#tinyusb

1 messages · Page 10 of 1

fallow birchBOT
fallow birchBOT
#

I think it should be safe, which scenario you are thinking about ?

You are right, I just feel a bit un-easy when both handle_epin_slave() and edpt_schedule_packets() can write to difof. Especially handle_epin_slave() also called edpt_schedule_packets() in case of ep0. But it is probably safe enough, actually we can refactor this and try to write as many packet as we could before enable the TX empty if there is remaining packet ?

    dwc2_ep_tsize_t tsiz = {.value = epin->tsiz};
...
fallow birchBOT
fallow birchBOT
fallow birchBOT
#

@HiFiPhile retrying iso with flush and re-write packet seems a bit heavy, with high enough bInterval we may end up doing it mostly every frame. Since dwc2 requires

For Periodic IN endpoints, the data must always be prefetched 1 microframe ahead for transmission
in the next microframe. This can be done, by enabling the Periodic IN endpoint 1 (micro)frame ahead
of the (micro)frame in which the data transfer is scheduled

I think in the future we have to improve how we manage IS...

fallow birchBOT
#

On smaller devices, there isn’t enough RAM to store an entire high-resolution frame. I haven’t found a way to use the video device without such a buffer, so I added a callback mechanism that allows the code to request payload data on the fly. This makes it possible to generate or forward data without storing a whole frame at once.

  • The code has been tested on a NanoCH32V305 board.
  • I added demo code to the video device example.
  • I tried to stay consistent with the existing code and us...
#

Related area

OTG

Hardware specification

STM32H7 controller

Is your feature request related to a problem?

Yes, While I was working i could notice that, Dual OTG Mode is not working. On H7 board

Describe the solution you'd like

Dedicated Dynamic switch of Host and Device on H7

I have checked existing issues, dicussion and documentation

  • [x] I confirm I have checked existing issues, dicussion and documentation.
#
  • iso transfer --> compute target frame_num = last xferred frame_num + bInterval
  • enable sof interrupt, loop for iso in check target frame, if there is transfer next --> write data, set odd/even bit.
  • iso incomplete still requires, but I guess host will mostly respect the iso bInterval so the number of rety would be much less often.
  • sof interrupt can be disabled when there is no active iso transfer.

That's what should be done ideally (kernel does something similar), but in r...

fallow birchBOT
#

Thanks @HiFiPhile for the detail info, I think we should follow the bInterval, I don't understand UAC1, but I think bInterval is the hard limit between the ISO transfer, while bRefresh is probably more flexible maybe bRefresh = n*bInterval. Mabye the class driver can have both with the same value to make every OS happy. For dwc2 driver, I think sticking with bInterval is easier and cleaner.

fallow birchBOT
#

@hathach I remembered why we can't do scheduling with bInterval, due to Nak interrupt is unavailable on some devices (OTG_FS). Nak interrupt is needed in order to align the frame number with the host.

For example when bInterval=4 kernel does this:

  • Enable global Nak interrupt on transfer start
  • Nak interrupt will fire since no packet is written
  • In Nak interrupt, check if it's ISO IN EP, then get the frame number (ex. 10), calculate the next frame of ISO transfer (14)
  • In SOF inte...
fallow birchBOT
fallow birchBOT
fallow birchBOT
fallow birchBOT
fallow birchBOT
fallow birchBOT
fallow birchBOT
#

I think we should not introduce this option. I always think the fine-tune fifo should be dictated by application per endpoint basic. E.g MSC + CDC, we would want a massive endpoint size for msc and smaller for cdc. I am think we should do that via a tud_configure() (which allo to pass an option id + pointer to struct) that fine tune the behavior of dcd or stack. similar to tuh_configure() https://github.com/hathach/tinyusb/blob/master/src/host/usbh.h#L145 . dwc2 option may include grxsize and...

fallow birchBOT
#

perfect !! Thank you very much, I didn't test but go through code changes. It looks great, audio is by far the most complicated driver. I think its descriptor is too complicated to have template descirptor as macro. I will try to improve it later on with typedef struct like video example. Thank you very much for putting lots of effort into the driver.

fallow birchBOT
fallow birchBOT
#

@hathach

Just realized my RM0090 is too old !

DIEPMSK->NAKM will enable the interrupt for all endpoints, many interrupts will be generated especially if there are any bulk EP.

Incomplete transfer interrupt only fires once each frame, by default when 80% time of the frame is elapsed. So the CPU load is similar to SOF interrupt.
<img width="861" height="390" alt="image" src="https://github.com/user-attachments/assets/4279e43e-b50d-4162-b218-93c35de843e7" />

fallow birchBOT
#

@HiFiPhile yeah, I think using incomplete iso interrupt is much better than NAK. I guess maybe this interrupt is probably introduced in later version of dwc2 where NAK is already implemented. Also I think we only need to do this once per ISO activate for syncing the first, however we cannot trust host to keep the bInterval right, so yeah sync target/last frame numb everytime ISO is transfer complete or incomplete is great idea.

fallow birchBOT
fallow birchBOT
fallow birchBOT
fallow birchBOT
fallow birchBOT
#

Describe the PR
Added the USB device for the STM32U3 using stm32_fsdev.

Additional context

  • Essentially the same as the STM32U0 and STM32U5 (stm32_fsdev) and others.
  • I am not sure if this addition also handles USB host, but it is possible on this MCU. I left the column empty in the README.
  • This was tested on a custom PCB so I did not add any hw/bsp
  • I have only tested it wit...
fallow birchBOT
#
[hathach/tinyusb] New branch created: fix-code-alerts
#

Pull Request Overview

This PR performs code cleanup and standardization across the TinyUSB codebase. The changes remove deprecated macros, improve code consistency, and fix minor issues related to header includes and code style.

Key changes:

  • Removes deprecated TU_BIN8() macro usage and replaces with hex literals
  • Renames internal macros to be public (_TU_CHECK_MCUTU_MCU_IS_EQUAL, _OSAL_Q_NAMEOSAL_Q_NAME, _TU_ARGS_APPLY_*TU_ARGS_APPLY_*)
  • Reorganizes `` includes...
#

💡 Codex Review

https://github.com/hathach/tinyusb/blob/a01bf9b3306c8aa093ebdef46d1c9175bae17b9a/src/common/tusb_common.h#L74-L79
<sub><sub>P1 Badge</sub></sub> Keep stdio available for modules using printf

Dropping #include <stdio.h> from the common header means all translation units that relied on tusb_common.h for the printf prototype now compile without it. Many BSP sources still call printf directly (for example `hw...

fallow birchBOT
fallow birchBOT
fallow birchBOT
fallow birchBOT
fallow birchBOT
#
[hathach/tinyusb] New branch created: me-no-dev-patch-1
fallow birchBOT
#

dwc2_esp32.h is included by dwc2_common.h, which is included by dwc2_common.c, dwc2_common.c also includes the prototype headers, so it should be fine:

dwc2_common.c
|--device/dcd.h   -> void dcd_int_handler(uint8_t rhport);
|--host/hcd.h     -> void hcd_int_handler(uint8_t rhport, bool in_isr);
|--dwc2_common.h
    |--dwc2_esp32.h

I think the real issue is prevent dwc2_int_handler_wrap to be compiled 2 times ?

#

@HiFiPhile

  • device/usbd.c includes dcd.h which defines dcd_int_handler and also pull dwc2_esp32.h
  • host/usbh.c includes hcd.h which defines hcd_int_handler and also pull dwc2_esp32.h

So they both compile the function dwc2_int_handler_wrap in dwc2_esp32.h and see that both Host and Device are enabled, but depending on which usbh or usbd is compiled, it only sees hcd_int_handler or dcd_int_handler declared, but never both. Compilation fails

#

@me-no-dev

device/usbd.c includes dcd.h which defines dcd_int_handler and also pull dwc2_esp32.h
host/usbh.c includes hcd.h which defines hcd_int_handler and also pull dwc2_esp32.h

I can't find how dwc2_esp32.h get pulled by usbd.c or usbh.c, the only dependency chain I found are:
ddc_dwc2.c -> dwc2_common.h ->dwc2_esp32.h
ddc_common.c -> dwc2_common.h ->dwc2_esp32.h
hdc_dwc2.c -> dwc2_common.h ->dwc2_esp32.h

#

@HiFiPhile
Device dcd_dwc2.c

/Users/ficeto/Desktop/ESP32/ESP-IDF-5/esp32-arduino-lib-builder/components/arduino_tinyusb/tinyusb/src/portable/synopsys/dwc2/dcd_dwc2.c
In file included from /Users/ficeto/Desktop/ESP32/ESP-IDF-5/esp32-arduino-lib-builder/components/arduino_tinyusb/tinyusb/src/portable/synopsys/dwc2/dwc2_common.h:43,
                 from /Users/ficeto/Desktop/ESP32/ESP-IDF-5/esp32-arduino-lib-builder/components/arduino_tinyusb/tinyusb/src/portable/synopsys/dwc2/dcd_d...
fallow birchBOT
#

@me-no-dev Thank you for the log.
Adding a declaration could resulting error dcd_dwc2.c:1040:6: error: redundant redeclaration of 'dcd_int_handler' [-Werror=redundant-decls], even though for esp-idf this check is not enabled ATM.

Another way is to fix once for all (future) ports, but it will leak dcd api into hcd or vice versa:

diff --git a/src/portable/synopsys/dwc2/dwc2_common.c b/src/portable/synopsys/dwc2/dwc2_common.c
index 5ff18ab94..ee79ddc46 100644
--- a/src/portabl...
fallow birchBOT
fallow birchBOT
fallow birchBOT
fallow birchBOT
fallow birchBOT
fallow birchBOT
fallow birchBOT
fallow birchBOT
fallow birchBOT
fallow birchBOT
#
[hathach/tinyusb] New branch created: espressif-dual-mode
fallow birchBOT
#

Operating System

Others

Commit SHA

5.5.1

Board

ESP32P4

Firmware

ESP IDF 5.5.1
espressif/esp_tinyusb: "~2.0.1"
espressif/tinyusb: ">=0.17.0"

What happened ?

I created a USB OTG MIDI device using the ESP32-P4 board and based it on an example template. I have code in place to read MIDI packets, and everything seemed to be working fine until I began testing SysEx data.

