Skip to content

Bring 7.1.x changes into main - cascadetoml undo + alarm fixes #5761

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 8 commits into from
Dec 23, 2021
11 changes: 6 additions & 5 deletions locale/circuitpython.pot
Original file line number Diff line number Diff line change
Expand Up @@ -574,7 +574,7 @@ msgstr ""

#: shared-bindings/displayio/Display.c
#: shared-bindings/framebufferio/FramebufferDisplay.c
#: shared-bindings/is31fl3741/is31fl3741.c
#: shared-bindings/is31fl3741/IS31FL3741.c
#: shared-bindings/rgbmatrix/RGBMatrix.c
msgid "Brightness must be 0-1.0"
msgstr ""
Expand Down Expand Up @@ -1462,7 +1462,7 @@ msgstr ""
msgid "Key must be 16, 24, or 32 bytes long"
msgstr ""

#: shared-module/is31fl3741/is31fl3741.c
#: shared-module/is31fl3741/IS31FL3741.c
msgid "LED mappings must match display size"
msgstr ""

Expand Down Expand Up @@ -2090,7 +2090,7 @@ msgstr ""
msgid "Sample rate too high. It must be less than %d"
msgstr ""

#: shared-bindings/is31fl3741/is31fl3741.c
#: shared-bindings/is31fl3741/IS31FL3741.c
msgid "Scale dimensions must divide by 3"
msgstr ""

Expand Down Expand Up @@ -2351,7 +2351,7 @@ msgstr ""
msgid "Unable to create lock"
msgstr ""

#: shared-module/displayio/I2CDisplay.c shared-module/is31fl3741/is31fl3741.c
#: shared-module/displayio/I2CDisplay.c shared-module/is31fl3741/IS31FL3741.c
#, c-format
msgid "Unable to find I2C Display at %x"
msgstr ""
Expand Down Expand Up @@ -3950,6 +3950,7 @@ msgstr ""
#: ports/espressif/boards/adafruit_funhouse/mpconfigboard.h
#: ports/espressif/boards/adafruit_magtag_2.9_grayscale/mpconfigboard.h
#: ports/espressif/boards/adafruit_metro_esp32s2/mpconfigboard.h
#: ports/espressif/boards/adafruit_qtpy_esp32s2/mpconfigboard.h
#: ports/espressif/boards/ai_thinker_esp32-c3s/mpconfigboard.h
#: ports/espressif/boards/ai_thinker_esp_12k_nodemcu/mpconfigboard.h
#: ports/espressif/boards/artisense_rd00/mpconfigboard.h
Expand Down Expand Up @@ -4462,7 +4463,7 @@ msgstr ""
msgid "width must be from 2 to 8 (inclusive), not %d"
msgstr ""

#: shared-bindings/is31fl3741/is31fl3741.c
#: shared-bindings/is31fl3741/IS31FL3741.c
#: shared-bindings/rgbmatrix/RGBMatrix.c
msgid "width must be greater than zero"
msgstr ""
Expand Down
33 changes: 22 additions & 11 deletions main.c
Original file line number Diff line number Diff line change
Expand Up @@ -122,7 +122,7 @@ static void reset_devices(void) {
#endif
}

