Fix Si4684 I2S audio: PIN_CONFIG_ENABLE conflict + ADAU1701 BCLK polarity
Two independent bugs silenced the digital audio path from Si4684 into the ADAU1701 even after the FM/DAB tune fix produced a real RF lock: 1. Si4684Driver::configureAfterBoot() wrote PIN_CONFIG_ENABLE (0x0800) as 0x0003, enabling both I2SOUTEN and DACOUTEN. AN649: "only I2SOUTEN or DACOUTEN can be enabled at a time. If both enabled, only analog audio output is enabled" — the chip silently fell back to its unused analog DAC output on every boot. Fixed to 0x8002 (I2SOUTEN + INTBOUTEN), matching the value hitech95/si468x_dab_receiver's working ALSA codec driver uses (SI468X_PROP_I2S_ENABLED); I2SOUTEN alone (0x0002) was not sufficient on this hardware. Also fixed AUDIO_OUTPUT_CONFIG (0x0302), which was being written with a stray I2S-enable bit that property does not have (its only real field is bit0 MONO). 2. Even with the chip correctly outputting I2S, the ADAU1701 received only static. Traced with SIGMA_WRITE_REGISTER_BLOCK live overrides of SerialInputRegister (0x081F, baked into the compiled SigmaStudio export at ILP=0/IBP=0): IBP=1 (input data clocked on the opposite BCLK edge) produced real, recognizable music instead of static on a locked, strong FM signal — first confirmed end-to-end audio in this project's history. ILP=1 made it worse and was reverted; IBP=1 kept as a runtime override in Adau1701Driver::boot(). Remaining noise on top of the music is attributed to antenna quality (RSSI/SNR fluctuated significantly between retunes of the same station on the current improvised antenna) — not yet confirmed with a proper antenna. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_0178rASQ6ZETPMUamvpoR2KR
This commit is contained in:
@@ -56,8 +56,11 @@ constexpr std::uint16_t kPropPinConfigEnable = 0x0800U;
|
||||
constexpr std::uint16_t kPropAudioVolume = 0x0300U;
|
||||
constexpr std::uint16_t kPropAudioMute = 0x0301U;
|
||||
constexpr std::uint16_t kPropAudioOutputConfig = 0x0302U;
|
||||
/** AN649 AUDIO_OUTPUT_CONFIG bit1 I2SOUTEN — required for I2S to ADAU1701. */
|
||||
constexpr std::uint16_t kSi4684I2sOutEnable = 0x0002U;
|
||||
/** AN649 PIN_CONFIG_ENABLE bit1 I2SOUTEN + bit15 INTBOUTEN — matches the
|
||||
* value used by hitech95/si468x_dab_receiver's working ALSA codec driver
|
||||
* (SI468X_PROP_I2S_ENABLED = 0x8002); INTBOUTEN alone (0x0002) was not
|
||||
* sufficient to produce audio on real hardware in this project. */
|
||||
constexpr std::uint16_t kSi4684I2sOutEnable = 0x8002U;
|
||||
/** Si4684 volume: 0=mute, 63=max (AN649 AUDIO_ANALOG_VOLUME). */
|
||||
constexpr std::uint8_t kSi4684VolumeMax = 63U;
|
||||
constexpr std::uint16_t kPropFmRdsConfig = 0x3C02U;
|
||||
@@ -560,14 +563,21 @@ std::expected<void, Si4684Error> Si4684Driver::configureAfterBoot(
|
||||
!rate) {
|
||||
return rate;
|
||||
}
|
||||
if (auto pins = setProperty(kPropPinConfigEnable, 0x0003U); !pins) {
|
||||
// AN649 Property 0x0800 PIN_CONFIG_ENABLE bit1=I2SOUTEN, bit0=DACOUTEN:
|
||||
// "only I2SOUTEN or DACOUTEN can be enabled at a time. If both enabled,
|
||||
// only analog audio output is enabled." We only wire I2S to the
|
||||
// ADAU1701 (no DAC pins connected), so DACOUTEN must stay 0 or the chip
|
||||
// silently falls back to analog-only and the I2S bus carries silence.
|
||||
if (auto pins = setProperty(kPropPinConfigEnable, kSi4684I2sOutEnable);
|
||||
!pins) {
|
||||
return pins;
|
||||
}
|
||||
if (auto mute = setProperty(kPropAudioMute, 0x0000U); !mute) {
|
||||
return mute;
|
||||
}
|
||||
if (auto outCfg = setProperty(kPropAudioOutputConfig, kSi4684I2sOutEnable);
|
||||
!outCfg) {
|
||||
// AN649 Property 0x0302 AUDIO_OUTPUT_CONFIG bit0=MONO (all other bits
|
||||
// reserved, must be 0). Not an I2S enable — that lives at 0x0800 above.
|
||||
if (auto outCfg = setProperty(kPropAudioOutputConfig, 0x0000U); !outCfg) {
|
||||
return outCfg;
|
||||
}
|
||||
if (auto vol = setProperty(kPropAudioVolume, kSi4684VolumeMax); !vol) {
|
||||
|
||||
Reference in New Issue
Block a user