@@ -75,9 +75,9 @@ typedef struct {
7575
7676 struct TU_ATTR_PACKED {
7777 uint32_t uframe_interval : 18 ; // micro-frame interval
78- uint32_t speed : 2 ;
79- uint32_t next_pid : 2 ;
80- uint32_t do_ping : 1 ;
78+ uint32_t speed : 2 ;
79+ uint32_t next_pid : 2 ; // PID for next transfer
80+ uint32_t next_do_ping : 1 ; // Do PING for next transfer if possible (highspeed OUT)
8181 // uint32_t : 9;
8282 };
8383
@@ -567,12 +567,12 @@ static bool channel_xfer_start(dwc2_regs_t* dwc2, uint8_t ch_id) {
567567 hctsiz .pid = edpt -> next_pid ; // next PID is set in transfer complete interrupt
568568 hctsiz .packet_count = packet_count ;
569569 hctsiz .xfer_size = edpt -> buflen ;
570- if (edpt -> do_ping && edpt -> speed == TUSB_SPEED_HIGH &&
570+ if (edpt -> next_do_ping && edpt -> speed == TUSB_SPEED_HIGH &&
571571 edpt -> next_pid != HCTSIZ_PID_SETUP && hcchar_bm -> ep_dir == TUSB_DIR_OUT ) {
572572 hctsiz .do_ping = 1 ;
573573 }
574574 channel -> hctsiz = hctsiz .value ;
575- edpt -> do_ping = 0 ;
575+ edpt -> next_do_ping = 0 ;
576576
577577 // pre-calculate next PID based on packet count, adjusted in transfer complete interrupt if short packet
578578 if (hcchar_bm -> ep_num == 0 ) {
@@ -603,7 +603,7 @@ static bool channel_xfer_start(dwc2_regs_t* dwc2, uint8_t ch_id) {
603603 hcintmsk |= HCINT_BABBLE_ERR | HCINT_DATATOGGLE_ERR | HCINT_ACK ;
604604 } else {
605605 hcintmsk |= HCINT_NYET ;
606- if (edpt -> hcsplt_bm .split_en ) {
606+ if (edpt -> hcsplt_bm .split_en || hctsiz . do_ping ) {
607607 hcintmsk |= HCINT_ACK ;
608608 }
609609 }
@@ -959,6 +959,10 @@ static bool handle_channel_out_slave(dwc2_regs_t* dwc2, uint8_t ch_id, uint32_t
959959 is_done = true;
960960 xfer -> result = XFER_RESULT_SUCCESS ;
961961 channel -> hcintmsk &= ~HCINT_ACK ;
962+ if (hcint & HCINT_NYET ) {
963+ // complete transfer with NYET, do ping next time
964+ edpt -> next_do_ping = 1 ;
965+ }
962966 } else if (hcint & HCINT_STALL ) {
963967 xfer -> result = XFER_RESULT_STALLED ;
964968 channel_disable (dwc2 , channel );
@@ -970,7 +974,7 @@ static bool handle_channel_out_slave(dwc2_regs_t* dwc2, uint8_t ch_id, uint32_t
970974 channel -> hcsplt = hcsplt .value ;
971975 channel -> hcchar |= HCCHAR_CHENA ;
972976 } else {
973- edpt -> do_ping = 1 ;
977+ edpt -> next_do_ping = 1 ;
974978 channel_xfer_out_wrapup (dwc2 , ch_id );
975979 channel_disable (dwc2 , channel );
976980 }
@@ -983,7 +987,7 @@ static bool handle_channel_out_slave(dwc2_regs_t* dwc2, uint8_t ch_id, uint32_t
983987 channel -> hcintmsk |= HCINT_ACK ;
984988 } else {
985989 // NAK disable channel to flush all posted request and try again
986- edpt -> do_ping = 1 ;
990+ edpt -> next_do_ping = 1 ;
987991 xfer -> err_count = 0 ;
988992 }
989993 } else if (hcint & HCINT_HALTED ) {
@@ -1000,10 +1004,17 @@ static bool handle_channel_out_slave(dwc2_regs_t* dwc2, uint8_t ch_id, uint32_t
10001004 } else if (hcint & HCINT_ACK ) {
10011005 xfer -> err_count = 0 ;
10021006 channel -> hcintmsk &= ~HCINT_ACK ;
1003- if (hcsplt .split_en && !hcsplt .split_compl ) {
1004- // start split is ACK --> do complete split
1005- hcsplt .split_compl = 1 ;
1006- channel -> hcsplt = hcsplt .value ;
1007+ if (hcsplt .split_en ) {
1008+ if (!hcsplt .split_compl ) {
1009+ // ACK for start split --> do complete split
1010+ hcsplt .split_compl = 1 ;
1011+ channel -> hcsplt = hcsplt .value ;
1012+ channel -> hcchar |= HCCHAR_CHENA ;
1013+ }
1014+ } else {
1015+ // ACK interrupt is only enabled for Split and PING
1016+ // ACK for PING, which mean device is ready to receive data
1017+ channel -> hctsiz &= ~HCTSIZ_DOPING ; // HC already cleared PING bit, but we clear anyway
10071018 channel -> hcchar |= HCCHAR_CHENA ;
10081019 }
10091020 }
0 commit comments