339 lines
11 KiB
Plaintext
339 lines
11 KiB
Plaintext
;******************************************************************************
|
|
; MSP430FG5438 - Real Time Clock Workaround
|
|
;
|
|
; Description: This program demonstrates the RTC Workaround for the RTC
|
|
; Errata deailed in the XMS '5438 Errata under RTC3
|
|
; Assembly functions for the RTC workaround
|
|
; Allows safe access to the RTC registers that potentially have a write issue
|
|
; Code is aligned so that the lower 5 bits of the address of the instruction
|
|
; fetch following the RTC register write are equal
|
|
; Do not change the code in the ASM file (.s43) all nops in there are needed.
|
|
;
|
|
; Texas Instruments Inc.
|
|
; October 2008
|
|
; Built with CCE version 3.2.2
|
|
;
|
|
;*******************************************************************************
|
|
; !!!!!! Do not change the code. Every nop has a function !!!!!!
|
|
;*******************************************************************************
|
|
|
|
.cdecls C,LIST,"msp430x54x.h" ; Include device header file
|
|
|
|
;-------------------------------------------------------------------------------
|
|
.text ; Progam Start
|
|
;-------------------------------------------------------------------------------
|
|
.align 32
|
|
;-------------------------------------------------------------------------------
|
|
.global SetRTCYEAR
|
|
; int SetRTCYEAR(int year)
|
|
; year will be set in the RTCYEAR register
|
|
; return value is read back from the RTCYEAR register
|
|
; Works only in calendar mode (RTCMODE = 1)
|
|
; argument year is in R12
|
|
; return value is in R12
|
|
SetRTCYEAR: nop
|
|
nop
|
|
nop
|
|
nop
|
|
dint
|
|
nop
|
|
nop
|
|
nop
|
|
mov.w R12,&RTCYEAR ; Set RTCYEAR to year
|
|
nop
|
|
nop
|
|
mov.w &RTCYEAR,R12 ; Return value
|
|
nop
|
|
eint
|
|
nop
|
|
.if $isdefed("__LARGE_CODE_MODEL__") = 0
|
|
ret
|
|
.else
|
|
reta
|
|
.endif
|
|
|
|
|
|
;-------------------------------------------------------------------------------
|
|
.global SetRTCMON
|
|
; int SetRTCMON(int month)
|
|
; month will be set in the RTCMON register
|
|
; Workaround requires to write 16 bits into RTCDATE
|
|
; return value is read back from the RTCMON register
|
|
; argument month is in R12
|
|
; return value is in R12
|
|
SetRTCMON: push.w R5 ; push R5
|
|
mov.b &RTCDAY,R5 ; read RTCDAY into R5
|
|
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
|
|
nop
|
|
mov.b &RTCMON,R12 ; Read RTCMON register
|
|
pop.w R5 ; pop R5
|
|
.if $isdefed("__LARGE_CODE_MODEL__") = 0
|
|
ret
|
|
.else
|
|
reta
|
|
.endif
|
|
;-------------------------------------------------------------------------------
|
|
.global SetRTCDAY
|
|
; int SetRTCDAY(int day)
|
|
; day will be set in the RTCDAY register
|
|
; Workaround requires to write 16 bits into RTCDATE
|
|
; return value is read back from the RTCDAY register
|
|
; argument day is in R12
|
|
; return value is in R12
|
|
nop
|
|
nop
|
|
nop
|
|
nop
|
|
nop
|
|
nop
|
|
nop
|
|
nop
|
|
nop
|
|
nop
|
|
nop
|
|
nop
|
|
SetRTCDAY: ; R12 holds day in lower byte
|
|
push.w R5 ; push R5
|
|
mov.b &RTCMON,R5 ; read RTCMON into lower byte of R5
|
|
swpb R5 ; month is now in higher byte of R5
|
|
bic.w #00FFh,R5 ; clear lower byte of R5
|
|
bis.w R12,R5 ; combine read RTCDAY and new RTCMON
|
|
dint
|
|
nop
|
|
mov.w R5,&RTCDATE ; write to RTCDATE
|
|
nop
|
|
eint
|
|
nop
|
|
mov.b &RTCDAY,R12 ; Read RTCDAY register
|
|
pop.w R5 ; pop R5
|
|
.if $isdefed("__LARGE_CODE_MODEL__") = 0
|
|
ret
|
|
.else
|
|
reta
|
|
.endif
|
|
;-------------------------------------------------------------------------------
|
|
.global SetRTCDOW
|
|
; int SetRTCDOW(int dow)
|
|
; dow will be set in the RTCDOW register
|
|
; Workaround requires to write 16 bits into RTCTIM1
|
|
; return value is read back from the RTCDOW register
|
|
; argument dow is in R12
|
|
; return value is in R12
|
|
SetRTCDOW: push.w R5 ; push R5
|
|
mov.b &RTCHOUR,R5 ; read RTCHOUR into R5
|
|
swpb R12 ; R12 holds dow - swap lower and upper byte
|
|
bis.w R12, R5 ; combine read RTCHOUR and new RTCDOW
|
|
dint
|
|
nop
|
|
mov.w R5,&RTCTIM1 ; write to RTCTIM1
|
|
nop
|
|
eint
|
|
nop
|
|
mov.b &RTCDOW,R12 ; Read RTCDOW register
|
|
pop.w R5 ; pop R5
|
|
.if $isdefed("__LARGE_CODE_MODEL__") = 0
|
|
ret
|
|
.else
|
|
reta
|
|
.endif
|
|
;-------------------------------------------------------------------------------
|
|
.global SetRTCHOUR
|
|
; int SetRTCHOUR(int hour)
|
|
; hour will be set in the RTCHOUR register
|
|
; Workaround requires to write 16 bits into RTCTIM1
|
|
; return value is read back from the RTCHOUR register
|
|
; argument hour is in R12
|
|
; return value is in R12
|
|
SetRTCHOUR: ; R12 holds day in lower byte
|
|
push.w R5 ; push R5
|
|
mov.b &RTCDOW,R5 ; read RTCDOW into lower byte of R5
|
|
swpb R5 ; dow is now in higher byte of R5
|
|
bis.w R12,R5 ; combine read RTCDOW and new RTCHOUR
|
|
dint
|
|
nop
|
|
nop
|
|
mov.w R5,&RTCTIM1 ; write to RTCTIM1
|
|
nop
|
|
eint
|
|
nop
|
|
mov.b &RTCHOUR,R12 ; Read RTCHOUR register
|
|
pop.w R5 ; pop R5
|
|
.if $isdefed("__LARGE_CODE_MODEL__") = 0
|
|
ret
|
|
.else
|
|
reta
|
|
.endif
|
|
;-------------------------------------------------------------------------------
|
|
.global SetRTCMIN
|
|
; 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
|
|
nop
|
|
mov.b &RTCMIN,R12 ; Read RTCDOW register
|
|
pop.w R5 ; pop R5
|
|
.if $isdefed("__LARGE_CODE_MODEL__") = 0
|
|
ret
|
|
.else
|
|
reta
|
|
.endif
|
|
;-------------------------------------------------------------------------------
|
|
.global SetRTCSEC
|
|
; 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
|
|
mov.w R5,&RTCTIM0 ; write to RTCTIM0
|
|
nop
|
|
eint
|
|
nop
|
|
mov.b &RTCSEC, R12 ; Read RTCSEC register
|
|
pop.w R5 ; pop R5
|
|
.if $isdefed("__LARGE_CODE_MODEL__") = 0
|
|
ret
|
|
.else
|
|
reta
|
|
.endif
|
|
;-------------------------------------------------------------------------------
|
|
|
|
.global GetRTCTIM0
|
|
; Read the RTC registers RTCTIM0
|
|
; return the values
|
|
GetRTCTIM0:
|
|
mov.w &RTCTIM0,R12
|
|
.if $isdefed("__LARGE_CODE_MODEL__") = 0
|
|
ret
|
|
.else
|
|
reta
|
|
.endif
|
|
|
|
.global GetRTCTIM1
|
|
; Read the RTC register RTCTIM1
|
|
; return the values
|
|
GetRTCTIM1:
|
|
mov.w &RTCTIM1,R12
|
|
.if $isdefed("__LARGE_CODE_MODEL__") = 0
|
|
ret
|
|
.else
|
|
reta
|
|
.endif
|
|
|
|
.global GetRTCDATE
|
|
; Read the RTC register RTCDATE
|
|
; return the values
|
|
GetRTCDATE:
|
|
mov.w &RTCDATE,R12
|
|
.if $isdefed("__LARGE_CODE_MODEL__") = 0
|
|
ret
|
|
.else
|
|
reta
|
|
.endif
|
|
|
|
.global GetRTCYEAR
|
|
; Read the RTC registers RTCYEAR
|
|
; return the values
|
|
GetRTCYEAR:
|
|
mov.w &RTCYEAR, R12
|
|
.if $isdefed("__LARGE_CODE_MODEL__") = 0
|
|
ret
|
|
.else
|
|
reta
|
|
.endif
|
|
|
|
.global GetRTCMON
|
|
; Read the RTC register RTCMON
|
|
; return the values
|
|
GetRTCMON:
|
|
mov.b &RTCMON, R12
|
|
.if $isdefed("__LARGE_CODE_MODEL__") = 0
|
|
ret
|
|
.else
|
|
reta
|
|
.endif
|
|
|
|
.global GetRTCDOW
|
|
; Read the RTC register RTCDOW
|
|
; return the values
|
|
GetRTCDOW:
|
|
mov.b &RTCDOW, R12
|
|
.if $isdefed("__LARGE_CODE_MODEL__") = 0
|
|
ret
|
|
.else
|
|
reta
|
|
.endif
|
|
|
|
.global GetRTCDAY
|
|
; Read the RTC register RTCDOW
|
|
; return the values
|
|
GetRTCDAY:
|
|
mov.b &RTCDAY, R12
|
|
.if $isdefed("__LARGE_CODE_MODEL__") = 0
|
|
ret
|
|
.else
|
|
reta
|
|
.endif
|
|
|
|
.global GetRTCHOUR
|
|
; Read the RTC register RTCDOW
|
|
; return the values
|
|
GetRTCHOUR:
|
|
mov.b &RTCHOUR, R12
|
|
.if $isdefed("__LARGE_CODE_MODEL__") = 0
|
|
ret
|
|
.else
|
|
reta
|
|
.endif
|
|
|
|
.global GetRTCMIN
|
|
; Read the RTC register RTCDOW
|
|
; return the values
|
|
GetRTCMIN:
|
|
mov.b &RTCMIN, R12
|
|
.if $isdefed("__LARGE_CODE_MODEL__") = 0
|
|
ret
|
|
.else
|
|
reta
|
|
.endif
|
|
|
|
.global GetRTCSEC
|
|
; Read the RTC register RTCDOW
|
|
; return the values
|
|
GetRTCSEC:
|
|
mov.b &RTCSEC, R12
|
|
.if $isdefed("__LARGE_CODE_MODEL__") = 0
|
|
ret
|
|
.else
|
|
reta
|
|
.endif
|
|
|