Files
tinyusb/examples/device/cdc_msc
hathach 12a507f507 Enable 4-packet bursts on CH569 SuperSpeed bulk endpoints
- Default CFG_TUD_WCH_USB30_MAX_BURST to 4 (tusb_mcu.h): matches the
  link layer's header-packet buffer count (NUM_HP_BUF). Burst 8 fails
  to configure; the TeenyUSB-reported burst corruption quirk did not
  reproduce with per-burst DMA re-arm (50x MSC write/read-back and
  256KB CDC echo integrity all clean at burst 4)
- Bounce slots stay one max packet regardless of burst (bounced
  transfers cap their burst to the slot; zero-copy uses the full burst)
  so the RAMX pool no longer scales with burst size
- cdc_msc/cdc_msc_throughput SS descriptors advertise
  bMaxBurst = CFG_TUD_WCH_USB30_MAX_BURST-1 via the
  CFG_EXAMPLE_SS_BULK_MAXBURST knob (0 for non-WCH SuperSpeed ports)

Measured on HydraUSB3 v1 at 5 Gbps (HIL cdc_msc_throughput): MSC read
147 MBps write 127 MBps - about 2x the single-packet figures (raw dd:
up to 163 MB/s read at 1M blocks).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-07 12:28:45 +07:00
..

CDC + MSC

A composite USB device that exposes two interfaces at once:

  • CDC — a virtual serial port (/dev/ttyACMx, or a COM port on Windows) that echoes back everything it receives.
  • MSC — a small mass-storage disk that mounts as a removable drive.

This is the canonical TinyUSB example for a multi-interface (composite) device.

What it does

  • CDC: reads incoming data and echoes it straight back. Pressing the on-board button sends a serial-state (UART) notification to the host.
  • MSC: presents an 8 KB FAT12 RAM disk (16 × 512-byte blocks — the smallest size Windows will mount) labelled TinyUSB MSC, containing a single README.TXT. The disk lives in RAM, so changes are not persistent.
  • LED shows bus state: 250 ms blink = not mounted, 1000 ms = mounted, 2500 ms = suspended.

USB Descriptors

Interface Class driver
01 CDC (virtual serial)
2 MSC (mass storage)

Configuration

Notable tusb_config.h settings:

#define CFG_TUD_CDC              1
#define CFG_TUD_MSC              1
#define CFG_TUD_CDC_RX_BUFSIZE   (TUD_OPT_HIGH_SPEED ? 512 : 64)
#define CFG_TUD_CDC_TX_BUFSIZE   (TUD_OPT_HIGH_SPEED ? 512 : 64)
#define CFG_TUD_MSC_EP_BUFSIZE   512

Building

CMake:

mkdir build && cd build
cmake -DBOARD=raspberry_pi_pico ..
cmake --build .

Make:

make BOARD=raspberry_pi_pico all

FreeRTOS variant

A FreeRTOS build is in examples/device/cdc_msc_freertos — identical CDC + MSC behavior, with the device, CDC, and LED-blink work split across FreeRTOS tasks.

Try it

  • Serial: open the CDC port (screen /dev/ttyACM0, PuTTY, …) and type — characters are echoed back.
  • Storage: a small TinyUSB MSC drive appears; open README.TXT to confirm it mounted.