Files
DigiRadio/Software
micheleandCursor 3afcba0d36 Polish igiRadio UI with premium audio, home, and FM screens.
Adds graphic EQ, vertical mixer faders, redesigned home and FM layouts, and an Audio tab for quicker access to DSP controls.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-08-18 15:56:51 +02:00
..
2026-07-06 01:12:37 +02:00
2026-07-06 01:12:37 +02:00

DigiRadio Firmware

Open-source Hi-Fi DAB+/FM receiver firmware for the ESP32-S3.

Status: fw 0.8.5 on main — BT1035 I2S slave boot init, dual OTA + DSP blob updates, EEPROM identity, NVS + flash encryption (development mode), tabbed Web UI with System uploads, 15 host tests, 4 CI jobs. Agent tasks T1T12 complete; device HIL pending first PCB.

Area Shipped in 0.8.5
Boot Si4684 HOST_LOAD, ADAU1701 RAM program, BT1035 I2S slave init (AUXCFG=3, I2SCFG=67)
Tuner FM/DAB tune, seek up/down, RSQ, RDS, DAB services + DLS
Audio 6-band EQ, mixer, stereo/bass enhance, NVS profile
Updates ESP32 dual-OTA, ADAU1701 dsp partition blob replay
Identity 24AA025E48 EUI-48 → serial, SoftAP/BT name suffix
Presets CRUD, reorder, integrated recall + last-preset at boot
Network SoftAP/STA, tabbed gzipped SPA, typed JSON REST API
Security initEncryptedStorage() — see docs/security-flash-nvs.md
Quality Doxygen, manual sync, Si4684 blob policy check

Architecture: functional core (components/core, host-tested, no ESP-IDF) + imperative shell (drivers, services, net, secure_store). Rules: AGENTS.md · backlog: docs/TODO.md

Prerequisites

Si4684 blobs (proprietary, local only — not in git):

python3 tools/fetch_si4684_firmware.py --dab-only
python3 tools/fetch_si4684_firmware.py --si46xx-dir /path/to/si46xx_firmware
python3 tools/check_si4684_blobs.py

See Firmware/Si4684-Firmware/README.md.

ESP-IDF v5.5.x, target esp32s3.

Quick start

Open this directory (Software/) as the Cursor project so AGENTS.md and .cursor/rules/ load automatically.

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

Production flash-encryption release mode: overlay sdkconfig.defaults.production (see security doc — irreversible on chip).

Host tests

Pure core, no hardware (needs C++23 compiler on macOS — Homebrew llvm or GCC 14):

cmake -S components/core/test -B build-host \
      -DCMAKE_CXX_COMPILER="$(brew --prefix llvm)/bin/clang++"
cmake --build build-host
ctest --test-dir build-host --output-on-failure

Quality gates (CI on every push to main)

Run from Software/:

doxygen Doxyfile
python3 tools/check-manual-sync.py
python3 tools/check_si4684_blobs.py
tools/gzip-www.sh   # after editing components/net/www/index.html

CI jobs: host-tests, doxygen, manual-sync, si4684-blobs (.github/workflows/ci.yml).

Web UI

Gzipped single-page app at / — tabs: Now (RDS/DLS), Radio, Presets, Audio (6-band EQ), BT, WiFi, System (firmware OTA + DSP upload). Header shows EEPROM serial from /api/health. Source: components/net/www/index.html · regenerate embed: tools/gzip-www.sh.

HTTP API (fw 0.8.5)

Method Path Purpose
GET /api/health Status, firmware version, serial, companion-chip flags
POST /api/wifi Provision STA credentials; reboot on success
GET /api/tuner/status Tuner snapshot (DAB/FM, RDS/DLS metadata)
GET /api/tuner/services DAB service list for current ensemble
POST /api/tuner/tune Tune DAB ensemble or FM frequency
POST /api/tuner/play Start DAB service playback
POST /api/tuner/seek FM seek up or down ({"direction":"up|down"})
GET/PUT /api/audio/profile Read/apply ADAU1701 mixer + 6-band EQ
POST /api/audio/reset Factory-flat audio profile
POST /api/audio/stereo-enhance Stereo depth overlay (0100)
POST /api/audio/bass-enhance Bass enhance overlay (0100)
POST /api/dsp/program Upload ADAU1701 DRAD blob (raw bytes, reboot)
POST /api/system/ota Upload ESP32 firmware image (raw bytes, reboot)
GET /api/bluetooth/status BT1035 boot, pairing, A2DP, name, auto-reconnect
GET /api/bluetooth/paired Paired-device list from module
POST /api/bluetooth/pair Enter discoverable mode
POST /api/bluetooth/pair/stop Leave discoverable mode
POST /api/bluetooth/disconnect Release A2DP session
POST /api/bluetooth/auto-reconnect Set auto-reconnect count (015)
GET /api/stations List saved presets
POST /api/stations Add preset
POST /api/stations/remove Remove preset by index
POST /api/stations/reorder Move preset (from/to indices)
POST /api/stations/tune Recall preset (tuner + audio profile + NVS)

Wire schemas: docs/manual/ch-api.tex · C++ API: doxygen Doxyfiledocs/api/html/index.html.

Layout

Path Role
Firmware/ Si4684 .bin (local) + ADAU1701 SigmaStudio export
components/core/ Pure domain (host-tested)
components/drivers/ Si4684, ADAU1701, BT1035
components/services/ Tuner, audio, Bluetooth, station, integration
components/secure_store/ Encrypted NVS: credentials, profiles, presets
components/net/ Wi-Fi, HTTP server, gzipped web UI
sdkconfig.defaults C++23, NVS + flash encryption (dev mode)
partitions.csv nvs, otadata, dual OTA (ota_0/ota_1), dsp blob, nvs_keys
docs/manual/ LaTeX technical manual
docs/security-flash-nvs.md Encryption + device HIL checklist
docs/TODO.md Completed tasks + HIL backlog
tools/ Blob fetch, CI policy checks, UI gzip

Manual PDF: cd docs/manual && latexmk -lualatex manual.tex

Licence

Apache-2.0 — see LICENSE.