1 /**
2   ******************************************************************************
3   * @file    stm32u0xx_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 extended peripheral:
8   *           + Extended Peripheral Control functions
9   *           + Extended Clock management functions
10   *           + Extended Clock Recovery System Control functions
11   *
12   ******************************************************************************
13   * @attention
14   *
15   * Copyright (c) 2023 STMicroelectronics.
16   * All rights reserved.
17   *
18   * This software is licensed under terms that can be found in the LICENSE file
19   * in the root directory of this software component.
20   * If no LICENSE file comes with this software, it is provided AS-IS.
21   *
22   ******************************************************************************
23   */
24 
25 /* Includes ------------------------------------------------------------------*/
26 #include "stm32u0xx_hal.h"
27 
28 /** @addtogroup STM32U0xx_HAL_Driver
29   * @{
30   */
31 
32 /** @defgroup RCCEx RCCEx
33   * @brief RCC Extended HAL module driver
34   * @{
35   */
36 
37 #ifdef HAL_RCC_MODULE_ENABLED
38 
39 /* Private typedef -----------------------------------------------------------*/
40 /* Private defines -----------------------------------------------------------*/
41 /** @defgroup RCCEx_Private_Constants RCCEx Private Constants
42   * @{
43   */
44 #define __LSCO_CLK_ENABLE()       __HAL_RCC_GPIOA_CLK_ENABLE()
45 #define LSCO_GPIO_PORT            GPIOA
46 #define LSCO_PIN                  GPIO_PIN_2
47 
48 /**
49   * @}
50   */
51 
52 /* Private macros ------------------------------------------------------------*/
53 /* Private variables ---------------------------------------------------------*/
54 /* Private function prototypes -----------------------------------------------*/
55 /** @defgroup RCCEx_Private_Functions RCCEx Private Functions
56   * @{
57   */
58 static HAL_StatusTypeDef RCCEx_PLLSource_Enable(uint32_t PllSource);
59 
60 /**
61   * @}
62   */
63 
64 /* Exported functions --------------------------------------------------------*/
65 
66 /** @defgroup RCCEx_Exported_Functions RCCEx Exported Functions
67   * @{
68   */
69 
70 /** @defgroup RCCEx_Exported_Functions_Group1 Extended Peripheral Control functions
71   *  @brief  Extended Peripheral Control functions
72   *
73 @verbatim
74  ===============================================================================
75                 ##### Extended Peripheral Control functions  #####
76  ===============================================================================
77     [..]
78     This subsection provides a set of functions allowing to control the RCC Clocks
79     frequencies.
80     [..]
81     (@) Important note: Care must be taken when HAL_RCCEx_PeriphCLKConfig() is used to
82         select the RTC clock source; in this case the Backup domain will be reset in
83         order to modify the RTC Clock source, as consequence RTC registers (including
84         the backup registers) are set to their reset values.
85 
86 @endverbatim
87   * @{
88   */
89 /**
90   * @brief  Initialize the RCC extended peripherals clocks according to the specified
91   *         parameters in the RCC_PeriphCLKInitTypeDef.
92   * @param  PeriphClkInit  pointer to an RCC_PeriphCLKInitTypeDef structure that
93   *         contains a field PeriphClockSelection which can be a combination of the following values:
94   *            @arg @ref RCC_PERIPHCLK_USART1  USART1 peripheral clock
95   *            @arg @ref RCC_PERIPHCLK_USART2  USART2 peripheral clock
96   *            @arg @ref RCC_PERIPHCLK_LPUART1  LPUART1 peripheral clock
97   *            @arg @ref RCC_PERIPHCLK_LPUART2  LPUART2 peripheral clock
98   *            @arg @ref RCC_PERIPHCLK_LPUART3  LPUART3 peripheral clock
99   *            @arg @ref RCC_PERIPHCLK_I2C1  I2C1 peripheral clock
100   *            @arg @ref RCC_PERIPHCLK_I2C3  I2C3 peripheral clock
101   *            @arg @ref RCC_PERIPHCLK_LPTIM1  LPTIM1 peripheral clock
102   *            @arg @ref RCC_PERIPHCLK_LPTIM2  LPTIM2 peripheral clock
103   *            @arg @ref RCC_PERIPHCLK_LPTIM3  LPTIM3 peripheral clock
104   *            @arg @ref RCC_PERIPHCLK_TIM1  TIM1 peripheral clock
105   *            @arg @ref RCC_PERIPHCLK_TIM15  TIM15 peripheral clock
106   *            @arg @ref RCC_PERIPHCLK_USB  USB peripheral clock
107   *            @arg @ref RCC_PERIPHCLK_ADC  ADC peripheral clock
108   *
109   * @note   Care must be taken when HAL_RCCEx_PeriphCLKConfig() is used to select
110   *         the RTC clock source: in this case the access to Backup domain is enabled.
111   *
112   * @retval HAL status
113   */
HAL_RCCEx_PeriphCLKConfig(const RCC_PeriphCLKInitTypeDef * PeriphClkInit)114 HAL_StatusTypeDef HAL_RCCEx_PeriphCLKConfig(const RCC_PeriphCLKInitTypeDef  *PeriphClkInit)
115 {
116   uint32_t tmpregister;
117   uint32_t tickstart;
118   HAL_StatusTypeDef ret = HAL_OK;      /* Intermediate status */
119   HAL_StatusTypeDef status = HAL_OK;   /* Final status */
120 
121   /* Check the parameters */
122   assert_param(IS_RCC_PERIPHCLOCK(PeriphClkInit->PeriphClockSelection));
123 
124   /*-------------------------- RTC clock source configuration ----------------------*/
125   if ((PeriphClkInit->PeriphClockSelection & RCC_PERIPHCLK_RTC) == RCC_PERIPHCLK_RTC)
126   {
127     FlagStatus       pwrclkchanged = RESET;
128 
129     /* Check for RTC Parameters used to output RTCCLK */
130     assert_param(IS_RCC_RTCCLKSOURCE(PeriphClkInit->RTCClockSelection));
131 
132     /* Enable Power Clock */
133     if (__HAL_RCC_PWR_IS_CLK_DISABLED())
134     {
135       __HAL_RCC_PWR_CLK_ENABLE();
136       pwrclkchanged = SET;
137     }
138 
139     /* Enable write access to Backup domain */
140     SET_BIT(PWR->CR1, PWR_CR1_DBP);
141 
142     /* Wait for Backup domain Write protection disable */
143     tickstart = HAL_GetTick();
144 
145     while (READ_BIT(PWR->CR1, PWR_CR1_DBP) == 0U)
146     {
147       if ((HAL_GetTick() - tickstart) > RCC_DBP_TIMEOUT_VALUE)
148       {
149         ret = HAL_TIMEOUT;
150         break;
151       }
152     }
153 
154     if (ret == HAL_OK)
155     {
156       /* Reset the Backup domain only if the RTC Clock source selection is modified from default */
157       tmpregister = READ_BIT(RCC->BDCR, RCC_BDCR_RTCSEL);
158 
159       if ((tmpregister != RCC_RTCCLKSOURCE_NONE) && (tmpregister != PeriphClkInit->RTCClockSelection))
160       {
161         /* Store the content of BDCR register before the reset of Backup Domain */
162         tmpregister = READ_BIT(RCC->BDCR, ~(RCC_BDCR_RTCSEL));
163         /* RTC Clock selection can be changed only if the Backup Domain is reset */
164         __HAL_RCC_BACKUPRESET_FORCE();
165         __HAL_RCC_BACKUPRESET_RELEASE();
166         /* Restore the Content of BDCR register */
167         RCC->BDCR = tmpregister;
168       }
169 
170       /* Wait for LSE reactivation if LSE was enable prior to Backup Domain reset */
171       if (HAL_IS_BIT_SET(tmpregister, RCC_BDCR_LSEON))
172       {
173         /* Get Start Tick*/
174         tickstart = HAL_GetTick();
175 
176         /* Wait till LSE is ready */
177         while (READ_BIT(RCC->BDCR, RCC_BDCR_LSERDY) == 0U)
178         {
179           if ((HAL_GetTick() - tickstart) > RCC_LSE_TIMEOUT_VALUE)
180           {
181             ret = HAL_TIMEOUT;
182             break;
183           }
184         }
185       }
186 
187       if (ret == HAL_OK)
188       {
189         /* Apply new RTC clock source selection */
190         __HAL_RCC_RTC_CONFIG(PeriphClkInit->RTCClockSelection);
191       }
192       else
193       {
194         /* set overall return value */
195         status = ret;
196       }
197     }
198     else
199     {
200       /* set overall return value */
201       status = ret;
202     }
203 
204     /* Restore clock configuration if changed */
205     if (pwrclkchanged == SET)
206     {
207       __HAL_RCC_PWR_CLK_DISABLE();
208     }
209   }
210 
211   /*-------------------------- USART1 clock source configuration -------------------*/
212   if (((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_USART1) == RCC_PERIPHCLK_USART1)
213   {
214     /* Check the parameters */
215     assert_param(IS_RCC_USART1CLKSOURCE(PeriphClkInit->Usart1ClockSelection));
216 
217     /* Configure the USART1 clock source */
218     __HAL_RCC_USART1_CONFIG(PeriphClkInit->Usart1ClockSelection);
219   }
220 
221   /*-------------------------- USART2 clock source configuration -------------------*/
222   if (((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_USART2) == RCC_PERIPHCLK_USART2)
223   {
224     /* Check the parameters */
225     assert_param(IS_RCC_USART2CLKSOURCE(PeriphClkInit->Usart2ClockSelection));
226 
227     /* Configure the USART2 clock source */
228     __HAL_RCC_USART2_CONFIG(PeriphClkInit->Usart2ClockSelection);
229   }
230 
231   /*-------------------------- LPUART1 clock source configuration ------------------*/
232   if (((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_LPUART1) == RCC_PERIPHCLK_LPUART1)
233   {
234     /* Check the parameters */
235     assert_param(IS_RCC_LPUART1CLKSOURCE(PeriphClkInit->Lpuart1ClockSelection));
236 
237     /* Configure the LPUART1 clock source */
238     __HAL_RCC_LPUART1_CONFIG(PeriphClkInit->Lpuart1ClockSelection);
239   }
240 
241   /*-------------------------- LPUART2 clock source configuration ------------------*/
242   if (((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_LPUART2) == RCC_PERIPHCLK_LPUART2)
243   {
244     /* Check the parameters */
245     assert_param(IS_RCC_LPUART2CLKSOURCE(PeriphClkInit->Lpuart2ClockSelection));
246 
247     /* Configure the LPUART2 clock source */
248     __HAL_RCC_LPUART2_CONFIG(PeriphClkInit->Lpuart2ClockSelection);
249   }
250 #if defined (LPUART3)
251   /*-------------------------- LPUART3 clock source configuration ------------------*/
252   if (((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_LPUART3) == RCC_PERIPHCLK_LPUART3)
253   {
254     /* Check the parameters */
255     assert_param(IS_RCC_LPUART3CLKSOURCE(PeriphClkInit->Lpuart3ClockSelection));
256 
257     /* Configure the LPUART3 clock source */
258     __HAL_RCC_LPUART3_CONFIG(PeriphClkInit->Lpuart3ClockSelection);
259   }
260 #endif /* LPUART3 */
261   /*-------------------------- I2C1 clock source configuration ---------------------*/
262   if (((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_I2C1) == RCC_PERIPHCLK_I2C1)
263   {
264     /* Check the parameters */
265     assert_param(IS_RCC_I2C1CLKSOURCE(PeriphClkInit->I2c1ClockSelection));
266 
267     /* Configure the I2C1 clock source */
268     __HAL_RCC_I2C1_CONFIG(PeriphClkInit->I2c1ClockSelection);
269   }
270 
271   /*-------------------------- I2C3 clock source configuration ---------------------*/
272   if (((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_I2C3) == RCC_PERIPHCLK_I2C3)
273   {
274     /* Check the parameters */
275     assert_param(IS_RCC_I2C3CLKSOURCE(PeriphClkInit->I2c3ClockSelection));
276 
277     /* Configure the I2C3 clock source */
278     __HAL_RCC_I2C3_CONFIG(PeriphClkInit->I2c3ClockSelection);
279   }
280 
281   /*----------------------- LPTIM1 clock source configuration -------------------*/
282   if (((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_LPTIM1) == (RCC_PERIPHCLK_LPTIM1))
283   {
284     assert_param(IS_RCC_LPTIM1CLKSOURCE(PeriphClkInit->Lptim1ClockSelection));
285     __HAL_RCC_LPTIM1_CONFIG(PeriphClkInit->Lptim1ClockSelection);
286   }
287 
288   /*-------------------------- LPTIM2 clock source configuration -------------------*/
289   if (((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_LPTIM2) == (RCC_PERIPHCLK_LPTIM2))
290   {
291     assert_param(IS_RCC_LPTIM2CLKSOURCE(PeriphClkInit->Lptim2ClockSelection));
292     __HAL_RCC_LPTIM2_CONFIG(PeriphClkInit->Lptim2ClockSelection);
293   }
294 #if defined (LPTIM3)
295   /*----------------------- LPTIM3 clock source configuration -------------------*/
296   if (((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_LPTIM3) == (RCC_PERIPHCLK_LPTIM3))
297   {
298     assert_param(IS_RCC_LPTIM3CLKSOURCE(PeriphClkInit->Lptim3ClockSelection));
299     __HAL_RCC_LPTIM3_CONFIG(PeriphClkInit->Lptim3ClockSelection);
300   }
301 #endif /* LPTIM3 */
302   /*-------------------------- ADC clock source configuration ----------------*/
303   if (((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_ADC) == RCC_PERIPHCLK_ADC)
304   {
305     /* Check the parameters */
306     assert_param(IS_RCC_ADCCLKSOURCE(PeriphClkInit->AdcClockSelection));
307     if (PeriphClkInit->AdcClockSelection == RCC_ADCCLKSOURCE_PLLP)
308     {
309       __HAL_RCC_PLLCLKOUT_ENABLE(RCC_PLL_DIVP);
310     }
311     /* Configure the ADC1 clock source */
312     __HAL_RCC_ADC_CONFIG(PeriphClkInit->AdcClockSelection);
313   }
314 #if defined (USB_DRD_FS)
315   /*-------------------------- USB clock source configuration ----------------*/
316   if (((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_USB) == RCC_PERIPHCLK_USB)
317   {
318     /* Check the parameters */
319     assert_param(IS_RCC_USBCLKSOURCE(PeriphClkInit->UsbClockSelection));
320     if (PeriphClkInit->UsbClockSelection == RCC_USBCLKSOURCE_PLLQ)
321     {
322       __HAL_RCC_PLLCLKOUT_ENABLE(RCC_PLL_DIVQ);
323     }
324     /* Configure the USB clock source */
325     __HAL_RCC_USB_CONFIG(PeriphClkInit->UsbClockSelection);
326 
327   }
328 #endif /* USB_DRD_FS */
329   /*-------------------------- RNG clock source configuration ----------------*/
330   if (((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_RNG) == RCC_PERIPHCLK_RNG)
331   {
332     /* Check the parameters */
333     assert_param(IS_RCC_RNGCLKSOURCE(PeriphClkInit->RngClockSelection));
334     if (PeriphClkInit->RngClockSelection == RCC_RNGCLKSOURCE_PLLQ)
335     {
336       __HAL_RCC_PLLCLKOUT_ENABLE(RCC_PLL_DIVQ);
337     }
338     /* Configure the RNG clock source */
339     __HAL_RCC_RNG_CONFIG(PeriphClkInit->RngClockSelection);
340 
341   }
342   /*-------------------------- TIM1 clock source configuration ----------------*/
343   if (((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_TIM1) == RCC_PERIPHCLK_TIM1)
344   {
345 
346     /* Check the parameters */
347     assert_param(IS_RCC_TIM1CLKSOURCE(PeriphClkInit->Tim1ClockSelection));
348     if (PeriphClkInit->Tim1ClockSelection == RCC_TIM1CLKSOURCE_PLLQ)
349     {
350       __HAL_RCC_PLLCLKOUT_ENABLE(RCC_PLL_DIVQ);
351     }
352     /* Configure the TIM1 clock source */
353     __HAL_RCC_TIM1_CONFIG(PeriphClkInit->Tim1ClockSelection);
354 
355   }
356   /*-------------------------- TIM15 clock source configuration ----------------*/
357   if (((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_TIM15) == RCC_PERIPHCLK_TIM15)
358   {
359     /* Check the parameters */
360     assert_param(IS_RCC_TIM15CLKSOURCE(PeriphClkInit->Tim15ClockSelection));
361     if (PeriphClkInit->Tim15ClockSelection == RCC_TIM15CLKSOURCE_PLLQ)
362     {
363       __HAL_RCC_PLLCLKOUT_ENABLE(RCC_PLL_DIVQ);
364     }
365     /* Configure the TIM1 clock source */
366     __HAL_RCC_TIM15_CONFIG(PeriphClkInit->Tim15ClockSelection);
367 
368   }
369 
370   return status;
371 }
372 /**
373   * @brief  Get the RCC_ClkInitStruct according to the internal RCC configuration registers.
374   * @param  PeriphClkInit  pointer to an RCC_PeriphCLKInitTypeDef structure that
375   *         returns the configuration information for the Extended Peripherals
376   *         clocks(USART1, USART2, LPUART1, LPUART2, LPUART3, I2C1, I2C2, I2C3, I2C4, LPTIM1,
377   *         LPTIM2, LPTIM3, USB, TIM1, LCD, SPI1, SPI2, SPI3, RTC, RNG, ADC, DAC, IWDG).
378   * @retval None
379   */
HAL_RCCEx_GetPeriphCLKConfig(RCC_PeriphCLKInitTypeDef * PeriphClkInit)380 void HAL_RCCEx_GetPeriphCLKConfig(RCC_PeriphCLKInitTypeDef  *PeriphClkInit)
381 {
382   /* Set all possible values for the extended clock type parameter------------*/
383   PeriphClkInit->PeriphClockSelection = RCC_PERIPHCLK_RTC  | RCC_PERIPHCLK_USART1 | RCC_PERIPHCLK_USART2 | \
384                                         RCC_PERIPHCLK_LPUART1 | RCC_PERIPHCLK_LPUART2 | RCC_PERIPHCLK_I2C1 | \
385                                         RCC_PERIPHCLK_I2C3 | RCC_PERIPHCLK_LPTIM1 | RCC_PERIPHCLK_LPTIM2 | \
386                                         RCC_PERIPHCLK_TIM1 | RCC_PERIPHCLK_TIM15 | RCC_PERIPHCLK_RNG | \
387                                         RCC_PERIPHCLK_ADC ;
388 
389 #if defined(LPUART3)
390   PeriphClkInit->PeriphClockSelection |= RCC_PERIPHCLK_LPUART3;
391 #endif /* LPUART3*/
392 #if defined(LPTIM3)
393   PeriphClkInit->PeriphClockSelection |= RCC_PERIPHCLK_LPTIM3;
394 #endif /* LPTIM3 */
395 #if defined(USB_DRD_FS)
396   PeriphClkInit->PeriphClockSelection |= RCC_PERIPHCLK_USB;
397 #endif /* USB_DRD_FS */
398   /* Get the RTC clock source ---------------------------------------------*/
399   PeriphClkInit->RTCClockSelection   = __HAL_RCC_GET_RTC_SOURCE();
400 
401   /* Get the USART1 clock source ---------------------------------------------*/
402   PeriphClkInit->Usart1ClockSelection   = __HAL_RCC_GET_USART1_SOURCE();
403 
404   /* Get the USART2 clock source ---------------------------------------------*/
405   PeriphClkInit->Usart2ClockSelection   = __HAL_RCC_GET_USART2_SOURCE();
406 
407   /* Get the LPUART1 clock source --------------------------------------------*/
408   PeriphClkInit->Lpuart1ClockSelection  = __HAL_RCC_GET_LPUART1_SOURCE();
409 
410   /* Get the LPUART2 clock source --------------------------------------------*/
411   PeriphClkInit->Lpuart2ClockSelection  = __HAL_RCC_GET_LPUART2_SOURCE();
412 
413 #if defined (LPUART3)
414   /* Get the LPUART3 clock source --------------------------------------------*/
415   PeriphClkInit->Lpuart3ClockSelection  = __HAL_RCC_GET_LPUART3_SOURCE();
416 #endif /* LPUART3 */
417 
418   /* Get the I2C1 clock source -----------------------------------------------*/
419   PeriphClkInit->I2c1ClockSelection     = __HAL_RCC_GET_I2C1_SOURCE();
420 
421   /* Get the I2C3 clock source -----------------------------------------------*/
422   PeriphClkInit->I2c3ClockSelection     = __HAL_RCC_GET_I2C3_SOURCE();
423 
424   /* Get the LPTIM1 clock source ---------------------------------------------*/
425   PeriphClkInit->Lptim1ClockSelection  = __HAL_RCC_GET_LPTIM1_SOURCE();
426 
427   /* Get the LPTIM2 clock source ---------------------------------------------*/
428   PeriphClkInit->Lptim2ClockSelection   = __HAL_RCC_GET_LPTIM2_SOURCE();
429 
430 #if defined (LPTIM3)
431   /* Get the LPTIM3 clock source ---------------------------------------------*/
432   PeriphClkInit->Lptim3ClockSelection   = __HAL_RCC_GET_LPTIM3_SOURCE();
433 #endif /* LPTIM3 */
434 
435   /* Get the ADC clock source -----------------------------------------------*/
436   PeriphClkInit->AdcClockSelection      = __HAL_RCC_GET_ADC_SOURCE();
437 
438   /* Get the TIM1 clock source -----------------------------------------------*/
439   PeriphClkInit->Tim1ClockSelection     = __HAL_RCC_GET_TIM1_SOURCE();
440 
441   /* Get the TIM15 clock source -----------------------------------------------*/
442   PeriphClkInit->Tim15ClockSelection     = __HAL_RCC_GET_TIM15_SOURCE();
443 
444 #if defined (USB_DRD_FS)
445   /* Get the USB clock source -------------------------------------------------*/
446   PeriphClkInit->UsbClockSelection     = __HAL_RCC_GET_USB_SOURCE();
447 #endif /* USB_DRD_FS */
448 
449   /* Get the RNG clock source -------------------------------------------------*/
450   PeriphClkInit->RngClockSelection     = __HAL_RCC_GET_RNG_SOURCE();
451 
452 }
453 
454 /**
455   * @brief  Return the peripheral clock frequency for peripherals with clock source from PLLSAIs
456   * @note   Return 0 if peripheral clock identifier not managed by this API
457   * @param  PeriphClk  Peripheral clock identifier
458   *         This parameter can be one of the following values:
459   *            @arg @ref RCC_PERIPHCLK_ADC  ADC peripheral clock
460   *            @arg @ref RCC_PERIPHCLK_I2C1  I2C1 peripheral clock
461   *            @arg @ref RCC_PERIPHCLK_I2C3  I2C3 peripheral clock
462   *            @arg @ref RCC_PERIPHCLK_LPTIM1  LPTIM1 peripheral clock
463   *            @arg @ref RCC_PERIPHCLK_LPTIM2  LPTIM2 peripheral clock
464   *            @arg @ref RCC_PERIPHCLK_LPTIM3  LPTIM3 peripheral clock
465   *            @arg @ref RCC_PERIPHCLK_LPUART1  LPUART1 peripheral clock
466   *            @arg @ref RCC_PERIPHCLK_LPUART2  LPUART2 peripheral clock
467   *            @arg @ref RCC_PERIPHCLK_LPUART3  LPUART3 peripheral clock
468   *            @arg @ref RCC_PERIPHCLK_USART1  USART1 peripheral clock
469   *            @arg @ref RCC_PERIPHCLK_USART2  USART2 peripheral clock
470   *            @arg @ref RCC_PERIPHCLK_USART3  USART3 peripheral clock
471   *            @arg @ref RCC_PERIPHCLK_USART4  USART4 peripheral clock
472   *            @arg @ref RCC_PERIPHCLK_USB  USB peripheral clock (only for devices with USB)
473   *            @arg @ref RCC_PERIPHCLK_RNG  RNG peripheral clock (only for devices with RNG)
474   *            @arg @ref RCC_PERIPHCLK_TIM1  TIM1 peripheral clock (only for devices with TIM1)
475   *            @arg @ref RCC_PERIPHCLK_TIM15  TIM15 peripheral clock (only for devices with TIM15)
476   * @retval Frequency in Hz
477   */
HAL_RCCEx_GetPeriphCLKFreq(uint32_t PeriphClk)478 uint32_t HAL_RCCEx_GetPeriphCLKFreq(uint32_t PeriphClk)
479 {
480   uint32_t frequency = 0U;
481   uint32_t srcclk;    /* no init needed */
482   PLL_ClocksTypeDef pll_freq;
483   uint32_t msirange;
484   /* Check the parameters */
485   assert_param(IS_RCC_PERIPHCLOCK(PeriphClk));
486 
487   if (PeriphClk == RCC_PERIPHCLK_RTC)
488   {
489     /* Get the current RCC_PERIPHCLK_RTC source */
490     srcclk = __HAL_RCC_GET_RTC_SOURCE();
491 
492     switch (srcclk)
493     {
494       case RCC_RTCCLKSOURCE_LSE:
495         /* Check if LSE is ready */
496         if (HAL_IS_BIT_SET(RCC->BDCR, RCC_BDCR_LSERDY))
497         {
498           frequency = LSE_VALUE;
499         }
500         break;
501       case RCC_RTCCLKSOURCE_LSI:
502         /* Check if LSI is ready */
503         if (HAL_IS_BIT_SET(RCC->CSR, RCC_CSR_LSIRDY))
504         {
505 #if defined(RCC_CSR_LSIPREDIV)
506           if (HAL_IS_BIT_SET(RCC->CSR, RCC_CSR_LSIPREDIV))
507           {
508             frequency = LSI_VALUE / 128U;
509           }
510           else
511 #endif /* RCC_CSR_LSIPREDIV */
512           {
513             frequency = LSI_VALUE;
514           }
515         }
516         break;
517       case RCC_RTCCLKSOURCE_HSE:
518         /* Check if HSE is ready */
519         if (HAL_IS_BIT_SET(RCC->CR, RCC_CR_HSERDY))
520         {
521           frequency = HSE_VALUE / 32U;
522         }
523         break;
524       default:
525         /* No clock source, frequency default init at 0 */
526         break;
527     }
528   }
529   else
530   {
531     /* Other external peripheral clock source than RTC */
532     switch (PeriphClk)
533     {
534       case RCC_PERIPHCLK_USART1:
535       {
536         /* Get the current USART1 source */
537         srcclk = __HAL_RCC_GET_USART1_SOURCE();
538 
539         switch (srcclk)
540         {
541           case RCC_USART1CLKSOURCE_PCLK1:
542             frequency = HAL_RCC_GetPCLK1Freq();
543             break;
544           case RCC_USART1CLKSOURCE_SYSCLK:
545             frequency = HAL_RCC_GetSysClockFreq();
546             break;
547           case RCC_USART1CLKSOURCE_HSI:
548             if (HAL_IS_BIT_SET(RCC->CR, RCC_CR_HSIRDY))
549             {
550               frequency = HSI_VALUE;
551             }
552             break;
553           case RCC_USART1CLKSOURCE_LSE:
554             if (HAL_IS_BIT_SET(RCC->BDCR, RCC_BDCR_LSERDY))
555             {
556               frequency = LSE_VALUE;
557             }
558             break;
559           default:
560             /* No clock source, frequency default init at 0 */
561             break;
562         }
563 
564         break;
565       }
566 
567       case RCC_PERIPHCLK_USART2:
568       {
569         /* Get the current USART2 source */
570         srcclk = __HAL_RCC_GET_USART2_SOURCE();
571 
572         switch (srcclk)
573         {
574           case RCC_USART2CLKSOURCE_PCLK1:
575             frequency = HAL_RCC_GetPCLK1Freq();
576             break;
577           case RCC_USART2CLKSOURCE_SYSCLK:
578             frequency = HAL_RCC_GetSysClockFreq();
579             break;
580           case RCC_USART2CLKSOURCE_HSI:
581             if (HAL_IS_BIT_SET(RCC->CR, RCC_CR_HSIRDY))
582             {
583               frequency = HSI_VALUE;
584             }
585             break;
586           case RCC_USART2CLKSOURCE_LSE:
587             if (HAL_IS_BIT_SET(RCC->BDCR, RCC_BDCR_LSERDY))
588             {
589               frequency = LSE_VALUE;
590             }
591             break;
592           default:
593             /* No clock source, frequency default init at 0 */
594             break;
595         }
596 
597         break;
598       }
599 
600       /* USART3 and USART4 source */
601       case RCC_PERIPHCLK_USART3:
602       case RCC_PERIPHCLK_USART4:
603       {
604         frequency = HAL_RCC_GetPCLK1Freq();
605         break;
606       }
607 
608       case RCC_PERIPHCLK_LPUART1:
609       {
610         /* Get the current LPUART1 source */
611         srcclk = __HAL_RCC_GET_LPUART1_SOURCE();
612 
613         switch (srcclk)
614         {
615           case RCC_LPUART1CLKSOURCE_PCLK1:
616             frequency = HAL_RCC_GetPCLK1Freq();
617             break;
618           case RCC_LPUART1CLKSOURCE_SYSCLK:
619             frequency = HAL_RCC_GetSysClockFreq();
620             break;
621           case RCC_LPUART1CLKSOURCE_HSI:
622             if (HAL_IS_BIT_SET(RCC->CR, RCC_CR_HSIRDY))
623             {
624               frequency = HSI_VALUE;
625             }
626             break;
627           case RCC_LPUART1CLKSOURCE_LSE:
628             if (HAL_IS_BIT_SET(RCC->BDCR, RCC_BDCR_LSERDY))
629             {
630               frequency = LSE_VALUE;
631             }
632             break;
633           default:
634             /* No clock source, frequency default init at 0 */
635             break;
636         }
637         break;
638       }
639       case RCC_PERIPHCLK_LPUART2:
640       {
641         /* Get the current LPUART2 source */
642         srcclk = __HAL_RCC_GET_LPUART2_SOURCE();
643 
644         switch (srcclk)
645         {
646           case RCC_LPUART2CLKSOURCE_PCLK1:
647             frequency = HAL_RCC_GetPCLK1Freq();
648             break;
649           case RCC_LPUART2CLKSOURCE_SYSCLK:
650             frequency = HAL_RCC_GetSysClockFreq();
651             break;
652           case RCC_LPUART2CLKSOURCE_HSI:
653             if (HAL_IS_BIT_SET(RCC->CR, RCC_CR_HSIRDY))
654             {
655               frequency = HSI_VALUE;
656             }
657             break;
658           case RCC_LPUART2CLKSOURCE_LSE:
659             if (HAL_IS_BIT_SET(RCC->BDCR, RCC_BDCR_LSERDY))
660             {
661               frequency = LSE_VALUE;
662             }
663             break;
664           default:
665             /* No clock source, frequency default init at 0 */
666             break;
667         }
668         break;
669       }
670 #if defined(LPUART3)
671       case RCC_PERIPHCLK_LPUART3:
672       {
673         /* Get the current LPUART3 source */
674         srcclk = __HAL_RCC_GET_LPUART3_SOURCE();
675 
676         switch (srcclk)
677         {
678           case RCC_LPUART3CLKSOURCE_PCLK1:
679             frequency = HAL_RCC_GetPCLK1Freq();
680             break;
681           case RCC_LPUART3CLKSOURCE_SYSCLK:
682             frequency = HAL_RCC_GetSysClockFreq();
683             break;
684           case RCC_LPUART3CLKSOURCE_HSI:
685             if (HAL_IS_BIT_SET(RCC->CR, RCC_CR_HSIRDY))
686             {
687               frequency = HSI_VALUE;
688             }
689             break;
690           case RCC_LPUART3CLKSOURCE_LSE:
691             if (HAL_IS_BIT_SET(RCC->BDCR, RCC_BDCR_LSERDY))
692             {
693               frequency = LSE_VALUE;
694             }
695             break;
696           default:
697             /* No clock source, frequency default init at 0 */
698             break;
699         }
700         break;
701       }
702 #endif /* LPUART3 */
703       case RCC_PERIPHCLK_ADC:
704       {
705         srcclk = __HAL_RCC_GET_ADC_SOURCE();
706 
707         switch (srcclk)
708         {
709           case RCC_ADCCLKSOURCE_SYSCLK:
710             frequency = HAL_RCC_GetSysClockFreq();
711             break;
712           case RCC_ADCCLKSOURCE_HSI:
713             if (HAL_IS_BIT_SET(RCC->CR, RCC_CR_HSIRDY))
714             {
715               frequency = HSI_VALUE;
716             }
717             else
718             {
719               frequency = 0U;
720             }
721             break;
722           case RCC_ADCCLKSOURCE_PLLP:
723             HAL_RCCEx_GetPLLClockFreq(&pll_freq);
724             frequency = pll_freq.PLL_P_Frequency;
725             break;
726 
727           default:
728             /* No clock source, frequency default init at 0 */
729             break;
730         }
731         break;
732       }
733 
734       case RCC_PERIPHCLK_I2C1:
735       {
736         /* Get the current I2C1 source */
737         srcclk = __HAL_RCC_GET_I2C1_SOURCE();
738 
739         switch (srcclk)
740         {
741           case RCC_I2C1CLKSOURCE_PCLK1:
742             frequency = HAL_RCC_GetPCLK1Freq();
743             break;
744           case RCC_I2C1CLKSOURCE_SYSCLK:
745             frequency = HAL_RCC_GetSysClockFreq();
746             break;
747           case RCC_I2C1CLKSOURCE_HSI:
748             if (HAL_IS_BIT_SET(RCC->CR, RCC_CR_HSIRDY))
749             {
750               frequency = HSI_VALUE;
751             }
752             break;
753           default:
754             /* No clock source, frequency default init at 0 */
755             break;
756         }
757 
758         break;
759       }
760 
761       case RCC_PERIPHCLK_I2C3:
762       {
763         /* Get the current I2C3 source */
764         srcclk = __HAL_RCC_GET_I2C3_SOURCE();
765 
766         switch (srcclk)
767         {
768           case RCC_I2C3CLKSOURCE_PCLK1:
769             frequency = HAL_RCC_GetPCLK1Freq();
770             break;
771           case RCC_I2C3CLKSOURCE_SYSCLK:
772             frequency = HAL_RCC_GetSysClockFreq();
773             break;
774           case RCC_I2C3CLKSOURCE_HSI:
775             if (HAL_IS_BIT_SET(RCC->CR, RCC_CR_HSIRDY))
776             {
777               frequency = HSI_VALUE;
778             }
779             break;
780           default:
781             /* No clock source, frequency default init at 0 */
782             break;
783         }
784 
785         break;
786       }
787 
788       case RCC_PERIPHCLK_LPTIM1:
789       {
790         /* Get the current LPTIM1 source */
791         srcclk = __HAL_RCC_GET_LPTIM1_SOURCE();
792 
793         switch (srcclk)
794         {
795           case RCC_LPTIM1CLKSOURCE_PCLK1:
796             frequency = HAL_RCC_GetPCLK1Freq();
797             break;
798           case RCC_LPTIM1CLKSOURCE_LSI:
799             if (HAL_IS_BIT_SET(RCC->CSR, RCC_CSR_LSIRDY))
800             {
801 #if defined(RCC_CSR_LSIPREDIV)
802               if (HAL_IS_BIT_SET(RCC->CSR, RCC_CSR_LSIPREDIV))
803               {
804                 frequency = LSI_VALUE / 128U;
805               }
806               else
807 #endif /* RCC_CSR_LSIPREDIV */
808               {
809                 frequency = LSI_VALUE;
810               }
811             }
812             break;
813           case RCC_LPTIM1CLKSOURCE_HSI:
814             if (HAL_IS_BIT_SET(RCC->CR, RCC_CR_HSIRDY))
815             {
816               frequency = HSI_VALUE;
817             }
818             break;
819           case RCC_LPTIM1CLKSOURCE_LSE:
820             if (HAL_IS_BIT_SET(RCC->BDCR, RCC_BDCR_LSERDY))
821             {
822               frequency = LSE_VALUE;
823             }
824             break;
825           default:
826             /* No clock source, frequency default init at 0 */
827             break;
828         }
829 
830         break;
831       }
832 
833       case RCC_PERIPHCLK_LPTIM2:
834       {
835         /* Get the current LPTIM2 source */
836         srcclk = __HAL_RCC_GET_LPTIM2_SOURCE();
837 
838         switch (srcclk)
839         {
840           case RCC_LPTIM2CLKSOURCE_PCLK1:
841             frequency = HAL_RCC_GetPCLK1Freq();
842             break;
843           case RCC_LPTIM2CLKSOURCE_LSI:
844             if (HAL_IS_BIT_SET(RCC->CSR, RCC_CSR_LSIRDY))
845             {
846 #if defined(RCC_CSR_LSIPREDIV)
847               if (HAL_IS_BIT_SET(RCC->CSR, RCC_CSR_LSIPREDIV))
848               {
849                 frequency = LSI_VALUE / 128U;
850               }
851               else
852 #endif /* RCC_CSR_LSIPREDIV */
853               {
854                 frequency = LSI_VALUE;
855               }
856             }
857             break;
858           case RCC_LPTIM2CLKSOURCE_HSI:
859             if (HAL_IS_BIT_SET(RCC->CR, RCC_CR_HSIRDY))
860             {
861               frequency = HSI_VALUE;
862             }
863             break;
864           case RCC_LPTIM2CLKSOURCE_LSE:
865             if (HAL_IS_BIT_SET(RCC->BDCR, RCC_BDCR_LSERDY))
866             {
867               frequency = LSE_VALUE;
868             }
869             break;
870           default:
871             /* No clock source, frequency default init at 0 */
872             break;
873         }
874         break;
875       }
876 #if defined (LPTIM3)
877       case RCC_PERIPHCLK_LPTIM3:
878       {
879         /* Get the current LPTIM3 source */
880         srcclk = __HAL_RCC_GET_LPTIM3_SOURCE();
881 
882         switch (srcclk)
883         {
884           case RCC_LPTIM3CLKSOURCE_PCLK1:
885             frequency = HAL_RCC_GetPCLK1Freq();
886             break;
887           case RCC_LPTIM3CLKSOURCE_LSI:
888             if (HAL_IS_BIT_SET(RCC->CSR, RCC_CSR_LSIRDY))
889             {
890 #if defined(RCC_CSR_LSIPREDIV)
891               if (HAL_IS_BIT_SET(RCC->CSR, RCC_CSR_LSIPREDIV))
892               {
893                 frequency = LSI_VALUE / 128U;
894               }
895               else
896 #endif /* RCC_CSR_LSIPREDIV */
897               {
898                 frequency = LSI_VALUE;
899               }
900             }
901             break;
902           case RCC_LPTIM3CLKSOURCE_HSI:
903             if (HAL_IS_BIT_SET(RCC->CR, RCC_CR_HSIRDY))
904             {
905               frequency = HSI_VALUE;
906             }
907             break;
908           case RCC_LPTIM3CLKSOURCE_LSE:
909             if (HAL_IS_BIT_SET(RCC->BDCR, RCC_BDCR_LSERDY))
910             {
911               frequency = LSE_VALUE;
912             }
913             break;
914           default:
915             /* No clock source, frequency default init at 0 */
916             break;
917         }
918 
919         break;
920       }
921 #endif /* LPTIM3 */
922       case RCC_PERIPHCLK_TIM1:
923       {
924         /* Get the current TIM1 source */
925         srcclk = __HAL_RCC_GET_TIM1_SOURCE();
926         switch (srcclk)
927         {
928           case RCC_TIM1CLKSOURCE_PCLK1:
929             if ((READ_BIT(RCC->CFGR, RCC_CFGR_PPRE) == RCC_HCLK_DIV1))
930             {
931               frequency = HAL_RCC_GetPCLK1Freq();
932             }
933             else
934             {
935               frequency = (HAL_RCC_GetPCLK1Freq() * 2U);
936             }
937             break;
938           case RCC_TIM1CLKSOURCE_PLLQ:
939             HAL_RCCEx_GetPLLClockFreq(&pll_freq);
940             frequency = pll_freq.PLL_Q_Frequency;
941             break;
942           default:
943             /* No clock source, frequency default init at 0 */
944             break;
945         }
946         break;
947       }
948       case RCC_PERIPHCLK_TIM15:
949       {
950         /* Get the current TIM15 source */
951         srcclk = __HAL_RCC_GET_TIM15_SOURCE();
952         switch (srcclk)
953         {
954           case RCC_TIM15CLKSOURCE_PCLK1:
955             if ((READ_BIT(RCC->CFGR, RCC_CFGR_PPRE) == RCC_HCLK_DIV1))
956             {
957               frequency = HAL_RCC_GetPCLK1Freq();
958             }
959             else
960             {
961               frequency = (HAL_RCC_GetPCLK1Freq() * 2U);
962             }
963             break;
964           case RCC_TIM15CLKSOURCE_PLLQ:
965             HAL_RCCEx_GetPLLClockFreq(&pll_freq);
966             frequency = pll_freq.PLL_Q_Frequency;
967             break;
968           default:
969             /* No clock source, frequency default init at 0 */
970             break;
971         }
972         break;
973       }
974 #if defined (USB_DRD_FS)
975       case RCC_PERIPHCLK_USB:
976       {
977         /* Get the current USB source */
978         srcclk = __HAL_RCC_GET_USB_SOURCE();
979         switch (srcclk)
980         {
981           case RCC_USBCLKSOURCE_HSI48:
982             frequency = HSI48_VALUE;
983             break;
984           case RCC_USBCLKSOURCE_MSI:
985             if (HAL_IS_BIT_SET(RCC->CR, RCC_CR_MSIRDY))
986             {
987               msirange = (__HAL_RCC_GET_MSI_RANGE() >> 4U);
988               if (msirange > 11U)
989               {
990                 msirange = 11U;
991               }
992               frequency = MSIRangeTable[msirange];
993             }
994             break;
995           case RCC_USBCLKSOURCE_PLLQ:
996             HAL_RCCEx_GetPLLClockFreq(&pll_freq);
997             frequency = pll_freq.PLL_Q_Frequency;
998             break;
999           /* Clock not enabled for USB */
1000           case RCC_USBCLKSOURCE_NONE:
1001             frequency = 0U;
1002             break;
1003           default:
1004             /* No clock source, frequency default init at 0 */
1005             break;
1006         }
1007         break;
1008       }
1009 #endif /* USB_DRD_FS */
1010       case RCC_PERIPHCLK_RNG:
1011       {
1012         /* Get the current RNG source */
1013         srcclk = __HAL_RCC_GET_RNG_SOURCE();
1014         switch (srcclk)
1015         {
1016           case RCC_RNGCLKSOURCE_HSI48:
1017             frequency = HSI48_VALUE;
1018             break;
1019           case RCC_RNGCLKSOURCE_MSI:
1020             if (HAL_IS_BIT_SET(RCC->CR, RCC_CR_MSIRDY))
1021             {
1022               msirange = (__HAL_RCC_GET_MSI_RANGE() >> 4U);
1023               if (msirange > 11U)
1024               {
1025                 msirange = 11U;
1026               }
1027               frequency = MSIRangeTable[msirange];
1028             }
1029             break;
1030           case RCC_RNGCLKSOURCE_PLLQ:
1031             HAL_RCCEx_GetPLLClockFreq(&pll_freq);
1032             frequency = pll_freq.PLL_Q_Frequency;
1033             break;
1034           /* Clock not enabled for RNG */
1035           case RCC_RNGCLKSOURCE_NONE:
1036             frequency = 0U;
1037             break;
1038           default:
1039             /* No clock source, frequency default init at 0 */
1040             break;
1041         }
1042         break;
1043       }
1044       default:
1045         break;
1046     }
1047   }
1048   return (frequency);
1049 }
1050 
1051 /**
1052   * @brief  Returns the PLL clock frequencies :PLL_P_Frequency,PLL_R_Frequency and PLL_Q_Frequency
1053   * @note   The PLL clock frequencies computed by this function is not the real
1054   *         frequency in the chip. It is calculated based on the predefined
1055   *         constant and the selected clock source:
1056   * @note   The function returns values based on HSE_VALUE, HSI_VALUE or MSI Value multiplied/divided by the PLL factors
1057   * @note   This function can be used by the user application to compute the
1058   *         baud-rate for the communication peripherals or configure other parameters.
1059   *
1060   * @note   Each time PLLCLK changes, this function must be called to update the
1061   *         right PLLCLK value. Otherwise, any configuration based on this function will be incorrect.
1062   * @param  PLL_Clocks structure.
1063   * @retval None
1064   */
1065 
HAL_RCCEx_GetPLLClockFreq(PLL_ClocksTypeDef * PLL_Clocks)1066 void HAL_RCCEx_GetPLLClockFreq(PLL_ClocksTypeDef *PLL_Clocks)
1067 {
1068   uint32_t pllsource;
1069   uint32_t pllm;
1070   uint32_t plln;
1071   uint32_t pllvco;
1072   uint32_t msirange;
1073 
1074   plln = ((RCC->PLLCFGR & RCC_PLLCFGR_PLLN) >> RCC_PLLCFGR_PLLN_Pos);
1075   pllsource = (RCC->PLLCFGR & RCC_PLLCFGR_PLLSRC);
1076   pllm = ((RCC->PLLCFGR & RCC_PLLCFGR_PLLM) >> RCC_PLLCFGR_PLLM_Pos) + 1U;
1077   msirange = (__HAL_RCC_GET_MSI_RANGE() >> 4U);
1078   if (msirange > 11U)
1079   {
1080     msirange = 11U;
1081   }
1082   switch (pllsource)
1083   {
1084 
1085     case RCC_PLLSOURCE_HSI:  /* HSI used as PLL clock source */
1086       pllvco = (HSI_VALUE / pllm) * plln;
1087       break;
1088 
1089     case RCC_PLLSOURCE_MSI:  /* MSI used as PLL clock source */
1090       pllvco = ((MSIRangeTable[msirange] / pllm) * plln);
1091       break;
1092 
1093     case RCC_PLLSOURCE_HSE:  /* HSE used as PLL clock source */
1094       pllvco = (HSE_VALUE / pllm) * plln;
1095       break;
1096 
1097     default:
1098       pllvco = ((MSIRangeTable[msirange] / pllm) * plln);
1099       break;
1100   }
1101 
1102   if (__HAL_RCC_GET_PLLCLKOUT_CONFIG(RCC_PLL_DIVP) != 0U)
1103   {
1104     PLL_Clocks->PLL_P_Frequency = (uint32_t)(pllvco / (((RCC->PLLCFGR & RCC_PLLCFGR_PLLP) \
1105                                                         >> RCC_PLLCFGR_PLLP_Pos) + 1U));
1106   }
1107   else
1108   {
1109     PLL_Clocks->PLL_P_Frequency = 0;
1110   }
1111 
1112   if (__HAL_RCC_GET_PLLCLKOUT_CONFIG(RCC_PLL_DIVQ) != 0U)
1113   {
1114     PLL_Clocks->PLL_Q_Frequency = (uint32_t)(pllvco / (((RCC->PLLCFGR & RCC_PLLCFGR_PLLQ) \
1115                                                         >> RCC_PLLCFGR_PLLQ_Pos) + 1U));
1116   }
1117   else
1118   {
1119     PLL_Clocks->PLL_Q_Frequency = 0;
1120   }
1121 
1122   if (__HAL_RCC_GET_PLLCLKOUT_CONFIG(RCC_PLL_DIVR) != 0U)
1123   {
1124     PLL_Clocks->PLL_R_Frequency = (uint32_t)(pllvco / (((RCC->PLLCFGR & RCC_PLLCFGR_PLLR) \
1125                                                         >> RCC_PLLCFGR_PLLR_Pos) + 1U));
1126   }
1127   else
1128   {
1129     PLL_Clocks->PLL_R_Frequency = 0;
1130   }
1131 }
1132 
1133 /**
1134   * @brief  Enable PLL.
1135   * @param  PLLInit  pointer to an RCC_PLLInitTypeDef structure that
1136   *         contains the configuration information for the PLL
1137   * @retval HAL status
1138   */
HAL_RCCEx_EnablePLL(RCC_PLLInitTypeDef * PLLInit)1139 HAL_StatusTypeDef HAL_RCCEx_EnablePLL(RCC_PLLInitTypeDef  *PLLInit)
1140 {
1141   uint32_t tickstart;
1142   HAL_StatusTypeDef status = HAL_OK;
1143 
1144   /* check for PLL Parameters used to output PLLCLK */
1145   assert_param(IS_RCC_PLLSOURCE(PLLInit->PLLSource));
1146   assert_param(IS_RCC_PLL_DIVM_VALUE(PLLInit->PLLM));
1147   assert_param(IS_RCC_PLL_MULN_VALUE(PLLInit->PLLN));
1148   assert_param(IS_RCC_PLL_DIVP_VALUE(PLLInit->PLLP));
1149   assert_param(IS_RCC_PLL_DIVQ_VALUE(PLLInit->PLLQ));
1150   assert_param(IS_RCC_PLL_DIVR_VALUE(PLLInit->PLLR));
1151   assert_param(IS_RCC_PLLCLOCKOUT_VALUE(PLLInit->PLLClockOut));
1152 
1153   /* Disable the PLL */
1154   __HAL_RCC_PLL_DISABLE();
1155 
1156   /* Get Start Tick*/
1157   tickstart = HAL_GetTick();
1158 
1159   /* Wait till PLL is ready to be updated */
1160   while (READ_BIT(RCC->CR, RCC_CR_PLLRDY) != 0U)
1161   {
1162     if ((HAL_GetTick() - tickstart) > 2U) /* PLL_TIMEOUT_VALUE) */
1163     {
1164       status = HAL_TIMEOUT;
1165       break;
1166     }
1167   }
1168 
1169   if (status == HAL_OK)
1170   {
1171     /* Make sure PLLSource is ready */
1172     status = RCCEx_PLLSource_Enable(PLLInit->PLLSource);
1173 
1174     if (status == HAL_OK)
1175     {
1176       /* Configure the PLL clock source, multiplication factor N, */
1177       /* and division factors M, P, Q and R */
1178       __HAL_RCC_PLL_CONFIG(PLLInit->PLLSource, PLLInit->PLLM, PLLInit->PLLN,
1179                            PLLInit->PLLP, PLLInit->PLLQ, PLLInit->PLLR);
1180 
1181       /* Configure the PLL Clock output(s) */
1182       __HAL_RCC_PLLCLKOUT_ENABLE(PLLInit->PLLClockOut);
1183 
1184       /* Enable the PLL again by setting PLLON to 1*/
1185       __HAL_RCC_PLL_ENABLE();
1186 
1187       /* Get Start Tick*/
1188       tickstart = HAL_GetTick();
1189 
1190       /* Wait till PLL is ready */
1191       while (READ_BIT(RCC->CR, RCC_CR_PLLRDY) == 0U)
1192       {
1193         if ((HAL_GetTick() - tickstart) > 2U) /* PLL_TIMEOUT_VALUE) */
1194         {
1195           status = HAL_TIMEOUT;
1196           break;
1197         }
1198       }
1199     }
1200   }
1201 
1202   return status;
1203 }
1204 
1205 /**
1206   * @brief  Disable PLL.
1207   * @retval HAL status
1208   */
HAL_RCCEx_DisablePLL(void)1209 HAL_StatusTypeDef HAL_RCCEx_DisablePLL(void)
1210 {
1211   uint32_t tickstart;
1212   HAL_StatusTypeDef status = HAL_OK;
1213 
1214   /* Disable the PLL */
1215   __HAL_RCC_PLL_DISABLE();
1216 
1217   /* Get Start Tick*/
1218   tickstart = HAL_GetTick();
1219 
1220   /* Wait till PLL is ready */
1221   while (READ_BIT(RCC->CR, RCC_CR_PLLRDY) != 0U)
1222   {
1223     if ((HAL_GetTick() - tickstart) > 2U) /* PLL_TIMEOUT_VALUE) */
1224     {
1225       status = HAL_TIMEOUT;
1226       break;
1227     }
1228   }
1229 
1230   /* To save power disable the PLL Source, FRACN and Clock outputs */
1231   CLEAR_BIT(RCC->PLLCFGR, RCC_PLLCFGR_PLLREN | RCC_PLLCFGR_PLLQEN | RCC_PLLCFGR_PLLPEN | RCC_PLLCFGR_PLLSRC);
1232 
1233   return status;
1234 }
1235 
1236 /**
1237   * @brief  Configure the oscillator clock source for wakeup from Stop and CSS backup clock.
1238   * @param  WakeUpClk  Wakeup clock
1239   *         This parameter can be one of the following values:
1240   *            @arg @ref RCC_STOP_WAKEUPCLOCK_MSI  MSI oscillator selection
1241   *            @arg @ref RCC_STOP_WAKEUPCLOCK_HSI  HSI oscillator selection
1242   * @note   This function shall not be called after the Clock Security System on HSE has been
1243   *         enabled.
1244   * @retval None
1245   */
HAL_RCCEx_WakeUpStopCLKConfig(uint32_t WakeUpClk)1246 void HAL_RCCEx_WakeUpStopCLKConfig(uint32_t WakeUpClk)
1247 {
1248   assert_param(IS_RCC_STOP_WAKEUPCLOCK(WakeUpClk));
1249 
1250   __HAL_RCC_WAKEUPSTOP_CLK_CONFIG(WakeUpClk);
1251 }
1252 
1253 /**
1254   * @brief  Configure the MSI range after standby mode.
1255   * @note   After Standby its frequency can be selected between 3 possible values (1, 3.072 or 4 MHz).
1256   * @param  MSIRange  MSI range
1257   *         This parameter can be one of the following values:
1258   *            @arg @ref RCC_MSIRANGE_4  Range 4 around 4 MHz (reset value)
1259   *            @arg @ref RCC_MSIRANGE_5  Range 5 around 2 MHz
1260   *            @arg @ref RCC_MSIRANGE_6  Range 6 around 1.5 MHz
1261   *            @arg @ref RCC_MSIRANGE_7  Range 7 around 1 MHz
1262   * @retval None
1263   */
HAL_RCCEx_StandbyMSIRangeConfig(uint32_t MSIRange)1264 void HAL_RCCEx_StandbyMSIRangeConfig(uint32_t MSIRange)
1265 {
1266   assert_param(IS_RCC_MSI_STANDBY_CLOCK_RANGE(MSIRange));
1267 
1268   __HAL_RCC_MSI_STANDBY_RANGE_CONFIG(MSIRange);
1269 }
1270 
1271 /**
1272   * @brief  Enable the PLL-mode of the MSI.
1273   * @note   Prior to enable the PLL-mode of the MSI for automatic hardware
1274   *         calibration LSE oscillator is to be enabled with HAL_RCC_OscConfig().
1275   * @retval None
1276   */
HAL_RCCEx_EnableMSIPLLMode(void)1277 void HAL_RCCEx_EnableMSIPLLMode(void)
1278 {
1279   SET_BIT(RCC->CR, RCC_CR_MSIPLLEN);
1280 }
1281 
1282 /**
1283   * @brief  Disable the PLL-mode of the MSI.
1284   * @note   PLL-mode of the MSI is automatically reset when LSE oscillator is disabled.
1285   * @retval None
1286   */
HAL_RCCEx_DisableMSIPLLMode(void)1287 void HAL_RCCEx_DisableMSIPLLMode(void)
1288 {
1289   CLEAR_BIT(RCC->CR, RCC_CR_MSIPLLEN);
1290 }
1291 
1292 /**
1293   * @brief  Enables the LSE Clock Security System.
1294   * @retval None
1295   */
HAL_RCCEx_EnableLSECSS(void)1296 void HAL_RCCEx_EnableLSECSS(void)
1297 {
1298   SET_BIT(RCC->BDCR, RCC_BDCR_LSECSSON) ;
1299 }
1300 
1301 /**
1302   * @brief  Disables the LSE Clock Security System.
1303   * @note   Once enabled this bit cannot be disabled, except after an LSE failure detection
1304   *         (LSECSSD=1). In that case the software MUST disable the LSECSSON bit.
1305   *         Reset by power on reset and RTC software reset (RTCRST bit).
1306   * @retval None
1307   */
HAL_RCCEx_DisableLSECSS(void)1308 void HAL_RCCEx_DisableLSECSS(void)
1309 {
1310   /* Disable LSE CSS */
1311   CLEAR_BIT(RCC->BDCR, RCC_BDCR_LSECSSON) ;
1312 }
1313 
1314 /**
1315   * @brief  Enable the LSE Clock Security System IT & corresponding EXTI line.
1316   * @note   LSE Clock Security System IT is mapped on RTC EXTI line 27
1317   * @retval None
1318   */
HAL_RCCEx_EnableLSECSS_IT(void)1319 void HAL_RCCEx_EnableLSECSS_IT(void)
1320 {
1321   /* Enable LSE CSS */
1322   SET_BIT(RCC->BDCR, RCC_BDCR_LSECSSON) ;
1323   /* Enable LSE CSS IT */
1324   __HAL_RCC_ENABLE_IT(RCC_IT_LSECSS);
1325   /* Enable IT on EXTI Line 27 */
1326   __HAL_RCC_LSECSS_EXTI_ENABLE_IT();
1327   __HAL_RCC_LSECSS_EXTI_ENABLE_RISING_EDGE();
1328 }
1329 
1330 /**
1331   * @brief Handle the RCC LSE Clock Security System interrupt request.
1332   * @retval None
1333   */
HAL_RCCEx_LSECSS_IRQHandler(void)1334 void HAL_RCCEx_LSECSS_IRQHandler(void)
1335 {
1336   /* Check RCC LSE CSSF flag  */
1337   if (__HAL_RCC_GET_IT(RCC_IT_LSECSS))
1338   {
1339     /* RCC LSE Clock Security System interrupt user callback */
1340     HAL_RCCEx_LSECSS_Callback();
1341 
1342     /* Clear RCC LSE CSS pending bit */
1343     __HAL_RCC_CLEAR_IT(RCC_IT_LSECSS);
1344   }
1345 }
1346 
1347 /**
1348   * @brief  RCCEx LSE Clock Security System interrupt callback.
1349   * @retval none
1350   */
HAL_RCCEx_LSECSS_Callback(void)1351 __weak void HAL_RCCEx_LSECSS_Callback(void)
1352 {
1353   /* NOTE : This function should not be modified, when the callback is needed,
1354             the @ref HAL_RCCEx_LSECSS_Callback should be implemented in the user file
1355    */
1356 }
1357 
1358 /**
1359   * @brief  Select the Low Speed clock source to output on LSCO pin (PA2).
1360   * @param  LSCOSource  specifies the Low Speed clock source to output.
1361   *          This parameter can be one of the following values:
1362   *            @arg @ref RCC_LSCOSOURCE_LSI  LSI clock selected as LSCO source
1363   *            @arg @ref RCC_LSCOSOURCE_LSE  LSE clock selected as LSCO source
1364   * @retval None
1365   */
HAL_RCCEx_EnableLSCO(uint32_t LSCOSource)1366 void HAL_RCCEx_EnableLSCO(uint32_t LSCOSource)
1367 {
1368   GPIO_InitTypeDef GPIO_InitStruct = {0};
1369   FlagStatus       pwrclkchanged = RESET;
1370   FlagStatus       backupchanged = RESET;
1371 
1372   /* Check the parameters */
1373   assert_param(IS_RCC_LSCOSOURCE(LSCOSource));
1374 
1375   /* LSCO Pin Clock Enable */
1376   __LSCO_CLK_ENABLE();
1377 #if defined (LSCO_PIN)
1378   /* Configure the LSCO pin in analog mode */
1379   GPIO_InitStruct.Pin = LSCO_PIN;
1380   GPIO_InitStruct.Mode = GPIO_MODE_ANALOG;
1381   GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;
1382   GPIO_InitStruct.Pull = GPIO_NOPULL;
1383   HAL_GPIO_Init(LSCO_GPIO_PORT, &GPIO_InitStruct);
1384 #endif /* LSCO_PIN */
1385   /* Update LSCOSEL clock source in Backup Domain control register */
1386   if (__HAL_RCC_PWR_IS_CLK_DISABLED())
1387   {
1388     __HAL_RCC_PWR_CLK_ENABLE();
1389     pwrclkchanged = SET;
1390   }
1391   if (HAL_IS_BIT_CLR(PWR->CR1, PWR_CR1_DBP))
1392   {
1393     HAL_PWR_EnableBkUpAccess();
1394     backupchanged = SET;
1395   }
1396 
1397   MODIFY_REG(RCC->BDCR, RCC_BDCR_LSCOSEL | RCC_BDCR_LSCOEN, LSCOSource | RCC_BDCR_LSCOEN);
1398 
1399   if (backupchanged == SET)
1400   {
1401     HAL_PWR_DisableBkUpAccess();
1402   }
1403   if (pwrclkchanged == SET)
1404   {
1405     __HAL_RCC_PWR_CLK_DISABLE();
1406   }
1407 }
1408 
1409 /**
1410   * @brief  Disable the Low Speed clock output.
1411   * @retval None
1412   */
HAL_RCCEx_DisableLSCO(void)1413 void HAL_RCCEx_DisableLSCO(void)
1414 {
1415   FlagStatus       pwrclkchanged = RESET;
1416   FlagStatus       backupchanged = RESET;
1417 
1418   /* Update LSCOEN bit in Backup Domain control register */
1419   if (__HAL_RCC_PWR_IS_CLK_DISABLED())
1420   {
1421     __HAL_RCC_PWR_CLK_ENABLE();
1422     pwrclkchanged = SET;
1423   }
1424   if (HAL_IS_BIT_CLR(PWR->CR1, PWR_CR1_DBP))
1425   {
1426     /* Enable access to the backup domain */
1427     HAL_PWR_EnableBkUpAccess();
1428     backupchanged = SET;
1429   }
1430 
1431   CLEAR_BIT(RCC->BDCR, RCC_BDCR_LSCOEN);
1432 
1433   /* Restore previous configuration */
1434   if (backupchanged == SET)
1435   {
1436     /* Disable access to the backup domain */
1437     HAL_PWR_DisableBkUpAccess();
1438   }
1439   if (pwrclkchanged == SET)
1440   {
1441     __HAL_RCC_PWR_CLK_DISABLE();
1442   }
1443 }
1444 
1445 /**
1446   * @}
1447   */
1448 
1449 #if defined(CRS)
1450 
1451 /** @defgroup RCCEx_Exported_Functions_Group3 Extended Clock Recovery System Control functions
1452   * @brief  Extended Clock Recovery System Control functions
1453   *
1454 @verbatim
1455  ===============================================================================
1456                 ##### Extended Clock Recovery System Control functions  #####
1457  ===============================================================================
1458     [..]
1459       For devices with Clock Recovery System feature (CRS), RCC Extension HAL driver can be used as follows:
1460 
1461       (#) In System clock config, HSI48 needs to be enabled
1462 
1463       (#) Enable CRS clock in IP MSP init which will use CRS functions
1464 
1465       (#) Call CRS functions as follows:
1466           (##) Prepare synchronization configuration necessary for HSI48 calibration
1467               (+++) Default values can be set for frequency Error Measurement (reload and error limit)
1468                         and also HSI48 oscillator smooth trimming.
1469               (+++) Macro __HAL_RCC_CRS_RELOADVALUE_CALCULATE can be also used to calculate
1470                         directly reload value with target and synchronization frequencies values
1471           (##) Call function HAL_RCCEx_CRSConfig which
1472               (+++) Resets CRS registers to their default values.
1473               (+++) Configures CRS registers with synchronization configuration
1474               (+++) Enables automatic calibration and frequency error counter feature
1475            Note: When using USB LPM (Link Power Management) and the device is in Sleep mode, the
1476            periodic USB SOF will not be generated by the host. No SYNC signal will therefore be
1477            provided to the CRS to calibrate the HSI48 on the run. To guarantee the required clock
1478            precision after waking up from Sleep mode, the LSE or reference clock on the GPIOs
1479            should be used as SYNC signal.
1480 
1481           (##) A polling function is provided to wait for complete synchronization
1482               (+++) Call function HAL_RCCEx_CRSWaitSynchronization()
1483               (+++) According to CRS status, user can decide to adjust again the calibration or continue
1484                         application if synchronization is OK
1485 
1486       (#) User can retrieve information related to synchronization in calling function
1487             HAL_RCCEx_CRSGetSynchronizationInfo()
1488 
1489       (#) Regarding synchronization status and synchronization information, user can try a new calibration
1490            in changing synchronization configuration and call again HAL_RCCEx_CRSConfig.
1491            Note: When the SYNC event is detected during the downcounting phase (before reaching the zero value),
1492            it means that the actual frequency is lower than the target (and so, that the TRIM value should be
1493            incremented), while when it is detected during the upcounting phase it means that the actual frequency
1494            is higher (and that the TRIM value should be decremented).
1495 
1496       (#) In interrupt mode, user can resort to the available macros (__HAL_RCC_CRS_XXX_IT). Interrupts will go
1497           through CRS Handler (CRS_IRQn/CRS_IRQHandler)
1498               (++) Call function HAL_RCCEx_CRSConfig()
1499               (++) Enable CRS_IRQn (thanks to NVIC functions)
1500               (++) Enable CRS interrupt (__HAL_RCC_CRS_ENABLE_IT)
1501               (++) Implement CRS status management in the following user callbacks called from
1502                    HAL_RCCEx_CRS_IRQHandler():
1503                    (+++) HAL_RCCEx_CRS_SyncOkCallback()
1504                    (+++) HAL_RCCEx_CRS_SyncWarnCallback()
1505                    (+++) HAL_RCCEx_CRS_ExpectedSyncCallback()
1506                    (+++) HAL_RCCEx_CRS_ErrorCallback()
1507 
1508       (#) To force a SYNC EVENT, user can use the function HAL_RCCEx_CRSSoftwareSynchronizationGenerate().
1509           This function can be called before calling HAL_RCCEx_CRSConfig (for instance in Systick handler)
1510 
1511 @endverbatim
1512   * @{
1513   */
1514 
1515 /**
1516   * @brief  Start automatic synchronization for polling mode
1517   * @param  pInit Pointer on RCC_CRSInitTypeDef structure
1518   * @retval None
1519   */
HAL_RCCEx_CRSConfig(const RCC_CRSInitTypeDef * const pInit)1520 void HAL_RCCEx_CRSConfig(const RCC_CRSInitTypeDef *const pInit)
1521 {
1522   uint32_t value;  /* no init needed */
1523 
1524   /* Check the parameters */
1525   assert_param(IS_RCC_CRS_SYNC_DIV(pInit->Prescaler));
1526   assert_param(IS_RCC_CRS_SYNC_SOURCE(pInit->Source));
1527   assert_param(IS_RCC_CRS_SYNC_POLARITY(pInit->Polarity));
1528   assert_param(IS_RCC_CRS_RELOADVALUE(pInit->ReloadValue));
1529   assert_param(IS_RCC_CRS_ERRORLIMIT(pInit->ErrorLimitValue));
1530   assert_param(IS_RCC_CRS_HSI48CALIBRATION(pInit->HSI48CalibrationValue));
1531 
1532   /* CONFIGURATION */
1533 
1534   /* Before configuration, reset CRS registers to their default values*/
1535   __HAL_RCC_CRS_FORCE_RESET();
1536   __HAL_RCC_CRS_RELEASE_RESET();
1537 
1538   /* Set the SYNCDIV[2:0] bits according to Prescaler value */
1539   /* Set the SYNCSRC[1:0] bits according to Source value */
1540   /* Set the SYNCSPOL bit according to Polarity value */
1541   value = (pInit->Prescaler | pInit->Source | pInit->Polarity);
1542   /* Set the RELOAD[15:0] bits according to ReloadValue value */
1543   value |= pInit->ReloadValue;
1544   /* Set the FELIM[7:0] bits according to ErrorLimitValue value */
1545   value |= (pInit->ErrorLimitValue << CRS_CFGR_FELIM_Pos);
1546   WRITE_REG(CRS->CFGR, value);
1547 
1548   /* Adjust HSI48 oscillator smooth trimming */
1549   /* Set the TRIM[6:0] bits according to RCC_CRS_HSI48CalibrationValue value */
1550   MODIFY_REG(CRS->CR, CRS_CR_TRIM, (pInit->HSI48CalibrationValue << CRS_CR_TRIM_Pos));
1551 
1552   /* START AUTOMATIC SYNCHRONIZATION*/
1553 
1554   /* Enable Automatic trimming & Frequency error counter */
1555   SET_BIT(CRS->CR, CRS_CR_AUTOTRIMEN | CRS_CR_CEN);
1556 }
1557 
1558 /**
1559   * @brief  Generate the software synchronization event
1560   * @retval None
1561   */
HAL_RCCEx_CRSSoftwareSynchronizationGenerate(void)1562 void HAL_RCCEx_CRSSoftwareSynchronizationGenerate(void)
1563 {
1564   SET_BIT(CRS->CR, CRS_CR_SWSYNC);
1565 }
1566 
1567 /**
1568   * @brief  Return synchronization info
1569   * @param  pSynchroInfo Pointer on RCC_CRSSynchroInfoTypeDef structure
1570   * @retval None
1571   */
HAL_RCCEx_CRSGetSynchronizationInfo(RCC_CRSSynchroInfoTypeDef * pSynchroInfo)1572 void HAL_RCCEx_CRSGetSynchronizationInfo(RCC_CRSSynchroInfoTypeDef *pSynchroInfo)
1573 {
1574   /* Check the parameter */
1575   assert_param(pSynchroInfo != (void *)NULL);
1576 
1577   /* Get the reload value */
1578   pSynchroInfo->ReloadValue = (READ_BIT(CRS->CFGR, CRS_CFGR_RELOAD));
1579 
1580   /* Get HSI48 oscillator smooth trimming */
1581   pSynchroInfo->HSI48CalibrationValue = (READ_BIT(CRS->CR, CRS_CR_TRIM) >> CRS_CR_TRIM_Pos);
1582 
1583   /* Get Frequency error capture */
1584   pSynchroInfo->FreqErrorCapture = (READ_BIT(CRS->ISR, CRS_ISR_FECAP) >> CRS_ISR_FECAP_Pos);
1585 
1586   /* Get Frequency error direction */
1587   pSynchroInfo->FreqErrorDirection = (READ_BIT(CRS->ISR, CRS_ISR_FEDIR));
1588 }
1589 
1590 /**
1591   * @brief Wait for CRS Synchronization status.
1592   * @param Timeout  Duration of the timeout
1593   * @note  Timeout is based on the maximum time to receive a SYNC event based on synchronization
1594   *        frequency.
1595   * @note    If Timeout set to HAL_MAX_DELAY, HAL_TIMEOUT will be never returned.
1596   * @retval Combination of Synchronization status
1597   *          This parameter can be a combination of the following values:
1598   *            @arg @ref RCC_CRS_TIMEOUT
1599   *            @arg @ref RCC_CRS_SYNCOK
1600   *            @arg @ref RCC_CRS_SYNCWARN
1601   *            @arg @ref RCC_CRS_SYNCERR
1602   *            @arg @ref RCC_CRS_SYNCMISS
1603   *            @arg @ref RCC_CRS_TRIMOVF
1604   */
HAL_RCCEx_CRSWaitSynchronization(uint32_t Timeout)1605 uint32_t HAL_RCCEx_CRSWaitSynchronization(uint32_t Timeout)
1606 {
1607   uint32_t crsstatus = RCC_CRS_NONE;
1608   uint32_t tickstart;
1609 
1610   /* Get timeout */
1611   tickstart = HAL_GetTick();
1612 
1613   /* Wait for CRS flag or timeout detection */
1614   do
1615   {
1616     if (Timeout != HAL_MAX_DELAY)
1617     {
1618       if (((HAL_GetTick() - tickstart) > Timeout) || (Timeout == 0U))
1619       {
1620         crsstatus = RCC_CRS_TIMEOUT;
1621       }
1622     }
1623     /* Check CRS SYNCOK flag  */
1624     if (__HAL_RCC_CRS_GET_FLAG(RCC_CRS_FLAG_SYNCOK))
1625     {
1626       /* CRS SYNC event OK */
1627       crsstatus |= RCC_CRS_SYNCOK;
1628 
1629       /* Clear CRS SYNC event OK bit */
1630       __HAL_RCC_CRS_CLEAR_FLAG(RCC_CRS_FLAG_SYNCOK);
1631     }
1632 
1633     /* Check CRS SYNCWARN flag  */
1634     if (__HAL_RCC_CRS_GET_FLAG(RCC_CRS_FLAG_SYNCWARN))
1635     {
1636       /* CRS SYNC warning */
1637       crsstatus |= RCC_CRS_SYNCWARN;
1638 
1639       /* Clear CRS SYNCWARN bit */
1640       __HAL_RCC_CRS_CLEAR_FLAG(RCC_CRS_FLAG_SYNCWARN);
1641     }
1642 
1643     /* Check CRS TRIM overflow flag  */
1644     if (__HAL_RCC_CRS_GET_FLAG(RCC_CRS_FLAG_TRIMOVF))
1645     {
1646       /* CRS SYNC Error */
1647       crsstatus |= RCC_CRS_TRIMOVF;
1648 
1649       /* Clear CRS Error bit */
1650       __HAL_RCC_CRS_CLEAR_FLAG(RCC_CRS_FLAG_TRIMOVF);
1651     }
1652 
1653     /* Check CRS Error flag  */
1654     if (__HAL_RCC_CRS_GET_FLAG(RCC_CRS_FLAG_SYNCERR))
1655     {
1656       /* CRS SYNC Error */
1657       crsstatus |= RCC_CRS_SYNCERR;
1658 
1659       /* Clear CRS Error bit */
1660       __HAL_RCC_CRS_CLEAR_FLAG(RCC_CRS_FLAG_SYNCERR);
1661     }
1662 
1663     /* Check CRS SYNC Missed flag  */
1664     if (__HAL_RCC_CRS_GET_FLAG(RCC_CRS_FLAG_SYNCMISS))
1665     {
1666       /* CRS SYNC Missed */
1667       crsstatus |= RCC_CRS_SYNCMISS;
1668 
1669       /* Clear CRS SYNC Missed bit */
1670       __HAL_RCC_CRS_CLEAR_FLAG(RCC_CRS_FLAG_SYNCMISS);
1671     }
1672 
1673     /* Check CRS Expected SYNC flag  */
1674     if (__HAL_RCC_CRS_GET_FLAG(RCC_CRS_FLAG_ESYNC))
1675     {
1676       /* frequency error counter reached a zero value */
1677       __HAL_RCC_CRS_CLEAR_FLAG(RCC_CRS_FLAG_ESYNC);
1678     }
1679   } while (RCC_CRS_NONE == crsstatus);
1680 
1681   return crsstatus;
1682 }
1683 
1684 /**
1685   * @brief Handle the Clock Recovery System interrupt request.
1686   * @retval None
1687   */
HAL_RCCEx_CRS_IRQHandler(void)1688 void HAL_RCCEx_CRS_IRQHandler(void)
1689 {
1690   uint32_t crserror = RCC_CRS_NONE;
1691   /* Get current IT flags and IT sources values */
1692   uint32_t itflags = READ_REG(CRS->ISR);
1693   uint32_t itsources = READ_REG(CRS->CR);
1694 
1695   /* Check CRS SYNCOK flag  */
1696   if (((itflags & RCC_CRS_FLAG_SYNCOK) != 0U) && ((itsources & RCC_CRS_IT_SYNCOK) != 0U))
1697   {
1698     /* Clear CRS SYNC event OK flag */
1699     WRITE_REG(CRS->ICR, CRS_ICR_SYNCOKC);
1700 
1701     /* user callback */
1702     HAL_RCCEx_CRS_SyncOkCallback();
1703   }
1704   /* Check CRS SYNCWARN flag  */
1705   else if (((itflags & RCC_CRS_FLAG_SYNCWARN) != 0U) && ((itsources & RCC_CRS_IT_SYNCWARN) != 0U))
1706   {
1707     /* Clear CRS SYNCWARN flag */
1708     WRITE_REG(CRS->ICR, CRS_ICR_SYNCWARNC);
1709 
1710     /* user callback */
1711     HAL_RCCEx_CRS_SyncWarnCallback();
1712   }
1713   /* Check CRS Expected SYNC flag  */
1714   else if (((itflags & RCC_CRS_FLAG_ESYNC) != 0U) && ((itsources & RCC_CRS_IT_ESYNC) != 0U))
1715   {
1716     /* frequency error counter reached a zero value */
1717     WRITE_REG(CRS->ICR, CRS_ICR_ESYNCC);
1718 
1719     /* user callback */
1720     HAL_RCCEx_CRS_ExpectedSyncCallback();
1721   }
1722   /* Check CRS Error flags  */
1723   else
1724   {
1725     if (((itflags & RCC_CRS_FLAG_ERR) != 0U) && ((itsources & RCC_CRS_IT_ERR) != 0U))
1726     {
1727       if ((itflags & RCC_CRS_FLAG_SYNCERR) != 0U)
1728       {
1729         crserror |= RCC_CRS_SYNCERR;
1730       }
1731       if ((itflags & RCC_CRS_FLAG_SYNCMISS) != 0U)
1732       {
1733         crserror |= RCC_CRS_SYNCMISS;
1734       }
1735       if ((itflags & RCC_CRS_FLAG_TRIMOVF) != 0U)
1736       {
1737         crserror |= RCC_CRS_TRIMOVF;
1738       }
1739 
1740       /* Clear CRS Error flags */
1741       WRITE_REG(CRS->ICR, CRS_ICR_ERRC);
1742 
1743       /* user error callback */
1744       HAL_RCCEx_CRS_ErrorCallback(crserror);
1745     }
1746   }
1747 }
1748 
1749 /**
1750   * @brief  RCCEx Clock Recovery System SYNCOK interrupt callback.
1751   * @retval none
1752   */
HAL_RCCEx_CRS_SyncOkCallback(void)1753 __weak void HAL_RCCEx_CRS_SyncOkCallback(void)
1754 {
1755   /* NOTE : This function should not be modified, when the callback is needed,
1756             the @ref HAL_RCCEx_CRS_SyncOkCallback should be implemented in the user file
1757    */
1758 }
1759 
1760 /**
1761   * @brief  RCCEx Clock Recovery System SYNCWARN interrupt callback.
1762   * @retval none
1763   */
HAL_RCCEx_CRS_SyncWarnCallback(void)1764 __weak void HAL_RCCEx_CRS_SyncWarnCallback(void)
1765 {
1766   /* NOTE : This function should not be modified, when the callback is needed,
1767             the @ref HAL_RCCEx_CRS_SyncWarnCallback should be implemented in the user file
1768    */
1769 }
1770 
1771 /**
1772   * @brief  RCCEx Clock Recovery System Expected SYNC interrupt callback.
1773   * @retval none
1774   */
HAL_RCCEx_CRS_ExpectedSyncCallback(void)1775 __weak void HAL_RCCEx_CRS_ExpectedSyncCallback(void)
1776 {
1777   /* NOTE : This function should not be modified, when the callback is needed,
1778             the @ref HAL_RCCEx_CRS_ExpectedSyncCallback should be implemented in the user file
1779    */
1780 }
1781 
1782 /**
1783   * @brief  RCCEx Clock Recovery System Error interrupt callback.
1784   * @param  Error Combination of Error status.
1785   *         This parameter can be a combination of the following values:
1786   *           @arg @ref RCC_CRS_SYNCERR
1787   *           @arg @ref RCC_CRS_SYNCMISS
1788   *           @arg @ref RCC_CRS_TRIMOVF
1789   * @retval none
1790   */
HAL_RCCEx_CRS_ErrorCallback(uint32_t Error)1791 __weak void HAL_RCCEx_CRS_ErrorCallback(uint32_t Error)
1792 {
1793   /* Prevent unused argument(s) compilation warning */
1794   UNUSED(Error);
1795 
1796   /* NOTE : This function should not be modified, when the callback is needed,
1797             the @ref HAL_RCCEx_CRS_ErrorCallback should be implemented in the user file
1798    */
1799 }
1800 
1801 /**
1802   * @}
1803   */
1804 
1805 #endif /* CRS */
1806 
1807 /** @addtogroup RCCEx_Private_Functions
1808   * @{
1809   */
1810 
RCCEx_PLLSource_Enable(uint32_t PllSource)1811 static HAL_StatusTypeDef RCCEx_PLLSource_Enable(uint32_t PllSource)
1812 {
1813   uint32_t tickstart;
1814   HAL_StatusTypeDef status = HAL_OK;
1815 
1816   switch (PllSource)
1817   {
1818     case RCC_PLLSOURCE_MSI:
1819       /* Check whether MSI in not ready and enable it */
1820       if (READ_BIT(RCC->CR, RCC_CR_MSIRDY) == 0U)
1821       {
1822         /* Enable the Internal Multi Speed oscillator (MSI). */
1823         __HAL_RCC_MSI_ENABLE();
1824 
1825         /* Get timeout */
1826         tickstart = HAL_GetTick();
1827 
1828         /* Wait till MSI is ready */
1829         while (READ_BIT(RCC->CR, RCC_CR_MSIRDY) == 0U)
1830         {
1831           if ((HAL_GetTick() - tickstart) > RCC_MSI_TIMEOUT_VALUE)
1832           {
1833             status = HAL_TIMEOUT;
1834             break;
1835           }
1836         }
1837       }
1838       break;
1839 
1840     case RCC_PLLSOURCE_HSI:
1841       /* Check whether HSI in not ready and enable it */
1842       if (READ_BIT(RCC->CR, RCC_CR_HSIRDY) == 0U)
1843       {
1844         /* Enable the Internal High Speed oscillator (HSI). */
1845         __HAL_RCC_HSI_ENABLE();
1846 
1847         /* Get timeout */
1848         tickstart = HAL_GetTick();
1849 
1850         /* Wait till MSI is ready */
1851         while (READ_BIT(RCC->CR, RCC_CR_HSIRDY) == 0U)
1852         {
1853           if ((HAL_GetTick() - tickstart) > RCC_HSI_TIMEOUT_VALUE)
1854           {
1855             status = HAL_TIMEOUT;
1856             break;
1857           }
1858         }
1859       }
1860       break;
1861 
1862     case RCC_PLLSOURCE_HSE:
1863       /* Check whether HSE in not ready and enable it */
1864       if (READ_BIT(RCC->CR, RCC_CR_HSERDY) == 0U)
1865       {
1866         /* Enable the External High Speed oscillator (HSE). */
1867         SET_BIT(RCC->CR, RCC_CR_HSEON);
1868 
1869         /* Get Start Tick*/
1870         tickstart = HAL_GetTick();
1871 
1872         /* Wait till HSE is ready */
1873         while (READ_BIT(RCC->CR, RCC_CR_HSERDY) == 0U)
1874         {
1875           if ((HAL_GetTick() - tickstart) > RCC_HSE_TIMEOUT_VALUE)
1876           {
1877             status = HAL_TIMEOUT;
1878             break;
1879           }
1880         }
1881       }
1882       break;
1883 
1884     default:
1885       status = HAL_ERROR;
1886       break;
1887   }
1888 
1889   return status;
1890 }
1891 
1892 /**
1893   * @}
1894   */
1895 
1896 /**
1897   * @}
1898   */
1899 
1900 /**
1901   * @}
1902   */
1903 
1904 #endif /* HAL_RCC_MODULE_ENABLED */
1905 
1906 /**
1907   * @}
1908   */
1909 
1910 /**
1911   * @}
1912   */
1913