Power Management: support DFS and PMU feature for esp32h2

This commit is contained in:
Lou Tianhao
2023-05-22 14:17:02 +08:00
parent 09bc513b2c
commit 63d32ab620
29 changed files with 1025 additions and 482 deletions
+27 -2
View File
@@ -32,9 +32,11 @@
#if SOC_LP_AON_SUPPORTED
#include "hal/lp_aon_hal.h"
#else
#if !CONFIG_IDF_TARGET_ESP32H2
#include "hal/rtc_cntl_ll.h"
#include "hal/rtc_hal.h"
#endif
#endif
#include "driver/uart.h"
@@ -89,6 +91,15 @@
#include "esp32h2/rom/cache.h"
#include "esp32h2/rom/rtc.h"
#include "soc/extmem_reg.h"
#if SOC_LP_TIMER_SUPPORTED
#include "hal/lp_timer_hal.h"
#endif
#if SOC_PMU_SUPPORTED
#include "esp_private/esp_pmu.h"
#include "esp_private/sleep_sys_periph.h"
#include "esp_private/sleep_clock.h"
#endif
#endif
// If light sleep time is less than that, don't power down flash
@@ -245,6 +256,7 @@ static void touch_wakeup_prepare(void);
static void gpio_deep_sleep_wakeup_prepare(void);
#endif
#if !CONFIG_IDF_TARGET_ESP32H2
#if SOC_RTC_FAST_MEM_SUPPORTED
#if SOC_PM_SUPPORT_DEEPSLEEP_CHECK_STUB_ONLY
static RTC_FAST_ATTR esp_deep_sleep_wake_stub_fn_t wake_stub_fn_handler = NULL;
@@ -350,6 +362,7 @@ void RTC_IRAM_ATTR esp_default_wake_deep_sleep(void)
void __attribute__((weak, alias("esp_default_wake_deep_sleep"))) esp_wake_deep_sleep(void);
#endif // SOC_RTC_FAST_MEM_SUPPORTED
#endif // !CONFIG_IDF_TARGET_ESP32H2
void esp_deep_sleep(uint64_t time_in_us)
{
@@ -674,6 +687,7 @@ static esp_err_t IRAM_ATTR esp_sleep_start(uint32_t pd_flags, esp_sleep_mode_t m
esp_sleep_isolate_digital_gpio();
#endif
#if !CONFIG_IDF_TARGET_ESP32H2 // TODO: IDF-6268
#if SOC_PM_SUPPORT_DEEPSLEEP_CHECK_STUB_ONLY
esp_set_deep_sleep_wake_stub_default_entry();
// Enter Deep Sleep
@@ -694,9 +708,10 @@ static esp_err_t IRAM_ATTR esp_sleep_start(uint32_t pd_flags, esp_sleep_mode_t m
result = rtc_deep_sleep_start(s_config.wakeup_triggers, reject_triggers);
#endif
#endif // SOC_PM_SUPPORT_DEEPSLEEP_CHECK_STUB_ONLY
#else // !CONFIG_IDF_TARGET_ESP32H2
result = ESP_OK;
#endif // !CONFIG_IDF_TARGET_ESP32H2
} else {
/* On esp32c6, only the lp_aon pad hold function can only hold the GPIO state in the active mode.
In order to avoid the leakage of the SPI cs pin, hold it here */
#if (CONFIG_PM_POWER_DOWN_PERIPHERAL_IN_LIGHT_SLEEP && CONFIG_ESP_SLEEP_FLASH_LEAKAGE_WORKAROUND)
@@ -704,11 +719,14 @@ static esp_err_t IRAM_ATTR esp_sleep_start(uint32_t pd_flags, esp_sleep_mode_t m
rtcio_ll_force_hold_enable(SPI_CS0_GPIO_NUM);
}
#endif
#endif
#if SOC_PMU_SUPPORTED
#if SOC_PM_CPU_RETENTION_BY_SW
if (pd_flags & PMU_SLEEP_PD_CPU) {
result = esp_sleep_cpu_retention(pmu_sleep_start, s_config.wakeup_triggers, reject_triggers, config.power.hp_sys.dig_power.mem_dslp, deep_sleep);
} else {
#endif
result = call_rtc_sleep_start(reject_triggers, config.power.hp_sys.dig_power.mem_dslp, deep_sleep);
}
#else
@@ -1391,15 +1409,20 @@ uint64_t esp_sleep_get_ext1_wakeup_status(void)
#if SOC_GPIO_SUPPORT_DEEPSLEEP_WAKEUP
uint64_t esp_sleep_get_gpio_wakeup_status(void)
{
#if CONFIG_IDF_TARGET_ESP32H2 // TODO: IDF-6268
return 0;
#else
if (esp_sleep_get_wakeup_cause() != ESP_SLEEP_WAKEUP_GPIO) {
return 0;
}
return rtc_hal_gpio_get_wakeup_status();
#endif // !CONFIG_IDF_TARGET_ESP32H2
}
static void gpio_deep_sleep_wakeup_prepare(void)
{
#if !CONFIG_IDF_TARGET_ESP32H2 // TODO: IDF-6268
for (gpio_num_t gpio_idx = GPIO_NUM_0; gpio_idx < GPIO_NUM_MAX; gpio_idx++) {
if (((1ULL << gpio_idx) & s_config.gpio_wakeup_mask) == 0) {
continue;
@@ -1415,6 +1438,7 @@ static void gpio_deep_sleep_wakeup_prepare(void)
}
// Clear state from previous wakeup
rtc_hal_gpio_clear_wakeup_status();
#endif // !CONFIG_IDF_TARGET_ESP32H2
}
esp_err_t esp_deep_sleep_enable_gpio_wakeup(uint64_t gpio_pin_mask, esp_deepsleep_gpio_wake_up_mode_t mode)
@@ -1600,6 +1624,7 @@ esp_err_t esp_sleep_pd_config(esp_sleep_pd_domain_t domain, esp_sleep_pd_option_
return ESP_ERR_INVALID_ARG;
}
portENTER_CRITICAL_SAFE(&s_config.lock);
int refs = (option == ESP_PD_OPTION_ON) ? s_config.domain[domain].refs++ \
: (option == ESP_PD_OPTION_OFF) ? --s_config.domain[domain].refs \
: s_config.domain[domain].refs;