mirror of
https://github.com/liquidraver/ZephCore.git
synced 2026-09-02 00:38:50 +00:00
fix(sx126x): recover and re-arm duty-cycle RX after BUSY timeout
This commit is contained in:
@@ -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);
|
||||
|
||||
Reference in New Issue
Block a user