Is it possible to force using the internal oscillator instead of the external 32kHz crystal
Posted: Mon Dec 03, 2018 12:48 pm
Hi,
We have a custom board which uses an ESP32 W-ROVER module and all boards are equipped with an external crystal.
Unfortunately on some of the boards the external crystals do not work or appear to work for a while and then stop.
The non-working ones are not really that much of a problem: the unit will start using its internal 150kHz internal oscillator to perform RTC related functions. The time deviation is significantly higher but they do operate.
On the boards where the crystals do operate there is no problem either: they simply work and quite accurately as well.
The problem is with the boards where the crystals sometimes work but stop doing so, typically during deep sleep, which causes them to never wake up again.
As I am using the configuration where the external crystal is set up via menuconfig some boards start up, report an operational crystal and then fail later.
Hence my question: is it possible to force the use of the internal oscillator dynamically for those units that we find to be unreliable?
I know it is easy to fix via "make menuconfig" but that means making and maintaining 2 software versions for the same software, something I would rather not do.
Based on a variable stored in NVS I have tried calling rtc_clk_slow_freq_set ( RTC_SLOW_FREQ_RTC ); but that does not work as when it calls esp_deep_sleep_start it ends up using the wrong number of cycles till wake up value witch turns a 4200 seconds sleep into an 868 seconds sleep.
I have found out why as well: in the cycle calculation it uses the value returned by esp_clk_slowclk_cal_get. To correct that it would need to call esp_clk_slowclk_cal_set to define another value but that is not really correct either as the new value should have been determined during calibration of the 150 kHz internal oscillator against the main system clock.
The only way I can think off to do it correctly would be to call select_rtc_slow_clk ( RTC_SLOW_FREQ_RTC ) from within the application but unfortunately that is a local static function in file "clk.c" and the comments in the code about using esp_clk_slowclk_cal_set say that may very well create problems when calling gettimeofday or other related functions.
Any ideas/suggestions on how to do this correctly would be very much appreciated.
We have a custom board which uses an ESP32 W-ROVER module and all boards are equipped with an external crystal.
Unfortunately on some of the boards the external crystals do not work or appear to work for a while and then stop.
The non-working ones are not really that much of a problem: the unit will start using its internal 150kHz internal oscillator to perform RTC related functions. The time deviation is significantly higher but they do operate.
On the boards where the crystals do operate there is no problem either: they simply work and quite accurately as well.
The problem is with the boards where the crystals sometimes work but stop doing so, typically during deep sleep, which causes them to never wake up again.
As I am using the configuration where the external crystal is set up via menuconfig some boards start up, report an operational crystal and then fail later.
Hence my question: is it possible to force the use of the internal oscillator dynamically for those units that we find to be unreliable?
I know it is easy to fix via "make menuconfig" but that means making and maintaining 2 software versions for the same software, something I would rather not do.
Based on a variable stored in NVS I have tried calling rtc_clk_slow_freq_set ( RTC_SLOW_FREQ_RTC ); but that does not work as when it calls esp_deep_sleep_start it ends up using the wrong number of cycles till wake up value witch turns a 4200 seconds sleep into an 868 seconds sleep.
I have found out why as well: in the cycle calculation it uses the value returned by esp_clk_slowclk_cal_get. To correct that it would need to call esp_clk_slowclk_cal_set to define another value but that is not really correct either as the new value should have been determined during calibration of the 150 kHz internal oscillator against the main system clock.
The only way I can think off to do it correctly would be to call select_rtc_slow_clk ( RTC_SLOW_FREQ_RTC ) from within the application but unfortunately that is a local static function in file "clk.c" and the comments in the code about using esp_clk_slowclk_cal_set say that may very well create problems when calling gettimeofday or other related functions.
Any ideas/suggestions on how to do this correctly would be very much appreciated.