@@ -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