diff options
| author | cooljqln <cooljqln@noreply.codeberg.org> | 2024-05-03 04:48:17 +0000 |
|---|---|---|
| committer | cooljqln <cooljqln@noreply.codeberg.org> | 2024-05-03 04:48:17 +0000 |
| commit | 3ceb8025ee4330c177101ed30ec17dfb0002f41e (patch) | |
| tree | 58350210f15df7d00d967cac6f30eeceeb031a3c /src/tangara/system_fsm/system_fsm.cpp | |
| parent | 964da15a0b84f8e5f00e8abac2f7dfda0bf60488 (diff) | |
| parent | 9fafd797a5504f458b5fcae4a1d28a68da936315 (diff) | |
| download | tangara-fw-3ceb8025ee4330c177101ed30ec17dfb0002f41e.tar.gz | |
Merge pull request 'Break dependency cycles with our components by merging co-dependent components together' (#68) from jqln/component-merge into main
Reviewed-on: https://codeberg.org/cool-tech-zone/tangara-fw/pulls/68
Diffstat (limited to 'src/tangara/system_fsm/system_fsm.cpp')
| -rw-r--r-- | src/tangara/system_fsm/system_fsm.cpp | 102 |
1 files changed, 102 insertions, 0 deletions
diff --git a/src/tangara/system_fsm/system_fsm.cpp b/src/tangara/system_fsm/system_fsm.cpp new file mode 100644 index 00000000..2e819569 --- /dev/null +++ b/src/tangara/system_fsm/system_fsm.cpp @@ -0,0 +1,102 @@ +/* + * Copyright 2023 jacqueline <me@jacqueline.id.au> + * + * SPDX-License-Identifier: GPL-3.0-only + */ + +#include "system_fsm/system_fsm.hpp" +#include "audio/audio_fsm.hpp" +#include "audio/track_queue.hpp" +#include "database/tag_parser.hpp" +#include "driver/gpio.h" +#include "drivers/gpios.hpp" +#include "events/event_queue.hpp" +#include "system_fsm/service_locator.hpp" +#include "system_fsm/system_events.hpp" + +[[maybe_unused]] static const char kTag[] = "system"; + +namespace system_fsm { + +std::shared_ptr<ServiceLocator> SystemState::sServices; +std::unique_ptr<drivers::SdStorage> 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<states::Error>()) { + transit<states::Error>(); + } +} + +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<audio::states::Standby>(); +} + +} // namespace system_fsm + +FSM_INITIAL_STATE(system_fsm::SystemState, system_fsm::states::Booting) |
