1 /**
2 ******************************************************************************
3 * @file stm32f1xx_ll_rtc.c
4 * @author MCD Application Team
5 * @brief RTC LL module driver.
6 ******************************************************************************
7 * @attention
8 *
9 * <h2><center>© Copyright (c) 2016 STMicroelectronics.
10 * All rights reserved.</center></h2>
11 *
12 * This software component is licensed by ST under BSD 3-Clause license,
13 * the "License"; You may not use this file except in compliance with the
14 * License. You may obtain a copy of the License at:
15 * opensource.org/licenses/BSD-3-Clause
16 *
17 ******************************************************************************
18 */
19
20 #if defined(USE_FULL_LL_DRIVER)
21
22 /* Includes ------------------------------------------------------------------*/
23 #include "stm32f1xx_ll_rtc.h"
24 #include "stm32f1xx_ll_cortex.h"
25 #ifdef USE_FULL_ASSERT
26 #include "stm32_assert.h"
27 #else
28 #define assert_param(expr) ((void)0U)
29 #endif
30
31 /** @addtogroup STM32F1xx_LL_Driver
32 * @{
33 */
34
35 #if defined(RTC)
36
37 /** @addtogroup RTC_LL
38 * @{
39 */
40
41 /* Private types -------------------------------------------------------------*/
42 /* Private variables ---------------------------------------------------------*/
43 /* Private constants ---------------------------------------------------------*/
44 /** @addtogroup RTC_LL_Private_Constants
45 * @{
46 */
47 /* Default values used for prescaler */
48 #define RTC_ASYNCH_PRESC_DEFAULT 0x00007FFFU
49
50 /* Values used for timeout */
51 #define RTC_INITMODE_TIMEOUT 1000U /* 1s when tick set to 1ms */
52 #define RTC_SYNCHRO_TIMEOUT 1000U /* 1s when tick set to 1ms */
53 /**
54 * @}
55 */
56
57 /* Private macros ------------------------------------------------------------*/
58 /** @addtogroup RTC_LL_Private_Macros
59 * @{
60 */
61
62 #define IS_LL_RTC_ASYNCH_PREDIV(__VALUE__) ((__VALUE__) <= 0xFFFFFU)
63
64 #define IS_LL_RTC_FORMAT(__VALUE__) (((__VALUE__) == LL_RTC_FORMAT_BIN) \
65 || ((__VALUE__) == LL_RTC_FORMAT_BCD))
66
67 #define IS_LL_RTC_HOUR24(__HOUR__) ((__HOUR__) <= 23U)
68 #define IS_LL_RTC_MINUTES(__MINUTES__) ((__MINUTES__) <= 59U)
69 #define IS_LL_RTC_SECONDS(__SECONDS__) ((__SECONDS__) <= 59U)
70 #define IS_LL_RTC_CALIB_OUTPUT(__OUTPUT__) (((__OUTPUT__) == LL_RTC_CALIB_OUTPUT_NONE) || \
71 ((__OUTPUT__) == LL_RTC_CALIB_OUTPUT_RTCCLOCK) || \
72 ((__OUTPUT__) == LL_RTC_CALIB_OUTPUT_ALARM) || \
73 ((__OUTPUT__) == LL_RTC_CALIB_OUTPUT_SECOND))
74 /**
75 * @}
76 */
77 /* Private function prototypes -----------------------------------------------*/
78 /* Exported functions --------------------------------------------------------*/
79 /** @addtogroup RTC_LL_Exported_Functions
80 * @{
81 */
82
83 /** @addtogroup RTC_LL_EF_Init
84 * @{
85 */
86
87 /**
88 * @brief De-Initializes the RTC registers to their default reset values.
89 * @note This function doesn't reset the RTC Clock source and RTC Backup Data
90 * registers.
91 * @param RTCx RTC Instance
92 * @retval An ErrorStatus enumeration value:
93 * - SUCCESS: RTC registers are de-initialized
94 * - ERROR: RTC registers are not de-initialized
95 */
LL_RTC_DeInit(RTC_TypeDef * RTCx)96 ErrorStatus LL_RTC_DeInit(RTC_TypeDef *RTCx)
97 {
98 ErrorStatus status = ERROR;
99
100 /* Check the parameter */
101 assert_param(IS_RTC_ALL_INSTANCE(RTCx));
102
103 /* Disable the write protection for RTC registers */
104 LL_RTC_DisableWriteProtection(RTCx);
105
106 /* Set Initialization mode */
107 if (LL_RTC_EnterInitMode(RTCx) != ERROR)
108 {
109 LL_RTC_WriteReg(RTCx, CNTL, 0x0000);
110 LL_RTC_WriteReg(RTCx, CNTH, 0x0000);
111 LL_RTC_WriteReg(RTCx, PRLH, 0x0000);
112 LL_RTC_WriteReg(RTCx, PRLL, 0x8000);
113 LL_RTC_WriteReg(RTCx, CRH, 0x0000);
114 LL_RTC_WriteReg(RTCx, CRL, 0x0020);
115
116 /* Reset Tamper and alternate functions configuration register */
117 LL_RTC_WriteReg(BKP, RTCCR, 0x00000000U);
118 LL_RTC_WriteReg(BKP, CR, 0x00000000U);
119 LL_RTC_WriteReg(BKP, CSR, 0x00000000U);
120
121 /* Exit Initialization Mode */
122 if (LL_RTC_ExitInitMode(RTCx) != ERROR)
123 {
124 /* Wait till the RTC RSF flag is set */
125 status = LL_RTC_WaitForSynchro(RTCx);
126
127 /* Clear RSF Flag */
128 LL_RTC_ClearFlag_RS(RTCx);
129
130 /* Enable the write protection for RTC registers */
131 LL_RTC_EnableWriteProtection(RTCx);
132 }
133 }
134 else
135 {
136 /* Enable the write protection for RTC registers */
137 LL_RTC_EnableWriteProtection(RTCx);
138 }
139
140 return status;
141 }
142
143 /**
144 * @brief Initializes the RTC registers according to the specified parameters
145 * in RTC_InitStruct.
146 * @param RTCx RTC Instance
147 * @param RTC_InitStruct pointer to a @ref LL_RTC_InitTypeDef structure that contains
148 * the configuration information for the RTC peripheral.
149 * @note The RTC Prescaler register is write protected and can be written in
150 * initialization mode only.
151 * @note the user should call LL_RTC_StructInit() or the structure of Prescaler
152 * need to be initialized before RTC init()
153 * @retval An ErrorStatus enumeration value:
154 * - SUCCESS: RTC registers are initialized
155 * - ERROR: RTC registers are not initialized
156 */
LL_RTC_Init(RTC_TypeDef * RTCx,LL_RTC_InitTypeDef * RTC_InitStruct)157 ErrorStatus LL_RTC_Init(RTC_TypeDef *RTCx, LL_RTC_InitTypeDef *RTC_InitStruct)
158 {
159 ErrorStatus status = ERROR;
160
161 /* Check the parameters */
162 assert_param(IS_RTC_ALL_INSTANCE(RTCx));
163 assert_param(IS_LL_RTC_ASYNCH_PREDIV(RTC_InitStruct->AsynchPrescaler));
164 assert_param(IS_LL_RTC_CALIB_OUTPUT(RTC_InitStruct->OutPutSource));
165 /* Waiting for synchro */
166 if (LL_RTC_WaitForSynchro(RTCx) != ERROR)
167 {
168 /* Set Initialization mode */
169 if (LL_RTC_EnterInitMode(RTCx) != ERROR)
170 {
171 /* Clear Flag Bits */
172 LL_RTC_ClearFlag_ALR(RTCx);
173 LL_RTC_ClearFlag_OW(RTCx);
174 LL_RTC_ClearFlag_SEC(RTCx);
175
176 if (RTC_InitStruct->OutPutSource != LL_RTC_CALIB_OUTPUT_NONE)
177 {
178 /* Disable the selected Tamper Pin */
179 LL_RTC_TAMPER_Disable(BKP);
180 }
181 /* Set the signal which will be routed to RTC Tamper Pin */
182 LL_RTC_SetOutputSource(BKP, RTC_InitStruct->OutPutSource);
183
184 /* Configure Synchronous and Asynchronous prescaler factor */
185 LL_RTC_SetAsynchPrescaler(RTCx, RTC_InitStruct->AsynchPrescaler);
186
187 /* Exit Initialization Mode */
188 LL_RTC_ExitInitMode(RTCx);
189
190 status = SUCCESS;
191 }
192 }
193 return status;
194 }
195
196 /**
197 * @brief Set each @ref LL_RTC_InitTypeDef field to default value.
198 * @param RTC_InitStruct pointer to a @ref LL_RTC_InitTypeDef structure which will be initialized.
199 * @retval None
200 */
LL_RTC_StructInit(LL_RTC_InitTypeDef * RTC_InitStruct)201 void LL_RTC_StructInit(LL_RTC_InitTypeDef *RTC_InitStruct)
202 {
203 /* Set RTC_InitStruct fields to default values */
204 RTC_InitStruct->AsynchPrescaler = RTC_ASYNCH_PRESC_DEFAULT;
205 RTC_InitStruct->OutPutSource = LL_RTC_CALIB_OUTPUT_NONE;
206 }
207
208 /**
209 * @brief Set the RTC current time.
210 * @param RTCx RTC Instance
211 * @param RTC_Format This parameter can be one of the following values:
212 * @arg @ref LL_RTC_FORMAT_BIN
213 * @arg @ref LL_RTC_FORMAT_BCD
214 * @param RTC_TimeStruct pointer to a RTC_TimeTypeDef structure that contains
215 * the time configuration information for the RTC.
216 * @note The user should call LL_RTC_TIME_StructInit() or the structure
217 * of time need to be initialized before time init()
218 * @retval An ErrorStatus enumeration value:
219 * - SUCCESS: RTC Time register is configured
220 * - ERROR: RTC Time register is not configured
221 */
LL_RTC_TIME_Init(RTC_TypeDef * RTCx,uint32_t RTC_Format,LL_RTC_TimeTypeDef * RTC_TimeStruct)222 ErrorStatus LL_RTC_TIME_Init(RTC_TypeDef *RTCx, uint32_t RTC_Format, LL_RTC_TimeTypeDef *RTC_TimeStruct)
223 {
224 ErrorStatus status = ERROR;
225 uint32_t counter_time = 0U;
226
227 /* Check the parameters */
228 assert_param(IS_RTC_ALL_INSTANCE(RTCx));
229 assert_param(IS_LL_RTC_FORMAT(RTC_Format));
230
231 if (RTC_Format == LL_RTC_FORMAT_BIN)
232 {
233 assert_param(IS_LL_RTC_HOUR24(RTC_TimeStruct->Hours));
234 assert_param(IS_LL_RTC_MINUTES(RTC_TimeStruct->Minutes));
235 assert_param(IS_LL_RTC_SECONDS(RTC_TimeStruct->Seconds));
236 }
237 else
238 {
239 assert_param(IS_LL_RTC_HOUR24(__LL_RTC_CONVERT_BCD2BIN(RTC_TimeStruct->Hours)));
240 assert_param(IS_LL_RTC_MINUTES(__LL_RTC_CONVERT_BCD2BIN(RTC_TimeStruct->Minutes)));
241 assert_param(IS_LL_RTC_SECONDS(__LL_RTC_CONVERT_BCD2BIN(RTC_TimeStruct->Seconds)));
242 }
243
244 /* Enter Initialization mode */
245 if (LL_RTC_EnterInitMode(RTCx) != ERROR)
246 {
247 /* Check the input parameters format */
248 if (RTC_Format == LL_RTC_FORMAT_BIN)
249 {
250 counter_time = (uint32_t)(((uint32_t)RTC_TimeStruct->Hours * 3600U) + \
251 ((uint32_t)RTC_TimeStruct->Minutes * 60U) + \
252 ((uint32_t)RTC_TimeStruct->Seconds));
253 LL_RTC_TIME_Set(RTCx, counter_time);
254 }
255 else
256 {
257 counter_time = (((uint32_t)(__LL_RTC_CONVERT_BCD2BIN(RTC_TimeStruct->Hours)) * 3600U) + \
258 ((uint32_t)(__LL_RTC_CONVERT_BCD2BIN(RTC_TimeStruct->Minutes)) * 60U) + \
259 ((uint32_t)(__LL_RTC_CONVERT_BCD2BIN(RTC_TimeStruct->Seconds))));
260 LL_RTC_TIME_Set(RTCx, counter_time);
261 }
262 status = SUCCESS;
263 }
264 /* Exit Initialization mode */
265 LL_RTC_ExitInitMode(RTCx);
266
267 return status;
268 }
269
270 /**
271 * @brief Set each @ref LL_RTC_TimeTypeDef field to default value (Time = 00h:00min:00sec).
272 * @param RTC_TimeStruct pointer to a @ref LL_RTC_TimeTypeDef structure which will be initialized.
273 * @retval None
274 */
LL_RTC_TIME_StructInit(LL_RTC_TimeTypeDef * RTC_TimeStruct)275 void LL_RTC_TIME_StructInit(LL_RTC_TimeTypeDef *RTC_TimeStruct)
276 {
277 /* Time = 00h:00min:00sec */
278 RTC_TimeStruct->Hours = 0U;
279 RTC_TimeStruct->Minutes = 0U;
280 RTC_TimeStruct->Seconds = 0U;
281 }
282
283 /**
284 * @brief Set the RTC Alarm.
285 * @param RTCx RTC Instance
286 * @param RTC_Format This parameter can be one of the following values:
287 * @arg @ref LL_RTC_FORMAT_BIN
288 * @arg @ref LL_RTC_FORMAT_BCD
289 * @param RTC_AlarmStruct pointer to a @ref LL_RTC_AlarmTypeDef structure that
290 * contains the alarm configuration parameters.
291 * @note the user should call LL_RTC_ALARM_StructInit() or the structure
292 * of Alarm need to be initialized before Alarm init()
293 * @retval An ErrorStatus enumeration value:
294 * - SUCCESS: ALARM registers are configured
295 * - ERROR: ALARM registers are not configured
296 */
LL_RTC_ALARM_Init(RTC_TypeDef * RTCx,uint32_t RTC_Format,LL_RTC_AlarmTypeDef * RTC_AlarmStruct)297 ErrorStatus LL_RTC_ALARM_Init(RTC_TypeDef *RTCx, uint32_t RTC_Format, LL_RTC_AlarmTypeDef *RTC_AlarmStruct)
298 {
299 ErrorStatus status = ERROR;
300 uint32_t counter_alarm = 0U;
301 /* Check the parameters */
302 assert_param(IS_RTC_ALL_INSTANCE(RTCx));
303 assert_param(IS_LL_RTC_FORMAT(RTC_Format));
304
305 if (RTC_Format == LL_RTC_FORMAT_BIN)
306 {
307 assert_param(IS_LL_RTC_HOUR24(RTC_AlarmStruct->AlarmTime.Hours));
308 assert_param(IS_LL_RTC_MINUTES(RTC_AlarmStruct->AlarmTime.Minutes));
309 assert_param(IS_LL_RTC_SECONDS(RTC_AlarmStruct->AlarmTime.Seconds));
310 }
311 else
312 {
313 assert_param(IS_LL_RTC_HOUR24(__LL_RTC_CONVERT_BCD2BIN(RTC_AlarmStruct->AlarmTime.Hours)));
314 assert_param(IS_LL_RTC_MINUTES(__LL_RTC_CONVERT_BCD2BIN(RTC_AlarmStruct->AlarmTime.Minutes)));
315 assert_param(IS_LL_RTC_SECONDS(__LL_RTC_CONVERT_BCD2BIN(RTC_AlarmStruct->AlarmTime.Seconds)));
316 }
317
318 /* Enter Initialization mode */
319 if (LL_RTC_EnterInitMode(RTCx) != ERROR)
320 {
321 /* Check the input parameters format */
322 if (RTC_Format == LL_RTC_FORMAT_BIN)
323 {
324 counter_alarm = (uint32_t)(((uint32_t)RTC_AlarmStruct->AlarmTime.Hours * 3600U) + \
325 ((uint32_t)RTC_AlarmStruct->AlarmTime.Minutes * 60U) + \
326 ((uint32_t)RTC_AlarmStruct->AlarmTime.Seconds));
327 LL_RTC_ALARM_Set(RTCx, counter_alarm);
328 }
329 else
330 {
331 counter_alarm = (((uint32_t)(__LL_RTC_CONVERT_BCD2BIN(RTC_AlarmStruct->AlarmTime.Hours)) * 3600U) + \
332 ((uint32_t)(__LL_RTC_CONVERT_BCD2BIN(RTC_AlarmStruct->AlarmTime.Minutes)) * 60U) + \
333 ((uint32_t)(__LL_RTC_CONVERT_BCD2BIN(RTC_AlarmStruct->AlarmTime.Seconds))));
334 LL_RTC_ALARM_Set(RTCx, counter_alarm);
335 }
336 status = SUCCESS;
337 }
338 /* Exit Initialization mode */
339 LL_RTC_ExitInitMode(RTCx);
340
341 return status;
342 }
343
344 /**
345 * @brief Set each @ref LL_RTC_AlarmTypeDef of ALARM field to default value (Time = 00h:00mn:00sec /
346 * Day = 1st day of the month/Mask = all fields are masked).
347 * @param RTC_AlarmStruct pointer to a @ref LL_RTC_AlarmTypeDef structure which will be initialized.
348 * @retval None
349 */
LL_RTC_ALARM_StructInit(LL_RTC_AlarmTypeDef * RTC_AlarmStruct)350 void LL_RTC_ALARM_StructInit(LL_RTC_AlarmTypeDef *RTC_AlarmStruct)
351 {
352 /* Alarm Time Settings : Time = 00h:00mn:00sec */
353 RTC_AlarmStruct->AlarmTime.Hours = 0U;
354 RTC_AlarmStruct->AlarmTime.Minutes = 0U;
355 RTC_AlarmStruct->AlarmTime.Seconds = 0U;
356 }
357
358 /**
359 * @brief Enters the RTC Initialization mode.
360 * @param RTCx RTC Instance
361 * @retval An ErrorStatus enumeration value:
362 * - SUCCESS: RTC is in Init mode
363 * - ERROR: RTC is not in Init mode
364 */
LL_RTC_EnterInitMode(RTC_TypeDef * RTCx)365 ErrorStatus LL_RTC_EnterInitMode(RTC_TypeDef *RTCx)
366 {
367 __IO uint32_t timeout = RTC_INITMODE_TIMEOUT;
368 ErrorStatus status = SUCCESS;
369 uint32_t tmp = 0U;
370
371 /* Check the parameter */
372 assert_param(IS_RTC_ALL_INSTANCE(RTCx));
373
374 /* Wait till RTC is in INIT state and if Time out is reached exit */
375 tmp = LL_RTC_IsActiveFlag_RTOF(RTCx);
376 while ((timeout != 0U) && (tmp != 1U))
377 {
378 if (LL_SYSTICK_IsActiveCounterFlag() == 1U)
379 {
380 timeout --;
381 }
382 tmp = LL_RTC_IsActiveFlag_RTOF(RTCx);
383 if (timeout == 0U)
384 {
385 status = ERROR;
386 }
387 }
388
389 /* Disable the write protection for RTC registers */
390 LL_RTC_DisableWriteProtection(RTCx);
391
392 return status;
393 }
394
395 /**
396 * @brief Exit the RTC Initialization mode.
397 * @note When the initialization sequence is complete, the calendar restarts
398 * counting after 4 RTCCLK cycles.
399 * @param RTCx RTC Instance
400 * @retval An ErrorStatus enumeration value:
401 * - SUCCESS: RTC exited from in Init mode
402 * - ERROR: Not applicable
403 */
LL_RTC_ExitInitMode(RTC_TypeDef * RTCx)404 ErrorStatus LL_RTC_ExitInitMode(RTC_TypeDef *RTCx)
405 {
406 __IO uint32_t timeout = RTC_INITMODE_TIMEOUT;
407 ErrorStatus status = SUCCESS;
408 uint32_t tmp = 0U;
409
410 /* Check the parameter */
411 assert_param(IS_RTC_ALL_INSTANCE(RTCx));
412
413 /* Disable initialization mode */
414 LL_RTC_EnableWriteProtection(RTCx);
415
416 /* Wait till RTC is in INIT state and if Time out is reached exit */
417 tmp = LL_RTC_IsActiveFlag_RTOF(RTCx);
418 while ((timeout != 0U) && (tmp != 1U))
419 {
420 if (LL_SYSTICK_IsActiveCounterFlag() == 1U)
421 {
422 timeout --;
423 }
424 tmp = LL_RTC_IsActiveFlag_RTOF(RTCx);
425 if (timeout == 0U)
426 {
427 status = ERROR;
428 }
429 }
430 return status;
431 }
432
433 /**
434 * @brief Set the Time Counter
435 * @param RTCx RTC Instance
436 * @param TimeCounter this value can be from 0 to 0xFFFFFFFF
437 * @retval An ErrorStatus enumeration value:
438 * - SUCCESS: RTC Counter register configured
439 * - ERROR: Not applicable
440 */
LL_RTC_TIME_SetCounter(RTC_TypeDef * RTCx,uint32_t TimeCounter)441 ErrorStatus LL_RTC_TIME_SetCounter(RTC_TypeDef *RTCx, uint32_t TimeCounter)
442 {
443 ErrorStatus status = ERROR;
444 /* Check the parameter */
445 assert_param(IS_RTC_ALL_INSTANCE(RTCx));
446
447 /* Enter Initialization mode */
448 if (LL_RTC_EnterInitMode(RTCx) != ERROR)
449 {
450 LL_RTC_TIME_Set(RTCx, TimeCounter);
451 status = SUCCESS;
452 }
453 /* Exit Initialization mode */
454 LL_RTC_ExitInitMode(RTCx);
455
456 return status;
457 }
458
459 /**
460 * @brief Set Alarm Counter.
461 * @param RTCx RTC Instance
462 * @param AlarmCounter this value can be from 0 to 0xFFFFFFFF
463 * @retval An ErrorStatus enumeration value:
464 * - SUCCESS: RTC exited from in Init mode
465 * - ERROR: Not applicable
466 */
LL_RTC_ALARM_SetCounter(RTC_TypeDef * RTCx,uint32_t AlarmCounter)467 ErrorStatus LL_RTC_ALARM_SetCounter(RTC_TypeDef *RTCx, uint32_t AlarmCounter)
468 {
469 ErrorStatus status = ERROR;
470 /* Check the parameter */
471 assert_param(IS_RTC_ALL_INSTANCE(RTCx));
472
473 /* Enter Initialization mode */
474 if (LL_RTC_EnterInitMode(RTCx) != ERROR)
475 {
476 LL_RTC_ALARM_Set(RTCx, AlarmCounter);
477 status = SUCCESS;
478 }
479 /* Exit Initialization mode */
480 LL_RTC_ExitInitMode(RTCx);
481
482 return status;
483 }
484
485 /**
486 * @brief Waits until the RTC registers are synchronized with RTC APB clock.
487 * @note The RTC Resynchronization mode is write protected, use the
488 * @ref LL_RTC_DisableWriteProtection before calling this function.
489 * @param RTCx RTC Instance
490 * @retval An ErrorStatus enumeration value:
491 * - SUCCESS: RTC registers are synchronised
492 * - ERROR: RTC registers are not synchronised
493 */
LL_RTC_WaitForSynchro(RTC_TypeDef * RTCx)494 ErrorStatus LL_RTC_WaitForSynchro(RTC_TypeDef *RTCx)
495 {
496 __IO uint32_t timeout = RTC_SYNCHRO_TIMEOUT;
497 ErrorStatus status = SUCCESS;
498 uint32_t tmp = 0U;
499
500 /* Check the parameter */
501 assert_param(IS_RTC_ALL_INSTANCE(RTCx));
502
503 /* Clear RSF flag */
504 LL_RTC_ClearFlag_RS(RTCx);
505
506 /* Wait the registers to be synchronised */
507 tmp = LL_RTC_IsActiveFlag_RS(RTCx);
508 while ((timeout != 0U) && (tmp != 0U))
509 {
510 if (LL_SYSTICK_IsActiveCounterFlag() == 1U)
511 {
512 timeout--;
513 }
514 tmp = LL_RTC_IsActiveFlag_RS(RTCx);
515 if (timeout == 0U)
516 {
517 status = ERROR;
518 }
519 }
520
521 return (status);
522 }
523
524 /**
525 * @}
526 */
527
528 /**
529 * @}
530 */
531
532 /**
533 * @}
534 */
535
536 #endif /* defined(RTC) */
537
538 /**
539 * @}
540 */
541
542 #endif /* USE_FULL_LL_DRIVER */
543
544 /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
545