From b0757dfcfaa40ca789bbac5ae28b9b8120dd0cb2 Mon Sep 17 00:00:00 2001 From: Li Shuai Date: Thu, 19 Aug 2021 21:57:17 +0800 Subject: [PATCH] light sleep: separate sleep gpio function --- components/esp_hw_support/CMakeLists.txt | 1 + .../include/esp_private/sleep_gpio.h | 46 ++++++++++++ components/esp_hw_support/sleep_gpio.c | 72 +++++++++++++++++++ components/esp_hw_support/sleep_modes.c | 49 +------------ components/esp_pm/linker.lf | 2 + 5 files changed, 122 insertions(+), 48 deletions(-) create mode 100644 components/esp_hw_support/include/esp_private/sleep_gpio.h create mode 100644 components/esp_hw_support/sleep_gpio.c diff --git a/components/esp_hw_support/CMakeLists.txt b/components/esp_hw_support/CMakeLists.txt index 40dcb22947..58c8726ecd 100644 --- a/components/esp_hw_support/CMakeLists.txt +++ b/components/esp_hw_support/CMakeLists.txt @@ -15,6 +15,7 @@ if(NOT BOOTLOADER_BUILD) "intr_alloc.c" "mac_addr.c" "sleep_modes.c" + "sleep_gpio.c" "regi2c_ctrl.c") list(APPEND requires esp_ipc) else() diff --git a/components/esp_hw_support/include/esp_private/sleep_gpio.h b/components/esp_hw_support/include/esp_private/sleep_gpio.h new file mode 100644 index 0000000000..abab21871a --- /dev/null +++ b/components/esp_hw_support/include/esp_private/sleep_gpio.h @@ -0,0 +1,46 @@ +/* + * SPDX-FileCopyrightText: 2015-2021 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#pragma once +#include +#include "sdkconfig.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * @file sleep_gpio.h + * + * This file contains declarations of GPIO related functions in light sleep mode. + */ + +#if SOC_GPIO_SUPPORT_SLP_SWITCH && CONFIG_GPIO_ESP32_SUPPORT_SWITCH_SLP_PULL + +/** + * @brief Save GPIO pull-up and pull-down configuration information in the wake-up state + * + * In light sleep mode, the pull-up and pull-down resistors of GPIO will cause + * leakage current when the system sleeps. In order to reduce the power + * consumption of system sleep, it needs to save the configuration information + * of all GPIO pull-up and pull-down resistors and disable the pull-up and + * pull-down resistors of GPIO before the system enters sleep. + */ +void gpio_sleep_mode_config_apply(void); + +/** + * @brief Restore GPIO pull-up and pull-down configuration information in the wake-up state + * + * In light sleep mode, after the system wakes up, it needs to restore all GPIO + * pull-up and pull-down configurations before the last sleep. + */ +void gpio_sleep_mode_config_unapply(void); + +#endif // SOC_GPIO_SUPPORT_SLP_SWITCH && CONFIG_GPIO_ESP32_SUPPORT_SWITCH_SLP_PULL + +#ifdef __cplusplus +} +#endif diff --git a/components/esp_hw_support/sleep_gpio.c b/components/esp_hw_support/sleep_gpio.c new file mode 100644 index 0000000000..776ef053d8 --- /dev/null +++ b/components/esp_hw_support/sleep_gpio.c @@ -0,0 +1,72 @@ +/* + * SPDX-FileCopyrightText: 2015-2021 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include +#include +#include + +#include "esp_attr.h" +#include "esp_sleep.h" +#include "esp_log.h" +#include "soc/soc_caps.h" + +#include "sdkconfig.h" + +#include "driver/gpio.h" +#include "esp_private/gpio.h" +#include "esp_private/sleep_gpio.h" + +static const char *TAG = "sleep"; + +#if SOC_GPIO_SUPPORT_SLP_SWITCH + +#if CONFIG_GPIO_ESP32_SUPPORT_SWITCH_SLP_PULL +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); + } + } +} + +IRAM_ATTR 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_config_gpio_isolate(void) +{ + ESP_LOGI(TAG, "Configure to isolate all GPIO pins in sleep state"); + 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_enable_gpio_switch(bool enable) +{ + ESP_LOGI(TAG, "%s automatic switching of GPIO sleep configuration", enable ? "Enable" : "Disable"); + 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 // SOC_GPIO_SUPPORT_SLP_SWITCH diff --git a/components/esp_hw_support/sleep_modes.c b/components/esp_hw_support/sleep_modes.c index ee68b21f0c..b3b98bc9ab 100644 --- a/components/esp_hw_support/sleep_modes.c +++ b/components/esp_hw_support/sleep_modes.c @@ -49,6 +49,7 @@ #include "esp32/rom/rtc.h" #include "esp32/clk.h" #include "esp_private/gpio.h" +#include "esp_private/sleep_gpio.h" #elif CONFIG_IDF_TARGET_ESP32S2 #include "esp32s2/clk.h" #include "esp32s2/rom/cache.h" @@ -392,54 +393,6 @@ esp_err_t esp_sleep_cpu_pd_low_init(bool enable) } #endif // SOC_PM_SUPPORT_CPU_PD -#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_config_gpio_isolate(void) -{ - ESP_LOGI(TAG, "Configure to isolate all GPIO pins in sleep state"); - 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_enable_gpio_switch(bool enable) -{ - ESP_LOGI(TAG, "%s automatic switching of GPIO sleep configuration", enable ? "Enable" : "Disable"); - 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 // SOC_GPIO_SUPPORT_SLP_SWITCH - - 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. diff --git a/components/esp_pm/linker.lf b/components/esp_pm/linker.lf index 2abbeab151..3f4426b229 100644 --- a/components/esp_pm/linker.lf +++ b/components/esp_pm/linker.lf @@ -19,6 +19,8 @@ entries: esp_clk:esp_clk_slowclk_cal_set (noflash) esp_clk:esp_clk_slowclk_cal_get (noflash) esp_clk:esp_rtc_get_time_us (noflash) + if GPIO_ESP32_SUPPORT_SWITCH_SLP_PULL = y: + sleep_gpio:gpio_sleep_mode_config_apply (noflash) [mapping:esp_system_pm] archive: libesp_system.a