k_uptime_get() drift way too much using LFXO.

Hi

This project is using nRF52840 and NCS 2.5.2, using LFXO as LFCLK source.

I added a code snippet which will be called once a button is pressed

#include <zephyr/drivers/clock_control.h>
void check_clock_calibration(void)
{
    static uint8_t first_enter = 1;
    if (first_enter) {
        first_enter = 0;
        if (IS_ENABLED(CONFIG_CLOCK_CONTROL_NRF_K32SRC_RC_CALIBRATION)) {
            LOG_ERR("LFRC calibration is enabled.");
        } else {
            LOG_ERR("LFRC calibration is disabled.");
        }
    }

    uint32_t lfclk_src = NRF_CLOCK->LFCLKSTAT & CLOCK_LFCLKSTAT_SRC_Msk;
    if (lfclk_src == CLOCK_LFCLKSTAT_SRC_RC) {
        LOG_ERR("LFCLK is using LFRC.");
    } else if (lfclk_src == CLOCK_LFCLKSTAT_SRC_Xtal) {
        LOG_ERR("LFCLK is using external XTAL (LFXO).");
    } else if (lfclk_src == CLOCK_LFCLKSTAT_SRC_Synth) {
        LOG_ERR("LFCLK is using synthesized clock.");
    } else {
        LOG_ERR("LFCLK source is unknown or not set.");
    }

    LOG_ERR("NRF_CLOCK->LFCLKSTAT %d ", NRF_CLOCK->LFCLKSTAT);
    int64_t timestamp_ms = (int64_t)k_uptime_get();
    LOG_ERR("%s timestamp_ms %llu", __func__, timestamp_ms);
}

You can see that the delta between k_uptime_get() and RTT Viewer's timestamp increase to 738 ms within 30 seconds.

I double check the RTT Viewer's timestamp using a stop watch and it seems pretty accurate.

I continue this test for over 1 hour and the delta increase to over 90 seconds. Which is way too much.

00> [00:00:09.706,237] <err> sleekapp: LFRC calibration is disabled.
00> [00:00:09.706,268] <err> sleekapp: LFCLK is using external XTAL (LFXO).
00> [00:00:09.706,298] <err> sleekapp: NRF_CLOCK->LFCLKSTAT 65537 
00> [00:00:09.706,329] <err> sleekapp: check_clock_calibration timestamp_ms 9939 //delta:233
00> [00:00:11.357,482] <err> pal_run_loop: HAPPlatformRunLoopRun
00> [00:00:17.055,908] <err> sleekapp: LFCLK is using external XTAL (LFXO).
00> [00:00:17.055,938] <err> sleekapp: NRF_CLOCK->LFCLKSTAT 65537 
00> [00:00:17.055,969] <err> sleekapp: check_clock_calibration timestamp_ms 17465 //delta:409
00> [00:00:20.708,190] <err> sleekapp: LFCLK is using external XTAL (LFXO).
00> [00:00:20.708,221] <err> sleekapp: NRF_CLOCK->LFCLKSTAT 65537 
00> [00:00:20.708,251] <err> sleekapp: check_clock_calibration timestamp_ms 21205 //delta:497
00> [00:00:23.088,928] <err> pal_run_loop: HAPPlatformRunLoopRun
00> [00:00:23.586,120] <err> sleekapp: LFCLK is using external XTAL (LFXO).
00> [00:00:23.586,151] <err> sleekapp: NRF_CLOCK->LFCLKSTAT 65537 
00> [00:00:23.586,181] <err> sleekapp: check_clock_calibration timestamp_ms 24152 //delta:566
00> [00:00:25.461,120] <err> sleekapp: LFCLK is using external XTAL (LFXO).
00> [00:00:25.461,151] <err> sleekapp: NRF_CLOCK->LFCLKSTAT 65537 
00> [00:00:25.461,181] <err> sleekapp: check_clock_calibration timestamp_ms 26072 //delta:611
00> [00:00:27.160,339] <err> sleekapp: LFCLK is using external XTAL (LFXO).
00> [00:00:27.160,369] <err> sleekapp: NRF_CLOCK->LFCLKSTAT 65537 
00> [00:00:27.160,400] <err> sleekapp: check_clock_calibration timestamp_ms 27812 //delta:652
00> [00:00:30.735,534] <err> sleekapp: LFCLK is using external XTAL (LFXO).
00> [00:00:30.735,565] <err> sleekapp: NRF_CLOCK->LFCLKSTAT 65537 
00> [00:00:30.735,595] <err> sleekapp: check_clock_calibration timestamp_ms 31473 //delta:738

I use the same test scenario to add the same print on another project (different hardware, nRF52840 IC, different firmware using NCS 2.3.0).

The delta between k_uptime_get() and RTT Viewer's timestamp is less than 1 second after 1 hour test.

Could you kindly help me locate this issue to see is it hardware related?

Regards,

Anthony Yuan

