Page 1 of 1

Is it possible to force using the internal oscillator instead of the external 32kHz crystal

Posted: Mon Dec 03, 2018 12:48 pm
by Zingemneire
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.

Re: Is it possible to force using the internal oscillator instead of the external 32kHz crystal

Posted: Mon Dec 03, 2018 2:43 pm
by Zingemneire
Hi All,

I decided to simply test whether or not I could pull it off.

I simply copied the content of function select_rtc_slow_clk to my application level program that deals with any RTC related items. As I don't need anything related to the external crystal I stripped it of anything within it to handle the external crystal.

I called the new function Rtc_SelectRtcSlow150kClk, made sure it selects RTC_SLOW_FREQ_RTC and recalibrates the clock to the internal 150kHz oscillator.

End result: it works a treat!! I can have all units start up and let them try to use the external crystal, on units where the external crystal behaviour is dodgy/unreliable all I have to do is set a parameter in NVS and it will force the unit to abandon using the external crystal for its deep sleep cycles.

Re: Is it possible to force using the internal oscillator instead of the external 32kHz crystal

Posted: Mon Dec 03, 2018 3:25 pm
by loboris
If you set → Component config → ESP32-specific → RTC clock source (Internal 150kHz RC oscillator) in menuconfig, external crystal won't be used.

Re: Is it possible to force using the internal oscillator instead of the external 32kHz crystal

Posted: Tue Dec 04, 2018 9:46 am
by Zingemneire
Absolutely correct but in order to make a dodgy unit behave as it should it requires a rebuild of the project and flashing the new binary directly or via OTA if that is still possible. My method does not require that: once I have managed to send the appropriate parameter to the board, either via the UART serial port or via Wifi, it simply stops using the external crystal => no rebuild, no separate software versions etc...

Re: Is it possible to force using the internal oscillator instead of the external 32kHz crystal

Posted: Wed Dec 05, 2018 11:18 am
by ESP_igrr
Zingemneire: at the moment copying that bit of code is probably the easiest way to achieve what you need. I have added this as a feature request ("allow selecting RTC slow clock source at run time") for the next IDF version.

Re: Is it possible to force using the internal oscillator instead of the external 32kHz crystal

Posted: Thu Dec 06, 2018 10:07 am
by Zingemneire
Hi ESP_igrr,

Thanks, that would be useful. For now I have abandoned it because although it works well enough to trigger ULP wakeups every 5 minutes with or without the external crystal there is something odd going on when I read the time at startup using the getdatetime function. It is completely off the mark on a unit with an operational external crystal which is forced to operate on the internal 150000 Hz during deep sleep.

Re: Is it possible to force using the internal oscillator instead of the external 32kHz crystal

Posted: Tue May 18, 2021 4:41 pm
by juanfam1
Hello,
Do you have any update on this?
I'm trying to do something similar and would like to know if you have solved this issue?
Is there any update on "allow selecting RTC slow clock source at run time"? If this is available, where can I find it?
What I'm trying to do is dynamically change from internal oscillator to 32kHz crystal.
Changing from 32kHz crystal to internal oscillator can work for me too but would like to know which is the safest way to do it?
Thanks.