A couple sleep fixes

* Better messaging when code is stopped by an auto-reload.
* Auto-reload works during sleeps on ESP32-S2. Ticks wake up the
  main task each time.
* Made internal naming consistent. CamelCase Python names are NOT
  separated by an underscore.
This commit is contained in:
Scott Shawcroft 2020-12-22 16:13:02 -08:00
parent d4e9eea397
commit 1fca297a2d
No known key found for this signature in database
GPG Key ID: 0DFD512649C052DA
14 changed files with 142 additions and 149 deletions

9
main.c
View File

@ -308,8 +308,11 @@ STATIC bool run_code_py(safe_mode_t safe_mode) {
return reload_requested; return reload_requested;
} }
// Display a different completion message if the user has no USB attached (cannot save files) if (reload_requested && result.return_code == PYEXEC_EXCEPTION) {
serial_write_compressed(translate("\nCode done running. Waiting for reload.\n")); serial_write_compressed(translate("\nCode stopped by auto-reload.\n"));
} else {
serial_write_compressed(translate("\nCode done running.\n"));
}
} }
// Program has finished running. // Program has finished running.
@ -407,7 +410,7 @@ STATIC bool run_code_py(safe_mode_t safe_mode) {
alarm_enter_deep_sleep(); alarm_enter_deep_sleep();
// Does not return. // Does not return.
} else { } else {
serial_write_compressed(translate("Pretending to deep sleep until alarm, any key or file write.\n")); serial_write_compressed(translate("Pretending to deep sleep until alarm, CTRL-C or file write.\n"));
} }
} }
} }

View File

