rtc.c 26 KB

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