1 /**
2 ******************************************************************************
3 * @file stm32f1xx_hal_timebase_rtc_alarm_template.c
4 * @author MCD Application Team
5 * @brief HAL time base based on the hardware RTC_ALARM.
6 *
7 * This file override the native HAL time base functions (defined as weak)
8 * to use the RTC ALARM for time base generation:
9 * + Intializes the RTC peripheral to increment the seconds registers each 1ms
10 * + The alarm is configured to assert an interrupt when the RTC reaches 1ms
11 * + HAL_IncTick is called at each Alarm event and the time is reset to 00:00:00
12 * + HSE (default), LSE or LSI can be selected as RTC clock source
13 @verbatim
14 ==============================================================================
15 ##### How to use this driver #####
16 ==============================================================================
17 [..]
18 This file must be copied to the application folder and modified as follows:
19 (#) Rename it to 'stm32f1xx_hal_timebase_rtc_alarm.c'
20 (#) Add this file and the RTC HAL drivers to your project and uncomment
21 HAL_RTC_MODULE_ENABLED define in stm32f1xx_hal_conf.h
22
23 [..]
24 (@) HAL RTC alarm and HAL RTC wakeup drivers can�t be used with low power modes:
25 The wake up capability of the RTC may be intrusive in case of prior low power mode
26 configuration requiring different wake up sources.
27 Application/Example behavior is no more guaranteed
28 (@) The stm32f1xx_hal_timebase_tim use is recommended for the Applications/Examples
29 requiring low power modes
30
31 @endverbatim
32 ******************************************************************************
33 * @attention
34 *
35 * <h2><center>© Copyright (c) 2017 STMicroelectronics.
36 * All rights reserved.</center></h2>
37 *
38 * This software component is licensed by ST under BSD 3-Clause license,
39 * the "License"; You may not use this file except in compliance with the
40 * License. You may obtain a copy of the License at:
41 * opensource.org/licenses/BSD-3-Clause
42 *
43 ******************************************************************************
44 */
45
46 /* Includes ------------------------------------------------------------------*/
47 #include "stm32f1xx_hal.h"
48 /** @addtogroup STM32F1xx_HAL_Driver
49 * @{
50 */
51
52 /** @defgroup HAL_TimeBase_RTC_Alarm_Template HAL TimeBase RTC Alarm Template
53 * @{
54 */
55
56 /* Private typedef -----------------------------------------------------------*/
57 /* Private define ------------------------------------------------------------*/
58
59 /* Uncomment the line below to select the appropriate RTC Clock source for your application:
60 + RTC_CLOCK_SOURCE_HSE: can be selected for applications requiring timing precision.
61 + RTC_CLOCK_SOURCE_LSE: can be selected for applications with low constraint on timing
62 precision.
63 + RTC_CLOCK_SOURCE_LSI: can be selected for applications with low constraint on timing
64 precision.
65 */
66 #define RTC_CLOCK_SOURCE_HSE
67 /* #define RTC_CLOCK_SOURCE_LSE */
68 /* #define RTC_CLOCK_SOURCE_LSI */
69
70 /* Private macro -------------------------------------------------------------*/
71 /* Private variables ---------------------------------------------------------*/
72 RTC_HandleTypeDef hRTC_Handle;
73 /* Private function prototypes -----------------------------------------------*/
74 void RTC_Alarm_IRQHandler(void);
75 /* Private functions ---------------------------------------------------------*/
76
77 /**
78 * @brief This function configures the RTC_ALARMA as a time base source.
79 * The time source is configured to have 1ms time base with a dedicated
80 * Tick interrupt priority.
81 * @note This function is called automatically at the beginning of program after
82 * reset by HAL_Init() or at any time when clock is configured, by HAL_RCC_ClockConfig().
83 * @param TickPriority Tick interrupt priority.
84 * @retval HAL status
85 */
HAL_InitTick(uint32_t TickPriority)86 HAL_StatusTypeDef HAL_InitTick(uint32_t TickPriority)
87 {
88 __IO uint32_t counter = 0U;
89
90 RCC_OscInitTypeDef RCC_OscInitStruct;
91 RCC_PeriphCLKInitTypeDef PeriphClkInitStruct;
92
93 #ifdef RTC_CLOCK_SOURCE_LSE
94 /* Configue LSE as RTC clock soucre */
95 RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_LSE;
96 RCC_OscInitStruct.PLL.PLLState = RCC_PLL_NONE;
97 RCC_OscInitStruct.LSEState = RCC_LSE_ON;
98 PeriphClkInitStruct.RTCClockSelection = RCC_RTCCLKSOURCE_LSE;
99 #elif defined (RTC_CLOCK_SOURCE_LSI)
100 /* Configue LSI as RTC clock soucre */
101 RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_LSI;
102 RCC_OscInitStruct.PLL.PLLState = RCC_PLL_NONE;
103 RCC_OscInitStruct.LSIState = RCC_LSI_ON;
104 PeriphClkInitStruct.RTCClockSelection = RCC_RTCCLKSOURCE_LSI;
105 #elif defined (RTC_CLOCK_SOURCE_HSE)
106 /* Configue HSE as RTC clock soucre */
107 RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSE;
108 RCC_OscInitStruct.PLL.PLLState = RCC_PLL_NONE;
109 RCC_OscInitStruct.HSEState = RCC_HSE_ON;
110 PeriphClkInitStruct.RTCClockSelection = RCC_RTCCLKSOURCE_HSE_DIV128;
111 #else
112 #error Please select the RTC Clock source
113 #endif /* RTC_CLOCK_SOURCE_LSE */
114
115 if (HAL_RCC_OscConfig(&RCC_OscInitStruct) == HAL_OK)
116 {
117 PeriphClkInitStruct.PeriphClockSelection = RCC_PERIPHCLK_RTC;
118 if (HAL_RCCEx_PeriphCLKConfig(&PeriphClkInitStruct) == HAL_OK)
119 {
120 /* Enable RTC Clock */
121 __HAL_RCC_RTC_ENABLE();
122
123 hRTC_Handle.Instance = RTC;
124 /* Configure RTC time base to 10Khz */
125 hRTC_Handle.Init.AsynchPrediv = (HAL_RCCEx_GetPeriphCLKFreq(RCC_PERIPHCLK_RTC) / 10000) - 1;
126 hRTC_Handle.Init.OutPut = RTC_OUTPUTSOURCE_NONE;
127 HAL_RTC_Init(&hRTC_Handle);
128
129 /* Disable the write protection for RTC registers */
130 __HAL_RTC_WRITEPROTECTION_DISABLE(&hRTC_Handle);
131
132 /* Clear flag alarm A */
133 __HAL_RTC_ALARM_CLEAR_FLAG(&hRTC_Handle, RTC_FLAG_ALRAF);
134
135 counter = 0U;
136 /* Wait till RTC ALRAF flag is set and if Time out is reached exit */
137 while (__HAL_RTC_ALARM_GET_FLAG(&hRTC_Handle, RTC_FLAG_ALRAF) != RESET)
138 {
139 if (counter++ == SystemCoreClock / 48U) /* Timeout = ~ 1s */
140 {
141 return HAL_ERROR;
142 }
143 }
144
145 /* Set RTC COUNTER MSB word */
146 hRTC_Handle.Instance->ALRH = 0x00U;
147 /* Set RTC COUNTER LSB word */
148 hRTC_Handle.Instance->ALRL = 0x09U;
149
150 /* RTC Alarm Interrupt Configuration: EXTI configuration */
151 __HAL_RTC_ALARM_EXTI_ENABLE_IT();
152 __HAL_RTC_ALARM_EXTI_ENABLE_RISING_EDGE();
153
154 /* Clear Second and overflow flags */
155 CLEAR_BIT(hRTC_Handle.Instance->CRL, (RTC_FLAG_SEC | RTC_FLAG_OW));
156
157 /* Set RTC COUNTER MSB word */
158 hRTC_Handle.Instance->CNTH = 0x00U;
159 /* Set RTC COUNTER LSB word */
160 hRTC_Handle.Instance->CNTL = 0x00U;
161
162 /* Configure the Alarm interrupt */
163 __HAL_RTC_ALARM_ENABLE_IT(&hRTC_Handle, RTC_IT_ALRA);
164
165 /* Enable the write protection for RTC registers */
166 __HAL_RTC_WRITEPROTECTION_ENABLE(&hRTC_Handle);
167
168 /* Wait till RTC is in INIT state and if Time out is reached exit */
169 counter = 0U;
170 while ((hRTC_Handle.Instance->CRL & RTC_CRL_RTOFF) == (uint32_t)RESET)
171 {
172 if (counter++ == SystemCoreClock / 48U) /* Timeout = ~ 1s */
173 {
174 return HAL_ERROR;
175 }
176 }
177
178 HAL_NVIC_SetPriority(RTC_Alarm_IRQn, TickPriority, 0U);
179 HAL_NVIC_EnableIRQ(RTC_Alarm_IRQn);
180 return HAL_OK;
181 }
182 }
183 return HAL_ERROR;
184 }
185
186 /**
187 * @brief Suspend Tick increment.
188 * @note Disable the tick increment by disabling RTC ALARM interrupt.
189 * @param None
190 * @retval None
191 */
HAL_SuspendTick(void)192 void HAL_SuspendTick(void)
193 {
194 /* Disable RTC ALARM update Interrupt */
195 __HAL_RTC_ALARM_DISABLE_IT(&hRTC_Handle, RTC_IT_ALRA);
196 }
197
198 /**
199 * @brief Resume Tick increment.
200 * @note Enable the tick increment by Enabling RTC ALARM interrupt.
201 * @param None
202 * @retval None
203 */
HAL_ResumeTick(void)204 void HAL_ResumeTick(void)
205 {
206 __IO uint32_t counter = 0U;
207
208 /* Disable the write protection for RTC registers */
209 __HAL_RTC_WRITEPROTECTION_DISABLE(&hRTC_Handle);
210
211 /* Set RTC COUNTER MSB word */
212 hRTC_Handle.Instance->CNTH = 0x00U;
213 /* Set RTC COUNTER LSB word */
214 hRTC_Handle.Instance->CNTL = 0x00U;
215
216 /* Clear Second and overflow flags */
217 CLEAR_BIT(hRTC_Handle.Instance->CRL, (RTC_FLAG_SEC | RTC_FLAG_OW | RTC_FLAG_ALRAF));
218
219 /* Enable RTC ALARM Update interrupt */
220 __HAL_RTC_ALARM_ENABLE_IT(&hRTC_Handle, RTC_IT_ALRA);
221
222 /* Enable the write protection for RTC registers */
223 __HAL_RTC_WRITEPROTECTION_ENABLE(&hRTC_Handle);
224
225 /* Wait till RTC is in INIT state and if Time out is reached exit */
226 while ((hRTC_Handle.Instance->CRL & RTC_CRL_RTOFF) == (uint32_t)RESET)
227 {
228 if (counter++ == SystemCoreClock / 48U) /* Timeout = ~ 1s */
229 {
230 break;
231 }
232 }
233 }
234
235 /**
236 * @brief ALARM A Event Callback in non blocking mode
237 * @note This function is called when RTC_ALARM interrupt took place, inside
238 * RTC_ALARM_IRQHandler(). It makes a direct call to HAL_IncTick() to increment
239 * a global variable "uwTick" used as application time base.
240 * @param hrtc RTC handle
241 * @retval None
242 */
HAL_RTC_AlarmAEventCallback(RTC_HandleTypeDef * hrtc)243 void HAL_RTC_AlarmAEventCallback(RTC_HandleTypeDef *hrtc)
244 {
245 __IO uint32_t counter = 0U;
246
247 HAL_IncTick();
248
249 __HAL_RTC_WRITEPROTECTION_DISABLE(hrtc);
250
251 /* Set RTC COUNTER MSB word */
252 WRITE_REG(hrtc->Instance->CNTH, 0x00U);
253 /* Set RTC COUNTER LSB word */
254 WRITE_REG(hrtc->Instance->CNTL, 0x00U);
255
256 /* Clear Second and overflow flags */
257 CLEAR_BIT(hrtc->Instance->CRL, (RTC_FLAG_SEC | RTC_FLAG_OW));
258
259 /* Enable the write protection for RTC registers */
260 __HAL_RTC_WRITEPROTECTION_ENABLE(hrtc);
261
262 /* Wait till RTC is in INIT state and if Time out is reached exit */
263 while ((hrtc->Instance->CRL & RTC_CRL_RTOFF) == (uint32_t)RESET)
264 {
265 if (counter++ == SystemCoreClock / 48U) /* Timeout = ~ 1s */
266 {
267 break;
268 }
269 }
270 }
271
272 /**
273 * @brief This function handles RTC ALARM interrupt request.
274 * @retval None
275 */
RTC_Alarm_IRQHandler(void)276 void RTC_Alarm_IRQHandler(void)
277 {
278 HAL_RTC_AlarmIRQHandler(&hRTC_Handle);
279 }
280
281 /**
282 * @}
283 */
284
285 /**
286 * @}
287 */
288
289 /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
290