From 64058c04cc562cbeda1ac1e3cfcb4578befbf764 Mon Sep 17 00:00:00 2001 From: "Brian S. Stephan" Date: Tue, 1 Oct 2024 14:39:03 -0500 Subject: [PATCH 1/3] only write the config to flash when it is safe to the USB host port uses the flash, as does our config. both cores accessing the flash at the same time is no good and will crash the host port, so the host port core is locked when writing flash for saving the config, but this disables interrupts on the port and may interfere with auth, so this only saves at runtime when it is safe to (when USB host is disabled), with an optional flag to force saving the config, which should only be used in limited circumstances. --- headers/storagemanager.h | 1 + src/configmanager.cpp | 6 ------ src/gamepad.cpp | 7 +------ src/gp2040.cpp | 4 +++- src/storagemanager.cpp | 23 ++++++++++++++++------- 5 files changed, 21 insertions(+), 20 deletions(-) diff --git a/headers/storagemanager.h b/headers/storagemanager.h index 8778e5842..bed769283 100644 --- a/headers/storagemanager.h +++ b/headers/storagemanager.h @@ -49,6 +49,7 @@ class Storage { void init(); bool save(); + bool save(const bool force); // Perform saves that were enqueued from core1 void performEnqueuedSaves(); diff --git a/src/configmanager.cpp b/src/configmanager.cpp index 62592d3d4..3adc315c2 100644 --- a/src/configmanager.cpp +++ b/src/configmanager.cpp @@ -1,8 +1,6 @@ #include "configmanager.h" -#include "addonmanager.h" #include "configs/webconfig.h" -#include "addons/neopicoleds.h" void ConfigManager::setup(ConfigType config) { if (config == CONFIG_TYPE_WEB) @@ -19,7 +17,3 @@ void ConfigManager::setupConfig(GPConfig * gpconfig) { gpconfig->setup(); this->config = gpconfig; } - -void ConfigManager::setGamepadOptions(Gamepad* gamepad) { - gamepad->save(); -} diff --git a/src/gamepad.cpp b/src/gamepad.cpp index 3a1ffce8e..16ee3268e 100644 --- a/src/gamepad.cpp +++ b/src/gamepad.cpp @@ -323,11 +323,6 @@ void Gamepad::read() state.rt = 0; } -void Gamepad::save() -{ - Storage::getInstance().save(); -} - void Gamepad::hotkey() { if (options.lockHotkeys) @@ -583,6 +578,6 @@ void Gamepad::processHotkeyAction(GamepadHotkey action) { // only save if requested if (reqSave) { - save(); + Storage::getInstance().save(); } } diff --git a/src/gp2040.cpp b/src/gp2040.cpp index ed76528e6..6566ceb2a 100644 --- a/src/gp2040.cpp +++ b/src/gp2040.cpp @@ -177,7 +177,9 @@ void GP2040::setup() { // Save the changed input mode if (inputMode != gamepad->getOptions().inputMode) { gamepad->setInputMode(inputMode); - gamepad->save(); + // save to match user expectations on choosing mode at boot, and this is + // before USB host will be used so we can force it to ignore the check + Storage::getInstance().save(true); } } diff --git a/src/storagemanager.cpp b/src/storagemanager.cpp index c8d2121fe..68d7de338 100644 --- a/src/storagemanager.cpp +++ b/src/storagemanager.cpp @@ -7,29 +7,38 @@ #include "BoardConfig.h" #include "AnimationStorage.hpp" -#include "Effects/StaticColor.hpp" #include "FlashPROM.h" +#include "peripheralmanager.h" #include "config.pb.h" #include "hardware/watchdog.h" -#include "Animation.hpp" #include "CRC32.h" #include "types.h" #include "config_utils.h" -#include "bitmaps.h" - -#include "helper.h" - void Storage::init() { EEPROM.start(); critical_section_init(&animationOptionsCs); ConfigUtils::load(config); } +/** + * @brief Save the config, but only if it is safe to (as in USB host is not being used.) + */ bool Storage::save() { - return ConfigUtils::save(config); + return save(false); +} + +/** + * @brief Save the config; if forcing a save is requested, or if USB host is not enabled, this will write to flash. + */ +bool Storage::save(const bool force) { + if (!PeripheralManager::getInstance().isUSBEnabled(0) || force) { + return ConfigUtils::save(config); + } else { + return false; + } } static void updateAnimationOptionsProto(const AnimationOptions& options) From ffba86a1743e533c526aae650c9bd20114b2f545 Mon Sep 17 00:00:00 2001 From: "Brian S. Stephan" Date: Tue, 1 Oct 2024 14:47:41 -0500 Subject: [PATCH 2/3] always force config saves in the webconfig it doesn't use the USB host port for anything so this should always be fine --- src/configs/webconfig.cpp | 32 ++++++++++++++++---------------- 1 file changed, 16 insertions(+), 16 deletions(-) diff --git a/src/configs/webconfig.cpp b/src/configs/webconfig.cpp index a77fdae53..ab78f607c 100644 --- a/src/configs/webconfig.cpp +++ b/src/configs/webconfig.cpp @@ -469,7 +469,7 @@ std::string setDisplayOptions(DisplayOptions& displayOptions) std::string setDisplayOptions() { std::string response = setDisplayOptions(Storage::getInstance().getDisplayOptions()); - Storage::getInstance().save(); + Storage::getInstance().save(true); return response; } @@ -533,7 +533,7 @@ std::string setSplashImage() memcpy(displayOptions.splashImage.bytes, decoded.data(), length); displayOptions.splashImage.size = length; - Storage::getInstance().save(); + Storage::getInstance().save(true); return serialize_json(doc); } @@ -578,7 +578,7 @@ std::string setProfileOptions() if (altsIndex > 2) break; } - Storage::getInstance().save(); + Storage::getInstance().save(true); return serialize_json(doc); } @@ -688,7 +688,7 @@ std::string setGamepadOptions() ForcedSetupOptions& forcedSetupOptions = Storage::getInstance().getForcedSetupOptions(); readDoc(forcedSetupOptions.mode, doc, "forcedSetupMode"); - Storage::getInstance().save(); + Storage::getInstance().save(true); return serialize_json(doc); } @@ -800,7 +800,7 @@ std::string setLedOptions() readDoc(ledOptions.pledIndex4, doc, "pledIndex4"); readDoc(ledOptions.pledColor, doc, "pledColor"); - Storage::getInstance().save(); + Storage::getInstance().save(true); return serialize_json(doc); } @@ -1005,7 +1005,7 @@ std::string setCustomTheme() options.buttonPressColorCooldownTimeInMs = pressCooldown; AnimationStation::SetOptions(options); - AnimationStore.save(); + Storage::getInstance().save(true); return serialize_json(doc); } @@ -1081,7 +1081,7 @@ std::string setPinMappings() gpioMappings.profileLabel[profileLabelSize - 1] = '\0'; gpioMappings.enabled = doc["enabled"]; - Storage::getInstance().save(); + Storage::getInstance().save(true); return serialize_json(doc); } @@ -1175,7 +1175,7 @@ std::string setKeyMappings() readDoc(keyboardMapping.keyButtonE11, doc, "E11"); readDoc(keyboardMapping.keyButtonE12, doc, "E12"); - Storage::getInstance().save(); + Storage::getInstance().save(true); return serialize_json(doc); } @@ -1335,7 +1335,7 @@ std::string setPeripheralOptions() profiles.gpioMappingsSets[2].pins[oldPinDplus+adjacent].action = GpioAction::NONE; } - Storage::getInstance().save(); + Storage::getInstance().save(true); return serialize_json(doc); } @@ -1401,7 +1401,7 @@ std::string setExpansionPins() } Storage::getInstance().getAddonOptions().pcf8575Options.pins_count = 16; - Storage::getInstance().save(); + Storage::getInstance().save(true); return serialize_json(doc); } @@ -1435,7 +1435,7 @@ std::string setReactiveLEDs() } Storage::getInstance().getAddonOptions().reactiveLEDOptions.leds_count = 10; - Storage::getInstance().save(); + Storage::getInstance().save(true); return serialize_json(doc); } @@ -1628,7 +1628,7 @@ std::string setAddonOptions() docToValue(drv8833RumbleOptions.dutyMin, doc, "drv8833RumbleDutyMin"); docToValue(drv8833RumbleOptions.dutyMax, doc, "drv8833RumbleDutyMax"); - Storage::getInstance().save(); + Storage::getInstance().save(true); return serialize_json(doc); } @@ -1701,7 +1701,7 @@ std::string setPS4Options() if (ps4Options.rsaQP.size != 0) ps4Options.rsaQP.size = 0; if (ps4Options.rsaRN.size != 0) ps4Options.rsaRN.size = 0; - Storage::getInstance().save(); + Storage::getInstance().save(true); return "{\"success\":true}"; } @@ -1784,7 +1784,7 @@ std::string setWiiControls() readDoc(wiiOptions.controllers.turntable.effects.axisType, doc, "turntable.analogEffects.axisType"); readDoc(wiiOptions.controllers.turntable.fader.axisType, doc, "turntable.analogFader.axisType"); - Storage::getInstance().save(); + Storage::getInstance().save(true); return "{\"success\":true}"; } @@ -2106,7 +2106,7 @@ std::string setMacroAddonOptions() macroOptions.macroList_count = MAX_MACRO_LIMIT; - Storage::getInstance().save(); + Storage::getInstance().save(true); return serialize_json(doc); } @@ -2254,7 +2254,7 @@ DataAndStatusCode setConfig() { Storage::getInstance().getConfig() = *config.get(); config.reset(); - if (Storage::getInstance().save()) + if (Storage::getInstance().save(true)) { return DataAndStatusCode(getConfig(), HttpStatusCode::_200); } From 93adf709b91d2c5486e416fcbee15e5f4658ff53 Mon Sep 17 00:00:00 2001 From: "Brian S. Stephan" Date: Tue, 1 Oct 2024 15:47:11 -0500 Subject: [PATCH 3/3] add a hotkey to force a save of the config --- proto/enums.proto | 1 + src/gamepad.cpp | 3 +++ www/src/Locales/en/SettingsPage.jsx | 1 + www/src/Pages/SettingsPage.jsx | 1 + 4 files changed, 6 insertions(+) diff --git a/proto/enums.proto b/proto/enums.proto index db76de54b..7fa979950 100644 --- a/proto/enums.proto +++ b/proto/enums.proto @@ -300,6 +300,7 @@ enum GamepadHotkey HOTKEY_DPAD_LEFT = 40; HOTKEY_DPAD_RIGHT = 41; HOTKEY_PREVIOUS_PROFILE = 42; + HOTKEY_SAVE_CONFIG = 43; } // This has to be kept in sync with LEDFormat in NeoPico.hpp diff --git a/src/gamepad.cpp b/src/gamepad.cpp index 16ee3268e..c98b8b586 100644 --- a/src/gamepad.cpp +++ b/src/gamepad.cpp @@ -495,6 +495,9 @@ void Gamepad::processHotkeyAction(GamepadHotkey action) { case HOTKEY_REBOOT_DEFAULT: System::reboot(System::BootMode::DEFAULT); break; + case HOTKEY_SAVE_CONFIG: + Storage::getInstance().save(true); + break; case HOTKEY_CAPTURE_BUTTON: state.buttons |= GAMEPAD_MASK_A2; break; diff --git a/www/src/Locales/en/SettingsPage.jsx b/www/src/Locales/en/SettingsPage.jsx index 1a5955902..6c6a0cf9c 100644 --- a/www/src/Locales/en/SettingsPage.jsx +++ b/www/src/Locales/en/SettingsPage.jsx @@ -127,6 +127,7 @@ export default { 'load-profile-3': 'Load Profile #3', 'load-profile-4': 'Load Profile #4', 'reboot-default': 'Reboot GP2040-CE', + 'save-config': 'Save Config', 'next-profile': 'Next Profile', 'previous-profile': 'Previous Profile', }, diff --git a/www/src/Pages/SettingsPage.jsx b/www/src/Pages/SettingsPage.jsx index 443f01eca..5fffdea7d 100644 --- a/www/src/Pages/SettingsPage.jsx +++ b/www/src/Pages/SettingsPage.jsx @@ -266,6 +266,7 @@ const HOTKEY_ACTIONS = [ { labelKey: 'hotkey-actions.r3-button', value: 20 }, { labelKey: 'hotkey-actions.touchpad-button', value: 21 }, { labelKey: 'hotkey-actions.reboot-default', value: 22 }, + { labelKey: 'hotkey-actions.save-config', value: 43 }, { labelKey: 'hotkey-actions.b1-button', value: 23 }, { labelKey: 'hotkey-actions.b2-button', value: 24 }, { labelKey: 'hotkey-actions.b3-button', value: 25 },