From 1573a8c4cde1cd9528b422b2dcc598e37ffe94a7 Mon Sep 17 00:00:00 2001 From: jacqueline Date: Thu, 2 May 2024 19:12:26 +1000 Subject: WIP merge cyclically dependent components into one big component --- src/tangara/system_fsm/running.cpp | 197 +++++++++++++++++++++++++++++++++++++ 1 file changed, 197 insertions(+) create mode 100644 src/tangara/system_fsm/running.cpp (limited to 'src/tangara/system_fsm/running.cpp') diff --git a/src/tangara/system_fsm/running.cpp b/src/tangara/system_fsm/running.cpp new file mode 100644 index 00000000..796c96dc --- /dev/null +++ b/src/tangara/system_fsm/running.cpp @@ -0,0 +1,197 @@ +/* + * Copyright 2023 jacqueline + * + * SPDX-License-Identifier: GPL-3.0-only + */ + +#include "app_console.hpp" +#include "audio_events.hpp" +#include "database.hpp" +#include "db_events.hpp" +#include "ff.h" +#include "file_gatherer.hpp" +#include "freertos/portmacro.h" +#include "freertos/projdefs.h" +#include "gpios.hpp" +#include "result.hpp" + +#include "audio_fsm.hpp" +#include "event_queue.hpp" +#include "storage.hpp" +#include "system_events.hpp" +#include "system_fsm.hpp" +#include "ui_fsm.hpp" + +namespace system_fsm { +namespace states { + +[[maybe_unused]] static const char kTag[] = "RUN"; + +static const TickType_t kTicksBeforeUnmount = pdMS_TO_TICKS(10000); + +static TimerHandle_t sUnmountTimer = nullptr; + +static void timer_callback(TimerHandle_t timer) { + events::System().Dispatch(internal::UnmountTimeout{}); +} + +static database::IFileGatherer* sFileGatherer; + +void Running::entry() { + if (!sUnmountTimer) { + sUnmountTimer = xTimerCreate("unmount_timeout", kTicksBeforeUnmount, false, + NULL, timer_callback); + } + // Only mount our storage immediately if we know it's not currently in use + // by the SAMD. + if (!sServices->samd().UsbMassStorage()) { + mountStorage(); + } +} + +void Running::exit() { + unmountStorage(); +} + +void Running::react(const KeyLockChanged& ev) { + checkIdle(); +} + +void Running::react(const audio::PlaybackUpdate& ev) { + checkIdle(); +} + +void Running::react(const database::event::UpdateFinished&) { + checkIdle(); +} + +void Running::react(const internal::UnmountTimeout&) { + if (IdleCondition()) { + transit(); + } +} + +void Running::react(const SdDetectChanged& ev) { + if (sServices->samd().UsbMassStorage()) { + // We don't currently control the sd card, so don't mess with it. + return; + } + + if (ev.has_sd_card && !sStorage) { + mountStorage(); + } + // Don't automatically unmount, since this event seems to occasionally happen + // supriously. FIXME: Why? + // (It doesn't matter too much; by the time we get this event the SD card has + // already been disconnected electrically.) +} + +void Running::react(const SamdUsbMscChanged& ev) { + if (ev.en) { + // Stop using the sd card, and power it off. + unmountStorage(); + + // Set up the SD card for usage by the samd21. + auto& gpios = sServices->gpios(); + gpios.WriteSync(drivers::IGpios::Pin::kSdPowerEnable, 1); + gpios.WriteSync(drivers::IGpios::Pin::kSdMuxSwitch, + drivers::IGpios::SD_MUX_SAMD); + gpios.WriteSync(drivers::IGpios::Pin::kSdMuxDisable, 0); + + // Off you go! + sServices->samd().UsbMassStorage(true); + } else { + // Make sure the samd knows that its access is going away, and give it time + // to finish up any remaining work. + sServices->samd().UsbMassStorage(false); + vTaskDelay(pdMS_TO_TICKS(250)); + + auto& gpios = sServices->gpios(); + // No more writing, please! + gpios.WriteSync(drivers::IGpios::Pin::kSdMuxDisable, 1); + vTaskDelay(pdMS_TO_TICKS(100)); + + // Reboot the SD card so that it comes up in a consistent state. + // TODO: can we avoid doing this? + gpios.WriteSync(drivers::IGpios::Pin::kSdPowerEnable, 0); + + // Now it's ready for us. + mountStorage(); + } +} + +void Running::react(const StorageError& ev) { + ESP_LOGE(kTag, "storage error %u", ev.error); + if (ev.error == FR_DISK_ERR || ev.error == FR_INVALID_OBJECT) { + unmountStorage(); + } +} + +auto Running::checkIdle() -> void { + xTimerStop(sUnmountTimer, portMAX_DELAY); + if (IdleCondition()) { + xTimerStart(sUnmountTimer, portMAX_DELAY); + } +} + +auto Running::mountStorage() -> bool { + ESP_LOGI(kTag, "mounting sd card"); + auto storage_res = drivers::SdStorage::Create(sServices->gpios()); + if (storage_res.has_error()) { + ESP_LOGW(kTag, "failed to mount!"); + switch (storage_res.error()) { + case drivers::SdStorage::FAILED_TO_MOUNT: + sServices->sd(drivers::SdState::kNotFormatted); + break; + case drivers::SdStorage::FAILED_TO_READ: + default: + sServices->sd(drivers::SdState::kNotPresent); + break; + } + return false; + } + + sStorage.reset(storage_res.value()); + sServices->sd(drivers::SdState::kMounted); + + ESP_LOGI(kTag, "opening database"); + sFileGatherer = new database::FileGathererImpl(); + auto database_res = + database::Database::Open(*sFileGatherer, sServices->tag_parser(), + sServices->collator(), sServices->bg_worker()); + if (database_res.has_error()) { + unmountStorage(); + return false; + } + + sServices->database( + std::unique_ptr{database_res.value()}); + + ESP_LOGI(kTag, "storage loaded okay"); + events::Ui().Dispatch(StorageMounted{}); + events::Audio().Dispatch(StorageMounted{}); + events::System().Dispatch(StorageMounted{}); + + // Tell the database to refresh so that we pick up any changes from the newly + // mounted card. + if (sServices->nvs().DbAutoIndex()) { + sServices->bg_worker().Dispatch([&]() { + auto db = sServices->database().lock(); + if (!db) { + return; + } + db->updateIndexes(); + }); + } + + return true; +} + +auto Running::unmountStorage() -> void { + ESP_LOGW(kTag, "unmounting storage"); + sServices->database({}); + sStorage.reset(); +} + +} // namespace states +} // namespace system_fsm -- cgit v1.2.3 From 7d7f7755d17e1e0a2348d75d797097f166b70471 Mon Sep 17 00:00:00 2001 From: jacqueline Date: Thu, 2 May 2024 21:41:56 +1000 Subject: start moving include files into subdirs --- src/tangara/system_fsm/running.cpp | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) (limited to 'src/tangara/system_fsm/running.cpp') diff --git a/src/tangara/system_fsm/running.cpp b/src/tangara/system_fsm/running.cpp index 796c96dc..a19abdaf 100644 --- a/src/tangara/system_fsm/running.cpp +++ b/src/tangara/system_fsm/running.cpp @@ -4,23 +4,23 @@ * SPDX-License-Identifier: GPL-3.0-only */ -#include "app_console.hpp" -#include "audio_events.hpp" -#include "database.hpp" -#include "db_events.hpp" +#include "app_console/app_console.hpp" +#include "audio/audio_events.hpp" +#include "database/database.hpp" +#include "database/db_events.hpp" +#include "database/file_gatherer.hpp" #include "ff.h" -#include "file_gatherer.hpp" #include "freertos/portmacro.h" #include "freertos/projdefs.h" #include "gpios.hpp" #include "result.hpp" -#include "audio_fsm.hpp" -#include "event_queue.hpp" +#include "audio/audio_fsm.hpp" +#include "events/event_queue.hpp" #include "storage.hpp" -#include "system_events.hpp" -#include "system_fsm.hpp" -#include "ui_fsm.hpp" +#include "system_fsm/system_events.hpp" +#include "system_fsm/system_fsm.hpp" +#include "ui/ui_fsm.hpp" namespace system_fsm { namespace states { -- cgit v1.2.3 From 26eb580043ad176bdc58d996f30d470e1073ef00 Mon Sep 17 00:00:00 2001 From: jacqueline Date: Thu, 2 May 2024 21:52:59 +1000 Subject: move driver includes into a subdir as well --- src/tangara/system_fsm/running.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'src/tangara/system_fsm/running.cpp') diff --git a/src/tangara/system_fsm/running.cpp b/src/tangara/system_fsm/running.cpp index a19abdaf..82edd018 100644 --- a/src/tangara/system_fsm/running.cpp +++ b/src/tangara/system_fsm/running.cpp @@ -9,15 +9,15 @@ #include "database/database.hpp" #include "database/db_events.hpp" #include "database/file_gatherer.hpp" +#include "drivers/gpios.hpp" #include "ff.h" #include "freertos/portmacro.h" #include "freertos/projdefs.h" -#include "gpios.hpp" #include "result.hpp" #include "audio/audio_fsm.hpp" +#include "drivers/storage.hpp" #include "events/event_queue.hpp" -#include "storage.hpp" #include "system_fsm/system_events.hpp" #include "system_fsm/system_fsm.hpp" #include "ui/ui_fsm.hpp" -- cgit v1.2.3