README.md

April 15, 2026 · View on GitHub

PicoADK Firmware Template

build boards freertos license

PicoADK is the audio dev kit for the Raspberry Pi RP2040 (v1) and RP2350 (v2). This template is the firmware starting point: a clean HAL on top of the Pico SDK that hides the silicon differences (FPU, PSRAM, SDIO, M33 DSP intrinsics) so the same audio callback runs on both boards without #ifdefs. Drop in your DSP, pick from a tray of ready-made examples, build either board with one command.

Quickstart

git clone --recursive https://github.com/DatanoiseTV/PicoADK-Firmware-Template
cd PicoADK-Firmware-Template
cmake --preset v2                        # or v1
cmake --build build/v2

The UF2 lands in build/v2/app/picoadk_app.uf2. Hold BOOTSEL, plug in the board, drag-drop. You're running.

#include "picoadk/picoadk.h"
#include <FreeRTOS.h>
#include <task.h>

using namespace picoadk;

void audio(const float* const* /*in*/, float* const* out, std::size_t n, void*) {
    for (std::size_t i = 0; i < n; ++i)
        out[0][i] = out[1][i] = std::sin(2.0f * 3.14159f * 440.0f * i / 48000.0f);
}

int main() {
    HardwareConfig hw;
    hw.audio.sample_rate_hz = 48000;
    hw.midi.inputs          = MidiTransport::Usb | MidiTransport::Uart;
    Hardware::init(hw);
    Audio::set_callback(audio);
    Audio::start();
    vTaskStartScheduler();
}

Boots, plays a 440 Hz sine, accepts MIDI on USB and DIN. That's the whole program.

What's in the box

Audio engine with runtime-configurable sample rate (8 k–192 k), bit depth (16/24/32), block size, direction (out · in · full duplex), and frame format (I²S · left/right justified · TDM4 · TDM8). PIO + DMA, off-IRQ FreeRTOS audio task.

MIDI over USB device, UART (5-pin DIN), and USB host (Launchpad / keyboards via pico_pio_usb) — all three simultaneously through one callback set. NRPN/RPN aggregation, 14-bit pitch bend, MIDI clock, channel-mode messages.

USB composite assembled at runtime — CDC serial debug, USB-MIDI (multi-cable), and MSC exposing internal flash and/or the SD card as separate LUNs. Mix and match.

DSP toolkit. dsp::Real is float on RP2350 (FPU) and Q16 fixed-point on RP2040; same code compiles for both. Module library: BLEP / wavetable / noise oscillators, ADSR, state-variable + ladder filters, saturator, wavefolder, delay (PSRAM-backed), 8-line FDN reverb (PSRAM-backed), compressor.

Sampler — memory-resident or SD-streaming WAV (16/24/32-bit), pitch shift, looping, multisample keymap; SoundFont 2 via TinySoundFont (multisample/loop/release/modulators); embedded SFZ subset parser that builds streaming sources per region. Per-source 4096-frame prefetch ring keeps SD seeks at note-on time only.

PSRAM — TLSF allocator over the v2's 8 MB QSPI PSRAM. Linker section macros (PICOADK_PSRAM_BSS/_DATA), placement-new (PSRAM). Falls back to the system heap on v1 so portable code Just Works.

Storage — SdFat with FAT32 / exFAT / long file names. SDIO 4-bit on v2 (rabbitholecomputing/SDIO_RP2350), SPI on v1.

Display via u8g2 — SSD1306 / SH1106 / SSD1309 over I²C or SPI, full font catalog, gfx::Canvas C++ wrapper for one-liners.

Controls toolkit — MCP3208 SPI ADC, internal SAR ADC, mux banks (CD4051 / 74HC4067), polled quadrature encoders, debounced buttons with hold + double-click.

VoiceLink — wire several PicoADKs together over a 3 Mbaud UART for distributed polyphony / voice cards. Auto-enumerated chain, per-card capacity, oldest/quietest/round-robin allocation. DMA-fed framing keeps the audio thread untouched.

PureData (optional, -DPICOADK_LIBPD=ON) — embed libpd, load patches from flash or SD, route through the audio callback.

FreeRTOS SMP on both boards via the Raspberry Pi-curated kernel fork. xTaskCreatePinnedToCore() works ESP32-style. Stdio routes to UART by default and USB-CDC when you ask for it.

Examples

What it shows
examples/00_templateCopy-and-edit scaffold — audio + MIDI + controls + USB composite already wired.
examples/01_passthroughThe minimal program — full-duplex passthrough in 25 lines.
examples/02_synth_vultOriginal PicoADK Vult monosynth, ported to v3.
examples/03_fx_rackStereo delay + Hadamard FDN reverb in parallel; pots morph time / feedback / size / mix; PSRAM-backed buffers on v2.
examples/04_multisamplerKey-mapped piano loaded from SD, 8-voice polyphony with pitch-shift to root.
examples/05_midi_controllerNo audio — pots / encoder / button forwarded as USB-MIDI CCs.
examples/06_sf2_playerSoundFont 2 / SFZ player. Drop a default.sf2 (or default.sfz) on the SD card.
cmake --preset v2 -DPICOADK_APP=examples/03_fx_rack
cmake --build build/v2

Build

PresetBoardBuild type
v1RP2040Release
v1-debugRP2040Debug
v2RP2350Release
v2-debugRP2350Debug

Useful flags:

FlagDefaultEffect
-DPICOADK_APP=<dir>examples/02_synth_vultApp folder to build.
-DPICOADK_VULT_REAL=float|fixedautoVult numeric type (float on v2, Q16 on v1).
-DPICOADK_VULT_SAMPLERATE=4800048000Sample rate baked into Vult tables.
-DPICOADK_ENABLE_SDFAT=ONOFFPull in SdFat for Storage HAL.
-DPICOADK_ENABLE_SDIO=ONOFFPull in SDIO_RP2350 (v2 only).
-DPICOADK_ENABLE_USB_HOST=ONOFFCompile the TinyUSB host stack.
-DPICOADK_LIBPD=ONOFFEmbed libpd.

VS Code: install the official Raspberry Pi Pico extension. CMakePresets.json and .vscode/ are pre-wired — pick a preset from the status bar.

Hardware

PicoADK v1PicoADK v2
MCURP2040 — dual M0+RP2350A — dual M33 + FPU + DCP
Flash4 MB QSPI4 MB QSPI
PSRAM8 MB QSPI
SDSPISDIO 4-bit
MIDI inUSB + DINUSB + DIN + USB host (PIO USB)
DisplaySSD1306 I²CSSD1306 / TFT SPI

PicoADK Hardware repo

Documentation

docs/ARCHITECTURE.mdLayered model, audio pipeline diagram, threading model, memory map, file-by-file map.
docs/HAL.mdPer-subsystem reference with code samples for every public API.
docs/OVERCLOCKING.mdVoltage ladders + System::set_clock_khz() recipe.
CHANGELOG.mdWhat changed in v3.0.0.
CONTRIBUTING.mdHouse rules + how to add a HAL subsystem / DSP module.

Pinned dependencies

pico-sdk2.2.0
pico-extrassdk-2.2.0
FreeRTOS-Kernelraspberrypi/FreeRTOS-Kernel (SMP for both boards)
pico-pio-usblatest
u8g2latest
TinySoundFontlatest
SDIO_RP2350 / SdFat / libpdfetched on demand via CMake when the matching -DPICOADK_ENABLE_… flag is on

Status

All six example apps build and link clean for both boards (verified with arm-none-eabi-gcc 14.2); CI builds both targets on every push and runs the host-side DSP unit tests (tests/, 10/10 pass). PIO timing for the new I²S/TDM/SDIO programs and PSRAM init on v2 still need real boards on the bench — the structure and call sites are in place; values that need verification are clearly marked in the source.

The legacy firmware is preserved on the RP235x* branches and on tags. Nothing was removed from there.


BSD-3-Clause · for people who like their synths to sound exactly like they wanted