diff --git a/zephcore/patches/zephyr/0003-lora-sx126x-native.patch b/zephcore/patches/zephyr/0003-lora-sx126x-native.patch index 298ec83..9e9955d 100644 --- a/zephcore/patches/zephyr/0003-lora-sx126x-native.patch +++ b/zephcore/patches/zephyr/0003-lora-sx126x-native.patch @@ -68,7 +68,7 @@ index 17689720dd2..09982dc2e70 100644 return -EINVAL; } diff --git a/drivers/lora/native/sx126x/sx126x.c b/drivers/lora/native/sx126x/sx126x.c -index 30243ba5dc7..fc77b8ef258 100644 +index 30243ba5dc7..588d72d9e23 100644 --- a/drivers/lora/native/sx126x/sx126x.c +++ b/drivers/lora/native/sx126x/sx126x.c @@ -10,10 +10,19 @@ @@ -268,7 +268,7 @@ index 30243ba5dc7..fc77b8ef258 100644 sx126x_hal_set_rf_switch(dev, enable, tx); } } -@@ -455,6 +529,67 @@ static int sx126x_reconnect_rf_gpios(const struct device *dev) +@@ -455,6 +529,73 @@ static int sx126x_reconnect_rf_gpios(const struct device *dev) } #endif /* CONFIG_PM_DEVICE */ @@ -278,8 +278,10 @@ index 30243ba5dc7..fc77b8ef258 100644 + * IRQ handler. Sends SetRx(continuous) directly, skipping the §15.3 + * workaround (only needed for implicit-header timed RX). This saves + * 2 SPI register transactions (~200 us) on every received packet. */ -+static void sx126x_restart_rx(const struct device *dev, struct sx126x_data *data) ++static int sx126x_restart_rx(const struct device *dev, struct sx126x_data *data) +{ ++ int ret; ++ + if (data->rx_duty_cycle_enabled) { + const struct sx126x_hal_config *config = dev->config; + @@ -293,7 +295,10 @@ index 30243ba5dc7..fc77b8ef258 100644 + * preamble budget (16-sym preamble, need 8 to lock). */ + sx126x_calibrate(dev, SX126X_CALIBRATE_ALL); + k_busy_wait(5000); -+ sx126x_hal_wait_busy(dev, 50); ++ ret = sx126x_hal_wait_busy(dev, 50); ++ if (ret < 0) { ++ return ret; ++ } + + /* Re-apply DIO2 as RF switch — Calibrate resets it */ + if (config->dio2_tx_enable) { @@ -331,12 +336,13 @@ index 30243ba5dc7..fc77b8ef258 100644 + uint8_t gain = data->rx_boost_enabled ? SX126X_RX_GAIN_BOOSTED + : SX126X_RX_GAIN_POWER_SAVING; + sx126x_hal_write_regs(dev, SX126X_REG_RX_GAIN, &gain, 1); ++ return 0; +} + static int sx126x_set_sleep(const struct device *dev) { struct sx126x_data *data = dev->data; -@@ -566,19 +701,23 @@ static void sx126x_handle_irq_rx_done(const struct device *dev, uint16_t irq_sta +@@ -566,19 +707,23 @@ static void sx126x_handle_irq_rx_done(const struct device *dev, uint16_t irq_sta /* Handle async callback or signal sync receiver */ if (data->rx_cb != NULL) { @@ -369,7 +375,7 @@ index 30243ba5dc7..fc77b8ef258 100644 } else { /* Sync mode */ sx126x_set_sleep(dev); -@@ -591,6 +730,20 @@ static void sx126x_handle_irq_timeout(const struct device *dev) +@@ -591,6 +736,39 @@ static void sx126x_handle_irq_timeout(const struct device *dev) struct sx126x_data *data = dev->data; LOG_DBG("Timeout"); @@ -382,15 +388,34 @@ index 30243ba5dc7..fc77b8ef258 100644 + * preserves the stored rx/sleep timing and re-applies AGC reset + + * StopTimerOnPreamble. */ + if (data->rx_duty_cycle_enabled && data->rx_cb != NULL) { ++ int ret; ++ + atomic_inc(&data->dc_timeout_restarts); -+ sx126x_restart_rx(dev, data); ++ ret = sx126x_restart_rx(dev, data); ++ if (ret < 0) { ++ LOG_WRN("Duty-cycle restart failed (%d), retry from sleep", ret); ++ (void)sx126x_set_sleep(dev); ++ ++ ret = sx126x_ensure_ready(dev); ++ if (ret < 0) { ++ LOG_WRN("Duty-cycle wake failed (%d)", ret); ++ return; ++ } ++ ++ atomic_set(&data->state, SX126X_STATE_RX); ++ ret = sx126x_restart_rx(dev, data); ++ if (ret < 0) { ++ LOG_WRN("Duty-cycle rearm failed (%d)", ret); ++ (void)sx126x_set_sleep(dev); ++ } ++ } + return; + } + sx126x_set_sleep(dev); if (data->tx_async_signal != NULL) { -@@ -637,6 +790,25 @@ static void sx126x_irq_work_handler(struct k_work *work) +@@ -637,6 +815,25 @@ static void sx126x_irq_work_handler(struct k_work *work) sx126x_handle_irq_timeout(dev); } @@ -416,7 +441,7 @@ index 30243ba5dc7..fc77b8ef258 100644 /* Re-enable the DIO1 interrupt for the next event (unless sleeping) */ if (atomic_get(&data->state) != SX126X_REST_STATE) { sx126x_hal_dio1_irq_enable(dev); -@@ -698,6 +870,29 @@ static int sx126x_lora_config(const struct device *dev, +@@ -698,6 +895,29 @@ static int sx126x_lora_config(const struct device *dev, goto out; } @@ -446,7 +471,7 @@ index 30243ba5dc7..fc77b8ef258 100644 /* Set sync word */ ret = sx126x_set_sync_word(dev, config->public_network); if (ret < 0) { -@@ -721,6 +916,8 @@ out: +@@ -721,6 +941,8 @@ out: return ret; } @@ -455,7 +480,7 @@ index 30243ba5dc7..fc77b8ef258 100644 static int sx126x_lora_send_async(const struct device *dev, uint8_t *data_buf, uint32_t data_len, struct k_poll_signal *async) -@@ -752,6 +949,65 @@ static int sx126x_lora_send_async(const struct device *dev, +@@ -752,6 +974,65 @@ static int sx126x_lora_send_async(const struct device *dev, return ret; } @@ -521,7 +546,7 @@ index 30243ba5dc7..fc77b8ef258 100644 data->tx_async_signal = async; k_msgq_purge(&data->tx_msgq); -@@ -777,6 +1033,29 @@ static int sx126x_lora_send_async(const struct device *dev, +@@ -777,6 +1058,29 @@ static int sx126x_lora_send_async(const struct device *dev, /* Enable antenna and set TX path */ sx126x_set_rf_path(dev, true, true); @@ -551,7 +576,7 @@ index 30243ba5dc7..fc77b8ef258 100644 /* Start transmission with 10 second timeout */ ret = sx126x_set_tx(dev, 10000); if (ret < 0) { -@@ -947,6 +1226,7 @@ static int sx126x_lora_recv_async(const struct device *dev, +@@ -947,6 +1251,7 @@ static int sx126x_lora_recv_async(const struct device *dev, data->rx_cb = cb; data->rx_cb_user_data = user_data; @@ -559,7 +584,7 @@ index 30243ba5dc7..fc77b8ef258 100644 /* Set packet parameters */ ret = sx126x_set_packet_params(dev, -@@ -1083,14 +1363,454 @@ static int sx126x_lora_test_cw(const struct device *dev, uint32_t frequency, +@@ -1083,14 +1388,454 @@ static int sx126x_lora_test_cw(const struct device *dev, uint32_t frequency, return 0; } @@ -1021,7 +1046,7 @@ index 30243ba5dc7..fc77b8ef258 100644 }; #ifdef CONFIG_PM_DEVICE -@@ -1121,9 +1841,19 @@ static int sx126x_init(const struct device *dev) +@@ -1121,9 +1866,19 @@ static int sx126x_init(const struct device *dev) k_msgq_init(&data->rx_msgq, (char *)&data->rx_result, sizeof(struct sx126x_rx_result), 1); k_work_init(&data->irq_work, sx126x_irq_work_handler);