summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--movement/alt_fw/backer.h (renamed from movement/alt_fw/standard.h)0
-rw-r--r--movement/alt_fw/deep_space_now.h4
-rw-r--r--movement/alt_fw/the_stargazer.h7
-rwxr-xr-xmovement/make/make_alternate_fw.sh4
-rw-r--r--movement/movement.c15
-rw-r--r--movement/movement_config.h2
-rw-r--r--movement/watch_faces/complication/stopwatch_face.c48
-rw-r--r--movement/watch_faces/complication/sunrise_sunset_face.c17
-rw-r--r--movement/watch_faces/settings/set_time_face.c4
-rw-r--r--utils/movement_bulk_installer/standard-green.uf2bin172032 -> 206336 bytes
10 files changed, 79 insertions, 22 deletions
diff --git a/movement/alt_fw/standard.h b/movement/alt_fw/backer.h
index 3abcf457..3abcf457 100644
--- a/movement/alt_fw/standard.h
+++ b/movement/alt_fw/backer.h
diff --git a/movement/alt_fw/deep_space_now.h b/movement/alt_fw/deep_space_now.h
index f07fe2cb..6cb34237 100644
--- a/movement/alt_fw/deep_space_now.h
+++ b/movement/alt_fw/deep_space_now.h
@@ -32,15 +32,15 @@
#define MOVEMENT_CUSTOM_BOOT_COMMANDS() { \
/* Standard Time */\
- /*\
watch_store_backup_data(0x1e0c0c, 4);\
watch_store_backup_data(0x010115, 5);\
watch_store_backup_data(0x130105, 6);\
- */\
/* Daylight Saving Time */\
+ /*\
watch_store_backup_data(0x1f0c0c, 4);\
watch_store_backup_data(0x020115, 5);\
watch_store_backup_data(0x110105, 6);\
+ */\
watch_store_backup_data(0x0597b9, 2);\
}
diff --git a/movement/alt_fw/the_stargazer.h b/movement/alt_fw/the_stargazer.h
index 50a89aad..a13dc3ac 100644
--- a/movement/alt_fw/the_stargazer.h
+++ b/movement/alt_fw/the_stargazer.h
@@ -27,11 +27,8 @@
#include "movement_faces.h"
-#define MOVEMENT_CUSTOM_BOOT_COMMANDS() { \
- movement_state.settings.bit.led_green_color = 0x0;\
- movement_state.settings.bit.led_red_color = 0xF;\
- watch_store_backup_data(movement_state.settings.reg, 0);\
-}
+#define MOVEMENT_DEFAULT_RED_COLOR 0xF
+#define MOVEMENT_DEFAULT_GREEN_COLOR 0x0
const watch_face_t watch_faces[] = {
simple_clock_face,
diff --git a/movement/make/make_alternate_fw.sh b/movement/make/make_alternate_fw.sh
index 739c8557..d1ce7673 100755
--- a/movement/make/make_alternate_fw.sh
+++ b/movement/make/make_alternate_fw.sh
@@ -3,7 +3,7 @@
fw_dir="firmware/download"
sim_dir="firmware/simulate"
colors=("green" "blue")
-variants=("standard" "alt_time" "deep_space_now" "focus" "the_athlete" "the_backpacker" "the_stargazer")
+variants=("standard" "backer" "alt_time" "deep_space_now" "focus" "the_athlete" "the_backpacker" "the_stargazer")
if [ -d "$fw_dir" ] ; then
rm -r "$fw_dir"
@@ -25,7 +25,7 @@ do
make LED=$COLOR FIRMWARE=$VARIANT
mv "build/watch.uf2" "$fw_dir/$variant-$color.uf2"
done
- make clean
+ rm -rf ./build-sim
emmake make FIRMWARE=$VARIANT
mkdir "$sim_dir/$variant/"
mv "build-sim/watch.wasm" "$sim_dir/$variant/"
diff --git a/movement/movement.c b/movement/movement.c
index 0ded11e3..3997b4a4 100644
--- a/movement/movement.c
+++ b/movement/movement.c
@@ -37,7 +37,9 @@
#ifndef MOVEMENT_FIRMWARE
#include "movement_config.h"
#elif MOVEMENT_FIRMWARE == MOVEMENT_FIRMWARE_STANDARD
-#include "alt_fw/standard.h"
+#include "movement_config.h"
+#elif MOVEMENT_FIRMWARE == MOVEMENT_FIRMWARE_BACKER
+#include "alt_fw/backer.h"
#elif MOVEMENT_FIRMWARE == MOVEMENT_FIRMWARE_ALT_TIME
#include "alt_fw/alt_time.h"
#elif MOVEMENT_FIRMWARE == MOVEMENT_FIRMWARE_FOCUS
@@ -57,6 +59,14 @@
#define MOVEMENT_SECONDARY_FACE_INDEX 0
#endif
+// Set default LED colors if not set
+#ifndef MOVEMENT_DEFAULT_RED_COLOR
+#define MOVEMENT_DEFAULT_RED_COLOR 0x0
+#endif
+#ifndef MOVEMENT_DEFAULT_GREEN_COLOR
+#define MOVEMENT_DEFAULT_GREEN_COLOR 0xF
+#endif
+
#if __EMSCRIPTEN__
#include <emscripten.h>
#endif
@@ -284,7 +294,8 @@ uint8_t movement_claim_backup_register(void) {
void app_init(void) {
memset(&movement_state, 0, sizeof(movement_state));
- movement_state.settings.bit.led_green_color = 0xF;
+ movement_state.settings.bit.led_red_color = MOVEMENT_DEFAULT_RED_COLOR;
+ movement_state.settings.bit.led_green_color = MOVEMENT_DEFAULT_GREEN_COLOR;
movement_state.settings.bit.button_should_sound = true;
movement_state.settings.bit.le_interval = 1;
movement_state.settings.bit.led_duration = 1;
diff --git a/movement/movement_config.h b/movement/movement_config.h
index 19a501ea..9e446d4d 100644
--- a/movement/movement_config.h
+++ b/movement/movement_config.h
@@ -32,7 +32,7 @@ const watch_face_t watch_faces[] = {
world_clock_face,
sunrise_sunset_face,
moon_phase_face,
- thermistor_readout_face,
+ stopwatch_face,
preferences_face,
set_time_face,
};
diff --git a/movement/watch_faces/complication/stopwatch_face.c b/movement/watch_faces/complication/stopwatch_face.c
index e85bbd65..2a69e9d5 100644
--- a/movement/watch_faces/complication/stopwatch_face.c
+++ b/movement/watch_faces/complication/stopwatch_face.c
@@ -29,6 +29,12 @@
#include "watch.h"
#include "watch_utility.h"
+// distant future for background task: January 1, 2083
+// see stopwatch_face_activate for details
+static const watch_date_time distant_future = {
+ .unit = {0, 0, 0, 1, 1, 63}
+};
+
void stopwatch_face_setup(movement_settings_t *settings, uint8_t watch_face_index, void ** context_ptr) {
(void) settings;
(void) watch_face_index;
@@ -49,6 +55,7 @@ static void _stopwatch_face_update_display(stopwatch_state_t *stopwatch_state, b
if (stopwatch_state->seconds_counted >= 3456000) {
// display maxes out just shy of 40 days, thanks to the limit on the day digits (0-39)
stopwatch_state->running = false;
+ movement_cancel_background_task();
watch_display_string("st39235959", 0);
return;
}
@@ -72,12 +79,21 @@ static void _stopwatch_face_update_display(stopwatch_state_t *stopwatch_state, b
void stopwatch_face_activate(movement_settings_t *settings, void *context) {
(void) settings;
- (void) context;
if (watch_tick_animation_is_running()) watch_stop_tick_animation();
+
+ stopwatch_state_t *stopwatch_state = (stopwatch_state_t *)context;
+ if (stopwatch_state->running) {
+ // because the low power update happens on the minute mark, and the wearer could start
+ // the stopwatch anytime, the low power update could fire up to 59 seconds later than
+ // we need it to, causing the stopwatch to display stale data.
+ // So let's schedule a background task that will never fire. This will keep the watch
+ // from entering low energy mode while the stopwatch is on screen. This background task
+ // will remain scheduled until the stopwatch stops OR this watch face resigns.
+ movement_schedule_background_task(distant_future);
+ }
}
bool stopwatch_face_loop(movement_event_t event, movement_settings_t *settings, void *context) {
- (void) settings;
stopwatch_state_t *stopwatch_state = (stopwatch_state_t *)context;
switch (event.event_type) {
@@ -103,6 +119,9 @@ bool stopwatch_face_loop(movement_event_t event, movement_settings_t *settings,
}
break;
case EVENT_ALARM_BUTTON_DOWN:
+ if (settings->bit.button_should_sound) {
+ watch_buzzer_play_note(BUZZER_NOTE_C8, 50);
+ }
stopwatch_state->running = !stopwatch_state->running;
if (stopwatch_state->running) {
// we're running now, so we need to set the start_time.
@@ -118,15 +137,28 @@ bool stopwatch_face_loop(movement_event_t event, movement_settings_t *settings,
// and resume from the "virtual" start time that's that many seconds ago.
stopwatch_state->start_time = watch_utility_date_time_from_unix_time(timestamp, 0);
}
+ // schedule our keepalive task when running...
+ movement_schedule_background_task(distant_future);
+ } else {
+ // and cancel it when stopped.
+ movement_cancel_background_task();
}
break;
case EVENT_TIMEOUT:
// explicitly ignore the timeout event so we stay on screen
break;
case EVENT_LOW_ENERGY_UPDATE:
- if (!watch_tick_animation_is_running()) watch_start_tick_animation(500);
- _stopwatch_face_update_display(stopwatch_state, false);
- watch_set_indicator(WATCH_INDICATOR_BELL);
+ if (!watch_tick_animation_is_running()) watch_start_tick_animation(1000);
+ if (!stopwatch_state->running) {
+ // since the tick animation is running, displaying the stopped time could be misleading,
+ // as it could imply that the stopwatch is running. instead, show a blank display to
+ // indicate that we are in sleep mode.
+ watch_display_string("st ---- ", 0);
+ } else {
+ // this OTOH shouldn't happen anymore; if we're running, we shouldn't enter low energy mode
+ _stopwatch_face_update_display(stopwatch_state, false);
+ watch_set_indicator(WATCH_INDICATOR_BELL);
+ }
break;
default:
break;
@@ -138,4 +170,8 @@ bool stopwatch_face_loop(movement_event_t event, movement_settings_t *settings,
void stopwatch_face_resign(movement_settings_t *settings, void *context) {
(void) settings;
(void) context;
-} \ No newline at end of file
+
+ // regardless of whether we're running or stopped, cancel the task
+ // that was keeping us awake while on screen.
+ movement_cancel_background_task();
+}
diff --git a/movement/watch_faces/complication/sunrise_sunset_face.c b/movement/watch_faces/complication/sunrise_sunset_face.c
index 8dea812e..7807de83 100644
--- a/movement/watch_faces/complication/sunrise_sunset_face.c
+++ b/movement/watch_faces/complication/sunrise_sunset_face.c
@@ -96,6 +96,11 @@ static void _sunrise_sunset_face_update(movement_settings_t *settings, sunrise_s
if (seconds < 30) scratch_time.unit.minute = floor(minutes);
else scratch_time.unit.minute = ceil(minutes);
+ if (scratch_time.unit.minute == 60) {
+ scratch_time.unit.minute = 0;
+ scratch_time.unit.hour = (scratch_time.unit.hour + 1) % 24;
+ }
+
if (date_time.reg < scratch_time.reg) _sunrise_sunset_set_expiration(state, scratch_time);
if (date_time.reg < scratch_time.reg || show_next_match) {
@@ -118,6 +123,11 @@ static void _sunrise_sunset_face_update(movement_settings_t *settings, sunrise_s
if (seconds < 30) scratch_time.unit.minute = floor(minutes);
else scratch_time.unit.minute = ceil(minutes);
+ if (scratch_time.unit.minute == 60) {
+ scratch_time.unit.minute = 0;
+ scratch_time.unit.hour = (scratch_time.unit.hour + 1) % 24;
+ }
+
if (date_time.reg < scratch_time.reg) _sunrise_sunset_set_expiration(state, scratch_time);
if (date_time.reg < scratch_time.reg || show_next_match) {
@@ -371,8 +381,11 @@ bool sunrise_sunset_face_loop(movement_event_t event, movement_settings_t *setti
}
break;
case EVENT_TIMEOUT:
- if (state->page || state->rise_index) {
- // on timeout, exit settings mode and return to the next sunrise or sunset
+ if (watch_get_backup_data(1) == 0) {
+ // if no location set, return home
+ movement_move_to_face(0);
+ } else if (state->page || state->rise_index) {
+ // otherwise on timeout, exit settings mode and return to the next sunrise or sunset
state->page = 0;
state->rise_index = 0;
movement_request_tick_frequency(1);
diff --git a/movement/watch_faces/settings/set_time_face.c b/movement/watch_faces/settings/set_time_face.c
index af5421f1..1605f119 100644
--- a/movement/watch_faces/settings/set_time_face.c
+++ b/movement/watch_faces/settings/set_time_face.c
@@ -66,8 +66,8 @@ bool set_time_face_loop(movement_event_t event, movement_settings_t *settings, v
date_time.unit.second = 0;
break;
case 3: // year
- // only allow 2021-2030. fix this sometime next decade
- date_time.unit.year = ((date_time.unit.year % 10) + 1);
+ // only allow 2021-2050. fix this if we make it that far.
+ date_time.unit.year = ((date_time.unit.year % 30) + 1);
break;
case 4: // month
date_time.unit.month = (date_time.unit.month % 12) + 1;
diff --git a/utils/movement_bulk_installer/standard-green.uf2 b/utils/movement_bulk_installer/standard-green.uf2
index e7f80e91..a0716db0 100644
--- a/utils/movement_bulk_installer/standard-green.uf2
+++ b/utils/movement_bulk_installer/standard-green.uf2
Binary files differ