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>
This commit is contained in:
2026-07-06 16:47:58 +02:00
co-authored by Cursor
parent 4b931b0aad
commit ab3651e678
58 changed files with 3191 additions and 41 deletions
+1 -1
View File
@@ -3,5 +3,5 @@ idf_component_register(
"main.cpp"
"hardware_bootstrap.cpp"
INCLUDE_DIRS "."
REQUIRES core net secure_store adau1701 si4684 tuner
REQUIRES core net secure_store adau1701 si4684 tuner audio
)
+15
View File
@@ -14,7 +14,10 @@
#include "hardware_bootstrap.hpp"
#include "adau1701/Adau1701Driver.hpp"
#include "adau1701/Adau1701Dsp.hpp"
#include "audio/AudioService.hpp"
#include "board_pins.hpp"
#include "secure_store/NvsAudioProfileStore.hpp"
#include "si4684/Si4684Band.hpp"
#include "si4684/Si4684Driver.hpp"
#include "si4684/Si4684EmbeddedImages.hpp"
@@ -51,6 +54,9 @@ adau1701::Adau1701Driver gAdau1701(
.resetGpio = board::pins::Adau1701Reset,
.i2cAddr7 = board::pins::Adau1701Addr,
});
adau1701::Adau1701Dsp gAdau1701Dsp(gAdau1701);
secure_store::NvsAudioProfileStore gAudioStore;
audio::AudioService gAudioService(gAdau1701Dsp, &gAudioStore);
bool gReady = false;
} // namespace
@@ -74,6 +80,10 @@ std::expected<void, HardwareBootError> HardwareBootstrap::boot()
}
}
if (auto audioResult = gAudioService.loadAndApply(); !audioResult) {
ESP_LOGW(kTag, "ADAU1701 profile apply failed");
}
gReady = true;
ESP_LOGI(kTag, "companion chips ready");
return {};
@@ -84,4 +94,9 @@ si4684::Si4684Tuner& HardwareBootstrap::si4684Tuner()
return gSi4684Tuner;
}
audio::AudioService& HardwareBootstrap::audioService()
{
return gAudioService;
}
} // namespace hardware
+18
View File
@@ -14,6 +14,10 @@
#include <expected>
namespace audio {
class AudioService;
} // namespace audio
namespace si4684 {
class Si4684Tuner;
} // namespace si4684
@@ -75,6 +79,20 @@ public:
* @date 2026-07-06
*/
[[nodiscard]] static si4684::Si4684Tuner& si4684Tuner();
/**
* @brief audioService — borrow the audio orchestration service after boot.
*
* @dname audioService
* @return Reference to the static AudioService instance.
* @pubstate reads static storage initialised by boot().
*
* Valid only after a successful boot() call in the same process.
*
* @author Michele Bigi
* @date 2026-07-06
*/
[[nodiscard]] static audio::AudioService& audioService();
};
} // namespace hardware
+3 -2
View File
@@ -47,7 +47,7 @@ void heartbeatTask(void* arg)
*/
extern "C" void app_main()
{
ESP_LOGI(kTag, "DigiRadio firmware boot — Slice 4");
ESP_LOGI(kTag, "DigiRadio firmware boot — Slice 5");
auto hwResult = hardware::HardwareBootstrap::boot();
if (!hwResult) {
@@ -60,7 +60,8 @@ extern "C" void app_main()
static secure_store::NvsSecureStore store;
auto netResult = net::NetBootstrap::start(store, tunerService);
auto netResult = net::NetBootstrap::start(
store, tunerService, hardware::HardwareBootstrap::audioService());
if (!netResult) {
ESP_LOGE(kTag, "network bootstrap failed");
return;