Explorar o código

Merge branch 'bugfix/fix_rc_fast_calibration' into 'master'

rtc_clk: fix esp32c6/esp32h2 eco chip `RC_FAST` bad calibration value

Closes WIFI-5938

See merge request espressif/esp-idf!23927
Li Shuai %!s(int64=2) %!d(string=hai) anos
pai
achega
e505e19798

+ 29 - 10
components/esp_hw_support/port/esp32c6/rtc_time.c

@@ -39,7 +39,25 @@ static const char *TAG = "rtc_time";
 #define TIMG_RTC_CALI_CLK_SEL_RC_FAST 1
 #define TIMG_RTC_CALI_CLK_SEL_32K     2
 
-uint32_t rtc_clk_cal_internal(rtc_cal_sel_t cal_clk, uint32_t slowclk_cycles)
+/**
+ * @brief Clock calibration function used by rtc_clk_cal
+ *
+ * Calibration of RTC_SLOW_CLK is performed using a special feature of TIMG0.
+ * This feature counts the number of XTAL clock cycles within a given number of
+ * RTC_SLOW_CLK cycles.
+ *
+ * Slow clock calibration feature has two modes of operation: one-off and cycling.
+ * In cycling mode (which is enabled by default on SoC reset), counting of XTAL
+ * cycles within RTC_SLOW_CLK cycle is done continuously. Cycling mode is enabled
+ * using TIMG_RTC_CALI_START_CYCLING bit. In one-off mode counting is performed
+ * once, and TIMG_RTC_CALI_RDY bit is set when counting is done. One-off mode is
+ * enabled using TIMG_RTC_CALI_START bit.
+ *
+ * @param cal_clk which clock to calibrate
+ * @param slowclk_cycles number of slow clock cycles to count
+ * @return number of XTAL clock cycles within the given number of slow clock cycles
+ */
+static uint32_t rtc_clk_cal_internal(rtc_cal_sel_t cal_clk, uint32_t slowclk_cycles)
 {
     assert(slowclk_cycles < TIMG_RTC_CALI_MAX_V);
 
@@ -103,15 +121,6 @@ uint32_t rtc_clk_cal_internal(rtc_cal_sel_t cal_clk, uint32_t slowclk_cycles)
                && !GET_PERI_REG_MASK(TIMG_RTCCALICFG2_REG(0), TIMG_RTC_CALI_TIMEOUT));
     }
 
-    /*The Fosc CLK of calibration circuit is divided by 32 for ECO1.
-      So we need to divide the calibrate cycles of the FOSC for ECO1 and above chips by 32 to
-      avoid excessive calibration time.*/
-    if (ESP_CHIP_REV_ABOVE(efuse_hal_chip_revision(), 1)) {
-        if (cal_clk == RTC_CAL_RC_FAST) {
-            slowclk_cycles = slowclk_cycles >> 5;
-        }
-    }
-
     /* Prepare calibration */
     REG_SET_FIELD(TIMG_RTCCALICFG_REG(0), TIMG_RTC_CALI_CLK_SEL, cali_clk_sel);
     CLEAR_PERI_REG_MASK(TIMG_RTCCALICFG_REG(0), TIMG_RTC_CALI_START_CYCLING);
