mirror of
https://github.com/liquidraver/ZephCore.git
synced 2026-09-01 20:09:17 +00:00
stay in full RX after TX for 3 seconds
agc reset on every lora_recv_duty_cycle entry
This commit is contained in:
File diff suppressed because it is too large
Load Diff
@@ -123,6 +123,17 @@ protected:
|
||||
void configureTx();
|
||||
void startReceive();
|
||||
|
||||
/* Continuous (non-duty-cycle) RX entry, used for the post-TX hot
|
||||
* window so a quick reply (within ~3 s) is caught before we drop
|
||||
* back to duty cycle. Caller must check _rx_duty_cycle_enabled
|
||||
* — only meaningful when duty cycle would otherwise be active. */
|
||||
void startReceiveHot();
|
||||
|
||||
/* Decides between startReceiveHot() and startReceive() based on
|
||||
* whether duty cycle is currently enabled. Used by the TX wait
|
||||
* thread on every TX completion path. */
|
||||
void restartReceiveAfterTx();
|
||||
|
||||
void startTxThread(k_thread_stack_t *stack, size_t stack_size);
|
||||
|
||||
const struct device *_dev;
|
||||
@@ -191,6 +202,26 @@ private:
|
||||
struct k_sem _tx_start_sem;
|
||||
bool _tx_thread_running;
|
||||
|
||||
/* Post-TX hot-RX window: after every TX, run continuous RX for
|
||||
* POST_TX_HOT_RX_MS so a fast reply (e.g. our repeater echoing
|
||||
* our flood) can't fall into a duty-cycle sleep gap. After the
|
||||
* timer expires, _hot_rx_expire_work cancels async RX and re-enters
|
||||
* via duty cycle (which now does Calibrate(ALL) on entry).
|
||||
* Hot window is gated by _rx_duty_cycle_enabled — if duty cycle
|
||||
* is disabled globally there's nothing to "hot up" relative to. */
|
||||
/* Wrapper makes the work item standard-layout so CONTAINER_OF can
|
||||
* recover the owning radio without tripping the C++ -Winvalid-offsetof
|
||||
* warning that fires on the (non-standard-layout) LoRaRadioBase. */
|
||||
struct HotRxWork {
|
||||
struct k_work work;
|
||||
LoRaRadioBase *self;
|
||||
};
|
||||
struct k_timer _hot_rx_timer;
|
||||
HotRxWork _hot_rx_expire_work;
|
||||
atomic_t _hot_rx_active;
|
||||
static void hotRxTimerHandler(struct k_timer *timer);
|
||||
static void hotRxExpireWorkFn(struct k_work *work);
|
||||
|
||||
/* Packet statistics */
|
||||
atomic_t _packets_recv;
|
||||
atomic_t _packets_sent;
|
||||
|
||||
@@ -634,7 +634,7 @@ index 30243ba5dc7..c5e346da139 100644
|
||||
k_mutex_unlock(&data->lock);
|
||||
return 0;
|
||||
}
|
||||
@@ -1083,14 +1408,469 @@ static int sx126x_lora_test_cw(const struct device *dev, uint32_t frequency,
|
||||
@@ -1083,14 +1408,500 @@ static int sx126x_lora_test_cw(const struct device *dev, uint32_t frequency,
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -982,6 +982,37 @@ index 30243ba5dc7..c5e346da139 100644
|
||||
+ return ret;
|
||||
+ }
|
||||
+
|
||||
+ /* AGC reset on every entry: Calibrate(ALL) re-initialises the analog
|
||||
+ * frontend (ADC/PLL/RC) so the receiver starts with a clean AGC state.
|
||||
+ * Without this, an AGC lock-up from a strong adjacent-channel signal
|
||||
+ * persists across the cycle (the hardware-driven duty cycle never
|
||||
+ * fires an IRQ to trigger sx126x_restart_rx's calibration path), and
|
||||
+ * post-TX entry inherits whatever state the chip was in before TX.
|
||||
+ * Cost: ~5 ms — paid once per entry, not per internal duty-cycle wake. */
|
||||
+ {
|
||||
+ const struct sx126x_hal_config *hal_cfg = dev->config;
|
||||
+
|
||||
+ sx126x_calibrate(dev, SX126X_CALIBRATE_ALL);
|
||||
+ k_busy_wait(5000);
|
||||
+ ret = sx126x_hal_wait_busy(dev, 50);
|
||||
+ if (ret < 0) {
|
||||
+ k_mutex_unlock(&data->lock);
|
||||
+ atomic_set(&data->state, SX126X_REST_STATE);
|
||||
+ return ret;
|
||||
+ }
|
||||
+
|
||||
+ /* Re-issue CalibrateImage for the operating frequency:
|
||||
+ * Calibrate(ALL) reverts image cal to the chip default
|
||||
+ * (902-928 MHz band) which kills RX sensitivity on
|
||||
+ * EU868 / 433 / 779 MHz operation. */
|
||||
+ sx126x_calibrate_image(dev, data->config.frequency);
|
||||
+
|
||||
+ /* Re-apply DIO2 as RF switch — Calibrate resets it. */
|
||||
+ if (hal_cfg->dio2_tx_enable) {
|
||||
+ sx126x_set_dio2_as_rf_switch(dev, true);
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ data->rx_cb = cb;
|
||||
+ data->rx_cb_user_data = user_data;
|
||||
+ atomic_inc(&data->rx_cb_gen);
|
||||
@@ -1111,7 +1142,7 @@ index 30243ba5dc7..c5e346da139 100644
|
||||
};
|
||||
|
||||
#ifdef CONFIG_PM_DEVICE
|
||||
@@ -1112,6 +1892,7 @@ static int sx126x_pm_action(const struct device *dev,
|
||||
@@ -1112,6 +1923,7 @@ static int sx126x_pm_action(const struct device *dev,
|
||||
static int sx126x_init(const struct device *dev)
|
||||
{
|
||||
struct sx126x_data *data = dev->data;
|
||||
@@ -1119,7 +1150,7 @@ index 30243ba5dc7..c5e346da139 100644
|
||||
int ret;
|
||||
|
||||
/* Initialize data structures */
|
||||
@@ -1121,9 +1902,25 @@ static int sx126x_init(const struct device *dev)
|
||||
@@ -1121,9 +1933,25 @@ 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