Parents
  • Hi,

     

    Now you are introducing uncertainty in the RTT process itself, so this is not a very reliable way of checking the accuracy.

    What I would recommend is to check the timestamp against a known stable high speed timer on the nRF itself, as this is sourced from the HFCLK.

    What is important then is to first start the HFXO, either via clock_control API, or by just running this:

    NRF_CLOCK->TASKS_HFCLKSTART=1;
    while(NRF_CLOCK->EVENTS_HFCLKSTARTED == 0);
    NRF_CLOCK->EVENTS_HFCLKSTARTED = 0;

     

    Kind regards,

    Håkon 

  • Hi Håkon,

    Just tested with CONFIG_SYS_CLOCK_TICKS_PER_SEC=1024 in .conf file

    And now the k_uptime_get() matching with RTT log and matching with my stop watch.

    I am not quite familiar with zephyr/kernel, I have 2 questions about CONFIG_SYS_CLOCK_TICKS_PER_SEC:

    1. I can't find out why NCS 2.3.0 and NCS 2.5.2 use the same CONFIG_SYS_CLOCK_TICKS_PER_SEC=1000 but have different result.

    2. I change CONFIG_SYS_CLOCK_TICKS_PER_SEC=2048 and the k_uptime_get() works properly too, as my understanding that it will make zephyr kernel more accurate if I set CONFIG_SYS_CLOCK_TICKS_PER_SEC=32768, but is there any side effects?

    Regards,

    Anthony Yuan

  • Hi,

     

    You are changing the prescaler for the NRF_RTC instance that is used by the kernel for timekeeping by changing that specific kconfig.

    Could you try to run the sample in zephyr/samples/boards/nordic/clock_skew ?

     

    Then add the 32k RC config:

    CONFIG_CLOCK_CONTROL_NRF_K32SRC_RC=y
     
    And add this to the startup sequence to use HFXO:

    https://github.com/nrfconnect/sdk-nrf/blob/v2.8.0/samples/cellular/at_client/src/main.c#L18-L23


     
    My output running on RC32k:

    Ty  Latest           Base             Span             Err
    HF  00:03:40.572049  00:00:00.017209  00:03:40.554840
    LF  00:03:40.577789  00:00:00.033599  00:03:40.544189 -00:00:00.010651
    RHF 00:03:40.572019                                   -00:00:00.000030
    Skew 1.000048 ; err -48279 ppb
    
    Ty  Latest           Base             Span             Err
    HF  00:03:50.597951  00:00:00.017209  00:03:50.580741
    LF  00:03:50.603271  00:00:00.033599  00:03:50.569671 -00:00:00.011070
    RHF 00:03:50.597928                                   -00:00:00.000022
    Skew 1.000048 ; err -48041 ppb
    
    Ty  Latest           Base             Span             Err
    HF  00:04:00.623685  00:00:00.017209  00:04:00.606475
    LF  00:04:00.628753  00:00:00.033599  00:04:00.595153 -00:00:00.011322
    RHF 00:04:00.623685                                    00:00:00.000000
    Skew 1.000047 ; err -47087 ppb

     

    < 50 ppm drift.

     

    Changing to LFXO gives <2 ppm initial drift:

    Ty  Latest           Base             Span             Err
    HF  00:00:10.026283  00:00:00.017210  00:00:10.009073
    LF  00:00:10.523406  00:00:00.514312  00:00:10.009094  00:00:00.000021
    RHF 00:00:10.026273                                   -00:00:00.000009
    Skew 0.999998 ; err 2086 ppb

      

    Kind regards,

    Håkon

Reply
  • Hi,

     

    You are changing the prescaler for the NRF_RTC instance that is used by the kernel for timekeeping by changing that specific kconfig.

    Could you try to run the sample in zephyr/samples/boards/nordic/clock_skew ?

     

    Then add the 32k RC config:

    CONFIG_CLOCK_CONTROL_NRF_K32SRC_RC=y
     
    And add this to the startup sequence to use HFXO:

    https://github.com/nrfconnect/sdk-nrf/blob/v2.8.0/samples/cellular/at_client/src/main.c#L18-L23


     
    My output running on RC32k:

    Ty  Latest           Base             Span             Err
    HF  00:03:40.572049  00:00:00.017209  00:03:40.554840
    LF  00:03:40.577789  00:00:00.033599  00:03:40.544189 -00:00:00.010651
    RHF 00:03:40.572019                                   -00:00:00.000030
    Skew 1.000048 ; err -48279 ppb
    
    Ty  Latest           Base             Span             Err
    HF  00:03:50.597951  00:00:00.017209  00:03:50.580741
    LF  00:03:50.603271  00:00:00.033599  00:03:50.569671 -00:00:00.011070
    RHF 00:03:50.597928                                   -00:00:00.000022
    Skew 1.000048 ; err -48041 ppb
    
    Ty  Latest           Base             Span             Err
    HF  00:04:00.623685  00:00:00.017209  00:04:00.606475
    LF  00:04:00.628753  00:00:00.033599  00:04:00.595153 -00:00:00.011322
    RHF 00:04:00.623685                                    00:00:00.000000
    Skew 1.000047 ; err -47087 ppb

     

    < 50 ppm drift.

     

    Changing to LFXO gives <2 ppm initial drift:

    Ty  Latest           Base             Span             Err
    HF  00:00:10.026283  00:00:00.017210  00:00:10.009073
    LF  00:00:10.523406  00:00:00.514312  00:00:10.009094  00:00:00.000021
    RHF 00:00:10.026273                                   -00:00:00.000009
    Skew 0.999998 ; err 2086 ppb

      

    Kind regards,

    Håkon

Children
No Data
Related