The 2026-08-16 IBP=1 override (commit 6974095) was applied alongside a
separate, simultaneous fix to Si4684's PIN_CONFIG_ENABLE and credited
with turning static into audible music. SerialInputRegister (0x081F) is
a single register shared by every SDATA_INx pin on the ADAU1701, so the
override also applied to the ESP32 streaming input, not just Si4684's.
Live A/B testing today (DAB, FM, and ESP32 web-radio, all isolated via
mixer gain, with and without ADAU1701 DSP bypass, with and without BT
A2DP codec changes) narrowed the hiss to this one shared register.
Removing the override and leaving IBP at its compiled default (0x00)
resolved the hiss on both the Si4684 and ESP32 paths, confirmed by ear.
Also:
- Add a runtime HTTP API (GET/POST /api/bluetooth/a2dp-codec) to change
the BT1035 A2DP codec bitmask without reflashing, used to rule out
AAC/SBC codec choice as a contributing cause.
- Extend the ADAU1701 boot-time EQ diagnostic to read back all 6 bands
(previously band 0 only) using the correct 5.23 fixed-point format.
- Note EEPROM persistence for ANTCAP/crystal calibration as TODO.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.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.