1 /*---------------------------------------------------------------------------*
2 Project: TwlSDK - RTC - libraries
3 File: external.c
4
5 Copyright 2003-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-17#$
14 $Rev: 8556 $
15 $Author:$
16 *---------------------------------------------------------------------------*/
17
18 #include <nitro/os.h>
19 #include <nitro/rtc.h>
20
21 #ifdef SDK_TWL
22 #include <twl/rtc/ARM9/api_ex.h>
23 #include "private.h"
24 #endif
25
26 /*---------------------------------------------------------------------------*
27 Structure Definitions
28 *---------------------------------------------------------------------------*/
29 #ifndef SDK_TWL
30
31 // Lock definition for exclusive processing of asynchronous functions
32 typedef enum RTCLock
33 {
34 RTC_LOCK_OFF = 0, // Unlock status
35 RTC_LOCK_ON, // Lock status
36 RTC_LOCK_MAX
37 }
38 RTCLock;
39
40 // Sequence definitions for processing that includes continuous command transmission.
41 typedef enum RTCSequence
42 {
43 RTC_SEQ_GET_DATE = 0, // Sequence for getting dates
44 RTC_SEQ_GET_TIME, // Sequence for getting times
45 RTC_SEQ_GET_DATETIME, // Sequence for getting dates and times
46 RTC_SEQ_SET_DATE, // Sequence for setting dates
47 RTC_SEQ_SET_TIME, // Sequence for setting times
48 RTC_SEQ_SET_DATETIME, // Sequence for setting dates and times
49 RTC_SEQ_GET_ALARM1_STATUS, // Sequence for getting alarm 1's status
50 RTC_SEQ_GET_ALARM2_STATUS, // Sequence for getting alarm 2's status
51 RTC_SEQ_GET_ALARM_PARAM, // Sequence for getting alarm setting values
52 RTC_SEQ_SET_ALARM1_STATUS, // Sequence for changing alarm 1's status
53 RTC_SEQ_SET_ALARM2_STATUS, // Sequence for changing alarm 2's status
54 RTC_SEQ_SET_ALARM1_PARAM, // Sequence for changing alarm 1's setting values
55 RTC_SEQ_SET_ALARM2_PARAM, // Sequence for changing alarm 2's setting values
56 RTC_SEQ_SET_HOUR_FORMAT, // Sequence for changing the format of the time notation
57 RTC_SEQ_SET_REG_STATUS2, // Sequence for status 2 register writes
58 RTC_SEQ_SET_REG_ADJUST, // Sequence for adjust register writes
59 RTC_SEQ_MAX
60 }
61 RTCSequence;
62
63 // Work structure
64 typedef struct RTCWork
65 {
66 u32 lock; // Exclusive lock
67 RTCCallback callback; // For saving an asynchronous callback function
68 void *buffer[2]; // For storing asynchronous function parameters
69 void *callbackArg; // For saving arguments to the callback function
70 u32 sequence; // For controlling continuous processing mode
71 u32 index; // For controlling continuous processing status
72 RTCInterrupt interrupt; // For saving the call function(s) when an alarm notification occurs
73 RTCResult commonResult; // For saving asynchronous function processing results
74
75 }
76 RTCWork;
77
78 #endif
79
80 /*---------------------------------------------------------------------------*
81 Static Variable Definitions
82 *---------------------------------------------------------------------------*/
83 static u16 rtcInitialized; // Initialized verify flag
84 static RTCWork rtcWork; // Structure that combines work variables
85
86 /*---------------------------------------------------------------------------*
87 Internal Function Definitions
88 *---------------------------------------------------------------------------*/
89 static void RtcCommonCallback(PXIFifoTag tag, u32 data, BOOL err);
90 static u32 RtcBCD2HEX(u32 bcd);
91 static u32 RtcHEX2BCD(u32 hex);
92 static BOOL RtcCheckAlarmParam(const RTCAlarmParam *param);
93 static RTCRawAlarm RtcMakeAlarmParam(const RTCAlarmParam *param);
94 static BOOL RtcCheckDate(const RTCDate *date, RTCRawDate *raw);
95 static BOOL RtcCheckTime(const RTCTime *time, RTCRawTime *raw);
96 static void RtcGetResultCallback(RTCResult result, void *arg);
97 static void RtcWaitBusy(void);
98
99 /*---------------------------------------------------------------------------*
100 Name: RTC_Init
101
102 Description: Initializes the RTC library.
103 Notice: If component-side initialization detects that the power supply to the RTC device has been completely cut (this is caused for example by removing the battery), the internal state of the device will be reset. When this happens, the date is initialized to 2000/01/01 (Saturday), and the time is set to 00:00:00 (24-hour clock).
104
105
106
107 The RTC alarm-related settings values are zero-cleared in the system startup sequence regardless of removed batteries, but when applications are restarted by a software reset, the settings carry over.
108
109
110
111 Arguments: None.
112
113 Returns: None.
114 *---------------------------------------------------------------------------*/
RTC_Init(void)115 void RTC_Init(void)
116 {
117 // Verification of non-initialization
118 if (rtcInitialized)
119 {
120 return;
121 }
122 rtcInitialized = 1;
123
124 // Work variable initialization
125 rtcWork.lock = RTC_LOCK_OFF;
126 rtcWork.callback = NULL;
127 rtcWork.interrupt = NULL;
128 rtcWork.buffer[0] = NULL;
129 rtcWork.buffer[1] = NULL;
130
131 // Wait until the ARM7 RTC library is started
132 PXI_Init();
133 while (!PXI_IsCallbackReady(PXI_FIFO_TAG_RTC, PXI_PROC_ARM7))
134 {
135 }
136
137 // Set the PXI callback function
138 PXI_SetFifoRecvCallback(PXI_FIFO_TAG_RTC, RtcCommonCallback);
139 }
140
141 /*---------------------------------------------------------------------------*
142 Name: RTC_GetDateAsync
143
144 Description: Asynchronously reads date data from the RTC.
145
146 Arguments: date: Buffer for storing date data
147 callback: Function to be called when the asynchronous process is completed
148 arg: Argument used when calling the callback function
149
150 Returns: RTCResult: Result of the process that starts the asynchronous device operation.
151 *---------------------------------------------------------------------------*/
RTC_GetDateAsync(RTCDate * date,RTCCallback callback,void * arg)152 RTCResult RTC_GetDateAsync(RTCDate *date, RTCCallback callback, void *arg)
153 {
154 OSIntrMode enabled;
155
156 SDK_ASSERT(date != NULL);
157 SDK_ASSERT(callback != NULL);
158
159 // Check lock
160 enabled = OS_DisableInterrupts();
161 if (rtcWork.lock != RTC_LOCK_OFF)
162 {
163 (void)OS_RestoreInterrupts(enabled);
164 return RTC_RESULT_BUSY;
165 }
166 rtcWork.lock = RTC_LOCK_ON;
167 (void)OS_RestoreInterrupts(enabled);
168
169 // Send date read command
170 rtcWork.sequence = RTC_SEQ_GET_DATE;
171 rtcWork.index = 0;
172 rtcWork.buffer[0] = (void *)date;
173 rtcWork.callback = callback;
174 rtcWork.callbackArg = arg;
175 if (RTCi_ReadRawDateAsync())
176 {
177 return RTC_RESULT_SUCCESS;
178 }
179 else
180 {
181 rtcWork.lock = RTC_LOCK_OFF;
182 return RTC_RESULT_SEND_ERROR;
183 }
184 }
185
186 /*---------------------------------------------------------------------------*
187 Name: RTC_GetDate
188
189 Description: Reads date data from the RTC.
190
191 Arguments: date: Buffer for storing date data
192
193 Returns: RTCResult: Device operation processing result.
194 *---------------------------------------------------------------------------*/
RTC_GetDate(RTCDate * date)195 RTCResult RTC_GetDate(RTCDate *date)
196 {
197 rtcWork.commonResult = RTC_GetDateAsync(date, RtcGetResultCallback, NULL);
198 if (rtcWork.commonResult == RTC_RESULT_SUCCESS)
199 {
200 RtcWaitBusy();
201 }
202 return rtcWork.commonResult;
203 }
204
205 /*---------------------------------------------------------------------------*
206 Name: RTC_GetTimeAsync
207
208 Description: Asynchronously reads time data from the RTC.
209
210 Arguments: time: Buffer for storing time data
211 callback: Function to be called when the asynchronous process is completed
212 arg: Argument used when calling the callback function
213
214 Returns: RTCResult: Result of the process that starts the asynchronous device operation.
215 *---------------------------------------------------------------------------*/
RTC_GetTimeAsync(RTCTime * time,RTCCallback callback,void * arg)216 RTCResult RTC_GetTimeAsync(RTCTime *time, RTCCallback callback, void *arg)
217 {
218 OSIntrMode enabled;
219
220 SDK_NULL_ASSERT(time);
221 SDK_NULL_ASSERT(callback);
222
223 // Check lock
224 enabled = OS_DisableInterrupts();
225 if (rtcWork.lock != RTC_LOCK_OFF)
226 {
227 (void)OS_RestoreInterrupts(enabled);
228 return RTC_RESULT_BUSY;
229 }
230 rtcWork.lock = RTC_LOCK_ON;
231 (void)OS_RestoreInterrupts(enabled);
232
233 // Send time read command
234 rtcWork.sequence = RTC_SEQ_GET_TIME;
235 rtcWork.index = 0;
236 rtcWork.buffer[0] = (void *)time;
237 rtcWork.callback = callback;
238 rtcWork.callbackArg = arg;
239 if (RTCi_ReadRawTimeAsync())
240 {
241 return RTC_RESULT_SUCCESS;
242 }
243 else
244 {
245 rtcWork.lock = RTC_LOCK_OFF;
246 return RTC_RESULT_SEND_ERROR;
247 }
248 }
249
250 /*---------------------------------------------------------------------------*
251 Name: RTC_GetTime
252
253 Description: Reads time data from the RTC.
254
255 Arguments: time: Buffer for storing time data
256
257 Returns: RTCResult: Device operation processing result.
258 *---------------------------------------------------------------------------*/
RTC_GetTime(RTCTime * time)259 RTCResult RTC_GetTime(RTCTime *time)
260 {
261 rtcWork.commonResult = RTC_GetTimeAsync(time, RtcGetResultCallback, NULL);
262 if (rtcWork.commonResult == RTC_RESULT_SUCCESS)
263 {
264 RtcWaitBusy();
265 }
266 return rtcWork.commonResult;
267 }
268
269 /*---------------------------------------------------------------------------*
270 Name: RTC_GetDateTimeAsync
271
272 Description: Asynchronously reads date and time data from the RTC.
273
274 Arguments: date: Buffer for storing date data
275 time: Buffer for storing time data
276 callback: Function to be called when the asynchronous process is completed
277 arg: Argument used when calling the callback function
278
279 Returns: RTCResult: Result of the process that starts the asynchronous device operation.
280 *---------------------------------------------------------------------------*/
RTC_GetDateTimeAsync(RTCDate * date,RTCTime * time,RTCCallback callback,void * arg)281 RTCResult RTC_GetDateTimeAsync(RTCDate *date, RTCTime *time, RTCCallback callback, void *arg)
282 {
283 OSIntrMode enabled;
284
285 SDK_NULL_ASSERT(date);
286 SDK_NULL_ASSERT(time);
287 SDK_NULL_ASSERT(callback);
288
289 // Check lock
290 enabled = OS_DisableInterrupts();
291 if (rtcWork.lock != RTC_LOCK_OFF)
292 {
293 (void)OS_RestoreInterrupts(enabled);
294 return RTC_RESULT_BUSY;
295 }
296 rtcWork.lock = RTC_LOCK_ON;
297 (void)OS_RestoreInterrupts(enabled);
298
299 // Send time read command
300 rtcWork.sequence = RTC_SEQ_GET_DATETIME;
301 rtcWork.index = 0;
302 rtcWork.buffer[0] = (void *)date;
303 rtcWork.buffer[1] = (void *)time;
304 rtcWork.callback = callback;
305 rtcWork.callbackArg = arg;
306 if (RTCi_ReadRawDateTimeAsync())
307 {
308 return RTC_RESULT_SUCCESS;
309 }
310 else
311 {
312 rtcWork.lock = RTC_LOCK_OFF;
313 return RTC_RESULT_SEND_ERROR;
314 }
315 }
316
317 /*---------------------------------------------------------------------------*
318 Name: RTC_GetDateTime
319
320 Description: Read date and time data from RTC.
321
322 Arguments: date: Buffer for storing date data
323 time: Buffer for storing time data
324
325 Returns: RTCResult: Device operation processing result.
326 *---------------------------------------------------------------------------*/
RTC_GetDateTime(RTCDate * date,RTCTime * time)327 RTCResult RTC_GetDateTime(RTCDate *date, RTCTime *time)
328 {
329 rtcWork.commonResult = RTC_GetDateTimeAsync(date, time, RtcGetResultCallback, NULL);
330 if (rtcWork.commonResult == RTC_RESULT_SUCCESS)
331 {
332 RtcWaitBusy();
333 }
334 return rtcWork.commonResult;
335 }
336
337 /*---------------------------------------------------------------------------*
338 Name: RTC_SetDateAsync
339
340 Description: Asynchronously writes date data to the RTC.
341
342 Arguments: date: Buffer where date data is stored
343 callback: Function to be called when the asynchronous process is completed
344 arg: Argument used when calling the callback function
345
346 Returns: RTCResult: Result of the process that starts the asynchronous device operation.
347 *---------------------------------------------------------------------------*/
RTC_SetDateAsync(const RTCDate * date,RTCCallback callback,void * arg)348 RTCResult RTC_SetDateAsync(const RTCDate *date, RTCCallback callback, void *arg)
349 {
350 OSIntrMode enabled;
351
352 SDK_NULL_ASSERT(date);
353 SDK_NULL_ASSERT(callback);
354
355 // Verify and edit the date to set
356 if (!RtcCheckDate(date, &(((RTCRawData *)(OS_GetSystemWork()->real_time_clock))->t.date)))
357 {
358 return RTC_RESULT_ILLEGAL_PARAMETER;
359 }
360
361 // Check lock
362 enabled = OS_DisableInterrupts();
363 if (rtcWork.lock != RTC_LOCK_OFF)
364 {
365 (void)OS_RestoreInterrupts(enabled);
366 return RTC_RESULT_BUSY;
367 }
368 rtcWork.lock = RTC_LOCK_ON;
369 (void)OS_RestoreInterrupts(enabled);
370
371 // Send date write command
372 rtcWork.sequence = RTC_SEQ_SET_DATE;
373 rtcWork.index = 0;
374 rtcWork.callback = callback;
375 rtcWork.callbackArg = arg;
376 if (RTCi_WriteRawDateAsync())
377 {
378 return RTC_RESULT_SUCCESS;
379 }
380 else
381 {
382 rtcWork.lock = RTC_LOCK_OFF;
383 return RTC_RESULT_SEND_ERROR;
384 }
385 }
386
387 /*---------------------------------------------------------------------------*
388 Name: RTC_SetDate
389
390 Description: Writes date data to the RTC.
391
392 Arguments: date: Buffer where date data is stored
393
394 Returns: RTCResult: Device operation processing result.
395 *---------------------------------------------------------------------------*/
RTC_SetDate(const RTCDate * date)396 RTCResult RTC_SetDate(const RTCDate *date)
397 {
398 rtcWork.commonResult = RTC_SetDateAsync(date, RtcGetResultCallback, NULL);
399 if (rtcWork.commonResult == RTC_RESULT_SUCCESS)
400 {
401 RtcWaitBusy();
402 }
403 return rtcWork.commonResult;
404 }
405
406 /*---------------------------------------------------------------------------*
407 Name: RTC_SetTimeAsync
408
409 Description: Asynchronously writes time data to the RTC.
410
411 Arguments: time: Buffer where time data is stored
412 callback: Function to be called when the asynchronous process is completed
413 arg: Argument used when calling the callback function
414
415 Returns: RTCResult: Result of the process that starts the asynchronous device operation.
416 *---------------------------------------------------------------------------*/
RTC_SetTimeAsync(const RTCTime * time,RTCCallback callback,void * arg)417 RTCResult RTC_SetTimeAsync(const RTCTime *time, RTCCallback callback, void *arg)
418 {
419 OSIntrMode enabled;
420
421 SDK_NULL_ASSERT(time);
422 SDK_NULL_ASSERT(callback);
423
424 // Verify and edit the time to set
425 if (!RtcCheckTime(time, &(((RTCRawData *)(OS_GetSystemWork()->real_time_clock))->t.time)))
426 {
427 return RTC_RESULT_ILLEGAL_PARAMETER;
428 }
429
430 // Check lock
431 enabled = OS_DisableInterrupts();
432 if (rtcWork.lock != RTC_LOCK_OFF)
433 {
434 (void)OS_RestoreInterrupts(enabled);
435 return RTC_RESULT_BUSY;
436 }
437 rtcWork.lock = RTC_LOCK_ON;
438 (void)OS_RestoreInterrupts(enabled);
439
440 // Send time write command
441 rtcWork.sequence = RTC_SEQ_SET_TIME;
442 rtcWork.index = 0;
443 rtcWork.callback = callback;
444 rtcWork.callbackArg = arg;
445 if (RTCi_WriteRawTimeAsync())
446 {
447 return RTC_RESULT_SUCCESS;
448 }
449 else
450 {
451 rtcWork.lock = RTC_LOCK_OFF;
452 return RTC_RESULT_SEND_ERROR;
453 }
454 }
455
456 /*---------------------------------------------------------------------------*
457 Name: RTC_SetTime
458
459 Description: Writes time data to the RTC.
460
461 Arguments: time: Buffer where time data is stored
462
463 Returns: RTCResult: Device operation result.
464 *---------------------------------------------------------------------------*/
RTC_SetTime(const RTCTime * time)465 RTCResult RTC_SetTime(const RTCTime *time)
466 {
467 rtcWork.commonResult = RTC_SetTimeAsync(time, RtcGetResultCallback, NULL);
468 if (rtcWork.commonResult == RTC_RESULT_SUCCESS)
469 {
470 RtcWaitBusy();
471 }
472 return rtcWork.commonResult;
473 }
474
475 /*---------------------------------------------------------------------------*
476 Name: RTC_SetDateTimeAsync
477
478 Description: Asynchronously writes date and time data to the RTC.
479
480 Arguments: date: Buffer where date data is stored
481 time: Buffer where time data is stored
482 callback: Function to be called when the asynchronous process is completed
483 arg: Argument used when calling the callback function
484
485 Returns: RTCResult: Result of the process that starts the asynchronous device operation.
486 *---------------------------------------------------------------------------*/
487 RTCResult
RTC_SetDateTimeAsync(const RTCDate * date,const RTCTime * time,RTCCallback callback,void * arg)488 RTC_SetDateTimeAsync(const RTCDate *date, const RTCTime *time, RTCCallback callback, void *arg)
489 {
490 OSIntrMode enabled;
491
492 SDK_NULL_ASSERT(date);
493 SDK_NULL_ASSERT(time);
494 SDK_NULL_ASSERT(callback);
495
496 // Verify and edit the date and time that will be set
497 if (!RtcCheckDate(date, &(((RTCRawData *)(OS_GetSystemWork()->real_time_clock))->t.date)))
498 {
499 return RTC_RESULT_ILLEGAL_PARAMETER;
500 }
501 if (!RtcCheckTime(time, &(((RTCRawData *)(OS_GetSystemWork()->real_time_clock))->t.time)))
502 {
503 return RTC_RESULT_ILLEGAL_PARAMETER;
504 }
505
506 // Check lock
507 enabled = OS_DisableInterrupts();
508 if (rtcWork.lock != RTC_LOCK_OFF)
509 {
510 (void)OS_RestoreInterrupts(enabled);
511 return RTC_RESULT_BUSY;
512 }
513 rtcWork.lock = RTC_LOCK_ON;
514 (void)OS_RestoreInterrupts(enabled);
515
516 // Send date/time write command
517 rtcWork.sequence = RTC_SEQ_SET_DATETIME;
518 rtcWork.index = 0;
519 rtcWork.callback = callback;
520 rtcWork.callbackArg = arg;
521 if (RTCi_WriteRawDateTimeAsync())
522 {
523 return RTC_RESULT_SUCCESS;
524 }
525 else
526 {
527 rtcWork.lock = RTC_LOCK_OFF;
528 return RTC_RESULT_SEND_ERROR;
529 }
530 }
531
532 /*---------------------------------------------------------------------------*
533 Name: RTC_SetDateTime
534
535 Description: Writes date and time data to the RTC.
536
537 Arguments: date: Buffer where date data is stored
538 time: Buffer where time data is stored
539
540 Returns: RTCResult: Device operation processing result.
541 *---------------------------------------------------------------------------*/
RTC_SetDateTime(const RTCDate * date,const RTCTime * time)542 RTCResult RTC_SetDateTime(const RTCDate *date, const RTCTime *time)
543 {
544 rtcWork.commonResult = RTC_SetDateTimeAsync(date, time, RtcGetResultCallback, NULL);
545 if (rtcWork.commonResult == RTC_RESULT_SUCCESS)
546 {
547 RtcWaitBusy();
548 }
549 return rtcWork.commonResult;
550 }
551
552 /*---------------------------------------------------------------------------*
553 Name: RTC_SetRegStatus2Async
554
555 Description: Writes data to the RTC status 2 register.
556
557 Arguments: status2: Buffer where status 2 register contents are stored
558 callback: Function to be called when the asynchronous process is completed
559 arg: Argument used when calling the callback function
560
561 Returns: RTCResult: Result of the process that starts the asynchronous device operation.
562 *---------------------------------------------------------------------------*/
RTCi_SetRegStatus2Async(const RTCRawStatus2 * status2,RTCCallback callback,void * arg)563 RTCResult RTCi_SetRegStatus2Async(const RTCRawStatus2 *status2, RTCCallback callback, void *arg)
564 {
565 OSIntrMode enabled;
566
567 SDK_NULL_ASSERT(status2);
568 SDK_NULL_ASSERT(callback);
569
570 ((RTCRawData *)(OS_GetSystemWork()->real_time_clock))->a.status2.intr_mode = status2->intr_mode;
571 ((RTCRawData *)(OS_GetSystemWork()->real_time_clock))->a.status2.intr2_mode =
572 status2->intr2_mode;
573 ((RTCRawData *)(OS_GetSystemWork()->real_time_clock))->a.status2.test = status2->test;
574
575 /* No parameter check */
576 // Return RTC_RESULT_ILLEGAL_PARAMETER;
577
578
579 // Check lock
580 enabled = OS_DisableInterrupts();
581 if (rtcWork.lock != RTC_LOCK_OFF)
582 {
583 (void)OS_RestoreInterrupts(enabled);
584 return RTC_RESULT_BUSY;
585 }
586 rtcWork.lock = RTC_LOCK_ON;
587 (void)OS_RestoreInterrupts(enabled);
588
589 // Send the status 2 register write command
590 rtcWork.sequence = RTC_SEQ_SET_REG_STATUS2;
591 rtcWork.index = 0;
592 rtcWork.callback = callback;
593 rtcWork.callbackArg = arg;
594 if (RTCi_WriteRawStatus2Async())
595 {
596 return RTC_RESULT_SUCCESS;
597 }
598 else
599 {
600 rtcWork.lock = RTC_LOCK_OFF;
601 return RTC_RESULT_SEND_ERROR;
602 }
603 }
604
605 /*---------------------------------------------------------------------------*
606 Name: RTC_SetRegStatus2
607
608 Description: Writes data to the RTC status 2 register.
609
610 Arguments: status2: Buffer where status 2 register contents are stored
611
612 Returns: RTCResult: Device operation processing result.
613 *---------------------------------------------------------------------------*/
RTCi_SetRegStatus2(const RTCRawStatus2 * status2)614 RTCResult RTCi_SetRegStatus2(const RTCRawStatus2 *status2)
615 {
616 rtcWork.commonResult = RTCi_SetRegStatus2Async(status2, RtcGetResultCallback, NULL);
617 if (rtcWork.commonResult == RTC_RESULT_SUCCESS)
618 {
619 RtcWaitBusy();
620 }
621 return rtcWork.commonResult;
622 }
623
624
625 /*---------------------------------------------------------------------------*
626 Name: RTC_SetRegAdjustAsync
627
628 Description: Writes data to the RTC adjust register.
629
630 Arguments: adjust: Buffer where the adjust register contents are stored
631 callback: Function to be called when the asynchronous process is completed
632 arg: Argument used when calling the callback function
633
634 Returns: RTCResult: Result of the process that starts the asynchronous device operation.
635 *---------------------------------------------------------------------------*/
RTCi_SetRegAdjustAsync(const RTCRawAdjust * adjust,RTCCallback callback,void * arg)636 RTCResult RTCi_SetRegAdjustAsync(const RTCRawAdjust *adjust, RTCCallback callback, void *arg)
637 {
638 OSIntrMode enabled;
639
640 SDK_NULL_ASSERT(adjust);
641 SDK_NULL_ASSERT(callback);
642
643 ((RTCRawData *)(OS_GetSystemWork()->real_time_clock))->a.adjust.adjust = adjust->adjust;
644
645 /* No parameter check */
646 // Return RTC_RESULT_ILLEGAL_PARAMETER;
647
648 // Check lock
649 enabled = OS_DisableInterrupts();
650 if (rtcWork.lock != RTC_LOCK_OFF)
651 {
652 (void)OS_RestoreInterrupts(enabled);
653 return RTC_RESULT_BUSY;
654 }
655 rtcWork.lock = RTC_LOCK_ON;
656 (void)OS_RestoreInterrupts(enabled);
657
658 // Send the status 2 register write command
659 rtcWork.sequence = RTC_SEQ_SET_REG_ADJUST;
660 rtcWork.index = 0;
661 rtcWork.callback = callback;
662 rtcWork.callbackArg = arg;
663 if (RTCi_WriteRawAdjustAsync())
664 {
665 return RTC_RESULT_SUCCESS;
666 }
667 else
668 {
669 rtcWork.lock = RTC_LOCK_OFF;
670 return RTC_RESULT_SEND_ERROR;
671 }
672 }
673
674
675 /*---------------------------------------------------------------------------*
676 Name: RTC_SetRegAdjust
677
678 Description: Writes data to the RTC adjust register.
679
680 Arguments: status2: Buffer where the adjust register contents are stored
681
682 Returns: RTCResult: Device operation processing result.
683 *---------------------------------------------------------------------------*/
RTCi_SetRegAdjust(const RTCRawAdjust * Adjust)684 RTCResult RTCi_SetRegAdjust(const RTCRawAdjust *Adjust)
685 {
686 rtcWork.commonResult = RTCi_SetRegAdjustAsync(Adjust, RtcGetResultCallback, NULL);
687 if (rtcWork.commonResult == RTC_RESULT_SUCCESS)
688 {
689 RtcWaitBusy();
690 }
691 return rtcWork.commonResult;
692 }
693
694
695
696 /*---------------------------------------------------------------------------*
697 Name: RTC_GetAlarmStatusAsync
698
699 Description: Asynchronously reads alarm ON/OFF status from the RTC.
700
701 Arguments: chan: Alarm channel
702 status: Buffer for storing alarm status
703 callback: Function to be called when the asynchronous process is completed
704 arg: Argument used when calling the callback function
705
706 Returns: RTCResult: Result of the process that starts the asynchronous device operation.
707 *---------------------------------------------------------------------------*/
708 RTCResult
RTC_GetAlarmStatusAsync(RTCAlarmChan chan,RTCAlarmStatus * status,RTCCallback callback,void * arg)709 RTC_GetAlarmStatusAsync(RTCAlarmChan chan, RTCAlarmStatus *status, RTCCallback callback, void *arg)
710 {
711 OSIntrMode enabled;
712
713 SDK_NULL_ASSERT(status);
714 SDK_NULL_ASSERT(callback);
715
716 // Confirms parameters
717 if (chan >= RTC_ALARM_CHAN_MAX)
718 {
719 return RTC_RESULT_ILLEGAL_PARAMETER;
720 }
721 // Check lock
722 enabled = OS_DisableInterrupts();
723 if (rtcWork.lock != RTC_LOCK_OFF)
724 {
725 (void)OS_RestoreInterrupts(enabled);
726 return RTC_RESULT_BUSY;
727 }
728 rtcWork.lock = RTC_LOCK_ON;
729 (void)OS_RestoreInterrupts(enabled);
730
731 // Send status 2 register read command
732 switch (chan)
733 {
734 case RTC_ALARM_CHAN_1:
735 rtcWork.sequence = RTC_SEQ_GET_ALARM1_STATUS;
736 break;
737 case RTC_ALARM_CHAN_2:
738 rtcWork.sequence = RTC_SEQ_GET_ALARM2_STATUS;
739 break;
740 }
741 rtcWork.index = 0;
742 rtcWork.buffer[0] = (void *)status;
743 rtcWork.callback = callback;
744 rtcWork.callbackArg = arg;
745 if (RTCi_ReadRawStatus2Async())
746 {
747 return RTC_RESULT_SUCCESS;
748 }
749 else
750 {
751 rtcWork.lock = RTC_LOCK_OFF;
752 return RTC_RESULT_SEND_ERROR;
753 }
754 }
755
756 /*---------------------------------------------------------------------------*
757 Name: RTC_GetAlarmStatus
758
759 Description: Reads alarm ON/OFF status from the RTC.
760
761 Arguments: chan: Alarm channel
762 status: Buffer for storing alarm status
763
764 Returns: RTCResult: Device operation processing result.
765 *---------------------------------------------------------------------------*/
RTC_GetAlarmStatus(RTCAlarmChan chan,RTCAlarmStatus * status)766 RTCResult RTC_GetAlarmStatus(RTCAlarmChan chan, RTCAlarmStatus *status)
767 {
768 rtcWork.commonResult = RTC_GetAlarmStatusAsync(chan, status, RtcGetResultCallback, NULL);
769 if (rtcWork.commonResult == RTC_RESULT_SUCCESS)
770 {
771 RtcWaitBusy();
772 }
773 return rtcWork.commonResult;
774 }
775
776 /*---------------------------------------------------------------------------*
777 Name: RTC_GetAlarmParamAsync
778
779 Description: Asynchronously reads alarm setting values from the RTC.
780
781 Arguments: chan: Alarm channel
782 param: Buffer for storing alarm setting values
783 callback: Function to be called when the asynchronous process is completed
784 arg: Argument used when calling the callback function
785
786 Returns: RTCResult: Result of the process that starts the asynchronous device operation.
787 *---------------------------------------------------------------------------*/
788 RTCResult
RTC_GetAlarmParamAsync(RTCAlarmChan chan,RTCAlarmParam * param,RTCCallback callback,void * arg)789 RTC_GetAlarmParamAsync(RTCAlarmChan chan, RTCAlarmParam *param, RTCCallback callback, void *arg)
790 {
791 OSIntrMode enabled;
792
793 SDK_NULL_ASSERT(param);
794 SDK_NULL_ASSERT(callback);
795
796 // Confirms parameters
797 if (chan >= RTC_ALARM_CHAN_MAX)
798 {
799 return RTC_RESULT_ILLEGAL_PARAMETER;
800 }
801
802 // Check lock
803 enabled = OS_DisableInterrupts();
804 if (rtcWork.lock != RTC_LOCK_OFF)
805 {
806 (void)OS_RestoreInterrupts(enabled);
807 return RTC_RESULT_BUSY;
808 }
809 rtcWork.lock = RTC_LOCK_ON;
810 (void)OS_RestoreInterrupts(enabled);
811
812 // Send a read command for the alarm 1 or 2 setting values
813 rtcWork.sequence = RTC_SEQ_GET_ALARM_PARAM;
814 rtcWork.index = 0;
815 rtcWork.buffer[0] = (void *)param;
816 rtcWork.callback = callback;
817 rtcWork.callbackArg = arg;
818 if (chan == RTC_ALARM_CHAN_1)
819 {
820 if (RTCi_ReadRawAlarm1Async())
821 {
822 return RTC_RESULT_SUCCESS;
823 }
824 else
825 {
826 rtcWork.lock = RTC_LOCK_OFF;
827 return RTC_RESULT_SEND_ERROR;
828 }
829 }
830 if (RTCi_ReadRawAlarm2Async())
831 {
832 return RTC_RESULT_SUCCESS;
833 }
834 else
835 {
836 rtcWork.lock = RTC_LOCK_OFF;
837 return RTC_RESULT_SEND_ERROR;
838 }
839 }
840
841 /*---------------------------------------------------------------------------*
842 Name: RTC_GetAlarmParam
843
844 Description: Reads alarm setting values from the RTC.
845
846 Arguments: chan: Alarm channel
847 param: Buffer for storing alarm setting values
848
849 Returns: RTCResult: Device operation processing result.
850 *---------------------------------------------------------------------------*/
RTC_GetAlarmParam(RTCAlarmChan chan,RTCAlarmParam * param)851 RTCResult RTC_GetAlarmParam(RTCAlarmChan chan, RTCAlarmParam *param)
852 {
853 rtcWork.commonResult = RTC_GetAlarmParamAsync(chan, param, RtcGetResultCallback, NULL);
854 if (rtcWork.commonResult == RTC_RESULT_SUCCESS)
855 {
856 RtcWaitBusy();
857 }
858 return rtcWork.commonResult;
859 }
860
861 /*---------------------------------------------------------------------------*
862 Name: RTC_SetAlarmInterrupt
863
864 Description: Sets the callback function for when an alarm interrupt is generated.
865
866 Arguments: interrupt: Callback function
867
868 Returns: None.
869 *---------------------------------------------------------------------------*/
RTC_SetAlarmInterrupt(RTCInterrupt interrupt)870 void RTC_SetAlarmInterrupt(RTCInterrupt interrupt)
871 {
872 rtcWork.interrupt = interrupt;
873 }
874
875 /*---------------------------------------------------------------------------*
876 Name: RTC_SetAlarmStatusAsync
877
878 Description: Asynchronously writes alarm status to the RTC.
879
880 Arguments: chan: Alarm channel
881 status: Buffer where alarm status is stored
882 callback: Function to be called when the asynchronous process is completed
883 arg: Argument used when calling the callback function
884
885 Returns: RTCResult: Result of the process that starts the asynchronous device operation.
886 *---------------------------------------------------------------------------*/
887 RTCResult
RTC_SetAlarmStatusAsync(RTCAlarmChan chan,const RTCAlarmStatus * status,RTCCallback callback,void * arg)888 RTC_SetAlarmStatusAsync(RTCAlarmChan chan, const RTCAlarmStatus *status, RTCCallback callback,
889 void *arg)
890 {
891 OSIntrMode enabled;
892
893 SDK_NULL_ASSERT(status);
894 SDK_NULL_ASSERT(callback);
895
896 // Confirms parameters
897 if (chan >= RTC_ALARM_CHAN_MAX)
898 {
899 return RTC_RESULT_ILLEGAL_PARAMETER;
900 }
901 if (*status > RTC_ALARM_STATUS_ON)
902 {
903 return RTC_RESULT_ILLEGAL_PARAMETER;
904 }
905
906 // Check lock
907 enabled = OS_DisableInterrupts();
908 if (rtcWork.lock != RTC_LOCK_OFF)
909 {
910 (void)OS_RestoreInterrupts(enabled);
911 return RTC_RESULT_BUSY;
912 }
913 rtcWork.lock = RTC_LOCK_ON;
914 (void)OS_RestoreInterrupts(enabled);
915
916 // Send status 2 register read command
917 switch (chan)
918 {
919 case RTC_ALARM_CHAN_1:
920 rtcWork.sequence = RTC_SEQ_SET_ALARM1_STATUS;
921 break;
922 case RTC_ALARM_CHAN_2:
923 rtcWork.sequence = RTC_SEQ_SET_ALARM2_STATUS;
924 break;
925 }
926 rtcWork.index = 0;
927 rtcWork.buffer[0] = (void *)status;
928 rtcWork.callback = callback;
929 rtcWork.callbackArg = arg;
930 if (RTCi_ReadRawStatus2Async())
931 {
932 return RTC_RESULT_SUCCESS;
933 }
934 else
935 {
936 rtcWork.lock = RTC_LOCK_OFF;
937 return RTC_RESULT_SEND_ERROR;
938 }
939 }
940
941 /*---------------------------------------------------------------------------*
942 Name: RTC_SetAlarmStatus
943
944 Description: Writes alarm status to the RTC.
945
946 Arguments: chan: Alarm channel
947 status: Buffer where alarm status is stored
948
949 Returns: RTCResult: Device operation processing result.
950 *---------------------------------------------------------------------------*/
RTC_SetAlarmStatus(RTCAlarmChan chan,const RTCAlarmStatus * status)951 RTCResult RTC_SetAlarmStatus(RTCAlarmChan chan, const RTCAlarmStatus *status)
952 {
953 rtcWork.commonResult = RTC_SetAlarmStatusAsync(chan, status, RtcGetResultCallback, NULL);
954 if (rtcWork.commonResult == RTC_RESULT_SUCCESS)
955 {
956 RtcWaitBusy();
957 }
958 return rtcWork.commonResult;
959 }
960
961 /*---------------------------------------------------------------------------*
962 Name: RTC_SetAlarmParamAsync
963
964 Description: Asynchronously writes alarm settings to the RTC.
965 Notice: Write will fail if the RTC alarm status is not ON, because the device side will not accept write.
966
967
968 Arguments: chan: Alarm channel
969 param: Buffer where alarm setting values are stored
970 callback: Function to be called when the asynchronous process is completed
971 arg: Argument used when calling the callback function
972
973 Returns: RTCResult: Result of the process that starts the asynchronous device operation.
974 *---------------------------------------------------------------------------*/
975 RTCResult
RTC_SetAlarmParamAsync(RTCAlarmChan chan,const RTCAlarmParam * param,RTCCallback callback,void * arg)976 RTC_SetAlarmParamAsync(RTCAlarmChan chan, const RTCAlarmParam *param, RTCCallback callback,
977 void *arg)
978 {
979 OSIntrMode enabled;
980 RTCRawAlarm *pAlarm = &(((RTCRawData *)(OS_GetSystemWork()->real_time_clock))->a.alarm);
981 BOOL result = FALSE;
982
983 SDK_NULL_ASSERT(param);
984 SDK_NULL_ASSERT(callback);
985
986 // Confirms parameters
987 if (chan >= RTC_ALARM_CHAN_MAX)
988 {
989 return RTC_RESULT_ILLEGAL_PARAMETER;
990 }
991 if (!RtcCheckAlarmParam(param))
992 {
993 return RTC_RESULT_ILLEGAL_PARAMETER;
994 }
995
996 // Check lock
997 enabled = OS_DisableInterrupts();
998 if (rtcWork.lock != RTC_LOCK_OFF)
999 {
1000 (void)OS_RestoreInterrupts(enabled);
1001 return RTC_RESULT_BUSY;
1002 }
1003 rtcWork.lock = RTC_LOCK_ON;
1004 (void)OS_RestoreInterrupts(enabled);
1005
1006 // Edit the data to set
1007 rtcWork.index = 0;
1008 rtcWork.callback = callback;
1009 rtcWork.callbackArg = arg;
1010 ((RTCRawData *)(OS_GetSystemWork()->real_time_clock))->a.alarm = RtcMakeAlarmParam(param);
1011 // Divide the send command by the alarm number
1012 switch (chan)
1013 {
1014 case RTC_ALARM_CHAN_1:
1015 // Send the alarm �P register write command
1016 rtcWork.sequence = RTC_SEQ_SET_ALARM1_PARAM;
1017 result = RTCi_WriteRawAlarm1Async();
1018 break;
1019 case RTC_ALARM_CHAN_2:
1020 // Send the alarm �Q register write command
1021 rtcWork.sequence = RTC_SEQ_SET_ALARM2_PARAM;
1022 result = RTCi_WriteRawAlarm2Async();
1023 break;
1024 }
1025 if (result)
1026 {
1027 return RTC_RESULT_SUCCESS;
1028 }
1029 rtcWork.lock = RTC_LOCK_OFF;
1030 return RTC_RESULT_SEND_ERROR;
1031 }
1032
1033 /*---------------------------------------------------------------------------*
1034 Name: RTC_SetAlarmParam
1035
1036 Description: Writes alarm setting values to the RTC.
1037
1038 Arguments: chan: Alarm channel
1039 param: Buffer where alarm setting values are stored
1040
1041 Returns: RTCResult: Device operation processing result.
1042 *---------------------------------------------------------------------------*/
RTC_SetAlarmParam(RTCAlarmChan chan,const RTCAlarmParam * param)1043 RTCResult RTC_SetAlarmParam(RTCAlarmChan chan, const RTCAlarmParam *param)
1044 {
1045 rtcWork.commonResult = RTC_SetAlarmParamAsync(chan, param, RtcGetResultCallback, NULL);
1046 if (rtcWork.commonResult == RTC_RESULT_SUCCESS)
1047 {
1048 RtcWaitBusy();
1049 }
1050 return rtcWork.commonResult;
1051 }
1052
1053 #ifdef SDK_TWL
1054 /*---------------------------------------------------------------------------*
1055 Name: RTCi_GetSysWork
1056
1057 Description: Gets pointer to the library-internal shared working variable.
1058
1059 Arguments: None.
1060
1061 Returns: RTCWork*: Pointer to library-internal shared working variable.
1062 *---------------------------------------------------------------------------*/
1063 RTCWork*
RTCi_GetSysWork(void)1064 RTCi_GetSysWork(void)
1065 {
1066 return &rtcWork;
1067 }
1068
1069 /*---------------------------------------------------------------------------*
1070 Name: RTCi_GetCounterAsync
1071
1072 Description: Asynchronously reads the Up Counter value from the RTC.
1073
1074 Arguments: count: Buffer to store the Up Counter value
1075 callback: Function to be called when the asynchronous process is completed
1076 arg: Argument used when calling the callback function
1077
1078 Returns: RTCResult: Result of the process that starts the asynchronous device operation.
1079 *---------------------------------------------------------------------------*/
1080 RTCResult
RTCi_GetCounterAsync(u32 * count,RTCCallback callback,void * arg)1081 RTCi_GetCounterAsync(u32* count, RTCCallback callback, void* arg)
1082 {
1083 return ((OS_IsRunOnTwl() == FALSE) ?
1084 RTC_RESULT_INVALID_COMMAND : RTCEXi_GetCounterAsync(count, callback, arg));
1085 }
1086
1087 /*---------------------------------------------------------------------------*
1088 Name: RTCi_GetCounter
1089
1090 Description: Reads the Up Counter value from the RTC.
1091
1092 Arguments: count: Buffer to store the Up Counter value
1093
1094 Returns: RTCResult: Device operation processing result.
1095 *---------------------------------------------------------------------------*/
1096 RTCResult
RTCi_GetCounter(u32 * count)1097 RTCi_GetCounter(u32* count)
1098 {
1099 return ((OS_IsRunOnTwl() == FALSE) ?
1100 RTC_RESULT_INVALID_COMMAND : RTCEXi_GetCounter(count));
1101 }
1102
1103 /*---------------------------------------------------------------------------*
1104 Name: RTCi_GetFoutAsync
1105
1106 Description: Asynchronously reads FOUT setting values from the RTC.
1107
1108 Arguments: fout: Buffer for storing FOUT setting values
1109 callback: Function to be called when the asynchronous process is completed
1110 arg: Argument used when calling the callback function
1111
1112 Returns: RTCResult: Result of the process that starts the asynchronous device operation.
1113 *---------------------------------------------------------------------------*/
1114 RTCResult
RTCi_GetFoutAsync(u16 * fout,RTCCallback callback,void * arg)1115 RTCi_GetFoutAsync(u16* fout, RTCCallback callback, void* arg)
1116 {
1117 return ((OS_IsRunOnTwl() == FALSE) ?
1118 RTC_RESULT_INVALID_COMMAND : RTCEXi_GetFoutAsync(fout, callback, arg));
1119 }
1120
1121 /*---------------------------------------------------------------------------*
1122 Name: RTCi_GetFout
1123
1124 Description: Asynchronously reads FOUT setting values from the RTC.
1125
1126 Arguments: fout: Buffer for storing FOUT setting values
1127
1128 Returns: RTCResult: Device operation processing result.
1129 *---------------------------------------------------------------------------*/
1130 RTCResult
RTCi_GetFout(u16 * fout)1131 RTCi_GetFout(u16* fout)
1132 {
1133 return ((OS_IsRunOnTwl() == FALSE) ?
1134 RTC_RESULT_INVALID_COMMAND : RTCEXi_GetFout(fout));
1135 }
1136
1137 /*---------------------------------------------------------------------------*
1138 Name: RTCi_SetFoutAsync
1139
1140 Description: Asynchronously writes FOUT settings to the RTC.
1141
1142 Arguments: fout: Buffer storing FOUT setting values
1143 callback: Function to be called when the asynchronous process is completed
1144 arg: Argument used when calling the callback function
1145
1146 Returns: RTCResult: Result of the process that starts the asynchronous device operation.
1147 *---------------------------------------------------------------------------*/
1148 RTCResult
RTCi_SetFoutAsync(const u16 * fout,RTCCallback callback,void * arg)1149 RTCi_SetFoutAsync(const u16* fout, RTCCallback callback, void* arg)
1150 {
1151 return ((OS_IsRunOnTwl() == FALSE) ?
1152 RTC_RESULT_INVALID_COMMAND : RTCEXi_SetFoutAsync(fout, callback, arg));
1153 }
1154
1155 /*---------------------------------------------------------------------------*
1156 Name: RTCi_SetFout
1157
1158 Description: Writes FOUT setting values to the RTC.
1159
1160 Arguments: fout: Buffer storing FOUT setting values
1161
1162 Returns: RTCResult: Device operation processing result.
1163 *---------------------------------------------------------------------------*/
1164 RTCResult
RTCi_SetFout(const u16 * fout)1165 RTCi_SetFout(const u16* fout)
1166 {
1167 return ((OS_IsRunOnTwl() == FALSE) ?
1168 RTC_RESULT_INVALID_COMMAND : RTCEXi_SetFout(fout));
1169 }
1170 #endif
1171
1172 /*---------------------------------------------------------------------------*
1173 Name: RtcCommonCallback
1174
1175 Description: Common callback function for asynchronous RTC functions.
1176
1177 Arguments: tag: PXI tag that shows the message type
1178 data: Message from ARM7
1179 err: PXI transfer error flag
1180
1181 Returns: None.
1182 *---------------------------------------------------------------------------*/
RtcCommonCallback(PXIFifoTag tag,u32 data,BOOL err)1183 static void RtcCommonCallback(PXIFifoTag tag, u32 data, BOOL err)
1184 {
1185 #pragma unused( tag )
1186
1187 RTCResult result;
1188 RTCPxiResult pxiresult;
1189 u8 command;
1190 RTCCallback cb;
1191
1192 // Verify PXI communication error
1193 if (err)
1194 {
1195 // Forcibly end sequence
1196 if (rtcWork.index)
1197 {
1198 rtcWork.index = 0;
1199 }
1200 if (rtcWork.lock != RTC_LOCK_OFF)
1201 {
1202 rtcWork.lock = RTC_LOCK_OFF;
1203 }
1204 if (rtcWork.callback)
1205 {
1206 cb = rtcWork.callback;
1207 rtcWork.callback = NULL;
1208 cb(RTC_RESULT_FATAL_ERROR, rtcWork.callbackArg);
1209 }
1210 return;
1211 }
1212
1213 // Analyze received data
1214 command = (u8)((data & RTC_PXI_COMMAND_MASK) >> RTC_PXI_COMMAND_SHIFT);
1215 pxiresult = (RTCPxiResult)((data & RTC_PXI_RESULT_MASK) >> RTC_PXI_RESULT_SHIFT);
1216
1217 // Verify alarm interrupt
1218 if (command == RTC_PXI_COMMAND_INTERRUPT)
1219 {
1220 // While it is possible to decide whether the alarm is 1 or 2 in pxiresult, because the callbacks are unified, which one it is will be ignored
1221 //
1222 if (rtcWork.interrupt)
1223 {
1224 // Callback alarm interrupt notification
1225 rtcWork.interrupt();
1226 }
1227 return;
1228 }
1229
1230 // If the response indicates that processing was successful, processing performed after that will depend on the type of the internal state
1231 if (pxiresult == RTC_PXI_RESULT_SUCCESS)
1232 {
1233 result = RTC_RESULT_SUCCESS;
1234 switch (rtcWork.sequence)
1235 {
1236 // Sequence for getting dates
1237 case RTC_SEQ_GET_DATE:
1238 {
1239 RTCDate *pDst = (RTCDate *)(rtcWork.buffer[0]);
1240 RTCRawDate *pSrc = &(((RTCRawData *)(OS_GetSystemWork()->real_time_clock))->t.date);
1241
1242 pDst->year = RtcBCD2HEX(pSrc->year);
1243 pDst->month = RtcBCD2HEX(pSrc->month);
1244 pDst->day = RtcBCD2HEX(pSrc->day);
1245 pDst->week = RTC_GetDayOfWeek(pDst);
1246 }
1247 break;
1248 // Sequence for getting times
1249 case RTC_SEQ_GET_TIME:
1250 {
1251 RTCTime *pDst = (RTCTime *)(rtcWork.buffer[0]);
1252 RTCRawTime *pSrc = &(((RTCRawData *)(OS_GetSystemWork()->real_time_clock))->t.time);
1253
1254 pDst->hour = RtcBCD2HEX(pSrc->hour);
1255 pDst->minute = RtcBCD2HEX(pSrc->minute);
1256 pDst->second = RtcBCD2HEX(pSrc->second);
1257 }
1258 break;
1259 // Sequence for getting dates and times
1260 case RTC_SEQ_GET_DATETIME:
1261 {
1262 RTCDate *pDst = (RTCDate *)(rtcWork.buffer[0]);
1263 RTCRawDate *pSrc = &(((RTCRawData *)(OS_GetSystemWork()->real_time_clock))->t.date);
1264
1265 //pDst->year = RtcBCD2HEX( pSrc->year ); // Changed to the following code because for some reason the value is not passed
1266 pDst->year = RtcBCD2HEX(*(u32 *)pSrc & 0x000000ff);
1267 pDst->month = RtcBCD2HEX(pSrc->month);
1268 pDst->day = RtcBCD2HEX(pSrc->day);
1269 pDst->week = RTC_GetDayOfWeek(pDst);
1270 }
1271 {
1272 RTCTime *pDst = (RTCTime *)(rtcWork.buffer[1]);
1273 RTCRawTime *pSrc = &(((RTCRawData *)(OS_GetSystemWork()->real_time_clock))->t.time);
1274
1275 pDst->hour = RtcBCD2HEX(pSrc->hour);
1276 pDst->minute = RtcBCD2HEX(pSrc->minute);
1277 pDst->second = RtcBCD2HEX(pSrc->second);
1278 }
1279 break;
1280 // Sequence for changing dates
1281 case RTC_SEQ_SET_DATE:
1282 case RTC_SEQ_SET_TIME:
1283 case RTC_SEQ_SET_DATETIME:
1284 // No processing in particular
1285 break;
1286 // Sequence for getting alarm �P's status
1287 case RTC_SEQ_GET_ALARM1_STATUS:
1288 {
1289 RTCAlarmStatus *pDst = (RTCAlarmStatus *)(rtcWork.buffer[0]);
1290 RTCRawStatus2 *pSrc =
1291 &(((RTCRawData *)(OS_GetSystemWork()->real_time_clock))->a.status2);
1292
1293 switch (pSrc->intr_mode)
1294 {
1295 case RTC_INTERRUPT_MODE_ALARM:
1296 *pDst = RTC_ALARM_STATUS_ON;
1297 break;
1298 default:
1299 *pDst = RTC_ALARM_STATUS_OFF;
1300 }
1301 }
1302 break;
1303 // Sequence for getting alarm �Q's status
1304 case RTC_SEQ_GET_ALARM2_STATUS:
1305 {
1306 RTCAlarmStatus *pDst = (RTCAlarmStatus *)(rtcWork.buffer[0]);
1307 RTCRawStatus2 *pSrc =
1308 &(((RTCRawData *)(OS_GetSystemWork()->real_time_clock))->a.status2);
1309
1310 if (pSrc->intr2_mode)
1311 {
1312 *pDst = RTC_ALARM_STATUS_ON;
1313 }
1314 else
1315 {
1316 *pDst = RTC_ALARM_STATUS_OFF;
1317 }
1318 }
1319 break;
1320 // Sequence for getting alarm 1 or 2's setting values
1321 case RTC_SEQ_GET_ALARM_PARAM:
1322 {
1323 RTCAlarmParam *pDst = (RTCAlarmParam *)(rtcWork.buffer[0]);
1324 RTCRawAlarm *pSrc =
1325 &(((RTCRawData *)(OS_GetSystemWork()->real_time_clock))->a.alarm);
1326
1327 pDst->week = (RTCWeek)(pSrc->week);
1328 pDst->hour = RtcBCD2HEX(pSrc->hour);
1329 pDst->minute = RtcBCD2HEX(pSrc->minute);
1330 pDst->enable = RTC_ALARM_ENABLE_NONE;
1331 if (pSrc->we)
1332 pDst->enable += RTC_ALARM_ENABLE_WEEK;
1333 if (pSrc->he)
1334 pDst->enable += RTC_ALARM_ENABLE_HOUR;
1335 if (pSrc->me)
1336 pDst->enable += RTC_ALARM_ENABLE_MINUTE;
1337 }
1338 break;
1339 // Sequence for setting alarm �P's status
1340 case RTC_SEQ_SET_ALARM1_STATUS:
1341 if (rtcWork.index == 0)
1342 {
1343 RTCRawStatus2 *pSrc =
1344 &(((RTCRawData *)(OS_GetSystemWork()->real_time_clock))->a.status2);
1345
1346 // Status 2 register read result
1347 if (*(RTCAlarmStatus *)(rtcWork.buffer[0]) == RTC_ALARM_STATUS_ON)
1348 {
1349 // If interrupts are permitted
1350 if (pSrc->intr_mode != RTC_INTERRUPT_MODE_ALARM)
1351 {
1352 // Write to the Status 2 register
1353 rtcWork.index++; // Go to next sequence
1354 pSrc->intr_mode = RTC_INTERRUPT_MODE_ALARM;
1355 if (!RTCi_WriteRawStatus2Async())
1356 {
1357 rtcWork.index = 0; // Interrupt the sequence
1358 result = RTC_RESULT_SEND_ERROR;
1359 }
1360 }
1361 }
1362 else
1363 {
1364 // If interrupts are disabled
1365 if (pSrc->intr_mode != RTC_INTERRUPT_MODE_NONE)
1366 {
1367 // Write to the Status 2 register
1368 rtcWork.index++; // Go to next sequence
1369 pSrc->intr_mode = RTC_INTERRUPT_MODE_NONE;
1370 if (!RTCi_WriteRawStatus2Async())
1371 {
1372 rtcWork.index = 0; // Interrupt the sequence
1373 result = RTC_RESULT_SEND_ERROR;
1374 }
1375 }
1376 }
1377 }
1378 else
1379 {
1380 // Status 2 register write result
1381 rtcWork.index = 0; // End sequence
1382 }
1383 break;
1384 // Sequence for setting alarm �Q's status
1385 case RTC_SEQ_SET_ALARM2_STATUS:
1386 if (rtcWork.index == 0)
1387 {
1388 RTCRawStatus2 *pSrc =
1389 &(((RTCRawData *)(OS_GetSystemWork()->real_time_clock))->a.status2);
1390
1391 // Status 2 register read result
1392 if (*(RTCAlarmStatus *)(rtcWork.buffer[0]) == RTC_ALARM_STATUS_ON)
1393 {
1394 // If interrupts are permitted
1395 if (!pSrc->intr2_mode)
1396 {
1397 // Write to the Status 2 register
1398 rtcWork.index++; // Go to next sequence
1399 pSrc->intr2_mode = 1;
1400 if (!RTCi_WriteRawStatus2Async())
1401 {
1402 rtcWork.index = 0; // Interrupt the sequence
1403 result = RTC_RESULT_SEND_ERROR;
1404 }
1405 }
1406 }
1407 else
1408 {
1409 // If interrupts are disabled
1410 if (pSrc->intr2_mode)
1411 {
1412 // Write to the Status 2 register
1413 rtcWork.index++; // Go to next sequence
1414 pSrc->intr2_mode = 0;
1415 if (!RTCi_WriteRawStatus2Async())
1416 {
1417 rtcWork.index = 0; // Interrupt the sequence
1418 result = RTC_RESULT_SEND_ERROR;
1419 }
1420 }
1421 }
1422 }
1423 else
1424 {
1425 // Status 2 register write result
1426 rtcWork.index = 0; // End sequence
1427 }
1428 break;
1429 // Sequence for setting alarm �P's parameters
1430 case RTC_SEQ_SET_ALARM1_PARAM:
1431 // Sequence for setting alarm �Q's parameters
1432 case RTC_SEQ_SET_ALARM2_PARAM:
1433 // Sequence for changing the time notation
1434 case RTC_SEQ_SET_HOUR_FORMAT:
1435 // Sequence for status 2 register writes
1436 case RTC_SEQ_SET_REG_STATUS2:
1437 // Sequence for adjust register writes
1438 case RTC_SEQ_SET_REG_ADJUST:
1439 // No processing in particular
1440 break;
1441
1442 // Other unknown sequences
1443 default:
1444 #ifdef SDK_TWL
1445 if (OS_IsRunOnTwl() == TRUE)
1446 {
1447 result = RTCEXi_CommonCallback();
1448 break;
1449 }
1450 #endif
1451 result = RTC_RESULT_INVALID_COMMAND;
1452 rtcWork.index = 0;
1453 }
1454 }
1455 else
1456 {
1457 // A failure response was returned to the command, so the sequence is interrupted
1458 rtcWork.index = 0;
1459 // Determine the processing result from the classification of PXI communication responses
1460 switch (pxiresult)
1461 {
1462 case RTC_PXI_RESULT_INVALID_COMMAND:
1463 result = RTC_RESULT_INVALID_COMMAND;
1464 break;
1465 case RTC_PXI_RESULT_ILLEGAL_STATUS:
1466 result = RTC_RESULT_ILLEGAL_STATUS;
1467 break;
1468 case RTC_PXI_RESULT_BUSY:
1469 result = RTC_RESULT_BUSY;
1470 break;
1471 case RTC_PXI_RESULT_FATAL_ERROR:
1472 default:
1473 result = RTC_RESULT_FATAL_ERROR;
1474 }
1475 }
1476
1477 // Sequence termination processing if a continuous sequence completes
1478 if (rtcWork.index == 0)
1479 {
1480 // Open exclusive lock
1481 if (rtcWork.lock != RTC_LOCK_OFF)
1482 {
1483 rtcWork.lock = RTC_LOCK_OFF;
1484 }
1485 // Invoke the callback function.
1486 if (rtcWork.callback)
1487 {
1488 cb = rtcWork.callback;
1489 rtcWork.callback = NULL;
1490 cb(result, rtcWork.callbackArg);
1491 }
1492 }
1493 }
1494
1495 /*---------------------------------------------------------------------------*
1496 Name: RtcBCD2HEX
1497
1498 Description: Convert a numeric value expressed in the BCD type to a numeric value expressed as a general u32.
1499
1500 Arguments: bcd: Numeric value expressed in the BCD type
1501
1502 Returns: u32: Numeric value expressed as a general u32.
1503 Return 0 if the input parameter is not of the BCD type.
1504 *---------------------------------------------------------------------------*/
RtcBCD2HEX(u32 bcd)1505 static u32 RtcBCD2HEX(u32 bcd)
1506 {
1507 u32 hex = 0;
1508 s32 i;
1509 s32 w;
1510
1511 // Verify that 0xA-0xF is not included in any of the digits
1512 for (i = 0; i < 8; i++)
1513 {
1514 if (((bcd >> (i * 4)) & 0x0000000f) >= 0x0a)
1515 {
1516 return hex; // Stop conversion and forcibly return 0
1517 }
1518 }
1519
1520 // Conversion loop
1521 for (i = 0, w = 1; i < 8; i++, w *= 10)
1522 {
1523 hex += (((bcd >> (i * 4)) & 0x0000000f) * w);
1524 }
1525 return hex;
1526 }
1527
1528 /*---------------------------------------------------------------------------*
1529 Name: RtcHEX2BCD
1530
1531 Description: Convert a numeric value expressed as a general u32 to a numeric value expressed in the BCD type.
1532
1533 Arguments: hex: Numeric value expressed as a general u32
1534
1535 Returns: u32: Numeric value expressed in the BCD type.
1536 Return 0 if the input parameter cannot be expressed in the BCD type.
1537 *---------------------------------------------------------------------------*/
RtcHEX2BCD(u32 hex)1538 static u32 RtcHEX2BCD(u32 hex)
1539 {
1540 u32 bcd = 0;
1541 s32 i;
1542 u32 w;
1543
1544 // Make sure that this is not over 99999999
1545 if (hex > 99999999)
1546 {
1547 return 0;
1548 }
1549
1550 // Conversion loop
1551 for (i = 0, w = hex; i < 8; i++)
1552 {
1553 bcd += ((w % 10) << (i * 4));
1554 w /= 10;
1555 }
1556 return bcd;
1557 }
1558
1559 /*---------------------------------------------------------------------------*
1560 Name: RtcCheckAlarmParam
1561
1562 Description: Checks if an alarm setting value is one that will not cause problems when it is set in the RTC.
1563
1564 Arguments: param: Alarm setting value to check
1565
1566 Returns: BOOL: Returns TRUE if, as an alarm setting value, there are no problems. Returns FALSE if there is some sort of problem.
1567
1568 *---------------------------------------------------------------------------*/
RtcCheckAlarmParam(const RTCAlarmParam * param)1569 static BOOL RtcCheckAlarmParam(const RTCAlarmParam *param)
1570 {
1571 if (param->week >= RTC_WEEK_MAX)
1572 return FALSE;
1573 if (param->hour >= 24)
1574 return FALSE;
1575 if (param->minute >= 60)
1576 return FALSE;
1577 if (param->enable & ~RTC_ALARM_ENABLE_ALL)
1578 return FALSE;
1579 return TRUE;
1580 }
1581
1582 /*---------------------------------------------------------------------------*
1583 Name: RtcMakeAlarmParam
1584
1585 Description: Converts an alarm setting value into a format that can be set in the RTC.
1586
1587 Arguments: param: Target alarm setting value to convert
1588
1589 Returns: RTCRawAlarm: Data converted into a format that can be set in the RTC.
1590 *---------------------------------------------------------------------------*/
RtcMakeAlarmParam(const RTCAlarmParam * param)1591 static RTCRawAlarm RtcMakeAlarmParam(const RTCAlarmParam *param)
1592 {
1593 RTCRawAlarm dst;
1594
1595 // Zero out the return value
1596 *((u32 *)(&dst)) = 0;
1597
1598 // Just to be sure, check the compatibility of the setting value
1599 if (!RtcCheckAlarmParam(param))
1600 {
1601 return dst;
1602 }
1603
1604 // Data for the day of the week
1605 dst.week = (u32)(param->week);
1606 // Time data as well as an AM-PM flag
1607 if (param->hour >= 12)
1608 {
1609 dst.afternoon = 1;
1610 }
1611 dst.hour = RtcHEX2BCD(param->hour);
1612 // Minute data
1613 dst.minute = RtcHEX2BCD(param->minute);
1614 // Enable flag
1615 if (param->enable & RTC_ALARM_ENABLE_WEEK)
1616 {
1617 dst.we = 1;
1618 }
1619 if (param->enable & RTC_ALARM_ENABLE_HOUR)
1620 {
1621 dst.he = 1;
1622 }
1623 if (param->enable & RTC_ALARM_ENABLE_MINUTE)
1624 {
1625 dst.me = 1;
1626 }
1627
1628 return dst;
1629 }
1630
1631 /*---------------------------------------------------------------------------*
1632 Name: RtcCheckDate
1633
1634 Description: Verifies if the date value can be set in the RTC without any problems.
1635 If there are no problems, edits the format to one that can be set in the RTC.
1636
1637 Arguments: date: Inputs the date to check
1638 raw: Outputs the data edited into a format that can be set in the RTC
1639
1640 Returns: BOOL: Returns FALSE if there was a problem while checking.
1641 *---------------------------------------------------------------------------*/
RtcCheckDate(const RTCDate * date,RTCRawDate * raw)1642 static BOOL RtcCheckDate(const RTCDate *date, RTCRawDate *raw)
1643 {
1644 // Check whether each member is in the allowable range
1645 if (date->year >= 100)
1646 return FALSE;
1647 if ((date->month < 1) || (date->month > 12))
1648 return FALSE;
1649 if ((date->day < 1) || (date->day > 31))
1650 return FALSE;
1651 if (date->week >= RTC_WEEK_MAX)
1652 return FALSE;
1653
1654 // Edit to the raw data type
1655 //raw->year = RtcHEX2BCD( date->year ); // Change to the following code because for some reason the value is not stored
1656 *(u32 *)raw = RtcHEX2BCD(date->year);
1657 raw->month = RtcHEX2BCD(date->month);
1658 raw->day = RtcHEX2BCD(date->day);
1659 raw->week = (u32)RTC_GetDayOfWeek((RTCDate*)date); // Always recalculate the day of week, don't use the day of week from the input data
1660 return TRUE;
1661 }
1662
1663 /*---------------------------------------------------------------------------*
1664 Name: RtcCheckTime
1665
1666 Description: Verifies if the time value can be set in the RTC without any problems.
1667 If there are no problems, edits the format to one that can be set in the RTC.
1668
1669 Arguments: date: Inputs the time to check
1670 raw: Outputs the data edited into a format that can be set in the RTC
1671
1672 Returns: BOOL: Returns FALSE if there was a problem while checking.
1673 *---------------------------------------------------------------------------*/
RtcCheckTime(const RTCTime * time,RTCRawTime * raw)1674 static BOOL RtcCheckTime(const RTCTime *time, RTCRawTime *raw)
1675 {
1676 // Check whether each member is in the allowable range
1677 if (time->hour >= 24)
1678 return FALSE;
1679 if (time->minute >= 60)
1680 return FALSE;
1681 if (time->second >= 60)
1682 return FALSE;
1683
1684 // Edit to the raw data type
1685 if (time->hour >= 12)
1686 {
1687 raw->afternoon = 1;
1688 }
1689 else
1690 {
1691 raw->afternoon = 0;
1692 }
1693 raw->hour = RtcHEX2BCD(time->hour);
1694 raw->minute = RtcHEX2BCD(time->minute);
1695 raw->second = RtcHEX2BCD(time->second);
1696
1697 return TRUE;
1698 }
1699
1700 /*---------------------------------------------------------------------------*
1701 Name: RtcGetResultCallback
1702
1703 Description: Called when asynchronous processing completes. Updates the processing results of internal variables.
1704
1705 Arguments: result: The processing results from the asynchronous function
1706 arg: Not used
1707
1708 Returns: None.
1709 *---------------------------------------------------------------------------*/
RtcGetResultCallback(RTCResult result,void * arg)1710 static void RtcGetResultCallback(RTCResult result, void *arg)
1711 {
1712 #pragma unused( arg )
1713
1714 rtcWork.commonResult = result;
1715 }
1716
1717 #include <nitro/code32.h>
1718 /*---------------------------------------------------------------------------*
1719 Name: RtcWaitBusy
1720
1721 Description: Wait while the RTC's asynchronous processing is locked.
1722
1723 Arguments: None.
1724
1725 Returns: None.
1726 *---------------------------------------------------------------------------*/
1727 static asm void
RtcWaitBusy(void)1728 RtcWaitBusy( void )
1729 {
1730 ldr r12, =rtcWork.lock
1731 loop:
1732 ldr r0, [ r12, #0 ]
1733 cmp r0, #RTC_LOCK_ON
1734 beq loop
1735 bx lr
1736 }
1737 #include <nitro/codereset.h>
1738
1739
1740 /*---------------------------------------------------------------------------*
1741 End of file
1742 *---------------------------------------------------------------------------*/
1743