Si4684 RF investigation report; fix ADAU1701 I2C reliability under long safeload bursts

- Add docs/si4684-rf-investigation-report.md: full record of the FM/DAB no-lock
  investigation (crystal, front-end matching, ANTCAP sweep, continuity, leading
  EP solder-defect hypothesis, PCBWay report sent) plus the separate audio
  profile NVS bug found and partially fixed this session.
- Fix sigma_i2c_write() (SigmaStudioFW.c): no retry on I2C failure meant a single
  transient NACK anywhere in a long safeload burst (EQ apply = ~55 sequential
  transactions) aborted the whole sequence. Added a 3-attempt retry.
- Add granular failure logging (AudioService::applyProfileToDsp/persistProfile,
  Adau1701Driver::applyMixer/applyEq, NvsAudioProfileStore::saveProfile error
  codes) to isolate the remaining NVS-side audio profile save failure.
- Si4684Driver::tuneFm gains an optional ANTCAP argument (default 0 = unchanged
  auto-tune behavior) used during this session's front-end matching sweep.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
2026-08-13 22:21:04 +02:00
co-authored by Claude Sonnet 5
parent 6f7b6dd12c
commit bee8cfa86f
7 changed files with 193 additions and 13 deletions
@@ -690,7 +690,7 @@ Si4684Band Si4684Driver::loadedBand() const noexcept
}
std::expected<void, Si4684Error> Si4684Driver::tuneFm(
core::FrequencyKHz frequency)
core::FrequencyKHz frequency, std::uint8_t antCap)
{
if (auto band = ensureBand(Si4684Band::Fm); !band) {
return band;
@@ -703,8 +703,8 @@ std::expected<void, Si4684Error> Si4684Driver::tuneFm(
0x00U,
static_cast<std::uint8_t>(chipFreq & 0xFFU),
static_cast<std::uint8_t>(chipFreq >> 8),
0x00U,
0x00U,
antCap, // ANTCAP[7:0] -- 0 = auto (FE_VARM/VARB), else forced value
0x00U, // ANTCAP[15:8] -- range is 0-128, high byte always 0
0x00U, // PROG_ID (AN649 ARG6; ignored when DIR_TUNE=0)
};
if (auto cmd = writeCommand(Command::FmTuneFreq, args, sizeof(args));
@@ -728,8 +728,10 @@ std::expected<void, Si4684Error> Si4684Driver::tuneFm(
static_cast<unsigned>(readKhz));
}
ESP_LOGI(kTag,
"FM tuned %u kHz rssi=%d dBuV snr=%d dB valid=%d readfreq=%u",
"FM tuned %u kHz antcap=%u rssi=%d dBuV snr=%d dB valid=%d "
"readfreq=%u",
static_cast<unsigned>(frequency.value()),
static_cast<unsigned>(antCap),
static_cast<int>(rsq->rssiDbuV),
static_cast<int>(rsq->snrDb),
static_cast<int>(rsq->valid),