mirror of
https://github.com/liquidraver/ZephCore.git
synced 2026-09-10 17:26:05 +00:00
fix sx1262 cad timeout issue
This commit is contained in:
@@ -577,7 +577,7 @@ Regenerate with:
|
||||
appended to this preamble.
|
||||
|
||||
diff --git a/drivers/lora/native/sx126x/sx126x.c b/drivers/lora/native/sx126x/sx126x.c
|
||||
index 30243ba5dc7..a2c57493caf 100644
|
||||
index 30243ba5dc7..d512fb59afc 100644
|
||||
--- a/drivers/lora/native/sx126x/sx126x.c
|
||||
+++ b/drivers/lora/native/sx126x/sx126x.c
|
||||
@@ -6,72 +6,236 @@
|
||||
@@ -1787,7 +1787,7 @@ index 30243ba5dc7..a2c57493caf 100644
|
||||
sx126x_set_sleep(dev);
|
||||
|
||||
if (data->tx_async_signal != NULL) {
|
||||
@@ -630,13 +1548,80 @@ static void sx126x_irq_work_handler(struct k_work *work)
|
||||
@@ -630,13 +1548,97 @@ static void sx126x_irq_work_handler(struct k_work *work)
|
||||
}
|
||||
|
||||
if (irq_status & SX126X_IRQ_RX_DONE) {
|
||||
@@ -1817,7 +1817,24 @@ index 30243ba5dc7..a2c57493caf 100644
|
||||
+ * negative CAD_RX exits to STDBY_RC exactly like CAD_ONLY, so
|
||||
+ * there is nothing to track. */
|
||||
+ if (data->cad_exit_rx && detected) {
|
||||
+ /* CAD_ONLY has left the chip in STDBY_RC (DS 13.1.8), so
|
||||
+ * arm the follow-on Rx ourselves with an explicit
|
||||
+ * SetRx(timeout). That re-invokes and re-programs the RTC,
|
||||
+ * which is exactly what cadTimeout fails to do after
|
||||
+ * SetRxDutyCycle -- so the terminal IRQ (RX_DONE, CRC_ERR or
|
||||
+ * RX_TX_TIMEOUT) is genuinely guaranteed here, duty cycle or
|
||||
+ * not. Bound is max-length-packet airtime +25% +100 ms, the
|
||||
+ * same figure cadTimeout used, so a real packet still
|
||||
+ * completes inside it. Cost is the ~1 ms of SPI between
|
||||
+ * CAD_DONE and Rx, well inside the (P-8)-symbol preamble
|
||||
+ * budget the probe already spends. */
|
||||
+ uint8_t rxbuf[3];
|
||||
+ uint32_t tmo = SX126X_MS_TO_TIMEOUT(
|
||||
+ sx126x_max_payload_ms(data));
|
||||
+
|
||||
+ sys_put_be24(tmo & 0xFFFFFFU, rxbuf);
|
||||
+ atomic_set(&data->cad_rx_state, SX126X_CAD_RX_ARMED);
|
||||
+ sx126x_hal_write_cmd(dev, SX126X_CMD_SET_RX, rxbuf, 3);
|
||||
+ }
|
||||
+
|
||||
+ if (data->cad_cb) {
|
||||
@@ -1868,7 +1885,7 @@ index 30243ba5dc7..a2c57493caf 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);
|
||||
@@ -648,6 +1633,7 @@ static int sx126x_lora_config(const struct device *dev,
|
||||
@@ -648,6 +1650,7 @@ static int sx126x_lora_config(const struct device *dev,
|
||||
{
|
||||
struct sx126x_data *data = dev->data;
|
||||
const struct sx126x_hal_config *hal_config = dev->config;
|
||||
@@ -1876,11 +1893,14 @@ index 30243ba5dc7..a2c57493caf 100644
|
||||
bool ldro;
|
||||
int ret;
|
||||
|
||||
@@ -679,25 +1665,45 @@ static int sx126x_lora_config(const struct device *dev,
|
||||
@@ -679,25 +1682,45 @@ static int sx126x_lora_config(const struct device *dev,
|
||||
goto out;
|
||||
}
|
||||
|
||||
- /* Configure PA and TX power based on chip variant and frequency */
|
||||
- ret = sx126x_hal_configure_tx_params(dev, config->tx_power,
|
||||
- config->frequency,
|
||||
- SX126X_RAMP_200_US);
|
||||
+ /* Install the band's RSSI/AGC calibration (DS Sec 6.1.6) before the
|
||||
+ * RX gain write below, which consumes the AgcSensiAdjust this caches.
|
||||
+ * Re-run on every config so a runtime frequency change switches bands
|
||||
@@ -1891,9 +1911,8 @@ index 30243ba5dc7..a2c57493caf 100644
|
||||
+ }
|
||||
+
|
||||
+ /* Configure PA and TX power based on chip variant and frequency */
|
||||
ret = sx126x_hal_configure_tx_params(dev, config->tx_power,
|
||||
config->frequency,
|
||||
- SX126X_RAMP_200_US);
|
||||
+ ret = sx126x_hal_configure_tx_params(dev, config->tx_power,
|
||||
+ config->frequency,
|
||||
+ SX126X_TX_RAMP_TIME);
|
||||
if (ret < 0) {
|
||||
goto out;
|
||||
@@ -1925,7 +1944,7 @@ index 30243ba5dc7..a2c57493caf 100644
|
||||
/* Set sync word */
|
||||
ret = sx126x_set_sync_word(dev, config->public_network);
|
||||
if (ret < 0) {
|
||||
@@ -721,6 +1727,10 @@ out:
|
||||
@@ -721,6 +1744,10 @@ out:
|
||||
return ret;
|
||||
}
|
||||
|
||||
@@ -1936,7 +1955,7 @@ index 30243ba5dc7..a2c57493caf 100644
|
||||
static int sx126x_lora_send_async(const struct device *dev,
|
||||
uint8_t *data_buf, uint32_t data_len,
|
||||
struct k_poll_signal *async)
|
||||
@@ -738,11 +1748,27 @@ static int sx126x_lora_send_async(const struct device *dev,
|
||||
@@ -738,11 +1765,27 @@ static int sx126x_lora_send_async(const struct device *dev,
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
@@ -1966,7 +1985,7 @@ index 30243ba5dc7..a2c57493caf 100644
|
||||
k_mutex_lock(&data->lock, K_FOREVER);
|
||||
|
||||
ret = sx126x_ensure_ready(dev);
|
||||
@@ -752,6 +1778,59 @@ static int sx126x_lora_send_async(const struct device *dev,
|
||||
@@ -752,6 +1795,59 @@ static int sx126x_lora_send_async(const struct device *dev,
|
||||
return ret;
|
||||
}
|
||||
|
||||
@@ -2026,7 +2045,7 @@ index 30243ba5dc7..a2c57493caf 100644
|
||||
data->tx_async_signal = async;
|
||||
k_msgq_purge(&data->tx_msgq);
|
||||
|
||||
@@ -777,8 +1856,99 @@ static int sx126x_lora_send_async(const struct device *dev,
|
||||
@@ -777,8 +1873,99 @@ static int sx126x_lora_send_async(const struct device *dev,
|
||||
/* Enable antenna and set TX path */
|
||||
sx126x_set_rf_path(dev, true, true);
|
||||
|
||||
@@ -2128,7 +2147,7 @@ index 30243ba5dc7..a2c57493caf 100644
|
||||
if (ret < 0) {
|
||||
goto out_error;
|
||||
}
|
||||
@@ -847,6 +2017,8 @@ static int sx126x_lora_recv(const struct device *dev, uint8_t *data_buf,
|
||||
@@ -847,6 +2034,8 @@ static int sx126x_lora_recv(const struct device *dev, uint8_t *data_buf,
|
||||
}
|
||||
|
||||
data->rx_cb = NULL;
|
||||
@@ -2137,7 +2156,7 @@ index 30243ba5dc7..a2c57493caf 100644
|
||||
k_msgq_purge(&data->rx_msgq);
|
||||
|
||||
/* Set packet parameters for variable length reception */
|
||||
@@ -918,6 +2090,8 @@ static int sx126x_lora_recv_async(const struct device *dev,
|
||||
@@ -918,6 +2107,8 @@ static int sx126x_lora_recv_async(const struct device *dev,
|
||||
/* Stop async reception */
|
||||
data->rx_cb = NULL;
|
||||
data->rx_cb_user_data = NULL;
|
||||
@@ -2146,7 +2165,7 @@ index 30243ba5dc7..a2c57493caf 100644
|
||||
if (atomic_cas(&data->state, SX126X_STATE_RX, SX126X_STATE_IDLE)) {
|
||||
sx126x_set_standby(dev, SX126X_STANDBY_RC);
|
||||
sx126x_set_sleep(dev);
|
||||
@@ -932,6 +2106,19 @@ static int sx126x_lora_recv_async(const struct device *dev,
|
||||
@@ -932,6 +2123,19 @@ static int sx126x_lora_recv_async(const struct device *dev,
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
@@ -2166,7 +2185,7 @@ index 30243ba5dc7..a2c57493caf 100644
|
||||
if (!atomic_cas(&data->state, SX126X_REST_STATE, SX126X_STATE_RX)) {
|
||||
LOG_ERR("Busy");
|
||||
k_mutex_unlock(&data->lock);
|
||||
@@ -945,8 +2132,18 @@ static int sx126x_lora_recv_async(const struct device *dev,
|
||||
@@ -945,8 +2149,18 @@ static int sx126x_lora_recv_async(const struct device *dev,
|
||||
return ret;
|
||||
}
|
||||
|
||||
@@ -2185,7 +2204,7 @@ index 30243ba5dc7..a2c57493caf 100644
|
||||
|
||||
/* Set packet parameters */
|
||||
ret = sx126x_set_packet_params(dev,
|
||||
@@ -959,6 +2156,7 @@ static int sx126x_lora_recv_async(const struct device *dev,
|
||||
@@ -959,6 +2173,7 @@ static int sx126x_lora_recv_async(const struct device *dev,
|
||||
SX126X_LORA_IQ_INVERTED : SX126X_LORA_IQ_STANDARD);
|
||||
if (ret < 0) {
|
||||
data->rx_cb = NULL;
|
||||
@@ -2193,7 +2212,7 @@ index 30243ba5dc7..a2c57493caf 100644
|
||||
sx126x_set_sleep(dev);
|
||||
k_mutex_unlock(&data->lock);
|
||||
return ret;
|
||||
@@ -971,11 +2169,21 @@ static int sx126x_lora_recv_async(const struct device *dev,
|
||||
@@ -971,11 +2186,21 @@ static int sx126x_lora_recv_async(const struct device *dev,
|
||||
ret = sx126x_set_rx(dev, 0);
|
||||
if (ret < 0) {
|
||||
data->rx_cb = NULL;
|
||||
@@ -2215,7 +2234,7 @@ index 30243ba5dc7..a2c57493caf 100644
|
||||
k_mutex_unlock(&data->lock);
|
||||
return 0;
|
||||
}
|
||||
@@ -993,7 +2201,9 @@ static uint32_t sx126x_lora_airtime(const struct device *dev, uint32_t data_len)
|
||||
@@ -993,7 +2218,9 @@ static uint32_t sx126x_lora_airtime(const struct device *dev, uint32_t data_len)
|
||||
}
|
||||
|
||||
/* Calculate symbol time in microseconds */
|
||||
@@ -2226,7 +2245,7 @@ index 30243ba5dc7..a2c57493caf 100644
|
||||
sf = data->config.datarate;
|
||||
|
||||
/* Symbol time = 2^SF / BW (seconds) */
|
||||
@@ -1051,7 +2261,7 @@ static int sx126x_lora_test_cw(const struct device *dev, uint32_t frequency,
|
||||
@@ -1051,7 +2278,7 @@ static int sx126x_lora_test_cw(const struct device *dev, uint32_t frequency,
|
||||
|
||||
/* Set PA config and TX power */
|
||||
ret = sx126x_hal_configure_tx_params(dev, tx_power, frequency,
|
||||
@@ -2235,7 +2254,7 @@ index 30243ba5dc7..a2c57493caf 100644
|
||||
if (ret < 0) {
|
||||
sx126x_set_sleep(dev);
|
||||
k_mutex_unlock(&data->lock);
|
||||
@@ -1083,14 +2293,1067 @@ static int sx126x_lora_test_cw(const struct device *dev, uint32_t frequency,
|
||||
@@ -1083,14 +2310,1076 @@ static int sx126x_lora_test_cw(const struct device *dev, uint32_t frequency,
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -2837,13 +2856,22 @@ index 30243ba5dc7..a2c57493caf 100644
|
||||
+ * It is a chip-side deadline that always raises RX_TX_TIMEOUT, which is
|
||||
+ * what lets the outcome be *observed* rather than polled for. */
|
||||
+ uint8_t buf[7];
|
||||
+ uint32_t cad_timeout = data->cad_exit_rx
|
||||
+ ? SX126X_MS_TO_TIMEOUT(sx126x_max_payload_ms(data)) : 0U;
|
||||
+ /* Always CAD_ONLY on the wire. cadTimeout is NOT honoured once
|
||||
+ * SetRxDutyCycle has run -- the DS command table says that command
|
||||
+ * "stores values of RTC setup for listen mode", and errata 15.3 notes a
|
||||
+ * stale RTC misbehaves in "any subsequent mode where the RTC isn't
|
||||
+ * re-invoked, and therefore reset and re-programmed". A CAD_RX exit
|
||||
+ * does not re-program it, so on a duty-cycled node the chip entered Rx
|
||||
+ * unbounded and no terminal IRQ ever arrived (measured: GetStatus 0x52
|
||||
+ * = RX, IRQ register 0x0000, long past even a 500 ms cadTimeout).
|
||||
+ * The probe therefore arms its Rx explicitly after CAD_DONE instead --
|
||||
+ * see the cad_exit_rx branch in the DIO1 work handler. */
|
||||
+ uint32_t cad_timeout = 0U;
|
||||
+
|
||||
+ buf[0] = symb_nb;
|
||||
+ buf[1] = detect_peak;
|
||||
+ buf[2] = mc->cad.detection_minimum ? mc->cad.detection_minimum : 10;
|
||||
+ buf[3] = data->cad_exit_rx ? 0x01 : 0x00; /* CAD_RX : CAD_ONLY */
|
||||
+ buf[3] = 0x00; /* CAD_ONLY -- see the cad_timeout note above */
|
||||
+ sys_put_be24(cad_timeout & 0xFFFFFFU, &buf[4]);
|
||||
+
|
||||
+ ret = sx126x_hal_write_cmd(dev, SX126X_CMD_SET_CAD_PARAMS, buf, 7);
|
||||
@@ -3310,7 +3338,7 @@ index 30243ba5dc7..a2c57493caf 100644
|
||||
};
|
||||
|
||||
#ifdef CONFIG_PM_DEVICE
|
||||
@@ -1112,6 +3375,7 @@ static int sx126x_pm_action(const struct device *dev,
|
||||
@@ -1112,6 +3401,7 @@ static int sx126x_pm_action(const struct device *dev,
|
||||
static int sx126x_init(const struct device *dev)
|
||||
{
|
||||
struct sx126x_data *data = dev->data;
|
||||
@@ -3318,7 +3346,7 @@ index 30243ba5dc7..a2c57493caf 100644
|
||||
int ret;
|
||||
|
||||
/* Initialize data structures */
|
||||
@@ -1121,9 +3385,33 @@ static int sx126x_init(const struct device *dev)
|
||||
@@ -1121,9 +3411,33 @@ 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);
|
||||
@@ -3352,7 +3380,7 @@ index 30243ba5dc7..a2c57493caf 100644
|
||||
|
||||
/* Initialize HAL */
|
||||
ret = sx126x_hal_init(dev);
|
||||
@@ -1185,6 +3473,8 @@ static int sx126x_init(const struct device *dev)
|
||||
@@ -1185,6 +3499,8 @@ static int sx126x_init(const struct device *dev)
|
||||
{0}), \
|
||||
.rx_enable = GPIO_DT_SPEC_INST_GET_OR(inst, rx_enable_gpios, \
|
||||
{0}), \
|
||||
@@ -3361,7 +3389,7 @@ index 30243ba5dc7..a2c57493caf 100644
|
||||
.dio2_tx_enable = DT_INST_PROP(inst, dio2_tx_enable), \
|
||||
.dio3_tcxo_enable = DT_INST_NODE_HAS_PROP(inst, dio3_tcxo_voltage), \
|
||||
.dio3_tcxo_voltage = DT_INST_PROP_OR(inst, dio3_tcxo_voltage, 0), \
|
||||
@@ -1239,6 +3529,8 @@ DT_INST_FOREACH_STATUS_OKAY_VARGS(SX126X_INIT, true)
|
||||
@@ -1239,6 +3555,8 @@ DT_INST_FOREACH_STATUS_OKAY_VARGS(SX126X_INIT, true)
|
||||
{0}), \
|
||||
.rx_enable = GPIO_DT_SPEC_INST_GET_OR(inst, rx_enable_gpios, \
|
||||
{0}), \
|
||||
|
||||
Reference in New Issue
Block a user