gd32f3x0_rtc.c 32 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927
  1. /*!
  2. \file gd32f3x0_rtc.c
  3. \brief RTC driver
  4. */
  5. /*
  6. Copyright (C) 2017 GigaDevice
  7. 2017-06-06, V1.0.0, firmware for GD32F3x0
  8. */
  9. #include "gd32f3x0_rtc.h"
  10. /*!
  11. \brief reset most of the RTC registers
  12. \param[in] none
  13. \param[out] none
  14. \retval ErrStatus: ERROR or SUCCESS
  15. */
  16. ErrStatus rtc_deinit(void)
  17. {
  18. ErrStatus error_status = ERROR;
  19. /* RTC_TAMP register is not under write protection */
  20. RTC_TAMP = RTC_REGISTER_RESET;
  21. /* disable the write protection */
  22. RTC_WPK = RTC_UNLOCK_KEY1;
  23. RTC_WPK = RTC_UNLOCK_KEY2;
  24. /* reset RTC_CTL register, this can be done without the init mode */
  25. RTC_CTL &= RTC_REGISTER_RESET;
  26. /* enter init mode */
  27. error_status = rtc_init_mode_enter();
  28. if(ERROR != error_status){
  29. /* before reset RTC_TIME and RTC_DATE, BPSHAD bit in RTC_CTL should be reset as the condition.
  30. in order to read calendar from shadow register, not the real registers being reset */
  31. RTC_TIME = RTC_REGISTER_RESET;
  32. RTC_DATE = RTC_DATE_RESET;
  33. RTC_PSC = RTC_PSC_RESET;
  34. /* reset RTC_STAT register, also exit init mode.
  35. at the same time, RTC_STAT_SOPF bit is reset, as the condition to reset RTC_SHIFTCTL register later */
  36. RTC_STAT = RTC_STAT_RESET;
  37. /* to write RTC_ALRM0SS register, ALRM0EN bit in RTC_CTL register should be reset as the condition */
  38. RTC_ALRM0TD = RTC_REGISTER_RESET;
  39. RTC_ALRM0SS = RTC_REGISTER_RESET;
  40. /* reset RTC_SHIFTCTL and RTC_HRFC register, this can be done without the init mode */
  41. RTC_SHIFTCTL = RTC_REGISTER_RESET;
  42. RTC_HRFC = RTC_REGISTER_RESET;
  43. error_status = rtc_register_sync_wait();
  44. }
  45. /* enable the write protection */
  46. RTC_WPK = RTC_LOCK_KEY;
  47. return error_status;
  48. }
  49. /*!
  50. \brief initialize RTC registers
  51. \param[in] rtc_initpara_struct: pointer to a rtc_parameter_struct structure which contains
  52. parameters for initialization of the rtc peripheral
  53. members of the structure and the member values are shown as below:
  54. rtc_year: 0x0 - 0x99(BCD format)
  55. rtc_month: RTC_JAN, RTC_FEB, RTC_MAR, RTC_APR, RTC_MAY, RTC_JUN,
  56. RTC_JUL, RTC_AUG, RTC_SEP, RTC_OCT, RTC_NOV, RTC_DEC
  57. rtc_date: 0x1 - 0x31(BCD format)
  58. rtc_day_of_week: RTC_MONDAY, RTC_TUESDAY, RTC_WEDSDAY, RTC_THURSDAY
  59. RTC_FRIDAY, RTC_SATURDAY, RTC_SUNDAY
  60. rtc_hour: 0x0 - 0x12(BCD format) or 0x0 - 0x23(BCD format) depending on the rtc_display_format chose
  61. rtc_minute: 0x0 - 0x59(BCD format)
  62. rtc_second: 0x0 - 0x59(BCD format)
  63. rtc_factor_asyn: 0x0 - 0x7F
  64. rtc_factor_syn: 0x0 - 0x7FFF
  65. rtc_am_pm: RTC_AM, RTC_PM
  66. rtc_display_format: RTC_24HOUR, RTC_12HOUR
  67. \param[out] none
  68. \retval ErrStatus: ERROR or SUCCESS
  69. */
  70. ErrStatus rtc_init(rtc_parameter_struct* rtc_initpara_struct)
  71. {
  72. ErrStatus error_status = ERROR;
  73. uint32_t reg_time = 0x00U, reg_date = 0x00U;
  74. reg_date = (DATE_YR(rtc_initpara_struct->rtc_year) | \
  75. DATE_DOW(rtc_initpara_struct->rtc_day_of_week) | \
  76. DATE_MON(rtc_initpara_struct->rtc_month) | \
  77. DATE_DAY(rtc_initpara_struct->rtc_date));
  78. reg_time = (rtc_initpara_struct->rtc_am_pm| \
  79. TIME_HR(rtc_initpara_struct->rtc_hour) | \
  80. TIME_MN(rtc_initpara_struct->rtc_minute) | \
  81. TIME_SC(rtc_initpara_struct->rtc_second));
  82. /* 1st: disable the write protection */
  83. RTC_WPK = RTC_UNLOCK_KEY1;
  84. RTC_WPK = RTC_UNLOCK_KEY2;
  85. /* 2nd: enter init mode */
  86. error_status = rtc_init_mode_enter();
  87. if(ERROR != error_status){
  88. RTC_PSC = (uint32_t)(PSC_FACTOR_A(rtc_initpara_struct->rtc_factor_asyn)| \
  89. PSC_FACTOR_S(rtc_initpara_struct->rtc_factor_syn));
  90. RTC_TIME = (uint32_t)reg_time;
  91. RTC_DATE = (uint32_t)reg_date;
  92. RTC_CTL &= (uint32_t)(~RTC_CTL_CS);
  93. RTC_CTL |= rtc_initpara_struct->rtc_display_format;
  94. /* 3rd: exit init mode */
  95. rtc_init_mode_exit();
  96. /* 4th: wait the RSYNF flag to set */
  97. error_status = rtc_register_sync_wait();
  98. }
  99. /* 5th: enable the write protection */
  100. RTC_WPK = RTC_LOCK_KEY;
  101. return error_status;
  102. }
  103. /*!
  104. \brief enter RTC init mode
  105. \param[in] none
  106. \param[out] none
  107. \retval ErrStatus: ERROR or SUCCESS
  108. */
  109. ErrStatus rtc_init_mode_enter(void)
  110. {
  111. uint32_t time_index = RTC_INITM_TIMEOUT;
  112. uint32_t flag_status = RESET;
  113. ErrStatus error_status = ERROR;
  114. /* check whether it has been in init mode */
  115. if((uint32_t)RESET == (RTC_STAT & RTC_STAT_INITF)){
  116. RTC_STAT |= RTC_STAT_INITM;
  117. /* wait until the INITF flag to be set */
  118. do{
  119. flag_status = RTC_STAT & RTC_STAT_INITF;
  120. }while((--time_index > 0x00U) && ((uint32_t)RESET == flag_status));
  121. if((uint32_t)RESET != flag_status){
  122. error_status = SUCCESS;
  123. }
  124. }else{
  125. error_status = SUCCESS;
  126. }
  127. return error_status;
  128. }
  129. /*!
  130. \brief exit RTC init mode
  131. \param[in] none
  132. \param[out] none
  133. \retval none
  134. */
  135. void rtc_init_mode_exit(void)
  136. {
  137. RTC_STAT &= (uint32_t)(~RTC_STAT_INITM);
  138. }
  139. /*!
  140. \brief wait until RTC_TIME and RTC_DATE registers are synchronized with APB clock, and the shadow
  141. registers are updated
  142. \param[in] none
  143. \param[out] none
  144. \retval ErrStatus: ERROR or SUCCESS
  145. */
  146. ErrStatus rtc_register_sync_wait(void)
  147. {
  148. volatile uint32_t time_index = RTC_RSYNF_TIMEOUT;
  149. uint32_t flag_status = RESET;
  150. ErrStatus error_status = ERROR;
  151. if((uint32_t)RESET == (RTC_CTL & RTC_CTL_BPSHAD)){
  152. /* disable the write protection */
  153. RTC_WPK = RTC_UNLOCK_KEY1;
  154. RTC_WPK = RTC_UNLOCK_KEY2;
  155. /* firstly clear RSYNF flag */
  156. RTC_STAT &= (uint32_t)(~RTC_STAT_RSYNF);
  157. /* wait until RSYNF flag to be set */
  158. do{
  159. flag_status = RTC_STAT & RTC_STAT_RSYNF;
  160. }while((--time_index > 0x00U) && ((uint32_t)RESET == flag_status));
  161. if((uint32_t)RESET != flag_status){
  162. error_status = SUCCESS;
  163. }
  164. /* enable the write protection */
  165. RTC_WPK = RTC_LOCK_KEY;
  166. }else{
  167. error_status = SUCCESS;
  168. }
  169. return error_status;
  170. }
  171. /*!
  172. \brief get current time and date
  173. \param[in] none
  174. \param[out] rtc_initpara_struct: pointer to a rtc_parameter_struct structure which contains
  175. parameters for initialization of the rtc peripheral
  176. members of the structure and the member values are shown as below:
  177. rtc_year: 0x0 - 0x99(BCD format)
  178. rtc_month: RTC_JAN, RTC_FEB, RTC_MAR, RTC_APR, RTC_MAY, RTC_JUN,
  179. RTC_JUL, RTC_AUG, RTC_SEP, RTC_OCT, RTC_NOV, RTC_DEC
  180. rtc_date: 0x1 - 0x31(BCD format)
  181. rtc_day_of_week: RTC_MONDAY, RTC_TUESDAY, RTC_WEDSDAY, RTC_THURSDAY
  182. RTC_FRIDAY, RTC_SATURDAY, RTC_SUNDAY
  183. rtc_hour: 0x0 - 0x12(BCD format) or 0x0 - 0x23(BCD format) depending on the rtc_display_format chose
  184. rtc_minute: 0x0 - 0x59(BCD format)
  185. rtc_second: 0x0 - 0x59(BCD format)
  186. rtc_factor_asyn: 0x0 - 0x7F
  187. rtc_factor_syn: 0x0 - 0x7FFF
  188. rtc_am_pm: RTC_AM, RTC_PM
  189. rtc_display_format: RTC_24HOUR, RTC_12HOUR
  190. \retval none
  191. */
  192. void rtc_current_time_get(rtc_parameter_struct* rtc_initpara_struct)
  193. {
  194. uint32_t temp_tr = 0x00U, temp_dr = 0x00U, temp_pscr = 0x00U, temp_ctlr = 0x00U;
  195. temp_tr = (uint32_t)RTC_TIME;
  196. temp_dr = (uint32_t)RTC_DATE;
  197. temp_pscr = (uint32_t)RTC_PSC;
  198. temp_ctlr = (uint32_t)RTC_CTL;
  199. /* get current time and construct rtc_parameter_struct structure */
  200. rtc_initpara_struct->rtc_year = (uint8_t)GET_DATE_YR(temp_dr);
  201. rtc_initpara_struct->rtc_month = (uint8_t)GET_DATE_MON(temp_dr);
  202. rtc_initpara_struct->rtc_date = (uint8_t)GET_DATE_DAY(temp_dr);
  203. rtc_initpara_struct->rtc_day_of_week = (uint8_t)GET_DATE_DOW(temp_dr);
  204. rtc_initpara_struct->rtc_hour = (uint8_t)GET_TIME_HR(temp_tr);
  205. rtc_initpara_struct->rtc_minute = (uint8_t)GET_TIME_MN(temp_tr);
  206. rtc_initpara_struct->rtc_second = (uint8_t)GET_TIME_SC(temp_tr);
  207. rtc_initpara_struct->rtc_factor_asyn = (uint16_t)GET_PSC_FACTOR_A(temp_pscr);
  208. rtc_initpara_struct->rtc_factor_syn = (uint16_t)GET_PSC_FACTOR_S(temp_pscr);
  209. rtc_initpara_struct->rtc_am_pm = (uint32_t)(temp_pscr & RTC_TIME_PM);
  210. rtc_initpara_struct->rtc_display_format = (uint32_t)(temp_ctlr & RTC_CTL_CS);
  211. }
  212. /*!
  213. \brief get current subsecond value
  214. \param[in] none
  215. \param[out] none
  216. \retval current subsecond value
  217. */
  218. uint32_t rtc_subsecond_get(void)
  219. {
  220. uint32_t reg = 0x00U;
  221. /* if BPSHAD bit is reset, reading RTC_SS will lock RTC_TIME and RTC_DATE automatically */
  222. reg = (uint32_t)RTC_SS;
  223. /* read RTC_DATE to unlock the 3 shadow registers */
  224. (void) (RTC_DATE);
  225. return reg;
  226. }
  227. /*!
  228. \brief configure RTC alarm
  229. \param[in] rtc_alarm_time: pointer to a rtc_alarm_struct structure which contains
  230. parameters for RTC alarm configuration
  231. members of the structure and the member values are shown as below:
  232. rtc_alarm_mask: RTC_ALARM_NONE_MASK, RTC_ALARM_DATE_MASK, RTC_ALARM_HOUR_MASK
  233. RTC_ALARM_MINUTE_MASK, RTC_ALARM_SECOND_MASK, RTC_ALARM_ALL_MASK
  234. rtc_weekday_or_date: RTC_ALARM_DATE_SELECTED, RTC_ALARM_WEEKDAY_SELECTED
  235. rtc_alarm_day: 1) 0x1 - 0x31(BCD format) if RTC_ALARM_DATE_SELECTED is set
  236. 2) RTC_MONDAY, RTC_TUESDAY, RTC_WEDSDAY, RTC_THURSDAY, RTC_FRIDAY,
  237. RTC_SATURDAY, RTC_SUNDAY if RTC_ALARM_WEEKDAY_SELECTED is set
  238. rtc_alarm_hour: 0x0 - 0x12(BCD format) or 0x0 - 0x23(BCD format) depending on the rtc_display_format
  239. rtc_alarm_minute: 0x0 - 0x59(BCD format)
  240. rtc_alarm_second: 0x0 - 0x59(BCD format)
  241. rtc_am_pm: RTC_AM, RTC_PM
  242. \param[out] none
  243. \retval none
  244. */
  245. void rtc_alarm_config(rtc_alarm_struct* rtc_alarm_time)
  246. {
  247. uint32_t reg_alrm0td = 0x00U;
  248. reg_alrm0td = (rtc_alarm_time->rtc_alarm_mask | \
  249. rtc_alarm_time->rtc_weekday_or_date | \
  250. rtc_alarm_time->rtc_am_pm | \
  251. ALRM0TD_DAY(rtc_alarm_time->rtc_alarm_day) | \
  252. ALRM0TD_HR(rtc_alarm_time->rtc_alarm_hour) | \
  253. ALRM0TD_MN(rtc_alarm_time->rtc_alarm_minute) | \
  254. ALRM0TD_SC(rtc_alarm_time->rtc_alarm_second));
  255. /* disable the write protection */
  256. RTC_WPK = RTC_UNLOCK_KEY1;
  257. RTC_WPK = RTC_UNLOCK_KEY2;
  258. RTC_ALRM0TD = (uint32_t)reg_alrm0td;
  259. /* enable the write protection */
  260. RTC_WPK = RTC_LOCK_KEY;
  261. }
  262. /*!
  263. \brief configure subsecond of RTC alarm
  264. \param[in] mask_subsecond: alarm subsecond mask
  265. \arg RTC_MASKSSC_0_14: mask alarm subsecond configuration
  266. \arg RTC_MASKSSC_1_14: mask RTC_ALRM0SS_SSC[14:1], and RTC_ALRM0SS_SSC[0] is to be compared
  267. \arg RTC_MASKSSC_2_14: mask RTC_ALRM0SS_SSC[14:2], and RTC_ALRM0SS_SSC[1:0] is to be compared
  268. \arg RTC_MASKSSC_3_14: mask RTC_ALRM0SS_SSC[14:3], and RTC_ALRM0SS_SSC[2:0] is to be compared
  269. \arg RTC_MASKSSC_4_14: mask RTC_ALRM0SS_SSC[14:4], and RTC_ALRM0SS_SSC[3:0] is to be compared
  270. \arg RTC_MASKSSC_5_14: mask RTC_ALRM0SS_SSC[14:5], and RTC_ALRM0SS_SSC[4:0] is to be compared
  271. \arg RTC_MASKSSC_6_14: mask RTC_ALRM0SS_SSC[14:6], and RTC_ALRM0SS_SSC[5:0] is to be compared
  272. \arg RTC_MASKSSC_7_14: mask RTC_ALRM0SS_SSC[14:7], and RTC_ALRM0SS_SSC[6:0] is to be compared
  273. \arg RTC_MASKSSC_8_14: mask RTC_ALRM0SS_SSC[14:8], and RTC_ALRM0SS_SSC[7:0] is to be compared
  274. \arg RTC_MASKSSC_9_14: mask RTC_ALRM0SS_SSC[14:9], and RTC_ALRM0SS_SSC[8:0] is to be compared
  275. \arg RTC_MASKSSC_10_14: mask RTC_ALRM0SS_SSC[14:10], and RTC_ALRM0SS_SSC[9:0] is to be compared
  276. \arg RTC_MASKSSC_11_14: mask RTC_ALRM0SS_SSC[14:11], and RTC_ALRM0SS_SSC[10:0] is to be compared
  277. \arg RTC_MASKSSC_12_14: mask RTC_ALRM0SS_SSC[14:12], and RTC_ALRM0SS_SSC[11:0] is to be compared
  278. \arg RTC_MASKSSC_13_14: mask RTC_ALRM0SS_SSC[14:13], and RTC_ALRM0SS_SSC[12:0] is to be compared
  279. \arg RTC_MASKSSC_14: mask RTC_ALRM0SS_SSC[14], and RTC_ALRM0SS_SSC[13:0] is to be compared
  280. \arg RTC_MASKSSC_NONE: mask none, and RTC_ALRM0SS_SSC[14:0] is to be compared
  281. \param[in] subsecond: alarm subsecond value(0x000 - 0x7FFF)
  282. \param[out] none
  283. \retval none
  284. */
  285. void rtc_alarm_subsecond_config(uint32_t mask_subsecond, uint32_t subsecond)
  286. {
  287. /* disable the write protection */
  288. RTC_WPK = RTC_UNLOCK_KEY1;
  289. RTC_WPK = RTC_UNLOCK_KEY2;
  290. RTC_ALRM0SS = mask_subsecond | subsecond;
  291. /* enable the write protection */
  292. RTC_WPK = RTC_LOCK_KEY;
  293. }
  294. /*!
  295. \brief enable RTC alarm
  296. \param[in] none
  297. \param[out] none
  298. \retval none
  299. */
  300. void rtc_alarm_enable(void)
  301. {
  302. /* disable the write protection */
  303. RTC_WPK = RTC_UNLOCK_KEY1;
  304. RTC_WPK = RTC_UNLOCK_KEY2;
  305. RTC_CTL |= RTC_CTL_ALRM0EN;
  306. /* enable the write protection */
  307. RTC_WPK = RTC_LOCK_KEY;
  308. }
  309. /*!
  310. \brief disable RTC alarm
  311. \param[in] none
  312. \param[out] none
  313. \retval ErrStatus: ERROR or SUCCESS
  314. */
  315. ErrStatus rtc_alarm_disable(void)
  316. {
  317. volatile uint32_t time_index = RTC_ALRM0WF_TIMEOUT;
  318. ErrStatus error_status = ERROR;
  319. uint32_t flag_status = RESET;
  320. /* disable the write protection */
  321. RTC_WPK = RTC_UNLOCK_KEY1;
  322. RTC_WPK = RTC_UNLOCK_KEY2;
  323. /* clear the state of alarm */
  324. RTC_CTL &= (uint32_t)(~RTC_CTL_ALRM0EN);
  325. /* wait until ALRM0WF flag to be set after the alarm is disabled */
  326. do{
  327. flag_status = RTC_STAT & RTC_STAT_ALRM0WF;
  328. }while((--time_index > 0x00U) && ((uint32_t)RESET == flag_status));
  329. if((uint32_t)RESET != flag_status){
  330. error_status = SUCCESS;
  331. }
  332. /* enable the write protection */
  333. RTC_WPK = RTC_LOCK_KEY;
  334. return error_status;
  335. }
  336. /*!
  337. \brief get RTC alarm
  338. \param[in] none
  339. \param[out] rtc_alarm_time: pointer to a rtc_alarm_struct structure which contains
  340. parameters for RTC alarm configuration
  341. members of the structure and the member values are shown as below:
  342. rtc_alarm_mask: RTC_ALARM_NONE_MASK, RTC_ALARM_DATE_MASK, RTC_ALARM_HOUR_MASK
  343. RTC_ALARM_MINUTE_MASK, RTC_ALARM_SECOND_MASK, RTC_ALARM_ALL_MASK
  344. rtc_weekday_or_date: RTC_ALARM_DATE_SELECTED, RTC_ALARM_WEEKDAY_SELECTED
  345. rtc_alarm_day: 1) 0x1 - 0x31(BCD format) if RTC_ALARM_DATE_SELECTED is set
  346. 2) RTC_MONDAY, RTC_TUESDAY, RTC_WEDSDAY, RTC_THURSDAY, RTC_FRIDAY,
  347. RTC_SATURDAY, RTC_SUNDAY if RTC_ALARM_WEEKDAY_SELECTED is set
  348. rtc_alarm_hour: 0x0 - 0x12(BCD format) or 0x0 - 0x23(BCD format) depending on the rtc_display_format
  349. rtc_alarm_minute: 0x0 - 0x59(BCD format)
  350. rtc_alarm_second: 0x0 - 0x59(BCD format)
  351. rtc_am_pm: RTC_AM, RTC_PM
  352. \retval none
  353. */
  354. void rtc_alarm_get(rtc_alarm_struct* rtc_alarm_time)
  355. {
  356. uint32_t reg_alrm0td = 0x00U;
  357. /* get the value of RTC_ALRM0TD register */
  358. reg_alrm0td = RTC_ALRM0TD;
  359. /* get alarm parameters and construct the rtc_alarm_struct structure */
  360. rtc_alarm_time->rtc_alarm_mask = reg_alrm0td & RTC_ALARM_ALL_MASK;
  361. rtc_alarm_time->rtc_am_pm = (uint32_t)(reg_alrm0td & RTC_ALRM0TD_PM);
  362. rtc_alarm_time->rtc_weekday_or_date = (uint32_t)(reg_alrm0td & RTC_ALRM0TD_DOWS);
  363. rtc_alarm_time->rtc_alarm_day = (uint8_t)GET_ALRM0TD_DAY(reg_alrm0td);
  364. rtc_alarm_time->rtc_alarm_hour = (uint8_t)GET_ALRM0TD_HR(reg_alrm0td);
  365. rtc_alarm_time->rtc_alarm_minute = (uint8_t)GET_ALRM0TD_MN(reg_alrm0td);
  366. rtc_alarm_time->rtc_alarm_second = (uint8_t)GET_ALRM0TD_SC(reg_alrm0td);
  367. }
  368. /*!
  369. \brief get RTC alarm subsecond
  370. \param[in] none
  371. \param[out] none
  372. \retval RTC alarm subsecond value
  373. */
  374. uint32_t rtc_alarm_subsecond_get(void)
  375. {
  376. return ((uint32_t)(RTC_ALRM0SS & RTC_ALRM0SS_SSC));
  377. }
  378. /*!
  379. \brief enable RTC time-stamp
  380. \param[in] edge: specify which edge to detect of time-stamp
  381. \arg RTC_TIMESTAMP_RISING_EDGE: rising edge is valid event edge for timestamp event
  382. \arg RTC_TIMESTAMP_FALLING_EDGE: falling edge is valid event edge for timestamp event
  383. \param[out] none
  384. \retval none
  385. */
  386. void rtc_timestamp_enable(uint32_t edge)
  387. {
  388. uint32_t reg_ctl = 0x00U;
  389. /* clear the bits to be configured in RTC_CTL */
  390. reg_ctl = (uint32_t)(RTC_CTL & (uint32_t)(~(RTC_CTL_TSEG | RTC_CTL_TSEN)));
  391. /* new configuration */
  392. reg_ctl |= (uint32_t)(edge | RTC_CTL_TSEN);
  393. /* disable the write protection */
  394. RTC_WPK = RTC_UNLOCK_KEY1;
  395. RTC_WPK = RTC_UNLOCK_KEY2;
  396. RTC_CTL = (uint32_t)reg_ctl;
  397. /* enable the write protection */
  398. RTC_WPK = RTC_LOCK_KEY;
  399. }
  400. /*!
  401. \brief disable RTC time-stamp
  402. \param[in] none
  403. \param[out] none
  404. \retval none
  405. */
  406. void rtc_timestamp_disable(void)
  407. {
  408. /* disable the write protection */
  409. RTC_WPK = RTC_UNLOCK_KEY1;
  410. RTC_WPK = RTC_UNLOCK_KEY2;
  411. /* clear the TSEN bit */
  412. RTC_CTL &= (uint32_t)(~ RTC_CTL_TSEN);
  413. /* enable the write protection */
  414. RTC_WPK = RTC_LOCK_KEY;
  415. }
  416. /*!
  417. \brief get RTC timestamp time and date
  418. \param[in] none
  419. \param[out] rtc_timestamp: pointer to a rtc_timestamp_struct structure which contains
  420. parameters for RTC time-stamp configuration
  421. members of the structure and the member values are shown as below:
  422. rtc_timestamp_month: RTC_JAN, RTC_FEB, RTC_MAR, RTC_APR, RTC_MAY, RTC_JUN,
  423. RTC_JUL, RTC_AUG, RTC_SEP, RTC_OCT, RTC_NOV, RTC_DEC
  424. rtc_timestamp_date: 0x1 - 0x31(BCD format)
  425. rtc_timestamp_day: RTC_MONDAY, RTC_TUESDAY, RTC_WEDSDAY, RTC_THURSDAY, RTC_FRIDAY,
  426. RTC_SATURDAY, RTC_SUNDAY if RTC_ALARM_WEEKDAY_SELECTED is set
  427. rtc_timestamp_hour: 0x0 - 0x12(BCD format) or 0x0 - 0x23(BCD format) depending on the rtc_display_format
  428. rtc_timestamp_minute: 0x0 - 0x59(BCD format)
  429. rtc_timestamp_second: 0x0 - 0x59(BCD format)
  430. rtc_am_pm: RTC_AM, RTC_PM
  431. \retval none
  432. */
  433. void rtc_timestamp_get(rtc_timestamp_struct* rtc_timestamp)
  434. {
  435. uint32_t temp_tts = 0x00U, temp_dts = 0x00U;
  436. /* get the value of time_stamp registers */
  437. temp_tts = (uint32_t)RTC_TTS;
  438. temp_dts = (uint32_t)RTC_DTS;
  439. /* get timestamp time and construct the rtc_timestamp_struct structure */
  440. rtc_timestamp->rtc_am_pm = (uint32_t)(temp_tts & RTC_TTS_PM);
  441. rtc_timestamp->rtc_timestamp_month = (uint8_t)GET_DTS_MON(temp_dts);
  442. rtc_timestamp->rtc_timestamp_date = (uint8_t)GET_DTS_DAY(temp_dts);
  443. rtc_timestamp->rtc_timestamp_day = (uint8_t)GET_DTS_DOW(temp_dts);
  444. rtc_timestamp->rtc_timestamp_hour = (uint8_t)GET_TTS_HR(temp_tts);
  445. rtc_timestamp->rtc_timestamp_minute = (uint8_t)GET_TTS_MN(temp_tts);
  446. rtc_timestamp->rtc_timestamp_second = (uint8_t)GET_TTS_SC(temp_tts);
  447. }
  448. /*!
  449. \brief get RTC time-stamp subsecond
  450. \param[in] none
  451. \param[out] none
  452. \retval RTC time-stamp subsecond value
  453. */
  454. uint32_t rtc_timestamp_subsecond_get(void)
  455. {
  456. return ((uint32_t)RTC_SSTS);
  457. }
  458. /*!
  459. \brief enable RTC tamper
  460. \param[in] rtc_tamper: pointer to a rtc_tamper_struct structure which contains
  461. parameters for RTC tamper configuration
  462. members of the structure and the member values are shown as below:
  463. rtc_tamper_source: RTC_TAMPER0, RTC_TAMPER1
  464. rtc_tamper_trigger: RTC_TAMPER_TRIGGER_EDGE_RISING, RTC_TAMPER_TRIGGER_EDGE_FALLING
  465. RTC_TAMPER_TRIGGER_LEVEL_LOW, RTC_TAMPER_TRIGGER_LEVEL_HIGH
  466. rtc_tamper_filter: RTC_FLT_EDGE, RTC_FLT_2S, RTC_FLT_4S, RTC_FLT_8S
  467. rtc_tamper_sample_frequency: RTC_FREQ_DIV32768, RTC_FREQ_DIV16384, RTC_FREQ_DIV8192,
  468. RTC_FREQ_DIV4096, RTC_FREQ_DIV2048, RTC_FREQ_DIV1024,
  469. RTC_FREQ_DIV512, RTC_FREQ_DIV256
  470. rtc_tamper_precharge_enable: DISABLE, ENABLE
  471. rtc_tamper_precharge_time: RTC_PRCH_1C, RTC_PRCH_2C, RTC_PRCH_4C, RTC_PRCH_8C
  472. rtc_tamper_with_timestamp: DISABLE, ENABLE
  473. \param[out] none
  474. \retval none
  475. */
  476. void rtc_tamper_enable(rtc_tamper_struct* rtc_tamper)
  477. {
  478. /* disable tamper */
  479. RTC_TAMP &= (uint32_t)~(rtc_tamper->rtc_tamper_source);
  480. /* tamper filter must be used when the tamper source is voltage level detection */
  481. RTC_TAMP &= (uint32_t)~RTC_TAMP_FLT;
  482. /* the tamper source is voltage level detection */
  483. if(rtc_tamper->rtc_tamper_filter != RTC_FLT_EDGE ){
  484. RTC_TAMP &= (uint32_t)~(RTC_TAMP_DISPU | RTC_TAMP_PRCH | RTC_TAMP_FREQ | RTC_TAMP_FLT);
  485. /* check if the tamper pin need precharge, if need, then configure the precharge time */
  486. if(DISABLE == rtc_tamper->rtc_tamper_precharge_enable){
  487. RTC_TAMP |= (uint32_t)RTC_TAMP_DISPU;
  488. }else{
  489. RTC_TAMP |= (uint32_t)(rtc_tamper->rtc_tamper_precharge_time);
  490. }
  491. RTC_TAMP |= (uint32_t)(rtc_tamper->rtc_tamper_sample_frequency);
  492. RTC_TAMP |= (uint32_t)(rtc_tamper->rtc_tamper_filter);
  493. }
  494. RTC_TAMP &= (uint32_t)~RTC_TAMP_TPTS;
  495. if(DISABLE != rtc_tamper->rtc_tamper_with_timestamp){
  496. /* the tamper event also cause a time-stamp event */
  497. RTC_TAMP |= (uint32_t)RTC_TAMP_TPTS;
  498. }
  499. /* configure the tamper trigger */
  500. RTC_TAMP &= ((uint32_t)~((rtc_tamper->rtc_tamper_source) << RTC_TAMPER_TRIGGER_POS));
  501. if(RTC_TAMPER_TRIGGER_EDGE_RISING != rtc_tamper->rtc_tamper_trigger){
  502. RTC_TAMP |= (uint32_t)((rtc_tamper->rtc_tamper_source)<< RTC_TAMPER_TRIGGER_POS);
  503. }
  504. /* enable tamper */
  505. RTC_TAMP |= (uint32_t)(rtc_tamper->rtc_tamper_source);
  506. }
  507. /*!
  508. \brief disable RTC tamper
  509. \param[in] source: specify which tamper source to be disabled
  510. \arg RTC_TAMPER0
  511. \arg RTC_TAMPER1
  512. \param[out] none
  513. \retval none
  514. */
  515. void rtc_tamper_disable(uint32_t source)
  516. {
  517. /* disable tamper */
  518. RTC_TAMP &= (uint32_t)~source;
  519. }
  520. /*!
  521. \brief enable specified RTC interrupt
  522. \param[in] interrupt: specify which interrupt source to be enabled
  523. \arg RTC_INT_TIMESTAMP: timestamp interrupt
  524. \arg RTC_INT_ALARM: alarm interrupt
  525. \arg RTC_INT_TAMP: tamp interrupt
  526. \param[out] none
  527. \retval none
  528. */
  529. void rtc_interrupt_enable(uint32_t interrupt)
  530. {
  531. /* disable the write protection */
  532. RTC_WPK = RTC_UNLOCK_KEY1;
  533. RTC_WPK = RTC_UNLOCK_KEY2;
  534. /* enable the interrupts in RTC_CTL register */
  535. RTC_CTL |= (uint32_t)(interrupt & (uint32_t)~RTC_TAMP_TPIE);
  536. /* enable the interrupts in RTC_TAMP register */
  537. RTC_TAMP |= (uint32_t)(interrupt & RTC_TAMP_TPIE);
  538. /* enable the write protection */
  539. RTC_WPK = RTC_LOCK_KEY;
  540. }
  541. /*!
  542. \brief disble specified RTC interrupt
  543. \param[in] interrupt: specify which interrupt source to be disabled
  544. \arg RTC_INT_TIMESTAMP: timestamp interrupt
  545. \arg RTC_INT_ALARM: alarm interrupt
  546. \arg RTC_INT_TAMP: tamp interrupt
  547. \param[out] none
  548. \retval none
  549. */
  550. void rtc_interrupt_disable(uint32_t interrupt)
  551. {
  552. /* disable the write protection */
  553. RTC_WPK = RTC_UNLOCK_KEY1;
  554. RTC_WPK = RTC_UNLOCK_KEY2;
  555. /* disable the interrupts in RTC_CTL register */
  556. RTC_CTL &= (uint32_t)~(interrupt & (uint32_t)~RTC_TAMP_TPIE);
  557. /* disable the interrupts in RTC_TAMP register */
  558. RTC_TAMP &= (uint32_t)~(interrupt & RTC_TAMP_TPIE);
  559. /* enable the write protection */
  560. RTC_WPK = RTC_LOCK_KEY;
  561. }
  562. /*!
  563. \brief check specified flag
  564. \param[in] flag: specify which flag to check
  565. \arg RTC_FLAG_RECALIBRATION: recalibration pending flag
  566. \arg RTC_FLAG_TAMP1: tamper 1 event flag
  567. \arg RTC_FLAG_TAMP0: tamper 0 event flag
  568. \arg RTC_FLAG_TIMESTAMP_OVERFLOW: time-stamp overflow event flag
  569. \arg RTC_FLAG_TIMESTAMP: time-stamp event flag
  570. \arg RTC_FLAG_ALARM0: alarm event flag
  571. \arg RTC_FLAG_INIT: init mode event flag
  572. \arg RTC_FLAG_RSYN: time and date registers synchronized event flag
  573. \arg RTC_FLAG_YCM: year parameter configured event flag
  574. \arg RTC_FLAG_SHIFT: shift operation pending flag
  575. \arg RTC_FLAG_ALARM0_WRITTEN: alarm writen available flag
  576. \param[out] none
  577. \retval FlagStatus: SET or RESET
  578. */
  579. FlagStatus rtc_flag_get(uint32_t flag)
  580. {
  581. FlagStatus flag_state = RESET;
  582. if((uint32_t)RESET != (RTC_STAT & flag)){
  583. flag_state = SET;
  584. }
  585. return flag_state;
  586. }
  587. /*!
  588. \brief clear specified flag
  589. \param[in] flag: specify which flag to clear
  590. \arg RTC_FLAG_TAMP1: tamper 1 event flag
  591. \arg RTC_FLAG_TAMP0: tamper 0 event flag
  592. \arg RTC_FLAG_TIMESTAMP_OVERFLOW: time-stamp overflow event flag
  593. \arg RTC_FLAG_TIMESTAMP: time-stamp event flag
  594. \arg RTC_FLAG_ALARM0: alarm event flag
  595. \arg RTC_FLAG_RSYN: time and date registers synchronized event flag
  596. \param[out] none
  597. \retval none
  598. */
  599. void rtc_flag_clear(uint32_t flag)
  600. {
  601. RTC_STAT &= (uint32_t)(~flag);
  602. }
  603. /*!
  604. \brief configure rtc alternate output source
  605. \param[in] source: specify signal to output
  606. \arg RTC_CALIBRATION_512HZ: when the LSE freqency is 32768Hz and the RTC_PSC
  607. is the default value, output 512Hz signal
  608. \arg RTC_CALIBRATION_1HZ: when the LSE freqency is 32768Hz and the RTC_PSC
  609. is the default value, output 512Hz signal
  610. \arg RTC_ALARM_HIGH: when the alarm flag is set, the output pin is high
  611. \arg RTC_ALARM_LOW: when the Alarm flag is set, the output pin is low
  612. \param[in] mode: specify the output pin (PC13) mode when output alarm signal
  613. \arg RTC_ALARM_OUTPUT_OD: open drain mode
  614. \arg RTC_ALARM_OUTPUT_PP: push pull mode
  615. \param[out] none
  616. \retval none
  617. */
  618. void rtc_alter_output_config(uint32_t source, uint32_t mode)
  619. {
  620. /* disable the write protection */
  621. RTC_WPK = RTC_UNLOCK_KEY1;
  622. RTC_WPK = RTC_UNLOCK_KEY2;
  623. RTC_CTL &= (uint32_t)~(RTC_CTL_COEN | RTC_CTL_OS | RTC_CTL_OPOL | RTC_CTL_COS);
  624. RTC_CTL |= (uint32_t)(source);
  625. /* alarm output */
  626. if((uint32_t)RESET != (source & RTC_OS_ENABLE)){
  627. RTC_TAMP &= (uint32_t)~(RTC_TAMP_PC13VAL);
  628. RTC_TAMP |= (uint32_t)(mode);
  629. }
  630. /* enable the write protection */
  631. RTC_WPK = RTC_LOCK_KEY;
  632. }
  633. /*!
  634. \brief ajust the daylight saving time by adding or substracting one hour from the current time
  635. \param[in] operation: hour ajustment operation
  636. \arg RTC_CTL_A1H: add one hour
  637. \arg RTC_CTL_S1H: substract one hour
  638. \param[out] none
  639. \retval none
  640. */
  641. void rtc_hour_adjust(uint32_t operation)
  642. {
  643. /* disable the write protection */
  644. RTC_WPK = RTC_UNLOCK_KEY1;
  645. RTC_WPK = RTC_UNLOCK_KEY2;
  646. RTC_CTL |= (uint32_t)(operation);
  647. /* enable the write protection */
  648. RTC_WPK = RTC_LOCK_KEY;
  649. }
  650. /*!
  651. \brief enable RTC bypass shadow registers function
  652. \param[in] none
  653. \param[out] none
  654. \retval none
  655. */
  656. void rtc_bypass_shadow_enable(void)
  657. {
  658. /* disable the write protection */
  659. RTC_WPK = RTC_UNLOCK_KEY1;
  660. RTC_WPK = RTC_UNLOCK_KEY2;
  661. RTC_CTL |= (uint8_t)RTC_CTL_BPSHAD;
  662. /* enable the write protection */
  663. RTC_WPK = RTC_LOCK_KEY;
  664. }
  665. /*!
  666. \brief disable RTC bypass shadow registers function
  667. \param[in] none
  668. \param[out] none
  669. \retval none
  670. */
  671. void rtc_bypass_shadow_disable(void)
  672. {
  673. /* disable the write protection */
  674. RTC_WPK = RTC_UNLOCK_KEY1;
  675. RTC_WPK = RTC_UNLOCK_KEY2;
  676. RTC_CTL &= (uint8_t)~RTC_CTL_BPSHAD;
  677. /* enable the write protection */
  678. RTC_WPK = RTC_LOCK_KEY;
  679. }
  680. /*!
  681. \brief enable RTC reference clock detection function
  682. \param[in] none
  683. \param[out] none
  684. \retval ErrStatus: ERROR or SUCCESS
  685. */
  686. ErrStatus rtc_refclock_detection_enable(void)
  687. {
  688. ErrStatus error_status = ERROR;
  689. /* disable the write protection */
  690. RTC_WPK = RTC_UNLOCK_KEY1;
  691. RTC_WPK = RTC_UNLOCK_KEY2;
  692. /* enter init mode */
  693. error_status = rtc_init_mode_enter();
  694. if(ERROR != error_status){
  695. RTC_CTL |= (uint32_t)RTC_CTL_REFEN;
  696. /* exit init mode */
  697. rtc_init_mode_exit();
  698. }
  699. /* enable the write protection */
  700. RTC_WPK = RTC_LOCK_KEY;
  701. return error_status;
  702. }
  703. /*!
  704. \brief disable RTC reference clock detection function
  705. \param[in] none
  706. \param[out] none
  707. \retval ErrStatus: ERROR or SUCCESS
  708. */
  709. ErrStatus rtc_refclock_detection_disable(void)
  710. {
  711. ErrStatus error_status = ERROR;
  712. /* disable the write protection */
  713. RTC_WPK = RTC_UNLOCK_KEY1;
  714. RTC_WPK = RTC_UNLOCK_KEY2;
  715. /* enter init mode */
  716. error_status = rtc_init_mode_enter();
  717. if(ERROR != error_status){
  718. RTC_CTL &= (uint32_t)~RTC_CTL_REFEN;
  719. /* exit init mode */
  720. rtc_init_mode_exit();
  721. }
  722. /* enable the write protection */
  723. RTC_WPK = RTC_LOCK_KEY;
  724. return error_status;
  725. }
  726. /*!
  727. \brief ajust RTC second or subsecond value of current time
  728. \param[in] add: add 1s to current time or not
  729. \arg RTC_SHIFT_ADD1S_RESET: no effect
  730. \arg RTC_SHIFT_ADD1S_SET: add 1s to current time
  731. \param[in] minus: number of subsecond to minus from current time(0x0 - 0x7FFF)
  732. \param[out] none
  733. \retval ErrStatus: ERROR or SUCCESS
  734. */
  735. ErrStatus rtc_second_ajust(uint32_t add, uint32_t minus)
  736. {
  737. uint32_t time_index = RTC_SHIFTCTL_TIMEOUT;
  738. ErrStatus error_status = ERROR;
  739. uint32_t flag_status = RESET;
  740. uint32_t temp=0U;
  741. /* disable the write protection */
  742. RTC_WPK = RTC_UNLOCK_KEY1;
  743. RTC_WPK = RTC_UNLOCK_KEY2;
  744. /* check if a shift operation is ongoing */
  745. do{
  746. flag_status = RTC_STAT & RTC_STAT_SOPF;
  747. }while((--time_index > 0x00U) && ((uint32_t)RESET != flag_status));
  748. temp = RTC_CTL & RTC_CTL_REFEN;
  749. /* check if the function of reference clock detection is disabled */
  750. if(((uint32_t)RESET == flag_status) && (RESET == temp)){
  751. RTC_SHIFTCTL = (uint32_t)(add | SHIFTCTL_SFS(minus));
  752. error_status = rtc_register_sync_wait();
  753. }
  754. /* enable the write protection */
  755. RTC_WPK = RTC_LOCK_KEY;
  756. return error_status;
  757. }
  758. /*!
  759. \brief configure RTC calibration register
  760. \param[in] window: select calibration window
  761. \arg RTC_CALIBRATION_WINDOW_32S: 2exp20 RTCCLK cycles, 32s if RTCCLK = 32768 Hz
  762. \arg RTC_CALIBRATION_WINDOW_16S: 2exp19 RTCCLK cycles, 16s if RTCCLK = 32768 Hz
  763. \arg RTC_CALIBRATION_WINDOW_8S: 2exp18 RTCCLK cycles, 8s if RTCCLK = 32768 Hz
  764. \param[in] plus: add RTC clock or not
  765. \arg RTC_CALIBRATION_PLUS_SET: add one RTC clock every 2048 rtc clock
  766. \arg RTC_CALIBRATION_PLUS_RESET: no effect
  767. \param[in] minus: the RTC clock to minus during the calibration window(0x0 - 0x1FF)
  768. \param[out] none
  769. \retval ErrStatus: ERROR or SUCCESS
  770. */
  771. ErrStatus rtc_calibration_config(uint32_t window, uint32_t plus, uint32_t minus)
  772. {
  773. uint32_t time_index = RTC_HRFC_TIMEOUT;
  774. ErrStatus error_status = ERROR;
  775. uint32_t flag_status = RESET;
  776. /* disable the write protection */
  777. RTC_WPK = RTC_UNLOCK_KEY1;
  778. RTC_WPK = RTC_UNLOCK_KEY2;
  779. /* check if a calibration operation is ongoing */
  780. do{
  781. flag_status = RTC_STAT & RTC_STAT_SCPF;
  782. }while((--time_index > 0x00U) && ((uint32_t)RESET != flag_status));
  783. if((uint32_t)RESET == flag_status){
  784. RTC_HRFC = (uint32_t)(window | plus | HRFC_CMSK(minus));
  785. error_status = SUCCESS;
  786. }
  787. /* enable the write protection */
  788. RTC_WPK = RTC_LOCK_KEY;
  789. return error_status;
  790. }