@@ -200,6 +209,16 @@ static bool rtc_clk_cal_32k_valid(rtc_xtal_freq_t xtal_freq, uint32_t slowclk_cy
 uint32_t rtc_clk_cal(rtc_cal_sel_t cal_clk, uint32_t slowclk_cycles)
 {
     rtc_xtal_freq_t xtal_freq = rtc_clk_xtal_freq_get();
+
+    /*The Fosc CLK of calibration circuit is divided by 32 for ECO1.
+      So we need to divide the calibrate cycles of the FOSC for ECO1 and above chips by 32 to
+      avoid excessive calibration time.*/
+    if (ESP_CHIP_REV_ABOVE(efuse_hal_chip_revision(), 1)) {
+        if (cal_clk == RTC_CAL_RC_FAST) {
+            slowclk_cycles = slowclk_cycles >> 5;
+        }
+    }
+
     uint64_t xtal_cycles = rtc_clk_cal_internal(cal_clk, slowclk_cycles);
 
     if (cal_clk == RTC_CAL_32K_XTAL && !rtc_clk_cal_32k_valid(xtal_freq, slowclk_cycles, xtal_cycles)) {

+ 29 - 10
components/esp_hw_support/port/esp32h2/rtc_time.c

@@ -38,7 +38,25 @@ static const char *TAG = "rtc_time";
 #define TIMG_RTC_CALI_CLK_SEL_RC_FAST 1
 #define TIMG_RTC_CALI_CLK_SEL_32K     2
 
-uint32_t rtc_clk_cal_internal(rtc_cal_sel_t cal_clk, uint32_t slowclk_cycles)
+/**
+ * @brief Clock calibration function used by rtc_clk_cal
+ *
+ * Calibration of RTC_SLOW_CLK is performed using a special feature of TIMG0.
+ * This feature counts the number of XTAL clock cycles within a given number of
+ * RTC_SLOW_CLK cycles.
+ *
+ * Slow clock calibration feature has two modes of operation: one-off and cycling.
+ * In cycling mode (which is enabled by default on SoC reset), counting of XTAL
+ * cycles within RTC_SLOW_CLK cycle is done continuously. Cycling mode is enabled
+ * using TIMG_RTC_CALI_START_CYCLING bit. In one-off mode counting is performed
+ * once, and TIMG_RTC_CALI_RDY bit is set when counting is done. One-off mode is
+ * enabled using TIMG_RTC_CALI_START bit.
+ *
+ * @param cal_clk which clock to calibrate
+ * @param slowclk_cycles number of slow clock cycles to count
+ * @return number of XTAL clock cycles within the given number of slow clock cycles
+ */
+static uint32_t rtc_clk_cal_internal(rtc_cal_sel_t cal_clk, uint32_t slowclk_cycles)
 {
     assert(slowclk_cycles < TIMG_RTC_CALI_MAX_V);
 
@@ -102,15 +120,6 @@ uint32_t rtc_clk_cal_internal(rtc_cal_sel_t cal_clk, uint32_t slowclk_cycles)
                && !GET_PERI_REG_MASK(TIMG_RTCCALICFG2_REG(0), TIMG_RTC_CALI_TIMEOUT));
     }
 
-    /*The Fosc CLK of calibration circuit is divided by 32 for ECO2.
-      So we need to divide the calibrate cycles of the FOSC for ECO1 and above chips by 32 to
-      avoid excessive calibration time.*/
-    if (ESP_CHIP_REV_ABOVE(efuse_hal_chip_revision(), 2)) {
-        if (cal_clk == RTC_CAL_RC_FAST) {
-            slowclk_cycles = slowclk_cycles >> 5;
-        }
-    }
-
     /* Prepare calibration */
     REG_SET_FIELD(TIMG_RTCCALICFG_REG(0), TIMG_RTC_CALI_CLK_SEL, cali_clk_sel);
     CLEAR_PERI_REG_MASK(TIMG_RTCCALICFG_REG(0), TIMG_RTC_CALI_START_CYCLING);
@@ -199,6 +208,16 @@ static bool rtc_clk_cal_32k_valid(rtc_xtal_freq_t xtal_freq, uint32_t slowclk_cy
 uint32_t rtc_clk_cal(rtc_cal_sel_t cal_clk, uint32_t slowclk_cycles)
 {
     rtc_xtal_freq_t xtal_freq = rtc_clk_xtal_freq_get();
+
+    /*The Fosc CLK of calibration circuit is divided by 32 for ECO2.
+      So we need to divide the calibrate cycles of the FOSC for ECO1 and above chips by 32 to
+      avoid excessive calibration time.*/
+    if (ESP_CHIP_REV_ABOVE(efuse_hal_chip_revision(), 2)) {
+        if (cal_clk == RTC_CAL_RC_FAST) {
+            slowclk_cycles = slowclk_cycles >> 5;
+        }
+    }
+
     uint64_t xtal_cycles = rtc_clk_cal_internal(cal_clk, slowclk_cycles);
 
     if (cal_clk == RTC_CAL_32K_XTAL && !rtc_clk_cal_32k_valid(xtal_freq, slowclk_cycles, xtal_cycles)) {

+ 0 - 20
components/soc/esp32c6/include/soc/rtc.h

@@ -392,26 +392,6 @@ void rtc_clk_cpu_freq_to_pll_and_pll_lock_release(int cpu_freq_mhz);
  */
 uint32_t rtc_clk_apb_freq_get(void);
 
-/**
- * @brief Clock calibration function used by rtc_clk_cal
- *
- * Calibration of RTC_SLOW_CLK is performed using a special feature of TIMG0.
- * This feature counts the number of XTAL clock cycles within a given number of
- * RTC_SLOW_CLK cycles.
- *
- * Slow clock calibration feature has two modes of operation: one-off and cycling.
- * In cycling mode (which is enabled by default on SoC reset), counting of XTAL
- * cycles within RTC_SLOW_CLK cycle is done continuously. Cycling mode is enabled
- * using TIMG_RTC_CALI_START_CYCLING bit. In one-off mode counting is performed
- * once, and TIMG_RTC_CALI_RDY bit is set when counting is done. One-off mode is
- * enabled using TIMG_RTC_CALI_START bit.
- *
- * @param cal_clk which clock to calibrate
- * @param slowclk_cycles number of slow clock cycles to count
- * @return number of XTAL clock cycles within the given number of slow clock cycles
- */
-uint32_t rtc_clk_cal_internal(rtc_cal_sel_t cal_clk, uint32_t slowclk_cycles);
-
 /**
  * @brief Measure RTC slow clock's period, based on main XTAL frequency
  *

+ 0 - 20
components/soc/esp32h2/include/soc/rtc.h

@@ -393,26 +393,6 @@ void rtc_clk_cpu_freq_set_xtal(void);
  */
 uint32_t rtc_clk_apb_freq_get(void);
 
-/**
- * @brief Clock calibration function used by rtc_clk_cal
- *
- * Calibration of RTC_SLOW_CLK is performed using a special feature of TIMG0.
- * This feature counts the number of XTAL clock cycles within a given number of
- * RTC_SLOW_CLK cycles.
- *
- * Slow clock calibration feature has two modes of operation: one-off and cycling.
- * In cycling mode (which is enabled by default on SoC reset), counting of XTAL
- * cycles within RTC_SLOW_CLK cycle is done continuously. Cycling mode is enabled
- * using TIMG_RTC_CALI_START_CYCLING bit. In one-off mode counting is performed
- * once, and TIMG_RTC_CALI_RDY bit is set when counting is done. One-off mode is
- * enabled using TIMG_RTC_CALI_START bit.
- *
- * @param cal_clk which clock to calibrate
- * @param slowclk_cycles number of slow clock cycles to count
- * @return number of XTAL clock cycles within the given number of slow clock cycles
- */
-uint32_t rtc_clk_cal_internal(rtc_cal_sel_t cal_clk, uint32_t slowclk_cycles);
-
 /**
  * @brief Measure RTC slow clock's period, based on main XTAL frequency
  *