#pragma once #include "gpio-expander.hpp" #include #include #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, 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 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 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