RTC 8.45 KB
Newer Older
Ben Avison's avatar
Ben Avison committed
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
; Copyright 2011 Castle Technology Ltd
;
; Licensed under the Apache License, Version 2.0 (the "License");
; you may not use this file except in compliance with the License.
; You may obtain a copy of the License at
;
;     http://www.apache.org/licenses/LICENSE-2.0
;
; Unless required by applicable law or agreed to in writing, software
; distributed under the License is distributed on an "AS IS" BASIS,
; WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
; See the License for the specific language governing permissions and
; limitations under the License.
;

Robert Sprowson's avatar
Robert Sprowson committed
16 17 18 19 20 21
        GET     Hdr:ListOpts
        GET     Hdr:Macros
        GET     Hdr:System
        GET     Hdr:Machine.<Machine>
        GET     Hdr:ImageSize.<ImageSize>
        $GetIO
Ben Avison's avatar
Ben Avison committed
22

Robert Sprowson's avatar
Robert Sprowson committed
23 24 25 26
        GET     Hdr:OSEntries
        GET     Hdr:HALEntries
        GET     Hdr:HALDevice
        GET     Hdr:RTCDevice
Ben Avison's avatar
Ben Avison committed
27

Robert Sprowson's avatar
Robert Sprowson committed
28 29 30 31
        GET     hdr.omap4430
        GET     hdr.StaticWS
        GET     hdr.Timers
        GET     hdr.PRCM
Ben Avison's avatar
Ben Avison committed
32

Robert Sprowson's avatar
Robert Sprowson committed
33
        AREA    |Asm$$Code|, CODE, READONLY, PIC
Ben Avison's avatar
Ben Avison committed
34

Robert Sprowson's avatar
Robert Sprowson committed
35 36 37
        EXPORT  RTC_Init
        IMPORT  TPSRead
        IMPORT  TPSWrite
38
        IMPORT  memcpy
Ben Avison's avatar
Ben Avison committed
39 40

; TWL6030 RTC IIC address
Robert Sprowson's avatar
Robert Sprowson committed
41
TPSRTC_IIC              *       &48
Ben Avison's avatar
Ben Avison committed
42 43

; Some RTC registers
Robert Sprowson's avatar
Robert Sprowson committed
44 45 46
SECONDS_REG             *       &00
RTC_CTRL_REG            *       &10
RTC_STATUS_REG          *       &11
Ben Avison's avatar
Ben Avison committed
47 48

; RTC_CTRL_REG bitfields
Robert Sprowson's avatar
Robert Sprowson committed
49 50 51 52 53 54 55
RTC_CTRL_STOP_RTC_M             *       (1 << 0)
RTC_CTRL_ROUND_30S_M            *       (1 << 1)
RTC_CTRL_AUTO_COMP_M            *       (1 << 2)
RTC_CTRL_MODE_12_24_M           *       (1 << 3)
RTC_CTRL_TEST_MODE_M            *       (1 << 4)
RTC_CTRL_SET_32_COUNTER_M       *       (1 << 5)
RTC_CTRL_GET_TIME_M             *       (1 << 6)
Ben Avison's avatar
Ben Avison committed
56 57

; RTC_STATUS_REG bitfields
Robert Sprowson's avatar
Robert Sprowson committed
58 59 60 61 62 63 64
RTC_STATUS_RUN_M                *       (1 << 1)
RTC_STATUS_1S_EVENT_M           *       (1 << 2)
RTC_STATUS_1M_EVENT_M           *       (1 << 3)
RTC_STATUS_1H_EVENT_M           *       (1 << 4)
RTC_STATUS_1D_EVENT_M           *       (1 << 5)
RTC_STATUS_ALARM_M              *       (1 << 6)
RTC_STATUS_POWER_UP_M           *       (1 << 7)
Ben Avison's avatar
Ben Avison committed
65 66

RTC_Init
Robert Sprowson's avatar
Robert Sprowson committed
67
        ; Just register our HAL Device with the OS
