diff --git a/docs/library/machine.rst b/docs/library/machine.rst index 532266d1d9102..ad732b174c434 100644 --- a/docs/library/machine.rst +++ b/docs/library/machine.rst @@ -166,6 +166,24 @@ Power related functions Availability: ESP32, WiPy. +.. function:: wake_ext1_pins() + + Returns the GPIO pin numbers of those pins which caused wakeup from deep sleep as a + tuple of integers. + + This is a direct interface to the ESP-IDF ``esp_sleep_get_ext1_wakeup_status()`` function. + + Availability: ESP32 (except ESP32C3). + +.. function:: wake_gpio_pins() + + Returns the GPIO pin numbers of those pins which caused wakeup from deep sleep as a + tuple of integers. + + This is a direct interface to the ESP-IDF ``esp_sleep_get_gpio_wakeup_status()`` function. + + Availability: ESP32C3 only. + Miscellaneous functions ----------------------- diff --git a/ports/esp32/modesp32.c b/ports/esp32/modesp32.c index 1ee9153d7d620..c4b2bf9ae24f9 100644 --- a/ports/esp32/modesp32.c +++ b/ports/esp32/modesp32.c @@ -63,6 +63,12 @@ static MP_DEFINE_CONST_FUN_OBJ_1(esp32_wake_on_touch_obj, esp32_wake_on_touch); static mp_obj_t esp32_wake_on_ext0(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) { + #if CONFIG_IDF_TARGET_ESP32C3 + + mp_raise_ValueError(MP_ERROR_TEXT("not supported")); + + #else + if (machine_rtc_config.wake_on_touch) { mp_raise_ValueError(MP_ERROR_TEXT("no resources")); } @@ -89,6 +95,8 @@ static mp_obj_t esp32_wake_on_ext0(size_t n_args, const mp_obj_t *pos_args, mp_m machine_rtc_config.ext0_level = args[ARG_level].u_bool; machine_rtc_config.ext0_wake_types = MACHINE_WAKE_SLEEP | MACHINE_WAKE_DEEPSLEEP; + #endif + return mp_const_none; } static MP_DEFINE_CONST_FUN_OBJ_KW(esp32_wake_on_ext0_obj, 0, esp32_wake_on_ext0); diff --git a/ports/esp32/modesp32.h b/ports/esp32/modesp32.h index a685b7b38fe6f..7064f3eadbb67 100644 --- a/ports/esp32/modesp32.h +++ b/ports/esp32/modesp32.h @@ -1,7 +1,7 @@ #ifndef MICROPY_INCLUDED_ESP32_MODESP32_H #define MICROPY_INCLUDED_ESP32_MODESP32_H -#if CONFIG_IDF_TARGET_ESP32S2 || CONFIG_IDF_TARGET_ESP32S3 +#if CONFIG_IDF_TARGET_ESP32S2 || CONFIG_IDF_TARGET_ESP32S3 || CONFIG_IDF_TARGET_ESP32C3 #define RTC_VALID_EXT_PINS \ ( \ diff --git a/ports/esp32/modmachine.c b/ports/esp32/modmachine.c index 759455a59a5d6..6718f5493df66 100644 --- a/ports/esp32/modmachine.c +++ b/ports/esp32/modmachine.c @@ -51,6 +51,39 @@ #define MICROPY_PY_MACHINE_TOUCH_PAD_ENTRY #endif +#if CONFIG_IDF_TARGET_ESP32C3 +#define MICROPY_PY_MACHINE_EXTRA_GLOBALS \ + { MP_ROM_QSTR(MP_QSTR_sleep), MP_ROM_PTR(&machine_lightsleep_obj) }, \ + \ + { MP_ROM_QSTR(MP_QSTR_Timer), MP_ROM_PTR(&machine_timer_type) }, \ + MICROPY_PY_MACHINE_SDCARD_ENTRY \ + { MP_ROM_QSTR(MP_QSTR_Pin), MP_ROM_PTR(&machine_pin_type) }, \ + MICROPY_PY_MACHINE_TOUCH_PAD_ENTRY \ + { MP_ROM_QSTR(MP_QSTR_RTC), MP_ROM_PTR(&machine_rtc_type) }, \ + \ + /* wake abilities */ \ + { MP_ROM_QSTR(MP_QSTR_SLEEP), MP_ROM_INT(MACHINE_WAKE_SLEEP) }, \ + { MP_ROM_QSTR(MP_QSTR_DEEPSLEEP), MP_ROM_INT(MACHINE_WAKE_DEEPSLEEP) }, \ + \ + /* Reset reasons */ \ + { MP_ROM_QSTR(MP_QSTR_HARD_RESET), MP_ROM_INT(MP_HARD_RESET) }, \ + { MP_ROM_QSTR(MP_QSTR_PWRON_RESET), MP_ROM_INT(MP_PWRON_RESET) }, \ + { MP_ROM_QSTR(MP_QSTR_WDT_RESET), MP_ROM_INT(MP_WDT_RESET) }, \ + { MP_ROM_QSTR(MP_QSTR_DEEPSLEEP_RESET), MP_ROM_INT(MP_DEEPSLEEP_RESET) }, \ + { MP_ROM_QSTR(MP_QSTR_SOFT_RESET), MP_ROM_INT(MP_SOFT_RESET) }, \ + \ + /* Wake reasons */ \ + { MP_ROM_QSTR(MP_QSTR_wake_reason), MP_ROM_PTR(&machine_wake_reason_obj) }, \ + { MP_ROM_QSTR(MP_QSTR_PIN_WAKE), MP_ROM_INT(ESP_SLEEP_WAKEUP_EXT0) }, \ + { MP_ROM_QSTR(MP_QSTR_EXT0_WAKE), MP_ROM_INT(ESP_SLEEP_WAKEUP_EXT0) }, \ + { MP_ROM_QSTR(MP_QSTR_EXT1_WAKE), MP_ROM_INT(ESP_SLEEP_WAKEUP_EXT1) }, \ + { MP_ROM_QSTR(MP_QSTR_GPIO_WAKE), MP_ROM_INT(ESP_SLEEP_WAKEUP_GPIO) }, \ + { MP_ROM_QSTR(MP_QSTR_TIMER_WAKE), MP_ROM_INT(ESP_SLEEP_WAKEUP_TIMER) }, \ + { MP_ROM_QSTR(MP_QSTR_TOUCHPAD_WAKE), MP_ROM_INT(ESP_SLEEP_WAKEUP_TOUCHPAD) }, \ + { MP_ROM_QSTR(MP_QSTR_ULP_WAKE), MP_ROM_INT(ESP_SLEEP_WAKEUP_ULP) }, \ + { MP_ROM_QSTR(MP_QSTR_wake_gpio_pins), MP_ROM_PTR(&machine_wake_gpio_pins_obj) }, \ + +#else #define MICROPY_PY_MACHINE_EXTRA_GLOBALS \ { MP_ROM_QSTR(MP_QSTR_sleep), MP_ROM_PTR(&machine_lightsleep_obj) }, \ \ @@ -76,9 +109,13 @@ { MP_ROM_QSTR(MP_QSTR_PIN_WAKE), MP_ROM_INT(ESP_SLEEP_WAKEUP_EXT0) }, \ { MP_ROM_QSTR(MP_QSTR_EXT0_WAKE), MP_ROM_INT(ESP_SLEEP_WAKEUP_EXT0) }, \ { MP_ROM_QSTR(MP_QSTR_EXT1_WAKE), MP_ROM_INT(ESP_SLEEP_WAKEUP_EXT1) }, \ + { MP_ROM_QSTR(MP_QSTR_GPIO_WAKE), MP_ROM_INT(ESP_SLEEP_WAKEUP_GPIO) }, \ { MP_ROM_QSTR(MP_QSTR_TIMER_WAKE), MP_ROM_INT(ESP_SLEEP_WAKEUP_TIMER) }, \ { MP_ROM_QSTR(MP_QSTR_TOUCHPAD_WAKE), MP_ROM_INT(ESP_SLEEP_WAKEUP_TOUCHPAD) }, \ { MP_ROM_QSTR(MP_QSTR_ULP_WAKE), MP_ROM_INT(ESP_SLEEP_WAKEUP_ULP) }, \ + { MP_ROM_QSTR(MP_QSTR_wake_ext1_pins), MP_ROM_PTR(&machine_wake_ext1_pins_obj) }, \ + +#endif typedef enum { MP_PWRON_RESET = 1, @@ -146,7 +183,36 @@ static void machine_sleep_helper(wake_type_t wake_type, size_t n_args, const mp_ esp_sleep_enable_timer_wakeup(((uint64_t)expiry) * 1000); } - #if !CONFIG_IDF_TARGET_ESP32C3 + #if CONFIG_IDF_TARGET_ESP32C3 + + if (machine_rtc_config.ext1_pins != 0) { + gpio_int_type_t intr_type = machine_rtc_config.ext1_level ? GPIO_INTR_HIGH_LEVEL : GPIO_INTR_LOW_LEVEL; + + for (int i = 0; i < GPIO_NUM_MAX; ++i) { + gpio_num_t gpio = (gpio_num_t)i; + uint64_t bm = 1ULL << i; + + if (machine_rtc_config.ext1_pins & bm) { + gpio_sleep_set_direction(gpio, GPIO_MODE_INPUT); + + if (MACHINE_WAKE_SLEEP == wake_type) { + gpio_wakeup_enable(gpio, intr_type); + } + } + } + + if (MACHINE_WAKE_DEEPSLEEP == wake_type) { + if (ESP_OK != esp_deep_sleep_enable_gpio_wakeup( + machine_rtc_config.ext1_pins, + machine_rtc_config.ext1_level ? ESP_GPIO_WAKEUP_GPIO_HIGH : ESP_GPIO_WAKEUP_GPIO_LOW)) { + mp_raise_ValueError(MP_ERROR_TEXT("wake-up pin not supported")); + } + } else { + esp_sleep_enable_gpio_wakeup(); + } + } + + #else if (machine_rtc_config.ext0_pin != -1 && (machine_rtc_config.ext0_wake_types & wake_type)) { esp_sleep_enable_ext0_wakeup(machine_rtc_config.ext0_pin, machine_rtc_config.ext0_level ? 1 : 0); @@ -250,6 +316,58 @@ static mp_obj_t machine_wake_reason(size_t n_args, const mp_obj_t *pos_args, mp_ } static MP_DEFINE_CONST_FUN_OBJ_KW(machine_wake_reason_obj, 0, machine_wake_reason); +#if CONFIG_IDF_TARGET_ESP32C3 +static mp_obj_t machine_wake_gpio_pins(void) { + uint64_t status = esp_sleep_get_gpio_wakeup_status(); + int len, index; + mp_obj_t *tuple = NULL; + + // Only a few (~8) GPIOs might cause EXT1 wakeup. + // Therefore, we don't allocate 64*4 = 256 bytes on the stack and calculate the + // required space in a first pass. + for (index = 0, len = 0; index < 64; index++) { + len += (status & ((uint64_t)1 << index)) ? 1 : 0; + } + if (len) { + tuple = alloca(len * sizeof(*tuple)); + + for (index = 0, len = 0; index < 64; index++) { + if (status & ((uint64_t)1 << index)) { + tuple[len++] = MP_OBJ_NEW_SMALL_INT(index); + } + } + } + return mp_obj_new_tuple(len, tuple); +} + +static MP_DEFINE_CONST_FUN_OBJ_0(machine_wake_gpio_pins_obj, machine_wake_gpio_pins); +#else +static mp_obj_t machine_wake_ext1_pins(void) { + uint64_t status = esp_sleep_get_ext1_wakeup_status(); + int len, index; + mp_obj_t *tuple = NULL; + + // Only a few (~8) GPIOs might cause EXT1 wakeup. + // Therefore, we don't allocate 64*4 = 256 bytes on the stack and calculate the + // required space in a first pass. + for (index = 0, len = 0; index < 64; index++) { + len += (status & ((uint64_t)1 << index)) ? 1 : 0; + } + if (len) { + tuple = alloca(len * sizeof(*tuple)); + + for (index = 0, len = 0; index < 64; index++) { + if (status & ((uint64_t)1 << index)) { + tuple[len++] = MP_OBJ_NEW_SMALL_INT(index); + } + } + } + return mp_obj_new_tuple(len, tuple); +} + +static MP_DEFINE_CONST_FUN_OBJ_0(machine_wake_ext1_pins_obj, machine_wake_ext1_pins); +#endif + NORETURN static void mp_machine_reset(void) { esp_restart(); }
Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.
Alternative Proxies: