Skip to content

Commit c9a65af

Browse files
authored
Merge pull request #6051 from dhalbert/deep-sleep-usb-delays
don't wait for USB or BLE workflow after true deep sleep
2 parents fe6e03f + 2871496 commit c9a65af

File tree

3 files changed

+31
-15
lines changed

3 files changed

+31
-15
lines changed

main.c

Lines changed: 21 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -301,7 +301,8 @@ STATIC void cleanup_after_vm(supervisor_allocation *heap, mp_obj_t exception) {
301301

302302
STATIC void print_code_py_status_message(safe_mode_t safe_mode) {
303303
if (autoreload_is_enabled()) {
304-
serial_write_compressed(translate("Auto-reload is on. Simply save files over USB to run them or enter REPL to disable.\n"));
304+
serial_write_compressed(
305+
translate("Auto-reload is on. Simply save files over USB to run them or enter REPL to disable.\n"));
305306
} else {
306307
serial_write_compressed(translate("Auto-reload is off.\n"));
307308
}
@@ -401,7 +402,8 @@ STATIC bool run_code_py(safe_mode_t safe_mode, bool first_run, bool *simulate_re
401402
// the options because it can be treated like any other reason-for-stickiness bit. The
402403
// source is different though: it comes from the options that will apply to the next run,
403404
// while the rest of next_code_options is what applied to this run.
404-
if (next_code_allocation != NULL && (((next_code_info_t *)next_code_allocation->ptr)->options & SUPERVISOR_NEXT_CODE_OPT_NEWLY_SET)) {
405+
if (next_code_allocation != NULL &&
406+
(((next_code_info_t *)next_code_allocation->ptr)->options & SUPERVISOR_NEXT_CODE_OPT_NEWLY_SET)) {
405407
next_code_options |= SUPERVISOR_NEXT_CODE_OPT_NEWLY_SET;
406408
}
407409

@@ -527,28 +529,38 @@ STATIC bool run_code_py(safe_mode_t safe_mode, bool first_run, bool *simulate_re
527529
// Sleep until our next interrupt.
528530
#if CIRCUITPY_ALARM
529531
if (result.return_code & PYEXEC_DEEP_SLEEP) {
530-
// Make sure we have been awake long enough for USB to connect (enumeration delay).
531-
int64_t connecting_delay_ticks = CIRCUITPY_USB_CONNECTED_SLEEP_DELAY * 1024 - port_get_raw_ticks(NULL);
532-
// Until it's safe to decide whether we're real/fake sleeping
532+
const bool awoke_from_true_deep_sleep =
533+
common_hal_mcu_processor_get_reset_reason() == RESET_REASON_DEEP_SLEEP_ALARM;
534+
533535
if (fake_sleeping) {
534536
// This waits until a pretend deep sleep alarm occurs. They are set
535537
// during common_hal_alarm_set_deep_sleep_alarms. On some platforms
536538
// it may also return due to another interrupt, that's why we check
537539
// for deep sleep alarms above. If it wasn't a deep sleep alarm,
538540
// then we'll idle here again.
539541
common_hal_alarm_pretending_deep_sleep();
540-
} else if (connecting_delay_ticks < 0) {
541-
// Entering deep sleep (may be fake or real.)
542+
}
543+
// The first time we go into a deep sleep, make sure we have been awake long enough
544+
// for USB to connect (enumeration delay), or for the BLE workflow to start.
545+
// We wait CIRCUITPY_WORKFLOW_CONNECTION_SLEEP_DELAY seconds after a restart.
546+
// But if we woke up from a real deep sleep, don't wait for connection. The user will need to
547+
// do a hard reset to get out of the real deep sleep.
548+
else if (awoke_from_true_deep_sleep ||
549+
port_get_raw_ticks(NULL) > CIRCUITPY_WORKFLOW_CONNECTION_SLEEP_DELAY * 1024) {
550+
// OK to start sleeping, real or fake.
542551
status_led_deinit();
543552
deinit_rxtx_leds();
544553
board_deinit();
545-
if (!supervisor_workflow_active()) {
554+
555+
// Continue with true deep sleep even if workflow is available.
556+
if (awoke_from_true_deep_sleep || !supervisor_workflow_active()) {
546557
// Enter true deep sleep. When we wake up we'll be back at the
547558
// top of main(), not in this loop.
548559
common_hal_alarm_enter_deep_sleep();
549560
// Does not return.
550561
} else {
551-
serial_write_compressed(translate("Pretending to deep sleep until alarm, CTRL-C or file write.\n"));
562+
serial_write_compressed(
563+
translate("Pretending to deep sleep until alarm, CTRL-C or file write.\n"));
552564
fake_sleeping = true;
553565
}
554566
} else {

py/circuitpy_mpconfig.h

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -447,9 +447,9 @@ void supervisor_run_background_tasks_if_tick(void);
447447
#define CIRCUITPY_PYSTACK_SIZE 1536
448448
#endif
449449

450-
// Wait this long imediately after startup to see if we are connected to USB.
451-
#ifndef CIRCUITPY_USB_CONNECTED_SLEEP_DELAY
452-
#define CIRCUITPY_USB_CONNECTED_SLEEP_DELAY 5
450+
// Wait this long before sleeping immediately after startup, to see if we are connected via USB or BLE.
451+
#ifndef CIRCUITPY_WORKFLOW_CONNECTION_SLEEP_DELAY
452+
#define CIRCUITPY_WORKFLOW_CONNECTION_SLEEP_DELAY 5
453453
#endif
454454

455455
#ifndef CIRCUITPY_PROCESSOR_COUNT

shared-bindings/alarm/__init__.c

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -125,11 +125,15 @@ MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(alarm_light_sleep_until_alarms_obj, 1, MP_OB
125125
//|
126126
//| If no alarms are specified, the microcontroller will deep sleep until reset.
127127
//|
128-
//| **If CircuitPython is connected to a host computer, the connection will be maintained,
129-
//| and the system will not go into deep sleep.**
128+
//| **If CircuitPython is connected to a host computer via USB or BLE
129+
//| the first time a deep sleep is requested,
130+
//| the connection will be maintained and the system will not go into deep sleep.**
130131
//| This allows the user to interrupt an existing program with ctrl-C,
131132
//| and to edit the files in CIRCUITPY, which would not be possible in true deep sleep.
132-
//| Thus, to use deep sleep and save significant power, you will need to disconnect from the host.
133+
//|
134+
//| If CircuitPython goes into a true deep sleep, and USB or BLE is reconnected,
135+
//| the next deep sleep will still be a true deep sleep. You must do a hard reset
136+
//| or power-cycle to exit a true deep sleep loop.
133137
//|
134138
//| Here is skeletal example that deep-sleeps and restarts every 60 seconds:
135139
//|

0 commit comments

Comments
 (0)