don't wait for USB or BLE workflow after true deep sleep

This commit is contained in:
Dan Halbert 2022-02-17 15:24:31 -05:00
parent 16c44a4d50
commit 28714963d5
3 changed files with 31 additions and 15 deletions

30
main.c
View File

@ -301,7 +301,8 @@ STATIC void cleanup_after_vm(supervisor_allocation *heap, mp_obj_t exception) {
STATIC void print_code_py_status_message(safe_mode_t safe_mode) { STATIC void print_code_py_status_message(safe_mode_t safe_mode) {
if (autoreload_is_enabled()) { if (autoreload_is_enabled()) {
serial_write_compressed(translate("Auto-reload is on. Simply save files over USB to run them or enter REPL to disable.\n")); serial_write_compressed(
translate("Auto-reload is on. Simply save files over USB to run them or enter REPL to disable.\n"));
} else { } else {
serial_write_compressed(translate("Auto-reload is off.\n")); serial_write_compressed(translate("Auto-reload is off.\n"));
} }
@ -401,7 +402,8 @@ STATIC bool run_code_py(safe_mode_t safe_mode, bool first_run, bool *simulate_re
// the options because it can be treated like any other reason-for-stickiness bit. The // the options because it can be treated like any other reason-for-stickiness bit. The
// source is different though: it comes from the options that will apply to the next run, // source is different though: it comes from the options that will apply to the next run,
// while the rest of next_code_options is what applied to this run. // while the rest of next_code_options is what applied to this run.
if (next_code_allocation != NULL && (((next_code_info_t *)next_code_allocation->ptr)->options & SUPERVISOR_NEXT_CODE_OPT_NEWLY_SET)) { if (next_code_allocation != NULL &&
(((next_code_info_t *)next_code_allocation->ptr)->options & SUPERVISOR_NEXT_CODE_OPT_NEWLY_SET)) {
next_code_options |= SUPERVISOR_NEXT_CODE_OPT_NEWLY_SET; next_code_options |= SUPERVISOR_NEXT_CODE_OPT_NEWLY_SET;
} }
@ -527,9 +529,9 @@ STATIC bool run_code_py(safe_mode_t safe_mode, bool first_run, bool *simulate_re
// Sleep until our next interrupt. // Sleep until our next interrupt.
#if CIRCUITPY_ALARM #if CIRCUITPY_ALARM
if (result.return_code & PYEXEC_DEEP_SLEEP) { if (result.return_code & PYEXEC_DEEP_SLEEP) {
// Make sure we have been awake long enough for USB to connect (enumeration delay). const bool awoke_from_true_deep_sleep =
int64_t connecting_delay_ticks = CIRCUITPY_USB_CONNECTED_SLEEP_DELAY * 1024 - port_get_raw_ticks(NULL); common_hal_mcu_processor_get_reset_reason() == RESET_REASON_DEEP_SLEEP_ALARM;
// Until it's safe to decide whether we're real/fake sleeping
if (fake_sleeping) { if (fake_sleeping) {
// This waits until a pretend deep sleep alarm occurs. They are set // This waits until a pretend deep sleep alarm occurs. They are set
// during common_hal_alarm_set_deep_sleep_alarms. On some platforms // during common_hal_alarm_set_deep_sleep_alarms. On some platforms
@ -537,18 +539,28 @@ STATIC bool run_code_py(safe_mode_t safe_mode, bool first_run, bool *simulate_re
// for deep sleep alarms above. If it wasn't a deep sleep alarm, // for deep sleep alarms above. If it wasn't a deep sleep alarm,
// then we'll idle here again. // then we'll idle here again.
common_hal_alarm_pretending_deep_sleep(); common_hal_alarm_pretending_deep_sleep();
} else if (connecting_delay_ticks < 0) { }
// Entering deep sleep (may be fake or real.) // The first time we go into a deep sleep, make sure we have been awake long enough
// for USB to connect (enumeration delay), or for the BLE workflow to start.
// We wait CIRCUITPY_WORKFLOW_CONNECTION_SLEEP_DELAY seconds after a restart.
// But if we woke up from a real deep sleep, don't wait for connection. The user will need to
// do a hard reset to get out of the real deep sleep.
else if (awoke_from_true_deep_sleep ||
port_get_raw_ticks(NULL) > CIRCUITPY_WORKFLOW_CONNECTION_SLEEP_DELAY * 1024) {
// OK to start sleeping, real or fake.
status_led_deinit(); status_led_deinit();
deinit_rxtx_leds(); deinit_rxtx_leds();
board_deinit(); board_deinit();
if (!supervisor_workflow_active()) {
// Continue with true deep sleep even if workflow is available.
if (awoke_from_true_deep_sleep || !supervisor_workflow_active()) {
// Enter true deep sleep. When we wake up we'll be back at the // Enter true deep sleep. When we wake up we'll be back at the
// top of main(), not in this loop. // top of main(), not in this loop.
common_hal_alarm_enter_deep_sleep(); common_hal_alarm_enter_deep_sleep();
// Does not return. // Does not return.
} else { } else {
serial_write_compressed(translate("Pretending to deep sleep until alarm, CTRL-C or file write.\n")); serial_write_compressed(
translate("Pretending to deep sleep until alarm, CTRL-C or file write.\n"));
fake_sleeping = true; fake_sleeping = true;
} }
} else { } else {

View File

@ -447,9 +447,9 @@ void supervisor_run_background_tasks_if_tick(void);
#define CIRCUITPY_PYSTACK_SIZE 1536 #define CIRCUITPY_PYSTACK_SIZE 1536
#endif #endif
// Wait this long imediately after startup to see if we are connected to USB. // Wait this long before sleeping immediately after startup, to see if we are connected via USB or BLE.
#ifndef CIRCUITPY_USB_CONNECTED_SLEEP_DELAY #ifndef CIRCUITPY_WORKFLOW_CONNECTION_SLEEP_DELAY
#define CIRCUITPY_USB_CONNECTED_SLEEP_DELAY 5 #define CIRCUITPY_WORKFLOW_CONNECTION_SLEEP_DELAY 5
#endif #endif
#ifndef CIRCUITPY_PROCESSOR_COUNT #ifndef CIRCUITPY_PROCESSOR_COUNT

View File

@ -125,11 +125,15 @@ MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(alarm_light_sleep_until_alarms_obj, 1, MP_OB
//| //|
//| If no alarms are specified, the microcontroller will deep sleep until reset. //| If no alarms are specified, the microcontroller will deep sleep until reset.
//| //|
//| **If CircuitPython is connected to a host computer, the connection will be maintained, //| **If CircuitPython is connected to a host computer via USB or BLE
//| and the system will not go into deep sleep.** //| the first time a deep sleep is requested,
//| the connection will be maintained and the system will not go into deep sleep.**
//| This allows the user to interrupt an existing program with ctrl-C, //| This allows the user to interrupt an existing program with ctrl-C,
//| and to edit the files in CIRCUITPY, which would not be possible in true deep sleep. //| and to edit the files in CIRCUITPY, which would not be possible in true deep sleep.
//| Thus, to use deep sleep and save significant power, you will need to disconnect from the host. //|
//| If CircuitPython goes into a true deep sleep, and USB or BLE is reconnected,
//| the next deep sleep will still be a true deep sleep. You must do a hard reset
//| or power-cycle to exit a true deep sleep loop.
//| //|
//| Here is skeletal example that deep-sleeps and restarts every 60 seconds: //| Here is skeletal example that deep-sleeps and restarts every 60 seconds:
//| //|