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