Skip to content

Commit bfe2978

Browse files
authored
Merge pull request #5074 from tannewt/break_deep_sleep
Fix a couple fake sleep bugs on nrf and esp
2 parents afa4ddb + cdf978f commit bfe2978

File tree

6 files changed

+27
-55
lines changed

6 files changed

+27
-55
lines changed

lib/utils/pyexec.c

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -165,7 +165,12 @@ STATIC int parse_compile_execute(const void *source, mp_parse_input_kind_t input
165165
}
166166
if (result != NULL) {
167167
result->return_code = ret;
168+
#if CIRCUITPY_ALARM
169+
// Don't set the exception object if we exited for deep sleep.
170+
if (ret != 0 && ret != PYEXEC_DEEP_SLEEP) {
171+
#else
168172
if (ret != 0) {
173+
#endif
169174
mp_obj_t return_value = (mp_obj_t)nlr.ret_val;
170175
result->exception = return_value;
171176
result->exception_line = -1;

ports/esp32s2/common-hal/alarm/__init__.c

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,11 @@ void alarm_reset(void) {
6262
esp_sleep_disable_wakeup_source(ESP_SLEEP_WAKEUP_ALL);
6363
}
6464

65+
// This will be reset to false by full resets when bss is cleared. Otherwise, the
66+
// reload is due to CircuitPython and the ESP wakeup cause will be stale. This
67+
// can happen if USB is connected after a deep sleep.
68+
STATIC bool soft_wakeup = false;
69+
6570
STATIC esp_sleep_wakeup_cause_t _get_wakeup_cause(void) {
6671
// First check if the modules remember what last woke up
6772
if (alarm_pin_pinalarm_woke_this_cycle()) {
@@ -75,7 +80,11 @@ STATIC esp_sleep_wakeup_cause_t _get_wakeup_cause(void) {
7580
}
7681
// If waking from true deep sleep, modules will have lost their state,
7782
// so check the deep wakeup cause manually
78-
return esp_sleep_get_wakeup_cause();
83+
if (!soft_wakeup) {
84+
soft_wakeup = true;
85+
return esp_sleep_get_wakeup_cause();
86+
}
87+
return ESP_SLEEP_WAKEUP_UNDEFINED;
7988
}
8089

8190
bool common_hal_alarm_woken_from_sleep(void) {

ports/esp32s2/supervisor/usb.c

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@
2828
#include "py/runtime.h"
2929
#include "supervisor/usb.h"
3030
#include "supervisor/esp_port.h"
31+
#include "supervisor/port.h"
3132
#include "lib/utils/interrupt_char.h"
3233
#include "lib/mp-readline/readline.h"
3334

@@ -109,20 +110,21 @@ void init_usb_hardware(void) {
109110
usb_device_stack,
110111
&usb_device_taskdef);
111112
}
113+
112114
/**
113115
* Callback invoked when received an "wanted" char.
114116
* @param itf Interface index (for multiple cdc interfaces)
115117
* @param wanted_char The wanted char (set previously)
116118
*/
117119
void tud_cdc_rx_wanted_cb(uint8_t itf, char wanted_char) {
118120
(void)itf; // not used
121+
// CircuitPython's VM is run in a separate FreeRTOS task from TinyUSB.
122+
// So, we must notify the other task when a CTRL-C is received.
123+
port_wake_main_task();
119124
// Workaround for using lib/utils/interrupt_char.c
120125
// Compare mp_interrupt_char with wanted_char and ignore if not matched
121126
if (mp_interrupt_char == wanted_char) {
122127
tud_cdc_read_flush(); // flush read fifo
123128
mp_sched_keyboard_interrupt();
124-
// CircuitPython's VM is run in a separate FreeRTOS task from TinyUSB.
125-
// So, we must notify the other task when a CTRL-C is received.
126-
xTaskNotifyGive(circuitpython_task);
127129
}
128130
}

ports/nrf/common-hal/_bleio/Adapter.c

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -952,8 +952,11 @@ bool common_hal_bleio_adapter_is_bonded_to_central(bleio_adapter_obj_t *self) {
952952
}
953953

954954
void bleio_adapter_gc_collect(bleio_adapter_obj_t *adapter) {
955-
gc_collect_root((void **)adapter, sizeof(bleio_adapter_obj_t) / sizeof(size_t));
956-
gc_collect_root((void **)bleio_connections, sizeof(bleio_connections) / sizeof(size_t));
955+
// We divide by size_t so that we can scan each 32-bit aligned value to see
956+
// if it is a pointer. This allows us to change the structs without worrying
957+
// about collecting new pointers.
958+
gc_collect_root((void **)adapter, sizeof(bleio_adapter_obj_t) / (sizeof(size_t)));
959+
gc_collect_root((void **)bleio_connections, sizeof(bleio_connections) / (sizeof(size_t)));
957960
}
958961

959962
void bleio_adapter_reset(bleio_adapter_obj_t *adapter) {

ports/nrf/common-hal/alarm/__init__.c

Lines changed: 2 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -137,6 +137,8 @@ mp_obj_t common_hal_alarm_create_wake_alarm(void) {
137137

138138
// Set up light sleep or deep sleep alarms.
139139
STATIC void _setup_sleep_alarms(bool deep_sleep, size_t n_alarms, const mp_obj_t *alarms) {
140+
sleepmem_wakeup_event = SLEEPMEM_WAKEUP_BY_NONE;
141+
sleepmem_wakeup_pin = WAKEUP_PIN_UNDEF;
140142
alarm_pin_pinalarm_set_alarms(deep_sleep, n_alarms, alarms);
141143
alarm_time_timealarm_set_alarms(deep_sleep, n_alarms, alarms);
142144
alarm_touch_touchalarm_set_alarm(deep_sleep, n_alarms, alarms);
@@ -156,10 +158,6 @@ void system_on_idle_until_alarm(int64_t timediff_ms, uint32_t prescaler) {
156158

157159
if (timediff_ms != -1) {
158160
have_timeout = true;
159-
#if 0
160-
int64_t now = common_hal_time_monotonic_ms();
161-
dbg_printf("now_ms=%ld timediff_ms=%ld\r\n", (long)now, (long)timediff_ms);
162-
#endif
163161
if (timediff_ms < 0) {
164162
timediff_ms = 0;
165163
}
@@ -175,86 +173,46 @@ void system_on_idle_until_alarm(int64_t timediff_ms, uint32_t prescaler) {
175173
start_tick = port_get_raw_ticks(NULL);
176174
end_tick = start_tick + tickdiff;
177175
}
178-
#if 0
179-
dbg_printf("start_tick=%ld end_tick=%ld have_timeout=%c\r\n", (long)start_tick, (long)end_tick, have_timeout ? 'T' : 'F');
180-
#endif
181176

182177
int64_t remaining;
183-
sleepmem_wakeup_event = SLEEPMEM_WAKEUP_BY_NONE;
184-
sleepmem_wakeup_pin = WAKEUP_PIN_UNDEF;
185-
186-
#ifdef NRF_DEBUG_PRINT
187-
int ct = 40;
188-
char reason = '?';
189-
#define WAKEUP_REASON(x) reason = (x)
190-
#else
191-
#define WAKEUP_REASON(x)
192-
#endif
193-
194178
while (1) {
195179
if (mp_hal_is_interrupted()) {
196-
WAKEUP_REASON('I');
197180
break;
198181
}
199182
if (serial_connected() && serial_bytes_available()) {
200-
WAKEUP_REASON('S');
201183
break;
202184
}
203185
RUN_BACKGROUND_TASKS;
204186
if (common_hal_alarm_woken_from_sleep()) {
205-
WAKEUP_REASON('W');
206187
break;
207188
}
208189
if (have_timeout) {
209190
remaining = end_tick - port_get_raw_ticks(NULL);
210191
// We break a bit early so we don't risk setting the alarm before the time when we call
211192
// sleep.
212193
if (remaining < 1) {
213-
WAKEUP_REASON('t');
214194
break;
215195
}
216196
port_interrupt_after_ticks(remaining);
217197
}
218198
// Idle until an interrupt happens.
219199
port_idle_until_interrupt();
220-
#ifdef NRF_DEBUG_PRINT
221-
if (ct > 0) {
222-
mp_printf(&mp_plat_print, "_");
223-
--ct;
224-
}
225-
#endif
226200
if (have_timeout) {
227201
remaining = end_tick - port_get_raw_ticks(NULL);
228202
if (remaining <= 0) {
229203
sleepmem_wakeup_event = SLEEPMEM_WAKEUP_BY_TIMER;
230-
WAKEUP_REASON('T');
231204
break;
232205
}
233206
}
234207
}
235-
#ifdef NRF_DEBUG_PRINT
236-
mp_printf(&mp_plat_print, "%c\r\n", reason);
237-
#endif
238208

239209
#if defined(MICROPY_QSPI_CS)
240210
qspi_flash_exit_sleep();
241211
#endif
242-
243-
#ifdef NRF_DEBUG_PRINT
244-
tickdiff = port_get_raw_ticks(NULL) - start_tick;
245-
double sec;
246-
if (prescaler == 0) {
247-
sec = (double)tickdiff / 1024;
248-
} else {
249-
sec = (double)(tickdiff * prescaler) / 1024;
250-
}
251-
mp_printf(&mp_plat_print, "lapse %6.1f sec\r\n", sec);
252-
#endif
253212
}
254213

255214
mp_obj_t common_hal_alarm_light_sleep_until_alarms(size_t n_alarms, const mp_obj_t *alarms) {
256215
mp_obj_t wake_alarm = mp_const_none;
257-
alarm_time_timealarm_clear_wakeup_time();
258216
_setup_sleep_alarms(false, n_alarms, alarms);
259217

260218
#ifdef NRF_DEBUG_PRINT
@@ -290,7 +248,6 @@ mp_obj_t common_hal_alarm_light_sleep_until_alarms(size_t n_alarms, const mp_obj
290248
}
291249

292250
void common_hal_alarm_set_deep_sleep_alarms(size_t n_alarms, const mp_obj_t *alarms) {
293-
alarm_time_timealarm_clear_wakeup_time();
294251
_setup_sleep_alarms(true, n_alarms, alarms);
295252
}
296253

ports/nrf/common-hal/alarm/time/TimeAlarm.c

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -70,10 +70,6 @@ int64_t alarm_time_timealarm_get_wakeup_timediff_ms(void) {
7070
return wakeup_time_saved - common_hal_time_monotonic_ms();
7171
}
7272

73-
void alarm_time_timealarm_clear_wakeup_time(void) {
74-
wakeup_time_saved = 0;
75-
}
76-
7773
void alarm_time_timealarm_reset(void) {
7874
port_disable_interrupt_after_ticks_ch(1);
7975
wakeup_time_saved = 0;

0 commit comments

Comments
 (0)