diff --git a/firmware/Gravity/Gravity.ino b/firmware/Gravity/Gravity.ino index aef4ab8..b79d2e9 100644 --- a/firmware/Gravity/Gravity.ino +++ b/firmware/Gravity/Gravity.ino @@ -2,7 +2,7 @@ * @file Gravity.ino * @author Adam Wonak (https://github.com/awonak/) * @brief Alt firmware version of Gravity by Sitka Instruments. - * @version v2.0.0 - June 2025 awonak - Full rewrite + * @version v2.0.1 - June 2025 awonak - Full rewrite * @version v1.0 - August 2023 Oleksiy H - Initial release * @date 2025-07-04 * @@ -227,8 +227,16 @@ void HandleEncoderPressed() { case PARAM_MAIN_LOAD_DATA: if (app.selected_sub_param < StateManager::MAX_SAVE_SLOTS) { app.selected_save_slot = app.selected_sub_param; + // Load pattern data into app state. stateManager.loadData(app, app.selected_save_slot); - InitGravity(app); + // Load global performance settings if they have changed. + if (gravity.clock.Tempo() != app.tempo) { + gravity.clock.SetTempo(app.tempo); + } + // Load global settings only clock is not active. + if (gravity.clock.IsPaused()) { + InitGravity(app); + } } break; case PARAM_MAIN_FACTORY_RESET: diff --git a/firmware/Gravity/save_state.cpp b/firmware/Gravity/save_state.cpp index ff00005..564cf70 100644 --- a/firmware/Gravity/save_state.cpp +++ b/firmware/Gravity/save_state.cpp @@ -17,7 +17,7 @@ // Define the constants for the current firmware. const char StateManager::SKETCH_NAME[] = "ALT GRAVITY"; -const char StateManager::SEMANTIC_VERSION[] = "2.0.0"; // NOTE: This should match the version in the library.properties file. +const char StateManager::SEMANTIC_VERSION[] = "2.0.1"; // NOTE: This should match the version in the library.properties file. // Number of available save slots. const byte StateManager::MAX_SAVE_SLOTS = 10; @@ -33,54 +33,66 @@ const int StateManager::EEPROM_DATA_START_ADDR = sizeof(StateManager::Metadata); StateManager::StateManager() : _isDirty(false), _lastChangeTime(0) {} bool StateManager::initialize(AppState& app) { + noInterrupts(); + bool success = false; if (_isDataValid()) { // Load global settings. _loadMetadata(app); // Load app data from the transient slot. _loadState(app, TRANSIENT_SLOT); - return true; + success = true; } // EEPROM does not contain save data for this firmware & version. else { // Erase EEPROM and initialize state. Save default pattern to all save slots. factoryReset(app); - return false; } + interrupts(); + return success; } bool StateManager::loadData(AppState& app, byte slot_index) { // Check if slot_index is within max range + 1 for transient. if (slot_index >= MAX_SAVE_SLOTS + 1) return false; + noInterrupts(); + // Load the state data from the specified EEPROM slot and update the app state save slot. _loadState(app, slot_index); app.selected_save_slot = slot_index; - // Persist this change in the global metadata. - _saveMetadata(app); + // Persist this change in the global metadata on next update. + _isDirty = true; + interrupts(); return true; } // Save app state to user specified save slot. void StateManager::saveData(const AppState& app) { + noInterrupts(); // Check if slot_index is within max range + 1 for transient. if (app.selected_save_slot >= MAX_SAVE_SLOTS + 1) return; _saveState(app, app.selected_save_slot); _saveMetadata(app); _isDirty = false; + interrupts(); } // Save transient state if it has changed and enough time has passed since last save. void StateManager::update(const AppState& app) { if (_isDirty && (millis() - _lastChangeTime > SAVE_DELAY_MS)) { + noInterrupts(); _saveState(app, TRANSIENT_SLOT); _saveMetadata(app); _isDirty = false; + interrupts(); } } void StateManager::reset(AppState& app) { + noInterrupts(); + AppState default_app; app.tempo = default_app.tempo; app.selected_param = default_app.selected_param; @@ -98,6 +110,7 @@ void StateManager::reset(AppState& app) { _loadMetadata(app); _isDirty = false; + interrupts(); } void StateManager::markDirty() { @@ -134,7 +147,6 @@ void StateManager::_saveState(const AppState& app, byte slot_index) { // Check if slot_index is within max range + 1 for transient. if (app.selected_save_slot >= MAX_SAVE_SLOTS + 1) return; - noInterrupts(); static EepromData save_data; save_data.tempo = app.tempo; @@ -165,14 +177,12 @@ void StateManager::_saveState(const AppState& app, byte slot_index) { int address = EEPROM_DATA_START_ADDR + (slot_index * sizeof(EepromData)); EEPROM.put(address, save_data); - interrupts(); } void StateManager::_loadState(AppState& app, byte slot_index) { // Check if slot_index is within max range + 1 for transient. if (slot_index >= MAX_SAVE_SLOTS + 1) return; - noInterrupts(); static EepromData load_data; int address = EEPROM_DATA_START_ADDR + (slot_index * sizeof(EepromData)); EEPROM.get(address, load_data); @@ -200,11 +210,9 @@ void StateManager::_loadState(AppState& app, byte slot_index) { ch.setCv1Dest(static_cast(saved_ch_state.cv1_dest)); ch.setCv2Dest(static_cast(saved_ch_state.cv2_dest)); } - interrupts(); } void StateManager::_saveMetadata(const AppState& app) { - noInterrupts(); Metadata current_meta; strcpy(current_meta.sketch_name, SKETCH_NAME); strcpy(current_meta.version, SEMANTIC_VERSION); @@ -215,14 +223,12 @@ void StateManager::_saveMetadata(const AppState& app) { current_meta.rotate_display = app.rotate_display; EEPROM.put(METADATA_START_ADDR, current_meta); - interrupts(); } void StateManager::_loadMetadata(AppState& app) { - noInterrupts(); Metadata metadata; EEPROM.get(METADATA_START_ADDR, metadata); app.selected_save_slot = metadata.selected_save_slot; app.encoder_reversed = metadata.encoder_reversed; - interrupts(); + app.rotate_display = metadata.rotate_display; } \ No newline at end of file diff --git a/firmware/Gravity/save_state.h b/firmware/Gravity/save_state.h index 29226e7..220af7a 100644 --- a/firmware/Gravity/save_state.h +++ b/firmware/Gravity/save_state.h @@ -52,8 +52,8 @@ class StateManager { // This struct holds the data that identifies the firmware version. struct Metadata { - char sketch_name[12]; - char version[5]; + char sketch_name[16]; + char version[16]; // Additional global/hardware settings byte selected_save_slot; bool encoder_reversed; diff --git a/library.properties b/library.properties index bce41dd..afcb2f5 100644 --- a/library.properties +++ b/library.properties @@ -1,5 +1,5 @@ name=libGravity -version=2.0.0 +version=2.0.1 author=Adam Wonak maintainer=awonak sentence=Hardware abstraction library for Sitka Instruments Gravity eurorack module @@ -7,4 +7,4 @@ category=Other license=MIT url=https://github.com/awonak/libGravity architectures=avr -depends=uClock,RotaryEncoder,U8g2 \ No newline at end of file +depends=uClock,RotaryEncoder,U8g2,NeoHWSerial