From 62d06e7b19d82dbbc3d1089b249913c13eb7fc2a Mon Sep 17 00:00:00 2001 From: Maxime Vincent Date: Mon, 14 Apr 2025 09:24:54 +0200 Subject: [PATCH] dwc2/host: fix all retry intervals Signed-off-by: Maxime Vincent --- src/portable/synopsys/dwc2/hcd_dwc2.c | 31 +++++++++++++-------------- 1 file changed, 15 insertions(+), 16 deletions(-) diff --git a/src/portable/synopsys/dwc2/hcd_dwc2.c b/src/portable/synopsys/dwc2/hcd_dwc2.c index 6e2737afd..d2070e57c 100644 --- a/src/portable/synopsys/dwc2/hcd_dwc2.c +++ b/src/portable/synopsys/dwc2/hcd_dwc2.c @@ -736,23 +736,22 @@ static void channel_xfer_in_retry(dwc2_regs_t* dwc2, uint8_t ch_id, uint32_t hci } } - // immediately retry if bInterval is 1 - otherwise we'd waste a microframe before retrying - if ((hcint & HCINT_HALTED) && (edpt->uframe_interval == 1)) { - edpt->hcchar_bm.odd_frame = 1 - (dwc2->hfnum & 1); // transfer on next frame - channel->hcchar = (edpt->hcchar & ~HCCHAR_CHENA); - channel_send_in_token(dwc2, channel); - return; - } - - // for periodic, de-allocate channel, enable SOF set frame counter for later transfer - const dwc2_channel_tsize_t hctsiz = {.value = channel->hctsiz}; - edpt->next_pid = hctsiz.pid; // save PID - edpt->uframe_countdown = edpt->uframe_interval; - dwc2->gintmsk |= GINTSTS_SOF; - if (hcint & HCINT_HALTED) { - // already halted, de-allocate channel (called from DMA isr) - channel_dealloc(dwc2, ch_id); + const uint32_t ucount = (hprt_speed_get(dwc2) == TUSB_SPEED_HIGH ? 1 : 8); + if (edpt->uframe_interval == ucount) { + // immediately retry if bInterval is 1 + edpt->hcchar_bm.odd_frame = 1 - (dwc2->hfnum & 1); // transfer on next frame + channel->hcchar = (edpt->hcchar & ~HCCHAR_CHENA); + channel_send_in_token(dwc2, channel); + } else { + // otherwise, de-allocate channel, enable SOF set frame counter for later transfer + const dwc2_channel_tsize_t hctsiz = {.value = channel->hctsiz}; + edpt->next_pid = hctsiz.pid; // save PID + edpt->uframe_countdown = edpt->uframe_interval - ucount; + dwc2->gintmsk |= GINTSTS_SOF; + // already halted, de-allocate channel (called from DMA isr) + channel_dealloc(dwc2, ch_id); + } } else { // disable channel first if not halted (called slave isr) xfer->halted_sof_schedule = 1;