When my app (running on a Mac) sends a burst of SysEx messages (each less than 12 bytes, with 16–24...

fallow birchBOT
fallow birchBOT
#

Pull Request Overview

This PR refactors the CMake build system to improve modularity and adds FreeRTOS support for the ESP32P4 platform. The main changes extract TinyUSB source file lists into a reusable function and enable the host_info_to_device_cdc dual-role example to work with FreeRTOS-based systems like ESP32P4.

Key changes:

  • Extracted TinyUSB source listing into tinyusb_sources_get() function for better reusability
  • Added FreeRTOS task management to host_info_to_device_cdc exa...
#

💡 Codex Review

Here are some automated review suggestions for this pull request.

ℹ️ 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 update the PR. Try commenting "@code...

#

<sub><sub>P1 Badge</sub></sub> Fix typoed stack size macros in FreeRTOS path

When configSUPPORT_STATIC_ALLOCATION is disabled the FreeRTOS setup uses xTaskCreate with USBH_STACK_SZE and MAIN_STACK_SZIE. Both identifiers are misspelled and undefined, so any build that relies on dynamic task allocation will fail to compile. These lines should use the existing USBH_STACK_SIZE and MAIN_STACK_SIZE macros.

Useful? React with 👍...

fallow birchBOT
#
[hathach/tinyusb] New branch created: fix-alerts-3
#

Pull Request Overview

This PR adds support for the STM32U3 microcontroller family to TinyUSB. The STM32U3 uses the FSDEV (Full-Speed Device) USB peripheral similar to other STM32 U-series microcontrollers.

Key Changes

  • Added STM32U3 MCU option definition (OPT_MCU_STM32U3 = 321)
  • Configured STM32U3 to use the stm32_fsdev driver with 2KB PMA buffer, 32-bit bus, and 8 endpoints
  • Added STM32U3 USB interrupt configuration (USB_FS_IRQn)

Reviewed Changes

Copilot reviewed 4 out of 4...

#

The Host column is empty (no symbol) for STM32U3, which is inconsistent with other entries in the table. Looking at similar entries (U0 line 213, G4 line 205), untested/unknown host support is indicated with '✖'. Consider using '✖' instead of leaving it blank, or if host support status is truly unknown, consider using a '?' or similar indicator for consistency.

|              | U3                          | ✔      | ✖    | ✖         | stm32_fsdev            |                   |...
#

The comment indicates SBUF_ISO support is untested. This is inconsistent with STM32U0 (line 206) which explicitly disables SBUF_ISO due to performance issues. Consider either: (1) disabling SBUF_ISO for STM32U3 until tested, similar to U0, or (2) updating the comment to explain why U3 is expected to work better than U0, given their architectural similarities (both use USB_DRD_FS, FSDEV_BUS_32BIT).

  // Disable SBUF_ISO on U3 for now due to lack of testing and possible performanc...
#

💡 Codex Review

Here are some automated review suggestions for this pull request.

ℹ️ 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 update the PR. Try commenting "@code...

#

<sub><sub>P0 Badge</sub></sub> osal_semaphore_post now returns a void expression

osal_semaphore_post() now returns the result of sem_release(sem_hdl). On the RP2040 SDK sem_release returns void, so this change produces a compile-time error (“void value not ignored as it ought to be”) and breaks all Pico builds. The previous implementation returned true after calling sem_release. Restore the explicit `sem_release(); return ...

#

<sub><sub>P1 Badge</sub></sub> Restore default TX FIFO overwrite behaviour

The default configuration macro now sets tx_overwritabe_if_not_connected to false, whereas previously it was 1 and the driver still documents “Default: is overwritable”. This silently changes the public API’s behaviour so that CDC writes while the terminal is disconnected will stop once the FIFO fills rather than overwriting old data. Existing applicatio...

#

Pull Request Overview

This PR focuses on code quality improvements through static analysis fixes, formatting standardization, and MISRA C compliance. The changes include PVS-Studio warning suppressions, explicit comparisons for clarity, proper type usage (bool instead of uint8_t for flags), void casts for unused return values, and clang-format configuration updates for consistent code style.

Key Changes

  • Added PVS-Studio static analysis suppressions and configuration improvements
  • ...
#

The default value for tx_overwritabe_if_not_connected was changed from 1 (true) to false, which appears to be an unintended behavior change. The original code set this to 1 (true), indicating that this was the intended default behavior. If this change is intentional, it should be documented as a breaking change.

  .tx_overwritabe_if_not_connected = true, \
#

Changing TU_LOG1 from tu_printf to (void) tu_printf breaks the macro's functionality. When used as TU_LOG1("format", args...), it will expand to (void) tu_printf("format", args...) which attempts to cast a function pointer rather than calling the function and casting its return value. The correct form should be #define TU_LOG1(...) (void) tu_printf(__VA_ARGS__) to properly suppress the return value warning while maintaining functionality.

#define TU_LOG1(...)        ...
#

The cast (uint8_t*) is unnecessary here. _mscd_epbuf.buf is already defined as uint8_t[] via the TUD_EPBUF_DEF macro, and &p_msc->csw is of type msc_csw_t* which is compatible with const void* (memcpy's second parameter). The standard memcpy signature is void* memcpy(void*, const void*, size_t), so no cast is needed for either parameter.

  memcpy(_mscd_epbuf.buf, &p_msc->csw, sizeof(msc_csw_t)); //-V1086
fallow birchBOT
#

Pull Request Overview

This PR adds nested locking support to the bare-metal spinlock implementation in osal_none.h. The enhancement allows the same execution context to acquire a spinlock multiple times without deadlocking, which is crucial for single-core bare-metal systems where nested critical sections are common.

Key changes:

  • Added nested_count field to track lock depth and prevent premature interrupt re-enabling
  • Modified lock/unlock logic to only disable/enable interrupts on...
#

Re-enabling interrupts in the underflow error path is problematic. If nested_count is 0, it means either: (1) unlock was called without a matching lock, or (2) the lock was acquired in an ISR. In case (1), the interrupt state is unknown - interrupts may have been disabled by other code or may already be enabled. Unconditionally enabling them could break the caller's interrupt state assumptions. Consider removing lines 66-69 and just asserting, or only re-enable if you can confirm they were di...

#

The comment on line 56 claims the nested_count increment is atomic, but it's not. There's a race condition: an interrupt could fire between checking ctx->nested_count == 0 (line 57) and disabling interrupts (line 58), potentially causing the same interrupt handler to see nested_count == 0 and also disable interrupts. While this may not break the current implementation's correctness, the comment is misleading. Consider revising the comment to: `// Disable interrupts on first lock to protect ...

fallow birchBOT
#

Pull Request Overview

This PR adds FIFO threshold configuration support for USB audio devices, enabling fine-tuned control over both EP IN (transmit) and EP OUT (receive via feedback) FIFO buffer management for better latency control.

  • Adds getter/setter API functions for EP IN FIFO threshold configuration
  • Extends audio_feedback_params_t struct with fifo_count.fifo_threshold field for EP OUT feedback control
  • Updates flow control logic to use configurable thresholds instead of ha...
#

Missing NULL descriptor check. The setter function should verify that _audiod_fct[func_id].p_desc != NULL before accessing ep_in_ff.depth and setting ep_in_fifo_threshold, consistent with other API functions like tud_audio_n_clear_ep_in_ff() at line 538. Without this check, there's a risk of accessing uninitialized data.

  if (func_id < CFG_TUD_AUDIO && _audiod_fct[func_id].p_desc != NULL && threshold < _audiod_fct[func_id].ep_in_ff.depth) {
#

Missing NULL descriptor check. The getter function should verify that _audiod_fct[func_id].p_desc != NULL before accessing ep_in_fifo_threshold, consistent with tud_audio_n_get_ep_in_ff() at line 543. Without this check, there's a risk of accessing uninitialized data.

  if (func_id < CFG_TUD_AUDIO && _audiod_fct[func_id].p_desc != NULL) {
    return _audiod_fct[func_id].ep_in_fifo_threshold;
  }
fallow birchBOT
fallow birchBOT
fallow birchBOT
fallow birchBOT
fallow birchBOT
fallow birchBOT
fallow birchBOT
#

Hi,

I just want to let you know that your original code (current version) works correctly in ESP-IDF + ESP32 P4 for SysEx MIDI (the problem I tested).
I tried to make an identical project with esp-tinyUSB fork again, but I was not able to read all incoming data (SysEx burst),
and I tried almost everything I think could be related.
I will push this to Espressif, of course.

Thank you.

J.

On 6 Nov 2025, at 12:43, Ha Thach @.***> wrote:

hathach
left a commen...

fallow birchBOT
fallow birchBOT
fallow birchBOT
#
[hathach/tinyusb] New branch created: midi-edpt-stream
#

Pull Request Overview

This PR migrates the MIDI device class driver from using direct FIFO management to using the new endpoint stream API. This simplifies the code by leveraging the shared stream infrastructure and adds new functions for reading/writing multiple MIDI packets at once.

  • Replaced manual FIFO and endpoint management with tu_edpt_stream_t API
  • Added tud_midi_n_packet_read_n() and tud_midi_n_packet_write_n() functions for bulk packet operations
  • Updated style convent...
#

💡 Codex Review

https://github.com/hathach/tinyusb/blob/0b6d5080e1bd45d6ad334e8b0148628c27b60431/src/class/midi/midi_device.c#L298-L309
<sub><sub>P1 Badge</sub></sub> Return packet count from tud_midi_n_packet_write_n

The new bulk send API advertises that it returns the number of packets written, mirroring tud_midi_n_packet_read_n. However the implementation returns the raw byte count from tu_edpt_stream_write. Callers that ...

fallow birchBOT
fallow birchBOT
#

The order of operations is inconsistent with the pattern used in the host code. While functionally correct (since n_packets << 2u is always a multiple of 4), the host code pattern (see tuh_midi_packet_read_n in midi_host.c lines 425-426) is clearer:

n_bytes = tu_min32(n_bytes, n_packets << 2u);
n_bytes = tu_align4(n_bytes);

or equivalently:

n_bytes = tu_align4(tu_min32(n_bytes, n_packets << 2u));

This makes the intent clearer: take the minimum of available and requested ...

fallow birchBOT
#
[hathach/tinyusb] New branch created: cdc-edpt-stream
#

💡 Codex Review

https://github.com/hathach/tinyusb/blob/0871c7d619d96953d6a87bdc37a447217a836fc2/src/class/cdc/cdc_device.c#L372-L379
<sub><sub>P1 Badge</sub></sub> Avoid asserting when persistent CDC RX FIFO is full

The new cdcd_open always asserts that tu_edpt_stream_read_xfer() succeeds after opening the OUT endpoint. When RX persistence is enabled (_cdcd_cfg.rx_persistent == true) the FIFO contents are intentionally pr...

#

Pull Request Overview

This PR migrates the CDC device class to use the unified endpoint stream API, consolidating FIFO management and endpoint transfer logic into reusable stream abstractions. The changes simplify CDC device/host implementations while maintaining backward compatibility.

Key Changes:

  • Refactored CDC device to use tu_edpt_stream_t instead of direct FIFO management, removing ~150 lines of code
  • Updated MIDI and vendor device classes to use stream clear operations fo...
#

Clearing stream state before closing streams. The tu_memclr on line 309 clears ITF_MEM_RESET_SIZE bytes which includes the stream state (ep_addr, is_mps512), but then tu_edpt_stream_close is called on lines 312-313 which sets ep_addr = 0. The close calls are redundant since the streams are already cleared. Consider either: 1) calling tu_edpt_stream_close before tu_memclr, or 2) removing the close calls since memclr already zeros the ep_addr.


fallow birchBOT
fallow birchBOT
#
[hathach/tinyusb] New branch created: update-iso-alloc
fallow birchBOT
#

Describe the PR
Remove assumption that HID Report descriptor is before HID Endpoint.

Additional context
I have been using tinyusb's HID Host stack in my project and came across a game controller that has an...odd configuration.

Most HID Devices have the HID Report Descriptor preceding the endpoint, however I came across a device that has it following the endpoint.

you can see it in this lsusb call where it tails the endpoint with DEVICE CLASS which is actually the Rep...

fallow birchBOT
#

