1 /*************************************************************************************
2 * Copyright (C) 2017, Huada Semiconductor Co.,Ltd All rights reserved.
3 *
4 * This software is owned and published by:
5 * Huada Semiconductor Co.,Ltd ("HDSC").
6 *
7 * BY DOWNLOADING, INSTALLING OR USING THIS SOFTWARE, YOU AGREE TO BE BOUND
8 * BY ALL THE TERMS AND CONDITIONS OF THIS AGREEMENT.
9 *
10 * This software contains source code for use with HDSC
11 * components. This software is licensed by HDSC to be adapted only
12 * for use in systems utilizing HDSC components. HDSC shall not be
13 * responsible for misuse or illegal use of this software for devices not
14 * supported herein. HDSC is providing this software "AS IS" and will
15 * not be responsible for issues arising from incorrect user implementation
16 * of the software.
17 *
18 * Disclaimer:
19 * HDSC MAKES NO WARRANTY, EXPRESS OR IMPLIED, ARISING BY LAW OR OTHERWISE,
20 * REGARDING THE SOFTWARE (INCLUDING ANY ACOOMPANYING WRITTEN MATERIALS),
21 * ITS PERFORMANCE OR SUITABILITY FOR YOUR INTENDED USE, INCLUDING,
22 * WITHOUT LIMITATION, THE IMPLIED WARRANTY OF MERCHANTABILITY, THE IMPLIED
23 * WARRANTY OF FITNESS FOR A PARTICULAR PURPOSE OR USE, AND THE IMPLIED
24 * WARRANTY OF NONINFRINGEMENT.
25 * HDSC SHALL HAVE NO LIABILITY (WHETHER IN CONTRACT, WARRANTY, TORT,
26 * NEGLIGENCE OR OTHERWISE) FOR ANY DAMAGES WHATSOEVER (INCLUDING, WITHOUT
27 * LIMITATION, DAMAGES FOR LOSS OF BUSINESS PROFITS, BUSINESS INTERRUPTION,
28 * LOSS OF BUSINESS INFORMATION, OR OTHER PECUNIARY LOSS) ARISING FROM USE OR
29 * INABILITY TO USE THE SOFTWARE, INCLUDING, WITHOUT LIMITATION, ANY DIRECT,
30 * INDIRECT, INCIDENTAL, SPECIAL OR CONSEQUENTIAL DAMAGES OR LOSS OF DATA,
31 * SAVINGS OR PROFITS,
32 * EVEN IF Disclaimer HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
33 * YOU ASSUME ALL RESPONSIBILITIES FOR SELECTION OF THE SOFTWARE TO ACHIEVE YOUR
34 * INTENDED RESULTS, AND FOR THE INSTALLATION OF, USE OF, AND RESULTS OBTAINED
35 * FROM, THE SOFTWARE.
36 *
37 * This software may be replicated in part or whole for the licensed use,
38 * with the restriction that this Disclaimer and Copyright notice must be
39 * included with each copy of this software, whether used in part or whole,
40 * at all times.
41 */
42 /******************************************************************************/
43 /** \file rtc.c
44  **
45  ** RTC function driver API.
46  ** @link SampleGroup Some description @endlink
47  **
48  **   - 2017-05-17  1.0  CJ First version for Device Driver Library of Module.
49  **
50  ******************************************************************************/
51 
52 /******************************************************************************/
53 /* Include files                                                              */
54 /******************************************************************************/
55 #include "rtc.h"
56 /**
57  ******************************************************************************
58  ** \addtogroup RtcGroup
59  ******************************************************************************/
60 //@{
61 
62 /******************************************************************************/
63 /* Local pre-processor symbols/macros ('#define')                             */
64 /******************************************************************************/
65 #define IS_VALID_CLK(x)             (RtcClk32768 == (x)||\
66                                      RtcClk32768_1== (x)||\
67                                      RtcClk32 == (x)||\
68                                      RtcClk32_1 == (x)||\
69                                      RtcClkHxt128 == (x)||\
70                                      RtcClkHxt256 == (x)||\
71                                      RtcClkHxt512 == (x)||\
72                                      RtcClkHxt1024 == (x))
73 
74 #define IS_VALID_CYCSEL(x)        (RtcPrads == (x)||\
75                                  RtcPradx==(x))
76 
77 #define IS_VALID_PRDS(x)     (Rtc_None == (x)||\
78                               Rtc_05S == (x)||\
79                               Rtc_1S == (x)||\
80                               Rtc_1Min == (x)||\
81                               Rtc_1H == (x)||\
82                               Rtc_1Day == (x)||\
83                               Rtc_1Mon == (x)||\
84                               Rtc_1Mon_1 == (x))
85 
86 #define     IS_VALID_IRQ_SEL(x)      (RtcPrdf == (x) ||\
87                                       RtcAlmf == (x))
88 
89 #define     IS_VALID_FUNC(x)  ((RtcCount==(x))||\
90                                (RtcAlarmEn==(x))||\
91                                (Rtc_ComenEn==(x))||\
92                                (Rtc1HzOutEn==(x)))
93 #define     CkDateTime    0x7F
94 #define     CkDate        0x78
95 #define     CkTime        0x07
96 
97 //#define DecToBcd(x)           ((((x)/10)<<4) + ((x)%10))
98 //#define BcdToDec(x)           ((((x)>>4)*10) + ((x)&0x0F))
99 
100 #define RTC_TIMEOUT             1000//test 1s
101 
102 /******************************************************************************/
103 /* Local function prototypes ('const')                                       */
104 /******************************************************************************/
105 const uint8_t Leap_Month_Base[]     =    {3,6,0,3,5,1,3,6,2,4,0,2};
106 const uint8_t NonLeap_Month_Base[]  =    {4,0,0,3,5,1,3,6,2,4,0,2};
107 const uint8_t Cnst_Month_Tbl[12]={0x31,0x28,0x31,0x30,0x31,0x30,0x31,0x31,0x30,0x31,0x30,0x31};
108 /******************************************************************************/
109 /* Local function prototypes ('static')                                       */
110 /******************************************************************************/
111 static stc_rtc_intern_cb_t* RtcGetInternDataCb(void);
112 /******************************************************************************/
113 /* Local variable prototypes ('static')                                       */
114 /******************************************************************************/
115 static stc_rtc_intern_cb_t stcRtcIrqCb = {NULL, NULL};
116 /**
117  ******************************************************************************
118  ** \brief  RTC计数时钟选择
119  **
120  ** \param [in] enClk时钟源
121  **
122  ** \retval Ok
123  **
124  ******************************************************************************/
Rtc_SelClk(en_rtc_clk_t enClk)125 en_result_t Rtc_SelClk(en_rtc_clk_t enClk)
126 {
127     en_result_t enRet = Error;
128     ASSERT(IS_VALID_CLK(enClk));
129     M0P_RTC->CR1_f.CKSEL = enClk;
130     enRet = Ok;
131     return enRet;
132 }
133 /**
134  ******************************************************************************
135  ** \brief  RTC周期中断方式选择
136  **
137  ** \param [in] pstccCyc周期中断方式及周期间隔选择
138  **
139  ** \retval Ok
140  **
141  ******************************************************************************/
Rtc_SetCyc(stc_rtc_cyc_sel_t * pstcCyc)142 en_result_t Rtc_SetCyc(stc_rtc_cyc_sel_t* pstcCyc)
143 {
144     en_result_t enRet = Error;
145     ASSERT(IS_VALID_CYCSEL(pstcCyc->enCyc_sel));
146     ASSERT(IS_VALID_PRDS(pstcCyc->enPrds_sel));
147     M0P_RTC->CR0_f.PRDSEL = pstcCyc->enCyc_sel;
148     if(pstcCyc->enCyc_sel)
149     {
150         M0P_RTC->CR0_f.PRDX = pstcCyc->u8Prdx;
151     }
152     else
153     {
154         M0P_RTC->CR0_f.PRDS = pstcCyc->enPrds_sel;
155     }
156     enRet = Ok;
157     return enRet;
158 }
159 /**
160  ******************************************************************************
161  ** \brief  RTC时制选择
162  **
163  ** \param [in] bmode是12时制or24时制
164  **
165  ** \retval Ok  设置正常
166  ** \retval ErrorInvalidParameter 设置异常
167  ******************************************************************************/
Rtc_SetAmPm(en_rtc_ampm_t enMode)168 en_result_t Rtc_SetAmPm(en_rtc_ampm_t enMode)
169 {
170     en_result_t enRet = Error;
171     switch(enMode)
172     {
173         case 0:
174         case 1:
175             M0P_RTC->CR0_f.AMPM = enMode;
176             break;
177         default:
178             return ErrorInvalidParameter;
179     }
180     enRet = Ok;
181     return enRet;
182 }
183 /**
184  ******************************************************************************
185  ** \brief  RTC时制获取
186  **
187  ** \param [in] 无
188  **
189  ** \retval 时制
190  ******************************************************************************/
Rtc_GetHourMode(void)191 boolean_t Rtc_GetHourMode(void)
192 {
193   return(M0P_RTC->CR0_f.AMPM);
194 }
195 /**
196  ******************************************************************************
197  ** \brief  RTC闹钟中断设置
198  **
199  ** \param [in] pstcAlarmTime闹钟时间时、分、周
200  **
201  ** \retval Ok  设置正常
202  **
203  ******************************************************************************/
Rtc_SetAlarmTime(stc_rtc_alarmset_t * pstcAlarmTime)204 en_result_t Rtc_SetAlarmTime(stc_rtc_alarmset_t* pstcAlarmTime)
205 {
206     en_result_t enRet = Ok;
207     ASSERT(NULL != pstcAlarmTime);
208     if(Rtc12h == M0P_RTC->CR0_f.AMPM)
209     {
210         enRet = Check_BCD_Format(pstcAlarmTime->u8Hour,0x00,0x12);
211     }
212     else
213     {
214         enRet = Check_BCD_Format(pstcAlarmTime->u8Hour,0x00,0x24);
215     }
216     if(enRet != Ok)
217     {
218         return enRet;
219     }
220     enRet = Check_BCD_Format(pstcAlarmTime->u8Minute,0x00,0x59);
221     if(enRet != Ok)
222     {
223         return enRet;
224     }
225    // enRet = Check_BCD_Format(pstcAlarmTime->u8Week,0x00,0x06);
226     if(enRet != Ok)
227     {
228         return enRet;
229     }
230     M0P_RTC->ALMHOUR = pstcAlarmTime->u8Hour;
231     M0P_RTC->ALMMIN = pstcAlarmTime->u8Minute;
232     M0P_RTC->ALMWEEK = pstcAlarmTime->u8Week;
233     enRet = Ok;
234     return enRet;
235 }
236 /**
237  ******************************************************************************
238  ** \brief  RTC闹钟中断时间获取
239  **
240  ** \param [in] pstcAlarmTime闹钟时间时、分、周
241  **
242  ** \retval Ok  设置正常
243  **
244  ******************************************************************************/
Rtc_GetAlarmTime(stc_rtc_alarmset_t * pstcAlarmTime)245 en_result_t Rtc_GetAlarmTime(stc_rtc_alarmset_t* pstcAlarmTime)
246 {
247     en_result_t enRet = Error;
248     ASSERT(NULL != pstcAlarmTime);
249     pstcAlarmTime->u8Minute = M0P_RTC->ALMMIN;
250     pstcAlarmTime->u8Hour = M0P_RTC->ALMHOUR;
251     pstcAlarmTime->u8Week = M0P_RTC->ALMWEEK;
252     enRet = Ok;
253     return enRet;
254 }
255 /**
256  ******************************************************************************
257  ** \brief  RTC 1hz模式选择
258  **
259  ** \param [in] bmode 高精度和普通精度
260  **
261  ** \retval Ok  设置正常
262  **
263  ******************************************************************************/
Rtc_Set1HzMode(boolean_t bMode)264 en_result_t Rtc_Set1HzMode(boolean_t bMode)
265 {
266     en_result_t enRet = Error;
267     M0P_RTC->CR0_f.HZ1SEL = bMode;
268     enRet = Ok;
269     return enRet;
270 }
271 /**
272  ******************************************************************************
273  ** \brief  RTC 1hz补偿值设置
274  **
275  ** \param [in] u16Cr 补偿值
276  **
277  ** \retval Ok  设置正常
278  **
279  ******************************************************************************/
Rtc_SetCompCr(uint16_t u16Cr)280 en_result_t Rtc_SetCompCr(uint16_t u16Cr)
281 {
282     en_result_t enRet = Error;
283     M0P_RTC->COMPEN_f.CR = u16Cr;
284     enRet = Ok;
285     return enRet;
286 }
287 /**
288  ******************************************************************************
289  ** \brief  RTC 功能使能设置
290  **
291  ** \param [in] enFunc 功能选择
292  **
293  ** \retval Ok  设置正常
294  ** \retval ErrorInvalidParameter 设置异常
295  ******************************************************************************/
Rtc_EnableFunc(en_rtc_func_t enFunc)296 en_result_t Rtc_EnableFunc(en_rtc_func_t enFunc)
297 {
298     ASSERT(IS_VALID_FUNC(enFunc));
299     switch(enFunc)
300     {
301         case RtcCount:
302             M0P_RTC->CR0_f.START = 1u;
303             break;
304         case RtcAlarmEn:
305             M0P_RTC->CR1_f.ALMEN = 1u;
306             break;
307         case Rtc_ComenEn:
308             M0P_RTC->COMPEN_f.EN = 1u;
309             break;
310         case Rtc1HzOutEn:
311             M0P_RTC->CR0_f.HZ1OE = 1u;
312             break;
313         default:
314             return ErrorInvalidParameter;
315     }
316     return Ok;
317 }
318 /**
319  ******************************************************************************
320  ** \brief  RTC 功能禁止设置
321  **
322  ** \param [in] enFunc 功能选择
323  **
324  ** \retval Ok  设置正常
325  ** \retval ErrorInvalidParameter 设置异常
326  ******************************************************************************/
Rtc_DisableFunc(en_rtc_func_t enFunc)327 en_result_t Rtc_DisableFunc(en_rtc_func_t enFunc)
328 {
329     ASSERT(IS_VALID_FUNC(enFunc));
330     switch(enFunc)
331     {
332         case RtcCount:
333             M0P_RTC->CR0_f.START = 0u;
334             break;
335         case RtcAlarmEn:
336             M0P_RTC->CR1_f.ALMEN = 0u;
337             break;
338         case Rtc_ComenEn:
339             M0P_RTC->COMPEN_f.EN = 0u;
340             break;
341         case Rtc1HzOutEn:
342             M0P_RTC->CR0_f.HZ1OE = 0u;
343             break;
344         default:
345             return ErrorInvalidParameter;
346     }
347     return Ok;
348 }
Change_DateTimeFormat(uint8_t u8sr)349 uint8_t Change_DateTimeFormat(uint8_t u8sr)
350 {
351     uint8_t u8de=0;
352     while(u8sr>=0x10)
353     {
354         u8de +=10;
355         u8sr -=0x10;
356     }
357     u8de += u8sr;
358     return(u8de);
359 }
360 /**
361  ******************************************************************************
362  ** \brief  RTC 平、闰年检测
363  **
364  ** \param [in] u8year 年十进制低两位
365  **
366  ** \retval 1  闰年
367  ** \retval 0 平年
368  ******************************************************************************/
Rtc_CheckLeapYear(uint8_t u8year)369 uint8_t Rtc_CheckLeapYear(uint8_t u8year)
370 {
371     uint8_t u8year_shl,u8year_shr;
372     u8year_shl = u8year>>2;
373     u8year_shr = u8year_shl<<2;
374     if(u8year== u8year_shr)
375     {
376         return 1;
377     }
378     else
379     {
380         return 0;
381     }
382 }
383 /**
384  ******************************************************************************
385  ** \brief  RTC根据日期计算周数
386  **
387  ** \param [in] pu8Date日期
388  **
389  ** \retval week  周数
390  **
391  ******************************************************************************/
Rtc_CalWeek(uint8_t * pu8Date)392 uint8_t Rtc_CalWeek(uint8_t* pu8Date)
393 {
394     uint8_t u8week;
395     if((Rtc_CheckLeapYear(Change_DateTimeFormat(*(pu8Date+2)))==1))
396     {
397         u8week = (Change_DateTimeFormat(*(pu8Date+2))+Change_DateTimeFormat(*(pu8Date+2))/4+Leap_Month_Base[Change_DateTimeFormat(*(pu8Date+1))-1]+Change_DateTimeFormat(*(pu8Date))+2)%7;
398     }
399     else
400     {
401         u8week = (Change_DateTimeFormat(*(pu8Date+2))+Change_DateTimeFormat(*(pu8Date+2))/4+NonLeap_Month_Base[Change_DateTimeFormat(*(pu8Date+1))-1]+Change_DateTimeFormat(*(pu8Date))+2)%7;
402     }
403     return u8week;
404 }
405 /**
406  ******************************************************************************
407  ** \brief  RTC根据年月获取天数
408  **
409  ** \param [in] u8month月份,u8year年份
410  **
411  ** \retval u8day天数
412  **
413  ******************************************************************************/
Get_Month_Max_Day(uint8_t u8month,uint8_t u8year)414 uint8_t Get_Month_Max_Day(uint8_t u8month, uint8_t u8year)
415 {
416     uint8_t u8day = 0;
417 
418     u8day = Cnst_Month_Tbl[u8month - 1];
419     if((u8month == 2) && ((u8year % 4) == 0))
420     {
421         u8day++;
422     }
423     return(u8day);//day的格式是bcd码,例如;日为31天,day=0x31
424 }
425 /**
426  ******************************************************************************
427  ** \brief  RTC根据日期计算周数
428  **
429  ** \param [in] pu8buf日期时间数据,u8len检查数据长度,u8limit_min最小值,u8limit_max最大值
430  **
431  ** \retval Error 错误,Ok校验正确
432  **
433  ******************************************************************************/
Check_BCD_Format(uint8_t u8data,uint8_t u8limit_min,uint8_t u8limit_max)434 en_result_t Check_BCD_Format(uint8_t u8data,uint8_t u8limit_min, uint8_t u8limit_max)
435 {
436 
437     if (((u8data & 0x0F) > 0x09) || ((u8data & 0xF0) > 0x90)
438     ||(u8data > u8limit_max) || (u8data < u8limit_min))
439     {
440         return Error;
441     }
442     return Ok;
443 }
444 /**
445  ******************************************************************************
446  ** \brief  RTC时间格式检测
447  **
448  ** \param [in] pu8TimeDate日期时间数据,u8Mode检测模式
449  **
450  ** \retval enRet校验结果
451  **
452  ******************************************************************************/
Rtc_CheckDateTimeFormat(uint8_t * pu8TimeDate,uint8_t u8Mode)453 en_result_t Rtc_CheckDateTimeFormat(uint8_t* pu8TimeDate,uint8_t u8Mode)
454 {
455     uint8_t u8i=0;
456     uint8_t u8mon_max_day = 0x28;
457     uint8_t u8date[3];
458     uint8_t u8Hour = 0;
459     en_result_t enRet=Error;
460     while(u8i<7)
461     {
462         if(u8Mode && (1 << u8i) != 0)
463         {
464             switch(u8i)
465             {
466                 case 0:
467                     enRet = Check_BCD_Format(*pu8TimeDate,0x00,0x59);//秒
468                     break;
469                 case 1:
470                     enRet = Check_BCD_Format(*pu8TimeDate,0x00,0x59);//分
471                     break;
472                 case 2:
473                     if(Rtc12h == M0P_RTC->CR0_f.AMPM)
474                     {
475                         u8Hour = *pu8TimeDate&0x1f;
476                         enRet = Check_BCD_Format(u8Hour,0x00,0x12);//时
477                     }
478                     else
479                     {
480                         enRet = Check_BCD_Format(*pu8TimeDate,0x00,0x24);
481                     }
482                     break;
483                 case 3:
484                     enRet = Check_BCD_Format(*pu8TimeDate,0x00,0x06);
485                     break;
486                 case 4:
487                     enRet = Check_BCD_Format(*pu8TimeDate,0x00,0x31);
488                     u8date[0] = *pu8TimeDate;
489                     break;
490                 case 5:
491                     enRet = Check_BCD_Format(*pu8TimeDate,0x00,0x12);
492                     u8date[1] = *pu8TimeDate;
493                     break;
494                 case 6:
495                     enRet = Check_BCD_Format(*pu8TimeDate,0x00,0x99);
496                     u8date[2] = *pu8TimeDate;
497                     break;
498                 default:
499                   break;
500             }
501             pu8TimeDate++;
502         }
503         if(enRet!=Ok)
504         {
505             return enRet;
506         }
507         u8i++;
508     }
509        if((u8Mode&0x10)&&(u8Mode&0x20))
510     {
511         if(u8Mode&0x40)
512         {
513           u8mon_max_day = Get_Month_Max_Day(Change_DateTimeFormat(u8date[1]), Change_DateTimeFormat(u8date[2]));
514         }
515         else
516         {
517             u8mon_max_day = Get_Month_Max_Day(Change_DateTimeFormat(u8date[1]), 1);
518         }
519         if(u8date[0]>u8mon_max_day)
520         {
521             return Error;
522         }
523     }
524     if((u8Mode&0x10)&&(!(u8Mode&0x20)))
525     {
526         if(u8date[0]>0x28)
527         {
528             return Error;
529         }
530     }
531     enRet = Ok;
532     return(enRet);
533 }
534 /**
535  ******************************************************************************
536  ** \brief  RTC设置时间函数
537  **
538  ** \param [in] pstcTimeDate日期时间数据、bUpdateTime是否更改时间、bUpdateDate是否更改日期
539  **
540  ** \retval Ok  设置正常
541  ** \retval ErrorTimeout 时间溢出错误
542  ******************************************************************************/
Rtc_WriteDateTime(stc_rtc_time_t * pstcTimeDate,boolean_t bUpdateTime,boolean_t bUpdateDate)543 en_result_t Rtc_WriteDateTime(stc_rtc_time_t* pstcTimeDate,boolean_t bUpdateTime,
544                             boolean_t bUpdateDate)
545 {
546     int32_t u32TimeOut;
547     uint8_t* pu8TimeDate;
548     en_result_t enRet = Ok;
549     u32TimeOut = RTC_TIMEOUT;
550     pu8TimeDate = &pstcTimeDate->u8Second;
551     ASSERT(NULL != pstcTimeDate);
552     if(1 == M0P_RTC->CR0_f.START)
553     {
554         M0P_RTC->CR1_f.WAIT = 1;
555         while(--u32TimeOut)
556         {
557             if(M0P_RTC->CR1_f.WAITF)
558             {
559                 break;
560             }
561         }
562         if(u32TimeOut==0)
563         {
564             return ErrorTimeout;
565         }
566     }
567     if(TRUE == bUpdateTime)
568     {
569         enRet = Rtc_CheckDateTimeFormat(pu8TimeDate,CkTime);
570         if(enRet != Ok)
571         {
572             return enRet;
573         }
574         M0P_RTC->SEC = pstcTimeDate->u8Second;
575         M0P_RTC->MIN = pstcTimeDate->u8Minute;
576         M0P_RTC->HOUR = pstcTimeDate->u8Hour;
577     }
578     if(TRUE == bUpdateDate)
579     {
580         enRet = Rtc_CheckDateTimeFormat(pu8TimeDate,CkDate);
581         if(enRet != Ok)
582         {
583             return enRet;
584         }
585         M0P_RTC->DAY = pstcTimeDate->u8Day;
586         M0P_RTC->MON = pstcTimeDate->u8Month;
587         M0P_RTC->YEAR = pstcTimeDate->u8Year;
588         M0P_RTC->WEEK = pstcTimeDate->u8DayOfWeek;
589     }
590     M0P_RTC->CR1_f.WAIT = 0;
591     if(1 == M0P_RTC->CR0_f.START)
592     {
593         while(M0P_RTC->CR1_f.WAITF)
594         {}
595     }
596     return enRet;
597 }
598 /**
599  ******************************************************************************
600 ** \brief  RTC 12小时上午或下午获取
601  **
602  ** \param [in] 无
603  **
604 ** \retval 上午或下午
605  ******************************************************************************/
Rtc_RDAmPm(void)606 boolean_t Rtc_RDAmPm(void)
607 {
608 	boolean_t bRet;
609 
610     bRet = M0P_RTC->HOUR&0x20;
611     bRet>>=5;
612     return bRet;
613 }
614 /**
615  ******************************************************************************
616  ** \brief  RTC获取时间函数
617  **
618  ** \param [in] pstcTimeDate日期时间数据
619  **
620  ** \retval Ok  获取正常
621  ** \retval ErrorTimeout 时间溢出错误
622  ******************************************************************************/
Rtc_ReadDateTime(stc_rtc_time_t * pstcTimeDate)623 en_result_t Rtc_ReadDateTime(stc_rtc_time_t* pstcTimeDate)
624 {
625     uint32_t u32TimeOut;
626     uint8_t  u8DayOfWeek, u8BcdSec, u8BcdMin, u8BcdHour, u8Day, u8Month, u8Year;
627 
628     ASSERT(NULL != pstcTimeDate);
629     u32TimeOut = RTC_TIMEOUT;
630     if(1 == M0P_RTC->CR0_f.START)
631     {
632         M0P_RTC->CR1_f.WAIT = 1;
633         while(u32TimeOut--)
634         {
635             if(M0P_RTC->CR1_f.WAITF)
636             {
637             break;
638             }
639         }
640         if(u32TimeOut==0)
641         {
642             return ErrorTimeout;
643         }
644     }
645     u8BcdSec  = M0P_RTC->SEC;
646     u8BcdMin  = M0P_RTC->MIN;
647     u8BcdHour = M0P_RTC->HOUR;
648     u8Day     = M0P_RTC->DAY;
649     u8Month   = M0P_RTC->MON;
650     u8Year    = M0P_RTC->YEAR;
651     u8DayOfWeek = M0P_RTC->WEEK;
652 
653 	pstcTimeDate->u8Second = u8BcdSec;
654 	pstcTimeDate->u8Minute = u8BcdMin;
655 	if(1 == M0P_RTC->CR0_f.AMPM)
656 	{
657 		pstcTimeDate->u8Hour   = u8BcdHour;
658 	}
659 	else
660 	{
661 		pstcTimeDate->u8Hour   = u8BcdHour&0x1f;
662 	}
663 	pstcTimeDate->u8Day    = u8Day;
664 	pstcTimeDate->u8Month  = u8Month;
665 	pstcTimeDate->u8Year  = u8Year;
666 	pstcTimeDate->u8DayOfWeek = u8DayOfWeek;
667 
668     M0P_RTC->CR1_f.WAIT = 0;
669     if(1 == M0P_RTC->CR0_f.START)
670     {
671         while(M0P_RTC->CR1_f.WAITF)
672         {}
673     }
674 
675     return Ok;
676 }
677 /**
678  ******************************************************************************
679  ** \brief  RTC计数or读写状态获取
680  **
681  ** \param [in] 无
682  **
683  ** \retval 计数or读写状态
684  **
685  ******************************************************************************/
Rtc_RDStatus(void)686 boolean_t Rtc_RDStatus(void)
687 {
688     boolean_t bRet;
689     bRet = M0P_RTC->CR1_f.WAITF;
690     return bRet;
691 }
692 /**
693  ******************************************************************************
694  ** \brief  RTC闹钟中断使能
695  **
696  ** \param [in] enordis中断使能or禁止
697  **
698  ** \retval Ok设置成功
699  **
700  ******************************************************************************/
Rtc_EnAlarmIrq(en_rtc_alarmirq_t enIrqEn)701 en_result_t Rtc_EnAlarmIrq(en_rtc_alarmirq_t enIrqEn)
702 {
703     en_result_t enRet = Error;
704     M0P_RTC->CR1_f.ALMIE = enIrqEn;
705     Rtc_ClrIrqStatus(RtcAlmf);//使能中断后清除中断请求标记
706     enRet = Ok;
707     return enRet;
708 }
709 /**
710  ******************************************************************************
711  ** \brief  RTC中断请求状态获取
712  **
713  ** \param [in] enIrqSel获取哪种中断请求
714  **
715  ** \retval 中断请求状态
716  **
717  ******************************************************************************/
Rtc_GetIrqStatus(en_rtc_status_irq_t enIrqSel)718 boolean_t Rtc_GetIrqStatus(en_rtc_status_irq_t enIrqSel)
719 {
720     boolean_t bRet = FALSE;
721     ASSERT(IS_VALID_IRQ_SEL(enIrqSel));
722     switch(enIrqSel)
723     {
724         case RtcPrdf:
725             (M0P_RTC->CR1_f.PRDF == 1)?(bRet = TRUE) : (bRet = FALSE);
726             break;
727         case RtcAlmf :
728             (M0P_RTC->CR1_f.ALMF == 1)?(bRet = TRUE) : (bRet = FALSE);
729             break;
730         default:
731             break;
732     }
733     return bRet;
734 }
735 /**
736  ******************************************************************************
737  ** \brief  RTC中断请求清除
738  **
739  ** \param [in] enIrqSel清除哪种中断请求
740  **
741  ** \retval Ok 清除成功
742  ** \retval ErrorInvalidParameter 清除失败
743  ******************************************************************************/
Rtc_ClrIrqStatus(en_rtc_status_irq_t enIrqSel)744 en_result_t Rtc_ClrIrqStatus(en_rtc_status_irq_t enIrqSel)
745 {
746     ASSERT(IS_VALID_IRQ_SEL(enIrqSel));
747     switch(enIrqSel)
748     {
749         case RtcPrdf:
750             M0P_RTC->CR1_f.PRDF = 0;
751             break;
752         case  RtcAlmf:
753             M0P_RTC->CR1_f.ALMF = 0;
754             break;
755         default:
756             return ErrorInvalidParameter;
757     }
758     return Ok;
759 }
760 
761 /**
762  ******************************************************************************
763  ** \brief  RTC中断处理函数接口获取
764  **
765  ** \param [in] 无
766  **
767  ** \retval 接口函数地址
768  **
769  ******************************************************************************/
RtcGetInternDataCb(void)770 static stc_rtc_intern_cb_t* RtcGetInternDataCb(void)
771 {
772     return &stcRtcIrqCb;
773 }
774 /**
775  ******************************************************************************
776  ** \brief  RTC总体初始化函数
777  **
778  ** \param [in] pstcRtcConfig初始化结构
779  **
780  ** \retval Ok初始化成功
781  ** \retval ErrorInvalidParameter 初始化错误
782  ******************************************************************************/
Rtc_Init(stc_rtc_config_t * pstcRtcConfig)783 en_result_t Rtc_Init(stc_rtc_config_t* pstcRtcConfig)
784 {
785     en_result_t enRet = Error;
786     stc_rtc_intern_cb_t* pstcRtcInternCb;
787     if(NULL == pstcRtcConfig)
788     {
789         return Error;
790     }
791     pstcRtcInternCb =  RtcGetInternDataCb();
792     enRet = Rtc_SelClk(pstcRtcConfig->enClkSel);
793     enRet = Rtc_SetAmPm(pstcRtcConfig->enAmpmSel);
794     if(enRet != Ok)
795     {
796       return enRet;
797     }
798     if(NULL != pstcRtcConfig->pstcCycSel)
799     {
800         if(Ok != Rtc_SetCyc(pstcRtcConfig->pstcCycSel))
801         {
802             return Error;
803         }
804     }
805     if(NULL != pstcRtcConfig->pstcTimeDate)
806     {
807         if(Ok != Rtc_WriteDateTime(pstcRtcConfig->pstcTimeDate,TRUE,TRUE))
808         {
809             return Error;
810         }
811     }
812     if(NULL != pstcRtcConfig->pstcIrqCb)
813     {
814         pstcRtcInternCb->pfnAlarmIrqCb = pstcRtcConfig->pstcIrqCb->pfnAlarmIrqCb;
815         pstcRtcInternCb->pfnTimerIrqCb = pstcRtcConfig->pstcIrqCb->pfnTimerIrqCb;
816     }
817     if(TRUE == pstcRtcConfig->bTouchNvic)
818     {
819         EnableNvic(RTC_IRQn,IrqLevel3,TRUE);
820     }
821     else
822     {
823         EnableNvic(RTC_IRQn,IrqLevel3,FALSE);
824     }
825     return enRet;
826 }
827 /**
828  ******************************************************************************
829  ** \brief  RTC计数禁止函数
830  **
831  ** \param [in] 无
832  **
833  ** \retval Ok禁止设置成功
834  **
835  ******************************************************************************/
Rtc_DeInit(void)836 en_result_t Rtc_DeInit(void)
837 {
838     EnableNvic(RTC_IRQn,IrqLevel3,FALSE);
839     Rtc_DisableFunc(RtcCount);
840     Rtc_DisableFunc(RtcAlarmEn);
841     Rtc_DisableFunc(Rtc_ComenEn);
842     Rtc_DisableFunc(Rtc1HzOutEn);
843     return Ok;
844 }
845 /**
846  ******************************************************************************
847  ** \brief  RTC中断处理函数
848  **
849  ** \param [in] 无
850  **
851  ** \retval 无
852  **
853  ******************************************************************************/
Rtc_IRQHandler(void)854 void Rtc_IRQHandler(void)
855 {
856     stc_rtc_intern_cb_t* pstcRtcInternCb;
857     pstcRtcInternCb = RtcGetInternDataCb() ;
858     if(TRUE == M0P_RTC->CR1_f.ALMF)
859     {
860         M0P_RTC->CR1_f.ALMF = 0u;
861         if(NULL != pstcRtcInternCb->pfnAlarmIrqCb)
862         {
863             pstcRtcInternCb->pfnAlarmIrqCb();
864         }
865     }
866     if(TRUE == M0P_RTC->CR1_f.PRDF)
867     {
868         M0P_RTC->CR1_f.PRDF = 0;
869         if(NULL != pstcRtcInternCb->pfnTimerIrqCb)
870         {
871             pstcRtcInternCb->pfnTimerIrqCb();
872         }
873     }
874 }
875 //@} // RtcGroup
876