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