-
-
Notifications
You must be signed in to change notification settings - Fork 8.5k
esp32: Fix USB Zero Length Packet issue via patched TinyUSB #18407
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: master
Are you sure you want to change the base?
Conversation
This comment was marked as outdated.
This comment was marked as outdated.
This comment was marked as outdated.
This comment was marked as outdated.
|
Code size report: |
This is necessary so the ESP-IDF TinyUSB component can include py/mpconfig.h, but is also a good design goal (less creep of symbols into unrelated parts of the code). This work was funded through GitHub Sponsors. Signed-off-by: Angus Gratton <[email protected]>
Codecov Report✅ All modified and coverable lines are covered by tests. Additional details and impacted files@@ Coverage Diff @@
## master #18407 +/- ##
==========================================
- Coverage 98.38% 98.38% -0.01%
==========================================
Files 171 171
Lines 22297 22294 -3
==========================================
- Hits 21936 21933 -3
Misses 361 361 ☔ View full report in Codecov by Sentry. 🚀 New features to boost your workflow:
|
21cc6f5 to
f6b6e2c
Compare
This comment was marked as outdated.
This comment was marked as outdated.
f6b6e2c to
3debe81
Compare
|
I've reported the root cause of this to Espressif as well: espressif/esp-usb#315 |
|
Hi @projectgus,
may I clarify that after this change you will need the |
Yes, I'm very much hoping we can switch back to the Espressif TinyUSB component once the fix for espressif/esp-usb#315 is available in a component release (but this may not be soon.) (In a perfect world we'd use the same |
3debe81 to
49af741
Compare
|
Have updated the sdkconfig entries to no longer use (The UnexpectedMaker boards had hard-coded serial numbers before this PR, but now their serial numbers will be based on the ESP32 MAC address - same as other ports.) |
|
Quick comment: |
Instead, depend directly on espressif/tinyusb component (which is otherwise transitively included via esp_tinyusb). Turns out esp_tinyusb builds a bunch of source files with symbols that conflict with our tinyusb symbols (i.e. descriptors_control.c). This only works because nothing in MicroPython causes the linker to include the esp_tinyusb.a library, however in order to override the dcd_int_handler (in following commit) this caused the linker to pull this library in and break the build. There's also a problematic header skew - TinyUSB component was building with the tusb_config.h file from esp_tinyusb component, but we have our own tusb_config.h file in shared/tinyusb. The changes in parent commit allow us to build the TinyUSB component with our tusb_config.h header. User-facing impacts are: - Can no longer override USB VID & PID via sdkconfig, have to set MICROPY_HW_USB_VID/PID instead (changes applied in this commit). - esp32 boards will have the same USB serial number as other ports (i.e. based on the hardware MAC address, not hard-coded). Side effects include: - CFG_TUD_DWC2_SLAVE_ENABLE is now set, DMA mode is disabled. Signed-off-by: Angus Gratton <[email protected]>
Temporarily switch from the espressif TinyUSB component to a MicroPython fork where this fix has been cherry-picked: hathach/tinyusb#3293 This work was funded through GitHub Sponsors. Signed-off-by: Angus Gratton <[email protected]>
49af741 to
de51611
Compare
Fixed, thanks! I did these with a script, now idea how that snuck back in... |
|
I noticed that the default manufacturer/product string is now different. Eg ESP32_GENERIC_S3 used to be: and it's now changed to I guess that's OK, it matches all other ports and keeps the configuration simple. Although one could argue that the Espressif VID should go with the Espressif manufacturer name... so either we change the manufacturer or change the VID to the one all other ports use. |
dpgeorge
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks @projectgus for fixing this. It was definitely more than I expected to get this working.
But, at the same time, the changes here are really good for the long term:
- removing dependencies from
mpconfigport.his great - removing the
esp_tinyusbcomponent altogether is excellent! that's a really nice simplification and fixes potential issues with incorrecttusb_config.hbeing used - updating to use our fork of
tinyusb-espressifis pretty simple and clean
Eventually we won't need to fork tinyusb-espressif. But it's also now very easy for us to switch esp32 to use upstream tinyusb (like we used to), it's really just a matter of swapping source files, no configuration would need to change.
I've tested this PR on the following hardware/boards:
- ESP32_GENERIC_S3 (DevKit without PSRAM)
- UM_FEATHERS2 (with PSRAM)
- UM_TINYS3 (with PSRAM)
Tested using the updated serial_test.py with echo test, on Arch Linux and macOS. The test passes.
Also tested HID (simple keyboard example) on Arch Linux and macOS. It works.
|
Hi @projectgus, thanks for the clarification! I am afraid that I still didn't get the answer to my original question. Let me rephrase it a bit.
Just to be clear, that there are three different repos:
Based on this comment, it seems that in this case the better option would be to use the component under number 2. |
Summary
This PR updates the TinyUSB component to a custom version that cherry-picks this patch: hathach/tinyusb#3293
This is necessary to avoid corrupt transfers when DMA is disabled for esp32 port (see #18332) and the host sends an OUT zero length packet (ZLP). This is particularly reproducible in serial transfers from macOS host (see #18402 for test program).
See #18406 for a TinyUSB update that includes the same fix for other ports.
Two other esp32 port changes were required as dependencies for this change:
Remove esp_tinyusb component
Espressif has an esp_tinyusb component which contains glue code for using TinyUSB with ESP-IDF.
esp_tinyusbpulls in the "real"tinyusbcomponent as a dependency. The IDF Component Manager doesn't allow overriding components that are added as dependencies this way (have requested it), soesp_tinyusbhas been removed and replaced with a direct dependency ontinyusb.While looking into this I noticed that MicroPython should actually not be building
esp_tinyusbanyhow:esp_tinyusbintroduces a number of duplicate symbols that are also defined in MicroPython (for example, indescriptors_control.c). These don't currently fail the build as the linker doesn't examine these files, but it could.esp_tinyusbincludes its owntusb_config.hfile and thetinyusbcomponent source files are built with this config header, but MicroPython files are built withshared/tinyusb/tusb_config.h. This introduces the possibility for weird ABI incompatibility if the configs don't match.The only user-facing changes are:
MICROPY_HW_USB_VID,MICROPY_HW_USB_PID, etc. macros inmpconfigboard.hinstead. (Existing boards are changed over in this PR.)This change also makes #18332 redundant, as the config option it sets is set via
esp_tinyusb(and the default is to disable DMA).Remove component dependencies from mpconfigport.h
In order to build the TinyUSB component with MicroPython's
tusb_config.h, the esp32mpconfigport.hheader needed to have some external dependencies (wifi, i2s driver) pulled out. This turned out to be pretty straightforward, and IMO it's a good change anyway not to havepy/mpconfig.hpull in too many other things.Testing
serial_test.pyprogram from tests/serial_test.py: add a serial echo test #18402 on Linux and MacOS hosts with an ESP32_GENERIC_S3 board and one with octal SPIRAM, verified nothing failed.Trade-offs and Alternatives
dcd_dwc2_patch.cfile which contained the patcheddcd_int_handler()function instead and then applying a linker wrap, but this didn't work (I think due to linker order). Decided that this approach was less hacky, out of the two. Working with the patch file was also how I noticed the other issues withesp_tinyusbcomponent, though.