Add preset polish and broadcast metadata (fw 0.8.0).
Ship station reorder, DAB playing ids in presets, RDS PS/RT and DAB DLS in tuner status, Si4684 data-service read, host tests, and UI now-playing lines. Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
+12
-26
@@ -12,16 +12,15 @@ errors, no plaintext secrets.
|
||||
|
||||
Working directory for all commands is `Software/`.
|
||||
|
||||
**Current firmware:** `0.7.1` — CI green gate (Doxygen + host tests +
|
||||
manual sync), BT1035 pairing, station presets.
|
||||
**Current firmware:** `0.8.0` — broadcast metadata (RDS PS/RT, DAB DLS),
|
||||
preset reorder, CI gate (Doxygen + host tests + manual sync).
|
||||
|
||||
---
|
||||
|
||||
## Completed (fw 0.7.0)
|
||||
## Completed (fw 0.7.0–0.7.2)
|
||||
|
||||
- **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.
|
||||
- **Broadcast metadata (T4)** — RDS PS/RT and DAB DLS in
|
||||
`/api/tuner/status`, core parsers, Si4684 driver hook, UI lines.
|
||||
- **BT1035 pairing** — `AT+PAIR`, `AT+A2DPSTAT`, `AT+A2DPDISC`,
|
||||
`BluetoothService`, REST + UI (not numbered below; landed with Slice 7).
|
||||
|
||||
@@ -42,27 +41,14 @@ push/PR to `main`.
|
||||
|
||||
## P1 — Missing domain features
|
||||
|
||||
### 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.
|
||||
### T3. Station / preset list — polish — **DONE (fw 0.7.2)**
|
||||
Reorder API (`POST /api/stations/reorder`), DAB playing ids in tuner
|
||||
status and preset save, UI Up/Dn, host tests. **Remaining:** device HIL
|
||||
(preset survives reboot) — manual only.
|
||||
|
||||
### 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.
|
||||
### T4. Broadcast metadata (RDS / DLS) — **DONE (fw 0.8.0)**
|
||||
`BroadcastLabel`, RDS accumulator, DAB DLS accumulator, driver
|
||||
`readDabServiceData`, status JSON fields, UI now-playing lines, host tests.
|
||||
|
||||
### T5. Remove the services stub — integration service
|
||||
**Why:** `components/services/src/component_stub.cpp` is a Slice-7
|
||||
|
||||
@@ -36,7 +36,7 @@ Returns a health-check DTO serialised by
|
||||
|
||||
\begin{drnote}[Response schema]
|
||||
\begin{drcode}[JSON]
|
||||
{"status":"ok","fw":"0.7.0",
|
||||
{"status":"ok","fw":"0.8.0",
|
||||
"chips":{"si4684":true,"adau1701":true,"bt1035":true}}
|
||||
\end{drcode}
|
||||
\begin{itemize}
|
||||
@@ -108,15 +108,20 @@ and~\ref{sec:si4684-fm-session}.
|
||||
\begin{drnote}[Response schema (DAB example)]
|
||||
\begin{drcode}[JSON]
|
||||
{"booted":true,"band":"dab","locked":true,"volume":63,
|
||||
"dab":{"freq_index":12,"fic_quality":80,"cnr_db":25},"fm":null}
|
||||
"dab":{"freq_index":12,"fic_quality":80,"cnr_db":25,
|
||||
"playing_service_id":42,"playing_component_id":7,
|
||||
"dynamic_label":"Live show"},"fm":null}
|
||||
\end{drcode}
|
||||
For FM, \texttt{fm} carries \texttt{frequency\_khz}, \texttt{rssi\_dbuv},
|
||||
\texttt{snr\_db}, and \texttt{stereo}; \texttt{dab} is \texttt{null}.
|
||||
\texttt{snr\_db}, \texttt{stereo}, optional \texttt{station\_name} (RDS PS),
|
||||
and \texttt{radiotext} (RDS RT); \texttt{dab} is \texttt{null}.
|
||||
\end{drnote}
|
||||
|
||||
HTTP status: \textbf{200 OK}; \textbf{500} with
|
||||
\texttt{\{"status":"error","reason":...\}} on driver failure;
|
||||
\textbf{503} when the tuner service is unavailable.
|
||||
\textbf{503} when the tuner service is unavailable. FM responses may include
|
||||
\texttt{station\_name} and \texttt{radiotext}; DAB responses may include
|
||||
\texttt{dynamic\_label} when a programme is playing.
|
||||
|
||||
\subsection{\texttt{GET /api/tuner/services}}
|
||||
\label{sec:api-tuner-services}
|
||||
@@ -306,6 +311,12 @@ Adds one preset (\texttt{core::parseStationJson()}); persists via
|
||||
|
||||
Removes a preset by list index (\texttt{\{"index":0\}}).
|
||||
|
||||
\subsection{\texttt{POST /api/stations/reorder}}
|
||||
\label{sec:api-stations-reorder}
|
||||
|
||||
Reorders presets using \texttt{StationList::move()}. Body:
|
||||
\texttt{\{"from":1,"to":0\}}. Success: \texttt{\{"status":"reordered"\}}.
|
||||
|
||||
\subsection{\texttt{POST /api/stations/tune}}
|
||||
\label{sec:api-stations-tune}
|
||||
|
||||
|
||||
@@ -230,6 +230,18 @@ Validated at the HTTP boundary by \texttt{core::parseEnhanceLevelJson()}.
|
||||
Strong type for a preset label (1--32 bytes). Parsed at the HTTP boundary
|
||||
via \texttt{StationName::tryFrom()}.
|
||||
|
||||
\section{BroadcastLabel}\label{cls:BroadcastLabel}
|
||||
Trimmed on-air label from RDS or DAB chip byte buffers (up to 128 bytes).
|
||||
Built by \texttt{BroadcastLabel::tryFromChipBytes()} in the pure core.
|
||||
|
||||
\section{RdsMetadataAccumulator}\label{cls:RdsMetadataAccumulator}
|
||||
Stateful RDS decoder assembling program service name and radiotext from
|
||||
raw block~A--D snapshots returned by the Si4684 driver.
|
||||
|
||||
\section{DabDynamicLabelAccumulator}\label{cls:DabDynamicLabelAccumulator}
|
||||
Reassembles segmented DAB DLS payloads into one dynamic label for
|
||||
\texttt{TunerStatus}.
|
||||
|
||||
\section{PresetSlot}\label{cls:PresetSlot}
|
||||
Optional hardware preset button index (1--20). Validated by
|
||||
\texttt{PresetSlot::tryFrom()}.
|
||||
|
||||
@@ -180,7 +180,9 @@ Requires \texttt{boot(Si4684Band::Fm)}.
|
||||
\item \texttt{tuneFm(frequencyKhz)} --- FM\_TUNE\_FREQ, waits for STC.
|
||||
\item \texttt{seekFm(up, wrap)} --- FM\_SEEK\_START; returns tuned kHz.
|
||||
\item \texttt{readFmRsq()} --- RSSI, SNR, stereo flag, validity.
|
||||
\item \texttt{readFmRds()} --- last RDS group blocks A--D.
|
||||
\item \texttt{readFmRds()} --- last RDS group blocks A--D (FIFO depth).
|
||||
\item \texttt{readDabServiceData(statusOnly, ack)} --- DAB data-service
|
||||
payload (DLS when \texttt{DATA\_SRC=2}).
|
||||
\end{itemize}
|
||||
|
||||
\subsection{DAB operations}
|
||||
|
||||
Reference in New Issue
Block a user