From 1357634d9d6ca4e77b380ed3592ea3d49f3e9571 Mon Sep 17 00:00:00 2001 From: joeycastillo Date: Mon, 23 Sep 2024 00:02:31 -0400 Subject: [PATCH] fix flickering LED in preferences screen --- movement.c | 12 +- movement.h | 2 + watch-faces/settings/preferences_face.c | 202 ++++++++++++------------ 3 files changed, 109 insertions(+), 107 deletions(-) diff --git a/movement.c b/movement.c index 9cb77b05..df93d24e 100644 --- a/movement.c +++ b/movement.c @@ -212,7 +212,13 @@ void movement_illuminate_led(void) { } } -static void _movement_led_off(void) { +void movement_force_led_on(uint8_t red, uint8_t green, uint8_t blue) { + // this is hacky, we need a way for watch faces to set an arbitrary color and prevent Movement from turning it right back off. + watch_set_led_color_rgb(red, green, blue); + movement_state.light_ticks = 32767; +} + +void movement_force_led_off(void) { watch_set_led_off(); movement_state.light_ticks = -1; _movement_disable_fast_tick_if_possible(); @@ -230,7 +236,7 @@ bool movement_default_loop_handler(movement_event_t event, movement_settings_t * break; case EVENT_LIGHT_BUTTON_UP: if (movement_state.settings.bit.led_duration == 0) { - _movement_led_off(); + movement_force_led_off(); } break; case EVENT_MODE_LONG_PRESS: @@ -512,7 +518,7 @@ bool app_loop(void) { if (HAL_GPIO_BTN_LIGHT_read()) { movement_state.light_ticks = 1; } else { - _movement_led_off(); + movement_force_led_off(); } } diff --git a/movement.h b/movement.h index b7d0da6a..fd323ea6 100644 --- a/movement.h +++ b/movement.h @@ -290,6 +290,8 @@ void movement_move_to_next_face(void); bool movement_default_loop_handler(movement_event_t event, movement_settings_t *settings); void movement_illuminate_led(void); +void movement_force_led_on(uint8_t red, uint8_t green, uint8_t blue); +void movement_force_led_off(void); void movement_request_tick_frequency(uint8_t freq); diff --git a/watch-faces/settings/preferences_face.c b/watch-faces/settings/preferences_face.c index 45f6e285..77c7c823 100644 --- a/watch-faces/settings/preferences_face.c +++ b/watch-faces/settings/preferences_face.c @@ -75,10 +75,99 @@ bool preferences_face_loop(movement_event_t event, movement_settings_t *settings switch (event.event_type) { case EVENT_TICK: case EVENT_ACTIVATE: - // Do nothing; handled below. + watch_display_text(WATCH_POSITION_FULL, (char *)preferences_face_titles[state->current_page]); + watch_clear_all_indicators(); + watch_clear_colon(); + + // blink active setting on even-numbered quarter-seconds + if (event.subsecond % 2) { + char buf[8]; + switch (state->current_page) { + case PREFERENCES_PAGE_CLOCK_MODE: + if (settings->bit.clock_mode_24h) watch_display_text(WATCH_POSITION_BOTTOM, "24h"); + else watch_display_text(WATCH_POSITION_BOTTOM, "12h"); + break; + case PREFERENCES_PAGE_BUTTON_SOUND: + if (settings->bit.button_should_sound) { + watch_display_text(WATCH_POSITION_TOP_RIGHT, " Y"); + } else { + watch_display_text(WATCH_POSITION_TOP_RIGHT, " N"); + } + break; + case PREFERENCES_PAGE_TIMEOUT: + switch (settings->bit.to_interval) { + case 0: + watch_display_text(WATCH_POSITION_BOTTOM, "60 SeC"); + break; + case 1: + watch_display_text(WATCH_POSITION_BOTTOM, "2 n&in"); + break; + case 2: + watch_display_text(WATCH_POSITION_BOTTOM, "5 n&in"); + break; + case 3: + watch_display_text(WATCH_POSITION_BOTTOM, "30n&in"); + break; + } + break; + case PREFERENCES_PAGE_LOW_ENERGY: + switch (settings->bit.le_interval) { + case 0: + watch_display_text(WATCH_POSITION_BOTTOM, " Never"); + break; + case 1: + watch_display_text(WATCH_POSITION_BOTTOM, "10n&in"); + break; + case 2: + watch_display_text(WATCH_POSITION_BOTTOM, "1 hour"); + break; + case 3: + watch_display_text(WATCH_POSITION_BOTTOM, "2 hour"); + break; + case 4: + watch_display_text(WATCH_POSITION_BOTTOM, "6 hour"); + break; + case 5: + watch_display_text(WATCH_POSITION_BOTTOM, "12 hr"); + break; + case 6: + watch_display_text(WATCH_POSITION_BOTTOM, " 1 day"); + break; + case 7: + watch_display_text(WATCH_POSITION_BOTTOM, " 7 day"); + break; + } + break; + case PREFERENCES_PAGE_LED_DURATION: + if (settings->bit.led_duration == 0) { + watch_display_text(WATCH_POSITION_BOTTOM, "instnt"); + } else if (settings->bit.led_duration == 0b111) { + watch_display_text(WATCH_POSITION_BOTTOM, "no LEd"); + } else { + sprintf(buf, " %1d SeC", settings->bit.led_duration * 2 - 1); + watch_display_text(WATCH_POSITION_BOTTOM, buf); + } + break; + case PREFERENCES_PAGE_LED_RED: + sprintf(buf, "%2d", settings->bit.led_red_color); + watch_display_text(WATCH_POSITION_TOP_RIGHT, buf); + break; + case PREFERENCES_PAGE_LED_GREEN: + sprintf(buf, "%2d", settings->bit.led_green_color); + watch_display_text(WATCH_POSITION_TOP_RIGHT, buf); + break; + case PREFERENCES_PAGE_LED_BLUE: + sprintf(buf, "%2d", settings->bit.led_blue_color); + watch_display_text(WATCH_POSITION_TOP_RIGHT, buf); + break; + case PREFERENCES_PAGE_NUM_PREFERENCES: + // nothing to do here, just silencing the warning + break; + } + } break; case EVENT_MODE_BUTTON_UP: - watch_set_led_off(); + movement_force_led_off(); movement_move_to_next_face(); return false; case EVENT_LIGHT_BUTTON_DOWN: @@ -129,117 +218,22 @@ bool preferences_face_loop(movement_event_t event, movement_settings_t *settings return movement_default_loop_handler(event, settings); } - watch_display_text(WATCH_POSITION_FULL, (char *)preferences_face_titles[state->current_page]); - watch_clear_all_indicators(); - watch_clear_colon(); - - // blink active setting on even-numbered quarter-seconds - if (event.subsecond % 2) { - char buf[8]; - switch (state->current_page) { - case PREFERENCES_PAGE_CLOCK_MODE: - if (settings->bit.clock_mode_24h) watch_display_text(WATCH_POSITION_BOTTOM, "24h"); - else watch_display_text(WATCH_POSITION_BOTTOM, "12h"); - break; - case PREFERENCES_PAGE_BUTTON_SOUND: - if (settings->bit.button_should_sound) { - watch_display_text(WATCH_POSITION_TOP_RIGHT, " Y"); - } else { - watch_display_text(WATCH_POSITION_TOP_RIGHT, " N"); - } - break; - case PREFERENCES_PAGE_TIMEOUT: - switch (settings->bit.to_interval) { - case 0: - watch_display_text(WATCH_POSITION_BOTTOM, "60 SeC"); - break; - case 1: - watch_display_text(WATCH_POSITION_BOTTOM, "2 n&in"); - break; - case 2: - watch_display_text(WATCH_POSITION_BOTTOM, "5 n&in"); - break; - case 3: - watch_display_text(WATCH_POSITION_BOTTOM, "30n&in"); - break; - } - break; - case PREFERENCES_PAGE_LOW_ENERGY: - switch (settings->bit.le_interval) { - case 0: - watch_display_text(WATCH_POSITION_BOTTOM, " Never"); - break; - case 1: - watch_display_text(WATCH_POSITION_BOTTOM, "10n&in"); - break; - case 2: - watch_display_text(WATCH_POSITION_BOTTOM, "1 hour"); - break; - case 3: - watch_display_text(WATCH_POSITION_BOTTOM, "2 hour"); - break; - case 4: - watch_display_text(WATCH_POSITION_BOTTOM, "6 hour"); - break; - case 5: - watch_display_text(WATCH_POSITION_BOTTOM, "12 hr"); - break; - case 6: - watch_display_text(WATCH_POSITION_BOTTOM, " 1 day"); - break; - case 7: - watch_display_text(WATCH_POSITION_BOTTOM, " 7 day"); - break; - } - break; - case PREFERENCES_PAGE_LED_DURATION: - if (settings->bit.led_duration == 0) { - watch_display_text(WATCH_POSITION_BOTTOM, "instnt"); - } else if (settings->bit.led_duration == 0b111) { - watch_display_text(WATCH_POSITION_BOTTOM, "no LEd"); - } else { - sprintf(buf, " %1d SeC", settings->bit.led_duration * 2 - 1); - watch_display_text(WATCH_POSITION_BOTTOM, buf); - } - break; - case PREFERENCES_PAGE_LED_RED: - sprintf(buf, "%2d", settings->bit.led_red_color); - watch_display_text(WATCH_POSITION_TOP_RIGHT, buf); - break; - break; - case PREFERENCES_PAGE_LED_GREEN: - sprintf(buf, "%2d", settings->bit.led_green_color); - watch_display_text(WATCH_POSITION_TOP_RIGHT, buf); - break; - break; - case PREFERENCES_PAGE_LED_BLUE: - sprintf(buf, "%2d", settings->bit.led_blue_color); - watch_display_text(WATCH_POSITION_TOP_RIGHT, buf); - break; - case PREFERENCES_PAGE_NUM_PREFERENCES: - // nothing to do here, just silencing the warning - break; - } - } - - // on LED color select screns, preview the color. if (state->current_page == PREFERENCES_PAGE_LED_RED || state->current_page == PREFERENCES_PAGE_LED_GREEN || state->current_page == PREFERENCES_PAGE_LED_BLUE) { - watch_set_led_color_rgb(settings->bit.led_red_color ? (0xF | settings->bit.led_red_color << 4) : 0, - settings->bit.led_green_color ? (0xF | settings->bit.led_green_color << 4) : 0, - settings->bit.led_blue_color ? (0xF | settings->bit.led_blue_color << 4) : 0); - // return false so the watch stays awake (needed for the PWM driver to function). + movement_force_led_on(settings->bit.led_red_color | settings->bit.led_red_color << 4, + settings->bit.led_green_color | settings->bit.led_green_color << 4, + settings->bit.led_blue_color | settings->bit.led_blue_color << 4); return false; + } else { + movement_force_led_off(); + return true; } - - watch_set_led_off(); - return true; } void preferences_face_resign(movement_settings_t *settings, void *context) { (void) settings; (void) context; - watch_set_led_off(); + movement_force_led_off(); watch_store_backup_data(settings->reg, 0); }