diff --git a/components/driver/Kconfig b/components/driver/Kconfig index e3bf6a86f9..1f9632b5e2 100644 --- a/components/driver/Kconfig +++ b/components/driver/Kconfig @@ -114,4 +114,18 @@ menu "Driver configurations" endmenu # RTCIO Configuration + menu "GPIO Configuration" + visible if IDF_TARGET_ESP32 + + config GPIO_ESP32_SUPPORT_SWITCH_SLP_PULL + bool "Support light sleep GPIO pullup/pulldown configuration for ESP32" + depends on IDF_TARGET_ESP32 + help + This option is intended to fix the bug that ESP32 is not able to switch to configured + pullup/pulldown mode in sleep. + If this option is selected, chip will automatically emulate the behaviour of switching, + and about 450B of source codes would be placed into IRAM. + + endmenu # GPIO Configuration + endmenu # Driver configurations diff --git a/components/driver/gpio.c b/components/driver/gpio.c index f8cbcae1ba..e9e711989b 100644 --- a/components/driver/gpio.c +++ b/components/driver/gpio.c @@ -704,3 +704,177 @@ void gpio_iomux_out(uint8_t gpio_num, int func, bool oen_inv) { gpio_hal_iomux_out(gpio_context.gpio_hal, gpio_num, func, (uint32_t)oen_inv); } + +#if SOC_GPIO_SUPPORT_SLP_SWITCH +static esp_err_t gpio_sleep_pullup_en(gpio_num_t gpio_num) +{ + GPIO_CHECK(GPIO_IS_VALID_GPIO(gpio_num), "GPIO number error", ESP_ERR_INVALID_ARG); + + portENTER_CRITICAL(&gpio_context.gpio_spinlock); + gpio_hal_sleep_pullup_en(gpio_context.gpio_hal, gpio_num); + portEXIT_CRITICAL(&gpio_context.gpio_spinlock); + + return ESP_OK; +} + +static esp_err_t gpio_sleep_pullup_dis(gpio_num_t gpio_num) +{ + GPIO_CHECK(GPIO_IS_VALID_GPIO(gpio_num), "GPIO number error", ESP_ERR_INVALID_ARG); + + portENTER_CRITICAL(&gpio_context.gpio_spinlock); + gpio_hal_sleep_pullup_dis(gpio_context.gpio_hal, gpio_num); + portEXIT_CRITICAL(&gpio_context.gpio_spinlock); + + return ESP_OK; +} + +static esp_err_t gpio_sleep_pulldown_en(gpio_num_t gpio_num) +{ + GPIO_CHECK(GPIO_IS_VALID_GPIO(gpio_num), "GPIO number error", ESP_ERR_INVALID_ARG); + + portENTER_CRITICAL(&gpio_context.gpio_spinlock); + gpio_hal_sleep_pulldown_en(gpio_context.gpio_hal, gpio_num); + portEXIT_CRITICAL(&gpio_context.gpio_spinlock); + + return ESP_OK; +} + +static esp_err_t gpio_sleep_pulldown_dis(gpio_num_t gpio_num) +{ + GPIO_CHECK(GPIO_IS_VALID_GPIO(gpio_num), "GPIO number error", ESP_ERR_INVALID_ARG); + + portENTER_CRITICAL(&gpio_context.gpio_spinlock); + gpio_hal_sleep_pulldown_dis(gpio_context.gpio_hal, gpio_num); + portEXIT_CRITICAL(&gpio_context.gpio_spinlock); + + return ESP_OK; +} + +static esp_err_t gpio_sleep_input_disable(gpio_num_t gpio_num) +{ + GPIO_CHECK(GPIO_IS_VALID_GPIO(gpio_num), "GPIO number error", ESP_ERR_INVALID_ARG); + gpio_hal_sleep_input_disable(gpio_context.gpio_hal, gpio_num); + return ESP_OK; +} + +static esp_err_t gpio_sleep_input_enable(gpio_num_t gpio_num) +{ + GPIO_CHECK(GPIO_IS_VALID_GPIO(gpio_num), "GPIO number error", ESP_ERR_INVALID_ARG); + gpio_hal_sleep_input_enable(gpio_context.gpio_hal, gpio_num); + return ESP_OK; +} + +static esp_err_t gpio_sleep_output_disable(gpio_num_t gpio_num) +{ + GPIO_CHECK(GPIO_IS_VALID_GPIO(gpio_num), "GPIO number error", ESP_ERR_INVALID_ARG); + gpio_hal_sleep_output_disable(gpio_context.gpio_hal, gpio_num); + return ESP_OK; +} + +static esp_err_t gpio_sleep_output_enable(gpio_num_t gpio_num) +{ + GPIO_CHECK(GPIO_IS_VALID_OUTPUT_GPIO(gpio_num), "GPIO output gpio_num error", ESP_ERR_INVALID_ARG); + gpio_hal_sleep_output_enable(gpio_context.gpio_hal, gpio_num); + return ESP_OK; +} + +esp_err_t gpio_sleep_set_direction(gpio_num_t gpio_num, gpio_mode_t mode) +{ + GPIO_CHECK(GPIO_IS_VALID_GPIO(gpio_num), "GPIO number error", ESP_ERR_INVALID_ARG); + + if ((GPIO_IS_VALID_OUTPUT_GPIO(gpio_num) != true) && (mode & GPIO_MODE_DEF_OUTPUT)) { + ESP_LOGE(GPIO_TAG, "io_num=%d can only be input", gpio_num); + return ESP_ERR_INVALID_ARG; + } + + esp_err_t ret = ESP_OK; + + if (mode & GPIO_MODE_DEF_INPUT) { + gpio_sleep_input_enable(gpio_num); + } else { + gpio_sleep_input_disable(gpio_num); + } + + if (mode & GPIO_MODE_DEF_OUTPUT) { + gpio_sleep_output_enable(gpio_num); + } else { + gpio_sleep_output_disable(gpio_num); + } + + return ret; +} + +esp_err_t gpio_sleep_set_pull_mode(gpio_num_t gpio_num, gpio_pull_mode_t pull) +{ + GPIO_CHECK(GPIO_IS_VALID_GPIO(gpio_num), "GPIO number error", ESP_ERR_INVALID_ARG); + GPIO_CHECK(pull <= GPIO_FLOATING, "GPIO pull mode error", ESP_ERR_INVALID_ARG); + esp_err_t ret = ESP_OK; + + switch (pull) { + case GPIO_PULLUP_ONLY: + gpio_sleep_pulldown_dis(gpio_num); + gpio_sleep_pullup_en(gpio_num); + break; + + case GPIO_PULLDOWN_ONLY: + gpio_sleep_pulldown_en(gpio_num); + gpio_sleep_pullup_dis(gpio_num); + break; + + case GPIO_PULLUP_PULLDOWN: + gpio_sleep_pulldown_en(gpio_num); + gpio_sleep_pullup_en(gpio_num); + break; + + case GPIO_FLOATING: + gpio_sleep_pulldown_dis(gpio_num); + gpio_sleep_pullup_dis(gpio_num); + break; + + default: + ESP_LOGE(GPIO_TAG, "Unknown pull up/down mode,gpio_num=%u,pull=%u", gpio_num, pull); + ret = ESP_ERR_INVALID_ARG; + break; + } + + return ret; +} + +esp_err_t gpio_sleep_sel_en(gpio_num_t gpio_num) +{ + GPIO_CHECK(GPIO_IS_VALID_GPIO(gpio_num), "GPIO number error", ESP_ERR_INVALID_ARG); + + portENTER_CRITICAL(&gpio_context.gpio_spinlock); + gpio_hal_sleep_sel_en(gpio_context.gpio_hal, gpio_num); + portEXIT_CRITICAL(&gpio_context.gpio_spinlock); + + return ESP_OK; +} + +esp_err_t gpio_sleep_sel_dis(gpio_num_t gpio_num) +{ + GPIO_CHECK(GPIO_IS_VALID_GPIO(gpio_num), "GPIO number error", ESP_ERR_INVALID_ARG); + + portENTER_CRITICAL(&gpio_context.gpio_spinlock); + gpio_hal_sleep_sel_dis(gpio_context.gpio_hal, gpio_num); + portEXIT_CRITICAL(&gpio_context.gpio_spinlock); + + return ESP_OK; +} + +#if CONFIG_GPIO_ESP32_SUPPORT_SWITCH_SLP_PULL +esp_err_t gpio_sleep_pupd_config_apply(gpio_num_t gpio_num) +{ + GPIO_CHECK(GPIO_IS_VALID_GPIO(gpio_num), "GPIO number error", ESP_ERR_INVALID_ARG); + gpio_hal_sleep_pupd_config_apply(gpio_context.gpio_hal, gpio_num); + return ESP_OK; +} + +esp_err_t gpio_sleep_pupd_config_unapply(gpio_num_t gpio_num) +{ + GPIO_CHECK(GPIO_IS_VALID_GPIO(gpio_num), "GPIO number error", ESP_ERR_INVALID_ARG); + gpio_hal_sleep_pupd_config_unapply(gpio_context.gpio_hal, gpio_num); + return ESP_OK; +} +#endif +#endif diff --git a/components/driver/include/driver/gpio.h b/components/driver/include/driver/gpio.h index 333f75ddbc..d9fe4289f0 100644 --- a/components/driver/include/driver/gpio.h +++ b/components/driver/include/driver/gpio.h @@ -445,6 +445,82 @@ esp_err_t gpio_force_hold_all(void); esp_err_t gpio_force_unhold_all(void); #endif +#if SOC_GPIO_SUPPORT_SLP_SWITCH +/** + * @brief Enable SLP_SEL to change GPIO status automantically in lightsleep. + * @param gpio_num GPIO number of the pad. + * + * @return + * - ESP_OK Success + * + */ +esp_err_t gpio_sleep_sel_en(gpio_num_t gpio_num); + +/** + * @brief Disable SLP_SEL to change GPIO status automantically in lightsleep. + * @param gpio_num GPIO number of the pad. + * + * @return + * - ESP_OK Success + * + */ +esp_err_t gpio_sleep_sel_dis(gpio_num_t gpio_num); + +/** + * @brief GPIO set direction at sleep + * + * Configure GPIO direction,such as output_only,input_only,output_and_input + * + * @param gpio_num Configure GPIO pins number, it should be GPIO number. If you want to set direction of e.g. GPIO16, gpio_num should be GPIO_NUM_16 (16); + * @param mode GPIO direction + * + * @return + * - ESP_OK Success + * - ESP_ERR_INVALID_ARG GPIO error + * + */ +esp_err_t gpio_sleep_set_direction(gpio_num_t gpio_num, gpio_mode_t mode); + +/** + * @brief Configure GPIO pull-up/pull-down resistors at sleep + * + * Only pins that support both input & output have integrated pull-up and pull-down resistors. Input-only GPIOs 34-39 do not. + * + * @param gpio_num GPIO number. If you want to set pull up or down mode for e.g. GPIO16, gpio_num should be GPIO_NUM_16 (16); + * @param pull GPIO pull up/down mode. + * + * @return + * - ESP_OK Success + * - ESP_ERR_INVALID_ARG : Parameter error + * + */ +esp_err_t gpio_sleep_set_pull_mode(gpio_num_t gpio_num, gpio_pull_mode_t pull); + +#if CONFIG_GPIO_ESP32_SUPPORT_SWITCH_SLP_PULL +/** + * @brief Emulate ESP32S2 behaviour to backup FUN_PU, FUN_PD information + * + * @note Need to be called before sleep. + * + * @return + * - ESP_OK Success + * + * */ +esp_err_t gpio_sleep_pupd_config_apply(gpio_num_t gpio_num); + +/** + * @brief Emulate ESP32S2 behaviour to restore FUN_PU, FUN_PD information + * + * @note Need to be called after sleep. + * + * @return + * - ESP_OK Success + * + * */ +esp_err_t gpio_sleep_pupd_config_unapply(gpio_num_t gpio_num); +#endif +#endif + #ifdef __cplusplus } #endif diff --git a/components/esp_pm/Kconfig b/components/esp_pm/Kconfig index e066022621..1ce8e6af4f 100644 --- a/components/esp_pm/Kconfig +++ b/components/esp_pm/Kconfig @@ -77,4 +77,17 @@ menu "Power Management" This feature is intended to be used when lower power consumption is needed while there is enough place in IRAM to place source code. + config PM_SLP_DISABLE_GPIO + bool "Disable all GPIO when chip at sleep" + depends on FREERTOS_USE_TICKLESS_IDLE + help + This feature is intended to disable all GPIO pins at automantic sleep to get a lower power mode. + If enabled, chips will disable all GPIO pins at automantic sleep to reduce about 200~300 uA current. + If you want to specifically use some pins normally as chip wakes when chip sleeps, + you can call 'gpio_sleep_sel_dis' to disable this feature on those pins. + You can also keep this feature on and call 'gpio_sleep_set_direction' and 'gpio_sleep_set_pull_mode' + to have a different GPIO configuration at sleep. + Waring: If you want to enable this option on ESP32, you should enable `GPIO_ESP32_SUPPORT_SWITCH_SLP_PULL` + at first, otherwise you will not be able to switch pullup/pulldown mode. + endmenu # "Power Management" diff --git a/components/esp_pm/linker.lf b/components/esp_pm/linker.lf index 6de8b2b302..e076a516c6 100644 --- a/components/esp_pm/linker.lf +++ b/components/esp_pm/linker.lf @@ -51,3 +51,22 @@ entries: esp_time_impl:esp_rtc_get_time_us (noflash) esp_time_impl:esp_clk_slowclk_cal_set (noflash) esp_time_impl:esp_set_time_from_rtc (noflash) + +[mapping:driver_pm] +archive: libdriver.a +entries: + if GPIO_ESP32_SUPPORT_SWITCH_SLP_PULL = y: + gpio:gpio_sleep_pupd_config_unapply (noflash) + if PM_SLP_IRAM_OPT = y: + gpio:gpio_sleep_pupd_config_apply (noflash) + +[mapping:hal_pm] +archive: libhal.a +entries: + if GPIO_ESP32_SUPPORT_SWITCH_SLP_PULL = y: + if PM_SLP_IRAM_OPT = y: + gpio_hal_workaround (noflash) + else: + gpio_hal_workaround:gpio_hal_sleep_pupd_config_unapply (noflash) + gpio_hal_workaround:gpio_hal_sleep_mode_setup_wrapper (noflash) + gpio_hal_workaround:gpio_hal_fun_pupd_restore (noflash) diff --git a/components/esp_pm/pm_impl.c b/components/esp_pm/pm_impl.c index 93a3786109..a7f764fc14 100644 --- a/components/esp_pm/pm_impl.c +++ b/components/esp_pm/pm_impl.c @@ -46,9 +46,11 @@ #if CONFIG_IDF_TARGET_ESP32 #include "esp32/clk.h" #include "esp32/pm.h" +#include "driver/gpio.h" #elif CONFIG_IDF_TARGET_ESP32S2 #include "esp32s2/clk.h" #include "esp32s2/pm.h" +#include "driver/gpio.h" #elif CONFIG_IDF_TARGET_ESP32S3 #include "esp32s3/clk.h" #include "esp32s3/pm.h" @@ -283,6 +285,10 @@ esp_err_t esp_pm_configure(const void* vconfig) s_config_changed = true; portEXIT_CRITICAL(&s_switch_lock); +#if CONFIG_PM_SLP_DISABLE_GPIO && SOC_GPIO_SUPPORT_SLP_SWITCH + esp_sleep_gpio_status_switch_configure(config->light_sleep_enable); +#endif + return ESP_OK; } @@ -697,6 +703,9 @@ void esp_pm_impl_init(void) esp_pm_trace_init(); #endif +#if CONFIG_PM_SLP_DISABLE_GPIO && SOC_GPIO_SUPPORT_SLP_SWITCH + esp_sleep_gpio_status_init(); +#endif ESP_ERROR_CHECK(esp_pm_lock_create(ESP_PM_CPU_FREQ_MAX, 0, "rtos0", &s_rtos_lock_handle[0])); ESP_ERROR_CHECK(esp_pm_lock_acquire(s_rtos_lock_handle[0])); diff --git a/components/esp_system/include/esp_sleep.h b/components/esp_system/include/esp_sleep.h index 5b90614cc3..423bee51a1 100644 --- a/components/esp_system/include/esp_sleep.h +++ b/components/esp_system/include/esp_sleep.h @@ -20,6 +20,8 @@ #include "hal/touch_sensor_types.h" #include "hal/gpio_types.h" +#include "soc/soc_caps.h" + #ifdef __cplusplus extern "C" { #endif @@ -382,6 +384,19 @@ void esp_default_wake_deep_sleep(void); */ void esp_deep_sleep_disable_rom_logging(void); +#if SOC_GPIO_SUPPORT_SLP_SWITCH +/** + * @brief Disable all GPIO pins at slept status. + * + */ +void esp_sleep_gpio_status_init(void); + +/** + * @brief Configure GPIO pins status switching between slept status and waked status. + * @param enable decide whether to switch status or not + */ +void esp_sleep_gpio_status_switch_configure(bool enable); +#endif #ifdef __cplusplus } #endif diff --git a/components/esp_system/sleep_modes.c b/components/esp_system/sleep_modes.c index 1a9d75a044..267caaa277 100644 --- a/components/esp_system/sleep_modes.c +++ b/components/esp_system/sleep_modes.c @@ -53,11 +53,13 @@ #include "esp32/rom/cache.h" #include "esp32/clk.h" #include "esp32/rom/rtc.h" +#include "driver/gpio.h" #elif CONFIG_IDF_TARGET_ESP32S2 #include "esp32s2/clk.h" #include "esp32s2/rom/cache.h" #include "esp32s2/rom/rtc.h" #include "soc/extmem_reg.h" +#include "driver/gpio.h" #elif CONFIG_IDF_TARGET_ESP32S3 #include "esp32s3/clk.h" #include "esp32s3/rom/cache.h" @@ -273,6 +275,58 @@ static void IRAM_ATTR resume_uarts(void) inline static uint32_t IRAM_ATTR call_rtc_sleep_start(uint32_t reject_triggers); +#if SOC_GPIO_SUPPORT_SLP_SWITCH +#if CONFIG_GPIO_ESP32_SUPPORT_SWITCH_SLP_PULL +static inline void gpio_sleep_mode_config_apply(void) +{ + for (gpio_num_t gpio_num = GPIO_NUM_0; gpio_num < GPIO_NUM_MAX; gpio_num++) { + if (GPIO_IS_VALID_GPIO(gpio_num)) { + gpio_sleep_pupd_config_apply(gpio_num); + } + } +} + +static inline void gpio_sleep_mode_config_unapply(void) +{ + for (gpio_num_t gpio_num = GPIO_NUM_0; gpio_num < GPIO_NUM_MAX; gpio_num++) { + if (GPIO_IS_VALID_GPIO(gpio_num)) { + gpio_sleep_pupd_config_unapply(gpio_num); + } + } +} +#endif + +void esp_sleep_gpio_status_init(void) +{ + ESP_LOGI(TAG, "Init to disable all pins at light sleep"); + for (gpio_num_t gpio_num = GPIO_NUM_0; gpio_num < GPIO_NUM_MAX; gpio_num++) { + if (GPIO_IS_VALID_GPIO(gpio_num)) { + gpio_sleep_set_direction(gpio_num, GPIO_MODE_DISABLE); + gpio_sleep_set_pull_mode(gpio_num, GPIO_FLOATING); + } + } +} + +void esp_sleep_gpio_status_switch_configure(bool enable) +{ + if (enable) { + ESP_LOGI(TAG, "Light sleep enabled, start GPIO status switching"); + } else { + ESP_LOGI(TAG, "Light sleep disabled, stop GPIO status switching"); + } + for (gpio_num_t gpio_num = GPIO_NUM_0; gpio_num < GPIO_NUM_MAX; gpio_num++) { + if (GPIO_IS_VALID_GPIO(gpio_num)) { + if (enable) { + gpio_sleep_sel_en(gpio_num); + } else { + gpio_sleep_sel_dis(gpio_num); + } + } + } +} + +#endif + static uint32_t IRAM_ATTR esp_sleep_start(uint32_t pd_flags) { // Stop UART output so that output is not lost due to APB frequency change. @@ -313,6 +367,9 @@ static uint32_t IRAM_ATTR esp_sleep_start(uint32_t pd_flags) if (s_config.wakeup_triggers & RTC_ULP_TRIG_EN) { rtc_hal_ulp_wakeup_enable(); } +#if CONFIG_GPIO_ESP32_SUPPORT_SWITCH_SLP_PULL + gpio_sleep_mode_config_apply(); +#endif #endif #if CONFIG_IDF_TARGET_ESP32S2 || CONFIG_IDF_TARGET_ESP32S3 @@ -391,6 +448,9 @@ static uint32_t IRAM_ATTR esp_sleep_start(uint32_t pd_flags) s_config.ccount_ticks_record = cpu_ll_get_cycle_count(); } +#if CONFIG_GPIO_ESP32_SUPPORT_SWITCH_SLP_PULL + gpio_sleep_mode_config_unapply(); +#endif // re-enable UART output resume_uarts(); diff --git a/components/hal/CMakeLists.txt b/components/hal/CMakeLists.txt index 90cd9bda25..28e0bc3213 100644 --- a/components/hal/CMakeLists.txt +++ b/components/hal/CMakeLists.txt @@ -43,7 +43,8 @@ if(NOT BOOTLOADER_BUILD) "esp32/adc_hal.c" "esp32/brownout_hal.c" "esp32/interrupt_descriptor_table.c" - "esp32/touch_sensor_hal.c") + "esp32/touch_sensor_hal.c" + "esp32/gpio_hal_workaround.c") if(NOT BOOTLOADER_BUILD AND CONFIG_ETH_USE_ESP32_EMAC) list(APPEND srcs "esp32/emac_hal.c") endif() diff --git a/components/hal/esp32/gpio_hal_workaround.c b/components/hal/esp32/gpio_hal_workaround.c new file mode 100644 index 0000000000..65eb5fc574 --- /dev/null +++ b/components/hal/esp32/gpio_hal_workaround.c @@ -0,0 +1,119 @@ +// Copyright 2015-2019 Espressif Systems (Shanghai) PTE LTD +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +// The HAL layer for GPIO (common part) +// +#include "esp_attr.h" +#include "soc/soc.h" +#include "hal/gpio_hal.h" +#include "soc/soc_caps.h" + +#if CONFIG_GPIO_ESP32_SUPPORT_SWITCH_SLP_PULL +typedef struct gpio_slp_mode_cfg { + volatile uint16_t fun_pu[((SOC_GPIO_PIN_COUNT-1) >> 4) + 1]; + volatile uint16_t fun_pd[((SOC_GPIO_PIN_COUNT-1) >> 4) + 1]; +} gpio_slp_mode_cfg_t; + +static void gpio_hal_sleep_mode_setup_wrapper( + gpio_hal_context_t *hal, + gpio_num_t gpio_num, + void (*opt)(gpio_hal_context_t *, gpio_num_t, void *) + ) +{ + static DRAM_ATTR gpio_slp_mode_cfg_t gpio_cfg; + if (opt) { + (*opt)(hal, gpio_num, (void *)&gpio_cfg); + } +} + +/** + * @brief GPIO pu/pd information backup function + * @param hal gpio hal + * @param gpio_num gpio num + * @param args pointer for bitmap to backup GPIO pu/pd information + */ +static void gpio_hal_fun_pupd_backup(gpio_hal_context_t *hal, gpio_num_t gpio_num, void *args) +{ + /* On ESP32, setting SLP_PU, SLP_PD couldn`t change GPIO status + * from FUN_PU, FUN_PD to SLP_PU, SLP_PD at sleep. + * On the ESP32S2, it does. + * The following code emulates ESP32S2`s behavior: + */ + gpio_slp_mode_cfg_t *pcfg = (gpio_slp_mode_cfg_t *)args; + + if (gpio_ll_sleep_sel_is_enabled(hal->dev, gpio_num)) { + /* Record fun_pu and fun_pd state in bitmap */ + if (gpio_ll_pullup_is_enabled(hal->dev, gpio_num)) { + pcfg->fun_pu[gpio_num >> 4] |= BIT(gpio_num & 0xf); + } else { + pcfg->fun_pu[gpio_num >> 4] &= ~BIT(gpio_num & 0xf); + } + if (gpio_ll_pulldown_is_enabled(hal->dev, gpio_num)) { + pcfg->fun_pd[gpio_num >> 4] |= BIT(gpio_num & 0xf); + } else { + pcfg->fun_pd[gpio_num >> 4] &= ~BIT(gpio_num & 0xf); + } + + if (gpio_ll_sleep_pullup_is_enabled(hal->dev, gpio_num)) { + gpio_ll_pullup_en(hal->dev, gpio_num); + } else { + gpio_ll_pullup_dis(hal->dev, gpio_num); + } + if (gpio_ll_sleep_pulldown_is_enabled(hal->dev, gpio_num)) { + gpio_ll_pulldown_en(hal->dev, gpio_num); + } else { + gpio_ll_pulldown_dis(hal->dev, gpio_num); + } + } +} + +/** + * @brief GPIO pu/pd information backup function + * @param hal gpio hal + * @param gpio_num gpio num + * @param args pointer for bitmap to restore GPIO pu/pd information + */ +static void gpio_hal_fun_pupd_restore(gpio_hal_context_t *hal, gpio_num_t gpio_num, void *args) +{ + /* On ESP32, setting SLP_PU, SLP_PD couldn`t change GPIO status + * from SLP_PU, SLP_PD to FUN_PU, FUN_PD when it wakes up. + * On the ESP32S2, it does. + * The following code emulates ESP32S2`s behavior: + */ + gpio_slp_mode_cfg_t *pcfg = (gpio_slp_mode_cfg_t *)args; + + if (gpio_ll_sleep_sel_is_enabled(hal->dev, gpio_num)) { + if (pcfg->fun_pu[gpio_num >> 4] & BIT(gpio_num & 0xf)) { + gpio_ll_pullup_en(hal->dev, gpio_num); + } else { + gpio_ll_pullup_dis(hal->dev, gpio_num); + } + if (pcfg->fun_pd[gpio_num >> 4] & BIT(gpio_num & 0xf)) { + gpio_ll_pulldown_en(hal->dev, gpio_num); + } else { + gpio_ll_pulldown_dis(hal->dev, gpio_num); + } + } +} + +void gpio_hal_sleep_pupd_config_apply(gpio_hal_context_t *hal, gpio_num_t gpio_num) +{ + gpio_hal_sleep_mode_setup_wrapper(hal, gpio_num, gpio_hal_fun_pupd_backup); +} + +void gpio_hal_sleep_pupd_config_unapply(gpio_hal_context_t *hal, gpio_num_t gpio_num) +{ + gpio_hal_sleep_mode_setup_wrapper(hal, gpio_num, gpio_hal_fun_pupd_restore); +} +#endif diff --git a/components/hal/esp32/include/hal/gpio_ll.h b/components/hal/esp32/include/hal/gpio_ll.h index 2d3c510bbe..a421cab413 100644 --- a/components/hal/esp32/include/hal/gpio_ll.h +++ b/components/hal/esp32/include/hal/gpio_ll.h @@ -22,6 +22,7 @@ #pragma once +#include #include "soc/soc.h" #include "soc/gpio_periph.h" #include "soc/rtc_cntl_reg.h" @@ -63,6 +64,18 @@ static inline void gpio_ll_pullup_dis(gpio_dev_t *hw, gpio_num_t gpio_num) REG_CLR_BIT(GPIO_PIN_MUX_REG[gpio_num], FUN_PU); } +/** + * @brief Return pull-up status on GPIO. + * + * @param hw Peripheral GPIO hardware instance address. + * @param gpio_num GPIO number + * @return if GPIO gpio_num`s FUN_PU is true + */ +static inline bool gpio_ll_pullup_is_enabled(gpio_dev_t *hw, gpio_num_t gpio_num) +{ + return REG_GET_BIT(GPIO_PIN_MUX_REG[gpio_num], FUN_PU) ? true : false; +} + /** * @brief Enable pull-down on GPIO. * @@ -85,6 +98,120 @@ static inline void gpio_ll_pulldown_dis(gpio_dev_t *hw, gpio_num_t gpio_num) REG_CLR_BIT(GPIO_PIN_MUX_REG[gpio_num], FUN_PD); } +/** + * @brief Return pull-down status on GPIO. + * + * @param hw Peripheral GPIO hardware instance address. + * @param gpio_num GPIO number + * @return if GPIO gpio_num`s FUN_PD is true + */ +static inline bool gpio_ll_pulldown_is_enabled(gpio_dev_t *hw, gpio_num_t gpio_num) +{ + return REG_GET_BIT(GPIO_PIN_MUX_REG[gpio_num], FUN_PD) ? true : false; +} + +/** + * @brief Enable GPIO pin used for wakeup from sleep. + * + * @param hw Peripheral GPIO hardware instance address. + * @param gpio_num GPIO number + */ +static inline void gpio_ll_sleep_sel_en(gpio_dev_t *hw, gpio_num_t gpio_num) +{ + PIN_SLP_SEL_ENABLE(GPIO_PIN_MUX_REG[gpio_num]); +} + +/** + * @brief Disable GPIO pin used for wakeup from sleep. + * + * @param hw Peripheral GPIO hardware instance address. + * @param gpio_num GPIO number + */ +static inline void gpio_ll_sleep_sel_dis(gpio_dev_t *hw, gpio_num_t gpio_num) +{ + PIN_SLP_SEL_DISABLE(GPIO_PIN_MUX_REG[gpio_num]); +} + +/** + * @brief Return slp-sel status on GPIO. + * + * @param hw Peripheral GPIO hardware instance address. + * @param gpio_num GPIO number + * @return if GPIO gpio_num`s SLP_SEL is true + */ +static inline bool gpio_ll_sleep_sel_is_enabled(gpio_dev_t *hw, gpio_num_t gpio_num) +{ + return REG_GET_BIT(GPIO_PIN_MUX_REG[gpio_num], SLP_SEL) ? true : false; +} + +/** + * @brief Disable GPIO pull-up in sleep mode. + * + * @param hw Peripheral GPIO hardware instance address. + * @param gpio_num GPIO number + */ +static inline void gpio_ll_sleep_pullup_dis(gpio_dev_t *hw, gpio_num_t gpio_num) +{ + PIN_SLP_PULLUP_DISABLE(GPIO_PIN_MUX_REG[gpio_num]); +} + +/** + * @brief Enable GPIO pull-up in sleep mode. + * + * @param hw Peripheral GPIO hardware instance address. + * @param gpio_num GPIO number + */ +static inline void gpio_ll_sleep_pullup_en(gpio_dev_t *hw, gpio_num_t gpio_num) +{ + PIN_SLP_PULLUP_ENABLE(GPIO_PIN_MUX_REG[gpio_num]); +} + +/** + * @brief Return slp-pull-up status on GPIO. + * + * @param hw Peripheral GPIO hardware instance address. + * @param gpio_num GPIO number + * @return if GPIO gpio_num`s SLP_PU is true + */ +static inline bool gpio_ll_sleep_pullup_is_enabled(gpio_dev_t *hw, gpio_num_t gpio_num) +{ + return REG_GET_BIT(GPIO_PIN_MUX_REG[gpio_num], SLP_PU) ? true : false; +} + +/** + * @brief Enable GPIO pull-down in sleep mode. + * + * @param hw Peripheral GPIO hardware instance address. + * @param gpio_num GPIO number + */ +static inline void gpio_ll_sleep_pulldown_en(gpio_dev_t *hw, gpio_num_t gpio_num) +{ + PIN_SLP_PULLDOWN_ENABLE(GPIO_PIN_MUX_REG[gpio_num]); +} + +/** + * @brief Disable GPIO pull-down in sleep mode. + * + * @param hw Peripheral GPIO hardware instance address. + * @param gpio_num GPIO number + */ +static inline void gpio_ll_sleep_pulldown_dis(gpio_dev_t *hw, gpio_num_t gpio_num) +{ + PIN_SLP_PULLDOWN_DISABLE(GPIO_PIN_MUX_REG[gpio_num]); +} + +/** + * @brief Return slp-pull-down status on GPIO. + * + * @param hw Peripheral GPIO hardware instance address. + * @param gpio_num GPIO number + * @return if GPIO gpio_num`s SLP_PD is true + */ +static inline bool gpio_ll_sleep_pulldown_is_enabled(gpio_dev_t *hw, gpio_num_t gpio_num) +{ + return REG_GET_BIT(GPIO_PIN_MUX_REG[gpio_num], SLP_PD) ? true : false; +} + /** * @brief GPIO set interrupt trigger type * @@ -226,6 +353,50 @@ static inline void gpio_ll_output_enable(gpio_dev_t *hw, gpio_num_t gpio_num) } } +/** + * @brief Disable GPIO input in sleep mode. + * + * @param hw Peripheral GPIO hardware instance address. + * @param gpio_num GPIO number + */ +static inline void gpio_ll_sleep_input_disable(gpio_dev_t *hw, gpio_num_t gpio_num) +{ + PIN_SLP_INPUT_DISABLE(GPIO_PIN_MUX_REG[gpio_num]); +} + +/** + * @brief Enable GPIO input in sleep mode. + * + * @param hw Peripheral GPIO hardware instance address. + * @param gpio_num GPIO number + */ +static inline void gpio_ll_sleep_input_enable(gpio_dev_t *hw, gpio_num_t gpio_num) +{ + PIN_SLP_INPUT_ENABLE(GPIO_PIN_MUX_REG[gpio_num]); +} + +/** + * @brief Disable GPIO output in sleep mode. + * + * @param hw Peripheral GPIO hardware instance address. + * @param gpio_num GPIO number + */ +static inline void gpio_ll_sleep_output_disable(gpio_dev_t *hw, gpio_num_t gpio_num) +{ + PIN_SLP_OUTPUT_DISABLE(GPIO_PIN_MUX_REG[gpio_num]); +} + +/** + * @brief Enable GPIO output in sleep mode. + * + * @param hw Peripheral GPIO hardware instance address. + * @param gpio_num GPIO number + */ +static inline void gpio_ll_sleep_output_enable(gpio_dev_t *hw, gpio_num_t gpio_num) +{ + PIN_SLP_OUTPUT_ENABLE(GPIO_PIN_MUX_REG[gpio_num]); +} + /** * @brief Disable open-drain mode on GPIO. * diff --git a/components/hal/esp32s2/include/hal/gpio_ll.h b/components/hal/esp32s2/include/hal/gpio_ll.h index 5b6ef3c97e..2ee9b08cf9 100644 --- a/components/hal/esp32s2/include/hal/gpio_ll.h +++ b/components/hal/esp32s2/include/hal/gpio_ll.h @@ -420,6 +420,117 @@ static inline void gpio_ll_force_unhold_all(gpio_dev_t *hw) SET_PERI_REG_MASK(RTC_CNTL_DIG_ISO_REG, RTC_CNTL_CLR_DG_PAD_AUTOHOLD); } +/** + * @brief Enable GPIO pin used for wakeup from sleep. + * + * @param hw Peripheral GPIO hardware instance address. + * @param gpio_num GPIO number + */ +static inline void gpio_ll_sleep_sel_en(gpio_dev_t *hw, gpio_num_t gpio_num) +{ + PIN_SLP_SEL_ENABLE(GPIO_PIN_MUX_REG[gpio_num]); +} + +/** + * @brief Disable GPIO pin used for wakeup from sleep. + * + * @param hw Peripheral GPIO hardware instance address. + * @param gpio_num GPIO number + */ +static inline void gpio_ll_sleep_sel_dis(gpio_dev_t *hw, gpio_num_t gpio_num) +{ + PIN_SLP_SEL_DISABLE(GPIO_PIN_MUX_REG[gpio_num]); +} + +/** + * @brief Disable GPIO pull-up in sleep mode. + * + * @param hw Peripheral GPIO hardware instance address. + * @param gpio_num GPIO number + */ +static inline void gpio_ll_sleep_pullup_dis(gpio_dev_t *hw, gpio_num_t gpio_num) +{ + PIN_SLP_PULLUP_DISABLE(GPIO_PIN_MUX_REG[gpio_num]); +} + +/** + * @brief Enable GPIO pull-up in sleep mode. + * + * @param hw Peripheral GPIO hardware instance address. + * @param gpio_num GPIO number + */ +static inline void gpio_ll_sleep_pullup_en(gpio_dev_t *hw, gpio_num_t gpio_num) +{ + PIN_SLP_PULLUP_ENABLE(GPIO_PIN_MUX_REG[gpio_num]); +} + +/** + * @brief Enable GPIO pull-down in sleep mode. + * + * @param hw Peripheral GPIO hardware instance address. + * @param gpio_num GPIO number + */ +static inline void gpio_ll_sleep_pulldown_en(gpio_dev_t *hw, gpio_num_t gpio_num) +{ + PIN_SLP_PULLDOWN_ENABLE(GPIO_PIN_MUX_REG[gpio_num]); +} + +/** + * @brief Disable GPIO pull-down in sleep mode. + * + * @param hw Peripheral GPIO hardware instance address. + * @param gpio_num GPIO number + */ +static inline void gpio_ll_sleep_pulldown_dis(gpio_dev_t *hw, gpio_num_t gpio_num) +{ + PIN_SLP_PULLDOWN_DISABLE(GPIO_PIN_MUX_REG[gpio_num]); +} + +/** + * @brief Disable GPIO input in sleep mode. + * + * @param hw Peripheral GPIO hardware instance address. + * @param gpio_num GPIO number + */ +static inline void gpio_ll_sleep_input_disable(gpio_dev_t *hw, gpio_num_t gpio_num) +{ + PIN_SLP_INPUT_DISABLE(GPIO_PIN_MUX_REG[gpio_num]); +} + +/** + * @brief Enable GPIO input in sleep mode. + * + * @param hw Peripheral GPIO hardware instance address. + * @param gpio_num GPIO number + */ +static inline void gpio_ll_sleep_input_enable(gpio_dev_t *hw, gpio_num_t gpio_num) +{ + PIN_SLP_INPUT_ENABLE(GPIO_PIN_MUX_REG[gpio_num]); +} + +/** + * @brief Disable GPIO output in sleep mode. + * + * @param hw Peripheral GPIO hardware instance address. + * @param gpio_num GPIO number + */ +static inline void gpio_ll_sleep_output_disable(gpio_dev_t *hw, gpio_num_t gpio_num) +{ + PIN_SLP_OUTPUT_DISABLE(GPIO_PIN_MUX_REG[gpio_num]); +} + +/** + * @brief Enable GPIO output in sleep mode. + * + * @param hw Peripheral GPIO hardware instance address. + * @param gpio_num GPIO number + */ +static inline void gpio_ll_sleep_output_enable(gpio_dev_t *hw, gpio_num_t gpio_num) +{ + PIN_SLP_OUTPUT_ENABLE(GPIO_PIN_MUX_REG[gpio_num]); +} + + #ifdef __cplusplus } #endif diff --git a/components/hal/include/hal/gpio_hal.h b/components/hal/include/hal/gpio_hal.h index 8b58b85f41..31a1814c1a 100644 --- a/components/hal/include/hal/gpio_hal.h +++ b/components/hal/include/hal/gpio_hal.h @@ -338,6 +338,105 @@ void gpio_hal_intr_disable(gpio_hal_context_t *hal, gpio_num_t gpio_num); #define gpio_hal_force_unhold_all(hal) gpio_ll_force_unhold_all((hal)->dev) #endif +#if SOC_GPIO_SUPPORT_SLP_SWITCH +/** + * @brief Enable pull-up on GPIO when system sleep. + * + * @param hal Context of the HAL layer + * @param gpio_num GPIO number + */ +#define gpio_hal_sleep_pullup_en(hal, gpio_num) gpio_ll_sleep_pullup_en((hal)->dev, gpio_num) + +/** + * @brief Disable pull-up on GPIO when system sleep. + * + * @param hal Context of the HAL layer + * @param gpio_num GPIO number + */ +#define gpio_hal_sleep_pullup_dis(hal, gpio_num) gpio_ll_sleep_pullup_dis((hal)->dev, gpio_num) + +/** + * @brief Enable pull-down on GPIO when system sleep. + * + * @param hal Context of the HAL layer + * @param gpio_num GPIO number + */ +#define gpio_hal_sleep_pulldown_en(hal, gpio_num) gpio_ll_sleep_pulldown_en((hal)->dev, gpio_num) + +/** + * @brief Disable pull-down on GPIO when system sleep. + * + * @param hal Context of the HAL layer + * @param gpio_num GPIO number + */ +#define gpio_hal_sleep_pulldown_dis(hal, gpio_num) gpio_ll_sleep_pulldown_dis((hal)->dev, gpio_num) + +/** + * @brief Enable sleep select on GPIO. + * + * @param hal Context of the HAL layer + * @param gpio_num GPIO number + */ +#define gpio_hal_sleep_sel_en(hal, gpio_num) gpio_ll_sleep_sel_en((hal)->dev, gpio_num) + +/** + * @brief Disable sleep select on GPIO. + * + * @param hal Context of the HAL layer + * @param gpio_num GPIO number + */ +#define gpio_hal_sleep_sel_dis(hal, gpio_num) gpio_ll_sleep_sel_dis((hal)->dev, gpio_num) + +/** + * @brief Disable input mode on GPIO when system sleep. + * + * @param hal Context of the HAL layer + * @param gpio_num GPIO number + */ +#define gpio_hal_sleep_input_disable(hal, gpio_num) gpio_ll_sleep_input_disable((hal)->dev, gpio_num) + +/** + * @brief Enable input mode on GPIO when system sleep. + * + * @param hal Context of the HAL layer + * @param gpio_num GPIO number + */ +#define gpio_hal_sleep_input_enable(hal, gpio_num) gpio_ll_sleep_input_enable((hal)->dev, gpio_num) + +/** + * @brief Disable output mode on GPIO when system sleep. + * + * @param hal Context of the HAL layer + * @param gpio_num GPIO number + */ +#define gpio_hal_sleep_output_disable(hal, gpio_num) gpio_ll_sleep_output_disable((hal)->dev, gpio_num) + +/** + * @brief Enable output mode on GPIO when system sleep. + * + * @param hal Context of the HAL layer + * @param gpio_num GPIO number + */ +#define gpio_hal_sleep_output_enable(hal, gpio_num) gpio_ll_sleep_output_enable((hal)->dev, gpio_num) + +#if CONFIG_GPIO_ESP32_SUPPORT_SWITCH_SLP_PULL +/** + * @brief Apply slp_pu/slp_pd configuration to fun_pu/fun_pd when system sleep. + * + * @param hal Context of the HAL layer + * @param gpio_num GPIO number. + */ +void gpio_hal_sleep_pupd_config_apply(gpio_hal_context_t *hal, gpio_num_t gpio_num); + +/** + * @brief Restore fun_pu/fun_pd configuration when system wakeup. + * + * @param hal Context of the HAL layer + * @param gpio_num GPIO number. + */ +void gpio_hal_sleep_pupd_config_unapply(gpio_hal_context_t *hal, gpio_num_t gpio_num); +#endif +#endif #ifdef __cplusplus } #endif diff --git a/components/soc/esp32/include/soc/io_mux_reg.h b/components/soc/esp32/include/soc/io_mux_reg.h index 22ea25b91f..3e9bbe1ce0 100644 --- a/components/soc/esp32/include/soc/io_mux_reg.h +++ b/components/soc/esp32/include/soc/io_mux_reg.h @@ -73,6 +73,17 @@ #define MCU_SEL_V 0x7 #define MCU_SEL_S 12 +#define PIN_SLP_INPUT_ENABLE(PIN_NAME) SET_PERI_REG_MASK(PIN_NAME,SLP_IE) +#define PIN_SLP_INPUT_DISABLE(PIN_NAME) CLEAR_PERI_REG_MASK(PIN_NAME,SLP_IE) +#define PIN_SLP_OUTPUT_ENABLE(PIN_NAME) SET_PERI_REG_MASK(PIN_NAME,SLP_OE) +#define PIN_SLP_OUTPUT_DISABLE(PIN_NAME) CLEAR_PERI_REG_MASK(PIN_NAME,SLP_OE) +#define PIN_SLP_PULLUP_ENABLE(PIN_NAME) SET_PERI_REG_MASK(PIN_NAME,SLP_PU) +#define PIN_SLP_PULLUP_DISABLE(PIN_NAME) CLEAR_PERI_REG_MASK(PIN_NAME,SLP_PU) +#define PIN_SLP_PULLDOWN_ENABLE(PIN_NAME) SET_PERI_REG_MASK(PIN_NAME,SLP_PD) +#define PIN_SLP_PULLDOWN_DISABLE(PIN_NAME) CLEAR_PERI_REG_MASK(PIN_NAME,SLP_PD) +#define PIN_SLP_SEL_ENABLE(PIN_NAME) SET_PERI_REG_MASK(PIN_NAME,SLP_SEL) +#define PIN_SLP_SEL_DISABLE(PIN_NAME) CLEAR_PERI_REG_MASK(PIN_NAME,SLP_SEL) + #define PIN_INPUT_ENABLE(PIN_NAME) SET_PERI_REG_MASK(PIN_NAME,FUN_IE) #define PIN_INPUT_DISABLE(PIN_NAME) CLEAR_PERI_REG_MASK(PIN_NAME,FUN_IE) #define PIN_SET_DRV(PIN_NAME, drv) REG_SET_FIELD(PIN_NAME, FUN_DRV, (drv)); diff --git a/components/soc/esp32/include/soc/soc_caps.h b/components/soc/esp32/include/soc/soc_caps.h index c8a00414d9..3e83316209 100644 --- a/components/soc/esp32/include/soc/soc_caps.h +++ b/components/soc/esp32/include/soc/soc_caps.h @@ -116,6 +116,9 @@ // GPIO >= 34 are input only #define SOC_GPIO_VALID_OUTPUT_GPIO_MASK (SOC_GPIO_VALID_GPIO_MASK & ~(0ULL | BIT34 | BIT35 | BIT36 | BIT37 | BIT38 | BIT39)) +// Support to configure slept status +#define SOC_GPIO_SUPPORT_SLP_SWITCH (1) + /*-------------------------- I2C CAPS ----------------------------------------*/ // ESP32 have 2 I2C. #define SOC_I2C_NUM (2) diff --git a/components/soc/esp32s2/include/soc/io_mux_reg.h b/components/soc/esp32s2/include/soc/io_mux_reg.h index b9de086724..fe480c91e5 100644 --- a/components/soc/esp32s2/include/soc/io_mux_reg.h +++ b/components/soc/esp32s2/include/soc/io_mux_reg.h @@ -73,6 +73,17 @@ #define MCU_SEL_V 0x7 #define MCU_SEL_S 12 +#define PIN_SLP_INPUT_ENABLE(PIN_NAME) SET_PERI_REG_MASK(PIN_NAME,SLP_IE) +#define PIN_SLP_INPUT_DISABLE(PIN_NAME) CLEAR_PERI_REG_MASK(PIN_NAME,SLP_IE) +#define PIN_SLP_OUTPUT_ENABLE(PIN_NAME) SET_PERI_REG_MASK(PIN_NAME,SLP_OE) +#define PIN_SLP_OUTPUT_DISABLE(PIN_NAME) CLEAR_PERI_REG_MASK(PIN_NAME,SLP_OE) +#define PIN_SLP_PULLUP_ENABLE(PIN_NAME) SET_PERI_REG_MASK(PIN_NAME,SLP_PU) +#define PIN_SLP_PULLUP_DISABLE(PIN_NAME) CLEAR_PERI_REG_MASK(PIN_NAME,SLP_PU) +#define PIN_SLP_PULLDOWN_ENABLE(PIN_NAME) SET_PERI_REG_MASK(PIN_NAME,SLP_PD) +#define PIN_SLP_PULLDOWN_DISABLE(PIN_NAME) CLEAR_PERI_REG_MASK(PIN_NAME,SLP_PD) +#define PIN_SLP_SEL_ENABLE(PIN_NAME) SET_PERI_REG_MASK(PIN_NAME,SLP_SEL) +#define PIN_SLP_SEL_DISABLE(PIN_NAME) CLEAR_PERI_REG_MASK(PIN_NAME,SLP_SEL) + #define PIN_INPUT_ENABLE(PIN_NAME) SET_PERI_REG_MASK(PIN_NAME,FUN_IE) #define PIN_INPUT_DISABLE(PIN_NAME) CLEAR_PERI_REG_MASK(PIN_NAME,FUN_IE) #define PIN_SET_DRV(PIN_NAME, drv) REG_SET_FIELD(PIN_NAME, FUN_DRV, (drv)); diff --git a/components/soc/esp32s2/include/soc/soc_caps.h b/components/soc/esp32s2/include/soc/soc_caps.h index f384c42a41..54552da3b1 100644 --- a/components/soc/esp32s2/include/soc/soc_caps.h +++ b/components/soc/esp32s2/include/soc/soc_caps.h @@ -99,6 +99,9 @@ // GPIO 46, 47 are input only #define SOC_GPIO_VALID_OUTPUT_GPIO_MASK (SOC_GPIO_VALID_GPIO_MASK & ~(0ULL | BIT46 | BIT47)) +// Support to configure slept status +#define SOC_GPIO_SUPPORT_SLP_SWITCH (1) + /*-------------------------- Dedicated GPIO CAPS ---------------------------------------*/ #define SOC_DEDIC_GPIO_OUT_CHANNELS_NUM (8) /*!< 8 outward channels on each CPU core */ #define SOC_DEDIC_GPIO_IN_CHANNELS_NUM (8) /*!< 8 inward channels on each CPU core */ diff --git a/examples/wifi/power_save/sdkconfig.defaults b/examples/wifi/power_save/sdkconfig.defaults index 60d93f2738..42b68979dd 100644 --- a/examples/wifi/power_save/sdkconfig.defaults +++ b/examples/wifi/power_save/sdkconfig.defaults @@ -9,3 +9,6 @@ CONFIG_PM_USE_RTC_TIMER_REF=y # Put related source code in IRAM CONFIG_PM_SLP_IRAM_OPT=y CONFIG_PM_RTOS_IDLE_OPT=y +# Disable all GPIO at light sleep +CONFIG_GPIO_ESP32_SUPPORT_SWITCH_SLP_PULL=y +CONFIG_PM_SLP_DISABLE_GPIO=y