#tinyusb

1 messages ยท Page 12 of 1

fallow birchBOT
#

I have a quirky device that has multiple devices in it's report (gamepad, keyboard, and a mouse).

If i send any set hid protocol message to the device during it's life cycle, it will stall the polls to the gamepad endpoint (which I want to talk to) and prefers the keyboard only.

I need some way to tell tinyusb to skip sending the set protocol command during operation, so this PR allows me to call in my code

tuh_hid_set_default_protocol(HID_PROTOCOL_SKIP);

and during enumeratio...

fallow birchBOT
fallow birchBOT
fallow birchBOT
#
[hathach/tinyusb] New branch created: refactor-fsdev
#

๐Ÿ’ก Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 9b2f6f4f0c

โ„น๏ธ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with ๐Ÿ‘.

Codex can also answer questions or u...

#

<sub><sub>P1 Badge</sub></sub> Select endpoint register mask after bus width is known

U_EPREG_MASK is chosen via #ifdef FSDEV_BUS_32BIT here before the vendor headers are included, but FSDEV_BUS_32BIT is defined later (in fsdev_stm32.h and the PMA-size block), so this path resolves to the 16-bit mask. On DRD MCUs (e.g. C0/G0/H5/U0/U3/U5), host paths such as channel_xfer_start() then mask channel registers with `U_EPREG_MASK...

fallow birchBOT
#

Hey, I hit the same issue while working with MIDI Host on ESP32-S3. My device has Audio Control (itf 0) + MIDI Streaming (itf 1), and set_config was crashing with idx=255.

I investigated and reached the same conclusion as @203Null. The problem is in the midih_open loop โ€” when it finds the next interface and sets found_new_interface = true, the p_desc = tu_desc_next(p_desc) at the end of the while still executes, advancing one descriptor beyond. This inflates desc_midi_total_len, and tu_bind_...

#

Sorry, this is harder than I expected. ch32 and ch58x have quite different usb register layouts (split/merged ep control, dma width, interrupt controller), so merging them isn't as straightforward as dwc2. I tried the port-header approach but still ended up with about 20 #if blocks.
The ch58x driver follows its sdk conventions, which are pretty different from ch32's (ch32 sdk mimics stm32 style, while ch58x sdk is more simplified). A full rewrite could help, but given how different these chi...

fallow birchBOT
#
[hathach/tinyusb] New branch created: fix-midi-host
#

๐Ÿ’ก Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 1c19a10ed1

โ„น๏ธ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with ๐Ÿ‘.

Codex can also answer questions or u...

#

<sub><sub>P1 Badge</sub></sub> Re-check bounds after advancing p_desc

This loop now validates tu_desc_in_bounds(p_desc, desc_end) before p_desc is advanced, but the descriptor access (tu_desc_type(p_desc)) happens after p_desc = tu_desc_next(p_desc). If the current descriptor is the last in-bounds one (for example, a truncated/malformed MIDI interface descriptor set from a device), the advance can move p_desc to o...

#

Pull request overview

Fixes MIDI host enumeration/configuration behavior to address issue #3544, where the MIDI host driver could be configured for an interface it didnโ€™t actually open (leading to asserts/faults on some targets).

Changes:

  • Adjusts descriptor-walk logic in midih_open() so the computed โ€œMIDI interface total lengthโ€ is intended to stop at the next interface descriptor (instead of stepping past it).
  • Ensures the mount callback reports the actual MIDI streaming interf...
#

