From 25341e8b8fe86757d5aa64caf0f39e84ea495dd6 Mon Sep 17 00:00:00 2001 From: Jakub <106778416+MarekZegare4@users.noreply.github.com> Date: Wed, 10 Jun 2026 18:01:39 +0200 Subject: [PATCH] =?UTF-8?q?fix(power):=20use=20XOSC=20standby=20to=20keep?= =?UTF-8?q?=20TCXO=20on=20through=20CAD=E2=86=92RX;=20add=20burst=20window?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - cadWake() now sets standbyXOSC=true so RadioLib's internal standby() calls keep the TCXO powered continuously through the CAD scan and into startReceive, eliminating the freq-drift window that dropped ~50% of long packets - PS_RX_TIMEOUT_MS 1500→3000 to cover 256 B packets at SF8/BW62.5/CR5 (~1925 ms) - 500 ms burst window after each successful receive: skip inter-scan sleep so back-to-back messages are caught without waiting out the 65 ms cadence Co-Authored-By: Claude Sonnet 4.6 --- src/helpers/radiolib/CustomSX1262Wrapper.h | 9 +++++---- src/helpers/radiolib/RadioLibWrappers.cpp | 14 ++++++++++++-- src/helpers/radiolib/RadioLibWrappers.h | 1 + 3 files changed, 18 insertions(+), 6 deletions(-) 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();