Files
DigiRadio/Software/docs/TODO.md
T
micheleandClaude Sonnet 5 c0eee4a4ad Firmware review pass: BT1035 boot retry, BluetoothJson tests, doc catch-up
BT1035Driver::boot() had zero retry on the reset+AT-init sequence — a
single hardware RESET# pulse followed immediately by AT commands,
with no second attempt if the module didn't come up in time. This is
the most plausible explanation for the intermittent "no spontaneous
UART bytes after hardware reset" / "AT init failed" boot failures
logged in docs/si4684-rf-investigation-report.md and observed again
live this morning on otherwise-identical hardware/wiring — classic
power-up timing jitter, not a permanent fault. Extracted the reset+
init sequence into resetAndInitOnce() and wrapped it in a 3-attempt
retry loop with a short delay between attempts; the one-time GPIO
config and UART driver install stay outside the loop since they don't
need repeating. Root cause of the underlying jitter is still open.

BluetoothJson.hpp was the only *Json.hpp module in the core with zero
host test coverage (status/scan/paired serialisation, auto-reconnect/
connect/speaker parsing) — every sibling module already has one.
Added bluetooth_json_test.cpp following the existing tuner_json_test
pattern; ctest now covers 20 suites instead of 19.

Documentation catch-up, found doing a full firmware re-review at the
user's request:
- POST /api/tuner/calibrate-antenna and the antcap field on
  POST /api/tuner/tune (added in a previous commit, never documented)
  are now in ch-api.tex.
- kFirmwareVersion was still hardcoded "0.8.5" despite the RF fixes,
  BLE provisioning, phone streaming, antenna calibration, and generic
  DSP param API landed since that version's actual release commit
  (0a1188a). Bumped to 0.9.0 everywhere it's mentioned (health JSON,
  the manual's title page, intro, classes, and API chapters).
- instructions.md and docs/TODO.md still described the firmware as
  frozen at 0.8.5 awaiting hardware-in-the-loop testing that has since
  happened extensively; docs/TODO.md's H5 verdict specifically still
  said "suspect U6 RF ground (re-open PCBWay)" for a bug that turned
  out to be firmware, not hardware — actively misleading, corrected.
  Both files now summarise the post-0.8.5 HIL findings and current
  open items (BT1035 root cause, intermittent HTTP unresponsiveness
  under load, antenna-limited signal quality, possibly-undersized 24 KB
  nvs partition).

Verified: idf.py build, doxygen (0 warnings), check-manual-sync,
check_si4684_blobs, ctest (20/20), two-pass xelatex manual build all
green. Flashed and confirmed live: fw reports 0.9.0, BT1035 booted on
the first attempt post-flash.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_0178rASQ6ZETPMUamvpoR2KR
2026-08-19 09:23:36 +02:00

6.2 KiB
Raw Blame History

TODO — DigiRadio firmware

Agent task list and hardware-in-the-loop backlog. Working directory for all commands is Software/.

Current firmware: 0.9.0 — everything in 0.8.5, plus: Si4684 RF blackout root-caused and fixed (real FM/DAB lock and audio on real hardware), DAB service list fixed (two rounds), FM ANTCAP antenna calibration persisted to EEPROM, generic ADAU1701 parameter API, phone PCM streaming, BLE Wi-Fi provisioning, full FM band scan, BT1035 boot retry. See "Post-0.8.5 hardware-in-the-loop findings" below and docs/si4684-rf-investigation-report.md for the full story.

Before writing code, read AGENTS.md, .cursor/rules/, and instructions.md. Definition of Done: Apache header, doc blocks, doxygen Doxyfile exits 0, host tests pass, check-manual-sync.py and check_si4684_blobs.py pass, no plaintext secrets.


Completed agent tasks (T1T12, fw 0.7.10.8.5)

Task Version Summary
T1 0.7.1 Doxygen warnings cleared
T2 0.7.1 CI workflow (host tests, Doxygen, manual sync)
T3 0.7.2 Preset reorder API/UI, DAB playing ids in status
T4 0.8.0 RDS/DLS broadcast metadata
T5 0.8.1 IntegrationService — startup, preset recall, last-preset NVS
T6 0.8.2 Tabbed configuration Web UI (REST coverage)
T7 0.8.2 Si4684 blob policy — gitignore, docs, check_si4684_blobs.py
T8 0.8.3 NVS + flash encryption — initEncryptedStorage, security docs
T9 0.8.4 Dual-OTA partition table + dsp blob slot, rollback Kconfig
T10 0.8.4 EEPROM EUI-48 identity — SoftAP/BT/hostname/serial
T11 0.8.4 Updatable ADAU1701 program — POST /api/dsp/program, DRAD blob
T12 0.8.4 ESP32 OTA — POST /api/system/ota, rollback confirm on boot

