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