1 /**
2 ******************************************************************************
3 * @file stm32g4xx_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 @verbatim
12 ==============================================================================
13 ##### RCC specific features #####
14 ==============================================================================
15 [..]
16 After reset the device is running from High Speed Internal oscillator
17 (16 MHz) with Flash 0 wait state. Flash prefetch buffer, D-Cache
18 and I-Cache are disabled, and all peripherals are off except internal
19 SRAM, Flash and JTAG.
20
21 (+) There is no prescaler on High speed (AHBs) and Low speed (APBs) buses:
22 all peripherals mapped on these buses are running at HSI speed.
23 (+) The clock for all peripherals is switched off, except the SRAM and FLASH.
24 (+) All GPIOs are in analog mode, except the JTAG pins which
25 are assigned to be used for debug purpose.
26
27 [..]
28 Once the device started from reset, the user application has to:
29 (+) Configure the clock source to be used to drive the System clock
30 (if the application needs higher frequency/performance)
31 (+) Configure the System clock frequency and Flash settings
32 (+) Configure the AHB and APB buses prescalers
33 (+) Enable the clock for the peripheral(s) to be used
34 (+) Configure the clock source(s) for peripherals which clocks are not
35 derived from the System clock (USB, RNG, USART, LPUART, FDCAN, some TIMERs,
36 UCPD, I2S, I2C, LPTIM, ADC, QSPI)
37
38 @endverbatim
39 ******************************************************************************
40 * @attention
41 *
42 * Copyright (c) 2019 STMicroelectronics.
43 * All rights reserved.
44 *
45 * This software is licensed under terms that can be found in the LICENSE file in
46 * the root directory of this software component.
47 * If no LICENSE file comes with this software, it is provided AS-IS.
48 ******************************************************************************
49 */
50
51 /* Includes ------------------------------------------------------------------*/
52 #include "stm32g4xx_hal.h"
53
54 /** @addtogroup STM32G4xx_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 /** @defgroup RCC_Private_Constants RCC Private Constants
68 * @{
69 */
70 #define HSE_TIMEOUT_VALUE HSE_STARTUP_TIMEOUT
71 #define HSI_TIMEOUT_VALUE 2U /* 2 ms (minimum Tick + 1) */
72 #define LSI_TIMEOUT_VALUE 2U /* 2 ms (minimum Tick + 1) */
73 #define HSI48_TIMEOUT_VALUE 2U /* 2 ms (minimum Tick + 1) */
74 #define PLL_TIMEOUT_VALUE 2U /* 2 ms (minimum Tick + 1) */
75 #define CLOCKSWITCH_TIMEOUT_VALUE 5000U /* 5 s */
76 /**
77 * @}
78 */
79
80 /* Private macro -------------------------------------------------------------*/
81 /** @defgroup RCC_Private_Macros RCC Private Macros
82 * @{
83 */
84 #define RCC_GET_MCO_GPIO_PIN(__RCC_MCOx__) ((__RCC_MCOx__) & GPIO_PIN_MASK)
85
86 #define RCC_GET_MCO_GPIO_AF(__RCC_MCOx__) (((__RCC_MCOx__) & RCC_MCO_GPIOAF_MASK) >> RCC_MCO_GPIOAF_POS)
87
88 #define RCC_GET_MCO_GPIO_INDEX(__RCC_MCOx__) (((__RCC_MCOx__) & RCC_MCO_GPIOPORT_MASK) >> RCC_MCO_GPIOPORT_POS)
89
90 #define RCC_GET_MCO_GPIO_PORT(__RCC_MCOx__) (AHB2PERIPH_BASE + ((0x00000400UL) * RCC_GET_MCO_GPIO_INDEX(__RCC_MCOx__)))
91
92 #define RCC_PLL_OSCSOURCE_CONFIG(__HAL_RCC_PLLSOURCE__) \
93 (MODIFY_REG(RCC->PLLCFGR, RCC_PLLCFGR_PLLSRC, (__HAL_RCC_PLLSOURCE__)))
94 /**
95 * @}
96 */
97
98 /* Private variables ---------------------------------------------------------*/
99
100 /* Private function prototypes -----------------------------------------------*/
101 /** @defgroup RCC_Private_Functions RCC Private Functions
102 * @{
103 */
104 static uint32_t RCC_GetSysClockFreqFromPLLSource(void);
105 /**
106 * @}
107 */
108
109 /* Exported functions --------------------------------------------------------*/
110
111 /** @defgroup RCC_Exported_Functions RCC Exported Functions
112 * @{
113 */
114
115 /** @defgroup RCC_Exported_Functions_Group1 Initialization and de-initialization functions
116 * @brief Initialization and Configuration functions
117 *
118 @verbatim
119 ===============================================================================
120 ##### Initialization and de-initialization functions #####
121 ===============================================================================
122 [..]
123 This section provides functions allowing to configure the internal and external oscillators
124 (HSE, HSI, LSE, LSI, PLL, CSS and MCO) and the System buses clocks (SYSCLK, AHB, APB1
125 and APB2).
126
127 [..] Internal/external clock and PLL configuration
128 (+) HSI (high-speed internal): 16 MHz factory-trimmed RC used directly or through
129 the PLL as System clock source.
130
131 (+) LSI (low-speed internal): 32 KHz low consumption RC used as IWDG and/or RTC
132 clock source.
133
134 (+) HSE (high-speed external): 4 to 48 MHz crystal oscillator used directly or
135 through the PLL as System clock source. Can be used also optionally as RTC clock source.
136
137 (+) LSE (low-speed external): 32.768 KHz oscillator used optionally as RTC clock source.
138
139 (+) PLL (clocked by HSI, HSE) providing up to three independent output clocks:
140 (++) The first output is used to generate the high speed system clock (up to 170 MHz).
141 (++) The second output is used to generate the clock for the USB (48 MHz),
142 the QSPI (<= 48 MHz), the FDCAN, the SAI and the I2S.
143 (++) The third output is used to generate a clock for ADC
144
145 (+) CSS (Clock security system): once enabled, if a HSE clock failure occurs
146 (HSE used directly or through PLL as System clock source), the System clock
147 is automatically switched to HSI and an interrupt is generated if enabled.
148 The interrupt is linked to the Cortex-M4 NMI (Non-Maskable Interrupt)
149 exception vector.
150
151 (+) MCO (microcontroller clock output): used to output LSI, HSI, LSE, HSE,
152 main PLL clock, system clock or RC48 clock (through a configurable prescaler) on PA8 pin.
153
154 [..] System, AHB and APB buses clocks configuration
155 (+) Several clock sources can be used to drive the System clock (SYSCLK): HSI,
156 HSE and main PLL.
157 The AHB clock (HCLK) is derived from System clock through configurable
158 prescaler and used to clock the CPU, memory and peripherals mapped
159 on AHB bus (DMA, GPIO...). APB1 (PCLK1) and APB2 (PCLK2) clocks are derived
160 from AHB clock through configurable prescalers and used to clock
161 the peripherals mapped on these buses. You can use
162 "HAL_RCC_GetSysClockFreq()" function to retrieve the frequencies of these clocks.
163
164 -@- All the peripheral clocks are derived from the System clock (SYSCLK) except:
165
166 (+@) RTC: the RTC clock can be derived either from the LSI, LSE or HSE clock
167 divided by 2 to 31.
168 You have to use __HAL_RCC_RTC_ENABLE() and HAL_RCCEx_PeriphCLKConfig() function
169 to configure this clock.
170 (+@) USB FS and RNG: USB FS requires a frequency equal to 48 MHz
171 to work correctly, while the RNG peripheral requires a frequency
172 equal or lower than to 48 MHz. This clock is derived of the main PLL
173 through PLLQ divider. You have to enable the peripheral clock and use
174 HAL_RCCEx_PeriphCLKConfig() function to configure this clock.
175 (+@) IWDG clock which is always the LSI clock.
176
177
178 (+) The maximum frequency of the SYSCLK, HCLK, PCLK1 and PCLK2 is 170 MHz.
179 The clock source frequency should be adapted depending on the device voltage range
180 as listed in the Reference Manual "Clock source frequency versus voltage scaling" chapter.
181
182 @endverbatim
183
184 Table 1. HCLK clock frequency for STM32G4xx devices
185 +----------------------------------------------------------------------------+
186 | Latency | HCLK clock frequency (MHz) |
187 | |----------------------------------------------------------|
188 | | voltage range 1 | voltage range 1 | voltage range 2 |
189 | | boost mode 1.28 V | normal mode 1.2 V | 1.0 V |
190 |-----------------|-------------------|-------------------|------------------|
191 |0WS(1 CPU cycles)| HCLK <= 34 | HCLK <= 30 | HCLK <= 13 |
192 |-----------------|-------------------|-------------------|------------------|
193 |1WS(2 CPU cycles)| HCLK <= 68 | HCLK <= 60 | HCLK <= 26 |
194 |-----------------|-------------------|-------------------|------------------|
195 |2WS(3 CPU cycles)| HCLK <= 102 | HCLK <= 90 | - |
196 |-----------------|-------------------|-------------------|------------------|
197 |3WS(4 CPU cycles)| HCLK <= 136 | HCLK <= 120 | - |
198 |-----------------|-------------------|-------------------|------------------|
199 |4WS(5 CPU cycles)| HCLK <= 170 | HCLK <= 150 | - |
200 +----------------------------------------------------------------------------+
201
202 * @{
203 */
204
205 /**
206 * @brief Reset the RCC clock configuration to the default reset state.
207 * @note The default reset state of the clock configuration is given below:
208 * - HSI ON and used as system clock source
209 * - HSE, PLL OFF
210 * - AHB, APB1 and APB2 prescaler set to 1.
211 * - CSS, MCO1 OFF
212 * - All interrupts disabled
213 * - All interrupt and reset flags cleared
214 * @note This function doesn't modify the configuration of the
215 * - Peripheral clocks
216 * - LSI, LSE and RTC clocks
217 * @retval HAL status
218 */
HAL_RCC_DeInit(void)219 HAL_StatusTypeDef HAL_RCC_DeInit(void)
220 {
221 uint32_t tickstart;
222
223 /* Get Start Tick*/
224 tickstart = HAL_GetTick();
225
226 /* Set HSION bit to the reset value */
227 SET_BIT(RCC->CR, RCC_CR_HSION);
228
229 /* Wait till HSI is ready */
230 while (READ_BIT(RCC->CR, RCC_CR_HSIRDY) == 0U)
231 {
232 if ((HAL_GetTick() - tickstart) > HSI_TIMEOUT_VALUE)
233 {
234 return HAL_TIMEOUT;
235 }
236 }
237
238 /* Set HSITRIM[6:0] bits to the reset value */
239 SET_BIT(RCC->ICSCR, RCC_HSICALIBRATION_DEFAULT << RCC_ICSCR_HSITRIM_Pos);
240
241 /* Get Start Tick*/
242 tickstart = HAL_GetTick();
243
244 /* Reset CFGR register (HSI is selected as system clock source) */
245 RCC->CFGR = 0x00000001u;
246
247 /* Wait till HSI is ready */
248 while (READ_BIT(RCC->CFGR, RCC_CFGR_SWS) != RCC_CFGR_SWS_HSI)
249 {
250 if ((HAL_GetTick() - tickstart) > CLOCKSWITCH_TIMEOUT_VALUE)
251 {
252 return HAL_TIMEOUT;
253 }
254 }
255
256 /* Update the SystemCoreClock global variable */
257 SystemCoreClock = HSI_VALUE;
258
259 /* Adapt Systick interrupt period */
260 if (HAL_InitTick(uwTickPrio) != HAL_OK)
261 {
262 return HAL_ERROR;
263 }
264
265 /* Clear CR register in 2 steps: first to clear HSEON in case bypass was enabled */
266 RCC->CR = RCC_CR_HSION;
267
268 /* Then again to HSEBYP in case bypass was enabled */
269 RCC->CR = RCC_CR_HSION;
270
271 /* Get Start Tick*/
272 tickstart = HAL_GetTick();
273
274 /* Wait till PLL is OFF */
275 while (READ_BIT(RCC->CR, RCC_CR_PLLRDY) != 0U)
276 {
277 if ((HAL_GetTick() - tickstart) > PLL_TIMEOUT_VALUE)
278 {
279 return HAL_TIMEOUT;
280 }
281 }
282
283 /* once PLL is OFF, reset PLLCFGR register to default value */
284 RCC->PLLCFGR = RCC_PLLCFGR_PLLN_4;
285
286 /* Disable all interrupts */
287 CLEAR_REG(RCC->CIER);
288
289 /* Clear all interrupt flags */
290 WRITE_REG(RCC->CICR, 0xFFFFFFFFU);
291
292 /* Clear all reset flags */
293 SET_BIT(RCC->CSR, RCC_CSR_RMVF);
294
295 return HAL_OK;
296 }
297
298 /**
299 * @brief Initialize the RCC Oscillators according to the specified parameters in the
300 * RCC_OscInitTypeDef.
301 * @param RCC_OscInitStruct pointer to an RCC_OscInitTypeDef structure that
302 * contains the configuration information for the RCC Oscillators.
303 * @note The PLL is not disabled when used as system clock.
304 * @note Transitions LSE Bypass to LSE On and LSE On to LSE Bypass are not
305 * supported by this macro. User should request a transition to LSE Off
306 * first and then LSE On or LSE Bypass.
307 * @note Transition HSE Bypass to HSE On and HSE On to HSE Bypass are not
308 * supported by this macro. User should request a transition to HSE Off
309 * first and then HSE On or HSE Bypass.
310 * @retval HAL status
311 */
HAL_RCC_OscConfig(RCC_OscInitTypeDef * RCC_OscInitStruct)312 HAL_StatusTypeDef HAL_RCC_OscConfig(RCC_OscInitTypeDef *RCC_OscInitStruct)
313 {
314 uint32_t tickstart;
315 uint32_t temp_sysclksrc;
316 uint32_t temp_pllckcfg;
317
318 /* Check Null pointer */
319 if (RCC_OscInitStruct == NULL)
320 {
321 return HAL_ERROR;
322 }
323
324 /* Check the parameters */
325 assert_param(IS_RCC_OSCILLATORTYPE(RCC_OscInitStruct->OscillatorType));
326
327 /*------------------------------- HSE Configuration ------------------------*/
328 if (((RCC_OscInitStruct->OscillatorType) & RCC_OSCILLATORTYPE_HSE) == RCC_OSCILLATORTYPE_HSE)
329 {
330 /* Check the parameters */
331 assert_param(IS_RCC_HSE(RCC_OscInitStruct->HSEState));
332
333 temp_sysclksrc = __HAL_RCC_GET_SYSCLK_SOURCE();
334 temp_pllckcfg = __HAL_RCC_GET_PLL_OSCSOURCE();
335
336 /* When the HSE is used as system clock or clock source for PLL in these cases it is not allowed to be disabled */
337 if (((temp_sysclksrc == RCC_CFGR_SWS_PLL) && (temp_pllckcfg == RCC_PLLSOURCE_HSE)) || (temp_sysclksrc == RCC_CFGR_SWS_HSE))
338 {
339 if ((READ_BIT(RCC->CR, RCC_CR_HSERDY) != 0U) && (RCC_OscInitStruct->HSEState == RCC_HSE_OFF))
340 {
341 return HAL_ERROR;
342 }
343 }
344 else
345 {
346 /* Set the new HSE configuration ---------------------------------------*/
347 __HAL_RCC_HSE_CONFIG(RCC_OscInitStruct->HSEState);
348
349 /* Check the HSE State */
350 if (RCC_OscInitStruct->HSEState != RCC_HSE_OFF)
351 {
352 /* Get Start Tick*/
353 tickstart = HAL_GetTick();
354
355 /* Wait till HSE is ready */
356 while (READ_BIT(RCC->CR, RCC_CR_HSERDY) == 0U)
357 {
358 if ((HAL_GetTick() - tickstart) > HSE_TIMEOUT_VALUE)
359 {
360 return HAL_TIMEOUT;
361 }
362 }
363 }
364 else
365 {
366 /* Get Start Tick*/
367 tickstart = HAL_GetTick();
368
369 /* Wait till HSE is disabled */
370 while (READ_BIT(RCC->CR, RCC_CR_HSERDY) != 0U)
371 {
372 if ((HAL_GetTick() - tickstart) > HSE_TIMEOUT_VALUE)
373 {
374 return HAL_TIMEOUT;
375 }
376 }
377 }
378 }
379 }
380 /*----------------------------- HSI Configuration --------------------------*/
381 if (((RCC_OscInitStruct->OscillatorType) & RCC_OSCILLATORTYPE_HSI) == RCC_OSCILLATORTYPE_HSI)
382 {
383 /* Check the parameters */
384 assert_param(IS_RCC_HSI(RCC_OscInitStruct->HSIState));
385 assert_param(IS_RCC_HSI_CALIBRATION_VALUE(RCC_OscInitStruct->HSICalibrationValue));
386
387 /* Check if HSI is used as system clock or as PLL source when PLL is selected as system clock */
388 temp_sysclksrc = __HAL_RCC_GET_SYSCLK_SOURCE();
389 temp_pllckcfg = __HAL_RCC_GET_PLL_OSCSOURCE();
390 if (((temp_sysclksrc == RCC_CFGR_SWS_PLL) && (temp_pllckcfg == RCC_PLLSOURCE_HSI)) || (temp_sysclksrc == RCC_CFGR_SWS_HSI))
391 {
392 /* When HSI is used as system clock it will not be disabled */
393 if ((READ_BIT(RCC->CR, RCC_CR_HSIRDY) != 0U) && (RCC_OscInitStruct->HSIState == RCC_HSI_OFF))
394 {
395 return HAL_ERROR;
396 }
397 /* Otherwise, just the calibration is allowed */
398 else
399 {
400 /* Adjusts the Internal High Speed oscillator (HSI) calibration value.*/
401 __HAL_RCC_HSI_CALIBRATIONVALUE_ADJUST(RCC_OscInitStruct->HSICalibrationValue);
402
403 /* Adapt Systick interrupt period */
404 if (HAL_InitTick(uwTickPrio) != HAL_OK)
405 {
406 return HAL_ERROR;
407 }
408 }
409 }
410 else
411 {
412 /* Check the HSI State */
413 if (RCC_OscInitStruct->HSIState != RCC_HSI_OFF)
414 {
415 /* Enable the Internal High Speed oscillator (HSI). */
416 __HAL_RCC_HSI_ENABLE();
417
418 /* Get Start Tick*/
419 tickstart = HAL_GetTick();
420
421 /* Wait till HSI is ready */
422 while (READ_BIT(RCC->CR, RCC_CR_HSIRDY) == 0U)
423 {
424 if ((HAL_GetTick() - tickstart) > HSI_TIMEOUT_VALUE)
425 {
426 return HAL_TIMEOUT;
427 }
428 }
429
430 /* Adjusts the Internal High Speed oscillator (HSI) calibration value.*/
431 __HAL_RCC_HSI_CALIBRATIONVALUE_ADJUST(RCC_OscInitStruct->HSICalibrationValue);
432 }
433 else
434 {
435 /* Disable the Internal High Speed oscillator (HSI). */
436 __HAL_RCC_HSI_DISABLE();
437
438 /* Get Start Tick*/
439 tickstart = HAL_GetTick();
440
441 /* Wait till HSI is disabled */
442 while (READ_BIT(RCC->CR, RCC_CR_HSIRDY) != 0U)
443 {
444 if ((HAL_GetTick() - tickstart) > HSI_TIMEOUT_VALUE)
445 {
446 return HAL_TIMEOUT;
447 }
448 }
449 }
450 }
451 }
452 /*------------------------------ LSI Configuration -------------------------*/
453 if (((RCC_OscInitStruct->OscillatorType) & RCC_OSCILLATORTYPE_LSI) == RCC_OSCILLATORTYPE_LSI)
454 {
455 /* Check the parameters */
456 assert_param(IS_RCC_LSI(RCC_OscInitStruct->LSIState));
457
458 /* Check the LSI State */
459 if(RCC_OscInitStruct->LSIState != RCC_LSI_OFF)
460 {
461 /* Enable the Internal Low Speed oscillator (LSI). */
462 __HAL_RCC_LSI_ENABLE();
463
464 /* Get Start Tick*/
465 tickstart = HAL_GetTick();
466
467 /* Wait till LSI is ready */
468 while (READ_BIT(RCC->CSR, RCC_CSR_LSIRDY) == 0U)
469 {
470 if ((HAL_GetTick() - tickstart) > LSI_TIMEOUT_VALUE)
471 {
472 return HAL_TIMEOUT;
473 }
474 }
475 }
476 else
477 {
478 /* Disable the Internal Low Speed oscillator (LSI). */
479 __HAL_RCC_LSI_DISABLE();
480
481 /* Get Start Tick*/
482 tickstart = HAL_GetTick();
483
484 /* Wait till LSI is disabled */
485 while(READ_BIT(RCC->CSR, RCC_CSR_LSIRDY) != 0U)
486 {
487 if((HAL_GetTick() - tickstart) > LSI_TIMEOUT_VALUE)
488 {
489 return HAL_TIMEOUT;
490 }
491 }
492 }
493 }
494 /*------------------------------ LSE Configuration -------------------------*/
495 if (((RCC_OscInitStruct->OscillatorType) & RCC_OSCILLATORTYPE_LSE) == RCC_OSCILLATORTYPE_LSE)
496 {
497 FlagStatus pwrclkchanged = RESET;
498
499 /* Check the parameters */
500 assert_param(IS_RCC_LSE(RCC_OscInitStruct->LSEState));
501
502 /* Update LSE configuration in Backup Domain control register */
503 /* Requires to enable write access to Backup Domain if necessary */
504 if (__HAL_RCC_PWR_IS_CLK_DISABLED() != 0U)
505 {
506 __HAL_RCC_PWR_CLK_ENABLE();
507 pwrclkchanged = SET;
508 }
509
510 if (HAL_IS_BIT_CLR(PWR->CR1, PWR_CR1_DBP))
511 {
512 /* Enable write access to Backup domain */
513 SET_BIT(PWR->CR1, PWR_CR1_DBP);
514
515 /* Wait for Backup domain Write protection disable */
516 tickstart = HAL_GetTick();
517
518 while (HAL_IS_BIT_CLR(PWR->CR1, PWR_CR1_DBP))
519 {
520 if ((HAL_GetTick() - tickstart) > RCC_DBP_TIMEOUT_VALUE)
521 {
522 return HAL_TIMEOUT;
523 }
524 }
525 }
526
527 /* Set the new LSE configuration -----------------------------------------*/
528 __HAL_RCC_LSE_CONFIG(RCC_OscInitStruct->LSEState);
529
530 /* Check the LSE State */
531 if (RCC_OscInitStruct->LSEState != RCC_LSE_OFF)
532 {
533 /* Get Start Tick*/
534 tickstart = HAL_GetTick();
535
536 /* Wait till LSE is ready */
537 while (READ_BIT(RCC->BDCR, RCC_BDCR_LSERDY) == 0U)
538 {
539 if((HAL_GetTick() - tickstart) > RCC_LSE_TIMEOUT_VALUE)
540 {
541 return HAL_TIMEOUT;
542 }
543 }
544 }
545 else
546 {
547 /* Get Start Tick*/
548 tickstart = HAL_GetTick();
549
550 /* Wait till LSE is disabled */
551 while (READ_BIT(RCC->BDCR, RCC_BDCR_LSERDY) != 0U)
552 {
553 if((HAL_GetTick() - tickstart) > RCC_LSE_TIMEOUT_VALUE)
554 {
555 return HAL_TIMEOUT;
556 }
557 }
558 }
559
560 /* Restore clock configuration if changed */
561 if (pwrclkchanged == SET)
562 {
563 __HAL_RCC_PWR_CLK_DISABLE();
564 }
565 }
566
567 /*------------------------------ HSI48 Configuration -----------------------*/
568 if(((RCC_OscInitStruct->OscillatorType) & RCC_OSCILLATORTYPE_HSI48) == RCC_OSCILLATORTYPE_HSI48)
569 {
570 /* Check the parameters */
571 assert_param(IS_RCC_HSI48(RCC_OscInitStruct->HSI48State));
572
573 /* Check the HSI48 State */
574 if(RCC_OscInitStruct->HSI48State != RCC_HSI48_OFF)
575 {
576 /* Enable the Internal Low Speed oscillator (HSI48). */
577 __HAL_RCC_HSI48_ENABLE();
578
579 /* Get Start Tick*/
580 tickstart = HAL_GetTick();
581
582 /* Wait till HSI48 is ready */
583 while(READ_BIT(RCC->CRRCR, RCC_CRRCR_HSI48RDY) == 0U)
584 {
585 if((HAL_GetTick() - tickstart) > HSI48_TIMEOUT_VALUE)
586 {
587 return HAL_TIMEOUT;
588 }
589 }
590 }
591 else
592 {
593 /* Disable the Internal Low Speed oscillator (HSI48). */
594 __HAL_RCC_HSI48_DISABLE();
595
596 /* Get Start Tick*/
597 tickstart = HAL_GetTick();
598
599 /* Wait till HSI48 is disabled */
600 while(READ_BIT(RCC->CRRCR, RCC_CRRCR_HSI48RDY) != 0U)
601 {
602 if((HAL_GetTick() - tickstart) > HSI48_TIMEOUT_VALUE)
603 {
604 return HAL_TIMEOUT;
605 }
606 }
607 }
608 }
609
610 /*-------------------------------- PLL Configuration -----------------------*/
611 /* Check the parameters */
612 assert_param(IS_RCC_PLL(RCC_OscInitStruct->PLL.PLLState));
613
614 if (RCC_OscInitStruct->PLL.PLLState != RCC_PLL_NONE)
615 {
616 /* Check if the PLL is used as system clock or not */
617 if (__HAL_RCC_GET_SYSCLK_SOURCE() != RCC_CFGR_SWS_PLL)
618 {
619 if (RCC_OscInitStruct->PLL.PLLState == RCC_PLL_ON)
620 {
621 /* Check the parameters */
622 assert_param(IS_RCC_PLLSOURCE(RCC_OscInitStruct->PLL.PLLSource));
623 assert_param(IS_RCC_PLLM_VALUE(RCC_OscInitStruct->PLL.PLLM));
624 assert_param(IS_RCC_PLLN_VALUE(RCC_OscInitStruct->PLL.PLLN));
625 assert_param(IS_RCC_PLLP_VALUE(RCC_OscInitStruct->PLL.PLLP));
626 assert_param(IS_RCC_PLLQ_VALUE(RCC_OscInitStruct->PLL.PLLQ));
627 assert_param(IS_RCC_PLLR_VALUE(RCC_OscInitStruct->PLL.PLLR));
628
629 /* Disable the main PLL. */
630 __HAL_RCC_PLL_DISABLE();
631
632 /* Get Start Tick*/
633 tickstart = HAL_GetTick();
634
635 /* Wait till PLL is disabled */
636 while (READ_BIT(RCC->CR, RCC_CR_PLLRDY) != 0U)
637 {
638 if ((HAL_GetTick() - tickstart) > PLL_TIMEOUT_VALUE)
639 {
640 return HAL_TIMEOUT;
641 }
642 }
643
644 /* Configure the main PLL clock source, multiplication and division factors. */
645 __HAL_RCC_PLL_CONFIG(RCC_OscInitStruct->PLL.PLLSource,
646 RCC_OscInitStruct->PLL.PLLM,
647 RCC_OscInitStruct->PLL.PLLN,
648 RCC_OscInitStruct->PLL.PLLP,
649 RCC_OscInitStruct->PLL.PLLQ,
650 RCC_OscInitStruct->PLL.PLLR);
651
652 /* Enable the main PLL. */
653 __HAL_RCC_PLL_ENABLE();
654
655 /* Enable PLL System Clock output. */
656 __HAL_RCC_PLLCLKOUT_ENABLE(RCC_PLL_SYSCLK);
657
658 /* Get Start Tick*/
659 tickstart = HAL_GetTick();
660
661 /* Wait till PLL is ready */
662 while (READ_BIT(RCC->CR, RCC_CR_PLLRDY) == 0U)
663 {
664 if ((HAL_GetTick() - tickstart) > PLL_TIMEOUT_VALUE)
665 {
666 return HAL_TIMEOUT;
667 }
668 }
669 }
670 else
671 {
672 /* Disable the main PLL. */
673 __HAL_RCC_PLL_DISABLE();
674
675 /* Get Start Tick*/
676 tickstart = HAL_GetTick();
677
678 /* Wait till PLL is disabled */
679 while (READ_BIT(RCC->CR, RCC_CR_PLLRDY) != 0U)
680 {
681 if ((HAL_GetTick() - tickstart) > PLL_TIMEOUT_VALUE)
682 {
683 return HAL_TIMEOUT;
684 }
685 }
686
687 /* Unselect PLL clock source and disable outputs to save power */
688 RCC->PLLCFGR &= ~(RCC_PLLCFGR_PLLSRC | RCC_PLL_SYSCLK | RCC_PLL_48M1CLK | RCC_PLL_ADCCLK);
689 }
690 }
691 else
692 {
693 /* Check if there is a request to disable the PLL used as System clock source */
694 if((RCC_OscInitStruct->PLL.PLLState) == RCC_PLL_OFF)
695 {
696 return HAL_ERROR;
697 }
698 else
699 {
700 /* Do not return HAL_ERROR if request repeats the current configuration */
701 temp_pllckcfg = RCC->PLLCFGR;
702 if((READ_BIT(temp_pllckcfg, RCC_PLLCFGR_PLLSRC) != RCC_OscInitStruct->PLL.PLLSource) ||
703 (READ_BIT(temp_pllckcfg, RCC_PLLCFGR_PLLM) != (((RCC_OscInitStruct->PLL.PLLM) - 1U) << RCC_PLLCFGR_PLLM_Pos)) ||
704 (READ_BIT(temp_pllckcfg, RCC_PLLCFGR_PLLN) != ((RCC_OscInitStruct->PLL.PLLN) << RCC_PLLCFGR_PLLN_Pos)) ||
705 (READ_BIT(temp_pllckcfg, RCC_PLLCFGR_PLLPDIV) != ((RCC_OscInitStruct->PLL.PLLP) << RCC_PLLCFGR_PLLPDIV_Pos)) ||
706 (READ_BIT(temp_pllckcfg, RCC_PLLCFGR_PLLQ) != ((((RCC_OscInitStruct->PLL.PLLQ) >> 1U) - 1U) << RCC_PLLCFGR_PLLQ_Pos)) ||
707 (READ_BIT(temp_pllckcfg, RCC_PLLCFGR_PLLR) != ((((RCC_OscInitStruct->PLL.PLLR) >> 1U) - 1U) << RCC_PLLCFGR_PLLR_Pos)))
708 {
709 return HAL_ERROR;
710 }
711 }
712 }
713 }
714
715 return HAL_OK;
716 }
717
718 /**
719 * @brief Initialize the CPU, AHB and APB buses clocks according to the specified
720 * parameters in the RCC_ClkInitStruct.
721 * @param RCC_ClkInitStruct pointer to an RCC_OscInitTypeDef structure that
722 * contains the configuration information for the RCC peripheral.
723 * @param FLatency FLASH Latency
724 * This parameter can be one of the following values:
725 * @arg FLASH_LATENCY_0 FLASH 0 Latency cycle
726 * @arg FLASH_LATENCY_1 FLASH 1 Latency cycle
727 * @arg FLASH_LATENCY_2 FLASH 2 Latency cycles
728 * @arg FLASH_LATENCY_3 FLASH 3 Latency cycles
729 * @arg FLASH_LATENCY_4 FLASH 4 Latency cycles
730 * @arg FLASH_LATENCY_5 FLASH 5 Latency cycles
731 * @arg FLASH_LATENCY_6 FLASH 6 Latency cycles
732 * @arg FLASH_LATENCY_7 FLASH 7 Latency cycles
733 * @arg FLASH_LATENCY_8 FLASH 8 Latency cycles
734 * @arg FLASH_LATENCY_9 FLASH 9 Latency cycles
735 * @arg FLASH_LATENCY_10 FLASH 10 Latency cycles
736 * @arg FLASH_LATENCY_11 FLASH 11 Latency cycles
737 * @arg FLASH_LATENCY_12 FLASH 12 Latency cycles
738 * @arg FLASH_LATENCY_13 FLASH 13 Latency cycles
739 * @arg FLASH_LATENCY_14 FLASH 14 Latency cycles
740 * @arg FLASH_LATENCY_15 FLASH 15 Latency cycles
741 *
742 * @note The SystemCoreClock CMSIS variable is used to store System Clock Frequency
743 * and updated by HAL_RCC_GetHCLKFreq() function called within this function
744 *
745 * @note The HSI is used by default as system clock source after
746 * startup from Reset, wake-up from STANDBY mode. After restart from Reset,
747 * the HSI frequency is set to its default value 16 MHz.
748 *
749 * @note The HSI can be selected as system clock source after
750 * from STOP modes or in case of failure of the HSE used directly or indirectly
751 * as system clock (if the Clock Security System CSS is enabled).
752 *
753 * @note A switch from one clock source to another occurs only if the target
754 * clock source is ready (clock stable after startup delay or PLL locked).
755 * If a clock source which is not yet ready is selected, the switch will
756 * occur when the clock source is ready.
757 *
758 * @note You can use HAL_RCC_GetClockConfig() function to know which clock is
759 * currently used as system clock source.
760 *
761 * @note Depending on the device voltage range, the software has to set correctly
762 * HPRE[3:0] bits to ensure that HCLK not exceed the maximum allowed frequency
763 * (for more details refer to section above "Initialization/de-initialization functions")
764 * @retval None
765 */
HAL_RCC_ClockConfig(RCC_ClkInitTypeDef * RCC_ClkInitStruct,uint32_t FLatency)766 HAL_StatusTypeDef HAL_RCC_ClockConfig(RCC_ClkInitTypeDef *RCC_ClkInitStruct, uint32_t FLatency)
767 {
768 uint32_t tickstart;
769 uint32_t pllfreq;
770 uint32_t hpre = RCC_SYSCLK_DIV1;
771
772 /* Check Null pointer */
773 if (RCC_ClkInitStruct == NULL)
774 {
775 return HAL_ERROR;
776 }
777
778 /* Check the parameters */
779 assert_param(IS_RCC_CLOCKTYPE(RCC_ClkInitStruct->ClockType));
780 assert_param(IS_FLASH_LATENCY(FLatency));
781
782 /* To correctly read data from FLASH memory, the number of wait states (LATENCY)
783 must be correctly programmed according to the frequency of the CPU clock
784 (HCLK) and the supply voltage of the device. */
785
786 /* Increasing the number of wait states because of higher CPU frequency */
787 if (FLatency > __HAL_FLASH_GET_LATENCY())
788 {
789 /* Program the new number of wait states to the LATENCY bits in the FLASH_ACR register */
790 __HAL_FLASH_SET_LATENCY(FLatency);
791
792 /* Check that the new number of wait states is taken into account to access the Flash
793 memory by reading the FLASH_ACR register */
794 if (__HAL_FLASH_GET_LATENCY() != FLatency)
795 {
796 return HAL_ERROR;
797 }
798 }
799
800 /*------------------------- SYSCLK Configuration ---------------------------*/
801 if(((RCC_ClkInitStruct->ClockType) & RCC_CLOCKTYPE_SYSCLK) == RCC_CLOCKTYPE_SYSCLK)
802 {
803 assert_param(IS_RCC_SYSCLKSOURCE(RCC_ClkInitStruct->SYSCLKSource));
804
805 /* PLL is selected as System Clock Source */
806 if (RCC_ClkInitStruct->SYSCLKSource == RCC_SYSCLKSOURCE_PLLCLK)
807 {
808 /* Check the PLL ready flag */
809 if (READ_BIT(RCC->CR, RCC_CR_PLLRDY) == 0U)
810 {
811 return HAL_ERROR;
812 }
813 /* Undershoot management when selection PLL as SYSCLK source and frequency above 80Mhz */
814 /* Compute target PLL output frequency */
815 pllfreq = RCC_GetSysClockFreqFromPLLSource();
816
817 /* Intermediate step with HCLK prescaler 2 necessary before to go over 80Mhz */
818 if(pllfreq > 80000000U)
819 {
820 if (((READ_BIT(RCC->CFGR, RCC_CFGR_HPRE) == RCC_SYSCLK_DIV1)) ||
821 (((((RCC_ClkInitStruct->ClockType) & RCC_CLOCKTYPE_HCLK) == RCC_CLOCKTYPE_HCLK) &&
822 (RCC_ClkInitStruct->AHBCLKDivider == RCC_SYSCLK_DIV1))))
823 {
824 MODIFY_REG(RCC->CFGR, RCC_CFGR_HPRE, RCC_SYSCLK_DIV2);
825 hpre = RCC_SYSCLK_DIV2;
826 }
827 }
828 }
829 else
830 {
831 /* HSE is selected as System Clock Source */
832 if (RCC_ClkInitStruct->SYSCLKSource == RCC_SYSCLKSOURCE_HSE)
833 {
834 /* Check the HSE ready flag */
835 if(READ_BIT(RCC->CR, RCC_CR_HSERDY) == 0U)
836 {
837 return HAL_ERROR;
838 }
839 }
840 /* HSI is selected as System Clock Source */
841 else
842 {
843 /* Check the HSI ready flag */
844 if(READ_BIT(RCC->CR, RCC_CR_HSIRDY) == 0U)
845 {
846 return HAL_ERROR;
847 }
848 }
849 /* Overshoot management when going down from PLL as SYSCLK source and frequency above 80Mhz */
850 pllfreq = HAL_RCC_GetSysClockFreq();
851
852 /* Intermediate step with HCLK prescaler 2 necessary before to go under 80Mhz */
853 if(pllfreq > 80000000U)
854 {
855 MODIFY_REG(RCC->CFGR, RCC_CFGR_HPRE, RCC_SYSCLK_DIV2);
856 hpre = RCC_SYSCLK_DIV2;
857 }
858
859 }
860
861 MODIFY_REG(RCC->CFGR, RCC_CFGR_SW, RCC_ClkInitStruct->SYSCLKSource);
862
863 /* Get Start Tick*/
864 tickstart = HAL_GetTick();
865
866 while (__HAL_RCC_GET_SYSCLK_SOURCE() != (RCC_ClkInitStruct->SYSCLKSource << RCC_CFGR_SWS_Pos))
867 {
868 if ((HAL_GetTick() - tickstart) > CLOCKSWITCH_TIMEOUT_VALUE)
869 {
870 return HAL_TIMEOUT;
871 }
872 }
873 }
874
875 /*-------------------------- HCLK Configuration --------------------------*/
876 if (((RCC_ClkInitStruct->ClockType) & RCC_CLOCKTYPE_HCLK) == RCC_CLOCKTYPE_HCLK)
877 {
878 /* Set the highest APB divider in order to ensure that we do not go through
879 a non-spec phase whatever we decrease or increase HCLK. */
880 if (((RCC_ClkInitStruct->ClockType) & RCC_CLOCKTYPE_PCLK1) == RCC_CLOCKTYPE_PCLK1)
881 {
882 MODIFY_REG(RCC->CFGR, RCC_CFGR_PPRE1, RCC_HCLK_DIV16);
883 }
884 if (((RCC_ClkInitStruct->ClockType) & RCC_CLOCKTYPE_PCLK2) == RCC_CLOCKTYPE_PCLK2)
885 {
886 MODIFY_REG(RCC->CFGR, RCC_CFGR_PPRE2, RCC_HCLK_DIV16);
887 }
888
889 /* Set the new HCLK clock divider */
890 assert_param(IS_RCC_HCLK(RCC_ClkInitStruct->AHBCLKDivider));
891 MODIFY_REG(RCC->CFGR, RCC_CFGR_HPRE, RCC_ClkInitStruct->AHBCLKDivider);
892 }
893 else
894 {
895 /* Is intermediate HCLK prescaler 2 applied internally, complete with HCLK prescaler 1 */
896 if(hpre == RCC_SYSCLK_DIV2)
897 {
898 MODIFY_REG(RCC->CFGR, RCC_CFGR_HPRE, RCC_SYSCLK_DIV1);
899 }
900 }
901
902 /* Decreasing the number of wait states because of lower CPU frequency */
903 if (FLatency < __HAL_FLASH_GET_LATENCY())
904 {
905 /* Program the new number of wait states to the LATENCY bits in the FLASH_ACR register */
906 __HAL_FLASH_SET_LATENCY(FLatency);
907
908 /* Check that the new number of wait states is taken into account to access the Flash
909 memory by polling the FLASH_ACR register */
910 tickstart = HAL_GetTick();
911
912 while (__HAL_FLASH_GET_LATENCY() != FLatency)
913 {
914 if ((HAL_GetTick() - tickstart) > CLOCKSWITCH_TIMEOUT_VALUE)
915 {
916 return HAL_TIMEOUT;
917 }
918 }
919 }
920
921 /*-------------------------- PCLK1 Configuration ---------------------------*/
922 if (((RCC_ClkInitStruct->ClockType) & RCC_CLOCKTYPE_PCLK1) == RCC_CLOCKTYPE_PCLK1)
923 {
924 assert_param(IS_RCC_PCLK(RCC_ClkInitStruct->APB1CLKDivider));
925 MODIFY_REG(RCC->CFGR, RCC_CFGR_PPRE1, RCC_ClkInitStruct->APB1CLKDivider);
926 }
927
928 /*-------------------------- PCLK2 Configuration ---------------------------*/
929 if(((RCC_ClkInitStruct->ClockType) & RCC_CLOCKTYPE_PCLK2) == RCC_CLOCKTYPE_PCLK2)
930 {
931 assert_param(IS_RCC_PCLK(RCC_ClkInitStruct->APB2CLKDivider));
932 MODIFY_REG(RCC->CFGR, RCC_CFGR_PPRE2, ((RCC_ClkInitStruct->APB2CLKDivider) << 3U));
933 }
934
935 /* Update the SystemCoreClock global variable */
936 SystemCoreClock = HAL_RCC_GetSysClockFreq() >> (AHBPrescTable[READ_BIT(RCC->CFGR, RCC_CFGR_HPRE) >> RCC_CFGR_HPRE_Pos] & 0x1FU);
937
938 /* Configure the source of time base considering new system clocks settings*/
939 return HAL_InitTick(uwTickPrio);
940 }
941
942 /**
943 * @}
944 */
945
946 /** @defgroup RCC_Exported_Functions_Group2 Peripheral Control functions
947 * @brief RCC clocks control functions
948 *
949 @verbatim
950 ===============================================================================
951 ##### Peripheral Control functions #####
952 ===============================================================================
953 [..]
954 This subsection provides a set of functions allowing to:
955
956 (+) Output clock to MCO pin.
957 (+) Retrieve current clock frequencies.
958 (+) Enable the Clock Security System.
959
960 @endverbatim
961 * @{
962 */
963
964 /**
965 * @brief Select the clock source to output on MCO pin(PA8/PG10).
966 * @note PA8/PG10 should be configured in alternate function mode.
967 * @note The default configuration of the GPIOG pin 10 (PG10) is set to reset mode (NRST pin)
968 * and user shall set the NRST_MODE Bit in the FLASH OPTR register to be able to use it
969 * as an MCO pin.
970 * The @ref HAL_FLASHEx_OBProgram() API can be used to configure the NRST_MODE Bit value.
971 * @param RCC_MCOx specifies the output direction for the clock source.
972 * For STM32G4xx family this parameter can have only one value:
973 * @arg @ref RCC_MCO_PA8 Clock source to output on MCO1 pin(PA8).
974 * @arg @ref RCC_MCO_PG10 Clock source to output on MCO1 pin(PG10).
975 * @param RCC_MCOSource specifies the clock source to output.
976 * This parameter can be one of the following values:
977 * @arg @ref RCC_MCO1SOURCE_NOCLOCK MCO output disabled, no clock on MCO
978 * @arg @ref RCC_MCO1SOURCE_SYSCLK system clock selected as MCO source
979 * @arg @ref RCC_MCO1SOURCE_HSI HSI clock selected as MCO source
980 * @arg @ref RCC_MCO1SOURCE_HSE HSE clock selected as MCO source
981 * @arg @ref RCC_MCO1SOURCE_PLLCLK main PLL clock selected as MCO source
982 * @arg @ref RCC_MCO1SOURCE_LSI LSI clock selected as MCO source
983 * @arg @ref RCC_MCO1SOURCE_LSE LSE clock selected as MCO source
984 * @arg @ref RCC_MCO1SOURCE_HSI48 HSI48 clock selected as MCO source for devices with HSI48
985 * @param RCC_MCODiv specifies the MCO prescaler.
986 * This parameter can be one of the following values:
987 * @arg @ref RCC_MCODIV_1 no division applied to MCO clock
988 * @arg @ref RCC_MCODIV_2 division by 2 applied to MCO clock
989 * @arg @ref RCC_MCODIV_4 division by 4 applied to MCO clock
990 * @arg @ref RCC_MCODIV_8 division by 8 applied to MCO clock
991 * @arg @ref RCC_MCODIV_16 division by 16 applied to MCO clock
992 * @retval None
993 */
HAL_RCC_MCOConfig(uint32_t RCC_MCOx,uint32_t RCC_MCOSource,uint32_t RCC_MCODiv)994 void HAL_RCC_MCOConfig(uint32_t RCC_MCOx, uint32_t RCC_MCOSource, uint32_t RCC_MCODiv)
995 {
996 GPIO_InitTypeDef gpio_initstruct;
997 uint32_t mcoindex;
998 uint32_t mco_gpio_index;
999 GPIO_TypeDef * mco_gpio_port;
1000
1001 /* Check the parameters */
1002 assert_param(IS_RCC_MCO(RCC_MCOx));
1003
1004 /* Common GPIO init parameters */
1005 gpio_initstruct.Mode = GPIO_MODE_AF_PP;
1006 gpio_initstruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
1007 gpio_initstruct.Pull = GPIO_NOPULL;
1008
1009 /* Get MCOx selection */
1010 mcoindex = RCC_MCOx & RCC_MCO_INDEX_MASK;
1011
1012 /* Get MCOx GPIO Port */
1013 mco_gpio_port = (GPIO_TypeDef *) RCC_GET_MCO_GPIO_PORT(RCC_MCOx);
1014
1015 /* MCOx Clock Enable */
1016 mco_gpio_index = RCC_GET_MCO_GPIO_INDEX(RCC_MCOx);
1017 SET_BIT(RCC->AHB2ENR, (1UL << mco_gpio_index ));
1018
1019 /* Configure the MCOx pin in alternate function mode */
1020 gpio_initstruct.Pin = RCC_GET_MCO_GPIO_PIN(RCC_MCOx);
1021 gpio_initstruct.Alternate = RCC_GET_MCO_GPIO_AF(RCC_MCOx);
1022 HAL_GPIO_Init(mco_gpio_port, &gpio_initstruct);
1023
1024 if (mcoindex == RCC_MCO1_INDEX)
1025 {
1026 assert_param(IS_RCC_MCODIV(RCC_MCODiv));
1027 assert_param(IS_RCC_MCO1SOURCE(RCC_MCOSource));
1028 /* Mask MCOSEL[] and MCOPRE[] bits then set MCO clock source and prescaler */
1029 MODIFY_REG(RCC->CFGR, (RCC_CFGR_MCOSEL | RCC_CFGR_MCOPRE), (RCC_MCOSource | RCC_MCODiv));
1030 }
1031 }
1032
1033 /**
1034 * @brief Return the SYSCLK frequency.
1035 *
1036 * @note The system frequency computed by this function is not the real
1037 * frequency in the chip. It is calculated based on the predefined
1038 * constant and the selected clock source:
1039 * @note If SYSCLK source is HSI, function returns values based on HSI_VALUE(*)
1040 * @note If SYSCLK source is HSE, function returns values based on HSE_VALUE(**)
1041 * @note If SYSCLK source is PLL, function returns values based on HSE_VALUE(**),
1042 * HSI_VALUE(*) Value multiplied/divided by the PLL factors.
1043 * @note (*) HSI_VALUE is a constant defined in stm32g4xx_hal_conf.h file (default value
1044 * 16 MHz) but the real value may vary depending on the variations
1045 * in voltage and temperature.
1046 * @note (**) HSE_VALUE is a constant defined in stm32g4xx_hal_conf.h file (default value
1047 * 8 MHz), user has to ensure that HSE_VALUE is same as the real
1048 * frequency of the crystal used. Otherwise, this function may
1049 * have wrong result.
1050 *
1051 * @note The result of this function could be not correct when using fractional
1052 * value for HSE crystal.
1053 *
1054 * @note This function can be used by the user application to compute the
1055 * baudrate for the communication peripherals or configure other parameters.
1056 *
1057 * @note Each time SYSCLK changes, this function must be called to update the
1058 * right SYSCLK value. Otherwise, any configuration based on this function will be incorrect.
1059 *
1060 *
1061 * @retval SYSCLK frequency
1062 */
HAL_RCC_GetSysClockFreq(void)1063 uint32_t HAL_RCC_GetSysClockFreq(void)
1064 {
1065 uint32_t pllvco, pllsource, pllr, pllm;
1066 uint32_t sysclockfreq;
1067
1068 if (__HAL_RCC_GET_SYSCLK_SOURCE() == RCC_CFGR_SWS_HSI)
1069 {
1070 /* HSI used as system clock source */
1071 sysclockfreq = HSI_VALUE;
1072 }
1073 else if (__HAL_RCC_GET_SYSCLK_SOURCE() == RCC_CFGR_SWS_HSE)
1074 {
1075 /* HSE used as system clock source */
1076 sysclockfreq = HSE_VALUE;
1077 }
1078 else if (__HAL_RCC_GET_SYSCLK_SOURCE() == RCC_CFGR_SWS_PLL)
1079 {
1080 /* PLL used as system clock source */
1081
1082 /* PLL_VCO = ((HSE_VALUE or HSI_VALUE)/ PLLM) * PLLN
1083 SYSCLK = PLL_VCO / PLLR
1084 */
1085 pllsource = READ_BIT(RCC->PLLCFGR, RCC_PLLCFGR_PLLSRC);
1086 pllm = (READ_BIT(RCC->PLLCFGR, RCC_PLLCFGR_PLLM) >> RCC_PLLCFGR_PLLM_Pos) + 1U ;
1087
1088 switch (pllsource)
1089 {
1090 case RCC_PLLSOURCE_HSE: /* HSE used as PLL clock source */
1091 pllvco = (HSE_VALUE / pllm) * (READ_BIT(RCC->PLLCFGR, RCC_PLLCFGR_PLLN) >> RCC_PLLCFGR_PLLN_Pos);
1092 break;
1093
1094 case RCC_PLLSOURCE_HSI: /* HSI used as PLL clock source */
1095 default:
1096 pllvco = (HSI_VALUE / pllm) * (READ_BIT(RCC->PLLCFGR, RCC_PLLCFGR_PLLN) >> RCC_PLLCFGR_PLLN_Pos);
1097 break;
1098 }
1099 pllr = ((READ_BIT(RCC->PLLCFGR, RCC_PLLCFGR_PLLR) >> RCC_PLLCFGR_PLLR_Pos) + 1U ) * 2U;
1100 sysclockfreq = pllvco/pllr;
1101 }
1102 else
1103 {
1104 sysclockfreq = 0U;
1105 }
1106
1107 return sysclockfreq;
1108 }
1109
1110 /**
1111 * @brief Return the HCLK frequency.
1112 * @note Each time HCLK changes, this function must be called to update the
1113 * right HCLK value. Otherwise, any configuration based on this function will be incorrect.
1114 *
1115 * @note The SystemCoreClock CMSIS variable is used to store System Clock Frequency.
1116 * @retval HCLK frequency in Hz
1117 */
HAL_RCC_GetHCLKFreq(void)1118 uint32_t HAL_RCC_GetHCLKFreq(void)
1119 {
1120 return SystemCoreClock;
1121 }
1122
1123 /**
1124 * @brief Return the PCLK1 frequency.
1125 * @note Each time PCLK1 changes, this function must be called to update the
1126 * right PCLK1 value. Otherwise, any configuration based on this function will be incorrect.
1127 * @retval PCLK1 frequency in Hz
1128 */
HAL_RCC_GetPCLK1Freq(void)1129 uint32_t HAL_RCC_GetPCLK1Freq(void)
1130 {
1131 /* Get HCLK source and Compute PCLK1 frequency ---------------------------*/
1132 return (HAL_RCC_GetHCLKFreq() >> (APBPrescTable[READ_BIT(RCC->CFGR, RCC_CFGR_PPRE1) >> RCC_CFGR_PPRE1_Pos] & 0x1FU));
1133 }
1134
1135 /**
1136 * @brief Return the PCLK2 frequency.
1137 * @note Each time PCLK2 changes, this function must be called to update the
1138 * right PCLK2 value. Otherwise, any configuration based on this function will be incorrect.
1139 * @retval PCLK2 frequency in Hz
1140 */
HAL_RCC_GetPCLK2Freq(void)1141 uint32_t HAL_RCC_GetPCLK2Freq(void)
1142 {
1143 /* Get HCLK source and Compute PCLK2 frequency ---------------------------*/
1144 return (HAL_RCC_GetHCLKFreq()>> (APBPrescTable[READ_BIT(RCC->CFGR, RCC_CFGR_PPRE2) >> RCC_CFGR_PPRE2_Pos] & 0x1FU));
1145 }
1146
1147 /**
1148 * @brief Configure the RCC_OscInitStruct according to the internal
1149 * RCC configuration registers.
1150 * @param RCC_OscInitStruct pointer to an RCC_OscInitTypeDef structure that
1151 * will be configured.
1152 * @retval None
1153 */
HAL_RCC_GetOscConfig(RCC_OscInitTypeDef * RCC_OscInitStruct)1154 void HAL_RCC_GetOscConfig(RCC_OscInitTypeDef *RCC_OscInitStruct)
1155 {
1156 /* Check the parameters */
1157 assert_param(RCC_OscInitStruct != (void *)NULL);
1158
1159 /* Set all possible values for the Oscillator type parameter ---------------*/
1160 RCC_OscInitStruct->OscillatorType = RCC_OSCILLATORTYPE_HSE | RCC_OSCILLATORTYPE_HSI | \
1161 RCC_OSCILLATORTYPE_LSE | RCC_OSCILLATORTYPE_LSI | RCC_OSCILLATORTYPE_HSI48;
1162
1163 /* Get the HSE configuration -----------------------------------------------*/
1164 if(READ_BIT(RCC->CR, RCC_CR_HSEBYP) == RCC_CR_HSEBYP)
1165 {
1166 RCC_OscInitStruct->HSEState = RCC_HSE_BYPASS;
1167 }
1168 else if(READ_BIT(RCC->CR, RCC_CR_HSEON) == RCC_CR_HSEON)
1169 {
1170 RCC_OscInitStruct->HSEState = RCC_HSE_ON;
1171 }
1172 else
1173 {
1174 RCC_OscInitStruct->HSEState = RCC_HSE_OFF;
1175 }
1176
1177 /* Get the HSI configuration -----------------------------------------------*/
1178 if(READ_BIT(RCC->CR, RCC_CR_HSION) == RCC_CR_HSION)
1179 {
1180 RCC_OscInitStruct->HSIState = RCC_HSI_ON;
1181 }
1182 else
1183 {
1184 RCC_OscInitStruct->HSIState = RCC_HSI_OFF;
1185 }
1186
1187 RCC_OscInitStruct->HSICalibrationValue = READ_BIT(RCC->ICSCR, RCC_ICSCR_HSITRIM) >> RCC_ICSCR_HSITRIM_Pos;
1188
1189 /* Get the LSE configuration -----------------------------------------------*/
1190 if(READ_BIT(RCC->BDCR, RCC_BDCR_LSEBYP) == RCC_BDCR_LSEBYP)
1191 {
1192 RCC_OscInitStruct->LSEState = RCC_LSE_BYPASS;
1193 }
1194 else if(READ_BIT(RCC->BDCR, RCC_BDCR_LSEON) == RCC_BDCR_LSEON)
1195 {
1196 RCC_OscInitStruct->LSEState = RCC_LSE_ON;
1197 }
1198 else
1199 {
1200 RCC_OscInitStruct->LSEState = RCC_LSE_OFF;
1201 }
1202
1203 /* Get the LSI configuration -----------------------------------------------*/
1204 if(READ_BIT(RCC->CSR, RCC_CSR_LSION) == RCC_CSR_LSION)
1205 {
1206 RCC_OscInitStruct->LSIState = RCC_LSI_ON;
1207 }
1208 else
1209 {
1210 RCC_OscInitStruct->LSIState = RCC_LSI_OFF;
1211 }
1212
1213 /* Get the HSI48 configuration ---------------------------------------------*/
1214 if(READ_BIT(RCC->CRRCR, RCC_CRRCR_HSI48ON) == RCC_CRRCR_HSI48ON)
1215 {
1216 RCC_OscInitStruct->HSI48State = RCC_HSI48_ON;
1217 }
1218 else
1219 {
1220 RCC_OscInitStruct->HSI48State = RCC_HSI48_OFF;
1221 }
1222
1223 /* Get the PLL configuration -----------------------------------------------*/
1224 if(READ_BIT(RCC->CR, RCC_CR_PLLON) == RCC_CR_PLLON)
1225 {
1226 RCC_OscInitStruct->PLL.PLLState = RCC_PLL_ON;
1227 }
1228 else
1229 {
1230 RCC_OscInitStruct->PLL.PLLState = RCC_PLL_OFF;
1231 }
1232 RCC_OscInitStruct->PLL.PLLSource = READ_BIT(RCC->PLLCFGR, RCC_PLLCFGR_PLLSRC);
1233 RCC_OscInitStruct->PLL.PLLM = (READ_BIT(RCC->PLLCFGR, RCC_PLLCFGR_PLLM) >> RCC_PLLCFGR_PLLM_Pos) + 1U;
1234 RCC_OscInitStruct->PLL.PLLN = READ_BIT(RCC->PLLCFGR, RCC_PLLCFGR_PLLN) >> RCC_PLLCFGR_PLLN_Pos;
1235 RCC_OscInitStruct->PLL.PLLQ = (((READ_BIT(RCC->PLLCFGR, RCC_PLLCFGR_PLLQ) >> RCC_PLLCFGR_PLLQ_Pos) + 1U) << 1U);
1236 RCC_OscInitStruct->PLL.PLLR = (((READ_BIT(RCC->PLLCFGR, RCC_PLLCFGR_PLLR) >> RCC_PLLCFGR_PLLR_Pos) + 1U) << 1U);
1237 RCC_OscInitStruct->PLL.PLLP = READ_BIT(RCC->PLLCFGR, RCC_PLLCFGR_PLLPDIV) >> RCC_PLLCFGR_PLLPDIV_Pos;
1238 }
1239
1240 /**
1241 * @brief Configure the RCC_ClkInitStruct according to the internal
1242 * RCC configuration registers.
1243 * @param RCC_ClkInitStruct pointer to an RCC_ClkInitTypeDef structure that
1244 * will be configured.
1245 * @param pFLatency Pointer on the Flash Latency.
1246 * @retval None
1247 */
HAL_RCC_GetClockConfig(RCC_ClkInitTypeDef * RCC_ClkInitStruct,uint32_t * pFLatency)1248 void HAL_RCC_GetClockConfig(RCC_ClkInitTypeDef *RCC_ClkInitStruct, uint32_t *pFLatency)
1249 {
1250 /* Check the parameters */
1251 assert_param(RCC_ClkInitStruct != (void *)NULL);
1252 assert_param(pFLatency != (void *)NULL);
1253
1254 /* Set all possible values for the Clock type parameter --------------------*/
1255 RCC_ClkInitStruct->ClockType = RCC_CLOCKTYPE_SYSCLK | RCC_CLOCKTYPE_HCLK | RCC_CLOCKTYPE_PCLK1 | RCC_CLOCKTYPE_PCLK2;
1256
1257 /* Get the SYSCLK configuration --------------------------------------------*/
1258 RCC_ClkInitStruct->SYSCLKSource = READ_BIT(RCC->CFGR, RCC_CFGR_SW);
1259
1260 /* Get the HCLK configuration ----------------------------------------------*/
1261 RCC_ClkInitStruct->AHBCLKDivider = READ_BIT(RCC->CFGR, RCC_CFGR_HPRE);
1262
1263 /* Get the APB1 configuration ----------------------------------------------*/
1264 RCC_ClkInitStruct->APB1CLKDivider = READ_BIT(RCC->CFGR, RCC_CFGR_PPRE1);
1265
1266 /* Get the APB2 configuration ----------------------------------------------*/
1267 RCC_ClkInitStruct->APB2CLKDivider = (READ_BIT(RCC->CFGR, RCC_CFGR_PPRE2) >> 3U);
1268
1269 /* Get the Flash Wait State (Latency) configuration ------------------------*/
1270 *pFLatency = __HAL_FLASH_GET_LATENCY();
1271 }
1272
1273 /**
1274 * @brief Enable the Clock Security System.
1275 * @note If a failure is detected on the HSE oscillator clock, this oscillator
1276 * is automatically disabled and an interrupt is generated to inform the
1277 * software about the failure (Clock Security System Interrupt, CSSI),
1278 * allowing the MCU to perform rescue operations. The CSSI is linked to
1279 * the Cortex-M4 NMI (Non-Maskable Interrupt) exception vector.
1280 * @note The Clock Security System can only be cleared by reset.
1281 * @retval None
1282 */
HAL_RCC_EnableCSS(void)1283 void HAL_RCC_EnableCSS(void)
1284 {
1285 SET_BIT(RCC->CR, RCC_CR_CSSON) ;
1286 }
1287
1288 /**
1289 * @brief Enable the LSE Clock Security System.
1290 * @note If a failure is detected on the external 32 kHz oscillator,
1291 * the LSE clock is no longer supplied to the RTC but no hardware action
1292 * is made to the registers. If enabled, an interrupt will be generated
1293 * and handle through @ref RCCEx_EXTI_LINE_LSECSS
1294 * @note The Clock Security System can only be cleared by reset or after a LSE failure detection.
1295 * @retval None
1296 */
HAL_RCC_EnableLSECSS(void)1297 void HAL_RCC_EnableLSECSS(void)
1298 {
1299 SET_BIT(RCC->BDCR, RCC_BDCR_LSECSSON) ;
1300 }
1301
1302 /**
1303 * @brief Disable the LSE Clock Security System.
1304 * @note After LSE failure detection, the software must disable LSECSSON
1305 * @note The Clock Security System can only be cleared by reset otherwise.
1306 * @retval None
1307 */
HAL_RCC_DisableLSECSS(void)1308 void HAL_RCC_DisableLSECSS(void)
1309 {
1310 CLEAR_BIT(RCC->BDCR, RCC_BDCR_LSECSSON) ;
1311 }
1312
1313 /**
1314 * @brief Handle the RCC Clock Security System interrupt request.
1315 * @note This API should be called under the NMI_Handler().
1316 * @retval None
1317 */
HAL_RCC_NMI_IRQHandler(void)1318 void HAL_RCC_NMI_IRQHandler(void)
1319 {
1320 /* Check RCC CSSF interrupt flag */
1321 if(__HAL_RCC_GET_IT(RCC_IT_CSS))
1322 {
1323 /* RCC Clock Security System interrupt user callback */
1324 HAL_RCC_CSSCallback();
1325
1326 /* Clear RCC CSS pending bit */
1327 __HAL_RCC_CLEAR_IT(RCC_IT_CSS);
1328 }
1329 }
1330
1331 /**
1332 * @brief RCC Clock Security System interrupt callback.
1333 * @retval none
1334 */
HAL_RCC_CSSCallback(void)1335 __weak void HAL_RCC_CSSCallback(void)
1336 {
1337 /* NOTE : This function should not be modified, when the callback is needed,
1338 the HAL_RCC_CSSCallback should be implemented in the user file
1339 */
1340 }
1341
1342 /**
1343 * @}
1344 */
1345
1346 /**
1347 * @}
1348 */
1349
1350 /* Private function prototypes -----------------------------------------------*/
1351 /** @addtogroup RCC_Private_Functions
1352 * @{
1353 */
1354
1355 /**
1356 * @brief Compute SYSCLK frequency based on PLL SYSCLK source.
1357 * @retval SYSCLK frequency
1358 */
RCC_GetSysClockFreqFromPLLSource(void)1359 static uint32_t RCC_GetSysClockFreqFromPLLSource(void)
1360 {
1361 uint32_t pllvco, pllsource, pllr, pllm;
1362 uint32_t sysclockfreq;
1363
1364 /* PLL_VCO = (HSE_VALUE or HSI_VALUE/ PLLM) * PLLN
1365 SYSCLK = PLL_VCO / PLLR
1366 */
1367 pllsource = READ_BIT(RCC->PLLCFGR, RCC_PLLCFGR_PLLSRC);
1368 pllm = (READ_BIT(RCC->PLLCFGR, RCC_PLLCFGR_PLLM) >> RCC_PLLCFGR_PLLM_Pos) + 1U ;
1369
1370 switch (pllsource)
1371 {
1372 case RCC_PLLSOURCE_HSE: /* HSE used as PLL clock source */
1373 pllvco = (HSE_VALUE / pllm) * (READ_BIT(RCC->PLLCFGR, RCC_PLLCFGR_PLLN) >> RCC_PLLCFGR_PLLN_Pos);
1374 break;
1375
1376 case RCC_PLLSOURCE_HSI: /* HSI used as PLL clock source */
1377 default:
1378 pllvco = (HSI_VALUE / pllm) * (READ_BIT(RCC->PLLCFGR, RCC_PLLCFGR_PLLN) >> RCC_PLLCFGR_PLLN_Pos);
1379 break;
1380 }
1381
1382 pllr = ((READ_BIT(RCC->PLLCFGR, RCC_PLLCFGR_PLLR) >> RCC_PLLCFGR_PLLR_Pos) + 1U ) * 2U;
1383 sysclockfreq = pllvco/pllr;
1384
1385 return sysclockfreq;
1386 }
1387
1388 /**
1389 * @}
1390 */
1391
1392 #endif /* HAL_RCC_MODULE_ENABLED */
1393 /**
1394 * @}
1395 */
1396
1397 /**
1398 * @}
1399 */
1400
1401