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>
This commit is contained in:
2026-08-21 08:12:08 +02:00
co-authored by Claude Sonnet 5
parent 9ad2e42fe2
commit 3a58d33aad
38 changed files with 1444 additions and 115 deletions
@@ -73,6 +73,10 @@ public:
*
* @dname tuneDab
* @param freqIndex Ensemble index 037.
* @param antCap Front-end antenna varactor override for this one
* tune (e.g. for a calibration sweep). Omit to use
* defaultDabAntCap_ (the board's saved calibration,
* or hardware auto-tune if never calibrated).
* @return Ok on success, or a TunerError from ITuner.
* @pubstate writes lastDabIndex_ on success; clears last-played DAB ids.
*
@@ -80,13 +84,32 @@ public:
* @date 2026-07-06
*/
[[nodiscard]] std::expected<void, core::TunerError> tuneDab(
std::uint8_t freqIndex);
std::uint8_t freqIndex,
std::optional<std::uint8_t> antCap = std::nullopt);
/**
* @brief setDefaultDabAntCap — set the board's calibrated DAB ANTCAP.
*
* @dname setDefaultDabAntCap
* @param antCap Value applied to every DAB tune that doesn't pass an
* explicit override (0 = chip auto-tune, the factory
* default before any calibration is saved).
* @pubstate writes defaultDabAntCap_. Does not itself re-tune.
*
* @author Michele Bigi
* @date 2026-08-20
*/
void setDefaultDabAntCap(std::uint8_t antCap) noexcept;
/**
* @brief tuneFm — tune to an FM centre frequency.
*
* @dname tuneFm
* @param frequency Validated FM centre frequency.
* @param antCap Front-end antenna varactor override for this one
* tune (e.g. for a calibration sweep). Omit to use
* defaultFmAntCap_ (the board's saved calibration,
* or hardware auto-tune if never calibrated).
* @return Ok on success, or a TunerError from ITuner.
* @pubstate writes lastFmFrequency_ on success.
*
@@ -94,7 +117,22 @@ public:
* @date 2026-07-06
*/
[[nodiscard]] std::expected<void, core::TunerError> tuneFm(
core::FrequencyKHz frequency);
core::FrequencyKHz frequency,
std::optional<std::uint8_t> antCap = std::nullopt);
/**
* @brief setDefaultFmAntCap — set the board's calibrated ANTCAP.
*
* @dname setDefaultFmAntCap
* @param antCap Value applied to every FM tune that doesn't pass an
* explicit override (0 = chip auto-tune, the factory
* default before any calibration is saved).
* @pubstate writes defaultFmAntCap_. Does not itself re-tune.
*
* @author Michele Bigi
* @date 2026-08-19
*/
void setDefaultFmAntCap(std::uint8_t antCap) noexcept;
/**
* @brief seekFm — seek FM in the given direction.
@@ -200,6 +238,8 @@ private:
std::uint8_t lastDabIndex_;
core::FrequencyKHz lastFmFrequency_;
std::uint8_t volume_;
std::uint8_t defaultFmAntCap_;
std::uint8_t defaultDabAntCap_;
std::optional<std::uint32_t> lastPlayedServiceId_;
std::optional<std::uint32_t> lastPlayedComponentId_;
};
@@ -138,9 +138,21 @@ TunerService::TunerService(core::ITuner& tuner)
, lastDabIndex_(0U)
, lastFmFrequency_(defaultFmFrequency())
, volume_(40U)
, defaultFmAntCap_(0U)
, defaultDabAntCap_(0U)
{
}
void TunerService::setDefaultFmAntCap(std::uint8_t antCap) noexcept
{
defaultFmAntCap_ = antCap;
}
void TunerService::setDefaultDabAntCap(std::uint8_t antCap) noexcept
{
defaultDabAntCap_ = antCap;
}
std::expected<core::TunerStatus, core::TunerError> TunerService::refreshStatus()
{
auto status = tuner_.readStatus();
@@ -155,9 +167,11 @@ std::expected<core::TunerStatus, core::TunerError> TunerService::refreshStatus()
}
std::expected<void, core::TunerError> TunerService::tuneDab(
std::uint8_t freqIndex)
std::uint8_t freqIndex, std::optional<std::uint8_t> antCap)
{
if (auto result = tuner_.tuneDab(freqIndex); !result) {
if (auto result =
tuner_.tuneDab(freqIndex, antCap.value_or(defaultDabAntCap_));
!result) {
return result;
}
lastDabIndex_ = freqIndex;
@@ -167,9 +181,10 @@ std::expected<void, core::TunerError> TunerService::tuneDab(
}
std::expected<void, core::TunerError> TunerService::tuneFm(
core::FrequencyKHz frequency)
core::FrequencyKHz frequency, std::optional<std::uint8_t> antCap)
{
if (auto result = tuner_.tuneFm(frequency); !result) {
if (auto result = tuner_.tuneFm(frequency, antCap.value_or(defaultFmAntCap_));
!result) {
return result;
}
lastFmFrequency_ = frequency;