mirror of
https://github.com/espressif/esp-idf.git
synced 2026-10-02 11:10:54 +03:00
Merge branch 'bugfix/gpio_esp32_workaround' into 'master'
fix(gpio): fix ESP32 GPIO sleep mode handling Closes IDF-13626 See merge request espressif/esp-idf!40988
This commit is contained in:
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2015-2021 Espressif Systems (Shanghai) CO LTD
|
||||
* SPDX-FileCopyrightText: 2015-2025 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
@@ -18,8 +18,7 @@ extern "C" {
|
||||
* This file contains declarations of GPIO related functions in sleep modes.
|
||||
*/
|
||||
|
||||
#if CONFIG_GPIO_ESP32_SUPPORT_SWITCH_SLP_PULL
|
||||
|
||||
#if CONFIG_IDF_TARGET_ESP32
|
||||
/**
|
||||
* @brief Save GPIO pull-up and pull-down configuration information in the wake-up state
|
||||
*
|
||||
@@ -29,7 +28,7 @@ extern "C" {
|
||||
* 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);
|
||||
void esp_sleep_gpio_pupd_config_workaround_apply(void);
|
||||
|
||||
/**
|
||||
* @brief Restore GPIO pull-up and pull-down configuration information in the wake-up state
|
||||
@@ -37,9 +36,9 @@ void gpio_sleep_mode_config_apply(void);
|
||||
* 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);
|
||||
void esp_sleep_gpio_pupd_config_workaround_unapply(void);
|
||||
|
||||
#endif // CONFIG_GPIO_ESP32_SUPPORT_SWITCH_SLP_PULL
|
||||
#endif // CONFIG_IDF_TARGET_ESP32
|
||||
|
||||
/**
|
||||
* @brief Call once in startup to disable the wakeup IO pins and release their holding state after waking up from Deep-sleep
|
||||
|
||||
@@ -34,21 +34,64 @@
|
||||
|
||||
static const char *TAG = "sleep_gpio";
|
||||
|
||||
#if CONFIG_GPIO_ESP32_SUPPORT_SWITCH_SLP_PULL
|
||||
void gpio_sleep_mode_config_apply(void)
|
||||
#if CONFIG_IDF_TARGET_ESP32
|
||||
/* On ESP32, for IOs with RTC functionality, setting SLP_PU, SLP_PD couldn't change IO status
|
||||
* from FUN_PU, FUN_PD to SLP_PU, SLP_PD at sleep.
|
||||
*/
|
||||
typedef struct gpio_slp_mode_cfg {
|
||||
volatile uint32_t fun_pu;
|
||||
volatile uint32_t fun_pd;
|
||||
} gpio_slp_mode_cfg_t;
|
||||
|
||||
static DRAM_ATTR gpio_slp_mode_cfg_t gpio_cfg = {};
|
||||
|
||||
void esp_sleep_gpio_pupd_config_workaround_apply(void)
|
||||
{
|
||||
/* Record fun_pu and fun_pd state in bitmap */
|
||||
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);
|
||||
int rtcio_num = rtc_io_num_map[gpio_num];
|
||||
if (rtcio_num >= 0 && gpio_ll_sleep_sel_is_enabled(&GPIO, gpio_num)) {
|
||||
if (rtcio_ll_is_pullup_enabled(rtcio_num)) {
|
||||
gpio_cfg.fun_pu |= BIT(rtcio_num);
|
||||
} else {
|
||||
gpio_cfg.fun_pu &= ~BIT(rtcio_num);
|
||||
}
|
||||
if (rtcio_ll_is_pulldown_enabled(rtcio_num)) {
|
||||
gpio_cfg.fun_pd |= BIT(rtcio_num);
|
||||
} else {
|
||||
gpio_cfg.fun_pd &= ~BIT(rtcio_num);
|
||||
}
|
||||
|
||||
if (gpio_ll_sleep_pullup_is_enabled(&GPIO, gpio_num)) {
|
||||
rtcio_ll_pullup_enable(rtcio_num);
|
||||
} else {
|
||||
rtcio_ll_pullup_disable(rtcio_num);
|
||||
}
|
||||
if (gpio_ll_sleep_pulldown_is_enabled(&GPIO, gpio_num)) {
|
||||
rtcio_ll_pulldown_enable(rtcio_num);
|
||||
} else {
|
||||
rtcio_ll_pulldown_disable(rtcio_num);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
IRAM_ATTR void gpio_sleep_mode_config_unapply(void)
|
||||
void esp_sleep_gpio_pupd_config_workaround_unapply(void)
|
||||
{
|
||||
/* Restore fun_pu and fun_pd state from bitmap */
|
||||
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);
|
||||
int rtcio_num = rtc_io_num_map[gpio_num];
|
||||
if (rtcio_num >= 0 && gpio_ll_sleep_sel_is_enabled(&GPIO, gpio_num)) {
|
||||
if (gpio_cfg.fun_pu & BIT(rtcio_num)) {
|
||||
rtcio_ll_pullup_enable(rtcio_num);
|
||||
} else {
|
||||
rtcio_ll_pullup_disable(rtcio_num);
|
||||
}
|
||||
if (gpio_cfg.fun_pd & BIT(rtcio_num)) {
|
||||
rtcio_ll_pulldown_enable(rtcio_num);
|
||||
} else {
|
||||
rtcio_ll_pulldown_disable(rtcio_num);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -733,8 +733,8 @@ static SLEEP_FN_ATTR void misc_modules_sleep_prepare(uint32_t sleep_flags, bool
|
||||
# endif
|
||||
mac_bb_power_down_cb_execute();
|
||||
#endif
|
||||
#if CONFIG_GPIO_ESP32_SUPPORT_SWITCH_SLP_PULL
|
||||
gpio_sleep_mode_config_apply();
|
||||
#if CONFIG_IDF_TARGET_ESP32
|
||||
esp_sleep_gpio_pupd_config_workaround_apply();
|
||||
#endif
|
||||
#if CONFIG_PM_POWER_DOWN_CPU_IN_LIGHT_SLEEP && SOC_PM_CPU_RETENTION_BY_RTCCNTL
|
||||
sleep_enable_cpu_retention();
|
||||
@@ -801,8 +801,8 @@ static SLEEP_FN_ATTR void misc_modules_wake_prepare(uint32_t sleep_flags)
|
||||
#if CONFIG_PM_POWER_DOWN_CPU_IN_LIGHT_SLEEP && SOC_PM_CPU_RETENTION_BY_RTCCNTL
|
||||
sleep_disable_cpu_retention();
|
||||
#endif
|
||||
#if CONFIG_GPIO_ESP32_SUPPORT_SWITCH_SLP_PULL
|
||||
gpio_sleep_mode_config_unapply();
|
||||
#if CONFIG_IDF_TARGET_ESP32
|
||||
esp_sleep_gpio_pupd_config_workaround_unapply();
|
||||
#endif
|
||||
#if CONFIG_MAC_BB_PD
|
||||
mac_bb_power_up_cb_execute();
|
||||
|
||||
Reference in New Issue
Block a user