mirror of
https://github.com/espressif/esp-idf.git
synced 2026-10-02 03:00:34 +03:00
esp_hw_support/sleep: fix current leakage when hold digital io during deep sleep
This commit is contained in:
@@ -6,6 +6,7 @@
|
||||
|
||||
#pragma once
|
||||
#include <stdbool.h>
|
||||
#include "sdkconfig.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
@@ -20,6 +21,15 @@ extern "C" {
|
||||
*/
|
||||
void esp_sleep_enable_adc_tsens_monitor(bool enable);
|
||||
|
||||
// TODO: IDF-6051, IDF-6052
|
||||
#if !CONFIG_IDF_TARGET_ESP32H2 && !CONFIG_IDF_TARGET_ESP32C6
|
||||
/**
|
||||
* @brief Isolate all digital IOs except those that are held during deep sleep
|
||||
*
|
||||
* Reduce digital IOs current leakage during deep sleep.
|
||||
*/
|
||||
void esp_sleep_isolate_digital_gpio(void);
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
||||
@@ -12,11 +12,13 @@
|
||||
#include "esp_attr.h"
|
||||
#include "esp_sleep.h"
|
||||
#include "esp_log.h"
|
||||
#include "esp_memory_utils.h"
|
||||
#include "soc/soc_caps.h"
|
||||
|
||||
#include "sdkconfig.h"
|
||||
|
||||
#include "driver/gpio.h"
|
||||
#include "hal/gpio_hal.h"
|
||||
#include "esp_private/gpio.h"
|
||||
#include "esp_private/sleep_gpio.h"
|
||||
#include "esp_private/spi_flash_os.h"
|
||||
@@ -94,3 +96,44 @@ void esp_sleep_enable_gpio_switch(bool enable)
|
||||
}
|
||||
|
||||
#endif // SOC_GPIO_SUPPORT_SLP_SWITCH
|
||||
|
||||
// TODO: IDF-6051, IDF-6052
|
||||
#if !CONFIG_IDF_TARGET_ESP32H2 && !CONFIG_IDF_TARGET_ESP32C6
|
||||
IRAM_ATTR void esp_sleep_isolate_digital_gpio(void)
|
||||
{
|
||||
gpio_hal_context_t gpio_hal = {
|
||||
.dev = GPIO_HAL_GET_HW(GPIO_PORT_0)
|
||||
};
|
||||
|
||||
/* no need to do isolate if digital IOs are not being held in deep sleep */
|
||||
if (!gpio_hal_deep_sleep_hold_is_en(&gpio_hal)) {
|
||||
return;
|
||||
}
|
||||
|
||||
/**
|
||||
* there is a situation where we cannot isolate digital IO before deep sleep:
|
||||
* - task stack is located in external ram(mspi ram), since we will isolate mspi io
|
||||
*
|
||||
* assert here instead of returning directly, because if digital IO is not isolated,
|
||||
* the bottom current of deep sleep will be higher than light sleep, and there is no
|
||||
* reason to use deep sleep at this time.
|
||||
*/
|
||||
assert(esp_ptr_internal(&gpio_hal) && "If hold digital IO, the stack of the task calling esp_deep_sleep_start must be in internal ram!");
|
||||
|
||||
/* isolate digital IO that is not held(keep the configuration of digital IOs held by users) */
|
||||
for (gpio_num_t gpio_num = GPIO_NUM_0; gpio_num < GPIO_NUM_MAX; gpio_num++) {
|
||||
if (GPIO_IS_VALID_DIGITAL_IO_PAD(gpio_num) && !gpio_hal_is_digital_io_hold(&gpio_hal, gpio_num)) {
|
||||
/* disable I/O */
|
||||
gpio_hal_input_disable(&gpio_hal, gpio_num);
|
||||
gpio_hal_output_disable(&gpio_hal, gpio_num);
|
||||
|
||||
/* disable pull up/down */
|
||||
gpio_hal_pullup_dis(&gpio_hal, gpio_num);
|
||||
gpio_hal_pulldown_dis(&gpio_hal, gpio_num);
|
||||
|
||||
/* make pad work as gpio(otherwise, deep sleep bottom current will rise) */
|
||||
gpio_hal_func_sel(&gpio_hal, gpio_num, PIN_FUNC_GPIO);
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -12,6 +12,7 @@
|
||||
#include "esp_attr.h"
|
||||
#include "esp_memory_utils.h"
|
||||
#include "esp_sleep.h"
|
||||
#include "esp_private/esp_sleep_internal.h"
|
||||
#include "esp_private/esp_timer_private.h"
|
||||
#include "esp_private/system_internal.h"
|
||||
#include "esp_log.h"
|
||||
@@ -516,6 +517,11 @@ static uint32_t IRAM_ATTR esp_sleep_start(uint32_t pd_flags)
|
||||
*/
|
||||
portENTER_CRITICAL(&spinlock_rtc_deep_sleep);
|
||||
|
||||
// TODO: IDF-6051, IDF-6052
|
||||
#if !CONFIG_IDF_TARGET_ESP32H2 && !CONFIG_IDF_TARGET_ESP32C6
|
||||
esp_sleep_isolate_digital_gpio();
|
||||
#endif
|
||||
|
||||
#if SOC_PM_SUPPORT_DEEPSLEEP_CHECK_STUB_ONLY
|
||||
extern char _rtc_text_start[];
|
||||
#if CONFIG_ESP32S3_RTCDATA_IN_FAST_MEM
|
||||
|
||||
Reference in New Issue
Block a user