Merge pull request #11198 from SteveCEvans/sce_rc2
[betaflight.git] / lib / main / STM32F4 / Drivers / STM32F4xx_HAL_Driver / Src / stm32f4xx_hal_rcc.c
blobb34b9543b26decbd98df27a735dc6cf874e6cb6e
1 /**
2 ******************************************************************************
3 * @file stm32f4xx_hal_rcc.c
4 * @author MCD Application Team
5 * @version V1.7.1
6 * @date 14-April-2017
7 * @brief RCC HAL module driver.
8 * This file provides firmware functions to manage the following
9 * functionalities of the Reset and Clock Control (RCC) peripheral:
10 * + Initialization and de-initialization functions
11 * + Peripheral Control functions
13 @verbatim
14 ==============================================================================
15 ##### RCC specific features #####
16 ==============================================================================
17 [..]
18 After reset the device is running from Internal High Speed oscillator
19 (HSI 16MHz) with Flash 0 wait state, Flash prefetch buffer, D-Cache
20 and I-Cache are disabled, and all peripherals are off except internal
21 SRAM, Flash and JTAG.
22 (+) There is no prescaler on High speed (AHB) and Low speed (APB) busses;
23 all peripherals mapped on these busses are running at HSI speed.
24 (+) The clock for all peripherals is switched off, except the SRAM and FLASH.
25 (+) All GPIOs are in input floating state, except the JTAG pins which
26 are assigned to be used for debug purpose.
28 [..]
29 Once the device started from reset, the user application has to:
30 (+) Configure the clock source to be used to drive the System clock
31 (if the application needs higher frequency/performance)
32 (+) Configure the System clock frequency and Flash settings
33 (+) Configure the AHB and APB busses prescalers
34 (+) Enable the clock for the peripheral(s) to be used
35 (+) Configure the clock source(s) for peripherals which clocks are not
36 derived from the System clock (I2S, RTC, ADC, USB OTG FS/SDIO/RNG)
38 ##### RCC Limitations #####
39 ==============================================================================
40 [..]
41 A delay between an RCC peripheral clock enable and the effective peripheral
42 enabling should be taken into account in order to manage the peripheral read/write
43 from/to registers.
44 (+) This delay depends on the peripheral mapping.
45 (+) If peripheral is mapped on AHB: the delay is 2 AHB clock cycle
46 after the clock enable bit is set on the hardware register
47 (+) If peripheral is mapped on APB: the delay is 2 APB clock cycle
48 after the clock enable bit is set on the hardware register
50 [..]
51 Implemented Workaround:
52 (+) For AHB & APB peripherals, a dummy read to the peripheral register has been
53 inserted in each __HAL_RCC_PPP_CLK_ENABLE() macro.
55 @endverbatim
56 ******************************************************************************
57 * @attention
59 * <h2><center>&copy; COPYRIGHT(c) 2017 STMicroelectronics</center></h2>
61 * Redistribution and use in source and binary forms, with or without modification,
62 * are permitted provided that the following conditions are met:
63 * 1. Redistributions of source code must retain the above copyright notice,
64 * this list of conditions and the following disclaimer.
65 * 2. Redistributions in binary form must reproduce the above copyright notice,
66 * this list of conditions and the following disclaimer in the documentation
67 * and/or other materials provided with the distribution.
68 * 3. Neither the name of STMicroelectronics nor the names of its contributors
69 * may be used to endorse or promote products derived from this software
70 * without specific prior written permission.
72 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
73 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
74 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
75 * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
76 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
77 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
78 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
79 * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
80 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
81 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
83 ******************************************************************************
84 */
86 /* Includes ------------------------------------------------------------------*/
87 #include "stm32f4xx_hal.h"
89 /** @addtogroup STM32F4xx_HAL_Driver
90 * @{
93 /** @defgroup RCC RCC
94 * @brief RCC HAL module driver
95 * @{
98 #ifdef HAL_RCC_MODULE_ENABLED
100 /* Private typedef -----------------------------------------------------------*/
101 /* Private define ------------------------------------------------------------*/
102 /** @addtogroup RCC_Private_Constants
103 * @{
105 #define CLOCKSWITCH_TIMEOUT_VALUE 5000U /* 5 s */
107 /* Private macro -------------------------------------------------------------*/
108 #define __MCO1_CLK_ENABLE() __HAL_RCC_GPIOA_CLK_ENABLE()
109 #define MCO1_GPIO_PORT GPIOA
110 #define MCO1_PIN GPIO_PIN_8
112 #define __MCO2_CLK_ENABLE() __HAL_RCC_GPIOC_CLK_ENABLE()
113 #define MCO2_GPIO_PORT GPIOC
114 #define MCO2_PIN GPIO_PIN_9
116 * @}
119 /* Private variables ---------------------------------------------------------*/
120 /** @defgroup RCC_Private_Variables RCC Private Variables
121 * @{
124 * @}
126 /* Private function prototypes -----------------------------------------------*/
127 /* Private functions ---------------------------------------------------------*/
129 /** @defgroup RCC_Exported_Functions RCC Exported Functions
130 * @{
133 /** @defgroup RCC_Exported_Functions_Group1 Initialization and de-initialization functions
134 * @brief Initialization and Configuration functions
136 @verbatim
137 ===============================================================================
138 ##### Initialization and de-initialization functions #####
139 ===============================================================================
140 [..]
141 This section provides functions allowing to configure the internal/external oscillators
142 (HSE, HSI, LSE, LSI, PLL, CSS and MCO) and the System busses clocks (SYSCLK, AHB, APB1
143 and APB2).
145 [..] Internal/external clock and PLL configuration
146 (#) HSI (high-speed internal), 16 MHz factory-trimmed RC used directly or through
147 the PLL as System clock source.
149 (#) LSI (low-speed internal), 32 KHz low consumption RC used as IWDG and/or RTC
150 clock source.
152 (#) HSE (high-speed external), 4 to 26 MHz crystal oscillator used directly or
153 through the PLL as System clock source. Can be used also as RTC clock source.
155 (#) LSE (low-speed external), 32 KHz oscillator used as RTC clock source.
157 (#) PLL (clocked by HSI or HSE), featuring two different output clocks:
158 (++) The first output is used to generate the high speed system clock (up to 168 MHz)
159 (++) The second output is used to generate the clock for the USB OTG FS (48 MHz),
160 the random analog generator (<=48 MHz) and the SDIO (<= 48 MHz).
162 (#) CSS (Clock security system), once enable using the macro __HAL_RCC_CSS_ENABLE()
163 and if a HSE clock failure occurs(HSE used directly or through PLL as System
164 clock source), the System clocks automatically switched to HSI and an interrupt
165 is generated if enabled. The interrupt is linked to the Cortex-M4 NMI
166 (Non-Maskable Interrupt) exception vector.
168 (#) MCO1 (microcontroller clock output), used to output HSI, LSE, HSE or PLL
169 clock (through a configurable prescaler) on PA8 pin.
171 (#) MCO2 (microcontroller clock output), used to output HSE, PLL, SYSCLK or PLLI2S
172 clock (through a configurable prescaler) on PC9 pin.
174 [..] System, AHB and APB busses clocks configuration
175 (#) Several clock sources can be used to drive the System clock (SYSCLK): HSI,
176 HSE and PLL.
177 The AHB clock (HCLK) is derived from System clock through configurable
178 prescaler and used to clock the CPU, memory and peripherals mapped
179 on AHB bus (DMA, GPIO...). APB1 (PCLK1) and APB2 (PCLK2) clocks are derived
180 from AHB clock through configurable prescalers and used to clock
181 the peripherals mapped on these busses. You can use
182 "HAL_RCC_GetSysClockFreq()" function to retrieve the frequencies of these clocks.
184 (#) For the STM32F405xx/07xx and STM32F415xx/17xx devices, the maximum
185 frequency of the SYSCLK and HCLK is 168 MHz, PCLK2 84 MHz and PCLK1 42 MHz.
186 Depending on the device voltage range, the maximum frequency should
187 be adapted accordingly (refer to the product datasheets for more details).
189 (#) For the STM32F42xxx, STM32F43xxx, STM32F446xx, STM32F469xx and STM32F479xx devices,
190 the maximum frequency of the SYSCLK and HCLK is 180 MHz, PCLK2 90 MHz and PCLK1 45 MHz.
191 Depending on the device voltage range, the maximum frequency should
192 be adapted accordingly (refer to the product datasheets for more details).
194 (#) For the STM32F401xx, the maximum frequency of the SYSCLK and HCLK is 84 MHz,
195 PCLK2 84 MHz and PCLK1 42 MHz.
196 Depending on the device voltage range, the maximum frequency should
197 be adapted accordingly (refer to the product datasheets for more details).
199 (#) For the STM32F41xxx, the maximum frequency of the SYSCLK and HCLK is 100 MHz,
200 PCLK2 100 MHz and PCLK1 50 MHz.
201 Depending on the device voltage range, the maximum frequency should
202 be adapted accordingly (refer to the product datasheets for more details).
204 @endverbatim
205 * @{
209 * @brief Resets the RCC clock configuration to the default reset state.
210 * @note The default reset state of the clock configuration is given below:
211 * - HSI ON and used as system clock source
212 * - HSE and PLL OFF
213 * - AHB, APB1 and APB2 prescaler set to 1.
214 * - CSS, MCO1 and MCO2 OFF
215 * - All interrupts disabled
216 * @note This function doesn't modify the configuration of the
217 * - Peripheral clocks
218 * - LSI, LSE and RTC clocks
219 * @retval None
221 __weak void HAL_RCC_DeInit(void)
225 * @brief Initializes the RCC Oscillators according to the specified parameters in the
226 * RCC_OscInitTypeDef.
227 * @param RCC_OscInitStruct: pointer to an RCC_OscInitTypeDef structure that
228 * contains the configuration information for the RCC Oscillators.
229 * @note The PLL is not disabled when used as system clock.
230 * @note Transitions LSE Bypass to LSE On and LSE On to LSE Bypass are not
231 * supported by this API. User should request a transition to LSE Off
232 * first and then LSE On or LSE Bypass.
233 * @note Transition HSE Bypass to HSE On and HSE On to HSE Bypass are not
234 * supported by this API. User should request a transition to HSE Off
235 * first and then HSE On or HSE Bypass.
236 * @retval HAL status
238 __weak HAL_StatusTypeDef HAL_RCC_OscConfig(RCC_OscInitTypeDef *RCC_OscInitStruct)
240 uint32_t tickstart = 0U;
242 /* Check the parameters */
243 assert_param(IS_RCC_OSCILLATORTYPE(RCC_OscInitStruct->OscillatorType));
244 /*------------------------------- HSE Configuration ------------------------*/
245 if(((RCC_OscInitStruct->OscillatorType) & RCC_OSCILLATORTYPE_HSE) == RCC_OSCILLATORTYPE_HSE)
247 /* Check the parameters */
248 assert_param(IS_RCC_HSE(RCC_OscInitStruct->HSEState));
249 /* When the HSE is used as system clock or clock source for PLL in these cases HSE will not disabled */
250 if((__HAL_RCC_GET_SYSCLK_SOURCE() == RCC_CFGR_SWS_HSE) ||\
251 ((__HAL_RCC_GET_SYSCLK_SOURCE() == RCC_CFGR_SWS_PLL) && ((RCC->PLLCFGR & RCC_PLLCFGR_PLLSRC) == RCC_PLLCFGR_PLLSRC_HSE)))
253 if((__HAL_RCC_GET_FLAG(RCC_FLAG_HSERDY) != RESET) && (RCC_OscInitStruct->HSEState == RCC_HSE_OFF))
255 return HAL_ERROR;
258 else
260 /* Set the new HSE configuration ---------------------------------------*/
261 __HAL_RCC_HSE_CONFIG(RCC_OscInitStruct->HSEState);
263 /* Check the HSE State */
264 if((RCC_OscInitStruct->HSEState) != RCC_HSE_OFF)
266 /* Get Start Tick*/
267 tickstart = HAL_GetTick();
269 /* Wait till HSE is ready */
270 while(__HAL_RCC_GET_FLAG(RCC_FLAG_HSERDY) == RESET)
272 if((HAL_GetTick() - tickstart ) > HSE_TIMEOUT_VALUE)
274 return HAL_TIMEOUT;
278 else
280 /* Get Start Tick*/
281 tickstart = HAL_GetTick();
283 /* Wait till HSE is bypassed or disabled */
284 while(__HAL_RCC_GET_FLAG(RCC_FLAG_HSERDY) != RESET)
286 if((HAL_GetTick() - tickstart ) > HSE_TIMEOUT_VALUE)
288 return HAL_TIMEOUT;
294 /*----------------------------- HSI Configuration --------------------------*/
295 if(((RCC_OscInitStruct->OscillatorType) & RCC_OSCILLATORTYPE_HSI) == RCC_OSCILLATORTYPE_HSI)
297 /* Check the parameters */
298 assert_param(IS_RCC_HSI(RCC_OscInitStruct->HSIState));
299 assert_param(IS_RCC_CALIBRATION_VALUE(RCC_OscInitStruct->HSICalibrationValue));
301 /* Check if HSI is used as system clock or as PLL source when PLL is selected as system clock */
302 if((__HAL_RCC_GET_SYSCLK_SOURCE() == RCC_CFGR_SWS_HSI) ||\
303 ((__HAL_RCC_GET_SYSCLK_SOURCE() == RCC_CFGR_SWS_PLL) && ((RCC->PLLCFGR & RCC_PLLCFGR_PLLSRC) == RCC_PLLCFGR_PLLSRC_HSI)))
305 /* When HSI is used as system clock it will not disabled */
306 if((__HAL_RCC_GET_FLAG(RCC_FLAG_HSIRDY) != RESET) && (RCC_OscInitStruct->HSIState != RCC_HSI_ON))
308 return HAL_ERROR;
310 /* Otherwise, just the calibration is allowed */
311 else
313 /* Adjusts the Internal High Speed oscillator (HSI) calibration value.*/
314 __HAL_RCC_HSI_CALIBRATIONVALUE_ADJUST(RCC_OscInitStruct->HSICalibrationValue);
317 else
319 /* Check the HSI State */
320 if((RCC_OscInitStruct->HSIState)!= RCC_HSI_OFF)
322 /* Enable the Internal High Speed oscillator (HSI). */
323 __HAL_RCC_HSI_ENABLE();
325 /* Get Start Tick*/
326 tickstart = HAL_GetTick();
328 /* Wait till HSI is ready */
329 while(__HAL_RCC_GET_FLAG(RCC_FLAG_HSIRDY) == RESET)
331 if((HAL_GetTick() - tickstart ) > HSI_TIMEOUT_VALUE)
333 return HAL_TIMEOUT;
337 /* Adjusts the Internal High Speed oscillator (HSI) calibration value.*/
338 __HAL_RCC_HSI_CALIBRATIONVALUE_ADJUST(RCC_OscInitStruct->HSICalibrationValue);
340 else
342 /* Disable the Internal High Speed oscillator (HSI). */
343 __HAL_RCC_HSI_DISABLE();
345 /* Get Start Tick*/
346 tickstart = HAL_GetTick();
348 /* Wait till HSI is ready */
349 while(__HAL_RCC_GET_FLAG(RCC_FLAG_HSIRDY) != RESET)
351 if((HAL_GetTick() - tickstart ) > HSI_TIMEOUT_VALUE)
353 return HAL_TIMEOUT;
359 /*------------------------------ LSI Configuration -------------------------*/
360 if(((RCC_OscInitStruct->OscillatorType) & RCC_OSCILLATORTYPE_LSI) == RCC_OSCILLATORTYPE_LSI)
362 /* Check the parameters */
363 assert_param(IS_RCC_LSI(RCC_OscInitStruct->LSIState));
365 /* Check the LSI State */
366 if((RCC_OscInitStruct->LSIState)!= RCC_LSI_OFF)
368 /* Enable the Internal Low Speed oscillator (LSI). */
369 __HAL_RCC_LSI_ENABLE();
371 /* Get Start Tick*/
372 tickstart = HAL_GetTick();
374 /* Wait till LSI is ready */
375 while(__HAL_RCC_GET_FLAG(RCC_FLAG_LSIRDY) == RESET)
377 if((HAL_GetTick() - tickstart ) > LSI_TIMEOUT_VALUE)
379 return HAL_TIMEOUT;
383 else
385 /* Disable the Internal Low Speed oscillator (LSI). */
386 __HAL_RCC_LSI_DISABLE();
388 /* Get Start Tick*/
389 tickstart = HAL_GetTick();
391 /* Wait till LSI is ready */
392 while(__HAL_RCC_GET_FLAG(RCC_FLAG_LSIRDY) != RESET)
394 if((HAL_GetTick() - tickstart ) > LSI_TIMEOUT_VALUE)
396 return HAL_TIMEOUT;
401 /*------------------------------ LSE Configuration -------------------------*/
402 if(((RCC_OscInitStruct->OscillatorType) & RCC_OSCILLATORTYPE_LSE) == RCC_OSCILLATORTYPE_LSE)
404 /* Check the parameters */
405 assert_param(IS_RCC_LSE(RCC_OscInitStruct->LSEState));
407 /* Enable Power Clock*/
408 __HAL_RCC_PWR_CLK_ENABLE();
410 /* Enable write access to Backup domain */
411 PWR->CR |= PWR_CR_DBP;
413 /* Wait for Backup domain Write protection enable */
414 tickstart = HAL_GetTick();
416 while((PWR->CR & PWR_CR_DBP) == RESET)
418 if((HAL_GetTick() - tickstart ) > RCC_DBP_TIMEOUT_VALUE)
420 return HAL_TIMEOUT;
424 /* Set the new LSE configuration -----------------------------------------*/
425 __HAL_RCC_LSE_CONFIG(RCC_OscInitStruct->LSEState);
426 /* Check the LSE State */
427 if((RCC_OscInitStruct->LSEState) != RCC_LSE_OFF)
429 /* Get Start Tick*/
430 tickstart = HAL_GetTick();
432 /* Wait till LSE is ready */
433 while(__HAL_RCC_GET_FLAG(RCC_FLAG_LSERDY) == RESET)
435 if((HAL_GetTick() - tickstart ) > RCC_LSE_TIMEOUT_VALUE)
437 return HAL_TIMEOUT;
441 else
443 /* Get Start Tick*/
444 tickstart = HAL_GetTick();
446 /* Wait till LSE is ready */
447 while(__HAL_RCC_GET_FLAG(RCC_FLAG_LSERDY) != RESET)
449 if((HAL_GetTick() - tickstart ) > RCC_LSE_TIMEOUT_VALUE)
451 return HAL_TIMEOUT;
456 /*-------------------------------- PLL Configuration -----------------------*/
457 /* Check the parameters */
458 assert_param(IS_RCC_PLL(RCC_OscInitStruct->PLL.PLLState));
459 if ((RCC_OscInitStruct->PLL.PLLState) != RCC_PLL_NONE)
461 /* Check if the PLL is used as system clock or not */
462 if(__HAL_RCC_GET_SYSCLK_SOURCE() != RCC_CFGR_SWS_PLL)
464 if((RCC_OscInitStruct->PLL.PLLState) == RCC_PLL_ON)
466 /* Check the parameters */
467 assert_param(IS_RCC_PLLSOURCE(RCC_OscInitStruct->PLL.PLLSource));
468 assert_param(IS_RCC_PLLM_VALUE(RCC_OscInitStruct->PLL.PLLM));
469 assert_param(IS_RCC_PLLN_VALUE(RCC_OscInitStruct->PLL.PLLN));
470 assert_param(IS_RCC_PLLP_VALUE(RCC_OscInitStruct->PLL.PLLP));
471 assert_param(IS_RCC_PLLQ_VALUE(RCC_OscInitStruct->PLL.PLLQ));
473 /* Disable the main PLL. */
474 __HAL_RCC_PLL_DISABLE();
476 /* Get Start Tick*/
477 tickstart = HAL_GetTick();
479 /* Wait till PLL is ready */
480 while(__HAL_RCC_GET_FLAG(RCC_FLAG_PLLRDY) != RESET)
482 if((HAL_GetTick() - tickstart ) > PLL_TIMEOUT_VALUE)
484 return HAL_TIMEOUT;
488 /* Configure the main PLL clock source, multiplication and division factors. */
489 WRITE_REG(RCC->PLLCFGR, (RCC_OscInitStruct->PLL.PLLSource | \
490 RCC_OscInitStruct->PLL.PLLM | \
491 (RCC_OscInitStruct->PLL.PLLN << POSITION_VAL(RCC_PLLCFGR_PLLN)) | \
492 (((RCC_OscInitStruct->PLL.PLLP >> 1U) - 1U) << POSITION_VAL(RCC_PLLCFGR_PLLP)) | \
493 (RCC_OscInitStruct->PLL.PLLQ << POSITION_VAL(RCC_PLLCFGR_PLLQ))));
494 /* Enable the main PLL. */
495 __HAL_RCC_PLL_ENABLE();
497 /* Get Start Tick*/
498 tickstart = HAL_GetTick();
500 /* Wait till PLL is ready */
501 while(__HAL_RCC_GET_FLAG(RCC_FLAG_PLLRDY) == RESET)
503 if((HAL_GetTick() - tickstart ) > PLL_TIMEOUT_VALUE)
505 return HAL_TIMEOUT;
509 else
511 /* Disable the main PLL. */
512 __HAL_RCC_PLL_DISABLE();
514 /* Get Start Tick*/
515 tickstart = HAL_GetTick();
517 /* Wait till PLL is ready */
518 while(__HAL_RCC_GET_FLAG(RCC_FLAG_PLLRDY) != RESET)
520 if((HAL_GetTick() - tickstart ) > PLL_TIMEOUT_VALUE)
522 return HAL_TIMEOUT;
527 else
529 return HAL_ERROR;
532 return HAL_OK;
536 * @brief Initializes the CPU, AHB and APB busses clocks according to the specified
537 * parameters in the RCC_ClkInitStruct.
538 * @param RCC_ClkInitStruct: pointer to an RCC_OscInitTypeDef structure that
539 * contains the configuration information for the RCC peripheral.
540 * @param FLatency: FLASH Latency, this parameter depend on device selected
542 * @note The SystemCoreClock CMSIS variable is used to store System Clock Frequency
543 * and updated by HAL_RCC_GetHCLKFreq() function called within this function
545 * @note The HSI is used (enabled by hardware) as system clock source after
546 * startup from Reset, wake-up from STOP and STANDBY mode, or in case
547 * of failure of the HSE used directly or indirectly as system clock
548 * (if the Clock Security System CSS is enabled).
550 * @note A switch from one clock source to another occurs only if the target
551 * clock source is ready (clock stable after startup delay or PLL locked).
552 * If a clock source which is not yet ready is selected, the switch will
553 * occur when the clock source will be ready.
555 * @note Depending on the device voltage range, the software has to set correctly
556 * HPRE[3:0] bits to ensure that HCLK not exceed the maximum allowed frequency
557 * (for more details refer to section above "Initialization/de-initialization functions")
558 * @retval None
560 HAL_StatusTypeDef HAL_RCC_ClockConfig(RCC_ClkInitTypeDef *RCC_ClkInitStruct, uint32_t FLatency)
562 uint32_t tickstart = 0U;
564 /* Check the parameters */
565 assert_param(IS_RCC_CLOCKTYPE(RCC_ClkInitStruct->ClockType));
566 assert_param(IS_FLASH_LATENCY(FLatency));
568 /* To correctly read data from FLASH memory, the number of wait states (LATENCY)
569 must be correctly programmed according to the frequency of the CPU clock
570 (HCLK) and the supply voltage of the device. */
572 /* Increasing the number of wait states because of higher CPU frequency */
573 if(FLatency > (FLASH->ACR & FLASH_ACR_LATENCY))
575 /* Program the new number of wait states to the LATENCY bits in the FLASH_ACR register */
576 __HAL_FLASH_SET_LATENCY(FLatency);
578 /* Check that the new number of wait states is taken into account to access the Flash
579 memory by reading the FLASH_ACR register */
580 if((FLASH->ACR & FLASH_ACR_LATENCY) != FLatency)
582 return HAL_ERROR;
586 /*-------------------------- HCLK Configuration --------------------------*/
587 if(((RCC_ClkInitStruct->ClockType) & RCC_CLOCKTYPE_HCLK) == RCC_CLOCKTYPE_HCLK)
589 assert_param(IS_RCC_HCLK(RCC_ClkInitStruct->AHBCLKDivider));
590 MODIFY_REG(RCC->CFGR, RCC_CFGR_HPRE, RCC_ClkInitStruct->AHBCLKDivider);
593 /*------------------------- SYSCLK Configuration ---------------------------*/
594 if(((RCC_ClkInitStruct->ClockType) & RCC_CLOCKTYPE_SYSCLK) == RCC_CLOCKTYPE_SYSCLK)
596 assert_param(IS_RCC_SYSCLKSOURCE(RCC_ClkInitStruct->SYSCLKSource));
598 /* HSE is selected as System Clock Source */
599 if(RCC_ClkInitStruct->SYSCLKSource == RCC_SYSCLKSOURCE_HSE)
601 /* Check the HSE ready flag */
602 if(__HAL_RCC_GET_FLAG(RCC_FLAG_HSERDY) == RESET)
604 return HAL_ERROR;
607 /* PLL is selected as System Clock Source */
608 else if((RCC_ClkInitStruct->SYSCLKSource == RCC_SYSCLKSOURCE_PLLCLK) ||
609 (RCC_ClkInitStruct->SYSCLKSource == RCC_SYSCLKSOURCE_PLLRCLK))
611 /* Check the PLL ready flag */
612 if(__HAL_RCC_GET_FLAG(RCC_FLAG_PLLRDY) == RESET)
614 return HAL_ERROR;
617 /* HSI is selected as System Clock Source */
618 else
620 /* Check the HSI ready flag */
621 if(__HAL_RCC_GET_FLAG(RCC_FLAG_HSIRDY) == RESET)
623 return HAL_ERROR;
627 __HAL_RCC_SYSCLK_CONFIG(RCC_ClkInitStruct->SYSCLKSource);
628 /* Get Start Tick*/
629 tickstart = HAL_GetTick();
631 if(RCC_ClkInitStruct->SYSCLKSource == RCC_SYSCLKSOURCE_HSE)
633 while (__HAL_RCC_GET_SYSCLK_SOURCE() != RCC_SYSCLKSOURCE_STATUS_HSE)
635 if((HAL_GetTick() - tickstart ) > CLOCKSWITCH_TIMEOUT_VALUE)
637 return HAL_TIMEOUT;
641 else if(RCC_ClkInitStruct->SYSCLKSource == RCC_SYSCLKSOURCE_PLLCLK)
643 while (__HAL_RCC_GET_SYSCLK_SOURCE() != RCC_SYSCLKSOURCE_STATUS_PLLCLK)
645 if((HAL_GetTick() - tickstart ) > CLOCKSWITCH_TIMEOUT_VALUE)
647 return HAL_TIMEOUT;
651 else if(RCC_ClkInitStruct->SYSCLKSource == RCC_SYSCLKSOURCE_PLLRCLK)
653 while (__HAL_RCC_GET_SYSCLK_SOURCE() != RCC_SYSCLKSOURCE_STATUS_PLLRCLK)
655 if((HAL_GetTick() - tickstart ) > CLOCKSWITCH_TIMEOUT_VALUE)
657 return HAL_TIMEOUT;
661 else
663 while(__HAL_RCC_GET_SYSCLK_SOURCE() != RCC_SYSCLKSOURCE_STATUS_HSI)
665 if((HAL_GetTick() - tickstart ) > CLOCKSWITCH_TIMEOUT_VALUE)
667 return HAL_TIMEOUT;
673 /* Decreasing the number of wait states because of lower CPU frequency */
674 if(FLatency < (FLASH->ACR & FLASH_ACR_LATENCY))
676 /* Program the new number of wait states to the LATENCY bits in the FLASH_ACR register */
677 __HAL_FLASH_SET_LATENCY(FLatency);
679 /* Check that the new number of wait states is taken into account to access the Flash
680 memory by reading the FLASH_ACR register */
681 if((FLASH->ACR & FLASH_ACR_LATENCY) != FLatency)
683 return HAL_ERROR;
687 /*-------------------------- PCLK1 Configuration ---------------------------*/
688 if(((RCC_ClkInitStruct->ClockType) & RCC_CLOCKTYPE_PCLK1) == RCC_CLOCKTYPE_PCLK1)
690 assert_param(IS_RCC_PCLK(RCC_ClkInitStruct->APB1CLKDivider));
691 MODIFY_REG(RCC->CFGR, RCC_CFGR_PPRE1, RCC_ClkInitStruct->APB1CLKDivider);
694 /*-------------------------- PCLK2 Configuration ---------------------------*/
695 if(((RCC_ClkInitStruct->ClockType) & RCC_CLOCKTYPE_PCLK2) == RCC_CLOCKTYPE_PCLK2)
697 assert_param(IS_RCC_PCLK(RCC_ClkInitStruct->APB2CLKDivider));
698 MODIFY_REG(RCC->CFGR, RCC_CFGR_PPRE2, ((RCC_ClkInitStruct->APB2CLKDivider) << 3U));
701 /* Update the SystemCoreClock global variable */
702 SystemCoreClock = HAL_RCC_GetSysClockFreq() >> AHBPrescTable[(RCC->CFGR & RCC_CFGR_HPRE)>> POSITION_VAL(RCC_CFGR_HPRE)];
704 /* Configure the source of time base considering new system clocks settings*/
705 HAL_InitTick (TICK_INT_PRIORITY);
707 return HAL_OK;
711 * @}
714 /** @defgroup RCC_Exported_Functions_Group2 Peripheral Control functions
715 * @brief RCC clocks control functions
717 @verbatim
718 ===============================================================================
719 ##### Peripheral Control functions #####
720 ===============================================================================
721 [..]
722 This subsection provides a set of functions allowing to control the RCC Clocks
723 frequencies.
725 @endverbatim
726 * @{
730 * @brief Selects the clock source to output on MCO1 pin(PA8) or on MCO2 pin(PC9).
731 * @note PA8/PC9 should be configured in alternate function mode.
732 * @param RCC_MCOx: specifies the output direction for the clock source.
733 * This parameter can be one of the following values:
734 * @arg RCC_MCO1: Clock source to output on MCO1 pin(PA8).
735 * @arg RCC_MCO2: Clock source to output on MCO2 pin(PC9).
736 * @param RCC_MCOSource: specifies the clock source to output.
737 * This parameter can be one of the following values:
738 * @arg RCC_MCO1SOURCE_HSI: HSI clock selected as MCO1 source
739 * @arg RCC_MCO1SOURCE_LSE: LSE clock selected as MCO1 source
740 * @arg RCC_MCO1SOURCE_HSE: HSE clock selected as MCO1 source
741 * @arg RCC_MCO1SOURCE_PLLCLK: main PLL clock selected as MCO1 source
742 * @arg RCC_MCO2SOURCE_SYSCLK: System clock (SYSCLK) selected as MCO2 source
743 * @arg RCC_MCO2SOURCE_PLLI2SCLK: PLLI2S clock selected as MCO2 source, available for all STM32F4 devices except STM32F410xx
744 * @arg RCC_MCO2SOURCE_I2SCLK: I2SCLK clock selected as MCO2 source, available only for STM32F410Rx devices
745 * @arg RCC_MCO2SOURCE_HSE: HSE clock selected as MCO2 source
746 * @arg RCC_MCO2SOURCE_PLLCLK: main PLL clock selected as MCO2 source
747 * @param RCC_MCODiv: specifies the MCOx prescaler.
748 * This parameter can be one of the following values:
749 * @arg RCC_MCODIV_1: no division applied to MCOx clock
750 * @arg RCC_MCODIV_2: division by 2 applied to MCOx clock
751 * @arg RCC_MCODIV_3: division by 3 applied to MCOx clock
752 * @arg RCC_MCODIV_4: division by 4 applied to MCOx clock
753 * @arg RCC_MCODIV_5: division by 5 applied to MCOx clock
754 * @note For STM32F410Rx devices to output I2SCLK clock on MCO2 you should have
755 * at last one of the SPI clocks enabled (SPI1, SPI2 or SPI5).
756 * @retval None
758 void HAL_RCC_MCOConfig(uint32_t RCC_MCOx, uint32_t RCC_MCOSource, uint32_t RCC_MCODiv)
760 GPIO_InitTypeDef GPIO_InitStruct;
761 /* Check the parameters */
762 assert_param(IS_RCC_MCO(RCC_MCOx));
763 assert_param(IS_RCC_MCODIV(RCC_MCODiv));
764 /* RCC_MCO1 */
765 if(RCC_MCOx == RCC_MCO1)
767 assert_param(IS_RCC_MCO1SOURCE(RCC_MCOSource));
769 /* MCO1 Clock Enable */
770 __MCO1_CLK_ENABLE();
772 /* Configure the MCO1 pin in alternate function mode */
773 GPIO_InitStruct.Pin = MCO1_PIN;
774 GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
775 GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
776 GPIO_InitStruct.Pull = GPIO_NOPULL;
777 GPIO_InitStruct.Alternate = GPIO_AF0_MCO;
778 HAL_GPIO_Init(MCO1_GPIO_PORT, &GPIO_InitStruct);
780 /* Mask MCO1 and MCO1PRE[2:0] bits then Select MCO1 clock source and prescaler */
781 MODIFY_REG(RCC->CFGR, (RCC_CFGR_MCO1 | RCC_CFGR_MCO1PRE), (RCC_MCOSource | RCC_MCODiv));
783 /* This RCC MCO1 enable feature is available only on STM32F410xx devices */
784 #if defined(RCC_CFGR_MCO1EN)
785 __HAL_RCC_MCO1_ENABLE();
786 #endif /* RCC_CFGR_MCO1EN */
788 #if defined(RCC_CFGR_MCO2)
789 else
791 assert_param(IS_RCC_MCO2SOURCE(RCC_MCOSource));
793 /* MCO2 Clock Enable */
794 __MCO2_CLK_ENABLE();
796 /* Configure the MCO2 pin in alternate function mode */
797 GPIO_InitStruct.Pin = MCO2_PIN;
798 GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
799 GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
800 GPIO_InitStruct.Pull = GPIO_NOPULL;
801 GPIO_InitStruct.Alternate = GPIO_AF0_MCO;
802 HAL_GPIO_Init(MCO2_GPIO_PORT, &GPIO_InitStruct);
804 /* Mask MCO2 and MCO2PRE[2:0] bits then Select MCO2 clock source and prescaler */
805 MODIFY_REG(RCC->CFGR, (RCC_CFGR_MCO2 | RCC_CFGR_MCO2PRE), (RCC_MCOSource | (RCC_MCODiv << 3U)));
807 /* This RCC MCO2 enable feature is available only on STM32F410Rx devices */
808 #if defined(RCC_CFGR_MCO2EN)
809 __HAL_RCC_MCO2_ENABLE();
810 #endif /* RCC_CFGR_MCO2EN */
812 #endif /* RCC_CFGR_MCO2 */
816 * @brief Enables the Clock Security System.
817 * @note If a failure is detected on the HSE oscillator clock, this oscillator
818 * is automatically disabled and an interrupt is generated to inform the
819 * software about the failure (Clock Security System Interrupt, CSSI),
820 * allowing the MCU to perform rescue operations. The CSSI is linked to
821 * the Cortex-M4 NMI (Non-Maskable Interrupt) exception vector.
822 * @retval None
824 void HAL_RCC_EnableCSS(void)
826 *(__IO uint32_t *) RCC_CR_CSSON_BB = (uint32_t)ENABLE;
830 * @brief Disables the Clock Security System.
831 * @retval None
833 void HAL_RCC_DisableCSS(void)
835 *(__IO uint32_t *) RCC_CR_CSSON_BB = (uint32_t)DISABLE;
839 * @brief Returns the SYSCLK frequency
841 * @note The system frequency computed by this function is not the real
842 * frequency in the chip. It is calculated based on the predefined
843 * constant and the selected clock source:
844 * @note If SYSCLK source is HSI, function returns values based on HSI_VALUE(*)
845 * @note If SYSCLK source is HSE, function returns values based on HSE_VALUE(**)
846 * @note If SYSCLK source is PLL, function returns values based on HSE_VALUE(**)
847 * or HSI_VALUE(*) multiplied/divided by the PLL factors.
848 * @note (*) HSI_VALUE is a constant defined in stm32f4xx_hal_conf.h file (default value
849 * 16 MHz) but the real value may vary depending on the variations
850 * in voltage and temperature.
851 * @note (**) HSE_VALUE is a constant defined in stm32f4xx_hal_conf.h file (default value
852 * 25 MHz), user has to ensure that HSE_VALUE is same as the real
853 * frequency of the crystal used. Otherwise, this function may
854 * have wrong result.
856 * @note The result of this function could be not correct when using fractional
857 * value for HSE crystal.
859 * @note This function can be used by the user application to compute the
860 * baudrate for the communication peripherals or configure other parameters.
862 * @note Each time SYSCLK changes, this function must be called to update the
863 * right SYSCLK value. Otherwise, any configuration based on this function will be incorrect.
866 * @retval SYSCLK frequency
868 __weak uint32_t HAL_RCC_GetSysClockFreq(void)
870 uint32_t pllm = 0U, pllvco = 0U, pllp = 0U;
871 uint32_t sysclockfreq = 0U;
873 /* Get SYSCLK source -------------------------------------------------------*/
874 switch (RCC->CFGR & RCC_CFGR_SWS)
876 case RCC_CFGR_SWS_HSI: /* HSI used as system clock source */
878 sysclockfreq = HSI_VALUE;
879 break;
881 case RCC_CFGR_SWS_HSE: /* HSE used as system clock source */
883 sysclockfreq = HSE_VALUE;
884 break;
886 case RCC_CFGR_SWS_PLL: /* PLL used as system clock source */
888 /* PLL_VCO = (HSE_VALUE or HSI_VALUE / PLLM) * PLLN
889 SYSCLK = PLL_VCO / PLLP */
890 pllm = RCC->PLLCFGR & RCC_PLLCFGR_PLLM;
891 if(__HAL_RCC_GET_PLL_OSCSOURCE() != RCC_PLLSOURCE_HSI)
893 /* HSE used as PLL clock source */
894 pllvco = ((HSE_VALUE / pllm) * ((RCC->PLLCFGR & RCC_PLLCFGR_PLLN) >> POSITION_VAL(RCC_PLLCFGR_PLLN)));
896 else
898 /* HSI used as PLL clock source */
899 pllvco = ((HSI_VALUE / pllm) * ((RCC->PLLCFGR & RCC_PLLCFGR_PLLN) >> POSITION_VAL(RCC_PLLCFGR_PLLN)));
901 pllp = ((((RCC->PLLCFGR & RCC_PLLCFGR_PLLP) >> POSITION_VAL(RCC_PLLCFGR_PLLP)) + 1U) *2U);
903 sysclockfreq = pllvco/pllp;
904 break;
906 default:
908 sysclockfreq = HSI_VALUE;
909 break;
912 return sysclockfreq;
916 * @brief Returns the HCLK frequency
917 * @note Each time HCLK changes, this function must be called to update the
918 * right HCLK value. Otherwise, any configuration based on this function will be incorrect.
920 * @note The SystemCoreClock CMSIS variable is used to store System Clock Frequency
921 * and updated within this function
922 * @retval HCLK frequency
924 uint32_t HAL_RCC_GetHCLKFreq(void)
926 return SystemCoreClock;
930 * @brief Returns the PCLK1 frequency
931 * @note Each time PCLK1 changes, this function must be called to update the
932 * right PCLK1 value. Otherwise, any configuration based on this function will be incorrect.
933 * @retval PCLK1 frequency
935 uint32_t HAL_RCC_GetPCLK1Freq(void)
937 /* Get HCLK source and Compute PCLK1 frequency ---------------------------*/
938 return (HAL_RCC_GetHCLKFreq() >> APBPrescTable[(RCC->CFGR & RCC_CFGR_PPRE1)>> POSITION_VAL(RCC_CFGR_PPRE1)]);
942 * @brief Returns the PCLK2 frequency
943 * @note Each time PCLK2 changes, this function must be called to update the
944 * right PCLK2 value. Otherwise, any configuration based on this function will be incorrect.
945 * @retval PCLK2 frequency
947 uint32_t HAL_RCC_GetPCLK2Freq(void)
949 /* Get HCLK source and Compute PCLK2 frequency ---------------------------*/
950 return (HAL_RCC_GetHCLKFreq()>> APBPrescTable[(RCC->CFGR & RCC_CFGR_PPRE2)>> POSITION_VAL(RCC_CFGR_PPRE2)]);
954 * @brief Configures the RCC_OscInitStruct according to the internal
955 * RCC configuration registers.
956 * @param RCC_OscInitStruct: pointer to an RCC_OscInitTypeDef structure that
957 * will be configured.
958 * @retval None
960 __weak void HAL_RCC_GetOscConfig(RCC_OscInitTypeDef *RCC_OscInitStruct)
962 /* Set all possible values for the Oscillator type parameter ---------------*/
963 RCC_OscInitStruct->OscillatorType = RCC_OSCILLATORTYPE_HSE | RCC_OSCILLATORTYPE_HSI | RCC_OSCILLATORTYPE_LSE | RCC_OSCILLATORTYPE_LSI;
965 /* Get the HSE configuration -----------------------------------------------*/
966 if((RCC->CR &RCC_CR_HSEBYP) == RCC_CR_HSEBYP)
968 RCC_OscInitStruct->HSEState = RCC_HSE_BYPASS;
970 else if((RCC->CR &RCC_CR_HSEON) == RCC_CR_HSEON)
972 RCC_OscInitStruct->HSEState = RCC_HSE_ON;
974 else
976 RCC_OscInitStruct->HSEState = RCC_HSE_OFF;
979 /* Get the HSI configuration -----------------------------------------------*/
980 if((RCC->CR &RCC_CR_HSION) == RCC_CR_HSION)
982 RCC_OscInitStruct->HSIState = RCC_HSI_ON;
984 else
986 RCC_OscInitStruct->HSIState = RCC_HSI_OFF;
989 RCC_OscInitStruct->HSICalibrationValue = (uint32_t)((RCC->CR &RCC_CR_HSITRIM) >> POSITION_VAL(RCC_CR_HSITRIM));
991 /* Get the LSE configuration -----------------------------------------------*/
992 if((RCC->BDCR &RCC_BDCR_LSEBYP) == RCC_BDCR_LSEBYP)
994 RCC_OscInitStruct->LSEState = RCC_LSE_BYPASS;
996 else if((RCC->BDCR &RCC_BDCR_LSEON) == RCC_BDCR_LSEON)
998 RCC_OscInitStruct->LSEState = RCC_LSE_ON;
1000 else
1002 RCC_OscInitStruct->LSEState = RCC_LSE_OFF;
1005 /* Get the LSI configuration -----------------------------------------------*/
1006 if((RCC->CSR &RCC_CSR_LSION) == RCC_CSR_LSION)
1008 RCC_OscInitStruct->LSIState = RCC_LSI_ON;
1010 else
1012 RCC_OscInitStruct->LSIState = RCC_LSI_OFF;
1015 /* Get the PLL configuration -----------------------------------------------*/
1016 if((RCC->CR &RCC_CR_PLLON) == RCC_CR_PLLON)
1018 RCC_OscInitStruct->PLL.PLLState = RCC_PLL_ON;
1020 else
1022 RCC_OscInitStruct->PLL.PLLState = RCC_PLL_OFF;
1024 RCC_OscInitStruct->PLL.PLLSource = (uint32_t)(RCC->PLLCFGR & RCC_PLLCFGR_PLLSRC);
1025 RCC_OscInitStruct->PLL.PLLM = (uint32_t)(RCC->PLLCFGR & RCC_PLLCFGR_PLLM);
1026 RCC_OscInitStruct->PLL.PLLN = (uint32_t)((RCC->PLLCFGR & RCC_PLLCFGR_PLLN) >> POSITION_VAL(RCC_PLLCFGR_PLLN));
1027 RCC_OscInitStruct->PLL.PLLP = (uint32_t)((((RCC->PLLCFGR & RCC_PLLCFGR_PLLP) + RCC_PLLCFGR_PLLP_0) << 1U) >> POSITION_VAL(RCC_PLLCFGR_PLLP));
1028 RCC_OscInitStruct->PLL.PLLQ = (uint32_t)((RCC->PLLCFGR & RCC_PLLCFGR_PLLQ) >> POSITION_VAL(RCC_PLLCFGR_PLLQ));
1032 * @brief Configures the RCC_ClkInitStruct according to the internal
1033 * RCC configuration registers.
1034 * @param RCC_ClkInitStruct: pointer to an RCC_ClkInitTypeDef structure that
1035 * will be configured.
1036 * @param pFLatency: Pointer on the Flash Latency.
1037 * @retval None
1039 void HAL_RCC_GetClockConfig(RCC_ClkInitTypeDef *RCC_ClkInitStruct, uint32_t *pFLatency)
1041 /* Set all possible values for the Clock type parameter --------------------*/
1042 RCC_ClkInitStruct->ClockType = RCC_CLOCKTYPE_SYSCLK | RCC_CLOCKTYPE_HCLK | RCC_CLOCKTYPE_PCLK1 | RCC_CLOCKTYPE_PCLK2;
1044 /* Get the SYSCLK configuration --------------------------------------------*/
1045 RCC_ClkInitStruct->SYSCLKSource = (uint32_t)(RCC->CFGR & RCC_CFGR_SW);
1047 /* Get the HCLK configuration ----------------------------------------------*/
1048 RCC_ClkInitStruct->AHBCLKDivider = (uint32_t)(RCC->CFGR & RCC_CFGR_HPRE);
1050 /* Get the APB1 configuration ----------------------------------------------*/
1051 RCC_ClkInitStruct->APB1CLKDivider = (uint32_t)(RCC->CFGR & RCC_CFGR_PPRE1);
1053 /* Get the APB2 configuration ----------------------------------------------*/
1054 RCC_ClkInitStruct->APB2CLKDivider = (uint32_t)((RCC->CFGR & RCC_CFGR_PPRE2) >> 3U);
1056 /* Get the Flash Wait State (Latency) configuration ------------------------*/
1057 *pFLatency = (uint32_t)(FLASH->ACR & FLASH_ACR_LATENCY);
1061 * @brief This function handles the RCC CSS interrupt request.
1062 * @note This API should be called under the NMI_Handler().
1063 * @retval None
1065 void HAL_RCC_NMI_IRQHandler(void)
1067 /* Check RCC CSSF flag */
1068 if(__HAL_RCC_GET_IT(RCC_IT_CSS))
1070 /* RCC Clock Security System interrupt user callback */
1071 HAL_RCC_CSSCallback();
1073 /* Clear RCC CSS pending bit */
1074 __HAL_RCC_CLEAR_IT(RCC_IT_CSS);
1079 * @brief RCC Clock Security System interrupt callback
1080 * @retval None
1082 __weak void HAL_RCC_CSSCallback(void)
1084 /* NOTE : This function Should not be modified, when the callback is needed,
1085 the HAL_RCC_CSSCallback could be implemented in the user file
1090 * @}
1094 * @}
1097 #endif /* HAL_RCC_MODULE_ENABLED */
1099 * @}
1103 * @}
1106 /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/