diff options
| author | jacqueline <me@jacqueline.id.au> | 2022-10-12 11:59:42 +1100 |
|---|---|---|
| committer | jacqueline <me@jacqueline.id.au> | 2022-10-12 11:59:42 +1100 |
| commit | 4fc5f931acf5bdc582fdad3cb48e6810964198c5 (patch) | |
| tree | 9057debaa13ec996450a63adf5f3228cd5ff1b54 /main/dac.cpp | |
| parent | efd5392f6cf2149369d7d3170400bbe8f2d5c82e (diff) | |
| download | tangara-fw-4fc5f931acf5bdc582fdad3cb48e6810964198c5.tar.gz | |
WIP use result<> and RAII
Diffstat (limited to 'main/dac.cpp')
| -rw-r--r-- | main/dac.cpp | 93 |
1 files changed, 54 insertions, 39 deletions
diff --git a/main/dac.cpp b/main/dac.cpp index 513793db..0e34c98f 100644 --- a/main/dac.cpp +++ b/main/dac.cpp @@ -1,41 +1,56 @@ #include "dac.h" -#include "esp_err.h" -#include "i2c.h" -#include "esp_log.h" +#include <cstdint> + #include "assert.h" #include "driver/i2c.h" +#include "esp_err.h" +#include "esp_log.h" #include "gpio-expander.h" #include "hal/i2c_types.h" -#include <cstdint> +#include "i2c.h" namespace gay_ipod { -static const char* TAG = "AUDIODAC"; - -AudioDac::AudioDac(GpioExpander *gpio) { - this->gpio_ = gpio; -}; +static const char* kTag = "AUDIODAC"; +static const uint8_t kPcm5122Address = 0x4C; +static const uint8_t kPcm5122Timeout = 100 / portTICK_RATE_MS; -AudioDac::~AudioDac() {}; +auto AudioDac::create(GpioExpander* expander) + -> cpp::result<std::unique_ptr<AudioDac>, Error> { + std::unique_ptr<AudioDac> dac = std::make_unique<AudioDac>(expander); -esp_err_t AudioDac::Start() { - bool is_booted = WaitForPowerState([](bool booted, PowerState state){ return booted; }); + bool is_booted = dac->WaitForPowerState( + [](bool booted, PowerState state) { return booted; }); if (!is_booted) { - ESP_LOGE(TAG, "Timed out waiting for boot"); - return ESP_ERR_TIMEOUT; + ESP_LOGE(kTag, "Timed out waiting for boot"); + return cpp::fail(Error::FAILED_TO_BOOT); } - WriteRegister(Register::DE_EMPHASIS, 1 << 4); - WriteVolume(100); + dac->WriteRegister(Register::DE_EMPHASIS, 1 << 4); + dac->WriteVolume(100); - WaitForPowerState([](bool booted, PowerState state){ - return state == WAIT_FOR_CP || state == RAMP_UP || state == RUN || state == STANDBY; - }); + bool is_configured = + dac->WaitForPowerState([](bool booted, PowerState state) { + return state == WAIT_FOR_CP || state == RAMP_UP || state == RUN || + state == STANDBY; + }); + if (!is_configured) { + return cpp::fail(Error::FAILED_TO_CONFIGURE); + } - return ESP_OK; + return dac; } +AudioDac::AudioDac(GpioExpander* gpio) { + this->gpio_ = gpio; +}; + +AudioDac::~AudioDac(){ + // TODO: reset stuff like de-emphasis? Reboot the whole dac? Need to think + // about this. +}; + void AudioDac::WriteVolume(uint8_t volume) { WriteRegister(Register::DIGITAL_VOLUME_L, volume); WriteRegister(Register::DIGITAL_VOLUME_R, volume); @@ -45,31 +60,32 @@ std::pair<bool, AudioDac::PowerState> AudioDac::ReadPowerState() { uint8_t result = 0; I2CTransaction transaction; - transaction - .start() - .write_addr(kPCM5122Address, I2C_MASTER_WRITE) - .write_ack(DSP_BOOT_POWER_STATE) - .start() - .write_addr(kPCM5122Address, I2C_MASTER_READ) - .read(&result, I2C_MASTER_NACK) - .stop(); + transaction.start() + .write_addr(kPcm5122Address, I2C_MASTER_WRITE) + .write_ack(DSP_BOOT_POWER_STATE) + .start() + .write_addr(kPcm5122Address, I2C_MASTER_READ) + .read(&result, I2C_MASTER_NACK) + .stop(); ESP_ERROR_CHECK(transaction.Execute()); bool is_booted = result >> 7; - PowerState detail = (PowerState) (result & 0b1111); + PowerState detail = (PowerState)(result & 0b1111); return std::pair(is_booted, detail); } -bool AudioDac::WaitForPowerState(std::function<bool(bool,AudioDac::PowerState)> predicate) { +bool AudioDac::WaitForPowerState( + std::function<bool(bool, AudioDac::PowerState)> predicate) { bool has_matched = false; - for (int i=0; i<10; i++) { + for (int i = 0; i < 10; i++) { std::pair<bool, PowerState> result = ReadPowerState(); has_matched = predicate(result.first, result.second); if (has_matched) { break; } else { - ESP_LOGI(TAG, "Waiting for power state (was %d %x)", result.first, (uint8_t) result.second); + ESP_LOGI(kTag, "Waiting for power state (was %d %x)", result.first, + (uint8_t)result.second); vTaskDelay(pdMS_TO_TICKS(1)); } } @@ -77,14 +93,13 @@ bool AudioDac::WaitForPowerState(std::function<bool(bool,AudioDac::PowerState)> } void AudioDac::WriteRegister(Register reg, uint8_t val) { - I2CTransaction transaction; - transaction - .start() - .write_addr(kPCM5122Address, I2C_MASTER_WRITE) + I2CTransaction transaction; + transaction.start() + .write_addr(kPcm5122Address, I2C_MASTER_WRITE) .write_ack(reg, val) .stop(); - // TODO: Retry once? - ESP_ERROR_CHECK(transaction.Execute()); + // TODO: Retry once? + ESP_ERROR_CHECK(transaction.Execute()); } -} // namespace gay_ipod +} // namespace gay_ipod |
