From 8ff93f5467b0eef54d18b35d742de05c8a63da9a Mon Sep 17 00:00:00 2001 From: jacqueline Date: Mon, 28 Aug 2023 10:18:02 +1000 Subject: Make idle state more robust + check playback state --- src/system_fsm/idle.cpp | 14 ++++++++++++-- src/system_fsm/include/system_fsm.hpp | 6 ++++++ src/system_fsm/running.cpp | 9 ++++++++- src/system_fsm/system_fsm.cpp | 5 +++++ 4 files changed, 31 insertions(+), 3 deletions(-) (limited to 'src/system_fsm') 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(); } } void Idle::react(const internal::IdleTimeout& ev) { + if (!IdleCondition()) { + // Defensively ensure that we didn't miss an idle-ending event. + transit(); + 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 #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 { 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 sGpios; static std::shared_ptr sSamd; static std::shared_ptr 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()) { + if (IdleCondition()) { + transit(); + } +} + +void Running::react(const audio::PlaybackFinished& ev) { + if (IdleCondition()) { transit(); } } 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(); +} + } // namespace system_fsm FSM_INITIAL_STATE(system_fsm::SystemState, system_fsm::states::Booting) -- cgit v1.2.3 From 3a0c42f9240eedfbc6a1e94ad3a59c52664fb5b5 Mon Sep 17 00:00:00 2001 From: jacqueline Date: Mon, 28 Aug 2023 13:26:53 +1000 Subject: Move battery measurement to its own class --- src/system_fsm/CMakeLists.txt | 2 +- src/system_fsm/booting.cpp | 24 ++++++++---------------- src/system_fsm/include/system_events.hpp | 4 +--- src/system_fsm/include/system_fsm.hpp | 4 ++-- src/system_fsm/system_fsm.cpp | 13 ++----------- 5 files changed, 14 insertions(+), 33 deletions(-) (limited to 'src/system_fsm') 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/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 a556be9e..371e5527 100644 --- a/src/system_fsm/include/system_fsm.hpp +++ b/src/system_fsm/include/system_fsm.hpp @@ -48,7 +48,6 @@ class SystemState : public tinyfsm::Fsm { 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&) {} @@ -67,7 +66,8 @@ class SystemState : public tinyfsm::Fsm { static std::shared_ptr sTouch; static std::shared_ptr sRelativeTouch; - static std::shared_ptr sBattery; + static std::shared_ptr sAdc; + static std::shared_ptr sBattery; static std::shared_ptr sStorage; static std::shared_ptr sDisplay; static std::shared_ptr sBluetooth; diff --git a/src/system_fsm/system_fsm.cpp b/src/system_fsm/system_fsm.cpp index 9ad89c7a..d21e8bcb 100644 --- a/src/system_fsm/system_fsm.cpp +++ b/src/system_fsm/system_fsm.cpp @@ -23,7 +23,8 @@ std::shared_ptr SystemState::sNvs; std::shared_ptr SystemState::sTouch; std::shared_ptr SystemState::sRelativeTouch; -std::shared_ptr SystemState::sBattery; +std::shared_ptr SystemState::sAdc; +std::shared_ptr SystemState::sBattery; std::shared_ptr SystemState::sStorage; std::shared_ptr SystemState::sDisplay; std::shared_ptr SystemState::sBluetooth; @@ -95,16 +96,6 @@ 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(); -- cgit v1.2.3