1 /**
2 ******************************************************************************
3 * @file stm32h7rsxx_hal_rcc.c
4 * @author MCD Application Team
5 * @brief RCC HAL module driver.
6 * This file provides firmware functions to manage the following
7 * functionalities of the Reset and Clock Control (RCC) peripheral:
8 * + Initialization and de-initialization functions
9 * + Peripheral Control functions
10 *
11 ******************************************************************************
12 * @attention
13 *
14 * Copyright (c) 2022 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 @verbatim
23 ==============================================================================
24 ##### RCC specific features #####
25 ==============================================================================
26 [..]
27 After reset the device is running from Internal High Speed oscillator
28 (HSI 64MHz) with Flash 0 wait state,and all peripherals are off except
29 internal SRAM, Flash, JTAG and PWR
30 (+) There is no pre-scaler on High speed (AHB) and Low speed (APB) buses;
31 all peripherals mapped on these buses are running at HSI speed.
32 (+) The clock for all peripherals is switched off, except the SRAM and FLASH.
33 (+) All GPIOs are in analogue mode , except the JTAG pins which
34 are assigned to be used for debug purpose.
35
36 [..]
37 Once the device started from reset, the user application has to:
38 (+) Configure the clock source to be used to drive the System clock
39 (if the application needs higher frequency/performance)
40 (+) Configure the System clock frequency and Flash settings
41 (+) Configure the AHB and APB buses pre-scalers
42 (+) Enable the clock for the peripheral(s) to be used
43 (+) Configure the clock kernel source(s) for peripherals which clocks are not
44 derived from the System clock through :RCC_D1CCIPR,RCC_D2CCIP1R,RCC_D2CCIP2R
45 and RCC_D3CCIPR registers
46
47 ##### RCC Limitations #####
48 ==============================================================================
49 [..]
50 A delay between an RCC peripheral clock enable and the effective peripheral
51 enabling should be taken into account in order to manage the peripheral read/write
52 from/to registers.
53 (+) This delay depends on the peripheral mapping.
54 (+) If peripheral is mapped on AHB: the delay is 2 AHB clock cycle
55 after the clock enable bit is set on the hardware register
56 (+) If peripheral is mapped on APB: the delay is 2 APB clock cycle
57 after the clock enable bit is set on the hardware register
58
59 [..]
60 Implemented Workaround:
61 (+) For AHB & APB peripherals, a dummy read to the peripheral register has been
62 inserted in each __HAL_RCC_PPP_CLK_ENABLE() macro.
63
64 @endverbatim
65 */
66
67 /* Includes ------------------------------------------------------------------*/
68 #include "stm32h7rsxx_hal.h"
69
70 /** @addtogroup STM32H7RSxx_HAL_Driver
71 * @{
72 */
73
74 /** @defgroup RCC RCC
75 * @brief RCC HAL module driver
76 * @{
77 */
78
79 #ifdef HAL_RCC_MODULE_ENABLED
80
81 /* Private typedef -----------------------------------------------------------*/
82 /* Private defines -----------------------------------------------------------*/
83 /** @defgroup RCC_Private_Constants RCC Private Constants
84 * @{
85 */
86 #define RCC_CSI_TIMEOUT_VALUE 1U /* 1 ms */
87 #define RCC_HSI_TIMEOUT_VALUE 1U /* 1 ms */
88 #define RCC_HSI48_TIMEOUT_VALUE 1U /* 1 ms */
89 #define RCC_HSE_TIMEOUT_VALUE HSE_STARTUP_TIMEOUT
90 #define RCC_LSI_TIMEOUT_VALUE 1U /* 1 ms */
91 #define RCC_CLOCKSWITCH_TIMEOUT_VALUE 5000U /* 5 s */
92 #define RCC_PLL_FRAC_WAIT_VALUE 1U /* PLL Fractional part waiting time before new latch enable : 1 ms */
93 #define RCC_PLL_INPUTRANGE0_FREQMAX 2000000U /* 2 MHz is maximum frequency for VCO input range 0 */
94 #define RCC_PLL_INPUTRANGE1_FREQMAX 4000000U /* 4 MHz is maximum frequency for VCO input range 1 */
95 #define RCC_PLL_INPUTRANGE2_FREQMAX 8000000U /* 8 MHz is maximum frequency for VCO input range 2 */
96
97 #define RCC_PLL1_CONFIG 0U
98 #define RCC_PLL2_CONFIG 1U
99 #define RCC_PLL3_CONFIG 2U
100 /**
101 * @}
102 */
103
104 /* Private macros ------------------------------------------------------------*/
105 /** @defgroup RCC_Private_Macros RCC Private Macros
106 * @{
107 */
108 #define RCC_GET_MCO_GPIO_PIN(__RCC_MCOx__) ((__RCC_MCOx__) & GPIO_PIN_MASK)
109
110 #define RCC_GET_MCO_GPIO_AF(__RCC_MCOx__) (((__RCC_MCOx__) & RCC_MCO_GPIOAF_MASK) >> RCC_MCO_GPIOAF_POS)
111
112 #define RCC_GET_MCO_GPIO_INDEX(__RCC_MCOx__) (((__RCC_MCOx__) & RCC_MCO_GPIOPORT_MASK) >> RCC_MCO_GPIOPORT_POS)
113
114 #define RCC_GET_MCO_GPIO_PORT(__RCC_MCOx__) (GPIOA_BASE + ((0x00000400UL) * RCC_GET_MCO_GPIO_INDEX((__RCC_MCOx__))))
115
116 /**
117 * @}
118 */
119
120 /* Private variables ---------------------------------------------------------*/
121 /** @defgroup RCC_Private_Variables Private Variables
122 * @{
123 */
124 /**
125 * @}
126 */
127
128 /* Private function prototypes -----------------------------------------------*/
129 /** @defgroup RCC_Private_Functions RCC Private Functions
130 * @{
131 */
132 static uint32_t RCC_PLL1_GetVCOOutputFreq(void);
133 static uint32_t RCC_PLL2_GetVCOOutputFreq(void);
134 static uint32_t RCC_PLL3_GetVCOOutputFreq(void);
135 static HAL_StatusTypeDef RCC_PLL_Config(uint32_t PLLnumber, const RCC_PLLInitTypeDef *pPLLInit);
136 /**
137 * @}
138 */
139
140 /* Exported functions --------------------------------------------------------*/
141
142 /** @defgroup RCC_Exported_Functions RCC Exported Functions
143 * @{
144 */
145
146 /** @defgroup RCC_Exported_Functions_Group1 Initialization and de-initialization functions
147 * @brief Initialization and Configuration functions
148 *
149 @verbatim
150 ===============================================================================
151 ##### Initialization and de-initialization functions #####
152 ===============================================================================
153 [..]
154 This section provides functions allowing to configure the internal/external oscillators
155 (HSE, HSI, LSE,CSI, LSI,HSI48, PLL, CSS and MCO) and the System buses clocks (SYSCLK, AHB3, AHB1
156 AHB2,AHB4,APB3, APB1L, APB1H, APB2, and APB4).
157
158 [..] Internal/external clock and PLL configuration
159 (#) HSI (high-speed internal), 64 MHz factory-trimmed RC used directly or through
160 the PLL as System clock source.
161 (#) CSI is a low-power RC oscillator which can be used directly as system clock, peripheral
162 clock, or PLL input.But even with frequency calibration, is less accurate than an
163 external crystal oscillator or ceramic resonator.
164 (#) LSI (low-speed internal), 32 KHz low consumption RC used as IWDG and/or RTC
165 clock source.
166
167 (#) HSE (high-speed external), 4 to 48 MHz crystal oscillator used directly or
168 through the PLL as System clock source. Can be used also as RTC clock source.
169
170 (#) LSE (low-speed external), 32 KHz oscillator used as RTC clock source.
171
172 (#) PLL , The RCC features three independent PLLs (clocked by HSI , HSE or CSI),
173 featuring three different output clocks and able to work either in integer or Fractional mode.
174 (++) A main PLL, PLL1, which is generally used to provide clocks to the CPU
175 and to some peripherals.
176 (++) Two dedicated PLLs, PLL2 and PLL3, which are used to generate the kernel clock for peripherals.
177
178
179 (#) CSS (Clock security system), once enabled and if a HSE clock failure occurs
180 (HSE used directly or through PLL as System clock source), the System clock
181 is automatically switched to HSI and an interrupt is generated if enabled.
182 The interrupt is linked to the Cortex-M NMI (Non-Mask-able Interrupt)
183 exception vector.
184
185 (#) MCO1 (micro controller clock output), used to output HSI, LSE, HSE, PLL1(PLL1_Q)
186 or HSI48 clock (through a configurable pre-scaler) on PA8 pin.
187
188 (#) MCO2 (micro controller clock output), used to output HSE, PLL2(PLL2_P), SYSCLK,
189 LSI, CSI, or PLL1(PLL1_P) clock (through a configurable pre-scaler) on PC9 pin.
190
191 [..] System, AHB and APB buses clocks configuration
192 (#) Several clock sources can be used to drive the System clock (SYSCLK): CSI,HSI,
193 HSE and PLL.
194 The AHB clock (HCLK) is derived from System core clock through configurable
195 pre-scaler and used to clock the CPU, memory and peripherals mapped
196 on AHB and APB bus of the 3 Domains (D1, D2, D3)* through configurable pre-scalers
197 and used to clock the peripherals mapped on these buses. You can use
198 "HAL_RCC_GetSysClockFreq()" function to retrieve system clock frequency.
199
200 -@- All the peripheral clocks are derived from the System clock (SYSCLK) except those
201 with dual clock domain where kernel source clock could be selected through
202 RCC_D1CCIPR,RCC_D2CCIP1R,RCC_D2CCIP2R and RCC_D3CCIPR registers.
203
204 (*) : 2 Domains (CD and SRD) for stm32h7a3xx and stm32h7b3xx family lines.
205 @endverbatim
206 * @{
207 */
208
209 /**
210 * @brief Resets the RCC clock configuration to the default reset state.
211 * @note The default reset state of the clock configuration is given below:
212 * - HSI ON and used as system clock source
213 * - HSE, PLL1, PLL2 and PLL3 OFF
214 * - AHB, APB Bus pre-scaler set to 1.
215 * - CSS, MCO1 and MCO2 OFF
216 * - All interrupts disabled
217 * @note This function doesn't modify the configuration of the
218 * - Peripheral clocks
219 * - LSI, LSE and RTC clocks
220 * @note In case the FMC or XSPI clock protection have been set, it must be disabled
221 * prior to calling this API.
222 * @retval HAL status
223 */
HAL_RCC_DeInit(void)224 HAL_StatusTypeDef HAL_RCC_DeInit(void)
225 {
226 uint32_t tickstart;
227
228 /* Get Start Tick */
229 tickstart = HAL_GetTick();
230
231 /* Set HSION bit */
232 SET_BIT(RCC->CR, RCC_CR_HSION);
233
234 /* Wait till HSI is ready */
235 while (READ_BIT(RCC->CR, RCC_CR_HSIRDY) == 0U)
236 {
237 if ((HAL_GetTick() - tickstart) > RCC_HSI_TIMEOUT_VALUE)
238 {
239 return HAL_TIMEOUT;
240 }
241 }
242
243 /* Set HSITRIM[6:0] bits to the reset value */
244 SET_BIT(RCC->HSICFGR, RCC_HSICFGR_HSITRIM_6);
245
246 if (HAL_RCC_GetHCLKFreq() > HSI_VALUE)
247 {
248 /* Reset CFGR register (HSI is selected as system clock source) */
249 CLEAR_REG(RCC->CFGR);
250
251 /* Update the SystemCoreClock and SystemD2Clock global variables */
252 SystemCoreClock = HSI_VALUE;
253
254 /* Adapt Systick interrupt period */
255 if (HAL_InitTick(uwTickPrio) != HAL_OK)
256 {
257 return HAL_ERROR;
258 }
259
260 /* Get Start Tick */
261 tickstart = HAL_GetTick();
262
263 /* Wait till clock switch is ready */
264 while (READ_BIT(RCC->CFGR, RCC_CFGR_SWS) != 0U)
265 {
266 if ((HAL_GetTick() - tickstart) > RCC_CLOCKSWITCH_TIMEOUT_VALUE)
267 {
268 return HAL_TIMEOUT;
269 }
270 }
271
272 /* Reduce flash latency */
273 __HAL_FLASH_SET_LATENCY(FLASH_LATENCY_1);
274 }
275 else
276 {
277 /* Increase flash latency */
278 __HAL_FLASH_SET_LATENCY(FLASH_LATENCY_1);
279
280 /* Reset CFGR register (HSI is selected as system clock source) */
281 CLEAR_REG(RCC->CFGR);
282
283 /* Adapt Systick interrupt period */
284 if (HAL_InitTick(uwTickPrio) != HAL_OK)
285 {
286 return HAL_ERROR;
287 }
288
289 /* Get Start Tick */
290 tickstart = HAL_GetTick();
291
292 /* Wait till clock switch is ready */
293 while (READ_BIT(RCC->CFGR, RCC_CFGR_SWS) != 0U)
294 {
295 if ((HAL_GetTick() - tickstart) > RCC_CLOCKSWITCH_TIMEOUT_VALUE)
296 {
297 return HAL_TIMEOUT;
298 }
299 }
300 }
301
302
303 /* Get Start Tick */
304 tickstart = HAL_GetTick();
305
306 /* Reset CSION, CSIKERON, HSEON, HSI48ON, HSECSSON, HSIDIV bits */
307 CLEAR_BIT(RCC->CR, RCC_CR_HSEON | RCC_CR_HSIKERON | RCC_CR_HSIDIV | RCC_CR_CSION | RCC_CR_CSIKERON \
308 | RCC_CR_HSI48ON | RCC_CR_HSECSSON);
309
310 /* Wait till HSE is disabled */
311 while (READ_BIT(RCC->CR, RCC_CR_HSERDY) != 0U)
312 {
313 if ((HAL_GetTick() - tickstart) > RCC_HSE_TIMEOUT_VALUE)
314 {
315 return HAL_TIMEOUT;
316 }
317 }
318
319 /* Get Start Tick */
320 tickstart = HAL_GetTick();
321
322 /* Clear PLLON bit */
323 CLEAR_BIT(RCC->CR, RCC_CR_PLL1ON);
324
325 /* Wait till PLL is disabled */
326 while (READ_BIT(RCC->CR, RCC_CR_PLL1RDY) != 0U)
327 {
328 if ((HAL_GetTick() - tickstart) > RCC_PLL_TIMEOUT_VALUE)
329 {
330 return HAL_TIMEOUT;
331 }
332 }
333
334 /* Get Start Tick */
335 tickstart = HAL_GetTick();
336
337 /* Reset PLL2ON bit */
338 CLEAR_BIT(RCC->CR, RCC_CR_PLL2ON);
339
340 /* Wait till PLL2 is disabled */
341 while (READ_BIT(RCC->CR, RCC_CR_PLL2RDY) != 0U)
342 {
343 if ((HAL_GetTick() - tickstart) > RCC_PLL_TIMEOUT_VALUE)
344 {
345 return HAL_TIMEOUT;
346 }
347 }
348
349 /* Get Start Tick */
350 tickstart = HAL_GetTick();
351
352 /* Reset PLL3 bit */
353 CLEAR_BIT(RCC->CR, RCC_CR_PLL3ON);
354
355 /* Wait till PLL3 is disabled */
356 while (READ_BIT(RCC->CR, RCC_CR_PLL3RDY) != 0U)
357 {
358 if ((HAL_GetTick() - tickstart) > RCC_PLL_TIMEOUT_VALUE)
359 {
360 return HAL_TIMEOUT;
361 }
362 }
363
364 /* Reset CDCFGR register */
365 CLEAR_REG(RCC->CDCFGR);
366
367 /* Reset BMCFGR register */
368 CLEAR_REG(RCC->BMCFGR);
369
370 /* Reset APBCFGR register */
371 CLEAR_REG(RCC->APBCFGR);
372
373 /* Reset PLLCKSELR register to default value */
374 WRITE_REG(RCC->PLLCKSELR, 0x02020200U);
375
376 /* Reset PLLCFGR register */
377 CLEAR_REG(RCC->PLLCFGR);
378
379 /* Reset PLL1DIVR1 register to default value */
380 WRITE_REG(RCC->PLL1DIVR1, 0x01010280U);
381
382 /* Reset PLL1DIVR2 register to default value */
383 WRITE_REG(RCC->PLL1DIVR2, 0x00000101U);
384
385 /* Reset PLL1FRACR register */
386 CLEAR_REG(RCC->PLL1FRACR);
387
388 /* Reset PLL2DIVR1 register to default value */
389 WRITE_REG(RCC->PLL2DIVR1, 0x01010280U);
390
391 /* Reset PLL2DIVR2 register to default value */
392 WRITE_REG(RCC->PLL2DIVR2, 0x00000101U);
393
394 /* Reset PLL2FRACR register */
395 CLEAR_REG(RCC->PLL2FRACR);
396
397 /* Reset PLL3DIVR1 register to default value */
398 WRITE_REG(RCC->PLL3DIVR1, 0x01010280U);
399
400 /* Reset PLL3DIVR2 register to default value */
401 WRITE_REG(RCC->PLL3DIVR2, 0x00000101U);
402
403 /* Reset PLL3FRACR register */
404 CLEAR_REG(RCC->PLL3FRACR);
405
406 /* Reset HSEBYP bit */
407 CLEAR_BIT(RCC->CR, RCC_CR_HSEBYP);
408
409 /* Disable all interrupts */
410 CLEAR_REG(RCC->CIER);
411
412 /* Clear all interrupts flags */
413 WRITE_REG(RCC->CICR, 0xFFFFFFFFU);
414
415 /* Reset all RSR flags */
416 SET_BIT(RCC->RSR, RCC_RSR_RMVF);
417
418 return HAL_OK;
419 }
420
421 /**
422 * @brief Initializes the RCC Oscillators according to the specified parameters in the
423 * RCC_OscInitTypeDef.
424 * @param RCC_OscInitStruct: pointer to an RCC_OscInitTypeDef structure that
425 * contains the configuration information for the RCC Oscillators.
426 * @note The PLL is not disabled when used as system clock.
427 * @note Transitions LSE Bypass to LSE On and LSE On to LSE Bypass are not
428 * supported by this function. User should request a transition to LSE Off
429 * first and then LSE On or LSE Bypass.
430 * @note Transition HSE Bypass to HSE On and HSE On to HSE Bypass are not
431 * supported by this function. User should request a transition to HSE Off
432 * first and then HSE On or HSE Bypass.
433 * @retval HAL status
434 */
HAL_RCC_OscConfig(RCC_OscInitTypeDef * RCC_OscInitStruct)435 HAL_StatusTypeDef HAL_RCC_OscConfig(RCC_OscInitTypeDef *RCC_OscInitStruct)
436 {
437 uint32_t tickstart;
438 uint32_t sysclksrc;
439 uint32_t pllsrc;
440 uint32_t pllrdy;
441 uint32_t tmpreg1;
442
443 /* Check Null pointer */
444 if (RCC_OscInitStruct == NULL)
445 {
446 return HAL_ERROR;
447 }
448
449 /* Check the parameters */
450 assert_param(IS_RCC_OSCILLATORTYPE(RCC_OscInitStruct->OscillatorType));
451
452 sysclksrc = __HAL_RCC_GET_SYSCLK_SOURCE();
453 pllsrc = __HAL_RCC_GET_PLL_OSCSOURCE();
454 pllrdy = RCC->CR & (RCC_CR_PLL1RDY | RCC_CR_PLL2RDY | RCC_CR_PLL3RDY);
455
456 /*------------------------------- HSE Configuration ------------------------*/
457 if (((RCC_OscInitStruct->OscillatorType) & RCC_OSCILLATORTYPE_HSE) == RCC_OSCILLATORTYPE_HSE)
458 {
459 /* Check the parameters */
460 assert_param(IS_RCC_HSE(RCC_OscInitStruct->HSEState));
461
462 /* When the HSE is used as system clock or clock source for PLL in these cases HSE will not disabled */
463 if ((sysclksrc == RCC_SYSCLKSOURCE_STATUS_HSE) ||
464 ((pllrdy != 0U) && (pllsrc == RCC_PLLSOURCE_HSE)))
465 {
466 if (RCC_OscInitStruct->HSEState == RCC_HSE_OFF)
467 {
468 return HAL_ERROR;
469 }
470 }
471 else
472 {
473 /* Set the new HSE configuration ---------------------------------------*/
474 __HAL_RCC_HSE_CONFIG(RCC_OscInitStruct->HSEState);
475
476 /* Get Start Tick*/
477 tickstart = HAL_GetTick();
478
479 /* Check the HSE State */
480 if (RCC_OscInitStruct->HSEState != RCC_HSE_OFF)
481 {
482 /* Wait till HSE is ready */
483 while (READ_BIT(RCC->CR, RCC_CR_HSERDY) == 0U)
484 {
485 if ((HAL_GetTick() - tickstart) > RCC_HSE_TIMEOUT_VALUE)
486 {
487 return HAL_TIMEOUT;
488 }
489 }
490 }
491 else
492 {
493 /* Wait till HSE is disabled */
494 while (READ_BIT(RCC->CR, RCC_CR_HSERDY) != 0U)
495 {
496 if ((HAL_GetTick() - tickstart) > RCC_HSE_TIMEOUT_VALUE)
497 {
498 return HAL_TIMEOUT;
499 }
500 }
501 }
502 }
503 }
504 /*----------------------------- HSI Configuration --------------------------*/
505 if (((RCC_OscInitStruct->OscillatorType) & RCC_OSCILLATORTYPE_HSI) == RCC_OSCILLATORTYPE_HSI)
506 {
507 /* Check the parameters */
508 assert_param(IS_RCC_HSI(RCC_OscInitStruct->HSIState));
509 assert_param(IS_RCC_HSICALIBRATION_VALUE(RCC_OscInitStruct->HSICalibrationValue));
510
511 /* Check if HSI is used as system clock or as PLL1 source when PLL1 is selected as system clock */
512 if ((sysclksrc == RCC_SYSCLKSOURCE_STATUS_HSI) ||
513 ((pllrdy != 0U) && (pllsrc == RCC_PLLSOURCE_HSI)))
514 {
515 /* When HSI is used as system clock it will not be disabled */
516 if (RCC_OscInitStruct->HSIState == RCC_HSI_OFF)
517 {
518 return HAL_ERROR;
519 }
520 /* Otherwise, calibration is allowed, divider update also unless used for any enabled PLL */
521 else
522 {
523 /* HSI must not be used as reference clock for any enabled PLL clock source */
524 tmpreg1 = (RCC->CR & RCC_CR_HSIDIV);
525 if ((pllsrc == RCC_PLLSOURCE_HSI) && (pllrdy != 0U) && \
526 (tmpreg1 != RCC_OscInitStruct->HSIDiv))
527 {
528 return HAL_ERROR;
529 }
530
531 assert_param(IS_RCC_HSIDIV(RCC_OscInitStruct->HSIDiv));
532
533 /* Set the Internal High Speed oscillator new divider */
534 __HAL_RCC_HSI_CONFIG(RCC_HSI_ON | RCC_OscInitStruct->HSIDiv);
535
536 if (sysclksrc == RCC_SYSCLKSOURCE_STATUS_HSI)
537 {
538 SystemCoreClock = (HSI_VALUE / (1UL << ((READ_BIT(RCC->CR, RCC_CR_HSIDIV)) >> RCC_CR_HSIDIV_Pos)));
539 }
540 /* Adapt Systick interrupt period */
541 if (HAL_InitTick(uwTickPrio) != HAL_OK)
542 {
543 return HAL_ERROR;
544 }
545 }
546 /* Adjusts the Internal High Speed oscillator (HSI) calibration value.*/
547 __HAL_RCC_HSI_CALIBRATIONVALUE_ADJUST(RCC_OscInitStruct->HSICalibrationValue);
548 }
549 else
550 {
551 /* Check the HSI State */
552 if (RCC_OscInitStruct->HSIState != RCC_HSI_OFF)
553 {
554 /* Enable the Internal High Speed oscillator */
555 __HAL_RCC_HSI_CONFIG(RCC_OscInitStruct->HSIState | RCC_OscInitStruct->HSIDiv);
556
557 /* Adjusts the Internal High Speed oscillator (HSI) calibration value.*/
558 __HAL_RCC_HSI_CALIBRATIONVALUE_ADJUST(RCC_OscInitStruct->HSICalibrationValue);
559
560 /* Get Start Tick*/
561 tickstart = HAL_GetTick();
562
563 /* Wait till HSI is ready */
564 while (READ_BIT(RCC->CR, RCC_CR_HSIRDY) == 0U)
565 {
566 if ((HAL_GetTick() - tickstart) > RCC_HSI_TIMEOUT_VALUE)
567 {
568 return HAL_TIMEOUT;
569 }
570 }
571 }
572 else
573 {
574 /* Disable the Internal High Speed oscillator (HSI). */
575 __HAL_RCC_HSI_DISABLE();
576
577 /* Get Start Tick*/
578 tickstart = HAL_GetTick();
579
580 /* Wait till HSI is disabled */
581 while (READ_BIT(RCC->CR, RCC_CR_HSIRDY) != 0U)
582 {
583 if ((HAL_GetTick() - tickstart) > RCC_HSI_TIMEOUT_VALUE)
584 {
585 return HAL_TIMEOUT;
586 }
587 }
588 }
589 }
590 }
591 /*----------------------------- CSI Configuration --------------------------*/
592 if (((RCC_OscInitStruct->OscillatorType) & RCC_OSCILLATORTYPE_CSI) == RCC_OSCILLATORTYPE_CSI)
593 {
594 /* Check the parameters */
595 assert_param(IS_RCC_CSI(RCC_OscInitStruct->CSIState));
596
597 /* When the CSI is used as system clock it will not disabled */
598 if ((sysclksrc == RCC_SYSCLKSOURCE_STATUS_CSI) ||
599 ((pllrdy != 0U) && (pllsrc == RCC_PLLSOURCE_CSI)))
600 {
601 /* When CSI is used as system clock it will not disabled */
602 if (RCC_OscInitStruct->CSIState == RCC_CSI_OFF)
603 {
604 return HAL_ERROR;
605 }
606 }
607 else
608 {
609 /* Check the CSI State */
610 if ((RCC_OscInitStruct->CSIState) != RCC_CSI_OFF)
611 {
612 /* Enable the Internal High Speed oscillator (CSI). */
613 __HAL_RCC_CSI_ENABLE();
614
615 /* Get Start Tick*/
616 tickstart = HAL_GetTick();
617
618 /* Wait till CSI is ready */
619 while (READ_BIT(RCC->CR, RCC_CR_CSIRDY) == 0U)
620 {
621 if ((HAL_GetTick() - tickstart) > RCC_CSI_TIMEOUT_VALUE)
622 {
623 return HAL_TIMEOUT;
624 }
625 }
626 }
627 else
628 {
629 /* Disable the Internal High Speed oscillator (CSI). */
630 __HAL_RCC_CSI_DISABLE();
631
632 /* Get Start Tick*/
633 tickstart = HAL_GetTick();
634
635 /* Wait till CSI is disabled */
636 while (READ_BIT(RCC->CR, RCC_CR_CSIRDY) != 0U)
637 {
638 if ((HAL_GetTick() - tickstart) > RCC_CSI_TIMEOUT_VALUE)
639 {
640 return HAL_TIMEOUT;
641 }
642 }
643 }
644 }
645 }
646 /*------------------------------ LSI Configuration -------------------------*/
647 if (((RCC_OscInitStruct->OscillatorType) & RCC_OSCILLATORTYPE_LSI) == RCC_OSCILLATORTYPE_LSI)
648 {
649 /* Check the parameters */
650 assert_param(IS_RCC_LSI(RCC_OscInitStruct->LSIState));
651
652 /* Check the LSI State */
653 if ((RCC_OscInitStruct->LSIState) != RCC_LSI_OFF)
654 {
655 /* Enable the Internal Low Speed oscillator (LSI). */
656 __HAL_RCC_LSI_ENABLE();
657
658 /* Get Start Tick*/
659 tickstart = HAL_GetTick();
660
661 /* Wait till LSI is ready */
662 while (READ_BIT(RCC->CSR, RCC_CSR_LSIRDY) == 0U)
663 {
664 if ((HAL_GetTick() - tickstart) > RCC_LSI_TIMEOUT_VALUE)
665 {
666 return HAL_TIMEOUT;
667 }
668 }
669 }
670 else
671 {
672 /* Disable the Internal Low Speed oscillator (LSI). */
673 __HAL_RCC_LSI_DISABLE();
674
675 /* Get Start Tick*/
676 tickstart = HAL_GetTick();
677
678 /* Wait till LSI is ready */
679 while (READ_BIT(RCC->CSR, RCC_CSR_LSIRDY) != 0U)
680 {
681 if ((HAL_GetTick() - tickstart) > RCC_LSI_TIMEOUT_VALUE)
682 {
683 return HAL_TIMEOUT;
684 }
685 }
686 }
687 }
688
689 /*------------------------------ HSI48 Configuration -------------------------*/
690 if (((RCC_OscInitStruct->OscillatorType) & RCC_OSCILLATORTYPE_HSI48) == RCC_OSCILLATORTYPE_HSI48)
691 {
692 /* Check the parameters */
693 assert_param(IS_RCC_HSI48(RCC_OscInitStruct->HSI48State));
694
695 /* Check the HSI48 State */
696 if ((RCC_OscInitStruct->HSI48State) != RCC_HSI48_OFF)
697 {
698 /* Enable the Internal Low Speed oscillator (HSI48). */
699 __HAL_RCC_HSI48_ENABLE();
700
701 /* Get time-out */
702 tickstart = HAL_GetTick();
703
704 /* Wait till HSI48 is ready */
705 while (READ_BIT(RCC->CR, RCC_CR_HSI48RDY) == 0U)
706 {
707 if ((HAL_GetTick() - tickstart) > RCC_HSI48_TIMEOUT_VALUE)
708 {
709 return HAL_TIMEOUT;
710 }
711 }
712 }
713 else
714 {
715 /* Disable the Internal Low Speed oscillator (HSI48). */
716 __HAL_RCC_HSI48_DISABLE();
717
718 /* Get time-out */
719 tickstart = HAL_GetTick();
720
721 /* Wait till HSI48 is ready */
722 while (READ_BIT(RCC->CR, RCC_CR_HSI48RDY) != 0U)
723 {
724 if ((HAL_GetTick() - tickstart) > RCC_HSI48_TIMEOUT_VALUE)
725 {
726 return HAL_TIMEOUT;
727 }
728 }
729 }
730 }
731 /*------------------------------ LSE Configuration -------------------------*/
732 if (((RCC_OscInitStruct->OscillatorType) & RCC_OSCILLATORTYPE_LSE) == RCC_OSCILLATORTYPE_LSE)
733 {
734 /* Check the parameters */
735 assert_param(IS_RCC_LSE(RCC_OscInitStruct->LSEState));
736
737 /* Enable write access to Backup domain */
738 PWR->CR1 |= PWR_CR1_DBP;
739
740 /* Set the new LSE configuration -----------------------------------------*/
741 __HAL_RCC_LSE_CONFIG(RCC_OscInitStruct->LSEState);
742 /* Check the LSE State */
743 if ((RCC_OscInitStruct->LSEState) != RCC_LSE_OFF)
744 {
745 /* Get Start Tick*/
746 tickstart = HAL_GetTick();
747
748 /* Wait till LSE is ready */
749 while (READ_BIT(RCC->BDCR, RCC_BDCR_LSERDY) == 0U)
750 {
751 if ((HAL_GetTick() - tickstart) > RCC_LSE_TIMEOUT_VALUE)
752 {
753 return HAL_TIMEOUT;
754 }
755 }
756 }
757 else
758 {
759 /* Get Start Tick*/
760 tickstart = HAL_GetTick();
761
762 /* Wait till LSE is disabled */
763 while (READ_BIT(RCC->BDCR, RCC_BDCR_LSERDY) != 0U)
764 {
765 if ((HAL_GetTick() - tickstart) > RCC_LSE_TIMEOUT_VALUE)
766 {
767 return HAL_TIMEOUT;
768 }
769 }
770 }
771 }
772
773 /*-------------------------------- PLL1 Configuration ----------------------*/
774 /* Check the parameters */
775 assert_param(IS_RCC_PLL(RCC_OscInitStruct->PLL1.PLLState));
776
777 if (RCC_OscInitStruct->PLL1.PLLState != RCC_PLL_NONE)
778 {
779 /* Check if the PLL is used as system clock or not */
780 if (sysclksrc == RCC_SYSCLKSOURCE_STATUS_PLLCLK)
781 {
782 /* No PLL off possible */
783 if (RCC_OscInitStruct->PLL1.PLLState == RCC_PLL_OFF)
784 {
785 return HAL_ERROR;
786 }
787 else
788 {
789 /* Check if only fractional part needs to be updated */
790 tmpreg1 = ((RCC->PLL1FRACR & RCC_PLL1FRACR_FRACN) >> RCC_PLL1FRACR_FRACN_Pos);
791
792 if (RCC_OscInitStruct->PLL1.PLLFractional != tmpreg1)
793 {
794 assert_param(IS_RCC_PLLFRACN_VALUE(RCC_OscInitStruct->PLL1.PLLFractional));
795
796 /* Disable PLL1FRACLE */
797 __HAL_RCC_PLL1_FRACN_DISABLE();
798
799 /* Get Start Tick*/
800 tickstart = HAL_GetTick();
801
802 /* Wait at least 2 CK_REF (PLL input source divided by M) period to make sure next latched value will be taken into account. */
803 while ((HAL_GetTick() - tickstart) < RCC_PLL_FRAC_WAIT_VALUE)
804 {
805 /* Do nothing */
806 }
807
808 /* Configure PLL1FRACN */
809 __HAL_RCC_PLL1_FRACN_CONFIG(RCC_OscInitStruct->PLL1.PLLFractional);
810
811 /* Enable PLL1FRACLE to latch new value . */
812 __HAL_RCC_PLL1_FRACN_ENABLE();
813 }
814 }
815 }
816 else
817 {
818 /* Initialize PLL1T to 1 to use common PLL initialization function */
819 RCC_OscInitStruct->PLL1.PLLT = 1U;
820 if (RCC_PLL_Config(RCC_PLL1_CONFIG, &(RCC_OscInitStruct->PLL1)) != HAL_OK)
821 {
822 return HAL_ERROR;
823 }
824 }
825 }
826
827 /*-------------------------------- PLL2 Configuration ----------------------*/
828 /* Check the parameters */
829 assert_param(IS_RCC_PLL(RCC_OscInitStruct->PLL2.PLLState));
830
831 if (RCC_OscInitStruct->PLL2.PLLState != RCC_PLL_NONE)
832 {
833 if (RCC_PLL_Config(RCC_PLL2_CONFIG, &(RCC_OscInitStruct->PLL2)) != HAL_OK)
834 {
835 return HAL_ERROR;
836 }
837 }
838
839 /*-------------------------------- PLL3 Configuration ----------------------*/
840 /* Check the parameters */
841 assert_param(IS_RCC_PLL(RCC_OscInitStruct->PLL3.PLLState));
842
843 if (RCC_OscInitStruct->PLL3.PLLState != RCC_PLL_NONE)
844 {
845 /* Initialize PLL3T to 1 to use common PLL initialization function */
846 RCC_OscInitStruct->PLL3.PLLT = 1U;
847 if (RCC_PLL_Config(RCC_PLL3_CONFIG, &(RCC_OscInitStruct->PLL3)) != HAL_OK)
848 {
849 return HAL_ERROR;
850 }
851 }
852
853 return HAL_OK;
854 }
855
856 /**
857 * @brief Initializes the CPU, AHB and APB buses clocks according to the specified
858 * parameters in the RCC_ClkInitStruct.
859 * @param RCC_ClkInitStruct: pointer to an RCC_OscInitTypeDef structure that
860 * contains the configuration information for the RCC peripheral.
861 * @param FLatency: FLASH Latency, this parameter depend on device selected
862 *
863 * @note The SystemCoreClock CMSIS variable is used to store System Core Clock Frequency
864 * and updated by HAL_InitTick() function called within this function
865 *
866 * @note The HSI is used (enabled by hardware) as system clock source after
867 * start-up from Reset, wake-up from STOP and STANDBY mode, or in case
868 * of failure of the HSE used directly or indirectly as system clock
869 * (if the Clock Security System CSS is enabled).
870 *
871 * @note A switch from one clock source to another occurs only if the target
872 * clock source is ready (clock stable after start-up delay or PLL locked).
873 * If a clock source which is not yet ready is selected, the switch will
874 * occur when the clock source will be ready.
875 * You can use HAL_RCC_GetClockConfig() function to know which clock is
876 * currently used as system clock source.
877 * @note Depending on the device voltage range, the software has to set correctly
878 * D1CPRE[3:0] bits to ensure that Domain1 core clock not exceed the maximum allowed frequency
879 * (for more details refer to section above "Initialization/de-initialization functions")
880 * @retval None
881 */
HAL_RCC_ClockConfig(const RCC_ClkInitTypeDef * RCC_ClkInitStruct,uint32_t FLatency)882 HAL_StatusTypeDef HAL_RCC_ClockConfig(const RCC_ClkInitTypeDef *RCC_ClkInitStruct, uint32_t FLatency)
883 {
884 HAL_StatusTypeDef halstatus;
885 uint32_t tickstart;
886
887 /* Check Null pointer */
888 if (RCC_ClkInitStruct == NULL)
889 {
890 return HAL_ERROR;
891 }
892
893 /* Check the parameters */
894 assert_param(IS_RCC_CLOCKTYPE(RCC_ClkInitStruct->ClockType));
895 assert_param(IS_FLASH_LATENCY(FLatency));
896
897 /* To correctly read data from FLASH memory, the number of wait states (LATENCY)
898 must be correctly programmed according to the frequency of the CPU clock
899 (HCLK) and the supply voltage of the device. */
900
901 /* Increasing the CPU frequency */
902 if (FLatency > __HAL_FLASH_GET_LATENCY())
903 {
904 /* Program the new number of wait states to the LATENCY bits in the FLASH_ACR register */
905 __HAL_FLASH_SET_LATENCY(FLatency);
906
907 /* Check that the new number of wait states is taken into account to access the Flash
908 memory by reading the FLASH_ACR register */
909 if (__HAL_FLASH_GET_LATENCY() != FLatency)
910 {
911 return HAL_ERROR;
912 }
913
914 }
915
916 /* Increasing the BUS frequency divider ? */
917
918 /*-------------------------- PCLK1 Configuration ---------------------------*/
919 if (((RCC_ClkInitStruct->ClockType) & RCC_CLOCKTYPE_PCLK1) == RCC_CLOCKTYPE_PCLK1)
920 {
921 assert_param(IS_RCC_PCLK1(RCC_ClkInitStruct->APB1CLKDivider));
922 if ((RCC_ClkInitStruct->APB1CLKDivider) > (RCC->APBCFGR & RCC_APBCFGR_PPRE1))
923 {
924 MODIFY_REG(RCC->APBCFGR, RCC_APBCFGR_PPRE1, (RCC_ClkInitStruct->APB1CLKDivider));
925 }
926 }
927
928 /*-------------------------- PCLK2 Configuration ---------------------------*/
929 if (((RCC_ClkInitStruct->ClockType) & RCC_CLOCKTYPE_PCLK2) == RCC_CLOCKTYPE_PCLK2)
930 {
931 assert_param(IS_RCC_PCLK2(RCC_ClkInitStruct->APB2CLKDivider));
932 if ((RCC_ClkInitStruct->APB2CLKDivider) > (RCC->APBCFGR & RCC_APBCFGR_PPRE2))
933 {
934 MODIFY_REG(RCC->APBCFGR, RCC_APBCFGR_PPRE2, (RCC_ClkInitStruct->APB2CLKDivider));
935 }
936 }
937
938 /*-------------------------- PCLK4 Configuration ---------------------------*/
939 if (((RCC_ClkInitStruct->ClockType) & RCC_CLOCKTYPE_PCLK4) == RCC_CLOCKTYPE_PCLK4)
940 {
941 assert_param(IS_RCC_PCLK4(RCC_ClkInitStruct->APB4CLKDivider));
942 if ((RCC_ClkInitStruct->APB4CLKDivider) > (RCC->APBCFGR & RCC_APBCFGR_PPRE4))
943 {
944 MODIFY_REG(RCC->APBCFGR, RCC_APBCFGR_PPRE4, (RCC_ClkInitStruct->APB4CLKDivider));
945 }
946 }
947
948 /*-------------------------- PCLK5 Configuration ---------------------------*/
949 if (((RCC_ClkInitStruct->ClockType) & RCC_CLOCKTYPE_PCLK5) == RCC_CLOCKTYPE_PCLK5)
950 {
951 assert_param(IS_RCC_PCLK5(RCC_ClkInitStruct->APB5CLKDivider));
952 if ((RCC_ClkInitStruct->APB5CLKDivider) > (RCC->APBCFGR & RCC_APBCFGR_PPRE5))
953 {
954 MODIFY_REG(RCC->APBCFGR, RCC_APBCFGR_PPRE5, (RCC_ClkInitStruct->APB5CLKDivider));
955 }
956 }
957
958 /*-------------------------- HCLK Configuration --------------------------*/
959 if (((RCC_ClkInitStruct->ClockType) & RCC_CLOCKTYPE_HCLK) == RCC_CLOCKTYPE_HCLK)
960 {
961 assert_param(IS_RCC_HCLK(RCC_ClkInitStruct->AHBCLKDivider));
962 if ((RCC_ClkInitStruct->AHBCLKDivider) > (RCC->BMCFGR & RCC_BMCFGR_BMPRE))
963 {
964 /* Set the new HCLK clock divider */
965 MODIFY_REG(RCC->BMCFGR, RCC_BMCFGR_BMPRE, RCC_ClkInitStruct->AHBCLKDivider);
966 }
967 }
968
969 /*------------------------- SYSCLK Configuration -------------------------*/
970 if ((RCC_ClkInitStruct->ClockType & RCC_CLOCKTYPE_SYSCLK) == RCC_CLOCKTYPE_SYSCLK)
971 {
972 assert_param(IS_RCC_SYSCLKSOURCE(RCC_ClkInitStruct->SYSCLKSource));
973 assert_param(IS_RCC_SYSCLK(RCC_ClkInitStruct->SYSCLKDivider));
974 MODIFY_REG(RCC->CDCFGR, RCC_CDCFGR_CPRE, RCC_ClkInitStruct->SYSCLKDivider);
975
976 /* HSE is selected as System Clock Source */
977 if (RCC_ClkInitStruct->SYSCLKSource == RCC_SYSCLKSOURCE_HSE)
978 {
979 /* Check the HSE ready flag */
980 if (READ_BIT(RCC->CR, RCC_CR_HSERDY) == 0U)
981 {
982 return HAL_ERROR;
983 }
984 }
985 /* PLL is selected as System Clock Source */
986 else if (RCC_ClkInitStruct->SYSCLKSource == RCC_SYSCLKSOURCE_PLLCLK)
987 {
988 /* Check the PLL ready flag */
989 if (READ_BIT(RCC->CR, RCC_CR_PLL1RDY) == 0U)
990 {
991 return HAL_ERROR;
992 }
993 }
994 /* CSI is selected as System Clock Source */
995 else if (RCC_ClkInitStruct->SYSCLKSource == RCC_SYSCLKSOURCE_CSI)
996 {
997 /* Check the PLL ready flag */
998 if (READ_BIT(RCC->CR, RCC_CR_CSIRDY) == 0U)
999 {
1000 return HAL_ERROR;
1001 }
1002 }
1003 /* HSI is selected as System Clock Source */
1004 else
1005 {
1006 /* Check the HSI ready flag */
1007 if (READ_BIT(RCC->CR, RCC_CR_HSIRDY) == 0U)
1008 {
1009 return HAL_ERROR;
1010 }
1011 }
1012 MODIFY_REG(RCC->CFGR, RCC_CFGR_SW, RCC_ClkInitStruct->SYSCLKSource);
1013
1014 /* Get Start Tick*/
1015 tickstart = HAL_GetTick();
1016
1017 while (__HAL_RCC_GET_SYSCLK_SOURCE() != (RCC_ClkInitStruct->SYSCLKSource << RCC_CFGR_SWS_Pos))
1018 {
1019 if ((HAL_GetTick() - tickstart) > RCC_CLOCKSWITCH_TIMEOUT_VALUE)
1020 {
1021 return HAL_TIMEOUT;
1022 }
1023 }
1024 }
1025
1026 /* Decreasing the BUS frequency divider ? */
1027
1028 /*-------------------------- HCLK Configuration --------------------------*/
1029 if (((RCC_ClkInitStruct->ClockType) & RCC_CLOCKTYPE_HCLK) == RCC_CLOCKTYPE_HCLK)
1030 {
1031 assert_param(IS_RCC_HCLK(RCC_ClkInitStruct->AHBCLKDivider));
1032 if ((RCC_ClkInitStruct->AHBCLKDivider) < (RCC->BMCFGR & RCC_BMCFGR_BMPRE))
1033 {
1034 /* Set the new HCLK clock divider */
1035 MODIFY_REG(RCC->BMCFGR, RCC_BMCFGR_BMPRE, RCC_ClkInitStruct->AHBCLKDivider);
1036 }
1037 }
1038
1039 /* Decreasing the number of wait states because of lower CPU frequency */
1040 if (FLatency < __HAL_FLASH_GET_LATENCY())
1041 {
1042 /* Program the new number of wait states to the LATENCY bits in the FLASH_ACR register */
1043 __HAL_FLASH_SET_LATENCY(FLatency);
1044
1045 /* Check that the new number of wait states is taken into account to access the Flash
1046 memory by reading the FLASH_ACR register */
1047 if (__HAL_FLASH_GET_LATENCY() != FLatency)
1048 {
1049 return HAL_ERROR;
1050 }
1051 }
1052
1053 /*-------------------------- PCLK1 Configuration ---------------------------*/
1054 if (((RCC_ClkInitStruct->ClockType) & RCC_CLOCKTYPE_PCLK1) == RCC_CLOCKTYPE_PCLK1)
1055 {
1056 assert_param(IS_RCC_PCLK1(RCC_ClkInitStruct->APB1CLKDivider));
1057 if ((RCC_ClkInitStruct->APB1CLKDivider) < (RCC->APBCFGR & RCC_APBCFGR_PPRE1))
1058 {
1059 MODIFY_REG(RCC->APBCFGR, RCC_APBCFGR_PPRE1, (RCC_ClkInitStruct->APB1CLKDivider));
1060 }
1061 }
1062
1063 /*-------------------------- PCLK2 Configuration ---------------------------*/
1064 if (((RCC_ClkInitStruct->ClockType) & RCC_CLOCKTYPE_PCLK2) == RCC_CLOCKTYPE_PCLK2)
1065 {
1066 assert_param(IS_RCC_PCLK2(RCC_ClkInitStruct->APB2CLKDivider));
1067 if ((RCC_ClkInitStruct->APB2CLKDivider) < (RCC->APBCFGR & RCC_APBCFGR_PPRE2))
1068 {
1069 MODIFY_REG(RCC->APBCFGR, RCC_APBCFGR_PPRE2, (RCC_ClkInitStruct->APB2CLKDivider));
1070 }
1071 }
1072
1073 /*-------------------------- PCLK4 Configuration ---------------------------*/
1074 if (((RCC_ClkInitStruct->ClockType) & RCC_CLOCKTYPE_PCLK4) == RCC_CLOCKTYPE_PCLK4)
1075 {
1076 assert_param(IS_RCC_PCLK4(RCC_ClkInitStruct->APB4CLKDivider));
1077 if ((RCC_ClkInitStruct->APB4CLKDivider) < (RCC->APBCFGR & RCC_APBCFGR_PPRE4))
1078 {
1079 MODIFY_REG(RCC->APBCFGR, RCC_APBCFGR_PPRE4, (RCC_ClkInitStruct->APB4CLKDivider));
1080 }
1081 }
1082
1083 /*-------------------------- PCLK5 Configuration ---------------------------*/
1084 if (((RCC_ClkInitStruct->ClockType) & RCC_CLOCKTYPE_PCLK5) == RCC_CLOCKTYPE_PCLK5)
1085 {
1086 assert_param(IS_RCC_PCLK5(RCC_ClkInitStruct->APB5CLKDivider));
1087 if ((RCC_ClkInitStruct->APB5CLKDivider) < (RCC->APBCFGR & RCC_APBCFGR_PPRE5))
1088 {
1089 MODIFY_REG(RCC->APBCFGR, RCC_APBCFGR_PPRE5, (RCC_ClkInitStruct->APB5CLKDivider));
1090 }
1091 }
1092
1093 /* Update the SystemCoreClock global variable with the System CPU clock */
1094 SystemCoreClock = HAL_RCC_GetSysClockFreq();
1095
1096 /* Configure the source of time base considering new system clocks settings*/
1097 halstatus = HAL_InitTick(uwTickPrio);
1098
1099 return halstatus;
1100 }
1101
1102 /**
1103 * @}
1104 */
1105
1106 /** @defgroup RCC_Group2 Peripheral Control functions
1107 * @brief RCC clocks control functions
1108 *
1109 @verbatim
1110 ===============================================================================
1111 ##### Peripheral Control functions #####
1112 ===============================================================================
1113 [..]
1114 This subsection provides a set of functions allowing to control the RCC Clocks
1115 frequencies.
1116
1117 @endverbatim
1118 * @{
1119 */
1120
1121 /**
1122 * @brief Selects the clock source to output on MCO1 pin(PA8) or on MCO2 pin(PC9).
1123 * @note PA8/PC9 should be configured in alternate function mode.
1124 * @param RCC_MCOx specifies the output direction for the clock source.
1125 * This parameter can be one of the following values:
1126 * @arg RCC_MCO1_PA8 Clock source to output on MCO1 pin(PA8).
1127 * @arg RCC_MCO2_PC9 Clock source to output on MCO2 pin(PC9).
1128 * @param RCC_MCOSource specifies the clock source to output.
1129 * This parameter can be one of the following values:
1130 * @arg RCC_MCO1SOURCE_HSI HSI clock selected as MCO1 source
1131 * @arg RCC_MCO1SOURCE_LSE LSE clock selected as MCO1 source
1132 * @arg RCC_MCO1SOURCE_HSE HSE clock selected as MCO1 source
1133 * @arg RCC_MCO1SOURCE_PLL1Q: PLL1Q clock selected as MCO1 source
1134 * @arg RCC_MCO1SOURCE_HSI48 HSI48 (48MHZ) selected as MCO1 source
1135 * @arg RCC_MCO2SOURCE_SYSCLK System clock (SYSCLK) selected as MCO2 source
1136 * @arg RCC_MCO2SOURCE_PLL2PCLK PLL2P clock selected as MCO2 source
1137 * @arg RCC_MCO2SOURCE_HSE HSE clock selected as MCO2 source
1138 * @arg RCC_MCO2SOURCE_PLL1P PLL1P clock selected as MCO2 source
1139 * @arg RCC_MCO2SOURCE_CSI CSI clock selected as MCO2 source
1140 * @arg RCC_MCO2SOURCE_LSI LSI clock selected as MCO2 source
1141 * @param RCC_MCODiv: specifies the MCOx pre-scaler.
1142 * This parameter can be one of the following values:
1143 * @arg RCC_MCODIV_1 up to RCC_MCODIV_15 : divider applied to MCOx clock
1144 * @retval None
1145 */
HAL_RCC_MCOConfig(uint32_t RCC_MCOx,uint32_t RCC_MCOSource,uint32_t RCC_MCODiv)1146 void HAL_RCC_MCOConfig(uint32_t RCC_MCOx, uint32_t RCC_MCOSource, uint32_t RCC_MCODiv)
1147 {
1148 #if defined(HAL_GPIO_MODULE_ENABLED)
1149 GPIO_InitTypeDef GPIO_InitStruct;
1150 uint32_t mcoindex;
1151 uint32_t mco_gpio_index;
1152 GPIO_TypeDef *mco_gpio_port;
1153
1154 /* Check the parameters */
1155 assert_param(IS_RCC_MCO(RCC_MCOx));
1156
1157 /* Common GPIO init parameters */
1158 GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
1159 GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
1160 GPIO_InitStruct.Pull = GPIO_NOPULL;
1161
1162 /* Get MCOx selection */
1163 mcoindex = RCC_MCOx & RCC_MCO_INDEX_MASK;
1164
1165 /* Get MCOx GPIO Port */
1166 mco_gpio_port = (GPIO_TypeDef *) RCC_GET_MCO_GPIO_PORT(RCC_MCOx);
1167
1168 /* MCOx Clock Enable */
1169 mco_gpio_index = RCC_GET_MCO_GPIO_INDEX(RCC_MCOx);
1170 SET_BIT(RCC->AHB4ENR, (1UL << mco_gpio_index));
1171
1172 /* Configure the MCOx pin in alternate function mode */
1173 GPIO_InitStruct.Pin = RCC_GET_MCO_GPIO_PIN(RCC_MCOx);
1174 GPIO_InitStruct.Alternate = RCC_GET_MCO_GPIO_AF(RCC_MCOx);
1175 HAL_GPIO_Init(mco_gpio_port, &GPIO_InitStruct);
1176
1177 if (mcoindex == RCC_MCO1_INDEX)
1178 {
1179 assert_param(IS_RCC_MCODIV(RCC_MCODiv));
1180 assert_param(IS_RCC_MCO1SOURCE(RCC_MCOSource));
1181 /* Mask MCOSEL[] and MCOPRE[] bits then set MCO clock source and prescaler */
1182 MODIFY_REG(RCC->CFGR, (RCC_CFGR_MCO1SEL | RCC_CFGR_MCO1PRE), (RCC_MCOSource | RCC_MCODiv));
1183 }
1184 else if (mcoindex == RCC_MCO2_INDEX)
1185 {
1186 assert_param(IS_RCC_MCODIV(RCC_MCODiv));
1187 assert_param(IS_RCC_MCO2SOURCE(RCC_MCOSource));
1188 /* Mask MCOSEL[] and MCOPRE[] bits then set MCO clock source and prescaler */
1189 MODIFY_REG(RCC->CFGR, (RCC_CFGR_MCO2SEL | RCC_CFGR_MCO2PRE), (RCC_MCOSource | (RCC_MCODiv << 7)));
1190 }
1191 else
1192 {
1193 /* Do nothing */
1194 }
1195
1196 #endif /* HAL_GPIO_MODULE_ENABLED */
1197 }
1198
1199 /**
1200 * @brief Enables the Clock Security System.
1201 * @note If a failure is detected on the HSE oscillator clock, this oscillator
1202 * is automatically disabled and an interrupt is generated to inform the
1203 * software about the failure (Clock Security System Interrupt, CSSI),
1204 * allowing the MCU to perform rescue operations. The CSSI is linked to
1205 * the Cortex-M NMI (Non-Mask-able Interrupt) exception vector.
1206 * @retval None
1207 */
HAL_RCC_EnableCSS(void)1208 void HAL_RCC_EnableCSS(void)
1209 {
1210 SET_BIT(RCC->CR, RCC_CR_HSECSSON);
1211 }
1212
1213 /**
1214 * @brief Disables the Clock Security System.
1215 * @retval None
1216 */
HAL_RCC_DisableCSS(void)1217 void HAL_RCC_DisableCSS(void)
1218 {
1219 CLEAR_BIT(RCC->CR, RCC_CR_HSECSSON);
1220 }
1221
1222 /**
1223 * @brief Returns the SYSCLK frequency
1224 *
1225 * @note The system frequency computed by this function is not the real
1226 * frequency in the chip. It is calculated based on the predefined
1227 * constant and the selected clock source:
1228 * @note If SYSCLK source is CSI, function returns values based on CSI_VALUE(*)
1229 * @note If SYSCLK source is HSI, function returns values based on HSI_VALUE(**)
1230 * @note If SYSCLK source is HSE, function returns values based on HSE_VALUE(***)
1231 * @note If SYSCLK source is PLL, function returns values based on CSI_VALUE(*),
1232 * HSI_VALUE(**) or HSE_VALUE(***) multiplied/divided by the PLL factors.
1233 * @note (*) CSI_VALUE is a constant defined in stm32h7rsxx_hal_conf.h file (default value
1234 * 4 MHz) but the real value may vary depending on the variations
1235 * in voltage and temperature.
1236 * @note (**) HSI_VALUE is a constant defined in stm32h7rsxx_hal_conf.h file (default value
1237 * 64 MHz) but the real value may vary depending on the variations
1238 * in voltage and temperature.
1239 * @note (***) HSE_VALUE is a constant defined in stm32h7rsxx_hal_conf.h file (default value
1240 * 24 MHz), user has to ensure that HSE_VALUE is same as the real
1241 * frequency of the crystal used. Otherwise, this function may
1242 * have wrong result.
1243 *
1244 * @note The result of this function could be not correct when using fractional
1245 * value for HSE crystal.
1246 *
1247 * @note This function can be used by the user application to compute the
1248 * baud rate for the communication peripherals or configure other parameters.
1249 *
1250 * @note Each time SYSCLK changes, this function must be called to update the
1251 * right SYSCLK value. Otherwise, any configuration based on this function will be incorrect.
1252 *
1253 *
1254 * @retval SYSCLK frequency
1255 */
HAL_RCC_GetSysClockFreq(void)1256 uint32_t HAL_RCC_GetSysClockFreq(void)
1257 {
1258 uint32_t pllp, pllsource, pllm, pllfracen, hsivalue;
1259 float_t fracn1, pllvco;
1260 uint32_t sysclockfreq, prescaler;
1261
1262 /* Get SYSCLK source -------------------------------------------------------*/
1263
1264 switch (RCC->CFGR & RCC_CFGR_SWS)
1265 {
1266 case RCC_SYSCLKSOURCE_STATUS_HSI: /* HSI used as system clock source */
1267
1268 if (READ_BIT(RCC->CR, RCC_CR_HSIDIVF) != 0U)
1269 {
1270 sysclockfreq = (uint32_t)(HSI_VALUE >> (__HAL_RCC_GET_HSI_DIVIDER() >> RCC_CR_HSIDIV_Pos));
1271 }
1272 else
1273 {
1274 /* Can't retrieve HSIDIV value */
1275 sysclockfreq = 0U;
1276 }
1277
1278 break;
1279
1280 case RCC_SYSCLKSOURCE_STATUS_CSI: /* CSI used as system clock source */
1281 sysclockfreq = CSI_VALUE;
1282 break;
1283
1284 case RCC_SYSCLKSOURCE_STATUS_HSE: /* HSE used as system clock source */
1285 sysclockfreq = HSE_VALUE;
1286 break;
1287
1288 case RCC_SYSCLKSOURCE_STATUS_PLLCLK: /* PLL1 used as system clock source */
1289
1290 /* PLL_VCO = (HSE_VALUE or HSI_VALUE or CSI_VALUE/ PLLM) * PLLN
1291 SYSCLK = PLL_VCO / PLLR
1292 */
1293 pllsource = (RCC->PLLCKSELR & RCC_PLLCKSELR_PLLSRC);
1294 pllm = ((RCC->PLLCKSELR & RCC_PLLCKSELR_DIVM1) >> RCC_PLLCKSELR_DIVM1_Pos) ;
1295 pllfracen = ((RCC-> PLLCFGR & RCC_PLLCFGR_PLL1FRACEN) >> RCC_PLLCFGR_PLL1FRACEN_Pos);
1296 fracn1 = (float_t)(uint32_t)(pllfracen * ((RCC->PLL1FRACR & RCC_PLL1FRACR_FRACN) >> 3));
1297
1298 if (pllm != 0U)
1299 {
1300 switch (pllsource)
1301 {
1302 case RCC_PLLSOURCE_HSI: /* HSI used as PLL clock source */
1303
1304 if (READ_BIT(RCC->CR, RCC_CR_HSIDIVF) != 0U)
1305 {
1306 hsivalue = (HSI_VALUE >> (__HAL_RCC_GET_HSI_DIVIDER() >> RCC_CR_HSIDIV_Pos));
1307 pllvco = ((float_t)hsivalue / (float_t)pllm) * ((float_t)(uint32_t)(RCC->PLL1DIVR1 & RCC_PLL1DIVR1_DIVN) + (fracn1 / (float_t)0x2000) + (float_t)1);
1308 }
1309 else
1310 {
1311 /* Can't retrieve HSIDIV value */
1312 pllvco = (float_t)0;
1313 }
1314 break;
1315
1316 case RCC_PLLSOURCE_CSI: /* CSI used as PLL clock source */
1317 pllvco = ((float_t)CSI_VALUE / (float_t)pllm) * ((float_t)(uint32_t)(RCC->PLL1DIVR1 & RCC_PLL1DIVR1_DIVN) + (fracn1 / (float_t)0x2000) + (float_t)1);
1318 break;
1319
1320 case RCC_PLLSOURCE_HSE: /* HSE used as PLL clock source */
1321 pllvco = ((float_t)HSE_VALUE / (float_t)pllm) * ((float_t)(uint32_t)(RCC->PLL1DIVR1 & RCC_PLL1DIVR1_DIVN) + (fracn1 / (float_t)0x2000) + (float_t)1);
1322 break;
1323
1324 default:
1325 pllvco = ((float_t)CSI_VALUE / (float_t)pllm) * ((float_t)(uint32_t)(RCC->PLL1DIVR1 & RCC_PLL1DIVR1_DIVN) + (fracn1 / (float_t)0x2000) + (float_t)1);
1326 break;
1327 }
1328 pllp = (((RCC->PLL1DIVR1 & RCC_PLL1DIVR1_DIVP) >> RCC_PLL1DIVR1_DIVP_Pos) + 1U) ;
1329 sysclockfreq = (uint32_t)(float_t)(pllvco / (float_t)pllp);
1330 }
1331 else
1332 {
1333 sysclockfreq = 0U;
1334 }
1335 break;
1336
1337 default:
1338 sysclockfreq = CSI_VALUE;
1339 break;
1340 }
1341
1342 prescaler = RCC->CDCFGR & RCC_CDCFGR_CPRE;
1343 if (prescaler >= 8U)
1344 {
1345 sysclockfreq = sysclockfreq >> (prescaler - RCC_CDCFGR_CPRE_3 + 1U);
1346 }
1347
1348 return sysclockfreq;
1349 }
1350
1351
1352 /**
1353 * @brief Return the HCLK frequency.
1354 * @retval HCLK frequency in Hz
1355 */
HAL_RCC_GetHCLKFreq(void)1356 uint32_t HAL_RCC_GetHCLKFreq(void)
1357 {
1358 uint32_t clock, prescaler;
1359 const uint8_t AHBPrescTable[8] = {1U, 2U, 3U, 4U, 6U, 7U, 8U, 9U};
1360
1361 /* SysClk */
1362 clock = HAL_RCC_GetSysClockFreq();
1363 /* Bus matrix divider */
1364 prescaler = (RCC->BMCFGR & RCC_BMCFGR_BMPRE) >> RCC_BMCFGR_BMPRE_Pos;
1365 if (prescaler >= 8U)
1366 {
1367 clock = clock >> AHBPrescTable[prescaler - 8U];
1368 }
1369 return (clock);
1370 }
1371
1372 /**
1373 * @brief Return the PCLK1 frequency.
1374 * @note Each time PCLK1 changes, this function must be called to update the
1375 * right PCLK1 value. Otherwise, any configuration based on this function will be incorrect.
1376 * @retval PCLK1 frequency in Hz
1377 */
HAL_RCC_GetPCLK1Freq(void)1378 uint32_t HAL_RCC_GetPCLK1Freq(void)
1379 {
1380 uint32_t clock, prescaler;
1381 /* Get HCLK source and compute PCLK1 frequency ---------------------------*/
1382 clock = HAL_RCC_GetHCLKFreq();
1383 /* APB1 prescaler */
1384 prescaler = (RCC->APBCFGR & RCC_APBCFGR_PPRE1) >> RCC_APBCFGR_PPRE1_Pos;
1385 if (prescaler >= 4U)
1386 {
1387 clock = clock >> (prescaler - 3U);
1388 }
1389 return (clock);
1390 }
1391
1392 /**
1393 * @brief Return the PCLK2 frequency.
1394 * @note Each time PCLK2 changes, this function must be called to update the
1395 * right PCLK2 value. Otherwise, any configuration based on this function will be incorrect.
1396 * @retval PCLK2 frequency in Hz
1397 */
HAL_RCC_GetPCLK2Freq(void)1398 uint32_t HAL_RCC_GetPCLK2Freq(void)
1399 {
1400 uint32_t clock, prescaler;
1401 /* Get HCLK source and compute PCLK2 frequency ---------------------------*/
1402 clock = HAL_RCC_GetHCLKFreq();
1403 /* APB2 prescaler */
1404 prescaler = (RCC->APBCFGR & RCC_APBCFGR_PPRE2) >> RCC_APBCFGR_PPRE2_Pos;
1405 if (prescaler >= 4U)
1406 {
1407 clock = clock >> (prescaler - 3U);
1408 }
1409 return (clock);
1410 }
1411
1412 /**
1413 * @brief Return the PCLK4 frequency.
1414 * @note Each time PCLK4 changes, this function must be called to update the
1415 * right PCLK4 value. Otherwise, any configuration based on this function will be incorrect.
1416 * @retval PCLK4 frequency in Hz
1417 */
HAL_RCC_GetPCLK4Freq(void)1418 uint32_t HAL_RCC_GetPCLK4Freq(void)
1419 {
1420 uint32_t clock, prescaler;
1421 /* Get HCLK source and compute PCLK4 frequency ---------------------------*/
1422 clock = HAL_RCC_GetHCLKFreq();
1423 /* APB4 prescaler */
1424 prescaler = (RCC->APBCFGR & RCC_APBCFGR_PPRE4) >> RCC_APBCFGR_PPRE4_Pos;
1425 if (prescaler >= 4U)
1426 {
1427 clock = clock >> (prescaler - 3U);
1428 }
1429 return (clock);
1430 }
1431
1432 /**
1433 * @brief Return the PCLK5 frequency.
1434 * @note Each time PCLK5 changes, this function must be called to update the
1435 * right PCLK5 value. Otherwise, any configuration based on this function will be incorrect.
1436 * @retval PCLK5 frequency in Hz
1437 */
HAL_RCC_GetPCLK5Freq(void)1438 uint32_t HAL_RCC_GetPCLK5Freq(void)
1439 {
1440 uint32_t clock, prescaler;
1441 /* Get HCLK source and compute PCLK5 frequency ---------------------------*/
1442 clock = HAL_RCC_GetHCLKFreq();
1443 /* APB5 prescaler */
1444 prescaler = (RCC->APBCFGR & RCC_APBCFGR_PPRE5) >> RCC_APBCFGR_PPRE5_Pos;
1445 if (prescaler >= 4U)
1446 {
1447 clock = clock >> (prescaler - 3U);
1448 }
1449 return (clock);
1450 }
1451
1452 /**
1453 * @brief Return the PLL1P frequency.
1454 * @retval PLL1P frequency in Hz
1455 */
HAL_RCC_GetPLL1PFreq(void)1456 uint32_t HAL_RCC_GetPLL1PFreq(void)
1457 {
1458 uint32_t pllp;
1459
1460 /* PLL1P divider */
1461 pllp = ((RCC->PLL1DIVR1 & RCC_PLL1DIVR1_DIVP) >> RCC_PLL1DIVR1_DIVP_Pos) + 1U;
1462
1463 /* Compute VCO output frequency and return PLL1P one */
1464 return ((uint32_t)RCC_PLL1_GetVCOOutputFreq() / pllp);
1465 }
1466
1467 /**
1468 * @brief Return the PLL1Q frequency.
1469 * @retval PLL1Q frequency in Hz
1470 */
HAL_RCC_GetPLL1QFreq(void)1471 uint32_t HAL_RCC_GetPLL1QFreq(void)
1472 {
1473 uint32_t pllq;
1474
1475 /* PLL1Q divider */
1476 pllq = ((RCC->PLL1DIVR1 & RCC_PLL1DIVR1_DIVQ) >> RCC_PLL1DIVR1_DIVQ_Pos) + 1U;
1477
1478 /* Compute VCO output frequency and return PLL1Q one */
1479 return ((uint32_t)RCC_PLL1_GetVCOOutputFreq() / pllq);
1480 }
1481
1482 /**
1483 * @brief Return the PLL1R frequency.
1484 * @retval PLL1R frequency in Hz
1485 */
HAL_RCC_GetPLL1RFreq(void)1486 uint32_t HAL_RCC_GetPLL1RFreq(void)
1487 {
1488 uint32_t pllr;
1489
1490 /* PLL1R divider */
1491 pllr = ((RCC->PLL1DIVR1 & RCC_PLL1DIVR1_DIVR) >> RCC_PLL1DIVR1_DIVR_Pos) + 1U;
1492
1493 /* Compute VCO output frequency and return PLL1R one */
1494 return ((uint32_t)RCC_PLL1_GetVCOOutputFreq() / pllr);
1495 }
1496
1497 /**
1498 * @brief Return the PLL1S frequency.
1499 * @retval PLL1S frequency in Hz
1500 */
HAL_RCC_GetPLL1SFreq(void)1501 uint32_t HAL_RCC_GetPLL1SFreq(void)
1502 {
1503 uint32_t plls;
1504
1505 /* PLL1S divider */
1506 plls = ((RCC->PLL1DIVR2 & RCC_PLL1DIVR2_DIVS) >> RCC_PLL1DIVR2_DIVS_Pos) + 1U;
1507
1508 /* Compute VCO output frequency and return PLL1S one */
1509 return ((uint32_t)RCC_PLL1_GetVCOOutputFreq() / plls);
1510 }
1511
1512 /**
1513 * @brief Return the PLL2P frequency.
1514 * @retval PLL2P frequency in Hz
1515 */
HAL_RCC_GetPLL2PFreq(void)1516 uint32_t HAL_RCC_GetPLL2PFreq(void)
1517 {
1518 uint32_t pllp;
1519
1520 /* PLL2P divider */
1521 pllp = ((RCC->PLL2DIVR1 & RCC_PLL2DIVR1_DIVP) >> RCC_PLL2DIVR1_DIVP_Pos) + 1U;
1522
1523 /* Compute VCO output frequency and return PLL2P one */
1524 return ((uint32_t)RCC_PLL2_GetVCOOutputFreq() / pllp);
1525 }
1526
1527 /**
1528 * @brief Return the PLL2Q frequency.
1529 * @retval PLL2Q frequency in Hz
1530 */
HAL_RCC_GetPLL2QFreq(void)1531 uint32_t HAL_RCC_GetPLL2QFreq(void)
1532 {
1533 uint32_t pllq;
1534
1535 /* PLL2Q divider */
1536 pllq = ((RCC->PLL2DIVR1 & RCC_PLL2DIVR1_DIVQ) >> RCC_PLL2DIVR1_DIVQ_Pos) + 1U;
1537
1538 /* Compute VCO output frequency and return PLL2Q one */
1539 return ((uint32_t)RCC_PLL2_GetVCOOutputFreq() / pllq);
1540 }
1541
1542 /**
1543 * @brief Return the PLL2R frequency.
1544 * @retval PLL2R frequency in Hz
1545 */
HAL_RCC_GetPLL2RFreq(void)1546 uint32_t HAL_RCC_GetPLL2RFreq(void)
1547 {
1548 uint32_t pllr;
1549
1550 /* PLL2R divider */
1551 pllr = ((RCC->PLL2DIVR1 & RCC_PLL2DIVR1_DIVR) >> RCC_PLL2DIVR1_DIVR_Pos) + 1U;
1552
1553 /* Compute VCO output frequency and return PLL2R one */
1554 return ((uint32_t)RCC_PLL2_GetVCOOutputFreq() / pllr);
1555 }
1556
1557 /**
1558 * @brief Return the PLL2S frequency.
1559 * @retval PLL2S frequency in Hz
1560 */
HAL_RCC_GetPLL2SFreq(void)1561 uint32_t HAL_RCC_GetPLL2SFreq(void)
1562 {
1563 uint32_t plls;
1564
1565 /* PLL2S divider */
1566 plls = ((RCC->PLL2DIVR2 & RCC_PLL2DIVR2_DIVS) >> RCC_PLL2DIVR2_DIVS_Pos) + 1U;
1567
1568 /* Compute VCO output frequency and return PLL2R one */
1569 return ((uint32_t)RCC_PLL2_GetVCOOutputFreq() / plls);
1570 }
1571
1572 /**
1573 * @brief Return the PLL2T frequency.
1574 * @retval PLL2T frequency in Hz
1575 */
HAL_RCC_GetPLL2TFreq(void)1576 uint32_t HAL_RCC_GetPLL2TFreq(void)
1577 {
1578 uint32_t pllt;
1579
1580 /* PLL2T divider */
1581 pllt = ((RCC->PLL2DIVR2 & RCC_PLL2DIVR2_DIVT) >> RCC_PLL2DIVR2_DIVT_Pos) + 1U;
1582
1583 /* Compute VCO output frequency and return PLL2T one */
1584 return ((uint32_t)RCC_PLL2_GetVCOOutputFreq() / pllt);
1585 }
1586
1587 /**
1588 * @brief Return the PLL3P frequency.
1589 * @retval PLL3P frequency in Hz
1590 */
HAL_RCC_GetPLL3PFreq(void)1591 uint32_t HAL_RCC_GetPLL3PFreq(void)
1592 {
1593 uint32_t pllp;
1594
1595 /* PLL3P divider */
1596 pllp = ((RCC->PLL3DIVR1 & RCC_PLL3DIVR1_DIVP) >> RCC_PLL3DIVR1_DIVP_Pos) + 1U;
1597
1598 /* Compute VCO output frequency and return PLL3P one */
1599 return ((uint32_t)RCC_PLL3_GetVCOOutputFreq() / pllp);
1600 }
1601
1602 /**
1603 * @brief Return the PLL3Q frequency.
1604 * @retval PLL3Q frequency in Hz
1605 */
HAL_RCC_GetPLL3QFreq(void)1606 uint32_t HAL_RCC_GetPLL3QFreq(void)
1607 {
1608 uint32_t pllq;
1609
1610 /* PLL3Q divider */
1611 pllq = ((RCC->PLL3DIVR1 & RCC_PLL3DIVR1_DIVQ) >> RCC_PLL3DIVR1_DIVQ_Pos) + 1U;
1612
1613 /* Compute VCO output frequency and return PLL3Q one */
1614 return ((uint32_t)RCC_PLL3_GetVCOOutputFreq() / pllq);
1615 }
1616
1617 /**
1618 * @brief Return the PLL3R frequency.
1619 * @retval PLL3R frequency in Hz
1620 */
HAL_RCC_GetPLL3RFreq(void)1621 uint32_t HAL_RCC_GetPLL3RFreq(void)
1622 {
1623 uint32_t pllr;
1624
1625 /* PLL3R divider */
1626 pllr = ((RCC->PLL3DIVR1 & RCC_PLL3DIVR1_DIVR) >> RCC_PLL3DIVR1_DIVR_Pos) + 1U;
1627
1628 /* Compute VCO output frequency and return PLL3R one */
1629 return ((uint32_t)RCC_PLL3_GetVCOOutputFreq() / pllr);
1630 }
1631
1632 /**
1633 * @brief Return the PLL3S frequency.
1634 * @retval PLL3S frequency in Hz
1635 */
HAL_RCC_GetPLL3SFreq(void)1636 uint32_t HAL_RCC_GetPLL3SFreq(void)
1637 {
1638 uint32_t plls;
1639
1640 /* PLL3S divider */
1641 plls = ((RCC->PLL3DIVR2 & RCC_PLL3DIVR2_DIVS) >> RCC_PLL3DIVR2_DIVS_Pos) + 1U;
1642
1643 /* Compute VCO output frequency and return PLL3S one */
1644 return ((uint32_t)RCC_PLL3_GetVCOOutputFreq() / plls);
1645 }
1646
1647 /**
1648 * @brief Configures the RCC_OscInitStruct according to the internal
1649 * RCC configuration registers.
1650 * @param RCC_OscInitStruct: pointer to an RCC_OscInitTypeDef structure that
1651 * will be configured.
1652 * @retval None
1653 */
HAL_RCC_GetOscConfig(RCC_OscInitTypeDef * RCC_OscInitStruct)1654 void HAL_RCC_GetOscConfig(RCC_OscInitTypeDef *RCC_OscInitStruct)
1655 {
1656
1657 uint32_t regvalue;
1658 uint32_t mask;
1659
1660 /* Check the parameters */
1661 assert_param(RCC_OscInitStruct != (void *)NULL);
1662
1663 /* Set all possible values for the Oscillator type parameter ---------------*/
1664 RCC_OscInitStruct->OscillatorType = RCC_OSCILLATORTYPE_HSE | RCC_OSCILLATORTYPE_HSI | RCC_OSCILLATORTYPE_CSI | \
1665 RCC_OSCILLATORTYPE_LSE | RCC_OSCILLATORTYPE_LSI | RCC_OSCILLATORTYPE_HSI48;
1666
1667 /* Get Backup Domain register */
1668 regvalue = RCC->BDCR;
1669
1670 /* Get the LSE configuration -----------------------------------------------*/
1671 mask = (RCC_BDCR_LSEBYP | RCC_BDCR_LSEEXT | RCC_BDCR_LSEON);
1672 RCC_OscInitStruct->LSEState = (regvalue & mask);
1673
1674 /* Get RCC clock control and status register */
1675 regvalue = RCC->CSR;
1676
1677 /* Get the LSI configuration -----------------------------------------------*/
1678 mask = RCC_CSR_LSION;
1679 RCC_OscInitStruct->LSIState = (regvalue & mask);
1680
1681 /* Get Control register */
1682 regvalue = RCC->CR;
1683
1684 /* Get the HSE configuration -----------------------------------------------*/
1685 mask = (RCC_CR_HSEBYP | RCC_CR_HSEEXT | RCC_CR_HSEON);
1686 RCC_OscInitStruct->HSEState = (regvalue & mask);
1687
1688 /* Get the HSI configuration -----------------------------------------------*/
1689 mask = RCC_CR_HSION;
1690 RCC_OscInitStruct->HSIState = (regvalue & mask);
1691 RCC_OscInitStruct->HSIDiv = (regvalue & RCC_CR_HSIDIV);
1692 RCC_OscInitStruct->HSICalibrationValue = ((RCC->HSICFGR & RCC_HSICFGR_HSITRIM) >> RCC_HSICFGR_HSITRIM_Pos);
1693
1694 /* Get the HSI48 configuration ---------------------------------------------*/
1695 mask = RCC_CR_HSI48ON;
1696 RCC_OscInitStruct->HSI48State = (regvalue & mask);
1697
1698 /* Get the CSI configuration -----------------------------------------------*/
1699 mask = RCC_CR_CSION;
1700 RCC_OscInitStruct->CSIState = (regvalue & mask);
1701
1702 /* Get the PLL1 configuration -----------------------------------------------*/
1703 if ((regvalue & RCC_CR_PLL1ON) == RCC_CR_PLL1ON)
1704 {
1705 RCC_OscInitStruct->PLL1.PLLState = RCC_PLL_ON;
1706 }
1707 else
1708 {
1709 RCC_OscInitStruct->PLL1.PLLState = RCC_PLL_OFF;
1710 }
1711
1712 /* Get PLL1 configuration register */
1713 regvalue = RCC->PLLCKSELR;
1714 RCC_OscInitStruct->PLL1.PLLSource = (regvalue & RCC_PLLCKSELR_PLLSRC);
1715 RCC_OscInitStruct->PLL1.PLLM = ((regvalue & RCC_PLLCKSELR_DIVM1) >> RCC_PLLCKSELR_DIVM1_Pos);
1716
1717 /* Check if fractional part is enable */
1718 regvalue = RCC->PLLCFGR;
1719 if ((regvalue & RCC_PLLCFGR_PLL1FRACEN) != 0x00u)
1720 {
1721 regvalue = (((RCC->PLL1FRACR & RCC_PLL1FRACR_FRACN) >> RCC_PLL1FRACR_FRACN_Pos));
1722 }
1723 else
1724 {
1725 regvalue = 0;
1726 }
1727 RCC_OscInitStruct->PLL1.PLLFractional = regvalue;
1728
1729 /* Get PLL1 dividers register */
1730 regvalue = RCC->PLL1DIVR1;
1731 RCC_OscInitStruct->PLL1.PLLN = ((regvalue & RCC_PLL1DIVR1_DIVN) + 1U);
1732 RCC_OscInitStruct->PLL1.PLLR = (((regvalue & RCC_PLL1DIVR1_DIVR) >> RCC_PLL1DIVR1_DIVR_Pos) + 1U);
1733 RCC_OscInitStruct->PLL1.PLLP = (((regvalue & RCC_PLL1DIVR1_DIVP) >> RCC_PLL1DIVR1_DIVP_Pos) + 1U);
1734 RCC_OscInitStruct->PLL1.PLLQ = (((regvalue & RCC_PLL1DIVR1_DIVQ) >> RCC_PLL1DIVR1_DIVQ_Pos) + 1U);
1735 regvalue = RCC->PLL1DIVR2;
1736 RCC_OscInitStruct->PLL1.PLLS = (((regvalue & RCC_PLL1DIVR2_DIVS) >> RCC_PLL1DIVR2_DIVS_Pos) + 1U);
1737 RCC_OscInitStruct->PLL1.PLLT = 0;
1738
1739 /* Get the PLL2 configuration -----------------------------------------------*/
1740 /* Get Control register */
1741 regvalue = RCC->CR;
1742 if ((regvalue & RCC_CR_PLL2ON) == RCC_CR_PLL2ON)
1743 {
1744 RCC_OscInitStruct->PLL2.PLLState = RCC_PLL_ON;
1745 }
1746 else
1747 {
1748 RCC_OscInitStruct->PLL2.PLLState = RCC_PLL_OFF;
1749 }
1750
1751 /* Get PLL2 configuration register */
1752 regvalue = RCC->PLLCKSELR;
1753 RCC_OscInitStruct->PLL2.PLLSource = (regvalue & RCC_PLLCKSELR_PLLSRC);
1754 RCC_OscInitStruct->PLL2.PLLM = ((regvalue & RCC_PLLCKSELR_DIVM2) >> RCC_PLLCKSELR_DIVM2_Pos);
1755
1756 /* Check if fractional part is enable */
1757 regvalue = RCC->PLLCFGR;
1758 if ((regvalue & RCC_PLLCFGR_PLL2FRACEN) != 0x00u)
1759 {
1760 regvalue = (((RCC->PLL2FRACR & RCC_PLL2FRACR_FRACN) >> RCC_PLL2FRACR_FRACN_Pos));
1761 }
1762 else
1763 {
1764 regvalue = 0;
1765 }
1766 RCC_OscInitStruct->PLL2.PLLFractional = regvalue;
1767
1768 /* Get PLL2 dividers register */
1769 regvalue = RCC->PLL2DIVR1;
1770 RCC_OscInitStruct->PLL2.PLLN = ((regvalue & RCC_PLL2DIVR1_DIVN) + 1U);
1771 RCC_OscInitStruct->PLL2.PLLR = (((regvalue & RCC_PLL2DIVR1_DIVR) >> RCC_PLL2DIVR1_DIVR_Pos) + 1U);
1772 RCC_OscInitStruct->PLL2.PLLP = (((regvalue & RCC_PLL2DIVR1_DIVP) >> RCC_PLL2DIVR1_DIVP_Pos) + 1U);
1773 RCC_OscInitStruct->PLL2.PLLQ = (((regvalue & RCC_PLL2DIVR1_DIVQ) >> RCC_PLL2DIVR1_DIVQ_Pos) + 1U);
1774 regvalue = RCC->PLL2DIVR2;
1775 RCC_OscInitStruct->PLL2.PLLS = (((regvalue & RCC_PLL2DIVR2_DIVS) >> RCC_PLL2DIVR2_DIVS_Pos) + 1U);
1776 RCC_OscInitStruct->PLL2.PLLT = (((regvalue & RCC_PLL2DIVR2_DIVT) >> RCC_PLL2DIVR2_DIVT_Pos) + 1U);
1777
1778 /* Get the PLL3 configuration -----------------------------------------------*/
1779 /* Get Control register */
1780 regvalue = RCC->CR;
1781 if ((regvalue & RCC_CR_PLL3ON) == RCC_CR_PLL3ON)
1782 {
1783 RCC_OscInitStruct->PLL3.PLLState = RCC_PLL_ON;
1784 }
1785 else
1786 {
1787 RCC_OscInitStruct->PLL3.PLLState = RCC_PLL_OFF;
1788 }
1789
1790 /* Get PLL3 configuration register */
1791 regvalue = RCC->PLLCKSELR;
1792 RCC_OscInitStruct->PLL3.PLLSource = (regvalue & RCC_PLLCKSELR_PLLSRC);
1793 RCC_OscInitStruct->PLL3.PLLM = ((regvalue & RCC_PLLCKSELR_DIVM3) >> RCC_PLLCKSELR_DIVM3_Pos);
1794
1795
1796 /* Check if fractional part is enable */
1797 regvalue = RCC->PLLCFGR;
1798 if ((regvalue & RCC_PLLCFGR_PLL3FRACEN) != 0x00u)
1799 {
1800 regvalue = (((RCC->PLL3FRACR & RCC_PLL3FRACR_FRACN) >> RCC_PLL3FRACR_FRACN_Pos));
1801 }
1802 else
1803 {
1804 regvalue = 0;
1805 }
1806 RCC_OscInitStruct->PLL3.PLLFractional = regvalue;
1807
1808 /* Get PLL3 dividers register */
1809 regvalue = RCC->PLL3DIVR1;
1810 RCC_OscInitStruct->PLL3.PLLN = ((regvalue & RCC_PLL3DIVR1_DIVN) + 1U);
1811 RCC_OscInitStruct->PLL3.PLLR = (((regvalue & RCC_PLL3DIVR1_DIVR) >> RCC_PLL3DIVR1_DIVR_Pos) + 1U);
1812 RCC_OscInitStruct->PLL3.PLLP = (((regvalue & RCC_PLL3DIVR1_DIVP) >> RCC_PLL3DIVR1_DIVP_Pos) + 1U);
1813 RCC_OscInitStruct->PLL3.PLLQ = (((regvalue & RCC_PLL3DIVR1_DIVQ) >> RCC_PLL3DIVR1_DIVQ_Pos) + 1U);
1814 regvalue = RCC->PLL3DIVR2;
1815 RCC_OscInitStruct->PLL3.PLLS = (((regvalue & RCC_PLL3DIVR2_DIVS) >> RCC_PLL3DIVR2_DIVS_Pos) + 1U);
1816 RCC_OscInitStruct->PLL3.PLLT = 0;
1817
1818 }
1819
1820 /**
1821 * @brief Configures the RCC_ClkInitStruct according to the internal
1822 * RCC configuration registers.
1823 * @param RCC_ClkInitStruct: pointer to an RCC_ClkInitTypeDef structure that
1824 * will be configured.
1825 * @param pFLatency: Pointer on the Flash Latency.
1826 * @retval None
1827 */
HAL_RCC_GetClockConfig(RCC_ClkInitTypeDef * RCC_ClkInitStruct,uint32_t * pFLatency)1828 void HAL_RCC_GetClockConfig(RCC_ClkInitTypeDef *RCC_ClkInitStruct, uint32_t *pFLatency)
1829 {
1830 /* Set all possible values for the Clock type parameter --------------------*/
1831 RCC_ClkInitStruct->ClockType = RCC_CLOCKTYPE_SYSCLK | RCC_CLOCKTYPE_HCLK | \
1832 RCC_CLOCKTYPE_PCLK1 | RCC_CLOCKTYPE_PCLK2 | \
1833 RCC_CLOCKTYPE_PCLK4 | RCC_CLOCKTYPE_PCLK5;
1834
1835 /* Get the SYSCLK source ---------------------------------------------------*/
1836 RCC_ClkInitStruct->SYSCLKSource = READ_BIT(RCC->CFGR, RCC_CFGR_SW);
1837
1838 /* Get the SYSCLK configuration---------------------------------------------*/
1839 RCC_ClkInitStruct->SYSCLKDivider = READ_BIT(RCC->CDCFGR, RCC_CDCFGR_CPRE);
1840
1841 /* Get the HCLK configuration ----------------------------------------------*/
1842 RCC_ClkInitStruct->AHBCLKDivider = READ_BIT(RCC->BMCFGR, RCC_BMCFGR_BMPRE);
1843
1844 /* Get the APB1 configuration ----------------------------------------------*/
1845 RCC_ClkInitStruct->APB1CLKDivider = READ_BIT(RCC->APBCFGR, RCC_APBCFGR_PPRE1);
1846
1847 /* Get the APB2 configuration ----------------------------------------------*/
1848 RCC_ClkInitStruct->APB2CLKDivider = READ_BIT(RCC->APBCFGR, RCC_APBCFGR_PPRE2);
1849
1850 /* Get the APB4 configuration ----------------------------------------------*/
1851 RCC_ClkInitStruct->APB4CLKDivider = READ_BIT(RCC->APBCFGR, RCC_APBCFGR_PPRE4);
1852
1853 /* Get the APB5 configuration ----------------------------------------------*/
1854 RCC_ClkInitStruct->APB5CLKDivider = READ_BIT(RCC->APBCFGR, RCC_APBCFGR_PPRE5);
1855
1856 /* Get the Flash Wait State (Latency) configuration ------------------------*/
1857 *pFLatency = __HAL_FLASH_GET_LATENCY();
1858 }
1859
1860 /**
1861 * @brief This function handles the RCC HSE CSS interrupt request.
1862 * @note This API should be called under the NMI_Handler().
1863 * @retval None
1864 */
HAL_RCC_NMI_IRQHandler(void)1865 void HAL_RCC_NMI_IRQHandler(void)
1866 {
1867 /* Check RCC HSECSSF interrupt flag */
1868 if (__HAL_RCC_GET_IT(RCC_IT_HSECSS))
1869 {
1870 /* Clear RCC HSE CSS pending bit */
1871 __HAL_RCC_CLEAR_IT(RCC_IT_HSECSS);
1872
1873 /* RCC HSE Clock Security System interrupt user callback */
1874 HAL_RCC_HSECSSCallback();
1875 }
1876 }
1877
1878 /**
1879 * @brief RCC HSE Clock Security System interrupt callback
1880 * @retval none
1881 */
HAL_RCC_HSECSSCallback(void)1882 __weak void HAL_RCC_HSECSSCallback(void)
1883 {
1884 /* NOTE : This function should not be modified, when the callback is needed,
1885 the HAL_RCC_HSECSSCallback could be implemented in the user file
1886 */
1887 }
1888
1889 /**
1890 * @brief RCC LSE Clock Security System interrupt callback
1891 * @retval none
1892 */
HAL_RCC_LSECSSCallback(void)1893 __weak void HAL_RCC_LSECSSCallback(void)
1894 {
1895 /* NOTE : This function should not be modified, when the callback is needed,
1896 the HAL_RCC_LSECSSCallback could be implemented in the user file
1897 */
1898 }
1899
1900 /**
1901 * @brief Get and clear reset flags
1902 * @note Once reset flags are retrieved, this API is clearing them in order
1903 * to isolate next reset reason.
1904 * @retval can be a combination of @ref RCC_Reset_Flag
1905 */
HAL_RCC_GetResetSource(void)1906 uint32_t HAL_RCC_GetResetSource(void)
1907 {
1908 uint32_t reset;
1909
1910 /* Get all reset flags */
1911 reset = RCC->RSR & RCC_RESET_FLAG_ALL;
1912
1913 /* Clear Reset flags */
1914 RCC->RSR |= RCC_RSR_RMVF;
1915
1916 return reset;
1917 }
1918
1919 /**
1920 * @}
1921 */
1922
1923 /* Private functions ---------------------------------------------------------*/
1924 /** @addtogroup RCC_Private_Functions
1925 * @{
1926 */
1927
1928 /**
1929 * @brief Configure the requested PLL
1930 * @param PLLnumber PLL number to configure
1931 * @param pPLLInit Pointer to an RCC_PLLInitTypeDef structure that
1932 * contains the configuration parameters.
1933 * @note PLL is temporary disabled to apply new parameters
1934 *
1935 * @retval HAL status
1936 */
RCC_PLL_Config(uint32_t PLLnumber,const RCC_PLLInitTypeDef * pPLLInit)1937 static HAL_StatusTypeDef RCC_PLL_Config(uint32_t PLLnumber, const RCC_PLLInitTypeDef *pPLLInit)
1938 {
1939 __IO uint32_t *p_rcc_pll_divr1_reg;
1940 __IO uint32_t *p_rcc_pll_divr2_reg;
1941 __IO uint32_t *p_rcc_pll_fracr_reg;
1942 HAL_StatusTypeDef ret = HAL_OK;
1943 uint32_t tickstart;
1944 uint32_t pllsrc;
1945 uint32_t pllvco;
1946
1947 p_rcc_pll_divr1_reg = &(RCC->PLL1DIVR1) + (((uint32_t)0x02) * PLLnumber);
1948 p_rcc_pll_divr2_reg = &(RCC->PLL1DIVR2) + (((uint32_t)0x01) * PLLnumber);
1949
1950 /* Disable the post-dividers */
1951 CLEAR_BIT(RCC->PLLCFGR, (RCC_PLLCFGR_PLL1PEN | RCC_PLLCFGR_PLL1QEN | RCC_PLLCFGR_PLL1REN | RCC_PLLCFGR_PLL1SEN |
1952 0x00000200U) /* Hardcoded because no definition in CMSIS */
1953 << ((RCC_PLLCFGR_PLL2PEN_Pos - RCC_PLLCFGR_PLL1PEN_Pos)*PLLnumber));
1954
1955 /* Ensure PLLx is disabled */
1956 CLEAR_BIT(RCC->CR, RCC_CR_PLL1ON << ((RCC_CR_PLL2ON_Pos - RCC_CR_PLL1ON_Pos)*PLLnumber));
1957
1958 /* Get Start Tick*/
1959 tickstart = HAL_GetTick();
1960
1961 /* Wait till PLLx is disabled */
1962 while (READ_BIT(RCC->CR, (RCC_CR_PLL1RDY << ((RCC_CR_PLL2RDY_Pos - RCC_CR_PLL1RDY_Pos)*PLLnumber))) != 0U)
1963 {
1964 if ((HAL_GetTick() - tickstart) > RCC_PLL_TIMEOUT_VALUE)
1965 {
1966 return HAL_TIMEOUT;
1967 }
1968 }
1969
1970 if (pPLLInit->PLLState == RCC_PLL_ON)
1971 {
1972 /* Check the parameters */
1973 assert_param(IS_RCC_PLLSOURCE(pPLLInit->PLLSource));
1974 assert_param(IS_RCC_PLLM_VALUE(pPLLInit->PLLM));
1975 assert_param(IS_RCC_PLLN_VALUE(pPLLInit->PLLN));
1976 assert_param(IS_RCC_PLLP_VALUE(pPLLInit->PLLP));
1977 assert_param(IS_RCC_PLLQ_VALUE(pPLLInit->PLLQ));
1978 assert_param(IS_RCC_PLLR_VALUE(pPLLInit->PLLR));
1979 assert_param(IS_RCC_PLLS_VALUE(pPLLInit->PLLS));
1980 assert_param(IS_RCC_PLLT_VALUE(pPLLInit->PLLT));
1981
1982 pllsrc = pPLLInit->PLLSource;
1983
1984 /* Compute VCO input frequency and define range accordingly. First check clock source frequency */
1985 if (pllsrc == RCC_PLLSOURCE_HSI)
1986 {
1987 /* Clock source is HSI or HSI/HSIDIV */
1988 pllvco = HSI_VALUE >> ((RCC->CR & RCC_CR_HSIDIV) >> RCC_CR_HSIDIV_Pos);
1989 }
1990 else if (pllsrc == RCC_PLLSOURCE_HSE)
1991 {
1992 /* Clock source is HSE */
1993 pllvco = HSE_VALUE;
1994 }
1995 else
1996 {
1997 /* Clock source is CSI */
1998 pllvco = CSI_VALUE;
1999 }
2000
2001 /* Compute VCO input frequency depending on M divider */
2002 pllvco = (pllvco / pPLLInit->PLLM);
2003 assert_param(IS_RCC_PLL_VCOINPUTFREQ(pllvco));
2004
2005 if (pllvco >= RCC_PLL_INPUTRANGE2_FREQMAX)
2006 {
2007 pllvco = RCC_PLL_VCOINPUT_RANGE3 | RCC_PLL_VCO_HIGH;
2008 }
2009 else if (pllvco >= RCC_PLL_INPUTRANGE1_FREQMAX)
2010 {
2011 pllvco = RCC_PLL_VCOINPUT_RANGE2 | RCC_PLL_VCO_HIGH;
2012 }
2013 else if (pllvco >= RCC_PLL_INPUTRANGE0_FREQMAX)
2014 {
2015 pllvco = RCC_PLL_VCOINPUT_RANGE1 | RCC_PLL_VCO_HIGH;
2016 }
2017 else
2018 {
2019 pllvco = RCC_PLL_VCOINPUT_RANGE0 | RCC_PLL_VCO_LOW;
2020 }
2021
2022 pllvco = (pllvco << ((RCC_PLLCFGR_PLL2RGE_Pos - RCC_PLLCFGR_PLL1RGE_Pos) * PLLnumber));
2023
2024 /* Configure PLL source and PLLM divider */
2025 MODIFY_REG(RCC->PLLCKSELR, (RCC_PLLCKSELR_PLLSRC | (RCC_PLLCKSELR_DIVM1 << ((RCC_PLLCKSELR_DIVM2_Pos - RCC_PLLCKSELR_DIVM1_Pos)*PLLnumber))), \
2026 pllsrc | (pPLLInit->PLLM << (RCC_PLLCKSELR_DIVM1_Pos + ((RCC_PLLCKSELR_DIVM2_Pos - RCC_PLLCKSELR_DIVM1_Pos)*PLLnumber))));
2027
2028 if ((RCC->PLLCKSELR & RCC_PLLCKSELR_PLLSRC) != pllsrc)
2029 {
2030 /* There is another PLL activated with another source */
2031 return HAL_ERROR;
2032 }
2033
2034 /* Configure VCO input range, VCO selection and clear FRACEN */
2035 MODIFY_REG(RCC->PLLCFGR, (RCC_PLLCFGR_PLL1RGE | RCC_PLLCFGR_PLL1VCOSEL | RCC_PLLCFGR_PLL1FRACEN) << (((RCC_PLLCFGR_PLL2RGE_Pos - RCC_PLLCFGR_PLL1RGE_Pos)*PLLnumber)), \
2036 pllvco);
2037
2038 /* Configure PLLN, PLLP, PLLQ, PLLR, PLLS and PLLT dividers */
2039 WRITE_REG(*p_rcc_pll_divr1_reg, ((pPLLInit->PLLN - 1U) |
2040 ((pPLLInit->PLLP - 1U) << RCC_PLL1DIVR1_DIVP_Pos) |
2041 ((pPLLInit->PLLQ - 1U) << RCC_PLL1DIVR1_DIVQ_Pos) |
2042 ((pPLLInit->PLLR - 1U) << RCC_PLL1DIVR1_DIVR_Pos)));
2043 WRITE_REG(*p_rcc_pll_divr2_reg, ((pPLLInit->PLLS - 1U) |
2044 ((pPLLInit->PLLT - 1U) << RCC_PLL2DIVR2_DIVT_Pos)));
2045
2046 if (PLLnumber == RCC_PLL1_CONFIG)
2047 {
2048 SET_BIT(RCC->PLLCFGR, RCC_PLLCFGR_PLL1PEN);
2049 }
2050
2051 if (pPLLInit->PLLFractional != 0U)
2052 {
2053 assert_param(IS_RCC_PLLFRACN_VALUE(pPLLInit->PLLFractional));
2054
2055 p_rcc_pll_fracr_reg = &(RCC->PLL1FRACR) + (((uint32_t)0x02) * PLLnumber);
2056
2057 /* Configure PLLFRACN */
2058 MODIFY_REG(*p_rcc_pll_fracr_reg, RCC_PLL1FRACR_FRACN, pPLLInit->PLLFractional << RCC_PLL1FRACR_FRACN_Pos);
2059
2060 /* Enable PLLFRACLE */
2061 SET_BIT(RCC->PLLCFGR, RCC_PLLCFGR_PLL1FRACEN << ((RCC_PLLCFGR_PLL2FRACEN_Pos - RCC_PLLCFGR_PLL1FRACEN_Pos)*PLLnumber));
2062 }
2063
2064 /* Enable the PLLx */
2065 SET_BIT(RCC->CR, RCC_CR_PLL1ON << ((RCC_CR_PLL2ON_Pos - RCC_CR_PLL1ON_Pos)*PLLnumber));
2066
2067 /* Get Start Tick*/
2068 tickstart = HAL_GetTick();
2069
2070 /* Wait till PLLx is ready */
2071 while (READ_BIT(RCC->CR, RCC_CR_PLL1RDY << ((RCC_CR_PLL2RDY_Pos - RCC_CR_PLL1RDY_Pos)*PLLnumber)) == 0U)
2072 {
2073 if ((HAL_GetTick() - tickstart) > RCC_PLL_TIMEOUT_VALUE)
2074 {
2075 return HAL_TIMEOUT;
2076 }
2077 }
2078 }
2079 else
2080 {
2081 /* Disable outputs to save power when PLLx is off */
2082 MODIFY_REG(RCC->PLLCKSELR, ((RCC_PLLCKSELR_DIVM1 << (RCC_PLLCKSELR_DIVM1_Pos + ((RCC_PLLCKSELR_DIVM2_Pos - RCC_PLLCKSELR_DIVM1_Pos)*PLLnumber)))
2083 | RCC_PLLCKSELR_PLLSRC), RCC_PLLSOURCE_NONE);
2084 }
2085
2086 return ret;
2087 }
2088
2089 /**
2090 * @brief Compute PLL1 VCO output frequency
2091 * @retval Value of PLL1 VCO output frequency
2092 */
RCC_PLL1_GetVCOOutputFreq(void)2093 static uint32_t RCC_PLL1_GetVCOOutputFreq(void)
2094 {
2095 uint32_t tmpreg1;
2096 uint32_t tmpreg2;
2097 uint32_t pllsrc;
2098 uint32_t pllm;
2099 uint32_t plln;
2100 uint32_t pllfracn;
2101 float_t frequency;
2102
2103 /* Get PLL1 CFGR and DIVR register values */
2104 tmpreg1 = RCC->PLLCKSELR;
2105 tmpreg2 = RCC->PLL1DIVR1;
2106
2107 /* Retrieve PLL1 multiplication factor and divider */
2108 pllm = (tmpreg1 & RCC_PLLCKSELR_DIVM1) >> RCC_PLLCKSELR_DIVM1_Pos;
2109 plln = (tmpreg2 & RCC_PLL1DIVR1_DIVN) + 1U;
2110
2111 if (pllm == 0U)
2112 {
2113 /* Prescaler disabled */
2114 return 0U;
2115 }
2116
2117 /* Check if fractional part is enable */
2118 if ((tmpreg1 & RCC_PLLCFGR_PLL1FRACEN) != 0U)
2119 {
2120 pllfracn = (RCC->PLL1FRACR & RCC_PLL1FRACR_FRACN) >> RCC_PLL1FRACR_FRACN_Pos;
2121 }
2122 else
2123 {
2124 pllfracn = 0U;
2125 }
2126
2127 /* determine PLL source */
2128 switch (tmpreg1 & RCC_PLLCKSELR_PLLSRC)
2129 {
2130 /* HSI used as PLL1 clock source */
2131 case RCC_PLLSOURCE_HSI:
2132 if (READ_BIT(RCC->CR, RCC_CR_HSIDIVF) != 0U)
2133 {
2134 pllsrc = HSI_VALUE >> ((RCC->CR & RCC_CR_HSIDIV) >> RCC_CR_HSIDIV_Pos);
2135 }
2136 else
2137 {
2138 /* Can't retrieve HSIDIV value */
2139 pllsrc = 0U;
2140 }
2141 break;
2142
2143 /* HSE used as PLL1 clock source */
2144 case RCC_PLLSOURCE_HSE:
2145 pllsrc = HSE_VALUE;
2146 break;
2147
2148 /* CSI used as PLL1 clock source */
2149 case RCC_PLLSOURCE_CSI:
2150 pllsrc = CSI_VALUE;
2151 break;
2152
2153 default:
2154 pllsrc = 0U;
2155 break;
2156 }
2157
2158 /* Compute VCO output frequency */
2159 frequency = ((float_t)pllsrc / (float_t)pllm) * ((float_t)plln + ((float_t)pllfracn / (float_t)0x2000U));
2160
2161 return (uint32_t)frequency;
2162 }
2163
2164 /**
2165 * @brief Compute PLL2 VCO output frequency
2166 * @retval Value of PLL2 VCO output frequency
2167 */
RCC_PLL2_GetVCOOutputFreq(void)2168 static uint32_t RCC_PLL2_GetVCOOutputFreq(void)
2169 {
2170 uint32_t tmpreg1;
2171 uint32_t tmpreg2;
2172 uint32_t pllsrc;
2173 uint32_t pllm;
2174 uint32_t plln;
2175 uint32_t pllfracn;
2176 float_t frequency;
2177
2178 /* Get PLL2 CFGR and DIVR register values */
2179 tmpreg1 = RCC->PLLCKSELR;
2180 tmpreg2 = RCC->PLL2DIVR1;
2181
2182 /* Retrieve PLL2 multiplication factor and divider */
2183 pllm = (tmpreg1 & RCC_PLLCKSELR_DIVM2) >> RCC_PLLCKSELR_DIVM2_Pos;
2184 plln = (tmpreg2 & RCC_PLL2DIVR1_DIVN) + 1U;
2185
2186 if (pllm == 0U)
2187 {
2188 /* Prescaler disabled */
2189 return 0U;
2190 }
2191
2192 /* Check if fractional part is enable */
2193 if ((tmpreg1 & RCC_PLLCFGR_PLL2FRACEN) != 0U)
2194 {
2195 pllfracn = (RCC->PLL2FRACR & RCC_PLL2FRACR_FRACN) >> RCC_PLL2FRACR_FRACN_Pos;
2196 }
2197 else
2198 {
2199 pllfracn = 0U;
2200 }
2201
2202 /* determine PLL source */
2203 switch (tmpreg1 & RCC_PLLCKSELR_PLLSRC)
2204 {
2205 /* HSI used as PLL2 clock source */
2206 case RCC_PLLSOURCE_HSI:
2207 if (READ_BIT(RCC->CR, RCC_CR_HSIDIVF) != 0U)
2208 {
2209 pllsrc = HSI_VALUE >> ((RCC->CR & RCC_CR_HSIDIV) >> RCC_CR_HSIDIV_Pos);
2210 }
2211 else
2212 {
2213 /* Can't retrieve HSIDIV value */
2214 pllsrc = 0U;
2215 }
2216 break;
2217
2218 /* HSE used as PLL2 clock source */
2219 case RCC_PLLSOURCE_HSE:
2220 pllsrc = HSE_VALUE;
2221 break;
2222
2223 /* CSI used as PLL2 clock source */
2224 case RCC_PLLSOURCE_CSI:
2225 pllsrc = CSI_VALUE;
2226 break;
2227
2228 default:
2229 pllsrc = 0U;
2230 break;
2231 }
2232
2233 /* Compute VCO output frequency */
2234 frequency = ((float_t)pllsrc / (float_t)pllm) * ((float_t)plln + ((float_t)pllfracn / (float_t)0x2000U));
2235
2236 return (uint32_t)frequency;
2237 }
2238
2239 /**
2240 * @brief Compute PLL3 VCO output frequency
2241 * @retval Value of PLL3 VCO output frequency
2242 */
RCC_PLL3_GetVCOOutputFreq(void)2243 static uint32_t RCC_PLL3_GetVCOOutputFreq(void)
2244 {
2245 uint32_t tmpreg1;
2246 uint32_t tmpreg2;
2247 uint32_t pllsrc;
2248 uint32_t pllm;
2249 uint32_t plln;
2250 uint32_t pllfracn;
2251 float_t frequency;
2252
2253 /* Get PLL3 CFGR and DIVR register values */
2254 tmpreg1 = RCC->PLLCKSELR;
2255 tmpreg2 = RCC->PLL3DIVR1;
2256
2257 /* Retrieve PLL3 multiplication factor and divider */
2258 pllm = (tmpreg1 & RCC_PLLCKSELR_DIVM3) >> RCC_PLLCKSELR_DIVM3_Pos;
2259 plln = (tmpreg2 & RCC_PLL3DIVR1_DIVN) + 1U;
2260
2261 if (pllm == 0U)
2262 {
2263 /* Prescaler disabled */
2264 return 0U;
2265 }
2266
2267 /* Check if fractional part is enable */
2268 if ((tmpreg1 & RCC_PLLCFGR_PLL3FRACEN) != 0U)
2269 {
2270 pllfracn = (RCC->PLL3FRACR & RCC_PLL3FRACR_FRACN) >> RCC_PLL3FRACR_FRACN_Pos;
2271 }
2272 else
2273 {
2274 pllfracn = 0U;
2275 }
2276
2277 /* determine PLL source */
2278 switch (tmpreg1 & RCC_PLLCKSELR_PLLSRC)
2279 {
2280 /* HSI used as PLL3 clock source */
2281 case RCC_PLLSOURCE_HSI:
2282 if (READ_BIT(RCC->CR, RCC_CR_HSIDIVF) != 0U)
2283 {
2284 pllsrc = HSI_VALUE >> ((RCC->CR & RCC_CR_HSIDIV) >> RCC_CR_HSIDIV_Pos);
2285 }
2286 else
2287 {
2288 /* Can't retrieve HSIDIV value */
2289 pllsrc = 0U;
2290 }
2291 break;
2292
2293 /* HSE used as PLL3 clock source */
2294 case RCC_PLLSOURCE_HSE:
2295 pllsrc = HSE_VALUE;
2296 break;
2297
2298 /* CSI used as PLL3 clock source */
2299 case RCC_PLLSOURCE_CSI:
2300 pllsrc = CSI_VALUE;
2301 break;
2302
2303 default:
2304 pllsrc = 0U;
2305 break;
2306 }
2307
2308 /* Compute VCO output frequency */
2309 frequency = ((float_t)pllsrc / (float_t)pllm) * ((float_t)plln + ((float_t)pllfracn / (float_t)0x2000U));
2310
2311 return (uint32_t)frequency;
2312 }
2313
2314 /**
2315 * @}
2316 */
2317
2318 /**
2319 * @}
2320 */
2321 #endif /* HAL_RCC_MODULE_ENABLED */
2322
2323 /**
2324 * @}
2325 */
2326
2327 /**
2328 * @}
2329 */
2330