diff --git a/src/helpers/radiolib/CustomSX1262Wrapper.h b/src/helpers/radiolib/CustomSX1262Wrapper.h index 1889a866..031512de 100644 --- a/src/helpers/radiolib/CustomSX1262Wrapper.h +++ b/src/helpers/radiolib/CustomSX1262Wrapper.h @@ -41,14 +41,15 @@ public: void doResetAGC() override { sx126xResetAGC((SX126x *)_radio); } // Warm sleep between CAD scans: ~1.5 µA vs ~600 µA in standby-RC. - // cadWake() delays 5 ms so the TCXO fully re-stabilises before the next scan - // (previous attempt without the delay corrupted long packets via freq drift). + // cadWake() sets standbyXOSC=true so every subsequent internal standby() call + // keeps the TCXO powered — no gap between CAD and startReceive, no freq drift. + // The chip's programmed TCXO timeout (set by begin()) handles stabilisation. void cadSleep() override { ((CustomSX1262 *)_radio)->sleep(true); // warm sleep — config retained } void cadWake() override { - _radio->standby(); - delayMicroseconds(5000); // TCXO stabilisation after warm sleep + ((SX126x *)_radio)->standbyXOSC = true; // all subsequent standby() → XOSC + _radio->standby(); // wake into standby-XOSC, TCXO on } void setRxBoostedGainMode(bool en) override { diff --git a/src/helpers/radiolib/RadioLibWrappers.cpp b/src/helpers/radiolib/RadioLibWrappers.cpp index 57e27f63..70af5171 100644 --- a/src/helpers/radiolib/RadioLibWrappers.cpp +++ b/src/helpers/radiolib/RadioLibWrappers.cpp @@ -24,8 +24,13 @@ // → 65 ms gives 2 guaranteed windows with margin. Revisit if SF/BW change. #define PS_CAD_INTERVAL_MS 65 // If CAD detects activity but no packet actually lands, fall back to scanning -// instead of sitting in continuous RX forever. -#define PS_RX_TIMEOUT_MS 1500 +// instead of sitting in continuous RX forever. Must exceed the longest possible +// packet air-time: 256 B at SF8/BW62.5/CR5 ≈ 1925 ms from preamble start, so +// 3000 ms gives ~1 s margin for a false-detect case. +#define PS_RX_TIMEOUT_MS 3000 +// After a successful receive, skip inter-scan sleep for this long so back-to-back +// messages are caught without waiting out the 65 ms window each time. +#define PS_BURST_WINDOW_MS 500 static volatile uint8_t state = STATE_IDLE; @@ -160,6 +165,10 @@ void RadioLibWrapper::armRecv() { } void RadioLibWrapper::enterCadSleep() { + if ((int32_t)(millis() - _ps_burst_until) < 0) { + armRecv(); // burst window: skip sleep, scan again immediately + return; + } cadSleep(); // warm sleep (SX126x) or standby fallback between scans _ps_phase = PS_SLEEPING; _ps_timer = millis() + PS_CAD_INTERVAL_MS; @@ -228,6 +237,7 @@ int RadioLibWrapper::recvRaw(uint8_t* bytes, int sz) { } else { // Serial.print(" readData() -> "); Serial.println(len); n_recv++; + _ps_burst_until = millis() + PS_BURST_WINDOW_MS; } } state = STATE_IDLE; // need another startReceive() diff --git a/src/helpers/radiolib/RadioLibWrappers.h b/src/helpers/radiolib/RadioLibWrappers.h index d39e3ebf..e1705c62 100644 --- a/src/helpers/radiolib/RadioLibWrappers.h +++ b/src/helpers/radiolib/RadioLibWrappers.h @@ -27,6 +27,7 @@ protected: bool _power_save = false; uint8_t _ps_phase = 0; // PS_* (see .cpp): scanning / sleeping / rxing uint32_t _ps_timer = 0; // next-scan time, or RX false-detect deadline + uint32_t _ps_burst_until = 0; // scan continuously until this time after RX void armRecv(); // arm RX honouring power-save (CAD) or continuous void powerSaveLoop(); void enterCadSleep();