In midih_open(), p_desc is advanced at the start of the loop (p_desc = tu_desc_next(p_desc);) but the loop condition only checks bounds for the previous descriptor. If the current p_desc is the last in-bounds descriptor, tu_desc_next(p_desc) can become desc_end (or beyond), and the subsequent tu_desc_type(p_desc) will read out of bounds and can fault. Restructure the loop so bounds are validated for the descriptor being inspected (e.g., pre-advance once before the loop and adv...

fallow birchBOT
fallow birchBOT
fallow birchBOT
#
[hathach/tinyusb] New branch created: hil-host-cdc
#

Pull request overview

Adds a new HIL host-side CDC test to validate CDC enumeration + data path (via host cdc_msc_hid example), and updates HIL configuration / BSP helpers to better support the test environment.

Changes:

  • Add a new HIL test host/cdc_msc_hid that waits for CDC mount and performs a UART-console-driven CDC echo check.
  • Extend HIL board config (tinyusb.json) dev_attached entries with an is_cdc flag to identify CDC-capable attached devices.
  • Improve STM32H7 B...
#

๐Ÿ’ก Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: a3b2b42176

โ„น๏ธ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with ๐Ÿ‘.

Codex can also answer questions or u...

#

<sub><sub>P1 Badge</sub></sub> Gate host/cdc_msc_hid on boards with UART RX support

Adding host/cdc_msc_hid to the default host test list makes it run on every host: true board, but at least one configured board (stm32f723disco in test/hil/tinyusb.json) routes through hw/bsp/stm32f7/family.c where board_uart_read() is a stub that always returns 0; in that setup board_getchar() never receives injected bytes, so the new C...

#

<sub><sub>P1 Badge</sub></sub> Avoid HAL_Delay retries during pre-scheduler init

Using HAL_Delay(10) in this retry loop can deadlock STM32H7 FreeRTOS startups: board_init() disables SysTick before calling board_init2() in hw/bsp/stm32h7/family.c, so if the first I2C access fails here, HAL_Delay() has no advancing tick source and blocks indefinitely instead of retrying. This retry path needs a delay mechanism that works befo...

#

Size Difference Report

Because TinyUSB code size varies by port and configuration, the metrics below represent the averaged totals across all example builds.

Note: If there is no change, only one value is shown.

Changes >1% in size

No entries.

Changes <1% in size

No entries.

<details><summary>No changes</summary>

file .text .rodata .data .bss size % diff
audio_device.c...
fallow birchBOT
#
[hathach/tinyusb] New branch created: hid-host-set-protocol-skipable
#

๐Ÿ’ก Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 28e14abdc7

โ„น๏ธ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with ๐Ÿ‘.

Codex can also answer questions or u...

#

<sub><sub>P2 Badge</sub></sub> Sync protocol_mode when skipping SET_PROTOCOL on enum

With CFG_TUH_HID_SET_PROTOCOL_ON_ENUM set to 0, this branch falls through to CONFIG_GET_REPORT_DESC without sending SET_PROTOCOL, but the interface state still keeps the preloaded _hidh_default_protocol value (default Boot). For Boot-subclass devices this causes tuh_hid_get_protocol() to report Boot while the device is actually still in R...

#

Pull request overview

Adds a new HID host configuration option to control whether SET_PROTOCOL is issued during enumeration, allowing users to skip that step for devices that misbehave.

Changes:

  • Introduced CFG_TUH_HID_SET_PROTOCOL_ON_ENUM (default 1) in the HID host public header.
  • Updated HID host enumeration state machine to optionally skip SET_PROTOCOL and fall through to report descriptor retrieval.
  • Minor internal renames/cleanup (_hidh_set_* -> hidh_set_*) and small...
#

When CFG_TUH_HID_SET_PROTOCOL_ON_ENUM is 0, this case intentionally skips sending SET_PROTOCOL, but p_hid->protocol_mode is still initialized to _hidh_default_protocol (default HID_PROTOCOL_BOOT) in hidh_open(). Per HID spec the device defaults to Report protocol, so tuh_hid_get_protocol() can return an incorrect value in the skip path (and callers may parse reports as Boot when the device is actually in Report). Consider explicitly setting p_hid->protocol_mode to `HID_PROTOCOL_...

#

Size Difference Report

Because TinyUSB code size varies by port and configuration, the metrics below represent the averaged totals across all example builds.

Note: If there is no change, only one value is shown.

Changes >1% in size

No entries.

Changes <1% in size

No entries.

<details><summary>No changes</summary>

file .text .rodata .data .bss size % diff
audio_device.c...
fallow birchBOT
fallow birchBOT
fallow birchBOT
fallow birchBOT
fallow birchBOT
#
[hathach/tinyusb] New branch created: fix-fsdev-midi-host-bugs
#

Summary

  • hcd_edpt_clear_stall: fix wrong endpoint lookup โ€” was always finding EP0 instead of the target endpoint, breaking stall recovery on non-control endpoints
  • hcd compile guard: add OPT_MCU_STM32U3 to enable USB host mode on STM32U3 (all infrastructure already in place)
  • dcd_edpt_close_all: use FSDEV_EP_COUNT instead of CFG_TUD_ENDPPOINT_MAX for PMA btable offset, matching handle_bus_reset
  • midi host tuh_midi_stream_write: add missing cable number to syst...
#

Size Difference Report

Because TinyUSB code size varies by port and configuration, the metrics below represent the averaged totals across all example builds.

Note: If there is no change, only one value is shown.

Changes >1% in size

No entries.

Changes <1% in size

No entries.

<details><summary>No changes</summary>

file .text .rodata .data .bss size % diff
audio_device.c...
fallow birchBOT
fallow birchBOT
#

๐Ÿ’ก Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 868ad07127

โ„น๏ธ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with ๐Ÿ‘.

Codex can also answer questions or u...

#

<sub><sub>P2 Badge</sub></sub> Disable RP2040 dcd_edpt_xfer_fifo() when hwfifo support is off

If an RP2040 build still uses the driver-level dcd_edpt_xfer_fifo() entry point (it remains exported in src/portable/raspberrypi/rp2040/dcd_rp2040.c:508-513), setting CFG_TUD_EDPT_DEDICATED_HWFIFO to 0 makes prepare_ep_buffer()/sync_ep_buffer() skip the only ep->is_xfer_fifo handling. hw_endpoint_xfer_start() stores the FIF...

#

Pull request overview

This PR disables the RP2040 device โ€œdedicated hardware FIFOโ€ transfer path by default and gates RP2040-specific hwfifo helpers/logic behind the corresponding compile-time option.

Changes:

  • Set CFG_TUD_EDPT_DEDICATED_HWFIFO to 0 for RP2040 (non PIO-USB device).
  • Compile tu_hwfifo_write() / tu_hwfifo_read() only when CFG_TUD_EDPT_DEDICATED_HWFIFO is enabled.
  • Wrap FIFO-based buffer copy paths in rp2040_usb.c with #if CFG_TUD_EDPT_DEDICATED_HWFIFO....
#

tu_hwfifo_write()/tu_hwfifo_read() are now compiled only when CFG_TUD_EDPT_DEDICATED_HWFIFO is enabled, but the RP2040 config still defines CFG_TUSB_FIFO_HWFIFO_CUSTOM_WRITE/READ. If someone enables CFG_TUH_EDPT_DEDICATED_HWFIFO (or otherwise turns on CFG_TUSB_FIFO_HWFIFO_API) while CFG_TUD_EDPT_DEDICATED_HWFIFO stays 0, the default implementations in tusb_fifo.c will be suppressed and these functions wonโ€™t be provided, causing link failures. Consider guarding these definition...

fallow birchBOT
fallow birchBOT
fallow birchBOT
#
[hathach/tinyusb] New branch created: rp2040-hcd-epx
fallow birchBOT
fallow birchBOT
#

Pull request overview

This PR refactors the RP2040 USB portable layer to make endpoint transfers operate on explicit DPRAM register pointers (EP/BUF ctrl), and reworks the host HCD to manage a pool of endpoint state structures while continuing to use the shared EPX hardware for non-interrupt transfers.

Changes:

  • Updates hw_endpoint_* APIs to take explicit ep_reg/buf_reg pointers, and renames/clarifies endpoint fields (max_packet_size, dpram_buf, pending).
  • Refactors RP2...
#

hcd_device_close() marks endpoints unused by setting max_packet_size = 0, but it doesnโ€™t reset other per-endpoint state (active, pending, next_pid, interrupt_num, etc.). Since edpt_alloc() reuses entries based solely on max_packet_size, stale fields can leak into the next deviceโ€™s endpoints and/or confuse IRQ handling. Consider calling hw_endpoint_reset_transfer() and clearing host-only fields (including interrupt_num) when freeing, or memset() the entry before reuse.

#

usb_hw_set is a write-only alias (atomic bit-set). Reading usb_hw_set->int_ep_ctrl here is unreliable and canโ€™t be used to detect which interrupt endpoints are already allocated/enabled, which may lead to duplicate allocations. Read usb_hw->int_ep_ctrl instead (or maintain a software bitmap), and keep the bit index consistent with interrupt_num semantics.

#

In host control transfers with an OUT data stage, ep_addr will remain 0x00 after hcd_setup_send(), so this conditional never runs and next_pid stays at 0 (DATA0). After a SETUP stage the data/status stages must start with DATA1; this will send the wrong PID for control-OUT data stages. Fix by ensuring EP0โ€™s next_pid is set to 1 after SETUP (or when starting any EP0 data/status stage, regardless of direction changes).

fallow birchBOT
#
[hathach/tinyusb] New branch created: remove-iar-make-support
#

Summary

  • Remove IAR toolchain files (arm_iar.mk, iar_rules.mk) from make build system
  • Remove all SRC_S_IAR and LD_FILE_IAR variables from family.mk and board.mk files
  • Remove IAR toolchain detection (iccarm) from family_support.mk
  • Simplify FreeRTOS portable path to always use GCC
  • Fix GET_SECTOR_COUNT truncation bug in msc_file_explorer (WORDโ†’DWORD cast)
  • Fix broken line formatting in stm32f7/family.c board_uart_write

IAR remains supported via CMake only.

T...

#

Size Difference Report

Because TinyUSB code size varies by port and configuration, the metrics below represent the averaged totals across all example builds.

Note: If there is no change, only one value is shown.

Changes >1% in size

No entries.

Changes <1% in size

No entries.

<details><summary>No changes</summary>

file .text .rodata .data .bss size % diff
audio_device.c...
fallow birchBOT
fallow birchBOT
fallow birchBOT
#

The notification endpoint bInterval was hardcoded to 50 in the macro. Expose it as _ep_notif_interval so callers can set an appropriate value for their device speed, per discussion #3553.

Update net_lwip_webserver to pass TUD_OPT_HIGH_SPEED ? 9 : 50, which preserves the original 50ms polling interval on full-speed (50 frames) and approximates it on high-speed (bInterval=9 โ†’ 2^8 ร— 125ยตs = 32ms).

fallow birchBOT
fallow birchBOT
#

Pull request overview

This PR fixes network class ZLP handling by basing decisions on the negotiated bulk endpoint wMaxPacketSize read from descriptors at netd_open() time, instead of compile-time or hardcoded speed assumptions (important for dual-speed devices).

Changes:

  • Remove CFG_TUD_NET_ENDPOINT_SIZE and store actual bulk EP max packet size in the network interface state for ECM/RNDIS and NCM.
  • Update ZLP decision logic to use the stored descriptor-derived endpoint siz...
#

TUD_CDC_NCM_DESCRIPTORโ€™s macro signature changed (adds _ep_notif_interval). Since this macro is part of the public descriptor template API in usbd.h, this is a breaking change for downstream descriptor code; consider providing a backward-compatible wrapper (e.g., keep the old name/arity mapping to a default interval) or clearly deprecating the old form in a release note.

#

xferred_bytes % ep_size will crash if ncm_interface.ep_size is ever 0 (e.g., unexpected descriptor content or if netd_open() hasnโ€™t populated it yet). Add a guard/assert that ep_size is non-zero before using it in the modulo operation (and treat 0 as โ€œno ZLP requiredโ€).

  uint16_t const ep_size = ncm_interface.ep_size;
  // If ep_size is zero, the endpoint is not configured; in this case, no ZLP is required.
  if (ep_size == 0) {
    return false;
  }
#

Size Difference Report

Because TinyUSB code size varies by port and configuration, the metrics below represent the averaged totals across all example builds.

Note: If there is no change, only one value is shown.

Changes >1% in size

No entries.

Changes <1% in size

| file | .text | .rodata | .data | .bss | size | % diff |
| :----------------- | ----------------: | ------: | -------------: | ---------------: | -----------...

#

Fixed in b46147a:

  • tud_descriptor_other_speed_configuration_cb() now copies the selected descriptor into a desc_other_speed_config[] scratch buffer (sized to MAX_CONFIG_TOTAL_LEN) and sets byte[1] = TUSB_DESC_OTHER_SPEED_CONFIG before returning, matching the pattern used in cdc_uac2, mtp, and usbtmc examples.
  • Added configuration_sz_arr[] to track the actual byte length of each configuration so memcpy copies the right amount.
  • Fixed typo: "GET OTHER SEED CONFIGURATION" โ†’ ...
#

driver->init() returns bool (see usbh_class_driver_t), but its return value is ignored. Several built-in class init functions can return false on internal TU_ASSERT failures, so tuh_rhport_init() may still succeed even though a class driver failed to initialize. Consider asserting/propagating the init result (e.g., fail tuh_rhport_init() if any present init() returns false).

        bool inited = driver->init();
        TU_ASSERT(inited);
        if (!inited) {
 ...
#

Pull request overview

This PR makes the host class-driver init() callback optional (similar to how deinit() is already treated), allowing application-provided host drivers to omit an init routine when it isnโ€™t needed.

Changes:

  • Guard host driver initialization so driver->init() is called only when non-NULL.
  • Update architecture documentation to list init() as an optional class driver function.

Reviewed changes

Copilot reviewed 2 out of 2 changed files in this pull req...

fallow birchBOT
fallow birchBOT
#

Pull request overview

This PR applies a small set of correctness fixes and simplifications following an earlier async-related change set, touching both host and device task scheduling behavior and cleaning up an unused OS configuration macro.

Changes:

  • Remove an unused OS scheduler capability macro from common configuration options.
  • Adjust USB host deferred-callback scheduling and ensure tuh_task_event_ready() considers deferred callbacks and deferred hub attachments appropriate...
#

Setting timeout_ms = 0 is meant to make the next osal_queue_receive() non-blocking so tud_task() can return when the queue becomes empty. However, some OSAL ports (e.g. Mynewt) ignore the msec parameter and always block (osal_mynewt.h notes osal_queue_receive() behaves as WAIT_FOREVER), so this change can cause tud_task_ext() to block indefinitely after processing a single event when the queue is empty. Consider restoring an explicit if (osal_queue_empty(_usbd_q)) return; chec...

fallow birchBOT
fallow birchBOT
#
[hathach/tinyusb] New branch created: revert-3565-driver-init
#

๐Ÿ’ก Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: d8994a3018

โ„น๏ธ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with ๐Ÿ‘.

Codex can also answer questions or u...

#

<sub><sub>P1 Badge</sub></sub> Avoid unguarded init() calls for app host drivers

Custom host drivers supplied through usbh_app_driver_get_cb() are still represented by usbh_class_driver_t, so .init can legally be left zero-initialized when a driver has no stack-level setup to do. In tuh_rhport_init() this change now calls driver->init() for every non-NULL driver, which turns those existing out-of-tree drivers into a NULL fu...

#

<sub><sub>P2 Badge</sub></sub> Don't fail device init when a custom driver omits init()

usbd_app_driver_get_cb() lets applications add device class drivers, and usbd_class_driver_t still allows .init to be omitted by leaving the function pointer NULL. Replacing the old guard with TU_ASSERT(driver && driver->init) means tud_rhport_init() now bails out before dcd_init() whenever one of those custom drivers does not need an ...

#

Pull request overview

Reverts the change that made class driver init() optional, restoring the expectation that class drivers provide an initialization hook during stack bring-up.

Changes:

  • Host: class driver initialization now runs unconditionally for each registered driver entry.
  • Device: class driver initialization now asserts that driver and driver->init exist before calling init().
  • Docs: moves init() from โ€œOptional Functionsโ€ to โ€œRequired Functionsโ€ in the class dr...
#

tuh_rhport_init() now calls driver->init() without checking that the function pointer is non-NULL. This can crash if an application-provided class driver omits init (previously it was skipped). If init() is intended to be required again, assert it explicitly (e.g., TU_ASSERT(driver && driver->init);) and optionally assert the return value (TU_ASSERT(driver->init());) to fail cleanly instead of dereferencing a NULL pointer.

        if (driver->init) {
          driver...
fallow birchBOT
fallow birchBOT
#

Additionally we attach test log of libmtp with testing (test on nrf52840):

libmtp version: 1.1.19

Listing raw device(s)
Device 0 (VID=cafe and PID=4020) is UNKNOWN in libmtp v1.1.19.
Please report this VID/PID and the device model to the libmtp development team
   Found 1 device(s):
   cafe:4020 @ bus 3, dev 20
Attempting to connect device(s)
USB low-level info:
   bcdUSB: 512
   bDeviceClass: 0
   bDeviceSubClass: 0
   bDeviceProtocol: 0
   idVendor: cafe
   idProduct:...
fallow birchBOT
#

Pull request overview

This PR adjusts MTP string serialization helpers to align with the MTP v1.1 โ€œStringsโ€ encoding rules (length byte including null terminator; empty string as a single zero byte), and updates the MTP filesystem example to always send an OPERATION_NOT_SUPPORTED response when appropriate.

Changes:

  • Update mtp_container_add_string() / mtp_container_add_cstring() string encoding behavior for MTP v1.1 compliance.
  • Ensure MTP_RESP_OPERATION_NOT_SUPPORTED respo...
#

mtp_container_add_string() now initializes count to 1 and checks utf16[count], which skips utf16[0]. For a non-empty string like "A\0", this will incorrectly treat it as empty and encode a single zero byte. Please compute the character count by scanning from index 0, then add 1 for the required null terminator (per MTP string format), and only use the single-zero-byte encoding when utf16[0] == 0 (empty string).

  uint8_t* buf = p_container->payload + p_container->heade...
#

In the empty-string branch, the code writes *buf = 0 before checking available space with TU_ASSERT(...). If the container is already at/near CFG_TUD_MTP_EP_BUFSIZE, this can write out of bounds before the assertion triggers. Please move the size check before writing to buf (same pattern applies to the empty-string handling in mtp_container_add_cstring()).

    const uint32_t added_len = 1u;
    TU_ASSERT(p_container->header->len + added_len < CFG_TUD_MTP_EP_BUFSIZE, 0)...
fallow birchBOT
fallow birchBOT
#

I have been following TinyUSB for a while and have deep respect for the work @hathach built here over the years. The care with static memory, the clarity of APIs, the callback patterns -- all of that directly influenced how I approached this implementation.

What I tried to do was bring MIDI 2.0 to TinyUSB following the same patterns as MIDI 1.0, as a natural extension of the code and architecture. Anyone familiar with midi_device.c and midi_host.c will recognize the structure. Same namin...

#

๐Ÿ’ก Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 5d5c50a274

โ„น๏ธ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with ๐Ÿ‘.

Codex can also answer questions or u...

#

<sub><sub>P1 Badge</sub></sub> Return parsed descriptor span instead of max_len

midih2_open() currently returns max_len unconditionally, but USB host enumeration expects each class driver to return only the number of descriptor bytes it consumed. In enum_parse_configuration_desc() (src/host/usbh.c), this return value is used to bind interfaces/endpoints to the class and advance parsing; returning the full remaining length mak...

#

<sub><sub>P1 Badge</sub></sub> Send SET_INTERFACE before completing MIDI2 config

midih2_set_config() selects alt_setting_current and immediately completes configuration without issuing a standard SET_INTERFACE control request for alternate setting 1. USB interfaces default to alt 0, so MIDI2-capable devices can be reported as mounted while still running alt 0 semantics, which prevents proper MIDI2/UMP operation on devices that ...

#

<sub><sub>P1 Badge</sub></sub> Stop scanning at the next interface in midi2d_open

The descriptor-skip loop in midi2d_open() continues through any TUSB_DESC_INTERFACE, not just MIDI2 alternate-setting descriptors. During process_set_config() (src/device/usbd.c), the returned length is used to bind all enclosed interfaces/endpoints to this driver, so this logic can consume unrelated interfaces that follow MIDI2 in a composite d...

#

Pull request overview

Adds USB-MIDI 2.0 support to TinyUSB by introducing new device/host class drivers, descriptor templates, configuration defaults, documentation, examples, and unit testsโ€”while keeping the feature opt-in via CFG_TUD_MIDI2 / CFG_TUH_MIDI2.

Changes:

  • Introduce new USB-MIDI 2.0 device and host class drivers (midi2_device.*, midi2_host.*) and register them with USBD/USBH.
  • Add USB-MIDI 2.0 descriptor templates/macros and new configuration defaults for buffer...
#

midih2_open() returns max_len, which will cause the USBH configuration parser to skip the rest of the configuration descriptor (and potentially prevent other interfaces/alt settings from being opened). The host class driver open() callback is expected to return the number of bytes consumed for this interface (see midih_open()). Compute and return the parsed length (e.g., advance a local descriptor pointer until the next TUSB_DESC_INTERFACE and return the delta from desc_start).

...
#

The host driver documentation states it will "Auto-Select" the highest available protocol, which matches the current implementation (midih2_auto_select_alt_setting). However, the PR description says the driver makes no protocol decisions and the application controls everything. Please align the PR description and public API/docs with the actual behavior (either document the auto-selection as the supported behavior, or add an application-controlled selection mechanism and update the code/docs ...

#

midi2d_control_xfer_cb handles SET_INTERFACE but accepts any alt value and updates p_midi->alt_setting without validation. Since this interface only defines Alt 0 and Alt 1, unsupported alternate settings should be rejected (stall/return false) to avoid leaving the driver in an undefined state. Also consider explicitly resetting negotiated/protocol state when switching back to Alt 0 if the driver relies on those fields elsewhere.

#

midih2_set_config() sets alt_setting_current to 1 when a MIDI 2.0-capable device is detected, but the driver never issues a SET_INTERFACE request to actually activate alternate setting 1. As a result the device will remain in Alt 0 while callbacks report Alt 1, and UMP read/write will interpret legacy MIDI 1.0 event packets as UMP words. Consider calling tuh_interface_set(dev_addr, p_midi->bInterfaceNumber, desired_alt, ...) and only marking mounted / invoking mount_cb (and usbh_driver_set_co...

#

In the Alt 1 descriptor parser, the CS_ENDPOINT subtype is MIDI_CS_ENDPOINT_GENERAL_2_0, but the code casts it to midi_desc_cs_endpoint_t and reads bNumEmbMIDIJack. For USB-MIDI 2.0 this field represents Group Terminal Block association (bNumGrpTrmBlk and following block IDs), not embedded jack/cable count, so the parsed rx/tx counts (and callback fields) are likely incorrect. Define/parse the correct USB-MIDI 2.0 CS endpoint descriptor layout and expose the appropriate GTB/group information ...

#

TUD_MIDI2_DESC_ALT1_EP(_numgtbs) sets bLength to (4 + _numgtbs) but the macro itself only emits the 4-byte CS endpoint header; the required _numgtbs bytes of bAssoGrpTrmBlkID must be appended manually. Since the macro signature suggests it is self-contained, it is easy to generate malformed descriptors when _numgtbs != 1. Consider either (a) hard-coding the template to 1 GTB and removing the parameter, or (b) extending the macro to accept/emit the GTB ID list so the output size matches the de...

fallow birchBOT
fallow birchBOT
fallow birchBOT
#

๐Ÿ’ก Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 1ecb4c8eee

โ„น๏ธ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with ๐Ÿ‘.

Codex can also answer questions or u...

#

<sub><sub>P1 Badge</sub></sub> Avoid requiring metrics artifact for membrowse comments

This if makes membrowse comments depend on steps.pr_number.outputs.number, but that output is only set when the Build workflow uploads metrics-comment/pr_number.txt from code-metrics in .github/workflows/build.yml (which itself is gated by code_changed == true and successful cmake). This means comments are now skipped for docs-only PR...

fallow birchBOT
#

Thank you for the automated review feedback. I pushed two commits addressing all of it:

9f1001e - PR review feedback:

  • midih2_open() now returns actual parsed length instead of max_len (composite device safety)
  • midi2d_open() skip loop stops at interfaces that belong to other functions
  • midih2_set_config() now issues SET_INTERFACE via tuh_interface_set() before completing mount, with fallback to alt 0 on failure
  • Alt 1 CS Endpoint parser uses MIDI 2.0 layout (`bNumGrpTrmB...
fallow birchBOT
fallow birchBOT
fallow birchBOT
#

Operating System

Windows 11

Commit SHA

Release 0.20.0

Board

nanoCH32V203 & WeActStudio BluePill Plus CH32

Firmware

Here is a repo containing the bare dfu example found in examples/device/dfu that was slightly modified to work with MounRiver Studio II. https://github.com/Devin-goBILDA/CH32V203-TinyUSB-DFU-Issue.

This issue is reproducible with the stock examples/device/dfu example code running on a ch32v203.

What happened ?

I am in the process of creating a DFU b...

fallow birchBOT
#

mtp_container_add_string() counts characters using a uint8_t. If the UTF-16 string is longer than 254 code units or is missing a terminator, count++ can wrap and the while (utf16[count] != 0u) scan can become an infinite loop / out-of-bounds read. Add an explicit maximum (255 including the required terminator per MTP) and fail/return 0 if the terminator isnโ€™t found within that bound.

  /* Count UTF-16 code units up to the MTP maximum (255 including terminator).
   * If n...
#

mtp_container_add_cstring() truncates strlen(str) + 1 into a uint8_t. For strings longer than 254 bytes, this will wrap and encode an incorrect length/count (and will only copy a prefix). Since MTP string count is a single byte, explicitly validate strlen(str) <= 254 (or otherwise handle/return 0) before casting.

  const size_t slen = strlen(str);
  // MTP string count is a single byte and includes the terminating 0,
  // so the maximum allowed character count (includi...
fallow birchBOT
fallow birchBOT
#

<!-- membrowse-pr-comment -->

<img src="https://membrowse.com/membrowse-logo.svg" height="24" align="top"> MemBrowse Memory Report

<!-- membrowse-pr-comment -->

<img src="https://membrowse.com/membrowse-logo.svg" height="24" align="top"> MemBrowse Memory Report

Top 10 targets by memory change (%) (out of 2156 targets) View Project Dashboard โ†’

| target | .text | .rodata | .data | .b...

fallow birchBOT
fallow birchBOT
fallow birchBOT
#

<!-- membrowse-pr-comment -->

<img src="https://membrowse.com/membrowse-logo.svg" height="24" align="top"> MemBrowse Memory Report

<!-- membrowse-pr-comment -->

<img src="https://membrowse.com/membrowse-logo.svg" height="24" align="top"> MemBrowse Memory Report

Top 10 targets by memory change (%) (out of 2156 targets) View Project Dashboard โ†’

| target | .text | .rodata | .data | .b...

fallow birchBOT
#

I investigated the LM20 DWC2 config and also reduced the fix further.

For the DWC2 config dump, I read the registers on hardware and added a dedicated nRF54LM20 column to dwc2_info.py / dwc2_info.md.

These differ from the existing generic nRF54 entry, so LM20 seems to need its own column.

I tested the DOEPCTL.SNAK addition in edpt_disable() by itself on hardware, but that was not sufficient for this case.

All the other writes I had in the earlier version (DOEPINT, `D...

fallow birchBOT
#

Thank you, it looks like something is changed in GID 5.00b.

But I don't understand why settings epout->doepctl = DOEPCTL_SNAK; will fix the issue, since doepctl should be reset in edpt_disable (those who left will be overwritten in edpt_activate). Unless there are some additional flag needs to be cleared but it's not listed in https://docs.nordicsemi.com/bundle/ps_nrf54LM20A/page/usbhs.html#register.DOEPCTL1

Could you check doepctl value before/after edpt_activate call w...

fallow birchBOT
#

I investigated further, it seems the issue is not that edpt_activate() fails to rewrite DOEPCTL. The problem is that edpt_disable() does not clear DOEPCTL.USBAEP. The edpt_activate() function sets USBAEP again via depctl.active = 1, while edpt_disable() only disables the endpoint (DOEPCTL_EPDIS) and leaves USBAEP set.

You are right, its probably better to not skip the normal disable flow. I changed the sequence to:

`edpt_disable() -> clear DOEPCTL.USBAEP -> edpt_acti...

fallow birchBOT
fallow birchBOT
#

Size Difference Report

Because TinyUSB code size varies by port and configuration, the metrics below represent the averaged totals across all example builds.

Note: If there is no change, only one value is shown.

Changes >1% in size

No entries.

Changes <1% in size

No entries.

<details><summary>No changes</summary>

file .text .rodata .data .bss size % diff
audio_device.c...
fallow birchBOT
#

I think it's safe to clear ActEP in edpt_disable, linux also clear it in EP disable, although the databook doesn't mention it much.

Is it work for you :

diff --git a/src/portable/synopsys/dwc2/dcd_dwc2.c b/src/portable/synopsys/dwc2/dcd_dwc2.c
index 8685ec6dc..e32dedd1b 100644
--- a/src/portable/synopsys/dwc2/dcd_dwc2.c
+++ b/src/portable/synopsys/dwc2/dcd_dwc2.c
@@ -345,6 +345,11 @@ static void edpt_disable(uint8_t rhport, uint8_t ep_addr, bool stall) {
       dwc2->dctl ...
fallow birchBOT
#

Refactor event signal generation to limit bus signal events generated by fuzzing harnesses. The main point is that the issues listed by OSS-Fuzz does not seem to be true positives https://issues.oss-fuzz.com/issues?q=project%3Dtinyusb status%3Dnew

For example, the existing set up could generate USBD_EVENT_FUNC_CALL which is explicitly not a DCD event.

This fixes the harnesses so they don't run into several of the oss-fuzz open issues.

#

Pull request overview

Refactors the TinyUSB device-controller fuzzing harness to avoid generating invalid/ill-formed DCD events that can trigger uninitialized-union reads and OSS-Fuzz false positives.

Changes:

  • Restricts dcd_event_bus_signal() generation to bus-signal-only DCD events (unplugged/suspend/resume).
  • Adds optional generation of a BUS_RESET event via dcd_event_bus_reset() with a bounded tusb_speed_t value.

๐Ÿ’ก Add Copilot custom instructions for smarter, ...

#

The index range is hard-coded to 0..2, which is coupled to the current size of bus_signal_events. If the list changes, this can become out-of-bounds or bias fuzzing. Prefer deriving the max from the array size (e.g., TU_ARRAY_SIZE(bus_signal_events) - 1) so the range stays correct automatically.

    uint8_t idx = _fuzz_data_provider->ConsumeIntegralInRange<uint8_t>(
        0, static_cast<uint8_t>(TU_ARRAY_SIZE(bus_signal_events) - 1));
#

The comment enumerates specific numeric values for the event IDs (e.g., UNPLUGGED(2), SUSPEND(4), RESUME(5)). These numbers can drift if dcd_eventid_t is modified, making the comment misleading. Consider removing the numeric IDs (or referencing the enum definition) and keeping only the symbolic names.

    // Valid bus-signal-only events: DCD_EVENT_UNPLUGGED, DCD_EVENT_SUSPEND, DCD_EVENT_RESUME.
fallow birchBOT
fallow birchBOT
fallow birchBOT
fallow birchBOT
#

Thank you, please run tools/gen_presets.py to refresh CMake presets.

For readme I think it's redundant (you can improve docs/getting_started.rst for Mac if you want)

So, if necessary I can make a separate PR with 6 channels usb mic descriptor + adjust the python drawing sample for supporting multiple usb mic devices

Glad it works ! You can improve the script if you want, but for the descriptor I think the usage of 6CH mic is relatively few, better to keep usbd.h not too big.

fallow birchBOT
fallow birchBOT
fallow birchBOT
#

๐Ÿ’ก Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: ab63ef436d

โ„น๏ธ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with ๐Ÿ‘.

Codex can also answer questions or u...

#

<sub><sub>P1 Badge</sub></sub> Initialize control EP0 PID to DATA1 before data stage

Control transfers on EP0 must begin data/status stages with DATA1, but endpoints are initialized with next_pid = 0 here and only corrected when direction flips later. For control writes where setup and data are both OUT (0x00), the direction does not flip, so packets are sent with DATA0 and can trigger data-sequence errors or stalls on compliant ...

#

<sub><sub>P1 Badge</sub></sub> Reset EPX transfer state when closing a removed device

When closing a disconnected device, this path only clears max_packet_size on the active shared EPX entry and does not clear active/transfer state. Because the later cleanup loop filters on max_packet_size > 0, that same endpoint is skipped and can remain logically active, so subsequent transfers can be queued as pending forever after unplug/re...

fallow birchBOT
#

thank you very much for the PR. I have tried this out quite a bit but got into quite a bit of issues with both testing and out-of-sync issue with master. The implemention is good but I found it is a bit more complicated than I would like to. For example we don't need to keep setup per endpoint since usbh will only carray 1 control transfer at a time. Also I think we should contiune to use hardware interrupt endpoints for interrupt endpoint and epx for bulk/control/iso only. There is lots of h...

fallow birchBOT
#

Pull request overview

Updates the vendored FatFS library under lib/fatfs/source to ChaN FatFS R0.16 (2025), bringing in upstream fixes and feature work (notably exFAT getcwd / .. path handling and directory iteration fixes).

Changes:

  • Sync core FatFS sources (ff.c, ff.h) and documentation (00history.txt, 00readme.txt) to R0.16.
  • Update FatFS configuration template (ffconf.h) to the new revision ID and option set.
  • Refresh disk I/O skeleton headers/sources (`dis...
fallow birchBOT
fallow birchBOT
fallow birchBOT
fallow birchBOT
#

Pull request overview

This PR adjusts the RP2040 native USB host/device implementation to improve robustness when sharing the single host โ€œEPXโ€ endpoint across multiple devices (notably EP0/control traffic), adds additional error/timeout handling in the host ISR, and tweaks RP2040/RP2350 SDK compatibility.

Changes:

  • Replace short cycle-based โ€œconcurrent accessโ€ delays with busy_wait_us(1) in several USB register write paths.
  • Rework host EP0 handling to always use the shared EPX,...
#

This introduces a new non-static exported function hcd_free_ep_count(), but it is not declared in any header and is not referenced anywhere else in the repo. Keeping an unadvertised global symbol in a portable driver makes the surface area harder to reason about; consider making it static (if only for local diagnostics), gating it behind a debug macro, or removing it if unused.

#

Potential stale interrupt_num: when opening a non-interrupt endpoint, interrupt_num is never explicitly cleared. Since endpoints are recycled by edpt_alloc() using only max_packet_size==0, a slot previously used for an interrupt endpoint can be reused for bulk/iso while retaining a nonzero interrupt_num, causing later xfers to go down the interrupt-endpoint path incorrectly. Ensure interrupt_num is set to 0 for non-interrupt endpoints (and/or fully cleared when freeing an endpoint...

fallow birchBOT
fallow birchBOT
#
[hathach/tinyusb] New branch created: fatfs-r0.16
#

Summary

  • Update FatFS from R0.15 to R0.16 using abbrev/fatfs GitHub mirror as a managed dependency via get_deps.py instead of vendoring source files
  • Move TinyUSB custom ffconf.h to examples/host/msc_file_explorer/src/ to keep project-specific settings separate from upstream
  • Remove ~24K lines of vendored FatFS source from git tracking

Based on #3581 by @non-bin. Rebased to current master with CI fixes.

Key changes

  • tools/get_deps.py: Added lib/fatfs to `deps_manda...
#

Pull request overview

This PR updates TinyUSBโ€™s FatFS integration from vendored R0.15 sources to a managed dependency (abbrev/fatfs) pinned to an R0.16 commit, and relocates TinyUSBโ€™s custom ffconf.h into the msc_file_explorer example so project-specific settings stay out of the upstream mirror.

Changes:

  • Add lib/fatfs as a mandatory dependency in tools/get_deps.py and remove upstream ffconf.h after cloning so the exampleโ€™s custom config is used.
  • Update the example-spe...
#

The new deps_remove_files step assumes p is already an initialized git repo when p.exists() is true. Since lib/fatfs used to be a vendored directory, some worktrees may still have a non-git lib/fatfs/ present (e.g., leftover untracked files), causing git rev-parse HEAD to fail earlier and the script to crash on splitlines()[0]. Consider detecting a missing .git/ (or non-zero rev-parse) and re-initializing/cleaning the directory before continuing.

#

Size Difference Report

Because TinyUSB code size varies by port and configuration, the metrics below represent the averaged totals across all example builds.

Note: If there is no change, only one value is shown.

Changes >1% in size

No entries.

Changes <1% in size

No entries.

<details><summary>No changes</summary>

file .text .rodata .data .bss size % diff
audio_device.c...
fallow birchBOT
fallow birchBOT
#
[hathach/tinyusb] New branch created: fix-hil
#

๐Ÿ’ก Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 99b721db60

โ„น๏ธ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with ๐Ÿ‘.

Codex can also answer questions or u...

#

<sub><sub>P1 Badge</sub></sub> Break sys_write loop when UART makes no progress

This loop never exits if board_uart_write() returns 0 or a negative value repeatedly, because written is only updated for wr > 0. Several BSP implementations legitimately return 0 when UART is not configured (for example, rp2040 without UART_DEV), so any printf/log call can hang forever in _write. The retry path should handle non-progress by r...

#

<sub><sub>P1 Badge</sub></sub> Use remaining length when retrying console writes

The retry loop passes the original count to console_write() even after wr has advanced, so on a partial write the next iteration reads past the end of the received CDC buffer and can transmit unrelated memory. This is reproducible whenever board_putchar() is temporarily unable to accept all bytes (the non-blocking path this change targets), becau...

#

Pull request overview

This PR adjusts UART/stdio behavior and host CDC example logic to improve reliability of CDC echo testing on fast MCUs (notably IMXRT), and adds configurability to HIL retry behavior.

Changes:

  • Make some BSP UART/stdio helpers non-blocking-friendly (e.g., board_uart_write() on IMXRT; board_putchar() now returns int).
  • Add retry/looping behavior around UART writes (sys_write) and update host CDC example/config to better handle rapid transfers.
  • Update ...
#

sys_write() can spin forever if board_uart_write() returns 0 (e.g. non-blocking UART TX FIFO full) or a negative error: the loop has no backoff/yield/timeout and only advances on wr > 0. This can hard-hang logging/printf and consume 100% CPU. Consider handling wr <= 0 (e.g. small delay/yield, retry limit/timeout, or returning the partial count / error) to avoid infinite busy-wait.

  int retry_count = 0;
  const int max_retry = 1000;

  while ((size_t) written < count) {
...
#

max_retry is only assigned in main(), but test_board()/test_example() are executed in multiprocessing.Pool workers. With the "spawn" start method (Windows/macOS default), workers import this module without running main(), so max_retry will be undefined here and raise NameError. Define max_retry at module scope (default 3) and/or pass retry count into worker functions (or use a Pool initializer) instead of relying on a main()-initialized global.

#

The do { ... } while (wr < count) loop can overrun the buffer and can also hang:

  • console_write(buf + wr, count) should use the remaining length (count - wr), otherwise it may read past the end of buf once wr > 0.
  • If console_write() returns 0 (e.g. board_putchar() temporarily canโ€™t write), wr never increases and this becomes an infinite loop.
    Adjust the length argument and add a break/backoff when no progress is made.
    if (count > wr) {
      size_t const r...
#
[hathach/tinyusb] New branch created: fix/rp2350-unaligned-memcpy
#

Summary

  • Use volatile byte accesses in unaligned_memcpy() to prevent the compiler from widening the byte-by-byte loop into 16/32-bit accesses, which cause a hard fault on RP2350 when targeting USB DPRAM (device memory)
  • Simpler alternative to #3554 โ€” same root cause fix with minimal code change and zero code size impact

Closes #3554

Detail

On RP2350, the compiler optimizes the plain *dst++ = *src++ loop into wider 16/32-bit accesses for performance. When the destination is US...

#

Pull request overview

This PR updates the RP2040 USB portโ€™s unaligned_memcpy() helper to force true byte-sized loads/stores, preventing the compiler from generating unaligned 16/32-bit accesses that can hard-fault on RP2350 when copying to/from USB DPRAM (device memory).

Changes:

  • Add volatile byte pointers in unaligned_memcpy() to inhibit access-width widening optimizations.
  • Clarify the rationale in comments (RP2350 USB DPRAM hard-fault scenario).

๐Ÿ’ก Add Copilot cu...

#

This PR fixes a bug for the UART pin initialization for Teensy boards.

For the teensy_40 and teensy_41 boards, in board.h, we correctly select UART6

#define UART_PORT             LPUART6

However, there was a copy-paste bug in pin_mux.c where we instead muxed UART1 to the chip pads.
This is now fixed by muxing the correct UART6 to the respective output pins.

This is also convenient because UART1 is not even accessible via the headers on the teensy_40.

fallow birchBOT
#

These are the problems my changes address. Keep in mind I have a complete MSC implementation with BOT, CBI, LUN, removable media, LBA64, and even TRIM support so I hit code parts that the examples do not, especially concerning removable media error recovery.

  • busy_wait_at_least_cycles uses the CPU clock instead of the SIE clock
  • Devices refuse to mount, e.g. a hub with MSC-BOT, CDC, and HID won't mount the HID.
  • Removing devices from hub causes panic hcd_clear_stall.
  • Too many endpo...
fallow birchBOT
fallow birchBOT
fallow birchBOT
fallow birchBOT
fallow birchBOT
fallow birchBOT
fallow birchBOT
fallow birchBOT
#
[hathach/tinyusb] New branch created: pr3581
fallow birchBOT
fallow birchBOT
#

Size Difference Report

Because TinyUSB code size varies by port and configuration, the metrics below represent the averaged totals across all example builds.

Note: If there is no change, only one value is shown.

Changes >1% in size

No entries.

Changes <1% in size

No entries.

<details><summary>No changes</summary>

file .text .rodata .data .bss size % diff
audio_device.c...
fallow birchBOT
#

๐Ÿ’ก Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 1293317765

โ„น๏ธ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with ๐Ÿ‘.

Codex can also answer questions or u...

#

<sub><sub>P1 Badge</sub></sub> Guard STM32F7 UART code with the board macro

The UART implementation is now compiled only when UART_ID is defined, but STM32F7 board headers still define UART_DEV (for example hw/bsp/stm32f7/boards/stm32f746disco/board.h). That means board_init() skips UART setup and board_uart_write()/board_uart_read() fall back to the no-UART stubs for every STM32F7 board, so stdio/log output silently stops ...

#

family.c switched UART enable path from UART_DEV (as provided by STM32F7 board headers) to a new UART_ID macro, but none of the STM32F7 board headers define UART_ID (they define UART_DEV/UART_CLK_EN). As a result, UART initialization and the IRQ handler are compiled out and UART logging/IO silently stops working on existing STM32F7 boards. Consider reverting to UART_DEV (or supporting both macros), or updating all STM32F7 board headers/build flags to define UART_ID consistently.

#

--specs=nosys.specs/--specs=nano.specs are GCC driver options; moving them into unconditional LDFLAGS means they will also be passed when building with the make arm_clang toolchain (examples/build_system/make/toolchain/arm_clang.mk), where clang typically rejects --specs. To keep clang builds working, gate these flags behind ifeq ($(TOOLCHAIN),gcc) (or move them into the GCC toolchain makefile) and provide a clang-compatible alternative if needed.

#

With UART_ID undefined for STM32F7 boards, board_uart_read()/board_uart_write() now always return 0 even when the board provides UART_DEV. This is a behavioral regression compared to the previous HAL_UART_Transmit()-based implementation and will break UART-based logging. Align the UART feature-guard with the board contract (e.g., #ifdef UART_DEV) or ensure UART_ID is provided for all boards that expect UART.

#

Pull request overview

Removes IAR toolchain support from the make build system by consolidating toolchain-specific variables into generic ones, deleting IAR make toolchain files, and updating family/board makefiles accordingly. Also includes a small MSC file explorer fix and STM32F7 UART formatting/logic changes.

Changes:

  • Remove IAR make toolchain integration (deleted arm_iar.mk / iar_rules.mk, removed IAR selection paths in make CPU/toolchain logic).
  • Update BSP family/bo...
worthy bluff
#

Hello. This is my first post here. I am strugling with Feather Wing USB Host (with MAX3421E) stacked to ESP32 Feather V2. I have a pyrometer that is connected to USB Host module (its serial parameters are 115200 8E1 and cannot be changed). I have tried few examples from Arduino IDE and I managed to received a packet (but it is scambled - I think because TinyUSB library has 8N1 => parity NONE by default and also cannot be changed - not yet implemented). Can anyone help me with that. If I connect pyrometer directly to PC then COM Port is created (COM4 for example). Then I start putty (with serial settings 115200 8E1) everything works as expected. I also find an example (host_device_info_max3421e) which also works fine. So now I have: an example that successfully reads device info and example that can receive a packet, but something is not set up correctly since message is not ok. I am pressing F1 multiple times ๐Ÿ™‚

worthy bluff
#

These are the examples

fallow birchBOT
#

Operating System

Linux

Commit SHA

aa0fc2e08f1c2dd6f026a431e8989357fbb4c5bf

Board

STM32N6

Firmware

micropython-latest

What happened ?

Updating the endpoint sizes to:

// USB CDC config
#define CFG_TUD_CDC_EP_BUFSIZE  (4096)
#define CFG_TUD_CDC_RX_BUFSIZE  (4096)
#define CFG_TUD_CDC_TX_BUFSIZE  (4096)

... from 512 bytes by default appears to break transactions exactly at 512 bytes.

More details on this MicroPython PR: https://github.com/micropython/micropy...

fallow birchBOT
#

Update: Feather RP2040 USB Host tested

@hathach As promised, the Adafruit Feather RP2040 with USB Type A Host has been tested. Board-to-board with an RP2040 Pico running the midi2_device example, SSD1306 128x64 OLED on the STEMMA QT connector.

Added examples/host/midi2_host_feather/ as a board-specific variant with:

  • PIO-USB on GP16/GP17
  • I2C1 via STEMMA QT (GP2/GP3) for the display
  • USB Host 5V power enable on GP18 (required to power the connected device)
  • Improved display: splas...
fallow birchBOT
fallow birchBOT
fallow birchBOT
#

This change extracts the STM32 FSDEV PMA buffer description table errata workaround from HCD-local logic into shared FSDEV common code, and applies the same workaround path to DCD. It also makes delay timing configurable via macros instead of fixed literals.

  • Errata workaround moved to shared FSDEV common layer

    • Added fsdev_btable_workaround_delay(bool low_speed) in fsdev_common.c/.h.
    • Centralizes the PMA BTable post-CTR delay used before reading PMA count/data.
  • **DCD now u...

#

Size Difference Report

Because TinyUSB code size varies by port and configuration, the metrics below represent the averaged totals across all example builds.

Note: If there is no change, only one value is shown.

Changes >1% in size

file .text size % diff
fsdev_common.c 180 โž™ 188 (+8) 180 โž™ 188 (+8) +4.4%
TOTAL 180 โž™ 188 (+8) 180 โž™ 188 (+8) +4.4%

Chang...

fallow birchBOT
#

Currently USBH only manage one control transfer:

  • Enumeration will fail if we're unlucky that we are setting the DTR of another device or something.
  • Vice versa, when we try to do ctrl transfer during enumeration, what's worse is since usbh_get_enum_buf() is not locked, enumeration data can be corrupted.

To fix it there are multiples way with pros/cons:

  1. Move _usbh_epbuf and ctrl_xfer_info into each device struct
    Pro: Fully concurrent, would be nice if one day we add DFU host.
    Con...
fallow birchBOT
fallow birchBOT
fallow birchBOT
#
[hathach/tinyusb] New branch created: worktree-fix-stm32h5-uid-icache
#

Summary

  • On STM32H5, reading UID_BASE with ICACHE enabled causes a hard fault (ST errata)
  • Cache the unique ID at the very start of board_init(), before any user code can enable ICACHE
  • board_get_unique_id() now returns the cached copy instead of reading UID_BASE directly

Closes: https://github.com/hathach/tinyusb/discussions/3588

Test plan

  • [x] Builds cleanly for stm32h563nucleo (cdc_msc example)
  • [ ] Verify on STM32H5 hardware with ICACHE enabled that USB serial numbe...
#

board_get_unique_id() now returns data from cached_uid, which is only populated in board_init(). If this API is called before board_init() (or if board_init() is skipped), it will silently return an all-zero ID, which can lead to non-unique USB serial numbers. Consider adding a uid_cached flag (set after copying) and either return 0 when not cached, or populate the cache lazily only when ICACHE is confirmed disabled, so the failure mode is explicit and safe.

#

Pull request overview

Fixes an STM32H5 errata-triggered hard fault by avoiding UID_BASE reads after the instruction cache may be enabled, by caching the UID early during board initialization and returning the cached value thereafter.

Changes:

  • Add a static cached_uid buffer to store the STM32H5 UID.
  • Populate cached_uid at the very start of board_init().
  • Update board_get_unique_id() to return the cached UID instead of reading UID_BASE.

๐Ÿ’ก Add Copilot custom i...

#

Size Difference Report

Because TinyUSB code size varies by port and configuration, the metrics below represent the averaged totals across all example builds.

Note: If there is no change, only one value is shown.

Changes >1% in size

No entries.

Changes <1% in size

No entries.

<details><summary>No changes</summary>

file .text .rodata .data .bss size % diff
audio_device.c...
fallow birchBOT
fallow birchBOT
#

The new compile-time guard errors for any unknown STM32 when CFG_TUSB_FSDEV_32BIT is set, even if a board wants to override the errata timing via CFG_TUSB_FSDEV_BTABLE_{FS,LS}_DELAY_COUNT as described in the PR. Consider only erroring when neither FSDEV_STM32_CPU_MHZ nor the delay-count override macros are provided, so new/unsupported 32-bit STM32 FSDEV targets can build when users supply explicit delay counts.

#

Pull request overview

This PR refactors the STM32 FSDEV 32-bit PMA Buffer Description Table (BTable) errata delay workaround into shared FSDEV common code, reusing it from both host (HCD) and device (DCD) paths while making the delay timing configurable via macros.

Changes:

  • Introduced a shared fsdev_btable_workaround_delay(bool low_speed) static-inline helper and default delay-count macros in fsdev_common.h.
  • Updated STM32 FSDEV HCD/DCD code paths to call the shared helper ins...
fallow birchBOT
#

<!-- membrowse-pr-comment -->

<img src="https://membrowse.com/membrowse-logo.svg" height="24" align="top"> MemBrowse Memory Report

Top 10 targets by memory change (%) (out of 2156 targets) View Project Dashboard โ†’

target .text .rodata .data .bss total % diff
[stm32h503nucleo/dynamic_switch](https://membrowse...
fallow birchBOT
#

perfect, thank you. Tested and it works well. I haven't tested with ISO just yet, but I think we could do that with follow-up PR. This is great start for nrf54 series. I update board_uart_read/write(), move the init sequence to dwc2_clock_init() which is run before accessing the dwc2 register, also fix freeRTOS config for secure mode. The speed isn't great for highspeed device, it could be dwc2 not optimized enough, will come back to this later.

nrf54lm20dk                              d...
#

Pull request overview

This PR adds initial TinyUSB BSP/port support for the Nordic nRF54LM20 DK, including DWC2 (USBHS) bring-up steps and build-system plumbing, plus a small refactor of the DWC2 FIFO sizing configuration to use DFIFO depth (words) instead of byte-sized SRAM constants.

Changes:

  • Refactor DWC2 controller configuration to use otg_dfifo_depth (32-bit words) and call a new dwc2_clock_init() hook before any DWC2 register access.
  • Add nRF54LM20 DK board support (link...
#

This diagram line says "gdfifocfg.EPINFOBASE (= gdfifocfg.GDFIFOCfg)", but (1) the field name casing is wrong (GDFIFOCFG_GDFIFOCFG), and (2) itโ€™s not an equality so much as "EPINFOBASE marks the start of EPInfo and GDFIFOCFG is the depth". Consider rewording to reflect the two 16-bit fields of GDFIFOCFG rather than implying EPINFOBASE equals the other field.

  |-------------|-- gdfifocfg.EPINFOBASE (start of EPInfo; FIFO space sized by GDFIFOCFG)
#

DFIFO depth is documented here as being in 32-bit words, but STM32U5 defines DFIFO_DEPTH_FS=1280 and DFIFO_DEPTH_HS=4096, which look like byte counts (matching the old EP_FIFO_SIZE_* values). This will make FIFO allocation calculations think the core has 4ร— more SPRAM than it really does and can lead to invalid GDFIFOCFG / FIFO sizing. Convert these to word units (e.g., divide by 4) or source the correct OTG_DFIFO_DEPTH values from the U5 reference manual/header macros and use those consisten...

fallow birchBOT
#

Resolves an issue in the musb handle_xfer_out function where not all execution paths cleared the MUSB_RXCSRL1_RXRDY bit, causing the RX interface to hang and no longer communicate with the host.

This issue was discovered while using the RNDIS class in a media converter application. When running iperf testing at full speed (10Mbps link) the USB stack was under constant load of packets and eventually would stop receiving new frames from the host PC. Other USB events and interrupts were ...

fallow birchBOT
#

USB wire format is little-endian, but TinyUSB assumed host byte order == little-endian
in two places:

  1. dcd_event_setup_received() (dcd.h): after memcpy-ing the raw SETUP bytes into
    tusb_control_request_t, wValue/wIndex/wLength were left in wire byte order.
    Fix: apply tu_le16toh() on each field. On LE hosts this is a no-op.

  2. Bit-field structs (tusb_types.h): GCC on big-endian ARM allocates bit fields
    from the MSB downward, opposite to the USB spec's LSB-first numbering...

fallow birchBOT
fallow birchBOT
fallow birchBOT
#
[hathach/tinyusb] New branch created: worktree-rp2040-freertos
#

Summary

  • Add FreeRTOS support for the RP2040 (Pico) and RP2350 (Pico 2) families using
    https://github.com/raspberrypi/FreeRTOS-Kernel which provides proper SMP ports for both platforms
  • Refactor rp2040/family.cmake to use family_configure_common() from family_support.cmake, reducing duplication
  • Remove mcu:RP2040 from all FreeRTOS example skip.txt files

Changes

  • hw/bsp/rp2040/FreeRTOSConfig/FreeRTOSConfig.h (new) โ€” FreeRTOS config based on...
#

Pull request overview

Adds FreeRTOS (SMP) integration for the RP2040/RP2350 BSP by pulling in Raspberry Piโ€™s FreeRTOS-Kernel fork, refactoring RP2040 family CMake to use shared helpers, and updating examples to enable RP2040 FreeRTOS builds.

Changes:

  • Integrate RP2040 FreeRTOS via the Raspberry Pi FreeRTOS-Kernel fork and add a RP2040 FreeRTOSConfig.
  • Refactor RP2040 family CMake to use family_configure_common() / family_add_rtos() from family_support.cmake.
  • Unskip RP2040 f...
#

vApplicationStackOverflowHook() passes pcTaskName to panic("...%s", pcTaskName). FreeRTOS may provide a NULL task name (depending on config/port), and passing NULL to %s is undefined behavior and can crash while handling the overflow. Consider guarding with a fallback string when pcTaskName == NULL (and the (void) pcTaskName; line becomes unnecessary).

  panic("FreeRTOS stack overflow: %s", pcTaskName != NULL ? pcTaskName : "unknown");
#

family_add_default_example_warnings() now applies ${WARN_FLAGS_*} (which include -Werror) to all example target sources via get_target_property(... SOURCES) without filtering out third-party sources under ${TOP}/lib. Many examples add lwIP/fatfs/etc sources from ${TOP}/lib, so this change can turn external-library warnings into hard build failures. Consider restoring the previous ${TOP}/lib filter (or otherwise limiting per-source warnings to TinyUSB + example-owned sources) a...

#

audio20_control_cur_2_t::bCur is defined as int16_t (signed volume in dB/256). Casting it to uint16_t changes semantics for negative volumes (they become large positive values) and makes the %d log output misleading. Prefer storing volume as int16_t (or cast to int16_t and update the volume[] type accordingly) to preserve signed volume behavior.

        int16_t volume_db = ((audio20_control_cur_2_t *) pBuff)->bCur;
        volume[channelNum] = volume_db;
        TU...
#

set_source_files_properties(... PROPERTIES COMPILE_OPTIONS "-Wno-conversion -Wno-cast-qual") sets a single compile option containing a space, which most compilers will treat as an unknown option and fail the build. COMPILE_OPTIONS should be a CMake list (e.g. separate -Wno-conversion and -Wno-cast-qual entries) or use COMPILE_FLAGS if you intend to pass a single string.

    COMPILE_OPTIONS -Wno-conversion -Wno-cast-qual
#

๐Ÿ’ก Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: b55786e43a

โ„น๏ธ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with ๐Ÿ‘.

Codex can also answer questio...

#

<sub><sub>P2 Badge</sub></sub> Split Clang suppression flags into separate options

This sets COMPILE_OPTIONS to one space-delimited string, so Clang receives a single unknown option (-Wno-conversion -Wno-cast-qual) instead of two flags. For non-RP2040 families, family_configure_common() applies WARN_FLAGS_Clang with -Werror (in hw/bsp/family_support.cmake), which makes that unknown-option warning fail the build for `msc_f...

fallow birchBOT
#

Size Difference Report

Because TinyUSB code size varies by port and configuration, the metrics below represent the averaged totals across all example builds.

Note: If there is no change, only one value is shown.

Changes >1% in size

No entries.

Changes <1% in size

| file | .text | .rodata | .data | .bss | size | % diff |
| :------------- | ---------------: | ------: | ---------------: | ---------------: | ---------------: | -...

fallow birchBOT
fallow birchBOT
#

Pull request overview

This PR aims to make TinyUSB work correctly on big-endian CPUs by (1) converting multi-byte SETUP fields from USB wire (little-endian) to host byte order and (2) making USB bitfield parsing deterministic across endian/compilers.

Changes:

  • Convert SETUP packet wValue/wIndex/wLength to host endianness in dcd_event_setup_received().
  • Add a TU_BITFIELD_ORDER mechanism and use it to select correct bitfield layouts for bmRequestType_bit and endpoint `bmAttri...
#

TU_BITFIELD_ORDER is only defined in the GCC/TI and IAR compiler branches, but not in the __CCRX__ branch (which is still supported and defines TU_ATTR_BIT_FIELD_ORDER_BEGIN). With the new #error checks in tusb_types.h, CCRX builds will now fail because TU_BITFIELD_ORDER will be undefined. Please define TU_BITFIELD_ORDER for __CCRX__ as well (likely TU_BITFIELD_LE if #pragma bit_order right is intended to enforce LSB-first allocation).

#

dcd_event_setup_received() now converts wValue/wIndex/wLength to host endianness. There is at least one in-tree caller that still applies tu_le16toh() to these fields (src/device/usbd.c passes tu_le16toh(p_request->wIndex) into tud_descriptor_string_cb()), which will double-swap on big-endian and break string descriptor requests (e.g., langid 0x0409 becomes 0x0904). After this change, the device stack should treat tusb_control_request_t fields as host-endian everywhere and remove ...

fallow birchBOT
fallow birchBOT
fallow birchBOT
#

This PR updates src/portable/wch/hcd_ch32_usbfs.c to improve:

  1. Lack of retry logic for NAK response
  2. Device enumeration failures on some devices
  3. Unstable plug/unplug behavior via USB hub
  4. Low Speed devices couldn't be enumerated in some cases.

After the commit 13e0b0c4f149016c829f039dc082151bca01174f, some USB device couldn't be enumerated at CH32 USBFS Host.

  • Adjusted retry logic for enumeration failures and interrupt transfer stalls
  • Added per-SOF retry limiting an...
fallow birchBOT
fallow birchBOT
#
[hathach/tinyusb] New branch created: fix-conversion-warnings
#

Pull request overview

This PR aims to reduce/eliminate -Wconversion / -Wsign-conversion warnings across multiple MCU/USB controller ports by making narrowing/bitwise operations explicit (casts, unsigned literals) and, in a few cases, suppressing warnings originating from vendor headers.

Changes:

  • Add explicit casts for arithmetic/bitfield operations that intentionally narrow (e.g., tu_div_ceil() results, register bitfields, endpoint IDs).
  • Replace signed shift literals with u...
#

SEGGER_RTT_Write() takes an unsigned NumBytes (see lib/SEGGER_RTT/RTT/SEGGER_RTT.h). Passing count (a size_t) without an explicit cast can still trigger -Wconversion on targets where size_t is wider than unsigned (or differs in signedness). Consider casting to unsigned (and, if desired, clamping) before calling to keep the intent explicit and avoid reintroducing the warning this PR is addressing.

#

Hello, I've been thinking about that the last few days, and here are some thoughts:

I think the problem of functions like tuh_cdc_set_line_coding() should be handled differently if used asynchronously (with or without rtos) or synchronously (with rtos).

For asynchronous calls, I think the allocation of all the required memory should be handled outside of the tinyusb library, so the application can decide what they wants.

An application could allocate only one static buffer and call all c...

fallow birchBOT
fallow birchBOT
fallow birchBOT
#
[hathach/tinyusb] New branch created: musb-followup-3594
#

Pull request overview

Adds follow-up improvements for the MUSB device controller and expands HIL coverage by adding a throughput/iperf validation test for the net_lwip_webserver example.

Changes:

  • Add a new HIL test that enumerates the USB network interface and runs an iperf throughput check.
  • Refactor MUSB endpoint transfer state tracking (buffer vs FIFO) and add โ€œarmedโ€ tracking to handle unposted OUT data more robustly.
  • Ensure net_lwip_webserver builds iperf support by def...
#

The test hard-codes the Linux interface name as enx<mac>; depending on distro/udev settings the interface may instead appear as usb0, ethX, etc. Since you already know the MAC, consider discovering the interface by scanning ip -o link for link/ether 02:02:84:6a:96:00 (or via sysfs) and using the found interface name, which will make the HIL test much less environment-dependent.

    # MAC hard-coded in examples/device/net_lwip_webserver/src/main.c. Discover the
    # co...
#

This assumes the host iperf binary is iperf2 and supports -y C CSV output. On many hosts iperf is iperf3 (which doesnโ€™t accept -y), which will cause a hard failure unrelated to the device. Consider explicitly invoking iperf2 if thatโ€™s what CI installs, or probing iperf --version/argument support and returning 'skipped' (with a clear message) when the required tool isnโ€™t available.

#

INCLUDE_IPERF is now always defined by default, and the example uses #ifdef INCLUDE_IPERF in main.c, so this effectively makes iperf unconditionally compiled in and difficult to disable (even -DINCLUDE_IPERF=0 wonโ€™t help). If the intent is optional inclusion, consider switching to a value macro (default 1) and gating with #if INCLUDE_IPERF, or only defining it in the specific HIL build configuration that needs it to avoid code size regressions on smaller MCUs.


#

handle_xfer_in() never reaches the completion path for a zero-length IN transfer (pipe->length == 0 and pipe->remaining == 0). In that case it will keep setting TXRDY with len == 0 on every TX interrupt, which can result in repeated ZLPs and the transfer never completing (USBD endpoint stays busy). Consider explicitly supporting ZLP transfers on non-EP0 (e.g., track whether the ZLP has already been queued/sent and complete after the first TX interrupt).

#

๐Ÿ’ก Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 9d0af750a5

โ„น๏ธ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with ๐Ÿ‘.

Codex can also answer questio...

#

<sub><sub>P1 Badge</sub></sub> Preserve ISR context when completing staged OUT transfer

When an OUT packet is staged in FIFO and dcd_edpt_xfer() is called from ISR context (is_isr=true is used by class ISR paths such as audio), this path completes the transfer immediately but hard-codes false in dcd_event_xfer_complete. That mislabels an ISR-originated event as task context, so OSAL queue/spinlock code may take non-ISR paths ...

fallow birchBOT
fallow birchBOT
fallow birchBOT
#

On RP2040 boards that expose an SD card as a second MSC LUN (via CircuitPython's CIRCUITPY_SDCARD_USB), macOS stalls the bulk-IN endpoint during multi-sector READ(10) probes when CFG_TUD_MSC_EP_BUFSIZE is the default 1024 bytes. macOS retries ~18 times over ~5 minutes then gives up. Linux handles the same firmware cleanly.

Bumping to 16 KB fully resolves the stall โ€” but that's a 16 KB RAM cost and shouldn't be pushed on all boards.

Tested (CircuitPython 10.1.4 stable)

| Board | C...

fallow birchBOT
fallow birchBOT
fallow birchBOT
#

Operating System

Windows 11

Commit SHA

86ad6e56c1700e85f1c5678607a762cfe3aa2f47

Board

custom rp2350 based board

Firmware

Custom RP2040 firmware, not a stock TinyUSB example. Uses USB Audio Class with an isochronous IN endpoint (and CDC present), built with Pico SDK 2.2.0 / TinyUSB 0.18.0. Not using USB stdio.

I have not yet reduced this to a minimal repro, but the issue appears in the audio SET_INTERFACE alt 1 -> 0 -> 1 reopen path, with logs and a small `dcd_rp2040....

#

thanks for pointing out the duplicate! sorry, I did not realise it is old, and did try to make a high quality issue report. seems i failed to search your issues well enough ;(
.
Somehow I did not manage to find the duplicate issue(s). as someone not following tinyusb dev closely, its hard to keep up. the previous pico sdk bundled 0.17 that had a memory leak. the issue you link is dec 2025 and this is considered 'old' but hasnt trickled into downstream places like pico. I know that's not your...

fallow birchBOT
#

hello! this PR doesnt seem to be in the current 0.20 release. i'm looking to upgrade from 0.18 to 0.20 after filing an (unfortunately dupllicate, sorry) unrelated issue on a bug that is fixed in 0.19 and up. however, on upgrading to 0.20 i'm hit by the bug that this PR fixes. I'm unsure how to proceed - should I start tracking master, apply this patch to 0.20, or is there somewhere I can go to see what the release plan is for 0.20.1? im working on a device where I value stability but i've bou...

fallow birchBOT
#

Summary

  • Add OPT_MCU_ESP32S31 to the MCU option list (911, Espressif vendor range)
  • Wire S31 into tusb_mcu.h: DWC2 USBIP, HS-only, 16 endpoints, multi-core,
    slave/DMA toggle
  • Add S31 HS controller entry in dwc2_esp32.h (reg base 0x20300000, 4096 FIFO,
    ETS_USB_OTGHS_INTR_SOURCE); skip soc/usb_wrap_struct.h include since S31 has
    no USB_WRAP peripheral
  • Skip USB_WRAP pull configuration for S31 in dcd_connect()/dcd_disconnect()
  • Include S31 in BSP `usb_init...
fallow birchBOT
#

usb_init is prototyped here as usb_init(uint8_t rhport, bool is_host), but in the #else branch for ESP_IDF_VERSION < 5.3.0 the function is defined as bool usb_init(void). If that legacy branch is ever compiled, this is a conflicting declaration/definition and will fail to compile. Consider moving the prototype under the same ESP_IDF_VERSION conditional (or make the legacy implementation match the newer signature and ignore the extra args).

#if TU_CHECK_MCU(OPT_MCU_ES...
#

In the ESP32-S31 controller descriptor, .ep_count/.ep_in_count are hard-coded even though DWC2_EP_MAX is defined just above. Consider using DWC2_EP_MAX (and a single source for IN count if applicable) to avoid accidental divergence if the endpoint count changes later.

#define DWC2_EP_IN_MAX     8

static const dwc2_controller_t _dwc2_controller[] = {
  { .reg_base = DWC2_HS_REG_BASE, .irqnum = ETS_USB_OTGHS_INTR_SOURCE, .ep_count = DWC2_EP_MAX, .ep_in_count = DWC2_EP_IN_...
fallow birchBOT
#

Update โ€” this is likely misdirected, pure tinyusb works fine.

Built examples/device/msc_dual_lun unmodified for BOARD=raspberry_pi_pico (uses the rp2040 family BSP), flashed to an Adafruit Feather RP2040 Adalogger on a macOS 26.x Apple Silicon host โ€” both LUNs mount cleanly:

/dev/disk4  TinyUSB 0   (LUN 0)
/dev/disk5  TinyUSB 1   (LUN 1)

Both IOMedia nodes publish in the macOS kernel log, both are readable. Same chip, same host, same USB path as the CP build that fa...

fallow birchBOT
#

This one is actually a pre-existing issue, not something introduced by this PR.
The forward declaration at the top of the file (static bool usb_init(uint8_t rhport, bool is_host);) matches the primary definition used on ESP32-S2/S3/H4/P4/S31. The mismatched zero-argument bool usb_init(void) is a legacy fallback that only compiles on ESP32-S2/S3 with ESP-IDF < 5.3.0 (the branch taken when usb_new_phy_* isn't available), so it has been silently out of sync since commit c0adaca3a ("fix e...

#

I don't think this change would be correct โ€” DWC2_EP_MAX and .ep_count / .ep_in_count are semantically different values that happen to coincide on S31.
Per the port-header contract in dwc2_common.h (line 43), DWC2_EP_MAX is documented as "largest EP counts of all controllers" โ€” a compile-time cross-controller maximum used to size shared arrays in the driver (e.g. xfer_status[DWC2_EP_MAX][2] in dcd_dwc2.c). The .ep_count / .ep_in_count fields are the actual per-controller ...

fallow birchBOT
#

Hi @hathach, a small spec-compliance sweep on top of the driver, all in one commit (31d730d8b).

The sweep aligns the descriptors with the USB Device Class Definition for MIDI Devices v2.0 (USB-IF, May 2020): Alt 1 MS Header wTotalLength now reports 0x0007 per Table 5-2, the GTB GET_DESCRIPTOR class request validates bmRequestType / wIndex / wValue high byte per Section 6, and iBlockItem is now driven by CFG_TUD_MIDI2_BLOCK_STRIDX per Table 5-6. Added an anti-regression asse...

fallow birchBOT
#

midi host: tuh_midi_stream_read can leave bytes in FIFO on cable-number transition, silently wedging bulk IN polling

Commit SHA: current master (reproduced against ~2026-03-18 snapshot)
Board / host controller: STM32H753 (Synopsys DWC2 OTG, full speed)
Device reproducer: Akai LPD8 mk1 โ€” VID 0x09E8, PID 0x0075

Summary

After the fix in #3239 (commit 0263cfc) landed, we still hit a related-but-distinct wedge with the same device. tuh_midi_stream_read returns to the ...

fallow birchBOT
#

Follow-up to #3239. That fix addressed garbage bytes in the data position of USB-MIDI event packets. A related wedge remains when a packet contains events whose header byte (cable number) varies mid-buffer, because tuh_midi_stream_read terminates on cable-number transitions rather than on end-of-FIFO.

With the default CFG_TUH_MIDI_RX_BUFSIZE = TUH_EPSIZE_BULK_MAX (64 B), any residue left in the stream FIFO by a parse-stop-on-cable-transition prevents the next bulk IN transfer from la...

#

Pull request overview

Adjusts TinyUSBโ€™s MIDI host defaults and API documentation to prevent a silent RX stall when tuh_midi_stream_read() stops early on USB-MIDI cable-number transitions, leaving residue in the endpoint stream FIFO.

Changes:

  • Increase default MIDI host RX FIFO size to 2 * TUH_EPSIZE_BULK_MAX to provide headroom for leftover bytes.
  • Increase default MIDI host TX FIFO size symmetrically.
  • Document that tuh_midi_stream_read() may return without draining the FIF...
#

CFG_TUH_MIDI_TX_BUFSIZE default is also doubled here, which increases RAM usage per MIDI instance by another endpoint packet (e.g., +64B FS / +512B HS) in addition to the RX change. The PR description currently calls out only โ€œ+64 B per MIDI instanceโ€; consider updating that description (or adding a brief note here) to reflect the total impact, or justify keeping TX doubled vs only changing RX.

fallow birchBOT
#

@copilot resolve the merge conflicts in this pull request, improve submodule path in .gitignore

Done in 5c0c166. Merged upstream master into the branch (only .gitignore had a conflict). The .gitignore submodule paths were improved: instead of the narrow list of two specific paths I happened to clone (hw/mcu/raspberry_pi/Pico-PIO-USB/, hw/mcu/st/cmsis_device_f4/, etc.), it now covers all directories that tools/get_deps.py can fetch โ€” using top-level vendor-dir patterns for `hw/mc...

fallow birchBOT
#

Description

In the USB specification, when wLength equals 0, direction should be ignored and the Status Stage is always IN, rather than being opposite to the direction of the Control Request. Therefore, we modified the logic for determining whether it is the Status Stage and the ACK transmission flow for the Status Stage.

Other

This change can be merged or discarded after thorough discussion and verification; please see #3606 for details.
This change has been tested and passed on E...

fallow birchBOT
fallow birchBOT
#

I observed that with the B-G474E-DPOW1 devkit, many USB-C PD sources I connected were failing to negotiate PD and some were causing the application to crash.

This PR fixes three issues:

Issue 1: CC cable orientation not detected correctly

The original code had a FIXME noting that CC2 vstate was always 1 on the DPOW1 board, and some code to work in spite of that. The original code guarded against this by pairing TYPECEVT2 with a vstate == 3 check, which also happened to mask th...

#

Pull request overview

This PR fixes STM32 UCPD Type-C sink behavior to improve USB-C PD negotiation reliability and prevent crashes/interrupt storms when interacting with newer PD sources.

Changes:

  • Adjust CC attach/orientation detection to consider both CC vstates and treat any non-zero vstate as attached.
  • Prevent sending GoodCRC in response to a received GoodCRC.
  • Add handling for RXHRSTDET (hard reset received) to clear the flag and re-arm RX.

๐Ÿ’ก Add Copilot custom ...

#

On STM32 DMA, CMAR/CNDTR updates generally require the channel to be disabled first. tcd_msg_receive() calls dma_start() unconditionally, so re-arming RX here risks writing to DMA registers while the RX channel is still enabled (and the reload being ignored). Consider stopping RX DMA (or checking dma_enabled() and stopping) before calling tcd_msg_receive() in the hard-reset path.

    // Re-arm RX DMA. On STM32, DMA transfer registers must be reloaded only
    // while th...
#

rx_header is derived from _rx_buf before checking _rx_buf for NULL. If an RXMSGEND interrupt occurs before the stack has armed a receive buffer, this will dereference a NULL pointer. Move the cast and is_good_crc computation inside the _rx_buf check (or early-return when _rx_buf == NULL).

      if (_rx_buf) {
        pd_header_t const* rx_header = (pd_header_t const*) _rx_buf;
        bool is_good_crc = (rx_header->n_data_obj == 0) && (rx_header->msg_type == PD_CTRL_...
fallow birchBOT
#

In the RXHRSTDET handler, this unconditionally restarts RX DMA via tcd_msg_receive() using the cached _rx_buf/_rx_buf_len. If a hard reset is detected before the stack has ever called tcd_msg_receive() (or after a detach when no RX buffer is armed), _rx_buf may be NULL and _rx_buf_len may be 0, which can leave the DMA channel enabled with an invalid address/length and make subsequent tcd_msg_receive() calls reprogram an already-enabled DMA channel. Please guard this path (e.g., only re-arm RX...

fallow birchBOT
#

Thanks for picking this up โ€” but I owe you a clearer status update before you spend time on it.

  • The "LUN 1 never probes" symptom was a CircuitPython bug (replying OK to PREVENT_ALLOW_MEDIUM_REMOVAL โ†’ host stops polling TUR โ†’ SD LUN freezes in NOT_READY). Fix in flight at adafruit/circuitpython#10967.
  • Per my 2026-04-22 update, pure tinyusb msc_dual_lun on the same RP2040 + same macOS Apple Silicon host mounts both LUNs cleanly at the default 512 B buffer. Baseline DCD path is fi...
fallow birchBOT
#

Follow-up โ€” I tested the hypothesis from my last comment.

Built CP with PR #10967 applied (per-LUN ILLEGAL_REQUEST to PREVENT_ALLOW_MEDIUM_REMOVAL), default 1024 B MSC buffer, on Feather RP2040 Adalogger + 8 GB microSD + macOS Apple Silicon (M2).

  • Both LUNs mount cleanly on first enumeration.
  • Stress read of a 13.6 MB file: 34.7 s at 410 KB/s, ~14,000 READ(10) cycles, zero stalls / retries / SCSI sense events. Repeated identically on a second pass.

No tinyusb bug here โ€” the origina...

fallow birchBOT
fallow birchBOT
#

Code review (endianness scan, requested post-merge)

Found 3 endian-related issues:

  1. The byte-swap in dcd_event_setup_received corrupts the audio20_control_request_t alias cast on big-endian hosts. After this PR, wValue/wIndex are stored in host byte order, so on BE the bytes that the audio examples reinterpret as bChannelNumber/bControlSelector (former wValue bytes) and bInterface/bEntityID (former wIndex bytes) are now swapped relative to wire data. UAC2 `tud_...
fallow birchBOT
#

Thanks for asking me to work on this. I will get started on it and keep this PR's description up to date as I form a plan and make progress.

Original prompt

Implement the remaining big-endian fixes identified in PR review comment https://github.com/hathach/tinyusb/pull/3597#issuecomment-4320042007.

Repository: hathach/tinyusb
Target branch: master

Context
PR #3597 introduced host-endian conversion for setup packet fields in dcd_event_setup_received and added bitfield-order guards...

fallow birchBOT
#
[hathach/tinyusb] New branch created: hil_hfp
#

Pull request overview

Updates HIL CI to build/test against multiple HIL configuration files (e.g., TinyUSB + HFP) and adjusts the GitHub Actions workflow to generate and consume a merged HIL build matrix.

Changes:

  • Extend hil_ci_set_matrix.py to accept multiple config JSON files, resolve paths robustly, and de-duplicate generated build args.
  • Update build.yml to generate a merged HIL matrix from test/hil/tinyusb.json and test/hil/hfp.json.
  • Expand the HIL test job to run o...
#

hil-tinyusb runs on self-hosted runners and executes code checked out from pull_request events. Without a fork guard, this job can run untrusted fork PR code on your self-hosted infrastructure. Consider adding an if: condition matching hil-hfp-iar (skip when github.event.pull_request.head.repo.fork == true) or otherwise requiring trusted context/approval before using self-hosted runners.

fallow birchBOT
fallow birchBOT
#

compile but does not run (no blinky), probably due to compile/linker/startup issue

#2674 has a startup issue in board_init() : __disable_irq() from CH32V103 EVT calls csrc mstatus, 0x88 in U-mode (which is only allowed in M-mode)

https://github.com/openwch/ch32v103/blob/f99a84c4c42b6fb676560a9b8b7c737401efe0ad/EVT/EXAM/SRC/Core/core_riscv.h#L144-L155

__disable_irq() in CH32V307 EVT (probably also in CH32V203), however, uses vendor-defined CSR 0x800. This CSR is writable in ...

fallow birchBOT
fallow birchBOT
#

This handler ACKs NCM_SET_ETHERNET_PACKET_FILTER for any request direction/length. Since this request is defined as Host-to-Device with no data stage, it should verify bmRequestType.direction == TUSB_DIR_OUT and wLength == 0 (and fail/STALL otherwise) to avoid accepting malformed requests and to match how other class control handlers validate requests.

        case NCM_SET_ETHERNET_PACKET_FILTER: {
          TU_VERIFY(request->bmRequestType_bit.direction == TUSB_DIR_OUT, f...
#

TUD_CDC_NCM_CAPS is defined unconditionally in a public header, which makes it hard for applications to keep the previous bmNetworkCapabilities value (0) or advertise a different capability bitmap. Consider guarding this with #ifndef TUD_CDC_NCM_CAPS (and documenting it as user-overridable) so existing projects can opt out or extend the capability bits without patching TinyUSB headers.

// May be overridden by applications before including this header.
#ifndef TUD_CDC_NCM_CAP...
#

Pull request overview

Adds CDC-NCM support for the hostโ€™s SetEthernetPacketFilter request and advertises the corresponding capability in the NCM functional descriptor, targeting improved interoperability (notably iOS behavior reported in #3505).

Changes:

  • Advertise bmNetworkCapabilities with Ethernet packet filter support in the CDC-NCM descriptor template.
  • Add NCM network capability bit definitions (NCM_NETWORK_CAPS_*).
  • Handle NCM_SET_ETHERNET_PACKET_FILTER control requ...
fallow birchBOT
#

When stress-testing a custom Vendor interface with lots of fast bulk transfers on CH32V30x (which use the USBFS controller), I noticed that a lot of data was dropped because tud_vendor_rx_cb() would not always fire.

After investigating, it seemed like dcd_ch32_usbfs wasn't updating the EP_RX_CTRL register after a transfer completed or when a new one was queued.

update_out() now properly sets EP_RX_CTRL to ACK or NAK for all endpoints based on transfer state, and `dcd_edpt_xfer...

fallow birchBOT
fallow birchBOT
#

Operating System

MacOS

Commit SHA

096458defffe3ca183169f9e2116c322074f4b1e

Board

ESP32S3-USB-OTG

Firmware

The MSC File Explorer example from the repository:
https://github.com/hathach/tinyusb/tree/master/examples/host/msc_file_explorer

What happened ?

I can read the files, list directories (so read works as expected), but when I want to write, it just hangs on the write10 method forever.

pinging @me-no-dev

How to reproduce ?

Flash the MSC Explorer example...

fallow birchBOT
fallow birchBOT
#
[hathach/tinyusb] New branch created: update-agents-md
#

๐Ÿ’ก Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: da9d36fa4c

โ„น๏ธ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with ๐Ÿ‘.

Codex can also answer questio...

#

<sub><sub>P2 Badge</sub></sub> Replace shell pipes used as โ€œorโ€ in flash examples

These examples use | between alternative commands, but in a shell that is a pipeline operator, not an โ€œorโ€ separator. Copying these lines literally will execute unintended pipelines (and flash|monitor attempts to pipe to a monitor command), so the documented commands fail despite appearing valid. Split alternatives into separate commands/lines ins...

#

<sub><sub>P1 Badge</sub></sub> Omit -b when running remote HIL for all boards

The skill text says board selection is optional and that remote mode can run all boards, but the remote invocation always includes -b $BOARD_NAME. If no board is specified, this expands into an invalid argument sequence (e.g., -b -B examples ...) and prevents the advertised โ€œall boardsโ€ path from working. The command should only add -b when a board ...

#

Pull request overview

Updates the repositoryโ€™s agent-facing documentation to introduce a dedicated Claude โ€œhilโ€ skill for running TinyUSB Hardware-in-the-Loop tests, while significantly condensing/reformatting the general contributor instructions.

Changes:

  • Rewrite and condense AGENTS.md, including new pointers to the HIL skill.
  • Add .claude/skills/hil/SKILL.md describing local/remote HIL workflows.
  • Remove the legacy .claude/commands/hil.md command file.

Reviewed chang...

#

The โ€œAll examples for a boardโ€ build uses examples/build/, but test/hil/hil_test.py (and test/hil/hil_ci.sh) expect per-board outputs under a directory named cmake-build-<board> (e.g., examples/cmake-build-raspberry_pi_pico/โ€ฆ). Consider updating this command to configure with -B cmake-build-<board> (or rename the build dir accordingly) so HIL instructions work without extra steps.

cd examples
cmake -B cmake-build-raspberry_pi_pico -DBOARD=raspberry_pi_pico -G Ninja -...
#

This prerequisite references โ€œAGENTS.md โ€ฆ Option 2โ€, but AGENTS.md no longer labels the Build section as numbered options. Update the wording to match the current heading (e.g., โ€œAll examples for a boardโ€), so the cross-reference remains accurate.

- Examples must already be built for the target board(s). See AGENTS.md "Build" -> "All examples for a board", which produces `examples/cmake-build-BOARD_NAME/`.
#

local.json is referenced as the local-mode config, but there is no local.json checked into the repository. Either add a tracked local config template (and explain how to customize it) or point to an existing config under test/hil/ (e.g., tinyusb.json / hfp.json) so the instructions are runnable as-is.

- **Local** โ†’ `test/hil/tinyusb.json`
- **Remote** โ†’ `test/hil/tinyusb.json`

## Local execution

Boards attached to this machine. Use the tracked HIL config checked into...
#

The remote run snippet always includes -b $BOARD_NAME, but earlier guidance allows running all boards when no board is specified. Add an โ€œall boardsโ€ variant without -b, or only include -b when $BOARD_NAME is set, otherwise this will error or test nothing.

# Run the test remotely
# Specific board:
ssh $REMOTE "cd $REMOTE_DIR && python3 test/hil/hil_test.py -b $BOARD_NAME -B examples tinyusb.json $EXTRA_ARGS"
# Or all boards in the config:
ssh $REMOTE "cd $REMOTE_DIR && p...
#

The Flash commands use | (e.g., ninja โ€ฆ | make โ€ฆ and flash|monitor) and the Unicode ellipsis (โ€ฆ). In a shell, | is a pipe operator and โ€ฆ isnโ€™t a valid placeholder, so copy/paste will run the wrong thing or fail. Split these into explicit alternatives (# or โ€ฆ) and use ASCII placeholders like BOARD=<board> / -DBOARD=<board>, with separate idf.py โ€ฆ flash and idf.py โ€ฆ monitor lines.

ninja cdc_msc-jlink                                     # JLink (CMake)
# or
ma...
#

This refers to โ€œBuild Option 2โ€, but the Build section no longer labels the workflows as options. Rename this to match the current heading (e.g., โ€œAll examples for a boardโ€) or reintroduce explicit option numbering so cross-references stay accurate.

**HIL (2-5 min):** invoke the `hil` skill (`.claude/skills/hil/SKILL.md`) for the full procedure (local vs remote mode, config selection, SSH copy steps, debugging tips). Requires pre-built examples (see Build: All examples for a boa...
#

Local-run examples use python โ€ฆ, while the script has a python3 shebang and the remote-run example uses python3. Prefer python3 consistently to avoid environments where python is Python 2 or not installed.

python3 test/hil/hil_test.py -b BOARD_NAME -B examples local.json $EXTRA_ARGS
# or for all boards in the config:
python3 test/hil/hil_test.py -B examples local.json $EXTRA_ARGS
fallow birchBOT
fallow birchBOT
fallow birchBOT
fallow birchBOT
#

In addition to the fix from #3621 (NCM_SET_ETHERNET_PACKET_FILTER), I also needed to add support for NCM_SET_NTB_INPUT_SIZE to avoid stalls.

Tested primarily on iPhone 17e, running iOS 26.4.1.

Without the changes, no IP address would be obtained in the vast majority of the cases. With the changes, IP address is obtained 101/101 attempts.

iPadOs 26.4 testing scheduled next - also worked 101/101 attempts.

Following to you...

fallow birchBOT
#

${ARGS[*]} is expanded into a double-quoted ssh command string, so any spaces/quotes/metacharacters inside forwarded args can be re-interpreted by the remote shell (and can break argument boundaries). To make this robust and avoid remote shell injection, pass the args as separate ssh parameters (e.g., ssh ... bash -lc '... "$@"' -- "${ARGS[@]}") or otherwise properly shell-escape them before embedding.

ssh -t "$REMOTE" bash -lc 'cd "$1" && shift && python3 -u test/hil/hil_te...
#

The suggested CMake configure command in the "build directory not found" error uses .. as the source dir. For TinyUSB examples, the source is examples/ itself (it has its own CMakeLists.txt), so .. will configure the repo root instead. Update the guidance to use . as the source directory.

    echo "Build first with: cd examples && cmake -DBOARD=$BOARD -G Ninja -B cmake-build-$BOARD . && cmake --build cmake-build-$BOARD"
fallow birchBOT
#

Pull request overview

Copilot reviewed 6 out of 7 changed files in this pull request and generated 6 comments.

Comments suppressed due to low confidence (1)

test/hil/hil_ci.sh:33

  • The script only tracks a single BOARD (last -b seen) for deciding which build directory to rsync, but hil_test.py supports repeating -b/--board. If the caller passes multiple -b flags, only the last boardโ€™s artifacts will be copied, and the remote test run will likely fail for the other boards...
#

The timing note claims --ci is a โ€œparallel buildโ€, but tools/metrics_compare_base.py builds boards sequentially (it may parallelize within a single Ninja build, but not across boards). Please adjust this wording to avoid setting incorrect expectations about runtime.

- `--ci` (all arm-gcc families, first board each): 4-8 minutes (full sequential sweep across selected boards)
#

The base-branch worktree will not contain untracked dependency checkouts produced by tools/get_deps.py (e.g., hw/mcu/st, lib/CMSIS_5). As written, building many boards (especially --ci) will fail in the worktree even if deps exist in the main checkout. Consider symlinking/copying the dependency directories into the worktree (similar to linkermap), or invoking tools/get_deps.py -b <board> inside the worktree before configuring.

#

For --combined, this builds a single metrics.py combine command by expanding and inlining every **/*.map.json path across all boards. With --ci this can easily become thousands of arguments and hit OS command-line length limits. Consider aggregating per-board outputs instead (e.g., run metrics.py combine per-board and then combine the resulting .json files), or pass file lists via a temp file/response file mechanism.

#

build_board() has an example parameter and supports building a specific CMake target, but main() always calls it without example, so -e/--example still builds all examples for each board. This undermines the โ€œsingle exampleโ€ workflow (and --bloaty use case) and can add significant build time. Consider passing the requested example targets into build_board() (or explicitly documenting that the script always builds all examples).

            # Step 2: Build base (all...
fallow birchBOT
#

run() is used with timeout=... (e.g., during cmake --build). subprocess.run(..., timeout=...) raises TimeoutExpired rather than returning a non-zero CompletedProcess, and this function doesn't catch it. Consider catching subprocess.TimeoutExpired in run() (or in callers like build_board) and converting it into a handled failure path so the script prints a clear error and continues/cleans up without a Python traceback.

    try:
        return subprocess.run(cmd,...
#

Related to the filter mismatch above: the reporting guidance says to highlight rows with non-zero diffs in tinyusb/src paths, but with the scriptโ€™s default absolute-src filtering the reported compile-unit paths may not include that substring. Adjust the guidance to reflect what the reports will actually contain under the default settings.

- Highlight any rows with non-zero diff for the default TinyUSB stack source filter; in the report these will be compile-unit/source-path ro...
#

This skill doc says the default filter is tinyusb/src and instructs readers to look for diffs in tinyusb/src paths, but tools/metrics_compare_base.py defaults to per-checkout absolute <checkout>/src/ filters (unless -f/--filter is passed). Please update the skill text to match the scriptโ€™s actual default behavior (and mention -f if a repo-relative filter like tinyusb/src is desired).

fallow birchBOT
#

The remote heredoc that runs hil_test.py doesnโ€™t enable set -e (or -euo pipefail). If cd -- "$1" fails (wrong REMOTE_DIR, permission issue), the script will continue and run from the wrong directory, producing harder-to-diagnose failures. Add set -e (and optionally -u -o pipefail) at the top of the remote snippet to fail fast with a clear error.

ssh "$REMOTE" bash -s -- "$REMOTE_DIR" "${ARGS[@]}" "test/hil/$CONFIG_BASENAME" <<'REMOTE'
set -euo pipefail
#

git worktree add <path> <branch> fails if the base branch is already checked out in another worktree (including when the current checkout is on master). To make the script more robust, consider adding the worktree in detached mode (e.g., git worktree add --detach ... <ref>) or creating a temporary branch name, so comparisons work regardless of what branches are currently checked out.

    ret = run(['git', '-C', TINYUSB_ROOT, 'worktree', 'add', '--detach', worktree_dir, args....
fallow birchBOT
#

Just a heads up that the next release will be a significant regression for anyone using the rp2040 in host mode. This PR has already been deployed to my users who all use hubs and have multiple devices connected simultaneously. Typically, keyboard, mouse, gamepad, MSC CBI/BOT, and CDC, all at once. We're also regularly hot plugging devices, which is where most of the crashes happen.

fallow birchBOT
fallow birchBOT
#

Just a heads up that the next release will be a significant regression for anyone using the rp2040 in host mode. This PR has already been deployed to my users who all use hubs and have multiple devices connected simultaneously. Typically, keyboard, mouse, gamepad, MSC CBI/BOT, and CDC, all at once. We're also regularly hot plugging devices, which is where most of the crashes happen.

Thanks, I saw issues with pico2 with hub + ch34x + a msc device on hil test as well. I am not sure if it i...

fallow birchBOT
fallow birchBOT
#

Operating System

Linux

Commit SHA

939c2f91c200db2bf9874c2e6c50b3530f8a6725

Board

STM32H563NUCLEO

Firmware

Completely stock and freshly installed tinyusb/examples/device/dfu/main.c with no changes.

What happened ?

I can run dfu-util -d cafe -a 0 -U fetch.txt and get the Hello world from TinyUSB DFU! - Partition 0

But the issue is when I run dfu-util -d cafe -a 0 -D skip.txt I get the following LIBUSB_ERROR_TIMEOUT

~/tinyusb/examples/device/dfu$ dfu-...
fallow birchBOT
#
[hathach/tinyusb] New branch created: merge-usbd-control
#

Pull request overview

Refactors TinyUSB device control transfer handling by moving EP0 control transfer state and logic into src/device/usbd.c, deprecating the legacy usbd_control.c translation unit, and updating build/test wiring accordingly.

Changes:

  • Moved EP0 control-transfer state into _usbd_dev and inlined former usbd_control.c logic into usbd.c.
  • Dropped usbd_control.c from in-tree build source lists; left a deprecated stub file for downstream builds.
  • Updated u...
#

tud_control_xfer() ignores its request argument and instead uses _usbd_dev.ctrl_xfer.request. This breaks call sites that intentionally pass a modified request (e.g. process_get_descriptor() creates mod_request with a shorter wLength to avoid sending a ZLP on the very first GET_DEVICE_DESCRIPTOR when EP0 size < 18). Consider copying *request into _usbd_dev.ctrl_xfer.request (or at least using request->wLength for data_len/status-stage direction) so these existing semantics...

#

usbd_driver_print_control_complete_name() was removed from this file, but itโ€™s still declared in src/device/usbd_pvt.h behind #if CFG_TUSB_DEBUG >= CFG_TUD_LOG_LEVEL. If any in-tree or out-of-tree code links against that symbol when debug logging is enabled, this will become an undefined reference. Either keep a (possibly static-less) implementation in usbd.c under the same #if, or remove/adjust the declaration in the header.


void usbd_driver_print_control_complete_...
#

This file is now a stub with an unconditional #warning. #warning is non-standard and, combined with common -Werror settings (or compilers that donโ€™t support it), can break downstream/vendor builds that still compile this translation unit. Consider guarding the warning by compiler support and/or a config macro (or replacing it with a portable deprecation mechanism) so including the legacy path doesnโ€™t hard-fail builds.

// keep resolving. Drop usbd_control.c from your build ...
#

Code review

Found 1 issue:

  1. TUD_CDC_NCM_CAPS is defined unconditionally with no #ifndef guard, so applications cannot override the advertised NCM bmNetworkCapabilities (e.g., to add other capability bits, or to advertise none if their device doesn't actually handle the filter request). Other configurable macros in this stack consistently use the #ifndef pattern (e.g., CFG_TUD_NCM_OUT_NTB_MAX_SIZE in [src/class/net/ncm.h](https://github.com/hathach/tinyusb/blob/405dadecc73f...
fallow birchBOT
#
[hathach/tinyusb] New branch created: fix_uart_write
#

Pull request overview

Updates BSP UART write stubs to return an error (-1) when UART logging isnโ€™t available, preventing the default sys_write() retarget from spinning indefinitely when board_uart_write() previously returned 0 in โ€œno UARTโ€ builds.

Changes:

  • Change board_uart_write() stub/default paths from return 0; to return -1; across multiple BSP families.
  • Update PIC32MZ weak board_uart_write() to return -1 instead of falsely reporting success.
  • Adjust FT9xx `boa...
#

With this change, the stub path now returns -1. The generic implementation of board_putchar() (in hw/bsp/board.c) treats any non-zero return from board_uart_write() as success, so a -1 error will be misinterpreted as โ€œbyte writtenโ€ and board_putchar() will return the character instead of -1. Please update board_putchar() to check for a positive write count (e.g., > 0) so the new โ€œnegative means UART unavailableโ€ convention is handled correctly (and consider documenting the negative return con...

#

In builds where BOARD_UART is not defined, count is still declared at the start of this function but is no longer referenced because the return count; moved inside the #ifdef BOARD_UART block. This can trigger an unused-variable warning. Consider moving the count declaration inside the #ifdef BOARD_UART block (or otherwise ensuring itโ€™s used) so the stub path compiles cleanly with -Wall/-Wextra.

fallow birchBOT
fallow birchBOT
fallow birchBOT
#

Operating System

Others

Commit SHA

none

Board

NXP imx RT1176

Firmware

FreeRTOS based firmware on custom board using NXP imx RT1176. Using TinyUSB 0.20.0.

What happened ?

ESD test causes attached USB hub reset which causes breakdown of USB touch. This happens due to reconnect issues with USB Hub.

I've already preapared a fix using copilot and sucessfully tested it on my hardware. The patch file for the fix is attached. The patch changes files src/portable/ehci/eh...

fallow birchBOT
fallow birchBOT
#

Pull request overview

Adds CDC-NCM support for the class-specific SetEthernetPacketFilter request and advertises that capability in the NCM functional descriptor, improving host compatibility (reopened #3621 / research from #3505).

Changes:

  • Add NCM_SET_ETHERNET_PACKET_FILTER handling in the NCM control transfer callback (acknowledges the request).
  • Introduce bmNetworkCapabilities bit definitions for NCM and set the descriptor capability flag accordingly.
  • Update the CDC-NCM...
#

TUD_CDC_NCM_CAPS is introduced as a public macro but is unconditionally defined, which makes it hard for applications to override the advertised bmNetworkCapabilities (and can trigger macro redefinition warnings if a project defines it before including this header). Consider wrapping it in #ifndef TUD_CDC_NCM_CAPS (or making capabilities a parameter of TUD_CDC_NCM_DESCRIPTOR) so apps can opt-in/out or extend the bitmask cleanly.

// NCM Capabilities, bitmap of NCM_NETWORK_C...
fallow birchBOT
fallow birchBOT
fallow birchBOT
#

This example advertises NCM_NETWORK_CAPS_MAX_DATAGRAM_SIZE, but the NCM device class implementation in this PR only adds handlers for SetEthernetPacketFilter and Get/SetNtbInputSize (no Get/SetMaxDatagramSize handling). Either drop the MAX_DATAGRAM_SIZE capability bit here or add the corresponding request handlers so hosts donโ€™t probe an unsupported feature and get stalled.

      CFG_TUD_NET_MTU, (uint8_t)NCM_NETWORK_CAPS_ETH_FILTER),
#

Changing TUD_CDC_NCM_DESCRIPTOR to require an extra _capability argument is a breaking change for existing downstream descriptor code. Consider preserving backward compatibility by keeping the old 9-arg macro (defaulting capabilities to 0) and introducing a new macro name/variant for the extended form, or making the last argument optional via a variadic wrapper.

// Interface number, description string index, MAC address string index, EP notification address and size, EP data...
fallow birchBOT
fallow birchBOT
fallow birchBOT
fallow birchBOT
fallow birchBOT
#

Pull request overview

This PR reworks the MUSB device controllerโ€™s Endpoint 0 (control) handling to better tolerate merged/level-triggered EP0 interrupt conditions under heavy CPU load, by replacing the prior EP0 state handling with an explicit stage-based EP0 state machine.

Changes:

  • Replaces the prior EP0 state tracking with a new ep0_state_t (SETUP/DATA/STATUS stages) and updates dcd_data_t accordingly.
  • Reimplements edpt0_xfer() and process_ep0() around the new EP0 stag...
#

In SETEND handling, TU_LOG3(false, ...) passes a boolean where TU_LOG3 expects a format string (TU_LOG3 maps to TU_LOG1). Also the format uses %s but _dcd.ep0_state is an enum, and csrl = _dcd.ep0_state; overwrites the CSR bitfield variable with the state value, breaking subsequent flag checks. Fix the log call/format and refresh csrl from ep_csr->csr0l (or avoid reusing csrl) instead of assigning the enum to it.

#

process_ep0() in USB_EP0_STAGE_TX only fires dcd_event_xfer_complete() when _dcd.remaining_ctrl is nonzero, which means the final IN data packet (the one that transitions ep0_state to STATUSOUT in edpt0_xfer) never generates an IN xfer_complete event. TinyUSBโ€™s control state machine relies on the last DATA-stage xfer_complete to queue the status-stage transaction. Ensure an IN xfer_complete is emitted for every posted IN transfer, including the final packet, before/when transitioning to STA...

#

ep0_setup() sets _dcd.is_set_addr based only on bRequest == 5. Since SET_ADDRESS is only guaranteed for standard device requests, a vendor/class request using bRequest==5 could incorrectly trigger an address write in STATUSIN using a stale _dcd.addr. Since TinyUSB calls dcd_set_address() only for the standard SET_ADDRESS request (see src/device/usbd.c), consider setting is_set_addr inside dcd_set_address() instead of inferring it from the setup packet.

fallow birchBOT
#
[hathach/tinyusb] New branch created: msc_os
#
fallow birchBOT
fallow birchBOT
fallow birchBOT
#

Pull request overview

This PR fixes a DWC2 host-side TX FIFO space check that can stall MSC WRITE10 transfers, and adds a new FreeRTOS-based msc_file_explorer host example intended to exercise MSC storage on RTOS targets such as Espressif boards.

Changes:

  • Re-read DWC2 TX FIFO/queue status inside the per-packet write loop so host TX scheduling uses current FIFO state.
  • Add a new examples/host/msc_file_explorer_freertos example with FatFs-backed CLI file browsing and benchmarkin...
#

This callback runs on the USB host task, but it calls FatFs directly even though the example config leaves FF_FS_REENTRANT disabled. That means f_unmount() can race with f_read()/f_write()/f_readdir() running in msc_app_task, which is especially risky during disconnects while writes are in flight. Please defer unmounting to the same task that owns the other FatFs calls, like you already do for mounting.

fallow birchBOT
fallow birchBOT
fallow birchBOT
#

Pull request overview

This PR targets reliability of bulk OUT transfers on WCH CH32 USBFS device controller by ensuring OUT endpoints are properly re-armed via EP_RX_CTRL, preventing missed receive callbacks and dropped packets during sustained high-rate transfers.

Changes:

  • Update update_out() to program EP_RX_CTRL (ACK/NAK) for non-EP0 OUT endpoints based on whether an OUT transfer is still active.
  • Update dcd_edpt_xfer() to explicitly re-enable OUT endpoint RX ACK when a...
#

update_out() now updates EP_RX_CTRL for non-EP0 endpoints using only ACK/NAK based on xfer->valid. This ignores the isochronous configuration (data.isochronous[ep]), which elsewhere uses USBFS_EP_R_RES_NYET for iso OUT (see dcd_edpt_open()). Consider selecting the RX response based on data.isochronous[ep] (e.g., NYET while active) to avoid changing behavior for iso endpoints.

Also, EP_RX_CTRL is only updated when xfer->valid was true on entry; if an OUT token arrives while ...

#

dcd_edpt_xfer() unconditionally forces OUT endpoints to USBFS_EP_R_RES_ACK when (re)queuing a transfer. This can override the isochronous RX setting established in dcd_edpt_open() (USBFS_EP_R_RES_NYET for iso OUT), changing endpoint behavior. Consider using data.isochronous[ep] here as well so iso OUT endpoints are re-armed with the correct RX response.

fallow birchBOT
fallow birchBOT
fallow birchBOT
#

NCM_SET_ETHERNET_PACKET_FILTER is rejected unless bmCapabilities advertises NCM_NETWORK_CAPS_ETH_FILTER. Linux hosts have been observed to issue this request even when the capability bit is clear (see tinyusb issue #2010), so stalling here can still break enumeration/bring-up for users that leave capabilities at 0. Consider accepting the request unconditionally (and optionally no-op/callback) to maximize interoperability.

#

This TU_ATTR_WEAK stub is duplicated in both ncm_device.c and ecm_rndis_device.c. On toolchains where TU_ATTR_WEAK expands to nothing (e.g. CCRX in tusb_compiler.h), this becomes a strong definition and will cause a multiple-definition link error when both network classes are enabled. Move the stub to a single common compilation unit, or conditionally compile it so only one TU provides the fallback implementation.

#

NCM_SET_NTB_INPUT_SIZE: returning false during CONTROL_STAGE_ACK cannot stall the control transfer (status stage has already completed; usbd.c ignores the return value at ACK). This makes the invalid-size path ineffective and the host will still see the request as successful. Validate and decide to stall during CONTROL_STAGE_DATA (when the OUT payload is available and the return value is honored), or avoid returning false here and instead clamp/ignore invalid values deterministica...

fallow birchBOT
#
[hathach/tinyusb] New branch created: fix/nrf5x-hfclk-wait-post-sd
#

Summary

Fix a deadlock in tusb_hal_nrf_power_event(USB_EVT_READY) when fired after the SoftDevice has been enabled.

USB_EVT_DETECTED runs hfclk_enable() which, when SD is not yet enabled, starts HFXO via direct CLOCK register access. After sd_softdevice_enable() takes over the CLOCK peripheral, HFXO is physically off again and SD's HFCLK reference count is 0.

If USB_EVT_READY is then fired post-SD (e.g. on nRF52 via Bluefruit's usb_softdevice_post_enable() when the pre-SD `n...

#

Size Difference Report

Because TinyUSB code size varies by port and configuration, the metrics below represent the averaged totals across all example builds.

Note: If there is no change, only one value is shown.

Changes >1% in size

No entries.

Changes <1% in size

file .text .bss size % diff
dcd_nrf5x.c 2916 โž™ 2940 (+24) 292 3208 โž™ 3232 (+24) +0.7%
TO...
fallow birchBOT
#

On STM32 DWC2, SETUP phase done and EP0 OUT transfer complete can be reported together. Processing SETUP first can overwrite control state before the previous zero-length OUT status stage is acknowledged, which causes DFU DNLOAD/GETSTATUS traffic to lose the status ACK and stall.

Queue the EP0 OUT zero-length transfer completion before queuing the SETUP event when the endpoint has no pending OUT data and total_len is zero. This keeps TinyUSB control-transfer ordering intact for the combine...

#

Pull request overview

This PR adjusts the DWC2 (STM32) device controller driver to preserve TinyUSB control-transfer event ordering when DWC2 reports EP0 OUT transfer completion and SETUP phase done in the same interrupt, avoiding loss of the EP0 OUT status-stage ACK (notably impacting DFU DNLOAD/GETSTATUS sequences).

Changes:

  • Detect the combined setup_phase_done + xfer_complete interrupt case on EP0 OUT with zero total length.
  • Enqueue an EP0 OUT zero-length xfer_complete eve...
#

Same issue as the slave-path: ep0_status_complete_before_setup can fire based solely on setup_phase_done && xfer_complete && total_len==0, but xfer_complete is known to be asserted during SETUP reception on some STM32 DWC2 variants. This would enqueue an EP0 OUT xfer-complete event (len=0) before the SETUP event even when no status ZLP completion actually occurred, potentially corrupting TinyUSBโ€™s control-transfer state.

Recommend reusing the existing filter (`!doepint_bm.status_phase_...

#

The new ep0_status_complete_before_setup predicate doesnโ€™t filter out the known STM32 DWC2 quirk where xfer_complete can be asserted during SETUP reception (see the existing comment below about xfer_complete + status_phase_rx being set when GRXSTS_PKTSTS_SETUP_RX is popped). In that case, this code could enqueue a spurious EP0 OUT xfer-complete (len=0) before the SETUP event, which can break the control state machine (e.g., usbd_control_xfer_cb() asserts _ctrl_xfer.buffer for an u...

fallow birchBOT
#
[hathach/tinyusb] New branch created: stm32c5
fallow birchBOT
#

Pull request overview

Adds TinyUSB support scaffolding for the new STM32C5 family (HAL2-based drivers) by wiring the MCU option into the STM32 FSDEV backend, adding a BSP/board definition, and updating dependency fetching + CI/docs accordingly.

Changes:

  • Introduce OPT_MCU_STM32C5 and enable STM32 FSDEV (DRD, 2KB PMA) configuration paths for STM32C5.
  • Add STM32C5 BSP support (make/cmake build files, family implementation, Nucleo-C542 board files, HAL/FreeRTOS config headers).
  • Up...
fallow birchBOT
fallow birchBOT
#

Summary

Adds examples/host/usbipd, a USB/IP-over-Ethernet host bridge: a TinyUSB host that forwards URBs from an attached USB device over TCP/IP to a Linux usbip client. Once attached, the device shows up in the kernel's USB bus the same way a locally plugged one would (cdc-acm becomes /dev/ttyACM, HID becomes an evdev node, etc).

The bridge core (usbip_server.c) is portable C against the public tuh_* and lwIP tcp_* APIs, so it should work on any TinyUSB host port with a TCP-...

fallow birchBOT
#

Hi, it looks very nice !

Just for the example I think it's better to include a host/device dual port approach with NCM device + USBIP host, in this way it can be tested on more MCUs. F439 is a very old MCU which I don't have, I don't know if Ha Thach has it but it's not in the HIL test farm anyway.

PS: I'm thinking about adding a Awesome projects section to readme for external projects which are not trivial to maintain.

fallow birchBOT
fallow birchBOT
fallow birchBOT
#

Operating System

Windows 11

Commit SHA

N/A (reproduced through espressif/arduino-esp32 v3.3.8, release tag 3.3.8 / commit b4f85ba)

Board

ESP32-S3

Firmware

  • espressif/arduino-esp32 v3.3.8
  • release tag: 3.3.8
  • Arduino-ESP32 release commit: b4f85ba
  • USB audio implemented through Arduino-ESP32's integrated TinyUSB stack (USBAudioCard)
  • not using Adafruit_TinyUSB_Arduino
  • Arduino release๏ผš
    https://github.com/espressif/arduino-esp32/releases/tag/3.3.8
  • Arduino PR๏ผš...
fallow birchBOT
#

Hi @hathach ,

I know you have a lot on your plate right now, so please don't take this as a bump. Just want to share what this PR is already enabling here.

Rebased the PR on top of current master (4e64f3e91c) to pick up the recent refactors (#3627 usbd_control โ†’ usbd.c, tu_edpt_state_t โ†’ uint8_t, #3598 RP2040 family.cmake). All 12 commits applied cleanly, zero conflicts. Builds green across 8 RP2040 boards (including RP2350), and 25/25 unit tests passing.

Flashed `examples/...

fallow birchBOT
fallow birchBOT
fallow birchBOT
#
[hathach/tinyusb] New branch created: dwc2_iso_in
fallow birchBOT
fallow birchBOT
fallow birchBOT
#

Currently MTP example works fine under Windows, but Linux file explorers had problems with opening files directly from MTP drive. Copying entire file to local drive was working though.

This is most likely due to fact that Windows uses GetObject to read entire file in one transfer and Linux tries to use GetPartialObject which is not implemented in this example.

This PR fixes this problem by implementing GetPartialObject handler. Implementation is very similar to existing GetObject, but t...

fallow birchBOT
fallow birchBOT
fallow birchBOT
#

USB2 for CH32H41X, have not tested for all the possible firmwares yet. cdc_msc and uac2 seems to work. There is USB3 on the chip but this PR doesn't include it, I couldn't get it working.

Modified the dcd_ch32_usbhs driver by adding chip specific includes, inspired by the dwc2_* files. Maybe #3515 might be able to follow the same pattern.

fallow birchBOT
#
[hathach/tinyusb] New branch created: musb_ep0_race
#

Handle cases where a new SETUP arrives before the previous control transfer fully completes by buffering the SETUP and replaying it after status completion. Split EP0 DATA state into DATA_IN/DATA_OUT and finalize pending status-out completion before processing deferred SETUP.

Take care these 2 cases if new SETUP packet arrived while old control transfer is not finished yet. This could happen in following scenarios when CPU load is high:

  • Status IN/OUT finished, IRQ and new setup packet I...
#

Pull request overview

This PR updates the Mentor MUSB device controller (DCD) EP0 control-transfer state machine to better handle a race where a new SETUP arrives before the prior control transfer has fully completed (typically under high CPU load). It also adjusts MUSB port headers to avoid multiple-definition linkage issues around MUSB_BASES.

Changes:

  • Split EP0 DATA state into explicit DATA_IN / DATA_OUT states and add buffering of a โ€œdeferredโ€ SETUP request to replay after...
#

In PIPE0_STATE_DATA_IN status handling, the new shortcut that immediately fires a STATUS-OUT (TU_EP0_OUT) xfer_complete and then starts processing the deferred SETUP can break the TinyUSB control-flow ordering: the stack schedules the Status stage only after it processes the DATA-IN xfer_complete, so completing STATUS-OUT (and advancing to the next SETUP) here can cause the stack to later queue a stale status-stage transfer against the new EP0 state, leading to stuck control transfers or ...

#

process_ep0() is reading csr0l and then checking csrl & MUSB_CSRL0_DATAEND to early-return. In MUSB, bit 0x08 is overloaded: it is SETUP when read and DATAEND when written (see musb_type.h where MUSB_CSRL0_SETUP and MUSB_CSRL0_DATAEND share the same value). This means the new early-return will trigger on SETUP packets and can prevent EP0 from ever draining/handling a received SETUP. Consider removing this check or explicitly checking the intended read-side condition (e.g. `MUS...

fallow birchBOT
fallow birchBOT
fallow birchBOT
fallow birchBOT
#

Summary

In hcd_edpt_xfer() (src/portable/raspberrypi/rp2040/hcd_rp2040.c), ep->next_pid is reset to 1 only when the control-endpoint direction changes between stages. That works for IN-data control transfers (GET_REPORT, GET_DESCRIPTOR, โ€ฆ) where SETUP is OUT and DATA is IN โ€” the direction flips and the data stage correctly goes out as DATA1. It does not work for class requests with an OUT data stage like SET_REPORT, where both SETUP and DATA are OUT (ep_addr == 0x00 for bo...

fallow birchBOT
#

Thanks for your effort, since Ha Thach is busy I'm trying to boost it.

  • Device driver itself generally looks good, initially I think about adding MIDI 2.0 support into existing MIDI 1.0 driver, but looks like the packet format changed a lot.
    One thing is how tud_midi2_n_ump_read/write()/tud_midi2_n_packet_read/write() should be used, adding error handling on wrong protocol ?

  • For the device example I saw nothing special to RP2040 (personally not a fan of RPI), please remove the r...

fallow birchBOT
#

Thanks for your effort, since Ha Thach is busy I'm trying to boost it.

* Device driver itself generally looks good, initially I think about adding MIDI 2.0 support into existing MIDI 1.0 driver, but looks like the packet format changed a lot.
  One thing is how `tud_midi2_n_ump_read/write()`/`tud_midi2_n_packet_read/write()` should be used, adding error handling on wrong protocol ?

* For the device example I saw nothing special to RP2040 (personally not a fan of...
opal bay
#

anyone know if i can use USB ethernet adapters (CDC NCM) with tinyusb? and whether its possible in {circuit, micro}python?

fallow birchBOT
#

@HiFiPhile thanks for the review. Each point addressed in separate commits on the branch.

For the wrong protocol error handling, tud_midi2_n_ump_read/write now return 0 when the interface is not on Alt 1, matching the pattern from audio_device.c. MIDI_PROTOCOL_MIDI1/MIDI2 are exposed in the public header so applications can branch on the negotiated protocol. packet_read/write stay protocol-agnostic since a raw 4-byte word is valid in either alt.

The device example dropped the rp2040...

fallow birchBOT
fallow birchBOT
#

@HiFiPhile pushed three commits addressing the latest feedback. 5ac6346d fixes packet segmentation in midi2d_xfer_cb by peeking 4 bytes and reading MT from byte 3 to match LE memory order. 4b729bf adds per-interface weak callbacks for NUM_GROUPS, NUM_FUNCTION_BLOCKS, EP_NAME and PRODUCT_ID. 287096f7 scales the device buffers with EPSIZE to match the midi2_host pattern. Tested on RP2040 with echo loopback and dual-instance enumeration on Linux 6.17 native UMP.

fallow birchBOT
fallow birchBOT
#

Packet segmentation can happen if the host reading is slow or sending too much.

Imaging sending 11 UMP of 96 bits each (1134=132 bytes)

  1. In tud_midi2_n_ump_write() 60 bytes are written into ring buffer, then pushed into EP buffer, remaining 72 bytes stays in ring buffer.
  2. Host made the transfer.
  3. In midi2d_xfer_cb() tu_edpt_stream_write_xfer() will send maximum bytes possible, resulting 11th packet segmented.

Actually I think using streaming API is hard to resolve issue, mayb...

fallow birchBOT
#

@HiFiPhile thanks for the #3614 pointer. Applied the same pattern: CFG_TUD_MIDI2_*_BUFSIZE defaults are back to EPSIZE (no multiplier) on both device and host, and the drain-in-loop requirement is documented on tud_midi2_n_ump_read and tuh_midi2_ump_read. The midi2_device example now drains until 0 inside tud_midi2_rx_cb. Reproduced the wedge with a no-drain firmware (Pico RP2040, Linux 6.17 native UMP): 100 NoteOns sent, only 12% received, ALSA write blocked. With the drain loop,...

#

@HiFiPhile looked into this scenario and from what I can see it does not materialize with BUFSIZE = EPSIZE applied in the previous commit. The reason is that the tud_midi2_n_ump_write loop breaks when available < pkt_bytes. With BUFSIZE = mps, that means the FIFO never accepts a packet that would cross mps, and the boundary-aware pre-flush never adds a partial packet. When xfer_cb calls write_xfer, the FIFO holds only intact UMPs whose total is always โ‰ค mps.

Validated this at...

fallow birchBOT
#

It happens if CFG_TUD_MIDI2_TX_BUFSIZE is larger, like CFG_TUD_MIDI2_TX_BUFSIZE=128 to be able to send more data in one tud_midi2_n_ump_write call.

Always with 11 UMPs of 96 bits each (1134=132 bytes)

  1. tud_midi2_n_ump_write called with 132 bytes, data write into Tx FIFO by tu_edpt_stream_write in L386.
  2. At 6th while (written < count) { loop, ff_count equals to 60, tu_edpt_stream_write_xfer(ep_tx); at L383 is called 60 bytes pulled from Tx FIFO and written into EP bu...
fallow birchBOT
#

@HiFiPhile applied the fix in commit aaca323bd. The midi2d_xfer_cb now invokes a helper midi2d_flush_tx_boundary_aware with 3 paths:

  • ff_count == 0: ZLP if needed.
  • ff_count <= mps: stream API drain (fast path).
  • ff_count > mps: manual UMP-aligned drain via tu_fifo_peek_n + tu_fifo_read_n + direct usbd_edpt_xfer.

Reproduced the scenario you described on hardware (Pico RP2040, CFG_TUD_MIDI2_TX_BUFSIZE=128, burst of 11 UMPs of 12B in a single ump_write call). Instrume...

fallow birchBOT
#
[hathach/tinyusb] New branch created: feat/midi2-device-host-driver
#
[hathach/tinyusb] New branch created: midi2-device-host-driver
fallow birchBOT
#

CFG_TUD_MIDI2_TX_BUFSIZE < mps normally won't happen, in opposite CFG_TUD_MIDI2_TX_BUFSIZE > mps is more common. We can't relies on it.

I think converting to raw FIFO is actually easier since we need to frequently poking into the FIFO. As the change is huge I posted it here to let you take a look first: https://github.com/hathach/tinyusb/compare/midi2-device-host-driver

Changes also made to tud_midi2_n_packet_write/read:

  • Add count to inline with UMP API
  • Limit to Alt0 to avoid UMP...
fallow birchBOT
#

@HiFiPhile nice work! Ran runtime tests on your midi2-device-host-driver branch on a Pico RP2040 with Linux 6.17 native UMP. Each burst validates raw bytes from /dev/snd/umpC*D0 against a payload with markers (DEAD/BEEF/CAFE/seq) to detect segmentation:

mode scenario result
A BUFSIZE=EPSIZE, 5000 UMPs mix MT 0x0 + MT 0x4 + MT 0x5 10/10 PASS
B BUFSIZE=128, 11 UMPs MT 0xB (your canonical scenario) 10/10 PASS
D BUFSIZE=128, 100 UMPs MT 0xB in ...
fallow birchBOT
fallow birchBOT
#

Operating System

Linux

Commit SHA

81641e35c67ea8197397d1d03c666e94db6fdaec

Board

Custom

Firmware

I can observe the following issue with EP0 on a custom SoC, with DWC2 configured with DMA mode enabled. This seems like a generic issue in the DWC2 port.

It's a simple CDC device, issue shows up very early when host fetches descriptors on EP0.



DMA = 1
E0WP 8
USBD Bus Reset : Full Speed
E0DD
E0WP 8
USBD Setup Received 80 06 00 01 00 00 12 00
  Get Descriptor Device
 ...
fallow birchBOT
fallow birchBOT
fallow birchBOT
fallow birchBOT
#

@HiFiPhile applied the same refactor to midi2_host.c in commit dad8c0ae5, mirroring yours from 4baf1883c. tu_edpt_stream_t tx became a custom midih2_tx_t, with the same helpers (_tuh_tx_byte_at, _tuh_tx_nonseg_len_to_mps, _tuh_tx_start_xfer, _tuh_tx_ump_write). tuh_midi2_ump_write and tuh_midi2_write_flush now delegate to the helpers, and the TX branch of midih2_xfer_cb does the ZLP in the same pattern as the device.

For runtime validation I set up an Adafruit Feather...

fallow birchBOT
fallow birchBOT
#

Well, I now realised my dfu-util LIBUSB_ERROR_PIPE error is not reproducable reliable.

I tried with different USB hubs and cables, but currently even the old commit 4c7fd70e5, which has previously not worked for my DFU application, works just fine. I guess since this issue is timing related it could make sense that it's not always reproducable.

Since I don't have a USB sniffer to actually look into the protocol details, I can only test functionality. I'll see if I can find out what ...

fallow birchBOT
fallow birchBOT
fallow birchBOT
#

Due to the PR being created from an organization, it's not possible to give PR write access, but I've invited you with write rights to the fork. You may change it there, or if you better want to create a new clean PR with your suggested implementation, thats also fine for me.

I have now created a minimal example for STM32U5G9J-DK2 board and tested different commits from before my fix, with my fix or with your fix, but the results are not conclusive: Only broadly delaying the interrupt hand...

fallow birchBOT
#

I've tried your repo (had to modify linker as I've Nucleo-U5A5ZJ), with 500 delay count I can reproduce the failure but can't explain the underlying issue ๐Ÿ™Œ Maybe I've overlooked something... (or my sniffer is lying to me ?)

To me it looks like no issue !

fallow birchBOT
#

Update: There was a sniffer PING filter issue ๐Ÿคฆ

The failure was due to inep0_status_complete_before_setup's condition doepint_bm.xfer_complete could be false.
A xfer_complete IRQ fired and reset the flag, but since doepint_bm.setup_packet_rx is also true as SETUP packet is already arrived, no xfer completion event is queued:
https://github.com/hathach/tinyusb/blob/4c87db341e4af7d53ce9cbbdf693593a520dc538/src/portable/synopsys/dwc2/dcd_dwc2.c#L964

fallow birchBOT
#

In the EP0 OUT completion path, gating dcd_event_xfer_complete() on xfer->total_len > 0 can drop a legitimate completion when the host ends an OUT data stage with a ZLP (short packet), making xfer->total_len compute to 0 even though this was not a status stage. This would leave the control transfer stuck waiting for the DATA-stage completion event.

Consider skipping the event only for the specific "armed EP0 status-OUT" case (e.g., track status-OUT separately from total_len/add a dis...

fallow birchBOT
#
[hathach/tinyusb] New branch created: dwc2_dma_setup
#

Please try https://github.com/hathach/tinyusb/commit/608b77de5ba61ca6a1a94767945ec547646632ad based on #3634

There was an race condition where dma_setup_prepare is called unconditionally, then DMA settings are modified again in edpt_schedule_packets.

Now it's only called if previous transfer is finished:

<img width="1978" height="898" alt="Image" src="https://github.com/user-attachments/assets/0a79a609-d602-4ff7-bc75-bc6307d51c98" />

fallow birchBOT
#

Pull request overview

This PR targets the CH32V103 BSP startup/hardfault issue by avoiding the vendor __disable_irq()/__enable_irq() implementation that traps when executed in U-mode, and it adds a new CH32V103C8T6 โ€œBluepillโ€ board definition with appropriate flash/RAM linker sizing.

Changes:

  • Avoids calling __disable_irq() / __enable_irq() in hw/bsp/ch32v10x/family.c to prevent hardfaults on CH32V103 EVT when running in U-mode.
  • Adds a new ch32v103c_bluepill board (pin...
#

board_init() no longer calls __enable_irq(). That changes behavior from other WCH BSPs (and the previous implementation) where board_init() explicitly enables global interrupts after peripheral setup. If interrupts are disabled on entry (e.g., after certain startup/bootloader paths), SysTick/USB IRQs may never run. Instead of commenting these out globally, consider providing a U-mode-safe interrupt enable/disable implementation (or a board/MCU-specific compile-time switch) so `board_ini...

fallow birchBOT
fallow birchBOT
#
[hathach/tinyusb] New branch created: ch32hs
fallow birchBOT
#

I've included a large transfer reliability patch for both USBFS/USBHS driver.

  • Resolve race condition on control transfer status OUT / next SETUP
  • Spurious transfer when EP is not ready

Tested on CH32V203/CH32V305 with audio_4_channel_mic, cdc_dual_ports, dfu, cdc_msc, net_lwip_webserver examples.

Concurrent ISO transfer is not working yet, eg uac2_headset

fallow birchBOT
fallow birchBOT
#

Related area

Making TinyUSB more flexible and less annoying to use in edge-cases

Hardware specification

Hardware agnostic

Is your feature request related to a problem?

I'm trying to make a UAC2 audio interface using an ESP32-P4 and a few DACs and ADCs (MelodyCatcher).
I am using upstream TinyUSB to handle the USB side which works wonders, but I want each input (I have 4 on my design intended to be used in mono configuration) to ha...

fallow birchBOT
#

@HiFiPhile are you recommending that I try using ch32_usbfs? I was using fs_dev, but I faintly remember trying to use ch32_usbfs and I don't think it enumerated properly. I might try it again though and see if I have better luck with it.

Do you have any other suggestions for me if that doesn't work? I don't really have the equipment to debug the USB protocol, nor do I have the knowledge at this point in time.

fallow birchBOT
fallow birchBOT
#
[hathach/tinyusb] New branch created: ch32_fsdev
#

Pull request overview

This PR adds a CH32-specific workaround in the STM32 FSDEV DCD to prevent EP0 from prematurely ACKing OUT packets during control transfers by tracking EP0 control direction/length and dynamically toggling EP0โ€™s configured type (CONTROL โ†” BULK) to gate handshakes.

Changes:

  • Track EP0 control transfer direction and whether a data stage is expected (based on SETUP + wLength) for CH32 targets.
  • Add an EP0 helper to switch endpoint type and apply it during control ...
#

In handle_ctr_rx(), ep0_set_type(U_EP_BULK, ...) is called before the function potentially re-arms RX and writes ep_reg back to EP0. Since ep_reg was captured before switching the type, the later ep_write(ep_id, ep_reg, ...) will restore the old EP type (likely CONTROL), undoing the intended re-lock on multi-packet control OUT transfers. Consider updating the local ep_reg type field to BULK before the final ep_write(), or moving the type switch to a point where it won't be overw...

fallow birchBOT
fallow birchBOT
#
[hathach/tinyusb] New branch created: hathach-funding
fallow birchBOT
#

What resources have you used in order to learn about USB? Also what hardware do you recommend for debugging the USB protocol?

Mostly specifications, USB2.0 and classes like CDC. It's a little boring to read fully but very useful reading a chapter for a specific issue.

Some IPs like DWC2 and Chipidea HS have detailed databook but they are under NDA.

I use a cheap sniffer, nothing fancy but much better than Wireshark based ones.
https://www.usbpacketviewer.com/products/

fallow birchBOT
#

sorry but it really does not meet my needs. do as you wish, but what I proposed is based on define switch and hurts nothing.
Given that you refuse, that means that I need to be looking again into custom copies of tinyusb files in IDF, in order to get it working properly for Arduino on ESP32S2. Your solution does not work at all in my case.

Could you please comment on #385 with your use case that it wouldn't handle? Seems like it is close to done and just needs someone to add some last...

#
[hathach/tinyusb] New branch created: fix\-dfu\-rt
fallow birchBOT
#

@me-no-dev Do you have a PR that splits out the USB fixes from the persistence? That'd be helpful to not block the fixes.

I'd also encourage you to make PRs instead of an issue if you have example code that fixes an issue. That way it's much easier to see the change and the context.

Regarding persistence, I don't think that TinyUSB is the best place to fix it. Reconnecting to a device should be up to the host, not the device. However, if we can make it appear as the same device that wou...

fallow birchBOT
#

@tannewt

Do you have a PR that splits out the USB fixes from the persistence? That'd be helpful to not block the fixes.

I'll open new one, no problem.

I'd also encourage you to make PRs instead of an issue if you have example code that fixes an issue.

I was really confused by the fact that there was no issue already existing for it, so I thought that there is still a chance that I am missing something or that it was known. Having the second platform to confirm, helped.

Reg...

fallow birchBOT
#

I'll open new one, no problem.

Thanks!

Regarding persistence, I don't think that TinyUSB is the best place to fix it. Reconnecting to a device should be up to the host, not the device.

The host is not requesting reset of the device in this case. We in effect just emulate a regular USB-UART chip. They do not reset/enumerate when you are flashing a device. The code in TinyUSB is not a fix, but rather a way to handle the situation. On Mac at least the device will reenumerate w...

fallow birchBOT
#

because of additional bootloaders that do more advanced protocols than cdc (like MSC.)

Guys, I totally get all your points. You are used to a very different workflow, and from what I read in the UF2 repo, it is acting much like bootloaders on other devices.
Please consider the fact that Arduino and IDF workflow on those chips is different than yours. Things like MSC would run in the active application and not in a factory partition. Bootloaders need to be reflashed for different reasons...

fallow birchBOT
fallow birchBOT
fallow birchBOT
#
[hathach/tinyusb] New branch created: add\-da14695\-usb
#

@UweBonnes thank you for your PR, I have tested on my F723 and F769, both work great with OTG HS. SInce you are busy I will merge this now to WIP add-stm-hs branch. So that I could test and address the board_delay() issue in the dcd as well.

PS: If you manage to have time to work on this and not happy with what I done with #447, feel free to continue submitting PR to it or master branch.

fallow birchBOT
fallow birchBOT
#

That is a very good price

I don't doubt it. Just I am not doing USB full time, so such investment makes no sence in may particular case :) I have a cheaper more general purpose LA that runs 9 channels at 200Msps and started on a decoder plugin. Will never be anything close to what your tool does, but could at least shed some light on issues on the bus for me.

can you try out the PR #452 to see if that fixes your issue.

Already did :) looks great, but seems unfinished (you added ...

fallow birchBOT
#

More or less yes. That was the reason we worked on that feature :)

Thanks for confirmation, Let's me sum it up

The Problem
Esptool couldn't upload the way it is currently using FTDI/CP210x since native USB re-enumerate

Proposed solution
You add persistent mode to trick OS thinking bootloader is application

My thought

You guys are approaching the wrong way. Here is the reasons

  1. The firmware is behaving correctly, 99 (if not 100) out of 100 devices out ther...
#

@tannewt reading more into the PR is not that far from what I proposed. Main difference is that my proposal does not use callback to load the app drivers, does not load all built drivers and uses one list, as opposed to two. I will make work with what is made available and not stir more issues :)

I mentioned the PR multiple of times in our conversation :facepalm:

#

I made tests with all and no drivers loaded. Difference was 300 or so bytes. Not worth it. Will go with all drivers loaded and then extra ones from the application through callback as you propose. I am looking forward being able to add custom drivers as well. Your PR will allow it. I am content :) nothing more to comment on it.

Yeah, that is the reason I went with all drivers on smaller chip like nrf52 and samd. Sometimes we thought it is a good idea, but it could turn out not really. Ho...

#

I will let you know once I look into BT and RNDIS, which I so definitely will. HCI makes no sense on S2, but it will on S3 :)
For RNDIS, i think that we have most things already covered in IDF (Lwip, etc) so I hope that will end up smaller in the end as well.

There is no freertos port to run the rndis example, however, if you have any boards with stm32f4 (not sure if f103 could have enough ram/rom to run it ), you could try it out. You should be able to access the on-board webserver v...

#

I have 401 and 411RE, but both do not have USB i think. (Nucleo boards). One thing that comes to mind is to repurpose an old flight controller from one of my quads :) I will port it to S2 for sure. I think I will only have to mess with attaching to LwIP and that is it. It can be a native interface in IDF's IP stack, then be directly bridged to WiFi and more.

stm32f4 has the same USB IP with your esp32s2 from synopsys, which I use a lot for developing the stack

I have the feeling that ...

#

I already implemented that for your esp32s2, but it doesn't work out the same way as STM32F4

https://github.com/hathach/tinyusb/blob/master/src/portable/st/synopsys/dcd_synopsys.c#L749

That is possibly due to the lack of VBUS sense or something. I am not entirely sure, but the detach detection code work with stm32f4, you could also find this in reference code of stm32 cube library as well. For this, you really need to ping your hardware guy, he has the full access to Synopsys IP databoo...

#

I have the databook. It's what I used to figure out persistence. Thing is that I find differences from what it says there and what I see in reality. What it says there is probably in line with what you have on STM. IP Config here is a bit different, not all registers seem to respond to what is documented, and few more cases like that. I already poked the hardware guys for one edge case, will ask for the OTG interrupt. It seem to not come at all for ESP32S2. I was dumping all interrupt flags a...

fallow birchBOT
fallow birchBOT
#

yup... D+ is high after disconnect. This must be it :) will fix!

