From fe5d294f6cd4a1d3a65f09dcb238bf4c69a72397 Mon Sep 17 00:00:00 2001 From: Ivan Grokhotkov Date: Tue, 27 Mar 2018 10:51:07 +0800 Subject: [PATCH] pm: handle changes to the PM_MODE_ACTIVE frequency The issue would manifest itself in cases when switching from PM configuration like {active=160MHz, idle=80MHz} to {active=80MHz, idle=80Mhz}. After the configuration was changed, PM logic would think that current frequency was 80MHz and would not do any further switching. In fact, frequency was still 160MHz. --- components/esp32/pm_esp32.c | 17 ++++++++++++++++- 1 file changed, 16 insertions(+), 1 deletion(-) diff --git a/components/esp32/pm_esp32.c b/components/esp32/pm_esp32.c index 6f848f250..c866bd146 100644 --- a/components/esp32/pm_esp32.c +++ b/components/esp32/pm_esp32.c @@ -110,6 +110,13 @@ static const char* s_freq_names[] __attribute__((unused)) = { /* Whether automatic light sleep is enabled. Currently always false */ static bool s_light_sleep_en = false; +/* When configuration is changed, current frequency may not match the + * newly configured frequency for the current mode. This is an indicator + * to the mode switch code to get the actual current frequency instead of + * relying on the current mode. + */ +static bool s_config_changed = false; + #ifdef WITH_PROFILING /* Time, in microseconds, spent so far in each mode */ static pm_time_t s_time_in_mode[PM_MODE_COUNT]; @@ -209,6 +216,7 @@ esp_err_t esp_pm_configure(const void* vconfig) s_cpu_freq_by_mode[PM_MODE_APB_MIN] = min_freq; s_cpu_freq_by_mode[PM_MODE_LIGHT_SLEEP] = min_freq; s_light_sleep_en = config->light_sleep_enable; + s_config_changed = true; portEXIT_CRITICAL(&s_switch_lock); return ESP_OK; @@ -343,10 +351,17 @@ static void IRAM_ATTR do_switch(pm_mode_t new_mode) } while (true); s_new_mode = new_mode; s_is_switching = true; + bool config_changed = s_config_changed; + s_config_changed = false; portEXIT_CRITICAL_ISR(&s_switch_lock); - rtc_cpu_freq_t old_freq = s_cpu_freq_by_mode[s_mode]; rtc_cpu_freq_t new_freq = s_cpu_freq_by_mode[new_mode]; + rtc_cpu_freq_t old_freq; + if (!config_changed) { + old_freq = s_cpu_freq_by_mode[s_mode]; + } else { + old_freq = rtc_clk_cpu_freq_get(); + } if (new_freq != old_freq) { uint32_t old_ticks_per_us = g_ticks_per_us_pro;