STM32F103xB HAL User Manual
stm32f1xx_ll_utils.c
Go to the documentation of this file.
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>&copy; 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****/