The official starting point for building RP2350 apps for the dadamachines TBD-16 audio DSP platform.
This template provides the core libraries and project structure for creating custom instruments, effects, sequencers, and utilities that run on the TBD-16's RP2350 co-processor — communicating with the ESP32-P4 DSP engine over SPI.
The RP2350 controls the TBD-16's user interface and MIDI I/O. Your app has full access to:
- 50+ DSP plugins on the ESP32-P4 via the SPI command API
- OLED display (SSD1309, 128×64, software SPI via PIO)
- NeoPixel LED strip (PIO-driven)
- Rotary encoders and buttons (via I2C polling of STM32F0)
- USB MIDI host (connect controllers like Arturia BeatStep Pro)
- UART MIDI (TRS MIDI in/out × 2)
- 8 MB PSRAM and SD card (SDIO)
- PlatformIO (recommended) or Arduino CLI
- TBD-16 hardware
# Clone this repo (or fork it for your own app)
git clone https://github.com/dadamachines/dada-tbd-app-template.git
cd dada-tbd-app-template
# Build
pio run -e pi2350
# Flash — enter BOOTSEL mode (hold right front button while connecting USB-C port #2)
pio run -e pi2350 -t uploadThe .uf2 output lands in .pio/build/pi2350/firmware.uf2. You can also drag-and-drop this file onto the RP2350 USB drive in BOOTSEL mode.
src/
├── Midi.cpp/.h USB + UART MIDI host and routing
├── MidiParser.cpp/.h MIDI-to-SPI parameter mapping
├── MidiRunningStatusExpander.h Running status → full messages
├── SpiAPI.cpp/.h SPI command API to ESP32-P4
├── Ui.cpp/.h OLED display, LEDs, encoders, buttons
├── DadaLogo.h Boot logo bitmap
├── Fonts/ OLED font data
└── src.ino Arduino entry point
examples/
└── main.cpp Example: load plugins, map MIDI, SPI API demos
platformio.ini PlatformIO build configuration
pinmap.md Full GPIO pin assignments
architecture.png System architecture diagram
Dockerfile Reproducible CI build environment
The TBD-16 has two processors connected via dual SPI buses:
| Bus | Speed | Purpose |
|---|---|---|
| SPI1 (real-time) | 30 MHz, ~1378 Hz | MIDI/CV/trigger data to DSP, audio levels + USB MIDI back |
| SPI0 (command) | 30 MHz, on-demand | Plugin loading, parameter changes, preset management |
Both use 512-byte frames. See SpiAPI.h for the full command reference and pinmap.md for GPIO assignments.
| Class | Purpose |
|---|---|
SpiAPI |
Send commands to the P4 DSP engine — load plugins, read/write parameters, manage presets, send files |
Midi |
Initialize USB host + UART MIDI, route messages, manage USB power and mux GPIOs |
MidiParser |
Map parsed MIDI events (notes, CCs) to SPI real-time control data for the DSP |
Ui |
Drive the OLED display, NeoPixel strip, and poll encoders/buttons via I2C |
The examples/main.cpp file demonstrates:
- Real-time CV/Trigger API — send control data directly to plugins without the MIDI parser
- Load and map plugins — load a DrumRack plugin and map note-ons to triggers
- SPI API tests — exercise the command API (plugin state, parameters, presets)
To explore, look at Ui::Init() and Ui::Update() for the call sites.
- SPI1 — Real-time audio control at 44100/32 Hz (~1378 Hz). RP2350 sends MIDI/CV data, P4 returns USB MIDI device data and audio level indicators.
- SPI0 — On-demand command API for plugin management, parameter changes, preset storage, file transfers.
- OLED — Software SPI via PIO (SSD1309, 128×64).
- NeoPixel — PIO-driven LED strip.
- USB Host — USB MIDI controllers. Requires GPIO-controlled power and USB mux enable (see
Midi::Init()). - UART — Two MIDI I/O ports (TRS connectors).
- I2C — Polls STM32F0 for encoder positions and button states.
- Fork this repo on GitHub
- Modify
src/— add your instrument logic, UI pages, MIDI mappings - Build with
pio run -e pi2350 - Flash via BOOTSEL or copy
.uf2to the Pico SD card (multi-app mode)
You can also use any RP2350 toolchain (Arduino IDE, Pico SDK, Rust) — the SPI protocol is documented in SpiAPI.h.
To share your app with the TBD community:
- Create a GitHub Release with your
.uf2attached - Open a PR to dada-tbd-firmware adding a manifest under
apps/your-app/manifest.json - CI validates your manifest and binary — dadamachines reviews and merges
- Your app appears in the App Manager catalog
This is optional — sideloading works without any registration.
Managed automatically by PlatformIO:
| Library | Source |
|---|---|
| Adafruit GFX | adafruit/Adafruit GFX Library@^1.12.1 |
| Adafruit NeoPixel | adafruit/Adafruit NeoPixel@^1.12.4 |
| ArduinoJson | ArduinoJson@^7.4.2 |
| TinyUSB (USB host fork) | ctag-fh-kiel/Adafruit_TinyUSB_Arduino#fix/usb_host_arturia_bspro |
| USB MIDI Host | rppicomidi/usb_midi_host#1.1.4 |
| DaDa OLED | ctag-fh-kiel/DaDa_OLED#v1.0.0 |
| DaDa SPI | ctag-fh-kiel/DaDa_SPI#v1.0.5 |
If you prefer Arduino CLI over PlatformIO, you'll need to manually install the dependencies listed above, then:
cd src
arduino-cli compile \
--fqbn rp2040:rp2040:generic_rp2350:variantchip=RP2530B,usbstack=tinyusb_host \
--build-path ./buildFlash with cp build/src.uf2 /Volumes/RP2350.
Uncomment the debug lines in platformio.ini to use a CMSIS-DAP debugger (e.g. Pico Debug Probe):
debug_tool = cmsis-dap
upload_protocol = cmsis-dapThis repo contains several branches, each with a different firmware variant:
The default branch. A full Arduino-framework template for building custom TBD-16 apps with OLED UI, MIDI, NeoPixels, and the SPI command API to the ESP32-P4 DSP engine. See the rest of this README for details.
Flash-targeted USB Mass Storage firmware with OLED status display. Exposes the TBD-16's SD card as a USB drive for file management.
- Framework: Arduino (earlephilhower core) + Adafruit TinyUSB + SdFat
- Binary type: Standard flash (UF2 addresses
0x10000000+) - OLED: PIO SPI via DaDa_OLED / Adafruit GFX — shows mount/ready/eject status
- Flash via: Picoboot WebUSB (App Manager) or drag-and-drop in BOOTSEL mode
- Build:
pio run -e pi2350 - CDN: Published as
tusb-msc-pico(flash target)
RAM-targeted USB Mass Storage firmware with OLED status display. Same functionality as feature/tusb-msc-flash but designed to be loaded by the SD card bootloader at runtime.
- Framework: Pico SDK (raw C) + TinyUSB + no-OS-FatFS (SDIO PIO)
- Binary type:
no_flash(UF2 addresses0x20000000+, requires-DPICO_NO_FLASH=1) - OLED: Hardware SPI1 via lcdspi library — shows mount/ready/eject status
- Flash via: Copy
tusb_msc.uf2to SD cardtbd-apps/folder (multi-app bootloader) - Build:
pio run -e pi2350 - CDN: Published as
tusb-msc-pico(RAM target)
Erases the entire RP2350 flash chip. Compatible with Picoboot WebUSB flashing.
- Framework: Pico SDK (raw C)
- Binary type:
copy_to_ram(UF2 addresses0x10000000+, CRT0 copies to RAM before executing) - Flash via: Picoboot WebUSB (App Manager) or drag-and-drop in BOOTSEL mode
- Build:
pio run -e pi2350 - CDN: Published as
flash-nuke
- dadamachines Forum — Ask questions, share apps, connect with other TBD developers
- GitHub Issues — Bug reports and feature requests
- TBD-16 Documentation — Full platform docs, plugin reference, flashing guides
The TBD platform and SPI API were created by Robert Manzke at the Creative Technologies AG, Kiel University of Applied Sciences.
The TBD-16 adaptation is led by dadamachines.
This repository is licensed under the GNU General Public License, version 3 only (GPL-3.0-only), as the CTAG TBD source headers state; the full text is in COPYING.
An app that includes or links the template's code (SpiAPI, Midi, MidiParser, Ui and related headers) and is distributed must be released under GPL-3.0 as well; for other terms, dadamachines can provide a commercial license. An earlier version of this README and of LICENSE named the LGPL 3.0 by mistake.
See LICENSE for the full details, including trademark and commercial use terms.