Integrating TinyUSB¶
Once you’ve seen TinyUSB working in the examples, use this guide to wire the stack into your own firmware.
Integration Steps¶
Get TinyUSB: Copy this repository or add it as a git submodule to your project at
your_project/tinyusb.Add source files: Add every
.cfile fromtinyusb/src/to your project build system.
Note
Only supported dcd/hcd drivers for your CPU sources under tinyusb/src/portable/vendor/usbip/ are needed. Add
Configure TinyUSB: Create
tusb_config.hwith macros such asCFG_TUSB_MCU,CFG_TUSB_OS, and class enable flags. Start from any example’stusb_config.hand tweak.Configure include paths: Add
your_project/tinyusb/src(and the folder holdingtusb_config.h) to your include paths.Implement USB descriptors: For device stack, implement the
tud_descriptor_*_cb()callbacks (device) or host descriptor helpers that match your product.Initialize TinyUSB: Call
tusb_init()once the clocks/peripherals are ready. Passtusb_rhport_init_tif you need per-port settings.Handle interrupts: From the USB ISR call
tusb_int_handler(rhport, true)so the stack can process events.Run USB tasks: Call
tud_task()(device) ortuh_task()(host) regularly from the main loop, RTOS task.Implement class callbacks: Provide the callbacks for the classes you enabled (e.g.,
tud_cdc_rx_cb(),tuh_msc_mount_cb()).
Minimal Example¶
#include "tusb.h"
int main(void) {
board_init(); // Your board initialization
// Init device stack on roothub port 0 for highspeed device
tusb_rhport_init_t dev_init = {
.role = TUSB_ROLE_DEVICE,
.speed = TUSB_SPEED_HIGH
};
tusb_init(0, &dev_init);
// init host stack on roothub port 1 for fullspeed host
tusb_rhport_init_t host_init = {
.role = TUSB_ROLE_DEVICE,
.speed = TUSB_SPEED_FULL
};
tusb_init(1, &host_init);
while (1) {
tud_task(); // device task
tuh_task(); // host task
app_task(); // Your application logic
}
}
void USB0_IRQHandler(void) {
// forward interrupt port 0 to TinyUSB stack
tusb_int_handler(0, true);
}
void USB1_IRQHandler(void) {
// forward interrupt port 0 to TinyUSB stack
tusb_int_handler(1, true);
}
Note
Unlike many libraries, TinyUSB callbacks don’t need to be registered. Implement functions with the prescribed names (for example tud_cdc_rx_cb()) and the stack will invoke them automatically.
Note
Naming follows tud_* for device APIs and tuh_* for host APIs. Refer to Glossary for a summary of the prefixes and callback naming rules.
STM32CubeIDE Integration¶
To integrate TinyUSB device stack with STM32CubeIDE
In STM32CubeMX, enable USB_OTG_FS/HS under Connectivity, set to “Device_Only” mode
Enable the USB global interrupt in NVIC Settings
Add
tusb.hinclude and calltusb_init()in main.cCall
tud_task()in your main loopIn the generated
stm32xxx_it.c, modify the USB IRQ handler to calltud_int_handler(0)
void OTG_FS_IRQHandler(void) {
tud_int_handler(0);
}
Create
tusb_config.handusb_descriptors.cfiles
Tip
STM32CubeIDE generated code conflicts with TinyUSB. Don’t use STM32’s built-in USB middleware (USB Device Library) when using TinyUSB. Disable USB code generation in STM32CubeMX and let TinyUSB handle all USB functionality.