summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorHiFiPHile <[email protected]>2026-09-02 16:18:44 +0200
committerHiFiPHile <[email protected]>2026-09-02 16:18:44 +0200
commite461c6f9c139a0012ef01d53db1aab1c68789b56 (patch)
treea0139e6458fc3d5d13670920ee9529cc0a9349d5
parent14060950b487f931d959699c42b0875c96ca6a01 (diff)
fix(dwc2): bound periodic intervals to HFNUM range
HFNUM retains only 16384 host-frame positions, while valid periodic endpoint intervals can be longer. Resubmission after the counter wraps can therefore alias the elapsed time and skip the next established service phase. Cap the host-selected interval to one HFNUM cycle using the root-port frame unit. USB permits a shorter host-provided period, and the bounded interval keeps phase calculation unambiguous for native and split endpoints.
-rw-r--r--src/portable/synopsys/dwc2/hcd_dwc2.c10
1 files changed, 9 insertions, 1 deletions
diff --git a/src/portable/synopsys/dwc2/hcd_dwc2.c b/src/portable/synopsys/dwc2/hcd_dwc2.c
index 2055b320b..5a171f80e 100644
--- a/src/portable/synopsys/dwc2/hcd_dwc2.c
+++ b/src/portable/synopsys/dwc2/hcd_dwc2.c
@@ -44,7 +44,8 @@ enum {
enum {
HCD_XFER_PERIOD_SPLIT_NYET_MAX = 3,
- HCD_FRAME_NUMBER_MASK = 0x3fff
+ HCD_FRAME_NUMBER_MASK = 0x3fff,
+ HCD_FRAME_COUNT = HCD_FRAME_NUMBER_MASK + 1
};
//--------------------------------------------------------------------
@@ -652,6 +653,13 @@ bool hcd_edpt_open(uint8_t rhport, uint8_t dev_addr, const tusb_desc_endpoint_t*
break;
}
+ if (channel_is_periodic(edpt->hcchar)) {
+ // HFNUM cannot distinguish elapsed periods longer than one counter cycle. USB permits the host to provide a
+ // shorter period, so bound the selected period to the history available from HFNUM.
+ const uint32_t ucount = (rh_speed == TUSB_SPEED_HIGH) ? 1u : 8u;
+ edpt->uframe_interval = tu_min32(edpt->uframe_interval, HCD_FRAME_COUNT * ucount);
+ }
+
return true;
}