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:
@@ -3,12 +3,13 @@ set(ADAU_FW_DIR "${CMAKE_CURRENT_LIST_DIR}/../../../Firmware/ADAU1701-Firmware")
|
||||
idf_component_register(
|
||||
SRCS
|
||||
"src/Adau1701Driver.cpp"
|
||||
"src/Adau1701Dsp.cpp"
|
||||
"src/SigmaStudioFW.c"
|
||||
"src/adau1701_program.c"
|
||||
INCLUDE_DIRS
|
||||
"include"
|
||||
"${ADAU_FW_DIR}"
|
||||
REQUIRES driver esp_driver_gpio esp_driver_i2c
|
||||
REQUIRES core driver esp_driver_gpio esp_driver_i2c
|
||||
)
|
||||
|
||||
target_compile_features(${COMPONENT_LIB} PUBLIC cxx_std_23)
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/**
|
||||
* @file Adau1701Driver.hpp
|
||||
* @brief ADAU1701 SigmaDSP driver — RAM boot on every power-up.
|
||||
* @brief ADAU1701 SigmaDSP driver — RAM boot and runtime safeload control.
|
||||
*
|
||||
* DigiRadio firmware — https://github.com/manvalan/DigiRadio
|
||||
*
|
||||
@@ -14,6 +14,15 @@
|
||||
|
||||
#include "adau1701/Adau1701Error.hpp"
|
||||
|
||||
#include "core/AudioProfile.hpp"
|
||||
#include "core/EqBandIndex.hpp"
|
||||
#include "core/EqProfile.hpp"
|
||||
#include "core/FrequencyHz.hpp"
|
||||
#include "core/GainDb.hpp"
|
||||
#include "core/MixSource.hpp"
|
||||
#include "core/MixerState.hpp"
|
||||
|
||||
#include <cstdint>
|
||||
#include <expected>
|
||||
|
||||
namespace adau1701 {
|
||||
@@ -36,7 +45,7 @@ struct Adau1701Pins {
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief Adau1701Driver — owns I2C + reset and loads SigmaStudio RAM.
|
||||
* @brief Adau1701Driver — owns I2C + reset, boot, and safeload runtime.
|
||||
*
|
||||
* @dname Adau1701Driver
|
||||
* @param pins Board wiring for I2C and RESET#.
|
||||
@@ -45,7 +54,8 @@ struct Adau1701Pins {
|
||||
* successful default_download replay.
|
||||
*
|
||||
* Writes the SigmaStudio export from Firmware/ADAU1701-Firmware on every
|
||||
* boot (no EEPROM self-boot on DigiRadio).
|
||||
* boot (no EEPROM self-boot on DigiRadio). Runtime EQ and mixer changes
|
||||
* use the ADAU1701 safeload mechanism.
|
||||
*
|
||||
* @author Michele Bigi
|
||||
* @date 2026-07-06
|
||||
@@ -102,7 +112,104 @@ public:
|
||||
*/
|
||||
[[nodiscard]] bool isBooted() const noexcept;
|
||||
|
||||
/**
|
||||
* @brief applyProfile — safeload mixer, EQ, and master from snapshot.
|
||||
*
|
||||
* @dname applyProfile
|
||||
* @param profile User audio configuration.
|
||||
* @return Ok on success, or Adau1701Error.
|
||||
* @pubstate writes parameter RAM via safeload.
|
||||
*
|
||||
* @author Michele Bigi
|
||||
* @date 2026-07-06
|
||||
*/
|
||||
[[nodiscard]] std::expected<void, Adau1701Error> applyProfile(
|
||||
const core::AudioProfile& profile);
|
||||
|
||||
/**
|
||||
* @brief applyMixer — safeload input and stereo-mixer gains.
|
||||
*
|
||||
* @dname applyMixer
|
||||
* @param mixer Per-source and St Mixer1 levels.
|
||||
* @return Ok on success, or Adau1701Error.
|
||||
* @pubstate writes parameter RAM via safeload.
|
||||
*
|
||||
* @author Michele Bigi
|
||||
* @date 2026-07-06
|
||||
*/
|
||||
[[nodiscard]] std::expected<void, Adau1701Error> applyMixer(
|
||||
const core::MixerState& mixer);
|
||||
|
||||
/**
|
||||
* @brief applyEq — safeload all six PEQ bands.
|
||||
*
|
||||
* @dname applyEq
|
||||
* @param eq Six-band parametric EQ settings.
|
||||
* @return Ok on success, or Adau1701Error.
|
||||
* @pubstate writes parameter RAM via safeload.
|
||||
*
|
||||
* @author Michele Bigi
|
||||
* @date 2026-07-06
|
||||
*/
|
||||
[[nodiscard]] std::expected<void, Adau1701Error> applyEq(
|
||||
const core::EqProfile& eq);
|
||||
|
||||
/**
|
||||
* @brief setInputVolume — safeload one input path gain.
|
||||
*
|
||||
* @dname setInputVolume
|
||||
* @param source Si4684 or ESP32 I2S path.
|
||||
* @param left Left channel gain.
|
||||
* @param right Right channel gain.
|
||||
* @return Ok on success, or Adau1701Error.
|
||||
* @pubstate writes parameter RAM via safeload.
|
||||
*
|
||||
* @author Michele Bigi
|
||||
* @date 2026-07-06
|
||||
*/
|
||||
[[nodiscard]] std::expected<void, Adau1701Error> setInputVolume(
|
||||
core::MixSource source, core::GainDb left, core::GainDb right);
|
||||
|
||||
/**
|
||||
* @brief setMasterVolume — safeload Multiple 1 master output gain.
|
||||
*
|
||||
* @dname setMasterVolume
|
||||
* @param left Left master gain.
|
||||
* @param right Right master gain.
|
||||
* @return Ok on success, or Adau1701Error.
|
||||
* @pubstate writes parameter RAM via safeload.
|
||||
*
|
||||
* @author Michele Bigi
|
||||
* @date 2026-07-06
|
||||
*/
|
||||
[[nodiscard]] std::expected<void, Adau1701Error> setMasterVolume(
|
||||
core::GainDb left, core::GainDb right);
|
||||
|
||||
/**
|
||||
* @brief setEqBand — design and safeload one PEQ band.
|
||||
*
|
||||
* @dname setEqBand
|
||||
* @param band Band index 0..5.
|
||||
* @param gain Band gain in dB.
|
||||
* @param center Centre frequency.
|
||||
* @param q Quality factor.
|
||||
* @return Ok on success, or Adau1701Error.
|
||||
* @pubstate writes five coefficients in one safeload transfer.
|
||||
*
|
||||
* @author Michele Bigi
|
||||
* @date 2026-07-06
|
||||
*/
|
||||
[[nodiscard]] std::expected<void, Adau1701Error> setEqBand(
|
||||
core::EqBandIndex band, core::GainDb gain, core::FrequencyHz center,
|
||||
float q);
|
||||
|
||||
private:
|
||||
[[nodiscard]] std::expected<void, Adau1701Error> ensureBooted() const;
|
||||
[[nodiscard]] std::expected<void, Adau1701Error> safeloadGain(
|
||||
unsigned paramAddr, core::GainDb gain);
|
||||
[[nodiscard]] std::expected<void, Adau1701Error> safeloadFixpoint(
|
||||
unsigned paramAddr, std::int32_t fixpoint);
|
||||
|
||||
Adau1701Pins pins_;
|
||||
bool booted_;
|
||||
void* i2cBus_;
|
||||
|
||||
@@ -0,0 +1,70 @@
|
||||
/**
|
||||
* @file Adau1701Dsp.hpp
|
||||
* @brief core::IDsp adapter over Adau1701Driver.
|
||||
*
|
||||
* DigiRadio firmware — https://github.com/manvalan/DigiRadio
|
||||
*
|
||||
* Copyright 2026 Michele Bigi
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*
|
||||
* @author Michele Bigi
|
||||
* @date 2026-07-06
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
#include "adau1701/Adau1701Driver.hpp"
|
||||
|
||||
#include "core/IDsp.hpp"
|
||||
|
||||
namespace adau1701 {
|
||||
|
||||
/**
|
||||
* @brief Adau1701Dsp — maps core::IDsp to Adau1701Driver safeload API.
|
||||
*
|
||||
* @dname Adau1701Dsp
|
||||
* @return n/a (type)
|
||||
* @pubstate Borrows Adau1701Driver for the process lifetime.
|
||||
*
|
||||
* @author Michele Bigi
|
||||
* @date 2026-07-06
|
||||
*/
|
||||
class Adau1701Dsp final : public core::IDsp {
|
||||
public:
|
||||
/**
|
||||
* @brief Adau1701Dsp — bind to the board driver instance.
|
||||
*
|
||||
* @dname Adau1701Dsp
|
||||
* @param driver Booted ADAU1701 driver (must outlive this adapter).
|
||||
* @pubstate stores driver reference.
|
||||
*
|
||||
* @author Michele Bigi
|
||||
* @date 2026-07-06
|
||||
*/
|
||||
explicit Adau1701Dsp(Adau1701Driver& driver);
|
||||
|
||||
[[nodiscard]] std::expected<void, core::DspError> applyProfile(
|
||||
const core::AudioProfile& profile) override;
|
||||
|
||||
[[nodiscard]] std::expected<void, core::DspError> applyMixer(
|
||||
const core::MixerState& mixer) override;
|
||||
|
||||
[[nodiscard]] std::expected<void, core::DspError> applyEq(
|
||||
const core::EqProfile& eq) override;
|
||||
|
||||
[[nodiscard]] std::expected<void, core::DspError> setInputVolume(
|
||||
core::MixSource source, core::GainDb left, core::GainDb right) override;
|
||||
|
||||
[[nodiscard]] std::expected<void, core::DspError> setMasterVolume(
|
||||
core::GainDb left, core::GainDb right) override;
|
||||
|
||||
[[nodiscard]] std::expected<void, core::DspError> setEqBand(
|
||||
core::EqBandIndex band, core::GainDb gain, core::FrequencyHz center,
|
||||
float q) override;
|
||||
|
||||
private:
|
||||
[[nodiscard]] static core::DspError mapError(Adau1701Error error) noexcept;
|
||||
|
||||
Adau1701Driver& driver_;
|
||||
};
|
||||
|
||||
} // namespace adau1701
|
||||
@@ -28,6 +28,8 @@ enum class Adau1701Error {
|
||||
I2cInitFailed,
|
||||
ResetFailed,
|
||||
DownloadFailed,
|
||||
NotBooted,
|
||||
SafeloadFailed,
|
||||
};
|
||||
|
||||
} // namespace adau1701
|
||||
|
||||
@@ -0,0 +1,77 @@
|
||||
/**
|
||||
* @file Adau1701ParamMap.hpp
|
||||
* @brief SigmaStudio parameter RAM addresses for DigiRadio runtime control.
|
||||
*
|
||||
* DigiRadio firmware — https://github.com/manvalan/DigiRadio
|
||||
*
|
||||
* Copyright 2026 Michele Bigi
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*
|
||||
* @author Michele Bigi
|
||||
* @date 2026-07-06
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
#include "DigiRadio_IC_1_PARAM.h"
|
||||
|
||||
#include "core/EqBandIndex.hpp"
|
||||
#include "core/MixSource.hpp"
|
||||
|
||||
#include <cstdint>
|
||||
|
||||
namespace adau1701 {
|
||||
|
||||
/**
|
||||
* @brief paramAddrEqBandBase — first coefficient address for a PEQ band.
|
||||
*
|
||||
* @dname paramAddrEqBandBase
|
||||
* @param band Band index 0..5.
|
||||
* @return ADDR_PARAMEQ1_STn_B0 from the SigmaStudio export.
|
||||
* @pubstate none
|
||||
*
|
||||
* @author Michele Bigi
|
||||
* @date 2026-07-06
|
||||
*/
|
||||
[[nodiscard]] inline unsigned paramAddrEqBandBase(std::uint8_t band) noexcept
|
||||
{
|
||||
return static_cast<unsigned>(ADDR_PARAMEQ1_ST0_B0)
|
||||
+ static_cast<unsigned>(band) * 5U;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief paramAddrInputLeft — left volume address for an input source.
|
||||
*
|
||||
* @dname paramAddrInputLeft
|
||||
* @param source Si4684 or ESP32 path.
|
||||
* @return Parameter RAM address for the left channel gain cell.
|
||||
* @pubstate none
|
||||
*
|
||||
* @author Michele Bigi
|
||||
* @date 2026-07-06
|
||||
*/
|
||||
[[nodiscard]] inline unsigned paramAddrInputLeft(core::MixSource source) noexcept
|
||||
{
|
||||
return source == core::MixSource::Si4684
|
||||
? static_cast<unsigned>(ADDR_SI4674)
|
||||
: static_cast<unsigned>(ADDR_ESP32);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief paramAddrInputRight — right volume address for an input source.
|
||||
*
|
||||
* @dname paramAddrInputRight
|
||||
* @param source Si4684 or ESP32 path.
|
||||
* @return Parameter RAM address for the right channel gain cell.
|
||||
* @pubstate none
|
||||
*
|
||||
* @author Michele Bigi
|
||||
* @date 2026-07-06
|
||||
*/
|
||||
[[nodiscard]] inline unsigned paramAddrInputRight(core::MixSource source) noexcept
|
||||
{
|
||||
return source == core::MixSource::Si4684
|
||||
? static_cast<unsigned>(ADDR_SI4674_1)
|
||||
: static_cast<unsigned>(ADDR_ESP32_1);
|
||||
}
|
||||
|
||||
} // namespace adau1701
|
||||
@@ -13,6 +13,11 @@
|
||||
|
||||
#include "adau1701/Adau1701Driver.hpp"
|
||||
|
||||
#include "adau1701/Adau1701ParamMap.hpp"
|
||||
|
||||
#include "core/BiquadDesign.hpp"
|
||||
|
||||
#include "DigiRadio_IC_1_PARAM.h"
|
||||
#include "SigmaStudioFW.h"
|
||||
|
||||
#include "driver/gpio.h"
|
||||
@@ -115,4 +120,139 @@ bool Adau1701Driver::isBooted() const noexcept
|
||||
return booted_;
|
||||
}
|
||||
|
||||
std::expected<void, Adau1701Error> Adau1701Driver::ensureBooted() const
|
||||
{
|
||||
if (!booted_) {
|
||||
return std::unexpected(Adau1701Error::NotBooted);
|
||||
}
|
||||
return {};
|
||||
}
|
||||
|
||||
std::expected<void, Adau1701Error> Adau1701Driver::safeloadFixpoint(
|
||||
unsigned paramAddr, std::int32_t fixpoint)
|
||||
{
|
||||
if (sigma_safeload_param(paramAddr, fixpoint) != 0) {
|
||||
return std::unexpected(Adau1701Error::SafeloadFailed);
|
||||
}
|
||||
return {};
|
||||
}
|
||||
|
||||
std::expected<void, Adau1701Error> Adau1701Driver::safeloadGain(
|
||||
unsigned paramAddr, core::GainDb gain)
|
||||
{
|
||||
return safeloadFixpoint(paramAddr, core::gainDbToLinearFixpoint(gain));
|
||||
}
|
||||
|
||||
std::expected<void, Adau1701Error> Adau1701Driver::setInputVolume(
|
||||
core::MixSource source, core::GainDb left, core::GainDb right)
|
||||
{
|
||||
if (auto ready = ensureBooted(); !ready) {
|
||||
return ready;
|
||||
}
|
||||
if (auto result = safeloadGain(paramAddrInputLeft(source), left); !result) {
|
||||
return result;
|
||||
}
|
||||
return safeloadGain(paramAddrInputRight(source), right);
|
||||
}
|
||||
|
||||
std::expected<void, Adau1701Error> Adau1701Driver::setMasterVolume(
|
||||
core::GainDb left, core::GainDb right)
|
||||
{
|
||||
if (auto ready = ensureBooted(); !ready) {
|
||||
return ready;
|
||||
}
|
||||
if (auto result = safeloadGain(static_cast<unsigned>(ADDR_MULTIPLE1), left);
|
||||
!result) {
|
||||
return result;
|
||||
}
|
||||
return safeloadGain(static_cast<unsigned>(ADDR_MULTIPLE1_1), right);
|
||||
}
|
||||
|
||||
std::expected<void, Adau1701Error> Adau1701Driver::applyMixer(
|
||||
const core::MixerState& mixer)
|
||||
{
|
||||
if (auto ready = ensureBooted(); !ready) {
|
||||
return ready;
|
||||
}
|
||||
if (auto result = setInputVolume(core::MixSource::Si4684, mixer.si4684Left,
|
||||
mixer.si4684Right);
|
||||
!result) {
|
||||
return result;
|
||||
}
|
||||
if (auto result = setInputVolume(core::MixSource::Esp32, mixer.esp32Left,
|
||||
mixer.esp32Right);
|
||||
!result) {
|
||||
return result;
|
||||
}
|
||||
if (auto result =
|
||||
safeloadGain(static_cast<unsigned>(ADDR_STMIXER1_ST0_VOLUME),
|
||||
mixer.mixLeft);
|
||||
!result) {
|
||||
return result;
|
||||
}
|
||||
return safeloadGain(static_cast<unsigned>(ADDR_STMIXER1_ST1_VOLUME),
|
||||
mixer.mixRight);
|
||||
}
|
||||
|
||||
std::expected<void, Adau1701Error> Adau1701Driver::setEqBand(
|
||||
core::EqBandIndex band, core::GainDb gain, core::FrequencyHz center, float q)
|
||||
{
|
||||
if (auto ready = ensureBooted(); !ready) {
|
||||
return ready;
|
||||
}
|
||||
|
||||
const core::BiquadCoefficients coeffs =
|
||||
core::designPeakingEq(center, gain, q);
|
||||
const auto fixpoints = coeffs.toFixpoint823();
|
||||
const unsigned baseAddr = paramAddrEqBandBase(band.value());
|
||||
|
||||
unsigned addrs[5U];
|
||||
int values[5U];
|
||||
for (unsigned i = 0U; i < 5U; ++i) {
|
||||
addrs[i] = baseAddr + i;
|
||||
values[i] = fixpoints[i];
|
||||
}
|
||||
|
||||
if (sigma_safeload_block(5U, addrs, values) != 0) {
|
||||
return std::unexpected(Adau1701Error::SafeloadFailed);
|
||||
}
|
||||
return {};
|
||||
}
|
||||
|
||||
std::expected<void, Adau1701Error> Adau1701Driver::applyEq(
|
||||
const core::EqProfile& eq)
|
||||
{
|
||||
if (auto ready = ensureBooted(); !ready) {
|
||||
return ready;
|
||||
}
|
||||
|
||||
for (std::uint8_t i = 0; i < core::EqBandIndex::kBandCount; ++i) {
|
||||
const auto index = core::EqBandIndex::tryFromIndex(i);
|
||||
if (!index) {
|
||||
return std::unexpected(Adau1701Error::SafeloadFailed);
|
||||
}
|
||||
const core::EqBandSettings& band = eq.band(*index);
|
||||
if (auto result = setEqBand(*index, band.gain, band.center, band.q);
|
||||
!result) {
|
||||
return result;
|
||||
}
|
||||
}
|
||||
return {};
|
||||
}
|
||||
|
||||
std::expected<void, Adau1701Error> Adau1701Driver::applyProfile(
|
||||
const core::AudioProfile& profile)
|
||||
{
|
||||
if (auto ready = ensureBooted(); !ready) {
|
||||
return ready;
|
||||
}
|
||||
if (auto result = applyMixer(profile.mixer); !result) {
|
||||
return result;
|
||||
}
|
||||
if (auto result = applyEq(profile.eq); !result) {
|
||||
return result;
|
||||
}
|
||||
return setMasterVolume(profile.masterLeft, profile.masterRight);
|
||||
}
|
||||
|
||||
} // namespace adau1701
|
||||
|
||||
@@ -0,0 +1,90 @@
|
||||
/**
|
||||
* @file Adau1701Dsp.cpp
|
||||
* @brief Adau1701Dsp implementation.
|
||||
*
|
||||
* DigiRadio firmware — https://github.com/manvalan/DigiRadio
|
||||
*
|
||||
* Copyright 2026 Michele Bigi
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*
|
||||
* @author Michele Bigi
|
||||
* @date 2026-07-06
|
||||
*/
|
||||
|
||||
#include "adau1701/Adau1701Dsp.hpp"
|
||||
|
||||
namespace adau1701 {
|
||||
|
||||
Adau1701Dsp::Adau1701Dsp(Adau1701Driver& driver)
|
||||
: driver_(driver)
|
||||
{
|
||||
}
|
||||
|
||||
core::DspError Adau1701Dsp::mapError(Adau1701Error error) noexcept
|
||||
{
|
||||
switch (error) {
|
||||
case Adau1701Error::NotBooted:
|
||||
return core::DspError::NotBooted;
|
||||
case Adau1701Error::SafeloadFailed:
|
||||
return core::DspError::SafeloadFailed;
|
||||
default:
|
||||
return core::DspError::SafeloadFailed;
|
||||
}
|
||||
}
|
||||
|
||||
std::expected<void, core::DspError> Adau1701Dsp::applyProfile(
|
||||
const core::AudioProfile& profile)
|
||||
{
|
||||
if (auto result = driver_.applyProfile(profile); !result) {
|
||||
return std::unexpected(mapError(result.error()));
|
||||
}
|
||||
return {};
|
||||
}
|
||||
|
||||
std::expected<void, core::DspError> Adau1701Dsp::applyMixer(
|
||||
const core::MixerState& mixer)
|
||||
{
|
||||
if (auto result = driver_.applyMixer(mixer); !result) {
|
||||
return std::unexpected(mapError(result.error()));
|
||||
}
|
||||
return {};
|
||||
}
|
||||
|
||||
std::expected<void, core::DspError> Adau1701Dsp::applyEq(
|
||||
const core::EqProfile& eq)
|
||||
{
|
||||
if (auto result = driver_.applyEq(eq); !result) {
|
||||
return std::unexpected(mapError(result.error()));
|
||||
}
|
||||
return {};
|
||||
}
|
||||
|
||||
std::expected<void, core::DspError> Adau1701Dsp::setInputVolume(
|
||||
core::MixSource source, core::GainDb left, core::GainDb right)
|
||||
{
|
||||
if (auto result = driver_.setInputVolume(source, left, right); !result) {
|
||||
return std::unexpected(mapError(result.error()));
|
||||
}
|
||||
return {};
|
||||
}
|
||||
|
||||
std::expected<void, core::DspError> Adau1701Dsp::setMasterVolume(
|
||||
core::GainDb left, core::GainDb right)
|
||||
{
|
||||
if (auto result = driver_.setMasterVolume(left, right); !result) {
|
||||
return std::unexpected(mapError(result.error()));
|
||||
}
|
||||
return {};
|
||||
}
|
||||
|
||||
std::expected<void, core::DspError> Adau1701Dsp::setEqBand(
|
||||
core::EqBandIndex band, core::GainDb gain, core::FrequencyHz center,
|
||||
float q)
|
||||
{
|
||||
if (auto result = driver_.setEqBand(band, gain, center, q); !result) {
|
||||
return std::unexpected(mapError(result.error()));
|
||||
}
|
||||
return {};
|
||||
}
|
||||
|
||||
} // namespace adau1701
|
||||
@@ -58,3 +58,78 @@ void SIGMA_WRITE_REGISTER_BLOCK(unsigned char devAddress,
|
||||
remaining = (unsigned char)(remaining - chunk);
|
||||
}
|
||||
}
|
||||
|
||||
static int sigma_i2c_write(unsigned int reg, const unsigned char* data,
|
||||
unsigned char length)
|
||||
{
|
||||
if (s_dev == NULL || data == NULL || length == 0U) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
unsigned char buf[2U + 4U];
|
||||
if ((size_t)length + 2U > sizeof(buf)) {
|
||||
return -1;
|
||||
}
|
||||
buf[0] = (unsigned char)((reg >> 8) & 0xFFU);
|
||||
buf[1] = (unsigned char)(reg & 0xFFU);
|
||||
memcpy(buf + 2U, data, length);
|
||||
const esp_err_t err =
|
||||
i2c_master_transmit(s_dev, buf, (size_t)(2U + length), 1000);
|
||||
return err == ESP_OK ? 0 : -1;
|
||||
}
|
||||
|
||||
static int sigma_write_fixpoint_reg(unsigned int reg, int fixpoint)
|
||||
{
|
||||
unsigned char payload[4U];
|
||||
payload[0] = 0U;
|
||||
payload[1] = (unsigned char)((fixpoint >> 16) & 0xFFU);
|
||||
payload[2] = (unsigned char)((fixpoint >> 8) & 0xFFU);
|
||||
payload[3] = (unsigned char)(fixpoint & 0xFFU);
|
||||
return sigma_i2c_write(reg, payload, 4U);
|
||||
}
|
||||
|
||||
static int sigma_write_param_addr(unsigned int reg, unsigned int paramAddr)
|
||||
{
|
||||
unsigned char payload[2U];
|
||||
payload[0] = (unsigned char)((paramAddr >> 8) & 0xFFU);
|
||||
payload[1] = (unsigned char)(paramAddr & 0xFFU);
|
||||
return sigma_i2c_write(reg, payload, 2U);
|
||||
}
|
||||
|
||||
static int sigma_trigger_safeload(void)
|
||||
{
|
||||
unsigned char payload[2U];
|
||||
payload[0] = (unsigned char)((ADAU1701_CORE_IST_TRIGGER >> 8) & 0xFFU);
|
||||
payload[1] = (unsigned char)(ADAU1701_CORE_IST_TRIGGER & 0xFFU);
|
||||
return sigma_i2c_write(ADAU1701_CORE_CONTROL_REG, payload, 2U);
|
||||
}
|
||||
|
||||
int sigma_safeload_param(unsigned int paramAddr, int fixpoint)
|
||||
{
|
||||
const unsigned int addrs[1U] = {paramAddr};
|
||||
const int values[1U] = {fixpoint};
|
||||
return sigma_safeload_block(1U, addrs, values);
|
||||
}
|
||||
|
||||
int sigma_safeload_block(unsigned char count, const unsigned int* paramAddrs,
|
||||
const int* fixpoints)
|
||||
{
|
||||
if (count == 0U || count > 5U || paramAddrs == NULL || fixpoints == NULL) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
for (unsigned char i = 0U; i < count; ++i) {
|
||||
const unsigned int dataReg =
|
||||
ADAU1701_SAFELOAD_DATA_BASE + (unsigned int)i;
|
||||
const unsigned int addrReg =
|
||||
ADAU1701_SAFELOAD_ADDR_BASE + (unsigned int)i;
|
||||
if (sigma_write_fixpoint_reg(dataReg, fixpoints[i]) != 0) {
|
||||
return -1;
|
||||
}
|
||||
if (sigma_write_param_addr(addrReg, paramAddrs[i]) != 0) {
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
return sigma_trigger_safeload();
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user