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