diff --git a/lib/utils/pyexec.c b/lib/utils/pyexec.c index 2651189915..292c7f8595 100644 --- a/lib/utils/pyexec.c +++ b/lib/utils/pyexec.c @@ -165,7 +165,12 @@ STATIC int parse_compile_execute(const void *source, mp_parse_input_kind_t input } if (result != NULL) { result->return_code = ret; + #if CIRCUITPY_ALARM + // Don't set the exception object if we exited for deep sleep. + if (ret != 0 && ret != PYEXEC_DEEP_SLEEP) { + #else if (ret != 0) { + #endif mp_obj_t return_value = (mp_obj_t)nlr.ret_val; result->exception = return_value; result->exception_line = -1; diff --git a/ports/esp32s2/common-hal/alarm/__init__.c b/ports/esp32s2/common-hal/alarm/__init__.c index 7a977b093c..77dc2ff3f2 100644 --- a/ports/esp32s2/common-hal/alarm/__init__.c +++ b/ports/esp32s2/common-hal/alarm/__init__.c @@ -62,6 +62,11 @@ 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()) { @@ -75,7 +80,11 @@ 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 - return esp_sleep_get_wakeup_cause(); + if (!soft_wakeup) { + soft_wakeup = true; + return esp_sleep_get_wakeup_cause(); + } + return ESP_SLEEP_WAKEUP_UNDEFINED; } bool common_hal_alarm_woken_from_sleep(void) { diff --git a/ports/esp32s2/supervisor/usb.c b/ports/esp32s2/supervisor/usb.c index 05e0746b00..0aa379b166 100644 --- a/ports/esp32s2/supervisor/usb.c +++ b/ports/esp32s2/supervisor/usb.c @@ -28,6 +28,7 @@ #include "py/runtime.h" #include "supervisor/usb.h" #include "supervisor/esp_port.h" +#include "supervisor/port.h" #include "lib/utils/interrupt_char.h" #include "lib/mp-readline/readline.h" @@ -109,6 +110,7 @@ void init_usb_hardware(void) { usb_device_stack, &usb_device_taskdef); } + /** * Callback invoked when received an "wanted" char. * @param itf Interface index (for multiple cdc interfaces) @@ -116,13 +118,13 @@ void init_usb_hardware(void) { */ void tud_cdc_rx_wanted_cb(uint8_t itf, char wanted_char) { (void)itf; // not used + // CircuitPython's VM is run in a separate FreeRTOS task from TinyUSB. + // So, we must notify the other task when a CTRL-C is received. + port_wake_main_task(); // Workaround for using lib/utils/interrupt_char.c // Compare mp_interrupt_char with wanted_char and ignore if not matched if (mp_interrupt_char == wanted_char) { tud_cdc_read_flush(); // flush read fifo mp_sched_keyboard_interrupt(); - // CircuitPython's VM is run in a separate FreeRTOS task from TinyUSB. - // So, we must notify the other task when a CTRL-C is received. - xTaskNotifyGive(circuitpython_task); } } diff --git a/ports/nrf/common-hal/_bleio/Adapter.c b/ports/nrf/common-hal/_bleio/Adapter.c index 9f5f46f656..f4302b839d 100644 --- a/ports/nrf/common-hal/_bleio/Adapter.c +++ b/ports/nrf/common-hal/_bleio/Adapter.c @@ -952,8 +952,11 @@ bool common_hal_bleio_adapter_is_bonded_to_central(bleio_adapter_obj_t *self) { } void bleio_adapter_gc_collect(bleio_adapter_obj_t *adapter) { - gc_collect_root((void **)adapter, sizeof(bleio_adapter_obj_t) / sizeof(size_t)); - gc_collect_root((void **)bleio_connections, sizeof(bleio_connections) / sizeof(size_t)); + // We divide by size_t so that we can scan each 32-bit aligned value to see + // if it is a pointer. This allows us to change the structs without worrying + // about collecting new pointers. + gc_collect_root((void **)adapter, sizeof(bleio_adapter_obj_t) / (sizeof(size_t))); + gc_collect_root((void **)bleio_connections, sizeof(bleio_connections) / (sizeof(size_t))); } void bleio_adapter_reset(bleio_adapter_obj_t *adapter) { diff --git a/ports/nrf/common-hal/alarm/__init__.c b/ports/nrf/common-hal/alarm/__init__.c index 8accc88764..117fa1168f 100644 --- a/ports/nrf/common-hal/alarm/__init__.c +++ b/ports/nrf/common-hal/alarm/__init__.c @@ -137,6 +137,8 @@ mp_obj_t common_hal_alarm_create_wake_alarm(void) { // Set up light sleep or deep sleep alarms. STATIC void _setup_sleep_alarms(bool deep_sleep, size_t n_alarms, const mp_obj_t *alarms) { + sleepmem_wakeup_event = SLEEPMEM_WAKEUP_BY_NONE; + sleepmem_wakeup_pin = WAKEUP_PIN_UNDEF; alarm_pin_pinalarm_set_alarms(deep_sleep, n_alarms, alarms); alarm_time_timealarm_set_alarms(deep_sleep, n_alarms, alarms); alarm_touch_touchalarm_set_alarm(deep_sleep, n_alarms, alarms); @@ -156,10 +158,6 @@ void system_on_idle_until_alarm(int64_t timediff_ms, uint32_t prescaler) { if (timediff_ms != -1) { have_timeout = true; - #if 0 - int64_t now = common_hal_time_monotonic_ms(); - dbg_printf("now_ms=%ld timediff_ms=%ld\r\n", (long)now, (long)timediff_ms); - #endif if (timediff_ms < 0) { timediff_ms = 0; } @@ -175,34 +173,17 @@ void system_on_idle_until_alarm(int64_t timediff_ms, uint32_t prescaler) { start_tick = port_get_raw_ticks(NULL); end_tick = start_tick + tickdiff; } - #if 0 - dbg_printf("start_tick=%ld end_tick=%ld have_timeout=%c\r\n", (long)start_tick, (long)end_tick, have_timeout ? 'T' : 'F'); - #endif int64_t remaining; - sleepmem_wakeup_event = SLEEPMEM_WAKEUP_BY_NONE; - sleepmem_wakeup_pin = WAKEUP_PIN_UNDEF; - - #ifdef NRF_DEBUG_PRINT - int ct = 40; - char reason = '?'; -#define WAKEUP_REASON(x) reason = (x) - #else -#define WAKEUP_REASON(x) - #endif - while (1) { if (mp_hal_is_interrupted()) { - WAKEUP_REASON('I'); break; } if (serial_connected() && serial_bytes_available()) { - WAKEUP_REASON('S'); break; } RUN_BACKGROUND_TASKS; if (common_hal_alarm_woken_from_sleep()) { - WAKEUP_REASON('W'); break; } if (have_timeout) { @@ -210,51 +191,28 @@ void system_on_idle_until_alarm(int64_t timediff_ms, uint32_t prescaler) { // We break a bit early so we don't risk setting the alarm before the time when we call // sleep. if (remaining < 1) { - WAKEUP_REASON('t'); break; } port_interrupt_after_ticks(remaining); } // Idle until an interrupt happens. port_idle_until_interrupt(); - #ifdef NRF_DEBUG_PRINT - if (ct > 0) { - mp_printf(&mp_plat_print, "_"); - --ct; - } - #endif if (have_timeout) { remaining = end_tick - port_get_raw_ticks(NULL); if (remaining <= 0) { sleepmem_wakeup_event = SLEEPMEM_WAKEUP_BY_TIMER; - WAKEUP_REASON('T'); break; } } } - #ifdef NRF_DEBUG_PRINT - mp_printf(&mp_plat_print, "%c\r\n", reason); - #endif #if defined(MICROPY_QSPI_CS) qspi_flash_exit_sleep(); #endif - - #ifdef NRF_DEBUG_PRINT - tickdiff = port_get_raw_ticks(NULL) - start_tick; - double sec; - if (prescaler == 0) { - sec = (double)tickdiff / 1024; - } else { - sec = (double)(tickdiff * prescaler) / 1024; - } - mp_printf(&mp_plat_print, "lapse %6.1f sec\r\n", sec); - #endif } mp_obj_t common_hal_alarm_light_sleep_until_alarms(size_t n_alarms, const mp_obj_t *alarms) { mp_obj_t wake_alarm = mp_const_none; - alarm_time_timealarm_clear_wakeup_time(); _setup_sleep_alarms(false, n_alarms, alarms); #ifdef NRF_DEBUG_PRINT @@ -290,7 +248,6 @@ mp_obj_t common_hal_alarm_light_sleep_until_alarms(size_t n_alarms, const mp_obj } void common_hal_alarm_set_deep_sleep_alarms(size_t n_alarms, const mp_obj_t *alarms) { - alarm_time_timealarm_clear_wakeup_time(); _setup_sleep_alarms(true, n_alarms, alarms); } diff --git a/ports/nrf/common-hal/alarm/time/TimeAlarm.c b/ports/nrf/common-hal/alarm/time/TimeAlarm.c index 54d9a8921f..c5f3bfd705 100644 --- a/ports/nrf/common-hal/alarm/time/TimeAlarm.c +++ b/ports/nrf/common-hal/alarm/time/TimeAlarm.c @@ -70,10 +70,6 @@ int64_t alarm_time_timealarm_get_wakeup_timediff_ms(void) { return wakeup_time_saved - common_hal_time_monotonic_ms(); } -void alarm_time_timealarm_clear_wakeup_time(void) { - wakeup_time_saved = 0; -} - void alarm_time_timealarm_reset(void) { port_disable_interrupt_after_ticks_ch(1); wakeup_time_saved = 0;