gd32f4xx_rtc.c 43 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257
  1. /*!
  2. \file gd32f4xx_rtc.c
  3. \brief RTC driver
  4. */
  5. /*
  6. Copyright (C) 2016 GigaDevice
  7. 2016-08-15, V1.0.0, firmware for GD32F4xx
  8. */
  9. #include "gd32f4xx_rtc.h"
  10. /* RTC timeout value */
  11. #define RTC_WTWF_TIMEOUT ((uint32_t)0x00004000U) /*!< wakeup timer can be write flag timeout */
  12. #define RTC_INITM_TIMEOUT ((uint32_t)0x00004000U) /*!< initialization state flag timeout */
  13. #define RTC_RSYNF_TIMEOUT ((uint32_t)0x00008000U) /*!< register synchronization flag timeout */
  14. #define RTC_HRFC_TIMEOUT ((uint32_t)0x20000000U) /*!< recalibration pending flag timeout */
  15. #define RTC_SHIFTCTL_TIMEOUT ((uint32_t)0x00001000U) /*!< shift function operation pending flag timeout */
  16. #define RTC_ALRMXWF_TIMEOUT ((uint32_t)0x00008000U) /*!< alarm configuration can be write flag timeout */
  17. /*!
  18. \brief reset most of the RTC registers
  19. \param[in] none
  20. \param[out] none
  21. \retval ErrStatus: ERROR or SUCCESS
  22. */
  23. ErrStatus rtc_deinit(void)
  24. {
  25. ErrStatus error_status = ERROR;
  26. volatile uint32_t time_index = RTC_WTWF_TIMEOUT;
  27. uint32_t flag_status = RESET;
  28. /* RTC_TAMP register is not under write protection */
  29. RTC_TAMP = RTC_REGISTER_RESET;
  30. /* disable the write protection */
  31. RTC_WPK = RTC_UNLOCK_KEY1;
  32. RTC_WPK = RTC_UNLOCK_KEY2;
  33. /* enter init mode */
  34. error_status = rtc_init_mode_enter();
  35. if(ERROR != error_status){
  36. /* reset RTC_CTL register, but RTC_CTL[2£º0] */
  37. RTC_CTL &= (RTC_REGISTER_RESET | RTC_CTL_WTCS);
  38. /* before reset RTC_TIME and RTC_DATE, BPSHAD bit in RTC_CTL should be reset as the condition.
  39. in order to read calendar from shadow register, not the real registers being reset */
  40. RTC_TIME = RTC_REGISTER_RESET;
  41. RTC_DATE = RTC_DATE_RESET;
  42. RTC_PSC = RTC_PSC_RESET;
  43. /* only when RTC_CTL_WTEN=0 and RTC_STAT_WTWF=1 can write RTC_CTL[2£º0] */
  44. /* wait until the WTWF flag to be set */
  45. do{
  46. flag_status = RTC_STAT & RTC_STAT_WTWF;
  47. }while((--time_index > 0U) && ((uint32_t)RESET == flag_status));
  48. if ((uint32_t)RESET == flag_status){
  49. error_status = ERROR;
  50. }else{
  51. RTC_CTL &= RTC_REGISTER_RESET;
  52. RTC_WUT = RTC_WUT_RESET;
  53. RTC_COSC = RTC_REGISTER_RESET;
  54. /* to write RTC_ALRMxSS register, ALRMxEN bit in RTC_CTL register should be reset as the condition */
  55. RTC_ALRM0TD = RTC_REGISTER_RESET;
  56. RTC_ALRM1TD = RTC_REGISTER_RESET;
  57. RTC_ALRM0SS = RTC_REGISTER_RESET;
  58. RTC_ALRM1SS = RTC_REGISTER_RESET;
  59. /* reset RTC_STAT register, also exit init mode.
  60. at the same time, RTC_STAT_SOPF bit is reset, as the condition to reset RTC_SHIFTCTL register later */
  61. RTC_STAT = RTC_STAT_RESET;
  62. /* reset RTC_SHIFTCTL and RTC_HRFC register, this can be done without the init mode */
  63. RTC_SHIFTCTL = RTC_REGISTER_RESET;
  64. RTC_HRFC = RTC_REGISTER_RESET;
  65. error_status = rtc_register_sync_wait();
  66. }
  67. }
  68. /* enable the write protection */
  69. RTC_WPK = RTC_LOCK_KEY;
  70. return error_status;
  71. }
  72. /*!
  73. \brief initialize RTC registers
  74. \param[in] rtc_initpara_struct: pointer to a rtc_parameter_struct structure which contains
  75. parameters for initialization of the rtc peripheral
  76. members of the structure and the member values are shown as below:
  77. year: 0x0 - 0x99(BCD format)
  78. month: RTC_JAN, RTC_FEB, RTC_MAR, RTC_APR, RTC_MAY, RTC_JUN,
  79. RTC_JUL, RTC_AUG, RTC_SEP, RTC_OCT, RTC_NOV, RTC_DEC
  80. date: 0x1 - 0x31(BCD format)
  81. day_of_week: RTC_MONDAY, RTC_TUESDAY, RTC_WEDSDAY, RTC_THURSDAY
  82. RTC_FRIDAY, RTC_SATURDAY, RTC_SUNDAY
  83. hour: 0x0 - 0x12(BCD format) or 0x0 - 0x23(BCD format) depending on the rtc_display_format chose
  84. minute: 0x0 - 0x59(BCD format)
  85. second: 0x0 - 0x59(BCD format)
  86. factor_asyn: 0x0 - 0x7F
  87. factor_syn: 0x0 - 0x7FFF
  88. am_pm: RTC_AM, RTC_PM
  89. display_format: RTC_24HOUR, RTC_12HOUR
  90. \param[out] none
  91. \retval ErrStatus: ERROR or SUCCESS
  92. */
  93. ErrStatus rtc_init(rtc_parameter_struct* rtc_initpara_struct)
  94. {
  95. ErrStatus error_status = ERROR;
  96. uint32_t reg_time = 0U, reg_date = 0U;
  97. reg_date = (DATE_YR(rtc_initpara_struct->year) | \
  98. DATE_DOW(rtc_initpara_struct->day_of_week) | \
  99. DATE_MON(rtc_initpara_struct->month) | \
  100. DATE_DAY(rtc_initpara_struct->date));
  101. reg_time = (rtc_initpara_struct->am_pm| \
  102. TIME_HR(rtc_initpara_struct->hour) | \
  103. TIME_MN(rtc_initpara_struct->minute) | \
  104. TIME_SC(rtc_initpara_struct->second));
  105. /* 1st: disable the write protection */
  106. RTC_WPK = RTC_UNLOCK_KEY1;
  107. RTC_WPK = RTC_UNLOCK_KEY2;
  108. /* 2nd: enter init mode */
  109. error_status = rtc_init_mode_enter();
  110. if(ERROR != error_status){
  111. RTC_PSC = (uint32_t)(PSC_FACTOR_A(rtc_initpara_struct->factor_asyn)| \
  112. PSC_FACTOR_S(rtc_initpara_struct->factor_syn));
  113. RTC_TIME = (uint32_t)reg_time;
  114. RTC_DATE = (uint32_t)reg_date;
  115. RTC_CTL &= (uint32_t)(~RTC_CTL_CS);
  116. RTC_CTL |= rtc_initpara_struct->display_format;
  117. /* 3rd: exit init mode */
  118. rtc_init_mode_exit();
  119. /* 4th: wait the RSYNF flag to set */
  120. error_status = rtc_register_sync_wait();
  121. }
  122. /* 5th: enable the write protection */
  123. RTC_WPK = RTC_LOCK_KEY;
  124. return error_status;
  125. }
  126. /*!
  127. \brief enter RTC init mode
  128. \param[in] none
  129. \param[out] none
  130. \retval ErrStatus: ERROR or SUCCESS
  131. */
  132. ErrStatus rtc_init_mode_enter(void)
  133. {
  134. volatile uint32_t time_index = RTC_INITM_TIMEOUT;
  135. uint32_t flag_status = RESET;
  136. ErrStatus error_status = ERROR;
  137. /* check whether it has been in init mode */
  138. if ((uint32_t)RESET == (RTC_STAT & RTC_STAT_INITF)){
  139. RTC_STAT |= RTC_STAT_INITM;
  140. /* wait until the INITF flag to be set */
  141. do{
  142. flag_status = RTC_STAT & RTC_STAT_INITF;
  143. }while((--time_index > 0U) && ((uint32_t)RESET == flag_status));
  144. if ((uint32_t)RESET != flag_status){
  145. error_status = SUCCESS;
  146. }
  147. }else{
  148. error_status = SUCCESS;
  149. }
  150. return error_status;
  151. }
  152. /*!
  153. \brief exit RTC init mode
  154. \param[in] none
  155. \param[out] none
  156. \retval none
  157. */
  158. void rtc_init_mode_exit(void)
  159. {
  160. RTC_STAT &= (uint32_t)(~RTC_STAT_INITM);
  161. }
  162. /*!
  163. \brief wait until RTC_TIME and RTC_DATE registers are synchronized with APB clock, and the shadow
  164. registers are updated
  165. \param[in] none
  166. \param[out] none
  167. \retval ErrStatus: ERROR or SUCCESS
  168. */
  169. ErrStatus rtc_register_sync_wait(void)
  170. {
  171. volatile uint32_t time_index = RTC_RSYNF_TIMEOUT;
  172. uint32_t flag_status = RESET;
  173. ErrStatus error_status = ERROR;
  174. if ((uint32_t)RESET == (RTC_CTL & RTC_CTL_BPSHAD)){
  175. /* disable the write protection */
  176. RTC_WPK = RTC_UNLOCK_KEY1;
  177. RTC_WPK = RTC_UNLOCK_KEY2;
  178. /* firstly clear RSYNF flag */
  179. RTC_STAT &= (uint32_t)(~RTC_STAT_RSYNF);
  180. /* wait until RSYNF flag to be set */
  181. do{
  182. flag_status = RTC_STAT & RTC_STAT_RSYNF;
  183. }while((--time_index > 0U) && ((uint32_t)RESET == flag_status));
  184. if ((uint32_t)RESET != flag_status){
  185. error_status = SUCCESS;
  186. }
  187. /* enable the write protection */
  188. RTC_WPK = RTC_LOCK_KEY;
  189. }else{
  190. error_status = SUCCESS;
  191. }
  192. return error_status;
  193. }
  194. /*!
  195. \brief get current time and date
  196. \param[in] none
  197. \param[out] rtc_initpara_struct: pointer to a rtc_parameter_struct structure which contains
  198. parameters for initialization of the rtc peripheral
  199. members of the structure and the member values are shown as below:
  200. year: 0x0 - 0x99(BCD format)
  201. month: RTC_JAN, RTC_FEB, RTC_MAR, RTC_APR, RTC_MAY, RTC_JUN,
  202. RTC_JUL, RTC_AUG, RTC_SEP, RTC_OCT, RTC_NOV, RTC_DEC
  203. date: 0x1 - 0x31(BCD format)
  204. day_of_week: RTC_MONDAY, RTC_TUESDAY, RTC_WEDSDAY, RTC_THURSDAY
  205. RTC_FRIDAY, RTC_SATURDAY, RTC_SUNDAY
  206. hour: 0x0 - 0x12(BCD format) or 0x0 - 0x23(BCD format) depending on the rtc_display_format chose
  207. minute: 0x0 - 0x59(BCD format)
  208. second: 0x0 - 0x59(BCD format)
  209. factor_asyn: 0x0 - 0x7F
  210. factor_syn: 0x0 - 0x7FFF
  211. am_pm: RTC_AM, RTC_PM
  212. display_format: RTC_24HOUR, RTC_12HOUR
  213. \retval none
  214. */
  215. void rtc_current_time_get(rtc_parameter_struct* rtc_initpara_struct)
  216. {
  217. uint32_t temp_tr = 0U, temp_dr = 0U, temp_pscr = 0U, temp_ctlr = 0U;
  218. temp_tr = (uint32_t)RTC_TIME;
  219. temp_dr = (uint32_t)RTC_DATE;
  220. temp_pscr = (uint32_t)RTC_PSC;
  221. temp_ctlr = (uint32_t)RTC_CTL;
  222. /* get current time and construct rtc_parameter_struct structure */
  223. rtc_initpara_struct->year = (uint8_t)GET_DATE_YR(temp_dr);
  224. rtc_initpara_struct->month = (uint8_t)GET_DATE_MON(temp_dr);
  225. rtc_initpara_struct->date = (uint8_t)GET_DATE_DAY(temp_dr);
  226. rtc_initpara_struct->day_of_week = (uint8_t)GET_DATE_DOW(temp_dr);
  227. rtc_initpara_struct->hour = (uint8_t)GET_TIME_HR(temp_tr);
  228. rtc_initpara_struct->minute = (uint8_t)GET_TIME_MN(temp_tr);
  229. rtc_initpara_struct->second = (uint8_t)GET_TIME_SC(temp_tr);
  230. rtc_initpara_struct->factor_asyn = (uint16_t)GET_PSC_FACTOR_A(temp_pscr);
  231. rtc_initpara_struct->factor_syn = (uint16_t)GET_PSC_FACTOR_S(temp_pscr);
  232. rtc_initpara_struct->am_pm = (uint32_t)(temp_pscr & RTC_TIME_PM);
  233. rtc_initpara_struct->display_format = (uint32_t)(temp_ctlr & RTC_CTL_CS);
  234. }
  235. /*!
  236. \brief get current subsecond value
  237. \param[in] none
  238. \param[out] none
  239. \retval current subsecond value
  240. */
  241. uint32_t rtc_subsecond_get(void)
  242. {
  243. uint32_t reg = 0U;
  244. /* if BPSHAD bit is reset, reading RTC_SS will lock RTC_TIME and RTC_DATE automatically */
  245. reg = (uint32_t)RTC_SS;
  246. /* read RTC_DATE to unlock the 3 shadow registers */
  247. (void) (RTC_DATE);
  248. return reg;
  249. }
  250. /*!
  251. \brief configure RTC alarm
  252. \param[in] rtc_alarm: RTC_ALARM0 or RTC_ALARM1
  253. \param[in] rtc_alarm_time: pointer to a rtc_alarm_struct structure which contains
  254. parameters for RTC alarm configuration
  255. members of the structure and the member values are shown as below:
  256. alarm_mask: RTC_ALARM_NONE_MASK, RTC_ALARM_DATE_MASK, RTC_ALARM_HOUR_MASK
  257. RTC_ALARM_MINUTE_MASK, RTC_ALARM_SECOND_MASK, RTC_ALARM_ALL_MASK
  258. weekday_or_date: RTC_ALARM_DATE_SELECTED, RTC_ALARM_WEEKDAY_SELECTED
  259. alarm_day: 1) 0x1 - 0x31(BCD format) if RTC_ALARM_DATE_SELECTED is set
  260. 2) RTC_MONDAY, RTC_TUESDAY, RTC_WEDSDAY, RTC_THURSDAY, RTC_FRIDAY,
  261. RTC_SATURDAY, RTC_SUNDAY if RTC_ALARM_WEEKDAY_SELECTED is set
  262. alarm_hour: 0x0 - 0x12(BCD format) or 0x0 - 0x23(BCD format) depending on the rtc_display_format
  263. alarm_minute: 0x0 - 0x59(BCD format)
  264. alarm_second: 0x0 - 0x59(BCD format)
  265. am_pm: RTC_AM, RTC_PM
  266. \param[out] none
  267. \retval none
  268. */
  269. void rtc_alarm_config(uint8_t rtc_alarm, rtc_alarm_struct* rtc_alarm_time)
  270. {
  271. uint32_t reg_alrmtd = 0U;
  272. reg_alrmtd =(rtc_alarm_time->alarm_mask | \
  273. rtc_alarm_time->weekday_or_date | \
  274. rtc_alarm_time->am_pm | \
  275. ALRMTD_DAY(rtc_alarm_time->alarm_day) | \
  276. ALRMTD_HR(rtc_alarm_time->alarm_hour) | \
  277. ALRMTD_MN(rtc_alarm_time->alarm_minute) | \
  278. ALRMTD_SC(rtc_alarm_time->alarm_second));
  279. /* disable the write protection */
  280. RTC_WPK = RTC_UNLOCK_KEY1;
  281. RTC_WPK = RTC_UNLOCK_KEY2;
  282. if(RTC_ALARM0 == rtc_alarm){
  283. RTC_ALRM0TD = (uint32_t)reg_alrmtd;
  284. }else{
  285. RTC_ALRM1TD = (uint32_t)reg_alrmtd;
  286. }
  287. /* enable the write protection */
  288. RTC_WPK = RTC_LOCK_KEY;
  289. }
  290. /*!
  291. \brief configure subsecond of RTC alarm
  292. \param[in] rtc_alarm: RTC_ALARM0 or RTC_ALARM1
  293. \param[in] mask_subsecond: alarm subsecond mask
  294. \arg RTC_MASKSSC_0_14: mask alarm subsecond configuration
  295. \arg RTC_MASKSSC_1_14: mask RTC_ALRMXSS_SSC[14:1], and RTC_ALRMXSS_SSC[0] is to be compared
  296. \arg RTC_MASKSSC_2_14: mask RTC_ALRMXSS_SSC[14:2], and RTC_ALRMXSS_SSC[1:0] is to be compared
  297. \arg RTC_MASKSSC_3_14: mask RTC_ALRMXSS_SSC[14:3], and RTC_ALRMXSS_SSC[2:0] is to be compared
  298. \arg RTC_MASKSSC_4_14: mask RTC_ALRMXSS_SSC[14:4]], and RTC_ALRMXSS_SSC[3:0] is to be compared
  299. \arg RTC_MASKSSC_5_14: mask RTC_ALRMXSS_SSC[14:5], and RTC_ALRMXSS_SSC[4:0] is to be compared
  300. \arg RTC_MASKSSC_6_14: mask RTC_ALRMXSS_SSC[14:6], and RTC_ALRMXSS_SSC[5:0] is to be compared
  301. \arg RTC_MASKSSC_7_14: mask RTC_ALRMXSS_SSC[14:7], and RTC_ALRMXSS_SSC[6:0] is to be compared
  302. \arg RTC_MASKSSC_8_14: mask RTC_ALRMXSS_SSC[14:8], and RTC_ALRMXSS_SSC[7:0] is to be compared
  303. \arg RTC_MASKSSC_9_14: mask RTC_ALRMXSS_SSC[14:9], and RTC_ALRMXSS_SSC[8:0] is to be compared
  304. \arg RTC_MASKSSC_10_14: mask RTC_ALRMXSS_SSC[14:10], and RTC_ALRMXSS_SSC[9:0] is to be compared
  305. \arg RTC_MASKSSC_11_14: mask RTC_ALRMXSS_SSC[14:11], and RTC_ALRMXSS_SSC[10:0] is to be compared
  306. \arg RTC_MASKSSC_12_14: mask RTC_ALRMXSS_SSC[14:12], and RTC_ALRMXSS_SSC[11:0] is to be compared
  307. \arg RTC_MASKSSC_13_14: mask RTC_ALRMXSS_SSC[14:13], and RTC_ALRMXSS_SSC[12:0] is to be compared
  308. \arg RTC_MASKSSC_14: mask RTC_ALRMXSS_SSC[14], and RTC_ALRMXSS_SSC[13:0] is to be compared
  309. \arg RTC_MASKSSC_NONE: mask none, and RTC_ALRMXSS_SSC[14:0] is to be compared
  310. \param[in] subsecond: alarm subsecond value(0x000 - 0x7FFF)
  311. \param[out] none
  312. \retval none
  313. */
  314. void rtc_alarm_subsecond_config(uint8_t rtc_alarm, uint32_t mask_subsecond, uint32_t subsecond)
  315. {
  316. /* disable the write protection */
  317. RTC_WPK = RTC_UNLOCK_KEY1;
  318. RTC_WPK = RTC_UNLOCK_KEY2;
  319. if(RTC_ALARM0 == rtc_alarm){
  320. RTC_ALRM0SS = mask_subsecond | subsecond;
  321. }else{
  322. RTC_ALRM1SS = mask_subsecond | subsecond;
  323. }
  324. /* enable the write protection */
  325. RTC_WPK = RTC_LOCK_KEY;
  326. }
  327. /*!
  328. \brief get RTC alarm
  329. \param[in] rtc_alarm: RTC_ALARM0 or RTC_ALARM1
  330. \param[out] rtc_alarm_time: pointer to a rtc_alarm_struct structure which contains
  331. parameters for RTC alarm configuration
  332. members of the structure and the member values are shown as below:
  333. alarm_mask: RTC_ALARM_NONE_MASK, RTC_ALARM_DATE_MASK, RTC_ALARM_HOUR_MASK
  334. RTC_ALARM_MINUTE_MASK, RTC_ALARM_SECOND_MASK, RTC_ALARM_ALL_MASK
  335. weekday_or_date: RTC_ALARM_DATE_SELECTED, RTC_ALARM_WEEKDAY_SELECTED
  336. alarm_day: 1) 0x1 - 0x31(BCD format) if RTC_ALARM_DATE_SELECTED is set
  337. 2) RTC_MONDAY, RTC_TUESDAY, RTC_WEDSDAY, RTC_THURSDAY, RTC_FRIDAY,
  338. RTC_SATURDAY, RTC_SUNDAY if RTC_ALARM_WEEKDAY_SELECTED is set
  339. alarm_hour: 0x0 - 0x12(BCD format) or 0x0 - 0x23(BCD format) depending on the rtc_display_format
  340. alarm_minute: 0x0 - 0x59(BCD format)
  341. alarm_second: 0x0 - 0x59(BCD format)
  342. am_pm: RTC_AM, RTC_PM
  343. \retval none
  344. */
  345. void rtc_alarm_get(uint8_t rtc_alarm, rtc_alarm_struct* rtc_alarm_time)
  346. {
  347. uint32_t reg_alrmtd = 0U;
  348. /* get the value of RTC_ALRM0TD register */
  349. if(RTC_ALARM0 == rtc_alarm){
  350. reg_alrmtd = RTC_ALRM0TD;
  351. }else{
  352. reg_alrmtd = RTC_ALRM1TD;
  353. }
  354. /* get alarm parameters and construct the rtc_alarm_struct structure */
  355. rtc_alarm_time->alarm_mask = reg_alrmtd & RTC_ALARM_ALL_MASK;
  356. rtc_alarm_time->am_pm = (uint32_t)(reg_alrmtd & RTC_ALRMXTD_PM);
  357. rtc_alarm_time->weekday_or_date = (uint32_t)(reg_alrmtd & RTC_ALRMXTD_DOWS);
  358. rtc_alarm_time->alarm_day = (uint8_t)GET_ALRMTD_DAY(reg_alrmtd);
  359. rtc_alarm_time->alarm_hour = (uint8_t)GET_ALRMTD_HR(reg_alrmtd);
  360. rtc_alarm_time->alarm_minute = (uint8_t)GET_ALRMTD_MN(reg_alrmtd);
  361. rtc_alarm_time->alarm_second = (uint8_t)GET_ALRMTD_SC(reg_alrmtd);
  362. }
  363. /*!
  364. \brief get RTC alarm subsecond
  365. \param[in] rtc_alarm: RTC_ALARM0 or RTC_ALARM1
  366. \param[out] none
  367. \retval RTC alarm subsecond value
  368. */
  369. uint32_t rtc_alarm_subsecond_get(uint8_t rtc_alarm)
  370. {
  371. if(RTC_ALARM0 == rtc_alarm){
  372. return ((uint32_t)(RTC_ALRM0SS & RTC_ALRM0SS_SSC));
  373. }else{
  374. return ((uint32_t)(RTC_ALRM1SS & RTC_ALRM1SS_SSC));
  375. }
  376. }
  377. /*!
  378. \brief enable RTC alarm
  379. \param[in] rtc_alarm: RTC_ALARM0 or RTC_ALARM1
  380. \param[out] none
  381. \retval none
  382. */
  383. void rtc_alarm_enable(uint8_t rtc_alarm)
  384. {
  385. /* disable the write protection */
  386. RTC_WPK = RTC_UNLOCK_KEY1;
  387. RTC_WPK = RTC_UNLOCK_KEY2;
  388. if(RTC_ALARM0 == rtc_alarm){
  389. RTC_CTL |= RTC_CTL_ALRM0EN;
  390. }else{
  391. RTC_CTL |= RTC_CTL_ALRM1EN;
  392. }
  393. /* enable the write protection */
  394. RTC_WPK = RTC_LOCK_KEY;
  395. }
  396. /*!
  397. \brief disable RTC alarm
  398. \param[in] rtc_alarm: RTC_ALARM0 or RTC_ALARM1
  399. \param[out] none
  400. \retval ErrStatus: ERROR or SUCCESS
  401. */
  402. ErrStatus rtc_alarm_disable(uint8_t rtc_alarm)
  403. {
  404. volatile uint32_t time_index = RTC_ALRMXWF_TIMEOUT;
  405. ErrStatus error_status = ERROR;
  406. uint32_t flag_status = RESET;
  407. /* disable the write protection */
  408. RTC_WPK = RTC_UNLOCK_KEY1;
  409. RTC_WPK = RTC_UNLOCK_KEY2;
  410. /* clear the state of alarm */
  411. if(RTC_ALARM0 == rtc_alarm){
  412. RTC_CTL &= (uint32_t)(~RTC_CTL_ALRM0EN);
  413. /* wait until ALRM0WF flag to be set after the alarm is disabled */
  414. do{
  415. flag_status = RTC_STAT & RTC_STAT_ALRM0WF;
  416. }while((--time_index > 0U) && ((uint32_t)RESET == flag_status));
  417. }else{
  418. RTC_CTL &= (uint32_t)(~RTC_CTL_ALRM1EN);
  419. /* wait until ALRM1WF flag to be set after the alarm is disabled */
  420. do{
  421. flag_status = RTC_STAT & RTC_STAT_ALRM1WF;
  422. }while((--time_index > 0U) && ((uint32_t)RESET == flag_status));
  423. }
  424. if ((uint32_t)RESET != flag_status){
  425. error_status = SUCCESS;
  426. }
  427. /* enable the write protection */
  428. RTC_WPK = RTC_LOCK_KEY;
  429. return error_status;
  430. }
  431. /*!
  432. \brief enable RTC time-stamp
  433. \param[in] edge: specify which edge to detect of time-stamp
  434. \arg RTC_TIMESTAMP_RISING_EDGE: rising edge is valid event edge for timestamp event
  435. \arg RTC_TIMESTAMP_FALLING_EDGE: falling edge is valid event edge for timestamp event
  436. \param[out] none
  437. \retval none
  438. */
  439. void rtc_timestamp_enable(uint32_t edge)
  440. {
  441. uint32_t reg_ctl = 0U;
  442. /* clear the bits to be configured in RTC_CTL */
  443. reg_ctl = (uint32_t)(RTC_CTL & (uint32_t)(~(RTC_CTL_TSEG | RTC_CTL_TSEN)));
  444. /* new configuration */
  445. reg_ctl |= (uint32_t)(edge | RTC_CTL_TSEN);
  446. /* disable the write protection */
  447. RTC_WPK = RTC_UNLOCK_KEY1;
  448. RTC_WPK = RTC_UNLOCK_KEY2;
  449. RTC_CTL = (uint32_t)reg_ctl;
  450. /* enable the write protection */
  451. RTC_WPK = RTC_LOCK_KEY;
  452. }
  453. /*!
  454. \brief disable RTC time-stamp
  455. \param[in] none
  456. \param[out] none
  457. \retval none
  458. */
  459. void rtc_timestamp_disable(void)
  460. {
  461. /* disable the write protection */
  462. RTC_WPK = RTC_UNLOCK_KEY1;
  463. RTC_WPK = RTC_UNLOCK_KEY2;
  464. /* clear the TSEN bit */
  465. RTC_CTL &= (uint32_t)(~ RTC_CTL_TSEN);
  466. /* enable the write protection */
  467. RTC_WPK = RTC_LOCK_KEY;
  468. }
  469. /*!
  470. \brief get RTC timestamp time and date
  471. \param[in] none
  472. \param[out] rtc_timestamp: pointer to a rtc_timestamp_struct structure which contains
  473. parameters for RTC time-stamp configuration
  474. members of the structure and the member values are shown as below:
  475. timestamp_month: RTC_JAN, RTC_FEB, RTC_MAR, RTC_APR, RTC_MAY, RTC_JUN,
  476. RTC_JUL, RTC_AUG, RTC_SEP, RTC_OCT, RTC_NOV, RTC_DEC
  477. timestamp_date: 0x1 - 0x31(BCD format)
  478. timestamp_day: RTC_MONDAY, RTC_TUESDAY, RTC_WEDSDAY, RTC_THURSDAY, RTC_FRIDAY,
  479. RTC_SATURDAY, RTC_SUNDAY if RTC_ALARM_WEEKDAY_SELECTED is set
  480. timestamp_hour: 0x0 - 0x12(BCD format) or 0x0 - 0x23(BCD format) depending on the rtc_display_format
  481. timestamp_minute: 0x0 - 0x59(BCD format)
  482. timestamp_second: 0x0 - 0x59(BCD format)
  483. am_pm: RTC_AM, RTC_PM
  484. \retval none
  485. */
  486. void rtc_timestamp_get(rtc_timestamp_struct* rtc_timestamp)
  487. {
  488. uint32_t temp_tts = 0U, temp_dts = 0U;
  489. /* get the value of time_stamp registers */
  490. temp_tts = (uint32_t)RTC_TTS;
  491. temp_dts = (uint32_t)RTC_DTS;
  492. /* get timestamp time and construct the rtc_timestamp_struct structure */
  493. rtc_timestamp->am_pm = (uint32_t)(temp_tts & RTC_TTS_PM);
  494. rtc_timestamp->timestamp_month = (uint8_t)GET_DTS_MON(temp_dts);
  495. rtc_timestamp->timestamp_date = (uint8_t)GET_DTS_DAY(temp_dts);
  496. rtc_timestamp->timestamp_day = (uint8_t)GET_DTS_DOW(temp_dts);
  497. rtc_timestamp->timestamp_hour = (uint8_t)GET_TTS_HR(temp_tts);
  498. rtc_timestamp->timestamp_minute = (uint8_t)GET_TTS_MN(temp_tts);
  499. rtc_timestamp->timestamp_second = (uint8_t)GET_TTS_SC(temp_tts);
  500. }
  501. /*!
  502. \brief get RTC time-stamp subsecond
  503. \param[in] none
  504. \param[out] none
  505. \retval RTC time-stamp subsecond value
  506. */
  507. uint32_t rtc_timestamp_subsecond_get(void)
  508. {
  509. return ((uint32_t)RTC_SSTS);
  510. }
  511. /*!
  512. \brief RTC time-stamp mapping
  513. \param[in] rtc_af:
  514. \arg RTC_AF0_TIMESTAMP: RTC_AF0 use for timestamp
  515. \arg RTC_AF1_TIMESTAMP: RTC_AF1 use for timestamp
  516. \param[out] none
  517. \retval none
  518. */
  519. void rtc_timestamp_pin_map(uint32_t rtc_af)
  520. {
  521. RTC_TAMP &= ~RTC_TAMP_TSSEL;
  522. RTC_TAMP |= rtc_af;
  523. }
  524. /*!
  525. \brief enable RTC tamper
  526. \param[in] rtc_tamper: pointer to a rtc_tamper_struct structure which contains
  527. parameters for RTC tamper configuration
  528. members of the structure and the member values are shown as below:
  529. tamper_source: RTC_TAMPER0, RTC_TAMPER1
  530. tamper_trigger: RTC_TAMPER_TRIGGER_EDGE_RISING, RTC_TAMPER_TRIGGER_EDGE_FALLING
  531. RTC_TAMPER_TRIGGER_LEVEL_LOW, RTC_TAMPER_TRIGGER_LEVEL_HIGH
  532. tamper_filter: RTC_FLT_EDGE, RTC_FLT_2S, RTC_FLT_4S, RTC_FLT_8S
  533. tamper_sample_frequency: RTC_FREQ_DIV32768, RTC_FREQ_DIV16384, RTC_FREQ_DIV8192,
  534. RTC_FREQ_DIV4096, RTC_FREQ_DIV2048, RTC_FREQ_DIV1024,
  535. RTC_FREQ_DIV512, RTC_FREQ_DIV256
  536. tamper_precharge_enable: DISABLE, ENABLE
  537. tamper_precharge_time: RTC_PRCH_1C, RTC_PRCH_2C, RTC_PRCH_4C, RTC_PRCH_8C
  538. tamper_with_timestamp: DISABLE, ENABLE
  539. \param[out] none
  540. \retval none
  541. */
  542. void rtc_tamper_enable(rtc_tamper_struct* rtc_tamper)
  543. {
  544. /* disable tamper */
  545. RTC_TAMP &= (uint32_t)~(rtc_tamper->tamper_source);
  546. /* tamper filter must be used when the tamper source is voltage level detection */
  547. RTC_TAMP &= (uint32_t)~RTC_TAMP_FLT;
  548. /* the tamper source is voltage level detection */
  549. if((uint32_t)(rtc_tamper->tamper_filter) != RTC_FLT_EDGE ){
  550. RTC_TAMP &= (uint32_t)~(RTC_TAMP_DISPU | RTC_TAMP_PRCH | RTC_TAMP_FREQ | RTC_TAMP_FLT);
  551. /* check if the tamper pin need precharge, if need, then configure the precharge time */
  552. if(DISABLE == rtc_tamper->tamper_precharge_enable){
  553. RTC_TAMP |= (uint32_t)RTC_TAMP_DISPU;
  554. }else{
  555. RTC_TAMP |= (uint32_t)(rtc_tamper->tamper_precharge_time);
  556. }
  557. RTC_TAMP |= (uint32_t)(rtc_tamper->tamper_sample_frequency);
  558. RTC_TAMP |= (uint32_t)(rtc_tamper->tamper_filter);
  559. }
  560. RTC_TAMP &= (uint32_t)~RTC_TAMP_TPTS;
  561. if(DISABLE != rtc_tamper->tamper_with_timestamp){
  562. /* the tamper event also cause a time-stamp event */
  563. RTC_TAMP |= (uint32_t)RTC_TAMP_TPTS;
  564. }
  565. /* configure the tamper trigger */
  566. RTC_TAMP &= ((uint32_t)~((rtc_tamper->tamper_source) << RTC_TAMPER_TRIGGER_POS));
  567. if(RTC_TAMPER_TRIGGER_EDGE_RISING != rtc_tamper->tamper_trigger){
  568. RTC_TAMP |= (uint32_t)((rtc_tamper->tamper_source)<< RTC_TAMPER_TRIGGER_POS);
  569. }
  570. /* enable tamper */
  571. RTC_TAMP |= (uint32_t)(rtc_tamper->tamper_source);
  572. }
  573. /*!
  574. \brief disable RTC tamper
  575. \param[in] source: specify which tamper source to be disabled
  576. \arg RTC_TAMPER0
  577. \arg RTC_TAMPER1
  578. \param[out] none
  579. \retval none
  580. */
  581. void rtc_tamper_disable(uint32_t source)
  582. {
  583. /* disable tamper */
  584. RTC_TAMP &= (uint32_t)~source;
  585. }
  586. /*!
  587. \brief RTC tamper0 mapping
  588. \param[in] rtc_af:
  589. \arg RTC_AF0_TAMPER0: RTC_AF0 use for tamper0
  590. \arg RTC_AF1_TAMPER0: RTC_AF1 use for tamper0
  591. \param[out] none
  592. \retval none
  593. */
  594. void rtc_tamper0_pin_map(uint32_t rtc_af)
  595. {
  596. RTC_TAMP &= ~(RTC_TAMP_TP0EN | RTC_TAMP_TP0SEL);
  597. RTC_TAMP |= rtc_af;
  598. }
  599. /*!
  600. \brief enable specified RTC interrupt
  601. \param[in] interrupt: specify which interrupt source to be enabled
  602. \arg RTC_INT_TIMESTAMP: timestamp interrupt
  603. \arg RTC_INT_ALARM0: alarm0 interrupt
  604. \arg RTC_INT_ALARM1: alarm1 interrupt
  605. \arg RTC_INT_TAMP: tamp interrupt
  606. \arg RTC_INT_WAKEUP: wakeup timer interrupt
  607. \param[out] none
  608. \retval none
  609. */
  610. void rtc_interrupt_enable(uint32_t interrupt)
  611. {
  612. /* disable the write protection */
  613. RTC_WPK = RTC_UNLOCK_KEY1;
  614. RTC_WPK = RTC_UNLOCK_KEY2;
  615. /* enable the interrupts in RTC_CTL register */
  616. RTC_CTL |= (uint32_t)(interrupt & (uint32_t)~RTC_TAMP_TPIE);
  617. /* enable the interrupts in RTC_TAMP register */
  618. RTC_TAMP |= (uint32_t)(interrupt & RTC_TAMP_TPIE);
  619. /* enable the write protection */
  620. RTC_WPK = RTC_LOCK_KEY;
  621. }
  622. /*!
  623. \brief disble specified RTC interrupt
  624. \param[in] interrupt: specify which interrupt source to be disabled
  625. \arg RTC_INT_TIMESTAMP: timestamp interrupt
  626. \arg RTC_INT_ALARM0: alarm interrupt
  627. \arg RTC_INT_ALARM1: alarm interrupt
  628. \arg RTC_INT_TAMP: tamp interrupt
  629. \arg RTC_INT_WAKEUP: wakeup timer interrupt
  630. \param[out] none
  631. \retval none
  632. */
  633. void rtc_interrupt_disable(uint32_t interrupt)
  634. {
  635. /* disable the write protection */
  636. RTC_WPK = RTC_UNLOCK_KEY1;
  637. RTC_WPK = RTC_UNLOCK_KEY2;
  638. /* disable the interrupts in RTC_CTL register */
  639. RTC_CTL &= (uint32_t)~(interrupt & (uint32_t)~RTC_TAMP_TPIE);
  640. /* disable the interrupts in RTC_TAMP register */
  641. RTC_TAMP &= (uint32_t)~(interrupt & RTC_TAMP_TPIE);
  642. /* enable the write protection */
  643. RTC_WPK = RTC_LOCK_KEY;
  644. }
  645. /*!
  646. \brief check specified flag
  647. \param[in] flag: specify which flag to check
  648. \arg RTC_STAT_RECPF: recalibration pending flag
  649. \arg RTC_STAT_TP1F: tamper 1 event flag
  650. \arg RTC_STAT_TP0F: tamper 0 event flag
  651. \arg RTC_STAT_TSOVRF: time-stamp overflow event flag
  652. \arg RTC_STAT_TSF: time-stamp event flag
  653. \arg RTC_STAT_ALRM0F: alarm0 event flag
  654. \arg RTC_STAT_ALRM1F: alarm1 event flag
  655. \arg RTC_STAT_WTF: wakeup timer event flag
  656. \arg RTC_STAT_INITF: init mode event flag
  657. \arg RTC_STAT_RSYNF: time and date registers synchronized event flag
  658. \arg RTC_STAT_YCM: year parameter configured event flag
  659. \arg RTC_STAT_SOPF: shift operation pending flag
  660. \arg RTC_STAT_ALRM0WF: alarm0 writen available flag
  661. \arg RTC_STAT_ALRM1WF: alarm1 writen available flag
  662. \arg RTC_STAT_WTWF: wakeup timer writen available flag
  663. \param[out] none
  664. \retval FlagStatus: SET or RESET
  665. */
  666. FlagStatus rtc_flag_get(uint32_t flag)
  667. {
  668. FlagStatus flag_state = RESET;
  669. if ((uint32_t)RESET != (RTC_STAT & flag)){
  670. flag_state = SET;
  671. }
  672. return flag_state;
  673. }
  674. /*!
  675. \brief clear specified flag
  676. \param[in] flag: specify which flag to clear
  677. \arg RTC_STAT_TP1F: tamper 1 event flag
  678. \arg RTC_STAT_TP0F: tamper 0 event flag
  679. \arg RTC_STAT_TSOVRF: time-stamp overflow event flag
  680. \arg RTC_STAT_TSF: time-stamp event flag
  681. \arg RTC_STAT_WTF: time-stamp event flag
  682. \arg RTC_STAT_ALRM0F: alarm0 event flag
  683. \arg RTC_STAT_ALRM1F: alarm1 event flag
  684. \arg RTC_STAT_RSYNF: time and date registers synchronized event flag
  685. \param[out] none
  686. \retval none
  687. */
  688. void rtc_flag_clear(uint32_t flag)
  689. {
  690. RTC_STAT &= (uint32_t)(~flag);
  691. }
  692. /*!
  693. \brief configure rtc alarm output source
  694. \param[in] source: specify signal to output
  695. \arg RTC_ALARM0_HIGH: when the alarm0 flag is set, the output pin is high
  696. \arg RTC_ALARM0_LOW: when the alarm0 flag is set, the output pin is low
  697. \arg RTC_ALARM1_HIGH: when the alarm1 flag is set, the output pin is high
  698. \arg RTC_ALARM1_LOW: when the alarm1 flag is set, the output pin is low
  699. \arg RTC_WAKEUP_HIGH: when the wakeup flag is set, the output pin is high
  700. \arg RTC_WAKEUP_LOW: when the wakeup flag is set, the output pin is low
  701. \param[in] mode: specify the output pin mode when output alarm signal
  702. \arg RTC_ALARM_OUTPUT_OD: open drain mode
  703. \arg RTC_ALARM_OUTPUT_PP: push pull mode
  704. \param[out] none
  705. \retval none
  706. */
  707. void rtc_alarm_output_config(uint32_t source, uint32_t mode)
  708. {
  709. /* disable the write protection */
  710. RTC_WPK = RTC_UNLOCK_KEY1;
  711. RTC_WPK = RTC_UNLOCK_KEY2;
  712. RTC_CTL &= ~(RTC_CTL_OS | RTC_CTL_OPOL);
  713. RTC_TAMP &= ~RTC_TAMP_AOT;
  714. RTC_CTL |= (uint32_t)(source);
  715. /* alarm output */
  716. RTC_TAMP |= (uint32_t)(mode);
  717. /* enable the write protection */
  718. RTC_WPK = RTC_LOCK_KEY;
  719. }
  720. /*!
  721. \brief configure rtc calibration output source
  722. \param[in] source: specify signal to output
  723. \arg RTC_CALIBRATION_512HZ: when the LSE freqency is 32768Hz and the RTC_PSC
  724. is the default value, output 512Hz signal
  725. \arg RTC_CALIBRATION_1HZ: when the LSE freqency is 32768Hz and the RTC_PSC
  726. is the default value, output 512Hz signal
  727. \param[out] none
  728. \retval none
  729. */
  730. void rtc_calibration_output_config(uint32_t source)
  731. {
  732. /* disable the write protection */
  733. RTC_WPK = RTC_UNLOCK_KEY1;
  734. RTC_WPK = RTC_UNLOCK_KEY2;
  735. RTC_CTL &= (uint32_t)~(RTC_CTL_COEN | RTC_CTL_COS);
  736. RTC_CTL |= (uint32_t)(source);
  737. /* enable the write protection */
  738. RTC_WPK = RTC_LOCK_KEY;
  739. }
  740. /*!
  741. \brief adjust the daylight saving time by adding or substracting one hour from the current time
  742. \param[in] operation: hour adjustment operation
  743. \arg RTC_CTL_A1H: add one hour
  744. \arg RTC_CTL_S1H: substract one hour
  745. \param[out] none
  746. \retval none
  747. */
  748. void rtc_hour_adjust(uint32_t operation)
  749. {
  750. /* disable the write protection */
  751. RTC_WPK = RTC_UNLOCK_KEY1;
  752. RTC_WPK = RTC_UNLOCK_KEY2;
  753. RTC_CTL |= (uint32_t)(operation);
  754. /* enable the write protection */
  755. RTC_WPK = RTC_LOCK_KEY;
  756. }
  757. /*!
  758. \brief adjust RTC second or subsecond value of current time
  759. \param[in] add: add 1s to current time or not
  760. \arg RTC_SHIFT_ADD1S_RESET: no effect
  761. \arg RTC_SHIFT_ADD1S_SET: add 1s to current time
  762. \param[in] minus: number of subsecond to minus from current time(0x0 - 0x7FFF)
  763. \param[out] none
  764. \retval ErrStatus: ERROR or SUCCESS
  765. */
  766. ErrStatus rtc_second_adjust(uint32_t add, uint32_t minus)
  767. {
  768. volatile uint32_t time_index = RTC_SHIFTCTL_TIMEOUT;
  769. ErrStatus error_status = ERROR;
  770. uint32_t flag_status = RESET;
  771. uint32_t temp=0U;
  772. /* disable the write protection */
  773. RTC_WPK = RTC_UNLOCK_KEY1;
  774. RTC_WPK = RTC_UNLOCK_KEY2;
  775. /* check if a shift operation is ongoing */
  776. do{
  777. flag_status = RTC_STAT & RTC_STAT_SOPF;
  778. }while((--time_index > 0U) && ((uint32_t)RESET != flag_status));
  779. /* check if the function of reference clock detection is disabled */
  780. temp = RTC_CTL & RTC_CTL_REFEN;
  781. if((RESET == flag_status) && (RESET == temp)){
  782. RTC_SHIFTCTL = (uint32_t)(add | SHIFTCTL_SFS(minus));
  783. error_status = rtc_register_sync_wait();
  784. }
  785. /* enable the write protection */
  786. RTC_WPK = RTC_LOCK_KEY;
  787. return error_status;
  788. }
  789. /*!
  790. \brief enable RTC bypass shadow registers function
  791. \param[in] none
  792. \param[out] none
  793. \retval none
  794. */
  795. void rtc_bypass_shadow_enable(void)
  796. {
  797. /* disable the write protection */
  798. RTC_WPK = RTC_UNLOCK_KEY1;
  799. RTC_WPK = RTC_UNLOCK_KEY2;
  800. RTC_CTL |= RTC_CTL_BPSHAD;
  801. /* enable the write protection */
  802. RTC_WPK = RTC_LOCK_KEY;
  803. }
  804. /*!
  805. \brief disable RTC bypass shadow registers function
  806. \param[in] none
  807. \param[out] none
  808. \retval none
  809. */
  810. void rtc_bypass_shadow_disable(void)
  811. {
  812. /* disable the write protection */
  813. RTC_WPK = RTC_UNLOCK_KEY1;
  814. RTC_WPK = RTC_UNLOCK_KEY2;
  815. RTC_CTL &= ~RTC_CTL_BPSHAD;
  816. /* enable the write protection */
  817. RTC_WPK = RTC_LOCK_KEY;
  818. }
  819. /*!
  820. \brief enable RTC reference clock detection function
  821. \param[in] none
  822. \param[out] none
  823. \retval ErrStatus: ERROR or SUCCESS
  824. */
  825. ErrStatus rtc_refclock_detection_enable(void)
  826. {
  827. ErrStatus error_status = ERROR;
  828. /* disable the write protection */
  829. RTC_WPK = RTC_UNLOCK_KEY1;
  830. RTC_WPK = RTC_UNLOCK_KEY2;
  831. /* enter init mode */
  832. error_status = rtc_init_mode_enter();
  833. if(ERROR != error_status){
  834. RTC_CTL |= (uint32_t)RTC_CTL_REFEN;
  835. /* exit init mode */
  836. rtc_init_mode_exit();
  837. }
  838. /* enable the write protection */
  839. RTC_WPK = RTC_LOCK_KEY;
  840. return error_status;
  841. }
  842. /*!
  843. \brief disable RTC reference clock detection function
  844. \param[in] none
  845. \param[out] none
  846. \retval ErrStatus: ERROR or SUCCESS
  847. */
  848. ErrStatus rtc_refclock_detection_disable(void)
  849. {
  850. ErrStatus error_status = ERROR;
  851. /* disable the write protection */
  852. RTC_WPK = RTC_UNLOCK_KEY1;
  853. RTC_WPK = RTC_UNLOCK_KEY2;
  854. /* enter init mode */
  855. error_status = rtc_init_mode_enter();
  856. if(ERROR != error_status){
  857. RTC_CTL &= (uint32_t)~RTC_CTL_REFEN;
  858. /* exit init mode */
  859. rtc_init_mode_exit();
  860. }
  861. /* enable the write protection */
  862. RTC_WPK = RTC_LOCK_KEY;
  863. return error_status;
  864. }
  865. /*!
  866. \brief enable RTC auto wakeup function
  867. \param[in] none
  868. \param[out] none
  869. \retval none
  870. */
  871. void rtc_wakeup_enable(void)
  872. {
  873. /* disable the write protection */
  874. RTC_WPK = RTC_UNLOCK_KEY1;
  875. RTC_WPK = RTC_UNLOCK_KEY2;
  876. RTC_CTL |= RTC_CTL_WTEN;
  877. /* enable the write protection */
  878. RTC_WPK = RTC_LOCK_KEY;
  879. }
  880. /*!
  881. \brief disable RTC auto wakeup function
  882. \param[in] none
  883. \param[out] none
  884. \retval ErrStatus: ERROR or SUCCESS
  885. */
  886. ErrStatus rtc_wakeup_disable(void)
  887. {
  888. ErrStatus error_status = ERROR;
  889. volatile uint32_t time_index = RTC_WTWF_TIMEOUT;
  890. uint32_t flag_status = RESET;
  891. /* disable the write protection */
  892. RTC_WPK = RTC_UNLOCK_KEY1;
  893. RTC_WPK = RTC_UNLOCK_KEY2;
  894. RTC_CTL &= ~RTC_CTL_WTEN;
  895. /* wait until the WTWF flag to be set */
  896. do{
  897. flag_status = RTC_STAT & RTC_STAT_WTWF;
  898. }while((--time_index > 0U) && ((uint32_t)RESET == flag_status));
  899. if ((uint32_t)RESET == flag_status){
  900. error_status = ERROR;
  901. }else{
  902. error_status = SUCCESS;
  903. }
  904. /* enable the write protection */
  905. RTC_WPK = RTC_LOCK_KEY;
  906. return error_status;
  907. }
  908. /*!
  909. \brief set RTC auto wakeup timer clock
  910. \param[in] wakeup_clock:
  911. \arg WAKEUP_RTCCK_DIV16: RTC auto wakeup timer clock is RTC clock divided by 16
  912. \arg WAKEUP_RTCCK_DIV8: RTC auto wakeup timer clock is RTC clock divided by 8
  913. \arg WAKEUP_RTCCK_DIV4: RTC auto wakeup timer clock is RTC clock divided by 4
  914. \arg WAKEUP_RTCCK_DIV2: RTC auto wakeup timer clock is RTC clock divided by 2
  915. \arg WAKEUP_CKSPRE: RTC auto wakeup timer clock is ckspre
  916. \arg WAKEUP_CKSPRE_2EXP16: RTC auto wakeup timer clock is ckspre and wakeup timer add 2exp16
  917. \param[out] none
  918. \retval ErrStatus: ERROR or SUCCESS
  919. */
  920. ErrStatus rtc_wakeup_clock_set(uint8_t wakeup_clock)
  921. {
  922. ErrStatus error_status = ERROR;
  923. volatile uint32_t time_index = RTC_WTWF_TIMEOUT;
  924. uint32_t flag_status = RESET;
  925. /* disable the write protection */
  926. RTC_WPK = RTC_UNLOCK_KEY1;
  927. RTC_WPK = RTC_UNLOCK_KEY2;
  928. /* only when RTC_CTL_WTEN=0 and RTC_STAT_WTWF=1 can write RTC_CTL[2£º0] */
  929. /* wait until the WTWF flag to be set */
  930. do{
  931. flag_status = RTC_STAT & RTC_STAT_WTWF;
  932. }while((--time_index > 0U) && ((uint32_t)RESET == flag_status));
  933. if ((uint32_t)RESET == flag_status){
  934. error_status = ERROR;
  935. }else{
  936. RTC_CTL &= (uint32_t)~ RTC_CTL_WTCS;
  937. RTC_CTL |= (uint32_t)wakeup_clock;
  938. error_status = SUCCESS;
  939. }
  940. /* enable the write protection */
  941. RTC_WPK = RTC_LOCK_KEY;
  942. return error_status;
  943. }
  944. /*!
  945. \brief set wakeup timer value
  946. \param[in] wakeup_timer: 0x0000-0xffff
  947. \param[out] none
  948. \retval ErrStatus: ERROR or SUCCESS
  949. */
  950. ErrStatus rtc_wakeup_timer_set(uint16_t wakeup_timer)
  951. {
  952. ErrStatus error_status = ERROR;
  953. volatile uint32_t time_index = RTC_WTWF_TIMEOUT;
  954. uint32_t flag_status = RESET;
  955. /* disable the write protection */
  956. RTC_WPK = RTC_UNLOCK_KEY1;
  957. RTC_WPK = RTC_UNLOCK_KEY2;
  958. /* wait until the WTWF flag to be set */
  959. do{
  960. flag_status = RTC_STAT & RTC_STAT_WTWF;
  961. }while((--time_index > 0U) && ((uint32_t)RESET == flag_status));
  962. if ((uint32_t)RESET == flag_status){
  963. error_status = ERROR;
  964. }else{
  965. RTC_WUT = (uint32_t)wakeup_timer;
  966. error_status = SUCCESS;
  967. }
  968. /* enable the write protection */
  969. RTC_WPK = RTC_LOCK_KEY;
  970. return error_status;
  971. }
  972. /*!
  973. \brief get wakeup timer value
  974. \param[in] none
  975. \param[out] none
  976. \retval wakeup timer value
  977. */
  978. uint16_t rtc_wakeup_timer_get(void)
  979. {
  980. return (uint16_t)RTC_WUT;
  981. }
  982. /*!
  983. \brief configure RTC smooth calibration
  984. \param[in] window: select calibration window
  985. \arg RTC_CALIBRATION_WINDOW_32S: 2exp20 RTCCLK cycles, 32s if RTCCLK = 32768 Hz
  986. \arg RTC_CALIBRATION_WINDOW_16S: 2exp19 RTCCLK cycles, 16s if RTCCLK = 32768 Hz
  987. \arg RTC_CALIBRATION_WINDOW_8S: 2exp18 RTCCLK cycles, 8s if RTCCLK = 32768 Hz
  988. \param[in] plus: add RTC clock or not
  989. \arg RTC_CALIBRATION_PLUS_SET: add one RTC clock every 2048 rtc clock
  990. \arg RTC_CALIBRATION_PLUS_RESET: no effect
  991. \param[in] minus: the RTC clock to minus during the calibration window(0x0 - 0x1FF)
  992. \param[out] none
  993. \retval ErrStatus: ERROR or SUCCESS
  994. */
  995. ErrStatus rtc_smooth_calibration_config(uint32_t window, uint32_t plus, uint32_t minus)
  996. {
  997. volatile uint32_t time_index = RTC_HRFC_TIMEOUT;
  998. ErrStatus error_status = ERROR;
  999. uint32_t flag_status = RESET;
  1000. /* disable the write protection */
  1001. RTC_WPK = RTC_UNLOCK_KEY1;
  1002. RTC_WPK = RTC_UNLOCK_KEY2;
  1003. /* check if a smooth calibration operation is ongoing */
  1004. do{
  1005. flag_status = RTC_STAT & RTC_STAT_SCPF;
  1006. }while((--time_index > 0U) && ((uint32_t)RESET != flag_status));
  1007. if((uint32_t)RESET == flag_status){
  1008. RTC_HRFC = (uint32_t)(window | plus | HRFC_CMSK(minus));
  1009. error_status = SUCCESS;
  1010. }
  1011. /* enable the write protection */
  1012. RTC_WPK = RTC_LOCK_KEY;
  1013. return error_status;
  1014. }
  1015. /*!
  1016. \brief enable RTC coarse calibration
  1017. \param[in] none
  1018. \param[out] none
  1019. \retval ErrStatus: ERROR or SUCCESS
  1020. */
  1021. ErrStatus rtc_coarse_calibration_enable(void)
  1022. {
  1023. ErrStatus error_status = ERROR;
  1024. /* disable the write protection */
  1025. RTC_WPK = RTC_UNLOCK_KEY1;
  1026. RTC_WPK = RTC_UNLOCK_KEY2;
  1027. /* enter init mode */
  1028. error_status = rtc_init_mode_enter();
  1029. if(ERROR != error_status){
  1030. RTC_CTL |= (uint32_t)RTC_CTL_CCEN;
  1031. /* exit init mode */
  1032. rtc_init_mode_exit();
  1033. }
  1034. /* enable the write protection */
  1035. RTC_WPK = RTC_LOCK_KEY;
  1036. return error_status;
  1037. }
  1038. /*!
  1039. \brief disable RTC coarse calibration
  1040. \param[in] none
  1041. \param[out] none
  1042. \retval ErrStatus: ERROR or SUCCESS
  1043. */
  1044. ErrStatus rtc_coarse_calibration_disable(void)
  1045. {
  1046. ErrStatus error_status = ERROR;
  1047. /* disable the write protection */
  1048. RTC_WPK = RTC_UNLOCK_KEY1;
  1049. RTC_WPK = RTC_UNLOCK_KEY2;
  1050. /* enter init mode */
  1051. error_status = rtc_init_mode_enter();
  1052. if(ERROR != error_status){
  1053. RTC_CTL &= (uint32_t)~RTC_CTL_CCEN;
  1054. /* exit init mode */
  1055. rtc_init_mode_exit();
  1056. }
  1057. /* enable the write protection */
  1058. RTC_WPK = RTC_LOCK_KEY;
  1059. return error_status;
  1060. }
  1061. /*!
  1062. \brief config coarse calibration direction and step
  1063. \param[in] direction: CALIB_INCREASE or CALIB_DECREASE
  1064. \param[in] step: 0x00-0x1F
  1065. COSD=0:
  1066. 0x00:+0 PPM
  1067. 0x01:+4 PPM
  1068. 0x02:+8 PPM
  1069. ....
  1070. 0x1F:+126 PPM
  1071. COSD=1:
  1072. 0x00:-0 PPM
  1073. 0x01:-2 PPM
  1074. 0x02:-4 PPM
  1075. ....
  1076. 0x1F:-63 PPM
  1077. \param[out] none
  1078. \retval ErrStatus: ERROR or SUCCESS
  1079. */
  1080. ErrStatus rtc_coarse_calibration_config(uint8_t direction, uint8_t step)
  1081. {
  1082. ErrStatus error_status = ERROR;
  1083. /* disable the write protection */
  1084. RTC_WPK = RTC_UNLOCK_KEY1;
  1085. RTC_WPK = RTC_UNLOCK_KEY2;
  1086. /* enter init mode */
  1087. error_status = rtc_init_mode_enter();
  1088. if(ERROR != error_status){
  1089. if(CALIB_DECREASE == direction){
  1090. RTC_COSC |= (uint32_t)RTC_COSC_COSD;
  1091. }else{
  1092. RTC_COSC &= (uint32_t)~RTC_COSC_COSD;
  1093. }
  1094. RTC_COSC &= ~RTC_COSC_COSS;
  1095. RTC_COSC |= (uint32_t)((uint32_t)step & 0x1FU);
  1096. /* exit init mode */
  1097. rtc_init_mode_exit();
  1098. }
  1099. /* enable the write protection */
  1100. RTC_WPK = RTC_LOCK_KEY;
  1101. return error_status;
  1102. }