1 /**
2   ******************************************************************************
3   * @file    stm32l5xx_hal_rcc_ex.c
4   * @author  MCD Application Team
5   * @brief   Extended RCC HAL module driver.
6   *          This file provides firmware functions to manage the following
7   *          functionalities RCC extended peripheral:
8   *           + Extended Peripheral Control functions
9   *           + Extended Clock management functions
10   *           + Extended Clock Recovery System Control functions
11   *
12   ******************************************************************************
13   * @attention
14   *
15   * Copyright (c) 2019 STMicroelectronics.
16   * All rights reserved.
17   *
18   * This software is licensed under terms that can be found in the LICENSE file in
19   * the root directory of this software component.
20   * If no LICENSE file comes with this software, it is provided AS-IS.
21   ******************************************************************************
22   */
23 
24 /* Includes ------------------------------------------------------------------*/
25 #include "stm32l5xx_hal.h"
26 
27 /** @addtogroup STM32L5xx_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 #define PLLSAI1_TIMEOUT_VALUE    ((uint32_t)2U)    /* 2 ms (minimum Tick + 1) */
44 #define PLLSAI2_TIMEOUT_VALUE    ((uint32_t)2U)    /* 2 ms (minimum Tick + 1) */
45 #define PLL_TIMEOUT_VALUE        ((uint32_t)2U)    /* 2 ms (minimum Tick + 1) */
46 
47 #define DIVIDER_P_UPDATE          0U
48 #define DIVIDER_Q_UPDATE          1U
49 #define DIVIDER_R_UPDATE          2U
50 
51 #define PLLSAI1CFGR_PLLSAI1SRC_NONE  0U
52 #define PLLSAI1CFGR_PLLSAI1SRC_MSI   RCC_PLLSAI1CFGR_PLLSAI1SRC_0
53 #define PLLSAI1CFGR_PLLSAI1SRC_HSI   RCC_PLLSAI1CFGR_PLLSAI1SRC_1
54 #define PLLSAI1CFGR_PLLSAI1SRC_HSE   (RCC_PLLSAI1CFGR_PLLSAI1SRC_1 | RCC_PLLSAI1CFGR_PLLSAI1SRC_0)
55 
56 #define PLLSAI2CFGR_PLLSAI2SRC_NONE  0U
57 #define PLLSAI2CFGR_PLLSAI2SRC_MSI   RCC_PLLSAI2CFGR_PLLSAI2SRC_0
58 #define PLLSAI2CFGR_PLLSAI2SRC_HSI   RCC_PLLSAI2CFGR_PLLSAI2SRC_1
59 #define PLLSAI2CFGR_PLLSAI2SRC_HSE   (RCC_PLLSAI2CFGR_PLLSAI2SRC_1 | RCC_PLLSAI2CFGR_PLLSAI2SRC_0)
60 
61 #define __LSCO_CLK_ENABLE()       __HAL_RCC_GPIOA_CLK_ENABLE()
62 #define LSCO_GPIO_PORT            GPIOA
63 #define LSCO_PIN                  GPIO_PIN_2
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 static HAL_StatusTypeDef RCCEx_PLLSource_Enable(uint32_t PllSource);
75 static HAL_StatusTypeDef RCCEx_PLLSAI1_Config(RCC_PLLSAI1InitTypeDef *pPllSai1, uint32_t Divider);
76 static uint32_t          RCCEx_PLLSAI1_GetVCOFreq(void);
77 static HAL_StatusTypeDef RCCEx_PLLSAI2_Config(RCC_PLLSAI2InitTypeDef *pPllSai2, uint32_t Divider);
78 static uint32_t          RCCEx_PLLSAI2_GetVCOFreq(void);
79 static uint32_t          RCCEx_GetSAIxPeriphCLKFreq(uint32_t PeriphClk, uint32_t InputFrequency);
80 
81 /**
82   * @}
83   */
84 
85 /* Exported functions --------------------------------------------------------*/
86 
87 /** @defgroup RCCEx_Exported_Functions RCCEx Exported Functions
88   * @{
89   */
90 
91 /** @defgroup RCCEx_Exported_Functions_Group1 Extended Peripheral Control functions
92   *  @brief  Extended Peripheral Control functions
93   *
94 @verbatim
95  ===============================================================================
96                 ##### Extended Peripheral Control functions  #####
97  ===============================================================================
98     [..]
99     This subsection provides a set of functions allowing to control the RCC Clocks
100     frequencies.
101     [..]
102     (@) Important note: Care must be taken when HAL_RCCEx_PeriphCLKConfig() is used to
103         select the RTC clock source; in this case the Backup domain will be reset in
104         order to modify the RTC Clock source, as consequence RTC registers (including
105         the backup registers) are set to their reset values.
106 
107 @endverbatim
108   * @{
109   */
110 /**
111   * @brief  Initialize the RCC extended peripherals clocks according to the specified
112   *         parameters in the RCC_PeriphCLKInitTypeDef.
113   * @param  PeriphClkInit  pointer to an RCC_PeriphCLKInitTypeDef structure that
114   *         contains a field PeriphClockSelection which can be a combination of the following values:
115   *            @arg @ref RCC_PERIPHCLK_RTC  RTC peripheral clock
116   *            @arg @ref RCC_PERIPHCLK_ADC  ADC peripheral clock
117   *            @arg @ref RCC_PERIPHCLK_DFSDM1  DFSDM1 peripheral clock
118   *            @arg @ref RCC_PERIPHCLK_I2C1  I2C1 peripheral clock
119   *            @arg @ref RCC_PERIPHCLK_I2C2  I2C2 peripheral clock
120   *            @arg @ref RCC_PERIPHCLK_I2C3  I2C3 peripheral clock
121   *            @arg @ref RCC_PERIPHCLK_I2C4  I2C4 peripheral clock
122   *            @arg @ref RCC_PERIPHCLK_LPTIM1  LPTIM1 peripheral clock
123   *            @arg @ref RCC_PERIPHCLK_LPTIM2  LPTIM2 peripheral clock
124   *            @arg @ref RCC_PERIPHCLK_LPTIM3  LPTIM3 peripheral clock
125   *            @arg @ref RCC_PERIPHCLK_LPUART1  LPUART1 peripheral clock
126   *            @arg @ref RCC_PERIPHCLK_RNG  RNG peripheral clock
127   *            @arg @ref RCC_PERIPHCLK_SAI1  SAI1 peripheral clock
128   *            @arg @ref RCC_PERIPHCLK_SAI2  SAI2 peripheral clock
129   *            @arg @ref RCC_PERIPHCLK_SDMMC1  SDMMC1 peripheral clock
130   *            @arg @ref RCC_PERIPHCLK_USART1  USART1 peripheral clock
131   *            @arg @ref RCC_PERIPHCLK_USART2  USART1 peripheral clock
132   *            @arg @ref RCC_PERIPHCLK_USART3  USART1 peripheral clock
133   *            @arg @ref RCC_PERIPHCLK_UART4  UART4 peripheral clock
134   *            @arg @ref RCC_PERIPHCLK_UART5  UART5 peripheral clock
135   *            @arg @ref RCC_PERIPHCLK_USB  USB peripheral clock
136   *            @arg @ref RCC_PERIPHCLK_DFSDM1  DFSDM1 peripheral kernel clock
137   *            @arg @ref RCC_PERIPHCLK_DFSDM1AUDIO  DFSDM1 peripheral audio clock
138   *            @arg @ref RCC_PERIPHCLK_OSPI  OctoSPI peripheral clock
139   *            @arg @ref RCC_PERIPHCLK_FDCAN  FDCAN peripheral clock
140   *
141   * @note   Care must be taken when HAL_RCCEx_PeriphCLKConfig() is used to select
142   *         the RTC clock source: in this case the access to Backup domain is enabled.
143   *
144   * @retval HAL status
145   */
HAL_RCCEx_PeriphCLKConfig(RCC_PeriphCLKInitTypeDef * PeriphClkInit)146 HAL_StatusTypeDef HAL_RCCEx_PeriphCLKConfig(RCC_PeriphCLKInitTypeDef  *PeriphClkInit)
147 {
148   HAL_StatusTypeDef ret = HAL_OK;      /* Intermediate status */
149   HAL_StatusTypeDef status = HAL_OK;   /* Final status */
150   uint32_t tmpregister;
151   uint32_t tickstart;
152 
153   /* Check the parameters */
154   assert_param(IS_RCC_PERIPHCLOCK(PeriphClkInit->PeriphClockSelection));
155 
156   /*-------------------------- SAI1 clock source configuration ---------------------*/
157   if ((((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_SAI1) == RCC_PERIPHCLK_SAI1))
158   {
159     /* Check the parameters */
160     assert_param(IS_RCC_SAI1CLK(PeriphClkInit->Sai1ClockSelection));
161 
162     switch (PeriphClkInit->Sai1ClockSelection)
163     {
164       case RCC_SAI1CLKSOURCE_PLL:      /* PLL is used as clock source for SAI1*/
165         /* Enable SAI Clock output generated from System PLL . */
166         __HAL_RCC_PLLCLKOUT_ENABLE(RCC_PLL_SAI3CLK);
167         /* SAI1 clock source config set later after clock selection check */
168         break;
169 
170       case RCC_SAI1CLKSOURCE_PLLSAI1:  /* PLLSAI1 is used as clock source for SAI1*/
171         /* PLLSAI1 input clock, parameters M, N & P configuration and clock output (PLLSAI1ClockOut) */
172         ret = RCCEx_PLLSAI1_Config(&(PeriphClkInit->PLLSAI1), DIVIDER_P_UPDATE);
173         /* SAI1 clock source config set later after clock selection check */
174         break;
175 
176       case RCC_SAI1CLKSOURCE_PLLSAI2:  /* PLLSAI2 is used as clock source for SAI1*/
177         /* PLLSAI2 input clock, parameters M, N & P configuration clock output (PLLSAI2ClockOut) */
178         ret = RCCEx_PLLSAI2_Config(&(PeriphClkInit->PLLSAI2), DIVIDER_P_UPDATE);
179         /* SAI1 clock source config set later after clock selection check */
180         break;
181 
182       case RCC_SAI1CLKSOURCE_PIN:      /* External clock is used as source of SAI1 clock*/
183       case RCC_SAI1CLKSOURCE_HSI:      /* HSI is used as source of SAI1 clock*/
184         /* SAI1 clock source config set later after clock selection check */
185         break;
186 
187       default:
188         ret = HAL_ERROR;
189         break;
190     }
191 
192     if (ret == HAL_OK)
193     {
194       /* Set the source of SAI1 clock*/
195       __HAL_RCC_SAI1_CONFIG(PeriphClkInit->Sai1ClockSelection);
196     }
197     else
198     {
199       /* set overall return value */
200       status = ret;
201     }
202   }
203 
204   /*-------------------------- SAI2 clock source configuration ---------------------*/
205   if ((((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_SAI2) == RCC_PERIPHCLK_SAI2))
206   {
207     /* Check the parameters */
208     assert_param(IS_RCC_SAI2CLK(PeriphClkInit->Sai2ClockSelection));
209 
210     switch (PeriphClkInit->Sai2ClockSelection)
211     {
212       case RCC_SAI2CLKSOURCE_PLL:      /* PLL is used as clock source for SAI2*/
213         /* Enable SAI Clock output generated from System PLL . */
214         __HAL_RCC_PLLCLKOUT_ENABLE(RCC_PLL_SAI3CLK);
215         /* SAI2 clock source config set later after clock selection check */
216         break;
217 
218       case RCC_SAI2CLKSOURCE_PLLSAI1: /* PLLSAI1 is used as clock source for SAI2*/
219         /* PLLSAI1 input clock, parameters M, N & P configuration and clock output (PLLSAI1ClockOut) */
220         ret = RCCEx_PLLSAI1_Config(&(PeriphClkInit->PLLSAI1), DIVIDER_P_UPDATE);
221         /* SAI2 clock source config set later after clock selection check */
222         break;
223 
224       case RCC_SAI2CLKSOURCE_PLLSAI2:  /* PLLSAI2 is used as clock source for SAI2*/
225         /* PLLSAI2 input clock, parameters M, N & P configuration and clock output (PLLSAI2ClockOut) */
226         ret = RCCEx_PLLSAI2_Config(&(PeriphClkInit->PLLSAI2), DIVIDER_P_UPDATE);
227         /* SAI2 clock source config set later after clock selection check */
228         break;
229 
230       case RCC_SAI2CLKSOURCE_PIN:      /* External clock is used as source of SAI2 clock*/
231       case RCC_SAI2CLKSOURCE_HSI:      /* HSI is used as source of SAI2 clock*/
232         /* SAI2 clock source config set later after clock selection check */
233         break;
234 
235       default:
236         ret = HAL_ERROR;
237         break;
238     }
239 
240     if (ret == HAL_OK)
241     {
242       /* Set the source of SAI2 clock*/
243       __HAL_RCC_SAI2_CONFIG(PeriphClkInit->Sai2ClockSelection);
244     }
245     else
246     {
247       /* set overall return value */
248       status = ret;
249     }
250   }
251 
252   /*-------------------------- RTC clock source configuration ----------------------*/
253   if ((PeriphClkInit->PeriphClockSelection & RCC_PERIPHCLK_RTC) == RCC_PERIPHCLK_RTC)
254   {
255     FlagStatus       pwrclkchanged = RESET;
256 
257     /* Check for RTC Parameters used to output RTCCLK */
258     assert_param(IS_RCC_RTCCLKSOURCE(PeriphClkInit->RTCClockSelection));
259 
260     /* Enable Power Clock */
261     if (__HAL_RCC_PWR_IS_CLK_DISABLED())
262     {
263       __HAL_RCC_PWR_CLK_ENABLE();
264       pwrclkchanged = SET;
265     }
266 
267     /* Enable write access to Backup domain */
268     SET_BIT(PWR->CR1, PWR_CR1_DBP);
269 
270     /* Wait for Backup domain Write protection disable */
271     tickstart = HAL_GetTick();
272 
273     while ((PWR->CR1 & PWR_CR1_DBP) == 0U)
274     {
275       if ((HAL_GetTick() - tickstart) > RCC_DBP_TIMEOUT_VALUE)
276       {
277         /* New check to avoid false timeout detection in case of preemption */
278         if ((PWR->CR1 & PWR_CR1_DBP) == 0U)
279         {
280           ret = HAL_TIMEOUT;
281         }
282         break;
283       }
284     }
285 
286     if (ret == HAL_OK)
287     {
288       /* Reset the Backup domain only if the RTC Clock source selection is modified from default */
289       tmpregister = READ_BIT(RCC->BDCR, RCC_BDCR_RTCSEL);
290 
291       if ((tmpregister != RCC_RTCCLKSOURCE_NONE) && (tmpregister != PeriphClkInit->RTCClockSelection))
292       {
293         /* Store the content of BDCR register before the reset of Backup Domain */
294         tmpregister = READ_BIT(RCC->BDCR, ~(RCC_BDCR_RTCSEL));
295         /* RTC Clock selection can be changed only if the Backup Domain is reset */
296         __HAL_RCC_BACKUPRESET_FORCE();
297         __HAL_RCC_BACKUPRESET_RELEASE();
298         /* Restore the Content of BDCR register */
299         RCC->BDCR = tmpregister;
300       }
301 
302       /* Wait for LSE reactivation if LSE was enable prior to Backup Domain reset */
303       if (HAL_IS_BIT_SET(tmpregister, RCC_BDCR_LSEON))
304       {
305         /* Get Start Tick*/
306         tickstart = HAL_GetTick();
307 
308         /* Wait till LSE is ready */
309         while (READ_BIT(RCC->BDCR, RCC_BDCR_LSERDY) == 0U)
310         {
311           if ((HAL_GetTick() - tickstart) > RCC_LSE_TIMEOUT_VALUE)
312           {
313             /* New check to avoid false timeout detection in case of preemption */
314             if (READ_BIT(RCC->BDCR, RCC_BDCR_LSERDY) == 0U)
315             {
316               ret = HAL_TIMEOUT;
317             }
318             break;
319           }
320         }
321       }
322 
323       if (ret == HAL_OK)
324       {
325         /* Apply new RTC clock source selection */
326         __HAL_RCC_RTC_CONFIG(PeriphClkInit->RTCClockSelection);
327       }
328       else
329       {
330         /* set overall return value */
331         status = ret;
332       }
333     }
334     else
335     {
336       /* set overall return value */
337       status = ret;
338     }
339 
340     /* Restore clock configuration if changed */
341     if (pwrclkchanged == SET)
342     {
343       __HAL_RCC_PWR_CLK_DISABLE();
344     }
345   }
346 
347   /*-------------------------- USART1 clock source configuration -------------------*/
348   if (((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_USART1) == RCC_PERIPHCLK_USART1)
349   {
350     /* Check the parameters */
351     assert_param(IS_RCC_USART1CLKSOURCE(PeriphClkInit->Usart1ClockSelection));
352 
353     /* Configure the USART1 clock source */
354     __HAL_RCC_USART1_CONFIG(PeriphClkInit->Usart1ClockSelection);
355   }
356 
357   /*-------------------------- USART2 clock source configuration -------------------*/
358   if (((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_USART2) == RCC_PERIPHCLK_USART2)
359   {
360     /* Check the parameters */
361     assert_param(IS_RCC_USART2CLKSOURCE(PeriphClkInit->Usart2ClockSelection));
362 
363     /* Configure the USART2 clock source */
364     __HAL_RCC_USART2_CONFIG(PeriphClkInit->Usart2ClockSelection);
365   }
366 
367   /*-------------------------- USART3 clock source configuration -------------------*/
368   if (((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_USART3) == RCC_PERIPHCLK_USART3)
369   {
370     /* Check the parameters */
371     assert_param(IS_RCC_USART3CLKSOURCE(PeriphClkInit->Usart3ClockSelection));
372 
373     /* Configure the USART3 clock source */
374     __HAL_RCC_USART3_CONFIG(PeriphClkInit->Usart3ClockSelection);
375   }
376 
377   /*-------------------------- UART4 clock source configuration --------------------*/
378   if (((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_UART4) == RCC_PERIPHCLK_UART4)
379   {
380     /* Check the parameters */
381     assert_param(IS_RCC_UART4CLKSOURCE(PeriphClkInit->Uart4ClockSelection));
382 
383     /* Configure the UART4 clock source */
384     __HAL_RCC_UART4_CONFIG(PeriphClkInit->Uart4ClockSelection);
385   }
386 
387   /*-------------------------- UART5 clock source configuration --------------------*/
388   if (((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_UART5) == RCC_PERIPHCLK_UART5)
389   {
390     /* Check the parameters */
391     assert_param(IS_RCC_UART5CLKSOURCE(PeriphClkInit->Uart5ClockSelection));
392 
393     /* Configure the UART5 clock source */
394     __HAL_RCC_UART5_CONFIG(PeriphClkInit->Uart5ClockSelection);
395   }
396 
397   /*-------------------------- LPUART1 clock source configuration ------------------*/
398   if (((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_LPUART1) == RCC_PERIPHCLK_LPUART1)
399   {
400     /* Check the parameters */
401     assert_param(IS_RCC_LPUART1CLKSOURCE(PeriphClkInit->Lpuart1ClockSelection));
402 
403     /* Configure the LPUART1 clock source */
404     __HAL_RCC_LPUART1_CONFIG(PeriphClkInit->Lpuart1ClockSelection);
405   }
406 
407   /*-------------------------- LPTIM1 clock source configuration -------------------*/
408   if (((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_LPTIM1) == (RCC_PERIPHCLK_LPTIM1))
409   {
410     /* Check the parameters */
411     assert_param(IS_RCC_LPTIM1CLK(PeriphClkInit->Lptim1ClockSelection));
412 
413     /* Configure the LPTIM1 clock source */
414     __HAL_RCC_LPTIM1_CONFIG(PeriphClkInit->Lptim1ClockSelection);
415   }
416 
417   /*-------------------------- LPTIM2 clock source configuration -------------------*/
418   if (((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_LPTIM2) == (RCC_PERIPHCLK_LPTIM2))
419   {
420     /* Check the parameters */
421     assert_param(IS_RCC_LPTIM2CLK(PeriphClkInit->Lptim2ClockSelection));
422 
423     /* Configure the LPTIM2 clock source */
424     __HAL_RCC_LPTIM2_CONFIG(PeriphClkInit->Lptim2ClockSelection);
425   }
426 
427   /*-------------------------- LPTIM3 clock source configuration -------------------*/
428   if (((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_LPTIM3) == (RCC_PERIPHCLK_LPTIM3))
429   {
430     /* Check the parameters */
431     assert_param(IS_RCC_LPTIM3CLK(PeriphClkInit->Lptim3ClockSelection));
432 
433     /* Configure the LPTIM3 clock source */
434     __HAL_RCC_LPTIM3_CONFIG(PeriphClkInit->Lptim3ClockSelection);
435   }
436 
437   /*-------------------------- FDCAN kernel clock source configuration -------------*/
438   if (((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_FDCAN) == (RCC_PERIPHCLK_FDCAN))
439   {
440     /* Check the parameters */
441     assert_param(IS_RCC_FDCANCLK(PeriphClkInit->FdcanClockSelection));
442 
443     /* Configure the FDCAN kernel clock source */
444     switch (PeriphClkInit->FdcanClockSelection)
445     {
446       case RCC_FDCANCLKSOURCE_HSE:      /* HSE is used as source of FDCAN kernel clock*/
447         /* FDCAN kernel clock source config set later after clock selection check */
448         break;
449 
450       case RCC_FDCANCLKSOURCE_PLL:      /* PLL is used as clock source for FDCAN kernel clock*/
451         /* Enable PLL48M1CLK output clock generated from System PLL . */
452         __HAL_RCC_PLLCLKOUT_ENABLE(RCC_PLL_48M1CLK);
453         /* FDCAN kernel clock source config set later after clock selection check */
454         break;
455 
456       case RCC_FDCANCLKSOURCE_PLLSAI1:  /* PLLSAI1 is used as clock source for FDCAN kernel clock*/
457         /* PLLSAI1 input clock, parameters M, N & P configuration and clock output (PLLSAI1ClockOut) */
458         ret = RCCEx_PLLSAI1_Config(&(PeriphClkInit->PLLSAI1), DIVIDER_P_UPDATE);
459         /* FDCAN kernel clock source config set later after clock selection check */
460         break;
461 
462       default:
463         ret = HAL_ERROR;
464         break;
465     }
466 
467     if (ret == HAL_OK)
468     {
469       /* Set the source of FDCAN kernel clock*/
470       __HAL_RCC_FDCAN_CONFIG(PeriphClkInit->FdcanClockSelection);
471     }
472     else
473     {
474       /* set overall return value */
475       status = ret;
476     }
477   }
478 
479   /*-------------------------- I2C1 clock source configuration ---------------------*/
480   if (((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_I2C1) == RCC_PERIPHCLK_I2C1)
481   {
482     /* Check the parameters */
483     assert_param(IS_RCC_I2C1CLKSOURCE(PeriphClkInit->I2c1ClockSelection));
484 
485     /* Configure the I2C1 clock source */
486     __HAL_RCC_I2C1_CONFIG(PeriphClkInit->I2c1ClockSelection);
487   }
488 
489   /*-------------------------- I2C2 clock source configuration ---------------------*/
490   if (((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_I2C2) == RCC_PERIPHCLK_I2C2)
491   {
492     /* Check the parameters */
493     assert_param(IS_RCC_I2C2CLKSOURCE(PeriphClkInit->I2c2ClockSelection));
494 
495     /* Configure the I2C2 clock source */
496     __HAL_RCC_I2C2_CONFIG(PeriphClkInit->I2c2ClockSelection);
497   }
498 
499   /*-------------------------- I2C3 clock source configuration ---------------------*/
500   if (((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_I2C3) == RCC_PERIPHCLK_I2C3)
501   {
502     /* Check the parameters */
503     assert_param(IS_RCC_I2C3CLKSOURCE(PeriphClkInit->I2c3ClockSelection));
504 
505     /* Configure the I2C3 clock source */
506     __HAL_RCC_I2C3_CONFIG(PeriphClkInit->I2c3ClockSelection);
507   }
508 
509   /*-------------------------- I2C4 clock source configuration ---------------------*/
510   if (((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_I2C4) == RCC_PERIPHCLK_I2C4)
511   {
512     /* Check the parameters */
513     assert_param(IS_RCC_I2C4CLKSOURCE(PeriphClkInit->I2c4ClockSelection));
514 
515     /* Configure the I2C4 clock source */
516     __HAL_RCC_I2C4_CONFIG(PeriphClkInit->I2c4ClockSelection);
517   }
518 
519 #if defined(USB)
520 
521   /*-------------------------- USB clock source configuration ----------------------*/
522   if (((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_USB) == (RCC_PERIPHCLK_USB))
523   {
524     /* Check the parameters */
525     assert_param(IS_RCC_USBCLKSOURCE(PeriphClkInit->UsbClockSelection));
526 
527     /* Configure the USB clock source */
528     __HAL_RCC_USB_CONFIG(PeriphClkInit->UsbClockSelection);
529 
530     if (PeriphClkInit->UsbClockSelection == RCC_USBCLKSOURCE_PLL)
531     {
532       /* Enable PLL48M1CLK output clock */
533       __HAL_RCC_PLLCLKOUT_ENABLE(RCC_PLL_48M1CLK);
534     }
535     else
536     {
537       if (PeriphClkInit->UsbClockSelection == RCC_USBCLKSOURCE_PLLSAI1)
538       {
539         /* PLLSAI1 input clock, parameters M, N & Q configuration and clock output (PLLSAI1ClockOut) */
540         ret = RCCEx_PLLSAI1_Config(&(PeriphClkInit->PLLSAI1), DIVIDER_Q_UPDATE);
541 
542         if (ret != HAL_OK)
543         {
544           /* set overall return value */
545           status = ret;
546         }
547       }
548     }
549   }
550 
551 #endif /* USB */
552 
553   /*-------------------------- SDMMC1 clock source configuration -------------------*/
554   if (((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_SDMMC1) == (RCC_PERIPHCLK_SDMMC1))
555   {
556     /* Check the parameters */
557     assert_param(IS_RCC_SDMMC1CLKSOURCE(PeriphClkInit->Sdmmc1ClockSelection));
558 
559     /* Configure the SDMMC1 clock source */
560     __HAL_RCC_SDMMC1_CONFIG(PeriphClkInit->Sdmmc1ClockSelection);
561 
562     if (PeriphClkInit->Sdmmc1ClockSelection == RCC_SDMMC1CLKSOURCE_PLLSAI1)
563     {
564       /* PLLSAI1 input clock, parameters M, N & Q configuration and clock output (PLLSAI1ClockOut) */
565       ret = RCCEx_PLLSAI1_Config(&(PeriphClkInit->PLLSAI1), DIVIDER_Q_UPDATE);
566 
567       if (ret != HAL_OK)
568       {
569         /* set overall return value */
570         status = ret;
571       }
572     }
573     else if (PeriphClkInit->Sdmmc1ClockSelection == RCC_SDMMC1CLKSOURCE_PLL)
574     {
575       /* Enable PLL48M1CLK output clock */
576       __HAL_RCC_PLLCLKOUT_ENABLE(RCC_PLL_48M1CLK);
577     }
578     else if (PeriphClkInit->Sdmmc1ClockSelection == RCC_SDMMC1CLKSOURCE_PLLP)
579     {
580       /* Enable PLLSAI3CLK output clock */
581       __HAL_RCC_PLLCLKOUT_ENABLE(RCC_PLL_SAI3CLK);
582     }
583     else
584     {
585       /* Nothing to do */
586     }
587   }
588 
589   /*-------------------------- RNG clock source configuration ----------------------*/
590   if (((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_RNG) == (RCC_PERIPHCLK_RNG))
591   {
592     /* Check the parameters */
593     assert_param(IS_RCC_RNGCLKSOURCE(PeriphClkInit->RngClockSelection));
594 
595     /* Configure the RNG clock source */
596     __HAL_RCC_RNG_CONFIG(PeriphClkInit->RngClockSelection);
597 
598     if (PeriphClkInit->RngClockSelection == RCC_RNGCLKSOURCE_PLL)
599     {
600       /* Enable PLL48M1CLK output clock */
601       __HAL_RCC_PLLCLKOUT_ENABLE(RCC_PLL_48M1CLK);
602     }
603     else if (PeriphClkInit->RngClockSelection == RCC_RNGCLKSOURCE_PLLSAI1)
604     {
605       /* PLLSAI1 input clock, parameters M, N & Q configuration and clock output (PLLSAI1ClockOut) */
606       ret = RCCEx_PLLSAI1_Config(&(PeriphClkInit->PLLSAI1), DIVIDER_Q_UPDATE);
607 
608       if (ret != HAL_OK)
609       {
610         /* set overall return value */
611         status = ret;
612       }
613     }
614     else
615     {
616       /* Nothing to do */
617     }
618   }
619 
620   /*-------------------------- ADC clock source configuration ----------------------*/
621   if (((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_ADC) == RCC_PERIPHCLK_ADC)
622   {
623     /* Check the parameters */
624     assert_param(IS_RCC_ADCCLKSOURCE(PeriphClkInit->AdcClockSelection));
625 
626     /* Configure the ADC interface clock source */
627     __HAL_RCC_ADC_CONFIG(PeriphClkInit->AdcClockSelection);
628 
629     if (PeriphClkInit->AdcClockSelection == RCC_ADCCLKSOURCE_PLLSAI1)
630     {
631       /* PLLSAI1 input clock, parameters M, N & R configuration and clock output (PLLSAI1ClockOut) */
632       ret = RCCEx_PLLSAI1_Config(&(PeriphClkInit->PLLSAI1), DIVIDER_R_UPDATE);
633 
634       if (ret != HAL_OK)
635       {
636         /* set overall return value */
637         status = ret;
638       }
639     }
640   }
641 
642   /*-------------------------- DFSDM1 clock source configuration -------------------*/
643   if (((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_DFSDM1) == RCC_PERIPHCLK_DFSDM1)
644   {
645     /* Check the parameters */
646     assert_param(IS_RCC_DFSDM1CLKSOURCE(PeriphClkInit->Dfsdm1ClockSelection));
647 
648     /* Configure the DFSDM1 interface clock source */
649     __HAL_RCC_DFSDM1_CONFIG(PeriphClkInit->Dfsdm1ClockSelection);
650   }
651 
652   /*-------------------------- DFSDM1 audio clock source configuration -------------*/
653   if (((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_DFSDM1AUDIO) == RCC_PERIPHCLK_DFSDM1AUDIO)
654   {
655     /* Check the parameters */
656     assert_param(IS_RCC_DFSDM1AUDIOCLKSOURCE(PeriphClkInit->Dfsdm1AudioClockSelection));
657 
658     /* Configure the DFSDM1 interface audio clock source */
659     __HAL_RCC_DFSDM1AUDIO_CONFIG(PeriphClkInit->Dfsdm1AudioClockSelection);
660   }
661 
662   /*-------------------------- OctoSPIx clock source configuration ----------------*/
663   if (((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_OSPI) == RCC_PERIPHCLK_OSPI)
664   {
665     /* Check the parameters */
666     assert_param(IS_RCC_OSPICLKSOURCE(PeriphClkInit->OspiClockSelection));
667 
668     /* Configure the OctoSPI clock source */
669     __HAL_RCC_OSPI_CONFIG(PeriphClkInit->OspiClockSelection);
670 
671     if (PeriphClkInit->OspiClockSelection == RCC_OSPICLKSOURCE_PLL)
672     {
673       /* Enable PLL48M1CLK output clock */
674       __HAL_RCC_PLLCLKOUT_ENABLE(RCC_PLL_48M1CLK);
675     }
676   }
677 
678   return status;
679 }
680 
681 /**
682   * @brief  Get the RCC_ClkInitStruct according to the internal RCC configuration registers.
683   * @param  PeriphClkInit  pointer to an RCC_PeriphCLKInitTypeDef structure that
684   *         returns the configuration information for the Extended Peripherals
685   *         clocks(SAI1, SAI2, LPTIM1, LPTIM2, LPTIM3, I2C1, I2C2, I2C3, I2C4, LPUART1,
686   *         USART1, USART2, USART3, UART4, UART5, RTC, ADCx, DFSDMx, USB, SDMMC1, RNG and FDCAN).
687   * @retval None
688   */
HAL_RCCEx_GetPeriphCLKConfig(RCC_PeriphCLKInitTypeDef * PeriphClkInit)689 void HAL_RCCEx_GetPeriphCLKConfig(RCC_PeriphCLKInitTypeDef  *PeriphClkInit)
690 {
691   /* Set all possible values for the extended clock type parameter------------*/
692   PeriphClkInit->PeriphClockSelection = RCC_PERIPHCLK_USART1  | RCC_PERIPHCLK_USART2 | RCC_PERIPHCLK_USART3 | RCC_PERIPHCLK_UART4  | RCC_PERIPHCLK_UART5  | \
693                                         RCC_PERIPHCLK_LPUART1 | RCC_PERIPHCLK_I2C1   | RCC_PERIPHCLK_I2C2   | RCC_PERIPHCLK_I2C3   | RCC_PERIPHCLK_I2C4   | \
694                                         RCC_PERIPHCLK_LPTIM1  | RCC_PERIPHCLK_LPTIM2 | RCC_PERIPHCLK_LPTIM3 | RCC_PERIPHCLK_SAI1   | RCC_PERIPHCLK_SAI2   | \
695                                         RCC_PERIPHCLK_SDMMC1  | RCC_PERIPHCLK_RNG    | RCC_PERIPHCLK_ADC    | RCC_PERIPHCLK_USB    | RCC_PERIPHCLK_DFSDM1 | \
696                                         RCC_PERIPHCLK_DFSDM1AUDIO | RCC_PERIPHCLK_RTC | RCC_PERIPHCLK_OSPI  | RCC_PERIPHCLK_FDCAN;
697 
698   /* Get the PLLSAI1 Clock configuration -----------------------------------------------*/
699   PeriphClkInit->PLLSAI1.PLLSAI1Source = (uint32_t)((RCC->PLLSAI1CFGR & RCC_PLLSAI1CFGR_PLLSAI1SRC) >> RCC_PLLSAI1CFGR_PLLSAI1SRC_Pos);
700   PeriphClkInit->PLLSAI1.PLLSAI1M = (uint32_t)((RCC->PLLSAI1CFGR & RCC_PLLSAI1CFGR_PLLSAI1M) >> RCC_PLLSAI1CFGR_PLLSAI1M_Pos) + 1U;
701   PeriphClkInit->PLLSAI1.PLLSAI1N = (uint32_t)((RCC->PLLSAI1CFGR & RCC_PLLSAI1CFGR_PLLSAI1N) >> RCC_PLLSAI1CFGR_PLLSAI1N_Pos);
702   PeriphClkInit->PLLSAI1.PLLSAI1P = (uint32_t)(((RCC->PLLSAI1CFGR & RCC_PLLSAI1CFGR_PLLSAI1P) >> RCC_PLLSAI1CFGR_PLLSAI1P_Pos) << 4U) + 7U;
703   PeriphClkInit->PLLSAI1.PLLSAI1Q = (uint32_t)(((RCC->PLLSAI1CFGR & RCC_PLLSAI1CFGR_PLLSAI1Q) >> RCC_PLLSAI1CFGR_PLLSAI1Q_Pos) + 1U) * 2U;
704   PeriphClkInit->PLLSAI1.PLLSAI1R = (uint32_t)(((RCC->PLLSAI1CFGR & RCC_PLLSAI1CFGR_PLLSAI1R) >> RCC_PLLSAI1CFGR_PLLSAI1R_Pos) + 1U) * 2U;
705 
706   /* Get the PLLSAI2 Clock configuration -----------------------------------------------*/
707   PeriphClkInit->PLLSAI2.PLLSAI2Source = (uint32_t)((RCC->PLLSAI2CFGR & RCC_PLLSAI2CFGR_PLLSAI2SRC) >> RCC_PLLSAI2CFGR_PLLSAI2SRC_Pos);
708   PeriphClkInit->PLLSAI2.PLLSAI2M = (uint32_t)((RCC->PLLSAI2CFGR & RCC_PLLSAI2CFGR_PLLSAI2M) >> RCC_PLLSAI2CFGR_PLLSAI2M_Pos) + 1U;
709   PeriphClkInit->PLLSAI2.PLLSAI2N = (uint32_t)((RCC->PLLSAI2CFGR & RCC_PLLSAI2CFGR_PLLSAI2N) >> RCC_PLLSAI2CFGR_PLLSAI2N_Pos);
710   PeriphClkInit->PLLSAI2.PLLSAI2P = (uint32_t)(((RCC->PLLSAI2CFGR & RCC_PLLSAI2CFGR_PLLSAI2P) >> RCC_PLLSAI2CFGR_PLLSAI2P_Pos) << 4U) + 7U;
711 
712   /* Get the USART1 clock source ---------------------------------------------*/
713   PeriphClkInit->Usart1ClockSelection  = __HAL_RCC_GET_USART1_SOURCE();
714 
715   /* Get the USART2 clock source ---------------------------------------------*/
716   PeriphClkInit->Usart2ClockSelection  = __HAL_RCC_GET_USART2_SOURCE();
717 
718   /* Get the USART3 clock source ---------------------------------------------*/
719   PeriphClkInit->Usart3ClockSelection  = __HAL_RCC_GET_USART3_SOURCE();
720 
721   /* Get the UART4 clock source ----------------------------------------------*/
722   PeriphClkInit->Uart4ClockSelection   = __HAL_RCC_GET_UART4_SOURCE();
723 
724   /* Get the UART5 clock source ----------------------------------------------*/
725   PeriphClkInit->Uart5ClockSelection   = __HAL_RCC_GET_UART5_SOURCE();
726 
727   /* Get the LPUART1 clock source --------------------------------------------*/
728   PeriphClkInit->Lpuart1ClockSelection = __HAL_RCC_GET_LPUART1_SOURCE();
729 
730   /* Get the I2C1 clock source -----------------------------------------------*/
731   PeriphClkInit->I2c1ClockSelection    = __HAL_RCC_GET_I2C1_SOURCE();
732 
733   /* Get the I2C2 clock source ----------------------------------------------*/
734   PeriphClkInit->I2c2ClockSelection    = __HAL_RCC_GET_I2C2_SOURCE();
735 
736   /* Get the I2C3 clock source -----------------------------------------------*/
737   PeriphClkInit->I2c3ClockSelection    = __HAL_RCC_GET_I2C3_SOURCE();
738 
739   /* Get the I2C4 clock source -----------------------------------------------*/
740   PeriphClkInit->I2c4ClockSelection    = __HAL_RCC_GET_I2C4_SOURCE();
741 
742   /* Get the LPTIM1 clock source ---------------------------------------------*/
743   PeriphClkInit->Lptim1ClockSelection  = __HAL_RCC_GET_LPTIM1_SOURCE();
744 
745   /* Get the LPTIM2 clock source ---------------------------------------------*/
746   PeriphClkInit->Lptim2ClockSelection  = __HAL_RCC_GET_LPTIM2_SOURCE();
747 
748   /* Get the LPTIM3 clock source ---------------------------------------------*/
749   PeriphClkInit->Lptim3ClockSelection  = __HAL_RCC_GET_LPTIM3_SOURCE();
750 
751   /* Get the FDCAN kernel clock source ---------------------------------------*/
752   PeriphClkInit->FdcanClockSelection  = __HAL_RCC_GET_FDCAN_SOURCE();
753 
754   /* Get the SAI1 clock source -----------------------------------------------*/
755   PeriphClkInit->Sai1ClockSelection    = __HAL_RCC_GET_SAI1_SOURCE();
756 
757   /* Get the SAI2 clock source -----------------------------------------------*/
758   PeriphClkInit->Sai2ClockSelection    = __HAL_RCC_GET_SAI2_SOURCE();
759 
760   /* Get the RTC clock source ------------------------------------------------*/
761   PeriphClkInit->RTCClockSelection     = __HAL_RCC_GET_RTC_SOURCE();
762 
763 #if defined(USB)
764   /* Get the USB clock source ------------------------------------------------*/
765   PeriphClkInit->UsbClockSelection   = __HAL_RCC_GET_USB_SOURCE();
766 #endif /* USB */
767 
768   /* Get the SDMMC1 clock source ---------------------------------------------*/
769   PeriphClkInit->Sdmmc1ClockSelection   = __HAL_RCC_GET_SDMMC1_SOURCE();
770 
771   /* Get the RNG clock source ------------------------------------------------*/
772   PeriphClkInit->RngClockSelection   = __HAL_RCC_GET_RNG_SOURCE();
773 
774   /* Get the ADC clock source ------------------------------------------------*/
775   PeriphClkInit->AdcClockSelection     = __HAL_RCC_GET_ADC_SOURCE();
776 
777   /* Get the DFSDM1 clock source ---------------------------------------------*/
778   PeriphClkInit->Dfsdm1ClockSelection  = __HAL_RCC_GET_DFSDM1_SOURCE();
779 
780   /* Get the DFSDM1 audio clock source ---------------------------------------*/
781   PeriphClkInit->Dfsdm1AudioClockSelection  = __HAL_RCC_GET_DFSDM1AUDIO_SOURCE();
782 
783   /* Get the OctoSPIclock source --------------------------------------------*/
784   PeriphClkInit->OspiClockSelection = __HAL_RCC_GET_OSPI_SOURCE();
785 }
786 
787 /**
788   * @brief  Return the peripheral clock frequency for peripherals with clock source from PLLSAIs
789   * @note   Return 0 if peripheral clock identifier not managed by this API
790   * @param  PeriphClk  Peripheral clock identifier
791   *         This parameter can be one of the following values:
792   *            @arg @ref RCC_PERIPHCLK_RTC  RTC peripheral clock
793   *            @arg @ref RCC_PERIPHCLK_ADC  ADC peripheral clock
794   *            @arg @ref RCC_PERIPHCLK_DFSDM1  DFSDM1 peripheral clock
795   *            @arg @ref RCC_PERIPHCLK_I2C1  I2C1 peripheral clock
796   *            @arg @ref RCC_PERIPHCLK_I2C2  I2C2 peripheral clock
797   *            @arg @ref RCC_PERIPHCLK_I2C3  I2C3 peripheral clock
798   *            @arg @ref RCC_PERIPHCLK_I2C4  I2C4 peripheral clock
799   *            @arg @ref RCC_PERIPHCLK_LPTIM1  LPTIM1 peripheral clock
800   *            @arg @ref RCC_PERIPHCLK_LPTIM2  LPTIM2 peripheral clock
801   *            @arg @ref RCC_PERIPHCLK_LPTIM3  LPTIM3 peripheral clock
802   *            @arg @ref RCC_PERIPHCLK_LPUART1  LPUART1 peripheral clock
803   *            @arg @ref RCC_PERIPHCLK_RNG  RNG peripheral clock
804   *            @arg @ref RCC_PERIPHCLK_SAI1  SAI1 peripheral clock
805   *            @arg @ref RCC_PERIPHCLK_SAI2  SAI2 peripheral clock
806   *            @arg @ref RCC_PERIPHCLK_SDMMC1  SDMMC1 peripheral clock
807   *            @arg @ref RCC_PERIPHCLK_USART1  USART1 peripheral clock
808   *            @arg @ref RCC_PERIPHCLK_USART2  USART1 peripheral clock
809   *            @arg @ref RCC_PERIPHCLK_USART3  USART1 peripheral clock
810   *            @arg @ref RCC_PERIPHCLK_UART4  UART4 peripheral clock
811   *            @arg @ref RCC_PERIPHCLK_UART5  UART5 peripheral clock
812   *            @arg @ref RCC_PERIPHCLK_USB  USB peripheral clock
813   *            @arg @ref RCC_PERIPHCLK_FDCAN  FDCAN peripheral clock
814   * @retval Frequency in Hz
815   */
HAL_RCCEx_GetPeriphCLKFreq(uint32_t PeriphClk)816 uint32_t HAL_RCCEx_GetPeriphCLKFreq(uint32_t PeriphClk)
817 {
818   uint32_t frequency = 0U;   /* Default is 0 */
819   uint32_t srcclk;
820   uint32_t pllvco, plln, pllp;
821   uint32_t pll_oscsource;
822 
823   /* Check the parameters */
824   assert_param(IS_RCC_PERIPHCLOCK(PeriphClk));
825 
826   if (PeriphClk == RCC_PERIPHCLK_RTC)
827   {
828     /* Get the current RTC source */
829     srcclk = __HAL_RCC_GET_RTC_SOURCE();
830 
831     switch (srcclk)
832     {
833       case RCC_RTCCLKSOURCE_LSE:
834         /* Check if LSE is ready */
835         if (HAL_IS_BIT_SET(RCC->BDCR, RCC_BDCR_LSERDY))
836         {
837           frequency = LSE_VALUE;
838         }
839         break;
840       case RCC_RTCCLKSOURCE_LSI:
841         /* Check if LSI is ready */
842         if (HAL_IS_BIT_SET(RCC->CSR, RCC_CSR_LSIRDY))
843         {
844           frequency = LSI_VALUE;
845         }
846         break;
847       case RCC_RTCCLKSOURCE_HSE_DIV32:
848         /* Check if HSE is ready */
849         if (HAL_IS_BIT_SET(RCC->CR, RCC_CR_HSERDY))
850         {
851           frequency = HSE_VALUE / 32U;
852         }
853         break;
854       default:
855         /* No clock source, frequency default init at 0 */
856         break;
857     }
858   }
859   else
860   {
861     /* Other external peripheral clock source than RTC */
862     pll_oscsource = __HAL_RCC_GET_PLL_OSCSOURCE();
863 
864     /* Compute PLL clock input */
865     switch (pll_oscsource)
866     {
867       case RCC_PLLSOURCE_MSI:   /* MSI ? */
868         if (HAL_IS_BIT_SET(RCC->CR, RCC_CR_MSIRDY))
869         {
870           /*MSI frequency range in HZ*/
871           pllvco = MSIRangeTable[(__HAL_RCC_GET_MSI_RANGE() >> 4U)];
872         }
873         else
874         {
875           pllvco = 0U;
876         }
877         break;
878       case RCC_PLLSOURCE_HSI:   /* HSI ? */
879         if (HAL_IS_BIT_SET(RCC->CR, RCC_CR_HSIRDY))
880         {
881           pllvco = HSI_VALUE;
882         }
883         else
884         {
885           pllvco = 0U;
886         }
887         break;
888       case RCC_PLLSOURCE_HSE:   /* HSE ? */
889         if (HAL_IS_BIT_SET(RCC->CR, RCC_CR_HSERDY))
890         {
891           pllvco = HSE_VALUE;
892         }
893         else
894         {
895           pllvco = 0U;
896         }
897         break;
898       default:
899         /* No source */
900         pllvco = 0U;
901         break;
902     }
903 
904     switch (PeriphClk)
905     {
906       case RCC_PERIPHCLK_SAI1:
907         frequency = RCCEx_GetSAIxPeriphCLKFreq(RCC_PERIPHCLK_SAI1, pllvco);
908         break;
909 
910       case RCC_PERIPHCLK_SAI2:
911         frequency = RCCEx_GetSAIxPeriphCLKFreq(RCC_PERIPHCLK_SAI2, pllvco);
912         break;
913 
914 #if defined(USB)
915 
916       case RCC_PERIPHCLK_USB:
917 
918 #endif /* USB */
919 
920       case RCC_PERIPHCLK_RNG:
921 
922         srcclk = READ_BIT(RCC->CCIPR1, RCC_CCIPR1_CLK48MSEL);
923 
924         switch (srcclk)
925         {
926           case RCC_CCIPR1_CLK48MSEL:   /* MSI ? */
927             if (HAL_IS_BIT_SET(RCC->CR, RCC_CR_MSIRDY))
928             {
929               /*MSI frequency range in HZ*/
930               frequency = MSIRangeTable[(__HAL_RCC_GET_MSI_RANGE() >> 4U)];
931             }
932             break;
933           case RCC_CCIPR1_CLK48MSEL_1:  /* PLL "Q" ? */
934             if (HAL_IS_BIT_SET(RCC->CR, RCC_CR_PLLRDY))
935             {
936               if (HAL_IS_BIT_SET(RCC->PLLCFGR, RCC_PLLCFGR_PLLQEN))
937               {
938                 /* f(PLL Source) / PLLM */
939                 pllvco = (pllvco / ((READ_BIT(RCC->PLLCFGR, RCC_PLLCFGR_PLLM) >> RCC_PLLCFGR_PLLM_Pos) + 1U));
940                 /* f(PLL48M1CLK) = f(VCO input) * PLLN / PLLQ */
941                 plln = READ_BIT(RCC->PLLCFGR, RCC_PLLCFGR_PLLN) >> RCC_PLLCFGR_PLLN_Pos;
942                 frequency = (pllvco * plln) / (((READ_BIT(RCC->PLLCFGR, RCC_PLLCFGR_PLLQ) >> RCC_PLLCFGR_PLLQ_Pos) + 1U) << 1U);
943               }
944             }
945             break;
946           case RCC_CCIPR1_CLK48MSEL_0:  /* PLLSAI1 ? */
947             if (HAL_IS_BIT_SET(RCC->CR, RCC_CR_PLLSAI1RDY))
948             {
949               if (HAL_IS_BIT_SET(RCC->PLLSAI1CFGR, RCC_PLLSAI1CFGR_PLLSAI1QEN))
950               {
951                 /* Get f(PLLSAI1 source) */
952                 pllvco = RCCEx_PLLSAI1_GetVCOFreq();
953                 /* f(PLLSAI1 Source) / PLLSAI1M */
954                 pllvco = (pllvco / ((READ_BIT(RCC->PLLSAI1CFGR, RCC_PLLSAI1CFGR_PLLSAI1M) >> RCC_PLLSAI1CFGR_PLLSAI1M_Pos) + 1U));
955                 /* f(PLL48M2CLK) = f(VCOSAI1 input) * PLLSAI1N / PLLSAI1Q */
956                 plln = READ_BIT(RCC->PLLSAI1CFGR, RCC_PLLSAI1CFGR_PLLSAI1N) >> RCC_PLLSAI1CFGR_PLLSAI1N_Pos;
957                 frequency = (pllvco * plln) / (((READ_BIT(RCC->PLLSAI1CFGR, RCC_PLLSAI1CFGR_PLLSAI1Q) >> RCC_PLLSAI1CFGR_PLLSAI1Q_Pos) + 1U) << 1U);
958               }
959             }
960             break;
961           case 0U:
962             if (HAL_IS_BIT_SET(RCC->CRRCR, RCC_CRRCR_HSI48RDY)) /* HSI48 ? */
963             {
964               frequency = HSI48_VALUE;
965             }
966             break;
967           default:
968             /* No clock source, frequency default init at 0 */
969             break;
970         } /* switch(srcclk) */
971 
972         break;
973 
974       case RCC_PERIPHCLK_SDMMC1:
975 
976         if (HAL_IS_BIT_SET(RCC->CCIPR2, RCC_CCIPR2_SDMMCSEL)) /* PLLP ? */
977         {
978           if (HAL_IS_BIT_SET(RCC->CR, RCC_CR_PLLRDY))
979           {
980             if (HAL_IS_BIT_SET(RCC->PLLCFGR, RCC_PLLCFGR_PLLPEN))
981             {
982               /* f(PLL Source) / PLLM */
983               pllvco = (pllvco / ((READ_BIT(RCC->PLLCFGR, RCC_PLLCFGR_PLLM) >> RCC_PLLCFGR_PLLM_Pos) + 1U));
984               /* f(PLLSAI3CLK) = f(VCO input) * PLLN / PLLP */
985               plln = READ_BIT(RCC->PLLCFGR, RCC_PLLCFGR_PLLN) >> RCC_PLLCFGR_PLLN_Pos;
986               pllp = READ_BIT(RCC->PLLCFGR, RCC_PLLCFGR_PLLPDIV) >> RCC_PLLCFGR_PLLPDIV_Pos;
987               if (pllp == 0U)
988               {
989                 if (READ_BIT(RCC->PLLCFGR, RCC_PLLCFGR_PLLP) != 0U)
990                 {
991                   pllp = 17U;
992                 }
993                 else
994                 {
995                   pllp = 7U;
996                 }
997               }
998               frequency = (pllvco * plln) / pllp;
999             }
1000           }
1001         }
1002         else  /* 48MHz from MSI or PLLSAI1Q or PLLQ or HSI48 */
1003         {
1004           srcclk = READ_BIT(RCC->CCIPR1, RCC_CCIPR1_CLK48MSEL);
1005 
1006           switch (srcclk)
1007           {
1008             case RCC_CCIPR1_CLK48MSEL:   /* MSI ? */
1009               if (HAL_IS_BIT_SET(RCC->CR, RCC_CR_MSIRDY))
1010               {
1011                 /*MSI frequency range in HZ*/
1012                 frequency = MSIRangeTable[(__HAL_RCC_GET_MSI_RANGE() >> 4U)];
1013               }
1014               break;
1015             case RCC_CCIPR1_CLK48MSEL_1:  /* PLL "Q" ? */
1016               if (HAL_IS_BIT_SET(RCC->CR, RCC_CR_PLLRDY))
1017               {
1018                 if (HAL_IS_BIT_SET(RCC->PLLCFGR, RCC_PLLCFGR_PLLQEN))
1019                 {
1020                   /* f(PLL Source) / PLLM */
1021                   pllvco = (pllvco / ((READ_BIT(RCC->PLLCFGR, RCC_PLLCFGR_PLLM) >> RCC_PLLCFGR_PLLM_Pos) + 1U));
1022                   /* f(PLL48M1CLK) = f(VCO input) * PLLN / PLLQ */
1023                   plln = READ_BIT(RCC->PLLCFGR, RCC_PLLCFGR_PLLN) >> RCC_PLLCFGR_PLLN_Pos;
1024                   frequency = (pllvco * plln) / (((READ_BIT(RCC->PLLCFGR, RCC_PLLCFGR_PLLQ) >> RCC_PLLCFGR_PLLQ_Pos) + 1U) << 1U);
1025                 }
1026               }
1027               break;
1028             case RCC_CCIPR1_CLK48MSEL_0:  /* PLLSAI1 ? */
1029               if (HAL_IS_BIT_SET(RCC->CR, RCC_CR_PLLSAI1RDY))
1030               {
1031                 if (HAL_IS_BIT_SET(RCC->PLLSAI1CFGR, RCC_PLLSAI1CFGR_PLLSAI1QEN))
1032                 {
1033                   /* Get f(PLLSAI1 source) */
1034                   pllvco = RCCEx_PLLSAI1_GetVCOFreq();
1035                   /* f(PLLSAI1 Source) / PLLSAI1M */
1036                   pllvco = (pllvco / ((READ_BIT(RCC->PLLSAI1CFGR, RCC_PLLSAI1CFGR_PLLSAI1M) >> RCC_PLLSAI1CFGR_PLLSAI1M_Pos) + 1U));
1037                   /* f(PLL48M2CLK) = f(VCOSAI1 input) * PLLSAI1N / PLLSAI1Q */
1038                   plln = READ_BIT(RCC->PLLSAI1CFGR, RCC_PLLSAI1CFGR_PLLSAI1N) >> RCC_PLLSAI1CFGR_PLLSAI1N_Pos;
1039                   frequency = (pllvco * plln) / (((READ_BIT(RCC->PLLSAI1CFGR, RCC_PLLSAI1CFGR_PLLSAI1Q) >> RCC_PLLSAI1CFGR_PLLSAI1Q_Pos) + 1U) << 1U);
1040                 }
1041               }
1042               break;
1043             case 0U:
1044               if (HAL_IS_BIT_SET(RCC->CRRCR, RCC_CRRCR_HSI48RDY)) /* HSI48 ? */
1045               {
1046                 frequency = HSI48_VALUE;
1047               }
1048               break;
1049             default:
1050               /* No clock source, frequency default init at 0 */
1051               break;
1052           } /* switch(srcclk) */
1053         }
1054 
1055         break;
1056 
1057       case RCC_PERIPHCLK_USART1:
1058 
1059         /* Get the current USART1 source */
1060         srcclk = __HAL_RCC_GET_USART1_SOURCE();
1061 
1062         switch (srcclk)
1063         {
1064           case RCC_USART1CLKSOURCE_PCLK2:
1065             frequency = HAL_RCC_GetPCLK2Freq();
1066             break;
1067           case RCC_USART1CLKSOURCE_SYSCLK:
1068             frequency = HAL_RCC_GetSysClockFreq();
1069             break;
1070           case RCC_USART1CLKSOURCE_HSI:
1071             if (HAL_IS_BIT_SET(RCC->CR, RCC_CR_HSIRDY))
1072             {
1073               frequency = HSI_VALUE;
1074             }
1075             break;
1076           case RCC_USART1CLKSOURCE_LSE:
1077             if (HAL_IS_BIT_SET(RCC->BDCR, RCC_BDCR_LSERDY))
1078             {
1079               frequency = LSE_VALUE;
1080             }
1081             break;
1082           default:
1083             /* No clock source, frequency default init at 0 */
1084             break;
1085         }
1086 
1087         break;
1088 
1089       case RCC_PERIPHCLK_USART2:
1090 
1091         /* Get the current USART2 source */
1092         srcclk = __HAL_RCC_GET_USART2_SOURCE();
1093 
1094         switch (srcclk)
1095         {
1096           case RCC_USART2CLKSOURCE_PCLK1:
1097             frequency = HAL_RCC_GetPCLK1Freq();
1098             break;
1099           case RCC_USART2CLKSOURCE_SYSCLK:
1100             frequency = HAL_RCC_GetSysClockFreq();
1101             break;
1102           case RCC_USART2CLKSOURCE_HSI:
1103             if (HAL_IS_BIT_SET(RCC->CR, RCC_CR_HSIRDY))
1104             {
1105               frequency = HSI_VALUE;
1106             }
1107             break;
1108           case RCC_USART2CLKSOURCE_LSE:
1109             if (HAL_IS_BIT_SET(RCC->BDCR, RCC_BDCR_LSERDY))
1110             {
1111               frequency = LSE_VALUE;
1112             }
1113             break;
1114           default:
1115             /* No clock source, frequency default init at 0 */
1116             break;
1117         }
1118 
1119         break;
1120 
1121       case RCC_PERIPHCLK_USART3:
1122 
1123         /* Get the current USART3 source */
1124         srcclk = __HAL_RCC_GET_USART3_SOURCE();
1125 
1126         switch (srcclk)
1127         {
1128           case RCC_USART3CLKSOURCE_PCLK1:
1129             frequency = HAL_RCC_GetPCLK1Freq();
1130             break;
1131           case RCC_USART3CLKSOURCE_SYSCLK:
1132             frequency = HAL_RCC_GetSysClockFreq();
1133             break;
1134           case RCC_USART3CLKSOURCE_HSI:
1135             if (HAL_IS_BIT_SET(RCC->CR, RCC_CR_HSIRDY))
1136             {
1137               frequency = HSI_VALUE;
1138             }
1139             break;
1140           case RCC_USART3CLKSOURCE_LSE:
1141             if (HAL_IS_BIT_SET(RCC->BDCR, RCC_BDCR_LSERDY))
1142             {
1143               frequency = LSE_VALUE;
1144             }
1145             break;
1146           default:
1147             /* No clock source, frequency default init at 0 */
1148             break;
1149         }
1150 
1151         break;
1152 
1153       case RCC_PERIPHCLK_UART4:
1154 
1155         /* Get the current UART4 source */
1156         srcclk = __HAL_RCC_GET_UART4_SOURCE();
1157 
1158         switch (srcclk)
1159         {
1160           case RCC_UART4CLKSOURCE_PCLK1:
1161             frequency = HAL_RCC_GetPCLK1Freq();
1162             break;
1163           case RCC_UART4CLKSOURCE_SYSCLK:
1164             frequency = HAL_RCC_GetSysClockFreq();
1165             break;
1166           case RCC_UART4CLKSOURCE_HSI:
1167             if (HAL_IS_BIT_SET(RCC->CR, RCC_CR_HSIRDY))
1168             {
1169               frequency = HSI_VALUE;
1170             }
1171             break;
1172           case RCC_UART4CLKSOURCE_LSE:
1173             if (HAL_IS_BIT_SET(RCC->BDCR, RCC_BDCR_LSERDY))
1174             {
1175               frequency = LSE_VALUE;
1176             }
1177             break;
1178           default:
1179             /* No clock source, frequency default init at 0 */
1180             break;
1181         }
1182 
1183         break;
1184 
1185       case RCC_PERIPHCLK_UART5:
1186 
1187         /* Get the current UART5 source */
1188         srcclk = __HAL_RCC_GET_UART5_SOURCE();
1189 
1190         switch (srcclk)
1191         {
1192           case RCC_UART5CLKSOURCE_PCLK1:
1193             frequency = HAL_RCC_GetPCLK1Freq();
1194             break;
1195           case RCC_UART5CLKSOURCE_SYSCLK:
1196             frequency = HAL_RCC_GetSysClockFreq();
1197             break;
1198           case RCC_UART5CLKSOURCE_HSI:
1199             if (HAL_IS_BIT_SET(RCC->CR, RCC_CR_HSIRDY))
1200             {
1201               frequency = HSI_VALUE;
1202             }
1203             break;
1204           case RCC_UART5CLKSOURCE_LSE:
1205             if (HAL_IS_BIT_SET(RCC->BDCR, RCC_BDCR_LSERDY))
1206             {
1207               frequency = LSE_VALUE;
1208             }
1209             break;
1210           default:
1211             /* No clock source, frequency default init at 0 */
1212             break;
1213         }
1214 
1215         break;
1216 
1217       case RCC_PERIPHCLK_LPUART1:
1218 
1219         /* Get the current LPUART1 source */
1220         srcclk = __HAL_RCC_GET_LPUART1_SOURCE();
1221 
1222         switch (srcclk)
1223         {
1224           case RCC_LPUART1CLKSOURCE_PCLK1:
1225             frequency = HAL_RCC_GetPCLK1Freq();
1226             break;
1227           case RCC_LPUART1CLKSOURCE_SYSCLK:
1228             frequency = HAL_RCC_GetSysClockFreq();
1229             break;
1230           case RCC_LPUART1CLKSOURCE_HSI:
1231             if (HAL_IS_BIT_SET(RCC->CR, RCC_CR_HSIRDY))
1232             {
1233               frequency = HSI_VALUE;
1234             }
1235             break;
1236           case RCC_LPUART1CLKSOURCE_LSE:
1237             if (HAL_IS_BIT_SET(RCC->BDCR, RCC_BDCR_LSERDY))
1238             {
1239               frequency = LSE_VALUE;
1240             }
1241             break;
1242           default:
1243             /* No clock source, frequency default init at 0 */
1244             break;
1245         }
1246 
1247         break;
1248 
1249       case RCC_PERIPHCLK_ADC:
1250 
1251         /* Get the current ADC source */
1252         srcclk = __HAL_RCC_GET_ADC_SOURCE();
1253 
1254         switch (srcclk)
1255         {
1256           case RCC_ADCCLKSOURCE_SYSCLK:
1257             frequency = HAL_RCC_GetSysClockFreq();
1258             break;
1259           case RCC_ADCCLKSOURCE_PLLSAI1:
1260             if (__HAL_RCC_GET_PLLSAI1CLKOUT_CONFIG(RCC_PLLSAI1_ADC1CLK) != 0U)
1261             {
1262               /* Get f(PLLSAI1 source) */
1263               pllvco = RCCEx_PLLSAI1_GetVCOFreq();
1264               /* f(PLLSAI1 Source) / PLLSAI1M */
1265               pllvco = (pllvco / ((READ_BIT(RCC->PLLSAI1CFGR, RCC_PLLSAI1CFGR_PLLSAI1M) >> RCC_PLLSAI1CFGR_PLLSAI1M_Pos) + 1U));
1266               /* f(PLLADC1CLK) = f(VCOSAI1 input) * PLLSAI1N / PLLSAI1R */
1267               plln = READ_BIT(RCC->PLLSAI1CFGR, RCC_PLLSAI1CFGR_PLLSAI1N) >> RCC_PLLSAI1CFGR_PLLSAI1N_Pos;
1268               frequency = (pllvco * plln) / (((READ_BIT(RCC->PLLSAI1CFGR, RCC_PLLSAI1CFGR_PLLSAI1R) >> RCC_PLLSAI1CFGR_PLLSAI1R_Pos) + 1U) << 1U);
1269             }
1270             break;
1271           default:
1272             /* No clock source, frequency default init at 0 */
1273             break;
1274         }
1275 
1276         break;
1277 
1278       case RCC_PERIPHCLK_DFSDM1:
1279 
1280         /* Get the current DFSDM1 source */
1281         srcclk = __HAL_RCC_GET_DFSDM1_SOURCE();
1282 
1283         if (srcclk == RCC_DFSDM1CLKSOURCE_PCLK2)
1284         {
1285           frequency = HAL_RCC_GetPCLK2Freq();
1286         }
1287         else
1288         {
1289           frequency = HAL_RCC_GetSysClockFreq();
1290         }
1291 
1292         break;
1293 
1294       case RCC_PERIPHCLK_DFSDM1AUDIO:
1295 
1296         /* Get the current DFSDM1 audio source */
1297         srcclk = __HAL_RCC_GET_DFSDM1AUDIO_SOURCE();
1298 
1299         switch (srcclk)
1300         {
1301           case RCC_DFSDM1AUDIOCLKSOURCE_SAI1:
1302             frequency = RCCEx_GetSAIxPeriphCLKFreq(RCC_PERIPHCLK_SAI1, pllvco);
1303             break;
1304           case RCC_DFSDM1AUDIOCLKSOURCE_MSI:
1305             if (HAL_IS_BIT_SET(RCC->CR, RCC_CR_MSIRDY))
1306             {
1307               /*MSI frequency range in HZ*/
1308               frequency = MSIRangeTable[(__HAL_RCC_GET_MSI_RANGE() >> 4U)];
1309             }
1310             break;
1311           case RCC_DFSDM1AUDIOCLKSOURCE_HSI:
1312             if (HAL_IS_BIT_SET(RCC->CR, RCC_CR_HSIRDY))
1313             {
1314               frequency = HSI_VALUE;
1315             }
1316             break;
1317           default:
1318             /* No clock source, frequency default init at 0 */
1319             break;
1320         }
1321 
1322         break;
1323 
1324       case RCC_PERIPHCLK_I2C1:
1325 
1326         /* Get the current I2C1 source */
1327         srcclk = __HAL_RCC_GET_I2C1_SOURCE();
1328 
1329         switch (srcclk)
1330         {
1331           case RCC_I2C1CLKSOURCE_PCLK1:
1332             frequency = HAL_RCC_GetPCLK1Freq();
1333             break;
1334           case RCC_I2C1CLKSOURCE_SYSCLK:
1335             frequency = HAL_RCC_GetSysClockFreq();
1336             break;
1337           case RCC_I2C1CLKSOURCE_HSI:
1338             if (HAL_IS_BIT_SET(RCC->CR, RCC_CR_HSIRDY))
1339             {
1340               frequency = HSI_VALUE;
1341             }
1342             break;
1343           default:
1344             /* No clock source, frequency default init at 0 */
1345             break;
1346         }
1347 
1348         break;
1349 
1350       case RCC_PERIPHCLK_I2C2:
1351 
1352         /* Get the current I2C2 source */
1353         srcclk = __HAL_RCC_GET_I2C2_SOURCE();
1354 
1355         switch (srcclk)
1356         {
1357           case RCC_I2C2CLKSOURCE_PCLK1:
1358             frequency = HAL_RCC_GetPCLK1Freq();
1359             break;
1360           case RCC_I2C2CLKSOURCE_SYSCLK:
1361             frequency = HAL_RCC_GetSysClockFreq();
1362             break;
1363           case RCC_I2C2CLKSOURCE_HSI:
1364             if (HAL_IS_BIT_SET(RCC->CR, RCC_CR_HSIRDY))
1365             {
1366               frequency = HSI_VALUE;
1367             }
1368             break;
1369           default:
1370             /* No clock source, frequency default init at 0 */
1371             break;
1372         }
1373 
1374         break;
1375 
1376       case RCC_PERIPHCLK_I2C3:
1377 
1378         /* Get the current I2C3 source */
1379         srcclk = __HAL_RCC_GET_I2C3_SOURCE();
1380 
1381         switch (srcclk)
1382         {
1383           case RCC_I2C3CLKSOURCE_PCLK1:
1384             frequency = HAL_RCC_GetPCLK1Freq();
1385             break;
1386           case RCC_I2C3CLKSOURCE_SYSCLK:
1387             frequency = HAL_RCC_GetSysClockFreq();
1388             break;
1389           case RCC_I2C3CLKSOURCE_HSI:
1390             if (HAL_IS_BIT_SET(RCC->CR, RCC_CR_HSIRDY))
1391             {
1392               frequency = HSI_VALUE;
1393             }
1394             break;
1395           default:
1396             /* No clock source, frequency default init at 0 */
1397             break;
1398         }
1399         break;
1400 
1401       case RCC_PERIPHCLK_I2C4:
1402 
1403         /* Get the current I2C4 source */
1404         srcclk = __HAL_RCC_GET_I2C4_SOURCE();
1405 
1406         switch (srcclk)
1407         {
1408           case RCC_I2C4CLKSOURCE_PCLK1:
1409             frequency = HAL_RCC_GetPCLK1Freq();
1410             break;
1411           case RCC_I2C4CLKSOURCE_SYSCLK:
1412             frequency = HAL_RCC_GetSysClockFreq();
1413             break;
1414           case RCC_I2C4CLKSOURCE_HSI:
1415             if (HAL_IS_BIT_SET(RCC->CR, RCC_CR_HSIRDY))
1416             {
1417               frequency = HSI_VALUE;
1418             }
1419             break;
1420           default:
1421             /* No clock source, frequency default init at 0 */
1422             break;
1423         }
1424 
1425         break;
1426 
1427       case RCC_PERIPHCLK_LPTIM1:
1428 
1429         /* Get the current LPTIM1 source */
1430         srcclk = __HAL_RCC_GET_LPTIM1_SOURCE();
1431 
1432         switch (srcclk)
1433         {
1434           case RCC_LPTIM1CLKSOURCE_PCLK1:
1435             frequency = HAL_RCC_GetPCLK1Freq();
1436             break;
1437           case RCC_LPTIM1CLKSOURCE_LSI:
1438             if (HAL_IS_BIT_SET(RCC->CSR, RCC_CSR_LSIRDY))
1439             {
1440               frequency = LSI_VALUE;
1441             }
1442             break;
1443           case RCC_LPTIM1CLKSOURCE_HSI:
1444             if (HAL_IS_BIT_SET(RCC->CR, RCC_CR_HSIRDY))
1445             {
1446               frequency = HSI_VALUE;
1447             }
1448             break;
1449           case RCC_LPTIM1CLKSOURCE_LSE:
1450             if (HAL_IS_BIT_SET(RCC->BDCR, RCC_BDCR_LSERDY))
1451             {
1452               frequency = LSE_VALUE;
1453             }
1454             break;
1455           default:
1456             /* No clock source, frequency default init at 0 */
1457             break;
1458         }
1459 
1460         break;
1461 
1462       case RCC_PERIPHCLK_LPTIM2:
1463 
1464         /* Get the current LPTIM2 source */
1465         srcclk = __HAL_RCC_GET_LPTIM2_SOURCE();
1466 
1467         switch (srcclk)
1468         {
1469           case RCC_LPTIM2CLKSOURCE_PCLK1:
1470             frequency = HAL_RCC_GetPCLK1Freq();
1471             break;
1472           case RCC_LPTIM2CLKSOURCE_LSI:
1473             if (HAL_IS_BIT_SET(RCC->CSR, RCC_CSR_LSIRDY))
1474             {
1475               frequency = LSI_VALUE;
1476             }
1477             break;
1478           case RCC_LPTIM2CLKSOURCE_HSI:
1479             if (HAL_IS_BIT_SET(RCC->CR, RCC_CR_HSIRDY))
1480             {
1481               frequency = HSI_VALUE;
1482             }
1483             break;
1484           case RCC_LPTIM2CLKSOURCE_LSE:
1485             if (HAL_IS_BIT_SET(RCC->BDCR, RCC_BDCR_LSERDY))
1486             {
1487               frequency = LSE_VALUE;
1488             }
1489             break;
1490           default:
1491             /* No clock source, frequency default init at 0 */
1492             break;
1493         }
1494 
1495         break;
1496 
1497       case RCC_PERIPHCLK_LPTIM3:
1498 
1499         /* Get the current LPTIM3 source */
1500         srcclk = __HAL_RCC_GET_LPTIM3_SOURCE();
1501 
1502         switch (srcclk)
1503         {
1504           case RCC_LPTIM3CLKSOURCE_PCLK1:
1505             frequency = HAL_RCC_GetPCLK1Freq();
1506             break;
1507           case RCC_LPTIM3CLKSOURCE_LSI:
1508             if (HAL_IS_BIT_SET(RCC->CSR, RCC_CSR_LSIRDY))
1509             {
1510               frequency = LSI_VALUE;
1511             }
1512             break;
1513           case RCC_LPTIM3CLKSOURCE_HSI:
1514             if (HAL_IS_BIT_SET(RCC->CR, RCC_CR_HSIRDY))
1515             {
1516               frequency = HSI_VALUE;
1517             }
1518             break;
1519           case RCC_LPTIM3CLKSOURCE_LSE:
1520             if (HAL_IS_BIT_SET(RCC->BDCR, RCC_BDCR_LSERDY))
1521             {
1522               frequency = LSE_VALUE;
1523             }
1524             break;
1525           default:
1526             /* No clock source, frequency default init at 0 */
1527             break;
1528         }
1529 
1530         break;
1531 
1532       case RCC_PERIPHCLK_FDCAN:
1533 
1534         /* Get the current FDCAN kernel source */
1535         srcclk = __HAL_RCC_GET_FDCAN_SOURCE();
1536 
1537         switch (srcclk)
1538         {
1539           case RCC_FDCANCLKSOURCE_HSE:
1540             if (HAL_IS_BIT_SET(RCC->CR, RCC_CR_HSERDY))
1541             {
1542               frequency = HSE_VALUE;
1543             }
1544             break;
1545 
1546           case RCC_FDCANCLKSOURCE_PLL:
1547             if (HAL_IS_BIT_SET(RCC->CR, RCC_CR_PLLRDY))
1548             {
1549               if (HAL_IS_BIT_SET(RCC->PLLCFGR, RCC_PLLCFGR_PLLQEN))
1550               {
1551                 /* f(PLL Source) / PLLM */
1552                 pllvco = (pllvco / ((READ_BIT(RCC->PLLCFGR, RCC_PLLCFGR_PLLM) >> RCC_PLLCFGR_PLLM_Pos) + 1U));
1553                 /* f(PLL48M1CLK) = f(VCO input) * PLLN / PLLQ */
1554                 plln = READ_BIT(RCC->PLLCFGR, RCC_PLLCFGR_PLLN) >> RCC_PLLCFGR_PLLN_Pos;
1555                 frequency = (pllvco * plln) / (((READ_BIT(RCC->PLLCFGR, RCC_PLLCFGR_PLLQ) >> RCC_PLLCFGR_PLLQ_Pos) + 1U) << 1U);
1556               }
1557             }
1558             break;
1559 
1560           case RCC_FDCANCLKSOURCE_PLLSAI1:
1561             if (__HAL_RCC_GET_PLLSAI1CLKOUT_CONFIG(RCC_PLLSAI1_SAI1CLK) != 0U)
1562             {
1563               /* Get f(PLLSAI1 source) */
1564               pllvco = RCCEx_PLLSAI1_GetVCOFreq();
1565               /* f(PLLSAI1 Source) / PLLSAI1M */
1566               pllvco = (pllvco / ((READ_BIT(RCC->PLLSAI1CFGR, RCC_PLLSAI1CFGR_PLLSAI1M) >> RCC_PLLSAI1CFGR_PLLSAI1M_Pos) + 1U));
1567               /* f(PLLSAI1CLK) = f(VCOSAI1 input) * PLLSAI1N / PLLSAI1P */
1568               plln = READ_BIT(RCC->PLLSAI1CFGR, RCC_PLLSAI1CFGR_PLLSAI1N) >> RCC_PLLSAI1CFGR_PLLSAI1N_Pos;
1569               pllp = READ_BIT(RCC->PLLSAI1CFGR, RCC_PLLSAI1CFGR_PLLSAI1PDIV) >> RCC_PLLSAI1CFGR_PLLSAI1PDIV_Pos;
1570               if (pllp == 0U)
1571               {
1572                 if (READ_BIT(RCC->PLLSAI1CFGR, RCC_PLLSAI1CFGR_PLLSAI1P) != 0U)
1573                 {
1574                   pllp = 17U;
1575                 }
1576                 else
1577                 {
1578                   pllp = 7U;
1579                 }
1580               }
1581               frequency = (pllvco * plln) / pllp;
1582             }
1583             break;
1584 
1585           default:
1586             /* No clock source, frequency default init at 0 */
1587             break;
1588         }
1589 
1590         break;
1591 
1592       default:
1593         /* Unexpected case, frequency default init at 0 */
1594         break;
1595     }
1596   }
1597 
1598   return (frequency);
1599 }
1600 
1601 /**
1602   * @}
1603   */
1604 
1605 /** @defgroup RCCEx_Exported_Functions_Group2 Extended Clock management functions
1606   *  @brief  Extended Clock management functions
1607   *
1608 @verbatim
1609  ===============================================================================
1610                 ##### Extended clock management functions  #####
1611  ===============================================================================
1612     [..]
1613     This subsection provides a set of functions allowing to control the
1614     activation or deactivation of MSI PLL-mode, PLLSAI1, PLLSAI2, CSS on LSE,
1615     low speed clock output and clock after wake-up from STOP mode.
1616 @endverbatim
1617   * @{
1618   */
1619 
1620 /**
1621   * @brief  Enable PLLSAI1.
1622   * @param  PLLSAI1Init  pointer to an RCC_PLLSAI1InitTypeDef structure that
1623   *         contains the configuration information for the PLLSAI1
1624   * @retval HAL status
1625   */
HAL_RCCEx_EnablePLLSAI1(RCC_PLLSAI1InitTypeDef * PLLSAI1Init)1626 HAL_StatusTypeDef HAL_RCCEx_EnablePLLSAI1(RCC_PLLSAI1InitTypeDef  *PLLSAI1Init)
1627 {
1628   HAL_StatusTypeDef status = HAL_OK;
1629   uint32_t tickstart;
1630 
1631   /* check for PLLSAI1 Parameters used to output PLLSAI1CLK */
1632   assert_param(IS_RCC_PLLSAI1SOURCE(PLLSAI1Init->PLLSAI1Source));
1633   assert_param(IS_RCC_PLLSAI1M_VALUE(PLLSAI1Init->PLLSAI1M));
1634   assert_param(IS_RCC_PLLSAI1N_VALUE(PLLSAI1Init->PLLSAI1N));
1635   assert_param(IS_RCC_PLLSAI1P_VALUE(PLLSAI1Init->PLLSAI1P));
1636   assert_param(IS_RCC_PLLSAI1Q_VALUE(PLLSAI1Init->PLLSAI1Q));
1637   assert_param(IS_RCC_PLLSAI1R_VALUE(PLLSAI1Init->PLLSAI1R));
1638   assert_param(IS_RCC_PLLSAI1CLOCKOUT_VALUE(PLLSAI1Init->PLLSAI1ClockOut));
1639 
1640   /* Disable the PLLSAI1 */
1641   __HAL_RCC_PLLSAI1_DISABLE();
1642 
1643   /* Get Start Tick*/
1644   tickstart = HAL_GetTick();
1645 
1646   /* Wait till PLLSAI1 is ready to be updated */
1647   while (READ_BIT(RCC->CR, RCC_CR_PLLSAI1RDY) != 0U)
1648   {
1649     if ((HAL_GetTick() - tickstart) > PLLSAI1_TIMEOUT_VALUE)
1650     {
1651       /* New check to avoid false timeout detection in case of preemption */
1652       if (READ_BIT(RCC->CR, RCC_CR_PLLSAI1RDY) != 0U)
1653       {
1654         status = HAL_TIMEOUT;
1655       }
1656       break;
1657     }
1658   }
1659 
1660   if (status == HAL_OK)
1661   {
1662     /* Make sure PLLSAI1Source is ready */
1663     status = RCCEx_PLLSource_Enable(PLLSAI1Init->PLLSAI1Source);
1664 
1665     if (status == HAL_OK)
1666     {
1667       /* Configure the PLLSAI1 clock source, multiplication factor N, */
1668       /* and division factors M, P, Q and R */
1669       __HAL_RCC_PLLSAI1_CONFIG(PLLSAI1Init->PLLSAI1Source, PLLSAI1Init->PLLSAI1M, PLLSAI1Init->PLLSAI1N,
1670                                PLLSAI1Init->PLLSAI1P, PLLSAI1Init->PLLSAI1Q, PLLSAI1Init->PLLSAI1R);
1671       /* Configure the PLLSAI1 Clock output(s) */
1672       __HAL_RCC_PLLSAI1CLKOUT_ENABLE(PLLSAI1Init->PLLSAI1ClockOut);
1673 
1674       /* Enable the PLLSAI1 again by setting PLLSAI1ON to 1*/
1675       __HAL_RCC_PLLSAI1_ENABLE();
1676 
1677       /* Get Start Tick*/
1678       tickstart = HAL_GetTick();
1679 
1680       /* Wait till PLLSAI1 is ready */
1681       while (READ_BIT(RCC->CR, RCC_CR_PLLSAI1RDY) == 0U)
1682       {
1683         if ((HAL_GetTick() - tickstart) > PLLSAI1_TIMEOUT_VALUE)
1684         {
1685           /* New check to avoid false timeout detection in case of preemption */
1686           if (READ_BIT(RCC->CR, RCC_CR_PLLSAI1RDY) == 0U)
1687           {
1688             status = HAL_TIMEOUT;
1689           }
1690           break;
1691         }
1692       }
1693     }
1694   }
1695 
1696   return status;
1697 }
1698 
1699 /**
1700   * @brief  Disable PLLSAI1.
1701   * @retval HAL status
1702   */
HAL_RCCEx_DisablePLLSAI1(void)1703 HAL_StatusTypeDef HAL_RCCEx_DisablePLLSAI1(void)
1704 {
1705   HAL_StatusTypeDef status = HAL_OK;
1706   uint32_t tickstart;
1707 
1708   /* Disable the PLLSAI1 */
1709   __HAL_RCC_PLLSAI1_DISABLE();
1710 
1711   /* Get Start Tick*/
1712   tickstart = HAL_GetTick();
1713 
1714   /* Wait till PLLSAI1 is ready */
1715   while (READ_BIT(RCC->CR, RCC_CR_PLLSAI1RDY) != 0U)
1716   {
1717     if ((HAL_GetTick() - tickstart) > PLLSAI1_TIMEOUT_VALUE)
1718     {
1719       /* New check to avoid false timeout detection in case of preemption */
1720       if (READ_BIT(RCC->CR, RCC_CR_PLLSAI1RDY) != 0U)
1721       {
1722         status = HAL_TIMEOUT;
1723       }
1724       break;
1725     }
1726   }
1727 
1728   /* To save power disable the PLLSAI1 Source and Clock outputs */
1729   CLEAR_BIT(RCC->PLLSAI1CFGR,
1730             RCC_PLLSAI1CFGR_PLLSAI1PEN | RCC_PLLSAI1CFGR_PLLSAI1QEN | RCC_PLLSAI1CFGR_PLLSAI1REN | RCC_PLLSAI1CFGR_PLLSAI1SRC);
1731 
1732   return status;
1733 }
1734 
1735 /**
1736   * @brief  Enable PLLSAI2.
1737   * @param  PLLSAI2Init  pointer to an RCC_PLLSAI2InitTypeDef structure that
1738   *         contains the configuration information for the PLLSAI2
1739   * @retval HAL status
1740   */
HAL_RCCEx_EnablePLLSAI2(RCC_PLLSAI2InitTypeDef * PLLSAI2Init)1741 HAL_StatusTypeDef HAL_RCCEx_EnablePLLSAI2(RCC_PLLSAI2InitTypeDef  *PLLSAI2Init)
1742 {
1743   HAL_StatusTypeDef status = HAL_OK;
1744   uint32_t tickstart;
1745 
1746   /* check for PLLSAI2 Parameters used to output PLLSAI2CLK */
1747   assert_param(IS_RCC_PLLSAI2SOURCE(PLLSAI2Init->PLLSAI2Source));
1748   assert_param(IS_RCC_PLLSAI2M_VALUE(PLLSAI2Init->PLLSAI2M));
1749   assert_param(IS_RCC_PLLSAI2N_VALUE(PLLSAI2Init->PLLSAI2N));
1750   assert_param(IS_RCC_PLLSAI2P_VALUE(PLLSAI2Init->PLLSAI2P));
1751   assert_param(IS_RCC_PLLSAI2CLOCKOUT_VALUE(PLLSAI2Init->PLLSAI2ClockOut));
1752 
1753   /* Disable the PLLSAI2 */
1754   __HAL_RCC_PLLSAI2_DISABLE();
1755 
1756   /* Get Start Tick*/
1757   tickstart = HAL_GetTick();
1758 
1759   /* Wait till PLLSAI2 is ready to be updated */
1760   while (READ_BIT(RCC->CR, RCC_CR_PLLSAI2RDY) != 0U)
1761   {
1762     if ((HAL_GetTick() - tickstart) > PLLSAI2_TIMEOUT_VALUE)
1763     {
1764       /* New check to avoid false timeout detection in case of preemption */
1765       if (READ_BIT(RCC->CR, RCC_CR_PLLSAI2RDY) != 0U)
1766       {
1767         status = HAL_TIMEOUT;
1768       }
1769       break;
1770     }
1771   }
1772 
1773   if (status == HAL_OK)
1774   {
1775     /* Make sure PLLSAI2Source is ready */
1776     status = RCCEx_PLLSource_Enable(PLLSAI2Init->PLLSAI2Source);
1777 
1778     if (status == HAL_OK)
1779     {
1780       /* Configure the PLLSAI2 clock source, multiplication factor N, */
1781       /* and division factors M and P */
1782       __HAL_RCC_PLLSAI2_CONFIG(PLLSAI2Init->PLLSAI2Source, PLLSAI2Init->PLLSAI2M, PLLSAI2Init->PLLSAI2N,
1783                                PLLSAI2Init->PLLSAI2P);
1784       /* Configure the PLLSAI2 Clock output(s) */
1785       __HAL_RCC_PLLSAI2CLKOUT_ENABLE(PLLSAI2Init->PLLSAI2ClockOut);
1786 
1787       /* Enable the PLLSAI2 again by setting PLLSAI2ON to 1*/
1788       __HAL_RCC_PLLSAI2_ENABLE();
1789 
1790       /* Get Start Tick*/
1791       tickstart = HAL_GetTick();
1792 
1793       /* Wait till PLLSAI2 is ready */
1794       while (READ_BIT(RCC->CR, RCC_CR_PLLSAI2RDY) == 0U)
1795       {
1796         if ((HAL_GetTick() - tickstart) > PLLSAI2_TIMEOUT_VALUE)
1797         {
1798           /* New check to avoid false timeout detection in case of preemption */
1799           if (READ_BIT(RCC->CR, RCC_CR_PLLSAI2RDY) == 0U)
1800           {
1801             status = HAL_TIMEOUT;
1802           }
1803           break;
1804         }
1805       }
1806     }
1807   }
1808 
1809   return status;
1810 }
1811 
1812 /**
1813   * @brief  Disable PLLISAI2.
1814   * @retval HAL status
1815   */
HAL_RCCEx_DisablePLLSAI2(void)1816 HAL_StatusTypeDef HAL_RCCEx_DisablePLLSAI2(void)
1817 {
1818   HAL_StatusTypeDef status = HAL_OK;
1819   uint32_t tickstart;
1820 
1821   /* Disable the PLLSAI2 */
1822   __HAL_RCC_PLLSAI2_DISABLE();
1823 
1824   /* Get Start Tick*/
1825   tickstart = HAL_GetTick();
1826 
1827   /* Wait till PLLSAI2 is ready */
1828   while (READ_BIT(RCC->CR, RCC_CR_PLLSAI2RDY) != 0U)
1829   {
1830     if ((HAL_GetTick() - tickstart) > PLLSAI2_TIMEOUT_VALUE)
1831     {
1832       /* New check to avoid false timeout detection in case of preemption */
1833       if (READ_BIT(RCC->CR, RCC_CR_PLLSAI2RDY) != 0U)
1834       {
1835         status = HAL_TIMEOUT;
1836       }
1837       break;
1838     }
1839   }
1840 
1841   /* To save power disable the PLLSAI2 Source and Clock outputs */
1842   CLEAR_BIT(RCC->PLLSAI2CFGR,
1843             RCC_PLLSAI2CFGR_PLLSAI2PEN | RCC_PLLSAI2CFGR_PLLSAI2SRC);
1844 
1845   return status;
1846 }
1847 
1848 /**
1849   * @brief  Configure the oscillator clock source for wakeup from Stop and CSS backup clock.
1850   * @param  WakeUpClk  Wakeup clock
1851   *         This parameter can be one of the following values:
1852   *            @arg @ref RCC_STOP_WAKEUPCLOCK_MSI  MSI oscillator selection
1853   *            @arg @ref RCC_STOP_WAKEUPCLOCK_HSI  HSI oscillator selection
1854   * @note   This function shall not be called after the Clock Security System on HSE has been
1855   *         enabled.
1856   * @retval None
1857   */
HAL_RCCEx_WakeUpStopCLKConfig(uint32_t WakeUpClk)1858 void HAL_RCCEx_WakeUpStopCLKConfig(uint32_t WakeUpClk)
1859 {
1860   assert_param(IS_RCC_STOP_WAKEUPCLOCK(WakeUpClk));
1861 
1862   __HAL_RCC_WAKEUPSTOP_CLK_CONFIG(WakeUpClk);
1863 }
1864 
1865 /**
1866   * @brief  Configure the MSI range after standby mode.
1867   * @note   After Standby its frequency can be selected between 4 possible values (1, 2, 4 or 8 MHz).
1868   * @param  MSIRange  MSI range
1869   *         This parameter can be one of the following values:
1870   *            @arg @ref RCC_MSIRANGE_4  Range 4 around 1 MHz
1871   *            @arg @ref RCC_MSIRANGE_5  Range 5 around 2 MHz
1872   *            @arg @ref RCC_MSIRANGE_6  Range 6 around 4 MHz (reset value)
1873   *            @arg @ref RCC_MSIRANGE_7  Range 7 around 8 MHz
1874   * @retval None
1875   */
HAL_RCCEx_StandbyMSIRangeConfig(uint32_t MSIRange)1876 void HAL_RCCEx_StandbyMSIRangeConfig(uint32_t MSIRange)
1877 {
1878   assert_param(IS_RCC_MSI_STANDBY_CLOCK_RANGE(MSIRange));
1879 
1880   __HAL_RCC_MSI_STANDBY_RANGE_CONFIG(MSIRange);
1881 }
1882 
1883 /**
1884   * @brief  Enable the Clock Security System on LSE.
1885   * @note   Prior to enable the Clock Security System on LSE, LSE oscillator is to be enabled
1886   *         with HAL_RCC_OscConfig() and the LSE oscillator clock is to be selected as RTC
1887   *         clock with HAL_RCCEx_PeriphCLKConfig().
1888   * @retval None
1889   */
HAL_RCCEx_EnableLSECSS(void)1890 void HAL_RCCEx_EnableLSECSS(void)
1891 {
1892   SET_BIT(RCC->BDCR, RCC_BDCR_LSECSSON);
1893 }
1894 
1895 /**
1896   * @brief  Disable the Clock Security System on LSE.
1897   * @note   LSE Clock Security System can only be disabled after a LSE failure detection.
1898   * @retval None
1899   */
HAL_RCCEx_DisableLSECSS(void)1900 void HAL_RCCEx_DisableLSECSS(void)
1901 {
1902   CLEAR_BIT(RCC->BDCR, RCC_BDCR_LSECSSON);
1903 }
1904 
1905 /**
1906   * @brief Handle the RCC Clock Security System on LSE interrupt request.
1907   * @retval None
1908   */
HAL_RCCEx_LSECSS_IRQHandler(void)1909 void HAL_RCCEx_LSECSS_IRQHandler(void)
1910 {
1911   /* Check RCC LSECSSD flag  */
1912   if (READ_BIT(RCC->BDCR, RCC_BDCR_LSECSSD) != 0U)
1913   {
1914     /* RCC LSE Clock Security System interrupt user callback */
1915     HAL_RCCEx_LSECSS_Callback();
1916   }
1917 }
1918 
1919 /**
1920   * @brief  RCCEx Clock Security System on LSE interrupt callback.
1921   * @retval none
1922   */
HAL_RCCEx_LSECSS_Callback(void)1923 __weak void HAL_RCCEx_LSECSS_Callback(void)
1924 {
1925   /* NOTE : This function should not be modified, when the callback is needed,
1926             the @ref HAL_RCCEx_LSECSS_Callback should be implemented in the user file
1927    */
1928 }
1929 
1930 /**
1931   * @brief  Select the Low Speed clock source to output on LSCO pin (PA2).
1932   * @param  LSCOSource  specifies the Low Speed clock source to output.
1933   *          This parameter can be one of the following values:
1934   *            @arg @ref RCC_LSCOSOURCE_LSI  LSI clock selected as LSCO source
1935   *            @arg @ref RCC_LSCOSOURCE_LSE  LSE clock selected as LSCO source
1936   * @retval None
1937   */
HAL_RCCEx_EnableLSCO(uint32_t LSCOSource)1938 void HAL_RCCEx_EnableLSCO(uint32_t LSCOSource)
1939 {
1940   GPIO_InitTypeDef GPIO_InitStruct;
1941   FlagStatus       pwrclkchanged = RESET;
1942   FlagStatus       backupchanged = RESET;
1943 
1944   /* Check the parameters */
1945   assert_param(IS_RCC_LSCOSOURCE(LSCOSource));
1946 
1947   /* LSCO Pin Clock Enable */
1948   __LSCO_CLK_ENABLE();
1949 
1950   /* Configure the LSCO pin in analog mode */
1951   GPIO_InitStruct.Pin = LSCO_PIN;
1952   GPIO_InitStruct.Mode = GPIO_MODE_ANALOG;
1953   GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;
1954   GPIO_InitStruct.Pull = GPIO_NOPULL;
1955   HAL_GPIO_Init(LSCO_GPIO_PORT, &GPIO_InitStruct);
1956 
1957   /* Update LSCOSEL clock source in Backup Domain control register */
1958   if (__HAL_RCC_PWR_IS_CLK_DISABLED())
1959   {
1960     __HAL_RCC_PWR_CLK_ENABLE();
1961     pwrclkchanged = SET;
1962   }
1963   if (HAL_IS_BIT_CLR(PWR->CR1, PWR_CR1_DBP))
1964   {
1965     HAL_PWR_EnableBkUpAccess();
1966     backupchanged = SET;
1967   }
1968 
1969   MODIFY_REG(RCC->BDCR, RCC_BDCR_LSCOSEL | RCC_BDCR_LSCOEN, LSCOSource | RCC_BDCR_LSCOEN);
1970 
1971   if (backupchanged == SET)
1972   {
1973     HAL_PWR_DisableBkUpAccess();
1974   }
1975   if (pwrclkchanged == SET)
1976   {
1977     __HAL_RCC_PWR_CLK_DISABLE();
1978   }
1979 }
1980 
1981 /**
1982   * @brief  Disable the Low Speed clock output.
1983   * @retval None
1984   */
HAL_RCCEx_DisableLSCO(void)1985 void HAL_RCCEx_DisableLSCO(void)
1986 {
1987   FlagStatus       pwrclkchanged = RESET;
1988   FlagStatus       backupchanged = RESET;
1989 
1990   /* Update LSCOEN bit in Backup Domain control register */
1991   if (__HAL_RCC_PWR_IS_CLK_DISABLED())
1992   {
1993     __HAL_RCC_PWR_CLK_ENABLE();
1994     pwrclkchanged = SET;
1995   }
1996   if (HAL_IS_BIT_CLR(PWR->CR1, PWR_CR1_DBP))
1997   {
1998     /* Enable access to the backup domain */
1999     HAL_PWR_EnableBkUpAccess();
2000     backupchanged = SET;
2001   }
2002 
2003   CLEAR_BIT(RCC->BDCR, RCC_BDCR_LSCOEN);
2004 
2005   /* Restore previous configuration */
2006   if (backupchanged == SET)
2007   {
2008     /* Disable access to the backup domain */
2009     HAL_PWR_DisableBkUpAccess();
2010   }
2011   if (pwrclkchanged == SET)
2012   {
2013     __HAL_RCC_PWR_CLK_DISABLE();
2014   }
2015 }
2016 
2017 /**
2018   * @brief  Enable the PLL-mode of the MSI.
2019   * @note   Prior to enable the PLL-mode of the MSI for automatic hardware
2020   *         calibration LSE oscillator is to be enabled with HAL_RCC_OscConfig().
2021   * @retval None
2022   */
HAL_RCCEx_EnableMSIPLLMode(void)2023 void HAL_RCCEx_EnableMSIPLLMode(void)
2024 {
2025   SET_BIT(RCC->CR, RCC_CR_MSIPLLEN) ;
2026 }
2027 
2028 /**
2029   * @brief  Disable the PLL-mode of the MSI.
2030   * @note   PLL-mode of the MSI is automatically reset when LSE oscillator is disabled
2031   *         of after a LSE failure.
2032   * @retval None
2033   */
HAL_RCCEx_DisableMSIPLLMode(void)2034 void HAL_RCCEx_DisableMSIPLLMode(void)
2035 {
2036   CLEAR_BIT(RCC->CR, RCC_CR_MSIPLLEN) ;
2037 }
2038 
2039 /**
2040   * @}
2041   */
2042 
2043 #if defined(CRS)
2044 
2045 /** @defgroup RCCEx_Exported_Functions_Group3 Extended Clock Recovery System Control functions
2046   *  @brief  Extended Clock Recovery System Control functions
2047   *
2048 @verbatim
2049  ===============================================================================
2050                 ##### Extended Clock Recovery System Control functions  #####
2051  ===============================================================================
2052     [..]
2053       For devices with Clock Recovery System feature (CRS), RCC Extension HAL driver can be used as follows:
2054 
2055       (#) In System clock config, HSI48 needs to be enabled
2056 
2057       (#) Enable CRS clock
2058 
2059       (#) Call CRS functions as follows:
2060           (##) Prepare synchronization configuration necessary for HSI48 calibration
2061               (+++) Default values can be set for frequency Error Measurement (reload and error limit)
2062                         and also HSI48 oscillator smooth trimming.
2063               (+++) Macro __HAL_RCC_CRS_RELOADVALUE_CALCULATE can be also used to calculate
2064                         directly reload value with target and synchronization frequencies values
2065           (##) Call function HAL_RCCEx_CRSConfig which
2066               (+++) Resets CRS registers to their default values.
2067               (+++) Configures CRS registers with synchronization configuration
2068               (+++) Enables automatic calibration and frequency error counter feature
2069            Note: When using USB LPM (Link Power Management) and the device is in Sleep mode, the
2070            periodic USB SOF will not be generated by the host. No SYNC signal will therefore be
2071            provided to the CRS to calibrate the HSI48 on the run. To guarantee the required clock
2072            precision after waking up from Sleep mode, the LSE or reference clock on the GPIOs
2073            should be used as SYNC signal.
2074 
2075           (##) A polling function is provided to wait for complete synchronization
2076               (+++) Call function HAL_RCCEx_CRSWaitSynchronization()
2077               (+++) According to CRS status, user can decide to adjust again the calibration or continue
2078                         application if synchronization is OK
2079 
2080       (#) User can retrieve information related to synchronization in calling function
2081             HAL_RCCEx_CRSGetSynchronizationInfo()
2082 
2083       (#) Regarding synchronization status and synchronization information, user can try a new calibration
2084            in changing synchronization configuration and call again HAL_RCCEx_CRSConfig.
2085            Note: When the SYNC event is detected during the downcounting phase (before reaching the zero value),
2086            it means that the actual frequency is lower than the target (and so, that the TRIM value should be
2087            incremented), while when it is detected during the upcounting phase it means that the actual frequency
2088            is higher (and that the TRIM value should be decremented).
2089 
2090       (#) In interrupt mode, user can resort to the available macros (__HAL_RCC_CRS_XXX_IT). Interrupts will go
2091           through CRS Handler (CRS_IRQn/CRS_IRQHandler)
2092               (++) Call function HAL_RCCEx_CRSConfig()
2093               (++) Enable CRS_IRQn (thanks to NVIC functions)
2094               (++) Enable CRS interrupt (__HAL_RCC_CRS_ENABLE_IT)
2095               (++) Implement CRS status management in the following user callbacks called from
2096                    HAL_RCCEx_CRS_IRQHandler():
2097                    (+++) HAL_RCCEx_CRS_SyncOkCallback()
2098                    (+++) HAL_RCCEx_CRS_SyncWarnCallback()
2099                    (+++) HAL_RCCEx_CRS_ExpectedSyncCallback()
2100                    (+++) HAL_RCCEx_CRS_ErrorCallback()
2101 
2102       (#) To force a SYNC EVENT, user can use the function HAL_RCCEx_CRSSoftwareSynchronizationGenerate().
2103           This function can be called before calling HAL_RCCEx_CRSConfig (for instance in Systick handler)
2104 
2105 @endverbatim
2106   * @{
2107   */
2108 
2109 /**
2110   * @brief  Start automatic synchronization for polling mode.
2111   * @param  pInit Pointer on RCC_CRSInitTypeDef structure
2112   * @retval None
2113   */
HAL_RCCEx_CRSConfig(RCC_CRSInitTypeDef * pInit)2114 void HAL_RCCEx_CRSConfig(RCC_CRSInitTypeDef *pInit)
2115 {
2116   uint32_t value;
2117 
2118   /* Check the parameters */
2119   assert_param(IS_RCC_CRS_SYNC_DIV(pInit->Prescaler));
2120   assert_param(IS_RCC_CRS_SYNC_SOURCE(pInit->Source));
2121   assert_param(IS_RCC_CRS_SYNC_POLARITY(pInit->Polarity));
2122   assert_param(IS_RCC_CRS_RELOADVALUE(pInit->ReloadValue));
2123   assert_param(IS_RCC_CRS_ERRORLIMIT(pInit->ErrorLimitValue));
2124   assert_param(IS_RCC_CRS_HSI48CALIBRATION(pInit->HSI48CalibrationValue));
2125 
2126   /* CONFIGURATION */
2127 
2128   /* Before configuration, reset CRS registers to their default values*/
2129   __HAL_RCC_CRS_FORCE_RESET();
2130   __HAL_RCC_CRS_RELEASE_RESET();
2131 
2132   /* Set the SYNCDIV[2:0] bits according to Prescaler value */
2133   /* Set the SYNCSRC[1:0] bits according to Source value */
2134   /* Set the SYNCSPOL bit according to Polarity value */
2135   value = (pInit->Prescaler | pInit->Source | pInit->Polarity);
2136   /* Set the RELOAD[15:0] bits according to ReloadValue value */
2137   value |= pInit->ReloadValue;
2138   /* Set the FELIM[7:0] bits according to ErrorLimitValue value */
2139   value |= (pInit->ErrorLimitValue << CRS_CFGR_FELIM_Pos);
2140   WRITE_REG(CRS->CFGR, value);
2141 
2142   /* Adjust HSI48 oscillator smooth trimming */
2143   /* Set the TRIM[6:0] bits according to RCC_CRS_HSI48CalibrationValue value */
2144   MODIFY_REG(CRS->CR, CRS_CR_TRIM, (pInit->HSI48CalibrationValue << CRS_CR_TRIM_Pos));
2145 
2146   /* START AUTOMATIC SYNCHRONIZATION*/
2147 
2148   /* Enable Automatic trimming & Frequency error counter */
2149   SET_BIT(CRS->CR, CRS_CR_AUTOTRIMEN | CRS_CR_CEN);
2150 }
2151 
2152 /**
2153   * @brief  Generate the software synchronization event.
2154   * @retval None
2155   */
HAL_RCCEx_CRSSoftwareSynchronizationGenerate(void)2156 void HAL_RCCEx_CRSSoftwareSynchronizationGenerate(void)
2157 {
2158   SET_BIT(CRS->CR, CRS_CR_SWSYNC);
2159 }
2160 
2161 /**
2162   * @brief  Return synchronization info.
2163   * @param  pSynchroInfo Pointer on RCC_CRSSynchroInfoTypeDef structure
2164   * @retval None
2165   */
HAL_RCCEx_CRSGetSynchronizationInfo(RCC_CRSSynchroInfoTypeDef * pSynchroInfo)2166 void HAL_RCCEx_CRSGetSynchronizationInfo(RCC_CRSSynchroInfoTypeDef *pSynchroInfo)
2167 {
2168   /* Check the parameter */
2169   assert_param(pSynchroInfo != (void *)NULL);
2170 
2171   /* Get the reload value */
2172   pSynchroInfo->ReloadValue = (uint32_t)(READ_BIT(CRS->CFGR, CRS_CFGR_RELOAD));
2173 
2174   /* Get HSI48 oscillator smooth trimming */
2175   pSynchroInfo->HSI48CalibrationValue = (uint32_t)(READ_BIT(CRS->CR, CRS_CR_TRIM) >> CRS_CR_TRIM_Pos);
2176 
2177   /* Get Frequency error capture */
2178   pSynchroInfo->FreqErrorCapture = (uint32_t)(READ_BIT(CRS->ISR, CRS_ISR_FECAP) >> CRS_ISR_FECAP_Pos);
2179 
2180   /* Get Frequency error direction */
2181   pSynchroInfo->FreqErrorDirection = (uint32_t)(READ_BIT(CRS->ISR, CRS_ISR_FEDIR));
2182 }
2183 
2184 /**
2185   * @brief Wait for CRS Synchronization status.
2186   * @param Timeout  Duration of the timeout
2187   * @note  Timeout is based on the maximum time to receive a SYNC event based on synchronization
2188   *        frequency.
2189   * @note    If Timeout set to HAL_MAX_DELAY, HAL_TIMEOUT will be never returned.
2190   * @retval Combination of Synchronization status
2191   *          This parameter can be a combination of the following values:
2192   *            @arg @ref RCC_CRS_TIMEOUT
2193   *            @arg @ref RCC_CRS_SYNCOK
2194   *            @arg @ref RCC_CRS_SYNCWARN
2195   *            @arg @ref RCC_CRS_SYNCERR
2196   *            @arg @ref RCC_CRS_SYNCMISS
2197   *            @arg @ref RCC_CRS_TRIMOVF
2198   */
HAL_RCCEx_CRSWaitSynchronization(uint32_t Timeout)2199 uint32_t HAL_RCCEx_CRSWaitSynchronization(uint32_t Timeout)
2200 {
2201   uint32_t crsstatus = RCC_CRS_NONE;
2202   uint32_t tickstart;
2203   HAL_StatusTypeDef status = HAL_OK;
2204 
2205   /* Get timeout */
2206   tickstart = HAL_GetTick();
2207 
2208   /* Wait for CRS flag or timeout detection */
2209   do
2210   {
2211     if (Timeout != HAL_MAX_DELAY)
2212     {
2213       if (((HAL_GetTick() - tickstart) > Timeout) || (Timeout == 0U))
2214       {
2215         status = HAL_TIMEOUT;
2216       }
2217     }
2218     /* Check CRS SYNCOK flag  */
2219     if (__HAL_RCC_CRS_GET_FLAG(RCC_CRS_FLAG_SYNCOK))
2220     {
2221       /* CRS SYNC event OK */
2222       crsstatus |= RCC_CRS_SYNCOK;
2223 
2224       /* Clear CRS SYNC event OK bit */
2225       __HAL_RCC_CRS_CLEAR_FLAG(RCC_CRS_FLAG_SYNCOK);
2226     }
2227 
2228     /* Check CRS SYNCWARN flag  */
2229     if (__HAL_RCC_CRS_GET_FLAG(RCC_CRS_FLAG_SYNCWARN))
2230     {
2231       /* CRS SYNC warning */
2232       crsstatus |= RCC_CRS_SYNCWARN;
2233 
2234       /* Clear CRS SYNCWARN bit */
2235       __HAL_RCC_CRS_CLEAR_FLAG(RCC_CRS_FLAG_SYNCWARN);
2236     }
2237 
2238     /* Check CRS TRIM overflow flag  */
2239     if (__HAL_RCC_CRS_GET_FLAG(RCC_CRS_FLAG_TRIMOVF))
2240     {
2241       /* CRS SYNC Error */
2242       crsstatus |= RCC_CRS_TRIMOVF;
2243 
2244       /* Clear CRS Error bit */
2245       __HAL_RCC_CRS_CLEAR_FLAG(RCC_CRS_FLAG_TRIMOVF);
2246     }
2247 
2248     /* Check CRS Error flag  */
2249     if (__HAL_RCC_CRS_GET_FLAG(RCC_CRS_FLAG_SYNCERR))
2250     {
2251       /* CRS SYNC Error */
2252       crsstatus |= RCC_CRS_SYNCERR;
2253 
2254       /* Clear CRS Error bit */
2255       __HAL_RCC_CRS_CLEAR_FLAG(RCC_CRS_FLAG_SYNCERR);
2256     }
2257 
2258     /* Check CRS SYNC Missed flag  */
2259     if (__HAL_RCC_CRS_GET_FLAG(RCC_CRS_FLAG_SYNCMISS))
2260     {
2261       /* CRS SYNC Missed */
2262       crsstatus |= RCC_CRS_SYNCMISS;
2263 
2264       /* Clear CRS SYNC Missed bit */
2265       __HAL_RCC_CRS_CLEAR_FLAG(RCC_CRS_FLAG_SYNCMISS);
2266     }
2267 
2268     /* Check CRS Expected SYNC flag  */
2269     if (__HAL_RCC_CRS_GET_FLAG(RCC_CRS_FLAG_ESYNC))
2270     {
2271       /* frequency error counter reached a zero value */
2272       __HAL_RCC_CRS_CLEAR_FLAG(RCC_CRS_FLAG_ESYNC);
2273     }
2274   } while ((crsstatus == RCC_CRS_NONE) && (status == HAL_OK));
2275 
2276   if (crsstatus == RCC_CRS_NONE)
2277   {
2278     crsstatus = RCC_CRS_TIMEOUT;
2279   }
2280 
2281   return crsstatus;
2282 }
2283 
2284 /**
2285   * @brief Handle the Clock Recovery System interrupt request.
2286   * @retval None
2287   */
HAL_RCCEx_CRS_IRQHandler(void)2288 void HAL_RCCEx_CRS_IRQHandler(void)
2289 {
2290   uint32_t crserror = RCC_CRS_NONE;
2291   /* Get current IT flags and IT sources values */
2292   uint32_t itflags = READ_REG(CRS->ISR);
2293   uint32_t itsources = READ_REG(CRS->CR);
2294 
2295   /* Check CRS SYNCOK flag  */
2296   if (((itflags & RCC_CRS_FLAG_SYNCOK) != 0U) && ((itsources & RCC_CRS_IT_SYNCOK) != 0U))
2297   {
2298     /* Clear CRS SYNC event OK flag */
2299     WRITE_REG(CRS->ICR, CRS_ICR_SYNCOKC);
2300 
2301     /* user callback */
2302     HAL_RCCEx_CRS_SyncOkCallback();
2303   }
2304   /* Check CRS SYNCWARN flag  */
2305   else if (((itflags & RCC_CRS_FLAG_SYNCWARN) != 0U) && ((itsources & RCC_CRS_IT_SYNCWARN) != 0U))
2306   {
2307     /* Clear CRS SYNCWARN flag */
2308     WRITE_REG(CRS->ICR, CRS_ICR_SYNCWARNC);
2309 
2310     /* user callback */
2311     HAL_RCCEx_CRS_SyncWarnCallback();
2312   }
2313   /* Check CRS Expected SYNC flag  */
2314   else if (((itflags & RCC_CRS_FLAG_ESYNC) != 0U) && ((itsources & RCC_CRS_IT_ESYNC) != 0U))
2315   {
2316     /* frequency error counter reached a zero value */
2317     WRITE_REG(CRS->ICR, CRS_ICR_ESYNCC);
2318 
2319     /* user callback */
2320     HAL_RCCEx_CRS_ExpectedSyncCallback();
2321   }
2322   /* Check CRS Error flags  */
2323   else
2324   {
2325     if (((itflags & RCC_CRS_FLAG_ERR) != 0U) && ((itsources & RCC_CRS_IT_ERR) != 0U))
2326     {
2327       if ((itflags & RCC_CRS_FLAG_SYNCERR) != 0U)
2328       {
2329         crserror |= RCC_CRS_SYNCERR;
2330       }
2331       if ((itflags & RCC_CRS_FLAG_SYNCMISS) != 0U)
2332       {
2333         crserror |= RCC_CRS_SYNCMISS;
2334       }
2335       if ((itflags & RCC_CRS_FLAG_TRIMOVF) != 0U)
2336       {
2337         crserror |= RCC_CRS_TRIMOVF;
2338       }
2339 
2340       /* Clear CRS Error flags */
2341       WRITE_REG(CRS->ICR, CRS_ICR_ERRC);
2342 
2343       /* user error callback */
2344       HAL_RCCEx_CRS_ErrorCallback(crserror);
2345     }
2346   }
2347 }
2348 
2349 /**
2350   * @brief  RCCEx Clock Recovery System SYNCOK interrupt callback.
2351   * @retval none
2352   */
HAL_RCCEx_CRS_SyncOkCallback(void)2353 __weak void HAL_RCCEx_CRS_SyncOkCallback(void)
2354 {
2355   /* NOTE : This function should not be modified, when the callback is needed,
2356             the @ref HAL_RCCEx_CRS_SyncOkCallback should be implemented in the user file
2357    */
2358 }
2359 
2360 /**
2361   * @brief  RCCEx Clock Recovery System SYNCWARN interrupt callback.
2362   * @retval none
2363   */
HAL_RCCEx_CRS_SyncWarnCallback(void)2364 __weak void HAL_RCCEx_CRS_SyncWarnCallback(void)
2365 {
2366   /* NOTE : This function should not be modified, when the callback is needed,
2367             the @ref HAL_RCCEx_CRS_SyncWarnCallback should be implemented in the user file
2368    */
2369 }
2370 
2371 /**
2372   * @brief  RCCEx Clock Recovery System Expected SYNC interrupt callback.
2373   * @retval none
2374   */
HAL_RCCEx_CRS_ExpectedSyncCallback(void)2375 __weak void HAL_RCCEx_CRS_ExpectedSyncCallback(void)
2376 {
2377   /* NOTE : This function should not be modified, when the callback is needed,
2378             the @ref HAL_RCCEx_CRS_ExpectedSyncCallback should be implemented in the user file
2379    */
2380 }
2381 
2382 /**
2383   * @brief  RCCEx Clock Recovery System Error interrupt callback.
2384   * @param  Error Combination of Error status.
2385   *         This parameter can be a combination of the following values:
2386   *           @arg @ref RCC_CRS_SYNCERR
2387   *           @arg @ref RCC_CRS_SYNCMISS
2388   *           @arg @ref RCC_CRS_TRIMOVF
2389   * @retval none
2390   */
HAL_RCCEx_CRS_ErrorCallback(uint32_t Error)2391 __weak void HAL_RCCEx_CRS_ErrorCallback(uint32_t Error)
2392 {
2393   /* Prevent unused argument(s) compilation warning */
2394   UNUSED(Error);
2395 
2396   /* NOTE : This function should not be modified, when the callback is needed,
2397             the @ref HAL_RCCEx_CRS_ErrorCallback should be implemented in the user file
2398    */
2399 }
2400 
2401 /**
2402   * @}
2403   */
2404 
2405 #endif /* CRS */
2406 
2407 /**
2408   * @}
2409   */
2410 
2411 /** @addtogroup RCCEx_Private_Functions
2412   * @{
2413   */
2414 
RCCEx_PLLSource_Enable(uint32_t PllSource)2415 static HAL_StatusTypeDef RCCEx_PLLSource_Enable(uint32_t PllSource)
2416 {
2417   HAL_StatusTypeDef status = HAL_OK;
2418   uint32_t tickstart;
2419 
2420   switch (PllSource)
2421   {
2422     case RCC_PLLSOURCE_MSI:
2423       /* Check whether MSI in not ready and enable it */
2424       if (READ_BIT(RCC->CR, RCC_CR_MSIRDY) == 0U)
2425       {
2426         /* Enable the Internal Multi Speed oscillator (MSI). */
2427         __HAL_RCC_MSI_ENABLE();
2428 
2429         /* Get timeout */
2430         tickstart = HAL_GetTick();
2431 
2432         /* Wait till MSI is ready */
2433         while (READ_BIT(RCC->CR, RCC_CR_MSIRDY) == 0U)
2434         {
2435           if ((HAL_GetTick() - tickstart) > MSI_TIMEOUT_VALUE)
2436           {
2437             /* New check to avoid false timeout detection in case of preemption */
2438             if (READ_BIT(RCC->CR, RCC_CR_MSIRDY) == 0U)
2439             {
2440               status = HAL_TIMEOUT;
2441             }
2442             break;
2443           }
2444         }
2445       }
2446       break;
2447 
2448     case RCC_PLLSOURCE_HSI:
2449       /* Check whether HSI in not ready and enable it */
2450       if (READ_BIT(RCC->CR, RCC_CR_HSIRDY) == 0U)
2451       {
2452         /* Enable the Internal High Speed oscillator (HSI). */
2453         __HAL_RCC_HSI_ENABLE();
2454 
2455         /* Get timeout */
2456         tickstart = HAL_GetTick();
2457 
2458         /* Wait till MSI is ready */
2459         while (READ_BIT(RCC->CR, RCC_CR_HSIRDY) == 0U)
2460         {
2461           if ((HAL_GetTick() - tickstart) > HSI_TIMEOUT_VALUE)
2462           {
2463             /* New check to avoid false timeout detection in case of preemption */
2464             if (READ_BIT(RCC->CR, RCC_CR_HSIRDY) == 0U)
2465             {
2466               status = HAL_TIMEOUT;
2467             }
2468             break;
2469           }
2470         }
2471       }
2472       break;
2473 
2474     case RCC_PLLSOURCE_HSE:
2475       /* Check whether HSE in not ready and enable it */
2476       if (READ_BIT(RCC->CR, RCC_CR_HSERDY) == 0U)
2477       {
2478         /* Enable the External High Speed oscillator (HSE). */
2479         SET_BIT(RCC->CR, RCC_CR_HSEON);
2480 
2481         /* Get Start Tick*/
2482         tickstart = HAL_GetTick();
2483 
2484         /* Wait till HSE is ready */
2485         while (READ_BIT(RCC->CR, RCC_CR_HSERDY) == 0U)
2486         {
2487           if ((HAL_GetTick() - tickstart) > HSE_TIMEOUT_VALUE)
2488           {
2489             /* New check to avoid false timeout detection in case of preemption */
2490             if (READ_BIT(RCC->CR, RCC_CR_HSERDY) == 0U)
2491             {
2492               status = HAL_TIMEOUT;
2493             }
2494             break;
2495           }
2496         }
2497       }
2498       break;
2499 
2500     case RCC_PLLSOURCE_NONE:
2501       /* Nothing to do */
2502       break;
2503 
2504     default:
2505       status = HAL_ERROR;
2506       break;
2507   }
2508 
2509   return status;
2510 }
2511 
2512 /**
2513   * @brief  Configure the parameters N & P & optionally M of PLLSAI1 and enable PLLSAI1 output clock(s).
2514   * @param  pPllSai1  pointer to an RCC_PLLSAI1InitTypeDef structure that
2515   *         contains the configuration parameters N & P & optionally M as well as PLLSAI1 output clock(s)
2516   * @param  Divider  divider parameter to be updated
2517   *
2518   * @note   PLLSAI1 is temporary disable to apply new parameters
2519   *
2520   * @retval HAL status
2521   */
RCCEx_PLLSAI1_Config(RCC_PLLSAI1InitTypeDef * pPllSai1,uint32_t Divider)2522 static HAL_StatusTypeDef RCCEx_PLLSAI1_Config(RCC_PLLSAI1InitTypeDef *pPllSai1, uint32_t Divider)
2523 {
2524   HAL_StatusTypeDef status = HAL_OK;
2525   uint32_t tickstart;
2526 
2527   /* check for PLLSAI1 Parameters used to output PLLSAI1CLK */
2528   /* P, Q and R dividers are verified in each specific divider case below */
2529   assert_param(IS_RCC_PLLSAI1SOURCE(pPllSai1->PLLSAI1Source));
2530   assert_param(IS_RCC_PLLSAI1M_VALUE(pPllSai1->PLLSAI1M));
2531   assert_param(IS_RCC_PLLSAI1N_VALUE(pPllSai1->PLLSAI1N));
2532   assert_param(IS_RCC_PLLSAI1CLOCKOUT_VALUE(pPllSai1->PLLSAI1ClockOut));
2533 
2534   /* Check PLLSAI1 clock source availability */
2535   switch (pPllSai1->PLLSAI1Source)
2536   {
2537     case RCC_PLLSOURCE_MSI:
2538       if (HAL_IS_BIT_CLR(RCC->CR, RCC_CR_MSIRDY))
2539       {
2540         status = HAL_ERROR;
2541       }
2542       break;
2543     case RCC_PLLSOURCE_HSI:
2544       if (HAL_IS_BIT_CLR(RCC->CR, RCC_CR_HSIRDY))
2545       {
2546         status = HAL_ERROR;
2547       }
2548       break;
2549     case RCC_PLLSOURCE_HSE:
2550       if (HAL_IS_BIT_CLR(RCC->CR, (RCC_CR_HSERDY | RCC_CR_HSEBYP)))
2551       {
2552         status = HAL_ERROR;
2553       }
2554       break;
2555     default:
2556       status = HAL_ERROR;
2557       break;
2558   }
2559 
2560   if (status == HAL_OK)
2561   {
2562     /* Disable the PLLSAI1 */
2563     __HAL_RCC_PLLSAI1_DISABLE();
2564 
2565     /* Get Start Tick*/
2566     tickstart = HAL_GetTick();
2567 
2568     /* Wait till PLLSAI1 is ready to be updated */
2569     while (READ_BIT(RCC->CR, RCC_CR_PLLSAI1RDY) != 0U)
2570     {
2571       if ((HAL_GetTick() - tickstart) > PLLSAI1_TIMEOUT_VALUE)
2572       {
2573         /* New check to avoid false timeout detection in case of preemption */
2574         if (READ_BIT(RCC->CR, RCC_CR_PLLSAI1RDY) != 0U)
2575         {
2576           status = HAL_TIMEOUT;
2577         }
2578         break;
2579       }
2580     }
2581 
2582     if (status == HAL_OK)
2583     {
2584       if (Divider == DIVIDER_P_UPDATE)
2585       {
2586         assert_param(IS_RCC_PLLSAI1P_VALUE(pPllSai1->PLLSAI1P));
2587 
2588         /* Configure the PLLSAI1 Division factor M, P and Multiplication factor N*/
2589         MODIFY_REG(RCC->PLLSAI1CFGR,
2590                    RCC_PLLSAI1CFGR_PLLSAI1N | RCC_PLLSAI1CFGR_PLLSAI1PDIV | RCC_PLLSAI1CFGR_PLLSAI1M | RCC_PLLSAI1CFGR_PLLSAI1SRC,
2591                    (pPllSai1->PLLSAI1N << RCC_PLLSAI1CFGR_PLLSAI1N_Pos) |
2592                    (pPllSai1->PLLSAI1P << RCC_PLLSAI1CFGR_PLLSAI1PDIV_Pos) |
2593                    ((pPllSai1->PLLSAI1M - 1U) << RCC_PLLSAI1CFGR_PLLSAI1M_Pos) |
2594                    pPllSai1->PLLSAI1Source);
2595       }
2596       else if (Divider == DIVIDER_Q_UPDATE)
2597       {
2598         assert_param(IS_RCC_PLLSAI1Q_VALUE(pPllSai1->PLLSAI1Q));
2599 
2600         /* Configure the PLLSAI1 Division factor M, Q and Multiplication factor N*/
2601         MODIFY_REG(RCC->PLLSAI1CFGR,
2602                    RCC_PLLSAI1CFGR_PLLSAI1N | RCC_PLLSAI1CFGR_PLLSAI1Q | RCC_PLLSAI1CFGR_PLLSAI1M | RCC_PLLSAI1CFGR_PLLSAI1SRC,
2603                    (pPllSai1->PLLSAI1N << RCC_PLLSAI1CFGR_PLLSAI1N_Pos) |
2604                    (((pPllSai1->PLLSAI1Q >> 1U) - 1U) << RCC_PLLSAI1CFGR_PLLSAI1Q_Pos) |
2605                    ((pPllSai1->PLLSAI1M - 1U) << RCC_PLLSAI1CFGR_PLLSAI1M_Pos) |
2606                    pPllSai1->PLLSAI1Source);
2607       }
2608       else
2609       {
2610         assert_param(IS_RCC_PLLSAI1R_VALUE(pPllSai1->PLLSAI1R));
2611 
2612         /* Configure the PLLSAI1 Division factor M, R and Multiplication factor N*/
2613         MODIFY_REG(RCC->PLLSAI1CFGR,
2614                    RCC_PLLSAI1CFGR_PLLSAI1N | RCC_PLLSAI1CFGR_PLLSAI1R | RCC_PLLSAI1CFGR_PLLSAI1M | RCC_PLLSAI1CFGR_PLLSAI1SRC,
2615                    (pPllSai1->PLLSAI1N << RCC_PLLSAI1CFGR_PLLSAI1N_Pos) |
2616                    (((pPllSai1->PLLSAI1R >> 1U) - 1U) << RCC_PLLSAI1CFGR_PLLSAI1R_Pos) |
2617                    ((pPllSai1->PLLSAI1M - 1U) << RCC_PLLSAI1CFGR_PLLSAI1M_Pos) |
2618                    pPllSai1->PLLSAI1Source);
2619       }
2620 
2621       /* Enable the PLLSAI1 again by setting PLLSAI1ON to 1*/
2622       __HAL_RCC_PLLSAI1_ENABLE();
2623 
2624       /* Get Start Tick*/
2625       tickstart = HAL_GetTick();
2626 
2627       /* Wait till PLLSAI1 is ready */
2628       while (READ_BIT(RCC->CR, RCC_CR_PLLSAI1RDY) == 0U)
2629       {
2630         if ((HAL_GetTick() - tickstart) > PLLSAI1_TIMEOUT_VALUE)
2631         {
2632           /* New check to avoid false timeout detection in case of preemption */
2633           if (READ_BIT(RCC->CR, RCC_CR_PLLSAI1RDY) == 0U)
2634           {
2635             status = HAL_TIMEOUT;
2636           }
2637           break;
2638         }
2639       }
2640 
2641       if (status == HAL_OK)
2642       {
2643         /* Configure the PLLSAI1 Clock output(s) */
2644         __HAL_RCC_PLLSAI1CLKOUT_ENABLE(pPllSai1->PLLSAI1ClockOut);
2645       }
2646     }
2647   }
2648 
2649   return status;
2650 }
2651 
2652 /**
2653   * @brief  Configure the parameters N & P & optionally M of PLLSAI2 and enable PLLSAI2 output clock(s).
2654   * @param  pPllSai2  pointer to an RCC_PLLSAI2InitTypeDef structure that
2655   *         contains the configuration parameters N & P & optionally M as well as PLLSAI2 output clock(s)
2656   * @param  Divider  divider parameter to be updated
2657   *
2658   * @note   PLLSAI2 is temporary disable to apply new parameters
2659   *
2660   * @retval HAL status
2661   */
RCCEx_PLLSAI2_Config(RCC_PLLSAI2InitTypeDef * pPllSai2,uint32_t Divider)2662 static HAL_StatusTypeDef RCCEx_PLLSAI2_Config(RCC_PLLSAI2InitTypeDef *pPllSai2, uint32_t Divider)
2663 {
2664   HAL_StatusTypeDef status = HAL_OK;
2665   uint32_t tickstart;
2666 
2667   /* check for PLLSAI2 Parameters used to output PLLSAI2CLK */
2668   /* P, Q and R dividers are verified in each specific divider case below */
2669   assert_param(IS_RCC_PLLSAI2SOURCE(pPllSai2->PLLSAI2Source));
2670   assert_param(IS_RCC_PLLSAI2M_VALUE(pPllSai2->PLLSAI2M));
2671   assert_param(IS_RCC_PLLSAI2N_VALUE(pPllSai2->PLLSAI2N));
2672   assert_param(IS_RCC_PLLSAI2CLOCKOUT_VALUE(pPllSai2->PLLSAI2ClockOut));
2673 
2674   /* Check PLLSAI2 clock source availability */
2675   switch (pPllSai2->PLLSAI2Source)
2676   {
2677     case RCC_PLLSOURCE_MSI:
2678       if (HAL_IS_BIT_CLR(RCC->CR, RCC_CR_MSIRDY))
2679       {
2680         status = HAL_ERROR;
2681       }
2682       break;
2683     case RCC_PLLSOURCE_HSI:
2684       if (HAL_IS_BIT_CLR(RCC->CR, RCC_CR_HSIRDY))
2685       {
2686         status = HAL_ERROR;
2687       }
2688       break;
2689     case RCC_PLLSOURCE_HSE:
2690       if (HAL_IS_BIT_CLR(RCC->CR, (RCC_CR_HSERDY | RCC_CR_HSEBYP)))
2691       {
2692         status = HAL_ERROR;
2693       }
2694       break;
2695     default:
2696       status = HAL_ERROR;
2697       break;
2698   }
2699 
2700   if (status == HAL_OK)
2701   {
2702     /* Disable the PLLSAI2 */
2703     __HAL_RCC_PLLSAI2_DISABLE();
2704 
2705     /* Get Start Tick*/
2706     tickstart = HAL_GetTick();
2707 
2708     /* Wait till PLLSAI2 is ready to be updated */
2709     while (READ_BIT(RCC->CR, RCC_CR_PLLSAI2RDY) != 0U)
2710     {
2711       if ((HAL_GetTick() - tickstart) > PLLSAI2_TIMEOUT_VALUE)
2712       {
2713         /* New check to avoid false timeout detection in case of preemption */
2714         if (READ_BIT(RCC->CR, RCC_CR_PLLSAI2RDY) != 0U)
2715         {
2716           status = HAL_TIMEOUT;
2717         }
2718         break;
2719       }
2720     }
2721 
2722     if (status == HAL_OK)
2723     {
2724       if (Divider == DIVIDER_P_UPDATE)
2725       {
2726         assert_param(IS_RCC_PLLSAI2P_VALUE(pPllSai2->PLLSAI2P));
2727 
2728         /* Configure the PLLSAI2 Division factor M, P and Multiplication factor N*/
2729         MODIFY_REG(RCC->PLLSAI2CFGR,
2730                    RCC_PLLSAI2CFGR_PLLSAI2N | RCC_PLLSAI2CFGR_PLLSAI2PDIV | RCC_PLLSAI2CFGR_PLLSAI2M | RCC_PLLSAI2CFGR_PLLSAI2SRC,
2731                    (pPllSai2->PLLSAI2N << RCC_PLLSAI2CFGR_PLLSAI2N_Pos) |
2732                    (pPllSai2->PLLSAI2P << RCC_PLLSAI2CFGR_PLLSAI2PDIV_Pos) |
2733                    ((pPllSai2->PLLSAI2M - 1U) << RCC_PLLSAI2CFGR_PLLSAI2M_Pos) |
2734                    pPllSai2->PLLSAI2Source);
2735 
2736       }
2737 
2738       /* Enable the PLLSAI2 again by setting PLLSAI2ON to 1*/
2739       __HAL_RCC_PLLSAI2_ENABLE();
2740 
2741       /* Get Start Tick*/
2742       tickstart = HAL_GetTick();
2743 
2744       /* Wait till PLLSAI2 is ready */
2745       while (READ_BIT(RCC->CR, RCC_CR_PLLSAI2RDY) == 0U)
2746       {
2747         if ((HAL_GetTick() - tickstart) > PLLSAI2_TIMEOUT_VALUE)
2748         {
2749           /* New check to avoid false timeout detection in case of preemption */
2750           if (READ_BIT(RCC->CR, RCC_CR_PLLSAI2RDY) == 0U)
2751           {
2752             status = HAL_TIMEOUT;
2753           }
2754           break;
2755         }
2756       }
2757 
2758       if (status == HAL_OK)
2759       {
2760         /* Configure the PLLSAI2 Clock output(s) */
2761         __HAL_RCC_PLLSAI2CLKOUT_ENABLE(pPllSai2->PLLSAI2ClockOut);
2762       }
2763     }
2764   }
2765 
2766   return status;
2767 }
2768 
2769 /**
2770   * @brief  Get the PLLSAI1 input VCO frequency.
2771   * @retval pllvco frequency in Hz
2772   */
RCCEx_PLLSAI1_GetVCOFreq(void)2773 static uint32_t RCCEx_PLLSAI1_GetVCOFreq(void)
2774 {
2775   uint32_t pllvco = 0U;
2776 
2777   switch (READ_BIT(RCC->PLLSAI1CFGR, RCC_PLLSAI1CFGR_PLLSAI1SRC))
2778   {
2779     case PLLSAI1CFGR_PLLSAI1SRC_MSI:
2780       if (HAL_IS_BIT_SET(RCC->CR, RCC_CR_MSIRDY))
2781       {
2782         /*MSI frequency range in HZ*/
2783         pllvco = MSIRangeTable[(__HAL_RCC_GET_MSI_RANGE() >> 4U)];
2784       }
2785       else
2786       {
2787         /* pllvco already set as 0 */
2788       }
2789       break;
2790     case PLLSAI1CFGR_PLLSAI1SRC_HSI:
2791       if (HAL_IS_BIT_SET(RCC->CR, RCC_CR_HSIRDY))
2792       {
2793         pllvco = HSI_VALUE;
2794       }
2795       else
2796       {
2797         /* pllvco already set as 0 */
2798       }
2799       break;
2800     case PLLSAI1CFGR_PLLSAI1SRC_HSE:
2801       if (HAL_IS_BIT_SET(RCC->CR, RCC_CR_HSERDY))
2802       {
2803         pllvco = HSE_VALUE;
2804       }
2805       else
2806       {
2807         /* pllvco already set as 0 */
2808       }
2809       break;
2810     default:
2811       /* pllvco already set as 0 */
2812       break;
2813   }
2814 
2815   return pllvco;
2816 }
2817 
2818 /**
2819   * @brief  Get the PLLSAI2 input VCO frequency.
2820   * @retval pllvco frequency in Hz
2821   */
RCCEx_PLLSAI2_GetVCOFreq(void)2822 static uint32_t RCCEx_PLLSAI2_GetVCOFreq(void)
2823 {
2824   uint32_t pllvco = 0U;
2825 
2826   switch (READ_BIT(RCC->PLLSAI2CFGR, RCC_PLLSAI2CFGR_PLLSAI2SRC))
2827   {
2828     case PLLSAI2CFGR_PLLSAI2SRC_MSI:
2829       if (HAL_IS_BIT_SET(RCC->CR, RCC_CR_MSIRDY))
2830       {
2831         /*MSI frequency range in HZ*/
2832         pllvco = MSIRangeTable[(__HAL_RCC_GET_MSI_RANGE() >> 4U)];
2833       }
2834       else
2835       {
2836         /* pllvco already set as 0 */
2837       }
2838       break;
2839     case PLLSAI2CFGR_PLLSAI2SRC_HSI:
2840       if (HAL_IS_BIT_SET(RCC->CR, RCC_CR_HSIRDY))
2841       {
2842         pllvco = HSI_VALUE;
2843       }
2844       else
2845       {
2846         /* pllvco already set as 0 */
2847       }
2848       break;
2849     case PLLSAI2CFGR_PLLSAI2SRC_HSE:
2850       if (HAL_IS_BIT_SET(RCC->CR, RCC_CR_HSERDY))
2851       {
2852         pllvco = HSE_VALUE;
2853       }
2854       else
2855       {
2856         /* pllvco already set as 0 */
2857       }
2858       break;
2859     default:
2860       /* pllvco already set as 0 */
2861       break;
2862   }
2863 
2864   return pllvco;
2865 }
2866 
2867 /**
2868   * @brief  Get the frequency applied to SAIx peripheral.
2869   * @param  PeriphClk  Peripheral clock identifier
2870   *         This parameter can be one of the following values:
2871   *            @arg @ref RCC_PERIPHCLK_SAI1  SAI1 peripheral clock
2872   *            @arg @ref RCC_PERIPHCLK_SAI2  SAI2 peripheral clock
2873   * @param  InputFrequency pllvco frequency in Hz
2874   * @retval Frequency in Hz
2875   */
RCCEx_GetSAIxPeriphCLKFreq(uint32_t PeriphClk,uint32_t InputFrequency)2876 static uint32_t RCCEx_GetSAIxPeriphCLKFreq(uint32_t PeriphClk, uint32_t InputFrequency)
2877 {
2878   uint32_t frequency = 0U;
2879   uint32_t srcclk, pllvco, plln, pllp;    /* no init needed */
2880 
2881   if (PeriphClk == RCC_PERIPHCLK_SAI1)
2882   {
2883     srcclk = __HAL_RCC_GET_SAI1_SOURCE();
2884 
2885     if (srcclk == RCC_SAI1CLKSOURCE_PIN)
2886     {
2887       frequency = EXTERNAL_SAI1_CLOCK_VALUE;
2888     }
2889     /* Else, PLL clock output to check below */
2890   }
2891   else /* RCC_PERIPHCLK_SAI2 */
2892   {
2893     srcclk = __HAL_RCC_GET_SAI2_SOURCE();
2894 
2895     if (srcclk == RCC_SAI2CLKSOURCE_PIN)
2896     {
2897       frequency = EXTERNAL_SAI2_CLOCK_VALUE;
2898     }
2899     /* Else, PLL clock output to check below */
2900   }
2901 
2902   if (frequency == 0U)
2903   {
2904     pllvco = InputFrequency;
2905 
2906     if ((srcclk == RCC_SAI1CLKSOURCE_PLL) || (srcclk == RCC_SAI2CLKSOURCE_PLL))
2907     {
2908       if (HAL_IS_BIT_SET(RCC->CR, RCC_CR_PLLRDY))
2909       {
2910         if (__HAL_RCC_GET_PLLCLKOUT_CONFIG(RCC_PLL_SAI3CLK) != 0U)
2911         {
2912           /* f(PLL Source) / PLLM */
2913           pllvco = (pllvco / ((READ_BIT(RCC->PLLCFGR, RCC_PLLCFGR_PLLM) >> RCC_PLLCFGR_PLLM_Pos) + 1U));
2914           /* f(PLLSAI3CLK) = f(VCO input) * PLLN / PLLP */
2915           plln = READ_BIT(RCC->PLLCFGR, RCC_PLLCFGR_PLLN) >> RCC_PLLCFGR_PLLN_Pos;
2916           pllp = READ_BIT(RCC->PLLCFGR, RCC_PLLCFGR_PLLPDIV) >> RCC_PLLCFGR_PLLPDIV_Pos;
2917           if (pllp == 0U)
2918           {
2919             if (READ_BIT(RCC->PLLCFGR, RCC_PLLCFGR_PLLP) != 0U)
2920             {
2921               pllp = 17U;
2922             }
2923             else
2924             {
2925               pllp = 7U;
2926             }
2927           }
2928           frequency = (pllvco * plln) / pllp;
2929         }
2930       }
2931     }
2932     else if ((srcclk == RCC_SAI1CLKSOURCE_HSI) || (srcclk == RCC_SAI2CLKSOURCE_HSI))
2933     {
2934       if (HAL_IS_BIT_SET(RCC->CR, RCC_CR_HSIRDY))
2935       {
2936         frequency = HSI_VALUE;
2937       }
2938     }
2939     else if (srcclk == 0U) /* RCC_SAI1CLKSOURCE_PLLSAI1 || RCC_SAI2CLKSOURCE_PLLSAI1 */
2940     {
2941       if (__HAL_RCC_GET_PLLSAI1CLKOUT_CONFIG(RCC_PLLSAI1_SAI1CLK) != 0U)
2942       {
2943         /* Get f(PLLSAI1 source) */
2944         pllvco = RCCEx_PLLSAI1_GetVCOFreq();
2945         /* f(PLLSAI1 Source) / PLLSAI1M */
2946         pllvco = (pllvco / ((READ_BIT(RCC->PLLSAI1CFGR, RCC_PLLSAI1CFGR_PLLSAI1M) >> RCC_PLLSAI1CFGR_PLLSAI1M_Pos) + 1U));
2947         /* f(PLLSAI1CLK) = f(VCOSAI1 input) * PLLSAI1N / PLLSAI1P */
2948         plln = READ_BIT(RCC->PLLSAI1CFGR, RCC_PLLSAI1CFGR_PLLSAI1N) >> RCC_PLLSAI1CFGR_PLLSAI1N_Pos;
2949         pllp = READ_BIT(RCC->PLLSAI1CFGR, RCC_PLLSAI1CFGR_PLLSAI1PDIV) >> RCC_PLLSAI1CFGR_PLLSAI1PDIV_Pos;
2950         if (pllp == 0U)
2951         {
2952           if (READ_BIT(RCC->PLLSAI1CFGR, RCC_PLLSAI1CFGR_PLLSAI1P) != 0U)
2953           {
2954             pllp = 17U;
2955           }
2956           else
2957           {
2958             pllp = 7U;
2959           }
2960         }
2961         frequency = (pllvco * plln) / pllp;
2962       }
2963     }
2964     else if ((srcclk == RCC_SAI1CLKSOURCE_PLLSAI2) || (srcclk == RCC_SAI2CLKSOURCE_PLLSAI2))
2965     {
2966       if (__HAL_RCC_GET_PLLSAI2CLKOUT_CONFIG(RCC_PLLSAI2_SAI2CLK) != 0U)
2967       {
2968         /* Get f(PLLSAI2 source) */
2969         pllvco = RCCEx_PLLSAI2_GetVCOFreq();
2970         /* f(PLLSAI2 Source) / PLLSAI2M */
2971         pllvco = (pllvco / ((READ_BIT(RCC->PLLSAI2CFGR, RCC_PLLSAI2CFGR_PLLSAI2M) >> RCC_PLLSAI2CFGR_PLLSAI2M_Pos) + 1U));
2972         /* f(PLLSAI2CLK) = f(VCOSAI2 input) * PLLSAI2N / PLLSAI2P */
2973         plln = READ_BIT(RCC->PLLSAI2CFGR, RCC_PLLSAI2CFGR_PLLSAI2N) >> RCC_PLLSAI2CFGR_PLLSAI2N_Pos;
2974         pllp = READ_BIT(RCC->PLLSAI2CFGR, RCC_PLLSAI2CFGR_PLLSAI2PDIV) >> RCC_PLLSAI2CFGR_PLLSAI2PDIV_Pos;
2975         if (pllp == 0U)
2976         {
2977           if (READ_BIT(RCC->PLLSAI2CFGR, RCC_PLLSAI2CFGR_PLLSAI2P) != 0U)
2978           {
2979             pllp = 17U;
2980           }
2981           else
2982           {
2983             pllp = 7U;
2984           }
2985         }
2986         frequency = (pllvco * plln) / pllp;
2987       }
2988     }
2989     else
2990     {
2991       /* No clock source, frequency default init at 0 */
2992     }
2993   }
2994 
2995   return frequency;
2996 }
2997 
2998 /**
2999   * @}
3000   */
3001 
3002 #endif /* HAL_RCC_MODULE_ENABLED */
3003 
3004 /**
3005   * @}
3006   */
3007 
3008 /**
3009   * @}
3010   */
3011 
3012 
3013