mirror of
				https://github.com/espressif/esp-idf.git
				synced 2025-10-31 13:09:38 +00:00 
			
		
		
		
	esp_hw_support/clk_cali: fix xtal32k error detect
This commit is contained in:
		| @@ -117,10 +117,22 @@ uint32_t rtc_clk_cal_ratio(rtc_cal_sel_t cal_clk, uint32_t slowclk_cycles) | ||||
|     return ratio; | ||||
| } | ||||
|  | ||||
| static inline bool rtc_clk_cal_32k_valid(rtc_xtal_freq_t xtal_freq, uint32_t slowclk_cycles, uint64_t actual_xtal_cycles) | ||||
| { | ||||
|     uint64_t expected_xtal_cycles = (xtal_freq * 1000000ULL * slowclk_cycles) >> 15; // xtal_freq(hz) * slowclk_cycles / 32768 | ||||
|     uint64_t delta = expected_xtal_cycles / 2000;                                    // 5/10000 | ||||
|     return (actual_xtal_cycles >= (expected_xtal_cycles - delta)) && (actual_xtal_cycles <= (expected_xtal_cycles + delta)); | ||||
| } | ||||
|  | ||||
| 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(); | ||||
|     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)) { | ||||
|         return 0; | ||||
|     } | ||||
|  | ||||
|     uint64_t divider = ((uint64_t)xtal_freq) * slowclk_cycles; | ||||
|     uint64_t period_64 = ((xtal_cycles << RTC_CLK_CAL_FRACT) + divider / 2 - 1) / divider; | ||||
|     uint32_t period = (uint32_t)(period_64 & UINT32_MAX); | ||||
|   | ||||
| @@ -129,10 +129,22 @@ uint32_t rtc_clk_cal_ratio(rtc_cal_sel_t cal_clk, uint32_t slowclk_cycles) | ||||
|     return ratio; | ||||
| } | ||||
|  | ||||
| static bool rtc_clk_cal_32k_valid(rtc_xtal_freq_t xtal_freq, uint32_t slowclk_cycles, uint64_t actual_xtal_cycles) | ||||
| { | ||||
|     uint64_t expected_xtal_cycles = (xtal_freq * 1000000ULL * slowclk_cycles) >> 15; // xtal_freq(hz) * slowclk_cycles / 32768 | ||||
|     uint64_t delta = expected_xtal_cycles / 2000;                                    // 5/10000 | ||||
|     return (actual_xtal_cycles >= (expected_xtal_cycles - delta)) && (actual_xtal_cycles <= (expected_xtal_cycles + delta)); | ||||
| } | ||||
|  | ||||
| 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(); | ||||
|     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)) { | ||||
|         return 0; | ||||
|     } | ||||
|  | ||||
|     uint64_t divider = ((uint64_t)xtal_freq) * slowclk_cycles; | ||||
|     uint64_t period_64 = ((xtal_cycles << RTC_CLK_CAL_FRACT) + divider / 2 - 1) / divider; | ||||
|     uint32_t period = (uint32_t)(period_64 & UINT32_MAX); | ||||
|   | ||||
| @@ -191,11 +191,22 @@ uint32_t rtc_clk_cal_ratio(rtc_cal_sel_t cal_clk, uint32_t slowclk_cycles) | ||||
|     return ratio; | ||||
| } | ||||
|  | ||||
| static inline bool rtc_clk_cal_32k_valid(rtc_xtal_freq_t xtal_freq, uint32_t slowclk_cycles, uint64_t actual_xtal_cycles) | ||||
| { | ||||
|     uint64_t expected_xtal_cycles = (xtal_freq * 1000000ULL * slowclk_cycles) >> 15; // xtal_freq(hz) * slowclk_cycles / 32768 | ||||
|     uint64_t delta = expected_xtal_cycles / 2000;                                    // 5/10000 | ||||
|     return (actual_xtal_cycles >= (expected_xtal_cycles - delta)) && (actual_xtal_cycles <= (expected_xtal_cycles + delta)); | ||||
| } | ||||
|  | ||||
| uint32_t rtc_clk_cal(rtc_cal_sel_t cal_clk, uint32_t slowclk_cycles) | ||||
| { | ||||
|     uint64_t xtal_cycles = rtc_clk_cal_internal(cal_clk, slowclk_cycles, RTC_TIME_CAL_ONEOFF_MODE); | ||||
|     uint32_t period = rtc_clk_xtal_to_slowclk(xtal_cycles, slowclk_cycles); | ||||
|     return period; | ||||
|  | ||||
|     if ((cal_clk == RTC_CAL_32K_XTAL) && !rtc_clk_cal_32k_valid(rtc_clk_xtal_freq_get(), slowclk_cycles, xtal_cycles)) { | ||||
|         return 0; | ||||
|     } | ||||
|  | ||||
|     return rtc_clk_xtal_to_slowclk(xtal_cycles, slowclk_cycles); | ||||
| } | ||||
|  | ||||
| uint32_t rtc_clk_cal_cycling(rtc_cal_sel_t cal_clk, uint32_t slowclk_cycles) | ||||
|   | ||||
| @@ -128,10 +128,22 @@ uint32_t rtc_clk_cal_ratio(rtc_cal_sel_t cal_clk, uint32_t slowclk_cycles) | ||||
|     return ratio; | ||||
| } | ||||
|  | ||||
| static inline bool rtc_clk_cal_32k_valid(rtc_xtal_freq_t xtal_freq, uint32_t slowclk_cycles, uint64_t actual_xtal_cycles) | ||||
| { | ||||
|     uint64_t expected_xtal_cycles = (xtal_freq * 1000000ULL * slowclk_cycles) >> 15; // xtal_freq(hz) * slowclk_cycles / 32768 | ||||
|     uint64_t delta = expected_xtal_cycles / 2000;                                    // 5/10000 | ||||
|     return (actual_xtal_cycles >= (expected_xtal_cycles - delta)) && (actual_xtal_cycles <= (expected_xtal_cycles + delta)); | ||||
| } | ||||
|  | ||||
| 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(); | ||||
|     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)) { | ||||
|         return 0; | ||||
|     } | ||||
|  | ||||
|     uint64_t divider = ((uint64_t)xtal_freq) * slowclk_cycles; | ||||
|     uint64_t period_64 = ((xtal_cycles << RTC_CLK_CAL_FRACT) + divider / 2 - 1) / divider; | ||||
|     uint32_t period = (uint32_t)(period_64 & UINT32_MAX); | ||||
|   | ||||
| @@ -403,6 +403,11 @@ uint32_t rtc_clk_apb_freq_get(void); | ||||
|  * 32k XTAL is being calibrated, but the oscillator has not started up (due to | ||||
|  * incorrect loading capacitance, board design issue, or lack of 32 XTAL on board). | ||||
|  * | ||||
|  * @note When 32k CLK is being calibrated, this function will check the accuracy | ||||
|  * of the clock. Since the xtal 32k or ext osc 32k is generally very stable, if | ||||
|  * the check fails, then consider this an invalid 32k clock and return 0. This | ||||
|  * check can filter some jamming signal. | ||||
|  * | ||||
|  * @param cal_clk  clock to be measured | ||||
|  * @param slow_clk_cycles  number of slow clock cycles to average | ||||
|  * @return average slow clock period in microseconds, Q13.19 fixed point format, | ||||
|   | ||||
| @@ -509,6 +509,11 @@ uint32_t rtc_clk_cal_internal(rtc_cal_sel_t cal_clk, uint32_t slowclk_cycles); | ||||
|  * 32k XTAL is being calibrated, but the oscillator has not started up (due to | ||||
|  * incorrect loading capacitance, board design issue, or lack of 32 XTAL on board). | ||||
|  * | ||||
|  * @note When 32k CLK is being calibrated, this function will check the accuracy | ||||
|  * of the clock. Since the xtal 32k or ext osc 32k is generally very stable, if | ||||
|  * the check fails, then consider this an invalid 32k clock and return 0. This | ||||
|  * check can filter some jamming signal. | ||||
|  * | ||||
|  * @param cal_clk  clock to be measured | ||||
|  * @param slow_clk_cycles  number of slow clock cycles to average | ||||
|  * @return average slow clock period in microseconds, Q13.19 fixed point format, | ||||
|   | ||||
| @@ -539,6 +539,11 @@ uint32_t rtc_clk_cal_internal(rtc_cal_sel_t cal_clk, uint32_t slowclk_cycles, ui | ||||
|  * 32k XTAL is being calibrated, but the oscillator has not started up (due to | ||||
|  * incorrect loading capacitance, board design issue, or lack of 32 XTAL on board). | ||||
|  * | ||||
|  * @note When 32k CLK is being calibrated, this function will check the accuracy | ||||
|  * of the clock. Since the xtal 32k or ext osc 32k is generally very stable, if | ||||
|  * the check fails, then consider this an invalid 32k clock and return 0. This | ||||
|  * check can filter some jamming signal. | ||||
|  * | ||||
|  * @param cal_clk  clock to be measured | ||||
|  * @param slow_clk_cycles  number of slow clock cycles to average | ||||
|  * @return average slow clock period in microseconds, Q13.19 fixed point format, | ||||
|   | ||||
| @@ -503,6 +503,11 @@ uint32_t rtc_clk_cal_internal(rtc_cal_sel_t cal_clk, uint32_t slowclk_cycles); | ||||
|  * 32k XTAL is being calibrated, but the oscillator has not started up (due to | ||||
|  * incorrect loading capacitance, board design issue, or lack of 32 XTAL on board). | ||||
|  * | ||||
|  * @note When 32k CLK is being calibrated, this function will check the accuracy | ||||
|  * of the clock. Since the xtal 32k or ext osc 32k is generally very stable, if | ||||
|  * the check fails, then consider this an invalid 32k clock and return 0. This | ||||
|  * check can filter some jamming signal. | ||||
|  * | ||||
|  * @param cal_clk  clock to be measured | ||||
|  * @param slow_clk_cycles  number of slow clock cycles to average | ||||
|  * @return average slow clock period in microseconds, Q13.19 fixed point format, | ||||
|   | ||||
		Reference in New Issue
	
	Block a user
	 jingli
					jingli