STM32F103xB HAL User Manual
|
00001 /** 00002 ****************************************************************************** 00003 * @file stm32f1xx_hal_rcc.c 00004 * @author MCD Application Team 00005 * @brief RCC HAL module driver. 00006 * This file provides firmware functions to manage the following 00007 * functionalities of the Reset and Clock Control (RCC) peripheral: 00008 * + Initialization and de-initialization functions 00009 * + Peripheral Control functions 00010 * 00011 @verbatim 00012 ============================================================================== 00013 ##### RCC specific features ##### 00014 ============================================================================== 00015 [..] 00016 After reset the device is running from Internal High Speed oscillator 00017 (HSI 8MHz) with Flash 0 wait state, Flash prefetch buffer is enabled, 00018 and all peripherals are off except internal SRAM, Flash and JTAG. 00019 (+) There is no prescaler on High speed (AHB) and Low speed (APB) buses; 00020 all peripherals mapped on these buses are running at HSI speed. 00021 (+) The clock for all peripherals is switched off, except the SRAM and FLASH. 00022 (+) All GPIOs are in input floating state, except the JTAG pins which 00023 are assigned to be used for debug purpose. 00024 [..] Once the device started from reset, the user application has to: 00025 (+) Configure the clock source to be used to drive the System clock 00026 (if the application needs higher frequency/performance) 00027 (+) Configure the System clock frequency and Flash settings 00028 (+) Configure the AHB and APB buses prescalers 00029 (+) Enable the clock for the peripheral(s) to be used 00030 (+) Configure the clock source(s) for peripherals whose clocks are not 00031 derived from the System clock (I2S, RTC, ADC, USB OTG FS) 00032 00033 ##### RCC Limitations ##### 00034 ============================================================================== 00035 [..] 00036 A delay between an RCC peripheral clock enable and the effective peripheral 00037 enabling should be taken into account in order to manage the peripheral read/write 00038 from/to registers. 00039 (+) This delay depends on the peripheral mapping. 00040 (++) AHB & APB peripherals, 1 dummy read is necessary 00041 00042 [..] 00043 Workarounds: 00044 (#) For AHB & APB peripherals, a dummy read to the peripheral register has been 00045 inserted in each __HAL_RCC_PPP_CLK_ENABLE() macro. 00046 00047 @endverbatim 00048 ****************************************************************************** 00049 * @attention 00050 * 00051 * <h2><center>© Copyright (c) 2016 STMicroelectronics. 00052 * All rights reserved.</center></h2> 00053 * 00054 * This software component is licensed by ST under BSD 3-Clause license, 00055 * the "License"; You may not use this file except in compliance with the 00056 * License. You may obtain a copy of the License at: 00057 * opensource.org/licenses/BSD-3-Clause 00058 * 00059 ****************************************************************************** 00060 */ 00061 00062 /* Includes ------------------------------------------------------------------*/ 00063 #include "stm32f1xx_hal.h" 00064 00065 /** @addtogroup STM32F1xx_HAL_Driver 00066 * @{ 00067 */ 00068 00069 /** @defgroup RCC RCC 00070 * @brief RCC HAL module driver 00071 * @{ 00072 */ 00073 00074 #ifdef HAL_RCC_MODULE_ENABLED 00075 00076 /* Private typedef -----------------------------------------------------------*/ 00077 /* Private define ------------------------------------------------------------*/ 00078 /** @defgroup RCC_Private_Constants RCC Private Constants 00079 * @{ 00080 */ 00081 /** 00082 * @} 00083 */ 00084 /* Private macro -------------------------------------------------------------*/ 00085 /** @defgroup RCC_Private_Macros RCC Private Macros 00086 * @{ 00087 */ 00088 00089 #define MCO1_CLK_ENABLE() __HAL_RCC_GPIOA_CLK_ENABLE() 00090 #define MCO1_GPIO_PORT GPIOA 00091 #define MCO1_PIN GPIO_PIN_8 00092 00093 /** 00094 * @} 00095 */ 00096 00097 /* Private variables ---------------------------------------------------------*/ 00098 /** @defgroup RCC_Private_Variables RCC Private Variables 00099 * @{ 00100 */ 00101 /** 00102 * @} 00103 */ 00104 00105 /* Private function prototypes -----------------------------------------------*/ 00106 static void RCC_Delay(uint32_t mdelay); 00107 00108 /* Exported functions --------------------------------------------------------*/ 00109 00110 /** @defgroup RCC_Exported_Functions RCC Exported Functions 00111 * @{ 00112 */ 00113 00114 /** @defgroup RCC_Exported_Functions_Group1 Initialization and de-initialization functions 00115 * @brief Initialization and Configuration functions 00116 * 00117 @verbatim 00118 =============================================================================== 00119 ##### Initialization and de-initialization functions ##### 00120 =============================================================================== 00121 [..] 00122 This section provides functions allowing to configure the internal/external oscillators 00123 (HSE, HSI, LSE, LSI, PLL, CSS and MCO) and the System buses clocks (SYSCLK, AHB, APB1 00124 and APB2). 00125 00126 [..] Internal/external clock and PLL configuration 00127 (#) HSI (high-speed internal), 8 MHz factory-trimmed RC used directly or through 00128 the PLL as System clock source. 00129 (#) LSI (low-speed internal), ~40 KHz low consumption RC used as IWDG and/or RTC 00130 clock source. 00131 00132 (#) HSE (high-speed external), 4 to 24 MHz (STM32F100xx) or 4 to 16 MHz (STM32F101x/STM32F102x/STM32F103x) or 3 to 25 MHz (STM32F105x/STM32F107x) crystal oscillator used directly or 00133 through the PLL as System clock source. Can be used also as RTC clock source. 00134 00135 (#) LSE (low-speed external), 32 KHz oscillator used as RTC clock source. 00136 00137 (#) PLL (clocked by HSI or HSE), featuring different output clocks: 00138 (++) The first output is used to generate the high speed system clock (up to 72 MHz for STM32F10xxx or up to 24 MHz for STM32F100xx) 00139 (++) The second output is used to generate the clock for the USB OTG FS (48 MHz) 00140 00141 (#) CSS (Clock security system), once enable using the macro __HAL_RCC_CSS_ENABLE() 00142 and if a HSE clock failure occurs(HSE used directly or through PLL as System 00143 clock source), the System clocks automatically switched to HSI and an interrupt 00144 is generated if enabled. The interrupt is linked to the Cortex-M3 NMI 00145 (Non-Maskable Interrupt) exception vector. 00146 00147 (#) MCO1 (microcontroller clock output), used to output SYSCLK, HSI, 00148 HSE or PLL clock (divided by 2) on PA8 pin + PLL2CLK, PLL3CLK/2, PLL3CLK and XTI for STM32F105x/STM32F107x 00149 00150 [..] System, AHB and APB buses clocks configuration 00151 (#) Several clock sources can be used to drive the System clock (SYSCLK): HSI, 00152 HSE and PLL. 00153 The AHB clock (HCLK) is derived from System clock through configurable 00154 prescaler and used to clock the CPU, memory and peripherals mapped 00155 on AHB bus (DMA, GPIO...). APB1 (PCLK1) and APB2 (PCLK2) clocks are derived 00156 from AHB clock through configurable prescalers and used to clock 00157 the peripherals mapped on these buses. You can use 00158 "@ref HAL_RCC_GetSysClockFreq()" function to retrieve the frequencies of these clocks. 00159 00160 -@- All the peripheral clocks are derived from the System clock (SYSCLK) except: 00161 (+@) RTC: RTC clock can be derived either from the LSI, LSE or HSE clock 00162 divided by 128. 00163 (+@) USB OTG FS and RTC: USB OTG FS require a frequency equal to 48 MHz 00164 to work correctly. This clock is derived of the main PLL through PLL Multiplier. 00165 (+@) I2S interface on STM32F105x/STM32F107x can be derived from PLL3CLK 00166 (+@) IWDG clock which is always the LSI clock. 00167 00168 (#) For STM32F10xxx, the maximum frequency of the SYSCLK and HCLK/PCLK2 is 72 MHz, PCLK1 36 MHz. 00169 For STM32F100xx, the maximum frequency of the SYSCLK and HCLK/PCLK1/PCLK2 is 24 MHz. 00170 Depending on the SYSCLK frequency, the flash latency should be adapted accordingly. 00171 @endverbatim 00172 * @{ 00173 */ 00174 00175 /* 00176 Additional consideration on the SYSCLK based on Latency settings: 00177 +-----------------------------------------------+ 00178 | Latency | SYSCLK clock frequency (MHz) | 00179 |---------------|-------------------------------| 00180 |0WS(1CPU cycle)| 0 < SYSCLK <= 24 | 00181 |---------------|-------------------------------| 00182 |1WS(2CPU cycle)| 24 < SYSCLK <= 48 | 00183 |---------------|-------------------------------| 00184 |2WS(3CPU cycle)| 48 < SYSCLK <= 72 | 00185 +-----------------------------------------------+ 00186 */ 00187 00188 /** 00189 * @brief Resets the RCC clock configuration to the default reset state. 00190 * @note The default reset state of the clock configuration is given below: 00191 * - HSI ON and used as system clock source 00192 * - HSE, PLL, PLL2 and PLL3 are OFF 00193 * - AHB, APB1 and APB2 prescaler set to 1. 00194 * - CSS and MCO1 OFF 00195 * - All interrupts disabled 00196 * - All flags are cleared 00197 * @note This function does not modify the configuration of the 00198 * - Peripheral clocks 00199 * - LSI, LSE and RTC clocks 00200 * @retval HAL_StatusTypeDef 00201 */ 00202 HAL_StatusTypeDef HAL_RCC_DeInit(void) 00203 { 00204 uint32_t tickstart; 00205 00206 /* Get Start Tick */ 00207 tickstart = HAL_GetTick(); 00208 00209 /* Set HSION bit */ 00210 SET_BIT(RCC->CR, RCC_CR_HSION); 00211 00212 /* Wait till HSI is ready */ 00213 while (READ_BIT(RCC->CR, RCC_CR_HSIRDY) == RESET) 00214 { 00215 if ((HAL_GetTick() - tickstart) > HSI_TIMEOUT_VALUE) 00216 { 00217 return HAL_TIMEOUT; 00218 } 00219 } 00220 00221 /* Set HSITRIM bits to the reset value */ 00222 MODIFY_REG(RCC->CR, RCC_CR_HSITRIM, (0x10U << RCC_CR_HSITRIM_Pos)); 00223 00224 /* Get Start Tick */ 00225 tickstart = HAL_GetTick(); 00226 00227 /* Reset CFGR register */ 00228 CLEAR_REG(RCC->CFGR); 00229 00230 /* Wait till clock switch is ready */ 00231 while (READ_BIT(RCC->CFGR, RCC_CFGR_SWS) != RESET) 00232 { 00233 if ((HAL_GetTick() - tickstart) > CLOCKSWITCH_TIMEOUT_VALUE) 00234 { 00235 return HAL_TIMEOUT; 00236 } 00237 } 00238 00239 /* Update the SystemCoreClock global variable */ 00240 SystemCoreClock = HSI_VALUE; 00241 00242 /* Adapt Systick interrupt period */ 00243 if (HAL_InitTick(uwTickPrio) != HAL_OK) 00244 { 00245 return HAL_ERROR; 00246 } 00247 00248 /* Get Start Tick */ 00249 tickstart = HAL_GetTick(); 00250 00251 /* Second step is to clear PLLON bit */ 00252 CLEAR_BIT(RCC->CR, RCC_CR_PLLON); 00253 00254 /* Wait till PLL is disabled */ 00255 while (READ_BIT(RCC->CR, RCC_CR_PLLRDY) != RESET) 00256 { 00257 if ((HAL_GetTick() - tickstart) > PLL_TIMEOUT_VALUE) 00258 { 00259 return HAL_TIMEOUT; 00260 } 00261 } 00262 00263 /* Ensure to reset PLLSRC and PLLMUL bits */ 00264 CLEAR_REG(RCC->CFGR); 00265 00266 /* Get Start Tick */ 00267 tickstart = HAL_GetTick(); 00268 00269 /* Reset HSEON & CSSON bits */ 00270 CLEAR_BIT(RCC->CR, RCC_CR_HSEON | RCC_CR_CSSON); 00271 00272 /* Wait till HSE is disabled */ 00273 while (READ_BIT(RCC->CR, RCC_CR_HSERDY) != RESET) 00274 { 00275 if ((HAL_GetTick() - tickstart) > HSE_TIMEOUT_VALUE) 00276 { 00277 return HAL_TIMEOUT; 00278 } 00279 } 00280 00281 /* Reset HSEBYP bit */ 00282 CLEAR_BIT(RCC->CR, RCC_CR_HSEBYP); 00283 00284 #if defined(RCC_PLL2_SUPPORT) 00285 /* Get Start Tick */ 00286 tickstart = HAL_GetTick(); 00287 00288 /* Clear PLL2ON bit */ 00289 CLEAR_BIT(RCC->CR, RCC_CR_PLL2ON); 00290 00291 /* Wait till PLL2 is disabled */ 00292 while (READ_BIT(RCC->CR, RCC_CR_PLL2RDY) != RESET) 00293 { 00294 if ((HAL_GetTick() - tickstart) > PLL2_TIMEOUT_VALUE) 00295 { 00296 return HAL_TIMEOUT; 00297 } 00298 } 00299 #endif /* RCC_PLL2_SUPPORT */ 00300 00301 #if defined(RCC_PLLI2S_SUPPORT) 00302 /* Get Start Tick */ 00303 tickstart = HAL_GetTick(); 00304 00305 /* Clear PLL3ON bit */ 00306 CLEAR_BIT(RCC->CR, RCC_CR_PLL3ON); 00307 00308 /* Wait till PLL3 is disabled */ 00309 while (READ_BIT(RCC->CR, RCC_CR_PLL3RDY) != RESET) 00310 { 00311 if ((HAL_GetTick() - tickstart) > PLLI2S_TIMEOUT_VALUE) 00312 { 00313 return HAL_TIMEOUT; 00314 } 00315 } 00316 #endif /* RCC_PLLI2S_SUPPORT */ 00317 00318 #if defined(RCC_CFGR2_PREDIV1) 00319 /* Reset CFGR2 register */ 00320 CLEAR_REG(RCC->CFGR2); 00321 #endif /* RCC_CFGR2_PREDIV1 */ 00322 00323 /* Reset all CSR flags */ 00324 SET_BIT(RCC->CSR, RCC_CSR_RMVF); 00325 00326 /* Disable all interrupts */ 00327 CLEAR_REG(RCC->CIR); 00328 00329 return HAL_OK; 00330 } 00331 00332 /** 00333 * @brief Initializes the RCC Oscillators according to the specified parameters in the 00334 * RCC_OscInitTypeDef. 00335 * @param RCC_OscInitStruct pointer to an RCC_OscInitTypeDef structure that 00336 * contains the configuration information for the RCC Oscillators. 00337 * @note The PLL is not disabled when used as system clock. 00338 * @note The PLL is not disabled when USB OTG FS clock is enabled (specific to devices with USB FS) 00339 * @note Transitions LSE Bypass to LSE On and LSE On to LSE Bypass are not 00340 * supported by this macro. User should request a transition to LSE Off 00341 * first and then LSE On or LSE Bypass. 00342 * @note Transition HSE Bypass to HSE On and HSE On to HSE Bypass are not 00343 * supported by this macro. User should request a transition to HSE Off 00344 * first and then HSE On or HSE Bypass. 00345 * @retval HAL status 00346 */ 00347 HAL_StatusTypeDef HAL_RCC_OscConfig(RCC_OscInitTypeDef *RCC_OscInitStruct) 00348 { 00349 uint32_t tickstart; 00350 uint32_t pll_config; 00351 00352 /* Check Null pointer */ 00353 if (RCC_OscInitStruct == NULL) 00354 { 00355 return HAL_ERROR; 00356 } 00357 00358 /* Check the parameters */ 00359 assert_param(IS_RCC_OSCILLATORTYPE(RCC_OscInitStruct->OscillatorType)); 00360 00361 /*------------------------------- HSE Configuration ------------------------*/ 00362 if (((RCC_OscInitStruct->OscillatorType) & RCC_OSCILLATORTYPE_HSE) == RCC_OSCILLATORTYPE_HSE) 00363 { 00364 /* Check the parameters */ 00365 assert_param(IS_RCC_HSE(RCC_OscInitStruct->HSEState)); 00366 00367 /* When the HSE is used as system clock or clock source for PLL in these cases it is not allowed to be disabled */ 00368 if ((__HAL_RCC_GET_SYSCLK_SOURCE() == RCC_SYSCLKSOURCE_STATUS_HSE) 00369 || ((__HAL_RCC_GET_SYSCLK_SOURCE() == RCC_SYSCLKSOURCE_STATUS_PLLCLK) && (__HAL_RCC_GET_PLL_OSCSOURCE() == RCC_PLLSOURCE_HSE))) 00370 { 00371 if ((__HAL_RCC_GET_FLAG(RCC_FLAG_HSERDY) != RESET) && (RCC_OscInitStruct->HSEState == RCC_HSE_OFF)) 00372 { 00373 return HAL_ERROR; 00374 } 00375 } 00376 else 00377 { 00378 /* Set the new HSE configuration ---------------------------------------*/ 00379 __HAL_RCC_HSE_CONFIG(RCC_OscInitStruct->HSEState); 00380 00381 00382 /* Check the HSE State */ 00383 if (RCC_OscInitStruct->HSEState != RCC_HSE_OFF) 00384 { 00385 /* Get Start Tick */ 00386 tickstart = HAL_GetTick(); 00387 00388 /* Wait till HSE is ready */ 00389 while (__HAL_RCC_GET_FLAG(RCC_FLAG_HSERDY) == RESET) 00390 { 00391 if ((HAL_GetTick() - tickstart) > HSE_TIMEOUT_VALUE) 00392 { 00393 return HAL_TIMEOUT; 00394 } 00395 } 00396 } 00397 else 00398 { 00399 /* Get Start Tick */ 00400 tickstart = HAL_GetTick(); 00401 00402 /* Wait till HSE is disabled */ 00403 while (__HAL_RCC_GET_FLAG(RCC_FLAG_HSERDY) != RESET) 00404 { 00405 if ((HAL_GetTick() - tickstart) > HSE_TIMEOUT_VALUE) 00406 { 00407 return HAL_TIMEOUT; 00408 } 00409 } 00410 } 00411 } 00412 } 00413 /*----------------------------- HSI Configuration --------------------------*/ 00414 if (((RCC_OscInitStruct->OscillatorType) & RCC_OSCILLATORTYPE_HSI) == RCC_OSCILLATORTYPE_HSI) 00415 { 00416 /* Check the parameters */ 00417 assert_param(IS_RCC_HSI(RCC_OscInitStruct->HSIState)); 00418 assert_param(IS_RCC_CALIBRATION_VALUE(RCC_OscInitStruct->HSICalibrationValue)); 00419 00420 /* Check if HSI is used as system clock or as PLL source when PLL is selected as system clock */ 00421 if ((__HAL_RCC_GET_SYSCLK_SOURCE() == RCC_SYSCLKSOURCE_STATUS_HSI) 00422 || ((__HAL_RCC_GET_SYSCLK_SOURCE() == RCC_SYSCLKSOURCE_STATUS_PLLCLK) && (__HAL_RCC_GET_PLL_OSCSOURCE() == RCC_PLLSOURCE_HSI_DIV2))) 00423 { 00424 /* When HSI is used as system clock it will not disabled */ 00425 if ((__HAL_RCC_GET_FLAG(RCC_FLAG_HSIRDY) != RESET) && (RCC_OscInitStruct->HSIState != RCC_HSI_ON)) 00426 { 00427 return HAL_ERROR; 00428 } 00429 /* Otherwise, just the calibration is allowed */ 00430 else 00431 { 00432 /* Adjusts the Internal High Speed oscillator (HSI) calibration value.*/ 00433 __HAL_RCC_HSI_CALIBRATIONVALUE_ADJUST(RCC_OscInitStruct->HSICalibrationValue); 00434 } 00435 } 00436 else 00437 { 00438 /* Check the HSI State */ 00439 if (RCC_OscInitStruct->HSIState != RCC_HSI_OFF) 00440 { 00441 /* Enable the Internal High Speed oscillator (HSI). */ 00442 __HAL_RCC_HSI_ENABLE(); 00443 00444 /* Get Start Tick */ 00445 tickstart = HAL_GetTick(); 00446 00447 /* Wait till HSI is ready */ 00448 while (__HAL_RCC_GET_FLAG(RCC_FLAG_HSIRDY) == RESET) 00449 { 00450 if ((HAL_GetTick() - tickstart) > HSI_TIMEOUT_VALUE) 00451 { 00452 return HAL_TIMEOUT; 00453 } 00454 } 00455 00456 /* Adjusts the Internal High Speed oscillator (HSI) calibration value.*/ 00457 __HAL_RCC_HSI_CALIBRATIONVALUE_ADJUST(RCC_OscInitStruct->HSICalibrationValue); 00458 } 00459 else 00460 { 00461 /* Disable the Internal High Speed oscillator (HSI). */ 00462 __HAL_RCC_HSI_DISABLE(); 00463 00464 /* Get Start Tick */ 00465 tickstart = HAL_GetTick(); 00466 00467 /* Wait till HSI is disabled */ 00468 while (__HAL_RCC_GET_FLAG(RCC_FLAG_HSIRDY) != RESET) 00469 { 00470 if ((HAL_GetTick() - tickstart) > HSI_TIMEOUT_VALUE) 00471 { 00472 return HAL_TIMEOUT; 00473 } 00474 } 00475 } 00476 } 00477 } 00478 /*------------------------------ LSI Configuration -------------------------*/ 00479 if (((RCC_OscInitStruct->OscillatorType) & RCC_OSCILLATORTYPE_LSI) == RCC_OSCILLATORTYPE_LSI) 00480 { 00481 /* Check the parameters */ 00482 assert_param(IS_RCC_LSI(RCC_OscInitStruct->LSIState)); 00483 00484 /* Check the LSI State */ 00485 if (RCC_OscInitStruct->LSIState != RCC_LSI_OFF) 00486 { 00487 /* Enable the Internal Low Speed oscillator (LSI). */ 00488 __HAL_RCC_LSI_ENABLE(); 00489 00490 /* Get Start Tick */ 00491 tickstart = HAL_GetTick(); 00492 00493 /* Wait till LSI is ready */ 00494 while (__HAL_RCC_GET_FLAG(RCC_FLAG_LSIRDY) == RESET) 00495 { 00496 if ((HAL_GetTick() - tickstart) > LSI_TIMEOUT_VALUE) 00497 { 00498 return HAL_TIMEOUT; 00499 } 00500 } 00501 /* To have a fully stabilized clock in the specified range, a software delay of 1ms 00502 should be added.*/ 00503 RCC_Delay(1); 00504 } 00505 else 00506 { 00507 /* Disable the Internal Low Speed oscillator (LSI). */ 00508 __HAL_RCC_LSI_DISABLE(); 00509 00510 /* Get Start Tick */ 00511 tickstart = HAL_GetTick(); 00512 00513 /* Wait till LSI is disabled */ 00514 while (__HAL_RCC_GET_FLAG(RCC_FLAG_LSIRDY) != RESET) 00515 { 00516 if ((HAL_GetTick() - tickstart) > LSI_TIMEOUT_VALUE) 00517 { 00518 return HAL_TIMEOUT; 00519 } 00520 } 00521 } 00522 } 00523 /*------------------------------ LSE Configuration -------------------------*/ 00524 if (((RCC_OscInitStruct->OscillatorType) & RCC_OSCILLATORTYPE_LSE) == RCC_OSCILLATORTYPE_LSE) 00525 { 00526 FlagStatus pwrclkchanged = RESET; 00527 00528 /* Check the parameters */ 00529 assert_param(IS_RCC_LSE(RCC_OscInitStruct->LSEState)); 00530 00531 /* Update LSE configuration in Backup Domain control register */ 00532 /* Requires to enable write access to Backup Domain of necessary */ 00533 if (__HAL_RCC_PWR_IS_CLK_DISABLED()) 00534 { 00535 __HAL_RCC_PWR_CLK_ENABLE(); 00536 pwrclkchanged = SET; 00537 } 00538 00539 if (HAL_IS_BIT_CLR(PWR->CR, PWR_CR_DBP)) 00540 { 00541 /* Enable write access to Backup domain */ 00542 SET_BIT(PWR->CR, PWR_CR_DBP); 00543 00544 /* Wait for Backup domain Write protection disable */ 00545 tickstart = HAL_GetTick(); 00546 00547 while (HAL_IS_BIT_CLR(PWR->CR, PWR_CR_DBP)) 00548 { 00549 if ((HAL_GetTick() - tickstart) > RCC_DBP_TIMEOUT_VALUE) 00550 { 00551 return HAL_TIMEOUT; 00552 } 00553 } 00554 } 00555 00556 /* Set the new LSE configuration -----------------------------------------*/ 00557 __HAL_RCC_LSE_CONFIG(RCC_OscInitStruct->LSEState); 00558 /* Check the LSE State */ 00559 if (RCC_OscInitStruct->LSEState != RCC_LSE_OFF) 00560 { 00561 /* Get Start Tick */ 00562 tickstart = HAL_GetTick(); 00563 00564 /* Wait till LSE is ready */ 00565 while (__HAL_RCC_GET_FLAG(RCC_FLAG_LSERDY) == RESET) 00566 { 00567 if ((HAL_GetTick() - tickstart) > RCC_LSE_TIMEOUT_VALUE) 00568 { 00569 return HAL_TIMEOUT; 00570 } 00571 } 00572 } 00573 else 00574 { 00575 /* Get Start Tick */ 00576 tickstart = HAL_GetTick(); 00577 00578 /* Wait till LSE is disabled */ 00579 while (__HAL_RCC_GET_FLAG(RCC_FLAG_LSERDY) != RESET) 00580 { 00581 if ((HAL_GetTick() - tickstart) > RCC_LSE_TIMEOUT_VALUE) 00582 { 00583 return HAL_TIMEOUT; 00584 } 00585 } 00586 } 00587 00588 /* Require to disable power clock if necessary */ 00589 if (pwrclkchanged == SET) 00590 { 00591 __HAL_RCC_PWR_CLK_DISABLE(); 00592 } 00593 } 00594 00595 #if defined(RCC_CR_PLL2ON) 00596 /*-------------------------------- PLL2 Configuration -----------------------*/ 00597 /* Check the parameters */ 00598 assert_param(IS_RCC_PLL2(RCC_OscInitStruct->PLL2.PLL2State)); 00599 if ((RCC_OscInitStruct->PLL2.PLL2State) != RCC_PLL2_NONE) 00600 { 00601 /* This bit can not be cleared if the PLL2 clock is used indirectly as system 00602 clock (i.e. it is used as PLL clock entry that is used as system clock). */ 00603 if ((__HAL_RCC_GET_PLL_OSCSOURCE() == RCC_PLLSOURCE_HSE) && \ 00604 (__HAL_RCC_GET_SYSCLK_SOURCE() == RCC_SYSCLKSOURCE_STATUS_PLLCLK) && \ 00605 ((READ_BIT(RCC->CFGR2, RCC_CFGR2_PREDIV1SRC)) == RCC_CFGR2_PREDIV1SRC_PLL2)) 00606 { 00607 return HAL_ERROR; 00608 } 00609 else 00610 { 00611 if ((RCC_OscInitStruct->PLL2.PLL2State) == RCC_PLL2_ON) 00612 { 00613 /* Check the parameters */ 00614 assert_param(IS_RCC_PLL2_MUL(RCC_OscInitStruct->PLL2.PLL2MUL)); 00615 assert_param(IS_RCC_HSE_PREDIV2(RCC_OscInitStruct->PLL2.HSEPrediv2Value)); 00616 00617 /* Prediv2 can be written only when the PLLI2S is disabled. */ 00618 /* Return an error only if new value is different from the programmed value */ 00619 if (HAL_IS_BIT_SET(RCC->CR, RCC_CR_PLL3ON) && \ 00620 (__HAL_RCC_HSE_GET_PREDIV2() != RCC_OscInitStruct->PLL2.HSEPrediv2Value)) 00621 { 00622 return HAL_ERROR; 00623 } 00624 00625 /* Disable the main PLL2. */ 00626 __HAL_RCC_PLL2_DISABLE(); 00627 00628 /* Get Start Tick */ 00629 tickstart = HAL_GetTick(); 00630 00631 /* Wait till PLL2 is disabled */ 00632 while (__HAL_RCC_GET_FLAG(RCC_FLAG_PLL2RDY) != RESET) 00633 { 00634 if ((HAL_GetTick() - tickstart) > PLL2_TIMEOUT_VALUE) 00635 { 00636 return HAL_TIMEOUT; 00637 } 00638 } 00639 00640 /* Configure the HSE prediv2 factor --------------------------------*/ 00641 __HAL_RCC_HSE_PREDIV2_CONFIG(RCC_OscInitStruct->PLL2.HSEPrediv2Value); 00642 00643 /* Configure the main PLL2 multiplication factors. */ 00644 __HAL_RCC_PLL2_CONFIG(RCC_OscInitStruct->PLL2.PLL2MUL); 00645 00646 /* Enable the main PLL2. */ 00647 __HAL_RCC_PLL2_ENABLE(); 00648 00649 /* Get Start Tick */ 00650 tickstart = HAL_GetTick(); 00651 00652 /* Wait till PLL2 is ready */ 00653 while (__HAL_RCC_GET_FLAG(RCC_FLAG_PLL2RDY) == RESET) 00654 { 00655 if ((HAL_GetTick() - tickstart) > PLL2_TIMEOUT_VALUE) 00656 { 00657 return HAL_TIMEOUT; 00658 } 00659 } 00660 } 00661 else 00662 { 00663 /* Set PREDIV1 source to HSE */ 00664 CLEAR_BIT(RCC->CFGR2, RCC_CFGR2_PREDIV1SRC); 00665 00666 /* Disable the main PLL2. */ 00667 __HAL_RCC_PLL2_DISABLE(); 00668 00669 /* Get Start Tick */ 00670 tickstart = HAL_GetTick(); 00671 00672 /* Wait till PLL2 is disabled */ 00673 while (__HAL_RCC_GET_FLAG(RCC_FLAG_PLL2RDY) != RESET) 00674 { 00675 if ((HAL_GetTick() - tickstart) > PLL2_TIMEOUT_VALUE) 00676 { 00677 return HAL_TIMEOUT; 00678 } 00679 } 00680 } 00681 } 00682 } 00683 00684 #endif /* RCC_CR_PLL2ON */ 00685 /*-------------------------------- PLL Configuration -----------------------*/ 00686 /* Check the parameters */ 00687 assert_param(IS_RCC_PLL(RCC_OscInitStruct->PLL.PLLState)); 00688 if ((RCC_OscInitStruct->PLL.PLLState) != RCC_PLL_NONE) 00689 { 00690 /* Check if the PLL is used as system clock or not */ 00691 if (__HAL_RCC_GET_SYSCLK_SOURCE() != RCC_SYSCLKSOURCE_STATUS_PLLCLK) 00692 { 00693 if ((RCC_OscInitStruct->PLL.PLLState) == RCC_PLL_ON) 00694 { 00695 /* Check the parameters */ 00696 assert_param(IS_RCC_PLLSOURCE(RCC_OscInitStruct->PLL.PLLSource)); 00697 assert_param(IS_RCC_PLL_MUL(RCC_OscInitStruct->PLL.PLLMUL)); 00698 00699 /* Disable the main PLL. */ 00700 __HAL_RCC_PLL_DISABLE(); 00701 00702 /* Get Start Tick */ 00703 tickstart = HAL_GetTick(); 00704 00705 /* Wait till PLL is disabled */ 00706 while (__HAL_RCC_GET_FLAG(RCC_FLAG_PLLRDY) != RESET) 00707 { 00708 if ((HAL_GetTick() - tickstart) > PLL_TIMEOUT_VALUE) 00709 { 00710 return HAL_TIMEOUT; 00711 } 00712 } 00713 00714 /* Configure the HSE prediv factor --------------------------------*/ 00715 /* It can be written only when the PLL is disabled. Not used in PLL source is different than HSE */ 00716 if (RCC_OscInitStruct->PLL.PLLSource == RCC_PLLSOURCE_HSE) 00717 { 00718 /* Check the parameter */ 00719 assert_param(IS_RCC_HSE_PREDIV(RCC_OscInitStruct->HSEPredivValue)); 00720 #if defined(RCC_CFGR2_PREDIV1SRC) 00721 assert_param(IS_RCC_PREDIV1_SOURCE(RCC_OscInitStruct->Prediv1Source)); 00722 00723 /* Set PREDIV1 source */ 00724 SET_BIT(RCC->CFGR2, RCC_OscInitStruct->Prediv1Source); 00725 #endif /* RCC_CFGR2_PREDIV1SRC */ 00726 00727 /* Set PREDIV1 Value */ 00728 __HAL_RCC_HSE_PREDIV_CONFIG(RCC_OscInitStruct->HSEPredivValue); 00729 } 00730 00731 /* Configure the main PLL clock source and multiplication factors. */ 00732 __HAL_RCC_PLL_CONFIG(RCC_OscInitStruct->PLL.PLLSource, 00733 RCC_OscInitStruct->PLL.PLLMUL); 00734 /* Enable the main PLL. */ 00735 __HAL_RCC_PLL_ENABLE(); 00736 00737 /* Get Start Tick */ 00738 tickstart = HAL_GetTick(); 00739 00740 /* Wait till PLL is ready */ 00741 while (__HAL_RCC_GET_FLAG(RCC_FLAG_PLLRDY) == RESET) 00742 { 00743 if ((HAL_GetTick() - tickstart) > PLL_TIMEOUT_VALUE) 00744 { 00745 return HAL_TIMEOUT; 00746 } 00747 } 00748 } 00749 else 00750 { 00751 /* Disable the main PLL. */ 00752 __HAL_RCC_PLL_DISABLE(); 00753 00754 /* Get Start Tick */ 00755 tickstart = HAL_GetTick(); 00756 00757 /* Wait till PLL is disabled */ 00758 while (__HAL_RCC_GET_FLAG(RCC_FLAG_PLLRDY) != RESET) 00759 { 00760 if ((HAL_GetTick() - tickstart) > PLL_TIMEOUT_VALUE) 00761 { 00762 return HAL_TIMEOUT; 00763 } 00764 } 00765 } 00766 } 00767 else 00768 { 00769 /* Check if there is a request to disable the PLL used as System clock source */ 00770 if ((RCC_OscInitStruct->PLL.PLLState) == RCC_PLL_OFF) 00771 { 00772 return HAL_ERROR; 00773 } 00774 else 00775 { 00776 /* Do not return HAL_ERROR if request repeats the current configuration */ 00777 pll_config = RCC->CFGR; 00778 if ((READ_BIT(pll_config, RCC_CFGR_PLLSRC) != RCC_OscInitStruct->PLL.PLLSource) || 00779 (READ_BIT(pll_config, RCC_CFGR_PLLMULL) != RCC_OscInitStruct->PLL.PLLMUL)) 00780 { 00781 return HAL_ERROR; 00782 } 00783 } 00784 } 00785 } 00786 00787 return HAL_OK; 00788 } 00789 00790 /** 00791 * @brief Initializes the CPU, AHB and APB buses clocks according to the specified 00792 * parameters in the RCC_ClkInitStruct. 00793 * @param RCC_ClkInitStruct pointer to an RCC_OscInitTypeDef structure that 00794 * contains the configuration information for the RCC peripheral. 00795 * @param FLatency FLASH Latency 00796 * The value of this parameter depend on device used within the same series 00797 * @note The SystemCoreClock CMSIS variable is used to store System Clock Frequency 00798 * and updated by @ref HAL_RCC_GetHCLKFreq() function called within this function 00799 * 00800 * @note The HSI is used (enabled by hardware) as system clock source after 00801 * start-up from Reset, wake-up from STOP and STANDBY mode, or in case 00802 * of failure of the HSE used directly or indirectly as system clock 00803 * (if the Clock Security System CSS is enabled). 00804 * 00805 * @note A switch from one clock source to another occurs only if the target 00806 * clock source is ready (clock stable after start-up delay or PLL locked). 00807 * If a clock source which is not yet ready is selected, the switch will 00808 * occur when the clock source will be ready. 00809 * You can use @ref HAL_RCC_GetClockConfig() function to know which clock is 00810 * currently used as system clock source. 00811 * @retval HAL status 00812 */ 00813 HAL_StatusTypeDef HAL_RCC_ClockConfig(RCC_ClkInitTypeDef *RCC_ClkInitStruct, uint32_t FLatency) 00814 { 00815 uint32_t tickstart; 00816 00817 /* Check Null pointer */ 00818 if (RCC_ClkInitStruct == NULL) 00819 { 00820 return HAL_ERROR; 00821 } 00822 00823 /* Check the parameters */ 00824 assert_param(IS_RCC_CLOCKTYPE(RCC_ClkInitStruct->ClockType)); 00825 assert_param(IS_FLASH_LATENCY(FLatency)); 00826 00827 /* To correctly read data from FLASH memory, the number of wait states (LATENCY) 00828 must be correctly programmed according to the frequency of the CPU clock 00829 (HCLK) of the device. */ 00830 00831 #if defined(FLASH_ACR_LATENCY) 00832 /* Increasing the number of wait states because of higher CPU frequency */ 00833 if (FLatency > __HAL_FLASH_GET_LATENCY()) 00834 { 00835 /* Program the new number of wait states to the LATENCY bits in the FLASH_ACR register */ 00836 __HAL_FLASH_SET_LATENCY(FLatency); 00837 00838 /* Check that the new number of wait states is taken into account to access the Flash 00839 memory by reading the FLASH_ACR register */ 00840 if (__HAL_FLASH_GET_LATENCY() != FLatency) 00841 { 00842 return HAL_ERROR; 00843 } 00844 } 00845 00846 #endif /* FLASH_ACR_LATENCY */ 00847 /*-------------------------- HCLK Configuration --------------------------*/ 00848 if (((RCC_ClkInitStruct->ClockType) & RCC_CLOCKTYPE_HCLK) == RCC_CLOCKTYPE_HCLK) 00849 { 00850 /* Set the highest APBx dividers in order to ensure that we do not go through 00851 a non-spec phase whatever we decrease or increase HCLK. */ 00852 if (((RCC_ClkInitStruct->ClockType) & RCC_CLOCKTYPE_PCLK1) == RCC_CLOCKTYPE_PCLK1) 00853 { 00854 MODIFY_REG(RCC->CFGR, RCC_CFGR_PPRE1, RCC_HCLK_DIV16); 00855 } 00856 00857 if (((RCC_ClkInitStruct->ClockType) & RCC_CLOCKTYPE_PCLK2) == RCC_CLOCKTYPE_PCLK2) 00858 { 00859 MODIFY_REG(RCC->CFGR, RCC_CFGR_PPRE2, (RCC_HCLK_DIV16 << 3)); 00860 } 00861 00862 /* Set the new HCLK clock divider */ 00863 assert_param(IS_RCC_HCLK(RCC_ClkInitStruct->AHBCLKDivider)); 00864 MODIFY_REG(RCC->CFGR, RCC_CFGR_HPRE, RCC_ClkInitStruct->AHBCLKDivider); 00865 } 00866 00867 /*------------------------- SYSCLK Configuration ---------------------------*/ 00868 if (((RCC_ClkInitStruct->ClockType) & RCC_CLOCKTYPE_SYSCLK) == RCC_CLOCKTYPE_SYSCLK) 00869 { 00870 assert_param(IS_RCC_SYSCLKSOURCE(RCC_ClkInitStruct->SYSCLKSource)); 00871 00872 /* HSE is selected as System Clock Source */ 00873 if (RCC_ClkInitStruct->SYSCLKSource == RCC_SYSCLKSOURCE_HSE) 00874 { 00875 /* Check the HSE ready flag */ 00876 if (__HAL_RCC_GET_FLAG(RCC_FLAG_HSERDY) == RESET) 00877 { 00878 return HAL_ERROR; 00879 } 00880 } 00881 /* PLL is selected as System Clock Source */ 00882 else if (RCC_ClkInitStruct->SYSCLKSource == RCC_SYSCLKSOURCE_PLLCLK) 00883 { 00884 /* Check the PLL ready flag */ 00885 if (__HAL_RCC_GET_FLAG(RCC_FLAG_PLLRDY) == RESET) 00886 { 00887 return HAL_ERROR; 00888 } 00889 } 00890 /* HSI is selected as System Clock Source */ 00891 else 00892 { 00893 /* Check the HSI ready flag */ 00894 if (__HAL_RCC_GET_FLAG(RCC_FLAG_HSIRDY) == RESET) 00895 { 00896 return HAL_ERROR; 00897 } 00898 } 00899 __HAL_RCC_SYSCLK_CONFIG(RCC_ClkInitStruct->SYSCLKSource); 00900 00901 /* Get Start Tick */ 00902 tickstart = HAL_GetTick(); 00903 00904 while (__HAL_RCC_GET_SYSCLK_SOURCE() != (RCC_ClkInitStruct->SYSCLKSource << RCC_CFGR_SWS_Pos)) 00905 { 00906 if ((HAL_GetTick() - tickstart) > CLOCKSWITCH_TIMEOUT_VALUE) 00907 { 00908 return HAL_TIMEOUT; 00909 } 00910 } 00911 } 00912 00913 #if defined(FLASH_ACR_LATENCY) 00914 /* Decreasing the number of wait states because of lower CPU frequency */ 00915 if (FLatency < __HAL_FLASH_GET_LATENCY()) 00916 { 00917 /* Program the new number of wait states to the LATENCY bits in the FLASH_ACR register */ 00918 __HAL_FLASH_SET_LATENCY(FLatency); 00919 00920 /* Check that the new number of wait states is taken into account to access the Flash 00921 memory by reading the FLASH_ACR register */ 00922 if (__HAL_FLASH_GET_LATENCY() != FLatency) 00923 { 00924 return HAL_ERROR; 00925 } 00926 } 00927 #endif /* FLASH_ACR_LATENCY */ 00928 00929 /*-------------------------- PCLK1 Configuration ---------------------------*/ 00930 if (((RCC_ClkInitStruct->ClockType) & RCC_CLOCKTYPE_PCLK1) == RCC_CLOCKTYPE_PCLK1) 00931 { 00932 assert_param(IS_RCC_PCLK(RCC_ClkInitStruct->APB1CLKDivider)); 00933 MODIFY_REG(RCC->CFGR, RCC_CFGR_PPRE1, RCC_ClkInitStruct->APB1CLKDivider); 00934 } 00935 00936 /*-------------------------- PCLK2 Configuration ---------------------------*/ 00937 if (((RCC_ClkInitStruct->ClockType) & RCC_CLOCKTYPE_PCLK2) == RCC_CLOCKTYPE_PCLK2) 00938 { 00939 assert_param(IS_RCC_PCLK(RCC_ClkInitStruct->APB2CLKDivider)); 00940 MODIFY_REG(RCC->CFGR, RCC_CFGR_PPRE2, ((RCC_ClkInitStruct->APB2CLKDivider) << 3)); 00941 } 00942 00943 /* Update the SystemCoreClock global variable */ 00944 SystemCoreClock = HAL_RCC_GetSysClockFreq() >> AHBPrescTable[(RCC->CFGR & RCC_CFGR_HPRE) >> RCC_CFGR_HPRE_Pos]; 00945 00946 /* Configure the source of time base considering new system clocks settings*/ 00947 HAL_InitTick(uwTickPrio); 00948 00949 return HAL_OK; 00950 } 00951 00952 /** 00953 * @} 00954 */ 00955 00956 /** @defgroup RCC_Exported_Functions_Group2 Peripheral Control functions 00957 * @brief RCC clocks control functions 00958 * 00959 @verbatim 00960 =============================================================================== 00961 ##### Peripheral Control functions ##### 00962 =============================================================================== 00963 [..] 00964 This subsection provides a set of functions allowing to control the RCC Clocks 00965 frequencies. 00966 00967 @endverbatim 00968 * @{ 00969 */ 00970 00971 /** 00972 * @brief Selects the clock source to output on MCO pin. 00973 * @note MCO pin should be configured in alternate function mode. 00974 * @param RCC_MCOx specifies the output direction for the clock source. 00975 * This parameter can be one of the following values: 00976 * @arg @ref RCC_MCO1 Clock source to output on MCO1 pin(PA8). 00977 * @param RCC_MCOSource specifies the clock source to output. 00978 * This parameter can be one of the following values: 00979 * @arg @ref RCC_MCO1SOURCE_NOCLOCK No clock selected as MCO clock 00980 * @arg @ref RCC_MCO1SOURCE_SYSCLK System clock selected as MCO clock 00981 * @arg @ref RCC_MCO1SOURCE_HSI HSI selected as MCO clock 00982 * @arg @ref RCC_MCO1SOURCE_HSE HSE selected as MCO clock 00983 @if STM32F105xC 00984 * @arg @ref RCC_MCO1SOURCE_PLLCLK PLL clock divided by 2 selected as MCO source 00985 * @arg @ref RCC_MCO1SOURCE_PLL2CLK PLL2 clock selected as MCO source 00986 * @arg @ref RCC_MCO1SOURCE_PLL3CLK_DIV2 PLL3 clock divided by 2 selected as MCO source 00987 * @arg @ref RCC_MCO1SOURCE_EXT_HSE XT1 external 3-25 MHz oscillator clock selected as MCO source 00988 * @arg @ref RCC_MCO1SOURCE_PLL3CLK PLL3 clock selected as MCO source 00989 @endif 00990 @if STM32F107xC 00991 * @arg @ref RCC_MCO1SOURCE_PLLCLK PLL clock divided by 2 selected as MCO source 00992 * @arg @ref RCC_MCO1SOURCE_PLL2CLK PLL2 clock selected as MCO source 00993 * @arg @ref RCC_MCO1SOURCE_PLL3CLK_DIV2 PLL3 clock divided by 2 selected as MCO source 00994 * @arg @ref RCC_MCO1SOURCE_EXT_HSE XT1 external 3-25 MHz oscillator clock selected as MCO source 00995 * @arg @ref RCC_MCO1SOURCE_PLL3CLK PLL3 clock selected as MCO source 00996 @endif 00997 * @param RCC_MCODiv specifies the MCO DIV. 00998 * This parameter can be one of the following values: 00999 * @arg @ref RCC_MCODIV_1 no division applied to MCO clock 01000 * @retval None 01001 */ 01002 void HAL_RCC_MCOConfig(uint32_t RCC_MCOx, uint32_t RCC_MCOSource, uint32_t RCC_MCODiv) 01003 { 01004 GPIO_InitTypeDef gpio = {0U}; 01005 01006 /* Check the parameters */ 01007 assert_param(IS_RCC_MCO(RCC_MCOx)); 01008 assert_param(IS_RCC_MCODIV(RCC_MCODiv)); 01009 assert_param(IS_RCC_MCO1SOURCE(RCC_MCOSource)); 01010 01011 /* Prevent unused argument(s) compilation warning */ 01012 UNUSED(RCC_MCOx); 01013 UNUSED(RCC_MCODiv); 01014 01015 /* Configure the MCO1 pin in alternate function mode */ 01016 gpio.Mode = GPIO_MODE_AF_PP; 01017 gpio.Speed = GPIO_SPEED_FREQ_HIGH; 01018 gpio.Pull = GPIO_NOPULL; 01019 gpio.Pin = MCO1_PIN; 01020 01021 /* MCO1 Clock Enable */ 01022 MCO1_CLK_ENABLE(); 01023 01024 HAL_GPIO_Init(MCO1_GPIO_PORT, &gpio); 01025 01026 /* Configure the MCO clock source */ 01027 __HAL_RCC_MCO1_CONFIG(RCC_MCOSource, RCC_MCODiv); 01028 } 01029 01030 /** 01031 * @brief Enables the Clock Security System. 01032 * @note If a failure is detected on the HSE oscillator clock, this oscillator 01033 * is automatically disabled and an interrupt is generated to inform the 01034 * software about the failure (Clock Security System Interrupt, CSSI), 01035 * allowing the MCU to perform rescue operations. The CSSI is linked to 01036 * the Cortex-M3 NMI (Non-Maskable Interrupt) exception vector. 01037 * @retval None 01038 */ 01039 void HAL_RCC_EnableCSS(void) 01040 { 01041 *(__IO uint32_t *) RCC_CR_CSSON_BB = (uint32_t)ENABLE; 01042 } 01043 01044 /** 01045 * @brief Disables the Clock Security System. 01046 * @retval None 01047 */ 01048 void HAL_RCC_DisableCSS(void) 01049 { 01050 *(__IO uint32_t *) RCC_CR_CSSON_BB = (uint32_t)DISABLE; 01051 } 01052 01053 /** 01054 * @brief Returns the SYSCLK frequency 01055 * @note The system frequency computed by this function is not the real 01056 * frequency in the chip. It is calculated based on the predefined 01057 * constant and the selected clock source: 01058 * @note If SYSCLK source is HSI, function returns values based on HSI_VALUE(*) 01059 * @note If SYSCLK source is HSE, function returns a value based on HSE_VALUE 01060 * divided by PREDIV factor(**) 01061 * @note If SYSCLK source is PLL, function returns a value based on HSE_VALUE 01062 * divided by PREDIV factor(**) or HSI_VALUE(*) multiplied by the PLL factor. 01063 * @note (*) HSI_VALUE is a constant defined in stm32f1xx_hal_conf.h file (default value 01064 * 8 MHz) but the real value may vary depending on the variations 01065 * in voltage and temperature. 01066 * @note (**) HSE_VALUE is a constant defined in stm32f1xx_hal_conf.h file (default value 01067 * 8 MHz), user has to ensure that HSE_VALUE is same as the real 01068 * frequency of the crystal used. Otherwise, this function may 01069 * have wrong result. 01070 * 01071 * @note The result of this function could be not correct when using fractional 01072 * value for HSE crystal. 01073 * 01074 * @note This function can be used by the user application to compute the 01075 * baud-rate for the communication peripherals or configure other parameters. 01076 * 01077 * @note Each time SYSCLK changes, this function must be called to update the 01078 * right SYSCLK value. Otherwise, any configuration based on this function will be incorrect. 01079 * 01080 * @retval SYSCLK frequency 01081 */ 01082 uint32_t HAL_RCC_GetSysClockFreq(void) 01083 { 01084 #if defined(RCC_CFGR2_PREDIV1SRC) 01085 const uint8_t aPLLMULFactorTable[14] = {0, 0, 4, 5, 6, 7, 8, 9, 0, 0, 0, 0, 0, 13}; 01086 const uint8_t aPredivFactorTable[16] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16}; 01087 #else 01088 const uint8_t aPLLMULFactorTable[16] = {2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 16}; 01089 #if defined(RCC_CFGR2_PREDIV1) 01090 const uint8_t aPredivFactorTable[16] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16}; 01091 #else 01092 const uint8_t aPredivFactorTable[2] = {1, 2}; 01093 #endif /*RCC_CFGR2_PREDIV1*/ 01094 01095 #endif 01096 uint32_t tmpreg = 0U, prediv = 0U, pllclk = 0U, pllmul = 0U; 01097 uint32_t sysclockfreq = 0U; 01098 #if defined(RCC_CFGR2_PREDIV1SRC) 01099 uint32_t prediv2 = 0U, pll2mul = 0U; 01100 #endif /*RCC_CFGR2_PREDIV1SRC*/ 01101 01102 tmpreg = RCC->CFGR; 01103 01104 /* Get SYSCLK source -------------------------------------------------------*/ 01105 switch (tmpreg & RCC_CFGR_SWS) 01106 { 01107 case RCC_SYSCLKSOURCE_STATUS_HSE: /* HSE used as system clock */ 01108 { 01109 sysclockfreq = HSE_VALUE; 01110 break; 01111 } 01112 case RCC_SYSCLKSOURCE_STATUS_PLLCLK: /* PLL used as system clock */ 01113 { 01114 pllmul = aPLLMULFactorTable[(uint32_t)(tmpreg & RCC_CFGR_PLLMULL) >> RCC_CFGR_PLLMULL_Pos]; 01115 if ((tmpreg & RCC_CFGR_PLLSRC) != RCC_PLLSOURCE_HSI_DIV2) 01116 { 01117 #if defined(RCC_CFGR2_PREDIV1) 01118 prediv = aPredivFactorTable[(uint32_t)(RCC->CFGR2 & RCC_CFGR2_PREDIV1) >> RCC_CFGR2_PREDIV1_Pos]; 01119 #else 01120 prediv = aPredivFactorTable[(uint32_t)(RCC->CFGR & RCC_CFGR_PLLXTPRE) >> RCC_CFGR_PLLXTPRE_Pos]; 01121 #endif /*RCC_CFGR2_PREDIV1*/ 01122 #if defined(RCC_CFGR2_PREDIV1SRC) 01123 01124 if (HAL_IS_BIT_SET(RCC->CFGR2, RCC_CFGR2_PREDIV1SRC)) 01125 { 01126 /* PLL2 selected as Prediv1 source */ 01127 /* PLLCLK = PLL2CLK / PREDIV1 * PLLMUL with PLL2CLK = HSE/PREDIV2 * PLL2MUL */ 01128 prediv2 = ((RCC->CFGR2 & RCC_CFGR2_PREDIV2) >> RCC_CFGR2_PREDIV2_Pos) + 1; 01129 pll2mul = ((RCC->CFGR2 & RCC_CFGR2_PLL2MUL) >> RCC_CFGR2_PLL2MUL_Pos) + 2; 01130 pllclk = (uint32_t)(((uint64_t)HSE_VALUE * (uint64_t)pll2mul * (uint64_t)pllmul) / ((uint64_t)prediv2 * (uint64_t)prediv)); 01131 } 01132 else 01133 { 01134 /* HSE used as PLL clock source : PLLCLK = HSE/PREDIV1 * PLLMUL */ 01135 pllclk = (uint32_t)((HSE_VALUE * pllmul) / prediv); 01136 } 01137 01138 /* If PLLMUL was set to 13 means that it was to cover the case PLLMUL 6.5 (avoid using float) */ 01139 /* In this case need to divide pllclk by 2 */ 01140 if (pllmul == aPLLMULFactorTable[(uint32_t)(RCC_CFGR_PLLMULL6_5) >> RCC_CFGR_PLLMULL_Pos]) 01141 { 01142 pllclk = pllclk / 2; 01143 } 01144 #else 01145 /* HSE used as PLL clock source : PLLCLK = HSE/PREDIV1 * PLLMUL */ 01146 pllclk = (uint32_t)((HSE_VALUE * pllmul) / prediv); 01147 #endif /*RCC_CFGR2_PREDIV1SRC*/ 01148 } 01149 else 01150 { 01151 /* HSI used as PLL clock source : PLLCLK = HSI/2 * PLLMUL */ 01152 pllclk = (uint32_t)((HSI_VALUE >> 1) * pllmul); 01153 } 01154 sysclockfreq = pllclk; 01155 break; 01156 } 01157 case RCC_SYSCLKSOURCE_STATUS_HSI: /* HSI used as system clock source */ 01158 default: /* HSI used as system clock */ 01159 { 01160 sysclockfreq = HSI_VALUE; 01161 break; 01162 } 01163 } 01164 return sysclockfreq; 01165 } 01166 01167 /** 01168 * @brief Returns the HCLK frequency 01169 * @note Each time HCLK changes, this function must be called to update the 01170 * right HCLK value. Otherwise, any configuration based on this function will be incorrect. 01171 * 01172 * @note The SystemCoreClock CMSIS variable is used to store System Clock Frequency 01173 * and updated within this function 01174 * @retval HCLK frequency 01175 */ 01176 uint32_t HAL_RCC_GetHCLKFreq(void) 01177 { 01178 return SystemCoreClock; 01179 } 01180 01181 /** 01182 * @brief Returns the PCLK1 frequency 01183 * @note Each time PCLK1 changes, this function must be called to update the 01184 * right PCLK1 value. Otherwise, any configuration based on this function will be incorrect. 01185 * @retval PCLK1 frequency 01186 */ 01187 uint32_t HAL_RCC_GetPCLK1Freq(void) 01188 { 01189 /* Get HCLK source and Compute PCLK1 frequency ---------------------------*/ 01190 return (HAL_RCC_GetHCLKFreq() >> APBPrescTable[(RCC->CFGR & RCC_CFGR_PPRE1) >> RCC_CFGR_PPRE1_Pos]); 01191 } 01192 01193 /** 01194 * @brief Returns the PCLK2 frequency 01195 * @note Each time PCLK2 changes, this function must be called to update the 01196 * right PCLK2 value. Otherwise, any configuration based on this function will be incorrect. 01197 * @retval PCLK2 frequency 01198 */ 01199 uint32_t HAL_RCC_GetPCLK2Freq(void) 01200 { 01201 /* Get HCLK source and Compute PCLK2 frequency ---------------------------*/ 01202 return (HAL_RCC_GetHCLKFreq() >> APBPrescTable[(RCC->CFGR & RCC_CFGR_PPRE2) >> RCC_CFGR_PPRE2_Pos]); 01203 } 01204 01205 /** 01206 * @brief Configures the RCC_OscInitStruct according to the internal 01207 * RCC configuration registers. 01208 * @param RCC_OscInitStruct pointer to an RCC_OscInitTypeDef structure that 01209 * will be configured. 01210 * @retval None 01211 */ 01212 void HAL_RCC_GetOscConfig(RCC_OscInitTypeDef *RCC_OscInitStruct) 01213 { 01214 /* Check the parameters */ 01215 assert_param(RCC_OscInitStruct != NULL); 01216 01217 /* Set all possible values for the Oscillator type parameter ---------------*/ 01218 RCC_OscInitStruct->OscillatorType = RCC_OSCILLATORTYPE_HSE | RCC_OSCILLATORTYPE_HSI \ 01219 | RCC_OSCILLATORTYPE_LSE | RCC_OSCILLATORTYPE_LSI; 01220 01221 #if defined(RCC_CFGR2_PREDIV1SRC) 01222 /* Get the Prediv1 source --------------------------------------------------*/ 01223 RCC_OscInitStruct->Prediv1Source = READ_BIT(RCC->CFGR2, RCC_CFGR2_PREDIV1SRC); 01224 #endif /* RCC_CFGR2_PREDIV1SRC */ 01225 01226 /* Get the HSE configuration -----------------------------------------------*/ 01227 if ((RCC->CR & RCC_CR_HSEBYP) == RCC_CR_HSEBYP) 01228 { 01229 RCC_OscInitStruct->HSEState = RCC_HSE_BYPASS; 01230 } 01231 else if ((RCC->CR & RCC_CR_HSEON) == RCC_CR_HSEON) 01232 { 01233 RCC_OscInitStruct->HSEState = RCC_HSE_ON; 01234 } 01235 else 01236 { 01237 RCC_OscInitStruct->HSEState = RCC_HSE_OFF; 01238 } 01239 RCC_OscInitStruct->HSEPredivValue = __HAL_RCC_HSE_GET_PREDIV(); 01240 01241 /* Get the HSI configuration -----------------------------------------------*/ 01242 if ((RCC->CR & RCC_CR_HSION) == RCC_CR_HSION) 01243 { 01244 RCC_OscInitStruct->HSIState = RCC_HSI_ON; 01245 } 01246 else 01247 { 01248 RCC_OscInitStruct->HSIState = RCC_HSI_OFF; 01249 } 01250 01251 RCC_OscInitStruct->HSICalibrationValue = (uint32_t)((RCC->CR & RCC_CR_HSITRIM) >> RCC_CR_HSITRIM_Pos); 01252 01253 /* Get the LSE configuration -----------------------------------------------*/ 01254 if ((RCC->BDCR & RCC_BDCR_LSEBYP) == RCC_BDCR_LSEBYP) 01255 { 01256 RCC_OscInitStruct->LSEState = RCC_LSE_BYPASS; 01257 } 01258 else if ((RCC->BDCR & RCC_BDCR_LSEON) == RCC_BDCR_LSEON) 01259 { 01260 RCC_OscInitStruct->LSEState = RCC_LSE_ON; 01261 } 01262 else 01263 { 01264 RCC_OscInitStruct->LSEState = RCC_LSE_OFF; 01265 } 01266 01267 /* Get the LSI configuration -----------------------------------------------*/ 01268 if ((RCC->CSR & RCC_CSR_LSION) == RCC_CSR_LSION) 01269 { 01270 RCC_OscInitStruct->LSIState = RCC_LSI_ON; 01271 } 01272 else 01273 { 01274 RCC_OscInitStruct->LSIState = RCC_LSI_OFF; 01275 } 01276 01277 01278 /* Get the PLL configuration -----------------------------------------------*/ 01279 if ((RCC->CR & RCC_CR_PLLON) == RCC_CR_PLLON) 01280 { 01281 RCC_OscInitStruct->PLL.PLLState = RCC_PLL_ON; 01282 } 01283 else 01284 { 01285 RCC_OscInitStruct->PLL.PLLState = RCC_PLL_OFF; 01286 } 01287 RCC_OscInitStruct->PLL.PLLSource = (uint32_t)(RCC->CFGR & RCC_CFGR_PLLSRC); 01288 RCC_OscInitStruct->PLL.PLLMUL = (uint32_t)(RCC->CFGR & RCC_CFGR_PLLMULL); 01289 #if defined(RCC_CR_PLL2ON) 01290 /* Get the PLL2 configuration -----------------------------------------------*/ 01291 if ((RCC->CR & RCC_CR_PLL2ON) == RCC_CR_PLL2ON) 01292 { 01293 RCC_OscInitStruct->PLL2.PLL2State = RCC_PLL2_ON; 01294 } 01295 else 01296 { 01297 RCC_OscInitStruct->PLL2.PLL2State = RCC_PLL2_OFF; 01298 } 01299 RCC_OscInitStruct->PLL2.HSEPrediv2Value = __HAL_RCC_HSE_GET_PREDIV2(); 01300 RCC_OscInitStruct->PLL2.PLL2MUL = (uint32_t)(RCC->CFGR2 & RCC_CFGR2_PLL2MUL); 01301 #endif /* RCC_CR_PLL2ON */ 01302 } 01303 01304 /** 01305 * @brief Get the RCC_ClkInitStruct according to the internal 01306 * RCC configuration registers. 01307 * @param RCC_ClkInitStruct pointer to an RCC_ClkInitTypeDef structure that 01308 * contains the current clock configuration. 01309 * @param pFLatency Pointer on the Flash Latency. 01310 * @retval None 01311 */ 01312 void HAL_RCC_GetClockConfig(RCC_ClkInitTypeDef *RCC_ClkInitStruct, uint32_t *pFLatency) 01313 { 01314 /* Check the parameters */ 01315 assert_param(RCC_ClkInitStruct != NULL); 01316 assert_param(pFLatency != NULL); 01317 01318 /* Set all possible values for the Clock type parameter --------------------*/ 01319 RCC_ClkInitStruct->ClockType = RCC_CLOCKTYPE_SYSCLK | RCC_CLOCKTYPE_HCLK | RCC_CLOCKTYPE_PCLK1 | RCC_CLOCKTYPE_PCLK2; 01320 01321 /* Get the SYSCLK configuration --------------------------------------------*/ 01322 RCC_ClkInitStruct->SYSCLKSource = (uint32_t)(RCC->CFGR & RCC_CFGR_SW); 01323 01324 /* Get the HCLK configuration ----------------------------------------------*/ 01325 RCC_ClkInitStruct->AHBCLKDivider = (uint32_t)(RCC->CFGR & RCC_CFGR_HPRE); 01326 01327 /* Get the APB1 configuration ----------------------------------------------*/ 01328 RCC_ClkInitStruct->APB1CLKDivider = (uint32_t)(RCC->CFGR & RCC_CFGR_PPRE1); 01329 01330 /* Get the APB2 configuration ----------------------------------------------*/ 01331 RCC_ClkInitStruct->APB2CLKDivider = (uint32_t)((RCC->CFGR & RCC_CFGR_PPRE2) >> 3); 01332 01333 #if defined(FLASH_ACR_LATENCY) 01334 /* Get the Flash Wait State (Latency) configuration ------------------------*/ 01335 *pFLatency = (uint32_t)(FLASH->ACR & FLASH_ACR_LATENCY); 01336 #else 01337 /* For VALUE lines devices, only LATENCY_0 can be set*/ 01338 *pFLatency = (uint32_t)FLASH_LATENCY_0; 01339 #endif 01340 } 01341 01342 /** 01343 * @brief This function handles the RCC CSS interrupt request. 01344 * @note This API should be called under the NMI_Handler(). 01345 * @retval None 01346 */ 01347 void HAL_RCC_NMI_IRQHandler(void) 01348 { 01349 /* Check RCC CSSF flag */ 01350 if (__HAL_RCC_GET_IT(RCC_IT_CSS)) 01351 { 01352 /* RCC Clock Security System interrupt user callback */ 01353 HAL_RCC_CSSCallback(); 01354 01355 /* Clear RCC CSS pending bit */ 01356 __HAL_RCC_CLEAR_IT(RCC_IT_CSS); 01357 } 01358 } 01359 01360 /** 01361 * @brief This function provides delay (in milliseconds) based on CPU cycles method. 01362 * @param mdelay: specifies the delay time length, in milliseconds. 01363 * @retval None 01364 */ 01365 static void RCC_Delay(uint32_t mdelay) 01366 { 01367 __IO uint32_t Delay = mdelay * (SystemCoreClock / 8U / 1000U); 01368 do 01369 { 01370 __NOP(); 01371 } 01372 while (Delay --); 01373 } 01374 01375 /** 01376 * @brief RCC Clock Security System interrupt callback 01377 * @retval none 01378 */ 01379 __weak void HAL_RCC_CSSCallback(void) 01380 { 01381 /* NOTE : This function Should not be modified, when the callback is needed, 01382 the HAL_RCC_CSSCallback could be implemented in the user file 01383 */ 01384 } 01385 01386 /** 01387 * @} 01388 */ 01389 01390 /** 01391 * @} 01392 */ 01393 01394 #endif /* HAL_RCC_MODULE_ENABLED */ 01395 /** 01396 * @} 01397 */ 01398 01399 /** 01400 * @} 01401 */ 01402 01403 /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/