STM32L443xx HAL User Manual
|
00001 /** 00002 ****************************************************************************** 00003 * @file stm32l4xx_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 Multiple Speed Internal oscillator 00017 (4 MHz) with Flash 0 wait state. Flash prefetch buffer, D-Cache 00018 and I-Cache are disabled, and all peripherals are off except internal 00019 SRAM, Flash and JTAG. 00020 00021 (+) There is no prescaler on High speed (AHBs) and Low speed (APBs) busses: 00022 all peripherals mapped on these busses are running at MSI speed. 00023 (+) The clock for all peripherals is switched off, except the SRAM and FLASH. 00024 (+) All GPIOs are in analog mode, except the JTAG pins which 00025 are assigned to be used for debug purpose. 00026 00027 [..] 00028 Once the device started from reset, the user application has to: 00029 (+) Configure the clock source to be used to drive the System clock 00030 (if the application needs higher frequency/performance) 00031 (+) Configure the System clock frequency and Flash settings 00032 (+) Configure the AHB and APB busses prescalers 00033 (+) Enable the clock for the peripheral(s) to be used 00034 (+) Configure the clock source(s) for peripherals which clocks are not 00035 derived from the System clock (SAIx, RTC, ADC, USB OTG FS/SDMMC1/RNG) 00036 00037 @endverbatim 00038 ****************************************************************************** 00039 * @attention 00040 * 00041 * Copyright (c) 2017 STMicroelectronics. 00042 * All rights reserved. 00043 * 00044 * This software is licensed under terms that can be found in the LICENSE file in 00045 * the root directory of this software component. 00046 * If no LICENSE file comes with this software, it is provided AS-IS. 00047 ****************************************************************************** 00048 */ 00049 00050 /* Includes ------------------------------------------------------------------*/ 00051 #include "stm32l4xx_hal.h" 00052 00053 /** @addtogroup STM32L4xx_HAL_Driver 00054 * @{ 00055 */ 00056 00057 /** @defgroup RCC RCC 00058 * @brief RCC HAL module driver 00059 * @{ 00060 */ 00061 00062 #ifdef HAL_RCC_MODULE_ENABLED 00063 00064 /* Private typedef -----------------------------------------------------------*/ 00065 /* Private define ------------------------------------------------------------*/ 00066 /** @defgroup RCC_Private_Constants RCC Private Constants 00067 * @{ 00068 */ 00069 #define HSE_TIMEOUT_VALUE HSE_STARTUP_TIMEOUT 00070 #define HSI_TIMEOUT_VALUE 2U /* 2 ms (minimum Tick + 1) */ 00071 #define MSI_TIMEOUT_VALUE 2U /* 2 ms (minimum Tick + 1) */ 00072 #if defined(RCC_CSR_LSIPREDIV) 00073 #define LSI_TIMEOUT_VALUE 17U /* 17 ms (16 ms starting time + 1) */ 00074 #else 00075 #define LSI_TIMEOUT_VALUE 2U /* 2 ms (minimum Tick + 1) */ 00076 #endif /* RCC_CSR_LSIPREDIV */ 00077 #define HSI48_TIMEOUT_VALUE 2U /* 2 ms (minimum Tick + 1) */ 00078 #define PLL_TIMEOUT_VALUE 2U /* 2 ms (minimum Tick + 1) */ 00079 #define CLOCKSWITCH_TIMEOUT_VALUE 5000U /* 5 s */ 00080 /** 00081 * @} 00082 */ 00083 00084 /* Private macro -------------------------------------------------------------*/ 00085 /** @defgroup RCC_Private_Macros RCC Private Macros 00086 * @{ 00087 */ 00088 #define __MCO1_CLK_ENABLE() __HAL_RCC_GPIOA_CLK_ENABLE() 00089 #define MCO1_GPIO_PORT GPIOA 00090 #define MCO1_PIN GPIO_PIN_8 00091 00092 #define RCC_PLL_OSCSOURCE_CONFIG(__HAL_RCC_PLLSOURCE__) \ 00093 (MODIFY_REG(RCC->PLLCFGR, RCC_PLLCFGR_PLLSRC, (__HAL_RCC_PLLSOURCE__))) 00094 /** 00095 * @} 00096 */ 00097 00098 /* Private variables ---------------------------------------------------------*/ 00099 00100 /* Private function prototypes -----------------------------------------------*/ 00101 /** @defgroup RCC_Private_Functions RCC Private Functions 00102 * @{ 00103 */ 00104 static HAL_StatusTypeDef RCC_SetFlashLatencyFromMSIRange(uint32_t msirange); 00105 #if defined(STM32L4P5xx) || defined(STM32L4Q5xx) || \ 00106 defined(STM32L4R5xx) || defined(STM32L4R7xx) || defined(STM32L4R9xx) || defined(STM32L4S5xx) || defined(STM32L4S7xx) || defined(STM32L4S9xx) 00107 static uint32_t RCC_GetSysClockFreqFromPLLSource(void); 00108 #endif 00109 /** 00110 * @} 00111 */ 00112 00113 /* Exported functions --------------------------------------------------------*/ 00114 00115 /** @defgroup RCC_Exported_Functions RCC Exported Functions 00116 * @{ 00117 */ 00118 00119 /** @defgroup RCC_Exported_Functions_Group1 Initialization and de-initialization functions 00120 * @brief Initialization and Configuration functions 00121 * 00122 @verbatim 00123 =============================================================================== 00124 ##### Initialization and de-initialization functions ##### 00125 =============================================================================== 00126 [..] 00127 This section provides functions allowing to configure the internal and external oscillators 00128 (HSE, HSI, LSE, MSI, LSI, PLL, CSS and MCO) and the System busses clocks (SYSCLK, AHB, APB1 00129 and APB2). 00130 00131 [..] Internal/external clock and PLL configuration 00132 (+) HSI (high-speed internal): 16 MHz factory-trimmed RC used directly or through 00133 the PLL as System clock source. 00134 00135 (+) MSI (Mutiple Speed Internal): Its frequency is software trimmable from 100KHZ to 48MHZ. 00136 It can be used to generate the clock for the USB OTG FS (48 MHz). 00137 The number of flash wait states is automatically adjusted when MSI range is updated with 00138 HAL_RCC_OscConfig() and the MSI is used as System clock source. 00139 00140 (+) LSI (low-speed internal): 32 KHz low consumption RC used as IWDG and/or RTC 00141 clock source. 00142 00143 (+) HSE (high-speed external): 4 to 48 MHz crystal oscillator used directly or 00144 through the PLL as System clock source. Can be used also optionally as RTC clock source. 00145 00146 (+) LSE (low-speed external): 32.768 KHz oscillator used optionally as RTC clock source. 00147 00148 (+) PLL (clocked by HSI, HSE or MSI) providing up to three independent output clocks: 00149 (++) The first output is used to generate the high speed system clock (up to 80MHz). 00150 (++) The second output is used to generate the clock for the USB OTG FS (48 MHz), 00151 the random analog generator (<=48 MHz) and the SDMMC1 (<= 48 MHz). 00152 (++) The third output is used to generate an accurate clock to achieve 00153 high-quality audio performance on SAI interface. 00154 00155 (+) PLLSAI1 (clocked by HSI, HSE or MSI) providing up to three independent output clocks: 00156 (++) The first output is used to generate SAR ADC1 clock. 00157 (++) The second output is used to generate the clock for the USB OTG FS (48 MHz), 00158 the random analog generator (<=48 MHz) and the SDMMC1 (<= 48 MHz). 00159 (++) The third output is used to generate an accurate clock to achieve 00160 high-quality audio performance on SAI interface. 00161 00162 (+) PLLSAI2 (clocked by HSI, HSE or MSI) providing up to three independent output clocks: 00163 (++) The first output is used to generate an accurate clock to achieve 00164 high-quality audio performance on SAI interface. 00165 (++) The second output is used to generate either SAR ADC2 clock if ADC2 is present 00166 or LCD clock if LTDC is present. 00167 (++) The third output is used to generate DSI clock if DSI is present. 00168 00169 (+) CSS (Clock security system): once enabled, if a HSE clock failure occurs 00170 (HSE used directly or through PLL as System clock source), the System clock 00171 is automatically switched to HSI and an interrupt is generated if enabled. 00172 The interrupt is linked to the Cortex-M4 NMI (Non-Maskable Interrupt) 00173 exception vector. 00174 00175 (+) MCO (microcontroller clock output): used to output MSI, LSI, HSI, LSE, HSE or 00176 main PLL clock (through a configurable prescaler) on PA8 pin. 00177 00178 [..] System, AHB and APB busses clocks configuration 00179 (+) Several clock sources can be used to drive the System clock (SYSCLK): MSI, HSI, 00180 HSE and main PLL. 00181 The AHB clock (HCLK) is derived from System clock through configurable 00182 prescaler and used to clock the CPU, memory and peripherals mapped 00183 on AHB bus (DMA, GPIO...). APB1 (PCLK1) and APB2 (PCLK2) clocks are derived 00184 from AHB clock through configurable prescalers and used to clock 00185 the peripherals mapped on these busses. You can use 00186 "HAL_RCC_GetSysClockFreq()" function to retrieve the frequencies of these clocks. 00187 00188 -@- All the peripheral clocks are derived from the System clock (SYSCLK) except: 00189 00190 (+@) SAI: the SAI clock can be derived either from a specific PLL (PLLSAI1) or (PLLSAI2) or 00191 from an external clock mapped on the SAI_CKIN pin. 00192 You have to use HAL_RCCEx_PeriphCLKConfig() function to configure this clock. 00193 (+@) RTC: the RTC clock can be derived either from the LSI, LSE or HSE clock 00194 divided by 2 to 31. 00195 You have to use __HAL_RCC_RTC_ENABLE() and HAL_RCCEx_PeriphCLKConfig() function 00196 to configure this clock. 00197 (+@) USB OTG FS, SDMMC1 and RNG: USB OTG FS requires a frequency equal to 48 MHz 00198 to work correctly, while the SDMMC1 and RNG peripherals require a frequency 00199 equal or lower than to 48 MHz. This clock is derived of the main PLL or PLLSAI1 00200 through PLLQ divider. You have to enable the peripheral clock and use 00201 HAL_RCCEx_PeriphCLKConfig() function to configure this clock. 00202 (+@) IWDG clock which is always the LSI clock. 00203 00204 00205 (+) The maximum frequency of the SYSCLK, HCLK, PCLK1 and PCLK2 is 80 MHz. 00206 The clock source frequency should be adapted depending on the device voltage range 00207 as listed in the Reference Manual "Clock source frequency versus voltage scaling" chapter. 00208 00209 @endverbatim 00210 00211 Table 1. HCLK clock frequency for other STM32L4 devices 00212 +-------------------------------------------------------+ 00213 | Latency | HCLK clock frequency (MHz) | 00214 | |-------------------------------------| 00215 | | voltage range 1 | voltage range 2 | 00216 | | 1.2 V | 1.0 V | 00217 |-----------------|------------------|------------------| 00218 |0WS(1 CPU cycles)| 0 < HCLK <= 16 | 0 < HCLK <= 6 | 00219 |-----------------|------------------|------------------| 00220 |1WS(2 CPU cycles)| 16 < HCLK <= 32 | 6 < HCLK <= 12 | 00221 |-----------------|------------------|------------------| 00222 |2WS(3 CPU cycles)| 32 < HCLK <= 48 | 12 < HCLK <= 18 | 00223 |-----------------|------------------|------------------| 00224 |3WS(4 CPU cycles)| 48 < HCLK <= 64 | 18 < HCLK <= 26 | 00225 |-----------------|------------------|------------------| 00226 |4WS(5 CPU cycles)| 64 < HCLK <= 80 | 18 < HCLK <= 26 | 00227 +-------------------------------------------------------+ 00228 00229 Table 2. HCLK clock frequency for STM32L4+ devices 00230 +--------------------------------------------------------+ 00231 | Latency | HCLK clock frequency (MHz) | 00232 | |--------------------------------------| 00233 | | voltage range 1 | voltage range 2 | 00234 | | 1.2 V | 1.0 V | 00235 |-----------------|-------------------|------------------| 00236 |0WS(1 CPU cycles)| 0 < HCLK <= 20 | 0 < HCLK <= 8 | 00237 |-----------------|-------------------|------------------| 00238 |1WS(2 CPU cycles)| 20 < HCLK <= 40 | 8 < HCLK <= 16 | 00239 |-----------------|-------------------|------------------| 00240 |2WS(3 CPU cycles)| 40 < HCLK <= 60 | 16 < HCLK <= 26 | 00241 |-----------------|-------------------|------------------| 00242 |3WS(4 CPU cycles)| 60 < HCLK <= 80 | 16 < HCLK <= 26 | 00243 |-----------------|-------------------|------------------| 00244 |4WS(5 CPU cycles)| 80 < HCLK <= 100 | 16 < HCLK <= 26 | 00245 |-----------------|-------------------|------------------| 00246 |5WS(6 CPU cycles)| 100 < HCLK <= 120 | 16 < HCLK <= 26 | 00247 +--------------------------------------------------------+ 00248 * @{ 00249 */ 00250 00251 /** 00252 * @brief Reset the RCC clock configuration to the default reset state. 00253 * @note The default reset state of the clock configuration is given below: 00254 * - MSI ON and used as system clock source 00255 * - HSE, HSI, PLL, PLLSAI1 and PLLSAI2 OFF 00256 * - AHB, APB1 and APB2 prescalers set to 1. 00257 * - CSS, MCO1 OFF 00258 * - All interrupts disabled 00259 * - All interrupt and reset flags cleared 00260 * @note This function does not modify the configuration of the 00261 * - Peripheral clock sources 00262 * - LSI, LSE and RTC clocks (Backup domain) 00263 * @retval HAL status 00264 */ 00265 HAL_StatusTypeDef HAL_RCC_DeInit(void) 00266 { 00267 uint32_t tickstart; 00268 00269 /* Reset to default System clock */ 00270 /* Set MSION bit */ 00271 SET_BIT(RCC->CR, RCC_CR_MSION); 00272 00273 /* Insure MSIRDY bit is set before writing default MSIRANGE value */ 00274 /* Get start tick */ 00275 tickstart = HAL_GetTick(); 00276 00277 /* Wait till MSI is ready */ 00278 while(READ_BIT(RCC->CR, RCC_CR_MSIRDY) == 0U) 00279 { 00280 if((HAL_GetTick() - tickstart) > MSI_TIMEOUT_VALUE) 00281 { 00282 return HAL_TIMEOUT; 00283 } 00284 } 00285 00286 /* Set MSIRANGE default value */ 00287 MODIFY_REG(RCC->CR, RCC_CR_MSIRANGE, RCC_MSIRANGE_6); 00288 00289 /* Reset CFGR register (MSI is selected as system clock source) */ 00290 CLEAR_REG(RCC->CFGR); 00291 00292 /* Update the SystemCoreClock global variable for MSI as system clock source */ 00293 SystemCoreClock = MSI_VALUE; 00294 00295 /* Configure the source of time base considering new system clock settings */ 00296 if(HAL_InitTick(uwTickPrio) != HAL_OK) 00297 { 00298 return HAL_ERROR; 00299 } 00300 00301 /* Insure MSI selected as system clock source */ 00302 /* Get start tick */ 00303 tickstart = HAL_GetTick(); 00304 00305 /* Wait till system clock source is ready */ 00306 while(READ_BIT(RCC->CFGR, RCC_CFGR_SWS) != RCC_CFGR_SWS_MSI) 00307 { 00308 if((HAL_GetTick() - tickstart) > CLOCKSWITCH_TIMEOUT_VALUE) 00309 { 00310 return HAL_TIMEOUT; 00311 } 00312 } 00313 00314 /* Reset HSION, HSIKERON, HSIASFS, HSEON, HSECSSON, PLLON, PLLSAIxON bits */ 00315 #if defined(RCC_PLLSAI2_SUPPORT) 00316 00317 CLEAR_BIT(RCC->CR, RCC_CR_HSEON | RCC_CR_HSION | RCC_CR_HSIKERON| RCC_CR_HSIASFS | RCC_CR_PLLON | RCC_CR_PLLSAI1ON | RCC_CR_PLLSAI2ON); 00318 00319 #elif defined(RCC_PLLSAI1_SUPPORT) 00320 00321 CLEAR_BIT(RCC->CR, RCC_CR_HSEON | RCC_CR_HSION | RCC_CR_HSIKERON| RCC_CR_HSIASFS | RCC_CR_PLLON | RCC_CR_PLLSAI1ON); 00322 00323 #else 00324 00325 CLEAR_BIT(RCC->CR, RCC_CR_HSEON | RCC_CR_HSION | RCC_CR_HSIKERON| RCC_CR_HSIASFS | RCC_CR_PLLON); 00326 00327 #endif /* RCC_PLLSAI2_SUPPORT */ 00328 00329 /* Insure PLLRDY, PLLSAI1RDY and PLLSAI2RDY (if present) are reset */ 00330 /* Get start tick */ 00331 tickstart = HAL_GetTick(); 00332 00333 #if defined(RCC_PLLSAI2_SUPPORT) 00334 00335 while(READ_BIT(RCC->CR, RCC_CR_PLLRDY | RCC_CR_PLLSAI1RDY | RCC_CR_PLLSAI2RDY) != 0U) 00336 00337 #elif defined(RCC_PLLSAI1_SUPPORT) 00338 00339 while(READ_BIT(RCC->CR, RCC_CR_PLLRDY | RCC_CR_PLLSAI1RDY) != 0U) 00340 00341 #else 00342 00343 while(READ_BIT(RCC->CR, RCC_CR_PLLRDY) != 0U) 00344 00345 #endif 00346 { 00347 if((HAL_GetTick() - tickstart) > PLL_TIMEOUT_VALUE) 00348 { 00349 return HAL_TIMEOUT; 00350 } 00351 } 00352 00353 /* Reset PLLCFGR register */ 00354 CLEAR_REG(RCC->PLLCFGR); 00355 SET_BIT(RCC->PLLCFGR, RCC_PLLCFGR_PLLN_4 ); 00356 00357 #if defined(RCC_PLLSAI1_SUPPORT) 00358 00359 /* Reset PLLSAI1CFGR register */ 00360 CLEAR_REG(RCC->PLLSAI1CFGR); 00361 SET_BIT(RCC->PLLSAI1CFGR, RCC_PLLSAI1CFGR_PLLSAI1N_4 ); 00362 00363 #endif /* RCC_PLLSAI1_SUPPORT */ 00364 00365 #if defined(RCC_PLLSAI2_SUPPORT) 00366 00367 /* Reset PLLSAI2CFGR register */ 00368 CLEAR_REG(RCC->PLLSAI2CFGR); 00369 SET_BIT(RCC->PLLSAI2CFGR, RCC_PLLSAI2CFGR_PLLSAI2N_4 ); 00370 00371 #endif /* RCC_PLLSAI2_SUPPORT */ 00372 00373 /* Reset HSEBYP bit */ 00374 CLEAR_BIT(RCC->CR, RCC_CR_HSEBYP); 00375 00376 /* Disable all interrupts */ 00377 CLEAR_REG(RCC->CIER); 00378 00379 /* Clear all interrupt flags */ 00380 WRITE_REG(RCC->CICR, 0xFFFFFFFFU); 00381 00382 /* Clear all reset flags */ 00383 SET_BIT(RCC->CSR, RCC_CSR_RMVF); 00384 00385 return HAL_OK; 00386 } 00387 00388 /** 00389 * @brief Initialize the RCC Oscillators according to the specified parameters in the 00390 * RCC_OscInitTypeDef. 00391 * @param RCC_OscInitStruct pointer to an RCC_OscInitTypeDef structure that 00392 * contains the configuration information for the RCC Oscillators. 00393 * @note The PLL is not disabled when used as system clock. 00394 * @note The PLL source is not updated when used as PLLSAI(s) clock source. 00395 * @note Transitions LSE Bypass to LSE On and LSE On to LSE Bypass are not 00396 * supported by this macro. User should request a transition to LSE Off 00397 * first and then LSE On or LSE Bypass. 00398 * @note Transition HSE Bypass to HSE On and HSE On to HSE Bypass are not 00399 * supported by this macro. User should request a transition to HSE Off 00400 * first and then HSE On or HSE Bypass. 00401 * @retval HAL status 00402 */ 00403 HAL_StatusTypeDef HAL_RCC_OscConfig(RCC_OscInitTypeDef *RCC_OscInitStruct) 00404 { 00405 uint32_t tickstart; 00406 HAL_StatusTypeDef status; 00407 uint32_t sysclk_source, pll_config; 00408 00409 /* Check Null pointer */ 00410 if(RCC_OscInitStruct == NULL) 00411 { 00412 return HAL_ERROR; 00413 } 00414 00415 /* Check the parameters */ 00416 assert_param(IS_RCC_OSCILLATORTYPE(RCC_OscInitStruct->OscillatorType)); 00417 00418 sysclk_source = __HAL_RCC_GET_SYSCLK_SOURCE(); 00419 pll_config = __HAL_RCC_GET_PLL_OSCSOURCE(); 00420 00421 /*----------------------------- MSI Configuration --------------------------*/ 00422 if(((RCC_OscInitStruct->OscillatorType) & RCC_OSCILLATORTYPE_MSI) == RCC_OSCILLATORTYPE_MSI) 00423 { 00424 /* Check the parameters */ 00425 assert_param(IS_RCC_MSI(RCC_OscInitStruct->MSIState)); 00426 assert_param(IS_RCC_MSICALIBRATION_VALUE(RCC_OscInitStruct->MSICalibrationValue)); 00427 assert_param(IS_RCC_MSI_CLOCK_RANGE(RCC_OscInitStruct->MSIClockRange)); 00428 00429 /* Check if MSI is used as system clock or as PLL source when PLL is selected as system clock */ 00430 if((sysclk_source == RCC_CFGR_SWS_MSI) || 00431 ((sysclk_source == RCC_CFGR_SWS_PLL) && (pll_config == RCC_PLLSOURCE_MSI))) 00432 { 00433 if((READ_BIT(RCC->CR, RCC_CR_MSIRDY) != 0U) && (RCC_OscInitStruct->MSIState == RCC_MSI_OFF)) 00434 { 00435 return HAL_ERROR; 00436 } 00437 00438 /* Otherwise, just the calibration and MSI range change are allowed */ 00439 else 00440 { 00441 /* To correctly read data from FLASH memory, the number of wait states (LATENCY) 00442 must be correctly programmed according to the frequency of the CPU clock 00443 (HCLK) and the supply voltage of the device. */ 00444 if(RCC_OscInitStruct->MSIClockRange > __HAL_RCC_GET_MSI_RANGE()) 00445 { 00446 /* First increase number of wait states update if necessary */ 00447 if(RCC_SetFlashLatencyFromMSIRange(RCC_OscInitStruct->MSIClockRange) != HAL_OK) 00448 { 00449 return HAL_ERROR; 00450 } 00451 00452 /* Selects the Multiple Speed oscillator (MSI) clock range .*/ 00453 __HAL_RCC_MSI_RANGE_CONFIG(RCC_OscInitStruct->MSIClockRange); 00454 /* Adjusts the Multiple Speed oscillator (MSI) calibration value.*/ 00455 __HAL_RCC_MSI_CALIBRATIONVALUE_ADJUST(RCC_OscInitStruct->MSICalibrationValue); 00456 } 00457 else 00458 { 00459 /* Else, keep current flash latency while decreasing applies */ 00460 /* Selects the Multiple Speed oscillator (MSI) clock range .*/ 00461 __HAL_RCC_MSI_RANGE_CONFIG(RCC_OscInitStruct->MSIClockRange); 00462 /* Adjusts the Multiple Speed oscillator (MSI) calibration value.*/ 00463 __HAL_RCC_MSI_CALIBRATIONVALUE_ADJUST(RCC_OscInitStruct->MSICalibrationValue); 00464 00465 /* Decrease number of wait states update if necessary */ 00466 /* Only possible when MSI is the System clock source */ 00467 if(sysclk_source == RCC_CFGR_SWS_MSI) 00468 { 00469 if(RCC_SetFlashLatencyFromMSIRange(RCC_OscInitStruct->MSIClockRange) != HAL_OK) 00470 { 00471 return HAL_ERROR; 00472 } 00473 } 00474 } 00475 00476 /* Update the SystemCoreClock global variable */ 00477 SystemCoreClock = HAL_RCC_GetSysClockFreq() >> (AHBPrescTable[READ_BIT(RCC->CFGR, RCC_CFGR_HPRE) >> RCC_CFGR_HPRE_Pos] & 0x1FU); 00478 00479 /* Configure the source of time base considering new system clocks settings*/ 00480 status = HAL_InitTick(uwTickPrio); 00481 if(status != HAL_OK) 00482 { 00483 return status; 00484 } 00485 } 00486 } 00487 else 00488 { 00489 /* Check the MSI State */ 00490 if(RCC_OscInitStruct->MSIState != RCC_MSI_OFF) 00491 { 00492 /* Enable the Internal High Speed oscillator (MSI). */ 00493 __HAL_RCC_MSI_ENABLE(); 00494 00495 /* Get timeout */ 00496 tickstart = HAL_GetTick(); 00497 00498 /* Wait till MSI is ready */ 00499 while(READ_BIT(RCC->CR, RCC_CR_MSIRDY) == 0U) 00500 { 00501 if((HAL_GetTick() - tickstart) > MSI_TIMEOUT_VALUE) 00502 { 00503 return HAL_TIMEOUT; 00504 } 00505 } 00506 /* Selects the Multiple Speed oscillator (MSI) clock range .*/ 00507 __HAL_RCC_MSI_RANGE_CONFIG(RCC_OscInitStruct->MSIClockRange); 00508 /* Adjusts the Multiple Speed oscillator (MSI) calibration value.*/ 00509 __HAL_RCC_MSI_CALIBRATIONVALUE_ADJUST(RCC_OscInitStruct->MSICalibrationValue); 00510 00511 } 00512 else 00513 { 00514 /* Disable the Internal High Speed oscillator (MSI). */ 00515 __HAL_RCC_MSI_DISABLE(); 00516 00517 /* Get timeout */ 00518 tickstart = HAL_GetTick(); 00519 00520 /* Wait till MSI is ready */ 00521 while(READ_BIT(RCC->CR, RCC_CR_MSIRDY) != 0U) 00522 { 00523 if((HAL_GetTick() - tickstart) > MSI_TIMEOUT_VALUE) 00524 { 00525 return HAL_TIMEOUT; 00526 } 00527 } 00528 } 00529 } 00530 } 00531 /*------------------------------- HSE Configuration ------------------------*/ 00532 if(((RCC_OscInitStruct->OscillatorType) & RCC_OSCILLATORTYPE_HSE) == RCC_OSCILLATORTYPE_HSE) 00533 { 00534 /* Check the parameters */ 00535 assert_param(IS_RCC_HSE(RCC_OscInitStruct->HSEState)); 00536 00537 /* When the HSE is used as system clock or clock source for PLL in these cases it is not allowed to be disabled */ 00538 if((sysclk_source == RCC_CFGR_SWS_HSE) || 00539 ((sysclk_source == RCC_CFGR_SWS_PLL) && (pll_config == RCC_PLLSOURCE_HSE))) 00540 { 00541 if((READ_BIT(RCC->CR, RCC_CR_HSERDY) != 0U) && (RCC_OscInitStruct->HSEState == RCC_HSE_OFF)) 00542 { 00543 return HAL_ERROR; 00544 } 00545 } 00546 else 00547 { 00548 /* Set the new HSE configuration ---------------------------------------*/ 00549 __HAL_RCC_HSE_CONFIG(RCC_OscInitStruct->HSEState); 00550 00551 /* Check the HSE State */ 00552 if(RCC_OscInitStruct->HSEState != RCC_HSE_OFF) 00553 { 00554 /* Get Start Tick*/ 00555 tickstart = HAL_GetTick(); 00556 00557 /* Wait till HSE is ready */ 00558 while(READ_BIT(RCC->CR, RCC_CR_HSERDY) == 0U) 00559 { 00560 if((HAL_GetTick() - tickstart) > HSE_TIMEOUT_VALUE) 00561 { 00562 return HAL_TIMEOUT; 00563 } 00564 } 00565 } 00566 else 00567 { 00568 /* Get Start Tick*/ 00569 tickstart = HAL_GetTick(); 00570 00571 /* Wait till HSE is disabled */ 00572 while(READ_BIT(RCC->CR, RCC_CR_HSERDY) != 0U) 00573 { 00574 if((HAL_GetTick() - tickstart) > HSE_TIMEOUT_VALUE) 00575 { 00576 return HAL_TIMEOUT; 00577 } 00578 } 00579 } 00580 } 00581 } 00582 /*----------------------------- HSI Configuration --------------------------*/ 00583 if(((RCC_OscInitStruct->OscillatorType) & RCC_OSCILLATORTYPE_HSI) == RCC_OSCILLATORTYPE_HSI) 00584 { 00585 /* Check the parameters */ 00586 assert_param(IS_RCC_HSI(RCC_OscInitStruct->HSIState)); 00587 assert_param(IS_RCC_HSI_CALIBRATION_VALUE(RCC_OscInitStruct->HSICalibrationValue)); 00588 00589 /* Check if HSI is used as system clock or as PLL source when PLL is selected as system clock */ 00590 if((sysclk_source == RCC_CFGR_SWS_HSI) || 00591 ((sysclk_source == RCC_CFGR_SWS_PLL) && (pll_config == RCC_PLLSOURCE_HSI))) 00592 { 00593 /* When HSI is used as system clock it will not be disabled */ 00594 if((READ_BIT(RCC->CR, RCC_CR_HSIRDY) != 0U) && (RCC_OscInitStruct->HSIState == RCC_HSI_OFF)) 00595 { 00596 return HAL_ERROR; 00597 } 00598 /* Otherwise, just the calibration is allowed */ 00599 else 00600 { 00601 /* Adjusts the Internal High Speed oscillator (HSI) calibration value.*/ 00602 __HAL_RCC_HSI_CALIBRATIONVALUE_ADJUST(RCC_OscInitStruct->HSICalibrationValue); 00603 } 00604 } 00605 else 00606 { 00607 /* Check the HSI State */ 00608 if(RCC_OscInitStruct->HSIState != RCC_HSI_OFF) 00609 { 00610 /* Enable the Internal High Speed oscillator (HSI). */ 00611 __HAL_RCC_HSI_ENABLE(); 00612 00613 /* Get Start Tick*/ 00614 tickstart = HAL_GetTick(); 00615 00616 /* Wait till HSI is ready */ 00617 while(READ_BIT(RCC->CR, RCC_CR_HSIRDY) == 0U) 00618 { 00619 if((HAL_GetTick() - tickstart) > HSI_TIMEOUT_VALUE) 00620 { 00621 return HAL_TIMEOUT; 00622 } 00623 } 00624 00625 /* Adjusts the Internal High Speed oscillator (HSI) calibration value.*/ 00626 __HAL_RCC_HSI_CALIBRATIONVALUE_ADJUST(RCC_OscInitStruct->HSICalibrationValue); 00627 } 00628 else 00629 { 00630 /* Disable the Internal High Speed oscillator (HSI). */ 00631 __HAL_RCC_HSI_DISABLE(); 00632 00633 /* Get Start Tick*/ 00634 tickstart = HAL_GetTick(); 00635 00636 /* Wait till HSI is disabled */ 00637 while(READ_BIT(RCC->CR, RCC_CR_HSIRDY) != 0U) 00638 { 00639 if((HAL_GetTick() - tickstart) > HSI_TIMEOUT_VALUE) 00640 { 00641 return HAL_TIMEOUT; 00642 } 00643 } 00644 } 00645 } 00646 } 00647 /*------------------------------ LSI Configuration -------------------------*/ 00648 if(((RCC_OscInitStruct->OscillatorType) & RCC_OSCILLATORTYPE_LSI) == RCC_OSCILLATORTYPE_LSI) 00649 { 00650 /* Check the parameters */ 00651 assert_param(IS_RCC_LSI(RCC_OscInitStruct->LSIState)); 00652 00653 /* Check the LSI State */ 00654 if(RCC_OscInitStruct->LSIState != RCC_LSI_OFF) 00655 { 00656 #if defined(RCC_CSR_LSIPREDIV) 00657 uint32_t csr_temp = RCC->CSR; 00658 00659 /* Check LSI division factor */ 00660 assert_param(IS_RCC_LSIDIV(RCC_OscInitStruct->LSIDiv)); 00661 00662 if (RCC_OscInitStruct->LSIDiv != (csr_temp & RCC_CSR_LSIPREDIV)) 00663 { 00664 if (((csr_temp & RCC_CSR_LSIRDY) == RCC_CSR_LSIRDY) && \ 00665 ((csr_temp & RCC_CSR_LSION) != RCC_CSR_LSION)) 00666 { 00667 /* If LSIRDY is set while LSION is not enabled, 00668 LSIPREDIV can't be updated */ 00669 return HAL_ERROR; 00670 } 00671 00672 /* Turn off LSI before changing RCC_CSR_LSIPREDIV */ 00673 if ((csr_temp & RCC_CSR_LSION) == RCC_CSR_LSION) 00674 { 00675 __HAL_RCC_LSI_DISABLE(); 00676 00677 /* Get Start Tick*/ 00678 tickstart = HAL_GetTick(); 00679 00680 /* Wait till LSI is disabled */ 00681 while(READ_BIT(RCC->CSR, RCC_CSR_LSIRDY) != 0U) 00682 { 00683 if((HAL_GetTick() - tickstart) > LSI_TIMEOUT_VALUE) 00684 { 00685 return HAL_TIMEOUT; 00686 } 00687 } 00688 } 00689 00690 /* Set LSI division factor */ 00691 MODIFY_REG(RCC->CSR, RCC_CSR_LSIPREDIV, RCC_OscInitStruct->LSIDiv); 00692 } 00693 #endif /* RCC_CSR_LSIPREDIV */ 00694 00695 /* Enable the Internal Low Speed oscillator (LSI). */ 00696 __HAL_RCC_LSI_ENABLE(); 00697 00698 /* Get Start Tick*/ 00699 tickstart = HAL_GetTick(); 00700 00701 /* Wait till LSI is ready */ 00702 while(READ_BIT(RCC->CSR, RCC_CSR_LSIRDY) == 0U) 00703 { 00704 if((HAL_GetTick() - tickstart) > LSI_TIMEOUT_VALUE) 00705 { 00706 return HAL_TIMEOUT; 00707 } 00708 } 00709 } 00710 else 00711 { 00712 /* Disable the Internal Low Speed oscillator (LSI). */ 00713 __HAL_RCC_LSI_DISABLE(); 00714 00715 /* Get Start Tick*/ 00716 tickstart = HAL_GetTick(); 00717 00718 /* Wait till LSI is disabled */ 00719 while(READ_BIT(RCC->CSR, RCC_CSR_LSIRDY) != 0U) 00720 { 00721 if((HAL_GetTick() - tickstart) > LSI_TIMEOUT_VALUE) 00722 { 00723 return HAL_TIMEOUT; 00724 } 00725 } 00726 } 00727 } 00728 /*------------------------------ LSE Configuration -------------------------*/ 00729 if(((RCC_OscInitStruct->OscillatorType) & RCC_OSCILLATORTYPE_LSE) == RCC_OSCILLATORTYPE_LSE) 00730 { 00731 FlagStatus pwrclkchanged = RESET; 00732 00733 /* Check the parameters */ 00734 assert_param(IS_RCC_LSE(RCC_OscInitStruct->LSEState)); 00735 00736 /* Update LSE configuration in Backup Domain control register */ 00737 /* Requires to enable write access to Backup Domain of necessary */ 00738 if(HAL_IS_BIT_CLR(RCC->APB1ENR1, RCC_APB1ENR1_PWREN)) 00739 { 00740 __HAL_RCC_PWR_CLK_ENABLE(); 00741 pwrclkchanged = SET; 00742 } 00743 00744 if(HAL_IS_BIT_CLR(PWR->CR1, PWR_CR1_DBP)) 00745 { 00746 /* Enable write access to Backup domain */ 00747 SET_BIT(PWR->CR1, PWR_CR1_DBP); 00748 00749 /* Wait for Backup domain Write protection disable */ 00750 tickstart = HAL_GetTick(); 00751 00752 while(HAL_IS_BIT_CLR(PWR->CR1, PWR_CR1_DBP)) 00753 { 00754 if((HAL_GetTick() - tickstart) > RCC_DBP_TIMEOUT_VALUE) 00755 { 00756 return HAL_TIMEOUT; 00757 } 00758 } 00759 } 00760 00761 /* Set the new LSE configuration -----------------------------------------*/ 00762 #if defined(RCC_BDCR_LSESYSDIS) 00763 if((RCC_OscInitStruct->LSEState & RCC_BDCR_LSEON) != 0U) 00764 { 00765 /* Set LSESYSDIS bit according to LSE propagation option (enabled or disabled) */ 00766 MODIFY_REG(RCC->BDCR, RCC_BDCR_LSESYSDIS, (RCC_OscInitStruct->LSEState & RCC_BDCR_LSESYSDIS)); 00767 00768 if((RCC_OscInitStruct->LSEState & RCC_BDCR_LSEBYP) != 0U) 00769 { 00770 /* LSE oscillator bypass enable */ 00771 SET_BIT(RCC->BDCR, RCC_BDCR_LSEBYP); 00772 SET_BIT(RCC->BDCR, RCC_BDCR_LSEON); 00773 } 00774 else 00775 { 00776 /* LSE oscillator enable */ 00777 SET_BIT(RCC->BDCR, RCC_BDCR_LSEON); 00778 } 00779 } 00780 else 00781 { 00782 CLEAR_BIT(RCC->BDCR, RCC_BDCR_LSEON); 00783 CLEAR_BIT(RCC->BDCR, RCC_BDCR_LSEBYP); 00784 } 00785 #else 00786 __HAL_RCC_LSE_CONFIG(RCC_OscInitStruct->LSEState); 00787 #endif /* RCC_BDCR_LSESYSDIS */ 00788 00789 /* Check the LSE State */ 00790 if(RCC_OscInitStruct->LSEState != RCC_LSE_OFF) 00791 { 00792 /* Get Start Tick*/ 00793 tickstart = HAL_GetTick(); 00794 00795 /* Wait till LSE is ready */ 00796 while(READ_BIT(RCC->BDCR, RCC_BDCR_LSERDY) == 0U) 00797 { 00798 if((HAL_GetTick() - tickstart) > RCC_LSE_TIMEOUT_VALUE) 00799 { 00800 return HAL_TIMEOUT; 00801 } 00802 } 00803 } 00804 else 00805 { 00806 /* Get Start Tick*/ 00807 tickstart = HAL_GetTick(); 00808 00809 /* Wait till LSE is disabled */ 00810 while(READ_BIT(RCC->BDCR, RCC_BDCR_LSERDY) != 0U) 00811 { 00812 if((HAL_GetTick() - tickstart) > RCC_LSE_TIMEOUT_VALUE) 00813 { 00814 return HAL_TIMEOUT; 00815 } 00816 } 00817 00818 #if defined(RCC_BDCR_LSESYSDIS) 00819 /* By default, stop disabling LSE propagation */ 00820 CLEAR_BIT(RCC->BDCR, RCC_BDCR_LSESYSDIS); 00821 #endif /* RCC_BDCR_LSESYSDIS */ 00822 } 00823 00824 /* Restore clock configuration if changed */ 00825 if(pwrclkchanged == SET) 00826 { 00827 __HAL_RCC_PWR_CLK_DISABLE(); 00828 } 00829 } 00830 #if defined(RCC_HSI48_SUPPORT) 00831 /*------------------------------ HSI48 Configuration -----------------------*/ 00832 if(((RCC_OscInitStruct->OscillatorType) & RCC_OSCILLATORTYPE_HSI48) == RCC_OSCILLATORTYPE_HSI48) 00833 { 00834 /* Check the parameters */ 00835 assert_param(IS_RCC_HSI48(RCC_OscInitStruct->HSI48State)); 00836 00837 /* Check the LSI State */ 00838 if(RCC_OscInitStruct->HSI48State != RCC_HSI48_OFF) 00839 { 00840 /* Enable the Internal Low Speed oscillator (HSI48). */ 00841 __HAL_RCC_HSI48_ENABLE(); 00842 00843 /* Get Start Tick*/ 00844 tickstart = HAL_GetTick(); 00845 00846 /* Wait till HSI48 is ready */ 00847 while(READ_BIT(RCC->CRRCR, RCC_CRRCR_HSI48RDY) == 0U) 00848 { 00849 if((HAL_GetTick() - tickstart) > HSI48_TIMEOUT_VALUE) 00850 { 00851 return HAL_TIMEOUT; 00852 } 00853 } 00854 } 00855 else 00856 { 00857 /* Disable the Internal Low Speed oscillator (HSI48). */ 00858 __HAL_RCC_HSI48_DISABLE(); 00859 00860 /* Get Start Tick*/ 00861 tickstart = HAL_GetTick(); 00862 00863 /* Wait till HSI48 is disabled */ 00864 while(READ_BIT(RCC->CRRCR, RCC_CRRCR_HSI48RDY) != 0U) 00865 { 00866 if((HAL_GetTick() - tickstart) > HSI48_TIMEOUT_VALUE) 00867 { 00868 return HAL_TIMEOUT; 00869 } 00870 } 00871 } 00872 } 00873 #endif /* RCC_HSI48_SUPPORT */ 00874 /*-------------------------------- PLL Configuration -----------------------*/ 00875 /* Check the parameters */ 00876 assert_param(IS_RCC_PLL(RCC_OscInitStruct->PLL.PLLState)); 00877 00878 if(RCC_OscInitStruct->PLL.PLLState != RCC_PLL_NONE) 00879 { 00880 /* PLL On ? */ 00881 if(RCC_OscInitStruct->PLL.PLLState == RCC_PLL_ON) 00882 { 00883 /* Check the parameters */ 00884 assert_param(IS_RCC_PLLSOURCE(RCC_OscInitStruct->PLL.PLLSource)); 00885 assert_param(IS_RCC_PLLM_VALUE(RCC_OscInitStruct->PLL.PLLM)); 00886 assert_param(IS_RCC_PLLN_VALUE(RCC_OscInitStruct->PLL.PLLN)); 00887 #if defined(RCC_PLLP_SUPPORT) 00888 assert_param(IS_RCC_PLLP_VALUE(RCC_OscInitStruct->PLL.PLLP)); 00889 #endif /* RCC_PLLP_SUPPORT */ 00890 assert_param(IS_RCC_PLLQ_VALUE(RCC_OscInitStruct->PLL.PLLQ)); 00891 assert_param(IS_RCC_PLLR_VALUE(RCC_OscInitStruct->PLL.PLLR)); 00892 00893 /* Do nothing if PLL configuration is the unchanged */ 00894 pll_config = RCC->PLLCFGR; 00895 if((READ_BIT(pll_config, RCC_PLLCFGR_PLLSRC) != RCC_OscInitStruct->PLL.PLLSource) || 00896 (READ_BIT(pll_config, RCC_PLLCFGR_PLLM) != ((RCC_OscInitStruct->PLL.PLLM - 1U) << RCC_PLLCFGR_PLLM_Pos)) || 00897 (READ_BIT(pll_config, RCC_PLLCFGR_PLLN) != (RCC_OscInitStruct->PLL.PLLN << RCC_PLLCFGR_PLLN_Pos)) || 00898 #if defined(RCC_PLLP_SUPPORT) 00899 #if defined(RCC_PLLP_DIV_2_31_SUPPORT) 00900 (READ_BIT(pll_config, RCC_PLLCFGR_PLLPDIV) != (RCC_OscInitStruct->PLL.PLLP << RCC_PLLCFGR_PLLPDIV_Pos)) || 00901 #else 00902 (READ_BIT(pll_config, RCC_PLLCFGR_PLLP) != ((RCC_OscInitStruct->PLL.PLLP == RCC_PLLP_DIV7) ? 0U : 1U)) || 00903 #endif 00904 #endif 00905 (READ_BIT(pll_config, RCC_PLLCFGR_PLLQ) != ((((RCC_OscInitStruct->PLL.PLLQ) >> 1U) - 1U) << RCC_PLLCFGR_PLLQ_Pos)) || 00906 (READ_BIT(pll_config, RCC_PLLCFGR_PLLR) != ((((RCC_OscInitStruct->PLL.PLLR) >> 1U) - 1U) << RCC_PLLCFGR_PLLR_Pos))) 00907 { 00908 /* Check if the PLL is used as system clock or not */ 00909 if(sysclk_source != RCC_CFGR_SWS_PLL) 00910 { 00911 #if defined(RCC_PLLSAI1_SUPPORT) || defined(RCC_PLLSAI2_SUPPORT) 00912 /* Check if main PLL can be updated */ 00913 /* Not possible if the source is shared by other enabled PLLSAIx */ 00914 if((READ_BIT(RCC->CR, RCC_CR_PLLSAI1ON) != 0U) 00915 #if defined(RCC_PLLSAI2_SUPPORT) 00916 || (READ_BIT(RCC->CR, RCC_CR_PLLSAI2ON) != 0U) 00917 #endif 00918 ) 00919 { 00920 return HAL_ERROR; 00921 } 00922 else 00923 #endif /* RCC_PLLSAI1_SUPPORT || RCC_PLLSAI2_SUPPORT */ 00924 { 00925 /* Disable the main PLL. */ 00926 __HAL_RCC_PLL_DISABLE(); 00927 00928 /* Get Start Tick*/ 00929 tickstart = HAL_GetTick(); 00930 00931 /* Wait till PLL is ready */ 00932 while(READ_BIT(RCC->CR, RCC_CR_PLLRDY) != 0U) 00933 { 00934 if((HAL_GetTick() - tickstart) > PLL_TIMEOUT_VALUE) 00935 { 00936 return HAL_TIMEOUT; 00937 } 00938 } 00939 00940 /* Configure the main PLL clock source, multiplication and division factors. */ 00941 #if defined(RCC_PLLP_SUPPORT) 00942 __HAL_RCC_PLL_CONFIG(RCC_OscInitStruct->PLL.PLLSource, 00943 RCC_OscInitStruct->PLL.PLLM, 00944 RCC_OscInitStruct->PLL.PLLN, 00945 RCC_OscInitStruct->PLL.PLLP, 00946 RCC_OscInitStruct->PLL.PLLQ, 00947 RCC_OscInitStruct->PLL.PLLR); 00948 #else 00949 __HAL_RCC_PLL_CONFIG(RCC_OscInitStruct->PLL.PLLSource, 00950 RCC_OscInitStruct->PLL.PLLM, 00951 RCC_OscInitStruct->PLL.PLLN, 00952 RCC_OscInitStruct->PLL.PLLQ, 00953 RCC_OscInitStruct->PLL.PLLR); 00954 #endif 00955 00956 /* Enable the main PLL. */ 00957 __HAL_RCC_PLL_ENABLE(); 00958 00959 /* Enable PLL System Clock output. */ 00960 __HAL_RCC_PLLCLKOUT_ENABLE(RCC_PLL_SYSCLK); 00961 00962 /* Get Start Tick*/ 00963 tickstart = HAL_GetTick(); 00964 00965 /* Wait till PLL is ready */ 00966 while(READ_BIT(RCC->CR, RCC_CR_PLLRDY) == 0U) 00967 { 00968 if((HAL_GetTick() - tickstart) > PLL_TIMEOUT_VALUE) 00969 { 00970 return HAL_TIMEOUT; 00971 } 00972 } 00973 } 00974 } 00975 else 00976 { 00977 /* PLL is already used as System core clock */ 00978 return HAL_ERROR; 00979 } 00980 } 00981 else 00982 { 00983 /* PLL configuration is unchanged */ 00984 /* Re-enable PLL if it was disabled (ie. low power mode) */ 00985 if(READ_BIT(RCC->CR, RCC_CR_PLLRDY) == 0U) 00986 { 00987 /* Enable the main PLL. */ 00988 __HAL_RCC_PLL_ENABLE(); 00989 00990 /* Enable PLL System Clock output. */ 00991 __HAL_RCC_PLLCLKOUT_ENABLE(RCC_PLL_SYSCLK); 00992 00993 /* Get Start Tick*/ 00994 tickstart = HAL_GetTick(); 00995 00996 /* Wait till PLL is ready */ 00997 while(READ_BIT(RCC->CR, RCC_CR_PLLRDY) == 0U) 00998 { 00999 if((HAL_GetTick() - tickstart) > PLL_TIMEOUT_VALUE) 01000 { 01001 return HAL_TIMEOUT; 01002 } 01003 } 01004 } 01005 } 01006 } 01007 else 01008 { 01009 /* Check that PLL is not used as system clock or not */ 01010 if(sysclk_source != RCC_CFGR_SWS_PLL) 01011 { 01012 /* Disable the main PLL. */ 01013 __HAL_RCC_PLL_DISABLE(); 01014 01015 /* Disable all PLL outputs to save power if no PLLs on */ 01016 #if defined(RCC_PLLSAI1_SUPPORT) && defined(RCC_CR_PLLSAI2RDY) 01017 if(READ_BIT(RCC->CR, (RCC_CR_PLLSAI1RDY | RCC_CR_PLLSAI2RDY)) == 0U) 01018 { 01019 MODIFY_REG(RCC->PLLCFGR, RCC_PLLCFGR_PLLSRC, RCC_PLLSOURCE_NONE); 01020 } 01021 #elif defined(RCC_PLLSAI1_SUPPORT) 01022 if(READ_BIT(RCC->CR, RCC_CR_PLLSAI1RDY) == 0U) 01023 { 01024 MODIFY_REG(RCC->PLLCFGR, RCC_PLLCFGR_PLLSRC, RCC_PLLSOURCE_NONE); 01025 } 01026 #else 01027 MODIFY_REG(RCC->PLLCFGR, RCC_PLLCFGR_PLLSRC, RCC_PLLSOURCE_NONE); 01028 #endif /* RCC_PLLSAI1_SUPPORT && RCC_CR_PLLSAI2RDY */ 01029 01030 #if defined(RCC_PLLSAI2_SUPPORT) 01031 __HAL_RCC_PLLCLKOUT_DISABLE(RCC_PLL_SYSCLK | RCC_PLL_48M1CLK | RCC_PLL_SAI3CLK); 01032 #elif defined(RCC_PLLSAI1_SUPPORT) 01033 __HAL_RCC_PLLCLKOUT_DISABLE(RCC_PLL_SYSCLK | RCC_PLL_48M1CLK | RCC_PLL_SAI2CLK); 01034 #else 01035 __HAL_RCC_PLLCLKOUT_DISABLE(RCC_PLL_SYSCLK | RCC_PLL_48M1CLK); 01036 #endif /* RCC_PLLSAI2_SUPPORT */ 01037 01038 /* Get Start Tick*/ 01039 tickstart = HAL_GetTick(); 01040 01041 /* Wait till PLL is disabled */ 01042 while(READ_BIT(RCC->CR, RCC_CR_PLLRDY) != 0U) 01043 { 01044 if((HAL_GetTick() - tickstart) > PLL_TIMEOUT_VALUE) 01045 { 01046 return HAL_TIMEOUT; 01047 } 01048 } 01049 } 01050 else 01051 { 01052 /* PLL is already used as System core clock */ 01053 return HAL_ERROR; 01054 } 01055 } 01056 } 01057 return HAL_OK; 01058 } 01059 01060 /** 01061 * @brief Initialize the CPU, AHB and APB busses clocks according to the specified 01062 * parameters in the RCC_ClkInitStruct. 01063 * @param RCC_ClkInitStruct pointer to an RCC_OscInitTypeDef structure that 01064 * contains the configuration information for the RCC peripheral. 01065 * @param FLatency FLASH Latency 01066 * This parameter can be one of the following values: 01067 * @arg FLASH_LATENCY_0 FLASH 0 Latency cycle 01068 * @arg FLASH_LATENCY_1 FLASH 1 Latency cycle 01069 * @arg FLASH_LATENCY_2 FLASH 2 Latency cycles 01070 * @arg FLASH_LATENCY_3 FLASH 3 Latency cycles 01071 * @arg FLASH_LATENCY_4 FLASH 4 Latency cycles 01072 @if STM32L4S9xx 01073 * @arg FLASH_LATENCY_5 FLASH 5 Latency cycles 01074 * @arg FLASH_LATENCY_6 FLASH 6 Latency cycles 01075 * @arg FLASH_LATENCY_7 FLASH 7 Latency cycles 01076 * @arg FLASH_LATENCY_8 FLASH 8 Latency cycles 01077 * @arg FLASH_LATENCY_9 FLASH 9 Latency cycles 01078 * @arg FLASH_LATENCY_10 FLASH 10 Latency cycles 01079 * @arg FLASH_LATENCY_11 FLASH 11 Latency cycles 01080 * @arg FLASH_LATENCY_12 FLASH 12 Latency cycles 01081 * @arg FLASH_LATENCY_13 FLASH 13 Latency cycles 01082 * @arg FLASH_LATENCY_14 FLASH 14 Latency cycles 01083 * @arg FLASH_LATENCY_15 FLASH 15 Latency cycles 01084 @endif 01085 * 01086 * @note The SystemCoreClock CMSIS variable is used to store System Clock Frequency 01087 * and updated by HAL_RCC_GetHCLKFreq() function called within this function 01088 * 01089 * @note The MSI is used by default as system clock source after 01090 * startup from Reset, wake-up from STANDBY mode. After restart from Reset, 01091 * the MSI frequency is set to its default value 4 MHz. 01092 * 01093 * @note The HSI can be selected as system clock source after 01094 * from STOP modes or in case of failure of the HSE used directly or indirectly 01095 * as system clock (if the Clock Security System CSS is enabled). 01096 * 01097 * @note A switch from one clock source to another occurs only if the target 01098 * clock source is ready (clock stable after startup delay or PLL locked). 01099 * If a clock source which is not yet ready is selected, the switch will 01100 * occur when the clock source is ready. 01101 * 01102 * @note You can use HAL_RCC_GetClockConfig() function to know which clock is 01103 * currently used as system clock source. 01104 * 01105 * @note Depending on the device voltage range, the software has to set correctly 01106 * HPRE[3:0] bits to ensure that HCLK not exceed the maximum allowed frequency 01107 * (for more details refer to section above "Initialization/de-initialization functions") 01108 * @retval None 01109 */ 01110 HAL_StatusTypeDef HAL_RCC_ClockConfig(RCC_ClkInitTypeDef *RCC_ClkInitStruct, uint32_t FLatency) 01111 { 01112 uint32_t tickstart; 01113 #if defined(STM32L4P5xx) || defined(STM32L4Q5xx) || \ 01114 defined(STM32L4R5xx) || defined(STM32L4R7xx) || defined(STM32L4R9xx) || defined(STM32L4S5xx) || defined(STM32L4S7xx) || defined(STM32L4S9xx) 01115 uint32_t hpre = RCC_SYSCLK_DIV1; 01116 #endif 01117 HAL_StatusTypeDef status; 01118 01119 /* Check Null pointer */ 01120 if(RCC_ClkInitStruct == NULL) 01121 { 01122 return HAL_ERROR; 01123 } 01124 01125 /* Check the parameters */ 01126 assert_param(IS_RCC_CLOCKTYPE(RCC_ClkInitStruct->ClockType)); 01127 assert_param(IS_FLASH_LATENCY(FLatency)); 01128 01129 /* To correctly read data from FLASH memory, the number of wait states (LATENCY) 01130 must be correctly programmed according to the frequency of the CPU clock 01131 (HCLK) and the supply voltage of the device. */ 01132 01133 /* Increasing the number of wait states because of higher CPU frequency */ 01134 if(FLatency > __HAL_FLASH_GET_LATENCY()) 01135 { 01136 /* Program the new number of wait states to the LATENCY bits in the FLASH_ACR register */ 01137 __HAL_FLASH_SET_LATENCY(FLatency); 01138 01139 /* Check that the new number of wait states is taken into account to access the Flash 01140 memory by reading the FLASH_ACR register */ 01141 if(__HAL_FLASH_GET_LATENCY() != FLatency) 01142 { 01143 return HAL_ERROR; 01144 } 01145 } 01146 01147 /*------------------------- SYSCLK Configuration ---------------------------*/ 01148 if(((RCC_ClkInitStruct->ClockType) & RCC_CLOCKTYPE_SYSCLK) == RCC_CLOCKTYPE_SYSCLK) 01149 { 01150 assert_param(IS_RCC_SYSCLKSOURCE(RCC_ClkInitStruct->SYSCLKSource)); 01151 01152 /* PLL is selected as System Clock Source */ 01153 if(RCC_ClkInitStruct->SYSCLKSource == RCC_SYSCLKSOURCE_PLLCLK) 01154 { 01155 /* Check the PLL ready flag */ 01156 if(READ_BIT(RCC->CR, RCC_CR_PLLRDY) == 0U) 01157 { 01158 return HAL_ERROR; 01159 } 01160 #if defined(STM32L4P5xx) || defined(STM32L4Q5xx) || \ 01161 defined(STM32L4R5xx) || defined(STM32L4R7xx) || defined(STM32L4R9xx) || defined(STM32L4S5xx) || defined(STM32L4S7xx) || defined(STM32L4S9xx) 01162 /* Undershoot management when selection PLL as SYSCLK source and frequency above 80Mhz */ 01163 /* Compute target PLL output frequency */ 01164 if(RCC_GetSysClockFreqFromPLLSource() > 80000000U) 01165 { 01166 if(READ_BIT(RCC->CFGR, RCC_CFGR_HPRE) == RCC_SYSCLK_DIV1) 01167 { 01168 /* Intermediate step with HCLK prescaler 2 necessary before to go over 80Mhz */ 01169 MODIFY_REG(RCC->CFGR, RCC_CFGR_HPRE, RCC_SYSCLK_DIV2); 01170 hpre = RCC_SYSCLK_DIV2; 01171 } 01172 else if((((RCC_ClkInitStruct->ClockType) & RCC_CLOCKTYPE_HCLK) == RCC_CLOCKTYPE_HCLK) && (RCC_ClkInitStruct->AHBCLKDivider == RCC_SYSCLK_DIV1)) 01173 { 01174 /* Intermediate step with HCLK prescaler 2 necessary before to go over 80Mhz */ 01175 MODIFY_REG(RCC->CFGR, RCC_CFGR_HPRE, RCC_SYSCLK_DIV2); 01176 hpre = RCC_SYSCLK_DIV2; 01177 } 01178 else 01179 { 01180 /* nothing to do */ 01181 } 01182 } 01183 #endif 01184 } 01185 else 01186 { 01187 /* HSE is selected as System Clock Source */ 01188 if(RCC_ClkInitStruct->SYSCLKSource == RCC_SYSCLKSOURCE_HSE) 01189 { 01190 /* Check the HSE ready flag */ 01191 if(READ_BIT(RCC->CR, RCC_CR_HSERDY) == 0U) 01192 { 01193 return HAL_ERROR; 01194 } 01195 } 01196 /* MSI is selected as System Clock Source */ 01197 else if(RCC_ClkInitStruct->SYSCLKSource == RCC_SYSCLKSOURCE_MSI) 01198 { 01199 /* Check the MSI ready flag */ 01200 if(READ_BIT(RCC->CR, RCC_CR_MSIRDY) == 0U) 01201 { 01202 return HAL_ERROR; 01203 } 01204 } 01205 /* HSI is selected as System Clock Source */ 01206 else 01207 { 01208 /* Check the HSI ready flag */ 01209 if(READ_BIT(RCC->CR, RCC_CR_HSIRDY) == 0U) 01210 { 01211 return HAL_ERROR; 01212 } 01213 } 01214 #if defined(STM32L4P5xx) || defined(STM32L4Q5xx) || \ 01215 defined(STM32L4R5xx) || defined(STM32L4R7xx) || defined(STM32L4R9xx) || defined(STM32L4S5xx) || defined(STM32L4S7xx) || defined(STM32L4S9xx) 01216 /* Overshoot management when going down from PLL as SYSCLK source and frequency above 80Mhz */ 01217 if(HAL_RCC_GetSysClockFreq() > 80000000U) 01218 { 01219 /* Intermediate step with HCLK prescaler 2 necessary before to go under 80Mhz */ 01220 MODIFY_REG(RCC->CFGR, RCC_CFGR_HPRE, RCC_SYSCLK_DIV2); 01221 hpre = RCC_SYSCLK_DIV2; 01222 } 01223 #endif 01224 01225 } 01226 01227 MODIFY_REG(RCC->CFGR, RCC_CFGR_SW, RCC_ClkInitStruct->SYSCLKSource); 01228 01229 /* Get Start Tick*/ 01230 tickstart = HAL_GetTick(); 01231 01232 while(__HAL_RCC_GET_SYSCLK_SOURCE() != (RCC_ClkInitStruct->SYSCLKSource << RCC_CFGR_SWS_Pos)) 01233 { 01234 if((HAL_GetTick() - tickstart) > CLOCKSWITCH_TIMEOUT_VALUE) 01235 { 01236 return HAL_TIMEOUT; 01237 } 01238 } 01239 } 01240 01241 /*-------------------------- HCLK Configuration --------------------------*/ 01242 if(((RCC_ClkInitStruct->ClockType) & RCC_CLOCKTYPE_HCLK) == RCC_CLOCKTYPE_HCLK) 01243 { 01244 assert_param(IS_RCC_HCLK(RCC_ClkInitStruct->AHBCLKDivider)); 01245 MODIFY_REG(RCC->CFGR, RCC_CFGR_HPRE, RCC_ClkInitStruct->AHBCLKDivider); 01246 } 01247 #if defined(STM32L4P5xx) || defined(STM32L4Q5xx) || \ 01248 defined(STM32L4R5xx) || defined(STM32L4R7xx) || defined(STM32L4R9xx) || defined(STM32L4S5xx) || defined(STM32L4S7xx) || defined(STM32L4S9xx) 01249 else 01250 { 01251 /* Is intermediate HCLK prescaler 2 applied internally, complete with HCLK prescaler 1 */ 01252 if(hpre == RCC_SYSCLK_DIV2) 01253 { 01254 MODIFY_REG(RCC->CFGR, RCC_CFGR_HPRE, RCC_SYSCLK_DIV1); 01255 } 01256 } 01257 #endif 01258 01259 /* Decreasing the number of wait states because of lower CPU frequency */ 01260 if(FLatency < __HAL_FLASH_GET_LATENCY()) 01261 { 01262 /* Program the new number of wait states to the LATENCY bits in the FLASH_ACR register */ 01263 __HAL_FLASH_SET_LATENCY(FLatency); 01264 01265 /* Check that the new number of wait states is taken into account to access the Flash 01266 memory by reading the FLASH_ACR register */ 01267 if(__HAL_FLASH_GET_LATENCY() != FLatency) 01268 { 01269 return HAL_ERROR; 01270 } 01271 } 01272 01273 /*-------------------------- PCLK1 Configuration ---------------------------*/ 01274 if(((RCC_ClkInitStruct->ClockType) & RCC_CLOCKTYPE_PCLK1) == RCC_CLOCKTYPE_PCLK1) 01275 { 01276 assert_param(IS_RCC_PCLK(RCC_ClkInitStruct->APB1CLKDivider)); 01277 MODIFY_REG(RCC->CFGR, RCC_CFGR_PPRE1, RCC_ClkInitStruct->APB1CLKDivider); 01278 } 01279 01280 /*-------------------------- PCLK2 Configuration ---------------------------*/ 01281 if(((RCC_ClkInitStruct->ClockType) & RCC_CLOCKTYPE_PCLK2) == RCC_CLOCKTYPE_PCLK2) 01282 { 01283 assert_param(IS_RCC_PCLK(RCC_ClkInitStruct->APB2CLKDivider)); 01284 MODIFY_REG(RCC->CFGR, RCC_CFGR_PPRE2, ((RCC_ClkInitStruct->APB2CLKDivider) << 3U)); 01285 } 01286 01287 /* Update the SystemCoreClock global variable */ 01288 SystemCoreClock = HAL_RCC_GetSysClockFreq() >> (AHBPrescTable[READ_BIT(RCC->CFGR, RCC_CFGR_HPRE) >> RCC_CFGR_HPRE_Pos] & 0x1FU); 01289 01290 /* Configure the source of time base considering new system clocks settings*/ 01291 status = HAL_InitTick(uwTickPrio); 01292 01293 return status; 01294 } 01295 01296 /** 01297 * @} 01298 */ 01299 01300 /** @defgroup RCC_Exported_Functions_Group2 Peripheral Control functions 01301 * @brief RCC clocks control functions 01302 * 01303 @verbatim 01304 =============================================================================== 01305 ##### Peripheral Control functions ##### 01306 =============================================================================== 01307 [..] 01308 This subsection provides a set of functions allowing to: 01309 01310 (+) Ouput clock to MCO pin. 01311 (+) Retrieve current clock frequencies. 01312 (+) Enable the Clock Security System. 01313 01314 @endverbatim 01315 * @{ 01316 */ 01317 01318 /** 01319 * @brief Select the clock source to output on MCO pin(PA8). 01320 * @note PA8 should be configured in alternate function mode. 01321 * @param RCC_MCOx specifies the output direction for the clock source. 01322 * For STM32L4xx family this parameter can have only one value: 01323 * @arg @ref RCC_MCO1 Clock source to output on MCO1 pin(PA8). 01324 * @param RCC_MCOSource specifies the clock source to output. 01325 * This parameter can be one of the following values: 01326 * @arg @ref RCC_MCO1SOURCE_NOCLOCK MCO output disabled, no clock on MCO 01327 * @arg @ref RCC_MCO1SOURCE_SYSCLK system clock selected as MCO source 01328 * @arg @ref RCC_MCO1SOURCE_MSI MSI clock selected as MCO source 01329 * @arg @ref RCC_MCO1SOURCE_HSI HSI clock selected as MCO source 01330 * @arg @ref RCC_MCO1SOURCE_HSE HSE clock selected as MCO sourcee 01331 * @arg @ref RCC_MCO1SOURCE_PLLCLK main PLL clock selected as MCO source 01332 * @arg @ref RCC_MCO1SOURCE_LSI LSI clock selected as MCO source 01333 * @arg @ref RCC_MCO1SOURCE_LSE LSE clock selected as MCO source 01334 @if STM32L443xx 01335 * @arg @ref RCC_MCO1SOURCE_HSI48 HSI48 clock selected as MCO source for devices with HSI48 01336 @endif 01337 * @param RCC_MCODiv specifies the MCO prescaler. 01338 * This parameter can be one of the following values: 01339 * @arg @ref RCC_MCODIV_1 no division applied to MCO clock 01340 * @arg @ref RCC_MCODIV_2 division by 2 applied to MCO clock 01341 * @arg @ref RCC_MCODIV_4 division by 4 applied to MCO clock 01342 * @arg @ref RCC_MCODIV_8 division by 8 applied to MCO clock 01343 * @arg @ref RCC_MCODIV_16 division by 16 applied to MCO clock 01344 * @retval None 01345 */ 01346 void HAL_RCC_MCOConfig( uint32_t RCC_MCOx, uint32_t RCC_MCOSource, uint32_t RCC_MCODiv) 01347 { 01348 GPIO_InitTypeDef GPIO_InitStruct; 01349 01350 /* Check the parameters */ 01351 assert_param(IS_RCC_MCO(RCC_MCOx)); 01352 assert_param(IS_RCC_MCODIV(RCC_MCODiv)); 01353 assert_param(IS_RCC_MCO1SOURCE(RCC_MCOSource)); 01354 01355 /* Prevent unused argument(s) compilation warning if no assert_param check */ 01356 UNUSED(RCC_MCOx); 01357 01358 /* MCO Clock Enable */ 01359 __MCO1_CLK_ENABLE(); 01360 01361 /* Configue the MCO1 pin in alternate function mode */ 01362 GPIO_InitStruct.Pin = MCO1_PIN; 01363 GPIO_InitStruct.Mode = GPIO_MODE_AF_PP; 01364 GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH; 01365 GPIO_InitStruct.Pull = GPIO_NOPULL; 01366 GPIO_InitStruct.Alternate = GPIO_AF0_MCO; 01367 HAL_GPIO_Init(MCO1_GPIO_PORT, &GPIO_InitStruct); 01368 01369 /* Mask MCOSEL[] and MCOPRE[] bits then set MCO1 clock source and prescaler */ 01370 MODIFY_REG(RCC->CFGR, (RCC_CFGR_MCOSEL | RCC_CFGR_MCOPRE), (RCC_MCOSource | RCC_MCODiv )); 01371 } 01372 01373 /** 01374 * @brief Return the SYSCLK frequency. 01375 * 01376 * @note The system frequency computed by this function is not the real 01377 * frequency in the chip. It is calculated based on the predefined 01378 * constant and the selected clock source: 01379 * @note If SYSCLK source is MSI, function returns values based on MSI 01380 * Value as defined by the MSI range. 01381 * @note If SYSCLK source is HSI, function returns values based on HSI_VALUE(*) 01382 * @note If SYSCLK source is HSE, function returns values based on HSE_VALUE(**) 01383 * @note If SYSCLK source is PLL, function returns values based on HSE_VALUE(**), 01384 * HSI_VALUE(*) or MSI Value multiplied/divided by the PLL factors. 01385 * @note (*) HSI_VALUE is a constant defined in stm32l4xx_hal_conf.h file (default value 01386 * 16 MHz) but the real value may vary depending on the variations 01387 * in voltage and temperature. 01388 * @note (**) HSE_VALUE is a constant defined in stm32l4xx_hal_conf.h file (default value 01389 * 8 MHz), user has to ensure that HSE_VALUE is same as the real 01390 * frequency of the crystal used. Otherwise, this function may 01391 * have wrong result. 01392 * 01393 * @note The result of this function could be not correct when using fractional 01394 * value for HSE crystal. 01395 * 01396 * @note This function can be used by the user application to compute the 01397 * baudrate for the communication peripherals or configure other parameters. 01398 * 01399 * @note Each time SYSCLK changes, this function must be called to update the 01400 * right SYSCLK value. Otherwise, any configuration based on this function will be incorrect. 01401 * 01402 * 01403 * @retval SYSCLK frequency 01404 */ 01405 uint32_t HAL_RCC_GetSysClockFreq(void) 01406 { 01407 uint32_t msirange = 0U, sysclockfreq = 0U; 01408 uint32_t pllvco, pllsource, pllr, pllm; /* no init needed */ 01409 uint32_t sysclk_source, pll_oscsource; 01410 01411 sysclk_source = __HAL_RCC_GET_SYSCLK_SOURCE(); 01412 pll_oscsource = __HAL_RCC_GET_PLL_OSCSOURCE(); 01413 01414 if((sysclk_source == RCC_CFGR_SWS_MSI) || 01415 ((sysclk_source == RCC_CFGR_SWS_PLL) && (pll_oscsource == RCC_PLLSOURCE_MSI))) 01416 { 01417 /* MSI or PLL with MSI source used as system clock source */ 01418 01419 /* Get SYSCLK source */ 01420 if(READ_BIT(RCC->CR, RCC_CR_MSIRGSEL) == 0U) 01421 { /* MSISRANGE from RCC_CSR applies */ 01422 msirange = READ_BIT(RCC->CSR, RCC_CSR_MSISRANGE) >> RCC_CSR_MSISRANGE_Pos; 01423 } 01424 else 01425 { /* MSIRANGE from RCC_CR applies */ 01426 msirange = READ_BIT(RCC->CR, RCC_CR_MSIRANGE) >> RCC_CR_MSIRANGE_Pos; 01427 } 01428 /*MSI frequency range in HZ*/ 01429 msirange = MSIRangeTable[msirange]; 01430 01431 if(sysclk_source == RCC_CFGR_SWS_MSI) 01432 { 01433 /* MSI used as system clock source */ 01434 sysclockfreq = msirange; 01435 } 01436 } 01437 else if(sysclk_source == RCC_CFGR_SWS_HSI) 01438 { 01439 /* HSI used as system clock source */ 01440 sysclockfreq = HSI_VALUE; 01441 } 01442 else if(sysclk_source == RCC_CFGR_SWS_HSE) 01443 { 01444 /* HSE used as system clock source */ 01445 sysclockfreq = HSE_VALUE; 01446 } 01447 else 01448 { 01449 /* unexpected case: sysclockfreq at 0 */ 01450 } 01451 01452 if(sysclk_source == RCC_CFGR_SWS_PLL) 01453 { 01454 /* PLL used as system clock source */ 01455 01456 /* PLL_VCO = (HSE_VALUE or HSI_VALUE or MSI_VALUE) * PLLN / PLLM 01457 SYSCLK = PLL_VCO / PLLR 01458 */ 01459 pllsource = READ_BIT(RCC->PLLCFGR, RCC_PLLCFGR_PLLSRC); 01460 01461 switch (pllsource) 01462 { 01463 case RCC_PLLSOURCE_HSI: /* HSI used as PLL clock source */ 01464 pllvco = HSI_VALUE; 01465 break; 01466 01467 case RCC_PLLSOURCE_HSE: /* HSE used as PLL clock source */ 01468 pllvco = HSE_VALUE; 01469 break; 01470 01471 case RCC_PLLSOURCE_MSI: /* MSI used as PLL clock source */ 01472 default: 01473 pllvco = msirange; 01474 break; 01475 } 01476 pllm = (READ_BIT(RCC->PLLCFGR, RCC_PLLCFGR_PLLM) >> RCC_PLLCFGR_PLLM_Pos) + 1U ; 01477 pllvco = (pllvco * (READ_BIT(RCC->PLLCFGR, RCC_PLLCFGR_PLLN) >> RCC_PLLCFGR_PLLN_Pos)) / pllm; 01478 pllr = ((READ_BIT(RCC->PLLCFGR, RCC_PLLCFGR_PLLR) >> RCC_PLLCFGR_PLLR_Pos) + 1U ) * 2U; 01479 sysclockfreq = pllvco / pllr; 01480 } 01481 01482 return sysclockfreq; 01483 } 01484 01485 /** 01486 * @brief Return the HCLK frequency. 01487 * @note Each time HCLK changes, this function must be called to update the 01488 * right HCLK value. Otherwise, any configuration based on this function will be incorrect. 01489 * 01490 * @note The SystemCoreClock CMSIS variable is used to store System Clock Frequency. 01491 * @retval HCLK frequency in Hz 01492 */ 01493 uint32_t HAL_RCC_GetHCLKFreq(void) 01494 { 01495 return SystemCoreClock; 01496 } 01497 01498 /** 01499 * @brief Return the PCLK1 frequency. 01500 * @note Each time PCLK1 changes, this function must be called to update the 01501 * right PCLK1 value. Otherwise, any configuration based on this function will be incorrect. 01502 * @retval PCLK1 frequency in Hz 01503 */ 01504 uint32_t HAL_RCC_GetPCLK1Freq(void) 01505 { 01506 /* Get HCLK source and Compute PCLK1 frequency ---------------------------*/ 01507 return (HAL_RCC_GetHCLKFreq() >> (APBPrescTable[READ_BIT(RCC->CFGR, RCC_CFGR_PPRE1) >> RCC_CFGR_PPRE1_Pos] & 0x1FU)); 01508 } 01509 01510 /** 01511 * @brief Return the PCLK2 frequency. 01512 * @note Each time PCLK2 changes, this function must be called to update the 01513 * right PCLK2 value. Otherwise, any configuration based on this function will be incorrect. 01514 * @retval PCLK2 frequency in Hz 01515 */ 01516 uint32_t HAL_RCC_GetPCLK2Freq(void) 01517 { 01518 /* Get HCLK source and Compute PCLK2 frequency ---------------------------*/ 01519 return (HAL_RCC_GetHCLKFreq()>> (APBPrescTable[READ_BIT(RCC->CFGR, RCC_CFGR_PPRE2) >> RCC_CFGR_PPRE2_Pos] & 0x1FU)); 01520 } 01521 01522 /** 01523 * @brief Configure the RCC_OscInitStruct according to the internal 01524 * RCC configuration registers. 01525 * @param RCC_OscInitStruct pointer to an RCC_OscInitTypeDef structure that 01526 * will be configured. 01527 * @retval None 01528 */ 01529 void HAL_RCC_GetOscConfig(RCC_OscInitTypeDef *RCC_OscInitStruct) 01530 { 01531 /* Check the parameters */ 01532 assert_param(RCC_OscInitStruct != (void *)NULL); 01533 01534 /* Set all possible values for the Oscillator type parameter ---------------*/ 01535 #if defined(RCC_HSI48_SUPPORT) 01536 RCC_OscInitStruct->OscillatorType = RCC_OSCILLATORTYPE_HSE | RCC_OSCILLATORTYPE_HSI | RCC_OSCILLATORTYPE_MSI | \ 01537 RCC_OSCILLATORTYPE_LSE | RCC_OSCILLATORTYPE_LSI | RCC_OSCILLATORTYPE_HSI48; 01538 #else 01539 RCC_OscInitStruct->OscillatorType = RCC_OSCILLATORTYPE_HSE | RCC_OSCILLATORTYPE_HSI | RCC_OSCILLATORTYPE_MSI | \ 01540 RCC_OSCILLATORTYPE_LSE | RCC_OSCILLATORTYPE_LSI; 01541 #endif /* RCC_HSI48_SUPPORT */ 01542 01543 /* Get the HSE configuration -----------------------------------------------*/ 01544 if(READ_BIT(RCC->CR, RCC_CR_HSEBYP) == RCC_CR_HSEBYP) 01545 { 01546 RCC_OscInitStruct->HSEState = RCC_HSE_BYPASS; 01547 } 01548 else if(READ_BIT(RCC->CR, RCC_CR_HSEON) == RCC_CR_HSEON) 01549 { 01550 RCC_OscInitStruct->HSEState = RCC_HSE_ON; 01551 } 01552 else 01553 { 01554 RCC_OscInitStruct->HSEState = RCC_HSE_OFF; 01555 } 01556 01557 /* Get the MSI configuration -----------------------------------------------*/ 01558 if(READ_BIT(RCC->CR, RCC_CR_MSION) == RCC_CR_MSION) 01559 { 01560 RCC_OscInitStruct->MSIState = RCC_MSI_ON; 01561 } 01562 else 01563 { 01564 RCC_OscInitStruct->MSIState = RCC_MSI_OFF; 01565 } 01566 01567 RCC_OscInitStruct->MSICalibrationValue = READ_BIT(RCC->ICSCR, RCC_ICSCR_MSITRIM) >> RCC_ICSCR_MSITRIM_Pos; 01568 RCC_OscInitStruct->MSIClockRange = READ_BIT(RCC->CR, RCC_CR_MSIRANGE); 01569 01570 /* Get the HSI configuration -----------------------------------------------*/ 01571 if(READ_BIT(RCC->CR, RCC_CR_HSION) == RCC_CR_HSION) 01572 { 01573 RCC_OscInitStruct->HSIState = RCC_HSI_ON; 01574 } 01575 else 01576 { 01577 RCC_OscInitStruct->HSIState = RCC_HSI_OFF; 01578 } 01579 01580 RCC_OscInitStruct->HSICalibrationValue = READ_BIT(RCC->ICSCR, RCC_ICSCR_HSITRIM) >> RCC_ICSCR_HSITRIM_Pos; 01581 01582 /* Get the LSE configuration -----------------------------------------------*/ 01583 if(READ_BIT(RCC->BDCR, RCC_BDCR_LSEBYP) == RCC_BDCR_LSEBYP) 01584 { 01585 #if defined(RCC_BDCR_LSESYSDIS) 01586 if((RCC->BDCR & RCC_BDCR_LSESYSDIS) == RCC_BDCR_LSESYSDIS) 01587 { 01588 RCC_OscInitStruct->LSEState = RCC_LSE_BYPASS_RTC_ONLY; 01589 } 01590 else 01591 #endif /* RCC_BDCR_LSESYSDIS */ 01592 { 01593 RCC_OscInitStruct->LSEState = RCC_LSE_BYPASS; 01594 } 01595 } 01596 else if(READ_BIT(RCC->BDCR, RCC_BDCR_LSEON) == RCC_BDCR_LSEON) 01597 { 01598 #if defined(RCC_BDCR_LSESYSDIS) 01599 if((RCC->BDCR & RCC_BDCR_LSESYSDIS) == RCC_BDCR_LSESYSDIS) 01600 { 01601 RCC_OscInitStruct->LSEState = RCC_LSE_ON_RTC_ONLY; 01602 } 01603 else 01604 #endif /* RCC_BDCR_LSESYSDIS */ 01605 { 01606 RCC_OscInitStruct->LSEState = RCC_LSE_ON; 01607 } 01608 } 01609 else 01610 { 01611 RCC_OscInitStruct->LSEState = RCC_LSE_OFF; 01612 } 01613 01614 /* Get the LSI configuration -----------------------------------------------*/ 01615 if(READ_BIT(RCC->CSR, RCC_CSR_LSION) == RCC_CSR_LSION) 01616 { 01617 RCC_OscInitStruct->LSIState = RCC_LSI_ON; 01618 } 01619 else 01620 { 01621 RCC_OscInitStruct->LSIState = RCC_LSI_OFF; 01622 } 01623 #if defined(RCC_CSR_LSIPREDIV) 01624 01625 /* Get the LSI configuration -----------------------------------------------*/ 01626 if((RCC->CSR & RCC_CSR_LSIPREDIV) == RCC_CSR_LSIPREDIV) 01627 { 01628 RCC_OscInitStruct->LSIDiv = RCC_LSI_DIV128; 01629 } 01630 else 01631 { 01632 RCC_OscInitStruct->LSIDiv = RCC_LSI_DIV1; 01633 } 01634 #endif /* RCC_CSR_LSIPREDIV */ 01635 01636 #if defined(RCC_HSI48_SUPPORT) 01637 /* Get the HSI48 configuration ---------------------------------------------*/ 01638 if(READ_BIT(RCC->CRRCR, RCC_CRRCR_HSI48ON) == RCC_CRRCR_HSI48ON) 01639 { 01640 RCC_OscInitStruct->HSI48State = RCC_HSI48_ON; 01641 } 01642 else 01643 { 01644 RCC_OscInitStruct->HSI48State = RCC_HSI48_OFF; 01645 } 01646 #else 01647 RCC_OscInitStruct->HSI48State = RCC_HSI48_OFF; 01648 #endif /* RCC_HSI48_SUPPORT */ 01649 01650 /* Get the PLL configuration -----------------------------------------------*/ 01651 if(READ_BIT(RCC->CR, RCC_CR_PLLON) == RCC_CR_PLLON) 01652 { 01653 RCC_OscInitStruct->PLL.PLLState = RCC_PLL_ON; 01654 } 01655 else 01656 { 01657 RCC_OscInitStruct->PLL.PLLState = RCC_PLL_OFF; 01658 } 01659 RCC_OscInitStruct->PLL.PLLSource = READ_BIT(RCC->PLLCFGR, RCC_PLLCFGR_PLLSRC); 01660 RCC_OscInitStruct->PLL.PLLM = (READ_BIT(RCC->PLLCFGR, RCC_PLLCFGR_PLLM) >> RCC_PLLCFGR_PLLM_Pos) + 1U; 01661 RCC_OscInitStruct->PLL.PLLN = READ_BIT(RCC->PLLCFGR, RCC_PLLCFGR_PLLN) >> RCC_PLLCFGR_PLLN_Pos; 01662 RCC_OscInitStruct->PLL.PLLQ = (((READ_BIT(RCC->PLLCFGR, RCC_PLLCFGR_PLLQ) >> RCC_PLLCFGR_PLLQ_Pos) + 1U) << 1U); 01663 RCC_OscInitStruct->PLL.PLLR = (((READ_BIT(RCC->PLLCFGR, RCC_PLLCFGR_PLLR) >> RCC_PLLCFGR_PLLR_Pos) + 1U) << 1U); 01664 #if defined(RCC_PLLP_SUPPORT) 01665 #if defined(RCC_PLLP_DIV_2_31_SUPPORT) 01666 RCC_OscInitStruct->PLL.PLLP = READ_BIT(RCC->PLLCFGR, RCC_PLLCFGR_PLLPDIV) >> RCC_PLLCFGR_PLLPDIV_Pos; 01667 #else 01668 if(READ_BIT(RCC->PLLCFGR, RCC_PLLCFGR_PLLP) != 0U) 01669 { 01670 RCC_OscInitStruct->PLL.PLLP = RCC_PLLP_DIV17; 01671 } 01672 else 01673 { 01674 RCC_OscInitStruct->PLL.PLLP = RCC_PLLP_DIV7; 01675 } 01676 #endif /* RCC_PLLP_DIV_2_31_SUPPORT */ 01677 #endif /* RCC_PLLP_SUPPORT */ 01678 } 01679 01680 /** 01681 * @brief Configure the RCC_ClkInitStruct according to the internal 01682 * RCC configuration registers. 01683 * @param RCC_ClkInitStruct pointer to an RCC_ClkInitTypeDef structure that 01684 * will be configured. 01685 * @param pFLatency Pointer on the Flash Latency. 01686 * @retval None 01687 */ 01688 void HAL_RCC_GetClockConfig(RCC_ClkInitTypeDef *RCC_ClkInitStruct, uint32_t *pFLatency) 01689 { 01690 /* Check the parameters */ 01691 assert_param(RCC_ClkInitStruct != (void *)NULL); 01692 assert_param(pFLatency != (void *)NULL); 01693 01694 /* Set all possible values for the Clock type parameter --------------------*/ 01695 RCC_ClkInitStruct->ClockType = RCC_CLOCKTYPE_SYSCLK | RCC_CLOCKTYPE_HCLK | RCC_CLOCKTYPE_PCLK1 | RCC_CLOCKTYPE_PCLK2; 01696 01697 /* Get the SYSCLK configuration --------------------------------------------*/ 01698 RCC_ClkInitStruct->SYSCLKSource = READ_BIT(RCC->CFGR, RCC_CFGR_SW); 01699 01700 /* Get the HCLK configuration ----------------------------------------------*/ 01701 RCC_ClkInitStruct->AHBCLKDivider = READ_BIT(RCC->CFGR, RCC_CFGR_HPRE); 01702 01703 /* Get the APB1 configuration ----------------------------------------------*/ 01704 RCC_ClkInitStruct->APB1CLKDivider = READ_BIT(RCC->CFGR, RCC_CFGR_PPRE1); 01705 01706 /* Get the APB2 configuration ----------------------------------------------*/ 01707 RCC_ClkInitStruct->APB2CLKDivider = (READ_BIT(RCC->CFGR, RCC_CFGR_PPRE2) >> 3U); 01708 01709 /* Get the Flash Wait State (Latency) configuration ------------------------*/ 01710 *pFLatency = __HAL_FLASH_GET_LATENCY(); 01711 } 01712 01713 /** 01714 * @brief Enable the Clock Security System. 01715 * @note If a failure is detected on the HSE oscillator clock, this oscillator 01716 * is automatically disabled and an interrupt is generated to inform the 01717 * software about the failure (Clock Security System Interrupt, CSSI), 01718 * allowing the MCU to perform rescue operations. The CSSI is linked to 01719 * the Cortex-M4 NMI (Non-Maskable Interrupt) exception vector. 01720 * @note The Clock Security System can only be cleared by reset. 01721 * @retval None 01722 */ 01723 void HAL_RCC_EnableCSS(void) 01724 { 01725 SET_BIT(RCC->CR, RCC_CR_CSSON) ; 01726 } 01727 01728 /** 01729 * @brief Handle the RCC Clock Security System interrupt request. 01730 * @note This API should be called under the NMI_Handler(). 01731 * @retval None 01732 */ 01733 void HAL_RCC_NMI_IRQHandler(void) 01734 { 01735 /* Check RCC CSSF interrupt flag */ 01736 if(__HAL_RCC_GET_IT(RCC_IT_CSS)) 01737 { 01738 /* RCC Clock Security System interrupt user callback */ 01739 HAL_RCC_CSSCallback(); 01740 01741 /* Clear RCC CSS pending bit */ 01742 __HAL_RCC_CLEAR_IT(RCC_IT_CSS); 01743 } 01744 } 01745 01746 /** 01747 * @brief RCC Clock Security System interrupt callback. 01748 * @retval none 01749 */ 01750 __weak void HAL_RCC_CSSCallback(void) 01751 { 01752 /* NOTE : This function should not be modified, when the callback is needed, 01753 the HAL_RCC_CSSCallback should be implemented in the user file 01754 */ 01755 } 01756 01757 /** 01758 * @brief Get and clear reset flags 01759 * @param None 01760 * @note Once reset flags are retrieved, this API is clearing them in order 01761 * to isolate next reset reason. 01762 * @retval can be a combination of @ref RCC_Reset_Flag 01763 */ 01764 uint32_t HAL_RCC_GetResetSource(void) 01765 { 01766 uint32_t reset; 01767 01768 /* Get all reset flags */ 01769 reset = RCC->CSR & RCC_RESET_FLAG_ALL; 01770 01771 /* Clear Reset flags */ 01772 RCC->CSR |= RCC_CSR_RMVF; 01773 01774 return reset; 01775 } 01776 01777 /** * @} 01778 */ 01779 01780 /** 01781 * @} 01782 */ 01783 01784 /* Private function prototypes -----------------------------------------------*/ 01785 /** @addtogroup RCC_Private_Functions 01786 * @{ 01787 */ 01788 /** 01789 * @brief Update number of Flash wait states in line with MSI range and current 01790 voltage range. 01791 * @param msirange MSI range value from RCC_MSIRANGE_0 to RCC_MSIRANGE_11 01792 * @retval HAL status 01793 */ 01794 static HAL_StatusTypeDef RCC_SetFlashLatencyFromMSIRange(uint32_t msirange) 01795 { 01796 uint32_t vos; 01797 uint32_t latency = FLASH_LATENCY_0; /* default value 0WS */ 01798 01799 if(__HAL_RCC_PWR_IS_CLK_ENABLED()) 01800 { 01801 vos = HAL_PWREx_GetVoltageRange(); 01802 } 01803 else 01804 { 01805 __HAL_RCC_PWR_CLK_ENABLE(); 01806 vos = HAL_PWREx_GetVoltageRange(); 01807 __HAL_RCC_PWR_CLK_DISABLE(); 01808 } 01809 01810 if(vos == PWR_REGULATOR_VOLTAGE_SCALE1) 01811 { 01812 if(msirange > RCC_MSIRANGE_8) 01813 { 01814 /* MSI > 16Mhz */ 01815 if(msirange > RCC_MSIRANGE_10) 01816 { 01817 /* MSI 48Mhz */ 01818 latency = FLASH_LATENCY_2; /* 2WS */ 01819 } 01820 else 01821 { 01822 /* MSI 24Mhz or 32Mhz */ 01823 latency = FLASH_LATENCY_1; /* 1WS */ 01824 } 01825 } 01826 /* else MSI <= 16Mhz default FLASH_LATENCY_0 0WS */ 01827 } 01828 else 01829 { 01830 #if defined(STM32L4P5xx) || defined(STM32L4Q5xx) || \ 01831 defined(STM32L4R5xx) || defined(STM32L4R7xx) || defined(STM32L4R9xx) || defined(STM32L4S5xx) || defined(STM32L4S7xx) || defined(STM32L4S9xx) 01832 if(msirange >= RCC_MSIRANGE_8) 01833 { 01834 /* MSI >= 16Mhz */ 01835 latency = FLASH_LATENCY_2; /* 2WS */ 01836 } 01837 else 01838 { 01839 if(msirange == RCC_MSIRANGE_7) 01840 { 01841 /* MSI 8Mhz */ 01842 latency = FLASH_LATENCY_1; /* 1WS */ 01843 } 01844 /* else MSI < 8Mhz default FLASH_LATENCY_0 0WS */ 01845 } 01846 #else 01847 if(msirange > RCC_MSIRANGE_8) 01848 { 01849 /* MSI > 16Mhz */ 01850 latency = FLASH_LATENCY_3; /* 3WS */ 01851 } 01852 else 01853 { 01854 if(msirange == RCC_MSIRANGE_8) 01855 { 01856 /* MSI 16Mhz */ 01857 latency = FLASH_LATENCY_2; /* 2WS */ 01858 } 01859 else if(msirange == RCC_MSIRANGE_7) 01860 { 01861 /* MSI 8Mhz */ 01862 latency = FLASH_LATENCY_1; /* 1WS */ 01863 } 01864 /* else MSI < 8Mhz default FLASH_LATENCY_0 0WS */ 01865 } 01866 #endif 01867 } 01868 01869 __HAL_FLASH_SET_LATENCY(latency); 01870 01871 /* Check that the new number of wait states is taken into account to access the Flash 01872 memory by reading the FLASH_ACR register */ 01873 if(__HAL_FLASH_GET_LATENCY() != latency) 01874 { 01875 return HAL_ERROR; 01876 } 01877 01878 return HAL_OK; 01879 } 01880 01881 #if defined(STM32L4P5xx) || defined(STM32L4Q5xx) || \ 01882 defined(STM32L4R5xx) || defined(STM32L4R7xx) || defined(STM32L4R9xx) || defined(STM32L4S5xx) || defined(STM32L4S7xx) || defined(STM32L4S9xx) 01883 /** 01884 * @brief Compute SYSCLK frequency based on PLL SYSCLK source. 01885 * @retval SYSCLK frequency 01886 */ 01887 static uint32_t RCC_GetSysClockFreqFromPLLSource(void) 01888 { 01889 uint32_t msirange = 0U; 01890 uint32_t pllvco, pllsource, pllr, pllm, sysclockfreq; /* no init needed */ 01891 01892 if(__HAL_RCC_GET_PLL_OSCSOURCE() == RCC_PLLSOURCE_MSI) 01893 { 01894 /* Get MSI range source */ 01895 if(READ_BIT(RCC->CR, RCC_CR_MSIRGSEL) == 0U) 01896 { /* MSISRANGE from RCC_CSR applies */ 01897 msirange = READ_BIT(RCC->CSR, RCC_CSR_MSISRANGE) >> RCC_CSR_MSISRANGE_Pos; 01898 } 01899 else 01900 { /* MSIRANGE from RCC_CR applies */ 01901 msirange = READ_BIT(RCC->CR, RCC_CR_MSIRANGE) >> RCC_CR_MSIRANGE_Pos; 01902 } 01903 /*MSI frequency range in HZ*/ 01904 msirange = MSIRangeTable[msirange]; 01905 } 01906 01907 /* PLL_VCO = (HSE_VALUE or HSI_VALUE or MSI_VALUE) * PLLN / PLLM 01908 SYSCLK = PLL_VCO / PLLR 01909 */ 01910 pllsource = READ_BIT(RCC->PLLCFGR, RCC_PLLCFGR_PLLSRC); 01911 01912 switch (pllsource) 01913 { 01914 case RCC_PLLSOURCE_HSI: /* HSI used as PLL clock source */ 01915 pllvco = HSI_VALUE; 01916 break; 01917 01918 case RCC_PLLSOURCE_HSE: /* HSE used as PLL clock source */ 01919 pllvco = HSE_VALUE; 01920 break; 01921 01922 case RCC_PLLSOURCE_MSI: /* MSI used as PLL clock source */ 01923 default: 01924 pllvco = msirange; 01925 break; 01926 } 01927 pllm = (READ_BIT(RCC->PLLCFGR, RCC_PLLCFGR_PLLM) >> RCC_PLLCFGR_PLLM_Pos) + 1U ; 01928 pllvco = (pllvco * (READ_BIT(RCC->PLLCFGR, RCC_PLLCFGR_PLLN) >> RCC_PLLCFGR_PLLN_Pos)) / pllm; 01929 pllr = ((READ_BIT(RCC->PLLCFGR, RCC_PLLCFGR_PLLR) >> RCC_PLLCFGR_PLLR_Pos) + 1U ) * 2U; 01930 sysclockfreq = pllvco / pllr; 01931 01932 return sysclockfreq; 01933 } 01934 #endif 01935 01936 /** 01937 * @} 01938 */ 01939 01940 #endif /* HAL_RCC_MODULE_ENABLED */ 01941 /** 01942 * @} 01943 */ 01944 01945 /** 01946 * @} 01947 */ 01948