@@ -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