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