blob: 398a0b9bda134da5e6e9f756c61dd726252c8f3a (
plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
|
/*
* Copyright 2023 jacqueline <me@jacqueline.id.au>
*
* SPDX-License-Identifier: GPL-3.0-only
*/
#pragma once
#include <memory>
#include "freertos/FreeRTOS.h"
#include "freertos/timers.h"
#include "app_console/app_console.hpp"
#include "audio/audio_events.hpp"
#include "audio/track_queue.hpp"
#include "battery/battery.hpp"
#include "database/database.hpp"
#include "database/db_events.hpp"
#include "database/tag_parser.hpp"
#include "drivers/bluetooth.hpp"
#include "drivers/display.hpp"
#include "drivers/gpios.hpp"
#include "drivers/nvs.hpp"
#include "drivers/samd.hpp"
#include "drivers/storage.hpp"
#include "drivers/touchwheel.hpp"
#include "system_fsm/service_locator.hpp"
#include "system_fsm/system_events.hpp"
#include "ui/ui_fsm.hpp"
#include "tinyfsm.hpp"
namespace system_fsm {
void check_interrupts_cb(TimerHandle_t timer);
/*
* State machine for the overall system state. Responsible for managing
* peripherals, and bringing the rest of the system up and down.
*/
class SystemState : public tinyfsm::Fsm<SystemState> {
public:
virtual ~SystemState() {}
virtual void entry() {}
virtual void exit() {}
/* Fallback event handler. Does nothing. */
void react(const tinyfsm::Event& ev) {}
void react(const FatalError&);
void react(const internal::GpioInterrupt&);
void react(const internal::SamdInterrupt&);
void react(const HapticTrigger&);
virtual void react(const DisplayReady&) {}
virtual void react(const BootComplete&) {}
virtual void react(const StorageError&) {}
virtual void react(const KeyLockChanged&) {}
virtual void react(const SdDetectChanged&) {}
virtual void react(const SamdUsbMscChanged&) {}
virtual void react(const database::event::UpdateFinished&) {}
virtual void react(const audio::PlaybackUpdate&) {}
virtual void react(const internal::IdleTimeout&) {}
virtual void react(const internal::UnmountTimeout&) {}
virtual void react(const internal::Mount&) {}
virtual void react(const ui::UnmountRequest&) {}
virtual void react(const audio::UnmountReady&) {}
protected:
auto IdleCondition() -> bool;
static std::shared_ptr<ServiceLocator> sServices;
static std::unique_ptr<drivers::SdStorage> sStorage;
static console::AppConsole* sAppConsole;
};
namespace states {
/*
* Initial state. Initialises peripherals, starts up lvgl, checks everything
* looks good.
*/
class Booting : public SystemState {
public:
void entry() override;
void exit() override;
void react(const BootComplete&) override;
using SystemState::react;
};
/*
* Most common state. Everything is going full bore!
*/
class Running : public SystemState {
public:
void entry() override;
void exit() override;
void react(const KeyLockChanged&) override;
void react(const SdDetectChanged&) override;
void react(const audio::PlaybackUpdate&) override;
void react(const database::event::UpdateFinished&) override;
void react(const SamdUsbMscChanged&) override;
void react(const StorageError&) override;
void react(const ui::UnmountRequest&) override;
void react(const audio::UnmountReady&) override;
void react(const internal::UnmountTimeout&) override;
void react(const internal::Mount&) override;
using SystemState::react;
private:
auto checkIdle() -> void;
auto updateSdState(drivers::SdState) -> void;
auto unmountStorage() -> void;
bool storage_mounted_;
};
/**
* State for when the screen is off, controls locked, and music paused. Prelude
* to shutting off power completely.
*/
class Idle : public SystemState {
public:
void entry() override;
void exit() override;
void react(const KeyLockChanged&) override;
void react(const internal::IdleTimeout&) override;
using SystemState::react;
private:
TimerHandle_t sIdleTimeout;
};
/*
* Something unrecoverably bad went wrong. Shows an error (if possible), awaits
* reboot.
*/
class Error : public SystemState {};
} // namespace states
} // namespace system_fsm
|