Commit Graph
21 Commits
Author SHA1 Message Date
micheleandClaude Sonnet 5 a91c63fc31 Redesign BT1035 RESET#/SYS_CTRL handling, add CTS/RTS diagnostics
RESET# (pin 8) is no longer driven at all: reconfigured as a floating
input relying entirely on the module's own internal pull-up per
datasheet §4.8, as a diagnostic test to rule out host-side RESET# drive
as a contributor to intermittent boot failures.

SYS_CTRL (pin 34) now performs a genuine LOW(2.5s)->HIGH power-cycle on
every resetAndInitOnce() call rather than being asserted once ever:
previously every later retry from bt1035RetryTask silently reused an
already-HIGH SYS_CTRL line without ever actually power-cycling the
module.

Added read-only diagnostics on the CTS/RTS pins (physically wired,
named in board_pins.hpp since their original definition, never
configured by any driver code, host flow control disabled) to observe
their level around the boot-banner wait, after reviewing a sibling
project's PinScope report and re-reading the datasheet's UART flow
control and PA_MUTE default-function documentation.

Across ~45 minutes of live testing after these changes, zero successful
boots were observed - inconclusive on whether this improves anything,
but each change is independently correct per the datasheet. Escalated
to Feasycom support with the full findings. Documented in the RF
investigation report and TODO.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-08-22 13:58:27 +02:00
micheleandClaude Sonnet 5 f6dc9916a4 Add BT1035 background boot retry; document intermittent silence findings
BT1035 boot can fail with total UART silence even after the banner-timing
fix, on otherwise-identical, correctly-powered hardware. Confirmed via
multimeter (VBAT_IN, 1.8V_OUT, SYS_CTRL/RESET, TX all normal) and by
observing the same physical module both succeed and fail across different
boot attempts in one session, that this is intermittent, not a dead
module — the crystal is sealed inside the module and not inspectable or
fixable from our side.

Since the fault self-clears on a later attempt, mitigate with an
indefinite background retry task: if the initial boot() fails, keep
retrying with no artificial delay (each attempt already takes ~25-60s) so
a temporary failure becomes a bounded, self-recovering delay instead of
requiring a manual power cycle. Documented the full diagnostic session,
including the ruled-out theories and a possible future ESP32-S31 (native
Bluetooth Classic) migration path, in the RF investigation report.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-08-21 09:32:07 +02:00
micheleandClaude Sonnet 5 3a58d33aad Add DAB ANTCAP calibration and fix BT1035 boot banner timing
Extend the FM-only ANTCAP antenna-varactor override to DAB, mirroring the
existing mechanism end to end (driver, tuner, service, EEPROM storage,
HTTP API). Live sweep on real hardware found no ANTCAP value beating
auto-tune on the ensembles tested, so DAB stays on auto-tune by default.

Also fix BT1035 boot: the module's real boot banner doesn't appear until
~18-24s after RESET# releases, not the 3.5s previously waited; add a
2-attempt retry and a baud-rate probe fallback for diagnostics.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-08-21 08:12:08 +02:00
micheleandClaude Sonnet 5 e8f79c4b79 Add PUT /api/stream/phone: raw PCM audio push from a phone app
New endpoint accepts chunked, header-less, 16-bit LE stereo PCM @ 48 kHz
in the request body and writes it straight to the shared I2S sink for as
long as the connection stays open. Chosen deliberately unencoded (no
MP3/AAC/Opus decode) to keep this path as simple and low-risk as
possible — the companion app controls the encoding on its side.

Extracted the I2S TX channel that used to be owned outright by
web_radio_stream.cpp into main/esp32_i2s_sink.cpp, shared by both
producers with a simple tryAcquire()/release() exclusivity guard — web
radio streaming and a phone PCM stream would otherwise fight over the
same physical wire. web_radio_stream.cpp now acquires/releases around
each streamWhileEnabled() cycle instead of owning the channel itself.

net::PhoneStreamSink is a plain function-pointer struct (not a class
hierarchy) threaded through NetBootstrap::start() -> SetupWebServer::start()
-> HttpRouteContext, so components/net stays free of I2S driver headers;
main/phone_stream.cpp supplies the concrete functions (bound to
esp32_i2s_sink) and does the int16->ADAU 32-bit-slot conversion, batched
per chunk rather than per sample for the same reason as the web radio
stutter fix (6974095/7e65394 lineage).

