STM32F103xB HAL User Manual
|
00001 /** 00002 ****************************************************************************** 00003 * @file stm32f1xx_ll_utils.c 00004 * @author MCD Application Team 00005 * @brief UTILS LL module driver. 00006 ****************************************************************************** 00007 * @attention 00008 * 00009 * <h2><center>© Copyright (c) 2016 STMicroelectronics. 00010 * All rights reserved.</center></h2> 00011 * 00012 * This software component is licensed by ST under BSD 3-Clause license, 00013 * the "License"; You may not use this file except in compliance with the 00014 * License. You may obtain a copy of the License at: 00015 * opensource.org/licenses/BSD-3-Clause 00016 * 00017 ****************************************************************************** 00018 */ 00019 00020 /* Includes ------------------------------------------------------------------*/ 00021 #include "stm32f1xx_ll_rcc.h" 00022 #include "stm32f1xx_ll_utils.h" 00023 #include "stm32f1xx_ll_system.h" 00024 #ifdef USE_FULL_ASSERT 00025 #include "stm32_assert.h" 00026 #else 00027 #define assert_param(expr) ((void)0U) 00028 #endif 00029 00030 /** @addtogroup STM32F1xx_LL_Driver 00031 * @{ 00032 */ 00033 00034 /** @addtogroup UTILS_LL 00035 * @{ 00036 */ 00037 00038 /* Private types -------------------------------------------------------------*/ 00039 /* Private variables ---------------------------------------------------------*/ 00040 /* Private constants ---------------------------------------------------------*/ 00041 /** @addtogroup UTILS_LL_Private_Constants 00042 * @{ 00043 */ 00044 00045 /* Defines used for PLL range */ 00046 #define UTILS_PLL_OUTPUT_MAX RCC_MAX_FREQUENCY /*!< Frequency max for PLL output, in Hz */ 00047 #define UTILS_PLL2_OUTPUT_MAX RCC_MAX_FREQUENCY /*!< Frequency max for PLL2 output, in Hz */ 00048 00049 /* Defines used for HSE range */ 00050 #define UTILS_HSE_FREQUENCY_MIN RCC_HSE_MIN /*!< Frequency min for HSE frequency, in Hz */ 00051 #define UTILS_HSE_FREQUENCY_MAX RCC_HSE_MAX /*!< Frequency max for HSE frequency, in Hz */ 00052 00053 /* Defines used for FLASH latency according to HCLK Frequency */ 00054 #if defined(FLASH_ACR_LATENCY) 00055 #define UTILS_LATENCY1_FREQ 24000000U /*!< SYSCLK frequency to set FLASH latency 1 */ 00056 #define UTILS_LATENCY2_FREQ 48000000U /*!< SYSCLK frequency to set FLASH latency 2 */ 00057 #else 00058 /*!< No Latency Configuration in this device */ 00059 #endif 00060 /** 00061 * @} 00062 */ 00063 /* Private macros ------------------------------------------------------------*/ 00064 /** @addtogroup UTILS_LL_Private_Macros 00065 * @{ 00066 */ 00067 #define IS_LL_UTILS_SYSCLK_DIV(__VALUE__) (((__VALUE__) == LL_RCC_SYSCLK_DIV_1) \ 00068 || ((__VALUE__) == LL_RCC_SYSCLK_DIV_2) \ 00069 || ((__VALUE__) == LL_RCC_SYSCLK_DIV_4) \ 00070 || ((__VALUE__) == LL_RCC_SYSCLK_DIV_8) \ 00071 || ((__VALUE__) == LL_RCC_SYSCLK_DIV_16) \ 00072 || ((__VALUE__) == LL_RCC_SYSCLK_DIV_64) \ 00073 || ((__VALUE__) == LL_RCC_SYSCLK_DIV_128) \ 00074 || ((__VALUE__) == LL_RCC_SYSCLK_DIV_256) \ 00075 || ((__VALUE__) == LL_RCC_SYSCLK_DIV_512)) 00076 00077 #define IS_LL_UTILS_APB1_DIV(__VALUE__) (((__VALUE__) == LL_RCC_APB1_DIV_1) \ 00078 || ((__VALUE__) == LL_RCC_APB1_DIV_2) \ 00079 || ((__VALUE__) == LL_RCC_APB1_DIV_4) \ 00080 || ((__VALUE__) == LL_RCC_APB1_DIV_8) \ 00081 || ((__VALUE__) == LL_RCC_APB1_DIV_16)) 00082 00083 #define IS_LL_UTILS_APB2_DIV(__VALUE__) (((__VALUE__) == LL_RCC_APB2_DIV_1) \ 00084 || ((__VALUE__) == LL_RCC_APB2_DIV_2) \ 00085 || ((__VALUE__) == LL_RCC_APB2_DIV_4) \ 00086 || ((__VALUE__) == LL_RCC_APB2_DIV_8) \ 00087 || ((__VALUE__) == LL_RCC_APB2_DIV_16)) 00088 00089 #if defined(RCC_CFGR_PLLMULL6_5) 00090 #define IS_LL_UTILS_PLLMUL_VALUE(__VALUE__) (((__VALUE__) == LL_RCC_PLL_MUL_4) \ 00091 || ((__VALUE__) == LL_RCC_PLL_MUL_5) \ 00092 || ((__VALUE__) == LL_RCC_PLL_MUL_6) \ 00093 || ((__VALUE__) == LL_RCC_PLL_MUL_7) \ 00094 || ((__VALUE__) == LL_RCC_PLL_MUL_8) \ 00095 || ((__VALUE__) == LL_RCC_PLL_MUL_9) \ 00096 || ((__VALUE__) == LL_RCC_PLL_MUL_6_5)) 00097 #else 00098 #define IS_LL_UTILS_PLLMUL_VALUE(__VALUE__) (((__VALUE__) == LL_RCC_PLL_MUL_2) \ 00099 || ((__VALUE__) == LL_RCC_PLL_MUL_3) \ 00100 || ((__VALUE__) == LL_RCC_PLL_MUL_4) \ 00101 || ((__VALUE__) == LL_RCC_PLL_MUL_5) \ 00102 || ((__VALUE__) == LL_RCC_PLL_MUL_6) \ 00103 || ((__VALUE__) == LL_RCC_PLL_MUL_7) \ 00104 || ((__VALUE__) == LL_RCC_PLL_MUL_8) \ 00105 || ((__VALUE__) == LL_RCC_PLL_MUL_9) \ 00106 || ((__VALUE__) == LL_RCC_PLL_MUL_10) \ 00107 || ((__VALUE__) == LL_RCC_PLL_MUL_11) \ 00108 || ((__VALUE__) == LL_RCC_PLL_MUL_12) \ 00109 || ((__VALUE__) == LL_RCC_PLL_MUL_13) \ 00110 || ((__VALUE__) == LL_RCC_PLL_MUL_14) \ 00111 || ((__VALUE__) == LL_RCC_PLL_MUL_15) \ 00112 || ((__VALUE__) == LL_RCC_PLL_MUL_16)) 00113 #endif /* RCC_CFGR_PLLMULL6_5 */ 00114 00115 #if defined(RCC_CFGR2_PREDIV1) 00116 #define IS_LL_UTILS_PREDIV_VALUE(__VALUE__) (((__VALUE__) == LL_RCC_PREDIV_DIV_1) || ((__VALUE__) == LL_RCC_PREDIV_DIV_2) || \ 00117 ((__VALUE__) == LL_RCC_PREDIV_DIV_3) || ((__VALUE__) == LL_RCC_PREDIV_DIV_4) || \ 00118 ((__VALUE__) == LL_RCC_PREDIV_DIV_5) || ((__VALUE__) == LL_RCC_PREDIV_DIV_6) || \ 00119 ((__VALUE__) == LL_RCC_PREDIV_DIV_7) || ((__VALUE__) == LL_RCC_PREDIV_DIV_8) || \ 00120 ((__VALUE__) == LL_RCC_PREDIV_DIV_9) || ((__VALUE__) == LL_RCC_PREDIV_DIV_10) || \ 00121 ((__VALUE__) == LL_RCC_PREDIV_DIV_11) || ((__VALUE__) == LL_RCC_PREDIV_DIV_12) || \ 00122 ((__VALUE__) == LL_RCC_PREDIV_DIV_13) || ((__VALUE__) == LL_RCC_PREDIV_DIV_14) || \ 00123 ((__VALUE__) == LL_RCC_PREDIV_DIV_15) || ((__VALUE__) == LL_RCC_PREDIV_DIV_16)) 00124 #else 00125 #define IS_LL_UTILS_PREDIV_VALUE(__VALUE__) (((__VALUE__) == LL_RCC_PREDIV_DIV_1) || ((__VALUE__) == LL_RCC_PREDIV_DIV_2)) 00126 #endif /*RCC_PREDIV1_DIV_2_16_SUPPORT*/ 00127 00128 #define IS_LL_UTILS_PLL_FREQUENCY(__VALUE__) ((__VALUE__) <= UTILS_PLL_OUTPUT_MAX) 00129 00130 #if defined(RCC_PLL2_SUPPORT) 00131 #define IS_LL_UTILS_PLL2MUL_VALUE(__VALUE__) (((__VALUE__) == LL_RCC_PLL2_MUL_8) \ 00132 || ((__VALUE__) == LL_RCC_PLL2_MUL_9) \ 00133 || ((__VALUE__) == LL_RCC_PLL2_MUL_10) \ 00134 || ((__VALUE__) == LL_RCC_PLL2_MUL_11) \ 00135 || ((__VALUE__) == LL_RCC_PLL2_MUL_12) \ 00136 || ((__VALUE__) == LL_RCC_PLL2_MUL_13) \ 00137 || ((__VALUE__) == LL_RCC_PLL2_MUL_14) \ 00138 || ((__VALUE__) == LL_RCC_PLL2_MUL_16) \ 00139 || ((__VALUE__) == LL_RCC_PLL2_MUL_20)) 00140 00141 #define IS_LL_UTILS_PREDIV2_VALUE(__VALUE__) (((__VALUE__) == LL_RCC_HSE_PREDIV2_DIV_1) || ((__VALUE__) == LL_RCC_HSE_PREDIV2_DIV_2) || \ 00142 ((__VALUE__) == LL_RCC_HSE_PREDIV2_DIV_3) || ((__VALUE__) == LL_RCC_HSE_PREDIV2_DIV_4) || \ 00143 ((__VALUE__) == LL_RCC_HSE_PREDIV2_DIV_5) || ((__VALUE__) == LL_RCC_HSE_PREDIV2_DIV_6) || \ 00144 ((__VALUE__) == LL_RCC_HSE_PREDIV2_DIV_7) || ((__VALUE__) == LL_RCC_HSE_PREDIV2_DIV_8) || \ 00145 ((__VALUE__) == LL_RCC_HSE_PREDIV2_DIV_9) || ((__VALUE__) == LL_RCC_HSE_PREDIV2_DIV_10) || \ 00146 ((__VALUE__) == LL_RCC_HSE_PREDIV2_DIV_11) || ((__VALUE__) == LL_RCC_HSE_PREDIV2_DIV_12) || \ 00147 ((__VALUE__) == LL_RCC_HSE_PREDIV2_DIV_13) || ((__VALUE__) == LL_RCC_HSE_PREDIV2_DIV_14) || \ 00148 ((__VALUE__) == LL_RCC_HSE_PREDIV2_DIV_15) || ((__VALUE__) == LL_RCC_HSE_PREDIV2_DIV_16)) 00149 00150 #define IS_LL_UTILS_PLL2_FREQUENCY(__VALUE__) ((__VALUE__) <= UTILS_PLL2_OUTPUT_MAX) 00151 #endif /* RCC_PLL2_SUPPORT */ 00152 00153 #define IS_LL_UTILS_HSE_BYPASS(__STATE__) (((__STATE__) == LL_UTILS_HSEBYPASS_ON) \ 00154 || ((__STATE__) == LL_UTILS_HSEBYPASS_OFF)) 00155 00156 #define IS_LL_UTILS_HSE_FREQUENCY(__FREQUENCY__) (((__FREQUENCY__) >= UTILS_HSE_FREQUENCY_MIN) && ((__FREQUENCY__) <= UTILS_HSE_FREQUENCY_MAX)) 00157 /** 00158 * @} 00159 */ 00160 /* Private function prototypes -----------------------------------------------*/ 00161 /** @defgroup UTILS_LL_Private_Functions UTILS Private functions 00162 * @{ 00163 */ 00164 static uint32_t UTILS_GetPLLOutputFrequency(uint32_t PLL_InputFrequency, 00165 LL_UTILS_PLLInitTypeDef *UTILS_PLLInitStruct); 00166 static ErrorStatus UTILS_PLL_HSE_ConfigSystemClock(uint32_t PLL_InputFrequency, uint32_t HSEBypass, 00167 LL_UTILS_PLLInitTypeDef *UTILS_PLLInitStruct, 00168 LL_UTILS_ClkInitTypeDef *UTILS_ClkInitStruct); 00169 #if defined(RCC_PLL2_SUPPORT) 00170 static uint32_t UTILS_GetPLL2OutputFrequency(uint32_t PLL2_InputFrequency, 00171 LL_UTILS_PLLInitTypeDef *UTILS_PLL2InitStruct); 00172 #endif /* RCC_PLL2_SUPPORT */ 00173 static ErrorStatus UTILS_EnablePLLAndSwitchSystem(uint32_t SYSCLK_Frequency, LL_UTILS_ClkInitTypeDef *UTILS_ClkInitStruct); 00174 static ErrorStatus UTILS_PLL_IsBusy(void); 00175 /** 00176 * @} 00177 */ 00178 00179 /* Exported functions --------------------------------------------------------*/ 00180 /** @addtogroup UTILS_LL_Exported_Functions 00181 * @{ 00182 */ 00183 00184 /** @addtogroup UTILS_LL_EF_DELAY 00185 * @{ 00186 */ 00187 00188 /** 00189 * @brief This function configures the Cortex-M SysTick source to have 1ms time base. 00190 * @note When a RTOS is used, it is recommended to avoid changing the Systick 00191 * configuration by calling this function, for a delay use rather osDelay RTOS service. 00192 * @param HCLKFrequency HCLK frequency in Hz 00193 * @note HCLK frequency can be calculated thanks to RCC helper macro or function @ref LL_RCC_GetSystemClocksFreq 00194 * @retval None 00195 */ 00196 void LL_Init1msTick(uint32_t HCLKFrequency) 00197 { 00198 /* Use frequency provided in argument */ 00199 LL_InitTick(HCLKFrequency, 1000U); 00200 } 00201 00202 /** 00203 * @brief This function provides accurate delay (in milliseconds) based 00204 * on SysTick counter flag 00205 * @note When a RTOS is used, it is recommended to avoid using blocking delay 00206 * and use rather osDelay service. 00207 * @note To respect 1ms timebase, user should call @ref LL_Init1msTick function which 00208 * will configure Systick to 1ms 00209 * @param Delay specifies the delay time length, in milliseconds. 00210 * @retval None 00211 */ 00212 void LL_mDelay(uint32_t Delay) 00213 { 00214 __IO uint32_t tmp = SysTick->CTRL; /* Clear the COUNTFLAG first */ 00215 /* Add this code to indicate that local variable is not used */ 00216 ((void)tmp); 00217 00218 /* Add a period to guaranty minimum wait */ 00219 if (Delay < LL_MAX_DELAY) 00220 { 00221 Delay++; 00222 } 00223 00224 while (Delay) 00225 { 00226 if ((SysTick->CTRL & SysTick_CTRL_COUNTFLAG_Msk) != 0U) 00227 { 00228 Delay--; 00229 } 00230 } 00231 } 00232 00233 /** 00234 * @} 00235 */ 00236 00237 /** @addtogroup UTILS_EF_SYSTEM 00238 * @brief System Configuration functions 00239 * 00240 @verbatim 00241 =============================================================================== 00242 ##### System Configuration functions ##### 00243 =============================================================================== 00244 [..] 00245 System, AHB and APB buses clocks configuration 00246 00247 (+) The maximum frequency of the SYSCLK, HCLK, PCLK1 and PCLK2 is RCC_MAX_FREQUENCY Hz. 00248 @endverbatim 00249 @internal 00250 Depending on the SYSCLK frequency, the flash latency should be adapted accordingly: 00251 (++) +-----------------------------------------------+ 00252 (++) | Latency | SYSCLK clock frequency (MHz) | 00253 (++) |---------------|-------------------------------| 00254 (++) |0WS(1CPU cycle)| 0 < SYSCLK <= 24 | 00255 (++) |---------------|-------------------------------| 00256 (++) |1WS(2CPU cycle)| 24 < SYSCLK <= 48 | 00257 (++) |---------------|-------------------------------| 00258 (++) |2WS(3CPU cycle)| 48 < SYSCLK <= 72 | 00259 (++) +-----------------------------------------------+ 00260 @endinternal 00261 * @{ 00262 */ 00263 00264 /** 00265 * @brief This function sets directly SystemCoreClock CMSIS variable. 00266 * @note Variable can be calculated also through SystemCoreClockUpdate function. 00267 * @param HCLKFrequency HCLK frequency in Hz (can be calculated thanks to RCC helper macro) 00268 * @retval None 00269 */ 00270 void LL_SetSystemCoreClock(uint32_t HCLKFrequency) 00271 { 00272 /* HCLK clock frequency */ 00273 SystemCoreClock = HCLKFrequency; 00274 } 00275 00276 /** 00277 * @brief Update number of Flash wait states in line with new frequency and current 00278 voltage range. 00279 * @param Frequency SYSCLK frequency 00280 * @retval An ErrorStatus enumeration value: 00281 * - SUCCESS: Latency has been modified 00282 * - ERROR: Latency cannot be modified 00283 */ 00284 #if defined(FLASH_ACR_LATENCY) 00285 ErrorStatus LL_SetFlashLatency(uint32_t Frequency) 00286 { 00287 uint32_t timeout; 00288 uint32_t getlatency; 00289 uint32_t latency = LL_FLASH_LATENCY_0; /* default value 0WS */ 00290 ErrorStatus status = SUCCESS; 00291 00292 /* Frequency cannot be equal to 0 */ 00293 if (Frequency == 0U) 00294 { 00295 status = ERROR; 00296 } 00297 else 00298 { 00299 if (Frequency > UTILS_LATENCY2_FREQ) 00300 { 00301 /* 48 < SYSCLK <= 72 => 2WS (3 CPU cycles) */ 00302 latency = LL_FLASH_LATENCY_2; 00303 } 00304 else 00305 { 00306 if (Frequency > UTILS_LATENCY1_FREQ) 00307 { 00308 /* 24 < SYSCLK <= 48 => 1WS (2 CPU cycles) */ 00309 latency = LL_FLASH_LATENCY_1; 00310 } 00311 else 00312 { 00313 /* else SYSCLK < 24MHz default LL_FLASH_LATENCY_0 0WS */ 00314 latency = LL_FLASH_LATENCY_0; 00315 } 00316 } 00317 00318 if (status != ERROR) 00319 { 00320 LL_FLASH_SetLatency(latency); 00321 00322 /* Check that the new number of wait states is taken into account to access the Flash 00323 memory by reading the FLASH_ACR register */ 00324 timeout = 2; 00325 do 00326 { 00327 /* Wait for Flash latency to be updated */ 00328 getlatency = LL_FLASH_GetLatency(); 00329 timeout--; 00330 } 00331 while ((getlatency != latency) && (timeout > 0)); 00332 00333 if (getlatency != latency) 00334 { 00335 status = ERROR; 00336 } 00337 else 00338 { 00339 status = SUCCESS; 00340 } 00341 } 00342 } 00343 00344 return status; 00345 } 00346 #endif /* FLASH_ACR_LATENCY */ 00347 00348 /** 00349 * @brief This function configures system clock with HSI as clock source of the PLL 00350 * @note The application need to ensure that PLL is disabled. 00351 * @note Function is based on the following formula: 00352 * - PLL output frequency = ((HSI frequency / PREDIV) * PLLMUL) 00353 * - PREDIV: Set to 2 for few devices 00354 * - PLLMUL: The application software must set correctly the PLL multiplication factor to 00355 * not exceed 72MHz 00356 * @note FLASH latency can be modified through this function. 00357 * @param UTILS_PLLInitStruct pointer to a @ref LL_UTILS_PLLInitTypeDef structure that contains 00358 * the configuration information for the PLL. 00359 * @param UTILS_ClkInitStruct pointer to a @ref LL_UTILS_ClkInitTypeDef structure that contains 00360 * the configuration information for the BUS prescalers. 00361 * @retval An ErrorStatus enumeration value: 00362 * - SUCCESS: Max frequency configuration done 00363 * - ERROR: Max frequency configuration not done 00364 */ 00365 ErrorStatus LL_PLL_ConfigSystemClock_HSI(LL_UTILS_PLLInitTypeDef *UTILS_PLLInitStruct, 00366 LL_UTILS_ClkInitTypeDef *UTILS_ClkInitStruct) 00367 { 00368 ErrorStatus status = SUCCESS; 00369 uint32_t pllfreq = 0U; 00370 00371 /* Check if one of the PLL is enabled */ 00372 if (UTILS_PLL_IsBusy() == SUCCESS) 00373 { 00374 #if defined(RCC_PLLSRC_PREDIV1_SUPPORT) 00375 /* Check PREDIV value */ 00376 assert_param(IS_LL_UTILS_PREDIV_VALUE(UTILS_PLLInitStruct->PLLDiv)); 00377 #else 00378 /* Force PREDIV value to 2 */ 00379 UTILS_PLLInitStruct->Prediv = LL_RCC_PREDIV_DIV_2; 00380 #endif /*RCC_PLLSRC_PREDIV1_SUPPORT*/ 00381 /* Calculate the new PLL output frequency */ 00382 pllfreq = UTILS_GetPLLOutputFrequency(HSI_VALUE, UTILS_PLLInitStruct); 00383 00384 /* Enable HSI if not enabled */ 00385 if (LL_RCC_HSI_IsReady() != 1U) 00386 { 00387 LL_RCC_HSI_Enable(); 00388 while (LL_RCC_HSI_IsReady() != 1U) 00389 { 00390 /* Wait for HSI ready */ 00391 } 00392 } 00393 00394 /* Configure PLL */ 00395 LL_RCC_PLL_ConfigDomain_SYS(LL_RCC_PLLSOURCE_HSI_DIV_2, UTILS_PLLInitStruct->PLLMul); 00396 00397 /* Enable PLL and switch system clock to PLL */ 00398 status = UTILS_EnablePLLAndSwitchSystem(pllfreq, UTILS_ClkInitStruct); 00399 } 00400 else 00401 { 00402 /* Current PLL configuration cannot be modified */ 00403 status = ERROR; 00404 } 00405 00406 return status; 00407 } 00408 00409 /** 00410 * @brief This function configures system clock with HSE as clock source of the PLL 00411 * @note The application need to ensure that PLL is disabled. 00412 * @note Function is based on the following formula: 00413 * - PLL output frequency = ((HSI frequency / PREDIV) * PLLMUL) 00414 * - PREDIV: Set to 2 for few devices 00415 * - PLLMUL: The application software must set correctly the PLL multiplication factor to 00416 * not exceed @ref UTILS_PLL_OUTPUT_MAX 00417 * @note FLASH latency can be modified through this function. 00418 * @param HSEFrequency Value between Min_Data = RCC_HSE_MIN and Max_Data = RCC_HSE_MAX 00419 * @param HSEBypass This parameter can be one of the following values: 00420 * @arg @ref LL_UTILS_HSEBYPASS_ON 00421 * @arg @ref LL_UTILS_HSEBYPASS_OFF 00422 * @param UTILS_PLLInitStruct pointer to a @ref LL_UTILS_PLLInitTypeDef structure that contains 00423 * the configuration information for the PLL. 00424 * @param UTILS_ClkInitStruct pointer to a @ref LL_UTILS_ClkInitTypeDef structure that contains 00425 * the configuration information for the BUS prescalers. 00426 * @retval An ErrorStatus enumeration value: 00427 * - SUCCESS: Max frequency configuration done 00428 * - ERROR: Max frequency configuration not done 00429 */ 00430 ErrorStatus LL_PLL_ConfigSystemClock_HSE(uint32_t HSEFrequency, uint32_t HSEBypass, 00431 LL_UTILS_PLLInitTypeDef *UTILS_PLLInitStruct, LL_UTILS_ClkInitTypeDef *UTILS_ClkInitStruct) 00432 { 00433 ErrorStatus status = SUCCESS; 00434 uint32_t pllfrequency = 0U; 00435 00436 /* Check the parameters */ 00437 assert_param(IS_LL_UTILS_HSE_FREQUENCY(HSEFrequency)); 00438 assert_param(IS_LL_UTILS_HSE_BYPASS(HSEBypass)); 00439 assert_param(IS_LL_UTILS_PREDIV_VALUE(UTILS_PLLInitStruct->Prediv)); 00440 00441 /* Calculate the new PLL output frequency */ 00442 pllfrequency = UTILS_GetPLLOutputFrequency(HSEFrequency, UTILS_PLLInitStruct); 00443 00444 /* Enable HSE if not enabled */ 00445 status = UTILS_PLL_HSE_ConfigSystemClock(HSEFrequency, HSEBypass, UTILS_PLLInitStruct, UTILS_ClkInitStruct); 00446 00447 /* Check if HSE is not enabled*/ 00448 if (status == SUCCESS) 00449 { 00450 /* Configure PLL */ 00451 LL_RCC_PLL_ConfigDomain_SYS((LL_RCC_PLLSOURCE_HSE | UTILS_PLLInitStruct->Prediv), UTILS_PLLInitStruct->PLLMul); 00452 00453 /* Enable PLL and switch system clock to PLL */ 00454 status = UTILS_EnablePLLAndSwitchSystem(pllfrequency, UTILS_ClkInitStruct); 00455 } 00456 00457 return status; 00458 } 00459 00460 #if defined(RCC_PLL2_SUPPORT) 00461 /** 00462 * @brief This function configures system clock with HSE as clock source of the PLL, via PLL2 00463 * @note The application need to ensure that PLL and PLL2 are disabled. 00464 * @note Function is based on the following formula: 00465 * - PLL output frequency = ((((HSE frequency / PREDIV2) * PLL2MUL) / PREDIV) * PLLMUL) 00466 * - PREDIV, PLLMUL, PREDIV2, PLL2MUL: The application software must set correctly the 00467 * PLL multiplication factor to not exceed @ref UTILS_PLL_OUTPUT_MAX 00468 * @note FLASH latency can be modified through this function. 00469 * @param HSEFrequency Value between Min_Data = RCC_HSE_MIN and Max_Data = RCC_HSE_MAX 00470 * @param HSEBypass This parameter can be one of the following values: 00471 * @arg @ref LL_UTILS_HSEBYPASS_ON 00472 * @arg @ref LL_UTILS_HSEBYPASS_OFF 00473 * @param UTILS_PLLInitStruct pointer to a @ref LL_UTILS_PLLInitTypeDef structure that contains 00474 * the configuration information for the PLL. 00475 * @param UTILS_PLL2InitStruct pointer to a @ref LL_UTILS_PLLInitTypeDef structure that contains 00476 * the configuration information for the PLL2. 00477 * @param UTILS_ClkInitStruct pointer to a @ref LL_UTILS_ClkInitTypeDef structure that contains 00478 * the configuration information for the BUS prescalers. 00479 * @retval An ErrorStatus enumeration value: 00480 * - SUCCESS: Max frequency configuration done 00481 * - ERROR: Max frequency configuration not done 00482 */ 00483 ErrorStatus LL_PLL_ConfigSystemClock_PLL2(uint32_t HSEFrequency, uint32_t HSEBypass, 00484 LL_UTILS_PLLInitTypeDef *UTILS_PLLInitStruct, 00485 LL_UTILS_PLLInitTypeDef *UTILS_PLL2InitStruct, 00486 LL_UTILS_ClkInitTypeDef *UTILS_ClkInitStruct) 00487 { 00488 ErrorStatus status = SUCCESS; 00489 uint32_t pllfrequency = 0U; 00490 00491 /* Check the parameters */ 00492 assert_param(IS_LL_UTILS_HSE_FREQUENCY(HSEFrequency)); 00493 assert_param(IS_LL_UTILS_HSE_BYPASS(HSEBypass)); 00494 assert_param(IS_LL_UTILS_PREDIV_VALUE(UTILS_PLLInitStruct->Prediv)); 00495 assert_param(IS_LL_UTILS_PREDIV2_VALUE(UTILS_PLL2InitStruct->Prediv)); 00496 00497 /* Calculate the new PLL output frequency */ 00498 pllfrequency = UTILS_GetPLLOutputFrequency(HSEFrequency, UTILS_PLLInitStruct); 00499 00500 /* Enable HSE if not enabled */ 00501 status = UTILS_PLL_HSE_ConfigSystemClock(HSEFrequency, HSEBypass, UTILS_PLLInitStruct, UTILS_ClkInitStruct); 00502 00503 /* Check if HSE is not enabled*/ 00504 if (status == SUCCESS) 00505 { 00506 /* Configure PLL */ 00507 LL_RCC_PLL_ConfigDomain_PLL2(UTILS_PLL2InitStruct->Prediv, UTILS_PLL2InitStruct->PLLMul); 00508 LL_RCC_PLL_ConfigDomain_SYS((LL_RCC_PLLSOURCE_PLL2 | UTILS_PLLInitStruct->Prediv), UTILS_PLLInitStruct->PLLMul); 00509 00510 /* Calculate the new PLL output frequency */ 00511 pllfrequency = UTILS_GetPLL2OutputFrequency(pllfrequency, UTILS_PLL2InitStruct); 00512 00513 /* Enable PLL and switch system clock to PLL */ 00514 status = UTILS_EnablePLLAndSwitchSystem(pllfrequency, UTILS_ClkInitStruct); 00515 } 00516 00517 return status; 00518 } 00519 #endif /* RCC_PLL2_SUPPORT */ 00520 00521 /** 00522 * @} 00523 */ 00524 00525 /** 00526 * @} 00527 */ 00528 00529 /** @addtogroup UTILS_LL_Private_Functions 00530 * @{ 00531 */ 00532 /** 00533 * @brief Function to check that PLL can be modified 00534 * @param PLL_InputFrequency PLL input frequency (in Hz) 00535 * @param UTILS_PLLInitStruct pointer to a @ref LL_UTILS_PLLInitTypeDef structure that contains 00536 * the configuration information for the PLL. 00537 * @retval PLL output frequency (in Hz) 00538 */ 00539 static uint32_t UTILS_GetPLLOutputFrequency(uint32_t PLL_InputFrequency, LL_UTILS_PLLInitTypeDef *UTILS_PLLInitStruct) 00540 { 00541 uint32_t pllfreq = 0U; 00542 00543 /* Check the parameters */ 00544 assert_param(IS_LL_UTILS_PLLMUL_VALUE(UTILS_PLLInitStruct->PLLMul)); 00545 00546 /* Check different PLL parameters according to RM */ 00547 #if defined (RCC_CFGR2_PREDIV1) 00548 pllfreq = __LL_RCC_CALC_PLLCLK_FREQ(PLL_InputFrequency / (UTILS_PLLInitStruct->Prediv + 1U), UTILS_PLLInitStruct->PLLMul); 00549 #else 00550 pllfreq = __LL_RCC_CALC_PLLCLK_FREQ(PLL_InputFrequency / ((UTILS_PLLInitStruct->Prediv >> RCC_CFGR_PLLXTPRE_Pos) + 1U), UTILS_PLLInitStruct->PLLMul); 00551 #endif /*RCC_CFGR2_PREDIV1SRC*/ 00552 assert_param(IS_LL_UTILS_PLL_FREQUENCY(pllfreq)); 00553 00554 return pllfreq; 00555 } 00556 00557 /** 00558 * @brief This function enable the HSE when it is used by PLL or PLL2 00559 * @note The application need to ensure that PLL is disabled. 00560 * @param HSEFrequency Value between Min_Data = RCC_HSE_MIN and Max_Data = RCC_HSE_MAX 00561 * @param HSEBypass This parameter can be one of the following values: 00562 * @arg @ref LL_UTILS_HSEBYPASS_ON 00563 * @arg @ref LL_UTILS_HSEBYPASS_OFF 00564 * @param UTILS_PLLInitStruct pointer to a @ref LL_UTILS_PLLInitTypeDef structure that contains 00565 * the configuration information for the PLL. 00566 * @param UTILS_ClkInitStruct pointer to a @ref LL_UTILS_ClkInitTypeDef structure that contains 00567 * the configuration information for the BUS prescalers. 00568 * @retval An ErrorStatus enumeration value: 00569 * - SUCCESS: HSE configuration done 00570 * - ERROR: HSE configuration not done 00571 */ 00572 static ErrorStatus UTILS_PLL_HSE_ConfigSystemClock(uint32_t PLL_InputFrequency, uint32_t HSEBypass, 00573 LL_UTILS_PLLInitTypeDef *UTILS_PLLInitStruct, 00574 LL_UTILS_ClkInitTypeDef *UTILS_ClkInitStruct) 00575 { 00576 ErrorStatus status = SUCCESS; 00577 00578 /* Check if one of the PLL is enabled */ 00579 if (UTILS_PLL_IsBusy() == SUCCESS) 00580 { 00581 /* Enable HSE if not enabled */ 00582 if (LL_RCC_HSE_IsReady() != 1U) 00583 { 00584 /* Check if need to enable HSE bypass feature or not */ 00585 if (HSEBypass == LL_UTILS_HSEBYPASS_ON) 00586 { 00587 LL_RCC_HSE_EnableBypass(); 00588 } 00589 else 00590 { 00591 LL_RCC_HSE_DisableBypass(); 00592 } 00593 00594 /* Enable HSE */ 00595 LL_RCC_HSE_Enable(); 00596 while (LL_RCC_HSE_IsReady() != 1U) 00597 { 00598 /* Wait for HSE ready */ 00599 } 00600 } 00601 } 00602 else 00603 { 00604 /* Current PLL configuration cannot be modified */ 00605 status = ERROR; 00606 } 00607 00608 return status; 00609 } 00610 00611 #if defined(RCC_PLL2_SUPPORT) 00612 /** 00613 * @brief Function to check that PLL2 can be modified 00614 * @param PLL2_InputFrequency PLL2 input frequency (in Hz) 00615 * @param UTILS_PLL2InitStruct pointer to a @ref LL_UTILS_PLLInitTypeDef structure that contains 00616 * the configuration information for the PLL. 00617 * @retval PLL2 output frequency (in Hz) 00618 */ 00619 static uint32_t UTILS_GetPLL2OutputFrequency(uint32_t PLL2_InputFrequency, LL_UTILS_PLLInitTypeDef *UTILS_PLL2InitStruct) 00620 { 00621 uint32_t pll2freq = 0U; 00622 00623 /* Check the parameters */ 00624 assert_param(IS_LL_UTILS_PLL2MUL_VALUE(UTILS_PLL2InitStruct->PLLMul)); 00625 assert_param(IS_LL_UTILS_PREDIV2_VALUE(UTILS_PLL2InitStruct->Prediv)); 00626 00627 /* Check different PLL2 parameters according to RM */ 00628 pll2freq = __LL_RCC_CALC_PLL2CLK_FREQ(PLL2_InputFrequency, UTILS_PLL2InitStruct->PLLMul, UTILS_PLL2InitStruct->Prediv); 00629 assert_param(IS_LL_UTILS_PLL2_FREQUENCY(pll2freq)); 00630 00631 return pll2freq; 00632 } 00633 #endif /* RCC_PLL2_SUPPORT */ 00634 00635 /** 00636 * @brief Function to check that PLL can be modified 00637 * @retval An ErrorStatus enumeration value: 00638 * - SUCCESS: PLL modification can be done 00639 * - ERROR: PLL is busy 00640 */ 00641 static ErrorStatus UTILS_PLL_IsBusy(void) 00642 { 00643 ErrorStatus status = SUCCESS; 00644 00645 /* Check if PLL is busy*/ 00646 if (LL_RCC_PLL_IsReady() != 0U) 00647 { 00648 /* PLL configuration cannot be modified */ 00649 status = ERROR; 00650 } 00651 #if defined(RCC_PLL2_SUPPORT) 00652 /* Check if PLL2 is busy*/ 00653 if (LL_RCC_PLL2_IsReady() != 0U) 00654 { 00655 /* PLL2 configuration cannot be modified */ 00656 status = ERROR; 00657 } 00658 #endif /* RCC_PLL2_SUPPORT */ 00659 00660 #if defined(RCC_PLLI2S_SUPPORT) 00661 /* Check if PLLI2S is busy*/ 00662 if (LL_RCC_PLLI2S_IsReady() != 0U) 00663 { 00664 /* PLLI2S configuration cannot be modified */ 00665 status = ERROR; 00666 } 00667 #endif /* RCC_PLLI2S_SUPPORT */ 00668 00669 return status; 00670 } 00671 00672 /** 00673 * @brief Function to enable PLL and switch system clock to PLL 00674 * @param SYSCLK_Frequency SYSCLK frequency 00675 * @param UTILS_ClkInitStruct pointer to a @ref LL_UTILS_ClkInitTypeDef structure that contains 00676 * the configuration information for the BUS prescalers. 00677 * @retval An ErrorStatus enumeration value: 00678 * - SUCCESS: No problem to switch system to PLL 00679 * - ERROR: Problem to switch system to PLL 00680 */ 00681 static ErrorStatus UTILS_EnablePLLAndSwitchSystem(uint32_t SYSCLK_Frequency, LL_UTILS_ClkInitTypeDef *UTILS_ClkInitStruct) 00682 { 00683 ErrorStatus status = SUCCESS; 00684 #if defined(FLASH_ACR_LATENCY) 00685 uint32_t sysclk_frequency_current = 0U; 00686 #endif /* FLASH_ACR_LATENCY */ 00687 00688 assert_param(IS_LL_UTILS_SYSCLK_DIV(UTILS_ClkInitStruct->AHBCLKDivider)); 00689 assert_param(IS_LL_UTILS_APB1_DIV(UTILS_ClkInitStruct->APB1CLKDivider)); 00690 assert_param(IS_LL_UTILS_APB2_DIV(UTILS_ClkInitStruct->APB2CLKDivider)); 00691 00692 #if defined(FLASH_ACR_LATENCY) 00693 /* Calculate current SYSCLK frequency */ 00694 sysclk_frequency_current = (SystemCoreClock << AHBPrescTable[LL_RCC_GetAHBPrescaler() >> RCC_CFGR_HPRE_Pos]); 00695 #endif /* FLASH_ACR_LATENCY */ 00696 00697 /* Increasing the number of wait states because of higher CPU frequency */ 00698 #if defined (FLASH_ACR_LATENCY) 00699 if (sysclk_frequency_current < SYSCLK_Frequency) 00700 { 00701 /* Set FLASH latency to highest latency */ 00702 status = LL_SetFlashLatency(SYSCLK_Frequency); 00703 } 00704 #endif /* FLASH_ACR_LATENCY */ 00705 00706 /* Update system clock configuration */ 00707 if (status == SUCCESS) 00708 { 00709 #if defined(RCC_PLL2_SUPPORT) 00710 if (LL_RCC_PLL_GetMainSource() != LL_RCC_PLLSOURCE_HSI_DIV_2) 00711 { 00712 /* Enable PLL2 */ 00713 LL_RCC_PLL2_Enable(); 00714 while (LL_RCC_PLL2_IsReady() != 1U) 00715 { 00716 /* Wait for PLL2 ready */ 00717 } 00718 } 00719 #endif /* RCC_PLL2_SUPPORT */ 00720 /* Enable PLL */ 00721 LL_RCC_PLL_Enable(); 00722 while (LL_RCC_PLL_IsReady() != 1U) 00723 { 00724 /* Wait for PLL ready */ 00725 } 00726 00727 /* Sysclk activation on the main PLL */ 00728 LL_RCC_SetAHBPrescaler(UTILS_ClkInitStruct->AHBCLKDivider); 00729 LL_RCC_SetSysClkSource(LL_RCC_SYS_CLKSOURCE_PLL); 00730 while (LL_RCC_GetSysClkSource() != LL_RCC_SYS_CLKSOURCE_STATUS_PLL) 00731 { 00732 /* Wait for system clock switch to PLL */ 00733 } 00734 00735 /* Set APB1 & APB2 prescaler*/ 00736 LL_RCC_SetAPB1Prescaler(UTILS_ClkInitStruct->APB1CLKDivider); 00737 LL_RCC_SetAPB2Prescaler(UTILS_ClkInitStruct->APB2CLKDivider); 00738 } 00739 00740 /* Decreasing the number of wait states because of lower CPU frequency */ 00741 #if defined (FLASH_ACR_LATENCY) 00742 if (sysclk_frequency_current > SYSCLK_Frequency) 00743 { 00744 /* Set FLASH latency to lowest latency */ 00745 status = LL_SetFlashLatency(SYSCLK_Frequency); 00746 } 00747 #endif /* FLASH_ACR_LATENCY */ 00748 00749 /* Update SystemCoreClock variable */ 00750 if (status == SUCCESS) 00751 { 00752 LL_SetSystemCoreClock(__LL_RCC_CALC_HCLK_FREQ(SYSCLK_Frequency, UTILS_ClkInitStruct->AHBCLKDivider)); 00753 } 00754 00755 return status; 00756 } 00757 00758 /** 00759 * @} 00760 */ 00761 00762 /** 00763 * @} 00764 */ 00765 00766 /** 00767 * @} 00768 */ 00769 00770 /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/