Skip to content

Commit cd8bbb8

Browse files
committed
codal_port/modpower: Make deep_sleep run run_every's in the background.
Addresses issue #118. Signed-off-by: Damien George <[email protected]>
1 parent 369d549 commit cd8bbb8

File tree

1 file changed

+42
-15
lines changed

1 file changed

+42
-15
lines changed

src/codal_port/modpower.c

Lines changed: 42 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -56,7 +56,7 @@ STATIC mp_obj_t power_deep_sleep(size_t n_args, const mp_obj_t *pos_args, mp_map
5656
static const mp_arg_t allowed_args[] = {
5757
{ MP_QSTR_ms, MP_ARG_OBJ, {.u_rom_obj = MP_ROM_NONE} },
5858
{ MP_QSTR_wake_on, MP_ARG_OBJ, {.u_rom_obj = MP_ROM_NONE} },
59-
{ MP_QSTR_run_every, MP_ARG_BOOL, {.u_bool = false} },
59+
{ MP_QSTR_run_every, MP_ARG_BOOL, {.u_bool = true} },
6060
};
6161

6262
mp_arg_val_t args[MP_ARRAY_SIZE(allowed_args)];
@@ -86,24 +86,51 @@ STATIC mp_obj_t power_deep_sleep(size_t n_args, const mp_obj_t *pos_args, mp_map
8686
}
8787
}
8888

89-
// If run_every is true then check if any soft timers will expire and need to wake the device.
90-
if (args[ARG_run_every].u_bool) {
91-
microbit_soft_timer_set_pause(true);
92-
uint32_t ms = microbit_soft_timer_get_ms_to_next_expiry();
93-
if (ms != UINT32_MAX) {
94-
// A soft timer will expire in "ms" milliseconds.
95-
wake_on_ms = true;
96-
if (ms < wake_ms) {
97-
wake_ms = ms;
89+
uint32_t start_ms = mp_hal_ticks_ms();
90+
uint32_t remain_ms = wake_ms;
91+
92+
for (;;) {
93+
bool wake = wake_on_ms;
94+
uint32_t ms = remain_ms;
95+
96+
// If run_every is true then check if any soft timers will expire and need to wake the device.
97+
if (args[ARG_run_every].u_bool) {
98+
microbit_soft_timer_set_pause(true);
99+
uint32_t soft_timer_ms = microbit_soft_timer_get_ms_to_next_expiry();
100+
if (soft_timer_ms != UINT32_MAX) {
101+
// A soft timer will expire in "ms" milliseconds.
102+
wake = true;
103+
if (soft_timer_ms < ms) {
104+
ms = soft_timer_ms;
105+
}
98106
}
99107
}
100-
}
101108

102-
// Enter low power state.
103-
microbit_hal_power_deep_sleep(wake_on_ms, wake_ms);
109+
// Enter low power state.
110+
bool interrupted = microbit_hal_power_deep_sleep(wake, ms);
111+
112+
// Resume soft timer (doesn't hurt to resume even if it wasn't paused).
113+
microbit_soft_timer_set_pause(false);
114+
115+
// Run all outstanding scheduled functions.
116+
while (MP_STATE_VM(sched_state) == MP_SCHED_PENDING) {
117+
mp_handle_pending(true);
118+
}
104119

105-
// Resume soft timer (doesn't hurt to resume even if it wasn't paused).
106-
microbit_soft_timer_set_pause(false);
120+
if (interrupted) {
121+
// A wake-up source interrupted the deep-sleep, so finish.
122+
break;
123+
}
124+
125+
if (wake_on_ms) {
126+
uint32_t dt = mp_hal_ticks_ms() - start_ms;
127+
if (dt >= wake_ms) {
128+
// User supplied timeout has expired.
129+
break;
130+
}
131+
remain_ms = wake_ms - dt;
132+
}
133+
}
107134

108135
return mp_const_none;
109136
}

0 commit comments

Comments
 (0)