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