diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/portable/mentor/musb/dcd_musb.c | 12 |
1 files changed, 8 insertions, 4 deletions
diff --git a/src/portable/mentor/musb/dcd_musb.c b/src/portable/mentor/musb/dcd_musb.c index 9bdd6b080..86ae3ae9a 100644 --- a/src/portable/mentor/musb/dcd_musb.c +++ b/src/portable/mentor/musb/dcd_musb.c @@ -458,10 +458,7 @@ static void process_ep0(uint8_t rhport) { musb_ep_csr_t* ep_csr = get_ep_csr(musb_regs, 0); uint_fast8_t csrl = ep_csr->csr0l; - if (csrl & MUSB_CSRL0_DATAEND) { - return; - } - + // 21.1.5: SentStall and SetupEnd must be checked before anything else. if (csrl & MUSB_CSRL0_STALLED) { ep_csr->csr0l = 0; _dcd.pipe0.state = PIPE0_STATE_IDLE; @@ -559,6 +556,13 @@ static void process_ep0(uint8_t rhport) { return; } + if (csrl & MUSB_CSRL0_DATAEND) { + // Last DATA IN chunk / STATUS IN arm wrote TXRDY|DATAEND and the status stage has not completed + // yet — nothing to service. DataEnd is CPU-set-only per the CSR access table; whether it ever + // reads back 1 is vendor-dependent (on cores where it reads 0 this guard is dead code). + return; + } + /* When CSRL0 is zero, it means that either * - completion of sending any length packet TxPktRdy clear * - or status stage is complete (ZLP) after DataEnd is set */ |
