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