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