summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorhathach <[email protected]>2025-04-18 16:17:35 +0700
committerhathach <[email protected]>2025-04-18 16:17:35 +0700
commit1b888a3311f1c722978d3bcb8ee0f5d5d4debd55 (patch)
treeabf32bfef0be0feea693d3965d287bc1ebd6184e /src
parent62d06e7b19d82dbbc3d1089b249913c13eb7fc2a (diff)
clean up, remove halted_sof_schedule flags since channel_xfer_in_retry() is only called when channel is halted.
Diffstat (limited to 'src')
-rw-r--r--src/portable/synopsys/dwc2/hcd_dwc2.c48
1 files changed, 20 insertions, 28 deletions
diff --git a/src/portable/synopsys/dwc2/hcd_dwc2.c b/src/portable/synopsys/dwc2/hcd_dwc2.c
index d2070e57c..a95cc5e10 100644
--- a/src/portable/synopsys/dwc2/hcd_dwc2.c
+++ b/src/portable/synopsys/dwc2/hcd_dwc2.c
@@ -95,7 +95,6 @@ typedef struct {
uint8_t err_count : 3;
uint8_t period_split_nyet_count : 3;
uint8_t halted_nyet : 1;
- uint8_t halted_sof_schedule : 1;
};
uint8_t result;
@@ -713,19 +712,21 @@ bool hcd_edpt_clear_stall(uint8_t rhport, uint8_t dev_addr, uint8_t ep_addr) {
//--------------------------------------------------------------------
// HCD Event Handler
//--------------------------------------------------------------------
+
+// retry an IN transfer, channel must be halted
static void channel_xfer_in_retry(dwc2_regs_t* dwc2, uint8_t ch_id, uint32_t hcint) {
hcd_xfer_t* xfer = &_hcd_data.xfer[ch_id];
- dwc2_channel_t* channel = &dwc2->channel[ch_id];
hcd_endpoint_t* edpt = &_hcd_data.edpt[xfer->ep_id];
+ dwc2_channel_t* channel = &dwc2->channel[ch_id];
+ dwc2_channel_char_t hcchar = {.value = channel->hcchar};
- if (channel_is_periodic(channel->hcchar)){
+ if (channel_is_periodic(hcchar.value)){
const dwc2_channel_split_t hcsplt = {.value = channel->hcsplt};
// retry immediately for periodic split NYET if we haven't reach max retry
if (hcsplt.split_en && hcsplt.split_compl && (hcint & HCINT_NYET || xfer->halted_nyet)) {
xfer->period_split_nyet_count++;
xfer->halted_nyet = 0;
if (xfer->period_split_nyet_count < HCD_XFER_PERIOD_SPLIT_NYET_MAX) {
- dwc2_channel_char_t hcchar = {.value = channel->hcchar};
hcchar.odd_frame = 1 - (dwc2->hfnum & 1); // transfer on next frame
channel->hcchar = hcchar.value;
channel_send_in_token(dwc2, channel);
@@ -736,26 +737,20 @@ static void channel_xfer_in_retry(dwc2_regs_t* dwc2, uint8_t ch_id, uint32_t hci
}
}
- if (hcint & HCINT_HALTED) {
- 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);
- }
+ const uint32_t ucount = (hprt_speed_get(dwc2) == TUSB_SPEED_HIGH ? 1 : 8);
+ if (edpt->uframe_interval == ucount) {
+ // retry on next frame if bInterval is 1
+ hcchar.odd_frame = 1 - (dwc2->hfnum & 1);
+ channel->hcchar = hcchar.value;
+ channel_send_in_token(dwc2, channel);
} else {
- // disable channel first if not halted (called slave isr)
- xfer->halted_sof_schedule = 1;
- channel_disable(dwc2, channel);
+ // 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 {
// for control/bulk: retry immediately
@@ -905,7 +900,7 @@ static bool handle_channel_in_slave(dwc2_regs_t* dwc2, uint8_t ch_id, uint32_t h
xfer->halted_nyet = 1;
channel_disable(dwc2, channel);
} else if (hcint & HCINT_NAK) {
- // NAK received, re-enable channel if request queue is available
+ // NAK received, disable channel to flush all posted request and try again
if (hcsplt.split_en) {
hcsplt.split_compl = 0; // restart with start-split
channel->hcsplt = hcsplt.value;
@@ -937,10 +932,7 @@ static bool handle_channel_in_slave(dwc2_regs_t* dwc2, uint8_t ch_id, uint32_t h
}
} else if (hcint & HCINT_HALTED) {
channel->hcintmsk &= ~HCINT_HALTED;
- if (xfer->halted_sof_schedule) {
- // de-allocate channel but does not complete xfer, we schedule it in the SOF interrupt
- channel_dealloc(dwc2, ch_id);
- } else if (xfer->result != XFER_RESULT_INVALID) {
+ if (xfer->result != XFER_RESULT_INVALID) {
is_done = true;
} else if (xfer->err_count == HCD_XFER_ERROR_MAX) {
xfer->result = XFER_RESULT_FAILED;