diff --git a/ports/esp32/machine_rtc.c b/ports/esp32/machine_rtc.c index 72d7b5c8280aa..41016cca78580 100644 --- a/ports/esp32/machine_rtc.c +++ b/ports/esp32/machine_rtc.c @@ -73,7 +73,8 @@ STATIC const machine_rtc_obj_t machine_rtc_obj = {{&machine_rtc_type}}; machine_rtc_config_t machine_rtc_config = { .ext1_pins = 0, - .ext0_pin = -1 + .ext0_pin = -1, + .wake_pins = 0 }; STATIC mp_obj_t machine_rtc_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *args) { diff --git a/ports/esp32/machine_rtc.h b/ports/esp32/machine_rtc.h index ce2a5482a2241..92902adbe7d55 100644 --- a/ports/esp32/machine_rtc.h +++ b/ports/esp32/machine_rtc.h @@ -38,6 +38,8 @@ typedef struct { bool ext0_level : 1; wake_type_t ext0_wake_types; bool ext1_level : 1; + uint64_t wake_pins; + uint64_t wake_level : 1; } machine_rtc_config_t; extern machine_rtc_config_t machine_rtc_config; diff --git a/ports/esp32/modesp32.c b/ports/esp32/modesp32.c index 017db36e22adf..82efc64fb53b0 100644 --- a/ports/esp32/modesp32.c +++ b/ports/esp32/modesp32.c @@ -63,6 +63,46 @@ STATIC mp_obj_t esp32_wake_on_touch(const mp_obj_t wake) { } STATIC MP_DEFINE_CONST_FUN_OBJ_1(esp32_wake_on_touch_obj, esp32_wake_on_touch); +#if CONFIG_IDF_TARGET_ESP32C3 + +STATIC mp_obj_t esp32_wake_on_pins(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) { + enum {ARG_pins, ARG_level}; + const mp_arg_t allowed_args[] = { + { MP_QSTR_pins, MP_ARG_OBJ, {.u_obj = mp_const_none} }, + { MP_QSTR_level, MP_ARG_BOOL, {.u_bool = machine_rtc_config.wake_level} }, + }; + 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); + uint64_t wake_pins = machine_rtc_config.wake_pins; + + + // Check that all pins are allowed + if (args[ARG_pins].u_obj != mp_const_none) { + size_t len = 0; + mp_obj_t *elem; + mp_obj_get_array(args[ARG_pins].u_obj, &len, &elem); + wake_pins = 0; + + for (int i = 0; i < len; i++) { + + gpio_num_t pin_id = machine_pin_get_id(elem[i]); + if (!RTC_IS_VALID_EXT_PIN(pin_id)) { + mp_raise_ValueError(MP_ERROR_TEXT("invalid pin")); + break; + } + wake_pins |= (1ll << pin_id); + } + } + + machine_rtc_config.wake_level = args[ARG_level].u_bool; + machine_rtc_config.wake_pins = wake_pins; + + return mp_const_none; +} +STATIC MP_DEFINE_CONST_FUN_OBJ_KW(esp32_wake_on_pins_obj, 0, esp32_wake_on_pins); + +#else + STATIC mp_obj_t esp32_wake_on_ext0(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) { if (machine_rtc_config.wake_on_touch) { @@ -140,6 +180,8 @@ STATIC mp_obj_t esp32_wake_on_ulp(const mp_obj_t wake) { } STATIC MP_DEFINE_CONST_FUN_OBJ_1(esp32_wake_on_ulp_obj, esp32_wake_on_ulp); +#endif + STATIC mp_obj_t esp32_gpio_deep_sleep_hold(const mp_obj_t enable) { if (mp_obj_is_true(enable)) { gpio_deep_sleep_hold_en(); @@ -204,9 +246,13 @@ STATIC const mp_rom_map_elem_t esp32_module_globals_table[] = { { MP_ROM_QSTR(MP_QSTR___name__), MP_ROM_QSTR(MP_QSTR_esp32) }, { MP_ROM_QSTR(MP_QSTR_wake_on_touch), MP_ROM_PTR(&esp32_wake_on_touch_obj) }, + #if CONFIG_IDF_TARGET_ESP32C3 + { MP_ROM_QSTR(MP_QSTR_wake_on_pins), MP_ROM_PTR(&esp32_wake_on_pins_obj) }, + #else { MP_ROM_QSTR(MP_QSTR_wake_on_ext0), MP_ROM_PTR(&esp32_wake_on_ext0_obj) }, { MP_ROM_QSTR(MP_QSTR_wake_on_ext1), MP_ROM_PTR(&esp32_wake_on_ext1_obj) }, { MP_ROM_QSTR(MP_QSTR_wake_on_ulp), MP_ROM_PTR(&esp32_wake_on_ulp_obj) }, + #endif { MP_ROM_QSTR(MP_QSTR_gpio_deep_sleep_hold), MP_ROM_PTR(&esp32_gpio_deep_sleep_hold_obj) }, #if CONFIG_IDF_TARGET_ESP32 { MP_ROM_QSTR(MP_QSTR_raw_temperature), MP_ROM_PTR(&esp32_raw_temperature_obj) }, diff --git a/ports/esp32/modesp32.h b/ports/esp32/modesp32.h index a685b7b38fe6f..2d5d70691cb5e 100644 --- a/ports/esp32/modesp32.h +++ b/ports/esp32/modesp32.h @@ -30,6 +30,32 @@ ) #define RTC_LAST_EXT_PIN 21 +#elif CONFIG_IDF_TARGET_ESP32C3 + + #define RTC_VALID_EXT_PINS \ + ( \ + (1ll << 2) | \ + (1ll << 3) | \ + (1ll << 4) | \ + (1ll << 5) | \ + (1ll << 6) | \ + (1ll << 7) | \ + (1ll << 8) | \ + (1ll << 9) | \ + (1ll << 10) | \ + (1ll << 11) | \ + (1ll << 12) | \ + (1ll << 13) | \ + (1ll << 14) | \ + (1ll << 15) | \ + (1ll << 16) | \ + (1ll << 17) | \ + (1ll << 18) | \ + (1ll << 19) | \ + (1ll << 21) \ + ) + #define RTC_LAST_EXT_PIN 21 + #else #define RTC_VALID_EXT_PINS \ diff --git a/ports/esp32/modmachine.c b/ports/esp32/modmachine.c index a70f2fbedb59c..a11088493b952 100644 --- a/ports/esp32/modmachine.c +++ b/ports/esp32/modmachine.c @@ -160,6 +160,18 @@ STATIC mp_obj_t machine_sleep_helper(wake_type_t wake_type, size_t n_args, const #endif + #if CONFIG_IDF_TARGET_ESP32C3 + + if (machine_rtc_config.wake_pins != 0) { + if (esp_deep_sleep_enable_gpio_wakeup( + machine_rtc_config.wake_pins, + machine_rtc_config.wake_level ? ESP_GPIO_WAKEUP_GPIO_HIGH : ESP_GPIO_WAKEUP_GPIO_LOW) != ESP_OK) { + mp_raise_msg(&mp_type_RuntimeError, MP_ERROR_TEXT("esp_sleep_enable_gpio_wakeup() failed")); + } + } + + #endif + switch (wake_type) { case MACHINE_WAKE_SLEEP: esp_light_sleep_start();