mirror of
https://github.com/espressif/esp-idf.git
synced 2025-09-30 19:19:21 +00:00
fix(esp_pm): fix PM_SLP_IRAM_OPT/PM_RTOS_IDLE_OPT feature
- Fix flash accessed code to resolve issues with PM_SLP_IRAM_OPT/PM_RTOS_IDLE_OPT enabled
This commit is contained in:
@@ -400,10 +400,11 @@ void esp_deep_sleep_deregister_hook(esp_deep_sleep_cb_t old_dslp_cb)
|
||||
portEXIT_CRITICAL(&spinlock_rtc_deep_sleep);
|
||||
}
|
||||
|
||||
#if (CONFIG_PM_POWER_DOWN_PERIPHERAL_IN_LIGHT_SLEEP && CONFIG_ESP_SLEEP_FLASH_LEAKAGE_WORKAROUND) \
|
||||
#if (CONFIG_PM_POWER_DOWN_PERIPHERAL_IN_LIGHT_SLEEP && CONFIG_ESP_SLEEP_FLASH_LEAKAGE_WORKAROUND && !CONFIG_IDF_TARGET_ESP32H2) \
|
||||
|| CONFIG_ESP_SLEEP_CACHE_SAFE_ASSERTION
|
||||
static int s_cache_suspend_cnt = 0;
|
||||
|
||||
// Must be called from critical sections.
|
||||
static void IRAM_ATTR suspend_cache(void) {
|
||||
s_cache_suspend_cnt++;
|
||||
if (s_cache_suspend_cnt == 1) {
|
||||
@@ -411,9 +412,10 @@ static void IRAM_ATTR suspend_cache(void) {
|
||||
}
|
||||
}
|
||||
|
||||
// Must be called from critical sections.
|
||||
static void IRAM_ATTR resume_cache(void) {
|
||||
s_cache_suspend_cnt--;
|
||||
assert(s_cache_suspend_cnt >= 0 && "cache resume doesn't match suspend ops");
|
||||
assert(s_cache_suspend_cnt >= 0 && DRAM_STR("cache resume doesn't match suspend ops"));
|
||||
if (s_cache_suspend_cnt == 0) {
|
||||
cache_hal_resume(CACHE_TYPE_ALL);
|
||||
}
|
||||
@@ -427,7 +429,7 @@ static void IRAM_ATTR flush_uarts(void)
|
||||
#ifdef CONFIG_IDF_TARGET_ESP32
|
||||
esp_rom_uart_tx_wait_idle(i);
|
||||
#else
|
||||
if (periph_ll_periph_enabled(PERIPH_UART0_MODULE + i)) {
|
||||
if (periph_ll_uart_enabled(i)) {
|
||||
esp_rom_uart_tx_wait_idle(i);
|
||||
}
|
||||
#endif
|
||||
@@ -437,14 +439,15 @@ static void IRAM_ATTR flush_uarts(void)
|
||||
static uint32_t s_suspended_uarts_bmap = 0;
|
||||
|
||||
/**
|
||||
* Suspend enabled uarts and return suspended uarts bit map
|
||||
* Suspend enabled uarts and return suspended uarts bit map.
|
||||
* Must be called from critical sections.
|
||||
*/
|
||||
static IRAM_ATTR void suspend_uarts(void)
|
||||
FORCE_INLINE_ATTR void suspend_uarts(void)
|
||||
{
|
||||
s_suspended_uarts_bmap = 0;
|
||||
for (int i = 0; i < SOC_UART_HP_NUM; ++i) {
|
||||
#ifndef CONFIG_IDF_TARGET_ESP32
|
||||
if (!periph_ll_periph_enabled(PERIPH_UART0_MODULE + i)) {
|
||||
if (!periph_ll_uart_enabled(i)) {
|
||||
continue;
|
||||
}
|
||||
#endif
|
||||
@@ -461,7 +464,8 @@ static IRAM_ATTR void suspend_uarts(void)
|
||||
}
|
||||
}
|
||||
|
||||
static void IRAM_ATTR resume_uarts(void)
|
||||
// Must be called from critical sections
|
||||
FORCE_INLINE_ATTR void resume_uarts(void)
|
||||
{
|
||||
for (int i = 0; i < SOC_UART_HP_NUM; ++i) {
|
||||
if (s_suspended_uarts_bmap & 0x1) {
|
||||
@@ -487,7 +491,7 @@ static void IRAM_ATTR resume_uarts(void)
|
||||
completion time has exceeded the wakeup time, we should abandon the flush, skip the sleep and
|
||||
return ESP_ERR_SLEEP_REJECT.
|
||||
*/
|
||||
static bool light_sleep_uart_prepare(uint32_t pd_flags, int64_t sleep_duration)
|
||||
FORCE_INLINE_ATTR bool light_sleep_uart_prepare(uint32_t pd_flags, int64_t sleep_duration)
|
||||
{
|
||||
bool should_skip_sleep = false;
|
||||
#if !SOC_PM_SUPPORT_TOP_PD
|
||||
@@ -513,7 +517,7 @@ static bool light_sleep_uart_prepare(uint32_t pd_flags, int64_t sleep_duration)
|
||||
/**
|
||||
* These save-restore workaround should be moved to lower layer
|
||||
*/
|
||||
inline static void IRAM_ATTR misc_modules_sleep_prepare(bool deep_sleep)
|
||||
FORCE_INLINE_ATTR void misc_modules_sleep_prepare(bool deep_sleep)
|
||||
{
|
||||
if (deep_sleep){
|
||||
for (int n = 0; n < MAX_DSLP_HOOKS; n++) {
|
||||
@@ -548,7 +552,7 @@ inline static void IRAM_ATTR misc_modules_sleep_prepare(bool deep_sleep)
|
||||
/**
|
||||
* These save-restore workaround should be moved to lower layer
|
||||
*/
|
||||
inline static void IRAM_ATTR misc_modules_wake_prepare(void)
|
||||
FORCE_INLINE_ATTR void misc_modules_wake_prepare(void)
|
||||
{
|
||||
#if SOC_PM_RETENTION_HAS_REGDMA_POWER_BUG
|
||||
sleep_retention_do_system_retention(false);
|
||||
@@ -746,7 +750,7 @@ static esp_err_t IRAM_ATTR esp_sleep_start(uint32_t pd_flags, esp_sleep_mode_t m
|
||||
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)
|
||||
#if !CONFIG_IDF_TARGET_ESP32H2 // ESP32H2 TODO IDF-7359: related rtcio ll func not supported yet
|
||||
if(!(pd_flags & PMU_SLEEP_PD_VDDSDIO)) {
|
||||
if(!(pd_flags & RTC_SLEEP_PD_VDDSDIO)) {
|
||||
/* Cache Suspend 1: will wait cache idle in cache suspend, also means SPI bus IDLE, then we can hold SPI CS pin safely*/
|
||||
suspend_cache();
|
||||
gpio_ll_hold_en(&GPIO, SPI_CS0_GPIO_NUM);
|
||||
@@ -769,7 +773,7 @@ static esp_err_t IRAM_ATTR esp_sleep_start(uint32_t pd_flags, esp_sleep_mode_t m
|
||||
/* Unhold the SPI CS pin */
|
||||
#if (CONFIG_PM_POWER_DOWN_PERIPHERAL_IN_LIGHT_SLEEP && CONFIG_ESP_SLEEP_FLASH_LEAKAGE_WORKAROUND)
|
||||
#if !CONFIG_IDF_TARGET_ESP32H2 // ESP32H2 TODO IDF-7359: related rtcio ll func not supported yet
|
||||
if(!(pd_flags & PMU_SLEEP_PD_VDDSDIO)) {
|
||||
if(!(pd_flags & RTC_SLEEP_PD_VDDSDIO)) {
|
||||
gpio_ll_hold_dis(&GPIO, SPI_CS0_GPIO_NUM);
|
||||
/* Cache Resume 1: Resume cache for continue running*/
|
||||
resume_cache();
|
||||
@@ -949,7 +953,7 @@ static esp_err_t esp_light_sleep_inner(uint32_t pd_flags,
|
||||
* x | 1 | pd flash with relaxed conditions(force_pd)
|
||||
* 1 | 0 | pd flash with strict conditions(safe_pd)
|
||||
*/
|
||||
static inline bool can_power_down_vddsdio(uint32_t pd_flags, const uint32_t vddsdio_pd_sleep_duration)
|
||||
FORCE_INLINE_ATTR bool can_power_down_vddsdio(uint32_t pd_flags, const uint32_t vddsdio_pd_sleep_duration)
|
||||
{
|
||||
bool force_pd = !(s_config.wakeup_triggers & RTC_TIMER_TRIG_EN) || (s_config.sleep_duration > vddsdio_pd_sleep_duration);
|
||||
bool safe_pd = (s_config.wakeup_triggers == RTC_TIMER_TRIG_EN) && (s_config.sleep_duration > vddsdio_pd_sleep_duration);
|
||||
@@ -1702,7 +1706,7 @@ esp_err_t esp_sleep_pd_config(esp_sleep_pd_domain_t domain, esp_sleep_pd_option_
|
||||
* the XTAL clock control of some chips(esp32c6/esp32h2) depends on the top domain.
|
||||
*/
|
||||
#if SOC_PM_SUPPORT_TOP_PD
|
||||
static inline bool top_domain_pd_allowed(void) {
|
||||
FORCE_INLINE_ATTR bool top_domain_pd_allowed(void) {
|
||||
return (cpu_domain_pd_allowed() && \
|
||||
clock_domain_pd_allowed() && \
|
||||
peripheral_domain_pd_allowed() && \
|
||||
@@ -1794,7 +1798,7 @@ static uint32_t get_power_down_flags(void)
|
||||
s_config.domain[ESP_PD_DOMAIN_XTAL].pd_option = ESP_PD_OPTION_OFF;
|
||||
#endif
|
||||
|
||||
const __attribute__((unused)) char *option_str[] = {"OFF", "ON", "AUTO(OFF)" /* Auto works as OFF */};
|
||||
const __attribute__((unused)) char *option_str[] = {DRAM_STR("OFF"), DRAM_STR("ON"), DRAM_STR("AUTO(OFF)") /* Auto works as OFF */};
|
||||
/* This function is called from a critical section, log with ESP_EARLY_LOGD. */
|
||||
#if SOC_PM_SUPPORT_RTC_PERIPH_PD
|
||||
ESP_EARLY_LOGD(TAG, "RTC_PERIPH: %s", option_str[s_config.domain[ESP_PD_DOMAIN_RTC_PERIPH].pd_option]);
|
||||
|
Reference in New Issue
Block a user