Skip to content

Commit 3e0da82

Browse files
authored
Merge pull request #577 from adafruit/fix-warning-tusb-init
Fix tusb init warning, add AGENTS.md
2 parents e84b9bb + b69d1f0 commit 3e0da82

8 files changed

Lines changed: 162 additions & 6 deletions

File tree

AGENTS.md

Lines changed: 131 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,131 @@
1+
# AGENTS.md
2+
3+
This file provides guidance to AI coding agents when working with code in this repository.
4+
5+
## Project Overview
6+
7+
Adafruit TinyUSB Arduino — an Arduino library wrapping the [TinyUSB](https://github.com/hathach/tinyusb) USB stack. Provides Arduino-friendly classes for USB device and host functionality across multiple MCU families (nRF52, SAMD, ESP32, RP2040, CH32, STM32).
8+
9+
## Build Commands
10+
11+
This is an Arduino library — there is no standalone build. It compiles as part of Arduino sketches via `arduino-cli`.
12+
13+
**Install library dependencies:**
14+
```bash
15+
arduino-cli lib install "Adafruit SPIFlash" "Adafruit seesaw Library" "Adafruit NeoPixel" "Adafruit Circuit Playground" "Adafruit InternalFlash" "SdFat - Adafruit Fork" "SD" "MIDI Library" "Pico PIO USB"
16+
```
17+
18+
**Build a single sketch** (one representative board per platform):
19+
```bash
20+
# nRF52840
21+
arduino-cli compile --warnings all --fqbn adafruit:nrf52:feather52840:softdevice=s140v6,debug=l0 path/to/sketch
22+
23+
# SAMD21 (M0)
24+
arduino-cli compile --warnings all --fqbn adafruit:samd:adafruit_metro_m0:usbstack=tinyusb path/to/sketch
25+
26+
# SAMD51 (M4)
27+
arduino-cli compile --warnings all --fqbn adafruit:samd:adafruit_metro_m4:usbstack=tinyusb path/to/sketch
28+
29+
# RP2040
30+
arduino-cli compile --warnings all --fqbn rp2040:rp2040:adafruit_feather:usbstack=tinyusb path/to/sketch
31+
32+
# ESP32-S3
33+
arduino-cli compile --warnings all --fqbn esp32:esp32:adafruit_feather_esp32s3 path/to/sketch
34+
35+
# ESP32-P4
36+
arduino-cli compile --warnings all --fqbn espressif:esp32:esp32p4 path/to/sketch
37+
38+
# CH32V20x
39+
arduino-cli compile --warnings all --fqbn WCH:ch32v:CH32V20x_EVT path/to/sketch
40+
```
41+
42+
**CI builds** use [adafruit/ci-arduino](https://github.com/adafruit/ci-arduino) scripts:
43+
```bash
44+
# Build for a specific platform (requires ci-arduino checked out to ./ci)
45+
python3 ci/build_platform.py <platform>
46+
```
47+
48+
**CI platform matrix**: `feather_esp32_v2`, `feather_esp32s2`, `feather_esp32s3`, `esp32p4`, `cpb`, `nrf52840`, `feather_rp2040_tinyusb`, `pico_rp2040_tinyusb_host`, `metro_m0_tinyusb`, `metro_m4_tinyusb`, `CH32V20x_EVT`
49+
50+
**PlatformIO**: `platformio.ini` has environment definitions for all supported boards. Build with `pio run -e <env>`.
51+
52+
## Code Quality
53+
54+
**Pre-commit hooks** (`.pre-commit-config.yaml`):
55+
```bash
56+
pre-commit run --all-files
57+
```
58+
- **clang-format** (v15): applies only to `src/arduino/` code. The vendored TinyUSB core directories (`src/class/`, `src/common/`, `src/device/`, `src/host/`, `src/osal/`, `src/portable/`, `src/tusb.c`, `src/tusb.h`, `src/tusb_option.h`) are excluded.
59+
- **codespell**: spell checking with ignore list in `.codespell/`
60+
61+
## Architecture
62+
63+
### Layer Diagram
64+
```
65+
User Sketch → Adafruit_TinyUSB.h
66+
67+
┌─────────────┼─────────────┐
68+
▼ ▼ ▼
69+
USBD_Device USBD_* classes USBH_Host
70+
(descriptor (CDC, HID, (host mode
71+
management) MSC, MIDI, manager)
72+
Video, WebUSB)
73+
│ │ │
74+
▼ ▼ ▼
75+
TinyUSB Stack (tusb.h / tusb.c)
76+
77+
78+
Port Layer (src/arduino/ports/<mcu>/)
79+
80+
81+
Portable Drivers (src/portable/<vendor>/)
82+
```
83+
84+
### Key Source Directories
85+
86+
- **`src/arduino/`** — Arduino abstraction layer (the code this project maintains)
87+
- `Adafruit_USBD_Device.*` — USB device manager, descriptor building, endpoint allocation
88+
- `Adafruit_USBD_CDC.*` — CDC serial (replaces Arduino `Serial` on supported cores)
89+
- `Adafruit_USBD_Interface.*` — Base class for all USB interfaces
90+
- `Adafruit_USBH_Host.*` — USB host stack manager
91+
- `hid/`, `msc/`, `midi/`, `video/`, `webusb/`, `cdc/` — class-specific wrappers
92+
- `ports/` — MCU-specific port implementations (nrf, samd, esp32, rp2040, ch32, stm32)
93+
94+
- **`src/class/`, `src/device/`, `src/host/`, `src/common/`, `src/portable/`, `src/osal/`** — Vendored TinyUSB core. Do NOT apply clang-format to these.
95+
96+
### Updating Vendored TinyUSB Core
97+
98+
When syncing `src/` from upstream [hathach/tinyusb](https://github.com/hathach/tinyusb), most files are copied as-is. However, **`src/tusb_option.h`** has an Arduino-specific patch that must be preserved. After copying the upstream version, re-add the following block (around line 265, inside the MCU detection `#elif` chain):
99+
100+
```c
101+
#elif defined(ARDUINO_ARCH_ESP32)
102+
// ESP32 out-of-sync
103+
#include "arduino/ports/esp32/tusb_config_esp32.h"
104+
```
105+
106+
This is needed because the ESP32 Arduino core bundles an older TinyUSB version, so the config must be force-included here rather than relying on the core's copy.
107+
108+
### Port Implementation Contract
109+
110+
Each MCU port in `src/arduino/ports/<mcu>/` must implement:
111+
- `TinyUSB_Port_InitDevice()` — initialize USB hardware
112+
- `TinyUSB_Port_EnterDFU()` — enter bootloader (1200 baud touch)
113+
- `TinyUSB_Port_GetSerialNumber()` — return unique device serial
114+
115+
### Core Integration Modes
116+
117+
- **Built-in support** (nRF52, SAMD, RP2040, ESP32, CH32): the Arduino core calls `TinyUSB_Device_Init()`, `TinyUSB_Device_Task()`, `TinyUSB_Device_FlushCDC()` automatically. Macro `USE_TINYUSB` is defined.
118+
- **Non-built-in** (STM32, mbed_rp2040): sketches must call these functions explicitly. Macro `TINYUSB_NEED_POLLING_TASK` is set.
119+
120+
### Configuration
121+
122+
- `src/tusb_config.h` — dispatches to per-MCU config (`tusb_config_<mcu>.h`)
123+
- Per-class enable macros: `CFG_TUD_CDC`, `CFG_TUD_HID`, `CFG_TUD_MSC`, etc.
124+
- `CFG_TUD_ENABLED` / `CFG_TUH_ENABLED` — device/host stack toggles
125+
126+
### Examples
127+
128+
40+ examples organized by USB class in `examples/`:
129+
`CDC/`, `HID/`, `MassStorage/`, `MIDI/`, `WebUSB/`, `Video/`, `Vendor/`, `Composite/`, `DualRole/`, `Host/`
130+
131+
Board-specific test filtering uses `.test.only` files within example directories.
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
11
feather_esp32_v2
22
pico_rp2040_tinyusb_host
33
CH32V20x_EVT
4+
metro_m0_tinyusb

src/arduino/Adafruit_USBH_Host.cpp

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -137,7 +137,11 @@ bool Adafruit_USBH_Host::begin(uint8_t rhport) {
137137
#endif
138138

139139
_rhport = rhport;
140-
return tuh_init(rhport);
140+
const tusb_rhport_init_t rh_init = {
141+
.role = TUSB_ROLE_HOST,
142+
.speed = TUH_OPT_HIGH_SPEED ? TUSB_SPEED_HIGH : TUSB_SPEED_FULL,
143+
};
144+
return tusb_init(rhport, &rh_init);
141145
}
142146

143147
void Adafruit_USBH_Host::task(uint32_t timeout_ms, bool in_isr) {

src/arduino/ports/ch32/Adafruit_TinyUSB_ch32.cpp

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -163,7 +163,11 @@ void TinyUSB_Port_InitDevice(uint8_t rhport) {
163163
RCC_AHBPeriphClockCmd(RCC_AHBPeriph_USBHS, ENABLE);
164164
#endif
165165

166-
tud_init(rhport);
166+
const tusb_rhport_init_t rh_init = {
167+
.role = TUSB_ROLE_DEVICE,
168+
.speed = TUD_OPT_HIGH_SPEED ? TUSB_SPEED_HIGH : TUSB_SPEED_FULL,
169+
};
170+
tusb_init(rhport, &rh_init);
167171
}
168172

169173
void TinyUSB_Port_EnterDFU(void) {

src/arduino/ports/nrf/Adafruit_TinyUSB_nrf.cpp

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -69,7 +69,11 @@ static void usb_device_task(void *param) {
6969
NVIC_SetPriority(USBD_IRQn, 2);
7070

7171
// init device on rhport0
72-
tud_init(0);
72+
const tusb_rhport_init_t rh_init = {
73+
.role = TUSB_ROLE_DEVICE,
74+
.speed = TUD_OPT_HIGH_SPEED ? TUSB_SPEED_HIGH : TUSB_SPEED_FULL,
75+
};
76+
tusb_init(0, &rh_init);
7377

7478
usb_hardware_init();
7579

src/arduino/ports/rp2040/Adafruit_TinyUSB_rp2040.cpp

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -98,7 +98,11 @@ static void usb_task_trigger_irq(void) { irq_set_pending(USB_TASK_IRQ); }
9898
void TinyUSB_Port_InitDevice(uint8_t rhport) {
9999
mutex_init(&__usb_mutex);
100100

101-
tud_init(rhport);
101+
const tusb_rhport_init_t rh_init = {
102+
.role = TUSB_ROLE_DEVICE,
103+
.speed = TUSB_SPEED_FULL,
104+
};
105+
tusb_init(rhport, &rh_init);
102106

103107
// soft irq for task runner
104108
#if (PICO_SDK_VERSION_MAJOR * 100 + PICO_SDK_VERSION_MINOR) >= 104

src/arduino/ports/samd/Adafruit_TinyUSB_samd.cpp

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -113,7 +113,11 @@ void TinyUSB_Port_InitDevice(uint8_t rhport) {
113113
#endif
114114

115115
// Init port 0 as device
116-
tud_init(0);
116+
const tusb_rhport_init_t rh_init = {
117+
.role = TUSB_ROLE_DEVICE,
118+
.speed = TUSB_SPEED_FULL,
119+
};
120+
tusb_init(0, &rh_init);
117121
}
118122

119123
void TinyUSB_Port_EnterDFU(void) {

src/arduino/ports/stm32/Adafruit_TinyUSB_stm32.cpp

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -80,7 +80,11 @@ void TinyUSB_Port_InitDevice(uint8_t rhport) {
8080
USB_OTG_FS->GCCFG &= ~USB_OTG_GCCFG_VBUSASEN;
8181

8282
// Initialize TinyUSB device stack
83-
tud_init(rhport);
83+
const tusb_rhport_init_t rh_init = {
84+
.role = TUSB_ROLE_DEVICE,
85+
.speed = TUD_OPT_HIGH_SPEED ? TUSB_SPEED_HIGH : TUSB_SPEED_FULL,
86+
};
87+
tusb_init(rhport, &rh_init);
8488
}
8589

8690
void TinyUSB_Port_EnterDFU(void) {

0 commit comments

Comments
 (0)