Skip to content

Commit bd96c74

Browse files
committed
tune TinyUSB fail wait delay to 15ms
Previously, I used a 50ms delay after hitting a TinyUSB tuh_* API call failure result to have a big safety margin. But, that seems long enough that it might mess up animation loops. So, I tried many builds with delays between 0ms and 20ms, testing unplug detection with my big pile of USB devices. A 15ms delay worked fine with everything I tried. My Full Speed devices were marginal down to 13ms, but they stopped working at 12ms. Some of my Low Speed devices were okay down to 3ms, but the Adafruit generic SNES gamepad was marginal below 12ms.
1 parent f1ad79b commit bd96c74

File tree

2 files changed

+18
-4
lines changed

2 files changed

+18
-4
lines changed

shared-module/usb/core/Device.c

Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -69,10 +69,17 @@ void common_hal_usb_core_device_deinit(usb_core_device_obj_t *self) {
6969
}
7070

7171
static void _wait_then_raise_USBError(int errno) {
72-
// 1. Spin for 50 ms in a background task loop because some USB glitches
73-
// will magically clear up if you just wait for a bit
74-
// 2. Raise the exception so the calling code knows it needs to try again
75-
const uint32_t end = supervisor_ticks_ms32() + 50;
72+
// 1. Spin briefly in background task loop because this seems to fix the
73+
// enumeration or addressing glitch that can cause tuh_* calls to fail after
74+
// a device is unplugged. Don't know why this works, but things magically
75+
// self correct if you just wait for a bit before attempting another control
76+
// transfer.
77+
// 2. Raise the exception so the calling code knows it needs to try again.
78+
//
79+
// TODO: Consider removing this mechanism if somebody finds and fixes whatever is
80+
// causing TinyUSB to get confused about unplugged devices.
81+
//
82+
const uint32_t end = supervisor_ticks_ms32() + USB_CORE_TUH_FAIL_WAIT_MS;
7683
while (supervisor_ticks_ms32() < end && !mp_hal_is_interrupted()) {
7784
RUN_BACKGROUND_TASKS;
7885
}

shared-module/usb/core/Device.h

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,13 @@ typedef struct {
1919
} usb_core_device_obj_t;
2020

2121

22+
// Number of ms to wait in a background task loop after a TinyUSB tuh_* api call
23+
// returns a failure result. This delay is part of a kludge to help TinyUSB
24+
// recognize when a device has been unplugged. Without the delay, usb.core.find()
25+
// can get super broken. This mechanism can be removed once somebody finds and
26+
// fixes whatever is causing TinyUSB to get confused about unplugged devices.
27+
#define USB_CORE_TUH_FAIL_WAIT_MS (15)
28+
2229
// These values get used to set USBError.errno and USBTimeoutError.errno.
2330
// It would be possible to define these to more closely mimic desktop PyUSB on
2431
// a given OS (maybe Debian?). But, for USB error handling in CircuitPython,

0 commit comments

Comments
 (0)