]> granicus.if.org Git - esp-idf/commitdiff
pm: fix incorrect configuration at startup
authorIvan Grokhotkov <ivan@espressif.com>
Tue, 20 Mar 2018 10:06:58 +0000 (18:06 +0800)
committerIvan Grokhotkov <ivan@espressif.com>
Tue, 20 Mar 2018 10:06:58 +0000 (18:06 +0800)
s_cpu_freq_by_mode array was statically initialised with 80MHz CPU
frequency in CPU_MAX and APB_MAX modes, but sdkconfig setting for the
CPU frequency could have been different. For the case of 240MHz CPU
frequency, this would cause a frequency switch between 240MHz and
80MHz to happen, even though such switch is not supported in the fast
path switching functions used by the DFS implementation.

This fixes the issue by moving initialisation into esp_pm_impl_init,
which is called at startup before the first mode switch can happen.

Fixes https://github.com/espressif/esp-idf/issues/1729.

components/esp32/pm_esp32.c

index 5866484a7af906f20b79423687ba379d5a545cd4..8a1005f43f1fa2c7082f5393ea0c29a53c647a66 100644 (file)
@@ -82,14 +82,9 @@ static bool s_core_idle[portNUM_PROCESSORS];
 extern uint32_t g_ticks_per_us_pro;
 
 /* Lookup table of CPU frequencies to be used in each mode.
- * Modified by esp_pm_configure.
+ * Initialized by esp_pm_impl_init and modified by esp_pm_configure.
  */
-rtc_cpu_freq_t s_cpu_freq_by_mode[PM_MODE_COUNT] = {
-        [PM_MODE_LIGHT_SLEEP] = (rtc_cpu_freq_t) -1, /* unused */
-        [PM_MODE_APB_MIN] = RTC_CPU_FREQ_XTAL,
-        [PM_MODE_APB_MAX] = RTC_CPU_FREQ_80M,
-        [PM_MODE_CPU_MAX] = RTC_CPU_FREQ_80M,
-};
+rtc_cpu_freq_t s_cpu_freq_by_mode[PM_MODE_COUNT];
 
 /* Lookup table of CPU ticks per microsecond for each RTC_CPU_FREQ_ value.
  * Essentially the same as returned by rtc_clk_cpu_freq_value(), but without
@@ -192,6 +187,7 @@ esp_err_t esp_pm_configure(const void* vconfig)
     s_cpu_freq_by_mode[PM_MODE_CPU_MAX] = max_freq;
     s_cpu_freq_by_mode[PM_MODE_APB_MAX] = apb_max_freq;
     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;
     portEXIT_CRITICAL(&s_switch_lock);
 
@@ -452,5 +448,14 @@ void esp_pm_impl_init()
     ESP_ERROR_CHECK(esp_pm_lock_create(ESP_PM_CPU_FREQ_MAX, 0, "rtos1",
             &s_rtos_lock_handle[1]));
     ESP_ERROR_CHECK(esp_pm_lock_acquire(s_rtos_lock_handle[1]));
+
+    /* Configure all modes to use the default CPU frequency.
+     * This will be modified later by a call to esp_pm_configure.
+     */
+    rtc_cpu_freq_t default_freq;
+    assert(rtc_clk_cpu_freq_from_mhz(CONFIG_ESP32_DEFAULT_CPU_FREQ_MHZ, &default_freq));
+    for (size_t i = 0; i < PM_MODE_COUNT; ++i) {
+        s_cpu_freq_by_mode[i] = default_freq;
+    }
 #endif // portNUM_PROCESSORS == 2
 }