diff options
Diffstat (limited to 'src/system_fsm')
| -rw-r--r-- | src/system_fsm/include/system_events.hpp | 1 | ||||
| -rw-r--r-- | src/system_fsm/include/system_fsm.hpp | 8 | ||||
| -rw-r--r-- | src/system_fsm/running.cpp | 49 |
3 files changed, 40 insertions, 18 deletions
diff --git a/src/system_fsm/include/system_events.hpp b/src/system_fsm/include/system_events.hpp index a363887e..32394958 100644 --- a/src/system_fsm/include/system_events.hpp +++ b/src/system_fsm/include/system_events.hpp @@ -76,6 +76,7 @@ struct GpioInterrupt : tinyfsm::Event {}; struct SamdInterrupt : tinyfsm::Event {}; struct IdleTimeout : tinyfsm::Event {}; +struct UnmountTimeout : tinyfsm::Event {}; } // namespace internal diff --git a/src/system_fsm/include/system_fsm.hpp b/src/system_fsm/include/system_fsm.hpp index 5a0ea599..cc60e43b 100644 --- a/src/system_fsm/include/system_fsm.hpp +++ b/src/system_fsm/include/system_fsm.hpp @@ -63,8 +63,9 @@ class SystemState : public tinyfsm::Fsm<SystemState> { virtual void react(const SdDetectChanged&) {} virtual void react(const SamdUsbMscChanged&) {} virtual void react(const database::event::UpdateFinished&) {} - virtual void react(const audio::PlaybackFinished&) {} + virtual void react(const audio::PlaybackStopped&) {} virtual void react(const internal::IdleTimeout&) {} + virtual void react(const internal::UnmountTimeout&) {} protected: auto IdleCondition() -> bool; @@ -100,13 +101,16 @@ class Running : public SystemState { void react(const KeyLockChanged&) override; void react(const SdDetectChanged&) override; - void react(const audio::PlaybackFinished&) override; + void react(const audio::PlaybackStopped&) override; void react(const database::event::UpdateFinished&) override; void react(const SamdUsbMscChanged&) override; + void react(const internal::UnmountTimeout&) override; using SystemState::react; private: + auto checkIdle() -> void; + auto mountStorage() -> bool; auto unmountStorage() -> void; diff --git a/src/system_fsm/running.cpp b/src/system_fsm/running.cpp index ec146029..d1d02fab 100644 --- a/src/system_fsm/running.cpp +++ b/src/system_fsm/running.cpp @@ -9,6 +9,7 @@ #include "database.hpp" #include "db_events.hpp" #include "file_gatherer.hpp" +#include "freertos/portmacro.h" #include "freertos/projdefs.h" #include "gpios.hpp" #include "result.hpp" @@ -25,12 +26,22 @@ 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 (mountStorage()) { - events::Ui().Dispatch(StorageMounted{}); + if (!sUnmountTimer) { + sUnmountTimer = xTimerCreate("unmount_timeout", kTicksBeforeUnmount, false, + NULL, timer_callback); } + mountStorage(); } void Running::exit() { @@ -38,18 +49,18 @@ void Running::exit() { } void Running::react(const KeyLockChanged& ev) { - if (IdleCondition()) { - transit<Idle>(); - } + checkIdle(); } -void Running::react(const audio::PlaybackFinished& ev) { - if (IdleCondition()) { - transit<Idle>(); - } +void Running::react(const audio::PlaybackStopped& ev) { + checkIdle(); } void Running::react(const database::event::UpdateFinished&) { + checkIdle(); +} + +void Running::react(const internal::UnmountTimeout&) { if (IdleCondition()) { transit<Idle>(); } @@ -61,10 +72,8 @@ void Running::react(const SdDetectChanged& ev) { return; } - if (ev.has_sd_card) { - if (!sStorage && mountStorage()) { - events::Ui().Dispatch(StorageMounted{}); - } + if (ev.has_sd_card && !sStorage) { + mountStorage(); } // Don't automatically unmount, since this event seems to occasionally happen // supriously. FIXME: Why? @@ -102,9 +111,14 @@ void Running::react(const SamdUsbMscChanged& ev) { gpios.WriteSync(drivers::IGpios::Pin::kSdPowerEnable, 0); // Now it's ready for us. - if (mountStorage()) { - events::Ui().Dispatch(StorageMounted{}); - } + mountStorage(); + } +} + +auto Running::checkIdle() -> void { + xTimerStop(sUnmountTimer, portMAX_DELAY); + if (IdleCondition()) { + xTimerStart(sUnmountTimer, portMAX_DELAY); } } @@ -142,6 +156,9 @@ auto Running::mountStorage() -> bool { std::unique_ptr<database::Database>{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. |
