Replace TODO with agent backlog and refresh READMEs.
Adopt the prioritised task list for the coding agent and document fw 0.7.0 status plus the full HTTP API in Software/README. Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
+31
-8
@@ -2,7 +2,9 @@
|
||||
|
||||
Open-source Hi-Fi DAB+/FM receiver firmware for the ESP32-S3.
|
||||
|
||||
**Status:** Slice 3 — Si4684 + ADAU1701 boot at power-up (network from Slice 2).
|
||||
**Status:** fw **0.7.0** — companion-chip boot (Si4684, ADAU1701, BT1035),
|
||||
Wi-Fi provisioning, tuner/audio REST API, Bluetooth pairing, station presets.
|
||||
See [`docs/TODO.md`](docs/TODO.md) for the agent task list.
|
||||
|
||||
## Quick start
|
||||
|
||||
@@ -24,7 +26,7 @@ cmake --build build-host
|
||||
ctest --test-dir build-host --output-on-failure
|
||||
```
|
||||
|
||||
Documentation (must exit 0):
|
||||
Documentation gates (must exit 0 before merging):
|
||||
|
||||
```bash
|
||||
doxygen Doxyfile
|
||||
@@ -37,26 +39,47 @@ Manual PDF (design + HTTP API + class reference):
|
||||
cd docs/manual && latexmk -lualatex manual.tex
|
||||
```
|
||||
|
||||
## HTTP API (fw 0.3.0)
|
||||
## HTTP API (fw 0.7.0)
|
||||
|
||||
| Method | Path | Purpose |
|
||||
|--------|------|---------|
|
||||
| GET | `/api/health` | `{"status":"ok","fw":"0.3.0"}` |
|
||||
| GET | `/api/health` | Status, firmware version, companion-chip flags |
|
||||
| POST | `/api/wifi` | Provision STA credentials; reboot on success |
|
||||
| GET | `/api/tuner/status` | Tuner snapshot (DAB/FM) |
|
||||
| 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 |
|
||||
| GET/PUT | `/api/audio/profile` | Read/apply ADAU1701 mixer + EQ profile |
|
||||
| POST | `/api/audio/reset` | Factory-flat audio profile |
|
||||
| POST | `/api/audio/stereo-enhance` | Stereo depth overlay (0–100) |
|
||||
| POST | `/api/audio/bass-enhance` | Bass enhance overlay (0–100) |
|
||||
| GET | `/api/bluetooth/status` | BT1035 boot, pairing, A2DP state |
|
||||
| POST | `/api/bluetooth/pair` | Enter discoverable mode |
|
||||
| POST | `/api/bluetooth/pair/stop` | Leave discoverable mode |
|
||||
| POST | `/api/bluetooth/disconnect` | Release A2DP session |
|
||||
| GET | `/api/stations` | List saved presets |
|
||||
| POST | `/api/stations` | Add preset |
|
||||
| POST | `/api/stations/remove` | Remove preset by index |
|
||||
| POST | `/api/stations/tune` | Recall preset on tuner |
|
||||
|
||||
Full schemas, error tokens, and boot flow: [`docs/manual/ch-api.tex`](docs/manual/ch-api.tex).
|
||||
C++ signatures: generate with `doxygen Doxyfile` → `docs/api/html/index.html`.
|
||||
C++ signatures: `doxygen Doxyfile` → `docs/api/html/index.html`.
|
||||
|
||||
## Layout
|
||||
|
||||
| Path | Role |
|
||||
|------|------|
|
||||
| `Firmware/` | Si4684 `.bin` blobs (DAB+FM) + ADAU1701 SigmaStudio export |
|
||||
| `components/drivers/si4684/` | AN649 SPI boot driver |
|
||||
| `components/drivers/adau1701/` | I2C SigmaStudio RAM download |
|
||||
| `components/core/` | Pure domain (host-tested) |
|
||||
| `components/drivers/` | Si4684, ADAU1701, BT1035 drivers |
|
||||
| `components/services/` | Tuner, audio, Bluetooth, station services |
|
||||
| `components/net/` | Wi-Fi, HTTP server, gzipped web UI |
|
||||
| `docs/manual/` | LaTeX technical manual (canonical) |
|
||||
| `docs/TODO.md` | Agent task list (prioritised backlog) |
|
||||
|
||||
See [`AGENTS.md`](AGENTS.md) §12 and [`instructions.md`](instructions.md) for
|
||||
the authoritative repo layout, coding rules, and development roadmap.
|
||||
coding rules and slice roadmap.
|
||||
|
||||
## Licence
|
||||
|
||||
|
||||
+130
-47
@@ -1,62 +1,145 @@
|
||||
# DigiRadio — consolidated TODO (audit 2026-07-06)
|
||||
# TODO — DigiRadio firmware
|
||||
|
||||
Firmware **0.7.0** after BT1035 pairing + Slice 4 presets. This list
|
||||
cross-checks code, manual, API, UI, and `instructions.md`.
|
||||
Task list for the coding agent. Work top to bottom; each task is a
|
||||
vertical slice that keeps `main` building and the host tests green.
|
||||
|
||||
## Done in this slice
|
||||
**Before writing code, read `AGENTS.md`, `.cursor/rules/`, and
|
||||
`instructions.md`.** Every task below must satisfy the Definition of Done
|
||||
in `AGENTS.md §10`: Apache header on new files, doc block on every class
|
||||
and method, `doxygen Doxyfile` exits 0, host tests pass,
|
||||
`tools/check-manual-sync.py` passes, no primitive obsession, typed
|
||||
errors, no plaintext secrets.
|
||||
|
||||
| Area | Status |
|
||||
|------|--------|
|
||||
| BT1035 pairing AT (`AT+PAIR`, `AT+A2DPSTAT`, `AT+A2DPDISC`) | Done |
|
||||
| `BluetoothService` + `/api/bluetooth/*` + UI | Done |
|
||||
| `Station`, `StationList`, NVS persistence | Done |
|
||||
| `StationService` + `/api/stations/*` + UI | Done |
|
||||
| Host tests (10/10 green) | Done |
|
||||
| Manual: `ch-api`, `ch-bt1035`, `ch-classes` | Done |
|
||||
Working directory for all commands is `Software/`.
|
||||
|
||||
## High priority (next)
|
||||
**Current firmware:** `0.7.0` — BT1035 pairing (`/api/bluetooth/*`),
|
||||
station presets (`/api/stations/*`), host tests green (10/10), manual
|
||||
sync green (38 classes).
|
||||
|
||||
1. **Device flash / HIL** — verify Si4684, ADAU1701, BT1035 on hardware; pairing with real headphones; preset recall across reboot.
|
||||
2. **DAB preset save from UI** — “Save current tune target” stores ensemble index only; capture `service_id` / `component_id` from the last played DAB service (needs UI state or tuner cache).
|
||||
3. **FM band switch UX** — Si4684 boots DAB; FM tune may reload FM image; document/limit band changes in UI (auto-reload or explicit band selector).
|
||||
4. **NVS encryption** — enable `nvs_keys` partition for production (Wi-Fi, presets, future user creds).
|
||||
5. **Slice 8 integration** — unify tuner + audio + presets in a single “now playing” model; source selection (DAB / FM / BT Line-In).
|
||||
---
|
||||
|
||||
## Medium priority
|
||||
## Completed (fw 0.7.0)
|
||||
|
||||
6. **IBtModule interface** — AGENTS mentions it; driver is used directly today. Add when a second BT module or host fake is needed.
|
||||
7. **BT1035 extended AT** — `AT+NAME`, `AT+PLIST`, `AT+A2DPCONN`, event-driven `+PAIRED` / `+A2DPDEV` (UART listener task).
|
||||
8. **Station list reorder API** — `StationList::move()` exists in core; no HTTP route yet.
|
||||
9. **EQ UI completeness** — web UI exposes master/mixer/enhance; per-band EQ editing not in UI (API supports full profile PUT).
|
||||
10. **Si4684 RSQ / scan UX** — driver + HTTP largely done; polish seek, service list refresh, signal display on UI.
|
||||
11. **User credentials** — `ISecureStore` extension for login (out of scope until product needs it).
|
||||
- **Station / preset list (T3 core)** — `Station`, `StationList`, NVS key
|
||||
`station_list`, `StationService`, REST + Presets UI. Remaining polish:
|
||||
reorder API, save DAB `service_id`/`component_id` from UI, HIL on device.
|
||||
- **BT1035 pairing** — `AT+PAIR`, `AT+A2DPSTAT`, `AT+A2DPDISC`,
|
||||
`BluetoothService`, REST + UI (not numbered below; landed with Slice 7).
|
||||
|
||||
## Documentation / tooling
|
||||
---
|
||||
|
||||
12. **Overleaf sync** — GitHub is source of truth; root `docs/` symlink can break Overleaf push; compile from `Software/docs/manual/manual.tex`.
|
||||
13. **Firmware version single source** — `0.7.0` in `SetupWebServer.cpp`; align `FirmwareVersion` / health test constants if desired.
|
||||
14. **Doxygen pass** — run `doxygen Doxyfile` on CI host with ESP-IDF toolchain.
|
||||
## P0 — Fix the build gate (do this first)
|
||||
|
||||
## Low priority / ideas
|
||||
### T1. Clear the 16 Doxygen warnings
|
||||
**Why:** `doxygen Doxyfile` currently exits non-zero, so the docs gate is
|
||||
red and CI (once added) will fail.
|
||||
**What:**
|
||||
- Replace the invalid `\texttt{...}` with `` `...` `` (backticks) or
|
||||
`\c word` in: `core/AudioProfileJson.hpp` (l.58, l.80),
|
||||
`core/AudioEnhancements.hpp` (l.25).
|
||||
- Fix `\r` interpreted as a command in `core/Bt1035At.hpp` (l.64) —
|
||||
wrap the AT string in `@code ... @endcode` or escape as `\\r`.
|
||||
- Add a space after `\ref` in `bt1035/Bt1035Driver.hpp` (l.89) and
|
||||
`core/AudioEnhancements.hpp` (l.24).
|
||||
- Document the missing `@param companionChips` in
|
||||
`net/NetBootstrap.hpp` (`start`) and `net/SetupWebServer.hpp` (`start`).
|
||||
**Done when:** `doxygen Doxyfile` exits 0 and `docs/api/doxygen-warnings.log`
|
||||
is empty.
|
||||
|
||||
15. Physical preset buttons → map GPIO to `StationService::tuneToIndex` by `PresetSlot`.
|
||||
16. OTA updates, mDNS hostname (`digiradio.local`), HTTPS on LAN.
|
||||
17. aptX license note (Feasycom) — commercial firmware variant if needed.
|
||||
### T2. Add the CI workflow
|
||||
**Why:** validate every push automatically.
|
||||
**What:** add `.github/workflows/ci.yml` with three jobs — host build +
|
||||
`ctest`, `doxygen` (fail on warnings), and `check-manual-sync.py`. A ready
|
||||
draft was prepared; place it and confirm all three jobs pass.
|
||||
**Done when:** the workflow is green on `main` after T1.
|
||||
|
||||
## Test gaps
|
||||
---
|
||||
|
||||
| Missing test | Layer |
|
||||
|--------------|-------|
|
||||
| `BluetoothService` with fake driver | Host (needs `IBtModule` or inject interface) |
|
||||
| `StationService` + fake `ISecureStore` | Host |
|
||||
| `NvsSecureStore` station round-trip | Target / integration |
|
||||
| BT1035 UART HIL | Hardware-only, marked separate |
|
||||
## P1 — Missing domain features
|
||||
|
||||
## Roadmap alignment (`instructions.md`)
|
||||
### T3. Station / preset list — polish *(core done in 0.7.0)*
|
||||
**Status:** CRUD, NVS persistence, tune recall, and basic UI are shipped.
|
||||
**Remaining:**
|
||||
- `POST /api/stations/reorder` (core has `StationList::move()`).
|
||||
- Save DAB presets with `service_id` / `component_id` from last played service.
|
||||
- Device HIL: preset survives reboot, tune recall on hardware.
|
||||
**Done when:** the gaps above are closed and covered by tests.
|
||||
|
||||
| Slice | Item | State |
|
||||
|-------|------|-------|
|
||||
| 4 | Station list + persistence + UI | **Done** (basic CRUD + tune) |
|
||||
| 5 | Si4684 tuning / RSQ / DAB properties | Mostly done; UI polish open |
|
||||
| 7 | BT1035 pairing | **Done** (discover + A2DP stat/disconnect) |
|
||||
| 8 | TunerService + AudioService E2E | Partial — health chips OK; unified UX open |
|
||||
### T4. Broadcast metadata (RDS / DLS)
|
||||
**Why:** `TunerStatus` currently carries only a 17-char `label`. Real
|
||||
radio UX needs the FM RDS station name/radiotext and DAB DLS dynamic
|
||||
label so the UI can show "what's playing".
|
||||
**What:**
|
||||
- Extend the tuner data model with structured metadata (station name,
|
||||
radiotext/dynamic label), read from the Si4684 in the driver.
|
||||
- Surface it through `TunerService::refreshStatus` and the
|
||||
`/api/tuner/status` JSON.
|
||||
- Keep the Si4684 register/command details in the driver; the core model
|
||||
stays hardware-free.
|
||||
**Done when:** the status JSON exposes the metadata and host tests cover
|
||||
the parsing of raw label bytes into the model.
|
||||
|
||||
### T5. Remove the services stub — integration service
|
||||
**Why:** `components/services/src/component_stub.cpp` is a Slice-7
|
||||
placeholder. Tuner and Audio services exist separately but nothing
|
||||
orchestrates them together.
|
||||
**What:** implement the integration layer that binds `TunerService`,
|
||||
`AudioService`, the station list, and the network layer into the
|
||||
application flow (e.g. "select a preset → tune → apply the stored audio
|
||||
profile"). Replace the stub file.
|
||||
**Done when:** `app_main` drives a real end-to-end flow through this
|
||||
service; the stub is gone; a manual section documents the new class.
|
||||
|
||||
---
|
||||
|
||||
## P2 — User interface
|
||||
|
||||
### T6. Complete the configuration Web UI
|
||||
**Why:** `components/net/www/index.html` is functional but the
|
||||
requirement is an *elegant, essential* SPA. It should cover:
|
||||
Wi-Fi provisioning, station list management, tuner control (FM/DAB,
|
||||
seek, play), live EQ/volume/enhancement control, Bluetooth pairing, and
|
||||
now-playing metadata.
|
||||
**What:** a minimal single-page app served gzipped from flash, design
|
||||
tokens defined once (spacing, type scale, one accent), thin client over
|
||||
the existing typed JSON API. No heavy frameworks. No business logic in
|
||||
the UI.
|
||||
**Done when:** every API capability has a UI control; the page is served
|
||||
gzipped; no debug endpoint is exposed in a shipping build.
|
||||
|
||||
---
|
||||
|
||||
## P3 — Procurement & hardening
|
||||
|
||||
### T7. Si4684 firmware blob strategy (legal)
|
||||
**Why:** the Si4684 images are proprietary (Skyworks). Tools to fetch/
|
||||
extract exist under `tools/`, but the `.bin` images must **not** be
|
||||
committed to the public repo.
|
||||
**What:**
|
||||
- Confirm `*.bin` (patch, FM, DAB images) are in `.gitignore` and absent
|
||||
from git history.
|
||||
- Document in `Software/Firmware/Si4684-Firmware/README.md` how a builder
|
||||
obtains the images locally (tools + AN649 reference), without
|
||||
redistributing proprietary binaries.
|
||||
**Done when:** no proprietary blob is tracked; the procurement path is
|
||||
documented and reproducible.
|
||||
|
||||
### T8. Flash/NVS encryption enablement
|
||||
**Why:** secure storage holds Wi-Fi and user credentials; encryption at
|
||||
rest was deferred.
|
||||
**What:** enable NVS encryption on an encrypted partition (with flash
|
||||
encryption), per current ESP-IDF security docs. Verify the mechanism
|
||||
before enabling; keep keys out of the repo.
|
||||
**Done when:** credentials are encrypted at rest and the boot path still
|
||||
loads them.
|
||||
|
||||
---
|
||||
|
||||
## Notes for the agent
|
||||
- Prefer extending existing patterns over inventing new ones: copy the
|
||||
shape of `AudioProfile` / `AudioProfileJson` / `IAudioProfileStore` for
|
||||
new persisted models.
|
||||
- Never invent Si4684 register/command details — cite AN649.
|
||||
- One logical change per commit; 50/72 commit messages.
|
||||
- After each task, run: host `ctest`, `doxygen Doxyfile`,
|
||||
`tools/check-manual-sync.py` — all must pass before moving on.
|
||||
|
||||
Reference in New Issue
Block a user