Skip to content

Commit ed37ad8

Browse files
committed
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 <brent.kowal@analog.com>
1 parent 470715a commit ed37ad8

1 file changed

Lines changed: 10 additions & 3 deletions

File tree

src/portable/mentor/musb/dcd_musb.c

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -230,13 +230,19 @@ static bool handle_xfer_out(uint8_t rhport, uint_fast8_t ep_addr)
230230
musb_ep_csr_t* ep_csr = get_ep_csr(musb_regs, epnum);
231231
// TU_LOG1(" RXCSRL%d = %x\r\n", epnum_minus1 + 1, ep_csr->rx_csrl);
232232

233-
TU_ASSERT(ep_csr->rx_csrl & MUSB_RXCSRL1_RXRDY);
233+
//Fail gracefully. Spurious interrupt.
234+
if (!(ep_csr->rx_csrl & MUSB_RXCSRL1_RXRDY)) return false;
235+
236+
void *buf = pipe->buf;
237+
if (buf == NULL) {
238+
ep_csr->rx_csrl = MUSB_RXCSRL1_FLUSH;
239+
return false;
240+
}
234241

235242
const unsigned mps = ep_csr->rx_maxp;
236243
const unsigned rem = pipe->remaining;
237244
const unsigned vld = ep_csr->rx_count;
238245
const unsigned len = TU_MIN(TU_MIN(rem, mps), vld);
239-
void *buf = pipe->buf;
240246
volatile void *fifo_ptr = &musb_regs->fifo[epnum];
241247
if (len) {
242248
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)
247253
}
248254
pipe->remaining = rem - len;
249255
}
256+
257+
ep_csr->rx_csrl = 0; /* Always Clear RXRDY bit */
250258
if ((len < mps) || (rem == len)) {
251259
pipe->buf = NULL;
252260
return NULL != buf;
253261
}
254-
ep_csr->rx_csrl = 0; /* Clear RXRDY bit */
255262
return false;
256263
}
257264

0 commit comments

Comments
 (0)