movement_state_t movement_state;
void * watch_face_contexts[MOVEMENT_NUM_FACES];
-watch_date_time scheduled_tasks[MOVEMENT_NUM_FACES];
+watch_date_time_t scheduled_tasks[MOVEMENT_NUM_FACES];
const int32_t movement_le_inactivity_deadlines[8] = {INT_MAX, 600, 3600, 7200, 21600, 43200, 86400, 604800};
const int16_t movement_timeout_inactivity_deadlines[4] = {60, 120, 300, 1800};
movement_event_t event;
cdc_task();
}
-static udatetime_t _movement_convert_date_time_to_udate(watch_date_time date_time) {
+static udatetime_t _movement_convert_date_time_to_udate(watch_date_time_t date_time) {
return (udatetime_t) {
.date.dayofmonth = date_time.unit.day,
.date.dayofweek = dayofweek(UYEAR_FROM_YEAR(date_time.unit.year + WATCH_RTC_REFERENCE_YEAR), date_time.unit.month, date_time.unit.day),
uzone_t local_zone;
udatetime_t udate_time;
bool dst_changed = false;
- watch_date_time system_date_time = watch_rtc_get_date_time();
+ watch_date_time_t system_date_time = watch_rtc_get_date_time();
printf("current zone: %d\n", movement_state.settings.bit.time_zone);
for (uint8_t i = 0; i < NUM_ZONE_NAMES; i++) {
unpack_zone(&zone_defns[i], "", &local_zone);
- watch_date_time date_time = watch_utility_date_time_convert_zone(system_date_time, 0, local_zone.offset.hours * 3600 + local_zone.offset.minutes * 60);
+ watch_date_time_t date_time = watch_utility_date_time_convert_zone(system_date_time, 0, local_zone.offset.hours * 3600 + local_zone.offset.minutes * 60);
if (!!local_zone.rules_len) {
// if local zone has DST rules, we need to see if DST applies.
}
static void _movement_handle_top_of_minute(void) {
- watch_date_time date_time = watch_rtc_get_date_time();
+ watch_date_time_t date_time = watch_rtc_get_date_time();
// update the DST offset cache every 15 minutes, since someplace in the world could change.
if (date_time.unit.minute % 15 == 0) {
}
static void _movement_handle_scheduled_tasks(void) {
- watch_date_time date_time = watch_rtc_get_date_time();
+ watch_date_time_t date_time = watch_rtc_get_date_time();
uint8_t num_active_tasks = 0;
for(uint8_t i = 0; i < MOVEMENT_NUM_FACES; i++) {
movement_move_to_face((movement_state.current_face_idx + 1) % face_max);
}
-void movement_schedule_background_task(watch_date_time date_time) {
+void movement_schedule_background_task(watch_date_time_t date_time) {
movement_schedule_background_task_for_face(movement_state.current_face_idx, date_time);
}
movement_cancel_background_task_for_face(movement_state.current_face_idx);
}
-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();
+void movement_schedule_background_task_for_face(uint8_t watch_face_index, watch_date_time_t date_time) {
+ watch_date_time_t now = watch_rtc_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;
movement_state.settings.bit.time_zone = value;
}
-watch_date_time movement_get_utc_date_time(void) {
+watch_date_time_t movement_get_utc_date_time(void) {
return watch_rtc_get_date_time();
}
-watch_date_time movement_get_date_time_in_zone(uint8_t zone_index) {
+watch_date_time_t movement_get_date_time_in_zone(uint8_t zone_index) {
int32_t offset = movement_get_current_timezone_offset_for_zone(zone_index);
return watch_utility_date_time_convert_zone(watch_rtc_get_date_time(), 0, offset);
}
-watch_date_time movement_get_local_date_time(void) {
- watch_date_time date_time = watch_rtc_get_date_time();
+watch_date_time_t movement_get_local_date_time(void) {
+ watch_date_time_t date_time = watch_rtc_get_date_time();
return watch_utility_date_time_convert_zone(date_time, 0, movement_get_current_timezone_offset());
}
-void movement_set_local_date_time(watch_date_time date_time) {
+void movement_set_local_date_time(watch_date_time_t date_time) {
int32_t current_offset = movement_get_current_timezone_offset();
- watch_date_time utc_date_time = watch_utility_date_time_convert_zone(date_time, current_offset, 0);
+ watch_date_time_t utc_date_time = watch_utility_date_time_convert_zone(date_time, current_offset, 0);
watch_rtc_set_date_time(utc_date_time);
// this may seem wasteful, but if the user's local time is in a zone that observes DST,
void app_init(void) {
_watch_init();
- watch_date_time date_time = watch_rtc_get_date_time();
+ watch_date_time_t date_time = watch_rtc_get_date_time();
if (date_time.reg == 0) {
// at first boot, set year to 2024
date_time.unit.year = 2024 - WATCH_RTC_REFERENCE_YEAR;
_movement_update_dst_offset_cache();
// set up the 1 minute alarm (for background tasks and low power updates)
- watch_date_time alarm_time;
+ watch_date_time_t alarm_time;
alarm_time.reg = 0;
alarm_time.unit.second = 59; // after a match, the alarm fires at the next rising edge of CLK_RTC_CNT, so 59 seconds lets us update at :00
watch_rtc_register_alarm_callback(cb_alarm_fired, alarm_time, ALARM_MATCH_SS);
void cb_tick(void) {
event.event_type = EVENT_TICK;
- watch_date_time date_time = watch_rtc_get_date_time();
+ watch_date_time_t date_time = watch_rtc_get_date_time();
if (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--;
// note: watch faces can only schedule a background task when in the foreground, since
// movement will associate the scheduled task with the currently active face.
-void movement_schedule_background_task(watch_date_time date_time);
+void movement_schedule_background_task(watch_date_time_t date_time);
// note: watch faces can only cancel their background task when in the foreground, since
// movement will associate the scheduled task with the currently active face.
void movement_cancel_background_task(void);
// these functions should work around the limitation of the above functions, which will be deprecated.
-void movement_schedule_background_task_for_face(uint8_t watch_face_index, watch_date_time date_time);
+void movement_schedule_background_task_for_face(uint8_t watch_face_index, watch_date_time_t date_time);
void movement_cancel_background_task_for_face(uint8_t watch_face_index);
void movement_request_sleep(void);
int32_t movement_get_timezone_index(void);
void movement_set_timezone_index(uint8_t value);
-watch_date_time movement_get_utc_date_time(void);
-watch_date_time movement_get_local_date_time(void);
-watch_date_time movement_get_date_time_in_zone(uint8_t zone_index);
+watch_date_time_t movement_get_utc_date_time(void);
+watch_date_time_t movement_get_local_date_time(void);
+watch_date_time_t movement_get_date_time_in_zone(uint8_t zone_index);
-void movement_set_local_date_time(watch_date_time date_time);
+void movement_set_local_date_time(watch_date_time_t date_time);
bool movement_button_should_sound(void);
void movement_set_button_should_sound(bool value);
close_enough_clock_state_t *state = (close_enough_clock_state_t *)context;
char buf[11];
- watch_date_time date_time;
+ watch_date_time_t date_time;
bool show_next_hour = false;
int prev_five_minute_period;
int prev_min_checked;
return fmod(fmod(x, y) + y, y);
}
-static void recalculate(watch_date_time utc_now, day_night_percentage_state_t *state) {
+static void recalculate(watch_date_time_t utc_now, day_night_percentage_state_t *state) {
movement_location_t movement_location = (movement_location_t) watch_get_backup_data(1);
if (movement_location.reg == 0) {
if (*context_ptr == NULL) {
*context_ptr = malloc(sizeof(day_night_percentage_state_t));
day_night_percentage_state_t *state = (day_night_percentage_state_t *)*context_ptr;
- watch_date_time utc_now = watch_utility_date_time_convert_zone(watch_rtc_get_date_time(), movement_get_current_timezone_offset(), 0);
+ watch_date_time_t utc_now = watch_utility_date_time_convert_zone(watch_rtc_get_date_time(), movement_get_current_timezone_offset(), 0);
recalculate(utc_now, state);
}
}
day_night_percentage_state_t *state = (day_night_percentage_state_t *)context;
char buf[12];
- watch_date_time date_time = watch_rtc_get_date_time();
- watch_date_time utc_now = watch_utility_date_time_convert_zone(date_time, movement_get_current_timezone_offset(), 0);
+ watch_date_time_t date_time = watch_rtc_get_date_time();
+ watch_date_time_t utc_now = watch_utility_date_time_convert_zone(date_time, movement_get_current_timezone_offset(), 0);
switch (event.event_type) {
case EVENT_ACTIVATE:
char buf[16];
uint8_t centihours, decimal_seconds;
- watch_date_time date_time;
+ watch_date_time_t date_time;
switch (event.event_type) {
case EVENT_ACTIVATE:
french_revolutionary_state_t *state = (french_revolutionary_state_t *)context;
char buf[11];
- watch_date_time date_time;
+ watch_date_time_t date_time;
fr_decimal_time decimal_time;
switch (event.event_type) {
}
// Calculate decimal time from normal (24hr) time
-fr_decimal_time get_decimal_time(watch_date_time *date_time) {
+fr_decimal_time get_decimal_time(watch_date_time_t *date_time) {
uint32_t current_24hr_secs, current_decimal_seconds;
fr_decimal_time decimal_time;
// Current 24-hr time in seconds (There are 86400 of these in a day.)
// - Decimal-time with normal time in the top (minutes first, then hours, due to display limitations)
// TODO: There is some power-saving stuff that simple clock does here around not redrawing characters that haven't changed, but we're not doing that here.
// I'll try to add that optimization could be added in a future commit.
-void set_display_buffer(char *buf, french_revolutionary_state_t *state, fr_decimal_time *decimal_time, watch_date_time *date_time) {
+void set_display_buffer(char *buf, french_revolutionary_state_t *state, fr_decimal_time *decimal_time, watch_date_time_t *date_time) {
switch (state->display_type) {
// Decimal time only
case 0:
bool french_revolutionary_face_loop(movement_event_t event, void *context);
void french_revolutionary_face_resign(void *context);
char fix_character_one(char digit);
-fr_decimal_time get_decimal_time(watch_date_time *date_time);
-void set_display_buffer(char *buf, french_revolutionary_state_t *state, fr_decimal_time *decimal_time, watch_date_time *date_time);
+fr_decimal_time get_decimal_time(watch_date_time_t *date_time);
+void set_display_buffer(char *buf, french_revolutionary_state_t *state, fr_decimal_time *decimal_time, watch_date_time_t *date_time);
#define french_revolutionary_face ((const watch_face_t){ \
static void _update(mars_time_state_t *state) {
char buf[11];
- watch_date_time date_time = watch_rtc_get_date_time();
+ watch_date_time_t date_time = watch_rtc_get_date_time();
uint32_t now = watch_utility_date_time_to_unix_time(date_time, movement_get_current_timezone_offset());
// TODO: I'm skipping over some steps here.
// https://www.giss.nasa.gov/tools/mars24/help/algorithm.html
#include "minimal_clock_face.h"
static void _minimal_clock_face_update_display() {
- watch_date_time date_time = watch_rtc_get_date_time();
+ watch_date_time_t date_time = watch_rtc_get_date_time();
char buffer[11];
if (!movement_clock_mode_24h()) {
char buf[11];
uint8_t pos;
- watch_date_time date_time;
+ watch_date_time_t date_time;
uint32_t previous_date_time;
switch (event.event_type) {
case EVENT_ACTIVATE:
movement_watch_face_advisory_t retval = { 0 };
if (state->signal_enabled) {
- watch_date_time date_time = watch_rtc_get_date_time();
+ watch_date_time_t date_time = watch_rtc_get_date_time();
retval.wants_background_task = date_time.unit.minute == 0;
}
char buf[11];
uint8_t pos;
- watch_date_time date_time;
+ watch_date_time_t date_time;
uint32_t previous_date_time;
switch (event.event_type) {
case EVENT_ACTIVATE:
movement_watch_face_advisory_t retval = { 0 };
if (state->signal_enabled) {
- watch_date_time date_time = watch_rtc_get_date_time();
+ watch_date_time_t date_time = watch_rtc_get_date_time();
retval.wants_background_task = date_time.unit.minute == 0;
}
char buf[11];
uint8_t pos;
- watch_date_time date_time;
+ watch_date_time_t date_time;
uint32_t previous_date_time;
switch (event.event_type) {
case EVENT_ACTIVATE:
movement_watch_face_advisory_t retval = { 0 };
if (state->signal_enabled) {
- watch_date_time date_time = watch_rtc_get_date_time();
+ watch_date_time_t date_time = watch_rtc_get_date_time();
retval.wants_background_task = date_time.unit.minute == 0;
}
char buf[11];
uint8_t pos;
- watch_date_time date_time;
+ watch_date_time_t date_time;
uint32_t previous_date_time;
switch (event.event_type) {
case EVENT_ACTIVATE:
movement_watch_face_advisory_t retval = { 0 };
if (state->signal_enabled) {
- watch_date_time date_time = watch_rtc_get_date_time();
+ watch_date_time_t date_time = watch_rtc_get_date_time();
retval.wants_background_task = date_time.unit.minute == 0;
}
uint32_t timestamp;
uint32_t previous_date_time;
- watch_date_time date_time;
+ watch_date_time_t date_time;
switch (event.event_type) {
case EVENT_ACTIVATE:
bool wyoscan_face_loop(movement_event_t event, void *context) {
wyoscan_state_t *state = (wyoscan_state_t *)context;
- watch_date_time date_time;
+ watch_date_time_t date_time;
switch (event.event_type) {
case EVENT_ACTIVATE:
break;
// One logged activity
typedef struct __attribute__((__packed__)) {
// Activity's start time
- watch_date_time start_time;
+ watch_date_time_t start_time;
// Total duration of activity, including time spend in paus
uint16_t total_sec;
uint16_t counter;
// Start of currently logged activity, if any
- watch_date_time start_time;
+ watch_date_time_t start_time;
// Total seconds elapsed since logging started
uint16_t curr_total_sec;
// Those are not up-to-date because ticks have not been coming
if (state->le_state != 0 && state->mode == ACTM_LOGGING) {
state->le_state = 2;
- watch_date_time now = watch_rtc_get_date_time();
+ watch_date_time_t now = watch_rtc_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(state->start_time, 0);
uint32_t total_seconds = now_timestamp - start_timestamp;
// If we're in LE state: per-minute update is special
if (state->le_state == 1) {
- watch_date_time now = watch_rtc_get_date_time();
+ watch_date_time_t now = watch_rtc_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(state->start_time, 0);
uint32_t total_seconds = now_timestamp - start_timestamp;
// Briefly, show time without seconds
else {
watch_clear_indicator(WATCH_INDICATOR_LAP);
- watch_date_time now = watch_rtc_get_date_time();
+ watch_date_time_t now = watch_rtc_get_date_time();
uint8_t hour = now.unit.hour;
if (!movement_clock_mode_24h()) {
watch_clear_indicator(WATCH_INDICATOR_24H);
// Do this the hard way, byte by byte, to avoid high/low endedness issues
// Higher order bytes first, is our serialization format
uint8_t val;
- // watch_date_time start_time;
+ // watch_date_time_t start_time;
// uint16_t total_sec;
// uint16_t pause_sec;
// uint8_t activity_type;
}
#endif
- watch_date_time date_time = watch_rtc_get_date_time();
+ watch_date_time_t date_time = watch_rtc_get_date_time();
uint32_t timestamp = watch_utility_date_time_to_unix_time(date_time, movement_get_current_timezone_offset());
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);
static void _day_one_face_update(day_one_state_t *state) {
char buf[15];
- watch_date_time date_time = watch_rtc_get_date_time();
+ watch_date_time_t date_time = watch_rtc_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);
if (julian_date < julian_birthdate) {
break;
// otherwise, check if we have to update. the display only needs to change at midnight!
case PAGE_DISPLAY: {
- watch_date_time date_time = watch_rtc_get_date_time();
+ watch_date_time_t date_time = watch_rtc_get_date_time();
if (date_time.unit.hour == 0 && date_time.unit.minute == 0 && date_time.unit.second == 0) {
_day_one_face_update(state);
}
static void _running_display(movement_event_t event, deadline_state_t *state);
static void _setting_init(deadline_state_t *state);
static bool _setting_loop(movement_event_t event, void *context);
-static void _setting_display(movement_event_t event, deadline_state_t *state, watch_date_time date);
+static void _setting_display(movement_event_t event, deadline_state_t *state, watch_date_time_t date);
/* Utility functions */
static void _background_alarm_play(deadline_state_t *state);
static void _background_alarm_schedule(deadline_state_t *state);
static void _background_alarm_cancel(deadline_state_t *state);
-static void _increment_date(deadline_state_t *state, watch_date_time date_time);
+static void _increment_date(deadline_state_t *state, watch_date_time_t date_time);
static inline void _change_tick_freq(uint8_t freq, deadline_state_t *state);
static inline bool _is_leap(int16_t y);
static inline int _days_in_month(int16_t mpnth, int16_t y);
/* Determine index of closest deadline */
static uint8_t _closest_deadline(deadline_state_t *state)
{
- watch_date_time now = watch_rtc_get_date_time();
+ watch_date_time_t now = watch_rtc_get_date_time();
uint32_t now_ts = watch_utility_date_time_to_unix_time(now, movement_get_current_timezone_offset());
uint32_t min_ts = UINT32_MAX;
uint8_t min_index = 0;
static inline void _reset_deadline(deadline_state_t *state)
{
/* Get current time and reset hours/minutes/seconds */
- watch_date_time date_time = watch_rtc_get_date_time();
+ watch_date_time_t date_time = watch_rtc_get_date_time();
date_time.unit.second = 0;
date_time.unit.minute = 0;
date_time.unit.hour = 0;
}
/* Increment date in settings mode. Function taken from `set_time_face.c` */
-static void _increment_date(deadline_state_t *state, watch_date_time date_time)
+static void _increment_date(deadline_state_t *state, watch_date_time_t date_time)
{
const uint8_t days_in_month[12] = { 31, 28, 31, 30, 31, 30, 30, 31, 30, 31, 30, 31 };
else
watch_clear_indicator(WATCH_INDICATOR_BELL);
- watch_date_time now = watch_rtc_get_date_time();
+ watch_date_time_t now = watch_rtc_get_date_time();
uint32_t now_ts = watch_utility_date_time_to_unix_time(now, movement_get_current_timezone_offset());
/* Deadline expired */
}
/* Get date time structs */
- watch_date_time deadline = watch_utility_date_time_from_unix_time(state->deadlines[state->current_index], movement_get_current_timezone_offset()
+ watch_date_time_t deadline = watch_utility_date_time_from_unix_time(state->deadlines[state->current_index], movement_get_current_timezone_offset()
);
/* Calculate naive difference of dates */
}
/* Update display in settings mode */
-static void _setting_display(movement_event_t event, deadline_state_t *state, watch_date_time date_time)
+static void _setting_display(movement_event_t event, deadline_state_t *state, watch_date_time_t date_time)
{
char buf[11];
static bool _setting_loop(movement_event_t event, void *context)
{
deadline_state_t *state = (deadline_state_t *) context;
- watch_date_time date_time;
+ watch_date_time_t date_time;
date_time = watch_utility_date_time_from_unix_time(state->deadlines[state->current_index], movement_get_current_timezone_offset());
if (event.event_type != EVENT_BACKGROUND_TASK)
return false;
/* Determine closest deadline */
- watch_date_time now = watch_rtc_get_date_time();
+ watch_date_time_t now = watch_rtc_get_date_time();
uint32_t now_ts = watch_utility_date_time_to_unix_time(now, movement_get_current_timezone_offset());
uint32_t next_ts = state->deadlines[_closest_deadline(state)];
return false;
/* Deadline within next minute. Let's set up an alarm */
- watch_date_time next = watch_utility_date_time_from_unix_time(next_ts, movement_get_current_timezone_offset());
+ watch_date_time_t next = watch_utility_date_time_from_unix_time(next_ts, movement_get_current_timezone_offset());
movement_request_wake();
movement_schedule_background_task_for_face(state->face_idx, next);
return false;
#include "../../../watch-library/hardware/hri/hri_tc_l22.h"
#endif
-static const watch_date_time distant_future = {.unit = {0, 0, 0, 1, 1, 63}};
+static const watch_date_time_t distant_future = {.unit = {0, 0, 0, 1, 1, 63}};
static bool _is_running;
static uint32_t _ticks;
static void check_and_reset_hi_score(endless_runner_state_t *state) {
// Resets the hi score at the beginning of each month.
- watch_date_time date_time = watch_rtc_get_date_time();
+ watch_date_time_t date_time = watch_rtc_get_date_time();
if ((state -> year_last_hi_score != date_time.unit.year) ||
(state -> month_last_hi_score != date_time.unit.month))
{
display_difficulty(difficulty);
}
-static void display_time(watch_date_time date_time, bool clock_mode_24h) {
- static watch_date_time previous_date_time;
+static void display_time(watch_date_time_t date_time, bool clock_mode_24h) {
+ static watch_date_time_t previous_date_time;
char buf[6 + 1];
// If the hour needs updating or it's the first time displaying the time
#include <string.h>
static inline uint32_t today_unix(const uint32_t utc_offset) {
- const watch_date_time dt = watch_rtc_get_date_time();
+ const watch_date_time_t dt = watch_rtc_get_date_time();
return watch_utility_convert_to_unix_time(dt.unit.year + 2020, dt.unit.month,
dt.unit.day, 0, 0, 0, utc_offset);
}
static uint32_t _get_now_ts() {
// returns the current date time as unix timestamp
- watch_date_time now = watch_rtc_get_date_time();
+ watch_date_time_t now = watch_rtc_get_date_time();
return watch_utility_date_time_to_unix_time(now, 0);
}
if (delta <= 0) delta = 1;
_target_ts += delta;
// schedule next background task
- watch_date_time target_dt = watch_utility_date_time_from_unix_time(_target_ts, 0);
+ watch_date_time_t target_dt = watch_utility_date_time_from_unix_time(_target_ts, 0);
movement_schedule_background_task_for_face(state->face_idx, target_dt);
// play sound
watch_buzzer_play_sequence(sound_seq, NULL);
// resume paused timer
_now_ts = _get_now_ts();
_target_ts += _now_ts - _paused_ts;
- watch_date_time target_dt = watch_utility_date_time_from_unix_time(_target_ts, 0);
+ watch_date_time_t target_dt = watch_utility_date_time_from_unix_time(_target_ts, 0);
movement_schedule_background_task_for_face(state->face_idx, target_dt);
state->face_state = interval_state_running;
watch_set_indicator(WATCH_INDICATOR_BELL);
return 0;
// Otherwise, set the start date to the first day of the first tracked cycle
- watch_date_time date_time_start;
+ watch_date_time_t date_time_start;
date_time_start.unit.second = 0;
date_time_start.unit.minute = 0;
date_time_start.unit.hour = 0;
date_time_start.unit.year = state->dates.bit.first_year;
// Get the current date and time
- watch_date_time date_time_now = watch_rtc_get_date_time();
+ watch_date_time_t date_time_now = watch_rtc_get_date_time();
// Convert the start date and current date to Unix time
uint32_t unix_start = watch_utility_date_time_to_unix_time(date_time_start, state->utc_offset);
static inline uint32_t get_day_pk_fert(menstrual_cycle_state_t *state, fertile_window which_day) {
// Get the date of the previous period
- watch_date_time date_prev_period;
+ watch_date_time_t date_prev_period;
date_prev_period.unit.second = 0;
date_prev_period.unit.minute = 0;
date_prev_period.unit.hour = 0;
return false;
// Get the current date/time
- watch_date_time date_time_now = watch_rtc_get_date_time();
+ watch_date_time_t date_time_now = watch_rtc_get_date_time();
// Check if the current day falls between the first and last predicted peak fertility days
if (get_day_pk_fert(state, first_day) > get_day_pk_fert(state, last_day)) { // We are crossing over the end of the month
static inline void update_shortest_longest_cycle(menstrual_cycle_state_t *state) {
// Get the date of the previous menstrual cycle
- watch_date_time date_prev_period;
+ watch_date_time_t date_prev_period;
date_prev_period.unit.second = 0;
date_prev_period.unit.minute = 0;
date_prev_period.unit.hour = 0;
bool menstrual_cycle_face_loop(movement_event_t event, void *context) {
menstrual_cycle_state_t *state = (menstrual_cycle_state_t *)context;
- watch_date_time date_period;
+ watch_date_time_t date_period;
uint8_t current_page = state->current_page;
uint8_t first_day_fert;
uint8_t last_day_fert;
static void _update(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_t date_time = watch_rtc_get_date_time();
uint32_t now = watch_utility_date_time_to_unix_time(date_time, movement_get_current_timezone_offset()) + offset;
date_time = watch_utility_date_time_from_unix_time(now, movement_get_current_timezone_offset());
double currentfrac = fmod(now - FIRST_MOON, LUNAR_SECONDS) / LUNAR_SECONDS;
bool moon_phase_face_loop(movement_event_t event, void *context) {
moon_phase_state_t *state = (moon_phase_state_t *)context;
- watch_date_time date_time;
+ watch_date_time_t date_time;
switch (event.event_type) {
case EVENT_ACTIVATE:
};
static void _orrery_face_recalculate(orrery_state_t *state) {
- watch_date_time date_time = watch_rtc_get_date_time();
+ watch_date_time_t date_time = watch_rtc_get_date_time();
uint32_t timestamp = watch_utility_date_time_to_unix_time(date_time, movement_get_current_timezone_offset());
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);
// location detected
state->no_location = false;
- watch_date_time date_time = watch_rtc_get_date_time(); // the current local date / time
- watch_date_time utc_now = watch_utility_date_time_convert_zone(date_time, movement_get_current_timezone_offset(), 0); // the current date / time in UTC
- watch_date_time scratch_time; // scratchpad, contains different values at different times
- watch_date_time midnight;
+ watch_date_time_t date_time = watch_rtc_get_date_time(); // the current local date / time
+ watch_date_time_t utc_now = watch_utility_date_time_convert_zone(date_time, movement_get_current_timezone_offset(), 0); // the current date / time in UTC
+ watch_date_time_t scratch_time; // scratchpad, contains different values at different times
+ watch_date_time_t midnight;
scratch_time.reg = midnight.reg = utc_now.reg;
midnight.unit.hour = midnight.unit.minute = midnight.unit.second = 0; // start of the day at midnight
char ruler[3];
uint8_t weekday, planet, planetary_hour;
uint32_t current_hour_epoch;
- watch_date_time scratch_time;
+ watch_date_time_t scratch_time;
// check if we have a location. If not, display error
if ( state->no_location ) {
}
// get current time
- watch_date_time date_time = watch_rtc_get_date_time(); // the current local date / time
- watch_date_time utc_now = watch_utility_date_time_convert_zone(date_time, movement_get_current_timezone_offset(), 0); // the current date / time in UTC
+ watch_date_time_t date_time = watch_rtc_get_date_time(); // the current local date / time
+ watch_date_time_t utc_now = watch_utility_date_time_convert_zone(date_time, movement_get_current_timezone_offset(), 0); // the current date / time in UTC
current_hour_epoch = watch_utility_date_time_to_unix_time(utc_now, 0);
// set the current planetary hour as default screen
// location detected
state->no_location = false;
- watch_date_time date_time = watch_rtc_get_date_time(); // the current local date / time
- watch_date_time utc_now = watch_utility_date_time_convert_zone(date_time, movement_get_current_timezone_offset(), 0); // the current date / time in UTC
- watch_date_time scratch_time; // scratchpad, contains different values at different times
- watch_date_time midnight;
+ watch_date_time_t date_time = watch_rtc_get_date_time(); // the current local date / time
+ watch_date_time_t utc_now = watch_utility_date_time_convert_zone(date_time, movement_get_current_timezone_offset(), 0); // the current date / time in UTC
+ watch_date_time_t scratch_time; // scratchpad, contains different values at different times
+ watch_date_time_t midnight;
scratch_time.reg = midnight.reg = utc_now.reg;
midnight.unit.hour = midnight.unit.minute = midnight.unit.second = 0; // start of the day at midnight
bool day_ruler;
bool no_location;
sunrise_sunset_state_t sunstate;
- watch_date_time scratch;
+ watch_date_time_t scratch;
} planetary_time_state_t;
void planetary_time_face_setup(uint8_t watch_face_index, void ** context_ptr);
return;
}
state->nextbeep_ts = state->target_ts - beepseconds[beepflag+1];
- watch_date_time target_dt = watch_utility_date_time_from_unix_time(state->nextbeep_ts, get_tz_offset(settings));
+ watch_date_time_t target_dt = watch_utility_date_time_from_unix_time(state->nextbeep_ts, get_tz_offset(settings));
movement_schedule_background_task_for_face(state->watch_face_index, target_dt);
//background task is set, now we have time to play the tune. If this is cancelled accidentally, the next alarm will still ring. Sound is implemented non-blocking, so that neither buttons nor display output are compromised.
for (int i = 0; i < 5; i++) {
beepflag++;
}
if (state->index > 5 || state->minutes[state->index] == 0) {
- watch_date_time now = watch_rtc_get_date_time();
+ watch_date_time_t now = watch_rtc_get_date_time();
state->now_ts = watch_utility_date_time_to_unix_time(now, get_tz_offset(settings));
state->target_ts = state->now_ts;
if (alarmflag != 0){
}
movement_request_tick_frequency(1); //synchronises tick with the moment the button was pressed. Solves 1s offset between sound and display, solves up to +-0.5s offset between button action and display.
state->mode = sl_running;
- watch_date_time now = watch_rtc_get_date_time();
+ watch_date_time_t now = watch_rtc_get_date_time();
state->now_ts = watch_utility_date_time_to_unix_time(now, get_tz_offset(settings));
state->target_ts = watch_utility_offset_timestamp(state->now_ts, 0, state->minutes[state->index], 0);
ring(state, settings);
void sailing_face_activate(void *context) {
sailing_state_t *state = (sailing_state_t *)context;
if(state->mode == sl_running) {
- watch_date_time now = watch_rtc_get_date_time();
+ watch_date_time_t now = watch_rtc_get_date_time();
state->now_ts = watch_utility_date_time_to_unix_time(now, get_tz_offset(settings));
}
if(state->mode == sl_counting) {
- watch_date_time now = watch_rtc_get_date_time();
+ watch_date_time_t now = watch_rtc_get_date_time();
state->now_ts = watch_utility_date_time_to_unix_time(now, get_tz_offset(settings));
watch_set_indicator(WATCH_INDICATOR_LAP);
}
#include "ships_bell_face.h"
static void ships_bell_ring() {
- watch_date_time date_time = watch_rtc_get_date_time();
+ watch_date_time_t date_time = watch_rtc_get_date_time();
date_time.unit.hour %= 4;
date_time.unit.hour = date_time.unit.hour == 0 && date_time.unit.minute < 30 ? 4 : date_time.unit.hour;
sprintf(buf, " ");
}
- watch_date_time date_time = watch_rtc_get_date_time();
+ watch_date_time_t date_time = watch_rtc_get_date_time();
date_time.unit.hour %= 4;
sprintf(buf + 1, " %d%02d%02d", date_time.unit.hour, date_time.unit.minute, date_time.unit.second);
if (!state->bell_enabled) return retval;
- watch_date_time date_time = watch_rtc_get_date_time();
+ watch_date_time_t date_time = watch_rtc_get_date_time();
if (!(date_time.unit.minute == 0 || date_time.unit.minute == 30)) return retval;
date_time.unit.hour %= 12;
}
// Convert JDE to Gergorian datetime as per Meeus Ch 7
-static watch_date_time jde_to_date_time(double JDE) {
+static watch_date_time_t jde_to_date_time(double JDE) {
double tmp = JDE + 0.5;
double Z = floor(tmp);
double F = fmod(tmp, 1);
double minutes = fmod(hours, 1) * 60;
double seconds = fmod(minutes, 1) * 60;
- watch_date_time result = {.unit = {
+ watch_date_time_t result = {.unit = {
floor(seconds),
floor(minutes),
floor(hours),
*context_ptr = malloc(sizeof(solstice_state_t));
solstice_state_t *state = (solstice_state_t *)*context_ptr;
- watch_date_time now = watch_rtc_get_date_time();
+ watch_date_time_t now = watch_rtc_get_date_time();
state->year = now.unit.year;
state->index = 0;
calculate_datetimes(state, settings);
static void show_main_screen(solstice_state_t *state) {
char buf[11];
- watch_date_time date_time = state->datetimes[state->index];
+ watch_date_time_t date_time = state->datetimes[state->index];
sprintf(buf, " %2d %2d%02d", date_time.unit.year + 20, date_time.unit.month, date_time.unit.day);
watch_display_string(buf, 0);
}
static void show_date_time(solstice_state_t *state) {
char buf[11];
- watch_date_time date_time = state->datetimes[state->index];
+ watch_date_time_t date_time = state->datetimes[state->index];
if (!movement_clock_mode_24h()) {
if (date_time.unit.hour < 12) {
watch_clear_indicator(WATCH_INDICATOR_PM);
*/
typedef struct {
- watch_date_time datetimes[4];
+ watch_date_time_t datetimes[4];
uint8_t year;
uint8_t index;
} solstice_state_t;
// distant future for background task: January 1, 2083
// see stopwatch_face_activate for details
-static const watch_date_time distant_future = {
+static const watch_date_time_t distant_future = {
.unit = {0, 0, 0, 1, 1, 63}
};
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_t now = watch_rtc_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;
typedef struct {
bool running;
- watch_date_time start_time; // while running, show the difference between this time and now
+ watch_date_time_t start_time; // while running, show the difference between this time and now
uint32_t seconds_counted; // set this value when paused, and show that instead.
} stopwatch_state_t;
}
// Stop running
state->running = false;
- watch_date_time now = watch_rtc_get_date_time();
+ watch_date_time_t now = watch_rtc_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(state->start_seconds, 0);
// Total time in centiseconds
bool editing; // editing distance
uint8_t active_digit; // active digit at editing distance
uint8_t animation_state; // running animation state
- watch_date_time start_seconds; // start_seconds
+ watch_date_time_t start_seconds; // start_seconds
int8_t start_subsecond; // start_subsecond count (each count = 250 ms)
distance_digits_t dist_digits; // distance digitwise
uint32_t distance; // distance
thermistor_driver_enable();
float temperature_c = thermistor_driver_get_temperature();
thermistor_driver_disable();
- watch_date_time date_time = watch_rtc_get_date_time();
+ watch_date_time_t date_time = watch_rtc_get_date_time();
int temp = round(temperature_c * 2);
if ((temp < 0) || (temp >= 70)) break;
(void) context;
movement_watch_face_advisory_t retval = { 0 };
- watch_date_time date_time = watch_rtc_get_date_time();
+ watch_date_time_t date_time = watch_rtc_get_date_time();
// Updating data every 5 minutes
retval.wants_background_task = date_time.unit.minute % 5 == 0;
watch_display_character(_state_titles[state->current_page][2], 3);
if (state->current_page < TIME_LEFT_FACE_SETTINGS_STATE) {
// we are displaying days left or days from birth
- watch_date_time date_time = watch_rtc_get_date_time();
+ watch_date_time_t date_time = watch_rtc_get_date_time();
uint32_t julian_current_day = _juliandaynum(date_time.unit.year + WATCH_RTC_REFERENCE_YEAR, date_time.unit.month, date_time.unit.day);
uint32_t julian_target_day = _juliandaynum(state->target_date.bit.year, state->target_date.bit.month, state->target_date.bit.day);
int32_t days_left = julian_target_day - julian_current_day;
state->birth_date.bit.day = 1;
watch_store_backup_data(state->birth_date.reg, 2);
// set target date to today + 10 years (just to have any value)
- watch_date_time date_time = watch_rtc_get_date_time();
+ watch_date_time_t date_time = watch_rtc_get_date_time();
state->target_date.bit.year = date_time.unit.year + WATCH_RTC_REFERENCE_YEAR + 10;
state->target_date.bit.month = date_time.unit.month;
state->target_date.bit.day = date_time.unit.day;
time_left_state_t *state = (time_left_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_t date_time = watch_rtc_get_date_time();
state->current_year = date_time.unit.year + WATCH_RTC_REFERENCE_YEAR;
_quick_ticks_running = false;
// fetch the user's birth date from the birthday register
_draw(state, subsecond);
} 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_t date_time = watch_rtc_get_date_time();
if (date_time.unit.hour == 0 && date_time.unit.minute == 0 && date_time.unit.second == 0) {
_draw(state, subsecond);
}
static void _start(timer_state_t *state, bool with_beep) {
if (state->timers[state->current_timer].value == 0) return;
- watch_date_time now = watch_rtc_get_date_time();
+ watch_date_time_t now = watch_rtc_get_date_time();
state->now_ts = watch_utility_date_time_to_unix_time(now, movement_get_current_timezone_offset());
if (state->mode == pausing)
state->target_ts = state->now_ts + state->paused_left;
state->timers[state->current_timer].unit.hours,
state->timers[state->current_timer].unit.minutes,
state->timers[state->current_timer].unit.seconds);
- watch_date_time target_dt = watch_utility_date_time_from_unix_time(state->target_ts, movement_get_current_timezone_offset());
+ watch_date_time_t target_dt = watch_utility_date_time_from_unix_time(state->target_ts, movement_get_current_timezone_offset());
state->mode = running;
movement_schedule_background_task_for_face(state->watch_face_index, target_dt);
watch_set_indicator(WATCH_INDICATOR_BELL);
watch_display_string("TR", 0);
watch_set_colon();
if(state->mode == running) {
- watch_date_time now = watch_rtc_get_date_time();
+ watch_date_time_t now = watch_rtc_get_date_time();
state->now_ts = watch_utility_date_time_to_unix_time(now, movement_get_current_timezone_offset());
watch_set_indicator(WATCH_INDICATOR_BELL);
} else {
}
static void tomato_start(tomato_state_t *state) {
- watch_date_time now = watch_rtc_get_date_time();
+ watch_date_time_t now = watch_rtc_get_date_time();
int8_t length = (int8_t) get_length(state);
state->mode = tomato_run;
state->now_ts = watch_utility_date_time_to_unix_time(now, movement_get_current_timezone_offset());
state->target_ts = watch_utility_offset_timestamp(state->now_ts, 0, length, 0);
- watch_date_time target_dt = watch_utility_date_time_from_unix_time(state->target_ts, movement_get_current_timezone_offset());
+ watch_date_time_t target_dt = watch_utility_date_time_from_unix_time(state->target_ts, movement_get_current_timezone_offset());
movement_schedule_background_task(target_dt);
watch_set_indicator(WATCH_INDICATOR_BELL);
}
void tomato_face_activate(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_t now = watch_rtc_get_date_time();
state->now_ts = watch_utility_date_time_to_unix_time(now, movement_get_current_timezone_offset());
watch_set_indicator(WATCH_INDICATOR_BELL);
}
movement_watch_face_advisory_t retval = { 0 };
if ( state->mode ) {
- watch_date_time now = watch_rtc_get_date_time();
+ watch_date_time_t now = watch_rtc_get_date_time();
retval.wants_background_task = state->hour==now.unit.hour && state->minute==now.unit.minute;
// We’re at the mercy of the advise handler
// In Safari, the emulator triggers at the ›end‹ of the minute
#endif
static uint32_t get_day_unix_time(void) {
- watch_date_time now = watch_rtc_get_date_time();
+ watch_date_time_t now = watch_rtc_get_date_time();
#if WORDLE_USE_DAILY_STREAK == 2
now.unit.hour = now.unit.minute = now.unit.second = 0;
#endif
// Pressing the alarm button enters the log mode, where the main display shows the number of interrupts detected in each of the last
// 24 hours (the hour is shown in the top right digit and AM/PM indicator, if the clock is set to 12 hour mode)
-static void _lis2dw_logging_face_update_display(lis2dw_logger_state_t *logger_state, lis2dw_wakeup_source wakeup_source) {
+static void _lis2dw_logging_face_update_display(lis2dw_logger_state_t *logger_state, lis2dw_wakeup_source_t wakeup_source) {
char buf[14];
char time_indication_character;
int8_t pos;
- watch_date_time date_time;
+ watch_date_time_t date_time;
if (logger_state->log_ticks) {
pos = (logger_state->data_points - 1 - logger_state->display_index) % LIS2DW_LOGGING_NUM_DATA_POINTS;
}
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_t date_time = watch_rtc_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;
bool lis2dw_logging_face_loop(movement_event_t event, void *context) {
lis2dw_logger_state_t *logger_state = (lis2dw_logger_state_t *)context;
- lis2dw_wakeup_source wakeup_source = 0;
- lis2dw_interrupt_source interrupt_source = 0;
+ lis2dw_wakeup_source_t wakeup_source = 0;
+ lis2dw_interrupt_source_t interrupt_source = 0;
switch (event.event_type) {
case EVENT_LIGHT_BUTTON_DOWN:
movement_watch_face_advisory_t lis2dw_logging_face_advise(void *context) {
lis2dw_logger_state_t *logger_state = (lis2dw_logger_state_t *)context;
- watch_date_time date_time = watch_rtc_get_date_time();
+ watch_date_time_t date_time = watch_rtc_get_date_time();
movement_watch_face_advisory_t retval = { 0 };
// this is kind of an abuse of the API, but, let's use the 1 minute tick to shift all our data over.
#define LIS2DW_LOGGING_NUM_DATA_POINTS (96)
typedef struct {
- watch_date_time timestamp;
+ watch_date_time_t timestamp;
uint32_t x_interrupts;
uint32_t y_interrupts;
uint32_t z_interrupts;
lis2dw_enable_fifo();
accelerometer_data_acquisition_record_t record;
- watch_date_time date_time = watch_rtc_get_date_time();
+ watch_date_time_t date_time = watch_rtc_get_date_time();
state->starting_timestamp = watch_utility_date_time_to_unix_time(date_time, movement_get_current_timezone_offset());
record.header.info.record_type = ACCELEROMETER_DATA_ACQUISITION_HEADER;
record.header.info.range = ACCELEROMETER_RANGE;
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_t date_time = watch_rtc_get_date_time();
size_t pos = logger_state->data_points % THERMISTOR_LOGGING_NUM_DATA_POINTS;
logger_state->data[pos].timestamp.reg = date_time.reg;
if (pos < 0) {
sprintf(buf, "TL%2dno dat", logger_state->display_index);
} else if (logger_state->ts_ticks) {
- watch_date_time date_time = logger_state->data[pos].timestamp;
+ watch_date_time_t date_time = logger_state->data[pos].timestamp;
watch_set_colon();
if (clock_mode_24h) {
watch_set_indicator(WATCH_INDICATOR_24H);
#define THERMISTOR_LOGGING_NUM_DATA_POINTS (36)
typedef struct {
- watch_date_time timestamp;
+ watch_date_time_t timestamp;
float temperature_c;
} thermistor_logger_data_point_t;
bool thermistor_readout_face_loop(movement_event_t event, void *context) {
(void) context;
- watch_date_time date_time = watch_rtc_get_date_time();
+ watch_date_time_t date_time = watch_rtc_get_date_time();
switch (event.event_type) {
case EVENT_ALARM_BUTTON_DOWN:
movement_set_use_imperial_units(!movement_use_imperial_units());
if (finetune_page == 0) {
watch_display_string("FT", 0);
- watch_date_time date_time = watch_rtc_get_date_time();
+ watch_date_time_t date_time = watch_rtc_get_date_time();
sprintf(buf, "%02d", date_time.unit.second);
watch_display_string(buf, 8);
watch_rtc_enable(false);
delay_ms(delta);
if (delta > 500) {
- watch_date_time date_time = watch_rtc_get_date_time();
+ watch_date_time_t date_time = watch_rtc_get_date_time();
date_time.unit.second = (date_time.unit.second + 1) % 60;
if (date_time.unit.second == 0) { // Overflow
date_time.unit.minute = (date_time.unit.minute + 1) % 60;
// If needed, update your display here, at canonical 0.5sec position.
// We flash green LED once per minute to measure clock error, when we are not on first screen
if (finetune_page!=0) {
- watch_date_time date_time;
+ watch_date_time_t date_time;
date_time = watch_rtc_get_date_time();
if (date_time.unit.second == 0) {
watch_set_led_green();
static void nanosec_init_profile(void) {
nanosec_changed = true;
nanosec_state.correction_cadence = 10;
- watch_date_time date_time = watch_rtc_get_date_time();
+ watch_date_time_t date_time = watch_rtc_get_date_time();
nanosec_state.last_correction_time = watch_utility_date_time_to_unix_time(date_time, 0);
// init data after changing profile - do that once per profile selection
float nanosec_get_aging() // Returns aging correction in ppm
{
- watch_date_time date_time = watch_rtc_get_date_time();
+ watch_date_time_t date_time = watch_rtc_get_date_time();
float years = (watch_utility_date_time_to_unix_time(date_time, 0) - nanosec_state.last_correction_time) / 31536000.0f; // Years passed since finetune
return years*nanosec_state.aging_ppm_pa/100.0f;
}
// No need for background correction if we are on profile 0 - static hardware correction.
if (nanosec_state.correction_profile != 0) {
- watch_date_time date_time = watch_rtc_get_date_time();
+ watch_date_time_t date_time = watch_rtc_get_date_time();
retval.wants_background_task = date_time.unit.minute % nanosec_state.correction_cadence == 0;
}
uint32_t b5;
uint32_t b6;
uint32_t b7;
- watch_date_time rtc;
+ watch_date_time_t rtc;
} savefile_t;
#define SAVE_LOAD_SLOTS 4
char set_time_hackwatch_face_titles[][3] = {"HR", "M1", "SE", "YR", "MO", "DA", "ZO"};
#define set_time_hackwatch_face_NUM_SETTINGS (sizeof(set_time_hackwatch_face_titles) / sizeof(*set_time_hackwatch_face_titles))
-watch_date_time date_time_settings;
+watch_date_time_t date_time_settings;
void set_time_hackwatch_face_setup(uint8_t watch_face_index, void ** context_ptr) {
(void) watch_face_index;
char buf[16];
uint32_t centibeats;
- watch_date_time date_time;
+ watch_date_time_t date_time;
switch (event.event_type) {
case EVENT_ACTIVATE:
case EVENT_TICK:
typedef struct {
struct {
- watch_date_time previous;
+ watch_date_time_t previous;
} date_time;
uint8_t last_battery_check;
uint8_t watch_face_index;
clock_indicate(WATCH_INDICATOR_24H, !!movement_clock_mode_24h());
}
-static bool clock_is_pm(watch_date_time date_time) {
+static bool clock_is_pm(watch_date_time_t date_time) {
return date_time.unit.hour >= 12;
}
-static void clock_indicate_pm(watch_date_time date_time) {
+static void clock_indicate_pm(watch_date_time_t date_time) {
if (movement_clock_mode_24h()) { return; }
clock_indicate(WATCH_INDICATOR_PM, clock_is_pm(date_time));
}
clock_indicate(WATCH_INDICATOR_LAP, clock->battery_low);
}
-static watch_date_time clock_24h_to_12h(watch_date_time date_time) {
+static watch_date_time_t clock_24h_to_12h(watch_date_time_t date_time) {
date_time.unit.hour %= 12;
if (date_time.unit.hour == 0) {
return date_time;
}
-static void clock_check_battery_periodically(clock_state_t *clock, watch_date_time date_time) {
+static void clock_check_battery_periodically(clock_state_t *clock, watch_date_time_t date_time) {
// check the battery voltage once a day
if (date_time.unit.day == clock->last_battery_check) { return; }
clock_indicate_time_signal(clock);
}
-static void clock_display_all(watch_date_time date_time) {
+static void clock_display_all(watch_date_time_t date_time) {
char buf[8 + 1];
snprintf(
watch_display_text(WATCH_POSITION_BOTTOM, buf + 2);
}
-static bool clock_display_some(watch_date_time current, watch_date_time previous) {
+static bool clock_display_some(watch_date_time_t current, watch_date_time_t previous) {
if ((current.reg >> 6) == (previous.reg >> 6)) {
// everything before seconds is the same, don't waste cycles setting those segments.
}
}
-static void clock_display_clock(clock_state_t *clock, watch_date_time current) {
+static void clock_display_clock(clock_state_t *clock, watch_date_time_t current) {
if (!clock_display_some(current, clock->date_time.previous)) {
if (movement_clock_mode_24h() == MOVEMENT_CLOCK_MODE_12H) {
clock_indicate_pm(current);
}
}
-static void clock_display_low_energy(watch_date_time date_time) {
+static void clock_display_low_energy(watch_date_time_t date_time) {
if (movement_clock_mode_24h() == MOVEMENT_CLOCK_MODE_12H) {
clock_indicate_pm(date_time);
date_time = clock_24h_to_12h(date_time);
bool clock_face_loop(movement_event_t event, void *context) {
clock_state_t *state = (clock_state_t *) context;
- watch_date_time current;
+ watch_date_time_t current;
switch (event.event_type) {
case EVENT_LOW_ENERGY_UPDATE:
clock_state_t *state = (clock_state_t *) context;
if (state->time_signal_enabled) {
- watch_date_time date_time = movement_get_local_date_time();
+ watch_date_time_t date_time = movement_get_local_date_time();
retval.wants_background_task = date_time.unit.minute == 0;
}
char buf[11];
uint32_t previous_date_time;
- watch_date_time date_time;
+ watch_date_time_t date_time;
switch (event.event_type) {
case EVENT_ACTIVATE:
if (movement_clock_mode_24h()) watch_set_indicator(WATCH_INDICATOR_24H);
static int8_t _wait_ticks;
-static uint8_t _get_weekday_idx(watch_date_time date_time) {
+static uint8_t _get_weekday_idx(watch_date_time_t date_time) {
date_time.unit.year += 20;
if (date_time.unit.month <= 2) {
date_time.unit.month += 12;
static void _alarm_update_alarm_enabled(alarm_state_t *state) {
// save indication for active alarms to movement settings
bool active_alarms = false;
- watch_date_time now;
+ watch_date_time_t now;
bool now_init = false;
uint8_t weekday_idx;
uint16_t now_minutes_of_day;
alarm_state_t *state = (alarm_state_t *)context;
movement_watch_face_advisory_t retval = { 0 };
- watch_date_time now = movement_get_local_date_time();
+ watch_date_time_t now = movement_get_local_date_time();
// just a failsafe: never fire more than one alarm within a minute
if (state->alarm_handled_minute == now.unit.minute) return retval;
state->alarm_handled_minute = now.unit.minute;
uint32_t new_now = watch_utility_date_time_to_unix_time(movement_get_utc_date_time(), movement_get_current_timezone_offset());
state->target_ts = watch_utility_offset_timestamp(new_now, state->hours, state->minutes, state->seconds);
state->now_ts = new_now;
- watch_date_time target_dt = watch_utility_date_time_from_unix_time(state->target_ts, movement_get_current_timezone_offset());
+ watch_date_time_t target_dt = watch_utility_date_time_from_unix_time(state->target_ts, movement_get_current_timezone_offset());
movement_schedule_background_task_for_face(state->watch_face_index, target_dt);
}
void countdown_face_activate(void *context) {
countdown_state_t *state = (countdown_state_t *)context;
if(state->mode == cd_running) {
- watch_date_time now = movement_get_utc_date_time();
+ watch_date_time_t now = movement_get_utc_date_time();
state->now_ts = watch_utility_date_time_to_unix_time(now, movement_get_current_timezone_offset());
watch_set_indicator(WATCH_INDICATOR_SIGNAL);
}
#endif
// distant future for background task: January 1, 2083
-static const watch_date_time distant_future = {
+static const watch_date_time_t distant_future = {
.unit = {0, 0, 0, 1, 1, 63}
};
static const uint8_t _location_count = sizeof(longLatPresets) / sizeof(long_lat_presets_t);
-static void _sunrise_sunset_set_expiration(sunrise_sunset_state_t *state, watch_date_time next_rise_set) {
+static void _sunrise_sunset_set_expiration(sunrise_sunset_state_t *state, watch_date_time_t next_rise_set) {
uint32_t timestamp = watch_utility_date_time_to_unix_time(next_rise_set, 0);
state->rise_set_expires = watch_utility_date_time_from_unix_time(timestamp + 60, 0);
}
return;
}
- watch_date_time date_time = movement_get_local_date_time(); // the current local date / time
- watch_date_time utc_now = watch_utility_date_time_convert_zone(date_time, movement_get_current_timezone_offset(), 0); // the current date / time in UTC
- watch_date_time scratch_time; // scratchpad, contains different values at different times
+ watch_date_time_t date_time = movement_get_local_date_time(); // the current local date / time
+ watch_date_time_t utc_now = watch_utility_date_time_convert_zone(date_time, movement_get_current_timezone_offset(), 0); // the current date / time in UTC
+ watch_date_time_t scratch_time; // scratchpad, contains different values at different times
scratch_time.reg = utc_now.reg;
// Weird quirky unsigned things were happening when I tried to cast these directly to doubles below.
double lon = (double)lon_centi / 100.0;
// sunriset returns the rise/set times as signed decimal hours in UTC.
- // this can mean hours below 0 or above 31, which won't fit into a watch_date_time struct.
- // to deal with this, we set aside the offset in hours, and add it back before converting it to a watch_date_time.
+ // this can mean hours below 0 or above 31, which won't fit into a watch_date_time_t struct.
+ // to deal with this, we set aside the offset in hours, and add it back before converting it to a watch_date_time_t.
double hours_from_utc = ((double)movement_get_current_timezone_offset()) / 3600.0;
// we loop twice because if it's after sunset today, we need to recalculate to display values for tomorrow.
// if entering low energy mode, start tick animation
if (event.event_type == EVENT_LOW_ENERGY_UPDATE && !watch_sleep_animation_is_running()) watch_start_sleep_animation(1000);
// check if we need to update the display
- watch_date_time date_time = movement_get_local_date_time();
+ watch_date_time_t date_time = movement_get_local_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;
uint8_t rise_index;
uint8_t active_digit;
bool location_changed;
- watch_date_time rise_set_expires;
+ watch_date_time_t rise_set_expires;
sunrise_sunset_lat_lon_settings_t working_latitude;
sunrise_sunset_lat_lon_settings_t working_longitude;
uint8_t longLatToUse;
bool voltage_face_loop(movement_event_t event, void *context) {
(void) context;
- watch_date_time date_time;
+ watch_date_time_t date_time;
switch (event.event_type) {
case EVENT_ACTIVATE:
_voltage_face_update_display();
static bool _quick_ticks_running;
static int32_t current_offset;
-static void _handle_alarm_button(watch_date_time date_time, uint8_t current_page) {
+static void _handle_alarm_button(watch_date_time_t date_time, uint8_t current_page) {
// handles short or long pressing of the alarm button
switch (current_page) {
bool set_time_face_loop(movement_event_t event, void *context) {
uint8_t current_page = *((uint8_t *)context);
- watch_date_time date_time = movement_get_local_date_time();
+ watch_date_time_t date_time = movement_get_local_date_time();
switch (event.event_type) {
case EVENT_TICK:
watch_i2c_write8(LIS2DW_ADDRESS, LIS2DW_REG_CTRL7, configuration | LIS2DW_CTRL7_VAL_INTERRUPTS_ENABLE);
}
-lis2dw_wakeup_source lis2dw_get_wakeup_source() {
- return (lis2dw_wakeup_source) watch_i2c_read8(LIS2DW_ADDRESS, LIS2DW_REG_WAKE_UP_SRC);
+lis2dw_wakeup_source_t lis2dw_get_wakeup_source() {
+ return (lis2dw_wakeup_source_t) watch_i2c_read8(LIS2DW_ADDRESS, LIS2DW_REG_WAKE_UP_SRC);
}
-lis2dw_interrupt_source lis2dw_get_interrupt_source(void) {
- return (lis2dw_interrupt_source) watch_i2c_read8(LIS2DW_ADDRESS, LIS2DW_REG_ALL_INT_SRC);
+lis2dw_interrupt_source_t lis2dw_get_interrupt_source(void) {
+ return (lis2dw_interrupt_source_t) watch_i2c_read8(LIS2DW_ADDRESS, LIS2DW_REG_ALL_INT_SRC);
}
LIS2DW_INTERRUPT_SRC_SINGLE_TAP = 0b00000100,
LIS2DW_INTERRUPT_SRC_WU = 0b00000010,
LIS2DW_INTERRUPT_SRC_FF = 0b00000001
-} lis2dw_interrupt_source;
+} lis2dw_interrupt_source_t;
typedef enum {
LIS2DW_WAKEUP_SRC_FREEFALL = 0b00100000,
LIS2DW_WAKEUP_SRC_WAKEUP_X = 0b00000100,
LIS2DW_WAKEUP_SRC_WAKEUP_Y = 0b00000010,
LIS2DW_WAKEUP_SRC_WAKEUP_Z = 0b00000001
-} lis2dw_wakeup_source;
+} lis2dw_wakeup_source_t;
// Assumes SA0 is high; if low, its 0x18
#define LIS2DW_ADDRESS (0x19)
void lis2dw_configure_wakeup_int1(uint8_t threshold, bool latch, bool active_state);
-lis2dw_interrupt_source lis2dw_get_interrupt_source(void);
+lis2dw_interrupt_source_t lis2dw_get_interrupt_source(void);
-lis2dw_wakeup_source lis2dw_get_wakeup_source(void);
+lis2dw_wakeup_source_t lis2dw_get_wakeup_source(void);
#endif // LIS2DW_H
#define WATCH_RTC_REFERENCE_YEAR (2020)
-#define watch_date_time rtc_date_time_t
+#define watch_date_time_t rtc_date_time_t
/** @brief Called by main.c to check if the RTC is enabled.
* You may call this function, but outside of app_init, it should always return true.
#include <math.h>
#include "watch_utility.h"
-const char * watch_utility_get_weekday(watch_date_time date_time) {
+const char * watch_utility_get_weekday(watch_date_time_t date_time) {
static const char weekdays[7][3] = {"MO", "TU", "WE", "TH", "FR", "SA", "SU"};
return weekdays[watch_utility_get_iso8601_weekday_number(date_time.unit.year + WATCH_RTC_REFERENCE_YEAR, date_time.unit.month, date_time.unit.day) - 1];
}
-const char * watch_utility_get_long_weekday(watch_date_time date_time) {
+const char * watch_utility_get_long_weekday(watch_date_time_t date_time) {
static const char weekdays[7][4] = {"Mon", "Tue", "Wed", "Thu", "Fri", "Sat", "Sun"};
return weekdays[watch_utility_get_iso8601_weekday_number(date_time.unit.year + WATCH_RTC_REFERENCE_YEAR, date_time.unit.month, date_time.unit.day) - 1];
}
return timestamp;
}
-uint32_t watch_utility_date_time_to_unix_time(watch_date_time date_time, int32_t utc_offset) {
+uint32_t watch_utility_date_time_to_unix_time(watch_date_time_t date_time, int32_t utc_offset) {
return watch_utility_convert_to_unix_time(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, utc_offset);
}
#define DAYS_PER_100Y (365*100 + 24)
#define DAYS_PER_4Y (365*4 + 1)
-watch_date_time watch_utility_date_time_from_unix_time(uint32_t timestamp, int32_t utc_offset) {
- watch_date_time retval;
+watch_date_time_t watch_utility_date_time_from_unix_time(uint32_t timestamp, int32_t utc_offset) {
+ watch_date_time_t retval;
retval.reg = 0;
int32_t days, secs;
int32_t remdays, remsecs, remyears;
return retval;
}
-watch_date_time watch_utility_date_time_convert_zone(watch_date_time date_time, uint32_t origin_utc_offset, uint32_t destination_utc_offset) {
+watch_date_time_t watch_utility_date_time_convert_zone(watch_date_time_t date_time, uint32_t origin_utc_offset, uint32_t destination_utc_offset) {
uint32_t timestamp = watch_utility_date_time_to_unix_time(date_time, origin_utc_offset);
return watch_utility_date_time_from_unix_time(timestamp, destination_utc_offset);
}
return retval;
}
-bool watch_utility_convert_to_12_hour(watch_date_time *date_time) {
+bool watch_utility_convert_to_12_hour(watch_date_time_t *date_time) {
bool is_pm = date_time->unit.hour > 11;
date_time->unit.hour %= 12;
if (date_time->unit.hour == 0) date_time->unit.hour = 12;
} watch_duration_t;
/** @brief Returns a two-letter weekday for the given timestamp, suitable for display in positions 0-1 of the watch face
- * @param date_time The watch_date_time whose weekday you want.
+ * @param date_time The watch_date_time_t whose weekday you want.
*/
-const char * watch_utility_get_weekday(watch_date_time date_time);
+const char * watch_utility_get_weekday(watch_date_time_t date_time);
/** @brief Returns a three-letter weekday for the given timestamp, suitable for display on the custom LCD
- * @param date_time The watch_date_time whose weekday you want.
+ * @param date_time The watch_date_time_t whose weekday you want.
*/
-const char * watch_utility_get_long_weekday(watch_date_time date_time);
+const char * watch_utility_get_long_weekday(watch_date_time_t date_time);
/** @brief Returns a number between 1-7 representing the weekday according to ISO8601 : week starts on Monday and has index 1, Sunday has index 7
* @param year The year of the date
uint8_t is_leap(uint16_t year);
/** @brief Returns the UNIX time (seconds since 1970) for a given date/time in UTC.
- * @param date_time The watch_date_time that you wish to convert.
+ * @param date_time The watch_date_time_t that you wish to convert.
* @param year The year of the date you wish to convert.
* @param month The month of the date you wish to convert.
* @param day The day of the date you wish to convert.
*/
uint32_t watch_utility_convert_to_unix_time(uint16_t year, uint8_t month, uint8_t day, uint8_t hour, uint8_t minute, uint8_t second, int32_t utc_offset);
-/** @brief Returns the UNIX time (seconds since 1970) for a given watch_date_time struct.
- * @param date_time The watch_date_time that you wish to convert.
+/** @brief Returns the UNIX time (seconds since 1970) for a given watch_date_time_t struct.
+ * @param date_time The watch_date_time_t that you wish to convert.
* @param utc_offset The number of seconds that date_time is offset from UTC, or 0 if the time is UTC.
- * @return A UNIX timestamp for the given watch_date_time and UTC offset.
+ * @return A UNIX timestamp for the given watch_date_time_t and UTC offset.
*/
-uint32_t watch_utility_date_time_to_unix_time(watch_date_time date_time, int32_t utc_offset);
+uint32_t watch_utility_date_time_to_unix_time(watch_date_time_t date_time, int32_t utc_offset);
/** @brief Converts a duration in seconds to a watch_duration_t struct.
* @param seconds A positive number of seconds that you wish to convert to a formatted duration.
*/
watch_duration_t watch_utility_seconds_to_duration(uint32_t seconds);
-/** @brief Returns a watch_date_time struct for a given UNIX time and UTC offset.
+/** @brief Returns a watch_date_time_t struct for a given UNIX time and UTC offset.
* @param timestamp The UNIX timestamp that you wish to convert.
* @param utc_offset The number of seconds that you wish date_time to be offset from UTC.
- * @return A watch_date_time for the given UNIX timestamp and UTC offset, or if outside the range that
- * watch_date_time can represent, a watch_date_time with all fields set to 0.
+ * @return A watch_date_time_t for the given UNIX timestamp and UTC offset, or if outside the range that
+ * watch_date_time_t can represent, a watch_date_time_t with all fields set to 0.
* @note Adapted from MIT-licensed code from musl, Copyright © 2005-2014 Rich Felker, et al.:
* https://github.com/esmil/musl/blob/1cc81f5cb0df2b66a795ff0c26d7bbc4d16e13c6/src/time/__secs_to_tm.c
*/
-watch_date_time watch_utility_date_time_from_unix_time(uint32_t timestamp, int32_t utc_offset);
+watch_date_time_t watch_utility_date_time_from_unix_time(uint32_t timestamp, int32_t utc_offset);
-/** @brief Converts a watch_date_time for 12-hour display.
- * @param date_time A pointer to the watch_date_time that you wish to convert for display. Note that this
+/** @brief Converts a watch_date_time_t for 12-hour display.
+ * @param date_time A pointer to the watch_date_time_t that you wish to convert for display. Note that this
* function will OVERWRITE the original date/time, rendering it invalid for date/time
* calculations. Midnight (hour 0) will become 12, and hours in the afternoon will wrap
* back around to values from 1-11.
* @return True if the value is in the afternoon. You can use this value to determine whether to set the
* PM indicator on the LCD.
- * @note This function sort of abuses the watch_date_time struct; the date/time that results from calling
+ * @note This function sort of abuses the watch_date_time_t struct; the date/time that results from calling
* this function is clamped to the hours of 1:00:00 AM through 12:59:59 PM. It no longer reflects a
- * valid watch_date_time for writing to an RTC register.
+ * valid watch_date_time_t for writing to an RTC register.
*/
-bool watch_utility_convert_to_12_hour(watch_date_time *date_time);
+bool watch_utility_convert_to_12_hour(watch_date_time_t *date_time);
/** @brief Converts a time from a given time zone to another time zone.
- * @param date_time The watch_date_time that you wish to convert
+ * @param date_time The watch_date_time_t that you wish to convert
* @param origin_utc_offset The number of seconds from UTC in the origin time zone
* @param destination_utc_offset The number of seconds from UTC in the destination time zone
- * @return A watch_date_time for the given UNIX timestamp and UTC offset, or if outside the range that
- * watch_date_time can represent, a watch_date_time with all fields set to 0.
+ * @return A watch_date_time_t for the given UNIX timestamp and UTC offset, or if outside the range that
+ * watch_date_time_t can represent, a watch_date_time_t with all fields set to 0.
* @note Adapted from MIT-licensed code from musl, Copyright © 2005-2014 Rich Felker, et al.:
* https://github.com/esmil/musl/blob/1cc81f5cb0df2b66a795ff0c26d7bbc4d16e13c6/src/time/__secs_to_tm.c
*/
-watch_date_time watch_utility_date_time_convert_zone(watch_date_time date_time, uint32_t origin_utc_offset, uint32_t destination_utc_offset);
+watch_date_time_t watch_utility_date_time_convert_zone(watch_date_time_t date_time, uint32_t origin_utc_offset, uint32_t destination_utc_offset);
/** @brief Returns a temperature in degrees Celsius for a given thermistor voltage divider circuit.
* @param value The raw analog reading from the thermistor pin (0-65535)
int _gettimeofday(struct timeval *tv, void *tzvp);
int _gettimeofday(struct timeval *tv, void *tzvp) {
(void)tzvp;
- watch_date_time date_time = watch_rtc_get_date_time();
+ watch_date_time_t date_time = watch_rtc_get_date_time();
// FIXME: this assumes the system time is UTC! Will break for any other time zone.
tv->tv_sec = watch_utility_date_time_to_unix_time(date_time, 0);
void _watch_rtc_init(void) {
}
-void watch_rtc_set_date_time(watch_date_time date_time) {
+void watch_rtc_set_date_time(watch_date_time_t date_time) {
time_offset = EM_ASM_DOUBLE({
const year = 2020 + (($0 >> 26) & 0x3f);
const month = ($0 >> 22) & 0xf;
}, date_time.reg);
}
-watch_date_time watch_rtc_get_date_time(void) {
- watch_date_time retval;
+watch_date_time_t watch_rtc_get_date_time(void) {
+ watch_date_time_t retval;
retval.reg = EM_ASM_INT({
const date = new Date(Date.now() + $0);
return date.getSeconds() |
alarm_interval_id = emscripten_set_interval(watch_invoke_alarm_interval_callback, alarm_interval, NULL);
}
-void watch_rtc_register_alarm_callback(ext_irq_cb_t callback, watch_date_time alarm_time, watch_rtc_alarm_match mask) {
+void watch_rtc_register_alarm_callback(ext_irq_cb_t callback, watch_date_time_t alarm_time, watch_rtc_alarm_match mask) {
watch_rtc_disable_alarm_callback();
switch (mask) {