Verified by build only — not confirmed live yet (board disconnected this
session); the actual phone app that will exercise this endpoint doesn't
exist yet either.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_0178rASQ6ZETPMUamvpoR2KR
2026-08-18 08:03:39 +02:00
micheleandClaude Sonnet 5 7e65394100 Fix web radio streaming stutter: batch I2S writes, widen DMA buffer
writeFrame() called i2s_channel_write() once per decoded PCM sample (up to
1152 separate driver calls per MP3 frame), each with its own locking/DMA
bookkeeping overhead. Now accumulates a whole frame into one buffer and
writes it in a single call.

The I2S TX channel also used the ESP-IDF default DMA config (6 descriptors
x 240 frames = ~30 ms of buffering at 48 kHz), leaving almost no headroom
against network jitter in this single-task fetch+decode+play pipeline.
Widened to 12 x 480 (~120 ms) so a brief HTTP stall doesn't immediately
starve the DMA and audibly crackle.

Both are static/architectural fixes verified by build only — not confirmed
live yet (board disconnected this session).

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_0178rASQ6ZETPMUamvpoR2KR
2026-08-18 07:50:48 +02:00
micheleandClaude Sonnet 5 ef15e9839c Fix Si4684 FM/DAB tune commands: ARG offset bug caused total RF blackout
writeCommand() always prepends a fixed ARG1=0x00 byte before the payload;
tuneFm()/tuneDab() built their argument arrays starting at what the author
believed was ARG1, so every byte landed one slot right of its real AN649
position and an extra unused byte was appended. The chip never received the
requested frequency. This is the root cause of the months-long total RF
blackout (RSQ frozen at all-zero on every frequency/ANTCAP value) previously
attributed to a QFN exposed-pad hardware defect — that hypothesis is now
overturned, confirmed live: RSSI/SNR now read real, frequency-dependent
values with zero STC timeouts after the fix.

Also make BT1035 boot failure non-fatal in HardwareBootstrap::boot() so a
companion-chip fault no longer halts the whole device (Si4684 tuning, web
UI, Wi-Fi already isolate BT1035 readiness via CompanionChipStatus).

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_0178rASQ6ZETPMUamvpoR2KR
2026-08-16 00:19:43 +02:00
micheleandClaude Sonnet 5 6f7b6dd12c Add internet radio streaming with runtime API, modernize web UI, remove auto-tune/beep at boot
Streaming (main feature this session):
- New WebRadioConfig/WebRadioJson core types, ISecureStore-backed persistence
- New webradio::WebRadioService (thread-safe live config) + GET/POST /api/streaming
- web_radio_stream task now runtime-toggleable (no reboot), no hardcoded URL
- Content-Type diagnostic: warns clearly when a URL is a webpage, not an audio stream

Boot cleanup:
- Removed boot-time auto FM/DAB tune, auto-beep, and the (now-concluded) Si4684
  crystal IBIAS/CTUN empirical sweep from main.cpp — tuning/beep are on-demand
  via the existing REST API only

Web UI:
- Modernized styling (cards, gradients, toggle switches, light/dark theme)
- New Stream tab wired to /api/streaming

Fixes found via real idf.py build (not just clangd):
- Restored wrongly-removed si4684/Si4684Tuner.hpp include in main.cpp
- Fixed MP3Decode() argument types in web_radio_stream.cpp (unsigned char**/int*)

Quality-gate fixes:
- Host-test stub headers (esp_log.h, freertos/*) so TunerService.cpp's
  scanForStation logging/pacing compiles for station_service_test /
  integration_service_test instead of running stale binaries
- Added WifiScanner and WebRadioService manual sections; filled in missing
  Doxygen docs on BluetoothService, i2s_sdata_probe, test_firmware, Bt1035At
- Ignore clangd's .cache/ index directory

Also includes prior uncommitted work carried in the tree: Wi-Fi/Bluetooth
device scan REST API and UI (WifiScanner, BT scan), SigmaStudio TCP bridge,
and the current ADAU1701 SigmaStudio DSP program export.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-08-08 21:15:22 +02:00
micheleandCursor 7d3369b098 Fix Wi-Fi credential save with plain NVS (encryption off).
Initialise NVS before integration startup, recover from encrypted-partition mismatches without re-enabling encryption, and improve provisioning logs and POST body handling.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-08-05 14:10:00 +02:00
michele 34f247019a Si4684 boot fix: flash encryption off, 16MB flash, NVS enc off, main task stack 8KB, CTS timeout 10s (fixes BootCmd error 6), DMA-safe HOST_LOAD buffer 2026-08-05 08:57:43 +02:00
micheleandCursor 176cdd9319 Release fw 0.8.4: doc sync, System UI, BT/FM polish.
Align README, manual, and backlog to 0.8.4; add Web UI System tab for OTA/DSP uploads, serial in health header, FM seek down, and BT1035 paired list plus auto-reconnect API.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-07-07 09:56:44 +02:00
micheleandCursor b0cff8369e Add ESP32 OTA firmware update with rollback confirmation.
Stream application binaries to the inactive OTA slot via POST /api/system/ota,
validate the esp_app_desc project name in core, and cancel rollback after a
healthy network boot through OtaService::confirmBoot().

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-07-07 09:41:29 +02:00
micheleandCursor cc4a03168e Add updatable ADAU1701 program via flash partition and HTTP API.
Decouple the SigmaStudio RAM download from compiled-in adau1701_program.c:
DRAD v1 blobs in the dsp partition with embedded fallback, POST /api/dsp/program,
and host-tested blob parse/serialize helpers.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-07-07 09:21:49 +02:00
micheleandCursor cd94e36a9d Add EEPROM EUI-48 device identity across firmware and API.
Read the factory 24AA025E48 serial after ADAU I2C boot, derive SoftAP SSID, BT name, STA hostname, and expose serialNumber on GET /api/health with graceful fallbacks.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-07-07 09:00:38 +02:00
micheleandCursor d13012ce4b Add integration startup service and fix Doxygen (fw 0.8.1).
Replace the services stub with IntegrationService for boot preset recall and tune orchestration, persist last preset in NVS, and remove invalid @return tags that broke CI on T4 metadata headers.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-07-07 00:17:13 +02:00
micheleandCursor 82c9f401da Add BT1035 pairing and station presets (fw 0.7.0).
Expose discoverable mode and A2DP control over REST, add persisted
DAB/FM preset list with web UI, and document gaps in docs/TODO.md.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-07-06 17:42:11 +02:00
micheleandCursor 98518c5424 Integrate companion-chip status into GET /api/health (fw 0.6.0).
Expose Si4684, ADAU1701, and BT1035 boot flags via CompanionChipStatus after
HardwareBootstrap; update API manual schema for Slice 8.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-07-06 17:15:17 +02:00
micheleandCursor d49b2011dd Add BT1035 driver with manual chapter and expand Si4684 tuning docs.
Implement Bt1035Driver AT init (AT+AUXCFG=1), core AT parser with host tests,
wire boot into HardwareBootstrap, and document DAB/FM tuning workflows in ch-si4684.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-07-06 17:07:37 +02:00
micheleandCursor ab3651e678 Add Slice 5 ADAU1701 runtime audio control (firmware 0.5.0).
Safeload mixer/EQ/master on the ADAU1701, persist AudioProfile in NVS,
expose /api/audio routes and web UI controls, with host tests and manual sync.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-07-06 16:47:58 +02:00
micheleandCursor 81d404a1df Add Slice 4 tuner stack with AGENTS-compliant core types and HTTP API.
Introduces Si4684/ADAU1701 drivers, TunerService, FrequencyKHz,
SeekDirection, /api/tuner routes without file-scope globals, host tests,
and firmware blob tooling (binaries remain gitignored).

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-07-06 16:17:56 +02:00
micheleandCursor ddbee70c23 Add firmware slices 1–2: skeleton and Wi-Fi provisioning
Implement ESP-IDF walking skeleton with SoftAP, health API, and host
tests, then Slice 2 ISecureStore/NvsSecureStore, STA join, POST
/api/wifi, and the provisioning web UI.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-07-06 09:10:37 +02:00
michele 9f04c4bb0c pre-agent-version2 2026-07-06 08:53:33 +02:00