STM32L486xx HAL User Manual
|
00001 /** 00002 ****************************************************************************** 00003 * @file stm32l4xx_ll_utils.c 00004 * @author MCD Application Team 00005 * @brief UTILS LL module driver. 00006 ****************************************************************************** 00007 * @attention 00008 * 00009 * <h2><center>© COPYRIGHT(c) 2017 STMicroelectronics</center></h2> 00010 * 00011 * Redistribution and use in source and binary forms, with or without modification, 00012 * are permitted provided that the following conditions are met: 00013 * 1. Redistributions of source code must retain the above copyright notice, 00014 * this list of conditions and the following disclaimer. 00015 * 2. Redistributions in binary form must reproduce the above copyright notice, 00016 * this list of conditions and the following disclaimer in the documentation 00017 * and/or other materials provided with the distribution. 00018 * 3. Neither the name of STMicroelectronics nor the names of its contributors 00019 * may be used to endorse or promote products derived from this software 00020 * without specific prior written permission. 00021 * 00022 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 00023 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 00024 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 00025 * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE 00026 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 00027 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 00028 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 00029 * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 00030 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 00031 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 00032 * 00033 ****************************************************************************** 00034 */ 00035 /* Includes ------------------------------------------------------------------*/ 00036 #include "stm32l4xx_ll_utils.h" 00037 #include "stm32l4xx_ll_rcc.h" 00038 #include "stm32l4xx_ll_system.h" 00039 #include "stm32l4xx_ll_pwr.h" 00040 #ifdef USE_FULL_ASSERT 00041 #include "stm32_assert.h" 00042 #else 00043 #define assert_param(expr) ((void)0U) 00044 #endif /* USE_FULL_ASSERT */ 00045 00046 /** @addtogroup STM32L4xx_LL_Driver 00047 * @{ 00048 */ 00049 00050 /** @addtogroup UTILS_LL 00051 * @{ 00052 */ 00053 00054 /* Private types -------------------------------------------------------------*/ 00055 /* Private variables ---------------------------------------------------------*/ 00056 /* Private constants ---------------------------------------------------------*/ 00057 /** @addtogroup UTILS_LL_Private_Constants 00058 * @{ 00059 */ 00060 #if defined(STM32L4R5xx) || defined(STM32L4R7xx) || defined(STM32L4R9xx) || defined(STM32L4S5xx) || defined(STM32L4S7xx) || defined(STM32L4S9xx) 00061 #define UTILS_MAX_FREQUENCY_SCALE1 120000000U /*!< Maximum frequency for system clock at power scale1, in Hz */ 00062 #define UTILS_MAX_FREQUENCY_SCALE2 26000000U /*!< Maximum frequency for system clock at power scale2, in Hz */ 00063 #else 00064 #define UTILS_MAX_FREQUENCY_SCALE1 80000000U /*!< Maximum frequency for system clock at power scale1, in Hz */ 00065 #define UTILS_MAX_FREQUENCY_SCALE2 26000000U /*!< Maximum frequency for system clock at power scale2, in Hz */ 00066 #endif 00067 00068 /* Defines used for PLL range */ 00069 #define UTILS_PLLVCO_INPUT_MIN 4000000U /*!< Frequency min for PLLVCO input, in Hz */ 00070 #define UTILS_PLLVCO_INPUT_MAX 16000000U /*!< Frequency max for PLLVCO input, in Hz */ 00071 #define UTILS_PLLVCO_OUTPUT_MIN 64000000U /*!< Frequency min for PLLVCO output, in Hz */ 00072 #define UTILS_PLLVCO_OUTPUT_MAX 344000000U /*!< Frequency max for PLLVCO output, in Hz */ 00073 00074 /* Defines used for HSE range */ 00075 #define UTILS_HSE_FREQUENCY_MIN 4000000U /*!< Frequency min for HSE frequency, in Hz */ 00076 #define UTILS_HSE_FREQUENCY_MAX 48000000U /*!< Frequency max for HSE frequency, in Hz */ 00077 00078 /* Defines used for FLASH latency according to HCLK Frequency */ 00079 #if defined(STM32L4R5xx) || defined(STM32L4R7xx) || defined(STM32L4R9xx) || defined(STM32L4S5xx) || defined(STM32L4S7xx) || defined(STM32L4S9xx) 00080 #define UTILS_SCALE1_LATENCY1_FREQ 20000000U /*!< HCLK frequency to set FLASH latency 1 in power scale 1 */ 00081 #define UTILS_SCALE1_LATENCY2_FREQ 40000000U /*!< HCLK frequency to set FLASH latency 2 in power scale 1 */ 00082 #define UTILS_SCALE1_LATENCY3_FREQ 60000000U /*!< HCLK frequency to set FLASH latency 3 in power scale 1 */ 00083 #define UTILS_SCALE1_LATENCY4_FREQ 80000000U /*!< HCLK frequency to set FLASH latency 4 in power scale 1 */ 00084 #define UTILS_SCALE1_LATENCY5_FREQ 100000000U /*!< HCLK frequency to set FLASH latency 4 in power scale 1 */ 00085 #define UTILS_SCALE2_LATENCY1_FREQ 8000000U /*!< HCLK frequency to set FLASH latency 1 in power scale 2 */ 00086 #define UTILS_SCALE2_LATENCY2_FREQ 16000000U /*!< HCLK frequency to set FLASH latency 2 in power scale 2 */ 00087 #else 00088 #define UTILS_SCALE1_LATENCY1_FREQ 16000000U /*!< HCLK frequency to set FLASH latency 1 in power scale 1 */ 00089 #define UTILS_SCALE1_LATENCY2_FREQ 32000000U /*!< HCLK frequency to set FLASH latency 2 in power scale 1 */ 00090 #define UTILS_SCALE1_LATENCY3_FREQ 48000000U /*!< HCLK frequency to set FLASH latency 3 in power scale 1 */ 00091 #define UTILS_SCALE1_LATENCY4_FREQ 64000000U /*!< HCLK frequency to set FLASH latency 4 in power scale 1 */ 00092 #define UTILS_SCALE2_LATENCY1_FREQ 6000000U /*!< HCLK frequency to set FLASH latency 1 in power scale 2 */ 00093 #define UTILS_SCALE2_LATENCY2_FREQ 12000000U /*!< HCLK frequency to set FLASH latency 2 in power scale 2 */ 00094 #define UTILS_SCALE2_LATENCY3_FREQ 18000000U /*!< HCLK frequency to set FLASH latency 3 in power scale 2 */ 00095 #endif 00096 /** 00097 * @} 00098 */ 00099 00100 /* Private macros ------------------------------------------------------------*/ 00101 /** @addtogroup UTILS_LL_Private_Macros 00102 * @{ 00103 */ 00104 #define IS_LL_UTILS_SYSCLK_DIV(__VALUE__) (((__VALUE__) == LL_RCC_SYSCLK_DIV_1) \ 00105 || ((__VALUE__) == LL_RCC_SYSCLK_DIV_2) \ 00106 || ((__VALUE__) == LL_RCC_SYSCLK_DIV_4) \ 00107 || ((__VALUE__) == LL_RCC_SYSCLK_DIV_8) \ 00108 || ((__VALUE__) == LL_RCC_SYSCLK_DIV_16) \ 00109 || ((__VALUE__) == LL_RCC_SYSCLK_DIV_64) \ 00110 || ((__VALUE__) == LL_RCC_SYSCLK_DIV_128) \ 00111 || ((__VALUE__) == LL_RCC_SYSCLK_DIV_256) \ 00112 || ((__VALUE__) == LL_RCC_SYSCLK_DIV_512)) 00113 00114 #define IS_LL_UTILS_APB1_DIV(__VALUE__) (((__VALUE__) == LL_RCC_APB1_DIV_1) \ 00115 || ((__VALUE__) == LL_RCC_APB1_DIV_2) \ 00116 || ((__VALUE__) == LL_RCC_APB1_DIV_4) \ 00117 || ((__VALUE__) == LL_RCC_APB1_DIV_8) \ 00118 || ((__VALUE__) == LL_RCC_APB1_DIV_16)) 00119 00120 #define IS_LL_UTILS_APB2_DIV(__VALUE__) (((__VALUE__) == LL_RCC_APB2_DIV_1) \ 00121 || ((__VALUE__) == LL_RCC_APB2_DIV_2) \ 00122 || ((__VALUE__) == LL_RCC_APB2_DIV_4) \ 00123 || ((__VALUE__) == LL_RCC_APB2_DIV_8) \ 00124 || ((__VALUE__) == LL_RCC_APB2_DIV_16)) 00125 00126 #define IS_LL_UTILS_PLLM_VALUE(__VALUE__) (((__VALUE__) == LL_RCC_PLLM_DIV_1) \ 00127 || ((__VALUE__) == LL_RCC_PLLM_DIV_2) \ 00128 || ((__VALUE__) == LL_RCC_PLLM_DIV_3) \ 00129 || ((__VALUE__) == LL_RCC_PLLM_DIV_4) \ 00130 || ((__VALUE__) == LL_RCC_PLLM_DIV_5) \ 00131 || ((__VALUE__) == LL_RCC_PLLM_DIV_6) \ 00132 || ((__VALUE__) == LL_RCC_PLLM_DIV_7) \ 00133 || ((__VALUE__) == LL_RCC_PLLM_DIV_8)) 00134 00135 #define IS_LL_UTILS_PLLN_VALUE(__VALUE__) ((8 <= (__VALUE__)) && ((__VALUE__) <= 86)) 00136 00137 #define IS_LL_UTILS_PLLR_VALUE(__VALUE__) (((__VALUE__) == LL_RCC_PLLR_DIV_2) \ 00138 || ((__VALUE__) == LL_RCC_PLLR_DIV_4) \ 00139 || ((__VALUE__) == LL_RCC_PLLR_DIV_6) \ 00140 || ((__VALUE__) == LL_RCC_PLLR_DIV_8)) 00141 00142 #define IS_LL_UTILS_PLLVCO_INPUT(__VALUE__) ((UTILS_PLLVCO_INPUT_MIN <= (__VALUE__)) && ((__VALUE__) <= UTILS_PLLVCO_INPUT_MAX)) 00143 00144 #define IS_LL_UTILS_PLLVCO_OUTPUT(__VALUE__) ((UTILS_PLLVCO_OUTPUT_MIN <= (__VALUE__)) && ((__VALUE__) <= UTILS_PLLVCO_OUTPUT_MAX)) 00145 00146 #define IS_LL_UTILS_PLL_FREQUENCY(__VALUE__) ((LL_PWR_GetRegulVoltageScaling() == LL_PWR_REGU_VOLTAGE_SCALE1) ? ((__VALUE__) <= UTILS_MAX_FREQUENCY_SCALE1) : \ 00147 ((__VALUE__) <= UTILS_MAX_FREQUENCY_SCALE2)) 00148 00149 #define IS_LL_UTILS_HSE_BYPASS(__STATE__) (((__STATE__) == LL_UTILS_HSEBYPASS_ON) \ 00150 || ((__STATE__) == LL_UTILS_HSEBYPASS_OFF)) 00151 00152 #define IS_LL_UTILS_HSE_FREQUENCY(__FREQUENCY__) (((__FREQUENCY__) >= UTILS_HSE_FREQUENCY_MIN) && ((__FREQUENCY__) <= UTILS_HSE_FREQUENCY_MAX)) 00153 /** 00154 * @} 00155 */ 00156 /* Private function prototypes -----------------------------------------------*/ 00157 /** @defgroup UTILS_LL_Private_Functions UTILS Private functions 00158 * @{ 00159 */ 00160 static uint32_t UTILS_GetPLLOutputFrequency(uint32_t PLL_InputFrequency, 00161 LL_UTILS_PLLInitTypeDef *UTILS_PLLInitStruct); 00162 static ErrorStatus UTILS_SetFlashLatency(uint32_t HCLK_Frequency); 00163 static ErrorStatus UTILS_EnablePLLAndSwitchSystem(uint32_t SYSCLK_Frequency, LL_UTILS_ClkInitTypeDef *UTILS_ClkInitStruct); 00164 static ErrorStatus UTILS_PLL_IsBusy(void); 00165 /** 00166 * @} 00167 */ 00168 00169 /* Exported functions --------------------------------------------------------*/ 00170 /** @addtogroup UTILS_LL_Exported_Functions 00171 * @{ 00172 */ 00173 00174 /** @addtogroup UTILS_LL_EF_DELAY 00175 * @{ 00176 */ 00177 00178 /** 00179 * @brief This function configures the Cortex-M SysTick source to have 1ms time base. 00180 * @note When a RTOS is used, it is recommended to avoid changing the Systick 00181 * configuration by calling this function, for a delay use rather osDelay RTOS service. 00182 * @param HCLKFrequency HCLK frequency in Hz 00183 * @note HCLK frequency can be calculated thanks to RCC helper macro or function @ref LL_RCC_GetSystemClocksFreq 00184 * @retval None 00185 */ 00186 void LL_Init1msTick(uint32_t HCLKFrequency) 00187 { 00188 /* Use frequency provided in argument */ 00189 LL_InitTick(HCLKFrequency, 1000U); 00190 } 00191 00192 /** 00193 * @brief This function provides accurate delay (in milliseconds) based 00194 * on SysTick counter flag 00195 * @note When a RTOS is used, it is recommended to avoid using blocking delay 00196 * and use rather osDelay service. 00197 * @note To respect 1ms timebase, user should call @ref LL_Init1msTick function which 00198 * will configure Systick to 1ms 00199 * @param Delay specifies the delay time length, in milliseconds. 00200 * @retval None 00201 */ 00202 void LL_mDelay(uint32_t Delay) 00203 { 00204 __IO uint32_t tmp = SysTick->CTRL; /* Clear the COUNTFLAG first */ 00205 /* Add this code to indicate that local variable is not used */ 00206 ((void)tmp); 00207 00208 /* Add a period to guaranty minimum wait */ 00209 if(Delay < LL_MAX_DELAY) 00210 { 00211 Delay++; 00212 } 00213 00214 while (Delay) 00215 { 00216 if((SysTick->CTRL & SysTick_CTRL_COUNTFLAG_Msk) != 0U) 00217 { 00218 Delay--; 00219 } 00220 } 00221 } 00222 00223 /** 00224 * @} 00225 */ 00226 00227 /** @addtogroup UTILS_EF_SYSTEM 00228 * @brief System Configuration functions 00229 * 00230 @verbatim 00231 =============================================================================== 00232 ##### System Configuration functions ##### 00233 =============================================================================== 00234 [..] 00235 System, AHB and APB buses clocks configuration 00236 00237 (+) The maximum frequency of the SYSCLK, HCLK, PCLK1 and PCLK2 is 00238 120000000 Hz for STM32L4Rx/STM32L4Sx devices and 80000000 Hz for others. 00239 @endverbatim 00240 @internal 00241 Depending on the device voltage range, the maximum frequency should be 00242 adapted accordingly: 00243 00244 (++) Table 1. HCLK clock frequency for STM32L4Rx/STM32L4Sx devices 00245 (++) +--------------------------------------------------------+ 00246 (++) | Latency | HCLK clock frequency (MHz) | 00247 (++) | |--------------------------------------| 00248 (++) | | voltage range 1 | voltage range 2 | 00249 (++) | | 1.2 V | 1.0 V | 00250 (++) |-----------------|-------------------|------------------| 00251 (++) |0WS(1 CPU cycles)| 0 < HCLK <= 20 | 0 < HCLK <= 8 | 00252 (++) |-----------------|-------------------|------------------| 00253 (++) |1WS(2 CPU cycles)| 20 < HCLK <= 40 | 8 < HCLK <= 16 | 00254 (++) |-----------------|-------------------|------------------| 00255 (++) |2WS(3 CPU cycles)| 40 < HCLK <= 60 | 16 < HCLK <= 26 | 00256 (++) |-----------------|-------------------|------------------| 00257 (++) |3WS(4 CPU cycles)| 60 < HCLK <= 80 | 16 < HCLK <= 26 | 00258 (++) |-----------------|-------------------|------------------| 00259 (++) |4WS(5 CPU cycles)| 80 < HCLK <= 100 | 16 < HCLK <= 26 | 00260 (++) |-----------------|-------------------|------------------| 00261 (++) |5WS(6 CPU cycles)| 100 < HCLK <= 120 | 16 < HCLK <= 26 | 00262 (++) +--------------------------------------------------------+ 00263 00264 (++) Table 2. HCLK clock frequency for other STM32L4 devices 00265 (++) +-------------------------------------------------------+ 00266 (++) | Latency | HCLK clock frequency (MHz) | 00267 (++) | |-------------------------------------| 00268 (++) | | voltage range 1 | voltage range 2 | 00269 (++) | | 1.2 V | 1.0 V | 00270 (++) |-----------------|------------------|------------------| 00271 (++) |0WS(1 CPU cycles)| 0 < HCLK <= 16 | 0 < HCLK <= 6 | 00272 (++) |-----------------|------------------|------------------| 00273 (++) |1WS(2 CPU cycles)| 16 < HCLK <= 32 | 6 < HCLK <= 12 | 00274 (++) |-----------------|------------------|------------------| 00275 (++) |2WS(3 CPU cycles)| 32 < HCLK <= 48 | 12 < HCLK <= 18 | 00276 (++) |-----------------|------------------|------------------| 00277 (++) |3WS(4 CPU cycles)| 48 < HCLK <= 64 | 18 < HCLK <= 26 | 00278 (++) |-----------------|------------------|------------------| 00279 (++) |4WS(5 CPU cycles)| 64 < HCLK <= 80 | 18 < HCLK <= 26 | 00280 (++) +-------------------------------------------------------+ 00281 00282 @endinternal 00283 * @{ 00284 */ 00285 00286 /** 00287 * @brief This function sets directly SystemCoreClock CMSIS variable. 00288 * @note Variable can be calculated also through SystemCoreClockUpdate function. 00289 * @param HCLKFrequency HCLK frequency in Hz (can be calculated thanks to RCC helper macro) 00290 * @retval None 00291 */ 00292 void LL_SetSystemCoreClock(uint32_t HCLKFrequency) 00293 { 00294 /* HCLK clock frequency */ 00295 SystemCoreClock = HCLKFrequency; 00296 } 00297 00298 /** 00299 * @brief This function configures system clock with MSI as clock source of the PLL 00300 * @note The application needs to ensure that PLL, PLLSAI1 and/or PLLSAI2 are disabled. 00301 * @note Function is based on the following formula: 00302 * - PLL output frequency = (((MSI frequency / PLLM) * PLLN) / PLLR) 00303 * - PLLM: ensure that the VCO input frequency ranges from 4 to 16 MHz (PLLVCO_input = MSI frequency / PLLM) 00304 * - PLLN: ensure that the VCO output frequency is between 64 and 344 MHz (PLLVCO_output = PLLVCO_input * PLLN) 00305 * - PLLR: ensure that max frequency at 120000000 Hz is reached (PLLVCO_output / PLLR) 00306 * @param UTILS_PLLInitStruct pointer to a @ref LL_UTILS_PLLInitTypeDef structure that contains 00307 * the configuration information for the PLL. 00308 * @param UTILS_ClkInitStruct pointer to a @ref LL_UTILS_ClkInitTypeDef structure that contains 00309 * the configuration information for the BUS prescalers. 00310 * @retval An ErrorStatus enumeration value: 00311 * - SUCCESS: Max frequency configuration done 00312 * - ERROR: Max frequency configuration not done 00313 */ 00314 ErrorStatus LL_PLL_ConfigSystemClock_MSI(LL_UTILS_PLLInitTypeDef *UTILS_PLLInitStruct, 00315 LL_UTILS_ClkInitTypeDef *UTILS_ClkInitStruct) 00316 { 00317 ErrorStatus status = SUCCESS; 00318 uint32_t pllfreq = 0U, msi_range = 0U; 00319 #if defined(STM32L4R5xx) || defined(STM32L4R7xx) || defined(STM32L4R9xx) || defined(STM32L4S5xx) || defined(STM32L4S7xx) || defined(STM32L4S9xx) 00320 uint32_t hpre = 0U; 00321 #endif 00322 00323 /* Check if one of the PLL is enabled */ 00324 if(UTILS_PLL_IsBusy() == SUCCESS) 00325 { 00326 /* Get the current MSI range */ 00327 if(LL_RCC_MSI_IsEnabledRangeSelect()) 00328 { 00329 msi_range = LL_RCC_MSI_GetRange(); 00330 switch (msi_range) 00331 { 00332 case LL_RCC_MSIRANGE_0: /* MSI = 100 KHz */ 00333 case LL_RCC_MSIRANGE_1: /* MSI = 200 KHz */ 00334 case LL_RCC_MSIRANGE_2: /* MSI = 400 KHz */ 00335 case LL_RCC_MSIRANGE_3: /* MSI = 800 KHz */ 00336 case LL_RCC_MSIRANGE_4: /* MSI = 1 MHz */ 00337 case LL_RCC_MSIRANGE_5: /* MSI = 2 MHz */ 00338 /* PLLVCO input frequency is not in the range from 4 to 16 MHz*/ 00339 status = ERROR; 00340 break; 00341 00342 case LL_RCC_MSIRANGE_6: /* MSI = 4 MHz */ 00343 case LL_RCC_MSIRANGE_7: /* MSI = 8 MHz */ 00344 case LL_RCC_MSIRANGE_8: /* MSI = 16 MHz */ 00345 case LL_RCC_MSIRANGE_9: /* MSI = 24 MHz */ 00346 case LL_RCC_MSIRANGE_10: /* MSI = 32 MHz */ 00347 case LL_RCC_MSIRANGE_11: /* MSI = 48 MHz */ 00348 default: 00349 break; 00350 } 00351 } 00352 else 00353 { 00354 msi_range = LL_RCC_MSI_GetRangeAfterStandby(); 00355 switch (msi_range) 00356 { 00357 case LL_RCC_MSISRANGE_4: /* MSI = 1 MHz */ 00358 case LL_RCC_MSISRANGE_5: /* MSI = 2 MHz */ 00359 /* PLLVCO input frequency is not in the range from 4 to 16 MHz*/ 00360 status = ERROR; 00361 break; 00362 00363 case LL_RCC_MSISRANGE_7: /* MSI = 8 MHz */ 00364 case LL_RCC_MSISRANGE_6: /* MSI = 4 MHz */ 00365 default: 00366 break; 00367 } 00368 } 00369 00370 /* Main PLL configuration and activation */ 00371 if(status != ERROR) 00372 { 00373 /* Calculate the new PLL output frequency */ 00374 pllfreq = UTILS_GetPLLOutputFrequency(__LL_RCC_CALC_MSI_FREQ(LL_RCC_MSI_IsEnabledRangeSelect(), msi_range), 00375 UTILS_PLLInitStruct); 00376 00377 /* Enable MSI if not enabled */ 00378 if(LL_RCC_MSI_IsReady() != 1U) 00379 { 00380 LL_RCC_MSI_Enable(); 00381 while ((LL_RCC_MSI_IsReady() != 1U)) 00382 { 00383 /* Wait for MSI ready */ 00384 } 00385 } 00386 00387 /* Configure PLL */ 00388 LL_RCC_PLL_ConfigDomain_SYS(LL_RCC_PLLSOURCE_MSI, UTILS_PLLInitStruct->PLLM, UTILS_PLLInitStruct->PLLN, 00389 UTILS_PLLInitStruct->PLLR); 00390 00391 #if defined(STM32L4R5xx) || defined(STM32L4R7xx) || defined(STM32L4R9xx) || defined(STM32L4S5xx) || defined(STM32L4S7xx) || defined(STM32L4S9xx) 00392 /* Prevent undershoot at highest frequency by applying intermediate AHB prescaler 2 */ 00393 if(pllfreq > 80000000U) 00394 { 00395 hpre = UTILS_ClkInitStruct->AHBCLKDivider; 00396 if(hpre == LL_RCC_SYSCLK_DIV_1) 00397 { 00398 UTILS_ClkInitStruct->AHBCLKDivider = LL_RCC_SYSCLK_DIV_2; 00399 } 00400 } 00401 #endif 00402 /* Enable PLL and switch system clock to PLL */ 00403 status = UTILS_EnablePLLAndSwitchSystem(pllfreq, UTILS_ClkInitStruct); 00404 00405 #if defined(STM32L4R5xx) || defined(STM32L4R7xx) || defined(STM32L4R9xx) || defined(STM32L4S5xx) || defined(STM32L4S7xx) || defined(STM32L4S9xx) 00406 /* Apply definitive AHB prescaler value if necessary */ 00407 if((status == SUCCESS) && (hpre != 0U)) 00408 { 00409 UTILS_ClkInitStruct->AHBCLKDivider = LL_RCC_SYSCLK_DIV_1; 00410 LL_RCC_SetAHBPrescaler(UTILS_ClkInitStruct->AHBCLKDivider); 00411 } 00412 #endif 00413 } 00414 } 00415 else 00416 { 00417 /* Current PLL configuration cannot be modified */ 00418 status = ERROR; 00419 } 00420 00421 return status; 00422 } 00423 00424 /** 00425 * @brief This function configures system clock at maximum frequency with HSI as clock source of the PLL 00426 * @note The application need to ensure that PLL, PLLSAI1 and/or PLLSAI2 are disabled. 00427 * @note Function is based on the following formula: 00428 * - PLL output frequency = (((HSI frequency / PLLM) * PLLN) / PLLR) 00429 * - PLLM: ensure that the VCO input frequency ranges from 4 to 16 MHz (PLLVCO_input = HSI frequency / PLLM) 00430 * - PLLN: ensure that the VCO output frequency is between 64 and 344 MHz (PLLVCO_output = PLLVCO_input * PLLN) 00431 * - PLLR: ensure that max frequency at 120000000 Hz is reach (PLLVCO_output / PLLR) 00432 * @param UTILS_PLLInitStruct pointer to a @ref LL_UTILS_PLLInitTypeDef structure that contains 00433 * the configuration information for the PLL. 00434 * @param UTILS_ClkInitStruct pointer to a @ref LL_UTILS_ClkInitTypeDef structure that contains 00435 * the configuration information for the BUS prescalers. 00436 * @retval An ErrorStatus enumeration value: 00437 * - SUCCESS: Max frequency configuration done 00438 * - ERROR: Max frequency configuration not done 00439 */ 00440 ErrorStatus LL_PLL_ConfigSystemClock_HSI(LL_UTILS_PLLInitTypeDef *UTILS_PLLInitStruct, 00441 LL_UTILS_ClkInitTypeDef *UTILS_ClkInitStruct) 00442 { 00443 ErrorStatus status = SUCCESS; 00444 uint32_t pllfreq = 0U; 00445 #if defined(STM32L4R5xx) || defined(STM32L4R7xx) || defined(STM32L4R9xx) || defined(STM32L4S5xx) || defined(STM32L4S7xx) || defined(STM32L4S9xx) 00446 uint32_t hpre = 0U; 00447 #endif 00448 00449 /* Check if one of the PLL is enabled */ 00450 if(UTILS_PLL_IsBusy() == SUCCESS) 00451 { 00452 /* Calculate the new PLL output frequency */ 00453 pllfreq = UTILS_GetPLLOutputFrequency(HSI_VALUE, UTILS_PLLInitStruct); 00454 00455 /* Enable HSI if not enabled */ 00456 if(LL_RCC_HSI_IsReady() != 1U) 00457 { 00458 LL_RCC_HSI_Enable(); 00459 while (LL_RCC_HSI_IsReady() != 1U) 00460 { 00461 /* Wait for HSI ready */ 00462 } 00463 } 00464 00465 /* Configure PLL */ 00466 LL_RCC_PLL_ConfigDomain_SYS(LL_RCC_PLLSOURCE_HSI, UTILS_PLLInitStruct->PLLM, UTILS_PLLInitStruct->PLLN, 00467 UTILS_PLLInitStruct->PLLR); 00468 00469 #if defined(STM32L4R5xx) || defined(STM32L4R7xx) || defined(STM32L4R9xx) || defined(STM32L4S5xx) || defined(STM32L4S7xx) || defined(STM32L4S9xx) 00470 /* Prevent undershoot at highest frequency by applying intermediate AHB prescaler 2 */ 00471 if(pllfreq > 80000000U) 00472 { 00473 hpre = UTILS_ClkInitStruct->AHBCLKDivider; 00474 if(hpre == LL_RCC_SYSCLK_DIV_1) 00475 { 00476 UTILS_ClkInitStruct->AHBCLKDivider = LL_RCC_SYSCLK_DIV_2; 00477 } 00478 } 00479 #endif 00480 /* Enable PLL and switch system clock to PLL */ 00481 status = UTILS_EnablePLLAndSwitchSystem(pllfreq, UTILS_ClkInitStruct); 00482 00483 #if defined(STM32L4R5xx) || defined(STM32L4R7xx) || defined(STM32L4R9xx) || defined(STM32L4S5xx) || defined(STM32L4S7xx) || defined(STM32L4S9xx) 00484 /* Apply definitive AHB prescaler value if necessary */ 00485 if((status == SUCCESS) && (hpre != 0U)) 00486 { 00487 UTILS_ClkInitStruct->AHBCLKDivider = LL_RCC_SYSCLK_DIV_1; 00488 LL_RCC_SetAHBPrescaler(UTILS_ClkInitStruct->AHBCLKDivider); 00489 } 00490 #endif 00491 } 00492 else 00493 { 00494 /* Current PLL configuration cannot be modified */ 00495 status = ERROR; 00496 } 00497 00498 return status; 00499 } 00500 00501 /** 00502 * @brief This function configures system clock with HSE as clock source of the PLL 00503 * @note The application need to ensure that PLL, PLLSAI1 and/or PLLSAI2 are disabled. 00504 * @note Function is based on the following formula: 00505 * - PLL output frequency = (((HSE frequency / PLLM) * PLLN) / PLLR) 00506 * - PLLM: ensure that the VCO input frequency ranges from 4 to 16 MHz (PLLVCO_input = HSE frequency / PLLM) 00507 * - PLLN: ensure that the VCO output frequency is between 64 and 344 MHz (PLLVCO_output = PLLVCO_input * PLLN) 00508 * - PLLR: ensure that max frequency at 120000000 Hz is reached (PLLVCO_output / PLLR) 00509 * @param HSEFrequency Value between Min_Data = 4000000 and Max_Data = 48000000 00510 * @param HSEBypass This parameter can be one of the following values: 00511 * @arg @ref LL_UTILS_HSEBYPASS_ON 00512 * @arg @ref LL_UTILS_HSEBYPASS_OFF 00513 * @param UTILS_PLLInitStruct pointer to a @ref LL_UTILS_PLLInitTypeDef structure that contains 00514 * the configuration information for the PLL. 00515 * @param UTILS_ClkInitStruct pointer to a @ref LL_UTILS_ClkInitTypeDef structure that contains 00516 * the configuration information for the BUS prescalers. 00517 * @retval An ErrorStatus enumeration value: 00518 * - SUCCESS: Max frequency configuration done 00519 * - ERROR: Max frequency configuration not done 00520 */ 00521 ErrorStatus LL_PLL_ConfigSystemClock_HSE(uint32_t HSEFrequency, uint32_t HSEBypass, 00522 LL_UTILS_PLLInitTypeDef *UTILS_PLLInitStruct, LL_UTILS_ClkInitTypeDef *UTILS_ClkInitStruct) 00523 { 00524 ErrorStatus status = SUCCESS; 00525 uint32_t pllfreq = 0U; 00526 #if defined(STM32L4R5xx) || defined(STM32L4R7xx) || defined(STM32L4R9xx) || defined(STM32L4S5xx) || defined(STM32L4S7xx) || defined(STM32L4S9xx) 00527 uint32_t hpre = 0U; 00528 #endif 00529 00530 /* Check the parameters */ 00531 assert_param(IS_LL_UTILS_HSE_FREQUENCY(HSEFrequency)); 00532 assert_param(IS_LL_UTILS_HSE_BYPASS(HSEBypass)); 00533 00534 /* Check if one of the PLL is enabled */ 00535 if(UTILS_PLL_IsBusy() == SUCCESS) 00536 { 00537 /* Calculate the new PLL output frequency */ 00538 pllfreq = UTILS_GetPLLOutputFrequency(HSEFrequency, UTILS_PLLInitStruct); 00539 00540 /* Enable HSE if not enabled */ 00541 if(LL_RCC_HSE_IsReady() != 1U) 00542 { 00543 /* Check if need to enable HSE bypass feature or not */ 00544 if(HSEBypass == LL_UTILS_HSEBYPASS_ON) 00545 { 00546 LL_RCC_HSE_EnableBypass(); 00547 } 00548 else 00549 { 00550 LL_RCC_HSE_DisableBypass(); 00551 } 00552 00553 /* Enable HSE */ 00554 LL_RCC_HSE_Enable(); 00555 while (LL_RCC_HSE_IsReady() != 1U) 00556 { 00557 /* Wait for HSE ready */ 00558 } 00559 } 00560 00561 /* Configure PLL */ 00562 LL_RCC_PLL_ConfigDomain_SYS(LL_RCC_PLLSOURCE_HSE, UTILS_PLLInitStruct->PLLM, UTILS_PLLInitStruct->PLLN, 00563 UTILS_PLLInitStruct->PLLR); 00564 00565 #if defined(STM32L4R5xx) || defined(STM32L4R7xx) || defined(STM32L4R9xx) || defined(STM32L4S5xx) || defined(STM32L4S7xx) || defined(STM32L4S9xx) 00566 /* Prevent undershoot at highest frequency by applying intermediate AHB prescaler 2 */ 00567 if(pllfreq > 80000000U) 00568 { 00569 hpre = UTILS_ClkInitStruct->AHBCLKDivider; 00570 if(hpre == LL_RCC_SYSCLK_DIV_1) 00571 { 00572 UTILS_ClkInitStruct->AHBCLKDivider = LL_RCC_SYSCLK_DIV_2; 00573 } 00574 } 00575 #endif 00576 /* Enable PLL and switch system clock to PLL */ 00577 status = UTILS_EnablePLLAndSwitchSystem(pllfreq, UTILS_ClkInitStruct); 00578 00579 #if defined(STM32L4R5xx) || defined(STM32L4R7xx) || defined(STM32L4R9xx) || defined(STM32L4S5xx) || defined(STM32L4S7xx) || defined(STM32L4S9xx) 00580 /* Apply definitive AHB prescaler value if necessary */ 00581 if((status == SUCCESS) && (hpre != 0U)) 00582 { 00583 UTILS_ClkInitStruct->AHBCLKDivider = LL_RCC_SYSCLK_DIV_1; 00584 LL_RCC_SetAHBPrescaler(UTILS_ClkInitStruct->AHBCLKDivider); 00585 } 00586 #endif 00587 } 00588 else 00589 { 00590 /* Current PLL configuration cannot be modified */ 00591 status = ERROR; 00592 } 00593 00594 return status; 00595 } 00596 00597 /** 00598 * @} 00599 */ 00600 00601 /** 00602 * @} 00603 */ 00604 00605 /** @addtogroup UTILS_LL_Private_Functions 00606 * @{ 00607 */ 00608 /** 00609 * @brief Update number of Flash wait states in line with new frequency and current 00610 voltage range. 00611 * @param HCLK_Frequency HCLK frequency 00612 * @retval An ErrorStatus enumeration value: 00613 * - SUCCESS: Latency has been modified 00614 * - ERROR: Latency cannot be modified 00615 */ 00616 static ErrorStatus UTILS_SetFlashLatency(uint32_t HCLK_Frequency) 00617 { 00618 ErrorStatus status = SUCCESS; 00619 00620 uint32_t latency = LL_FLASH_LATENCY_0; /* default value 0WS */ 00621 00622 /* Frequency cannot be equal to 0 */ 00623 if(HCLK_Frequency == 0U) 00624 { 00625 status = ERROR; 00626 } 00627 else 00628 { 00629 if(LL_PWR_GetRegulVoltageScaling() == LL_PWR_REGU_VOLTAGE_SCALE1) 00630 { 00631 #if defined(STM32L4R5xx) || defined(STM32L4R7xx) || defined(STM32L4R9xx) || defined(STM32L4S5xx) || defined(STM32L4S7xx) || defined(STM32L4S9xx) 00632 if(HCLK_Frequency > UTILS_SCALE1_LATENCY5_FREQ) 00633 { 00634 /* 100 < HCLK <= 120 => 5WS (6 CPU cycles) */ 00635 latency = LL_FLASH_LATENCY_5; 00636 } 00637 else if(HCLK_Frequency > UTILS_SCALE1_LATENCY4_FREQ) 00638 { 00639 /* 80 < HCLK <= 100 => 4WS (5 CPU cycles) */ 00640 latency = LL_FLASH_LATENCY_4; 00641 } 00642 else if(HCLK_Frequency > UTILS_SCALE1_LATENCY3_FREQ) 00643 { 00644 /* 60 < HCLK <= 80 => 3WS (4 CPU cycles) */ 00645 latency = LL_FLASH_LATENCY_3; 00646 } 00647 else if(HCLK_Frequency > UTILS_SCALE1_LATENCY2_FREQ) 00648 { 00649 /* 40 < HCLK <= 20 => 2WS (3 CPU cycles) */ 00650 latency = LL_FLASH_LATENCY_2; 00651 } 00652 else 00653 { 00654 if(HCLK_Frequency > UTILS_SCALE1_LATENCY1_FREQ) 00655 { 00656 /* 20 < HCLK <= 40 => 1WS (2 CPU cycles) */ 00657 latency = LL_FLASH_LATENCY_1; 00658 } 00659 /* else HCLK_Frequency <= 10MHz default LL_FLASH_LATENCY_0 0WS */ 00660 } 00661 #else 00662 if(HCLK_Frequency > UTILS_SCALE1_LATENCY4_FREQ) 00663 { 00664 /* 64 < HCLK <= 80 => 4WS (5 CPU cycles) */ 00665 latency = LL_FLASH_LATENCY_4; 00666 } 00667 else if(HCLK_Frequency > UTILS_SCALE1_LATENCY3_FREQ) 00668 { 00669 /* 48 < HCLK <= 64 => 3WS (4 CPU cycles) */ 00670 latency = LL_FLASH_LATENCY_3; 00671 } 00672 else if(HCLK_Frequency > UTILS_SCALE1_LATENCY2_FREQ) 00673 { 00674 /* 32 < HCLK <= 48 => 2WS (3 CPU cycles) */ 00675 latency = LL_FLASH_LATENCY_2; 00676 } 00677 else 00678 { 00679 if(HCLK_Frequency > UTILS_SCALE1_LATENCY1_FREQ) 00680 { 00681 /* 16 < HCLK <= 32 => 1WS (2 CPU cycles) */ 00682 latency = LL_FLASH_LATENCY_1; 00683 } 00684 /* else HCLK_Frequency <= 16MHz default LL_FLASH_LATENCY_0 0WS */ 00685 } 00686 #endif 00687 } 00688 else /* SCALE2 */ 00689 { 00690 #if defined(STM32L4R5xx) || defined(STM32L4R7xx) || defined(STM32L4R9xx) || defined(STM32L4S5xx) || defined(STM32L4S7xx) || defined(STM32L4S9xx) 00691 if(HCLK_Frequency > UTILS_SCALE2_LATENCY2_FREQ) 00692 { 00693 /* 16 < HCLK <= 26 => 2WS (3 CPU cycles) */ 00694 latency = LL_FLASH_LATENCY_2; 00695 } 00696 else 00697 { 00698 if(HCLK_Frequency > UTILS_SCALE2_LATENCY1_FREQ) 00699 { 00700 /* 8 < HCLK <= 16 => 1WS (2 CPU cycles) */ 00701 latency = LL_FLASH_LATENCY_1; 00702 } 00703 /* else HCLK_Frequency <= 8MHz default LL_FLASH_LATENCY_0 0WS */ 00704 } 00705 #else 00706 if(HCLK_Frequency > UTILS_SCALE2_LATENCY3_FREQ) 00707 { 00708 /* 18 < HCLK <= 26 => 3WS (4 CPU cycles) */ 00709 latency = LL_FLASH_LATENCY_3; 00710 } 00711 else if(HCLK_Frequency > UTILS_SCALE2_LATENCY2_FREQ) 00712 { 00713 /* 12 < HCLK <= 18 => 2WS (3 CPU cycles) */ 00714 latency = LL_FLASH_LATENCY_2; 00715 } 00716 else 00717 { 00718 if(HCLK_Frequency > UTILS_SCALE2_LATENCY1_FREQ) 00719 { 00720 /* 6 < HCLK <= 12 => 1WS (2 CPU cycles) */ 00721 latency = LL_FLASH_LATENCY_1; 00722 } 00723 /* else HCLK_Frequency <= 6MHz default LL_FLASH_LATENCY_0 0WS */ 00724 } 00725 #endif 00726 } 00727 00728 LL_FLASH_SetLatency(latency); 00729 00730 /* Check that the new number of wait states is taken into account to access the Flash 00731 memory by reading the FLASH_ACR register */ 00732 if(LL_FLASH_GetLatency() != latency) 00733 { 00734 status = ERROR; 00735 } 00736 } 00737 return status; 00738 } 00739 00740 /** 00741 * @brief Function to check that PLL can be modified 00742 * @param PLL_InputFrequency PLL input frequency (in Hz) 00743 * @param UTILS_PLLInitStruct pointer to a @ref LL_UTILS_PLLInitTypeDef structure that contains 00744 * the configuration information for the PLL. 00745 * @retval PLL output frequency (in Hz) 00746 */ 00747 static uint32_t UTILS_GetPLLOutputFrequency(uint32_t PLL_InputFrequency, LL_UTILS_PLLInitTypeDef *UTILS_PLLInitStruct) 00748 { 00749 uint32_t pllfreq = 0U; 00750 00751 /* Check the parameters */ 00752 assert_param(IS_LL_UTILS_PLLM_VALUE(UTILS_PLLInitStruct->PLLM)); 00753 assert_param(IS_LL_UTILS_PLLN_VALUE(UTILS_PLLInitStruct->PLLN)); 00754 assert_param(IS_LL_UTILS_PLLR_VALUE(UTILS_PLLInitStruct->PLLR)); 00755 00756 /* Check different PLL parameters according to RM */ 00757 /* - PLLM: ensure that the VCO input frequency ranges from 4 to 16 MHz. */ 00758 pllfreq = PLL_InputFrequency / (((UTILS_PLLInitStruct->PLLM >> RCC_PLLCFGR_PLLM_Pos) + 1)); 00759 assert_param(IS_LL_UTILS_PLLVCO_INPUT(pllfreq)); 00760 00761 /* - PLLN: ensure that the VCO output frequency is between 64 and 344 MHz.*/ 00762 pllfreq = pllfreq * (UTILS_PLLInitStruct->PLLN & (RCC_PLLCFGR_PLLN >> RCC_PLLCFGR_PLLN_Pos)); 00763 assert_param(IS_LL_UTILS_PLLVCO_OUTPUT(pllfreq)); 00764 00765 /* - PLLR: ensure that max frequency at 120000000 Hz is reached */ 00766 pllfreq = pllfreq / (((UTILS_PLLInitStruct->PLLR >> RCC_PLLCFGR_PLLR_Pos) + 1) * 2); 00767 assert_param(IS_LL_UTILS_PLL_FREQUENCY(pllfreq)); 00768 00769 return pllfreq; 00770 } 00771 00772 /** 00773 * @brief Function to check that PLL can be modified 00774 * @retval An ErrorStatus enumeration value: 00775 * - SUCCESS: PLL modification can be done 00776 * - ERROR: PLL is busy 00777 */ 00778 static ErrorStatus UTILS_PLL_IsBusy(void) 00779 { 00780 ErrorStatus status = SUCCESS; 00781 00782 /* Check if PLL is busy*/ 00783 if(LL_RCC_PLL_IsReady() != 0U) 00784 { 00785 /* PLL configuration cannot be modified */ 00786 status = ERROR; 00787 } 00788 00789 /* Check if PLLSAI1 is busy*/ 00790 if(LL_RCC_PLLSAI1_IsReady() != 0U) 00791 { 00792 /* PLLSAI1 configuration cannot be modified */ 00793 status = ERROR; 00794 } 00795 #if defined(RCC_PLLSAI2_SUPPORT) 00796 00797 /* Check if PLLSAI2 is busy*/ 00798 if(LL_RCC_PLLSAI2_IsReady() != 0U) 00799 { 00800 /* PLLSAI2 configuration cannot be modified */ 00801 status = ERROR; 00802 } 00803 #endif /*RCC_PLLSAI2_SUPPORT*/ 00804 00805 return status; 00806 } 00807 00808 /** 00809 * @brief Function to enable PLL and switch system clock to PLL 00810 * @param SYSCLK_Frequency SYSCLK frequency 00811 * @param UTILS_ClkInitStruct pointer to a @ref LL_UTILS_ClkInitTypeDef structure that contains 00812 * the configuration information for the BUS prescalers. 00813 * @retval An ErrorStatus enumeration value: 00814 * - SUCCESS: No problem to switch system to PLL 00815 * - ERROR: Problem to switch system to PLL 00816 */ 00817 static ErrorStatus UTILS_EnablePLLAndSwitchSystem(uint32_t SYSCLK_Frequency, LL_UTILS_ClkInitTypeDef *UTILS_ClkInitStruct) 00818 { 00819 ErrorStatus status = SUCCESS; 00820 uint32_t hclk_frequency = 0U; 00821 00822 assert_param(IS_LL_UTILS_SYSCLK_DIV(UTILS_ClkInitStruct->AHBCLKDivider)); 00823 assert_param(IS_LL_UTILS_APB1_DIV(UTILS_ClkInitStruct->APB1CLKDivider)); 00824 assert_param(IS_LL_UTILS_APB2_DIV(UTILS_ClkInitStruct->APB2CLKDivider)); 00825 00826 /* Calculate HCLK frequency */ 00827 hclk_frequency = __LL_RCC_CALC_HCLK_FREQ(SYSCLK_Frequency, UTILS_ClkInitStruct->AHBCLKDivider); 00828 00829 /* Increasing the number of wait states because of higher CPU frequency */ 00830 if(SystemCoreClock < hclk_frequency) 00831 { 00832 /* Set FLASH latency to highest latency */ 00833 status = UTILS_SetFlashLatency(hclk_frequency); 00834 } 00835 00836 /* Update system clock configuration */ 00837 if(status == SUCCESS) 00838 { 00839 /* Enable PLL */ 00840 LL_RCC_PLL_Enable(); 00841 LL_RCC_PLL_EnableDomain_SYS(); 00842 while (LL_RCC_PLL_IsReady() != 1U) 00843 { 00844 /* Wait for PLL ready */ 00845 } 00846 00847 /* Sysclk activation on the main PLL */ 00848 LL_RCC_SetAHBPrescaler(UTILS_ClkInitStruct->AHBCLKDivider); 00849 LL_RCC_SetSysClkSource(LL_RCC_SYS_CLKSOURCE_PLL); 00850 while (LL_RCC_GetSysClkSource() != LL_RCC_SYS_CLKSOURCE_STATUS_PLL) 00851 { 00852 /* Wait for system clock switch to PLL */ 00853 } 00854 00855 /* Set APB1 & APB2 prescaler*/ 00856 LL_RCC_SetAPB1Prescaler(UTILS_ClkInitStruct->APB1CLKDivider); 00857 LL_RCC_SetAPB2Prescaler(UTILS_ClkInitStruct->APB2CLKDivider); 00858 } 00859 00860 /* Decreasing the number of wait states because of lower CPU frequency */ 00861 if(SystemCoreClock > hclk_frequency) 00862 { 00863 /* Set FLASH latency to lowest latency */ 00864 status = UTILS_SetFlashLatency(hclk_frequency); 00865 } 00866 00867 /* Update SystemCoreClock variable */ 00868 if(status == SUCCESS) 00869 { 00870 LL_SetSystemCoreClock(hclk_frequency); 00871 } 00872 00873 return status; 00874 } 00875 00876 /** 00877 * @} 00878 */ 00879 00880 /** 00881 * @} 00882 */ 00883 00884 /** 00885 * @} 00886 */ 00887 00888 /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/