Forum Rule: Always post complete source code & details to reproduce any issue!
Results 1 to 3 of 3

Thread: Correct way to read RTC registers?

  1. #1
    Member Rena's Avatar
    Join Date
    Oct 2014
    Location
    Cambridge, Ontario, Canadia
    Posts
    32

    Correct way to read RTC registers?

    The register `RTC_TSR` contains the counter in seconds, and `RTC_TPR` contains fractional seconds, but what's the proper way to read both? If I read one and then the other, it's possible the TSR increments between reads, so the resulting value will be off by almost a whole second. Is there some "atomic 64-bit read" I can use? Should I stop the counter before every read?

    Also, the datasheet claims that the TSR increments when bit 14 of TPR transitions to zero. Is this correct? So the TPR counts in increments of 1/16384 second, not 1/32768? Is this intended to provide a solution to the race condition? Or is this a typo? From my tests it does seem to be counting 1/32768 second.

  2. #2
    Senior Member+ MichaelMeissner's Avatar
    Join Date
    Nov 2012
    Location
    Ayer Massachussetts
    Posts
    3,256
    Quote Originally Posted by Rena View Post
    The register `RTC_TSR` contains the counter in seconds, and `RTC_TPR` contains fractional seconds, but what's the proper way to read both? If I read one and then the other, it's possible the TSR increments between reads, so the resulting value will be off by almost a whole second. Is there some "atomic 64-bit read" I can use? Should I stop the counter before every read?

    Also, the datasheet claims that the TSR increments when bit 14 of TPR transitions to zero. Is this correct? So the TPR counts in increments of 1/16384 second, not 1/32768? Is this intended to provide a solution to the race condition? Or is this a typo? From my tests it does seem to be counting 1/32768 second.
    In other processors that have split registers like this, you read the seconds value twice, and if the versions are different, you loop back, and re-read all three. I.e. something like:

    Code:
        unsigned long seconds, seconds2, fraction;
    
        // ...
    
        do {
            seconds = RTC_TSR;
            fraction = RTC_TPR;
            seconds2 = RTC_TSR;
        } while (seconds != seconds2);

  3. #3
    Member Rena's Avatar
    Join Date
    Oct 2014
    Location
    Cambridge, Ontario, Canadia
    Posts
    32
    Of course, that should have been obvious. Thanks!

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •