mirror of
https://github.com/espressif/esp-idf.git
synced 2026-05-04 03:52:01 +02:00
soc: implement XTAL frequency detection
ROM code already implements XTAL frequency detection, but it uses the 8M clock before the clock tuning parameters are initialized. With the zero clock tuning parameter, 8M clock has significant frequency deviation at high temperatures, which can lead to erroneous detection of 40 MHz crystal as a 26 MHz one. This change adds XTAL frequency detection code to rtc_clk_init routine, and detection is performed after the 8M clock tuning parameter as been initialized.
This commit is contained in:
@@ -31,9 +31,8 @@
|
||||
* once, and TIMG_RTC_CALI_RDY bit is set when counting is done. One-off mode is
|
||||
* enabled using TIMG_RTC_CALI_START bit.
|
||||
*/
|
||||
uint32_t rtc_clk_cal(rtc_cal_sel_t cal_clk, uint32_t slowclk_cycles)
|
||||
uint32_t rtc_clk_cal_ratio(rtc_cal_sel_t cal_clk, uint32_t slowclk_cycles)
|
||||
{
|
||||
rtc_xtal_freq_t xtal_freq = rtc_clk_xtal_freq_get();
|
||||
/* Enable requested clock (150k clock is always on) */
|
||||
if (cal_clk == RTC_CAL_32K_XTAL) {
|
||||
SET_PERI_REG_MASK(RTC_CNTL_CLK_CONF_REG, RTC_CNTL_DIG_XTAL32K_EN);
|
||||
@@ -53,7 +52,7 @@ uint32_t rtc_clk_cal(rtc_cal_sel_t cal_clk, uint32_t slowclk_cycles)
|
||||
expected_freq = 32768; /* standard 32k XTAL */
|
||||
} else if (cal_clk == RTC_CAL_8MD256 ||
|
||||
(cal_clk == RTC_CAL_RTC_MUX && slow_freq == RTC_SLOW_FREQ_8MD256)) {
|
||||
expected_freq = 8 * MHZ / 256;
|
||||
expected_freq = RTC_FAST_CLK_FREQ_APPROX / 256;
|
||||
} else {
|
||||
expected_freq = 150000; /* 150k internal oscillator */
|
||||
}
|
||||
@@ -69,7 +68,8 @@ uint32_t rtc_clk_cal(rtc_cal_sel_t cal_clk, uint32_t slowclk_cycles)
|
||||
/* Wait for calibration to finish up to another us_time_estimate */
|
||||
int timeout_us = us_time_estimate;
|
||||
while (!GET_PERI_REG_MASK(TIMG_RTCCALICFG_REG(0), TIMG_RTC_CALI_RDY) &&
|
||||
timeout_us-- > 0) {
|
||||
timeout_us > 0) {
|
||||
timeout_us--;
|
||||
ets_delay_us(1);
|
||||
}
|
||||
if (cal_clk == RTC_CAL_32K_XTAL) {
|
||||
@@ -84,9 +84,16 @@ uint32_t rtc_clk_cal(rtc_cal_sel_t cal_clk, uint32_t slowclk_cycles)
|
||||
}
|
||||
|
||||
uint64_t xtal_cycles = REG_GET_FIELD(TIMG_RTCCALICFG1_REG(0), TIMG_RTC_CALI_VALUE);
|
||||
uint64_t divider = ((uint64_t)xtal_freq) * slowclk_cycles;
|
||||
uint64_t period_64 = (xtal_cycles << RTC_CLK_CAL_FRACT) / divider;
|
||||
uint32_t period = (uint32_t)(period_64 & UINT32_MAX);
|
||||
uint64_t ratio_64 = (xtal_cycles << RTC_CLK_CAL_FRACT) / slowclk_cycles;
|
||||
uint32_t ratio = (uint32_t)(ratio_64 & UINT32_MAX);
|
||||
return ratio;
|
||||
}
|
||||
|
||||
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();
|
||||
uint32_t ratio = rtc_clk_cal_ratio(cal_clk, slowclk_cycles);
|
||||
uint32_t period = ratio / xtal_freq;
|
||||
return period;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user