summaryrefslogtreecommitdiff
path: root/src/system_fsm
diff options
context:
space:
mode:
authorjacqueline <me@jacqueline.id.au>2024-01-30 12:10:23 +1100
committerjacqueline <me@jacqueline.id.au>2024-01-30 12:10:23 +1100
commit968d545d6735cd5a5c41574248fd5aeaa81471e7 (patch)
treeecfe52fda01da576eec371961b103589896846fb /src/system_fsm
parenteacea59e8a3f9602ed06834a8edc4e6ab18a4bb9 (diff)
downloadtangara-fw-968d545d6735cd5a5c41574248fd5aeaa81471e7.tar.gz
hand off the sd card to the samd properly, and remount when it's finished
Diffstat (limited to 'src/system_fsm')
-rw-r--r--src/system_fsm/include/system_events.hpp4
-rw-r--r--src/system_fsm/include/system_fsm.hpp2
-rw-r--r--src/system_fsm/running.cpp42
3 files changed, 48 insertions, 0 deletions
diff --git a/src/system_fsm/include/system_events.hpp b/src/system_fsm/include/system_events.hpp
index 794cf84f..a363887e 100644
--- a/src/system_fsm/include/system_events.hpp
+++ b/src/system_fsm/include/system_events.hpp
@@ -53,6 +53,10 @@ struct SdDetectChanged : tinyfsm::Event {
bool has_sd_card;
};
+struct SamdUsbMscChanged : tinyfsm::Event {
+ bool en;
+};
+
struct ChargingStatusChanged : tinyfsm::Event {};
struct BatteryStateChanged : tinyfsm::Event {
battery::Battery::BatteryState new_state;
diff --git a/src/system_fsm/include/system_fsm.hpp b/src/system_fsm/include/system_fsm.hpp
index 1e340711..5a0ea599 100644
--- a/src/system_fsm/include/system_fsm.hpp
+++ b/src/system_fsm/include/system_fsm.hpp
@@ -61,6 +61,7 @@ class SystemState : public tinyfsm::Fsm<SystemState> {
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::PlaybackFinished&) {}
virtual void react(const internal::IdleTimeout&) {}
@@ -101,6 +102,7 @@ class Running : public SystemState {
void react(const SdDetectChanged&) override;
void react(const audio::PlaybackFinished&) override;
void react(const database::event::UpdateFinished&) override;
+ void react(const SamdUsbMscChanged&) override;
using SystemState::react;
diff --git a/src/system_fsm/running.cpp b/src/system_fsm/running.cpp
index ec448657..60103086 100644
--- a/src/system_fsm/running.cpp
+++ b/src/system_fsm/running.cpp
@@ -10,6 +10,7 @@
#include "db_events.hpp"
#include "file_gatherer.hpp"
#include "freertos/projdefs.h"
+#include "gpios.hpp"
#include "result.hpp"
#include "audio_fsm.hpp"
@@ -55,6 +56,11 @@ void Running::react(const database::event::UpdateFinished&) {
}
void Running::react(const SdDetectChanged& ev) {
+ if (sServices->samd().UsbMassStorage()) {
+ // We don't currently control the sd card, so don't mess with it.
+ return;
+ }
+
if (ev.has_sd_card) {
if (!sStorage && mountStorage()) {
events::Ui().Dispatch(StorageMounted{});
@@ -64,6 +70,42 @@ void Running::react(const SdDetectChanged& ev) {
}
}
+void Running::react(const SamdUsbMscChanged& ev) {
+ if (ev.en) {
+ // Stop using the sd card, and power it off.
+ unmountStorage();
+
+ // Set up the SD card for usage by the samd21.
+ auto& gpios = sServices->gpios();
+ gpios.WriteSync(drivers::IGpios::Pin::kSdPowerEnable, 1);
+ gpios.WriteSync(drivers::IGpios::Pin::kSdMuxSwitch,
+ drivers::IGpios::SD_MUX_SAMD);
+ gpios.WriteSync(drivers::IGpios::Pin::kSdMuxDisable, 0);
+
+ // Off you go!
+ sServices->samd().UsbMassStorage(true);
+ } else {
+ // Make sure the samd knows that its access is going away, and give it time
+ // to finish up any remaining work.
+ sServices->samd().UsbMassStorage(false);
+ vTaskDelay(pdMS_TO_TICKS(250));
+
+ auto& gpios = sServices->gpios();
+ // No more writing, please!
+ gpios.WriteSync(drivers::IGpios::Pin::kSdMuxDisable, 1);
+ vTaskDelay(pdMS_TO_TICKS(100));
+
+ // Reboot the SD card so that it comes up in a consistent state.
+ // TODO: can we avoid doing this?
+ gpios.WriteSync(drivers::IGpios::Pin::kSdPowerEnable, 0);
+
+ // Now it's ready for us.
+ if (mountStorage()) {
+ events::Ui().Dispatch(StorageMounted{});
+ }
+ }
+}
+
auto Running::mountStorage() -> bool {
ESP_LOGI(kTag, "mounting sd card");
auto storage_res = drivers::SdStorage::Create(sServices->gpios());