1 /**
2 ******************************************************************************
3 * @file stm32f0xx_hal_rcc_ex.c
4 * @author MCD Application Team
5 * @brief Extended RCC HAL module driver.
6 * This file provides firmware functions to manage the following
7 * functionalities RCC extension peripheral:
8 * + Extended Peripheral Control functions
9 * + Extended Clock Recovery System Control functions
10 *
11 ******************************************************************************
12 * @attention
13 *
14 * <h2><center>© Copyright (c) 2016 STMicroelectronics.
15 * All rights reserved.</center></h2>
16 *
17 * This software component is licensed by ST under BSD 3-Clause license,
18 * the "License"; You may not use this file except in compliance with the
19 * License. You may obtain a copy of the License at:
20 * opensource.org/licenses/BSD-3-Clause
21 *
22 ******************************************************************************
23 */
24
25 /* Includes ------------------------------------------------------------------*/
26 #include "stm32f0xx_hal.h"
27
28 /** @addtogroup STM32F0xx_HAL_Driver
29 * @{
30 */
31
32 #ifdef HAL_RCC_MODULE_ENABLED
33
34 /** @defgroup RCCEx RCCEx
35 * @brief RCC Extension HAL module driver.
36 * @{
37 */
38
39 /* Private typedef -----------------------------------------------------------*/
40 /* Private define ------------------------------------------------------------*/
41 #if defined(CRS)
42 /** @defgroup RCCEx_Private_Constants RCCEx Private Constants
43 * @{
44 */
45 /* Bit position in register */
46 #define CRS_CFGR_FELIM_BITNUMBER 16
47 #define CRS_CR_TRIM_BITNUMBER 8
48 #define CRS_ISR_FECAP_BITNUMBER 16
49 /**
50 * @}
51 */
52 #endif /* CRS */
53
54 /* Private macro -------------------------------------------------------------*/
55 /** @defgroup RCCEx_Private_Macros RCCEx Private Macros
56 * @{
57 */
58 /**
59 * @}
60 */
61
62 /* Private variables ---------------------------------------------------------*/
63 /* Private function prototypes -----------------------------------------------*/
64 /* Private functions ---------------------------------------------------------*/
65
66 /** @defgroup RCCEx_Exported_Functions RCCEx Exported Functions
67 * @{
68 */
69
70 /** @defgroup RCCEx_Exported_Functions_Group1 Extended Peripheral Control functions
71 * @brief Extended Peripheral Control functions
72 *
73 @verbatim
74 ===============================================================================
75 ##### Extended Peripheral Control functions #####
76 ===============================================================================
77 [..]
78 This subsection provides a set of functions allowing to control the RCC Clocks
79 frequencies.
80 [..]
81 (@) Important note: Care must be taken when HAL_RCCEx_PeriphCLKConfig() is used to
82 select the RTC clock source; in this case the Backup domain will be reset in
83 order to modify the RTC Clock source, as consequence RTC registers (including
84 the backup registers) are set to their reset values.
85
86 @endverbatim
87 * @{
88 */
89
90 /**
91 * @brief Initializes the RCC extended peripherals clocks according to the specified
92 * parameters in the RCC_PeriphCLKInitTypeDef.
93 * @param PeriphClkInit pointer to an RCC_PeriphCLKInitTypeDef structure that
94 * contains the configuration information for the Extended Peripherals clocks
95 * (USART, RTC, I2C, CEC and USB).
96 *
97 * @note Care must be taken when @ref HAL_RCCEx_PeriphCLKConfig() is used to select
98 * the RTC clock source; in this case the Backup domain will be reset in
99 * order to modify the RTC Clock source, as consequence RTC registers (including
100 * the backup registers) and RCC_BDCR register are set to their reset values.
101 *
102 * @retval HAL status
103 */
HAL_RCCEx_PeriphCLKConfig(RCC_PeriphCLKInitTypeDef * PeriphClkInit)104 HAL_StatusTypeDef HAL_RCCEx_PeriphCLKConfig(RCC_PeriphCLKInitTypeDef *PeriphClkInit)
105 {
106 uint32_t tickstart = 0U;
107 uint32_t temp_reg = 0U;
108
109 /* Check the parameters */
110 assert_param(IS_RCC_PERIPHCLOCK(PeriphClkInit->PeriphClockSelection));
111
112 /*---------------------------- RTC configuration -------------------------------*/
113 if(((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_RTC) == (RCC_PERIPHCLK_RTC))
114 {
115 /* check for RTC Parameters used to output RTCCLK */
116 assert_param(IS_RCC_RTCCLKSOURCE(PeriphClkInit->RTCClockSelection));
117
118 FlagStatus pwrclkchanged = RESET;
119
120 /* As soon as function is called to change RTC clock source, activation of the
121 power domain is done. */
122 /* Requires to enable write access to Backup Domain of necessary */
123 if(__HAL_RCC_PWR_IS_CLK_DISABLED())
124 {
125 __HAL_RCC_PWR_CLK_ENABLE();
126 pwrclkchanged = SET;
127 }
128
129 if(HAL_IS_BIT_CLR(PWR->CR, PWR_CR_DBP))
130 {
131 /* Enable write access to Backup domain */
132 SET_BIT(PWR->CR, PWR_CR_DBP);
133
134 /* Wait for Backup domain Write protection disable */
135 tickstart = HAL_GetTick();
136
137 while(HAL_IS_BIT_CLR(PWR->CR, PWR_CR_DBP))
138 {
139 if((HAL_GetTick() - tickstart) > RCC_DBP_TIMEOUT_VALUE)
140 {
141 return HAL_TIMEOUT;
142 }
143 }
144 }
145
146 /* Reset the Backup domain only if the RTC Clock source selection is modified from reset value */
147 temp_reg = (RCC->BDCR & RCC_BDCR_RTCSEL);
148 if((temp_reg != 0x00000000U) && (temp_reg != (PeriphClkInit->RTCClockSelection & RCC_BDCR_RTCSEL)))
149 {
150 /* Store the content of BDCR register before the reset of Backup Domain */
151 temp_reg = (RCC->BDCR & ~(RCC_BDCR_RTCSEL));
152 /* RTC Clock selection can be changed only if the Backup Domain is reset */
153 __HAL_RCC_BACKUPRESET_FORCE();
154 __HAL_RCC_BACKUPRESET_RELEASE();
155 /* Restore the Content of BDCR register */
156 RCC->BDCR = temp_reg;
157
158 /* Wait for LSERDY if LSE was enabled */
159 if (HAL_IS_BIT_SET(temp_reg, RCC_BDCR_LSEON))
160 {
161 /* Get Start Tick */
162 tickstart = HAL_GetTick();
163
164 /* Wait till LSE is ready */
165 while(__HAL_RCC_GET_FLAG(RCC_FLAG_LSERDY) == RESET)
166 {
167 if((HAL_GetTick() - tickstart) > RCC_LSE_TIMEOUT_VALUE)
168 {
169 return HAL_TIMEOUT;
170 }
171 }
172 }
173 }
174 __HAL_RCC_RTC_CONFIG(PeriphClkInit->RTCClockSelection);
175
176 /* Require to disable power clock if necessary */
177 if(pwrclkchanged == SET)
178 {
179 __HAL_RCC_PWR_CLK_DISABLE();
180 }
181 }
182
183 /*------------------------------- USART1 Configuration ------------------------*/
184 if(((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_USART1) == RCC_PERIPHCLK_USART1)
185 {
186 /* Check the parameters */
187 assert_param(IS_RCC_USART1CLKSOURCE(PeriphClkInit->Usart1ClockSelection));
188
189 /* Configure the USART1 clock source */
190 __HAL_RCC_USART1_CONFIG(PeriphClkInit->Usart1ClockSelection);
191 }
192
193 #if defined(STM32F071xB) || defined(STM32F072xB) || defined(STM32F078xx)\
194 || defined(STM32F091xC) || defined(STM32F098xx)
195 /*----------------------------- USART2 Configuration --------------------------*/
196 if(((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_USART2) == RCC_PERIPHCLK_USART2)
197 {
198 /* Check the parameters */
199 assert_param(IS_RCC_USART2CLKSOURCE(PeriphClkInit->Usart2ClockSelection));
200
201 /* Configure the USART2 clock source */
202 __HAL_RCC_USART2_CONFIG(PeriphClkInit->Usart2ClockSelection);
203 }
204 #endif /* STM32F071xB || STM32F072xB || STM32F078xx || */
205 /* STM32F091xC || STM32F098xx */
206
207 #if defined(STM32F091xC) || defined(STM32F098xx)
208 /*----------------------------- USART3 Configuration --------------------------*/
209 if(((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_USART3) == RCC_PERIPHCLK_USART3)
210 {
211 /* Check the parameters */
212 assert_param(IS_RCC_USART3CLKSOURCE(PeriphClkInit->Usart3ClockSelection));
213
214 /* Configure the USART3 clock source */
215 __HAL_RCC_USART3_CONFIG(PeriphClkInit->Usart3ClockSelection);
216 }
217 #endif /* STM32F091xC || STM32F098xx */
218
219 /*------------------------------ I2C1 Configuration ------------------------*/
220 if(((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_I2C1) == RCC_PERIPHCLK_I2C1)
221 {
222 /* Check the parameters */
223 assert_param(IS_RCC_I2C1CLKSOURCE(PeriphClkInit->I2c1ClockSelection));
224
225 /* Configure the I2C1 clock source */
226 __HAL_RCC_I2C1_CONFIG(PeriphClkInit->I2c1ClockSelection);
227 }
228
229 #if defined(STM32F042x6) || defined(STM32F048xx) || defined(STM32F072xB) || defined(STM32F078xx) || defined(STM32F070xB) || defined(STM32F070x6)
230 /*------------------------------ USB Configuration ------------------------*/
231 if(((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_USB) == RCC_PERIPHCLK_USB)
232 {
233 /* Check the parameters */
234 assert_param(IS_RCC_USBCLKSOURCE(PeriphClkInit->UsbClockSelection));
235
236 /* Configure the USB clock source */
237 __HAL_RCC_USB_CONFIG(PeriphClkInit->UsbClockSelection);
238 }
239 #endif /* STM32F042x6 || STM32F048xx || STM32F072xB || STM32F078xx || STM32F070xB || STM32F070x6 */
240
241 #if defined(STM32F042x6) || defined(STM32F048xx)\
242 || defined(STM32F051x8) || defined(STM32F058xx)\
243 || defined(STM32F071xB) || defined(STM32F072xB) || defined(STM32F078xx)\
244 || defined(STM32F091xC) || defined(STM32F098xx)
245 /*------------------------------ CEC clock Configuration -------------------*/
246 if(((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_CEC) == RCC_PERIPHCLK_CEC)
247 {
248 /* Check the parameters */
249 assert_param(IS_RCC_CECCLKSOURCE(PeriphClkInit->CecClockSelection));
250
251 /* Configure the CEC clock source */
252 __HAL_RCC_CEC_CONFIG(PeriphClkInit->CecClockSelection);
253 }
254 #endif /* STM32F042x6 || STM32F048xx || */
255 /* STM32F051x8 || STM32F058xx || */
256 /* STM32F071xB || STM32F072xB || STM32F078xx || */
257 /* STM32F091xC || STM32F098xx */
258
259 return HAL_OK;
260 }
261
262 /**
263 * @brief Get the RCC_ClkInitStruct according to the internal
264 * RCC configuration registers.
265 * @param PeriphClkInit pointer to an RCC_PeriphCLKInitTypeDef structure that
266 * returns the configuration information for the Extended Peripherals clocks
267 * (USART, RTC, I2C, CEC and USB).
268 * @retval None
269 */
HAL_RCCEx_GetPeriphCLKConfig(RCC_PeriphCLKInitTypeDef * PeriphClkInit)270 void HAL_RCCEx_GetPeriphCLKConfig(RCC_PeriphCLKInitTypeDef *PeriphClkInit)
271 {
272 /* Set all possible values for the extended clock type parameter------------*/
273 /* Common part first */
274 PeriphClkInit->PeriphClockSelection = RCC_PERIPHCLK_USART1 | RCC_PERIPHCLK_I2C1 | RCC_PERIPHCLK_RTC;
275 /* Get the RTC configuration --------------------------------------------*/
276 PeriphClkInit->RTCClockSelection = __HAL_RCC_GET_RTC_SOURCE();
277 /* Get the USART1 clock configuration --------------------------------------------*/
278 PeriphClkInit->Usart1ClockSelection = __HAL_RCC_GET_USART1_SOURCE();
279 /* Get the I2C1 clock source -----------------------------------------------*/
280 PeriphClkInit->I2c1ClockSelection = __HAL_RCC_GET_I2C1_SOURCE();
281
282 #if defined(STM32F071xB) || defined(STM32F072xB) || defined(STM32F078xx)\
283 || defined(STM32F091xC) || defined(STM32F098xx)
284 PeriphClkInit->PeriphClockSelection |= RCC_PERIPHCLK_USART2;
285 /* Get the USART2 clock source ---------------------------------------------*/
286 PeriphClkInit->Usart2ClockSelection = __HAL_RCC_GET_USART2_SOURCE();
287 #endif /* STM32F071xB || STM32F072xB || STM32F078xx || */
288 /* STM32F091xC || STM32F098xx */
289
290 #if defined(STM32F091xC) || defined(STM32F098xx)
291 PeriphClkInit->PeriphClockSelection |= RCC_PERIPHCLK_USART3;
292 /* Get the USART3 clock source ---------------------------------------------*/
293 PeriphClkInit->Usart3ClockSelection = __HAL_RCC_GET_USART3_SOURCE();
294 #endif /* STM32F091xC || STM32F098xx */
295
296 #if defined(STM32F042x6) || defined(STM32F048xx) || defined(STM32F072xB) || defined(STM32F078xx) || defined(STM32F070xB) || defined(STM32F070x6)
297 PeriphClkInit->PeriphClockSelection |= RCC_PERIPHCLK_USB;
298 /* Get the USB clock source ---------------------------------------------*/
299 PeriphClkInit->UsbClockSelection = __HAL_RCC_GET_USB_SOURCE();
300 #endif /* STM32F042x6 || STM32F048xx || STM32F072xB || STM32F078xx || STM32F070xB || STM32F070x6 */
301
302 #if defined(STM32F042x6) || defined(STM32F048xx)\
303 || defined(STM32F051x8) || defined(STM32F058xx)\
304 || defined(STM32F071xB) || defined(STM32F072xB) || defined(STM32F078xx)\
305 || defined(STM32F091xC) || defined(STM32F098xx)
306 PeriphClkInit->PeriphClockSelection |= RCC_PERIPHCLK_CEC;
307 /* Get the CEC clock source ------------------------------------------------*/
308 PeriphClkInit->CecClockSelection = __HAL_RCC_GET_CEC_SOURCE();
309 #endif /* STM32F042x6 || STM32F048xx || */
310 /* STM32F051x8 || STM32F058xx || */
311 /* STM32F071xB || STM32F072xB || STM32F078xx || */
312 /* STM32F091xC || STM32F098xx */
313
314 }
315
316 /**
317 * @brief Returns the peripheral clock frequency
318 * @note Returns 0 if peripheral clock is unknown
319 * @param PeriphClk Peripheral clock identifier
320 * This parameter can be one of the following values:
321 * @arg @ref RCC_PERIPHCLK_RTC RTC peripheral clock
322 * @arg @ref RCC_PERIPHCLK_USART1 USART1 peripheral clock
323 * @arg @ref RCC_PERIPHCLK_I2C1 I2C1 peripheral clock
324 @if STM32F042x6
325 * @arg @ref RCC_PERIPHCLK_USB USB peripheral clock
326 * @arg @ref RCC_PERIPHCLK_CEC CEC peripheral clock
327 @endif
328 @if STM32F048xx
329 * @arg @ref RCC_PERIPHCLK_USB USB peripheral clock
330 * @arg @ref RCC_PERIPHCLK_CEC CEC peripheral clock
331 @endif
332 @if STM32F051x8
333 * @arg @ref RCC_PERIPHCLK_CEC CEC peripheral clock
334 @endif
335 @if STM32F058xx
336 * @arg @ref RCC_PERIPHCLK_CEC CEC peripheral clock
337 @endif
338 @if STM32F070x6
339 * @arg @ref RCC_PERIPHCLK_USB USB peripheral clock
340 @endif
341 @if STM32F070xB
342 * @arg @ref RCC_PERIPHCLK_USB USB peripheral clock
343 @endif
344 @if STM32F071xB
345 * @arg @ref RCC_PERIPHCLK_USART2 USART2 peripheral clock
346 * @arg @ref RCC_PERIPHCLK_CEC CEC peripheral clock
347 @endif
348 @if STM32F072xB
349 * @arg @ref RCC_PERIPHCLK_USART2 USART2 peripheral clock
350 * @arg @ref RCC_PERIPHCLK_USB USB peripheral clock
351 * @arg @ref RCC_PERIPHCLK_CEC CEC peripheral clock
352 @endif
353 @if STM32F078xx
354 * @arg @ref RCC_PERIPHCLK_USART2 USART2 peripheral clock
355 * @arg @ref RCC_PERIPHCLK_USB USB peripheral clock
356 * @arg @ref RCC_PERIPHCLK_CEC CEC peripheral clock
357 @endif
358 @if STM32F091xC
359 * @arg @ref RCC_PERIPHCLK_USART2 USART2 peripheral clock
360 * @arg @ref RCC_PERIPHCLK_USART3 USART2 peripheral clock
361 * @arg @ref RCC_PERIPHCLK_CEC CEC peripheral clock
362 @endif
363 @if STM32F098xx
364 * @arg @ref RCC_PERIPHCLK_USART2 USART2 peripheral clock
365 * @arg @ref RCC_PERIPHCLK_USART3 USART2 peripheral clock
366 * @arg @ref RCC_PERIPHCLK_CEC CEC peripheral clock
367 @endif
368 * @retval Frequency in Hz (0: means that no available frequency for the peripheral)
369 */
HAL_RCCEx_GetPeriphCLKFreq(uint32_t PeriphClk)370 uint32_t HAL_RCCEx_GetPeriphCLKFreq(uint32_t PeriphClk)
371 {
372 /* frequency == 0 : means that no available frequency for the peripheral */
373 uint32_t frequency = 0U;
374
375 uint32_t srcclk = 0U;
376 #if defined(USB)
377 uint32_t pllmull = 0U, pllsource = 0U, predivfactor = 0U;
378 #endif /* USB */
379
380 /* Check the parameters */
381 assert_param(IS_RCC_PERIPHCLOCK(PeriphClk));
382
383 switch (PeriphClk)
384 {
385 case RCC_PERIPHCLK_RTC:
386 {
387 /* Get the current RTC source */
388 srcclk = __HAL_RCC_GET_RTC_SOURCE();
389
390 /* Check if LSE is ready and if RTC clock selection is LSE */
391 if ((srcclk == RCC_RTCCLKSOURCE_LSE) && (HAL_IS_BIT_SET(RCC->BDCR, RCC_BDCR_LSERDY)))
392 {
393 frequency = LSE_VALUE;
394 }
395 /* Check if LSI is ready and if RTC clock selection is LSI */
396 else if ((srcclk == RCC_RTCCLKSOURCE_LSI) && (HAL_IS_BIT_SET(RCC->CSR, RCC_CSR_LSIRDY)))
397 {
398 frequency = LSI_VALUE;
399 }
400 /* Check if HSE is ready and if RTC clock selection is HSI_DIV32*/
401 else if ((srcclk == RCC_RTCCLKSOURCE_HSE_DIV32) && (HAL_IS_BIT_SET(RCC->CR, RCC_CR_HSERDY)))
402 {
403 frequency = HSE_VALUE / 32U;
404 }
405 break;
406 }
407 case RCC_PERIPHCLK_USART1:
408 {
409 /* Get the current USART1 source */
410 srcclk = __HAL_RCC_GET_USART1_SOURCE();
411
412 /* Check if USART1 clock selection is PCLK1 */
413 if (srcclk == RCC_USART1CLKSOURCE_PCLK1)
414 {
415 frequency = HAL_RCC_GetPCLK1Freq();
416 }
417 /* Check if HSI is ready and if USART1 clock selection is HSI */
418 else if ((srcclk == RCC_USART1CLKSOURCE_HSI) && (HAL_IS_BIT_SET(RCC->CR, RCC_CR_HSIRDY)))
419 {
420 frequency = HSI_VALUE;
421 }
422 /* Check if USART1 clock selection is SYSCLK */
423 else if (srcclk == RCC_USART1CLKSOURCE_SYSCLK)
424 {
425 frequency = HAL_RCC_GetSysClockFreq();
426 }
427 /* Check if LSE is ready and if USART1 clock selection is LSE */
428 else if ((srcclk == RCC_USART1CLKSOURCE_LSE) && (HAL_IS_BIT_SET(RCC->BDCR, RCC_BDCR_LSERDY)))
429 {
430 frequency = LSE_VALUE;
431 }
432 break;
433 }
434 #if defined(RCC_CFGR3_USART2SW)
435 case RCC_PERIPHCLK_USART2:
436 {
437 /* Get the current USART2 source */
438 srcclk = __HAL_RCC_GET_USART2_SOURCE();
439
440 /* Check if USART2 clock selection is PCLK1 */
441 if (srcclk == RCC_USART2CLKSOURCE_PCLK1)
442 {
443 frequency = HAL_RCC_GetPCLK1Freq();
444 }
445 /* Check if HSI is ready and if USART2 clock selection is HSI */
446 else if ((srcclk == RCC_USART2CLKSOURCE_HSI) && (HAL_IS_BIT_SET(RCC->CR, RCC_CR_HSIRDY)))
447 {
448 frequency = HSI_VALUE;
449 }
450 /* Check if USART2 clock selection is SYSCLK */
451 else if (srcclk == RCC_USART2CLKSOURCE_SYSCLK)
452 {
453 frequency = HAL_RCC_GetSysClockFreq();
454 }
455 /* Check if LSE is ready and if USART2 clock selection is LSE */
456 else if ((srcclk == RCC_USART2CLKSOURCE_LSE) && (HAL_IS_BIT_SET(RCC->BDCR, RCC_BDCR_LSERDY)))
457 {
458 frequency = LSE_VALUE;
459 }
460 break;
461 }
462 #endif /* RCC_CFGR3_USART2SW */
463 #if defined(RCC_CFGR3_USART3SW)
464 case RCC_PERIPHCLK_USART3:
465 {
466 /* Get the current USART3 source */
467 srcclk = __HAL_RCC_GET_USART3_SOURCE();
468
469 /* Check if USART3 clock selection is PCLK1 */
470 if (srcclk == RCC_USART3CLKSOURCE_PCLK1)
471 {
472 frequency = HAL_RCC_GetPCLK1Freq();
473 }
474 /* Check if HSI is ready and if USART3 clock selection is HSI */
475 else if ((srcclk == RCC_USART3CLKSOURCE_HSI) && (HAL_IS_BIT_SET(RCC->CR, RCC_CR_HSIRDY)))
476 {
477 frequency = HSI_VALUE;
478 }
479 /* Check if USART3 clock selection is SYSCLK */
480 else if (srcclk == RCC_USART3CLKSOURCE_SYSCLK)
481 {
482 frequency = HAL_RCC_GetSysClockFreq();
483 }
484 /* Check if LSE is ready and if USART3 clock selection is LSE */
485 else if ((srcclk == RCC_USART3CLKSOURCE_LSE) && (HAL_IS_BIT_SET(RCC->BDCR, RCC_BDCR_LSERDY)))
486 {
487 frequency = LSE_VALUE;
488 }
489 break;
490 }
491 #endif /* RCC_CFGR3_USART3SW */
492 case RCC_PERIPHCLK_I2C1:
493 {
494 /* Get the current I2C1 source */
495 srcclk = __HAL_RCC_GET_I2C1_SOURCE();
496
497 /* Check if HSI is ready and if I2C1 clock selection is HSI */
498 if ((srcclk == RCC_I2C1CLKSOURCE_HSI) && (HAL_IS_BIT_SET(RCC->CR, RCC_CR_HSIRDY)))
499 {
500 frequency = HSI_VALUE;
501 }
502 /* Check if I2C1 clock selection is SYSCLK */
503 else if (srcclk == RCC_I2C1CLKSOURCE_SYSCLK)
504 {
505 frequency = HAL_RCC_GetSysClockFreq();
506 }
507 break;
508 }
509 #if defined(USB)
510 case RCC_PERIPHCLK_USB:
511 {
512 /* Get the current USB source */
513 srcclk = __HAL_RCC_GET_USB_SOURCE();
514
515 /* Check if PLL is ready and if USB clock selection is PLL */
516 if ((srcclk == RCC_USBCLKSOURCE_PLL) && (HAL_IS_BIT_SET(RCC->CR, RCC_CR_PLLRDY)))
517 {
518 /* Get PLL clock source and multiplication factor ----------------------*/
519 pllmull = RCC->CFGR & RCC_CFGR_PLLMUL;
520 pllsource = RCC->CFGR & RCC_CFGR_PLLSRC;
521 pllmull = (pllmull >> RCC_CFGR_PLLMUL_BITNUMBER) + 2U;
522 predivfactor = (RCC->CFGR2 & RCC_CFGR2_PREDIV) + 1U;
523
524 if (pllsource == RCC_CFGR_PLLSRC_HSE_PREDIV)
525 {
526 /* HSE used as PLL clock source : frequency = HSE/PREDIV * PLLMUL */
527 frequency = (HSE_VALUE/predivfactor) * pllmull;
528 }
529 #if defined(RCC_CR2_HSI48ON)
530 else if (pllsource == RCC_CFGR_PLLSRC_HSI48_PREDIV)
531 {
532 /* HSI48 used as PLL clock source : frequency = HSI48/PREDIV * PLLMUL */
533 frequency = (HSI48_VALUE / predivfactor) * pllmull;
534 }
535 #endif /* RCC_CR2_HSI48ON */
536 else
537 {
538 #if defined(STM32F042x6) || defined(STM32F048xx) || defined(STM32F078xx) || defined(STM32F072xB) || defined(STM32F070xB)
539 /* HSI used as PLL clock source : frequency = HSI/PREDIV * PLLMUL */
540 frequency = (HSI_VALUE / predivfactor) * pllmull;
541 #else
542 /* HSI used as PLL clock source : frequency = HSI/2U * PLLMUL */
543 frequency = (HSI_VALUE >> 1U) * pllmull;
544 #endif /* STM32F042x6 || STM32F048xx || STM32F072xB || STM32F078xx || STM32F070xB */
545 }
546 }
547 #if defined(RCC_CR2_HSI48ON)
548 /* Check if HSI48 is ready and if USB clock selection is HSI48 */
549 else if ((srcclk == RCC_USBCLKSOURCE_HSI48) && (HAL_IS_BIT_SET(RCC->CR2, RCC_CR2_HSI48RDY)))
550 {
551 frequency = HSI48_VALUE;
552 }
553 #endif /* RCC_CR2_HSI48ON */
554 break;
555 }
556 #endif /* USB */
557 #if defined(CEC)
558 case RCC_PERIPHCLK_CEC:
559 {
560 /* Get the current CEC source */
561 srcclk = __HAL_RCC_GET_CEC_SOURCE();
562
563 /* Check if HSI is ready and if CEC clock selection is HSI */
564 if ((srcclk == RCC_CECCLKSOURCE_HSI) && (HAL_IS_BIT_SET(RCC->CR, RCC_CR_HSIRDY)))
565 {
566 frequency = HSI_VALUE;
567 }
568 /* Check if LSE is ready and if CEC clock selection is LSE */
569 else if ((srcclk == RCC_CECCLKSOURCE_LSE) && (HAL_IS_BIT_SET(RCC->BDCR, RCC_BDCR_LSERDY)))
570 {
571 frequency = LSE_VALUE;
572 }
573 break;
574 }
575 #endif /* CEC */
576 default:
577 {
578 break;
579 }
580 }
581 return(frequency);
582 }
583
584 /**
585 * @}
586 */
587
588 #if defined(CRS)
589
590 /** @defgroup RCCEx_Exported_Functions_Group3 Extended Clock Recovery System Control functions
591 * @brief Extended Clock Recovery System Control functions
592 *
593 @verbatim
594 ===============================================================================
595 ##### Extended Clock Recovery System Control functions #####
596 ===============================================================================
597 [..]
598 For devices with Clock Recovery System feature (CRS), RCC Extension HAL driver can be used as follows:
599
600 (#) In System clock config, HSI48 needs to be enabled
601
602 (#) Enable CRS clock in IP MSP init which will use CRS functions
603
604 (#) Call CRS functions as follows:
605 (##) Prepare synchronization configuration necessary for HSI48 calibration
606 (+++) Default values can be set for frequency Error Measurement (reload and error limit)
607 and also HSI48 oscillator smooth trimming.
608 (+++) Macro __HAL_RCC_CRS_RELOADVALUE_CALCULATE can be also used to calculate
609 directly reload value with target and synchronization frequencies values
610 (##) Call function HAL_RCCEx_CRSConfig which
611 (+++) Reset CRS registers to their default values.
612 (+++) Configure CRS registers with synchronization configuration
613 (+++) Enable automatic calibration and frequency error counter feature
614 Note: When using USB LPM (Link Power Management) and the device is in Sleep mode, the
615 periodic USB SOF will not be generated by the host. No SYNC signal will therefore be
616 provided to the CRS to calibrate the HSI48 on the run. To guarantee the required clock
617 precision after waking up from Sleep mode, the LSE or reference clock on the GPIOs
618 should be used as SYNC signal.
619
620 (##) A polling function is provided to wait for complete synchronization
621 (+++) Call function HAL_RCCEx_CRSWaitSynchronization()
622 (+++) According to CRS status, user can decide to adjust again the calibration or continue
623 application if synchronization is OK
624
625 (#) User can retrieve information related to synchronization in calling function
626 HAL_RCCEx_CRSGetSynchronizationInfo()
627
628 (#) Regarding synchronization status and synchronization information, user can try a new calibration
629 in changing synchronization configuration and call again HAL_RCCEx_CRSConfig.
630 Note: When the SYNC event is detected during the downcounting phase (before reaching the zero value),
631 it means that the actual frequency is lower than the target (and so, that the TRIM value should be
632 incremented), while when it is detected during the upcounting phase it means that the actual frequency
633 is higher (and that the TRIM value should be decremented).
634
635 (#) In interrupt mode, user can resort to the available macros (__HAL_RCC_CRS_XXX_IT). Interrupts will go
636 through CRS Handler (RCC_IRQn/RCC_IRQHandler)
637 (++) Call function HAL_RCCEx_CRSConfig()
638 (++) Enable RCC_IRQn (thanks to NVIC functions)
639 (++) Enable CRS interrupt (__HAL_RCC_CRS_ENABLE_IT)
640 (++) Implement CRS status management in the following user callbacks called from
641 HAL_RCCEx_CRS_IRQHandler():
642 (+++) HAL_RCCEx_CRS_SyncOkCallback()
643 (+++) HAL_RCCEx_CRS_SyncWarnCallback()
644 (+++) HAL_RCCEx_CRS_ExpectedSyncCallback()
645 (+++) HAL_RCCEx_CRS_ErrorCallback()
646
647 (#) To force a SYNC EVENT, user can use the function HAL_RCCEx_CRSSoftwareSynchronizationGenerate().
648 This function can be called before calling HAL_RCCEx_CRSConfig (for instance in Systick handler)
649
650 @endverbatim
651 * @{
652 */
653
654 /**
655 * @brief Start automatic synchronization for polling mode
656 * @param pInit Pointer on RCC_CRSInitTypeDef structure
657 * @retval None
658 */
HAL_RCCEx_CRSConfig(RCC_CRSInitTypeDef * pInit)659 void HAL_RCCEx_CRSConfig(RCC_CRSInitTypeDef *pInit)
660 {
661 uint32_t value = 0U;
662
663 /* Check the parameters */
664 assert_param(IS_RCC_CRS_SYNC_DIV(pInit->Prescaler));
665 assert_param(IS_RCC_CRS_SYNC_SOURCE(pInit->Source));
666 assert_param(IS_RCC_CRS_SYNC_POLARITY(pInit->Polarity));
667 assert_param(IS_RCC_CRS_RELOADVALUE(pInit->ReloadValue));
668 assert_param(IS_RCC_CRS_ERRORLIMIT(pInit->ErrorLimitValue));
669 assert_param(IS_RCC_CRS_HSI48CALIBRATION(pInit->HSI48CalibrationValue));
670
671 /* CONFIGURATION */
672
673 /* Before configuration, reset CRS registers to their default values*/
674 __HAL_RCC_CRS_FORCE_RESET();
675 __HAL_RCC_CRS_RELEASE_RESET();
676
677 /* Set the SYNCDIV[2:0] bits according to Prescaler value */
678 /* Set the SYNCSRC[1:0] bits according to Source value */
679 /* Set the SYNCSPOL bit according to Polarity value */
680 value = (pInit->Prescaler | pInit->Source | pInit->Polarity);
681 /* Set the RELOAD[15:0] bits according to ReloadValue value */
682 value |= pInit->ReloadValue;
683 /* Set the FELIM[7:0] bits according to ErrorLimitValue value */
684 value |= (pInit->ErrorLimitValue << CRS_CFGR_FELIM_BITNUMBER);
685 WRITE_REG(CRS->CFGR, value);
686
687 /* Adjust HSI48 oscillator smooth trimming */
688 /* Set the TRIM[5:0] bits according to RCC_CRS_HSI48CalibrationValue value */
689 MODIFY_REG(CRS->CR, CRS_CR_TRIM, (pInit->HSI48CalibrationValue << CRS_CR_TRIM_BITNUMBER));
690
691 /* START AUTOMATIC SYNCHRONIZATION*/
692
693 /* Enable Automatic trimming & Frequency error counter */
694 SET_BIT(CRS->CR, CRS_CR_AUTOTRIMEN | CRS_CR_CEN);
695 }
696
697 /**
698 * @brief Generate the software synchronization event
699 * @retval None
700 */
HAL_RCCEx_CRSSoftwareSynchronizationGenerate(void)701 void HAL_RCCEx_CRSSoftwareSynchronizationGenerate(void)
702 {
703 SET_BIT(CRS->CR, CRS_CR_SWSYNC);
704 }
705
706 /**
707 * @brief Return synchronization info
708 * @param pSynchroInfo Pointer on RCC_CRSSynchroInfoTypeDef structure
709 * @retval None
710 */
HAL_RCCEx_CRSGetSynchronizationInfo(RCC_CRSSynchroInfoTypeDef * pSynchroInfo)711 void HAL_RCCEx_CRSGetSynchronizationInfo(RCC_CRSSynchroInfoTypeDef *pSynchroInfo)
712 {
713 /* Check the parameter */
714 assert_param(pSynchroInfo != NULL);
715
716 /* Get the reload value */
717 pSynchroInfo->ReloadValue = (uint32_t)(READ_BIT(CRS->CFGR, CRS_CFGR_RELOAD));
718
719 /* Get HSI48 oscillator smooth trimming */
720 pSynchroInfo->HSI48CalibrationValue = (uint32_t)(READ_BIT(CRS->CR, CRS_CR_TRIM) >> CRS_CR_TRIM_BITNUMBER);
721
722 /* Get Frequency error capture */
723 pSynchroInfo->FreqErrorCapture = (uint32_t)(READ_BIT(CRS->ISR, CRS_ISR_FECAP) >> CRS_ISR_FECAP_BITNUMBER);
724
725 /* Get Frequency error direction */
726 pSynchroInfo->FreqErrorDirection = (uint32_t)(READ_BIT(CRS->ISR, CRS_ISR_FEDIR));
727 }
728
729 /**
730 * @brief Wait for CRS Synchronization status.
731 * @param Timeout Duration of the timeout
732 * @note Timeout is based on the maximum time to receive a SYNC event based on synchronization
733 * frequency.
734 * @note If Timeout set to HAL_MAX_DELAY, HAL_TIMEOUT will be never returned.
735 * @retval Combination of Synchronization status
736 * This parameter can be a combination of the following values:
737 * @arg @ref RCC_CRS_TIMEOUT
738 * @arg @ref RCC_CRS_SYNCOK
739 * @arg @ref RCC_CRS_SYNCWARN
740 * @arg @ref RCC_CRS_SYNCERR
741 * @arg @ref RCC_CRS_SYNCMISS
742 * @arg @ref RCC_CRS_TRIMOVF
743 */
HAL_RCCEx_CRSWaitSynchronization(uint32_t Timeout)744 uint32_t HAL_RCCEx_CRSWaitSynchronization(uint32_t Timeout)
745 {
746 uint32_t crsstatus = RCC_CRS_NONE;
747 uint32_t tickstart = 0U;
748
749 /* Get timeout */
750 tickstart = HAL_GetTick();
751
752 /* Wait for CRS flag or timeout detection */
753 do
754 {
755 if(Timeout != HAL_MAX_DELAY)
756 {
757 if((Timeout == 0U) || ((HAL_GetTick() - tickstart) > Timeout))
758 {
759 crsstatus = RCC_CRS_TIMEOUT;
760 }
761 }
762 /* Check CRS SYNCOK flag */
763 if(__HAL_RCC_CRS_GET_FLAG(RCC_CRS_FLAG_SYNCOK))
764 {
765 /* CRS SYNC event OK */
766 crsstatus |= RCC_CRS_SYNCOK;
767
768 /* Clear CRS SYNC event OK bit */
769 __HAL_RCC_CRS_CLEAR_FLAG(RCC_CRS_FLAG_SYNCOK);
770 }
771
772 /* Check CRS SYNCWARN flag */
773 if(__HAL_RCC_CRS_GET_FLAG(RCC_CRS_FLAG_SYNCWARN))
774 {
775 /* CRS SYNC warning */
776 crsstatus |= RCC_CRS_SYNCWARN;
777
778 /* Clear CRS SYNCWARN bit */
779 __HAL_RCC_CRS_CLEAR_FLAG(RCC_CRS_FLAG_SYNCWARN);
780 }
781
782 /* Check CRS TRIM overflow flag */
783 if(__HAL_RCC_CRS_GET_FLAG(RCC_CRS_FLAG_TRIMOVF))
784 {
785 /* CRS SYNC Error */
786 crsstatus |= RCC_CRS_TRIMOVF;
787
788 /* Clear CRS Error bit */
789 __HAL_RCC_CRS_CLEAR_FLAG(RCC_CRS_FLAG_TRIMOVF);
790 }
791
792 /* Check CRS Error flag */
793 if(__HAL_RCC_CRS_GET_FLAG(RCC_CRS_FLAG_SYNCERR))
794 {
795 /* CRS SYNC Error */
796 crsstatus |= RCC_CRS_SYNCERR;
797
798 /* Clear CRS Error bit */
799 __HAL_RCC_CRS_CLEAR_FLAG(RCC_CRS_FLAG_SYNCERR);
800 }
801
802 /* Check CRS SYNC Missed flag */
803 if(__HAL_RCC_CRS_GET_FLAG(RCC_CRS_FLAG_SYNCMISS))
804 {
805 /* CRS SYNC Missed */
806 crsstatus |= RCC_CRS_SYNCMISS;
807
808 /* Clear CRS SYNC Missed bit */
809 __HAL_RCC_CRS_CLEAR_FLAG(RCC_CRS_FLAG_SYNCMISS);
810 }
811
812 /* Check CRS Expected SYNC flag */
813 if(__HAL_RCC_CRS_GET_FLAG(RCC_CRS_FLAG_ESYNC))
814 {
815 /* frequency error counter reached a zero value */
816 __HAL_RCC_CRS_CLEAR_FLAG(RCC_CRS_FLAG_ESYNC);
817 }
818 } while(RCC_CRS_NONE == crsstatus);
819
820 return crsstatus;
821 }
822
823 /**
824 * @brief Handle the Clock Recovery System interrupt request.
825 * @retval None
826 */
HAL_RCCEx_CRS_IRQHandler(void)827 void HAL_RCCEx_CRS_IRQHandler(void)
828 {
829 uint32_t crserror = RCC_CRS_NONE;
830 /* Get current IT flags and IT sources values */
831 uint32_t itflags = READ_REG(CRS->ISR);
832 uint32_t itsources = READ_REG(CRS->CR);
833
834 /* Check CRS SYNCOK flag */
835 if(((itflags & RCC_CRS_FLAG_SYNCOK) != RESET) && ((itsources & RCC_CRS_IT_SYNCOK) != RESET))
836 {
837 /* Clear CRS SYNC event OK flag */
838 WRITE_REG(CRS->ICR, CRS_ICR_SYNCOKC);
839
840 /* user callback */
841 HAL_RCCEx_CRS_SyncOkCallback();
842 }
843 /* Check CRS SYNCWARN flag */
844 else if(((itflags & RCC_CRS_FLAG_SYNCWARN) != RESET) && ((itsources & RCC_CRS_IT_SYNCWARN) != RESET))
845 {
846 /* Clear CRS SYNCWARN flag */
847 WRITE_REG(CRS->ICR, CRS_ICR_SYNCWARNC);
848
849 /* user callback */
850 HAL_RCCEx_CRS_SyncWarnCallback();
851 }
852 /* Check CRS Expected SYNC flag */
853 else if(((itflags & RCC_CRS_FLAG_ESYNC) != RESET) && ((itsources & RCC_CRS_IT_ESYNC) != RESET))
854 {
855 /* frequency error counter reached a zero value */
856 WRITE_REG(CRS->ICR, CRS_ICR_ESYNCC);
857
858 /* user callback */
859 HAL_RCCEx_CRS_ExpectedSyncCallback();
860 }
861 /* Check CRS Error flags */
862 else
863 {
864 if(((itflags & RCC_CRS_FLAG_ERR) != RESET) && ((itsources & RCC_CRS_IT_ERR) != RESET))
865 {
866 if((itflags & RCC_CRS_FLAG_SYNCERR) != RESET)
867 {
868 crserror |= RCC_CRS_SYNCERR;
869 }
870 if((itflags & RCC_CRS_FLAG_SYNCMISS) != RESET)
871 {
872 crserror |= RCC_CRS_SYNCMISS;
873 }
874 if((itflags & RCC_CRS_FLAG_TRIMOVF) != RESET)
875 {
876 crserror |= RCC_CRS_TRIMOVF;
877 }
878
879 /* Clear CRS Error flags */
880 WRITE_REG(CRS->ICR, CRS_ICR_ERRC);
881
882 /* user error callback */
883 HAL_RCCEx_CRS_ErrorCallback(crserror);
884 }
885 }
886 }
887
888 /**
889 * @brief RCCEx Clock Recovery System SYNCOK interrupt callback.
890 * @retval none
891 */
HAL_RCCEx_CRS_SyncOkCallback(void)892 __weak void HAL_RCCEx_CRS_SyncOkCallback(void)
893 {
894 /* NOTE : This function should not be modified, when the callback is needed,
895 the @ref HAL_RCCEx_CRS_SyncOkCallback should be implemented in the user file
896 */
897 }
898
899 /**
900 * @brief RCCEx Clock Recovery System SYNCWARN interrupt callback.
901 * @retval none
902 */
HAL_RCCEx_CRS_SyncWarnCallback(void)903 __weak void HAL_RCCEx_CRS_SyncWarnCallback(void)
904 {
905 /* NOTE : This function should not be modified, when the callback is needed,
906 the @ref HAL_RCCEx_CRS_SyncWarnCallback should be implemented in the user file
907 */
908 }
909
910 /**
911 * @brief RCCEx Clock Recovery System Expected SYNC interrupt callback.
912 * @retval none
913 */
HAL_RCCEx_CRS_ExpectedSyncCallback(void)914 __weak void HAL_RCCEx_CRS_ExpectedSyncCallback(void)
915 {
916 /* NOTE : This function should not be modified, when the callback is needed,
917 the @ref HAL_RCCEx_CRS_ExpectedSyncCallback should be implemented in the user file
918 */
919 }
920
921 /**
922 * @brief RCCEx Clock Recovery System Error interrupt callback.
923 * @param Error Combination of Error status.
924 * This parameter can be a combination of the following values:
925 * @arg @ref RCC_CRS_SYNCERR
926 * @arg @ref RCC_CRS_SYNCMISS
927 * @arg @ref RCC_CRS_TRIMOVF
928 * @retval none
929 */
HAL_RCCEx_CRS_ErrorCallback(uint32_t Error)930 __weak void HAL_RCCEx_CRS_ErrorCallback(uint32_t Error)
931 {
932 /* Prevent unused argument(s) compilation warning */
933 UNUSED(Error);
934
935 /* NOTE : This function should not be modified, when the callback is needed,
936 the @ref HAL_RCCEx_CRS_ErrorCallback should be implemented in the user file
937 */
938 }
939
940 /**
941 * @}
942 */
943
944 #endif /* CRS */
945
946 /**
947 * @}
948 */
949
950 /**
951 * @}
952 */
953
954 /**
955 * @}
956 */
957
958 #endif /* HAL_RCC_MODULE_ENABLED */
959
960 /**
961 * @}
962 */
963
964 /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
965