summaryrefslogtreecommitdiff
path: root/src/system_fsm
diff options
context:
space:
mode:
Diffstat (limited to 'src/system_fsm')
-rw-r--r--src/system_fsm/include/system_events.hpp1
-rw-r--r--src/system_fsm/include/system_fsm.hpp8
-rw-r--r--src/system_fsm/running.cpp49
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.