This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

TM4C123GH6PM: TM4C123 read RTC not as expected

Part Number: TM4C123GH6PM

Tool/software:

Hello,

I am reading my RTC seconds and subseconds as follows:

            // process rtc
            if(!rtc_semaphore) {                                                  // check if rtc is being accessed
                rtc_semaphore = true;                                             // set rtc semaphore true
                g_rtc_mark = HWREG(HIB_RTCC);                                     // mark rtc seconds
                g_rtc_sub_mark = (HWREG(HIB_RTCSS) & HIB_RTCSS_RTCSSC_M);         // mark rtc subseconds
                valid_timing = (g_rtc_mark == HWREG(HIB_RTCC));                   // if seconds are not the same timing is valid
            } else {
                valid_timing = false;                                             // rtc is being accessed
            }
            rtc_semaphore = false;                                                // set rtc semaphore false as soon as we are done with RTC

This runs inside a loop triggered periodically. As instructed in the datasheet, i am reading RTCC, and then RTCSS, and reading RTCC again comparing to first read, and only if both are equal I am processing that read via a valid_timing flag. There is also a rtc_semaphore that will skip packet if rtc is being read by another part of code, such as inside usb_handler.h, which measures incoming sync packet differences with RTC.

Below is a log of RTC and Host time stamps, and their differenes in nanos:

[node-1] [INFO] [1748355072.989121466] [node]: nanos_diff 769990 rtc 1748355072.32386 host 1748355072.989112275
[node-1] [INFO] [1748355072.992817739] [node]: nanos_diff 559546 rtc 1748355072.32514 host 1748355072.992808081
[node-1] [INFO] [1748355072.996931401] [node]: nanos_diff 767505 rtc 1748355072.32642 host 1748355072.996922290
[node-1] [INFO] [1748355073.000778899] [node]: nanos_diff -999196287 rtc 1748355073.32767 host 1748355073.773195
[node-1] [INFO] [1748355073.004645475] [node]: nanos_diff 761379 rtc 1748355073.127 host 1748355073.4637111
[node-1] [INFO] [1748355073.008656346] [node]: nanos_diff 865244 rtc 1748355073.255 host 1748355073.8647226
[node-1] [INFO] [1748355073.012311718] [node]: nanos_diff 614277 rtc 1748355073.383 host 1748355073.12302509
[node-1] [INFO] [1748355073.016466674] [node]: nanos_diff 865056 rtc 1748355073.511 host 1748355073.16459538

What happens is that near the end of the second, the rtc is at 1748355072.32642 - next reading is at rtc 1748355073.32767 - and next reading is 1748355073.127

The second skips to the new second, but the subseconds belong in the old second. If I were reading RTCSS first, and then RTCC, RTCC could increment by +1. But I am reading RTCC first, reading the subseconds, then reading rtcc again, to see if they are equal. And they always are, but the second is +1 from expected.

Any ideas recomendations help greatly appreciated.

Best Regards,

