diff options
| author | jacqueline <me@jacqueline.id.au> | 2023-05-19 21:21:27 +1000 |
|---|---|---|
| committer | jacqueline <me@jacqueline.id.au> | 2023-05-19 21:21:27 +1000 |
| commit | a6ab1504058304012791281f9eb42c262745888f (patch) | |
| tree | f82379cd1e66a8ae2f1afbae5cf083a8ab7acc53 /src/main | |
| parent | b320a6a863cf1c10dc79254af41f573730935564 (diff) | |
| download | tangara-fw-a6ab1504058304012791281f9eb42c262745888f.tar.gz | |
Add tinyfsm, start converting core functions to an FSM-based event loop
Diffstat (limited to 'src/main')
| -rw-r--r-- | src/main/CMakeLists.txt | 4 | ||||
| -rw-r--r-- | src/main/app_console.cpp | 263 | ||||
| -rw-r--r-- | src/main/app_console.hpp | 25 | ||||
| -rw-r--r-- | src/main/main.cpp | 114 |
4 files changed, 11 insertions, 395 deletions
diff --git a/src/main/CMakeLists.txt b/src/main/CMakeLists.txt index 524a7d30..c557a7df 100644 --- a/src/main/CMakeLists.txt +++ b/src/main/CMakeLists.txt @@ -1,5 +1,5 @@ idf_component_register( - SRCS "main.cpp" "app_console.cpp" + SRCS "main.cpp" INCLUDE_DIRS "." - REQUIRES "audio" "drivers" "dev_console" "drivers" "database" "ui") + REQUIRES "audio" "ui" "system_fsm" "events") target_compile_options(${COMPONENT_LIB} PRIVATE ${EXTRA_WARNINGS}) diff --git a/src/main/app_console.cpp b/src/main/app_console.cpp deleted file mode 100644 index a85faaf0..00000000 --- a/src/main/app_console.cpp +++ /dev/null @@ -1,263 +0,0 @@ -#include "app_console.hpp" - -#include <dirent.h> - -#include <cstdint> -#include <cstdio> -#include <cstdlib> -#include <iostream> -#include <string> - -#include "audio_playback.hpp" -#include "database.hpp" -#include "esp_console.h" -#include "esp_log.h" - -namespace console { - -static AppConsole* sInstance = nullptr; - -std::string toSdPath(const std::string& filepath) { - return std::string(drivers::kStoragePath) + "/" + filepath; -} - -int CmdListDir(int argc, char** argv) { - static const std::string usage = "usage: ls [directory]"; - if (argc > 2) { - std::cout << usage << std::endl; - return 1; - } - - std::string path; - if (argc == 2) { - path = toSdPath(argv[1]); - } else { - path = toSdPath(""); - } - - DIR* dir; - struct dirent* ent; - dir = opendir(path.c_str()); - while ((ent = readdir(dir))) { - std::cout << ent->d_name << std::endl; - } - closedir(dir); - - return 0; -} - -void RegisterListDir() { - esp_console_cmd_t cmd{.command = "ls", - .help = "Lists SD contents", - .hint = NULL, - .func = &CmdListDir, - .argtable = NULL}; - esp_console_cmd_register(&cmd); -} - -int CmdPlayFile(int argc, char** argv) { - static const std::string usage = "usage: play [file]"; - if (argc != 2) { - std::cout << usage << std::endl; - return 1; - } - - std::string path = "/"; - sInstance->playback_->Play(path + argv[1]); - - return 0; -} - -void RegisterPlayFile() { - esp_console_cmd_t cmd{.command = "play", - .help = "Begins playback of the file at the given path", - .hint = "filepath", - .func = &CmdPlayFile, - .argtable = NULL}; - esp_console_cmd_register(&cmd); -} - -int CmdToggle(int argc, char** argv) { - static const std::string usage = "usage: toggle"; - if (argc != 1) { - std::cout << usage << std::endl; - return 1; - } - - // sInstance->playback_->Toggle(); - - return 0; -} - -void RegisterToggle() { - esp_console_cmd_t cmd{.command = "toggle", - .help = "Toggles between play and pause", - .hint = NULL, - .func = &CmdToggle, - .argtable = NULL}; - esp_console_cmd_register(&cmd); -} - -int CmdVolume(int argc, char** argv) { - static const std::string usage = "usage: volume [0-255]"; - if (argc != 2) { - std::cout << usage << std::endl; - return 1; - } - - long int raw_vol = strtol(argv[1], NULL, 10); - if (raw_vol < 0 || raw_vol > 255) { - std::cout << usage << std::endl; - return 1; - } - - // sInstance->playback_->SetVolume((uint8_t)raw_vol); - - return 0; -} - -void RegisterVolume() { - esp_console_cmd_t cmd{ - .command = "vol", - .help = "Changes the volume (between 0 and 254. 255 is mute.)", - .hint = NULL, - .func = &CmdVolume, - .argtable = NULL}; - esp_console_cmd_register(&cmd); -} - -int CmdAudioStatus(int argc, char** argv) { - static const std::string usage = "usage: audio"; - if (argc != 1) { - std::cout << usage << std::endl; - return 1; - } - - sInstance->playback_->LogStatus(); - - return 0; -} - -void RegisterAudioStatus() { - esp_console_cmd_t cmd{.command = "audio", - .help = "logs the current status of the audio pipeline", - .hint = NULL, - .func = &CmdAudioStatus, - .argtable = NULL}; - esp_console_cmd_register(&cmd); -} - -int CmdDbInit(int argc, char** argv) { - static const std::string usage = "usage: db_init"; - if (argc != 1) { - std::cout << usage << std::endl; - return 1; - } - - sInstance->database_->Update(); - - return 0; -} - -void RegisterDbInit() { - esp_console_cmd_t cmd{ - .command = "db_init", - .help = "scans for playable files and adds them to the database", - .hint = NULL, - .func = &CmdDbInit, - .argtable = NULL}; - esp_console_cmd_register(&cmd); -} - -int CmdDbSongs(int argc, char** argv) { - static const std::string usage = "usage: db_songs"; - if (argc != 1) { - std::cout << usage << std::endl; - return 1; - } - - std::unique_ptr<database::Result<database::Song>> res( - sInstance->database_->GetSongs(5).get()); - while (true) { - for (database::Song s : res->values()) { - std::cout << s.tags().title.value_or("[BLANK]") << std::endl; - } - if (res->next_page()) { - auto continuation = res->next_page().value(); - res.reset(sInstance->database_->GetPage(&continuation).get()); - } else { - break; - } - } - - return 0; -} - -void RegisterDbSongs() { - esp_console_cmd_t cmd{.command = "db_songs", - .help = "lists titles of ALL songs in the database", - .hint = NULL, - .func = &CmdDbSongs, - .argtable = NULL}; - esp_console_cmd_register(&cmd); -} - -int CmdDbDump(int argc, char** argv) { - static const std::string usage = "usage: db_dump"; - if (argc != 1) { - std::cout << usage << std::endl; - return 1; - } - - std::cout << "=== BEGIN DUMP ===" << std::endl; - - std::unique_ptr<database::Result<std::string>> res( - sInstance->database_->GetDump(5).get()); - while (true) { - for (std::string s : res->values()) { - std::cout << s << std::endl; - } - if (res->next_page()) { - auto continuation = res->next_page().value(); - res.reset( - sInstance->database_->GetPage<std::string>(&continuation).get()); - } else { - break; - } - } - - std::cout << "=== END DUMP ===" << std::endl; - - return 0; -} - -void RegisterDbDump() { - esp_console_cmd_t cmd{.command = "db_dump", - .help = "prints every key/value pair in the db", - .hint = NULL, - .func = &CmdDbDump, - .argtable = NULL}; - esp_console_cmd_register(&cmd); -} - -AppConsole::AppConsole(audio::AudioPlayback* playback, - database::Database* database) - : playback_(playback), database_(database) { - sInstance = this; -} -AppConsole::~AppConsole() { - sInstance = nullptr; -} - -auto AppConsole::RegisterExtraComponents() -> void { - RegisterListDir(); - RegisterPlayFile(); - RegisterToggle(); - RegisterVolume(); - RegisterAudioStatus(); - RegisterDbInit(); - RegisterDbSongs(); - RegisterDbDump(); -} - -} // namespace console diff --git a/src/main/app_console.hpp b/src/main/app_console.hpp deleted file mode 100644 index 3a11d70c..00000000 --- a/src/main/app_console.hpp +++ /dev/null @@ -1,25 +0,0 @@ -#pragma once - -#include <memory> - -#include "audio_playback.hpp" -#include "console.hpp" -#include "database.hpp" -#include "storage.hpp" - -namespace console { - -class AppConsole : public Console { - public: - explicit AppConsole(audio::AudioPlayback* playback, - database::Database* database); - virtual ~AppConsole(); - - audio::AudioPlayback* playback_; - database::Database* database_; - - protected: - virtual auto RegisterExtraComponents() -> void; -}; - -} // namespace console diff --git a/src/main/main.cpp b/src/main/main.cpp index 29ac2c7f..df1eb8b2 100644 --- a/src/main/main.cpp +++ b/src/main/main.cpp @@ -1,114 +1,18 @@ -#include <dirent.h> -#include <stdint.h> -#include <stdio.h> - -#include <cstddef> -#include <cstdint> -#include <memory> - -#include "driver/gpio.h" -#include "driver/i2c.h" -#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_heap_caps.h" -#include "esp_intr_alloc.h" -#include "esp_log.h" #include "freertos/portmacro.h" -#include "freertos/projdefs.h" -#include "hal/gpio_types.h" -#include "hal/spi_types.h" -#include "app_console.hpp" -#include "audio_playback.hpp" -#include "battery.hpp" -#include "dac.hpp" -#include "database.hpp" -#include "display.hpp" -#include "display_init.hpp" -#include "gpio_expander.hpp" -#include "i2c.hpp" -#include "lvgl_task.hpp" -#include "samd.hpp" -#include "spi.hpp" -#include "storage.hpp" -#include "touchwheel.hpp" +#include "tinyfsm.hpp" -static const char* TAG = "MAIN"; +#include "audio_fsm.hpp" +#include "event_queue.hpp" +#include "system_fsm.hpp" +#include "ui_fsm.hpp" extern "C" void app_main(void) { - ESP_LOGI(TAG, "Initialising peripherals"); - - 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 = drivers->AcquireGpios(); - - ESP_LOGI(TAG, "Init SAMD comms"); - drivers::Samd samd; - ESP_LOGI(TAG, "It might have worked? Let's read something!"); - auto res = samd.ReadChargeStatus(); - if (res) { - ESP_LOGI(TAG, "Charge status is %d", static_cast<uint8_t>(*res)); - } else { - ESP_LOGI(TAG, "no charge status?"); - } - - ESP_LOGI(TAG, "Enable power rails for development"); - 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 = drivers->AcquireStorage(); - if (!storage) { - ESP_LOGE(TAG, "Failed! Do you have an SD card?"); - } - - ESP_LOGI(TAG, "Init touch wheel"); - std::shared_ptr<drivers::TouchWheel> touchwheel = - drivers->AcquireTouchWheel(); - - std::atomic<bool> lvgl_quit; - TaskHandle_t lvgl_task_handle; - ui::StartLvgl(drivers.get(), &lvgl_quit, &lvgl_task_handle); - - std::unique_ptr<audio::AudioPlayback> playback; - if (storage) { - ESP_LOGI(TAG, "Init audio pipeline"); - playback = std::make_unique<audio::AudioPlayback>(drivers.get()); - } - - ESP_LOGI(TAG, "Init database"); - std::unique_ptr<database::Database> db; - auto db_res = database::Database::Open(); - if (db_res.has_value()) { - db.reset(db_res.value()); - } - - ESP_LOGI(TAG, "Waiting for background tasks before launching console..."); - vTaskDelay(pdMS_TO_TICKS(1000)); - - ESP_LOGI(TAG, "Launch console"); - console::AppConsole console(playback.get(), db.get()); - console.Launch(); + tinyfsm::FsmList<system_fsm::SystemState, ui::UiState, + audio::AudioState>::start(); - uint8_t prev_position = 0; + auto& queue = events::EventQueue::GetInstance(); while (1) { - touchwheel->Update(); - auto wheel_data = touchwheel->GetTouchWheelData(); - if (wheel_data.wheel_position != prev_position) { - prev_position = wheel_data.wheel_position; - ESP_LOGI(TAG, "Touch wheel pos: %u", prev_position); - } - vTaskDelay(pdMS_TO_TICKS(100)); + queue.Service(portMAX_DELAY); } } |
