GET /api/tuner/status and the full FM band scan always returned an
empty station_name, on every frequency, regardless of signal quality
-- confirmed live on multiple >35 dB SNR channels before this fix.
Three independent problems, found by reading the Si4684 datasheet
(AN649 Rev.2.0) instead of guessing further:
1. FM_RDS_CONFIG (property 0x3C02) was enabled (RDSEN=1) but with both
block-error thresholds at 0 ("no block errors"), so almost any
real-world RDS group -- routine with ordinary multipath/noise, even
on a strong signal -- got rejected from the FIFO outright. Raised
to the datasheet's most tolerant recommended setting (2, "3-5 bit
errors detected and corrected").
2. FM_RDS_INTERRUPT_FIFO_COUNT (property 0x3C01) was never set at all,
defaulting to 0 -- which the datasheet states disables RDSFIFOINT
permanently. Si4684Driver::readFmRds()'s "received" flag reads
exactly that bit (FM_RDS_STATUS RESP4 bit 0), so it could never be
true, and Si4684Tuner::refreshStatus()'s RDS poll loop broke out on
its first iteration every single time, before ever touching the
accumulator. Set to 1 (fire as soon as one group is queued).
3. The real bug, once groups actually started arriving:
RdsMetadataAccumulator::applyGroup() read the two Program Service
name characters from Block C and computed the segment index as
(blockB >> 1) & 0x3. Per ETSI EN 62106 §3.1.5, PS characters for
group type 0 (both 0A and 0B) are always in Block D -- Block C
holds alternate-frequency codes (0A) or a repeated PI code (0B),
never text -- and the segment address is blockB bits[1:0] with no
shift. This function had no dedicated test before now, which is
how a wrong block/bit pair could ship unnoticed: the old test
fixture encoded the same bug in its "expected" input.
Confirmed live after all three fixes: station_name and radiotext both
populate with stable, plausible content across repeated reads (not
noise) on a real broadcast signal.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>