summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorHiFiPHile <[email protected]>2026-08-27 14:49:47 +0200
committerHiFiPHile <[email protected]>2026-09-02 10:50:02 +0200
commit13971b58df52bc29de97632295fcae43aeade5c9 (patch)
tree8ca52d5bf292290368132b1d815cd3a9891e4b1d
parenta0d3de76869ce728c7c1d9713085bc970da39671 (diff)
fix(dwc2): drain host RX status before channel IRQ
Popping an IN transfer-completion entry from GRXSTSP asserts HCINT.XferCompl. Drain the receive FIFO first, then read the live masked global status so the newly asserted channel completion is handled without waiting for another interrupt.
-rw-r--r--src/portable/synopsys/dwc2/hcd_dwc2.c30
1 files changed, 15 insertions, 15 deletions
diff --git a/src/portable/synopsys/dwc2/hcd_dwc2.c b/src/portable/synopsys/dwc2/hcd_dwc2.c
index 05efacbee..ca16eec70 100644
--- a/src/portable/synopsys/dwc2/hcd_dwc2.c
+++ b/src/portable/synopsys/dwc2/hcd_dwc2.c
@@ -1574,21 +1574,6 @@ void hcd_int_handler(uint8_t rhport, bool in_isr) {
handle_hprt_irq(rhport, in_isr);
}
- if (gintsts & GINTSTS_HCINT) {
- // Host Channel interrupt: source is cleared in HCINT register
- // must be handled after TX FIFO empty
- handle_channel_irq(rhport, in_isr);
- }
-
- if (gintsts & GINTSTS_DISCINT) {
- // Device disconnected
- dwc2->gintsts = GINTSTS_DISCINT;
-
- if (0 == (dwc2->hprt & HPRT_CONN_STATUS)) {
- hcd_event_device_remove(rhport, in_isr);
- }
- }
-
#if CFG_TUH_DWC2_SLAVE_ENABLE
// RxFIFO non-empty interrupt handling
if (gintsts & GINTSTS_RXFLVL) {
@@ -1620,6 +1605,21 @@ void hcd_int_handler(uint8_t rhport, bool in_isr) {
}
}
#endif
+
+ // Draining the RxFIFO completion status can assert HCINT.XferCompl. Read
+ // the live status here so the completion is handled in this ISR invocation.
+ if ((dwc2->gintsts & dwc2->gintmsk) & GINTSTS_HCINT) {
+ handle_channel_irq(rhport, in_isr);
+ }
+
+ if (gintsts & GINTSTS_DISCINT) {
+ // Device disconnected
+ dwc2->gintsts = GINTSTS_DISCINT;
+
+ if (0 == (dwc2->hprt & HPRT_CONN_STATUS)) {
+ hcd_event_device_remove(rhport, in_isr);
+ }
+ }
}
#endif