summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBrent Kowal <[email protected]>2026-04-10 14:25:28 -0400
committerBrent Kowal <[email protected]>2026-04-11 07:29:06 -0400
commited37ad8ce2c7175aacb7dbc6348b4328835a2ff2 (patch)
treec4fa5139b946a8a5814e466e65cebc27a47c7a92
parent470715ad8cb07b496ad2c2e9bf0b95d32cf768c7 (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.c13
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;
}