mirror of
https://github.com/firewalkwithm3/Sensor-Watch.git
synced 2024-11-22 19:20:30 +08:00
movement: first crack at background tasks API
This commit is contained in:
parent
ee1b3c8780
commit
8475ffcd7a
|
@ -23,6 +23,18 @@ static inline void _movement_reset_inactivity_countdown() {
|
|||
movement_state.timeout_ticks = movement_timeout_inactivity_deadlines[movement_state.settings.bit.to_interval];
|
||||
}
|
||||
|
||||
void _movement_handle_background_tasks() {
|
||||
for(uint8_t i = 0; i < MOVEMENT_NUM_FACES; i++) {
|
||||
// For each face, if the watch face wants a background task...
|
||||
if (watch_faces[i].wants_background_task != NULL && watch_faces[i].wants_background_task(&movement_state.settings, watch_face_contexts[i])) {
|
||||
// ...we give it one. pretty straightforward!
|
||||
movement_event_t background_event = { EVENT_BACKGROUND_TASK, 0 };
|
||||
watch_faces[i].loop(background_event, &movement_state.settings, watch_face_contexts[i]);
|
||||
}
|
||||
}
|
||||
movement_state.needs_background_tasks_handled = false;
|
||||
}
|
||||
|
||||
void movement_request_tick_frequency(uint8_t freq) {
|
||||
watch_rtc_disable_all_periodic_callbacks();
|
||||
movement_state.subsecond = 0;
|
||||
|
@ -68,10 +80,15 @@ void app_setup() {
|
|||
watch_face_contexts[i] = NULL;
|
||||
is_first_launch = false;
|
||||
}
|
||||
|
||||
// set up the 1 minute alarm (for background tasks and low power updates)
|
||||
watch_date_time 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);
|
||||
}
|
||||
if (movement_state.le_mode_ticks != -1) {
|
||||
watch_disable_extwake_interrupt(BTN_ALARM);
|
||||
watch_rtc_disable_alarm_callback();
|
||||
|
||||
watch_enable_external_interrupts();
|
||||
watch_register_interrupt_callback(BTN_MODE, cb_mode_btn_interrupt, INTERRUPT_TRIGGER_BOTH);
|
||||
|
@ -131,13 +148,12 @@ bool app_loop() {
|
|||
event.event_type = EVENT_TIMEOUT;
|
||||
}
|
||||
|
||||
// handle background tasks, if the alarm handler told us we need to
|
||||
if (movement_state.needs_background_tasks_handled) _movement_handle_background_tasks();
|
||||
|
||||
// if we have timed out of our low energy mode countdown, enter low energy mode.
|
||||
if (movement_state.le_mode_ticks == 0) {
|
||||
movement_state.le_mode_ticks = -1;
|
||||
watch_date_time 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);
|
||||
watch_register_extwake_callback(BTN_ALARM, cb_alarm_btn_extwake, true);
|
||||
event.event_type = EVENT_NONE;
|
||||
event.subsecond = 0;
|
||||
|
@ -145,6 +161,9 @@ bool app_loop() {
|
|||
// this is a little mini-runloop.
|
||||
// as long as le_mode_ticks is -1 (i.e. we are in low energy mode), we wake up here, update the screen, and go right back to sleep.
|
||||
while (movement_state.le_mode_ticks == -1) {
|
||||
// we also have to handle background tasks here in the mini-runloop
|
||||
if (movement_state.needs_background_tasks_handled) _movement_handle_background_tasks();
|
||||
|
||||
event.event_type = EVENT_LOW_ENERGY_UPDATE;
|
||||
watch_faces[movement_state.current_watch_face].loop(event, &movement_state.settings, watch_face_contexts[movement_state.current_watch_face]);
|
||||
watch_enter_sleep_mode();
|
||||
|
@ -202,7 +221,7 @@ void cb_alarm_btn_extwake() {
|
|||
}
|
||||
|
||||
void cb_alarm_fired() {
|
||||
event.event_type = EVENT_LOW_ENERGY_UPDATE;
|
||||
movement_state.needs_background_tasks_handled = true;
|
||||
}
|
||||
|
||||
void cb_tick() {
|
||||
|
|
|
@ -167,6 +167,9 @@ typedef struct {
|
|||
uint8_t mode_down_timestamp;
|
||||
uint8_t alarm_down_timestamp;
|
||||
|
||||
// background task handling
|
||||
bool needs_background_tasks_handled;
|
||||
|
||||
// low energy mode countdown
|
||||
int32_t le_mode_ticks;
|
||||
|
||||
|
|
|
@ -63,7 +63,6 @@ void thermistor_logging_face_activate(movement_settings_t *settings, void *conte
|
|||
|
||||
bool thermistor_logging_face_loop(movement_event_t event, movement_settings_t *settings, void *context) {
|
||||
thermistor_logger_state_t *logger_state = (thermistor_logger_state_t *)context;
|
||||
watch_date_time date_time = watch_rtc_get_date_time();
|
||||
switch (event.event_type) {
|
||||
case EVENT_TIMEOUT:
|
||||
movement_move_to_face(0);
|
||||
|
@ -90,11 +89,9 @@ bool thermistor_logging_face_loop(movement_event_t event, movement_settings_t *s
|
|||
if (logger_state->ts_ticks && --logger_state->ts_ticks == 0) {
|
||||
_thermistor_logging_face_update_display(logger_state, settings->bit.use_imperial_units, settings->bit.clock_mode_24h);
|
||||
}
|
||||
// this is just temporary for testing: log a data point every 30 seconds.
|
||||
if (date_time.unit.second % 30 == 0 && !logger_state->ts_ticks) {
|
||||
_thermistor_logging_face_log_data(logger_state);
|
||||
_thermistor_logging_face_update_display(logger_state, settings->bit.use_imperial_units, settings->bit.clock_mode_24h);
|
||||
}
|
||||
break;
|
||||
case EVENT_BACKGROUND_TASK:
|
||||
_thermistor_logging_face_log_data(logger_state);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
|
@ -107,3 +104,11 @@ void thermistor_logging_face_resign(movement_settings_t *settings, void *context
|
|||
(void) settings;
|
||||
(void) context;
|
||||
}
|
||||
|
||||
bool thermistor_logging_face_wants_background_task(movement_settings_t *settings, void *context) {
|
||||
(void) 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;
|
||||
}
|
||||
|
|
|
@ -22,13 +22,14 @@ void thermistor_logging_face_setup(movement_settings_t *settings, void ** contex
|
|||
void thermistor_logging_face_activate(movement_settings_t *settings, void *context);
|
||||
bool thermistor_logging_face_loop(movement_event_t event, movement_settings_t *settings, void *context);
|
||||
void thermistor_logging_face_resign(movement_settings_t *settings, void *context);
|
||||
bool thermistor_logging_face_wants_background_task(movement_settings_t *settings, void *context);
|
||||
|
||||
static const watch_face_t thermistor_logging_face = {
|
||||
thermistor_logging_face_setup,
|
||||
thermistor_logging_face_activate,
|
||||
thermistor_logging_face_loop,
|
||||
thermistor_logging_face_resign,
|
||||
NULL
|
||||
thermistor_logging_face_wants_background_task
|
||||
};
|
||||
|
||||
#endif // THERMISTOR_LOGGING_FACE_H_
|
||||
|
|
Loading…
Reference in a new issue