Refresh BOM (2026-07-09 CSV), Gerbers, EasyEDA project, pick-and-place, and schematic export; document corrected ADAU crystal/PLL strapping and Si4684 reference clock in the manual; add PCBWay acknowledgement on the back cover only. Co-authored-by: Cursor <cursoragent@cursor.com>
DigiRadio
DAB+/FM Bluetooth Receiver with SigmaDSP Audio Processing
Open-source digital radio — Si4684 tuner · ADAU1701 SigmaDSP · Bluetooth aptX Adaptive · ESP32-S3
Overview
DigiRadio is an open-source digital radio receiver that combines terrestrial broadcast reception (DAB+ / DAB / FM) with a programmable audio-processing stage and high-quality Bluetooth audio output.
Incoming broadcast audio is decoded by a Silicon Labs Si4684 digital-radio receiver, processed by an Analog Devices ADAU1701 SigmaDSP (equalisation, mixing, level control), and transmitted over Bluetooth by a Qualcomm QCC3056-based Feasycom FSC-BT1035 module supporting the aptX Adaptive codec. An Espressif ESP32-S3 acts as the host controller, orchestrating the three subsystems and providing Wi-Fi connectivity, encrypted credential storage, and a browser-based configuration UI.
The entire tuner → DSP → Bluetooth path is fully digital (I²S, 48 kHz / 24-bit) — no analogue conversions are introduced between the tuner and the wireless link.
FM/DAB antenna → [ Si4684 ] --I²S--> [ ADAU1701 DSP ] --I²S--> [ FSC-BT1035 ] → aptX
↑ ↑ ↑
└──── SPI ──── [ ESP32-S3 host ] ──── UART ────┘
│ I²C
Wi-Fi · NVS · HTTP UI
Key Features
Hardware
- DAB+ / DAB / FM reception (Si4684) via external whip antenna (SMA)
- Fully digital audio path — no avoidable A/D–D/A conversions
- Programmable audio processing on the ADAU1701 SigmaDSP
- Bluetooth 5.2 output with aptX / aptX HD / aptX Adaptive
- ESP32-S3 host with native USB, Wi-Fi and BLE
- USB-C powered; single-rail 3.3 V + low-noise 1.8 V for the tuner
- 6-layer impedance-controlled PCB, 50 × 90 mm, two ground planes
- Three antennas (ESP32 2.4 GHz, BT1035 2.4 GHz, FM/DAB SMA) with proper keep-outs
Firmware (ESP-IDF, C++23 — fw 0.8.5)
| Area | Capability |
|---|---|
| Boot & chips | Si4684 DAB+FM firmware load (HOST_LOAD blobs), ADAU1701 RAM program at every boot, BT1035 I2S slave init (AT+AUXCFG=3, AT+I2SCFG=67) |
| Tuner | FM tune/seek, DAB ensemble tune, service scan & play, RSQ/RDS, DAB event status |
| Now playing | FM RDS (PS, RadioText, PI, PTY) and DAB Dynamic Label (DLS) in status JSON and web UI |
| Audio | 6-band EQ, input mixer, stereo/bass enhancement overlays, profile persist in encrypted NVS |
| Presets | Station list CRUD, reorder, recall with audio profile re-apply, last-preset restore at boot |
| Bluetooth | Discoverable pairing, A2DP status, disconnect |
| Network | SoftAP setup mode, STA provisioning, tabbed gzipped SPA (/), typed JSON REST API |
| Security | NVS + flash encryption at rest (dev mode); keys never in repo |
| Quality | 13 host unit tests, 4 CI jobs (tests, Doxygen, manual sync, blob policy) |
Architecture follows a functional core + imperative shell: pure domain logic
(compilation, JSON, EQ design, RDS/DLS parsing) runs on the host under ctest;
drivers and FreeRTOS live in thin ESP-IDF components. See Software/AGENTS.md.
Firmware Progress
Vertical slices landed on main (newest first):
| Version | Highlights |
|---|---|
| 0.8.5 | BT1035 I2S slave boot init (schematic-aligned); I2C pull-ups R1/R16 confirmed 2 kΩ; Hardware/DATASHEET/ bundle |
| 0.8.4 | Dual OTA + DSP blob updates, EEPROM identity, System tab OTA/DSP upload |
| 0.8.3 | NVS + flash encryption (development mode), initEncryptedStorage, security docs |
| 0.8.2 | Tabbed Web UI (now-playing, 6-band EQ, all REST); Si4684 blob CI policy |
| 0.8.1 | IntegrationService — boot preset recall, tune orchestration (tuner + audio + NVS last_preset); services stub removed |
| 0.8.0 | Preset reorder API/UI; broadcast metadata (RDS + DAB DLS); readDabServiceData driver path |
| 0.7.1 | CI workflow (host tests, Doxygen, manual sync); Doxygen warnings cleared |
| 0.7.0 | Station presets (NVS station_list), BT1035 pairing, full /api/stations/* |
| 0.5–0.6 | ADAU1701 runtime EQ/mixer, Si4684 tuning & DAB service list, BT1035 driver |
| 0.3–0.4 | Secure store, Wi-Fi provisioning, companion-chip boot, walking skeleton |
Next: device HIL when the PCB arrives (Software/docs/security-flash-nvs.md,
Software/docs/TODO.md). Contributing:
CONTRIBUTING.md.
Repository Structure
DigiRadio/
├── .github/workflows/ CI — host tests, Doxygen, manual sync, Si4684 blob policy
├── Hardware/
│ ├── schematics/ Schematic (PDF)
│ ├── gerber/ Gerber + drill (fabrication)
│ ├── bom/ Bill of Materials
│ ├── pick-and-place/ CPL / centroid
│ ├── easyeda/ EasyEDA source
│ └── 3d/ Renders / STEP
├── Software/ Firmware project root — open this in Cursor
│ ├── AGENTS.md Authoritative coding rules for agents
│ ├── instructions.md Agent kickoff & slice roadmap
│ ├── Doxyfile API documentation gate
│ ├── components/
│ │ ├── core/ Pure domain (host-tested, no ESP-IDF)
│ │ ├── drivers/ Si4684, ADAU1701, BT1035
│ │ ├── services/ Tuner, audio, Bluetooth, station, integration
│ │ ├── secure_store/ NVS wrappers (Wi-Fi, profiles, presets)
│ │ └── net/ Wi-Fi, HTTP server, gzipped web UI
│ ├── docs/
│ │ ├── manual/ LaTeX technical manual (canonical)
│ │ ├── security-flash-nvs.md NVS/flash encryption + HIL checklist
│ │ └── TODO.md Agent backlog and completed tasks
│ ├── Firmware/ Si4684 blobs + ADAU1701 SigmaStudio export
│ ├── main/ app_main, hardware bootstrap
│ └── tools/ fetch_si4684_firmware, check_*, gzip-www
├── CONTRIBUTING.md human-facing dev guide
├── LICENSE CERN-OHL-S v2 (hardware)
└── README.md ← you are here
Build the manual from Software/docs/manual/:
cd Software/docs/manual && latexmk -lualatex manual.tex
Getting Started
Firmware (developers)
Open Software/ as the Cursor project so AGENTS.md and .cursor/rules/ load.
cd Software
idf.py set-target esp32s3
idf.py build
idf.py erase-flash flash # once when first enabling encryption (0.8.3+)
idf.py -p <port> monitor
Host unit tests (no hardware):
cd Software
cmake -S components/core/test -B build-host \
-DCMAKE_CXX_COMPILER="$(brew --prefix llvm)/bin/clang++" # macOS
cmake --build build-host
ctest --test-dir build-host --output-on-failure
Quality gates (also enforced in CI):
cd Software
doxygen Doxyfile
python3 tools/check-manual-sync.py
python3 tools/check_si4684_blobs.py
Full build notes: Software/README.md · security:
Software/docs/security-flash-nvs.md.
First boot (device)
- Power the board; ESP32 starts SoftAP setup mode (
DigiRadio-setup— see manual). - Connect and open the gzipped web UI or call
GET /api/health. POST /api/wifiwith STA credentials; device reboots into normal mode.- Tune via
/api/tuner/*, manage presets via/api/stations/*, pair BT via/api/bluetooth/*.
Schemas, error tokens, and boot flow: Software/docs/manual/ch-api.tex.
HTTP API (summary)
| Method | Path | Purpose |
|---|---|---|
| GET | /api/health |
Status, firmware version, companion-chip flags |
| POST | /api/wifi |
Provision STA credentials |
| GET | /api/tuner/status |
Tuner snapshot incl. RDS/DLS metadata |
| GET | /api/tuner/services |
DAB service list |
| POST | /api/tuner/tune · /play · /seek |
Tuner control |
| GET/PUT | /api/audio/profile |
ADAU1701 mixer + EQ |
| POST | /api/audio/reset · /stereo-enhance · /bass-enhance |
Audio overlays |
| GET | /api/bluetooth/status |
BT1035 state |
| POST | /api/bluetooth/pair · /pair/stop · /disconnect |
Bluetooth control |
| GET/POST | /api/stations · /remove · /reorder · /tune |
Preset list & recall |
Generated C++ API reference: run doxygen Doxyfile → Software/docs/api/html/index.html.
Design Highlights
| Topic | Choice | Rationale |
|---|---|---|
| Audio quality | QCC3056 / aptX Adaptive | Codec dominates wireless quality; DAC lives in the sink |
| Audio path | Fully digital I²S | Avoids unnecessary A/D–D/A between tuner and Bluetooth |
| I²S master | ADAU1701 (12.288 MHz) | Clean ×256 → 48 kHz; avoids sample-rate mismatch |
| Firmware style | C++23, std::expected, RAII |
Typed errors, host-testable core, no primitive obsession |
| Stack-up | 6-layer, 2× GND | Solid ground under RF, crystals and USB |
| USB routing | TOP, ref. GND | 90 Ω diff at manufacturable geometry |
| Antennas | 3 zones, diagonal 2.4 GHz | Coexistence separation + full-layer keep-outs |
Status
| Layer | State |
|---|---|
| Schematic | Complete and reviewed |
| PCB layout | 6-layer, DRC clean, plane continuity verified |
| BOM | Finalised (manufacturable / sourced) |
| Prototype | In fabrication (PCBWay) |
| Firmware | 0.8.5 on main — BT1035 I2S boot init, dual OTA, encrypted NVS, full Web UI |
| Web UI | Tabbed SPA covering every REST endpoint |
| HIL | Device validation pending PCB (Software/docs/security-flash-nvs.md) |
| Agent backlog | Feature-complete on main (fw 0.8.5); see Software/docs/TODO.md |
Manufacturing
The board is manufactured with PCBWay as a 6-layer, impedance-controlled PCB
with turnkey assembly. The FSC-BT1035 Bluetooth module is sourced from Feasycom
(the footprint uses a BT806-compatible, pin-identical land pattern). Component
datasheets for design review live in
Hardware/DATASHEET/ (Si4684-A10, AN851, ADAU1701, FSC-BT1035).
See the Technical Manual hardware chapter
and manufacturing notes for fabrication settings and MSL-3 handling of the BT
module.
License
- Hardware (schematics, PCB, Gerbers, BOM): CERN-OHL-S v2 — see
LICENSE - Firmware / Software: Apache-2.0 — see
Software/LICENSE - Documentation: CC BY 4.0
Intellectual property of the design remains with the author. You are free to study, modify and build the hardware under the terms of the respective licenses.
Author
Michele Bigi — Open-source hardware project.
Contributions, issues and questions are welcome via the issue tracker.