From 90b9ec6f2ce840885492f125f8c473df8bd67337 Mon Sep 17 00:00:00 2001 From: microDev <70126934+microDev1@users.noreply.github.com> Date: Fri, 18 Sep 2020 17:40:49 +0530 Subject: [PATCH 01/34] Initial Sleep Support --- .../common-hal/microcontroller/__init__.c | 6 ++++ ports/esp32s2/common-hal/timealarm/__init__.c | 10 ++++++ ports/esp32s2/mpconfigport.mk | 1 + py/circuitpy_defns.mk | 4 +++ py/circuitpy_mpconfig.h | 8 +++++ py/circuitpy_mpconfig.mk | 3 ++ shared-bindings/microcontroller/__init__.c | 17 ++++++++++ shared-bindings/microcontroller/__init__.h | 2 ++ shared-bindings/timealarm/__init__.c | 31 +++++++++++++++++++ shared-bindings/timealarm/__init__.h | 8 +++++ 10 files changed, 90 insertions(+) create mode 100644 ports/esp32s2/common-hal/timealarm/__init__.c create mode 100644 shared-bindings/timealarm/__init__.c create mode 100644 shared-bindings/timealarm/__init__.h diff --git a/ports/esp32s2/common-hal/microcontroller/__init__.c b/ports/esp32s2/common-hal/microcontroller/__init__.c index 6b2e18673d..2fcc2ceda1 100644 --- a/ports/esp32s2/common-hal/microcontroller/__init__.c +++ b/ports/esp32s2/common-hal/microcontroller/__init__.c @@ -41,6 +41,8 @@ #include "freertos/FreeRTOS.h" +#include "esp_sleep.h" + void common_hal_mcu_delay_us(uint32_t delay) { } @@ -77,6 +79,10 @@ void common_hal_mcu_reset(void) { while(1); } +void common_hal_mcu_sleep(void) { + esp_deep_sleep_start(); +} + // The singleton microcontroller.Processor object, bound to microcontroller.cpu // It currently only has properties, and no state. const mcu_processor_obj_t common_hal_mcu_processor_obj = { diff --git a/ports/esp32s2/common-hal/timealarm/__init__.c b/ports/esp32s2/common-hal/timealarm/__init__.c new file mode 100644 index 0000000000..e404f801a6 --- /dev/null +++ b/ports/esp32s2/common-hal/timealarm/__init__.c @@ -0,0 +1,10 @@ +#include "esp_sleep.h" + +#include "shared-bindings/timealarm/__init__.h" + +void common_hal_timealarm_duration (uint32_t ms) { + if (esp_sleep_enable_timer_wakeup((ms) * 1000) == ESP_ERR_INVALID_ARG) { + mp_raise_ValueError(translate("time out of range")); + } +} + diff --git a/ports/esp32s2/mpconfigport.mk b/ports/esp32s2/mpconfigport.mk index c06c89c909..125d078e8a 100644 --- a/ports/esp32s2/mpconfigport.mk +++ b/ports/esp32s2/mpconfigport.mk @@ -22,6 +22,7 @@ CIRCUITPY_FREQUENCYIO = 0 CIRCUITPY_I2CPERIPHERAL = 0 CIRCUITPY_ROTARYIO = 0 CIRCUITPY_NVM = 0 +CIRCUITPY_TIMEALARM = 1 # We don't have enough endpoints to include MIDI. CIRCUITPY_USB_MIDI = 0 CIRCUITPY_WIFI = 1 diff --git a/py/circuitpy_defns.mk b/py/circuitpy_defns.mk index ccdf973e9f..91af6ffc15 100644 --- a/py/circuitpy_defns.mk +++ b/py/circuitpy_defns.mk @@ -259,6 +259,9 @@ endif ifeq ($(CIRCUITPY_TIME),1) SRC_PATTERNS += time/% endif +ifeq ($(CIRCUITPY_TIMEALARM),1) +SRC_PATTERNS += timealarm/% +endif ifeq ($(CIRCUITPY_TOUCHIO),1) SRC_PATTERNS += touchio/% endif @@ -360,6 +363,7 @@ SRC_COMMON_HAL_ALL = \ ssl/SSLContext.c \ supervisor/Runtime.c \ supervisor/__init__.c \ + timealarm/__init__.c \ watchdog/WatchDogMode.c \ watchdog/WatchDogTimer.c \ watchdog/__init__.c \ diff --git a/py/circuitpy_mpconfig.h b/py/circuitpy_mpconfig.h index 1e01bd9c5e..8efd439212 100644 --- a/py/circuitpy_mpconfig.h +++ b/py/circuitpy_mpconfig.h @@ -663,6 +663,13 @@ extern const struct _mp_obj_module_t time_module; #define TIME_MODULE_ALT_NAME #endif +#if CIRCUITPY_TIMEALARM +extern const struct _mp_obj_module_t timealarm_module; +#define TIMEALARM_MODULE { MP_OBJ_NEW_QSTR(MP_QSTR_timealarm), (mp_obj_t)&timealarm_module }, +#else +#define TIMEALARM_MODULE +#endif + #if CIRCUITPY_TOUCHIO extern const struct _mp_obj_module_t touchio_module; #define TOUCHIO_MODULE { MP_OBJ_NEW_QSTR(MP_QSTR_touchio), (mp_obj_t)&touchio_module }, @@ -821,6 +828,7 @@ extern const struct _mp_obj_module_t wifi_module; STRUCT_MODULE \ SUPERVISOR_MODULE \ TOUCHIO_MODULE \ + TIMEALARM_MODULE \ UHEAP_MODULE \ USB_HID_MODULE \ USB_MIDI_MODULE \ diff --git a/py/circuitpy_mpconfig.mk b/py/circuitpy_mpconfig.mk index a6aabec33d..bb70daccc7 100644 --- a/py/circuitpy_mpconfig.mk +++ b/py/circuitpy_mpconfig.mk @@ -234,6 +234,9 @@ CFLAGS += -DCIRCUITPY_TERMINALIO=$(CIRCUITPY_TERMINALIO) CIRCUITPY_TIME ?= 1 CFLAGS += -DCIRCUITPY_TIME=$(CIRCUITPY_TIME) +CIRCUITPY_TIMEALARM ?= 0 +CFLAGS += -DCIRCUITPY_TIMEALARM=$(CIRCUITPY_TIMEALARM) + # touchio might be native or generic. See circuitpy_defns.mk. CIRCUITPY_TOUCHIO_USE_NATIVE ?= 0 CFLAGS += -DCIRCUITPY_TOUCHIO_USE_NATIVE=$(CIRCUITPY_TOUCHIO_USE_NATIVE) diff --git a/shared-bindings/microcontroller/__init__.c b/shared-bindings/microcontroller/__init__.c index 2e58bdcc29..b8ca8f18ba 100644 --- a/shared-bindings/microcontroller/__init__.c +++ b/shared-bindings/microcontroller/__init__.c @@ -136,6 +136,22 @@ STATIC mp_obj_t mcu_reset(void) { } STATIC MP_DEFINE_CONST_FUN_OBJ_0(mcu_reset_obj, mcu_reset); +//| def sleep() -> None: +//| """Microcontroller will go into deep sleep. +//| cpy will restart when wakeup func. is triggered`. +//| +//| .. warning:: This may result in file system corruption when connected to a +//| host computer. Be very careful when calling this! Make sure the device +//| "Safely removed" on Windows or "ejected" on Mac OSX and Linux.""" +//| ... +//| +STATIC mp_obj_t mcu_sleep(void) { + common_hal_mcu_sleep(); + // We won't actually get here because mcu is going into sleep. + return mp_const_none; +} +STATIC MP_DEFINE_CONST_FUN_OBJ_0(mcu_sleep_obj, mcu_sleep); + //| nvm: Optional[ByteArray] //| """Available non-volatile memory. //| This object is the sole instance of `nvm.ByteArray` when available or ``None`` otherwise. @@ -171,6 +187,7 @@ STATIC const mp_rom_map_elem_t mcu_module_globals_table[] = { { MP_ROM_QSTR(MP_QSTR_enable_interrupts), MP_ROM_PTR(&mcu_enable_interrupts_obj) }, { MP_ROM_QSTR(MP_QSTR_on_next_reset), MP_ROM_PTR(&mcu_on_next_reset_obj) }, { MP_ROM_QSTR(MP_QSTR_reset), MP_ROM_PTR(&mcu_reset_obj) }, + { MP_ROM_QSTR(MP_QSTR_sleep), MP_ROM_PTR(&mcu_sleep_obj) }, #if CIRCUITPY_INTERNAL_NVM_SIZE > 0 { MP_ROM_QSTR(MP_QSTR_nvm), MP_ROM_PTR(&common_hal_mcu_nvm_obj) }, #else diff --git a/shared-bindings/microcontroller/__init__.h b/shared-bindings/microcontroller/__init__.h index 8abdff763c..b0f61e64b9 100644 --- a/shared-bindings/microcontroller/__init__.h +++ b/shared-bindings/microcontroller/__init__.h @@ -43,6 +43,8 @@ extern void common_hal_mcu_enable_interrupts(void); extern void common_hal_mcu_on_next_reset(mcu_runmode_t runmode); extern void common_hal_mcu_reset(void); +extern void common_hal_mcu_sleep(void); + extern const mp_obj_dict_t mcu_pin_globals; extern const mcu_processor_obj_t common_hal_mcu_processor_obj; diff --git a/shared-bindings/timealarm/__init__.c b/shared-bindings/timealarm/__init__.c new file mode 100644 index 0000000000..19fb4f093a --- /dev/null +++ b/shared-bindings/timealarm/__init__.c @@ -0,0 +1,31 @@ +#include "py/obj.h" +#include "shared-bindings/timealarm/__init__.h" + +//| Set Timer Wakeup +//| +STATIC mp_obj_t timealarm_duration(mp_obj_t seconds_o) { + #if MICROPY_PY_BUILTINS_FLOAT + mp_float_t seconds = mp_obj_get_float(seconds_o); + mp_float_t msecs = 1000.0f * seconds + 0.5f; + #else + mp_int_t seconds = mp_obj_get_int(seconds_o); + mp_int_t msecs = 1000 * seconds; + #endif + if (seconds < 0) { + mp_raise_ValueError(translate("sleep length must be non-negative")); + } + common_hal_timealarm_duration(msecs); + return mp_const_none; +} +STATIC MP_DEFINE_CONST_FUN_OBJ_1(timealarm_duration_obj, timealarm_duration); + +STATIC const mp_rom_map_elem_t timealarm_module_globals_table[] = { + { MP_ROM_QSTR(MP_QSTR___name__), MP_ROM_QSTR(MP_QSTR_timealarm) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_duration), MP_ROM_PTR(&timealarm_duration_obj) }, +}; +STATIC MP_DEFINE_CONST_DICT(timealarm_module_globals, timealarm_module_globals_table); + +const mp_obj_module_t timealarm_module = { + .base = { &mp_type_module }, + .globals = (mp_obj_dict_t*)&timealarm_module_globals, +}; diff --git a/shared-bindings/timealarm/__init__.h b/shared-bindings/timealarm/__init__.h new file mode 100644 index 0000000000..b70cbda1f2 --- /dev/null +++ b/shared-bindings/timealarm/__init__.h @@ -0,0 +1,8 @@ +#ifndef MICROPY_INCLUDED_SHARED_BINDINGS_ulp___INIT___H +#define MICROPY_INCLUDED_SHARED_BINDINGS_ulp___INIT___H + +#include "py/runtime.h" + +extern void common_hal_timealarm_duration(uint32_t); + +#endif \ No newline at end of file From 3a30887b444c6c17f116abd85308251486c9dfe9 Mon Sep 17 00:00:00 2001 From: microDev <70126934+microDev1@users.noreply.github.com> Date: Fri, 18 Sep 2020 17:59:18 +0530 Subject: [PATCH 02/34] Update soft reboot message --- main.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/main.c b/main.c index b43b3b8c80..ebce8cd403 100755 --- a/main.c +++ b/main.c @@ -509,7 +509,7 @@ int __attribute__((used)) main(void) { } if (exit_code == PYEXEC_FORCED_EXIT) { if (!first_run) { - serial_write_compressed(translate("soft reboot\n")); + serial_write_compressed(translate("\n\n ----- soft reboot -----\n")); } first_run = false; skip_repl = run_code_py(safe_mode); From e310b871c8eb8cf924e6937edc7cd51a2be1a6b7 Mon Sep 17 00:00:00 2001 From: microDev <70126934+microDev1@users.noreply.github.com> Date: Sat, 19 Sep 2020 17:48:36 +0530 Subject: [PATCH 03/34] Get io wake working --- main.c | 2 +- ports/esp32s2/common-hal/io_alarm/__init__.c | 27 +++++++++++++++ .../{timealarm => time_alarm}/__init__.c | 4 +-- ports/esp32s2/mpconfigport.mk | 3 +- py/circuitpy_defns.mk | 10 ++++-- py/circuitpy_mpconfig.h | 18 +++++++--- py/circuitpy_mpconfig.mk | 7 ++-- shared-bindings/io_alarm/__init__.c | 34 +++++++++++++++++++ shared-bindings/io_alarm/__init__.h | 8 +++++ shared-bindings/time_alarm/__init__.c | 31 +++++++++++++++++ shared-bindings/time_alarm/__init__.h | 8 +++++ shared-bindings/timealarm/__init__.c | 31 ----------------- shared-bindings/timealarm/__init__.h | 8 ----- 13 files changed, 138 insertions(+), 53 deletions(-) create mode 100644 ports/esp32s2/common-hal/io_alarm/__init__.c rename ports/esp32s2/common-hal/{timealarm => time_alarm}/__init__.c (63%) create mode 100644 shared-bindings/io_alarm/__init__.c create mode 100644 shared-bindings/io_alarm/__init__.h create mode 100644 shared-bindings/time_alarm/__init__.c create mode 100644 shared-bindings/time_alarm/__init__.h delete mode 100644 shared-bindings/timealarm/__init__.c delete mode 100644 shared-bindings/timealarm/__init__.h diff --git a/main.c b/main.c index ebce8cd403..5a30f4bb26 100755 --- a/main.c +++ b/main.c @@ -509,7 +509,7 @@ int __attribute__((used)) main(void) { } if (exit_code == PYEXEC_FORCED_EXIT) { if (!first_run) { - serial_write_compressed(translate("\n\n ----- soft reboot -----\n")); + serial_write_compressed(translate("\n\n------ soft reboot ------\n")); } first_run = false; skip_repl = run_code_py(safe_mode); diff --git a/ports/esp32s2/common-hal/io_alarm/__init__.c b/ports/esp32s2/common-hal/io_alarm/__init__.c new file mode 100644 index 0000000000..d88c147fe0 --- /dev/null +++ b/ports/esp32s2/common-hal/io_alarm/__init__.c @@ -0,0 +1,27 @@ +#include "shared-bindings/io_alarm/__init__.h" + +#include "esp_sleep.h" +#include "driver/rtc_io.h" + +void common_hal_io_alarm_pin_state (uint8_t gpio, uint8_t level, bool pull) { + if (!rtc_gpio_is_valid_gpio(gpio)) { + mp_raise_ValueError(translate("io must be rtc io")); + return; + } + + switch(esp_sleep_enable_ext0_wakeup(gpio, level)) { + case ESP_ERR_INVALID_ARG: + mp_raise_ValueError(translate("trigger level must be 0 or 1")); + return; + case ESP_ERR_INVALID_STATE: + mp_raise_RuntimeError(translate("wakeup conflict")); + return; + default: + break; + } + + if (pull) { + (level) ? rtc_gpio_pulldown_en(gpio) : rtc_gpio_pullup_en(gpio); + } +} + diff --git a/ports/esp32s2/common-hal/timealarm/__init__.c b/ports/esp32s2/common-hal/time_alarm/__init__.c similarity index 63% rename from ports/esp32s2/common-hal/timealarm/__init__.c rename to ports/esp32s2/common-hal/time_alarm/__init__.c index e404f801a6..342ca9d154 100644 --- a/ports/esp32s2/common-hal/timealarm/__init__.c +++ b/ports/esp32s2/common-hal/time_alarm/__init__.c @@ -1,8 +1,8 @@ #include "esp_sleep.h" -#include "shared-bindings/timealarm/__init__.h" +#include "shared-bindings/time_alarm/__init__.h" -void common_hal_timealarm_duration (uint32_t ms) { +void common_hal_time_alarm_duration (uint32_t ms) { if (esp_sleep_enable_timer_wakeup((ms) * 1000) == ESP_ERR_INVALID_ARG) { mp_raise_ValueError(translate("time out of range")); } diff --git a/ports/esp32s2/mpconfigport.mk b/ports/esp32s2/mpconfigport.mk index 125d078e8a..0f8f3ada53 100644 --- a/ports/esp32s2/mpconfigport.mk +++ b/ports/esp32s2/mpconfigport.mk @@ -22,7 +22,8 @@ CIRCUITPY_FREQUENCYIO = 0 CIRCUITPY_I2CPERIPHERAL = 0 CIRCUITPY_ROTARYIO = 0 CIRCUITPY_NVM = 0 -CIRCUITPY_TIMEALARM = 1 +CIRCUITPY_TIME_ALARM = 1 +CIRCUITPY_IO_ALARM = 1 # We don't have enough endpoints to include MIDI. CIRCUITPY_USB_MIDI = 0 CIRCUITPY_WIFI = 1 diff --git a/py/circuitpy_defns.mk b/py/circuitpy_defns.mk index 91af6ffc15..672eeda40c 100644 --- a/py/circuitpy_defns.mk +++ b/py/circuitpy_defns.mk @@ -259,8 +259,11 @@ endif ifeq ($(CIRCUITPY_TIME),1) SRC_PATTERNS += time/% endif -ifeq ($(CIRCUITPY_TIMEALARM),1) -SRC_PATTERNS += timealarm/% +ifeq ($(CIRCUITPY_TIME_ALARM),1) +SRC_PATTERNS += time_alarm/% +endif +ifeq ($(CIRCUITPY_IO_ALARM),1) +SRC_PATTERNS += io_alarm/% endif ifeq ($(CIRCUITPY_TOUCHIO),1) SRC_PATTERNS += touchio/% @@ -363,7 +366,8 @@ SRC_COMMON_HAL_ALL = \ ssl/SSLContext.c \ supervisor/Runtime.c \ supervisor/__init__.c \ - timealarm/__init__.c \ + time_alarm/__init__.c \ + io_alarm/__init__.c \ watchdog/WatchDogMode.c \ watchdog/WatchDogTimer.c \ watchdog/__init__.c \ diff --git a/py/circuitpy_mpconfig.h b/py/circuitpy_mpconfig.h index 8efd439212..d899ecacb6 100644 --- a/py/circuitpy_mpconfig.h +++ b/py/circuitpy_mpconfig.h @@ -663,11 +663,18 @@ extern const struct _mp_obj_module_t time_module; #define TIME_MODULE_ALT_NAME #endif -#if CIRCUITPY_TIMEALARM -extern const struct _mp_obj_module_t timealarm_module; -#define TIMEALARM_MODULE { MP_OBJ_NEW_QSTR(MP_QSTR_timealarm), (mp_obj_t)&timealarm_module }, +#if CIRCUITPY_TIME_ALARM +extern const struct _mp_obj_module_t time_alarm_module; +#define TIME_ALARM_MODULE { MP_OBJ_NEW_QSTR(MP_QSTR_time_alarm), (mp_obj_t)&time_alarm_module }, #else -#define TIMEALARM_MODULE +#define TIME_ALARM_MODULE +#endif + +#if CIRCUITPY_IO_ALARM +extern const struct _mp_obj_module_t io_alarm_module; +#define IO_ALARM_MODULE { MP_OBJ_NEW_QSTR(MP_QSTR_io_alarm), (mp_obj_t)&io_alarm_module }, +#else +#define IO_ALARM_MODULE #endif #if CIRCUITPY_TOUCHIO @@ -828,7 +835,8 @@ extern const struct _mp_obj_module_t wifi_module; STRUCT_MODULE \ SUPERVISOR_MODULE \ TOUCHIO_MODULE \ - TIMEALARM_MODULE \ + TIME_ALARM_MODULE \ + IO_ALARM_MODULE \ UHEAP_MODULE \ USB_HID_MODULE \ USB_MIDI_MODULE \ diff --git a/py/circuitpy_mpconfig.mk b/py/circuitpy_mpconfig.mk index bb70daccc7..4cce2a0a1a 100644 --- a/py/circuitpy_mpconfig.mk +++ b/py/circuitpy_mpconfig.mk @@ -234,8 +234,11 @@ CFLAGS += -DCIRCUITPY_TERMINALIO=$(CIRCUITPY_TERMINALIO) CIRCUITPY_TIME ?= 1 CFLAGS += -DCIRCUITPY_TIME=$(CIRCUITPY_TIME) -CIRCUITPY_TIMEALARM ?= 0 -CFLAGS += -DCIRCUITPY_TIMEALARM=$(CIRCUITPY_TIMEALARM) +CIRCUITPY_TIME_ALARM ?= 0 +CFLAGS += -DCIRCUITPY_TIME_ALARM=$(CIRCUITPY_TIME_ALARM) + +CIRCUITPY_IO_ALARM ?= 0 +CFLAGS += -DCIRCUITPY_IO_ALARM=$(CIRCUITPY_IO_ALARM) # touchio might be native or generic. See circuitpy_defns.mk. CIRCUITPY_TOUCHIO_USE_NATIVE ?= 0 diff --git a/shared-bindings/io_alarm/__init__.c b/shared-bindings/io_alarm/__init__.c new file mode 100644 index 0000000000..534b7e66f5 --- /dev/null +++ b/shared-bindings/io_alarm/__init__.c @@ -0,0 +1,34 @@ +#include "py/obj.h" + +#include "shared-bindings/io_alarm/__init__.h" +#include "shared-bindings/microcontroller/Pin.h" + +//| Set Timer Wakeup +//| +STATIC mp_obj_t io_alarm_pin_state(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) { + enum { ARG_level, ARG_pull }; + static const mp_arg_t allowed_args[] = { + { MP_QSTR_level, MP_ARG_INT | MP_ARG_KW_ONLY | MP_ARG_REQUIRED }, + { MP_QSTR_pull, MP_ARG_INT | MP_ARG_KW_ONLY, {.u_bool = false} }, + }; + + mp_arg_val_t args[MP_ARRAY_SIZE(allowed_args)]; + mp_arg_parse_all(n_args - 1, pos_args + 1, kw_args, MP_ARRAY_SIZE(allowed_args), allowed_args, args); + + mcu_pin_obj_t *pin = validate_obj_is_pin(pos_args[0]); + common_hal_io_alarm_pin_state(pin->number, args[ARG_level].u_int, args[ARG_pull].u_bool); + + return mp_const_none; +} +STATIC MP_DEFINE_CONST_FUN_OBJ_KW(io_alarm_pin_state_obj, 1, io_alarm_pin_state); + +STATIC const mp_rom_map_elem_t io_alarm_module_globals_table[] = { + { MP_ROM_QSTR(MP_QSTR___name__), MP_ROM_QSTR(MP_QSTR_io_alarm) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_PinState), MP_ROM_PTR(&io_alarm_pin_state_obj) }, +}; +STATIC MP_DEFINE_CONST_DICT(io_alarm_module_globals, io_alarm_module_globals_table); + +const mp_obj_module_t io_alarm_module = { + .base = { &mp_type_module }, + .globals = (mp_obj_dict_t*)&io_alarm_module_globals, +}; diff --git a/shared-bindings/io_alarm/__init__.h b/shared-bindings/io_alarm/__init__.h new file mode 100644 index 0000000000..dd4b881657 --- /dev/null +++ b/shared-bindings/io_alarm/__init__.h @@ -0,0 +1,8 @@ +#ifndef MICROPY_INCLUDED_SHARED_BINDINGS_IO_ALARM___INIT___H +#define MICROPY_INCLUDED_SHARED_BINDINGS_IO_ALARM___INIT___H + +#include "py/runtime.h" + +extern void common_hal_io_alarm_pin_state(uint8_t gpio, uint8_t level, bool pull); + +#endif //MICROPY_INCLUDED_SHARED_BINDINGS_IO_ALARM___INIT___H diff --git a/shared-bindings/time_alarm/__init__.c b/shared-bindings/time_alarm/__init__.c new file mode 100644 index 0000000000..bfbece83c0 --- /dev/null +++ b/shared-bindings/time_alarm/__init__.c @@ -0,0 +1,31 @@ +#include "py/obj.h" +#include "shared-bindings/time_alarm/__init__.h" + +//| Set Timer Wakeup +//| +STATIC mp_obj_t time_alarm_duration(mp_obj_t seconds_o) { + #if MICROPY_PY_BUILTINS_FLOAT + mp_float_t seconds = mp_obj_get_float(seconds_o); + mp_float_t msecs = 1000.0f * seconds + 0.5f; + #else + mp_int_t seconds = mp_obj_get_int(seconds_o); + mp_int_t msecs = 1000 * seconds; + #endif + if (seconds < 0) { + mp_raise_ValueError(translate("sleep length must be non-negative")); + } + common_hal_time_alarm_duration(msecs); + return mp_const_none; +} +STATIC MP_DEFINE_CONST_FUN_OBJ_1(time_alarm_duration_obj, time_alarm_duration); + +STATIC const mp_rom_map_elem_t time_alarm_module_globals_table[] = { + { MP_ROM_QSTR(MP_QSTR___name__), MP_ROM_QSTR(MP_QSTR_time_alarm) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_Duration), MP_ROM_PTR(&time_alarm_duration_obj) }, +}; +STATIC MP_DEFINE_CONST_DICT(time_alarm_module_globals, time_alarm_module_globals_table); + +const mp_obj_module_t time_alarm_module = { + .base = { &mp_type_module }, + .globals = (mp_obj_dict_t*)&time_alarm_module_globals, +}; diff --git a/shared-bindings/time_alarm/__init__.h b/shared-bindings/time_alarm/__init__.h new file mode 100644 index 0000000000..0913f7fded --- /dev/null +++ b/shared-bindings/time_alarm/__init__.h @@ -0,0 +1,8 @@ +#ifndef MICROPY_INCLUDED_SHARED_BINDINGS_TIME_ALARM___INIT___H +#define MICROPY_INCLUDED_SHARED_BINDINGS_TIME_ALARM___INIT___H + +#include "py/runtime.h" + +extern void common_hal_time_alarm_duration(uint32_t); + +#endif //MICROPY_INCLUDED_SHARED_BINDINGS_TIME_ALARM___INIT___H diff --git a/shared-bindings/timealarm/__init__.c b/shared-bindings/timealarm/__init__.c deleted file mode 100644 index 19fb4f093a..0000000000 --- a/shared-bindings/timealarm/__init__.c +++ /dev/null @@ -1,31 +0,0 @@ -#include "py/obj.h" -#include "shared-bindings/timealarm/__init__.h" - -//| Set Timer Wakeup -//| -STATIC mp_obj_t timealarm_duration(mp_obj_t seconds_o) { - #if MICROPY_PY_BUILTINS_FLOAT - mp_float_t seconds = mp_obj_get_float(seconds_o); - mp_float_t msecs = 1000.0f * seconds + 0.5f; - #else - mp_int_t seconds = mp_obj_get_int(seconds_o); - mp_int_t msecs = 1000 * seconds; - #endif - if (seconds < 0) { - mp_raise_ValueError(translate("sleep length must be non-negative")); - } - common_hal_timealarm_duration(msecs); - return mp_const_none; -} -STATIC MP_DEFINE_CONST_FUN_OBJ_1(timealarm_duration_obj, timealarm_duration); - -STATIC const mp_rom_map_elem_t timealarm_module_globals_table[] = { - { MP_ROM_QSTR(MP_QSTR___name__), MP_ROM_QSTR(MP_QSTR_timealarm) }, - { MP_OBJ_NEW_QSTR(MP_QSTR_duration), MP_ROM_PTR(&timealarm_duration_obj) }, -}; -STATIC MP_DEFINE_CONST_DICT(timealarm_module_globals, timealarm_module_globals_table); - -const mp_obj_module_t timealarm_module = { - .base = { &mp_type_module }, - .globals = (mp_obj_dict_t*)&timealarm_module_globals, -}; diff --git a/shared-bindings/timealarm/__init__.h b/shared-bindings/timealarm/__init__.h deleted file mode 100644 index b70cbda1f2..0000000000 --- a/shared-bindings/timealarm/__init__.h +++ /dev/null @@ -1,8 +0,0 @@ -#ifndef MICROPY_INCLUDED_SHARED_BINDINGS_ulp___INIT___H -#define MICROPY_INCLUDED_SHARED_BINDINGS_ulp___INIT___H - -#include "py/runtime.h" - -extern void common_hal_timealarm_duration(uint32_t); - -#endif \ No newline at end of file From 05a3f203dbaf53fbccd97395a90d025f2d3b9dc2 Mon Sep 17 00:00:00 2001 From: microDev <70126934+microDev1@users.noreply.github.com> Date: Tue, 22 Sep 2020 23:45:38 +0530 Subject: [PATCH 04/34] Add function to get time elapsed during sleep --- .../common-hal/microcontroller/__init__.c | 46 +++++++++++++++++++ shared-bindings/microcontroller/__init__.c | 20 ++++++++ shared-bindings/microcontroller/__init__.h | 5 ++ 3 files changed, 71 insertions(+) diff --git a/ports/esp32s2/common-hal/microcontroller/__init__.c b/ports/esp32s2/common-hal/microcontroller/__init__.c index 2fcc2ceda1..8b9fef2f98 100644 --- a/ports/esp32s2/common-hal/microcontroller/__init__.c +++ b/ports/esp32s2/common-hal/microcontroller/__init__.c @@ -25,6 +25,8 @@ * THE SOFTWARE. */ +#include + #include "py/mphal.h" #include "py/obj.h" #include "py/runtime.h" @@ -42,6 +44,9 @@ #include "freertos/FreeRTOS.h" #include "esp_sleep.h" +#include "soc/rtc_periph.h" + +static RTC_DATA_ATTR struct timeval sleep_enter_time; void common_hal_mcu_delay_us(uint32_t delay) { @@ -80,9 +85,50 @@ void common_hal_mcu_reset(void) { } void common_hal_mcu_sleep(void) { + gettimeofday(&sleep_enter_time, NULL); esp_deep_sleep_start(); } +int common_hal_mcu_get_sleep_time(void) { + struct timeval now; + gettimeofday(&now, NULL); + return (now.tv_sec - sleep_enter_time.tv_sec) * 1000 + (now.tv_usec - sleep_enter_time.tv_usec) / 1000; +} + +mp_obj_t common_hal_mcu_get_wake_alarm(void) { + switch (esp_sleep_get_wakeup_cause()) { + case ESP_SLEEP_WAKEUP_TIMER: ; + //Wake up from timer. + time_alarm_obj_t *timer = m_new_obj(time_alarm_obj_t); + timer->base.type = &time_alarm_type; + return timer; + case ESP_SLEEP_WAKEUP_EXT0: ; + //Wake up from GPIO + io_alarm_obj_t *ext0 = m_new_obj(io_alarm_obj_t); + ext0->base.type = &io_alarm_type; + return ext0; + case ESP_SLEEP_WAKEUP_EXT1: + //Wake up from GPIO, returns -> esp_sleep_get_ext1_wakeup_status() + /*uint64_t wakeup_pin_mask = esp_sleep_get_ext1_wakeup_status(); + if (wakeup_pin_mask != 0) { + int pin = __builtin_ffsll(wakeup_pin_mask) - 1; + printf("Wake up from GPIO %d\n", pin); + } else { + printf("Wake up from GPIO\n"); + }*/ + break; + case ESP_SLEEP_WAKEUP_TOUCHPAD: + //TODO: implement TouchIO + //Wake up from touch on pad, returns -> esp_sleep_get_touchpad_wakeup_status() + break; + case ESP_SLEEP_WAKEUP_UNDEFINED: + default: + //Not a deep sleep reset + break; + } + return mp_const_none; +} + // The singleton microcontroller.Processor object, bound to microcontroller.cpu // It currently only has properties, and no state. const mcu_processor_obj_t common_hal_mcu_processor_obj = { diff --git a/shared-bindings/microcontroller/__init__.c b/shared-bindings/microcontroller/__init__.c index b8ca8f18ba..7b896d99b2 100644 --- a/shared-bindings/microcontroller/__init__.c +++ b/shared-bindings/microcontroller/__init__.c @@ -152,6 +152,24 @@ STATIC mp_obj_t mcu_sleep(void) { } STATIC MP_DEFINE_CONST_FUN_OBJ_0(mcu_sleep_obj, mcu_sleep); +//| def getWakeAlarm() -> None: +//| """This returns the alarm that triggered wakeup, +//| also returns alarm specific parameters`. +//| +STATIC mp_obj_t mcu_get_wake_alarm(void) { + return common_hal_mcu_get_wake_alarm(); +} +STATIC MP_DEFINE_CONST_FUN_OBJ_0(mcu_get_wake_alarm_obj, mcu_get_wake_alarm); + +//| def getSleepTime() -> None: +//| """This returns the period of time in ms, +//| in which the board was in deep sleep`. +//| +STATIC mp_obj_t mcu_get_sleep_time(void) { + return mp_obj_new_int(common_hal_mcu_get_sleep_time()); +} +STATIC MP_DEFINE_CONST_FUN_OBJ_0(mcu_get_sleep_time_obj, mcu_get_sleep_time); + //| nvm: Optional[ByteArray] //| """Available non-volatile memory. //| This object is the sole instance of `nvm.ByteArray` when available or ``None`` otherwise. @@ -188,6 +206,8 @@ STATIC const mp_rom_map_elem_t mcu_module_globals_table[] = { { MP_ROM_QSTR(MP_QSTR_on_next_reset), MP_ROM_PTR(&mcu_on_next_reset_obj) }, { MP_ROM_QSTR(MP_QSTR_reset), MP_ROM_PTR(&mcu_reset_obj) }, { MP_ROM_QSTR(MP_QSTR_sleep), MP_ROM_PTR(&mcu_sleep_obj) }, + { MP_ROM_QSTR(MP_QSTR_getSleepTime), MP_ROM_PTR(&mcu_get_sleep_time_obj) }, + { MP_ROM_QSTR(MP_QSTR_getWakeAlarm), MP_ROM_PTR(&mcu_get_wake_alarm_obj) }, #if CIRCUITPY_INTERNAL_NVM_SIZE > 0 { MP_ROM_QSTR(MP_QSTR_nvm), MP_ROM_PTR(&common_hal_mcu_nvm_obj) }, #else diff --git a/shared-bindings/microcontroller/__init__.h b/shared-bindings/microcontroller/__init__.h index b0f61e64b9..f0a3cee2df 100644 --- a/shared-bindings/microcontroller/__init__.h +++ b/shared-bindings/microcontroller/__init__.h @@ -35,6 +35,9 @@ #include "shared-bindings/microcontroller/RunMode.h" +#include "shared-bindings/io_alarm/__init__.h" +#include "shared-bindings/time_alarm/__init__.h" + extern void common_hal_mcu_delay_us(uint32_t); extern void common_hal_mcu_disable_interrupts(void); @@ -44,6 +47,8 @@ extern void common_hal_mcu_on_next_reset(mcu_runmode_t runmode); extern void common_hal_mcu_reset(void); extern void common_hal_mcu_sleep(void); +extern int common_hal_mcu_get_sleep_time(void); +extern mp_obj_t common_hal_mcu_get_wake_alarm(void); extern const mp_obj_dict_t mcu_pin_globals; From 21ba61afbbdfbf1a693e9e136c645d970c0a7e9c Mon Sep 17 00:00:00 2001 From: microDev <70126934+microDev1@users.noreply.github.com> Date: Tue, 22 Sep 2020 23:47:10 +0530 Subject: [PATCH 05/34] Add function to disable alarm --- ports/esp32s2/common-hal/io_alarm/__init__.c | 20 +++++++------- .../esp32s2/common-hal/time_alarm/__init__.c | 3 +++ shared-bindings/io_alarm/__init__.c | 26 ++++++++++++++++--- shared-bindings/io_alarm/__init__.h | 11 +++++++- shared-bindings/time_alarm/__init__.c | 21 ++++++++++++++- shared-bindings/time_alarm/__init__.h | 7 +++++ 6 files changed, 73 insertions(+), 15 deletions(-) diff --git a/ports/esp32s2/common-hal/io_alarm/__init__.c b/ports/esp32s2/common-hal/io_alarm/__init__.c index d88c147fe0..5d926d4e93 100644 --- a/ports/esp32s2/common-hal/io_alarm/__init__.c +++ b/ports/esp32s2/common-hal/io_alarm/__init__.c @@ -3,25 +3,25 @@ #include "esp_sleep.h" #include "driver/rtc_io.h" -void common_hal_io_alarm_pin_state (uint8_t gpio, uint8_t level, bool pull) { - if (!rtc_gpio_is_valid_gpio(gpio)) { - mp_raise_ValueError(translate("io must be rtc io")); - return; +mp_obj_t common_hal_io_alarm_pin_state (io_alarm_obj_t *self_in) { + if (!rtc_gpio_is_valid_gpio(self_in->gpio)) { + mp_raise_ValueError(translate("io must be rtc io")); } - switch(esp_sleep_enable_ext0_wakeup(gpio, level)) { + switch(esp_sleep_enable_ext0_wakeup(self_in->gpio, self_in->level)) { case ESP_ERR_INVALID_ARG: mp_raise_ValueError(translate("trigger level must be 0 or 1")); - return; case ESP_ERR_INVALID_STATE: mp_raise_RuntimeError(translate("wakeup conflict")); - return; default: break; } - if (pull) { - (level) ? rtc_gpio_pulldown_en(gpio) : rtc_gpio_pullup_en(gpio); - } + if (self_in->pull) { (self_in->level) ? rtc_gpio_pulldown_en(self_in->gpio) : rtc_gpio_pullup_en(self_in->gpio); } + + return self_in; } +void common_hal_io_alarm_disable (void) { + esp_sleep_disable_wakeup_source(ESP_SLEEP_WAKEUP_EXT0 | ESP_SLEEP_WAKEUP_EXT1); +} diff --git a/ports/esp32s2/common-hal/time_alarm/__init__.c b/ports/esp32s2/common-hal/time_alarm/__init__.c index 342ca9d154..a33376bb09 100644 --- a/ports/esp32s2/common-hal/time_alarm/__init__.c +++ b/ports/esp32s2/common-hal/time_alarm/__init__.c @@ -8,3 +8,6 @@ void common_hal_time_alarm_duration (uint32_t ms) { } } +void common_hal_time_alarm_disable (void) { + esp_sleep_disable_wakeup_source(ESP_SLEEP_WAKEUP_TIMER); +} diff --git a/shared-bindings/io_alarm/__init__.c b/shared-bindings/io_alarm/__init__.c index 534b7e66f5..934b34e49d 100644 --- a/shared-bindings/io_alarm/__init__.c +++ b/shared-bindings/io_alarm/__init__.c @@ -3,7 +3,7 @@ #include "shared-bindings/io_alarm/__init__.h" #include "shared-bindings/microcontroller/Pin.h" -//| Set Timer Wakeup +//| Set Pin Wakeup //| STATIC mp_obj_t io_alarm_pin_state(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) { enum { ARG_level, ARG_pull }; @@ -16,15 +16,30 @@ STATIC mp_obj_t io_alarm_pin_state(size_t n_args, const mp_obj_t *pos_args, mp_m mp_arg_parse_all(n_args - 1, pos_args + 1, kw_args, MP_ARRAY_SIZE(allowed_args), allowed_args, args); mcu_pin_obj_t *pin = validate_obj_is_pin(pos_args[0]); - common_hal_io_alarm_pin_state(pin->number, args[ARG_level].u_int, args[ARG_pull].u_bool); + io_alarm_obj_t *self = m_new_obj(io_alarm_obj_t); - return mp_const_none; + self->base.type = &io_alarm_type; + self->gpio = pin->number; + self->level = args[ARG_level].u_int; + self->pull = args[ARG_pull].u_bool; + + return common_hal_io_alarm_pin_state(self); } STATIC MP_DEFINE_CONST_FUN_OBJ_KW(io_alarm_pin_state_obj, 1, io_alarm_pin_state); + +//| Disable Pin Wakeup +//| +STATIC mp_obj_t io_alarm_disable(void) { + common_hal_io_alarm_disable(); + return mp_const_none; +} +STATIC MP_DEFINE_CONST_FUN_OBJ_0(io_alarm_disable_obj, io_alarm_disable); + STATIC const mp_rom_map_elem_t io_alarm_module_globals_table[] = { { MP_ROM_QSTR(MP_QSTR___name__), MP_ROM_QSTR(MP_QSTR_io_alarm) }, { MP_OBJ_NEW_QSTR(MP_QSTR_PinState), MP_ROM_PTR(&io_alarm_pin_state_obj) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_Disable), MP_ROM_PTR(&io_alarm_disable_obj) }, }; STATIC MP_DEFINE_CONST_DICT(io_alarm_module_globals, io_alarm_module_globals_table); @@ -32,3 +47,8 @@ const mp_obj_module_t io_alarm_module = { .base = { &mp_type_module }, .globals = (mp_obj_dict_t*)&io_alarm_module_globals, }; + +const mp_obj_type_t io_alarm_type = { + { &mp_type_type }, + .name = MP_QSTR_ioAlarm, +}; diff --git a/shared-bindings/io_alarm/__init__.h b/shared-bindings/io_alarm/__init__.h index dd4b881657..2b91f781d5 100644 --- a/shared-bindings/io_alarm/__init__.h +++ b/shared-bindings/io_alarm/__init__.h @@ -3,6 +3,15 @@ #include "py/runtime.h" -extern void common_hal_io_alarm_pin_state(uint8_t gpio, uint8_t level, bool pull); +typedef struct { + mp_obj_base_t base; + uint8_t gpio, level; + bool pull; +} io_alarm_obj_t; + +extern const mp_obj_type_t io_alarm_type; + +extern mp_obj_t common_hal_io_alarm_pin_state (io_alarm_obj_t *self_in); +extern void common_hal_io_alarm_disable (void); #endif //MICROPY_INCLUDED_SHARED_BINDINGS_IO_ALARM___INIT___H diff --git a/shared-bindings/time_alarm/__init__.c b/shared-bindings/time_alarm/__init__.c index bfbece83c0..e45c5239f1 100644 --- a/shared-bindings/time_alarm/__init__.c +++ b/shared-bindings/time_alarm/__init__.c @@ -11,17 +11,31 @@ STATIC mp_obj_t time_alarm_duration(mp_obj_t seconds_o) { mp_int_t seconds = mp_obj_get_int(seconds_o); mp_int_t msecs = 1000 * seconds; #endif + if (seconds < 0) { mp_raise_ValueError(translate("sleep length must be non-negative")); } common_hal_time_alarm_duration(msecs); - return mp_const_none; + + time_alarm_obj_t *self = m_new_obj(time_alarm_obj_t); + self->base.type = &time_alarm_type; + + return self; } STATIC MP_DEFINE_CONST_FUN_OBJ_1(time_alarm_duration_obj, time_alarm_duration); +//| Disable Timer Wakeup +//| +STATIC mp_obj_t time_alarm_disable(void) { + common_hal_time_alarm_disable(); + return mp_const_none; +} +STATIC MP_DEFINE_CONST_FUN_OBJ_0(time_alarm_disable_obj, time_alarm_disable); + STATIC const mp_rom_map_elem_t time_alarm_module_globals_table[] = { { MP_ROM_QSTR(MP_QSTR___name__), MP_ROM_QSTR(MP_QSTR_time_alarm) }, { MP_OBJ_NEW_QSTR(MP_QSTR_Duration), MP_ROM_PTR(&time_alarm_duration_obj) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_Disable), MP_ROM_PTR(&time_alarm_disable_obj) }, }; STATIC MP_DEFINE_CONST_DICT(time_alarm_module_globals, time_alarm_module_globals_table); @@ -29,3 +43,8 @@ const mp_obj_module_t time_alarm_module = { .base = { &mp_type_module }, .globals = (mp_obj_dict_t*)&time_alarm_module_globals, }; + +const mp_obj_type_t time_alarm_type = { + { &mp_type_type }, + .name = MP_QSTR_timeAlarm, +}; diff --git a/shared-bindings/time_alarm/__init__.h b/shared-bindings/time_alarm/__init__.h index 0913f7fded..52b6e89ee2 100644 --- a/shared-bindings/time_alarm/__init__.h +++ b/shared-bindings/time_alarm/__init__.h @@ -3,6 +3,13 @@ #include "py/runtime.h" +typedef struct { + mp_obj_base_t base; +} time_alarm_obj_t; + +extern const mp_obj_type_t time_alarm_type; + extern void common_hal_time_alarm_duration(uint32_t); +extern void common_hal_time_alarm_disable (void); #endif //MICROPY_INCLUDED_SHARED_BINDINGS_TIME_ALARM___INIT___H From e5ff55b15c8cc67c2ece3b8857b5805109b858b3 Mon Sep 17 00:00:00 2001 From: microDev <70126934+microDev1@users.noreply.github.com> Date: Wed, 23 Sep 2020 12:54:07 +0530 Subject: [PATCH 06/34] Renamed alarm modules --- .../{io_alarm => alarm_io}/__init__.c | 6 +-- .../{time_alarm => alarm_time}/__init__.c | 6 +-- .../common-hal/microcontroller/__init__.c | 8 +-- ports/esp32s2/mpconfigport.mk | 4 +- py/circuitpy_defns.mk | 12 ++--- py/circuitpy_mpconfig.h | 20 +++---- py/circuitpy_mpconfig.mk | 8 +-- shared-bindings/alarm_io/__init__.c | 54 +++++++++++++++++++ shared-bindings/alarm_io/__init__.h | 17 ++++++ shared-bindings/alarm_time/__init__.c | 50 +++++++++++++++++ shared-bindings/alarm_time/__init__.h | 15 ++++++ shared-bindings/io_alarm/__init__.c | 54 ------------------- shared-bindings/io_alarm/__init__.h | 17 ------ shared-bindings/microcontroller/__init__.h | 4 +- shared-bindings/time_alarm/__init__.c | 50 ----------------- shared-bindings/time_alarm/__init__.h | 15 ------ 16 files changed, 170 insertions(+), 170 deletions(-) rename ports/esp32s2/common-hal/{io_alarm => alarm_io}/__init__.c (83%) rename ports/esp32s2/common-hal/{time_alarm => alarm_time}/__init__.c (62%) create mode 100644 shared-bindings/alarm_io/__init__.c create mode 100644 shared-bindings/alarm_io/__init__.h create mode 100644 shared-bindings/alarm_time/__init__.c create mode 100644 shared-bindings/alarm_time/__init__.h delete mode 100644 shared-bindings/io_alarm/__init__.c delete mode 100644 shared-bindings/io_alarm/__init__.h delete mode 100644 shared-bindings/time_alarm/__init__.c delete mode 100644 shared-bindings/time_alarm/__init__.h diff --git a/ports/esp32s2/common-hal/io_alarm/__init__.c b/ports/esp32s2/common-hal/alarm_io/__init__.c similarity index 83% rename from ports/esp32s2/common-hal/io_alarm/__init__.c rename to ports/esp32s2/common-hal/alarm_io/__init__.c index 5d926d4e93..9aa28f4156 100644 --- a/ports/esp32s2/common-hal/io_alarm/__init__.c +++ b/ports/esp32s2/common-hal/alarm_io/__init__.c @@ -1,9 +1,9 @@ -#include "shared-bindings/io_alarm/__init__.h" +#include "shared-bindings/alarm_io/__init__.h" #include "esp_sleep.h" #include "driver/rtc_io.h" -mp_obj_t common_hal_io_alarm_pin_state (io_alarm_obj_t *self_in) { +mp_obj_t common_hal_alarm_io_pin_state (alarm_io_obj_t *self_in) { if (!rtc_gpio_is_valid_gpio(self_in->gpio)) { mp_raise_ValueError(translate("io must be rtc io")); } @@ -22,6 +22,6 @@ mp_obj_t common_hal_io_alarm_pin_state (io_alarm_obj_t *self_in) { return self_in; } -void common_hal_io_alarm_disable (void) { +void common_hal_alarm_io_disable (void) { esp_sleep_disable_wakeup_source(ESP_SLEEP_WAKEUP_EXT0 | ESP_SLEEP_WAKEUP_EXT1); } diff --git a/ports/esp32s2/common-hal/time_alarm/__init__.c b/ports/esp32s2/common-hal/alarm_time/__init__.c similarity index 62% rename from ports/esp32s2/common-hal/time_alarm/__init__.c rename to ports/esp32s2/common-hal/alarm_time/__init__.c index a33376bb09..fb601e6be0 100644 --- a/ports/esp32s2/common-hal/time_alarm/__init__.c +++ b/ports/esp32s2/common-hal/alarm_time/__init__.c @@ -1,13 +1,13 @@ #include "esp_sleep.h" -#include "shared-bindings/time_alarm/__init__.h" +#include "shared-bindings/alarm_time/__init__.h" -void common_hal_time_alarm_duration (uint32_t ms) { +void common_hal_alarm_time_duration (uint32_t ms) { if (esp_sleep_enable_timer_wakeup((ms) * 1000) == ESP_ERR_INVALID_ARG) { mp_raise_ValueError(translate("time out of range")); } } -void common_hal_time_alarm_disable (void) { +void common_hal_alarm_time_disable (void) { esp_sleep_disable_wakeup_source(ESP_SLEEP_WAKEUP_TIMER); } diff --git a/ports/esp32s2/common-hal/microcontroller/__init__.c b/ports/esp32s2/common-hal/microcontroller/__init__.c index 8b9fef2f98..e79c602020 100644 --- a/ports/esp32s2/common-hal/microcontroller/__init__.c +++ b/ports/esp32s2/common-hal/microcontroller/__init__.c @@ -99,13 +99,13 @@ mp_obj_t common_hal_mcu_get_wake_alarm(void) { switch (esp_sleep_get_wakeup_cause()) { case ESP_SLEEP_WAKEUP_TIMER: ; //Wake up from timer. - time_alarm_obj_t *timer = m_new_obj(time_alarm_obj_t); - timer->base.type = &time_alarm_type; + alarm_time_obj_t *timer = m_new_obj(alarm_time_obj_t); + timer->base.type = &alarm_time_type; return timer; case ESP_SLEEP_WAKEUP_EXT0: ; //Wake up from GPIO - io_alarm_obj_t *ext0 = m_new_obj(io_alarm_obj_t); - ext0->base.type = &io_alarm_type; + alarm_io_obj_t *ext0 = m_new_obj(alarm_io_obj_t); + ext0->base.type = &alarm_io_type; return ext0; case ESP_SLEEP_WAKEUP_EXT1: //Wake up from GPIO, returns -> esp_sleep_get_ext1_wakeup_status() diff --git a/ports/esp32s2/mpconfigport.mk b/ports/esp32s2/mpconfigport.mk index 0f8f3ada53..4aaf1d00c7 100644 --- a/ports/esp32s2/mpconfigport.mk +++ b/ports/esp32s2/mpconfigport.mk @@ -22,8 +22,8 @@ CIRCUITPY_FREQUENCYIO = 0 CIRCUITPY_I2CPERIPHERAL = 0 CIRCUITPY_ROTARYIO = 0 CIRCUITPY_NVM = 0 -CIRCUITPY_TIME_ALARM = 1 -CIRCUITPY_IO_ALARM = 1 +CIRCUITPY_ALARM_TIME = 1 +CIRCUITPY_ALARM_IO = 1 # We don't have enough endpoints to include MIDI. CIRCUITPY_USB_MIDI = 0 CIRCUITPY_WIFI = 1 diff --git a/py/circuitpy_defns.mk b/py/circuitpy_defns.mk index 672eeda40c..4c57165936 100644 --- a/py/circuitpy_defns.mk +++ b/py/circuitpy_defns.mk @@ -259,11 +259,11 @@ endif ifeq ($(CIRCUITPY_TIME),1) SRC_PATTERNS += time/% endif -ifeq ($(CIRCUITPY_TIME_ALARM),1) -SRC_PATTERNS += time_alarm/% +ifeq ($(CIRCUITPY_ALARM_TIME),1) +SRC_PATTERNS += alarm_time/% endif -ifeq ($(CIRCUITPY_IO_ALARM),1) -SRC_PATTERNS += io_alarm/% +ifeq ($(CIRCUITPY_ALARM_IO),1) +SRC_PATTERNS += alarm_io/% endif ifeq ($(CIRCUITPY_TOUCHIO),1) SRC_PATTERNS += touchio/% @@ -366,8 +366,8 @@ SRC_COMMON_HAL_ALL = \ ssl/SSLContext.c \ supervisor/Runtime.c \ supervisor/__init__.c \ - time_alarm/__init__.c \ - io_alarm/__init__.c \ + alarm_time/__init__.c \ + alarm_io/__init__.c \ watchdog/WatchDogMode.c \ watchdog/WatchDogTimer.c \ watchdog/__init__.c \ diff --git a/py/circuitpy_mpconfig.h b/py/circuitpy_mpconfig.h index d899ecacb6..94072f580b 100644 --- a/py/circuitpy_mpconfig.h +++ b/py/circuitpy_mpconfig.h @@ -663,18 +663,18 @@ extern const struct _mp_obj_module_t time_module; #define TIME_MODULE_ALT_NAME #endif -#if CIRCUITPY_TIME_ALARM -extern const struct _mp_obj_module_t time_alarm_module; -#define TIME_ALARM_MODULE { MP_OBJ_NEW_QSTR(MP_QSTR_time_alarm), (mp_obj_t)&time_alarm_module }, +#if CIRCUITPY_ALARM_TIME +extern const struct _mp_obj_module_t alarm_time_module; +#define ALARM_TIME_MODULE { MP_OBJ_NEW_QSTR(MP_QSTR_alarm_time), (mp_obj_t)&alarm_time_module }, #else -#define TIME_ALARM_MODULE +#define ALARM_TIME_MODULE #endif -#if CIRCUITPY_IO_ALARM -extern const struct _mp_obj_module_t io_alarm_module; -#define IO_ALARM_MODULE { MP_OBJ_NEW_QSTR(MP_QSTR_io_alarm), (mp_obj_t)&io_alarm_module }, +#if CIRCUITPY_ALARM_IO +extern const struct _mp_obj_module_t alarm_io_module; +#define ALARM_IO_MODULE { MP_OBJ_NEW_QSTR(MP_QSTR_alarm_io), (mp_obj_t)&alarm_io_module }, #else -#define IO_ALARM_MODULE +#define ALARM_IO_MODULE #endif #if CIRCUITPY_TOUCHIO @@ -835,8 +835,8 @@ extern const struct _mp_obj_module_t wifi_module; STRUCT_MODULE \ SUPERVISOR_MODULE \ TOUCHIO_MODULE \ - TIME_ALARM_MODULE \ - IO_ALARM_MODULE \ + ALARM_TIME_MODULE \ + ALARM_IO_MODULE \ UHEAP_MODULE \ USB_HID_MODULE \ USB_MIDI_MODULE \ diff --git a/py/circuitpy_mpconfig.mk b/py/circuitpy_mpconfig.mk index 4cce2a0a1a..e8619347dd 100644 --- a/py/circuitpy_mpconfig.mk +++ b/py/circuitpy_mpconfig.mk @@ -234,11 +234,11 @@ CFLAGS += -DCIRCUITPY_TERMINALIO=$(CIRCUITPY_TERMINALIO) CIRCUITPY_TIME ?= 1 CFLAGS += -DCIRCUITPY_TIME=$(CIRCUITPY_TIME) -CIRCUITPY_TIME_ALARM ?= 0 -CFLAGS += -DCIRCUITPY_TIME_ALARM=$(CIRCUITPY_TIME_ALARM) +CIRCUITPY_ALARM_TIME ?= 0 +CFLAGS += -DCIRCUITPY_ALARM_TIME=$(CIRCUITPY_ALARM_TIME) -CIRCUITPY_IO_ALARM ?= 0 -CFLAGS += -DCIRCUITPY_IO_ALARM=$(CIRCUITPY_IO_ALARM) +CIRCUITPY_ALARM_IO ?= 0 +CFLAGS += -DCIRCUITPY_ALARM_IO=$(CIRCUITPY_ALARM_IO) # touchio might be native or generic. See circuitpy_defns.mk. CIRCUITPY_TOUCHIO_USE_NATIVE ?= 0 diff --git a/shared-bindings/alarm_io/__init__.c b/shared-bindings/alarm_io/__init__.c new file mode 100644 index 0000000000..09783d0d08 --- /dev/null +++ b/shared-bindings/alarm_io/__init__.c @@ -0,0 +1,54 @@ +#include "py/obj.h" + +#include "shared-bindings/alarm_io/__init__.h" +#include "shared-bindings/microcontroller/Pin.h" + +//| Set Pin Wakeup +//| +STATIC mp_obj_t alarm_io_pin_state(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) { + enum { ARG_level, ARG_pull }; + static const mp_arg_t allowed_args[] = { + { MP_QSTR_level, MP_ARG_INT | MP_ARG_KW_ONLY | MP_ARG_REQUIRED }, + { MP_QSTR_pull, MP_ARG_INT | MP_ARG_KW_ONLY, {.u_bool = false} }, + }; + + mp_arg_val_t args[MP_ARRAY_SIZE(allowed_args)]; + mp_arg_parse_all(n_args - 1, pos_args + 1, kw_args, MP_ARRAY_SIZE(allowed_args), allowed_args, args); + + mcu_pin_obj_t *pin = validate_obj_is_pin(pos_args[0]); + alarm_io_obj_t *self = m_new_obj(alarm_io_obj_t); + + self->base.type = &alarm_io_type; + self->gpio = pin->number; + self->level = args[ARG_level].u_int; + self->pull = args[ARG_pull].u_bool; + + return common_hal_alarm_io_pin_state(self); +} +STATIC MP_DEFINE_CONST_FUN_OBJ_KW(alarm_io_pin_state_obj, 1, alarm_io_pin_state); + + +//| Disable Pin Wakeup +//| +STATIC mp_obj_t alarm_io_disable(void) { + common_hal_alarm_io_disable(); + return mp_const_none; +} +STATIC MP_DEFINE_CONST_FUN_OBJ_0(alarm_io_disable_obj, alarm_io_disable); + +STATIC const mp_rom_map_elem_t alarm_io_module_globals_table[] = { + { MP_ROM_QSTR(MP_QSTR___name__), MP_ROM_QSTR(MP_QSTR_alarm_io) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_PinState), MP_ROM_PTR(&alarm_io_pin_state_obj) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_Disable), MP_ROM_PTR(&alarm_io_disable_obj) }, +}; +STATIC MP_DEFINE_CONST_DICT(alarm_io_module_globals, alarm_io_module_globals_table); + +const mp_obj_module_t alarm_io_module = { + .base = { &mp_type_module }, + .globals = (mp_obj_dict_t*)&alarm_io_module_globals, +}; + +const mp_obj_type_t alarm_io_type = { + { &mp_type_type }, + .name = MP_QSTR_ioAlarm, +}; diff --git a/shared-bindings/alarm_io/__init__.h b/shared-bindings/alarm_io/__init__.h new file mode 100644 index 0000000000..0a53497c01 --- /dev/null +++ b/shared-bindings/alarm_io/__init__.h @@ -0,0 +1,17 @@ +#ifndef MICROPY_INCLUDED_SHARED_BINDINGS_ALARM_IO___INIT___H +#define MICROPY_INCLUDED_SHARED_BINDINGS_ALARM_IO___INIT___H + +#include "py/runtime.h" + +typedef struct { + mp_obj_base_t base; + uint8_t gpio, level; + bool pull; +} alarm_io_obj_t; + +extern const mp_obj_type_t alarm_io_type; + +extern mp_obj_t common_hal_alarm_io_pin_state (alarm_io_obj_t *self_in); +extern void common_hal_alarm_io_disable (void); + +#endif //MICROPY_INCLUDED_SHARED_BINDINGS_ALARM_IO___INIT___H diff --git a/shared-bindings/alarm_time/__init__.c b/shared-bindings/alarm_time/__init__.c new file mode 100644 index 0000000000..22fb935064 --- /dev/null +++ b/shared-bindings/alarm_time/__init__.c @@ -0,0 +1,50 @@ +#include "py/obj.h" +#include "shared-bindings/alarm_time/__init__.h" + +//| Set Timer Wakeup +//| +STATIC mp_obj_t alarm_time_duration(mp_obj_t seconds_o) { + #if MICROPY_PY_BUILTINS_FLOAT + mp_float_t seconds = mp_obj_get_float(seconds_o); + mp_float_t msecs = 1000.0f * seconds + 0.5f; + #else + mp_int_t seconds = mp_obj_get_int(seconds_o); + mp_int_t msecs = 1000 * seconds; + #endif + + if (seconds < 0) { + mp_raise_ValueError(translate("sleep length must be non-negative")); + } + common_hal_alarm_time_duration(msecs); + + alarm_time_obj_t *self = m_new_obj(alarm_time_obj_t); + self->base.type = &alarm_time_type; + + return self; +} +STATIC MP_DEFINE_CONST_FUN_OBJ_1(alarm_time_duration_obj, alarm_time_duration); + +//| Disable Timer Wakeup +//| +STATIC mp_obj_t alarm_time_disable(void) { + common_hal_alarm_time_disable(); + return mp_const_none; +} +STATIC MP_DEFINE_CONST_FUN_OBJ_0(alarm_time_disable_obj, alarm_time_disable); + +STATIC const mp_rom_map_elem_t alarm_time_module_globals_table[] = { + { MP_ROM_QSTR(MP_QSTR___name__), MP_ROM_QSTR(MP_QSTR_alarm_time) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_Duration), MP_ROM_PTR(&alarm_time_duration_obj) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_Disable), MP_ROM_PTR(&alarm_time_disable_obj) }, +}; +STATIC MP_DEFINE_CONST_DICT(alarm_time_module_globals, alarm_time_module_globals_table); + +const mp_obj_module_t alarm_time_module = { + .base = { &mp_type_module }, + .globals = (mp_obj_dict_t*)&alarm_time_module_globals, +}; + +const mp_obj_type_t alarm_time_type = { + { &mp_type_type }, + .name = MP_QSTR_timeAlarm, +}; diff --git a/shared-bindings/alarm_time/__init__.h b/shared-bindings/alarm_time/__init__.h new file mode 100644 index 0000000000..d69aa5a443 --- /dev/null +++ b/shared-bindings/alarm_time/__init__.h @@ -0,0 +1,15 @@ +#ifndef MICROPY_INCLUDED_SHARED_BINDINGS_ALARM_TIME___INIT___H +#define MICROPY_INCLUDED_SHARED_BINDINGS_ALARM_TIME___INIT___H + +#include "py/runtime.h" + +typedef struct { + mp_obj_base_t base; +} alarm_time_obj_t; + +extern const mp_obj_type_t alarm_time_type; + +extern void common_hal_alarm_time_duration(uint32_t); +extern void common_hal_alarm_time_disable (void); + +#endif //MICROPY_INCLUDED_SHARED_BINDINGS_ALARM_TIME___INIT___H diff --git a/shared-bindings/io_alarm/__init__.c b/shared-bindings/io_alarm/__init__.c deleted file mode 100644 index 934b34e49d..0000000000 --- a/shared-bindings/io_alarm/__init__.c +++ /dev/null @@ -1,54 +0,0 @@ -#include "py/obj.h" - -#include "shared-bindings/io_alarm/__init__.h" -#include "shared-bindings/microcontroller/Pin.h" - -//| Set Pin Wakeup -//| -STATIC mp_obj_t io_alarm_pin_state(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) { - enum { ARG_level, ARG_pull }; - static const mp_arg_t allowed_args[] = { - { MP_QSTR_level, MP_ARG_INT | MP_ARG_KW_ONLY | MP_ARG_REQUIRED }, - { MP_QSTR_pull, MP_ARG_INT | MP_ARG_KW_ONLY, {.u_bool = false} }, - }; - - mp_arg_val_t args[MP_ARRAY_SIZE(allowed_args)]; - mp_arg_parse_all(n_args - 1, pos_args + 1, kw_args, MP_ARRAY_SIZE(allowed_args), allowed_args, args); - - mcu_pin_obj_t *pin = validate_obj_is_pin(pos_args[0]); - io_alarm_obj_t *self = m_new_obj(io_alarm_obj_t); - - self->base.type = &io_alarm_type; - self->gpio = pin->number; - self->level = args[ARG_level].u_int; - self->pull = args[ARG_pull].u_bool; - - return common_hal_io_alarm_pin_state(self); -} -STATIC MP_DEFINE_CONST_FUN_OBJ_KW(io_alarm_pin_state_obj, 1, io_alarm_pin_state); - - -//| Disable Pin Wakeup -//| -STATIC mp_obj_t io_alarm_disable(void) { - common_hal_io_alarm_disable(); - return mp_const_none; -} -STATIC MP_DEFINE_CONST_FUN_OBJ_0(io_alarm_disable_obj, io_alarm_disable); - -STATIC const mp_rom_map_elem_t io_alarm_module_globals_table[] = { - { MP_ROM_QSTR(MP_QSTR___name__), MP_ROM_QSTR(MP_QSTR_io_alarm) }, - { MP_OBJ_NEW_QSTR(MP_QSTR_PinState), MP_ROM_PTR(&io_alarm_pin_state_obj) }, - { MP_OBJ_NEW_QSTR(MP_QSTR_Disable), MP_ROM_PTR(&io_alarm_disable_obj) }, -}; -STATIC MP_DEFINE_CONST_DICT(io_alarm_module_globals, io_alarm_module_globals_table); - -const mp_obj_module_t io_alarm_module = { - .base = { &mp_type_module }, - .globals = (mp_obj_dict_t*)&io_alarm_module_globals, -}; - -const mp_obj_type_t io_alarm_type = { - { &mp_type_type }, - .name = MP_QSTR_ioAlarm, -}; diff --git a/shared-bindings/io_alarm/__init__.h b/shared-bindings/io_alarm/__init__.h deleted file mode 100644 index 2b91f781d5..0000000000 --- a/shared-bindings/io_alarm/__init__.h +++ /dev/null @@ -1,17 +0,0 @@ -#ifndef MICROPY_INCLUDED_SHARED_BINDINGS_IO_ALARM___INIT___H -#define MICROPY_INCLUDED_SHARED_BINDINGS_IO_ALARM___INIT___H - -#include "py/runtime.h" - -typedef struct { - mp_obj_base_t base; - uint8_t gpio, level; - bool pull; -} io_alarm_obj_t; - -extern const mp_obj_type_t io_alarm_type; - -extern mp_obj_t common_hal_io_alarm_pin_state (io_alarm_obj_t *self_in); -extern void common_hal_io_alarm_disable (void); - -#endif //MICROPY_INCLUDED_SHARED_BINDINGS_IO_ALARM___INIT___H diff --git a/shared-bindings/microcontroller/__init__.h b/shared-bindings/microcontroller/__init__.h index f0a3cee2df..cd234fb033 100644 --- a/shared-bindings/microcontroller/__init__.h +++ b/shared-bindings/microcontroller/__init__.h @@ -35,8 +35,8 @@ #include "shared-bindings/microcontroller/RunMode.h" -#include "shared-bindings/io_alarm/__init__.h" -#include "shared-bindings/time_alarm/__init__.h" +#include "shared-bindings/alarm_io/__init__.h" +#include "shared-bindings/alarm_time/__init__.h" extern void common_hal_mcu_delay_us(uint32_t); diff --git a/shared-bindings/time_alarm/__init__.c b/shared-bindings/time_alarm/__init__.c deleted file mode 100644 index e45c5239f1..0000000000 --- a/shared-bindings/time_alarm/__init__.c +++ /dev/null @@ -1,50 +0,0 @@ -#include "py/obj.h" -#include "shared-bindings/time_alarm/__init__.h" - -//| Set Timer Wakeup -//| -STATIC mp_obj_t time_alarm_duration(mp_obj_t seconds_o) { - #if MICROPY_PY_BUILTINS_FLOAT - mp_float_t seconds = mp_obj_get_float(seconds_o); - mp_float_t msecs = 1000.0f * seconds + 0.5f; - #else - mp_int_t seconds = mp_obj_get_int(seconds_o); - mp_int_t msecs = 1000 * seconds; - #endif - - if (seconds < 0) { - mp_raise_ValueError(translate("sleep length must be non-negative")); - } - common_hal_time_alarm_duration(msecs); - - time_alarm_obj_t *self = m_new_obj(time_alarm_obj_t); - self->base.type = &time_alarm_type; - - return self; -} -STATIC MP_DEFINE_CONST_FUN_OBJ_1(time_alarm_duration_obj, time_alarm_duration); - -//| Disable Timer Wakeup -//| -STATIC mp_obj_t time_alarm_disable(void) { - common_hal_time_alarm_disable(); - return mp_const_none; -} -STATIC MP_DEFINE_CONST_FUN_OBJ_0(time_alarm_disable_obj, time_alarm_disable); - -STATIC const mp_rom_map_elem_t time_alarm_module_globals_table[] = { - { MP_ROM_QSTR(MP_QSTR___name__), MP_ROM_QSTR(MP_QSTR_time_alarm) }, - { MP_OBJ_NEW_QSTR(MP_QSTR_Duration), MP_ROM_PTR(&time_alarm_duration_obj) }, - { MP_OBJ_NEW_QSTR(MP_QSTR_Disable), MP_ROM_PTR(&time_alarm_disable_obj) }, -}; -STATIC MP_DEFINE_CONST_DICT(time_alarm_module_globals, time_alarm_module_globals_table); - -const mp_obj_module_t time_alarm_module = { - .base = { &mp_type_module }, - .globals = (mp_obj_dict_t*)&time_alarm_module_globals, -}; - -const mp_obj_type_t time_alarm_type = { - { &mp_type_type }, - .name = MP_QSTR_timeAlarm, -}; diff --git a/shared-bindings/time_alarm/__init__.h b/shared-bindings/time_alarm/__init__.h deleted file mode 100644 index 52b6e89ee2..0000000000 --- a/shared-bindings/time_alarm/__init__.h +++ /dev/null @@ -1,15 +0,0 @@ -#ifndef MICROPY_INCLUDED_SHARED_BINDINGS_TIME_ALARM___INIT___H -#define MICROPY_INCLUDED_SHARED_BINDINGS_TIME_ALARM___INIT___H - -#include "py/runtime.h" - -typedef struct { - mp_obj_base_t base; -} time_alarm_obj_t; - -extern const mp_obj_type_t time_alarm_type; - -extern void common_hal_time_alarm_duration(uint32_t); -extern void common_hal_time_alarm_disable (void); - -#endif //MICROPY_INCLUDED_SHARED_BINDINGS_TIME_ALARM___INIT___H From 4d8ffdca8dc570f63c34b8f02856feae2d880688 Mon Sep 17 00:00:00 2001 From: microDev <70126934+microDev1@users.noreply.github.com> Date: Thu, 24 Sep 2020 10:59:04 +0530 Subject: [PATCH 07/34] restructure alarm modules --- ports/esp32s2/common-hal/alarm/__init__.c | 84 +++++++++++++++++++ ports/esp32s2/common-hal/alarm/__init__.h | 6 ++ .../common-hal/microcontroller/__init__.c | 48 +---------- ports/esp32s2/mpconfigport.mk | 6 +- ports/esp32s2/supervisor/port.c | 7 +- py/circuitpy_defns.mk | 20 +++-- py/circuitpy_mpconfig.h | 40 +++++---- py/circuitpy_mpconfig.mk | 15 ++-- shared-bindings/alarm/__init__.c | 32 +++++++ shared-bindings/alarm/__init__.h | 12 +++ shared-bindings/alarm_time/__init__.h | 2 +- shared-bindings/microcontroller/__init__.c | 21 ----- shared-bindings/microcontroller/__init__.h | 7 +- 13 files changed, 191 insertions(+), 109 deletions(-) create mode 100644 ports/esp32s2/common-hal/alarm/__init__.c create mode 100644 ports/esp32s2/common-hal/alarm/__init__.h create mode 100644 shared-bindings/alarm/__init__.c create mode 100644 shared-bindings/alarm/__init__.h diff --git a/ports/esp32s2/common-hal/alarm/__init__.c b/ports/esp32s2/common-hal/alarm/__init__.c new file mode 100644 index 0000000000..90e8e9ecc8 --- /dev/null +++ b/ports/esp32s2/common-hal/alarm/__init__.c @@ -0,0 +1,84 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2016 Scott Shawcroft for Adafruit Industries + * Copyright (c) 2019 Lucian Copeland for Adafruit Industries + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +#include + +#include "common-hal/alarm/__init__.h" +#include "shared-bindings/alarm/__init__.h" + +#include "esp_sleep.h" +#include "soc/rtc_periph.h" +#include "driver/rtc_io.h" + +static RTC_DATA_ATTR struct timeval sleep_enter_time; +static RTC_DATA_ATTR struct timeval sleep_exit_time; +static RTC_DATA_ATTR uint8_t wake_io; + +int common_hal_alarm_get_sleep_time(void) { + return (sleep_exit_time.tv_sec - sleep_enter_time.tv_sec) * 1000 + (sleep_exit_time.tv_usec - sleep_enter_time.tv_usec) / 1000; +} + +void RTC_IRAM_ATTR esp_wake_deep_sleep(void) { + esp_default_wake_deep_sleep(); + wake_io = rtc_gpio_get_level(6); + gettimeofday(&sleep_exit_time, NULL); +} + +mp_obj_t common_hal_alarm_get_wake_alarm(void) { + switch (esp_sleep_get_wakeup_cause()) { + case ESP_SLEEP_WAKEUP_TIMER: ; + //Wake up from timer. + alarm_time_obj_t *timer = m_new_obj(alarm_time_obj_t); + timer->base.type = &alarm_time_type; + return timer; + case ESP_SLEEP_WAKEUP_EXT0: ; + //Wake up from GPIO + /*alarm_io_obj_t *ext0 = m_new_obj(alarm_io_obj_t); + ext0->base.type = &alarm_io_type; + return ext0;*/ + return mp_obj_new_int(wake_io); + case ESP_SLEEP_WAKEUP_EXT1: + //Wake up from GPIO, returns -> esp_sleep_get_ext1_wakeup_status() + /*uint64_t wakeup_pin_mask = esp_sleep_get_ext1_wakeup_status(); + if (wakeup_pin_mask != 0) { + int pin = __builtin_ffsll(wakeup_pin_mask) - 1; + printf("Wake up from GPIO %d\n", pin); + } else { + printf("Wake up from GPIO\n"); + }*/ + break; + case ESP_SLEEP_WAKEUP_TOUCHPAD: + //TODO: implement TouchIO + //Wake up from touch on pad, returns -> esp_sleep_get_touchpad_wakeup_status() + break; + case ESP_SLEEP_WAKEUP_UNDEFINED: + default: + //Not a deep sleep reset + break; + } + return mp_const_none; +} diff --git a/ports/esp32s2/common-hal/alarm/__init__.h b/ports/esp32s2/common-hal/alarm/__init__.h new file mode 100644 index 0000000000..8ba5e2b04a --- /dev/null +++ b/ports/esp32s2/common-hal/alarm/__init__.h @@ -0,0 +1,6 @@ +#ifndef MICROPY_INCLUDED_ESP32S2_COMMON_HAL_MICROCONTROLLER_ALARM_H +#define MICROPY_INCLUDED_ESP32S2_COMMON_HAL_MICROCONTROLLER_ALARM_H + +extern void esp_wake_deep_sleep(void); + +#endif // MICROPY_INCLUDED_ESP32S2_COMMON_HAL_MICROCONTROLLER_ALARM_H \ No newline at end of file diff --git a/ports/esp32s2/common-hal/microcontroller/__init__.c b/ports/esp32s2/common-hal/microcontroller/__init__.c index e79c602020..ba24e1c48d 100644 --- a/ports/esp32s2/common-hal/microcontroller/__init__.c +++ b/ports/esp32s2/common-hal/microcontroller/__init__.c @@ -25,10 +25,8 @@ * THE SOFTWARE. */ -#include - -#include "py/mphal.h" #include "py/obj.h" +#include "py/mphal.h" #include "py/runtime.h" #include "common-hal/microcontroller/Pin.h" @@ -44,9 +42,6 @@ #include "freertos/FreeRTOS.h" #include "esp_sleep.h" -#include "soc/rtc_periph.h" - -static RTC_DATA_ATTR struct timeval sleep_enter_time; void common_hal_mcu_delay_us(uint32_t delay) { @@ -85,50 +80,9 @@ void common_hal_mcu_reset(void) { } void common_hal_mcu_sleep(void) { - gettimeofday(&sleep_enter_time, NULL); esp_deep_sleep_start(); } -int common_hal_mcu_get_sleep_time(void) { - struct timeval now; - gettimeofday(&now, NULL); - return (now.tv_sec - sleep_enter_time.tv_sec) * 1000 + (now.tv_usec - sleep_enter_time.tv_usec) / 1000; -} - -mp_obj_t common_hal_mcu_get_wake_alarm(void) { - switch (esp_sleep_get_wakeup_cause()) { - case ESP_SLEEP_WAKEUP_TIMER: ; - //Wake up from timer. - alarm_time_obj_t *timer = m_new_obj(alarm_time_obj_t); - timer->base.type = &alarm_time_type; - return timer; - case ESP_SLEEP_WAKEUP_EXT0: ; - //Wake up from GPIO - alarm_io_obj_t *ext0 = m_new_obj(alarm_io_obj_t); - ext0->base.type = &alarm_io_type; - return ext0; - case ESP_SLEEP_WAKEUP_EXT1: - //Wake up from GPIO, returns -> esp_sleep_get_ext1_wakeup_status() - /*uint64_t wakeup_pin_mask = esp_sleep_get_ext1_wakeup_status(); - if (wakeup_pin_mask != 0) { - int pin = __builtin_ffsll(wakeup_pin_mask) - 1; - printf("Wake up from GPIO %d\n", pin); - } else { - printf("Wake up from GPIO\n"); - }*/ - break; - case ESP_SLEEP_WAKEUP_TOUCHPAD: - //TODO: implement TouchIO - //Wake up from touch on pad, returns -> esp_sleep_get_touchpad_wakeup_status() - break; - case ESP_SLEEP_WAKEUP_UNDEFINED: - default: - //Not a deep sleep reset - break; - } - return mp_const_none; -} - // The singleton microcontroller.Processor object, bound to microcontroller.cpu // It currently only has properties, and no state. const mcu_processor_obj_t common_hal_mcu_processor_obj = { diff --git a/ports/esp32s2/mpconfigport.mk b/ports/esp32s2/mpconfigport.mk index 4aaf1d00c7..1a78821d32 100644 --- a/ports/esp32s2/mpconfigport.mk +++ b/ports/esp32s2/mpconfigport.mk @@ -14,6 +14,9 @@ LONGINT_IMPL = MPZ # These modules are implemented in ports//common-hal: CIRCUITPY_FULL_BUILD = 1 +CIRCUITPY_ALARM = 1 +CIRCUITPY_ALARM_IO = 1 +CIRCUITPY_ALARM_TIME = 1 CIRCUITPY_AUDIOBUSIO = 0 CIRCUITPY_AUDIOIO = 0 CIRCUITPY_CANIO = 1 @@ -22,8 +25,7 @@ CIRCUITPY_FREQUENCYIO = 0 CIRCUITPY_I2CPERIPHERAL = 0 CIRCUITPY_ROTARYIO = 0 CIRCUITPY_NVM = 0 -CIRCUITPY_ALARM_TIME = 1 -CIRCUITPY_ALARM_IO = 1 + # We don't have enough endpoints to include MIDI. CIRCUITPY_USB_MIDI = 0 CIRCUITPY_WIFI = 1 diff --git a/ports/esp32s2/supervisor/port.c b/ports/esp32s2/supervisor/port.c index 0b9c03f747..98c064a8b7 100644 --- a/ports/esp32s2/supervisor/port.c +++ b/ports/esp32s2/supervisor/port.c @@ -34,13 +34,14 @@ #include "freertos/FreeRTOS.h" #include "freertos/task.h" -#include "common-hal/microcontroller/Pin.h" +#include "common-hal/alarm/__init__.h" #include "common-hal/analogio/AnalogOut.h" #include "common-hal/busio/I2C.h" #include "common-hal/busio/SPI.h" #include "common-hal/busio/UART.h" -#include "common-hal/pulseio/PulseIn.h" #include "common-hal/pwmio/PWMOut.h" +#include "common-hal/pulseio/PulseIn.h" +#include "common-hal/microcontroller/Pin.h" #include "common-hal/wifi/__init__.h" #include "supervisor/memory.h" #include "supervisor/shared/tick.h" @@ -87,6 +88,8 @@ safe_mode_t port_init(void) { return NO_HEAP; } + esp_wake_deep_sleep(); + return NO_SAFE_MODE; } diff --git a/py/circuitpy_defns.mk b/py/circuitpy_defns.mk index 4c57165936..cd25c01f23 100644 --- a/py/circuitpy_defns.mk +++ b/py/circuitpy_defns.mk @@ -99,6 +99,15 @@ endif ifeq ($(CIRCUITPY_AESIO),1) SRC_PATTERNS += aesio/% endif +ifeq ($(CIRCUITPY_ALARM),1) +SRC_PATTERNS += alarm/% +endif +ifeq ($(CIRCUITPY_ALARM_IO),1) +SRC_PATTERNS += alarm_io/% +endif +ifeq ($(CIRCUITPY_ALARM_TIME),1) +SRC_PATTERNS += alarm_time/% +endif ifeq ($(CIRCUITPY_ANALOGIO),1) SRC_PATTERNS += analogio/% endif @@ -259,12 +268,6 @@ endif ifeq ($(CIRCUITPY_TIME),1) SRC_PATTERNS += time/% endif -ifeq ($(CIRCUITPY_ALARM_TIME),1) -SRC_PATTERNS += alarm_time/% -endif -ifeq ($(CIRCUITPY_ALARM_IO),1) -SRC_PATTERNS += alarm_io/% -endif ifeq ($(CIRCUITPY_TOUCHIO),1) SRC_PATTERNS += touchio/% endif @@ -304,6 +307,9 @@ SRC_COMMON_HAL_ALL = \ _bleio/__init__.c \ _pew/PewPew.c \ _pew/__init__.c \ + alarm/__init__.c \ + alarm_io/__init__.c \ + alarm_time/__init__.c \ analogio/AnalogIn.c \ analogio/AnalogOut.c \ analogio/__init__.c \ @@ -366,8 +372,6 @@ SRC_COMMON_HAL_ALL = \ ssl/SSLContext.c \ supervisor/Runtime.c \ supervisor/__init__.c \ - alarm_time/__init__.c \ - alarm_io/__init__.c \ watchdog/WatchDogMode.c \ watchdog/WatchDogTimer.c \ watchdog/__init__.c \ diff --git a/py/circuitpy_mpconfig.h b/py/circuitpy_mpconfig.h index 94072f580b..778c3131b6 100644 --- a/py/circuitpy_mpconfig.h +++ b/py/circuitpy_mpconfig.h @@ -240,6 +240,27 @@ extern const struct _mp_obj_module_t aesio_module; #define AESIO_MODULE #endif +#if CIRCUITPY_ALARM +extern const struct _mp_obj_module_t alarm_module; +#define ALARM_MODULE { MP_OBJ_NEW_QSTR(MP_QSTR_alarm), (mp_obj_t)&alarm_module }, +#else +#define ALARM_MODULE +#endif + +#if CIRCUITPY_ALARM_IO +extern const struct _mp_obj_module_t alarm_io_module; +#define ALARM_IO_MODULE { MP_OBJ_NEW_QSTR(MP_QSTR_alarm_io), (mp_obj_t)&alarm_io_module }, +#else +#define ALARM_IO_MODULE +#endif + +#if CIRCUITPY_ALARM_TIME +extern const struct _mp_obj_module_t alarm_time_module; +#define ALARM_TIME_MODULE { MP_OBJ_NEW_QSTR(MP_QSTR_alarm_time), (mp_obj_t)&alarm_time_module }, +#else +#define ALARM_TIME_MODULE +#endif + #if CIRCUITPY_ANALOGIO #define ANALOGIO_MODULE { MP_OBJ_NEW_QSTR(MP_QSTR_analogio), (mp_obj_t)&analogio_module }, extern const struct _mp_obj_module_t analogio_module; @@ -663,20 +684,6 @@ extern const struct _mp_obj_module_t time_module; #define TIME_MODULE_ALT_NAME #endif -#if CIRCUITPY_ALARM_TIME -extern const struct _mp_obj_module_t alarm_time_module; -#define ALARM_TIME_MODULE { MP_OBJ_NEW_QSTR(MP_QSTR_alarm_time), (mp_obj_t)&alarm_time_module }, -#else -#define ALARM_TIME_MODULE -#endif - -#if CIRCUITPY_ALARM_IO -extern const struct _mp_obj_module_t alarm_io_module; -#define ALARM_IO_MODULE { MP_OBJ_NEW_QSTR(MP_QSTR_alarm_io), (mp_obj_t)&alarm_io_module }, -#else -#define ALARM_IO_MODULE -#endif - #if CIRCUITPY_TOUCHIO extern const struct _mp_obj_module_t touchio_module; #define TOUCHIO_MODULE { MP_OBJ_NEW_QSTR(MP_QSTR_touchio), (mp_obj_t)&touchio_module }, @@ -777,6 +784,9 @@ extern const struct _mp_obj_module_t wifi_module; // Some are omitted because they're in MICROPY_PORT_BUILTIN_MODULE_WEAK_LINKS above. #define MICROPY_PORT_BUILTIN_MODULES_STRONG_LINKS \ AESIO_MODULE \ + ALARM_MODULE \ + ALARM_IO_MODULE \ + ALARM_TIME_MODULE \ ANALOGIO_MODULE \ AUDIOBUSIO_MODULE \ AUDIOCORE_MODULE \ @@ -835,8 +845,6 @@ extern const struct _mp_obj_module_t wifi_module; STRUCT_MODULE \ SUPERVISOR_MODULE \ TOUCHIO_MODULE \ - ALARM_TIME_MODULE \ - ALARM_IO_MODULE \ UHEAP_MODULE \ USB_HID_MODULE \ USB_MIDI_MODULE \ diff --git a/py/circuitpy_mpconfig.mk b/py/circuitpy_mpconfig.mk index e8619347dd..c1790e5e35 100644 --- a/py/circuitpy_mpconfig.mk +++ b/py/circuitpy_mpconfig.mk @@ -39,6 +39,15 @@ CFLAGS += -DMICROPY_PY_ASYNC_AWAIT=$(MICROPY_PY_ASYNC_AWAIT) CIRCUITPY_AESIO ?= 0 CFLAGS += -DCIRCUITPY_AESIO=$(CIRCUITPY_AESIO) +CIRCUITPY_ALARM ?= 0 +CFLAGS += -DCIRCUITPY_ALARM=$(CIRCUITPY_ALARM) + +CIRCUITPY_ALARM_IO ?= 0 +CFLAGS += -DCIRCUITPY_ALARM_IO=$(CIRCUITPY_ALARM_IO) + +CIRCUITPY_ALARM_TIME ?= 0 +CFLAGS += -DCIRCUITPY_ALARM_TIME=$(CIRCUITPY_ALARM_TIME) + CIRCUITPY_ANALOGIO ?= 1 CFLAGS += -DCIRCUITPY_ANALOGIO=$(CIRCUITPY_ANALOGIO) @@ -234,12 +243,6 @@ CFLAGS += -DCIRCUITPY_TERMINALIO=$(CIRCUITPY_TERMINALIO) CIRCUITPY_TIME ?= 1 CFLAGS += -DCIRCUITPY_TIME=$(CIRCUITPY_TIME) -CIRCUITPY_ALARM_TIME ?= 0 -CFLAGS += -DCIRCUITPY_ALARM_TIME=$(CIRCUITPY_ALARM_TIME) - -CIRCUITPY_ALARM_IO ?= 0 -CFLAGS += -DCIRCUITPY_ALARM_IO=$(CIRCUITPY_ALARM_IO) - # touchio might be native or generic. See circuitpy_defns.mk. CIRCUITPY_TOUCHIO_USE_NATIVE ?= 0 CFLAGS += -DCIRCUITPY_TOUCHIO_USE_NATIVE=$(CIRCUITPY_TOUCHIO_USE_NATIVE) diff --git a/shared-bindings/alarm/__init__.c b/shared-bindings/alarm/__init__.c new file mode 100644 index 0000000000..51a3776934 --- /dev/null +++ b/shared-bindings/alarm/__init__.c @@ -0,0 +1,32 @@ +#include "shared-bindings/alarm/__init__.h" + +//| def getWakeAlarm() -> None: +//| """This returns the alarm that triggered wakeup, +//| also returns alarm specific parameters`. +//| +STATIC mp_obj_t alarm_get_wake_alarm(void) { + return common_hal_alarm_get_wake_alarm(); +} +STATIC MP_DEFINE_CONST_FUN_OBJ_0(alarm_get_wake_alarm_obj, alarm_get_wake_alarm); + +//| def getSleepTime() -> None: +//| """This returns the period of time in ms, +//| in which the board was in deep sleep`. +//| +STATIC mp_obj_t alarm_get_sleep_time(void) { + return mp_obj_new_int(common_hal_alarm_get_sleep_time()); +} +STATIC MP_DEFINE_CONST_FUN_OBJ_0(alarm_get_sleep_time_obj, alarm_get_sleep_time); + +STATIC const mp_rom_map_elem_t alarm_module_globals_table[] = { + { MP_ROM_QSTR(MP_QSTR___name__), MP_ROM_QSTR(MP_QSTR_alarm) }, + { MP_ROM_QSTR(MP_QSTR_getSleepTime), MP_ROM_PTR(&alarm_get_sleep_time_obj) }, + { MP_ROM_QSTR(MP_QSTR_getWakeAlarm), MP_ROM_PTR(&alarm_get_wake_alarm_obj) }, +}; + +STATIC MP_DEFINE_CONST_DICT(alarm_module_globals, alarm_module_globals_table); + +const mp_obj_module_t alarm_module = { + .base = { &mp_type_module }, + .globals = (mp_obj_dict_t*)&alarm_module_globals, +}; diff --git a/shared-bindings/alarm/__init__.h b/shared-bindings/alarm/__init__.h new file mode 100644 index 0000000000..2289028eff --- /dev/null +++ b/shared-bindings/alarm/__init__.h @@ -0,0 +1,12 @@ +#ifndef MICROPY_INCLUDED_SHARED_BINDINGS_ALARM___INIT___H +#define MICROPY_INCLUDED_SHARED_BINDINGS_ALARM___INIT___H + +#include "py/obj.h" + +#include "shared-bindings/alarm_io/__init__.h" +#include "shared-bindings/alarm_time/__init__.h" + +extern int common_hal_alarm_get_sleep_time(void); +extern mp_obj_t common_hal_alarm_get_wake_alarm(void); + +#endif // MICROPY_INCLUDED_SHARED_BINDINGS_ALARM___INIT___H diff --git a/shared-bindings/alarm_time/__init__.h b/shared-bindings/alarm_time/__init__.h index d69aa5a443..a963830693 100644 --- a/shared-bindings/alarm_time/__init__.h +++ b/shared-bindings/alarm_time/__init__.h @@ -9,7 +9,7 @@ typedef struct { extern const mp_obj_type_t alarm_time_type; -extern void common_hal_alarm_time_duration(uint32_t); +extern void common_hal_alarm_time_duration (uint32_t); extern void common_hal_alarm_time_disable (void); #endif //MICROPY_INCLUDED_SHARED_BINDINGS_ALARM_TIME___INIT___H diff --git a/shared-bindings/microcontroller/__init__.c b/shared-bindings/microcontroller/__init__.c index 7b896d99b2..eb58a40982 100644 --- a/shared-bindings/microcontroller/__init__.c +++ b/shared-bindings/microcontroller/__init__.c @@ -39,7 +39,6 @@ #include "shared-bindings/microcontroller/Pin.h" #include "shared-bindings/microcontroller/Processor.h" -#include "py/runtime.h" #include "supervisor/shared/translate.h" //| """Pin references and cpu functionality @@ -152,24 +151,6 @@ STATIC mp_obj_t mcu_sleep(void) { } STATIC MP_DEFINE_CONST_FUN_OBJ_0(mcu_sleep_obj, mcu_sleep); -//| def getWakeAlarm() -> None: -//| """This returns the alarm that triggered wakeup, -//| also returns alarm specific parameters`. -//| -STATIC mp_obj_t mcu_get_wake_alarm(void) { - return common_hal_mcu_get_wake_alarm(); -} -STATIC MP_DEFINE_CONST_FUN_OBJ_0(mcu_get_wake_alarm_obj, mcu_get_wake_alarm); - -//| def getSleepTime() -> None: -//| """This returns the period of time in ms, -//| in which the board was in deep sleep`. -//| -STATIC mp_obj_t mcu_get_sleep_time(void) { - return mp_obj_new_int(common_hal_mcu_get_sleep_time()); -} -STATIC MP_DEFINE_CONST_FUN_OBJ_0(mcu_get_sleep_time_obj, mcu_get_sleep_time); - //| nvm: Optional[ByteArray] //| """Available non-volatile memory. //| This object is the sole instance of `nvm.ByteArray` when available or ``None`` otherwise. @@ -206,8 +187,6 @@ STATIC const mp_rom_map_elem_t mcu_module_globals_table[] = { { MP_ROM_QSTR(MP_QSTR_on_next_reset), MP_ROM_PTR(&mcu_on_next_reset_obj) }, { MP_ROM_QSTR(MP_QSTR_reset), MP_ROM_PTR(&mcu_reset_obj) }, { MP_ROM_QSTR(MP_QSTR_sleep), MP_ROM_PTR(&mcu_sleep_obj) }, - { MP_ROM_QSTR(MP_QSTR_getSleepTime), MP_ROM_PTR(&mcu_get_sleep_time_obj) }, - { MP_ROM_QSTR(MP_QSTR_getWakeAlarm), MP_ROM_PTR(&mcu_get_wake_alarm_obj) }, #if CIRCUITPY_INTERNAL_NVM_SIZE > 0 { MP_ROM_QSTR(MP_QSTR_nvm), MP_ROM_PTR(&common_hal_mcu_nvm_obj) }, #else diff --git a/shared-bindings/microcontroller/__init__.h b/shared-bindings/microcontroller/__init__.h index cd234fb033..95f1cf8fc7 100644 --- a/shared-bindings/microcontroller/__init__.h +++ b/shared-bindings/microcontroller/__init__.h @@ -28,16 +28,13 @@ #ifndef MICROPY_INCLUDED_SHARED_BINDINGS_MICROCONTROLLER___INIT___H #define MICROPY_INCLUDED_SHARED_BINDINGS_MICROCONTROLLER___INIT___H -#include "py/mpconfig.h" #include "py/obj.h" +#include "py/mpconfig.h" #include "common-hal/microcontroller/Processor.h" #include "shared-bindings/microcontroller/RunMode.h" -#include "shared-bindings/alarm_io/__init__.h" -#include "shared-bindings/alarm_time/__init__.h" - extern void common_hal_mcu_delay_us(uint32_t); extern void common_hal_mcu_disable_interrupts(void); @@ -47,8 +44,6 @@ extern void common_hal_mcu_on_next_reset(mcu_runmode_t runmode); extern void common_hal_mcu_reset(void); extern void common_hal_mcu_sleep(void); -extern int common_hal_mcu_get_sleep_time(void); -extern mp_obj_t common_hal_mcu_get_wake_alarm(void); extern const mp_obj_dict_t mcu_pin_globals; From da449723df14623647729954dd5427101070d01c Mon Sep 17 00:00:00 2001 From: microDev <70126934+microDev1@users.noreply.github.com> Date: Thu, 24 Sep 2020 15:01:36 +0530 Subject: [PATCH 08/34] Fix build error --- locale/circuitpython.pot | 13 +++++--- ports/esp32s2/common-hal/alarm/__init__.c | 38 +++-------------------- ports/esp32s2/common-hal/alarm/__init__.h | 6 ---- ports/esp32s2/supervisor/port.c | 5 +-- py/circuitpy_defns.mk | 2 +- shared-bindings/alarm/__init__.c | 14 --------- shared-bindings/alarm/__init__.h | 4 --- shared-bindings/alarm_io/__init__.c | 5 --- shared-bindings/alarm_time/__init__.c | 4 --- 9 files changed, 15 insertions(+), 76 deletions(-) delete mode 100644 ports/esp32s2/common-hal/alarm/__init__.h diff --git a/locale/circuitpython.pot b/locale/circuitpython.pot index 16c3dd973a..e344f4dd81 100644 --- a/locale/circuitpython.pot +++ b/locale/circuitpython.pot @@ -17,6 +17,13 @@ msgstr "" "Content-Type: text/plain; charset=CHARSET\n" "Content-Transfer-Encoding: 8bit\n" +#: main.c +msgid "" +"\n" +"\n" +"------ soft reboot ------\n" +msgstr "" + #: main.c msgid "" "\n" @@ -3303,7 +3310,7 @@ msgstr "" msgid "size is defined for ndarrays only" msgstr "" -#: shared-bindings/time/__init__.c +#: shared-bindings/alarm_time/__init__.c shared-bindings/time/__init__.c msgid "sleep length must be non-negative" msgstr "" @@ -3319,10 +3326,6 @@ msgstr "" msgid "small int overflow" msgstr "" -#: main.c -msgid "soft reboot\n" -msgstr "" - #: extmod/ulab/code/numerical/numerical.c msgid "sort argument must be an ndarray" msgstr "" diff --git a/ports/esp32s2/common-hal/alarm/__init__.c b/ports/esp32s2/common-hal/alarm/__init__.c index 90e8e9ecc8..89ff6865de 100644 --- a/ports/esp32s2/common-hal/alarm/__init__.c +++ b/ports/esp32s2/common-hal/alarm/__init__.c @@ -25,28 +25,11 @@ * THE SOFTWARE. */ -#include - -#include "common-hal/alarm/__init__.h" #include "shared-bindings/alarm/__init__.h" +#include "shared-bindings/alarm_io/__init__.h" +#include "shared-bindings/alarm_time/__init__.h" #include "esp_sleep.h" -#include "soc/rtc_periph.h" -#include "driver/rtc_io.h" - -static RTC_DATA_ATTR struct timeval sleep_enter_time; -static RTC_DATA_ATTR struct timeval sleep_exit_time; -static RTC_DATA_ATTR uint8_t wake_io; - -int common_hal_alarm_get_sleep_time(void) { - return (sleep_exit_time.tv_sec - sleep_enter_time.tv_sec) * 1000 + (sleep_exit_time.tv_usec - sleep_enter_time.tv_usec) / 1000; -} - -void RTC_IRAM_ATTR esp_wake_deep_sleep(void) { - esp_default_wake_deep_sleep(); - wake_io = rtc_gpio_get_level(6); - gettimeofday(&sleep_exit_time, NULL); -} mp_obj_t common_hal_alarm_get_wake_alarm(void) { switch (esp_sleep_get_wakeup_cause()) { @@ -57,23 +40,12 @@ mp_obj_t common_hal_alarm_get_wake_alarm(void) { return timer; case ESP_SLEEP_WAKEUP_EXT0: ; //Wake up from GPIO - /*alarm_io_obj_t *ext0 = m_new_obj(alarm_io_obj_t); + alarm_io_obj_t *ext0 = m_new_obj(alarm_io_obj_t); ext0->base.type = &alarm_io_type; - return ext0;*/ - return mp_obj_new_int(wake_io); - case ESP_SLEEP_WAKEUP_EXT1: - //Wake up from GPIO, returns -> esp_sleep_get_ext1_wakeup_status() - /*uint64_t wakeup_pin_mask = esp_sleep_get_ext1_wakeup_status(); - if (wakeup_pin_mask != 0) { - int pin = __builtin_ffsll(wakeup_pin_mask) - 1; - printf("Wake up from GPIO %d\n", pin); - } else { - printf("Wake up from GPIO\n"); - }*/ - break; + return ext0; case ESP_SLEEP_WAKEUP_TOUCHPAD: //TODO: implement TouchIO - //Wake up from touch on pad, returns -> esp_sleep_get_touchpad_wakeup_status() + //Wake up from touch on pad, esp_sleep_get_touchpad_wakeup_status() break; case ESP_SLEEP_WAKEUP_UNDEFINED: default: diff --git a/ports/esp32s2/common-hal/alarm/__init__.h b/ports/esp32s2/common-hal/alarm/__init__.h deleted file mode 100644 index 8ba5e2b04a..0000000000 --- a/ports/esp32s2/common-hal/alarm/__init__.h +++ /dev/null @@ -1,6 +0,0 @@ -#ifndef MICROPY_INCLUDED_ESP32S2_COMMON_HAL_MICROCONTROLLER_ALARM_H -#define MICROPY_INCLUDED_ESP32S2_COMMON_HAL_MICROCONTROLLER_ALARM_H - -extern void esp_wake_deep_sleep(void); - -#endif // MICROPY_INCLUDED_ESP32S2_COMMON_HAL_MICROCONTROLLER_ALARM_H \ No newline at end of file diff --git a/ports/esp32s2/supervisor/port.c b/ports/esp32s2/supervisor/port.c index 98c064a8b7..840b979632 100644 --- a/ports/esp32s2/supervisor/port.c +++ b/ports/esp32s2/supervisor/port.c @@ -34,7 +34,6 @@ #include "freertos/FreeRTOS.h" #include "freertos/task.h" -#include "common-hal/alarm/__init__.h" #include "common-hal/analogio/AnalogOut.h" #include "common-hal/busio/I2C.h" #include "common-hal/busio/SPI.h" @@ -87,9 +86,7 @@ safe_mode_t port_init(void) { if (heap == NULL) { return NO_HEAP; } - - esp_wake_deep_sleep(); - + return NO_SAFE_MODE; } diff --git a/py/circuitpy_defns.mk b/py/circuitpy_defns.mk index cd25c01f23..473536d530 100644 --- a/py/circuitpy_defns.mk +++ b/py/circuitpy_defns.mk @@ -309,7 +309,7 @@ SRC_COMMON_HAL_ALL = \ _pew/__init__.c \ alarm/__init__.c \ alarm_io/__init__.c \ - alarm_time/__init__.c \ + alarm_time/__init__.c \ analogio/AnalogIn.c \ analogio/AnalogOut.c \ analogio/__init__.c \ diff --git a/shared-bindings/alarm/__init__.c b/shared-bindings/alarm/__init__.c index 51a3776934..37462d88cc 100644 --- a/shared-bindings/alarm/__init__.c +++ b/shared-bindings/alarm/__init__.c @@ -1,26 +1,12 @@ #include "shared-bindings/alarm/__init__.h" -//| def getWakeAlarm() -> None: -//| """This returns the alarm that triggered wakeup, -//| also returns alarm specific parameters`. -//| STATIC mp_obj_t alarm_get_wake_alarm(void) { return common_hal_alarm_get_wake_alarm(); } STATIC MP_DEFINE_CONST_FUN_OBJ_0(alarm_get_wake_alarm_obj, alarm_get_wake_alarm); -//| def getSleepTime() -> None: -//| """This returns the period of time in ms, -//| in which the board was in deep sleep`. -//| -STATIC mp_obj_t alarm_get_sleep_time(void) { - return mp_obj_new_int(common_hal_alarm_get_sleep_time()); -} -STATIC MP_DEFINE_CONST_FUN_OBJ_0(alarm_get_sleep_time_obj, alarm_get_sleep_time); - STATIC const mp_rom_map_elem_t alarm_module_globals_table[] = { { MP_ROM_QSTR(MP_QSTR___name__), MP_ROM_QSTR(MP_QSTR_alarm) }, - { MP_ROM_QSTR(MP_QSTR_getSleepTime), MP_ROM_PTR(&alarm_get_sleep_time_obj) }, { MP_ROM_QSTR(MP_QSTR_getWakeAlarm), MP_ROM_PTR(&alarm_get_wake_alarm_obj) }, }; diff --git a/shared-bindings/alarm/__init__.h b/shared-bindings/alarm/__init__.h index 2289028eff..8b2cd9f770 100644 --- a/shared-bindings/alarm/__init__.h +++ b/shared-bindings/alarm/__init__.h @@ -3,10 +3,6 @@ #include "py/obj.h" -#include "shared-bindings/alarm_io/__init__.h" -#include "shared-bindings/alarm_time/__init__.h" - -extern int common_hal_alarm_get_sleep_time(void); extern mp_obj_t common_hal_alarm_get_wake_alarm(void); #endif // MICROPY_INCLUDED_SHARED_BINDINGS_ALARM___INIT___H diff --git a/shared-bindings/alarm_io/__init__.c b/shared-bindings/alarm_io/__init__.c index 09783d0d08..d772ccb796 100644 --- a/shared-bindings/alarm_io/__init__.c +++ b/shared-bindings/alarm_io/__init__.c @@ -3,8 +3,6 @@ #include "shared-bindings/alarm_io/__init__.h" #include "shared-bindings/microcontroller/Pin.h" -//| Set Pin Wakeup -//| STATIC mp_obj_t alarm_io_pin_state(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) { enum { ARG_level, ARG_pull }; static const mp_arg_t allowed_args[] = { @@ -27,9 +25,6 @@ STATIC mp_obj_t alarm_io_pin_state(size_t n_args, const mp_obj_t *pos_args, mp_m } STATIC MP_DEFINE_CONST_FUN_OBJ_KW(alarm_io_pin_state_obj, 1, alarm_io_pin_state); - -//| Disable Pin Wakeup -//| STATIC mp_obj_t alarm_io_disable(void) { common_hal_alarm_io_disable(); return mp_const_none; diff --git a/shared-bindings/alarm_time/__init__.c b/shared-bindings/alarm_time/__init__.c index 22fb935064..d4474ea2de 100644 --- a/shared-bindings/alarm_time/__init__.c +++ b/shared-bindings/alarm_time/__init__.c @@ -1,8 +1,6 @@ #include "py/obj.h" #include "shared-bindings/alarm_time/__init__.h" -//| Set Timer Wakeup -//| STATIC mp_obj_t alarm_time_duration(mp_obj_t seconds_o) { #if MICROPY_PY_BUILTINS_FLOAT mp_float_t seconds = mp_obj_get_float(seconds_o); @@ -24,8 +22,6 @@ STATIC mp_obj_t alarm_time_duration(mp_obj_t seconds_o) { } STATIC MP_DEFINE_CONST_FUN_OBJ_1(alarm_time_duration_obj, alarm_time_duration); -//| Disable Timer Wakeup -//| STATIC mp_obj_t alarm_time_disable(void) { common_hal_alarm_time_disable(); return mp_const_none; From 59df1a11ade4a39d079c9f418740b45b4d6121ce Mon Sep 17 00:00:00 2001 From: microDev <70126934+microDev1@users.noreply.github.com> Date: Fri, 25 Sep 2020 00:28:50 +0530 Subject: [PATCH 09/34] Add alarm_touch module --- ports/esp32s2/common-hal/alarm/__init__.c | 10 ++++---- ports/esp32s2/common-hal/alarm_io/__init__.c | 12 +++++----- .../esp32s2/common-hal/alarm_time/__init__.c | 4 ++-- .../esp32s2/common-hal/alarm_touch/__init__.c | 7 ++++++ .../common-hal/microcontroller/__init__.c | 2 +- ports/esp32s2/mpconfigport.mk | 1 + ports/esp32s2/supervisor/port.c | 2 +- py/circuitpy_defns.mk | 4 ++++ py/circuitpy_mpconfig.h | 8 +++++++ py/circuitpy_mpconfig.mk | 3 +++ shared-bindings/alarm_io/__init__.c | 10 ++++---- shared-bindings/alarm_time/__init__.c | 4 ++-- shared-bindings/alarm_touch/__init__.c | 24 +++++++++++++++++++ shared-bindings/alarm_touch/__init__.h | 14 +++++++++++ shared-bindings/microcontroller/__init__.c | 9 ------- 15 files changed, 83 insertions(+), 31 deletions(-) create mode 100644 ports/esp32s2/common-hal/alarm_touch/__init__.c create mode 100644 shared-bindings/alarm_touch/__init__.c create mode 100644 shared-bindings/alarm_touch/__init__.h diff --git a/ports/esp32s2/common-hal/alarm/__init__.c b/ports/esp32s2/common-hal/alarm/__init__.c index 89ff6865de..46715d9bf6 100644 --- a/ports/esp32s2/common-hal/alarm/__init__.c +++ b/ports/esp32s2/common-hal/alarm/__init__.c @@ -36,17 +36,17 @@ mp_obj_t common_hal_alarm_get_wake_alarm(void) { case ESP_SLEEP_WAKEUP_TIMER: ; //Wake up from timer. alarm_time_obj_t *timer = m_new_obj(alarm_time_obj_t); - timer->base.type = &alarm_time_type; + timer->base.type = &alarm_time_type; return timer; case ESP_SLEEP_WAKEUP_EXT0: ; //Wake up from GPIO alarm_io_obj_t *ext0 = m_new_obj(alarm_io_obj_t); - ext0->base.type = &alarm_io_type; - return ext0; - case ESP_SLEEP_WAKEUP_TOUCHPAD: + ext0->base.type = &alarm_io_type; + return ext0; + case ESP_SLEEP_WAKEUP_TOUCHPAD: //TODO: implement TouchIO //Wake up from touch on pad, esp_sleep_get_touchpad_wakeup_status() - break; + break; case ESP_SLEEP_WAKEUP_UNDEFINED: default: //Not a deep sleep reset diff --git a/ports/esp32s2/common-hal/alarm_io/__init__.c b/ports/esp32s2/common-hal/alarm_io/__init__.c index 9aa28f4156..a98b933246 100644 --- a/ports/esp32s2/common-hal/alarm_io/__init__.c +++ b/ports/esp32s2/common-hal/alarm_io/__init__.c @@ -5,22 +5,22 @@ mp_obj_t common_hal_alarm_io_pin_state (alarm_io_obj_t *self_in) { if (!rtc_gpio_is_valid_gpio(self_in->gpio)) { - mp_raise_ValueError(translate("io must be rtc io")); - } + mp_raise_ValueError(translate("io must be rtc io")); + } switch(esp_sleep_enable_ext0_wakeup(self_in->gpio, self_in->level)) { case ESP_ERR_INVALID_ARG: mp_raise_ValueError(translate("trigger level must be 0 or 1")); case ESP_ERR_INVALID_STATE: mp_raise_RuntimeError(translate("wakeup conflict")); - default: - break; + default: + break; } if (self_in->pull) { (self_in->level) ? rtc_gpio_pulldown_en(self_in->gpio) : rtc_gpio_pullup_en(self_in->gpio); } - return self_in; -} + return self_in; +} void common_hal_alarm_io_disable (void) { esp_sleep_disable_wakeup_source(ESP_SLEEP_WAKEUP_EXT0 | ESP_SLEEP_WAKEUP_EXT1); diff --git a/ports/esp32s2/common-hal/alarm_time/__init__.c b/ports/esp32s2/common-hal/alarm_time/__init__.c index fb601e6be0..252b6e107c 100644 --- a/ports/esp32s2/common-hal/alarm_time/__init__.c +++ b/ports/esp32s2/common-hal/alarm_time/__init__.c @@ -5,8 +5,8 @@ void common_hal_alarm_time_duration (uint32_t ms) { if (esp_sleep_enable_timer_wakeup((ms) * 1000) == ESP_ERR_INVALID_ARG) { mp_raise_ValueError(translate("time out of range")); - } -} + } +} void common_hal_alarm_time_disable (void) { esp_sleep_disable_wakeup_source(ESP_SLEEP_WAKEUP_TIMER); diff --git a/ports/esp32s2/common-hal/alarm_touch/__init__.c b/ports/esp32s2/common-hal/alarm_touch/__init__.c new file mode 100644 index 0000000000..df32b26930 --- /dev/null +++ b/ports/esp32s2/common-hal/alarm_touch/__init__.c @@ -0,0 +1,7 @@ +#include "esp_sleep.h" + +#include "shared-bindings/alarm_touch/__init__.h" + +void common_hal_alarm_touch_disable (void) { + esp_sleep_disable_wakeup_source(ESP_SLEEP_WAKEUP_TOUCHPAD); +} diff --git a/ports/esp32s2/common-hal/microcontroller/__init__.c b/ports/esp32s2/common-hal/microcontroller/__init__.c index ba24e1c48d..f1dc24bb89 100644 --- a/ports/esp32s2/common-hal/microcontroller/__init__.c +++ b/ports/esp32s2/common-hal/microcontroller/__init__.c @@ -80,7 +80,7 @@ void common_hal_mcu_reset(void) { } void common_hal_mcu_sleep(void) { - esp_deep_sleep_start(); + esp_deep_sleep_start(); } // The singleton microcontroller.Processor object, bound to microcontroller.cpu diff --git a/ports/esp32s2/mpconfigport.mk b/ports/esp32s2/mpconfigport.mk index 1a78821d32..7024ceb630 100644 --- a/ports/esp32s2/mpconfigport.mk +++ b/ports/esp32s2/mpconfigport.mk @@ -17,6 +17,7 @@ CIRCUITPY_FULL_BUILD = 1 CIRCUITPY_ALARM = 1 CIRCUITPY_ALARM_IO = 1 CIRCUITPY_ALARM_TIME = 1 +CIRCUITPY_ALARM_TOUCH = 1 CIRCUITPY_AUDIOBUSIO = 0 CIRCUITPY_AUDIOIO = 0 CIRCUITPY_CANIO = 1 diff --git a/ports/esp32s2/supervisor/port.c b/ports/esp32s2/supervisor/port.c index 840b979632..df6755783d 100644 --- a/ports/esp32s2/supervisor/port.c +++ b/ports/esp32s2/supervisor/port.c @@ -86,7 +86,7 @@ safe_mode_t port_init(void) { if (heap == NULL) { return NO_HEAP; } - + return NO_SAFE_MODE; } diff --git a/py/circuitpy_defns.mk b/py/circuitpy_defns.mk index 473536d530..72091decbf 100644 --- a/py/circuitpy_defns.mk +++ b/py/circuitpy_defns.mk @@ -108,6 +108,9 @@ endif ifeq ($(CIRCUITPY_ALARM_TIME),1) SRC_PATTERNS += alarm_time/% endif +ifeq ($(CIRCUITPY_ALARM_TIME),1) +SRC_PATTERNS += alarm_touch/% +endif ifeq ($(CIRCUITPY_ANALOGIO),1) SRC_PATTERNS += analogio/% endif @@ -310,6 +313,7 @@ SRC_COMMON_HAL_ALL = \ alarm/__init__.c \ alarm_io/__init__.c \ alarm_time/__init__.c \ + alarm_touch/__init__.c \ analogio/AnalogIn.c \ analogio/AnalogOut.c \ analogio/__init__.c \ diff --git a/py/circuitpy_mpconfig.h b/py/circuitpy_mpconfig.h index 778c3131b6..c8141a99a6 100644 --- a/py/circuitpy_mpconfig.h +++ b/py/circuitpy_mpconfig.h @@ -261,6 +261,13 @@ extern const struct _mp_obj_module_t alarm_time_module; #define ALARM_TIME_MODULE #endif +#if CIRCUITPY_ALARM_TOUCH +extern const struct _mp_obj_module_t alarm_touch_module; +#define ALARM_TOUCH_MODULE { MP_OBJ_NEW_QSTR(MP_QSTR_alarm_touch), (mp_obj_t)&alarm_touch_module }, +#else +#define ALARM_TOUCH_MODULE +#endif + #if CIRCUITPY_ANALOGIO #define ANALOGIO_MODULE { MP_OBJ_NEW_QSTR(MP_QSTR_analogio), (mp_obj_t)&analogio_module }, extern const struct _mp_obj_module_t analogio_module; @@ -787,6 +794,7 @@ extern const struct _mp_obj_module_t wifi_module; ALARM_MODULE \ ALARM_IO_MODULE \ ALARM_TIME_MODULE \ + ALARM_TOUCH_MODULE \ ANALOGIO_MODULE \ AUDIOBUSIO_MODULE \ AUDIOCORE_MODULE \ diff --git a/py/circuitpy_mpconfig.mk b/py/circuitpy_mpconfig.mk index c1790e5e35..59d23e4667 100644 --- a/py/circuitpy_mpconfig.mk +++ b/py/circuitpy_mpconfig.mk @@ -48,6 +48,9 @@ CFLAGS += -DCIRCUITPY_ALARM_IO=$(CIRCUITPY_ALARM_IO) CIRCUITPY_ALARM_TIME ?= 0 CFLAGS += -DCIRCUITPY_ALARM_TIME=$(CIRCUITPY_ALARM_TIME) +CIRCUITPY_ALARM_TOUCH ?= 0 +CFLAGS += -DCIRCUITPY_ALARM_TOUCH=$(CIRCUITPY_ALARM_TOUCH) + CIRCUITPY_ANALOGIO ?= 1 CFLAGS += -DCIRCUITPY_ANALOGIO=$(CIRCUITPY_ANALOGIO) diff --git a/shared-bindings/alarm_io/__init__.c b/shared-bindings/alarm_io/__init__.c index d772ccb796..dbe4671763 100644 --- a/shared-bindings/alarm_io/__init__.c +++ b/shared-bindings/alarm_io/__init__.c @@ -3,15 +3,15 @@ #include "shared-bindings/alarm_io/__init__.h" #include "shared-bindings/microcontroller/Pin.h" -STATIC mp_obj_t alarm_io_pin_state(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) { +STATIC mp_obj_t alarm_io_pin_state(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) { enum { ARG_level, ARG_pull }; static const mp_arg_t allowed_args[] = { { MP_QSTR_level, MP_ARG_INT | MP_ARG_KW_ONLY | MP_ARG_REQUIRED }, { MP_QSTR_pull, MP_ARG_INT | MP_ARG_KW_ONLY, {.u_bool = false} }, - }; + }; mp_arg_val_t args[MP_ARRAY_SIZE(allowed_args)]; - mp_arg_parse_all(n_args - 1, pos_args + 1, kw_args, MP_ARRAY_SIZE(allowed_args), allowed_args, args); + mp_arg_parse_all(n_args - 1, pos_args + 1, kw_args, MP_ARRAY_SIZE(allowed_args), allowed_args, args); mcu_pin_obj_t *pin = validate_obj_is_pin(pos_args[0]); alarm_io_obj_t *self = m_new_obj(alarm_io_obj_t); @@ -20,12 +20,12 @@ STATIC mp_obj_t alarm_io_pin_state(size_t n_args, const mp_obj_t *pos_args, mp_m self->gpio = pin->number; self->level = args[ARG_level].u_int; self->pull = args[ARG_pull].u_bool; - + return common_hal_alarm_io_pin_state(self); } STATIC MP_DEFINE_CONST_FUN_OBJ_KW(alarm_io_pin_state_obj, 1, alarm_io_pin_state); -STATIC mp_obj_t alarm_io_disable(void) { +STATIC mp_obj_t alarm_io_disable(void) { common_hal_alarm_io_disable(); return mp_const_none; } diff --git a/shared-bindings/alarm_time/__init__.c b/shared-bindings/alarm_time/__init__.c index d4474ea2de..218ac68575 100644 --- a/shared-bindings/alarm_time/__init__.c +++ b/shared-bindings/alarm_time/__init__.c @@ -1,7 +1,7 @@ #include "py/obj.h" #include "shared-bindings/alarm_time/__init__.h" -STATIC mp_obj_t alarm_time_duration(mp_obj_t seconds_o) { +STATIC mp_obj_t alarm_time_duration(mp_obj_t seconds_o) { #if MICROPY_PY_BUILTINS_FLOAT mp_float_t seconds = mp_obj_get_float(seconds_o); mp_float_t msecs = 1000.0f * seconds + 0.5f; @@ -22,7 +22,7 @@ STATIC mp_obj_t alarm_time_duration(mp_obj_t seconds_o) { } STATIC MP_DEFINE_CONST_FUN_OBJ_1(alarm_time_duration_obj, alarm_time_duration); -STATIC mp_obj_t alarm_time_disable(void) { +STATIC mp_obj_t alarm_time_disable(void) { common_hal_alarm_time_disable(); return mp_const_none; } diff --git a/shared-bindings/alarm_touch/__init__.c b/shared-bindings/alarm_touch/__init__.c new file mode 100644 index 0000000000..e36fa73cb8 --- /dev/null +++ b/shared-bindings/alarm_touch/__init__.c @@ -0,0 +1,24 @@ +#include "py/obj.h" +#include "shared-bindings/alarm_touch/__init__.h" + +STATIC mp_obj_t alarm_touch_disable(void) { + common_hal_alarm_touch_disable(); + return mp_const_none; +} +STATIC MP_DEFINE_CONST_FUN_OBJ_0(alarm_touch_disable_obj, alarm_touch_disable); + +STATIC const mp_rom_map_elem_t alarm_touch_module_globals_table[] = { + { MP_ROM_QSTR(MP_QSTR___name__), MP_ROM_QSTR(MP_QSTR_alarm_touch) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_Disable), MP_ROM_PTR(&alarm_touch_disable_obj) }, +}; +STATIC MP_DEFINE_CONST_DICT(alarm_touch_module_globals, alarm_touch_module_globals_table); + +const mp_obj_module_t alarm_touch_module = { + .base = { &mp_type_module }, + .globals = (mp_obj_dict_t*)&alarm_touch_module_globals, +}; + +const mp_obj_type_t alarm_touch_type = { + { &mp_type_type }, + .name = MP_QSTR_touchAlarm, +}; diff --git a/shared-bindings/alarm_touch/__init__.h b/shared-bindings/alarm_touch/__init__.h new file mode 100644 index 0000000000..600587d247 --- /dev/null +++ b/shared-bindings/alarm_touch/__init__.h @@ -0,0 +1,14 @@ +#ifndef MICROPY_INCLUDED_SHARED_BINDINGS_ALARM_TOUCH___INIT___H +#define MICROPY_INCLUDED_SHARED_BINDINGS_ALARM_TOUCH___INIT___H + +#include "py/runtime.h" + +typedef struct { + mp_obj_base_t base; +} alarm_touch_obj_t; + +extern const mp_obj_type_t alarm_touch_type; + +extern void common_hal_alarm_touch_disable (void); + +#endif //MICROPY_INCLUDED_SHARED_BINDINGS_ALARM_TOUCH___INIT___H diff --git a/shared-bindings/microcontroller/__init__.c b/shared-bindings/microcontroller/__init__.c index eb58a40982..88dc4179d6 100644 --- a/shared-bindings/microcontroller/__init__.c +++ b/shared-bindings/microcontroller/__init__.c @@ -135,15 +135,6 @@ STATIC mp_obj_t mcu_reset(void) { } STATIC MP_DEFINE_CONST_FUN_OBJ_0(mcu_reset_obj, mcu_reset); -//| def sleep() -> None: -//| """Microcontroller will go into deep sleep. -//| cpy will restart when wakeup func. is triggered`. -//| -//| .. warning:: This may result in file system corruption when connected to a -//| host computer. Be very careful when calling this! Make sure the device -//| "Safely removed" on Windows or "ejected" on Mac OSX and Linux.""" -//| ... -//| STATIC mp_obj_t mcu_sleep(void) { common_hal_mcu_sleep(); // We won't actually get here because mcu is going into sleep. From e35938971a4e9c0177e68163e1baab3b25c17ca8 Mon Sep 17 00:00:00 2001 From: microDev <70126934+microDev1@users.noreply.github.com> Date: Fri, 25 Sep 2020 03:32:31 +0530 Subject: [PATCH 10/34] Add description of alarm modules --- ports/atmel-samd/common-hal/microcontroller/__init__.c | 4 ++++ ports/cxd56/common-hal/microcontroller/__init__.c | 4 ++++ ports/litex/common-hal/microcontroller/__init__.c | 4 ++++ ports/mimxrt10xx/common-hal/microcontroller/__init__.c | 4 ++++ ports/nrf/common-hal/microcontroller/__init__.c | 4 ++++ ports/stm/common-hal/microcontroller/__init__.c | 4 ++++ shared-bindings/alarm/__init__.c | 4 ++++ shared-bindings/alarm_io/__init__.c | 4 ++++ shared-bindings/alarm_time/__init__.c | 4 ++++ shared-bindings/alarm_touch/__init__.c | 4 ++++ 10 files changed, 40 insertions(+) diff --git a/ports/atmel-samd/common-hal/microcontroller/__init__.c b/ports/atmel-samd/common-hal/microcontroller/__init__.c index 50a1ec038e..b3ff06b62f 100644 --- a/ports/atmel-samd/common-hal/microcontroller/__init__.c +++ b/ports/atmel-samd/common-hal/microcontroller/__init__.c @@ -84,6 +84,10 @@ void common_hal_mcu_reset(void) { reset(); } +void common_hal_mcu_sleep(void) { + //deep sleep call here +} + // The singleton microcontroller.Processor object, bound to microcontroller.cpu // It currently only has properties, and no state. const mcu_processor_obj_t common_hal_mcu_processor_obj = { diff --git a/ports/cxd56/common-hal/microcontroller/__init__.c b/ports/cxd56/common-hal/microcontroller/__init__.c index 7aa3b839d7..4379f9be66 100644 --- a/ports/cxd56/common-hal/microcontroller/__init__.c +++ b/ports/cxd56/common-hal/microcontroller/__init__.c @@ -81,6 +81,10 @@ void common_hal_mcu_reset(void) { boardctl(BOARDIOC_RESET, 0); } +void common_hal_mcu_sleep(void) { + //deep sleep call here +} + STATIC const mp_rom_map_elem_t mcu_pin_globals_table[] = { { MP_ROM_QSTR(MP_QSTR_UART2_RXD), MP_ROM_PTR(&pin_UART2_RXD) }, { MP_ROM_QSTR(MP_QSTR_UART2_TXD), MP_ROM_PTR(&pin_UART2_TXD) }, diff --git a/ports/litex/common-hal/microcontroller/__init__.c b/ports/litex/common-hal/microcontroller/__init__.c index 3c91661144..3b1628c39a 100644 --- a/ports/litex/common-hal/microcontroller/__init__.c +++ b/ports/litex/common-hal/microcontroller/__init__.c @@ -89,6 +89,10 @@ void common_hal_mcu_reset(void) { while(1); } +void common_hal_mcu_sleep(void) { + //deep sleep call here +} + // The singleton microcontroller.Processor object, bound to microcontroller.cpu // It currently only has properties, and no state. const mcu_processor_obj_t common_hal_mcu_processor_obj = { diff --git a/ports/mimxrt10xx/common-hal/microcontroller/__init__.c b/ports/mimxrt10xx/common-hal/microcontroller/__init__.c index 6a8537e2da..c7bc7eb9e8 100644 --- a/ports/mimxrt10xx/common-hal/microcontroller/__init__.c +++ b/ports/mimxrt10xx/common-hal/microcontroller/__init__.c @@ -86,6 +86,10 @@ void common_hal_mcu_reset(void) { NVIC_SystemReset(); } +void common_hal_mcu_sleep(void) { + //deep sleep call here +} + // The singleton microcontroller.Processor object, bound to microcontroller.cpu // It currently only has properties, and no state. const mcu_processor_obj_t common_hal_mcu_processor_obj = { diff --git a/ports/nrf/common-hal/microcontroller/__init__.c b/ports/nrf/common-hal/microcontroller/__init__.c index 06aac9409d..ff6c658b8b 100644 --- a/ports/nrf/common-hal/microcontroller/__init__.c +++ b/ports/nrf/common-hal/microcontroller/__init__.c @@ -95,6 +95,10 @@ void common_hal_mcu_reset(void) { reset_cpu(); } +void common_hal_mcu_sleep(void) { + //deep sleep call here +} + // The singleton microcontroller.Processor object, bound to microcontroller.cpu // It currently only has properties, and no state. const mcu_processor_obj_t common_hal_mcu_processor_obj = { diff --git a/ports/stm/common-hal/microcontroller/__init__.c b/ports/stm/common-hal/microcontroller/__init__.c index a827399ccb..2a60c53426 100644 --- a/ports/stm/common-hal/microcontroller/__init__.c +++ b/ports/stm/common-hal/microcontroller/__init__.c @@ -81,6 +81,10 @@ void common_hal_mcu_reset(void) { NVIC_SystemReset(); } +void common_hal_mcu_sleep(void) { + //deep sleep call here +} + // The singleton microcontroller.Processor object, bound to microcontroller.cpu // It currently only has properties, and no state. const mcu_processor_obj_t common_hal_mcu_processor_obj = { diff --git a/shared-bindings/alarm/__init__.c b/shared-bindings/alarm/__init__.c index 37462d88cc..88c4bc8878 100644 --- a/shared-bindings/alarm/__init__.c +++ b/shared-bindings/alarm/__init__.c @@ -1,5 +1,9 @@ #include "shared-bindings/alarm/__init__.h" +//| """alarm module +//| +//| The `alarm` module implements deep sleep.""" + STATIC mp_obj_t alarm_get_wake_alarm(void) { return common_hal_alarm_get_wake_alarm(); } diff --git a/shared-bindings/alarm_io/__init__.c b/shared-bindings/alarm_io/__init__.c index dbe4671763..4e42f9a2e1 100644 --- a/shared-bindings/alarm_io/__init__.c +++ b/shared-bindings/alarm_io/__init__.c @@ -3,6 +3,10 @@ #include "shared-bindings/alarm_io/__init__.h" #include "shared-bindings/microcontroller/Pin.h" +//| """alarm_io module +//| +//| The `alarm_io` module implements deep sleep.""" + STATIC mp_obj_t alarm_io_pin_state(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) { enum { ARG_level, ARG_pull }; static const mp_arg_t allowed_args[] = { diff --git a/shared-bindings/alarm_time/__init__.c b/shared-bindings/alarm_time/__init__.c index 218ac68575..1707f7488f 100644 --- a/shared-bindings/alarm_time/__init__.c +++ b/shared-bindings/alarm_time/__init__.c @@ -1,6 +1,10 @@ #include "py/obj.h" #include "shared-bindings/alarm_time/__init__.h" +//| """alarm_time module +//| +//| The `alarm_time` module implements deep sleep.""" + STATIC mp_obj_t alarm_time_duration(mp_obj_t seconds_o) { #if MICROPY_PY_BUILTINS_FLOAT mp_float_t seconds = mp_obj_get_float(seconds_o); diff --git a/shared-bindings/alarm_touch/__init__.c b/shared-bindings/alarm_touch/__init__.c index e36fa73cb8..5f5a156d80 100644 --- a/shared-bindings/alarm_touch/__init__.c +++ b/shared-bindings/alarm_touch/__init__.c @@ -1,6 +1,10 @@ #include "py/obj.h" #include "shared-bindings/alarm_touch/__init__.h" +//| """alarm_touch module +//| +//| The `alarm_touch` module implements deep sleep.""" + STATIC mp_obj_t alarm_touch_disable(void) { common_hal_alarm_touch_disable(); return mp_const_none; From 930cf14dcef3e3552a0e7d7476fd89b873738c2d Mon Sep 17 00:00:00 2001 From: microDev <70126934+microDev1@users.noreply.github.com> Date: Sat, 26 Sep 2020 11:15:50 +0530 Subject: [PATCH 11/34] Add check for invalid io, function to disable all alarms --- ports/atmel-samd/common-hal/microcontroller/__init__.c | 2 +- ports/cxd56/common-hal/microcontroller/__init__.c | 2 +- ports/esp32s2/common-hal/alarm/__init__.c | 4 ++++ ports/esp32s2/common-hal/alarm_io/__init__.c | 8 ++++++++ ports/esp32s2/common-hal/microcontroller/__init__.c | 2 +- ports/litex/common-hal/microcontroller/__init__.c | 2 +- ports/mimxrt10xx/common-hal/microcontroller/__init__.c | 2 +- ports/nrf/common-hal/microcontroller/__init__.c | 2 +- ports/stm/common-hal/microcontroller/__init__.c | 2 +- py/circuitpy_defns.mk | 2 +- shared-bindings/alarm/__init__.c | 9 ++++++++- shared-bindings/alarm/__init__.h | 1 + shared-bindings/microcontroller/__init__.c | 3 ++- shared-bindings/microcontroller/__init__.h | 2 +- 14 files changed, 32 insertions(+), 11 deletions(-) diff --git a/ports/atmel-samd/common-hal/microcontroller/__init__.c b/ports/atmel-samd/common-hal/microcontroller/__init__.c index b3ff06b62f..ca39f28386 100644 --- a/ports/atmel-samd/common-hal/microcontroller/__init__.c +++ b/ports/atmel-samd/common-hal/microcontroller/__init__.c @@ -84,7 +84,7 @@ void common_hal_mcu_reset(void) { reset(); } -void common_hal_mcu_sleep(void) { +void common_hal_mcu_deep_sleep(void) { //deep sleep call here } diff --git a/ports/cxd56/common-hal/microcontroller/__init__.c b/ports/cxd56/common-hal/microcontroller/__init__.c index 4379f9be66..57140dec70 100644 --- a/ports/cxd56/common-hal/microcontroller/__init__.c +++ b/ports/cxd56/common-hal/microcontroller/__init__.c @@ -81,7 +81,7 @@ void common_hal_mcu_reset(void) { boardctl(BOARDIOC_RESET, 0); } -void common_hal_mcu_sleep(void) { +void common_hal_mcu_deep_sleep(void) { //deep sleep call here } diff --git a/ports/esp32s2/common-hal/alarm/__init__.c b/ports/esp32s2/common-hal/alarm/__init__.c index 46715d9bf6..552ad4452b 100644 --- a/ports/esp32s2/common-hal/alarm/__init__.c +++ b/ports/esp32s2/common-hal/alarm/__init__.c @@ -31,6 +31,10 @@ #include "esp_sleep.h" +void common_hal_alarm_disable_all(void) { + esp_sleep_disable_wakeup_source(ESP_SLEEP_WAKEUP_ALL); +} + mp_obj_t common_hal_alarm_get_wake_alarm(void) { switch (esp_sleep_get_wakeup_cause()) { case ESP_SLEEP_WAKEUP_TIMER: ; diff --git a/ports/esp32s2/common-hal/alarm_io/__init__.c b/ports/esp32s2/common-hal/alarm_io/__init__.c index a98b933246..b39693c6af 100644 --- a/ports/esp32s2/common-hal/alarm_io/__init__.c +++ b/ports/esp32s2/common-hal/alarm_io/__init__.c @@ -8,6 +8,14 @@ mp_obj_t common_hal_alarm_io_pin_state (alarm_io_obj_t *self_in) { mp_raise_ValueError(translate("io must be rtc io")); } + if (self_in->pull && !self_in->level) { + for (uint8_t i = 0; i<=4; i+=2) { + if (self_in->gpio == i) { + mp_raise_ValueError(translate("IOs 0, 2 & 4 do not support internal pullup in sleep")); + } + } + } + switch(esp_sleep_enable_ext0_wakeup(self_in->gpio, self_in->level)) { case ESP_ERR_INVALID_ARG: mp_raise_ValueError(translate("trigger level must be 0 or 1")); diff --git a/ports/esp32s2/common-hal/microcontroller/__init__.c b/ports/esp32s2/common-hal/microcontroller/__init__.c index f1dc24bb89..ab0e1bfaa4 100644 --- a/ports/esp32s2/common-hal/microcontroller/__init__.c +++ b/ports/esp32s2/common-hal/microcontroller/__init__.c @@ -79,7 +79,7 @@ void common_hal_mcu_reset(void) { while(1); } -void common_hal_mcu_sleep(void) { +void common_hal_mcu_deep_sleep(void) { esp_deep_sleep_start(); } diff --git a/ports/litex/common-hal/microcontroller/__init__.c b/ports/litex/common-hal/microcontroller/__init__.c index 3b1628c39a..e6f50ed5a6 100644 --- a/ports/litex/common-hal/microcontroller/__init__.c +++ b/ports/litex/common-hal/microcontroller/__init__.c @@ -89,7 +89,7 @@ void common_hal_mcu_reset(void) { while(1); } -void common_hal_mcu_sleep(void) { +void common_hal_mcu_deep_sleep(void) { //deep sleep call here } diff --git a/ports/mimxrt10xx/common-hal/microcontroller/__init__.c b/ports/mimxrt10xx/common-hal/microcontroller/__init__.c index c7bc7eb9e8..0329ced69b 100644 --- a/ports/mimxrt10xx/common-hal/microcontroller/__init__.c +++ b/ports/mimxrt10xx/common-hal/microcontroller/__init__.c @@ -86,7 +86,7 @@ void common_hal_mcu_reset(void) { NVIC_SystemReset(); } -void common_hal_mcu_sleep(void) { +void common_hal_mcu_deep_sleep(void) { //deep sleep call here } diff --git a/ports/nrf/common-hal/microcontroller/__init__.c b/ports/nrf/common-hal/microcontroller/__init__.c index ff6c658b8b..9911896bff 100644 --- a/ports/nrf/common-hal/microcontroller/__init__.c +++ b/ports/nrf/common-hal/microcontroller/__init__.c @@ -95,7 +95,7 @@ void common_hal_mcu_reset(void) { reset_cpu(); } -void common_hal_mcu_sleep(void) { +void common_hal_mcu_deep_sleep(void) { //deep sleep call here } diff --git a/ports/stm/common-hal/microcontroller/__init__.c b/ports/stm/common-hal/microcontroller/__init__.c index 2a60c53426..bc81b0e4f5 100644 --- a/ports/stm/common-hal/microcontroller/__init__.c +++ b/ports/stm/common-hal/microcontroller/__init__.c @@ -81,7 +81,7 @@ void common_hal_mcu_reset(void) { NVIC_SystemReset(); } -void common_hal_mcu_sleep(void) { +void common_hal_mcu_deep_sleep(void) { //deep sleep call here } diff --git a/py/circuitpy_defns.mk b/py/circuitpy_defns.mk index 72091decbf..7e17934a56 100644 --- a/py/circuitpy_defns.mk +++ b/py/circuitpy_defns.mk @@ -108,7 +108,7 @@ endif ifeq ($(CIRCUITPY_ALARM_TIME),1) SRC_PATTERNS += alarm_time/% endif -ifeq ($(CIRCUITPY_ALARM_TIME),1) +ifeq ($(CIRCUITPY_ALARM_TOUCH),1) SRC_PATTERNS += alarm_touch/% endif ifeq ($(CIRCUITPY_ANALOGIO),1) diff --git a/shared-bindings/alarm/__init__.c b/shared-bindings/alarm/__init__.c index 88c4bc8878..f43c2ea12d 100644 --- a/shared-bindings/alarm/__init__.c +++ b/shared-bindings/alarm/__init__.c @@ -4,6 +4,12 @@ //| //| The `alarm` module implements deep sleep.""" +STATIC mp_obj_t alarm_disable_all(void) { + common_hal_alarm_disable_all(); + return mp_const_none; +} +STATIC MP_DEFINE_CONST_FUN_OBJ_0(alarm_disable_all_obj, alarm_disable_all); + STATIC mp_obj_t alarm_get_wake_alarm(void) { return common_hal_alarm_get_wake_alarm(); } @@ -11,7 +17,8 @@ STATIC MP_DEFINE_CONST_FUN_OBJ_0(alarm_get_wake_alarm_obj, alarm_get_wake_alarm) STATIC const mp_rom_map_elem_t alarm_module_globals_table[] = { { MP_ROM_QSTR(MP_QSTR___name__), MP_ROM_QSTR(MP_QSTR_alarm) }, - { MP_ROM_QSTR(MP_QSTR_getWakeAlarm), MP_ROM_PTR(&alarm_get_wake_alarm_obj) }, + { MP_ROM_QSTR(MP_QSTR_Disable), MP_ROM_PTR(&alarm_disable_all_obj) }, + { MP_ROM_QSTR(MP_QSTR_get_wake_alarm), MP_ROM_PTR(&alarm_get_wake_alarm_obj) }, }; STATIC MP_DEFINE_CONST_DICT(alarm_module_globals, alarm_module_globals_table); diff --git a/shared-bindings/alarm/__init__.h b/shared-bindings/alarm/__init__.h index 8b2cd9f770..db3966ac5d 100644 --- a/shared-bindings/alarm/__init__.h +++ b/shared-bindings/alarm/__init__.h @@ -3,6 +3,7 @@ #include "py/obj.h" +extern void common_hal_alarm_disable_all(void); extern mp_obj_t common_hal_alarm_get_wake_alarm(void); #endif // MICROPY_INCLUDED_SHARED_BINDINGS_ALARM___INIT___H diff --git a/shared-bindings/microcontroller/__init__.c b/shared-bindings/microcontroller/__init__.c index 88dc4179d6..bbc1640f76 100644 --- a/shared-bindings/microcontroller/__init__.c +++ b/shared-bindings/microcontroller/__init__.c @@ -136,7 +136,7 @@ STATIC mp_obj_t mcu_reset(void) { STATIC MP_DEFINE_CONST_FUN_OBJ_0(mcu_reset_obj, mcu_reset); STATIC mp_obj_t mcu_sleep(void) { - common_hal_mcu_sleep(); + common_hal_mcu_deep_sleep(); // We won't actually get here because mcu is going into sleep. return mp_const_none; } @@ -177,6 +177,7 @@ STATIC const mp_rom_map_elem_t mcu_module_globals_table[] = { { MP_ROM_QSTR(MP_QSTR_enable_interrupts), MP_ROM_PTR(&mcu_enable_interrupts_obj) }, { MP_ROM_QSTR(MP_QSTR_on_next_reset), MP_ROM_PTR(&mcu_on_next_reset_obj) }, { MP_ROM_QSTR(MP_QSTR_reset), MP_ROM_PTR(&mcu_reset_obj) }, + //ToDo: Remove MP_QSTR_sleep when sleep on code.py exit implemented. { MP_ROM_QSTR(MP_QSTR_sleep), MP_ROM_PTR(&mcu_sleep_obj) }, #if CIRCUITPY_INTERNAL_NVM_SIZE > 0 { MP_ROM_QSTR(MP_QSTR_nvm), MP_ROM_PTR(&common_hal_mcu_nvm_obj) }, diff --git a/shared-bindings/microcontroller/__init__.h b/shared-bindings/microcontroller/__init__.h index 95f1cf8fc7..f5bcfaa08a 100644 --- a/shared-bindings/microcontroller/__init__.h +++ b/shared-bindings/microcontroller/__init__.h @@ -43,7 +43,7 @@ extern void common_hal_mcu_enable_interrupts(void); extern void common_hal_mcu_on_next_reset(mcu_runmode_t runmode); extern void common_hal_mcu_reset(void); -extern void common_hal_mcu_sleep(void); +extern void common_hal_mcu_deep_sleep(void); extern const mp_obj_dict_t mcu_pin_globals; From 0e444f0de8dd4db8b5be1c41b4c8062364e4fd94 Mon Sep 17 00:00:00 2001 From: microDev <70126934+microDev1@users.noreply.github.com> Date: Wed, 30 Sep 2020 11:15:02 +0530 Subject: [PATCH 12/34] Implement sleep on code.py exit --- main.c | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/main.c b/main.c index 5a30f4bb26..328c3bbcba 100755 --- a/main.c +++ b/main.c @@ -57,6 +57,9 @@ #include "supervisor/shared/status_leds.h" #include "supervisor/shared/stack.h" #include "supervisor/serial.h" +#include "supervisor/usb.h" + +#include "shared-bindings/microcontroller/__init__.h" #include "boards/board.h" @@ -300,6 +303,19 @@ bool run_code_py(safe_mode_t safe_mode) { } } + for (uint8_t i = 0; i<=100; i++) { + if (!usb_msc_ejected()) { + //Go into light sleep + break; + } + mp_hal_delay_ms(10); + } + + if (usb_msc_ejected()) { + //Go into deep sleep + common_hal_mcu_deep_sleep(); + } + // Display a different completion message if the user has no USB attached (cannot save files) if (!serial_connected_at_start) { serial_write_compressed(translate("\nCode done running. Waiting for reload.\n")); From 354536c09fca3cecca6e6e5605710436501fccac Mon Sep 17 00:00:00 2001 From: microDev <70126934+microDev1@users.noreply.github.com> Date: Wed, 7 Oct 2020 09:55:48 +0530 Subject: [PATCH 13/34] Update translation --- locale/circuitpython.pot | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/locale/circuitpython.pot b/locale/circuitpython.pot index e344f4dd81..eb958a5999 100644 --- a/locale/circuitpython.pot +++ b/locale/circuitpython.pot @@ -980,6 +980,10 @@ msgstr "" msgid "I2SOut not available" msgstr "" +#: ports/esp32s2/common-hal/alarm_io/__init__.c +msgid "IOs 0, 2 & 4 do not support internal pullup in sleep" +msgstr "" + #: shared-bindings/aesio/aes.c #, c-format msgid "IV must be %d bytes long" @@ -2790,6 +2794,10 @@ msgstr "" msgid "invalid syntax for number" msgstr "" +#: ports/esp32s2/common-hal/alarm_io/__init__.c +msgid "io must be rtc io" +msgstr "" + #: py/objtype.c msgid "issubclass() arg 1 must be a class" msgstr "" @@ -3410,6 +3418,10 @@ msgstr "" msgid "threshold must be in the range 0-65536" msgstr "" +#: ports/esp32s2/common-hal/alarm_time/__init__.c +msgid "time out of range" +msgstr "" + #: shared-bindings/time/__init__.c msgid "time.struct_time() takes a 9-sequence" msgstr "" @@ -3455,6 +3467,10 @@ msgstr "" msgid "trapz is defined for 1D arrays of equal length" msgstr "" +#: ports/esp32s2/common-hal/alarm_io/__init__.c +msgid "trigger level must be 0 or 1" +msgstr "" + #: extmod/ulab/code/linalg/linalg.c msgid "tuple index out of range" msgstr "" @@ -3597,6 +3613,10 @@ msgstr "" msgid "vectors must have same lengths" msgstr "" +#: ports/esp32s2/common-hal/alarm_io/__init__.c +msgid "wakeup conflict" +msgstr "" + #: shared-bindings/watchdog/WatchDogTimer.c msgid "watchdog timeout must be greater than 0" msgstr "" From 1196d4bcf62884a18316bf44258a8d9b838f7273 Mon Sep 17 00:00:00 2001 From: Scott Shawcroft Date: Wed, 14 Oct 2020 14:09:41 -0700 Subject: [PATCH 14/34] move to new module --- shared-bindings/alarm/__init__.c | 29 --------- shared-bindings/alarm/__init__.h | 9 --- shared-bindings/sleepio/__init__.c | 101 +++++++++++++++++++++++++++++ shared-bindings/sleepio/__init__.h | 10 +++ 4 files changed, 111 insertions(+), 38 deletions(-) delete mode 100644 shared-bindings/alarm/__init__.c delete mode 100644 shared-bindings/alarm/__init__.h create mode 100644 shared-bindings/sleepio/__init__.c create mode 100644 shared-bindings/sleepio/__init__.h diff --git a/shared-bindings/alarm/__init__.c b/shared-bindings/alarm/__init__.c deleted file mode 100644 index f43c2ea12d..0000000000 --- a/shared-bindings/alarm/__init__.c +++ /dev/null @@ -1,29 +0,0 @@ -#include "shared-bindings/alarm/__init__.h" - -//| """alarm module -//| -//| The `alarm` module implements deep sleep.""" - -STATIC mp_obj_t alarm_disable_all(void) { - common_hal_alarm_disable_all(); - return mp_const_none; -} -STATIC MP_DEFINE_CONST_FUN_OBJ_0(alarm_disable_all_obj, alarm_disable_all); - -STATIC mp_obj_t alarm_get_wake_alarm(void) { - return common_hal_alarm_get_wake_alarm(); -} -STATIC MP_DEFINE_CONST_FUN_OBJ_0(alarm_get_wake_alarm_obj, alarm_get_wake_alarm); - -STATIC const mp_rom_map_elem_t alarm_module_globals_table[] = { - { MP_ROM_QSTR(MP_QSTR___name__), MP_ROM_QSTR(MP_QSTR_alarm) }, - { MP_ROM_QSTR(MP_QSTR_Disable), MP_ROM_PTR(&alarm_disable_all_obj) }, - { MP_ROM_QSTR(MP_QSTR_get_wake_alarm), MP_ROM_PTR(&alarm_get_wake_alarm_obj) }, -}; - -STATIC MP_DEFINE_CONST_DICT(alarm_module_globals, alarm_module_globals_table); - -const mp_obj_module_t alarm_module = { - .base = { &mp_type_module }, - .globals = (mp_obj_dict_t*)&alarm_module_globals, -}; diff --git a/shared-bindings/alarm/__init__.h b/shared-bindings/alarm/__init__.h deleted file mode 100644 index db3966ac5d..0000000000 --- a/shared-bindings/alarm/__init__.h +++ /dev/null @@ -1,9 +0,0 @@ -#ifndef MICROPY_INCLUDED_SHARED_BINDINGS_ALARM___INIT___H -#define MICROPY_INCLUDED_SHARED_BINDINGS_ALARM___INIT___H - -#include "py/obj.h" - -extern void common_hal_alarm_disable_all(void); -extern mp_obj_t common_hal_alarm_get_wake_alarm(void); - -#endif // MICROPY_INCLUDED_SHARED_BINDINGS_ALARM___INIT___H diff --git a/shared-bindings/sleepio/__init__.c b/shared-bindings/sleepio/__init__.c new file mode 100644 index 0000000000..2f7a8c6c7b --- /dev/null +++ b/shared-bindings/sleepio/__init__.c @@ -0,0 +1,101 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2020 Scott Shawcroft + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +#include "shared-bindings/alarm/__init__.h" + +//| """Light and deep sleep used to save power +//| +//| The `sleepio` module provides sleep related functionality. There are two supported levels of +//| sleep, light and deep. +//| +//| Light sleep leaves the CPU and RAM powered so that CircuitPython can resume where it left off +//| after being woken up. Light sleep is automatically done by CircuitPython when `time.sleep()` is +//| called. To light sleep until a non-time alarm use `sleepio.sleep_until_alarm()`. +//| +//| Deep sleep shuts down power to nearly all of the chip including the CPU and RAM. This can save +//| a more significant amount of power at the cost of starting CircuitPython from scratch when woken +//| up. CircuitPython will enter deep sleep automatically when code exits without error. If an +//| error causes CircuitPython to exit, error LED error flashes will be done periodically. To set +//| alarms for deep sleep use `sleepio.set_alarms` they will apply to next deep sleep only.""" + + +//| wake_alarm: Alarm +//| """The most recent alarm to wake us up from a sleep (light or deep.)""" +//| + +//| def sleep_until_alarm(alarm: Alarm, ...) -> Alarm: +//| """Performs a light sleep until woken by one of the alarms. The alarm that woke us up is +//| returned.""" +//| ... +//| + +STATIC mp_obj_t sleepio_sleep_until_alarm(size_t n_args, const mp_obj_t *args) { + // mp_int_t size = MP_OBJ_SMALL_INT_VALUE(struct_calcsize(args[0])); + // vstr_t vstr; + // vstr_init_len(&vstr, size); + // byte *p = (byte*)vstr.buf; + // memset(p, 0, size); + // byte *end_p = &p[size]; + // shared_modules_struct_pack_into(args[0], p, end_p, n_args - 1, &args[1]); + // return mp_obj_new_str_from_vstr(&mp_type_bytes, &vstr); +} +MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(sleepio_sleep_until_alarm_obj, 1, MP_OBJ_FUN_ARGS_MAX, sleepio_sleep_until_alarm); + +//| def set_alarms(alarm: Alarm, ...) -> None: +//| """Set one or more alarms to wake up from a deep sleep. The last alarm to wake us up is +//| available as `wake_alarm`.""" +//| ... +//| +STATIC mp_obj_t sleepio_set_alarms(size_t n_args, const mp_obj_t *args) { + // mp_int_t size = MP_OBJ_SMALL_INT_VALUE(struct_calcsize(args[0])); + // vstr_t vstr; + // vstr_init_len(&vstr, size); + // byte *p = (byte*)vstr.buf; + // memset(p, 0, size); + // byte *end_p = &p[size]; + // shared_modules_struct_pack_into(args[0], p, end_p, n_args - 1, &args[1]); + // return mp_obj_new_str_from_vstr(&mp_type_bytes, &vstr); +} +MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(sleepio_set_alarms_obj, 1, MP_OBJ_FUN_ARGS_MAX, sleepio_set_alarms); + + +mp_map_elem_t sleepio_module_globals_table[] = { + { MP_ROM_QSTR(MP_QSTR___name__), MP_ROM_QSTR(MP_QSTR_sleepio) }, + + { MP_ROM_QSTR(MP_QSTR_wake_alarm), mp_const_none }, + { MP_ROM_QSTR(MP_QSTR_sleep_until_alarm), mp_const_none }, + { MP_ROM_QSTR(MP_QSTR_set_alarms), mp_const_none }, +}; +STATIC MP_DEFINE_CONST_DICT(sleepio_module_globals, sleepio_module_globals_table); + +void common_hal_sleepio_set_wake_alarm(mp_obj_t alarm) { + // sleepio_module_globals_table[1].value = alarm; +} + +const mp_obj_module_t sleepio_module = { + .base = { &mp_type_module }, + .globals = (mp_obj_dict_t*)&sleepio_module_globals, +}; diff --git a/shared-bindings/sleepio/__init__.h b/shared-bindings/sleepio/__init__.h new file mode 100644 index 0000000000..ccd3bf4a02 --- /dev/null +++ b/shared-bindings/sleepio/__init__.h @@ -0,0 +1,10 @@ +#ifndef MICROPY_INCLUDED_SHARED_BINDINGS_SLEEPIO___INIT___H +#define MICROPY_INCLUDED_SHARED_BINDINGS_SLEEPIO___INIT___H + +#include "py/obj.h" + +// This is implemented by shared-bindings so that implementations can set the +// newest alarm source. +extern void common_hal_sleepio_set_wake_alarm(mp_obj_t alarm); + +#endif // MICROPY_INCLUDED_SHARED_BINDINGS_SLEEPIO___INIT___H From 85dadf3a561c21e284d5daf42b1b3e367ce7ebc6 Mon Sep 17 00:00:00 2001 From: Scott Shawcroft Date: Thu, 15 Oct 2020 16:59:29 -0700 Subject: [PATCH 15/34] More API changes --- shared-bindings/_typing/__init__.pyi | 12 ++++ shared-bindings/alarm_time/Time.c | 76 ++++++++++++++++++++++++++ shared-bindings/alarm_time/Time.h | 42 ++++++++++++++ shared-bindings/alarm_time/__init__.c | 26 +++++++++ shared-bindings/canio/BusState.c | 70 ++++++++++++++++++++++++ shared-bindings/canio/BusState.h | 33 +++++++++++ shared-bindings/canio/__init__.c | 60 ++++---------------- shared-bindings/canio/__init__.h | 6 -- shared-bindings/sleepio/__init__.c | 10 ++-- shared-bindings/supervisor/RunReason.c | 62 +++++++++++++++++++++ shared-bindings/supervisor/RunReason.h | 36 ++++++++++++ shared-bindings/supervisor/Runtime.c | 22 ++++++++ 12 files changed, 395 insertions(+), 60 deletions(-) create mode 100644 shared-bindings/alarm_time/Time.c create mode 100644 shared-bindings/alarm_time/Time.h create mode 100644 shared-bindings/canio/BusState.c create mode 100644 shared-bindings/canio/BusState.h create mode 100644 shared-bindings/supervisor/RunReason.c create mode 100644 shared-bindings/supervisor/RunReason.h diff --git a/shared-bindings/_typing/__init__.pyi b/shared-bindings/_typing/__init__.pyi index 48e68a8d57..3b3f18cb9b 100644 --- a/shared-bindings/_typing/__init__.pyi +++ b/shared-bindings/_typing/__init__.pyi @@ -52,3 +52,15 @@ FrameBuffer = Union[rgbmatrix.RGBMatrix] - `rgbmatrix.RGBMatrix` """ + +Alarm = Union[ + alarm_time.Time, alarm_pin.PinLevel, alarm_touch.PinTouch +] +"""Classes that implement the audiosample protocol + + - `alarm_time.Time` + - `alarm_pin.PinLevel` + - `alarm_touch.PinTouch` + + You can play use these alarms to wake from light or deep sleep. +""" diff --git a/shared-bindings/alarm_time/Time.c b/shared-bindings/alarm_time/Time.c new file mode 100644 index 0000000000..904bf522e2 --- /dev/null +++ b/shared-bindings/alarm_time/Time.c @@ -0,0 +1,76 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2020 Scott Shawcroft + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +#include "py/obj.h" +#include "shared-bindings/alarm_time/__init__.h" + +//| """alarm_time module +//| +//| The `alarm_time` module implements deep sleep.""" + +STATIC mp_obj_t alarm_time_duration(mp_obj_t seconds_o) { + #if MICROPY_PY_BUILTINS_FLOAT + mp_float_t seconds = mp_obj_get_float(seconds_o); + mp_float_t msecs = 1000.0f * seconds + 0.5f; + #else + mp_int_t seconds = mp_obj_get_int(seconds_o); + mp_int_t msecs = 1000 * seconds; + #endif + + if (seconds < 0) { + mp_raise_ValueError(translate("sleep length must be non-negative")); + } + common_hal_alarm_time_duration(msecs); + + alarm_time_obj_t *self = m_new_obj(alarm_time_obj_t); + self->base.type = &alarm_time_type; + + return self; +} +STATIC MP_DEFINE_CONST_FUN_OBJ_1(alarm_time_duration_obj, alarm_time_duration); + +STATIC mp_obj_t alarm_time_disable(void) { + common_hal_alarm_time_disable(); + return mp_const_none; +} +STATIC MP_DEFINE_CONST_FUN_OBJ_0(alarm_time_disable_obj, alarm_time_disable); + +STATIC const mp_rom_map_elem_t alarm_time_module_globals_table[] = { + { MP_ROM_QSTR(MP_QSTR___name__), MP_ROM_QSTR(MP_QSTR_alarm_time) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_Duration), MP_ROM_PTR(&alarm_time_duration_obj) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_Disable), MP_ROM_PTR(&alarm_time_disable_obj) }, +}; +STATIC MP_DEFINE_CONST_DICT(alarm_time_module_globals, alarm_time_module_globals_table); + +const mp_obj_module_t alarm_time_module = { + .base = { &mp_type_module }, + .globals = (mp_obj_dict_t*)&alarm_time_module_globals, +}; + +const mp_obj_type_t alarm_time_type = { + { &mp_type_type }, + .name = MP_QSTR_timeAlarm, +}; diff --git a/shared-bindings/alarm_time/Time.h b/shared-bindings/alarm_time/Time.h new file mode 100644 index 0000000000..9962c26f25 --- /dev/null +++ b/shared-bindings/alarm_time/Time.h @@ -0,0 +1,42 @@ +/* + * This file is part of the Micro Python project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2020 Scott Shawcroft for Adafruit Industries + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +#ifndef MICROPY_INCLUDED_SHARED_BINDINGS_ALARM_TIME_TIME_H +#define MICROPY_INCLUDED_SHARED_BINDINGS_ALARM_TIME_TIME_H + +#include "py/runtime.h" + +typedef struct { + mp_obj_base_t base; + uint64_t time_to_alarm; +} alarm_time_time_obj_t; + +extern const mp_obj_type_t alarm_time_time_type; + +void common_hal_alarm_time_time_construct(alarm_time_time_obj_t* self, + uint64_t ticks_ms); + +#endif //MICROPY_INCLUDED_SHARED_BINDINGS_ALARM_TIME_TIME_H diff --git a/shared-bindings/alarm_time/__init__.c b/shared-bindings/alarm_time/__init__.c index 1707f7488f..904bf522e2 100644 --- a/shared-bindings/alarm_time/__init__.c +++ b/shared-bindings/alarm_time/__init__.c @@ -1,3 +1,29 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2020 Scott Shawcroft + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + #include "py/obj.h" #include "shared-bindings/alarm_time/__init__.h" diff --git a/shared-bindings/canio/BusState.c b/shared-bindings/canio/BusState.c new file mode 100644 index 0000000000..e0501b8d83 --- /dev/null +++ b/shared-bindings/canio/BusState.c @@ -0,0 +1,70 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2020 Jeff Epler for Adafruit Industries + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +#include "py/enum.h" + +#include "shared-bindings/canio/BusState.h" + +MAKE_ENUM_VALUE(canio_bus_state_type, bus_state, ERROR_ACTIVE, BUS_STATE_ERROR_ACTIVE); +MAKE_ENUM_VALUE(canio_bus_state_type, bus_state, ERROR_PASSIVE, BUS_STATE_ERROR_PASSIVE); +MAKE_ENUM_VALUE(canio_bus_state_type, bus_state, ERROR_WARNING, BUS_STATE_ERROR_WARNING); +MAKE_ENUM_VALUE(canio_bus_state_type, bus_state, BUS_OFF, BUS_STATE_OFF); + +//| class BusState: +//| """The state of the CAN bus""" +//| +//| ERROR_ACTIVE: object +//| """The bus is in the normal (active) state""" +//| +//| ERROR_WARNING: object +//| """The bus is in the normal (active) state, but a moderate number of errors have occurred recently. +//| +//| NOTE: Not all implementations may use ERROR_WARNING. Do not rely on seeing ERROR_WARNING before ERROR_PASSIVE.""" +//| +//| ERROR_PASSIVE: object +//| """The bus is in the passive state due to the number of errors that have occurred recently. +//| +//| This device will acknowledge packets it receives, but cannot transmit messages. +//| If additional errors occur, this device may progress to BUS_OFF. +//| If it successfully acknowledges other packets on the bus, it can return to ERROR_WARNING or ERROR_ACTIVE and transmit packets. +//| """ +//| +//| BUS_OFF: object +//| """The bus has turned off due to the number of errors that have +//| occurred recently. It must be restarted before it will send or receive +//| packets. This device will neither send or acknowledge packets on the bus.""" +//| +MAKE_ENUM_MAP(canio_bus_state) { + MAKE_ENUM_MAP_ENTRY(bus_state, ERROR_ACTIVE), + MAKE_ENUM_MAP_ENTRY(bus_state, ERROR_PASSIVE), + MAKE_ENUM_MAP_ENTRY(bus_state, ERROR_WARNING), + MAKE_ENUM_MAP_ENTRY(bus_state, BUS_OFF), +}; +STATIC MP_DEFINE_CONST_DICT(canio_bus_state_locals_dict, canio_bus_state_locals_table); + +MAKE_PRINTER(canio, canio_bus_state); + +MAKE_ENUM_TYPE(canio, BusState, canio_bus_state); diff --git a/shared-bindings/canio/BusState.h b/shared-bindings/canio/BusState.h new file mode 100644 index 0000000000..e24eba92c1 --- /dev/null +++ b/shared-bindings/canio/BusState.h @@ -0,0 +1,33 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2020 Jeff Epler for Adafruit Industries + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +#pragma once + +typedef enum { + BUS_STATE_ERROR_ACTIVE, BUS_STATE_ERROR_PASSIVE, BUS_STATE_ERROR_WARNING, BUS_STATE_OFF +} canio_bus_state_t; + +extern const mp_obj_type_t canio_bus_state_type; diff --git a/shared-bindings/canio/__init__.c b/shared-bindings/canio/__init__.c index f29d3ab8ac..451a68c9eb 100644 --- a/shared-bindings/canio/__init__.c +++ b/shared-bindings/canio/__init__.c @@ -24,6 +24,16 @@ * THE SOFTWARE. */ +#include "py/obj.h" + +#include "shared-bindings/canio/__init__.h" + +#include "shared-bindings/canio/BusState.h" +#include "shared-bindings/canio/CAN.h" +#include "shared-bindings/canio/Match.h" +#include "shared-bindings/canio/Message.h" +#include "shared-bindings/canio/Listener.h" + //| """CAN bus access //| //| The `canio` module contains low level classes to support the CAN bus @@ -57,56 +67,6 @@ //| """ //| -#include "py/obj.h" -#include "py/enum.h" - -#include "shared-bindings/canio/__init__.h" -#include "shared-bindings/canio/CAN.h" -#include "shared-bindings/canio/Match.h" -#include "shared-bindings/canio/Message.h" -#include "shared-bindings/canio/Listener.h" - -MAKE_ENUM_VALUE(canio_bus_state_type, bus_state, ERROR_ACTIVE, BUS_STATE_ERROR_ACTIVE); -MAKE_ENUM_VALUE(canio_bus_state_type, bus_state, ERROR_PASSIVE, BUS_STATE_ERROR_PASSIVE); -MAKE_ENUM_VALUE(canio_bus_state_type, bus_state, ERROR_WARNING, BUS_STATE_ERROR_WARNING); -MAKE_ENUM_VALUE(canio_bus_state_type, bus_state, BUS_OFF, BUS_STATE_OFF); - -//| class BusState: -//| """The state of the CAN bus""" -//| -//| ERROR_ACTIVE: object -//| """The bus is in the normal (active) state""" -//| -//| ERROR_WARNING: object -//| """The bus is in the normal (active) state, but a moderate number of errors have occurred recently. -//| -//| NOTE: Not all implementations may use ERROR_WARNING. Do not rely on seeing ERROR_WARNING before ERROR_PASSIVE.""" -//| -//| ERROR_PASSIVE: object -//| """The bus is in the passive state due to the number of errors that have occurred recently. -//| -//| This device will acknowledge packets it receives, but cannot transmit messages. -//| If additional errors occur, this device may progress to BUS_OFF. -//| If it successfully acknowledges other packets on the bus, it can return to ERROR_WARNING or ERROR_ACTIVE and transmit packets. -//| """ -//| -//| BUS_OFF: object -//| """The bus has turned off due to the number of errors that have -//| occurred recently. It must be restarted before it will send or receive -//| packets. This device will neither send or acknowledge packets on the bus.""" -//| -MAKE_ENUM_MAP(canio_bus_state) { - MAKE_ENUM_MAP_ENTRY(bus_state, ERROR_ACTIVE), - MAKE_ENUM_MAP_ENTRY(bus_state, ERROR_PASSIVE), - MAKE_ENUM_MAP_ENTRY(bus_state, ERROR_WARNING), - MAKE_ENUM_MAP_ENTRY(bus_state, BUS_OFF), -}; -STATIC MP_DEFINE_CONST_DICT(canio_bus_state_locals_dict, canio_bus_state_locals_table); - -MAKE_PRINTER(canio, canio_bus_state); - -MAKE_ENUM_TYPE(canio, BusState, canio_bus_state); - STATIC const mp_rom_map_elem_t canio_module_globals_table[] = { { MP_ROM_QSTR(MP_QSTR_BusState), MP_ROM_PTR(&canio_bus_state_type) }, { MP_ROM_QSTR(MP_QSTR_CAN), MP_ROM_PTR(&canio_can_type) }, diff --git a/shared-bindings/canio/__init__.h b/shared-bindings/canio/__init__.h index e24eba92c1..20b6638cd8 100644 --- a/shared-bindings/canio/__init__.h +++ b/shared-bindings/canio/__init__.h @@ -25,9 +25,3 @@ */ #pragma once - -typedef enum { - BUS_STATE_ERROR_ACTIVE, BUS_STATE_ERROR_PASSIVE, BUS_STATE_ERROR_WARNING, BUS_STATE_OFF -} canio_bus_state_t; - -extern const mp_obj_type_t canio_bus_state_type; diff --git a/shared-bindings/sleepio/__init__.c b/shared-bindings/sleepio/__init__.c index 2f7a8c6c7b..2d5db18f0a 100644 --- a/shared-bindings/sleepio/__init__.c +++ b/shared-bindings/sleepio/__init__.c @@ -33,14 +33,15 @@ //| //| Light sleep leaves the CPU and RAM powered so that CircuitPython can resume where it left off //| after being woken up. Light sleep is automatically done by CircuitPython when `time.sleep()` is -//| called. To light sleep until a non-time alarm use `sleepio.sleep_until_alarm()`. +//| called. To light sleep until a non-time alarm use `sleepio.sleep_until_alarm()`. Any active +//| peripherals, such as I2C, are left on. //| //| Deep sleep shuts down power to nearly all of the chip including the CPU and RAM. This can save //| a more significant amount of power at the cost of starting CircuitPython from scratch when woken //| up. CircuitPython will enter deep sleep automatically when code exits without error. If an //| error causes CircuitPython to exit, error LED error flashes will be done periodically. To set //| alarms for deep sleep use `sleepio.set_alarms` they will apply to next deep sleep only.""" - +//| //| wake_alarm: Alarm //| """The most recent alarm to wake us up from a sleep (light or deep.)""" @@ -86,8 +87,9 @@ mp_map_elem_t sleepio_module_globals_table[] = { { MP_ROM_QSTR(MP_QSTR___name__), MP_ROM_QSTR(MP_QSTR_sleepio) }, { MP_ROM_QSTR(MP_QSTR_wake_alarm), mp_const_none }, - { MP_ROM_QSTR(MP_QSTR_sleep_until_alarm), mp_const_none }, - { MP_ROM_QSTR(MP_QSTR_set_alarms), mp_const_none }, + + { MP_ROM_QSTR(MP_QSTR_sleep_until_alarm), sleepio_sleep_until_alarm_obj }, + { MP_ROM_QSTR(MP_QSTR_set_alarms), sleepio_set_alarms_obj }, }; STATIC MP_DEFINE_CONST_DICT(sleepio_module_globals, sleepio_module_globals_table); diff --git a/shared-bindings/supervisor/RunReason.c b/shared-bindings/supervisor/RunReason.c new file mode 100644 index 0000000000..5233cf959b --- /dev/null +++ b/shared-bindings/supervisor/RunReason.c @@ -0,0 +1,62 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2020 Scott Shawcroft for Adafruit Industries + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +#include "py/enum.h" + +#include "shared-bindings/supervisor/RunReason.h" + +MAKE_ENUM_VALUE(canio_bus_state_type, run_reason, ERROR_ACTIVE, RUN_REASON_STARTUP); +MAKE_ENUM_VALUE(canio_bus_state_type, bus_state, ERROR_PASSIVE, RUN_REASON_AUTORELOAD); +MAKE_ENUM_VALUE(canio_bus_state_type, bus_state, ERROR_WARNING, RUN_REASON_SUPERVISOR_RELOAD); +MAKE_ENUM_VALUE(canio_bus_state_type, bus_state, BUS_OFF, RUN_REASON_RELOAD_HOTKEY); + +//| class RunReason: +//| """The state of the CAN bus""" +//| +//| STARTUP: object +//| """The first VM was run after the microcontroller started up. See `microcontroller.start_reason` +//| for more detail why the microcontroller was started.""" +//| +//| AUTORELOAD: object +//| """The VM was run due to a USB write to the filesystem.""" +//| +//| SUPERVISOR_RELOAD: object +//| """The VM was run due to a call to `supervisor.reload()`.""" +//| +//| RELOAD_HOTKEY: object +//| """The VM was run due CTRL-D.""" +//| +MAKE_ENUM_MAP(canio_bus_state) { + MAKE_ENUM_MAP_ENTRY(bus_state, ERROR_ACTIVE), + MAKE_ENUM_MAP_ENTRY(bus_state, ERROR_PASSIVE), + MAKE_ENUM_MAP_ENTRY(bus_state, ERROR_WARNING), + MAKE_ENUM_MAP_ENTRY(bus_state, BUS_OFF), +}; +STATIC MP_DEFINE_CONST_DICT(canio_bus_state_locals_dict, canio_bus_state_locals_table); + +MAKE_PRINTER(canio, canio_bus_state); + +MAKE_ENUM_TYPE(canio, BusState, canio_bus_state); diff --git a/shared-bindings/supervisor/RunReason.h b/shared-bindings/supervisor/RunReason.h new file mode 100644 index 0000000000..f9aaacae63 --- /dev/null +++ b/shared-bindings/supervisor/RunReason.h @@ -0,0 +1,36 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2020 Scott Shawcroft for Adafruit Industries + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +#pragma once + +typedef enum { + RUN_REASON_STARTUP, + RUN_REASON_AUTORELOAD, + RUN_REASON_SUPERVISOR_RELOAD, + RUN_REASON_RELOAD_HOTKEY +} supervisor_run_reason_t; + +extern const mp_obj_type_t canio_bus_state_type; diff --git a/shared-bindings/supervisor/Runtime.c b/shared-bindings/supervisor/Runtime.c index bfca6e7b1d..f9db38c9b5 100755 --- a/shared-bindings/supervisor/Runtime.c +++ b/shared-bindings/supervisor/Runtime.c @@ -90,9 +90,31 @@ const mp_obj_property_t supervisor_serial_bytes_available_obj = { }; +//| run_reason: RunReason +//| """Returns why the Python VM was run this time.""" +//| +STATIC mp_obj_t supervisor_get_run_reason(mp_obj_t self) { + if (!common_hal_get_serial_bytes_available()) { + return mp_const_false; + } + else { + return mp_const_true; + } +} +MP_DEFINE_CONST_FUN_OBJ_1(supervisor_get_run_reason_obj, supervisor_get_run_reason); + +const mp_obj_property_t supervisor_run_reason_obj = { + .base.type = &mp_type_property, + .proxy = {(mp_obj_t)&supervisor_get_run_reason_obj, + (mp_obj_t)&mp_const_none_obj, + (mp_obj_t)&mp_const_none_obj}, +}; + + STATIC const mp_rom_map_elem_t supervisor_runtime_locals_dict_table[] = { { MP_ROM_QSTR(MP_QSTR_serial_connected), MP_ROM_PTR(&supervisor_serial_connected_obj) }, { MP_ROM_QSTR(MP_QSTR_serial_bytes_available), MP_ROM_PTR(&supervisor_serial_bytes_available_obj) }, + { MP_ROM_QSTR(MP_QSTR_run_reason), MP_ROM_PTR(&supervisor_run_reason_obj) }, }; STATIC MP_DEFINE_CONST_DICT(supervisor_runtime_locals_dict, supervisor_runtime_locals_dict_table); From 9a4efed8cbaca3aa48c6cc0ce0a4e267eef7a8e1 Mon Sep 17 00:00:00 2001 From: Scott Shawcroft Date: Tue, 27 Oct 2020 17:55:03 -0700 Subject: [PATCH 16/34] Start tweaking the workflow to sleep --- main.c | 49 ++++++++++----- .../esp32s2/common-hal/alarm_touch/__init__.c | 7 --- shared-bindings/alarm_touch/__init__.c | 28 --------- shared-bindings/alarm_touch/__init__.h | 14 ----- shared-bindings/sleepio/ResetReason.c | 61 +++++++++++++++++++ shared-bindings/sleepio/ResetReason.h | 36 +++++++++++ shared-bindings/sleepio/__init__.c | 27 ++++---- shared-bindings/sleepio/__init__.h | 5 +- supervisor/serial.h | 1 - supervisor/shared/rgb_led_status.c | 10 ++- supervisor/shared/safe_mode.c | 4 ++ supervisor/shared/serial.h | 29 +++++++++ supervisor/shared/usb/usb.c | 9 ++- supervisor/shared/workflow.c | 32 ++++++++++ supervisor/shared/workflow.h | 29 +++++++++ supervisor/supervisor.mk | 1 + supervisor/workflow.h | 30 +++++++++ 17 files changed, 282 insertions(+), 90 deletions(-) delete mode 100644 ports/esp32s2/common-hal/alarm_touch/__init__.c delete mode 100644 shared-bindings/alarm_touch/__init__.c delete mode 100644 shared-bindings/alarm_touch/__init__.h create mode 100644 shared-bindings/sleepio/ResetReason.c create mode 100644 shared-bindings/sleepio/ResetReason.h create mode 100644 supervisor/shared/serial.h create mode 100644 supervisor/shared/workflow.c create mode 100644 supervisor/shared/workflow.h create mode 100755 supervisor/workflow.h diff --git a/main.c b/main.c index 328c3bbcba..1854a14071 100755 --- a/main.c +++ b/main.c @@ -88,6 +88,10 @@ #include "common-hal/canio/CAN.h" #endif +#if CIRCUITPY_SLEEPIO +#include "shared-bindings/sleepio/__init__.h" +#endif + void do_str(const char *src, mp_parse_input_kind_t input_kind) { mp_lexer_t *lex = mp_lexer_new_from_str_len(MP_QSTR__lt_stdin_gt_, src, strlen(src), 0); if (lex == NULL) { @@ -303,19 +307,6 @@ bool run_code_py(safe_mode_t safe_mode) { } } - for (uint8_t i = 0; i<=100; i++) { - if (!usb_msc_ejected()) { - //Go into light sleep - break; - } - mp_hal_delay_ms(10); - } - - if (usb_msc_ejected()) { - //Go into deep sleep - common_hal_mcu_deep_sleep(); - } - // Display a different completion message if the user has no USB attached (cannot save files) if (!serial_connected_at_start) { serial_write_compressed(translate("\nCode done running. Waiting for reload.\n")); @@ -326,6 +317,14 @@ bool run_code_py(safe_mode_t safe_mode) { bool refreshed_epaper_display = false; #endif rgb_status_animation_t animation; + bool ok = result->return_code != PYEXEC_EXCEPTION; + #if CIRCUITPY_SLEEPIO + // If USB isn't enumerated then deep sleep. + if (ok && !supervisor_workflow_active() && supervisor_ticks_ms64() > CIRCUITPY_USB_ENUMERATION_DELAY * 1024) { + common_hal_sleepio_deep_sleep(); + } + #endif + // Show the animation every N seconds. prep_rgb_status_animation(&result, found_main, safe_mode, &animation); while (true) { RUN_BACKGROUND_TASKS; @@ -358,8 +357,24 @@ bool run_code_py(safe_mode_t safe_mode) { refreshed_epaper_display = maybe_refresh_epaperdisplay(); } #endif - - tick_rgb_status_animation(&animation); + bool animation_done = tick_rgb_status_animation(&animation); + if (animation_done && supervisor_workflow_active()) { + #if CIRCUITPY_SLEEPIO + int64_t remaining_enumeration_wait = CIRCUITPY_USB_ENUMERATION_DELAY * 1024 - supervisor_ticks_ms64(); + // If USB isn't enumerated then deep sleep after our waiting period. + if (ok && remaining_enumeration_wait < 0) { + common_hal_sleepio_deep_sleep(); + return; // Doesn't actually get here. + } + #endif + // Wake up every so often to flash the error code. + if (!ok) { + port_interrupt_after_ticks(CIRCUITPY_FLASH_ERROR_PERIOD * 1024); + } else { + port_interrupt_after_ticks(remaining_enumeration_wait); + } + port_sleep_until_interrupt(); + } } } @@ -406,7 +421,9 @@ void __attribute__ ((noinline)) run_boot_py(safe_mode_t safe_mode) { if (!skip_boot_output) { // Wait 1.5 seconds before opening CIRCUITPY_BOOT_OUTPUT_FILE for write, // in case power is momentary or will fail shortly due to, say a low, battery. - mp_hal_delay_ms(1500); + if (common_hal_sleepio_get_reset_reason() == RESET_REASON_POWER_VALID) { + mp_hal_delay_ms(1500); + } // USB isn't up, so we can write the file. filesystem_set_internal_writable_by_usb(false); diff --git a/ports/esp32s2/common-hal/alarm_touch/__init__.c b/ports/esp32s2/common-hal/alarm_touch/__init__.c deleted file mode 100644 index df32b26930..0000000000 --- a/ports/esp32s2/common-hal/alarm_touch/__init__.c +++ /dev/null @@ -1,7 +0,0 @@ -#include "esp_sleep.h" - -#include "shared-bindings/alarm_touch/__init__.h" - -void common_hal_alarm_touch_disable (void) { - esp_sleep_disable_wakeup_source(ESP_SLEEP_WAKEUP_TOUCHPAD); -} diff --git a/shared-bindings/alarm_touch/__init__.c b/shared-bindings/alarm_touch/__init__.c deleted file mode 100644 index 5f5a156d80..0000000000 --- a/shared-bindings/alarm_touch/__init__.c +++ /dev/null @@ -1,28 +0,0 @@ -#include "py/obj.h" -#include "shared-bindings/alarm_touch/__init__.h" - -//| """alarm_touch module -//| -//| The `alarm_touch` module implements deep sleep.""" - -STATIC mp_obj_t alarm_touch_disable(void) { - common_hal_alarm_touch_disable(); - return mp_const_none; -} -STATIC MP_DEFINE_CONST_FUN_OBJ_0(alarm_touch_disable_obj, alarm_touch_disable); - -STATIC const mp_rom_map_elem_t alarm_touch_module_globals_table[] = { - { MP_ROM_QSTR(MP_QSTR___name__), MP_ROM_QSTR(MP_QSTR_alarm_touch) }, - { MP_OBJ_NEW_QSTR(MP_QSTR_Disable), MP_ROM_PTR(&alarm_touch_disable_obj) }, -}; -STATIC MP_DEFINE_CONST_DICT(alarm_touch_module_globals, alarm_touch_module_globals_table); - -const mp_obj_module_t alarm_touch_module = { - .base = { &mp_type_module }, - .globals = (mp_obj_dict_t*)&alarm_touch_module_globals, -}; - -const mp_obj_type_t alarm_touch_type = { - { &mp_type_type }, - .name = MP_QSTR_touchAlarm, -}; diff --git a/shared-bindings/alarm_touch/__init__.h b/shared-bindings/alarm_touch/__init__.h deleted file mode 100644 index 600587d247..0000000000 --- a/shared-bindings/alarm_touch/__init__.h +++ /dev/null @@ -1,14 +0,0 @@ -#ifndef MICROPY_INCLUDED_SHARED_BINDINGS_ALARM_TOUCH___INIT___H -#define MICROPY_INCLUDED_SHARED_BINDINGS_ALARM_TOUCH___INIT___H - -#include "py/runtime.h" - -typedef struct { - mp_obj_base_t base; -} alarm_touch_obj_t; - -extern const mp_obj_type_t alarm_touch_type; - -extern void common_hal_alarm_touch_disable (void); - -#endif //MICROPY_INCLUDED_SHARED_BINDINGS_ALARM_TOUCH___INIT___H diff --git a/shared-bindings/sleepio/ResetReason.c b/shared-bindings/sleepio/ResetReason.c new file mode 100644 index 0000000000..095f4bed0d --- /dev/null +++ b/shared-bindings/sleepio/ResetReason.c @@ -0,0 +1,61 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2020 Scott Shawcroft for Adafruit Industries + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +#include "py/enum.h" + +#include "shared-bindings/sleepio/ResetReason.h" + +MAKE_ENUM_VALUE(sleepio_reset_reason_type, reset_reason, POWER_VALID, RESET_REASON_POWER_VALID); +MAKE_ENUM_VALUE(sleepio_reset_reason_type, reset_reason, SOFTWARE, RESET_REASON_SOFTWARE); +MAKE_ENUM_VALUE(sleepio_reset_reason_type, reset_reason, DEEP_SLEEP_ALARM, RESET_REASON_DEEP_SLEEP_ALARM); +MAKE_ENUM_VALUE(sleepio_reset_reason_type, reset_reason, EXTERNAL, RESET_REASON_EXTERNAL); + +//| class ResetReason: +//| """The reason the chip was last reset""" +//| +//| POWER_VALID: object +//| """The chip was reset and started once power levels were valid.""" +//| +//| SOFTWARE: object +//| """The chip was reset from software.""" +//| +//| DEEP_SLEEP_ALARM: object +//| """The chip was reset for deep sleep and started by an alarm.""" +//| +//| EXTERNAL: object +//| """The chip was reset by an external input such as a button.""" +//| +MAKE_ENUM_MAP(sleepio_reset_reason) { + MAKE_ENUM_MAP_ENTRY(reset_reason, POWER_VALID), + MAKE_ENUM_MAP_ENTRY(reset_reason, SOFTWARE), + MAKE_ENUM_MAP_ENTRY(reset_reason, DEEP_SLEEP_ALARM), + MAKE_ENUM_MAP_ENTRY(reset_reason, EXTERNAL), +}; +STATIC MP_DEFINE_CONST_DICT(sleepio_reset_reason_locals_dict, sleepio_reset_reason_locals_table); + +MAKE_PRINTER(sleepio, sleepio_reset_reason); + +MAKE_ENUM_TYPE(sleepio, ResetReason, sleepio_reset_reason); diff --git a/shared-bindings/sleepio/ResetReason.h b/shared-bindings/sleepio/ResetReason.h new file mode 100644 index 0000000000..50b8d002aa --- /dev/null +++ b/shared-bindings/sleepio/ResetReason.h @@ -0,0 +1,36 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2020 Scott Shawcroft for Adafruit Industries + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +#pragma once + +typedef enum { + RESET_REASON_POWER_APPLIED, + RESET_REASON_SOFTWARE, + RESET_REASON_DEEP_SLEEP_ALARM, + RESET_REASON_BUTTON, +} sleepio_reset_reason_t; + +extern const mp_obj_type_t sleepio_reset_reason_type; diff --git a/shared-bindings/sleepio/__init__.c b/shared-bindings/sleepio/__init__.c index 2d5db18f0a..9793c1b502 100644 --- a/shared-bindings/sleepio/__init__.c +++ b/shared-bindings/sleepio/__init__.c @@ -47,6 +47,10 @@ //| """The most recent alarm to wake us up from a sleep (light or deep.)""" //| +//| reset_reason: ResetReason +//| """The reason the chip started up from reset state. This can may be power up or due to an alarm.""" +//| + //| def sleep_until_alarm(alarm: Alarm, ...) -> Alarm: //| """Performs a light sleep until woken by one of the alarms. The alarm that woke us up is //| returned.""" @@ -54,14 +58,6 @@ //| STATIC mp_obj_t sleepio_sleep_until_alarm(size_t n_args, const mp_obj_t *args) { - // mp_int_t size = MP_OBJ_SMALL_INT_VALUE(struct_calcsize(args[0])); - // vstr_t vstr; - // vstr_init_len(&vstr, size); - // byte *p = (byte*)vstr.buf; - // memset(p, 0, size); - // byte *end_p = &p[size]; - // shared_modules_struct_pack_into(args[0], p, end_p, n_args - 1, &args[1]); - // return mp_obj_new_str_from_vstr(&mp_type_bytes, &vstr); } MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(sleepio_sleep_until_alarm_obj, 1, MP_OBJ_FUN_ARGS_MAX, sleepio_sleep_until_alarm); @@ -71,14 +67,6 @@ MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(sleepio_sleep_until_alarm_obj, 1, MP_OBJ_FUN //| ... //| STATIC mp_obj_t sleepio_set_alarms(size_t n_args, const mp_obj_t *args) { - // mp_int_t size = MP_OBJ_SMALL_INT_VALUE(struct_calcsize(args[0])); - // vstr_t vstr; - // vstr_init_len(&vstr, size); - // byte *p = (byte*)vstr.buf; - // memset(p, 0, size); - // byte *end_p = &p[size]; - // shared_modules_struct_pack_into(args[0], p, end_p, n_args - 1, &args[1]); - // return mp_obj_new_str_from_vstr(&mp_type_bytes, &vstr); } MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(sleepio_set_alarms_obj, 1, MP_OBJ_FUN_ARGS_MAX, sleepio_set_alarms); @@ -87,16 +75,23 @@ mp_map_elem_t sleepio_module_globals_table[] = { { MP_ROM_QSTR(MP_QSTR___name__), MP_ROM_QSTR(MP_QSTR_sleepio) }, { MP_ROM_QSTR(MP_QSTR_wake_alarm), mp_const_none }, + { MP_ROM_QSTR(MP_QSTR_reset_reason), mp_const_none }, { MP_ROM_QSTR(MP_QSTR_sleep_until_alarm), sleepio_sleep_until_alarm_obj }, { MP_ROM_QSTR(MP_QSTR_set_alarms), sleepio_set_alarms_obj }, }; STATIC MP_DEFINE_CONST_DICT(sleepio_module_globals, sleepio_module_globals_table); +// These are called from common hal code to set the current wake alarm. void common_hal_sleepio_set_wake_alarm(mp_obj_t alarm) { // sleepio_module_globals_table[1].value = alarm; } +// These are called from common hal code to set the current wake alarm. +void common_hal_sleepio_set_reset_reason(mp_obj_t reset_reason) { + // sleepio_module_globals_table[1].value = alarm; +} + const mp_obj_module_t sleepio_module = { .base = { &mp_type_module }, .globals = (mp_obj_dict_t*)&sleepio_module_globals, diff --git a/shared-bindings/sleepio/__init__.h b/shared-bindings/sleepio/__init__.h index ccd3bf4a02..6ea538055a 100644 --- a/shared-bindings/sleepio/__init__.h +++ b/shared-bindings/sleepio/__init__.h @@ -3,8 +3,7 @@ #include "py/obj.h" -// This is implemented by shared-bindings so that implementations can set the -// newest alarm source. -extern void common_hal_sleepio_set_wake_alarm(mp_obj_t alarm); +extern mp_obj_t common_hal_sleepio_get_wake_alarm(void); +extern sleepio_reset_reason_t common_hal_sleepio_get_reset_reason(void); #endif // MICROPY_INCLUDED_SHARED_BINDINGS_SLEEPIO___INIT___H diff --git a/supervisor/serial.h b/supervisor/serial.h index 9c2d44737a..066886303e 100644 --- a/supervisor/serial.h +++ b/supervisor/serial.h @@ -47,5 +47,4 @@ char serial_read(void); bool serial_bytes_available(void); bool serial_connected(void); -extern volatile bool _serial_connected; #endif // MICROPY_INCLUDED_SUPERVISOR_SERIAL_H diff --git a/supervisor/shared/rgb_led_status.c b/supervisor/shared/rgb_led_status.c index 283b9da123..bff74a1f0e 100644 --- a/supervisor/shared/rgb_led_status.c +++ b/supervisor/shared/rgb_led_status.c @@ -367,6 +367,7 @@ void prep_rgb_status_animation(const pyexec_result_t* result, status->found_main = found_main; status->total_exception_cycle = 0; status->ok = result->return_code != PYEXEC_EXCEPTION; + status->cycles = 0; if (status->ok) { // If this isn't an exception, skip exception sorting and handling return; @@ -411,14 +412,16 @@ void prep_rgb_status_animation(const pyexec_result_t* result, #endif } -void tick_rgb_status_animation(rgb_status_animation_t* status) { +bool tick_rgb_status_animation(rgb_status_animation_t* status) { #if defined(MICROPY_HW_NEOPIXEL) || (defined(MICROPY_HW_APA102_MOSI) && defined(MICROPY_HW_APA102_SCK)) || (defined(CP_RGB_STATUS_LED)) uint32_t tick_diff = supervisor_ticks_ms32() - status->pattern_start; if (status->ok) { // All is good. Ramp ALL_DONE up and down. if (tick_diff > ALL_GOOD_CYCLE_MS) { status->pattern_start = supervisor_ticks_ms32(); - tick_diff = 0; + status->cycles++; + new_status_color(BLACK); + return status->cycles; } uint16_t brightness = tick_diff * 255 / (ALL_GOOD_CYCLE_MS / 2); @@ -433,7 +436,8 @@ void tick_rgb_status_animation(rgb_status_animation_t* status) { } else { if (tick_diff > status->total_exception_cycle) { status->pattern_start = supervisor_ticks_ms32(); - tick_diff = 0; + status->cycles++; + return; } // First flash the file color. if (tick_diff < EXCEPTION_TYPE_LENGTH_MS) { diff --git a/supervisor/shared/safe_mode.c b/supervisor/shared/safe_mode.c index d59e754ed4..fa871eeebf 100644 --- a/supervisor/shared/safe_mode.c +++ b/supervisor/shared/safe_mode.c @@ -52,6 +52,10 @@ safe_mode_t wait_for_safe_mode_reset(void) { current_safe_mode = safe_mode; return safe_mode; } + if (common_hal_sleepio_get_reset_reason() != RESET_REASON_POWER_VALID && + common_hal_sleepio_get_reset_reason() != RESET_REASON_BUTTON) { + return NO_SAFE_MODE; + } port_set_saved_word(SAFE_MODE_DATA_GUARD | (MANUAL_SAFE_MODE << 8)); // Wait for a while to allow for reset. temp_status_color(SAFE_MODE); diff --git a/supervisor/shared/serial.h b/supervisor/shared/serial.h new file mode 100644 index 0000000000..84f92c337c --- /dev/null +++ b/supervisor/shared/serial.h @@ -0,0 +1,29 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2020 Scott Shawcroft for Adafruit Industries + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +#pragma once + +extern volatile bool _serial_connected; diff --git a/supervisor/shared/usb/usb.c b/supervisor/shared/usb/usb.c index 89fbf56f37..7fbc5cbe6a 100644 --- a/supervisor/shared/usb/usb.c +++ b/supervisor/shared/usb/usb.c @@ -30,6 +30,7 @@ #include "supervisor/background_callback.h" #include "supervisor/port.h" #include "supervisor/serial.h" +#include "supervisor/shared/serial.h" #include "supervisor/usb.h" #include "lib/utils/interrupt_char.h" #include "lib/mp-readline/readline.h" @@ -102,14 +103,16 @@ void usb_irq_handler(void) { // tinyusb callbacks //--------------------------------------------------------------------+ -// Invoked when device is mounted +// Invoked when device is plugged into a host void tud_mount_cb(void) { usb_msc_mount(); + _workflow_active = true; } -// Invoked when device is unmounted +// Invoked when device is unplugged from the host void tud_umount_cb(void) { usb_msc_umount(); + _workflow_active = false; } // Invoked when usb bus is suspended @@ -117,10 +120,12 @@ void tud_umount_cb(void) { // USB Specs: Within 7ms, device must draw an average current less than 2.5 mA from bus void tud_suspend_cb(bool remote_wakeup_en) { _serial_connected = false; + _workflow_active = false; } // Invoked when usb bus is resumed void tud_resume_cb(void) { + _workflow_active = true; } // Invoked when cdc when line state changed e.g connected/disconnected diff --git a/supervisor/shared/workflow.c b/supervisor/shared/workflow.c new file mode 100644 index 0000000000..adcffb319a --- /dev/null +++ b/supervisor/shared/workflow.c @@ -0,0 +1,32 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2020 Scott Shawcroft for Adafruit Industries + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +// Set by the shared USB code. +volatile bool _workflow_active; + +bool workflow_active(void) { + return _workflow_active; +} diff --git a/supervisor/shared/workflow.h b/supervisor/shared/workflow.h new file mode 100644 index 0000000000..4a138332a7 --- /dev/null +++ b/supervisor/shared/workflow.h @@ -0,0 +1,29 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2020 Scott Shawcroft for Adafruit Industries + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +#pragma once + +extern volatile bool _workflow_active; diff --git a/supervisor/supervisor.mk b/supervisor/supervisor.mk index e81c51a88c..a59e99e3de 100644 --- a/supervisor/supervisor.mk +++ b/supervisor/supervisor.mk @@ -75,6 +75,7 @@ else lib/tinyusb/src/class/cdc/cdc_device.c \ lib/tinyusb/src/tusb.c \ supervisor/shared/serial.c \ + supervisor/shared/workflow.c \ supervisor/usb.c \ supervisor/shared/usb/usb_desc.c \ supervisor/shared/usb/usb.c \ diff --git a/supervisor/workflow.h b/supervisor/workflow.h new file mode 100755 index 0000000000..4008b83a11 --- /dev/null +++ b/supervisor/workflow.h @@ -0,0 +1,30 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2020 Scott Shawcroft for Adafruit Industries + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +#pragma once + +// True when the user could be actively iterating on their code. +bool workflow_active(void); From 682054a2169c108ad69e84acdb53fdd26405077e Mon Sep 17 00:00:00 2001 From: Dan Halbert Date: Wed, 18 Nov 2020 20:44:34 -0500 Subject: [PATCH 17/34] WIP: redo API; not compiled yet --- locale/circuitpython.pot | 8 +- ports/esp32s2/mpconfigport.mk | 3 - py/circuitpy_defns.mk | 22 +-- py/circuitpy_mpconfig.h | 32 ----- py/circuitpy_mpconfig.mk | 20 +-- .../{sleep => alarm}/ResetReason.c | 18 +-- .../{sleep => alarm}/ResetReason.h | 9 +- shared-bindings/alarm/__init__.c | 130 ++++++++++++++++++ shared-bindings/alarm/__init__.h | 35 +++++ shared-bindings/alarm/pin/PinAlarm.c | 116 ++++++++++++++++ .../Time.h => alarm/pin/PinAlarm.h} | 22 ++- shared-bindings/alarm/time/DurationAlarm.c | 91 ++++++++++++ shared-bindings/alarm/time/DurationAlarm.h | 34 +++++ shared-bindings/alarm_io/__init__.c | 53 ------- shared-bindings/alarm_io/__init__.h | 17 --- shared-bindings/alarm_time/Time.c | 76 ---------- shared-bindings/alarm_time/__init__.c | 76 ---------- shared-bindings/alarm_time/__init__.h | 15 -- shared-bindings/microcontroller/__init__.c | 1 - shared-bindings/sleep/__init__.c | 112 --------------- shared-bindings/sleep/__init__.h | 9 -- 21 files changed, 445 insertions(+), 454 deletions(-) rename shared-bindings/{sleep => alarm}/ResetReason.c (79%) rename shared-bindings/{sleep => alarm}/ResetReason.h (83%) create mode 100644 shared-bindings/alarm/__init__.c create mode 100644 shared-bindings/alarm/__init__.h create mode 100644 shared-bindings/alarm/pin/PinAlarm.c rename shared-bindings/{alarm_time/Time.h => alarm/pin/PinAlarm.h} (64%) create mode 100644 shared-bindings/alarm/time/DurationAlarm.c create mode 100644 shared-bindings/alarm/time/DurationAlarm.h delete mode 100644 shared-bindings/alarm_io/__init__.c delete mode 100644 shared-bindings/alarm_io/__init__.h delete mode 100644 shared-bindings/alarm_time/Time.c delete mode 100644 shared-bindings/alarm_time/__init__.c delete mode 100644 shared-bindings/alarm_time/__init__.h delete mode 100644 shared-bindings/sleep/__init__.c delete mode 100644 shared-bindings/sleep/__init__.h diff --git a/locale/circuitpython.pot b/locale/circuitpython.pot index 14049eaef7..daeb5c3123 100644 --- a/locale/circuitpython.pot +++ b/locale/circuitpython.pot @@ -8,7 +8,7 @@ msgid "" msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2020-11-04 21:18+0530\n" +"POT-Creation-Date: 2020-11-19 00:22-0500\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language-Team: LANGUAGE \n" @@ -303,7 +303,8 @@ msgstr "" msgid "All I2C peripherals are in use" msgstr "" -#: ports/esp32s2/peripherals/pcnt_handler.c +#: ports/esp32s2/common-hal/countio/Counter.c +#: ports/esp32s2/common-hal/rotaryio/IncrementalEncoder.c msgid "All PCNT units in use" msgstr "" @@ -3221,6 +3222,7 @@ msgstr "" msgid "pow() with 3 arguments requires integers" msgstr "" +#: ports/esp32s2/boards/adafruit_magtag_2.9_grayscale/mpconfigboard.h #: ports/esp32s2/boards/adafruit_metro_esp32s2/mpconfigboard.h #: ports/esp32s2/boards/electroniccats_bastwifi/mpconfigboard.h #: ports/esp32s2/boards/espressif_kaluga_1/mpconfigboard.h @@ -3328,7 +3330,7 @@ msgstr "" msgid "size is defined for ndarrays only" msgstr "" -#: shared-bindings/alarm_time/__init__.c shared-bindings/time/__init__.c +#: shared-bindings/time/__init__.c msgid "sleep length must be non-negative" msgstr "" diff --git a/ports/esp32s2/mpconfigport.mk b/ports/esp32s2/mpconfigport.mk index af1db2b2bf..dea5d4dc18 100644 --- a/ports/esp32s2/mpconfigport.mk +++ b/ports/esp32s2/mpconfigport.mk @@ -15,9 +15,6 @@ LONGINT_IMPL = MPZ # These modules are implemented in ports//common-hal: CIRCUITPY_FULL_BUILD = 1 CIRCUITPY_ALARM = 1 -CIRCUITPY_ALARM_IO = 1 -CIRCUITPY_ALARM_TIME = 1 -CIRCUITPY_ALARM_TOUCH = 1 CIRCUITPY_AUDIOBUSIO = 0 CIRCUITPY_AUDIOIO = 0 CIRCUITPY_CANIO = 1 diff --git a/py/circuitpy_defns.mk b/py/circuitpy_defns.mk index d6c0f995ec..dd36c9457f 100644 --- a/py/circuitpy_defns.mk +++ b/py/circuitpy_defns.mk @@ -102,15 +102,6 @@ endif ifeq ($(CIRCUITPY_ALARM),1) SRC_PATTERNS += alarm/% endif -ifeq ($(CIRCUITPY_ALARM_IO),1) -SRC_PATTERNS += alarm_io/% -endif -ifeq ($(CIRCUITPY_ALARM_TIME),1) -SRC_PATTERNS += alarm_time/% -endif -ifeq ($(CIRCUITPY_ALARM_TOUCH),1) -SRC_PATTERNS += alarm_touch/% -endif ifeq ($(CIRCUITPY_ANALOGIO),1) SRC_PATTERNS += analogio/% endif @@ -247,9 +238,6 @@ endif ifeq ($(CIRCUITPY_SHARPDISPLAY),1) SRC_PATTERNS += sharpdisplay/% endif -ifeq ($(CIRCUITPY_SLEEP),1) -SRC_PATTERNS += sleep/% -endif ifeq ($(CIRCUITPY_SOCKETPOOL),1) SRC_PATTERNS += socketpool/% endif @@ -314,9 +302,9 @@ SRC_COMMON_HAL_ALL = \ _pew/PewPew.c \ _pew/__init__.c \ alarm/__init__.c \ - alarm_io/__init__.c \ - alarm_time/__init__.c \ - alarm_touch/__init__.c \ + alarm/pin/__init__.c \ + alarm/time/__init__.c \ + alarm/touch/__init__.c \ analogio/AnalogIn.c \ analogio/AnalogOut.c \ analogio/__init__.c \ @@ -372,8 +360,8 @@ SRC_COMMON_HAL_ALL = \ rtc/__init__.c \ sdioio/SDCard.c \ sdioio/__init__.c \ - sleep/__init__.c \ - sleep/ResetReason.c \ + sleepio/__init__.c \ + sleepio/ResetReason.c \ socketpool/__init__.c \ socketpool/SocketPool.c \ socketpool/Socket.c \ diff --git a/py/circuitpy_mpconfig.h b/py/circuitpy_mpconfig.h index b31cef8071..b5e9faa26e 100644 --- a/py/circuitpy_mpconfig.h +++ b/py/circuitpy_mpconfig.h @@ -250,27 +250,6 @@ extern const struct _mp_obj_module_t alarm_module; #define ALARM_MODULE #endif -#if CIRCUITPY_ALARM_IO -extern const struct _mp_obj_module_t alarm_io_module; -#define ALARM_IO_MODULE { MP_OBJ_NEW_QSTR(MP_QSTR_alarm_io), (mp_obj_t)&alarm_io_module }, -#else -#define ALARM_IO_MODULE -#endif - -#if CIRCUITPY_ALARM_TIME -extern const struct _mp_obj_module_t alarm_time_module; -#define ALARM_TIME_MODULE { MP_OBJ_NEW_QSTR(MP_QSTR_alarm_time), (mp_obj_t)&alarm_time_module }, -#else -#define ALARM_TIME_MODULE -#endif - -#if CIRCUITPY_ALARM_TOUCH -extern const struct _mp_obj_module_t alarm_touch_module; -#define ALARM_TOUCH_MODULE { MP_OBJ_NEW_QSTR(MP_QSTR_alarm_touch), (mp_obj_t)&alarm_touch_module }, -#else -#define ALARM_TOUCH_MODULE -#endif - #if CIRCUITPY_ANALOGIO #define ANALOGIO_MODULE { MP_OBJ_NEW_QSTR(MP_QSTR_analogio), (mp_obj_t)&analogio_module }, extern const struct _mp_obj_module_t analogio_module; @@ -642,13 +621,6 @@ extern const struct _mp_obj_module_t sharpdisplay_module; #define SHARPDISPLAY_MODULE #endif -#if CIRCUITPY_SLEEP -extern const struct _mp_obj_module_t sleep_module; -#define SLEEP_MODULE { MP_OBJ_NEW_QSTR(MP_QSTR_sleep),(mp_obj_t)&sleep_module }, -#else -#define SLEEP_MODULE -#endif - #if CIRCUITPY_SOCKETPOOL extern const struct _mp_obj_module_t socketpool_module; #define SOCKETPOOL_MODULE { MP_OBJ_NEW_QSTR(MP_QSTR_socketpool), (mp_obj_t)&socketpool_module }, @@ -807,9 +779,6 @@ extern const struct _mp_obj_module_t wifi_module; #define MICROPY_PORT_BUILTIN_MODULES_STRONG_LINKS \ AESIO_MODULE \ ALARM_MODULE \ - ALARM_IO_MODULE \ - ALARM_TIME_MODULE \ - ALARM_TOUCH_MODULE \ ANALOGIO_MODULE \ AUDIOBUSIO_MODULE \ AUDIOCORE_MODULE \ @@ -862,7 +831,6 @@ extern const struct _mp_obj_module_t wifi_module; SDCARDIO_MODULE \ SDIOIO_MODULE \ SHARPDISPLAY_MODULE \ - SLEEP_MODULE \ SOCKETPOOL_MODULE \ SSL_MODULE \ STAGE_MODULE \ diff --git a/py/circuitpy_mpconfig.mk b/py/circuitpy_mpconfig.mk index c47e3755ba..6192ee8a7a 100644 --- a/py/circuitpy_mpconfig.mk +++ b/py/circuitpy_mpconfig.mk @@ -39,18 +39,15 @@ CFLAGS += -DMICROPY_PY_ASYNC_AWAIT=$(MICROPY_PY_ASYNC_AWAIT) CIRCUITPY_AESIO ?= 0 CFLAGS += -DCIRCUITPY_AESIO=$(CIRCUITPY_AESIO) +# TODO: CIRCUITPY_ALARM will gradually be added to +# as many ports as possible +# so make this 1 or CIRCUITPY_FULL_BUILD eventually +CIRCUITPY_SLEEPIO ?= 0 +CFLAGS += -DCIRCUITPY_SLEEPIO=$(CIRCUITPY_SLEEPIO) + CIRCUITPY_ALARM ?= 0 CFLAGS += -DCIRCUITPY_ALARM=$(CIRCUITPY_ALARM) -CIRCUITPY_ALARM_IO ?= 0 -CFLAGS += -DCIRCUITPY_ALARM_IO=$(CIRCUITPY_ALARM_IO) - -CIRCUITPY_ALARM_TIME ?= 0 -CFLAGS += -DCIRCUITPY_ALARM_TIME=$(CIRCUITPY_ALARM_TIME) - -CIRCUITPY_ALARM_TOUCH ?= 0 -CFLAGS += -DCIRCUITPY_ALARM_TOUCH=$(CIRCUITPY_ALARM_TOUCH) - CIRCUITPY_ANALOGIO ?= 1 CFLAGS += -DCIRCUITPY_ANALOGIO=$(CIRCUITPY_ANALOGIO) @@ -221,11 +218,6 @@ CFLAGS += -DCIRCUITPY_SDIOIO=$(CIRCUITPY_SDIOIO) CIRCUITPY_SHARPDISPLAY ?= $(CIRCUITPY_FRAMEBUFFERIO) CFLAGS += -DCIRCUITPY_SHARPDISPLAY=$(CIRCUITPY_SHARPDISPLAY) -# TODO: CIRCUITPY_SLEEP will gradually be added to all ports -# even if it doesn't actually sleep, so make this 1 eventually. -CIRCUITPY_SLEEP ?= 0 -CFLAGS += -DCIRCUITPY_SLEEP=$(CIRCUITPY_SLEEP) - CIRCUITPY_SOCKETPOOL ?= $(CIRCUITPY_WIFI) CFLAGS += -DCIRCUITPY_SOCKETPOOL=$(CIRCUITPY_SOCKETPOOL) diff --git a/shared-bindings/sleep/ResetReason.c b/shared-bindings/alarm/ResetReason.c similarity index 79% rename from shared-bindings/sleep/ResetReason.c rename to shared-bindings/alarm/ResetReason.c index cce55a81a5..456715a08e 100644 --- a/shared-bindings/sleep/ResetReason.c +++ b/shared-bindings/alarm/ResetReason.c @@ -26,12 +26,12 @@ #include "py/enum.h" -#include "shared-bindings/sleep/ResetReason.h" +#include "shared-bindings/alarm/ResetReason.h" -MAKE_ENUM_VALUE(sleep_reset_reason_type, reset_reason, POWER_VALID, RESET_REASON_POWER_VALID); -MAKE_ENUM_VALUE(sleep_reset_reason_type, reset_reason, SOFTWARE, RESET_REASON_SOFTWARE); -MAKE_ENUM_VALUE(sleep_reset_reason_type, reset_reason, DEEP_SLEEP_ALARM, RESET_REASON_DEEP_SLEEP_ALARM); -MAKE_ENUM_VALUE(sleep_reset_reason_type, reset_reason, EXTERNAL, RESET_REASON_EXTERNAL); +MAKE_ENUM_VALUE(alarm_reset_reason_type, reset_reason, POWER_VALID, RESET_REASON_POWER_VALID); +MAKE_ENUM_VALUE(alarm_reset_reason_type, reset_reason, SOFTWARE, RESET_REASON_SOFTWARE); +MAKE_ENUM_VALUE(alarm_reset_reason_type, reset_reason, DEEP_SLEEP_ALARM, RESET_REASON_DEEP_SLEEP_ALARM); +MAKE_ENUM_VALUE(alarm_reset_reason_type, reset_reason, EXTERNAL, RESET_REASON_EXTERNAL); //| class ResetReason: //| """The reason the chip was last reset""" @@ -48,14 +48,14 @@ MAKE_ENUM_VALUE(sleep_reset_reason_type, reset_reason, EXTERNAL, RESET_REASON_EX //| EXTERNAL: object //| """The chip was reset by an external input such as a button.""" //| -MAKE_ENUM_MAP(sleep_reset_reason) { +MAKE_ENUM_MAP(alarm_reset_reason) { MAKE_ENUM_MAP_ENTRY(reset_reason, POWER_VALID), MAKE_ENUM_MAP_ENTRY(reset_reason, SOFTWARE), MAKE_ENUM_MAP_ENTRY(reset_reason, DEEP_SLEEP_ALARM), MAKE_ENUM_MAP_ENTRY(reset_reason, EXTERNAL), }; -STATIC MP_DEFINE_CONST_DICT(sleep_reset_reason_locals_dict, sleep_reset_reason_locals_table); +STATIC MP_DEFINE_CONST_DICT(alarm_reset_reason_locals_dict, alarm_reset_reason_locals_table); -MAKE_PRINTER(sleep, sleep_reset_reason); +MAKE_PRINTER(alarm, alarm_reset_reason); -MAKE_ENUM_TYPE(sleep, ResetReason, sleep_reset_reason); +MAKE_ENUM_TYPE(alarm, ResetReason, alarm_reset_reason); diff --git a/shared-bindings/sleep/ResetReason.h b/shared-bindings/alarm/ResetReason.h similarity index 83% rename from shared-bindings/sleep/ResetReason.h rename to shared-bindings/alarm/ResetReason.h index 2b312bb897..6fe7a4bd31 100644 --- a/shared-bindings/sleep/ResetReason.h +++ b/shared-bindings/alarm/ResetReason.h @@ -24,13 +24,16 @@ * THE SOFTWARE. */ -#pragma once +#ifndef MICROPY_INCLUDED_SHARED_BINDINGS_ALARM__RESET_REASON__H +#define MICROPY_INCLUDED_SHARED_BINDINGS_ALARM__RESET_REASON__H typedef enum { RESET_REASON_POWER_APPLIED, RESET_REASON_SOFTWARE, RESET_REASON_DEEP_SLEEP_ALARM, RESET_REASON_BUTTON, -} sleep_reset_reason_t; +} alarm_reset_reason_t; -extern const mp_obj_type_t sleep_reset_reason_type; +extern const mp_obj_type_t alarm_reset_reason_type; + +#endif // MICROPY_INCLUDED_SHARED_BINDINGS_ALARM__RESET_REASON__H diff --git a/shared-bindings/alarm/__init__.c b/shared-bindings/alarm/__init__.c new file mode 100644 index 0000000000..20535e156b --- /dev/null +++ b/shared-bindings/alarm/__init__.c @@ -0,0 +1,130 @@ +//| """Power-saving light and deep sleep. Alarms can be set to wake up from sleep. +//| +//| The `alarm` module provides sleep related functionality. There are two supported levels of +//| sleep, light and deep. +//| +//| Light sleep leaves the CPU and RAM powered so that CircuitPython can resume where it left off +//| after being woken up. CircuitPython automatically goes into a light sleep when `time.sleep()` is +//| called. To light sleep until a non-time alarm use `alarm.sleep_until_alarm()`. Any active +//| peripherals, such as I2C, are left on. +//| +//| Deep sleep shuts down power to nearly all of the chip including the CPU and RAM. This can save +//| a more significant amount of power, but CircuitPython must start ``code.py`` from the beginning when woken +//| up. CircuitPython will enter deep sleep automatically when the current program exits without error +//| or calls `sys.exit(0)`. +//| If an error causes CircuitPython to exit, error LED error flashes will be done periodically. +//| An error includes an uncaught exception, or sys.exit called with a non-zero argumetn. +//| To set alarms for deep sleep use `alarm.reload_on_alarm()` they will apply to next deep sleep only.""" +//| + +//| wake_alarm: Alarm +//| """The most recent alarm to wake us up from a sleep (light or deep.)""" +//| + +//| reset_reason: ResetReason +//| """The reason the chip started up from reset state. This can may be power up or due to an alarm.""" +//| + +//| def sleep(alarm: Alarm, ...) -> Alarm: +//| """Performs a light sleep until woken by one of the alarms. The alarm that triggers the wake +//| is returned, and is also available as `alarm.wake_alarm` +//| ... +//| + +#include "py/obj.h" +#include "py/runtime.h" + +#include "shared-bindings/alarm/pin/__init__.h" +#include "shared-bindings/alarm/time/__init__.h" + +STATIC mp_obj_t alarm_sleep_until_alarm(size_t n_args, const mp_obj_t *args) { + // TODO +} +MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(alarm_sleep_until_alarm_obj, 1, MP_OBJ_FUN_ARGS_MAX, alarm_sleep_until_alarm); + +//| def restart_on_alarm(alarm: Alarm, ...) -> None: +//| """Set one or more alarms to wake up from a deep sleep. +//| When awakened, ``code.py`` will restart from the beginning. +//| The last alarm to wake us up is available as `wake_alarm`. +//| """ +//| ... +//| +STATIC mp_obj_t alarm_restart_on_alarm(size_t n_args, const mp_obj_t *args) { + // TODO +} +MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(alarm_restart_on_alarm_obj, 1, MP_OBJ_FUN_ARGS_MAX, alarm_restart_on_alarm); + +//| """The `alarm.pin` module contains alarm attributes and classes related to pins +//| """ +//| +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_PinAlarm), MP_ROM_PTR(&alarm_pin_pin_alarm_type) }, +}; + +STATIC MP_DEFINE_CONST_DICT(alarm_pin_globals, alarm_pin_globals_table); + +const mp_obj_module_t alarm_pin_module = { + .base = { &mp_type_module }, + .globals = (mp_obj_dict_t*)&alarm_pinn_globals, +}; + +//| """The `alarm.time` module contains alarm attributes and classes related to time-keeping. +//| """ +//| +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_DurationAlarm), MP_ROM_PTR(&alarm_time_duration_alarm_type) }, +}; + +STATIC MP_DEFINE_CONST_DICT(alarm_time_globals, alarm_time_globals_table); + +const mp_obj_module_t alarm_time_module = { + .base = { &mp_type_module }, + .globals = (mp_obj_dict_t*)&alarm_time_globals, +}; + +mp_map_elem_t alarm_module_globals_table[] = { + { MP_ROM_QSTR(MP_QSTR___name__), MP_ROM_QSTR(MP_QSTR_alarm) }, + + // wake_alarm and reset_reason are mutable attributes. + { MP_ROM_QSTR(MP_QSTR_wake_alarm), mp_const_none }, + { MP_ROM_QSTR(MP_QSTR_reset_reason), mp_const_none }, + + { MP_ROM_QSTR(MP_QSTR_sleep_until_alarm), MP_ROM_PTR(&alarm_sleep_until_alarm_obj) }, + { MP_ROM_QSTR(MP_QSTR_restart_on_alarm), MP_ROM_PTR(&alarm_restart_on_alarm_obj) }, + + { MP_ROM_QSTR(MP_QSTR_pin), MP_ROM_PTR(&alarm_pin_module) }, + { MP_ROM_QSTR(MP_QSTR_time), MP_ROM_PTR(&alarm_time_module) } + +}; +STATIC MP_DEFINE_MUTABLE_DICT(alarm_module_globals, alarm_module_globals_table); + +// These are called from common_hal code to set the current wake alarm. +void common_hal_alarm_set_wake_alarm(mp_obj_t alarm) { + // Equivalent of: + // alarm.wake_alarm = alarm + mp_map_elem_t *elem = + mp_map_lookup(&alarm_module_globals_table, MP_ROM_QSTR(MP_QSTR_wake_alarm), MP_MAP_LOOKUP); + if (elem) { + elem->value = alarm; + } +} + +// These are called from common hal code to set the current wake alarm. +void common_hal_alarm_set_reset_reason(mp_obj_t reset_reason) { + // Equivalent of: + // alarm.reset_reason = reset_reason + mp_map_elem_t *elem = + mp_map_lookup(&alarm_module_globals_table, MP_ROM_QSTR(MP_QSTR_reset_reason), MP_MAP_LOOKUP); + if (elem) { + elem->value = reset_reason; + } +} + +const mp_obj_module_t alarm_module = { + .base = { &mp_type_module }, + .globals = (mp_obj_dict_t*)&alarm_module_globals, +}; diff --git a/shared-bindings/alarm/__init__.h b/shared-bindings/alarm/__init__.h new file mode 100644 index 0000000000..ce9cc79f40 --- /dev/null +++ b/shared-bindings/alarm/__init__.h @@ -0,0 +1,35 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2020 Dan Halbert for Adafruit Industries + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +#ifndef MICROPY_INCLUDED_SHARED_BINDINGS_ALARM___INIT___H +#define MICROPY_INCLUDED_SHARED_BINDINGS_ALARM___INIT___H + +#include "py/obj.h" + +extern void common_hal_alarm_set_wake_alarm(mp_obj_t alarm); +extern void common_hal_alarm_set_reset_reason(mp_obj_t reset_reason); + +#endif // MICROPY_INCLUDED_SHARED_BINDINGS_ALARM___INIT___H diff --git a/shared-bindings/alarm/pin/PinAlarm.c b/shared-bindings/alarm/pin/PinAlarm.c new file mode 100644 index 0000000000..1404fa3f41 --- /dev/null +++ b/shared-bindings/alarm/pin/PinAlarm.c @@ -0,0 +1,116 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2020 Dan Halbert for Adafruit Industries + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +#include "shared-bindings/board/__init__.h" +#include "shared-bindings/microcontroller/__init__.h" +#include "shared-bindings/microcontroller/Pin.h" + +#include "py/nlr.h" +#include "py/obj.h" +#include "py/runtime.h" +#include "supervisor/shared/translate.h" + +//| class PinAlarm: +//| """Trigger an alarm when a pin changes state. +//| +//| def __init__(self, pin: microcontroller.Pin, level: bool, *, edge: bool = False, pull: bool = False) -> None: +//| """Create an alarm triggered by a `~microcontroller.Pin` level. The alarm is not active +//| until it is listed in an `alarm`-enabling function, such as `alarm.sleep()` or +//| `alarm.wake_after_exit()`. + +//| :param ~microcontroller.Pin pin: The pin to monitor. On some ports, the choice of pin +//| may be limited due to hardware restrictions, particularly for deep-sleep alarms. +//| :param bool level: When active, trigger when the level is high (``True``) or low (``False``). +//| On some ports, multiple `PinAlarm` objects may need to have coordinated levels +//| for deep-sleep alarms +//| :param bool edge: If ``True``, trigger only when there is a transition to the specified +//| value of `level`. If ``True``, if the alarm becomes active when the pin level already +//| matches `level`, the alarm is not triggered: the pin must transition from ``not level`` +//| to ``level`` to trigger the alarm. On some ports, edge-triggering may not be available, +//| particularly for deep-sleep alarms. +//| :param bool pull: Enable a pull-up or pull-down which pulls the pin to level opposite +//| opposite that of `level`. For instance, if `level` is set to ``True``, setting `pull` +//| to ``True`` will enable a pull-down, to hold the pin low normally until an outside signal +//| pulls it high. +//| """ +//| ... +//| +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 *args, mp_map_t *kw_args) { + alarm_pin_pin_alarm_obj_t *self = m_new_obj(alarm_pin_pin_alarm_obj_t); + self->base.type = &alarm_pin_pin_alarm_type; + enum { ARG_pin, ARG_level, ARG_edge, ARG_pull }; + static const mp_arg_t allowed_args[] = { + { MP_QSTR_pin, MP_ARG_REQUIRED | MP_ARG_OBJ }, + { MP_QSTR_level, MP_ARG_REQUIRED | MP_ARG_BOOL }, + { MP_QSTR_edge, MP_ARG_KW_ONLY | MP_ARG_BOOL, {.u_bool = false} }, + { MP_QSTR_pull, MP_ARG_KW_ONLY | MP_ARG_BOOL, {.u_bool = false} }, + }; + mp_arg_val_t args[MP_ARRAY_SIZE(allowed_args)]; + mp_arg_parse_all(n_args, pos_args, kw_args, MP_ARRAY_SIZE(allowed_args), allowed_args, args); + + const mcu_pin_obj_t* pin = validate_obj_is_free_pin(args[ARG_pin].u_obj); + + common_hal_alarm_pin_pin_pin_alarm_construct( + self, pin, args[ARG_level].u_bool, args[ARG_edge].u_bool, args[ARG_pull].u_bool); + + return MP_OBJ_FROM_PTR(self); +} + +//| def __eq__(self, other: object) -> bool: +//| """Two PinAlarm objects are equal if their durations are the same if their pin, +//| level, edge, and pull attributes are all the same.""" +//| ... +//| +STATIC mp_obj_t alarm_pin_pin_alarm_binary_op(mp_binary_op_t op, mp_obj_t lhs_in, mp_obj_t rhs_in) { + switch (op) { + case MP_BINARY_OP_EQUAL: + if (MP_OBJ_IS_TYPE(rhs_in, &alarm_pin_pin_alarm_type)) { + // Pins are singletons, so we can compare them directly. + return mp_obj_new_bool( + common_hal_pin_pin_alarm_get_pin(lhs_in) == common_hal_pin_pin_alarm_get_pin(rhs_in) && + common_hal_pin_pin_alarm_get_level(lhs_in) == common_hal_pin_pin_alarm_get_level(rhs_in) && + common_hal_pin_pin_alarm_get_edge(lhs_in) == common_hal_pin_pin_alarm_get_edge(rhs_in) && + common_hal_pin_pin_alarm_get_pull(lhs_in) == common_hal_pin_pin_alarm_get_pull(rhs_in)) + } + return mp_const_false; + + default: + return MP_OBJ_NULL; // op not supported + } +} + +STATIC const mp_rom_map_elem_t alarm_pin_pin_alarm_locals_dict_table[] = { +}; + +STATIC MP_DEFINE_CONST_DICT(alarm_pin_pin_alarm_locals, alarm_pin_pin_alarm_locals_dict); + +const mp_obj_type_t alarm_pin_pin_alarm_type = { + { &mp_type_type }, + .name = MP_QSTR_PinAlarm, + .make_new = alarm_pin_pin_alarm_make_new, + .locals_dict = (mp_obj_t)&alarm_pin_pin_alarm_locals, +}; diff --git a/shared-bindings/alarm_time/Time.h b/shared-bindings/alarm/pin/PinAlarm.h similarity index 64% rename from shared-bindings/alarm_time/Time.h rename to shared-bindings/alarm/pin/PinAlarm.h index 9962c26f25..e38c7f620c 100644 --- a/shared-bindings/alarm_time/Time.h +++ b/shared-bindings/alarm/pin/PinAlarm.h @@ -1,9 +1,9 @@ /* - * This file is part of the Micro Python project, http://micropython.org/ + * This file is part of the MicroPython project, http://micropython.org/ * * The MIT License (MIT) * - * Copyright (c) 2020 Scott Shawcroft for Adafruit Industries + * Copyright (c) 2020 Dan Halbert for Adafruit Industries * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -24,19 +24,13 @@ * THE SOFTWARE. */ -#ifndef MICROPY_INCLUDED_SHARED_BINDINGS_ALARM_TIME_TIME_H -#define MICROPY_INCLUDED_SHARED_BINDINGS_ALARM_TIME_TIME_H +#ifndef MICROPY_INCLUDED_SHARED_BINDINGS_ALARM_PIN_PIN_ALARM_H +#define MICROPY_INCLUDED_SHARED_BINDINGS_ALARM_PIN_PIN_ALARM_H -#include "py/runtime.h" +#include "py/obj.h" -typedef struct { - mp_obj_base_t base; - uint64_t time_to_alarm; -} alarm_time_time_obj_t; +extern const mp_obj_type_t alarm_pin_pin_alarm_type; -extern const mp_obj_type_t alarm_time_time_type; +extern void common_hal_alarm_pin_pin_pin_alarm_construct(alarm_pin_pin_alarm_obj_t *self, const mcu_pin_obj_t *pin, bool level, bool edge, bool pull); -void common_hal_alarm_time_time_construct(alarm_time_time_obj_t* self, - uint64_t ticks_ms); - -#endif //MICROPY_INCLUDED_SHARED_BINDINGS_ALARM_TIME_TIME_H +#endif // MICROPY_INCLUDED_SHARED_BINDINGS_ALARM_PIN_PIN_ALARM_H diff --git a/shared-bindings/alarm/time/DurationAlarm.c b/shared-bindings/alarm/time/DurationAlarm.c new file mode 100644 index 0000000000..c30c7f326c --- /dev/null +++ b/shared-bindings/alarm/time/DurationAlarm.c @@ -0,0 +1,91 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2020 Dan Halbert for Adafruit Industries + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +#include "shared-bindings/board/__init__.h" +#include "shared-bindings/microcontroller/__init__.h" +#include "shared-bindings/microcontroller/Pin.h" + +#include "py/nlr.h" +#include "py/obj.h" +#include "py/runtime.h" +#include "supervisor/shared/translate.h" + +//| class DurationAlarm: +//| """Trigger an alarm at a specified interval from now. +//| +//| def __init__(self, secs: float) -> None: +//| """Create an alarm that will be triggered in `secs` seconds **from the time +//| the alarm is created**. The alarm is not active until it is listed in an +//| `alarm`-enabling function, such as `alarm.sleep()` or +//| `alarm.wake_after_exit()`. But the interval starts immediately upon +//| instantiation. +//| """ +//| ... +//| +STATIC mp_obj_t alarm_time_duration_alarm_make_new(const mp_obj_type_t *type, + mp_uint_t n_args, const mp_obj_t *args, mp_map_t *kw_args) { + mp_arg_check_num(n_args, kw_args, 1, 1, false); + + alarm_pin_duration_alarm_obj_t *self = m_new_obj(alarm_pin_duration_alarm_obj_t); + self->base.type = &alarm_pin_pin_alarm_type; + + mp_float_t secs = mp_obj_get_float(args[0]); + + common_hal_alarm_time_duration_alarm_construct(self, secs); + + return MP_OBJ_FROM_PTR(self); +} + +//| def __eq__(self, other: object) -> bool: +//| """Two DurationAlarm objects are equal if their durations are the same.""" +//| ... +//| +STATIC mp_obj_t alarm_time_duration_alarm_binary_op(mp_binary_op_t op, mp_obj_t lhs_in, mp_obj_t rhs_in) { + switch (op) { + case MP_BINARY_OP_EQUAL: + if (MP_OBJ_IS_TYPE(rhs_in, &alarm_time_duration_alarm_type)) { + return mp_obj_new_bool( + common_hal_alarm_time_duration_alarm_get_duration(lhs_in) == + common_hal_alarm_time_duration_alarm_get_duration(rhs_in)); + } + return mp_const_false; + + default: + return MP_OBJ_NULL; // op not supported + } +} + +STATIC const mp_rom_map_elem_t alarm_time_duration_alarm_locals_dict_table[] = { +}; + +STATIC MP_DEFINE_CONST_DICT(alarm_time_duration_alarm_locals_dict, alarm_time_duration_alarm_locals_dict_table); + +const mp_obj_type_t alarm_time_duration_alarm_type = { + { &mp_type_type }, + .name = MP_QSTR_DurationAlarm, + .make_new = alarm_time_duration_alarm_make_new, + .locals_dict = (mp_obj_t)&alarm_time_duration_alarm_locals, +}; diff --git a/shared-bindings/alarm/time/DurationAlarm.h b/shared-bindings/alarm/time/DurationAlarm.h new file mode 100644 index 0000000000..1e4db6ac53 --- /dev/null +++ b/shared-bindings/alarm/time/DurationAlarm.h @@ -0,0 +1,34 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2020 Dan Halbert for Adafruit Industries + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +#ifndef MICROPY_INCLUDED_SHARED_BINDINGS_ALARM_TIME_DURATION_ALARM_H +#define MICROPY_INCLUDED_SHARED_BINDINGS_ALARM_TIME_DURATION_ALARM_H + +#include "py/obj.h" + +extern const mp_obj_type_t alarm_time_duration_alarm_type; + +#endif // MICROPY_INCLUDED_SHARED_BINDINGS_ALARM_TIME_DURATION_ALARM_H diff --git a/shared-bindings/alarm_io/__init__.c b/shared-bindings/alarm_io/__init__.c deleted file mode 100644 index 4e42f9a2e1..0000000000 --- a/shared-bindings/alarm_io/__init__.c +++ /dev/null @@ -1,53 +0,0 @@ -#include "py/obj.h" - -#include "shared-bindings/alarm_io/__init__.h" -#include "shared-bindings/microcontroller/Pin.h" - -//| """alarm_io module -//| -//| The `alarm_io` module implements deep sleep.""" - -STATIC mp_obj_t alarm_io_pin_state(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) { - enum { ARG_level, ARG_pull }; - static const mp_arg_t allowed_args[] = { - { MP_QSTR_level, MP_ARG_INT | MP_ARG_KW_ONLY | MP_ARG_REQUIRED }, - { MP_QSTR_pull, MP_ARG_INT | MP_ARG_KW_ONLY, {.u_bool = false} }, - }; - - mp_arg_val_t args[MP_ARRAY_SIZE(allowed_args)]; - mp_arg_parse_all(n_args - 1, pos_args + 1, kw_args, MP_ARRAY_SIZE(allowed_args), allowed_args, args); - - mcu_pin_obj_t *pin = validate_obj_is_pin(pos_args[0]); - alarm_io_obj_t *self = m_new_obj(alarm_io_obj_t); - - self->base.type = &alarm_io_type; - self->gpio = pin->number; - self->level = args[ARG_level].u_int; - self->pull = args[ARG_pull].u_bool; - - return common_hal_alarm_io_pin_state(self); -} -STATIC MP_DEFINE_CONST_FUN_OBJ_KW(alarm_io_pin_state_obj, 1, alarm_io_pin_state); - -STATIC mp_obj_t alarm_io_disable(void) { - common_hal_alarm_io_disable(); - return mp_const_none; -} -STATIC MP_DEFINE_CONST_FUN_OBJ_0(alarm_io_disable_obj, alarm_io_disable); - -STATIC const mp_rom_map_elem_t alarm_io_module_globals_table[] = { - { MP_ROM_QSTR(MP_QSTR___name__), MP_ROM_QSTR(MP_QSTR_alarm_io) }, - { MP_OBJ_NEW_QSTR(MP_QSTR_PinState), MP_ROM_PTR(&alarm_io_pin_state_obj) }, - { MP_OBJ_NEW_QSTR(MP_QSTR_Disable), MP_ROM_PTR(&alarm_io_disable_obj) }, -}; -STATIC MP_DEFINE_CONST_DICT(alarm_io_module_globals, alarm_io_module_globals_table); - -const mp_obj_module_t alarm_io_module = { - .base = { &mp_type_module }, - .globals = (mp_obj_dict_t*)&alarm_io_module_globals, -}; - -const mp_obj_type_t alarm_io_type = { - { &mp_type_type }, - .name = MP_QSTR_ioAlarm, -}; diff --git a/shared-bindings/alarm_io/__init__.h b/shared-bindings/alarm_io/__init__.h deleted file mode 100644 index 0a53497c01..0000000000 --- a/shared-bindings/alarm_io/__init__.h +++ /dev/null @@ -1,17 +0,0 @@ -#ifndef MICROPY_INCLUDED_SHARED_BINDINGS_ALARM_IO___INIT___H -#define MICROPY_INCLUDED_SHARED_BINDINGS_ALARM_IO___INIT___H - -#include "py/runtime.h" - -typedef struct { - mp_obj_base_t base; - uint8_t gpio, level; - bool pull; -} alarm_io_obj_t; - -extern const mp_obj_type_t alarm_io_type; - -extern mp_obj_t common_hal_alarm_io_pin_state (alarm_io_obj_t *self_in); -extern void common_hal_alarm_io_disable (void); - -#endif //MICROPY_INCLUDED_SHARED_BINDINGS_ALARM_IO___INIT___H diff --git a/shared-bindings/alarm_time/Time.c b/shared-bindings/alarm_time/Time.c deleted file mode 100644 index 904bf522e2..0000000000 --- a/shared-bindings/alarm_time/Time.c +++ /dev/null @@ -1,76 +0,0 @@ -/* - * This file is part of the MicroPython project, http://micropython.org/ - * - * The MIT License (MIT) - * - * Copyright (c) 2020 Scott Shawcroft - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ - -#include "py/obj.h" -#include "shared-bindings/alarm_time/__init__.h" - -//| """alarm_time module -//| -//| The `alarm_time` module implements deep sleep.""" - -STATIC mp_obj_t alarm_time_duration(mp_obj_t seconds_o) { - #if MICROPY_PY_BUILTINS_FLOAT - mp_float_t seconds = mp_obj_get_float(seconds_o); - mp_float_t msecs = 1000.0f * seconds + 0.5f; - #else - mp_int_t seconds = mp_obj_get_int(seconds_o); - mp_int_t msecs = 1000 * seconds; - #endif - - if (seconds < 0) { - mp_raise_ValueError(translate("sleep length must be non-negative")); - } - common_hal_alarm_time_duration(msecs); - - alarm_time_obj_t *self = m_new_obj(alarm_time_obj_t); - self->base.type = &alarm_time_type; - - return self; -} -STATIC MP_DEFINE_CONST_FUN_OBJ_1(alarm_time_duration_obj, alarm_time_duration); - -STATIC mp_obj_t alarm_time_disable(void) { - common_hal_alarm_time_disable(); - return mp_const_none; -} -STATIC MP_DEFINE_CONST_FUN_OBJ_0(alarm_time_disable_obj, alarm_time_disable); - -STATIC const mp_rom_map_elem_t alarm_time_module_globals_table[] = { - { MP_ROM_QSTR(MP_QSTR___name__), MP_ROM_QSTR(MP_QSTR_alarm_time) }, - { MP_OBJ_NEW_QSTR(MP_QSTR_Duration), MP_ROM_PTR(&alarm_time_duration_obj) }, - { MP_OBJ_NEW_QSTR(MP_QSTR_Disable), MP_ROM_PTR(&alarm_time_disable_obj) }, -}; -STATIC MP_DEFINE_CONST_DICT(alarm_time_module_globals, alarm_time_module_globals_table); - -const mp_obj_module_t alarm_time_module = { - .base = { &mp_type_module }, - .globals = (mp_obj_dict_t*)&alarm_time_module_globals, -}; - -const mp_obj_type_t alarm_time_type = { - { &mp_type_type }, - .name = MP_QSTR_timeAlarm, -}; diff --git a/shared-bindings/alarm_time/__init__.c b/shared-bindings/alarm_time/__init__.c deleted file mode 100644 index 904bf522e2..0000000000 --- a/shared-bindings/alarm_time/__init__.c +++ /dev/null @@ -1,76 +0,0 @@ -/* - * This file is part of the MicroPython project, http://micropython.org/ - * - * The MIT License (MIT) - * - * Copyright (c) 2020 Scott Shawcroft - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ - -#include "py/obj.h" -#include "shared-bindings/alarm_time/__init__.h" - -//| """alarm_time module -//| -//| The `alarm_time` module implements deep sleep.""" - -STATIC mp_obj_t alarm_time_duration(mp_obj_t seconds_o) { - #if MICROPY_PY_BUILTINS_FLOAT - mp_float_t seconds = mp_obj_get_float(seconds_o); - mp_float_t msecs = 1000.0f * seconds + 0.5f; - #else - mp_int_t seconds = mp_obj_get_int(seconds_o); - mp_int_t msecs = 1000 * seconds; - #endif - - if (seconds < 0) { - mp_raise_ValueError(translate("sleep length must be non-negative")); - } - common_hal_alarm_time_duration(msecs); - - alarm_time_obj_t *self = m_new_obj(alarm_time_obj_t); - self->base.type = &alarm_time_type; - - return self; -} -STATIC MP_DEFINE_CONST_FUN_OBJ_1(alarm_time_duration_obj, alarm_time_duration); - -STATIC mp_obj_t alarm_time_disable(void) { - common_hal_alarm_time_disable(); - return mp_const_none; -} -STATIC MP_DEFINE_CONST_FUN_OBJ_0(alarm_time_disable_obj, alarm_time_disable); - -STATIC const mp_rom_map_elem_t alarm_time_module_globals_table[] = { - { MP_ROM_QSTR(MP_QSTR___name__), MP_ROM_QSTR(MP_QSTR_alarm_time) }, - { MP_OBJ_NEW_QSTR(MP_QSTR_Duration), MP_ROM_PTR(&alarm_time_duration_obj) }, - { MP_OBJ_NEW_QSTR(MP_QSTR_Disable), MP_ROM_PTR(&alarm_time_disable_obj) }, -}; -STATIC MP_DEFINE_CONST_DICT(alarm_time_module_globals, alarm_time_module_globals_table); - -const mp_obj_module_t alarm_time_module = { - .base = { &mp_type_module }, - .globals = (mp_obj_dict_t*)&alarm_time_module_globals, -}; - -const mp_obj_type_t alarm_time_type = { - { &mp_type_type }, - .name = MP_QSTR_timeAlarm, -}; diff --git a/shared-bindings/alarm_time/__init__.h b/shared-bindings/alarm_time/__init__.h deleted file mode 100644 index a963830693..0000000000 --- a/shared-bindings/alarm_time/__init__.h +++ /dev/null @@ -1,15 +0,0 @@ -#ifndef MICROPY_INCLUDED_SHARED_BINDINGS_ALARM_TIME___INIT___H -#define MICROPY_INCLUDED_SHARED_BINDINGS_ALARM_TIME___INIT___H - -#include "py/runtime.h" - -typedef struct { - mp_obj_base_t base; -} alarm_time_obj_t; - -extern const mp_obj_type_t alarm_time_type; - -extern void common_hal_alarm_time_duration (uint32_t); -extern void common_hal_alarm_time_disable (void); - -#endif //MICROPY_INCLUDED_SHARED_BINDINGS_ALARM_TIME___INIT___H diff --git a/shared-bindings/microcontroller/__init__.c b/shared-bindings/microcontroller/__init__.c index bbc1640f76..bfeb812d67 100644 --- a/shared-bindings/microcontroller/__init__.c +++ b/shared-bindings/microcontroller/__init__.c @@ -160,7 +160,6 @@ STATIC MP_DEFINE_CONST_FUN_OBJ_0(mcu_sleep_obj, mcu_sleep); //| //| .. module:: microcontroller.pin //| :synopsis: Microcontroller pin names -//| :platform: SAMD21 //| //| References to pins as named by the microcontroller""" //| diff --git a/shared-bindings/sleep/__init__.c b/shared-bindings/sleep/__init__.c deleted file mode 100644 index a714e00213..0000000000 --- a/shared-bindings/sleep/__init__.c +++ /dev/null @@ -1,112 +0,0 @@ -/* - * This file is part of the MicroPython project, http://micropython.org/ - * - * The MIT License (MIT) - * - * Copyright (c) 2020 Scott Shawcroft - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ - -#include "shared-bindings/alarm/__init__.h" - -//| """Light and deep sleep used to save power -//| -//| The `sleep` module provides sleep related functionality. There are two supported levels of -//| sleep, light and deep. -//| -//| Light sleep leaves the CPU and RAM powered so that CircuitPython can resume where it left off -//| after being woken up. Light sleep is automatically done by CircuitPython when `time.sleep()` is -//| called. To light sleep until a non-time alarm use `sleep.sleep_until_alarm()`. Any active -//| peripherals, such as I2C, are left on. -//| -//| Deep sleep shuts down power to nearly all of the chip including the CPU and RAM. This can save -//| a more significant amount of power, but CircuitPython must start code.py from the beginning when woken -//| up. CircuitPython will enter deep sleep automatically when the current program exits without error -//| or calls `sys.exit(0)`. -//| If an error causes CircuitPython to exit, error LED error flashes will be done periodically. -//| An error includes an uncaught exception, or sys.exit called with a non-zero argumetn. -//| To set alarms for deep sleep use `sleep.restart_on_alarm()` they will apply to next deep sleep only.""" -//| - -//| wake_alarm: Alarm -//| """The most recent alarm to wake us up from a sleep (light or deep.)""" -//| - -//| reset_reason: ResetReason -//| """The reason the chip started up from reset state. This can may be power up or due to an alarm.""" -//| - -//| def sleep_until_alarm(alarm: Alarm, ...) -> Alarm: -//| """Performs a light sleep until woken by one of the alarms. The alarm that woke us up is -//| returned.""" -//| ... -//| - -STATIC mp_obj_t sleep_sleep_until_alarm(size_t n_args, const mp_obj_t *args) { -} -MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(sleep_sleep_until_alarm_obj, 1, MP_OBJ_FUN_ARGS_MAX, sleep_sleep_until_alarm); - -//| def restart_on_alarm(alarm: Alarm, ...) -> None: -//| """Set one or more alarms to wake up from a deep sleep. When awakened, ``code.py`` will restart -//| from the beginning. The last alarm to wake us up is available as `wake_alarm`. """ -//| ... -//| -STATIC mp_obj_t sleep_restart_on_alarm(size_t n_args, const mp_obj_t *args) { -} -MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(sleep_restart_on_alarm_obj, 1, MP_OBJ_FUN_ARGS_MAX, sleep_restart_on_alarm); - - -mp_map_elem_t sleep_module_globals_table[] = { - { MP_ROM_QSTR(MP_QSTR___name__), MP_ROM_QSTR(MP_QSTR_sleep) }, - - { MP_ROM_QSTR(MP_QSTR_wake_alarm), mp_const_none }, - { MP_ROM_QSTR(MP_QSTR_reset_reason), mp_const_none }, - - { MP_ROM_QSTR(MP_QSTR_sleep_until_alarm), sleep_sleep_until_alarm_obj }, - { MP_ROM_QSTR(MP_QSTR_restart_on_alarm), sleep_restart_on_alarm_obj }, -}; -STATIC MP_DEFINE_MUTABLE_DICT(sleep_module_globals, sleep_module_globals_table); - -// These are called from common hal code to set the current wake alarm. -void common_hal_sleep_set_wake_alarm(mp_obj_t alarm) { - // Equivalent of: - // sleep.wake_alarm = alarm - mp_map_elem_t *elem = - mp_map_lookup(&sleep_module_globals_table, MP_ROM_QSTR(MP_QSTR_wake_alarm), MP_MAP_LOOKUP); - if (elem) { - elem->value = alarm; - } -} - -// These are called from common hal code to set the current wake alarm. -void common_hal_sleep_set_reset_reason(mp_obj_t reset_reason) { - // Equivalent of: - // sleep.reset_reason = reset_reason - mp_map_elem_t *elem = - mp_map_lookup(&sleep_module_globals_table, MP_ROM_QSTR(MP_QSTR_reset_reason), MP_MAP_LOOKUP); - if (elem) { - elem->value = reset_reason; - } -} - -const mp_obj_module_t sleep_module = { - .base = { &mp_type_module }, - .globals = (mp_obj_dict_t*)&sleep_module_globals, -}; diff --git a/shared-bindings/sleep/__init__.h b/shared-bindings/sleep/__init__.h deleted file mode 100644 index cd23ba5e49..0000000000 --- a/shared-bindings/sleep/__init__.h +++ /dev/null @@ -1,9 +0,0 @@ -#ifndef MICROPY_INCLUDED_SHARED_BINDINGS_SLEEP___INIT___H -#define MICROPY_INCLUDED_SHARED_BINDINGS_SLEEP___INIT___H - -#include "py/obj.h" - -extern mp_obj_t common_hal_sleep_get_wake_alarm(void); -extern sleep_reset_reason_t common_hal_sleep_get_reset_reason(void); - -#endif // MICROPY_INCLUDED_SHARED_BINDINGS_SLEEPxs___INIT___H From 649c9305364f10ea1dc43179e768ec968d0b9ed5 Mon Sep 17 00:00:00 2001 From: Dan Halbert Date: Thu, 19 Nov 2020 15:43:39 -0500 Subject: [PATCH 18/34] wip --- main.c | 18 ++++--- ports/esp32s2/common-hal/alarm/pin/PinAlarm.c | 52 +++++++++++++++++++ ports/esp32s2/common-hal/alarm/pin/PinAlarm.h | 36 +++++++++++++ .../{alarm_io => alarm/pin}/__init__.c | 0 .../common-hal/alarm/time/DurationAlarm.c | 48 +++++++++++++++++ .../common-hal/alarm/time/DurationAlarm.h | 34 ++++++++++++ .../esp32s2/common-hal/alarm_time/__init__.c | 13 ----- py/circuitpy_defns.mk | 5 +- py/circuitpy_mpconfig.mk | 3 -- shared-bindings/alarm/ResetReason.c | 24 ++++++--- shared-bindings/alarm/ResetReason.h | 8 ++- shared-bindings/alarm/pin/PinAlarm.c | 12 +++-- shared-bindings/alarm/pin/PinAlarm.h | 5 ++ shared-bindings/alarm/time/DurationAlarm.h | 6 +++ supervisor/shared/rgb_led_status.c | 7 +-- supervisor/shared/rgb_led_status.h | 2 +- supervisor/shared/safe_mode.c | 9 +++- 17 files changed, 234 insertions(+), 48 deletions(-) create mode 100644 ports/esp32s2/common-hal/alarm/pin/PinAlarm.c create mode 100644 ports/esp32s2/common-hal/alarm/pin/PinAlarm.h rename ports/esp32s2/common-hal/{alarm_io => alarm/pin}/__init__.c (100%) create mode 100644 ports/esp32s2/common-hal/alarm/time/DurationAlarm.c create mode 100644 ports/esp32s2/common-hal/alarm/time/DurationAlarm.h delete mode 100644 ports/esp32s2/common-hal/alarm_time/__init__.c diff --git a/main.c b/main.c index a200b62641..251cb00a3f 100755 --- a/main.c +++ b/main.c @@ -63,6 +63,10 @@ #include "boards/board.h" +#if CIRCUITPY_ALARM +#include "shared-bindings/alarm/__init__.h" +#endif + #if CIRCUITPY_DISPLAYIO #include "shared-module/displayio/__init__.h" #endif @@ -88,10 +92,6 @@ #include "common-hal/canio/CAN.h" #endif -#if CIRCUITPY_SLEEP -#include "shared-bindings/sleep/__init__.h" -#endif - void do_str(const char *src, mp_parse_input_kind_t input_kind) { mp_lexer_t *lex = mp_lexer_new_from_str_len(MP_QSTR__lt_stdin_gt_, src, strlen(src), 0); if (lex == NULL) { @@ -320,7 +320,7 @@ bool run_code_py(safe_mode_t safe_mode) { #endif rgb_status_animation_t animation; bool ok = result->return_code != PYEXEC_EXCEPTION; - #if CIRCUITPY_SLEEP + #if CIRCUITPY_ALARM // If USB isn't enumerated then deep sleep. if (ok && !supervisor_workflow_active() && supervisor_ticks_ms64() > CIRCUITPY_USB_ENUMERATION_DELAY * 1024) { common_hal_sleep_deep_sleep(); @@ -361,7 +361,7 @@ bool run_code_py(safe_mode_t safe_mode) { #endif bool animation_done = tick_rgb_status_animation(&animation); if (animation_done && supervisor_workflow_active()) { - #if CIRCUITPY_SLEEP + #if CIRCUITPY_ALARM int64_t remaining_enumeration_wait = CIRCUITPY_USB_ENUMERATION_DELAY * 1024 - supervisor_ticks_ms64(); // If USB isn't enumerated then deep sleep after our waiting period. if (ok && remaining_enumeration_wait < 0) { @@ -423,9 +423,13 @@ void __attribute__ ((noinline)) run_boot_py(safe_mode_t safe_mode) { if (!skip_boot_output) { // Wait 1.5 seconds before opening CIRCUITPY_BOOT_OUTPUT_FILE for write, // in case power is momentary or will fail shortly due to, say a low, battery. - if (common_hal_sleep_get_reset_reason() == RESET_REASON_POWER_VALID) { +#if CIRCUITPY_ALARM + if (common_hal_sleep_get_reset_reason() == RESET_REASON_POWER_ON) { +#endif mp_hal_delay_ms(1500); +#if CIRCUITPY_ALARM } +#endif // USB isn't up, so we can write the file. filesystem_set_internal_writable_by_usb(false); diff --git a/ports/esp32s2/common-hal/alarm/pin/PinAlarm.c b/ports/esp32s2/common-hal/alarm/pin/PinAlarm.c new file mode 100644 index 0000000000..1211406665 --- /dev/null +++ b/ports/esp32s2/common-hal/alarm/pin/PinAlarm.c @@ -0,0 +1,52 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2020 @microDev1 (GitHub) + * Copyright (c) 2020 Dan Halbert for Adafruit Industries + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +#include "esp_sleep.h" + +#include "shared-bindings/alarm/time/DurationAlarm.h" + +void common_hal_alarm_pin_pin_pin_alarm_construct(alarm_pin_pin_alarm_obj_t *self, mcu_pin_obj_t *pin, bool level, bool edge, bool pull) { + self->pin = pin; + self->level = level; + self->edge = edge; + self->pull = pull; + +mcu_pin_obj_t *common_hal_alarm_pin_pin_alarm_get_pin(alarm_pin_pin_alarm_obj_t *self) { + return self->pin; +} + +bool common_hal_alarm_pin_pin_alarm_get_level(alarm_pin_pin_alarm_obj_t *self) { + return self->level; +} + +bool common_hal_alarm_pin_pin_alarm_get_edge(alarm_pin_pin_alarm_obj_t *self) { + return self->edge; +} + +bool common_hal_alarm_pin_pin_alarm_get_pull(alarm_pin_pin_alarm_obj_t *self) { + return self->pull; +} diff --git a/ports/esp32s2/common-hal/alarm/pin/PinAlarm.h b/ports/esp32s2/common-hal/alarm/pin/PinAlarm.h new file mode 100644 index 0000000000..5273918584 --- /dev/null +++ b/ports/esp32s2/common-hal/alarm/pin/PinAlarm.h @@ -0,0 +1,36 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2020 Dan Halbert for Adafruit Industries + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + + +#include "py/obj.h" + +typedef struct { + mp_obj_base_t base; + mcu_pin_obj_t *pin; + bool level; + bool edge; + bool pull; +} alarm_pin_pin_alarm_obj_t; diff --git a/ports/esp32s2/common-hal/alarm_io/__init__.c b/ports/esp32s2/common-hal/alarm/pin/__init__.c similarity index 100% rename from ports/esp32s2/common-hal/alarm_io/__init__.c rename to ports/esp32s2/common-hal/alarm/pin/__init__.c diff --git a/ports/esp32s2/common-hal/alarm/time/DurationAlarm.c b/ports/esp32s2/common-hal/alarm/time/DurationAlarm.c new file mode 100644 index 0000000000..bf1a6cc421 --- /dev/null +++ b/ports/esp32s2/common-hal/alarm/time/DurationAlarm.c @@ -0,0 +1,48 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2020 @microDev1 (GitHub) + * Copyright (c) 2020 Dan Halbert for Adafruit Industries + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +#include "esp_sleep.h" + +#include "shared-bindings/alarm/time/DurationAlarm.h" + +void common_hal_alarm_time_duration_alarm_construct(alarm_time_duration_alarm_obj_t *self, mp_float_t duration) { + self->duration = duration; +} + +mp_float_t common_hal_alarm_time_duration_alarm_get_duration(alarm_time_duration_alarm_obj_t *self) { + return self->duration; +} +void common_hal_alarm_time_duration_alarm_enable(alarm_time_duration_alarm_obj_t *self) + if (esp_sleep_enable_timer_wakeup((uint64_t) (self->duration * 1000000)) == ESP_ERR_INVALID_ARG) { + mp_raise_ValueError(translate("duration out of range")); + } +} + +void common_hal_alarm_time_duration_alarm_disable (alarm_time_duration_alarm_obj_t *self) { + (void) self; + esp_sleep_disable_wakeup_source(ESP_SLEEP_WAKEUP_TIMER); +} diff --git a/ports/esp32s2/common-hal/alarm/time/DurationAlarm.h b/ports/esp32s2/common-hal/alarm/time/DurationAlarm.h new file mode 100644 index 0000000000..3e81cbac2f --- /dev/null +++ b/ports/esp32s2/common-hal/alarm/time/DurationAlarm.h @@ -0,0 +1,34 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2020 @microDev1 (GitHub) + * Copyright (c) 2020 Dan Halbert for Adafruit Industries + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + + +#include "py/obj.h" + +typedef struct { + mp_obj_base_t base; + mp_float_t duration; // seconds +} alarm_time_duration_alarm_obj_t; diff --git a/ports/esp32s2/common-hal/alarm_time/__init__.c b/ports/esp32s2/common-hal/alarm_time/__init__.c deleted file mode 100644 index 252b6e107c..0000000000 --- a/ports/esp32s2/common-hal/alarm_time/__init__.c +++ /dev/null @@ -1,13 +0,0 @@ -#include "esp_sleep.h" - -#include "shared-bindings/alarm_time/__init__.h" - -void common_hal_alarm_time_duration (uint32_t ms) { - if (esp_sleep_enable_timer_wakeup((ms) * 1000) == ESP_ERR_INVALID_ARG) { - mp_raise_ValueError(translate("time out of range")); - } -} - -void common_hal_alarm_time_disable (void) { - esp_sleep_disable_wakeup_source(ESP_SLEEP_WAKEUP_TIMER); -} diff --git a/py/circuitpy_defns.mk b/py/circuitpy_defns.mk index dd36c9457f..dbde1a34d6 100644 --- a/py/circuitpy_defns.mk +++ b/py/circuitpy_defns.mk @@ -302,9 +302,8 @@ SRC_COMMON_HAL_ALL = \ _pew/PewPew.c \ _pew/__init__.c \ alarm/__init__.c \ - alarm/pin/__init__.c \ - alarm/time/__init__.c \ - alarm/touch/__init__.c \ + alarm/pin/PinAlarm.c \ + alarm/time/DurationAlarm.c \ analogio/AnalogIn.c \ analogio/AnalogOut.c \ analogio/__init__.c \ diff --git a/py/circuitpy_mpconfig.mk b/py/circuitpy_mpconfig.mk index 6192ee8a7a..6d555a44b4 100644 --- a/py/circuitpy_mpconfig.mk +++ b/py/circuitpy_mpconfig.mk @@ -42,9 +42,6 @@ CFLAGS += -DCIRCUITPY_AESIO=$(CIRCUITPY_AESIO) # TODO: CIRCUITPY_ALARM will gradually be added to # as many ports as possible # so make this 1 or CIRCUITPY_FULL_BUILD eventually -CIRCUITPY_SLEEPIO ?= 0 -CFLAGS += -DCIRCUITPY_SLEEPIO=$(CIRCUITPY_SLEEPIO) - CIRCUITPY_ALARM ?= 0 CFLAGS += -DCIRCUITPY_ALARM=$(CIRCUITPY_ALARM) diff --git a/shared-bindings/alarm/ResetReason.c b/shared-bindings/alarm/ResetReason.c index 456715a08e..c46b2ba8f1 100644 --- a/shared-bindings/alarm/ResetReason.c +++ b/shared-bindings/alarm/ResetReason.c @@ -28,7 +28,7 @@ #include "shared-bindings/alarm/ResetReason.h" -MAKE_ENUM_VALUE(alarm_reset_reason_type, reset_reason, POWER_VALID, RESET_REASON_POWER_VALID); +MAKE_ENUM_VALUE(alarm_reset_reason_type, reset_reason, POWER_VALID, RESET_REASON_POWER_ON); MAKE_ENUM_VALUE(alarm_reset_reason_type, reset_reason, SOFTWARE, RESET_REASON_SOFTWARE); MAKE_ENUM_VALUE(alarm_reset_reason_type, reset_reason, DEEP_SLEEP_ALARM, RESET_REASON_DEEP_SLEEP_ALARM); MAKE_ENUM_VALUE(alarm_reset_reason_type, reset_reason, EXTERNAL, RESET_REASON_EXTERNAL); @@ -36,23 +36,31 @@ MAKE_ENUM_VALUE(alarm_reset_reason_type, reset_reason, EXTERNAL, RESET_REASON_EX //| class ResetReason: //| """The reason the chip was last reset""" //| -//| POWER_VALID: object -//| """The chip was reset and started once power levels were valid.""" +//| POWER_ON: object +//| """The chip was started from power off.""" +//| +//| BROWNOUT: object +//| """The chip was reset due to voltage brownout.""" //| //| SOFTWARE: object //| """The chip was reset from software.""" //| //| DEEP_SLEEP_ALARM: object -//| """The chip was reset for deep sleep and started by an alarm.""" +//| """The chip was reset for deep sleep and restarted by an alarm.""" //| -//| EXTERNAL: object -//| """The chip was reset by an external input such as a button.""" +//| RESET_PIN: object +//| """The chip was reset by a signal on its reset pin. The pin might be connected to a reset buton.""" +//| +//| WATCHDOG: object +//| """The chip was reset by its watchdog timer.""" //| MAKE_ENUM_MAP(alarm_reset_reason) { - MAKE_ENUM_MAP_ENTRY(reset_reason, POWER_VALID), + MAKE_ENUM_MAP_ENTRY(reset_reason, POWER_ON), + MAKE_ENUM_MAP_ENTRY(reset_reason, BROWNOUT), MAKE_ENUM_MAP_ENTRY(reset_reason, SOFTWARE), MAKE_ENUM_MAP_ENTRY(reset_reason, DEEP_SLEEP_ALARM), - MAKE_ENUM_MAP_ENTRY(reset_reason, EXTERNAL), + MAKE_ENUM_MAP_ENTRY(reset_reason, RESET_PIN), + MAKE_ENUM_MAP_ENTRY(reset_reason, WATCHDOG), }; STATIC MP_DEFINE_CONST_DICT(alarm_reset_reason_locals_dict, alarm_reset_reason_locals_table); diff --git a/shared-bindings/alarm/ResetReason.h b/shared-bindings/alarm/ResetReason.h index 6fe7a4bd31..0325ba8e33 100644 --- a/shared-bindings/alarm/ResetReason.h +++ b/shared-bindings/alarm/ResetReason.h @@ -28,12 +28,16 @@ #define MICROPY_INCLUDED_SHARED_BINDINGS_ALARM__RESET_REASON__H typedef enum { - RESET_REASON_POWER_APPLIED, + RESET_REASON_POWER_ON, + RESET_REASON_BROWNOUT, RESET_REASON_SOFTWARE, RESET_REASON_DEEP_SLEEP_ALARM, - RESET_REASON_BUTTON, + RESET_REASON_RESET_PIN, + RESET_REASON_WATCHDOG, } alarm_reset_reason_t; extern const mp_obj_type_t alarm_reset_reason_type; +extern alarm_reset_reason_t common_hal_alarm_get_reset_reason(void); + #endif // MICROPY_INCLUDED_SHARED_BINDINGS_ALARM__RESET_REASON__H diff --git a/shared-bindings/alarm/pin/PinAlarm.c b/shared-bindings/alarm/pin/PinAlarm.c index 1404fa3f41..0146a3a1ad 100644 --- a/shared-bindings/alarm/pin/PinAlarm.c +++ b/shared-bindings/alarm/pin/PinAlarm.c @@ -91,10 +91,14 @@ STATIC mp_obj_t alarm_pin_pin_alarm_binary_op(mp_binary_op_t op, mp_obj_t lhs_in if (MP_OBJ_IS_TYPE(rhs_in, &alarm_pin_pin_alarm_type)) { // Pins are singletons, so we can compare them directly. return mp_obj_new_bool( - common_hal_pin_pin_alarm_get_pin(lhs_in) == common_hal_pin_pin_alarm_get_pin(rhs_in) && - common_hal_pin_pin_alarm_get_level(lhs_in) == common_hal_pin_pin_alarm_get_level(rhs_in) && - common_hal_pin_pin_alarm_get_edge(lhs_in) == common_hal_pin_pin_alarm_get_edge(rhs_in) && - common_hal_pin_pin_alarm_get_pull(lhs_in) == common_hal_pin_pin_alarm_get_pull(rhs_in)) + common_hal_alarm_pin_pin_alarm_get_pin(lhs_in) == + common_hal_alarm_pin_pin_alarm_get_pin(rhs_in) && + common_hal_alarm_pin_pin_alarm_get_level(lhs_in) == + common_hal_alarm_pin_pin_alarm_get_level(rhs_in) && + common_hal_alarm_pin_pin_alarm_get_edge(lhs_in) == + common_hal_alarm_pin_pin_alarm_get_edge(rhs_in) && + common_hal_alarm_pin_pin_alarm_get_pull(lhs_in) == + common_hal_alarm_pin_pin_alarm_get_pull(rhs_in)); } return mp_const_false; diff --git a/shared-bindings/alarm/pin/PinAlarm.h b/shared-bindings/alarm/pin/PinAlarm.h index e38c7f620c..b7c553ad5d 100644 --- a/shared-bindings/alarm/pin/PinAlarm.h +++ b/shared-bindings/alarm/pin/PinAlarm.h @@ -28,9 +28,14 @@ #define MICROPY_INCLUDED_SHARED_BINDINGS_ALARM_PIN_PIN_ALARM_H #include "py/obj.h" +#include "common-hal/microcontroller/Pin.h" extern const mp_obj_type_t alarm_pin_pin_alarm_type; extern void common_hal_alarm_pin_pin_pin_alarm_construct(alarm_pin_pin_alarm_obj_t *self, const mcu_pin_obj_t *pin, bool level, 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 bool common_hal_alarm_pin_pin_alarm_get_level(alarm_pin_pin_alarm_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_pin_alarm_get_pull(alarm_pin_pin_alarm_obj_t *self); #endif // MICROPY_INCLUDED_SHARED_BINDINGS_ALARM_PIN_PIN_ALARM_H diff --git a/shared-bindings/alarm/time/DurationAlarm.h b/shared-bindings/alarm/time/DurationAlarm.h index 1e4db6ac53..f6ab4f975c 100644 --- a/shared-bindings/alarm/time/DurationAlarm.h +++ b/shared-bindings/alarm/time/DurationAlarm.h @@ -31,4 +31,10 @@ extern const mp_obj_type_t alarm_time_duration_alarm_type; +extern void common_hal_alarm_time_duration_alarm_construct(alarm_time_duration_alarm_obj_t *self, mp_float_t duration); +extern mp_float_t common_hal_alarm_time_duration_alarm_get_duration(alarm_time_duration_alarm_obj_t *self); + +extern void common_hal_alarm_time_duration_alarm_enable(alarm_time_duration_alarm_obj_t *self); +extern void common_hal_alarm_time_duration_alarm_disable (alarm_time_duration_alarm_obj_t *self); + #endif // MICROPY_INCLUDED_SHARED_BINDINGS_ALARM_TIME_DURATION_ALARM_H diff --git a/supervisor/shared/rgb_led_status.c b/supervisor/shared/rgb_led_status.c index bff74a1f0e..c3d33ad3ea 100644 --- a/supervisor/shared/rgb_led_status.c +++ b/supervisor/shared/rgb_led_status.c @@ -367,7 +367,6 @@ void prep_rgb_status_animation(const pyexec_result_t* result, status->found_main = found_main; status->total_exception_cycle = 0; status->ok = result->return_code != PYEXEC_EXCEPTION; - status->cycles = 0; if (status->ok) { // If this isn't an exception, skip exception sorting and handling return; @@ -419,9 +418,8 @@ bool tick_rgb_status_animation(rgb_status_animation_t* status) { // All is good. Ramp ALL_DONE up and down. if (tick_diff > ALL_GOOD_CYCLE_MS) { status->pattern_start = supervisor_ticks_ms32(); - status->cycles++; new_status_color(BLACK); - return status->cycles; + return true; } uint16_t brightness = tick_diff * 255 / (ALL_GOOD_CYCLE_MS / 2); @@ -436,8 +434,7 @@ bool tick_rgb_status_animation(rgb_status_animation_t* status) { } else { if (tick_diff > status->total_exception_cycle) { status->pattern_start = supervisor_ticks_ms32(); - status->cycles++; - return; + return true; } // First flash the file color. if (tick_diff < EXCEPTION_TYPE_LENGTH_MS) { diff --git a/supervisor/shared/rgb_led_status.h b/supervisor/shared/rgb_led_status.h index e4e1981a21..84c97796a4 100644 --- a/supervisor/shared/rgb_led_status.h +++ b/supervisor/shared/rgb_led_status.h @@ -76,6 +76,6 @@ void prep_rgb_status_animation(const pyexec_result_t* result, bool found_main, safe_mode_t safe_mode, rgb_status_animation_t* status); -void tick_rgb_status_animation(rgb_status_animation_t* status); +bool tick_rgb_status_animation(rgb_status_animation_t* status); #endif // MICROPY_INCLUDED_SUPERVISOR_RGB_LED_STATUS_H diff --git a/supervisor/shared/safe_mode.c b/supervisor/shared/safe_mode.c index 905a0c408f..7630010d03 100644 --- a/supervisor/shared/safe_mode.c +++ b/supervisor/shared/safe_mode.c @@ -29,6 +29,9 @@ #include "mphalport.h" #include "shared-bindings/digitalio/DigitalInOut.h" +#if CIRCUITPY_ALARM +#include "shared-bindings/alarm/ResetReason.h" +#endif #include "supervisor/serial.h" #include "supervisor/shared/rgb_led_colors.h" @@ -52,10 +55,12 @@ safe_mode_t wait_for_safe_mode_reset(void) { current_safe_mode = safe_mode; return safe_mode; } - if (common_hal_sleep_get_reset_reason() != RESET_REASON_POWER_VALID && - common_hal_sleep_get_reset_reason() != RESET_REASON_BUTTON) { +#if CIRCUITPY_ALARM + if (common_hal_alarm_get_reset_reason() != RESET_REASON_POWER_ON && + common_hal_alarm_get_reset_reason() != RESET_REASON_RESET_PIN) { return NO_SAFE_MODE; } +#endif port_set_saved_word(SAFE_MODE_DATA_GUARD | (MANUAL_SAFE_MODE << 8)); // Wait for a while to allow for reset. temp_status_color(SAFE_MODE); From 39e1f52e28c620db65d59f16a29d5476c4868901 Mon Sep 17 00:00:00 2001 From: Dan Halbert Date: Thu, 19 Nov 2020 17:47:12 -0500 Subject: [PATCH 19/34] wip; not compiling yet --- main.c | 17 ++++-- ports/esp32s2/common-hal/alarm/__init__.c | 16 ++++++ shared-bindings/alarm/__init__.c | 17 ++++-- shared-bindings/alarm/__init__.h | 4 ++ shared-bindings/canio/BusState.c | 70 ----------------------- shared-bindings/canio/BusState.h | 33 ----------- shared-bindings/canio/__init__.c | 60 +++++++++++++++---- shared-bindings/canio/__init__.h | 6 ++ supervisor/shared/rgb_led_status.c | 1 + supervisor/shared/serial.c | 4 +- supervisor/shared/serial.h | 29 ---------- supervisor/shared/usb/usb.c | 4 +- supervisor/shared/workflow.c | 4 +- supervisor/shared/workflow.h | 2 + 14 files changed, 108 insertions(+), 159 deletions(-) delete mode 100644 shared-bindings/canio/BusState.c delete mode 100644 shared-bindings/canio/BusState.h delete mode 100644 supervisor/shared/serial.h diff --git a/main.c b/main.c index 251cb00a3f..30ceaeaa6d 100755 --- a/main.c +++ b/main.c @@ -56,6 +56,7 @@ #include "supervisor/shared/safe_mode.h" #include "supervisor/shared/status_leds.h" #include "supervisor/shared/stack.h" +#include "supervisor/shared/workflow.h" #include "supervisor/serial.h" #include "supervisor/usb.h" @@ -92,6 +93,12 @@ #include "common-hal/canio/CAN.h" #endif +// How long to wait for host to enumerate (secs). +#define CIRCUITPY_USB_ENUMERATION_DELAY 1 + +// How long to flash errors on the RGB status LED before going to sleep (secs) +#define CIRCUITPY_FLASH_ERROR_PERIOD 10 + void do_str(const char *src, mp_parse_input_kind_t input_kind) { mp_lexer_t *lex = mp_lexer_new_from_str_len(MP_QSTR__lt_stdin_gt_, src, strlen(src), 0); if (lex == NULL) { @@ -319,11 +326,11 @@ bool run_code_py(safe_mode_t safe_mode) { bool refreshed_epaper_display = false; #endif rgb_status_animation_t animation; - bool ok = result->return_code != PYEXEC_EXCEPTION; + bool ok = result.return_code != PYEXEC_EXCEPTION; #if CIRCUITPY_ALARM // If USB isn't enumerated then deep sleep. if (ok && !supervisor_workflow_active() && supervisor_ticks_ms64() > CIRCUITPY_USB_ENUMERATION_DELAY * 1024) { - common_hal_sleep_deep_sleep(); + common_hal_mcu_deep_sleep(); } #endif // Show the animation every N seconds. @@ -365,8 +372,8 @@ bool run_code_py(safe_mode_t safe_mode) { int64_t remaining_enumeration_wait = CIRCUITPY_USB_ENUMERATION_DELAY * 1024 - supervisor_ticks_ms64(); // If USB isn't enumerated then deep sleep after our waiting period. if (ok && remaining_enumeration_wait < 0) { - common_hal_sleep_deep_sleep(); - return; // Doesn't actually get here. + common_hal_mcu_deep_sleep(); + return false; // Doesn't actually get here. } #endif // Wake up every so often to flash the error code. @@ -424,7 +431,7 @@ void __attribute__ ((noinline)) run_boot_py(safe_mode_t safe_mode) { // Wait 1.5 seconds before opening CIRCUITPY_BOOT_OUTPUT_FILE for write, // in case power is momentary or will fail shortly due to, say a low, battery. #if CIRCUITPY_ALARM - if (common_hal_sleep_get_reset_reason() == RESET_REASON_POWER_ON) { + if (common_hal_alarm_get_reset_reason() == RESET_REASON_POWER_ON) { #endif mp_hal_delay_ms(1500); #if CIRCUITPY_ALARM diff --git a/ports/esp32s2/common-hal/alarm/__init__.c b/ports/esp32s2/common-hal/alarm/__init__.c index 552ad4452b..e8cb7b882e 100644 --- a/ports/esp32s2/common-hal/alarm/__init__.c +++ b/ports/esp32s2/common-hal/alarm/__init__.c @@ -35,6 +35,22 @@ void common_hal_alarm_disable_all(void) { esp_sleep_disable_wakeup_source(ESP_SLEEP_WAKEUP_ALL); } +mp_obj_t common_hal_alarm_get_reset_reason(void) { + switch (esp_sleep_get_wakeup_cause()) { + case ESP_SLEEP_WAKEUP_TIMER: + return RESET_REASON_DEEP_SLEEP_ALARM; + case ESP_SLEEP_WAKEUP_EXT0: + return RESET_REASON_DEEP_SLEEP_ALARM; + case ESP_SLEEP_WAKEUP_TOUCHPAD: + //TODO: implement TouchIO + case ESP_SLEEP_WAKEUP_UNDEFINED: + default: + return mp_const_none; + break; + } +} + + mp_obj_t common_hal_alarm_get_wake_alarm(void) { switch (esp_sleep_get_wakeup_cause()) { case ESP_SLEEP_WAKEUP_TIMER: ; diff --git a/shared-bindings/alarm/__init__.c b/shared-bindings/alarm/__init__.c index 20535e156b..ecbf7fe04f 100644 --- a/shared-bindings/alarm/__init__.c +++ b/shared-bindings/alarm/__init__.c @@ -34,11 +34,9 @@ #include "py/obj.h" #include "py/runtime.h" -#include "shared-bindings/alarm/pin/__init__.h" -#include "shared-bindings/alarm/time/__init__.h" - STATIC mp_obj_t alarm_sleep_until_alarm(size_t n_args, const mp_obj_t *args) { // TODO + return mp_const_none; } MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(alarm_sleep_until_alarm_obj, 1, MP_OBJ_FUN_ARGS_MAX, alarm_sleep_until_alarm); @@ -51,6 +49,7 @@ MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(alarm_sleep_until_alarm_obj, 1, MP_OBJ_FUN_A //| STATIC mp_obj_t alarm_restart_on_alarm(size_t n_args, const mp_obj_t *args) { // TODO + return mp_const_none; } MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(alarm_restart_on_alarm_obj, 1, MP_OBJ_FUN_ARGS_MAX, alarm_restart_on_alarm); @@ -102,7 +101,6 @@ mp_map_elem_t alarm_module_globals_table[] = { }; STATIC MP_DEFINE_MUTABLE_DICT(alarm_module_globals, alarm_module_globals_table); -// These are called from common_hal code to set the current wake alarm. void common_hal_alarm_set_wake_alarm(mp_obj_t alarm) { // Equivalent of: // alarm.wake_alarm = alarm @@ -113,7 +111,16 @@ void common_hal_alarm_set_wake_alarm(mp_obj_t alarm) { } } -// These are called from common hal code to set the current wake alarm. +alarm_reset_reason_t common_hal_alarm_get_reset_reason(void) { + mp_map_elem_t *elem = + mp_map_lookup(&alarm_module_globals_table, MP_ROM_QSTR(MP_QSTR_reset_reason), MP_MAP_LOOKUP); + if (elem) { + return elem->value; + } else { + return mp_const_none; + } +} + void common_hal_alarm_set_reset_reason(mp_obj_t reset_reason) { // Equivalent of: // alarm.reset_reason = reset_reason diff --git a/shared-bindings/alarm/__init__.h b/shared-bindings/alarm/__init__.h index ce9cc79f40..a0ee76e53b 100644 --- a/shared-bindings/alarm/__init__.h +++ b/shared-bindings/alarm/__init__.h @@ -29,7 +29,11 @@ #include "py/obj.h" +#include "shared-bindings/alarm/ResetReason.h" + extern void common_hal_alarm_set_wake_alarm(mp_obj_t alarm); + +extern alarm_reset_reason_t common_hal_alarm_get_reset_reason(void); extern void common_hal_alarm_set_reset_reason(mp_obj_t reset_reason); #endif // MICROPY_INCLUDED_SHARED_BINDINGS_ALARM___INIT___H diff --git a/shared-bindings/canio/BusState.c b/shared-bindings/canio/BusState.c deleted file mode 100644 index e0501b8d83..0000000000 --- a/shared-bindings/canio/BusState.c +++ /dev/null @@ -1,70 +0,0 @@ -/* - * This file is part of the MicroPython project, http://micropython.org/ - * - * The MIT License (MIT) - * - * Copyright (c) 2020 Jeff Epler for Adafruit Industries - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ - -#include "py/enum.h" - -#include "shared-bindings/canio/BusState.h" - -MAKE_ENUM_VALUE(canio_bus_state_type, bus_state, ERROR_ACTIVE, BUS_STATE_ERROR_ACTIVE); -MAKE_ENUM_VALUE(canio_bus_state_type, bus_state, ERROR_PASSIVE, BUS_STATE_ERROR_PASSIVE); -MAKE_ENUM_VALUE(canio_bus_state_type, bus_state, ERROR_WARNING, BUS_STATE_ERROR_WARNING); -MAKE_ENUM_VALUE(canio_bus_state_type, bus_state, BUS_OFF, BUS_STATE_OFF); - -//| class BusState: -//| """The state of the CAN bus""" -//| -//| ERROR_ACTIVE: object -//| """The bus is in the normal (active) state""" -//| -//| ERROR_WARNING: object -//| """The bus is in the normal (active) state, but a moderate number of errors have occurred recently. -//| -//| NOTE: Not all implementations may use ERROR_WARNING. Do not rely on seeing ERROR_WARNING before ERROR_PASSIVE.""" -//| -//| ERROR_PASSIVE: object -//| """The bus is in the passive state due to the number of errors that have occurred recently. -//| -//| This device will acknowledge packets it receives, but cannot transmit messages. -//| If additional errors occur, this device may progress to BUS_OFF. -//| If it successfully acknowledges other packets on the bus, it can return to ERROR_WARNING or ERROR_ACTIVE and transmit packets. -//| """ -//| -//| BUS_OFF: object -//| """The bus has turned off due to the number of errors that have -//| occurred recently. It must be restarted before it will send or receive -//| packets. This device will neither send or acknowledge packets on the bus.""" -//| -MAKE_ENUM_MAP(canio_bus_state) { - MAKE_ENUM_MAP_ENTRY(bus_state, ERROR_ACTIVE), - MAKE_ENUM_MAP_ENTRY(bus_state, ERROR_PASSIVE), - MAKE_ENUM_MAP_ENTRY(bus_state, ERROR_WARNING), - MAKE_ENUM_MAP_ENTRY(bus_state, BUS_OFF), -}; -STATIC MP_DEFINE_CONST_DICT(canio_bus_state_locals_dict, canio_bus_state_locals_table); - -MAKE_PRINTER(canio, canio_bus_state); - -MAKE_ENUM_TYPE(canio, BusState, canio_bus_state); diff --git a/shared-bindings/canio/BusState.h b/shared-bindings/canio/BusState.h deleted file mode 100644 index e24eba92c1..0000000000 --- a/shared-bindings/canio/BusState.h +++ /dev/null @@ -1,33 +0,0 @@ -/* - * This file is part of the MicroPython project, http://micropython.org/ - * - * The MIT License (MIT) - * - * Copyright (c) 2020 Jeff Epler for Adafruit Industries - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ - -#pragma once - -typedef enum { - BUS_STATE_ERROR_ACTIVE, BUS_STATE_ERROR_PASSIVE, BUS_STATE_ERROR_WARNING, BUS_STATE_OFF -} canio_bus_state_t; - -extern const mp_obj_type_t canio_bus_state_type; diff --git a/shared-bindings/canio/__init__.c b/shared-bindings/canio/__init__.c index 451a68c9eb..f29d3ab8ac 100644 --- a/shared-bindings/canio/__init__.c +++ b/shared-bindings/canio/__init__.c @@ -24,16 +24,6 @@ * THE SOFTWARE. */ -#include "py/obj.h" - -#include "shared-bindings/canio/__init__.h" - -#include "shared-bindings/canio/BusState.h" -#include "shared-bindings/canio/CAN.h" -#include "shared-bindings/canio/Match.h" -#include "shared-bindings/canio/Message.h" -#include "shared-bindings/canio/Listener.h" - //| """CAN bus access //| //| The `canio` module contains low level classes to support the CAN bus @@ -67,6 +57,56 @@ //| """ //| +#include "py/obj.h" +#include "py/enum.h" + +#include "shared-bindings/canio/__init__.h" +#include "shared-bindings/canio/CAN.h" +#include "shared-bindings/canio/Match.h" +#include "shared-bindings/canio/Message.h" +#include "shared-bindings/canio/Listener.h" + +MAKE_ENUM_VALUE(canio_bus_state_type, bus_state, ERROR_ACTIVE, BUS_STATE_ERROR_ACTIVE); +MAKE_ENUM_VALUE(canio_bus_state_type, bus_state, ERROR_PASSIVE, BUS_STATE_ERROR_PASSIVE); +MAKE_ENUM_VALUE(canio_bus_state_type, bus_state, ERROR_WARNING, BUS_STATE_ERROR_WARNING); +MAKE_ENUM_VALUE(canio_bus_state_type, bus_state, BUS_OFF, BUS_STATE_OFF); + +//| class BusState: +//| """The state of the CAN bus""" +//| +//| ERROR_ACTIVE: object +//| """The bus is in the normal (active) state""" +//| +//| ERROR_WARNING: object +//| """The bus is in the normal (active) state, but a moderate number of errors have occurred recently. +//| +//| NOTE: Not all implementations may use ERROR_WARNING. Do not rely on seeing ERROR_WARNING before ERROR_PASSIVE.""" +//| +//| ERROR_PASSIVE: object +//| """The bus is in the passive state due to the number of errors that have occurred recently. +//| +//| This device will acknowledge packets it receives, but cannot transmit messages. +//| If additional errors occur, this device may progress to BUS_OFF. +//| If it successfully acknowledges other packets on the bus, it can return to ERROR_WARNING or ERROR_ACTIVE and transmit packets. +//| """ +//| +//| BUS_OFF: object +//| """The bus has turned off due to the number of errors that have +//| occurred recently. It must be restarted before it will send or receive +//| packets. This device will neither send or acknowledge packets on the bus.""" +//| +MAKE_ENUM_MAP(canio_bus_state) { + MAKE_ENUM_MAP_ENTRY(bus_state, ERROR_ACTIVE), + MAKE_ENUM_MAP_ENTRY(bus_state, ERROR_PASSIVE), + MAKE_ENUM_MAP_ENTRY(bus_state, ERROR_WARNING), + MAKE_ENUM_MAP_ENTRY(bus_state, BUS_OFF), +}; +STATIC MP_DEFINE_CONST_DICT(canio_bus_state_locals_dict, canio_bus_state_locals_table); + +MAKE_PRINTER(canio, canio_bus_state); + +MAKE_ENUM_TYPE(canio, BusState, canio_bus_state); + STATIC const mp_rom_map_elem_t canio_module_globals_table[] = { { MP_ROM_QSTR(MP_QSTR_BusState), MP_ROM_PTR(&canio_bus_state_type) }, { MP_ROM_QSTR(MP_QSTR_CAN), MP_ROM_PTR(&canio_can_type) }, diff --git a/shared-bindings/canio/__init__.h b/shared-bindings/canio/__init__.h index 20b6638cd8..e24eba92c1 100644 --- a/shared-bindings/canio/__init__.h +++ b/shared-bindings/canio/__init__.h @@ -25,3 +25,9 @@ */ #pragma once + +typedef enum { + BUS_STATE_ERROR_ACTIVE, BUS_STATE_ERROR_PASSIVE, BUS_STATE_ERROR_WARNING, BUS_STATE_OFF +} canio_bus_state_t; + +extern const mp_obj_type_t canio_bus_state_type; diff --git a/supervisor/shared/rgb_led_status.c b/supervisor/shared/rgb_led_status.c index c3d33ad3ea..006bb1b34c 100644 --- a/supervisor/shared/rgb_led_status.c +++ b/supervisor/shared/rgb_led_status.c @@ -483,4 +483,5 @@ bool tick_rgb_status_animation(rgb_status_animation_t* status) { } } #endif + return false; // Animation is not finished. } diff --git a/supervisor/shared/serial.c b/supervisor/shared/serial.c index 7383cc2282..303f89e752 100644 --- a/supervisor/shared/serial.c +++ b/supervisor/shared/serial.c @@ -69,9 +69,7 @@ bool serial_connected(void) { #if defined(DEBUG_UART_TX) && defined(DEBUG_UART_RX) return true; #else - // True if DTR is asserted, and the USB connection is up. - // tud_cdc_get_line_state(): bit 0 is DTR, bit 1 is RTS - return (tud_cdc_get_line_state() & 1) && tud_ready(); + return tud_cdc_connected(); #endif } diff --git a/supervisor/shared/serial.h b/supervisor/shared/serial.h deleted file mode 100644 index 84f92c337c..0000000000 --- a/supervisor/shared/serial.h +++ /dev/null @@ -1,29 +0,0 @@ -/* - * This file is part of the MicroPython project, http://micropython.org/ - * - * The MIT License (MIT) - * - * Copyright (c) 2020 Scott Shawcroft for Adafruit Industries - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ - -#pragma once - -extern volatile bool _serial_connected; diff --git a/supervisor/shared/usb/usb.c b/supervisor/shared/usb/usb.c index 8a425c9907..3d76e7000a 100644 --- a/supervisor/shared/usb/usb.c +++ b/supervisor/shared/usb/usb.c @@ -31,6 +31,7 @@ #include "supervisor/port.h" #include "supervisor/serial.h" #include "supervisor/usb.h" +#include "supervisor/shared/workflow.h" #include "lib/utils/interrupt_char.h" #include "lib/mp-readline/readline.h" @@ -118,7 +119,6 @@ void tud_umount_cb(void) { // remote_wakeup_en : if host allows us to perform remote wakeup // USB Specs: Within 7ms, device must draw an average current less than 2.5 mA from bus void tud_suspend_cb(bool remote_wakeup_en) { - _serial_connected = false; _workflow_active = false; } @@ -132,8 +132,6 @@ void tud_resume_cb(void) { void tud_cdc_line_state_cb(uint8_t itf, bool dtr, bool rts) { (void) itf; // interface ID, not used - _serial_connected = dtr; - // DTR = false is counted as disconnected if ( !dtr ) { diff --git a/supervisor/shared/workflow.c b/supervisor/shared/workflow.c index adcffb319a..cd19d3aa25 100644 --- a/supervisor/shared/workflow.c +++ b/supervisor/shared/workflow.c @@ -24,9 +24,11 @@ * THE SOFTWARE. */ +#include + // Set by the shared USB code. volatile bool _workflow_active; -bool workflow_active(void) { +bool supervisor_workflow_active(void) { return _workflow_active; } diff --git a/supervisor/shared/workflow.h b/supervisor/shared/workflow.h index 4a138332a7..2968961f48 100644 --- a/supervisor/shared/workflow.h +++ b/supervisor/shared/workflow.h @@ -27,3 +27,5 @@ #pragma once extern volatile bool _workflow_active; + +extern bool supervisor_workflow_active(void); From e4c66990e27779f43f4901d431b6c61f8da85f51 Mon Sep 17 00:00:00 2001 From: Dan Halbert Date: Fri, 20 Nov 2020 23:33:39 -0500 Subject: [PATCH 20/34] compiles --- ports/esp32s2/common-hal/alarm/__init__.c | 38 +++++++++------- ports/esp32s2/common-hal/alarm/pin/PinAlarm.c | 8 ++-- ports/esp32s2/common-hal/alarm/pin/PinAlarm.h | 2 +- .../common-hal/alarm/time/DurationAlarm.c | 5 ++- py/circuitpy_defns.mk | 11 +++-- py/enum.h | 4 +- py/genlast.py | 4 +- shared-bindings/alarm/ResetReason.c | 12 ++++- shared-bindings/alarm/ResetReason.h | 8 +++- shared-bindings/alarm/__init__.c | 45 +++++++++---------- shared-bindings/alarm/pin/PinAlarm.c | 11 ++--- shared-bindings/alarm/pin/PinAlarm.h | 5 ++- shared-bindings/alarm/time/DurationAlarm.c | 15 ++++--- shared-bindings/alarm/time/DurationAlarm.h | 2 + supervisor/shared/safe_mode.c | 1 + 15 files changed, 98 insertions(+), 73 deletions(-) diff --git a/ports/esp32s2/common-hal/alarm/__init__.c b/ports/esp32s2/common-hal/alarm/__init__.c index e8cb7b882e..d2ac3981ef 100644 --- a/ports/esp32s2/common-hal/alarm/__init__.c +++ b/ports/esp32s2/common-hal/alarm/__init__.c @@ -26,8 +26,8 @@ */ #include "shared-bindings/alarm/__init__.h" -#include "shared-bindings/alarm_io/__init__.h" -#include "shared-bindings/alarm_time/__init__.h" +#include "shared-bindings/alarm/pin/PinAlarm.h" +#include "shared-bindings/alarm/time/DurationAlarm.h" #include "esp_sleep.h" @@ -35,41 +35,47 @@ void common_hal_alarm_disable_all(void) { esp_sleep_disable_wakeup_source(ESP_SLEEP_WAKEUP_ALL); } -mp_obj_t common_hal_alarm_get_reset_reason(void) { +alarm_reset_reason_t common_hal_alarm_get_reset_reason(void) { switch (esp_sleep_get_wakeup_cause()) { case ESP_SLEEP_WAKEUP_TIMER: return RESET_REASON_DEEP_SLEEP_ALARM; + case ESP_SLEEP_WAKEUP_EXT0: return RESET_REASON_DEEP_SLEEP_ALARM; + case ESP_SLEEP_WAKEUP_TOUCHPAD: //TODO: implement TouchIO case ESP_SLEEP_WAKEUP_UNDEFINED: default: - return mp_const_none; - break; + return RESET_REASON_INVALID; } } mp_obj_t common_hal_alarm_get_wake_alarm(void) { switch (esp_sleep_get_wakeup_cause()) { - case ESP_SLEEP_WAKEUP_TIMER: ; - //Wake up from timer. - alarm_time_obj_t *timer = m_new_obj(alarm_time_obj_t); - timer->base.type = &alarm_time_type; + case ESP_SLEEP_WAKEUP_TIMER: { + // Wake up from timer. + alarm_time_duration_alarm_obj_t *timer = m_new_obj(alarm_time_duration_alarm_obj_t); + timer->base.type = &alarm_time_duration_alarm_type; return timer; - case ESP_SLEEP_WAKEUP_EXT0: ; - //Wake up from GPIO - alarm_io_obj_t *ext0 = m_new_obj(alarm_io_obj_t); - ext0->base.type = &alarm_io_type; + } + + case ESP_SLEEP_WAKEUP_EXT0: { + // Wake up from GPIO + alarm_pin_pin_alarm_obj_t *ext0 = m_new_obj(alarm_pin_pin_alarm_obj_t); + ext0->base.type = &alarm_pin_pin_alarm_type; return ext0; + } + case ESP_SLEEP_WAKEUP_TOUCHPAD: - //TODO: implement TouchIO - //Wake up from touch on pad, esp_sleep_get_touchpad_wakeup_status() + // TODO: implement TouchIO + // Wake up from touch on pad, esp_sleep_get_touchpad_wakeup_status() break; + case ESP_SLEEP_WAKEUP_UNDEFINED: default: - //Not a deep sleep reset + // Not a deep sleep reset. break; } return mp_const_none; diff --git a/ports/esp32s2/common-hal/alarm/pin/PinAlarm.c b/ports/esp32s2/common-hal/alarm/pin/PinAlarm.c index 1211406665..6ac3d05f87 100644 --- a/ports/esp32s2/common-hal/alarm/pin/PinAlarm.c +++ b/ports/esp32s2/common-hal/alarm/pin/PinAlarm.c @@ -27,15 +27,17 @@ #include "esp_sleep.h" -#include "shared-bindings/alarm/time/DurationAlarm.h" +#include "shared-bindings/alarm/pin/PinAlarm.h" +#include "shared-bindings/microcontroller/Pin.h" -void common_hal_alarm_pin_pin_pin_alarm_construct(alarm_pin_pin_alarm_obj_t *self, mcu_pin_obj_t *pin, bool level, bool edge, bool pull) { +void common_hal_alarm_pin_pin_alarm_construct(alarm_pin_pin_alarm_obj_t *self, const mcu_pin_obj_t *pin, bool level, bool edge, bool pull) { self->pin = pin; self->level = level; self->edge = edge; self->pull = pull; +} -mcu_pin_obj_t *common_hal_alarm_pin_pin_alarm_get_pin(alarm_pin_pin_alarm_obj_t *self) { +const mcu_pin_obj_t *common_hal_alarm_pin_pin_alarm_get_pin(alarm_pin_pin_alarm_obj_t *self) { return self->pin; } diff --git a/ports/esp32s2/common-hal/alarm/pin/PinAlarm.h b/ports/esp32s2/common-hal/alarm/pin/PinAlarm.h index 5273918584..c6a760b96a 100644 --- a/ports/esp32s2/common-hal/alarm/pin/PinAlarm.h +++ b/ports/esp32s2/common-hal/alarm/pin/PinAlarm.h @@ -29,7 +29,7 @@ typedef struct { mp_obj_base_t base; - mcu_pin_obj_t *pin; + const mcu_pin_obj_t *pin; bool level; bool edge; bool pull; diff --git a/ports/esp32s2/common-hal/alarm/time/DurationAlarm.c b/ports/esp32s2/common-hal/alarm/time/DurationAlarm.c index bf1a6cc421..80bf4244e3 100644 --- a/ports/esp32s2/common-hal/alarm/time/DurationAlarm.c +++ b/ports/esp32s2/common-hal/alarm/time/DurationAlarm.c @@ -27,6 +27,8 @@ #include "esp_sleep.h" +#include "py/runtime.h" + #include "shared-bindings/alarm/time/DurationAlarm.h" void common_hal_alarm_time_duration_alarm_construct(alarm_time_duration_alarm_obj_t *self, mp_float_t duration) { @@ -36,7 +38,8 @@ void common_hal_alarm_time_duration_alarm_construct(alarm_time_duration_alarm_ob mp_float_t common_hal_alarm_time_duration_alarm_get_duration(alarm_time_duration_alarm_obj_t *self) { return self->duration; } -void common_hal_alarm_time_duration_alarm_enable(alarm_time_duration_alarm_obj_t *self) + +void common_hal_alarm_time_duration_alarm_enable(alarm_time_duration_alarm_obj_t *self) { if (esp_sleep_enable_timer_wakeup((uint64_t) (self->duration * 1000000)) == ESP_ERR_INVALID_ARG) { mp_raise_ValueError(translate("duration out of range")); } diff --git a/py/circuitpy_defns.mk b/py/circuitpy_defns.mk index dbde1a34d6..d788a5411c 100644 --- a/py/circuitpy_defns.mk +++ b/py/circuitpy_defns.mk @@ -359,8 +359,6 @@ SRC_COMMON_HAL_ALL = \ rtc/__init__.c \ sdioio/SDCard.c \ sdioio/__init__.c \ - sleepio/__init__.c \ - sleepio/ResetReason.c \ socketpool/__init__.c \ socketpool/SocketPool.c \ socketpool/Socket.c \ @@ -395,9 +393,10 @@ $(filter $(SRC_PATTERNS), \ _bleio/Address.c \ _bleio/Attribute.c \ _bleio/ScanEntry.c \ - canio/Match.c \ _eve/__init__.c \ + alarm/ResetReason.c \ camera/ImageFormat.c \ + canio/Match.c \ digitalio/Direction.c \ digitalio/DriveMode.c \ digitalio/Pull.c \ @@ -414,9 +413,6 @@ SRC_SHARED_MODULE_ALL = \ _bleio/Attribute.c \ _bleio/ScanEntry.c \ _bleio/ScanResults.c \ - canio/Match.c \ - canio/Message.c \ - canio/RemoteTransmissionRequest.c \ _eve/__init__.c \ _pixelbuf/PixelBuf.c \ _pixelbuf/__init__.c \ @@ -441,6 +437,9 @@ SRC_SHARED_MODULE_ALL = \ bitbangio/__init__.c \ board/__init__.c \ busio/OneWire.c \ + canio/Match.c \ + canio/Message.c \ + canio/RemoteTransmissionRequest.c \ displayio/Bitmap.c \ displayio/ColorConverter.c \ displayio/Display.c \ diff --git a/py/enum.h b/py/enum.h index 1c38ae5ae6..708678eb69 100644 --- a/py/enum.h +++ b/py/enum.h @@ -35,12 +35,12 @@ typedef struct { } cp_enum_obj_t; #define MAKE_ENUM_VALUE(type, prefix, name, value) \ - STATIC const cp_enum_obj_t prefix ## _ ## name ## _obj = { \ + const cp_enum_obj_t prefix ## _ ## name ## _obj = { \ { &type }, value, MP_QSTR_ ## name, \ } #define MAKE_ENUM_MAP(name) \ - STATIC const mp_rom_map_elem_t name ## _locals_table[] = + const mp_rom_map_elem_t name ## _locals_table[] = #define MAKE_ENUM_MAP_ENTRY(prefix, name) \ { MP_ROM_QSTR(MP_QSTR_ ## name), MP_ROM_PTR(&prefix ## _ ## name ## _obj) } diff --git a/py/genlast.py b/py/genlast.py index 1df2a24825..5b195d23e4 100644 --- a/py/genlast.py +++ b/py/genlast.py @@ -47,7 +47,9 @@ def preprocess(command, output_dir, fn): print(e, file=sys.stderr) def maybe_preprocess(command, output_dir, fn): - if subprocess.call(["grep", "-lqE", "(MP_QSTR|translate)", fn]) == 0: + # Preprocess the source file if it contains "MP_QSTR", "translate", + # or if it uses enum.h (which generates "MP_QSTR" strings. + if subprocess.call(["grep", "-lqE", r"(MP_QSTR|translate|enum\.h)", fn]) == 0: preprocess(command, output_dir, fn) if __name__ == '__main__': diff --git a/shared-bindings/alarm/ResetReason.c b/shared-bindings/alarm/ResetReason.c index c46b2ba8f1..086562fc9c 100644 --- a/shared-bindings/alarm/ResetReason.c +++ b/shared-bindings/alarm/ResetReason.c @@ -24,18 +24,25 @@ * THE SOFTWARE. */ +#include "py/obj.h" #include "py/enum.h" #include "shared-bindings/alarm/ResetReason.h" -MAKE_ENUM_VALUE(alarm_reset_reason_type, reset_reason, POWER_VALID, RESET_REASON_POWER_ON); +MAKE_ENUM_VALUE(alarm_reset_reason_type, reset_reason, INVALID, RESET_REASON_INVALID); +MAKE_ENUM_VALUE(alarm_reset_reason_type, reset_reason, POWER_ON, RESET_REASON_POWER_ON); +MAKE_ENUM_VALUE(alarm_reset_reason_type, reset_reason, BROWNOUT, RESET_REASON_BROWNOUT); MAKE_ENUM_VALUE(alarm_reset_reason_type, reset_reason, SOFTWARE, RESET_REASON_SOFTWARE); MAKE_ENUM_VALUE(alarm_reset_reason_type, reset_reason, DEEP_SLEEP_ALARM, RESET_REASON_DEEP_SLEEP_ALARM); -MAKE_ENUM_VALUE(alarm_reset_reason_type, reset_reason, EXTERNAL, RESET_REASON_EXTERNAL); +MAKE_ENUM_VALUE(alarm_reset_reason_type, reset_reason, RESET_PIN, RESET_REASON_RESET_PIN); +MAKE_ENUM_VALUE(alarm_reset_reason_type, reset_reason, WATCHDOG, RESET_REASON_WATCHDOG); //| class ResetReason: //| """The reason the chip was last reset""" //| +//| INVALID: object +//| """Invalid reason: indicates an internal error.""" +//| //| POWER_ON: object //| """The chip was started from power off.""" //| @@ -55,6 +62,7 @@ MAKE_ENUM_VALUE(alarm_reset_reason_type, reset_reason, EXTERNAL, RESET_REASON_EX //| """The chip was reset by its watchdog timer.""" //| MAKE_ENUM_MAP(alarm_reset_reason) { + MAKE_ENUM_MAP_ENTRY(reset_reason, INVALID), MAKE_ENUM_MAP_ENTRY(reset_reason, POWER_ON), MAKE_ENUM_MAP_ENTRY(reset_reason, BROWNOUT), MAKE_ENUM_MAP_ENTRY(reset_reason, SOFTWARE), diff --git a/shared-bindings/alarm/ResetReason.h b/shared-bindings/alarm/ResetReason.h index 0325ba8e33..2d6b8bc0c3 100644 --- a/shared-bindings/alarm/ResetReason.h +++ b/shared-bindings/alarm/ResetReason.h @@ -27,7 +27,11 @@ #ifndef MICROPY_INCLUDED_SHARED_BINDINGS_ALARM__RESET_REASON__H #define MICROPY_INCLUDED_SHARED_BINDINGS_ALARM__RESET_REASON__H +#include "py/obj.h" +#include "py/enum.h" + typedef enum { + RESET_REASON_INVALID, RESET_REASON_POWER_ON, RESET_REASON_BROWNOUT, RESET_REASON_SOFTWARE, @@ -36,8 +40,8 @@ typedef enum { RESET_REASON_WATCHDOG, } alarm_reset_reason_t; +extern const cp_enum_obj_t reset_reason_INVALID_obj; + extern const mp_obj_type_t alarm_reset_reason_type; -extern alarm_reset_reason_t common_hal_alarm_get_reset_reason(void); - #endif // MICROPY_INCLUDED_SHARED_BINDINGS_ALARM__RESET_REASON__H diff --git a/shared-bindings/alarm/__init__.c b/shared-bindings/alarm/__init__.c index ecbf7fe04f..771c8ff9bf 100644 --- a/shared-bindings/alarm/__init__.c +++ b/shared-bindings/alarm/__init__.c @@ -34,6 +34,11 @@ #include "py/obj.h" #include "py/runtime.h" +#include "shared-bindings/alarm/__init__.h" +#include "shared-bindings/alarm/ResetReason.h" +#include "shared-bindings/alarm/pin/PinAlarm.h" +#include "shared-bindings/alarm/time/DurationAlarm.h" + STATIC mp_obj_t alarm_sleep_until_alarm(size_t n_args, const mp_obj_t *args) { // TODO return mp_const_none; @@ -56,47 +61,47 @@ MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(alarm_restart_on_alarm_obj, 1, MP_OBJ_FUN_AR //| """The `alarm.pin` module contains alarm attributes and classes related to pins //| """ //| -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_PinAlarm), MP_ROM_PTR(&alarm_pin_pin_alarm_type) }, + { MP_ROM_QSTR(MP_QSTR_PinAlarm), MP_OBJ_FROM_PTR(&alarm_pin_pin_alarm_type) }, }; STATIC MP_DEFINE_CONST_DICT(alarm_pin_globals, alarm_pin_globals_table); -const mp_obj_module_t alarm_pin_module = { +STATIC const mp_obj_module_t alarm_pin_module = { .base = { &mp_type_module }, - .globals = (mp_obj_dict_t*)&alarm_pinn_globals, + .globals = (mp_obj_dict_t*)&alarm_pin_globals, }; //| """The `alarm.time` module contains alarm attributes and classes related to time-keeping. //| """ //| -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_DurationAlarm), MP_ROM_PTR(&alarm_time_duration_alarm_type) }, + { MP_ROM_QSTR(MP_QSTR_DurationAlarm), MP_OBJ_FROM_PTR(&alarm_time_duration_alarm_type) }, }; STATIC MP_DEFINE_CONST_DICT(alarm_time_globals, alarm_time_globals_table); -const mp_obj_module_t alarm_time_module = { +STATIC const mp_obj_module_t alarm_time_module = { .base = { &mp_type_module }, .globals = (mp_obj_dict_t*)&alarm_time_globals, }; -mp_map_elem_t alarm_module_globals_table[] = { +STATIC mp_map_elem_t alarm_module_globals_table[] = { { MP_ROM_QSTR(MP_QSTR___name__), MP_ROM_QSTR(MP_QSTR_alarm) }, // wake_alarm and reset_reason are mutable attributes. { MP_ROM_QSTR(MP_QSTR_wake_alarm), mp_const_none }, - { MP_ROM_QSTR(MP_QSTR_reset_reason), mp_const_none }, + { MP_ROM_QSTR(MP_QSTR_reset_reason), MP_OBJ_FROM_PTR(&reset_reason_INVALID_obj) }, - { MP_ROM_QSTR(MP_QSTR_sleep_until_alarm), MP_ROM_PTR(&alarm_sleep_until_alarm_obj) }, - { MP_ROM_QSTR(MP_QSTR_restart_on_alarm), MP_ROM_PTR(&alarm_restart_on_alarm_obj) }, + { MP_ROM_QSTR(MP_QSTR_sleep_until_alarm), MP_OBJ_FROM_PTR(&alarm_sleep_until_alarm_obj) }, + { MP_ROM_QSTR(MP_QSTR_restart_on_alarm), MP_OBJ_FROM_PTR(&alarm_restart_on_alarm_obj) }, - { MP_ROM_QSTR(MP_QSTR_pin), MP_ROM_PTR(&alarm_pin_module) }, - { MP_ROM_QSTR(MP_QSTR_time), MP_ROM_PTR(&alarm_time_module) } + { MP_ROM_QSTR(MP_QSTR_pin), MP_OBJ_FROM_PTR(&alarm_pin_module) }, + { MP_ROM_QSTR(MP_QSTR_time), MP_OBJ_FROM_PTR(&alarm_time_module) } }; STATIC MP_DEFINE_MUTABLE_DICT(alarm_module_globals, alarm_module_globals_table); @@ -105,27 +110,17 @@ void common_hal_alarm_set_wake_alarm(mp_obj_t alarm) { // Equivalent of: // alarm.wake_alarm = alarm mp_map_elem_t *elem = - mp_map_lookup(&alarm_module_globals_table, MP_ROM_QSTR(MP_QSTR_wake_alarm), MP_MAP_LOOKUP); + mp_map_lookup(&alarm_module_globals.map, MP_ROM_QSTR(MP_QSTR_wake_alarm), MP_MAP_LOOKUP); if (elem) { elem->value = alarm; } } -alarm_reset_reason_t common_hal_alarm_get_reset_reason(void) { - mp_map_elem_t *elem = - mp_map_lookup(&alarm_module_globals_table, MP_ROM_QSTR(MP_QSTR_reset_reason), MP_MAP_LOOKUP); - if (elem) { - return elem->value; - } else { - return mp_const_none; - } -} - void common_hal_alarm_set_reset_reason(mp_obj_t reset_reason) { // Equivalent of: // alarm.reset_reason = reset_reason mp_map_elem_t *elem = - mp_map_lookup(&alarm_module_globals_table, MP_ROM_QSTR(MP_QSTR_reset_reason), MP_MAP_LOOKUP); + mp_map_lookup(&alarm_module_globals.map, MP_ROM_QSTR(MP_QSTR_reset_reason), MP_MAP_LOOKUP); if (elem) { elem->value = reset_reason; } diff --git a/shared-bindings/alarm/pin/PinAlarm.c b/shared-bindings/alarm/pin/PinAlarm.c index 0146a3a1ad..fef1face76 100644 --- a/shared-bindings/alarm/pin/PinAlarm.c +++ b/shared-bindings/alarm/pin/PinAlarm.c @@ -27,6 +27,7 @@ #include "shared-bindings/board/__init__.h" #include "shared-bindings/microcontroller/__init__.h" #include "shared-bindings/microcontroller/Pin.h" +#include "shared-bindings/alarm/pin/PinAlarm.h" #include "py/nlr.h" #include "py/obj.h" @@ -58,8 +59,7 @@ //| """ //| ... //| -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 *args, mp_map_t *kw_args) { +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) { alarm_pin_pin_alarm_obj_t *self = m_new_obj(alarm_pin_pin_alarm_obj_t); self->base.type = &alarm_pin_pin_alarm_type; enum { ARG_pin, ARG_level, ARG_edge, ARG_pull }; @@ -74,7 +74,7 @@ STATIC mp_obj_t alarm_pin_pin_alarm_make_new(const mp_obj_type_t *type, const mcu_pin_obj_t* pin = validate_obj_is_free_pin(args[ARG_pin].u_obj); - common_hal_alarm_pin_pin_pin_alarm_construct( + common_hal_alarm_pin_pin_alarm_construct( self, pin, args[ARG_level].u_bool, args[ARG_edge].u_bool, args[ARG_pull].u_bool); return MP_OBJ_FROM_PTR(self); @@ -110,11 +110,12 @@ STATIC mp_obj_t alarm_pin_pin_alarm_binary_op(mp_binary_op_t op, mp_obj_t lhs_in STATIC const mp_rom_map_elem_t alarm_pin_pin_alarm_locals_dict_table[] = { }; -STATIC MP_DEFINE_CONST_DICT(alarm_pin_pin_alarm_locals, alarm_pin_pin_alarm_locals_dict); +STATIC MP_DEFINE_CONST_DICT(alarm_pin_pin_alarm_locals_dict, alarm_pin_pin_alarm_locals_dict_table); const mp_obj_type_t alarm_pin_pin_alarm_type = { { &mp_type_type }, .name = MP_QSTR_PinAlarm, .make_new = alarm_pin_pin_alarm_make_new, - .locals_dict = (mp_obj_t)&alarm_pin_pin_alarm_locals, + .binary_op = alarm_pin_pin_alarm_binary_op, + .locals_dict = (mp_obj_t)&alarm_pin_pin_alarm_locals_dict, }; diff --git a/shared-bindings/alarm/pin/PinAlarm.h b/shared-bindings/alarm/pin/PinAlarm.h index b7c553ad5d..978ceaad56 100644 --- a/shared-bindings/alarm/pin/PinAlarm.h +++ b/shared-bindings/alarm/pin/PinAlarm.h @@ -29,11 +29,12 @@ #include "py/obj.h" #include "common-hal/microcontroller/Pin.h" +#include "common-hal/alarm/pin/PinAlarm.h" extern const mp_obj_type_t alarm_pin_pin_alarm_type; -extern void common_hal_alarm_pin_pin_pin_alarm_construct(alarm_pin_pin_alarm_obj_t *self, const mcu_pin_obj_t *pin, bool level, 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 void common_hal_alarm_pin_pin_alarm_construct(alarm_pin_pin_alarm_obj_t *self, const mcu_pin_obj_t *pin, bool level, bool edge, bool pull); +extern const mcu_pin_obj_t *common_hal_alarm_pin_pin_alarm_get_pin(alarm_pin_pin_alarm_obj_t *self); extern bool common_hal_alarm_pin_pin_alarm_get_level(alarm_pin_pin_alarm_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_pin_alarm_get_pull(alarm_pin_pin_alarm_obj_t *self); diff --git a/shared-bindings/alarm/time/DurationAlarm.c b/shared-bindings/alarm/time/DurationAlarm.c index c30c7f326c..5fb232f4ae 100644 --- a/shared-bindings/alarm/time/DurationAlarm.c +++ b/shared-bindings/alarm/time/DurationAlarm.c @@ -26,7 +26,7 @@ #include "shared-bindings/board/__init__.h" #include "shared-bindings/microcontroller/__init__.h" -#include "shared-bindings/microcontroller/Pin.h" +#include "shared-bindings/alarm/time/DurationAlarm.h" #include "py/nlr.h" #include "py/obj.h" @@ -49,8 +49,8 @@ STATIC mp_obj_t alarm_time_duration_alarm_make_new(const mp_obj_type_t *type, mp_uint_t n_args, const mp_obj_t *args, mp_map_t *kw_args) { mp_arg_check_num(n_args, kw_args, 1, 1, false); - alarm_pin_duration_alarm_obj_t *self = m_new_obj(alarm_pin_duration_alarm_obj_t); - self->base.type = &alarm_pin_pin_alarm_type; + alarm_time_duration_alarm_obj_t *self = m_new_obj(alarm_time_duration_alarm_obj_t); + self->base.type = &alarm_time_duration_alarm_type; mp_float_t secs = mp_obj_get_float(args[0]); @@ -60,7 +60,7 @@ STATIC mp_obj_t alarm_time_duration_alarm_make_new(const mp_obj_type_t *type, } //| def __eq__(self, other: object) -> bool: -//| """Two DurationAlarm objects are equal if their durations are the same.""" +//| """Two DurationAlarm objects are equal if their durations differ by less than a millisecond.""" //| ... //| STATIC mp_obj_t alarm_time_duration_alarm_binary_op(mp_binary_op_t op, mp_obj_t lhs_in, mp_obj_t rhs_in) { @@ -68,8 +68,8 @@ STATIC mp_obj_t alarm_time_duration_alarm_binary_op(mp_binary_op_t op, mp_obj_t case MP_BINARY_OP_EQUAL: if (MP_OBJ_IS_TYPE(rhs_in, &alarm_time_duration_alarm_type)) { return mp_obj_new_bool( - common_hal_alarm_time_duration_alarm_get_duration(lhs_in) == - common_hal_alarm_time_duration_alarm_get_duration(rhs_in)); + abs(common_hal_alarm_time_duration_alarm_get_duration(lhs_in) - + common_hal_alarm_time_duration_alarm_get_duration(rhs_in)) < 0.001f); } return mp_const_false; @@ -87,5 +87,6 @@ const mp_obj_type_t alarm_time_duration_alarm_type = { { &mp_type_type }, .name = MP_QSTR_DurationAlarm, .make_new = alarm_time_duration_alarm_make_new, - .locals_dict = (mp_obj_t)&alarm_time_duration_alarm_locals, + .binary_op = alarm_time_duration_alarm_binary_op, + .locals_dict = (mp_obj_t)&alarm_time_duration_alarm_locals_dict, }; diff --git a/shared-bindings/alarm/time/DurationAlarm.h b/shared-bindings/alarm/time/DurationAlarm.h index f6ab4f975c..87f5d9390c 100644 --- a/shared-bindings/alarm/time/DurationAlarm.h +++ b/shared-bindings/alarm/time/DurationAlarm.h @@ -29,6 +29,8 @@ #include "py/obj.h" +#include "common-hal/alarm/time/DurationAlarm.h" + extern const mp_obj_type_t alarm_time_duration_alarm_type; extern void common_hal_alarm_time_duration_alarm_construct(alarm_time_duration_alarm_obj_t *self, mp_float_t duration); diff --git a/supervisor/shared/safe_mode.c b/supervisor/shared/safe_mode.c index 7630010d03..ee8af2c2ca 100644 --- a/supervisor/shared/safe_mode.c +++ b/supervisor/shared/safe_mode.c @@ -30,6 +30,7 @@ #include "shared-bindings/digitalio/DigitalInOut.h" #if CIRCUITPY_ALARM +#include "shared-bindings/alarm/__init__.h" #include "shared-bindings/alarm/ResetReason.h" #endif From 75559f35ccc946dfd292e25671919e5d5b3bd7a6 Mon Sep 17 00:00:00 2001 From: Dan Halbert Date: Sat, 21 Nov 2020 23:29:52 -0500 Subject: [PATCH 21/34] wip: ResetReason to microcontroller.cpu --- locale/circuitpython.pot | 18 ++--- main.c | 9 +-- .../common-hal/microcontroller/Processor.c | 5 ++ .../common-hal/microcontroller/__init__.c | 4 - .../common-hal/microcontroller/Processor.c | 5 ++ .../common-hal/microcontroller/__init__.c | 4 - ports/esp32s2/common-hal/alarm/__init__.c | 17 ----- .../common-hal/microcontroller/Processor.c | 23 +++++- .../common-hal/microcontroller/__init__.c | 4 - .../common-hal/microcontroller/Processor.c | 8 +- .../common-hal/microcontroller/__init__.c | 4 - .../common-hal/microcontroller/Processor.c | 5 ++ .../common-hal/microcontroller/__init__.c | 4 - .../common-hal/microcontroller/Processor.c | 8 +- .../nrf/common-hal/microcontroller/__init__.c | 4 - .../common-hal/microcontroller/Processor.c | 9 ++- .../stm/common-hal/microcontroller/__init__.c | 4 - py/circuitpy_defns.mk | 2 +- shared-bindings/_typing/__init__.pyi | 11 ++- shared-bindings/alarm/__init__.c | 74 +++++++++++-------- shared-bindings/alarm/__init__.h | 6 +- shared-bindings/alarm/pin/PinAlarm.c | 28 +++---- shared-bindings/alarm/time/DurationAlarm.c | 11 ++- shared-bindings/microcontroller/Processor.c | 18 +++++ shared-bindings/microcontroller/Processor.h | 3 +- .../{alarm => microcontroller}/ResetReason.c | 41 +++++----- .../{alarm => microcontroller}/ResetReason.h | 18 +++-- shared-bindings/microcontroller/__init__.c | 9 --- shared-bindings/microcontroller/__init__.h | 4 +- shared-bindings/supervisor/RunReason.c | 38 +++++----- shared-bindings/supervisor/RunReason.h | 4 +- shared-bindings/supervisor/Runtime.c | 10 +-- supervisor/shared/safe_mode.c | 14 ++-- 33 files changed, 220 insertions(+), 206 deletions(-) rename shared-bindings/{alarm => microcontroller}/ResetReason.c (54%) rename shared-bindings/{alarm => microcontroller}/ResetReason.h (71%) diff --git a/locale/circuitpython.pot b/locale/circuitpython.pot index 969f3f36fb..1dae9547a3 100644 --- a/locale/circuitpython.pot +++ b/locale/circuitpython.pot @@ -8,7 +8,7 @@ msgid "" msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2020-11-19 00:28-0500\n" +"POT-Creation-Date: 2020-11-21 12:36-0500\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language-Team: LANGUAGE \n" @@ -990,7 +990,7 @@ msgstr "" msgid "I2SOut not available" msgstr "" -#: ports/esp32s2/common-hal/alarm_io/__init__.c +#: ports/esp32s2/common-hal/alarm/pin/__init__.c msgid "IOs 0, 2 & 4 do not support internal pullup in sleep" msgstr "" @@ -2449,6 +2449,10 @@ msgstr "" msgid "division by zero" msgstr "" +#: ports/esp32s2/common-hal/alarm/time/DurationAlarm.c +msgid "duration out of range" +msgstr "" + #: py/objdeque.c msgid "empty" msgstr "" @@ -2809,7 +2813,7 @@ msgstr "" msgid "invalid syntax for number" msgstr "" -#: ports/esp32s2/common-hal/alarm_io/__init__.c +#: ports/esp32s2/common-hal/alarm/pin/__init__.c msgid "io must be rtc io" msgstr "" @@ -3434,10 +3438,6 @@ msgstr "" msgid "threshold must be in the range 0-65536" msgstr "" -#: ports/esp32s2/common-hal/alarm_time/__init__.c -msgid "time out of range" -msgstr "" - #: shared-bindings/time/__init__.c msgid "time.struct_time() takes a 9-sequence" msgstr "" @@ -3484,7 +3484,7 @@ msgstr "" msgid "trapz is defined for 1D arrays of equal length" msgstr "" -#: ports/esp32s2/common-hal/alarm_io/__init__.c +#: ports/esp32s2/common-hal/alarm/pin/__init__.c msgid "trigger level must be 0 or 1" msgstr "" @@ -3630,7 +3630,7 @@ msgstr "" msgid "vectors must have same lengths" msgstr "" -#: ports/esp32s2/common-hal/alarm_io/__init__.c +#: ports/esp32s2/common-hal/alarm/pin/__init__.c msgid "wakeup conflict" msgstr "" diff --git a/main.c b/main.c index 30ceaeaa6d..8938d714af 100755 --- a/main.c +++ b/main.c @@ -330,7 +330,7 @@ bool run_code_py(safe_mode_t safe_mode) { #if CIRCUITPY_ALARM // If USB isn't enumerated then deep sleep. if (ok && !supervisor_workflow_active() && supervisor_ticks_ms64() > CIRCUITPY_USB_ENUMERATION_DELAY * 1024) { - common_hal_mcu_deep_sleep(); + common_hal_alarm_restart_on_alarm(0, NULL); } #endif // Show the animation every N seconds. @@ -430,14 +430,9 @@ void __attribute__ ((noinline)) run_boot_py(safe_mode_t safe_mode) { if (!skip_boot_output) { // Wait 1.5 seconds before opening CIRCUITPY_BOOT_OUTPUT_FILE for write, // in case power is momentary or will fail shortly due to, say a low, battery. -#if CIRCUITPY_ALARM - if (common_hal_alarm_get_reset_reason() == RESET_REASON_POWER_ON) { -#endif + if (common_hal_mcu_processor_get_reset_reason() == RESET_REASON_POWER_ON) { mp_hal_delay_ms(1500); -#if CIRCUITPY_ALARM } -#endif - // USB isn't up, so we can write the file. filesystem_set_internal_writable_by_usb(false); f_open(fs, boot_output_file, CIRCUITPY_BOOT_OUTPUT_FILE, FA_WRITE | FA_CREATE_ALWAYS); diff --git a/ports/atmel-samd/common-hal/microcontroller/Processor.c b/ports/atmel-samd/common-hal/microcontroller/Processor.c index ba8daf3fb0..9955212657 100644 --- a/ports/atmel-samd/common-hal/microcontroller/Processor.c +++ b/ports/atmel-samd/common-hal/microcontroller/Processor.c @@ -65,6 +65,7 @@ #include "py/mphal.h" #include "common-hal/microcontroller/Processor.h" +#include "shared-bindings/microcontroller/ResetReason.h" #include "samd/adc.h" @@ -349,3 +350,7 @@ void common_hal_mcu_processor_get_uid(uint8_t raw_id[]) { } } } + +mcu_reset_reason_t common_hal_mcu_processor_get_reset_reason(void) { + return RESET_REASON_POWER_ON; +} diff --git a/ports/atmel-samd/common-hal/microcontroller/__init__.c b/ports/atmel-samd/common-hal/microcontroller/__init__.c index ca39f28386..50a1ec038e 100644 --- a/ports/atmel-samd/common-hal/microcontroller/__init__.c +++ b/ports/atmel-samd/common-hal/microcontroller/__init__.c @@ -84,10 +84,6 @@ void common_hal_mcu_reset(void) { reset(); } -void common_hal_mcu_deep_sleep(void) { - //deep sleep call here -} - // The singleton microcontroller.Processor object, bound to microcontroller.cpu // It currently only has properties, and no state. const mcu_processor_obj_t common_hal_mcu_processor_obj = { diff --git a/ports/cxd56/common-hal/microcontroller/Processor.c b/ports/cxd56/common-hal/microcontroller/Processor.c index 1eddbb01de..bd778e80dd 100644 --- a/ports/cxd56/common-hal/microcontroller/Processor.c +++ b/ports/cxd56/common-hal/microcontroller/Processor.c @@ -31,6 +31,7 @@ // For NAN: remove when not needed. #include #include "py/mphal.h" +#include "shared-bindings/microcontroller/ResetReason.h" uint32_t common_hal_mcu_processor_get_frequency(void) { return cxd56_get_cpu_baseclk(); @@ -47,3 +48,7 @@ float common_hal_mcu_processor_get_voltage(void) { void common_hal_mcu_processor_get_uid(uint8_t raw_id[]) { boardctl(BOARDIOC_UNIQUEID, (uintptr_t) raw_id); } + +mcu_reset_reason_t common_hal_mcu_processor_get_reset_reason(void) { + return RESET_REASON_POWER_ON; +} diff --git a/ports/cxd56/common-hal/microcontroller/__init__.c b/ports/cxd56/common-hal/microcontroller/__init__.c index 57140dec70..7aa3b839d7 100644 --- a/ports/cxd56/common-hal/microcontroller/__init__.c +++ b/ports/cxd56/common-hal/microcontroller/__init__.c @@ -81,10 +81,6 @@ void common_hal_mcu_reset(void) { boardctl(BOARDIOC_RESET, 0); } -void common_hal_mcu_deep_sleep(void) { - //deep sleep call here -} - STATIC const mp_rom_map_elem_t mcu_pin_globals_table[] = { { MP_ROM_QSTR(MP_QSTR_UART2_RXD), MP_ROM_PTR(&pin_UART2_RXD) }, { MP_ROM_QSTR(MP_QSTR_UART2_TXD), MP_ROM_PTR(&pin_UART2_TXD) }, diff --git a/ports/esp32s2/common-hal/alarm/__init__.c b/ports/esp32s2/common-hal/alarm/__init__.c index d2ac3981ef..e335345508 100644 --- a/ports/esp32s2/common-hal/alarm/__init__.c +++ b/ports/esp32s2/common-hal/alarm/__init__.c @@ -35,23 +35,6 @@ void common_hal_alarm_disable_all(void) { esp_sleep_disable_wakeup_source(ESP_SLEEP_WAKEUP_ALL); } -alarm_reset_reason_t common_hal_alarm_get_reset_reason(void) { - switch (esp_sleep_get_wakeup_cause()) { - case ESP_SLEEP_WAKEUP_TIMER: - return RESET_REASON_DEEP_SLEEP_ALARM; - - case ESP_SLEEP_WAKEUP_EXT0: - return RESET_REASON_DEEP_SLEEP_ALARM; - - case ESP_SLEEP_WAKEUP_TOUCHPAD: - //TODO: implement TouchIO - case ESP_SLEEP_WAKEUP_UNDEFINED: - default: - return RESET_REASON_INVALID; - } -} - - mp_obj_t common_hal_alarm_get_wake_alarm(void) { switch (esp_sleep_get_wakeup_cause()) { case ESP_SLEEP_WAKEUP_TIMER: { diff --git a/ports/esp32s2/common-hal/microcontroller/Processor.c b/ports/esp32s2/common-hal/microcontroller/Processor.c index b815216012..bd625dc6e2 100644 --- a/ports/esp32s2/common-hal/microcontroller/Processor.c +++ b/ports/esp32s2/common-hal/microcontroller/Processor.c @@ -28,8 +28,9 @@ #include #include -#include "common-hal/microcontroller/Processor.h" #include "py/runtime.h" + +#include "common-hal/microcontroller/Processor.h" #include "supervisor/shared/translate.h" #include "soc/efuse_reg.h" @@ -74,3 +75,23 @@ void common_hal_mcu_processor_get_uid(uint8_t raw_id[]) { *ptr-- = swap_nibbles(mac_address_part & 0xff); mac_address_part >>= 8; *ptr-- = swap_nibbles(mac_address_part & 0xff); } + +mcu_reset_reason_t common_hal_mcu_processor_get_reset_reason(void) { + switch (esp_sleep_get_wakeup_cause()) { + case ESP_SLEEP_WAKEUP_TIMER: + return RESET_REASON_DEEP_SLEEP_ALARM; + + case ESP_SLEEP_WAKEUP_EXT0: + return RESET_REASON_DEEP_SLEEP_ALARM; + + case ESP_SLEEP_WAKEUP_TOUCHPAD: + //TODO: implement TouchIO + case ESP_SLEEP_WAKEUP_UNDEFINED: + default: + return RESET_REASON_POWER_APPLIED; + } +} + +mcu_reset_reason_t common_hal_mcu_processor_get_reset_reason(void) { + return RESET_REASON_POWER_ON; +} diff --git a/ports/esp32s2/common-hal/microcontroller/__init__.c b/ports/esp32s2/common-hal/microcontroller/__init__.c index 79cb938939..3056c65655 100644 --- a/ports/esp32s2/common-hal/microcontroller/__init__.c +++ b/ports/esp32s2/common-hal/microcontroller/__init__.c @@ -79,10 +79,6 @@ void common_hal_mcu_reset(void) { while(1); } -void common_hal_mcu_deep_sleep(void) { - esp_deep_sleep_start(); -} - // The singleton microcontroller.Processor object, bound to microcontroller.cpu // It currently only has properties, and no state. const mcu_processor_obj_t common_hal_mcu_processor_obj = { diff --git a/ports/litex/common-hal/microcontroller/Processor.c b/ports/litex/common-hal/microcontroller/Processor.c index 9d2b05aade..013a7ca035 100644 --- a/ports/litex/common-hal/microcontroller/Processor.c +++ b/ports/litex/common-hal/microcontroller/Processor.c @@ -26,8 +26,10 @@ */ #include -#include "common-hal/microcontroller/Processor.h" #include "py/runtime.h" + +#include "common-hal/microcontroller/Processor.h" +#include "shared-bindings/microcontroller/ResetReason.h" #include "supervisor/shared/translate.h" #include "csr.h" @@ -62,3 +64,7 @@ void common_hal_mcu_processor_get_uid(uint8_t raw_id[]) { raw_id[13] = csr_readl(CSR_VERSION_SEED_ADDR + 8); raw_id[14] = csr_readl(CSR_VERSION_SEED_ADDR + 12); } + +mcu_reset_reason_t common_hal_mcu_processor_get_reset_reason(void) { + return RESET_REASON_POWER_ON; +} diff --git a/ports/litex/common-hal/microcontroller/__init__.c b/ports/litex/common-hal/microcontroller/__init__.c index e6f50ed5a6..3c91661144 100644 --- a/ports/litex/common-hal/microcontroller/__init__.c +++ b/ports/litex/common-hal/microcontroller/__init__.c @@ -89,10 +89,6 @@ void common_hal_mcu_reset(void) { while(1); } -void common_hal_mcu_deep_sleep(void) { - //deep sleep call here -} - // The singleton microcontroller.Processor object, bound to microcontroller.cpu // It currently only has properties, and no state. const mcu_processor_obj_t common_hal_mcu_processor_obj = { diff --git a/ports/mimxrt10xx/common-hal/microcontroller/Processor.c b/ports/mimxrt10xx/common-hal/microcontroller/Processor.c index f3a578014e..28fe67db7c 100644 --- a/ports/mimxrt10xx/common-hal/microcontroller/Processor.c +++ b/ports/mimxrt10xx/common-hal/microcontroller/Processor.c @@ -28,6 +28,7 @@ #include #include "common-hal/microcontroller/Processor.h" +#include "shared-bindings/microcontroller/ResetReason.h" #include "fsl_tempmon.h" #include "fsl_ocotp.h" @@ -70,3 +71,7 @@ void common_hal_mcu_processor_get_uid(uint8_t raw_id[]) { } OCOTP_Deinit(OCOTP); } + +mcu_reset_reason_t common_hal_mcu_processor_get_reset_reason(void) { + return RESET_REASON_POWER_ON; +} diff --git a/ports/mimxrt10xx/common-hal/microcontroller/__init__.c b/ports/mimxrt10xx/common-hal/microcontroller/__init__.c index 0329ced69b..6a8537e2da 100644 --- a/ports/mimxrt10xx/common-hal/microcontroller/__init__.c +++ b/ports/mimxrt10xx/common-hal/microcontroller/__init__.c @@ -86,10 +86,6 @@ void common_hal_mcu_reset(void) { NVIC_SystemReset(); } -void common_hal_mcu_deep_sleep(void) { - //deep sleep call here -} - // The singleton microcontroller.Processor object, bound to microcontroller.cpu // It currently only has properties, and no state. const mcu_processor_obj_t common_hal_mcu_processor_obj = { diff --git a/ports/nrf/common-hal/microcontroller/Processor.c b/ports/nrf/common-hal/microcontroller/Processor.c index 03d9c4d3f0..e2695139c5 100644 --- a/ports/nrf/common-hal/microcontroller/Processor.c +++ b/ports/nrf/common-hal/microcontroller/Processor.c @@ -24,8 +24,10 @@ * THE SOFTWARE. */ -#include "common-hal/microcontroller/Processor.h" #include "py/runtime.h" + +#include "common-hal/microcontroller/Processor.h" +#include "shared-bindings/microcontroller/ResetReason.h" #include "supervisor/shared/translate.h" #include "nrfx_saadc.h" @@ -119,3 +121,7 @@ void common_hal_mcu_processor_get_uid(uint8_t raw_id[]) { ((uint32_t*) raw_id)[i] = NRF_FICR->DEVICEID[i]; } } + +mcu_reset_reason_t common_hal_mcu_processor_get_reset_reason(void) { + return RESET_REASON_POWER_ON; +} diff --git a/ports/nrf/common-hal/microcontroller/__init__.c b/ports/nrf/common-hal/microcontroller/__init__.c index 9911896bff..06aac9409d 100644 --- a/ports/nrf/common-hal/microcontroller/__init__.c +++ b/ports/nrf/common-hal/microcontroller/__init__.c @@ -95,10 +95,6 @@ void common_hal_mcu_reset(void) { reset_cpu(); } -void common_hal_mcu_deep_sleep(void) { - //deep sleep call here -} - // The singleton microcontroller.Processor object, bound to microcontroller.cpu // It currently only has properties, and no state. const mcu_processor_obj_t common_hal_mcu_processor_obj = { diff --git a/ports/stm/common-hal/microcontroller/Processor.c b/ports/stm/common-hal/microcontroller/Processor.c index 8dc968b36a..d77d287a9e 100644 --- a/ports/stm/common-hal/microcontroller/Processor.c +++ b/ports/stm/common-hal/microcontroller/Processor.c @@ -25,9 +25,12 @@ */ #include -#include "common-hal/microcontroller/Processor.h" #include "py/runtime.h" + +#include "common-hal/microcontroller/Processor.h" +#include "shared-bindings/microcontroller/ResetReason.h" #include "supervisor/shared/translate.h" + #include STM32_HAL_H #if CPY_STM32F4 @@ -138,3 +141,7 @@ void common_hal_mcu_processor_get_uid(uint8_t raw_id[]) { } #endif } + +mcu_reset_reason_t common_hal_mcu_processor_get_reset_reason(void) { + return RESET_REASON_POWER_ON; +} diff --git a/ports/stm/common-hal/microcontroller/__init__.c b/ports/stm/common-hal/microcontroller/__init__.c index bc81b0e4f5..a827399ccb 100644 --- a/ports/stm/common-hal/microcontroller/__init__.c +++ b/ports/stm/common-hal/microcontroller/__init__.c @@ -81,10 +81,6 @@ void common_hal_mcu_reset(void) { NVIC_SystemReset(); } -void common_hal_mcu_deep_sleep(void) { - //deep sleep call here -} - // The singleton microcontroller.Processor object, bound to microcontroller.cpu // It currently only has properties, and no state. const mcu_processor_obj_t common_hal_mcu_processor_obj = { diff --git a/py/circuitpy_defns.mk b/py/circuitpy_defns.mk index d788a5411c..2731f2ae8d 100644 --- a/py/circuitpy_defns.mk +++ b/py/circuitpy_defns.mk @@ -394,7 +394,6 @@ $(filter $(SRC_PATTERNS), \ _bleio/Attribute.c \ _bleio/ScanEntry.c \ _eve/__init__.c \ - alarm/ResetReason.c \ camera/ImageFormat.c \ canio/Match.c \ digitalio/Direction.c \ @@ -402,6 +401,7 @@ $(filter $(SRC_PATTERNS), \ digitalio/Pull.c \ fontio/Glyph.c \ math/__init__.c \ + microcontroller/ResetReason.c \ microcontroller/RunMode.c \ ) diff --git a/shared-bindings/_typing/__init__.pyi b/shared-bindings/_typing/__init__.pyi index 3b3f18cb9b..02839ab477 100644 --- a/shared-bindings/_typing/__init__.pyi +++ b/shared-bindings/_typing/__init__.pyi @@ -54,13 +54,12 @@ FrameBuffer = Union[rgbmatrix.RGBMatrix] """ Alarm = Union[ - alarm_time.Time, alarm_pin.PinLevel, alarm_touch.PinTouch + alarm.pin.PinAlarm, alarm.time.DurationAlarm ] -"""Classes that implement the audiosample protocol +"""Classes that implement alarms for sleeping and asynchronous notification. - - `alarm_time.Time` - - `alarm_pin.PinLevel` - - `alarm_touch.PinTouch` + - `alarm.pin.PinAlarm` + - `alarm.time.DurationAlarm` - You can play use these alarms to wake from light or deep sleep. + You can use these alarms to wake from light or deep sleep. """ diff --git a/shared-bindings/alarm/__init__.c b/shared-bindings/alarm/__init__.c index 771c8ff9bf..9345442164 100644 --- a/shared-bindings/alarm/__init__.c +++ b/shared-bindings/alarm/__init__.c @@ -1,3 +1,37 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2020 Dan Halbert for Adafruit Industries + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +#include "py/obj.h" +#include "py/runtime.h" + +#include "shared-bindings/alarm/__init__.h" +#include "shared-bindings/alarm/ResetReason.h" +#include "shared-bindings/alarm/pin/PinAlarm.h" +#include "shared-bindings/alarm/time/DurationAlarm.h" + //| """Power-saving light and deep sleep. Alarms can be set to wake up from sleep. //| //| The `alarm` module provides sleep related functionality. There are two supported levels of @@ -11,54 +45,43 @@ //| Deep sleep shuts down power to nearly all of the chip including the CPU and RAM. This can save //| a more significant amount of power, but CircuitPython must start ``code.py`` from the beginning when woken //| up. CircuitPython will enter deep sleep automatically when the current program exits without error -//| or calls `sys.exit(0)`. +//| or calls ``sys.exit(0)``. //| If an error causes CircuitPython to exit, error LED error flashes will be done periodically. //| An error includes an uncaught exception, or sys.exit called with a non-zero argumetn. -//| To set alarms for deep sleep use `alarm.reload_on_alarm()` they will apply to next deep sleep only.""" +//| To set alarms for deep sleep use `alarm.restart_on_alarm()` they will apply to next deep sleep only.""" //| - //| wake_alarm: Alarm //| """The most recent alarm to wake us up from a sleep (light or deep.)""" //| -//| reset_reason: ResetReason -//| """The reason the chip started up from reset state. This can may be power up or due to an alarm.""" -//| - -//| def sleep(alarm: Alarm, ...) -> Alarm: +//| def sleep_until_alarm(*alarms: Alarm) -> Alarm: //| """Performs a light sleep until woken by one of the alarms. The alarm that triggers the wake //| is returned, and is also available as `alarm.wake_alarm` +//| """ //| ... //| - -#include "py/obj.h" -#include "py/runtime.h" - -#include "shared-bindings/alarm/__init__.h" -#include "shared-bindings/alarm/ResetReason.h" -#include "shared-bindings/alarm/pin/PinAlarm.h" -#include "shared-bindings/alarm/time/DurationAlarm.h" - STATIC mp_obj_t alarm_sleep_until_alarm(size_t n_args, const mp_obj_t *args) { // TODO + common_hal_alarm_sleep_until_alarm(size_t n_args, const mp_obj_t *args); return mp_const_none; } MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(alarm_sleep_until_alarm_obj, 1, MP_OBJ_FUN_ARGS_MAX, alarm_sleep_until_alarm); -//| def restart_on_alarm(alarm: Alarm, ...) -> None: +//| def restart_on_alarm(*alarms: Alarm) -> None: //| """Set one or more alarms to wake up from a deep sleep. //| When awakened, ``code.py`` will restart from the beginning. -//| The last alarm to wake us up is available as `wake_alarm`. +//| The last alarm to wake us up is available as `alarm.wake_alarm`. //| """ //| ... //| STATIC mp_obj_t alarm_restart_on_alarm(size_t n_args, const mp_obj_t *args) { // TODO + common_hal_alarm_restart_on_alarm(size_t n_args, const mp_obj_t *args); return mp_const_none; } MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(alarm_restart_on_alarm_obj, 1, MP_OBJ_FUN_ARGS_MAX, alarm_restart_on_alarm); -//| """The `alarm.pin` module contains alarm attributes and classes related to pins +//| """The `alarm.pin` module contains alarm attributes and classes related to pins. //| """ //| STATIC const mp_map_elem_t alarm_pin_globals_table[] = { @@ -95,7 +118,6 @@ STATIC mp_map_elem_t alarm_module_globals_table[] = { // wake_alarm and reset_reason are mutable attributes. { MP_ROM_QSTR(MP_QSTR_wake_alarm), mp_const_none }, - { MP_ROM_QSTR(MP_QSTR_reset_reason), MP_OBJ_FROM_PTR(&reset_reason_INVALID_obj) }, { MP_ROM_QSTR(MP_QSTR_sleep_until_alarm), MP_OBJ_FROM_PTR(&alarm_sleep_until_alarm_obj) }, { MP_ROM_QSTR(MP_QSTR_restart_on_alarm), MP_OBJ_FROM_PTR(&alarm_restart_on_alarm_obj) }, @@ -116,16 +138,6 @@ void common_hal_alarm_set_wake_alarm(mp_obj_t alarm) { } } -void common_hal_alarm_set_reset_reason(mp_obj_t reset_reason) { - // Equivalent of: - // alarm.reset_reason = reset_reason - mp_map_elem_t *elem = - mp_map_lookup(&alarm_module_globals.map, MP_ROM_QSTR(MP_QSTR_reset_reason), MP_MAP_LOOKUP); - if (elem) { - elem->value = reset_reason; - } -} - const mp_obj_module_t alarm_module = { .base = { &mp_type_module }, .globals = (mp_obj_dict_t*)&alarm_module_globals, diff --git a/shared-bindings/alarm/__init__.h b/shared-bindings/alarm/__init__.h index a0ee76e53b..29be8716c5 100644 --- a/shared-bindings/alarm/__init__.h +++ b/shared-bindings/alarm/__init__.h @@ -29,11 +29,9 @@ #include "py/obj.h" -#include "shared-bindings/alarm/ResetReason.h" - extern void common_hal_alarm_set_wake_alarm(mp_obj_t alarm); -extern alarm_reset_reason_t common_hal_alarm_get_reset_reason(void); -extern void common_hal_alarm_set_reset_reason(mp_obj_t reset_reason); +extern mp_obj_t common_hal_alarm_restart_on_alarm(size_t n_alarms, const mp_obj_t *alarms); +extern mp_obj_t alarm_sleep_until_alarm(size_t n_alarms, const mp_obj_t *alarms); #endif // MICROPY_INCLUDED_SHARED_BINDINGS_ALARM___INIT___H diff --git a/shared-bindings/alarm/pin/PinAlarm.c b/shared-bindings/alarm/pin/PinAlarm.c index fef1face76..835a5be5ce 100644 --- a/shared-bindings/alarm/pin/PinAlarm.c +++ b/shared-bindings/alarm/pin/PinAlarm.c @@ -35,27 +35,27 @@ #include "supervisor/shared/translate.h" //| class PinAlarm: -//| """Trigger an alarm when a pin changes state. +//| """Trigger an alarm when a pin changes state.""" //| //| def __init__(self, pin: microcontroller.Pin, level: bool, *, edge: bool = False, pull: bool = False) -> None: //| """Create an alarm triggered by a `~microcontroller.Pin` level. The alarm is not active -//| until it is listed in an `alarm`-enabling function, such as `alarm.sleep()` or -//| `alarm.wake_after_exit()`. - +//| until it is listed in an `alarm`-enabling function, such as `alarm.sleep_until_alarm()` or +//| `alarm.restart_on_alarm()`. +//| //| :param ~microcontroller.Pin pin: The pin to monitor. On some ports, the choice of pin -//| may be limited due to hardware restrictions, particularly for deep-sleep alarms. +//| may be limited due to hardware restrictions, particularly for deep-sleep alarms. //| :param bool level: When active, trigger when the level is high (``True``) or low (``False``). -//| On some ports, multiple `PinAlarm` objects may need to have coordinated levels -//| for deep-sleep alarms +//| On some ports, multiple `PinAlarm` objects may need to have coordinated levels +//| for deep-sleep alarms. //| :param bool edge: If ``True``, trigger only when there is a transition to the specified -//| value of `level`. If ``True``, if the alarm becomes active when the pin level already -//| matches `level`, the alarm is not triggered: the pin must transition from ``not level`` -//| to ``level`` to trigger the alarm. On some ports, edge-triggering may not be available, -//| particularly for deep-sleep alarms. +//| value of `level`. If ``True``, if the alarm becomes active when the pin level already +//| matches `level`, the alarm is not triggered: the pin must transition from ``not level`` +//| to ``level`` to trigger the alarm. On some ports, edge-triggering may not be available, +//| particularly for deep-sleep alarms. //| :param bool pull: Enable a pull-up or pull-down which pulls the pin to level opposite -//| opposite that of `level`. For instance, if `level` is set to ``True``, setting `pull` -//| to ``True`` will enable a pull-down, to hold the pin low normally until an outside signal -//| pulls it high. +//| opposite that of `level`. For instance, if `level` is set to ``True``, setting `pull` +//| to ``True`` will enable a pull-down, to hold the pin low normally until an outside signal +//| pulls it high. //| """ //| ... //| diff --git a/shared-bindings/alarm/time/DurationAlarm.c b/shared-bindings/alarm/time/DurationAlarm.c index 5fb232f4ae..c105bbebf7 100644 --- a/shared-bindings/alarm/time/DurationAlarm.c +++ b/shared-bindings/alarm/time/DurationAlarm.c @@ -34,14 +34,13 @@ #include "supervisor/shared/translate.h" //| class DurationAlarm: -//| """Trigger an alarm at a specified interval from now. +//| """Trigger an alarm at a specified interval from now.""" //| //| def __init__(self, secs: float) -> None: -//| """Create an alarm that will be triggered in `secs` seconds **from the time -//| the alarm is created**. The alarm is not active until it is listed in an -//| `alarm`-enabling function, such as `alarm.sleep()` or -//| `alarm.wake_after_exit()`. But the interval starts immediately upon -//| instantiation. +//| """Create an alarm that will be triggered in `secs` seconds from the time +//| sleep starts. The alarm is not active until it is listed in an +//| `alarm`-enabling function, such as `alarm.sleep_until_alarm()` or +//| `alarm.restart_on_alarm()`. //| """ //| ... //| diff --git a/shared-bindings/microcontroller/Processor.c b/shared-bindings/microcontroller/Processor.c index 8c703891d7..b0ab842f4c 100644 --- a/shared-bindings/microcontroller/Processor.c +++ b/shared-bindings/microcontroller/Processor.c @@ -67,6 +67,23 @@ const mp_obj_property_t mcu_processor_frequency_obj = { }, }; +//| reset_reason: `microcontroller.ResetReason` +//| """The reason the microcontroller started up from reset state.""" +//| +STATIC mp_obj_t mcu_processor_get_reset_reason(mp_obj_t self) { + return cp_enum_find(&mcu_reset_reason_type, common_hal_mcu_processor_get_reset_reason()); +} + +MP_DEFINE_CONST_FUN_OBJ_1(mcu_processor_get_reset_reason_obj, mcu_processor_get_reset_reason); + +const mp_obj_property_t mcu_reset_reason_obj = { + .base.type = &mp_type_property, + .proxy = {(mp_obj_t)&mcu_processor_get_reason_reason_obj, // getter + (mp_obj_t)&mp_const_none_obj, // no setter + (mp_obj_t)&mp_const_none_obj, // no deleter + }, +}; + //| temperature: Optional[float] //| """The on-chip temperature, in Celsius, as a float. (read-only) //| @@ -128,6 +145,7 @@ const mp_obj_property_t mcu_processor_voltage_obj = { STATIC const mp_rom_map_elem_t mcu_processor_locals_dict_table[] = { { MP_ROM_QSTR(MP_QSTR_frequency), MP_ROM_PTR(&mcu_processor_frequency_obj) }, + { MP_ROM_QSTR(MP_QSTR_reset_reason), MP_ROM_PTR(&mcu_processor_reset_reason_obj) }, { MP_ROM_QSTR(MP_QSTR_temperature), MP_ROM_PTR(&mcu_processor_temperature_obj) }, { MP_ROM_QSTR(MP_QSTR_uid), MP_ROM_PTR(&mcu_processor_uid_obj) }, { MP_ROM_QSTR(MP_QSTR_voltage), MP_ROM_PTR(&mcu_processor_voltage_obj) }, diff --git a/shared-bindings/microcontroller/Processor.h b/shared-bindings/microcontroller/Processor.h index 0f520f940c..a842e06f32 100644 --- a/shared-bindings/microcontroller/Processor.h +++ b/shared-bindings/microcontroller/Processor.h @@ -29,11 +29,12 @@ #include "py/obj.h" -#include "common-hal/microcontroller/Processor.h" +#include "shared-bindings/microcontroller/ResetReason.h" extern const mp_obj_type_t mcu_processor_type; uint32_t common_hal_mcu_processor_get_frequency(void); +mcu_reset_reason_t common_hal_mcu_processor_get_reset_reason(void); float common_hal_mcu_processor_get_temperature(void); void common_hal_mcu_processor_get_uid(uint8_t raw_id[]); float common_hal_mcu_processor_get_voltage(void); diff --git a/shared-bindings/alarm/ResetReason.c b/shared-bindings/microcontroller/ResetReason.c similarity index 54% rename from shared-bindings/alarm/ResetReason.c rename to shared-bindings/microcontroller/ResetReason.c index 086562fc9c..151fcf3159 100644 --- a/shared-bindings/alarm/ResetReason.c +++ b/shared-bindings/microcontroller/ResetReason.c @@ -27,42 +27,37 @@ #include "py/obj.h" #include "py/enum.h" -#include "shared-bindings/alarm/ResetReason.h" +#include "shared-bindings/microcontroller/ResetReason.h" -MAKE_ENUM_VALUE(alarm_reset_reason_type, reset_reason, INVALID, RESET_REASON_INVALID); -MAKE_ENUM_VALUE(alarm_reset_reason_type, reset_reason, POWER_ON, RESET_REASON_POWER_ON); -MAKE_ENUM_VALUE(alarm_reset_reason_type, reset_reason, BROWNOUT, RESET_REASON_BROWNOUT); -MAKE_ENUM_VALUE(alarm_reset_reason_type, reset_reason, SOFTWARE, RESET_REASON_SOFTWARE); -MAKE_ENUM_VALUE(alarm_reset_reason_type, reset_reason, DEEP_SLEEP_ALARM, RESET_REASON_DEEP_SLEEP_ALARM); -MAKE_ENUM_VALUE(alarm_reset_reason_type, reset_reason, RESET_PIN, RESET_REASON_RESET_PIN); -MAKE_ENUM_VALUE(alarm_reset_reason_type, reset_reason, WATCHDOG, RESET_REASON_WATCHDOG); +MAKE_ENUM_VALUE(mcu_reset_reason_type, reset_reason, POWER_ON, RESET_REASON_POWER_ON); +MAKE_ENUM_VALUE(mcu_reset_reason_type, reset_reason, BROWNOUT, RESET_REASON_BROWNOUT); +MAKE_ENUM_VALUE(mcu_reset_reason_type, reset_reason, SOFTWARE, RESET_REASON_SOFTWARE); +MAKE_ENUM_VALUE(mcu_reset_reason_type, reset_reason, DEEP_SLEEP_ALARM, RESET_REASON_DEEP_SLEEP_ALARM); +MAKE_ENUM_VALUE(mcu_reset_reason_type, reset_reason, RESET_PIN, RESET_REASON_RESET_PIN); +MAKE_ENUM_VALUE(mcu_reset_reason_type, reset_reason, WATCHDOG, RESET_REASON_WATCHDOG); //| class ResetReason: -//| """The reason the chip was last reset""" -//| -//| INVALID: object -//| """Invalid reason: indicates an internal error.""" +//| """The reason the microntroller was last reset""" //| //| POWER_ON: object -//| """The chip was started from power off.""" +//| """The microntroller was started from power off.""" //| //| BROWNOUT: object -//| """The chip was reset due to voltage brownout.""" +//| """The microntroller was reset due to too low a voltage.""" //| //| SOFTWARE: object -//| """The chip was reset from software.""" +//| """The microntroller was reset from software.""" //| //| DEEP_SLEEP_ALARM: object -//| """The chip was reset for deep sleep and restarted by an alarm.""" +//| """The microntroller was reset for deep sleep and restarted by an alarm.""" //| //| RESET_PIN: object -//| """The chip was reset by a signal on its reset pin. The pin might be connected to a reset buton.""" +//| """The microntroller was reset by a signal on its reset pin. The pin might be connected to a reset button.""" //| //| WATCHDOG: object -//| """The chip was reset by its watchdog timer.""" +//| """The chip microcontroller reset by its watchdog timer.""" //| -MAKE_ENUM_MAP(alarm_reset_reason) { - MAKE_ENUM_MAP_ENTRY(reset_reason, INVALID), +MAKE_ENUM_MAP(mcu_reset_reason) { MAKE_ENUM_MAP_ENTRY(reset_reason, POWER_ON), MAKE_ENUM_MAP_ENTRY(reset_reason, BROWNOUT), MAKE_ENUM_MAP_ENTRY(reset_reason, SOFTWARE), @@ -70,8 +65,8 @@ MAKE_ENUM_MAP(alarm_reset_reason) { MAKE_ENUM_MAP_ENTRY(reset_reason, RESET_PIN), MAKE_ENUM_MAP_ENTRY(reset_reason, WATCHDOG), }; -STATIC MP_DEFINE_CONST_DICT(alarm_reset_reason_locals_dict, alarm_reset_reason_locals_table); +STATIC MP_DEFINE_CONST_DICT(mcu_reset_reason_locals_dict, mcu_reset_reason_locals_table); -MAKE_PRINTER(alarm, alarm_reset_reason); +MAKE_PRINTER(alarm, mcu_reset_reason); -MAKE_ENUM_TYPE(alarm, ResetReason, alarm_reset_reason); +MAKE_ENUM_TYPE(alarm, ResetReason, mcu_reset_reason); diff --git a/shared-bindings/alarm/ResetReason.h b/shared-bindings/microcontroller/ResetReason.h similarity index 71% rename from shared-bindings/alarm/ResetReason.h rename to shared-bindings/microcontroller/ResetReason.h index 2d6b8bc0c3..df1abf266e 100644 --- a/shared-bindings/alarm/ResetReason.h +++ b/shared-bindings/microcontroller/ResetReason.h @@ -24,24 +24,28 @@ * THE SOFTWARE. */ -#ifndef MICROPY_INCLUDED_SHARED_BINDINGS_ALARM__RESET_REASON__H -#define MICROPY_INCLUDED_SHARED_BINDINGS_ALARM__RESET_REASON__H +#ifndef MICROPY_INCLUDED_SHARED_BINDINGS_MCU__RESET_REASON__H +#define MICROPY_INCLUDED_SHARED_BINDINGS_MCU__RESET_REASON__H #include "py/obj.h" #include "py/enum.h" typedef enum { - RESET_REASON_INVALID, RESET_REASON_POWER_ON, RESET_REASON_BROWNOUT, RESET_REASON_SOFTWARE, RESET_REASON_DEEP_SLEEP_ALARM, RESET_REASON_RESET_PIN, RESET_REASON_WATCHDOG, -} alarm_reset_reason_t; +} mcu_reset_reason_t; -extern const cp_enum_obj_t reset_reason_INVALID_obj; +extern const cp_enum_obj_t reset_reason_POWER_ON_obj; +extern const cp_enum_obj_t reset_reason_BROWNOUT_obj; +extern const cp_enum_obj_t reset_reason_SOFTWARE_obj; +extern const cp_enum_obj_t reset_reason_DEEP_SLEEP_ALARM_obj; +extern const cp_enum_obj_t reset_reason_RESET_PIN_obj; +extern const cp_enum_obj_t reset_reason_WATCHDOG_obj; -extern const mp_obj_type_t alarm_reset_reason_type; +extern const mp_obj_type_t mcu_reset_reason_type; -#endif // MICROPY_INCLUDED_SHARED_BINDINGS_ALARM__RESET_REASON__H +#endif // MICROPY_INCLUDED_SHARED_BINDINGS_MCU__RESET_REASON__H diff --git a/shared-bindings/microcontroller/__init__.c b/shared-bindings/microcontroller/__init__.c index bfeb812d67..d09cf8f445 100644 --- a/shared-bindings/microcontroller/__init__.c +++ b/shared-bindings/microcontroller/__init__.c @@ -135,13 +135,6 @@ STATIC mp_obj_t mcu_reset(void) { } STATIC MP_DEFINE_CONST_FUN_OBJ_0(mcu_reset_obj, mcu_reset); -STATIC mp_obj_t mcu_sleep(void) { - common_hal_mcu_deep_sleep(); - // We won't actually get here because mcu is going into sleep. - return mp_const_none; -} -STATIC MP_DEFINE_CONST_FUN_OBJ_0(mcu_sleep_obj, mcu_sleep); - //| nvm: Optional[ByteArray] //| """Available non-volatile memory. //| This object is the sole instance of `nvm.ByteArray` when available or ``None`` otherwise. @@ -176,8 +169,6 @@ STATIC const mp_rom_map_elem_t mcu_module_globals_table[] = { { MP_ROM_QSTR(MP_QSTR_enable_interrupts), MP_ROM_PTR(&mcu_enable_interrupts_obj) }, { MP_ROM_QSTR(MP_QSTR_on_next_reset), MP_ROM_PTR(&mcu_on_next_reset_obj) }, { MP_ROM_QSTR(MP_QSTR_reset), MP_ROM_PTR(&mcu_reset_obj) }, - //ToDo: Remove MP_QSTR_sleep when sleep on code.py exit implemented. - { MP_ROM_QSTR(MP_QSTR_sleep), MP_ROM_PTR(&mcu_sleep_obj) }, #if CIRCUITPY_INTERNAL_NVM_SIZE > 0 { MP_ROM_QSTR(MP_QSTR_nvm), MP_ROM_PTR(&common_hal_mcu_nvm_obj) }, #else diff --git a/shared-bindings/microcontroller/__init__.h b/shared-bindings/microcontroller/__init__.h index f5bcfaa08a..ac71de4247 100644 --- a/shared-bindings/microcontroller/__init__.h +++ b/shared-bindings/microcontroller/__init__.h @@ -32,7 +32,7 @@ #include "py/mpconfig.h" #include "common-hal/microcontroller/Processor.h" - +#include "shared-bindings/microcontroller/ResetReason.h" #include "shared-bindings/microcontroller/RunMode.h" extern void common_hal_mcu_delay_us(uint32_t); @@ -43,8 +43,6 @@ extern void common_hal_mcu_enable_interrupts(void); extern void common_hal_mcu_on_next_reset(mcu_runmode_t runmode); extern void common_hal_mcu_reset(void); -extern void common_hal_mcu_deep_sleep(void); - extern const mp_obj_dict_t mcu_pin_globals; extern const mcu_processor_obj_t common_hal_mcu_processor_obj; diff --git a/shared-bindings/supervisor/RunReason.c b/shared-bindings/supervisor/RunReason.c index 5233cf959b..ee08f6d71b 100644 --- a/shared-bindings/supervisor/RunReason.c +++ b/shared-bindings/supervisor/RunReason.c @@ -28,35 +28,35 @@ #include "shared-bindings/supervisor/RunReason.h" -MAKE_ENUM_VALUE(canio_bus_state_type, run_reason, ERROR_ACTIVE, RUN_REASON_STARTUP); -MAKE_ENUM_VALUE(canio_bus_state_type, bus_state, ERROR_PASSIVE, RUN_REASON_AUTORELOAD); -MAKE_ENUM_VALUE(canio_bus_state_type, bus_state, ERROR_WARNING, RUN_REASON_SUPERVISOR_RELOAD); -MAKE_ENUM_VALUE(canio_bus_state_type, bus_state, BUS_OFF, RUN_REASON_RELOAD_HOTKEY); +MAKE_ENUM_VALUE(supervisor_run_reason_type, run_reason, STARTUP, RUN_REASON_STARTUP); +MAKE_ENUM_VALUE(supervisor_run_reason_type, run_reason, AUTORELOAD, RUN_REASON_AUTORELOAD); +MAKE_ENUM_VALUE(supervisor_run_reason_type, run_reason, SUPERVISOR_RELOAD, RUN_REASON_SUPERVISOR_RELOAD); +MAKE_ENUM_VALUE(supervisor_run_reason_type, run_reason, REPL_RELOAD, RUN_REASON_REPL_RELOAD); //| class RunReason: -//| """The state of the CAN bus""" +//| """The reason that CircuitPython started running.""" //| //| STARTUP: object -//| """The first VM was run after the microcontroller started up. See `microcontroller.start_reason` -//| for more detail why the microcontroller was started.""" +//| """CircuitPython started the microcontroller started up. See `microcontroller.cpu.reset_reason` +//| for more detail on why the microcontroller was started.""" //| //| AUTORELOAD: object -//| """The VM was run due to a USB write to the filesystem.""" +//| """CircuitPython restarted due to a USB write to the filesystem.""" //| //| SUPERVISOR_RELOAD: object -//| """The VM was run due to a call to `supervisor.reload()`.""" +//| """CircuitPython restarted due to a call to `supervisor.reload()`.""" //| -//| RELOAD_HOTKEY: object -//| """The VM was run due CTRL-D.""" +//| REPL_RELOAD: object +//| """CircuitPython started due to the user typing CTRL-D in the REPL.""" //| -MAKE_ENUM_MAP(canio_bus_state) { - MAKE_ENUM_MAP_ENTRY(bus_state, ERROR_ACTIVE), - MAKE_ENUM_MAP_ENTRY(bus_state, ERROR_PASSIVE), - MAKE_ENUM_MAP_ENTRY(bus_state, ERROR_WARNING), - MAKE_ENUM_MAP_ENTRY(bus_state, BUS_OFF), +MAKE_ENUM_MAP(run_reason) { + MAKE_ENUM_MAP_ENTRY(run_reason, STARTUP), + MAKE_ENUM_MAP_ENTRY(run_reason, AUTORELOAD), + MAKE_ENUM_MAP_ENTRY(run_reason, SUPERVISOR_RELOAD), + MAKE_ENUM_MAP_ENTRY(run_reason, REPL_RELOAD), }; -STATIC MP_DEFINE_CONST_DICT(canio_bus_state_locals_dict, canio_bus_state_locals_table); +STATIC MP_DEFINE_CONST_DICT(supervisor_run_reason_locals_dict, supervisor_run_reason_locals_table); -MAKE_PRINTER(canio, canio_bus_state); +MAKE_PRINTER(supervisor, supervisor_run_reason); -MAKE_ENUM_TYPE(canio, BusState, canio_bus_state); +MAKE_ENUM_TYPE(supervisor, RunReason, supervisor_run_reason); diff --git a/shared-bindings/supervisor/RunReason.h b/shared-bindings/supervisor/RunReason.h index f9aaacae63..934c72fd8c 100644 --- a/shared-bindings/supervisor/RunReason.h +++ b/shared-bindings/supervisor/RunReason.h @@ -30,7 +30,7 @@ typedef enum { RUN_REASON_STARTUP, RUN_REASON_AUTORELOAD, RUN_REASON_SUPERVISOR_RELOAD, - RUN_REASON_RELOAD_HOTKEY + RUN_REASON_REPL_RELOAD, } supervisor_run_reason_t; -extern const mp_obj_type_t canio_bus_state_type; +extern const mp_obj_type_t supervisor_run_reason_type; diff --git a/shared-bindings/supervisor/Runtime.c b/shared-bindings/supervisor/Runtime.c index f9db38c9b5..6500dadd59 100755 --- a/shared-bindings/supervisor/Runtime.c +++ b/shared-bindings/supervisor/Runtime.c @@ -91,15 +91,11 @@ const mp_obj_property_t supervisor_serial_bytes_available_obj = { //| run_reason: RunReason -//| """Returns why the Python VM was run this time.""" +//| """Returns why CircuitPython started running this particular time. //| STATIC mp_obj_t supervisor_get_run_reason(mp_obj_t self) { - if (!common_hal_get_serial_bytes_available()) { - return mp_const_false; - } - else { - return mp_const_true; - } + mp_raise_NotImplementedError(NULL); + return mp_const_none; } MP_DEFINE_CONST_FUN_OBJ_1(supervisor_get_run_reason_obj, supervisor_get_run_reason); diff --git a/supervisor/shared/safe_mode.c b/supervisor/shared/safe_mode.c index ee8af2c2ca..9032e40451 100644 --- a/supervisor/shared/safe_mode.c +++ b/supervisor/shared/safe_mode.c @@ -29,10 +29,8 @@ #include "mphalport.h" #include "shared-bindings/digitalio/DigitalInOut.h" -#if CIRCUITPY_ALARM -#include "shared-bindings/alarm/__init__.h" -#include "shared-bindings/alarm/ResetReason.h" -#endif +#include "shared-bindings/microcontroller/Processor.h" +#include "shared-bindings/microcontroller/ResetReason.h" #include "supervisor/serial.h" #include "supervisor/shared/rgb_led_colors.h" @@ -56,12 +54,12 @@ safe_mode_t wait_for_safe_mode_reset(void) { current_safe_mode = safe_mode; return safe_mode; } -#if CIRCUITPY_ALARM - if (common_hal_alarm_get_reset_reason() != RESET_REASON_POWER_ON && - common_hal_alarm_get_reset_reason() != RESET_REASON_RESET_PIN) { + + const mcu_reset_reason_t reset_reason = common_hal_mcu_processor_get_reset_reason(); + if (reset_reason != RESET_REASON_POWER_ON && + reset_reason != RESET_REASON_RESET_PIN) { return NO_SAFE_MODE; } -#endif port_set_saved_word(SAFE_MODE_DATA_GUARD | (MANUAL_SAFE_MODE << 8)); // Wait for a while to allow for reset. temp_status_color(SAFE_MODE); From a0f1ec3c4a3dd52b11752e10d0dd31202e9c705f Mon Sep 17 00:00:00 2001 From: Dan Halbert Date: Sun, 22 Nov 2020 19:10:09 -0500 Subject: [PATCH 22/34] wip --- main.c | 16 +++-- .../common-hal/microcontroller/__init__.c | 4 ++ .../common-hal/microcontroller/__init__.c | 4 ++ ports/esp32s2/common-hal/alarm/__init__.c | 43 ++++++++++++ ports/esp32s2/common-hal/alarm/pin/PinAlarm.c | 19 ++++-- ports/esp32s2/common-hal/alarm/pin/PinAlarm.h | 7 +- .../common-hal/microcontroller/Processor.c | 51 ++++++++++---- .../common-hal/microcontroller/Processor.h | 6 +- .../common-hal/microcontroller/__init__.c | 8 +++ ports/esp32s2/common-hal/rtc/RTC.h | 6 +- ports/esp32s2/common-hal/supervisor/Runtime.h | 6 +- .../supervisor/internal_flash_root_pointers.h | 6 +- .../common-hal/microcontroller/__init__.c | 4 ++ .../common-hal/microcontroller/__init__.c | 4 ++ .../mimxrt10xx/MIMXRT1011/periph.h | 6 +- .../mimxrt10xx/MIMXRT1062/periph.h | 6 +- .../nrf/common-hal/microcontroller/__init__.c | 4 ++ ports/nrf/common-hal/rgbmatrix/RGBMatrix.h | 4 +- .../stm/common-hal/microcontroller/__init__.c | 4 ++ ports/stm/common-hal/rgbmatrix/RGBMatrix.h | 4 +- shared-bindings/alarm/__init__.c | 60 +++++++++++------ shared-bindings/alarm/__init__.h | 7 +- shared-bindings/alarm/pin/PinAlarm.c | 66 +++++++------------ shared-bindings/alarm/pin/PinAlarm.h | 5 +- shared-bindings/audiopwmio/__init__.h | 6 +- shared-bindings/microcontroller/Processor.c | 4 +- shared-bindings/microcontroller/Processor.h | 1 + shared-bindings/microcontroller/ResetReason.c | 7 +- shared-bindings/microcontroller/ResetReason.h | 14 ++-- shared-bindings/microcontroller/__init__.c | 14 ++++ shared-bindings/microcontroller/__init__.h | 2 + shared-bindings/supervisor/RunReason.c | 8 +-- shared-bindings/supervisor/RunReason.h | 2 +- shared-bindings/supervisor/Runtime.c | 10 ++- shared-bindings/supervisor/Runtime.h | 3 + shared-bindings/supervisor/__init__.c | 1 + supervisor/shared/usb/usb.c | 4 -- supervisor/shared/workflow.c | 8 +-- 38 files changed, 285 insertions(+), 149 deletions(-) diff --git a/main.c b/main.c index 8938d714af..f77bf41d84 100755 --- a/main.c +++ b/main.c @@ -61,6 +61,8 @@ #include "supervisor/usb.h" #include "shared-bindings/microcontroller/__init__.h" +#include "shared-bindings/microcontroller/Processor.h" +#include "shared-bindings/supervisor/Runtime.h" #include "boards/board.h" @@ -327,24 +329,27 @@ bool run_code_py(safe_mode_t safe_mode) { #endif rgb_status_animation_t animation; bool ok = result.return_code != PYEXEC_EXCEPTION; - #if CIRCUITPY_ALARM // If USB isn't enumerated then deep sleep. if (ok && !supervisor_workflow_active() && supervisor_ticks_ms64() > CIRCUITPY_USB_ENUMERATION_DELAY * 1024) { - common_hal_alarm_restart_on_alarm(0, NULL); + common_hal_mcu_deep_sleep(); } - #endif // Show the animation every N seconds. prep_rgb_status_animation(&result, found_main, safe_mode, &animation); while (true) { RUN_BACKGROUND_TASKS; if (reload_requested) { + supervisor_set_run_reason(RUN_REASON_AUTO_RELOAD); reload_requested = false; return true; } if (serial_connected() && serial_bytes_available()) { // Skip REPL if reload was requested. - return (serial_read() == CHAR_CTRL_D); + bool ctrl_d = serial_read() == CHAR_CTRL_D; + if (ctrl_d) { + supervisor_set_run_reason(RUN_REASON_REPL_RELOAD); + } + return (ctrl_d); } if (!serial_connected_before_animation && serial_connected()) { @@ -521,6 +526,9 @@ int __attribute__((used)) main(void) { reset_devices(); reset_board(); + // This is first time we are running CircuitPython after a reset or power-up. + supervisor_set_run_reason(RUN_REASON_STARTUP); + // If not in safe mode turn on autoreload by default but before boot.py in case it wants to change it. if (safe_mode == NO_SAFE_MODE) { autoreload_enable(); diff --git a/ports/atmel-samd/common-hal/microcontroller/__init__.c b/ports/atmel-samd/common-hal/microcontroller/__init__.c index 50a1ec038e..ca39f28386 100644 --- a/ports/atmel-samd/common-hal/microcontroller/__init__.c +++ b/ports/atmel-samd/common-hal/microcontroller/__init__.c @@ -84,6 +84,10 @@ void common_hal_mcu_reset(void) { reset(); } +void common_hal_mcu_deep_sleep(void) { + //deep sleep call here +} + // The singleton microcontroller.Processor object, bound to microcontroller.cpu // It currently only has properties, and no state. const mcu_processor_obj_t common_hal_mcu_processor_obj = { diff --git a/ports/cxd56/common-hal/microcontroller/__init__.c b/ports/cxd56/common-hal/microcontroller/__init__.c index 7aa3b839d7..57140dec70 100644 --- a/ports/cxd56/common-hal/microcontroller/__init__.c +++ b/ports/cxd56/common-hal/microcontroller/__init__.c @@ -81,6 +81,10 @@ void common_hal_mcu_reset(void) { boardctl(BOARDIOC_RESET, 0); } +void common_hal_mcu_deep_sleep(void) { + //deep sleep call here +} + STATIC const mp_rom_map_elem_t mcu_pin_globals_table[] = { { MP_ROM_QSTR(MP_QSTR_UART2_RXD), MP_ROM_PTR(&pin_UART2_RXD) }, { MP_ROM_QSTR(MP_QSTR_UART2_TXD), MP_ROM_PTR(&pin_UART2_TXD) }, diff --git a/ports/esp32s2/common-hal/alarm/__init__.c b/ports/esp32s2/common-hal/alarm/__init__.c index e335345508..4a255c51cc 100644 --- a/ports/esp32s2/common-hal/alarm/__init__.c +++ b/ports/esp32s2/common-hal/alarm/__init__.c @@ -25,12 +25,20 @@ * THE SOFTWARE. */ +#include "py/objtuple.h" + #include "shared-bindings/alarm/__init__.h" #include "shared-bindings/alarm/pin/PinAlarm.h" #include "shared-bindings/alarm/time/DurationAlarm.h" #include "esp_sleep.h" +STATIC mp_obj_tuple_t *_deep_sleep_alarms; + +void alarm_reset(void) { + _deep_sleep_alarms = &mp_const_empty_tuple; +} + void common_hal_alarm_disable_all(void) { esp_sleep_disable_wakeup_source(ESP_SLEEP_WAKEUP_ALL); } @@ -63,3 +71,38 @@ mp_obj_t common_hal_alarm_get_wake_alarm(void) { } return mp_const_none; } + +mp_obj_t common_hal_alarm_sleep_until_alarms(size_t n_alarms, const mp_obj_t *alarms) { + mp_raise_NotImplementedError(NULL); +} + +void common_hal_alarm_set_deep_sleep_alarms(size_t n_alarms, const mp_obj_t *alarms) { + bool time_alarm_set = false; + for (size_t i = 0; i < n_alarms; i++) { + if (MP_OBJ_IS_TYPE(alarms[i], &alarm_pin_pin_alarm_type)) { + mp_raise_NotImplementedError(translate("PinAlarm deep sleep not yet implemented")); + } + if (MP_OBJ_IS_TYPE(alarms[i], &alarm_time_duration_alarm_type)) { + if (time_alarm_set) { + mp_raise_ValueError(translate("Only one alarm.time alarm can be set.")); + } + time_alarm_set = true; + } + } + + _deep_sleep_alarms = mp_obj_new_tuple(n_alarms, alarms); +} + +void common_hal_deep_sleep_with_alarms(void) { + for (size_t i = 0; i < _deep_sleep_alarms.len; i++) { + mp_obj_t alarm = _deep_sleep_alarms.items[i] + if (MP_OBJ_IS_TYPE(alarm, &alarm_time_duration_alarm_type)) { + alarm_time_duration_alarm_obj_t *duration_alarm = MP_OBJ_TO_PTR(alarm); + esp_sleep_enable_timer_wakeup( + (uint64_t) (duration_alarm->duration * 1000000.0f)); + } + // TODO: handle pin alarms + } + + common_hal_mcu_deep_sleep(); +} diff --git a/ports/esp32s2/common-hal/alarm/pin/PinAlarm.c b/ports/esp32s2/common-hal/alarm/pin/PinAlarm.c index 6ac3d05f87..f26c8a179a 100644 --- a/ports/esp32s2/common-hal/alarm/pin/PinAlarm.c +++ b/ports/esp32s2/common-hal/alarm/pin/PinAlarm.c @@ -30,19 +30,24 @@ #include "shared-bindings/alarm/pin/PinAlarm.h" #include "shared-bindings/microcontroller/Pin.h" -void common_hal_alarm_pin_pin_alarm_construct(alarm_pin_pin_alarm_obj_t *self, const mcu_pin_obj_t *pin, bool level, bool edge, bool pull) { - self->pin = pin; - self->level = level; +void common_hal_alarm_pin_pin_alarm_construct(alarm_pin_pin_alarm_obj_t *self, const mp_obj_t pins[], size_t num_pins, bool value, bool all_same_value, bool edge, bool pull) { + self->pins = mp_obj_new_tuple(num_pins, pins); + self->value = value; + self->all_same_value = all_same_value; self->edge = edge; self->pull = pull; } -const mcu_pin_obj_t *common_hal_alarm_pin_pin_alarm_get_pin(alarm_pin_pin_alarm_obj_t *self) { - return self->pin; +const mp_obj_tuple_t *common_hal_alarm_pin_pin_alarm_get_pins(alarm_pin_pin_alarm_obj_t *self) { + return self->pins; } -bool common_hal_alarm_pin_pin_alarm_get_level(alarm_pin_pin_alarm_obj_t *self) { - return self->level; +bool common_hal_alarm_pin_pin_alarm_get_value(alarm_pin_pin_alarm_obj_t *self) { + return self->value; +} + +bool common_hal_alarm_pin_pin_alarm_get_all_same_value(alarm_pin_pin_alarm_obj_t *self) { + return self->all_same_value; } bool common_hal_alarm_pin_pin_alarm_get_edge(alarm_pin_pin_alarm_obj_t *self) { diff --git a/ports/esp32s2/common-hal/alarm/pin/PinAlarm.h b/ports/esp32s2/common-hal/alarm/pin/PinAlarm.h index c6a760b96a..d7e7e2552a 100644 --- a/ports/esp32s2/common-hal/alarm/pin/PinAlarm.h +++ b/ports/esp32s2/common-hal/alarm/pin/PinAlarm.h @@ -24,13 +24,14 @@ * THE SOFTWARE. */ - #include "py/obj.h" +#include "py/objtuple.h" typedef struct { mp_obj_base_t base; - const mcu_pin_obj_t *pin; - bool level; + mp_obj_tuple_t *pins; + bool value; + bool all_same_value; bool edge; bool pull; } alarm_pin_pin_alarm_obj_t; diff --git a/ports/esp32s2/common-hal/microcontroller/Processor.c b/ports/esp32s2/common-hal/microcontroller/Processor.c index bd625dc6e2..fffd1a1b19 100644 --- a/ports/esp32s2/common-hal/microcontroller/Processor.c +++ b/ports/esp32s2/common-hal/microcontroller/Processor.c @@ -31,8 +31,12 @@ #include "py/runtime.h" #include "common-hal/microcontroller/Processor.h" +#include "shared-bindings/microcontroller/ResetReason.h" #include "supervisor/shared/translate.h" +#include "esp_sleep.h" +#include "esp_system.h" + #include "soc/efuse_reg.h" #include "components/driver/esp32s2/include/driver/temp_sensor.h" @@ -77,21 +81,42 @@ void common_hal_mcu_processor_get_uid(uint8_t raw_id[]) { } mcu_reset_reason_t common_hal_mcu_processor_get_reset_reason(void) { - switch (esp_sleep_get_wakeup_cause()) { - case ESP_SLEEP_WAKEUP_TIMER: - return RESET_REASON_DEEP_SLEEP_ALARM; + switch (esp_reset_reason()) { + case ESP_RST_POWERON: + return RESET_REASON_POWER_ON; - case ESP_SLEEP_WAKEUP_EXT0: - return RESET_REASON_DEEP_SLEEP_ALARM; + case ESP_RST_SW: + case ESP_RST_PANIC: + return RESET_REASON_SOFTWARE; - case ESP_SLEEP_WAKEUP_TOUCHPAD: - //TODO: implement TouchIO - case ESP_SLEEP_WAKEUP_UNDEFINED: + case ESP_RST_INT_WDT: + case ESP_RST_TASK_WDT: + case ESP_RST_WDT: + return RESET_REASON_WATCHDOG; + + case ESP_RST_BROWNOUT: + return RESET_REASON_BROWNOUT; + + case ESP_RST_SDIO: + case ESP_RST_EXT: + return RESET_REASON_RESET_PIN; + + case ESP_RST_DEEPSLEEP: + switch (esp_sleep_get_wakeup_cause()) { + case ESP_SLEEP_WAKEUP_TIMER: + case ESP_SLEEP_WAKEUP_EXT0: + case ESP_SLEEP_WAKEUP_EXT1: + case ESP_SLEEP_WAKEUP_TOUCHPAD: + return RESET_REASON_DEEP_SLEEP_ALARM; + + case ESP_SLEEP_WAKEUP_UNDEFINED: + default: + return RESET_REASON_UNKNOWN; + } + + case ESP_RST_UNKNOWN: default: - return RESET_REASON_POWER_APPLIED; + return RESET_REASON_UNKNOWN; + } } - -mcu_reset_reason_t common_hal_mcu_processor_get_reset_reason(void) { - return RESET_REASON_POWER_ON; -} diff --git a/ports/esp32s2/common-hal/microcontroller/Processor.h b/ports/esp32s2/common-hal/microcontroller/Processor.h index f6636b333c..641a11d555 100644 --- a/ports/esp32s2/common-hal/microcontroller/Processor.h +++ b/ports/esp32s2/common-hal/microcontroller/Processor.h @@ -24,8 +24,8 @@ * THE SOFTWARE. */ -#ifndef MICROPY_INCLUDED_LITEX_COMMON_HAL_MICROCONTROLLER_PROCESSOR_H -#define MICROPY_INCLUDED_LITEX_COMMON_HAL_MICROCONTROLLER_PROCESSOR_H +#ifndef MICROPY_INCLUDED_ESP32S2_COMMON_HAL_MICROCONTROLLER_PROCESSOR_H +#define MICROPY_INCLUDED_ESP32S2_COMMON_HAL_MICROCONTROLLER_PROCESSOR_H #define COMMON_HAL_MCU_PROCESSOR_UID_LENGTH 6 @@ -36,4 +36,4 @@ typedef struct { // Stores no state currently. } mcu_processor_obj_t; -#endif // MICROPY_INCLUDED_LITEX_COMMON_HAL_MICROCONTROLLER_PROCESSOR_H +#endif // MICROPY_INCLUDED_ESP32S2_COMMON_HAL_MICROCONTROLLER_PROCESSOR_H diff --git a/ports/esp32s2/common-hal/microcontroller/__init__.c b/ports/esp32s2/common-hal/microcontroller/__init__.c index 3056c65655..fdfbd65fad 100644 --- a/ports/esp32s2/common-hal/microcontroller/__init__.c +++ b/ports/esp32s2/common-hal/microcontroller/__init__.c @@ -79,6 +79,14 @@ void common_hal_mcu_reset(void) { while(1); } +void common_hal_mcu_deep_sleep(void) { + // Shut down wifi cleanly. + esp_wifi_stop(); + + // Does not return. + esp_deep_sleep_start(); +} + // The singleton microcontroller.Processor object, bound to microcontroller.cpu // It currently only has properties, and no state. const mcu_processor_obj_t common_hal_mcu_processor_obj = { diff --git a/ports/esp32s2/common-hal/rtc/RTC.h b/ports/esp32s2/common-hal/rtc/RTC.h index e51f1f7848..233cde3fd2 100644 --- a/ports/esp32s2/common-hal/rtc/RTC.h +++ b/ports/esp32s2/common-hal/rtc/RTC.h @@ -24,11 +24,11 @@ * THE SOFTWARE. */ -#ifndef MICROPY_INCLUDED_NRF_COMMON_HAL_RTC_RTC_H -#define MICROPY_INCLUDED_NRF_COMMON_HAL_RTC_RTC_H +#ifndef MICROPY_INCLUDED_ESP32S2_COMMON_HAL_RTC_RTC_H +#define MICROPY_INCLUDED_ESP32S2_COMMON_HAL_RTC_RTC_H extern void rtc_init(void); extern void rtc_reset(void); extern void common_hal_rtc_init(void); -#endif // MICROPY_INCLUDED_NRF_COMMON_HAL_RTC_RTC_H +#endif // MICROPY_INCLUDED_ESP32S2_COMMON_HAL_RTC_RTC_H diff --git a/ports/esp32s2/common-hal/supervisor/Runtime.h b/ports/esp32s2/common-hal/supervisor/Runtime.h index d1fe246211..840ce1bbb3 100644 --- a/ports/esp32s2/common-hal/supervisor/Runtime.h +++ b/ports/esp32s2/common-hal/supervisor/Runtime.h @@ -24,8 +24,8 @@ * THE SOFTWARE. */ -#ifndef MICROPY_INCLUDED_LITEX_COMMON_HAL_SUPERVISOR_RUNTIME_H -#define MICROPY_INCLUDED_LITEX_COMMON_HAL_SUPERVISOR_RUNTIME_H +#ifndef MICROPY_INCLUDED_ESP32S2_COMMON_HAL_SUPERVISOR_RUNTIME_H +#define MICROPY_INCLUDED_ESP32S2_COMMON_HAL_SUPERVISOR_RUNTIME_H #include "py/obj.h" @@ -34,4 +34,4 @@ typedef struct { // Stores no state currently. } super_runtime_obj_t; -#endif // MICROPY_INCLUDED_LITEX_COMMON_HAL_SUPERVISOR_RUNTIME_H +#endif // MICROPY_INCLUDED_ESP32S2_COMMON_HAL_SUPERVISOR_RUNTIME_H diff --git a/ports/esp32s2/supervisor/internal_flash_root_pointers.h b/ports/esp32s2/supervisor/internal_flash_root_pointers.h index ae3e45e14c..a9a8c2a22e 100644 --- a/ports/esp32s2/supervisor/internal_flash_root_pointers.h +++ b/ports/esp32s2/supervisor/internal_flash_root_pointers.h @@ -23,9 +23,9 @@ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. */ -#ifndef MICROPY_INCLUDED_LITEX_INTERNAL_FLASH_ROOT_POINTERS_H -#define MICROPY_INCLUDED_LITEX_INTERNAL_FLASH_ROOT_POINTERS_H +#ifndef MICROPY_INCLUDED_ESP32S2_INTERNAL_FLASH_ROOT_POINTERS_H +#define MICROPY_INCLUDED_ESP32S2_INTERNAL_FLASH_ROOT_POINTERS_H #define FLASH_ROOT_POINTERS -#endif // MICROPY_INCLUDED_LITEX_INTERNAL_FLASH_ROOT_POINTERS_H +#endif // MICROPY_INCLUDED_ESP32S2_INTERNAL_FLASH_ROOT_POINTERS_H diff --git a/ports/litex/common-hal/microcontroller/__init__.c b/ports/litex/common-hal/microcontroller/__init__.c index 3c91661144..e6f50ed5a6 100644 --- a/ports/litex/common-hal/microcontroller/__init__.c +++ b/ports/litex/common-hal/microcontroller/__init__.c @@ -89,6 +89,10 @@ void common_hal_mcu_reset(void) { while(1); } +void common_hal_mcu_deep_sleep(void) { + //deep sleep call here +} + // The singleton microcontroller.Processor object, bound to microcontroller.cpu // It currently only has properties, and no state. const mcu_processor_obj_t common_hal_mcu_processor_obj = { diff --git a/ports/mimxrt10xx/common-hal/microcontroller/__init__.c b/ports/mimxrt10xx/common-hal/microcontroller/__init__.c index 6a8537e2da..0329ced69b 100644 --- a/ports/mimxrt10xx/common-hal/microcontroller/__init__.c +++ b/ports/mimxrt10xx/common-hal/microcontroller/__init__.c @@ -86,6 +86,10 @@ void common_hal_mcu_reset(void) { NVIC_SystemReset(); } +void common_hal_mcu_deep_sleep(void) { + //deep sleep call here +} + // The singleton microcontroller.Processor object, bound to microcontroller.cpu // It currently only has properties, and no state. const mcu_processor_obj_t common_hal_mcu_processor_obj = { diff --git a/ports/mimxrt10xx/peripherals/mimxrt10xx/MIMXRT1011/periph.h b/ports/mimxrt10xx/peripherals/mimxrt10xx/MIMXRT1011/periph.h index c3f04a0490..c50d73294b 100644 --- a/ports/mimxrt10xx/peripherals/mimxrt10xx/MIMXRT1011/periph.h +++ b/ports/mimxrt10xx/peripherals/mimxrt10xx/MIMXRT1011/periph.h @@ -24,8 +24,8 @@ * THE SOFTWARE. */ -#ifndef MICROPY_INCLUDED_MIMXRT10XX_PERIPHERALS_MIMXRT1011_PERIPH_H -#define MICROPY_INCLUDED_MIMXRT10XX_PERIPHERALS_MIMXRT1011_PERIPH_H +#ifndef MICROPY_INCLUDED_MIMXRT10XX_MIMXRT1011_PERIPHERALS_MIMXRT1011_PERIPH_H +#define MICROPY_INCLUDED_MIMXRT10XX_MIMXRT1011_PERIPHERALS_MIMXRT1011_PERIPH_H extern LPI2C_Type *mcu_i2c_banks[2]; @@ -47,4 +47,4 @@ extern const mcu_periph_obj_t mcu_uart_cts_list[4]; extern const mcu_pwm_obj_t mcu_pwm_list[20]; -#endif // MICROPY_INCLUDED_MIMXRT10XX_PERIPHERALS_MIMXRT1011_PERIP_H +#endif // MICROPY_INCLUDED_MIMXRT10XX_MIMXRT1011_PERIPHERALS_MIMXRT1011_PERIPH_H diff --git a/ports/mimxrt10xx/peripherals/mimxrt10xx/MIMXRT1062/periph.h b/ports/mimxrt10xx/peripherals/mimxrt10xx/MIMXRT1062/periph.h index 4f6ab6261e..067c05d0d0 100644 --- a/ports/mimxrt10xx/peripherals/mimxrt10xx/MIMXRT1062/periph.h +++ b/ports/mimxrt10xx/peripherals/mimxrt10xx/MIMXRT1062/periph.h @@ -24,8 +24,8 @@ * THE SOFTWARE. */ -#ifndef MICROPY_INCLUDED_MIMXRT10XX_PERIPHERALS_MIMXRT1011_PERIPH_H -#define MICROPY_INCLUDED_MIMXRT10XX_PERIPHERALS_MIMXRT1011_PERIPH_H +#ifndef MICROPY_INCLUDED_MIMXRT10XX_MIMXRT1062_PERIPHERALS_MIMXRT1011_PERIPH_H +#define MICROPY_INCLUDED_MIMXRT10XX_MIMXRT1062_PERIPHERALS_MIMXRT1011_PERIPH_H extern LPI2C_Type *mcu_i2c_banks[4]; @@ -47,4 +47,4 @@ extern const mcu_periph_obj_t mcu_uart_cts_list[9]; extern const mcu_pwm_obj_t mcu_pwm_list[67]; -#endif // MICROPY_INCLUDED_MIMXRT10XX_PERIPHERALS_MIMXRT1011_PERIPH_H +#endif // MICROPY_INCLUDED_MIMXRT10XX_MIMXRT1062_PERIPHERALS_MIMXRT1011_PERIPH_H diff --git a/ports/nrf/common-hal/microcontroller/__init__.c b/ports/nrf/common-hal/microcontroller/__init__.c index 06aac9409d..9911896bff 100644 --- a/ports/nrf/common-hal/microcontroller/__init__.c +++ b/ports/nrf/common-hal/microcontroller/__init__.c @@ -95,6 +95,10 @@ void common_hal_mcu_reset(void) { reset_cpu(); } +void common_hal_mcu_deep_sleep(void) { + //deep sleep call here +} + // The singleton microcontroller.Processor object, bound to microcontroller.cpu // It currently only has properties, and no state. const mcu_processor_obj_t common_hal_mcu_processor_obj = { diff --git a/ports/nrf/common-hal/rgbmatrix/RGBMatrix.h b/ports/nrf/common-hal/rgbmatrix/RGBMatrix.h index 48de4dcb21..24d86f1779 100644 --- a/ports/nrf/common-hal/rgbmatrix/RGBMatrix.h +++ b/ports/nrf/common-hal/rgbmatrix/RGBMatrix.h @@ -24,8 +24,8 @@ * THE SOFTWARE. */ -#ifndef MICROPY_INCLUDED_ATMEL_SAMD_COMMON_HAL_RGBMATRIX_RGBMATRIX_H -#define MICROPY_INCLUDED_ATMEL_SAMD_COMMON_HAL_RGBMATRIX_RGBMATRIX_H +#ifndef MICROPY_INCLUDED_NRF_COMMON_HAL_RGBMATRIX_RGBMATRIX_H +#define MICROPY_INCLUDED_NRF_COMMON_HAL_RGBMATRIX_RGBMATRIX_H void *common_hal_rgbmatrix_timer_allocate(void); void common_hal_rgbmatrix_timer_enable(void*); diff --git a/ports/stm/common-hal/microcontroller/__init__.c b/ports/stm/common-hal/microcontroller/__init__.c index a827399ccb..bc81b0e4f5 100644 --- a/ports/stm/common-hal/microcontroller/__init__.c +++ b/ports/stm/common-hal/microcontroller/__init__.c @@ -81,6 +81,10 @@ void common_hal_mcu_reset(void) { NVIC_SystemReset(); } +void common_hal_mcu_deep_sleep(void) { + //deep sleep call here +} + // The singleton microcontroller.Processor object, bound to microcontroller.cpu // It currently only has properties, and no state. const mcu_processor_obj_t common_hal_mcu_processor_obj = { diff --git a/ports/stm/common-hal/rgbmatrix/RGBMatrix.h b/ports/stm/common-hal/rgbmatrix/RGBMatrix.h index 48de4dcb21..323878d202 100644 --- a/ports/stm/common-hal/rgbmatrix/RGBMatrix.h +++ b/ports/stm/common-hal/rgbmatrix/RGBMatrix.h @@ -24,8 +24,8 @@ * THE SOFTWARE. */ -#ifndef MICROPY_INCLUDED_ATMEL_SAMD_COMMON_HAL_RGBMATRIX_RGBMATRIX_H -#define MICROPY_INCLUDED_ATMEL_SAMD_COMMON_HAL_RGBMATRIX_RGBMATRIX_H +#ifndef MICROPY_INCLUDED_STM_COMMON_HAL_RGBMATRIX_RGBMATRIX_H +#define MICROPY_INCLUDED_STM_COMMON_HAL_RGBMATRIX_RGBMATRIX_H void *common_hal_rgbmatrix_timer_allocate(void); void common_hal_rgbmatrix_timer_enable(void*); diff --git a/shared-bindings/alarm/__init__.c b/shared-bindings/alarm/__init__.c index 9345442164..22b2e7f6ab 100644 --- a/shared-bindings/alarm/__init__.c +++ b/shared-bindings/alarm/__init__.c @@ -28,7 +28,6 @@ #include "py/runtime.h" #include "shared-bindings/alarm/__init__.h" -#include "shared-bindings/alarm/ResetReason.h" #include "shared-bindings/alarm/pin/PinAlarm.h" #include "shared-bindings/alarm/time/DurationAlarm.h" @@ -44,42 +43,61 @@ //| //| Deep sleep shuts down power to nearly all of the chip including the CPU and RAM. This can save //| a more significant amount of power, but CircuitPython must start ``code.py`` from the beginning when woken -//| up. CircuitPython will enter deep sleep automatically when the current program exits without error -//| or calls ``sys.exit(0)``. -//| If an error causes CircuitPython to exit, error LED error flashes will be done periodically. -//| An error includes an uncaught exception, or sys.exit called with a non-zero argumetn. +//| up. If the board is not actively connected to a host computer (usually via USB), +//| CircuitPython will enter deep sleep automatically when the current program finishes its last statement +//| or calls ``sys.exit()``. +//| If the board is connected, the board will not enter deep sleep unless `supervisor.exit_and_deep_sleep()` +//| is called explicitly. +//| +//| An error includes an uncaught exception, or sys.exit() called with a non-zero argument +//| //| To set alarms for deep sleep use `alarm.restart_on_alarm()` they will apply to next deep sleep only.""" //| //| wake_alarm: Alarm //| """The most recent alarm to wake us up from a sleep (light or deep.)""" //| -//| def sleep_until_alarm(*alarms: Alarm) -> Alarm: -//| """Performs a light sleep until woken by one of the alarms. The alarm that triggers the wake +void validate_objs_are_alarms(size_t n_args, const mp_obj_t *objs) { + for (size_t i = 0; i < n_args; i++) { + if (MP_OBJ_IS_TYPE(objs[i], &alarm_pin_pin_alarm_type) || + MP_OBJ_IS_TYPE(objs[i], &alarm_time_duration_alarm_type)) { + continue; + } + mp_raise_TypeError_varg(translate("Expected an alarm")); + } +} + +//| def sleep_until_alarms(*alarms: Alarm) -> Alarm: +//| """Performs a light sleep until woken by one of the alarms. The alarm caused the wake-up //| is returned, and is also available as `alarm.wake_alarm` //| """ //| ... //| -STATIC mp_obj_t alarm_sleep_until_alarm(size_t n_args, const mp_obj_t *args) { - // TODO - common_hal_alarm_sleep_until_alarm(size_t n_args, const mp_obj_t *args); +STATIC mp_obj_t alarm_sleep_until_alarms(size_t n_args, const mp_obj_t *args) { + validate_objs_are_alarms(n_args, args); + common_hal_alarm_sleep_until_alarms(n_args, args); return mp_const_none; } -MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(alarm_sleep_until_alarm_obj, 1, MP_OBJ_FUN_ARGS_MAX, alarm_sleep_until_alarm); +MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(alarm_sleep_until_alarms_obj, 1, MP_OBJ_FUN_ARGS_MAX, alarm_sleep_until_alarms); -//| def restart_on_alarm(*alarms: Alarm) -> None: +//| def set_deep_sleep_alarms(*alarms: Alarm) -> None: //| """Set one or more alarms to wake up from a deep sleep. -//| When awakened, ``code.py`` will restart from the beginning. -//| The last alarm to wake us up is available as `alarm.wake_alarm`. +//| +//| When awakened, the microcontroller will restart and run ``boot.py`` and ``code.py`` +//| from the beginning. +//| +//| The alarm that caused the wake-up is available as `alarm.wake_alarm`. +//| +//| If you call this routine more than once, only the last set of alarms given will be used. //| """ //| ... //| -STATIC mp_obj_t alarm_restart_on_alarm(size_t n_args, const mp_obj_t *args) { - // TODO - common_hal_alarm_restart_on_alarm(size_t n_args, const mp_obj_t *args); +STATIC mp_obj_t alarm_set_deep_sleep_alarms(size_t n_args, const mp_obj_t *args) { + validate_objs_are_alarms(n_args, args); + common_hal_alarm_set_deep_sleep_alarms(n_args, args); return mp_const_none; } -MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(alarm_restart_on_alarm_obj, 1, MP_OBJ_FUN_ARGS_MAX, alarm_restart_on_alarm); +MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(alarm_set_deep_sleep_alarms_obj, 1, MP_OBJ_FUN_ARGS_MAX, alarm_set_deep_sleep_alarms); //| """The `alarm.pin` module contains alarm attributes and classes related to pins. //| """ @@ -116,11 +134,11 @@ STATIC const mp_obj_module_t alarm_time_module = { STATIC mp_map_elem_t alarm_module_globals_table[] = { { MP_ROM_QSTR(MP_QSTR___name__), MP_ROM_QSTR(MP_QSTR_alarm) }, - // wake_alarm and reset_reason are mutable attributes. + // wake_alarm is a mutable attribute. { MP_ROM_QSTR(MP_QSTR_wake_alarm), mp_const_none }, - { MP_ROM_QSTR(MP_QSTR_sleep_until_alarm), MP_OBJ_FROM_PTR(&alarm_sleep_until_alarm_obj) }, - { MP_ROM_QSTR(MP_QSTR_restart_on_alarm), MP_OBJ_FROM_PTR(&alarm_restart_on_alarm_obj) }, + { MP_ROM_QSTR(MP_QSTR_sleep_until_alarms), MP_OBJ_FROM_PTR(&alarm_sleep_until_alarms_obj) }, + { MP_ROM_QSTR(MP_QSTR_set_deep_sleep_alarms), MP_OBJ_FROM_PTR(&alarm_set_deep_sleep_alarms_obj) }, { MP_ROM_QSTR(MP_QSTR_pin), MP_OBJ_FROM_PTR(&alarm_pin_module) }, { MP_ROM_QSTR(MP_QSTR_time), MP_OBJ_FROM_PTR(&alarm_time_module) } diff --git a/shared-bindings/alarm/__init__.h b/shared-bindings/alarm/__init__.h index 29be8716c5..4df12175d4 100644 --- a/shared-bindings/alarm/__init__.h +++ b/shared-bindings/alarm/__init__.h @@ -29,9 +29,10 @@ #include "py/obj.h" +extern mp_obj_t common_hal_alarm_sleep_until_alarms(size_t n_alarms, const mp_obj_t *alarms); +extern mp_obj_t common_hal_alarm_set_deep_sleep_alarms(size_t n_alarms, const mp_obj_t *alarms); + +// Used by wake-up code. extern void common_hal_alarm_set_wake_alarm(mp_obj_t alarm); -extern mp_obj_t common_hal_alarm_restart_on_alarm(size_t n_alarms, const mp_obj_t *alarms); -extern mp_obj_t alarm_sleep_until_alarm(size_t n_alarms, const mp_obj_t *alarms); - #endif // MICROPY_INCLUDED_SHARED_BINDINGS_ALARM___INIT___H diff --git a/shared-bindings/alarm/pin/PinAlarm.c b/shared-bindings/alarm/pin/PinAlarm.c index 835a5be5ce..a2d2e0ab7a 100644 --- a/shared-bindings/alarm/pin/PinAlarm.c +++ b/shared-bindings/alarm/pin/PinAlarm.c @@ -37,23 +37,25 @@ //| class PinAlarm: //| """Trigger an alarm when a pin changes state.""" //| -//| def __init__(self, pin: microcontroller.Pin, level: bool, *, edge: bool = False, pull: bool = False) -> None: +//| def __init__(self, *pins: microcontroller.Pin, value: bool, all_same_value: bool = False, edge: bool = False, pull: bool = False) -> None: //| """Create an alarm triggered by a `~microcontroller.Pin` level. The alarm is not active //| until it is listed in an `alarm`-enabling function, such as `alarm.sleep_until_alarm()` or //| `alarm.restart_on_alarm()`. //| -//| :param ~microcontroller.Pin pin: The pin to monitor. On some ports, the choice of pin +//| :param pins: The pins to monitor. On some ports, the choice of pins //| may be limited due to hardware restrictions, particularly for deep-sleep alarms. -//| :param bool level: When active, trigger when the level is high (``True``) or low (``False``). -//| On some ports, multiple `PinAlarm` objects may need to have coordinated levels +//| :param bool value: When active, trigger when the pin value is high (``True``) or low (``False``). +//| On some ports, multiple `PinAlarm` objects may need to have coordinated values //| for deep-sleep alarms. +//| :param bool all_same_value: If ``True``, all pins listed must be at `value` to trigger the alarm. +//| If ``False``, any one of the pins going to `value` will trigger the alarm. //| :param bool edge: If ``True``, trigger only when there is a transition to the specified -//| value of `level`. If ``True``, if the alarm becomes active when the pin level already -//| matches `level`, the alarm is not triggered: the pin must transition from ``not level`` -//| to ``level`` to trigger the alarm. On some ports, edge-triggering may not be available, +//| value of `value`. If ``True``, if the alarm becomes active when the pin value already +//| matches `value`, the alarm is not triggered: the pin must transition from ``not value`` +//| to ``value`` to trigger the alarm. On some ports, edge-triggering may not be available, //| particularly for deep-sleep alarms. -//| :param bool pull: Enable a pull-up or pull-down which pulls the pin to level opposite -//| opposite that of `level`. For instance, if `level` is set to ``True``, setting `pull` +//| :param bool pull: Enable a pull-up or pull-down which pulls the pin to value opposite +//| opposite that of `value`. For instance, if `value` is set to ``True``, setting `pull` //| to ``True`` will enable a pull-down, to hold the pin low normally until an outside signal //| pulls it high. //| """ @@ -62,51 +64,30 @@ 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) { alarm_pin_pin_alarm_obj_t *self = m_new_obj(alarm_pin_pin_alarm_obj_t); self->base.type = &alarm_pin_pin_alarm_type; - enum { ARG_pin, ARG_level, ARG_edge, ARG_pull }; + enum { ARG_value, ARG_all_same_value, ARG_edge, ARG_pull }; static const mp_arg_t allowed_args[] = { - { MP_QSTR_pin, MP_ARG_REQUIRED | MP_ARG_OBJ }, - { MP_QSTR_level, MP_ARG_REQUIRED | MP_ARG_BOOL }, + { MP_QSTR_value, MP_ARG_KW_ONLY | MP_ARG_REQUIRED | MP_ARG_BOOL }, + { MP_QSTR_all_same_value, MP_ARG_KW_ONLY | MP_ARG_BOOL, {.u_bool = false} }, { MP_QSTR_edge, MP_ARG_KW_ONLY | MP_ARG_BOOL, {.u_bool = false} }, { MP_QSTR_pull, MP_ARG_KW_ONLY | MP_ARG_BOOL, {.u_bool = false} }, }; mp_arg_val_t args[MP_ARRAY_SIZE(allowed_args)]; - mp_arg_parse_all(n_args, pos_args, kw_args, MP_ARRAY_SIZE(allowed_args), allowed_args, args); + mp_arg_parse_all(0, pos_args, kw_args, MP_ARRAY_SIZE(allowed_args), allowed_args, args); - const mcu_pin_obj_t* pin = validate_obj_is_free_pin(args[ARG_pin].u_obj); + for (size_t i = 0; i < n_args; i ++) { + validate_obj_is_free_pin(pos_args[i]); + } common_hal_alarm_pin_pin_alarm_construct( - self, pin, args[ARG_level].u_bool, args[ARG_edge].u_bool, args[ARG_pull].u_bool); + self, pos_args, n_args, + args[ARG_value].u_bool, + args[ARG_all_same_value].u_bool, + args[ARG_edge].u_bool, + args[ARG_pull].u_bool); return MP_OBJ_FROM_PTR(self); } -//| def __eq__(self, other: object) -> bool: -//| """Two PinAlarm objects are equal if their durations are the same if their pin, -//| level, edge, and pull attributes are all the same.""" -//| ... -//| -STATIC mp_obj_t alarm_pin_pin_alarm_binary_op(mp_binary_op_t op, mp_obj_t lhs_in, mp_obj_t rhs_in) { - switch (op) { - case MP_BINARY_OP_EQUAL: - if (MP_OBJ_IS_TYPE(rhs_in, &alarm_pin_pin_alarm_type)) { - // Pins are singletons, so we can compare them directly. - return mp_obj_new_bool( - common_hal_alarm_pin_pin_alarm_get_pin(lhs_in) == - common_hal_alarm_pin_pin_alarm_get_pin(rhs_in) && - common_hal_alarm_pin_pin_alarm_get_level(lhs_in) == - common_hal_alarm_pin_pin_alarm_get_level(rhs_in) && - common_hal_alarm_pin_pin_alarm_get_edge(lhs_in) == - common_hal_alarm_pin_pin_alarm_get_edge(rhs_in) && - common_hal_alarm_pin_pin_alarm_get_pull(lhs_in) == - common_hal_alarm_pin_pin_alarm_get_pull(rhs_in)); - } - return mp_const_false; - - default: - return MP_OBJ_NULL; // op not supported - } -} - STATIC const mp_rom_map_elem_t alarm_pin_pin_alarm_locals_dict_table[] = { }; @@ -116,6 +97,5 @@ const mp_obj_type_t alarm_pin_pin_alarm_type = { { &mp_type_type }, .name = MP_QSTR_PinAlarm, .make_new = alarm_pin_pin_alarm_make_new, - .binary_op = alarm_pin_pin_alarm_binary_op, .locals_dict = (mp_obj_t)&alarm_pin_pin_alarm_locals_dict, }; diff --git a/shared-bindings/alarm/pin/PinAlarm.h b/shared-bindings/alarm/pin/PinAlarm.h index 978ceaad56..bbf3018b5d 100644 --- a/shared-bindings/alarm/pin/PinAlarm.h +++ b/shared-bindings/alarm/pin/PinAlarm.h @@ -28,13 +28,14 @@ #define MICROPY_INCLUDED_SHARED_BINDINGS_ALARM_PIN_PIN_ALARM_H #include "py/obj.h" +#include "py/objtuple.h" #include "common-hal/microcontroller/Pin.h" #include "common-hal/alarm/pin/PinAlarm.h" extern const mp_obj_type_t alarm_pin_pin_alarm_type; -extern void common_hal_alarm_pin_pin_alarm_construct(alarm_pin_pin_alarm_obj_t *self, const mcu_pin_obj_t *pin, bool level, bool edge, bool pull); -extern const mcu_pin_obj_t *common_hal_alarm_pin_pin_alarm_get_pin(alarm_pin_pin_alarm_obj_t *self); +void common_hal_alarm_pin_pin_alarm_construct(alarm_pin_pin_alarm_obj_t *self, const mp_obj_t pins[], size_t num_pins, bool value, bool all_same_value, bool edge, bool pull); +extern const mp_obj_tuple_t *common_hal_alarm_pin_pin_alarm_get_pins(alarm_pin_pin_alarm_obj_t *self); extern bool common_hal_alarm_pin_pin_alarm_get_level(alarm_pin_pin_alarm_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_pin_alarm_get_pull(alarm_pin_pin_alarm_obj_t *self); diff --git a/shared-bindings/audiopwmio/__init__.h b/shared-bindings/audiopwmio/__init__.h index e4b7067d11..d7956d31e6 100644 --- a/shared-bindings/audiopwmio/__init__.h +++ b/shared-bindings/audiopwmio/__init__.h @@ -24,11 +24,11 @@ * THE SOFTWARE. */ -#ifndef MICROPY_INCLUDED_SHARED_BINDINGS_AUDIOIO___INIT___H -#define MICROPY_INCLUDED_SHARED_BINDINGS_AUDIOIO___INIT___H +#ifndef MICROPY_INCLUDED_SHARED_BINDINGS_AUDIOPWMIO___INIT___H +#define MICROPY_INCLUDED_SHARED_BINDINGS_AUDIOPWMIO___INIT___H #include "py/obj.h" // Nothing now. -#endif // MICROPY_INCLUDED_SHARED_BINDINGS_AUDIOIO___INIT___H +#endif // MICROPY_INCLUDED_SHARED_BINDINGS_AUDIOPWMIO___INIT___H diff --git a/shared-bindings/microcontroller/Processor.c b/shared-bindings/microcontroller/Processor.c index b0ab842f4c..ea43688213 100644 --- a/shared-bindings/microcontroller/Processor.c +++ b/shared-bindings/microcontroller/Processor.c @@ -76,9 +76,9 @@ STATIC mp_obj_t mcu_processor_get_reset_reason(mp_obj_t self) { MP_DEFINE_CONST_FUN_OBJ_1(mcu_processor_get_reset_reason_obj, mcu_processor_get_reset_reason); -const mp_obj_property_t mcu_reset_reason_obj = { +const mp_obj_property_t mcu_processor_reset_reason_obj = { .base.type = &mp_type_property, - .proxy = {(mp_obj_t)&mcu_processor_get_reason_reason_obj, // getter + .proxy = {(mp_obj_t)&mcu_processor_get_reset_reason_obj, // getter (mp_obj_t)&mp_const_none_obj, // no setter (mp_obj_t)&mp_const_none_obj, // no deleter }, diff --git a/shared-bindings/microcontroller/Processor.h b/shared-bindings/microcontroller/Processor.h index a842e06f32..98d4790876 100644 --- a/shared-bindings/microcontroller/Processor.h +++ b/shared-bindings/microcontroller/Processor.h @@ -29,6 +29,7 @@ #include "py/obj.h" +#include "common-hal/microcontroller/Processor.h" #include "shared-bindings/microcontroller/ResetReason.h" extern const mp_obj_type_t mcu_processor_type; diff --git a/shared-bindings/microcontroller/ResetReason.c b/shared-bindings/microcontroller/ResetReason.c index 151fcf3159..61891934ae 100644 --- a/shared-bindings/microcontroller/ResetReason.c +++ b/shared-bindings/microcontroller/ResetReason.c @@ -35,6 +35,7 @@ MAKE_ENUM_VALUE(mcu_reset_reason_type, reset_reason, SOFTWARE, RESET_REASON_SOFT MAKE_ENUM_VALUE(mcu_reset_reason_type, reset_reason, DEEP_SLEEP_ALARM, RESET_REASON_DEEP_SLEEP_ALARM); MAKE_ENUM_VALUE(mcu_reset_reason_type, reset_reason, RESET_PIN, RESET_REASON_RESET_PIN); MAKE_ENUM_VALUE(mcu_reset_reason_type, reset_reason, WATCHDOG, RESET_REASON_WATCHDOG); +MAKE_ENUM_VALUE(mcu_reset_reason_type, reset_reason, UNKNOWN, RESET_REASON_UNKNOWN); //| class ResetReason: //| """The reason the microntroller was last reset""" @@ -55,7 +56,10 @@ MAKE_ENUM_VALUE(mcu_reset_reason_type, reset_reason, WATCHDOG, RESET_REASON_WATC //| """The microntroller was reset by a signal on its reset pin. The pin might be connected to a reset button.""" //| //| WATCHDOG: object -//| """The chip microcontroller reset by its watchdog timer.""" +//| """The microcontroller was reset by its watchdog timer.""" +//| +//| UNKNOWN: object +//| """The microntroller restarted for an unknown reason.""" //| MAKE_ENUM_MAP(mcu_reset_reason) { MAKE_ENUM_MAP_ENTRY(reset_reason, POWER_ON), @@ -64,6 +68,7 @@ MAKE_ENUM_MAP(mcu_reset_reason) { MAKE_ENUM_MAP_ENTRY(reset_reason, DEEP_SLEEP_ALARM), MAKE_ENUM_MAP_ENTRY(reset_reason, RESET_PIN), MAKE_ENUM_MAP_ENTRY(reset_reason, WATCHDOG), + MAKE_ENUM_MAP_ENTRY(reset_reason, UNKNOWN), }; STATIC MP_DEFINE_CONST_DICT(mcu_reset_reason_locals_dict, mcu_reset_reason_locals_table); diff --git a/shared-bindings/microcontroller/ResetReason.h b/shared-bindings/microcontroller/ResetReason.h index df1abf266e..8ed5e48315 100644 --- a/shared-bindings/microcontroller/ResetReason.h +++ b/shared-bindings/microcontroller/ResetReason.h @@ -24,8 +24,8 @@ * THE SOFTWARE. */ -#ifndef MICROPY_INCLUDED_SHARED_BINDINGS_MCU__RESET_REASON__H -#define MICROPY_INCLUDED_SHARED_BINDINGS_MCU__RESET_REASON__H +#ifndef MICROPY_INCLUDED_SHARED_BINDINGS_MCU_RESET_REASON__H +#define MICROPY_INCLUDED_SHARED_BINDINGS_MCU_RESET_REASON__H #include "py/obj.h" #include "py/enum.h" @@ -37,15 +37,9 @@ typedef enum { RESET_REASON_DEEP_SLEEP_ALARM, RESET_REASON_RESET_PIN, RESET_REASON_WATCHDOG, + RESET_REASON_UNKNOWN, } mcu_reset_reason_t; -extern const cp_enum_obj_t reset_reason_POWER_ON_obj; -extern const cp_enum_obj_t reset_reason_BROWNOUT_obj; -extern const cp_enum_obj_t reset_reason_SOFTWARE_obj; -extern const cp_enum_obj_t reset_reason_DEEP_SLEEP_ALARM_obj; -extern const cp_enum_obj_t reset_reason_RESET_PIN_obj; -extern const cp_enum_obj_t reset_reason_WATCHDOG_obj; - extern const mp_obj_type_t mcu_reset_reason_type; -#endif // MICROPY_INCLUDED_SHARED_BINDINGS_MCU__RESET_REASON__H +#endif // MICROPY_INCLUDED_SHARED_BINDINGS_MCU_RESET_REASON__H diff --git a/shared-bindings/microcontroller/__init__.c b/shared-bindings/microcontroller/__init__.c index d09cf8f445..d6ce323c58 100644 --- a/shared-bindings/microcontroller/__init__.c +++ b/shared-bindings/microcontroller/__init__.c @@ -56,6 +56,19 @@ //| This object is the sole instance of `microcontroller.Processor`.""" //| +//| def deep_sleep() -> None: +//| Go into deep sleep. If the board is connected via USB, disconnect USB first. +//| +//| The board will awake from deep sleep only if the reset button is pressed +//| or it is awoken by an alarm set by `alarm.set_deep_sleep_alarms()`. +//| ... +//| +STATIC mp_obj_t mcu_deep_sleep(void){ + + return mp_const_none; +} +MP_DEFINE_CONST_FUN_OBJ_0(mcu_deep_sleep_obj, mcu_deep_sleep); + //| def delay_us(delay: int) -> None: //| """Dedicated delay method used for very short delays. **Do not** do long delays //| because this stops all other functions from completing. Think of this as an empty @@ -164,6 +177,7 @@ const mp_obj_module_t mcu_pin_module = { STATIC const mp_rom_map_elem_t mcu_module_globals_table[] = { { MP_ROM_QSTR(MP_QSTR___name__), MP_ROM_QSTR(MP_QSTR_microcontroller) }, { MP_ROM_QSTR(MP_QSTR_cpu), MP_ROM_PTR(&common_hal_mcu_processor_obj) }, + { MP_ROM_QSTR(MP_QSTR_deep_sleep), MP_ROM_PTR(&mcu_deep_sleep_obj) }, { MP_ROM_QSTR(MP_QSTR_delay_us), MP_ROM_PTR(&mcu_delay_us_obj) }, { MP_ROM_QSTR(MP_QSTR_disable_interrupts), MP_ROM_PTR(&mcu_disable_interrupts_obj) }, { MP_ROM_QSTR(MP_QSTR_enable_interrupts), MP_ROM_PTR(&mcu_enable_interrupts_obj) }, diff --git a/shared-bindings/microcontroller/__init__.h b/shared-bindings/microcontroller/__init__.h index ac71de4247..c6ccccea72 100644 --- a/shared-bindings/microcontroller/__init__.h +++ b/shared-bindings/microcontroller/__init__.h @@ -43,6 +43,8 @@ extern void common_hal_mcu_enable_interrupts(void); extern void common_hal_mcu_on_next_reset(mcu_runmode_t runmode); extern void common_hal_mcu_reset(void); +extern void common_hal_mcu_deep_sleep(void); + extern const mp_obj_dict_t mcu_pin_globals; extern const mcu_processor_obj_t common_hal_mcu_processor_obj; diff --git a/shared-bindings/supervisor/RunReason.c b/shared-bindings/supervisor/RunReason.c index ee08f6d71b..7e7a74d2f4 100644 --- a/shared-bindings/supervisor/RunReason.c +++ b/shared-bindings/supervisor/RunReason.c @@ -29,7 +29,7 @@ #include "shared-bindings/supervisor/RunReason.h" MAKE_ENUM_VALUE(supervisor_run_reason_type, run_reason, STARTUP, RUN_REASON_STARTUP); -MAKE_ENUM_VALUE(supervisor_run_reason_type, run_reason, AUTORELOAD, RUN_REASON_AUTORELOAD); +MAKE_ENUM_VALUE(supervisor_run_reason_type, run_reason, AUTORELOAD, RUN_REASON_AUTO_RELOAD); MAKE_ENUM_VALUE(supervisor_run_reason_type, run_reason, SUPERVISOR_RELOAD, RUN_REASON_SUPERVISOR_RELOAD); MAKE_ENUM_VALUE(supervisor_run_reason_type, run_reason, REPL_RELOAD, RUN_REASON_REPL_RELOAD); @@ -40,8 +40,8 @@ MAKE_ENUM_VALUE(supervisor_run_reason_type, run_reason, REPL_RELOAD, RUN_REASON_ //| """CircuitPython started the microcontroller started up. See `microcontroller.cpu.reset_reason` //| for more detail on why the microcontroller was started.""" //| -//| AUTORELOAD: object -//| """CircuitPython restarted due to a USB write to the filesystem.""" +//| AUTO_RELOAD: object +//| """CircuitPython restarted due to an external write to the filesystem.""" //| //| SUPERVISOR_RELOAD: object //| """CircuitPython restarted due to a call to `supervisor.reload()`.""" @@ -51,7 +51,7 @@ MAKE_ENUM_VALUE(supervisor_run_reason_type, run_reason, REPL_RELOAD, RUN_REASON_ //| MAKE_ENUM_MAP(run_reason) { MAKE_ENUM_MAP_ENTRY(run_reason, STARTUP), - MAKE_ENUM_MAP_ENTRY(run_reason, AUTORELOAD), + MAKE_ENUM_MAP_ENTRY(run_reason, AUTO_RELOAD), MAKE_ENUM_MAP_ENTRY(run_reason, SUPERVISOR_RELOAD), MAKE_ENUM_MAP_ENTRY(run_reason, REPL_RELOAD), }; diff --git a/shared-bindings/supervisor/RunReason.h b/shared-bindings/supervisor/RunReason.h index 934c72fd8c..391e6d3064 100644 --- a/shared-bindings/supervisor/RunReason.h +++ b/shared-bindings/supervisor/RunReason.h @@ -28,7 +28,7 @@ typedef enum { RUN_REASON_STARTUP, - RUN_REASON_AUTORELOAD, + RUN_REASON_AUTO_RELOAD, RUN_REASON_SUPERVISOR_RELOAD, RUN_REASON_REPL_RELOAD, } supervisor_run_reason_t; diff --git a/shared-bindings/supervisor/Runtime.c b/shared-bindings/supervisor/Runtime.c index 6500dadd59..67193e051e 100755 --- a/shared-bindings/supervisor/Runtime.c +++ b/shared-bindings/supervisor/Runtime.c @@ -25,9 +25,13 @@ */ #include +#include "py/enum.h" #include "py/objproperty.h" +#include "shared-bindings/supervisor/RunReason.h" #include "shared-bindings/supervisor/Runtime.h" +STATIC supervisor_run_reason_t _run_reason; + //TODO: add USB, REPL to description once they're operational //| class Runtime: //| """Current status of runtime objects. @@ -94,8 +98,7 @@ const mp_obj_property_t supervisor_serial_bytes_available_obj = { //| """Returns why CircuitPython started running this particular time. //| STATIC mp_obj_t supervisor_get_run_reason(mp_obj_t self) { - mp_raise_NotImplementedError(NULL); - return mp_const_none; + return cp_enum_find(&supervisor_run_reason_type, _run_reason); } MP_DEFINE_CONST_FUN_OBJ_1(supervisor_get_run_reason_obj, supervisor_get_run_reason); @@ -106,6 +109,9 @@ const mp_obj_property_t supervisor_run_reason_obj = { (mp_obj_t)&mp_const_none_obj}, }; +void supervisor_set_run_reason(supervisor_run_reason_t run_reason) { + _run_reason = run_reason; +} STATIC const mp_rom_map_elem_t supervisor_runtime_locals_dict_table[] = { { MP_ROM_QSTR(MP_QSTR_serial_connected), MP_ROM_PTR(&supervisor_serial_connected_obj) }, diff --git a/shared-bindings/supervisor/Runtime.h b/shared-bindings/supervisor/Runtime.h index 2dc59c3ab6..51ed7604df 100755 --- a/shared-bindings/supervisor/Runtime.h +++ b/shared-bindings/supervisor/Runtime.h @@ -30,9 +30,12 @@ #include #include "py/obj.h" +#include "shared-bindings/supervisor/RunReason.h" extern const mp_obj_type_t supervisor_runtime_type; +void supervisor_set_run_reason(supervisor_run_reason_t run_reason); + bool common_hal_get_serial_connected(void); bool common_hal_get_serial_bytes_available(void); diff --git a/shared-bindings/supervisor/__init__.c b/shared-bindings/supervisor/__init__.c index bc6fdbff5a..4d2d6db309 100644 --- a/shared-bindings/supervisor/__init__.c +++ b/shared-bindings/supervisor/__init__.c @@ -88,6 +88,7 @@ MP_DEFINE_CONST_FUN_OBJ_1(supervisor_set_rgb_status_brightness_obj, supervisor_s //| STATIC mp_obj_t supervisor_reload(void) { reload_requested = true; + supervisor_set_run_reason(RUN_REASON_SUPERVISOR_RELOAD); mp_raise_reload_exception(); return mp_const_none; } diff --git a/supervisor/shared/usb/usb.c b/supervisor/shared/usb/usb.c index 3d76e7000a..ff08ade18a 100644 --- a/supervisor/shared/usb/usb.c +++ b/supervisor/shared/usb/usb.c @@ -106,25 +106,21 @@ void usb_irq_handler(void) { // Invoked when device is mounted void tud_mount_cb(void) { usb_msc_mount(); - _workflow_active = true; } // Invoked when device is unmounted void tud_umount_cb(void) { usb_msc_umount(); - _workflow_active = false; } // Invoked when usb bus is suspended // remote_wakeup_en : if host allows us to perform remote wakeup // USB Specs: Within 7ms, device must draw an average current less than 2.5 mA from bus void tud_suspend_cb(bool remote_wakeup_en) { - _workflow_active = false; } // Invoked when usb bus is resumed void tud_resume_cb(void) { - _workflow_active = true; } // Invoked when cdc when line state changed e.g connected/disconnected diff --git a/supervisor/shared/workflow.c b/supervisor/shared/workflow.c index cd19d3aa25..41af22eb70 100644 --- a/supervisor/shared/workflow.c +++ b/supervisor/shared/workflow.c @@ -25,10 +25,10 @@ */ #include - -// Set by the shared USB code. -volatile bool _workflow_active; +#include "tusb.h" bool supervisor_workflow_active(void) { - return _workflow_active; + // Eventually there might be other non-USB workflows, such as BLE. + // tud_ready() checks for usb mounted and not suspended. + return tud_ready(); } From 3abee9b2563f0203f3d9521631499008708bb407 Mon Sep 17 00:00:00 2001 From: Dan Halbert Date: Sun, 22 Nov 2020 21:52:37 -0500 Subject: [PATCH 23/34] compiles; maybe ready to test, or almost --- ports/esp32s2/common-hal/alarm/__init__.c | 8 +++-- ports/esp32s2/common-hal/alarm/__init__.h | 32 +++++++++++++++++++ .../common-hal/microcontroller/__init__.c | 1 + shared-bindings/alarm/__init__.h | 2 +- 4 files changed, 39 insertions(+), 4 deletions(-) create mode 100644 ports/esp32s2/common-hal/alarm/__init__.h diff --git a/ports/esp32s2/common-hal/alarm/__init__.c b/ports/esp32s2/common-hal/alarm/__init__.c index 4a255c51cc..0ea476d860 100644 --- a/ports/esp32s2/common-hal/alarm/__init__.c +++ b/ports/esp32s2/common-hal/alarm/__init__.c @@ -26,17 +26,19 @@ */ #include "py/objtuple.h" +#include "py/runtime.h" #include "shared-bindings/alarm/__init__.h" #include "shared-bindings/alarm/pin/PinAlarm.h" #include "shared-bindings/alarm/time/DurationAlarm.h" +#include "shared-bindings/microcontroller/__init__.h" #include "esp_sleep.h" STATIC mp_obj_tuple_t *_deep_sleep_alarms; void alarm_reset(void) { - _deep_sleep_alarms = &mp_const_empty_tuple; + _deep_sleep_alarms = mp_const_empty_tuple; } void common_hal_alarm_disable_all(void) { @@ -94,8 +96,8 @@ void common_hal_alarm_set_deep_sleep_alarms(size_t n_alarms, const mp_obj_t *ala } void common_hal_deep_sleep_with_alarms(void) { - for (size_t i = 0; i < _deep_sleep_alarms.len; i++) { - mp_obj_t alarm = _deep_sleep_alarms.items[i] + for (size_t i = 0; i < _deep_sleep_alarms->len; i++) { + mp_obj_t alarm = _deep_sleep_alarms->items[i]; if (MP_OBJ_IS_TYPE(alarm, &alarm_time_duration_alarm_type)) { alarm_time_duration_alarm_obj_t *duration_alarm = MP_OBJ_TO_PTR(alarm); esp_sleep_enable_timer_wakeup( diff --git a/ports/esp32s2/common-hal/alarm/__init__.h b/ports/esp32s2/common-hal/alarm/__init__.h new file mode 100644 index 0000000000..5678a0e7f1 --- /dev/null +++ b/ports/esp32s2/common-hal/alarm/__init__.h @@ -0,0 +1,32 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2020 Dan Halbert for Adafruit Industries. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +#ifndef MICROPY_INCLUDED_ESP32S2_COMMON_HAL_ALARM__INIT__H +#define MICROPY_INCLUDED_ESP32S2_COMMON_HAL_ALARM__INIT__H + +void alarm_reset(void); + +#endif // MICROPY_INCLUDED_ESP32S2_COMMON_HAL_ALARM__INIT__H diff --git a/ports/esp32s2/common-hal/microcontroller/__init__.c b/ports/esp32s2/common-hal/microcontroller/__init__.c index 9d87e4536f..59eb1afcc0 100644 --- a/ports/esp32s2/common-hal/microcontroller/__init__.c +++ b/ports/esp32s2/common-hal/microcontroller/__init__.c @@ -42,6 +42,7 @@ #include "freertos/FreeRTOS.h" #include "esp_sleep.h" +#include "esp_wifi.h" void common_hal_mcu_delay_us(uint32_t delay) { mp_hal_delay_us(delay); diff --git a/shared-bindings/alarm/__init__.h b/shared-bindings/alarm/__init__.h index 4df12175d4..c74dfbe5c3 100644 --- a/shared-bindings/alarm/__init__.h +++ b/shared-bindings/alarm/__init__.h @@ -30,7 +30,7 @@ #include "py/obj.h" extern mp_obj_t common_hal_alarm_sleep_until_alarms(size_t n_alarms, const mp_obj_t *alarms); -extern mp_obj_t common_hal_alarm_set_deep_sleep_alarms(size_t n_alarms, const mp_obj_t *alarms); +extern void common_hal_alarm_set_deep_sleep_alarms(size_t n_alarms, const mp_obj_t *alarms); // Used by wake-up code. extern void common_hal_alarm_set_wake_alarm(mp_obj_t alarm); From 7a45afc54919162df342fab421ed113ff1771d01 Mon Sep 17 00:00:00 2001 From: Dan Halbert Date: Mon, 23 Nov 2020 22:44:53 -0500 Subject: [PATCH 24/34] working, but need to avoid deep sleeping too fast before USB ready --- main.c | 104 ++++++++++-------- ports/esp32s2/Makefile | 4 +- ports/esp32s2/common-hal/alarm/__init__.c | 4 +- .../common-hal/microcontroller/__init__.c | 4 +- py/circuitpy_defns.mk | 1 + shared-bindings/alarm/__init__.h | 3 + shared-bindings/microcontroller/__init__.c | 14 --- shared-bindings/microcontroller/__init__.h | 2 +- shared-bindings/supervisor/RunReason.c | 4 +- shared-bindings/supervisor/Runtime.c | 3 + shared-bindings/supervisor/__init__.c | 51 ++++++++- supervisor/shared/workflow.c | 26 +++++ supervisor/shared/workflow.h | 8 +- 13 files changed, 153 insertions(+), 75 deletions(-) diff --git a/main.c b/main.c index f77bf41d84..b2e527ddef 100755 --- a/main.c +++ b/main.c @@ -47,17 +47,17 @@ #include "mpconfigboard.h" #include "supervisor/background_callback.h" #include "supervisor/cpu.h" +#include "supervisor/filesystem.h" #include "supervisor/memory.h" #include "supervisor/port.h" -#include "supervisor/filesystem.h" +#include "supervisor/serial.h" #include "supervisor/shared/autoreload.h" -#include "supervisor/shared/translate.h" #include "supervisor/shared/rgb_led_status.h" #include "supervisor/shared/safe_mode.h" -#include "supervisor/shared/status_leds.h" #include "supervisor/shared/stack.h" +#include "supervisor/shared/status_leds.h" +#include "supervisor/shared/translate.h" #include "supervisor/shared/workflow.h" -#include "supervisor/serial.h" #include "supervisor/usb.h" #include "shared-bindings/microcontroller/__init__.h" @@ -66,6 +66,8 @@ #include "boards/board.h" +#include "esp_log.h" + #if CIRCUITPY_ALARM #include "shared-bindings/alarm/__init__.h" #endif @@ -101,26 +103,6 @@ // How long to flash errors on the RGB status LED before going to sleep (secs) #define CIRCUITPY_FLASH_ERROR_PERIOD 10 -void do_str(const char *src, mp_parse_input_kind_t input_kind) { - mp_lexer_t *lex = mp_lexer_new_from_str_len(MP_QSTR__lt_stdin_gt_, src, strlen(src), 0); - if (lex == NULL) { - //printf("MemoryError: lexer could not allocate memory\n"); - return; - } - - nlr_buf_t nlr; - if (nlr_push(&nlr) == 0) { - qstr source_name = lex->source_name; - mp_parse_tree_t parse_tree = mp_parse(lex, input_kind); - mp_obj_t module_fun = mp_compile(&parse_tree, source_name, MP_EMIT_OPT_NONE, true); - mp_call_function_0(module_fun); - nlr_pop(); - } else { - // uncaught exception - mp_obj_print_exception(&mp_plat_print, (mp_obj_t)nlr.ret_val); - } -} - #if MICROPY_ENABLE_PYSTACK static size_t PLACE_IN_DTCM_BSS(_pystack[CIRCUITPY_PYSTACK_SIZE / sizeof(size_t)]); #endif @@ -131,9 +113,13 @@ static void reset_devices(void) { #endif } -void start_mp(supervisor_allocation* heap) { +STATIC void start_mp(supervisor_allocation* heap) { reset_status_led(); autoreload_stop(); + supervisor_workflow_reset(); +#if CIRCUITPY_ALARM + alarm_reset(); +#endif // Stack limit should be less than real stack size, so we have a chance // to recover from limit hit. (Limit is measured in bytes.) @@ -182,7 +168,7 @@ void start_mp(supervisor_allocation* heap) { #endif } -void stop_mp(void) { +STATIC void stop_mp(void) { #if CIRCUITPY_NETWORK network_module_deinit(); #endif @@ -207,7 +193,7 @@ void stop_mp(void) { // Look for the first file that exists in the list of filenames, using mp_import_stat(). // Return its index. If no file found, return -1. -const char* first_existing_file_in_list(const char * const * filenames) { +STATIC const char* first_existing_file_in_list(const char * const * filenames) { for (int i = 0; filenames[i] != (char*)""; i++) { mp_import_stat_t stat = mp_import_stat(filenames[i]); if (stat == MP_IMPORT_STAT_FILE) { @@ -217,7 +203,7 @@ const char* first_existing_file_in_list(const char * const * filenames) { return NULL; } -bool maybe_run_list(const char * const * filenames, pyexec_result_t* exec_result) { +STATIC bool maybe_run_list(const char * const * filenames, pyexec_result_t* exec_result) { const char* filename = first_existing_file_in_list(filenames); if (filename == NULL) { return false; @@ -231,7 +217,7 @@ bool maybe_run_list(const char * const * filenames, pyexec_result_t* exec_result return true; } -void cleanup_after_vm(supervisor_allocation* heap) { +STATIC void cleanup_after_vm(supervisor_allocation* heap) { // Reset port-independent devices, like CIRCUITPY_BLEIO_HCI. reset_devices(); // Turn off the display and flush the fileystem before the heap disappears. @@ -260,7 +246,7 @@ void cleanup_after_vm(supervisor_allocation* heap) { reset_status_led(); } -void print_code_py_status_message(safe_mode_t safe_mode) { +STATIC void print_code_py_status_message(safe_mode_t safe_mode) { if (autoreload_is_enabled()) { serial_write_compressed(translate("Auto-reload is on. Simply save files over USB to run them or enter REPL to disable.\n")); } else { @@ -272,7 +258,7 @@ void print_code_py_status_message(safe_mode_t safe_mode) { } } -bool run_code_py(safe_mode_t safe_mode) { +STATIC bool run_code_py(safe_mode_t safe_mode) { bool serial_connected_at_start = serial_connected(); #if CIRCUITPY_AUTORELOAD_DELAY_MS > 0 if (serial_connected_at_start) { @@ -318,6 +304,8 @@ bool run_code_py(safe_mode_t safe_mode) { } } + // Program has finished running. + // Display a different completion message if the user has no USB attached (cannot save files) if (!serial_connected_at_start) { serial_write_compressed(translate("\nCode done running. Waiting for reload.\n")); @@ -329,11 +317,26 @@ bool run_code_py(safe_mode_t safe_mode) { #endif rgb_status_animation_t animation; bool ok = result.return_code != PYEXEC_EXCEPTION; - // If USB isn't enumerated then deep sleep. - if (ok && !supervisor_workflow_active() && supervisor_ticks_ms64() > CIRCUITPY_USB_ENUMERATION_DELAY * 1024) { - common_hal_mcu_deep_sleep(); - } - // Show the animation every N seconds. + + ESP_LOGI("main", "common_hal_alarm_enable_deep_sleep_alarms()"); + // Decide whether to deep sleep. + #if CIRCUITPY_ALARM + // Enable pin or time alarms before sleeping. + common_hal_alarm_enable_deep_sleep_alarms(); + #endif + + // Normally we won't deep sleep if there was an error or if we are connected to a host + // but either of those can be enabled. + // *********DON'T SLEEP IF USB HASN'T HAD TIME TO ENUMERATE. + bool will_deep_sleep = + (ok || supervisor_workflow_get_allow_deep_sleep_on_error()) && + (!supervisor_workflow_active() || supervisor_workflow_get_allow_deep_sleep_when_connected()); + + ESP_LOGI("main", "ok %d", will_deep_sleep); + ESP_LOGI("main", "...on_error() %d", supervisor_workflow_get_allow_deep_sleep_on_error()); + ESP_LOGI("main", "supervisor_workflow_active() %d", supervisor_workflow_active()); + ESP_LOGI("main", "...when_connected() %d", supervisor_workflow_get_allow_deep_sleep_when_connected()); + will_deep_sleep = false; prep_rgb_status_animation(&result, found_main, safe_mode, &animation); while (true) { RUN_BACKGROUND_TASKS; @@ -356,9 +359,12 @@ bool run_code_py(safe_mode_t safe_mode) { if (!serial_connected_at_start) { print_code_py_status_message(safe_mode); } - print_safe_mode_message(safe_mode); - serial_write("\n"); - serial_write_compressed(translate("Press any key to enter the REPL. Use CTRL-D to reload.")); + // We won't be going into the REPL if we're going to sleep. + if (!will_deep_sleep) { + print_safe_mode_message(safe_mode); + serial_write("\n"); + serial_write_compressed(translate("Press any key to enter the REPL. Use CTRL-D to reload.")); + } } if (serial_connected_before_animation && !serial_connected()) { serial_connected_at_start = false; @@ -371,16 +377,22 @@ bool run_code_py(safe_mode_t safe_mode) { refreshed_epaper_display = maybe_refresh_epaperdisplay(); } #endif - bool animation_done = tick_rgb_status_animation(&animation); - if (animation_done && supervisor_workflow_active()) { - #if CIRCUITPY_ALARM + + bool animation_done = false; + if (will_deep_sleep && ok) { + // Skip animation if everything is OK. + animation_done = true; + } else { + animation_done = tick_rgb_status_animation(&animation); + } + // Do an error animation only once before deep-sleeping. + if (animation_done && will_deep_sleep) { int64_t remaining_enumeration_wait = CIRCUITPY_USB_ENUMERATION_DELAY * 1024 - supervisor_ticks_ms64(); // If USB isn't enumerated then deep sleep after our waiting period. if (ok && remaining_enumeration_wait < 0) { common_hal_mcu_deep_sleep(); - return false; // Doesn't actually get here. + // Does not return. } - #endif // Wake up every so often to flash the error code. if (!ok) { port_interrupt_after_ticks(CIRCUITPY_FLASH_ERROR_PERIOD * 1024); @@ -394,7 +406,7 @@ bool run_code_py(safe_mode_t safe_mode) { FIL* boot_output_file; -void __attribute__ ((noinline)) run_boot_py(safe_mode_t safe_mode) { +STATIC void __attribute__ ((noinline)) run_boot_py(safe_mode_t safe_mode) { // If not in safe mode, run boot before initing USB and capture output in a // file. if (filesystem_present() && safe_mode == NO_SAFE_MODE && MP_STATE_VM(vfs_mount_table) != NULL) { @@ -473,7 +485,7 @@ void __attribute__ ((noinline)) run_boot_py(safe_mode_t safe_mode) { } } -int run_repl(void) { +STATIC int run_repl(void) { int exit_code = PYEXEC_FORCED_EXIT; stack_resize(); filesystem_flush(); diff --git a/ports/esp32s2/Makefile b/ports/esp32s2/Makefile index 55d6e91d44..794df0daba 100644 --- a/ports/esp32s2/Makefile +++ b/ports/esp32s2/Makefile @@ -332,10 +332,10 @@ $(BUILD)/firmware.uf2: $(BUILD)/circuitpython-firmware.bin $(Q)$(PYTHON3) $(TOP)/tools/uf2/utils/uf2conv.py -f 0xbfdd4eee -b 0x0000 -c -o $@ $^ flash: $(BUILD)/firmware.bin - esptool.py --chip esp32s2 -p $(PORT) --no-stub -b 460800 --before=default_reset --after=hard_reset write_flash $(FLASH_FLAGS) 0x0000 $^ + esptool.py --chip esp32s2 -p $(PORT) --no-stub -b 460800 --before=default_reset --after=no_reset write_flash $(FLASH_FLAGS) 0x0000 $^ flash-circuitpython-only: $(BUILD)/circuitpython-firmware.bin - esptool.py --chip esp32s2 -p $(PORT) --no-stub -b 460800 --before=default_reset --after=hard_reset write_flash $(FLASH_FLAGS) 0x10000 $^ + esptool.py --chip esp32s2 -p $(PORT) --no-stub -b 460800 --before=default_reset --after=no_reset write_flash $(FLASH_FLAGS) 0x10000 $^ include $(TOP)/py/mkrules.mk diff --git a/ports/esp32s2/common-hal/alarm/__init__.c b/ports/esp32s2/common-hal/alarm/__init__.c index 0ea476d860..87276bdaf0 100644 --- a/ports/esp32s2/common-hal/alarm/__init__.c +++ b/ports/esp32s2/common-hal/alarm/__init__.c @@ -95,7 +95,7 @@ void common_hal_alarm_set_deep_sleep_alarms(size_t n_alarms, const mp_obj_t *ala _deep_sleep_alarms = mp_obj_new_tuple(n_alarms, alarms); } -void common_hal_deep_sleep_with_alarms(void) { +void common_hal_alarm_enable_deep_sleep_alarms(void) { for (size_t i = 0; i < _deep_sleep_alarms->len; i++) { mp_obj_t alarm = _deep_sleep_alarms->items[i]; if (MP_OBJ_IS_TYPE(alarm, &alarm_time_duration_alarm_type)) { @@ -105,6 +105,4 @@ void common_hal_deep_sleep_with_alarms(void) { } // TODO: handle pin alarms } - - common_hal_mcu_deep_sleep(); } diff --git a/ports/esp32s2/common-hal/microcontroller/__init__.c b/ports/esp32s2/common-hal/microcontroller/__init__.c index 59eb1afcc0..5aa0ff8eda 100644 --- a/ports/esp32s2/common-hal/microcontroller/__init__.c +++ b/ports/esp32s2/common-hal/microcontroller/__init__.c @@ -80,11 +80,9 @@ void common_hal_mcu_reset(void) { while(1); } -void common_hal_mcu_deep_sleep(void) { +void NORETURN common_hal_mcu_deep_sleep(void) { // Shut down wifi cleanly. esp_wifi_stop(); - - // Does not return. esp_deep_sleep_start(); } diff --git a/py/circuitpy_defns.mk b/py/circuitpy_defns.mk index 2731f2ae8d..27466282a8 100644 --- a/py/circuitpy_defns.mk +++ b/py/circuitpy_defns.mk @@ -403,6 +403,7 @@ $(filter $(SRC_PATTERNS), \ math/__init__.c \ microcontroller/ResetReason.c \ microcontroller/RunMode.c \ + supervisor/RunReason.c \ ) SRC_BINDINGS_ENUMS += \ diff --git a/shared-bindings/alarm/__init__.h b/shared-bindings/alarm/__init__.h index c74dfbe5c3..d8d6812c90 100644 --- a/shared-bindings/alarm/__init__.h +++ b/shared-bindings/alarm/__init__.h @@ -29,7 +29,10 @@ #include "py/obj.h" +#include "common-hal/alarm/__init__.h" + extern mp_obj_t common_hal_alarm_sleep_until_alarms(size_t n_alarms, const mp_obj_t *alarms); +extern void common_hal_alarm_enable_deep_sleep_alarms(void); extern void common_hal_alarm_set_deep_sleep_alarms(size_t n_alarms, const mp_obj_t *alarms); // Used by wake-up code. diff --git a/shared-bindings/microcontroller/__init__.c b/shared-bindings/microcontroller/__init__.c index d6ce323c58..d09cf8f445 100644 --- a/shared-bindings/microcontroller/__init__.c +++ b/shared-bindings/microcontroller/__init__.c @@ -56,19 +56,6 @@ //| This object is the sole instance of `microcontroller.Processor`.""" //| -//| def deep_sleep() -> None: -//| Go into deep sleep. If the board is connected via USB, disconnect USB first. -//| -//| The board will awake from deep sleep only if the reset button is pressed -//| or it is awoken by an alarm set by `alarm.set_deep_sleep_alarms()`. -//| ... -//| -STATIC mp_obj_t mcu_deep_sleep(void){ - - return mp_const_none; -} -MP_DEFINE_CONST_FUN_OBJ_0(mcu_deep_sleep_obj, mcu_deep_sleep); - //| def delay_us(delay: int) -> None: //| """Dedicated delay method used for very short delays. **Do not** do long delays //| because this stops all other functions from completing. Think of this as an empty @@ -177,7 +164,6 @@ const mp_obj_module_t mcu_pin_module = { STATIC const mp_rom_map_elem_t mcu_module_globals_table[] = { { MP_ROM_QSTR(MP_QSTR___name__), MP_ROM_QSTR(MP_QSTR_microcontroller) }, { MP_ROM_QSTR(MP_QSTR_cpu), MP_ROM_PTR(&common_hal_mcu_processor_obj) }, - { MP_ROM_QSTR(MP_QSTR_deep_sleep), MP_ROM_PTR(&mcu_deep_sleep_obj) }, { MP_ROM_QSTR(MP_QSTR_delay_us), MP_ROM_PTR(&mcu_delay_us_obj) }, { MP_ROM_QSTR(MP_QSTR_disable_interrupts), MP_ROM_PTR(&mcu_disable_interrupts_obj) }, { MP_ROM_QSTR(MP_QSTR_enable_interrupts), MP_ROM_PTR(&mcu_enable_interrupts_obj) }, diff --git a/shared-bindings/microcontroller/__init__.h b/shared-bindings/microcontroller/__init__.h index c6ccccea72..87284fc2e5 100644 --- a/shared-bindings/microcontroller/__init__.h +++ b/shared-bindings/microcontroller/__init__.h @@ -43,7 +43,7 @@ extern void common_hal_mcu_enable_interrupts(void); extern void common_hal_mcu_on_next_reset(mcu_runmode_t runmode); extern void common_hal_mcu_reset(void); -extern void common_hal_mcu_deep_sleep(void); +extern void NORETURN common_hal_mcu_deep_sleep(void); extern const mp_obj_dict_t mcu_pin_globals; diff --git a/shared-bindings/supervisor/RunReason.c b/shared-bindings/supervisor/RunReason.c index 7e7a74d2f4..73f62fed6d 100644 --- a/shared-bindings/supervisor/RunReason.c +++ b/shared-bindings/supervisor/RunReason.c @@ -29,7 +29,7 @@ #include "shared-bindings/supervisor/RunReason.h" MAKE_ENUM_VALUE(supervisor_run_reason_type, run_reason, STARTUP, RUN_REASON_STARTUP); -MAKE_ENUM_VALUE(supervisor_run_reason_type, run_reason, AUTORELOAD, RUN_REASON_AUTO_RELOAD); +MAKE_ENUM_VALUE(supervisor_run_reason_type, run_reason, AUTO_RELOAD, RUN_REASON_AUTO_RELOAD); MAKE_ENUM_VALUE(supervisor_run_reason_type, run_reason, SUPERVISOR_RELOAD, RUN_REASON_SUPERVISOR_RELOAD); MAKE_ENUM_VALUE(supervisor_run_reason_type, run_reason, REPL_RELOAD, RUN_REASON_REPL_RELOAD); @@ -49,7 +49,7 @@ MAKE_ENUM_VALUE(supervisor_run_reason_type, run_reason, REPL_RELOAD, RUN_REASON_ //| REPL_RELOAD: object //| """CircuitPython started due to the user typing CTRL-D in the REPL.""" //| -MAKE_ENUM_MAP(run_reason) { +MAKE_ENUM_MAP(supervisor_run_reason) { MAKE_ENUM_MAP_ENTRY(run_reason, STARTUP), MAKE_ENUM_MAP_ENTRY(run_reason, AUTO_RELOAD), MAKE_ENUM_MAP_ENTRY(run_reason, SUPERVISOR_RELOAD), diff --git a/shared-bindings/supervisor/Runtime.c b/shared-bindings/supervisor/Runtime.c index 67193e051e..1a283b35c0 100755 --- a/shared-bindings/supervisor/Runtime.c +++ b/shared-bindings/supervisor/Runtime.c @@ -25,8 +25,11 @@ */ #include +#include "py/obj.h" #include "py/enum.h" +#include "py/runtime.h" #include "py/objproperty.h" + #include "shared-bindings/supervisor/RunReason.h" #include "shared-bindings/supervisor/Runtime.h" diff --git a/shared-bindings/supervisor/__init__.c b/shared-bindings/supervisor/__init__.c index 4d2d6db309..c13b19e48e 100644 --- a/shared-bindings/supervisor/__init__.c +++ b/shared-bindings/supervisor/__init__.c @@ -32,7 +32,9 @@ #include "supervisor/shared/rgb_led_status.h" #include "supervisor/shared/stack.h" #include "supervisor/shared/translate.h" +#include "supervisor/shared/workflow.h" +#include "shared-bindings/microcontroller/__init__.h" #include "shared-bindings/supervisor/__init__.h" #include "shared-bindings/supervisor/Runtime.h" @@ -45,6 +47,47 @@ //| This object is the sole instance of `supervisor.Runtime`.""" //| +//| def allow_deep_sleep(*, when_connected: bool = False, on_error: bool = False): +//| """Configure when CircuitPython can go into deep sleep. Deep sleep can occur +//| after a program has finished running or when `supervisor.deep_sleep_now()` is called. +//| +//| :param bool when_connected: If ``True``, CircuitPython will go into deep sleep +//| when a program finishes, even if it is connected to a host computer over USB or other means. +//| It will disconnect from the host before sleeping. +//| If ``False``, deep sleep will not be entered if connected. +//| :param bool on_error: If ``True``, deep sleep will be entered if even a program +//| terminated due to an exception or fatal error. If ``False``, an error will cause +//| CircuitPython to stay awake, flashing error codes on the status RGB LED, if available. +//| ... +//| +STATIC mp_obj_t supervisor_allow_deep_sleep(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) { + enum { ARG_when_connected, ARG_on_error }; + static const mp_arg_t allowed_args[] = { + { MP_QSTR_when_connected, MP_ARG_KW_ONLY | MP_ARG_BOOL, {.u_bool = false} }, + { MP_QSTR_on_error, MP_ARG_KW_ONLY | MP_ARG_BOOL, {.u_bool = false} }, + }; + + mp_arg_val_t args[MP_ARRAY_SIZE(allowed_args)]; + mp_arg_parse_all(n_args, pos_args, kw_args, MP_ARRAY_SIZE(allowed_args), allowed_args, args); + + supervisor_workflow_set_allow_deep_sleep_when_connected(args[ARG_when_connected].u_bool); + supervisor_workflow_set_allow_deep_sleep_on_error(args[ARG_on_error].u_bool); + + return mp_const_none; +} +MP_DEFINE_CONST_FUN_OBJ_KW(supervisor_allow_deep_sleep_obj, 0, supervisor_allow_deep_sleep); + +//| def deep_sleep(): -> None +//| """Go into deep sleep mode immediately, if not connected to a host computer. +//| But if connected and `supervisor.runtime.allow_deep_sleep(when_connected=true)` +//| has not been called, simply restart. +//| + +STATIC mp_obj_t supervisor_deep_sleep(void) { + common_hal_mcu_deep_sleep(); +} +MP_DEFINE_CONST_FUN_OBJ_0(supervisor_deep_sleep_obj, supervisor_deep_sleep); + //| def enable_autoreload() -> None: //| """Enable autoreload based on USB file write activity.""" //| ... @@ -112,9 +155,11 @@ MP_DEFINE_CONST_FUN_OBJ_1(supervisor_set_next_stack_limit_obj, supervisor_set_ne STATIC const mp_rom_map_elem_t supervisor_module_globals_table[] = { { MP_ROM_QSTR(MP_QSTR___name__), MP_ROM_QSTR(MP_QSTR_supervisor) }, - { MP_OBJ_NEW_QSTR(MP_QSTR_enable_autoreload), MP_ROM_PTR(&supervisor_enable_autoreload_obj) }, - { MP_OBJ_NEW_QSTR(MP_QSTR_disable_autoreload), MP_ROM_PTR(&supervisor_disable_autoreload_obj) }, - { MP_OBJ_NEW_QSTR(MP_QSTR_set_rgb_status_brightness), MP_ROM_PTR(&supervisor_set_rgb_status_brightness_obj) }, + { MP_ROM_QSTR(MP_QSTR_allow_deep_sleep), MP_ROM_PTR(&supervisor_allow_deep_sleep_obj) }, + { MP_ROM_QSTR(MP_QSTR_deep_sleep), MP_ROM_PTR(&supervisor_deep_sleep_obj) }, + { MP_ROM_QSTR(MP_QSTR_enable_autoreload), MP_ROM_PTR(&supervisor_enable_autoreload_obj) }, + { MP_ROM_QSTR(MP_QSTR_disable_autoreload), MP_ROM_PTR(&supervisor_disable_autoreload_obj) }, + { MP_ROM_QSTR(MP_QSTR_set_rgb_status_brightness), MP_ROM_PTR(&supervisor_set_rgb_status_brightness_obj) }, { MP_ROM_QSTR(MP_QSTR_runtime), MP_ROM_PTR(&common_hal_supervisor_runtime_obj) }, { MP_ROM_QSTR(MP_QSTR_reload), MP_ROM_PTR(&supervisor_reload_obj) }, { MP_ROM_QSTR(MP_QSTR_set_next_stack_limit), MP_ROM_PTR(&supervisor_set_next_stack_limit_obj) }, diff --git a/supervisor/shared/workflow.c b/supervisor/shared/workflow.c index 41af22eb70..67d191172f 100644 --- a/supervisor/shared/workflow.c +++ b/supervisor/shared/workflow.c @@ -25,10 +25,36 @@ */ #include +#include "py/mpconfig.h" #include "tusb.h" +STATIC bool _allow_deep_sleep_when_connected; +STATIC bool _allow_deep_sleep_on_error; + + +void supervisor_workflow_reset(void) { + _allow_deep_sleep_when_connected = false; + _allow_deep_sleep_on_error = false; +} + bool supervisor_workflow_active(void) { // Eventually there might be other non-USB workflows, such as BLE. // tud_ready() checks for usb mounted and not suspended. return tud_ready(); } + +bool supervisor_workflow_get_allow_deep_sleep_when_connected(void) { + return _allow_deep_sleep_when_connected; +} + +void supervisor_workflow_set_allow_deep_sleep_when_connected(bool allow) { + _allow_deep_sleep_when_connected = allow; +} + +bool supervisor_workflow_get_allow_deep_sleep_on_error(void) { + return _allow_deep_sleep_on_error; +} + +void supervisor_workflow_set_allow_deep_sleep_on_error(bool allow) { + _allow_deep_sleep_on_error = allow; +} diff --git a/supervisor/shared/workflow.h b/supervisor/shared/workflow.h index 2968961f48..97584a1f46 100644 --- a/supervisor/shared/workflow.h +++ b/supervisor/shared/workflow.h @@ -26,6 +26,12 @@ #pragma once -extern volatile bool _workflow_active; +extern void supervisor_workflow_reset(void); extern bool supervisor_workflow_active(void); + +extern bool supervisor_workflow_get_allow_deep_sleep_when_connected(void); +extern void supervisor_workflow_set_allow_deep_sleep_when_connected(bool allow); + +extern bool supervisor_workflow_get_allow_deep_sleep_on_error(void); +extern void supervisor_workflow_set_allow_deep_sleep_on_error(bool allow); From f868cc5dd02319957500180541281f41ec0d0573 Mon Sep 17 00:00:00 2001 From: Dan Halbert Date: Tue, 24 Nov 2020 23:36:59 -0500 Subject: [PATCH 25/34] some API renaming and bug fixes; fix docs --- main.c | 48 ++++++++++++--------- shared-bindings/alarm/__init__.c | 4 +- shared-bindings/alarm/pin/PinAlarm.c | 34 +++++++-------- shared-bindings/alarm/time/DurationAlarm.c | 6 +-- shared-bindings/microcontroller/Processor.c | 4 +- shared-bindings/supervisor/RunReason.c | 2 +- shared-bindings/supervisor/Runtime.c | 2 +- shared-bindings/supervisor/__init__.c | 37 ++++++++-------- 8 files changed, 72 insertions(+), 65 deletions(-) diff --git a/main.c b/main.c index b2e527ddef..10066bd92f 100755 --- a/main.c +++ b/main.c @@ -98,7 +98,7 @@ #endif // How long to wait for host to enumerate (secs). -#define CIRCUITPY_USB_ENUMERATION_DELAY 1 +#define CIRCUITPY_USB_ENUMERATION_DELAY 5 // How long to flash errors on the RGB status LED before going to sleep (secs) #define CIRCUITPY_FLASH_ERROR_PERIOD 10 @@ -319,26 +319,28 @@ STATIC bool run_code_py(safe_mode_t safe_mode) { bool ok = result.return_code != PYEXEC_EXCEPTION; ESP_LOGI("main", "common_hal_alarm_enable_deep_sleep_alarms()"); - // Decide whether to deep sleep. #if CIRCUITPY_ALARM // Enable pin or time alarms before sleeping. common_hal_alarm_enable_deep_sleep_alarms(); #endif - // Normally we won't deep sleep if there was an error or if we are connected to a host - // but either of those can be enabled. - // *********DON'T SLEEP IF USB HASN'T HAD TIME TO ENUMERATE. - bool will_deep_sleep = - (ok || supervisor_workflow_get_allow_deep_sleep_on_error()) && - (!supervisor_workflow_active() || supervisor_workflow_get_allow_deep_sleep_when_connected()); - ESP_LOGI("main", "ok %d", will_deep_sleep); - ESP_LOGI("main", "...on_error() %d", supervisor_workflow_get_allow_deep_sleep_on_error()); - ESP_LOGI("main", "supervisor_workflow_active() %d", supervisor_workflow_active()); - ESP_LOGI("main", "...when_connected() %d", supervisor_workflow_get_allow_deep_sleep_when_connected()); - will_deep_sleep = false; prep_rgb_status_animation(&result, found_main, safe_mode, &animation); while (true) { + // Normally we won't deep sleep if there was an error or if we are connected to a host + // but either of those can be enabled. + // It's ok to deep sleep if we're not connected to a host, but we need to make sure + // we're giving enough time for USB enumeration to happen. + bool deep_sleep_allowed = + (ok || supervisor_workflow_get_allow_deep_sleep_on_error()) && + (!supervisor_workflow_active() || supervisor_workflow_get_allow_deep_sleep_when_connected()) && + (supervisor_ticks_ms64() > CIRCUITPY_USB_ENUMERATION_DELAY * 1024); + + ESP_LOGI("main", "ok %d", deep_sleep_allowed); + ESP_LOGI("main", "...on_error() %d", supervisor_workflow_get_allow_deep_sleep_on_error()); + ESP_LOGI("main", "supervisor_workflow_active() %d", supervisor_workflow_active()); + ESP_LOGI("main", "...when_connected() %d", supervisor_workflow_get_allow_deep_sleep_when_connected()); + ESP_LOGI("main", "supervisor_ticks_ms64() %lld", supervisor_ticks_ms64()); RUN_BACKGROUND_TASKS; if (reload_requested) { supervisor_set_run_reason(RUN_REASON_AUTO_RELOAD); @@ -360,7 +362,7 @@ STATIC bool run_code_py(safe_mode_t safe_mode) { print_code_py_status_message(safe_mode); } // We won't be going into the REPL if we're going to sleep. - if (!will_deep_sleep) { + if (!deep_sleep_allowed) { print_safe_mode_message(safe_mode); serial_write("\n"); serial_write_compressed(translate("Press any key to enter the REPL. Use CTRL-D to reload.")); @@ -379,27 +381,31 @@ STATIC bool run_code_py(safe_mode_t safe_mode) { #endif bool animation_done = false; - if (will_deep_sleep && ok) { + + if (deep_sleep_allowed && ok) { // Skip animation if everything is OK. animation_done = true; } else { animation_done = tick_rgb_status_animation(&animation); } // Do an error animation only once before deep-sleeping. - if (animation_done && will_deep_sleep) { - int64_t remaining_enumeration_wait = CIRCUITPY_USB_ENUMERATION_DELAY * 1024 - supervisor_ticks_ms64(); - // If USB isn't enumerated then deep sleep after our waiting period. - if (ok && remaining_enumeration_wait < 0) { + if (animation_done) { + if (deep_sleep_allowed) { common_hal_mcu_deep_sleep(); // Does not return. } + // Wake up every so often to flash the error code. if (!ok) { port_interrupt_after_ticks(CIRCUITPY_FLASH_ERROR_PERIOD * 1024); } else { - port_interrupt_after_ticks(remaining_enumeration_wait); + int64_t remaining_enumeration_wait = + CIRCUITPY_USB_ENUMERATION_DELAY * 1024 - supervisor_ticks_ms64(); + if (remaining_enumeration_wait > 0) { + port_interrupt_after_ticks(remaining_enumeration_wait); + } + port_sleep_until_interrupt(); } - port_sleep_until_interrupt(); } } } diff --git a/shared-bindings/alarm/__init__.c b/shared-bindings/alarm/__init__.c index 22b2e7f6ab..b6b86c8354 100644 --- a/shared-bindings/alarm/__init__.c +++ b/shared-bindings/alarm/__init__.c @@ -38,7 +38,7 @@ //| //| Light sleep leaves the CPU and RAM powered so that CircuitPython can resume where it left off //| after being woken up. CircuitPython automatically goes into a light sleep when `time.sleep()` is -//| called. To light sleep until a non-time alarm use `alarm.sleep_until_alarm()`. Any active +//| called. To light sleep until a non-time alarm use `alarm.sleep_until_alarms()`. Any active //| peripherals, such as I2C, are left on. //| //| Deep sleep shuts down power to nearly all of the chip including the CPU and RAM. This can save @@ -51,7 +51,7 @@ //| //| An error includes an uncaught exception, or sys.exit() called with a non-zero argument //| -//| To set alarms for deep sleep use `alarm.restart_on_alarm()` they will apply to next deep sleep only.""" +//| To set alarms for deep sleep use `alarm.set_deep_sleep_alarms()` they will apply to next deep sleep only.""" //| //| wake_alarm: Alarm //| """The most recent alarm to wake us up from a sleep (light or deep.)""" diff --git a/shared-bindings/alarm/pin/PinAlarm.c b/shared-bindings/alarm/pin/PinAlarm.c index a2d2e0ab7a..bb48b93c42 100644 --- a/shared-bindings/alarm/pin/PinAlarm.c +++ b/shared-bindings/alarm/pin/PinAlarm.c @@ -38,26 +38,26 @@ //| """Trigger an alarm when a pin changes state.""" //| //| def __init__(self, *pins: microcontroller.Pin, value: bool, all_same_value: bool = False, edge: bool = False, pull: bool = False) -> None: -//| """Create an alarm triggered by a `~microcontroller.Pin` level. The alarm is not active -//| until it is listed in an `alarm`-enabling function, such as `alarm.sleep_until_alarm()` or -//| `alarm.restart_on_alarm()`. +//| """Create an alarm triggered by a `microcontroller.Pin` level. The alarm is not active +//| until it is listed in an `alarm`-enabling function, such as `alarm.sleep_until_alarms()` or +//| `alarm.set_deep_sleep_alarms()`. //| -//| :param pins: The pins to monitor. On some ports, the choice of pins -//| may be limited due to hardware restrictions, particularly for deep-sleep alarms. +//| :param microcontroller.Pin \*pins: The pins to monitor. On some ports, the choice of pins +//| may be limited due to hardware restrictions, particularly for deep-sleep alarms. //| :param bool value: When active, trigger when the pin value is high (``True``) or low (``False``). -//| On some ports, multiple `PinAlarm` objects may need to have coordinated values -//| for deep-sleep alarms. -//| :param bool all_same_value: If ``True``, all pins listed must be at `value` to trigger the alarm. -//| If ``False``, any one of the pins going to `value` will trigger the alarm. +//| On some ports, multiple `PinAlarm` objects may need to have coordinated values +//| for deep-sleep alarms. +//| :param bool all_same_value: If ``True``, all pins listed must be at ``value`` to trigger the alarm. +//| If ``False``, any one of the pins going to ``value`` will trigger the alarm. //| :param bool edge: If ``True``, trigger only when there is a transition to the specified -//| value of `value`. If ``True``, if the alarm becomes active when the pin value already -//| matches `value`, the alarm is not triggered: the pin must transition from ``not value`` -//| to ``value`` to trigger the alarm. On some ports, edge-triggering may not be available, -//| particularly for deep-sleep alarms. -//| :param bool pull: Enable a pull-up or pull-down which pulls the pin to value opposite -//| opposite that of `value`. For instance, if `value` is set to ``True``, setting `pull` -//| to ``True`` will enable a pull-down, to hold the pin low normally until an outside signal -//| pulls it high. +//| value of ``value``. If ``True``, if the alarm becomes active when the pin value already +//| matches ``value``, the alarm is not triggered: the pin must transition from ``not value`` +//| to ``value`` to trigger the alarm. On some ports, edge-triggering may not be available, +//| particularly for deep-sleep alarms. +//| :param bool pull: Enable a pull-up or pull-down which pulls the pin to the level opposite +//| opposite that of ``value``. For instance, if ``value`` is set to ``True``, setting ``pull`` +//| to ``True`` will enable a pull-down, to hold the pin low normally until an outside signal +//| pulls it high. //| """ //| ... //| diff --git a/shared-bindings/alarm/time/DurationAlarm.c b/shared-bindings/alarm/time/DurationAlarm.c index c105bbebf7..6831aba5db 100644 --- a/shared-bindings/alarm/time/DurationAlarm.c +++ b/shared-bindings/alarm/time/DurationAlarm.c @@ -37,10 +37,10 @@ //| """Trigger an alarm at a specified interval from now.""" //| //| def __init__(self, secs: float) -> None: -//| """Create an alarm that will be triggered in `secs` seconds from the time +//| """Create an alarm that will be triggered in ``secs`` seconds from the time //| sleep starts. The alarm is not active until it is listed in an -//| `alarm`-enabling function, such as `alarm.sleep_until_alarm()` or -//| `alarm.restart_on_alarm()`. +//| `alarm`-enabling function, such as `alarm.sleep_until_alarms()` or +//| `alarm.set_deep_sleep_alarms()`. //| """ //| ... //| diff --git a/shared-bindings/microcontroller/Processor.c b/shared-bindings/microcontroller/Processor.c index ea43688213..90cc02fe39 100644 --- a/shared-bindings/microcontroller/Processor.c +++ b/shared-bindings/microcontroller/Processor.c @@ -67,8 +67,8 @@ const mp_obj_property_t mcu_processor_frequency_obj = { }, }; -//| reset_reason: `microcontroller.ResetReason` -//| """The reason the microcontroller started up from reset state.""" +//| reset_reason: microcontroller.ResetReason +//| """The reason the microcontroller started up from reset state.""" //| STATIC mp_obj_t mcu_processor_get_reset_reason(mp_obj_t self) { return cp_enum_find(&mcu_reset_reason_type, common_hal_mcu_processor_get_reset_reason()); diff --git a/shared-bindings/supervisor/RunReason.c b/shared-bindings/supervisor/RunReason.c index 73f62fed6d..a2a5fe13ef 100644 --- a/shared-bindings/supervisor/RunReason.c +++ b/shared-bindings/supervisor/RunReason.c @@ -37,7 +37,7 @@ MAKE_ENUM_VALUE(supervisor_run_reason_type, run_reason, REPL_RELOAD, RUN_REASON_ //| """The reason that CircuitPython started running.""" //| //| STARTUP: object -//| """CircuitPython started the microcontroller started up. See `microcontroller.cpu.reset_reason` +//| """CircuitPython started the microcontroller started up. See `microcontroller.Processor.reset_reason` //| for more detail on why the microcontroller was started.""" //| //| AUTO_RELOAD: object diff --git a/shared-bindings/supervisor/Runtime.c b/shared-bindings/supervisor/Runtime.c index 1a283b35c0..8e0259a3b3 100755 --- a/shared-bindings/supervisor/Runtime.c +++ b/shared-bindings/supervisor/Runtime.c @@ -98,7 +98,7 @@ const mp_obj_property_t supervisor_serial_bytes_available_obj = { //| run_reason: RunReason -//| """Returns why CircuitPython started running this particular time. +//| """Returns why CircuitPython started running this particular time.""" //| STATIC mp_obj_t supervisor_get_run_reason(mp_obj_t self) { return cp_enum_find(&supervisor_run_reason_type, _run_reason); diff --git a/shared-bindings/supervisor/__init__.c b/shared-bindings/supervisor/__init__.c index c13b19e48e..9a7890a87d 100644 --- a/shared-bindings/supervisor/__init__.c +++ b/shared-bindings/supervisor/__init__.c @@ -47,18 +47,19 @@ //| This object is the sole instance of `supervisor.Runtime`.""" //| -//| def allow_deep_sleep(*, when_connected: bool = False, on_error: bool = False): -//| """Configure when CircuitPython can go into deep sleep. Deep sleep can occur -//| after a program has finished running or when `supervisor.deep_sleep_now()` is called. +//| def allow_deep_sleep(*, when_connected: bool = False, on_error: bool = False) -> None: +//| """Configure when CircuitPython can go into deep sleep. Deep sleep can occur +//| after a program has finished running or when `supervisor.exit_and_deep_sleep()` is called. //| -//| :param bool when_connected: If ``True``, CircuitPython will go into deep sleep -//| when a program finishes, even if it is connected to a host computer over USB or other means. -//| It will disconnect from the host before sleeping. -//| If ``False``, deep sleep will not be entered if connected. -//| :param bool on_error: If ``True``, deep sleep will be entered if even a program -//| terminated due to an exception or fatal error. If ``False``, an error will cause -//| CircuitPython to stay awake, flashing error codes on the status RGB LED, if available. -//| ... +//| :param bool when_connected: If ``True``, CircuitPython will go into deep sleep +//| when a program finishes, even if it is connected to a host computer over USB or other means. +//| It will disconnect from the host before sleeping. +//| If ``False``, deep sleep will not be entered if connected. +//| :param bool on_error: If ``True``, deep sleep will be entered if even a program +//| terminated due to an exception or fatal error. If ``False``, an error will cause +//| CircuitPython to stay awake, flashing error codes on the status RGB LED, if available. +//| """ +//| ... //| STATIC mp_obj_t supervisor_allow_deep_sleep(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) { enum { ARG_when_connected, ARG_on_error }; @@ -77,16 +78,16 @@ STATIC mp_obj_t supervisor_allow_deep_sleep(size_t n_args, const mp_obj_t *pos_a } MP_DEFINE_CONST_FUN_OBJ_KW(supervisor_allow_deep_sleep_obj, 0, supervisor_allow_deep_sleep); -//| def deep_sleep(): -> None +//| def exit_and_deep_sleep() -> None: //| """Go into deep sleep mode immediately, if not connected to a host computer. -//| But if connected and `supervisor.runtime.allow_deep_sleep(when_connected=true)` -//| has not been called, simply restart. -//| +//| But if connected and ``supervisor.allow_deep_sleep(when_connected=true)`` +//| has not been called, simply restart.""" +//| ... -STATIC mp_obj_t supervisor_deep_sleep(void) { +STATIC mp_obj_t supervisor_exit_and_deep_sleep(void) { common_hal_mcu_deep_sleep(); } -MP_DEFINE_CONST_FUN_OBJ_0(supervisor_deep_sleep_obj, supervisor_deep_sleep); +MP_DEFINE_CONST_FUN_OBJ_0(supervisor_exit_and_deep_sleep_obj, supervisor_exit_and_deep_sleep); //| def enable_autoreload() -> None: //| """Enable autoreload based on USB file write activity.""" @@ -156,7 +157,7 @@ MP_DEFINE_CONST_FUN_OBJ_1(supervisor_set_next_stack_limit_obj, supervisor_set_ne STATIC const mp_rom_map_elem_t supervisor_module_globals_table[] = { { MP_ROM_QSTR(MP_QSTR___name__), MP_ROM_QSTR(MP_QSTR_supervisor) }, { MP_ROM_QSTR(MP_QSTR_allow_deep_sleep), MP_ROM_PTR(&supervisor_allow_deep_sleep_obj) }, - { MP_ROM_QSTR(MP_QSTR_deep_sleep), MP_ROM_PTR(&supervisor_deep_sleep_obj) }, + { MP_ROM_QSTR(MP_QSTR_exit_and_deep_sleep), MP_ROM_PTR(&supervisor_exit_and_deep_sleep_obj) }, { MP_ROM_QSTR(MP_QSTR_enable_autoreload), MP_ROM_PTR(&supervisor_enable_autoreload_obj) }, { MP_ROM_QSTR(MP_QSTR_disable_autoreload), MP_ROM_PTR(&supervisor_disable_autoreload_obj) }, { MP_ROM_QSTR(MP_QSTR_set_rgb_status_brightness), MP_ROM_PTR(&supervisor_set_rgb_status_brightness_obj) }, From 9dbea36eac9a78cf324bba8d32a5cb2c9940d411 Mon Sep 17 00:00:00 2001 From: Dan Halbert Date: Wed, 25 Nov 2020 15:07:57 -0500 Subject: [PATCH 26/34] changed alarm.time API --- locale/circuitpython.pot | 29 +++--- main.c | 7 +- ports/esp32s2/common-hal/alarm/__init__.c | 33 +++++-- ports/esp32s2/common-hal/alarm/pin/PinAlarm.c | 3 +- .../{DurationAlarm.c => MonotonicTimeAlarm.c} | 22 +---- .../{DurationAlarm.h => MonotonicTimeAlarm.h} | 5 +- py/circuitpy_defns.mk | 2 +- py/obj.h | 1 + py/objfloat.c | 7 ++ shared-bindings/alarm/__init__.c | 10 +- shared-bindings/alarm/__init__.h | 2 +- shared-bindings/alarm/pin/PinAlarm.c | 37 +++++++- shared-bindings/alarm/pin/PinAlarm.h | 4 +- shared-bindings/alarm/time/DurationAlarm.c | 91 ------------------ .../alarm/time/MonotonicTimeAlarm.c | 93 +++++++++++++++++++ .../{DurationAlarm.h => MonotonicTimeAlarm.h} | 17 ++-- shared-bindings/time/__init__.c | 4 +- 17 files changed, 209 insertions(+), 158 deletions(-) rename ports/esp32s2/common-hal/alarm/time/{DurationAlarm.c => MonotonicTimeAlarm.c} (61%) rename ports/esp32s2/common-hal/alarm/time/{DurationAlarm.h => MonotonicTimeAlarm.h} (91%) delete mode 100644 shared-bindings/alarm/time/DurationAlarm.c create mode 100644 shared-bindings/alarm/time/MonotonicTimeAlarm.c rename shared-bindings/alarm/time/{DurationAlarm.h => MonotonicTimeAlarm.h} (63%) diff --git a/locale/circuitpython.pot b/locale/circuitpython.pot index 1dae9547a3..b59a5f77e4 100644 --- a/locale/circuitpython.pot +++ b/locale/circuitpython.pot @@ -8,7 +8,7 @@ msgid "" msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2020-11-21 12:36-0500\n" +"POT-Creation-Date: 2020-11-25 15:08-0500\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language-Team: LANGUAGE \n" @@ -17,13 +17,6 @@ msgstr "" "Content-Type: text/plain; charset=CHARSET\n" "Content-Transfer-Encoding: 8bit\n" -#: main.c -msgid "" -"\n" -"\n" -"------ soft reboot ------\n" -msgstr "" - #: main.c msgid "" "\n" @@ -849,6 +842,10 @@ msgstr "" msgid "Expected an Address" msgstr "" +#: shared-bindings/alarm/__init__.c +msgid "Expected an alarm" +msgstr "" + #: shared-module/_pixelbuf/PixelBuf.c #, c-format msgid "Expected tuple of length %d, got %d" @@ -1440,6 +1437,10 @@ msgid "" "%d bpp given" msgstr "" +#: ports/esp32s2/common-hal/alarm/__init__.c +msgid "Only one alarm.time alarm can be set." +msgstr "" + #: shared-module/displayio/ColorConverter.c msgid "Only one color can be transparent at a time" msgstr "" @@ -1497,6 +1498,10 @@ msgstr "" msgid "Pin number already reserved by EXTI" msgstr "" +#: ports/esp32s2/common-hal/alarm/__init__.c +msgid "PinAlarm deep sleep not yet implemented" +msgstr "" + #: shared-bindings/rgbmatrix/RGBMatrix.c #, c-format msgid "" @@ -2449,10 +2454,6 @@ msgstr "" msgid "division by zero" msgstr "" -#: ports/esp32s2/common-hal/alarm/time/DurationAlarm.c -msgid "duration out of range" -msgstr "" - #: py/objdeque.c msgid "empty" msgstr "" @@ -3354,6 +3355,10 @@ msgstr "" msgid "small int overflow" msgstr "" +#: main.c +msgid "soft reboot\n" +msgstr "" + #: extmod/ulab/code/numerical/numerical.c msgid "sort argument must be an ndarray" msgstr "" diff --git a/main.c b/main.c index 10066bd92f..d52f840185 100755 --- a/main.c +++ b/main.c @@ -321,7 +321,9 @@ STATIC bool run_code_py(safe_mode_t safe_mode) { ESP_LOGI("main", "common_hal_alarm_enable_deep_sleep_alarms()"); #if CIRCUITPY_ALARM // Enable pin or time alarms before sleeping. - common_hal_alarm_enable_deep_sleep_alarms(); + // If immediate_wake is true, then there's alarm that would trigger immediately, + // so don't sleep. + bool immediate_wake = !common_hal_alarm_enable_deep_sleep_alarms(); #endif @@ -332,6 +334,7 @@ STATIC bool run_code_py(safe_mode_t safe_mode) { // It's ok to deep sleep if we're not connected to a host, but we need to make sure // we're giving enough time for USB enumeration to happen. bool deep_sleep_allowed = + !immediate_wake && (ok || supervisor_workflow_get_allow_deep_sleep_on_error()) && (!supervisor_workflow_active() || supervisor_workflow_get_allow_deep_sleep_when_connected()) && (supervisor_ticks_ms64() > CIRCUITPY_USB_ENUMERATION_DELAY * 1024); @@ -576,7 +579,7 @@ int __attribute__((used)) main(void) { } if (exit_code == PYEXEC_FORCED_EXIT) { if (!first_run) { - serial_write_compressed(translate("\n\n------ soft reboot ------\n")); + serial_write_compressed(translate("soft reboot\n")); } first_run = false; skip_repl = run_code_py(safe_mode); diff --git a/ports/esp32s2/common-hal/alarm/__init__.c b/ports/esp32s2/common-hal/alarm/__init__.c index 87276bdaf0..37d74c0be3 100644 --- a/ports/esp32s2/common-hal/alarm/__init__.c +++ b/ports/esp32s2/common-hal/alarm/__init__.c @@ -25,13 +25,15 @@ * THE SOFTWARE. */ +#include "py/obj.h" #include "py/objtuple.h" #include "py/runtime.h" #include "shared-bindings/alarm/__init__.h" #include "shared-bindings/alarm/pin/PinAlarm.h" -#include "shared-bindings/alarm/time/DurationAlarm.h" +#include "shared-bindings/alarm/time/MonotonicTimeAlarm.h" #include "shared-bindings/microcontroller/__init__.h" +#include "shared-bindings/time/__init__.h" #include "esp_sleep.h" @@ -49,8 +51,8 @@ mp_obj_t common_hal_alarm_get_wake_alarm(void) { switch (esp_sleep_get_wakeup_cause()) { case ESP_SLEEP_WAKEUP_TIMER: { // Wake up from timer. - alarm_time_duration_alarm_obj_t *timer = m_new_obj(alarm_time_duration_alarm_obj_t); - timer->base.type = &alarm_time_duration_alarm_type; + alarm_time_monotonic_time_alarm_obj_t *timer = m_new_obj(alarm_time_monotonic_time_alarm_obj_t); + timer->base.type = &alarm_time_monotonic_time_alarm_type; return timer; } @@ -84,7 +86,7 @@ void common_hal_alarm_set_deep_sleep_alarms(size_t n_alarms, const mp_obj_t *ala if (MP_OBJ_IS_TYPE(alarms[i], &alarm_pin_pin_alarm_type)) { mp_raise_NotImplementedError(translate("PinAlarm deep sleep not yet implemented")); } - if (MP_OBJ_IS_TYPE(alarms[i], &alarm_time_duration_alarm_type)) { + else if (MP_OBJ_IS_TYPE(alarms[i], &alarm_time_monotonic_time_alarm_type)) { if (time_alarm_set) { mp_raise_ValueError(translate("Only one alarm.time alarm can be set.")); } @@ -95,14 +97,25 @@ void common_hal_alarm_set_deep_sleep_alarms(size_t n_alarms, const mp_obj_t *ala _deep_sleep_alarms = mp_obj_new_tuple(n_alarms, alarms); } -void common_hal_alarm_enable_deep_sleep_alarms(void) { +// Return false if we should wake up immediately because a time alarm is in the past +// or otherwise already triggered. +bool common_hal_alarm_enable_deep_sleep_alarms(void) { for (size_t i = 0; i < _deep_sleep_alarms->len; i++) { mp_obj_t alarm = _deep_sleep_alarms->items[i]; - if (MP_OBJ_IS_TYPE(alarm, &alarm_time_duration_alarm_type)) { - alarm_time_duration_alarm_obj_t *duration_alarm = MP_OBJ_TO_PTR(alarm); - esp_sleep_enable_timer_wakeup( - (uint64_t) (duration_alarm->duration * 1000000.0f)); + if (MP_OBJ_IS_TYPE(alarm, &alarm_pin_pin_alarm_type)) { + // TODO: handle pin alarms + mp_raise_NotImplementedError(translate("PinAlarm deep sleep not yet implemented")); + } + else if (MP_OBJ_IS_TYPE(alarm, &alarm_time_monotonic_time_alarm_type)) { + alarm_time_monotonic_time_alarm_obj_t *monotonic_time_alarm = MP_OBJ_TO_PTR(alarm); + mp_float_t now = uint64_to_float(common_hal_time_monotonic()); + // Compute a relative time in the future from now. + mp_float_t duration_secs = now - monotonic_time_alarm->monotonic_time; + if (duration_secs <= 0.0f) { + return false; + } + esp_sleep_enable_timer_wakeup((uint64_t) (duration_secs * 1000000)); } - // TODO: handle pin alarms } + return true; } diff --git a/ports/esp32s2/common-hal/alarm/pin/PinAlarm.c b/ports/esp32s2/common-hal/alarm/pin/PinAlarm.c index f26c8a179a..438d6885dc 100644 --- a/ports/esp32s2/common-hal/alarm/pin/PinAlarm.c +++ b/ports/esp32s2/common-hal/alarm/pin/PinAlarm.c @@ -3,7 +3,6 @@ * * The MIT License (MIT) * - * Copyright (c) 2020 @microDev1 (GitHub) * Copyright (c) 2020 Dan Halbert for Adafruit Industries * * Permission is hereby granted, free of charge, to any person obtaining a copy @@ -38,7 +37,7 @@ void common_hal_alarm_pin_pin_alarm_construct(alarm_pin_pin_alarm_obj_t *self, c self->pull = pull; } -const mp_obj_tuple_t *common_hal_alarm_pin_pin_alarm_get_pins(alarm_pin_pin_alarm_obj_t *self) { +mp_obj_tuple_t *common_hal_alarm_pin_pin_alarm_get_pins(alarm_pin_pin_alarm_obj_t *self) { return self->pins; } diff --git a/ports/esp32s2/common-hal/alarm/time/DurationAlarm.c b/ports/esp32s2/common-hal/alarm/time/MonotonicTimeAlarm.c similarity index 61% rename from ports/esp32s2/common-hal/alarm/time/DurationAlarm.c rename to ports/esp32s2/common-hal/alarm/time/MonotonicTimeAlarm.c index 80bf4244e3..81864d99ed 100644 --- a/ports/esp32s2/common-hal/alarm/time/DurationAlarm.c +++ b/ports/esp32s2/common-hal/alarm/time/MonotonicTimeAlarm.c @@ -3,7 +3,6 @@ * * The MIT License (MIT) * - * Copyright (c) 2020 @microDev1 (GitHub) * Copyright (c) 2020 Dan Halbert for Adafruit Industries * * Permission is hereby granted, free of charge, to any person obtaining a copy @@ -29,23 +28,12 @@ #include "py/runtime.h" -#include "shared-bindings/alarm/time/DurationAlarm.h" +#include "shared-bindings/alarm/time/MonotonicTimeAlarm.h" -void common_hal_alarm_time_duration_alarm_construct(alarm_time_duration_alarm_obj_t *self, mp_float_t duration) { - self->duration = duration; +void common_hal_alarm_time_monotonic_time_alarm_construct(alarm_time_monotonic_time_alarm_obj_t *self, mp_float_t monotonic_time) { + self->monotonic_time = monotonic_time; } -mp_float_t common_hal_alarm_time_duration_alarm_get_duration(alarm_time_duration_alarm_obj_t *self) { - return self->duration; -} - -void common_hal_alarm_time_duration_alarm_enable(alarm_time_duration_alarm_obj_t *self) { - if (esp_sleep_enable_timer_wakeup((uint64_t) (self->duration * 1000000)) == ESP_ERR_INVALID_ARG) { - mp_raise_ValueError(translate("duration out of range")); - } -} - -void common_hal_alarm_time_duration_alarm_disable (alarm_time_duration_alarm_obj_t *self) { - (void) self; - esp_sleep_disable_wakeup_source(ESP_SLEEP_WAKEUP_TIMER); +mp_float_t common_hal_alarm_time_monotonic_time_alarm_get_monotonic_time(alarm_time_monotonic_time_alarm_obj_t *self) { + return self->monotonic_time; } diff --git a/ports/esp32s2/common-hal/alarm/time/DurationAlarm.h b/ports/esp32s2/common-hal/alarm/time/MonotonicTimeAlarm.h similarity index 91% rename from ports/esp32s2/common-hal/alarm/time/DurationAlarm.h rename to ports/esp32s2/common-hal/alarm/time/MonotonicTimeAlarm.h index 3e81cbac2f..5ff8294506 100644 --- a/ports/esp32s2/common-hal/alarm/time/DurationAlarm.h +++ b/ports/esp32s2/common-hal/alarm/time/MonotonicTimeAlarm.h @@ -3,7 +3,6 @@ * * The MIT License (MIT) * - * Copyright (c) 2020 @microDev1 (GitHub) * Copyright (c) 2020 Dan Halbert for Adafruit Industries * * Permission is hereby granted, free of charge, to any person obtaining a copy @@ -30,5 +29,5 @@ typedef struct { mp_obj_base_t base; - mp_float_t duration; // seconds -} alarm_time_duration_alarm_obj_t; + mp_float_t monotonic_time; // values compatible with time.monotonic_time() +} alarm_time_monotonic_time_alarm_obj_t; diff --git a/py/circuitpy_defns.mk b/py/circuitpy_defns.mk index 27466282a8..14b658df4a 100644 --- a/py/circuitpy_defns.mk +++ b/py/circuitpy_defns.mk @@ -303,7 +303,7 @@ SRC_COMMON_HAL_ALL = \ _pew/__init__.c \ alarm/__init__.c \ alarm/pin/PinAlarm.c \ - alarm/time/DurationAlarm.c \ + alarm/time/MonotonicTimeAlarm.c \ analogio/AnalogIn.c \ analogio/AnalogOut.c \ analogio/__init__.c \ diff --git a/py/obj.h b/py/obj.h index 805b26e487..e055c97506 100644 --- a/py/obj.h +++ b/py/obj.h @@ -679,6 +679,7 @@ mp_obj_t mp_obj_new_bytearray_by_ref(size_t n, void *items); #if MICROPY_PY_BUILTINS_FLOAT mp_obj_t mp_obj_new_int_from_float(mp_float_t val); mp_obj_t mp_obj_new_complex(mp_float_t real, mp_float_t imag); +extern mp_float_t uint64_to_float(uint64_t ui64); #endif mp_obj_t mp_obj_new_exception(const mp_obj_type_t *exc_type); mp_obj_t mp_obj_new_exception_arg1(const mp_obj_type_t *exc_type, mp_obj_t arg); diff --git a/py/objfloat.c b/py/objfloat.c index 59f1eb2f69..80f10e816e 100644 --- a/py/objfloat.c +++ b/py/objfloat.c @@ -333,6 +333,13 @@ mp_obj_t mp_obj_float_binary_op(mp_binary_op_t op, mp_float_t lhs_val, mp_obj_t return mp_obj_new_float(lhs_val); } +// Convert a uint64_t to a 32-bit float without invoking the double-precision math routines, +// which are large. +mp_float_t uint64_to_float(uint64_t ui64) { + // 4294967296 = 2^32 + return (mp_float_t) ((uint32_t) (ui64 >> 32) * 4294967296.0f + (uint32_t) (ui64 & 0xffffffff)); +} + #pragma GCC diagnostic pop #endif // MICROPY_PY_BUILTINS_FLOAT diff --git a/shared-bindings/alarm/__init__.c b/shared-bindings/alarm/__init__.c index b6b86c8354..a3ecdd2ba0 100644 --- a/shared-bindings/alarm/__init__.c +++ b/shared-bindings/alarm/__init__.c @@ -29,7 +29,7 @@ #include "shared-bindings/alarm/__init__.h" #include "shared-bindings/alarm/pin/PinAlarm.h" -#include "shared-bindings/alarm/time/DurationAlarm.h" +#include "shared-bindings/alarm/time/MonotonicTimeAlarm.h" //| """Power-saving light and deep sleep. Alarms can be set to wake up from sleep. //| @@ -60,7 +60,7 @@ void validate_objs_are_alarms(size_t n_args, const mp_obj_t *objs) { for (size_t i = 0; i < n_args; i++) { if (MP_OBJ_IS_TYPE(objs[i], &alarm_pin_pin_alarm_type) || - MP_OBJ_IS_TYPE(objs[i], &alarm_time_duration_alarm_type)) { + MP_OBJ_IS_TYPE(objs[i], &alarm_time_monotonic_time_alarm_type)) { continue; } mp_raise_TypeError_varg(translate("Expected an alarm")); @@ -86,7 +86,9 @@ MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(alarm_sleep_until_alarms_obj, 1, MP_OBJ_FUN_ //| When awakened, the microcontroller will restart and run ``boot.py`` and ``code.py`` //| from the beginning. //| -//| The alarm that caused the wake-up is available as `alarm.wake_alarm`. +//| An alarm equivalent to the one that caused the wake-up is available as `alarm.wake_alarm`. +//| Its type and/or attributes may not correspond exactly to the original alarm. +//| For time-base alarms, currently, an `alarm.time.MonotonicTimeAlarm()` is created. //| //| If you call this routine more than once, only the last set of alarms given will be used. //| """ @@ -121,7 +123,7 @@ STATIC const mp_obj_module_t alarm_pin_module = { 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_DurationAlarm), MP_OBJ_FROM_PTR(&alarm_time_duration_alarm_type) }, + { MP_ROM_QSTR(MP_QSTR_MonotonicTimeAlarm), MP_OBJ_FROM_PTR(&alarm_time_monotonic_time_alarm_type) }, }; STATIC MP_DEFINE_CONST_DICT(alarm_time_globals, alarm_time_globals_table); diff --git a/shared-bindings/alarm/__init__.h b/shared-bindings/alarm/__init__.h index d8d6812c90..0f084c78e8 100644 --- a/shared-bindings/alarm/__init__.h +++ b/shared-bindings/alarm/__init__.h @@ -32,7 +32,7 @@ #include "common-hal/alarm/__init__.h" extern mp_obj_t common_hal_alarm_sleep_until_alarms(size_t n_alarms, const mp_obj_t *alarms); -extern void common_hal_alarm_enable_deep_sleep_alarms(void); +extern bool common_hal_alarm_enable_deep_sleep_alarms(void); extern void common_hal_alarm_set_deep_sleep_alarms(size_t n_alarms, const mp_obj_t *alarms); // Used by wake-up code. diff --git a/shared-bindings/alarm/pin/PinAlarm.c b/shared-bindings/alarm/pin/PinAlarm.c index bb48b93c42..ff7b19ca1f 100644 --- a/shared-bindings/alarm/pin/PinAlarm.c +++ b/shared-bindings/alarm/pin/PinAlarm.c @@ -31,6 +31,7 @@ #include "py/nlr.h" #include "py/obj.h" +#include "py/objproperty.h" #include "py/runtime.h" #include "supervisor/shared/translate.h" @@ -39,7 +40,7 @@ //| //| def __init__(self, *pins: microcontroller.Pin, value: bool, all_same_value: bool = False, edge: bool = False, pull: bool = False) -> None: //| """Create an alarm triggered by a `microcontroller.Pin` level. The alarm is not active -//| until it is listed in an `alarm`-enabling function, such as `alarm.sleep_until_alarms()` or +//| until it is passed to an `alarm`-enabling function, such as `alarm.sleep_until_alarms()` or //| `alarm.set_deep_sleep_alarms()`. //| //| :param microcontroller.Pin \*pins: The pins to monitor. On some ports, the choice of pins @@ -88,7 +89,41 @@ STATIC mp_obj_t alarm_pin_pin_alarm_make_new(const mp_obj_type_t *type, mp_uint_ return MP_OBJ_FROM_PTR(self); } +//| pins: Tuple[microcontroller.pin] +//| """The trigger pins.""" +//| +STATIC mp_obj_t alarm_pin_pin_alarm_obj_get_pins(mp_obj_t self_in) { + alarm_pin_pin_alarm_obj_t *self = MP_OBJ_TO_PTR(self_in); + return common_hal_alarm_pin_pin_alarm_get_pins(self); +} +MP_DEFINE_CONST_FUN_OBJ_1(alarm_pin_pin_alarm_get_pins_obj, alarm_pin_pin_alarm_obj_get_pins); + +const mp_obj_property_t alarm_pin_pin_alarm_pins_obj = { + .base.type = &mp_type_property, + .proxy = {(mp_obj_t)&alarm_pin_pin_alarm_get_pins_obj, + (mp_obj_t)&mp_const_none_obj, + (mp_obj_t)&mp_const_none_obj}, +}; + +//| value: Tuple[microcontroller.pin] +//| """The value on which to trigger.""" +//| +STATIC mp_obj_t alarm_pin_pin_alarm_obj_get_value(mp_obj_t self_in) { + alarm_pin_pin_alarm_obj_t *self = MP_OBJ_TO_PTR(self_in); + return mp_obj_new_bool(common_hal_alarm_pin_pin_alarm_get_value(self)); +} +MP_DEFINE_CONST_FUN_OBJ_1(alarm_pin_pin_alarm_get_value_obj, alarm_pin_pin_alarm_obj_get_value); + +const mp_obj_property_t alarm_pin_pin_alarm_value_obj = { + .base.type = &mp_type_property, + .proxy = {(mp_obj_t)&alarm_pin_pin_alarm_get_value_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[] = { + { MP_ROM_QSTR(MP_QSTR_pins), MP_ROM_PTR(&alarm_pin_pin_alarm_pins_obj) }, + { MP_ROM_QSTR(MP_QSTR_value), MP_ROM_PTR(&alarm_pin_pin_alarm_value_obj) }, }; STATIC MP_DEFINE_CONST_DICT(alarm_pin_pin_alarm_locals_dict, alarm_pin_pin_alarm_locals_dict_table); diff --git a/shared-bindings/alarm/pin/PinAlarm.h b/shared-bindings/alarm/pin/PinAlarm.h index bbf3018b5d..cb69468124 100644 --- a/shared-bindings/alarm/pin/PinAlarm.h +++ b/shared-bindings/alarm/pin/PinAlarm.h @@ -35,8 +35,8 @@ extern const mp_obj_type_t alarm_pin_pin_alarm_type; void common_hal_alarm_pin_pin_alarm_construct(alarm_pin_pin_alarm_obj_t *self, const mp_obj_t pins[], size_t num_pins, bool value, bool all_same_value, bool edge, bool pull); -extern const mp_obj_tuple_t *common_hal_alarm_pin_pin_alarm_get_pins(alarm_pin_pin_alarm_obj_t *self); -extern bool common_hal_alarm_pin_pin_alarm_get_level(alarm_pin_pin_alarm_obj_t *self); +extern mp_obj_tuple_t *common_hal_alarm_pin_pin_alarm_get_pins(alarm_pin_pin_alarm_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_pin_alarm_get_edge(alarm_pin_pin_alarm_obj_t *self); extern bool common_hal_alarm_pin_pin_alarm_get_pull(alarm_pin_pin_alarm_obj_t *self); diff --git a/shared-bindings/alarm/time/DurationAlarm.c b/shared-bindings/alarm/time/DurationAlarm.c deleted file mode 100644 index 6831aba5db..0000000000 --- a/shared-bindings/alarm/time/DurationAlarm.c +++ /dev/null @@ -1,91 +0,0 @@ -/* - * This file is part of the MicroPython project, http://micropython.org/ - * - * The MIT License (MIT) - * - * Copyright (c) 2020 Dan Halbert for Adafruit Industries - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ - -#include "shared-bindings/board/__init__.h" -#include "shared-bindings/microcontroller/__init__.h" -#include "shared-bindings/alarm/time/DurationAlarm.h" - -#include "py/nlr.h" -#include "py/obj.h" -#include "py/runtime.h" -#include "supervisor/shared/translate.h" - -//| class DurationAlarm: -//| """Trigger an alarm at a specified interval from now.""" -//| -//| def __init__(self, secs: float) -> None: -//| """Create an alarm that will be triggered in ``secs`` seconds from the time -//| sleep starts. The alarm is not active until it is listed in an -//| `alarm`-enabling function, such as `alarm.sleep_until_alarms()` or -//| `alarm.set_deep_sleep_alarms()`. -//| """ -//| ... -//| -STATIC mp_obj_t alarm_time_duration_alarm_make_new(const mp_obj_type_t *type, - mp_uint_t n_args, const mp_obj_t *args, mp_map_t *kw_args) { - mp_arg_check_num(n_args, kw_args, 1, 1, false); - - alarm_time_duration_alarm_obj_t *self = m_new_obj(alarm_time_duration_alarm_obj_t); - self->base.type = &alarm_time_duration_alarm_type; - - mp_float_t secs = mp_obj_get_float(args[0]); - - common_hal_alarm_time_duration_alarm_construct(self, secs); - - return MP_OBJ_FROM_PTR(self); -} - -//| def __eq__(self, other: object) -> bool: -//| """Two DurationAlarm objects are equal if their durations differ by less than a millisecond.""" -//| ... -//| -STATIC mp_obj_t alarm_time_duration_alarm_binary_op(mp_binary_op_t op, mp_obj_t lhs_in, mp_obj_t rhs_in) { - switch (op) { - case MP_BINARY_OP_EQUAL: - if (MP_OBJ_IS_TYPE(rhs_in, &alarm_time_duration_alarm_type)) { - return mp_obj_new_bool( - abs(common_hal_alarm_time_duration_alarm_get_duration(lhs_in) - - common_hal_alarm_time_duration_alarm_get_duration(rhs_in)) < 0.001f); - } - return mp_const_false; - - default: - return MP_OBJ_NULL; // op not supported - } -} - -STATIC const mp_rom_map_elem_t alarm_time_duration_alarm_locals_dict_table[] = { -}; - -STATIC MP_DEFINE_CONST_DICT(alarm_time_duration_alarm_locals_dict, alarm_time_duration_alarm_locals_dict_table); - -const mp_obj_type_t alarm_time_duration_alarm_type = { - { &mp_type_type }, - .name = MP_QSTR_DurationAlarm, - .make_new = alarm_time_duration_alarm_make_new, - .binary_op = alarm_time_duration_alarm_binary_op, - .locals_dict = (mp_obj_t)&alarm_time_duration_alarm_locals_dict, -}; diff --git a/shared-bindings/alarm/time/MonotonicTimeAlarm.c b/shared-bindings/alarm/time/MonotonicTimeAlarm.c new file mode 100644 index 0000000000..6ee411e883 --- /dev/null +++ b/shared-bindings/alarm/time/MonotonicTimeAlarm.c @@ -0,0 +1,93 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2020 Dan Halbert for Adafruit Industries + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +#include "shared-bindings/board/__init__.h" +#include "shared-bindings/microcontroller/__init__.h" +#include "shared-bindings/alarm/time/MonotonicTimeAlarm.h" + +#include "py/nlr.h" +#include "py/obj.h" +#include "py/objproperty.h" +#include "py/runtime.h" +#include "supervisor/shared/translate.h" + +//| class MonotonicTimeAlarm: +//| """Trigger an alarm when `time.monotonic()` reaches the given value.""" +//| +//| def __init__(self, monotonic_time: float) -> None: +//| """Create an alarm that will be triggered when `time.monotonic()` would equal +//| ``monotonic_time``. +//| The alarm is not active until it is passed to an +//| `alarm`-enabling function, such as `alarm.sleep_until_alarms()` or +//| `alarm.set_deep_sleep_alarms()`. +//| +//| If the given time is in the past when sleep occurs, the alarm will be triggered +//| immediately. +//| """ +//| ... +//| +STATIC mp_obj_t alarm_time_monotonic_time_alarm_make_new(const mp_obj_type_t *type, + mp_uint_t n_args, const mp_obj_t *args, mp_map_t *kw_args) { + mp_arg_check_num(n_args, kw_args, 1, 1, false); + + alarm_time_monotonic_time_alarm_obj_t *self = m_new_obj(alarm_time_monotonic_time_alarm_obj_t); + self->base.type = &alarm_time_monotonic_time_alarm_type; + + mp_float_t secs = mp_obj_get_float(args[0]); + + common_hal_alarm_time_monotonic_time_alarm_construct(self, secs); + + return MP_OBJ_FROM_PTR(self); +} + +//| monotonic_time: float +//| """The time at which to trigger, based on the `time.monotonic()` clock.""" +//| +STATIC mp_obj_t alarm_time_monotonic_time_alarm_obj_get_monotonic_time(mp_obj_t self_in) { + alarm_time_monotonic_time_alarm_obj_t *self = MP_OBJ_TO_PTR(self_in); + return mp_obj_new_float(common_hal_alarm_time_monotonic_time_alarm_get_monotonic_time(self)); +} +MP_DEFINE_CONST_FUN_OBJ_1(alarm_time_monotonic_time_alarm_get_monotonic_time_obj, alarm_time_monotonic_time_alarm_obj_get_monotonic_time); + +const mp_obj_property_t alarm_time_monotonic_time_alarm_monotonic_time_obj = { + .base.type = &mp_type_property, + .proxy = {(mp_obj_t)&alarm_time_monotonic_time_alarm_get_monotonic_time_obj, + (mp_obj_t)&mp_const_none_obj, + (mp_obj_t)&mp_const_none_obj}, +}; + +STATIC const mp_rom_map_elem_t alarm_time_monotonic_time_alarm_locals_dict_table[] = { + { MP_ROM_QSTR(MP_QSTR_monotonic_time), MP_ROM_PTR(&alarm_time_monotonic_time_alarm_monotonic_time_obj) }, +}; + +STATIC MP_DEFINE_CONST_DICT(alarm_time_monotonic_time_alarm_locals_dict, alarm_time_monotonic_time_alarm_locals_dict_table); + +const mp_obj_type_t alarm_time_monotonic_time_alarm_type = { + { &mp_type_type }, + .name = MP_QSTR_TimeAlarm, + .make_new = alarm_time_monotonic_time_alarm_make_new, + .locals_dict = (mp_obj_t)&alarm_time_monotonic_time_alarm_locals_dict, +}; diff --git a/shared-bindings/alarm/time/DurationAlarm.h b/shared-bindings/alarm/time/MonotonicTimeAlarm.h similarity index 63% rename from shared-bindings/alarm/time/DurationAlarm.h rename to shared-bindings/alarm/time/MonotonicTimeAlarm.h index 87f5d9390c..6eb2738ab5 100644 --- a/shared-bindings/alarm/time/DurationAlarm.h +++ b/shared-bindings/alarm/time/MonotonicTimeAlarm.h @@ -24,19 +24,16 @@ * THE SOFTWARE. */ -#ifndef MICROPY_INCLUDED_SHARED_BINDINGS_ALARM_TIME_DURATION_ALARM_H -#define MICROPY_INCLUDED_SHARED_BINDINGS_ALARM_TIME_DURATION_ALARM_H +#ifndef MICROPY_INCLUDED_SHARED_BINDINGS_ALARM_TIME_MONOTONIC_TIME_ALARM_H +#define MICROPY_INCLUDED_SHARED_BINDINGS_ALARM_TIME_MONOTINIC_TIME_ALARM_H #include "py/obj.h" -#include "common-hal/alarm/time/DurationAlarm.h" +#include "common-hal/alarm/time/MonotonicTimeAlarm.h" -extern const mp_obj_type_t alarm_time_duration_alarm_type; +extern const mp_obj_type_t alarm_time_monotonic_time_alarm_type; -extern void common_hal_alarm_time_duration_alarm_construct(alarm_time_duration_alarm_obj_t *self, mp_float_t duration); -extern mp_float_t common_hal_alarm_time_duration_alarm_get_duration(alarm_time_duration_alarm_obj_t *self); +extern void common_hal_alarm_time_monotonic_time_alarm_construct(alarm_time_monotonic_time_alarm_obj_t *self, mp_float_t monotonic_time); +extern mp_float_t common_hal_alarm_time_monotonic_time_alarm_get_monotonic_time(alarm_time_monotonic_time_alarm_obj_t *self); -extern void common_hal_alarm_time_duration_alarm_enable(alarm_time_duration_alarm_obj_t *self); -extern void common_hal_alarm_time_duration_alarm_disable (alarm_time_duration_alarm_obj_t *self); - -#endif // MICROPY_INCLUDED_SHARED_BINDINGS_ALARM_TIME_DURATION_ALARM_H +#endif // MICROPY_INCLUDED_SHARED_BINDINGS_ALARM_TIME_MONOTONIC_TIME_ALARM_H diff --git a/shared-bindings/time/__init__.c b/shared-bindings/time/__init__.c index 44f82c62e7..804d5ecd89 100644 --- a/shared-bindings/time/__init__.c +++ b/shared-bindings/time/__init__.c @@ -51,9 +51,9 @@ //| ... //| STATIC mp_obj_t time_monotonic(void) { + // Returns ms ticks. uint64_t time64 = common_hal_time_monotonic(); - // 4294967296 = 2^32 - return mp_obj_new_float(((uint32_t) (time64 >> 32) * 4294967296.0f + (uint32_t) (time64 & 0xffffffff)) / 1000.0f); + return mp_obj_new_float(uint64_to_float(time64) / 1000.0f); } MP_DEFINE_CONST_FUN_OBJ_0(time_monotonic_obj, time_monotonic); From 104a089677d62de3554deea7850796dfbb29b1fc Mon Sep 17 00:00:00 2001 From: Dan Halbert Date: Thu, 26 Nov 2020 22:06:37 -0500 Subject: [PATCH 27/34] deep sleep working; deep sleep delay when connected --- main.c | 82 +++---------------- .../common-hal/microcontroller/__init__.c | 4 - .../common-hal/microcontroller/__init__.c | 4 - ports/esp32s2/common-hal/alarm/__init__.c | 54 ++++++------ .../common-hal/microcontroller/__init__.c | 6 -- .../common-hal/microcontroller/__init__.c | 4 - .../common-hal/microcontroller/__init__.c | 4 - .../nrf/common-hal/microcontroller/__init__.c | 4 - .../stm/common-hal/microcontroller/__init__.c | 4 - shared-bindings/_typing/__init__.pyi | 4 +- shared-bindings/alarm/__init__.c | 43 ++++++++-- shared-bindings/alarm/__init__.h | 3 +- shared-bindings/alarm/pin/PinAlarm.c | 2 +- shared-bindings/alarm/time/TimeAlarm.c | 78 ++++++++++++++---- shared-bindings/microcontroller/__init__.h | 2 - 15 files changed, 143 insertions(+), 155 deletions(-) diff --git a/main.c b/main.c index a9dbb1b7c3..dda439d6de 100755 --- a/main.c +++ b/main.c @@ -66,9 +66,6 @@ #include "boards/board.h" -// REMOVE *********** -#include "esp_log.h" - #if CIRCUITPY_ALARM #include "shared-bindings/alarm/__init__.h" #endif @@ -98,12 +95,6 @@ #include "common-hal/canio/CAN.h" #endif -// How long to wait for host to start connecting.. -#define CIRCUITPY_USB_CONNECTING_DELAY 1 - -// How long to flash errors on the RGB status LED before going to sleep (secs) -#define CIRCUITPY_FLASH_ERROR_PERIOD 10 - #if MICROPY_ENABLE_PYSTACK static size_t PLACE_IN_DTCM_BSS(_pystack[CIRCUITPY_PYSTACK_SIZE / sizeof(size_t)]); #endif @@ -259,17 +250,6 @@ STATIC void print_code_py_status_message(safe_mode_t safe_mode) { } } -// Should we go into deep sleep when program finishes? -// Normally we won't deep sleep if there was an error or if we are connected to a host -// but either of those can be enabled. -// It's ok to deep sleep if we're not connected to a host, but we need to make sure -// we're giving enough time for USB to start to connect -STATIC bool deep_sleep_allowed(void) { - return - (ok || supervisor_workflow_get_allow_deep_sleep_on_error()) && - !supervisor_workflow_connecting() - (supervisor_ticks_ms64() > CIRCUITPY_USB_CONNECTING_DELAY * 1024); - STATIC bool run_code_py(safe_mode_t safe_mode) { bool serial_connected_at_start = serial_connected(); #if CIRCUITPY_AUTORELOAD_DELAY_MS > 0 @@ -290,10 +270,12 @@ STATIC bool run_code_py(safe_mode_t safe_mode) { if (safe_mode == NO_SAFE_MODE) { new_status_color(MAIN_RUNNING); - static const char * const supported_filenames[] = STRING_LIST("code.txt", "code.py", "main.py", "main.txt"); + static const char * const supported_filenames[] = STRING_LIST( + "code.txt", "code.py", "main.py", "main.txt"); #if CIRCUITPY_FULL_BUILD - static const char * const double_extension_filenames[] = STRING_LIST("code.txt.py", "code.py.txt", "code.txt.txt","code.py.py", - "main.txt.py", "main.py.txt", "main.txt.txt","main.py.py"); + static const char * const double_extension_filenames[] = STRING_LIST( + "code.txt.py", "code.py.txt", "code.txt.txt","code.py.py", + "main.txt.py", "main.py.txt", "main.txt.txt","main.py.py"); #endif stack_resize(); @@ -319,7 +301,7 @@ STATIC bool run_code_py(safe_mode_t safe_mode) { // Program has finished running. // Display a different completion message if the user has no USB attached (cannot save files) - if (!serial_connected_at_start && !deep_sleep_allowed()) { + if (!serial_connected_at_start) { serial_write_compressed(translate("\nCode done running. Waiting for reload.\n")); } @@ -327,16 +309,8 @@ STATIC bool run_code_py(safe_mode_t safe_mode) { #if CIRCUITPY_DISPLAYIO bool refreshed_epaper_display = false; #endif + rgb_status_animation_t animation; - bool ok = result.return_code != PYEXEC_EXCEPTION; - - #if CIRCUITPY_ALARM - // Enable pin or time alarms before sleeping. - // If immediate_wake is true, then there's an alarm that would trigger immediately, - // so don't sleep. - bool immediate_wake = !common_hal_alarm_enable_deep_sleep_alarms(); - #endif - prep_rgb_status_animation(&result, found_main, safe_mode, &animation); while (true) { @@ -360,12 +334,10 @@ STATIC bool run_code_py(safe_mode_t safe_mode) { if (!serial_connected_at_start) { print_code_py_status_message(safe_mode); } - // We won't be going into the REPL if we're going to sleep. - if (!deep_sleep_allowed()) { - print_safe_mode_message(safe_mode); - serial_write("\n"); - serial_write_compressed(translate("Press any key to enter the REPL. Use CTRL-D to reload.")); - } + + print_safe_mode_message(safe_mode); + serial_write("\n"); + serial_write_compressed(translate("Press any key to enter the REPL. Use CTRL-D to reload.")); } if (serial_connected_before_animation && !serial_connected()) { serial_connected_at_start = false; @@ -379,37 +351,7 @@ STATIC bool run_code_py(safe_mode_t safe_mode) { } #endif - bool animation_done = false; - - if (deep_sleep_allowed() && ok) { - // Skip animation if everything is OK. - animation_done = true; - } else { - animation_done = tick_rgb_status_animation(&animation); - } - // Do an error animation only once before deep-sleeping. - if (animation_done) { - if (immediate_wake) { - // Don't sleep, we are already supposed to wake up. - return true; - } - if (deep_sleep_allowed()) { - common_hal_mcu_deep_sleep(); - // Does not return. - } - - // Wake up every so often to flash the error code. - if (!ok) { - port_interrupt_after_ticks(CIRCUITPY_FLASH_ERROR_PERIOD * 1024); - } else { - int64_t remaining_connecting_wait = - CIRCUITPY_USB_CONNECTING_DELAY * 1024 - supervisor_ticks_ms64(); - if (remaining_connecting_wait > 0) { - port_interrupt_after_ticks(remaining_connecting_wait); - } - port_sleep_until_interrupt(); - } - } + tick_rgb_status_animation(&animation); } } diff --git a/ports/atmel-samd/common-hal/microcontroller/__init__.c b/ports/atmel-samd/common-hal/microcontroller/__init__.c index ca39f28386..50a1ec038e 100644 --- a/ports/atmel-samd/common-hal/microcontroller/__init__.c +++ b/ports/atmel-samd/common-hal/microcontroller/__init__.c @@ -84,10 +84,6 @@ void common_hal_mcu_reset(void) { reset(); } -void common_hal_mcu_deep_sleep(void) { - //deep sleep call here -} - // The singleton microcontroller.Processor object, bound to microcontroller.cpu // It currently only has properties, and no state. const mcu_processor_obj_t common_hal_mcu_processor_obj = { diff --git a/ports/cxd56/common-hal/microcontroller/__init__.c b/ports/cxd56/common-hal/microcontroller/__init__.c index 57140dec70..7aa3b839d7 100644 --- a/ports/cxd56/common-hal/microcontroller/__init__.c +++ b/ports/cxd56/common-hal/microcontroller/__init__.c @@ -81,10 +81,6 @@ void common_hal_mcu_reset(void) { boardctl(BOARDIOC_RESET, 0); } -void common_hal_mcu_deep_sleep(void) { - //deep sleep call here -} - STATIC const mp_rom_map_elem_t mcu_pin_globals_table[] = { { MP_ROM_QSTR(MP_QSTR_UART2_RXD), MP_ROM_PTR(&pin_UART2_RXD) }, { MP_ROM_QSTR(MP_QSTR_UART2_TXD), MP_ROM_PTR(&pin_UART2_TXD) }, diff --git a/ports/esp32s2/common-hal/alarm/__init__.c b/ports/esp32s2/common-hal/alarm/__init__.c index 7cf74a0efc..767b0de70e 100644 --- a/ports/esp32s2/common-hal/alarm/__init__.c +++ b/ports/esp32s2/common-hal/alarm/__init__.c @@ -1,4 +1,4 @@ -/* + /* * This file is part of the MicroPython project, http://micropython.org/ * * The MIT License (MIT) @@ -77,12 +77,10 @@ mp_obj_t common_hal_alarm_get_wake_alarm(void) { return mp_const_none; } -mp_obj_t common_hal_alarm_sleep_until_alarms(size_t n_alarms, const mp_obj_t *alarms) { - mp_raise_NotImplementedError(NULL); -} - -void common_hal_alarm_set_deep_sleep_alarms(size_t n_alarms, const mp_obj_t *alarms) { +STATIC void setup_alarms(size_t n_alarms, const mp_obj_t *alarms) { bool time_alarm_set = false; + alarm_time_time_alarm_obj_t *time_alarm = MP_OBJ_NULL; + for (size_t i = 0; i < n_alarms; i++) { if (MP_OBJ_IS_TYPE(alarms[i], &alarm_pin_pin_alarm_type)) { mp_raise_NotImplementedError(translate("PinAlarm deep sleep not yet implemented")); @@ -91,32 +89,32 @@ void common_hal_alarm_set_deep_sleep_alarms(size_t n_alarms, const mp_obj_t *ala if (time_alarm_set) { mp_raise_ValueError(translate("Only one alarm.time alarm can be set.")); } + time_alarm = MP_OBJ_TO_PTR(alarms[i]); time_alarm_set = true; } } - _deep_sleep_alarms = mp_obj_new_tuple(n_alarms, alarms); + if (time_alarm != MP_OBJ_NULL) { + // 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 wakeup_in_secs = MAX(0.0f, time_alarm->monotonic_time - now_secs); + esp_sleep_enable_timer_wakeup((uint64_t) (wakeup_in_secs * 1000000)); + } } -// Return false if we should wake up immediately because a time alarm is in the past -// or otherwise already triggered. -bool common_hal_alarm_enable_deep_sleep_alarms(void) { - for (size_t i = 0; i < _deep_sleep_alarms->len; i++) { - mp_obj_t alarm = _deep_sleep_alarms->items[i]; - if (MP_OBJ_IS_TYPE(alarm, &alarm_pin_pin_alarm_type)) { - // TODO: handle pin alarms - mp_raise_NotImplementedError(translate("PinAlarm deep sleep not yet implemented")); - } - else if (MP_OBJ_IS_TYPE(alarm, &alarm_time_time_alarm_type)) { - alarm_time_time_alarm_obj_t *time_alarm = MP_OBJ_TO_PTR(alarm); - mp_float_t now_secs = uint64_to_float(common_hal_time_monotonic_ms()) / 1000.0f; - // Compute how long to actually sleep, considering hte time now. - mp_float_t wakeup_in_secs = time_alarm->monotonic_time - now_secs; - if (wakeup_in_secs <= 0.0f) { - return false; - } - esp_sleep_enable_timer_wakeup((uint64_t) (wakeup_in_secs * 1000000)); - } - } - return true; +mp_obj_t common_hal_alarm_sleep_until_alarms(size_t n_alarms, const mp_obj_t *alarms) { + setup_alarms(n_alarms, alarms); + + // Shut down wifi cleanly. + esp_wifi_stop(); + esp_light_sleep_start(); + return common_hal_alarm_get_wake_alarm(); +} + +void common_hal_alarm_exit_and_deep_sleep_until_alarms(size_t n_alarms, const mp_obj_t *alarms) { + setup_alarms(n_alarms, alarms); + + // Shut down wifi cleanly. + esp_wifi_stop(); + esp_deep_sleep_start(); } diff --git a/ports/esp32s2/common-hal/microcontroller/__init__.c b/ports/esp32s2/common-hal/microcontroller/__init__.c index 3578b86d02..184f5be696 100644 --- a/ports/esp32s2/common-hal/microcontroller/__init__.c +++ b/ports/esp32s2/common-hal/microcontroller/__init__.c @@ -81,12 +81,6 @@ void common_hal_mcu_reset(void) { while(1); } -void NORETURN common_hal_mcu_deep_sleep(void) { - // Shut down wifi cleanly. - esp_wifi_stop(); - esp_deep_sleep_start(); -} - // The singleton microcontroller.Processor object, bound to microcontroller.cpu // It currently only has properties, and no state. const mcu_processor_obj_t common_hal_mcu_processor_obj = { diff --git a/ports/litex/common-hal/microcontroller/__init__.c b/ports/litex/common-hal/microcontroller/__init__.c index e6f50ed5a6..3c91661144 100644 --- a/ports/litex/common-hal/microcontroller/__init__.c +++ b/ports/litex/common-hal/microcontroller/__init__.c @@ -89,10 +89,6 @@ void common_hal_mcu_reset(void) { while(1); } -void common_hal_mcu_deep_sleep(void) { - //deep sleep call here -} - // The singleton microcontroller.Processor object, bound to microcontroller.cpu // It currently only has properties, and no state. const mcu_processor_obj_t common_hal_mcu_processor_obj = { diff --git a/ports/mimxrt10xx/common-hal/microcontroller/__init__.c b/ports/mimxrt10xx/common-hal/microcontroller/__init__.c index 0329ced69b..6a8537e2da 100644 --- a/ports/mimxrt10xx/common-hal/microcontroller/__init__.c +++ b/ports/mimxrt10xx/common-hal/microcontroller/__init__.c @@ -86,10 +86,6 @@ void common_hal_mcu_reset(void) { NVIC_SystemReset(); } -void common_hal_mcu_deep_sleep(void) { - //deep sleep call here -} - // The singleton microcontroller.Processor object, bound to microcontroller.cpu // It currently only has properties, and no state. const mcu_processor_obj_t common_hal_mcu_processor_obj = { diff --git a/ports/nrf/common-hal/microcontroller/__init__.c b/ports/nrf/common-hal/microcontroller/__init__.c index 9911896bff..06aac9409d 100644 --- a/ports/nrf/common-hal/microcontroller/__init__.c +++ b/ports/nrf/common-hal/microcontroller/__init__.c @@ -95,10 +95,6 @@ void common_hal_mcu_reset(void) { reset_cpu(); } -void common_hal_mcu_deep_sleep(void) { - //deep sleep call here -} - // The singleton microcontroller.Processor object, bound to microcontroller.cpu // It currently only has properties, and no state. const mcu_processor_obj_t common_hal_mcu_processor_obj = { diff --git a/ports/stm/common-hal/microcontroller/__init__.c b/ports/stm/common-hal/microcontroller/__init__.c index bc81b0e4f5..a827399ccb 100644 --- a/ports/stm/common-hal/microcontroller/__init__.c +++ b/ports/stm/common-hal/microcontroller/__init__.c @@ -81,10 +81,6 @@ void common_hal_mcu_reset(void) { NVIC_SystemReset(); } -void common_hal_mcu_deep_sleep(void) { - //deep sleep call here -} - // The singleton microcontroller.Processor object, bound to microcontroller.cpu // It currently only has properties, and no state. const mcu_processor_obj_t common_hal_mcu_processor_obj = { diff --git a/shared-bindings/_typing/__init__.pyi b/shared-bindings/_typing/__init__.pyi index 02839ab477..2716936860 100644 --- a/shared-bindings/_typing/__init__.pyi +++ b/shared-bindings/_typing/__init__.pyi @@ -54,12 +54,12 @@ FrameBuffer = Union[rgbmatrix.RGBMatrix] """ Alarm = Union[ - alarm.pin.PinAlarm, alarm.time.DurationAlarm + alarm.pin.PinAlarm, alarm.time.TimeAlarm ] """Classes that implement alarms for sleeping and asynchronous notification. - `alarm.pin.PinAlarm` - - `alarm.time.DurationAlarm` + - `alarm.time.TimeAlarm` You can use these alarms to wake from light or deep sleep. """ diff --git a/shared-bindings/alarm/__init__.c b/shared-bindings/alarm/__init__.c index 4aa6c8457d..4c2189c0d0 100644 --- a/shared-bindings/alarm/__init__.c +++ b/shared-bindings/alarm/__init__.c @@ -30,6 +30,15 @@ #include "shared-bindings/alarm/__init__.h" #include "shared-bindings/alarm/pin/PinAlarm.h" #include "shared-bindings/alarm/time/TimeAlarm.h" +#include "shared-bindings/time/__init__.h" +#include "supervisor/shared/rgb_led_status.h" +#include "supervisor/shared/workflow.h" + +// Wait this long to see if USB is being connected (enumeration starting). +#define CIRCUITPY_USB_CONNECTING_DELAY 1 +// Wait this long before going into deep sleep if connected. This +// allows the user to ctrl-C before deep sleep starts. +#define CIRCUITPY_USB_CONNECTED_DEEP_SLEEP_DELAY 5 //| """Power-saving light and deep sleep. Alarms can be set to wake up from sleep. //| @@ -44,16 +53,12 @@ //| Deep sleep shuts down power to nearly all of the chip including the CPU and RAM. This can save //| a more significant amount of power, but CircuitPython must start ``code.py`` from the beginning when //| awakened. +//| """ -//| -//| An error includes an uncaught exception, or sys.exit() called with a non-zero argument -//| -//| To set alarms for deep sleep use `alarm.set_deep_sleep_alarms()` they will apply to next deep sleep only.""" //| //| wake_alarm: Alarm //| """The most recent alarm to wake us up from a sleep (light or deep.)""" //| - void validate_objs_are_alarms(size_t n_args, const mp_obj_t *objs) { for (size_t i = 0; i < n_args; i++) { if (MP_OBJ_IS_TYPE(objs[i], &alarm_pin_pin_alarm_type) || @@ -88,12 +93,38 @@ MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(alarm_sleep_until_alarms_obj, 1, MP_OBJ_FUN_ //| For time-base alarms, currently, an `alarm.time.TimeAlarm()` is created. //| //| If no alarms are specified, the microcontroller will deep sleep until reset. +//| +//| If CircuitPython is unconnected to a host computer, go into deep sleep immediately. +//| But if it already connected or in the process of connecting to a host computer, wait at least +//| five seconds after starting code.py before entering deep sleep. +//| This allows interrupting a program that would otherwise go into deep sleep too quickly +//| to interrupt from the keyboard. //| """ //| ... //| STATIC mp_obj_t alarm_exit_and_deep_sleep_until_alarms(size_t n_args, const mp_obj_t *args) { validate_objs_are_alarms(n_args, args); - common_hal_exit_and_deep_sleep_until_alarms(n_args, args); + + int64_t connecting_delay_msec = CIRCUITPY_USB_CONNECTING_DELAY * 1024 - supervisor_ticks_ms64(); + if (connecting_delay_msec > 0) { + common_hal_time_delay_ms(connecting_delay_msec * 1000 / 1024); + } + + // If connected, wait for the program to be running at least as long as + // CIRCUITPY_USB_CONNECTED_DEEP_SLEEP_DELAY. This allows a user to ctrl-C the running + // program in case it is in a tight deep sleep loop that would otherwise be difficult + // or impossible to interrupt. + // Indicate that we're delaying with the SAFE_MODE color. + int64_t delay_before_sleeping_msec = + supervisor_ticks_ms64() - CIRCUITPY_USB_CONNECTED_DEEP_SLEEP_DELAY * 1000; + if (supervisor_workflow_connecting() && delay_before_sleeping_msec > 0) { + temp_status_color(SAFE_MODE); + common_hal_time_delay_ms(delay_before_sleeping_msec); + clear_temp_status(); + } + + common_hal_alarm_exit_and_deep_sleep_until_alarms(n_args, args); + // Does not return. return mp_const_none; } MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(alarm_exit_and_deep_sleep_until_alarms_obj, 1, MP_OBJ_FUN_ARGS_MAX, alarm_exit_and_deep_sleep_until_alarms); diff --git a/shared-bindings/alarm/__init__.h b/shared-bindings/alarm/__init__.h index 0f084c78e8..968136345c 100644 --- a/shared-bindings/alarm/__init__.h +++ b/shared-bindings/alarm/__init__.h @@ -32,8 +32,7 @@ #include "common-hal/alarm/__init__.h" extern mp_obj_t common_hal_alarm_sleep_until_alarms(size_t n_alarms, const mp_obj_t *alarms); -extern bool common_hal_alarm_enable_deep_sleep_alarms(void); -extern void common_hal_alarm_set_deep_sleep_alarms(size_t n_alarms, const mp_obj_t *alarms); +extern void common_hal_alarm_exit_and_deep_sleep_until_alarms(size_t n_alarms, const mp_obj_t *alarms); // Used by wake-up code. extern void common_hal_alarm_set_wake_alarm(mp_obj_t alarm); diff --git a/shared-bindings/alarm/pin/PinAlarm.c b/shared-bindings/alarm/pin/PinAlarm.c index ff7b19ca1f..fadd1b0d4a 100644 --- a/shared-bindings/alarm/pin/PinAlarm.c +++ b/shared-bindings/alarm/pin/PinAlarm.c @@ -41,7 +41,7 @@ //| def __init__(self, *pins: microcontroller.Pin, value: bool, all_same_value: bool = False, edge: bool = False, pull: bool = False) -> None: //| """Create an alarm triggered by a `microcontroller.Pin` level. The alarm is not active //| until it is passed to an `alarm`-enabling function, such as `alarm.sleep_until_alarms()` or -//| `alarm.set_deep_sleep_alarms()`. +//| `alarm.exit_and_deep_sleep_until_alarms()`. //| //| :param microcontroller.Pin \*pins: The pins to monitor. On some ports, the choice of pins //| may be limited due to hardware restrictions, particularly for deep-sleep alarms. diff --git a/shared-bindings/alarm/time/TimeAlarm.c b/shared-bindings/alarm/time/TimeAlarm.c index 864ece284e..6339b850c6 100644 --- a/shared-bindings/alarm/time/TimeAlarm.c +++ b/shared-bindings/alarm/time/TimeAlarm.c @@ -24,25 +24,32 @@ * THE SOFTWARE. */ -#include "shared-bindings/board/__init__.h" -#include "shared-bindings/microcontroller/__init__.h" -#include "shared-bindings/alarm/time/TimeAlarm.h" - #include "py/nlr.h" #include "py/obj.h" #include "py/objproperty.h" #include "py/runtime.h" + +#include "shared-bindings/time/__init__.h" +#include "shared-bindings/alarm/time/TimeAlarm.h" + #include "supervisor/shared/translate.h" +#if MICROPY_LONGINT_IMPL != MICROPY_LONGINT_IMPL_NONE +mp_obj_t MP_WEAK rtc_get_time_source_time(void) { + mp_raise_RuntimeError(translate("RTC is not supported on this board")); +} +#endif + //| class TimeAlarm: -//| """Trigger an alarm when `time.monotonic()` reaches the given value.""" +//| """Trigger an alarm when the specified time is reached.""" //| -//| def __init__(self, monotonic_time: float) -> None: +//| def __init__(self, monotonic_time: Optional[Float] = None, epoch_time: Optional[int] = None) -> None: //| """Create an alarm that will be triggered when `time.monotonic()` would equal -//| ``monotonic_time``. +//| ``monotonic_time``, or when `time.time()` would equal ``epoch_time``. +//| Only one of the two arguments can be given. //| The alarm is not active until it is passed to an //| `alarm`-enabling function, such as `alarm.sleep_until_alarms()` or -//| `alarm.set_deep_sleep_alarms()`. +//| `alarm.exit_and_deep_sleep_until_alarms()`. //| //| If the given time is in the past when sleep occurs, the alarm will be triggered //| immediately. @@ -50,21 +57,64 @@ //| ... //| STATIC mp_obj_t alarm_time_time_alarm_make_new(const mp_obj_type_t *type, - mp_uint_t n_args, const mp_obj_t *args, mp_map_t *kw_args) { - mp_arg_check_num(n_args, kw_args, 1, 1, false); - + 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); self->base.type = &alarm_time_time_alarm_type; - mp_float_t secs = mp_obj_get_float(args[0]); + enum { ARG_monotonic_time, ARG_epoch_time }; + static const mp_arg_t allowed_args[] = { + { MP_QSTR_monotonic_time, MP_ARG_KW_ONLY | MP_ARG_OBJ, {.u_obj = mp_const_none} }, + { MP_QSTR_epoch_time, MP_ARG_KW_ONLY | MP_ARG_OBJ, {.u_obj = mp_const_none} }, + }; - common_hal_alarm_time_time_alarm_construct(self, secs); + mp_arg_val_t args[MP_ARRAY_SIZE(allowed_args)]; + mp_arg_parse_all(n_args, pos_args, kw_args, MP_ARRAY_SIZE(allowed_args), allowed_args, args); + + bool have_monotonic = args[ARG_monotonic_time].u_obj != mp_const_none; + bool have_epoch = args[ARG_epoch_time].u_obj != mp_const_none; + + if (!(have_monotonic ^ have_epoch)) { + mp_raise_ValueError(translate("Supply one of monotonic_time or epoch_time")); + } + + mp_float_t monotonic_time = 0; // To avoid compiler warning. + if (have_monotonic) { + monotonic_time = mp_obj_get_float(args[ARG_monotonic_time].u_obj); + } + + mp_float_t monotonic_time_now = common_hal_time_monotonic_ms() / 1000.0; + + if (have_epoch) { +#if MICROPY_LONGINT_IMPL == MICROPY_LONGINT_IMPL_NONE + mp_raise_ValueError(translate("epoch_time not supported on this board")); +#else + mp_uint_t epoch_time_secs = mp_obj_int_get_checked(args[ARG_epoch_time].u_obj); + + timeutils_struct_time_t tm; + struct_time_to_tm(rtc_get_time_source_time(), &tm); + mp_uint_t epoch_secs_now = timeutils_seconds_since_epoch(tm.tm_year, tm.tm_mon, tm.tm_mday, + tm.tm_hour, tm.tm_min, tm.tm_sec); + // How far in the future (in secs) is the requested time? + mp_int_t epoch_diff = epoch_time_secs - epoch_secs_now; + // Convert it to a future monotonic time. + monotonic_time = monotonic_time_now + epoch_diff; +#endif + } + + if (monotonic_time < monotonic_time_now) { + mp_raise_ValueError(translate("Time is in the past.")); + } + + common_hal_alarm_time_time_alarm_construct(self, monotonic_time); return MP_OBJ_FROM_PTR(self); } //| monotonic_time: float -//| """The time at which to trigger, based on the `time.monotonic()` clock.""" +//| """When this time is reached, the alarm will trigger, based on the `time.monotonic()` clock. +//| The time may be given as ``epoch_time`` in the constructor, but it is returned +//| 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) { alarm_time_time_alarm_obj_t *self = MP_OBJ_TO_PTR(self_in); diff --git a/shared-bindings/microcontroller/__init__.h b/shared-bindings/microcontroller/__init__.h index 87284fc2e5..ac71de4247 100644 --- a/shared-bindings/microcontroller/__init__.h +++ b/shared-bindings/microcontroller/__init__.h @@ -43,8 +43,6 @@ extern void common_hal_mcu_enable_interrupts(void); extern void common_hal_mcu_on_next_reset(mcu_runmode_t runmode); extern void common_hal_mcu_reset(void); -extern void NORETURN common_hal_mcu_deep_sleep(void); - extern const mp_obj_dict_t mcu_pin_globals; extern const mcu_processor_obj_t common_hal_mcu_processor_obj; From e308a9ec1134412f6194358790176d17b0724ef1 Mon Sep 17 00:00:00 2001 From: Dan Halbert Date: Fri, 27 Nov 2020 16:02:17 -0500 Subject: [PATCH 28/34] working! PinAlarm not implemented yet. --- locale/circuitpython.pot | 25 +++- ports/esp32s2/common-hal/alarm/__init__.c | 71 +++++++++- .../common-hal/microcontroller/__init__.c | 3 - shared-bindings/alarm/__init__.c | 122 ++++++++++++------ shared-bindings/alarm/__init__.h | 1 + shared-bindings/alarm/pin/PinAlarm.c | 6 +- supervisor/shared/workflow.c | 4 +- 7 files changed, 175 insertions(+), 57 deletions(-) diff --git a/locale/circuitpython.pot b/locale/circuitpython.pot index 1532a67b54..36fd5f647c 100644 --- a/locale/circuitpython.pot +++ b/locale/circuitpython.pot @@ -8,11 +8,7 @@ msgid "" msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "Report-Msgid-Bugs-To: \n" -<<<<<<< HEAD -"POT-Creation-Date: 2020-11-25 15:08-0500\n" -======= -"POT-Creation-Date: 2020-11-11 16:30+0530\n" ->>>>>>> adafruit/main +"POT-Creation-Date: 2020-11-27 16:03-0500\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language-Team: LANGUAGE \n" @@ -301,6 +297,7 @@ msgid "All I2C peripherals are in use" msgstr "" #: ports/esp32s2/common-hal/countio/Counter.c +#: ports/esp32s2/common-hal/frequencyio/FrequencyIn.c #: ports/esp32s2/common-hal/rotaryio/IncrementalEncoder.c msgid "All PCNT units in use" msgstr "" @@ -337,6 +334,7 @@ msgstr "" #: ports/atmel-samd/common-hal/pulseio/PulseIn.c #: ports/atmel-samd/common-hal/pulseio/PulseOut.c #: ports/cxd56/common-hal/pulseio/PulseOut.c +#: ports/esp32s2/common-hal/frequencyio/FrequencyIn.c #: ports/esp32s2/common-hal/neopixel_write/__init__.c #: ports/esp32s2/common-hal/pulseio/PulseIn.c #: ports/esp32s2/common-hal/pulseio/PulseOut.c @@ -1098,6 +1096,7 @@ msgid "Invalid byteorder string" msgstr "" #: ports/atmel-samd/common-hal/frequencyio/FrequencyIn.c +#: ports/esp32s2/common-hal/frequencyio/FrequencyIn.c msgid "Invalid capture period. Valid range: 1 - 500" msgstr "" @@ -1511,7 +1510,7 @@ msgid "Pin number already reserved by EXTI" msgstr "" #: ports/esp32s2/common-hal/alarm/__init__.c -msgid "PinAlarm deep sleep not yet implemented" +msgid "PinAlarm not yet implemented" msgstr "" #: shared-bindings/rgbmatrix/RGBMatrix.c @@ -1575,7 +1574,7 @@ msgstr "" msgid "RTC calibration is not supported on this board" msgstr "" -#: shared-bindings/time/__init__.c +#: shared-bindings/alarm/time/TimeAlarm.c shared-bindings/time/__init__.c msgid "RTC is not supported on this board" msgstr "" @@ -1721,6 +1720,10 @@ msgstr "" msgid "Supply at least one UART pin" msgstr "" +#: shared-bindings/alarm/time/TimeAlarm.c +msgid "Supply one of monotonic_time or epoch_time" +msgstr "" + #: shared-bindings/gnss/GNSS.c msgid "System entry must be gnss.SatelliteSystem" msgstr "" @@ -1784,6 +1787,10 @@ msgstr "" msgid "Tile width must exactly divide bitmap width" msgstr "" +#: shared-bindings/alarm/time/TimeAlarm.c +msgid "Time is in the past." +msgstr "" + #: ports/nrf/common-hal/_bleio/Adapter.c #, c-format msgid "Timeout is too long: Maximum timeout length is %d seconds" @@ -2498,6 +2505,10 @@ msgstr "" msgid "end_x should be an int" msgstr "" +#: shared-bindings/alarm/time/TimeAlarm.c +msgid "epoch_time not supported on this board" +msgstr "" + #: ports/nrf/common-hal/busio/UART.c #, c-format msgid "error = 0x%08lX" diff --git a/ports/esp32s2/common-hal/alarm/__init__.c b/ports/esp32s2/common-hal/alarm/__init__.c index 767b0de70e..e044103bce 100644 --- a/ports/esp32s2/common-hal/alarm/__init__.c +++ b/ports/esp32s2/common-hal/alarm/__init__.c @@ -37,6 +37,7 @@ #include "esp_log.h" #include "esp_sleep.h" +#include "esp_wifi.h" STATIC mp_obj_tuple_t *_deep_sleep_alarms; @@ -77,13 +78,14 @@ mp_obj_t common_hal_alarm_get_wake_alarm(void) { return mp_const_none; } -STATIC void setup_alarms(size_t n_alarms, const mp_obj_t *alarms) { +// Set up light sleep or deep sleep alarms. +STATIC void setup_sleep_alarms(size_t n_alarms, const mp_obj_t *alarms) { bool time_alarm_set = false; alarm_time_time_alarm_obj_t *time_alarm = MP_OBJ_NULL; for (size_t i = 0; i < n_alarms; i++) { if (MP_OBJ_IS_TYPE(alarms[i], &alarm_pin_pin_alarm_type)) { - mp_raise_NotImplementedError(translate("PinAlarm deep sleep not yet implemented")); + mp_raise_NotImplementedError(translate("PinAlarm not yet implemented")); } else if (MP_OBJ_IS_TYPE(alarms[i], &alarm_time_time_alarm_type)) { if (time_alarm_set) { @@ -98,23 +100,82 @@ STATIC void setup_alarms(size_t n_alarms, const mp_obj_t *alarms) { // 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 wakeup_in_secs = MAX(0.0f, time_alarm->monotonic_time - now_secs); - esp_sleep_enable_timer_wakeup((uint64_t) (wakeup_in_secs * 1000000)); + const uint64_t sleep_for_us = (uint64_t) (wakeup_in_secs * 1000000); + ESP_LOGI("ALARM", "Sleep for us: %lld", sleep_for_us); + esp_sleep_enable_timer_wakeup(sleep_for_us); } } +mp_obj_t common_hal_alarm_wait_until_alarms(size_t n_alarms, const mp_obj_t *alarms) { + if (n_alarms == 0) { + return mp_const_none; + } + + bool time_alarm_set = false; + alarm_time_time_alarm_obj_t *time_alarm = MP_OBJ_NULL; + + for (size_t i = 0; i < n_alarms; i++) { + if (MP_OBJ_IS_TYPE(alarms[i], &alarm_pin_pin_alarm_type)) { + mp_raise_NotImplementedError(translate("PinAlarm not yet implemented")); + } + else if (MP_OBJ_IS_TYPE(alarms[i], &alarm_time_time_alarm_type)) { + if (time_alarm_set) { + mp_raise_ValueError(translate("Only one alarm.time alarm can be set.")); + } + time_alarm = MP_OBJ_TO_PTR(alarms[i]); + time_alarm_set = true; + } + } + + ESP_LOGI("ALARM", "waiting for alarms"); + + if (time_alarm_set && n_alarms == 1) { + // If we're only checking time, avoid a polling loop, so maybe we can save some power. + const mp_float_t now_secs = uint64_to_float(common_hal_time_monotonic_ms()) / 1000.0f; + const mp_float_t wakeup_in_secs = MAX(0.0f, time_alarm->monotonic_time - now_secs); + const uint32_t delay_ms = (uint32_t) (wakeup_in_secs * 1000.0f); + ESP_LOGI("ALARM", "Delay for ms: %d", delay_ms); + common_hal_time_delay_ms((uint32_t) delay_ms); + } else { + // Poll for alarms. + while (true) { + RUN_BACKGROUND_TASKS; + // Allow ctrl-C interrupt. + if (mp_hal_is_interrupted()) { + return mp_const_none; + } + + // TODO: Check PinAlarms. + + if (time_alarm != MP_OBJ_NULL && + common_hal_time_monotonic_ms() * 1000.f >= time_alarm->monotonic_time) { + return time_alarm; + } + } + } + + return mp_const_none; +} + mp_obj_t common_hal_alarm_sleep_until_alarms(size_t n_alarms, const mp_obj_t *alarms) { - setup_alarms(n_alarms, alarms); + if (n_alarms == 0) { + return mp_const_none; + } + + setup_sleep_alarms(n_alarms, alarms); // Shut down wifi cleanly. esp_wifi_stop(); + ESP_LOGI("ALARM", "start light sleep"); esp_light_sleep_start(); return common_hal_alarm_get_wake_alarm(); } void common_hal_alarm_exit_and_deep_sleep_until_alarms(size_t n_alarms, const mp_obj_t *alarms) { - setup_alarms(n_alarms, alarms); + setup_sleep_alarms(n_alarms, alarms); // Shut down wifi cleanly. esp_wifi_stop(); + ESP_LOGI("ALARM", "start deep sleep"); esp_deep_sleep_start(); } diff --git a/ports/esp32s2/common-hal/microcontroller/__init__.c b/ports/esp32s2/common-hal/microcontroller/__init__.c index 184f5be696..b7bea4e6b8 100644 --- a/ports/esp32s2/common-hal/microcontroller/__init__.c +++ b/ports/esp32s2/common-hal/microcontroller/__init__.c @@ -42,9 +42,6 @@ #include "freertos/FreeRTOS.h" -#include "esp_sleep.h" -#include "esp_wifi.h" - void common_hal_mcu_delay_us(uint32_t delay) { mp_hal_delay_us(delay); } diff --git a/shared-bindings/alarm/__init__.c b/shared-bindings/alarm/__init__.c index 4c2189c0d0..195ec63745 100644 --- a/shared-bindings/alarm/__init__.c +++ b/shared-bindings/alarm/__init__.c @@ -25,40 +25,46 @@ */ #include "py/obj.h" +#include "py/reload.h" #include "py/runtime.h" #include "shared-bindings/alarm/__init__.h" #include "shared-bindings/alarm/pin/PinAlarm.h" #include "shared-bindings/alarm/time/TimeAlarm.h" +#include "shared-bindings/supervisor/Runtime.h" #include "shared-bindings/time/__init__.h" -#include "supervisor/shared/rgb_led_status.h" +#include "supervisor/shared/autoreload.h" #include "supervisor/shared/workflow.h" -// Wait this long to see if USB is being connected (enumeration starting). -#define CIRCUITPY_USB_CONNECTING_DELAY 1 -// Wait this long before going into deep sleep if connected. This -// allows the user to ctrl-C before deep sleep starts. -#define CIRCUITPY_USB_CONNECTED_DEEP_SLEEP_DELAY 5 +// Wait this long imediately after startup to see if we are connected to USB. +#define CIRCUITPY_USB_CONNECTED_SLEEP_DELAY 5 -//| """Power-saving light and deep sleep. Alarms can be set to wake up from sleep. +//| """Alarms and sleep //| -//| The `alarm` module provides sleep related functionality. There are two supported levels of -//| sleep, light and deep. +//| Provides alarms that trigger based on time intervals or on external events, such as pin +//| changes. +//| The program can simply wait for these alarms, or go into a sleep state and +//| and be awoken when they trigger. //| -//| Light sleep leaves the CPU and RAM powered so that CircuitPython can resume where it left off -//| after being woken up. CircuitPython automatically goes into a light sleep when `time.sleep()` is -//| called. To light sleep until a non-time alarm use `alarm.sleep_until_alarms()`. Any active -//| peripherals, such as I2C, are left on. +//| There are two supported levels of sleep: light sleep and deep sleep. //| -//| Deep sleep shuts down power to nearly all of the chip including the CPU and RAM. This can save -//| a more significant amount of power, but CircuitPython must start ``code.py`` from the beginning when +//| Light sleep leaves the CPU and RAM powered so the program can resume after sleeping. +//| +//| *However, note that on some platforms, light sleep will shut down some communications, including +//| WiFi and/or Bluetooth.* +//| +//| Deep sleep shuts down power to nearly all of the microcontroller including the CPU and RAM. This can save +//| a more significant amount of power, but CircuitPython must restart ``code.py`` from the beginning when //| awakened. //| """ //| //| wake_alarm: Alarm -//| """The most recent alarm to wake us up from a sleep (light or deep.)""" +//| """The most recently triggered alarm. If CircuitPython was sleeping, the alarm the woke it from sleep.""" //| + +// wake_alarm is implemented as a dictionary entry, so there's no code here. + void validate_objs_are_alarms(size_t n_args, const mp_obj_t *objs) { for (size_t i = 0; i < n_args; i++) { if (MP_OBJ_IS_TYPE(objs[i], &alarm_pin_pin_alarm_type) || @@ -69,9 +75,36 @@ void validate_objs_are_alarms(size_t n_args, const mp_obj_t *objs) { } } +//| def wait_until_alarms(*alarms: Alarm) -> Alarm: +//| """Wait for one of the alarms to trigger. The triggering alarm is returned. +//| is returned, and is also available as `alarm.wake_alarm`. Nothing is shut down +//| or interrupted. Power consumption will be reduced if possible. +//| +//| If no alarms are specified, return immediately. +//| """ +//| ... +//| +STATIC mp_obj_t alarm_wait_until_alarms(size_t n_args, const mp_obj_t *args) { + validate_objs_are_alarms(n_args, args); + common_hal_alarm_wait_until_alarms(n_args, args); + return mp_const_none; +} +MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(alarm_wait_until_alarms_obj, 1, MP_OBJ_FUN_ARGS_MAX, alarm_wait_until_alarms); + //| def sleep_until_alarms(*alarms: Alarm) -> Alarm: //| """Go into a light sleep until awakened one of the alarms. The alarm causing the wake-up -//| is returned, and is also available as `alarm.wake_alarm`. +//| is returned, and is also available as `alarm.wake_alarm`. +//| +//| Some functionality may be shut down during sleep. On ESP32-S2, WiFi is turned off, +//| and existing connections are broken. +//| +//| If no alarms are specified, return immediately. +//| +//| **If CircuitPython is connected to a host computer,** `alarm.sleep_until_alarms()` +//| **does not go into light sleep.** +//| Instead, light sleep is simulated by doing `alarm.wait_until_alarms()`, +//| This allows the user to interrupt an existing program with ctrl-C, +//| and to edit the files in CIRCUITPY, which would not be possible in true light sleep //| """ //| ... //| @@ -84,47 +117,60 @@ MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(alarm_sleep_until_alarms_obj, 1, MP_OBJ_FUN_ //| def exit_and_deep_sleep_until_alarms(*alarms: Alarm) -> None: //| """Exit the program and go into a deep sleep, until awakened by one of the alarms. +//| This function does not return. //| //| When awakened, the microcontroller will restart and will run ``boot.py`` and ``code.py`` //| from the beginning. //| -//| An alarm equivalent to the one that caused the wake-up is available as `alarm.wake_alarm`. +//| After restart, an alarm *equivalent* to the one that caused the wake-up +//| will be available as `alarm.wake_alarm`. //| Its type and/or attributes may not correspond exactly to the original alarm. //| For time-base alarms, currently, an `alarm.time.TimeAlarm()` is created. //| //| If no alarms are specified, the microcontroller will deep sleep until reset. //| -//| If CircuitPython is unconnected to a host computer, go into deep sleep immediately. -//| But if it already connected or in the process of connecting to a host computer, wait at least -//| five seconds after starting code.py before entering deep sleep. -//| This allows interrupting a program that would otherwise go into deep sleep too quickly -//| to interrupt from the keyboard. +//| **If CircuitPython is connected to a host computer, `alarm.exit_and_deep_sleep_until_alarms()` +//| does not go into deep sleep.** +//| Instead, deep sleep is simulated by first doing `alarm.wait_until_alarms()`, +//| and then, when an alarm triggers, by restarting CircuitPython. +//| This allows the user to interrupt an existing program with ctrl-C, +//| and to edit the files in CIRCUITPY, which would not be possible in true deep sleep. +//| +//| Here is skeletal example that deep-sleeps and restarts every 60 seconds: +//| +//| .. code-block:: python +//| +//| import alarm +//| import time +//| +//| print("Waking up") +//| +//| # Set an alarm for 60 seconds from now. +//| time_alarm = alarm.time.TimeAlarm(monotonic_time=time.monotonic() + 60) +//| +//| # Deep sleep until the alarm goes off. Then restart the program. +//| alarm.exit_and_deep_sleep_until_alarms(time_alarm) //| """ //| ... //| STATIC mp_obj_t alarm_exit_and_deep_sleep_until_alarms(size_t n_args, const mp_obj_t *args) { validate_objs_are_alarms(n_args, args); - int64_t connecting_delay_msec = CIRCUITPY_USB_CONNECTING_DELAY * 1024 - supervisor_ticks_ms64(); + // Make sure we have been awake long enough for USB to connect (enumeration delay). + int64_t connecting_delay_msec = CIRCUITPY_USB_CONNECTED_SLEEP_DELAY * 1024 - supervisor_ticks_ms64(); if (connecting_delay_msec > 0) { common_hal_time_delay_ms(connecting_delay_msec * 1000 / 1024); } - // If connected, wait for the program to be running at least as long as - // CIRCUITPY_USB_CONNECTED_DEEP_SLEEP_DELAY. This allows a user to ctrl-C the running - // program in case it is in a tight deep sleep loop that would otherwise be difficult - // or impossible to interrupt. - // Indicate that we're delaying with the SAFE_MODE color. - int64_t delay_before_sleeping_msec = - supervisor_ticks_ms64() - CIRCUITPY_USB_CONNECTED_DEEP_SLEEP_DELAY * 1000; - if (supervisor_workflow_connecting() && delay_before_sleeping_msec > 0) { - temp_status_color(SAFE_MODE); - common_hal_time_delay_ms(delay_before_sleeping_msec); - clear_temp_status(); + if (supervisor_workflow_active()) { + common_hal_alarm_wait_until_alarms(n_args, args); + reload_requested = true; + supervisor_set_run_reason(RUN_REASON_STARTUP); + mp_raise_reload_exception(); + } else { + common_hal_alarm_exit_and_deep_sleep_until_alarms(n_args, args); + // Does not return. } - - common_hal_alarm_exit_and_deep_sleep_until_alarms(n_args, args); - // Does not return. return mp_const_none; } MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(alarm_exit_and_deep_sleep_until_alarms_obj, 1, MP_OBJ_FUN_ARGS_MAX, alarm_exit_and_deep_sleep_until_alarms); diff --git a/shared-bindings/alarm/__init__.h b/shared-bindings/alarm/__init__.h index 968136345c..26dbb2897c 100644 --- a/shared-bindings/alarm/__init__.h +++ b/shared-bindings/alarm/__init__.h @@ -31,6 +31,7 @@ #include "common-hal/alarm/__init__.h" +extern mp_obj_t common_hal_alarm_wait_until_alarms(size_t n_alarms, const mp_obj_t *alarms); extern mp_obj_t common_hal_alarm_sleep_until_alarms(size_t n_alarms, const mp_obj_t *alarms); extern void common_hal_alarm_exit_and_deep_sleep_until_alarms(size_t n_alarms, const mp_obj_t *alarms); diff --git a/shared-bindings/alarm/pin/PinAlarm.c b/shared-bindings/alarm/pin/PinAlarm.c index fadd1b0d4a..a6497d4cde 100644 --- a/shared-bindings/alarm/pin/PinAlarm.c +++ b/shared-bindings/alarm/pin/PinAlarm.c @@ -56,7 +56,7 @@ //| to ``value`` to trigger the alarm. On some ports, edge-triggering may not be available, //| particularly for deep-sleep alarms. //| :param bool pull: Enable a pull-up or pull-down which pulls the pin to the level opposite -//| opposite that of ``value``. For instance, if ``value`` is set to ``True``, setting ``pull`` +//| that of ``value``. For instance, if ``value`` is set to ``True``, setting ``pull`` //| to ``True`` will enable a pull-down, to hold the pin low normally until an outside signal //| pulls it high. //| """ @@ -89,7 +89,7 @@ STATIC mp_obj_t alarm_pin_pin_alarm_make_new(const mp_obj_type_t *type, mp_uint_ return MP_OBJ_FROM_PTR(self); } -//| pins: Tuple[microcontroller.pin] +//| pins: Tuple[microcontroller.Pin] //| """The trigger pins.""" //| STATIC mp_obj_t alarm_pin_pin_alarm_obj_get_pins(mp_obj_t self_in) { @@ -105,7 +105,7 @@ const mp_obj_property_t alarm_pin_pin_alarm_pins_obj = { (mp_obj_t)&mp_const_none_obj}, }; -//| value: Tuple[microcontroller.pin] +//| value: Tuple[microcontroller.Pin] //| """The value on which to trigger.""" //| STATIC mp_obj_t alarm_pin_pin_alarm_obj_get_value(mp_obj_t self_in) { diff --git a/supervisor/shared/workflow.c b/supervisor/shared/workflow.c index 8e4ec16c0b..4986c09570 100644 --- a/supervisor/shared/workflow.c +++ b/supervisor/shared/workflow.c @@ -33,8 +33,10 @@ void supervisor_workflow_reset(void) { // Return true as soon as USB communication with host has started, // even before enumeration is done. +// Not that some chips don't notice when USB is unplugged after first being plugged in, +// so this is not perfect, but tud_suspended() check helps. bool supervisor_workflow_connecting(void) { - return tud_connected(); + return tud_connected() && !tud_suspended(); } // Return true if host has completed connection to us (such as USB enumeration). From f96475cbbf5417531bbdd302b720658c5fa0f541 Mon Sep 17 00:00:00 2001 From: Dan Halbert Date: Fri, 27 Nov 2020 16:24:36 -0500 Subject: [PATCH 29/34] update Requests; rolled back by accident --- frozen/Adafruit_CircuitPython_Requests | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/frozen/Adafruit_CircuitPython_Requests b/frozen/Adafruit_CircuitPython_Requests index 43017e30a1..53902152c6 160000 --- a/frozen/Adafruit_CircuitPython_Requests +++ b/frozen/Adafruit_CircuitPython_Requests @@ -1 +1 @@ -Subproject commit 43017e30a1e772b67ac68293a944e863c031e389 +Subproject commit 53902152c674b0ba31536b50291f7ddd28960f47 From 65e2fe46540abc09f341c39d877eafeb791933f1 Mon Sep 17 00:00:00 2001 From: Dan Halbert Date: Fri, 27 Nov 2020 23:27:15 -0500 Subject: [PATCH 30/34] fix stub problems; touch up doc --- shared-bindings/_typing/__init__.pyi | 5 ++++- shared-bindings/alarm/time/TimeAlarm.c | 2 +- shared-bindings/microcontroller/__init__.c | 9 --------- tools/extract_pyi.py | 2 +- 4 files changed, 6 insertions(+), 12 deletions(-) diff --git a/shared-bindings/_typing/__init__.pyi b/shared-bindings/_typing/__init__.pyi index 2716936860..cc4a0a4391 100644 --- a/shared-bindings/_typing/__init__.pyi +++ b/shared-bindings/_typing/__init__.pyi @@ -2,6 +2,9 @@ from typing import Union +import alarm +import alarm.pin +import alarm.time import array import audiocore import audiomixer @@ -61,5 +64,5 @@ Alarm = Union[ - `alarm.pin.PinAlarm` - `alarm.time.TimeAlarm` - You can use these alarms to wake from light or deep sleep. + You can use these alarms to wake up from light or deep sleep. """ diff --git a/shared-bindings/alarm/time/TimeAlarm.c b/shared-bindings/alarm/time/TimeAlarm.c index 6339b850c6..17a4faac25 100644 --- a/shared-bindings/alarm/time/TimeAlarm.c +++ b/shared-bindings/alarm/time/TimeAlarm.c @@ -43,7 +43,7 @@ mp_obj_t MP_WEAK rtc_get_time_source_time(void) { //| class TimeAlarm: //| """Trigger an alarm when the specified time is reached.""" //| -//| def __init__(self, monotonic_time: Optional[Float] = None, epoch_time: Optional[int] = None) -> None: +//| def __init__(self, monotonic_time: Optional[float] = None, epoch_time: Optional[int] = None) -> None: //| """Create an alarm that will be triggered when `time.monotonic()` would equal //| ``monotonic_time``, or when `time.time()` would equal ``epoch_time``. //| Only one of the two arguments can be given. diff --git a/shared-bindings/microcontroller/__init__.c b/shared-bindings/microcontroller/__init__.c index d09cf8f445..8a77d1df5b 100644 --- a/shared-bindings/microcontroller/__init__.c +++ b/shared-bindings/microcontroller/__init__.c @@ -147,15 +147,6 @@ STATIC MP_DEFINE_CONST_FUN_OBJ_0(mcu_reset_obj, mcu_reset); //| This object is the sole instance of `watchdog.WatchDogTimer` when available or ``None`` otherwise.""" //| - -//| """:mod:`microcontroller.pin` --- Microcontroller pin names -//| -------------------------------------------------------- -//| -//| .. module:: microcontroller.pin -//| :synopsis: Microcontroller pin names -//| -//| References to pins as named by the microcontroller""" -//| const mp_obj_module_t mcu_pin_module = { .base = { &mp_type_module }, .globals = (mp_obj_dict_t*)&mcu_pin_globals, diff --git a/tools/extract_pyi.py b/tools/extract_pyi.py index b7ce584a1e..2730102ac0 100644 --- a/tools/extract_pyi.py +++ b/tools/extract_pyi.py @@ -19,7 +19,7 @@ import black IMPORTS_IGNORE = frozenset({'int', 'float', 'bool', 'str', 'bytes', 'tuple', 'list', 'set', 'dict', 'bytearray', 'slice', 'file', 'buffer', 'range', 'array', 'struct_time'}) IMPORTS_TYPING = frozenset({'Any', 'Optional', 'Union', 'Tuple', 'List', 'Sequence', 'NamedTuple', 'Iterable', 'Iterator', 'Callable', 'AnyStr', 'overload', 'Type'}) IMPORTS_TYPES = frozenset({'TracebackType'}) -CPY_TYPING = frozenset({'ReadableBuffer', 'WriteableBuffer', 'AudioSample', 'FrameBuffer'}) +CPY_TYPING = frozenset({'ReadableBuffer', 'WriteableBuffer', 'AudioSample', 'FrameBuffer', 'Alarm'}) def is_typed(node, allow_any=False): From 2830cc9433dc9954c781c5351f3051dcacaaa467 Mon Sep 17 00:00:00 2001 From: Dan Halbert Date: Fri, 27 Nov 2020 23:57:59 -0500 Subject: [PATCH 31/34] make translate --- locale/circuitpython.pot | 36 ++++++++++++++++++++++++++++++++++-- 1 file changed, 34 insertions(+), 2 deletions(-) diff --git a/locale/circuitpython.pot b/locale/circuitpython.pot index 38deb62d70..63d818da9c 100644 --- a/locale/circuitpython.pot +++ b/locale/circuitpython.pot @@ -8,7 +8,7 @@ msgid "" msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2020-11-24 15:40-0500\n" +"POT-Creation-Date: 2020-11-27 23:57-0500\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language-Team: LANGUAGE \n" @@ -1448,6 +1448,10 @@ msgid "" "%d bpp given" msgstr "" +#: ports/esp32s2/common-hal/alarm/__init__.c +msgid "Only one alarm.time alarm can be set." +msgstr "" + #: shared-module/displayio/ColorConverter.c msgid "Only one color can be transparent at a time" msgstr "" @@ -1505,6 +1509,10 @@ msgstr "" msgid "Pin number already reserved by EXTI" msgstr "" +#: ports/esp32s2/common-hal/alarm/__init__.c +msgid "PinAlarm not yet implemented" +msgstr "" + #: shared-bindings/rgbmatrix/RGBMatrix.c #, c-format msgid "" @@ -1566,7 +1574,7 @@ msgstr "" msgid "RTC calibration is not supported on this board" msgstr "" -#: shared-bindings/time/__init__.c +#: shared-bindings/alarm/time/TimeAlarm.c shared-bindings/time/__init__.c msgid "RTC is not supported on this board" msgstr "" @@ -1712,6 +1720,10 @@ msgstr "" msgid "Supply at least one UART pin" msgstr "" +#: shared-bindings/alarm/time/TimeAlarm.c +msgid "Supply one of monotonic_time or epoch_time" +msgstr "" + #: shared-bindings/gnss/GNSS.c msgid "System entry must be gnss.SatelliteSystem" msgstr "" @@ -1775,6 +1787,10 @@ msgstr "" msgid "Tile width must exactly divide bitmap width" msgstr "" +#: shared-bindings/alarm/time/TimeAlarm.c +msgid "Time is in the past." +msgstr "" + #: ports/nrf/common-hal/_bleio/Adapter.c #, c-format msgid "Timeout is too long: Maximum timeout length is %d seconds" @@ -2489,6 +2505,10 @@ msgstr "" msgid "end_x should be an int" msgstr "" +#: shared-bindings/alarm/time/TimeAlarm.c +msgid "epoch_time not supported on this board" +msgstr "" + #: ports/nrf/common-hal/busio/UART.c #, c-format msgid "error = 0x%08lX" @@ -2858,6 +2878,10 @@ msgstr "" msgid "invalid syntax for number" msgstr "" +#: ports/esp32s2/common-hal/alarm/pin/__init__.c +msgid "io must be rtc io" +msgstr "" + #: py/objtype.c msgid "issubclass() arg 1 must be a class" msgstr "" @@ -3545,6 +3569,10 @@ msgstr "" msgid "trapz is defined for 1D arrays of equal length" msgstr "" +#: ports/esp32s2/common-hal/alarm/pin/__init__.c +msgid "trigger level must be 0 or 1" +msgstr "" + #: extmod/ulab/code/linalg/linalg.c msgid "tuple index out of range" msgstr "" @@ -3687,6 +3715,10 @@ msgstr "" msgid "vectors must have same lengths" msgstr "" +#: ports/esp32s2/common-hal/alarm/pin/__init__.c +msgid "wakeup conflict" +msgstr "" + #: ports/esp32s2/common-hal/watchdog/WatchDogTimer.c msgid "watchdog not initialized" msgstr "" From 28d9e9186e6a9a153217535bd2d9f144672846bb Mon Sep 17 00:00:00 2001 From: Dan Halbert Date: Sat, 28 Nov 2020 10:12:46 -0500 Subject: [PATCH 32/34] Disable complex arithmetic on SAMD21 builds to make space --- ports/atmel-samd/mpconfigport.h | 1 + py/circuitpy_mpconfig.h | 2 ++ 2 files changed, 3 insertions(+) diff --git a/ports/atmel-samd/mpconfigport.h b/ports/atmel-samd/mpconfigport.h index ed10da9b9d..bce89e0b99 100644 --- a/ports/atmel-samd/mpconfigport.h +++ b/ports/atmel-samd/mpconfigport.h @@ -42,6 +42,7 @@ #define CIRCUITPY_MCU_FAMILY samd21 #define MICROPY_PY_SYS_PLATFORM "Atmel SAMD21" #define SPI_FLASH_MAX_BAUDRATE 8000000 +#define MICROPY_PY_BUILTINS_COMPLEX (0) #define MICROPY_PY_BUILTINS_NOTIMPLEMENTED (0) #define MICROPY_PY_FUNCTION_ATTRS (0) // MICROPY_PY_UJSON depends on MICROPY_PY_IO diff --git a/py/circuitpy_mpconfig.h b/py/circuitpy_mpconfig.h index 799217777c..4b847de38b 100644 --- a/py/circuitpy_mpconfig.h +++ b/py/circuitpy_mpconfig.h @@ -188,7 +188,9 @@ typedef long mp_off_t; #define MICROPY_COMP_FSTRING_LITERAL (MICROPY_CPYTHON_COMPAT) #define MICROPY_MODULE_WEAK_LINKS (0) #define MICROPY_PY_ALL_SPECIAL_METHODS (CIRCUITPY_FULL_BUILD) +#ifndef MICROPY_PY_BUILTINS_COMPLEX #define MICROPY_PY_BUILTINS_COMPLEX (CIRCUITPY_FULL_BUILD) +#endif #define MICROPY_PY_BUILTINS_FROZENSET (CIRCUITPY_FULL_BUILD) #define MICROPY_PY_BUILTINS_STR_CENTER (CIRCUITPY_FULL_BUILD) #define MICROPY_PY_BUILTINS_STR_PARTITION (CIRCUITPY_FULL_BUILD) From 8b7c23c1ee5d3fbfbda9116d6689e99f44e3b95a Mon Sep 17 00:00:00 2001 From: Dan Halbert Date: Tue, 1 Dec 2020 20:01:14 -0500 Subject: [PATCH 33/34] address review comments --- lib/utils/pyexec.c | 6 +- lib/utils/pyexec.h | 1 + main.c | 10 +++ .../common-hal/microcontroller/Processor.c | 2 +- .../common-hal/microcontroller/Processor.c | 2 +- ports/esp32s2/common-hal/alarm/__init__.c | 43 +++++++--- ports/esp32s2/common-hal/alarm/pin/PinAlarm.c | 13 +-- ports/esp32s2/common-hal/alarm/pin/PinAlarm.h | 2 +- .../common-hal/microcontroller/Processor.c | 2 +- .../common-hal/microcontroller/Processor.c | 2 +- .../common-hal/microcontroller/Processor.c | 2 +- .../common-hal/microcontroller/Processor.c | 2 +- py/obj.h | 4 + py/objexcept.c | 3 + py/reload.c | 22 ++++- py/reload.h | 22 ++++- shared-bindings/alarm/__init__.c | 80 +++++++++---------- shared-bindings/alarm/__init__.h | 4 +- shared-bindings/alarm/pin/PinAlarm.c | 37 ++++----- shared-bindings/alarm/pin/PinAlarm.h | 4 +- 20 files changed, 160 insertions(+), 103 deletions(-) diff --git a/lib/utils/pyexec.c b/lib/utils/pyexec.c index 378fb6267d..68a3710ce6 100755 --- a/lib/utils/pyexec.c +++ b/lib/utils/pyexec.c @@ -101,7 +101,7 @@ STATIC int parse_compile_execute(const void *source, mp_parse_input_kind_t input #endif } - // If the code was loaded from a file its likely to be running for a while so we'll long + // If the code was loaded from a file it's likely to be running for a while so we'll long // live it and collect any garbage before running. if (input_kind == MP_PARSE_FILE_INPUT) { module_fun = make_obj_long_lived(module_fun, 6); @@ -132,6 +132,10 @@ STATIC int parse_compile_execute(const void *source, mp_parse_input_kind_t input if (mp_obj_is_subclass_fast(mp_obj_get_type((mp_obj_t)nlr.ret_val), &mp_type_SystemExit)) { // at the moment, the value of SystemExit is unused ret = pyexec_system_exit; +#if CIRCUITPY_ALARM + } else if (mp_obj_is_subclass_fast(mp_obj_get_type((mp_obj_t)nlr.ret_val), &mp_type_DeepSleepRequest)) { + ret = PYEXEC_DEEP_SLEEP; +#endif } else { if ((mp_obj_t) nlr.ret_val != MP_OBJ_FROM_PTR(&MP_STATE_VM(mp_reload_exception))) { mp_obj_print_exception(&mp_plat_print, (mp_obj_t)nlr.ret_val); diff --git a/lib/utils/pyexec.h b/lib/utils/pyexec.h index cef72a76c7..4c773cd640 100644 --- a/lib/utils/pyexec.h +++ b/lib/utils/pyexec.h @@ -49,6 +49,7 @@ extern int pyexec_system_exit; #define PYEXEC_FORCED_EXIT (0x100) #define PYEXEC_SWITCH_MODE (0x200) #define PYEXEC_EXCEPTION (0x400) +#define PYEXEC_DEEP_SLEEP (0x800) int pyexec_raw_repl(void); int pyexec_friendly_repl(void); diff --git a/main.c b/main.c index dda439d6de..270c0eacf7 100755 --- a/main.c +++ b/main.c @@ -291,11 +291,21 @@ STATIC bool run_code_py(safe_mode_t safe_mode) { } } #endif + + // TODO: on deep sleep, make sure display is refreshed before sleeping (for e-ink). + cleanup_after_vm(heap); if (result.return_code & PYEXEC_FORCED_EXIT) { return reload_requested; } + + #if CIRCUITPY_ALARM + if (result.return_code & PYEXEC_DEEP_SLEEP) { + common_hal_alarm_enter_deep_sleep(); + // Does not return. + } + #endif } // Program has finished running. diff --git a/ports/atmel-samd/common-hal/microcontroller/Processor.c b/ports/atmel-samd/common-hal/microcontroller/Processor.c index 9955212657..8c288a352e 100644 --- a/ports/atmel-samd/common-hal/microcontroller/Processor.c +++ b/ports/atmel-samd/common-hal/microcontroller/Processor.c @@ -352,5 +352,5 @@ void common_hal_mcu_processor_get_uid(uint8_t raw_id[]) { } mcu_reset_reason_t common_hal_mcu_processor_get_reset_reason(void) { - return RESET_REASON_POWER_ON; + return RESET_REASON_UNKNOWN; } diff --git a/ports/cxd56/common-hal/microcontroller/Processor.c b/ports/cxd56/common-hal/microcontroller/Processor.c index bd778e80dd..3cb187de61 100644 --- a/ports/cxd56/common-hal/microcontroller/Processor.c +++ b/ports/cxd56/common-hal/microcontroller/Processor.c @@ -50,5 +50,5 @@ void common_hal_mcu_processor_get_uid(uint8_t raw_id[]) { } mcu_reset_reason_t common_hal_mcu_processor_get_reset_reason(void) { - return RESET_REASON_POWER_ON; + return RESET_REASON_UNKNOWN; } diff --git a/ports/esp32s2/common-hal/alarm/__init__.c b/ports/esp32s2/common-hal/alarm/__init__.c index e044103bce..11e173fe2e 100644 --- a/ports/esp32s2/common-hal/alarm/__init__.c +++ b/ports/esp32s2/common-hal/alarm/__init__.c @@ -29,15 +29,16 @@ #include "py/objtuple.h" #include "py/runtime.h" -#include "shared-bindings/alarm/__init__.h" #include "shared-bindings/alarm/pin/PinAlarm.h" #include "shared-bindings/alarm/time/TimeAlarm.h" #include "shared-bindings/microcontroller/__init__.h" #include "shared-bindings/time/__init__.h" +#include "shared-bindings/wifi/__init__.h" + +#include "common-hal/alarm/__init__.h" #include "esp_log.h" #include "esp_sleep.h" -#include "esp_wifi.h" STATIC mp_obj_tuple_t *_deep_sleep_alarms; @@ -101,7 +102,7 @@ STATIC void setup_sleep_alarms(size_t n_alarms, const mp_obj_t *alarms) { 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); const uint64_t sleep_for_us = (uint64_t) (wakeup_in_secs * 1000000); - ESP_LOGI("ALARM", "Sleep for us: %lld", sleep_for_us); + ESP_LOGI("ALARM", "will sleep for us: %lld", sleep_for_us); esp_sleep_enable_timer_wakeup(sleep_for_us); } } @@ -157,25 +158,41 @@ mp_obj_t common_hal_alarm_wait_until_alarms(size_t n_alarms, const mp_obj_t *ala return mp_const_none; } -mp_obj_t common_hal_alarm_sleep_until_alarms(size_t n_alarms, const mp_obj_t *alarms) { +// 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) { + return !common_hal_wifi_radio_get_enabled(&common_hal_wifi_radio_obj); +} + +mp_obj_t common_hal_alarm_light_sleep_until_alarms(size_t n_alarms, const mp_obj_t *alarms) { if (n_alarms == 0) { return mp_const_none; } - setup_sleep_alarms(n_alarms, alarms); - - // Shut down wifi cleanly. - esp_wifi_stop(); - ESP_LOGI("ALARM", "start light sleep"); - esp_light_sleep_start(); - return common_hal_alarm_get_wake_alarm(); + if (light_sleep_ok()) { + ESP_LOGI("ALARM", "start light sleep"); + setup_sleep_alarms(n_alarms, alarms); + esp_light_sleep_start(); + return common_hal_alarm_get_wake_alarm(); + } else { + // Don't do an ESP32 light sleep. + return common_hal_alarm_wait_until_alarms(n_alarms, alarms); + } } void common_hal_alarm_exit_and_deep_sleep_until_alarms(size_t n_alarms, const mp_obj_t *alarms) { setup_sleep_alarms(n_alarms, alarms); - // Shut down wifi cleanly. - esp_wifi_stop(); + // Raise an exception, which will be processed in main.c. + mp_raise_arg1(&mp_type_DeepSleepRequest, NULL); +} + +void common_hal_alarm_prepare_for_deep_sleep(void) { + // Turn off WiFi and anything else that should be shut down cleanly. + common_hal_wifi_radio_set_enabled(&common_hal_wifi_radio_obj, false); +} + +void NORETURN common_hal_alarm_enter_deep_sleep(void) { ESP_LOGI("ALARM", "start deep sleep"); esp_deep_sleep_start(); } diff --git a/ports/esp32s2/common-hal/alarm/pin/PinAlarm.c b/ports/esp32s2/common-hal/alarm/pin/PinAlarm.c index 438d6885dc..582a665729 100644 --- a/ports/esp32s2/common-hal/alarm/pin/PinAlarm.c +++ b/ports/esp32s2/common-hal/alarm/pin/PinAlarm.c @@ -29,26 +29,21 @@ #include "shared-bindings/alarm/pin/PinAlarm.h" #include "shared-bindings/microcontroller/Pin.h" -void common_hal_alarm_pin_pin_alarm_construct(alarm_pin_pin_alarm_obj_t *self, const mp_obj_t pins[], size_t num_pins, bool value, bool all_same_value, bool edge, bool pull) { - self->pins = mp_obj_new_tuple(num_pins, pins); +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) { + self->pin = pin; self->value = value; - self->all_same_value = all_same_value; self->edge = edge; self->pull = pull; } -mp_obj_tuple_t *common_hal_alarm_pin_pin_alarm_get_pins(alarm_pin_pin_alarm_obj_t *self) { - return self->pins; +mcu_pin_obj_t *common_hal_alarm_pin_pin_alarm_get_pin(alarm_pin_pin_alarm_obj_t *self) { + return self->pin; } bool common_hal_alarm_pin_pin_alarm_get_value(alarm_pin_pin_alarm_obj_t *self) { return self->value; } -bool common_hal_alarm_pin_pin_alarm_get_all_same_value(alarm_pin_pin_alarm_obj_t *self) { - return self->all_same_value; -} - bool common_hal_alarm_pin_pin_alarm_get_edge(alarm_pin_pin_alarm_obj_t *self) { return self->edge; } diff --git a/ports/esp32s2/common-hal/alarm/pin/PinAlarm.h b/ports/esp32s2/common-hal/alarm/pin/PinAlarm.h index d7e7e2552a..0eaa7777f5 100644 --- a/ports/esp32s2/common-hal/alarm/pin/PinAlarm.h +++ b/ports/esp32s2/common-hal/alarm/pin/PinAlarm.h @@ -29,7 +29,7 @@ typedef struct { mp_obj_base_t base; - mp_obj_tuple_t *pins; + mcu_pin_obj_t *pin; bool value; bool all_same_value; bool edge; diff --git a/ports/litex/common-hal/microcontroller/Processor.c b/ports/litex/common-hal/microcontroller/Processor.c index 013a7ca035..4d4f88288e 100644 --- a/ports/litex/common-hal/microcontroller/Processor.c +++ b/ports/litex/common-hal/microcontroller/Processor.c @@ -66,5 +66,5 @@ void common_hal_mcu_processor_get_uid(uint8_t raw_id[]) { } mcu_reset_reason_t common_hal_mcu_processor_get_reset_reason(void) { - return RESET_REASON_POWER_ON; + return RESET_REASON_UNKNOWN; } diff --git a/ports/mimxrt10xx/common-hal/microcontroller/Processor.c b/ports/mimxrt10xx/common-hal/microcontroller/Processor.c index 28fe67db7c..efbde35d28 100644 --- a/ports/mimxrt10xx/common-hal/microcontroller/Processor.c +++ b/ports/mimxrt10xx/common-hal/microcontroller/Processor.c @@ -73,5 +73,5 @@ void common_hal_mcu_processor_get_uid(uint8_t raw_id[]) { } mcu_reset_reason_t common_hal_mcu_processor_get_reset_reason(void) { - return RESET_REASON_POWER_ON; + return RESET_REASON_UNKNOWN; } diff --git a/ports/nrf/common-hal/microcontroller/Processor.c b/ports/nrf/common-hal/microcontroller/Processor.c index e2695139c5..ab5f29b5db 100644 --- a/ports/nrf/common-hal/microcontroller/Processor.c +++ b/ports/nrf/common-hal/microcontroller/Processor.c @@ -123,5 +123,5 @@ void common_hal_mcu_processor_get_uid(uint8_t raw_id[]) { } mcu_reset_reason_t common_hal_mcu_processor_get_reset_reason(void) { - return RESET_REASON_POWER_ON; + return RESET_REASON_UNKNOWN; } diff --git a/ports/stm/common-hal/microcontroller/Processor.c b/ports/stm/common-hal/microcontroller/Processor.c index d77d287a9e..dd04c56dce 100644 --- a/ports/stm/common-hal/microcontroller/Processor.c +++ b/ports/stm/common-hal/microcontroller/Processor.c @@ -143,5 +143,5 @@ void common_hal_mcu_processor_get_uid(uint8_t raw_id[]) { } mcu_reset_reason_t common_hal_mcu_processor_get_reset_reason(void) { - return RESET_REASON_POWER_ON; + return RESET_REASON_UNKNOWN; } diff --git a/py/obj.h b/py/obj.h index e055c97506..066562cc43 100644 --- a/py/obj.h +++ b/py/obj.h @@ -640,6 +640,10 @@ extern const mp_obj_type_t mp_type_UnicodeError; extern const mp_obj_type_t mp_type_ValueError; extern const mp_obj_type_t mp_type_ViperTypeError; extern const mp_obj_type_t mp_type_ZeroDivisionError; +#if CIRCUITPY_ALARM +extern const mp_obj_type_t mp_type_DeepSleepRequest; +#endif + // Constant objects, globally accessible // The macros are for convenience only diff --git a/py/objexcept.c b/py/objexcept.c index 01ba6da9c4..afefee2caf 100644 --- a/py/objexcept.c +++ b/py/objexcept.c @@ -318,6 +318,9 @@ MP_DEFINE_EXCEPTION(Exception, BaseException) #if MICROPY_PY_BUILTINS_STR_UNICODE MP_DEFINE_EXCEPTION(UnicodeError, ValueError) //TODO: Implement more UnicodeError subclasses which take arguments +#endif +#if CIRCUITPY_ALARM + MP_DEFINE_EXCEPTION(DeepSleepRequest, BaseException) #endif MP_DEFINE_EXCEPTION(MpyError, ValueError) /* diff --git a/py/reload.c b/py/reload.c index 95305f2c9c..f9f8a590a6 100644 --- a/py/reload.c +++ b/py/reload.c @@ -1,6 +1,22 @@ -// -// Created by Roy Hooper on 2018-05-14. -// + /* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2018 by Roy Hooper + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ #include "reload.h" #include "py/mpstate.h" diff --git a/py/reload.h b/py/reload.h index 72e84e5ca6..3e8928a32c 100644 --- a/py/reload.h +++ b/py/reload.h @@ -1,6 +1,22 @@ -// -// Created by Roy Hooper on 2018-05-14. -// + /* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2018 by Roy Hooper + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ #ifndef CIRCUITPYTHON_RELOAD_H #define CIRCUITPYTHON_RELOAD_H diff --git a/shared-bindings/alarm/__init__.c b/shared-bindings/alarm/__init__.c index 195ec63745..c983130a19 100644 --- a/shared-bindings/alarm/__init__.c +++ b/shared-bindings/alarm/__init__.c @@ -43,19 +43,21 @@ //| //| Provides alarms that trigger based on time intervals or on external events, such as pin //| changes. -//| The program can simply wait for these alarms, or go into a sleep state and -//| and be awoken when they trigger. +//| The program can simply wait for these alarms, or go to sleep and be awoken when they trigger. //| //| There are two supported levels of sleep: light sleep and deep sleep. //| -//| Light sleep leaves the CPU and RAM powered so the program can resume after sleeping. -//| -//| *However, note that on some platforms, light sleep will shut down some communications, including -//| WiFi and/or Bluetooth.* +//| Light sleep keeps sufficient state so the program can resume after sleeping. +//| It does not shut down WiFi, BLE, or other communications, or ongoing activities such +//| as audio playback. It reduces power consumption to the extent possible that leaves +//| these continuing activities running. In some cases there may be no decrease in power consumption. //| //| Deep sleep shuts down power to nearly all of the microcontroller including the CPU and RAM. This can save //| a more significant amount of power, but CircuitPython must restart ``code.py`` from the beginning when //| awakened. +//| +//| For both light sleep and deep sleep, if CircuitPython is connected to a host computer, +//| maintaining the connection takes priority and power consumption may not be reduced. //| """ //| @@ -75,45 +77,39 @@ void validate_objs_are_alarms(size_t n_args, const mp_obj_t *objs) { } } -//| def wait_until_alarms(*alarms: Alarm) -> Alarm: -//| """Wait for one of the alarms to trigger. The triggering alarm is returned. -//| is returned, and is also available as `alarm.wake_alarm`. Nothing is shut down -//| or interrupted. Power consumption will be reduced if possible. -//| -//| If no alarms are specified, return immediately. -//| """ -//| ... -//| -STATIC mp_obj_t alarm_wait_until_alarms(size_t n_args, const mp_obj_t *args) { - validate_objs_are_alarms(n_args, args); - common_hal_alarm_wait_until_alarms(n_args, args); - return mp_const_none; -} -MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(alarm_wait_until_alarms_obj, 1, MP_OBJ_FUN_ARGS_MAX, alarm_wait_until_alarms); - -//| def sleep_until_alarms(*alarms: Alarm) -> Alarm: +//| def light_sleep_until_alarms(*alarms: Alarm) -> Alarm: //| """Go into a light sleep until awakened one of the alarms. The alarm causing the wake-up //| is returned, and is also available as `alarm.wake_alarm`. //| -//| Some functionality may be shut down during sleep. On ESP32-S2, WiFi is turned off, -//| and existing connections are broken. -//| //| If no alarms are specified, return immediately. //| -//| **If CircuitPython is connected to a host computer,** `alarm.sleep_until_alarms()` -//| **does not go into light sleep.** -//| Instead, light sleep is simulated by doing `alarm.wait_until_alarms()`, +//| **If CircuitPython is connected to a host computer, the connection will be maintained, +//| and the microcontroller may not actually go into a light sleep.** //| This allows the user to interrupt an existing program with ctrl-C, -//| and to edit the files in CIRCUITPY, which would not be possible in true light sleep +//| and to edit the files in CIRCUITPY, which would not be possible in true light sleep. +//| Thus, to use light sleep and save significant power, +// it may be necessary to disconnect from the host. //| """ //| ... //| -STATIC mp_obj_t alarm_sleep_until_alarms(size_t n_args, const mp_obj_t *args) { +STATIC mp_obj_t alarm_light_sleep_until_alarms(size_t n_args, const mp_obj_t *args) { validate_objs_are_alarms(n_args, args); - common_hal_alarm_sleep_until_alarms(n_args, args); + + // See if we are connected to a host. + // Make sure we have been awake long enough for USB to connect (enumeration delay). + int64_t connecting_delay_msec = CIRCUITPY_USB_CONNECTED_SLEEP_DELAY * 1024 - supervisor_ticks_ms64(); + if (connecting_delay_msec > 0) { + common_hal_time_delay_ms(connecting_delay_msec * 1000 / 1024); + } + + if (supervisor_workflow_active()) { + common_hal_alarm_wait_until_alarms(n_args, args); + } else { + common_hal_alarm_light_sleep_until_alarms(n_args, args); + } return mp_const_none; } -MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(alarm_sleep_until_alarms_obj, 1, MP_OBJ_FUN_ARGS_MAX, alarm_sleep_until_alarms); +MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(alarm_light_sleep_until_alarms_obj, 1, MP_OBJ_FUN_ARGS_MAX, alarm_light_sleep_until_alarms); //| def exit_and_deep_sleep_until_alarms(*alarms: Alarm) -> None: //| """Exit the program and go into a deep sleep, until awakened by one of the alarms. @@ -130,11 +126,10 @@ MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(alarm_sleep_until_alarms_obj, 1, MP_OBJ_FUN_ //| If no alarms are specified, the microcontroller will deep sleep until reset. //| //| **If CircuitPython is connected to a host computer, `alarm.exit_and_deep_sleep_until_alarms()` -//| does not go into deep sleep.** -//| Instead, deep sleep is simulated by first doing `alarm.wait_until_alarms()`, -//| and then, when an alarm triggers, by restarting CircuitPython. +//| then the connection will be maintained, and the system will not go into deep sleep.** //| This allows the user to interrupt an existing program with ctrl-C, //| and to edit the files in CIRCUITPY, which would not be possible in true deep sleep. +//| Thus, to use deep sleep and save significant power, you will need to disconnect from the host. //| //| Here is skeletal example that deep-sleeps and restarts every 60 seconds: //| @@ -156,6 +151,10 @@ MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(alarm_sleep_until_alarms_obj, 1, MP_OBJ_FUN_ STATIC mp_obj_t alarm_exit_and_deep_sleep_until_alarms(size_t n_args, const mp_obj_t *args) { validate_objs_are_alarms(n_args, args); + // Shut down WiFi, etc. + common_hal_alarm_prepare_for_deep_sleep(); + + // See if we are connected to a host. // Make sure we have been awake long enough for USB to connect (enumeration delay). int64_t connecting_delay_msec = CIRCUITPY_USB_CONNECTED_SLEEP_DELAY * 1024 - supervisor_ticks_ms64(); if (connecting_delay_msec > 0) { @@ -163,6 +162,7 @@ STATIC mp_obj_t alarm_exit_and_deep_sleep_until_alarms(size_t n_args, const mp_o } if (supervisor_workflow_active()) { + // Simulate deep sleep by waiting for an alarm and then restarting when done. common_hal_alarm_wait_until_alarms(n_args, args); reload_requested = true; supervisor_set_run_reason(RUN_REASON_STARTUP); @@ -175,9 +175,6 @@ STATIC mp_obj_t alarm_exit_and_deep_sleep_until_alarms(size_t n_args, const mp_o } MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(alarm_exit_and_deep_sleep_until_alarms_obj, 1, MP_OBJ_FUN_ARGS_MAX, alarm_exit_and_deep_sleep_until_alarms); -//| """The `alarm.pin` module contains alarm attributes and classes related to pins. -//| """ -//| STATIC const mp_map_elem_t alarm_pin_globals_table[] = { { MP_ROM_QSTR(MP_QSTR___name__), MP_ROM_QSTR(MP_QSTR_pin) }, @@ -191,9 +188,6 @@ STATIC const mp_obj_module_t alarm_pin_module = { .globals = (mp_obj_dict_t*)&alarm_pin_globals, }; -//| """The `alarm.time` module contains alarm attributes and classes related to time-keeping. -//| """ -//| STATIC const mp_map_elem_t alarm_time_globals_table[] = { { MP_ROM_QSTR(MP_QSTR___name__), MP_ROM_QSTR(MP_QSTR_time) }, @@ -213,7 +207,7 @@ STATIC mp_map_elem_t alarm_module_globals_table[] = { // wake_alarm is a mutable attribute. { MP_ROM_QSTR(MP_QSTR_wake_alarm), mp_const_none }, - { MP_ROM_QSTR(MP_QSTR_sleep_until_alarms), MP_OBJ_FROM_PTR(&alarm_sleep_until_alarms_obj) }, + { MP_ROM_QSTR(MP_QSTR_light_sleep_until_alarms), MP_OBJ_FROM_PTR(&alarm_light_sleep_until_alarms_obj) }, { MP_ROM_QSTR(MP_QSTR_exit_and_deep_sleep_until_alarms), MP_OBJ_FROM_PTR(&alarm_exit_and_deep_sleep_until_alarms_obj) }, diff --git a/shared-bindings/alarm/__init__.h b/shared-bindings/alarm/__init__.h index 26dbb2897c..380c65ea8c 100644 --- a/shared-bindings/alarm/__init__.h +++ b/shared-bindings/alarm/__init__.h @@ -32,8 +32,10 @@ #include "common-hal/alarm/__init__.h" extern mp_obj_t common_hal_alarm_wait_until_alarms(size_t n_alarms, const mp_obj_t *alarms); -extern mp_obj_t common_hal_alarm_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); extern void common_hal_alarm_exit_and_deep_sleep_until_alarms(size_t n_alarms, const mp_obj_t *alarms); +extern void common_hal_alarm_prepare_for_deep_sleep(void); +extern NORETURN void common_hal_alarm_enter_deep_sleep(void); // Used by wake-up code. extern void common_hal_alarm_set_wake_alarm(mp_obj_t alarm); diff --git a/shared-bindings/alarm/pin/PinAlarm.c b/shared-bindings/alarm/pin/PinAlarm.c index a6497d4cde..a435407acc 100644 --- a/shared-bindings/alarm/pin/PinAlarm.c +++ b/shared-bindings/alarm/pin/PinAlarm.c @@ -38,18 +38,16 @@ //| class PinAlarm: //| """Trigger an alarm when a pin changes state.""" //| -//| def __init__(self, *pins: microcontroller.Pin, value: bool, all_same_value: bool = False, edge: bool = False, pull: bool = False) -> None: +//| def __init__(self, pin: microcontroller.Pin, value: bool, edge: bool = False, pull: bool = False) -> None: //| """Create an alarm triggered by a `microcontroller.Pin` level. The alarm is not active //| until it is passed to an `alarm`-enabling function, such as `alarm.sleep_until_alarms()` or //| `alarm.exit_and_deep_sleep_until_alarms()`. //| -//| :param microcontroller.Pin \*pins: The pins to monitor. On some ports, the choice of pins +//| :param microcontroller.Pin pin: The pin to monitor. On some ports, the choice of pin //| may be limited due to hardware restrictions, particularly for deep-sleep alarms. //| :param bool value: When active, trigger when the pin value is high (``True``) or low (``False``). //| On some ports, multiple `PinAlarm` objects may need to have coordinated values //| for deep-sleep alarms. -//| :param bool all_same_value: If ``True``, all pins listed must be at ``value`` to trigger the alarm. -//| If ``False``, any one of the pins going to ``value`` will trigger the alarm. //| :param bool edge: If ``True``, trigger only when there is a transition to the specified //| value of ``value``. If ``True``, if the alarm becomes active when the pin value already //| matches ``value``, the alarm is not triggered: the pin must transition from ``not value`` @@ -65,47 +63,44 @@ 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) { alarm_pin_pin_alarm_obj_t *self = m_new_obj(alarm_pin_pin_alarm_obj_t); self->base.type = &alarm_pin_pin_alarm_type; - enum { ARG_value, ARG_all_same_value, ARG_edge, ARG_pull }; + enum { ARG_pin, ARG_value, ARG_edge, ARG_pull }; static const mp_arg_t allowed_args[] = { + { MP_QSTR_pin, MP_ARG_REQUIRED | MP_ARG_OBJ }, { MP_QSTR_value, MP_ARG_KW_ONLY | MP_ARG_REQUIRED | MP_ARG_BOOL }, - { MP_QSTR_all_same_value, MP_ARG_KW_ONLY | MP_ARG_BOOL, {.u_bool = false} }, { MP_QSTR_edge, MP_ARG_KW_ONLY | MP_ARG_BOOL, {.u_bool = false} }, { MP_QSTR_pull, MP_ARG_KW_ONLY | MP_ARG_BOOL, {.u_bool = false} }, }; mp_arg_val_t args[MP_ARRAY_SIZE(allowed_args)]; mp_arg_parse_all(0, pos_args, kw_args, MP_ARRAY_SIZE(allowed_args), allowed_args, args); - for (size_t i = 0; i < n_args; i ++) { - validate_obj_is_free_pin(pos_args[i]); - } + mcu_pin_obj_t *pin = validate_obj_is_free_pin(args[ARG_pin].u_obj); - common_hal_alarm_pin_pin_alarm_construct( - self, pos_args, n_args, + common_hal_alarm_pin_pin_alarm_construct(self, + pin, args[ARG_value].u_bool, - args[ARG_all_same_value].u_bool, args[ARG_edge].u_bool, args[ARG_pull].u_bool); return MP_OBJ_FROM_PTR(self); } -//| pins: Tuple[microcontroller.Pin] -//| """The trigger pins.""" +//| pin: microcontroller.Pin +//| """The trigger pin.""" //| -STATIC mp_obj_t alarm_pin_pin_alarm_obj_get_pins(mp_obj_t self_in) { +STATIC mp_obj_t alarm_pin_pin_alarm_obj_get_pin(mp_obj_t self_in) { alarm_pin_pin_alarm_obj_t *self = MP_OBJ_TO_PTR(self_in); - return common_hal_alarm_pin_pin_alarm_get_pins(self); + return common_hal_alarm_pin_pin_alarm_get_pin(self); } -MP_DEFINE_CONST_FUN_OBJ_1(alarm_pin_pin_alarm_get_pins_obj, alarm_pin_pin_alarm_obj_get_pins); +MP_DEFINE_CONST_FUN_OBJ_1(alarm_pin_pin_alarm_get_pin_obj, alarm_pin_pin_alarm_obj_get_pin); -const mp_obj_property_t alarm_pin_pin_alarm_pins_obj = { +const mp_obj_property_t alarm_pin_pin_alarm_pin_obj = { .base.type = &mp_type_property, - .proxy = {(mp_obj_t)&alarm_pin_pin_alarm_get_pins_obj, + .proxy = {(mp_obj_t)&alarm_pin_pin_alarm_get_pin_obj, (mp_obj_t)&mp_const_none_obj, (mp_obj_t)&mp_const_none_obj}, }; -//| value: Tuple[microcontroller.Pin] +//| value: bool //| """The value on which to trigger.""" //| STATIC mp_obj_t alarm_pin_pin_alarm_obj_get_value(mp_obj_t self_in) { @@ -122,7 +117,7 @@ const mp_obj_property_t alarm_pin_pin_alarm_value_obj = { }; STATIC const mp_rom_map_elem_t alarm_pin_pin_alarm_locals_dict_table[] = { - { MP_ROM_QSTR(MP_QSTR_pins), MP_ROM_PTR(&alarm_pin_pin_alarm_pins_obj) }, + { MP_ROM_QSTR(MP_QSTR_pin), MP_ROM_PTR(&alarm_pin_pin_alarm_pin_obj) }, { MP_ROM_QSTR(MP_QSTR_value), MP_ROM_PTR(&alarm_pin_pin_alarm_value_obj) }, }; diff --git a/shared-bindings/alarm/pin/PinAlarm.h b/shared-bindings/alarm/pin/PinAlarm.h index cb69468124..49ba710899 100644 --- a/shared-bindings/alarm/pin/PinAlarm.h +++ b/shared-bindings/alarm/pin/PinAlarm.h @@ -34,8 +34,8 @@ extern const mp_obj_type_t alarm_pin_pin_alarm_type; -void common_hal_alarm_pin_pin_alarm_construct(alarm_pin_pin_alarm_obj_t *self, const mp_obj_t pins[], size_t num_pins, bool value, bool all_same_value, bool edge, bool pull); -extern mp_obj_tuple_t *common_hal_alarm_pin_pin_alarm_get_pins(alarm_pin_pin_alarm_obj_t *self); +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); +extern mcu_pin_obj_t *common_hal_alarm_pin_pin_alarm_get_pin(alarm_pin_pin_alarm_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_pin_alarm_get_edge(alarm_pin_pin_alarm_obj_t *self); extern bool common_hal_alarm_pin_pin_alarm_get_pull(alarm_pin_pin_alarm_obj_t *self); From 72fa7d88b881d2ed9978c0bd65ce5f8d6eb51703 Mon Sep 17 00:00:00 2001 From: Dan Halbert Date: Tue, 1 Dec 2020 20:13:46 -0500 Subject: [PATCH 34/34] fix doc errors --- shared-bindings/alarm/pin/PinAlarm.c | 2 +- shared-bindings/alarm/time/TimeAlarm.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/shared-bindings/alarm/pin/PinAlarm.c b/shared-bindings/alarm/pin/PinAlarm.c index a435407acc..7a5617142b 100644 --- a/shared-bindings/alarm/pin/PinAlarm.c +++ b/shared-bindings/alarm/pin/PinAlarm.c @@ -40,7 +40,7 @@ //| //| def __init__(self, pin: microcontroller.Pin, value: bool, edge: bool = False, pull: bool = False) -> None: //| """Create an alarm triggered by a `microcontroller.Pin` level. The alarm is not active -//| until it is passed to an `alarm`-enabling function, such as `alarm.sleep_until_alarms()` or +//| until it is passed to an `alarm`-enabling function, such as `alarm.light_sleep_until_alarms()` or //| `alarm.exit_and_deep_sleep_until_alarms()`. //| //| :param microcontroller.Pin pin: The pin to monitor. On some ports, the choice of pin diff --git a/shared-bindings/alarm/time/TimeAlarm.c b/shared-bindings/alarm/time/TimeAlarm.c index 17a4faac25..1c4d976ada 100644 --- a/shared-bindings/alarm/time/TimeAlarm.c +++ b/shared-bindings/alarm/time/TimeAlarm.c @@ -48,7 +48,7 @@ mp_obj_t MP_WEAK rtc_get_time_source_time(void) { //| ``monotonic_time``, or when `time.time()` would equal ``epoch_time``. //| Only one of the two arguments can be given. //| The alarm is not active until it is passed to an -//| `alarm`-enabling function, such as `alarm.sleep_until_alarms()` or +//| `alarm`-enabling function, such as `alarm.light_sleep_until_alarms()` or //| `alarm.exit_and_deep_sleep_until_alarms()`. //| //| If the given time is in the past when sleep occurs, the alarm will be triggered