summaryrefslogtreecommitdiff
path: root/src/tangara/system_fsm/system_fsm.cpp
diff options
context:
space:
mode:
authorcooljqln <cooljqln@noreply.codeberg.org>2024-05-03 04:48:17 +0000
committercooljqln <cooljqln@noreply.codeberg.org>2024-05-03 04:48:17 +0000
commit3ceb8025ee4330c177101ed30ec17dfb0002f41e (patch)
tree58350210f15df7d00d967cac6f30eeceeb031a3c /src/tangara/system_fsm/system_fsm.cpp
parent964da15a0b84f8e5f00e8abac2f7dfda0bf60488 (diff)
parent9fafd797a5504f458b5fcae4a1d28a68da936315 (diff)
downloadtangara-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.cpp102
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)