From 65e9d0ddb9307497a4dc5a674bc2424aca7c24f5 Mon Sep 17 00:00:00 2001 From: wuzhenghui Date: Fri, 22 Dec 2023 19:36:24 +0800 Subject: [PATCH] feat(esp_hw_support): add esp32p4 sleep initial support --- components/esp_hw_support/CMakeLists.txt | 1 - .../esp_hw_support/port/esp32p4/pmu_sleep.c | 20 ++++- .../esp_hw_support/port/esp32p4/rtc_clk.c | 11 ++- .../esp_hw_support/port/esp32p4/rtc_time.c | 1 + components/esp_hw_support/sleep_gpio.c | 4 - components/esp_hw_support/sleep_modes.c | 34 +++---- components/esp_pm/linker.lf | 3 +- components/esp_rom/include/esp32p4/rom/rtc.h | 10 +++ .../hal/esp32c6/include/hal/lp_aon_hal.h | 12 +-- .../hal/esp32h2/include/hal/lp_aon_hal.h | 12 +-- components/hal/esp32p4/include/hal/cache_ll.h | 24 ++--- .../hal/esp32p4/include/hal/lp_aon_hal.h | 19 ++++ .../hal/esp32p4/include/hal/lp_sys_ll.h | 89 +++++++++++++++++++ components/hal/include/hal/rtc_hal.h | 17 ++-- 14 files changed, 200 insertions(+), 57 deletions(-) create mode 100644 components/hal/esp32p4/include/hal/lp_aon_hal.h create mode 100644 components/hal/esp32p4/include/hal/lp_sys_ll.h diff --git a/components/esp_hw_support/CMakeLists.txt b/components/esp_hw_support/CMakeLists.txt index 7ac1e9cba1..d4dd3332c7 100644 --- a/components/esp_hw_support/CMakeLists.txt +++ b/components/esp_hw_support/CMakeLists.txt @@ -165,7 +165,6 @@ if(NOT BOOTLOADER_BUILD) if(CONFIG_IDF_TARGET_ESP32P4) list(REMOVE_ITEM srcs "sleep_cpu.c" # TODO: IDF-7528, IDF-7529 - "sleep_modes.c" # TODO: IDF-7528, IDF-7529 "sleep_wake_stub.c" # TODO: IDF-7529 "sleep_gpio.c" # TODO: IDF-7528, IDF-7529 ) diff --git a/components/esp_hw_support/port/esp32p4/pmu_sleep.c b/components/esp_hw_support/port/esp32p4/pmu_sleep.c index c80b6504cc..fb4f4017de 100644 --- a/components/esp_hw_support/port/esp32p4/pmu_sleep.c +++ b/components/esp_hw_support/port/esp32p4/pmu_sleep.c @@ -241,7 +241,16 @@ void pmu_sleep_increase_ldo_volt(void) { void pmu_sleep_shutdown_dcdc(void) { SET_PERI_REG_MASK(LP_SYSTEM_REG_SYS_CTRL_REG, LP_SYSTEM_REG_LP_FIB_DCDC_SWITCH); //0: enable, 1: disable REG_SET_BIT(PMU_DCM_CTRL_REG, PMU_DCDC_OFF_REQ); - REG_SET_FIELD(PMU_HP_ACTIVE_HP_REGULATOR0_REG, PMU_HP_ACTIVE_HP_REGULATOR_DBIAS, 28); // decrease hp_ldo voltage + // Decrease the DCDC voltage to reduce the voltage difference between the DCDC and the LDO to avoid overshooting the DCDC voltage during wake-up. + REG_SET_FIELD(PMU_HP_ACTIVE_BIAS_REG, PMU_HP_ACTIVE_DCM_VSET, 24); + // Decrease hp_ldo voltage. + REG_SET_FIELD(PMU_HP_ACTIVE_HP_REGULATOR0_REG, PMU_HP_ACTIVE_HP_REGULATOR_DBIAS, 24); +} + +void pmu_sleep_enable_dcdc(void) { + CLEAR_PERI_REG_MASK(LP_SYSTEM_REG_SYS_CTRL_REG, LP_SYSTEM_REG_LP_FIB_DCDC_SWITCH); //0: enable, 1: disable + SET_PERI_REG_MASK(PMU_DCM_CTRL_REG, PMU_DCDC_ON_REQ); + REG_SET_FIELD(PMU_HP_ACTIVE_BIAS_REG, PMU_HP_ACTIVE_DCM_VSET, 27); } void pmu_sleep_shutdown_ldo(void) { @@ -274,6 +283,15 @@ TCM_IRAM_ATTR uint32_t pmu_sleep_start(uint32_t wakeup_opt, uint32_t reject_opt, TCM_IRAM_ATTR bool pmu_sleep_finish(void) { + REG_SET_FIELD(PMU_HP_ACTIVE_BIAS_REG, PMU_HP_ACTIVE_DCM_VSET, 27); + if (pmu_ll_hp_is_sleep_reject(PMU_instance()->hal->dev)) { + // If sleep is rejected, the hardware wake-up process that turns on DCDC + // is skipped, and software is used to enable DCDC here. + pmu_sleep_enable_dcdc(); + esp_rom_delay_us(950); + } + pmu_sleep_shutdown_ldo(); + REGI2C_WRITE_MASK(I2C_CPLL, I2C_CPLL_OC_DIV_7_0, 6); // lower default cpu_pll freq to 400M REGI2C_WRITE_MASK(I2C_SYSPLL, I2C_SYSPLL_OC_DIV_7_0, 8); // lower default sys_pll freq to 480M return pmu_ll_hp_is_sleep_reject(PMU_instance()->hal->dev); diff --git a/components/esp_hw_support/port/esp32p4/rtc_clk.c b/components/esp_hw_support/port/esp32p4/rtc_clk.c index 6f214b757f..db3aa3f422 100644 --- a/components/esp_hw_support/port/esp32p4/rtc_clk.c +++ b/components/esp_hw_support/port/esp32p4/rtc_clk.c @@ -234,17 +234,16 @@ static void rtc_clk_cpu_freq_to_cpll_mhz(int cpu_freq_mhz, hal_utils_clk_div_t * abort(); } // Update bit does not control CPU clock sel mux. Therefore, there may be a middle state during the switch (CPU rises) - // We will switch cpu clock source first, and then set the desired dividers. - // It is likely that the hardware will automatically adjust dividers to meet mem_clk, apb_clk freq constraints when - // cpu clock source is set. - // However, the desired dividers will be written into registers anyways afterwards. - // This ensures the final confguration is the desired one. - clk_ll_cpu_set_src(SOC_CPU_CLK_SRC_PLL); + // Since this is upscaling, we need to configure the frequency division coefficient before switching the clock source. + // Otherwise, an intermediate state will occur, in the intermediate state, the frequency of APB/MEM does not meet the + // timing requirements. If there are periperals/CPU access that depend on these two clocks at this moment, some exception + // might occur. clk_ll_cpu_set_divider(div->integer, div->numerator, div->denominator); clk_ll_mem_set_divider(mem_divider); clk_ll_sys_set_divider(sys_divider); clk_ll_apb_set_divider(apb_divider); clk_ll_bus_update(); + clk_ll_cpu_set_src(SOC_CPU_CLK_SRC_PLL); esp_rom_set_cpu_ticks_per_us(cpu_freq_mhz); } diff --git a/components/esp_hw_support/port/esp32p4/rtc_time.c b/components/esp_hw_support/port/esp32p4/rtc_time.c index 591df13a21..7bc3674eb1 100644 --- a/components/esp_hw_support/port/esp32p4/rtc_time.c +++ b/components/esp_hw_support/port/esp32p4/rtc_time.c @@ -143,6 +143,7 @@ uint32_t rtc_clk_cal_internal(rtc_cal_sel_t cal_clk, uint32_t slowclk_cycles) } } CLEAR_PERI_REG_MASK(TIMG_RTCCALICFG_REG(0), TIMG_RTC_CALI_START); + CLEAR_PERI_REG_MASK(HP_SYS_CLKRST_PERI_CLK_CTRL21_REG, HP_SYS_CLKRST_REG_TIMERGRP0_TGRT_CLK_DIV_NUM_M); /* if dig_32k_xtal was originally off and enabled due to calibration, then set back to off state */ if (cal_clk == RTC_CAL_32K_XTAL && !dig_32k_xtal_enabled) { diff --git a/components/esp_hw_support/sleep_gpio.c b/components/esp_hw_support/sleep_gpio.c index d29541f634..1ef17e64c7 100644 --- a/components/esp_hw_support/sleep_gpio.c +++ b/components/esp_hw_support/sleep_gpio.c @@ -22,11 +22,7 @@ #include "hal/rtc_io_hal.h" #include "soc/rtc_io_periph.h" -#if SOC_LP_AON_SUPPORTED -#include "hal/lp_aon_hal.h" -#else #include "hal/rtc_hal.h" -#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 77a556574c..3bed79b431 100644 --- a/components/esp_hw_support/sleep_modes.c +++ b/components/esp_hw_support/sleep_modes.c @@ -30,12 +30,10 @@ #include "esp_private/pm_impl.h" #endif -#if SOC_LP_AON_SUPPORTED -#include "hal/lp_aon_hal.h" -#else +#if !SOC_PMU_SUPPORTED #include "hal/rtc_cntl_ll.h" -#include "hal/rtc_hal.h" #endif +#include "hal/rtc_hal.h" #include "soc/rtc.h" #include "soc/soc_caps.h" @@ -90,6 +88,9 @@ #include "esp32h2/rom/rtc.h" #include "soc/extmem_reg.h" #include "hal/gpio_ll.h" +#elif CONFIG_IDF_TARGET_ESP32P4 +#include "esp32p4/rom/rtc.h" +#include "hal/gpio_ll.h" #endif #if SOC_LP_TIMER_SUPPORTED @@ -138,11 +139,11 @@ #define DEFAULT_SLEEP_OUT_OVERHEAD_US (318) #define DEFAULT_HARDWARE_OUT_OVERHEAD_US (56) #elif CONFIG_IDF_TARGET_ESP32H2 -#define DEFAULT_SLEEP_OUT_OVERHEAD_US (118)// TODO: IDF-6267 +#define DEFAULT_SLEEP_OUT_OVERHEAD_US (118) #define DEFAULT_HARDWARE_OUT_OVERHEAD_US (9) #elif CONFIG_IDF_TARGET_ESP32P4 -#define DEFAULT_SLEEP_OUT_OVERHEAD_US (118)// TODO: IDF-6267 -#define DEFAULT_HARDWARE_OUT_OVERHEAD_US (9) +#define DEFAULT_SLEEP_OUT_OVERHEAD_US (324)// TODO: IDF-7528 +#define DEFAULT_HARDWARE_OUT_OVERHEAD_US (240) #define LDO_POWER_TAKEOVER_PREPARATION_TIME_US (185) #endif @@ -275,7 +276,7 @@ static void touch_wakeup_prepare(void); static void gpio_deep_sleep_wakeup_prepare(void); #endif -#if SOC_RTC_FAST_MEM_SUPPORTED +#if SOC_RTC_FAST_MEM_SUPPORTED && !CONFIG_IDF_TARGET_ESP32P4 // TODO: IDF-7529 #if SOC_PM_SUPPORT_DEEPSLEEP_CHECK_STUB_ONLY static RTC_FAST_ATTR esp_deep_sleep_wake_stub_fn_t wake_stub_fn_handler = NULL; @@ -568,10 +569,12 @@ FORCE_INLINE_ATTR void misc_modules_sleep_prepare(bool deep_sleep) #endif } +#if !CONFIG_IDF_TARGET_ESP32P4 // TODO: IDF-6496 // TODO: IDF-7370 if (!(deep_sleep && s_adc_tsen_enabled)){ sar_periph_ctrl_power_disable(); } +#endif } /** @@ -582,7 +585,11 @@ FORCE_INLINE_ATTR void misc_modules_wake_prepare(void) #if SOC_USB_SERIAL_JTAG_SUPPORTED && !SOC_USB_SERIAL_JTAG_SUPPORT_LIGHT_SLEEP sleep_console_usj_pad_restore(); #endif + +#if !CONFIG_IDF_TARGET_ESP32P4 // TODO: IDF-6496 sar_periph_ctrl_power_enable(); +#endif + #if SOC_PM_SUPPORT_CPU_PD && SOC_PM_CPU_RETENTION_BY_RTCCNTL sleep_disable_cpu_retention(); #endif @@ -822,7 +829,9 @@ static esp_err_t IRAM_ATTR esp_sleep_start(uint32_t pd_flags, esp_sleep_mode_t m #endif #if SOC_PM_SUPPORT_DEEPSLEEP_CHECK_STUB_ONLY +#if !CONFIG_IDF_TARGET_ESP32P4 // TODO: IDF-7529 esp_set_deep_sleep_wake_stub_default_entry(); +#endif // Enter Deep Sleep #if SOC_PMU_SUPPORTED result = call_rtc_sleep_start(reject_triggers, config.power.hp_sys.dig_power.mem_dslp, deep_sleep); @@ -1086,15 +1095,6 @@ static esp_err_t esp_light_sleep_inner(uint32_t pd_flags, esp_rom_delay_us(flash_enable_time_us); } -#if SOC_DCDC_SUPPORTED - uint32_t dcdc_ready_hw_waited_time_us = pmu_sleep_calculate_hp_hw_wait_time(pd_flags, s_config.rtc_clk_cal_period, s_config.fast_clk_cal_period); - uint32_t dcdc_ready_sw_waited_time_us = (esp_cpu_get_cycle_count() - s_config.ccount_ticks_record) / (esp_clk_cpu_freq() / MHZ); - if (dcdc_ready_hw_waited_time_us + dcdc_ready_sw_waited_time_us < DCDC_POWER_STARTUP_TIME_US) { - esp_rom_delay_us(DCDC_POWER_STARTUP_TIME_US - dcdc_ready_hw_waited_time_us - dcdc_ready_sw_waited_time_us); - } - pmu_sleep_shutdown_ldo(); -#endif - #if CONFIG_ESP_SLEEP_CACHE_SAFE_ASSERTION if (pd_flags & RTC_SLEEP_PD_VDDSDIO) { /* Cache Resume 2: flash is ready now, we can resume the cache and access flash safely after */ diff --git a/components/esp_pm/linker.lf b/components/esp_pm/linker.lf index 6930c61995..66493f6852 100644 --- a/components/esp_pm/linker.lf +++ b/components/esp_pm/linker.lf @@ -36,7 +36,8 @@ entries: sleep_system_peripheral:peripheral_domain_pd_allowed (noflash) sleep_modem:modem_domain_pd_allowed (noflash) sleep_modem:periph_inform_out_light_sleep_overhead (noflash) - sar_periph_ctrl:sar_periph_ctrl_power_disable (noflash) + if IDF_TARGET_ESP32P4 = n: # TODO: IDF-6496 + sar_periph_ctrl:sar_periph_ctrl_power_disable (noflash) [mapping:esp_system_pm] archive: libesp_system.a diff --git a/components/esp_rom/include/esp32p4/rom/rtc.h b/components/esp_rom/include/esp32p4/rom/rtc.h index f616bc287d..61baa33304 100644 --- a/components/esp_rom/include/esp32p4/rom/rtc.h +++ b/components/esp_rom/include/esp32p4/rom/rtc.h @@ -64,6 +64,16 @@ extern "C" { #define RTC_DISABLE_ROM_LOG ((1 << 0) | (1 << 16)) //!< Disable logging from the ROM code. +/* + * Use LP_SYS_LP_STORE8_REG to store light sleep wake stub addr and sleep mode + * + * bit[31: 2] Wake restore func addr + * bit[0]: + * 0 -- light sleep + * 1 -- deep sleep + */ +#define SLEEP_MODE_REG LP_SYSTEM_REG_LP_STORE8_REG + typedef enum { AWAKE = 0, //freeze_l1_icache0_enable(CACHE_FREEZE_ACK_BUSY); } else if (cache_id == 1) { - Cache_Freeze_L1_ICache1_Enable(CACHE_FREEZE_ACK_BUSY); + rom_cache_internal_table_ptr->freeze_l1_icache1_enable(CACHE_FREEZE_ACK_BUSY); } else if (cache_id == CACHE_LL_ID_ALL) { - Cache_Freeze_L1_ICache0_Enable(CACHE_FREEZE_ACK_BUSY); - Cache_Freeze_L1_ICache1_Enable(CACHE_FREEZE_ACK_BUSY); + rom_cache_internal_table_ptr->freeze_l1_icache0_enable(CACHE_FREEZE_ACK_BUSY); + rom_cache_internal_table_ptr->freeze_l1_icache1_enable(CACHE_FREEZE_ACK_BUSY); } } @@ -696,7 +696,7 @@ __attribute__((always_inline)) static inline void cache_ll_l1_freeze_dcache(uint32_t cache_id) { if (cache_id == 0 || cache_id == CACHE_LL_ID_ALL) { - Cache_Freeze_L1_DCache_Enable(CACHE_FREEZE_ACK_BUSY); + rom_cache_internal_table_ptr->freeze_l1_dcache_enable(CACHE_FREEZE_ACK_BUSY); } } @@ -709,7 +709,7 @@ __attribute__((always_inline)) static inline void cache_ll_l2_freeze_cache(uint32_t cache_id) { if (cache_id == 0 || cache_id == CACHE_LL_ID_ALL) { - Cache_Freeze_L2_Cache_Enable(CACHE_FREEZE_ACK_BUSY); + rom_cache_internal_table_ptr->freeze_l2_cache_enable(CACHE_FREEZE_ACK_BUSY); } } @@ -755,12 +755,12 @@ __attribute__((always_inline)) static inline void cache_ll_l1_unfreeze_icache(uint32_t cache_id) { if (cache_id == 0) { - Cache_Freeze_L1_ICache0_Disable(); + rom_cache_internal_table_ptr->freeze_l1_icache0_disable(); } else if (cache_id == 1) { - Cache_Freeze_L1_ICache1_Disable(); + rom_cache_internal_table_ptr->freeze_l1_icache1_disable(); } else if (cache_id == CACHE_LL_ID_ALL) { - Cache_Freeze_L1_ICache1_Disable(); - Cache_Freeze_L1_ICache0_Disable(); + rom_cache_internal_table_ptr->freeze_l1_icache1_disable(); + rom_cache_internal_table_ptr->freeze_l1_icache0_disable(); } } @@ -773,7 +773,7 @@ __attribute__((always_inline)) static inline void cache_ll_l1_unfreeze_dcache(uint32_t cache_id) { if (cache_id == 0 || cache_id == CACHE_LL_ID_ALL) { - Cache_Freeze_L1_DCache_Disable(); + rom_cache_internal_table_ptr->freeze_l1_dcache_disable(); } } @@ -786,7 +786,7 @@ __attribute__((always_inline)) static inline void cache_ll_l2_unfreeze_cache(uint32_t cache_id) { if (cache_id == 0 || cache_id == CACHE_LL_ID_ALL) { - Cache_Freeze_L2_Cache_Disable(); + rom_cache_internal_table_ptr->freeze_l2_cache_disable(); } } diff --git a/components/hal/esp32p4/include/hal/lp_aon_hal.h b/components/hal/esp32p4/include/hal/lp_aon_hal.h new file mode 100644 index 0000000000..31d7c57485 --- /dev/null +++ b/components/hal/esp32p4/include/hal/lp_aon_hal.h @@ -0,0 +1,19 @@ +/* + * SPDX-FileCopyrightText: 2020-2023 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#pragma once + +#include "hal/lp_sys_ll.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#define lp_aon_hal_inform_wakeup_type(dslp) lp_sys_ll_inform_wakeup_type(dslp) + +#ifdef __cplusplus +} +#endif diff --git a/components/hal/esp32p4/include/hal/lp_sys_ll.h b/components/hal/esp32p4/include/hal/lp_sys_ll.h new file mode 100644 index 0000000000..875fb22116 --- /dev/null +++ b/components/hal/esp32p4/include/hal/lp_sys_ll.h @@ -0,0 +1,89 @@ +/* + * SPDX-FileCopyrightText: 2023 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +// The LL layer for ESP32-C6 LP_SYS register operations + +#pragma once + +#include +#include "soc/soc.h" +#include "soc/lp_system_struct.h" +#include "hal/misc.h" +#include "esp32p4/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_sys_ll_ext1_get_wakeup_status(void) +{ + // TODO: IDF-7529 + return 0; +} + +/** + * @brief Clear the ext1 wakeup source status + */ +static inline void lp_sys_ll_ext1_clear_wakeup_status(void) +{ + // TODO: IDF-7529 +} + +/** + * @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_sys_ll_ext1_set_wakeup_pins(uint32_t mask, int mode) +{ + // TODO: IDF-7529 +} + +/** + * @brief Clear all ext1 wakup-source setting + */ +static inline void lp_sys_ll_ext1_clear_wakeup_pins(void) +{ + // TODO: IDF-7529 +} + +/** + * @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_sys_ll_ext1_get_wakeup_pins(void) +{ + // TODO: IDF-7529 + return 0; +} + + +/** + * @brief ROM obtains the wake-up type through LP_SYS_STORE9_REG[0]. + * Set the flag to inform + * @param true: deepsleep false: lightsleep + */ +static inline void lp_sys_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/hal/include/hal/rtc_hal.h b/components/hal/include/hal/rtc_hal.h index dec7912554..cf6c882770 100644 --- a/components/hal/include/hal/rtc_hal.h +++ b/components/hal/include/hal/rtc_hal.h @@ -20,6 +20,10 @@ #include "hal/rtc_io_ll.h" #endif +#if SOC_LP_AON_SUPPORTED +#include "hal/lp_aon_ll.h" +#endif + #ifdef __cplusplus extern "C" { #endif @@ -51,16 +55,19 @@ typedef struct rtc_cntl_sleep_retent { #if SOC_PM_SUPPORT_EXT1_WAKEUP +#if SOC_LP_AON_SUPPORTED +#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(io_mask, mode_mask) lp_aon_ll_ext1_set_wakeup_pins(io_mask, mode_mask) +#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() +#else #define rtc_hal_ext1_get_wakeup_status() rtc_cntl_ll_ext1_get_wakeup_status() - #define rtc_hal_ext1_clear_wakeup_status() rtc_cntl_ll_ext1_clear_wakeup_status() - #define rtc_hal_ext1_set_wakeup_pins(io_mask, mode_mask) rtc_cntl_ll_ext1_set_wakeup_pins(io_mask, mode_mask) - #define rtc_hal_ext1_clear_wakeup_pins() rtc_cntl_ll_ext1_clear_wakeup_pins() - #define rtc_hal_ext1_get_wakeup_pins() rtc_cntl_ll_ext1_get_wakeup_pins() - +#endif #endif // SOC_PM_SUPPORT_EXT1_WAKEUP #if SOC_GPIO_SUPPORT_DEEPSLEEP_WAKEUP && (SOC_RTCIO_PIN_COUNT == 0)