mirror of
https://github.com/meshtastic/firmware.git
synced 2026-10-31 20:40:53 -04:00
* Radio: end a CAD handoff whose RX hits a damaged header When CAD hands off to RX and that RX ends on a damaged header (CRC_ERR or HEADER_ERR with no RX_DONE), the RX readout task cleared those flags and returned. Nothing was notified and cadHandoffRxStart stayed set, so the radio thread never re-armed. Where the chip had stopped listening, the node stayed deaf until the main loop's backstop logged "CAD>RX timeout" and re-armed: 200 ms to over a second later. Before the readout task, the same edge went to handleReceiveInterrupt(), which read the error, cleared the flags and re-armed. The bench saw this on an LR2021 (X1) running develop: 5 "CAD>RX timeout" lines across 3 runs, where pre-#11983 develop logged none in 4 runs. Now the task hands every frameless end of a handoff's RX (TIMEOUT, CRC_ERR, HEADER_ERR) to the radio thread, which clears the flags through handleReceiveInterrupt() and re-arms, as it already did for TIMEOUT. Co-Authored-By: Jonathan Bennett <jbennett@incomsystems.biz> Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01REkPVFh6kvG4AZJ5A8AtM9 * Radio: don't strand a damaged header's flags when its notification is dropped Three follow-ups to the handoff end, from review of the first commit. The readout task's notify(ISR_RX, !rxArmedBeforeTxDone) deliberately does not overwrite a pending TX notification, so the RX notification can be dropped. That is pre-existing for the TIMEOUT case, and the ISR_TX path does put the chip back into RX, but the first commit moved the clearing of CRC_ERR / HEADER_ERR to the radio thread, so in the dropped case nothing clears them until checkCadHandoffTimeout(). notify() returns false exactly when it dropped, so clear them at that site in that case, as the code did before, and leave the open handoff to the backstop. handleReceiveInterrupt() logged "CAD>RX pkt" for a frameless end, and read a length that is not a frame's. A damaged header now takes the same exit as an empty window, with its own log line, so a capture says which of the two happened and getPacketLength() is not asked about a packet that never arrived. rxBad is unchanged either way: neither case counted before. An empty window inside a handoff can carry a damaged header's flags alongside the timeout, both routed to DIO1, so that exit clears them together. Plain RX is untouched there and still leaves HEADER_ERR to checkStaleRxFlags(). Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01GTiifXrVc4YdonmLRCeWhw --------- Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>