comparison l476rg/Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_rcc_ex.c @ 0:32a3b1785697

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