0.8.5 (hardware/doc alignment): BT1035 boot uses AT+AUXCFG=3 + AT+I2SCFG=67 (I2S from ADAU1701, not Line-In); I2C pull-ups R1/R16 confirmed 2,kΩ; Hardware/DATASHEET/ bundle + manual cross-refs.

Also landed (not numbered): BT1035 pairing (BluetoothService), station presets (fw 0.7.0), companion-chip boot (Slice 3), ADAU1701 runtime (Slice 5).


P4 — Hardware-in-the-loop (when PCB arrives)

Manual validation only — does not block host CI.

H1. Encrypted NVS boot path

Follow docs/security-flash-nvs.md: first flash with idf.py erase-flash flash, verify boot logs, Wi-Fi provisioning survives reboot, presets and last_preset survive power cycle.

H2. End-to-end listening

Si4684 DAB/FM tune, ADAU1701 profile apply, BT1035 A2DP to headphones, now-playing metadata in UI and /api/tuner/status.

H3. OTA and DSP program update (on hardware)

Push a known-good .bin via POST /api/system/ota, confirm rollback after a deliberately bad image. Upload a DRAD blob via POST /api/dsp/program and verify ADAU replay after reboot.

H4. Production flash encryption (optional)

After H1 passes, trial build with sdkconfig.defaults.production overlay on a sacrificial unit; confirm RELEASE mode policy before shipping.

H5. Si4684 FM/DAB no-lock — RESOLVED, was firmware after all

Superseded verdict (2026-08-13): blob OK → suspected U6 RF ground, PCBWay dispute opened. That verdict was wrong. The actual cause was writeCommand()'s ARG1 byte being mis-offset across FM/DAB tune, seek, and several status/ack commands — the chip always answered correctly, so every signal pointed at hardware, but it never actually tuned. Fixed; real FM lock, real DAB ensemble lock, real audio confirmed live on the same board. No PCB rework was needed. Full investigation, the wrong initial verdict, and the eventual root cause: docs/si4684-rf-investigation-report.md.


Post-0.8.5 hardware-in-the-loop findings

The board arrived and testing against it (not just host tests) found real bugs the host-testable core couldn't catch, since they live in ESP-IDF-only drivers. Full detail and evidence in docs/si4684-rf-investigation-report.md. Short version:

  • Si4684 total RF blackout (H5 above) — firmware bug, fixed.
  • Si4684→ADAU1701 digital audio silence — PIN_CONFIG_ENABLE mutual exclusion + SerialInputRegister polarity, fixed.
  • DAB service list empty/garbled — response-parsing offset bugs (two rounds) plus DAB_EVENT_INTERRUPT_SOURCE (0xB300) never configured, fixed.
  • FM front-end auto-tune measurably suboptimal on this board's actual matching network — ANTCAP calibration swept and persisted to EEPROM, POST /api/tuner/calibrate-antenna.
  • BT1035 intermittent boot failure — root cause still unknown, but a reset+init retry loop (up to 3 attempts) was added since the failure looked like power-up timing jitter, not a permanent fault.
  • Still open: BT1035 root cause; intermittent multi-second HTTP unresponsiveness under load; DAB signal quality still antenna-limited; 24 KB nvs partition may be undersized (saveProfile() store_failed seen intermittently, error code never captured).

Open firmware polish (non-blocking)

Done in fw 0.8.5 unless noted:

  • BT1035 boot — I2S slave init (AT+AUXCFG=3, AT+I2SCFG=67) per PCB routing (0.8.5).
  • FM seek down — POST /api/tuner/seek with {"direction":"down"} (0.8.4).
  • BT1035 — query/set name, paired list (AT+PLIST), auto-reconnect (AT+AUTOCONN) per Feasycom BT1035 manual (0.8.4).
  • Si4684 — STOP_DIGITAL_SERVICE (0x82) before FM band switch when DAB audio is active; ensemble metrics remain via DAB_DIGRAD_STATUS in status (0.8.4).

Quality gates (run from Software/ before merge)

cmake -S components/core/test -B build-host && cmake --build build-host
ctest --test-dir build-host --output-on-failure
doxygen Doxyfile
python3 tools/check-manual-sync.py
python3 tools/check_si4684_blobs.py

After editing the web UI: tools/gzip-www.sh.


Notes for the agent

  • Extend existing patterns (AudioProfile / IAudioProfileStore shape).
  • Never invent Si4684 opcodes — cite AN649.
  • Never invent BT1035 AT strings — cite Feasycom BT1035 programming guide.
  • One logical change per commit; 50/72 messages.
  • Update ch-classes.tex / ch-api.tex when public API or HTTP changes.