fix: clear IRQ register after RX restore to prevent gpiod polling dea…#79
Open
zindello wants to merge 1 commit into
Open
fix: clear IRQ register after RX restore to prevent gpiod polling dea…#79zindello wants to merge 1 commit into
zindello wants to merge 1 commit into
Conversation
…fness When two back-to-back packets arrive within the gpiod polling window (20ms), the IRQ line stays HIGH after the first interrupt is handled. The polling thread never sees a LOW→HIGH transition for the second event, so _handle_interrupt is never called and the radio goes deaf indefinitely. Calling clearIrqStatus(0xFFFF) immediately after request(RX_CONTINUOUS) forces DIO1 LOW, allowing the polling thread to detect the next real rising edge. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
fix: radio deafness on gpiod devices after back-to-back corrupted packets
Problem
On devices using the
gpiodGPIO backend, the radio would intermittently go completely deaf — receiving no packets until the next transmit cycle or a restart.The root cause is a race between back-to-back LoRa IRQs and the gpiod polling interval. The
gpiodbackend detects interrupts by polling DIO1 every 20ms, looking for a LOW→HIGH transition. When two IRQs arrive close together (e.g. a corrupted preamble followed immediately by another), DIO1 is already HIGH when the second IRQ fires. The polling thread sees HIGH→HIGH, not LOW→HIGH, so the second interrupt is silently lost. DIO1 stays HIGH indefinitely,_handle_interruptis never called again, and the radio stops receiving.The condition was confirmed in production logs: DIO1 remained stuck HIGH for over 100 seconds with no recovery.
Fix
After calling
request(RX_CONTINUOUS)to restore the radio at the end of IRQ handling, immediately callclearIrqStatus(0xFFFF). This sends an SPI command to the SX1262 to clear all pending IRQ flags, which causes the chip to de-assert DIO1. The line goes LOW, and the polling thread can now detect the next real rising edge normally.Why this isn't guarded to gpiod only
The
peripherybackend uses kernel-level edge detection (hardware FIFO), so it doesn't suffer from missed edges. However, theclearIrqStatuscall is an SPI transaction that executes in approximately 8µs — far shorter than the minimum possible LoRa Time-on-Air (~5ms at SF5/250kHz). No valid packet can arrive and complete reception in that window on any supported SF or bandwidth combination, making the call safe to apply unconditionally on both backends.