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