From dcacd8cdf803b4ba27221f91a51d70babee98037 Mon Sep 17 00:00:00 2001 From: Lou Tianhao Date: Mon, 3 Jul 2023 20:36:39 +0800 Subject: [PATCH 1/7] feat(pm/deepsleep): Support deep_sleep example and deep_sleep_wake_stub example for esp32h2 --- components/esp_hw_support/CMakeLists.txt | 6 -- .../esp_hw_support/port/esp32h2/pmu_sleep.c | 3 + components/esp_hw_support/sleep_modes.c | 10 +- components/esp_rom/include/esp32h2/rom/rtc.h | 2 + .../esp_system/ld/esp32h2/sections.ld.in | 2 + .../hal/esp32h2/include/hal/lp_aon_hal.h | 24 +++++ .../hal/esp32h2/include/hal/lp_aon_ll.h | 97 +++++++++++++++++++ .../esp32h2/include/soc/Kconfig.soc_caps.in | 4 + components/soc/esp32h2/include/soc/soc_caps.h | 1 + 9 files changed, 135 insertions(+), 14 deletions(-) create mode 100644 components/hal/esp32h2/include/hal/lp_aon_hal.h create mode 100644 components/hal/esp32h2/include/hal/lp_aon_ll.h diff --git a/components/esp_hw_support/CMakeLists.txt b/components/esp_hw_support/CMakeLists.txt index 80b5c5ec0d..f07906a1ae 100644 --- a/components/esp_hw_support/CMakeLists.txt +++ b/components/esp_hw_support/CMakeLists.txt @@ -122,12 +122,6 @@ if(NOT BOOTLOADER_BUILD) if(CONFIG_SOC_RTC_FAST_MEM_SUPPORTED) list(APPEND srcs "sleep_wake_stub.c") endif() - - if(CONFIG_IDF_TARGET_ESP32H2) - list(REMOVE_ITEM srcs - "sleep_wake_stub.c" # TODO: IDF-6268 - ) - endif() else() # Requires "_esp_error_check_failed()" function list(APPEND priv_requires "esp_system") diff --git a/components/esp_hw_support/port/esp32h2/pmu_sleep.c b/components/esp_hw_support/port/esp32h2/pmu_sleep.c index 30ef282da7..ffe456fa60 100644 --- a/components/esp_hw_support/port/esp32h2/pmu_sleep.c +++ b/components/esp_hw_support/port/esp32h2/pmu_sleep.c @@ -14,6 +14,7 @@ #include "soc/soc.h" #include "soc/rtc.h" #include "soc/pmu_struct.h" +#include "hal/lp_aon_hal.h" #include "esp_private/esp_pmu.h" #define HP(state) (PMU_MODE_HP_ ## state) @@ -218,6 +219,8 @@ uint32_t pmu_sleep_start(uint32_t wakeup_opt, uint32_t reject_opt, uint32_t lslp { assert(PMU_instance()->hal); + lp_aon_hal_inform_wakeup_type(dslp); + pmu_ll_hp_set_wakeup_enable(PMU_instance()->hal->dev, wakeup_opt); pmu_ll_hp_set_reject_enable(PMU_instance()->hal->dev, reject_opt); diff --git a/components/esp_hw_support/sleep_modes.c b/components/esp_hw_support/sleep_modes.c index a513570e2a..2fdb536f73 100644 --- a/components/esp_hw_support/sleep_modes.c +++ b/components/esp_hw_support/sleep_modes.c @@ -260,7 +260,6 @@ static void touch_wakeup_prepare(void); static void gpio_deep_sleep_wakeup_prepare(void); #endif -#if !CONFIG_IDF_TARGET_ESP32H2 #if SOC_RTC_FAST_MEM_SUPPORTED #if SOC_PM_SUPPORT_DEEPSLEEP_CHECK_STUB_ONLY static RTC_FAST_ATTR esp_deep_sleep_wake_stub_fn_t wake_stub_fn_handler = NULL; @@ -366,7 +365,6 @@ void RTC_IRAM_ATTR esp_default_wake_deep_sleep(void) void __attribute__((weak, alias("esp_default_wake_deep_sleep"))) esp_wake_deep_sleep(void); #endif // SOC_RTC_FAST_MEM_SUPPORTED -#endif // !CONFIG_IDF_TARGET_ESP32H2 void esp_deep_sleep(uint64_t time_in_us) { @@ -641,7 +639,6 @@ static esp_err_t IRAM_ATTR esp_sleep_start(uint32_t pd_flags, esp_sleep_mode_t m #endif } #endif - misc_modules_sleep_prepare(deep_sleep); #if CONFIG_IDF_TARGET_ESP32S2 || CONFIG_IDF_TARGET_ESP32S3 @@ -681,7 +678,6 @@ static esp_err_t IRAM_ATTR esp_sleep_start(uint32_t pd_flags, esp_sleep_mode_t m if (periph_using_8m) { sleep_flags |= RTC_SLEEP_DIG_USE_8M; } - // Enter sleep esp_err_t result; #if SOC_PMU_SUPPORTED @@ -721,7 +717,6 @@ static esp_err_t IRAM_ATTR esp_sleep_start(uint32_t pd_flags, esp_sleep_mode_t m esp_sleep_isolate_digital_gpio(); #endif -#if !CONFIG_IDF_TARGET_ESP32H2 // TODO: IDF-6268 #if SOC_PM_SUPPORT_DEEPSLEEP_CHECK_STUB_ONLY esp_set_deep_sleep_wake_stub_default_entry(); // Enter Deep Sleep @@ -742,9 +737,6 @@ static esp_err_t IRAM_ATTR esp_sleep_start(uint32_t pd_flags, esp_sleep_mode_t m result = rtc_deep_sleep_start(s_config.wakeup_triggers, reject_triggers); #endif #endif // SOC_PM_SUPPORT_DEEPSLEEP_CHECK_STUB_ONLY -#else // !CONFIG_IDF_TARGET_ESP32H2 - result = ESP_OK; -#endif // !CONFIG_IDF_TARGET_ESP32H2 } else { /* On esp32c6, only the lp_aon pad hold function can only hold the GPIO state in the active mode. In order to avoid the leakage of the SPI cs pin, hold it here */ @@ -858,6 +850,8 @@ void IRAM_ATTR esp_deep_sleep_start(void) if (esp_get_deep_sleep_wake_stub() == NULL) { esp_set_deep_sleep_wake_stub(esp_wake_deep_sleep); } + // assert(0); + #endif // SOC_RTC_FAST_MEM_SUPPORTED // Decide which power domains can be powered down diff --git a/components/esp_rom/include/esp32h2/rom/rtc.h b/components/esp_rom/include/esp32h2/rom/rtc.h index 7f516d704b..69e625dc50 100644 --- a/components/esp_rom/include/esp32h2/rom/rtc.h +++ b/components/esp_rom/include/esp32h2/rom/rtc.h @@ -51,6 +51,7 @@ extern "C" { * LP_AON_STORE6_REG FAST_RTC_MEMORY_ENTRY * LP_AON_STORE7_REG FAST_RTC_MEMORY_CRC * LP_AON_STORE8_REG Store light sleep wake stub addr + * LP_AON_STORE9_REG Store the sleep mode at bit[0] (0:light sleep 1:deep sleep) ************************************************************************************* */ @@ -63,6 +64,7 @@ extern "C" { #define RTC_RESET_CAUSE_REG LP_AON_STORE6_REG #define RTC_MEMORY_CRC_REG LP_AON_STORE7_REG #define LIGHT_SLEEP_WAKE_STUB_ADDR_REG LP_AON_STORE8_REG +#define SLEEP_MODE_REG LP_AON_STORE9_REG #define RTC_DISABLE_ROM_LOG ((1 << 0) | (1 << 16)) //!< Disable logging from the ROM code. diff --git a/components/esp_system/ld/esp32h2/sections.ld.in b/components/esp_system/ld/esp32h2/sections.ld.in index c8e45343f3..8f84717185 100644 --- a/components/esp_system/ld/esp32h2/sections.ld.in +++ b/components/esp_system/ld/esp32h2/sections.ld.in @@ -17,6 +17,8 @@ SECTIONS { . = ALIGN(4); _rtc_fast_start = ABSOLUTE(.); + _rtc_text_start = ABSOLUTE(.); + *(.rtc.entry.text) mapping[rtc_text] diff --git a/components/hal/esp32h2/include/hal/lp_aon_hal.h b/components/hal/esp32h2/include/hal/lp_aon_hal.h new file mode 100644 index 0000000000..c619dc0a6d --- /dev/null +++ b/components/hal/esp32h2/include/hal/lp_aon_hal.h @@ -0,0 +1,24 @@ +/* + * SPDX-FileCopyrightText: 2020-2023 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#pragma once + +#include "hal/lp_aon_ll.h" + +#define rtc_hal_ext1_get_wakeup_status() lp_aon_hal_ext1_get_wakeup_status() +#define rtc_hal_ext1_clear_wakeup_status() lp_aon_hal_ext1_clear_wakeup_status() +#define rtc_hal_ext1_set_wakeup_pins(mask, mode) lp_aon_hal_ext1_set_wakeup_pins(mask, mode) +#define rtc_hal_ext1_clear_wakeup_pins() lp_aon_hal_ext1_clear_wakeup_pins() +#define rtc_hal_ext1_get_wakeup_pins() lp_aon_hal_ext1_get_wakeup_pins() + + +#define lp_aon_hal_ext1_get_wakeup_status() lp_aon_ll_ext1_get_wakeup_status() +#define lp_aon_hal_ext1_clear_wakeup_status() lp_aon_ll_ext1_clear_wakeup_status() +#define lp_aon_hal_ext1_set_wakeup_pins(mask, mode) lp_aon_ll_ext1_set_wakeup_pins(mask, mode) +#define lp_aon_hal_ext1_clear_wakeup_pins() lp_aon_ll_ext1_clear_wakeup_pins() +#define lp_aon_hal_ext1_get_wakeup_pins() lp_aon_ll_ext1_get_wakeup_pins() + +#define lp_aon_hal_inform_wakeup_type(dslp) lp_aon_ll_inform_wakeup_type(dslp) diff --git a/components/hal/esp32h2/include/hal/lp_aon_ll.h b/components/hal/esp32h2/include/hal/lp_aon_ll.h new file mode 100644 index 0000000000..c214c6f638 --- /dev/null +++ b/components/hal/esp32h2/include/hal/lp_aon_ll.h @@ -0,0 +1,97 @@ +/* + * SPDX-FileCopyrightText: 2023 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +// The LL layer for ESP32-C6 LP_AON register operations + +#pragma once + +#include +#include "soc/soc.h" +#include "soc/lp_aon_struct.h" +#include "hal/misc.h" +#include "esp32h2/rom/rtc.h" + + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * @brief Get ext1 wakeup source status + * @return The lower 8 bits of the returned value are the bitmap of + * the wakeup source status, bit 0~7 corresponds to LP_IO 0~7 + */ +static inline uint32_t lp_aon_ll_ext1_get_wakeup_status(void) +{ + return HAL_FORCE_READ_U32_REG_FIELD(LP_AON.ext_wakeup_cntl, ext_wakeup_status); +} + +/** + * @brief Clear the ext1 wakeup source status + */ +static inline void lp_aon_ll_ext1_clear_wakeup_status(void) +{ + HAL_FORCE_MODIFY_U32_REG_FIELD(LP_AON.ext_wakeup_cntl, ext_wakeup_status_clr, 1); +} + +/** + * @brief Set the wake-up LP_IO of the ext1 wake-up source + * @param mask wakeup LP_IO bitmap, bit 0~7 corresponds to LP_IO 0~7 + * @param mode 0: Wake the chip when all selected GPIOs go low + * 1: Wake the chip when any of the selected GPIOs go high + */ +static inline void lp_aon_ll_ext1_set_wakeup_pins(uint32_t mask, int mode) +{ + uint32_t wakeup_sel_mask = HAL_FORCE_READ_U32_REG_FIELD(LP_AON.ext_wakeup_cntl, ext_wakeup_sel); + wakeup_sel_mask |= mask; + HAL_FORCE_MODIFY_U32_REG_FIELD(LP_AON.ext_wakeup_cntl, ext_wakeup_sel, wakeup_sel_mask); + + uint32_t wakeup_level_mask = HAL_FORCE_READ_U32_REG_FIELD(LP_AON.ext_wakeup_cntl, ext_wakeup_lv); + if (mode) { + wakeup_level_mask |= mask; + } else { + wakeup_level_mask &= ~mask; + } + HAL_FORCE_MODIFY_U32_REG_FIELD(LP_AON.ext_wakeup_cntl, ext_wakeup_lv, wakeup_level_mask); +} + +/** + * @brief Clear all ext1 wakup-source setting + */ +static inline void lp_aon_ll_ext1_clear_wakeup_pins(void) +{ + HAL_FORCE_MODIFY_U32_REG_FIELD(LP_AON.ext_wakeup_cntl, ext_wakeup_sel, 0); +} + +/** + * @brief Get ext1 wakeup source setting + * @return The lower 8 bits of the returned value are the bitmap of + * the wakeup source status, bit 0~7 corresponds to LP_IO 0~7 + */ +static inline uint32_t lp_aon_ll_ext1_get_wakeup_pins(void) +{ + return HAL_FORCE_READ_U32_REG_FIELD(LP_AON.ext_wakeup_cntl, ext_wakeup_sel); +} + + +/** + * @brief ROM obtains the wake-up type through LP_AON_STORE9_REG[0]. + * Set the flag to inform + * @param true: deepsleep false: lightsleep + */ +static inline void lp_aon_ll_inform_wakeup_type(bool dslp) +{ + if (dslp) { + REG_SET_BIT(SLEEP_MODE_REG, BIT(0)); /* Tell rom to run deep sleep wake stub */ + + } else { + REG_CLR_BIT(SLEEP_MODE_REG, BIT(0)); /* Tell rom to run light sleep wake stub */ + } +} + +#ifdef __cplusplus +} +#endif diff --git a/components/soc/esp32h2/include/soc/Kconfig.soc_caps.in b/components/soc/esp32h2/include/soc/Kconfig.soc_caps.in index 7dee2ca2c5..ab8973df8d 100644 --- a/components/soc/esp32h2/include/soc/Kconfig.soc_caps.in +++ b/components/soc/esp32h2/include/soc/Kconfig.soc_caps.in @@ -1099,6 +1099,10 @@ config SOC_PHY_DIG_REGS_MEM_SIZE int default 21 +config SOC_PM_SUPPORT_EXT1_WAKEUP + bool + default n + config SOC_PM_SUPPORT_BT_WAKEUP bool default y diff --git a/components/soc/esp32h2/include/soc/soc_caps.h b/components/soc/esp32h2/include/soc/soc_caps.h index aa87cf7cee..618c6969f6 100644 --- a/components/soc/esp32h2/include/soc/soc_caps.h +++ b/components/soc/esp32h2/include/soc/soc_caps.h @@ -462,6 +462,7 @@ #define SOC_PHY_DIG_REGS_MEM_SIZE (21*4) /*-------------------------- Power Management CAPS ----------------------------*/ +#define SOC_PM_SUPPORT_EXT1_WAKEUP (0) #define SOC_PM_SUPPORT_BT_WAKEUP (1) // #define SOC_PM_SUPPORT_EXT1_WAKEUP (1) // TODO: IDF-6268 #define SOC_PM_SUPPORT_CPU_PD (1) From 7bd92287c41435afc3e9466976d87da84382692d Mon Sep 17 00:00:00 2001 From: Lou Tianhao Date: Mon, 3 Jul 2023 20:38:35 +0800 Subject: [PATCH 2/7] change(pm/deepsleep): Update deep_sleep pmu analog parameter for esp32h2 --- .../port/esp32h2/private_include/pmu_param.h | 21 +++++++++---------- 1 file changed, 10 insertions(+), 11 deletions(-) diff --git a/components/esp_hw_support/port/esp32h2/private_include/pmu_param.h b/components/esp_hw_support/port/esp32h2/private_include/pmu_param.h index 22ca4216e4..f52cdcf5ff 100644 --- a/components/esp_hw_support/port/esp32h2/private_include/pmu_param.h +++ b/components/esp_hw_support/port/esp32h2/private_include/pmu_param.h @@ -337,34 +337,33 @@ typedef struct { .pd_cur = 1, \ .bias_sleep = 1, \ .xpd = 0, \ - .dbias = 0x15, \ - .slp_mem_xpd = 1, \ - .slp_mem_dbias = 0xc, \ - .slp_logic_xpd = 1, \ - .slp_logic_dbias = 0x5, \ - .drv_b = 0x18c \ + .dbias = 0, \ + .slp_mem_xpd = 0, \ + .slp_mem_dbias = 0, \ + .slp_logic_xpd = 0, \ + .slp_logic_dbias = 0, \ + .drv_b = 0xFFFFFF \ } \ }, \ .lp_sys[PMU_MODE_LP_ACTIVE] = { \ .analog = { \ .xpd = 1, \ - .dbias = 0x1a, \ + .dbias = 0xe, \ .slp_xpd = 0, \ .slp_dbias = 0, \ - .drv_b = 0x7 \ + .drv_b = 0 \ } \ }, \ .lp_sys[PMU_MODE_LP_SLEEP] = { \ .analog = { \ .xpd_bias = 0, \ - .dbg_atten = 0xe, \ .pd_cur = 1, \ .bias_sleep = 1, \ .xpd = 0, \ .dbias = 0, \ .slp_xpd = 1, \ - .slp_dbias = 0xe, \ - .drv_b = 0 \ + .slp_dbias = 5, \ + .drv_b = 7 \ } \ } \ } From 99c26914671f88c76da3d754301963a2cf990966 Mon Sep 17 00:00:00 2001 From: Song Ruo Jing Date: Fri, 30 Jun 2023 16:30:03 +0800 Subject: [PATCH 3/7] change(driver/rtcio): Describe RTCIO CAPS with more accurate note --- components/soc/esp32c6/include/soc/soc_caps.h | 5 ++++- components/soc/esp32s2/include/soc/soc_caps.h | 7 +++++-- components/soc/esp32s3/include/soc/soc_caps.h | 5 ++++- 3 files changed, 13 insertions(+), 4 deletions(-) diff --git a/components/soc/esp32c6/include/soc/soc_caps.h b/components/soc/esp32c6/include/soc/soc_caps.h index ddcb0f886f..52d9b8f7da 100644 --- a/components/soc/esp32c6/include/soc/soc_caps.h +++ b/components/soc/esp32c6/include/soc/soc_caps.h @@ -203,7 +203,10 @@ /*-------------------------- RTCIO CAPS --------------------------------------*/ #define SOC_RTCIO_PIN_COUNT 8 -#define SOC_RTCIO_INPUT_OUTPUT_SUPPORTED 1 // The target has separate LP(RTC) IOMUX +#define SOC_RTCIO_INPUT_OUTPUT_SUPPORTED 1 /* This macro indicates that the target has separate RTC IOMUX hardware feature, + * so it supports unique IOMUX configuration (including IE, OE, PU, PD, DRV etc.) + * when the pins are switched to RTC function. + */ #define SOC_RTCIO_HOLD_SUPPORTED 1 #define SOC_RTCIO_WAKE_SUPPORTED 1 diff --git a/components/soc/esp32s2/include/soc/soc_caps.h b/components/soc/esp32s2/include/soc/soc_caps.h index 7ea6a91c03..669ff5773e 100644 --- a/components/soc/esp32s2/include/soc/soc_caps.h +++ b/components/soc/esp32s2/include/soc/soc_caps.h @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2020-2022 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2020-2023 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -249,7 +249,10 @@ /*-------------------------- RTCIO CAPS --------------------------------------*/ #define SOC_RTCIO_PIN_COUNT 22 -#define SOC_RTCIO_INPUT_OUTPUT_SUPPORTED 1 // The target has separate RTC IOMUX +#define SOC_RTCIO_INPUT_OUTPUT_SUPPORTED 1 /* This macro indicates that the target has separate RTC IOMUX hardware feature, + * so it supports unique IOMUX configuration (including IE, OE, PU, PD, DRV etc.) + * when the pins are switched to RTC function. + */ #define SOC_RTCIO_HOLD_SUPPORTED 1 #define SOC_RTCIO_WAKE_SUPPORTED 1 diff --git a/components/soc/esp32s3/include/soc/soc_caps.h b/components/soc/esp32s3/include/soc/soc_caps.h index 0a6206dab3..6cd12bd56e 100644 --- a/components/soc/esp32s3/include/soc/soc_caps.h +++ b/components/soc/esp32s3/include/soc/soc_caps.h @@ -278,7 +278,10 @@ /*-------------------------- RTCIO CAPS --------------------------------------*/ #define SOC_RTCIO_PIN_COUNT 22 -#define SOC_RTCIO_INPUT_OUTPUT_SUPPORTED 1 // The target has separate RTC IOMUX +#define SOC_RTCIO_INPUT_OUTPUT_SUPPORTED 1 /* This macro indicates that the target has separate RTC IOMUX hardware feature, + * so it supports unique IOMUX configuration (including IE, OE, PU, PD, DRV etc.) + * when the pins are switched to RTC function. + */ #define SOC_RTCIO_HOLD_SUPPORTED 1 #define SOC_RTCIO_WAKE_SUPPORTED 1 From e70763f9a465df161a09e47ab5553a9b44af88d6 Mon Sep 17 00:00:00 2001 From: Lou Tianhao Date: Mon, 3 Jul 2023 21:25:56 +0800 Subject: [PATCH 4/7] feat(pm/deepsleep): Support EXT1 wakeup for esp32h2 deep_sleep --- components/esp_hw_support/include/esp_sleep.h | 9 ++++++- components/esp_hw_support/sleep_gpio.c | 3 +-- components/esp_hw_support/sleep_modes.c | 24 +++++++++---------- .../hal/esp32c6/include/hal/lp_aon_hal.h | 17 ++++--------- .../hal/esp32h2/include/hal/lp_aon_hal.h | 17 ++++--------- .../hal/esp32h2/include/hal/lp_aon_ll.h | 2 +- .../esp32h2/include/soc/Kconfig.soc_caps.in | 12 ++++++---- components/soc/esp32h2/include/soc/soc_caps.h | 4 ++-- .../system/deep_sleep/main/Kconfig.projbuild | 6 ++--- examples/system/deep_sleep/main/ext_wakeup.c | 17 +++++++++++-- 10 files changed, 59 insertions(+), 52 deletions(-) diff --git a/components/esp_hw_support/include/esp_sleep.h b/components/esp_hw_support/include/esp_sleep.h index a836a399c2..7a83c09a02 100644 --- a/components/esp_hw_support/include/esp_sleep.h +++ b/components/esp_hw_support/include/esp_sleep.h @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2015-2021 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2015-2023 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -26,10 +26,17 @@ typedef void (*esp_deep_sleep_cb_t)(void); /** * @brief Logic function used for EXT1 wakeup mode. */ +#if CONFIG_IDF_TARGET_ESP32 typedef enum { ESP_EXT1_WAKEUP_ALL_LOW = 0, //!< Wake the chip when all selected GPIOs go low ESP_EXT1_WAKEUP_ANY_HIGH = 1 //!< Wake the chip when any of the selected GPIOs go high } esp_sleep_ext1_wakeup_mode_t; +#else +typedef enum { + ESP_EXT1_WAKEUP_ANY_LOW = 0, //!< Wake the chip when any of the selected GPIOs go low + ESP_EXT1_WAKEUP_ANY_HIGH = 1 //!< Wake the chip when any of the selected GPIOs go high +} esp_sleep_ext1_wakeup_mode_t; +#endif #if SOC_GPIO_SUPPORT_DEEPSLEEP_WAKEUP typedef enum { diff --git a/components/esp_hw_support/sleep_gpio.c b/components/esp_hw_support/sleep_gpio.c index 8a420fce9b..759659d1a9 100644 --- a/components/esp_hw_support/sleep_gpio.c +++ b/components/esp_hw_support/sleep_gpio.c @@ -20,14 +20,13 @@ #include "driver/gpio.h" #include "hal/gpio_hal.h" #include "hal/rtc_io_hal.h" +#include "soc/rtc_io_periph.h" #if SOC_LP_AON_SUPPORTED #include "hal/lp_aon_hal.h" #else -#if !CONFIG_IDF_TARGET_ESP32H2 #include "hal/rtc_hal.h" #endif -#endif #include "esp_private/gpio.h" #include "esp_private/sleep_gpio.h" diff --git a/components/esp_hw_support/sleep_modes.c b/components/esp_hw_support/sleep_modes.c index 2fdb536f73..035cedb024 100644 --- a/components/esp_hw_support/sleep_modes.c +++ b/components/esp_hw_support/sleep_modes.c @@ -32,11 +32,9 @@ #if SOC_LP_AON_SUPPORTED #include "hal/lp_aon_hal.h" #else -#if !CONFIG_IDF_TARGET_ESP32H2 #include "hal/rtc_cntl_ll.h" #include "hal/rtc_hal.h" #endif -#endif #include "driver/uart.h" @@ -90,6 +88,7 @@ #include "esp32h2/rom/cache.h" #include "esp32h2/rom/rtc.h" #include "soc/extmem_reg.h" +#include "hal/gpio_ll.h" #endif #if SOC_LP_TIMER_SUPPORTED @@ -850,8 +849,6 @@ void IRAM_ATTR esp_deep_sleep_start(void) if (esp_get_deep_sleep_wake_stub() == NULL) { esp_set_deep_sleep_wake_stub(esp_wake_deep_sleep); } - // assert(0); - #endif // SOC_RTC_FAST_MEM_SUPPORTED // Decide which power domains can be powered down @@ -1419,8 +1416,18 @@ static void ext1_wakeup_prepare(void) rtcio_hal_function_select(rtc_pin, RTCIO_FUNC_RTC); // set input enable in sleep mode rtcio_hal_input_enable(rtc_pin); -#endif +#else + /* ESP32H2 use hp iomux to config rtcio, and there is no complete + * rtcio functionality. In the case of EXT1 wakeup, rtcio only provides + * a pathway to EXT1. */ + // Route pad to DIGITAL + rtcio_hal_function_select(rtc_pin, RTCIO_FUNC_DIGITAL); + // set input enable + gpio_ll_input_enable(&GPIO, gpio); + // hold rtc_pin to use it during sleep state + rtcio_hal_hold_enable(rtc_pin); +#endif #if SOC_PM_SUPPORT_RTC_PERIPH_PD // Pad configuration depends on RTC_PERIPH state in sleep mode if (s_config.domain[ESP_PD_DOMAIN_RTC_PERIPH].pd_option != ESP_PD_OPTION_ON) { @@ -1470,20 +1477,14 @@ uint64_t esp_sleep_get_ext1_wakeup_status(void) #if SOC_GPIO_SUPPORT_DEEPSLEEP_WAKEUP uint64_t esp_sleep_get_gpio_wakeup_status(void) { -#if CONFIG_IDF_TARGET_ESP32H2 // TODO: IDF-6268 - return 0; -#else if (esp_sleep_get_wakeup_cause() != ESP_SLEEP_WAKEUP_GPIO) { return 0; } - return rtc_hal_gpio_get_wakeup_status(); -#endif // !CONFIG_IDF_TARGET_ESP32H2 } static void gpio_deep_sleep_wakeup_prepare(void) { -#if !CONFIG_IDF_TARGET_ESP32H2 // TODO: IDF-6268 for (gpio_num_t gpio_idx = GPIO_NUM_0; gpio_idx < GPIO_NUM_MAX; gpio_idx++) { if (((1ULL << gpio_idx) & s_config.gpio_wakeup_mask) == 0) { continue; @@ -1499,7 +1500,6 @@ static void gpio_deep_sleep_wakeup_prepare(void) } // Clear state from previous wakeup rtc_hal_gpio_clear_wakeup_status(); -#endif // !CONFIG_IDF_TARGET_ESP32H2 } esp_err_t esp_deep_sleep_enable_gpio_wakeup(uint64_t gpio_pin_mask, esp_deepsleep_gpio_wake_up_mode_t mode) diff --git a/components/hal/esp32c6/include/hal/lp_aon_hal.h b/components/hal/esp32c6/include/hal/lp_aon_hal.h index c619dc0a6d..f3cd9e6b85 100644 --- a/components/hal/esp32c6/include/hal/lp_aon_hal.h +++ b/components/hal/esp32c6/include/hal/lp_aon_hal.h @@ -8,17 +8,10 @@ #include "hal/lp_aon_ll.h" -#define rtc_hal_ext1_get_wakeup_status() lp_aon_hal_ext1_get_wakeup_status() -#define rtc_hal_ext1_clear_wakeup_status() lp_aon_hal_ext1_clear_wakeup_status() -#define rtc_hal_ext1_set_wakeup_pins(mask, mode) lp_aon_hal_ext1_set_wakeup_pins(mask, mode) -#define rtc_hal_ext1_clear_wakeup_pins() lp_aon_hal_ext1_clear_wakeup_pins() -#define rtc_hal_ext1_get_wakeup_pins() lp_aon_hal_ext1_get_wakeup_pins() - - -#define lp_aon_hal_ext1_get_wakeup_status() lp_aon_ll_ext1_get_wakeup_status() -#define lp_aon_hal_ext1_clear_wakeup_status() lp_aon_ll_ext1_clear_wakeup_status() -#define lp_aon_hal_ext1_set_wakeup_pins(mask, mode) lp_aon_ll_ext1_set_wakeup_pins(mask, mode) -#define lp_aon_hal_ext1_clear_wakeup_pins() lp_aon_ll_ext1_clear_wakeup_pins() -#define lp_aon_hal_ext1_get_wakeup_pins() lp_aon_ll_ext1_get_wakeup_pins() +#define rtc_hal_ext1_get_wakeup_status() lp_aon_ll_ext1_get_wakeup_status() +#define rtc_hal_ext1_clear_wakeup_status() lp_aon_ll_ext1_clear_wakeup_status() +#define rtc_hal_ext1_set_wakeup_pins(mask, mode) lp_aon_ll_ext1_set_wakeup_pins(mask, mode) +#define rtc_hal_ext1_clear_wakeup_pins() lp_aon_ll_ext1_clear_wakeup_pins() +#define rtc_hal_ext1_get_wakeup_pins() lp_aon_ll_ext1_get_wakeup_pins() #define lp_aon_hal_inform_wakeup_type(dslp) lp_aon_ll_inform_wakeup_type(dslp) diff --git a/components/hal/esp32h2/include/hal/lp_aon_hal.h b/components/hal/esp32h2/include/hal/lp_aon_hal.h index c619dc0a6d..f3cd9e6b85 100644 --- a/components/hal/esp32h2/include/hal/lp_aon_hal.h +++ b/components/hal/esp32h2/include/hal/lp_aon_hal.h @@ -8,17 +8,10 @@ #include "hal/lp_aon_ll.h" -#define rtc_hal_ext1_get_wakeup_status() lp_aon_hal_ext1_get_wakeup_status() -#define rtc_hal_ext1_clear_wakeup_status() lp_aon_hal_ext1_clear_wakeup_status() -#define rtc_hal_ext1_set_wakeup_pins(mask, mode) lp_aon_hal_ext1_set_wakeup_pins(mask, mode) -#define rtc_hal_ext1_clear_wakeup_pins() lp_aon_hal_ext1_clear_wakeup_pins() -#define rtc_hal_ext1_get_wakeup_pins() lp_aon_hal_ext1_get_wakeup_pins() - - -#define lp_aon_hal_ext1_get_wakeup_status() lp_aon_ll_ext1_get_wakeup_status() -#define lp_aon_hal_ext1_clear_wakeup_status() lp_aon_ll_ext1_clear_wakeup_status() -#define lp_aon_hal_ext1_set_wakeup_pins(mask, mode) lp_aon_ll_ext1_set_wakeup_pins(mask, mode) -#define lp_aon_hal_ext1_clear_wakeup_pins() lp_aon_ll_ext1_clear_wakeup_pins() -#define lp_aon_hal_ext1_get_wakeup_pins() lp_aon_ll_ext1_get_wakeup_pins() +#define rtc_hal_ext1_get_wakeup_status() lp_aon_ll_ext1_get_wakeup_status() +#define rtc_hal_ext1_clear_wakeup_status() lp_aon_ll_ext1_clear_wakeup_status() +#define rtc_hal_ext1_set_wakeup_pins(mask, mode) lp_aon_ll_ext1_set_wakeup_pins(mask, mode) +#define rtc_hal_ext1_clear_wakeup_pins() lp_aon_ll_ext1_clear_wakeup_pins() +#define rtc_hal_ext1_get_wakeup_pins() lp_aon_ll_ext1_get_wakeup_pins() #define lp_aon_hal_inform_wakeup_type(dslp) lp_aon_ll_inform_wakeup_type(dslp) diff --git a/components/hal/esp32h2/include/hal/lp_aon_ll.h b/components/hal/esp32h2/include/hal/lp_aon_ll.h index c214c6f638..23eacccb53 100644 --- a/components/hal/esp32h2/include/hal/lp_aon_ll.h +++ b/components/hal/esp32h2/include/hal/lp_aon_ll.h @@ -4,7 +4,7 @@ * SPDX-License-Identifier: Apache-2.0 */ -// The LL layer for ESP32-C6 LP_AON register operations +// The LL layer for ESP32-H2 LP_AON register operations #pragma once diff --git a/components/soc/esp32h2/include/soc/Kconfig.soc_caps.in b/components/soc/esp32h2/include/soc/Kconfig.soc_caps.in index ab8973df8d..e019e99a72 100644 --- a/components/soc/esp32h2/include/soc/Kconfig.soc_caps.in +++ b/components/soc/esp32h2/include/soc/Kconfig.soc_caps.in @@ -175,6 +175,10 @@ config SOC_LP_TIMER_SUPPORTED bool default y +config SOC_LP_AON_SUPPORTED + bool + default y + config SOC_PAU_SUPPORTED bool default y @@ -1099,14 +1103,14 @@ config SOC_PHY_DIG_REGS_MEM_SIZE int default 21 -config SOC_PM_SUPPORT_EXT1_WAKEUP - bool - default n - config SOC_PM_SUPPORT_BT_WAKEUP bool default y +config SOC_PM_SUPPORT_EXT1_WAKEUP + bool + default y + config SOC_PM_SUPPORT_CPU_PD bool default y diff --git a/components/soc/esp32h2/include/soc/soc_caps.h b/components/soc/esp32h2/include/soc/soc_caps.h index 618c6969f6..845dffb21d 100644 --- a/components/soc/esp32h2/include/soc/soc_caps.h +++ b/components/soc/esp32h2/include/soc/soc_caps.h @@ -69,6 +69,7 @@ #define SOC_APM_SUPPORTED 1 #define SOC_PMU_SUPPORTED 1 #define SOC_LP_TIMER_SUPPORTED 1 +#define SOC_LP_AON_SUPPORTED 1 #define SOC_PAU_SUPPORTED 1 #define SOC_CLK_TREE_SUPPORTED 1 #define SOC_ASSIST_DEBUG_SUPPORTED 1 @@ -462,9 +463,8 @@ #define SOC_PHY_DIG_REGS_MEM_SIZE (21*4) /*-------------------------- Power Management CAPS ----------------------------*/ -#define SOC_PM_SUPPORT_EXT1_WAKEUP (0) #define SOC_PM_SUPPORT_BT_WAKEUP (1) -// #define SOC_PM_SUPPORT_EXT1_WAKEUP (1) // TODO: IDF-6268 +#define SOC_PM_SUPPORT_EXT1_WAKEUP (1) #define SOC_PM_SUPPORT_CPU_PD (1) #define SOC_PM_SUPPORT_MODEM_PD (1) /*! Date: Thu, 13 Jul 2023 14:19:48 +0800 Subject: [PATCH 5/7] feat(pm/deepsleep): Support EXT1 wakeup pin select --- .../system/deep_sleep/main/Kconfig.projbuild | 229 +++++++++++++++++- examples/system/deep_sleep/main/ext_wakeup.c | 19 +- 2 files changed, 227 insertions(+), 21 deletions(-) diff --git a/examples/system/deep_sleep/main/Kconfig.projbuild b/examples/system/deep_sleep/main/Kconfig.projbuild index 79ec174f85..96bd151b9f 100644 --- a/examples/system/deep_sleep/main/Kconfig.projbuild +++ b/examples/system/deep_sleep/main/Kconfig.projbuild @@ -32,20 +32,225 @@ menu "Example Configuration" floating pins. When triggering a wake up, connect one or both of the pins to HIGH. Note that floating pins may trigger a wake up. - config EXAMPLE_EXT1_USE_INTERNAL_PULLUPS - bool "Use internal pull-up/downs for EXT1 wakeup source" - default n - depends on EXAMPLE_EXT1_WAKEUP - help - When using EXT1 wakeup source without external pull-up/downs, you may want to make use of the internal - ones. + menu "EXT1 wakeup configuration" + visible if EXAMPLE_EXT1_WAKEUP - However, the RTC IO reside in the RTC Periph power domain. Enable this option to force that power domain - ON during deep sleep. Note that this will increase some power comsumption, so it's still suggested to use - external ones instead. + config EXAMPLE_EXT1_WAKEUP_PIN_1 + int "Enable wakeup from PIN_1" + depends on !IDF_TARGET_ESP32 + default 2 if !IDF_TARGET_ESP32H2 + default 10 if IDF_TARGET_ESP32H2 + range 0 7 if IDF_TARGET_ESP32C6 + range 7 14 if IDF_TARGET_ESP32H2 + range 0 21 if IDF_TARGET_ESP32S2 + range 0 21 if IDF_TARGET_ESP32S3 - EXT0 wakeup source resides in the same power domain as RTCIO (RTC Periph), so internal pull-up/downs are - always available. There's no need to explicitly force it on for EXT0. + choice EXAMPLE_EXT1_WAKEUP_PIN_1_SEL + prompt "Enable wakeup from PIN_1" + default EXAMPLE_EXT1_WAKEUP_PIN_1_SEL_2 + depends on IDF_TARGET_ESP32 + config EXAMPLE_EXT1_WAKEUP_PIN_1_SEL_0 + bool "GPIO 0" + config EXAMPLE_EXT1_WAKEUP_PIN_1_SEL_2 + bool "GPIO 2" + config EXAMPLE_EXT1_WAKEUP_PIN_1_SEL_4 + bool "GPIO 4" + config EXAMPLE_EXT1_WAKEUP_PIN_1_SEL_12 + bool "GPIO 12" + config EXAMPLE_EXT1_WAKEUP_PIN_1_SEL_13 + bool "GPIO 13" + config EXAMPLE_EXT1_WAKEUP_PIN_1_SEL_14 + bool "GPIO 14" + config EXAMPLE_EXT1_WAKEUP_PIN_1_SEL_15 + bool "GPIO 15" + config EXAMPLE_EXT1_WAKEUP_PIN_1_SEL_25 + bool "GPIO 25" + config EXAMPLE_EXT1_WAKEUP_PIN_1_SEL_26 + bool "GPIO 26" + config EXAMPLE_EXT1_WAKEUP_PIN_1_SEL_27 + bool "GPIO 27" + config EXAMPLE_EXT1_WAKEUP_PIN_1_SEL_32 + bool "GPIO 32" + config EXAMPLE_EXT1_WAKEUP_PIN_1_SEL_33 + bool "GPIO 33" + config EXAMPLE_EXT1_WAKEUP_PIN_1_SEL_34 + bool "GPIO 34" + config EXAMPLE_EXT1_WAKEUP_PIN_1_SEL_35 + bool "GPIO 35" + config EXAMPLE_EXT1_WAKEUP_PIN_1_SEL_36 + bool "GPIO 36" + config EXAMPLE_EXT1_WAKEUP_PIN_1_SEL_37 + bool "GPIO 37" + config EXAMPLE_EXT1_WAKEUP_PIN_1_SEL_38 + bool "GPIO 38" + config EXAMPLE_EXT1_WAKEUP_PIN_1_SEL_39 + bool "GPIO 39" + endchoice + + config EXAMPLE_EXT1_WAKEUP_PIN_1 + int + depends on IDF_TARGET_ESP32 + default 0 if EXAMPLE_EXT1_WAKEUP_PIN_1_SEL_0 + default 2 if EXAMPLE_EXT1_WAKEUP_PIN_1_SEL_2 + default 4 if EXAMPLE_EXT1_WAKEUP_PIN_1_SEL_4 + default 12 if EXAMPLE_EXT1_WAKEUP_PIN_1_SEL_12 + default 13 if EXAMPLE_EXT1_WAKEUP_PIN_1_SEL_13 + default 14 if EXAMPLE_EXT1_WAKEUP_PIN_1_SEL_14 + default 15 if EXAMPLE_EXT1_WAKEUP_PIN_1_SEL_15 + default 25 if EXAMPLE_EXT1_WAKEUP_PIN_1_SEL_25 + default 26 if EXAMPLE_EXT1_WAKEUP_PIN_1_SEL_26 + default 27 if EXAMPLE_EXT1_WAKEUP_PIN_1_SEL_27 + default 32 if EXAMPLE_EXT1_WAKEUP_PIN_1_SEL_32 + default 33 if EXAMPLE_EXT1_WAKEUP_PIN_1_SEL_33 + default 34 if EXAMPLE_EXT1_WAKEUP_PIN_1_SEL_34 + default 35 if EXAMPLE_EXT1_WAKEUP_PIN_1_SEL_35 + default 36 if EXAMPLE_EXT1_WAKEUP_PIN_1_SEL_36 + default 37 if EXAMPLE_EXT1_WAKEUP_PIN_1_SEL_37 + default 38 if EXAMPLE_EXT1_WAKEUP_PIN_1_SEL_38 + default 39 if EXAMPLE_EXT1_WAKEUP_PIN_1_SEL_39 + + config EXAMPLE_EXT1_WAKEUP_PIN_2 + int "Enable wakeup from PIN_2" + depends on !IDF_TARGET_ESP32 + default 4 if !IDF_TARGET_ESP32H2 + default 11 if IDF_TARGET_ESP32H2 + range 0 7 if IDF_TARGET_ESP32C6 + range 7 14 if IDF_TARGET_ESP32H2 + range 0 21 if IDF_TARGET_ESP32S2 + range 0 21 if IDF_TARGET_ESP32S3 + + choice EXAMPLE_EXT1_WAKEUP_PIN_2_SEL + prompt "Enable wakeup from PIN_2" + default EXAMPLE_EXT1_WAKEUP_PIN_2_SEL_4 + depends on IDF_TARGET_ESP32 + config EXAMPLE_EXT1_WAKEUP_PIN_2_SEL_0 + bool "GPIO 0" + config EXAMPLE_EXT1_WAKEUP_PIN_2_SEL_2 + bool "GPIO 2" + config EXAMPLE_EXT1_WAKEUP_PIN_2_SEL_4 + bool "GPIO 4" + config EXAMPLE_EXT1_WAKEUP_PIN_2_SEL_12 + bool "GPIO 12" + config EXAMPLE_EXT1_WAKEUP_PIN_2_SEL_13 + bool "GPIO 13" + config EXAMPLE_EXT1_WAKEUP_PIN_2_SEL_14 + bool "GPIO 14" + config EXAMPLE_EXT1_WAKEUP_PIN_2_SEL_15 + bool "GPIO 15" + config EXAMPLE_EXT1_WAKEUP_PIN_2_SEL_25 + bool "GPIO 25" + config EXAMPLE_EXT1_WAKEUP_PIN_2_SEL_26 + bool "GPIO 26" + config EXAMPLE_EXT1_WAKEUP_PIN_2_SEL_27 + bool "GPIO 27" + config EXAMPLE_EXT1_WAKEUP_PIN_2_SEL_32 + bool "GPIO 32" + config EXAMPLE_EXT1_WAKEUP_PIN_2_SEL_33 + bool "GPIO 33" + config EXAMPLE_EXT1_WAKEUP_PIN_2_SEL_34 + bool "GPIO 34" + config EXAMPLE_EXT1_WAKEUP_PIN_2_SEL_35 + bool "GPIO 35" + config EXAMPLE_EXT1_WAKEUP_PIN_2_SEL_36 + bool "GPIO 36" + config EXAMPLE_EXT1_WAKEUP_PIN_2_SEL_37 + bool "GPIO 37" + config EXAMPLE_EXT1_WAKEUP_PIN_2_SEL_38 + bool "GPIO 38" + config EXAMPLE_EXT1_WAKEUP_PIN_2_SEL_39 + bool "GPIO 39" + endchoice + + config EXAMPLE_EXT1_WAKEUP_PIN_2 + int + depends on IDF_TARGET_ESP32 + default 0 if EXAMPLE_EXT1_WAKEUP_PIN_2_SEL_0 + default 2 if EXAMPLE_EXT1_WAKEUP_PIN_2_SEL_2 + default 4 if EXAMPLE_EXT1_WAKEUP_PIN_2_SEL_4 + default 12 if EXAMPLE_EXT1_WAKEUP_PIN_2_SEL_12 + default 13 if EXAMPLE_EXT1_WAKEUP_PIN_2_SEL_13 + default 14 if EXAMPLE_EXT1_WAKEUP_PIN_2_SEL_14 + default 15 if EXAMPLE_EXT1_WAKEUP_PIN_2_SEL_15 + default 25 if EXAMPLE_EXT1_WAKEUP_PIN_2_SEL_25 + default 26 if EXAMPLE_EXT1_WAKEUP_PIN_2_SEL_26 + default 27 if EXAMPLE_EXT1_WAKEUP_PIN_2_SEL_27 + default 32 if EXAMPLE_EXT1_WAKEUP_PIN_2_SEL_32 + default 33 if EXAMPLE_EXT1_WAKEUP_PIN_2_SEL_33 + default 34 if EXAMPLE_EXT1_WAKEUP_PIN_2_SEL_34 + default 35 if EXAMPLE_EXT1_WAKEUP_PIN_2_SEL_35 + default 36 if EXAMPLE_EXT1_WAKEUP_PIN_2_SEL_36 + default 37 if EXAMPLE_EXT1_WAKEUP_PIN_2_SEL_37 + default 38 if EXAMPLE_EXT1_WAKEUP_PIN_2_SEL_38 + default 39 if EXAMPLE_EXT1_WAKEUP_PIN_2_SEL_39 + + choice EXAMPLE_EXT1_WAKEUP_MODE_SEL + prompt "Select wakeup mode from EXT1" + default ESP_EXT1_WAKEUP_ANY_HIGH + depends on !SOC_PM_SUPPORT_EXT1_MULTI_BIT_TRIGGER + config ESP_EXT1_WAKEUP_ANY_LOW + bool "GPIO any low level" + depends on !IDF_TARGET_ESP32 + config ESP_EXT1_WAKEUP_ALL_LOW + bool "GPIO all low level" + depends on IDF_TARGET_ESP32 + config ESP_EXT1_WAKEUP_ANY_HIGH + bool "GPIO any high level" + endchoice + + config EXAMPLE_EXT1_WAKEUP_MODE + int + depends on !SOC_PM_SUPPORT_EXT1_MULTI_BIT_TRIGGER + default 0 if ESP_EXT1_WAKEUP_ANY_LOW + default 0 if ESP_EXT1_WAKEUP_ALL_LOW + default 1 if ESP_EXT1_WAKEUP_ANY_HIGH + + choice EXAMPLE_EXT1_WAKEUP_PIN_1_MODE_SEL + prompt "Select pin_1 wakeup mode from EXT1" + default ESP_EXT1_WAKEUP_PIN_1_HIGH + depends on SOC_PM_SUPPORT_EXT1_MULTI_BIT_TRIGGER + config ESP_EXT1_WAKEUP_PIN_1_LOW + bool "GPIO low level" + config ESP_EXT1_WAKEUP_PIN_1_HIGH + bool "GPIO high level" + endchoice + + config EXAMPLE_EXT1_WAKEUP_MODE_PIN_1 + int + depends on SOC_PM_SUPPORT_EXT1_MULTI_BIT_TRIGGER + default 0 if ESP_EXT1_WAKEUP_PIN_1_LOW + default 1 if ESP_EXT1_WAKEUP_PIN_1_HIGH + + choice EXAMPLE_EXT1_WAKEUP_PIN_2_MODE_SEL + prompt "Select pin_2 wakeup mode from EXT1" + default ESP_EXT1_WAKEUP_PIN_2_HIGH + depends on SOC_PM_SUPPORT_EXT1_MULTI_BIT_TRIGGER + config ESP_EXT1_WAKEUP_PIN_2_LOW + bool "GPIO low level" + config ESP_EXT1_WAKEUP_PIN_2_HIGH + bool "GPIO high level" + endchoice + + config EXAMPLE_EXT1_WAKEUP_MODE_PIN_2 + int + depends on SOC_PM_SUPPORT_EXT1_MULTI_BIT_TRIGGER + default 0 if ESP_EXT1_WAKEUP_PIN_2_LOW + default 1 if ESP_EXT1_WAKEUP_PIN_2_HIGH + + config EXAMPLE_EXT1_USE_INTERNAL_PULLUPS + bool "Use internal pull-up/downs for EXT1 wakeup source" + default n + depends on EXAMPLE_EXT1_WAKEUP + help + When using EXT1 wakeup source without external pull-up/downs, you may want to make use of + the internal ones. + + However, the RTC IO reside in the RTC Periph power domain. Enable this option to force that + power domain ON during deep sleep. Note that this will increase some power comsumption, so + it's still suggested to use external ones instead. + + EXT0 wakeup source resides in the same power domain as RTCIO (RTC Periph), so internal + pull-up/downs are always available. There's no need to explicitly force it on for EXT0. + endmenu config EXAMPLE_GPIO_WAKEUP bool "Enable wakeup from GPIO" diff --git a/examples/system/deep_sleep/main/ext_wakeup.c b/examples/system/deep_sleep/main/ext_wakeup.c index 755d7bc78d..03870075ff 100644 --- a/examples/system/deep_sleep/main/ext_wakeup.c +++ b/examples/system/deep_sleep/main/ext_wakeup.c @@ -33,18 +33,19 @@ void example_deep_sleep_register_ext0_wakeup(void) #if CONFIG_EXAMPLE_EXT1_WAKEUP void example_deep_sleep_register_ext1_wakeup(void) { -#if !CONFIG_IDF_TARGET_ESP32H2 - const int ext_wakeup_pin_1 = 2; - const int ext_wakeup_pin_2 = 4; -#else - const int ext_wakeup_pin_1 = 10; - const int ext_wakeup_pin_2 = 11; -#endif - + const int ext_wakeup_pin_1 = CONFIG_EXAMPLE_EXT1_WAKEUP_PIN_1; + const int ext_wakeup_pin_2 = CONFIG_EXAMPLE_EXT1_WAKEUP_PIN_2; const uint64_t ext_wakeup_pin_1_mask = 1ULL << ext_wakeup_pin_1; const uint64_t ext_wakeup_pin_2_mask = 1ULL << ext_wakeup_pin_2; printf("Enabling EXT1 wakeup on pins GPIO%d, GPIO%d\n", ext_wakeup_pin_1, ext_wakeup_pin_2); - ESP_ERROR_CHECK(esp_sleep_enable_ext1_wakeup(ext_wakeup_pin_1_mask | ext_wakeup_pin_2_mask, ESP_EXT1_WAKEUP_ANY_HIGH)); +#if SOC_PM_SUPPORT_EXT1_MULTI_BIT_TRIGGER + const esp_sleep_ext1_wakeup_mode_t ext_wakeup_mode = CONFIG_EXAMPLE_EXT1_WAKEUP_MODE; +#else + const esp_sleep_ext1_wakeup_mode_t ext_wakeup_mode = CONFIG_EXAMPLE_EXT1_WAKEUP_MODE_PIN_1 << ext_wakeup_pin_1 | \ + CONFIG_EXAMPLE_EXT1_WAKEUP_MODE_PIN_2 << ext_wakeup_pin_2; +#endif + + ESP_ERROR_CHECK(esp_sleep_enable_ext1_wakeup(ext_wakeup_pin_1_mask | ext_wakeup_pin_2_mask, ext_wakeup_mode)); /* If there are no external pull-up/downs, tie wakeup pins to inactive level with internal pull-up/downs via RTC IO * during deepsleep. However, RTC IO relies on the RTC_PERIPH power domain. Keeping this power domain on will From 44cd96b5432b8e5963767097e831893a25c1b085 Mon Sep 17 00:00:00 2001 From: Lou Tianhao Date: Tue, 11 Jul 2023 17:15:59 +0800 Subject: [PATCH 6/7] change(pm/deepsleep): remove disable rtcio before hold it when ext1 wakeup --- components/esp_hw_support/sleep_modes.c | 19 ++++------ .../system/deep_sleep/main/Kconfig.projbuild | 7 ++-- examples/system/deep_sleep/main/ext_wakeup.c | 36 +++++++++++++------ 3 files changed, 35 insertions(+), 27 deletions(-) diff --git a/components/esp_hw_support/sleep_modes.c b/components/esp_hw_support/sleep_modes.c index 035cedb024..67c736d90c 100644 --- a/components/esp_hw_support/sleep_modes.c +++ b/components/esp_hw_support/sleep_modes.c @@ -1416,6 +1416,12 @@ static void ext1_wakeup_prepare(void) rtcio_hal_function_select(rtc_pin, RTCIO_FUNC_RTC); // set input enable in sleep mode rtcio_hal_input_enable(rtc_pin); +#if SOC_PM_SUPPORT_RTC_PERIPH_PD + // Pad configuration depends on RTC_PERIPH state in sleep mode + if (s_config.domain[ESP_PD_DOMAIN_RTC_PERIPH].pd_option != ESP_PD_OPTION_ON) { + rtcio_hal_hold_enable(rtc_pin); + } +#endif #else /* ESP32H2 use hp iomux to config rtcio, and there is no complete * rtcio functionality. In the case of EXT1 wakeup, rtcio only provides @@ -1427,19 +1433,6 @@ static void ext1_wakeup_prepare(void) gpio_ll_input_enable(&GPIO, gpio); // hold rtc_pin to use it during sleep state rtcio_hal_hold_enable(rtc_pin); -#endif -#if SOC_PM_SUPPORT_RTC_PERIPH_PD - // Pad configuration depends on RTC_PERIPH state in sleep mode - if (s_config.domain[ESP_PD_DOMAIN_RTC_PERIPH].pd_option != ESP_PD_OPTION_ON) { -#if SOC_RTCIO_INPUT_OUTPUT_SUPPORTED - // RTC_PERIPH will be powered down, so RTC_IO_ registers will - // loose their state. Lock pad configuration. - // Pullups/pulldowns also need to be disabled. - rtcio_hal_pullup_disable(rtc_pin); - rtcio_hal_pulldown_disable(rtc_pin); -#endif - rtcio_hal_hold_enable(rtc_pin); - } #endif // Keep track of pins which are processed to bail out early rtc_gpio_mask &= ~BIT(rtc_pin); diff --git a/examples/system/deep_sleep/main/Kconfig.projbuild b/examples/system/deep_sleep/main/Kconfig.projbuild index 96bd151b9f..0c16340f73 100644 --- a/examples/system/deep_sleep/main/Kconfig.projbuild +++ b/examples/system/deep_sleep/main/Kconfig.projbuild @@ -244,9 +244,10 @@ menu "Example Configuration" When using EXT1 wakeup source without external pull-up/downs, you may want to make use of the internal ones. - However, the RTC IO reside in the RTC Periph power domain. Enable this option to force that - power domain ON during deep sleep. Note that this will increase some power comsumption, so - it's still suggested to use external ones instead. + if we turn off the RTC_PERIPH domain or if certain chips lack the RTC_PERIPH domain, + we will use the HOLD feature to maintain the pull-up and pull-down on the pins during sleep. + but if we turn on the RTC_PERIPH domain, we don not need to use HOLD feature and this will + increase some power comsumption. EXT0 wakeup source resides in the same power domain as RTCIO (RTC Periph), so internal pull-up/downs are always available. There's no need to explicitly force it on for EXT0. diff --git a/examples/system/deep_sleep/main/ext_wakeup.c b/examples/system/deep_sleep/main/ext_wakeup.c index 03870075ff..3f2590be35 100644 --- a/examples/system/deep_sleep/main/ext_wakeup.c +++ b/examples/system/deep_sleep/main/ext_wakeup.c @@ -49,19 +49,33 @@ void example_deep_sleep_register_ext1_wakeup(void) /* If there are no external pull-up/downs, tie wakeup pins to inactive level with internal pull-up/downs via RTC IO * during deepsleep. However, RTC IO relies on the RTC_PERIPH power domain. Keeping this power domain on will - * increase some power comsumption. */ + * increase some power comsumption. However, if we turn off the RTC_PERIPH domain or if certain chips lack the RTC_PERIPH + * domain, we will use the HOLD feature to maintain the pull-up and pull-down on the pins during sleep.*/ #if CONFIG_EXAMPLE_EXT1_USE_INTERNAL_PULLUPS -#if !CONFIG_IDF_TARGET_ESP32H2 - ESP_ERROR_CHECK(esp_sleep_pd_config(ESP_PD_DOMAIN_RTC_PERIPH, ESP_PD_OPTION_ON)); - ESP_ERROR_CHECK(rtc_gpio_pullup_dis(ext_wakeup_pin_1)); - ESP_ERROR_CHECK(rtc_gpio_pulldown_en(ext_wakeup_pin_1)); - ESP_ERROR_CHECK(rtc_gpio_pullup_dis(ext_wakeup_pin_2)); - ESP_ERROR_CHECK(rtc_gpio_pulldown_en(ext_wakeup_pin_2)); +#if SOC_RTCIO_INPUT_OUTPUT_SUPPORTED + if (ext_wakeup_mode) { + ESP_ERROR_CHECK(rtc_gpio_pullup_dis(ext_wakeup_pin_1)); + ESP_ERROR_CHECK(rtc_gpio_pulldown_en(ext_wakeup_pin_1)); + ESP_ERROR_CHECK(rtc_gpio_pullup_dis(ext_wakeup_pin_2)); + ESP_ERROR_CHECK(rtc_gpio_pulldown_en(ext_wakeup_pin_2)); + } else { + ESP_ERROR_CHECK(rtc_gpio_pulldown_dis(ext_wakeup_pin_1)); + ESP_ERROR_CHECK(rtc_gpio_pullup_en(ext_wakeup_pin_1)); + ESP_ERROR_CHECK(rtc_gpio_pulldown_dis(ext_wakeup_pin_2)); + ESP_ERROR_CHECK(rtc_gpio_pullup_en(ext_wakeup_pin_2)); + } #else - gpio_pullup_dis(ext_wakeup_pin_1); - gpio_pulldown_en(ext_wakeup_pin_1); - gpio_pullup_dis(ext_wakeup_pin_2); - gpio_pulldown_en(ext_wakeup_pin_2); + if (ext_wakeup_mode) { + ESP_ERROR_CHECK(gpio_pullup_dis(ext_wakeup_pin_1)); + ESP_ERROR_CHECK(gpio_pulldown_en(ext_wakeup_pin_1)); + ESP_ERROR_CHECK(gpio_pullup_dis(ext_wakeup_pin_2)); + ESP_ERROR_CHECK(gpio_pulldown_en(ext_wakeup_pin_2)); + } else { + ESP_ERROR_CHECK(gpio_pulldown_dis(ext_wakeup_pin_1)); + ESP_ERROR_CHECK(gpio_pullup_en(ext_wakeup_pin_1)); + ESP_ERROR_CHECK(gpio_pulldown_dis(ext_wakeup_pin_2)); + ESP_ERROR_CHECK(gpio_pullup_en(ext_wakeup_pin_2)); + } #endif #endif //CONFIG_EXAMPLE_EXT1_USE_INTERNAL_PULLUPS } From 0d30bbe855e2c461e4c7251225d467685b5f644b Mon Sep 17 00:00:00 2001 From: Lou Tianhao Date: Tue, 18 Jul 2023 19:33:30 +0800 Subject: [PATCH 7/7] change(pm/deepsleep): rewrite the option all low as any low for esp32s2, esp32s3, esp32c6 and esp32h2 --- components/esp_hw_support/include/esp_sleep.h | 6 +++- components/esp_hw_support/sleep_modes.c | 2 +- .../esp_system_unity_tests/main/test_sleep.c | 10 +++++- .../hal/esp32c6/include/hal/lp_aon_ll.h | 2 +- .../hal/esp32h2/include/hal/lp_aon_ll.h | 2 +- .../system/deep_sleep/main/Kconfig.projbuild | 34 ------------------- examples/system/deep_sleep/main/ext_wakeup.c | 7 +--- 7 files changed, 18 insertions(+), 45 deletions(-) diff --git a/components/esp_hw_support/include/esp_sleep.h b/components/esp_hw_support/include/esp_sleep.h index 7a83c09a02..f0f3f26ab9 100644 --- a/components/esp_hw_support/include/esp_sleep.h +++ b/components/esp_hw_support/include/esp_sleep.h @@ -26,6 +26,7 @@ typedef void (*esp_deep_sleep_cb_t)(void); /** * @brief Logic function used for EXT1 wakeup mode. */ +#if SOC_PM_SUPPORT_EXT1_WAKEUP #if CONFIG_IDF_TARGET_ESP32 typedef enum { ESP_EXT1_WAKEUP_ALL_LOW = 0, //!< Wake the chip when all selected GPIOs go low @@ -34,9 +35,12 @@ typedef enum { #else typedef enum { ESP_EXT1_WAKEUP_ANY_LOW = 0, //!< Wake the chip when any of the selected GPIOs go low - ESP_EXT1_WAKEUP_ANY_HIGH = 1 //!< Wake the chip when any of the selected GPIOs go high + ESP_EXT1_WAKEUP_ANY_HIGH = 1, //!< Wake the chip when any of the selected GPIOs go high + ESP_EXT1_WAKEUP_ALL_LOW __attribute__((deprecated("wakeup mode \"ALL_LOW\" is no longer supported after ESP32, \ + please use ESP_EXT1_WAKEUP_ANY_LOW instead"))) = ESP_EXT1_WAKEUP_ANY_LOW } esp_sleep_ext1_wakeup_mode_t; #endif +#endif #if SOC_GPIO_SUPPORT_DEEPSLEEP_WAKEUP typedef enum { diff --git a/components/esp_hw_support/sleep_modes.c b/components/esp_hw_support/sleep_modes.c index 67c736d90c..3835c113aa 100644 --- a/components/esp_hw_support/sleep_modes.c +++ b/components/esp_hw_support/sleep_modes.c @@ -1440,7 +1440,7 @@ static void ext1_wakeup_prepare(void) // Clear state from previous wakeup rtc_hal_ext1_clear_wakeup_status(); - // Set RTC IO pins and mode (any high, all low) to be used for wakeup + // Set RTC IO pins and mode to be used for wakeup rtc_hal_ext1_set_wakeup_pins(s_config.ext1_rtc_gpio_mask, s_config.ext1_trigger_mode); } diff --git a/components/esp_system/test_apps/esp_system_unity_tests/main/test_sleep.c b/components/esp_system/test_apps/esp_system_unity_tests/main/test_sleep.c index 681ae8a81d..8ae49e9948 100644 --- a/components/esp_system/test_apps/esp_system_unity_tests/main/test_sleep.c +++ b/components/esp_system/test_apps/esp_system_unity_tests/main/test_sleep.c @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2019-2022 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2019-2023 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -419,7 +419,11 @@ TEST_CASE("wake up using ext1 when RTC_PERIPH is off (13 low)", "[deepsleep][ign { // This test needs external pullup ESP_ERROR_CHECK(rtc_gpio_init(GPIO_NUM_13)); +#if CONFIG_IDF_TARGET_ESP32 ESP_ERROR_CHECK(esp_sleep_enable_ext1_wakeup(BIT(GPIO_NUM_13), ESP_EXT1_WAKEUP_ALL_LOW)); +#else + ESP_ERROR_CHECK(esp_sleep_enable_ext1_wakeup(BIT(GPIO_NUM_13), ESP_EXT1_WAKEUP_ANY_LOW)); +#endif esp_deep_sleep_start(); } @@ -439,7 +443,11 @@ TEST_CASE("wake up using ext1 when RTC_PERIPH is on (13 low)", "[deepsleep][igno ESP_ERROR_CHECK(gpio_pullup_en(GPIO_NUM_13)); ESP_ERROR_CHECK(gpio_pulldown_dis(GPIO_NUM_13)); ESP_ERROR_CHECK(esp_sleep_pd_config(ESP_PD_DOMAIN_RTC_PERIPH, ESP_PD_OPTION_ON)); +#if CONFIG_IDF_TARGET_ESP32 ESP_ERROR_CHECK(esp_sleep_enable_ext1_wakeup(BIT(GPIO_NUM_13), ESP_EXT1_WAKEUP_ALL_LOW)); +#else + ESP_ERROR_CHECK(esp_sleep_enable_ext1_wakeup(BIT(GPIO_NUM_13), ESP_EXT1_WAKEUP_ANY_LOW)); +#endif esp_deep_sleep_start(); } #endif // SOC_PM_SUPPORT_EXT1_WAKEUP diff --git a/components/hal/esp32c6/include/hal/lp_aon_ll.h b/components/hal/esp32c6/include/hal/lp_aon_ll.h index db08715964..22ae12dbf6 100644 --- a/components/hal/esp32c6/include/hal/lp_aon_ll.h +++ b/components/hal/esp32c6/include/hal/lp_aon_ll.h @@ -40,7 +40,7 @@ static inline void lp_aon_ll_ext1_clear_wakeup_status(void) /** * @brief Set the wake-up LP_IO of the ext1 wake-up source * @param mask wakeup LP_IO bitmap, bit 0~7 corresponds to LP_IO 0~7 - * @param mode 0: Wake the chip when all selected GPIOs go low + * @param mode 0: Wake the chip when any of the selected GPIOs go low * 1: Wake the chip when any of the selected GPIOs go high */ static inline void lp_aon_ll_ext1_set_wakeup_pins(uint32_t mask, int mode) diff --git a/components/hal/esp32h2/include/hal/lp_aon_ll.h b/components/hal/esp32h2/include/hal/lp_aon_ll.h index 23eacccb53..f556def282 100644 --- a/components/hal/esp32h2/include/hal/lp_aon_ll.h +++ b/components/hal/esp32h2/include/hal/lp_aon_ll.h @@ -40,7 +40,7 @@ static inline void lp_aon_ll_ext1_clear_wakeup_status(void) /** * @brief Set the wake-up LP_IO of the ext1 wake-up source * @param mask wakeup LP_IO bitmap, bit 0~7 corresponds to LP_IO 0~7 - * @param mode 0: Wake the chip when all selected GPIOs go low + * @param mode 0: Wake the chip when any of the selected GPIOs go low * 1: Wake the chip when any of the selected GPIOs go high */ static inline void lp_aon_ll_ext1_set_wakeup_pins(uint32_t mask, int mode) diff --git a/examples/system/deep_sleep/main/Kconfig.projbuild b/examples/system/deep_sleep/main/Kconfig.projbuild index 0c16340f73..281703bcd9 100644 --- a/examples/system/deep_sleep/main/Kconfig.projbuild +++ b/examples/system/deep_sleep/main/Kconfig.projbuild @@ -186,7 +186,6 @@ menu "Example Configuration" choice EXAMPLE_EXT1_WAKEUP_MODE_SEL prompt "Select wakeup mode from EXT1" default ESP_EXT1_WAKEUP_ANY_HIGH - depends on !SOC_PM_SUPPORT_EXT1_MULTI_BIT_TRIGGER config ESP_EXT1_WAKEUP_ANY_LOW bool "GPIO any low level" depends on !IDF_TARGET_ESP32 @@ -199,43 +198,10 @@ menu "Example Configuration" config EXAMPLE_EXT1_WAKEUP_MODE int - depends on !SOC_PM_SUPPORT_EXT1_MULTI_BIT_TRIGGER default 0 if ESP_EXT1_WAKEUP_ANY_LOW default 0 if ESP_EXT1_WAKEUP_ALL_LOW default 1 if ESP_EXT1_WAKEUP_ANY_HIGH - choice EXAMPLE_EXT1_WAKEUP_PIN_1_MODE_SEL - prompt "Select pin_1 wakeup mode from EXT1" - default ESP_EXT1_WAKEUP_PIN_1_HIGH - depends on SOC_PM_SUPPORT_EXT1_MULTI_BIT_TRIGGER - config ESP_EXT1_WAKEUP_PIN_1_LOW - bool "GPIO low level" - config ESP_EXT1_WAKEUP_PIN_1_HIGH - bool "GPIO high level" - endchoice - - config EXAMPLE_EXT1_WAKEUP_MODE_PIN_1 - int - depends on SOC_PM_SUPPORT_EXT1_MULTI_BIT_TRIGGER - default 0 if ESP_EXT1_WAKEUP_PIN_1_LOW - default 1 if ESP_EXT1_WAKEUP_PIN_1_HIGH - - choice EXAMPLE_EXT1_WAKEUP_PIN_2_MODE_SEL - prompt "Select pin_2 wakeup mode from EXT1" - default ESP_EXT1_WAKEUP_PIN_2_HIGH - depends on SOC_PM_SUPPORT_EXT1_MULTI_BIT_TRIGGER - config ESP_EXT1_WAKEUP_PIN_2_LOW - bool "GPIO low level" - config ESP_EXT1_WAKEUP_PIN_2_HIGH - bool "GPIO high level" - endchoice - - config EXAMPLE_EXT1_WAKEUP_MODE_PIN_2 - int - depends on SOC_PM_SUPPORT_EXT1_MULTI_BIT_TRIGGER - default 0 if ESP_EXT1_WAKEUP_PIN_2_LOW - default 1 if ESP_EXT1_WAKEUP_PIN_2_HIGH - config EXAMPLE_EXT1_USE_INTERNAL_PULLUPS bool "Use internal pull-up/downs for EXT1 wakeup source" default n diff --git a/examples/system/deep_sleep/main/ext_wakeup.c b/examples/system/deep_sleep/main/ext_wakeup.c index 3f2590be35..e6cc7ac10a 100644 --- a/examples/system/deep_sleep/main/ext_wakeup.c +++ b/examples/system/deep_sleep/main/ext_wakeup.c @@ -38,12 +38,7 @@ void example_deep_sleep_register_ext1_wakeup(void) const uint64_t ext_wakeup_pin_1_mask = 1ULL << ext_wakeup_pin_1; const uint64_t ext_wakeup_pin_2_mask = 1ULL << ext_wakeup_pin_2; printf("Enabling EXT1 wakeup on pins GPIO%d, GPIO%d\n", ext_wakeup_pin_1, ext_wakeup_pin_2); -#if SOC_PM_SUPPORT_EXT1_MULTI_BIT_TRIGGER const esp_sleep_ext1_wakeup_mode_t ext_wakeup_mode = CONFIG_EXAMPLE_EXT1_WAKEUP_MODE; -#else - const esp_sleep_ext1_wakeup_mode_t ext_wakeup_mode = CONFIG_EXAMPLE_EXT1_WAKEUP_MODE_PIN_1 << ext_wakeup_pin_1 | \ - CONFIG_EXAMPLE_EXT1_WAKEUP_MODE_PIN_2 << ext_wakeup_pin_2; -#endif ESP_ERROR_CHECK(esp_sleep_enable_ext1_wakeup(ext_wakeup_pin_1_mask | ext_wakeup_pin_2_mask, ext_wakeup_mode)); @@ -77,7 +72,7 @@ void example_deep_sleep_register_ext1_wakeup(void) ESP_ERROR_CHECK(gpio_pullup_en(ext_wakeup_pin_2)); } #endif -#endif //CONFIG_EXAMPLE_EXT1_USE_INTERNAL_PULLUPS +#endif // CONFIG_EXAMPLE_EXT1_USE_INTERNAL_PULLUPS } #endif // CONFIG_EXAMPLE_EXT1_WAKEUP