Skip to content

Sleep API changes and fix for main.c silent issue #4503

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Apr 6, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
33 changes: 15 additions & 18 deletions main.c
Original file line number Diff line number Diff line change
Expand Up @@ -161,7 +161,7 @@ STATIC void start_mp(supervisor_allocation* heap) {

#if CIRCUITPY_ALARM
// Record which alarm woke us up, if any. An object may be created so the heap must be functional.
alarm_save_wake_alarm();
shared_alarm_save_wake_alarm();
// Reset alarm module only after we retrieved the wakeup alarm.
alarm_reset();
#endif
Expand Down Expand Up @@ -305,8 +305,6 @@ STATIC bool run_code_py(safe_mode_t safe_mode) {
}
#endif

// TODO: on deep sleep, make sure display is refreshed before sleeping (for e-ink).

cleanup_after_vm(heap);

if (result.return_code & PYEXEC_FORCED_EXIT) {
Expand All @@ -329,12 +327,12 @@ STATIC bool run_code_py(safe_mode_t safe_mode) {

rgb_status_animation_t animation;
prep_rgb_status_animation(&result, found_main, safe_mode, &animation);
bool asleep = false;
bool fake_sleeping = false;
while (true) {
RUN_BACKGROUND_TASKS;
if (reload_requested) {
#if CIRCUITPY_ALARM
if (asleep) {
if (fake_sleeping) {
board_init();
}
#endif
Expand All @@ -345,7 +343,7 @@ STATIC bool run_code_py(safe_mode_t safe_mode) {

if (serial_connected() && serial_bytes_available()) {
#if CIRCUITPY_ALARM
if (asleep) {
if (fake_sleeping) {
board_init();
}
#endif
Expand All @@ -361,7 +359,7 @@ STATIC bool run_code_py(safe_mode_t safe_mode) {
// an alarm alerts faster than our USB delay or if we pretended to deep
// sleep.
#if CIRCUITPY_ALARM
if (asleep && alarm_woken_from_sleep()) {
if (fake_sleeping && common_hal_alarm_woken_from_sleep()) {
serial_write_compressed(translate("Woken up by alarm.\n"));
board_init();
supervisor_set_run_reason(RUN_REASON_STARTUP);
Expand Down Expand Up @@ -400,20 +398,15 @@ STATIC bool run_code_py(safe_mode_t safe_mode) {
if (result.return_code & PYEXEC_DEEP_SLEEP) {
// Make sure we have been awake long enough for USB to connect (enumeration delay).
int64_t connecting_delay_ticks = CIRCUITPY_USB_CONNECTED_SLEEP_DELAY * 1024 - port_get_raw_ticks(NULL);
if (connecting_delay_ticks > 0) {
// Set when we've waited long enough so that we wake up from the
// port_idle_until_interrupt below and loop around to the real deep
// sleep in the else clause.
port_interrupt_after_ticks(connecting_delay_ticks);
// Deep sleep if we're not connected to a host.
} else if (!asleep) {
asleep = true;
// Until it's safe to decide whether we're real/fake sleeping, just run the RGB
if (connecting_delay_ticks < 0 && !fake_sleeping) {
fake_sleeping = true;
new_status_color(BLACK);
board_deinit();
if (!supervisor_workflow_active()) {
// Enter true deep sleep. When we wake up we'll be back at the
// top of main(), not in this loop.
alarm_enter_deep_sleep();
common_hal_alarm_enter_deep_sleep();
// Does not return.
} else {
serial_write_compressed(translate("Pretending to deep sleep until alarm, CTRL-C or file write.\n"));
Expand All @@ -422,15 +415,19 @@ STATIC bool run_code_py(safe_mode_t safe_mode) {
}
#endif

if (!asleep) {
if (!fake_sleeping) {
tick_rgb_status_animation(&animation);
} else {
// This waits until a pretend deep sleep alarm occurs. They are set
// during common_hal_alarm_set_deep_sleep_alarms. On some platforms
// it may also return due to another interrupt, that's why we check
// for deep sleep alarms above. If it wasn't a deep sleep alarm,
// then we'll idle here again.
port_idle_until_interrupt();
#if CIRCUITPY_ALARM
common_hal_alarm_pretending_deep_sleep();
#else
port_idle_until_interrupt();
#endif
}
}
}
Expand Down
10 changes: 5 additions & 5 deletions ports/esp32s2/common-hal/alarm/__init__.c
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,7 @@ STATIC esp_sleep_wakeup_cause_t _get_wakeup_cause(void) {
return esp_sleep_get_wakeup_cause();
}

bool alarm_woken_from_sleep(void) {
bool common_hal_alarm_woken_from_sleep(void) {
return _get_wakeup_cause() != ESP_SLEEP_WAKEUP_UNDEFINED;
}

Expand Down Expand Up @@ -120,8 +120,8 @@ STATIC void _idle_until_alarm(void) {
while (!mp_hal_is_interrupted()) {
RUN_BACKGROUND_TASKS;
// Allow ctrl-C interrupt.
if (alarm_woken_from_sleep()) {
alarm_save_wake_alarm();
if (common_hal_alarm_woken_from_sleep()) {
shared_alarm_save_wake_alarm();
return;
}
port_idle_until_interrupt();
Expand All @@ -147,7 +147,7 @@ void common_hal_alarm_set_deep_sleep_alarms(size_t n_alarms, const mp_obj_t *ala
_setup_sleep_alarms(true, n_alarms, alarms);
}

void NORETURN alarm_enter_deep_sleep(void) {
void NORETURN common_hal_alarm_enter_deep_sleep(void) {
alarm_pin_pinalarm_prepare_for_deep_sleep();
alarm_touch_touchalarm_prepare_for_deep_sleep();

Expand All @@ -164,5 +164,5 @@ void NORETURN alarm_enter_deep_sleep(void) {
}

void common_hal_alarm_gc_collect(void) {
gc_collect_ptr(alarm_get_wake_alarm());
gc_collect_ptr(shared_alarm_get_wake_alarm());
}
37 changes: 0 additions & 37 deletions ports/esp32s2/common-hal/alarm/pin/__init__.c

This file was deleted.

11 changes: 8 additions & 3 deletions shared-bindings/alarm/__init__.c
Original file line number Diff line number Diff line change
Expand Up @@ -92,7 +92,7 @@ void validate_objs_are_alarms(size_t n_args, const mp_obj_t *objs) {
//| 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 light sleep.
//| Thus, to use light sleep and save significant power,
// it may be necessary to disconnect from the host.
//| it may be necessary to disconnect from the host.
//| """
//| ...
//|
Expand Down Expand Up @@ -217,7 +217,7 @@ STATIC mp_map_elem_t alarm_module_globals_table[] = {
STATIC MP_DEFINE_MUTABLE_DICT(alarm_module_globals, alarm_module_globals_table);

// Fetch value from module dict.
mp_obj_t alarm_get_wake_alarm(void) {
mp_obj_t shared_alarm_get_wake_alarm(void) {
mp_map_elem_t *elem =
mp_map_lookup(&alarm_module_globals.map, MP_ROM_QSTR(MP_QSTR_wake_alarm), MP_MAP_LOOKUP);
if (elem) {
Expand All @@ -228,7 +228,7 @@ mp_obj_t alarm_get_wake_alarm(void) {
}

// Initialize .wake_alarm value.
void alarm_save_wake_alarm(void) {
void shared_alarm_save_wake_alarm(void) {
// Equivalent of:
// alarm.wake_alarm = alarm
mp_map_elem_t *elem =
Expand All @@ -242,3 +242,8 @@ const mp_obj_module_t alarm_module = {
.base = { &mp_type_module },
.globals = (mp_obj_dict_t *)&alarm_module_globals,
};

extern void port_idle_until_interrupt(void);
MP_WEAK void common_hal_alarm_pretending_deep_sleep(void) {
port_idle_until_interrupt();
}
13 changes: 6 additions & 7 deletions shared-bindings/alarm/__init__.h
Original file line number Diff line number Diff line change
Expand Up @@ -40,21 +40,20 @@ extern mp_obj_t common_hal_alarm_light_sleep_until_alarms(size_t n_alarms, const
// call alarm_woken_from_sleep to see if we've been woken by an alarm and if so,
// it will exit idle as if deep sleep was exited.
extern void common_hal_alarm_set_deep_sleep_alarms(size_t n_alarms, const mp_obj_t *alarms);
// Deep sleep is entered outside of the VM so we omit the `common_hal_` prefix.
extern NORETURN void alarm_enter_deep_sleep(void);

extern NORETURN void common_hal_alarm_enter_deep_sleep(void);
extern void common_hal_alarm_pretending_deep_sleep(void);

// Fetches value from module dict.
extern mp_obj_t alarm_get_wake_alarm(void);
extern mp_obj_t shared_alarm_get_wake_alarm(void);

extern void common_hal_alarm_gc_collect(void);
extern mp_obj_t common_hal_alarm_get_wake_alarm(void);

// Used by wake-up code.
void alarm_save_wake_alarm(void);

void shared_alarm_save_wake_alarm(void);

// True if an alarm is alerting. This is most useful for pretend deep sleep.
extern bool alarm_woken_from_sleep(void);

extern bool common_hal_alarm_woken_from_sleep(void);

#endif // MICROPY_INCLUDED_SHARED_BINDINGS_ALARM___INIT___H