gpio: clear irq status before calling user handler #4118
Merged
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.
This patch clears IRQ status on EXTI handlers before calling the user's handler.
Behavior without this patch was to clear IRQ afterwards (pseudocode):
This behavior meant that interrupts which fired during the user handler wouldn't be observed, since the IRQ status was unconditionally cleared afterwards — this throws away information. It risks the following:
The user code will never see or handle this interrupt condition. So if instead we clear the IRQ first, the handler will just be called again in this case.
Verification
Build a ring oscillator circuit: feed an output pin back into an input pin and invert the input level in an interrupt. Observe the feedback line on an oscilloscope. The circuit doesn't oscillate without this patch, but with it, it does.
This application can be used to verify: https://pub.npry.dev/irqfix (built .fap (API 80.1), gzipped so github will accept it). I symlinked into
applications_user/
to build. It uses pins PA7 and PA6 as input and output, respectively.The
Toggle
button can be used to "kick" the oscillator to start it if it doesn't start running automatically. This is what we see in the "no fix" image -- the toggle button inverts the level, the irq handler runs once, but then it stops, as the IRQ already fired within the handler and was then cleared.Flipper in circuit

No Fix

With Fix

Checklist (For Reviewer)