From dadac304dd930ddf4c5aebcc069c5d9f881b2b60 Mon Sep 17 00:00:00 2001 From: jacqueline Date: Thu, 21 Mar 2024 11:51:48 +1100 Subject: [PATCH] Add very basic usb msc ui --- lua/settings.lua | 50 ++++++++++++++++++++++++++++++++++++++ src/system_fsm/idle.cpp | 10 +++++++- src/system_fsm/running.cpp | 6 ++++- src/ui/include/ui_fsm.hpp | 2 ++ src/ui/ui_fsm.cpp | 15 ++++++++++++ 5 files changed, 81 insertions(+), 2 deletions(-) diff --git a/lua/settings.lua b/lua/settings.lua index 9d9ccf2d..e9e9d370 100644 --- a/lua/settings.lua +++ b/lua/settings.lua @@ -275,6 +275,53 @@ local InputSettings = screen:new { end } +local MassStorageSettings = screen:new { + createUi = function(self) + self.menu = SettingsScreen("USB Storage") + local version = require("version").samd() + if tonumber(version) < 2 then + self.menu.content:Label { + w = lvgl.PCT(100), + text = "Usb Mass Storage requires a SAMD21 firmware version >=2." + } + return + end + + local enable_container = self.menu.content:Object { + flex = { + flex_direction = "row", + justify_content = "flex-start", + align_items = "content", + align_content = "flex-start", + }, + w = lvgl.PCT(100), + h = lvgl.SIZE_CONTENT, + pad_bottom = 1, + } + enable_container:Label { text = "Enable", flex_grow = 1 } + local enable_sw = enable_container:Switch {} + + local usb = require("usb") + local bind_switch = function() + if usb.msc_enabled:get() then + enable_sw:add_state(lvgl.STATE.CHECKED) + else + enable_sw:clear_state(lvgl.STATE.CHECKED) + end + end + + enable_sw:onevent(lvgl.EVENT.VALUE_CHANGED, function() + usb.msc_enabled:set(enable_sw:enabled()) + bind_switch() + end) + + self.bindings = { + usb.msc_enabled:bind(bind_switch), + } + end, + canPop = true +} + local DatabaseSettings = screen:new { createUi = function(self) self.menu = SettingsScreen("Database") @@ -352,6 +399,9 @@ return screen:new { submenu("Display", DisplaySettings) submenu("Input Method", InputSettings) + section("USB") + submenu("Storage", MassStorageSettings) + section("System") submenu("Database", DatabaseSettings) submenu("Firmware", FirmwareSettings) diff --git a/src/system_fsm/idle.cpp b/src/system_fsm/idle.cpp index b6bb2572..980f0c94 100644 --- a/src/system_fsm/idle.cpp +++ b/src/system_fsm/idle.cpp @@ -13,6 +13,7 @@ #include "audio_fsm.hpp" #include "event_queue.hpp" +#include "samd.hpp" #include "storage.hpp" #include "system_events.hpp" #include "system_fsm.hpp" @@ -40,7 +41,7 @@ void Idle::entry() { events::Audio().Dispatch(OnIdle{}); events::Ui().Dispatch(OnIdle{}); - sIdleTimeout = xTimerCreate("idle_timeout", kTicksBeforeSleep, false, NULL, + sIdleTimeout = xTimerCreate("idle_timeout", kTicksBeforeSleep, true, NULL, timer_callback); xTimerStart(sIdleTimeout, portMAX_DELAY); } @@ -63,6 +64,13 @@ void Idle::react(const internal::IdleTimeout& ev) { transit(); return; } + auto s = static_cast(sServices->samd().GetUsbStatus()); + ESP_LOGI(kTag, "usb status is %i", s); + if (sServices->samd().GetUsbStatus() != drivers::Samd::UsbStatus::kDetached) { + // Stay powered on if we're plugged in, in order to charge faster, sync + // files, flash updates, etc. + return; + } ESP_LOGI(kTag, "system shutting down"); // FIXME: It would be neater to just free a bunch of our pointers, deinit the diff --git a/src/system_fsm/running.cpp b/src/system_fsm/running.cpp index d1d02fab..d80809e6 100644 --- a/src/system_fsm/running.cpp +++ b/src/system_fsm/running.cpp @@ -41,7 +41,11 @@ void Running::entry() { sUnmountTimer = xTimerCreate("unmount_timeout", kTicksBeforeUnmount, false, NULL, timer_callback); } - mountStorage(); + // Only mount our storage immediately if we know it's not currently in use + // by the SAMD. + if (!sServices->samd().UsbMassStorage()) { + mountStorage(); + } } void Running::exit() { diff --git a/src/ui/include/ui_fsm.hpp b/src/ui/include/ui_fsm.hpp index 579cc2bb..f7fde1dd 100644 --- a/src/ui/include/ui_fsm.hpp +++ b/src/ui/include/ui_fsm.hpp @@ -132,6 +132,8 @@ class UiState : public tinyfsm::Fsm { static lua::Property sLockSwitch; static lua::Property sDatabaseUpdating; + + static lua::Property sUsbMassStorageEnabled; }; namespace states { diff --git a/src/ui/ui_fsm.cpp b/src/ui/ui_fsm.cpp index c11f66a7..a913a339 100644 --- a/src/ui/ui_fsm.cpp +++ b/src/ui/ui_fsm.cpp @@ -285,6 +285,17 @@ lua::Property UiState::sLockSwitch{false}; lua::Property UiState::sDatabaseUpdating{false}; +lua::Property UiState::sUsbMassStorageEnabled{ + false, [](const lua::LuaValue& val) { + if (!std::holds_alternative(val)) { + return false; + } + bool enable = std::get(val); + // FIXME: Check for system busy. + events::System().Dispatch(system_fsm::SamdUsbMscChanged{.en = enable}); + return true; + }}; + auto UiState::InitBootSplash(drivers::IGpios& gpios, drivers::NvsStorage& nvs) -> bool { // Init LVGL first, since the display driver registers itself with LVGL. @@ -553,6 +564,10 @@ void Lua::entry() { registry.AddPropertyModule("database", { {"updating", &sDatabaseUpdating}, }); + registry.AddPropertyModule("usb", + { + {"msc_enabled", &sUsbMassStorageEnabled}, + }); auto bt = sServices->bluetooth(); sBluetoothEnabled.Update(bt.IsEnabled());