mirror of
https://github.com/espressif/esp-idf.git
synced 2025-11-18 10:31:09 +00:00
esp32/clk:Fix starting rtc oscillator if it is bad
If the RTC crystal is bad or has no matched capacitance, then you do not need to start such the crystal. It is necessary to determine this case, output an error (about impossibility to start from the oscillator) and start from the internal RC of the chain. Reduced the default value of the number of bootstrap cycles. Because we can oscillating the oscillator which then stops. (in Kconfig). Changed from 100 to 5. The number of calibration cycles has been increased. It is the main criterion for estimating the launch of an oscillator. A large increase leads to an increase in the load time, as well as the stability of recognition of this case. (in Kconfig). Changed from 1024 to 3000.
This commit is contained in:
@@ -36,7 +36,6 @@
|
||||
* Larger values increase startup delay. Smaller values may cause false positive
|
||||
* detection (i.e. oscillator runs for a few cycles and then stops).
|
||||
*/
|
||||
#define XTAL_32K_DETECT_CYCLES 32
|
||||
#define SLOW_CLK_CAL_CYCLES CONFIG_ESP32_RTC_CLK_CAL_CYCLES
|
||||
|
||||
#define MHZ (1000000)
|
||||
@@ -128,6 +127,9 @@ void IRAM_ATTR ets_update_cpu_frequency(uint32_t ticks_per_us)
|
||||
static void select_rtc_slow_clk(rtc_slow_freq_t slow_clk)
|
||||
{
|
||||
uint32_t cal_val = 0;
|
||||
uint32_t wait = 0;
|
||||
const uint32_t warning_timeout = 3 /* sec */ * 32768 /* Hz */ / (2 * SLOW_CLK_CAL_CYCLES);
|
||||
bool changing_clock_to_150k = false;
|
||||
do {
|
||||
if (slow_clk == RTC_SLOW_FREQ_32K_XTAL) {
|
||||
/* 32k XTAL oscillator needs to be enabled and running before it can
|
||||
@@ -137,24 +139,23 @@ static void select_rtc_slow_clk(rtc_slow_freq_t slow_clk)
|
||||
* oscillator cycles. If the 32k XTAL has not started up, calibration
|
||||
* will time out, returning 0.
|
||||
*/
|
||||
uint32_t wait = 0;
|
||||
// increment of 'wait' counter equivalent to 3 seconds
|
||||
const uint32_t warning_timeout = 3 /* sec */ * 32768 /* Hz */ / (2 * XTAL_32K_DETECT_CYCLES);
|
||||
ESP_EARLY_LOGD(TAG, "waiting for 32k oscillator to start up");
|
||||
do {
|
||||
++wait;
|
||||
rtc_clk_32k_enable(true);
|
||||
cal_val = rtc_clk_cal(RTC_CAL_32K_XTAL, XTAL_32K_DETECT_CYCLES);
|
||||
if (wait % warning_timeout == 0) {
|
||||
ESP_EARLY_LOGW(TAG, "still waiting for 32k oscillator to start up");
|
||||
}
|
||||
if(cal_val == 0){
|
||||
rtc_clk_32k_enable(false);
|
||||
rtc_clk_32k_bootstrap(CONFIG_ESP32_RTC_XTAL_BOOTSTRAP_CYCLES);
|
||||
}
|
||||
} while (cal_val == 0);
|
||||
rtc_clk_32k_enable(true);
|
||||
cal_val = rtc_clk_cal(RTC_CAL_32K_XTAL, SLOW_CLK_CAL_CYCLES);
|
||||
if(cal_val == 0 || cal_val < 15000000L){
|
||||
ESP_EARLY_LOGE(TAG, "RTC: Not found External 32 kHz XTAL. Switching to Internal 150 kHz RC chain");
|
||||
slow_clk = RTC_SLOW_FREQ_RTC;
|
||||
changing_clock_to_150k = true;
|
||||
}
|
||||
}
|
||||
rtc_clk_slow_freq_set(slow_clk);
|
||||
if (changing_clock_to_150k == true && wait > 1){
|
||||
// This helps when there are errors when switching the clock from External 32 kHz XTAL to Internal 150 kHz RC chain.
|
||||
rtc_clk_32k_enable(false);
|
||||
uint32_t min_bootstrap = 5; // Min bootstrapping for continue switching the clock.
|
||||
rtc_clk_32k_bootstrap(min_bootstrap);
|
||||
rtc_clk_32k_enable(true);
|
||||
}
|
||||
|
||||
if (SLOW_CLK_CAL_CYCLES > 0) {
|
||||
/* TODO: 32k XTAL oscillator has some frequency drift at startup.
|
||||
@@ -165,6 +166,9 @@ static void select_rtc_slow_clk(rtc_slow_freq_t slow_clk)
|
||||
const uint64_t cal_dividend = (1ULL << RTC_CLK_CAL_FRACT) * 1000000ULL;
|
||||
cal_val = (uint32_t) (cal_dividend / rtc_clk_slow_freq_get_hz());
|
||||
}
|
||||
if (++wait % warning_timeout == 0) {
|
||||
ESP_EARLY_LOGW(TAG, "still waiting for source selection RTC");
|
||||
}
|
||||
} while (cal_val == 0);
|
||||
ESP_EARLY_LOGD(TAG, "RTC_SLOW_CLK calibration value: %d", cal_val);
|
||||
esp_clk_slowclk_cal_set(cal_val);
|
||||
|
||||
Reference in New Issue
Block a user