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 ready */
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 /* Disable all PLL outputs to save power if no PLLs on */
676 MODIFY_REG(RCC->PLLCFGR, RCC_PLLCFGR_PLLSRC, RCC_PLLSOURCE_NONE);
677 __HAL_RCC_PLLCLKOUT_DISABLE(RCC_PLL_SYSCLK | RCC_PLL_48M1CLK | RCC_PLL_ADCCLK);
678
679 /* Get Start Tick*/
680 tickstart = HAL_GetTick();
681
682 /* Wait till PLL is disabled */
683 while (READ_BIT(RCC->CR, RCC_CR_PLLRDY) != 0U)
684 {
685 if ((HAL_GetTick() - tickstart) > PLL_TIMEOUT_VALUE)
686 {
687 return HAL_TIMEOUT;
688 }
689 }
690 }
691 }
692 else
693 {
694 /* Check if there is a request to disable the PLL used as System clock source */
695 if((RCC_OscInitStruct->PLL.PLLState) == RCC_PLL_OFF)
696 {
697 return HAL_ERROR;
698 }
699 else
700 {
701 /* Do not return HAL_ERROR if request repeats the current configuration */
702 temp_pllckcfg = RCC->PLLCFGR;
703 if((READ_BIT(temp_pllckcfg, RCC_PLLCFGR_PLLSRC) != RCC_OscInitStruct->PLL.PLLSource) ||
704 (READ_BIT(temp_pllckcfg, RCC_PLLCFGR_PLLM) != (((RCC_OscInitStruct->PLL.PLLM) - 1U) << RCC_PLLCFGR_PLLM_Pos)) ||
705 (READ_BIT(temp_pllckcfg, RCC_PLLCFGR_PLLN) != ((RCC_OscInitStruct->PLL.PLLN) << RCC_PLLCFGR_PLLN_Pos)) ||
706 (READ_BIT(temp_pllckcfg, RCC_PLLCFGR_PLLPDIV) != ((RCC_OscInitStruct->PLL.PLLP) << RCC_PLLCFGR_PLLPDIV_Pos)) ||
707 (READ_BIT(temp_pllckcfg, RCC_PLLCFGR_PLLQ) != ((((RCC_OscInitStruct->PLL.PLLQ) >> 1U) - 1U) << RCC_PLLCFGR_PLLQ_Pos)) ||
708 (READ_BIT(temp_pllckcfg, RCC_PLLCFGR_PLLR) != ((((RCC_OscInitStruct->PLL.PLLR) >> 1U) - 1U) << RCC_PLLCFGR_PLLR_Pos)))
709 {
710 return HAL_ERROR;
711 }
712 }
713 }
714 }
715
716 return HAL_OK;
717 }
718
719 /**
720 * @brief Initialize the CPU, AHB and APB buses clocks according to the specified
721 * parameters in the RCC_ClkInitStruct.
722 * @param RCC_ClkInitStruct pointer to an RCC_OscInitTypeDef structure that
723 * contains the configuration information for the RCC peripheral.
724 * @param FLatency FLASH Latency
725 * This parameter can be one of the following values:
726 * @arg FLASH_LATENCY_0 FLASH 0 Latency cycle
727 * @arg FLASH_LATENCY_1 FLASH 1 Latency cycle
728 * @arg FLASH_LATENCY_2 FLASH 2 Latency cycles
729 * @arg FLASH_LATENCY_3 FLASH 3 Latency cycles
730 * @arg FLASH_LATENCY_4 FLASH 4 Latency cycles
731 * @arg FLASH_LATENCY_5 FLASH 5 Latency cycles
732 * @arg FLASH_LATENCY_6 FLASH 6 Latency cycles
733 * @arg FLASH_LATENCY_7 FLASH 7 Latency cycles
734 * @arg FLASH_LATENCY_8 FLASH 8 Latency cycles
735 * @arg FLASH_LATENCY_9 FLASH 9 Latency cycles
736 * @arg FLASH_LATENCY_10 FLASH 10 Latency cycles
737 * @arg FLASH_LATENCY_11 FLASH 11 Latency cycles
738 * @arg FLASH_LATENCY_12 FLASH 12 Latency cycles
739 * @arg FLASH_LATENCY_13 FLASH 13 Latency cycles
740 * @arg FLASH_LATENCY_14 FLASH 14 Latency cycles
741 * @arg FLASH_LATENCY_15 FLASH 15 Latency cycles
742 *
743 * @note The SystemCoreClock CMSIS variable is used to store System Clock Frequency
744 * and updated by HAL_RCC_GetHCLKFreq() function called within this function
745 *
746 * @note The HSI is used by default as system clock source after
747 * startup from Reset, wake-up from STANDBY mode. After restart from Reset,
748 * the HSI frequency is set to its default value 16 MHz.
749 *
750 * @note The HSI can be selected as system clock source after
751 * from STOP modes or in case of failure of the HSE used directly or indirectly
752 * as system clock (if the Clock Security System CSS is enabled).
753 *
754 * @note A switch from one clock source to another occurs only if the target
755 * clock source is ready (clock stable after startup delay or PLL locked).
756 * If a clock source which is not yet ready is selected, the switch will
757 * occur when the clock source is ready.
758 *
759 * @note You can use HAL_RCC_GetClockConfig() function to know which clock is
760 * currently used as system clock source.
761 *
762 * @note Depending on the device voltage range, the software has to set correctly
763 * HPRE[3:0] bits to ensure that HCLK not exceed the maximum allowed frequency
764 * (for more details refer to section above "Initialization/de-initialization functions")
765 * @retval None
766 */
HAL_RCC_ClockConfig(RCC_ClkInitTypeDef * RCC_ClkInitStruct,uint32_t FLatency)767 HAL_StatusTypeDef HAL_RCC_ClockConfig(RCC_ClkInitTypeDef *RCC_ClkInitStruct, uint32_t FLatency)
768 {
769 uint32_t tickstart;
770 uint32_t pllfreq;
771 uint32_t hpre = RCC_SYSCLK_DIV1;
772
773 /* Check Null pointer */
774 if (RCC_ClkInitStruct == NULL)
775 {
776 return HAL_ERROR;
777 }
778
779 /* Check the parameters */
780 assert_param(IS_RCC_CLOCKTYPE(RCC_ClkInitStruct->ClockType));
781 assert_param(IS_FLASH_LATENCY(FLatency));
782
783 /* To correctly read data from FLASH memory, the number of wait states (LATENCY)
784 must be correctly programmed according to the frequency of the CPU clock
785 (HCLK) and the supply voltage of the device. */
786
787 /* Increasing the number of wait states because of higher CPU frequency */
788 if (FLatency > __HAL_FLASH_GET_LATENCY())
789 {
790 /* Program the new number of wait states to the LATENCY bits in the FLASH_ACR register */
791 __HAL_FLASH_SET_LATENCY(FLatency);
792
793 /* Check that the new number of wait states is taken into account to access the Flash
794 memory by reading the FLASH_ACR register */
795 if (__HAL_FLASH_GET_LATENCY() != FLatency)
796 {
797 return HAL_ERROR;
798 }
799 }
800
801 /*------------------------- SYSCLK Configuration ---------------------------*/
802 if(((RCC_ClkInitStruct->ClockType) & RCC_CLOCKTYPE_SYSCLK) == RCC_CLOCKTYPE_SYSCLK)
803 {
804 assert_param(IS_RCC_SYSCLKSOURCE(RCC_ClkInitStruct->SYSCLKSource));
805
806 /* PLL is selected as System Clock Source */
807 if (RCC_ClkInitStruct->SYSCLKSource == RCC_SYSCLKSOURCE_PLLCLK)
808 {
809 /* Check the PLL ready flag */
810 if (READ_BIT(RCC->CR, RCC_CR_PLLRDY) == 0U)
811 {
812 return HAL_ERROR;
813 }
814 /* Undershoot management when selection PLL as SYSCLK source and frequency above 80Mhz */
815 /* Compute target PLL output frequency */
816 pllfreq = RCC_GetSysClockFreqFromPLLSource();
817
818 /* Intermediate step with HCLK prescaler 2 necessary before to go over 80Mhz */
819 if(pllfreq > 80000000U)
820 {
821 if (((READ_BIT(RCC->CFGR, RCC_CFGR_HPRE) == RCC_SYSCLK_DIV1)) ||
822 (((((RCC_ClkInitStruct->ClockType) & RCC_CLOCKTYPE_HCLK) == RCC_CLOCKTYPE_HCLK) &&
823 (RCC_ClkInitStruct->AHBCLKDivider == RCC_SYSCLK_DIV1))))
824 {
825 MODIFY_REG(RCC->CFGR, RCC_CFGR_HPRE, RCC_SYSCLK_DIV2);
826 hpre = RCC_SYSCLK_DIV2;
827 }
828 }
829 }
830 else
831 {
832 /* HSE is selected as System Clock Source */
833 if (RCC_ClkInitStruct->SYSCLKSource == RCC_SYSCLKSOURCE_HSE)
834 {
835 /* Check the HSE ready flag */
836 if(READ_BIT(RCC->CR, RCC_CR_HSERDY) == 0U)
837 {
838 return HAL_ERROR;
839 }
840 }
841 /* HSI is selected as System Clock Source */
842 else
843 {
844 /* Check the HSI ready flag */
845 if(READ_BIT(RCC->CR, RCC_CR_HSIRDY) == 0U)
846 {
847 return HAL_ERROR;
848 }
849 }
850 /* Overshoot management when going down from PLL as SYSCLK source and frequency above 80Mhz */
851 pllfreq = HAL_RCC_GetSysClockFreq();
852
853 /* Intermediate step with HCLK prescaler 2 necessary before to go under 80Mhz */
854 if(pllfreq > 80000000U)
855 {
856 MODIFY_REG(RCC->CFGR, RCC_CFGR_HPRE, RCC_SYSCLK_DIV2);
857 hpre = RCC_SYSCLK_DIV2;
858 }
859
860 }
861
862 MODIFY_REG(RCC->CFGR, RCC_CFGR_SW, RCC_ClkInitStruct->SYSCLKSource);
863
864 /* Get Start Tick*/
865 tickstart = HAL_GetTick();
866
867 while (__HAL_RCC_GET_SYSCLK_SOURCE() != (RCC_ClkInitStruct->SYSCLKSource << RCC_CFGR_SWS_Pos))
868 {
869 if ((HAL_GetTick() - tickstart) > CLOCKSWITCH_TIMEOUT_VALUE)
870 {
871 return HAL_TIMEOUT;
872 }
873 }
874 }
875
876 /*-------------------------- HCLK Configuration --------------------------*/
877 if (((RCC_ClkInitStruct->ClockType) & RCC_CLOCKTYPE_HCLK) == RCC_CLOCKTYPE_HCLK)
878 {
879 /* Set the highest APB divider in order to ensure that we do not go through
880 a non-spec phase whatever we decrease or increase HCLK. */
881 if (((RCC_ClkInitStruct->ClockType) & RCC_CLOCKTYPE_PCLK1) == RCC_CLOCKTYPE_PCLK1)
882 {
883 MODIFY_REG(RCC->CFGR, RCC_CFGR_PPRE1, RCC_HCLK_DIV16);
884 }
885 if (((RCC_ClkInitStruct->ClockType) & RCC_CLOCKTYPE_PCLK2) == RCC_CLOCKTYPE_PCLK2)
886 {
887 MODIFY_REG(RCC->CFGR, RCC_CFGR_PPRE2, RCC_HCLK_DIV16);
888 }
889
890 /* Set the new HCLK clock divider */
891 assert_param(IS_RCC_HCLK(RCC_ClkInitStruct->AHBCLKDivider));
892 MODIFY_REG(RCC->CFGR, RCC_CFGR_HPRE, RCC_ClkInitStruct->AHBCLKDivider);
893 }
894 else
895 {
896 /* Is intermediate HCLK prescaler 2 applied internally, complete with HCLK prescaler 1 */
897 if(hpre == RCC_SYSCLK_DIV2)
898 {
899 MODIFY_REG(RCC->CFGR, RCC_CFGR_HPRE, RCC_SYSCLK_DIV1);
900 }
901 }
902
903 /* Decreasing the number of wait states because of lower CPU frequency */
904 if (FLatency < __HAL_FLASH_GET_LATENCY())
905 {
906 /* Program the new number of wait states to the LATENCY bits in the FLASH_ACR register */
907 __HAL_FLASH_SET_LATENCY(FLatency);
908
909 /* Check that the new number of wait states is taken into account to access the Flash
910 memory by polling the FLASH_ACR register */
911 tickstart = HAL_GetTick();
912
913 while (__HAL_FLASH_GET_LATENCY() != FLatency)
914 {
915 if ((HAL_GetTick() - tickstart) > CLOCKSWITCH_TIMEOUT_VALUE)
916 {
917 return HAL_TIMEOUT;
918 }
919 }
920 }
921
922 /*-------------------------- PCLK1 Configuration ---------------------------*/
923 if (((RCC_ClkInitStruct->ClockType) & RCC_CLOCKTYPE_PCLK1) == RCC_CLOCKTYPE_PCLK1)
924 {
925 assert_param(IS_RCC_PCLK(RCC_ClkInitStruct->APB1CLKDivider));
926 MODIFY_REG(RCC->CFGR, RCC_CFGR_PPRE1, RCC_ClkInitStruct->APB1CLKDivider);
927 }
928
929 /*-------------------------- PCLK2 Configuration ---------------------------*/
930 if(((RCC_ClkInitStruct->ClockType) & RCC_CLOCKTYPE_PCLK2) == RCC_CLOCKTYPE_PCLK2)
931 {
932 assert_param(IS_RCC_PCLK(RCC_ClkInitStruct->APB2CLKDivider));
933 MODIFY_REG(RCC->CFGR, RCC_CFGR_PPRE2, ((RCC_ClkInitStruct->APB2CLKDivider) << 3U));
934 }
935
936 /* Update the SystemCoreClock global variable */
937 SystemCoreClock = HAL_RCC_GetSysClockFreq() >> (AHBPrescTable[READ_BIT(RCC->CFGR, RCC_CFGR_HPRE) >> RCC_CFGR_HPRE_Pos] & 0x1FU);
938
939 /* Configure the source of time base considering new system clocks settings*/
940 return HAL_InitTick(uwTickPrio);
941 }
942
943 /**
944 * @}
945 */
946
947 /** @defgroup RCC_Exported_Functions_Group2 Peripheral Control functions
948 * @brief RCC clocks control functions
949 *
950 @verbatim
951 ===============================================================================
952 ##### Peripheral Control functions #####
953 ===============================================================================
954 [..]
955 This subsection provides a set of functions allowing to:
956
957 (+) Output clock to MCO pin.
958 (+) Retrieve current clock frequencies.
959 (+) Enable the Clock Security System.
960
961 @endverbatim
962 * @{
963 */
964
965 /**
966 * @brief Select the clock source to output on MCO pin(PA8/PG10).
967 * @note PA8/PG10 should be configured in alternate function mode.
968 * @note The default configuration of the GPIOG pin 10 (PG10) is set to reset mode (NRST pin)
969 * and user shall set the NRST_MODE Bit in the FLASH OPTR register to be able to use it
970 * as an MCO pin.
971 * The @ref HAL_FLASHEx_OBProgram() API can be used to configure the NRST_MODE Bit value.
972 * @param RCC_MCOx specifies the output direction for the clock source.
973 * For STM32G4xx family this parameter can have only one value:
974 * @arg @ref RCC_MCO_PA8 Clock source to output on MCO1 pin(PA8).
975 * @arg @ref RCC_MCO_PG10 Clock source to output on MCO1 pin(PG10).
976 * @param RCC_MCOSource specifies the clock source to output.
977 * This parameter can be one of the following values:
978 * @arg @ref RCC_MCO1SOURCE_NOCLOCK MCO output disabled, no clock on MCO
979 * @arg @ref RCC_MCO1SOURCE_SYSCLK system clock selected as MCO source
980 * @arg @ref RCC_MCO1SOURCE_HSI HSI clock selected as MCO source
981 * @arg @ref RCC_MCO1SOURCE_HSE HSE clock selected as MCO sourcee
982 * @arg @ref RCC_MCO1SOURCE_PLLCLK main PLL clock selected as MCO source
983 * @arg @ref RCC_MCO1SOURCE_LSI LSI clock selected as MCO source
984 * @arg @ref RCC_MCO1SOURCE_LSE LSE clock selected as MCO source
985 * @arg @ref RCC_MCO1SOURCE_HSI48 HSI48 clock selected as MCO source for devices with HSI48
986 * @param RCC_MCODiv specifies the MCO prescaler.
987 * This parameter can be one of the following values:
988 * @arg @ref RCC_MCODIV_1 no division applied to MCO clock
989 * @arg @ref RCC_MCODIV_2 division by 2 applied to MCO clock
990 * @arg @ref RCC_MCODIV_4 division by 4 applied to MCO clock
991 * @arg @ref RCC_MCODIV_8 division by 8 applied to MCO clock
992 * @arg @ref RCC_MCODIV_16 division by 16 applied to MCO clock
993 * @retval None
994 */
HAL_RCC_MCOConfig(uint32_t RCC_MCOx,uint32_t RCC_MCOSource,uint32_t RCC_MCODiv)995 void HAL_RCC_MCOConfig(uint32_t RCC_MCOx, uint32_t RCC_MCOSource, uint32_t RCC_MCODiv)
996 {
997 GPIO_InitTypeDef gpio_initstruct;
998 uint32_t mcoindex;
999 uint32_t mco_gpio_index;
1000 GPIO_TypeDef * mco_gpio_port;
1001
1002 /* Check the parameters */
1003 assert_param(IS_RCC_MCO(RCC_MCOx));
1004
1005 /* Common GPIO init parameters */
1006 gpio_initstruct.Mode = GPIO_MODE_AF_PP;
1007 gpio_initstruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
1008 gpio_initstruct.Pull = GPIO_NOPULL;
1009
1010 /* Get MCOx selection */
1011 mcoindex = RCC_MCOx & RCC_MCO_INDEX_MASK;
1012
1013 /* Get MCOx GPIO Port */
1014 mco_gpio_port = (GPIO_TypeDef *) RCC_GET_MCO_GPIO_PORT(RCC_MCOx);
1015
1016 /* MCOx Clock Enable */
1017 mco_gpio_index = RCC_GET_MCO_GPIO_INDEX(RCC_MCOx);
1018 SET_BIT(RCC->AHB2ENR, (1UL << mco_gpio_index ));
1019
1020 /* Configure the MCOx pin in alternate function mode */
1021 gpio_initstruct.Pin = RCC_GET_MCO_GPIO_PIN(RCC_MCOx);
1022 gpio_initstruct.Alternate = RCC_GET_MCO_GPIO_AF(RCC_MCOx);
1023 HAL_GPIO_Init(mco_gpio_port, &gpio_initstruct);
1024
1025 if (mcoindex == RCC_MCO1_INDEX)
1026 {
1027 assert_param(IS_RCC_MCODIV(RCC_MCODiv));
1028 assert_param(IS_RCC_MCO1SOURCE(RCC_MCOSource));
1029 /* Mask MCOSEL[] and MCOPRE[] bits then set MCO clock source and prescaler */
1030 MODIFY_REG(RCC->CFGR, (RCC_CFGR_MCOSEL | RCC_CFGR_MCOPRE), (RCC_MCOSource | RCC_MCODiv));
1031 }
1032 }
1033
1034 /**
1035 * @brief Return the SYSCLK frequency.
1036 *
1037 * @note The system frequency computed by this function is not the real
1038 * frequency in the chip. It is calculated based on the predefined
1039 * constant and the selected clock source:
1040 * @note If SYSCLK source is HSI, function returns values based on HSI_VALUE(*)
1041 * @note If SYSCLK source is HSE, function returns values based on HSE_VALUE(**)
1042 * @note If SYSCLK source is PLL, function returns values based on HSE_VALUE(**),
1043 * HSI_VALUE(*) Value multiplied/divided by the PLL factors.
1044 * @note (*) HSI_VALUE is a constant defined in stm32g4xx_hal_conf.h file (default value
1045 * 16 MHz) but the real value may vary depending on the variations
1046 * in voltage and temperature.
1047 * @note (**) HSE_VALUE is a constant defined in stm32g4xx_hal_conf.h file (default value
1048 * 8 MHz), user has to ensure that HSE_VALUE is same as the real
1049 * frequency of the crystal used. Otherwise, this function may
1050 * have wrong result.
1051 *
1052 * @note The result of this function could be not correct when using fractional
1053 * value for HSE crystal.
1054 *
1055 * @note This function can be used by the user application to compute the
1056 * baudrate for the communication peripherals or configure other parameters.
1057 *
1058 * @note Each time SYSCLK changes, this function must be called to update the
1059 * right SYSCLK value. Otherwise, any configuration based on this function will be incorrect.
1060 *
1061 *
1062 * @retval SYSCLK frequency
1063 */
HAL_RCC_GetSysClockFreq(void)1064 uint32_t HAL_RCC_GetSysClockFreq(void)
1065 {
1066 uint32_t pllvco, pllsource, pllr, pllm;
1067 uint32_t sysclockfreq;
1068
1069 if (__HAL_RCC_GET_SYSCLK_SOURCE() == RCC_CFGR_SWS_HSI)
1070 {
1071 /* HSI used as system clock source */
1072 sysclockfreq = HSI_VALUE;
1073 }
1074 else if (__HAL_RCC_GET_SYSCLK_SOURCE() == RCC_CFGR_SWS_HSE)
1075 {
1076 /* HSE used as system clock source */
1077 sysclockfreq = HSE_VALUE;
1078 }
1079 else if (__HAL_RCC_GET_SYSCLK_SOURCE() == RCC_CFGR_SWS_PLL)
1080 {
1081 /* PLL used as system clock source */
1082
1083 /* PLL_VCO = ((HSE_VALUE or HSI_VALUE)/ PLLM) * PLLN
1084 SYSCLK = PLL_VCO / PLLR
1085 */
1086 pllsource = READ_BIT(RCC->PLLCFGR, RCC_PLLCFGR_PLLSRC);
1087 pllm = (READ_BIT(RCC->PLLCFGR, RCC_PLLCFGR_PLLM) >> RCC_PLLCFGR_PLLM_Pos) + 1U ;
1088
1089 switch (pllsource)
1090 {
1091 case RCC_PLLSOURCE_HSE: /* HSE used as PLL clock source */
1092 pllvco = (HSE_VALUE / pllm) * (READ_BIT(RCC->PLLCFGR, RCC_PLLCFGR_PLLN) >> RCC_PLLCFGR_PLLN_Pos);
1093 break;
1094
1095 case RCC_PLLSOURCE_HSI: /* HSI used as PLL clock source */
1096 default:
1097 pllvco = (HSI_VALUE / pllm) * (READ_BIT(RCC->PLLCFGR, RCC_PLLCFGR_PLLN) >> RCC_PLLCFGR_PLLN_Pos);
1098 break;
1099 }
1100 pllr = ((READ_BIT(RCC->PLLCFGR, RCC_PLLCFGR_PLLR) >> RCC_PLLCFGR_PLLR_Pos) + 1U ) * 2U;
1101 sysclockfreq = pllvco/pllr;
1102 }
1103 else
1104 {
1105 sysclockfreq = 0U;
1106 }
1107
1108 return sysclockfreq;
1109 }
1110
1111 /**
1112 * @brief Return the HCLK frequency.
1113 * @note Each time HCLK changes, this function must be called to update the
1114 * right HCLK value. Otherwise, any configuration based on this function will be incorrect.
1115 *
1116 * @note The SystemCoreClock CMSIS variable is used to store System Clock Frequency.
1117 * @retval HCLK frequency in Hz
1118 */
HAL_RCC_GetHCLKFreq(void)1119 uint32_t HAL_RCC_GetHCLKFreq(void)
1120 {
1121 return SystemCoreClock;
1122 }
1123
1124 /**
1125 * @brief Return the PCLK1 frequency.
1126 * @note Each time PCLK1 changes, this function must be called to update the
1127 * right PCLK1 value. Otherwise, any configuration based on this function will be incorrect.
1128 * @retval PCLK1 frequency in Hz
1129 */
HAL_RCC_GetPCLK1Freq(void)1130 uint32_t HAL_RCC_GetPCLK1Freq(void)
1131 {
1132 /* Get HCLK source and Compute PCLK1 frequency ---------------------------*/
1133 return (HAL_RCC_GetHCLKFreq() >> (APBPrescTable[READ_BIT(RCC->CFGR, RCC_CFGR_PPRE1) >> RCC_CFGR_PPRE1_Pos] & 0x1FU));
1134 }
1135
1136 /**
1137 * @brief Return the PCLK2 frequency.
1138 * @note Each time PCLK2 changes, this function must be called to update the
1139 * right PCLK2 value. Otherwise, any configuration based on this function will be incorrect.
1140 * @retval PCLK2 frequency in Hz
1141 */
HAL_RCC_GetPCLK2Freq(void)1142 uint32_t HAL_RCC_GetPCLK2Freq(void)
1143 {
1144 /* Get HCLK source and Compute PCLK2 frequency ---------------------------*/
1145 return (HAL_RCC_GetHCLKFreq()>> (APBPrescTable[READ_BIT(RCC->CFGR, RCC_CFGR_PPRE2) >> RCC_CFGR_PPRE2_Pos] & 0x1FU));
1146 }
1147
1148 /**
1149 * @brief Configure the RCC_OscInitStruct according to the internal
1150 * RCC configuration registers.
1151 * @param RCC_OscInitStruct pointer to an RCC_OscInitTypeDef structure that
1152 * will be configured.
1153 * @retval None
1154 */
HAL_RCC_GetOscConfig(RCC_OscInitTypeDef * RCC_OscInitStruct)1155 void HAL_RCC_GetOscConfig(RCC_OscInitTypeDef *RCC_OscInitStruct)
1156 {
1157 /* Check the parameters */
1158 assert_param(RCC_OscInitStruct != (void *)NULL);
1159
1160 /* Set all possible values for the Oscillator type parameter ---------------*/
1161 RCC_OscInitStruct->OscillatorType = RCC_OSCILLATORTYPE_HSE | RCC_OSCILLATORTYPE_HSI | \
1162 RCC_OSCILLATORTYPE_LSE | RCC_OSCILLATORTYPE_LSI | RCC_OSCILLATORTYPE_HSI48;
1163
1164 /* Get the HSE configuration -----------------------------------------------*/
1165 if(READ_BIT(RCC->CR, RCC_CR_HSEBYP) == RCC_CR_HSEBYP)
1166 {
1167 RCC_OscInitStruct->HSEState = RCC_HSE_BYPASS;
1168 }
1169 else if(READ_BIT(RCC->CR, RCC_CR_HSEON) == RCC_CR_HSEON)
1170 {
1171 RCC_OscInitStruct->HSEState = RCC_HSE_ON;
1172 }
1173 else
1174 {
1175 RCC_OscInitStruct->HSEState = RCC_HSE_OFF;
1176 }
1177
1178 /* Get the HSI configuration -----------------------------------------------*/
1179 if(READ_BIT(RCC->CR, RCC_CR_HSION) == RCC_CR_HSION)
1180 {
1181 RCC_OscInitStruct->HSIState = RCC_HSI_ON;
1182 }
1183 else
1184 {
1185 RCC_OscInitStruct->HSIState = RCC_HSI_OFF;
1186 }
1187
1188 RCC_OscInitStruct->HSICalibrationValue = READ_BIT(RCC->ICSCR, RCC_ICSCR_HSITRIM) >> RCC_ICSCR_HSITRIM_Pos;
1189
1190 /* Get the LSE configuration -----------------------------------------------*/
1191 if(READ_BIT(RCC->BDCR, RCC_BDCR_LSEBYP) == RCC_BDCR_LSEBYP)
1192 {
1193 RCC_OscInitStruct->LSEState = RCC_LSE_BYPASS;
1194 }
1195 else if(READ_BIT(RCC->BDCR, RCC_BDCR_LSEON) == RCC_BDCR_LSEON)
1196 {
1197 RCC_OscInitStruct->LSEState = RCC_LSE_ON;
1198 }
1199 else
1200 {
1201 RCC_OscInitStruct->LSEState = RCC_LSE_OFF;
1202 }
1203
1204 /* Get the LSI configuration -----------------------------------------------*/
1205 if(READ_BIT(RCC->CSR, RCC_CSR_LSION) == RCC_CSR_LSION)
1206 {
1207 RCC_OscInitStruct->LSIState = RCC_LSI_ON;
1208 }
1209 else
1210 {
1211 RCC_OscInitStruct->LSIState = RCC_LSI_OFF;
1212 }
1213
1214 /* Get the HSI48 configuration ---------------------------------------------*/
1215 if(READ_BIT(RCC->CRRCR, RCC_CRRCR_HSI48ON) == RCC_CRRCR_HSI48ON)
1216 {
1217 RCC_OscInitStruct->HSI48State = RCC_HSI48_ON;
1218 }
1219 else
1220 {
1221 RCC_OscInitStruct->HSI48State = RCC_HSI48_OFF;
1222 }
1223
1224 /* Get the PLL configuration -----------------------------------------------*/
1225 if(READ_BIT(RCC->CR, RCC_CR_PLLON) == RCC_CR_PLLON)
1226 {
1227 RCC_OscInitStruct->PLL.PLLState = RCC_PLL_ON;
1228 }
1229 else
1230 {
1231 RCC_OscInitStruct->PLL.PLLState = RCC_PLL_OFF;
1232 }
1233 RCC_OscInitStruct->PLL.PLLSource = READ_BIT(RCC->PLLCFGR, RCC_PLLCFGR_PLLSRC);
1234 RCC_OscInitStruct->PLL.PLLM = (READ_BIT(RCC->PLLCFGR, RCC_PLLCFGR_PLLM) >> RCC_PLLCFGR_PLLM_Pos) + 1U;
1235 RCC_OscInitStruct->PLL.PLLN = READ_BIT(RCC->PLLCFGR, RCC_PLLCFGR_PLLN) >> RCC_PLLCFGR_PLLN_Pos;
1236 RCC_OscInitStruct->PLL.PLLQ = (((READ_BIT(RCC->PLLCFGR, RCC_PLLCFGR_PLLQ) >> RCC_PLLCFGR_PLLQ_Pos) + 1U) << 1U);
1237 RCC_OscInitStruct->PLL.PLLR = (((READ_BIT(RCC->PLLCFGR, RCC_PLLCFGR_PLLR) >> RCC_PLLCFGR_PLLR_Pos) + 1U) << 1U);
1238 RCC_OscInitStruct->PLL.PLLP = READ_BIT(RCC->PLLCFGR, RCC_PLLCFGR_PLLPDIV) >> RCC_PLLCFGR_PLLPDIV_Pos;
1239 }
1240
1241 /**
1242 * @brief Configure the RCC_ClkInitStruct according to the internal
1243 * RCC configuration registers.
1244 * @param RCC_ClkInitStruct pointer to an RCC_ClkInitTypeDef structure that
1245 * will be configured.
1246 * @param pFLatency Pointer on the Flash Latency.
1247 * @retval None
1248 */
HAL_RCC_GetClockConfig(RCC_ClkInitTypeDef * RCC_ClkInitStruct,uint32_t * pFLatency)1249 void HAL_RCC_GetClockConfig(RCC_ClkInitTypeDef *RCC_ClkInitStruct, uint32_t *pFLatency)
1250 {
1251 /* Check the parameters */
1252 assert_param(RCC_ClkInitStruct != (void *)NULL);
1253 assert_param(pFLatency != (void *)NULL);
1254
1255 /* Set all possible values for the Clock type parameter --------------------*/
1256 RCC_ClkInitStruct->ClockType = RCC_CLOCKTYPE_SYSCLK | RCC_CLOCKTYPE_HCLK | RCC_CLOCKTYPE_PCLK1 | RCC_CLOCKTYPE_PCLK2;
1257
1258 /* Get the SYSCLK configuration --------------------------------------------*/
1259 RCC_ClkInitStruct->SYSCLKSource = READ_BIT(RCC->CFGR, RCC_CFGR_SW);
1260
1261 /* Get the HCLK configuration ----------------------------------------------*/
1262 RCC_ClkInitStruct->AHBCLKDivider = READ_BIT(RCC->CFGR, RCC_CFGR_HPRE);
1263
1264 /* Get the APB1 configuration ----------------------------------------------*/
1265 RCC_ClkInitStruct->APB1CLKDivider = READ_BIT(RCC->CFGR, RCC_CFGR_PPRE1);
1266
1267 /* Get the APB2 configuration ----------------------------------------------*/
1268 RCC_ClkInitStruct->APB2CLKDivider = (READ_BIT(RCC->CFGR, RCC_CFGR_PPRE2) >> 3U);
1269
1270 /* Get the Flash Wait State (Latency) configuration ------------------------*/
1271 *pFLatency = __HAL_FLASH_GET_LATENCY();
1272 }
1273
1274 /**
1275 * @brief Enable the Clock Security System.
1276 * @note If a failure is detected on the HSE oscillator clock, this oscillator
1277 * is automatically disabled and an interrupt is generated to inform the
1278 * software about the failure (Clock Security System Interrupt, CSSI),
1279 * allowing the MCU to perform rescue operations. The CSSI is linked to
1280 * the Cortex-M4 NMI (Non-Maskable Interrupt) exception vector.
1281 * @note The Clock Security System can only be cleared by reset.
1282 * @retval None
1283 */
HAL_RCC_EnableCSS(void)1284 void HAL_RCC_EnableCSS(void)
1285 {
1286 SET_BIT(RCC->CR, RCC_CR_CSSON) ;
1287 }
1288
1289 /**
1290 * @brief Enable the LSE Clock Security System.
1291 * @note If a failure is detected on the external 32 kHz oscillator,
1292 * the LSE clock is no longer supplied to the RTC but no hardware action
1293 * is made to the registers. If enabled, an interrupt will be generated
1294 * and handle through @ref RCCEx_EXTI_LINE_LSECSS
1295 * @note The Clock Security System can only be cleared by reset or after a LSE failure detection.
1296 * @retval None
1297 */
HAL_RCC_EnableLSECSS(void)1298 void HAL_RCC_EnableLSECSS(void)
1299 {
1300 SET_BIT(RCC->BDCR, RCC_BDCR_LSECSSON) ;
1301 }
1302
1303 /**
1304 * @brief Disable the LSE Clock Security System.
1305 * @note After LSE failure detection, the software must disable LSECSSON
1306 * @note The Clock Security System can only be cleared by reset otherwise.
1307 * @retval None
1308 */
HAL_RCC_DisableLSECSS(void)1309 void HAL_RCC_DisableLSECSS(void)
1310 {
1311 CLEAR_BIT(RCC->BDCR, RCC_BDCR_LSECSSON) ;
1312 }
1313
1314 /**
1315 * @brief Handle the RCC Clock Security System interrupt request.
1316 * @note This API should be called under the NMI_Handler().
1317 * @retval None
1318 */
HAL_RCC_NMI_IRQHandler(void)1319 void HAL_RCC_NMI_IRQHandler(void)
1320 {
1321 /* Check RCC CSSF interrupt flag */
1322 if(__HAL_RCC_GET_IT(RCC_IT_CSS))
1323 {
1324 /* RCC Clock Security System interrupt user callback */
1325 HAL_RCC_CSSCallback();
1326
1327 /* Clear RCC CSS pending bit */
1328 __HAL_RCC_CLEAR_IT(RCC_IT_CSS);
1329 }
1330 }
1331
1332 /**
1333 * @brief RCC Clock Security System interrupt callback.
1334 * @retval none
1335 */
HAL_RCC_CSSCallback(void)1336 __weak void HAL_RCC_CSSCallback(void)
1337 {
1338 /* NOTE : This function should not be modified, when the callback is needed,
1339 the HAL_RCC_CSSCallback should be implemented in the user file
1340 */
1341 }
1342
1343 /**
1344 * @}
1345 */
1346
1347 /**
1348 * @}
1349 */
1350
1351 /* Private function prototypes -----------------------------------------------*/
1352 /** @addtogroup RCC_Private_Functions
1353 * @{
1354 */
1355
1356 /**
1357 * @brief Compute SYSCLK frequency based on PLL SYSCLK source.
1358 * @retval SYSCLK frequency
1359 */
RCC_GetSysClockFreqFromPLLSource(void)1360 static uint32_t RCC_GetSysClockFreqFromPLLSource(void)
1361 {
1362 uint32_t pllvco, pllsource, pllr, pllm;
1363 uint32_t sysclockfreq;
1364
1365 /* PLL_VCO = (HSE_VALUE or HSI_VALUE/ PLLM) * PLLN
1366 SYSCLK = PLL_VCO / PLLR
1367 */
1368 pllsource = READ_BIT(RCC->PLLCFGR, RCC_PLLCFGR_PLLSRC);
1369 pllm = (READ_BIT(RCC->PLLCFGR, RCC_PLLCFGR_PLLM) >> RCC_PLLCFGR_PLLM_Pos) + 1U ;
1370
1371 switch (pllsource)
1372 {
1373 case RCC_PLLSOURCE_HSE: /* HSE used as PLL clock source */
1374 pllvco = (HSE_VALUE / pllm) * (READ_BIT(RCC->PLLCFGR, RCC_PLLCFGR_PLLN) >> RCC_PLLCFGR_PLLN_Pos);
1375 break;
1376
1377 case RCC_PLLSOURCE_HSI: /* HSI used as PLL clock source */
1378 default:
1379 pllvco = (HSI_VALUE / pllm) * (READ_BIT(RCC->PLLCFGR, RCC_PLLCFGR_PLLN) >> RCC_PLLCFGR_PLLN_Pos);
1380 break;
1381 }
1382
1383 pllr = ((READ_BIT(RCC->PLLCFGR, RCC_PLLCFGR_PLLR) >> RCC_PLLCFGR_PLLR_Pos) + 1U ) * 2U;
1384 sysclockfreq = pllvco/pllr;
1385
1386 return sysclockfreq;
1387 }
1388
1389 /**
1390 * @}
1391 */
1392
1393 #endif /* HAL_RCC_MODULE_ENABLED */
1394 /**
1395 * @}
1396 */
1397
1398 /**
1399 * @}
1400 */
1401
1402