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

Implementing 64-bit Epoch Time Using Timer

I have an application that requires that timestamps be 64-bit epoch to the millisecond.  I'm currently using a Timer peripheral to track 1ms and increment a 64-bit counter.  I was concerned reading the value in an atomic way so I am currently disabling all interrupts when a read is performed but this seems to be pretty heavy handed. 

I saw this post https://devzone.nordicsemi.com/f/nordic-q-a/27597/extending-rtc-beyond-24-bits and it seem likes it's better just to disable the timer interrupt.

I noticed the driver API also clears the current timer value when the interrupts are enabled.  Is there a reason for this?

Is there are better way to achieve the atomic read than my current implementation?

Thanks,

  • Hi Darren

    For efficiency reasons I would suggest using a longer interval before you update your variable, and do a timer capture to get the 'lower bits' of the timestamp. 

    As an example if you configure the timer to run at a 1MHz frequency (prescaler = 4) you can reload it every second, and get the milliseconds (and microseconds if needed) by doing a capture on the timer. 

    To get the current timer value you could do the following:

    - Disable timer interrupt
    - Capture the current timer value to a separate CC register
    - Add the captured value to your variable counting the seconds, and return this as the current time
    - Enable timer interrupt

    Then in the interrupt you essentially need to increment the second variable, and increment the capture register by a million to schedule the next interrupt.

    Best regards
    Torbjørn

  • Thanks for taking time to answer.  I like this idea as it reduces overall load on the system.  Can you elaborate on point 2?  I'm not sure I follow on the meaning of "capture the current timer value to a separate CC register"

    Thanks,

    Darren

  • Hi Darren

    As you probably know the CC registers can be used either as compare registers, capture registers or both. 

    My point is just that if you use say CC[0] to generate an interrupt after 1 second you should use a separate register, such as CC[1], to capture the current timer value whenever you want to read the current time. 

    Best regards
    Torbjørn

  • Thank you for taking the time to answer.  Sorry I couldn't reply until now as I was away on vacation without much access to good internet.

    I understand your implementation.  I don't need the microseconds so it looks like the best option to get the milliseconds is to divide the result of the compare by 1000?

    Thanks,

    Darren

  • Hi Darren

    Yes, dividing by 1000 should work fine. 

    You can also reduce the speed of the timer to 125kHz by using a PRESCALER value of 7, and divide by 125 to get the milliseconds, but the end result is the same. 

    Best regards
    Torbjørn

Related