@ -54,7 +54,7 @@ const alarm_sleep_memory_obj_t alarm_sleep_memory_obj = {
void alarm_reset(void) { void alarm_reset(void) {
alarm_time_timealarm_reset(); alarm_time_timealarm_reset();
alarm_pin_pin_alarm_reset(); alarm_pin_pinalarm_reset();
alarm_sleep_memory_reset(); alarm_sleep_memory_reset();
esp_sleep_disable_wakeup_source(ESP_SLEEP_WAKEUP_ALL); esp_sleep_disable_wakeup_source(ESP_SLEEP_WAKEUP_ALL);
} }
@ -63,7 +63,7 @@ STATIC esp_sleep_wakeup_cause_t _get_wakeup_cause(void) {
if (alarm_time_timealarm_woke_us_up()) { if (alarm_time_timealarm_woke_us_up()) {
return ESP_SLEEP_WAKEUP_TIMER; return ESP_SLEEP_WAKEUP_TIMER;
} }
if (alarm_pin_pin_alarm_woke_us_up()) { if (alarm_pin_pinalarm_woke_us_up()) {
return ESP_SLEEP_WAKEUP_GPIO; return ESP_SLEEP_WAKEUP_GPIO;
} }
@ -84,7 +84,7 @@ STATIC mp_obj_t _get_wake_alarm(size_t n_alarms, const mp_obj_t *alarms) {
case ESP_SLEEP_WAKEUP_GPIO: case ESP_SLEEP_WAKEUP_GPIO:
case ESP_SLEEP_WAKEUP_EXT0: case ESP_SLEEP_WAKEUP_EXT0:
case ESP_SLEEP_WAKEUP_EXT1: { case ESP_SLEEP_WAKEUP_EXT1: {
return alarm_pin_pin_alarm_get_wakeup_alarm(n_alarms, alarms); return alarm_pin_pinalarm_get_wakeup_alarm(n_alarms, alarms);
} }
case ESP_SLEEP_WAKEUP_TOUCHPAD: case ESP_SLEEP_WAKEUP_TOUCHPAD:
@ -106,7 +106,7 @@ mp_obj_t common_hal_alarm_get_wake_alarm(void) {
// Set up light sleep or deep sleep alarms. // 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) { STATIC void _setup_sleep_alarms(bool deep_sleep, size_t n_alarms, const mp_obj_t *alarms) {
alarm_pin_pin_alarm_set_alarms(deep_sleep, n_alarms, alarms); alarm_pin_pinalarm_set_alarms(deep_sleep, n_alarms, alarms);
alarm_time_timealarm_set_alarms(deep_sleep, n_alarms, alarms); alarm_time_timealarm_set_alarms(deep_sleep, n_alarms, alarms);
} }
@ -123,25 +123,14 @@ STATIC void _idle_until_alarm(void) {
} }
} }
// Is it safe to do a light sleep? Check whether WiFi is on or there are
// other ongoing tasks that should not be shut down.
STATIC bool _light_sleep_ok(void) {
int64_t connecting_delay_ticks = CIRCUITPY_USB_CONNECTED_SLEEP_DELAY * 1024 - port_get_raw_ticks(NULL);
return !common_hal_wifi_radio_get_enabled(&common_hal_wifi_radio_obj) &&
!supervisor_workflow_active() &&
connecting_delay_ticks <= 0;
}
mp_obj_t common_hal_alarm_light_sleep_until_alarms(size_t n_alarms, const mp_obj_t *alarms) { mp_obj_t common_hal_alarm_light_sleep_until_alarms(size_t n_alarms, const mp_obj_t *alarms) {
_setup_sleep_alarms(false, n_alarms, alarms); _setup_sleep_alarms(false, n_alarms, alarms);
// Light sleep can break some functionality so only do it when possible. Otherwise we idle. // We cannot esp_light_sleep_start() here because it shuts down all non-RTC peripherals.
if (_light_sleep_ok()) { _idle_until_alarm();
// Flush the UART to complete the log line.
uart_wait_tx_idle_polling(CONFIG_ESP_CONSOLE_UART_NUM); if (mp_hal_is_interrupted()) {
esp_light_sleep_start(); return mp_const_none; // Shouldn't be given to python code because exception handling should kick in.
} else {
_idle_until_alarm();
} }
mp_obj_t wake_alarm = _get_wake_alarm(n_alarms, alarms); mp_obj_t wake_alarm = _get_wake_alarm(n_alarms, alarms);
@ -154,7 +143,7 @@ void common_hal_alarm_set_deep_sleep_alarms(size_t n_alarms, const mp_obj_t *ala
} }
void NORETURN alarm_enter_deep_sleep(void) { void NORETURN alarm_enter_deep_sleep(void) {
alarm_pin_pin_alarm_prepare_for_deep_sleep(); alarm_pin_pinalarm_prepare_for_deep_sleep();
// The ESP-IDF caches the deep sleep settings and applies them before sleep. // The ESP-IDF caches the deep sleep settings and applies them before sleep.
// We don't need to worry about resetting them in the interim. // We don't need to worry about resetting them in the interim.
esp_deep_sleep_start(); esp_deep_sleep_start();

View File

@ -38,7 +38,7 @@
#include "components/soc/src/esp32s2/include/hal/gpio_ll.h" #include "components/soc/src/esp32s2/include/hal/gpio_ll.h"
#include "components/xtensa/include/esp_debug_helpers.h" #include "components/xtensa/include/esp_debug_helpers.h"
void common_hal_alarm_pin_pin_alarm_construct(alarm_pin_pin_alarm_obj_t *self, mcu_pin_obj_t *pin, bool value, bool edge, bool pull) { void common_hal_alarm_pin_pinalarm_construct(alarm_pin_pinalarm_obj_t *self, mcu_pin_obj_t *pin, bool value, bool edge, bool pull) {
if (edge) { if (edge) {
mp_raise_ValueError(translate("Cannot wake on pin edge. Only level.")); mp_raise_ValueError(translate("Cannot wake on pin edge. Only level."));
} }
@ -51,41 +51,41 @@ void common_hal_alarm_pin_pin_alarm_construct(alarm_pin_pin_alarm_obj_t *self, m
self->pull = pull; self->pull = pull;
} }
mcu_pin_obj_t *common_hal_alarm_pin_pin_alarm_get_pin(alarm_pin_pin_alarm_obj_t *self) { mcu_pin_obj_t *common_hal_alarm_pin_pinalarm_get_pin(alarm_pin_pinalarm_obj_t *self) {
return self->pin; return self->pin;
} }
bool common_hal_alarm_pin_pin_alarm_get_value(alarm_pin_pin_alarm_obj_t *self) { bool common_hal_alarm_pin_pinalarm_get_value(alarm_pin_pinalarm_obj_t *self) {
return self->value; return self->value;
} }
bool common_hal_alarm_pin_pin_alarm_get_edge(alarm_pin_pin_alarm_obj_t *self) { bool common_hal_alarm_pin_pinalarm_get_edge(alarm_pin_pinalarm_obj_t *self) {
return false; return false;
} }
bool common_hal_alarm_pin_pin_alarm_get_pull(alarm_pin_pin_alarm_obj_t *self) { bool common_hal_alarm_pin_pinalarm_get_pull(alarm_pin_pinalarm_obj_t *self) {
return self->pull; return self->pull;
} }
gpio_isr_handle_t gpio_interrupt_handle; gpio_isr_handle_t gpio_interrupt_handle;
// Low and high are relative to pin number. 32+ is high. <32 is low. // Low and high are relative to pin number. 32+ is high. <32 is low.
static volatile uint32_t low_pin_status = 0; static volatile uint32_t pin_31_0_status = 0;
static volatile uint32_t high_pin_status = 0; static volatile uint32_t pin_63_32_status = 0;
void gpio_interrupt(void *arg) { void gpio_interrupt(void *arg) {
(void) arg; (void) arg;
gpio_ll_get_intr_status(&GPIO, xPortGetCoreID(), (uint32_t*) &low_pin_status); gpio_ll_get_intr_status(&GPIO, xPortGetCoreID(), (uint32_t*) &pin_31_0_status);
gpio_ll_clear_intr_status(&GPIO, low_pin_status); gpio_ll_clear_intr_status(&GPIO, pin_31_0_status);
gpio_ll_get_intr_status_high(&GPIO, xPortGetCoreID(), (uint32_t*) &high_pin_status); gpio_ll_get_intr_status_high(&GPIO, xPortGetCoreID(), (uint32_t*) &pin_63_32_status);
gpio_ll_clear_intr_status_high(&GPIO, high_pin_status); gpio_ll_clear_intr_status_high(&GPIO, pin_63_32_status);
// disable the interrupts that fired, maybe all of them // disable the interrupts that fired, maybe all of them
for (size_t i = 0; i < 32; i++) { for (size_t i = 0; i < 32; i++) {
uint32_t mask = 1 << i; uint32_t mask = 1 << i;
if ((low_pin_status & mask) != 0) { if ((pin_31_0_status & mask) != 0) {
gpio_ll_intr_disable(&GPIO, i); gpio_ll_intr_disable(&GPIO, i);
} }
if ((high_pin_status & mask) != 0) { if ((pin_63_32_status & mask) != 0) {
gpio_ll_intr_disable(&GPIO, 32 + i); gpio_ll_intr_disable(&GPIO, 32 + i);
} }
} }
@ -96,18 +96,18 @@ void gpio_interrupt(void *arg) {
} }
} }
bool alarm_pin_pin_alarm_woke_us_up(void) { bool alarm_pin_pinalarm_woke_us_up(void) {
return low_pin_status != 0 || high_pin_status != 0; return pin_31_0_status != 0 || pin_63_32_status != 0;
} }
mp_obj_t alarm_pin_pin_alarm_get_wakeup_alarm(size_t n_alarms, const mp_obj_t *alarms) { mp_obj_t alarm_pin_pinalarm_get_wakeup_alarm(size_t n_alarms, const mp_obj_t *alarms) {
// First, check to see if we match any given alarms. // First, check to see if we match any given alarms.
uint64_t pin_status = ((uint64_t) high_pin_status) << 32 | low_pin_status; uint64_t pin_status = ((uint64_t) pin_63_32_status) << 32 | pin_31_0_status;
for (size_t i = 0; i < n_alarms; i++) { for (size_t i = 0; i < n_alarms; i++) {
if (!MP_OBJ_IS_TYPE(alarms[i], &alarm_pin_pin_alarm_type)) { if (!MP_OBJ_IS_TYPE(alarms[i], &alarm_pin_pinalarm_type)) {
continue; continue;
} }
alarm_pin_pin_alarm_obj_t *alarm = MP_OBJ_TO_PTR(alarms[i]); alarm_pin_pinalarm_obj_t *alarm = MP_OBJ_TO_PTR(alarms[i]);
if ((pin_status & (1ull << alarm->pin->number)) != 0) { if ((pin_status & (1ull << alarm->pin->number)) != 0) {
return alarms[i]; return alarms[i];
} }
@ -131,8 +131,8 @@ mp_obj_t alarm_pin_pin_alarm_get_wakeup_alarm(size_t n_alarms, const mp_obj_t *a
} }
} }
alarm_pin_pin_alarm_obj_t *alarm = m_new_obj(alarm_pin_pin_alarm_obj_t); alarm_pin_pinalarm_obj_t *alarm = m_new_obj(alarm_pin_pinalarm_obj_t);
alarm->base.type = &alarm_pin_pin_alarm_type; alarm->base.type = &alarm_pin_pinalarm_type;
alarm->pin = NULL; alarm->pin = NULL;
// Map the pin number back to a pin object. // Map the pin number back to a pin object.
for (size_t i = 0; i < mcu_pin_globals.map.used; i++) { for (size_t i = 0; i < mcu_pin_globals.map.used; i++) {
@ -151,7 +151,7 @@ static uint64_t high_alarms = 0;
static uint64_t low_alarms = 0; static uint64_t low_alarms = 0;
static uint64_t pull_pins = 0; static uint64_t pull_pins = 0;
void alarm_pin_pin_alarm_reset(void) { void alarm_pin_pinalarm_reset(void) {
if (gpio_interrupt_handle != NULL) { if (gpio_interrupt_handle != NULL) {
esp_intr_free(gpio_interrupt_handle); esp_intr_free(gpio_interrupt_handle);
gpio_interrupt_handle = NULL; gpio_interrupt_handle = NULL;
@ -168,21 +168,21 @@ void alarm_pin_pin_alarm_reset(void) {
high_alarms = 0; high_alarms = 0;
low_alarms = 0; low_alarms = 0;
pull_pins = 0; pull_pins = 0;
high_pin_status = 0; pin_63_32_status = 0;
low_pin_status = 0; pin_31_0_status = 0;
} }
void alarm_pin_pin_alarm_set_alarms(bool deep_sleep, size_t n_alarms, const mp_obj_t *alarms) { void alarm_pin_pinalarm_set_alarms(bool deep_sleep, size_t n_alarms, const mp_obj_t *alarms) {
// Bitmask of wake up settings. // Bitmask of wake up settings.
size_t high_count = 0; size_t high_count = 0;
size_t low_count = 0; size_t low_count = 0;
for (size_t i = 0; i < n_alarms; i++) { for (size_t i = 0; i < n_alarms; i++) {
// TODO: Check for ULP or touch alarms because they can't coexist with GPIO alarms. // TODO: Check for ULP or touch alarms because they can't coexist with GPIO alarms.
if (!MP_OBJ_IS_TYPE(alarms[i], &alarm_pin_pin_alarm_type)) { if (!MP_OBJ_IS_TYPE(alarms[i], &alarm_pin_pinalarm_type)) {
continue; continue;
} }
alarm_pin_pin_alarm_obj_t *alarm = MP_OBJ_TO_PTR(alarms[i]); alarm_pin_pinalarm_obj_t *alarm = MP_OBJ_TO_PTR(alarms[i]);
gpio_num_t pin_number = alarm->pin->number; gpio_num_t pin_number = alarm->pin->number;
if (alarm->value) { if (alarm->value) {
@ -239,8 +239,8 @@ void alarm_pin_pin_alarm_set_alarms(bool deep_sleep, size_t n_alarms, const mp_o
} }
// Set GPIO interrupts so they wake us from light sleep or from idle via the // Set GPIO interrupts so they wake us from light sleep or from idle via the
// interrupt handler above. // interrupt handler above.
low_pin_status = 0; pin_31_0_status = 0;
high_pin_status = 0; pin_63_32_status = 0;
if (gpio_isr_register(gpio_interrupt, NULL, 0, &gpio_interrupt_handle) != ESP_OK) { if (gpio_isr_register(gpio_interrupt, NULL, 0, &gpio_interrupt_handle) != ESP_OK) {
mp_raise_ValueError(translate("Can only alarm on RTC IO from deep sleep.")); mp_raise_ValueError(translate("Can only alarm on RTC IO from deep sleep."));
} }
@ -282,7 +282,7 @@ void alarm_pin_pin_alarm_set_alarms(bool deep_sleep, size_t n_alarms, const mp_o
} }
void alarm_pin_pin_alarm_prepare_for_deep_sleep(void) { void alarm_pin_pinalarm_prepare_for_deep_sleep(void) {
if (pull_pins == 0) { if (pull_pins == 0) {
return; return;
} }

View File

@ -32,10 +32,10 @@ typedef struct {
mcu_pin_obj_t *pin; mcu_pin_obj_t *pin;
bool value; bool value;
bool pull; bool pull;
} alarm_pin_pin_alarm_obj_t; } alarm_pin_pinalarm_obj_t;
void alarm_pin_pin_alarm_reset(void); void alarm_pin_pinalarm_reset(void);
void alarm_pin_pin_alarm_set_alarms(bool deep_sleep, size_t n_alarms, const mp_obj_t *alarms); void alarm_pin_pinalarm_set_alarms(bool deep_sleep, size_t n_alarms, const mp_obj_t *alarms);
void alarm_pin_pin_alarm_prepare_for_deep_sleep(void); void alarm_pin_pinalarm_prepare_for_deep_sleep(void);
mp_obj_t alarm_pin_pin_alarm_get_wakeup_alarm(size_t n_alarms, const mp_obj_t *alarms); mp_obj_t alarm_pin_pinalarm_get_wakeup_alarm(size_t n_alarms, const mp_obj_t *alarms);
bool alarm_pin_pin_alarm_woke_us_up(void); bool alarm_pin_pinalarm_woke_us_up(void);

View File

@ -34,23 +34,23 @@
#include "shared-bindings/alarm/time/TimeAlarm.h" #include "shared-bindings/alarm/time/TimeAlarm.h"
#include "shared-bindings/time/__init__.h" #include "shared-bindings/time/__init__.h"
void common_hal_alarm_time_time_alarm_construct(alarm_time_time_alarm_obj_t *self, mp_float_t monotonic_time) { void common_hal_alarm_time_timealarm_construct(alarm_time_timealarm_obj_t *self, mp_float_t monotonic_time) {
self->monotonic_time = monotonic_time; self->monotonic_time = monotonic_time;
} }
mp_float_t common_hal_alarm_time_time_alarm_get_monotonic_time(alarm_time_time_alarm_obj_t *self) { mp_float_t common_hal_alarm_time_timealarm_get_monotonic_time(alarm_time_timealarm_obj_t *self) {
return self->monotonic_time; return self->monotonic_time;
} }
mp_obj_t alarm_time_timealarm_get_wakeup_alarm(size_t n_alarms, const mp_obj_t *alarms) { mp_obj_t alarm_time_timealarm_get_wakeup_alarm(size_t n_alarms, const mp_obj_t *alarms) {
// First, check to see if we match // First, check to see if we match
for (size_t i = 0; i < n_alarms; i++) { for (size_t i = 0; i < n_alarms; i++) {
if (MP_OBJ_IS_TYPE(alarms[i], &alarm_time_time_alarm_type)) { if (MP_OBJ_IS_TYPE(alarms[i], &alarm_time_timealarm_type)) {
return alarms[i]; return alarms[i];
} }
} }
alarm_time_time_alarm_obj_t *timer = m_new_obj(alarm_time_time_alarm_obj_t); alarm_time_timealarm_obj_t *timer = m_new_obj(alarm_time_timealarm_obj_t);
timer->base.type = &alarm_time_time_alarm_type; timer->base.type = &alarm_time_timealarm_type;
// TODO: Set monotonic_time based on the RTC state. // TODO: Set monotonic_time based on the RTC state.
timer->monotonic_time = 0.0f; timer->monotonic_time = 0.0f;
return timer; return timer;
@ -78,20 +78,20 @@ void alarm_time_timealarm_reset(void) {
} }
void alarm_time_timealarm_set_alarms(bool deep_sleep, size_t n_alarms, const mp_obj_t *alarms) { void alarm_time_timealarm_set_alarms(bool deep_sleep, size_t n_alarms, const mp_obj_t *alarms) {
bool time_alarm_set = false; bool timealarm_set = false;
alarm_time_time_alarm_obj_t *time_alarm = MP_OBJ_NULL; alarm_time_timealarm_obj_t *timealarm = MP_OBJ_NULL;
for (size_t i = 0; i < n_alarms; i++) { for (size_t i = 0; i < n_alarms; i++) {
if (!MP_OBJ_IS_TYPE(alarms[i], &alarm_time_time_alarm_type)) { if (!MP_OBJ_IS_TYPE(alarms[i], &alarm_time_timealarm_type)) {
continue; continue;
} }
if (time_alarm_set) { if (timealarm_set) {
mp_raise_ValueError(translate("Only one alarm.time alarm can be set.")); mp_raise_ValueError(translate("Only one alarm.time alarm can be set."));
} }
time_alarm = MP_OBJ_TO_PTR(alarms[i]); timealarm = MP_OBJ_TO_PTR(alarms[i]);
time_alarm_set = true; timealarm_set = true;
} }
if (!time_alarm_set) { if (!timealarm_set) {
return; return;
} }
@ -109,7 +109,7 @@ void alarm_time_timealarm_set_alarms(bool deep_sleep, size_t n_alarms, const mp_
// Compute how long to actually sleep, considering the time now. // Compute how long to actually sleep, considering the time now.
mp_float_t now_secs = uint64_to_float(common_hal_time_monotonic_ms()) / 1000.0f; mp_float_t now_secs = uint64_to_float(common_hal_time_monotonic_ms()) / 1000.0f;
mp_float_t wakeup_in_secs = MAX(0.0f, time_alarm->monotonic_time - now_secs); mp_float_t wakeup_in_secs = MAX(0.0f, timealarm->monotonic_time - now_secs);
const uint64_t sleep_for_us = (uint64_t) (wakeup_in_secs * 1000000); const uint64_t sleep_for_us = (uint64_t) (wakeup_in_secs * 1000000);
esp_sleep_enable_timer_wakeup(sleep_for_us); esp_sleep_enable_timer_wakeup(sleep_for_us);

View File

@ -30,7 +30,7 @@
typedef struct { typedef struct {
mp_obj_base_t base; mp_obj_base_t base;
mp_float_t monotonic_time; // values compatible with time.monotonic_time() mp_float_t monotonic_time; // values compatible with time.monotonic_time()
} alarm_time_time_alarm_obj_t; } alarm_time_timealarm_obj_t;
// Find the alarm object that caused us to wake up or create an equivalent one. // Find the alarm object that caused us to wake up or create an equivalent one.
mp_obj_t alarm_time_timealarm_get_wakeup_alarm(size_t n_alarms, const mp_obj_t *alarms); mp_obj_t alarm_time_timealarm_get_wakeup_alarm(size_t n_alarms, const mp_obj_t *alarms);

View File

@ -74,6 +74,10 @@ extern void esp_restart(void) NORETURN;
void tick_timer_cb(void* arg) { void tick_timer_cb(void* arg) {
supervisor_tick(); supervisor_tick();
// CircuitPython's VM is run in a separate FreeRTOS task from timer callbacks. So, we have to
// notify the main task every time in case it's waiting for us.
xTaskNotifyGive(circuitpython_task);
} }
void sleep_timer_cb(void* arg); void sleep_timer_cb(void* arg);
@ -92,6 +96,8 @@ safe_mode_t port_init(void) {
args.name = "CircuitPython Sleep"; args.name = "CircuitPython Sleep";
esp_timer_create(&args, &_sleep_timer); esp_timer_create(&args, &_sleep_timer);
circuitpython_task = xTaskGetCurrentTaskHandle();
// Send the ROM output out of the UART. This includes early logs. // Send the ROM output out of the UART. This includes early logs.
#ifdef DEBUG #ifdef DEBUG
ets_install_uart_printf(); ets_install_uart_printf();
@ -114,16 +120,16 @@ safe_mode_t port_init(void) {
} }
esp_reset_reason_t reason = esp_reset_reason(); esp_reset_reason_t reason = esp_reset_reason();
if (reason == ESP_RST_BROWNOUT) { switch (reason) {
return BROWNOUT; case ESP_RST_BROWNOUT:
return BROWNOUT;
case ESP_RST_PANIC:
case ESP_RST_INT_WDT:
case ESP_RST_WDT:
return HARD_CRASH;
default:
break;
} }
if (reason == ESP_RST_PANIC ||
reason == ESP_RST_INT_WDT ||
reason == ESP_RST_WDT) {
return HARD_CRASH;
}
circuitpython_task = xTaskGetCurrentTaskHandle();
return NO_SAFE_MODE; return NO_SAFE_MODE;
} }
@ -262,10 +268,6 @@ void port_enable_tick(void) {
// Disable 1/1024 second tick. // Disable 1/1024 second tick.
void port_disable_tick(void) { void port_disable_tick(void) {
esp_timer_stop(_tick_timer); esp_timer_stop(_tick_timer);
// CircuitPython's VM is run in a separate FreeRTOS task from TinyUSB.
// Tick disable can happen via auto-reload so poke the main task here.
xTaskNotifyGive(circuitpython_task);
} }
void sleep_timer_cb(void* arg) { void sleep_timer_cb(void* arg) {

View File

@ -68,10 +68,12 @@ void mp_obj_print_helper(const mp_print_t *print, mp_obj_t o_in, mp_print_kind_t
#ifdef RUN_BACKGROUND_TASKS #ifdef RUN_BACKGROUND_TASKS
RUN_BACKGROUND_TASKS; RUN_BACKGROUND_TASKS;
#endif #endif
#if MICROPY_KBD_EXCEPTION
// Stop printing if we've been interrupted. // Stop printing if we've been interrupted.
if (mp_hal_is_interrupted()) { if (mp_hal_is_interrupted()) {
return; return;
} }
#endif
#ifndef NDEBUG #ifndef NDEBUG
if (o_in == MP_OBJ_NULL) { if (o_in == MP_OBJ_NULL) {

View File

@ -71,8 +71,8 @@
void validate_objs_are_alarms(size_t n_args, const mp_obj_t *objs) { void validate_objs_are_alarms(size_t n_args, const mp_obj_t *objs) {
for (size_t i = 0; i < n_args; i++) { for (size_t i = 0; i < n_args; i++) {
if (MP_OBJ_IS_TYPE(objs[i], &alarm_pin_pin_alarm_type) || if (MP_OBJ_IS_TYPE(objs[i], &alarm_pin_pinalarm_type) ||
MP_OBJ_IS_TYPE(objs[i], &alarm_time_time_alarm_type)) { MP_OBJ_IS_TYPE(objs[i], &alarm_time_timealarm_type)) {
continue; continue;
} }
mp_raise_TypeError_varg(translate("Expected an alarm")); mp_raise_TypeError_varg(translate("Expected an alarm"));
@ -159,7 +159,7 @@ MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(alarm_exit_and_deep_sleep_until_alarms_obj,
STATIC const mp_map_elem_t alarm_pin_globals_table[] = { STATIC const mp_map_elem_t alarm_pin_globals_table[] = {
{ MP_ROM_QSTR(MP_QSTR___name__), MP_ROM_QSTR(MP_QSTR_pin) }, { MP_ROM_QSTR(MP_QSTR___name__), MP_ROM_QSTR(MP_QSTR_pin) },
{ MP_ROM_QSTR(MP_QSTR_PinAlarm), MP_OBJ_FROM_PTR(&alarm_pin_pin_alarm_type) }, { MP_ROM_QSTR(MP_QSTR_PinAlarm), MP_OBJ_FROM_PTR(&alarm_pin_pinalarm_type) },
}; };
STATIC MP_DEFINE_CONST_DICT(alarm_pin_globals, alarm_pin_globals_table); STATIC MP_DEFINE_CONST_DICT(alarm_pin_globals, alarm_pin_globals_table);
@ -172,7 +172,7 @@ STATIC const mp_obj_module_t alarm_pin_module = {
STATIC const mp_map_elem_t alarm_time_globals_table[] = { STATIC const mp_map_elem_t alarm_time_globals_table[] = {
{ MP_ROM_QSTR(MP_QSTR___name__), MP_ROM_QSTR(MP_QSTR_time) }, { MP_ROM_QSTR(MP_QSTR___name__), MP_ROM_QSTR(MP_QSTR_time) },
{ MP_ROM_QSTR(MP_QSTR_TimeAlarm), MP_OBJ_FROM_PTR(&alarm_time_time_alarm_type) }, { MP_ROM_QSTR(MP_QSTR_TimeAlarm), MP_OBJ_FROM_PTR(&alarm_time_timealarm_type) },
}; };
STATIC MP_DEFINE_CONST_DICT(alarm_time_globals, alarm_time_globals_table); STATIC MP_DEFINE_CONST_DICT(alarm_time_globals, alarm_time_globals_table);
@ -199,7 +199,7 @@ STATIC mp_map_elem_t alarm_module_globals_table[] = {
{ MP_ROM_QSTR(MP_QSTR_SleepMemory), MP_OBJ_FROM_PTR(&alarm_sleep_memory_type) }, { MP_ROM_QSTR(MP_QSTR_SleepMemory), MP_OBJ_FROM_PTR(&alarm_sleep_memory_type) },
{ MP_ROM_QSTR(MP_QSTR_sleep_memory), MP_OBJ_FROM_PTR(&alarm_sleep_memory_obj) }, { MP_ROM_QSTR(MP_QSTR_sleep_memory), MP_OBJ_FROM_PTR(&alarm_sleep_memory_obj) },
}; };
MP_DEFINE_MUTABLE_DICT(alarm_module_globals, alarm_module_globals_table); STATIC MP_DEFINE_MUTABLE_DICT(alarm_module_globals, alarm_module_globals_table);
// Fetch value from module dict. // Fetch value from module dict.
mp_obj_t alarm_get_wake_alarm(void) { mp_obj_t alarm_get_wake_alarm(void) {

View File

@ -31,9 +31,6 @@
#include "common-hal/alarm/__init__.h" #include "common-hal/alarm/__init__.h"
// Make module dict available elsewhere, so we can fetch
extern mp_obj_dict_t alarm_module_globals;
extern mp_obj_t common_hal_alarm_light_sleep_until_alarms(size_t n_alarms, const mp_obj_t *alarms); extern mp_obj_t common_hal_alarm_light_sleep_until_alarms(size_t n_alarms, const mp_obj_t *alarms);
// Deep sleep is a two step process. Alarms are set when the VM is valid but // Deep sleep is a two step process. Alarms are set when the VM is valid but

View File

@ -60,9 +60,9 @@
//| """ //| """
//| ... //| ...
//| //|
STATIC mp_obj_t alarm_pin_pin_alarm_make_new(const mp_obj_type_t *type, mp_uint_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) { STATIC mp_obj_t alarm_pin_pinalarm_make_new(const mp_obj_type_t *type, mp_uint_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) {
alarm_pin_pin_alarm_obj_t *self = m_new_obj(alarm_pin_pin_alarm_obj_t); alarm_pin_pinalarm_obj_t *self = m_new_obj(alarm_pin_pinalarm_obj_t);
self->base.type = &alarm_pin_pin_alarm_type; self->base.type = &alarm_pin_pinalarm_type;
enum { ARG_pin, ARG_value, ARG_edge, ARG_pull }; enum { ARG_pin, ARG_value, ARG_edge, ARG_pull };
static const mp_arg_t allowed_args[] = { static const mp_arg_t allowed_args[] = {
{ MP_QSTR_pin, MP_ARG_REQUIRED | MP_ARG_OBJ }, { MP_QSTR_pin, MP_ARG_REQUIRED | MP_ARG_OBJ },
@ -75,7 +75,7 @@ STATIC mp_obj_t alarm_pin_pin_alarm_make_new(const mp_obj_type_t *type, mp_uint_
mcu_pin_obj_t *pin = validate_obj_is_free_pin(args[ARG_pin].u_obj); mcu_pin_obj_t *pin = validate_obj_is_free_pin(args[ARG_pin].u_obj);
common_hal_alarm_pin_pin_alarm_construct(self, common_hal_alarm_pin_pinalarm_construct(self,
pin, pin,
args[ARG_value].u_bool, args[ARG_value].u_bool,
args[ARG_edge].u_bool, args[ARG_edge].u_bool,
@ -87,19 +87,19 @@ STATIC mp_obj_t alarm_pin_pin_alarm_make_new(const mp_obj_type_t *type, mp_uint_
//| pin: microcontroller.Pin //| pin: microcontroller.Pin
//| """The trigger pin.""" //| """The trigger pin."""
//| //|
STATIC mp_obj_t alarm_pin_pin_alarm_obj_get_pin(mp_obj_t self_in) { STATIC mp_obj_t alarm_pin_pinalarm_obj_get_pin(mp_obj_t self_in) {
alarm_pin_pin_alarm_obj_t *self = MP_OBJ_TO_PTR(self_in); alarm_pin_pinalarm_obj_t *self = MP_OBJ_TO_PTR(self_in);
mcu_pin_obj_t* pin = common_hal_alarm_pin_pin_alarm_get_pin(self); mcu_pin_obj_t* pin = common_hal_alarm_pin_pinalarm_get_pin(self);
if (pin == NULL) { if (pin == NULL) {
return mp_const_none; return mp_const_none;
} }
return MP_OBJ_FROM_PTR(pin); return MP_OBJ_FROM_PTR(pin);
} }
MP_DEFINE_CONST_FUN_OBJ_1(alarm_pin_pin_alarm_get_pin_obj, alarm_pin_pin_alarm_obj_get_pin); MP_DEFINE_CONST_FUN_OBJ_1(alarm_pin_pinalarm_get_pin_obj, alarm_pin_pinalarm_obj_get_pin);
const mp_obj_property_t alarm_pin_pin_alarm_pin_obj = { const mp_obj_property_t alarm_pin_pinalarm_pin_obj = {
.base.type = &mp_type_property, .base.type = &mp_type_property,
.proxy = {(mp_obj_t)&alarm_pin_pin_alarm_get_pin_obj, .proxy = {(mp_obj_t)&alarm_pin_pinalarm_get_pin_obj,
(mp_obj_t)&mp_const_none_obj, (mp_obj_t)&mp_const_none_obj,
(mp_obj_t)&mp_const_none_obj}, (mp_obj_t)&mp_const_none_obj},
}; };
@ -107,29 +107,29 @@ const mp_obj_property_t alarm_pin_pin_alarm_pin_obj = {
//| value: bool //| value: bool
//| """The value on which to trigger.""" //| """The value on which to trigger."""
//| //|
STATIC mp_obj_t alarm_pin_pin_alarm_obj_get_value(mp_obj_t self_in) { STATIC mp_obj_t alarm_pin_pinalarm_obj_get_value(mp_obj_t self_in) {
alarm_pin_pin_alarm_obj_t *self = MP_OBJ_TO_PTR(self_in); alarm_pin_pinalarm_obj_t *self = MP_OBJ_TO_PTR(self_in);
return mp_obj_new_bool(common_hal_alarm_pin_pin_alarm_get_value(self)); return mp_obj_new_bool(common_hal_alarm_pin_pinalarm_get_value(self));
} }
MP_DEFINE_CONST_FUN_OBJ_1(alarm_pin_pin_alarm_get_value_obj, alarm_pin_pin_alarm_obj_get_value); MP_DEFINE_CONST_FUN_OBJ_1(alarm_pin_pinalarm_get_value_obj, alarm_pin_pinalarm_obj_get_value);
const mp_obj_property_t alarm_pin_pin_alarm_value_obj = { const mp_obj_property_t alarm_pin_pinalarm_value_obj = {
.base.type = &mp_type_property, .base.type = &mp_type_property,
.proxy = {(mp_obj_t)&alarm_pin_pin_alarm_get_value_obj, .proxy = {(mp_obj_t)&alarm_pin_pinalarm_get_value_obj,
(mp_obj_t)&mp_const_none_obj, (mp_obj_t)&mp_const_none_obj,
(mp_obj_t)&mp_const_none_obj}, (mp_obj_t)&mp_const_none_obj},
}; };
STATIC const mp_rom_map_elem_t alarm_pin_pin_alarm_locals_dict_table[] = { STATIC const mp_rom_map_elem_t alarm_pin_pinalarm_locals_dict_table[] = {
{ MP_ROM_QSTR(MP_QSTR_pin), MP_ROM_PTR(&alarm_pin_pin_alarm_pin_obj) }, { MP_ROM_QSTR(MP_QSTR_pin), MP_ROM_PTR(&alarm_pin_pinalarm_pin_obj) },
{ MP_ROM_QSTR(MP_QSTR_value), MP_ROM_PTR(&alarm_pin_pin_alarm_value_obj) }, { MP_ROM_QSTR(MP_QSTR_value), MP_ROM_PTR(&alarm_pin_pinalarm_value_obj) },
}; };
STATIC MP_DEFINE_CONST_DICT(alarm_pin_pin_alarm_locals_dict, alarm_pin_pin_alarm_locals_dict_table); STATIC MP_DEFINE_CONST_DICT(alarm_pin_pinalarm_locals_dict, alarm_pin_pinalarm_locals_dict_table);
const mp_obj_type_t alarm_pin_pin_alarm_type = { const mp_obj_type_t alarm_pin_pinalarm_type = {
{ &mp_type_type }, { &mp_type_type },
.name = MP_QSTR_PinAlarm, .name = MP_QSTR_PinAlarm,
.make_new = alarm_pin_pin_alarm_make_new, .make_new = alarm_pin_pinalarm_make_new,
.locals_dict = (mp_obj_t)&alarm_pin_pin_alarm_locals_dict, .locals_dict = (mp_obj_t)&alarm_pin_pinalarm_locals_dict,
}; };

View File

@ -24,20 +24,20 @@
* THE SOFTWARE. * THE SOFTWARE.
*/ */
#ifndef MICROPY_INCLUDED_SHARED_BINDINGS_ALARM_PIN_PIN_ALARM_H #ifndef MICROPY_INCLUDED_SHARED_BINDINGS_ALARM_PIN_PINALARM_H
#define MICROPY_INCLUDED_SHARED_BINDINGS_ALARM_PIN_PIN_ALARM_H #define MICROPY_INCLUDED_SHARED_BINDINGS_ALARM_PIN_PINALARM_H
#include "py/obj.h" #include "py/obj.h"
#include "py/objtuple.h" #include "py/objtuple.h"
#include "common-hal/microcontroller/Pin.h" #include "common-hal/microcontroller/Pin.h"
#include "common-hal/alarm/pin/PinAlarm.h" #include "common-hal/alarm/pin/PinAlarm.h"
extern const mp_obj_type_t alarm_pin_pin_alarm_type; extern const mp_obj_type_t alarm_pin_pinalarm_type;
void common_hal_alarm_pin_pin_alarm_construct(alarm_pin_pin_alarm_obj_t *self, mcu_pin_obj_t *pin, bool value, bool edge, bool pull); void common_hal_alarm_pin_pinalarm_construct(alarm_pin_pinalarm_obj_t *self, mcu_pin_obj_t *pin, bool value, bool edge, bool pull);
extern mcu_pin_obj_t *common_hal_alarm_pin_pin_alarm_get_pin(alarm_pin_pin_alarm_obj_t *self); extern mcu_pin_obj_t *common_hal_alarm_pin_pinalarm_get_pin(alarm_pin_pinalarm_obj_t *self);
extern bool common_hal_alarm_pin_pin_alarm_get_value(alarm_pin_pin_alarm_obj_t *self); extern bool common_hal_alarm_pin_pinalarm_get_value(alarm_pin_pinalarm_obj_t *self);
extern bool common_hal_alarm_pin_pin_alarm_get_edge(alarm_pin_pin_alarm_obj_t *self); extern bool common_hal_alarm_pin_pinalarm_get_edge(alarm_pin_pinalarm_obj_t *self);
extern bool common_hal_alarm_pin_pin_alarm_get_pull(alarm_pin_pin_alarm_obj_t *self); extern bool common_hal_alarm_pin_pinalarm_get_pull(alarm_pin_pinalarm_obj_t *self);
#endif // MICROPY_INCLUDED_SHARED_BINDINGS_ALARM_PIN_PIN_ALARM_H #endif // MICROPY_INCLUDED_SHARED_BINDINGS_ALARM_PIN_PINALARM_H

View File

@ -56,10 +56,10 @@ mp_obj_t MP_WEAK rtc_get_time_source_time(void) {
//| """ //| """
//| ... //| ...
//| //|
STATIC mp_obj_t alarm_time_time_alarm_make_new(const mp_obj_type_t *type, STATIC mp_obj_t alarm_time_timealarm_make_new(const mp_obj_type_t *type,
mp_uint_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) { mp_uint_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) {
alarm_time_time_alarm_obj_t *self = m_new_obj(alarm_time_time_alarm_obj_t); alarm_time_timealarm_obj_t *self = m_new_obj(alarm_time_timealarm_obj_t);
self->base.type = &alarm_time_time_alarm_type; self->base.type = &alarm_time_timealarm_type;
enum { ARG_monotonic_time, ARG_epoch_time }; enum { ARG_monotonic_time, ARG_epoch_time };
static const mp_arg_t allowed_args[] = { static const mp_arg_t allowed_args[] = {
@ -105,7 +105,7 @@ STATIC mp_obj_t alarm_time_time_alarm_make_new(const mp_obj_type_t *type,
mp_raise_ValueError(translate("Time is in the past.")); mp_raise_ValueError(translate("Time is in the past."));
} }
common_hal_alarm_time_time_alarm_construct(self, monotonic_time); common_hal_alarm_time_timealarm_construct(self, monotonic_time);
return MP_OBJ_FROM_PTR(self); return MP_OBJ_FROM_PTR(self);
} }
@ -116,28 +116,28 @@ STATIC mp_obj_t alarm_time_time_alarm_make_new(const mp_obj_type_t *type,
//| by this property only as a `time.monotonic()` time. //| by this property only as a `time.monotonic()` time.
//| """ //| """
//| //|
STATIC mp_obj_t alarm_time_time_alarm_obj_get_monotonic_time(mp_obj_t self_in) { STATIC mp_obj_t alarm_time_timealarm_obj_get_monotonic_time(mp_obj_t self_in) {
alarm_time_time_alarm_obj_t *self = MP_OBJ_TO_PTR(self_in); alarm_time_timealarm_obj_t *self = MP_OBJ_TO_PTR(self_in);
return mp_obj_new_float(common_hal_alarm_time_time_alarm_get_monotonic_time(self)); return mp_obj_new_float(common_hal_alarm_time_timealarm_get_monotonic_time(self));
} }
MP_DEFINE_CONST_FUN_OBJ_1(alarm_time_time_alarm_get_monotonic_time_obj, alarm_time_time_alarm_obj_get_monotonic_time); MP_DEFINE_CONST_FUN_OBJ_1(alarm_time_timealarm_get_monotonic_time_obj, alarm_time_timealarm_obj_get_monotonic_time);
const mp_obj_property_t alarm_time_time_alarm_monotonic_time_obj = { const mp_obj_property_t alarm_time_timealarm_monotonic_time_obj = {
.base.type = &mp_type_property, .base.type = &mp_type_property,
.proxy = {(mp_obj_t)&alarm_time_time_alarm_get_monotonic_time_obj, .proxy = {(mp_obj_t)&alarm_time_timealarm_get_monotonic_time_obj,
(mp_obj_t)&mp_const_none_obj, (mp_obj_t)&mp_const_none_obj,
(mp_obj_t)&mp_const_none_obj}, (mp_obj_t)&mp_const_none_obj},
}; };
STATIC const mp_rom_map_elem_t alarm_time_time_alarm_locals_dict_table[] = { STATIC const mp_rom_map_elem_t alarm_time_timealarm_locals_dict_table[] = {
{ MP_ROM_QSTR(MP_QSTR_monotonic_time), MP_ROM_PTR(&alarm_time_time_alarm_monotonic_time_obj) }, { MP_ROM_QSTR(MP_QSTR_monotonic_time), MP_ROM_PTR(&alarm_time_timealarm_monotonic_time_obj) },
}; };
STATIC MP_DEFINE_CONST_DICT(alarm_time_time_alarm_locals_dict, alarm_time_time_alarm_locals_dict_table); STATIC MP_DEFINE_CONST_DICT(alarm_time_timealarm_locals_dict, alarm_time_timealarm_locals_dict_table);
const mp_obj_type_t alarm_time_time_alarm_type = { const mp_obj_type_t alarm_time_timealarm_type = {
{ &mp_type_type }, { &mp_type_type },
.name = MP_QSTR_TimeAlarm, .name = MP_QSTR_TimeAlarm,
.make_new = alarm_time_time_alarm_make_new, .make_new = alarm_time_timealarm_make_new,
.locals_dict = (mp_obj_t)&alarm_time_time_alarm_locals_dict, .locals_dict = (mp_obj_t)&alarm_time_timealarm_locals_dict,
}; };

View File

@ -24,16 +24,16 @@
* THE SOFTWARE. * THE SOFTWARE.
*/ */
#ifndef MICROPY_INCLUDED_SHARED_BINDINGS_ALARM_TIME_MONOTONIC_TIME_ALARM_H #ifndef MICROPY_INCLUDED_SHARED_BINDINGS_ALARM_TIME_TIMEALARM_H
#define MICROPY_INCLUDED_SHARED_BINDINGS_ALARM_TIME_MONOTINIC_TIME_ALARM_H #define MICROPY_INCLUDED_SHARED_BINDINGS_ALARM_TIME_TIMEALARM_H
#include "py/obj.h" #include "py/obj.h"
#include "common-hal/alarm/time/TimeAlarm.h" #include "common-hal/alarm/time/TimeAlarm.h"
extern const mp_obj_type_t alarm_time_time_alarm_type; extern const mp_obj_type_t alarm_time_timealarm_type;
extern void common_hal_alarm_time_time_alarm_construct(alarm_time_time_alarm_obj_t *self, mp_float_t monotonic_time); extern void common_hal_alarm_time_timealarm_construct(alarm_time_timealarm_obj_t *self, mp_float_t monotonic_time);
extern mp_float_t common_hal_alarm_time_time_alarm_get_monotonic_time(alarm_time_time_alarm_obj_t *self); extern mp_float_t common_hal_alarm_time_timealarm_get_monotonic_time(alarm_time_timealarm_obj_t *self);
#endif // MICROPY_INCLUDED_SHARED_BINDINGS_ALARM_TIME_MONOTONIC_TIME_ALARM_H #endif // MICROPY_INCLUDED_SHARED_BINDINGS_ALARM_TIME_TIMEALARM_H