gd32f4xx_rtc.c 45 KB

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