68 69 70 71 72 73 74 75
        ADRL    a1, RTCWS
        ADR     a2, RTCDeviceTemplate
        MOV     a3, #RTCSize
        Push    "lr"
        BL      memcpy
        Pull    "lr"
        STR     sb, [a1, #RTCDeviceHAL_SB]

76
        MOV     a2, a1
Robert Sprowson's avatar
Robert Sprowson committed
77 78
        MOV     a1, #0
        CallOS  OS_AddDevice, tailcall
Ben Avison's avatar
Ben Avison committed
79

80
RTCDeviceTemplate
Robert Sprowson's avatar
Robert Sprowson committed
81 82 83 84 85 86 87 88 89 90 91 92 93 94 95
        DCW     HALDeviceType_SysPeri + HALDeviceSysPeri_RTC
        DCW     HALDeviceID_RTC_TWL6030
        DCD     HALDeviceBus_Ser + HALDeviceSerBus_IIC
        DCD     0               ; API version
        DCD     RTCDesc
        DCD     0               ; Address - N/A
        %       12              ; Reserved
        DCD     RTCActivate
        DCD     RTCDeactivate
        DCD     RTCReset
        DCD     RTCSleep
        DCD     -1              ; Interrupt N/A
        DCD     0
        %       8
        DCB     RTCTimeFormat_BCD
96 97 98 99
        DCB     RTCFormatFlags_BCD_1BasedDay + \
                RTCFormatFlags_BCD_1BasedMonth + \
                RTCFormatFlags_BCD_YearLOIsGood + \
                RTCFormatFlags_BCD_NeedsYearHelp
Robert Sprowson's avatar
Robert Sprowson committed
100 101 102
        %       2
        DCD     RTCReadTime
        DCD     RTCWriteTime
Ben Avison's avatar
Ben Avison committed
103 104

RTCDesc
105
        DCB     "TWL6030-compatible real-time clock",0
Ben Avison's avatar
Ben Avison committed
106

Robert Sprowson's avatar
Robert Sprowson committed
107
        ALIGN
Ben Avison's avatar
Ben Avison committed
108 109

RTCActivate
Robert Sprowson's avatar
Robert Sprowson committed
110
        MOV     a1, #1
Ben Avison's avatar
Ben Avison committed
111 112
RTCDeactivate
RTCReset
Robert Sprowson's avatar
Robert Sprowson committed
113
        MOV     pc, lr
Ben Avison's avatar
Ben Avison committed
114 115

RTCSleep
Robert Sprowson's avatar
Robert Sprowson committed
116 117
        MOV     a1, #0 ; Previously at full power
        MOV     pc, lr
Ben Avison's avatar
Ben Avison committed
118 119

RTCReadTime
Robert Sprowson's avatar
Robert Sprowson committed
120 121 122 123 124 125
        ; In:
        ; a1 = HALDevice ptr
        ; a2 = RTCTimeStruct ptr
        ; Out:
        ; a1 = return code
        ; RTCTimeStruct updated
126 127 128
        Push    "v1,v3,sb,lr"
        LDR     sb, [a1, #RTCDeviceHAL_SB]
        LDR     v1, OSentries+4*OS_IICOpV ; for TPSRead/TPSWrite
Robert Sprowson's avatar
Robert Sprowson committed
129 130 131 132 133 134 135 136 137 138 139 140 141 142 143
        MOV     v3, a2
        ; Reading the time safely involves several transfers:
        ; 1. Read RTC_STATUS_REG. If bit 1 is clear, the RTC is stopped and we can just
        ;    assume its contents are invalid.
        ; 2. Set RTC_CTRL_REG=&41 (RTC running, GET_TIME set, 24hr mode). GET_TIME will read
        ;    the time from the RTC circuitry and latch it into the time registers (the regular
        ;    time registers, NOT the alarm ones as stated by the manual!)
        ; 3. Read the time regs to read latched time.
        ; There's no need to clear GET_TIME either, as it is cleared automatically by the HW.
        MOV     a1, #TPSRTC_IIC*2
        SUB     sp, sp, #4 ; temp small buffer on stack
        MOV     a3, #1
        MOV     a4, #RTC_STATUS_REG
        MOV     a2, sp
        BL      TPSRead
144
        CMP     a1, #IICStatus_Completed
Robert Sprowson's avatar
Robert Sprowson committed
145 146 147 148 149 150
        LDRB    ip, [a2]
        MOV     a1, #RTCRetCode_InvalidTime
        MOVNE   a1, #RTCRetCode_Error
        EOR     ip, ip, #RTC_STATUS_RUN_M
        TSTEQ   ip, #RTC_STATUS_RUN_M
        ADDNE   sp, sp, #4
151
        Pull    "v1,v3,sb,pc", NE
Robert Sprowson's avatar
Robert Sprowson committed
152 153 154 155 156
        MOV     ip, #(RTC_CTRL_GET_TIME_M + RTC_CTRL_STOP_RTC_M)
        STR     ip, [a2]
        MOV     a1, #TPSRTC_IIC*2
        MOV     a4, #RTC_CTRL_REG
        BL      TPSWrite
157
        CMP     a1, #IICStatus_Completed
Robert Sprowson's avatar
Robert Sprowson committed
158 159
        MOVNE   a1, #RTCRetCode_Error
        ADD     sp, sp, #4
160
        Pull    "v1,v3,sb,pc", NE
Robert Sprowson's avatar
Robert Sprowson committed
161 162 163 164 165 166 167 168 169 170 171
        MOV     a1, #TPSRTC_IIC*2
        ; We can read the time directly into the RTCTimeStruct buffer
        ASSERT RTCTimeStruct_BCD_Minutes=RTCTimeStruct_BCD_Seconds+1
        ASSERT RTCTimeStruct_BCD_Hours=RTCTimeStruct_BCD_Seconds+2
        ASSERT RTCTimeStruct_BCD_DayOfMonth=RTCTimeStruct_BCD_Seconds+3
        ASSERT RTCTimeStruct_BCD_Month=RTCTimeStruct_BCD_Seconds+4
        ASSERT RTCTimeStruct_BCD_YearLO=RTCTimeStruct_BCD_Seconds+5
        ADD     a2, v3, #RTCTimeStruct_BCD_Seconds
        MOV     a3, #6
        MOV     a4, #SECONDS_REG
        BL      TPSRead
172
        CMP     a1, #IICStatus_Completed
Robert Sprowson's avatar
Robert Sprowson committed
173
        MOVNE   a1, #RTCRetCode_Error
174
        ASSERT  IICStatus_Completed = 0
175 176
        STREQB  a1, [v3, #RTCTimeStruct_BCD_Centiseconds] ; No centisecond time
        STREQB  a1, [v3, #RTCTimeStruct_BCD_YearHI] ; Kernel gives year help
Robert Sprowson's avatar
Robert Sprowson committed
177
        ASSERT  RTCRetCode_OK = 0
178
        Pull    "v1,v3,sb,pc"
Ben Avison's avatar
Ben Avison committed
179 180

RTCWriteTime
Robert Sprowson's avatar
Robert Sprowson committed
181 182 183 184 185
        ; In:
        ; a1 = HALDevice ptr
        ; a2 = RTCTimeStruct ptr
        ; Out:
        ; a1 = return code
186 187 188
        Push    "v1,v3,sb,lr"
        LDR     sb, [a1, #RTCDeviceHAL_SB]
        LDR     v1, OSentries+4*OS_IICOpV ; for TPSRead/TPSWrite
Robert Sprowson's avatar
Robert Sprowson committed
189 190 191 192 193 194 195 196 197 198 199 200 201
        MOV     v3, a2
        ; Writing the time safely involves several transfers:
        ; 1. Write 0 to RTC_CTRL_REG to stop the clock (just in case there are any issues with
        ;    the clock updating while it's being written to)
        ; 2. Write the new time values
        ; 3. Write 1 to RTC_CTRL_REG to start the clock
        MOV     a1, #TPSRTC_IIC*2
        MOV     ip, #0
        STR     ip, [sp,#-4]! ; temp small buffer on stack
        MOV     a3, #1
        MOV     a4, #RTC_CTRL_REG
        MOV     a2, sp
        BL      TPSWrite
202
        CMP     a1, #IICStatus_Completed
Robert Sprowson's avatar
Robert Sprowson committed
203 204
        MOVNE   a1, #RTCRetCode_Error
        ADDNE   sp, sp, #4
205
        Pull    "v1,v3,sb,pc", NE
Robert Sprowson's avatar
Robert Sprowson committed
206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227
        MOV     a1, #TPSRTC_IIC*2
        ; We can write the time directly from the RTCTimeStruct buffer
        ASSERT RTCTimeStruct_BCD_Minutes=RTCTimeStruct_BCD_Seconds+1
        ASSERT RTCTimeStruct_BCD_Hours=RTCTimeStruct_BCD_Seconds+2
        ASSERT RTCTimeStruct_BCD_DayOfMonth=RTCTimeStruct_BCD_Seconds+3
        ASSERT RTCTimeStruct_BCD_Month=RTCTimeStruct_BCD_Seconds+4
        ASSERT RTCTimeStruct_BCD_YearLO=RTCTimeStruct_BCD_Seconds+5
        ADD     a2, v3, #RTCTimeStruct_BCD_Seconds
        MOV     a3, #6
        MOV     a4, #SECONDS_REG
        ; Sometimes we don't write the time, so skip those bytes if necessary
        LDRB    ip, [a2]
        CMP     ip, #255
        ADDEQ   a2, a2, #3
        SUBEQ   a3, a3, #3
        ADDEQ   a4, a4, #3
        ; Sometimes we don't write the date either
        LDRB    ip, [v3, #RTCTimeStruct_BCD_DayOfMonth]
        CMP     ip, #255
        SUBEQS  a3, a3, #3
        BEQ     %FT01 ; Nothing left to write!
        BL      TPSWrite
228
        CMP     a1, #IICStatus_Completed
Robert Sprowson's avatar
Robert Sprowson committed
229 230
        MOVNE   a1, #RTCRetCode_Error
        ADDNE   sp, sp, #4
231
        Pull    "v1,v3,sb,pc", NE
Ben Avison's avatar
Ben Avison committed
232
01
Robert Sprowson's avatar
Robert Sprowson committed
233 234 235 236 237 238
        MOV     a3, #RTC_CTRL_STOP_RTC_M
        STR     a3, [sp]
        MOV     a2, sp
        MOV     a4, #RTC_CTRL_REG
        MOV     a1, #TPSRTC_IIC*2
        BL      TPSWrite
239 240
        CMP     a1, #IICStatus_Completed
        ASSERT  RTCRetCode_OK = IICStatus_Completed
Robert Sprowson's avatar
Robert Sprowson committed
241 242
        MOVNE   a1, #RTCRetCode_Error
        ADD     sp, sp, #4
243
        Pull    "v1,v3,sb,pc"
Ben Avison's avatar
Ben Avison committed
244

Robert Sprowson's avatar
Robert Sprowson committed
245
        END