@@ -56,7 +56,7 @@ STATIC mp_obj_t power_deep_sleep(size_t n_args, const mp_obj_t *pos_args, mp_map
56
56
static const mp_arg_t allowed_args [] = {
57
57
{ MP_QSTR_ms , MP_ARG_OBJ , {.u_rom_obj = MP_ROM_NONE } },
58
58
{ 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 } },
60
60
};
61
61
62
62
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
86
86
}
87
87
}
88
88
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
+ }
98
106
}
99
107
}
100
- }
101
108
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
+ }
104
119
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
+ }
107
134
108
135
return mp_const_none ;
109
136
}
0 commit comments