@@ -102,6 +102,7 @@ void rp2usb_init(void) {
102102
103103void __tusb_irq_path_func (rp2usb_reset_transfer )(hw_endpoint_t * ep ) {
104104 ep -> active = false;
105+ ep -> pending = 0 ;
105106 ep -> remaining_len = 0 ;
106107 ep -> xferred_len = 0 ;
107108 ep -> user_buf = 0 ;
@@ -172,9 +173,8 @@ uint16_t __tusb_irq_path_func(bufctrl_prepare16)(hw_endpoint_t *ep, uint8_t *dpr
172173 buf_ctrl |= USB_BUF_CTRL_FULL ;
173174 }
174175
175- // Is this the last buffer? Only really matters for host mode. Will trigger
176- // the trans complete irq but also stop it polling. We only really care about
177- // trans complete for setup packets being sent
176+ // Is this the last buffer? Will trigger the trans complete irq but also stop it polling.
177+ // This is used to detect setup packets being sent in host mode
178178 if (ep -> remaining_len == 0 ) {
179179 buf_ctrl |= USB_BUF_CTRL_LAST ;
180180 }
@@ -349,7 +349,7 @@ bool __tusb_irq_path_func(rp2usb_xfer_continue)(hw_endpoint_t *ep, io_rw_32 *ep_
349349 uint8_t * dpram_buf = ep -> dpram_buf ;
350350 if (buf_id ) {
351351 #if CFG_TUSB_RP2_ERRATA_E4
352- if (!(is_host && !is_double )) // incorrect buf_id, buffer data is still buf0
352+ if (!(is_host && !is_double )) // E4 bug: incorrect buf_id, buffer data is still buf0
353353 #endif
354354 {
355355 dpram_buf += 64 ; // buf1 offset
@@ -370,54 +370,51 @@ bool __tusb_irq_path_func(rp2usb_xfer_continue)(hw_endpoint_t *ep, io_rw_32 *ep_
370370 // Note: Host mode current does not save next transfer data due to shared epx --> potential issue. However, RP2040-E4
371371 // causes more or less of the same issue since it write to buf1 and next time it continues to transfer on buf0 (stale)
372372 if (is_short && is_double && is_rx && !is_last ) {
373- #if CFG_TUH_ENABLED
373+ const uint32_t abort_bit = TU_BIT (tu_edpt_number (ep -> ep_addr ) << 1 ); // abort is device only -> IN endpoint
374+
374375 if (is_host ) {
375- // stop current transfer
376- uint32_t sie_ctrl = usb_hw -> sie_ctrl & SIE_CTRL_BASE_MASK ;
377- sie_ctrl |= USB_SIE_CTRL_STOP_TRANS_BITS ;
376+ // host stop current transfer, not safe, can be racing
377+ const uint32_t sie_ctrl = (usb_hw -> sie_ctrl & SIE_CTRL_BASE_MASK ) | USB_SIE_CTRL_STOP_TRANS_BITS ;
378378 usb_hw -> sie_ctrl = sie_ctrl ;
379- // maybe wait until STOP_TRANS bit is clear
380-
381- * buf_reg = 0 ; // reset buffer control
382- }
383- #endif
384-
385- #if CFG_TUD_ENABLED
386- if (!is_host ) {
387- io_rw_16 * buf_reg16_other = buf_reg16 + (buf_id ^ 1 );
388- const uint32_t abort_bit = TU_BIT (tu_edpt_number (ep -> ep_addr ) << 1 ); // IN endpoint
389-
390- #if CFG_TUSB_RP2_ERRATA_E2
379+ while (usb_hw -> sie_ctrl & USB_SIE_CTRL_STOP_TRANS_BITS ) {}
380+ } else {
381+ // device abort current transfer
382+ #if CFG_TUSB_RP2_ERRATA_E2
391383 if (rp2040_chipversion >= 2 )
392- #endif
384+ #endif
393385 {
394386 usb_hw_set -> abort = abort_bit ;
395387 while ((usb_hw -> abort_done & abort_bit ) != abort_bit ) {}
396388 }
389+ }
397390
398- // After abort, check if the other buffer received valid data
399- const uint16_t buf_ctrl16_other = * buf_reg16_other ;
400- if ( buf_ctrl16_other & USB_BUF_CTRL_FULL ) {
401- // Host already sent data into this buffer (e.g. write payload right after short CBW).
402- // Save it for the next transfer.
403- ep -> future_len = ( uint8_t )( buf_ctrl16_other & USB_BUF_CTRL_LEN_MASK );
404- ep -> future_bufid = buf_id ^ 1 ;
405- // buff_status will be clear by the next run
391+ // After abort, check if the other buffer received valid data
392+ io_rw_16 * buf_reg16_other = buf_reg16 + ( buf_id ^ 1 ) ;
393+ const uint16_t buf_ctrl16_other = * buf_reg16_other ;
394+ if ( buf_ctrl16_other & USB_BUF_CTRL_FULL ) {
395+ // Data already sent into this buffer. Save it for the next transfer.
396+ // buff_status will be clear by the next run
397+ if ( is_host ) {
398+ // host put future_len pointer at end of epx_data
406399 } else {
407- ep -> next_pid ^= 1u ; // roll back pid if aborted
400+ ep -> future_len = ( uint8_t )( buf_ctrl16_other & USB_BUF_CTRL_LEN_MASK );
408401 }
402+ ep -> future_bufid = buf_id ^ 1 ;
403+ } else {
404+ ep -> next_pid ^= 1u ; // roll back pid if aborted
405+ }
409406
410- * buf_reg = 0 ; // reset buffer control
407+ * buf_reg = 0 ; // reset buffer control
411408
412- #if CFG_TUSB_RP2_ERRATA_E2
409+ if (!is_host ) {
410+ #if CFG_TUSB_RP2_ERRATA_E2
413411 if (rp2040_chipversion >= 2 )
414- #endif
412+ #endif
415413 {
416414 usb_hw_clear -> abort_done = abort_bit ;
417415 usb_hw_clear -> abort = abort_bit ;
418416 }
419417 }
420- #endif
421418
422419 hw_endpoint_lock_update (ep , -1 );
423420 return true;
0 commit comments