2121#include "usb_rx.pio.h"
2222#include "usb_tx.pio.h"
2323
24+ enum {
25+ TRANSACTION_MAX_RETRY = 3 , // Number of times to retry a failed transaction
26+ };
27+
2428static alarm_pool_t * _alarm_pool = NULL ;
2529static repeating_timer_t sof_rt ;
2630// The sof_count may be incremented and then read on different cores.
@@ -535,7 +539,14 @@ static int __no_inline_not_in_flash_func(usb_in_transaction)(pio_port_t *pp,
535539 if ((pp -> pio_usb_rx -> irq & IRQ_RX_COMP_MASK ) == 0 ) {
536540 res = -2 ;
537541 }
538- pio_usb_ll_transfer_complete (ep , PIO_USB_INTS_ENDPOINT_ERROR_BITS );
542+
543+ if (++ ep -> failed_count >= TRANSACTION_MAX_RETRY ) {
544+ pio_usb_ll_transfer_complete (ep , PIO_USB_INTS_ENDPOINT_ERROR_BITS ); // failed after 3 consecutive retries
545+ }
546+ }
547+
548+ if (res == 0 ) {
549+ ep -> failed_count = 0 ; // reset failed count if we got a sound response
539550 }
540551
541552 pio_sm_set_enabled (pp -> pio_usb_rx , pp -> sm_rx , false);
@@ -569,7 +580,14 @@ static int __no_inline_not_in_flash_func(usb_out_transaction)(pio_port_t *pp,
569580 } else if (receive_token == USB_PID_STALL ) {
570581 pio_usb_ll_transfer_complete (ep , PIO_USB_INTS_ENDPOINT_STALLED_BITS );
571582 } else {
572- pio_usb_ll_transfer_complete (ep , PIO_USB_INTS_ENDPOINT_ERROR_BITS );
583+ res = -1 ;
584+ if (++ ep -> failed_count >= TRANSACTION_MAX_RETRY ) {
585+ pio_usb_ll_transfer_complete (ep , PIO_USB_INTS_ENDPOINT_ERROR_BITS );
586+ }
587+ }
588+
589+ if (res == 0 ) {
590+ ep -> failed_count = 0 ;// reset failed count if we got a sound response
573591 }
574592
575593 pio_sm_set_enabled (pp -> pio_usb_rx , pp -> sm_rx , false);
@@ -581,7 +599,6 @@ static int __no_inline_not_in_flash_func(usb_out_transaction)(pio_port_t *pp,
581599
582600static int __no_inline_not_in_flash_func (usb_setup_transaction )(
583601 pio_port_t * pp , endpoint_t * ep ) {
584-
585602 int res = 0 ;
586603
587604 // Setup token
@@ -598,13 +615,19 @@ static int __no_inline_not_in_flash_func(usb_setup_transaction)(
598615 pio_usb_bus_wait_handshake (pp );
599616 pio_sm_set_enabled (pp -> pio_usb_rx , pp -> sm_rx , false);
600617
601- ep -> actual_len = 8 ;
602-
603618 if (pp -> usb_rx_buffer [0 ] == USB_SYNC && pp -> usb_rx_buffer [1 ] == USB_PID_ACK ) {
619+ ep -> actual_len = 8 ;
604620 pio_usb_ll_transfer_complete (ep , PIO_USB_INTS_ENDPOINT_COMPLETE_BITS );
605621 } else {
606622 res = -1 ;
607- pio_usb_ll_transfer_complete (ep , PIO_USB_INTS_ENDPOINT_ERROR_BITS );
623+ ep -> data_id = USB_PID_SETUP ; // retry setup
624+ if (++ ep -> failed_count >= TRANSACTION_MAX_RETRY ) {
625+ pio_usb_ll_transfer_complete (ep , PIO_USB_INTS_ENDPOINT_ERROR_BITS );
626+ }
627+ }
628+
629+ if (res == 0 ) {
630+ ep -> failed_count = 0 ;// reset failed count if we got a sound response
608631 }
609632
610633 pp -> usb_rx_buffer [1 ] = 0 ; // reset buffer
0 commit comments