1 /**
2 ******************************************************************************
3 * @file stm32l0xx_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 * Copyright (c) 2016 STMicroelectronics.
15 * All rights reserved.
16 *
17 * This software is licensed under terms that can be found in the LICENSE file in
18 * the root directory of this software component.
19 * If no LICENSE file comes with this software, it is provided AS-IS.
20 ******************************************************************************
21 */
22
23 /* Includes ------------------------------------------------------------------*/
24 #include "stm32l0xx_hal.h"
25
26 /** @addtogroup STM32L0xx_HAL_Driver
27 * @{
28 */
29
30 #ifdef HAL_RCC_MODULE_ENABLED
31
32 /** @defgroup RCCEx RCCEx
33 * @brief RCC Extension HAL module driver
34 * @{
35 */
36
37 /* Private typedef -----------------------------------------------------------*/
38 /* Private define ------------------------------------------------------------*/
39 /** @defgroup RCCEx_Private_Constants RCCEx Private Constants
40 * @{
41 */
42 #if defined(USB)
43 extern const uint8_t PLLMulTable[];
44 #endif /* USB */
45 /**
46 * @}
47 */
48
49 /* Private macro -------------------------------------------------------------*/
50 /** @defgroup RCCEx_Private_Macros RCCEx Private Macros
51 * @{
52 */
53 /**
54 * @}
55 */
56
57 /* Private variables ---------------------------------------------------------*/
58 /* Private function prototypes -----------------------------------------------*/
59 /* Private functions ---------------------------------------------------------*/
60
61 /** @defgroup RCCEx_Exported_Functions RCCEx Exported Functions
62 * @{
63 */
64
65 /** @defgroup RCCEx_Exported_Functions_Group1 Extended Peripheral Control functions
66 * @brief Extended Peripheral Control functions
67 *
68 @verbatim
69 ===============================================================================
70 ##### Extended Peripheral Control functions #####
71 ===============================================================================
72 [..]
73 This subsection provides a set of functions allowing to control the RCC Clocks
74 frequencies.
75 [..]
76 (@) Important note: Care must be taken when HAL_RCCEx_PeriphCLKConfig() is used to
77 select the RTC clock source; in this case the Backup domain will be reset in
78 order to modify the RTC Clock source, as consequence RTC registers (including
79 the backup registers) are set to their reset values.
80
81 @endverbatim
82 * @{
83 */
84
85 /**
86 * @brief Initializes the RCC extended peripherals clocks according to the specified
87 * parameters in the RCC_PeriphCLKInitTypeDef.
88 * @param PeriphClkInit pointer to an RCC_PeriphCLKInitTypeDef structure that
89 * contains the configuration information for the Extended Peripherals clocks(USART1,USART2, LPUART1,
90 * I2C1, I2C3, RTC, USB/RNG and LPTIM1 clocks).
91 * @retval HAL status
92 * @note If HAL_ERROR returned, first switch-OFF HSE clock oscillator with @ref HAL_RCC_OscConfig()
93 * to possibly update HSE divider.
94 */
HAL_RCCEx_PeriphCLKConfig(RCC_PeriphCLKInitTypeDef * PeriphClkInit)95 HAL_StatusTypeDef HAL_RCCEx_PeriphCLKConfig(RCC_PeriphCLKInitTypeDef *PeriphClkInit)
96 {
97 uint32_t tickstart;
98 uint32_t temp_reg;
99 FlagStatus pwrclkchanged = RESET;
100
101 /* Check the parameters */
102 assert_param(IS_RCC_PERIPHCLOCK(PeriphClkInit->PeriphClockSelection));
103
104 /*------------------------------- RTC/LCD Configuration ------------------------*/
105 if ((((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_RTC) == RCC_PERIPHCLK_RTC)
106 #if defined(LCD)
107 || (((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_LCD) == RCC_PERIPHCLK_LCD)
108 #endif /* LCD */
109 )
110 {
111 /* check for RTC Parameters used to output RTCCLK */
112 if(((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_RTC) == RCC_PERIPHCLK_RTC)
113 {
114 assert_param(IS_RCC_RTCCLKSOURCE(PeriphClkInit->RTCClockSelection));
115 }
116
117 #if defined(LCD)
118 if(((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_LCD) == RCC_PERIPHCLK_LCD)
119 {
120 assert_param(IS_RCC_RTCCLKSOURCE(PeriphClkInit->LCDClockSelection));
121 }
122 #endif /* LCD */
123
124 /* As soon as function is called to change RTC clock source, activation of the
125 power domain is done. */
126 /* Requires to enable write access to Backup Domain of necessary */
127 if(__HAL_RCC_PWR_IS_CLK_DISABLED())
128 {
129 __HAL_RCC_PWR_CLK_ENABLE();
130 pwrclkchanged = SET;
131 }
132
133 if(HAL_IS_BIT_CLR(PWR->CR, PWR_CR_DBP))
134 {
135 /* Enable write access to Backup domain */
136 SET_BIT(PWR->CR, PWR_CR_DBP);
137
138 /* Wait for Backup domain Write protection disable */
139 tickstart = HAL_GetTick();
140
141 while(HAL_IS_BIT_CLR(PWR->CR, PWR_CR_DBP))
142 {
143 if((HAL_GetTick() - tickstart) > RCC_DBP_TIMEOUT_VALUE)
144 {
145 return HAL_TIMEOUT;
146 }
147 }
148 }
149
150 /* Check if user wants to change HSE RTC prescaler whereas HSE is enabled */
151 temp_reg = (RCC->CR & RCC_CR_RTCPRE);
152 if ((temp_reg != (PeriphClkInit->RTCClockSelection & RCC_CR_RTCPRE))
153 #if defined (LCD)
154 || (temp_reg != (PeriphClkInit->LCDClockSelection & RCC_CR_RTCPRE))
155 #endif /* LCD */
156 )
157 { /* Check HSE State */
158 if ((PeriphClkInit->RTCClockSelection & RCC_CSR_RTCSEL) == RCC_CSR_RTCSEL_HSE)
159 {
160 if (HAL_IS_BIT_SET(RCC->CR, RCC_CR_HSERDY))
161 {
162 /* To update HSE divider, first switch-OFF HSE clock oscillator*/
163 return HAL_ERROR;
164 }
165 }
166 }
167
168 /* Reset the Backup domain only if the RTC Clock source selection is modified from reset value */
169 temp_reg = (RCC->CSR & RCC_CSR_RTCSEL);
170
171 if((temp_reg != 0x00000000U) && (((temp_reg != (PeriphClkInit->RTCClockSelection & RCC_CSR_RTCSEL)) \
172 && (((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_RTC) == RCC_PERIPHCLK_RTC))
173 #if defined(LCD)
174 || ((temp_reg != (PeriphClkInit->LCDClockSelection & RCC_CSR_RTCSEL)) \
175 && (((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_LCD) == RCC_PERIPHCLK_LCD))
176 #endif /* LCD */
177 ))
178 {
179 /* Store the content of CSR register before the reset of Backup Domain */
180 temp_reg = (RCC->CSR & ~(RCC_CSR_RTCSEL));
181
182 /* RTC Clock selection can be changed only if the Backup Domain is reset */
183 __HAL_RCC_BACKUPRESET_FORCE();
184 __HAL_RCC_BACKUPRESET_RELEASE();
185
186 /* Restore the Content of CSR register */
187 RCC->CSR = temp_reg;
188
189 /* Wait for LSERDY if LSE was enabled */
190 if (HAL_IS_BIT_SET(temp_reg, RCC_CSR_LSEON))
191 {
192 /* Get Start Tick */
193 tickstart = HAL_GetTick();
194
195 /* Wait till LSE is ready */
196 while(__HAL_RCC_GET_FLAG(RCC_FLAG_LSERDY) == 0U)
197 {
198 if((HAL_GetTick() - tickstart ) > RCC_LSE_TIMEOUT_VALUE)
199 {
200 return HAL_TIMEOUT;
201 }
202 }
203 }
204 }
205 #if defined(LCD)
206 if(((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_LCD) == RCC_PERIPHCLK_LCD)
207 {
208 __HAL_RCC_LCD_CONFIG(PeriphClkInit->LCDClockSelection);
209 }
210 #endif /* LCD */
211
212 if(((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_RTC) == RCC_PERIPHCLK_RTC)
213 {
214 __HAL_RCC_RTC_CONFIG(PeriphClkInit->RTCClockSelection);
215 }
216
217 /* Require to disable power clock if necessary */
218 if(pwrclkchanged == SET)
219 {
220 __HAL_RCC_PWR_CLK_DISABLE();
221 }
222 }
223
224 #if defined (RCC_CCIPR_USART1SEL)
225 /*------------------------------- USART1 Configuration ------------------------*/
226 if(((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_USART1) == RCC_PERIPHCLK_USART1)
227 {
228 /* Check the parameters */
229 assert_param(IS_RCC_USART1CLKSOURCE(PeriphClkInit->Usart1ClockSelection));
230
231 /* Configure the USART1 clock source */
232 __HAL_RCC_USART1_CONFIG(PeriphClkInit->Usart1ClockSelection);
233 }
234 #endif /* RCC_CCIPR_USART1SEL */
235
236 /*----------------------------- USART2 Configuration --------------------------*/
237 if(((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_USART2) == RCC_PERIPHCLK_USART2)
238 {
239 /* Check the parameters */
240 assert_param(IS_RCC_USART2CLKSOURCE(PeriphClkInit->Usart2ClockSelection));
241
242 /* Configure the USART2 clock source */
243 __HAL_RCC_USART2_CONFIG(PeriphClkInit->Usart2ClockSelection);
244 }
245
246 /*------------------------------ LPUART1 Configuration ------------------------*/
247 if(((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_LPUART1) == RCC_PERIPHCLK_LPUART1)
248 {
249 /* Check the parameters */
250 assert_param(IS_RCC_LPUART1CLKSOURCE(PeriphClkInit->Lpuart1ClockSelection));
251
252 /* Configure the LPUAR1 clock source */
253 __HAL_RCC_LPUART1_CONFIG(PeriphClkInit->Lpuart1ClockSelection);
254 }
255
256 /*------------------------------ I2C1 Configuration ------------------------*/
257 if(((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_I2C1) == RCC_PERIPHCLK_I2C1)
258 {
259 /* Check the parameters */
260 assert_param(IS_RCC_I2C1CLKSOURCE(PeriphClkInit->I2c1ClockSelection));
261
262 /* Configure the I2C1 clock source */
263 __HAL_RCC_I2C1_CONFIG(PeriphClkInit->I2c1ClockSelection);
264 }
265
266 #if defined (RCC_CCIPR_I2C3SEL)
267 /*------------------------------ I2C3 Configuration ------------------------*/
268 if(((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_I2C3) == RCC_PERIPHCLK_I2C3)
269 {
270 /* Check the parameters */
271 assert_param(IS_RCC_I2C3CLKSOURCE(PeriphClkInit->I2c3ClockSelection));
272
273 /* Configure the I2C3 clock source */
274 __HAL_RCC_I2C3_CONFIG(PeriphClkInit->I2c3ClockSelection);
275 }
276 #endif /* RCC_CCIPR_I2C3SEL */
277
278 #if defined(USB)
279 /*---------------------------- USB and RNG configuration --------------------*/
280 if(((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_USB) == (RCC_PERIPHCLK_USB))
281 {
282 assert_param(IS_RCC_USBCLKSOURCE(PeriphClkInit->UsbClockSelection));
283 __HAL_RCC_USB_CONFIG(PeriphClkInit->UsbClockSelection);
284 }
285 #endif /* USB */
286
287 /*---------------------------- LPTIM1 configuration ------------------------*/
288 if(((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_LPTIM1) == (RCC_PERIPHCLK_LPTIM1))
289 {
290 assert_param(IS_RCC_LPTIMCLK(PeriphClkInit->LptimClockSelection));
291 __HAL_RCC_LPTIM1_CONFIG(PeriphClkInit->LptimClockSelection);
292 }
293
294 return HAL_OK;
295 }
296
297 /**
298 * @brief Get the PeriphClkInit according to the internal RCC configuration registers.
299 * @param PeriphClkInit pointer to an RCC_PeriphCLKInitTypeDef structure that
300 * returns the configuration information for the Extended Peripherals clocks(USART1,USART2, LPUART1,
301 * I2C1, I2C3, RTC, USB/RNG and LPTIM1 clocks).
302 * @retval None
303 */
HAL_RCCEx_GetPeriphCLKConfig(RCC_PeriphCLKInitTypeDef * PeriphClkInit)304 void HAL_RCCEx_GetPeriphCLKConfig(RCC_PeriphCLKInitTypeDef *PeriphClkInit)
305 {
306 uint32_t srcclk;
307
308 /* Set all possible values for the extended clock type parameter -----------*/
309 /* Common part first */
310 PeriphClkInit->PeriphClockSelection = RCC_PERIPHCLK_USART2 | RCC_PERIPHCLK_LPUART1 | \
311 RCC_PERIPHCLK_I2C1 | RCC_PERIPHCLK_RTC | \
312 RCC_PERIPHCLK_LPTIM1;
313 #if defined(RCC_CCIPR_USART1SEL)
314 PeriphClkInit->PeriphClockSelection |= RCC_PERIPHCLK_USART1;
315 #endif /* RCC_CCIPR_USART1SEL */
316 #if defined(RCC_CCIPR_I2C3SEL)
317 PeriphClkInit->PeriphClockSelection |= RCC_PERIPHCLK_I2C3;
318 #endif /* RCC_CCIPR_I2C3SEL */
319 #if defined(USB)
320 PeriphClkInit->PeriphClockSelection |= RCC_PERIPHCLK_USB;
321 #endif /* USB */
322 #if defined(LCD)
323 PeriphClkInit->PeriphClockSelection |= RCC_PERIPHCLK_LCD;
324 #endif /* LCD */
325
326 /* Get the RTC/LCD configuration -----------------------------------------------*/
327 srcclk = __HAL_RCC_GET_RTC_SOURCE();
328 if (srcclk != RCC_RTCCLKSOURCE_HSE_DIV2)
329 {
330 /* Source clock is LSE or LSI*/
331 PeriphClkInit->RTCClockSelection = srcclk;
332 }
333 else
334 {
335 /* Source clock is HSE. Need to get the prescaler value*/
336 PeriphClkInit->RTCClockSelection = srcclk | (READ_BIT(RCC->CR, RCC_CR_RTCPRE));
337 }
338 #if defined(LCD)
339 PeriphClkInit->LCDClockSelection = PeriphClkInit->RTCClockSelection;
340 #endif /* LCD */
341 #if defined(RCC_CCIPR_USART1SEL)
342 /* Get the USART1 configuration --------------------------------------------*/
343 PeriphClkInit->Usart1ClockSelection = __HAL_RCC_GET_USART1_SOURCE();
344 #endif /* RCC_CCIPR_USART1SEL */
345 /* Get the USART2 clock source ---------------------------------------------*/
346 PeriphClkInit->Usart2ClockSelection = __HAL_RCC_GET_USART2_SOURCE();
347 /* Get the LPUART1 clock source ---------------------------------------------*/
348 PeriphClkInit->Lpuart1ClockSelection = __HAL_RCC_GET_LPUART1_SOURCE();
349 /* Get the I2C1 clock source -----------------------------------------------*/
350 PeriphClkInit->I2c1ClockSelection = __HAL_RCC_GET_I2C1_SOURCE();
351 #if defined(RCC_CCIPR_I2C3SEL)
352 /* Get the I2C3 clock source -----------------------------------------------*/
353 PeriphClkInit->I2c3ClockSelection = __HAL_RCC_GET_I2C3_SOURCE();
354 #endif /* RCC_CCIPR_I2C3SEL */
355 /* Get the LPTIM1 clock source -----------------------------------------------*/
356 PeriphClkInit->LptimClockSelection = __HAL_RCC_GET_LPTIM1_SOURCE();
357 /* Get the RTC clock source -----------------------------------------------*/
358 PeriphClkInit->RTCClockSelection = __HAL_RCC_GET_RTC_SOURCE();
359 #if defined(USB)
360 /* Get the USB/RNG clock source -----------------------------------------------*/
361 PeriphClkInit->UsbClockSelection = __HAL_RCC_GET_USB_SOURCE();
362 #endif /* USB */
363 }
364
365 /**
366 * @brief Return the peripheral clock frequency
367 * @note Return 0 if peripheral clock is unknown
368 * @param PeriphClk Peripheral clock identifier
369 * This parameter can be one of the following values:
370 * @arg @ref RCC_PERIPHCLK_RTC RTC peripheral clock
371 * @arg @ref RCC_PERIPHCLK_LCD LCD peripheral clock (*)
372 * @arg @ref RCC_PERIPHCLK_USB USB or RNG peripheral clock (*)
373 * @arg @ref RCC_PERIPHCLK_USART1 USART1 peripheral clock (*)
374 * @arg @ref RCC_PERIPHCLK_USART2 USART2 peripheral clock
375 * @arg @ref RCC_PERIPHCLK_LPUART1 LPUART1 peripheral clock
376 * @arg @ref RCC_PERIPHCLK_I2C1 I2C1 peripheral clock
377 * @arg @ref RCC_PERIPHCLK_I2C2 I2C2 peripheral clock (*)
378 * @arg @ref RCC_PERIPHCLK_I2C3 I2C3 peripheral clock (*)
379 * @note (*) means that this peripheral is not present on all the devices
380 * @retval Frequency in Hz (0: means that no available frequency for the peripheral)
381 */
HAL_RCCEx_GetPeriphCLKFreq(uint32_t PeriphClk)382 uint32_t HAL_RCCEx_GetPeriphCLKFreq(uint32_t PeriphClk)
383 {
384 uint32_t frequency = 0U;
385 uint32_t temp_reg, clkprediv, srcclk; /* no init needed */
386 #if defined(USB)
387 uint32_t pllmul, plldiv, pllvco; /* no init needed */
388 #endif /* USB */
389
390 /* Check the parameters */
391 assert_param(IS_RCC_PERIPHCLOCK(PeriphClk));
392
393 switch (PeriphClk)
394 {
395 case RCC_PERIPHCLK_RTC:
396 #if defined(LCD)
397 case RCC_PERIPHCLK_LCD:
398 #endif /* LCD */
399 {
400 /* Get RCC CSR configuration ------------------------------------------------------*/
401 temp_reg = RCC->CSR;
402
403 /* Get the current RTC source */
404 srcclk = __HAL_RCC_GET_RTC_SOURCE();
405
406 /* Check if LSE is ready if RTC clock selection is LSE */
407 if ((srcclk == RCC_RTCCLKSOURCE_LSE) && (HAL_IS_BIT_SET(temp_reg, RCC_CSR_LSERDY)))
408 {
409 frequency = LSE_VALUE;
410 }
411 /* Check if LSI is ready if RTC clock selection is LSI */
412 else if (srcclk == RCC_RTCCLKSOURCE_LSI)
413 {
414 if (HAL_IS_BIT_SET(temp_reg, RCC_CSR_LSIRDY))
415 {
416 frequency = LSI_VALUE;
417 }
418 }
419 /* Check if HSE is ready and if RTC clock selection is HSE */
420 else if (srcclk == RCC_RTCCLKSOURCE_HSE_DIVX)
421 {
422 if (HAL_IS_BIT_SET(RCC->CR, RCC_CR_HSERDY))
423 {
424 /* Get the current HSE clock divider */
425 clkprediv = __HAL_RCC_GET_RTC_HSE_PRESCALER();
426
427 switch (clkprediv)
428 {
429 case RCC_RTC_HSE_DIV_16: /* HSE DIV16 has been selected */
430 {
431 frequency = HSE_VALUE / 16U;
432 break;
433 }
434 case RCC_RTC_HSE_DIV_8: /* HSE DIV8 has been selected */
435 {
436 frequency = HSE_VALUE / 8U;
437 break;
438 }
439 case RCC_RTC_HSE_DIV_4: /* HSE DIV4 has been selected */
440 {
441 frequency = HSE_VALUE / 4U;
442 break;
443 }
444 default: /* HSE DIV2 has been selected */
445 {
446 frequency = HSE_VALUE / 2U;
447 break;
448 }
449 }
450 }
451 }
452 /* Clock not enabled for RTC */
453 else
454 {
455 /* nothing to do: frequency already initialized to 0U */
456 }
457 break;
458 }
459 #if defined(USB)
460 case RCC_PERIPHCLK_USB:
461 {
462 /* Get the current USB source */
463 srcclk = __HAL_RCC_GET_USB_SOURCE();
464
465 if (srcclk == RCC_USBCLKSOURCE_PLL)
466 {
467 if (HAL_IS_BIT_SET(RCC->CR, RCC_CR_PLLRDY))
468 {
469 /* Get PLL clock source and multiplication factor ----------------------*/
470 pllmul = RCC->CFGR & RCC_CFGR_PLLMUL;
471 plldiv = RCC->CFGR & RCC_CFGR_PLLDIV;
472 pllmul = PLLMulTable[(pllmul >> RCC_CFGR_PLLMUL_Pos)];
473 plldiv = (plldiv >> RCC_CFGR_PLLDIV_Pos) + 1U;
474
475 /* Compute PLL clock input */
476 if(__HAL_RCC_GET_PLL_OSCSOURCE() == RCC_PLLSOURCE_HSI)
477 {
478 if (READ_BIT(RCC->CR, RCC_CR_HSIDIVF) != 0U)
479 {
480 pllvco = (HSI_VALUE >> 2U);
481 }
482 else
483 {
484 pllvco = HSI_VALUE;
485 }
486 }
487 else /* HSE source */
488 {
489 pllvco = HSE_VALUE;
490 }
491 /* pllvco * pllmul / plldiv */
492 pllvco = (pllvco * pllmul);
493 frequency = (pllvco/ plldiv);
494 }
495 }
496 else if (srcclk == RCC_USBCLKSOURCE_HSI48)
497 {
498 if (HAL_IS_BIT_SET(RCC->CRRCR, RCC_CRRCR_HSI48RDY))
499 {
500 frequency = HSI48_VALUE;
501 }
502 }
503 else /* RCC_USBCLKSOURCE_NONE */
504 {
505 /* nothing to do: frequency already initialized to 0U */
506 }
507 break;
508 }
509 #endif /* USB */
510 #if defined(RCC_CCIPR_USART1SEL)
511 case RCC_PERIPHCLK_USART1:
512 {
513 /* Get the current USART1 source */
514 srcclk = __HAL_RCC_GET_USART1_SOURCE();
515
516 /* Check if USART1 clock selection is PCLK2 */
517 if (srcclk == RCC_USART1CLKSOURCE_PCLK2)
518 {
519 frequency = HAL_RCC_GetPCLK2Freq();
520 }
521 /* Check if HSI is ready and if USART1 clock selection is HSI */
522 else if (srcclk == RCC_USART1CLKSOURCE_HSI)
523 {
524 if (HAL_IS_BIT_SET(RCC->CR, RCC_CR_HSIRDY))
525 {
526 if (READ_BIT(RCC->CR, RCC_CR_HSIDIVF) != 0U)
527 {
528 frequency = (HSI_VALUE >> 2U);
529 }
530 else
531 {
532 frequency = HSI_VALUE;
533 }
534 }
535 }
536 /* Check if USART1 clock selection is SYSCLK */
537 else if (srcclk == RCC_USART1CLKSOURCE_SYSCLK)
538 {
539 frequency = HAL_RCC_GetSysClockFreq();
540 }
541 /* Check if LSE is ready and if USART1 clock selection is LSE */
542 else if (srcclk == RCC_USART1CLKSOURCE_LSE)
543 {
544 if (HAL_IS_BIT_SET(RCC->CSR, RCC_CSR_LSERDY))
545 {
546 frequency = LSE_VALUE;
547 }
548 }
549 /* Clock not enabled for USART1*/
550 else
551 {
552 /* nothing to do: frequency already initialized to 0U */
553 }
554 break;
555 }
556 #endif /* RCC_CCIPR_USART1SEL */
557 case RCC_PERIPHCLK_USART2:
558 {
559 /* Get the current USART2 source */
560 srcclk = __HAL_RCC_GET_USART2_SOURCE();
561
562 /* Check if USART2 clock selection is PCLK1 */
563 if (srcclk == RCC_USART2CLKSOURCE_PCLK1)
564 {
565 frequency = HAL_RCC_GetPCLK1Freq();
566 }
567 /* Check if HSI is ready and if USART2 clock selection is HSI */
568 else if (srcclk == RCC_USART2CLKSOURCE_HSI)
569 {
570 if (HAL_IS_BIT_SET(RCC->CR, RCC_CR_HSIRDY))
571 {
572 if (READ_BIT(RCC->CR, RCC_CR_HSIDIVF) != 0U)
573 {
574 frequency = (HSI_VALUE >> 2U);
575 }
576 else
577 {
578 frequency = HSI_VALUE;
579 }
580 }
581 }
582 /* Check if USART2 clock selection is SYSCLK */
583 else if (srcclk == RCC_USART2CLKSOURCE_SYSCLK)
584 {
585 frequency = HAL_RCC_GetSysClockFreq();
586 }
587 /* Check if LSE is ready and if USART2 clock selection is LSE */
588 else if (srcclk == RCC_USART2CLKSOURCE_LSE)
589 {
590 if (HAL_IS_BIT_SET(RCC->CSR, RCC_CSR_LSERDY))
591 {
592 frequency = LSE_VALUE;
593 }
594 }
595 /* Clock not enabled for USART2*/
596 else
597 {
598 /* nothing to do: frequency already initialized to 0U */
599 }
600 break;
601 }
602 case RCC_PERIPHCLK_LPUART1:
603 {
604 /* Get the current LPUART1 source */
605 srcclk = __HAL_RCC_GET_LPUART1_SOURCE();
606
607 /* Check if LPUART1 clock selection is PCLK1 */
608 if (srcclk == RCC_LPUART1CLKSOURCE_PCLK1)
609 {
610 frequency = HAL_RCC_GetPCLK1Freq();
611 }
612 /* Check if HSI is ready and if LPUART1 clock selection is HSI */
613 else if (srcclk == RCC_LPUART1CLKSOURCE_HSI)
614 {
615 if (HAL_IS_BIT_SET(RCC->CR, RCC_CR_HSIRDY))
616 {
617 if (READ_BIT(RCC->CR, RCC_CR_HSIDIVF) != 0U)
618 {
619 frequency = (HSI_VALUE >> 2U);
620 }
621 else
622 {
623 frequency = HSI_VALUE;
624 }
625 }
626 }
627 /* Check if LPUART1 clock selection is SYSCLK */
628 else if (srcclk == RCC_LPUART1CLKSOURCE_SYSCLK)
629 {
630 frequency = HAL_RCC_GetSysClockFreq();
631 }
632 /* Check if LSE is ready and if LPUART1 clock selection is LSE */
633 else if (srcclk == RCC_LPUART1CLKSOURCE_LSE)
634 {
635 if (HAL_IS_BIT_SET(RCC->CSR, RCC_CSR_LSERDY))
636 {
637 frequency = LSE_VALUE;
638 }
639 }
640 /* Clock not enabled for LPUART1*/
641 else
642 {
643 /* nothing to do: frequency already initialized to 0U */
644 }
645 break;
646 }
647 case RCC_PERIPHCLK_I2C1:
648 {
649 /* Get the current I2C1 source */
650 srcclk = __HAL_RCC_GET_I2C1_SOURCE();
651
652 /* Check if I2C1 clock selection is PCLK1 */
653 if (srcclk == RCC_I2C1CLKSOURCE_PCLK1)
654 {
655 frequency = HAL_RCC_GetPCLK1Freq();
656 }
657 /* Check if HSI is ready and if I2C1 clock selection is HSI */
658 else if (srcclk == RCC_I2C1CLKSOURCE_HSI)
659 {
660 if (HAL_IS_BIT_SET(RCC->CR, RCC_CR_HSIRDY))
661 {
662 if (READ_BIT(RCC->CR, RCC_CR_HSIDIVF) != 0U)
663 {
664 frequency = (HSI_VALUE >> 2U);
665 }
666 else
667 {
668 frequency = HSI_VALUE;
669 }
670 }
671 }
672 /* Check if I2C1 clock selection is SYSCLK */
673 else if (srcclk == RCC_I2C1CLKSOURCE_SYSCLK)
674 {
675 frequency = HAL_RCC_GetSysClockFreq();
676 }
677 /* Clock not enabled for I2C1*/
678 else
679 {
680 /* nothing to do: frequency already initialized to 0U */
681 }
682 break;
683 }
684 #if defined(I2C2)
685 case RCC_PERIPHCLK_I2C2:
686 {
687
688 /* Check if I2C2 on APB1 clock enabled*/
689 if (READ_BIT(RCC->APB1ENR, (RCC_APB1ENR_I2C2EN))==RCC_APB1ENR_I2C2EN)
690 {
691 frequency = HAL_RCC_GetPCLK1Freq();
692 }
693 else
694 {
695 /* nothing to do: frequency already initialized to 0U */
696 }
697 break;
698 }
699 #endif /* I2C2 */
700
701 #if defined(RCC_CCIPR_I2C3SEL)
702 case RCC_PERIPHCLK_I2C3:
703 {
704 /* Get the current I2C3 source */
705 srcclk = __HAL_RCC_GET_I2C3_SOURCE();
706
707 /* Check if I2C3 clock selection is PCLK1 */
708 if (srcclk == RCC_I2C3CLKSOURCE_PCLK1)
709 {
710 frequency = HAL_RCC_GetPCLK1Freq();
711 }
712 /* Check if HSI is ready and if I2C3 clock selection is HSI */
713 else if (srcclk == RCC_I2C3CLKSOURCE_HSI)
714 {
715 if (HAL_IS_BIT_SET(RCC->CR, RCC_CR_HSIRDY))
716 {
717 if (READ_BIT(RCC->CR, RCC_CR_HSIDIVF) != 0U)
718 {
719 frequency = (HSI_VALUE >> 2U);
720 }
721 else
722 {
723 frequency = HSI_VALUE;
724 }
725 }
726 }
727 /* Check if I2C3 clock selection is SYSCLK */
728 else if (srcclk == RCC_I2C3CLKSOURCE_SYSCLK)
729 {
730 frequency = HAL_RCC_GetSysClockFreq();
731 }
732 /* Clock not enabled for I2C3*/
733 else
734 {
735 /* nothing to do: frequency already initialized to 0U */
736 }
737 break;
738 }
739 #endif /* RCC_CCIPR_I2C3SEL */
740 default:
741 {
742 break;
743 }
744 }
745 return(frequency);
746 }
747
748 /**
749 * @brief Enables the LSE Clock Security System.
750 * @retval None
751 */
HAL_RCCEx_EnableLSECSS(void)752 void HAL_RCCEx_EnableLSECSS(void)
753 {
754 SET_BIT(RCC->CSR, RCC_CSR_LSECSSON) ;
755 }
756
757 /**
758 * @brief Disables the LSE Clock Security System.
759 * @note Once enabled this bit cannot be disabled, except after an LSE failure detection
760 * (LSECSSD=1). In that case the software MUST disable the LSECSSON bit.
761 * Reset by power on reset and RTC software reset (RTCRST bit).
762 * @retval None
763 */
HAL_RCCEx_DisableLSECSS(void)764 void HAL_RCCEx_DisableLSECSS(void)
765 {
766 /* Disable LSE CSS */
767 CLEAR_BIT(RCC->CSR, RCC_CSR_LSECSSON) ;
768
769 /* Disable LSE CSS IT */
770 __HAL_RCC_DISABLE_IT(RCC_IT_LSECSS);
771 }
772
773 /**
774 * @brief Enable the LSE Clock Security System IT & corresponding EXTI line.
775 * @note LSE Clock Security System IT is mapped on RTC EXTI line 19
776 * @retval None
777 */
HAL_RCCEx_EnableLSECSS_IT(void)778 void HAL_RCCEx_EnableLSECSS_IT(void)
779 {
780 /* Enable LSE CSS */
781 SET_BIT(RCC->CSR, RCC_CSR_LSECSSON) ;
782
783 /* Enable LSE CSS IT */
784 __HAL_RCC_ENABLE_IT(RCC_IT_LSECSS);
785
786 /* Enable IT on EXTI Line 19 */
787 __HAL_RCC_LSECSS_EXTI_ENABLE_IT();
788 __HAL_RCC_LSECSS_EXTI_ENABLE_RISING_EDGE();
789 }
790
791 /**
792 * @brief Handle the RCC LSE Clock Security System interrupt request.
793 * @retval None
794 */
HAL_RCCEx_LSECSS_IRQHandler(void)795 void HAL_RCCEx_LSECSS_IRQHandler(void)
796 {
797 /* Check RCC LSE CSSF flag */
798 if(__HAL_RCC_GET_IT(RCC_IT_LSECSS))
799 {
800 /* RCC LSE Clock Security System interrupt user callback */
801 HAL_RCCEx_LSECSS_Callback();
802
803 /* Clear RCC LSE CSS pending bit */
804 __HAL_RCC_CLEAR_IT(RCC_IT_LSECSS);
805 }
806 }
807
808 /**
809 * @brief RCCEx LSE Clock Security System interrupt callback.
810 * @retval none
811 */
HAL_RCCEx_LSECSS_Callback(void)812 __weak void HAL_RCCEx_LSECSS_Callback(void)
813 {
814 /* NOTE : This function should not be modified, when the callback is needed,
815 the @ref HAL_RCCEx_LSECSS_Callback should be implemented in the user file
816 */
817 }
818
819 #if defined(SYSCFG_CFGR3_ENREF_HSI48)
820 /**
821 * @brief Enables Vrefint for the HSI48.
822 * @note This is functional only if the LOCK is not set
823 * @retval None
824 */
HAL_RCCEx_EnableHSI48_VREFINT(void)825 void HAL_RCCEx_EnableHSI48_VREFINT(void)
826 {
827 /* Enable the Buffer for the ADC by setting SYSCFG_CFGR3_ENREF_HSI48 bit in SYSCFG_CFGR3 register */
828 SET_BIT (SYSCFG->CFGR3, SYSCFG_CFGR3_ENREF_HSI48);
829 }
830
831 /**
832 * @brief Disables the Vrefint for the HSI48.
833 * @note This is functional only if the LOCK is not set
834 * @retval None
835 */
HAL_RCCEx_DisableHSI48_VREFINT(void)836 void HAL_RCCEx_DisableHSI48_VREFINT(void)
837 {
838 /* Disable the Vrefint by resetting SYSCFG_CFGR3_ENREF_HSI48 bit in SYSCFG_CFGR3 register */
839 CLEAR_BIT(SYSCFG->CFGR3, SYSCFG_CFGR3_ENREF_HSI48);
840 }
841
842 #endif /* SYSCFG_CFGR3_ENREF_HSI48 */
843
844 /**
845 * @}
846 */
847
848 #if defined (CRS)
849
850 /** @defgroup RCCEx_Exported_Functions_Group3 Extended Clock Recovery System Control functions
851 * @brief Extended Clock Recovery System Control functions
852 *
853 @verbatim
854 ===============================================================================
855 ##### Extended Clock Recovery System Control functions #####
856 ===============================================================================
857 [..]
858 For devices with Clock Recovery System feature (CRS), RCC Extension HAL driver can be used as follows:
859
860 (#) In System clock config, HSI48 needs to be enabled
861
862 (#) Enable CRS clock in IP MSP init which will use CRS functions
863
864 (#) Call CRS functions as follows:
865 (##) Prepare synchronization configuration necessary for HSI48 calibration
866 (+++) Default values can be set for frequency Error Measurement (reload and error limit)
867 and also HSI48 oscillator smooth trimming.
868 (+++) Macro __HAL_RCC_CRS_RELOADVALUE_CALCULATE can be also used to calculate
869 directly reload value with target and synchronization frequencies values
870 (##) Call function HAL_RCCEx_CRSConfig which
871 (+++) Reset CRS registers to their default values.
872 (+++) Configure CRS registers with synchronization configuration
873 (+++) Enable automatic calibration and frequency error counter feature
874 Note: When using USB LPM (Link Power Management) and the device is in Sleep mode, the
875 periodic USB SOF will not be generated by the host. No SYNC signal will therefore be
876 provided to the CRS to calibrate the HSI48 on the run. To guarantee the required clock
877 precision after waking up from Sleep mode, the LSE or reference clock on the GPIOs
878 should be used as SYNC signal.
879
880 (##) A polling function is provided to wait for complete synchronization
881 (+++) Call function HAL_RCCEx_CRSWaitSynchronization()
882 (+++) According to CRS status, user can decide to adjust again the calibration or continue
883 application if synchronization is OK
884
885 (#) User can retrieve information related to synchronization in calling function
886 HAL_RCCEx_CRSGetSynchronizationInfo()
887
888 (#) Regarding synchronization status and synchronization information, user can try a new calibration
889 in changing synchronization configuration and call again HAL_RCCEx_CRSConfig.
890 Note: When the SYNC event is detected during the downcounting phase (before reaching the zero value),
891 it means that the actual frequency is lower than the target (and so, that the TRIM value should be
892 incremented), while when it is detected during the upcounting phase it means that the actual frequency
893 is higher (and that the TRIM value should be decremented).
894
895 (#) In interrupt mode, user can resort to the available macros (__HAL_RCC_CRS_XXX_IT). Interrupts will go
896 through CRS Handler (RCC_IRQn/RCC_IRQHandler)
897 (++) Call function HAL_RCCEx_CRSConfig()
898 (++) Enable RCC_IRQn (thanks to NVIC functions)
899 (++) Enable CRS interrupt (__HAL_RCC_CRS_ENABLE_IT)
900 (++) Implement CRS status management in the following user callbacks called from
901 HAL_RCCEx_CRS_IRQHandler():
902 (+++) HAL_RCCEx_CRS_SyncOkCallback()
903 (+++) HAL_RCCEx_CRS_SyncWarnCallback()
904 (+++) HAL_RCCEx_CRS_ExpectedSyncCallback()
905 (+++) HAL_RCCEx_CRS_ErrorCallback()
906
907 (#) To force a SYNC EVENT, user can use the function HAL_RCCEx_CRSSoftwareSynchronizationGenerate().
908 This function can be called before calling HAL_RCCEx_CRSConfig (for instance in Systick handler)
909
910 @endverbatim
911 * @{
912 */
913
914 /**
915 * @brief Start automatic synchronization for polling mode
916 * @param pInit Pointer on RCC_CRSInitTypeDef structure
917 * @retval None
918 */
HAL_RCCEx_CRSConfig(RCC_CRSInitTypeDef * pInit)919 void HAL_RCCEx_CRSConfig(RCC_CRSInitTypeDef *pInit)
920 {
921 uint32_t value;
922
923 /* Check the parameters */
924 assert_param(IS_RCC_CRS_SYNC_DIV(pInit->Prescaler));
925 assert_param(IS_RCC_CRS_SYNC_SOURCE(pInit->Source));
926 assert_param(IS_RCC_CRS_SYNC_POLARITY(pInit->Polarity));
927 assert_param(IS_RCC_CRS_RELOADVALUE(pInit->ReloadValue));
928 assert_param(IS_RCC_CRS_ERRORLIMIT(pInit->ErrorLimitValue));
929 assert_param(IS_RCC_CRS_HSI48CALIBRATION(pInit->HSI48CalibrationValue));
930
931 /* CONFIGURATION */
932
933 /* Before configuration, reset CRS registers to their default values*/
934 __HAL_RCC_CRS_FORCE_RESET();
935 __HAL_RCC_CRS_RELEASE_RESET();
936
937 /* Set the SYNCDIV[2:0] bits according to Prescaler value */
938 /* Set the SYNCSRC[1:0] bits according to Source value */
939 /* Set the SYNCSPOL bit according to Polarity value */
940 value = (pInit->Prescaler | pInit->Source | pInit->Polarity);
941 /* Set the RELOAD[15:0] bits according to ReloadValue value */
942 value |= pInit->ReloadValue;
943 /* Set the FELIM[7:0] bits according to ErrorLimitValue value */
944 value |= (pInit->ErrorLimitValue << CRS_CFGR_FELIM_Pos);
945 WRITE_REG(CRS->CFGR, value);
946
947 /* Adjust HSI48 oscillator smooth trimming */
948 /* Set the TRIM[5:0] bits according to RCC_CRS_HSI48CalibrationValue value */
949 MODIFY_REG(CRS->CR, CRS_CR_TRIM, (pInit->HSI48CalibrationValue << CRS_CR_TRIM_Pos));
950
951 /* START AUTOMATIC SYNCHRONIZATION*/
952
953 /* Enable Automatic trimming & Frequency error counter */
954 SET_BIT(CRS->CR, CRS_CR_AUTOTRIMEN | CRS_CR_CEN);
955 }
956
957 /**
958 * @brief Generate the software synchronization event
959 * @retval None
960 */
HAL_RCCEx_CRSSoftwareSynchronizationGenerate(void)961 void HAL_RCCEx_CRSSoftwareSynchronizationGenerate(void)
962 {
963 SET_BIT(CRS->CR, CRS_CR_SWSYNC);
964 }
965
966 /**
967 * @brief Return synchronization info
968 * @param pSynchroInfo Pointer on RCC_CRSSynchroInfoTypeDef structure
969 * @retval None
970 */
HAL_RCCEx_CRSGetSynchronizationInfo(RCC_CRSSynchroInfoTypeDef * pSynchroInfo)971 void HAL_RCCEx_CRSGetSynchronizationInfo(RCC_CRSSynchroInfoTypeDef *pSynchroInfo)
972 {
973 /* Check the parameter */
974 assert_param(pSynchroInfo != (void *)NULL);
975
976 /* Get the reload value */
977 pSynchroInfo->ReloadValue = (uint32_t)(READ_BIT(CRS->CFGR, CRS_CFGR_RELOAD));
978
979 /* Get HSI48 oscillator smooth trimming */
980 pSynchroInfo->HSI48CalibrationValue = (uint32_t)(READ_BIT(CRS->CR, CRS_CR_TRIM) >> CRS_CR_TRIM_Pos);
981
982 /* Get Frequency error capture */
983 pSynchroInfo->FreqErrorCapture = (uint32_t)(READ_BIT(CRS->ISR, CRS_ISR_FECAP) >> CRS_ISR_FECAP_Pos);
984
985 /* Get Frequency error direction */
986 pSynchroInfo->FreqErrorDirection = (uint32_t)(READ_BIT(CRS->ISR, CRS_ISR_FEDIR));
987 }
988
989 /**
990 * @brief Wait for CRS Synchronization status.
991 * @param Timeout Duration of the timeout
992 * @note Timeout is based on the maximum time to receive a SYNC event based on synchronization
993 * frequency.
994 * @note If Timeout set to HAL_MAX_DELAY, HAL_TIMEOUT will be never returned.
995 * @retval Combination of Synchronization status
996 * This parameter can be a combination of the following values:
997 * @arg @ref RCC_CRS_TIMEOUT
998 * @arg @ref RCC_CRS_SYNCOK
999 * @arg @ref RCC_CRS_SYNCWARN
1000 * @arg @ref RCC_CRS_SYNCERR
1001 * @arg @ref RCC_CRS_SYNCMISS
1002 * @arg @ref RCC_CRS_TRIMOVF
1003 */
HAL_RCCEx_CRSWaitSynchronization(uint32_t Timeout)1004 uint32_t HAL_RCCEx_CRSWaitSynchronization(uint32_t Timeout)
1005 {
1006 uint32_t crsstatus = RCC_CRS_NONE;
1007 uint32_t tickstart;
1008
1009 /* Get timeout */
1010 tickstart = HAL_GetTick();
1011
1012 /* Wait for CRS flag or timeout detection */
1013 do
1014 {
1015 if(Timeout != HAL_MAX_DELAY)
1016 {
1017 if(((HAL_GetTick() - tickstart) > Timeout) || (Timeout == 0U))
1018 {
1019 crsstatus = RCC_CRS_TIMEOUT;
1020 }
1021 }
1022 /* Check CRS SYNCOK flag */
1023 if(__HAL_RCC_CRS_GET_FLAG(RCC_CRS_FLAG_SYNCOK))
1024 {
1025 /* CRS SYNC event OK */
1026 crsstatus |= RCC_CRS_SYNCOK;
1027
1028 /* Clear CRS SYNC event OK bit */
1029 __HAL_RCC_CRS_CLEAR_FLAG(RCC_CRS_FLAG_SYNCOK);
1030 }
1031
1032 /* Check CRS SYNCWARN flag */
1033 if(__HAL_RCC_CRS_GET_FLAG(RCC_CRS_FLAG_SYNCWARN))
1034 {
1035 /* CRS SYNC warning */
1036 crsstatus |= RCC_CRS_SYNCWARN;
1037
1038 /* Clear CRS SYNCWARN bit */
1039 __HAL_RCC_CRS_CLEAR_FLAG(RCC_CRS_FLAG_SYNCWARN);
1040 }
1041
1042 /* Check CRS TRIM overflow flag */
1043 if(__HAL_RCC_CRS_GET_FLAG(RCC_CRS_FLAG_TRIMOVF))
1044 {
1045 /* CRS SYNC Error */
1046 crsstatus |= RCC_CRS_TRIMOVF;
1047
1048 /* Clear CRS Error bit */
1049 __HAL_RCC_CRS_CLEAR_FLAG(RCC_CRS_FLAG_TRIMOVF);
1050 }
1051
1052 /* Check CRS Error flag */
1053 if(__HAL_RCC_CRS_GET_FLAG(RCC_CRS_FLAG_SYNCERR))
1054 {
1055 /* CRS SYNC Error */
1056 crsstatus |= RCC_CRS_SYNCERR;
1057
1058 /* Clear CRS Error bit */
1059 __HAL_RCC_CRS_CLEAR_FLAG(RCC_CRS_FLAG_SYNCERR);
1060 }
1061
1062 /* Check CRS SYNC Missed flag */
1063 if(__HAL_RCC_CRS_GET_FLAG(RCC_CRS_FLAG_SYNCMISS))
1064 {
1065 /* CRS SYNC Missed */
1066 crsstatus |= RCC_CRS_SYNCMISS;
1067
1068 /* Clear CRS SYNC Missed bit */
1069 __HAL_RCC_CRS_CLEAR_FLAG(RCC_CRS_FLAG_SYNCMISS);
1070 }
1071
1072 /* Check CRS Expected SYNC flag */
1073 if(__HAL_RCC_CRS_GET_FLAG(RCC_CRS_FLAG_ESYNC))
1074 {
1075 /* frequency error counter reached a zero value */
1076 __HAL_RCC_CRS_CLEAR_FLAG(RCC_CRS_FLAG_ESYNC);
1077 }
1078 } while(RCC_CRS_NONE == crsstatus);
1079
1080 return crsstatus;
1081 }
1082
1083 /**
1084 * @brief Handle the Clock Recovery System interrupt request.
1085 * @retval None
1086 */
HAL_RCCEx_CRS_IRQHandler(void)1087 void HAL_RCCEx_CRS_IRQHandler(void)
1088 {
1089 uint32_t crserror = RCC_CRS_NONE;
1090 /* Get current IT flags and IT sources values */
1091 uint32_t itflags = READ_REG(CRS->ISR);
1092 uint32_t itsources = READ_REG(CRS->CR);
1093
1094 /* Check CRS SYNCOK flag */
1095 if(((itflags & RCC_CRS_FLAG_SYNCOK) != 0U) && ((itsources & RCC_CRS_IT_SYNCOK) != 0U))
1096 {
1097 /* Clear CRS SYNC event OK flag */
1098 WRITE_REG(CRS->ICR, CRS_ICR_SYNCOKC);
1099
1100 /* user callback */
1101 HAL_RCCEx_CRS_SyncOkCallback();
1102 }
1103 /* Check CRS SYNCWARN flag */
1104 else if(((itflags & RCC_CRS_FLAG_SYNCWARN) != 0U) && ((itsources & RCC_CRS_IT_SYNCWARN) != 0U))
1105 {
1106 /* Clear CRS SYNCWARN flag */
1107 WRITE_REG(CRS->ICR, CRS_ICR_SYNCWARNC);
1108
1109 /* user callback */
1110 HAL_RCCEx_CRS_SyncWarnCallback();
1111 }
1112 /* Check CRS Expected SYNC flag */
1113 else if(((itflags & RCC_CRS_FLAG_ESYNC) != 0U) && ((itsources & RCC_CRS_IT_ESYNC) != 0U))
1114 {
1115 /* frequency error counter reached a zero value */
1116 WRITE_REG(CRS->ICR, CRS_ICR_ESYNCC);
1117
1118 /* user callback */
1119 HAL_RCCEx_CRS_ExpectedSyncCallback();
1120 }
1121 /* Check CRS Error flags */
1122 else
1123 {
1124 if(((itflags & RCC_CRS_FLAG_ERR) != 0U) && ((itsources & RCC_CRS_IT_ERR) != 0U))
1125 {
1126 if((itflags & RCC_CRS_FLAG_SYNCERR) != 0U)
1127 {
1128 crserror |= RCC_CRS_SYNCERR;
1129 }
1130 if((itflags & RCC_CRS_FLAG_SYNCMISS) != 0U)
1131 {
1132 crserror |= RCC_CRS_SYNCMISS;
1133 }
1134 if((itflags & RCC_CRS_FLAG_TRIMOVF) != 0U)
1135 {
1136 crserror |= RCC_CRS_TRIMOVF;
1137 }
1138
1139 /* Clear CRS Error flags */
1140 WRITE_REG(CRS->ICR, CRS_ICR_ERRC);
1141
1142 /* user error callback */
1143 HAL_RCCEx_CRS_ErrorCallback(crserror);
1144 }
1145 }
1146 }
1147
1148 /**
1149 * @brief RCCEx Clock Recovery System SYNCOK interrupt callback.
1150 * @retval none
1151 */
HAL_RCCEx_CRS_SyncOkCallback(void)1152 __weak void HAL_RCCEx_CRS_SyncOkCallback(void)
1153 {
1154 /* NOTE : This function should not be modified, when the callback is needed,
1155 the @ref HAL_RCCEx_CRS_SyncOkCallback should be implemented in the user file
1156 */
1157 }
1158
1159 /**
1160 * @brief RCCEx Clock Recovery System SYNCWARN interrupt callback.
1161 * @retval none
1162 */
HAL_RCCEx_CRS_SyncWarnCallback(void)1163 __weak void HAL_RCCEx_CRS_SyncWarnCallback(void)
1164 {
1165 /* NOTE : This function should not be modified, when the callback is needed,
1166 the @ref HAL_RCCEx_CRS_SyncWarnCallback should be implemented in the user file
1167 */
1168 }
1169
1170 /**
1171 * @brief RCCEx Clock Recovery System Expected SYNC interrupt callback.
1172 * @retval none
1173 */
HAL_RCCEx_CRS_ExpectedSyncCallback(void)1174 __weak void HAL_RCCEx_CRS_ExpectedSyncCallback(void)
1175 {
1176 /* NOTE : This function should not be modified, when the callback is needed,
1177 the @ref HAL_RCCEx_CRS_ExpectedSyncCallback should be implemented in the user file
1178 */
1179 }
1180
1181 /**
1182 * @brief RCCEx Clock Recovery System Error interrupt callback.
1183 * @param Error Combination of Error status.
1184 * This parameter can be a combination of the following values:
1185 * @arg @ref RCC_CRS_SYNCERR
1186 * @arg @ref RCC_CRS_SYNCMISS
1187 * @arg @ref RCC_CRS_TRIMOVF
1188 * @retval none
1189 */
HAL_RCCEx_CRS_ErrorCallback(uint32_t Error)1190 __weak void HAL_RCCEx_CRS_ErrorCallback(uint32_t Error)
1191 {
1192 /* Prevent unused argument(s) compilation warning */
1193 UNUSED(Error);
1194
1195 /* NOTE : This function should not be modified, when the callback is needed,
1196 the @ref HAL_RCCEx_CRS_ErrorCallback should be implemented in the user file
1197 */
1198 }
1199
1200 /**
1201 * @}
1202 */
1203
1204 #endif /* CRS */
1205 /**
1206 * @}
1207 */
1208
1209 /**
1210 * @}
1211 */
1212
1213 /**
1214 * @}
1215 */
1216
1217 #endif /* HAL_RCC_MODULE_ENABLED */
1218 /**
1219 * @}
1220 */
1221
1222