diff --git a/docs/library/machine.rst b/docs/library/machine.rst index 76d111f11ef3d..1e7ad7b6b9e7a 100644 --- a/docs/library/machine.rst +++ b/docs/library/machine.rst @@ -171,6 +171,13 @@ Power related functions Availability: ESP32, WiPy. +.. function:: wake_pins() + + Returns the GPIO pin numbers of those pins which caused wakeup from deep sleep as a + tuple of integers. + + Availability: ESP32. + Miscellaneous functions ----------------------- diff --git a/ports/esp32/modmachine.c b/ports/esp32/modmachine.c index 0d7ea44c66960..2dfc8793ffa2e 100644 --- a/ports/esp32/modmachine.c +++ b/ports/esp32/modmachine.c @@ -79,6 +79,7 @@ { 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_pins), MP_ROM_PTR(&machine_wake_pins_obj) }, \ typedef enum { MP_PWRON_RESET = 1, @@ -254,6 +255,40 @@ 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); +static mp_obj_t machine_wake_pins(void) { + uint64_t status = 0; + int len, index; + mp_obj_t *tuple = NULL; + + // There will be only one wake-up source, so it is OK to logically OR all the + // wake-up source statuses. + #if SOC_GPIO_SUPPORT_DEEPSLEEP_WAKEUP && SOC_DEEP_SLEEP_SUPPORTED + status |= esp_sleep_get_gpio_wakeup_status(); + #endif + + #if SOC_PM_SUPPORT_EXT1_WAKEUP && SOC_RTCIO_PIN_COUNT > 0 + status |= esp_sleep_get_ext1_wakeup_status(); + #endif + + // Only a few (~8) pins might cause 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_pins_obj, machine_wake_pins); + MP_NORETURN static void mp_machine_reset(void) { esp_restart(); }