summaryrefslogtreecommitdiff
path: root/src/drivers/include/dac.hpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/drivers/include/dac.hpp')
-rw-r--r--src/drivers/include/dac.hpp73
1 files changed, 73 insertions, 0 deletions
diff --git a/src/drivers/include/dac.hpp b/src/drivers/include/dac.hpp
new file mode 100644
index 00000000..6d025384
--- /dev/null
+++ b/src/drivers/include/dac.hpp
@@ -0,0 +1,73 @@
+#pragma once
+
+#include "gpio-expander.hpp"
+
+#include <stdint.h>
+#include <functional>
+
+#include "esp_err.h"
+#include "result.hpp"
+
+namespace gay_ipod {
+
+/**
+ * Interface for a PCM5122PWR DAC, configured over I2C.
+ */
+class AudioDac {
+ public:
+ enum Error {
+ FAILED_TO_BOOT,
+ FAILED_TO_CONFIGURE,
+ };
+ static auto create(GpioExpander* expander)
+ -> cpp::result<std::unique_ptr<AudioDac>, Error>;
+
+ AudioDac(GpioExpander* gpio);
+ ~AudioDac();
+
+ /**
+ * Sets the volume on a scale from 0 (loudest) to 254 (quietest). A value of
+ * 255 engages the soft mute function.
+ */
+ void WriteVolume(uint8_t volume);
+
+ enum PowerState {
+ POWERDOWN = 0b0,
+ WAIT_FOR_CP = 0b1,
+ CALIBRATION_1 = 0b10,
+ CALIBRATION_2 = 0b11,
+ RAMP_UP = 0b100,
+ RUN = 0b101,
+ SHORT = 0b110,
+ RAMP_DOWN = 0b111,
+ STANDBY = 0b1000,
+ };
+
+ /* Returns the current boot-up status and internal state of the DAC */
+ std::pair<bool, PowerState> ReadPowerState();
+
+ // Not copyable or movable.
+ AudioDac(const AudioDac&) = delete;
+ AudioDac& operator=(const AudioDac&) = delete;
+
+ private:
+ GpioExpander* gpio_;
+
+ /*
+ * Pools the power state for up to 10ms, waiting for the given predicate to
+ * be true.
+ */
+ bool WaitForPowerState(std::function<bool(bool, PowerState)> predicate);
+
+ enum Register {
+ PAGE_SELECT = 0,
+ DE_EMPHASIS = 7,
+ DIGITAL_VOLUME_L = 61,
+ DIGITAL_VOLUME_R = 62,
+ DSP_BOOT_POWER_STATE = 118,
+ };
+
+ void WriteRegister(Register reg, uint8_t val);
+};
+
+} // namespace gay_ipod