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