summaryrefslogtreecommitdiff
path: root/src/drivers/include
diff options
context:
space:
mode:
Diffstat (limited to 'src/drivers/include')
-rw-r--r--src/drivers/include/dac.hpp127
-rw-r--r--src/drivers/include/display.hpp3
-rw-r--r--src/drivers/include/driver_cache.hpp54
-rw-r--r--src/drivers/include/gpio_expander.hpp76
-rw-r--r--src/drivers/include/i2c.hpp2
-rw-r--r--src/drivers/include/storage.hpp7
-rw-r--r--src/drivers/include/touchwheel.hpp49
7 files changed, 248 insertions, 70 deletions
diff --git a/src/drivers/include/dac.hpp b/src/drivers/include/dac.hpp
index 06808a78..4952c992 100644
--- a/src/drivers/include/dac.hpp
+++ b/src/drivers/include/dac.hpp
@@ -12,6 +12,7 @@
#include "esp_err.h"
#include "freertos/FreeRTOS.h"
#include "freertos/portmacro.h"
+#include "freertos/stream_buffer.h"
#include "result.hpp"
#include "span.hpp"
@@ -20,6 +21,91 @@
namespace drivers {
+namespace pcm512x {
+class Register {
+ public:
+ uint8_t page;
+ uint8_t reg;
+
+ constexpr Register(uint8_t p, uint8_t r) : page(p), reg(r) {}
+};
+
+constexpr Register RESET(0, 1);
+constexpr Register POWER(0, 2);
+constexpr Register MUTE(0, 3);
+constexpr Register PLL_EN(0, 4);
+constexpr Register SPI_MISO_FUNCTION(0, 6);
+constexpr Register DSP(0, 7);
+constexpr Register GPIO_EN(0, 8);
+constexpr Register BCLK_LRCLK_CFG(0, 9);
+constexpr Register DSP_GPIO_INPUT(0, 10);
+constexpr Register MASTER_MODE(0, 12);
+constexpr Register PLL_REF(0, 13);
+constexpr Register DAC_REF(0, 14);
+constexpr Register GPIO_DACIN(0, 16);
+constexpr Register GPIO_PLLIN(0, 18);
+constexpr Register SYNCHRONIZE(0, 19);
+constexpr Register PLL_COEFF_0(0, 20);
+constexpr Register PLL_COEFF_1(0, 21);
+constexpr Register PLL_COEFF_2(0, 22);
+constexpr Register PLL_COEFF_3(0, 23);
+constexpr Register PLL_COEFF_4(0, 24);
+constexpr Register DSP_CLKDIV(0, 27);
+constexpr Register DAC_CLKDIV(0, 28);
+constexpr Register NCP_CLKDIV(0, 29);
+constexpr Register OSR_CLKDIV(0, 30);
+constexpr Register MASTER_CLKDIV_1(0, 32);
+constexpr Register MASTER_CLKDIV_2(0, 33);
+constexpr Register FS_SPEED_MODE(0, 34);
+constexpr Register IDAC_1(0, 35);
+constexpr Register IDAC_2(0, 36);
+constexpr Register ERROR_DETECT(0, 37);
+constexpr Register I2S_1(0, 40);
+constexpr Register I2S_2(0, 41);
+constexpr Register DAC_ROUTING(0, 42);
+constexpr Register DSP_PROGRAM(0, 43);
+constexpr Register CLKDET(0, 44);
+constexpr Register AUTO_MUTE(0, 59);
+constexpr Register DIGITAL_VOLUME_1(0, 60);
+constexpr Register DIGITAL_VOLUME_2(0, 61);
+constexpr Register DIGITAL_VOLUME_3(0, 62);
+constexpr Register DIGITAL_MUTE_1(0, 63);
+constexpr Register DIGITAL_MUTE_2(0, 64);
+constexpr Register DIGITAL_MUTE_3(0, 65);
+constexpr Register GPIO_OUTPUT_1(0, 80);
+constexpr Register GPIO_OUTPUT_2(0, 81);
+constexpr Register GPIO_OUTPUT_3(0, 82);
+constexpr Register GPIO_OUTPUT_4(0, 83);
+constexpr Register GPIO_OUTPUT_5(0, 84);
+constexpr Register GPIO_OUTPUT_6(0, 85);
+constexpr Register GPIO_CONTROL_1(0, 86);
+constexpr Register GPIO_CONTROL_2(0, 87);
+constexpr Register OVERFLOW(0, 90);
+constexpr Register RATE_DET_1(0, 91);
+constexpr Register RATE_DET_2(0, 92);
+constexpr Register RATE_DET_3(0, 93);
+constexpr Register RATE_DET_4(0, 94);
+constexpr Register CLOCK_STATUS(0, 95);
+constexpr Register ANALOG_MUTE_DET(0, 108);
+constexpr Register POWER_STATE(0, 118);
+constexpr Register GPIN(0, 119);
+constexpr Register DIGITAL_MUTE_DET(0, 120);
+
+constexpr Register OUTPUT_AMPLITUDE(1, 1);
+constexpr Register ANALOG_GAIN_CTRL(1, 2);
+constexpr Register UNDERVOLTAGE_PROT(1, 5);
+constexpr Register ANALOG_MUTE_CTRL(1, 6);
+constexpr Register ANALOG_GAIN_BOOST(1, 7);
+constexpr Register VCOM_CTRL_1(1, 8);
+constexpr Register VCOM_CTRL_2(1, 9);
+
+constexpr Register CRAM_CTRL(44, 1);
+
+constexpr Register FLEX_A(253, 63);
+constexpr Register FLEX_B(253, 64);
+
+} // namespace pcm512x
+
/**
* Interface for a PCM5122PWR DAC, configured over I2C.
*/
@@ -31,8 +117,7 @@ class AudioDac {
FAILED_TO_INSTALL_I2S,
};
- static auto create(GpioExpander* expander)
- -> cpp::result<std::unique_ptr<AudioDac>, Error>;
+ static auto create(GpioExpander* expander) -> cpp::result<AudioDac*, Error>;
AudioDac(GpioExpander* gpio, i2s_chan_handle_t i2s_handle);
~AudioDac();
@@ -64,14 +149,21 @@ class AudioDac {
BPS_32 = I2S_DATA_BIT_WIDTH_32BIT,
};
enum SampleRate {
+ SAMPLE_RATE_11_025 = 11025,
+ SAMPLE_RATE_16 = 16000,
+ SAMPLE_RATE_22_05 = 22050,
+ SAMPLE_RATE_32 = 32000,
SAMPLE_RATE_44_1 = 44100,
SAMPLE_RATE_48 = 48000,
+ SAMPLE_RATE_96 = 96000,
+ SAMPLE_RATE_192 = 192000,
};
// TODO(jacqueline): worth supporting channels here as well?
auto Reconfigure(BitsPerSample bps, SampleRate rate) -> void;
- auto WriteData(cpp::span<std::byte> data) -> std::size_t;
+ auto WriteData(const cpp::span<const std::byte>& data) -> void;
+ auto SetSource(StreamBufferHandle_t buffer) -> void;
auto Stop() -> void;
auto LogStatus() -> void;
@@ -83,6 +175,8 @@ class AudioDac {
private:
GpioExpander* gpio_;
i2s_chan_handle_t i2s_handle_;
+ bool i2s_active_;
+ std::optional<uint8_t> active_page_;
i2s_std_clk_config_t clock_config_;
i2s_std_slot_config_t slot_config_;
@@ -93,29 +187,12 @@ class AudioDac {
*/
bool WaitForPowerState(std::function<bool(bool, PowerState)> predicate);
- enum Register {
- PAGE_SELECT = 0,
- RESET = 1,
- POWER_MODE = 2,
- DE_EMPHASIS = 7,
- DAC_CLOCK_SOURCE = 14,
- CLOCK_ERRORS = 37,
- I2S_FORMAT = 40,
- DIGITAL_VOLUME_L = 61,
- DIGITAL_VOLUME_R = 62,
-
- SAMPLE_RATE_DETECTION = 91,
- BCK_DETECTION = 93,
- CLOCK_ERROR_STATE = 94,
- CLOCK_STATUS = 95,
- AUTO_MUTE_STATE = 108,
- SOFT_MUTE_STATE = 114,
- SAMPLE_RATE_STATE = 115,
- DSP_BOOT_POWER_STATE = 118,
- };
+ void WriteRegister(pcm512x::Register r, uint8_t val);
+ uint8_t ReadRegister(pcm512x::Register r);
- void WriteRegister(Register reg, uint8_t val);
- uint8_t ReadRegister(Register reg);
+ void SelectPage(uint8_t page);
+ void WriteRegisterRaw(uint8_t reg, uint8_t val);
+ uint8_t ReadRegisterRaw(uint8_t reg);
};
} // namespace drivers
diff --git a/src/drivers/include/display.hpp b/src/drivers/include/display.hpp
index 8157c3a5..9e4a0224 100644
--- a/src/drivers/include/display.hpp
+++ b/src/drivers/include/display.hpp
@@ -23,8 +23,7 @@ class Display {
* us back any kind of signal to tell us we're actually using them correctly.
*/
static auto create(GpioExpander* expander,
- const displays::InitialisationData& init_data)
- -> std::unique_ptr<Display>;
+ const displays::InitialisationData& init_data) -> Display*;
Display(GpioExpander* gpio, spi_device_handle_t handle);
~Display();
diff --git a/src/drivers/include/driver_cache.hpp b/src/drivers/include/driver_cache.hpp
new file mode 100644
index 00000000..c56ebc3f
--- /dev/null
+++ b/src/drivers/include/driver_cache.hpp
@@ -0,0 +1,54 @@
+#pragma once
+
+#include <memory>
+#include <mutex>
+
+#include "dac.hpp"
+#include "display.hpp"
+#include "gpio_expander.hpp"
+#include "storage.hpp"
+#include "touchwheel.hpp"
+
+namespace drivers {
+
+class DriverCache {
+ private:
+ std::unique_ptr<GpioExpander> gpios_;
+ std::weak_ptr<AudioDac> dac_;
+ std::weak_ptr<Display> display_;
+ std::weak_ptr<SdStorage> storage_;
+ std::weak_ptr<TouchWheel> touchwheel_;
+ // TODO(jacqueline): Haptics, samd
+
+ std::mutex mutex_;
+
+ template <typename T, typename F>
+ auto Acquire(std::weak_ptr<T> ptr, F factory) -> std::shared_ptr<T> {
+ std::shared_ptr<T> acquired = ptr.lock();
+ if (acquired) {
+ return acquired;
+ }
+
+ std::lock_guard<std::mutex> lock(mutex_);
+
+ acquired = ptr.lock();
+ if (acquired) {
+ return acquired;
+ }
+ acquired.reset(factory());
+ ptr = acquired;
+ return acquired;
+ }
+
+ public:
+ DriverCache();
+ ~DriverCache();
+
+ auto AcquireGpios() -> GpioExpander*;
+ auto AcquireDac() -> std::shared_ptr<AudioDac>;
+ auto AcquireDisplay() -> std::shared_ptr<Display>;
+ auto AcquireStorage() -> std::shared_ptr<SdStorage>;
+ auto AcquireTouchWheel() -> std::shared_ptr<TouchWheel>;
+};
+
+} // namespace drivers
diff --git a/src/drivers/include/gpio_expander.hpp b/src/drivers/include/gpio_expander.hpp
index a6e96d87..cd3719a0 100644
--- a/src/drivers/include/gpio_expander.hpp
+++ b/src/drivers/include/gpio_expander.hpp
@@ -35,28 +35,28 @@ class GpioExpander {
static const uint8_t kPca8575Timeout = pdMS_TO_TICKS(100);
// Port A:
- // 0 - audio power enable
- // 1 - usb interface power enable (active low)
- // 2 - display power enable
- // 3 - touchpad power enable
- // 4 - sd card power enable
- // 5 - sd mux switch
- // 6 - LDO enable
- // 7 - charge power ok (active low)
- // All power switches low, sd mux pointing away from us, inputs high.
- static const uint8_t kPortADefault = 0b10000010;
+ // 0 - sd card mux switch
+ // 1 - sd card mux enable (active low)
+ // 2 - key up
+ // 3 - key down
+ // 4 - key lock
+ // 5 - display reset
+ // 6 - NC
+ // 7 - sd card power (active low)
+ // Default to SD card off, inputs high.
+ static const uint8_t kPortADefault = 0b10111110;
// Port B:
- // 0 - 3.5mm jack detect (active low)
- // 1 - unused
- // 2 - volume up
- // 3 - volume down
- // 4 - lock switch
- // 5 - touchpad interupt
- // 6 - display DR
- // 7 - display LED
- // Inputs all high, all others low.
- static const uint8_t kPortBDefault = 0b00111101;
+ // 0 - trs output enable
+ // 1 - 3.5mm jack detect (active low)
+ // 2 - NC
+ // 3 - NC
+ // 4 - NC
+ // 5 - NC
+ // 6 - NC
+ // 7 - NC
+ // Default input high, trs output low
+ static const uint8_t kPortBDefault = 0b00000010;
/*
* Convenience mehod for packing the port a and b bytes into a single 16 bit
@@ -99,30 +99,30 @@ class GpioExpander {
/* Maps each pin of the expander to its number in a `pack`ed uint16. */
enum Pin {
// Port A
- AUDIO_POWER_ENABLE = 0,
- USB_INTERFACE_POWER_ENABLE = 1,
- DISPLAY_POWER_ENABLE = 2,
- TOUCHPAD_POWER_ENABLE = 3,
- SD_CARD_POWER_ENABLE = 4,
- SD_MUX_SWITCH = 5,
- LDO_ENABLE = 6,
- CHARGE_POWER_OK = 7, // Active-low input
+ SD_MUX_SWITCH = 0,
+ SD_MUX_EN_ACTIVE_LOW = 1,
+ KEY_UP = 2,
+ KEY_DOWN = 3,
+ KEY_LOCK = 4,
+ DISPLAY_RESET = 5,
+ // UNUSED = 6,
+ SD_CARD_POWER_ENABLE = 7,
// Port B
- PHONE_DETECT = 8, // Active-high input
- // UNUSED = 9,
- VOL_UP = 10,
- VOL_DOWN = 11,
- LOCK = 12,
- TOUCHPAD_INT = 13,
- DISPLAY_DR = 14,
- DISPLAY_LED = 15,
+ AMP_EN = 8,
+ PHONE_DETECT = 9,
+ // UNUSED = 10,
+ // UNUSED = 11,
+ // UNUSED = 12,
+ // UNUSED = 13,
+ // UNUSED = 14,
+ // UNUSED = 15,
};
/* Nicer value names for use with the SD_MUX_SWITCH pin. */
enum SdController {
- SD_MUX_ESP = 1,
- SD_MUX_USB = 0,
+ SD_MUX_ESP = 0,
+ SD_MUX_SAMD = 1,
};
/**
diff --git a/src/drivers/include/i2c.hpp b/src/drivers/include/i2c.hpp
index dbdd8a11..811c9333 100644
--- a/src/drivers/include/i2c.hpp
+++ b/src/drivers/include/i2c.hpp
@@ -35,7 +35,7 @@ class I2CTransaction {
* ESP_ERR_INVALID_STATE I2C driver not installed or not in master mode.
* ESP_ERR_TIMEOUT Operation timeout because the bus is busy.
*/
- esp_err_t Execute();
+ esp_err_t Execute(uint8_t port = I2C_NUM_0);
/*
* Enqueues a start condition. May also be used for repeated start
diff --git a/src/drivers/include/storage.hpp b/src/drivers/include/storage.hpp
index 64ce4782..c19ec935 100644
--- a/src/drivers/include/storage.hpp
+++ b/src/drivers/include/storage.hpp
@@ -25,14 +25,13 @@ class SdStorage {
FAILED_TO_MOUNT,
};
- static auto create(GpioExpander* gpio)
- -> cpp::result<std::shared_ptr<SdStorage>, Error>;
+ static auto create(GpioExpander* gpio) -> cpp::result<SdStorage*, Error>;
SdStorage(GpioExpander* gpio,
esp_err_t (*do_transaction)(sdspi_dev_handle_t, sdmmc_command_t*),
sdspi_dev_handle_t handle_,
- std::unique_ptr<sdmmc_host_t>& host_,
- std::unique_ptr<sdmmc_card_t>& card_,
+ std::unique_ptr<sdmmc_host_t> host_,
+ std::unique_ptr<sdmmc_card_t> card_,
FATFS* fs_);
~SdStorage();
diff --git a/src/drivers/include/touchwheel.hpp b/src/drivers/include/touchwheel.hpp
new file mode 100644
index 00000000..3dfa182b
--- /dev/null
+++ b/src/drivers/include/touchwheel.hpp
@@ -0,0 +1,49 @@
+#pragma once
+
+#include <stdint.h>
+#include <functional>
+
+#include "esp_err.h"
+#include "result.hpp"
+
+#include "gpio_expander.hpp"
+
+namespace drivers {
+
+struct TouchWheelData {
+ bool is_touched = false;
+ uint8_t wheel_position = -1;
+};
+
+class TouchWheel {
+ public:
+ TouchWheel();
+ ~TouchWheel();
+
+ // Not copyable or movable.
+ TouchWheel(const TouchWheel&) = delete;
+ TouchWheel& operator=(const TouchWheel&) = delete;
+
+ auto Update() -> void;
+ auto GetTouchWheelData() const -> TouchWheelData;
+
+ private:
+ TouchWheelData data_;
+
+ enum Register {
+ FIRMWARE_VERSION = 0x1,
+ DETECTION_STATUS = 0x2,
+ KEY_STATUS_A = 0x3,
+ KEY_STATUS_B = 0x4,
+ SLIDER_POSITION = 0x5,
+ CALIBRATE = 0x6,
+ RESET = 0x7,
+ LOW_POWER = 0x8,
+ SLIDER_OPTIONS = 0x14,
+ };
+
+ void WriteRegister(uint8_t reg, uint8_t val);
+ uint8_t ReadRegister(uint8_t reg);
+};
+
+} // namespace drivers