1 /**
2 ******************************************************************************
3 * @file stm32wbxx_hal_rcc_ex.c
4 * @author MCD Application Team
5 * @brief Extended RCC HAL module driver.
6 * This file provides firmware functions to manage the following
7 * functionalities RCC extended peripheral:
8 * + Extended Peripheral Control functions
9 * + Extended Clock management functions
10 * + Extended Clock Recovery System Control functions
11 ******************************************************************************
12 * @attention
13 *
14 * Copyright (c) 2019 STMicroelectronics.
15 * All rights reserved.
16 *
17 * This software is licensed under terms that can be found in the LICENSE file
18 * in the root directory of this software component.
19 * If no LICENSE file comes with this software, it is provided AS-IS.
20 *
21 ******************************************************************************
22 */
23
24 /* Includes ------------------------------------------------------------------*/
25 #include "stm32wbxx_hal.h"
26
27 /** @addtogroup STM32WBxx_HAL_Driver
28 * @{
29 */
30
31 /** @defgroup RCCEx RCCEx
32 * @brief RCC Extended HAL module driver
33 * @{
34 */
35
36 #ifdef HAL_RCC_MODULE_ENABLED
37
38 /* Private typedef -----------------------------------------------------------*/
39 /* Private defines -----------------------------------------------------------*/
40 /** @defgroup RCCEx_Private_Constants RCCEx Private Constants
41 * @{
42 */
43 #if defined(SAI1)
44 #define PLLSAI1_TIMEOUT_VALUE (2U) /* 2 ms (minimum Tick + 1) */
45 #endif /* SAI1 */
46 #define PLL_TIMEOUT_VALUE (2U) /* 2 ms (minimum Tick + 1) */
47
48 #define CLOCKSMPS_TIMEOUT_VALUE (5000U) /* 5 s */
49
50 #define __LSCO1_CLK_ENABLE() __HAL_RCC_GPIOA_CLK_ENABLE()
51 #define LSCO1_GPIO_PORT GPIOA
52 #define LSCO1_PIN GPIO_PIN_2
53
54 #define __LSCO2_CLK_ENABLE() __HAL_RCC_GPIOH_CLK_ENABLE()
55 #define LSCO2_GPIO_PORT GPIOH
56 #define LSCO2_PIN GPIO_PIN_3
57
58 #if defined(RCC_LSCO3_SUPPORT)
59 #define __LSCO3_CLK_ENABLE() __HAL_RCC_GPIOC_CLK_ENABLE()
60 #define LSCO3_GPIO_PORT GPIOC
61 #define LSCO3_PIN GPIO_PIN_12
62 #endif /* RCC_LSCO3_SUPPORT */
63
64 #define LSI2_TIMEOUT_VALUE (3U) /* to be adjusted with DS */
65
66 /**
67 * @}
68 */
69
70 /* Private macros ------------------------------------------------------------*/
71 /* Private variables ---------------------------------------------------------*/
72 /* Private function prototypes -----------------------------------------------*/
73 /** @defgroup RCCEx_Private_Functions RCCEx Private Functions
74 * @{
75 */
76 #if defined(SAI1)
77 static HAL_StatusTypeDef RCCEx_PLLSAI1_ConfigNP(RCC_PLLSAI1InitTypeDef *PLLSAI1);
78 static HAL_StatusTypeDef RCCEx_PLLSAI1_ConfigNQ(RCC_PLLSAI1InitTypeDef *PLLSAI1);
79 static HAL_StatusTypeDef RCCEx_PLLSAI1_ConfigNR(RCC_PLLSAI1InitTypeDef *PLLSAI1);
80 #endif /* SAI1 */
81
82 static uint32_t RCC_PLL_GetFreqDomain_P(void);
83 static uint32_t RCC_PLL_GetFreqDomain_Q(void);
84
85 #if defined(SAI1)
86 static uint32_t RCC_PLLSAI1_GetFreqDomain_R(void);
87 static uint32_t RCC_PLLSAI1_GetFreqDomain_P(void);
88 static uint32_t RCC_PLLSAI1_GetFreqDomain_Q(void);
89 #endif /* SAI1 */
90
91 /**
92 * @}
93 */
94
95 /* Exported functions --------------------------------------------------------*/
96
97 /** @defgroup RCCEx_Exported_Functions RCCEx Exported Functions
98 * @{
99 */
100
101 /** @defgroup RCCEx_Exported_Functions_Group1 Extended Peripheral Control functions
102 * @brief Extended Peripheral Control functions
103 *
104 @verbatim
105 ===============================================================================
106 ##### Extended Peripheral Control functions #####
107 ===============================================================================
108 [..]
109 This subsection provides a set of functions allowing to control the RCC Clocks
110 frequencies.
111 [..]
112 (@) Important note: Care must be taken when HAL_RCCEx_PeriphCLKConfig() is used to
113 select the RTC clock source; in this case the Backup domain will be reset in
114 order to modify the RTC Clock source, as consequence RTC registers (including
115 the backup registers) and RCC_BDCR register are set to their reset values.
116
117 @endverbatim
118 * @{
119 */
120
121 /**
122 * @brief Initialize the RCC extended peripherals clocks according to the specified
123 * parameters in the @ref RCC_PeriphCLKInitTypeDef.
124 * @param PeriphClkInit pointer to a @ref RCC_PeriphCLKInitTypeDef structure that
125 * contains a field PeriphClockSelection which can be a combination of the following values:
126 *
127 * @arg @ref RCC_PERIPHCLK_USART1 USART1 peripheral clock
128 * @arg @ref RCC_PERIPHCLK_LPUART1 LPUART1 peripheral clock
129 * @arg @ref RCC_PERIPHCLK_I2C1 I2C1 peripheral clock
130 * @arg @ref RCC_PERIPHCLK_I2C3 I2C3 peripheral clock
131 * @arg @ref RCC_PERIPHCLK_LPTIM1 LPTIM1 peripheral clock
132 * @arg @ref RCC_PERIPHCLK_LPTIM2 LPTIM2 peripheral clock
133 * @arg @ref RCC_PERIPHCLK_SAI1 SAI1 peripheral clock
134 * @arg @ref RCC_PERIPHCLK_USB USB peripheral clock
135 * @arg @ref RCC_PERIPHCLK_RNG RNG peripheral clock
136 * @arg @ref RCC_PERIPHCLK_ADC ADC peripheral clock
137 * @arg @ref RCC_PERIPHCLK_RTC RTC peripheral clock
138 * @arg @ref RCC_PERIPHCLK_RFWAKEUP RFWKP peripheral clock
139 * @arg @ref RCC_PERIPHCLK_SMPS SMPS peripheral clock
140 *
141 *
142 * @note Care must be taken when @ref HAL_RCCEx_PeriphCLKConfig() is used to select
143 * the RTC clock source: in this case the access to Backup domain is enabled.
144 *
145 * @retval HAL status
146 */
HAL_RCCEx_PeriphCLKConfig(RCC_PeriphCLKInitTypeDef * PeriphClkInit)147 HAL_StatusTypeDef HAL_RCCEx_PeriphCLKConfig(RCC_PeriphCLKInitTypeDef *PeriphClkInit)
148 {
149 uint32_t tickstart;
150 HAL_StatusTypeDef ret = HAL_OK; /* Intermediate status */
151 HAL_StatusTypeDef status = HAL_OK; /* Final status */
152
153 /* Check the parameters */
154 assert_param(IS_RCC_PERIPHCLOCK(PeriphClkInit->PeriphClockSelection));
155
156 #if defined(SAI1)
157 /*-------------------------- SAI1 clock source configuration ---------------------*/
158 if ((((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_SAI1) == RCC_PERIPHCLK_SAI1))
159 {
160 /* Check the parameters */
161 assert_param(IS_RCC_SAI1CLK(PeriphClkInit->Sai1ClockSelection));
162
163 switch (PeriphClkInit->Sai1ClockSelection)
164 {
165 case RCC_SAI1CLKSOURCE_PLL: /* PLL is used as clock source for SAI1 */
166 /* Enable SAI1 Clock output generated form System PLL . */
167 __HAL_RCC_PLLCLKOUT_ENABLE(RCC_PLL_SAI1CLK);
168
169 /* SAI1 clock source config set later after clock selection check */
170 break;
171
172 case RCC_SAI1CLKSOURCE_PLLSAI1: /* PLLSAI1 is used as clock source for SAI1 */
173 /* PLLSAI1 parameters N & P configuration and clock output (PLLSAI1ClockOut) */
174 ret = RCCEx_PLLSAI1_ConfigNP(&(PeriphClkInit->PLLSAI1));
175 /* SAI1 clock source config set later after clock selection check */
176 break;
177
178 case RCC_SAI1CLKSOURCE_PIN: /* External clock is used as source of SAI1 clock*/
179 /* SAI1 clock source config set later after clock selection check */
180 break;
181
182 case RCC_SAI1CLKSOURCE_HSI:
183
184 break;
185
186 default:
187 ret = HAL_ERROR;
188 break;
189 }
190
191 if (ret == HAL_OK)
192 {
193 /* Set the source of SAI1 clock*/
194 __HAL_RCC_SAI1_CONFIG(PeriphClkInit->Sai1ClockSelection);
195 }
196 else
197 {
198 /* set overall return value */
199 status = ret;
200 }
201 }
202 #endif /* SAI1 */
203
204 /*-------------------------- RTC clock source configuration ----------------------*/
205 if ((PeriphClkInit->PeriphClockSelection & RCC_PERIPHCLK_RTC) == RCC_PERIPHCLK_RTC)
206 {
207 uint32_t rtcclocksource = LL_RCC_GetRTCClockSource();
208
209 /* Check for RTC Parameters used to output RTCCLK */
210 assert_param(IS_RCC_RTCCLKSOURCE(PeriphClkInit->RTCClockSelection));
211
212 /* Configure the clock source only if a different source is expected */
213 if (rtcclocksource != PeriphClkInit->RTCClockSelection)
214 {
215 /* Enable write access to Backup domain */
216 HAL_PWR_EnableBkUpAccess();
217
218 /* If a clock source is not yet selected */
219 if (rtcclocksource == RCC_RTCCLKSOURCE_NONE)
220 {
221 /* Directly set the configuration of the clock source selection */
222 LL_RCC_SetRTCClockSource(PeriphClkInit->RTCClockSelection);
223 }
224 else /* A clock source is already selected */
225 {
226 /* Store the content of BDCR register before the reset of Backup Domain */
227 uint32_t bdcr = LL_RCC_ReadReg(BDCR);
228
229 /* RTC Clock selection can be changed only if the Backup Domain is reset */
230 LL_RCC_ForceBackupDomainReset();
231 LL_RCC_ReleaseBackupDomainReset();
232
233 /* Set the value of the clock source selection */
234 MODIFY_REG(bdcr, RCC_BDCR_RTCSEL, PeriphClkInit->RTCClockSelection);
235
236 /* Restore the content of BDCR register */
237 LL_RCC_WriteReg(BDCR, bdcr);
238
239 /* Wait for LSE reactivation if LSE was enable prior to Backup Domain reset */
240 if (LL_RCC_LSE_IsEnabled() == 1U)
241 {
242 /* Get Start Tick*/
243 tickstart = HAL_GetTick();
244
245 /* Wait till LSE is ready */
246 while (LL_RCC_LSE_IsReady() != 1U)
247 {
248 if ((HAL_GetTick() - tickstart) > RCC_LSE_TIMEOUT_VALUE)
249 {
250 ret = HAL_TIMEOUT;
251 break;
252 }
253 }
254 }
255 }
256
257 /* set overall return value */
258 status = ret;
259 }
260 else
261 {
262 /* set overall return value */
263 status = ret;
264 }
265
266 }
267
268 /*-------------------------- USART1 clock source configuration -------------------*/
269 if (((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_USART1) == RCC_PERIPHCLK_USART1)
270 {
271 /* Check the parameters */
272 assert_param(IS_RCC_USART1CLKSOURCE(PeriphClkInit->Usart1ClockSelection));
273
274 /* Configure the USART1 clock source */
275 __HAL_RCC_USART1_CONFIG(PeriphClkInit->Usart1ClockSelection);
276 }
277
278 #if defined(LPUART1)
279 /*-------------------------- LPUART1 clock source configuration ------------------*/
280 if (((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_LPUART1) == RCC_PERIPHCLK_LPUART1)
281 {
282 /* Check the parameters */
283 assert_param(IS_RCC_LPUART1CLKSOURCE(PeriphClkInit->Lpuart1ClockSelection));
284
285 /* Configure the LPUAR1 clock source */
286 __HAL_RCC_LPUART1_CONFIG(PeriphClkInit->Lpuart1ClockSelection);
287 }
288 #endif /* LPUART1 */
289
290 /*-------------------------- LPTIM1 clock source configuration -------------------*/
291 if (((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_LPTIM1) == (RCC_PERIPHCLK_LPTIM1))
292 {
293 assert_param(IS_RCC_LPTIM1CLK(PeriphClkInit->Lptim1ClockSelection));
294 __HAL_RCC_LPTIM1_CONFIG(PeriphClkInit->Lptim1ClockSelection);
295 }
296
297 /*-------------------------- LPTIM2 clock source configuration -------------------*/
298 if (((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_LPTIM2) == (RCC_PERIPHCLK_LPTIM2))
299 {
300 assert_param(IS_RCC_LPTIM2CLK(PeriphClkInit->Lptim2ClockSelection));
301 __HAL_RCC_LPTIM2_CONFIG(PeriphClkInit->Lptim2ClockSelection);
302 }
303
304 /*-------------------------- I2C1 clock source configuration ---------------------*/
305 if (((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_I2C1) == RCC_PERIPHCLK_I2C1)
306 {
307 /* Check the parameters */
308 assert_param(IS_RCC_I2C1CLKSOURCE(PeriphClkInit->I2c1ClockSelection));
309
310 /* Configure the I2C1 clock source */
311 __HAL_RCC_I2C1_CONFIG(PeriphClkInit->I2c1ClockSelection);
312 }
313
314 #if defined(I2C3)
315 /*-------------------------- I2C3 clock source configuration ---------------------*/
316 if (((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_I2C3) == RCC_PERIPHCLK_I2C3)
317 {
318 /* Check the parameters */
319 assert_param(IS_RCC_I2C3CLKSOURCE(PeriphClkInit->I2c3ClockSelection));
320
321 /* Configure the I2C3 clock source */
322 __HAL_RCC_I2C3_CONFIG(PeriphClkInit->I2c3ClockSelection);
323 }
324 #endif /* I2C3 */
325
326 #if defined(USB)
327 /*-------------------------- USB clock source configuration ----------------------*/
328 if (((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_USB) == (RCC_PERIPHCLK_USB))
329 {
330 assert_param(IS_RCC_USBCLKSOURCE(PeriphClkInit->UsbClockSelection));
331 __HAL_RCC_USB_CONFIG(PeriphClkInit->UsbClockSelection);
332
333 if (PeriphClkInit->UsbClockSelection == RCC_USBCLKSOURCE_PLL)
334 {
335 /* Enable PLLQ output */
336 __HAL_RCC_PLLCLKOUT_ENABLE(RCC_PLL_USBCLK);
337 }
338 #if defined(SAI1)
339 if (PeriphClkInit->UsbClockSelection == RCC_USBCLKSOURCE_PLLSAI1)
340 {
341 /* PLLSAI1 parameters N & Q configuration and clock output (PLLSAI1ClockOut) */
342 ret = RCCEx_PLLSAI1_ConfigNQ(&(PeriphClkInit->PLLSAI1));
343
344 if (ret != HAL_OK)
345 {
346 /* set overall return value */
347 status = ret;
348 }
349 }
350 #endif /* SAI1 */
351 }
352 #endif /* USB */
353
354 /*-------------------------- RNG clock source configuration ----------------------*/
355 if (((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_RNG) == (RCC_PERIPHCLK_RNG))
356 {
357 /* Check the parameters */
358 assert_param(IS_RCC_RNGCLKSOURCE(PeriphClkInit->RngClockSelection));
359
360 /* Configure the RNG clock source */
361 __HAL_RCC_RNG_CONFIG(PeriphClkInit->RngClockSelection);
362
363 if (PeriphClkInit->RngClockSelection == RCC_RNGCLKSOURCE_PLL)
364 {
365 /* Enable PLLQ output */
366 __HAL_RCC_PLLCLKOUT_ENABLE(RCC_PLL_RNGCLK);
367 }
368 }
369
370 /*-------------------------- ADC clock source configuration ----------------------*/
371 if (((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_ADC) == RCC_PERIPHCLK_ADC)
372 {
373 /* Check the parameters */
374 assert_param(IS_RCC_ADCCLKSOURCE(PeriphClkInit->AdcClockSelection));
375
376 /* Configure the ADC interface clock source */
377 __HAL_RCC_ADC_CONFIG(PeriphClkInit->AdcClockSelection);
378
379 if (PeriphClkInit->AdcClockSelection == RCC_ADCCLKSOURCE_PLL)
380 {
381 /* Enable RCC_PLL_RNGCLK output */
382 __HAL_RCC_PLLCLKOUT_ENABLE(RCC_PLL_ADCCLK);
383 }
384
385 #if defined(SAI1)
386 if (PeriphClkInit->AdcClockSelection == RCC_ADCCLKSOURCE_PLLSAI1)
387 {
388 /* PLLSAI1 parameters N & R configuration and clock output (PLLSAI1ClockOut) */
389 ret = RCCEx_PLLSAI1_ConfigNR(&(PeriphClkInit->PLLSAI1));
390
391 if (ret != HAL_OK)
392 {
393 /* set overall return value */
394 status = ret;
395 }
396 }
397 #endif /* SAI1 */
398 }
399
400 /*-------------------------- RFWKP clock source configuration ----------------------*/
401 if (((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_RFWAKEUP) == RCC_PERIPHCLK_RFWAKEUP)
402 {
403 /* Check the parameters */
404 assert_param(IS_RCC_RFWKPCLKSOURCE(PeriphClkInit->RFWakeUpClockSelection));
405
406 /* Configure the RFWKP interface clock source */
407 __HAL_RCC_RFWAKEUP_CONFIG(PeriphClkInit->RFWakeUpClockSelection);
408
409 }
410
411 #if defined(RCC_SMPS_SUPPORT)
412 /*-------------------------- SMPS clock source configuration ----------------------*/
413 if (((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_SMPS) == RCC_PERIPHCLK_SMPS)
414 {
415 /* Check the parameters */
416 assert_param(IS_RCC_SMPSCLKDIV(PeriphClkInit->SmpsDivSelection));
417 assert_param(IS_RCC_SMPSCLKSOURCE(PeriphClkInit->SmpsClockSelection));
418
419 /* Configure the SMPS interface clock division factor */
420 __HAL_RCC_SMPS_DIV_CONFIG(PeriphClkInit->SmpsDivSelection);
421
422 /* Configure the SMPS interface clock source */
423 __HAL_RCC_SMPS_CONFIG(PeriphClkInit->SmpsClockSelection);
424 }
425 #endif /* RCC_SMPS_SUPPORT */
426
427 return status;
428 }
429
430
431 /**
432 * @brief Get the RCC_ClkInitStruct according to the internal RCC configuration registers.
433 * @param PeriphClkInit pointer to an RCC_PeriphCLKInitTypeDef structure that
434 * returns the configuration information for the Extended Peripherals
435 * clocks(SAI1, LPTIM1, LPTIM2, I2C1, I2C3, LPUART1,
436 * USART1, RTC, ADCx, USB, RNG, RFWKP, SMPS).
437 * @retval None
438 */
HAL_RCCEx_GetPeriphCLKConfig(RCC_PeriphCLKInitTypeDef * PeriphClkInit)439 void HAL_RCCEx_GetPeriphCLKConfig(RCC_PeriphCLKInitTypeDef *PeriphClkInit)
440 {
441 /* Set all possible values for the extended clock type parameter------------*/
442
443 PeriphClkInit->PeriphClockSelection = RCC_PERIPHCLK_USART1 | RCC_PERIPHCLK_I2C1 | \
444 RCC_PERIPHCLK_LPTIM1 | RCC_PERIPHCLK_LPTIM2 | \
445 RCC_PERIPHCLK_RNG | RCC_PERIPHCLK_ADC | \
446 RCC_PERIPHCLK_RTC | RCC_PERIPHCLK_RFWAKEUP;
447 #if defined(LPUART1)
448 PeriphClkInit->PeriphClockSelection |= RCC_PERIPHCLK_LPUART1;
449 #endif /* LPUART1 */
450
451 #if defined(I2C3)
452 PeriphClkInit->PeriphClockSelection |= RCC_PERIPHCLK_I2C3;
453 #endif /* I2C3 */
454
455 #if defined(SAI1)
456 PeriphClkInit->PeriphClockSelection |= RCC_PERIPHCLK_SAI1;
457 #endif /* SAI1 */
458
459 #if defined(USB)
460 PeriphClkInit->PeriphClockSelection |= RCC_PERIPHCLK_USB;
461 #endif /* USB */
462
463 #if defined(RCC_SMPS_SUPPORT)
464 PeriphClkInit->PeriphClockSelection |= RCC_PERIPHCLK_SMPS;
465 #endif /* RCC_SMPS_SUPPORT */
466
467
468 #if defined(SAI1)
469 /* Get the PLLSAI1 Clock configuration -----------------------------------------------*/
470 PeriphClkInit->PLLSAI1.PLLN = LL_RCC_PLLSAI1_GetN();
471 PeriphClkInit->PLLSAI1.PLLP = LL_RCC_PLLSAI1_GetP();
472 PeriphClkInit->PLLSAI1.PLLR = LL_RCC_PLLSAI1_GetR();
473 PeriphClkInit->PLLSAI1.PLLQ = LL_RCC_PLLSAI1_GetQ();
474 #endif /* SAI1 */
475
476 /* Get the USART1 clock source ---------------------------------------------*/
477 PeriphClkInit->Usart1ClockSelection = __HAL_RCC_GET_USART1_SOURCE();
478
479 #if defined(LPUART1)
480 /* Get the LPUART1 clock source --------------------------------------------*/
481 PeriphClkInit->Lpuart1ClockSelection = __HAL_RCC_GET_LPUART1_SOURCE();
482 #endif /* LPUART1 */
483
484 /* Get the I2C1 clock source -----------------------------------------------*/
485 PeriphClkInit->I2c1ClockSelection = __HAL_RCC_GET_I2C1_SOURCE();
486
487 #if defined(I2C3)
488 /* Get the I2C3 clock source -----------------------------------------------*/
489 PeriphClkInit->I2c3ClockSelection = __HAL_RCC_GET_I2C3_SOURCE();
490 #endif /* I2C3 */
491
492 /* Get the LPTIM1 clock source ---------------------------------------------*/
493 PeriphClkInit->Lptim1ClockSelection = __HAL_RCC_GET_LPTIM1_SOURCE();
494
495 /* Get the LPTIM2 clock source ---------------------------------------------*/
496 PeriphClkInit->Lptim2ClockSelection = __HAL_RCC_GET_LPTIM2_SOURCE();
497
498 #if defined(SAI1)
499 /* Get the SAI1 clock source -----------------------------------------------*/
500 PeriphClkInit->Sai1ClockSelection = __HAL_RCC_GET_SAI1_SOURCE();
501 #endif /* SAI1 */
502
503 /* Get the RTC clock source ------------------------------------------------*/
504 PeriphClkInit->RTCClockSelection = __HAL_RCC_GET_RTC_SOURCE();
505
506 #if defined(USB)
507 /* Get the USB clock source ------------------------------------------------*/
508 PeriphClkInit->UsbClockSelection = __HAL_RCC_GET_USB_SOURCE();
509 #endif /* USB */
510
511 /* Get the RNG clock source ------------------------------------------------*/
512 PeriphClkInit->RngClockSelection = HAL_RCCEx_GetRngCLKSource();
513
514 /* Get the ADC clock source ------------------------------------------------*/
515 PeriphClkInit->AdcClockSelection = __HAL_RCC_GET_ADC_SOURCE();
516
517 /* Get the RFWKP clock source ----------------------------------------------*/
518 PeriphClkInit->RFWakeUpClockSelection = __HAL_RCC_GET_RFWAKEUP_SOURCE();
519
520 #if defined(RCC_SMPS_SUPPORT)
521 /* Get the SMPS clock division factor --------------------------------------*/
522 PeriphClkInit->SmpsDivSelection = __HAL_RCC_GET_SMPS_DIV();
523
524 /* Get the SMPS clock source -----------------------------------------------*/
525 PeriphClkInit->SmpsClockSelection = __HAL_RCC_GET_SMPS_SOURCE();
526 #endif /* RCC_SMPS_SUPPORT */
527
528 }
529
530 /**
531 * @brief Return the peripheral clock frequency for peripherals with clock source
532 * @note Return 0 if peripheral clock identifier not managed by this API
533 * @param PeriphClk Peripheral clock identifier
534 * This parameter can be one of the following values:
535 * @arg @ref RCC_PERIPHCLK_RTC RTC peripheral clock
536 * @arg @ref RCC_PERIPHCLK_ADC ADC peripheral clock
537 * @arg @ref RCC_PERIPHCLK_I2C1 I2C1 peripheral clock
538 * @arg @ref RCC_PERIPHCLK_I2C3 I2C3 peripheral clock
539 * @arg @ref RCC_PERIPHCLK_LPTIM1 LPTIM1 peripheral clock
540 * @arg @ref RCC_PERIPHCLK_LPTIM2 LPTIM2 peripheral clock
541 * @arg @ref RCC_PERIPHCLK_LPUART1 LPUART1 peripheral clock
542 * @arg @ref RCC_PERIPHCLK_RNG RNG peripheral clock
543 * @arg @ref RCC_PERIPHCLK_SAI1 SAI1 peripheral clock
544 * @arg @ref RCC_PERIPHCLK_USART1 USART1 peripheral clock
545 * @arg @ref RCC_PERIPHCLK_USB USB peripheral clock
546 * @arg @ref RCC_PERIPHCLK_RFWAKEUP RFWKP peripheral clock
547 * @arg @ref RCC_PERIPHCLK_SMPS SMPS peripheral clock
548 * @retval Frequency in Hz
549 */
HAL_RCCEx_GetPeriphCLKFreq(uint32_t PeriphClk)550 uint32_t HAL_RCCEx_GetPeriphCLKFreq(uint32_t PeriphClk)
551 {
552 uint32_t frequency = 0U;
553
554 #if defined(RCC_SMPS_SUPPORT)
555 uint32_t smps_prescaler_index = ((LL_RCC_GetSMPSPrescaler()) >> RCC_SMPSCR_SMPSDIV_Pos);
556 #endif /* RCC_SMPS_SUPPORT */
557
558 /* Check the parameters */
559 assert_param(IS_RCC_PERIPHCLOCK(PeriphClk));
560
561 if (PeriphClk == RCC_PERIPHCLK_RTC)
562 {
563 uint32_t rtcClockSource = LL_RCC_GetRTCClockSource();
564
565 if (rtcClockSource == LL_RCC_RTC_CLKSOURCE_LSE) /* LSE clock used as RTC clock source */
566 {
567 if (LL_RCC_LSE_IsReady() == 1U)
568 {
569 frequency = LSE_VALUE;
570 }
571 else
572 {
573 /* Nothing to do as frequency already initialized to 0U */
574 }
575 }
576 else if (rtcClockSource == LL_RCC_RTC_CLKSOURCE_LSI) /* LSI clock used as RTC clock source */
577 {
578 const uint32_t temp_lsi1ready = LL_RCC_LSI1_IsReady();
579 const uint32_t temp_lsi2ready = LL_RCC_LSI2_IsReady();
580 if ((temp_lsi1ready == 1U) || (temp_lsi2ready == 1U))
581 {
582 frequency = LSI_VALUE;
583 }
584 else
585 {
586 /* Nothing to do as frequency already initialized to 0U */
587 }
588 }
589 else if (rtcClockSource == LL_RCC_RTC_CLKSOURCE_HSE_DIV32) /* HSE clock used as RTC clock source */
590 {
591 frequency = HSE_VALUE / 32U;
592 }
593 else /* No clock used as RTC clock source */
594 {
595 /* Nothing to do as frequency already initialized to 0U */
596 }
597 }
598 #if defined(SAI1)
599 else if (PeriphClk == RCC_PERIPHCLK_SAI1)
600 {
601 switch (LL_RCC_GetSAIClockSource(LL_RCC_SAI1_CLKSOURCE))
602 {
603 case LL_RCC_SAI1_CLKSOURCE_HSI: /* HSI clock used as SAI1 clock source */
604 if (LL_RCC_HSI_IsReady() == 1U)
605 {
606 frequency = HSI_VALUE;
607 }
608 else
609 {
610 /* Nothing to do as frequency already initialized to 0U */
611 }
612 break;
613
614 case LL_RCC_SAI1_CLKSOURCE_PLLSAI1: /* PLLSAI1 clock used as SAI1 clock source */
615 if (LL_RCC_PLLSAI1_IsReady() == 1U)
616 {
617 frequency = RCC_PLLSAI1_GetFreqDomain_P();
618 }
619 else
620 {
621 /* Nothing to do as frequency already initialized to 0U */
622 }
623 break;
624
625 case LL_RCC_SAI1_CLKSOURCE_PLL: /* PLL clock used as SAI1 clock source */
626 if (LL_RCC_PLL_IsReady() == 1U)
627 {
628 frequency = RCC_PLL_GetFreqDomain_P();
629 }
630 else
631 {
632 /* Nothing to do as frequency already initialized to 0U */
633 }
634 break;
635
636 default: /* External input clock used as SAI1 clock source */
637 frequency = EXTERNAL_SAI1_CLOCK_VALUE;
638 break;
639 }
640 }
641 #endif /* SAI1 */
642 else if (PeriphClk == RCC_PERIPHCLK_RNG)
643 {
644 uint32_t rngClockSource = HAL_RCCEx_GetRngCLKSource();
645
646 if (rngClockSource == RCC_RNGCLKSOURCE_LSI) /* LSI clock used as RNG clock source */
647 {
648 const uint32_t temp_lsi1ready = LL_RCC_LSI1_IsReady();
649 const uint32_t temp_lsi2ready = LL_RCC_LSI2_IsReady();
650 if ((temp_lsi1ready == 1U) || (temp_lsi2ready == 1U))
651 {
652 frequency = LSI_VALUE;
653 }
654 else
655 {
656 /* Nothing to do as frequency already initialized to 0U */
657 }
658 }
659 else if (rngClockSource == RCC_RNGCLKSOURCE_LSE) /* LSE clock used as RNG clock source */
660 {
661 if (LL_RCC_LSE_IsReady() == 1U)
662 {
663 frequency = LSE_VALUE;
664 }
665 else
666 {
667 /* Nothing to do as frequency already initialized to 0U */
668 }
669 }
670 else if (rngClockSource == RCC_RNGCLKSOURCE_PLL) /* PLL clock divided by 3 used as RNG clock source */
671 {
672 if (LL_RCC_PLL_IsReady() == 1U)
673 {
674 frequency = (RCC_PLL_GetFreqDomain_Q() / 3U);
675 }
676 else
677 {
678 /* Nothing to do as frequency already initialized to 0U */
679 }
680 }
681 else if (rngClockSource == RCC_RNGCLKSOURCE_MSI) /* MSI clock divided by 3 used as RNG clock source */
682 {
683 if (LL_RCC_MSI_IsReady() == 1U)
684 {
685 frequency = (__LL_RCC_CALC_MSI_FREQ(LL_RCC_MSI_GetRange()) / 3U);
686 }
687 else
688 {
689 /* Nothing to do as frequency already initialized to 0U */
690 }
691 }
692 #if defined(SAI1)
693 else if (rngClockSource == RCC_RNGCLKSOURCE_PLLSAI1) /* PLLSAI1 clock used as SAI1 clock source */
694 {
695 if (LL_RCC_PLLSAI1_IsReady() == 1U)
696 {
697 frequency = RCC_PLLSAI1_GetFreqDomain_Q();
698 }
699 else
700 {
701 /* Nothing to do as frequency already initialized to 0U */
702 }
703 }
704 #endif /* SAI1 */
705 else /* HSI48 clock divided by 3 used as RNG clock source */
706 {
707 #if defined(RCC_HSI48_SUPPORT)
708 if (LL_RCC_HSI48_IsReady() == 1U)
709 {
710 frequency = HSI48_VALUE / 3U;
711 }
712 else
713 {
714 /* Nothing to do as frequency already initialized to 0U */
715 }
716 #else
717 /* Nothing to do as frequency already initialized to 0U */
718 #endif /* RCC_HSI48_SUPPORT */
719 }
720 }
721 #if defined(USB)
722 else if (PeriphClk == RCC_PERIPHCLK_USB)
723 {
724 switch (LL_RCC_GetUSBClockSource(LL_RCC_USB_CLKSOURCE))
725 {
726 #if defined(SAI1)
727 case LL_RCC_USB_CLKSOURCE_PLLSAI1: /* PLLSAI1 clock used as USB clock source */
728 if (LL_RCC_PLLSAI1_IsReady() == 1U)
729 {
730 frequency = RCC_PLLSAI1_GetFreqDomain_Q();
731 }
732 else
733 {
734 /* Nothing to do as frequency already initialized to 0U */
735 }
736 break;
737 #endif /* SAI1 */
738
739 case LL_RCC_USB_CLKSOURCE_PLL: /* PLL clock used as USB clock source */
740 if (LL_RCC_PLL_IsReady() == 1U)
741 {
742 frequency = RCC_PLL_GetFreqDomain_Q();
743 }
744 else
745 {
746 /* Nothing to do as frequency already initialized to 0U */
747 }
748 break;
749
750 case LL_RCC_USB_CLKSOURCE_MSI: /* MSI clock used as USB clock source */
751 if (LL_RCC_MSI_IsReady() == 1U)
752 {
753 frequency = __LL_RCC_CALC_MSI_FREQ(LL_RCC_MSI_GetRange());
754 }
755 else
756 {
757 /* Nothing to do as frequency already initialized to 0U */
758 }
759 break;
760
761 default: /* HSI48 clock used as USB clock source */
762 if (LL_RCC_HSI48_IsReady() == 1U)
763 {
764 frequency = HSI48_VALUE;
765 }
766 else
767 {
768 /* Nothing to do as frequency already initialized to 0U */
769 }
770 break;
771 }
772 }
773 #endif /* USB */
774 else if (PeriphClk == RCC_PERIPHCLK_USART1)
775 {
776 switch (LL_RCC_GetUSARTClockSource(LL_RCC_USART1_CLKSOURCE))
777 {
778 case LL_RCC_USART1_CLKSOURCE_SYSCLK: /* USART1 Clock is System Clock */
779 frequency = HAL_RCC_GetSysClockFreq();
780 break;
781
782 case LL_RCC_USART1_CLKSOURCE_HSI: /* USART1 Clock is HSI Osc. */
783 if (LL_RCC_HSI_IsReady() == 1U)
784 {
785 frequency = HSI_VALUE;
786 }
787 else
788 {
789 /* Nothing to do as frequency already initialized to 0U */
790 }
791 break;
792
793 case LL_RCC_USART1_CLKSOURCE_LSE: /* USART1 Clock is LSE Osc. */
794 if (LL_RCC_LSE_IsReady() == 1U)
795 {
796 frequency = LSE_VALUE;
797 }
798 else
799 {
800 /* Nothing to do as frequency already initialized to 0U */
801 }
802 break;
803
804 default: /* USART1 Clock is PCLK2 */
805 frequency = __LL_RCC_CALC_PCLK2_FREQ(__LL_RCC_CALC_HCLK1_FREQ(HAL_RCC_GetSysClockFreq(),
806 LL_RCC_GetAHBPrescaler()),
807 LL_RCC_GetAPB2Prescaler());
808 break;
809 }
810 }
811 #if defined(LPUART1)
812 else if (PeriphClk == RCC_PERIPHCLK_LPUART1)
813 {
814 switch (LL_RCC_GetLPUARTClockSource(LL_RCC_LPUART1_CLKSOURCE))
815 {
816 case LL_RCC_LPUART1_CLKSOURCE_SYSCLK: /* LPUART1 Clock is System Clock */
817 frequency = HAL_RCC_GetSysClockFreq();
818 break;
819
820 case LL_RCC_LPUART1_CLKSOURCE_HSI: /* LPUART1 Clock is HSI Osc. */
821 if (LL_RCC_HSI_IsReady() == 1U)
822 {
823 frequency = HSI_VALUE;
824 }
825 else
826 {
827 /* Nothing to do as frequency already initialized to 0U */
828 }
829 break;
830
831 case LL_RCC_LPUART1_CLKSOURCE_LSE: /* LPUART1 Clock is LSE Osc. */
832 if (LL_RCC_LSE_IsReady() == 1U)
833 {
834 frequency = LSE_VALUE;
835 }
836 else
837 {
838 /* Nothing to do as frequency already initialized to 0U */
839 }
840 break;
841
842 default: /* LPUART1 Clock is PCLK1 */
843 frequency = __LL_RCC_CALC_PCLK1_FREQ(__LL_RCC_CALC_HCLK1_FREQ(HAL_RCC_GetSysClockFreq(),
844 LL_RCC_GetAHBPrescaler()),
845 LL_RCC_GetAPB1Prescaler());
846 break;
847 }
848 }
849 #endif /* LPUART1 */
850 else if (PeriphClk == RCC_PERIPHCLK_ADC)
851 {
852 switch (LL_RCC_GetADCClockSource(LL_RCC_ADC_CLKSOURCE))
853 {
854 #if defined(STM32WB55xx) || defined (STM32WB5Mxx) || defined(STM32WB35xx)
855 case LL_RCC_ADC_CLKSOURCE_PLLSAI1: /* PLLSAI1 clock used as ADC clock source */
856 if (LL_RCC_PLLSAI1_IsReady() == 1U)
857 {
858 frequency = RCC_PLLSAI1_GetFreqDomain_R();
859 }
860 else
861 {
862 /* Nothing to do as frequency already initialized to 0U */
863 }
864 break;
865 #elif defined(STM32WB15xx) || defined(STM32WB1Mxx)
866 case LL_RCC_ADC_CLKSOURCE_HSI: /* HSI clock used as ADC clock source */
867 if (LL_RCC_HSI_IsReady() == 1U)
868 {
869 frequency = HSI_VALUE;
870 }
871 else
872 {
873 /* Nothing to do as frequency already initialized to 0U */
874 }
875 break;
876 #endif /* STM32WB55xx || STM32WB5Mxx || STM32WB35xx */
877 case LL_RCC_ADC_CLKSOURCE_SYSCLK: /* SYSCLK clock used as ADC clock source */
878 frequency = HAL_RCC_GetSysClockFreq();
879 break;
880 case LL_RCC_ADC_CLKSOURCE_PLL: /* PLL clock used as ADC clock source */
881 if (LL_RCC_PLL_IsReady() == 1U)
882 {
883 frequency = RCC_PLL_GetFreqDomain_P();
884 }
885 else
886 {
887 /* Nothing to do as frequency already initialized to 0U */
888 }
889 break;
890
891 default: /* No clock used as ADC clock source */
892 break;
893 }
894 }
895 else if (PeriphClk == RCC_PERIPHCLK_I2C1)
896 {
897 switch (LL_RCC_GetI2CClockSource(LL_RCC_I2C1_CLKSOURCE))
898 {
899 case LL_RCC_I2C1_CLKSOURCE_SYSCLK: /* I2C1 Clock is System Clock */
900 frequency = HAL_RCC_GetSysClockFreq();
901 break;
902
903 case LL_RCC_I2C1_CLKSOURCE_HSI: /* I2C1 Clock is HSI Osc. */
904 if (LL_RCC_HSI_IsReady() == 1U)
905 {
906 frequency = HSI_VALUE;
907 }
908 else
909 {
910 /* Nothing to do as frequency already initialized to 0U */
911 }
912 break;
913
914 default: /* I2C1 Clock is PCLK1 */
915 frequency = __LL_RCC_CALC_PCLK1_FREQ(__LL_RCC_CALC_HCLK1_FREQ(HAL_RCC_GetSysClockFreq(),
916 LL_RCC_GetAHBPrescaler()),
917 LL_RCC_GetAPB1Prescaler());
918 break;
919 }
920 }
921 #if defined(I2C3)
922 else if (PeriphClk == RCC_PERIPHCLK_I2C3)
923 {
924 switch (LL_RCC_GetI2CClockSource(LL_RCC_I2C3_CLKSOURCE))
925 {
926 case LL_RCC_I2C3_CLKSOURCE_SYSCLK: /* I2C3 Clock is System Clock */
927 frequency = HAL_RCC_GetSysClockFreq();
928 break;
929
930 case LL_RCC_I2C3_CLKSOURCE_HSI: /* I2C3 Clock is HSI Osc. */
931 if (LL_RCC_HSI_IsReady() == 1U)
932 {
933 frequency = HSI_VALUE;
934 }
935 else
936 {
937 /* Nothing to do as frequency already initialized to 0U */
938 }
939 break;
940
941 default: /* I2C3 Clock is PCLK1 */
942 frequency = __LL_RCC_CALC_PCLK1_FREQ(__LL_RCC_CALC_HCLK1_FREQ(HAL_RCC_GetSysClockFreq(),
943 LL_RCC_GetAHBPrescaler()),
944 LL_RCC_GetAPB1Prescaler());
945 break;
946 }
947 }
948 #endif /* I2C3 */
949 else if (PeriphClk == RCC_PERIPHCLK_LPTIM1)
950 {
951 uint32_t lptimClockSource = LL_RCC_GetLPTIMClockSource(LL_RCC_LPTIM1_CLKSOURCE);
952
953 if (lptimClockSource == LL_RCC_LPTIM1_CLKSOURCE_LSI) /* LPTIM1 Clock is LSI Osc. */
954 {
955 const uint32_t temp_lsi1ready = LL_RCC_LSI1_IsReady();
956 const uint32_t temp_lsi2ready = LL_RCC_LSI2_IsReady();
957 if ((temp_lsi1ready == 1U) || (temp_lsi2ready == 1U))
958 {
959 frequency = LSI_VALUE;
960 }
961 else
962 {
963 /* Nothing to do as frequency already initialized to 0U */
964 }
965 }
966 else if (lptimClockSource == LL_RCC_LPTIM1_CLKSOURCE_HSI) /* LPTIM1 Clock is HSI Osc. */
967 {
968 if (LL_RCC_HSI_IsReady() == 1U)
969 {
970 frequency = HSI_VALUE;
971 }
972 else
973 {
974 /* Nothing to do as frequency already initialized to 0U */
975 }
976 }
977 else if (lptimClockSource == LL_RCC_LPTIM1_CLKSOURCE_LSE) /* LPTIM1 Clock is LSE Osc. */
978 {
979 if (LL_RCC_LSE_IsReady() == 1U)
980 {
981 frequency = LSE_VALUE;
982 }
983 else
984 {
985 /* Nothing to do as frequency already initialized to 0U */
986 }
987 }
988 else /* LPTIM1 Clock is PCLK1 */
989 {
990 frequency = __LL_RCC_CALC_PCLK1_FREQ(__LL_RCC_CALC_HCLK1_FREQ(HAL_RCC_GetSysClockFreq(),
991 LL_RCC_GetAHBPrescaler()),
992 LL_RCC_GetAPB1Prescaler());
993 }
994 }
995 else if (PeriphClk == RCC_PERIPHCLK_LPTIM2)
996 {
997 uint32_t lptimClockSource = LL_RCC_GetLPTIMClockSource(LL_RCC_LPTIM2_CLKSOURCE);
998
999 if (lptimClockSource == LL_RCC_LPTIM2_CLKSOURCE_LSI) /* LPTIM2 Clock is LSI Osc. */
1000 {
1001 const uint32_t temp_lsi1ready = LL_RCC_LSI1_IsReady();
1002 const uint32_t temp_lsi2ready = LL_RCC_LSI2_IsReady();
1003 if ((temp_lsi1ready == 1U) || (temp_lsi2ready == 1U))
1004 {
1005 frequency = LSI_VALUE;
1006 }
1007 else
1008 {
1009 /* Nothing to do as frequency already initialized to 0U */
1010 }
1011 }
1012 else if (lptimClockSource == LL_RCC_LPTIM2_CLKSOURCE_HSI) /* LPTIM2 Clock is HSI Osc. */
1013 {
1014 if (LL_RCC_HSI_IsReady() == 1U)
1015 {
1016 frequency = HSI_VALUE;
1017 }
1018 else
1019 {
1020 /* Nothing to do as frequency already initialized to 0U */
1021 }
1022 }
1023 else if (lptimClockSource == LL_RCC_LPTIM2_CLKSOURCE_LSE) /* LPTIM2 Clock is LSE Osc. */
1024 {
1025 if (LL_RCC_LSE_IsReady() == 1U)
1026 {
1027 frequency = LSE_VALUE;
1028 }
1029 else
1030 {
1031 /* Nothing to do as frequency already initialized to 0U */
1032 }
1033 }
1034 else /* LPTIM2 Clock is PCLK1 */
1035 {
1036 frequency = __LL_RCC_CALC_PCLK1_FREQ(__LL_RCC_CALC_HCLK1_FREQ(HAL_RCC_GetSysClockFreq(),
1037 LL_RCC_GetAHBPrescaler()),
1038 LL_RCC_GetAPB1Prescaler());
1039 }
1040 }
1041 else if (PeriphClk == RCC_PERIPHCLK_RFWAKEUP)
1042 {
1043 uint32_t rfwkpClockSource = LL_RCC_GetRFWKPClockSource();
1044
1045 if (rfwkpClockSource == LL_RCC_RFWKP_CLKSOURCE_LSE) /* LSE clock used as RF Wakeup clock source */
1046 {
1047 if (LL_RCC_LSE_IsReady() == 1U)
1048 {
1049 frequency = LSE_VALUE;
1050 }
1051 else
1052 {
1053 /* Nothing to do as frequency already initialized to 0U */
1054 }
1055 }
1056 else if (rfwkpClockSource == LL_RCC_RFWKP_CLKSOURCE_HSE_DIV1024) /* HSE clock used as RF Wakeup clock source */
1057 {
1058 frequency = HSE_VALUE / 1024U;
1059 }
1060 else /* No clock used as RF Wakeup clock source */
1061 {
1062 /* Nothing to do as frequency already initialized to 0U */
1063 }
1064 }
1065 #if defined(RCC_SMPS_SUPPORT)
1066 else if (PeriphClk == RCC_PERIPHCLK_SMPS)
1067 {
1068 uint32_t smpsClockSource = LL_RCC_GetSMPSClockSource();
1069
1070 if (smpsClockSource == LL_RCC_SMPS_CLKSOURCE_STATUS_HSI) /* SMPS Clock source is HSI Osc. */
1071 {
1072 if (LL_RCC_HSI_IsReady() == 1U)
1073 {
1074 frequency = HSI_VALUE / SmpsPrescalerTable[smps_prescaler_index][0];
1075 frequency = frequency >> 1U; /* Systematic Div by 2 */
1076 }
1077 else
1078 {
1079 /* Nothing to do as frequency already initialized to 0U */
1080 }
1081 }
1082 else if (smpsClockSource == LL_RCC_SMPS_CLKSOURCE_STATUS_HSE) /* SMPS Clock source is HSE Osc. */
1083 {
1084 if (LL_RCC_HSE_IsReady() == 1U)
1085 {
1086 frequency = HSE_VALUE / SmpsPrescalerTable[smps_prescaler_index][5];
1087 frequency = frequency >> 1U; /* Systematic Div by 2 */
1088 }
1089 else
1090 {
1091 /* Nothing to do as frequency already initialized to 0U */
1092 }
1093 }
1094 else if (smpsClockSource == LL_RCC_SMPS_CLKSOURCE_STATUS_MSI) /* SMPS Clock source is MSI Osc. */
1095 {
1096 switch (LL_RCC_MSI_GetRange())
1097 {
1098 case LL_RCC_MSIRANGE_8:
1099 frequency = __LL_RCC_CALC_MSI_FREQ(LL_RCC_MSIRANGE_8) / SmpsPrescalerTable[smps_prescaler_index][4];
1100 break;
1101 case LL_RCC_MSIRANGE_9:
1102 frequency = __LL_RCC_CALC_MSI_FREQ(LL_RCC_MSIRANGE_9) / SmpsPrescalerTable[smps_prescaler_index][3];
1103 break;
1104 case LL_RCC_MSIRANGE_10:
1105 frequency = __LL_RCC_CALC_MSI_FREQ(LL_RCC_MSIRANGE_10) / SmpsPrescalerTable[smps_prescaler_index][2];
1106 break;
1107 case LL_RCC_MSIRANGE_11:
1108 frequency = __LL_RCC_CALC_MSI_FREQ(LL_RCC_MSIRANGE_11) / SmpsPrescalerTable[smps_prescaler_index][1];
1109 break;
1110 default:
1111 break;
1112 }
1113 frequency = frequency >> 1U; /* Systematic Div by 2 */
1114 }
1115 else /* SMPS has no Clock */
1116 {
1117 /* Nothing to do as frequency already initialized to 0U */
1118 }
1119 }
1120 #endif /* RCC_SMPS_SUPPORT */
1121
1122 return (frequency);
1123 }
1124
1125 /**
1126 * @brief Return the RNG clock source
1127 * @retval The RNG clock source can be one of the following values:
1128 * @arg @ref RCC_RNGCLKSOURCE_HSI48 HSI48 clock divided by 3 selected as RNG clock
1129 * @arg @ref RCC_RNGCLKSOURCE_PLL PLL "Q" clock divided by 3 selected as RNG clock
1130 * @arg @ref RCC_RNGCLKSOURCE_MSI MSI clock divided by 3 selected as RNG clock
1131 * @arg @ref RCC_RNGCLKSOURCE_PLLSAI1 PLLSAI1 "Q" clock selected as RNG clock (*)
1132 * @arg @ref RCC_RNGCLKSOURCE_LSI LSI clock selected as RNG clock
1133 * @arg @ref RCC_RNGCLKSOURCE_LSE LSE clock selected as RNG clock
1134 *
1135 * (*) Value not defined in all devices.
1136 *
1137 */
HAL_RCCEx_GetRngCLKSource(void)1138 uint32_t HAL_RCCEx_GetRngCLKSource(void)
1139 {
1140 uint32_t rng_clock_source = LL_RCC_GetRNGClockSource(LL_RCC_RNG_CLKSOURCE);
1141 uint32_t clk48_clock_source;
1142
1143 /* RNG clock source originates from 48 MHz RC oscillator */
1144 if (rng_clock_source == RCC_RNGCLKSOURCE_CLK48)
1145 {
1146 clk48_clock_source = LL_RCC_GetCLK48ClockSource(LL_RCC_CLK48_CLKSOURCE);
1147 rng_clock_source = (CLK48_MASK | clk48_clock_source);
1148 }
1149
1150 return rng_clock_source;
1151 }
1152
1153 /**
1154 * @}
1155 */
1156
1157 /** @defgroup RCCEx_Exported_Functions_Group2 Extended Clock management functions
1158 * @brief Extended Clock management functions
1159 *
1160 @verbatim
1161 ===============================================================================
1162 ##### Extended clock management functions #####
1163 ===============================================================================
1164 [..]
1165 This subsection provides a set of functions allowing to control the
1166 activation or deactivation of MSI PLL-mode, PLLSAI1, PLLSAI12, LSE CSS,
1167 Low speed clock output and clock after wake-up from STOP mode.
1168 @endverbatim
1169 * @{
1170 */
1171
1172 #if defined(SAI1)
1173 /**
1174 * @brief Enable PLLSAI1.
1175 * @param PLLSAI1Init pointer to an RCC_PLLSAI1InitTypeDef structure that
1176 * contains the configuration information for the PLLSAI1
1177 * @retval HAL status
1178 */
HAL_RCCEx_EnablePLLSAI1(RCC_PLLSAI1InitTypeDef * PLLSAI1Init)1179 HAL_StatusTypeDef HAL_RCCEx_EnablePLLSAI1(RCC_PLLSAI1InitTypeDef *PLLSAI1Init)
1180 {
1181 uint32_t tickstart;
1182 HAL_StatusTypeDef status = HAL_OK;
1183
1184 /* check for PLLSAI1 Parameters used to output PLLSAI1CLK */
1185 assert_param(IS_RCC_PLLN_VALUE(PLLSAI1Init->PLLN));
1186 assert_param(IS_RCC_PLLP_VALUE(PLLSAI1Init->PLLP));
1187 assert_param(IS_RCC_PLLQ_VALUE(PLLSAI1Init->PLLQ));
1188 assert_param(IS_RCC_PLLR_VALUE(PLLSAI1Init->PLLR));
1189 assert_param(IS_RCC_PLLSAI1CLOCKOUT_VALUE(PLLSAI1Init->PLLSAI1ClockOut));
1190
1191 /* Disable the PLLSAI1 */
1192 __HAL_RCC_PLLSAI1_DISABLE();
1193
1194 /* Get Start Tick*/
1195 tickstart = HAL_GetTick();
1196
1197 /* Wait till PLLSAI1 is ready to be updated */
1198 while (LL_RCC_PLLSAI1_IsReady() != 0U)
1199 {
1200 if ((HAL_GetTick() - tickstart) > PLLSAI1_TIMEOUT_VALUE)
1201 {
1202 status = HAL_TIMEOUT;
1203 break;
1204 }
1205 }
1206
1207 if (status == HAL_OK)
1208 {
1209 /* Configure the PLLSAI1 Multiplication factor N */
1210 /* Configure the PLLSAI1 Division factors P, Q and R */
1211 __HAL_RCC_PLLSAI1_CONFIG(PLLSAI1Init->PLLN, PLLSAI1Init->PLLP, PLLSAI1Init->PLLQ, PLLSAI1Init->PLLR);
1212 /* Configure the PLLSAI1 Clock output(s) */
1213 __HAL_RCC_PLLSAI1CLKOUT_ENABLE(PLLSAI1Init->PLLSAI1ClockOut);
1214
1215 /* Enable the PLLSAI1 again by setting PLLSAI1ON to 1*/
1216 __HAL_RCC_PLLSAI1_ENABLE();
1217
1218 /* Get Start Tick*/
1219 tickstart = HAL_GetTick();
1220
1221 /* Wait till PLLSAI1 is ready */
1222 while (LL_RCC_PLLSAI1_IsReady() != 1U)
1223 {
1224 if ((HAL_GetTick() - tickstart) > PLLSAI1_TIMEOUT_VALUE)
1225 {
1226 status = HAL_TIMEOUT;
1227 break;
1228 }
1229 }
1230 }
1231
1232 return status;
1233 }
1234
1235 /**
1236 * @brief Disable PLLSAI1.
1237 * @retval HAL status
1238 */
HAL_RCCEx_DisablePLLSAI1(void)1239 HAL_StatusTypeDef HAL_RCCEx_DisablePLLSAI1(void)
1240 {
1241 uint32_t tickstart;
1242 HAL_StatusTypeDef status = HAL_OK;
1243
1244 /* Disable the PLLSAI1 */
1245 __HAL_RCC_PLLSAI1_DISABLE();
1246
1247 /* Get Start Tick*/
1248 tickstart = HAL_GetTick();
1249
1250 /* Wait till PLLSAI1 is ready */
1251 while (LL_RCC_PLLSAI1_IsReady() != 0U)
1252 {
1253 if ((HAL_GetTick() - tickstart) > PLLSAI1_TIMEOUT_VALUE)
1254 {
1255 status = HAL_TIMEOUT;
1256 break;
1257 }
1258 }
1259
1260 /* Disable the PLLSAI1 Clock outputs */
1261 __HAL_RCC_PLLSAI1CLKOUT_DISABLE(RCC_PLLSAI1_SAI1CLK | RCC_PLLSAI1_USBCLK | RCC_PLLSAI1_ADCCLK);
1262
1263 return status;
1264 }
1265 #endif /* SAI1 */
1266
1267 /***********************************************************************************************/
1268
1269 /**
1270 * @brief Configure the oscillator clock source for wakeup from Stop and CSS backup clock.
1271 * @param WakeUpClk Wakeup clock
1272 * This parameter can be one of the following values:
1273 * @arg @ref RCC_STOP_WAKEUPCLOCK_MSI MSI oscillator selection
1274 * @arg @ref RCC_STOP_WAKEUPCLOCK_HSI HSI oscillator selection
1275 * @note This function shall not be called after the Clock Security System on HSE has been
1276 * enabled.
1277 * @retval None
1278 */
HAL_RCCEx_WakeUpStopCLKConfig(uint32_t WakeUpClk)1279 void HAL_RCCEx_WakeUpStopCLKConfig(uint32_t WakeUpClk)
1280 {
1281 assert_param(IS_RCC_STOP_WAKEUPCLOCK(WakeUpClk));
1282
1283 __HAL_RCC_WAKEUPSTOP_CLK_CONFIG(WakeUpClk);
1284 }
1285
1286 /**
1287 * @brief Enable the LSE Clock Security System.
1288 * @note Prior to enable the LSE Clock Security System, LSE oscillator is to be enabled
1289 * with HAL_RCC_OscConfig() and the LSE oscillator clock is to be selected as RTC
1290 * clock with HAL_RCCEx_PeriphCLKConfig().
1291 * @retval None
1292 */
HAL_RCCEx_EnableLSECSS(void)1293 void HAL_RCCEx_EnableLSECSS(void)
1294 {
1295 LL_RCC_LSE_EnableCSS();
1296 }
1297
1298 /**
1299 * @brief Disable the LSE Clock Security System.
1300 * @note LSE Clock Security System can only be disabled after a LSE failure detection.
1301 * @retval None
1302 */
HAL_RCCEx_DisableLSECSS(void)1303 void HAL_RCCEx_DisableLSECSS(void)
1304 {
1305 LL_RCC_LSE_DisableCSS();
1306
1307 /* Disable LSE CSS IT if any */
1308 __HAL_RCC_DISABLE_IT(RCC_IT_LSECSS);
1309 }
1310
1311 /**
1312 * @brief Enable the LSE Clock Security System Interrupt & corresponding EXTI line.
1313 * @note LSE Clock Security System Interrupt is mapped on RTC EXTI line 18
1314 * @retval None
1315 */
HAL_RCCEx_EnableLSECSS_IT(void)1316 void HAL_RCCEx_EnableLSECSS_IT(void)
1317 {
1318 /* Enable LSE CSS */
1319 LL_RCC_LSE_EnableCSS();
1320
1321 /* Enable LSE CSS IT */
1322 __HAL_RCC_ENABLE_IT(RCC_IT_LSECSS);
1323
1324 /* Enable IT on EXTI Line 18 */
1325 __HAL_RCC_LSECSS_EXTI_ENABLE_IT();
1326 __HAL_RCC_LSECSS_EXTI_ENABLE_RISING_EDGE();
1327 }
1328
1329 /**
1330 * @brief Handle the RCC LSE Clock Security System interrupt request.
1331 * @retval None
1332 */
HAL_RCCEx_LSECSS_IRQHandler(void)1333 void HAL_RCCEx_LSECSS_IRQHandler(void)
1334 {
1335 /* Check RCC LSE CSSF flag */
1336 if (__HAL_RCC_GET_IT(RCC_IT_LSECSS))
1337 {
1338 /* RCC LSE Clock Security System interrupt user callback */
1339 HAL_RCCEx_LSECSS_Callback();
1340
1341 /* Clear RCC LSE CSS pending bit */
1342 __HAL_RCC_CLEAR_IT(RCC_IT_LSECSS);
1343 }
1344 }
1345
1346 /**
1347 * @brief RCCEx LSE Clock Security System interrupt callback.
1348 * @retval none
1349 */
HAL_RCCEx_LSECSS_Callback(void)1350 __weak void HAL_RCCEx_LSECSS_Callback(void)
1351 {
1352 /* NOTE : This function should not be modified, when the callback is needed,
1353 the HAL_RCCEx_LSECSS_Callback should be implemented in the user file
1354 */
1355 }
1356
1357 /**
1358 * @brief Select the clock source to output on LSCO1 pin(PA2) or LSC02 pin (PH3) or LSCO3 pin (PC12).
1359 * @note PA2, PH3 or PC12 should be configured in alternate function mode.
1360 * @param RCC_LSCOx specifies the output direction for the clock source.
1361 * @arg @ref RCC_LSCO1 Clock source to output on LSCO1 pin(PA2)
1362 * @arg @ref RCC_LSCO2 Clock source to output on LSCO2 pin(PH3)
1363 * @arg @ref RCC_LSCO3 Clock source to output on LSCO3 pin(PC12)
1364 * @param RCC_LSCOSource specifies the clock source to output.
1365 * This parameter can be one of the following values:
1366 * @arg @ref RCC_LSCOSOURCE_LSI LSI clock selected as LSCO source
1367 * @arg @ref RCC_LSCOSOURCE_LSE LSE clock selected as LSCO source
1368 * @retval None
1369 * @note LSCO should be disable with @ref HAL_RCCEx_DisableLSCO
1370 */
HAL_RCCEx_LSCOConfig(uint32_t RCC_LSCOx,uint32_t RCC_LSCOSource)1371 void HAL_RCCEx_LSCOConfig(uint32_t RCC_LSCOx, uint32_t RCC_LSCOSource)
1372 {
1373 GPIO_InitTypeDef GPIO_InitStruct;
1374 FlagStatus backupchanged;
1375
1376 /* Check the parameters */
1377 assert_param(IS_RCC_LSCO(RCC_LSCOx));
1378 assert_param(IS_RCC_LSCOSOURCE(RCC_LSCOSource));
1379
1380 /* Common GPIO init parameters */
1381 GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
1382 GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
1383 GPIO_InitStruct.Pull = GPIO_NOPULL;
1384
1385 /* RCC_LSCO1 */
1386 if (RCC_LSCOx == RCC_LSCO1)
1387 {
1388 /* LSCO1 Clock Enable */
1389 __LSCO1_CLK_ENABLE();
1390 /* Configure the LSCO1 pin in alternate function mode */
1391 GPIO_InitStruct.Pin = LSCO1_PIN;
1392 GPIO_InitStruct.Alternate = GPIO_AF0_LSCO;
1393 HAL_GPIO_Init(LSCO1_GPIO_PORT, &GPIO_InitStruct);
1394 }
1395 else if (RCC_LSCOx == RCC_LSCO2)
1396 {
1397 /* LSCO2 Clock Enable */
1398 __LSCO2_CLK_ENABLE();
1399 /* Configure the LSCO2 pin in alternate function mode */
1400 GPIO_InitStruct.Pin = LSCO2_PIN;
1401 GPIO_InitStruct.Alternate = GPIO_AF0_LSCO;
1402 HAL_GPIO_Init(LSCO2_GPIO_PORT, &GPIO_InitStruct);
1403
1404 }
1405 #if defined(RCC_LSCO3_SUPPORT)
1406 else if (RCC_LSCOx == RCC_LSCO3)
1407 {
1408 /* LSCO3 Clock Enable */
1409 __LSCO3_CLK_ENABLE();
1410 /* Configure the LSCO3 pin in alternate function mode */
1411 GPIO_InitStruct.Pin = LSCO3_PIN;
1412 GPIO_InitStruct.Alternate = GPIO_AF6_LSCO;
1413 HAL_GPIO_Init(LSCO3_GPIO_PORT, &GPIO_InitStruct);
1414 }
1415 #endif /* RCC_LSCO3_SUPPORT */
1416 else
1417 {
1418 ;
1419 }
1420
1421 /* Update LSCOSEL clock source in Backup Domain control register */
1422 if (HAL_IS_BIT_CLR(PWR->CR1, PWR_CR1_DBP))
1423 {
1424 HAL_PWR_EnableBkUpAccess();
1425 backupchanged = SET;
1426 }
1427 else
1428 {
1429 backupchanged = RESET;
1430 }
1431
1432 MODIFY_REG(RCC->BDCR, RCC_BDCR_LSCOSEL | RCC_BDCR_LSCOEN, RCC_LSCOSource | RCC_BDCR_LSCOEN);
1433
1434 if (backupchanged == SET)
1435 {
1436 HAL_PWR_DisableBkUpAccess();
1437 }
1438
1439 }
1440
1441 /**
1442 * @brief Select the Low Speed clock source to output on LSCO pin (PA2).
1443 * @param LSCOSource specifies the Low Speed clock source to output.
1444 * This parameter can be one of the following values:
1445 * @arg @ref RCC_LSCOSOURCE_LSI LSI clock selected as LSCO source
1446 * @arg @ref RCC_LSCOSOURCE_LSE LSE clock selected as LSCO source
1447 * @retval None
1448 */
HAL_RCCEx_EnableLSCO(uint32_t LSCOSource)1449 void HAL_RCCEx_EnableLSCO(uint32_t LSCOSource)
1450 {
1451 /* Check the parameters */
1452 assert_param(IS_RCC_LSCOSOURCE(LSCOSource));
1453
1454 /* Update LSCO selection according to parameter and enable LSCO */
1455 MODIFY_REG(RCC->BDCR, RCC_BDCR_LSCOSEL, LSCOSource | RCC_BDCR_LSCOEN);
1456 }
1457
1458 /**
1459 * @brief Disable the Low Speed clock output.
1460 * @retval None
1461 */
HAL_RCCEx_DisableLSCO(void)1462 void HAL_RCCEx_DisableLSCO(void)
1463 {
1464 LL_RCC_LSCO_Disable();
1465 }
1466
1467 /**
1468 * @brief Enable the PLL-mode of the MSI.
1469 * @note Prior to enable the PLL-mode of the MSI for automatic hardware
1470 * calibration LSE oscillator is to be enabled with @ref HAL_RCC_OscConfig().
1471 * @retval None
1472 */
HAL_RCCEx_EnableMSIPLLMode(void)1473 void HAL_RCCEx_EnableMSIPLLMode(void)
1474 {
1475 LL_RCC_MSI_EnablePLLMode() ;
1476 }
1477
1478 /**
1479 * @brief Disable the PLL-mode of the MSI.
1480 * @note PLL-mode of the MSI is automatically reset when LSE oscillator is disabled.
1481 * @retval None
1482 */
HAL_RCCEx_DisableMSIPLLMode(void)1483 void HAL_RCCEx_DisableMSIPLLMode(void)
1484 {
1485 LL_RCC_MSI_DisablePLLMode() ;
1486 }
1487
1488 /**
1489 * @brief Set trimming value
1490 * @param OscillatorType Specifies the oscillator to be trimmed
1491 * This parameter can be one of the following values:
1492 * @arg @ref RCC_OSCILLATORTYPE_LSI2 LSI2 oscillator selected.
1493 * When disabling and re-enabling the LSI2 there is no need for re-trimming
1494 * Trimming is only needed once after a NRST reset.
1495 * Trimming values comes from factory trimmed flash location (0x1FFF7548).
1496 * @note The LSI2 oscillator must be disabled before calling this trimming function through @ref HAL_RCC_OscConfig
1497 * @retval HAL status
1498 */
HAL_RCCEx_TrimOsc(uint32_t OscillatorType)1499 HAL_StatusTypeDef HAL_RCCEx_TrimOsc(uint32_t OscillatorType)
1500 {
1501 #define FTLSI2TRIM (0xFUL)
1502 HAL_StatusTypeDef status = HAL_OK;
1503
1504 assert_param(IS_RCC_TRIMOSC(OscillatorType));
1505
1506 if (OscillatorType == RCC_OSCILLATORTYPE_LSI2)
1507 {
1508 if (LL_RCC_LSI2_IsReady() == 1U)
1509 {
1510 status = HAL_ERROR;
1511 }
1512 else
1513 {
1514 /* Copy the LSI2 trimming information from the factory trimmed Flash location */
1515 uint32_t factoryTrimming = ((*(uint32_t *)(0x1FFF7548)) & FTLSI2TRIM);
1516 LL_RCC_LSI2_SetTrimming(factoryTrimming);
1517 }
1518 }
1519 else
1520 {
1521 status = HAL_ERROR;
1522 }
1523 return status;
1524 }
1525
1526 /**
1527 * @}
1528 */
1529
1530 #if defined(CRS)
1531 /** @defgroup RCCEx_Exported_Functions_Group3 Extended Clock Recovery System Control functions
1532 * @brief Extended Clock Recovery System Control functions
1533 *
1534 @verbatim
1535 ===============================================================================
1536 ##### Extended Clock Recovery System Control functions #####
1537 ===============================================================================
1538 [..]
1539 For devices with Clock Recovery System feature (CRS), RCC Extended HAL driver can be used as follows:
1540
1541 (#) In System clock config, HSI48 needs to be enabled
1542
1543 (#) Enable CRS clock in IP MSP init which will use CRS functions
1544
1545 (#) Call CRS functions as follows:
1546 (##) Prepare synchronization configuration necessary for HSI48 calibration
1547 (+++) Default values can be set for frequency Error Measurement (reload and error limit)
1548 and also HSI48 oscillator smooth trimming.
1549 (+++) Macro __HAL_RCC_CRS_RELOADVALUE_CALCULATE can be also used to calculate
1550 directly reload value with target and synchronization frequencies values
1551 (##) Call function HAL_RCCEx_CRSConfig which
1552 (+++) Resets CRS registers to their default values.
1553 (+++) Configures CRS registers with synchronization configuration
1554 (+++) Enables automatic calibration and frequency error counter feature
1555 Note: When using USB LPM (Link Power Management) and the device is in Sleep mode, the
1556 periodic USB SOF will not be generated by the host. No SYNC signal will therefore be
1557 provided to the CRS to calibrate the HSI48 on the run. To guarantee the required clock
1558 precision after waking up from Sleep mode, the LSE or reference clock on the GPIOs
1559 should be used as SYNC signal.
1560
1561 (##) A polling function is provided to wait for complete synchronization
1562 (+++) Call function HAL_RCCEx_CRSWaitSynchronization()
1563 (+++) According to CRS status, user can decide to adjust again the calibration or continue
1564 application if synchronization is OK
1565
1566 (#) User can retrieve information related to synchronization in calling function
1567 HAL_RCCEx_CRSGetSynchronizationInfo()
1568
1569 (#) Regarding synchronization status and synchronization information, user can try a new calibration
1570 in changing synchronization configuration and call again HAL_RCCEx_CRSConfig.
1571 Note: When the SYNC event is detected during the downcounting phase (before reaching the zero value),
1572 it means that the actual frequency is lower than the target (and so, that the TRIM value should be
1573 incremented), while when it is detected during the upcounting phase it means that the actual frequency
1574 is higher (and that the TRIM value should be decremented).
1575
1576 (#) In interrupt mode, user can resort to the available macros (__HAL_RCC_CRS_XXX_IT). Interrupts will go
1577 through CRS Handler (CRS_IRQn/CRS_IRQHandler)
1578 (++) Call function HAL_RCCEx_CRSConfig()
1579 (++) Enable CRS_IRQn (thanks to NVIC functions)
1580 (++) Enable CRS interrupt (__HAL_RCC_CRS_ENABLE_IT)
1581 (++) Implement CRS status management in the following user callbacks called from
1582 HAL_RCCEx_CRS_IRQHandler():
1583 (+++) HAL_RCCEx_CRS_SyncOkCallback()
1584 (+++) HAL_RCCEx_CRS_SyncWarnCallback()
1585 (+++) HAL_RCCEx_CRS_ExpectedSyncCallback()
1586 (+++) HAL_RCCEx_CRS_ErrorCallback()
1587
1588 (#) To force a SYNC EVENT, user can use the function HAL_RCCEx_CRSSoftwareSynchronizationGenerate().
1589 This function can be called before calling HAL_RCCEx_CRSConfig (for instance in Systick handler)
1590
1591 @endverbatim
1592 * @{
1593 */
1594
1595 /**
1596 * @brief Start automatic synchronization for polling mode
1597 * @param pInit Pointer on RCC_CRSInitTypeDef structure
1598 * @retval None
1599 */
HAL_RCCEx_CRSConfig(RCC_CRSInitTypeDef * pInit)1600 void HAL_RCCEx_CRSConfig(RCC_CRSInitTypeDef *pInit)
1601 {
1602 uint32_t value;
1603
1604 /* Check the parameters */
1605 assert_param(IS_RCC_CRS_SYNC_DIV(pInit->Prescaler));
1606 assert_param(IS_RCC_CRS_SYNC_SOURCE(pInit->Source));
1607 assert_param(IS_RCC_CRS_SYNC_POLARITY(pInit->Polarity));
1608 assert_param(IS_RCC_CRS_RELOADVALUE(pInit->ReloadValue));
1609 assert_param(IS_RCC_CRS_ERRORLIMIT(pInit->ErrorLimitValue));
1610 assert_param(IS_RCC_CRS_HSI48CALIBRATION(pInit->HSI48CalibrationValue));
1611
1612 /* CONFIGURATION */
1613
1614 /* Before configuration, reset CRS registers to their default values*/
1615 __HAL_RCC_CRS_FORCE_RESET();
1616 __HAL_RCC_CRS_RELEASE_RESET();
1617
1618 /* Set the SYNCDIV[2:0] bits according to Prescaler value */
1619 /* Set the SYNCSRC[1:0] bits according to Source value */
1620 /* Set the SYNCSPOL bit according to Polarity value */
1621 value = (pInit->Prescaler | pInit->Source | pInit->Polarity);
1622 /* Set the RELOAD[15:0] bits according to ReloadValue value */
1623 value |= pInit->ReloadValue;
1624 /* Set the FELIM[7:0] bits according to ErrorLimitValue value */
1625 value |= (pInit->ErrorLimitValue << CRS_CFGR_FELIM_Pos);
1626 WRITE_REG(CRS->CFGR, value);
1627
1628 /* Adjust HSI48 oscillator smooth trimming */
1629 /* Set the TRIM[5:0] bits according to RCC_CRS_HSI48CalibrationValue value */
1630 MODIFY_REG(CRS->CR, CRS_CR_TRIM, (pInit->HSI48CalibrationValue << CRS_CR_TRIM_Pos));
1631
1632 /* START AUTOMATIC SYNCHRONIZATION*/
1633
1634 /* Enable Automatic trimming & Frequency error counter */
1635 SET_BIT(CRS->CR, CRS_CR_AUTOTRIMEN | CRS_CR_CEN);
1636 }
1637
1638 /**
1639 * @brief Generate the software synchronization event
1640 * @retval None
1641 */
HAL_RCCEx_CRSSoftwareSynchronizationGenerate(void)1642 void HAL_RCCEx_CRSSoftwareSynchronizationGenerate(void)
1643 {
1644 LL_CRS_GenerateEvent_SWSYNC();
1645 }
1646
1647 /**
1648 * @brief Return synchronization info
1649 * @param pSynchroInfo Pointer on @ref RCC_CRSSynchroInfoTypeDef structure
1650 * @retval None
1651 */
HAL_RCCEx_CRSGetSynchronizationInfo(RCC_CRSSynchroInfoTypeDef * pSynchroInfo)1652 void HAL_RCCEx_CRSGetSynchronizationInfo(RCC_CRSSynchroInfoTypeDef *pSynchroInfo)
1653 {
1654 /* Check the parameter */
1655 assert_param(pSynchroInfo != (void *)NULL);
1656
1657 /* Get the reload value */
1658 pSynchroInfo->ReloadValue = LL_CRS_GetReloadCounter();
1659
1660 /* Get HSI48 oscillator smooth trimming */
1661 pSynchroInfo->HSI48CalibrationValue = LL_CRS_GetHSI48SmoothTrimming();
1662
1663 /* Get Frequency error capture */
1664 pSynchroInfo->FreqErrorCapture = LL_CRS_GetFreqErrorCapture();
1665
1666 /* Get Frequency error direction */
1667 pSynchroInfo->FreqErrorDirection = LL_CRS_GetFreqErrorDirection();
1668 }
1669
1670 /**
1671 * @brief Wait for CRS Synchronization status.
1672 * @param Timeout Duration of the timeout
1673 * @note Timeout is based on the maximum time to receive a SYNC event based on synchronization
1674 * frequency.
1675 * @note If Timeout set to HAL_MAX_DELAY, HAL_TIMEOUT will be never returned.
1676 * @retval Combination of Synchronization status
1677 * This parameter can be a combination of the following values:
1678 * @arg @ref RCC_CRS_TIMEOUT
1679 * @arg @ref RCC_CRS_SYNCOK
1680 * @arg @ref RCC_CRS_SYNCWARN
1681 * @arg @ref RCC_CRS_SYNCERR
1682 * @arg @ref RCC_CRS_SYNCMISS
1683 * @arg @ref RCC_CRS_TRIMOVF
1684 */
HAL_RCCEx_CRSWaitSynchronization(uint32_t Timeout)1685 uint32_t HAL_RCCEx_CRSWaitSynchronization(uint32_t Timeout)
1686 {
1687 uint32_t crsstatus = RCC_CRS_NONE;
1688 uint32_t tickstart;
1689
1690 /* Get timeout */
1691 tickstart = HAL_GetTick();
1692
1693 /* Wait for CRS flag or timeout detection */
1694 do
1695 {
1696 if (Timeout != HAL_MAX_DELAY)
1697 {
1698 if (((HAL_GetTick() - tickstart) > Timeout) || (Timeout == 0U))
1699 {
1700 crsstatus = RCC_CRS_TIMEOUT;
1701 }
1702 }
1703 /* Check CRS SYNCOK flag */
1704 if (__HAL_RCC_CRS_GET_FLAG(RCC_CRS_FLAG_SYNCOK))
1705 {
1706 /* CRS SYNC event OK */
1707 crsstatus |= RCC_CRS_SYNCOK;
1708
1709 /* Clear CRS SYNC event OK bit */
1710 __HAL_RCC_CRS_CLEAR_FLAG(RCC_CRS_FLAG_SYNCOK);
1711 }
1712
1713 /* Check CRS SYNCWARN flag */
1714 if (__HAL_RCC_CRS_GET_FLAG(RCC_CRS_FLAG_SYNCWARN))
1715 {
1716 /* CRS SYNC warning */
1717 crsstatus |= RCC_CRS_SYNCWARN;
1718
1719 /* Clear CRS SYNCWARN bit */
1720 __HAL_RCC_CRS_CLEAR_FLAG(RCC_CRS_FLAG_SYNCWARN);
1721 }
1722
1723 /* Check CRS TRIM overflow flag */
1724 if (__HAL_RCC_CRS_GET_FLAG(RCC_CRS_FLAG_TRIMOVF))
1725 {
1726 /* CRS SYNC Error */
1727 crsstatus |= RCC_CRS_TRIMOVF;
1728
1729 /* Clear CRS Error bit */
1730 __HAL_RCC_CRS_CLEAR_FLAG(RCC_CRS_FLAG_TRIMOVF);
1731 }
1732
1733 /* Check CRS Error flag */
1734 if (__HAL_RCC_CRS_GET_FLAG(RCC_CRS_FLAG_SYNCERR))
1735 {
1736 /* CRS SYNC Error */
1737 crsstatus |= RCC_CRS_SYNCERR;
1738
1739 /* Clear CRS Error bit */
1740 __HAL_RCC_CRS_CLEAR_FLAG(RCC_CRS_FLAG_SYNCERR);
1741 }
1742
1743 /* Check CRS SYNC Missed flag */
1744 if (__HAL_RCC_CRS_GET_FLAG(RCC_CRS_FLAG_SYNCMISS))
1745 {
1746 /* CRS SYNC Missed */
1747 crsstatus |= RCC_CRS_SYNCMISS;
1748
1749 /* Clear CRS SYNC Missed bit */
1750 __HAL_RCC_CRS_CLEAR_FLAG(RCC_CRS_FLAG_SYNCMISS);
1751 }
1752
1753 /* Check CRS Expected SYNC flag */
1754 if (__HAL_RCC_CRS_GET_FLAG(RCC_CRS_FLAG_ESYNC))
1755 {
1756 /* frequency error counter reached a zero value */
1757 __HAL_RCC_CRS_CLEAR_FLAG(RCC_CRS_FLAG_ESYNC);
1758 }
1759 } while (RCC_CRS_NONE == crsstatus);
1760
1761 return crsstatus;
1762 }
1763
1764 /**
1765 * @brief Handle the Clock Recovery System interrupt request.
1766 * @retval None
1767 */
HAL_RCCEx_CRS_IRQHandler(void)1768 void HAL_RCCEx_CRS_IRQHandler(void)
1769 {
1770 uint32_t crserror = RCC_CRS_NONE;
1771 /* Get current IT flags and IT sources values */
1772 uint32_t itflags = READ_REG(CRS->ISR);
1773 uint32_t itsources = READ_REG(CRS->CR);
1774
1775 /* Check CRS SYNCOK flag */
1776 if (((itflags & RCC_CRS_FLAG_SYNCOK) != 0U) && ((itsources & RCC_CRS_IT_SYNCOK) != 0U))
1777 {
1778 /* Clear CRS SYNC event OK flag */
1779 LL_CRS_ClearFlag_SYNCOK();
1780
1781 /* user callback */
1782 HAL_RCCEx_CRS_SyncOkCallback();
1783 }
1784 /* Check CRS SYNCWARN flag */
1785 else if (((itflags & RCC_CRS_FLAG_SYNCWARN) != 0U) && ((itsources & RCC_CRS_IT_SYNCWARN) != 0U))
1786 {
1787 /* Clear CRS SYNCWARN flag */
1788 LL_CRS_ClearFlag_SYNCWARN();
1789
1790 /* user callback */
1791 HAL_RCCEx_CRS_SyncWarnCallback();
1792 }
1793 /* Check CRS Expected SYNC flag */
1794 else if (((itflags & RCC_CRS_FLAG_ESYNC) != 0U) && ((itsources & RCC_CRS_IT_ESYNC) != 0U))
1795 {
1796 /* frequency error counter reached a zero value */
1797 LL_CRS_ClearFlag_ESYNC();
1798
1799 /* user callback */
1800 HAL_RCCEx_CRS_ExpectedSyncCallback();
1801 }
1802 /* Check CRS Error flags */
1803 else
1804 {
1805 if (((itflags & RCC_CRS_FLAG_ERR) != 0U) && ((itsources & RCC_CRS_IT_ERR) != 0U))
1806 {
1807 if ((itflags & RCC_CRS_FLAG_SYNCERR) != 0U)
1808 {
1809 crserror |= RCC_CRS_SYNCERR;
1810 }
1811 if ((itflags & RCC_CRS_FLAG_SYNCMISS) != 0U)
1812 {
1813 crserror |= RCC_CRS_SYNCMISS;
1814 }
1815 if ((itflags & RCC_CRS_FLAG_TRIMOVF) != 0U)
1816 {
1817 crserror |= RCC_CRS_TRIMOVF;
1818 }
1819
1820 /* Clear CRS Error flags */
1821 LL_CRS_ClearFlag_ERR();
1822
1823 /* user error callback */
1824 HAL_RCCEx_CRS_ErrorCallback(crserror);
1825 }
1826 }
1827 }
1828
1829 /**
1830 * @brief RCCEx Clock Recovery System SYNCOK interrupt callback.
1831 * @retval none
1832 */
HAL_RCCEx_CRS_SyncOkCallback(void)1833 __weak void HAL_RCCEx_CRS_SyncOkCallback(void)
1834 {
1835 /* NOTE : This function should not be modified, when the callback is needed,
1836 the @ref HAL_RCCEx_CRS_SyncOkCallback should be implemented in the user file
1837 */
1838 }
1839
1840 /**
1841 * @brief RCCEx Clock Recovery System SYNCWARN interrupt callback.
1842 * @retval none
1843 */
HAL_RCCEx_CRS_SyncWarnCallback(void)1844 __weak void HAL_RCCEx_CRS_SyncWarnCallback(void)
1845 {
1846 /* NOTE : This function should not be modified, when the callback is needed,
1847 the HAL_RCCEx_CRS_SyncWarnCallback should be implemented in the user file
1848 */
1849 }
1850
1851 /**
1852 * @brief RCCEx Clock Recovery System Expected SYNC interrupt callback.
1853 * @retval none
1854 */
HAL_RCCEx_CRS_ExpectedSyncCallback(void)1855 __weak void HAL_RCCEx_CRS_ExpectedSyncCallback(void)
1856 {
1857 /* NOTE : This function should not be modified, when the callback is needed,
1858 the HAL_RCCEx_CRS_ExpectedSyncCallback should be implemented in the user file
1859 */
1860 }
1861
1862 /**
1863 * @brief RCCEx Clock Recovery System Error interrupt callback.
1864 * @param Error Combination of Error status.
1865 * This parameter can be a combination of the following values:
1866 * @arg @ref RCC_CRS_SYNCERR
1867 * @arg @ref RCC_CRS_SYNCMISS
1868 * @arg @ref RCC_CRS_TRIMOVF
1869 * @retval none
1870 */
HAL_RCCEx_CRS_ErrorCallback(uint32_t Error)1871 __weak void HAL_RCCEx_CRS_ErrorCallback(uint32_t Error)
1872 {
1873 /* Prevent unused argument(s) compilation warning */
1874 UNUSED(Error);
1875
1876 /* NOTE : This function should not be modified, when the callback is needed,
1877 the @ref HAL_RCCEx_CRS_ErrorCallback should be implemented in the user file
1878 */
1879 }
1880
1881 /**
1882 * @}
1883 */
1884 #endif /* CRS */
1885
1886 /**
1887 * @}
1888 */
1889
1890 /** @addtogroup RCCEx_Private_Functions
1891 * @{
1892 */
1893
1894 #if defined(SAI1)
1895 /**
1896 * @brief Configure the parameters N & P of PLLSAI1 and enable PLLSAI1 output clock(s).
1897 * @param PLLSAI1 pointer to an RCC_PLLSAI1InitTypeDef structure that
1898 * contains the configuration parameters N & P as well as PLLSAI1 output clock(s)
1899 *
1900 * @note PLLSAI1 is temporary disable to apply new parameters
1901 *
1902 * @retval HAL status
1903 */
RCCEx_PLLSAI1_ConfigNP(RCC_PLLSAI1InitTypeDef * PLLSAI1)1904 static HAL_StatusTypeDef RCCEx_PLLSAI1_ConfigNP(RCC_PLLSAI1InitTypeDef *PLLSAI1)
1905 {
1906 uint32_t tickstart;
1907 HAL_StatusTypeDef status = HAL_OK;
1908
1909 /* check for PLLSAI1 Parameters used to output PLLSAI1CLK */
1910 assert_param(IS_RCC_PLLN_VALUE(PLLSAI1->PLLN));
1911 assert_param(IS_RCC_PLLP_VALUE(PLLSAI1->PLLP));
1912 assert_param(IS_RCC_PLLSAI1CLOCKOUT_VALUE(PLLSAI1->PLLSAI1ClockOut));
1913
1914 /* Disable the PLLSAI1 */
1915 __HAL_RCC_PLLSAI1_DISABLE();
1916
1917 /* Get Start Tick*/
1918 tickstart = HAL_GetTick();
1919
1920 /* Wait till PLLSAI1 is ready to be updated */
1921 while (LL_RCC_PLLSAI1_IsReady() != 0U)
1922 {
1923 if ((HAL_GetTick() - tickstart) > PLLSAI1_TIMEOUT_VALUE)
1924 {
1925 status = HAL_TIMEOUT;
1926 break;
1927 }
1928 }
1929
1930 if (status == HAL_OK)
1931 {
1932 /* Configure the PLLSAI1 Multiplication factor N */
1933 __HAL_RCC_PLLSAI1_MULN_CONFIG(PLLSAI1->PLLN);
1934
1935 /* Configure the PLLSAI1 Division factor P */
1936 __HAL_RCC_PLLSAI1_DIVP_CONFIG(PLLSAI1->PLLP);
1937
1938 /* Enable the PLLSAI1 again by setting PLLSAI1ON to 1*/
1939 __HAL_RCC_PLLSAI1_ENABLE();
1940
1941 /* Get Start Tick*/
1942 tickstart = HAL_GetTick();
1943
1944 /* Wait till PLLSAI1 is ready */
1945 while (LL_RCC_PLLSAI1_IsReady() != 1U)
1946 {
1947 if ((HAL_GetTick() - tickstart) > PLLSAI1_TIMEOUT_VALUE)
1948 {
1949 status = HAL_TIMEOUT;
1950 break;
1951 }
1952 }
1953
1954 if (status == HAL_OK)
1955 {
1956 /* Configure the PLLSAI1 Clock output(s) */
1957 __HAL_RCC_PLLSAI1CLKOUT_ENABLE(PLLSAI1->PLLSAI1ClockOut);
1958 }
1959 }
1960
1961 return status;
1962 }
1963
1964 /**
1965 * @brief Configure the parameters N & Q of PLLSAI1 and enable PLLSAI1 output clock(s).
1966 * @param PLLSAI1 pointer to an RCC_PLLSAI1InitTypeDef structure that
1967 * contains the configuration parameters N & Q as well as PLLSAI1 output clock(s)
1968 *
1969 * @note PLLSAI1 is temporary disable to apply new parameters
1970 *
1971 * @retval HAL status
1972 */
RCCEx_PLLSAI1_ConfigNQ(RCC_PLLSAI1InitTypeDef * PLLSAI1)1973 static HAL_StatusTypeDef RCCEx_PLLSAI1_ConfigNQ(RCC_PLLSAI1InitTypeDef *PLLSAI1)
1974 {
1975 uint32_t tickstart;
1976 HAL_StatusTypeDef status = HAL_OK;
1977
1978 /* check for PLLSAI1 Parameters used to output PLLSAI1CLK */
1979 assert_param(IS_RCC_PLLN_VALUE(PLLSAI1->PLLN));
1980 assert_param(IS_RCC_PLLQ_VALUE(PLLSAI1->PLLQ));
1981 assert_param(IS_RCC_PLLSAI1CLOCKOUT_VALUE(PLLSAI1->PLLSAI1ClockOut));
1982
1983 /* Disable the PLLSAI1 */
1984 __HAL_RCC_PLLSAI1_DISABLE();
1985
1986 /* Get Start Tick*/
1987 tickstart = HAL_GetTick();
1988
1989 /* Wait till PLLSAI1 is ready to be updated */
1990 while (LL_RCC_PLLSAI1_IsReady() != 0U)
1991 {
1992 if ((HAL_GetTick() - tickstart) > PLLSAI1_TIMEOUT_VALUE)
1993 {
1994 status = HAL_TIMEOUT;
1995 break;
1996 }
1997 }
1998
1999 if (status == HAL_OK)
2000 {
2001 /* Configure the PLLSAI1 Multiplication factor N */
2002 __HAL_RCC_PLLSAI1_MULN_CONFIG(PLLSAI1->PLLN);
2003 /* Configure the PLLSAI1 Division factor Q */
2004 __HAL_RCC_PLLSAI1_DIVQ_CONFIG(PLLSAI1->PLLQ);
2005
2006 /* Enable the PLLSAI1 again by setting PLLSAI1ON to 1*/
2007 __HAL_RCC_PLLSAI1_ENABLE();
2008
2009 /* Get Start Tick*/
2010 tickstart = HAL_GetTick();
2011
2012 /* Wait till PLLSAI1 is ready */
2013 while (LL_RCC_PLLSAI1_IsReady() != 1U)
2014 {
2015 if ((HAL_GetTick() - tickstart) > PLLSAI1_TIMEOUT_VALUE)
2016 {
2017 status = HAL_TIMEOUT;
2018 break;
2019 }
2020 }
2021
2022 if (status == HAL_OK)
2023 {
2024 /* Configure the PLLSAI1 Clock output(s) */
2025 __HAL_RCC_PLLSAI1CLKOUT_ENABLE(PLLSAI1->PLLSAI1ClockOut);
2026 }
2027 }
2028
2029 return status;
2030 }
2031
2032 /**
2033 * @brief Configure the parameters N & R of PLLSAI1 and enable PLLSAI1 output clock(s).
2034 * @param PLLSAI1 pointer to an RCC_PLLSAI1InitTypeDef structure that
2035 * contains the configuration parameters N & R as well as PLLSAI1 output clock(s)
2036 *
2037 * @note PLLSAI1 is temporary disable to apply new parameters
2038 *
2039 * @retval HAL status
2040 */
RCCEx_PLLSAI1_ConfigNR(RCC_PLLSAI1InitTypeDef * PLLSAI1)2041 static HAL_StatusTypeDef RCCEx_PLLSAI1_ConfigNR(RCC_PLLSAI1InitTypeDef *PLLSAI1)
2042 {
2043 uint32_t tickstart;
2044 HAL_StatusTypeDef status = HAL_OK;
2045
2046 /* check for PLLSAI1 Parameters used to output PLLSAI1CLK */
2047 assert_param(IS_RCC_PLLN_VALUE(PLLSAI1->PLLN));
2048 assert_param(IS_RCC_PLLR_VALUE(PLLSAI1->PLLR));
2049 assert_param(IS_RCC_PLLSAI1CLOCKOUT_VALUE(PLLSAI1->PLLSAI1ClockOut));
2050
2051 /* Disable the PLLSAI1 */
2052 __HAL_RCC_PLLSAI1_DISABLE();
2053
2054 /* Get Start Tick*/
2055 tickstart = HAL_GetTick();
2056
2057 /* Wait till PLLSAI1 is ready to be updated */
2058 while (LL_RCC_PLLSAI1_IsReady() != 0U)
2059 {
2060 if ((HAL_GetTick() - tickstart) > PLLSAI1_TIMEOUT_VALUE)
2061 {
2062 status = HAL_TIMEOUT;
2063 break;
2064 }
2065 }
2066
2067 if (status == HAL_OK)
2068 {
2069 /* Configure the PLLSAI1 Multiplication factor N */
2070 __HAL_RCC_PLLSAI1_MULN_CONFIG(PLLSAI1->PLLN);
2071 /* Configure the PLLSAI1 Division factor R */
2072 __HAL_RCC_PLLSAI1_DIVR_CONFIG(PLLSAI1->PLLR);
2073
2074 /* Enable the PLLSAI1 again by setting PLLSAI1ON to 1*/
2075 __HAL_RCC_PLLSAI1_ENABLE();
2076
2077 /* Get Start Tick*/
2078 tickstart = HAL_GetTick();
2079
2080 /* Wait till PLLSAI1 is ready */
2081 while (LL_RCC_PLLSAI1_IsReady() != 1U)
2082 {
2083 if ((HAL_GetTick() - tickstart) > PLLSAI1_TIMEOUT_VALUE)
2084 {
2085 status = HAL_TIMEOUT;
2086 break;
2087 }
2088 }
2089
2090 if (status == HAL_OK)
2091 {
2092 /* Configure the PLLSAI1 Clock output(s) */
2093 __HAL_RCC_PLLSAI1CLKOUT_ENABLE(PLLSAI1->PLLSAI1ClockOut);
2094 }
2095 }
2096
2097 return status;
2098 }
2099 #endif /* SAI1 */
2100
2101 /**
2102 * @brief Return PLL clock (PLLPCLK) frequency used for SAI domain
2103 * @retval PLLPCLK clock frequency (in Hz)
2104 */
RCC_PLL_GetFreqDomain_P(void)2105 static uint32_t RCC_PLL_GetFreqDomain_P(void)
2106 {
2107 uint32_t pllinputfreq;
2108 uint32_t pllsource;
2109
2110 /* PLL_VCO = (HSE_VALUE or HSI_VALUE or MSI Value / PLLM) * PLLN
2111 SAI Domain clock = PLL_VCO / PLLP
2112 */
2113 pllsource = LL_RCC_PLL_GetMainSource();
2114
2115 switch (pllsource)
2116 {
2117 case LL_RCC_PLLSOURCE_MSI: /* MSI used as PLL clock source */
2118 pllinputfreq = __LL_RCC_CALC_MSI_FREQ(LL_RCC_MSI_GetRange());
2119 break;
2120
2121 case LL_RCC_PLLSOURCE_HSI: /* HSI used as PLL clock source */
2122 pllinputfreq = HSI_VALUE;
2123 break;
2124
2125 case LL_RCC_PLLSOURCE_HSE: /* HSE used as PLL clock source */
2126 if (LL_RCC_HSE_IsEnabledDiv2() == 1U)
2127 {
2128 pllinputfreq = HSE_VALUE / 2U;
2129 }
2130 else
2131 {
2132 pllinputfreq = HSE_VALUE;
2133 }
2134 break;
2135
2136 default:
2137 pllinputfreq = __LL_RCC_CALC_MSI_FREQ(LL_RCC_MSI_GetRange());
2138 break;
2139 }
2140 return __LL_RCC_CALC_PLLCLK_ADC_FREQ(pllinputfreq, LL_RCC_PLL_GetDivider(),
2141 LL_RCC_PLL_GetN(), LL_RCC_PLL_GetP());
2142 }
2143
2144 /**
2145 * @brief Return PLL clock (PLLQCLK) frequency used for 48 MHz domain
2146 * @retval PLLQCLK clock frequency (in Hz)
2147 */
RCC_PLL_GetFreqDomain_Q(void)2148 static uint32_t RCC_PLL_GetFreqDomain_Q(void)
2149 {
2150 uint32_t pllinputfreq;
2151 uint32_t pllsource;
2152
2153 /* PLL_VCO = (HSE_VALUE or HSI_VALUE or MSI Value/ PLLM) * PLLN
2154 48M Domain clock = PLL_VCO / PLLQ
2155 */
2156 pllsource = LL_RCC_PLL_GetMainSource();
2157
2158 switch (pllsource)
2159 {
2160 case LL_RCC_PLLSOURCE_MSI: /* MSI used as PLL clock source */
2161 pllinputfreq = __LL_RCC_CALC_MSI_FREQ(LL_RCC_MSI_GetRange());
2162 break;
2163
2164 case LL_RCC_PLLSOURCE_HSI: /* HSI used as PLL clock source */
2165 pllinputfreq = HSI_VALUE;
2166 break;
2167
2168 case LL_RCC_PLLSOURCE_HSE: /* HSE used as PLL clock source */
2169 if (LL_RCC_HSE_IsEnabledDiv2() == 1U)
2170 {
2171 pllinputfreq = HSE_VALUE / 2U;
2172 }
2173 else
2174 {
2175 pllinputfreq = HSE_VALUE;
2176 }
2177
2178 break;
2179
2180 default:
2181 pllinputfreq = __LL_RCC_CALC_MSI_FREQ(LL_RCC_MSI_GetRange());
2182 break;
2183 }
2184 return __LL_RCC_CALC_PLLCLK_48M_FREQ(pllinputfreq, LL_RCC_PLL_GetDivider(),
2185 LL_RCC_PLL_GetN(), LL_RCC_PLL_GetQ());
2186 }
2187
2188 #if defined(SAI1)
2189 /**
2190 * @brief Return PLLSAI1 clock (PLLSAI1RCLK) frequency used for ADC domain
2191 * @retval PLLSAI1RCLK clock frequency (in Hz)
2192 */
RCC_PLLSAI1_GetFreqDomain_R(void)2193 static uint32_t RCC_PLLSAI1_GetFreqDomain_R(void)
2194 {
2195 uint32_t pllinputfreq;
2196 uint32_t pllsource;
2197
2198 /* PLLSAI1_VCO = (HSE_VALUE or HSI_VALUE or MSI Value/ PLLM) * PLLSAI1N */
2199 /* 48M Domain clock = PLLSAI1_VCO / PLLSAI1R */
2200 pllsource = LL_RCC_PLL_GetMainSource();
2201
2202 switch (pllsource)
2203 {
2204 case LL_RCC_PLLSOURCE_MSI: /* MSI used as PLLSAI1 clock source */
2205 pllinputfreq = __LL_RCC_CALC_MSI_FREQ(LL_RCC_MSI_GetRange());
2206 break;
2207
2208 case LL_RCC_PLLSOURCE_HSI: /* HSI used as PLLSAI1 clock source */
2209 pllinputfreq = HSI_VALUE;
2210 break;
2211
2212 case LL_RCC_PLLSOURCE_HSE: /* HSE used as PLLSAI1 clock source */
2213 if (LL_RCC_HSE_IsEnabledDiv2() == 1U)
2214 {
2215 pllinputfreq = HSE_VALUE / 2U;
2216 }
2217 else
2218 {
2219 pllinputfreq = HSE_VALUE;
2220 }
2221 break;
2222
2223 default:
2224 pllinputfreq = __LL_RCC_CALC_MSI_FREQ(LL_RCC_MSI_GetRange());
2225 break;
2226 }
2227 return __LL_RCC_CALC_PLLSAI1_ADC_FREQ(pllinputfreq, LL_RCC_PLL_GetDivider(),
2228 LL_RCC_PLLSAI1_GetN(), LL_RCC_PLLSAI1_GetR());
2229 }
2230
2231 /**
2232 * @brief Return PLLSAI1 clock (PLLSAI1PCLK) frequency used for SAI domain
2233 * @retval PLLSAI1PCLK clock frequency (in Hz)
2234 */
RCC_PLLSAI1_GetFreqDomain_P(void)2235 static uint32_t RCC_PLLSAI1_GetFreqDomain_P(void)
2236 {
2237 uint32_t pllinputfreq;
2238 uint32_t pllsource;
2239
2240 /* PLLSAI1_VCO = (HSE_VALUE or HSI_VALUE or MSI Value/ PLLM) * PLLSAI1N */
2241 /* SAI Domain clock = PLLSAI1_VCO / PLLSAI1P */
2242 pllsource = LL_RCC_PLL_GetMainSource();
2243
2244 switch (pllsource)
2245 {
2246 case LL_RCC_PLLSOURCE_MSI: /* MSI used as PLLSAI1 clock source */
2247 pllinputfreq = __LL_RCC_CALC_MSI_FREQ(LL_RCC_MSI_GetRange());
2248 break;
2249
2250 case LL_RCC_PLLSOURCE_HSI: /* HSI used as PLLSAI1 clock source */
2251 pllinputfreq = HSI_VALUE;
2252 break;
2253
2254 case LL_RCC_PLLSOURCE_HSE: /* HSE used as PLLSAI1 clock source */
2255 if (LL_RCC_HSE_IsEnabledDiv2() == 1U)
2256 {
2257 pllinputfreq = HSE_VALUE / 2U;
2258 }
2259 else
2260 {
2261 pllinputfreq = HSE_VALUE;
2262 }
2263 break;
2264
2265 default:
2266 pllinputfreq = __LL_RCC_CALC_MSI_FREQ(LL_RCC_MSI_GetRange());
2267 break;
2268 }
2269 return __LL_RCC_CALC_PLLSAI1_SAI_FREQ(pllinputfreq, LL_RCC_PLL_GetDivider(),
2270 LL_RCC_PLLSAI1_GetN(), LL_RCC_PLLSAI1_GetP());
2271 }
2272
2273 /**
2274 * @brief Return PLLSAI1 clock (PLLSAI1QCLK) frequency used for 48Mhz domain
2275 * @retval PLLSAI1QCLK clock frequency (in Hz)
2276 */
RCC_PLLSAI1_GetFreqDomain_Q(void)2277 static uint32_t RCC_PLLSAI1_GetFreqDomain_Q(void)
2278 {
2279 uint32_t pllinputfreq;
2280 uint32_t pllsource;
2281
2282 /* PLLSAI1_VCO = (HSE_VALUE or HSI_VALUE or MSI Value/ PLLM) * PLLSAI1N */
2283 /* 48M Domain clock = PLLSAI1_VCO / PLLSAI1Q */
2284 pllsource = LL_RCC_PLL_GetMainSource();
2285
2286 switch (pllsource)
2287 {
2288 case LL_RCC_PLLSOURCE_MSI: /* MSI used as PLLSAI1 clock source */
2289 pllinputfreq = __LL_RCC_CALC_MSI_FREQ(LL_RCC_MSI_GetRange());
2290 break;
2291
2292 case LL_RCC_PLLSOURCE_HSI: /* HSI used as PLLSAI1 clock source */
2293 pllinputfreq = HSI_VALUE;
2294 break;
2295
2296 case LL_RCC_PLLSOURCE_HSE: /* HSE used as PLLSAI1 clock source */
2297 if (LL_RCC_HSE_IsEnabledDiv2() == 1U)
2298 {
2299 pllinputfreq = HSE_VALUE / 2U;
2300 }
2301 else
2302 {
2303 pllinputfreq = HSE_VALUE;
2304 }
2305 break;
2306
2307 default:
2308 pllinputfreq = __LL_RCC_CALC_MSI_FREQ(LL_RCC_MSI_GetRange());
2309 break;
2310 }
2311 return __LL_RCC_CALC_PLLSAI1_48M_FREQ(pllinputfreq, LL_RCC_PLL_GetDivider(),
2312 LL_RCC_PLLSAI1_GetN(), LL_RCC_PLLSAI1_GetQ());
2313 }
2314 #endif /* SAI1 */
2315
2316 /**
2317 * @}
2318 */
2319
2320 #endif /* HAL_RCC_MODULE_ENABLED */
2321
2322 /**
2323 * @}
2324 */
2325
2326 /**
2327 * @}
2328 */
2329