STATIC void start_mp(supervisor_allocation *heap) {
STATIC void start_mp(supervisor_allocation *heap, bool first_run) {
autoreload_stop();
supervisor_workflow_reset();

Expand Down Expand Up @@ -170,7 +170,8 @@ 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.
shared_alarm_save_wake_alarm(common_hal_alarm_create_wake_alarm());
// There is no alarm if this is not the first time code.py or the REPL has been run.
shared_alarm_save_wake_alarm(first_run ? common_hal_alarm_create_wake_alarm() : mp_const_none);
// Reset alarm module only after we retrieved the wakeup alarm.
alarm_reset();
#endif
Expand Down Expand Up @@ -308,7 +309,7 @@ STATIC void print_code_py_status_message(safe_mode_t safe_mode) {
}
}

STATIC bool run_code_py(safe_mode_t safe_mode) {
STATIC bool run_code_py(safe_mode_t safe_mode, bool first_run, bool *simulate_reset) {
bool serial_connected_at_start = serial_connected();
bool printed_safe_mode_message = false;
#if CIRCUITPY_AUTORELOAD_DELAY_MS > 0
Expand Down Expand Up @@ -347,7 +348,7 @@ STATIC bool run_code_py(safe_mode_t safe_mode) {
supervisor_allocation *heap = allocate_remaining_memory();

// Prepare the VM state. Includes an alarm check/reset for sleep.
start_mp(heap);
start_mp(heap, first_run);

#if CIRCUITPY_USB
usb_setup_with_vm();
Expand Down Expand Up @@ -630,6 +631,8 @@ STATIC bool run_code_py(safe_mode_t safe_mode) {
#if CIRCUITPY_ALARM
if (fake_sleeping) {
board_init();
// Pretend that the next run is the first run, as if we were reset.
*simulate_reset = true;
}
#endif

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

supervisor_allocation *heap = allocate_remaining_memory();
start_mp(heap);

// true means this is the first set of VM's after a hard reset.
start_mp(heap, true);

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

STATIC int run_repl(void) {
STATIC int run_repl(bool first_run) {
int exit_code = PYEXEC_FORCED_EXIT;
stack_resize();
filesystem_flush();
supervisor_allocation *heap = allocate_remaining_memory();
start_mp(heap);
start_mp(heap, first_run);

#if CIRCUITPY_USB
usb_setup_with_vm();
Expand Down Expand Up @@ -846,28 +851,34 @@ int __attribute__((used)) main(void) {
supervisor_start_bluetooth();
#endif

// Boot script is finished, so now go into REPL/main mode.
// Boot script is finished, so now go into REPL or run code.py.
int exit_code = PYEXEC_FORCED_EXIT;
bool skip_repl = true;
bool first_run = true;
bool simulate_reset;
for (;;) {
simulate_reset = false;
if (!skip_repl) {
exit_code = run_repl();
exit_code = run_repl(first_run);
supervisor_set_run_reason(RUN_REASON_REPL_RELOAD);
}
if (exit_code == PYEXEC_FORCED_EXIT) {
if (!first_run) {
serial_write_compressed(translate("soft reboot\n"));
}
first_run = false;
if (pyexec_mode_kind == PYEXEC_MODE_FRIENDLY_REPL) {
skip_repl = run_code_py(safe_mode);
skip_repl = run_code_py(safe_mode, first_run, &simulate_reset);
} else {
skip_repl = false;
}
} else if (exit_code != 0) {
break;
}

// Either the REPL or code.py has run and finished.
// If code.py did a fake deep sleep, pretend that we are running code.py for
// the first time after a hard reset. This will preserve any alarm information.
first_run = simulate_reset;
}
mp_deinit();
return 0;
Expand Down
11 changes: 1 addition & 10 deletions ports/espressif/common-hal/alarm/__init__.c
Original file line number Diff line number Diff line change
Expand Up @@ -62,11 +62,6 @@ void alarm_reset(void) {
esp_sleep_disable_wakeup_source(ESP_SLEEP_WAKEUP_ALL);
}

// This will be reset to false by full resets when bss is cleared. Otherwise, the
// reload is due to CircuitPython and the ESP wakeup cause will be stale. This
// can happen if USB is connected after a deep sleep.
STATIC bool soft_wakeup = false;

STATIC esp_sleep_wakeup_cause_t _get_wakeup_cause(void) {
// First check if the modules remember what last woke up
if (alarm_pin_pinalarm_woke_this_cycle()) {
Expand All @@ -80,11 +75,7 @@ STATIC esp_sleep_wakeup_cause_t _get_wakeup_cause(void) {
}
// If waking from true deep sleep, modules will have lost their state,
// so check the deep wakeup cause manually
if (!soft_wakeup) {
soft_wakeup = true;
return esp_sleep_get_wakeup_cause();
}
return ESP_SLEEP_WAKEUP_UNDEFINED;
return esp_sleep_get_wakeup_cause();
}

bool common_hal_alarm_woken_from_sleep(void) {
Expand Down
3 changes: 1 addition & 2 deletions requirements-dev.txt
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,7 @@
huffman

# For nvm.toml
cascadetoml==0.3.1
tomlkit==0.7.2
cascadetoml
jinja2
typer

Expand Down
10 changes: 7 additions & 3 deletions shared-bindings/alarm/__init__.c
Original file line number Diff line number Diff line change
Expand Up @@ -64,8 +64,10 @@
//| This object is the sole instance of `alarm.SleepMemory`."""
//|

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

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

validate_objs_are_alarms(n_args, args);

return common_hal_alarm_light_sleep_until_alarms(n_args, args);
mp_obj_t alarm = common_hal_alarm_light_sleep_until_alarms(n_args, args);
shared_alarm_save_wake_alarm(alarm);
return alarm;
}
MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(alarm_light_sleep_until_alarms_obj, 1, MP_OBJ_FUN_ARGS_MAX, alarm_light_sleep_until_alarms);

Expand Down