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