I would wonder if ESP32-S2 OTG peripheral differs that much from STM. The session end detected interrupt of STM is triggered due to voltage drop of Vbus. Also the D+ pull-up is just applied to the dataline if Vbus sensing detects a B-session valid voltage.

What's your exact hardware setup? Maybe the Vbus sensing pin sees a valid voltage even after disconnecting.

#

@hathach To add to your summary, the other part of the problem that persistence solves is related to console output. When the device re-enumerates after exiting the bootloader, early log output from the application is lost. Persistence allows the host tool to keep the port open on the OS side, so as soon as the device exits the bootloader and starts sending log output, this output is fully received by the host.

fallow birchBOT
fallow birchBOT
#

This is called withtin dcd_init() which only happens one when powering on or reset. Plug and unplug shouldn't be affected at all. If it does, it possibly cause the initial failure of the 1st enumeration or something like that. Though the 2ms delay isn't there for no reasons. Since it works for now, we could worry about this later on when there is problem with it :)

fallow birchBOT
fallow birchBOT
#

Would it be enough for early output to simply use a UART and a converter chip? Seems like native USB will be enough most of the time.

For multiple esps on the same system, with Linux, at least on raspberry pi, you can select the serial port based on the usb path:

pi@broadcastnetbridge:~ $ ls /dev/serial/by-path
platform-3f980000.usb-usb-0:1.2:1.0

