From 1573a8c4cde1cd9528b422b2dcc598e37ffe94a7 Mon Sep 17 00:00:00 2001 From: jacqueline Date: Thu, 2 May 2024 19:12:26 +1000 Subject: WIP merge cyclically dependent components into one big component --- src/tangara/system_fsm/system_fsm.cpp | 102 ++++++++++++++++++++++++++++++++++ 1 file changed, 102 insertions(+) create mode 100644 src/tangara/system_fsm/system_fsm.cpp (limited to 'src/tangara/system_fsm/system_fsm.cpp') diff --git a/src/tangara/system_fsm/system_fsm.cpp b/src/tangara/system_fsm/system_fsm.cpp new file mode 100644 index 00000000..59d41c73 --- /dev/null +++ b/src/tangara/system_fsm/system_fsm.cpp @@ -0,0 +1,102 @@ +/* + * Copyright 2023 jacqueline + * + * SPDX-License-Identifier: GPL-3.0-only + */ + +#include "system_fsm.hpp" +#include "audio_fsm.hpp" +#include "driver/gpio.h" +#include "event_queue.hpp" +#include "gpios.hpp" +#include "service_locator.hpp" +#include "system_events.hpp" +#include "tag_parser.hpp" +#include "track_queue.hpp" + +[[maybe_unused]] static const char kTag[] = "system"; + +namespace system_fsm { + +std::shared_ptr SystemState::sServices; +std::unique_ptr SystemState::sStorage; + +console::AppConsole* SystemState::sAppConsole; + +void check_interrupts_cb(TimerHandle_t timer) { + if (!gpio_get_level(GPIO_NUM_34)) { + events::System().Dispatch(internal::GpioInterrupt{}); + } + if (!gpio_get_level(GPIO_NUM_35)) { + events::System().Dispatch(internal::SamdInterrupt{}); + } +} + +void SystemState::react(const FatalError& err) { + if (!is_in_state()) { + transit(); + } +} + +void SystemState::react(const HapticTrigger& trigger) { + auto& haptics = sServices->haptics(); + haptics.PlayWaveformEffect(trigger.effect); +} + +void SystemState::react(const internal::GpioInterrupt&) { + auto& gpios = sServices->gpios(); + bool prev_key_lock = gpios.IsLocked(); + bool prev_has_headphones = !gpios.Get(drivers::Gpios::Pin::kPhoneDetect); + bool prev_has_sd = gpios.Get(drivers::Gpios::Pin::kSdCardDetect); + + gpios.Read(); + + bool key_lock = gpios.IsLocked(); + bool has_headphones = !gpios.Get(drivers::Gpios::Pin::kPhoneDetect); + bool has_sd = gpios.Get(drivers::Gpios::Pin::kSdCardDetect); + + if (key_lock != prev_key_lock) { + KeyLockChanged ev{.locking = key_lock}; + events::System().Dispatch(ev); + events::Audio().Dispatch(ev); + events::Ui().Dispatch(ev); + } + if (has_headphones != prev_has_headphones) { + HasPhonesChanged ev{.has_headphones = has_headphones}; + events::Audio().Dispatch(ev); + } + if (has_sd != prev_has_sd) { + SdDetectChanged ev{.has_sd_card = !has_sd}; + events::System().Dispatch(ev); + events::Ui().Dispatch(ev); + } +} + +void SystemState::react(const internal::SamdInterrupt&) { + auto& samd = sServices->samd(); + auto prev_charge_status = samd.GetChargeStatus(); + auto prev_usb_status = samd.GetUsbStatus(); + + samd.UpdateChargeStatus(); + samd.UpdateUsbStatus(); + + auto charge_status = samd.GetChargeStatus(); + auto usb_status = samd.GetUsbStatus(); + + if (charge_status != prev_charge_status && sServices) { + sServices->battery().Update(); + } + if (usb_status != prev_usb_status) { + events::Ui().Dispatch(SamdUsbStatusChanged{.new_status = usb_status}); + } +} + +auto SystemState::IdleCondition() -> bool { + auto db = sServices->database().lock(); + return sServices->gpios().IsLocked() && !(db && db->isUpdating()) && + audio::AudioState::is_in_state(); +} + +} // namespace system_fsm + +FSM_INITIAL_STATE(system_fsm::SystemState, system_fsm::states::Booting) -- cgit v1.2.3