Operating System

Others

Commit SHA

latest master

Board

Adafruit Feather nrf52832 + USB Host Featherwing (max3421)

Firmware

custom firmware based on based on examples/host/cdc_msc_hid (only enabled CDC), compiled with nrfsdk 2.9.2 based on Zephyr.

What happened ?

I'm working on a small device (USB Host) to connect my Rowing machine (CDC Device) to translate received data to be tracked by my sports watch.

What I've stumbled accross is, that after a couple of unplug...

fallow birchBOT
fallow birchBOT
fallow birchBOT
fallow birchBOT
fallow birchBOT
#

Pull Request Overview

This PR transitions TinyUSB to use dcd_edpt_iso_alloc()/dcd_edpt_iso_activate() as the default driver API for ISO endpoints, deprecating dcd_edpt_close(). The changes include:

  • Inverting the conditional compilation logic in dcd.h to make ISO APIs the default
  • Defining TUP_DCD_EDPT_CLOSE_API for drivers that still implement the old API
  • Updating multiple DCD drivers to either stub out or implement the new ISO APIs
  • Updating MCX board configuration files...
#

These commented-out lines in dcd_edpt_iso_activate() should either be removed if unnecessary or uncommented with an explanation if they're needed. Leaving ambiguous commented code reduces maintainability.

#if CFG_TUD_MEM_DCACHE_ENABLE
  // Ensure data cache coherency for DMA: clean and invalidate dcd_data_t before hardware access
  dcd_dcache_clean_invalidate(&_dcd_data, sizeof(dcd_data_t));
#endif
#

💡 Codex Review

Here are some automated review suggestions for this pull request.

ℹ️ 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 update the PR. Try commenting "@code...

#

<sub><sub>P1 Badge</sub></sub> Default ISO API leaves many MCUs without a working handler

Making TUP_DCD_EDPT_ISO_ALLOC the default in src/common/tusb_mcu.h (lines 692‑699) now routes every isochronous endpoint through dcd_edpt_iso_alloc()/dcd_edpt_iso_activate(), but several drivers added in the same commit still leave those functions as return false stubs – for example src/portable/microchip/samd/dcd_samd.c 248‑258, `src/...

fallow birchBOT
#

@HiFiPhile PR stil haven't implemented the target frame yet. So the application need to call the edpt_xfer() 1 frame before the bInterval, otherwise we will miss that IN token and send data in the next bInterval (late timing) ?

I think in the future we have to improve how we manage ISO transfer e.g

  • iso transfer --> compute target frame_num = last xferred frame_num + bInterval
  • enable sof interrupt, loop for iso in check target frame, if there is transfer next --> write data, set...
#

Pull Request Overview

This PR fixes an issue where queued transfers from a failed USB device enumeration interfere with subsequent enumeration attempts by implementing a cleanup mechanism for pending transfers when a device is closed.

Key Changes:

  • Added a closing flag to the hcd_xfer_t structure to mark transfers being cleaned up
  • Modified hcd_device_close() to mark associated transfers as closing and disable their channels
  • Updated all four channel interrupt handlers (IN/O...
#

For non-split periodic channels, the closing flag is set (line 470) but channel_disable() is not called (line 472-474). The closing flag is only checked within if (hcint & HCINT_HALTED) blocks in the interrupt handlers (lines 962-966, 1027-1031, 1149-1154, 1216-1221). If a non-split periodic channel doesn't naturally halt after the device is removed, it may never be properly cleaned up.

Consider whether non-split periodic channels need additional handling to ensure they eventually halt a...

#

In slave mode, the closing flag check uses else if (lines 962-966), which means it won't execute if the transfer has a valid result (line 957-958) or reached max errors (line 959-961). This could cause events to be sent for closing transfers.

In contrast, the DMA mode handlers (lines 1149-1154, 1216-1221) use a separate if statement that correctly overrides is_done to false regardless of the transfer result.

The slave mode handlers should use a separate if statement (not else if) ...

#

The endpoint is cleared before marking associated channels as closing, which creates a race condition. If a channel interrupt occurs after the endpoint is cleared (line 464) but before the transfer is marked as closing (line 470), the interrupt handler will access the cleared endpoint data via edpt = &_hcd_data.edpt[xfer->ep_id] (used in all channel handlers).

Recommendation: Move the tu_memclr(edpt, sizeof(hcd_endpoint_t)) call to after the channel cleanup loop, or disable interrupts fo...

#

Similar to the issue in handle_channel_in_slave, the closing flag check uses else if (lines 1027-1031), which means it won't execute if the transfer has a valid result (line 1022-1023) or reached max errors (line 1024-1026). This could cause events to be sent for closing transfers.

The DMA mode handlers (lines 1149-1154, 1216-1221) correctly use a separate if statement that overrides is_done to false.

Change this to a separate if statement (not else if) to match the DMA handler ...

fallow birchBOT
#

is there any chances that 2 ISO is schedule at the same uframe, and 1 is complete and 1 is incomplete and we detect the wrong endpoint ?

The interrupt is fired at the end of periodic frame interval (80% of the frame by default), it's unlikely any transfer is still pending.

<img width="832" height="79" alt="image" src="https://github.com/user-attachments/assets/7bad7c0d-f749-42fc-97d0-8b6038f6bb60" />

fallow birchBOT
#

PR stil haven't implemented the target frame yet. So the application need to call the edpt_xfer() 1 frame before the bInterval, otherwise we will miss that IN token and send data in the next bInterval (late timing) ?

@hathach Both audio and video are real-time streaming data it's ok to return transfer failed if the host didn't read the data in the specified interval. edpt_xfer() needs to be called not earlier than bInterval*frames before the IN token:

  • If bInterval = 1 the packet is s...
fallow birchBOT
fallow birchBOT
fallow birchBOT
fallow birchBOT
fallow birchBOT
#

@HiFiPhile thanks for the explanation, I know ISO data can be missed. Let's say bInterval = 10, and we recevie setInterface at frame=100, assume host send the 1st IN token as well. So we will have

  • frame 100: 1st IN token
  • frame 110: 2nd In token and so on

So ideally video/audio must prepare the next iso data within the bInterval and call edpt_xfer() it as soon as the data is ready. let's say at frame 105th, the stack would then ideally only fetch data to fifo at frame 109. with the c...

fallow birchBOT
fallow birchBOT
#

So ideally video/audio must prepare the next iso data within the bInterval and call edpt_xfer() it as soon as the data is ready. let's say at frame 105th, the stack would then ideally only fetch data to fifo at frame 109. with the current implementation, what would happen at frame 106,107 ?

@hathach If edpt_xfer is called at 105th data will be pushed into fifo and the transfer will be scheduled for 106th. At 106th incomplete interrupt fires and rearm the endpoint for 107th. At 107th same...

fallow birchBOT
fallow birchBOT
fallow birchBOT
#

So ideally video/audio must prepare the next iso data within the bInterval and call edpt_xfer() it as soon as the data is ready. let's say at frame 105th, the stack would then ideally only fetch data to fifo at frame 109. with the current implementation, what would happen at frame 106,107 ?

@hathach If edpt_xfer is called at 105th data will be pushed into fifo and the transfer will be scheduled for 106th. At 106th incomplete interrupt fires and rearm the endpoint for 107th. At 107t...

fallow birchBOT
#

Pull Request Overview

This PR addresses static analysis alerts from PVS-Studio across the DWC2 USB host controller driver, focusing on improving code clarity and addressing MISRA-C compliance warnings.

Key changes:

  • Added explicit unsigned literal suffixes (0x01u, 0x02u) to prevent type promotion issues
  • Converted implicit boolean checks to explicit comparisons for 1-bit bitfields
  • Refactored if-else chains into switch statements for transfer type handling
  • Introduced named constants...
#

The file is named copilot-instructions.md (plural), not copilot-instruction.md (singular) as shown in the comment. Also, the path should be .github/copilot-instructions.md not ./github/copilot-instruction.md (the leading period should not be included in the path reference).

## Copilot Agent Notes (`.github/copilot-instructions.md`)
#

The comparison > 0 is unnecessary and changes the semantics. The post-decrement operator count-- returns the value before decrementing, so when count is 0, it returns 0 (which is falsy) and the loop terminates correctly. The original while (count--) idiom is the standard C pattern for countdown loops and is used consistently in similar files (e.g., dwc2_at32.h line 98). The added comparison doesn't fix any issue and makes the code less idiomatic.

  while (count--) {
fallow birchBOT
fallow birchBOT
#
[hathach/tinyusb] New branch created: update-agents
#

Pull Request Overview

This PR bumps the TinyUSB version from 0.19.0 to 0.20.0 in preparation for a new release. The changes update version numbers across configuration files, consolidate agent documentation, add new board presets, and document all changes in the release changelog.

  • Version number updated from 0.19.0 to 0.20.0 across all configuration files
  • Documentation consolidated from .github/copilot-instructions.md into AGENTS.md with enhanced release instructions
  • New board ...
fallow birchBOT
#
[hathach/tinyusb] New branch created: update-changelog
fallow birchBOT
fallow birchBOT
#
[hathach/tinyusb] New tag created: 0.20.0
fallow birchBOT
fallow birchBOT
#
[hathach/tinyusb] New branch created: ep0_direct
fallow birchBOT
#

Pull Request Overview

This PR optimizes control transfer buffer management in TinyUSB by allowing device classes to use the EP0 buffer directly when it's large enough, avoiding unnecessary dedicated buffer allocations and memory copies. This improves memory efficiency on resource-constrained devices while maintaining the same functional behavior.

Key Changes

  • Added usbd_control_get_buffer() API to expose the EP0 buffer to device class implementations
  • Optimized control transfer p...
#

The get_ctrl_buffer() function is defined here but first used at line 1329 (before the definition). Since this is a static inline function, it needs to be defined before its first use or have a forward declaration.

Suggested fix: Move this function definition to an earlier location in the file, ideally near the other forward declarations (around line 450), or add a forward declaration.

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

Operating System

Others

Commit SHA

3af1bec

Board

STM32C071

Firmware

CDC Sample

What happened ?

HI,

Im trying now for days to make a very simple tinyUSB USB CDC sample with a STM32 Nucelo C071 board. I have searched the whole internet but found no explanation to my problem. Im failing to integrate the tinyUSB lib into my project. Can someone explain a minimal cmake example how to implement the tinyUSB lib?

BR
Matthias

How to reproduce ?

My cmake so far:

cm...

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

Pull request overview

This PR adds a new configuration API (dcd_configure) to dynamically configure DWC2 device controller behavior, specifically enabling double buffering for IN endpoints to improve throughput. The implementation replaces the previous hardcoded TX FIFO empty level configuration with a configurable double buffering approach.

Key changes:

  • New public API tud_configure() to configure device stack behavior before initialization
  • DWC2-specific configuration structure t...
fallow birchBOT
#

💡 Codex Review

Here are some automated review suggestions for this pull request.

ℹ️ 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 update the PR. Try commenting "@code...

#

<sub><sub>P1 Badge</sub></sub> Dedicated hwfifo now breaks DWC2 DMA transfers

The new block unconditionally sets CFG_TUD_EDPT_DEDICATED_HWFIFO whenever TUP_USBIP_DWC2 and slave mode are enabled. When DMA is also enabled (CFG_TUD_DWC2_DMA_ENABLE=1), CDC/device streams now use usbd_edpt_xfer_fifo, which clears xfer->buffer (dcd_dwc2.c:687-692). The DMA path in edpt_schedule_packets() still programs diepdma from `xfer->buffe...

