stm32/tinyusb: Add High-Speed USB support and fix CDC/VBUS issues.#26
Draft
andrewleech wants to merge 6 commits intomasterfrom
Draft
stm32/tinyusb: Add High-Speed USB support and fix CDC/VBUS issues.#26andrewleech wants to merge 6 commits intomasterfrom
andrewleech wants to merge 6 commits intomasterfrom
Conversation
|
Code size report: |
bb25aee to
4c3e95f
Compare
4c3e95f to
1e59002
Compare
|
Codecov Report✅ All modified and coverable lines are covered by tests. Additional details and impacted files@@ Coverage Diff @@
## master #26 +/- ##
==========================================
+ Coverage 98.45% 98.46% +0.01%
==========================================
Files 175 176 +1
Lines 22635 22784 +149
==========================================
+ Hits 22286 22435 +149
Misses 349 349 ☔ View full report in Codecov by Sentry. 🚀 New features to boost your workflow:
|
a60b5c5 to
105a90a
Compare
Implements mapping from MICROPY_HW_USB_MAIN_DEV to TinyUSB RHPORT configuration, enabling board-specific USB PHY selection for TinyUSB stack. Adds support for HS-in-FS mode (High Speed controller running at Full Speed) which is the default for STM32 boards without external ULPI PHY. Includes additional TinyUSB source files for DWC2 host controller support. Signed-off-by: Andrew Leech <andrew.leech@planetinnovation.com.au>
The MICROPY_HW_TINYUSB_RHPORTx_MODE macros from mpconfigboard_common.h are not available when tusb_config.h is compiled, because TinyUSB's build system includes tusb_config.h before MicroPython's full configuration chain (mpconfigport.h). This caused CFG_TUSB_RHPORT0_MODE and CFG_TUSB_RHPORT1_MODE to be set incorrectly for boards using High-Speed USB with external ULPI PHY, resulting in USB descriptors with Full-Speed packet sizes (64 bytes) instead of High-Speed packet sizes (512 bytes). Replicate the RHPORT selection logic directly in tusb_config.h using board configuration macros that ARE available at this compilation stage (MICROPY_HW_USB_MAIN_DEV, MICROPY_HW_USB_HS_ULPI, STM32 family defines). This ensures proper RHPORT configuration for all STM32 USB configurations: - Full-Speed only: RHPORT0 enabled, RHPORT1 disabled - High-Speed with ULPI: RHPORT0 disabled, RHPORT1 High-Speed mode - High-Speed internal PHY: RHPORT0 disabled, RHPORT1 Full-Speed mode Tested on STM32H747I-DISCO with USB3320 ULPI PHY. Signed-off-by: Andrew Leech <andrew.leech@planetinnovation.com.au>
Signed-off-by: Andrew Leech <andrew.leech@planetinnovation.com.au>
Signed-off-by: Andrew Leech <andrew.leech@planetinnovation.com.au>
When a host closes and reopens the CDC serial port, the IN endpoint may remain stalled from a prior runtime USB disconnect (e.g. mpremote connect/disconnect cycles). Clear the stall on DTR high so the connection recovers without requiring a device reset. On DTR low (host close), flush the TX FIFO so stale data does not accumulate and block writes on the next connection. Signed-off-by: Andrew Leech <andrew.leech@planetinnovation.com.au>
The TinyUSB serial descriptor used a raw hex dump of all 12 UID bytes in sequential order (24-char lowercase), while the legacy USB stack and ST's onboard DFU bootloader use a condensed algorithm that selects 6 bytes with two additions (12-char uppercase). This mismatch caused the device to report a different serial number depending on which USB stack was active, breaking tools that identify devices by serial (e.g. udev rules, mpremote, dfu-util). Use the ST DFU bootloader algorithm for consistency. Signed-off-by: Andrew Leech <andrew.leech@planetinnovation.com.au>
105a90a to
2fae783
Compare
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
The STM32 port's TinyUSB integration only supports the FS controller. Boards with a HS controller (PYBD_SF6, STM32F429DISC, OLIMEX_H407, or ULPI-based designs) cannot use TinyUSB — the RHPORT configuration is hardcoded to RHPORT 0 / full-speed only.
This PR adds proper RHPORT mode selection in
tusb_config.hbased onMICROPY_HW_USB_HSandMICROPY_HW_USB_HS_IN_FSboard config, routes HS IRQ handlers to the correct RHPORT (including STM32N6 which maps HS to RHPORT 0), and adds VBUS sensing configuration for the HS-in-FS path on STM32F4/F7 (mirroring the existing FS path, with support for both VBDEN and legacy NOVBUSSENS register variants).Additional issues found and fixed during testing (each is a separate commit and can be split into its own PR if preferred):
CDC reconnect stall: When a host closes and reopens the CDC serial port (e.g. repeated mpremote connect/disconnect cycles), the IN endpoint can remain stalled from a prior runtime USB disconnect. The device becomes unresponsive until reset. Fixed by clearing endpoint stall on DTR high. Additionally, on DTR low (host close) the TX FIFO is now flushed so stale data from a previous session does not accumulate and block writes on the next connection.
DFU bootloader serial number mismatch: The TinyUSB serial descriptor uses a raw hex dump of all 12 UID bytes (24-char lowercase), while the legacy USB stack and ST's onboard DFU bootloader use a condensed algorithm that selects 6 bytes with two additions (12-char uppercase). This causes the device to report a different serial number depending on which USB stack is active, breaking tools that identify devices by serial (udev rules, mpremote, dfu-util). Fixed by using the ST DFU bootloader algorithm.
TinyUSB-specific boot.py template: The factory reset boot.py template references
pyb.usb_mode()which does not exist on the TinyUSB stack. A TinyUSB-specific template is added that usesmachine.USBDevicewithBUILTIN_DEFAULT.Testing
Built with
CFLAGS_EXTRA=-DMICROPY_HW_TINYUSB_STACK=1for:machine.USBDeviceAPI, filesystem accessmachine.USBDeviceAPI, filesystem accessULPI boards (STM32H747I_DISCO) are tested on hardware as part of the original development in micropython#18303 — this branch is split out from that work.
CDC serial throughput (OPENMV_N6, HS link at 480 Mbit/s)
Compared TinyUSB vs legacy USB stack using
tests/serial_test.pymethodology.Read (device → host):
Write (host → device):
TinyUSB read is 6-12x faster. Write is 2.5-4.5x slower due to a pre-existing limitation in the TinyUSB CDC stdin path —
mp_hal_stdin_rx_chr()reads byte-by-byte through a 512-byte ringbuffer, causing backpressure on the USB OUT endpoint. This affects all TinyUSB ports, not just HS, and is being tracked separately.Trade-offs and Alternatives
The RHPORT configuration uses
#ifndefguards so boards like STM32N6 that pre-defineCFG_TUSB_RHPORT0_MODEinmpconfigboard_common.hpass through unchanged. This avoids needing per-family#ifchains but means any future HS-capable family (e.g. STM32U5) needs its own board-level override.