@@ -650,15 +650,13 @@ bool dcd_edpt_xfer(uint8_t rhport, uint8_t ep_addr, uint8_t* buffer, uint16_t to
650650 xfer -> buffer = buffer ;
651651 xfer -> ff = NULL ;
652652 xfer -> total_len = total_bytes ;
653+ xfer -> iso_retry = xfer -> interval ; // Reset ISO retry counter to interval value
653654
654655 // EP0 can only handle one packet
655656 if (epnum == 0 ) {
656657 _dcd_data .ep0_pending [dir ] = total_bytes ;
657658 }
658659
659- // Reset ISO retry counter to interval value
660- xfer -> iso_retry = xfer -> interval ;
661-
662660 // Schedule packets to be sent within interrupt
663661 edpt_schedule_packets (rhport , epnum , dir );
664662 ret = true;
@@ -690,9 +688,7 @@ bool dcd_edpt_xfer_fifo(uint8_t rhport, uint8_t ep_addr, tu_fifo_t* ff, uint16_t
690688 xfer -> buffer = NULL ;
691689 xfer -> ff = ff ;
692690 xfer -> total_len = total_bytes ;
693-
694- // Reset ISO retry counter to interval value
695- xfer -> iso_retry = xfer -> interval ;
691+ xfer -> iso_retry = xfer -> interval ; // Reset ISO retry counter to interval value
696692
697693 // Schedule packets to be sent within interrupt
698694 // TODO xfer fifo may only available for slave mode
@@ -1070,6 +1066,43 @@ static void handle_ep_irq(uint8_t rhport, uint8_t dir) {
10701066 }
10711067}
10721068
1069+ static void handle_incomplete_iso_in (uint8_t rhport ) {
1070+ dwc2_regs_t * dwc2 = DWC2_REG (rhport );
1071+ const dwc2_dsts_t dsts = {.value = dwc2 -> dsts };
1072+ const uint32_t odd_now = dsts .frame_number & 1u ;
1073+
1074+ // Loop over all IN endpoints
1075+ const uint8_t ep_count = dwc2_ep_count (dwc2 );
1076+ for (uint8_t epnum = 0 ; epnum < ep_count ; epnum ++ ) {
1077+ dwc2_dep_t * epin = & dwc2 -> epin [epnum ];
1078+ dwc2_depctl_t depctl = {.value = epin -> diepctl };
1079+ // Read DSTS and DIEPCTLn for all isochronous endpoints. If the current EP is enabled and the read value of
1080+ // DSTS.SOFFN is the targeted uframe number for this EP, then this EP has an incomplete transfer.
1081+ if (depctl .enable && depctl .type == DEPCTL_EPTYPE_ISOCHRONOUS && depctl .dpid_iso_odd == odd_now ) {
1082+ xfer_ctl_t * xfer = XFER_CTL_BASE (epnum , TUSB_DIR_IN );
1083+ if (xfer -> iso_retry > 0 ) {
1084+ xfer -> iso_retry -- ;
1085+ // Restart ISO transfe: re-write TSIZ and CTL
1086+ dwc2_ep_tsize_t deptsiz = {.value = 0 };
1087+ deptsiz .xfer_size = xfer -> total_len ;
1088+ deptsiz .packet_count = tu_div_ceil (xfer -> total_len , xfer -> max_size );
1089+ epin -> tsiz = deptsiz .value ;
1090+
1091+ if (odd_now ) {
1092+ depctl .set_data0_iso_even = 1 ;
1093+ } else {
1094+ depctl .set_data1_iso_odd = 1 ;
1095+ }
1096+ epin -> diepctl = depctl .value ;
1097+ } else {
1098+ // too many retries, give up
1099+ edpt_disable (rhport , epnum | TUSB_DIR_IN_MASK , false);
1100+ dcd_event_xfer_complete (rhport , epnum | TUSB_DIR_IN_MASK , 0 , XFER_RESULT_FAILED , true);
1101+ }
1102+ }
1103+ }
1104+ }
1105+
10731106/* Interrupt Hierarchy
10741107 DIEPINT DIEPINT
10751108 \ /
@@ -1173,38 +1206,7 @@ void dcd_int_handler(uint8_t rhport) {
11731206 // Incomplete isochronous IN transfer interrupt handling.
11741207 if (gintsts & GINTSTS_IISOIXFR ) {
11751208 dwc2 -> gintsts = GINTSTS_IISOIXFR ;
1176- const dwc2_dsts_t dsts = {.value = dwc2 -> dsts };
1177- const uint32_t odd_now = dsts .frame_number & 1u ;
1178- // Loop over all IN endpoints
1179- const uint8_t ep_count = dwc2_ep_count (dwc2 );
1180- for (uint8_t epnum = 0 ; epnum < ep_count ; epnum ++ ) {
1181- dwc2_dep_t * epin = & dwc2 -> epin [epnum ];
1182- dwc2_depctl_t depctl = {.value = epin -> diepctl };
1183- // Read DSTS and DIEPCTLn for all isochronous endpoints. If the current EP is enabled
1184- // and the read value of DSTS.SOFFN is the targeted uframe number for this EP, then
1185- // this EP has an incomplete transfer.
1186- if (depctl .enable && depctl .type == DEPCTL_EPTYPE_ISOCHRONOUS && depctl .dpid_iso_odd == odd_now ) {
1187- xfer_ctl_t * xfer = XFER_CTL_BASE (epnum , TUSB_DIR_IN );
1188- if (xfer -> iso_retry ) {
1189- xfer -> iso_retry -- ;
1190- // Restart ISO transfer
1191- dwc2_ep_tsize_t deptsiz = {.value = 0 };
1192- deptsiz .xfer_size = xfer -> total_len ;
1193- deptsiz .packet_count = tu_div_ceil (xfer -> total_len , xfer -> max_size );
1194- epin -> tsiz = deptsiz .value ;
1195- if (odd_now ) {
1196- depctl .set_data0_iso_even = 1 ;
1197- } else {
1198- depctl .set_data1_iso_odd = 1 ;
1199- }
1200- epin -> diepctl = depctl .value ;
1201- } else {
1202- // too many retries, give up
1203- edpt_disable (rhport , epnum | TUSB_DIR_IN_MASK , false);
1204- dcd_event_xfer_complete (rhport , epnum | TUSB_DIR_IN_MASK , 0 , XFER_RESULT_FAILED , true);
1205- }
1206- }
1207- }
1209+ handle_incomplete_iso_in (rhport );
12081210 }
12091211}
12101212
0 commit comments