summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorhathach <[email protected]>2026-07-09 23:38:38 +0700
committerhathach <[email protected]>2026-07-09 23:38:38 +0700
commit3fc60eafb3e7232e402c69d5ebd14c6de15034af (patch)
treeb47cfad1e5c0904890f340afef4f6376b90d2050
parent0464636878851a26b9995972a90aefe3825d043b (diff)
dcd(musb): flush TX FIFO on halt; don't load a disarmed pipe
Co-Authored-By: Claude Fable 5 <[email protected]> Claude-Session: https://claude.ai/code/session_01HeF2gZ1M7GWkz6Av4BpKPg
-rw-r--r--src/portable/mentor/musb/dcd_musb.c10
1 files changed, 10 insertions, 0 deletions
diff --git a/src/portable/mentor/musb/dcd_musb.c b/src/portable/mentor/musb/dcd_musb.c
index 1ebd1fe02..17993f23a 100644
--- a/src/portable/mentor/musb/dcd_musb.c
+++ b/src/portable/mentor/musb/dcd_musb.c
@@ -292,6 +292,12 @@ static void process_epin_isr(uint8_t rhport, musb_regs_t *musb_regs, uint8_t epn
}
pipe_state_t* pipe = pipe_get(epnum, TUSB_DIR_IN);
+ // No active transfer: a halt/abort disarmed the pipe (armed=false) but may leave remaining>0.
+ // Do not keep loading the aborted transfer — that would re-fill the just-flushed FIFO and the
+ // next (re-armed) transfer's data would stack on top (host sees an oversized packet -> babble).
+ if (!pipe->armed) {
+ return;
+ }
if (pipe->remaining > 0) {
pipe_write(musb_regs, pipe, epnum);
} else {
@@ -910,6 +916,10 @@ void dcd_edpt_stall(uint8_t rhport, uint8_t ep_addr) {
} else {
const tusb_dir_t ep_dir = tu_edpt_dir(ep_addr);
const uint8_t is_rx = (ep_dir == TUSB_DIR_OUT ? 1u : 0u);
+ // A halt aborts the transfer: flush staged FIFO packet(s) before stalling, else leftover TX data
+ // concatenates with the next transfer after un-halt -> host sees an oversized packet (babble).
+ // FLUSH must precede SEND_STALL, which clears the TXRDY that hwfifo_flush() gates on.
+ hwfifo_flush(musb_regs, epn, is_rx, false);
ep_csr->maxp_csr[is_rx].csrl = MUSB_CSRL_SEND_STALL(is_rx);
pipe_state_t* pipe = pipe_get(epn, ep_dir);
pipe->armed = false;