Timekeeping drift with nRF54L15 + GRTC + Date-Time library

I'm writing an application for the nRF54L15 that periodically receives the local time via bluetooth and keeps track of time on its own between syncs. I'm using a 10ppm external oscillator as LFCLK for the GRTC. I'm following the date-time lib docs like this:

int64_t uptime = k_uptime_get();
date_time_uptime_to_unix_time_ms(&uptime);
 
// At this point `uptime` contains the unix timestamp in milliseconds.

This works, but I'm experiencing an unexpectedly high (I think!) drift in time. After around 8 hours of runtime, the nRF54L15-computed clock is already ahead of the external reference by over 3 seconds. I'm trying to understand why this could be the case and if there's something I could try doing to improve it. I suspect the `k_uptime_get()` may be the culprit, returning uptimes that are larger than expected.

In my autoconf.h, I have:

// I believe this means the LFCLK is set to use the external 32 kHz oscillator.
#define CONFIG_CLOCK_CONTROL_NRF_K32SRC_XTAL 1

- I understand the GRTC automatically switches between HFCLK and LFCLK. Could this switching impact the accuracy?

- Would directly using the INTERVAL feature of the GRTC potentially improve my situation?

- I notice that in my autoconf.h, I have #define CONFIG_SYS_CLOCK_TICKS_PER_SEC 31250. I'm not 100% what is the impact of this config in this specific context, but should this be 32768? I came across this question & answer about the potential impact of rounding errors due to CONFIG_SYS_CLOCK_HW_CYCLES_PER_SEC and CONFIG_SYS_CLOCK_TICKS_PER_SEC:  RE: k_uptime_get() drift way too much using LFXO. . In my build I currently have:

#define CONFIG_SYS_CLOCK_HW_CYCLES_PER_SEC 1000000
#define CONFIG_SYS_CLOCK_TICKS_PER_SEC 31250

The author answers with the suggestion of changing CONFIG_SYS_CLOCK_TICKS_PER_SEC to 1024, but from what I understand, that does not make sense in my case, as 1000000 is already a multiple of 31250.

Please let me know if there's any idea on how to better debug this.

Thanks!

Parents
  • Hello,

    I am terribly sorry for the late reply. We are a bit short staffed, and we are doing our best to keep the wait time down to a minimum. Sorry for the inconvenience!

    During these 8 hours, are you connecting to your phone after the initial connection? Or does the nRF54L15 get the time from the phone after you started the 8h test?

    If so, can you try setting up a timer, and print the value of the clock, e.g every 5 minutes, or 30 minutes? Just to see if the clock is drifting without being interfered by the phone?

    I don't suspect that the phone's clock is drifting, but depending on your connection interval, the exact timestamp may be inacurate. Let us say that you have a connection interval of 4 seconds, then the time you receive from the phone may be everything from 0 to 4 seconds off, depending on when the phone queued the time message. It will first be sent after the next connection interval has passed, and that could have anything between 0 and 4 seconds remaining.

    If you leave your test running even further. Does the clock keep drifting 3 seconds every 8 hours? So 9 seconds per 24h?

    Best regards,

    Edvin

  • Hey  , thank you for your reply. Absolutely no need to apologize.

    In my initial tests the phone is not connected, except for the initial time sync, after which the BLE connection is shut down. I wanted to really test the accuracy of the RTC timekeeping by itself.

    I will repeat my tests for a longer period and see if the drift is somewhat linear like you suggested. In the end, I opted for doing a periodic time sync with the Current Time Service every one hour, which is more than fine for my use case.

    I'm just now mostly curious to check if there's any easy wins to be even more accurate. I will report back as soon as I manage to collect the data.

    Thanks!

  • Hello,

    Yes, we found your findings curious. Basically, the accuracy of the GRTC should be equal to the accuracy of the LFCLK (32.768kHz clock). If your external clock is 10ppm, this means that it will drift 10 seconds per 1 million seconds (or less). 8 hours = 28800 seconds, so you should expect a drift of 0.288 seconds or less per 8 hours. What you are seeing is roughly 10 times that, so that is 10 per 100 000 or 1/10 000, or 100ppm (if my math is correct)

    What you could do is to set up a small application using DPPI, connecting the GRTC to a GPIO, and toggling it every given amount of time/ticks, and measure this GPIO using a logic analyzer, to see how long it takes.

    I'm using a 10ppm external oscillator as LFCLK for the GRTC

    Just to be sure, this means some sort of external signal generator, and not a 32kHz LFXO? Can you share the part number? (sorry if that is a dumb question, but this is new for the nRF54 series, and I am no HW expert).

    Best regards,

    Edvin

  • Thanks once again Edvin.

    By this I meant I'm using an external 32 kHz LFXO XTAL. The crystal oscillator part number is Q13FC13500005 from Epson (datasheet). I am using the recommended 12.5pF load capacitors in my dts file as follows:

    &lfxo {
    	load-capacitors = "internal";
    	// 12.5pF.
    	load-capacitance-femtofarad = <12500>;
    };

    I think it could be a couple of things:

    - Some misconfiguration on my part somewhere

    - Things could be working as expected and my measurements are off. I'm using a simple method of comparing it with my phone (against which I did the original sync): right after the sync the minutes flip at the same time; in the next morning there is a visible 3 seconds offset when the minute flips on the phone to when it flips on the nRF54.

    I will try to pipe the LFXO clock to a GPIO and measure it with an oscilloscope. Meanwhile, I was wondering if there's a more reliable test I could run. Let me know if you have something I can also run on the nRF54L15dk and on my custom nRF54L15 board. This would rule out any mistakes on my side.

    Thanks!

  • Hello,

    The LFXO you are using seems to be out of spec. 

    https://docs.nordicsemi.com/bundle/ps_nrf54L15/page/_tmp/nrf54l15/autodita/OSCILLATORS/parameters.low_frequency_crystal_oscillator.html

    The max Cl should be 9pF, while your is 12.5.

    You may (! not sure) be able to get it to work by setting the load-capactors to 21pF, but the internal ones only go up to 18pF, so you would need some external capacitors. Or you need to change to another LFXO that is actually inside the specification.

    So the load-capacitors in the dts file is not the same as the Cl of the XO. It is used to set the overall correct capacitance. 

    Best regards,

    Edvin

Reply Children
No Data
Related