These are actually symlinks back to /dev/tty.

I don't know if windows has something similar.

fallow birchBOT
#

We discussed something like this with Ivan and will see what python offers on the different platforms. In a mean time I have submitted https://github.com/hathach/tinyusb/pull/454 to better manage the FIFO situation on S2. Will submit another small PR with a send output interrupt handling. A bit rare, but it happened a few times. And not that you will accept it, but persistence support has been condensed to the following changes only:
<img width="848" alt="Screenshot 2020-07-02 at 0 06 19" sr...

fallow birchBOT
#

Re: Not loading all compiled drivers if they are not needed:

One downside that I found in my particular use case (ESP32-S2 Arduino with all drivers precompiled) is that even if a driver is not to be used (descriptor is not loaded), all required callbacks for that driver need to exist at link time. HID and MSC being tested offenders, HCI and NET not tested, but if they have callbacks that are not weak, case will be the same.

fallow birchBOT
fallow birchBOT
fallow birchBOT
fallow birchBOT
fallow birchBOT
#

@hathach I'm a bit confused- what is the purpose of rhport in the device API? I thought rhport was mostly a host API thing; is it also relevant when a board has multiple USB controllers on board?

I notice that you use a compile-time define to set which port is in use on STM32 boards. Is it possible to use both ports at once with tinyusb, using the same driver for both?

