1 /**
2 ******************************************************************************
3 * @file stm32c0xx_hal_rcc.c
4 * @author MCD Application Team
5 * @brief RCC HAL module driver.
6 * This file provides firmware functions to manage the following
7 * functionalities of the Reset and Clock Control (RCC) peripheral:
8 * + Initialization and de-initialization functions
9 * + Peripheral Control functions
10 *
11 ******************************************************************************
12 * @attention
13 *
14 * Copyright (c) 2022 STMicroelectronics.
15 * All rights reserved.
16 *
17 * This software is licensed under terms that can be found in the LICENSE file
18 * in the root directory of this software component.
19 * If no LICENSE file comes with this software, it is provided AS-IS.
20 *
21 ******************************************************************************
22 @verbatim
23 ==============================================================================
24 ##### RCC specific features #####
25 ==============================================================================
26 [..]
27 After reset the device is running from High Speed Internal oscillator
28 divided by 4 that is the default system clock with Flash 0 wait state.
29
30 (+) There is no prescaler on High speed (AHB) and Low speed (APB) busses:
31 all peripherals mapped on these busses are running at HSI speed.
32 (+) The clock for all peripherals is switched off, except the SRAM and FLASH.
33 (+) All GPIOs are in analog mode
34
35 [..]
36 Once the device started from reset, the user application has to:
37 (+) Configure the clock source to be used to drive the System clock
38 (if the application needs higher frequency/performance)
39 (+) Configure the System clock frequency and Flash settings
40 (+) Configure the AHB and APB busses prescalers
41 (+) Enable the clock for the peripheral(s) to be used
42 (+) Configure the clock source(s) for peripherals which clocks are not
43 derived from the System clock (RTC, ADC, USART, I2C, I2S)
44
45 @endverbatim
46 ******************************************************************************
47 */
48
49 /* Includes ------------------------------------------------------------------*/
50 #include "stm32c0xx_hal.h"
51
52 /** @addtogroup STM32C0xx_HAL_Driver
53 * @{
54 */
55
56 /** @defgroup RCC RCC
57 * @brief RCC HAL module driver
58 * @{
59 */
60
61 #ifdef HAL_RCC_MODULE_ENABLED
62
63 /* Private typedef -----------------------------------------------------------*/
64 /* Private define ------------------------------------------------------------*/
65 /** @defgroup RCC_Private_Constants RCC Private Constants
66 * @{
67 */
68 #define RCC_HSE_TIMEOUT_VALUE HSE_STARTUP_TIMEOUT
69 #define RCC_HSI_TIMEOUT_VALUE (2U) /* 2 ms (minimum Tick + 1) */
70 #define RCC_LSI_TIMEOUT_VALUE (2U) /* 2 ms (minimum Tick + 1) */
71 #if defined(RCC_CR_HSIUSB48ON)
72 #define HSI48_TIMEOUT_VALUE (2U) /* 2 ms (minimum Tick + 1) */
73 #endif /* RCC_CR_HSIUSB48ON */
74 #define RCC_CLOCKSWITCH_TIMEOUT_VALUE (5000U) /* 5 s */
75
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__) (IOPORT_BASE + ((0x00000400UL) * RCC_GET_MCO_GPIO_INDEX((__RCC_MCOx__))))
91
92 /**
93 * @}
94 */
95
96 /* Private variables ---------------------------------------------------------*/
97 /** @defgroup RCC_Private_Variables RCC Private Variables
98 * @{
99 */
100
101 /**
102 * @}
103 */
104
105 /* Private function prototypes -----------------------------------------------*/
106 /* Exported functions --------------------------------------------------------*/
107
108 /** @defgroup RCC_Exported_Functions RCC Exported Functions
109 * @{
110 */
111
112 /** @defgroup RCC_Exported_Functions_Group1 Initialization and de-initialization functions
113 * @brief Initialization and Configuration functions
114 *
115 @verbatim
116 ===============================================================================
117 ##### Initialization and de-initialization functions #####
118 ===============================================================================
119 [..]
120 This section provides functions allowing to configure the internal and external oscillators
121 (HSE, HSI, LSE, LSI, CSS and MCO) and the System busses clocks (SYSCLK, AHB, APB)
122
123 [..] Internal/external clock
124 (+) HSI (high-speed internal): 48 MHz factory-trimmed RC used directly as System clock source.
125
126 (+) LSI (low-speed internal): 32 KHz low consumption RC used as IWDG and/or RTC
127 clock source.
128
129 (+) HSE (high-speed external): 4 to 48 MHz crystal oscillator used directly or
130 through the PLL as System clock source. Can be used also optionally as RTC clock source.
131
132 (+) LSE (low-speed external): 32.768 KHz oscillator used optionally as RTC clock source.
133
134 (+) CSS (Clock security system): once enabled, if a HSE or LSE clock failure occurs,
135 the System clock is automatically switched respectively to HSI or LSI and an interrupt
136 is generated if enabled. The interrupt is linked to the Cortex-M0+ NMI (Non-Maskable Interrupt)
137 exception vector.
138
139 (+) MCOx (microcontroller clock output): used to output LSI, HSI, LSE, HSE and SYSCLK on different pins.
140
141 [..] System, AHB and APB busses clocks configuration
142 (+) Several clock sources can be used to drive the System clock (SYSCLK): HSI,
143 HSE, LSI and LSE.
144 The AHB clock (HCLK) is derived from System clock through configurable
145 prescaler and used to clock the CPU, memory and peripherals mapped
146 on AHB bus (DMA, GPIO...).and APB (PCLK1) clock is derived
147 from AHB clock through configurable prescalers and used to clock
148 the peripherals mapped on these busses. You can use
149 "@ref HAL_RCC_GetSysClockFreq()" function to retrieve the frequencies of these clocks.
150
151 -@- All the peripheral clocks are derived from the System clock (SYSCLK) except:
152
153 (+@) RTC: the RTC clock can be derived either from the LSI, LSE or HSE clock
154 divided by 2 to 31.
155 You have to use @ref __HAL_RCC_RTC_ENABLE() and @ref HAL_RCCEx_PeriphCLKConfig() function
156 to configure this clock.
157
158 (+@) ADC: the ADC clock can be derived either from system clock or HSI
159
160 (+@) USART: the USART clock can be derived either from APB clock or HSI or LSE
161 (+@) I2C: the I2C clock can be derived either from system clock or HSI
162
163 (+@) I2S: the I2S clock can be derived either from system clock or HSI or external clock source
164
165 (+) The maximum frequency of the SYSCLK, HCLK, PCLK is 48 MHz.
166
167 @endverbatim
168
169 (++) Table 1. HCLK clock frequency.
170 (++) +------------------------------------+
171 (++) | Latency | HCLK clock |
172 (++) | | frequency (MHz) |
173 (++) | |------------------|
174 (++) | | voltage range |
175 (++) | | VDD33 2V - 3.6V |
176 (++) | | VDD12 1V - 1.32V|
177 (++) |-----------------|------------------|
178 (++) |0WS(1 CPU cycles)| HCLK <= 24 |
179 (++) |-----------------|------------------|
180 (++) |1WS(2 CPU cycles)| HCLK <= 48 |
181 (++) +------------------------------------+
182 (++)
183 * @{
184 */
185
186 /**
187 * @brief Reset the RCC clock configuration to the default reset state.
188 * @note The default reset state of the clock configuration is given below:
189 * - HSI ON and used as system clock source
190 * - HSE OFF
191 * - SYSDIV, AHB and APB prescaler set to 1.
192 * - CSS, MCO1, MCO2 OFF
193 * - All interrupts disabled
194 * @note This function does not modify the configuration of the
195 * - Peripheral clocks
196 * - LSI, LSE and RTC clocks
197 * @retval HAL status
198 */
HAL_RCC_DeInit(void)199 HAL_StatusTypeDef HAL_RCC_DeInit(void)
200 {
201 uint32_t tickstart;
202
203 /* Get Start Tick*/
204 tickstart = HAL_GetTick();
205
206 /* Set HSION bit to the reset value */
207 SET_BIT(RCC->CR, RCC_CR_HSION);
208
209 /* Wait till HSI is ready */
210 while (READ_BIT(RCC->CR, RCC_CR_HSIRDY) == 0U)
211 {
212 if ((HAL_GetTick() - tickstart) > RCC_HSI_TIMEOUT_VALUE)
213 {
214 return HAL_TIMEOUT;
215 }
216 }
217
218 /* Set HSITRIM[6:0] bits to the reset value */
219 RCC->ICSCR = RCC_ICSCR_HSITRIM_6;
220
221 /* Get Start Tick*/
222 tickstart = HAL_GetTick();
223
224 /* Reset CFGR register (HSI is selected as system clock source) */
225 RCC->CFGR = 0x00000000u;
226
227 /* Wait till HSI is ready */
228 while (READ_BIT(RCC->CFGR, RCC_CFGR_SWS) != 0U)
229 {
230 if ((HAL_GetTick() - tickstart) > RCC_CLOCKSWITCH_TIMEOUT_VALUE)
231 {
232 return HAL_TIMEOUT;
233 }
234 }
235
236 /* Get Start Tick*/
237 tickstart = HAL_GetTick();
238
239 /* Clear CR register in 2 steps: first to clear HSEON in case bypass was enabled */
240 RCC->CR &= ~RCC_CR_HSEON;
241
242 /* Wait till HSEON is disabled */
243 while (READ_BIT(RCC->CR, RCC_CR_HSERDY) != 0U)
244 {
245 if ((HAL_GetTick() - tickstart) > RCC_HSE_TIMEOUT_VALUE)
246 {
247 return HAL_TIMEOUT;
248 }
249 }
250
251 /* Then again to HSEBYP in case bypass was enabled */
252 RCC->CR &= ~RCC_CR_HSEBYP;
253
254 /* Disable all interrupts */
255 RCC->CIER = 0x00000000u;
256
257 /* Clear all flags */
258 RCC->CICR = 0xFFFFFFFFu;
259
260 /* Update the SystemCoreClock global variable */
261 SystemCoreClock = HSI_VALUE;
262
263 /* Adapt Systick interrupt period */
264 if (HAL_InitTick(uwTickPrio) != HAL_OK)
265 {
266 return HAL_ERROR;
267 }
268 else
269 {
270 return HAL_OK;
271 }
272 }
273
274 /**
275 * @brief Initialize the RCC Oscillators according to the specified parameters in the
276 * @ref RCC_OscInitTypeDef.
277 * @param RCC_OscInitStruct pointer to a @ref RCC_OscInitTypeDef structure that
278 * contains the configuration information for the RCC Oscillators.
279 * @note Transition HSE Bypass to HSE On and HSE On to HSE Bypass are not
280 * supported by this function. User should request a transition to HSE Off
281 * first and then to HSE On or HSE Bypass.
282 * @note Transition LSE Bypass to LSE On and LSE On to LSE Bypass are not
283 * supported by this function. User should request a transition to LSE Off
284 * first and then to LSE On or LSE Bypass.
285 * @retval HAL status
286 */
HAL_RCC_OscConfig(const RCC_OscInitTypeDef * RCC_OscInitStruct)287 HAL_StatusTypeDef HAL_RCC_OscConfig(const RCC_OscInitTypeDef *RCC_OscInitStruct)
288 {
289 uint32_t tickstart;
290 uint32_t temp_sysclksrc;
291
292 /* Check Null pointer */
293 if (RCC_OscInitStruct == NULL)
294 {
295 return HAL_ERROR;
296 }
297
298 /* Check the parameters */
299 assert_param(IS_RCC_OSCILLATORTYPE(RCC_OscInitStruct->OscillatorType));
300
301 /*------------------------------- HSE Configuration ------------------------*/
302 if (((RCC_OscInitStruct->OscillatorType) & RCC_OSCILLATORTYPE_HSE) == RCC_OSCILLATORTYPE_HSE)
303 {
304 /* Check the parameters */
305 assert_param(IS_RCC_HSE(RCC_OscInitStruct->HSEState));
306
307 temp_sysclksrc = __HAL_RCC_GET_SYSCLK_SOURCE();
308
309 /* When the HSE is used as system clock in these cases it is not allowed to be disabled */
310 if (temp_sysclksrc == RCC_CFGR_SWS_HSE)
311 {
312 if (RCC_OscInitStruct->HSEState == RCC_HSE_OFF)
313 {
314 return HAL_ERROR;
315 }
316 }
317 else
318 {
319 /* Set the new HSE configuration ---------------------------------------*/
320 __HAL_RCC_HSE_CONFIG(RCC_OscInitStruct->HSEState);
321
322 /* Check the HSE State */
323 if (RCC_OscInitStruct->HSEState != RCC_HSE_OFF)
324 {
325 /* Get Start Tick*/
326 tickstart = HAL_GetTick();
327
328 /* Wait till HSE is ready */
329 while (READ_BIT(RCC->CR, RCC_CR_HSERDY) == 0U)
330 {
331 if ((HAL_GetTick() - tickstart) > RCC_HSE_TIMEOUT_VALUE)
332 {
333 return HAL_TIMEOUT;
334 }
335 }
336 }
337 else
338 {
339 /* Get Start Tick*/
340 tickstart = HAL_GetTick();
341
342 /* Wait till HSE is disabled */
343 while (READ_BIT(RCC->CR, RCC_CR_HSERDY) != 0U)
344 {
345 if ((HAL_GetTick() - tickstart) > RCC_HSE_TIMEOUT_VALUE)
346 {
347 return HAL_TIMEOUT;
348 }
349 }
350 }
351 }
352 }
353 /*----------------------------- HSI Configuration --------------------------*/
354 if (((RCC_OscInitStruct->OscillatorType) & RCC_OSCILLATORTYPE_HSI) == RCC_OSCILLATORTYPE_HSI)
355 {
356 /* Check the parameters */
357 assert_param(IS_RCC_HSI(RCC_OscInitStruct->HSIState));
358 assert_param(IS_RCC_HSI_CALIBRATION_VALUE(RCC_OscInitStruct->HSICalibrationValue));
359 assert_param(IS_RCC_HSIDIV(RCC_OscInitStruct->HSIDiv));
360
361 /* Check if HSI48 is used as system clock */
362 temp_sysclksrc = __HAL_RCC_GET_SYSCLK_SOURCE();
363
364 if (temp_sysclksrc == RCC_CFGR_SWS_HSI)
365 {
366 /* When HSI is used as system clock it can not be disabled */
367 if (RCC_OscInitStruct->HSIState == RCC_HSI_OFF)
368 {
369 return HAL_ERROR;
370 }
371 /* Otherwise, just the calibration is allowed */
372 else
373 {
374 /* Adjusts the Internal High Speed oscillator (HSI) calibration value.*/
375 __HAL_RCC_HSI_CALIBRATIONVALUE_ADJUST(RCC_OscInitStruct->HSICalibrationValue);
376
377 if (temp_sysclksrc == RCC_CFGR_SWS_HSI)
378 {
379 /* Adjust the HSI48 division factor */
380 __HAL_RCC_HSI_CONFIG(RCC_OscInitStruct->HSIDiv);
381
382 /* Update the SystemCoreClock global variable with HSISYS value */
383 SystemCoreClock = (HSI_VALUE / (1UL << ((READ_BIT(RCC->CR, RCC_CR_HSIDIV)) >> RCC_CR_HSIDIV_Pos)));
384 }
385
386 /* Adapt Systick interrupt period */
387 if (HAL_InitTick(uwTickPrio) != HAL_OK)
388 {
389 return HAL_ERROR;
390 }
391 }
392 }
393 else
394 {
395 /* Check the HSI State */
396 if (RCC_OscInitStruct->HSIState != RCC_HSI_OFF)
397 {
398 /* Configure the HSI48 division factor */
399 __HAL_RCC_HSI_CONFIG(RCC_OscInitStruct->HSIDiv);
400
401 /* Enable the Internal High Speed oscillator (HSI48). */
402 __HAL_RCC_HSI_ENABLE();
403
404 /* Get Start Tick*/
405 tickstart = HAL_GetTick();
406
407 /* Wait till HSI is ready */
408 while (READ_BIT(RCC->CR, RCC_CR_HSIRDY) == 0U)
409 {
410 if ((HAL_GetTick() - tickstart) > RCC_HSI_TIMEOUT_VALUE)
411 {
412 return HAL_TIMEOUT;
413 }
414 }
415
416 /* Adjusts the Internal High Speed oscillator (HSI) calibration value.*/
417 __HAL_RCC_HSI_CALIBRATIONVALUE_ADJUST(RCC_OscInitStruct->HSICalibrationValue);
418 }
419 else
420 {
421 /* Disable the Internal High Speed oscillator (HSI48). */
422 __HAL_RCC_HSI_DISABLE();
423
424 /* Get Start Tick*/
425 tickstart = HAL_GetTick();
426
427 /* Wait till HSI is disabled */
428 while (READ_BIT(RCC->CR, RCC_CR_HSIRDY) != 0U)
429 {
430 if ((HAL_GetTick() - tickstart) > RCC_HSI_TIMEOUT_VALUE)
431 {
432 return HAL_TIMEOUT;
433 }
434 }
435 }
436 }
437 }
438 /*------------------------------ LSI Configuration -------------------------*/
439 if (((RCC_OscInitStruct->OscillatorType) & RCC_OSCILLATORTYPE_LSI) == RCC_OSCILLATORTYPE_LSI)
440 {
441 /* Check the parameters */
442 assert_param(IS_RCC_LSI(RCC_OscInitStruct->LSIState));
443
444 /* Check if LSI is used as system clock */
445 if (__HAL_RCC_GET_SYSCLK_SOURCE() == RCC_CFGR_SWS_LSI)
446 {
447 /* When LSI is used as system clock it will not be disabled */
448 if (RCC_OscInitStruct->LSIState == RCC_LSI_OFF)
449 {
450 return HAL_ERROR;
451 }
452 }
453 else
454 {
455 /* Check the LSI State */
456 if (RCC_OscInitStruct->LSIState != RCC_LSI_OFF)
457 {
458 /* Enable the Internal Low Speed oscillator (LSI). */
459 __HAL_RCC_LSI_ENABLE();
460
461 /* Get Start Tick*/
462 tickstart = HAL_GetTick();
463
464 /* Wait till LSI is ready */
465 while (READ_BIT(RCC->CSR2, RCC_CSR2_LSIRDY) == 0U)
466 {
467 if ((HAL_GetTick() - tickstart) > RCC_LSI_TIMEOUT_VALUE)
468 {
469 return HAL_TIMEOUT;
470 }
471 }
472 }
473 else
474 {
475 /* Disable the Internal Low Speed oscillator (LSI). */
476 __HAL_RCC_LSI_DISABLE();
477
478 /* Get Start Tick*/
479 tickstart = HAL_GetTick();
480
481 /* Wait till LSI is disabled */
482 while (READ_BIT(RCC->CSR2, RCC_CSR2_LSIRDY) != 0U)
483 {
484 if ((HAL_GetTick() - tickstart) > RCC_LSI_TIMEOUT_VALUE)
485 {
486 return HAL_TIMEOUT;
487 }
488 }
489 }
490 }
491 }
492 /*------------------------------ LSE Configuration -------------------------*/
493 if (((RCC_OscInitStruct->OscillatorType) & RCC_OSCILLATORTYPE_LSE) == RCC_OSCILLATORTYPE_LSE)
494 {
495 FlagStatus pwrclkchanged = RESET;
496
497 /* Check the parameters */
498 assert_param(IS_RCC_LSE(RCC_OscInitStruct->LSEState));
499
500 /* When the LSE is used as system clock, it is not allowed disable it */
501 if (__HAL_RCC_GET_SYSCLK_SOURCE() == RCC_CFGR_SWS_LSE)
502 {
503 if (RCC_OscInitStruct->LSEState == RCC_LSE_OFF)
504 {
505 return HAL_ERROR;
506 }
507 }
508 else
509 {
510 /* Update LSE configuration in RTC Domain control register */
511 /* Set the new LSE configuration -----------------------------------------*/
512 __HAL_RCC_LSE_CONFIG(RCC_OscInitStruct->LSEState);
513
514 /* Check the LSE State */
515 if (RCC_OscInitStruct->LSEState != RCC_LSE_OFF)
516 {
517 /* Get Start Tick*/
518 tickstart = HAL_GetTick();
519
520 /* Wait till LSE is ready */
521 while (READ_BIT(RCC->CSR1, RCC_CSR1_LSERDY) == 0U)
522 {
523 if ((HAL_GetTick() - tickstart) > RCC_LSE_TIMEOUT_VALUE)
524 {
525 return HAL_TIMEOUT;
526 }
527 }
528 }
529 else
530 {
531 /* Get Start Tick*/
532 tickstart = HAL_GetTick();
533
534 /* Wait till LSE is disabled */
535 while (READ_BIT(RCC->CSR1, RCC_CSR1_LSERDY) != 0U)
536 {
537 if ((HAL_GetTick() - tickstart) > RCC_LSE_TIMEOUT_VALUE)
538 {
539 return HAL_TIMEOUT;
540 }
541 }
542 }
543
544 /* Restore clock configuration if changed */
545 if (pwrclkchanged == SET)
546 {
547 __HAL_RCC_PWR_CLK_DISABLE();
548 }
549 }
550 }
551 #if defined(RCC_CR_HSIUSB48ON)
552 /*------------------------------ HSI48 Configuration -----------------------*/
553 if (((RCC_OscInitStruct->OscillatorType) & RCC_OSCILLATORTYPE_HSI48) == RCC_OSCILLATORTYPE_HSI48)
554 {
555 /* Check the parameters */
556 assert_param(IS_RCC_HSI48(RCC_OscInitStruct->HSI48State));
557
558 /* Check the LSI State */
559 if (RCC_OscInitStruct->HSI48State != RCC_HSI48_OFF)
560 {
561 /* Enable the Internal Low Speed oscillator (HSI48). */
562 __HAL_RCC_HSI48_ENABLE();
563
564 /* Get Start Tick*/
565 tickstart = HAL_GetTick();
566
567 /* Wait till HSI48 is ready */
568 while (READ_BIT(RCC->CR, RCC_CR_HSIUSB48RDY) == 0U)
569 {
570 if ((HAL_GetTick() - tickstart) > HSI48_TIMEOUT_VALUE)
571 {
572 return HAL_TIMEOUT;
573 }
574 }
575 }
576 else
577 {
578 /* Disable the Internal Low Speed oscillator (HSI48). */
579 __HAL_RCC_HSI48_DISABLE();
580
581 /* Get Start Tick*/
582 tickstart = HAL_GetTick();
583
584 /* Wait till HSI48 is disabled */
585 while (READ_BIT(RCC->CR, RCC_CR_HSIUSB48RDY) != 0U)
586 {
587 if ((HAL_GetTick() - tickstart) > HSI48_TIMEOUT_VALUE)
588 {
589 return HAL_TIMEOUT;
590 }
591 }
592 }
593 }
594 #endif /* RCC_CR_HSIUSB48ON */
595 return HAL_OK;
596 }
597
598 /**
599 * @brief Initialize the CPU, AHB and APB busses clocks according to the specified
600 * parameters in the RCC_ClkInitStruct.
601 * @param RCC_ClkInitStruct pointer to a @ref RCC_ClkInitTypeDef structure that
602 * contains the configuration information for the RCC peripheral.
603 * @param FLatency FLASH Latency
604 * This parameter can be one of the following values:
605 * @arg FLASH_LATENCY_0 FLASH 0 Latency cycle
606 * @arg FLASH_LATENCY_1 FLASH 1 Latency cycle
607 *
608 * @note The SystemCoreClock CMSIS variable is used to store System Clock Frequency
609 * and updated by @ref HAL_RCC_GetHCLKFreq() function called within this function
610 *
611 * @note The HSI is used by default as system clock source after
612 * startup from Reset, wake-up from STANDBY mode. After restart from Reset,
613 * the HSI frequency is set to 12 Mhz, as HSI divider is set to 4.
614 *
615 * @note The HSI can be selected as system clock source after
616 * from STOP modes or in case of failure of the HSE used directly or indirectly
617 * as system clock (if the Clock Security System CSS is enabled).
618 *
619 * @note The LSI can be selected as system clock source after
620 * in case of failure of the LSE used directly or indirectly
621 * as system clock (if the Clock Security System LSECSS is enabled).
622 *
623 * @note A switch from one clock source to another occurs only if the target
624 * clock source is ready (clock stable after startup delay).
625 * If a clock source which is not yet ready is selected, the switch will
626 * occur when the clock source is ready.
627 *
628 * @note You can use @ref HAL_RCC_GetClockConfig() function to know which clock is
629 * currently used as system clock source.
630 *
631 * @note Depending on the device voltage range, the software has to set correctly
632 * HPRE[3:0] bits to ensure that HCLK not exceed the maximum allowed frequency
633 * (for more details refer to section above "Initialization/de-initialization functions")
634 * @retval None
635 */
HAL_RCC_ClockConfig(const RCC_ClkInitTypeDef * RCC_ClkInitStruct,uint32_t FLatency)636 HAL_StatusTypeDef HAL_RCC_ClockConfig(const RCC_ClkInitTypeDef *RCC_ClkInitStruct, uint32_t FLatency)
637 {
638 uint32_t tickstart;
639
640 /* Check Null pointer */
641 if (RCC_ClkInitStruct == NULL)
642 {
643 return HAL_ERROR;
644 }
645
646 /* Check the parameters */
647 assert_param(IS_RCC_CLOCKTYPE(RCC_ClkInitStruct->ClockType));
648 assert_param(IS_FLASH_LATENCY(FLatency));
649
650 /* To correctly read data from FLASH memory, the number of wait states (LATENCY)
651 must be correctly programmed according to the frequency of the FLASH clock
652 (HCLK) and the supply voltage of the device. */
653
654 /* Increasing the number of wait states because of higher CPU frequency */
655 if (FLatency > __HAL_FLASH_GET_LATENCY())
656 {
657 /* Program the new number of wait states to the LATENCY bits in the FLASH_ACR register */
658 __HAL_FLASH_SET_LATENCY(FLatency);
659
660 /* Check that the new number of wait states is taken into account to access the Flash
661 memory by polling the FLASH_ACR register */
662 tickstart = HAL_GetTick();
663
664 while ((FLASH->ACR & FLASH_ACR_LATENCY) != FLatency)
665 {
666 if ((HAL_GetTick() - tickstart) > RCC_CLOCKSWITCH_TIMEOUT_VALUE)
667 {
668 return HAL_TIMEOUT;
669 }
670 }
671 }
672
673 /*-------------------------- HCLK Configuration --------------------------*/
674 if (((RCC_ClkInitStruct->ClockType) & RCC_CLOCKTYPE_HCLK) == RCC_CLOCKTYPE_HCLK)
675 {
676 /* Set the highest APB divider in order to ensure that we do not go through
677 a non-spec phase whatever we decrease or increase HCLK. */
678 if (((RCC_ClkInitStruct->ClockType) & RCC_CLOCKTYPE_PCLK1) == RCC_CLOCKTYPE_PCLK1)
679 {
680 MODIFY_REG(RCC->CFGR, RCC_CFGR_PPRE, RCC_HCLK_DIV16);
681 }
682
683 /* Set the new HCLK clock divider */
684 assert_param(IS_RCC_HCLK(RCC_ClkInitStruct->AHBCLKDivider));
685 MODIFY_REG(RCC->CFGR, RCC_CFGR_HPRE, RCC_ClkInitStruct->AHBCLKDivider);
686 }
687
688 /*------------------------- SYSCLK Configuration ---------------------------*/
689 if (((RCC_ClkInitStruct->ClockType) & RCC_CLOCKTYPE_SYSCLK) == RCC_CLOCKTYPE_SYSCLK)
690 {
691 assert_param(IS_RCC_SYSCLK(RCC_ClkInitStruct->SYSCLKDivider));
692 assert_param(IS_RCC_SYSCLKSOURCE(RCC_ClkInitStruct->SYSCLKSource));
693
694 #if defined(RCC_CR_SYSDIV)
695 MODIFY_REG(RCC->CR, RCC_CR_SYSDIV, RCC_ClkInitStruct->SYSCLKDivider);
696 #endif /* RCC_CR_SYSDIV */
697
698 /* HSE is selected as System Clock Source */
699 if (RCC_ClkInitStruct->SYSCLKSource == RCC_SYSCLKSOURCE_HSE)
700 {
701 /* Check the HSE ready flag */
702 if (READ_BIT(RCC->CR, RCC_CR_HSERDY) == 0U)
703 {
704 return HAL_ERROR;
705 }
706 }
707 /* HSI is selected as System Clock Source */
708 else if (RCC_ClkInitStruct->SYSCLKSource == RCC_SYSCLKSOURCE_HSI)
709 {
710 /* Check the HSI ready flag */
711 if (READ_BIT(RCC->CR, RCC_CR_HSIRDY) == 0U)
712 {
713 return HAL_ERROR;
714 }
715 }
716 #if defined(RCC_HSI48_SUPPORT)
717 /* HSIUSB48 is selected as System Clock Source */
718 else if (RCC_ClkInitStruct->SYSCLKSource == RCC_SYSCLKSOURCE_HSIUSB48)
719 {
720 /* Check the HSIUSB48 ready flag */
721 if (READ_BIT(RCC->CR, RCC_CR_HSIUSB48RDY) == 0U)
722 {
723 return HAL_ERROR;
724 }
725 }
726 #endif /* RCC_HSI48_SUPPORT */
727 /* LSI is selected as System Clock Source */
728 else if (RCC_ClkInitStruct->SYSCLKSource == RCC_SYSCLKSOURCE_LSI)
729 {
730 /* Check the LSI ready flag */
731 if (READ_BIT(RCC->CSR2, RCC_CSR2_LSIRDY) == 0U)
732 {
733 return HAL_ERROR;
734 }
735 }
736 /* LSE is selected as System Clock Source */
737 else
738 {
739 /* Check the LSE ready flag */
740 if (READ_BIT(RCC->CSR1, RCC_CSR1_LSERDY) == 0U)
741 {
742 return HAL_ERROR;
743 }
744 }
745 MODIFY_REG(RCC->CFGR, RCC_CFGR_SW, RCC_ClkInitStruct->SYSCLKSource);
746
747 /* Get Start Tick*/
748 tickstart = HAL_GetTick();
749
750 while (__HAL_RCC_GET_SYSCLK_SOURCE() != (RCC_ClkInitStruct->SYSCLKSource << RCC_CFGR_SWS_Pos))
751 {
752 if ((HAL_GetTick() - tickstart) > RCC_CLOCKSWITCH_TIMEOUT_VALUE)
753 {
754 return HAL_TIMEOUT;
755 }
756 }
757 }
758
759 /* Decreasing the number of wait states because of lower CPU frequency */
760 if (FLatency < __HAL_FLASH_GET_LATENCY())
761 {
762 /* Program the new number of wait states to the LATENCY bits in the FLASH_ACR register */
763 __HAL_FLASH_SET_LATENCY(FLatency);
764
765 /* Check that the new number of wait states is taken into account to access the Flash
766 memory by polling the FLASH_ACR register */
767 tickstart = HAL_GetTick();
768
769 while ((FLASH->ACR & FLASH_ACR_LATENCY) != FLatency)
770 {
771 if ((HAL_GetTick() - tickstart) > RCC_CLOCKSWITCH_TIMEOUT_VALUE)
772 {
773 return HAL_TIMEOUT;
774 }
775 }
776 }
777
778 /*-------------------------- PCLK1 Configuration ---------------------------*/
779 if (((RCC_ClkInitStruct->ClockType) & RCC_CLOCKTYPE_PCLK1) == RCC_CLOCKTYPE_PCLK1)
780 {
781 assert_param(IS_RCC_PCLK(RCC_ClkInitStruct->APB1CLKDivider));
782 MODIFY_REG(RCC->CFGR, RCC_CFGR_PPRE, RCC_ClkInitStruct->APB1CLKDivider);
783 }
784
785 /* Update the SystemCoreClock global variable */
786 SystemCoreClock = (HAL_RCC_GetSysClockFreq() >> ((AHBPrescTable[(RCC->CFGR & RCC_CFGR_HPRE) \
787 >> RCC_CFGR_HPRE_Pos]) & 0x1FU));
788
789 /* Configure the source of time base considering new system clocks settings*/
790 return HAL_InitTick(uwTickPrio);
791 }
792
793 /**
794 * @}
795 */
796
797 /** @defgroup RCC_Exported_Functions_Group2 Peripheral Control functions
798 * @brief RCC clocks control functions
799 *
800 @verbatim
801 ===============================================================================
802 ##### Peripheral Control functions #####
803 ===============================================================================
804 [..]
805 This subsection provides a set of functions allowing to:
806
807 (+) output clock to MCO pin.
808 (+) Retrieve current clock frequencies.
809 (+) Enable the Clock Security System.
810
811 @endverbatim
812 * @{
813 */
814
815 /**
816 * @brief Select the clock source to output on MCOx pin.
817 * @note PA8 for MCO1 and PB2 for MCO2 should be configured in alternate function mode.
818 * @param RCC_MCOx specifies the output direction for the clock source.
819 * @arg @ref RCC_MCO1 Clock source to output on MCO1 pins.
820 * @arg @ref RCC_MCO2 Clock source to output on MCO2 pins.
821 * @param RCC_MCOSource specifies the clock source to output.
822 * This parameter can be one of the following values:
823 * @arg @ref RCC_MCO1SOURCE_NOCLOCK MCO1 output disabled, no clock on MCO1
824 * @arg @ref RCC_MCO1SOURCE_SYSCLK system clock selected as MCO1 source
825 * @arg @ref RCC_MCO1SOURCE_HSI HSI clock selected as MCO1 source
826 * @arg @ref RCC_MCO1SOURCE_HSI48 HSI48 clock selected as MCO1 source (*)
827 * @arg @ref RCC_MCO1SOURCE_HSE HSE clock selected as MCO1 source
828 * @arg @ref RCC_MCO1SOURCE_LSI LSI clock selected as MCO1 source
829 * @arg @ref RCC_MCO1SOURCE_LSE LSE clock selected as MCO1 source
830 * @arg @ref RCC_MCO2SOURCE_NOCLOCK MCO2 output disabled, no clock on MCO2
831 * @arg @ref RCC_MCO2SOURCE_SYSCLK system clock selected as MCO2 source
832 * @arg @ref RCC_MCO2SOURCE_HSI HSI clock selected as MCO2 source
833 * @arg @ref RCC_MCO2SOURCE_HSI48 HSI48 clock selected as MCO2 source (*)
834 * @arg @ref RCC_MCO2SOURCE_HSE HSE clock selected as MCO2 source
835 * @arg @ref RCC_MCO2SOURCE_LSI LSI clock selected as MCO2 source
836 * @arg @ref RCC_MCO2SOURCE_LSE LSE clock selected as MCO2 source
837 * @param RCC_MCODiv specifies the MCO prescaler.
838 * This parameter can be one of the following values:
839 * @arg @ref RCC_MCODIV_1 no division applied to MCO clock
840 * @arg @ref RCC_MCODIV_2 division by 2 applied to MCO clock
841 * @arg @ref RCC_MCODIV_4 division by 4 applied to MCO clock
842 * @arg @ref RCC_MCODIV_8 division by 8 applied to MCO clock
843 * @arg @ref RCC_MCODIV_16 division by 16 applied to MCO clock
844 * @arg @ref RCC_MCODIV_32 division by 32 applied to MCO clock
845 * @arg @ref RCC_MCODIV_64 division by 64 applied to MCO clock
846 * @arg @ref RCC_MCODIV_128 division by 128 applied to MCO clock
847 * @note (*) peripheral not available on all devices
848 * @retval None
849 */
HAL_RCC_MCOConfig(uint32_t RCC_MCOx,uint32_t RCC_MCOSource,uint32_t RCC_MCODiv)850 void HAL_RCC_MCOConfig(uint32_t RCC_MCOx, uint32_t RCC_MCOSource, uint32_t RCC_MCODiv)
851 {
852 GPIO_InitTypeDef gpio_initstruct;
853 uint32_t mcoindex;
854 uint32_t mco_gpio_index;
855 GPIO_TypeDef *mco_gpio_port;
856
857 /* Check the parameters */
858 assert_param(IS_RCC_MCO(RCC_MCOx));
859
860 /* Common GPIO init parameters */
861 gpio_initstruct.Mode = GPIO_MODE_AF_PP;
862 gpio_initstruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
863 gpio_initstruct.Pull = GPIO_NOPULL;
864
865 /* Get MCOx selection */
866 mcoindex = RCC_MCOx & RCC_MCO_INDEX_MASK;
867
868 /* Get MCOx GPIO Port */
869 mco_gpio_port = (GPIO_TypeDef *) RCC_GET_MCO_GPIO_PORT(RCC_MCOx);
870
871 /* MCOx Clock Enable */
872 mco_gpio_index = RCC_GET_MCO_GPIO_INDEX(RCC_MCOx);
873 SET_BIT(RCC->IOPENR, (1UL << mco_gpio_index));
874
875 /* Configure the MCOx pin in alternate function mode */
876 gpio_initstruct.Pin = RCC_GET_MCO_GPIO_PIN(RCC_MCOx);
877 gpio_initstruct.Alternate = RCC_GET_MCO_GPIO_AF(RCC_MCOx);
878 HAL_GPIO_Init(mco_gpio_port, &gpio_initstruct);
879
880 if (mcoindex == RCC_MCO1_INDEX)
881 {
882 assert_param(IS_RCC_MCODIV(RCC_MCODiv));
883 assert_param(IS_RCC_MCO1SOURCE(RCC_MCOSource));
884 /* Mask MCOSEL[] and MCOPRE[] bits then set MCO clock source and prescaler */
885 LL_RCC_ConfigMCO(RCC_MCOSource, RCC_MCODiv);
886 }
887 else if (mcoindex == RCC_MCO2_INDEX)
888 {
889 assert_param(IS_RCC_MCO2DIV(RCC_MCODiv));
890 assert_param(IS_RCC_MCO2SOURCE(RCC_MCOSource));
891 /* Mask MCOSEL[] and MCOPRE[] bits then set MCO clock source and prescaler */
892 LL_RCC_ConfigMCO2(RCC_MCOSource, RCC_MCODiv);
893 }
894 else
895 {
896 /* unexpected case: added to resolve MISRA 15.7 rule */
897 }
898 }
899
900 /**
901 * @brief Return the SYSCLK frequency.
902 *
903 * @note The system frequency computed by this function is not the real
904 * frequency in the chip. It is calculated based on the predefined
905 * constant and the selected clock source:
906 * @note If SYSCLK source is HSI, function returns values based on HSI_VALUE/HSIDIV(*)
907 * @note If SYSCLK source is HSE, function returns values based on HSE_VALUE(**)
908 * @note If SYSCLK source is LSI, function returns values based on LSI_VALUE(***)
909 * @note If SYSCLK source is LSE, function returns values based on LSE_VALUE(****)
910 * @note (*) HSI_VALUE is a constant defined in stm32c0xx_hal_conf.h file (default value
911 * 48 MHz) but the real value may vary depending on the variations
912 * in voltage and temperature.
913 * @note (**) HSE_VALUE is a constant defined in stm32c0xx_hal_conf.h file (default value
914 * 48 MHz), user has to ensure that HSE_VALUE is same as the real
915 * frequency of the crystal used. Otherwise, this function may
916 * have wrong result.
917 * @note (***) LSE_VALUE is a constant defined in stm32c0xx_hal_conf.h file (default value
918 * 32768 Hz).
919 * @note (****) LSI_VALUE is a constant defined in stm32c0xx_hal_conf.h file (default value
920 * 32000 Hz).
921 *
922 * @note The result of this function could be not correct when using fractional
923 * value for HSE crystal.
924 *
925 * @note This function can be used by the user application to compute the
926 * baudrate for the communication peripherals or configure other parameters.
927 *
928 * @note Each time SYSCLK changes, this function must be called to update the
929 * right SYSCLK value. Otherwise, any configuration based on this function will be incorrect.
930 *
931 *
932 * @retval SYSCLK frequency
933 */
HAL_RCC_GetSysClockFreq(void)934 uint32_t HAL_RCC_GetSysClockFreq(void)
935 {
936 uint32_t hsidiv;
937 uint32_t sysclockfreq;
938 #if defined(RCC_CR_SYSDIV)
939 uint32_t sysclockdiv = (uint32_t)(((RCC->CR & RCC_CR_SYSDIV) >> RCC_CR_SYSDIV_Pos) + 1U);
940 #endif /* RCC_CR_SYSDIV */
941
942 if (__HAL_RCC_GET_SYSCLK_SOURCE() == RCC_CFGR_SWS_HSI)
943 {
944 /* HSISYS can be derived for HSI48 */
945 hsidiv = (1UL << ((READ_BIT(RCC->CR, RCC_CR_HSIDIV)) >> RCC_CR_HSIDIV_Pos));
946
947 /* HSI used as system clock source */
948 sysclockfreq = (HSI_VALUE / hsidiv);
949 }
950 else if (__HAL_RCC_GET_SYSCLK_SOURCE() == RCC_CFGR_SWS_HSE)
951 {
952 /* HSE used as system clock source */
953 sysclockfreq = HSE_VALUE;
954 }
955 else if (__HAL_RCC_GET_SYSCLK_SOURCE() == RCC_CFGR_SWS_LSE)
956 {
957 /* LSE used as system clock source */
958 sysclockfreq = LSE_VALUE;
959 }
960 else if (__HAL_RCC_GET_SYSCLK_SOURCE() == RCC_CFGR_SWS_LSI)
961 {
962 /* LSI used as system clock source */
963 sysclockfreq = LSI_VALUE;
964 }
965 #if defined(RCC_HSI48_SUPPORT)
966 else if (__HAL_RCC_GET_SYSCLK_SOURCE() == RCC_CFGR_SWS_HSI48)
967 {
968 /* HSI48 used as system clock source */
969 sysclockfreq = HSI48_VALUE;
970 }
971 #endif /* RCC_HSI48_SUPPORT */
972 else
973 {
974 sysclockfreq = 0U;
975 }
976 #if defined(RCC_CR_SYSDIV)
977 sysclockfreq = sysclockfreq / sysclockdiv;
978 #endif /* RCC_CR_SYSDIV */
979 return sysclockfreq;
980 }
981
982 /**
983 * @brief Return the HCLK frequency.
984 * @note Each time HCLK changes, this function must be called to update the
985 * right HCLK value. Otherwise, any configuration based on this function will be incorrect.
986 *
987 * @note The SystemCoreClock CMSIS variable is used to store System Clock Frequency.
988 * @retval HCLK frequency in Hz
989 */
HAL_RCC_GetHCLKFreq(void)990 uint32_t HAL_RCC_GetHCLKFreq(void)
991 {
992 SystemCoreClock = (HAL_RCC_GetSysClockFreq() >> ((AHBPrescTable[(RCC->CFGR & RCC_CFGR_HPRE) \
993 >> RCC_CFGR_HPRE_Pos]) & 0x1FU));
994 return SystemCoreClock;
995 }
996
997 /**
998 * @brief Return the PCLK1 frequency.
999 * @note Each time PCLK1 changes, this function must be called to update the
1000 * right PCLK1 value. Otherwise, any configuration based on this function will be incorrect.
1001 * @retval PCLK1 frequency in Hz
1002 */
HAL_RCC_GetPCLK1Freq(void)1003 uint32_t HAL_RCC_GetPCLK1Freq(void)
1004 {
1005 /* Get HCLK source and Compute PCLK1 frequency ---------------------------*/
1006 return (HAL_RCC_GetHCLKFreq() >> ((APBPrescTable[(RCC->CFGR & RCC_CFGR_PPRE) >> RCC_CFGR_PPRE_Pos]) & 0x1FU));
1007 }
1008
1009 /**
1010 * @brief Configure the RCC_OscInitStruct according to the internal
1011 * RCC configuration registers.
1012 * @param RCC_OscInitStruct pointer to an RCC_OscInitTypeDef structure that
1013 * will be configured.
1014 * @retval None
1015 */
HAL_RCC_GetOscConfig(RCC_OscInitTypeDef * RCC_OscInitStruct)1016 void HAL_RCC_GetOscConfig(RCC_OscInitTypeDef *RCC_OscInitStruct)
1017 {
1018 uint32_t regval;
1019
1020 /* Check the parameters */
1021 assert_param(RCC_OscInitStruct != (void *)NULL);
1022
1023 /* Set all possible values for the Oscillator type parameter ---------------*/
1024 #if defined(RCC_HSI48_SUPPORT)
1025 RCC_OscInitStruct->OscillatorType = RCC_OSCILLATORTYPE_HSE | RCC_OSCILLATORTYPE_HSI | \
1026 RCC_OSCILLATORTYPE_LSE | RCC_OSCILLATORTYPE_LSI | RCC_OSCILLATORTYPE_HSI48;
1027 #else
1028 RCC_OscInitStruct->OscillatorType = RCC_OSCILLATORTYPE_HSE | RCC_OSCILLATORTYPE_HSI | \
1029 RCC_OSCILLATORTYPE_LSE | RCC_OSCILLATORTYPE_LSI;
1030 #endif /* RCC_HSI48_SUPPORT */
1031 /* Get Control register */
1032 regval = RCC->CR;
1033
1034 /* Get the HSE configuration -----------------------------------------------*/
1035 RCC_OscInitStruct->HSEState = (regval & (RCC_CR_HSEON | RCC_CR_HSEBYP));
1036
1037 /* Get the HSI configuration -----------------------------------------------*/
1038 RCC_OscInitStruct->HSIState = regval & RCC_CR_HSION;
1039 RCC_OscInitStruct->HSICalibrationValue = ((RCC->ICSCR & RCC_ICSCR_HSITRIM) >> RCC_ICSCR_HSITRIM_Pos);
1040 RCC_OscInitStruct->HSIDiv = ((regval & RCC_CR_HSIDIV) >> RCC_CR_HSIDIV_Pos);
1041
1042 /* Get CSR1 register */
1043 regval = RCC->CSR1;
1044
1045 /* Get the LSE configuration -----------------------------------------------*/
1046 RCC_OscInitStruct->LSEState = (regval & (RCC_CSR1_LSEON | RCC_CSR1_LSEBYP));
1047
1048 /* Get CSR2 register */
1049 regval = RCC->CSR2;
1050
1051 /* Get the LSI configuration -----------------------------------------------*/
1052 RCC_OscInitStruct->LSIState = regval & RCC_CSR2_LSION;
1053
1054 #if defined(RCC_HSI48_SUPPORT)
1055 /* Get the HSI48 configuration ---------------------------------------------*/
1056 if (READ_BIT(RCC->CR, RCC_CR_HSIUSB48ON) == RCC_CR_HSIUSB48ON)
1057 {
1058 RCC_OscInitStruct->HSI48State = RCC_HSI48_ON;
1059 }
1060 else
1061 {
1062 RCC_OscInitStruct->HSI48State = RCC_HSI48_OFF;
1063 }
1064 #endif /* RCC_HSI48_SUPPORT */
1065
1066 }
1067
1068 /**
1069 * @brief Configure the RCC_ClkInitStruct according to the internal
1070 * RCC configuration registers.
1071 * @param RCC_ClkInitStruct Pointer to a @ref RCC_ClkInitTypeDef structure that
1072 * will be configured.
1073 * @param pFLatency Pointer on the Flash Latency.
1074 * @retval None
1075 */
HAL_RCC_GetClockConfig(RCC_ClkInitTypeDef * RCC_ClkInitStruct,uint32_t * pFLatency)1076 void HAL_RCC_GetClockConfig(RCC_ClkInitTypeDef *RCC_ClkInitStruct, uint32_t *pFLatency)
1077 {
1078 /* Check the parameters */
1079 assert_param(RCC_ClkInitStruct != (void *)NULL);
1080 assert_param(pFLatency != (void *)NULL);
1081
1082 /* Set all possible values for the Clock type parameter --------------------*/
1083 RCC_ClkInitStruct->ClockType = RCC_CLOCKTYPE_SYSCLK | RCC_CLOCKTYPE_HCLK | RCC_CLOCKTYPE_PCLK1;
1084
1085 /* Get the SYSCLK configuration --------------------------------------------*/
1086 RCC_ClkInitStruct->SYSCLKSource = (uint32_t)(RCC->CFGR & RCC_CFGR_SW);
1087
1088 #if defined(RCC_CR_SYSDIV)
1089 /* Get the SYSCLK configuration ----------------------------------------------*/
1090 RCC_ClkInitStruct->SYSCLKDivider = (uint32_t)(RCC->CR & RCC_CR_SYSDIV);
1091 #endif /* RCC_CR_SYSDIV */
1092
1093 /* Get the HCLK configuration ----------------------------------------------*/
1094 RCC_ClkInitStruct->AHBCLKDivider = (uint32_t)(RCC->CFGR & RCC_CFGR_HPRE);
1095
1096 /* Get the APB1 configuration ----------------------------------------------*/
1097 RCC_ClkInitStruct->APB1CLKDivider = (uint32_t)(RCC->CFGR & RCC_CFGR_PPRE);
1098
1099
1100 /* Get the Flash Wait State (Latency) configuration ------------------------*/
1101 *pFLatency = (uint32_t)(FLASH->ACR & FLASH_ACR_LATENCY);
1102 }
1103
1104 /**
1105 * @brief Enable the Clock Security System.
1106 * @note If a failure is detected on the HSE oscillator clock, this oscillator
1107 * is automatically disabled and an interrupt is generated to inform the
1108 * software about the failure (Clock Security System Interrupt, CSSI),
1109 * allowing the MCU to perform rescue operations. The CSSI is linked to
1110 * the Cortex-M0+ NMI (Non-Maskable Interrupt) exception vector.
1111 * @note The Clock Security System can only be cleared by reset.
1112 * @retval None
1113 */
HAL_RCC_EnableCSS(void)1114 void HAL_RCC_EnableCSS(void)
1115 {
1116 SET_BIT(RCC->CR, RCC_CR_CSSON) ;
1117 }
1118
1119 /**
1120 * @brief Enable the LSE Clock Security System.
1121 * @note If a failure is detected on the LSE oscillator clock, this oscillator
1122 * is automatically disabled and an interrupt is generated to inform the
1123 * software about the failure (Clock Security System Interrupt, CSSI),
1124 * allowing the MCU to perform rescue operations. The CSSI is linked to
1125 * the Cortex-M0+ NMI (Non-Maskable Interrupt) exception vector.
1126 * @note The LSE Clock Security System Detection bit (LSECSSD in CSR1) can only be
1127 * cleared by a backup domain reset.
1128 * @retval None
1129 */
HAL_RCC_EnableLSECSS(void)1130 void HAL_RCC_EnableLSECSS(void)
1131 {
1132 SET_BIT(RCC->CSR1, RCC_CSR1_LSECSSON) ;
1133 }
1134
1135 /**
1136 * @brief Disable the LSE Clock Security System.
1137 * @note After LSE failure detection, the software must disable LSECSSON
1138 * @note The Clock Security System can only be cleared by reset otherwise.
1139 * @retval None
1140 */
HAL_RCC_DisableLSECSS(void)1141 void HAL_RCC_DisableLSECSS(void)
1142 {
1143 CLEAR_BIT(RCC->CSR1, RCC_CSR1_LSECSSON) ;
1144 }
1145
1146 /**
1147 * @brief Handle the RCC Clock Security System interrupt request.
1148 * @note This API should be called under the NMI_Handler().
1149 * @retval None
1150 */
HAL_RCC_NMI_IRQHandler(void)1151 void HAL_RCC_NMI_IRQHandler(void)
1152 {
1153 uint32_t itflag = RCC->CIFR;
1154
1155 /* Clear interrupt flags related to CSS */
1156 RCC->CICR = (itflag & (RCC_CIFR_CSSF | RCC_CIFR_LSECSSF));
1157
1158 /* Check RCC CSSF interrupt flag */
1159 if ((itflag & RCC_CIFR_CSSF) != 0x00u)
1160 {
1161 /* RCC Clock Security System interrupt user callback */
1162 HAL_RCC_CSSCallback();
1163 }
1164
1165 /* Check RCC LSECSSF interrupt flag */
1166 if ((itflag & RCC_CIFR_LSECSSF) != 0x00u)
1167 {
1168 /* RCC Clock Security System interrupt user callback */
1169 HAL_RCC_LSECSSCallback();
1170 }
1171 }
1172
1173 /**
1174 * @brief Handle the RCC HSE Clock Security System interrupt callback.
1175 * @retval none
1176 */
HAL_RCC_CSSCallback(void)1177 __weak void HAL_RCC_CSSCallback(void)
1178 {
1179 /* NOTE : This function should not be modified, when the callback is needed,
1180 the @ref HAL_RCC_CSSCallback should be implemented in the user file
1181 */
1182 }
1183
1184 /**
1185 * @brief RCC LSE Clock Security System interrupt callback.
1186 * @retval none
1187 */
HAL_RCC_LSECSSCallback(void)1188 __weak void HAL_RCC_LSECSSCallback(void)
1189 {
1190 /* NOTE : This function should not be modified, when the callback is needed,
1191 the HAL_RCC_LSECSSCallback should be implemented in the user file
1192 */
1193 }
1194
1195 /**
1196 * @}
1197 */
1198
1199 /**
1200 * @}
1201 */
1202
1203 #endif /* HAL_RCC_MODULE_ENABLED */
1204 /**
1205 * @}
1206 */
1207
1208 /**
1209 * @}
1210 */
1211