summaryrefslogtreecommitdiff
path: root/src/system_fsm
diff options
context:
space:
mode:
authorjacqueline <me@jacqueline.id.au>2023-08-28 10:18:02 +1000
committerjacqueline <me@jacqueline.id.au>2023-08-28 10:18:02 +1000
commit8ff93f5467b0eef54d18b35d742de05c8a63da9a (patch)
treeca0215b64d1a779a69c30b71f8d7870f5aa3dbcb /src/system_fsm
parent0f5cf25e73fb2e789b472317966ff80323dddd75 (diff)
downloadtangara-fw-8ff93f5467b0eef54d18b35d742de05c8a63da9a.tar.gz
Make idle state more robust + check playback state
Diffstat (limited to 'src/system_fsm')
-rw-r--r--src/system_fsm/idle.cpp14
-rw-r--r--src/system_fsm/include/system_fsm.hpp6
-rw-r--r--src/system_fsm/running.cpp9
-rw-r--r--src/system_fsm/system_fsm.cpp5
4 files changed, 31 insertions, 3 deletions
diff --git a/src/system_fsm/idle.cpp b/src/system_fsm/idle.cpp
index 91075fc6..7cc1fa39 100644
--- a/src/system_fsm/idle.cpp
+++ b/src/system_fsm/idle.cpp
@@ -49,12 +49,17 @@ void Idle::exit() {
}
void Idle::react(const KeyLockChanged& ev) {
- if (!ev.falling) {
+ if (ev.falling) {
transit<Running>();
}
}
void Idle::react(const internal::IdleTimeout& ev) {
+ if (!IdleCondition()) {
+ // Defensively ensure that we didn't miss an idle-ending event.
+ transit<Running>();
+ return;
+ }
ESP_LOGI(kTag, "system shutting down");
// FIXME: It would be neater to just free a bunch of our pointers, deinit the
@@ -79,7 +84,12 @@ void Idle::react(const internal::IdleTimeout& ev) {
sGpios->Flush();
- sSamd->PowerDown();
+ // Retry shutting down in case of a transient failure with the SAMD. e.g. i2c
+ // timeouts. This guards against a buggy SAMD firmware preventing idle.
+ for (;;) {
+ sSamd->PowerDown();
+ vTaskDelay(pdMS_TO_TICKS(1000));
+ }
}
} // namespace states
diff --git a/src/system_fsm/include/system_fsm.hpp b/src/system_fsm/include/system_fsm.hpp
index 6baceca1..a556be9e 100644
--- a/src/system_fsm/include/system_fsm.hpp
+++ b/src/system_fsm/include/system_fsm.hpp
@@ -9,6 +9,7 @@
#include <memory>
#include "app_console.hpp"
+#include "audio_events.hpp"
#include "battery.hpp"
#include "bluetooth.hpp"
#include "database.hpp"
@@ -54,9 +55,12 @@ class SystemState : public tinyfsm::Fsm<SystemState> {
virtual void react(const StorageMounted&) {}
virtual void react(const StorageError&) {}
virtual void react(const KeyLockChanged&) {}
+ virtual void react(const audio::PlaybackFinished&) {}
virtual void react(const internal::IdleTimeout&) {}
protected:
+ auto IdleCondition() -> bool;
+
static std::shared_ptr<drivers::Gpios> sGpios;
static std::shared_ptr<drivers::Samd> sSamd;
static std::shared_ptr<drivers::NvsStorage> sNvs;
@@ -101,6 +105,8 @@ class Running : public SystemState {
void react(const KeyLockChanged&) override;
void react(const StorageError&) override;
+ void react(const audio::PlaybackFinished&) override;
+
using SystemState::react;
};
diff --git a/src/system_fsm/running.cpp b/src/system_fsm/running.cpp
index 9e250c9b..3fc5493f 100644
--- a/src/system_fsm/running.cpp
+++ b/src/system_fsm/running.cpp
@@ -5,6 +5,7 @@
*/
#include "app_console.hpp"
+#include "audio_events.hpp"
#include "file_gatherer.hpp"
#include "freertos/projdefs.h"
#include "result.hpp"
@@ -68,7 +69,13 @@ void Running::exit() {
}
void Running::react(const KeyLockChanged& ev) {
- if (!ev.falling && audio::AudioState::is_in_state<audio::states::Standby>()) {
+ if (IdleCondition()) {
+ transit<Idle>();
+ }
+}
+
+void Running::react(const audio::PlaybackFinished& ev) {
+ if (IdleCondition()) {
transit<Idle>();
}
}
diff --git a/src/system_fsm/system_fsm.cpp b/src/system_fsm/system_fsm.cpp
index 78c4c53e..9ad89c7a 100644
--- a/src/system_fsm/system_fsm.cpp
+++ b/src/system_fsm/system_fsm.cpp
@@ -105,6 +105,11 @@ void SystemState::react(const internal::BatteryTimerFired&) {
}
}
+auto SystemState::IdleCondition() -> bool {
+ return !sGpios->Get(drivers::IGpios::Pin::kKeyLock) &&
+ audio::AudioState::is_in_state<audio::states::Standby>();
+}
+
} // namespace system_fsm
FSM_INITIAL_STATE(system_fsm::SystemState, system_fsm::states::Booting)