1 /*---------------------------------------------------------------------------*
2 Project: TwlSDK - RTC - libraries
3 File: external_ex.c
4
5 Copyright 2007-2008 Nintendo. All rights reserved.
6
7 These coded instructions, statements, and computer programs contain
8 proprietary information of Nintendo of America Inc. and/or Nintendo
9 Company Ltd., and are protected by Federal copyright law. They may
10 not be disclosed to third parties or copied or duplicated in any form,
11 in whole or in part, without the prior written consent of Nintendo.
12
13 $Date:: 2008-09-18#$
14 $Rev: 8573 $
15 $Author: okubata_ryoma $
16 *---------------------------------------------------------------------------*/
17
18 #include <nitro/os.h>
19 #include <nitro/rtc.h>
20 #include <twl/rtc/common/type_ex.h>
21 #include <twl/rtc/ARM9/api_ex.h>
22 #include "private.h"
23
24 /*---------------------------------------------------------------------------*
25 Internal Function Definitions
26 *---------------------------------------------------------------------------*/
27 static void RtcexGetResultCallback(RTCResult result, void* arg);
28 static void RtcexWaitBusy(u32* lock);
29
30 /*---------------------------------------------------------------------------*
31 Name: RTCEXi_GetCounterAsync
32
33 Description: Asynchronously reads the Up Counter value from the RTC.
34
35 Arguments: count: Specifies the buffer to store the Up Counter value.
36 callback: Specifies the function to be called when the asynchronous process is completed.
37 arg: Specifies the argument used when calling the callback function.
38
39 Returns: RTCResult: Returns the result of the process that starts the asynchronous device operation.
40 *---------------------------------------------------------------------------*/
41 RTCResult
RTCEXi_GetCounterAsync(u32 * count,RTCCallback callback,void * arg)42 RTCEXi_GetCounterAsync(u32* count, RTCCallback callback, void* arg)
43 {
44 OSIntrMode enabled;
45 RTCWork* w = RTCi_GetSysWork();
46
47 SDK_NULL_ASSERT(count);
48 SDK_NULL_ASSERT(callback);
49
50 /* Check lock */
51 enabled = OS_DisableInterrupts();
52 if (w->lock != RTC_LOCK_OFF)
53 {
54 (void)OS_RestoreInterrupts(enabled);
55 return RTC_RESULT_BUSY;
56 }
57 w->lock = RTC_LOCK_ON;
58 (void)OS_RestoreInterrupts(enabled);
59
60 /* Send the Up Counter read command */
61 w->sequence = RTC_SEQ_GET_COUNTER;
62 w->index = 0;
63 w->buffer[0] = (void*)count;
64 w->callback = callback;
65 w->callbackArg = arg;
66 if (RTCEXi_ReadRawCounterAsync() == TRUE)
67 {
68 return RTC_RESULT_SUCCESS;
69 }
70 else
71 {
72 w->lock = RTC_LOCK_OFF;
73 return RTC_RESULT_SEND_ERROR;
74 }
75 }
76
77 /*---------------------------------------------------------------------------*
78 Name: RTCEXi_GetCounter
79
80 Description: Reads the Up Counter value from the RTC.
81
82 Arguments: count: Specifies the buffer to store the Up Counter value.
83
84 Returns: RTCResult: Returns the device operation processing result.
85 *---------------------------------------------------------------------------*/
86 RTCResult
RTCEXi_GetCounter(u32 * count)87 RTCEXi_GetCounter(u32* count)
88 {
89 RTCWork* w = RTCi_GetSysWork();
90
91 w->commonResult = RTCEXi_GetCounterAsync(count, RtcexGetResultCallback, NULL);
92 if (w->commonResult == RTC_RESULT_SUCCESS)
93 {
94 RtcexWaitBusy(&(w->lock));
95 }
96 return w->commonResult;
97 }
98
99 /*---------------------------------------------------------------------------*
100 Name: RTCEXi_GetFoutAsync
101
102 Description: Asynchronously reads FOUT setting values from the RTC.
103
104 Arguments: fout: Specifies a buffer for storing FOUT setting values.
105 callback: Specifies the function to be called when the asynchronous process is completed.
106 arg: Specifies the argument used when calling the callback function.
107
108 Returns: RTCResult: Returns the result of the process that starts the asynchronous device operation.
109 *---------------------------------------------------------------------------*/
110 RTCResult
RTCEXi_GetFoutAsync(u16 * fout,RTCCallback callback,void * arg)111 RTCEXi_GetFoutAsync(u16* fout, RTCCallback callback, void* arg)
112 {
113 OSIntrMode enabled;
114 RTCWork* w = RTCi_GetSysWork();
115
116 SDK_NULL_ASSERT(fout);
117 SDK_NULL_ASSERT(callback);
118
119 /* Check lock */
120 enabled = OS_DisableInterrupts();
121 if (w->lock != RTC_LOCK_OFF)
122 {
123 (void)OS_RestoreInterrupts(enabled);
124 return RTC_RESULT_BUSY;
125 }
126 w->lock = RTC_LOCK_ON;
127 (void)OS_RestoreInterrupts(enabled);
128
129 /* Send the FOUT setting value read command */
130 w->sequence = RTC_SEQ_GET_FOUT;
131 w->index = 0;
132 w->buffer[0] = (void*)fout;
133 w->callback = callback;
134 w->callbackArg = arg;
135 if (RTCEXi_ReadRawFoutAsync() == TRUE)
136 {
137 return RTC_RESULT_SUCCESS;
138 }
139 else
140 {
141 w->lock = RTC_LOCK_OFF;
142 return RTC_RESULT_SEND_ERROR;
143 }
144 }
145
146 /*---------------------------------------------------------------------------*
147 Name: RTCEXi_GetFout
148
149 Description: Asynchronously reads FOUT setting values from the RTC.
150
151 Arguments: fout: Specifies a buffer for storing FOUT setting values.
152
153 Returns: RTCResult: Returns the device operation processing result.
154 *---------------------------------------------------------------------------*/
155 RTCResult
RTCEXi_GetFout(u16 * fout)156 RTCEXi_GetFout(u16* fout)
157 {
158 RTCWork* w = RTCi_GetSysWork();
159
160 w->commonResult = RTCEXi_GetFoutAsync(fout, RtcexGetResultCallback, NULL);
161 if (w->commonResult == RTC_RESULT_SUCCESS)
162 {
163 RtcexWaitBusy(&(w->lock));
164 }
165 return w->commonResult;
166 }
167
168 /*---------------------------------------------------------------------------*
169 Name: RTCEXi_SetFoutAsync
170
171 Description: Asynchronously writes FOUT settings to the RTC.
172
173 Arguments: fout: Specifies the buffer storing FOUT setting values.
174 callback: Specifies the function to be called when the asynchronous process is completed.
175 arg: Specifies the argument used when calling the callback function.
176
177 Returns: RTCResult: Returns the result of the process that starts the asynchronous device operation.
178 *---------------------------------------------------------------------------*/
179 RTCResult
RTCEXi_SetFoutAsync(const u16 * fout,RTCCallback callback,void * arg)180 RTCEXi_SetFoutAsync(const u16* fout, RTCCallback callback, void* arg)
181 {
182 OSIntrMode enabled;
183 RTCWork* w = RTCi_GetSysWork();
184
185 SDK_NULL_ASSERT(fout);
186 SDK_NULL_ASSERT(callback);
187
188 /* Check lock */
189 enabled = OS_DisableInterrupts();
190 if (w->lock != RTC_LOCK_OFF)
191 {
192 (void)OS_RestoreInterrupts(enabled);
193 return RTC_RESULT_BUSY;
194 }
195 w->lock = RTC_LOCK_ON;
196 (void)OS_RestoreInterrupts(enabled);
197
198 /* Edit the data to set. */
199 ((RTCRawDataEx*)(OS_GetSystemWork()->real_time_clock))->a.fout.fout = *fout;
200
201 /* Send the FOUT setting value write command */
202 w->sequence = RTC_SEQ_SET_FOUT;
203 w->index = 0;
204 w->callback = callback;
205 w->callbackArg = arg;
206 if (RTCEXi_WriteRawFoutAsync() == TRUE)
207 {
208 return RTC_RESULT_SUCCESS;
209 }
210 else
211 {
212 w->lock = RTC_LOCK_OFF;
213 return RTC_RESULT_SEND_ERROR;
214 }
215 }
216
217 /*---------------------------------------------------------------------------*
218 Name: RTCEXi_SetFout
219
220 Description: Writes FOUT settings values to the RTC.
221
222 Arguments: fout: Specifies the buffer storing FOUT setting values.
223
224 Returns: RTCResult: Returns the device operation processing result.
225 *---------------------------------------------------------------------------*/
226 RTCResult
RTCEXi_SetFout(const u16 * fout)227 RTCEXi_SetFout(const u16* fout)
228 {
229 RTCWork* w = RTCi_GetSysWork();
230
231 w->commonResult = RTCEXi_SetFoutAsync(fout, RtcexGetResultCallback, NULL);
232 if (w->commonResult == RTC_RESULT_SUCCESS)
233 {
234 RtcexWaitBusy(&(w->lock));
235 }
236 return w->commonResult;
237 }
238
239 /*---------------------------------------------------------------------------*
240 Name: RTCEXi_CommonCallback
241
242 Description: Shared callback function corresponding to additional commands used by asynchronous RTC functions.
243
244 Arguments: tag: PXI tag that shows the message type.
245 data: Message from ARM7.
246 err: PXI transfer error flag.
247
248 Returns: RTCResult: Returns the asynchronous device operation processing result.
249 *---------------------------------------------------------------------------*/
250 RTCResult
RTCEXi_CommonCallback(void)251 RTCEXi_CommonCallback(void)
252 {
253 RTCWork* w = RTCi_GetSysWork();
254 RTCResult result = RTC_RESULT_SUCCESS;
255
256 /* Various types of postprocessing according to the internal status */
257 switch(w->sequence)
258 {
259 /* Sequence to get the Up Counter value */
260 case RTC_SEQ_GET_COUNTER:
261 {
262 u32* pDst = (u32*)(w->buffer[0]);
263 RTCRawCounter* pSrc =
264 &(((RTCRawDataEx*)(OS_GetSystemWork()->real_time_clock))->a.counter);
265 /* Change the endianness */
266 *pDst = (u32)(pSrc->bytes[0] | (pSrc->bytes[1] << 8) | (pSrc->bytes[2] << 16));
267 }
268 break;
269 /* Sequence to get the FOUT setting value */
270 case RTC_SEQ_GET_FOUT:
271 {
272 u16* pDst = (u16*)(w->buffer[0]);
273 RTCRawFout* pSrc =
274 &(((RTCRawDataEx*)(OS_GetSystemWork()->real_time_clock))->a.fout);
275 *pDst = (u16)(pSrc->fout);
276 }
277 break;
278 /* Sequence to change the FOUT setting value */
279 case RTC_SEQ_SET_FOUT:
280 /* No processing in particular. */
281 break;
282 default:
283 /* Other unknown sequences */
284 w->index = 0;
285 result = RTC_RESULT_INVALID_COMMAND;
286 }
287 return result;
288 }
289
290 /*---------------------------------------------------------------------------*
291 Name: RtcexGetResultCallback
292
293 Description: Called when asynchronous processing completes. Updates the processing results of internal variables.
294
295 Arguments: result: The processing results from the asynchronous function.
296 arg: Not used.
297
298 Returns: None.
299 *---------------------------------------------------------------------------*/
300 static void
RtcexGetResultCallback(RTCResult result,void * arg)301 RtcexGetResultCallback(RTCResult result, void* arg)
302 {
303 #pragma unused(arg)
304
305 RTCi_GetSysWork()->commonResult = result;
306 }
307
308 #include <nitro/code32.h>
309 /*---------------------------------------------------------------------------*
310 Name: RtcWaitBusy
311
312 Description: Wait while the RTC's asynchronous processing is locked.
313
314 Arguments: r0: Pointer to the lock control member in the library's shared work buffer.
315
316 Returns: None.
317 *---------------------------------------------------------------------------*/
318 static asm void
RtcexWaitBusy(u32 * lock)319 RtcexWaitBusy(u32* lock)
320 {
321 loop:
322 ldr r1, [r0]
323 cmp r1, #RTC_LOCK_ON
324 beq loop
325 bx lr
326 }
327 #include <nitro/codereset.h>
328