From 03477a59db6bd304630078b6fc1808e80485a02d Mon Sep 17 00:00:00 2001 From: songruojing Date: Fri, 27 May 2022 21:54:34 +0800 Subject: [PATCH] rtc_clk: Fix rtc8m calibration failure after cpu/core reset 1. make sure 8md256 clk is enabled before calibration 2. improve bootloader and application startup 8m, 8md256 enable logic --- components/esp_hw_support/port/esp32/rtc_clk_init.c | 11 +++++++---- components/esp_hw_support/port/esp32/rtc_time.c | 4 ++++ components/esp_hw_support/port/esp32c2/rtc_clk_init.c | 10 +++++++--- components/esp_hw_support/port/esp32c2/rtc_time.c | 4 ++++ components/esp_hw_support/port/esp32c3/rtc_clk_init.c | 11 +++++++---- components/esp_hw_support/port/esp32c3/rtc_time.c | 4 ++++ components/esp_hw_support/port/esp32s2/rtc_clk_init.c | 11 +++++++---- components/esp_hw_support/port/esp32s2/rtc_time.c | 4 ++++ components/esp_hw_support/port/esp32s3/rtc_clk_init.c | 11 +++++++---- components/esp_hw_support/port/esp32s3/rtc_time.c | 4 ++++ components/esp_system/port/soc/esp32/clk.c | 2 ++ components/esp_system/port/soc/esp32c2/clk.c | 2 ++ components/esp_system/port/soc/esp32c3/clk.c | 2 ++ components/esp_system/port/soc/esp32s2/clk.c | 2 ++ components/esp_system/port/soc/esp32s3/clk.c | 2 ++ 15 files changed, 65 insertions(+), 19 deletions(-) diff --git a/components/esp_hw_support/port/esp32/rtc_clk_init.c b/components/esp_hw_support/port/esp32/rtc_clk_init.c index 70551cc9df..31c63e4267 100644 --- a/components/esp_hw_support/port/esp32/rtc_clk_init.c +++ b/components/esp_hw_support/port/esp32/rtc_clk_init.c @@ -125,13 +125,16 @@ void rtc_clk_init(rtc_clk_config_t cfg) cpu_hal_set_cycle_count( (uint64_t)cpu_hal_get_cycle_count() * cfg.cpu_freq_mhz / freq_before ); /* Slow & fast clocks setup */ + // We will not power off RC_FAST in bootloader stage even if it is not being used as any + // cpu / rtc_fast / rtc_slow clock sources, this is because RNG always needs it in the bootloader stage. + bool need_rc_fast_en = true; + bool need_rc_fast_d256_en = false; if (cfg.slow_clk_src == SOC_RTC_SLOW_CLK_SRC_XTAL32K) { rtc_clk_32k_enable(true); + } else if (cfg.slow_clk_src == SOC_RTC_SLOW_CLK_SRC_RC_FAST_D256) { + need_rc_fast_d256_en = true; } - if (cfg.fast_clk_src == SOC_RTC_FAST_CLK_SRC_RC_FAST) { - bool need_8md256 = cfg.slow_clk_src == SOC_RTC_SLOW_CLK_SRC_RC_FAST_D256; - rtc_clk_8m_enable(true, need_8md256); - } + rtc_clk_8m_enable(need_rc_fast_en, need_rc_fast_d256_en); rtc_clk_fast_src_set(cfg.fast_clk_src); rtc_clk_slow_src_set(cfg.slow_clk_src); } diff --git a/components/esp_hw_support/port/esp32/rtc_time.c b/components/esp_hw_support/port/esp32/rtc_time.c index 777b5a9a4d..96d64a6d32 100644 --- a/components/esp_hw_support/port/esp32/rtc_time.c +++ b/components/esp_hw_support/port/esp32/rtc_time.c @@ -40,7 +40,10 @@ static uint32_t rtc_clk_cal_internal(rtc_cal_sel_t cal_clk, uint32_t slowclk_cyc clk_ll_xtal32k_digi_enable(); } + bool rc_fast_enabled = clk_ll_rc_fast_is_enabled(); + bool rc_fast_d256_enabled = clk_ll_rc_fast_d256_is_enabled(); if (cal_clk == RTC_CAL_8MD256) { + rtc_clk_8m_enable(true, true); clk_ll_rc_fast_d256_digi_enable(); } /* Prepare calibration */ @@ -94,6 +97,7 @@ static uint32_t rtc_clk_cal_internal(rtc_cal_sel_t cal_clk, uint32_t slowclk_cyc if (cal_clk == RTC_CAL_8MD256) { clk_ll_rc_fast_d256_digi_disable(); + rtc_clk_8m_enable(rc_fast_enabled, rc_fast_d256_enabled); } if (timeout_us == 0) { /* timed out waiting for calibration */ diff --git a/components/esp_hw_support/port/esp32c2/rtc_clk_init.c b/components/esp_hw_support/port/esp32c2/rtc_clk_init.c index bc3eac0d2a..fabfe3acb6 100644 --- a/components/esp_hw_support/port/esp32c2/rtc_clk_init.c +++ b/components/esp_hw_support/port/esp32c2/rtc_clk_init.c @@ -67,10 +67,14 @@ void rtc_clk_init(rtc_clk_config_t cfg) cpu_hal_set_cycle_count( (uint64_t)cpu_hal_get_cycle_count() * cfg.cpu_freq_mhz / freq_before ); /* Slow & fast clocks setup */ - if (cfg.fast_clk_src == SOC_RTC_FAST_CLK_SRC_RC_FAST) { - bool need_8md256 = cfg.slow_clk_src == SOC_RTC_SLOW_CLK_SRC_RC_FAST_D256; - rtc_clk_8m_enable(true, need_8md256); + // We will not power off RC_FAST in bootloader stage even if it is not being used as any + // cpu / rtc_fast / rtc_slow clock sources, this is because RNG always needs it in the bootloader stage. + bool need_rc_fast_en = true; + bool need_rc_fast_d256_en = false; + if (cfg.slow_clk_src == SOC_RTC_SLOW_CLK_SRC_RC_FAST_D256) { + need_rc_fast_d256_en = true; } + rtc_clk_8m_enable(need_rc_fast_en, need_rc_fast_d256_en); rtc_clk_fast_src_set(cfg.fast_clk_src); rtc_clk_slow_src_set(cfg.slow_clk_src); } diff --git a/components/esp_hw_support/port/esp32c2/rtc_time.c b/components/esp_hw_support/port/esp32c2/rtc_time.c index a48a7af301..600f0d16cb 100644 --- a/components/esp_hw_support/port/esp32c2/rtc_time.c +++ b/components/esp_hw_support/port/esp32c2/rtc_time.c @@ -51,7 +51,10 @@ uint32_t rtc_clk_cal_internal(rtc_cal_sel_t cal_clk, uint32_t slowclk_cycles) clk_ll_xtal32k_digi_enable(); } + bool rc_fast_enabled = clk_ll_rc_fast_is_enabled(); + bool rc_fast_d256_enabled = clk_ll_rc_fast_d256_is_enabled(); if (cal_clk == RTC_CAL_8MD256) { + rtc_clk_8m_enable(true, true); clk_ll_rc_fast_d256_digi_enable(); } /* Prepare calibration */ @@ -107,6 +110,7 @@ uint32_t rtc_clk_cal_internal(rtc_cal_sel_t cal_clk, uint32_t slowclk_cycles) if (cal_clk == RTC_CAL_8MD256) { clk_ll_rc_fast_d256_digi_disable(); + rtc_clk_8m_enable(rc_fast_enabled, rc_fast_d256_enabled); } return cal_val; diff --git a/components/esp_hw_support/port/esp32c3/rtc_clk_init.c b/components/esp_hw_support/port/esp32c3/rtc_clk_init.c index 68687ba005..86907937d6 100644 --- a/components/esp_hw_support/port/esp32c3/rtc_clk_init.c +++ b/components/esp_hw_support/port/esp32c3/rtc_clk_init.c @@ -67,13 +67,16 @@ void rtc_clk_init(rtc_clk_config_t cfg) cpu_hal_set_cycle_count( (uint64_t)cpu_hal_get_cycle_count() * cfg.cpu_freq_mhz / freq_before ); /* Slow & fast clocks setup */ + // We will not power off RC_FAST in bootloader stage even if it is not being used as any + // cpu / rtc_fast / rtc_slow clock sources, this is because RNG always needs it in the bootloader stage. + bool need_rc_fast_en = true; + bool need_rc_fast_d256_en = false; if (cfg.slow_clk_src == SOC_RTC_SLOW_CLK_SRC_XTAL32K) { rtc_clk_32k_enable(true); + } else if (cfg.slow_clk_src == SOC_RTC_SLOW_CLK_SRC_RC_FAST_D256) { + need_rc_fast_d256_en = true; } - if (cfg.fast_clk_src == SOC_RTC_FAST_CLK_SRC_RC_FAST) { - bool need_8md256 = cfg.slow_clk_src == SOC_RTC_SLOW_CLK_SRC_RC_FAST_D256; - rtc_clk_8m_enable(true, need_8md256); - } + rtc_clk_8m_enable(need_rc_fast_en, need_rc_fast_d256_en); rtc_clk_fast_src_set(cfg.fast_clk_src); rtc_clk_slow_src_set(cfg.slow_clk_src); } diff --git a/components/esp_hw_support/port/esp32c3/rtc_time.c b/components/esp_hw_support/port/esp32c3/rtc_time.c index 22ef6169bf..8e9d9e7872 100644 --- a/components/esp_hw_support/port/esp32c3/rtc_time.c +++ b/components/esp_hw_support/port/esp32c3/rtc_time.c @@ -55,7 +55,10 @@ uint32_t rtc_clk_cal_internal(rtc_cal_sel_t cal_clk, uint32_t slowclk_cycles) clk_ll_xtal32k_digi_enable(); } + bool rc_fast_enabled = clk_ll_rc_fast_is_enabled(); + bool rc_fast_d256_enabled = clk_ll_rc_fast_d256_is_enabled(); if (cal_clk == RTC_CAL_8MD256) { + rtc_clk_8m_enable(true, true); clk_ll_rc_fast_d256_digi_enable(); } /* There may be another calibration process already running during we call this function, @@ -116,6 +119,7 @@ uint32_t rtc_clk_cal_internal(rtc_cal_sel_t cal_clk, uint32_t slowclk_cycles) if (cal_clk == RTC_CAL_8MD256) { clk_ll_rc_fast_d256_digi_disable(); + rtc_clk_8m_enable(rc_fast_enabled, rc_fast_d256_enabled); } return cal_val; diff --git a/components/esp_hw_support/port/esp32s2/rtc_clk_init.c b/components/esp_hw_support/port/esp32s2/rtc_clk_init.c index 98a472481b..9c4378351a 100644 --- a/components/esp_hw_support/port/esp32s2/rtc_clk_init.c +++ b/components/esp_hw_support/port/esp32s2/rtc_clk_init.c @@ -67,13 +67,16 @@ void rtc_clk_init(rtc_clk_config_t cfg) cpu_hal_set_cycle_count( (uint64_t)cpu_hal_get_cycle_count() * cfg.cpu_freq_mhz / freq_before ); /* Slow & fast clocks setup */ + // We will not power off RC_FAST in bootloader stage even if it is not being used as any + // cpu / rtc_fast / rtc_slow clock sources, this is because RNG always needs it in the bootloader stage. + bool need_rc_fast_en = true; + bool need_rc_fast_d256_en = false; if (cfg.slow_clk_src == SOC_RTC_SLOW_CLK_SRC_XTAL32K) { rtc_clk_32k_enable(true); + } else if (cfg.slow_clk_src == SOC_RTC_SLOW_CLK_SRC_RC_FAST_D256) { + need_rc_fast_d256_en = true; } - if (cfg.fast_clk_src == SOC_RTC_FAST_CLK_SRC_RC_FAST) { - bool need_8md256 = cfg.slow_clk_src == SOC_RTC_SLOW_CLK_SRC_RC_FAST_D256; - rtc_clk_8m_enable(true, need_8md256); - } + rtc_clk_8m_enable(need_rc_fast_en, need_rc_fast_d256_en); rtc_clk_fast_src_set(cfg.fast_clk_src); rtc_clk_slow_src_set(cfg.slow_clk_src); } diff --git a/components/esp_hw_support/port/esp32s2/rtc_time.c b/components/esp_hw_support/port/esp32s2/rtc_time.c index e2209da9bb..3fd21be81b 100644 --- a/components/esp_hw_support/port/esp32s2/rtc_time.c +++ b/components/esp_hw_support/port/esp32s2/rtc_time.c @@ -157,7 +157,10 @@ uint32_t rtc_clk_cal_internal(rtc_cal_sel_t cal_clk, uint32_t slowclk_cycles, ui clk_ll_xtal32k_digi_enable(); } + bool rc_fast_enabled = clk_ll_rc_fast_is_enabled(); + bool rc_fast_d256_enabled = clk_ll_rc_fast_d256_is_enabled(); if (cal_clk == RTC_CAL_8MD256) { + rtc_clk_8m_enable(true, true); clk_ll_rc_fast_d256_digi_enable(); } @@ -177,6 +180,7 @@ uint32_t rtc_clk_cal_internal(rtc_cal_sel_t cal_clk, uint32_t slowclk_cycles, ui if (cal_clk == RTC_CAL_8MD256) { clk_ll_rc_fast_d256_digi_disable(); + rtc_clk_8m_enable(rc_fast_enabled, rc_fast_d256_enabled); } return cal_val; diff --git a/components/esp_hw_support/port/esp32s3/rtc_clk_init.c b/components/esp_hw_support/port/esp32s3/rtc_clk_init.c index 88c21a7f89..7d16112e62 100644 --- a/components/esp_hw_support/port/esp32s3/rtc_clk_init.c +++ b/components/esp_hw_support/port/esp32s3/rtc_clk_init.c @@ -63,13 +63,16 @@ void rtc_clk_init(rtc_clk_config_t cfg) cpu_hal_set_cycle_count( (uint64_t)cpu_hal_get_cycle_count() * cfg.cpu_freq_mhz / freq_before ); /* Slow & fast clocks setup */ + // We will not power off RC_FAST in bootloader stage even if it is not being used as any + // cpu / rtc_fast / rtc_slow clock sources, this is because RNG always needs it in the bootloader stage. + bool need_rc_fast_en = true; + bool need_rc_fast_d256_en = false; if (cfg.slow_clk_src == SOC_RTC_SLOW_CLK_SRC_XTAL32K) { rtc_clk_32k_enable(true); + } else if (cfg.slow_clk_src == SOC_RTC_SLOW_CLK_SRC_RC_FAST_D256) { + need_rc_fast_d256_en = true; } - if (cfg.fast_clk_src == SOC_RTC_FAST_CLK_SRC_RC_FAST) { - bool need_8md256 = cfg.slow_clk_src == SOC_RTC_SLOW_CLK_SRC_RC_FAST_D256; - rtc_clk_8m_enable(true, need_8md256); - } + rtc_clk_8m_enable(need_rc_fast_en, need_rc_fast_d256_en); rtc_clk_fast_src_set(cfg.fast_clk_src); rtc_clk_slow_src_set(cfg.slow_clk_src); } diff --git a/components/esp_hw_support/port/esp32s3/rtc_time.c b/components/esp_hw_support/port/esp32s3/rtc_time.c index 68eb091c03..5e9bb8faf8 100644 --- a/components/esp_hw_support/port/esp32s3/rtc_time.c +++ b/components/esp_hw_support/port/esp32s3/rtc_time.c @@ -53,7 +53,10 @@ uint32_t rtc_clk_cal_internal(rtc_cal_sel_t cal_clk, uint32_t slowclk_cycles) clk_ll_xtal32k_digi_enable(); } + bool rc_fast_enabled = clk_ll_rc_fast_is_enabled(); + bool rc_fast_d256_enabled = clk_ll_rc_fast_d256_is_enabled(); if (cal_clk == RTC_CAL_8MD256) { + rtc_clk_8m_enable(true, true); clk_ll_rc_fast_d256_digi_enable(); } /* There may be another calibration process already running during we call this function, @@ -114,6 +117,7 @@ uint32_t rtc_clk_cal_internal(rtc_cal_sel_t cal_clk, uint32_t slowclk_cycles) if (cal_clk == RTC_CAL_8MD256) { clk_ll_rc_fast_d256_digi_disable(); + rtc_clk_8m_enable(rc_fast_enabled, rc_fast_d256_enabled); } return cal_val; diff --git a/components/esp_system/port/soc/esp32/clk.c b/components/esp_system/port/soc/esp32/clk.c index 80f7e3acee..0c14307c58 100644 --- a/components/esp_system/port/soc/esp32/clk.c +++ b/components/esp_system/port/soc/esp32/clk.c @@ -131,6 +131,8 @@ static void select_rtc_slow_clk(slow_clk_sel_t slow_clk) assert(rtc_clk_xtal_freq_get() != RTC_XTAL_FREQ_AUTO); #endif + bool rc_fast_d256_is_enabled = rtc_clk_8md256_enabled(); + rtc_clk_8m_enable(true, rc_fast_d256_is_enabled); rtc_clk_fast_src_set(SOC_RTC_FAST_CLK_SRC_RC_FAST); #ifdef CONFIG_BOOTLOADER_WDT_ENABLE diff --git a/components/esp_system/port/soc/esp32c2/clk.c b/components/esp_system/port/soc/esp32c2/clk.c index ad4d6d992f..29991272b2 100644 --- a/components/esp_system/port/soc/esp32c2/clk.c +++ b/components/esp_system/port/soc/esp32c2/clk.c @@ -73,6 +73,8 @@ static const char *TAG = "clk"; assert(rtc_clk_xtal_freq_get() == RTC_XTAL_FREQ_40M); + bool rc_fast_d256_is_enabled = rtc_clk_8md256_enabled(); + rtc_clk_8m_enable(true, rc_fast_d256_is_enabled); rtc_clk_fast_src_set(SOC_RTC_FAST_CLK_SRC_RC_FAST); #endif diff --git a/components/esp_system/port/soc/esp32c3/clk.c b/components/esp_system/port/soc/esp32c3/clk.c index 7d608c91c6..78ca15502c 100644 --- a/components/esp_system/port/soc/esp32c3/clk.c +++ b/components/esp_system/port/soc/esp32c3/clk.c @@ -75,6 +75,8 @@ static const char *TAG = "clk"; assert(rtc_clk_xtal_freq_get() == RTC_XTAL_FREQ_40M); + bool rc_fast_d256_is_enabled = rtc_clk_8md256_enabled(); + rtc_clk_8m_enable(true, rc_fast_d256_is_enabled); rtc_clk_fast_src_set(SOC_RTC_FAST_CLK_SRC_RC_FAST); #endif diff --git a/components/esp_system/port/soc/esp32s2/clk.c b/components/esp_system/port/soc/esp32s2/clk.c index 98cffe9638..a14c64e861 100644 --- a/components/esp_system/port/soc/esp32s2/clk.c +++ b/components/esp_system/port/soc/esp32s2/clk.c @@ -74,6 +74,8 @@ static void select_rtc_slow_clk(slow_clk_sel_t slow_clk); } rtc_init(cfg); + bool rc_fast_d256_is_enabled = rtc_clk_8md256_enabled(); + rtc_clk_8m_enable(true, rc_fast_d256_is_enabled); rtc_clk_fast_src_set(SOC_RTC_FAST_CLK_SRC_RC_FAST); #ifdef CONFIG_BOOTLOADER_WDT_ENABLE diff --git a/components/esp_system/port/soc/esp32s3/clk.c b/components/esp_system/port/soc/esp32s3/clk.c index e5d1282e05..e8639004be 100644 --- a/components/esp_system/port/soc/esp32s3/clk.c +++ b/components/esp_system/port/soc/esp32s3/clk.c @@ -72,6 +72,8 @@ static void select_rtc_slow_clk(slow_clk_sel_t slow_clk); assert(rtc_clk_xtal_freq_get() == RTC_XTAL_FREQ_40M); + bool rc_fast_d256_is_enabled = rtc_clk_8md256_enabled(); + rtc_clk_8m_enable(true, rc_fast_d256_is_enabled); rtc_clk_fast_src_set(SOC_RTC_FAST_CLK_SRC_RC_FAST); #ifdef CONFIG_BOOTLOADER_WDT_ENABLE