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