Skip to content

EXTI: clear pending bits before dispatching handlers - #11942

Open
xhlsa wants to merge 1 commit into
iNavFlight:maintenance-10.xfrom
xhlsa:up/exti-clear-before-dispatch
Open

xhlsa wants to merge 1 commit into
iNavFlight:maintenance-10.xfrom
xhlsa:up/exti-clear-before-dispatch

Conversation

@xhlsa

@xhlsa xhlsa commented Sep 14, 2026

Copy link
Copy Markdown

Problem

EXTI_IRQHandler() clears each line's pending bit after its handler returns. If a new edge arrives on that line while the handler is running, it sets the pending bit again, and the write that follows wipes it. The interrupt is lost.

This is harmless for a gyro data-ready line, where the next sample brings another edge. It is fatal for a device that raises exactly one edge per step and then waits. A radio's BUSY/DIO line is the example: the driver waits for an interrupt that already arrived and was discarded.

Fix

Clear the snapshot of active lines once, before dispatching (as Betaflight's EXTI_IRQHandler does). An edge that arrives during dispatch stays pending, so the IRQ fires again on return.

Found / tested

  • Found porting Betaflight's SPI ExpressLRS (SX1280) receiver. Its interrupt chain stalled within seconds of linking.
  • A host-side unit test models EXTI pending/enable/software-trigger and runs the unmodified SX1280 driver with randomized BUSY timing. It stalls with the old clear order and runs clean with the new one. The test lives on the ELRS branch; happy to adapt it here if useful.
  • Flown on an AT32F435 board. Build-tested on STM32F4 and AT32F43x targets.

EXTI_IRQHandler() cleared each line's pending bit after its handler
returned. An edge arriving on that line while the handler ran set the bit
again and was then wiped, so the interrupt was silently lost. Any EXTI user
whose handler takes a while, or that triggers a follow-up edge (e.g. a
radio BUSY/DIO line), can stall waiting for an interrupt that already came.

Clear the snapshot of active lines first, as Betaflight does. Edges arriving
during dispatch stay pending and re-enter the handler.

Found porting Betaflight's SPI ExpressLRS receiver, where it stalled the
SX1280 interrupt chain; reproduced in a host simulation of the EXTI
pending/enable model.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
@xhlsa
xhlsa marked this pull request as ready for review September 14, 2026 04:00
@qodo-code-review

Copy link
Copy Markdown
Contributor

ⓘ Qodo reviews are paused because the subscription is no longer active. Ask your workspace admin to reactivate the subscription to resume reviews. Manage billing

@qodo-free-for-open-source-projects

Copy link
Copy Markdown

PR Summary by Qodo

Prevent lost EXTI edges during handler dispatch

🐞 Bug fix 🕐 10-20 Minutes

Grey Divider

AI Description

• Clears snapshotted EXTI pending lines before invoking registered handlers.
• Preserves same-line edges arriving during dispatch for subsequent IRQ delivery.
Diagram

sequenceDiagram
    participant EXTI as EXTI Hardware
    participant IRQ as IRQ Dispatcher
    participant Handler as Line Handler
    EXTI->>IRQ: Raise pending IRQ
    IRQ->>EXTI: Snapshot enabled pending
    IRQ->>EXTI: Clear snapshot
    IRQ->>Handler: Dispatch active line
    EXTI-->>EXTI: New edge stays pending
    Handler-->>IRQ: Return
    EXTI->>IRQ: Re-enter IRQ
Loading
High-Level Assessment

Clearing the complete active snapshot before dispatch is the preferred approach for write-one-to-clear EXTI registers. Unlike post-handler or per-line clearing, it preserves every edge arriving after the snapshot—including edges on lines waiting for dispatch—while requiring only one register write.

Files changed (1) +5 / -1

Bug fix (1) +5 / -1
exti.cClear active EXTI pending bits before callback dispatch +5/-1

Clear active EXTI pending bits before callback dispatch

• Moves the write-one-to-clear operation ahead of the handler loop and clears the captured active-line snapshot in one write. Edges arriving while callbacks execute now remain pending for subsequent interrupt delivery instead of being erased after callback return.

src/main/drivers/exti.c

@qodo-free-for-open-source-projects

Copy link
Copy Markdown

Code Review by Qodo

🐞 Bugs (0) 📘 Rule violations (0) 📎 Requirement gaps (0)

Grey Divider

Great, no issues found!

Qodo reviewed your code and found no material issues that require review

Grey Divider

Tip of the day
💡 Did you know, you can ask Qodo to dismiss a finding you disagree with, with your reason on record

More tips ↗ | Customize Qodo ↗ | Qodo docs ↗

Grey Divider

Qodo Logo

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant