Skip to content

Commit 6e11406

Browse files
committed
dcd_pic: handle EP0 timeout/stall correctly
1 parent 0192b2a commit 6e11406

File tree

1 file changed

+12
-1
lines changed

1 file changed

+12
-1
lines changed

src/portable/microchip/pic/dcd_pic.c

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -316,12 +316,23 @@ static void prepare_next_setup_packet(uint8_t rhport)
316316
{
317317
const unsigned out_odd = _dcd.endpoint[0][0].odd;
318318
const unsigned in_odd = _dcd.endpoint[0][1].odd;
319-
TU_ASSERT(0 == _dcd.bdt[0][0][out_odd].own, );
319+
320+
// Abandon any previous control transfers that might have been using EP0.
321+
// Ordinarily, nothing actually needs abandoning, since the previous control
322+
// transfer would have completed successfully prior to the host sending the
323+
// next SETUP packet. However, in a timeout error case, or after an EP0
324+
// STALL event, one or more UOWN bits might still be set. If so, we should
325+
// clear the UOWN bits, so the EP0 IN/OUT endpoints are in a known inactive
326+
// state, ready for re-arming by the `dcd_edpt_xfer' function that will be
327+
// called next.
320328

321329
_dcd.bdt[0][0][out_odd].data = 0;
330+
_dcd.bdt[0][0][out_odd].own = 0;
322331
_dcd.bdt[0][0][out_odd ^ 1].data = 1;
323332
_dcd.bdt[0][1][in_odd].data = 1;
333+
_dcd.bdt[0][1][in_odd].own = 0;
324334
_dcd.bdt[0][1][in_odd ^ 1].data = 0;
335+
_dcd.bdt[0][1][in_odd ^ 1].own = 0;
325336
dcd_edpt_xfer(rhport, tu_edpt_addr(0, TUSB_DIR_OUT),
326337
_dcd.setup_packet, sizeof(_dcd.setup_packet));
327338
}

0 commit comments

Comments
 (0)