summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorjacqueline <me@jacqueline.id.au>2023-04-21 15:27:57 +1000
committerjacqueline <me@jacqueline.id.au>2023-04-21 15:27:57 +1000
commit7083459cf3c62c32d0c039a4665e702d70a27bba (patch)
tree815757d591d8600469104398e95e80824bd94871
parent130009eb142a5ce8bb6cf9cbb59d69a4d96ed5f9 (diff)
downloadtangara-fw-7083459cf3c62c32d0c039a4665e702d70a27bba.tar.gz
wrap driver instance ownership + di in a class
-rw-r--r--src/audio/audio_playback.cpp16
-rw-r--r--src/audio/i2s_audio_output.cpp22
-rw-r--r--src/audio/include/audio_playback.hpp7
-rw-r--r--src/audio/include/i2s_audio_output.hpp8
-rw-r--r--src/drivers/CMakeLists.txt2
-rw-r--r--src/drivers/dac.cpp5
-rw-r--r--src/drivers/display.cpp4
-rw-r--r--src/drivers/include/dac.hpp3
-rw-r--r--src/drivers/include/display.hpp3
-rw-r--r--src/drivers/include/storage.hpp7
-rw-r--r--src/drivers/storage.cpp17
-rw-r--r--src/main/main.cpp42
-rw-r--r--src/ui/include/lvgl_task.hpp5
-rw-r--r--src/ui/lvgl_task.cpp17
14 files changed, 57 insertions, 101 deletions
diff --git a/src/audio/audio_playback.cpp b/src/audio/audio_playback.cpp
index fac4bfab..c51e41fb 100644
--- a/src/audio/audio_playback.cpp
+++ b/src/audio/audio_playback.cpp
@@ -5,6 +5,7 @@
#include <memory>
#include <string_view>
+#include "driver_cache.hpp"
#include "freertos/portmacro.h"
#include "audio_decoder.hpp"
@@ -21,19 +22,10 @@
#include "stream_message.hpp"
namespace audio {
-
-auto AudioPlayback::create(drivers::GpioExpander* expander)
- -> cpp::result<std::unique_ptr<AudioPlayback>, Error> {
- auto sink_res = I2SAudioOutput::create(expander);
- if (sink_res.has_error()) {
- return cpp::fail(ERR_INIT_ELEMENT);
- }
- return std::make_unique<AudioPlayback>(std::move(sink_res.value()));
-}
-
-AudioPlayback::AudioPlayback(std::unique_ptr<I2SAudioOutput> output)
+AudioPlayback::AudioPlayback(drivers::DriverCache* drivers)
: file_source_(std::make_unique<FatfsAudioInput>()),
- i2s_output_(std::move(output)) {
+ i2s_output_(std::make_unique<I2SAudioOutput>(drivers->AcquireGpios(),
+ drivers->AcquireDac())) {
AudioDecoder* codec = new AudioDecoder();
elements_.emplace_back(codec);
diff --git a/src/audio/i2s_audio_output.cpp b/src/audio/i2s_audio_output.cpp
index e5c672f9..e69cc5ac 100644
--- a/src/audio/i2s_audio_output.cpp
+++ b/src/audio/i2s_audio_output.cpp
@@ -2,6 +2,7 @@
#include <algorithm>
#include <cstddef>
+#include <memory>
#include <variant>
#include "esp_err.h"
@@ -18,27 +19,10 @@ static const char* kTag = "I2SOUT";
namespace audio {
-auto I2SAudioOutput::create(drivers::GpioExpander* expander)
- -> cpp::result<std::unique_ptr<I2SAudioOutput>, Error> {
- // First, we need to perform initial configuration of the DAC chip.
- auto dac_result = drivers::AudioDac::create(expander);
- if (dac_result.has_error()) {
- ESP_LOGE(kTag, "failed to init dac: %d", dac_result.error());
- return cpp::fail(DAC_CONFIG);
- }
- std::unique_ptr<drivers::AudioDac> dac = std::move(dac_result.value());
-
- // Soft mute immediately, in order to minimise any clicks and pops caused by
- // the initial output element and pipeline configuration.
- // dac->WriteVolume(255);
- dac->WriteVolume(127); // for testing
-
- return std::make_unique<I2SAudioOutput>(expander, std::move(dac));
-}
-
I2SAudioOutput::I2SAudioOutput(drivers::GpioExpander* expander,
- std::unique_ptr<drivers::AudioDac> dac)
+ std::shared_ptr<drivers::AudioDac> dac)
: expander_(expander), dac_(std::move(dac)), current_config_() {
+ dac->WriteVolume(127); // for testing
dac_->SetSource(buffer());
}
diff --git a/src/audio/include/audio_playback.hpp b/src/audio/include/audio_playback.hpp
index 88dc29aa..cd4be3e7 100644
--- a/src/audio/include/audio_playback.hpp
+++ b/src/audio/include/audio_playback.hpp
@@ -6,6 +6,7 @@
#include <vector>
#include "audio_task.hpp"
+#include "driver_cache.hpp"
#include "esp_err.h"
#include "fatfs_audio_input.hpp"
#include "i2s_audio_output.hpp"
@@ -25,11 +26,7 @@ namespace audio {
*/
class AudioPlayback {
public:
- enum Error { ERR_INIT_ELEMENT, ERR_MEM };
- static auto create(drivers::GpioExpander* expander)
- -> cpp::result<std::unique_ptr<AudioPlayback>, Error>;
-
- explicit AudioPlayback(std::unique_ptr<I2SAudioOutput> output);
+ explicit AudioPlayback(drivers::DriverCache* drivers);
~AudioPlayback();
/*
diff --git a/src/audio/include/i2s_audio_output.hpp b/src/audio/include/i2s_audio_output.hpp
index 31510a91..07430777 100644
--- a/src/audio/include/i2s_audio_output.hpp
+++ b/src/audio/include/i2s_audio_output.hpp
@@ -17,12 +17,8 @@ namespace audio {
class I2SAudioOutput : public IAudioSink {
public:
- enum Error { DAC_CONFIG, I2S_CONFIG, STREAM_INIT };
- static auto create(drivers::GpioExpander* expander)
- -> cpp::result<std::unique_ptr<I2SAudioOutput>, Error>;
-
I2SAudioOutput(drivers::GpioExpander* expander,
- std::unique_ptr<drivers::AudioDac> dac);
+ std::shared_ptr<drivers::AudioDac> dac);
~I2SAudioOutput();
auto Configure(const StreamInfo::Format& format) -> bool override;
@@ -36,7 +32,7 @@ class I2SAudioOutput : public IAudioSink {
auto SetVolume(uint8_t volume) -> void;
drivers::GpioExpander* expander_;
- std::unique_ptr<drivers::AudioDac> dac_;
+ std::shared_ptr<drivers::AudioDac> dac_;
std::optional<StreamInfo::Pcm> current_config_;
};
diff --git a/src/drivers/CMakeLists.txt b/src/drivers/CMakeLists.txt
index bf8f0c4e..072a8b68 100644
--- a/src/drivers/CMakeLists.txt
+++ b/src/drivers/CMakeLists.txt
@@ -1,6 +1,6 @@
idf_component_register(
SRCS "touchwheel.cpp" "dac.cpp" "gpio_expander.cpp" "battery.cpp" "storage.cpp" "i2c.cpp"
- "spi.cpp" "display.cpp" "display_init.cpp"
+ "spi.cpp" "display.cpp" "display_init.cpp" "driver_cache.cpp"
INCLUDE_DIRS "include"
REQUIRES "esp_adc" "fatfs" "result" "lvgl" "span")
target_compile_options(${COMPONENT_LIB} PRIVATE ${EXTRA_WARNINGS})
diff --git a/src/drivers/dac.cpp b/src/drivers/dac.cpp
index ac283600..e82f0d27 100644
--- a/src/drivers/dac.cpp
+++ b/src/drivers/dac.cpp
@@ -27,8 +27,7 @@ static const char* kTag = "AUDIODAC";
static const uint8_t kPcm5122Address = 0x4C;
static const i2s_port_t kI2SPort = I2S_NUM_0;
-auto AudioDac::create(GpioExpander* expander)
- -> cpp::result<std::unique_ptr<AudioDac>, Error> {
+auto AudioDac::create(GpioExpander* expander) -> cpp::result<AudioDac*, Error> {
// TODO: tune.
i2s_chan_handle_t i2s_handle;
i2s_chan_config_t channel_config =
@@ -111,7 +110,7 @@ auto AudioDac::create(GpioExpander* expander)
return state == RUN || state == STANDBY;
});
- return dac;
+ return dac.release();
}
AudioDac::AudioDac(GpioExpander* gpio, i2s_chan_handle_t i2s_handle)
diff --git a/src/drivers/display.cpp b/src/drivers/display.cpp
index 56bd6e60..f8594a5a 100644
--- a/src/drivers/display.cpp
+++ b/src/drivers/display.cpp
@@ -63,7 +63,7 @@ extern "C" void FlushDataCallback(lv_disp_drv_t* disp_drv,
auto Display::create(GpioExpander* expander,
const displays::InitialisationData& init_data)
- -> std::unique_ptr<Display> {
+ -> Display* {
ESP_LOGI(kTag, "Init I/O pins");
gpio_config_t dr_config{
.pin_bit_mask = 1ULL << kDisplayDr,
@@ -134,7 +134,7 @@ auto Display::create(GpioExpander* expander,
ESP_LOGI(kTag, "Registering driver");
display->display_ = lv_disp_drv_register(&display->driver_);
- return display;
+ return display.release();
}
Display::Display(GpioExpander* gpio, spi_device_handle_t handle)
diff --git a/src/drivers/include/dac.hpp b/src/drivers/include/dac.hpp
index acdd1743..4952c992 100644
--- a/src/drivers/include/dac.hpp
+++ b/src/drivers/include/dac.hpp
@@ -117,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();
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/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/storage.cpp b/src/drivers/storage.cpp
index 88159744..d90bd811 100644
--- a/src/drivers/storage.cpp
+++ b/src/drivers/storage.cpp
@@ -49,8 +49,9 @@ static esp_err_t do_transaction(sdspi_dev_handle_t handle,
}
} // namespace callback
-auto SdStorage::create(GpioExpander* gpio)
- -> cpp::result<std::shared_ptr<SdStorage>, Error> {
+auto SdStorage::create(GpioExpander* gpio) -> cpp::result<SdStorage*, Error> {
+ gpio->set_pin(GpioExpander::SD_CARD_POWER_ENABLE, 0);
+ gpio->set_pin(GpioExpander::SD_MUX_EN_ACTIVE_LOW, 0);
gpio->set_pin(GpioExpander::SD_MUX_SWITCH, GpioExpander::SD_MUX_ESP);
gpio->Write();
@@ -103,16 +104,16 @@ auto SdStorage::create(GpioExpander* gpio)
return cpp::fail(Error::FAILED_TO_MOUNT);
}
- return std::make_unique<SdStorage>(gpio, do_transaction, handle, host, card,
- fs);
+ return new SdStorage(gpio, do_transaction, handle, std::move(host),
+ std::move(card), fs);
}
SdStorage::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)
: gpio_(gpio),
do_transaction_(do_transaction),
@@ -136,6 +137,10 @@ SdStorage::~SdStorage() {
// Uninstall the SPI driver
sdspi_host_remove_device(this->handle_);
sdspi_host_deinit();
+
+ gpio_->set_pin(GpioExpander::SD_CARD_POWER_ENABLE, 0);
+ gpio_->set_pin(GpioExpander::SD_MUX_EN_ACTIVE_LOW, 1);
+ gpio_->Write();
}
auto SdStorage::HandleTransaction(sdspi_dev_handle_t handle,
diff --git a/src/main/main.cpp b/src/main/main.cpp
index 796c70f3..2a345899 100644
--- a/src/main/main.cpp
+++ b/src/main/main.cpp
@@ -11,6 +11,7 @@
#include "driver/sdspi_host.h"
#include "driver/spi_common.h"
#include "driver/spi_master.h"
+#include "driver_cache.hpp"
#include "esp_freertos_hooks.h"
#include "esp_intr_alloc.h"
#include "esp_log.h"
@@ -39,50 +40,37 @@ extern "C" void app_main(void) {
ESP_ERROR_CHECK(drivers::init_i2c());
ESP_ERROR_CHECK(drivers::init_spi());
+ std::unique_ptr<drivers::DriverCache> drivers =
+ std::make_unique<drivers::DriverCache>();
ESP_LOGI(TAG, "Init GPIOs");
- drivers::GpioExpander* expander = new drivers::GpioExpander();
+ drivers::GpioExpander* expander = drivers->AcquireGpios();
ESP_LOGI(TAG, "Enable power rails for development");
- expander->with([&](auto& gpio) {
- gpio.set_pin(drivers::GpioExpander::SD_MUX_EN_ACTIVE_LOW, 0);
- gpio.set_pin(drivers::GpioExpander::SD_MUX_SWITCH,
- drivers::GpioExpander::SD_MUX_ESP);
- gpio.set_pin(drivers::GpioExpander::SD_CARD_POWER_ENABLE, 0);
- gpio.set_pin(drivers::GpioExpander::AMP_EN, 1);
- });
+ expander->with(
+ [&](auto& gpio) { gpio.set_pin(drivers::GpioExpander::AMP_EN, 1); });
ESP_LOGI(TAG, "Init battery measurement");
drivers::Battery* battery = new drivers::Battery();
ESP_LOGI(TAG, "it's reading %d mV!", (int)battery->Millivolts());
ESP_LOGI(TAG, "Init SD card");
- auto storage_res = drivers::SdStorage::create(expander);
- std::shared_ptr<drivers::SdStorage> storage;
- if (storage_res.has_error()) {
+ auto storage = drivers->AcquireStorage();
+ if (!storage) {
ESP_LOGE(TAG, "Failed! Do you have an SD card?");
- } else {
- storage = std::move(storage_res.value());
}
ESP_LOGI(TAG, "Init touch wheel");
- std::unique_ptr<drivers::TouchWheel> touchwheel =
- std::make_unique<drivers::TouchWheel>();
+ std::shared_ptr<drivers::TouchWheel> touchwheel =
+ drivers->AcquireTouchWheel();
std::atomic<bool> lvgl_quit;
TaskHandle_t lvgl_task_handle;
- ui::StartLvgl(expander, &lvgl_quit, &lvgl_task_handle);
-
- std::unique_ptr<audio::AudioPlayback> playback;
- if (storage) {
- ESP_LOGI(TAG, "Init audio pipeline");
- auto playback_res = audio::AudioPlayback::create(expander);
- if (playback_res.has_error()) {
- ESP_LOGE(TAG, "Failed! Playback will not work.");
- } else {
- playback = std::move(playback_res.value());
- }
- }
+ ui::StartLvgl(drivers.get(), &lvgl_quit, &lvgl_task_handle);
+
+ ESP_LOGI(TAG, "Init audio pipeline");
+ std::unique_ptr<audio::AudioPlayback> playback =
+ std::make_unique<audio::AudioPlayback>(drivers.get());
ESP_LOGI(TAG, "Waiting for background tasks before launching console...");
vTaskDelay(pdMS_TO_TICKS(1000));
diff --git a/src/ui/include/lvgl_task.hpp b/src/ui/include/lvgl_task.hpp
index 1a2f425c..ca3fc771 100644
--- a/src/ui/include/lvgl_task.hpp
+++ b/src/ui/include/lvgl_task.hpp
@@ -5,11 +5,12 @@
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
-#include "gpio_expander.hpp"
+
+#include "driver_cache.hpp"
namespace ui {
-auto StartLvgl(drivers::GpioExpander* gpios,
+auto StartLvgl(drivers::DriverCache* drivers,
std::atomic<bool>* quit,
TaskHandle_t* handle) -> bool;
diff --git a/src/ui/lvgl_task.cpp b/src/ui/lvgl_task.cpp
index d66f6282..12dfd34e 100644
--- a/src/ui/lvgl_task.cpp
+++ b/src/ui/lvgl_task.cpp
@@ -26,7 +26,7 @@
#include "widgets/lv_label.h"
#include "display.hpp"
-#include "display_init.hpp"
+#include "driver_cache.hpp"
#include "gpio_expander.hpp"
namespace ui {
@@ -38,16 +38,14 @@ auto tick_hook(TimerHandle_t xTimer) -> void {
}
struct LvglArgs {
- drivers::GpioExpander* gpio_expander;
+ drivers::DriverCache* drivers;
std::atomic<bool>* quit;
};
void LvglMain(void* voidArgs) {
- LvglArgs* args = (LvglArgs*)voidArgs;
- drivers::GpioExpander* gpio_expander = args->gpio_expander;
+ LvglArgs* args = reinterpret_cast<LvglArgs*>(voidArgs);
+ drivers::DriverCache* drivers = args->drivers;
std::atomic<bool>* quit = args->quit;
-
- // Dispose of the args now that we've gotten everything out of them.
delete args;
{
@@ -59,8 +57,7 @@ void LvglMain(void* voidArgs) {
xTimerCreate("lv_tick", pdMS_TO_TICKS(1), pdTRUE, NULL, &tick_hook);
ESP_LOGI(kTag, "init display");
- std::unique_ptr<drivers::Display> display =
- drivers::Display::create(gpio_expander, drivers::displays::kST7735R);
+ std::shared_ptr<drivers::Display> display = drivers->AcquireDisplay();
lv_style_t style;
lv_style_init(&style);
@@ -96,11 +93,11 @@ static const size_t kLvglStackSize = 8 * 1024;
static StaticTask_t sLvglTaskBuffer = {};
static StackType_t sLvglStack[kLvglStackSize] = {0};
-auto StartLvgl(drivers::GpioExpander* gpios,
+auto StartLvgl(drivers::DriverCache* drivers,
std::atomic<bool>* quit,
TaskHandle_t* handle) -> bool {
LvglArgs* args = new LvglArgs();
- args->gpio_expander = gpios;
+ args->drivers = drivers;
args->quit = quit;
return xTaskCreateStaticPinnedToCore(&LvglMain, "LVGL", kLvglStackSize,