Files
DigiRadio/README.md
T
micheleandCursor 8439ec4055 Sync all project docs for firmware 0.8.3 completion.
Update READMEs, manual chapters, agent guides, CONTRIBUTING, and TODO to reflect T1–T8 done, encrypted NVS, CI gates, and pending HIL checklist.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-07-07 07:49:07 +02:00

11 KiB
Raw Blame History

DigiRadio

DAB+/FM Bluetooth Receiver with SigmaDSP Audio Processing

Open-source digital radio — Si4684 tuner · ADAU1701 SigmaDSP · Bluetooth aptX Adaptive · ESP32-S3

Status Firmware CI PCB Hardware License Firmware License: Apache 2.0


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/DD/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.3)

Area Capability
Boot & chips Si4684 DAB+FM firmware load (HOST_LOAD blobs), ADAU1701 RAM program at every boot, BT1035 UART init
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 5-band EQ, input mixer, stereo/bass enhancement overlays, profile persist in 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, Doxygen gate, LaTeX manual sync check, GitHub Actions CI on main

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.3 NVS + flash encryption (development mode), initEncryptedStorage, security docs
0.8.2 Tabbed Web UI + 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.50.6 ADAU1701 runtime EQ/mixer, Si4684 tuning & DAB service list, BT1035 driver
0.30.4 Secure store, Wi-Fi provisioning, companion-chip boot, walking skeleton

Next up: device HIL for encrypted NVS (when PCB arrives). Agent backlog: Software/docs/TODO.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/                Manual sync checker, Si4684 blob helpers
├── CONTRIBUTING.md
├── 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, API table, and component map: Software/README.md.

First boot (device)

  1. Power the board; ESP32 starts SoftAP setup mode (DigiRadio-setup — see manual).
  2. Connect and open the gzipped web UI or call GET /api/health.
  3. POST /api/wifi with STA credentials; device reboots into normal mode.
  4. 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 DoxyfileSoftware/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/DD/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.3 on main — encrypted NVS, full Web UI, integration, RDS/DLS
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.3); 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). 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.