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.

About CC430 errata "RTC3" "Unreliabe write to RTC register"



Hi,

  TI provides a sw workaround for this. Here is the description.

A write access to the RTC registers (SEC, MIN, HOUR, DATE, MON, YEAR, DOW) may
result in unexpected results. As a consequence the addressed register might not contain
the written data, or some data can be accidentally written to other RTC registers.

  My question is:

1. Only RTC in calendar mode needs  the workaround? what about counter mode? The workaround only provides set functions like "SetRTCHOUR", "SetRTCMIN" and "SetRTCSEC", but no functions like "SetRTCTIM0", although they should write to the same registers, simply different for byte or word operation.

2. Even if it has provided read functions "GetRTCTIM0" and "GetRTCTIM1", in order to correctly read RTC count in counter mode, it still needs SW majority check to ensure the result is valid, for example by calling "GetRTCTIM0" twice and think the result is valid only when both returned value are the same?  Or, "GetRTCTIM0" will ensure the result will be valid?

Thanks

 

 

  • Jianyi Bao said:
    Only RTC in calendar mode needs  the workaround? what about counter mode?

    errors occurs during access (writing) to RTC registers when RTC is in use

    Jianyi Bao said:
    The workaround only provides set functions like "SetRTCHOUR", "SetRTCMIN" and "SetRTCSEC", but no functions like "SetRTCTIM0", although they should write to the same registers, simply different for byte or word operation.

    look in code:

    ;-------------------------------------------------------------------------------	
    ; int SetRTCMIN(int min)
    ; min will be set in the RTCMIN register
    ; Workaround requires to write 16 bits into RTCTIM0
    ; return value is read back from the RTCDOW register
    ; argument min is in R12
    ; return value is in R12
    SetRTCMIN   push.w  R5                      ; push R5
                mov.b   &RTCSEC, R5             ; read RTCSEC into R5
                swpb    R12                     ; R12 holds min - swap lower and upper byte
                bis.w   R12, R5                 ; combine read RTCMIN and new RTCSEC
                dint
                nop
                mov.w   R5,&RTCTIM0             ; write to RTCTIM0
                nop
                eint
                mov.b   &RTCMIN, R12            ; Read RTCDOW register
                pop.w   R5                      ; pop R5
                reta
    ;-------------------------------------------------------------------------------	
    ; int SetRTCSEC(int sec)
    ; sec will be set in the RTCSEC register
    ; Workaround requires to write 16 bits into RTCTIM0
    ; return value is read back from the RTCSEC register
    ; argument sec is in R12
    ; return value is in R12
    SetRTCSEC                                   ; R12 holds day in lower byte
                push.w  R5                      ; push R5
                mov.b   &RTCMIN, R5             ; read RTCMIN into lower byte of R5
                swpb    R5                      ; min is now in higher byte of R5
                bis.w   R12, R5                 ; combine read RTCMIN and new RTCSEC
                dint
                nop
                nop                             ; WG:
                mov.w   R5,&RTCTIM0             ; write to RTCTIM0		
                nop
                eint
                mov.b   &RTCSEC, R12            ; Read RTCSEC register
                pop.w   R5                      ; pop R5
                reta
    

    Jianyi Bao said:
    Even if it has provided read functions "GetRTCTIM0" and "GetRTCTIM1", in order to correctly read RTC count in counter mode, it still needs SW majority check to ensure the result is valid, for example by calling "GetRTCTIM0" twice and think the result is valid only when both returned value are the same?  Or, "GetRTCTIM0" will ensure the result will be valid?

    "GetRTCTIM0" and "GetRTCTIM1"  functions are atomic they operating on 16 bit registers,

    look in code, only word read instruction (mov.w) is used

    ; Read the RTC registers RTCTIM0
    ; return the values
    GetRTCTIM0
                mov.w   &RTCTIM0,R12
                reta
    
    ; Read the RTC register RTCTIM1
    ; return the values
    GetRTCTIM1
                mov.w   &RTCTIM1,R12
                reta
    

    look in errata:

    A write access to the RTC registers (SEC, MIN, HOUR, DATE, MON, YEAR, DOW) may
    result in unexpected results.

    so read access to the RTC should be ok,

  • 1. For write RTC count, so you mean this workaround apply for both counter mode and calendar mode?

    2. For read issue, please see the description in user's guide:

    Accessing the RTCNT1, RTCNT2, RTCNT3, RTCNT4, RT0PS, RT1PS registers
    When the counter clock is asynchronous to the CPU clock, any read from any RTCNT1,
    RTCNT2, RTCNT3, RTCNT4, RT0PS, or RT1PS register should occur while the counter is
    not operating. Otherwise, the results may be unpredictable. Alternatively, the counter may be
    read multiple times while operating, and a majority vote taken in software to determine the
    correct reading.

    So I think the workaround didn't solve this issue, or maybe it can't be solved totally. Am I right?

  • yes you have right

    when RTC clock is asynchronous to the CPU clock,
    RTC value can change during RTC value is reading
    and in this situation read value will be corrupted

    like you wrote earlier, when you read value from RTC
    you should make it two, or more times
    and you should compare value from first read to value from next read, they should be equal

  • Thanks. Then I have some questions about the code. See the code and my questions below:

    SetRTCMON:  push.w  R5                      ; push R5
                mov.b   &RTCDAY,R5              ; read RTCDAY into R5 ***Here only one read. So this means this function could be calle only when RTC is not running (by setting RTCHOLD?)***
                swpb    R12                     ; R12 holds month - swap lower and upper byte
                bis.w   R12,R5                  ; combine read RTCDAY and new RTCMON
                dint
                nop
                mov.w   R5,&RTCDATE             ; write to RTCDATE  
                nop
                nop
                nop
                nop
                eint
                mov.b   &RTCMON,R12             ; Read RTCMON register ***Why reading is needed here? Simply because we want to read the value back? That is, if we only need to set the value, can we remove this line the above nops when we want the code more compact?***
                pop.w   R5                      ; pop R5
                .if     $isdefed("__LARGE_CODE_MODEL__") = 0
                ret
                .else
                reta
                .endif

**Attention** This is a public forum