If it's not possible to use both ports at once, why is rhport needed when the correct address and IRQ to use...

fallow birchBOT
#

Yes, your implementation is spot-on with the manual. However, since we only use the last setup packet and ignore the first two setup. I think we don't really need to store them, just overwrite it with each time we pull the setup packet from FIFO. Anything else still keeps the same, the STUPCNT is still 3. The semantic should be the same, it just we don't store the first 2 setup. Let's me know if I misunderstood the workflow, if yes then I am happy to revert this :)

fallow birchBOT
#

@hathach I'm a bit confused- what is the purpose of rhport in the device API? I thought rhport was mostly a host API thing; is it also relevant when a board has multiple USB controllers on board?

I notice that you use a compile-time define to set which port is in use on STM32 boards. Is it possible to use both ports at once with tinyusb, using the same driver for both?

If it's not possible to use both ports at once, why is rhport needed when the correct address and IR...

fallow birchBOT
#

Thanks for another PRs, everything looks great, I am very thankful that you could add a bunches of new BSP. That will help lots of people :). there are olny a few minor questions in the comment.

PS: Let's me know if you are still working on the PRs, and din't want this to be merged yet. Maybe best to mark this as draft if so. That helps to prevent accidentally merged as the previous first 2 ( I thought you are busy and couldn't work on on this).

fallow birchBOT
fallow birchBOT
#

@hathach just started porting the HID class to the restructured host stack and compilation now passes successfully. Initialization seems to work, but there is no USB interrupt when pressing a key on a keyboard. Do you have any idea how to fix this? You may have a look on my code on the branch "zybo" in the forked repository at my account here on GitHub.

I'd really appreciate if you find some time in helping me fixing this.

fallow birchBOT
fallow birchBOT
fallow birchBOT
fallow birchBOT
fallow birchBOT
fallow birchBOT
fallow birchBOT
fallow birchBOT
fallow birchBOT
#

@hathach To add to your summary, the other part of the problem that persistence solves is related to console output. When the device re-enumerates after exiting the bootloader, early log output from the application is lost. Persistence allows the host tool to keep the port open on the OS side, so as soon as the device exits the bootloader and starts sending log output, this output is fully received by the host.

Additional note on the proposed esptool change ("detect new port that mat...

fallow birchBOT
#

The full persistence change is in the image above. No more "hacks". This is all.

There is more code, external to TinyUSB, that is actually rebooting into the proper download mode. That code is still under development/testing. Will soon look into creating a PR with the above changes and some sort of cdc example to demonstrate the feature. If you just want to see it working, it's available in the esp32s2 branch of arduino-esp32 (together with example).

I have created 2 other PRs with fixe...

fallow birchBOT
fallow birchBOT
fallow birchBOT
fallow birchBOT
fallow birchBOT
fallow birchBOT
fallow birchBOT
#

Is your feature request related to a problem? Please describe.
When transmitting data over CDC the write operation can block if the transmit buffer is full and/or cannot fully contain the number of bytes to send. This can prevent preforming time critical functions etc.

Describe the solution you'd like
I would like to read the remaining capacity of the write buffer as a precondition to check. Only if there is capacity in the transmit buffer for a full message as to avoid blocking ...

fallow birchBOT
#

I would like to read the remaining capacity of the write buffer as a precondition to check.

Hello Craig, you've already found the correct function for doing this. tud_cdc_n_write_available() actually returns the remaining capacity of items which fit into the dedicated fifo. Since CDC class defines the fifo's item size by 1, this function will return exactly the number of free bytes within the CDC tx buffer.
Do you have any suggestions for a more descriptive name of this function? Mayb...

fallow birchBOT
#

@duempel Thanks for the response. I hadn't thought changing the function name itself but a improved comment could do it so as to not break existing code that may use it?

If I were to change the name somethign like this seems quite unambiguous:
tud_cdc_get_tx_buffer_remaining

The default setup of CDC will use a not overwriteable fifo. This means that if you put more bytes with tud_cdc_n_write than the remaining buffer capacity, the function will just truncate your data and let y...

fallow birchBOT
#

@duempel I updated the description accordingly.

I think updating the comment in the code would help others and would remove ambiguity to this function being either:

  1. The number of bytes available for transmitting onto the USB bus (i.e. How many bytes have been written to the buffer)
    or
  2. The number of bytes available to be written into the buffer (How many bytes can be written into the buffer before it is full)
fallow birchBOT
#

I wouldn't want to change the API name, it is similar to Arduino API, many Arduino user would find it familiar https://www.arduino.cc/reference/en/language/functions/communication/serial/availableforwrite/

@duempel I updated the description accordingly.

I think updating the comment in the code would help others and would remove ambiguity to this function being either:

  1. The number of bytes available for transmitting onto the USB bus (i.e. How many bytes have been written ...
fallow birchBOT
fallow birchBOT
#

How will you force something like that only on one platform? Surely both ways would work. And yes, I totally agree that it's really weird that endpoints and fifos do not match, especially since you can split the whole fifo memory to more than 5... but :) next silicon I guess. I will be looking into DMA as well, as that is something that can remove the limitation.
Any way you go is fine with me. TBH I have even added a hack locally (you know I like hacks :D) that assigns a fake fifo to EP5 be...