#

Pull request overview

This pull request removes intermediate endpoint buffers for USB endpoints with dedicated hardware FIFOs, optimizing memory usage and data transfer efficiency for certain USB controllers like DWC2.

  • Introduces CFG_TUD_EDPT_DEDICATED_HWFIFO configuration to enable direct hardware FIFO access without intermediate buffering
  • Refactors FIFO API to use tu_fifo_access_mode_t enum with TU_FIFO_FIXED_ADDR_RW32 mode for hardware FIFO operations
  • Updates CDC device cl...
fallow birchBOT
#

Operating System

Windows 11

Commit SHA

86a4990b96eafb5904f946fa061b310f155a7d51

Board

stm32n6

Firmware

examples/device/cdc_msc

What happened ?

Build fails with the following errors:
cdc_msc - Debug
system_stm32n6xx_fsbl.o

SAU->RNR = 0;		
^		

Error[Pe020]: identifier "SAU" is undefined D:\projects\SC3\test\BB\tinyusb\hw\mcu\st\cmsis_device_n6\Source\Templates\system_stm32n6xx_fsbl.c 192

SCB_NS->CPACR |= ((3UL << 20U)|(3UL << 22U));  /* set CP1...
fallow birchBOT
#
[hathach/tinyusb] New branch created: hcd_fsdev
fallow birchBOT
#

I am able to create custom IAR project with cubemx and make tinyusb work with stm32n6 but wanted to see how Cmake and documented "how to" works, and decided to build project from the examples folder. And this causes issue described above.

Normally internal symbols like __ARM_FEATURE_CMSE are defined automatically by IAR. Maybe the processor define in https://github.com/hathach/tinyusb/blob/master/examples/build_system/cmake/cpu/cortex-m55.cmake is incorrect, you can compare with your cu...

#

Describe the PR
Add stm32_fsdev HCD mode support, host mode works pretty like device mode with 8 bidirectional channels.

  • Static buffer allocation, 64 bytes per channel (no ISO support)
  • Dynamic channel allocation like dwc2
  • No interrupt transfer scheduler, transfer will be retried on each frame if NAKed
  • Hub is untested

Tested on Nucleo-C071RB (put on both STLINK and USB power jumper):

Example Result Note
device_info OK Keyboard/Disk...
#

Pull request overview

This PR adds USB Host Controller Driver (HCD) support for STM32 FSDEV peripheral, enabling host mode functionality on STM32 C0, G0, H5, and U5 MCU families. The implementation refactors common code from the existing device controller driver (DCD) into shared files to support both device and host modes.

Key changes:

  • Implements a new HCD driver with static buffer allocation (64 bytes per channel), dynamic channel allocation, and NAK retry mechanism
  • Refactors packe...
#

The comment incorrectly states 'External oscillator' but HSE_VALUE of 48MHz suggests this is configured for the Nucleo board's ST-LINK MCO output (which provides 48MHz from ST-LINK's HSE). The comment should clarify this is the ST-LINK MCO frequency, not a typical external crystal oscillator.

#define HSE_VALUE    (48000000U)         /*!< Value of the ST-LINK MCO output in Hz (Nucleo boards), not a typical external crystal oscillator */
fallow birchBOT
#

Thanks for your efforts!
tried to add extra param to

<img width="742" height="691" alt="Image" src="https://github.com/user-attachments/assets/674e1309-430f-42e9-98b1-f434ffd5a5cf" />

but same error for now.
<img width="2488" height="540" alt="Image" src="https://github.com/user-attachments/assets/3d61653a-f974-4092-b9da-b64c3656b730" />

Might be worth for me to rise issue with IAR on Cmake support.

fallow birchBOT
#

Operating System

Windows 11

Commit SHA

the latest HEAD

Board

any board can reproduce this issue per my test, I tried stm32f103_bluepill and stm32f072disco

Firmware

examples/device/webusb_serial with attached patch to remove the cdc so that only CFG_TUD_VENDOR is enabled.

tinyusb.patch

What happened ?

Windows can't initialize the usb device properly, and UsbTreeView show "28" for the device. so wi...

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

Pull request overview

This PR fixes SysTick timer configuration issues across multiple BSP (Board Support Package) implementations to ensure proper behavior when FreeRTOS is enabled. The changes prevent SysTick ISR from running before the FreeRTOS scheduler starts, which could cause timing issues and undefined behavior.

Key changes:

  • Added explicit SysTick disable (SysTick->CTRL &= ~1U;) for FreeRTOS configurations
  • Wrapped SysTick_Config calls with OPT_OS_NONE checks where they ...
#
[hathach/tinyusb] New branch created: misc_fix
fallow birchBOT
#

Pull request overview

This PR includes miscellaneous fixes across the codebase, addressing performance settings, concurrency issues, and developer tooling improvements.

Key Changes:

  • Enables FSDEV_HAS_SBUF_ISO for STM32U0, resolving previous audio performance issues
  • Fixes potential race condition in FIFO empty check by reading volatile indices to local variables
  • Improves Python audio debug script with better signal handling, error codes, and matplotlib best practices

Review...

fallow birchBOT
#

Hey Espressif guys =)
If possible: PLEASE add dual tinyUSB stack support, so both USB2.0 Hosts can run at the same time.
I want to give you a valid important usecase:
You are already providing usb audio support & usb_hid support. Both device types -and that is the point - are mostly FS (!) ones.
Currently you cannot use them together with devices like mass storage and others with these others running at HS.
There are boards available already, that have "hubs" for HS (3 ports) and a single FS ...

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

Description

