@@ -127,44 +127,54 @@ void IRAM_ATTR ets_update_cpu_frequency(uint32_t ticks_per_us)
127127
128128static void select_rtc_slow_clk (rtc_slow_freq_t slow_clk )
129129{
130- if (slow_clk == RTC_SLOW_FREQ_32K_XTAL ) {
131- /* 32k XTAL oscillator needs to be enabled and running before it can
132- * be used. Hardware doesn't have a direct way of checking if the
133- * oscillator is running. Here we use rtc_clk_cal function to count
134- * the number of main XTAL cycles in the given number of 32k XTAL
135- * oscillator cycles. If the 32k XTAL has not started up, calibration
136- * will time out, returning 0.
137- */
138- rtc_clk_32k_enable (true);
139- uint32_t cal_val = 0 ;
140- uint32_t wait = 0 ;
141- // increment of 'wait' counter equivalent to 3 seconds
142- const uint32_t warning_timeout = 3 /* sec */ * 32768 /* Hz */ / (2 * XTAL_32K_DETECT_CYCLES );
143- ESP_EARLY_LOGD (TAG , "waiting for 32k oscillator to start up" )
144- do {
145- ++ wait ;
146- cal_val = rtc_clk_cal (RTC_CAL_32K_XTAL , XTAL_32K_DETECT_CYCLES );
147- if (wait % warning_timeout == 0 ) {
148- ESP_EARLY_LOGW (TAG , "still waiting for 32k oscillator to start up" );
149- }
150- } while (cal_val == 0 );
151- ESP_EARLY_LOGD (TAG , "32k oscillator ready, wait=%d" , wait );
152- }
153- rtc_clk_slow_freq_set (slow_clk );
154- uint32_t cal_val ;
155- if (SLOW_CLK_CAL_CYCLES > 0 ) {
156- /* TODO: 32k XTAL oscillator has some frequency drift at startup.
157- * Improve calibration routine to wait until the frequency is stable.
158- */
159- cal_val = rtc_clk_cal (RTC_CAL_RTC_MUX , SLOW_CLK_CAL_CYCLES );
160- } else {
161- const uint64_t cal_dividend = (1ULL << RTC_CLK_CAL_FRACT ) * 1000000ULL ;
162- cal_val = (uint32_t ) (cal_dividend / rtc_clk_slow_freq_get_hz ());
163- }
130+ uint32_t cal_val = 0 ;
131+ do {
132+ if (slow_clk == RTC_SLOW_FREQ_32K_XTAL ) {
133+ /* 32k XTAL oscillator needs to be enabled and running before it can
134+ * be used. Hardware doesn't have a direct way of checking if the
135+ * oscillator is running. Here we use rtc_clk_cal function to count
136+ * the number of main XTAL cycles in the given number of 32k XTAL
137+ * oscillator cycles. If the 32k XTAL has not started up, calibration
138+ * will time out, returning 0.
139+ */
140+ uint32_t wait = 0 ;
141+ // increment of 'wait' counter equivalent to 3 seconds
142+ const uint32_t warning_timeout = 3 /* sec */ * 32768 /* Hz */ / (2 * XTAL_32K_DETECT_CYCLES );
143+ ESP_EARLY_LOGD (TAG , "waiting for 32k oscillator to start up" )
144+ do {
145+ ++ wait ;
146+ rtc_clk_32k_enable (true);
147+ cal_val = rtc_clk_cal (RTC_CAL_32K_XTAL , XTAL_32K_DETECT_CYCLES );
148+ if (wait % warning_timeout == 0 ) {
149+ ESP_EARLY_LOGW (TAG , "still waiting for 32k oscillator to start up" );
150+ }
151+ if (cal_val == 0 ){
152+ rtc_clk_32k_enable (false);
153+ rtc_clk_32k_bootstrap (CONFIG_ESP32_RTC_XTAL_BOOTSTRAP_CYCLES );
154+ }
155+ } while (cal_val == 0 );
156+ }
157+ rtc_clk_slow_freq_set (slow_clk );
158+
159+ if (SLOW_CLK_CAL_CYCLES > 0 ) {
160+ /* TODO: 32k XTAL oscillator has some frequency drift at startup.
161+ * Improve calibration routine to wait until the frequency is stable.
162+ */
163+ cal_val = rtc_clk_cal (RTC_CAL_RTC_MUX , SLOW_CLK_CAL_CYCLES );
164+ } else {
165+ const uint64_t cal_dividend = (1ULL << RTC_CLK_CAL_FRACT ) * 1000000ULL ;
166+ cal_val = (uint32_t ) (cal_dividend / rtc_clk_slow_freq_get_hz ());
167+ }
168+ } while (cal_val == 0 );
164169 ESP_EARLY_LOGD (TAG , "RTC_SLOW_CLK calibration value: %d" , cal_val );
165170 esp_clk_slowclk_cal_set (cal_val );
166171}
167172
173+ void rtc_clk_select_rtc_slow_clk ()
174+ {
175+ select_rtc_slow_clk (RTC_SLOW_FREQ_32K_XTAL );
176+ }
177+
168178/* This function is not exposed as an API at this point.
169179 * All peripheral clocks are default enabled after chip is powered on.
170180 * This function disables some peripheral clocks when cpu starts.
0 commit comments