1 /**
2 ******************************************************************************
3 * @file rtl8721d_rtc.c
4 * @author
5 * @version V1.0.0
6 * @date 2016-05-17
7 * @brief This file provides firmware functions to manage the following
8 * functionalities of the Real-Time Clock (RTC) peripheral:
9 * - Initialization
10 * - Calendar (Time and Date) configuration
11 * - Alarms configuration
12 * - WakeUp Timer configuration
13 * - Daylight Saving configuration
14 * - Output pin Configuration
15 * - Smooth digital Calibration configuration
16 * - TimeStamp configuration
17 * - Interrupts and flags management
18 ******************************************************************************
19 * @attention
20 *
21 * This module is a confidential and proprietary property of RealTek and
22 * possession or use of this module requires written permission of RealTek.
23 *
24 * Copyright(c) 2015, Realtek Semiconductor Corporation. All rights reserved.
25 ******************************************************************************
26 */
27 #include "ameba_soc.h"
28
29 /**
30 * @brief Converts a 2 digit decimal to BCD format.
31 * @param Value: Byte to be converted.
32 * @retval Converted byte
33 */
RTC_ByteToBcd2(u8 Value)34 u8 RTC_ByteToBcd2(u8 Value)
35 {
36 u8 bcdhigh = 0;
37
38 while (Value >= 10) {
39 bcdhigh++;
40 Value -= 10;
41 }
42
43 return ((u8)(bcdhigh << 4) | Value);
44 }
45
46 /**
47 * @brief Convert from 2 digit BCD to Binary.
48 * @param Value: BCD value to be converted.
49 * @retval Converted word
50 */
RTC_Bcd2ToByte(u8 Value)51 u8 RTC_Bcd2ToByte(u8 Value)
52 {
53 u8 tmp = 0;
54 tmp = (u8)(((Value & 0xF0) >> 0x4) * 10);
55 return ((u8)(tmp + (Value & 0x0F)));
56 }
57
58 /**
59 * @brief Enters the RTC Initialization mode.
60 * @note the time, date and prescaler registers can be updated in init mode.
61 * @param None
62 * @retval status value:
63 * - 1: RTC is in Init mode
64 * - 0: RTC is not in Init mode
65 */
RTC_EnterInitMode(void)66 u32 RTC_EnterInitMode(void)
67 {
68 RTC_TypeDef* RTC = ((RTC_TypeDef *) RTC_BASE);
69 u32 counter = 0x00;
70 u32 status = 0;
71 u32 initstatus = 0x00;
72
73 /* Check if the Initialization mode is set */
74 if ((RTC->ISR & RTC_ISR_INITF) == 0) {
75 /* Set the Initialization mode */
76 RTC->ISR |= (u32)RTC_ISR_INIT;
77
78 /* Wait till RTC is in INIT state and if Time out is reached exit */
79 do {
80 /* check Calendar registers update is allowed */
81 initstatus = RTC->ISR & RTC_ISR_INITF;
82 counter++;
83 } while((counter != INITMODE_TIMEOUT) && (initstatus == 0x00));
84
85 if (RTC->ISR & RTC_ISR_INITF) {
86 status = 1;
87 } else {
88 status = 0;
89 }
90 } else {
91 status = 1;
92 }
93
94 return (status);
95 }
96
97 /**
98 * @brief Exits the RTC Initialization mode.
99 * @note When the initialization sequence is complete, the calendar restarts
100 * counting after 4 RTCCLK cycles.
101 * @param None
102 * @retval None
103 * @about 3 RTC clock
104 */
RTC_ExitInitMode(void)105 void RTC_ExitInitMode(void)
106 {
107 RTC_TypeDef* RTC = ((RTC_TypeDef *) RTC_BASE);
108
109 /* Exit Initialization mode */
110 RTC->ISR &= ~RTC_ISR_INIT;
111 }
112
113 /**
114 * @brief Waits until the RTC Time register (RTC_TR) is
115 * synchronized with RTC APB clock.
116 * @note To read the calendar through the shadow registers after Calendar
117 * initialization, calendar update or after wakeup from low power modes
118 * the software must first clear the RSF flag.
119 * The software must then wait until it is set again before reading
120 * the calendar, which means that the calendar registers have been
121 * correctly copied into the RTC_TR shadow registers.
122 * @param None
123 * @retval status value:
124 * - 1: RTC registers are synchronised
125 * - 0: RTC registers are not synchronised
126 * @about 2 RTC clock
127 */
RTC_WaitForSynchro(void)128 u32 RTC_WaitForSynchro(void)
129 {
130 RTC_TypeDef* RTC = ((RTC_TypeDef *) RTC_BASE);
131 u32 counter = 0;
132 u32 status = 0;
133 u32 synchrostatus = 0x00;
134
135 /* we can not poll RTC_ISR_RSF when RTC_CR_BYPSHAD */
136 if (RTC->CR & RTC_CR_BYPSHAD) {
137 return 1;
138 }
139
140 /* Disable the write protection for RTC registers */
141 RTC->WPR = 0xCA;
142 RTC->WPR = 0x53;
143
144 /* write 1 to Clear RSF flag */
145 RTC->ISR |= RTC_ISR_RSF;
146
147 /* Wait the registers to be synchronised */
148 do {
149 synchrostatus = RTC->ISR & RTC_ISR_RSF; /* 6bus cycle one time */
150 counter++;
151 } while ((counter != SYNCHRO_TIMEOUT) && (synchrostatus == 0x00));
152
153 if (RTC->ISR & RTC_ISR_RSF) {
154 status = 1;
155 } else {
156 status = 0;
157 }
158
159 /* Enable the write protection for RTC registers */
160 RTC->WPR = 0xFF;
161
162 return (status);
163 }
164
165 /**
166 * @brief Enables or Disables the Bypass Shadow feature.
167 * @note When the Bypass Shadow is enabled the calendar value are taken
168 * directly from the Calendar counter.
169 * @param NewState: new state of the Bypass Shadow feature.
170 * This parameter can be: ENABLE or DISABLE.
171 * @retval None
172 */
RTC_BypassShadowCmd(u32 NewState)173 u32 RTC_BypassShadowCmd(u32 NewState)
174 {
175 RTC_TypeDef* RTC = ((RTC_TypeDef *) RTC_BASE);
176 u32 status;
177
178 /* Disable the write protection for RTC registers */
179 RTC->WPR = 0xCA;
180 RTC->WPR = 0x53;
181
182 /* Set Initialization mode */
183 if (RTC_EnterInitMode()) {
184 if (NewState != DISABLE) {
185 /* Set the BYPSHAD bit */
186 RTC->CR |= RTC_CR_BYPSHAD;
187 } else {
188 /* Reset the BYPSHAD bit */
189 RTC->CR &= ~RTC_CR_BYPSHAD;
190 }
191
192 /* Exit Initialization mode */
193 RTC_ExitInitMode();
194
195 if (RTC_WaitForSynchro()) {
196 status = 1;
197 } else {
198 status = 0;
199 }
200 } else {
201 status = 0;
202 }
203
204 /* Enable the write protection for RTC registers */
205 RTC->WPR = 0xFF;
206
207 return status;
208 }
209
210 /**
211 * @brief Fills each RTC_InitStruct member with its default value.
212 * @param RTC_InitStruct: pointer to a RTC_InitTypeDef structure which will be
213 * initialized.
214 * @retval None
215 */
RTC_StructInit(RTC_InitTypeDef * RTC_InitStruct)216 void RTC_StructInit(RTC_InitTypeDef* RTC_InitStruct)
217 {
218 /* Initialize the RTC_HourFormat member */
219 RTC_InitStruct->RTC_HourFormat = RTC_HourFormat_24;
220
221 /* Initialize the RTC_AsynchPrediv member */
222 RTC_InitStruct->RTC_AsynchPrediv = (u32)0x7F; /* 32768 /128 = 256Hz */
223
224 /* Initialize the RTC_SynchPrediv member */
225 RTC_InitStruct->RTC_SynchPrediv = (u32)0xFF; /* 256 /256 = 1Hz*/
226
227 /*Initialize the RTC_Day_Threshold member*/
228 RTC_InitStruct->RTC_DayThreshold = 365;
229 }
230
231 /**
232 * @brief Initializes the RTC registers according to the specified parameters
233 * in RTC_InitStruct.
234 * @param RTC_InitStruct: pointer to a RTC_InitTypeDef structure that contains
235 * the configuration information for the RTC peripheral.
236 * @note The RTC Prescaler register is write protected and can be written in
237 * initialization mode only.
238 * @retval status value:
239 * - 1: RTC registers are initialized
240 * - 0: RTC registers are not initialized
241 */
RTC_Init(RTC_InitTypeDef * RTC_InitStruct)242 u32 RTC_Init(RTC_InitTypeDef* RTC_InitStruct)
243 {
244 RTC_TypeDef* RTC = ((RTC_TypeDef *) RTC_BASE);
245 u32 Temp = 0;
246 u32 status = 0;
247
248 /* Check the parameters */
249 assert_param(IS_RTC_HOUR_FORMAT(RTC_InitStruct->RTC_HourFormat));
250 assert_param(IS_RTC_ASYNCH_PREDIV(RTC_InitStruct->RTC_AsynchPrediv));
251 assert_param(IS_RTC_SYNCH_PREDIV(RTC_InitStruct->RTC_SynchPrediv));
252 assert_param(IS_RTC_DAY_THRES(RTC_InitStruct->RTC_DayThreshold));
253
254 /* Disable the write protection for RTC registers */
255 RTC->WPR = 0xCA;
256 RTC->WPR = 0x53;
257
258 /* Set Initialization mode */
259 if (RTC_EnterInitMode()) {
260 /* Configure the RTC PRER to provide 1Hz to the Calendar */
261 Temp = (RTC_InitStruct->RTC_SynchPrediv) | (RTC_InitStruct->RTC_AsynchPrediv << 16);
262 RTC->PRER = Temp;
263
264 /* Set RTC CR FMT Bit */
265 Temp = RTC->CR;
266 Temp &= ((u32)~(RTC_CR_FMT | RTC_DAYTHRES_MSK | RTC_CR_DOVTHIE));
267 Temp |= ((u32)((RTC_InitStruct->RTC_HourFormat) | (RTC_InitStruct->RTC_DayThreshold<<23)));
268
269 /* Reset the BYPSHAD bit, get counter from shadow registger */
270 Temp &= ~RTC_CR_BYPSHAD;
271 RTC->CR = Temp;
272
273 /* Exit Initialization mode */
274 RTC_ExitInitMode();
275
276 if (RTC_WaitForSynchro()) {
277 status = 1;
278 } else {
279 status = 0;
280 }
281 } else {
282 status = 0;
283 }
284
285 /* Enable the write protection for RTC registers */
286 RTC->WPR = 0xFF;
287
288 return status;
289 }
290
291 /**
292 * @brief Fills each RTC_TimeStruct member with its default value
293 * (Time = 00d:00h:00min:00sec).
294 * @param RTC_TimeStruct: pointer to a RTC_TimeTypeDef structure which will be
295 * initialized.
296 * @retval None
297 */
RTC_TimeStructInit(RTC_TimeTypeDef * RTC_TimeStruct)298 void RTC_TimeStructInit(RTC_TimeTypeDef* RTC_TimeStruct)
299 {
300 /* Time = 00h:00min:00sec */
301 RTC_TimeStruct->RTC_H12_PMAM = RTC_H12_AM;
302 RTC_TimeStruct->RTC_Hours = 0;
303 RTC_TimeStruct->RTC_Minutes = 0;
304 RTC_TimeStruct->RTC_Seconds = 0;
305 RTC_TimeStruct->RTC_Days = 0;
306 }
307
308 /**
309 * @brief Set the RTC current time.
310 * @param RTC_Format: specifies the format of the entered parameters.
311 * This parameter can be one of the following values:
312 * @arg RTC_Format_BIN: Binary data format
313 * @arg RTC_Format_BCD: BCD data format
314 * @param RTC_TimeStruct: pointer to a RTC_TimeTypeDef structure that contains
315 * the time configuration information for the RTC.
316 * @retval status value:
317 * - 1: RTC Time register is configured
318 * - 0: RTC Time register is not configured
319 */
RTC_SetTime(u32 RTC_Format,RTC_TimeTypeDef * RTC_TimeStruct)320 u32 RTC_SetTime(u32 RTC_Format, RTC_TimeTypeDef* RTC_TimeStruct)
321 {
322 RTC_TypeDef* RTC = ((RTC_TypeDef *) RTC_BASE);
323 u32 tmpreg = 0;
324 u32 status = 0;
325
326 /* Check the parameters */
327 assert_param(IS_RTC_FORMAT(RTC_Format));
328
329 if (RTC_Format == RTC_Format_BIN) {
330 if ((RTC->CR & RTC_CR_FMT) != RTC_HourFormat_24) {
331 assert_param(IS_RTC_HOUR12(RTC_TimeStruct->RTC_Hours));
332 assert_param(IS_RTC_H12_AMPM(RTC_TimeStruct->RTC_H12_PMAM));
333 } else {
334 RTC_TimeStruct->RTC_H12_PMAM = 0x00;
335 assert_param(IS_RTC_HOUR24(RTC_TimeStruct->RTC_Hours));
336 }
337 assert_param(IS_RTC_MINUTES(RTC_TimeStruct->RTC_Minutes));
338 assert_param(IS_RTC_SECONDS(RTC_TimeStruct->RTC_Seconds));
339 } else {
340 if ((RTC->CR & RTC_CR_FMT) != RTC_HourFormat_24) {
341 tmpreg = RTC_Bcd2ToByte(RTC_TimeStruct->RTC_Hours);
342 assert_param(IS_RTC_HOUR12(tmpreg));
343 assert_param(IS_RTC_H12_AMPM(RTC_TimeStruct->RTC_H12_PMAM));
344 } else {
345 RTC_TimeStruct->RTC_H12_PMAM = 0x00;
346 assert_param(IS_RTC_HOUR24(RTC_Bcd2ToByte(RTC_TimeStruct->RTC_Hours)));
347 }
348 assert_param(IS_RTC_MINUTES(RTC_Bcd2ToByte(RTC_TimeStruct->RTC_Minutes)));
349 assert_param(IS_RTC_SECONDS(RTC_Bcd2ToByte(RTC_TimeStruct->RTC_Seconds)));
350 }
351
352 /* Check the input parameters format */
353 if (RTC_Format != RTC_Format_BIN) {
354 tmpreg = (((u32)(RTC_TimeStruct->RTC_Hours) << 16) | \
355 ((u32)(RTC_TimeStruct->RTC_Minutes) << 8) | \
356 ((u32)RTC_TimeStruct->RTC_Seconds) | \
357 ((u32)(RTC_TimeStruct->RTC_H12_PMAM) << 22));
358 } else {
359 tmpreg = (u32)(((u32)RTC_ByteToBcd2(RTC_TimeStruct->RTC_Hours) << 16) | \
360 ((u32)RTC_ByteToBcd2(RTC_TimeStruct->RTC_Minutes) << 8) | \
361 ((u32)RTC_ByteToBcd2(RTC_TimeStruct->RTC_Seconds)) | \
362 (((u32)RTC_TimeStruct->RTC_H12_PMAM) << 22));
363 }
364
365 /* set Days */
366 tmpreg |= (u32)(RTC_TimeStruct->RTC_Days) << 23;
367
368 /* Disable the write protection for RTC registers */
369 RTC->WPR = 0xCA;
370 RTC->WPR = 0x53;
371
372 /* Set Initialization mode */
373 if (RTC_EnterInitMode()) {
374 /* Set the RTC_TR register */
375 RTC->TR = (u32)(tmpreg & RTC_TR_RESERVED_MASK);
376
377 /* Exit Initialization mode */
378 RTC_ExitInitMode();
379
380 if (RTC_WaitForSynchro()) {
381 status = 1;
382 } else {
383 status = 0;
384 }
385 } else {
386 status = 0;
387 }
388
389 /* Enable the write protection for RTC registers */
390 RTC->WPR = 0xFF;
391
392 return status;
393 }
394
395 /**
396 * @brief Get the RTC current Time.
397 * @param RTC_Format: specifies the format of the returned parameters.
398 * This parameter can be one of the following values:
399 * @arg RTC_Format_BIN: Binary data format
400 * @arg RTC_Format_BCD: BCD data format
401 * @param RTC_TimeStruct: pointer to a RTC_TimeTypeDef structure that will
402 * contain the returned current time configuration.
403 * @retval None
404 */
RTC_GetTime(u32 RTC_Format,RTC_TimeTypeDef * RTC_TimeStruct)405 void RTC_GetTime(u32 RTC_Format, RTC_TimeTypeDef* RTC_TimeStruct)
406 {
407 RTC_TypeDef* RTC = ((RTC_TypeDef *) RTC_BASE);
408 u32 tmpreg = 0;
409
410 /* Check the parameters */
411 assert_param(IS_RTC_FORMAT(RTC_Format));
412
413 /* Get the RTC_TR register */
414 tmpreg = (u32)(RTC->TR & RTC_TR_RESERVED_MASK);
415
416 /* Fill the structure fields with the read parameters */
417 RTC_TimeStruct->RTC_Hours = (u8)((tmpreg & (RTC_TR_HT | RTC_TR_HU)) >> 16);
418 RTC_TimeStruct->RTC_Minutes = (u8)((tmpreg & (RTC_TR_MNT | RTC_TR_MNU)) >>8);
419 RTC_TimeStruct->RTC_Seconds = (u8)(tmpreg & (RTC_TR_ST | RTC_TR_SU));
420 RTC_TimeStruct->RTC_H12_PMAM = (u8)((tmpreg & (RTC_TR_PM)) >> 22);
421 RTC_TimeStruct->RTC_Days = (u16)((tmpreg & RTC_TR_DAY) >> 23);
422
423 /* Check the input parameters format */
424 if (RTC_Format == RTC_Format_BIN) {
425 /* Convert the structure parameters to Binary format */
426 RTC_TimeStruct->RTC_Hours = (u8)RTC_Bcd2ToByte(RTC_TimeStruct->RTC_Hours);
427 RTC_TimeStruct->RTC_Minutes = (u8)RTC_Bcd2ToByte(RTC_TimeStruct->RTC_Minutes);
428 RTC_TimeStruct->RTC_Seconds = (u8)RTC_Bcd2ToByte(RTC_TimeStruct->RTC_Seconds);
429 }
430 }
431
432 /**
433 * @brief clear day over threshold pending interrupt.
434 * @retval None
435 */
RTC_DayIntClear(void)436 void RTC_DayIntClear(void)
437 {
438 RTC_TypeDef* RTC = ((RTC_TypeDef *) RTC_BASE);
439 u32 isr = RTC->ISR;
440 u32 counter = 0;
441
442 /*not clear alarm flag*/
443 isr &= ~RTC_ISR_ALRAF;
444
445 isr |= RTC_ISR_DOVTHF;
446
447 RTC->ISR = isr;
448
449 while (1) {
450 /* check Alarm flag clear success*/
451 if ((RTC->ISR & RTC_ISR_DOVTHF) == 0)
452 break;
453 if (counter >= ALARMDIS_TIMEOUT)
454 break;
455
456 counter++;
457 }
458
459 /*delay one 32.768k clock cycle for actual interrupt signal clear*/
460 DelayUs(36);
461 }
462
463 /**
464 * @brief Enables or disables the RTC day over threshold interrupt.
465 * @param NewState: new state of the RTC day over threshold interrupt.
466 * This parameter can be: ENABLE or DISABLE.
467 */
RTC_DayIntCmd(u32 NewState)468 u32 RTC_DayIntCmd(u32 NewState)
469 {
470 RTC_TypeDef* RTC = ((RTC_TypeDef *) RTC_BASE);
471 u32 status = 0;
472
473 /* Disable the write protection for RTC registers */
474 RTC->WPR = 0xCA;
475 RTC->WPR = 0x53;
476
477 /* Set Initialization mode */
478 if (RTC_EnterInitMode()) {
479 /* clear isr, or set will fail */
480 RTC_DayIntClear();
481
482 /* Configure the day over threshold interrupt state */
483 if (NewState != DISABLE) {
484 /*enable day over threshold interrupt*/
485 RTC->CR |= (u32)(RTC_CR_DOVTHIE);
486 } else {
487 RTC->CR &= (u32)~(RTC_CR_DOVTHIE);
488 }
489
490 /* Exit Initialization mode */
491 RTC_ExitInitMode();
492
493 if (RTC_WaitForSynchro()) {
494 status = 1;
495 } else {
496 status = 0;
497 }
498 } else {
499 status = 0;
500 }
501
502 /* Enable the write protection for RTC registers */
503 RTC->WPR = 0xFF;
504
505 return status;
506 }
507
508 /**
509 * @brief Set the RTC day threshold.
510 * @param DayThres: specifies the day threshold to be configured.
511 * This parameter can be a value of @ref RTC_Day_Threshold.
512 * @retval status value:
513 * - 1: RTC day threshold is configured
514 * - 0: RTC day threshold is not configured
515 */
RTC_DayThresSet(u32 DayThres)516 u32 RTC_DayThresSet(u32 DayThres)
517 {
518 RTC_TypeDef* RTC = ((RTC_TypeDef *) RTC_BASE);
519 u32 temp = RTC->CR;
520 u32 status;
521
522 assert_param(IS_RTC_DAY_THRES(DayThres));
523
524 temp &= ~RTC_DAYTHRES_MSK;
525 temp |= (u32)((DayThres) << 23);
526
527 /* Disable the write protection for RTC registers */
528 RTC->WPR = 0xCA;
529 RTC->WPR = 0x53;
530
531 /* Set Initialization mode */
532 if (RTC_EnterInitMode()) {
533 /*Set the RTC_CR register*/
534 RTC->CR = temp;
535
536 /* Exit Initialization mode */
537 RTC_ExitInitMode();
538
539 if (RTC_WaitForSynchro()) {
540 status = 1;
541 } else {
542 status = 0;
543 }
544 } else {
545 status = 0;
546 }
547
548 /* Enable the write protection for RTC registers */
549 RTC->WPR = 0xFF;
550
551 return status;
552 }
553
554 /**
555 * @brief Get the RTC day threshold value in RTC_CR register.
556 * @retval RTC day threshold value
557 */
RTC_DayThresGet(void)558 u32 RTC_DayThresGet(void)
559 {
560 RTC_TypeDef* RTC = ((RTC_TypeDef *) RTC_BASE);
561
562 return ((RTC->CR & RTC_DAYTHRES_MSK) >>23);
563 }
564
565 /**
566 * @brief Set the specified RTC Alarm.
567 * @note The Alarm register can only be written when the corresponding Alarm
568 * is disabled (Use the RTC_AlarmCmd(DISABLE)).
569 * @param RTC_Format: specifies the format of the returned parameters.
570 * This parameter can be one of the following values:
571 * @arg RTC_Format_BIN: Binary data format
572 * @arg RTC_Format_BCD: BCD data format
573 * @param RTC_AlarmStruct: pointer to a RTC_AlarmTypeDef structure that
574 * contains the alarm configuration parameters.
575 * @retval status value:
576 * - 1: RTC Time Alarm is configured
577 * - 0: RTC Time Alarm is not configured
578 */
RTC_SetAlarm(u32 RTC_Format,RTC_AlarmTypeDef * RTC_AlarmStruct)579 u32 RTC_SetAlarm(u32 RTC_Format, RTC_AlarmTypeDef* RTC_AlarmStruct)
580 {
581 RTC_TypeDef* RTC = ((RTC_TypeDef *) RTC_BASE);
582 u32 tmpreg = 0;
583 u32 counter = 0;
584 u32 status = 0;
585
586 /* Check the parameters */
587 assert_param(IS_RTC_FORMAT(RTC_Format));
588 assert_param(IS_ALARM_MASK(RTC_AlarmStruct->RTC_AlarmMask));
589 assert_param(IS_ALARM2_MASK(RTC_AlarmStruct->RTC_Alarm2Mask));
590
591 if (RTC_Format == RTC_Format_BIN) {
592 if ((RTC->CR & RTC_CR_FMT) != RTC_HourFormat_24) {
593 assert_param(IS_RTC_HOUR12(RTC_AlarmStruct->RTC_AlarmTime.RTC_Hours));
594 assert_param(IS_RTC_H12_AMPM(RTC_AlarmStruct->RTC_AlarmTime.RTC_H12_PMAM));
595 } else {
596 RTC_AlarmStruct->RTC_AlarmTime.RTC_H12_PMAM = 0x00;
597 assert_param(IS_RTC_HOUR24(RTC_AlarmStruct->RTC_AlarmTime.RTC_Hours));
598 }
599 assert_param(IS_RTC_MINUTES(RTC_AlarmStruct->RTC_AlarmTime.RTC_Minutes));
600 assert_param(IS_RTC_SECONDS(RTC_AlarmStruct->RTC_AlarmTime.RTC_Seconds));
601 } else {
602 if ((RTC->CR & RTC_CR_FMT) != RTC_HourFormat_24) {
603 tmpreg = RTC_Bcd2ToByte(RTC_AlarmStruct->RTC_AlarmTime.RTC_Hours);
604 assert_param(IS_RTC_HOUR12(tmpreg));
605 assert_param(IS_RTC_H12_AMPM(RTC_AlarmStruct->RTC_AlarmTime.RTC_H12_PMAM));
606 } else {
607 RTC_AlarmStruct->RTC_AlarmTime.RTC_H12_PMAM = 0x00;
608 assert_param(IS_RTC_HOUR24(RTC_Bcd2ToByte(RTC_AlarmStruct->RTC_AlarmTime.RTC_Hours)));
609 }
610
611 assert_param(IS_RTC_MINUTES(RTC_Bcd2ToByte(RTC_AlarmStruct->RTC_AlarmTime.RTC_Minutes)));
612 assert_param(IS_RTC_SECONDS(RTC_Bcd2ToByte(RTC_AlarmStruct->RTC_AlarmTime.RTC_Seconds)));
613 }
614
615 /* Check the input parameters format */
616 if (RTC_Format != RTC_Format_BIN) {
617 tmpreg = (((u32)(RTC_AlarmStruct->RTC_AlarmTime.RTC_Hours) << 16) | \
618 ((u32)(RTC_AlarmStruct->RTC_AlarmTime.RTC_Minutes) << 8) | \
619 ((u32)RTC_AlarmStruct->RTC_AlarmTime.RTC_Seconds) | \
620 ((u32)(RTC_AlarmStruct->RTC_AlarmTime.RTC_H12_PMAM) << 22) | \
621 ((u32)RTC_AlarmStruct->RTC_AlarmMask));
622 } else {
623 tmpreg = (((u32)RTC_ByteToBcd2(RTC_AlarmStruct->RTC_AlarmTime.RTC_Hours) << 16) | \
624 ((u32)RTC_ByteToBcd2(RTC_AlarmStruct->RTC_AlarmTime.RTC_Minutes) << 8) | \
625 ((u32)RTC_ByteToBcd2(RTC_AlarmStruct->RTC_AlarmTime.RTC_Seconds)) | \
626 ((u32)(RTC_AlarmStruct->RTC_AlarmTime.RTC_H12_PMAM) << 22) | \
627 ((u32)RTC_AlarmStruct->RTC_AlarmMask));
628 }
629
630 /* Disable the write protection for RTC registers */
631 RTC->WPR = 0xCA;
632 RTC->WPR = 0x53;
633
634 /* Disable Alarm */
635 RTC->CR &= ~RTC_Alarm;
636 while (1) {
637 /* check Alarm update allowed */
638 if (RTC->ISR & RTC_ISR_ALMWF)
639 break;
640 if (counter >= ALARMDIS_TIMEOUT)
641 break;
642
643 counter++;
644 }
645
646 /* clear isr, or set wll fail */
647 RTC->ISR |= RTC_ISR_ALRAF;
648
649 if (RTC->ISR & RTC_ISR_ALMWF) {
650 /* Configure the Alarm1 register H:M:S */
651 RTC->ALMR1L = (u32)tmpreg;
652
653 /* Configure the Alarm2 register D */
654 RTC->ALMR1H = ((u32)RTC_AlarmStruct->RTC_AlarmTime.RTC_Days) | ((u32)RTC_AlarmStruct->RTC_Alarm2Mask);
655
656 status = 1;
657 } else {
658 status = 0;
659 }
660
661 /* Enable Alarm after this function */
662
663 /* Enable the write protection for RTC registers */
664 RTC->WPR = 0xFF;
665
666 return status;
667 }
668
669 /**
670 * @brief Fills each RTC_AlarmStruct member with its default value
671 * (Time = 00d:00h:00mn:20sec / Date = 1st day of the month/Mask =
672 * all fields are masked except Alarm Seconds field).
673 * @param RTC_AlarmStruct: pointer to a @ref RTC_AlarmTypeDef structure which
674 * will be initialized.
675 * @retval None
676 */
RTC_AlarmStructInit(RTC_AlarmTypeDef * RTC_AlarmStruct)677 void RTC_AlarmStructInit(RTC_AlarmTypeDef* RTC_AlarmStruct)
678 {
679 /* Alarm Time Settings : Time = 00h:00mn:00sec */
680 RTC_AlarmStruct->RTC_AlarmTime.RTC_H12_PMAM = RTC_H12_AM;
681 RTC_AlarmStruct->RTC_AlarmTime.RTC_Hours = 0;
682 RTC_AlarmStruct->RTC_AlarmTime.RTC_Minutes = 0;
683 RTC_AlarmStruct->RTC_AlarmTime.RTC_Seconds = 20;
684 RTC_AlarmStruct->RTC_AlarmTime.RTC_Days = 0;
685
686 /* Alarm Masks Settings : Mask = all fields are not masked */
687 RTC_AlarmStruct->RTC_AlarmMask = RTC_AlarmMask_Hours | RTC_AlarmMask_Minutes;
688
689 /* Alarm2 Mask: Day */
690 RTC_AlarmStruct->RTC_Alarm2Mask = RTC_Alarm2Mask_Days;
691 }
692
693 /**
694 * @brief Get the RTC Alarm value and masks.
695 * @param RTC_Format: specifies the format of the output parameters.
696 * This parameter can be one of the following values:
697 * @arg RTC_Format_BIN: Binary data format
698 * @arg RTC_Format_BCD: BCD data format
699 * @param RTC_AlarmStruct: pointer to a RTC_AlarmTypeDef structure that will
700 * contains the output alarm configuration values.
701 * @retval None
702 */
RTC_GetAlarm(u32 RTC_Format,RTC_AlarmTypeDef * RTC_AlarmStruct)703 void RTC_GetAlarm(u32 RTC_Format, RTC_AlarmTypeDef* RTC_AlarmStruct)
704 {
705 RTC_TypeDef* RTC = ((RTC_TypeDef *) RTC_BASE);
706 u32 tmpreg = 0;
707
708 /* Check the parameters */
709 assert_param(IS_RTC_FORMAT(RTC_Format));
710
711 /* Get the RTC_ALRMxR register */
712 tmpreg = (u32)(RTC->ALMR1L);
713
714 /* Fill the structure with the read parameters */
715 RTC_AlarmStruct->RTC_AlarmTime.RTC_Hours = (u8)((tmpreg & (RTC_ALRMAR_HT | RTC_ALRMAR_HU)) >> 16);
716 RTC_AlarmStruct->RTC_AlarmTime.RTC_Minutes = (u8)((tmpreg & (RTC_ALRMAR_MNT | RTC_ALRMAR_MNU)) >> 8);
717 RTC_AlarmStruct->RTC_AlarmTime.RTC_Seconds = (u8)(tmpreg & (RTC_ALRMAR_ST | RTC_ALRMAR_SU));
718 RTC_AlarmStruct->RTC_AlarmTime.RTC_H12_PMAM = (u8)((tmpreg & RTC_ALRMAR_PM) >> 22);
719 RTC_AlarmStruct->RTC_AlarmMask = (u32)(tmpreg & RTC_AlarmMask_All);
720
721 if (RTC_Format == RTC_Format_BIN) {
722 RTC_AlarmStruct->RTC_AlarmTime.RTC_Hours = RTC_Bcd2ToByte(RTC_AlarmStruct->RTC_AlarmTime.RTC_Hours);
723 RTC_AlarmStruct->RTC_AlarmTime.RTC_Minutes = RTC_Bcd2ToByte(RTC_AlarmStruct->RTC_AlarmTime.RTC_Minutes);
724 RTC_AlarmStruct->RTC_AlarmTime.RTC_Seconds = RTC_Bcd2ToByte(RTC_AlarmStruct->RTC_AlarmTime.RTC_Seconds);
725 }
726
727 /* Get Days */
728 RTC_AlarmStruct->RTC_AlarmTime.RTC_Days = (u16)((RTC->ALMR1H) & RTC_ALRMBR_DT);
729 RTC_AlarmStruct->RTC_Alarm2Mask = (u32)((RTC->ALMR1H) & RTC_ALRMBR_MSK3);
730 }
731
732 /**
733 * @brief Enables or disables the specified RTC Alarm.
734 * @param NewState: new state of the specified alarm.
735 * This parameter can be: ENABLE or DISABLE.
736 */
RTC_AlarmCmd(u32 NewState)737 void RTC_AlarmCmd(u32 NewState)
738 {
739 RTC_TypeDef* RTC = ((RTC_TypeDef *) RTC_BASE);
740 u32 counter = 0;
741
742 /* Disable the write protection for RTC registers */
743 RTC->WPR = 0xCA;
744 RTC->WPR = 0x53;
745
746 /* Configure the Alarm state */
747 if (NewState != DISABLE) {
748 RTC->ISR |= RTC_ISR_ALRAF;
749
750 RTC->CR |= (u32)(RTC_Alarm | RTC_Alarm_IntEn);
751
752 /* we should wait shadow reigster sync ok */
753 RTC_WaitForSynchro();
754 } else {
755 /* clear isr, or set will fail */
756 RTC->ISR |= RTC_ISR_ALRAF;
757
758 /* Disable the Alarm in RTC_CR register */
759 RTC->CR &= (u32)~(RTC_Alarm | RTC_Alarm_IntEn);
760
761 /* wait alarm disable */
762 while (1) {
763 /* check Alarm update allowed */
764 if (RTC->ISR & RTC_ISR_ALMWF)
765 break;
766 if (counter >= ALARMDIS_TIMEOUT)
767 break;
768
769 counter++;
770 }
771 }
772
773 /* Enable the write protection for RTC registers */
774 RTC->WPR = 0xFF;
775 }
776
777 /**
778 * @brief clear alarm pending interrupt.
779 * @retval None
780 */
RTC_AlarmClear(void)781 void RTC_AlarmClear(void)
782 {
783 RTC_TypeDef* RTC = ((RTC_TypeDef *) RTC_BASE);
784 u32 isr = RTC->ISR;
785 u32 counter = 0;
786
787 /*not clear day over thres flag*/
788 isr &= ~RTC_ISR_DOVTHF;
789
790 isr |= RTC_ISR_ALRAF;
791
792 RTC->ISR = isr;
793
794 while (1) {
795 /* check Alarm flag clear success*/
796 if ((RTC->ISR & RTC_ISR_ALRAF) == 0)
797 break;
798 if (counter >= ALARMDIS_TIMEOUT)
799 break;
800
801 counter++;
802 }
803
804 /*delay one 32.768k clock cycle for actual interrupt signal clear*/
805 DelayUs(36);
806 }
807
808 /**
809 * @brief Adds or substract one hour from the current time.
810 * @param RTC_DayLightSaving: the value of hour adjustment.
811 * This parameter can be one of the following values:
812 * @arg RTC_DayLightSaving_SUB1H: Substract one hour (winter time)
813 * @arg RTC_DayLightSaving_ADD1H: Add one hour (summer time)
814 * @param RTC_StoreOperation: Specifies the value to be written in the BCK bit
815 * in CR register to store the operation.
816 * This parameter can be one of the following values:
817 * @arg RTC_StoreOperation_Reset: BCK Bit Reset
818 * @arg RTC_StoreOperation_Set: BCK Bit Set
819 * @retval None
820 */
RTC_DayLightSavingConfig(u32 RTC_DayLightSaving,u32 RTC_StoreOperation)821 u32 RTC_DayLightSavingConfig(u32 RTC_DayLightSaving, u32 RTC_StoreOperation)
822 {
823 RTC_TypeDef* RTC = ((RTC_TypeDef *) RTC_BASE);
824 u32 CRTmp = RTC->CR;
825 u32 status = 0;
826
827 /* Check the parameters */
828 assert_param(IS_RTC_DAYLIGHT_SAVING(RTC_DayLightSaving));
829 assert_param(IS_RTC_STORE_OPERATION(RTC_StoreOperation));
830
831 /* Disable the write protection for RTC registers */
832 RTC->WPR = 0xCA;
833 RTC->WPR = 0x53;
834
835 /* Clear the bits to be configured */
836 CRTmp &= (u32)~(RTC_CR_BCK);
837
838 /* Configure the RTC_CR register */
839 CRTmp |= (u32)(RTC_DayLightSaving | RTC_StoreOperation);
840
841 /* Set Initialization mode */
842 if (RTC_EnterInitMode()) {
843 /* write CR */
844 RTC->CR = CRTmp;
845
846 /* Exit Initialization mode */
847 RTC_ExitInitMode();
848
849 if (RTC_WaitForSynchro()) {
850 status = 1;
851 } else {
852 status = 0;
853 }
854 } else {
855 status = 0;
856 }
857
858 /* Enable the write protection for RTC registers */
859 RTC->WPR = 0xFF;
860
861 //RTC_WaitForSynchro();
862
863 return status;
864 }
865
866 /**
867 * @brief Returns the RTC Day Light Saving stored operation.
868 * @retval RTC Day Light Saving stored operation.
869 * - RTC_StoreOperation_Reset
870 * - RTC_StoreOperation_Set
871 */
RTC_GetStoreOperation(void)872 u32 RTC_GetStoreOperation(void)
873 {
874 RTC_TypeDef* RTC = ((RTC_TypeDef *) RTC_BASE);
875
876 return (RTC->CR & RTC_CR_BCK);
877 }
878
879 /**
880 * @brief Configures the RTC output.
881 * @param RTC_Output: Specifies which signal will be routed to the RTC output.
882 * This parameter can be one of the following values:
883 * @arg RTC_Output_Disable: No output selected
884 * @arg RTC_Output_Alarm: signal of Alarm mapped to output
885 * @arg RTC_Output_clkspre: signal of clkspre mapped to output
886 * @arg RTC_Output_clkapre: signal of clkapre mapped to output
887 * @retval None
888 */
RTC_OutputConfig(u32 RTC_Output)889 u32 RTC_OutputConfig(u32 RTC_Output)
890 {
891 RTC_TypeDef* RTC = ((RTC_TypeDef *) RTC_BASE);
892 u32 CRTmp = RTC->CR;
893 u32 status;
894
895 /* Check the parameters */
896 assert_param(IS_RTC_OUTPUT(RTC_Output));
897
898 /* Disable the write protection for RTC registers */
899 RTC->WPR = 0xCA;
900 RTC->WPR = 0x53;
901
902 /* Clear the bits to be configured */
903 CRTmp &= (u32)~(RTC_CR_OSEL);
904
905 /* Configure the output selection and polarity */
906 CRTmp |= (u32)(RTC_Output);
907
908 /* Set Initialization mode */
909 if (RTC_EnterInitMode()) {
910 /* write CR */
911 RTC->CR = CRTmp;
912
913 /* Exit Initialization mode */
914 RTC_ExitInitMode();
915
916 if (RTC_WaitForSynchro()) {
917 status = 1;
918 } else {
919 status = 0;
920 }
921 } else {
922 status = 0;
923 }
924
925 /* Enable the write protection for RTC registers */
926 RTC->WPR = 0xFF;
927
928 return status;
929 }
930
931 /**
932 * @brief Configures the Coarse calibration parameters.
933 * @param CalibSign: CalibSign specifies the sign of the coarse calibration value.
934 * This parameter can be one of the following values:
935 * @arg RTC_CalibSign_Positive: The value sign is positive
936 * @arg RTC_CalibSign_Negative: The value sign is negative
937 * @param Value: value of coarse calibration expressed in ppm (coded on 7 bits).
938 * @param CalibPeriod: Calibration period, Compensate DC clkapre cycles every (CALP+1) minutes (coded on 3 bits).
939 * This parameter can be one of the following values:
940 * @arg RTC_CalibPeriod_1MIN
941 * @arg RTC_CalibPeriod_2MIN
942 * @arg RTC_CalibPeriod_3MIN
943 * @arg RTC_CalibPeriod_4MIN
944 * @arg RTC_CalibPeriod_5MIN
945 * @arg RTC_CalibPeriod_6MIN
946 * @arg RTC_CalibPeriod_7MIN
947 * @arg RTC_CalibPeriod_8MIN
948 * @param Calib_Enable: RTC_Calib_Disable or RTC_Calib_Enable .
949 * @retval status value:
950 * - 1: RTC Coarse calibration are initialized
951 * - 0: RTC Coarse calibration are not initialized
952 */
RTC_SmoothCalibConfig(u32 CalibSign,u32 Value,u32 CalibPeriod,u32 Calib_Enable)953 u32 RTC_SmoothCalibConfig(u32 CalibSign, u32 Value, u32 CalibPeriod, u32 Calib_Enable)
954 {
955 RTC_TypeDef* RTC = ((RTC_TypeDef *) RTC_BASE);
956 u32 counter = 0;
957 u32 status = 0;
958 u32 temp = 0;
959
960 /* Check the parameters */
961 assert_param(IS_RTC_CALIB_SIGN(CalibSign));
962 assert_param(IS_RTC_CALIB_VALUE(Value));
963 assert_param(IS_RTC_CALIB_PERIOD(CalibPeriod));
964 assert_param(IS_RTC_CALIB_ENABLE(Calib_Enable));
965
966 /* Disable the write protection for RTC registers */
967 RTC->WPR = 0xCA;
968 RTC->WPR = 0x53;
969
970 /* check if a calibration is pending*/
971 /* wait until the Calibration is completed*/
972 while (1) {
973 temp = RTC->ISR;
974
975 if ((temp & RTC_ISR_RECALPF) == 0)
976 break;
977 if (counter >= RECALPF_TIMEOUT)
978 break;
979
980 counter++;
981 }
982
983 /* check if the calibration pending is completed or if there is no calibration operation at all*/
984 if ((RTC->ISR & RTC_ISR_RECALPF) == 0) {
985 if (Calib_Enable == RTC_Calib_Disable) {
986 RTC->CALIBR &= ~RTC_Calib_Enable;
987 } else {
988 RTC->CALIBR = (u32)(Value | CalibSign | Calib_Enable | CalibPeriod);
989 }
990 status = 1;
991 } else {
992 status = 0;
993 }
994
995 /* Enable the write protection for RTC registers */
996 RTC->WPR = 0xFF;
997
998 return status;
999 }
1000
1001 /**
1002 * @brief Configures the 32K auto calibration parameters.
1003 * @param Cal_Period: value of auto calibration period (coded on 6 bits), unit is based on Unit_Sel.
1004 * @param Unit_Sel: Autocal_sel specifies the sign of the auto calibration.
1005 * This parameter can be one of the following values:
1006 * @arg RTC_32K_AUTOCAL_DISABLE: The auto calibration counter is disable
1007 * @arg RTC_32K_AUTOCAL_MINUTES: The auto calibration counter update per minute
1008 * @arg RTC_32K_AUTOCAL_HOURS: The auto calibration counter update per hour
1009 * @arg RTC_32K_AUTOCAL_DAYS: The auto calibration counter update per day
1010 * @retval status value:
1011 * - 1: RTC 32K auto calibration are configured ok
1012 * - 0: RTC 32K auto calibration are configured fail
1013 * @note:
1014 * - RTC ACAL_CNT[5:0] will be cleared by hardware
1015 */
RTC_32KAutoCalibConfig(u32 Cal_Period,u32 Unit_Sel)1016 u32 RTC_32KAutoCalibConfig(u32 Cal_Period, u32 Unit_Sel)
1017 {
1018 RTC_TypeDef* RTC = ((RTC_TypeDef *) RTC_BASE);
1019 u32 clkacalr = 0;
1020 u32 status;
1021
1022 /* Check the parameters */
1023 assert_param(IS_RTC_32K_AUTOCALIB_THRES(Cal_Period));
1024 assert_param(IS_RTC_32K_AUTOCAL_SIGN(Unit_Sel));
1025 if (Unit_Sel != RTC_32K_AUTOCAL_DISABLE)
1026 assert_param((Cal_Period) > 0);
1027
1028 clkacalr |= (u32)(((Cal_Period)<< 2) | Unit_Sel);
1029
1030 /* Disable the write protection for RTC registers */
1031 RTC->WPR = 0xCA;
1032 RTC->WPR = 0x53;
1033
1034 /* Set Initialization mode */
1035 if (RTC_EnterInitMode()) {
1036 /*Write CLKACALR */
1037 RTC->CLKACALR = clkacalr;
1038
1039 /* Exit Initialization mode */
1040 RTC_ExitInitMode();
1041
1042 /*Wait shadow reigster sync ok, then ACAL_CNT[5:0] will be cleared by hardware */
1043 if (RTC_WaitForSynchro()) {
1044 status = 1;
1045 } else {
1046 status = 0;
1047 }
1048 } else {
1049 status = 0;
1050 }
1051
1052 /* Enable the write protection for RTC registers */
1053 RTC->WPR = 0xFF;
1054
1055 return status;
1056 }
1057
1058 /******************* (C) COPYRIGHT 2016 Realtek Semiconductor *****END OF FILE****/
1059