← index #18098PR #17913
Related · medium · value 1.238
QUERY · ISSUE

USB HID device on ESP32 has a problem!

openby ThomasAtBBTFopened 2025-09-19updated 2025-09-19
bug

Port, board and/or hardware

ESP32S3

MicroPython version

I created an issue on USB-LIB but I think the problem must be solved here...
https://github.com/micropython/micropython-lib/issues/1044

Reproduction

The code for reproducing the problem has been tried on MicroPython 1.26.1 and also on the new 1.27 releases.

It is not ESP board related. I tried the examples on different boards with different MicroPython versions.

I can also share Wireshark logs if necessary, but the bug is easily reproducible with the unmodified USB HID device samples from the lib directory.

Expected behaviour

The samples should "just work" also for the ESP32S3 boards.

Observed behaviour

The LED out reports are arriving nicely in the code, but all keystrokes that are sent are arriving with all bytes "zero" at the host. (Confirmed by Wireshark )

Additional Information

See the debug code changes documented in the original lib-issue!

Code of Conduct

Yes, I agree

CANDIDATE · PULL REQUEST

esp32/esp32_common.cmake: Switch back to the vendored TinyUSB copy.

closedby agattiopened 2025-08-13updated 2025-08-29
port-esp32

Summary

This PR reverts d7371124d288cc85d2386b63ea39cfa4fa803194, fixing USB issues reported by macOS users on ESP32S2/ESP32S3 boards.

The commit's intention was to rely on the TinyUSB tree provided by Espressif as a dependency of their USB support library (so maintenance and other bug fixes would come from them rather than from MicroPython).

However, this seems to have opened a Pandora's box of incompatibilities triggered by macOS's USB stack behaviour (see discussion #17465 and issues #17560 and #17865).

Whilst this may look like a permanent solution, it is not. There are some important race condition fixes added in Espressif's patched USB code that are not available in MicroPython's TinyUSB copy (along other bug fixes and feature additions). Still, cutting macOS users out of their boards probably isn't the best thing to do.

Testing

Before this change, copying a file to the board from a macOS machine via USB using mpremote would fail either on the first or on the second iteration.

With this change applied, repeated copies to and from an ESP32S3-DevKitC-R8N16 succeed without problems.

Trade-offs and Alternatives

The only trade-off I can see right now is that by reverting to that particular TinyUSB version we're missing on race condition fixes being added both by the TinyUSB authors and by Espressif.

Alternatives? Where to start... There seems to be a bunch of incompatibilities manifesting at the same time only in a very specific situation:

  • This is triggered by macOS's USB stack, things seem to be fine on Linux and Windows
  • The issue shows up as either losing data and deadlocking TinyUSB, not deadlocking anything but silently duplicating data instead, or just hang on the REPL when printing the help message; the whole lot seems to be board-dependent to a certain extent
  • By forcing different versions of the espressif/esp_tinyusb and espressif/tinyusb components in ports/esp32/main/idf_component.yml things seem to be fixed for some users although with the same versions set I could still get my board to lock up during a stress test
  • When letting espressif/tinyusb match the version of what's present in lib/tinyusb, the issue still appears - so this seems related to espressif/esp_tinyusb instead, but again, changing version numbers changes its final behaviour
  • This was reported on both ESP32S3 and ESP32S2, so race conditions and multi-core issues do not seem to be related

I got a macOS machine on loan from a friend and I can at least replicate the mpremote issues on my board so I can slowly work on this in the meantime (I've been busy with a family situation the past couple of weeks).

I've only got one S3 board and to have JTAG exposed on GPIOs in order to have USB CDC available an eFuse must be burnt (thanks @projectgus for the help on that!). I'm a bit hesitant to burn the eFuse on my board right now, being my only S3 specimen; I've ordered a new one but the shipping times combined with a lackluster postal service plus holiday season here means somebody else may fix this issue before I am ever able to get a JTAG probe attached to the new board (if that happens I won't mind at all!).

Incidentally, I am able to replicate the same issue on a whole different set of conditions (WCH CH32V208 single-core MCU using STM's DCD while connecting from Linux) using the vendored TinyUSB copy, but that may be caused by a coding error on my end.

Keyboard

j / / n
next pair
k / / p
previous pair
1 / / h
show query pane
2 / / l
show candidate pane
c
copy suggested comment
r
toggle reasoning
g i
go to index
?
show this help
esc
close overlays

press ? or esc to close

copied