Compare commits

...

2 Commits

Author SHA1 Message Date
joeycastillo
5fec31f654 request time once per tick 2022-12-23 18:52:40 -06:00
joeycastillo
a6333f7b8b create movement_get_date_time function 2022-12-23 18:45:18 -06:00
25 changed files with 52 additions and 44 deletions

View File

@ -78,6 +78,8 @@ const int32_t movement_le_inactivity_deadlines[8] = {INT_MAX, 3600, 7200, 21600,
const int16_t movement_timeout_inactivity_deadlines[4] = {60, 120, 300, 1800};
movement_event_t event;
watch_date_time _cached_date_time;
const int16_t movement_timezone_offsets[] = {
0, // 0 : 0:00:00 (UTC)
60, // 1 : 1:00:00 (Central European Time)
@ -167,7 +169,7 @@ static void _movement_handle_background_tasks(void) {
}
static void _movement_handle_scheduled_tasks(void) {
watch_date_time date_time = watch_rtc_get_date_time();
watch_date_time date_time = movement_get_date_time();
uint8_t num_active_tasks = 0;
for(uint8_t i = 0; i < MOVEMENT_NUM_FACES; i++) {
@ -193,6 +195,10 @@ static void _movement_handle_scheduled_tasks(void) {
}
}
watch_date_time movement_get_date_time(void) {
return _cached_date_time;
}
void movement_request_tick_frequency(uint8_t freq) {
// Movement uses the 128 Hz tick internally
if (freq == 128) return;
@ -242,7 +248,7 @@ void movement_cancel_background_task(void) {
}
void movement_schedule_background_task_for_face(uint8_t watch_face_index, watch_date_time date_time) {
watch_date_time now = watch_rtc_get_date_time();
watch_date_time now = movement_get_date_time();
if (date_time.reg > now.reg) {
movement_state.has_scheduled_background_task = true;
scheduled_tasks[watch_face_index].reg = date_time.reg;
@ -612,13 +618,13 @@ void cb_fast_tick(void) {
void cb_tick(void) {
event.event_type = EVENT_TICK;
watch_date_time date_time = watch_rtc_get_date_time();
if (date_time.unit.second != movement_state.last_second) {
_cached_date_time = watch_rtc_get_date_time();
if (_cached_date_time.unit.second != movement_state.last_second) {
// TODO: can we consolidate these two ticks?
if (movement_state.settings.bit.le_interval && movement_state.le_mode_ticks > 0) movement_state.le_mode_ticks--;
if (movement_state.timeout_ticks > 0) movement_state.timeout_ticks--;
movement_state.last_second = date_time.unit.second;
movement_state.last_second = _cached_date_time.unit.second;
movement_state.subsecond = 0;
} else {
movement_state.subsecond++;

View File

@ -287,6 +287,8 @@ void movement_move_to_face(uint8_t watch_face_index);
void movement_move_to_next_face(void);
void movement_illuminate_led(void);
watch_date_time movement_get_date_time(void);
void movement_request_tick_frequency(uint8_t freq);
// note: watch faces can only schedule a background task when in the foreground, since

View File

@ -36,7 +36,7 @@ bool beats_face_loop(movement_event_t event, movement_settings_t *settings, void
switch (event.event_type) {
case EVENT_ACTIVATE:
case EVENT_TICK:
date_time = watch_rtc_get_date_time();
date_time = movement_get_date_time();
centibeats = clock2beats(date_time.unit.hour, date_time.unit.minute, date_time.unit.second, event.subsecond, movement_timezone_offsets[settings->bit.time_zone]);
if (centibeats == state->last_centibeat_displayed) {
// we missed this update, try again next subsecond
@ -51,7 +51,7 @@ bool beats_face_loop(movement_event_t event, movement_settings_t *settings, void
break;
case EVENT_LOW_ENERGY_UPDATE:
if (!watch_tick_animation_is_running()) watch_start_tick_animation(432);
date_time = watch_rtc_get_date_time();
date_time = movement_get_date_time();
centibeats = clock2beats(date_time.unit.hour, date_time.unit.minute, date_time.unit.second, event.subsecond, movement_timezone_offsets[settings->bit.time_zone]);
sprintf(buf, "bt %4lu ", centibeats / 100);

View File

@ -69,7 +69,7 @@ static void _h_to_hms(mars_clock_hms_t *date_time, double h) {
static void _update(movement_settings_t *settings, mars_time_state_t *state) {
char buf[11];
watch_date_time date_time = watch_rtc_get_date_time();
watch_date_time date_time = movement_get_date_time();
uint32_t now = watch_utility_date_time_to_unix_time(date_time, movement_timezone_offsets[settings->bit.time_zone] * 60);
// TODO: I'm skipping over some steps here.
// https://www.giss.nasa.gov/tools/mars24/help/algorithm.html

View File

@ -76,7 +76,7 @@ bool simple_clock_face_loop(movement_event_t event, movement_settings_t *setting
case EVENT_ACTIVATE:
case EVENT_TICK:
case EVENT_LOW_ENERGY_UPDATE:
date_time = watch_rtc_get_date_time();
date_time = movement_get_date_time();
previous_date_time = state->previous_date_time;
state->previous_date_time = date_time.reg;
@ -169,7 +169,7 @@ bool simple_clock_face_wants_background_task(movement_settings_t *settings, void
simple_clock_state_t *state = (simple_clock_state_t *)context;
if (!state->signal_enabled) return false;
watch_date_time date_time = watch_rtc_get_date_time();
watch_date_time date_time = movement_get_date_time();
return date_time.unit.minute == 0;
}

View File

@ -76,7 +76,7 @@ bool weeknumber_clock_face_loop(movement_event_t event, movement_settings_t *set
case EVENT_ACTIVATE:
case EVENT_TICK:
case EVENT_LOW_ENERGY_UPDATE:
date_time = watch_rtc_get_date_time();
date_time = movement_get_date_time();
previous_date_time = state->previous_date_time;
state->previous_date_time = date_time.reg;
@ -165,7 +165,7 @@ bool weeknumber_clock_face_wants_background_task(movement_settings_t *settings,
weeknumber_clock_state_t *state = (weeknumber_clock_state_t *)context;
if (!state->signal_enabled) return false;
watch_date_time date_time = watch_rtc_get_date_time();
watch_date_time date_time = movement_get_date_time();
return date_time.unit.minute == 0;
}

View File

@ -66,7 +66,7 @@ static bool world_clock_face_do_display_mode(movement_event_t event, movement_se
// fall through
case EVENT_TICK:
case EVENT_LOW_ENERGY_UPDATE:
date_time = watch_rtc_get_date_time();
date_time = movement_get_date_time();
timestamp = watch_utility_date_time_to_unix_time(date_time, movement_timezone_offsets[settings->bit.time_zone] * 60);
date_time = watch_utility_date_time_from_unix_time(timestamp, movement_timezone_offsets[state->settings.bit.timezone_index] * 60);
previous_date_time = state->previous_date_time;

View File

@ -172,7 +172,7 @@ static void _alarm_update_alarm_enabled(movement_settings_t *settings, alarm_sta
break;
} else {
if (!now_init) {
now = watch_rtc_get_date_time();
now = movement_get_date_time();
now_init = true;
weekday_idx = _get_weekday_idx(now);
now_minutes_of_day = now.unit.hour * 60 + now.unit.minute;
@ -261,7 +261,7 @@ void alarm_face_resign(movement_settings_t *settings, void *context) {
bool alarm_face_wants_background_task(movement_settings_t *settings, void *context) {
(void) settings;
alarm_state_t *state = (alarm_state_t *)context;
watch_date_time now = watch_rtc_get_date_time();
watch_date_time now = movement_get_date_time();
// just a failsafe: never fire more than one alarm within a minute
if (state->alarm_handled_minute == now.unit.minute) return false;
state->alarm_handled_minute = now.unit.minute;

View File

@ -79,7 +79,7 @@ static void _astronomy_face_recalculate(movement_settings_t *settings, astronomy
}
#endif
watch_date_time date_time = watch_rtc_get_date_time();
watch_date_time date_time = movement_get_date_time();
uint32_t timestamp = watch_utility_date_time_to_unix_time(date_time, movement_timezone_offsets[settings->bit.time_zone] * 60);
date_time = watch_utility_date_time_from_unix_time(timestamp, 0);
double jd = astro_convert_date_to_julian_date(date_time.unit.year + WATCH_RTC_REFERENCE_YEAR, date_time.unit.month, date_time.unit.day, date_time.unit.hour, date_time.unit.minute, date_time.unit.second);

View File

@ -40,7 +40,7 @@ static inline int32_t get_tz_offset(movement_settings_t *settings) {
}
static void start(countdown_state_t *state, movement_settings_t *settings) {
watch_date_time now = watch_rtc_get_date_time();
watch_date_time now = movement_get_date_time();
state->mode = cd_running;
state->now_ts = watch_utility_date_time_to_unix_time(now, get_tz_offset(settings));
@ -130,7 +130,7 @@ void countdown_face_activate(movement_settings_t *settings, void *context) {
(void) settings;
countdown_state_t *state = (countdown_state_t *)context;
if(state->mode == cd_running) {
watch_date_time now = watch_rtc_get_date_time();
watch_date_time now = movement_get_date_time();
state->now_ts = watch_utility_date_time_to_unix_time(now, get_tz_offset(settings));
watch_set_indicator(WATCH_INDICATOR_BELL);
}

View File

@ -34,7 +34,7 @@ static uint32_t _day_one_face_juliandaynum(uint16_t year, uint16_t month, uint16
static void _day_one_face_update(day_one_state_t state) {
char buf[14];
watch_date_time date_time = watch_rtc_get_date_time();
watch_date_time date_time = movement_get_date_time();
uint32_t julian_date = _day_one_face_juliandaynum(date_time.unit.year + WATCH_RTC_REFERENCE_YEAR, date_time.unit.month, date_time.unit.day);
uint32_t julian_birthdate = _day_one_face_juliandaynum(state.birth_year, state.birth_month, state.birth_day);
sprintf(buf, "DA %6lu", julian_date - julian_birthdate);
@ -65,7 +65,7 @@ void day_one_face_activate(movement_settings_t *settings, void *context) {
day_one_state_t *state = (day_one_state_t *)context;
// stash the current year, useful in birthday setting mode.
watch_date_time date_time = watch_rtc_get_date_time();
watch_date_time date_time = movement_get_date_time();
state->current_year = date_time.unit.year + WATCH_RTC_REFERENCE_YEAR;
// reset the current page to 0, display days alive.
state->current_page = 0;
@ -117,7 +117,7 @@ bool day_one_face_loop(movement_event_t event, movement_settings_t *settings, vo
}
} else {
// otherwise, check if we have to update. the display only needs to change at midnight!
watch_date_time date_time = watch_rtc_get_date_time();
watch_date_time date_time = movement_get_date_time();
if (date_time.unit.hour == 0 && date_time.unit.minute == 0 && date_time.unit.second == 0) {
_day_one_face_update(*state);
}

View File

@ -58,7 +58,7 @@ void moon_phase_face_activate(movement_settings_t *settings, void *context) {
static void _update(movement_settings_t *settings, moon_phase_state_t *state, uint32_t offset) {
(void)state;
char buf[11];
watch_date_time date_time = watch_rtc_get_date_time();
watch_date_time date_time = movement_get_date_time();
uint32_t now = watch_utility_date_time_to_unix_time(date_time, movement_timezone_offsets[settings->bit.time_zone] * 60) + offset;
date_time = watch_utility_date_time_from_unix_time(now, movement_timezone_offsets[settings->bit.time_zone] * 60);
double currentfrac = fmod(now - FIRST_MOON, LUNAR_SECONDS) / LUNAR_SECONDS;
@ -142,13 +142,13 @@ bool moon_phase_face_loop(movement_event_t event, movement_settings_t *settings,
break;
case EVENT_TICK:
// only update once an hour
date_time = watch_rtc_get_date_time();
date_time = movement_get_date_time();
if ((date_time.unit.minute == 0) && (date_time.unit.second == 0)) _update(settings, state, state->offset);
break;
case EVENT_LOW_ENERGY_UPDATE:
// update at the top of the hour OR if we're entering sleep mode with an offset.
// also, in sleep mode, always show the current moon phase (offset = 0).
if (state->offset || (watch_rtc_get_date_time().unit.minute == 0)) _update(settings, state, 0);
if (state->offset || (movement_get_date_time().unit.minute == 0)) _update(settings, state, 0);
// and kill the offset so when the wearer wakes up, it matches what's on screen.
state->offset = 0;
// finally: clear out the last two digits and replace them with the sleep mode indicator

View File

@ -48,7 +48,7 @@ static const char orrery_celestial_body_names[NUM_AVAILABLE_BODIES][3] = {
};
static void _orrery_face_recalculate(movement_settings_t *settings, orrery_state_t *state) {
watch_date_time date_time = watch_rtc_get_date_time();
watch_date_time date_time = movement_get_date_time();
uint32_t timestamp = watch_utility_date_time_to_unix_time(date_time, movement_timezone_offsets[settings->bit.time_zone] * 60);
date_time = watch_utility_date_time_from_unix_time(timestamp, 0);
double jd = astro_convert_date_to_julian_date(date_time.unit.year + WATCH_RTC_REFERENCE_YEAR, date_time.unit.month, date_time.unit.day, date_time.unit.hour, date_time.unit.minute, date_time.unit.second);

View File

@ -46,7 +46,7 @@ void stopwatch_face_setup(movement_settings_t *settings, uint8_t watch_face_inde
static void _stopwatch_face_update_display(stopwatch_state_t *stopwatch_state, bool show_seconds) {
if (stopwatch_state->running) {
watch_date_time now = watch_rtc_get_date_time();
watch_date_time now = movement_get_date_time();
uint32_t now_timestamp = watch_utility_date_time_to_unix_time(now, 0);
uint32_t start_timestamp = watch_utility_date_time_to_unix_time(stopwatch_state->start_time, 0);
stopwatch_state->seconds_counted = now_timestamp - start_timestamp;
@ -127,11 +127,11 @@ bool stopwatch_face_loop(movement_event_t event, movement_settings_t *settings,
// we're running now, so we need to set the start_time.
if (stopwatch_state->start_time.reg == 0) {
// if starting from the reset state, easy: we start now.
stopwatch_state->start_time = watch_rtc_get_date_time();
stopwatch_state->start_time = movement_get_date_time();
} else {
// if resuming with time already on the clock, the original start time isn't valid anymore!
// so let's fetch the current time...
uint32_t timestamp = watch_utility_date_time_to_unix_time(watch_rtc_get_date_time(), 0);
uint32_t timestamp = watch_utility_date_time_to_unix_time(movement_get_date_time(), 0);
// ...subtract the seconds we've already counted...
timestamp -= stopwatch_state->seconds_counted;
// and resume from the "virtual" start time that's that many seconds ago.

View File

@ -53,7 +53,7 @@ static void _sunrise_sunset_face_update(movement_settings_t *settings, sunrise_s
return;
}
watch_date_time date_time = watch_rtc_get_date_time(); // the current local date / time
watch_date_time date_time = movement_get_date_time(); // the current local date / time
watch_date_time utc_now = watch_utility_date_time_convert_zone(date_time, movement_timezone_offsets[settings->bit.time_zone] * 60, 0); // the current date / time in UTC
watch_date_time scratch_time; // scratchpad, contains different values at different times
scratch_time.reg = utc_now.reg;
@ -329,7 +329,7 @@ bool sunrise_sunset_face_loop(movement_event_t event, movement_settings_t *setti
// if entering low energy mode, start tick animation
if (event.event_type == EVENT_LOW_ENERGY_UPDATE && !watch_tick_animation_is_running()) watch_start_tick_animation(1000);
// check if we need to update the display
watch_date_time date_time = watch_rtc_get_date_time();
watch_date_time date_time = movement_get_date_time();
if (date_time.reg >= state->rise_set_expires.reg) {
// and on the off chance that this happened before EVENT_TIMEOUT snapped us back to rise/set 0, go back now
state->rise_index = 0;

View File

@ -46,7 +46,7 @@ static uint8_t get_length(tomato_state_t *state) {
}
static void tomato_start(tomato_state_t *state, movement_settings_t *settings) {
watch_date_time now = watch_rtc_get_date_time();
watch_date_time now = movement_get_date_time();
int8_t length = (int8_t) get_length(state);
state->mode = tomato_run;
@ -122,7 +122,7 @@ void tomato_face_setup(movement_settings_t *settings, uint8_t watch_face_index,
void tomato_face_activate(movement_settings_t *settings, void *context) {
tomato_state_t *state = (tomato_state_t *)context;
if (state->mode == tomato_run) {
watch_date_time now = watch_rtc_get_date_time();
watch_date_time now = movement_get_date_time();
state->now_ts = watch_utility_date_time_to_unix_time(now, get_tz_offset(settings));
watch_set_indicator(WATCH_INDICATOR_BELL);
}

View File

@ -37,7 +37,7 @@ void totp_face_activate(movement_settings_t *settings, void *context) {
memset(context, 0, sizeof(totp_state_t));
totp_state_t *totp_state = (totp_state_t *)context;
TOTP(keys, key_sizes[0], timesteps[0]);
totp_state->timestamp = watch_utility_date_time_to_unix_time(watch_rtc_get_date_time(), movement_timezone_offsets[settings->bit.time_zone] * 60);
totp_state->timestamp = watch_utility_date_time_to_unix_time(movement_get_date_time(), movement_timezone_offsets[settings->bit.time_zone] * 60);
totp_state->current_code = getCodeFromTimestamp(totp_state->timestamp);
}

View File

@ -187,7 +187,7 @@ void totp_face_lfs_activate(movement_settings_t *settings, void *context) {
}
#endif
totp_state->timestamp = watch_utility_date_time_to_unix_time(watch_rtc_get_date_time(), movement_timezone_offsets[settings->bit.time_zone] * 60);
totp_state->timestamp = watch_utility_date_time_to_unix_time(movement_get_date_time(), movement_timezone_offsets[settings->bit.time_zone] * 60);
totp_face_set_record(totp_state, 0);
}

View File

@ -102,7 +102,7 @@ bool wake_face_wants_background_task(movement_settings_t *settings, void *contex
bool rc = false;
if ( state->mode ) {
watch_date_time now = watch_rtc_get_date_time();
watch_date_time now = movement_get_date_time();
rc = state->hour==now.unit.hour && state->minute==now.unit.minute;
// Were at the mercy of the wants_background_task handler
// In Safari, the emulator triggers at the end of the minute

View File

@ -73,7 +73,7 @@ static void _lis2dw_logging_face_update_display(movement_settings_t *settings, l
}
}
} else {
date_time = watch_rtc_get_date_time();
date_time = movement_get_date_time();
watch_clear_colon();
watch_clear_indicator(WATCH_INDICATOR_PM);
watch_clear_indicator(WATCH_INDICATOR_24H);
@ -92,7 +92,7 @@ static void _lis2dw_logging_face_update_display(movement_settings_t *settings, l
}
static void _lis2dw_logging_face_log_data(lis2dw_logger_state_t *logger_state) {
watch_date_time date_time = watch_rtc_get_date_time();
watch_date_time date_time = movement_get_date_time();
// we get this call 15 minutes late; i.e. at 6:15 we're logging events for 6:00.
// so: if we're at the top of the hour, roll the hour back too (7:00 task logs data for 6:45)
if (date_time.unit.minute == 0) date_time.unit.hour = (date_time.unit.hour + 23) % 24;
@ -202,7 +202,7 @@ void lis2dw_logging_face_resign(movement_settings_t *settings, void *context) {
bool lis2dw_logging_face_wants_background_task(movement_settings_t *settings, void *context) {
(void) settings;
lis2dw_logger_state_t *logger_state = (lis2dw_logger_state_t *)context;
watch_date_time date_time = watch_rtc_get_date_time();
watch_date_time date_time = movement_get_date_time();
// this is kind of an abuse of the API, but, let's use the 1 minute tick to shift all our data over.
logger_state->interrupts[2] = logger_state->interrupts[1];

View File

@ -65,7 +65,7 @@ bool voltage_face_loop(movement_event_t event, movement_settings_t *settings, vo
_voltage_face_update_display();
break;
case EVENT_TICK:
date_time = watch_rtc_get_date_time();
date_time = movement_get_date_time();
if (date_time.unit.second % 5 == 4) {
watch_set_indicator(WATCH_INDICATOR_SIGNAL);
} else if (date_time.unit.second % 5 == 0) {

View File

@ -440,7 +440,7 @@ static void start_reading(accelerometer_data_acquisition_state_t *state, movemen
lis2dw_enable_fifo();
accelerometer_data_acquisition_record_t record;
watch_date_time date_time = watch_rtc_get_date_time();
watch_date_time date_time = movement_get_date_time();
state->starting_timestamp = watch_utility_date_time_to_unix_time(date_time, movement_timezone_offsets[settings->bit.time_zone] * 60);
record.header.info.record_type = ACCELEROMETER_DATA_ACQUISITION_HEADER;
record.header.info.range = ACCELEROMETER_RANGE;

View File

@ -30,7 +30,7 @@
static void _thermistor_logging_face_log_data(thermistor_logger_state_t *logger_state) {
thermistor_driver_enable();
watch_date_time date_time = watch_rtc_get_date_time();
watch_date_time date_time = movement_get_date_time();
size_t pos = logger_state->data_points % THERMISTOR_LOGGING_NUM_DATA_POINTS;
logger_state->data[pos].timestamp.reg = date_time.reg;
@ -137,5 +137,5 @@ bool thermistor_logging_face_wants_background_task(movement_settings_t *settings
(void) context;
// this will get called at the top of each minute, so all we check is if we're at the top of the hour as well.
// if we are, we ask for a background task.
return watch_rtc_get_date_time().unit.minute == 0;
return movement_get_date_time().unit.minute == 0;
}

View File

@ -55,7 +55,7 @@ void thermistor_readout_face_activate(movement_settings_t *settings, void *conte
bool thermistor_readout_face_loop(movement_event_t event, movement_settings_t *settings, void *context) {
(void) context;
watch_date_time date_time = watch_rtc_get_date_time();
watch_date_time date_time = movement_get_date_time();
switch (event.event_type) {
case EVENT_MODE_BUTTON_UP:
movement_move_to_next_face();

View File

@ -44,7 +44,7 @@ void set_time_face_activate(movement_settings_t *settings, void *context) {
bool set_time_face_loop(movement_event_t event, movement_settings_t *settings, void *context) {
uint8_t current_page = *((uint8_t *)context);
const uint8_t days_in_month[12] = {31, 28, 31, 30, 31, 30, 30, 31, 30, 31, 30, 31};
watch_date_time date_time = watch_rtc_get_date_time();
watch_date_time date_time = movement_get_date_time();
switch (event.event_type) {
case EVENT_MODE_BUTTON_UP: