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.

MSP430F5438: Alternative to majority vote when reading RTC counters

Part Number: MSP430F5438

According to the User's Guide, when RTC is asynchronous to CPU, majority vote should be taken to determine the correct reading of the counters. However, at least four successive readings are needed  to work correctly all the time, as Jens-Michael Gross pointed out here. In addition, one must assume that the CPU frequency is relatively high enough to run all the four readings before the next RTC clock arrives.


An alternative, which is much simpler, is as follows:

u32 RTC_counter(void)
{
    volatile u32 v1, v2;
    v1 = RTCNT;
    v2 = RTCNT;
    while (1 < v2 - v1) {
        v1 = v2;
        v2 = RTCNT;
    }
    return v2;
}

That is, read successively until one is found to be equal to or one greater than the previous, and return it.

Is that reliable? Or, is there a chance that v1 and v2 hit the same one race condition, resulting in the same v1 and  v2 while both are incorrect (which I think is relevant to the majority vote algorithm as well)?

Thanks!

  • Hi Wenhao,

    First, I need to warn you that the MSP430F5438 is not recommended for new designs. It has been replaced by the MSP430F5438A which has the same functionality and pinout.

    Now on to your question. As Jens-Michael Gross stated "If you read the registers while the counter is in the process of updating, any value can appear in the register (racing condition on the digit-to-digit rollover)." This means there is a chance that when you first populate v1 and v2 by reading RTCNT, you could "incorrectly" read a value that passes your criteria (1 < v2 - v1) but that value is incorrect.

    Additionally, if using the RTC in calendar mode, section 22.2.2.3 of MSP430x5xx and MSP430x6xx Family User's Guide describes other methods of properly reading registers. However, from what I've gathered it looks like you're using the RTC in counter mode?

    Best regards,
    Caleb Overbay

  • Hi Caleb,

    Yes, we're using the RTC in counter mode.

    But, assuming that the CPU's clock is much faster than the RTC's, and meanwhile it is slow enough when compared to the speed of the transition in the counter hardware, at most one of v1, v2 could hit the transition:

    • If v1 hits, then v2 is correct and returning v2 is always appropriate;
    • if v2 hits, then v1 is correct, and if the criteria is meet, v2 is either the same as v1 (as though v2 hits right before the transition) or is one greater than v1 (as though v2 hits right after the transition), and both are appropriate.

    Did I miss something? Thank you.

  • Hi Wenhao,

    Your logic seems correct. I believe the method you've detailed above should give you the correct result. Out of curiosity, what speed are you running the CPU and RTC at?

    Best regards,
    Caleb Overbay
  • Hi Caleb,

    We run RTC at 32768Hz, and CPU at several MHz.

  • Hi Wenhoa,

    With your CPU running at several MHz compared to a 32kHz RTC, you have plenty of time to take 4 readings of RTCNT for a majority vote as Jens-Michael Gross described in the post you referenced. When using the approach you've described above with the CPU running much faster than the RTC source, there is a chance both v2 and v1 are incorrect readings that occur while RTCNT is being updated. The method you've described above would work best when the CPU and RTC sources are much closer in frequency.

    Best regards,
    Caleb Overbay
  • Hi Caleb,

    Caleb Overbay said:
    with the CPU running much faster than the RTC source, there is a chance both v2 and v1 are incorrect readings

    In my opinion, the CPU speed, which determines how frequent we can read the RTC counter, should be compared to the speed of the transition in the RTC counter hardware, which ought to be driven by rising edges of the RTC clock. Therefore, the speed of the transition should be very high and nearly fixed (even not affected by the slope of the clock edges, not to mention the frequency of the clock). And, anyway, the majority vote algorithm also suffers from "both v2 and v1 are incorrect", as I mentioned in my first post.

    Caleb Overbay said:
    The method you've described above would work best when the CPU and RTC sources are much closer in frequency.

    On the contrary, the single fatal flaw of my proposal, I suppose, is that it cannot deal with the very case you mentioned above. When the CPU does not run fast enough, v2 can be two or more greater than v1 even in normal cases, which causes the while to loop endlessly.

  • Hi Wenhoa,

    This is a very interesting topic. I've been thinking about your method and its essentially the method Jens-Michael Gross has described. You continue to read until you get two consecutive readings that are identical. It's highly unlikely that you'll get two incorrect readings that are identical from the initial reads. I think your algorithm should work in this application. I apologize if I caused any confusion. It's always good to review these things with peers!

    Also, you're correct that if MCLK is too slow the algorithm will fail.

    Best regards,
    Caleb Overbay
  • Hi Caleb,

    Caleb Overbay said:
    essentially the method Jens-Michael Gross has described.

    I totally agree with you.

    Caleb Overbay said:
    It's highly unlikely that you'll get two incorrect readings that are identical from the initial reads.

    First, could you please explain this statement a little more? It's not quite clear for me, especially the word initial (sorry, English is not my mother tongue). Second, with CPU running at tens of MHz, I hope it's "impossible", not just "highly unlikely". :-)

    Caleb Overbay said:
    I apologize if I caused any confusion. It's always good to review these things with peers!

    I really appreciate your help. That's why I am here in the first place!

  • I do most of my work in assembler and would recommend the following way (here as a macro - more speedy). Pls keep in mind that this macro is only suitable in counter mode: The "xT" comments denote the numbers of MCU clock cycles.


    // Minimum total duration: 15 MCU cycles
    // Maximum total duration: 18 MCU cycles
    M_RTC_READCNT MACRO
            local locExit
            mov &RTCNT12,R14   // 3T 1st read of counter low word
            mov &RTCNT34,R13   // 3T Read counter high word
            mov &RTCNT12,R12   // 3T 2nd read of counter low word.
            cmp R12,R14            // 1T Both readings of low word identical?
            jeq locExit            // 2T If yes: Everything's fine - R12 and R13 already hold correct values
            mov &RTCNT34,R13   // 3T If a change occured then the first reading of RTCNT34 may not have been correct.
    locExit:
            ENDM

  • Nope. Your code can only deal with the synchronous case. When things are asynchronous, even reading a single byte (say RTCNT1) can give you unpredictable results.

  • The acccess is asynchronous but not the counter itself. As it can also handle up to 25MHz clock input its internal total transition time has to be smaller than 1/25MHz=40ns - you have stated that you use the RTC-module in counter mode, so there is no additional calculation work as it would be the case in calendar mode.

    A single reading requires 3 MCLK-cycles and even with MCLK=25MHz this means 120ns. Hence, the worst case is a reading access right within that transition period when counter bits are just flippling. Exactly that case is handeled by reading RTCNT12 twice with RTCNT34 in between. If both RTCNT12-readings lead to the same output then there was no transition and also RTCNT34-reading is ok - then R12 and R13 hold the correct values and we are done.
    If RTCTN12-readings are not identical, then the transition could have happened either within the 1st or 2nd RTCNT12-access. This requires at least one additional read of RTCNT34 as it is unclear if a rollover from RTCNT12 to RTCNT34 occured. Maybe another reading of RTCNT12 should then also be added, but that's it. This version would then allow an RTC/MCLK clock ratio down to 1:21

**Attention** This is a public forum