This post is older than 2 years and might not be relevant anymore
More Info: Consider searching for newer posts

Timer drifting in nRF52810 based custom board

Hi,

We are currently developing an application that makes use of soft device(s112). We tried using timer(Timer 1) for a timed wake up and sleep but found that the actual timeout is different than the configured timeout.
We tried using different frequencies and timeout values for timer but the results were the same.

Timer Drift Observations

Frequency Configured Timeout Actual Timeout
125 kHz 1 s 0.977 s
250 kHz 1 s 0.974 s
250 kHz 60 s 58.388 s
250 kHz 300 s 291.873
2 MHz 1 s 0.975 s
2 MHz 60 s 58.391 s
16 MHz 1 s 0.974 s

We are using "nRF SDK version 14.2".

Also we tried using the app timer instead of Timer module and the timings from app timer was correct (configured for 60s and it timed out after 60s perfectly).

We didn't populate the external low frequency crystal.

We could use app timer for this application(need to do further testing) but would like to know about the cause of this issue so that this can be taken in to consideration while designing our future products.

Thanking you in advance
Hari

Parents
  • You should make it a point to familiarize yourself with the product spec. Timer1 makes use of HF clock.  Thus after coming out of power manage the device is running on HF int to save power. HF int has an accuracy of +/- many percent. You have to actually request HF ext to get its accuracy.

    Regardless of the above, timer1 would be a terrible thing to use for 60second timing since it consumers so much power. You should be using the RTC timers. The RTC uses very little power and is very accurate.

    app_timer uses the RTC thus that is why you see it to be more accurate. Since your board doesn't have an external RTC crystal it is actually using the internal RTC RC oscillator.  The RC is calibrated periodically against the HF EXT based on the crystal info you passed to the SD when you initialized it.  Using calibration the RC RTC is kept to +/- 250ppm.

  • Hi,
    Thank you for your response but the thing is we did knew about the High frequency and Low frequency clocks(sorry that i didn't mention that previously) but still the drift shown in table is a little too much (we knew from other post that when soft device is used there will be a little drift in timer).

    Thus after coming out of power manage the device is running on HF int to save power. HF int has an accuracy of +/- many percent. You have to actually request HF ext to get its accuracy.

    Could you please explain the above sentence?

    Regardless of the above, timer1 would be a terrible thing to use for 60second timing since it consumers so much power. You should be using the RTC timers. The RTC uses very little power and is very accurate.

    Thanks to you we are glad for using app timer for our timed operation, but just for information could you please give the cause of such high drift in timer.

    Regards,
    Hari

  • There is no drift in any of the hardware timers at any time whether soft device is used or not. It is incorrect to say there is drift.

    What many people on this blog fail to realize is that ISR's get queued and the SD has top priority. So, TX/RX traffic on BLE will delay servicing of an ISR.  For this reason, time critical gpio activity should always be done within a timer by utilizing PPI/GPIOTE.

    Regarding what I stated above, the HF_EXT clock(ie, crystal based 32MHz) is never run for your app by default.  The nRF will always run client code on HF_INT which is RC based. This is done to reduce power consumption. An RC oscillator has terrible accuracy (it is about +/- 20000ppm) so you have to actually request HF_EXT the crystal based oscillator (+/-10ppm depending on your crystal choice) if you require it's accuracy.

    Regarding what I said at the bottom, if you are timing out 60 seconds it is foolish to use the main timers since HF_EXT uses so much power. The RTC is specifically designed to use very little power (about 2.5uAmp for internal RC based as you are using) and since it runs at only 32.768kHz is ideally suited for timing out long intervals.  The only caveat with using the internal RTC, as you are doing since you didn't place the crystal, is that it needs to be calibrated periodically.  The SD does this automatically on an interval that was in your init code for the SD.  If you don't run the SD then you have to do this manually and the code for that is referenced many times in the devzone.

    So, use RTC1, or RTC2 for your task.  RTC0 is utilized by the SD so you can not use it.  As long as the SD is running the RTC will calibrate and you will get about +/-250ppm accuracy.  If you had place the external crystal you would get about +/-20ppm accuracy or better depending on your crystal choice.

    If the RTC is generating an ISR via for example a system event, then that ISR will always be serviced after any SD ISR is done. This can result in a latency of up to 1 millisecond for servicing the ISR.

Reply
  • There is no drift in any of the hardware timers at any time whether soft device is used or not. It is incorrect to say there is drift.

    What many people on this blog fail to realize is that ISR's get queued and the SD has top priority. So, TX/RX traffic on BLE will delay servicing of an ISR.  For this reason, time critical gpio activity should always be done within a timer by utilizing PPI/GPIOTE.

    Regarding what I stated above, the HF_EXT clock(ie, crystal based 32MHz) is never run for your app by default.  The nRF will always run client code on HF_INT which is RC based. This is done to reduce power consumption. An RC oscillator has terrible accuracy (it is about +/- 20000ppm) so you have to actually request HF_EXT the crystal based oscillator (+/-10ppm depending on your crystal choice) if you require it's accuracy.

    Regarding what I said at the bottom, if you are timing out 60 seconds it is foolish to use the main timers since HF_EXT uses so much power. The RTC is specifically designed to use very little power (about 2.5uAmp for internal RC based as you are using) and since it runs at only 32.768kHz is ideally suited for timing out long intervals.  The only caveat with using the internal RTC, as you are doing since you didn't place the crystal, is that it needs to be calibrated periodically.  The SD does this automatically on an interval that was in your init code for the SD.  If you don't run the SD then you have to do this manually and the code for that is referenced many times in the devzone.

    So, use RTC1, or RTC2 for your task.  RTC0 is utilized by the SD so you can not use it.  As long as the SD is running the RTC will calibrate and you will get about +/-250ppm accuracy.  If you had place the external crystal you would get about +/-20ppm accuracy or better depending on your crystal choice.

    If the RTC is generating an ISR via for example a system event, then that ISR will always be serviced after any SD ISR is done. This can result in a latency of up to 1 millisecond for servicing the ISR.

Children
  • We tried our code in nRF52DK and the timer was working fine. We tried the code in second custom board and the timer timings were very different from board 1. So may be something related to the hardware?(But we are using the same reference design given in product specification only the Low frequency Xtal is eliminated).

  • Then that is related to my earlier comment that without a crystal the LF RC has to be calibrated against the HF clock. (see my initial answer)

    If you are running the SD, then this calibration happens automatically per your config settings.  If you turned it off in the config then obviously it won't calibrate. You should check this.

    If you are not running the SD then you have to add the code to periodically calibrate the LF RC.  Just search in the devzone and you will easily find the code for this.

  • But we are using soft device. So what does the Low frequency clock has to do with timer(Timer runs on 1Mhz and 16 Mhz clock, right).

  • Depends on which timer specifically.  Thus far we have discussed the app_tiimer, RTC1, and timer1.

    Also, there is a big difference between having the SD in its partition in flash and actually starting it.

    What I told you earlier is that it is foolish to use timer1 for long period applications.  So, not sure what you are using now.  Maybe you should post the code.

  • Just to make things clear, we needed to count hours in our program and initially we were using Timer 1 configured at 1min interrupt to count hours. But after some debugging the 1min timeout it is found to be inaccurate and tested the same code in nrf52DK and it was working fine. So as a workaround we tried using app timer based RTC and when it was found to be accurate we thought about using it for 1 min timeout. Now as you have mentioned earlier that it is better to use RTC for long operations we finalized on using app timer for 1 min timeout. Now we have no issue with timing as we are using RTC based timer but the issue with the Timer(not app timer) is still there(not using it in the application). So we would like to clarify the issue with the timer(not app timer) module so that if needed we could use the timer in our future projects.

    For the RC calibration we have the following definitions in sdk_config.h (if the RC calibration has something to do with timer issue)

    NRF_SDH_CLOCK_LF_RC_CTIV                     16
    NRF_SDH_CLOCK_LF_RC_TEMP_CTIV        2
    NRF_SDH_CLOCK_LF_XTAL_ACCURACY    7

Related