From a1d632d16cc80d2029c76f31b054ab0648bab5d2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jaros=C5=82aw=20Doma=C5=84ski?= Date: Sat, 25 Jul 2026 14:52:42 +0200 Subject: [PATCH] Stop RX duty-cycle before CAD to avoid main-loop hang. CAD on a still-running SX126x duty-cycle sequencer can lose CAD-done IRQ when the RTC knocks the chip back to standby, leaving scanChannel() waiting forever. --- src/helpers/radiolib/RadioLibWrappers.cpp | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/src/helpers/radiolib/RadioLibWrappers.cpp b/src/helpers/radiolib/RadioLibWrappers.cpp index 297aa3679..b44b428e7 100644 --- a/src/helpers/radiolib/RadioLibWrappers.cpp +++ b/src/helpers/radiolib/RadioLibWrappers.cpp @@ -424,6 +424,17 @@ bool RadioLibWrapper::isChannelActive() { // cad: hardware channel activity detection if (_cad_enabled) { + if (_rx_ps_armed) { + // CAD must not be issued on top of a running duty-cycle sequencer. The + // sequencer's RTC keeps running across the SetStandby that the scan does + // first (same errata as stopRTC() documents for RX), and its pending event + // can knock the chip back to standby mid-CAD without raising an IRQ. The + // CAD-done then never arrives and RadioLib's scanChannel() waits for it + // forever, hanging the whole main loop. Stop the sequencer and its RTC + // first, exactly like startSendRaw() and startReceiveMode() do; the + // startRecv() below re-arms the duty cycle. + stopReceiveDutyCycle(); + } int16_t result = performChannelScan(); // scanChannel() triggers DIO interrupt (CAD done) which sets STATE_INT_READY // via setFlag() ISR. Clear it before restarting RX so recvRaw() doesn't