diff options
| author | Brent Kowal <[email protected]> | 2026-04-10 14:25:28 -0400 |
|---|---|---|
| committer | Brent Kowal <[email protected]> | 2026-04-11 07:29:06 -0400 |
| commit | ed37ad8ce2c7175aacb7dbc6348b4328835a2ff2 (patch) | |
| tree | c4fa5139b946a8a5814e466e65cebc27a47c7a92 | |
| parent | 470715ad8cb07b496ad2c2e9bf0b95d32cf768c7 (diff) | |
Fix musb RXRDY Clearing
Resolves an issue in the musb handle_xfer_out function where not all
execution paths cleared the MUSB_RXCSRL1_RXRDY bit, causing the RX
interface to hang and no longer communicate with the host.
Signed-off-by: Brent Kowal <[email protected]>
| -rw-r--r-- | src/portable/mentor/musb/dcd_musb.c | 13 |
1 files changed, 10 insertions, 3 deletions
diff --git a/src/portable/mentor/musb/dcd_musb.c b/src/portable/mentor/musb/dcd_musb.c index 339048473..64f9ebacf 100644 --- a/src/portable/mentor/musb/dcd_musb.c +++ b/src/portable/mentor/musb/dcd_musb.c @@ -230,13 +230,19 @@ static bool handle_xfer_out(uint8_t rhport, uint_fast8_t ep_addr) musb_ep_csr_t* ep_csr = get_ep_csr(musb_regs, epnum); // TU_LOG1(" RXCSRL%d = %x\r\n", epnum_minus1 + 1, ep_csr->rx_csrl); - TU_ASSERT(ep_csr->rx_csrl & MUSB_RXCSRL1_RXRDY); + //Fail gracefully. Spurious interrupt. + if (!(ep_csr->rx_csrl & MUSB_RXCSRL1_RXRDY)) return false; + + void *buf = pipe->buf; + if (buf == NULL) { + ep_csr->rx_csrl = MUSB_RXCSRL1_FLUSH; + return false; + } const unsigned mps = ep_csr->rx_maxp; const unsigned rem = pipe->remaining; const unsigned vld = ep_csr->rx_count; const unsigned len = TU_MIN(TU_MIN(rem, mps), vld); - void *buf = pipe->buf; volatile void *fifo_ptr = &musb_regs->fifo[epnum]; if (len) { if (_dcd.pipe_buf_is_fifo[TUSB_DIR_OUT] & TU_BIT(epnum_minus1)) { @@ -247,11 +253,12 @@ static bool handle_xfer_out(uint8_t rhport, uint_fast8_t ep_addr) } pipe->remaining = rem - len; } + + ep_csr->rx_csrl = 0; /* Always Clear RXRDY bit */ if ((len < mps) || (rem == len)) { pipe->buf = NULL; return NULL != buf; } - ep_csr->rx_csrl = 0; /* Clear RXRDY bit */ return false; } |
