micheleandCursor 0e7d8449a9 Fix LaTeX manual build errors for LuaLaTeX.
Rename conflicting TikZ step style to drstep, add missing ch:firmware label, and use TeX Gyre Heros font fallback instead of Linux Biolinum O.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-07-07 10:19:15 +02:00
2026-07-06 08:53:33 +02:00
2026-07-06 01:12:37 +02:00

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 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.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.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: 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)

  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.

S
Description
No description provided
Readme
32 MiB
Languages
C++ 54.6%
C 18%
Swift 9.8%
TeX 9.4%
HTML 3.8%
Other 4.4%