diff options
| author | Mikey Sklar <[email protected]> | 2026-06-30 10:06:38 -0700 |
|---|---|---|
| committer | hathach <[email protected]> | 2026-07-01 16:07:59 +0700 |
| commit | f96757a19af640b14c272945b2272540c4af1cc4 (patch) | |
| tree | 4dbcf4b8956d054f1967ba9ef30cce0afeac4abf | |
| parent | dae3f9a366bfcddbf9dcf1b48d7500286a849539 (diff) | |
max3421: prevent USB host hang at startup
On some boards the MAX3421E doesn't report its oscillator ready after a
soft reset (CHIPRES), so hcd_init() waits on USBIRQ_OSCOK forever and the
host hangs at startup before any USB device can be used. Bound the wait so
it proceeds after a timeout; it is a no-op where OSCOK arrives normally.
Needed on the Adafruit Feather ESP32 V2 (classic ESP32) + USB Host
FeatherWing, which otherwise hangs on essentially every cold boot.
Relates to adafruit/circuitpython#10053.
| -rw-r--r-- | src/portable/analog/max3421/hcd_max3421.c | 9 |
1 files changed, 8 insertions, 1 deletions
diff --git a/src/portable/analog/max3421/hcd_max3421.c b/src/portable/analog/max3421/hcd_max3421.c index 971dbd62e..621d0d86c 100644 --- a/src/portable/analog/max3421/hcd_max3421.c +++ b/src/portable/analog/max3421/hcd_max3421.c @@ -504,8 +504,15 @@ bool hcd_init(uint8_t rhport, const tusb_rhport_init_t* rh_init) { // reset reg_write(rhport, USBCTL_ADDR, USBCTL_CHIPRES, false); reg_write(rhport, USBCTL_ADDR, 0, false); + // Bound the oscillator-OK wait. On boards where the MAX3421E is only + // soft-reset (CHIPRES) rather than hardware-reset via nRST, OSCOK may never + // latch, which would otherwise hang the host forever (adafruit/circuitpython#10053). + // The oscillator is generally running regardless, so proceed after a timeout. + uint32_t oscok_retries = 200000; while( !(reg_read(rhport, USBIRQ_ADDR, false) & USBIRQ_OSCOK_IRQ) ) { - // wait for oscillator to stabilize + if (--oscok_retries == 0) { + break; + } } // Mode: Host and DP/DM pull down |
