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