summaryrefslogtreecommitdiff
path: root/src/system_fsm
diff options
context:
space:
mode:
authorailurux <ailuruxx@gmail.com>2023-08-28 14:59:52 +1000
committerailurux <ailuruxx@gmail.com>2023-08-28 14:59:52 +1000
commitdb601935c6145445467692c0a4ff2b81e27cf6ce (patch)
treee2eed4a38abd03f14dba504ce5e8dedee0da6a12 /src/system_fsm
parent6f4ace1dd4b9b34f95af1ba365b68624e209d147 (diff)
parent3a0c42f9240eedfbc6a1e94ad3a59c52664fb5b5 (diff)
downloadtangara-fw-db601935c6145445467692c0a4ff2b81e27cf6ce.tar.gz
Merge branch 'main' of git.sr.ht:~jacqueline/tangara-fw
Diffstat (limited to 'src/system_fsm')
-rw-r--r--src/system_fsm/CMakeLists.txt2
-rw-r--r--src/system_fsm/booting.cpp24
-rw-r--r--src/system_fsm/idle.cpp14
-rw-r--r--src/system_fsm/include/system_events.hpp4
-rw-r--r--src/system_fsm/include/system_fsm.hpp10
-rw-r--r--src/system_fsm/running.cpp9
-rw-r--r--src/system_fsm/system_fsm.cpp14
7 files changed, 43 insertions, 34 deletions
diff --git a/src/system_fsm/CMakeLists.txt b/src/system_fsm/CMakeLists.txt
index 037e72c7..fced4093 100644
--- a/src/system_fsm/CMakeLists.txt
+++ b/src/system_fsm/CMakeLists.txt
@@ -5,5 +5,5 @@
idf_component_register(
SRCS "system_fsm.cpp" "running.cpp" "booting.cpp" "idle.cpp"
INCLUDE_DIRS "include"
- REQUIRES "tinyfsm" "drivers" "database" "ui" "result" "events" "audio" "app_console")
+ REQUIRES "tinyfsm" "drivers" "database" "ui" "result" "events" "audio" "app_console" "battery")
target_compile_options(${COMPONENT_LIB} PRIVATE ${EXTRA_WARNINGS})
diff --git a/src/system_fsm/booting.cpp b/src/system_fsm/booting.cpp
index 33ed39d1..f33d1679 100644
--- a/src/system_fsm/booting.cpp
+++ b/src/system_fsm/booting.cpp
@@ -38,12 +38,6 @@ namespace states {
static const char kTag[] = "BOOT";
-static const TickType_t kBatteryCheckPeriod = pdMS_TO_TICKS(60 * 1000);
-
-static void battery_timer_cb(TimerHandle_t timer) {
- events::System().Dispatch(internal::BatteryTimerFired{});
-}
-
auto Booting::entry() -> void {
ESP_LOGI(kTag, "beginning tangara boot");
ESP_LOGI(kTag, "installing early drivers");
@@ -53,33 +47,31 @@ auto Booting::entry() -> void {
ESP_ERROR_CHECK(drivers::init_spi());
sGpios.reset(drivers::Gpios::Create());
+ sSamd.reset(drivers::Samd::Create());
+ sAdc.reset(drivers::AdcBattery::Create());
+ assert(sSamd.get() && sAdc.get());
+
+ sBattery.reset(new battery::Battery(sSamd.get(), sAdc.get()));
+
// Start bringing up LVGL now, since we have all of its prerequisites.
sTrackQueue.reset(new audio::TrackQueue());
ESP_LOGI(kTag, "starting ui");
- if (!ui::UiState::Init(sGpios.get(), sTrackQueue.get())) {
+ if (!ui::UiState::Init(sGpios.get(), sTrackQueue.get(), sBattery)) {
events::System().Dispatch(FatalError{});
return;
}
// Install everything else that is certain to be needed.
ESP_LOGI(kTag, "installing remaining drivers");
- sSamd.reset(drivers::Samd::Create());
- sBattery.reset(drivers::Battery::Create());
sNvs.reset(drivers::NvsStorage::Open());
sTagParser.reset(new database::TagParserImpl());
- if (!sSamd || !sBattery || !sNvs) {
+ if (!sNvs) {
events::System().Dispatch(FatalError{});
events::Ui().Dispatch(FatalError{});
return;
}
- ESP_LOGI(kTag, "battery is at %u%% (= %lu mV)", sBattery->Percent(),
- sBattery->Millivolts());
- TimerHandle_t battery_timer = xTimerCreate("battery", kBatteryCheckPeriod,
- true, NULL, battery_timer_cb);
- xTimerStart(battery_timer, portMAX_DELAY);
-
// ESP_LOGI(kTag, "starting bluetooth");
// sBluetooth.reset(new drivers::Bluetooth(sNvs.get()));
// sBluetooth->Enable();
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_events.hpp b/src/system_fsm/include/system_events.hpp
index 8a3ba5ec..64cbd393 100644
--- a/src/system_fsm/include/system_events.hpp
+++ b/src/system_fsm/include/system_events.hpp
@@ -53,7 +53,7 @@ struct HasPhonesChanged : tinyfsm::Event {
};
struct ChargingStatusChanged : tinyfsm::Event {};
-struct BatteryPercentChanged : tinyfsm::Event {};
+struct BatteryStateChanged : tinyfsm::Event {};
namespace internal {
@@ -62,8 +62,6 @@ struct SamdInterrupt : tinyfsm::Event {};
struct IdleTimeout : tinyfsm::Event {};
-struct BatteryTimerFired : tinyfsm::Event {};
-
} // namespace internal
} // namespace system_fsm
diff --git a/src/system_fsm/include/system_fsm.hpp b/src/system_fsm/include/system_fsm.hpp
index 6baceca1..371e5527 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"
@@ -47,23 +48,26 @@ class SystemState : public tinyfsm::Fsm<SystemState> {
void react(const FatalError&);
void react(const internal::GpioInterrupt&);
void react(const internal::SamdInterrupt&);
- void react(const internal::BatteryTimerFired&);
virtual void react(const DisplayReady&) {}
virtual void react(const BootComplete&) {}
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;
static std::shared_ptr<drivers::TouchWheel> sTouch;
static std::shared_ptr<drivers::RelativeWheel> sRelativeTouch;
- static std::shared_ptr<drivers::Battery> sBattery;
+ static std::shared_ptr<drivers::AdcBattery> sAdc;
+ static std::shared_ptr<battery::Battery> sBattery;
static std::shared_ptr<drivers::SdStorage> sStorage;
static std::shared_ptr<drivers::Display> sDisplay;
static std::shared_ptr<drivers::Bluetooth> sBluetooth;
@@ -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..d21e8bcb 100644
--- a/src/system_fsm/system_fsm.cpp
+++ b/src/system_fsm/system_fsm.cpp
@@ -23,7 +23,8 @@ std::shared_ptr<drivers::NvsStorage> SystemState::sNvs;
std::shared_ptr<drivers::TouchWheel> SystemState::sTouch;
std::shared_ptr<drivers::RelativeWheel> SystemState::sRelativeTouch;
-std::shared_ptr<drivers::Battery> SystemState::sBattery;
+std::shared_ptr<drivers::AdcBattery> SystemState::sAdc;
+std::shared_ptr<battery::Battery> SystemState::sBattery;
std::shared_ptr<drivers::SdStorage> SystemState::sStorage;
std::shared_ptr<drivers::Display> SystemState::sDisplay;
std::shared_ptr<drivers::Bluetooth> SystemState::sBluetooth;
@@ -95,14 +96,9 @@ void SystemState::react(const internal::SamdInterrupt&) {
}
}
-void SystemState::react(const internal::BatteryTimerFired&) {
- ESP_LOGI(kTag, "checking battery");
- if (sBattery->UpdatePercent()) {
- ESP_LOGI(kTag, "battery now at %u%%", sBattery->Percent());
- BatteryPercentChanged ev{};
- events::Ui().Dispatch(ev);
- events::System().Dispatch(ev);
- }
+auto SystemState::IdleCondition() -> bool {
+ return !sGpios->Get(drivers::IGpios::Pin::kKeyLock) &&
+ audio::AudioState::is_in_state<audio::states::Standby>();
}
} // namespace system_fsm