Skip to content

Commit 9d5ae2e

Browse files
authored
Merge pull request #5762 from dhalbert/stale-wakeup-reasons
Fix recording of wake_alarm
2 parents c27c615 + 3bb9a44 commit 9d5ae2e

File tree

4 files changed

+36
-29
lines changed

4 files changed

+36
-29
lines changed

locale/circuitpython.pot

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -574,7 +574,7 @@ msgstr ""
574574

575575
#: shared-bindings/displayio/Display.c
576576
#: shared-bindings/framebufferio/FramebufferDisplay.c
577-
#: shared-bindings/is31fl3741/is31fl3741.c
577+
#: shared-bindings/is31fl3741/IS31FL3741.c
578578
#: shared-bindings/rgbmatrix/RGBMatrix.c
579579
msgid "Brightness must be 0-1.0"
580580
msgstr ""
@@ -1462,7 +1462,7 @@ msgstr ""
14621462
msgid "Key must be 16, 24, or 32 bytes long"
14631463
msgstr ""
14641464

1465-
#: shared-module/is31fl3741/is31fl3741.c
1465+
#: shared-module/is31fl3741/IS31FL3741.c
14661466
msgid "LED mappings must match display size"
14671467
msgstr ""
14681468

@@ -2090,7 +2090,7 @@ msgstr ""
20902090
msgid "Sample rate too high. It must be less than %d"
20912091
msgstr ""
20922092

2093-
#: shared-bindings/is31fl3741/is31fl3741.c
2093+
#: shared-bindings/is31fl3741/IS31FL3741.c
20942094
msgid "Scale dimensions must divide by 3"
20952095
msgstr ""
20962096

@@ -2351,7 +2351,7 @@ msgstr ""
23512351
msgid "Unable to create lock"
23522352
msgstr ""
23532353

2354-
#: shared-module/displayio/I2CDisplay.c shared-module/is31fl3741/is31fl3741.c
2354+
#: shared-module/displayio/I2CDisplay.c shared-module/is31fl3741/IS31FL3741.c
23552355
#, c-format
23562356
msgid "Unable to find I2C Display at %x"
23572357
msgstr ""
@@ -3950,6 +3950,7 @@ msgstr ""
39503950
#: ports/espressif/boards/adafruit_funhouse/mpconfigboard.h
39513951
#: ports/espressif/boards/adafruit_magtag_2.9_grayscale/mpconfigboard.h
39523952
#: ports/espressif/boards/adafruit_metro_esp32s2/mpconfigboard.h
3953+
#: ports/espressif/boards/adafruit_qtpy_esp32s2/mpconfigboard.h
39533954
#: ports/espressif/boards/ai_thinker_esp32-c3s/mpconfigboard.h
39543955
#: ports/espressif/boards/ai_thinker_esp_12k_nodemcu/mpconfigboard.h
39553956
#: ports/espressif/boards/artisense_rd00/mpconfigboard.h
@@ -4462,7 +4463,7 @@ msgstr ""
44624463
msgid "width must be from 2 to 8 (inclusive), not %d"
44634464
msgstr ""
44644465

4465-
#: shared-bindings/is31fl3741/is31fl3741.c
4466+
#: shared-bindings/is31fl3741/IS31FL3741.c
44664467
#: shared-bindings/rgbmatrix/RGBMatrix.c
44674468
msgid "width must be greater than zero"
44684469
msgstr ""

main.c

Lines changed: 22 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -122,7 +122,7 @@ static void reset_devices(void) {
122122
#endif
123123
}
124124

