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