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