1 /**
2   ******************************************************************************
3   * @file    stm32wbxx_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   * @attention
13   *
14   * Copyright (c) 2019 STMicroelectronics.
15   * All rights reserved.
16   *
17   * This software is licensed under terms that can be found in the LICENSE file
18   * in 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 
24 /* Includes ------------------------------------------------------------------*/
25 #include "stm32wbxx_hal.h"
26 
27 /** @addtogroup STM32WBxx_HAL_Driver
28   * @{
29   */
30 
31 /** @defgroup RCCEx RCCEx
32   * @brief RCC Extended HAL module driver
33   * @{
34   */
35 
36 #ifdef HAL_RCC_MODULE_ENABLED
37 
38 /* Private typedef -----------------------------------------------------------*/
39 /* Private defines -----------------------------------------------------------*/
40 /** @defgroup RCCEx_Private_Constants RCCEx Private Constants
41   * @{
42   */
43 #if defined(SAI1)
44 #define PLLSAI1_TIMEOUT_VALUE    (2U)    /* 2 ms (minimum Tick + 1) */
45 #endif /* SAI1 */
46 #define PLL_TIMEOUT_VALUE        (2U)    /* 2 ms (minimum Tick + 1) */
47 
48 #define CLOCKSMPS_TIMEOUT_VALUE  (5000U) /* 5 s */
49 
50 #define __LSCO1_CLK_ENABLE()   __HAL_RCC_GPIOA_CLK_ENABLE()
51 #define LSCO1_GPIO_PORT        GPIOA
52 #define LSCO1_PIN              GPIO_PIN_2
53 
54 #define __LSCO2_CLK_ENABLE()   __HAL_RCC_GPIOH_CLK_ENABLE()
55 #define LSCO2_GPIO_PORT        GPIOH
56 #define LSCO2_PIN              GPIO_PIN_3
57 
58 #if defined(RCC_LSCO3_SUPPORT)
59 #define __LSCO3_CLK_ENABLE()   __HAL_RCC_GPIOC_CLK_ENABLE()
60 #define LSCO3_GPIO_PORT        GPIOC
61 #define LSCO3_PIN              GPIO_PIN_12
62 #endif /* RCC_LSCO3_SUPPORT */
63 
64 #define LSI2_TIMEOUT_VALUE         (3U)   /* to be adjusted with DS    */
65 
66 /**
67   * @}
68   */
69 
70 /* Private macros ------------------------------------------------------------*/
71 /* Private variables ---------------------------------------------------------*/
72 /* Private function prototypes -----------------------------------------------*/
73 /** @defgroup RCCEx_Private_Functions RCCEx Private Functions
74   * @{
75   */
76 #if defined(SAI1)
77 static HAL_StatusTypeDef RCCEx_PLLSAI1_ConfigNP(RCC_PLLSAI1InitTypeDef *PLLSAI1);
78 static HAL_StatusTypeDef RCCEx_PLLSAI1_ConfigNQ(RCC_PLLSAI1InitTypeDef *PLLSAI1);
79 static HAL_StatusTypeDef RCCEx_PLLSAI1_ConfigNR(RCC_PLLSAI1InitTypeDef *PLLSAI1);
80 #endif /* SAI1 */
81 
82 static uint32_t          RCC_PLL_GetFreqDomain_P(void);
83 static uint32_t          RCC_PLL_GetFreqDomain_Q(void);
84 
85 #if defined(SAI1)
86 static uint32_t          RCC_PLLSAI1_GetFreqDomain_R(void);
87 static uint32_t          RCC_PLLSAI1_GetFreqDomain_P(void);
88 static uint32_t          RCC_PLLSAI1_GetFreqDomain_Q(void);
89 #endif /* SAI1 */
90 
91 /**
92   * @}
93   */
94 
95 /* Exported functions --------------------------------------------------------*/
96 
97 /** @defgroup RCCEx_Exported_Functions RCCEx Exported Functions
98   * @{
99   */
100 
101 /** @defgroup RCCEx_Exported_Functions_Group1 Extended Peripheral Control functions
102   *  @brief  Extended Peripheral Control functions
103   *
104 @verbatim
105  ===============================================================================
106                 ##### Extended Peripheral Control functions  #####
107  ===============================================================================
108     [..]
109     This subsection provides a set of functions allowing to control the RCC Clocks
110     frequencies.
111     [..]
112     (@) Important note: Care must be taken when HAL_RCCEx_PeriphCLKConfig() is used to
113         select the RTC clock source; in this case the Backup domain will be reset in
114         order to modify the RTC Clock source, as consequence RTC registers (including
115         the backup registers) and RCC_BDCR register are set to their reset values.
116 
117 @endverbatim
118   * @{
119   */
120 
121 /**
122   * @brief  Initialize the RCC extended peripherals clocks according to the specified
123   *         parameters in the @ref RCC_PeriphCLKInitTypeDef.
124   * @param  PeriphClkInit  pointer to a @ref RCC_PeriphCLKInitTypeDef structure that
125   *         contains a field PeriphClockSelection which can be a combination of the following values:
126   *
127   *            @arg @ref RCC_PERIPHCLK_USART1   USART1 peripheral clock
128   *            @arg @ref RCC_PERIPHCLK_LPUART1  LPUART1 peripheral clock
129   *            @arg @ref RCC_PERIPHCLK_I2C1     I2C1 peripheral clock
130   *            @arg @ref RCC_PERIPHCLK_I2C3     I2C3 peripheral clock
131   *            @arg @ref RCC_PERIPHCLK_LPTIM1   LPTIM1 peripheral clock
132   *            @arg @ref RCC_PERIPHCLK_LPTIM2   LPTIM2 peripheral clock
133   *            @arg @ref RCC_PERIPHCLK_SAI1     SAI1 peripheral clock
134   *            @arg @ref RCC_PERIPHCLK_USB      USB peripheral clock
135   *            @arg @ref RCC_PERIPHCLK_RNG      RNG peripheral clock
136   *            @arg @ref RCC_PERIPHCLK_ADC      ADC peripheral clock
137   *            @arg @ref RCC_PERIPHCLK_RTC      RTC peripheral clock
138   *            @arg @ref RCC_PERIPHCLK_RFWAKEUP RFWKP peripheral clock
139   *            @arg @ref RCC_PERIPHCLK_SMPS     SMPS peripheral clock
140   *
141   *
142   * @note   Care must be taken when @ref HAL_RCCEx_PeriphCLKConfig() is used to select
143   *         the RTC clock source: in this case the access to Backup domain is enabled.
144   *
145   * @retval HAL status
146   */
HAL_RCCEx_PeriphCLKConfig(RCC_PeriphCLKInitTypeDef * PeriphClkInit)147 HAL_StatusTypeDef HAL_RCCEx_PeriphCLKConfig(RCC_PeriphCLKInitTypeDef  *PeriphClkInit)
148 {
149   uint32_t tickstart;
150   HAL_StatusTypeDef ret     = HAL_OK;      /* Intermediate status */
151   HAL_StatusTypeDef status  = HAL_OK;   /* Final status */
152 
153   /* Check the parameters */
154   assert_param(IS_RCC_PERIPHCLOCK(PeriphClkInit->PeriphClockSelection));
155 
156 #if defined(SAI1)
157   /*-------------------------- SAI1 clock source configuration ---------------------*/
158   if ((((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_SAI1) == RCC_PERIPHCLK_SAI1))
159   {
160     /* Check the parameters */
161     assert_param(IS_RCC_SAI1CLK(PeriphClkInit->Sai1ClockSelection));
162 
163     switch (PeriphClkInit->Sai1ClockSelection)
164     {
165       case RCC_SAI1CLKSOURCE_PLL:      /* PLL is used as clock source for SAI1 */
166         /* Enable SAI1 Clock output generated form System PLL . */
167         __HAL_RCC_PLLCLKOUT_ENABLE(RCC_PLL_SAI1CLK);
168 
169         /* SAI1 clock source config set later after clock selection check */
170         break;
171 
172       case RCC_SAI1CLKSOURCE_PLLSAI1: /* PLLSAI1 is used as clock source for SAI1 */
173         /* PLLSAI1 parameters N & P configuration and clock output (PLLSAI1ClockOut) */
174         ret = RCCEx_PLLSAI1_ConfigNP(&(PeriphClkInit->PLLSAI1));
175         /* SAI1 clock source config set later after clock selection check */
176         break;
177 
178       case RCC_SAI1CLKSOURCE_PIN:      /* External clock is used as source of SAI1 clock*/
179         /* SAI1 clock source config set later after clock selection check */
180         break;
181 
182       case RCC_SAI1CLKSOURCE_HSI:
183 
184         break;
185 
186       default:
187         ret = HAL_ERROR;
188         break;
189     }
190 
191     if (ret == HAL_OK)
192     {
193       /* Set the source of SAI1 clock*/
194       __HAL_RCC_SAI1_CONFIG(PeriphClkInit->Sai1ClockSelection);
195     }
196     else
197     {
198       /* set overall return value */
199       status = ret;
200     }
201   }
202 #endif /* SAI1 */
203 
204   /*-------------------------- RTC clock source configuration ----------------------*/
205   if ((PeriphClkInit->PeriphClockSelection & RCC_PERIPHCLK_RTC) == RCC_PERIPHCLK_RTC)
206   {
207     uint32_t rtcclocksource = LL_RCC_GetRTCClockSource();
208 
209     /* Check for RTC Parameters used to output RTCCLK */
210     assert_param(IS_RCC_RTCCLKSOURCE(PeriphClkInit->RTCClockSelection));
211 
212     /* Configure the clock source only if a different source is expected */
213     if (rtcclocksource != PeriphClkInit->RTCClockSelection)
214     {
215       /* Enable write access to Backup domain */
216       HAL_PWR_EnableBkUpAccess();
217 
218       /* If a clock source is not yet selected */
219       if (rtcclocksource == RCC_RTCCLKSOURCE_NONE)
220       {
221         /* Directly set the configuration of the clock source selection */
222         LL_RCC_SetRTCClockSource(PeriphClkInit->RTCClockSelection);
223       }
224       else /* A clock source is already selected */
225       {
226         /* Store the content of BDCR register before the reset of Backup Domain */
227         uint32_t bdcr = LL_RCC_ReadReg(BDCR);
228 
229         /* RTC Clock selection can be changed only if the Backup Domain is reset */
230         LL_RCC_ForceBackupDomainReset();
231         LL_RCC_ReleaseBackupDomainReset();
232 
233         /* Set the value of the clock source selection */
234         MODIFY_REG(bdcr, RCC_BDCR_RTCSEL, PeriphClkInit->RTCClockSelection);
235 
236         /* Restore the content of BDCR register */
237         LL_RCC_WriteReg(BDCR, bdcr);
238 
239         /* Wait for LSE reactivation if LSE was enable prior to Backup Domain reset */
240         if (LL_RCC_LSE_IsEnabled() == 1U)
241         {
242           /* Get Start Tick*/
243           tickstart = HAL_GetTick();
244 
245           /* Wait till LSE is ready */
246           while (LL_RCC_LSE_IsReady() != 1U)
247           {
248             if ((HAL_GetTick() - tickstart) > RCC_LSE_TIMEOUT_VALUE)
249             {
250               ret = HAL_TIMEOUT;
251               break;
252             }
253           }
254         }
255       }
256 
257       /* set overall return value */
258       status = ret;
259     }
260     else
261     {
262       /* set overall return value */
263       status = ret;
264     }
265 
266   }
267 
268   /*-------------------------- USART1 clock source configuration -------------------*/
269   if (((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_USART1) == RCC_PERIPHCLK_USART1)
270   {
271     /* Check the parameters */
272     assert_param(IS_RCC_USART1CLKSOURCE(PeriphClkInit->Usart1ClockSelection));
273 
274     /* Configure the USART1 clock source */
275     __HAL_RCC_USART1_CONFIG(PeriphClkInit->Usart1ClockSelection);
276   }
277 
278 #if defined(LPUART1)
279   /*-------------------------- LPUART1 clock source configuration ------------------*/
280   if (((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_LPUART1) == RCC_PERIPHCLK_LPUART1)
281   {
282     /* Check the parameters */
283     assert_param(IS_RCC_LPUART1CLKSOURCE(PeriphClkInit->Lpuart1ClockSelection));
284 
285     /* Configure the LPUAR1 clock source */
286     __HAL_RCC_LPUART1_CONFIG(PeriphClkInit->Lpuart1ClockSelection);
287   }
288 #endif /* LPUART1 */
289 
290   /*-------------------------- LPTIM1 clock source configuration -------------------*/
291   if (((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_LPTIM1) == (RCC_PERIPHCLK_LPTIM1))
292   {
293     assert_param(IS_RCC_LPTIM1CLK(PeriphClkInit->Lptim1ClockSelection));
294     __HAL_RCC_LPTIM1_CONFIG(PeriphClkInit->Lptim1ClockSelection);
295   }
296 
297   /*-------------------------- LPTIM2 clock source configuration -------------------*/
298   if (((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_LPTIM2) == (RCC_PERIPHCLK_LPTIM2))
299   {
300     assert_param(IS_RCC_LPTIM2CLK(PeriphClkInit->Lptim2ClockSelection));
301     __HAL_RCC_LPTIM2_CONFIG(PeriphClkInit->Lptim2ClockSelection);
302   }
303 
304   /*-------------------------- I2C1 clock source configuration ---------------------*/
305   if (((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_I2C1) == RCC_PERIPHCLK_I2C1)
306   {
307     /* Check the parameters */
308     assert_param(IS_RCC_I2C1CLKSOURCE(PeriphClkInit->I2c1ClockSelection));
309 
310     /* Configure the I2C1 clock source */
311     __HAL_RCC_I2C1_CONFIG(PeriphClkInit->I2c1ClockSelection);
312   }
313 
314 #if defined(I2C3)
315   /*-------------------------- I2C3 clock source configuration ---------------------*/
316   if (((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_I2C3) == RCC_PERIPHCLK_I2C3)
317   {
318     /* Check the parameters */
319     assert_param(IS_RCC_I2C3CLKSOURCE(PeriphClkInit->I2c3ClockSelection));
320 
321     /* Configure the I2C3 clock source */
322     __HAL_RCC_I2C3_CONFIG(PeriphClkInit->I2c3ClockSelection);
323   }
324 #endif /* I2C3 */
325 
326 #if defined(USB)
327   /*-------------------------- USB clock source configuration ----------------------*/
328   if (((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_USB) == (RCC_PERIPHCLK_USB))
329   {
330     assert_param(IS_RCC_USBCLKSOURCE(PeriphClkInit->UsbClockSelection));
331     __HAL_RCC_USB_CONFIG(PeriphClkInit->UsbClockSelection);
332 
333     if (PeriphClkInit->UsbClockSelection == RCC_USBCLKSOURCE_PLL)
334     {
335       /* Enable PLLQ output */
336       __HAL_RCC_PLLCLKOUT_ENABLE(RCC_PLL_USBCLK);
337     }
338 #if defined(SAI1)
339     if (PeriphClkInit->UsbClockSelection == RCC_USBCLKSOURCE_PLLSAI1)
340     {
341       /* PLLSAI1 parameters N & Q configuration and clock output (PLLSAI1ClockOut) */
342       ret = RCCEx_PLLSAI1_ConfigNQ(&(PeriphClkInit->PLLSAI1));
343 
344       if (ret != HAL_OK)
345       {
346         /* set overall return value */
347         status = ret;
348       }
349     }
350 #endif /* SAI1 */
351   }
352 #endif /* USB */
353 
354   /*-------------------------- RNG clock source configuration ----------------------*/
355   if (((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_RNG) == (RCC_PERIPHCLK_RNG))
356   {
357     /* Check the parameters */
358     assert_param(IS_RCC_RNGCLKSOURCE(PeriphClkInit->RngClockSelection));
359 
360     /* Configure the RNG clock source */
361     __HAL_RCC_RNG_CONFIG(PeriphClkInit->RngClockSelection);
362 
363     if (PeriphClkInit->RngClockSelection == RCC_RNGCLKSOURCE_PLL)
364     {
365       /* Enable PLLQ output */
366       __HAL_RCC_PLLCLKOUT_ENABLE(RCC_PLL_RNGCLK);
367     }
368   }
369 
370   /*-------------------------- ADC clock source configuration ----------------------*/
371   if (((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_ADC) == RCC_PERIPHCLK_ADC)
372   {
373     /* Check the parameters */
374     assert_param(IS_RCC_ADCCLKSOURCE(PeriphClkInit->AdcClockSelection));
375 
376     /* Configure the ADC interface clock source */
377     __HAL_RCC_ADC_CONFIG(PeriphClkInit->AdcClockSelection);
378 
379     if (PeriphClkInit->AdcClockSelection == RCC_ADCCLKSOURCE_PLL)
380     {
381       /* Enable RCC_PLL_RNGCLK output */
382       __HAL_RCC_PLLCLKOUT_ENABLE(RCC_PLL_ADCCLK);
383     }
384 
385 #if defined(SAI1)
386     if (PeriphClkInit->AdcClockSelection == RCC_ADCCLKSOURCE_PLLSAI1)
387     {
388       /* PLLSAI1 parameters N & R configuration and clock output (PLLSAI1ClockOut) */
389       ret = RCCEx_PLLSAI1_ConfigNR(&(PeriphClkInit->PLLSAI1));
390 
391       if (ret != HAL_OK)
392       {
393         /* set overall return value */
394         status = ret;
395       }
396     }
397 #endif /* SAI1 */
398   }
399 
400   /*-------------------------- RFWKP clock source configuration ----------------------*/
401   if (((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_RFWAKEUP) == RCC_PERIPHCLK_RFWAKEUP)
402   {
403     /* Check the parameters */
404     assert_param(IS_RCC_RFWKPCLKSOURCE(PeriphClkInit->RFWakeUpClockSelection));
405 
406     /* Configure the RFWKP interface clock source */
407     __HAL_RCC_RFWAKEUP_CONFIG(PeriphClkInit->RFWakeUpClockSelection);
408 
409   }
410 
411 #if defined(RCC_SMPS_SUPPORT)
412   /*-------------------------- SMPS clock source configuration ----------------------*/
413   if (((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_SMPS) == RCC_PERIPHCLK_SMPS)
414   {
415     /* Check the parameters */
416     assert_param(IS_RCC_SMPSCLKDIV(PeriphClkInit->SmpsDivSelection));
417     assert_param(IS_RCC_SMPSCLKSOURCE(PeriphClkInit->SmpsClockSelection));
418 
419     /* Configure the SMPS interface clock division factor */
420     __HAL_RCC_SMPS_DIV_CONFIG(PeriphClkInit->SmpsDivSelection);
421 
422     /* Configure the SMPS interface clock source */
423     __HAL_RCC_SMPS_CONFIG(PeriphClkInit->SmpsClockSelection);
424   }
425 #endif /* RCC_SMPS_SUPPORT */
426 
427   return status;
428 }
429 
430 
431 /**
432   * @brief  Get the RCC_ClkInitStruct according to the internal RCC configuration registers.
433   * @param  PeriphClkInit  pointer to an RCC_PeriphCLKInitTypeDef structure that
434   *         returns the configuration information for the Extended Peripherals
435   *         clocks(SAI1, LPTIM1, LPTIM2, I2C1, I2C3, LPUART1,
436   *         USART1, RTC, ADCx, USB, RNG, RFWKP, SMPS).
437   * @retval None
438   */
HAL_RCCEx_GetPeriphCLKConfig(RCC_PeriphCLKInitTypeDef * PeriphClkInit)439 void HAL_RCCEx_GetPeriphCLKConfig(RCC_PeriphCLKInitTypeDef  *PeriphClkInit)
440 {
441   /* Set all possible values for the extended clock type parameter------------*/
442 
443   PeriphClkInit->PeriphClockSelection = RCC_PERIPHCLK_USART1 | RCC_PERIPHCLK_I2C1   | \
444                                         RCC_PERIPHCLK_LPTIM1 | RCC_PERIPHCLK_LPTIM2 | \
445                                         RCC_PERIPHCLK_RNG    | RCC_PERIPHCLK_ADC    | \
446                                         RCC_PERIPHCLK_RTC    | RCC_PERIPHCLK_RFWAKEUP;
447 #if defined(LPUART1)
448   PeriphClkInit->PeriphClockSelection |= RCC_PERIPHCLK_LPUART1;
449 #endif /* LPUART1 */
450 
451 #if defined(I2C3)
452   PeriphClkInit->PeriphClockSelection |= RCC_PERIPHCLK_I2C3;
453 #endif /* I2C3 */
454 
455 #if defined(SAI1)
456   PeriphClkInit->PeriphClockSelection |= RCC_PERIPHCLK_SAI1;
457 #endif /* SAI1 */
458 
459 #if defined(USB)
460   PeriphClkInit->PeriphClockSelection |= RCC_PERIPHCLK_USB;
461 #endif /* USB */
462 
463 #if defined(RCC_SMPS_SUPPORT)
464   PeriphClkInit->PeriphClockSelection |= RCC_PERIPHCLK_SMPS;
465 #endif /* RCC_SMPS_SUPPORT */
466 
467 
468 #if defined(SAI1)
469   /* Get the PLLSAI1 Clock configuration -----------------------------------------------*/
470   PeriphClkInit->PLLSAI1.PLLN = LL_RCC_PLLSAI1_GetN();
471   PeriphClkInit->PLLSAI1.PLLP = LL_RCC_PLLSAI1_GetP();
472   PeriphClkInit->PLLSAI1.PLLR = LL_RCC_PLLSAI1_GetR();
473   PeriphClkInit->PLLSAI1.PLLQ = LL_RCC_PLLSAI1_GetQ();
474 #endif /* SAI1 */
475 
476   /* Get the USART1 clock source ---------------------------------------------*/
477   PeriphClkInit->Usart1ClockSelection   = __HAL_RCC_GET_USART1_SOURCE();
478 
479 #if defined(LPUART1)
480   /* Get the LPUART1 clock source --------------------------------------------*/
481   PeriphClkInit->Lpuart1ClockSelection  = __HAL_RCC_GET_LPUART1_SOURCE();
482 #endif /* LPUART1 */
483 
484   /* Get the I2C1 clock source -----------------------------------------------*/
485   PeriphClkInit->I2c1ClockSelection     = __HAL_RCC_GET_I2C1_SOURCE();
486 
487 #if defined(I2C3)
488   /* Get the I2C3 clock source -----------------------------------------------*/
489   PeriphClkInit->I2c3ClockSelection     = __HAL_RCC_GET_I2C3_SOURCE();
490 #endif /* I2C3 */
491 
492   /* Get the LPTIM1 clock source ---------------------------------------------*/
493   PeriphClkInit->Lptim1ClockSelection   = __HAL_RCC_GET_LPTIM1_SOURCE();
494 
495   /* Get the LPTIM2 clock source ---------------------------------------------*/
496   PeriphClkInit->Lptim2ClockSelection   = __HAL_RCC_GET_LPTIM2_SOURCE();
497 
498 #if defined(SAI1)
499   /* Get the SAI1 clock source -----------------------------------------------*/
500   PeriphClkInit->Sai1ClockSelection     = __HAL_RCC_GET_SAI1_SOURCE();
501 #endif /* SAI1 */
502 
503   /* Get the RTC clock source ------------------------------------------------*/
504   PeriphClkInit->RTCClockSelection      = __HAL_RCC_GET_RTC_SOURCE();
505 
506 #if defined(USB)
507   /* Get the USB clock source ------------------------------------------------*/
508   PeriphClkInit->UsbClockSelection      = __HAL_RCC_GET_USB_SOURCE();
509 #endif /* USB */
510 
511   /* Get the RNG clock source ------------------------------------------------*/
512   PeriphClkInit->RngClockSelection      = HAL_RCCEx_GetRngCLKSource();
513 
514   /* Get the ADC clock source ------------------------------------------------*/
515   PeriphClkInit->AdcClockSelection      = __HAL_RCC_GET_ADC_SOURCE();
516 
517   /* Get the RFWKP clock source ----------------------------------------------*/
518   PeriphClkInit->RFWakeUpClockSelection = __HAL_RCC_GET_RFWAKEUP_SOURCE();
519 
520 #if defined(RCC_SMPS_SUPPORT)
521   /* Get the SMPS clock division factor --------------------------------------*/
522   PeriphClkInit->SmpsDivSelection       = __HAL_RCC_GET_SMPS_DIV();
523 
524   /* Get the SMPS clock source -----------------------------------------------*/
525   PeriphClkInit->SmpsClockSelection     = __HAL_RCC_GET_SMPS_SOURCE();
526 #endif /* RCC_SMPS_SUPPORT */
527 
528 }
529 
530 /**
531   * @brief  Return the peripheral clock frequency for peripherals with clock source
532   * @note   Return 0 if peripheral clock identifier not managed by this API
533   * @param  PeriphClk  Peripheral clock identifier
534   *         This parameter can be one of the following values:
535   *            @arg @ref RCC_PERIPHCLK_RTC  RTC peripheral clock
536   *            @arg @ref RCC_PERIPHCLK_ADC  ADC peripheral clock
537   *            @arg @ref RCC_PERIPHCLK_I2C1  I2C1 peripheral clock
538   *            @arg @ref RCC_PERIPHCLK_I2C3  I2C3 peripheral clock
539   *            @arg @ref RCC_PERIPHCLK_LPTIM1  LPTIM1 peripheral clock
540   *            @arg @ref RCC_PERIPHCLK_LPTIM2  LPTIM2 peripheral clock
541   *            @arg @ref RCC_PERIPHCLK_LPUART1  LPUART1 peripheral clock
542   *            @arg @ref RCC_PERIPHCLK_RNG  RNG peripheral clock
543   *            @arg @ref RCC_PERIPHCLK_SAI1  SAI1 peripheral clock
544   *            @arg @ref RCC_PERIPHCLK_USART1  USART1 peripheral clock
545   *            @arg @ref RCC_PERIPHCLK_USB  USB peripheral clock
546   *            @arg @ref RCC_PERIPHCLK_RFWAKEUP  RFWKP peripheral clock
547   *            @arg @ref RCC_PERIPHCLK_SMPS  SMPS peripheral clock
548   * @retval Frequency in Hz
549   */
HAL_RCCEx_GetPeriphCLKFreq(uint32_t PeriphClk)550 uint32_t HAL_RCCEx_GetPeriphCLKFreq(uint32_t PeriphClk)
551 {
552   uint32_t frequency = 0U;
553 
554 #if defined(RCC_SMPS_SUPPORT)
555   uint32_t smps_prescaler_index = ((LL_RCC_GetSMPSPrescaler()) >> RCC_SMPSCR_SMPSDIV_Pos);
556 #endif /* RCC_SMPS_SUPPORT */
557 
558   /* Check the parameters */
559   assert_param(IS_RCC_PERIPHCLOCK(PeriphClk));
560 
561   if (PeriphClk == RCC_PERIPHCLK_RTC)
562   {
563     uint32_t rtcClockSource = LL_RCC_GetRTCClockSource();
564 
565     if (rtcClockSource == LL_RCC_RTC_CLKSOURCE_LSE) /* LSE clock used as RTC clock source */
566     {
567       if (LL_RCC_LSE_IsReady() == 1U)
568       {
569         frequency = LSE_VALUE;
570       }
571       else
572       {
573         /* Nothing to do as frequency already initialized to 0U */
574       }
575     }
576     else if (rtcClockSource == LL_RCC_RTC_CLKSOURCE_LSI) /* LSI clock used as RTC clock source */
577     {
578       const uint32_t temp_lsi1ready = LL_RCC_LSI1_IsReady();
579       const uint32_t temp_lsi2ready = LL_RCC_LSI2_IsReady();
580       if ((temp_lsi1ready == 1U) || (temp_lsi2ready == 1U))
581       {
582         frequency = LSI_VALUE;
583       }
584       else
585       {
586         /* Nothing to do as frequency already initialized to 0U */
587       }
588     }
589     else if (rtcClockSource == LL_RCC_RTC_CLKSOURCE_HSE_DIV32) /* HSE clock used as RTC clock source */
590     {
591       frequency = HSE_VALUE / 32U;
592     }
593     else /* No clock used as RTC clock source */
594     {
595       /* Nothing to do as frequency already initialized to 0U */
596     }
597   }
598 #if defined(SAI1)
599   else if (PeriphClk == RCC_PERIPHCLK_SAI1)
600   {
601     switch (LL_RCC_GetSAIClockSource(LL_RCC_SAI1_CLKSOURCE))
602     {
603       case LL_RCC_SAI1_CLKSOURCE_HSI:        /* HSI clock used as SAI1 clock source */
604         if (LL_RCC_HSI_IsReady() == 1U)
605         {
606           frequency = HSI_VALUE;
607         }
608         else
609         {
610           /* Nothing to do as frequency already initialized to 0U */
611         }
612         break;
613 
614       case LL_RCC_SAI1_CLKSOURCE_PLLSAI1:    /* PLLSAI1 clock used as SAI1 clock source */
615         if (LL_RCC_PLLSAI1_IsReady() == 1U)
616         {
617           frequency = RCC_PLLSAI1_GetFreqDomain_P();
618         }
619         else
620         {
621           /* Nothing to do as frequency already initialized to 0U */
622         }
623         break;
624 
625       case LL_RCC_SAI1_CLKSOURCE_PLL:        /* PLL clock used as SAI1 clock source */
626         if (LL_RCC_PLL_IsReady() == 1U)
627         {
628           frequency = RCC_PLL_GetFreqDomain_P();
629         }
630         else
631         {
632           /* Nothing to do as frequency already initialized to 0U */
633         }
634         break;
635 
636       default: /* External input clock used as SAI1 clock source */
637         frequency = EXTERNAL_SAI1_CLOCK_VALUE;
638         break;
639     }
640   }
641 #endif /* SAI1 */
642   else if (PeriphClk == RCC_PERIPHCLK_RNG)
643   {
644     uint32_t rngClockSource = HAL_RCCEx_GetRngCLKSource();
645 
646     if (rngClockSource == RCC_RNGCLKSOURCE_LSI)             /* LSI clock used as RNG clock source */
647     {
648       const uint32_t temp_lsi1ready = LL_RCC_LSI1_IsReady();
649       const uint32_t temp_lsi2ready = LL_RCC_LSI2_IsReady();
650       if ((temp_lsi1ready == 1U) || (temp_lsi2ready == 1U))
651       {
652         frequency = LSI_VALUE;
653       }
654       else
655       {
656         /* Nothing to do as frequency already initialized to 0U */
657       }
658     }
659     else if (rngClockSource == RCC_RNGCLKSOURCE_LSE)        /* LSE clock used as RNG clock source */
660     {
661       if (LL_RCC_LSE_IsReady() == 1U)
662       {
663         frequency = LSE_VALUE;
664       }
665       else
666       {
667         /* Nothing to do as frequency already initialized to 0U */
668       }
669     }
670     else if (rngClockSource == RCC_RNGCLKSOURCE_PLL)        /* PLL clock divided by 3 used as RNG clock source */
671     {
672       if (LL_RCC_PLL_IsReady() == 1U)
673       {
674         frequency = (RCC_PLL_GetFreqDomain_Q() / 3U);
675       }
676       else
677       {
678         /* Nothing to do as frequency already initialized to 0U */
679       }
680     }
681     else if (rngClockSource == RCC_RNGCLKSOURCE_MSI)        /* MSI clock divided by 3 used as RNG clock source */
682     {
683       if (LL_RCC_MSI_IsReady() == 1U)
684       {
685         frequency = (__LL_RCC_CALC_MSI_FREQ(LL_RCC_MSI_GetRange()) / 3U);
686       }
687       else
688       {
689         /* Nothing to do as frequency already initialized to 0U */
690       }
691     }
692 #if defined(SAI1)
693     else if (rngClockSource == RCC_RNGCLKSOURCE_PLLSAI1)    /* PLLSAI1 clock used as SAI1 clock source */
694     {
695       if (LL_RCC_PLLSAI1_IsReady() == 1U)
696       {
697         frequency = RCC_PLLSAI1_GetFreqDomain_Q();
698       }
699       else
700       {
701         /* Nothing to do as frequency already initialized to 0U */
702       }
703     }
704 #endif /* SAI1 */
705     else                                                    /* HSI48 clock divided by 3 used as RNG clock source */
706     {
707 #if defined(RCC_HSI48_SUPPORT)
708       if (LL_RCC_HSI48_IsReady() == 1U)
709       {
710         frequency = HSI48_VALUE / 3U;
711       }
712       else
713       {
714         /* Nothing to do as frequency already initialized to 0U */
715       }
716 #else
717       /* Nothing to do as frequency already initialized to 0U */
718 #endif /* RCC_HSI48_SUPPORT */
719     }
720   }
721 #if defined(USB)
722   else if (PeriphClk == RCC_PERIPHCLK_USB)
723   {
724     switch (LL_RCC_GetUSBClockSource(LL_RCC_USB_CLKSOURCE))
725     {
726 #if defined(SAI1)
727       case LL_RCC_USB_CLKSOURCE_PLLSAI1:       /* PLLSAI1 clock used as USB clock source */
728         if (LL_RCC_PLLSAI1_IsReady() == 1U)
729         {
730           frequency = RCC_PLLSAI1_GetFreqDomain_Q();
731         }
732         else
733         {
734           /* Nothing to do as frequency already initialized to 0U */
735         }
736         break;
737 #endif /* SAI1 */
738 
739       case LL_RCC_USB_CLKSOURCE_PLL:           /* PLL clock used as USB clock source */
740         if (LL_RCC_PLL_IsReady() == 1U)
741         {
742           frequency = RCC_PLL_GetFreqDomain_Q();
743         }
744         else
745         {
746           /* Nothing to do as frequency already initialized to 0U */
747         }
748         break;
749 
750       case LL_RCC_USB_CLKSOURCE_MSI:           /* MSI clock used as USB clock source */
751         if (LL_RCC_MSI_IsReady() == 1U)
752         {
753           frequency = __LL_RCC_CALC_MSI_FREQ(LL_RCC_MSI_GetRange());
754         }
755         else
756         {
757           /* Nothing to do as frequency already initialized to 0U */
758         }
759         break;
760 
761       default: /* HSI48 clock used as USB clock source */
762         if (LL_RCC_HSI48_IsReady() == 1U)
763         {
764           frequency = HSI48_VALUE;
765         }
766         else
767         {
768           /* Nothing to do as frequency already initialized to 0U */
769         }
770         break;
771     }
772   }
773 #endif /* USB */
774   else if (PeriphClk == RCC_PERIPHCLK_USART1)
775   {
776     switch (LL_RCC_GetUSARTClockSource(LL_RCC_USART1_CLKSOURCE))
777     {
778       case LL_RCC_USART1_CLKSOURCE_SYSCLK: /* USART1 Clock is System Clock */
779         frequency = HAL_RCC_GetSysClockFreq();
780         break;
781 
782       case LL_RCC_USART1_CLKSOURCE_HSI:    /* USART1 Clock is HSI Osc. */
783         if (LL_RCC_HSI_IsReady() == 1U)
784         {
785           frequency = HSI_VALUE;
786         }
787         else
788         {
789           /* Nothing to do as frequency already initialized to 0U */
790         }
791         break;
792 
793       case LL_RCC_USART1_CLKSOURCE_LSE:    /* USART1 Clock is LSE Osc. */
794         if (LL_RCC_LSE_IsReady() == 1U)
795         {
796           frequency = LSE_VALUE;
797         }
798         else
799         {
800           /* Nothing to do as frequency already initialized to 0U */
801         }
802         break;
803 
804       default: /* USART1 Clock is PCLK2 */
805         frequency = __LL_RCC_CALC_PCLK2_FREQ(__LL_RCC_CALC_HCLK1_FREQ(HAL_RCC_GetSysClockFreq(),
806                                                                       LL_RCC_GetAHBPrescaler()),
807                                              LL_RCC_GetAPB2Prescaler());
808         break;
809     }
810   }
811 #if defined(LPUART1)
812   else if (PeriphClk == RCC_PERIPHCLK_LPUART1)
813   {
814     switch (LL_RCC_GetLPUARTClockSource(LL_RCC_LPUART1_CLKSOURCE))
815     {
816       case LL_RCC_LPUART1_CLKSOURCE_SYSCLK: /* LPUART1 Clock is System Clock */
817         frequency = HAL_RCC_GetSysClockFreq();
818         break;
819 
820       case LL_RCC_LPUART1_CLKSOURCE_HSI:    /* LPUART1 Clock is HSI Osc. */
821         if (LL_RCC_HSI_IsReady() == 1U)
822         {
823           frequency = HSI_VALUE;
824         }
825         else
826         {
827           /* Nothing to do as frequency already initialized to 0U */
828         }
829         break;
830 
831       case LL_RCC_LPUART1_CLKSOURCE_LSE:    /* LPUART1 Clock is LSE Osc. */
832         if (LL_RCC_LSE_IsReady() == 1U)
833         {
834           frequency = LSE_VALUE;
835         }
836         else
837         {
838           /* Nothing to do as frequency already initialized to 0U */
839         }
840         break;
841 
842       default: /* LPUART1 Clock is PCLK1 */
843         frequency = __LL_RCC_CALC_PCLK1_FREQ(__LL_RCC_CALC_HCLK1_FREQ(HAL_RCC_GetSysClockFreq(),
844                                                                       LL_RCC_GetAHBPrescaler()),
845                                              LL_RCC_GetAPB1Prescaler());
846         break;
847     }
848   }
849 #endif /* LPUART1 */
850   else if (PeriphClk == RCC_PERIPHCLK_ADC)
851   {
852     switch (LL_RCC_GetADCClockSource(LL_RCC_ADC_CLKSOURCE))
853     {
854 #if defined(STM32WB55xx) || defined (STM32WB5Mxx) || defined(STM32WB35xx)
855       case LL_RCC_ADC_CLKSOURCE_PLLSAI1:       /* PLLSAI1 clock used as ADC clock source */
856         if (LL_RCC_PLLSAI1_IsReady() == 1U)
857         {
858           frequency = RCC_PLLSAI1_GetFreqDomain_R();
859         }
860         else
861         {
862           /* Nothing to do as frequency already initialized to 0U */
863         }
864         break;
865 #elif defined(STM32WB15xx) || defined(STM32WB1Mxx)
866       case LL_RCC_ADC_CLKSOURCE_HSI:           /* HSI clock used as ADC clock source */
867         if (LL_RCC_HSI_IsReady() == 1U)
868         {
869           frequency = HSI_VALUE;
870         }
871         else
872         {
873           /* Nothing to do as frequency already initialized to 0U */
874         }
875         break;
876 #endif /* STM32WB55xx || STM32WB5Mxx || STM32WB35xx */
877       case LL_RCC_ADC_CLKSOURCE_SYSCLK:        /* SYSCLK clock used as ADC clock source */
878         frequency = HAL_RCC_GetSysClockFreq();
879         break;
880       case LL_RCC_ADC_CLKSOURCE_PLL:           /* PLL clock used as ADC clock source */
881         if (LL_RCC_PLL_IsReady() == 1U)
882         {
883           frequency = RCC_PLL_GetFreqDomain_P();
884         }
885         else
886         {
887           /* Nothing to do as frequency already initialized to 0U */
888         }
889         break;
890 
891       default: /* No clock used as ADC clock source */
892         break;
893     }
894   }
895   else if (PeriphClk == RCC_PERIPHCLK_I2C1)
896   {
897     switch (LL_RCC_GetI2CClockSource(LL_RCC_I2C1_CLKSOURCE))
898     {
899       case LL_RCC_I2C1_CLKSOURCE_SYSCLK: /* I2C1 Clock is System Clock */
900         frequency = HAL_RCC_GetSysClockFreq();
901         break;
902 
903       case LL_RCC_I2C1_CLKSOURCE_HSI:    /* I2C1 Clock is HSI Osc. */
904         if (LL_RCC_HSI_IsReady() == 1U)
905         {
906           frequency = HSI_VALUE;
907         }
908         else
909         {
910           /* Nothing to do as frequency already initialized to 0U */
911         }
912         break;
913 
914       default: /* I2C1 Clock is PCLK1 */
915         frequency = __LL_RCC_CALC_PCLK1_FREQ(__LL_RCC_CALC_HCLK1_FREQ(HAL_RCC_GetSysClockFreq(),
916                                                                       LL_RCC_GetAHBPrescaler()),
917                                              LL_RCC_GetAPB1Prescaler());
918         break;
919     }
920   }
921 #if defined(I2C3)
922   else if (PeriphClk == RCC_PERIPHCLK_I2C3)
923   {
924     switch (LL_RCC_GetI2CClockSource(LL_RCC_I2C3_CLKSOURCE))
925     {
926       case LL_RCC_I2C3_CLKSOURCE_SYSCLK: /* I2C3 Clock is System Clock */
927         frequency = HAL_RCC_GetSysClockFreq();
928         break;
929 
930       case LL_RCC_I2C3_CLKSOURCE_HSI: /* I2C3 Clock is HSI Osc. */
931         if (LL_RCC_HSI_IsReady() == 1U)
932         {
933           frequency = HSI_VALUE;
934         }
935         else
936         {
937           /* Nothing to do as frequency already initialized to 0U */
938         }
939         break;
940 
941       default: /* I2C3 Clock is PCLK1 */
942         frequency = __LL_RCC_CALC_PCLK1_FREQ(__LL_RCC_CALC_HCLK1_FREQ(HAL_RCC_GetSysClockFreq(),
943                                                                       LL_RCC_GetAHBPrescaler()),
944                                              LL_RCC_GetAPB1Prescaler());
945         break;
946     }
947   }
948 #endif /* I2C3 */
949   else if (PeriphClk == RCC_PERIPHCLK_LPTIM1)
950   {
951     uint32_t lptimClockSource = LL_RCC_GetLPTIMClockSource(LL_RCC_LPTIM1_CLKSOURCE);
952 
953     if (lptimClockSource == LL_RCC_LPTIM1_CLKSOURCE_LSI) /* LPTIM1 Clock is LSI Osc. */
954     {
955       const uint32_t temp_lsi1ready = LL_RCC_LSI1_IsReady();
956       const uint32_t temp_lsi2ready = LL_RCC_LSI2_IsReady();
957       if ((temp_lsi1ready == 1U) || (temp_lsi2ready == 1U))
958       {
959         frequency = LSI_VALUE;
960       }
961       else
962       {
963         /* Nothing to do as frequency already initialized to 0U */
964       }
965     }
966     else if (lptimClockSource == LL_RCC_LPTIM1_CLKSOURCE_HSI) /* LPTIM1 Clock is HSI Osc. */
967     {
968       if (LL_RCC_HSI_IsReady() == 1U)
969       {
970         frequency = HSI_VALUE;
971       }
972       else
973       {
974         /* Nothing to do as frequency already initialized to 0U */
975       }
976     }
977     else if (lptimClockSource == LL_RCC_LPTIM1_CLKSOURCE_LSE) /* LPTIM1 Clock is LSE Osc. */
978     {
979       if (LL_RCC_LSE_IsReady() == 1U)
980       {
981         frequency = LSE_VALUE;
982       }
983       else
984       {
985         /* Nothing to do as frequency already initialized to 0U */
986       }
987     }
988     else /* LPTIM1 Clock is PCLK1 */
989     {
990       frequency = __LL_RCC_CALC_PCLK1_FREQ(__LL_RCC_CALC_HCLK1_FREQ(HAL_RCC_GetSysClockFreq(),
991                                                                     LL_RCC_GetAHBPrescaler()),
992                                            LL_RCC_GetAPB1Prescaler());
993     }
994   }
995   else if (PeriphClk == RCC_PERIPHCLK_LPTIM2)
996   {
997     uint32_t lptimClockSource = LL_RCC_GetLPTIMClockSource(LL_RCC_LPTIM2_CLKSOURCE);
998 
999     if (lptimClockSource == LL_RCC_LPTIM2_CLKSOURCE_LSI) /* LPTIM2 Clock is LSI Osc. */
1000     {
1001       const uint32_t temp_lsi1ready = LL_RCC_LSI1_IsReady();
1002       const uint32_t temp_lsi2ready = LL_RCC_LSI2_IsReady();
1003       if ((temp_lsi1ready == 1U) || (temp_lsi2ready == 1U))
1004       {
1005         frequency = LSI_VALUE;
1006       }
1007       else
1008       {
1009         /* Nothing to do as frequency already initialized to 0U */
1010       }
1011     }
1012     else if (lptimClockSource == LL_RCC_LPTIM2_CLKSOURCE_HSI) /* LPTIM2 Clock is HSI Osc. */
1013     {
1014       if (LL_RCC_HSI_IsReady() == 1U)
1015       {
1016         frequency = HSI_VALUE;
1017       }
1018       else
1019       {
1020         /* Nothing to do as frequency already initialized to 0U */
1021       }
1022     }
1023     else if (lptimClockSource == LL_RCC_LPTIM2_CLKSOURCE_LSE) /* LPTIM2 Clock is LSE Osc. */
1024     {
1025       if (LL_RCC_LSE_IsReady() == 1U)
1026       {
1027         frequency = LSE_VALUE;
1028       }
1029       else
1030       {
1031         /* Nothing to do as frequency already initialized to 0U */
1032       }
1033     }
1034     else /* LPTIM2 Clock is PCLK1 */
1035     {
1036       frequency = __LL_RCC_CALC_PCLK1_FREQ(__LL_RCC_CALC_HCLK1_FREQ(HAL_RCC_GetSysClockFreq(),
1037                                                                     LL_RCC_GetAHBPrescaler()),
1038                                            LL_RCC_GetAPB1Prescaler());
1039     }
1040   }
1041   else if (PeriphClk == RCC_PERIPHCLK_RFWAKEUP)
1042   {
1043     uint32_t rfwkpClockSource = LL_RCC_GetRFWKPClockSource();
1044 
1045     if (rfwkpClockSource == LL_RCC_RFWKP_CLKSOURCE_LSE) /* LSE clock used as RF Wakeup clock source */
1046     {
1047       if (LL_RCC_LSE_IsReady() == 1U)
1048       {
1049         frequency = LSE_VALUE;
1050       }
1051       else
1052       {
1053         /* Nothing to do as frequency already initialized to 0U */
1054       }
1055     }
1056     else if (rfwkpClockSource == LL_RCC_RFWKP_CLKSOURCE_HSE_DIV1024) /* HSE clock used as RF Wakeup clock source */
1057     {
1058       frequency = HSE_VALUE / 1024U;
1059     }
1060     else /* No clock used as RF Wakeup clock source */
1061     {
1062       /* Nothing to do as frequency already initialized to 0U */
1063     }
1064   }
1065 #if defined(RCC_SMPS_SUPPORT)
1066   else if (PeriphClk == RCC_PERIPHCLK_SMPS)
1067   {
1068     uint32_t smpsClockSource = LL_RCC_GetSMPSClockSource();
1069 
1070     if (smpsClockSource == LL_RCC_SMPS_CLKSOURCE_STATUS_HSI) /* SMPS Clock source is HSI Osc. */
1071     {
1072       if (LL_RCC_HSI_IsReady() == 1U)
1073       {
1074         frequency = HSI_VALUE / SmpsPrescalerTable[smps_prescaler_index][0];
1075         frequency = frequency >> 1U; /* Systematic Div by 2 */
1076       }
1077       else
1078       {
1079         /* Nothing to do as frequency already initialized to 0U */
1080       }
1081     }
1082     else if (smpsClockSource == LL_RCC_SMPS_CLKSOURCE_STATUS_HSE) /* SMPS Clock source is HSE Osc. */
1083     {
1084       if (LL_RCC_HSE_IsReady() == 1U)
1085       {
1086         frequency = HSE_VALUE / SmpsPrescalerTable[smps_prescaler_index][5];
1087         frequency = frequency >> 1U; /* Systematic Div by 2 */
1088       }
1089       else
1090       {
1091         /* Nothing to do as frequency already initialized to 0U */
1092       }
1093     }
1094     else if (smpsClockSource == LL_RCC_SMPS_CLKSOURCE_STATUS_MSI) /* SMPS Clock source is MSI Osc. */
1095     {
1096       switch (LL_RCC_MSI_GetRange())
1097       {
1098         case LL_RCC_MSIRANGE_8:
1099           frequency = __LL_RCC_CALC_MSI_FREQ(LL_RCC_MSIRANGE_8) / SmpsPrescalerTable[smps_prescaler_index][4];
1100           break;
1101         case LL_RCC_MSIRANGE_9:
1102           frequency = __LL_RCC_CALC_MSI_FREQ(LL_RCC_MSIRANGE_9) / SmpsPrescalerTable[smps_prescaler_index][3];
1103           break;
1104         case LL_RCC_MSIRANGE_10:
1105           frequency = __LL_RCC_CALC_MSI_FREQ(LL_RCC_MSIRANGE_10) / SmpsPrescalerTable[smps_prescaler_index][2];
1106           break;
1107         case LL_RCC_MSIRANGE_11:
1108           frequency = __LL_RCC_CALC_MSI_FREQ(LL_RCC_MSIRANGE_11) / SmpsPrescalerTable[smps_prescaler_index][1];
1109           break;
1110         default:
1111           break;
1112       }
1113       frequency = frequency >> 1U; /* Systematic Div by 2 */
1114     }
1115     else /* SMPS has no Clock */
1116     {
1117       /* Nothing to do as frequency already initialized to 0U */
1118     }
1119   }
1120 #endif /* RCC_SMPS_SUPPORT */
1121 
1122   return (frequency);
1123 }
1124 
1125 /**
1126   * @brief  Return the RNG clock source
1127   * @retval The RNG clock source can be one of the following values:
1128   *            @arg @ref RCC_RNGCLKSOURCE_HSI48 HSI48 clock divided by 3 selected as RNG clock
1129   *            @arg @ref RCC_RNGCLKSOURCE_PLL      PLL "Q" clock divided by 3  selected as RNG clock
1130   *            @arg @ref RCC_RNGCLKSOURCE_MSI      MSI clock divided by 3 selected as RNG clock
1131   *            @arg @ref RCC_RNGCLKSOURCE_PLLSAI1  PLLSAI1 "Q" clock selected as RNG clock (*)
1132   *            @arg @ref RCC_RNGCLKSOURCE_LSI      LSI clock selected as RNG clock
1133   *            @arg @ref RCC_RNGCLKSOURCE_LSE      LSE clock selected as RNG clock
1134   *
1135   *         (*) Value not defined in all devices.
1136   *
1137   */
HAL_RCCEx_GetRngCLKSource(void)1138 uint32_t HAL_RCCEx_GetRngCLKSource(void)
1139 {
1140   uint32_t rng_clock_source = LL_RCC_GetRNGClockSource(LL_RCC_RNG_CLKSOURCE);
1141   uint32_t clk48_clock_source;
1142 
1143   /* RNG clock source originates from 48 MHz RC oscillator */
1144   if (rng_clock_source == RCC_RNGCLKSOURCE_CLK48)
1145   {
1146     clk48_clock_source = LL_RCC_GetCLK48ClockSource(LL_RCC_CLK48_CLKSOURCE);
1147     rng_clock_source = (CLK48_MASK | clk48_clock_source);
1148   }
1149 
1150   return rng_clock_source;
1151 }
1152 
1153 /**
1154   * @}
1155   */
1156 
1157 /** @defgroup RCCEx_Exported_Functions_Group2 Extended Clock management functions
1158   * @brief  Extended Clock management functions
1159   *
1160 @verbatim
1161  ===============================================================================
1162                 ##### Extended clock management functions  #####
1163  ===============================================================================
1164     [..]
1165     This subsection provides a set of functions allowing to control the
1166     activation or deactivation of MSI PLL-mode, PLLSAI1, PLLSAI12, LSE CSS,
1167     Low speed clock output and clock after wake-up from STOP mode.
1168 @endverbatim
1169   * @{
1170   */
1171 
1172 #if defined(SAI1)
1173 /**
1174   * @brief  Enable PLLSAI1.
1175   * @param  PLLSAI1Init  pointer to an RCC_PLLSAI1InitTypeDef structure that
1176   *         contains the configuration information for the PLLSAI1
1177   * @retval HAL status
1178   */
HAL_RCCEx_EnablePLLSAI1(RCC_PLLSAI1InitTypeDef * PLLSAI1Init)1179 HAL_StatusTypeDef HAL_RCCEx_EnablePLLSAI1(RCC_PLLSAI1InitTypeDef  *PLLSAI1Init)
1180 {
1181   uint32_t tickstart;
1182   HAL_StatusTypeDef status = HAL_OK;
1183 
1184   /* check for PLLSAI1 Parameters used to output PLLSAI1CLK */
1185   assert_param(IS_RCC_PLLN_VALUE(PLLSAI1Init->PLLN));
1186   assert_param(IS_RCC_PLLP_VALUE(PLLSAI1Init->PLLP));
1187   assert_param(IS_RCC_PLLQ_VALUE(PLLSAI1Init->PLLQ));
1188   assert_param(IS_RCC_PLLR_VALUE(PLLSAI1Init->PLLR));
1189   assert_param(IS_RCC_PLLSAI1CLOCKOUT_VALUE(PLLSAI1Init->PLLSAI1ClockOut));
1190 
1191   /* Disable the PLLSAI1 */
1192   __HAL_RCC_PLLSAI1_DISABLE();
1193 
1194   /* Get Start Tick*/
1195   tickstart = HAL_GetTick();
1196 
1197   /* Wait till PLLSAI1 is ready to be updated */
1198   while (LL_RCC_PLLSAI1_IsReady() != 0U)
1199   {
1200     if ((HAL_GetTick() - tickstart) > PLLSAI1_TIMEOUT_VALUE)
1201     {
1202       status = HAL_TIMEOUT;
1203       break;
1204     }
1205   }
1206 
1207   if (status == HAL_OK)
1208   {
1209     /* Configure the PLLSAI1 Multiplication factor N */
1210     /* Configure the PLLSAI1 Division factors P, Q and R */
1211     __HAL_RCC_PLLSAI1_CONFIG(PLLSAI1Init->PLLN, PLLSAI1Init->PLLP, PLLSAI1Init->PLLQ, PLLSAI1Init->PLLR);
1212     /* Configure the PLLSAI1 Clock output(s) */
1213     __HAL_RCC_PLLSAI1CLKOUT_ENABLE(PLLSAI1Init->PLLSAI1ClockOut);
1214 
1215     /* Enable the PLLSAI1 again by setting PLLSAI1ON to 1*/
1216     __HAL_RCC_PLLSAI1_ENABLE();
1217 
1218     /* Get Start Tick*/
1219     tickstart = HAL_GetTick();
1220 
1221     /* Wait till PLLSAI1 is ready */
1222     while (LL_RCC_PLLSAI1_IsReady() != 1U)
1223     {
1224       if ((HAL_GetTick() - tickstart) > PLLSAI1_TIMEOUT_VALUE)
1225       {
1226         status = HAL_TIMEOUT;
1227         break;
1228       }
1229     }
1230   }
1231 
1232   return status;
1233 }
1234 
1235 /**
1236   * @brief  Disable PLLSAI1.
1237   * @retval HAL status
1238   */
HAL_RCCEx_DisablePLLSAI1(void)1239 HAL_StatusTypeDef HAL_RCCEx_DisablePLLSAI1(void)
1240 {
1241   uint32_t tickstart;
1242   HAL_StatusTypeDef status = HAL_OK;
1243 
1244   /* Disable the PLLSAI1 */
1245   __HAL_RCC_PLLSAI1_DISABLE();
1246 
1247   /* Get Start Tick*/
1248   tickstart = HAL_GetTick();
1249 
1250   /* Wait till PLLSAI1 is ready */
1251   while (LL_RCC_PLLSAI1_IsReady() != 0U)
1252   {
1253     if ((HAL_GetTick() - tickstart) > PLLSAI1_TIMEOUT_VALUE)
1254     {
1255       status = HAL_TIMEOUT;
1256       break;
1257     }
1258   }
1259 
1260   /* Disable the PLLSAI1 Clock outputs */
1261   __HAL_RCC_PLLSAI1CLKOUT_DISABLE(RCC_PLLSAI1_SAI1CLK | RCC_PLLSAI1_USBCLK | RCC_PLLSAI1_ADCCLK);
1262 
1263   return status;
1264 }
1265 #endif /* SAI1 */
1266 
1267 /***********************************************************************************************/
1268 
1269 /**
1270   * @brief  Configure the oscillator clock source for wakeup from Stop and CSS backup clock.
1271   * @param  WakeUpClk  Wakeup clock
1272   *         This parameter can be one of the following values:
1273   *            @arg @ref RCC_STOP_WAKEUPCLOCK_MSI  MSI oscillator selection
1274   *            @arg @ref RCC_STOP_WAKEUPCLOCK_HSI  HSI oscillator selection
1275   * @note   This function shall not be called after the Clock Security System on HSE has been
1276   *         enabled.
1277   * @retval None
1278   */
HAL_RCCEx_WakeUpStopCLKConfig(uint32_t WakeUpClk)1279 void HAL_RCCEx_WakeUpStopCLKConfig(uint32_t WakeUpClk)
1280 {
1281   assert_param(IS_RCC_STOP_WAKEUPCLOCK(WakeUpClk));
1282 
1283   __HAL_RCC_WAKEUPSTOP_CLK_CONFIG(WakeUpClk);
1284 }
1285 
1286 /**
1287   * @brief  Enable the LSE Clock Security System.
1288   * @note   Prior to enable the LSE Clock Security System, LSE oscillator is to be enabled
1289   *         with HAL_RCC_OscConfig() and the LSE oscillator clock is to be selected as RTC
1290   *         clock with HAL_RCCEx_PeriphCLKConfig().
1291   * @retval None
1292   */
HAL_RCCEx_EnableLSECSS(void)1293 void HAL_RCCEx_EnableLSECSS(void)
1294 {
1295   LL_RCC_LSE_EnableCSS();
1296 }
1297 
1298 /**
1299   * @brief  Disable the LSE Clock Security System.
1300   * @note   LSE Clock Security System can only be disabled after a LSE failure detection.
1301   * @retval None
1302   */
HAL_RCCEx_DisableLSECSS(void)1303 void HAL_RCCEx_DisableLSECSS(void)
1304 {
1305   LL_RCC_LSE_DisableCSS();
1306 
1307   /* Disable LSE CSS IT if any */
1308   __HAL_RCC_DISABLE_IT(RCC_IT_LSECSS);
1309 }
1310 
1311 /**
1312   * @brief  Enable the LSE Clock Security System Interrupt & corresponding EXTI line.
1313   * @note   LSE Clock Security System Interrupt is mapped on RTC EXTI line 18
1314   * @retval None
1315   */
HAL_RCCEx_EnableLSECSS_IT(void)1316 void HAL_RCCEx_EnableLSECSS_IT(void)
1317 {
1318   /* Enable LSE CSS */
1319   LL_RCC_LSE_EnableCSS();
1320 
1321   /* Enable LSE CSS IT */
1322   __HAL_RCC_ENABLE_IT(RCC_IT_LSECSS);
1323 
1324   /* Enable IT on EXTI Line 18 */
1325   __HAL_RCC_LSECSS_EXTI_ENABLE_IT();
1326   __HAL_RCC_LSECSS_EXTI_ENABLE_RISING_EDGE();
1327 }
1328 
1329 /**
1330   * @brief Handle the RCC LSE Clock Security System interrupt request.
1331   * @retval None
1332   */
HAL_RCCEx_LSECSS_IRQHandler(void)1333 void HAL_RCCEx_LSECSS_IRQHandler(void)
1334 {
1335   /* Check RCC LSE CSSF flag  */
1336   if (__HAL_RCC_GET_IT(RCC_IT_LSECSS))
1337   {
1338     /* RCC LSE Clock Security System interrupt user callback */
1339     HAL_RCCEx_LSECSS_Callback();
1340 
1341     /* Clear RCC LSE CSS pending bit */
1342     __HAL_RCC_CLEAR_IT(RCC_IT_LSECSS);
1343   }
1344 }
1345 
1346 /**
1347   * @brief  RCCEx LSE Clock Security System interrupt callback.
1348   * @retval none
1349   */
HAL_RCCEx_LSECSS_Callback(void)1350 __weak void HAL_RCCEx_LSECSS_Callback(void)
1351 {
1352   /* NOTE : This function should not be modified, when the callback is needed,
1353             the HAL_RCCEx_LSECSS_Callback should be implemented in the user file
1354    */
1355 }
1356 
1357 /**
1358   * @brief  Select the clock source to output on LSCO1 pin(PA2) or LSC02 pin (PH3) or LSCO3 pin (PC12).
1359   * @note   PA2, PH3 or PC12 should be configured in alternate function mode.
1360   * @param  RCC_LSCOx  specifies the output direction for the clock source.
1361   *            @arg @ref RCC_LSCO1  Clock source to output on LSCO1 pin(PA2)
1362   *            @arg @ref RCC_LSCO2  Clock source to output on LSCO2 pin(PH3)
1363   *            @arg @ref RCC_LSCO3  Clock source to output on LSCO3 pin(PC12)
1364   * @param  RCC_LSCOSource  specifies the clock source to output.
1365   *          This parameter can be one of the following values:
1366   *            @arg @ref RCC_LSCOSOURCE_LSI  LSI clock selected as LSCO source
1367   *            @arg @ref RCC_LSCOSOURCE_LSE  LSE clock selected as LSCO source
1368   * @retval None
1369   * @note   LSCO should be disable with @ref HAL_RCCEx_DisableLSCO
1370   */
HAL_RCCEx_LSCOConfig(uint32_t RCC_LSCOx,uint32_t RCC_LSCOSource)1371 void HAL_RCCEx_LSCOConfig(uint32_t RCC_LSCOx, uint32_t RCC_LSCOSource)
1372 {
1373   GPIO_InitTypeDef GPIO_InitStruct;
1374   FlagStatus backupchanged;
1375 
1376   /* Check the parameters */
1377   assert_param(IS_RCC_LSCO(RCC_LSCOx));
1378   assert_param(IS_RCC_LSCOSOURCE(RCC_LSCOSource));
1379 
1380   /* Common GPIO init parameters */
1381   GPIO_InitStruct.Mode      = GPIO_MODE_AF_PP;
1382   GPIO_InitStruct.Speed     = GPIO_SPEED_FREQ_VERY_HIGH;
1383   GPIO_InitStruct.Pull      = GPIO_NOPULL;
1384 
1385   /* RCC_LSCO1 */
1386   if (RCC_LSCOx == RCC_LSCO1)
1387   {
1388     /* LSCO1 Clock Enable */
1389     __LSCO1_CLK_ENABLE();
1390     /* Configure the LSCO1 pin in alternate function mode */
1391     GPIO_InitStruct.Pin       = LSCO1_PIN;
1392     GPIO_InitStruct.Alternate = GPIO_AF0_LSCO;
1393     HAL_GPIO_Init(LSCO1_GPIO_PORT, &GPIO_InitStruct);
1394   }
1395   else if (RCC_LSCOx == RCC_LSCO2)
1396   {
1397     /* LSCO2 Clock Enable */
1398     __LSCO2_CLK_ENABLE();
1399     /* Configure the LSCO2 pin in alternate function mode */
1400     GPIO_InitStruct.Pin       = LSCO2_PIN;
1401     GPIO_InitStruct.Alternate = GPIO_AF0_LSCO;
1402     HAL_GPIO_Init(LSCO2_GPIO_PORT, &GPIO_InitStruct);
1403 
1404   }
1405 #if defined(RCC_LSCO3_SUPPORT)
1406   else if (RCC_LSCOx == RCC_LSCO3)
1407   {
1408     /* LSCO3 Clock Enable */
1409     __LSCO3_CLK_ENABLE();
1410     /* Configure the LSCO3 pin in alternate function mode */
1411     GPIO_InitStruct.Pin       = LSCO3_PIN;
1412     GPIO_InitStruct.Alternate = GPIO_AF6_LSCO;
1413     HAL_GPIO_Init(LSCO3_GPIO_PORT, &GPIO_InitStruct);
1414   }
1415 #endif /* RCC_LSCO3_SUPPORT */
1416   else
1417   {
1418     ;
1419   }
1420 
1421   /* Update LSCOSEL clock source in Backup Domain control register */
1422   if (HAL_IS_BIT_CLR(PWR->CR1, PWR_CR1_DBP))
1423   {
1424     HAL_PWR_EnableBkUpAccess();
1425     backupchanged = SET;
1426   }
1427   else
1428   {
1429     backupchanged = RESET;
1430   }
1431 
1432   MODIFY_REG(RCC->BDCR, RCC_BDCR_LSCOSEL | RCC_BDCR_LSCOEN, RCC_LSCOSource | RCC_BDCR_LSCOEN);
1433 
1434   if (backupchanged == SET)
1435   {
1436     HAL_PWR_DisableBkUpAccess();
1437   }
1438 
1439 }
1440 
1441 /**
1442   * @brief  Select the Low Speed clock source to output on LSCO pin (PA2).
1443   * @param  LSCOSource  specifies the Low Speed clock source to output.
1444   *          This parameter can be one of the following values:
1445   *            @arg @ref RCC_LSCOSOURCE_LSI  LSI clock selected as LSCO source
1446   *            @arg @ref RCC_LSCOSOURCE_LSE  LSE clock selected as LSCO source
1447   * @retval None
1448   */
HAL_RCCEx_EnableLSCO(uint32_t LSCOSource)1449 void HAL_RCCEx_EnableLSCO(uint32_t LSCOSource)
1450 {
1451   /* Check the parameters */
1452   assert_param(IS_RCC_LSCOSOURCE(LSCOSource));
1453 
1454   /* Update LSCO selection according to parameter and enable LSCO */
1455   MODIFY_REG(RCC->BDCR, RCC_BDCR_LSCOSEL, LSCOSource | RCC_BDCR_LSCOEN);
1456 }
1457 
1458 /**
1459   * @brief  Disable the Low Speed clock output.
1460   * @retval None
1461   */
HAL_RCCEx_DisableLSCO(void)1462 void HAL_RCCEx_DisableLSCO(void)
1463 {
1464   LL_RCC_LSCO_Disable();
1465 }
1466 
1467 /**
1468   * @brief  Enable the PLL-mode of the MSI.
1469   * @note   Prior to enable the PLL-mode of the MSI for automatic hardware
1470   *         calibration LSE oscillator is to be enabled with @ref HAL_RCC_OscConfig().
1471   * @retval None
1472   */
HAL_RCCEx_EnableMSIPLLMode(void)1473 void HAL_RCCEx_EnableMSIPLLMode(void)
1474 {
1475   LL_RCC_MSI_EnablePLLMode() ;
1476 }
1477 
1478 /**
1479   * @brief  Disable the PLL-mode of the MSI.
1480   * @note   PLL-mode of the MSI is automatically reset when LSE oscillator is disabled.
1481   * @retval None
1482   */
HAL_RCCEx_DisableMSIPLLMode(void)1483 void HAL_RCCEx_DisableMSIPLLMode(void)
1484 {
1485   LL_RCC_MSI_DisablePLLMode() ;
1486 }
1487 
1488 /**
1489   * @brief Set trimming value
1490   * @param OscillatorType Specifies the oscillator to be trimmed
1491   *   This parameter can be one of the following values:
1492   *     @arg @ref RCC_OSCILLATORTYPE_LSI2 LSI2 oscillator selected.
1493   *       When disabling and re-enabling the LSI2 there is no need for re-trimming
1494   *       Trimming is only needed once after a NRST reset.
1495   *       Trimming values comes from factory trimmed flash location (0x1FFF7548).
1496   * @note The LSI2 oscillator must be disabled before calling this trimming function through @ref HAL_RCC_OscConfig
1497   * @retval HAL status
1498   */
HAL_RCCEx_TrimOsc(uint32_t OscillatorType)1499 HAL_StatusTypeDef HAL_RCCEx_TrimOsc(uint32_t OscillatorType)
1500 {
1501 #define FTLSI2TRIM (0xFUL)
1502   HAL_StatusTypeDef status = HAL_OK;
1503 
1504   assert_param(IS_RCC_TRIMOSC(OscillatorType));
1505 
1506   if (OscillatorType == RCC_OSCILLATORTYPE_LSI2)
1507   {
1508     if (LL_RCC_LSI2_IsReady() == 1U)
1509     {
1510       status = HAL_ERROR;
1511     }
1512     else
1513     {
1514       /* Copy the LSI2 trimming information from the factory trimmed Flash location */
1515       uint32_t factoryTrimming = ((*(uint32_t *)(0x1FFF7548)) & FTLSI2TRIM);
1516       LL_RCC_LSI2_SetTrimming(factoryTrimming);
1517     }
1518   }
1519   else
1520   {
1521     status = HAL_ERROR;
1522   }
1523   return status;
1524 }
1525 
1526 /**
1527   * @}
1528   */
1529 
1530 #if defined(CRS)
1531 /** @defgroup RCCEx_Exported_Functions_Group3 Extended Clock Recovery System Control functions
1532   *  @brief  Extended Clock Recovery System Control functions
1533   *
1534 @verbatim
1535  ===============================================================================
1536                 ##### Extended Clock Recovery System Control functions  #####
1537  ===============================================================================
1538     [..]
1539       For devices with Clock Recovery System feature (CRS), RCC Extended HAL driver can be used as follows:
1540 
1541       (#) In System clock config, HSI48 needs to be enabled
1542 
1543       (#) Enable CRS clock in IP MSP init which will use CRS functions
1544 
1545       (#) Call CRS functions as follows:
1546           (##) Prepare synchronization configuration necessary for HSI48 calibration
1547               (+++) Default values can be set for frequency Error Measurement (reload and error limit)
1548                         and also HSI48 oscillator smooth trimming.
1549               (+++) Macro __HAL_RCC_CRS_RELOADVALUE_CALCULATE can be also used to calculate
1550                         directly reload value with target and synchronization frequencies values
1551           (##) Call function HAL_RCCEx_CRSConfig which
1552               (+++) Resets CRS registers to their default values.
1553               (+++) Configures CRS registers with synchronization configuration
1554               (+++) Enables automatic calibration and frequency error counter feature
1555            Note: When using USB LPM (Link Power Management) and the device is in Sleep mode, the
1556            periodic USB SOF will not be generated by the host. No SYNC signal will therefore be
1557            provided to the CRS to calibrate the HSI48 on the run. To guarantee the required clock
1558            precision after waking up from Sleep mode, the LSE or reference clock on the GPIOs
1559            should be used as SYNC signal.
1560 
1561           (##) A polling function is provided to wait for complete synchronization
1562               (+++) Call function HAL_RCCEx_CRSWaitSynchronization()
1563               (+++) According to CRS status, user can decide to adjust again the calibration or continue
1564                         application if synchronization is OK
1565 
1566       (#) User can retrieve information related to synchronization in calling function
1567             HAL_RCCEx_CRSGetSynchronizationInfo()
1568 
1569       (#) Regarding synchronization status and synchronization information, user can try a new calibration
1570            in changing synchronization configuration and call again HAL_RCCEx_CRSConfig.
1571            Note: When the SYNC event is detected during the downcounting phase (before reaching the zero value),
1572            it means that the actual frequency is lower than the target (and so, that the TRIM value should be
1573            incremented), while when it is detected during the upcounting phase it means that the actual frequency
1574            is higher (and that the TRIM value should be decremented).
1575 
1576       (#) In interrupt mode, user can resort to the available macros (__HAL_RCC_CRS_XXX_IT). Interrupts will go
1577           through CRS Handler (CRS_IRQn/CRS_IRQHandler)
1578               (++) Call function HAL_RCCEx_CRSConfig()
1579               (++) Enable CRS_IRQn (thanks to NVIC functions)
1580               (++) Enable CRS interrupt (__HAL_RCC_CRS_ENABLE_IT)
1581               (++) Implement CRS status management in the following user callbacks called from
1582                    HAL_RCCEx_CRS_IRQHandler():
1583                    (+++) HAL_RCCEx_CRS_SyncOkCallback()
1584                    (+++) HAL_RCCEx_CRS_SyncWarnCallback()
1585                    (+++) HAL_RCCEx_CRS_ExpectedSyncCallback()
1586                    (+++) HAL_RCCEx_CRS_ErrorCallback()
1587 
1588       (#) To force a SYNC EVENT, user can use the function HAL_RCCEx_CRSSoftwareSynchronizationGenerate().
1589           This function can be called before calling HAL_RCCEx_CRSConfig (for instance in Systick handler)
1590 
1591 @endverbatim
1592   * @{
1593   */
1594 
1595 /**
1596   * @brief  Start automatic synchronization for polling mode
1597   * @param  pInit Pointer on RCC_CRSInitTypeDef structure
1598   * @retval None
1599   */
HAL_RCCEx_CRSConfig(RCC_CRSInitTypeDef * pInit)1600 void HAL_RCCEx_CRSConfig(RCC_CRSInitTypeDef *pInit)
1601 {
1602   uint32_t value;
1603 
1604   /* Check the parameters */
1605   assert_param(IS_RCC_CRS_SYNC_DIV(pInit->Prescaler));
1606   assert_param(IS_RCC_CRS_SYNC_SOURCE(pInit->Source));
1607   assert_param(IS_RCC_CRS_SYNC_POLARITY(pInit->Polarity));
1608   assert_param(IS_RCC_CRS_RELOADVALUE(pInit->ReloadValue));
1609   assert_param(IS_RCC_CRS_ERRORLIMIT(pInit->ErrorLimitValue));
1610   assert_param(IS_RCC_CRS_HSI48CALIBRATION(pInit->HSI48CalibrationValue));
1611 
1612   /* CONFIGURATION */
1613 
1614   /* Before configuration, reset CRS registers to their default values*/
1615   __HAL_RCC_CRS_FORCE_RESET();
1616   __HAL_RCC_CRS_RELEASE_RESET();
1617 
1618   /* Set the SYNCDIV[2:0] bits according to Prescaler value */
1619   /* Set the SYNCSRC[1:0] bits according to Source value */
1620   /* Set the SYNCSPOL bit according to Polarity value */
1621   value = (pInit->Prescaler | pInit->Source | pInit->Polarity);
1622   /* Set the RELOAD[15:0] bits according to ReloadValue value */
1623   value |= pInit->ReloadValue;
1624   /* Set the FELIM[7:0] bits according to ErrorLimitValue value */
1625   value |= (pInit->ErrorLimitValue << CRS_CFGR_FELIM_Pos);
1626   WRITE_REG(CRS->CFGR, value);
1627 
1628   /* Adjust HSI48 oscillator smooth trimming */
1629   /* Set the TRIM[5:0] bits according to RCC_CRS_HSI48CalibrationValue value */
1630   MODIFY_REG(CRS->CR, CRS_CR_TRIM, (pInit->HSI48CalibrationValue << CRS_CR_TRIM_Pos));
1631 
1632   /* START AUTOMATIC SYNCHRONIZATION*/
1633 
1634   /* Enable Automatic trimming & Frequency error counter */
1635   SET_BIT(CRS->CR, CRS_CR_AUTOTRIMEN | CRS_CR_CEN);
1636 }
1637 
1638 /**
1639   * @brief  Generate the software synchronization event
1640   * @retval None
1641   */
HAL_RCCEx_CRSSoftwareSynchronizationGenerate(void)1642 void HAL_RCCEx_CRSSoftwareSynchronizationGenerate(void)
1643 {
1644   LL_CRS_GenerateEvent_SWSYNC();
1645 }
1646 
1647 /**
1648   * @brief  Return synchronization info
1649   * @param  pSynchroInfo Pointer on @ref RCC_CRSSynchroInfoTypeDef structure
1650   * @retval None
1651   */
HAL_RCCEx_CRSGetSynchronizationInfo(RCC_CRSSynchroInfoTypeDef * pSynchroInfo)1652 void HAL_RCCEx_CRSGetSynchronizationInfo(RCC_CRSSynchroInfoTypeDef *pSynchroInfo)
1653 {
1654   /* Check the parameter */
1655   assert_param(pSynchroInfo != (void *)NULL);
1656 
1657   /* Get the reload value */
1658   pSynchroInfo->ReloadValue = LL_CRS_GetReloadCounter();
1659 
1660   /* Get HSI48 oscillator smooth trimming */
1661   pSynchroInfo->HSI48CalibrationValue = LL_CRS_GetHSI48SmoothTrimming();
1662 
1663   /* Get Frequency error capture */
1664   pSynchroInfo->FreqErrorCapture = LL_CRS_GetFreqErrorCapture();
1665 
1666   /* Get Frequency error direction */
1667   pSynchroInfo->FreqErrorDirection = LL_CRS_GetFreqErrorDirection();
1668 }
1669 
1670 /**
1671   * @brief  Wait for CRS Synchronization status.
1672   * @param  Timeout  Duration of the timeout
1673   * @note   Timeout is based on the maximum time to receive a SYNC event based on synchronization
1674   *         frequency.
1675   * @note   If Timeout set to HAL_MAX_DELAY, HAL_TIMEOUT will be never returned.
1676   * @retval Combination of Synchronization status
1677   *          This parameter can be a combination of the following values:
1678   *            @arg @ref RCC_CRS_TIMEOUT
1679   *            @arg @ref RCC_CRS_SYNCOK
1680   *            @arg @ref RCC_CRS_SYNCWARN
1681   *            @arg @ref RCC_CRS_SYNCERR
1682   *            @arg @ref RCC_CRS_SYNCMISS
1683   *            @arg @ref RCC_CRS_TRIMOVF
1684   */
HAL_RCCEx_CRSWaitSynchronization(uint32_t Timeout)1685 uint32_t HAL_RCCEx_CRSWaitSynchronization(uint32_t Timeout)
1686 {
1687   uint32_t crsstatus = RCC_CRS_NONE;
1688   uint32_t tickstart;
1689 
1690   /* Get timeout */
1691   tickstart = HAL_GetTick();
1692 
1693   /* Wait for CRS flag or timeout detection */
1694   do
1695   {
1696     if (Timeout != HAL_MAX_DELAY)
1697     {
1698       if (((HAL_GetTick() - tickstart) > Timeout) || (Timeout == 0U))
1699       {
1700         crsstatus = RCC_CRS_TIMEOUT;
1701       }
1702     }
1703     /* Check CRS SYNCOK flag  */
1704     if (__HAL_RCC_CRS_GET_FLAG(RCC_CRS_FLAG_SYNCOK))
1705     {
1706       /* CRS SYNC event OK */
1707       crsstatus |= RCC_CRS_SYNCOK;
1708 
1709       /* Clear CRS SYNC event OK bit */
1710       __HAL_RCC_CRS_CLEAR_FLAG(RCC_CRS_FLAG_SYNCOK);
1711     }
1712 
1713     /* Check CRS SYNCWARN flag  */
1714     if (__HAL_RCC_CRS_GET_FLAG(RCC_CRS_FLAG_SYNCWARN))
1715     {
1716       /* CRS SYNC warning */
1717       crsstatus |= RCC_CRS_SYNCWARN;
1718 
1719       /* Clear CRS SYNCWARN bit */
1720       __HAL_RCC_CRS_CLEAR_FLAG(RCC_CRS_FLAG_SYNCWARN);
1721     }
1722 
1723     /* Check CRS TRIM overflow flag  */
1724     if (__HAL_RCC_CRS_GET_FLAG(RCC_CRS_FLAG_TRIMOVF))
1725     {
1726       /* CRS SYNC Error */
1727       crsstatus |= RCC_CRS_TRIMOVF;
1728 
1729       /* Clear CRS Error bit */
1730       __HAL_RCC_CRS_CLEAR_FLAG(RCC_CRS_FLAG_TRIMOVF);
1731     }
1732 
1733     /* Check CRS Error flag  */
1734     if (__HAL_RCC_CRS_GET_FLAG(RCC_CRS_FLAG_SYNCERR))
1735     {
1736       /* CRS SYNC Error */
1737       crsstatus |= RCC_CRS_SYNCERR;
1738 
1739       /* Clear CRS Error bit */
1740       __HAL_RCC_CRS_CLEAR_FLAG(RCC_CRS_FLAG_SYNCERR);
1741     }
1742 
1743     /* Check CRS SYNC Missed flag  */
1744     if (__HAL_RCC_CRS_GET_FLAG(RCC_CRS_FLAG_SYNCMISS))
1745     {
1746       /* CRS SYNC Missed */
1747       crsstatus |= RCC_CRS_SYNCMISS;
1748 
1749       /* Clear CRS SYNC Missed bit */
1750       __HAL_RCC_CRS_CLEAR_FLAG(RCC_CRS_FLAG_SYNCMISS);
1751     }
1752 
1753     /* Check CRS Expected SYNC flag  */
1754     if (__HAL_RCC_CRS_GET_FLAG(RCC_CRS_FLAG_ESYNC))
1755     {
1756       /* frequency error counter reached a zero value */
1757       __HAL_RCC_CRS_CLEAR_FLAG(RCC_CRS_FLAG_ESYNC);
1758     }
1759   } while (RCC_CRS_NONE == crsstatus);
1760 
1761   return crsstatus;
1762 }
1763 
1764 /**
1765   * @brief Handle the Clock Recovery System interrupt request.
1766   * @retval None
1767   */
HAL_RCCEx_CRS_IRQHandler(void)1768 void HAL_RCCEx_CRS_IRQHandler(void)
1769 {
1770   uint32_t crserror = RCC_CRS_NONE;
1771   /* Get current IT flags and IT sources values */
1772   uint32_t itflags = READ_REG(CRS->ISR);
1773   uint32_t itsources = READ_REG(CRS->CR);
1774 
1775   /* Check CRS SYNCOK flag  */
1776   if (((itflags & RCC_CRS_FLAG_SYNCOK) != 0U) && ((itsources & RCC_CRS_IT_SYNCOK) != 0U))
1777   {
1778     /* Clear CRS SYNC event OK flag */
1779     LL_CRS_ClearFlag_SYNCOK();
1780 
1781     /* user callback */
1782     HAL_RCCEx_CRS_SyncOkCallback();
1783   }
1784   /* Check CRS SYNCWARN flag  */
1785   else if (((itflags & RCC_CRS_FLAG_SYNCWARN) != 0U) && ((itsources & RCC_CRS_IT_SYNCWARN) != 0U))
1786   {
1787     /* Clear CRS SYNCWARN flag */
1788     LL_CRS_ClearFlag_SYNCWARN();
1789 
1790     /* user callback */
1791     HAL_RCCEx_CRS_SyncWarnCallback();
1792   }
1793   /* Check CRS Expected SYNC flag  */
1794   else if (((itflags & RCC_CRS_FLAG_ESYNC) != 0U) && ((itsources & RCC_CRS_IT_ESYNC) != 0U))
1795   {
1796     /* frequency error counter reached a zero value */
1797     LL_CRS_ClearFlag_ESYNC();
1798 
1799     /* user callback */
1800     HAL_RCCEx_CRS_ExpectedSyncCallback();
1801   }
1802   /* Check CRS Error flags  */
1803   else
1804   {
1805     if (((itflags & RCC_CRS_FLAG_ERR) != 0U) && ((itsources & RCC_CRS_IT_ERR) != 0U))
1806     {
1807       if ((itflags & RCC_CRS_FLAG_SYNCERR) != 0U)
1808       {
1809         crserror |= RCC_CRS_SYNCERR;
1810       }
1811       if ((itflags & RCC_CRS_FLAG_SYNCMISS) != 0U)
1812       {
1813         crserror |= RCC_CRS_SYNCMISS;
1814       }
1815       if ((itflags & RCC_CRS_FLAG_TRIMOVF) != 0U)
1816       {
1817         crserror |= RCC_CRS_TRIMOVF;
1818       }
1819 
1820       /* Clear CRS Error flags */
1821       LL_CRS_ClearFlag_ERR();
1822 
1823       /* user error callback */
1824       HAL_RCCEx_CRS_ErrorCallback(crserror);
1825     }
1826   }
1827 }
1828 
1829 /**
1830   * @brief  RCCEx Clock Recovery System SYNCOK interrupt callback.
1831   * @retval none
1832   */
HAL_RCCEx_CRS_SyncOkCallback(void)1833 __weak void HAL_RCCEx_CRS_SyncOkCallback(void)
1834 {
1835   /* NOTE : This function should not be modified, when the callback is needed,
1836             the @ref HAL_RCCEx_CRS_SyncOkCallback should be implemented in the user file
1837    */
1838 }
1839 
1840 /**
1841   * @brief  RCCEx Clock Recovery System SYNCWARN interrupt callback.
1842   * @retval none
1843   */
HAL_RCCEx_CRS_SyncWarnCallback(void)1844 __weak void HAL_RCCEx_CRS_SyncWarnCallback(void)
1845 {
1846   /* NOTE : This function should not be modified, when the callback is needed,
1847             the HAL_RCCEx_CRS_SyncWarnCallback should be implemented in the user file
1848    */
1849 }
1850 
1851 /**
1852   * @brief  RCCEx Clock Recovery System Expected SYNC interrupt callback.
1853   * @retval none
1854   */
HAL_RCCEx_CRS_ExpectedSyncCallback(void)1855 __weak void HAL_RCCEx_CRS_ExpectedSyncCallback(void)
1856 {
1857   /* NOTE : This function should not be modified, when the callback is needed,
1858             the HAL_RCCEx_CRS_ExpectedSyncCallback should be implemented in the user file
1859    */
1860 }
1861 
1862 /**
1863   * @brief  RCCEx Clock Recovery System Error interrupt callback.
1864   * @param  Error Combination of Error status.
1865   *         This parameter can be a combination of the following values:
1866   *           @arg @ref RCC_CRS_SYNCERR
1867   *           @arg @ref RCC_CRS_SYNCMISS
1868   *           @arg @ref RCC_CRS_TRIMOVF
1869   * @retval none
1870   */
HAL_RCCEx_CRS_ErrorCallback(uint32_t Error)1871 __weak void HAL_RCCEx_CRS_ErrorCallback(uint32_t Error)
1872 {
1873   /* Prevent unused argument(s) compilation warning */
1874   UNUSED(Error);
1875 
1876   /* NOTE : This function should not be modified, when the callback is needed,
1877             the @ref HAL_RCCEx_CRS_ErrorCallback should be implemented in the user file
1878    */
1879 }
1880 
1881 /**
1882   * @}
1883   */
1884 #endif /* CRS */
1885 
1886 /**
1887   * @}
1888   */
1889 
1890 /** @addtogroup RCCEx_Private_Functions
1891   * @{
1892   */
1893 
1894 #if defined(SAI1)
1895 /**
1896   * @brief  Configure the parameters N & P of PLLSAI1 and enable PLLSAI1 output clock(s).
1897   * @param  PLLSAI1  pointer to an RCC_PLLSAI1InitTypeDef structure that
1898   *         contains the configuration parameters N & P as well as PLLSAI1 output clock(s)
1899   *
1900   * @note   PLLSAI1 is temporary disable to apply new parameters
1901   *
1902   * @retval HAL status
1903   */
RCCEx_PLLSAI1_ConfigNP(RCC_PLLSAI1InitTypeDef * PLLSAI1)1904 static HAL_StatusTypeDef RCCEx_PLLSAI1_ConfigNP(RCC_PLLSAI1InitTypeDef *PLLSAI1)
1905 {
1906   uint32_t tickstart;
1907   HAL_StatusTypeDef status = HAL_OK;
1908 
1909   /* check for PLLSAI1 Parameters used to output PLLSAI1CLK */
1910   assert_param(IS_RCC_PLLN_VALUE(PLLSAI1->PLLN));
1911   assert_param(IS_RCC_PLLP_VALUE(PLLSAI1->PLLP));
1912   assert_param(IS_RCC_PLLSAI1CLOCKOUT_VALUE(PLLSAI1->PLLSAI1ClockOut));
1913 
1914   /* Disable the PLLSAI1 */
1915   __HAL_RCC_PLLSAI1_DISABLE();
1916 
1917   /* Get Start Tick*/
1918   tickstart = HAL_GetTick();
1919 
1920   /* Wait till PLLSAI1 is ready to be updated */
1921   while (LL_RCC_PLLSAI1_IsReady() != 0U)
1922   {
1923     if ((HAL_GetTick() - tickstart) > PLLSAI1_TIMEOUT_VALUE)
1924     {
1925       status = HAL_TIMEOUT;
1926       break;
1927     }
1928   }
1929 
1930   if (status == HAL_OK)
1931   {
1932     /* Configure the PLLSAI1 Multiplication factor N */
1933     __HAL_RCC_PLLSAI1_MULN_CONFIG(PLLSAI1->PLLN);
1934 
1935     /* Configure the PLLSAI1 Division factor P */
1936     __HAL_RCC_PLLSAI1_DIVP_CONFIG(PLLSAI1->PLLP);
1937 
1938     /* Enable the PLLSAI1 again by setting PLLSAI1ON to 1*/
1939     __HAL_RCC_PLLSAI1_ENABLE();
1940 
1941     /* Get Start Tick*/
1942     tickstart = HAL_GetTick();
1943 
1944     /* Wait till PLLSAI1 is ready */
1945     while (LL_RCC_PLLSAI1_IsReady() != 1U)
1946     {
1947       if ((HAL_GetTick() - tickstart) > PLLSAI1_TIMEOUT_VALUE)
1948       {
1949         status = HAL_TIMEOUT;
1950         break;
1951       }
1952     }
1953 
1954     if (status == HAL_OK)
1955     {
1956       /* Configure the PLLSAI1 Clock output(s) */
1957       __HAL_RCC_PLLSAI1CLKOUT_ENABLE(PLLSAI1->PLLSAI1ClockOut);
1958     }
1959   }
1960 
1961   return status;
1962 }
1963 
1964 /**
1965   * @brief  Configure the parameters N & Q of PLLSAI1 and enable PLLSAI1 output clock(s).
1966   * @param  PLLSAI1  pointer to an RCC_PLLSAI1InitTypeDef structure that
1967   *         contains the configuration parameters N & Q as well as PLLSAI1 output clock(s)
1968   *
1969   * @note   PLLSAI1 is temporary disable to apply new parameters
1970   *
1971   * @retval HAL status
1972   */
RCCEx_PLLSAI1_ConfigNQ(RCC_PLLSAI1InitTypeDef * PLLSAI1)1973 static HAL_StatusTypeDef RCCEx_PLLSAI1_ConfigNQ(RCC_PLLSAI1InitTypeDef *PLLSAI1)
1974 {
1975   uint32_t tickstart;
1976   HAL_StatusTypeDef status = HAL_OK;
1977 
1978   /* check for PLLSAI1 Parameters used to output PLLSAI1CLK */
1979   assert_param(IS_RCC_PLLN_VALUE(PLLSAI1->PLLN));
1980   assert_param(IS_RCC_PLLQ_VALUE(PLLSAI1->PLLQ));
1981   assert_param(IS_RCC_PLLSAI1CLOCKOUT_VALUE(PLLSAI1->PLLSAI1ClockOut));
1982 
1983   /* Disable the PLLSAI1 */
1984   __HAL_RCC_PLLSAI1_DISABLE();
1985 
1986   /* Get Start Tick*/
1987   tickstart = HAL_GetTick();
1988 
1989   /* Wait till PLLSAI1 is ready to be updated */
1990   while (LL_RCC_PLLSAI1_IsReady() != 0U)
1991   {
1992     if ((HAL_GetTick() - tickstart) > PLLSAI1_TIMEOUT_VALUE)
1993     {
1994       status = HAL_TIMEOUT;
1995       break;
1996     }
1997   }
1998 
1999   if (status == HAL_OK)
2000   {
2001     /* Configure the PLLSAI1 Multiplication factor N */
2002     __HAL_RCC_PLLSAI1_MULN_CONFIG(PLLSAI1->PLLN);
2003     /* Configure the PLLSAI1 Division factor Q */
2004     __HAL_RCC_PLLSAI1_DIVQ_CONFIG(PLLSAI1->PLLQ);
2005 
2006     /* Enable the PLLSAI1 again by setting PLLSAI1ON to 1*/
2007     __HAL_RCC_PLLSAI1_ENABLE();
2008 
2009     /* Get Start Tick*/
2010     tickstart = HAL_GetTick();
2011 
2012     /* Wait till PLLSAI1 is ready */
2013     while (LL_RCC_PLLSAI1_IsReady() != 1U)
2014     {
2015       if ((HAL_GetTick() - tickstart) > PLLSAI1_TIMEOUT_VALUE)
2016       {
2017         status = HAL_TIMEOUT;
2018         break;
2019       }
2020     }
2021 
2022     if (status == HAL_OK)
2023     {
2024       /* Configure the PLLSAI1 Clock output(s) */
2025       __HAL_RCC_PLLSAI1CLKOUT_ENABLE(PLLSAI1->PLLSAI1ClockOut);
2026     }
2027   }
2028 
2029   return status;
2030 }
2031 
2032 /**
2033   * @brief  Configure the parameters N & R of PLLSAI1 and enable PLLSAI1 output clock(s).
2034   * @param  PLLSAI1  pointer to an RCC_PLLSAI1InitTypeDef structure that
2035   *         contains the configuration parameters N & R as well as PLLSAI1 output clock(s)
2036   *
2037   * @note   PLLSAI1 is temporary disable to apply new parameters
2038   *
2039   * @retval HAL status
2040   */
RCCEx_PLLSAI1_ConfigNR(RCC_PLLSAI1InitTypeDef * PLLSAI1)2041 static HAL_StatusTypeDef RCCEx_PLLSAI1_ConfigNR(RCC_PLLSAI1InitTypeDef *PLLSAI1)
2042 {
2043   uint32_t tickstart;
2044   HAL_StatusTypeDef status = HAL_OK;
2045 
2046   /* check for PLLSAI1 Parameters used to output PLLSAI1CLK */
2047   assert_param(IS_RCC_PLLN_VALUE(PLLSAI1->PLLN));
2048   assert_param(IS_RCC_PLLR_VALUE(PLLSAI1->PLLR));
2049   assert_param(IS_RCC_PLLSAI1CLOCKOUT_VALUE(PLLSAI1->PLLSAI1ClockOut));
2050 
2051   /* Disable the PLLSAI1 */
2052   __HAL_RCC_PLLSAI1_DISABLE();
2053 
2054   /* Get Start Tick*/
2055   tickstart = HAL_GetTick();
2056 
2057   /* Wait till PLLSAI1 is ready to be updated */
2058   while (LL_RCC_PLLSAI1_IsReady() != 0U)
2059   {
2060     if ((HAL_GetTick() - tickstart) > PLLSAI1_TIMEOUT_VALUE)
2061     {
2062       status = HAL_TIMEOUT;
2063       break;
2064     }
2065   }
2066 
2067   if (status == HAL_OK)
2068   {
2069     /* Configure the PLLSAI1 Multiplication factor N */
2070     __HAL_RCC_PLLSAI1_MULN_CONFIG(PLLSAI1->PLLN);
2071     /* Configure the PLLSAI1 Division factor R */
2072     __HAL_RCC_PLLSAI1_DIVR_CONFIG(PLLSAI1->PLLR);
2073 
2074     /* Enable the PLLSAI1 again by setting PLLSAI1ON to 1*/
2075     __HAL_RCC_PLLSAI1_ENABLE();
2076 
2077     /* Get Start Tick*/
2078     tickstart = HAL_GetTick();
2079 
2080     /* Wait till PLLSAI1 is ready */
2081     while (LL_RCC_PLLSAI1_IsReady() != 1U)
2082     {
2083       if ((HAL_GetTick() - tickstart) > PLLSAI1_TIMEOUT_VALUE)
2084       {
2085         status = HAL_TIMEOUT;
2086         break;
2087       }
2088     }
2089 
2090     if (status == HAL_OK)
2091     {
2092       /* Configure the PLLSAI1 Clock output(s) */
2093       __HAL_RCC_PLLSAI1CLKOUT_ENABLE(PLLSAI1->PLLSAI1ClockOut);
2094     }
2095   }
2096 
2097   return status;
2098 }
2099 #endif /* SAI1 */
2100 
2101 /**
2102   * @brief  Return PLL clock (PLLPCLK) frequency used for SAI domain
2103   * @retval PLLPCLK clock frequency (in Hz)
2104   */
RCC_PLL_GetFreqDomain_P(void)2105 static uint32_t RCC_PLL_GetFreqDomain_P(void)
2106 {
2107   uint32_t pllinputfreq;
2108   uint32_t pllsource;
2109 
2110   /* PLL_VCO = (HSE_VALUE or HSI_VALUE or MSI Value / PLLM) * PLLN
2111      SAI Domain clock = PLL_VCO / PLLP
2112   */
2113   pllsource = LL_RCC_PLL_GetMainSource();
2114 
2115   switch (pllsource)
2116   {
2117     case LL_RCC_PLLSOURCE_MSI:  /* MSI used as PLL clock source */
2118       pllinputfreq = __LL_RCC_CALC_MSI_FREQ(LL_RCC_MSI_GetRange());
2119       break;
2120 
2121     case LL_RCC_PLLSOURCE_HSI:  /* HSI used as PLL clock source */
2122       pllinputfreq = HSI_VALUE;
2123       break;
2124 
2125     case LL_RCC_PLLSOURCE_HSE:  /* HSE used as PLL clock source */
2126       if (LL_RCC_HSE_IsEnabledDiv2() == 1U)
2127       {
2128         pllinputfreq = HSE_VALUE / 2U;
2129       }
2130       else
2131       {
2132         pllinputfreq = HSE_VALUE;
2133       }
2134       break;
2135 
2136     default:
2137       pllinputfreq = __LL_RCC_CALC_MSI_FREQ(LL_RCC_MSI_GetRange());
2138       break;
2139   }
2140   return __LL_RCC_CALC_PLLCLK_ADC_FREQ(pllinputfreq, LL_RCC_PLL_GetDivider(),
2141                                        LL_RCC_PLL_GetN(), LL_RCC_PLL_GetP());
2142 }
2143 
2144 /**
2145   * @brief  Return PLL clock (PLLQCLK) frequency used for 48 MHz domain
2146   * @retval PLLQCLK clock frequency (in Hz)
2147   */
RCC_PLL_GetFreqDomain_Q(void)2148 static uint32_t RCC_PLL_GetFreqDomain_Q(void)
2149 {
2150   uint32_t pllinputfreq;
2151   uint32_t pllsource;
2152 
2153   /* PLL_VCO = (HSE_VALUE or HSI_VALUE or MSI Value/ PLLM) * PLLN
2154      48M Domain clock = PLL_VCO / PLLQ
2155   */
2156   pllsource = LL_RCC_PLL_GetMainSource();
2157 
2158   switch (pllsource)
2159   {
2160     case LL_RCC_PLLSOURCE_MSI:  /* MSI used as PLL clock source */
2161       pllinputfreq = __LL_RCC_CALC_MSI_FREQ(LL_RCC_MSI_GetRange());
2162       break;
2163 
2164     case LL_RCC_PLLSOURCE_HSI:  /* HSI used as PLL clock source */
2165       pllinputfreq = HSI_VALUE;
2166       break;
2167 
2168     case LL_RCC_PLLSOURCE_HSE:  /* HSE used as PLL clock source */
2169       if (LL_RCC_HSE_IsEnabledDiv2() == 1U)
2170       {
2171         pllinputfreq = HSE_VALUE / 2U;
2172       }
2173       else
2174       {
2175         pllinputfreq = HSE_VALUE;
2176       }
2177 
2178       break;
2179 
2180     default:
2181       pllinputfreq = __LL_RCC_CALC_MSI_FREQ(LL_RCC_MSI_GetRange());
2182       break;
2183   }
2184   return __LL_RCC_CALC_PLLCLK_48M_FREQ(pllinputfreq, LL_RCC_PLL_GetDivider(),
2185                                        LL_RCC_PLL_GetN(), LL_RCC_PLL_GetQ());
2186 }
2187 
2188 #if defined(SAI1)
2189 /**
2190   * @brief  Return PLLSAI1 clock (PLLSAI1RCLK) frequency used for ADC domain
2191   * @retval PLLSAI1RCLK clock frequency (in Hz)
2192   */
RCC_PLLSAI1_GetFreqDomain_R(void)2193 static uint32_t RCC_PLLSAI1_GetFreqDomain_R(void)
2194 {
2195   uint32_t pllinputfreq;
2196   uint32_t pllsource;
2197 
2198   /* PLLSAI1_VCO = (HSE_VALUE or HSI_VALUE or MSI Value/ PLLM) * PLLSAI1N */
2199   /* 48M Domain clock  = PLLSAI1_VCO / PLLSAI1R */
2200   pllsource = LL_RCC_PLL_GetMainSource();
2201 
2202   switch (pllsource)
2203   {
2204     case LL_RCC_PLLSOURCE_MSI:  /* MSI used as PLLSAI1 clock source */
2205       pllinputfreq = __LL_RCC_CALC_MSI_FREQ(LL_RCC_MSI_GetRange());
2206       break;
2207 
2208     case LL_RCC_PLLSOURCE_HSI:  /* HSI used as PLLSAI1 clock source */
2209       pllinputfreq = HSI_VALUE;
2210       break;
2211 
2212     case LL_RCC_PLLSOURCE_HSE:  /* HSE used as PLLSAI1 clock source */
2213       if (LL_RCC_HSE_IsEnabledDiv2() == 1U)
2214       {
2215         pllinputfreq = HSE_VALUE / 2U;
2216       }
2217       else
2218       {
2219         pllinputfreq = HSE_VALUE;
2220       }
2221       break;
2222 
2223     default:
2224       pllinputfreq = __LL_RCC_CALC_MSI_FREQ(LL_RCC_MSI_GetRange());
2225       break;
2226   }
2227   return __LL_RCC_CALC_PLLSAI1_ADC_FREQ(pllinputfreq, LL_RCC_PLL_GetDivider(),
2228                                         LL_RCC_PLLSAI1_GetN(), LL_RCC_PLLSAI1_GetR());
2229 }
2230 
2231 /**
2232   * @brief  Return PLLSAI1 clock (PLLSAI1PCLK) frequency used for SAI domain
2233   * @retval PLLSAI1PCLK clock frequency (in Hz)
2234   */
RCC_PLLSAI1_GetFreqDomain_P(void)2235 static uint32_t RCC_PLLSAI1_GetFreqDomain_P(void)
2236 {
2237   uint32_t pllinputfreq;
2238   uint32_t pllsource;
2239 
2240   /* PLLSAI1_VCO = (HSE_VALUE or HSI_VALUE or MSI Value/ PLLM) * PLLSAI1N */
2241   /* SAI Domain clock  = PLLSAI1_VCO / PLLSAI1P */
2242   pllsource = LL_RCC_PLL_GetMainSource();
2243 
2244   switch (pllsource)
2245   {
2246     case LL_RCC_PLLSOURCE_MSI:  /* MSI used as PLLSAI1 clock source */
2247       pllinputfreq = __LL_RCC_CALC_MSI_FREQ(LL_RCC_MSI_GetRange());
2248       break;
2249 
2250     case LL_RCC_PLLSOURCE_HSI:  /* HSI used as PLLSAI1 clock source */
2251       pllinputfreq = HSI_VALUE;
2252       break;
2253 
2254     case LL_RCC_PLLSOURCE_HSE:  /* HSE used as PLLSAI1 clock source */
2255       if (LL_RCC_HSE_IsEnabledDiv2() == 1U)
2256       {
2257         pllinputfreq = HSE_VALUE / 2U;
2258       }
2259       else
2260       {
2261         pllinputfreq = HSE_VALUE;
2262       }
2263       break;
2264 
2265     default:
2266       pllinputfreq = __LL_RCC_CALC_MSI_FREQ(LL_RCC_MSI_GetRange());
2267       break;
2268   }
2269   return __LL_RCC_CALC_PLLSAI1_SAI_FREQ(pllinputfreq, LL_RCC_PLL_GetDivider(),
2270                                         LL_RCC_PLLSAI1_GetN(), LL_RCC_PLLSAI1_GetP());
2271 }
2272 
2273 /**
2274   * @brief  Return PLLSAI1 clock (PLLSAI1QCLK) frequency used for 48Mhz domain
2275   * @retval PLLSAI1QCLK clock frequency (in Hz)
2276   */
RCC_PLLSAI1_GetFreqDomain_Q(void)2277 static uint32_t RCC_PLLSAI1_GetFreqDomain_Q(void)
2278 {
2279   uint32_t pllinputfreq;
2280   uint32_t pllsource;
2281 
2282   /* PLLSAI1_VCO = (HSE_VALUE or HSI_VALUE or MSI Value/ PLLM) * PLLSAI1N */
2283   /* 48M Domain clock  = PLLSAI1_VCO / PLLSAI1Q */
2284   pllsource = LL_RCC_PLL_GetMainSource();
2285 
2286   switch (pllsource)
2287   {
2288     case LL_RCC_PLLSOURCE_MSI:  /* MSI used as PLLSAI1 clock source */
2289       pllinputfreq = __LL_RCC_CALC_MSI_FREQ(LL_RCC_MSI_GetRange());
2290       break;
2291 
2292     case LL_RCC_PLLSOURCE_HSI:  /* HSI used as PLLSAI1 clock source */
2293       pllinputfreq = HSI_VALUE;
2294       break;
2295 
2296     case LL_RCC_PLLSOURCE_HSE:  /* HSE used as PLLSAI1 clock source */
2297       if (LL_RCC_HSE_IsEnabledDiv2() == 1U)
2298       {
2299         pllinputfreq = HSE_VALUE / 2U;
2300       }
2301       else
2302       {
2303         pllinputfreq = HSE_VALUE;
2304       }
2305       break;
2306 
2307     default:
2308       pllinputfreq = __LL_RCC_CALC_MSI_FREQ(LL_RCC_MSI_GetRange());
2309       break;
2310   }
2311   return __LL_RCC_CALC_PLLSAI1_48M_FREQ(pllinputfreq, LL_RCC_PLL_GetDivider(),
2312                                         LL_RCC_PLLSAI1_GetN(), LL_RCC_PLLSAI1_GetQ());
2313 }
2314 #endif /* SAI1 */
2315 
2316 /**
2317   * @}
2318   */
2319 
2320 #endif /* HAL_RCC_MODULE_ENABLED */
2321 
2322 /**
2323   * @}
2324   */
2325 
2326 /**
2327   * @}
2328   */
2329