summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/drivers/storage.cpp2
-rw-r--r--src/system_fsm/include/system_events.hpp3
-rw-r--r--src/system_fsm/include/system_fsm.hpp13
-rw-r--r--src/system_fsm/running.cpp76
-rw-r--r--src/system_fsm/system_fsm.cpp7
5 files changed, 62 insertions, 39 deletions
diff --git a/src/drivers/storage.cpp b/src/drivers/storage.cpp
index cb1407a6..9cf505f8 100644
--- a/src/drivers/storage.cpp
+++ b/src/drivers/storage.cpp
@@ -118,7 +118,7 @@ SdStorage::~SdStorage() {
sdspi_host_remove_device(this->handle_);
sdspi_host_deinit();
- gpio_.WriteSync(IGpios::Pin::kSdPowerEnable, 1);
+ gpio_.WriteSync(IGpios::Pin::kSdPowerEnable, 0);
gpio_.WriteSync(IGpios::Pin::kSdMuxDisable, 1);
}
diff --git a/src/system_fsm/include/system_events.hpp b/src/system_fsm/include/system_events.hpp
index 54e0aa9c..794cf84f 100644
--- a/src/system_fsm/include/system_events.hpp
+++ b/src/system_fsm/include/system_events.hpp
@@ -49,6 +49,9 @@ struct KeyLockChanged : tinyfsm::Event {
struct HasPhonesChanged : tinyfsm::Event {
bool has_headphones;
};
+struct SdDetectChanged : tinyfsm::Event {
+ bool has_sd_card;
+};
struct ChargingStatusChanged : tinyfsm::Event {};
struct BatteryStateChanged : tinyfsm::Event {
diff --git a/src/system_fsm/include/system_fsm.hpp b/src/system_fsm/include/system_fsm.hpp
index cb733639..2db1cddc 100644
--- a/src/system_fsm/include/system_fsm.hpp
+++ b/src/system_fsm/include/system_fsm.hpp
@@ -59,6 +59,7 @@ class SystemState : public tinyfsm::Fsm<SystemState> {
virtual void react(const StorageMounted&) {}
virtual void react(const StorageError&) {}
virtual void react(const KeyLockChanged&) {}
+ virtual void react(const SdDetectChanged&) {}
virtual void react(const audio::PlaybackFinished&) {}
virtual void react(const internal::IdleTimeout&) {}
@@ -95,12 +96,22 @@ class Running : public SystemState {
void exit() override;
void react(const KeyLockChanged&) override;
- void react(const StorageError&) override;
+ void react(const SdDetectChanged&) override;
void react(const audio::PlaybackFinished&) override;
using SystemState::react;
+
+ private:
+ auto mountStorage() -> bool;
+ 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;
diff --git a/src/system_fsm/running.cpp b/src/system_fsm/running.cpp
index 9c556e0a..9e10f9ec 100644
--- a/src/system_fsm/running.cpp
+++ b/src/system_fsm/running.cpp
@@ -25,13 +25,40 @@ namespace states {
static database::IFileGatherer* sFileGatherer;
-/*
- * Ensure the storage and database are both available. If either of these fails
- * to open, then we assume it's an issue with the underlying SD card.
- */
void Running::entry() {
+ if (mountStorage()) {
+ events::Ui().Dispatch(StorageMounted{});
+ }
+}
+
+void Running::exit() {
+ unmountStorage();
+}
+
+void Running::react(const KeyLockChanged& ev) {
+ if (IdleCondition()) {
+ transit<Idle>();
+ }
+}
+
+void Running::react(const audio::PlaybackFinished& ev) {
+ if (IdleCondition()) {
+ transit<Idle>();
+ }
+}
+
+void Running::react(const SdDetectChanged& ev) {
+ if (ev.has_sd_card) {
+ if (!sStorage && mountStorage()) {
+ events::Ui().Dispatch(StorageMounted{});
+ }
+ } else {
+ unmountStorage();
+ }
+}
+
+auto Running::mountStorage() -> bool {
ESP_LOGI(kTag, "mounting sd card");
- vTaskDelay(pdMS_TO_TICKS(250));
auto storage_res = drivers::SdStorage::Create(sServices->gpios());
if (storage_res.has_error()) {
ESP_LOGW(kTag, "failed to mount!");
@@ -44,12 +71,9 @@ void Running::entry() {
sServices->sd(drivers::SdState::kNotPresent);
break;
}
-
- events::System().Dispatch(StorageError{});
- events::Audio().Dispatch(StorageError{});
- events::Ui().Dispatch(StorageError{});
- return;
+ return false;
}
+
sStorage.reset(storage_res.value());
sServices->sd(drivers::SdState::kMounted);
@@ -59,43 +83,21 @@ void Running::entry() {
database::Database::Open(*sFileGatherer, sServices->tag_parser(),
sServices->collator(), sServices->bg_worker());
if (database_res.has_error()) {
- ESP_LOGW(kTag, "failed to open!");
- events::System().Dispatch(StorageError{});
- events::Audio().Dispatch(StorageError{});
- events::Ui().Dispatch(StorageError{});
- return;
+ unmountStorage();
+ return false;
}
+
sServices->database(
std::unique_ptr<database::Database>{database_res.value()});
ESP_LOGI(kTag, "storage loaded okay");
- StorageMounted ev{};
- events::System().Dispatch(ev);
- events::Audio().Dispatch(ev);
- events::Ui().Dispatch(ev);
+ return true;
}
-void Running::exit() {
+auto Running::unmountStorage() -> void {
sServices->database({});
sStorage.reset();
}
-void Running::react(const KeyLockChanged& ev) {
- if (IdleCondition()) {
- transit<Idle>();
- }
-}
-
-void Running::react(const audio::PlaybackFinished& ev) {
- if (IdleCondition()) {
- transit<Idle>();
- }
-}
-
-void Running::react(const StorageError& ev) {
- ESP_LOGW(kTag, "error loading storage");
- // TODO.
-}
-
} // namespace states
} // namespace system_fsm
diff --git a/src/system_fsm/system_fsm.cpp b/src/system_fsm/system_fsm.cpp
index 17f09576..df750e80 100644
--- a/src/system_fsm/system_fsm.cpp
+++ b/src/system_fsm/system_fsm.cpp
@@ -48,11 +48,13 @@ 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};
@@ -64,6 +66,11 @@ void SystemState::react(const internal::GpioInterrupt&) {
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&) {