1 /**
2 ******************************************************************************
3 * @file stm32l5xx_hal_timebase_rtc_wakeup_template.c
4 * @author MCD Application Team
5 * @brief HAL time base based on the hardware RTC_WAKEUP Template.
6 *
7 * This file overrides the native HAL time base functions (defined as weak)
8 * to use the RTC WAKEUP for the time base generation:
9 * + Initializes the RTC peripheral and configures the wakeup timer to be
10 * incremented each 1ms when uwTickFreq is set to default value, else
11 * 10 ms or 100 ms, depending of above global variable value.
12 * + HAL_IncTick is called inside the HAL_RTCEx_WakeUpTimerEventCallback
13 * + HSE (default), LSE or LSI can be selected as RTC clock source
14 *
15 ******************************************************************************
16 * @attention
17 *
18 * Copyright (c) 2019 STMicroelectronics.
19 * All rights reserved.
20 *
21 * This software is licensed under terms that can be found in the LICENSE file
22 * in the root directory of this software component.
23 * If no LICENSE file comes with this software, it is provided AS-IS.
24 *
25 ******************************************************************************
26 @verbatim
27 ==============================================================================
28 ##### How to use this driver #####
29 ==============================================================================
30 [..]
31 This file must be copied to the application folder and modified as follows:
32 (#) Rename it to 'stm32l5xx_hal_timebase_rtc_wakeup.c'
33 (#) Add this file and the RTC HAL drivers to your project and uncomment
34 HAL_RTC_MODULE_ENABLED define in stm32l5xx_hal_conf.h
35
36 @endverbatim
37 ******************************************************************************
38 */
39
40 /* Includes ------------------------------------------------------------------*/
41 #include "stm32l5xx_hal.h"
42
43 /** @addtogroup STM32L5xx_HAL_Driver
44 * @{
45 */
46
47 /** @defgroup HAL_TimeBase_RTC_WakeUp_Template HAL TimeBase RTC WakeUp Template
48 * @{
49 */
50
51 /* Private typedef -----------------------------------------------------------*/
52 /* Private define ------------------------------------------------------------*/
53
54 /* Uncomment the line below to select the appropriate RTC Clock source for your application:
55 + RTC_CLOCK_SOURCE_HSE: can be selected for applications requiring timing precision.
56 + RTC_CLOCK_SOURCE_LSE: can be selected for applications with low constraint on timing
57 precision.
58 + RTC_CLOCK_SOURCE_LSI: can be selected for applications with low constraint on timing
59 precision.
60 */
61 #define RTC_CLOCK_SOURCE_HSE
62 /* #define RTC_CLOCK_SOURCE_LSE */
63 /* #define RTC_CLOCK_SOURCE_LSI */
64
65 #ifdef RTC_CLOCK_SOURCE_HSE
66 #define RTC_ASYNCH_PREDIV 99U
67 #define RTC_SYNCH_PREDIV 4U
68 #else /* RTC_CLOCK_SOURCE_LSE || RTC_CLOCK_SOURCE_LSI */
69 #define RTC_ASYNCH_PREDIV 31U
70 #define RTC_SYNCH_PREDIV 0U
71 #endif /* RTC_CLOCK_SOURCE_HSE */
72
73 /* Private macro -------------------------------------------------------------*/
74 /* Private variables ---------------------------------------------------------*/
75 RTC_HandleTypeDef hRTC_Handle = {.Init = {0}};
76
77 /* Private function prototypes -----------------------------------------------*/
78 void RTC_IRQHandler(void);
79
80 /* Private functions ---------------------------------------------------------*/
81
82 /**
83 * @brief This function configures the RTC wakeup timer as a time base source.
84 * The time source is configured to have 1ms time base with a dedicated
85 * Tick interrupt priority.
86 * Wakeup Time base = ((RTC_ASYNCH_PREDIV + 1) * (RTC_SYNCH_PREDIV + 1)) / RTC_CLOCK
87 = 1ms
88 * Wakeup Time = WakeupTimebase * WakeUpCounter (0 + 1)
89 = 1 ms
90 * @note This function is called automatically at the beginning of program after
91 * reset by HAL_Init() or at any time when clock is configured, by HAL_RCC_ClockConfig().
92 * @param TickPriority Tick interrupt priority.
93 * @retval HAL status
94 */
HAL_InitTick(uint32_t TickPriority)95 HAL_StatusTypeDef HAL_InitTick(uint32_t TickPriority)
96 {
97 HAL_StatusTypeDef status;
98 __IO uint32_t counter = 0U;
99
100 RCC_OscInitTypeDef RCC_OscInitStruct;
101 RCC_PeriphCLKInitTypeDef PeriphClkInitStruct;
102
103
104 /* Check uwTickFreq for MisraC 2012 (even if uwTickFreq is a enum type that don't take the value zero)*/
105 if ((uint32_t)uwTickFreq != 0U)
106 {
107 #ifdef RTC_CLOCK_SOURCE_LSE
108 /* Configure LSE as RTC clock source */
109 RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_LSE;
110 RCC_OscInitStruct.LSEState = RCC_LSE_ON_RTC_ONLY;
111 RCC_OscInitStruct.PLL.PLLState = RCC_PLL_NONE;
112
113 PeriphClkInitStruct.RTCClockSelection = RCC_RTCCLKSOURCE_LSE;
114 #elif defined (RTC_CLOCK_SOURCE_LSI)
115 /* Configure LSI as RTC clock source */
116 RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_LSI;
117 RCC_OscInitStruct.LSIState = RCC_LSI_ON;
118 RCC_OscInitStruct.LSIDiv = RCC_LSI_DIV1;
119 RCC_OscInitStruct.PLL.PLLState = RCC_PLL_NONE;
120
121 PeriphClkInitStruct.RTCClockSelection = RCC_RTCCLKSOURCE_LSI;
122 #elif defined (RTC_CLOCK_SOURCE_HSE)
123 /* Configure HSE as RTC clock source */
124 RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSE;
125 RCC_OscInitStruct.HSEState = RCC_HSE_ON;
126 RCC_OscInitStruct.PLL.PLLState = RCC_PLL_NONE;
127
128 PeriphClkInitStruct.RTCClockSelection = RCC_RTCCLKSOURCE_HSE_DIV32;
129 #else
130 #error Please select the RTC Clock source
131 #endif /* RTC_CLOCK_SOURCE_LSE */
132
133 status = HAL_RCC_OscConfig(&RCC_OscInitStruct);
134 if(status == HAL_OK)
135 {
136 PeriphClkInitStruct.PeriphClockSelection = RCC_PERIPHCLK_RTC;
137 status = HAL_RCCEx_PeriphCLKConfig(&PeriphClkInitStruct);
138
139 /* Enable RTC Clock */
140 if(status == HAL_OK)
141 {
142 /* Enable RTC Clock */
143 __HAL_RCC_RTC_ENABLE();
144 __HAL_RCC_RTCAPB_CLK_ENABLE();
145
146 /* The time base should be 1ms
147 Time base = ((RTC_ASYNCH_PREDIV + 1) * (RTC_SYNCH_PREDIV + 1)) / RTC_CLOCK
148 HSE as RTC clock
149 Time base = ((99 + 1) * (4 + 1)) / 500kHz
150 = 1ms
151 LSE as RTC clock
152 Time base = ((31 + 1) * (0 + 1)) / 32.768kHz
153 = ~1ms
154 LSI as RTC clock
155 Time base = ((31 + 1) * (0 + 1)) / 32kHz
156 = 1ms
157 */
158 hRTC_Handle.Instance = RTC;
159 hRTC_Handle.Init.HourFormat = RTC_HOURFORMAT_24;
160 hRTC_Handle.Init.AsynchPrediv = RTC_ASYNCH_PREDIV;
161 hRTC_Handle.Init.SynchPrediv = RTC_SYNCH_PREDIV;
162 hRTC_Handle.Init.OutPut = RTC_OUTPUT_DISABLE;
163 hRTC_Handle.Init.OutPutPolarity = RTC_OUTPUT_POLARITY_HIGH;
164 hRTC_Handle.Init.OutPutType = RTC_OUTPUT_TYPE_OPENDRAIN;
165 status = HAL_RTC_Init(&hRTC_Handle);
166 if(status == HAL_OK)
167 {
168 /* Disable the write protection for RTC registers */
169 __HAL_RTC_WRITEPROTECTION_DISABLE(&hRTC_Handle);
170
171 /* Disable the Wake-up Timer */
172 __HAL_RTC_WAKEUPTIMER_DISABLE(&hRTC_Handle);
173
174 /* In case of interrupt mode is used, the interrupt source must disabled */
175 __HAL_RTC_WAKEUPTIMER_DISABLE_IT(&hRTC_Handle, RTC_IT_WUT);
176
177 /* Wait till RTC WUTWF flag is set */
178 while (__HAL_RTC_WAKEUPTIMER_GET_FLAG(&hRTC_Handle, RTC_FLAG_WUTWF) == 0U)
179 {
180 counter++;
181 if (counter == (SystemCoreClock / 56U))
182 {
183 status = HAL_ERROR;
184 break;
185 }
186 }
187
188 if(status == HAL_OK)
189 {
190 /* Clear PWR wake up Flag */
191 __HAL_PWR_CLEAR_FLAG(PWR_FLAG_WU);
192
193 /* Clear RTC Wake Up timer Flag */
194 __HAL_RTC_WAKEUPTIMER_CLEAR_FLAG(&hRTC_Handle, RTC_FLAG_WUTF);
195
196 /* Configure the Wake-up Timer counter */
197 hRTC_Handle.Instance->WUTR = 0U;
198
199 /* Clear the Wake-up Timer clock source bits in CR register */
200 hRTC_Handle.Instance->CR &= (uint32_t)~RTC_CR_WUCKSEL;
201
202 /* Configure the clock source */
203 hRTC_Handle.Instance->CR |= (uint32_t)RTC_WAKEUPCLOCK_CK_SPRE_16BITS;
204
205 /* RTC WakeUpTimer Interrupt Configuration: EXTI configuration */
206 __HAL_RTC_WAKEUPTIMER_EXTI_ENABLE_IT();
207
208 /* Configure the Interrupt in the RTC_CR register */
209 __HAL_RTC_WAKEUPTIMER_ENABLE_IT(&hRTC_Handle, RTC_IT_WUT);
210
211 /* Enable the Wake-up Timer */
212 __HAL_RTC_WAKEUPTIMER_ENABLE(&hRTC_Handle);
213
214 /* Enable the write protection for RTC registers */
215 __HAL_RTC_WRITEPROTECTION_ENABLE(&hRTC_Handle);
216
217 HAL_NVIC_EnableIRQ(RTC_IRQn);
218
219 /* Configure the SysTick IRQ priority */
220 if (TickPriority < (1UL << __NVIC_PRIO_BITS))
221 {
222 HAL_NVIC_SetPriority(RTC_IRQn, TickPriority, 0U);
223 uwTickPrio = TickPriority;
224 }
225 else
226 {
227 status = HAL_ERROR;
228 }
229 }
230 }
231 }
232 }
233 }
234 else
235 {
236 status = HAL_ERROR;
237 }
238 return status;
239 }
240
241 /**
242 * @brief Suspend Tick increment.
243 * @note Disable the tick increment by disabling RTC interrupt.
244 * @retval None
245 */
HAL_SuspendTick(void)246 void HAL_SuspendTick(void)
247 {
248 /* Disable the write protection for RTC registers */
249 __HAL_RTC_WRITEPROTECTION_DISABLE(&hRTC_Handle);
250 /* Disable RTC WAKE UP TIMER Interrupt */
251 __HAL_RTC_WAKEUPTIMER_DISABLE_IT(&hRTC_Handle, RTC_IT_WUT);
252 /* Enable the write protection for RTC registers */
253 __HAL_RTC_WRITEPROTECTION_ENABLE(&hRTC_Handle);
254 }
255
256 /**
257 * @brief Resume Tick increment.
258 * @note Enable the tick increment by enabling RTC interrupt.
259 * @retval None
260 */
HAL_ResumeTick(void)261 void HAL_ResumeTick(void)
262 {
263 /* Disable the write protection for RTC registers */
264 __HAL_RTC_WRITEPROTECTION_DISABLE(&hRTC_Handle);
265 /* Enable RTC WAKE UP TIMER interrupt */
266 __HAL_RTC_WAKEUPTIMER_ENABLE_IT(&hRTC_Handle, RTC_IT_WUT);
267 /* Enable the write protection for RTC registers */
268 __HAL_RTC_WRITEPROTECTION_ENABLE(&hRTC_Handle);
269 }
270
271 /**
272 * @brief Wake Up Timer Event Callback in non blocking mode
273 * @note This function is called when RTC interrupt took place, inside
274 * RTC_IRQHandler(). It makes a direct call to HAL_IncTick() to increment
275 * a global variable "uwTick" used as application time base.
276 * @param hrtc : RTC handle
277 * @retval None
278 */
HAL_RTCEx_WakeUpTimerEventCallback(RTC_HandleTypeDef * hrtc)279 void HAL_RTCEx_WakeUpTimerEventCallback(RTC_HandleTypeDef *hrtc)
280 {
281 /* Prevent unused argument(s) compilation warning */
282 UNUSED(hrtc);
283
284 HAL_IncTick();
285 }
286
287 /**
288 * @brief This function handles RTC WAKE UP TIMER interrupt request.
289 * @retval None
290 */
RTC_IRQHandler(void)291 void RTC_IRQHandler(void)
292 {
293 HAL_RTCEx_WakeUpTimerIRQHandler(&hRTC_Handle);
294 }
295
296 /**
297 * @}
298 */
299
300 /**
301 * @}
302 */
303
304