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