]> git.earman.xyz Git - sensor-watch.git/commitdiff
second movement: persist settings to file system
authorJoey Castillo <joeycastillo@utexas.edu>
Sat, 15 Mar 2025 15:42:48 +0000 (11:42 -0400)
committerJoey Castillo <joeycastillo@utexas.edu>
Sat, 15 Mar 2025 15:44:00 +0000 (11:44 -0400)
movement.c
movement.h

index eba069c736adc0d6e1b0988405068bca733b8f97..27bdf21c6984f27e8768b8f82c7d47d1abdc45f5 100644 (file)
@@ -514,15 +514,19 @@ void movement_set_backlight_dwell(uint8_t value) {
 }
 
 void movement_store_settings(void) {
-    watch_store_backup_data(movement_state.settings.reg, 0);
+    movement_settings_t old_settings;
+    filesystem_read_file("settings.u32", (char *)&old_settings, sizeof(movement_settings_t));
+    if (movement_state.settings.reg != old_settings.reg) {
+        filesystem_write_file("settings.u32", (char *)&movement_state.settings, sizeof(movement_settings_t));
+    }
 }
 
 bool movement_alarm_enabled(void) {
-    return movement_state.settings.bit.alarm_enabled;
+    return movement_state.alarm_enabled;
 }
 
 void movement_set_alarm_enabled(bool value) {
-    movement_state.settings.bit.alarm_enabled = value;
+    movement_state.alarm_enabled = value;
 }
 
 void movement_enable_tap_detection_if_available(void) {
@@ -569,6 +573,8 @@ void movement_disable_tap_detection_if_available(void) {
 void app_init(void) {
     _watch_init();
 
+    filesystem_init();
+
     watch_date_time_t date_time = watch_rtc_get_date_time();
     if (date_time.reg == 0) {
         // at first boot, set year to 2024
@@ -597,41 +603,52 @@ void app_init(void) {
 
     memset(&movement_state, 0, sizeof(movement_state));
 
-    movement_state.settings.bit.clock_mode_24h = MOVEMENT_DEFAULT_24H_MODE;
-    movement_state.settings.bit.time_zone = UTZ_UTC;
-    movement_state.settings.bit.led_red_color = MOVEMENT_DEFAULT_RED_COLOR;
-    movement_state.settings.bit.led_green_color = MOVEMENT_DEFAULT_GREEN_COLOR;
-#if defined(WATCH_BLUE_TCC_CHANNEL) && !defined(WATCH_GREEN_TCC_CHANNEL)
-    // If there is a blue LED but no green LED, this is a blue Special Edition board.
-    // In the past, the "green color" showed up as the blue color on the blue board.
-    if (MOVEMENT_DEFAULT_RED_COLOR == 0 && MOVEMENT_DEFAULT_BLUE_COLOR == 0) {
-        // If the red color is 0 and the blue color is 0, we'll fall back to the old
-        // behavior, since otherwise there would be no default LED color.
-        movement_state.settings.bit.led_blue_color = MOVEMENT_DEFAULT_GREEN_COLOR;
+    bool settings_file_exists = filesystem_file_exists("settings.u32");
+    movement_settings_t maybe_settings;
+    if (settings_file_exists && maybe_settings.bit.version == 0) {
+        filesystem_read_file("settings.u32", (char *) &maybe_settings, sizeof(movement_settings_t));
+    }
+
+    if (settings_file_exists && maybe_settings.bit.version == 0) {
+        // If settings file exists and has a valid version, restore it!
+        movement_state.settings.reg = maybe_settings.reg;
     } else {
-        // however if either the red or blue color is nonzero, we'll assume the user
-        // has used the new defaults and knows what color they want. this could be red
-        // if blue is 0, or a custom color if both are nonzero.
+        // Otherwise set default values.
+        movement_state.settings.bit.version = 0;
+        movement_state.settings.bit.clock_mode_24h = MOVEMENT_DEFAULT_24H_MODE;
+        movement_state.settings.bit.time_zone = UTZ_UTC;
+        movement_state.settings.bit.led_red_color = MOVEMENT_DEFAULT_RED_COLOR;
+        movement_state.settings.bit.led_green_color = MOVEMENT_DEFAULT_GREEN_COLOR;
+    #if defined(WATCH_BLUE_TCC_CHANNEL) && !defined(WATCH_GREEN_TCC_CHANNEL)
+        // If there is a blue LED but no green LED, this is a blue Special Edition board.
+        // In the past, the "green color" showed up as the blue color on the blue board.
+        if (MOVEMENT_DEFAULT_RED_COLOR == 0 && MOVEMENT_DEFAULT_BLUE_COLOR == 0) {
+            // If the red color is 0 and the blue color is 0, we'll fall back to the old
+            // behavior, since otherwise there would be no default LED color.
+            movement_state.settings.bit.led_blue_color = MOVEMENT_DEFAULT_GREEN_COLOR;
+        } else {
+            // however if either the red or blue color is nonzero, we'll assume the user
+            // has used the new defaults and knows what color they want. this could be red
+            // if blue is 0, or a custom color if both are nonzero.
+            movement_state.settings.bit.led_blue_color = MOVEMENT_DEFAULT_BLUE_COLOR;
+        }
+    #else
         movement_state.settings.bit.led_blue_color = MOVEMENT_DEFAULT_BLUE_COLOR;
-    }
-#else
-    movement_state.settings.bit.led_blue_color = MOVEMENT_DEFAULT_BLUE_COLOR;
-#endif
-    movement_state.settings.bit.button_should_sound = MOVEMENT_DEFAULT_BUTTON_SOUND;
-    movement_state.settings.bit.to_interval = MOVEMENT_DEFAULT_TIMEOUT_INTERVAL;
-    movement_state.settings.bit.le_interval = MOVEMENT_DEFAULT_LOW_ENERGY_INTERVAL;
-    movement_state.settings.bit.led_duration = MOVEMENT_DEFAULT_LED_DURATION;
+    #endif
+        movement_state.settings.bit.button_should_sound = MOVEMENT_DEFAULT_BUTTON_SOUND;
+        movement_state.settings.bit.to_interval = MOVEMENT_DEFAULT_TIMEOUT_INTERVAL;
+        movement_state.settings.bit.le_interval = MOVEMENT_DEFAULT_LOW_ENERGY_INTERVAL;
+        movement_state.settings.bit.led_duration = MOVEMENT_DEFAULT_LED_DURATION;
 
+        movement_store_settings();
+    }
     movement_state.light_ticks = -1;
     movement_state.alarm_ticks = -1;
-    movement_state.next_available_backup_register = 4;
+    movement_state.next_available_backup_register = 2;
     _movement_reset_inactivity_countdown();
-
-    filesystem_init();
 }
 
 void app_wake_from_backup(void) {
-    /// TODO: #SecondMovement needs to restore settings from file system.
 }
 
 void app_setup(void) {
index 55a3b39170023b628a4d7fad74f530cd493c0f06..8031daebc18a7540786e058332a8ad21e8654a88 100644 (file)
@@ -66,6 +66,7 @@ typedef struct {
 // display, time zones, buzzer behavior, LED color and low energy mode timeouts.
 typedef union {
     struct {
+        uint8_t version : 2;                // A version number for the struct. 0-3; let's try not to update too often.
         bool button_should_sound : 1;       // if true, pressing a button emits a sound.
         uint8_t to_interval : 2;            // an inactivity interval for asking the active face to resign.
         uint8_t le_interval : 3;            // 0 to disable low energy mode, or an inactivity interval for going into low energy mode.
@@ -81,10 +82,9 @@ typedef union {
         // altimeter to display feet or meters as easily as it tells a thermometer to display degrees in F or C.
         bool clock_mode_24h : 1;            // indicates whether clock should use 12 or 24 hour mode.
         bool use_imperial_units : 1;        // indicates whether to use metric units (the default) or imperial.
-
-        /// TODO: for #SecondMovement: move alarm_enabled out of preferences
-        bool alarm_enabled : 1;             // indicates whether there is at least one alarm enabled.
-        uint8_t reserved : 2;               // room for more preferences if needed.
+        
+        // That's 31 bits, leaving room for one more toggle if needed.
+        uint8_t reserved : 1;
     } bit;
     uint32_t reg;
 } movement_settings_t;
@@ -260,7 +260,6 @@ typedef struct {
 } watch_face_t;
 
 typedef struct {
-    // properties stored in BACKUP register
     movement_settings_t settings;
 
     // transient properties
@@ -301,6 +300,9 @@ typedef struct {
 
     // backup register stuff
     uint8_t next_available_backup_register;
+
+    // temporary alarm enabled boolean, until we implement this in advisories
+    bool alarm_enabled;
 } movement_state_t;
 
 void movement_move_to_face(uint8_t watch_face_index);