During the recent update (https://github.com/hathach/tinyusb/pull/3326)

dcd_deinit(rhport); -> TU_VERIFY(dcd_deinit(rhport));

the assertion fails for the ports, where dcd_deinit() isn't implemented yet.

Changes

This PR introduces a quick fix by changing the default return value from false to true in the WEAK function, allowing the assert to pass.

The same way, as we have it for:

TU_ATTR_WEAK bool dcd_dcache_clean(const void* addr, uint32...
fallow birchBOT
#

Describe the PR
I've made 2 hub enumeration reliability improvements, they works will here but not sure if there are any edge case.

  • Stop enumeration gracefully if EP0 can't be open
    When CFG_TUH_FSDEV_ENDPOINT_MAX is not enough, usbh_edpt_control_open() fails and the hub become stuck.

    With quick plug/unplug sometimes old endpoint release happens after new endpoint open. Normally my config only needs 15 EPs (3 for hub + 4 for keyboard + 4 for USB key + 4 for FTDI) but I hit ...

fallow birchBOT
fallow birchBOT
#

Related area

class driver

Hardware specification

Pico W or other boards with bluetooth support

Is your feature request related to a problem?

Hi, I see there is not an example for Bluetooth device class, I'm would like to get some example how it's the correct use of this driver.

I'm trying to use this driver with rp2040, but I'm having a hard time with an error about the setting the device configuration. I'm getting this error:

USBD Setup Received 00 09 01 00 00 00 00 00...
fallow birchBOT
#

Hi @HiFiPhile,

I think we can take the chance to add dcd_deinit to dwc2

Sure, that is my next step.

This PR is about another thing: the dcd_deinit() might be optional, as the dcd_init() could have all the necessary code to start from two states: was init done or wasn't init done.
So in this case, if we have an TU_ASSERT() for the optional call, we need to make it pass even if the function isn't implemented.

fallow birchBOT
fallow birchBOT
#
[hathach/tinyusb] New branch created: vendor-dedicated-hwfifo
#

💡 Codex Review

Here are some automated review suggestions for this pull request.

ℹ️ 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 update the PR. Try commenting "@code...

#

<sub><sub>P1 Badge</sub></sub> Restore non-FIFO stream reads

In tu_edpt_stream_read the non-FIFO path now immediately returns 0 without copying from s->ep_buf. For configurations that deliberately disable the RX FIFO (e.g., CFG_TUD_VENDOR_RX_BUFSIZE == 0 or any stream with tu_fifo_depth(&s->ff) == 0), host transfers complete and tud_vendor_n_read() is invoked but always reports no data because the endpoint buffer is never...

#

Pull request overview

This PR updates the vendor device implementation to support hardware endpoints with dedicated FIFO buffers, eliminating the need for local endpoint buffers in such configurations. This optimization reduces memory usage on hardware platforms with built-in FIFO support.

Key Changes:

  • Modified stream read/write functions to handle both buffered and unbuffered (dedicated HWFIFO) modes
  • Changed tud_vendor_rx_cb() API behavior: buffer/bufsize parameters are only v...
fallow birchBOT
#

Related area

I am trying to make a CCID reader device

Hardware specification

ESP32S3

Is your feature request related to a problem?

Firstly, please, let me know if there is any way to make a "generic" device with simple bulk in and out.

If so, that would suit me for now. But so far I have not found one - perhaps this could itself be a feature to allow for a variety of classes of devices that are not yet covered by TinyUSB. I tried VENDOR, but had not realised that it specific...

#

You can slightly modify the vendor class and register it as a custom driver. check https://github.com/kkitayam/akiprobe as example.

Just declare the interface then use usbd_app_driver_get_cb()

usbd_class_driver_t const cmsis_dap = {
#if CFG_TUSB_DEBUG >= 2
  .name = "CMSIS-DAP",
#endif
  .init             = cmsis_dapd_init,
  .reset            = cmsis_dapd_reset,
  .open             = cmsis_dapd_open,
  .control_xfer_cb  = tud_vendor_control_xfer_cb,
  .xfer_cb          = cmsis_dapd_xf...
fallow birchBOT
#

Is that essentially a generic driver (does not check class) that has bulk in and out?

Yep, just modify the class code check to meet your need.

Perhaps the VENDOR class could avoid checking the class is 0xFF and add bulk in and out?

This check is needed for each class to avoid messing around with other class drivers, on device init the configuration descriptor passes into all classes, the class driver should process only the one it concerns.

what CFG_TUD_ do I define?

Do what ever y...

#

OK, a generic class could have a #define for what class code to check even. And even #defines to say which interfaces to expect with a simple BULK IN/OUT default perhaps.

But it seems I will have to change some tinyusb code to make anything work for me, bodging VENDOR or some such. I can do that, but makes it a maintenance headache as I can never update the managed components from ESP IDF without zapping my changes.

A feature request (apart from smart card specific) would be a way to allow,...

#

I can do that, but makes it a maintenance headache as I can never update the managed components from ESP IDF without zapping my changes.

You don't need to poke around managed components, I wasn't clear that I means was copy vendor class driver and modify it in your project, not in-place modification.

OK, a generic class could have a #define for what class code to check even. And even #defines to say which interfaces to expect with a simple BULK IN/OUT default perhaps.

Vendor class cod...

#

OK, can I just copy vendor class and change. Literally copy the C code to my main and that will work?

Yep, copy the code and modify the name to avoid collision, to something like ccid_open, ccid_reset, ccid_xfer_cb etc.

Then add driver registration:

usbd_class_driver_t const ccid_driver = {
#if CFG_TUSB_DEBUG >= 2
  .name = "CCID driver",
#endif
  .init             = ccid_init,
  .reset            = ccid_reset,
  .open             = ccid_open,
  .control_xfer_cb  = ccid_control...
fallow birchBOT
fallow birchBOT
#
[hathach/tinyusb] New branch created: fix-zephyr-build
#

Pull request overview

This PR fixes build compatibility with Zephyr RTOS when using the latest nrfx v4 by adding proper version detection and conditional compilation for Zephyr-specific configurations.

Key changes:

  • Extended nrfx version detection to support v3 and v4 based on MDK version ranges
  • Updated clock API calls to use the new nrf_clock_is_running() function for nrfx v2+
  • Added Zephyr-specific conditional compilation to exclude UART initialization that conflicts with Zephyr's ...
#

<sub><sub>P1 Badge</sub></sub> Preserve clock API for nrfx v2/v3 builds

When CFG_TUD_NRF_NRFX_VERSION resolves to 2 or 3 (MDK 8.44–8.53 per the version table), hfclk_running now calls nrf_clock_is_running(NRF_CLOCK, NRF_CLOCK_DOMAIN_HFCLK, …) for all versions greater than 1. That helper only exists in nrfx v4, while the v2/v3 HALs still expose nrf_clock_hf_is_running, so building against the common nrfx v2/v3 SDKs will fail t...

#

💡 Codex Review

Here are some automated review suggestions for this pull request.

ℹ️ 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 update the PR. Try commenting "@code...

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

Pull request overview

This PR refactors the ARM GCC toolchain setup in CI/CD workflows from using a third-party GitHub action to manual download and installation. The change enables cross-platform support by allowing OS-specific toolchain downloads for Windows and macOS builds.

Key changes:

  • Removes dependency on carlosperate/arm-none-eabi-gcc-action for ARM GCC installation
  • Adds OS-specific ARM GCC toolchain URLs to support macOS and Windows runners
  • Updates Nordic board reference...
#

The macOS toolchain URL specifies darwin-arm64, which only supports Apple Silicon Macs. Intel-based macOS runners (if any are used) would fail with this toolchain. Consider using darwin-x64 for broader compatibility or documenting that macOS builds require ARM64 runners.

  "arm-gcc-macos-latest": "https://github.com/xpack-dev-tools/arm-none-eabi-gcc-xpack/releases/download/v14.2.1-1.1/xpack-arm-none-eabi-gcc-14.2.1-1.1-darwin-x64.tar.gz",
fallow birchBOT
fallow birchBOT
#
[hathach/tinyusb] New branch created: dwc2_deinit
#

@roma-jam Hi, I've added deinit support to dwc2, tested on STM32H7S3:

      static uint32_t btn_prev = 0;
      const uint32_t btn = board_button_read();
      static bool onoff = false;
      if (!btn_prev && btn) {
        onoff = !onoff;
        if(onoff) {
          tud_deinit(BOARD_TUD_RHPORT);
          printf("Host Stopped\r\n");
        } else {
          tusb_rhport_init_t dev_init = {
            .role = TUSB_ROLE_DEVICE,
            .speed = TUSB_SPEED_AUTO
     ...
#

Pull request overview

This PR adds deinitialization support for the Synopsys DWC2 USB controller, enabling dynamic start/stop of USB host and device modes. The implementation mirrors the initialization sequence in reverse, disabling interrupts, disconnecting from the bus, and resetting the core. This was tested on STM32H7S3 with device mode toggling via button press.

Key Changes

  • Implements hcd_deinit() and dcd_deinit() functions for DWC2 host and device controllers
  • Adds commo...
#

The host deinit function should turn off VBUS power before shutdown, similar to how hcd_init() turns it on with dwc2->hprt = HPRT_POWER; at line 435.

Add before calling dwc2_core_deinit():

dwc2->hprt = HPRT_W1_MASK; // clear write-1-clear bits  
dwc2->hprt = 0;  // turn off VBUS

  // Turn off VBUS power before shutdown
  dwc2->hprt = HPRT_W1_MASK; // clear write-1-clear bits
  dwc2->hprt = 0;            // turn off VBUS
#

The deinit function already calls dcd_disconnect() at line 511, which sets dwc2->dctl |= DCTL_SDIS (soft disconnect). Then dwc2_core_deinit() sets the same bit again at dwc2_common.c:258. This is redundant, though not harmful. Consider whether the soft disconnect in dwc2_core_deinit should be removed to avoid duplicate operations.

  dwc2_core_deinit(rhport); // Note: Remove redundant soft disconnect in dwc2_core_deinit implementation.
#

The DCTL register is device-specific and should not be accessed unconditionally in a common deinit function that is called by both host and device modes. When in host mode, this writes to a device-only register which may cause undefined behavior.

Consider removing this line or making it conditional based on the role (host vs device), similar to how the init sequence uses TUSB_ROLE_HOST vs TUSB_ROLE_DEVICE. The device-specific disconnect should be handled in dcd_deinit() (which already...

fallow birchBOT
#

Thanks for the feedback on #3377. I've created this new PR, which merges into #3377, to address your comment. I will work on the changes and keep this PR's description up to date as I make progress.

Original PR: #3377
Triggering comment (https://github.com/hathach/tinyusb/pull/3377#issuecomment-3589933143):

@copilot fix ci build issue with make-os: matrix: os = "windows-latest", arm-none-abi-gcc is added to GITHUB_PATH but not found when running build.py with make. Possibly the GITHUB_PATH...

fallow birchBOT
#

Incorrect register field used. The code is clearing bits from USB_OTG_HS->GOTGCTL but using USB_OTG_GCCFG_VBVALEXTOEN and USB_OTG_GCCFG_VBVALOVAL which are GCCFG register bits, not GOTGCTL register bits. This should likely be:

USB_OTG_HS->GCCFG &= ~USB_OTG_GCCFG_VBVALEXTOEN;
USB_OTG_HS->GCCFG &= ~USB_OTG_GCCFG_VBVALOVAL;
      USB_OTG_HS->GCCFG &= ~USB_OTG_GCCFG_VBVALEXTOEN;
      USB_OTG_HS->GCCFG &= ~USB_OTG_GCCFG_VBVALOVAL;
#

Incorrect register field used. The code is clearing bits from USB_OTG_HS->GOTGCTL but using USB_OTG_GCCFG_VBVALEXTOEN and USB_OTG_GCCFG_VBVALOVAL which are GCCFG register bits, not GOTGCTL register bits. This should likely be:

USB_OTG_HS->GCCFG &= ~USB_OTG_GCCFG_VBVALEXTOEN;
USB_OTG_HS->GCCFG &= ~USB_OTG_GCCFG_VBVALOVAL;
      USB_OTG_HS->GCCFG &= ~USB_OTG_GCCFG_VBVALEXTOEN;
      USB_OTG_HS->GCCFG &= ~USB_OTG_GCCFG_VBVALOVAL;
fallow birchBOT
fallow birchBOT
#
[hathach/tinyusb] New branch created: audio_open
#

Pull request overview

This PR enhances the audiod_open function in audio_device.c to properly differentiate between Audio and MIDI device interfaces, preventing the audio driver from incorrectly accepting MIDI devices. The fix adds validation logic to verify that the interface following an Audio Control interface is Audio Streaming (subclass 2) rather than MIDI Streaming (subclass 3).

Key changes:

  • Added explicit return value 0 to all TU_VERIFY and TU_ASSERT macro calls for co...
#

The loop condition p_desc_end - p_desc > 0 doesn't validate that there's enough space to safely call tu_desc_next(p_desc) and tu_desc_type(p_desc). If a malformed descriptor has a length field of 0, this could cause an infinite loop. Consider using tu_desc_in_bounds(p_desc, p_desc_end) helper function (similar to line 870 in midi_device.c) which properly validates descriptor boundaries before advancing.

    while (tu_desc_in_bounds(p_desc, p_desc_end) && tu_desc_type(p_d...
#

The bounds check p_desc_end - p_desc > 0 only verifies at least 1 byte is available, but then the code accesses next_itf->bInterfaceClass and next_itf->bInterfaceSubClass which requires a full tusb_desc_interface_t structure (9 bytes). This could read beyond the buffer boundary if there are fewer than 9 bytes remaining. The check should be p_desc_end - p_desc >= sizeof(tusb_desc_interface_t) to ensure safe access to the structure fields.

    if (p_desc_end - p_desc >= ...
fallow birchBOT
#
[hathach/tinyusb] New branch created: pr-size-diff
#

💡 Codex Review

Here are some automated review suggestions for this pull request.

ℹ️ 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 update the PR. Try commenting "@code...

#

<sub><sub>P1 Badge</sub></sub> Metrics target lacks Python interpreter

The new tinyusb_examples_metrics target is invoked by the updated build script, but the command relies on ${Python3_EXECUTABLE} even though this CMake project never calls find_package(Python3). As a result, the first argument of the custom command expands to an empty string and attempts to execute tools/metrics.py directly, which is not marked executable. ...

#

Pull request overview

This PR introduces automated code size metrics collection and reporting for TinyUSB by integrating the linkermap tool. The changes include adding a new metrics aggregation script, refactoring the build system to use safer subprocess calls, and configuring CMake to generate linker map files and compute average code sizes across multiple builds.

  • Added tools/metrics.py to calculate and aggregate average sizes from multiple linker map files
  • Refactored `tools/build...
fallow birchBOT
fallow birchBOT
fallow birchBOT
#

TinyUSB Code Size Different Report

Base: base-metrics/metrics.json
New: metrics.json

File .rodata .text .data .bss Total
audio_device.c 0 2804 ➡ 2809 (+5, +0.2%) 1228 ➡ 1228 1754 ➡ 1749 (-5, -0.3%) 4553 ➡ 4553
cdc_device.c 16 ➡ 16 1431 ➡ 1436 (+5, +0.3%) 22 ➡ 22 664 ➡ 684 (+20, +3.0%) 2094 ➡ 2119 (+25, +1.2%)
cdc_host.c 487 ➡ 487 6653 ➡ 6655 (+2, +0.0%) 15 ➡ 15 1444 ➡ 1612 (+168, +...
fallow birchBOT
#
[hathach/tinyusb] New branch created: fine-tune-ci
#

💡 Codex Review

Here are some automated review suggestions for this pull request.

ℹ️ 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 update the PR. Try commenting "@code...

#

<sub><sub>P1 Badge</sub></sub> Avoid unbounded parallelism when PR builds switch to make

Setting BUILD_SYSTEM="make" for pull requests means CircleCI PR jobs now go through the make path in tools/build.py, but that path ignores the -j 4 cap you pass in config and instead spins up a multiprocessing pool sized to os.cpu_count() while also disabling -j in make_one_example when CIRCLECI is set (see tools/build.py lines 14...

#

Size Difference Report

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

File .rodata .text .data .bss Total
audio_device.c 0 2804 ➡ 2806 (+2, +0.1%) 1228 ➡ 1228 1754 ➡ 1754 4553 ➡ 4555 (+2, +0.0%)
cdc_device.c 16 ➡ 16 1431 ➡ 1433 (+2, +0.1%) 22 ➡ 22 664 ➡ 653 (-11, -1.7%) 2094 ➡ 2085 (-9, -0.4%)
cdc_host.c 487 ➡ 48...
fallow birchBOT
fallow birchBOT
#

Operating System

Linux

Commit SHA

1

Board

Any board using STM32F103xB

Firmware

TinyUSB asserts when trying to open a USB endpoint with address 08.

What happened ?

In STM32 USB endpoint values are 4 bit, with values 0 - 15.

tusb_mcu.h defines TUP_DCD_ENDPOINT_MAX as 8 which is incorrect. It should be 16.

How to reproduce ?

Try and open an endpoint address >= 0x08, e.g. 0x88 and usbd.c will assert at approx line 1360.
for example
#define EPNUM_CDC_3_NOTIF...

fallow birchBOT
fallow birchBOT
#

TinyUSB Code Size Different Report

Base: base-metrics/metrics.json
New: metrics.json

File .rodata .text .data .bss Total
audio_device.c 0 2804 ➡ 2809 (+5, +0.2%) 1228 ➡ 1228 1754 ➡ 1738 (-16, -0.9%) 4553 ➡ 4541 (-12, -0.3%)
cdc_device.c 16 ➡ 16 1431 ➡ 1438 (+7, +0.5%) 22 ➡ 22 664 ➡ 714 (+50, +7.5%) 2094 ➡ 2150 (+56, +2.7%)
cdc_host.c 487 ➡ 487 6653 ➡ 6619 (-34, -0.5%) 15 ➡ 15 1444 ...
fallow birchBOT
fallow birchBOT
fallow birchBOT
#
[hathach/tinyusb] New branch created: more-ci-build-for-size
#

Pull request overview

This PR refactors the CI build configuration to use a fixed set of boards, migrating from file-based skip lists to Python-based configuration dictionaries. The change introduces two new command-line options (--one-first and --one-random) to replace the previous --one-per-family flag, providing more explicit control over board selection in CI builds.

Key Changes:

  • Migrated CI board control from skip_ci.txt files to Python dictionaries (ci_skip_boards a...
#

The logic when both one_first and one_random are True is potentially confusing. If both flags are set, one_first always takes precedence over one_random (line 245-246 will execute before reaching 247-248). Consider adding mutual exclusivity validation or documenting the precedence order explicitly. For example:

if one_first and one_random:
    raise ValueError("Cannot specify both --one-first and --one-random")

Or at minimum, document in the function docstring which fl...

#

The select_list (from ci_preferred_boards) is returned without validation. This could return boards that:

  1. Don't exist in the family
  2. Were filtered out by skip_list (from ci_skip_boards)
  3. Result in an empty list if all preferred boards are skipped

Consider validating that at least one board from select_list exists in all_boards:

if select_list:
    valid_boards = [b for b in select_list if b in all_boards]
    if valid_boards:
        return valid_boards
    # Fa...
#

[nitpick] The previous implementation checked if a board was already specified via the -b flag and would skip selecting a board from that family. This check has been removed, which means if a user specifies both a family and a specific board from that family (e.g., python tools/build.py stm32h7 -b stm32h743eval --one-first), the board may be built twice (once from the -b flag and once from the family selection).

If this behavior change is intentional for simplification, consider docume...

#

The comment states "only one random board per family" but the actual build option used is --one-first (line 81), which selects the first board alphabetically, not a random one. Update the comment to reflect the actual behavior:

# CMake build: only one board per family (first alphabetically). Full build is done by CircleCI in PR
  # CMake build: only one board per family (first alphabetically). Full build is done by CircleCI in PR
#

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.

File .text .rodata .data .bss Total
audio_device.c 2811 ➙ 2809 (-2, -0.1%) 0 1228 1751 ➙ 1739 (-12, -0.7%) 4557 ➙ 4542 (-15, -0.3%)
cdc_device.c 1436 ➙ 1437 (+1, +0.1%) 16 22 680 ➙ 698 (+18, +2.6%) ...
fallow birchBOT
fallow birchBOT
#

@tannewt do you have a branch that have wip 0.20.0 (else I will just bump tinyusb submodule in cpy to test with). I will try to see if could reduce the size by dropping features that some smaller ports does not need. This refactor all common edpt stream code so it should reduce code size if e.g cdc and midi both enabled, but I haven't check.

PS: I am trying to optimize the code size for tinyusb, new PR now will have a comment on code size change.

fallow birchBOT
#
[hathach/tinyusb] New branch created: more-diff-size-report
fallow birchBOT
#

I've compared HEAD and 2f0a35f21af4c09154d6b4b5b118325af8990e51 with IAR debug build midi_test:

Header HEAD 2f0a35f21
midi_device.o 1578 1490
tusb.o 1964 448
Total 23298 21706

We can reduce size by remove some inline comparing tud_midi_n_available()

Master:
<img height="900" alt="image" src="https://github.com/user-attachments/assets/dd168d5c-9bc1-4550-93ec-a201e895d320" />

2f0a35f21af4c09154d6b4b5b118325af8990...

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

I did some test in https://github.com/hathach/tinyusb/tree/size_tweak by:

  • un-inline common used functions
  • unpack 2 packed bitfield, cortex-m is inefficient doing bit-ops

While it's still larger but half-way done ;)

Debug:

Header HEAD 2f0a35f21 Test
midi_device.o 1578 1490 1430
tusb.o 1964 448 1404
Total 23298 21706 22278

Release:

| Header | HEAD | 2f0a35f21| Test |
|--------|--------|--------|----...

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 any section

No entries.

Changes <1% in all sections

No entries.

No changes

File .rodata .text .data .bss Total
audio_device.c 0 2809 1228 1739 4542
cdc_device.c 16 1437 22 ...
fallow birchBOT
#
[hathach/tinyusb] New branch created: hide-unchange-size
fallow birchBOT
#

@tannewt do you have a branch that have wip 0.20.0 (else I will just bump tinyusb submodule in cpy to test with).

I was testing with https://github.com/adafruit/circuitpython/pull/10736 but didn't end up needing to update TinyUSB. I had done it to the 0.20.0 tag. The tip of master yesterday had even less remaining space.

I was doing the arduino_zero TRANSLATION=ru build in testing. It has CDC and MIDI so it should share the stream code. It is LTOd too. That may make a difference.

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

Pull request overview

This PR adds comprehensive deinitialization support to TinyUSB, enabling dynamic switching between USB device and host modes at runtime. The changes introduce new pre-init and post-deinit callback hooks, implement deinit functions across multiple USB controller drivers, and include a new example demonstrating the dual-role switching capability.

Key Changes:

  • Added tusb_pre_init_cb() and tusb_post_deinit_cb() callback hooks with weak default implementations ...
#

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 any section

File .rodata .text .data .bss Total
dcd_ci_hs.c 0 1725 ➙ 1726 (+1, +0.1%) 0 1152 ➙ 1280 (+128, +11.1%) 2493 ➙ 2512 (+19, +0.8%)
ehci.c 0 2651 ➙ 2655 (+4, +0.2%) 0 5970 ...
fallow birchBOT
fallow birchBOT
#

Operating System

Linux

Commit SHA

1

Board

WeActv-STM32F103CBT6-BluePillv1.1

Firmware

A triple CD, triple UART application on a AliExpress Bluepill board (fitted with a non fake STM processor).
TinyUSB source code was taken from the github Releases area in .zip form, for 0.19.0 and 0.20.0.
App code was initially written using 0.18.0.
I just updated it to using to 0.20.0 and it stopped working.
I've just stepped back and tried 0.19.0 instead which works, i.e. updating fro...

fallow birchBOT
#

From your log I saw a transfer was queued before the device is fully initialized:

USBD Setup Received 80 06 00 02 00 00 CF 00 
  Get Descriptor Configuration[0]
  Queue EP 80 with 32 bytes ...
  Queue EP 00 with 8 bytes ...                                 <-------EP not init yet
USBD Xfer Complete on EP 80 with 32 bytes
  Queue EP 80 with 32 bytes ...
USBD Xfer Complete on EP 80 with 32 bytes
  Queue EP 80 with 32 bytes ...
USBD Xfer Complete on EP 80 with 32 bytes
  Queue EP 80 with 32 b...
#
[hathach/tinyusb] New branch created: hwfifo_post
#

Describe the PR

  • Add CFG_TUD_EDPT_DEDICATED_HWFIFO flag to other supported families.
  • There is a weak dcd_edpt_xfer_fifo() implementation in usbd.c so no need to guard usbd_edpt_xfer_fifo() with CFG_TUD_EDPT_DEDICATED_HWFIFO flag, remove the ifdef guard makes the log more verbose when failed (was debugging why audio no longer work)
  • In audio_device.c, replace local test by CFG_TUD_EDPT_DEDICATED_HWFIFO
#

Pull request overview

This PR standardizes the handling of hardware FIFO support across different USB IP families by introducing and utilizing the CFG_TUD_EDPT_DEDICATED_HWFIFO configuration flag.

Key Changes:

  • Fixed a typo in DWC2 host configuration (CFG_TUD → CFG_TUH on line 312)
  • Added CFG_TUD_EDPT_DEDICATED_HWFIFO support for ChipIdea HS, FSDEV, MUSB, and RUSB2 USB IP families
  • Removed CFG_TUD_EDPT_DEDICATED_HWFIFO guards from usbd_edpt_xfer_fifo() to enable better log...
#

The condition !defined(CFG_TUD_MEM_DCACHE_ENABLE) should be !CFG_TUD_MEM_DCACHE_ENABLE. According to the comment on line 327, FIFO transfer should be enabled when "DCACHE is disabled" (i.e., when the value is 0), not when it's undefined. This matches the pattern used for DWC2 on line 308 (!CFG_TUD_DWC2_DMA_ENABLE) and the actual usage in dcd_ci_hs.c:526 (#if !CFG_TUD_MEM_DCACHE_ENABLE). The current condition would incorrectly enable FIFO when DCACHE is undefined, which could lead to...

#

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 any section

File .rodata .text .data .bss Total
audio_device.c 0 2809 ➙ 2802 (-7, -0.2%) 1228 1739 ➙ 1677 (-62, -3.6%) 4542 ➙ 4474 (-68, -1.5%)
cdc_device.c 16 1437 ➙ 1430 (-7, -0.5%) ...
fallow birchBOT
#

Thanks for the quick look at that. I've gone thru my code and added in tud_cdc_n_ready() calls prior to any CDC accesses.
Also chopped out most of the other app functionality, e.g. buttons, uarts etc... to reduce what I'm looking thru.

The app now asserts at cdcd_open 376, (cdc_device.c which is where it was initially asserting on my 1st attempt at using 0.20.0).
TU_ASSERT(tu_edpt_stream_read_xfer(rhport, stream_rx) > 0, 0); // prepare for incoming data

My app basically boils down to
m...

fallow birchBOT
#

UPDATE - I have found what it is in my code that is causing the failure in 0.20.0 --> setting CFG_TUD_CDC_RX_BUFSIZE=32.
(I have CFG_TUD_ENDPOINT0_SIZE=64, CFG_TUD_CDC_TX_BUFSIZE=64 and CFG_TUD_CDC_EP_BUFSIZE=64).

(My original app code which worked for 0.18.0 and 0.19.0 set all four values to 32).

Attached are two logs for CFG_TUD_CDC_RX_BUFSIZE=32 and CFG_TUD_CDC_RX_BUFSIZE=64.
(In both logs, the other three settings are 64, so the only change is that for CFG_TUD_CDC_RX_BUFSIZE).

[cutecom...

fallow birchBOT
#

UPDATE - I have found what it is in my code that is causing the failure in 0.20.0 --> setting CFG_TUD_CDC_RX_BUFSIZE=32.
(I have CFG_TUD_ENDPOINT0_SIZE=64, CFG_TUD_CDC_TX_BUFSIZE=64 and CFG_TUD_CDC_EP_BUFSIZE=64).

Yeah I took a look at new stream transfer functions and found that it assumes FS bulk endpoint size (MPS) is 64 bytes, it refuse to launch transfer if the FIFO is smaller than MPS.

Should be fixed by #3396

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

ℹ️ 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 update the PR. Try commenting "@code...

#

<sub><sub>P1 Badge</sub></sub> Merge metrics using truncated filenames

Bloaty compile units are recorded with file set to os.path.basename(unit_path), but compute_avg later groups entries solely by f["file"]. When two different objects share the same basename (e.g., usb.c in multiple port directories), their sizes and symbols are merged and averaged together, yielding incorrect totals and hiding regressions for any duplicat...

#

Pull request overview

This PR refactors the code metrics system to use Google's bloaty tool instead of the linkermap library for analyzing code size. It also introduces optimizations for reducing code size through conditional compilation of FIFO-related code when vendor class buffers are zero-sized, and consolidates compiler attribute definitions.

Key Changes

  • Replace linkermap-based metrics with bloaty CSV parsing in tools/metrics.py
  • Add CFG_TUSB_EDPT_STREAM_NO_FIFO_ENABLED to co...
#

[nitpick] Changing from include guards to #pragma once is generally fine, but #pragma once is not part of the C standard (though widely supported). The original include guards were more portable. If this codebase needs to support very old or non-standard compilers, this could be problematic. Consider verifying that all target compilers support #pragma once.

#

The condition CFG_TUD_VENDOR_TX_BUFSIZE == 0 || CFG_TUD_VENDOR_RX_BUFSIZE == 0 will enable CFG_TUSB_EDPT_STREAM_NO_FIFO_ENABLED if either buffer size is zero. However, this might not be the intended behavior - if only TX is zero but RX is non-zero, should no-FIFO mode be enabled for both? Consider whether this should be && instead of ||, or whether separate TX/RX flags are needed.

#if CFG_TUD_ENABLED && CFG_TUD_VENDOR && (CFG_TUD_VENDOR_TX_BUFSIZE == 0 && CFG_TUD_VENDO...
#

Potential division by zero when totals_list is empty. If all data entries lack a valid TOTAL, the fallback calculation sum(f["size"] for f in files_average) or 1 uses or 1 to avoid division by zero, but this creates a misleading total of 1 when all files have zero size. Consider raising an error or returning a more meaningful value instead.

    if totals_list:
        total_size = round(sum(totals_list) / len(totals_list))
    else:
        sum_sizes = sum(f["size"] for f ...
#

[nitpick] The (void)hwid; statement on line 505 is only needed when CFG_TUSB_EDPT_STREAM_NO_FIFO_ENABLED is 0. When it's 1, the non-fifo branch uses hwid. Consider moving this to the beginning of the function with a proper guard or restructuring the conditional compilation to avoid the unused parameter warning more cleanly.

  {
    // In FIFO mode, hwid is unused
#

[nitpick] The refactored overflow count calculation using int32_t intermediate cast is clearer and avoids potential unsigned underflow issues. However, ensure that wr_idx and rd_idx are always within the valid range for int32_t conversion. If these can exceed INT32_MAX, the cast could cause undefined behavior. Given they're uint16_t, this should be safe, but consider adding a comment explaining this constraint.

#

The fallback calculation on line 339 recomputes the total from files when json_data.get("TOTAL") is missing, but this differs from the averaging logic in compute_avg. In compute_avg, when totals_list is empty, it also falls back to summing file sizes. However, the or 1 on line 207 could cause total_size to be 1 instead of the actual sum, leading to incorrect percentage calculations. Consider ensuring consistency between these two code paths.

    total_size = json_dat...
#

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 .data .bss size % diff
tusb.c 616 ➙ 532 (-84) 524 ➙ 453 (-71) 3 617 ➙ 533 (-84) -13.6%
TOTAL 616...
fallow birchBOT
#

If one sends data of exactly the length of bulk_mps, is_complete is errorneously not set. Therefore, the referenced line
https://github.com/hathach/tinyusb/blob/e9cd4d823fe4cd7de03587c57fc8288ad5711b15/src/class/mtp/mtp_device.c#L428

should be:

  p_mtp->xferred_len >= p_mtp->total_len) // total length reached
          {

This happens, e.g. when replying to a GetHandles request with 12 elements (and low speed). This gives exactly 64 bytes, they are sent, but is_complete is ne...

fallow birchBOT
#

Thanks for assigning this issue to me. I'm starting to work on it and will keep this PR's description up to date as I form a plan and make progress.

Original prompt


This section details on the original issue you should resolve

MTP bug in mtp_device.c : mtpd_xfer_cb (including fix!)
If one sends data of exactly the length of bulk_mps, is_complete is errorneously not set. Therefore, the referenced line
https://github.com/hathach/tinyusb/blob/e9cd4d823fe4cd7de03...

fallow birchBOT
fallow birchBOT
#
[hathach/tinyusb] New branch created: more-size-reduce-edpt-stream
fallow birchBOT
fallow birchBOT
fallow birchBOT
fallow birchBOT
fallow birchBOT
fallow birchBOT
#

Though I revert the changes with ifdef guard for usbd_xfer_fifo() since it save a bit of flash. Why would it cause the audio issue with logging though, without the CFG_TUD_EDPT_DEDICATED_HWFIFO, the function would return false anyway ?

It's fine to revert now, audio_device used different test condition for FIFO transfer, resulting usbd_edpt_xfer_fifo is called when CFG_TUD_EDPT_DEDICATED_HWFIFO=0 but failed silently without assert or breakpoint.

seems like we have cdc echo issu...

#

It's fine to revert now, audio_device used different test condition for FIFO transfer, resulting usbd_edpt_xfer_fifo is called when CFG_TUD_EDPT_DEDICATED_HWFIFO=0 but failed silently without assert or breakpoint.

ok, I will refactor usbd_xfer and usbd xfer_fifo later. Let revert this for now.

seems like we have cdc echo issue with musb and rusb2

msub needs #3017, maybe rusb2 has the same access limitation ? I don't have board to test with.

right, I guess we need mor...

fallow birchBOT
fallow birchBOT
fallow birchBOT
fallow birchBOT
#

I think we need to verify if stream is opened before operation, the check is removed after cdc & vendor refactor. Fix #3395

diff --git a/src/class/cdc/cdc_device.c b/src/class/cdc/cdc_device.c
index d7792afe4..d8e636f38 100644
--- a/src/class/cdc/cdc_device.c
+++ b/src/class/cdc/cdc_device.c
@@ -43,7 +43,6 @@
 //--------------------------------------------------------------------+
 // MACRO CONSTANT TYPEDEF
 //----------------------------------------------------------------...
fallow birchBOT
fallow birchBOT
#

@HiFiPhile thank right, the idea to drop the check for cdc is to allow it to write/read from fifo even if device is not connected. Eg. some device print out boot message before enumerated. I think we should add the check to _xfer() only. Not sure if midi need this "feature", currently it skip if not connected.

In fact it's enough to put the check in fewer places while allowing fifo access. I think skip midi write is good, for midi read is less needed.

diff --git a/src/class/cdc...
fallow birchBOT
fallow birchBOT
#
[hathach/tinyusb] New branch created: rusb2_fifo_fix
fallow birchBOT
#

Remove this line should be OK?
https://github.com/hathach/tinyusb/blob/64820791516b4001cb169f095588ccb52eb35ea8/src/tusb.c#L453
Will this affect other logic?

I tried this method. It works fine.

void tud_vendor_tx_cb(uint8_t itf, uint32_t sent_bytes) { 
    // other logic...
	if(sendFinished){
        if(sent_bytes&&(sent_bytes%MAX_PACKET_SIZE)==0){
            tud_vendor_write(NULL,0);
        }
	}
}
fallow birchBOT
fallow birchBOT
#

💡 Codex Review

Here are some automated review suggestions for this pull request.

ℹ️ 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 update the PR. Try commenting "@code...

#

<sub><sub>P2 Badge</sub></sub> Correct MCU list name to match HPM family

FAMILY_MCUS is set to HPMIRCO instead of the actual HPM identifier, so CMake’s family_filter logic will iterate over the wrong MCU name. Any mcu:HPM entries in skip/only.txt (or other MCU-specific handling) will be ignored, causing unsupported HPM builds to be attempted rather than filtered out. Please rename the entry to the real HPM MCU token so filtering ...

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

@tannewt https://github.com/hathach/tinyusb/pull/3402 fine tune to reduce the tinyusb foot print. I also add the code metrics which basically sum average all boards/examples for each .c file. The metrics make it easier to follow the code size and make fine tuning later on.

 make BOARD=arduino_zero V=1 TRANSLATION=ru all
QSTR not updated
Module registrations not updated
Root pointer registrations not updated
Memory region         Used Size  Region Size  %age Used
FLASH_BOOTLOADER...
fallow birchBOT
fallow birchBOT
fallow birchBOT
#
[hathach/tinyusb] New branch created: metrics-on-release
#

💡 Codex Review

Here are some automated review suggestions for this pull request.

ℹ️ 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 update the PR. Try commenting "@code...

#

<sub><sub>P1 Badge</sub></sub> Pin checkout to a published major version

build.yml now uses actions/checkout@v6, but the checkout action only publishes up to v4 today. GitHub will abort the workflow with “Unable to resolve action ‘actions/checkout@v6’” before any steps run, and the same change in the other workflows in this commit will similarly block those jobs until the checkout version is pinned to an existing release.

Useful...

#

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...
#

Pull request overview

This PR enhances the build workflow to automatically upload code metrics and comparison reports to GitHub releases. It adds a release event trigger, downloads metrics from the previous release for comparison, and uploads both metrics.json and a comparison markdown file to the current release page. Additionally, it updates all actions/checkout references from v4 to v6 across multiple workflow files.

Key Changes

  • Adds release event trigger and upload functi...
#

The fetch-tags parameter may not be supported in actions/checkout v4. This parameter name appears to be non-standard. The standard parameter name is 'fetch-depth' to control cloning depth. If you need to fetch tags, you typically set fetch-depth to 0 or use a separate git command to fetch tags. Please verify this parameter name is correct for the version of actions/checkout being used.

          fetch-depth: ${{ github.event_name == 'release' && '0' || '1' }}
#

The git tag command may fail if there are fewer than 2 tags in the repository, or if tags have not been fetched. Consider adding error handling to check if PREV_TAG is empty before using it in subsequent commands, especially since the checkout step only fetches tags conditionally.

          if [ -z "$PREV_TAG" ]; then
            echo "No previous tag found. Skipping previous release asset download."
            echo "PREV_TAG=" >> $GITHUB_ENV
          else
            echo "Pr...
#

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

udpate build.yml to and metrics-comment.yml so that it ccould post PR comment on forked PR. Currently it does works


💡 You can make Copilot smarter by setting up custom instructions, customizing its development environment and configuring Model Context Protocol (MCP) servers. Learn more [Copilot coding agent tips](ht...

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

For anyone wanting to build the example cdc_dualports out of the box for an stm32f103 bluepill board, this is what I had to do.
unzip your copy of tinyusb "tinyusb.zip" into a folder... I used "/whatever"
cd /whatever/tinyusb-0.20.0/examples/device/cdc_dual_ports
make -C . BOARD=stm32f103_bluepill get-deps
make -C . BOARD=stm32f103_bluepill all

The resulting .bin or .hex files are then in the subfolder "_build/stm32f103_bluepill/"

fallow birchBOT
#

Operating System

Windows 10

Commit SHA

1

Board

STM32F103 Bluepill

Firmware

I'm not having much luck in getting my custom CDC_ACM device to be recognised by Win10 Pro 2009 Build 19045.5737.

Device manager generally says Get Device Descriptor failed, status 0xC000009C, Problem 0xA.

So I tried the CDC ACMM dual port example and it too won't load under Win 10.

What happened ?

The device works perfectly in Ubuntu 25.10, but Win10 refuses to load it.

Just in case it ...

fallow birchBOT
#
[hathach/tinyusb] New branch created: fifo-access-mode
fallow birchBOT
fallow birchBOT
fallow birchBOT
fallow birchBOT
#

Operating System

Linux

Commit SHA

3a0

Board

MSPM0G5187

Firmware

NA

What happened ?

While using DFU via TinyUSB on an MUSB-based controller, DFU_UPLOAD intermittently fails after one successful upload. The failure occurs specifically when the host issues a DFU_GETSTATUS request immediately after a DFU_UPLOAD transfer.

This results in:
• Device no longer responding to GETSTATUS
• DFU state machine getting stuck
• Subsequent DFU operations failing until reset

H...

fallow birchBOT
#

Hi, I'm a little confused about the cause. Both DFU Upload and GetStatus are control IN transfers just like get descriptors, unless there is a racing condition which makes one work but not another.

• _dcd.status_out is still set
• A new valid SETUP packet is already present
• The driver incorrectly interprets the new SETUP as STATUS handling and drops it

Setup packet is received in dcd_int_handler() -> process_ep0() -> process_setup_packet, the device is always ready to receive Setu...

fallow birchBOT
#

I don't have MSPM0G5187 and it is not one supported MCUs. Can you confirm the issue also occur with tm4c123. For the issue detail: please update 1st post with

  • complete commit hash
  • firmware: we will need an example that run on mcu, I guess you are runing dfu examples, if you have modification, please provide the minial example that could cause the issue.
  • "how to reproduce": which specific command or testing to trigger the issue
fallow birchBOT
fallow birchBOT
fallow birchBOT
#
[hathach/tinyusb] New branch created: remove-sprintf
#

Pull request overview

This PR removes the usage of snprintf in the tu_lookup_find function by replacing dynamic hex formatting of unknown keys with a static "NotFound" string. This change simplifies the code and eliminates a thread-safety issue caused by returning a pointer to a static buffer.

Key changes:

  • Removes snprintf call that formatted unknown keys as hex strings (e.g., "0x00000005")
  • Returns a constant "NotFound" string instead of a dynamically formatted value
  • Eliminat...
#

Replacing the hex-formatted key value with "NotFound" results in loss of important debugging information. When a lookup fails, developers previously could see the actual key value (e.g., "0x00000005") to help debug why the lookup failed. Now they will only see "NotFound" which provides no information about what key was being looked for. Consider passing the key value to the logging caller so the diagnostic value can be preserved, or provide an alternative mechanism to log unknown keys.

fallow birchBOT
#
[hathach/tinyusb] New branch created: fix-imxrt-1011-bsp
#

💡 Codex Review

Here are some automated review suggestions for this pull request.

ℹ️ 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 update the PR. Try commenting "@code...

#

<sub><sub>P1 Badge</sub></sub> Preserve XIP boot header symbols during link

The -Wl,-uimage_vector_table and -Wl,-ug_boot_data link options were removed here, but the imxrt toolchain uses --gc-sections (see examples/build_system/cmake/toolchain/common.cmake:35), and fsl_flexspi_nor_boot.c defines those boot header symbols without any references. Without the -u keeps, the linker can garbage-collect the boot header, so XIP ...

#

Pull request overview

This PR adds DCache enablement support for i.MX RT boards, particularly the RT1011, and refactors the build configuration to use __START=main instead of a custom _start() implementation.

  • Enables DCache early in board initialization for boards that don't configure it via MPU setup
  • Replaces custom _start() function with standard __START=main compiler define
  • Moves fsl_flexspi_nor_boot.c from board library to example targets in CMake build

Reviewed ...

#

The DCache is being enabled before BOARD_ConfigMPU() is called. This ordering may cause issues:

  1. Some boards (like mimxrt1170_evkb) disable DCache at the start of BOARD_ConfigMPU(), reconfigure the MPU, then re-enable DCache. For these boards, the early enablement here is redundant.

  2. For boards with empty BOARD_ConfigMPU(), enabling DCache before proper MPU configuration might work but goes against the recommended initialization sequence shown in boards like mimxrt1170_evkb.

Consider m...

fallow birchBOT
#

Describe the PR
I have run into an edge cast where the host application abruptly stops while there is data still within the vendor output buffer. I need to be able to manually clear this buffer after the application is restarted. This doesn't seem to be a perfect solution as there is still data in the endpoint buffer when the application starts reading. Please let me know if there is any way to fully solve this problem.

fallow birchBOT
fallow birchBOT
fallow birchBOT
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
fallow birchBOT
fallow birchBOT
#
[hathach/tinyusb] New branch created: fifo_read_epsize
#

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 .data .bss size % diff
tusb.c 420 ➙ 418 (-2) 361 ➙ 360 (-1) 3 421 ➙ 420 (-...
fallow birchBOT
#

Operating System

Windows 11

Commit SHA

from eed294f to master

Board

ch32v307v_r1_1v0

Firmware

Test code examples/device/audio_test

Caused commit https://github.com/hathach/tinyusb/commit/eed294fbb58257f56b0fb59284624e50f43fa8a4

What happened ?

The audio was intermittently set to near 0.

This wasn't just limited to the mic test; the same applied to the speaker.

This issue persists e...

fallow birchBOT
fallow birchBOT
fallow birchBOT
#

Operating System

Linux

Commit SHA

ALL

Board

STM32N6

Firmware

tinyusb/src/portable/synopsys/dwc2/dwc2_stm32.h

What happened ?

When I tried to open DMA, this error occurred. The specific code is:

static mem_region_t uncached_regions[] = {
  // DTCM (although USB DMA can't transfer to/from DTCM)
#if CFG_TUSB_MCU == OPT_MCU_STM32H7
  {.start = 0x20000000, .end = 0x2001FFFF},
#elif CFG_TUSB_MCU == OPT_MCU_STM32H7RS
  // DTCM (although USB DMA can't transfer to/f...
fallow birchBOT
#

Operating System

Others

Commit SHA

f6a77b87f04386ea27effb7c1faf8e1a33da0fa1

Board

RP2040

Firmware

based on examples/device/mtp/ , nothing special in fact

What happened ?

Some two weeks or so ago, I posted #3400 including a fix which was based on my lack of understanding how USB transfers work. The problem I was observing, that the condition setting is_complete=true in mtpd_xfer_cb() would never be met a case where I sent 64 bytes of mtp payload, leading to a...

fallow birchBOT
fallow birchBOT
#

These new function variants allows the main application loop to limit how much time is spend on these functions, to ensure that other critical code can run fast enough.

Describe the PR
An application main loop (without os) that usually tinyusb host and device stack look like:

      while(1) { // the mainloop
        application_code();
        tud_task(); // tinyusb device task
        tuh_task(); // tinyusb host task
      }

Unfortunately, without patching, tud_t...

#

I think this is just a poor man's solution, the number of events per cycle is not directly proportional to how long tud_task will run.

It might be a poor man's solution, but it still is a solution to a real problem.

For your MSC case the long latency is due to disk IO in blocked callback functions. The right way is using RTOS + non-blocking asynconous IO like cdc_msc_freertos example.

Well, in my c...

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
#

Operating System

MacOS

Commit SHA

3af1bec

Board

Custom STM32H747 board

Firmware

Custom firmware

What happened ?

When debugging my firmware (which uses tinyusb) by stopping on breakpoints on doing step-by-step, I will very quickly end up in the TU_LOG_USBD("FAILED\r\n"); TU_BREAKPOINT(); code at the end of usbd_edpt_xfer() and it's impossible to continue/recover.

What I believe is happening is that:

  1. the host detects that the device is "stuck" (because of d...
fallow birchBOT
fallow birchBOT
#

What you mean it's can't be continued ? You just need to step over the breakpoint

Well, I'm using the STM32CubeIDE and I just stay on this line (step over, step into, continue) nothing work. I might be doing something wrong, but no idea what.

Well that's strange, what about changing breakpoint number in the assembly macro?

I tried with { __asm("BKPT #1\n"); } no difference. Once I reach this opcode, I cannot go further.

You can remove TU_BREAKPOINT();

Ok, I wil...

fallow birchBOT
fallow birchBOT
#

Operating System

Linux

Commit SHA

Release V0.20

Board

STM32N647

Firmware

tinyusb/src/portable/synopsys/dwc2/dwc2_common.c
tinyusb/src/portable/synopsys/dwc2/dwc2_stm32.h

What happened ?

I attempted to use the STM32N647 development board to implement the Device mode USB-CDC. However, when I used the following macros, the USB-OTG peripheral of the STM32N647 could not function properly.

#ifndef TUSB_CONFIG_H_
#define TUSB_CONFIG_H_

#ifdef __cplusplus
extern "C...
fallow birchBOT
fallow birchBOT
#

Operating System

Linux

Commit SHA

3af1bec

Board

Custom stm32h747 board

Firmware

Custom stm32h747 board, but the problematic code is very similar to net_lwip_webserver with NCM config.
Alpine Linux 3.23 on the host side.

What happened ?

When the system run for the first time, everything is fine.

Configuration:

#define CFG_TUD_NCM_IN_NTB_N		2
#define CFG_TUD_NCM_IN_NTB_MAX_SIZE	2048
#define CFG_TUD_NCM_OUT_NTB_N		2
#define CFG_TUD_NCM_OUT_NTB_MAX_SIZE	2048

...

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

I am using HS USB and set CFG_TUD_CDC_EP_BUFSIZE to 512. And it solves my problem. Will discuss your PR #3424 with my colleague.

Any plans on this? On Windows C# App it is not possible to send ZLP packet. Help needed on the TinyUSB side.

tud_cdc_wait_for_zlp(bool)

Just set CFG_TUD_CDC_EP_BUFSIZE=64

Since I am using HS USB, i set CFG_TUD_CDC_EP_BUFSIZE to 512. And it solves my problem. Will discuss your PR #3424 with my colleague later on.