mirror of
https://github.com/espressif/esp-idf.git
synced 2024-10-05 20:47:46 -04:00
Merge branch 'bugfix/fix_xtal32k_error_detect_backport_v4.4' into 'release/v4.4'
esp_hw_support/clk_cali: fix xtal32k error detect(backport v4.4) See merge request espressif/esp-idf!20276
This commit is contained in:
commit
1b70a08cc9
@ -109,10 +109,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);
|
||||
|
@ -125,10 +125,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);
|
||||
|
@ -118,10 +118,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);
|
||||
|
@ -186,11 +186,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)
|
||||
|
@ -123,10 +123,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);
|
||||
|
@ -37,11 +37,6 @@ static const char* TAG = "clk";
|
||||
#define RTC_XTAL_CAL_RETRY 1
|
||||
#endif
|
||||
|
||||
/* Lower threshold for a reasonably-looking calibration value for a 32k XTAL.
|
||||
* The ideal value (assuming 32768 Hz frequency) is 1000000/32768*(2**19) = 16*10^6.
|
||||
*/
|
||||
#define MIN_32K_XTAL_CAL_VAL 15000000L
|
||||
|
||||
/* Indicates that this 32k oscillator gets input from external oscillator, rather
|
||||
* than a crystal.
|
||||
*/
|
||||
@ -85,7 +80,7 @@ static void select_rtc_slow_clk(slow_clk_sel_t slow_clk)
|
||||
// When SLOW_CLK_CAL_CYCLES is set to 0, clock calibration will not be performed at startup.
|
||||
if (SLOW_CLK_CAL_CYCLES > 0) {
|
||||
cal_val = rtc_clk_cal(RTC_CAL_32K_XTAL, SLOW_CLK_CAL_CYCLES);
|
||||
if (cal_val == 0 || cal_val < MIN_32K_XTAL_CAL_VAL) {
|
||||
if (cal_val == 0) {
|
||||
if (retry_32k_xtal-- > 0) {
|
||||
continue;
|
||||
}
|
||||
|
@ -37,11 +37,6 @@
|
||||
|
||||
#define MHZ (1000000)
|
||||
|
||||
/* Lower threshold for a reasonably-looking calibration value for a 32k XTAL.
|
||||
* The ideal value (assuming 32768 Hz frequency) is 1000000/32768*(2**19) = 16*10^6.
|
||||
*/
|
||||
#define MIN_32K_XTAL_CAL_VAL 15000000L
|
||||
|
||||
/* Indicates that this 32k oscillator gets input from external oscillator, rather
|
||||
* than a crystal.
|
||||
*/
|
||||
@ -164,7 +159,7 @@ static void select_rtc_slow_clk(slow_clk_sel_t slow_clk)
|
||||
// When SLOW_CLK_CAL_CYCLES is set to 0, clock calibration will not be performed at startup.
|
||||
if (SLOW_CLK_CAL_CYCLES > 0) {
|
||||
cal_val = rtc_clk_cal(RTC_CAL_32K_XTAL, SLOW_CLK_CAL_CYCLES);
|
||||
if (cal_val == 0 || cal_val < MIN_32K_XTAL_CAL_VAL) {
|
||||
if (cal_val == 0) {
|
||||
if (retry_32k_xtal-- > 0) {
|
||||
continue;
|
||||
}
|
||||
|
@ -37,11 +37,6 @@
|
||||
|
||||
#define MHZ (1000000)
|
||||
|
||||
/* Lower threshold for a reasonably-looking calibration value for a 32k XTAL.
|
||||
* The ideal value (assuming 32768 Hz frequency) is 1000000/32768*(2**19) = 16*10^6.
|
||||
*/
|
||||
#define MIN_32K_XTAL_CAL_VAL 15000000L
|
||||
|
||||
/* Indicates that this 32k oscillator gets input from external oscillator, rather
|
||||
* than a crystal.
|
||||
*/
|
||||
@ -158,7 +153,7 @@ static void select_rtc_slow_clk(slow_clk_sel_t slow_clk)
|
||||
// When SLOW_CLK_CAL_CYCLES is set to 0, clock calibration will not be performed at startup.
|
||||
if (SLOW_CLK_CAL_CYCLES > 0) {
|
||||
cal_val = rtc_clk_cal(RTC_CAL_32K_XTAL, SLOW_CLK_CAL_CYCLES);
|
||||
if (cal_val == 0 || cal_val < MIN_32K_XTAL_CAL_VAL) {
|
||||
if (cal_val == 0) {
|
||||
if (retry_32k_xtal-- > 0) {
|
||||
continue;
|
||||
}
|
||||
|
@ -42,11 +42,6 @@ static const char *TAG = "clk";
|
||||
#define RTC_XTAL_CAL_RETRY 1
|
||||
#endif
|
||||
|
||||
/* Lower threshold for a reasonably-looking calibration value for a 32k XTAL.
|
||||
* The ideal value (assuming 32768 Hz frequency) is 1000000/32768*(2**19) = 16*10^6.
|
||||
*/
|
||||
#define MIN_32K_XTAL_CAL_VAL 15000000L
|
||||
|
||||
/* Indicates that this 32k oscillator gets input from external oscillator, rather
|
||||
* than a crystal.
|
||||
*/
|
||||
@ -168,7 +163,7 @@ static void select_rtc_slow_clk(slow_clk_sel_t slow_clk)
|
||||
// When SLOW_CLK_CAL_CYCLES is set to 0, clock calibration will not be performed at startup.
|
||||
if (SLOW_CLK_CAL_CYCLES > 0) {
|
||||
cal_val = rtc_clk_cal(RTC_CAL_32K_XTAL, SLOW_CLK_CAL_CYCLES);
|
||||
if (cal_val == 0 || cal_val < MIN_32K_XTAL_CAL_VAL) {
|
||||
if (cal_val == 0) {
|
||||
if (retry_32k_xtal-- > 0) {
|
||||
continue;
|
||||
}
|
||||
|
@ -41,11 +41,6 @@ static const char *TAG = "clk";
|
||||
#define RTC_XTAL_CAL_RETRY 1
|
||||
#endif
|
||||
|
||||
/* Lower threshold for a reasonably-looking calibration value for a 32k XTAL.
|
||||
* The ideal value (assuming 32768 Hz frequency) is 1000000/32768*(2**19) = 16*10^6.
|
||||
*/
|
||||
#define MIN_32K_XTAL_CAL_VAL 15000000L
|
||||
|
||||
/* Indicates that this 32k oscillator gets input from external oscillator, rather
|
||||
* than a crystal.
|
||||
*/
|
||||
@ -162,7 +157,7 @@ static void select_rtc_slow_clk(slow_clk_sel_t slow_clk)
|
||||
// When SLOW_CLK_CAL_CYCLES is set to 0, clock calibration will not be performed at startup.
|
||||
if (SLOW_CLK_CAL_CYCLES > 0) {
|
||||
cal_val = rtc_clk_cal(RTC_CAL_32K_XTAL, SLOW_CLK_CAL_CYCLES);
|
||||
if (cal_val == 0 || cal_val < MIN_32K_XTAL_CAL_VAL) {
|
||||
if (cal_val == 0) {
|
||||
if (retry_32k_xtal-- > 0) {
|
||||
continue;
|
||||
}
|
||||
|
@ -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,
|
||||
|
@ -510,6 +510,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,
|
||||
|
@ -526,6 +526,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,
|
||||
|
@ -540,6 +540,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,
|
||||
|
@ -522,6 +522,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,
|
||||
|
Loading…
Reference in New Issue
Block a user