1 /**
2 ******************************************************************************
3 * @file stm32h5xx_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 High Speed Internal oscillator
28 (64 MHz) with Flash 3 wait states. Flash prefetch buffer, D-Cache
29 and I-Cache are disabled, and all peripherals are off except internal
30 SRAM, Flash and JTAG.
31
32 (+) There is no prescaler on High speed (AHBs) and Low speed (APBs) busses:
33 all peripherals mapped on these busses are running at HSI speed.
34 (+) The clock for all peripherals is switched off, except the SRAM and FLASH.
35 (+) All GPIOs are in analog mode, except the JTAG pins which
36 are assigned to be used for debug purpose.
37
38 [..]
39 Once the device started from reset, the user application has to:
40 (+) Configure the clock source to be used to drive the System clock
41 (if the application needs higher frequency/performance)
42 (+) Configure the System clock frequency and Flash settings
43 (+) Configure the AHB and APB busses prescalers
44 (+) Enable the clock for the peripheral(s) to be used
45 (+) Configure the clock source(s) for peripherals which clocks are not
46 derived from the System clock (SAIx, RTC, ADC, USB, SDMMC, etc.)
47
48 @endverbatim
49 */
50
51 /* Includes ------------------------------------------------------------------*/
52 #include "stm32h5xx_hal.h"
53
54 /** @addtogroup STM32H5xx_HAL_Driver
55 * @{
56 */
57
58 /** @defgroup RCC RCC
59 * @brief RCC HAL module driver
60 * @{
61 */
62
63 #ifdef HAL_RCC_MODULE_ENABLED
64
65 /* Private typedef -----------------------------------------------------------*/
66 /* Private define ------------------------------------------------------------*/
67 /* Private macro -------------------------------------------------------------*/
68 /** @defgroup RCC_Private_Macros RCC Private Macros
69 * @{
70 */
71
72 #define MCO1_CLK_ENABLE() __HAL_RCC_GPIOA_CLK_ENABLE()
73 #define MCO1_GPIO_PORT GPIOA
74 #define MCO1_PIN GPIO_PIN_8
75
76 #define MCO2_CLK_ENABLE() __HAL_RCC_GPIOC_CLK_ENABLE()
77 #define MCO2_GPIO_PORT GPIOC
78 #define MCO2_PIN GPIO_PIN_9
79
80 /**
81 * @}
82 */
83
84 /* Private variables ---------------------------------------------------------*/
85
86 /* Private function prototypes -----------------------------------------------*/
87 /* Exported functions --------------------------------------------------------*/
88
89 /** @defgroup RCC_Exported_Functions RCC Exported Functions
90 * @{
91 */
92
93 /** @defgroup RCC_Exported_Functions_Group1 Initialization and de-initialization functions
94 * @brief Initialization and Configuration functions
95 *
96 @verbatim
97 ===============================================================================
98 ##### Initialization and de-initialization functions #####
99 ===============================================================================
100 [..]
101 This section provides functions allowing to configure the internal and external oscillators
102 (HSE, HSI, LSE, CSI, LSI, PLL1, HSE CSS and MCOs) and the System busses clocks (SYSCLK, AHB, APB1, APB2
103 and APB3).
104
105 [..] Internal/external clock and PLL configuration
106 (+) HSI (high-speed internal): 64 MHz factory-trimmed RC used directly or through
107 the PLL as System clock source.
108
109 (#) CSI is a low-power RC oscillator which can be used directly as system clock, peripheral
110 clock, or PLL input. But even with frequency calibration, is less accurate than an
111 external crystal oscillator or ceramic resonator.
112
113 (+) LSI (low-speed internal): 32 KHz low consumption RC used as IWDG and/or RTC
114 clock source.
115
116 (+) HSE (high-speed external): 4 to 48 MHz crystal oscillator used directly or
117 through the PLL as System clock source. Can be used also optionally as RTC clock source.
118
119 (+) LSE (low-speed external): 32.768 KHz oscillator used optionally as RTC clock source.
120
121 (+) PLL1 (clocked by HSI, HSE or CSI) providing up to three independent output clocks:
122 (++) The first output is used to generate the high speed system clock (up to 240MHz).
123 (++) The second output is used to generate the clock for the USB (48 MHz), the FDCAN1/2,
124 the SPI1/2/3, the OCTOSPI, the RNG (<=48 MHz), the SDMMC1/2 and to generate an accurate
125 clock to achieve high-quality audio performance on SAI1/2 interface.
126
127 (+) PLL2 (clocked by HSI, HSE or CSI) providing up to three independent output clocks:
128 (++) The first output is used to generate the clock for the LPTIMs, the SPI1/2/3 and to generate
129 an accurate clock to achieve high-quality audio performance on SAI1/2 interface.
130 (++) The second output is used to generate the clock for USARTs, the UARTs, the LPUART1,
131 the FDCAN1/2, the SPI4/5/6 and the USB.
132 (++) The third output is used to generate the clock the SDMMC1/2, the ADC/DAC, the I2C1/2,
133 the I3C1/2 and the OCTOSPI.
134
135 (+) PLL3 (clocked by HSI , HSE or CSI) providing up to three independent output clocks:
136 (++) The first output is used to generate the clock for SPI1/2/3 and to generate an accurate
137 clock to achieve high-quality audio performance on SAI1/2 interface.
138 (++) The second output is used to generate the clock for USARTs, the UARTs, the LPUART1,
139 the SPI4/5/6 and the USB.
140 (++) The third output is used to generate the clock for the I2Cs, the I3Cs and the LPTIMs.
141
142 (+) HSE CSS (HSE Clock Security System): once enabled, if a HSE clock failure occurs
143 (HSE used directly or through PLL1 as System clock source), the System clock
144 is automatically switched to HSI and an interrupt is generated if enabled.
145 The interrupt is linked to the Cortex-M33 NMI (Non-Maskable Interrupt)
146 exception vector.
147
148 (#) MCO1 (micro controller clock output1), used to output HSI, LSE, HSE, PLL1(PLL1_Q)
149 or HSI48 clock (through a configurable pre-scaler) on PA8 pin.
150
151 (#) MCO2 (micro controller clock output2), used to output HSE, PLL2(PLL2_P), SYSCLK,
152 LSI, CSI, or PLL1(PLL1_P) clock (through a configurable pre-scaler) on PC9 pin.
153
154 [..] System, AHB and APB busses clocks configuration
155 (+) Several clock sources can be used to drive the System clock (SYSCLK): CSI, HSI, HSE and the main PLL.
156 The AHB clock (HCLK) is derived from System clock through configurable
157 prescaler and used to clock the CPU, memory and peripherals mapped
158 on AHB bus (DMA, GPIO...). APB1 (PCLK1), APB2 (PCLK2) and APB3 (PCLK3) clocks are derived
159 from AHB clock through configurable prescalers and used to clock
160 the peripherals mapped on these busses. You can use
161 "HAL_RCC_GetSysClockFreq()" function to retrieve the frequencies of these clocks.
162
163 -@- All the peripheral clocks are derived from the System clock (SYSCLK) except:
164
165 (+@) SAI: the SAI clock can be derived either from specific PLL (PLL1, PLL2 or PLL3),
166 the per_ck clock (HSE, HSI or CSI) or from an external clock mapped on the SAI_CKIN pin.
167 You have to use HAL_RCCEx_PeriphCLKConfig() function to configure this clock.
168 (+@) SPI/I2S: the SPI1/2/3 clock can be derived either from specific PLL (PLL1, PLL2 or PLL3),
169 the per_ck clock (HSE, HSI or CSI) or from an external clock mapped on the SPI_CKIN pin.
170 You have to use HAL_RCCEx_PeriphCLKConfig() function to configure this clock.
171 (+@) RTC: the RTC clock can be derived either from the LSI, LSE or HSE clock
172 divided by 2 to 31.
173 You have to use __HAL_RCC_RTC_ENABLE() and HAL_RCCEx_PeriphCLKConfig() function
174 to configure this clock.
175 (+@) USB: USB requires a frequency equal to 48 MHz to work correctly. This clock is derived
176 of the main PLL or PLL2 through PLLQ divider. You have to use HAL_RCCEx_PeriphCLKConfig()
177 function to configure this clock.
178 (+@) UCPD: the UCPD clock is derived from HSI (divided by 4) clock.
179 (+@) SDMMC: SDMMC1/2 peripherals require a frequency equal or lower than 48 MHz.
180 This clock is derived from the PLL1 or PLL2 through PLL1Q or PLL2R divider. You have
181 to use HAL_RCCEx_PeriphCLKConfig() function to configure this clock.
182 (+@) IWDG clock which is always the LSI clock. You have to use HAL_RCCEx_PeriphCLKConfig()
183 function to configure this clock.
184 (+@) RNG: the RNG clock can be derived either from PLL1Q, HSI48, LSE or LSI clock. You have
185 to use HAL_RCCEx_PeriphCLKConfig() function to configure this clock.
186 (+@) DAC: the DAC clock can be derived either from LSE or LSI clock. You have
187 to use HAL_RCCEx_PeriphCLKConfig() function to configure this clock.
188 (+@) FDCAN: the FDCAN1/2 clock can be derived either from HSE, PLL1Q or PLL2Q clock. You have
189 to use HAL_RCCEx_PeriphCLKConfig() function to configure this clock.
190 (+@) CEC: the CEC clock can be derived either from LSE, LSI or CSI (divided by 122) clock.You have
191 to use HAL_RCCEx_PeriphCLKConfig() function to configure this clock.
192 (+@) ETH: the Ethernet clock is derived from PLL1Q clock.
193
194
195
196 (+) The maximum frequency of the SYSCLK, HCLK, PCLK1, PCLK2 and PCLK3 is 240 MHz.
197 The clock source frequency should be adapted depending on the device voltage range
198 as listed in the Reference Manual "Clock source frequency versus voltage scaling" chapter.
199
200 @endverbatim
201
202
203 Table 1. HCLK clock frequency for STM32H5xx devices
204 +-----------------------------------------------------------------------------------------------+
205 | Latency | HCLK clock frequency (MHz) |
206 | |-----------------------------------------------------------------------------|
207 | | voltage range 0 | voltage range 1 | voltage range 2 | voltage range 3 |
208 | | 1.26 - 1.35V | 1.15 - 1.26V | 1.05 - 1.15V | 0,95 - 1,05V |
209 |-----------------|-------------------|------------------|------------------|-------------------|
210 |0WS(1 CPU cycles)| 0 < HCLK <= 38 | 0 < HCLK <= 32 | 0 < HCLK <= 26 | 0 < HCLK <= 16 |
211 |-----------------|-------------------|------------------|------------------|-------------------|
212 |1WS(2 CPU cycles)| 38 < HCLK <= 76 | 32 < HCLK <= 64 | 26 < HCLK <= 50 | 16 < HCLK <= 32 |
213 |-----------------|-------------------|------------------|------------------|-------------------|
214 |2WS(3 CPU cycles)| 76 < HCLK <= 114 | 64 < HCLK <= 96 | 50 < HCLK <= 80 | 32 < HCLK <= 50 |
215 |-----------------|-------------------|------------------|------------------|-------------------|
216 |3WS(4 CPU cycles)| 114 < HCLK <= 152 | 96 < HCLK <= 128 | 80 < HCLK <= 106 | 50 < HCLK <= 65 |
217 |-----------------|-------------------|------------------|------------------|-------------------|
218 |4WS(5 CPU cycles)| 152 < HCLK <= 190| 128 < HCLK <= 160| 106 < HCLK <= 130| 65 < HCLK <= 80 |
219 |-----------------|-------------------|------------------|------------------|-------------------|
220 |5WS(6 CPU cycles)| 190 < HCLK <= 240| 160 < HCLK <= 180| NA | NA |
221 +-----------------+-------------------+------------------+------------------+-------------------+
222 * @{
223 */
224
225 /**
226 * @brief Reset the RCC clock configuration to the default reset state.
227 * @note The default reset state of the clock configuration is given below:
228 * - HSI ON and used as system clock source
229 * - HSE, CSI, PLL, PLL2 and PLL3 OFF
230 * - AHB, APB1 and APB2 prescaler set to 1.
231 * - HSECSS, MCO1 and MCO2 OFF
232 * - All interrupts disabled
233 * @note This function doesn't modify the configuration of the
234 * - Peripheral clocks
235 * - LSI, LSE and RTC clocks
236 * @retval HAL Status.
237 */
238
HAL_RCC_DeInit(void)239 HAL_StatusTypeDef HAL_RCC_DeInit(void)
240 {
241 uint32_t tickstart;
242
243 /* Increasing the CPU frequency */
244 if (FLASH_LATENCY_DEFAULT > __HAL_FLASH_GET_LATENCY())
245 {
246 /* Program the new number of wait states to the LATENCY bits in the FLASH_ACR register */
247 __HAL_FLASH_SET_LATENCY(FLASH_LATENCY_DEFAULT);
248
249 /* Check that the new number of wait states is taken into account to access the Flash
250 memory by reading the FLASH_ACR register */
251 if (__HAL_FLASH_GET_LATENCY() != FLASH_LATENCY_DEFAULT)
252 {
253 return HAL_ERROR;
254 }
255
256 }
257
258 /* Get start tick*/
259 tickstart = HAL_GetTick();
260
261 /* Set HSION bit */
262 SET_BIT(RCC->CR, RCC_CR_HSION);
263
264 /* Wait till HSI is ready */
265 while (READ_BIT(RCC->CR, RCC_CR_HSIRDY) == 0U)
266 {
267 if ((HAL_GetTick() - tickstart) > HSI_TIMEOUT_VALUE)
268 {
269 return HAL_TIMEOUT;
270 }
271 }
272
273 /* Set HSIDIV Default value */
274 CLEAR_BIT(RCC->CR, RCC_CR_HSIDIV);
275
276 /* Set HSITRIM default value */
277 WRITE_REG(RCC->HSICFGR, RCC_HSICFGR_HSITRIM_6);
278
279
280 /* Adapt Systick interrupt period */
281 if (HAL_InitTick(uwTickPrio) != HAL_OK)
282 {
283 return HAL_ERROR;
284 }
285
286 /* Get start tick*/
287 tickstart = HAL_GetTick();
288
289 /* Reset CFGR register (HSI is selected as system clock source) */
290 CLEAR_REG(RCC->CFGR1);
291 CLEAR_REG(RCC->CFGR2);
292
293 /* Wait till clock switch is ready */
294 while (READ_BIT(RCC->CFGR1, RCC_CFGR1_SWS) != 0U)
295 {
296 if ((HAL_GetTick() - tickstart) > CLOCKSWITCH_TIMEOUT_VALUE)
297 {
298 return HAL_TIMEOUT;
299 }
300 }
301
302 /* Reset HSECSSON, HSEON, HSIKERON, CSION, CSIKERON and HSI48ON bits */
303 CLEAR_BIT(RCC->CR, RCC_CR_CSION | RCC_CR_CSIKERON | RCC_CR_HSECSSON | RCC_CR_HSIKERON | RCC_CR_HSI48ON | \
304 RCC_CR_HSEON);
305
306 /* Reset HSEEXT bit*/
307 CLEAR_BIT(RCC->CR, RCC_CR_HSEEXT);
308
309 /* Get Start Tick */
310 tickstart = HAL_GetTick();
311
312 /* Clear PLL1ON bit */
313 CLEAR_BIT(RCC->CR, RCC_CR_PLL1ON);
314
315 /* Wait till PLL1 is disabled */
316 while (READ_BIT(RCC->CR, RCC_CR_PLL1RDY) != 0U)
317 {
318 if ((HAL_GetTick() - tickstart) > PLL_TIMEOUT_VALUE)
319 {
320 return HAL_TIMEOUT;
321 }
322 }
323
324 /* Get Start Tick */
325 tickstart = HAL_GetTick();
326
327 /* Reset PLL2N bit */
328 CLEAR_BIT(RCC->CR, RCC_CR_PLL2ON);
329
330 /* Wait till PLL2 is disabled */
331 while (READ_BIT(RCC->CR, RCC_CR_PLL2RDY) != 0U)
332 {
333 if ((HAL_GetTick() - tickstart) > PLL_TIMEOUT_VALUE)
334 {
335 return HAL_TIMEOUT;
336 }
337 }
338
339 #if defined(RCC_CR_PLL3ON)
340
341 /* Get Start Tick */
342 tickstart = HAL_GetTick();
343
344 /* Reset PLL3 bit */
345 CLEAR_BIT(RCC->CR, RCC_CR_PLL3ON);
346
347 /* Wait till PLL3 is disabled */
348 while (READ_BIT(RCC->CR, RCC_CR_PLL3RDY) != 0U)
349 {
350 if ((HAL_GetTick() - tickstart) > PLL_TIMEOUT_VALUE)
351 {
352 return HAL_TIMEOUT;
353 }
354 }
355 #endif /* RCC_CR_PLL3ON */
356
357 /* Reset PLL1CFGR register */
358 CLEAR_REG(RCC->PLL1CFGR);
359
360 /* Reset PLL1DIVR register */
361 WRITE_REG(RCC->PLL1DIVR, 0x01010280U);
362
363 /* Reset PLL1FRACR register */
364 CLEAR_REG(RCC->PLL1FRACR);
365
366 /* Reset PLL2CFGR register */
367 CLEAR_REG(RCC->PLL2CFGR);
368
369 /* Reset PLL2DIVR register */
370 WRITE_REG(RCC->PLL2DIVR, 0x01010280U);
371
372 /* Reset PLL2FRACR register */
373 CLEAR_REG(RCC->PLL2FRACR);
374
375 #if defined(RCC_CR_PLL3ON)
376 /* Reset PLL3CFGR register */
377 CLEAR_REG(RCC->PLL3CFGR);
378
379 /* Reset PLL3DIVR register */
380 WRITE_REG(RCC->PLL3DIVR, 0x01010280U);
381
382 /* Reset PLL3FRACR register */
383 CLEAR_REG(RCC->PLL3FRACR);
384 #endif /* RCC_CR_PLL3ON */
385
386 /* Reset HSEBYP bit */
387 CLEAR_BIT(RCC->CR, RCC_CR_HSEBYP);
388
389 /* Disable all interrupts */
390 CLEAR_REG(RCC->CIER);
391
392 /* Clear all interrupts flags */
393 WRITE_REG(RCC->CICR, 0xFFFFFFFFU);
394
395 /* Reset all RSR flags */
396 SET_BIT(RCC->RSR, RCC_RSR_RMVF);
397
398 /* Update the SystemCoreClock global variable */
399 SystemCoreClock = HSI_VALUE;
400
401 /* Decreasing the number of wait states because of lower CPU frequency */
402 if (FLASH_LATENCY_DEFAULT < __HAL_FLASH_GET_LATENCY())
403 {
404 /* Program the new number of wait states to the LATENCY bits in the FLASH_ACR register */
405 __HAL_FLASH_SET_LATENCY(FLASH_LATENCY_DEFAULT);
406
407 /* Check that the new number of wait states is taken into account to access the Flash
408 memory by reading the FLASH_ACR register */
409 if (__HAL_FLASH_GET_LATENCY() != FLASH_LATENCY_DEFAULT)
410 {
411 return HAL_ERROR;
412 }
413 }
414
415 /* Adapt Systick interrupt period */
416 if (HAL_InitTick(TICK_INT_PRIORITY) != HAL_OK)
417 {
418 return HAL_ERROR;
419 }
420 else
421 {
422 return HAL_OK;
423 }
424 }
425
426 /**
427 * @brief Initialize the RCC Oscillators according to the specified parameters in the
428 * RCC_OscInitTypeDef.
429 * @param pOscInitStruct pointer to an RCC_OscInitTypeDef structure that
430 * contains the configuration information for the RCC Oscillators.
431 * @note The PLL is not disabled when used as system clock.
432 * @note Transitions LSE Bypass to LSE On and LSE On to LSE Bypass are not
433 * supported by this macro. User should request a transition to LSE Off
434 * first and then LSE On or LSE Bypass.
435 * @note Transition HSE Bypass to HSE On and HSE On to HSE Bypass are not
436 * supported by this macro. User should request a transition to HSE Off
437 * first and then HSE On or HSE Bypass.
438 * @retval HAL status
439 */
HAL_RCC_OscConfig(RCC_OscInitTypeDef * pOscInitStruct)440 HAL_StatusTypeDef HAL_RCC_OscConfig(RCC_OscInitTypeDef *pOscInitStruct)
441 {
442 uint32_t tickstart;
443 uint32_t temp_sysclksrc;
444 uint32_t temp_pllckselr;
445 uint32_t temp1_pllckcfg;
446 uint32_t temp2_pllckcfg;
447
448 /* Check Null pointer */
449 if (pOscInitStruct == NULL)
450 {
451 return HAL_ERROR;
452 }
453
454 /* Check the parameters */
455 assert_param(IS_RCC_OSCILLATORTYPE(pOscInitStruct->OscillatorType));
456 temp_sysclksrc = __HAL_RCC_GET_SYSCLK_SOURCE();
457 temp_pllckselr = __HAL_RCC_GET_PLL_OSCSOURCE();
458
459 /*----------------------------- CSI Configuration --------------------------*/
460 if (((pOscInitStruct->OscillatorType) & RCC_OSCILLATORTYPE_CSI) == RCC_OSCILLATORTYPE_CSI)
461 {
462 /* Check the parameters */
463 assert_param(IS_RCC_CSI(pOscInitStruct->CSIState));
464 assert_param(IS_RCC_CSICALIBRATION_VALUE(pOscInitStruct->CSICalibrationValue));
465
466 /* When the CSI is used as system clock it will not be disabled */
467 if ((temp_sysclksrc == RCC_SYSCLKSOURCE_STATUS_CSI) ||
468 ((temp_sysclksrc == RCC_SYSCLKSOURCE_STATUS_PLLCLK) && (temp_pllckselr == RCC_PLL1_SOURCE_CSI)))
469 {
470 if (pOscInitStruct->CSIState == RCC_CSI_OFF)
471 {
472 return HAL_ERROR;
473 }
474
475 /* Otherwise, just the calibration and CSI is allowed */
476 else
477 {
478 /* Adjusts the Internal Low-power oscillator (CSI) calibration value.*/
479 __HAL_RCC_CSI_CALIBRATIONVALUE_ADJUST(pOscInitStruct->CSICalibrationValue);
480 }
481 }
482 else
483 {
484 /* Check the CSI State */
485 if ((pOscInitStruct->CSIState) != RCC_CSI_OFF)
486 {
487 /* Enable the Internal High Speed oscillator (CSI). */
488 __HAL_RCC_CSI_ENABLE();
489
490 /* Get Start Tick*/
491 tickstart = HAL_GetTick();
492
493 /* Wait till CSI is ready */
494 while (READ_BIT(RCC->CR, RCC_CR_CSIRDY) == 0U)
495 {
496 if ((HAL_GetTick() - tickstart) > CSI_TIMEOUT_VALUE)
497 {
498 return HAL_TIMEOUT;
499 }
500 }
501
502 /* Adjusts the Internal High Speed oscillator (CSI) calibration value.*/
503 __HAL_RCC_CSI_CALIBRATIONVALUE_ADJUST(pOscInitStruct->CSICalibrationValue);
504 }
505 else
506 {
507 /* Disable the Internal High Speed oscillator (CSI). */
508 __HAL_RCC_CSI_DISABLE();
509
510 /* Get Start Tick*/
511 tickstart = HAL_GetTick();
512
513 /* Wait till CSI is disabled */
514 while (READ_BIT(RCC->CR, RCC_CR_CSIRDY) != 0U)
515 {
516 if ((HAL_GetTick() - tickstart) > CSI_TIMEOUT_VALUE)
517 {
518 return HAL_TIMEOUT;
519 }
520 }
521 }
522 }
523 }
524 /*------------------------------- HSE Configuration ------------------------*/
525 if (((pOscInitStruct->OscillatorType) & RCC_OSCILLATORTYPE_HSE) == RCC_OSCILLATORTYPE_HSE)
526 {
527 /* Check the parameters */
528 assert_param(IS_RCC_HSE(pOscInitStruct->HSEState));
529
530 /* When the HSE is used as system clock or clock source for PLL in these cases it is not allowed to be disabled */
531 if ((temp_sysclksrc == RCC_SYSCLKSOURCE_STATUS_HSE) ||
532 ((temp_sysclksrc == RCC_SYSCLKSOURCE_STATUS_PLLCLK) && (temp_pllckselr == RCC_PLL1_SOURCE_HSE)))
533 {
534 if (pOscInitStruct->HSEState == RCC_HSE_OFF)
535 {
536 return HAL_ERROR;
537 }
538 }
539 else
540 {
541 /* Set the new HSE configuration ---------------------------------------*/
542 __HAL_RCC_HSE_CONFIG(pOscInitStruct->HSEState);
543
544 /* Check the HSE State */
545 if (pOscInitStruct->HSEState != RCC_HSE_OFF)
546 {
547 /* Get Start Tick*/
548 tickstart = HAL_GetTick();
549
550 /* Wait till HSE is ready */
551 while (READ_BIT(RCC->CR, RCC_CR_HSERDY) == 0U)
552 {
553 if ((HAL_GetTick() - tickstart) > HSE_TIMEOUT_VALUE)
554 {
555 return HAL_TIMEOUT;
556 }
557 }
558 }
559 else
560 {
561 /* Get Start Tick*/
562 tickstart = HAL_GetTick();
563
564 /* Wait till HSE is disabled */
565 while (READ_BIT(RCC->CR, RCC_CR_HSERDY) != 0U)
566 {
567 if ((HAL_GetTick() - tickstart) > HSE_TIMEOUT_VALUE)
568 {
569 return HAL_TIMEOUT;
570 }
571 }
572 }
573 }
574 }
575 /*----------------------------- HSI Configuration --------------------------*/
576 if (((pOscInitStruct->OscillatorType) & RCC_OSCILLATORTYPE_HSI) == RCC_OSCILLATORTYPE_HSI)
577 {
578 /* Check the parameters */
579 assert_param(IS_RCC_HSI(pOscInitStruct->HSIState));
580 assert_param(IS_RCC_HSIDIV(pOscInitStruct->HSIDiv));
581 assert_param(IS_RCC_HSI_CALIBRATION_VALUE(pOscInitStruct->HSICalibrationValue));
582
583 /* Check if HSI is used as system clock or as PLL source when PLL is selected as system clock */
584 if ((temp_sysclksrc == RCC_SYSCLKSOURCE_STATUS_HSI) ||
585 ((temp_sysclksrc == RCC_SYSCLKSOURCE_STATUS_PLLCLK) && (temp_pllckselr == RCC_PLL1_SOURCE_HSI)))
586 {
587 /* When HSI is used as system clock it will not be disabled */
588 if (pOscInitStruct->HSIState == RCC_HSI_OFF)
589 {
590 return HAL_ERROR;
591 }
592 /* Otherwise, HSI calibration and division may be allowed */
593 else
594 {
595
596 /* HSI division is allowed if HSI is used as system clock */
597 if (temp_sysclksrc == RCC_SYSCLKSOURCE_STATUS_HSI)
598 {
599 if (__HAL_RCC_GET_HSI_DIVIDER() != (pOscInitStruct->HSIDiv))
600 {
601 /* Adjust the HSI division factor */
602 __HAL_RCC_HSI_DIVIDER_CONFIG(pOscInitStruct->HSIDiv);
603
604 /* Update the SystemCoreClock global variable with new HSI value */
605 (void) HAL_RCC_GetHCLKFreq();
606
607 /* Configure the source of time base considering new system clocks settings*/
608 if (HAL_InitTick(uwTickPrio) != HAL_OK)
609 {
610 return HAL_ERROR;
611 }
612 }
613 }
614
615 /* Get Start Tick*/
616 tickstart = HAL_GetTick();
617
618 /* Wait till HSI is ready */
619 while (READ_BIT(RCC->CR, RCC_CR_HSIRDY) == 0U)
620 {
621 if ((HAL_GetTick() - tickstart) > HSI_TIMEOUT_VALUE)
622 {
623 return HAL_TIMEOUT;
624 }
625 }
626 /* Adjusts the Internal High Speed oscillator (HSI) calibration value.*/
627 __HAL_RCC_HSI_CALIBRATIONVALUE_ADJUST(pOscInitStruct->HSICalibrationValue);
628 }
629 }
630 else
631 {
632 /* Check the HSI State */
633 if (pOscInitStruct->HSIState != RCC_HSI_OFF)
634 {
635 /* Adjust the HSI division factor */
636 __HAL_RCC_HSI_DIVIDER_CONFIG(pOscInitStruct->HSIDiv);
637
638 /* Enable the HSI oscillator */
639 __HAL_RCC_HSI_ENABLE();
640
641 /* Get Start Tick*/
642 tickstart = HAL_GetTick();
643
644 /* Wait till HSI is ready */
645 while (READ_BIT(RCC->CR, RCC_CR_HSIRDY) == 0U)
646 {
647 if ((HAL_GetTick() - tickstart) > HSI_TIMEOUT_VALUE)
648 {
649 return HAL_TIMEOUT;
650 }
651 }
652
653 /* Adjust the Internal High Speed oscillator (HSI) calibration value.*/
654 __HAL_RCC_HSI_CALIBRATIONVALUE_ADJUST(pOscInitStruct->HSICalibrationValue);
655 }
656 else
657 {
658 /* Disable the Internal High Speed oscillator (HSI). */
659 __HAL_RCC_HSI_DISABLE();
660
661 /* Get Start Tick*/
662 tickstart = HAL_GetTick();
663
664 /* Wait till HSI is disabled */
665 while (READ_BIT(RCC->CR, RCC_CR_HSIRDY) != 0U)
666 {
667 if ((HAL_GetTick() - tickstart) > HSI_TIMEOUT_VALUE)
668 {
669 return HAL_TIMEOUT;
670 }
671 }
672 }
673 }
674 }
675 /*------------------------------ LSI Configuration -------------------------*/
676 if (((pOscInitStruct->OscillatorType) & RCC_OSCILLATORTYPE_LSI) == RCC_OSCILLATORTYPE_LSI)
677 {
678
679 /* Check the parameters */
680 assert_param(IS_RCC_LSI(pOscInitStruct->LSIState));
681
682 /* Update LSI configuration in Backup Domain control register */
683
684 /* Check the LSI State */
685 if (pOscInitStruct->LSIState != RCC_LSI_OFF)
686 {
687 /* Enable the Internal Low Speed oscillator (LSI). */
688 __HAL_RCC_LSI_ENABLE();
689
690 /* Get Start Tick*/
691 tickstart = HAL_GetTick();
692
693 /* Wait till LSI is ready */
694 while (READ_BIT(RCC->BDCR, RCC_BDCR_LSIRDY) == 0U)
695 {
696 if ((HAL_GetTick() - tickstart) > LSI_TIMEOUT_VALUE)
697 {
698 return HAL_TIMEOUT;
699 }
700 }
701 }
702 else
703 {
704 /* Disable the Internal Low Speed oscillator (LSI). */
705 __HAL_RCC_LSI_DISABLE();
706
707 /* Get Start Tick*/
708 tickstart = HAL_GetTick();
709
710 /* Wait till LSI is disabled */
711 while (READ_BIT(RCC->BDCR, RCC_BDCR_LSIRDY) != 0U)
712 {
713 if ((HAL_GetTick() - tickstart) > LSI_TIMEOUT_VALUE)
714 {
715 return HAL_TIMEOUT;
716 }
717 }
718 }
719
720 }
721 /*------------------------------ LSE Configuration -------------------------*/
722 if (((pOscInitStruct->OscillatorType) & RCC_OSCILLATORTYPE_LSE) == RCC_OSCILLATORTYPE_LSE)
723 {
724
725 /* Check the parameters */
726 assert_param(IS_RCC_LSE(pOscInitStruct->LSEState));
727
728 /* Update LSE configuration in Backup Domain control register */
729 /* Requires to enable write access to Backup Domain */
730 if (HAL_IS_BIT_CLR(PWR->DBPCR, PWR_DBPCR_DBP))
731 {
732 /* Enable write access to Backup domain */
733 SET_BIT(PWR->DBPCR, PWR_DBPCR_DBP);
734
735 /* Wait for Backup domain Write protection disable */
736 tickstart = HAL_GetTick();
737
738 while (HAL_IS_BIT_CLR(PWR->DBPCR, PWR_DBPCR_DBP))
739 {
740 if ((HAL_GetTick() - tickstart) > RCC_DBP_TIMEOUT_VALUE)
741 {
742 return HAL_TIMEOUT;
743 }
744 }
745 }
746
747 /* Set the new LSE configuration -----------------------------------------*/
748 __HAL_RCC_LSE_CONFIG(pOscInitStruct->LSEState);
749
750 /* Check the LSE State */
751 if (pOscInitStruct->LSEState != RCC_LSE_OFF)
752 {
753 /* Get Start Tick*/
754 tickstart = HAL_GetTick();
755
756 /* Wait till LSE is ready */
757 while (READ_BIT(RCC->BDCR, RCC_BDCR_LSERDY) == 0U)
758 {
759 if ((HAL_GetTick() - tickstart) > RCC_LSE_TIMEOUT_VALUE)
760 {
761 return HAL_TIMEOUT;
762 }
763 }
764 }
765 else
766 {
767 /* Get Start Tick*/
768 tickstart = HAL_GetTick();
769
770 /* Wait till LSE is disabled */
771 while (READ_BIT(RCC->BDCR, RCC_BDCR_LSERDY) != 0U)
772 {
773 if ((HAL_GetTick() - tickstart) > RCC_LSE_TIMEOUT_VALUE)
774 {
775 return HAL_TIMEOUT;
776 }
777 }
778 }
779
780 }
781 /*------------------------------ HSI48 Configuration -----------------------*/
782 if (((pOscInitStruct->OscillatorType) & RCC_OSCILLATORTYPE_HSI48) == RCC_OSCILLATORTYPE_HSI48)
783 {
784 /* Check the parameters */
785 assert_param(IS_RCC_HSI48(pOscInitStruct->HSI48State));
786
787 /* Check the HSI48 State */
788 if (pOscInitStruct->HSI48State != RCC_HSI48_OFF)
789 {
790 /* Enable the Internal High Speed oscillator (HSI48). */
791 __HAL_RCC_HSI48_ENABLE();
792
793 /* Get Start Tick*/
794 tickstart = HAL_GetTick();
795
796 /* Wait till HSI48 is ready */
797 while (READ_BIT(RCC->CR, RCC_CR_HSI48RDY) == 0U)
798 {
799 if ((HAL_GetTick() - tickstart) > HSI48_TIMEOUT_VALUE)
800 {
801 return HAL_TIMEOUT;
802 }
803 }
804 }
805 else
806 {
807 /* Disable the Internal High Speed oscillator (HSI48). */
808 __HAL_RCC_HSI48_DISABLE();
809
810 /* Get Start Tick*/
811 tickstart = HAL_GetTick();
812
813 /* Wait till HSI48 is disabled */
814 while (READ_BIT(RCC->CR, RCC_CR_HSI48RDY) != 0U)
815 {
816 if ((HAL_GetTick() - tickstart) > HSI48_TIMEOUT_VALUE)
817 {
818 return HAL_TIMEOUT;
819 }
820 }
821 }
822 }
823
824 /*-------------------------------- PLL1 Configuration -----------------------*/
825 /* Check the parameters */
826 assert_param(IS_RCC_PLL(pOscInitStruct->PLL.PLLState));
827
828 if ((pOscInitStruct->PLL.PLLState) != RCC_PLL_NONE)
829 {
830 /* Check if the PLL1 is used as system clock or not */
831 if (temp_sysclksrc != RCC_SYSCLKSOURCE_STATUS_PLLCLK)
832 {
833 if ((pOscInitStruct->PLL.PLLState) == RCC_PLL_ON)
834 {
835 /* Check the parameters */
836 assert_param(IS_RCC_PLL1_SOURCE(pOscInitStruct->PLL.PLLSource));
837 assert_param(IS_RCC_PLL1_DIVM_VALUE(pOscInitStruct->PLL.PLLM));
838 assert_param(IS_RCC_PLL1_MULN_VALUE(pOscInitStruct->PLL.PLLN));
839 assert_param(IS_RCC_PLL1_DIVP_VALUE(pOscInitStruct->PLL.PLLP));
840 assert_param(IS_RCC_PLL1_DIVQ_VALUE(pOscInitStruct->PLL.PLLQ));
841 assert_param(IS_RCC_PLL1_DIVR_VALUE(pOscInitStruct->PLL.PLLR));
842
843 /* Disable the PLL1. */
844 __HAL_RCC_PLL1_DISABLE();
845
846 /* Get Start Tick*/
847 tickstart = HAL_GetTick();
848
849 /* Wait till PLL1 is disabled */
850 while (READ_BIT(RCC->CR, RCC_CR_PLL1RDY) != 0U)
851 {
852 if ((HAL_GetTick() - tickstart) > PLL_TIMEOUT_VALUE)
853 {
854 return HAL_TIMEOUT;
855 }
856 }
857
858 /* Configure the PLL1 clock source, multiplication and division factors. */
859 __HAL_RCC_PLL1_CONFIG(pOscInitStruct->PLL.PLLSource,
860 pOscInitStruct->PLL.PLLM,
861 pOscInitStruct->PLL.PLLN,
862 pOscInitStruct->PLL.PLLP,
863 pOscInitStruct->PLL.PLLQ,
864 pOscInitStruct->PLL.PLLR);
865
866 assert_param(IS_RCC_PLL1_FRACN_VALUE(pOscInitStruct->PLL.PLLFRACN));
867
868 /* Disable PLL1FRACN . */
869 __HAL_RCC_PLL1_FRACN_DISABLE();
870
871 /* Configure PLL PLL1FRACN */
872 __HAL_RCC_PLL1_FRACN_CONFIG(pOscInitStruct->PLL.PLLFRACN);
873
874 /* Enable PLL1FRACN . */
875 __HAL_RCC_PLL1_FRACN_ENABLE();
876
877 assert_param(IS_RCC_PLL1_VCIRGE_VALUE(pOscInitStruct->PLL.PLLRGE));
878
879 /* Select PLL1 input reference frequency range: VCI */
880 __HAL_RCC_PLL1_VCIRANGE(pOscInitStruct->PLL.PLLRGE) ;
881
882 assert_param(IS_RCC_PLL1_VCORGE_VALUE(pOscInitStruct->PLL.PLLVCOSEL));
883
884 /* Select PLL1 output frequency range : VCO */
885 __HAL_RCC_PLL1_VCORANGE(pOscInitStruct->PLL.PLLVCOSEL) ;
886
887 /* Enable PLL1 System Clock output. */
888 __HAL_RCC_PLL1_CLKOUT_ENABLE(RCC_PLL1_DIVP);
889
890 /* Enable the PLL1. */
891 __HAL_RCC_PLL1_ENABLE();
892
893 /* Get Start Tick*/
894 tickstart = HAL_GetTick();
895
896 /* Wait till PLL1 is ready */
897 while (READ_BIT(RCC->CR, RCC_CR_PLL1RDY) == 0U)
898 {
899 if ((HAL_GetTick() - tickstart) > PLL_TIMEOUT_VALUE)
900 {
901 return HAL_TIMEOUT;
902 }
903 }
904 }
905 else
906 {
907 /* Disable the PLL1. */
908 __HAL_RCC_PLL1_DISABLE();
909
910 /* Get Start Tick*/
911 tickstart = HAL_GetTick();
912
913 /* Wait till PLL1 is disabled */
914 while (READ_BIT(RCC->CR, RCC_CR_PLL1RDY) != 0U)
915 {
916 if ((HAL_GetTick() - tickstart) > PLL_TIMEOUT_VALUE)
917 {
918 return HAL_TIMEOUT;
919 }
920 }
921
922 /* Unselect PLL1 clock source and disable all PLL1 outputs to save power */
923 RCC->PLL1CFGR &= ~(RCC_PLL1CFGR_PLL1SRC | RCC_PLL1CFGR_PLL1PEN | RCC_PLL1CFGR_PLL1QEN | RCC_PLL1CFGR_PLL1REN);
924
925 }
926 }
927 else
928 {
929 /* Do not return HAL_ERROR if request repeats the current configuration */
930 temp1_pllckcfg = RCC->PLL1CFGR;
931 temp2_pllckcfg = RCC->PLL1DIVR;
932 if (((pOscInitStruct->PLL.PLLState) == RCC_PLL_OFF) ||
933 (READ_BIT(temp1_pllckcfg, RCC_PLL1CFGR_PLL1SRC) != pOscInitStruct->PLL.PLLSource) ||
934 ((READ_BIT(temp1_pllckcfg, RCC_PLL1CFGR_PLL1M) >> \
935 RCC_PLL1CFGR_PLL1M_Pos) != (pOscInitStruct->PLL.PLLM)) ||
936 (READ_BIT(temp2_pllckcfg, RCC_PLL1DIVR_PLL1N) != (pOscInitStruct->PLL.PLLN - 1U)) ||
937 ((READ_BIT(temp2_pllckcfg, RCC_PLL1DIVR_PLL1P) >> \
938 RCC_PLL1DIVR_PLL1P_Pos) != (pOscInitStruct->PLL.PLLP - 1U)) ||
939 ((READ_BIT(temp2_pllckcfg, RCC_PLL1DIVR_PLL1Q) >> \
940 RCC_PLL1DIVR_PLL1Q_Pos) != (pOscInitStruct->PLL.PLLQ - 1U)) ||
941 ((READ_BIT(temp2_pllckcfg, RCC_PLL1DIVR_PLL1R) >> \
942 RCC_PLL1DIVR_PLL1R_Pos) != (pOscInitStruct->PLL.PLLR - 1U)))
943 {
944 return HAL_ERROR;
945 }
946
947 /* FRACN1 on-the-fly value update */
948 if ((READ_BIT(RCC->PLL1FRACR, RCC_PLL1FRACR_PLL1FRACN) >> \
949 RCC_PLL1FRACR_PLL1FRACN_Pos) != (pOscInitStruct->PLL.PLLFRACN))
950 {
951 assert_param(IS_RCC_PLL1_FRACN_VALUE(pOscInitStruct->PLL.PLLFRACN));
952
953 /* Disable PLL1FRACN . */
954 __HAL_RCC_PLL1_FRACN_DISABLE();
955
956 /* Configure PLL PLL1FRACN */
957 __HAL_RCC_PLL1_FRACN_CONFIG(pOscInitStruct->PLL.PLLFRACN);
958
959 /* Enable PLL1FRACN . */
960 __HAL_RCC_PLL1_FRACN_ENABLE();
961 }
962
963 }
964 }
965 return HAL_OK;
966 }
967
968 /**
969 * @brief Initialize the CPU, AHB and APB busses clocks according to the specified
970 * parameters in the pClkInitStruct.
971 * @param pClkInitStruct pointer to an RCC_OscInitTypeDef structure that
972 * contains the configuration information for the RCC peripheral.
973 * @param FLatency FLASH Latency
974 * This parameter can be one of the following values:
975 * @arg FLASH_LATENCY_0 FLASH 0 Latency cycle
976 * @arg FLASH_LATENCY_1 FLASH 1 Latency cycle
977 * @arg FLASH_LATENCY_2 FLASH 2 Latency cycles
978 * @arg FLASH_LATENCY_3 FLASH 3 Latency cycles
979 * @arg FLASH_LATENCY_4 FLASH 4 Latency cycles
980 * @arg FLASH_LATENCY_5 FLASH 5 Latency cycles
981 *
982 * @note The SystemCoreClock CMSIS variable is used to store System Clock Frequency
983 * and updated by HAL_RCC_GetHCLKFreq() function called within this function
984 *
985 * @note The HSI is used by default as system clock source after
986 * startup from Reset, wake-up from STANDBY mode. After restart from Reset,
987 * the HSI frequency is set to its default value 64 MHz.
988 *
989 * @note The HSI or CSI can be selected as system clock source after wake-up
990 * from STOP modes or in case of failure of the HSE when used directly or indirectly
991 * as system clock (if the Clock Security System CSS is enabled).
992 *
993 * @note A switch from one clock source to another occurs only if the target
994 * clock source is ready (clock stable after startup delay or PLL locked).
995 * If a clock source which is not yet ready is selected, the switch will
996 * occur when the clock source is ready.
997 *
998 * @note You can use HAL_RCC_GetClockConfig() function to know which clock is
999 * currently used as system clock source.
1000 *
1001 * @retval HAL Status.
1002 */
HAL_RCC_ClockConfig(RCC_ClkInitTypeDef * pClkInitStruct,uint32_t FLatency)1003 HAL_StatusTypeDef HAL_RCC_ClockConfig(RCC_ClkInitTypeDef *pClkInitStruct, uint32_t FLatency)
1004 {
1005 HAL_StatusTypeDef halstatus;
1006 uint32_t tickstart;
1007
1008 /* Check Null pointer */
1009 if (pClkInitStruct == NULL)
1010 {
1011 return HAL_ERROR;
1012 }
1013
1014 /* Check the parameters */
1015 assert_param(IS_RCC_CLOCKTYPE(pClkInitStruct->ClockType));
1016 assert_param(IS_FLASH_LATENCY(FLatency));
1017
1018 /* To correctly read data from FLASH memory, the number of wait states (LATENCY)
1019 must be correctly programmed according to the frequency of the CPU clock
1020 (HCLK) and the supply voltage of the device. */
1021
1022 /* Increasing the number of wait states because of higher CPU frequency */
1023 if (FLatency > __HAL_FLASH_GET_LATENCY())
1024 {
1025 /* Program the new number of wait states to the LATENCY bits in the FLASH_ACR register */
1026 __HAL_FLASH_SET_LATENCY(FLatency);
1027
1028 /* Check that the new number of wait states is taken into account to access the Flash
1029 memory by reading the FLASH_ACR register */
1030 if (__HAL_FLASH_GET_LATENCY() != FLatency)
1031 {
1032 return HAL_ERROR;
1033 }
1034 }
1035
1036 /* Increasing the BUS frequency divider */
1037 /*-------------------------- PCLK3 Configuration ---------------------------*/
1038 if (((pClkInitStruct->ClockType) & RCC_CLOCKTYPE_PCLK3) == RCC_CLOCKTYPE_PCLK3)
1039 {
1040 if ((pClkInitStruct->APB3CLKDivider) > ((RCC->CFGR2 & RCC_CFGR2_PPRE3) >> 8))
1041 {
1042 assert_param(IS_RCC_PCLK(pClkInitStruct->APB3CLKDivider));
1043 MODIFY_REG(RCC->CFGR2, RCC_CFGR2_PPRE3, ((pClkInitStruct->APB3CLKDivider) << 8));
1044 }
1045 }
1046 /*-------------------------- PCLK2 Configuration ---------------------------*/
1047 if (((pClkInitStruct->ClockType) & RCC_CLOCKTYPE_PCLK2) == RCC_CLOCKTYPE_PCLK2)
1048 {
1049 if ((pClkInitStruct->APB2CLKDivider) > ((RCC->CFGR2 & RCC_CFGR2_PPRE2) >> 4))
1050 {
1051 assert_param(IS_RCC_PCLK(pClkInitStruct->APB2CLKDivider));
1052 MODIFY_REG(RCC->CFGR2, RCC_CFGR2_PPRE2, ((pClkInitStruct->APB2CLKDivider) << 4));
1053 }
1054 }
1055
1056 /*-------------------------- PCLK1 Configuration ---------------------------*/
1057 if (((pClkInitStruct->ClockType) & RCC_CLOCKTYPE_PCLK1) == RCC_CLOCKTYPE_PCLK1)
1058 {
1059 if ((pClkInitStruct->APB1CLKDivider) > (RCC->CFGR2 & RCC_CFGR2_PPRE1))
1060 {
1061 assert_param(IS_RCC_PCLK(pClkInitStruct->APB1CLKDivider));
1062 MODIFY_REG(RCC->CFGR2, RCC_CFGR2_PPRE1, pClkInitStruct->APB1CLKDivider);
1063 }
1064 }
1065
1066 /*-------------------------- HCLK Configuration --------------------------*/
1067 if (((pClkInitStruct->ClockType) & RCC_CLOCKTYPE_HCLK) == RCC_CLOCKTYPE_HCLK)
1068 {
1069 if ((pClkInitStruct->AHBCLKDivider) > (RCC->CFGR2 & RCC_CFGR2_HPRE))
1070 {
1071 assert_param(IS_RCC_HCLK(pClkInitStruct->AHBCLKDivider));
1072 MODIFY_REG(RCC->CFGR2, RCC_CFGR2_HPRE, pClkInitStruct->AHBCLKDivider);
1073 }
1074 }
1075
1076 /*------------------------- SYSCLK Configuration ---------------------------*/
1077 if (((pClkInitStruct->ClockType) & RCC_CLOCKTYPE_SYSCLK) == RCC_CLOCKTYPE_SYSCLK)
1078 {
1079 assert_param(IS_RCC_SYSCLKSOURCE(pClkInitStruct->SYSCLKSource));
1080
1081 /* PLL is selected as System Clock Source */
1082 if (pClkInitStruct->SYSCLKSource == RCC_SYSCLKSOURCE_PLLCLK)
1083 {
1084 /* Check the PLL ready flag */
1085 if (READ_BIT(RCC->CR, RCC_CR_PLL1RDY) == 0U)
1086 {
1087 return HAL_ERROR;
1088 }
1089 }
1090 else
1091 {
1092 /* HSE is selected as System Clock Source */
1093 if (pClkInitStruct->SYSCLKSource == RCC_SYSCLKSOURCE_HSE)
1094 {
1095 /* Check the HSE ready flag */
1096 if (READ_BIT(RCC->CR, RCC_CR_HSERDY) == 0U)
1097 {
1098 return HAL_ERROR;
1099 }
1100 }
1101 /* CSI is selected as System Clock Source */
1102 else if (pClkInitStruct->SYSCLKSource == RCC_SYSCLKSOURCE_CSI)
1103 {
1104 /* Check the CSI ready flag */
1105 if (READ_BIT(RCC->CR, RCC_CR_CSIRDY) == 0U)
1106 {
1107 return HAL_ERROR;
1108 }
1109 }
1110 /* HSI is selected as System Clock Source */
1111 else
1112 {
1113 /* Check the HSI ready flag */
1114 if (READ_BIT(RCC->CR, RCC_CR_HSIRDY) == 0U)
1115 {
1116 return HAL_ERROR;
1117 }
1118 }
1119 }
1120
1121 MODIFY_REG(RCC->CFGR1, RCC_CFGR1_SW, pClkInitStruct->SYSCLKSource);
1122
1123 /* Get Start Tick*/
1124 tickstart = HAL_GetTick();
1125
1126 if (pClkInitStruct->SYSCLKSource == RCC_SYSCLKSOURCE_PLLCLK)
1127 {
1128 while (__HAL_RCC_GET_SYSCLK_SOURCE() != RCC_SYSCLKSOURCE_STATUS_PLLCLK)
1129 {
1130 if ((HAL_GetTick() - tickstart) > CLOCKSWITCH_TIMEOUT_VALUE)
1131 {
1132 return HAL_TIMEOUT;
1133 }
1134 }
1135 }
1136 else
1137 {
1138 if (pClkInitStruct->SYSCLKSource == RCC_SYSCLKSOURCE_HSE)
1139 {
1140 while (__HAL_RCC_GET_SYSCLK_SOURCE() != RCC_SYSCLKSOURCE_STATUS_HSE)
1141 {
1142 if ((HAL_GetTick() - tickstart) > CLOCKSWITCH_TIMEOUT_VALUE)
1143 {
1144 return HAL_TIMEOUT;
1145 }
1146 }
1147 }
1148 else if (pClkInitStruct->SYSCLKSource == RCC_SYSCLKSOURCE_CSI)
1149 {
1150 while (__HAL_RCC_GET_SYSCLK_SOURCE() != RCC_SYSCLKSOURCE_STATUS_CSI)
1151 {
1152 if ((HAL_GetTick() - tickstart) > CLOCKSWITCH_TIMEOUT_VALUE)
1153 {
1154 return HAL_TIMEOUT;
1155 }
1156 }
1157 }
1158 else
1159 {
1160 while (__HAL_RCC_GET_SYSCLK_SOURCE() != RCC_SYSCLKSOURCE_STATUS_HSI)
1161 {
1162 if ((HAL_GetTick() - tickstart) > CLOCKSWITCH_TIMEOUT_VALUE)
1163 {
1164 return HAL_TIMEOUT;
1165 }
1166 }
1167 }
1168 }
1169 }
1170
1171 /* Decreasing the BUS frequency divider */
1172 /*-------------------------- HCLK Configuration --------------------------*/
1173 if (((pClkInitStruct->ClockType) & RCC_CLOCKTYPE_HCLK) == RCC_CLOCKTYPE_HCLK)
1174 {
1175 if ((pClkInitStruct->AHBCLKDivider) < (RCC->CFGR2 & RCC_CFGR2_HPRE))
1176 {
1177 assert_param(IS_RCC_HCLK(pClkInitStruct->AHBCLKDivider));
1178 MODIFY_REG(RCC->CFGR2, RCC_CFGR2_HPRE, pClkInitStruct->AHBCLKDivider);
1179 }
1180 }
1181
1182 /* Decreasing the number of wait states because of lower CPU frequency */
1183 if (FLatency < __HAL_FLASH_GET_LATENCY())
1184 {
1185 /* Program the new number of wait states to the LATENCY bits in the FLASH_ACR register */
1186 __HAL_FLASH_SET_LATENCY(FLatency);
1187
1188 /* Check that the new number of wait states is taken into account to access the Flash
1189 memory by reading the FLASH_ACR register */
1190 if (__HAL_FLASH_GET_LATENCY() != FLatency)
1191 {
1192 return HAL_ERROR;
1193 }
1194 }
1195
1196 /*-------------------------- PCLK1 Configuration ---------------------------*/
1197 if (((pClkInitStruct->ClockType) & RCC_CLOCKTYPE_PCLK1) == RCC_CLOCKTYPE_PCLK1)
1198 {
1199 if ((pClkInitStruct->APB1CLKDivider) < (RCC->CFGR2 & RCC_CFGR2_PPRE1))
1200 {
1201 assert_param(IS_RCC_PCLK(pClkInitStruct->APB1CLKDivider));
1202 MODIFY_REG(RCC->CFGR2, RCC_CFGR2_PPRE1, pClkInitStruct->APB1CLKDivider);
1203 }
1204 }
1205
1206 /*-------------------------- PCLK2 Configuration ---------------------------*/
1207 if (((pClkInitStruct->ClockType) & RCC_CLOCKTYPE_PCLK2) == RCC_CLOCKTYPE_PCLK2)
1208 {
1209 if ((pClkInitStruct->APB2CLKDivider) < ((RCC->CFGR2 & RCC_CFGR2_PPRE2) >> 4))
1210 {
1211 assert_param(IS_RCC_PCLK(pClkInitStruct->APB2CLKDivider));
1212 MODIFY_REG(RCC->CFGR2, RCC_CFGR2_PPRE2, ((pClkInitStruct->APB2CLKDivider) << 4));
1213 }
1214 }
1215
1216 /*-------------------------- PCLK3 Configuration ---------------------------*/
1217 if (((pClkInitStruct->ClockType) & RCC_CLOCKTYPE_PCLK3) == RCC_CLOCKTYPE_PCLK3)
1218 {
1219 if ((pClkInitStruct->APB3CLKDivider) < ((RCC->CFGR2 & RCC_CFGR2_PPRE3) >> 8))
1220 {
1221 assert_param(IS_RCC_PCLK(pClkInitStruct->APB3CLKDivider));
1222 MODIFY_REG(RCC->CFGR2, RCC_CFGR2_PPRE3, ((pClkInitStruct->APB3CLKDivider) << 8));
1223 }
1224 }
1225
1226 /* Update the SystemCoreClock global variable */
1227 SystemCoreClock = HAL_RCC_GetSysClockFreq() >> AHBPrescTable[(RCC->CFGR2 & RCC_CFGR2_HPRE) >> RCC_CFGR2_HPRE_Pos];
1228
1229 /* Configure the source of time base considering new system clocks settings*/
1230 halstatus = HAL_InitTick(uwTickPrio);
1231
1232 return halstatus;
1233 }
1234
1235 /**
1236 * @}
1237 */
1238
1239 /** @defgroup RCC_Exported_Functions_Group2 Peripheral Control functions
1240 * @brief RCC clocks control functions
1241 *
1242 @verbatim
1243 ===============================================================================
1244 ##### Peripheral Control functions #####
1245 ===============================================================================
1246 [..]
1247 This subsection provides a set of functions allowing to:
1248
1249 (+) Output clock to MCO pin.
1250 (+) Retrieve current clock frequencies.
1251 (+) Enable the Clock Security System.
1252
1253 @endverbatim
1254 * @{
1255 */
1256
1257 /**
1258 * @brief Select the clock source to output on MCO1 pin(PA8) or on MCO2 pin(PC9).
1259 * @note PA8/PC9 should be configured in alternate function mode.
1260 * @param RCC_MCOx specifies the output direction for the clock source.
1261 * For STM32H5xx family this parameter can have only one value:
1262 * @arg @ref RCC_MCO1 Clock source to output on MCO1 pin(PA8).
1263 * @arg @ref RCC_MCO2 Clock source to output on MCO2 pin(PC9).
1264 * @param RCC_MCOSource specifies the clock source to output.
1265 * This parameter can be one of the following values:
1266 * @arg RCC_MCO1SOURCE_HSI: HSI clock selected as MCO1 source
1267 * @arg RCC_MCO1SOURCE_LSE: LSE clock selected as MCO1 source
1268 * @arg RCC_MCO1SOURCE_HSE: HSE clock selected as MCO1 source
1269 * @arg RCC_MCO1SOURCE_PLL1QCLK: PLL1Q clock selected as MCO1 source
1270 * @arg RCC_MCO1SOURCE_HSI48: HSI48 (48MHZ) selected as MCO1 source
1271 * @arg RCC_MCO2SOURCE_SYSCLK: System clock (SYSCLK) selected as MCO2 source
1272 * @arg RCC_MCO2SOURCE_PLL2PCLK: PLL2P clock selected as MCO2 source
1273 * @arg RCC_MCO2SOURCE_HSE: HSE clock selected as MCO2 source
1274 * @arg RCC_MCO2SOURCE_PLL1PCLK: PLL1P clock selected as MCO2 source
1275 * @arg RCC_MCO2SOURCE_CSI: CSI clock selected as MCO2 source
1276 * @arg RCC_MCO2SOURCE_LSI: LSI clock selected as MCO2 source
1277 * @param RCC_MCODiv specifies the MCO prescaler.
1278 * This parameter can be one of the following values:
1279 * @arg RCC_MCODIV_1 up to RCC_MCODIV_15 : divider applied to MCOx clock
1280 * @retval None
1281 */
HAL_RCC_MCOConfig(uint32_t RCC_MCOx,uint32_t RCC_MCOSource,uint32_t RCC_MCODiv)1282 void HAL_RCC_MCOConfig(uint32_t RCC_MCOx, uint32_t RCC_MCOSource, uint32_t RCC_MCODiv)
1283 {
1284 GPIO_InitTypeDef GPIO_InitStruct;
1285 /* Check the parameters */
1286 assert_param(IS_RCC_MCO(RCC_MCOx));
1287 assert_param(IS_RCC_MCODIV(RCC_MCODiv));
1288 /* RCC_MCO1 */
1289 if (RCC_MCOx == RCC_MCO1)
1290 {
1291 assert_param(IS_RCC_MCO1SOURCE(RCC_MCOSource));
1292
1293 /* MCO1 Clock Enable */
1294 MCO1_CLK_ENABLE();
1295
1296 /* Configure the MCO1 pin in alternate function mode */
1297 GPIO_InitStruct.Pin = MCO1_PIN;
1298 GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
1299 GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
1300 GPIO_InitStruct.Pull = GPIO_NOPULL;
1301 GPIO_InitStruct.Alternate = GPIO_AF0_MCO;
1302 HAL_GPIO_Init(MCO1_GPIO_PORT, &GPIO_InitStruct);
1303
1304 /* Mask MCO1 and MCO1PRE[3:0] bits then Select MCO1 clock source and pre-scaler */
1305 MODIFY_REG(RCC->CFGR1, (RCC_CFGR1_MCO1SEL | RCC_CFGR1_MCO1PRE), (RCC_MCOSource | RCC_MCODiv));
1306 }
1307 else
1308 {
1309 assert_param(IS_RCC_MCO2SOURCE(RCC_MCOSource));
1310
1311 /* MCO2 Clock Enable */
1312 MCO2_CLK_ENABLE();
1313
1314 /* Configure the MCO2 pin in alternate function mode */
1315 GPIO_InitStruct.Pin = MCO2_PIN;
1316 GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
1317 GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
1318 GPIO_InitStruct.Pull = GPIO_NOPULL;
1319 GPIO_InitStruct.Alternate = GPIO_AF0_MCO;
1320 HAL_GPIO_Init(MCO2_GPIO_PORT, &GPIO_InitStruct);
1321
1322 /* Mask MCO2 and MCO2PRE[3:0] bits then Select MCO2 clock source and pre-scaler */
1323 MODIFY_REG(RCC->CFGR1, (RCC_CFGR1_MCO2SEL | RCC_CFGR1_MCO2PRE), (RCC_MCOSource | (RCC_MCODiv << 7U)));
1324 }
1325 }
1326
1327 /**
1328 * @brief Return the SYSCLK frequency.
1329 *
1330 * @note The system frequency computed by this function may not be the real
1331 * frequency in the chip. It is calculated based on the predefined
1332 * constants of the selected clock source:
1333 * @note If SYSCLK source is HSI, function returns values based on HSI_VALUE(*)
1334 * @note If SYSCLK source is CSI, function returns values based on CSI_VALUE(**)
1335 * @note If SYSCLK source is HSE, function returns values based on HSE_VALUE(***)
1336 * @note If SYSCLK source is PLL, function returns values based on HSI_VALUE(*), CSI_VALUE(**)
1337 * or HSE_VALUE(***) multiplied/divided by the PLL factors.
1338 * @note (*) HSI_VALUE is a constant defined in stm32h5xx_hal_conf.h file (default value
1339 * 64 MHz) but the real value may vary depending on the variations
1340 * in voltage and temperature.
1341 * @note (**) CSI_VALUE is a constant defined in stm32h5xx_hal_conf.h file (default value
1342 * 4 MHz) but the real value may vary depending on the variations
1343 * in voltage and temperature.
1344 * @note (***) HSE_VALUE is a constant defined in stm32h5xx_hal_conf.h file (default value
1345 * 24 MHz), user has to ensure that HSE_VALUE is same as the real
1346 * frequency of the crystal used. Otherwise, this function may
1347 * have wrong result.
1348 *
1349 * @note The result of this function could be not correct when using fractional
1350 * value for HSE crystal.
1351 *
1352 * @note This function can be used by the user application to compute the
1353 * baudrate for the communication peripherals or configure other parameters.
1354 *
1355 * @note Each time SYSCLK changes, this function must be called to update the
1356 * right SYSCLK value. Otherwise, any configuration based on this function will be incorrect.
1357 *
1358 *
1359 * @retval SYSCLK frequency
1360 */
HAL_RCC_GetSysClockFreq(void)1361 uint32_t HAL_RCC_GetSysClockFreq(void)
1362 {
1363 uint32_t pllsource;
1364 uint32_t pllp;
1365 uint32_t pllm;
1366 uint32_t pllfracen;
1367 uint32_t sysclockfreq;
1368 uint32_t hsivalue;
1369 float_t fracn1;
1370 float_t pllvco;
1371
1372 if (__HAL_RCC_GET_SYSCLK_SOURCE() == RCC_SYSCLKSOURCE_STATUS_CSI)
1373 {
1374 /* CSI used as system clock source */
1375 sysclockfreq = CSI_VALUE;
1376 }
1377 else if (__HAL_RCC_GET_SYSCLK_SOURCE() == RCC_SYSCLKSOURCE_STATUS_HSI)
1378 {
1379 /* HSI used as system clock source */
1380 if (__HAL_RCC_GET_FLAG(RCC_FLAG_HSIDIVF) != 0U)
1381 {
1382 sysclockfreq = (uint32_t)(HSI_VALUE >> (__HAL_RCC_GET_HSI_DIVIDER() >> RCC_CR_HSIDIV_Pos));
1383 }
1384 else
1385 {
1386 sysclockfreq = (uint32_t) HSI_VALUE;
1387 }
1388 }
1389 else if (__HAL_RCC_GET_SYSCLK_SOURCE() == RCC_SYSCLKSOURCE_STATUS_HSE)
1390 {
1391 /* HSE used as system clock source */
1392 sysclockfreq = HSE_VALUE;
1393 }
1394
1395 else if (__HAL_RCC_GET_SYSCLK_SOURCE() == RCC_SYSCLKSOURCE_STATUS_PLLCLK)
1396 {
1397 /* PLL used as system clock source */
1398
1399 /* PLL_VCO = (HSE_VALUE or HSI_VALUE or CSI_VALUE/ PLLM) * PLLN
1400 SYSCLK = PLL_VCO / PLLR
1401 */
1402 pllsource = (RCC->PLL1CFGR & RCC_PLL1CFGR_PLL1SRC);
1403 pllm = ((RCC->PLL1CFGR & RCC_PLL1CFGR_PLL1M) >> RCC_PLL1CFGR_PLL1M_Pos);
1404 pllfracen = ((RCC->PLL1CFGR & RCC_PLL1CFGR_PLL1FRACEN) >> RCC_PLL1CFGR_PLL1FRACEN_Pos);
1405 fracn1 = (float_t)(uint32_t)(pllfracen * ((RCC->PLL1FRACR & \
1406 RCC_PLL1FRACR_PLL1FRACN) >> RCC_PLL1FRACR_PLL1FRACN_Pos));
1407
1408 if (pllm != 0U)
1409 {
1410 switch (pllsource)
1411 {
1412 case RCC_PLL1_SOURCE_HSI: /* HSI used as PLL1 clock source */
1413
1414 if (__HAL_RCC_GET_FLAG(RCC_FLAG_HSIDIVF) != 0U)
1415 {
1416 hsivalue = (HSI_VALUE >> (__HAL_RCC_GET_HSI_DIVIDER() >> RCC_CR_HSIDIV_Pos));
1417 pllvco = ((float_t)hsivalue / (float_t)pllm) * ((float_t)(uint32_t)(RCC->PLL1DIVR & RCC_PLL1DIVR_PLL1N) + \
1418 (fracn1 / (float_t)0x2000) + (float_t)1);
1419 }
1420 else
1421 {
1422 pllvco = ((float_t)HSI_VALUE / (float_t)pllm) * ((float_t)(uint32_t)(RCC->PLL1DIVR & RCC_PLL1DIVR_PLL1N) + \
1423 (fracn1 / (float_t)0x2000) + (float_t)1);
1424 }
1425
1426 break;
1427
1428 case RCC_PLL1_SOURCE_HSE: /* HSE used as PLL1 clock source */
1429 pllvco = ((float_t)HSE_VALUE / (float_t)pllm) * ((float_t)(uint32_t)(RCC->PLL1DIVR & RCC_PLL1DIVR_PLL1N) + \
1430 (fracn1 / (float_t)0x2000) + (float_t)1);
1431
1432 break;
1433
1434 case RCC_PLL1_SOURCE_CSI: /* CSI used as PLL1 clock source */
1435 default:
1436 pllvco = ((float_t)CSI_VALUE / (float_t)pllm) * ((float_t)(uint32_t)(RCC->PLL1DIVR & RCC_PLL1DIVR_PLL1N) + \
1437 (fracn1 / (float_t)0x2000) + (float_t)1);
1438 break;
1439 }
1440
1441 pllp = (((RCC->PLL1DIVR & RCC_PLL1DIVR_PLL1P) >> RCC_PLL1DIVR_PLL1P_Pos) + 1U) ;
1442 sysclockfreq = (uint32_t)(float_t)(pllvco / (float_t)pllp);
1443 }
1444 else
1445 {
1446 sysclockfreq = 0;
1447 }
1448 }
1449
1450 else
1451 {
1452 /* HSI is the default system clock source */
1453 sysclockfreq = (uint32_t) HSI_VALUE;
1454 }
1455
1456 return sysclockfreq;
1457 }
1458
1459 /**
1460 * @brief Return the HCLK frequency.
1461 * @note Each time HCLK changes, this function must be called to update the
1462 * right HCLK value. Otherwise, any configuration based on this function will be incorrect.
1463 *
1464 * @note The SystemCoreClock CMSIS variable is used to store System Clock Frequency.
1465 * @retval HCLK frequency in Hz
1466 */
HAL_RCC_GetHCLKFreq(void)1467 uint32_t HAL_RCC_GetHCLKFreq(void)
1468 {
1469
1470 SystemCoreClock = HAL_RCC_GetSysClockFreq() >> (AHBPrescTable[(RCC->CFGR2 & RCC_CFGR2_HPRE) \
1471 >> RCC_CFGR2_HPRE_Pos] & 0x1FU);
1472
1473 return SystemCoreClock;
1474 }
1475
1476 /**
1477 * @brief Return the PCLK1 frequency.
1478 * @note Each time PCLK1 changes, this function must be called to update the
1479 * right PCLK1 value. Otherwise, any configuration based on this function will be incorrect.
1480 * @retval PCLK1 frequency in Hz
1481 */
HAL_RCC_GetPCLK1Freq(void)1482 uint32_t HAL_RCC_GetPCLK1Freq(void)
1483 {
1484 /* Get HCLK source and Compute PCLK1 frequency ---------------------------*/
1485 return (HAL_RCC_GetHCLKFreq() >> ((APBPrescTable[(RCC->CFGR2 & RCC_CFGR2_PPRE1) >> RCC_CFGR2_PPRE1_Pos]) & 0x1FU));
1486 }
1487
1488 /**
1489 * @brief Return the PCLK2 frequency.
1490 * @note Each time PCLK2 changes, this function must be called to update the
1491 * right PCLK2 value. Otherwise, any configuration based on this function will be incorrect.
1492 * @retval PCLK2 frequency in Hz
1493 */
HAL_RCC_GetPCLK2Freq(void)1494 uint32_t HAL_RCC_GetPCLK2Freq(void)
1495 {
1496 /* Get HCLK source and Compute PCLK2 frequency ---------------------------*/
1497 return (HAL_RCC_GetHCLKFreq() >> ((APBPrescTable[(RCC->CFGR2 & RCC_CFGR2_PPRE2) >> RCC_CFGR2_PPRE2_Pos]) & 0x1FU));
1498 }
1499
1500 /**
1501 * @brief Return the PCLK3 frequency.
1502 * @note Each time PCLK3 changes, this function must be called to update the
1503 * right PCLK3 value. Otherwise, any configuration based on this function will be incorrect.
1504 * @retval PCLK3 frequency in Hz
1505 */
HAL_RCC_GetPCLK3Freq(void)1506 uint32_t HAL_RCC_GetPCLK3Freq(void)
1507 {
1508 /* Get HCLK source and Compute PCLK3 frequency ---------------------------*/
1509 return (HAL_RCC_GetHCLKFreq() >> ((APBPrescTable[(RCC->CFGR2 & RCC_CFGR2_PPRE3) >> RCC_CFGR2_PPRE3_Pos]) & 0x1FU));
1510 }
1511 /**
1512 * @brief Configure the pOscInitStruct according to the internal
1513 * RCC configuration registers.
1514 * @param pOscInitStruct pointer to an RCC_OscInitTypeDef structure that
1515 * will be configured.
1516 * @retval None
1517 */
HAL_RCC_GetOscConfig(RCC_OscInitTypeDef * pOscInitStruct)1518 void HAL_RCC_GetOscConfig(RCC_OscInitTypeDef *pOscInitStruct)
1519 {
1520 uint32_t regval;
1521 uint32_t reg1val;
1522 uint32_t reg2val;
1523
1524 /* Check the parameters */
1525 assert_param(pOscInitStruct != (void *)NULL);
1526
1527 /* Set all possible values for the Oscillator type parameter ---------------*/
1528 pOscInitStruct->OscillatorType = RCC_OSCILLATORTYPE_HSE | RCC_OSCILLATORTYPE_HSI | RCC_OSCILLATORTYPE_CSI | \
1529 RCC_OSCILLATORTYPE_LSE | RCC_OSCILLATORTYPE_LSI | RCC_OSCILLATORTYPE_HSI48;
1530
1531 /* Get Control register */
1532 regval = RCC->CR;
1533
1534 /* Get the HSE configuration -----------------------------------------------*/
1535 pOscInitStruct->HSEState = (regval & (RCC_CR_HSEON | RCC_CR_HSEBYP | RCC_CR_HSEEXT));
1536
1537 /* Get the CSI configuration -----------------------------------------------*/
1538 pOscInitStruct->CSIState = regval & RCC_CR_CSION;
1539
1540 /* Get the HSI configuration -----------------------------------------------*/
1541 pOscInitStruct->HSIState = regval & RCC_CR_HSION;
1542 pOscInitStruct->HSIDiv = regval & RCC_CR_HSIDIV;
1543 pOscInitStruct->HSICalibrationValue = (uint32_t)(READ_BIT(RCC->HSICFGR, \
1544 RCC_HSICFGR_HSITRIM) >> RCC_HSICFGR_HSITRIM_Pos);
1545
1546 /* Get BDCR register */
1547 regval = RCC->BDCR;
1548
1549 /* Get the LSE configuration -----------------------------------------------*/
1550 pOscInitStruct->LSEState = (regval & (RCC_BDCR_LSEON | RCC_BDCR_LSEBYP | RCC_BDCR_LSEEXT));
1551
1552 /* Get the LSI configuration -----------------------------------------------*/
1553 pOscInitStruct->LSIState = regval & RCC_BDCR_LSION;
1554
1555 /* Get Control register */
1556 regval = RCC->CR;
1557
1558 /* Get the HSI48 configuration ---------------------------------------------*/
1559 pOscInitStruct->HSI48State = regval & RCC_CR_HSI48ON;
1560
1561 /* Get the PLL configuration -----------------------------------------------*/
1562 if ((regval & RCC_CR_PLL1ON) == RCC_CR_PLL1ON)
1563 {
1564 pOscInitStruct->PLL.PLLState = RCC_PLL_ON;
1565 }
1566 else
1567 {
1568 pOscInitStruct->PLL.PLLState = RCC_PLL_OFF;
1569 }
1570
1571 /* Get PLL configuration register */
1572 reg1val = RCC->PLL1CFGR;
1573 reg2val = RCC->PLL1DIVR;
1574
1575 pOscInitStruct->PLL.PLLSource = (uint32_t)(reg1val & RCC_PLL1CFGR_PLL1SRC);
1576 pOscInitStruct->PLL.PLLM = (uint32_t)((reg1val & RCC_PLL1CFGR_PLL1M) >> RCC_PLL1CFGR_PLL1M_Pos);
1577 pOscInitStruct->PLL.PLLN = (uint32_t)(((reg2val & RCC_PLL1DIVR_PLL1N) >> RCC_PLL1DIVR_PLL1N_Pos) + 1U);
1578 pOscInitStruct->PLL.PLLQ = (uint32_t)(((reg2val & RCC_PLL1DIVR_PLL1Q) >> RCC_PLL1DIVR_PLL1Q_Pos) + 1U);
1579 pOscInitStruct->PLL.PLLR = (uint32_t)(((reg2val & RCC_PLL1DIVR_PLL1R) >> RCC_PLL1DIVR_PLL1R_Pos) + 1U);
1580 pOscInitStruct->PLL.PLLP = (uint32_t)(((reg2val & RCC_PLL1DIVR_PLL1P) >> RCC_PLL1DIVR_PLL1P_Pos) + 1U);
1581 pOscInitStruct->PLL.PLLRGE = (uint32_t)((reg1val & RCC_PLL1CFGR_PLL1RGE));
1582 pOscInitStruct->PLL.PLLVCOSEL = (uint32_t)((reg1val & RCC_PLL1CFGR_PLL1VCOSEL) >> RCC_PLL1CFGR_PLL1VCOSEL_Pos);
1583 pOscInitStruct->PLL.PLLFRACN = (uint32_t)(((RCC->PLL1FRACR & RCC_PLL1FRACR_PLL1FRACN) \
1584 >> RCC_PLL1FRACR_PLL1FRACN_Pos));
1585 }
1586
1587 /**
1588 * @brief Configure the pClkInitStruct according to the internal
1589 * RCC configuration registers.
1590 * @param pClkInitStruct pointer to an RCC_ClkInitTypeDef structure that
1591 * will be configured.
1592 * @param pFLatency Pointer on the Flash Latency.
1593 * @retval None
1594 */
HAL_RCC_GetClockConfig(RCC_ClkInitTypeDef * pClkInitStruct,uint32_t * pFLatency)1595 void HAL_RCC_GetClockConfig(RCC_ClkInitTypeDef *pClkInitStruct, uint32_t *pFLatency)
1596 {
1597 uint32_t regval;
1598
1599 /* Check the parameters */
1600 assert_param(pClkInitStruct != (void *)NULL);
1601 assert_param(pFLatency != (void *)NULL);
1602
1603 /* Set all possible values for the Clock type parameter --------------------*/
1604 pClkInitStruct->ClockType = RCC_CLOCKTYPE_SYSCLK | RCC_CLOCKTYPE_HCLK | RCC_CLOCKTYPE_PCLK1 | RCC_CLOCKTYPE_PCLK2 | \
1605 RCC_CLOCKTYPE_PCLK3;
1606
1607 /* Get the SYSCLK configuration --------------------------------------------*/
1608 pClkInitStruct->SYSCLKSource = (uint32_t)(RCC->CFGR1 & RCC_CFGR1_SW);
1609
1610 /* Get the HCLK configuration ----------------------------------------------*/
1611 regval = RCC->CFGR2;
1612 pClkInitStruct->AHBCLKDivider = (uint32_t)(regval & RCC_CFGR2_HPRE);
1613
1614 /* Get the APB1 configuration ----------------------------------------------*/
1615 pClkInitStruct->APB1CLKDivider = (uint32_t)(regval & RCC_CFGR2_PPRE1);
1616
1617 /* Get the APB2 configuration ----------------------------------------------*/
1618 pClkInitStruct->APB2CLKDivider = (uint32_t)((regval & RCC_CFGR2_PPRE2) >> 4);
1619
1620 /* Get the APB3 configuration ----------------------------------------------*/
1621 pClkInitStruct->APB3CLKDivider = (uint32_t)((regval & RCC_CFGR2_PPRE3) >> 8);
1622
1623 /* Get the Flash Wait State (Latency) configuration ------------------------*/
1624 *pFLatency = (uint32_t)(FLASH->ACR & FLASH_ACR_LATENCY);
1625 }
1626
1627 /**
1628 * @brief Get and clear reset flags
1629 * @note Once reset flags are retrieved, this API is clearing them in order
1630 * to isolate next reset reason.
1631 * @retval can be a combination of @ref RCC_Reset_Flag
1632 */
HAL_RCC_GetResetSource(void)1633 uint32_t HAL_RCC_GetResetSource(void)
1634 {
1635 uint32_t reset;
1636
1637 /* Get all reset flags */
1638 reset = RCC->RSR & RCC_RESET_FLAG_ALL;
1639
1640 /* Clear Reset flags */
1641 RCC->RSR |= RCC_RSR_RMVF;
1642
1643 return reset;
1644 }
1645
1646 /**
1647 * @brief Enable the HSE Clock Security System.
1648 * @note If a failure is detected on the HSE oscillator clock, this oscillator
1649 * is automatically disabled and an interrupt is generated to inform the
1650 * software about the failure (Clock Security System Interrupt, CSSI),
1651 * allowing the MCU to perform rescue operations. The CSSI is linked to
1652 * the Cortex-M NMI (Non-Maskable Interrupt) exception vector.
1653 * @note The Clock Security System can only be cleared by reset.
1654 * @retval None
1655 */
HAL_RCC_EnableCSS(void)1656 void HAL_RCC_EnableCSS(void)
1657 {
1658 SET_BIT(RCC->CR, RCC_CR_HSECSSON);
1659 }
1660
1661 /**
1662 * @brief Handle the RCC Clock Security System interrupt request.
1663 * @note This API should be called under the NMI_Handler().
1664 * @retval None
1665 */
HAL_RCC_NMI_IRQHandler(void)1666 void HAL_RCC_NMI_IRQHandler(void)
1667 {
1668 /* Check RCC CSSF interrupt flag */
1669 if (__HAL_RCC_GET_IT(RCC_IT_HSECSS))
1670 {
1671 /* RCC Clock Security System interrupt user callback */
1672 HAL_RCC_CSSCallback();
1673
1674 /* Clear RCC CSS pending bit */
1675 __HAL_RCC_CLEAR_IT(RCC_IT_HSECSS);
1676 }
1677 }
1678
1679 /**
1680 * @brief RCC HSE Clock Security System interrupt callback.
1681 * @retval none
1682 */
HAL_RCC_CSSCallback(void)1683 __weak void HAL_RCC_CSSCallback(void)
1684 {
1685 /* NOTE : This function should not be modified, when the callback is needed,
1686 the HAL_RCC_CSSCallback should be implemented in the user file
1687 */
1688 }
1689
1690 /**
1691 * @}
1692 */
1693
1694 /** @defgroup RCC_Exported_Functions_Group3 Attributes management functions
1695 * @brief Attributes management functions.
1696 *
1697 @verbatim
1698 ===============================================================================
1699 ##### RCC attributes functions #####
1700 ===============================================================================
1701 [..]
1702 This subsection provides a set of functions allowing to:
1703
1704 (+) Configure the RCC item(s) attributes.
1705 (+) Get the attribute of an RCC item.
1706
1707 @endverbatim
1708 * @{
1709 */
1710 /**
1711 * @brief Configure the RCC item(s) attribute(s).
1712 * @note Available attributes are to secure items and set RCC as privileged (*).
1713 * Default state is non-secure and unprivileged access allowed.
1714 * @note Secure and non-secure attributes can only be set from the secure
1715 * state when the system implements the security (TZEN=1).
1716 * @param Item Item(s) to set attributes on.
1717 * This parameter can be a one or a combination of @ref RCC_items (**).
1718 * @param Attributes specifies the RCC secure/privilege attributes.
1719 * This parameter can be a value of @RCC_attributes
1720 * @retval None
1721 *
1722 * (*) : For stm32h503xx devices, attributes specifies the privilege attribute only (no items).
1723 * (**) : For stm32h503xx devices, this parameter is unused, it can take 0 or any other numerical value.
1724 */
HAL_RCC_ConfigAttributes(uint32_t Item,uint32_t Attributes)1725 void HAL_RCC_ConfigAttributes(uint32_t Item, uint32_t Attributes)
1726 {
1727
1728 /* Check the parameters */
1729 assert_param(IS_RCC_ATTRIBUTES(Attributes));
1730
1731 #if defined(RCC_SECCFGR_HSISEC)
1732 assert_param(IS_RCC_ITEM_ATTRIBUTES(Item));
1733
1734 switch (Attributes)
1735 {
1736 #if defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U)
1737 /* Secure Privilege attribute */
1738 case RCC_SEC_PRIV:
1739 SET_BIT(RCC->SECCFGR, Item);
1740 SET_BIT(RCC->PRIVCFGR, RCC_PRIVCFGR_SPRIV);
1741 break;
1742 /* Secure Non-Privilege attribute */
1743 case RCC_SEC_NPRIV:
1744 SET_BIT(RCC->SECCFGR, Item);
1745 CLEAR_BIT(RCC->PRIVCFGR, RCC_PRIVCFGR_SPRIV);
1746 break;
1747 /* Non-secure Privilege attribute */
1748 case RCC_NSEC_PRIV:
1749 CLEAR_BIT(RCC->SECCFGR, Item);
1750 SET_BIT(RCC->PRIVCFGR, RCC_PRIVCFGR_NSPRIV);
1751 break;
1752 /* Non-secure Non-Privilege attribute */
1753 case RCC_NSEC_NPRIV:
1754 CLEAR_BIT(RCC->SECCFGR, Item);
1755 CLEAR_BIT(RCC->PRIVCFGR, RCC_PRIVCFGR_NSPRIV);
1756 break;
1757 #else /* __ARM_FEATURE_CMSE */
1758 /* Non-secure Privilege attribute */
1759 case RCC_NSEC_PRIV:
1760 SET_BIT(RCC->PRIVCFGR, RCC_PRIVCFGR_NSPRIV);
1761 break;
1762 /* Non-secure Non-Privilege attribute */
1763 case RCC_NSEC_NPRIV:
1764 CLEAR_BIT(RCC->PRIVCFGR, RCC_PRIVCFGR_NSPRIV);
1765 break;
1766 #endif /* __ARM_FEATURE_CMSE */
1767 default:
1768 /* Nothing to do */
1769 break;
1770 }
1771
1772 #else /* RCC_SECCFGR_HSISEC */
1773
1774 UNUSED(Item);
1775
1776 switch (Attributes)
1777 {
1778 /* Privilege attribute */
1779 case RCC_PRIV:
1780 SET_BIT(RCC->PRIVCFGR, RCC_PRIVCFGR_PRIV);
1781 break;
1782 /* Non-secure Non-Privilege attribute */
1783 case RCC_NPRIV:
1784 CLEAR_BIT(RCC->PRIVCFGR, RCC_PRIVCFGR_PRIV);
1785 break;
1786 default:
1787 /* Nothing to do */
1788 break;
1789 }
1790
1791 #endif /* RCC_SECCFGR_HSISEC */
1792 }
1793
1794 /**
1795 * @brief Get the attribute of an RCC item.
1796 * @note Secure and non-secure attributes are only available from secure state
1797 * when the system implements the security (TZEN=1)
1798 * @param Item Single item to get secure/non-secure and privilege/non-privilege attribute from.
1799 * This parameter can be a one value of @ref RCC_items except RCC_ALL. (*)
1800 * @param pAttributes pointer to return the attributes.
1801 * @retval HAL Status.
1802 *
1803 * (*) : This parameter is unused for stm32h503xx devices, it can take 0 or any other numerical value.
1804 */
HAL_RCC_GetConfigAttributes(uint32_t Item,uint32_t * pAttributes)1805 HAL_StatusTypeDef HAL_RCC_GetConfigAttributes(uint32_t Item, uint32_t *pAttributes)
1806 {
1807 uint32_t attributes;
1808
1809 /* Check null pointer */
1810 if (pAttributes == NULL)
1811 {
1812 return HAL_ERROR;
1813 }
1814
1815 #if defined(RCC_SECCFGR_HSISEC)
1816 /* Check the parameters */
1817 assert_param(IS_RCC_SINGLE_ITEM_ATTRIBUTES(Item));
1818
1819 #if defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U)
1820
1821 /* Check item security */
1822 if ((RCC->SECCFGR & Item) == Item)
1823 {
1824 /* Get Secure privileges attribute */
1825 attributes = ((RCC->PRIVCFGR & RCC_PRIVCFGR_SPRIV) == 0U) ? RCC_SEC_NPRIV : RCC_SEC_PRIV;
1826 }
1827 else
1828 {
1829 /* Get Non-Secure privileges attribute */
1830 attributes = ((RCC->PRIVCFGR & RCC_PRIVCFGR_NSPRIV) == 0U) ? RCC_NSEC_NPRIV : RCC_NSEC_PRIV;
1831 }
1832 #else /* __ARM_FEATURE_CMSE */
1833 attributes = ((RCC->PRIVCFGR & RCC_PRIVCFGR_NSPRIV) == 0U) ? RCC_NSEC_NPRIV : RCC_NSEC_PRIV;
1834 #endif /* __ARM_FEATURE_CMSE */
1835
1836 #else /* RCC_SECCFGR_HSISEC */
1837 UNUSED(Item);
1838 /* Get privileges attribute */
1839 attributes = ((RCC->PRIVCFGR & RCC_PRIVCFGR_PRIV) == 0U) ? RCC_NPRIV : RCC_PRIV;
1840 #endif /* RCC_SECCFGR_HSISEC */
1841
1842 /* return value */
1843 *pAttributes = attributes;
1844
1845 return HAL_OK;
1846 }
1847
1848 /**
1849 * @}
1850 */
1851
1852 /**
1853 * @}
1854 */
1855
1856 /* Private function prototypes -----------------------------------------------*/
1857 #endif /* HAL_RCC_MODULE_ENABLED */
1858 /**
1859 * @}
1860 */
1861
1862 /**
1863 * @}
1864 */
1865