Skip to content

Commit 900ec91

Browse files
authored
Merge pull request #5761 from adafruit/7.1.x
Bring 7.1.x changes into main - cascadetoml undo + alarm fixes
2 parents c1236fb + 41db3f6 commit 900ec91

File tree

4 files changed

+31
-26
lines changed

4 files changed

+31
-26
lines changed

main.c

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

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

@@ -171,7 +171,8 @@ STATIC void start_mp(supervisor_allocation *heap) {
171171

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

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

350351
// Prepare the VM state. Includes an alarm check/reset for sleep.
351-
start_mp(heap);
352+
start_mp(heap, first_run);
352353

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

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

654657
supervisor_allocation *heap = allocate_remaining_memory();
655-
start_mp(heap);
658+
659+
// true means this is the first set of VM's after a hard reset.
660+
start_mp(heap, true);
656661

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

732-
STATIC int run_repl(void) {
737+
STATIC int run_repl(bool first_run) {
733738
int exit_code = PYEXEC_FORCED_EXIT;
734739
stack_resize();
735740
filesystem_flush();
736741
supervisor_allocation *heap = allocate_remaining_memory();
737-
start_mp(heap);
742+
start_mp(heap, first_run);
738743

739744
#if CIRCUITPY_USB
740745
usb_setup_with_vm();
@@ -847,28 +852,34 @@ int __attribute__((used)) main(void) {
847852
supervisor_start_bluetooth();
848853
#endif
849854

850-
// Boot script is finished, so now go into REPL/main mode.
855+
// Boot script is finished, so now go into REPL or run code.py.
851856
int exit_code = PYEXEC_FORCED_EXIT;
852857
bool skip_repl = true;
853858
bool first_run = true;
859+
bool simulate_reset;
854860
for (;;) {
861+
simulate_reset = false;
855862
if (!skip_repl) {
856-
exit_code = run_repl();
863+
exit_code = run_repl(first_run);
857864
supervisor_set_run_reason(RUN_REASON_REPL_RELOAD);
858865
}
859866
if (exit_code == PYEXEC_FORCED_EXIT) {
860867
if (!first_run) {
861868
serial_write_compressed(translate("soft reboot\n"));
862869
}
863-
first_run = false;
864870
if (pyexec_mode_kind == PYEXEC_MODE_FRIENDLY_REPL) {
865-
skip_repl = run_code_py(safe_mode);
871+
skip_repl = run_code_py(safe_mode, first_run, &simulate_reset);
866872
} else {
867873
skip_repl = false;
868874
}
869875
} else if (exit_code != 0) {
870876
break;
871877
}
878+
879+
// Either the REPL or code.py has run and finished.
880+
// If code.py did a fake deep sleep, pretend that we are running code.py for
881+
// the first time after a hard reset. This will preserve any alarm information.
882+
first_run = simulate_reset;
872883
}
873884
mp_deinit();
874885
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) {

requirements-dev.txt

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,7 @@
22
huffman
33

44
# For nvm.toml
5-
cascadetoml==0.3.1
6-
tomlkit==0.7.2
5+
cascadetoml
76
jinja2
87
typer
98

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)