Timer error is large. How to determine the clock source of the timer

I use ncs3.0.2 to develop the 54l10 chip. I created a timer using k_timer, with a period of 1 second, to record the device time. Although I have adjusted the load capacitors for the high-speed crystal and low-speed crystal, and measured the crystal's period with an oscilloscope, I can see it is 32.0003MHz and 32.768kHz, which is already very accurate, but through this timer, there is still an error of about 2.5 seconds per day.

Previously, on the board of the 52833 chip developed using NRF5, a timer was created with APP_TIMER_DEF macros, and the period was also 1 second, and the daily error was less than 1 second
I checked the information and found that it may be k_timer that the internal oscillator was used as a clock source instead of an external crystal oscillator, which caused the timing error problem?

CONFIG_SYS_CLOCK_HW_CYCLES_PER_SEC=1000000
CONFIG_SYS_CLOCK_TICKS_PER_SEC=31250
The above two values are also integer multiples
How should I troubleshoot this issue?
  • Drift of 2.5 seconds/day is about 30PPM, you cannot measure a crystal this precise with just an oscilloscope. 

    What is the actual spec of your LFXO crystal according to the datasheet? Maybe your loading caps are a tiny bit off.

  • Hi,

    As  has already noted, 30 PPM is quite good and may need good equipment for accurately measuring that. However if you ran a test for a day and then compared the clock, then I would not doubt your measurements. 

    k_timer runs from the low frequency clock, which can have multiple clock sources (internal RC, synthesized from high frequency clock, or external crystal). First step would therefore be to check the LFCLK configuration, to ensure you use the correct clock source. Default source is internal RC, with a rating of 250 PPM (calibrated) or 4.5 % (uncalibrated), both of which are significantly less accurate than what you see. Please note that if you do have a bootloader, then you may need the same configuration there as well.

    I also notice in the Timer documentation, that:

    Note that the timer’s duration and period parameters specify minimum delays that will elapse. Because of internal system timer precision (and potentially runtime interactions like interrupt delay) it is possible that more time may have passed as measured by reads from the relevant system time APIs. But at least this much time is guaranteed to have elapsed.

    Depending on your implementation, this may mean you get accumulated delays. However, form what I understand k_uptime_get() should provide consistent time since startup, and also not getting reset on sleep. Therefore, it might be a good idea to check if your time tracking drifts away from what you get from k_uptime_get().

    Regards,
    Terje

  • hi

    How can I check if the current timer's clock source is internal RC or other? And how can I modify it?

  • For a 32.768kHz crystal oscillator, 30ppm is approximately 1Hz. The oscilloscope we use can display frequency with 4 decimal places, so this should be able to show the difference, right? If not, how should we know if the load capacitance is appropriate?

    This is part of the parameters of a 32.768kHz crystal oscillator. According to this CL value, the load capacitance should be in the range of several pF, but when we measure the crystal oscillator frequency with an oscilloscope, the actual frequency is most accurate with a load capacitance of 20 or 22pF.

  • Hi,

    The LFCLK source is selected through enabling one (and only one) of the following kconfigs:

    • CONFIG_CLOCK_CONTROL_NRF_K32SRC_XTAL
    • CONFIG_CLOCK_CONTROL_NRF_K32SRC_RC
    • CONFIG_CLOCK_CONTROL_NRF_K32SRC_SYNTH

    Those are for using external crystal, internal RC oscillator, and synthesize from HFCLK respectively. For external crystal there should be also a node in the device tree.

    To check the current clock source, it should be possible to use nrf_clock_lf_src_get() from nrfx.

    Regards,
    Terje

Related