C.

  • ok, I also need to add I use RTCTrimSet(RTC_NEUTRAL + RTC_OFFSET 60th second of each 64 seconds. The trim statement takes effect on the 63rd second, and we have no control of when it does. it could be that I am polling the rtc, while trim is being applied?

    --- edited ---

    upon further debugging, it is definitively rtc trim being applied. rtcss increases, but rtcss is decremented to trim value to count up. I have found the reason but not the solution. can't really isolate the point that it will apply trim.

  • ok, I also need to add I use RTCTrimSet(RTC_NEUTRAL + RTC_OFFSET 60th second of each 64 seconds. The trim statement takes effect on the 63rd second, and we have no control of when it does. it could be that I am polling the rtc, while trim is being applied?

    Hi Can,

      I think that is very unlikely. For experiment, can you comment out the RTCTrimSet and do you see the same issue? The datasheet does mention about extra or missing interrupt. 

    Care must be taken when using trim values that are near to the sub seconds match value in the
    HIBRTCSS register. It is possible when using trim values above 0x7FFF to receive two match
    interrupts for the same counter value. In addition, it is possible when using trim values below 0x7FFF
    to miss a match interrupt.
    In the case of a trim value above 0x7FFF, when the RTCSSC value in the HIBRTCSS register reaches
    0x7FFF, the RTCC value increments from 0x0 to 0x1 while the RTCSSC value is decreased by the
    trim amount. The RTCSSC value is counted up again to 0x7FFF before rolling over to 0x0 to begin
    counting up again. If the match value is within this range, the match interrupt is triggered twice. For
    example, as shown in Figure 7-5 on page 515, if the match interrupt was configured with RTCM0=0x1
    and RTCSSM=0x7FFD, two interrupts would be triggered.

    In the case of a trim value below 0x7FFF, the RTCSSC value is advanced from 0x7FFF to the trim
    value while the RTCC value is incremented from 0x0 to 0x1. If the match value is within that range,
    the match interrupt is not triggered. For example, as shown in Figure 7-6 on page 515, if the match
    interrupt was configured with RTCM0=0x1 and RTCSSM=0x2,an interrupt would never be triggered.

  • ok there is not an interrupt. however I am polling rtc periodically, and while this happens (the rtc trim) it produces the wrong result.

    if I comment out the rtc trim command, it will not cause any error.

    Also in the datasheet there is an error, or it is my misunderstanding:

    For trim values larger than 0x7fff, after the rtc counts up to 0x7fff, it is decremented by trim amount, and starts counting up again.

    For trim values smaller than 0x7fff, it also says "RTCSSC value is advanced from 0x7FFF to the trim"

    Does not this cause the same effect.? the first one causes a delay, but for the second one it would need to jump to 0x7fff. or jump from 0 to trim amount. (trim amount being distance from 0x7fff) The illustration on the datasheet also does not makes sense. Figure 7-5 and 7-6 are to the same effect.

    Best Regards,

    C

    --- edit

    I have found https://e2e.ti.com/support/microcontrollers/arm-based-microcontrollers-group/arm-based-microcontrollers/f/arm-based-microcontrollers-forum/610515/tm4c123gh6pm-discrepancies-in-description-of-rtc-trim-in-datasheets

    while i understand how rtc trim works, i could not find a way to not poll it while it is updating.

  • For trim values larger than 0x7fff, after the rtc counts up to 0x7fff, it is decremented by trim amount, and starts counting up again.

    Below is what it says in the datasheet. I don't see a problem with it. It is saying that if the Trim is larger like 0x8002 as shown in the figure, the RTCSSC (the sub-seconds) will be first decremented by the trim amount (which is 3) before it starts to count from 0 again. Since 0x8002 - 0x7FFF = 3, it will repeat the last three sub-seconds again starting at 0x7FFD -> 0x7FFE -> 0x7FFF before starting from 0 again. 

    In the case of a trim value above 0x7FFF, when the RTCSSC value in the HIBRTCSS register reaches
    0x7FFF, the RTCC value increments from 0x0 to 0x1 while the RTCSSC value is decreased by the
    trim amount. The RTCSSC value is counted up again to 0x7FFF before rolling over to 0x0 to begin
    counting up again.

    For trim values smaller than 0x7fff, it also says "RTCSSC value is advanced from 0x7FFF to the trim"

    Below is what is says in the datasheet. It is a bit unclear and I agree. I think what it is trying to say is that if the trim value is smaller it will start the RTCSSC counter with the trim difference. Using a trim value of 0x7FFC as shown in the figure, the trim difference is 0x7FFF - 0x7FFFC = 0x3. The RTCSSC will then start with 0x3 instead 0x0. It will count from 0x3 -> 0x4 -> 0x5 -> .... -> 0x7FFD -> 0x7FFE -> 0x7FFF. 

    In the case of a trim value below 0x7FFF, the RTCSSC value is advanced from 0x7FFF to the trim
    value while the RTCC value is incremented from 0x0 to 0x1.

  • is there any way to generate an interrupt when this adjustment happens? it happens at 63rd of each 64 seconds, but this is not enough. if I could generate an interrupt when rtc counter is skipped back or advanced? or is there any other way to detect it? best regards.

  • HI Can,

    is there any way to generate an interrupt when this adjustment happens? it happens at 63rd of each 64 seconds, but this is not enough. if I could generate an interrupt when rtc counter is skipped back or advanced? or is there any other way to detect it?

    There is not an unique interrupt flag to indicate the counter is either skipped back or advanced. Here is just a thought. Initially set the RTC to generate an match interrupt at one second with for RTCM0=0x0 and RTCSSM=0x7FFF. Let's say your trim value is 0x8002. When the match is reached, it means one second has elapsed and in the ISR, set the RTCM0= 0x1 and RTCSSM=0x7FFF.  In the next second you should get two interrupts very closely to each other instead of one second apart. This is how I envision to detect the counter being skipped back. You can continue on to the next one second interrupt and change the RTCM0 to 0x2, 0x3, 0x4 so on so forth until 0x63 and then reset your global counter. Only when RTCM=0x1 and RTCSSM=0x7FFF will you get two very closely interrupts.

     You can do similarly for trim values less than 0x7FFF. There is one instance where you will only receive interrupt after two seconds while all other interrupts come in every second. 

  • Thank you Charles,

    While this scheme will detect this in an unique way, it works on a resolution of 0 to 2 seconds. I need something like skip this packet while I am reading the rtc, such as read a flag if rtc is being updated.

    However we know exact timing. It happens on the beginning of 63rd seconds. Therefore I might attempt to maybe generate an interrupt each second, and if it is the 63rd second set a flag. But that would also be slow.

    For now I am just comparing them to past values, and if a large skip happens, I will not process them.

    Best Regards,

    C.