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