125-
STATIC void start_mp(supervisor_allocation *heap) {
125+
STATIC void start_mp(supervisor_allocation *heap, bool first_run) {
126126
autoreload_stop();
127127
supervisor_workflow_reset();
128128

@@ -170,7 +170,8 @@ STATIC void start_mp(supervisor_allocation *heap) {
170170

171171
#if CIRCUITPY_ALARM
172172
// Record which alarm woke us up, if any. An object may be created so the heap must be functional.
173-
shared_alarm_save_wake_alarm(common_hal_alarm_create_wake_alarm());
173+
// There is no alarm if this is not the first time code.py or the REPL has been run.
174+
shared_alarm_save_wake_alarm(first_run ? common_hal_alarm_create_wake_alarm() : mp_const_none);
174175
// Reset alarm module only after we retrieved the wakeup alarm.
175176
alarm_reset();
176177
#endif
@@ -308,7 +309,7 @@ STATIC void print_code_py_status_message(safe_mode_t safe_mode) {
308309
}
309310
}
310311

311-
STATIC bool run_code_py(safe_mode_t safe_mode) {
312+
STATIC bool run_code_py(safe_mode_t safe_mode, bool first_run, bool *simulate_reset) {
312313
bool serial_connected_at_start = serial_connected();
313314
bool printed_safe_mode_message = false;
314315
#if CIRCUITPY_AUTORELOAD_DELAY_MS > 0
@@ -347,7 +348,7 @@ STATIC bool run_code_py(safe_mode_t safe_mode) {
347348
supervisor_allocation *heap = allocate_remaining_memory();
348349

349350
// Prepare the VM state. Includes an alarm check/reset for sleep.
350-
start_mp(heap);
351+
start_mp(heap, first_run);
351352

352353
#if CIRCUITPY_USB
353354
usb_setup_with_vm();
@@ -630,6 +631,8 @@ STATIC bool run_code_py(safe_mode_t safe_mode) {
630631
#if CIRCUITPY_ALARM
631632
if (fake_sleeping) {
632633
board_init();
634+
// Pretend that the next run is the first run, as if we were reset.
635+
*simulate_reset = true;
633636
}
634637
#endif
635638

@@ -651,7 +654,9 @@ STATIC void __attribute__ ((noinline)) run_boot_py(safe_mode_t safe_mode) {
651654
// Do USB setup even if boot.py is not run.
652655

653656
supervisor_allocation *heap = allocate_remaining_memory();
654-
start_mp(heap);
657+
658+
// true means this is the first set of VM's after a hard reset.
659+
start_mp(heap, true);
655660

656661
#if CIRCUITPY_USB
657662
// Set up default USB values after boot.py VM starts but before running boot.py.
@@ -728,12 +733,12 @@ STATIC void __attribute__ ((noinline)) run_boot_py(safe_mode_t safe_mode) {
728733
#endif
729734
}
730735

731-
STATIC int run_repl(void) {
736+
STATIC int run_repl(bool first_run) {
732737
int exit_code = PYEXEC_FORCED_EXIT;
733738
stack_resize();
734739
filesystem_flush();
735740
supervisor_allocation *heap = allocate_remaining_memory();
736-
start_mp(heap);
741+
start_mp(heap, first_run);
737742

738743
#if CIRCUITPY_USB
739744
usb_setup_with_vm();
@@ -846,28 +851,34 @@ int __attribute__((used)) main(void) {
846851
supervisor_start_bluetooth();
847852
#endif
848853

849-
// Boot script is finished, so now go into REPL/main mode.
854+
// Boot script is finished, so now go into REPL or run code.py.
850855
int exit_code = PYEXEC_FORCED_EXIT;
851856
bool skip_repl = true;
852857
bool first_run = true;
858+
bool simulate_reset;
853859
for (;;) {
860+
simulate_reset = false;
854861
if (!skip_repl) {
855-
exit_code = run_repl();
862+
exit_code = run_repl(first_run);
856863
supervisor_set_run_reason(RUN_REASON_REPL_RELOAD);
857864
}
858865
if (exit_code == PYEXEC_FORCED_EXIT) {
859866
if (!first_run) {
860867
serial_write_compressed(translate("soft reboot\n"));
861868
}
862-
first_run = false;
863869
if (pyexec_mode_kind == PYEXEC_MODE_FRIENDLY_REPL) {
864-
skip_repl = run_code_py(safe_mode);
870+
skip_repl = run_code_py(safe_mode, first_run, &simulate_reset);
865871
} else {
866872
skip_repl = false;
867873
}
868874
} else if (exit_code != 0) {
869875
break;
870876
}
877+
878+
// Either the REPL or code.py has run and finished.
879+
// If code.py did a fake deep sleep, pretend that we are running code.py for
880+
// the first time after a hard reset. This will preserve any alarm information.
881+
first_run = simulate_reset;
871882
}
872883
mp_deinit();
873884
return 0;

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

Lines changed: 1 addition & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -62,11 +62,6 @@ 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-
7065
STATIC esp_sleep_wakeup_cause_t _get_wakeup_cause(void) {
7166
// First check if the modules remember what last woke up
7267
if (alarm_pin_pinalarm_woke_this_cycle()) {
@@ -80,11 +75,7 @@ STATIC esp_sleep_wakeup_cause_t _get_wakeup_cause(void) {
8075
}
8176
// If waking from true deep sleep, modules will have lost their state,
8277
// so check the deep wakeup cause manually
83-
if (!soft_wakeup) {
84-
soft_wakeup = true;
85-
return esp_sleep_get_wakeup_cause();
86-
}
87-
return ESP_SLEEP_WAKEUP_UNDEFINED;
78+
return esp_sleep_get_wakeup_cause();
8879
}
8980

9081
bool common_hal_alarm_woken_from_sleep(void) {

shared-bindings/alarm/__init__.c

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -64,8 +64,10 @@
6464
//| This object is the sole instance of `alarm.SleepMemory`."""
6565
//|
6666

67-
//| wake_alarm: Alarm
68-
//| """The most recently triggered alarm. If CircuitPython was sleeping, the alarm the woke it from sleep."""
67+
//| wake_alarm: Optional[Alarm]
68+
//| """The most recently triggered alarm. If CircuitPython was sleeping, the alarm that woke it from sleep.
69+
//| If no alarm occured since the last hard reset or soft restart, value is ``None``.
70+
//| """
6971
//|
7072

7173
// wake_alarm is implemented as a dictionary entry, so there's no code here.
@@ -103,7 +105,9 @@ STATIC mp_obj_t alarm_light_sleep_until_alarms(size_t n_args, const mp_obj_t *ar
103105

104106
validate_objs_are_alarms(n_args, args);
105107

106-
return common_hal_alarm_light_sleep_until_alarms(n_args, args);
108+
mp_obj_t alarm = common_hal_alarm_light_sleep_until_alarms(n_args, args);
109+
shared_alarm_save_wake_alarm(alarm);
110+
return alarm;
107111
}
108112
MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(alarm_light_sleep_until_alarms_obj, 1, MP_OBJ_FUN_ARGS_MAX, alarm_light_sleep_until_alarms);
109113

0 commit comments

Comments
 (0)