summaryrefslogtreecommitdiff
path: root/main/dac.cpp
diff options
context:
space:
mode:
authorjacqueline <me@jacqueline.id.au>2022-10-12 11:59:42 +1100
committerjacqueline <me@jacqueline.id.au>2022-10-12 11:59:42 +1100
commit4fc5f931acf5bdc582fdad3cb48e6810964198c5 (patch)
tree9057debaa13ec996450a63adf5f3228cd5ff1b54 /main/dac.cpp
parentefd5392f6cf2149369d7d3170400bbe8f2d5c82e (diff)
downloadtangara-fw-4fc5f931acf5bdc582fdad3cb48e6810964198c5.tar.gz
WIP use result<> and RAII
Diffstat (limited to 'main/dac.cpp')
-rw-r--r--main/dac.cpp93
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