1 /**
2   ******************************************************************************
3   * @file    stm32l1xx_ll_utils.c
4   * @author  MCD Application Team
5   * @brief   UTILS LL module driver.
6   ******************************************************************************
7   * @attention
8   *
9   * <h2><center>&copy; Copyright(c) 2017 STMicroelectronics.
10   * All rights reserved.</center></h2>
11   *
12   * This software component is licensed by ST under BSD 3-Clause license,
13   * the "License"; You may not use this file except in compliance with the
14   * License. You may obtain a copy of the License at:
15   *                        opensource.org/licenses/BSD-3-Clause
16   *
17   ******************************************************************************
18   */
19 /* Includes ------------------------------------------------------------------*/
20 #include "stm32l1xx_ll_rcc.h"
21 #include "stm32l1xx_ll_utils.h"
22 #include "stm32l1xx_ll_system.h"
23 #include "stm32l1xx_ll_pwr.h"
24 #ifdef  USE_FULL_ASSERT
25 #include "stm32_assert.h"
26 #else
27 #define assert_param(expr) ((void)0U)
28 #endif
29 
30 /** @addtogroup STM32L1xx_LL_Driver
31   * @{
32   */
33 
34 /** @addtogroup UTILS_LL
35   * @{
36   */
37 
38 /* Private types -------------------------------------------------------------*/
39 /* Private variables ---------------------------------------------------------*/
40 /* Private constants ---------------------------------------------------------*/
41 /** @addtogroup UTILS_LL_Private_Constants
42   * @{
43   */
44 #define UTILS_MAX_FREQUENCY_SCALE1  32000000U        /*!< Maximum frequency for system clock at power scale1, in Hz */
45 #define UTILS_MAX_FREQUENCY_SCALE2  16000000U        /*!< Maximum frequency for system clock at power scale2, in Hz */
46 #define UTILS_MAX_FREQUENCY_SCALE3   4000000U        /*!< Maximum frequency for system clock at power scale3, in Hz */
47 
48 /* Defines used for PLL range */
49 #define UTILS_PLLVCO_OUTPUT_SCALE1  96000000U        /*!< Frequency max for PLLVCO output at power scale1, in Hz  */
50 #define UTILS_PLLVCO_OUTPUT_SCALE2  48000000U        /*!< Frequency max for PLLVCO output at power scale2, in Hz  */
51 #define UTILS_PLLVCO_OUTPUT_SCALE3  24000000U        /*!< Frequency max for PLLVCO output at power scale3, in Hz  */
52 
53 /* Defines used for HSE range */
54 #define UTILS_HSE_FREQUENCY_MIN      1000000U       /*!< Frequency min for HSE frequency, in Hz   */
55 #define UTILS_HSE_FREQUENCY_MAX     24000000U       /*!< Frequency max for HSE frequency, in Hz   */
56 
57 /* Defines used for FLASH latency according to HCLK Frequency */
58 #define UTILS_SCALE1_LATENCY1_FREQ  16000000U        /*!< HCLK frequency to set FLASH latency 1 in power scale 1 */
59 #define UTILS_SCALE2_LATENCY1_FREQ   8000000U        /*!< HCLK frequency to set FLASH latency 1 in power scale 2 */
60 #define UTILS_SCALE3_LATENCY1_FREQ   2000000U        /*!< HCLK frequency to set FLASH latency 1 in power scale 3 */
61 /**
62   * @}
63   */
64 /* Private macros ------------------------------------------------------------*/
65 /** @addtogroup UTILS_LL_Private_Macros
66   * @{
67   */
68 #define IS_LL_UTILS_SYSCLK_DIV(__VALUE__) (((__VALUE__) == LL_RCC_SYSCLK_DIV_1)   \
69                                         || ((__VALUE__) == LL_RCC_SYSCLK_DIV_2)   \
70                                         || ((__VALUE__) == LL_RCC_SYSCLK_DIV_4)   \
71                                         || ((__VALUE__) == LL_RCC_SYSCLK_DIV_8)   \
72                                         || ((__VALUE__) == LL_RCC_SYSCLK_DIV_16)  \
73                                         || ((__VALUE__) == LL_RCC_SYSCLK_DIV_64)  \
74                                         || ((__VALUE__) == LL_RCC_SYSCLK_DIV_128) \
75                                         || ((__VALUE__) == LL_RCC_SYSCLK_DIV_256) \
76                                         || ((__VALUE__) == LL_RCC_SYSCLK_DIV_512))
77 
78 #define IS_LL_UTILS_APB1_DIV(__VALUE__) (((__VALUE__) == LL_RCC_APB1_DIV_1) \
79                                       || ((__VALUE__) == LL_RCC_APB1_DIV_2) \
80                                       || ((__VALUE__) == LL_RCC_APB1_DIV_4) \
81                                       || ((__VALUE__) == LL_RCC_APB1_DIV_8) \
82                                       || ((__VALUE__) == LL_RCC_APB1_DIV_16))
83 
84 #define IS_LL_UTILS_APB2_DIV(__VALUE__) (((__VALUE__) == LL_RCC_APB2_DIV_1) \
85                                       || ((__VALUE__) == LL_RCC_APB2_DIV_2) \
86                                       || ((__VALUE__) == LL_RCC_APB2_DIV_4) \
87                                       || ((__VALUE__) == LL_RCC_APB2_DIV_8) \
88                                       || ((__VALUE__) == LL_RCC_APB2_DIV_16))
89 
90 #define IS_LL_UTILS_PLLMUL_VALUE(__VALUE__) (((__VALUE__) == LL_RCC_PLL_MUL_3) \
91                                           || ((__VALUE__) == LL_RCC_PLL_MUL_4) \
92                                           || ((__VALUE__) == LL_RCC_PLL_MUL_6) \
93                                           || ((__VALUE__) == LL_RCC_PLL_MUL_8) \
94                                           || ((__VALUE__) == LL_RCC_PLL_MUL_12) \
95                                           || ((__VALUE__) == LL_RCC_PLL_MUL_16) \
96                                           || ((__VALUE__) == LL_RCC_PLL_MUL_24) \
97                                           || ((__VALUE__) == LL_RCC_PLL_MUL_32) \
98                                           || ((__VALUE__) == LL_RCC_PLL_MUL_48))
99 
100 #define IS_LL_UTILS_PLLDIV_VALUE(__VALUE__) (((__VALUE__) == LL_RCC_PLL_DIV_2) || ((__VALUE__) == LL_RCC_PLL_DIV_3) || \
101                                              ((__VALUE__) == LL_RCC_PLL_DIV_4))
102 
103 #define IS_LL_UTILS_PLLVCO_OUTPUT(__VALUE__) ((LL_PWR_GetRegulVoltageScaling() == LL_PWR_REGU_VOLTAGE_SCALE1) ? ((__VALUE__) <= UTILS_PLLVCO_OUTPUT_SCALE1) : \
104                                              ((LL_PWR_GetRegulVoltageScaling() == LL_PWR_REGU_VOLTAGE_SCALE2) ? ((__VALUE__) <= UTILS_PLLVCO_OUTPUT_SCALE2) : \
105                                              ((__VALUE__) <= UTILS_PLLVCO_OUTPUT_SCALE3)))
106 
107 #define IS_LL_UTILS_PLL_FREQUENCY(__VALUE__) ((LL_PWR_GetRegulVoltageScaling() == LL_PWR_REGU_VOLTAGE_SCALE1) ? ((__VALUE__) <= UTILS_MAX_FREQUENCY_SCALE1) : \
108                                              ((LL_PWR_GetRegulVoltageScaling() == LL_PWR_REGU_VOLTAGE_SCALE2) ? ((__VALUE__) <= UTILS_MAX_FREQUENCY_SCALE2) : \
109                                              ((__VALUE__) <= UTILS_MAX_FREQUENCY_SCALE3)))
110 
111 #define IS_LL_UTILS_HSE_BYPASS(__STATE__) (((__STATE__) == LL_UTILS_HSEBYPASS_ON) \
112                                         || ((__STATE__) == LL_UTILS_HSEBYPASS_OFF))
113 
114 #define IS_LL_UTILS_HSE_FREQUENCY(__FREQUENCY__) (((__FREQUENCY__) >= UTILS_HSE_FREQUENCY_MIN) && ((__FREQUENCY__) <= UTILS_HSE_FREQUENCY_MAX))
115 /**
116   * @}
117   */
118 /* Private function prototypes -----------------------------------------------*/
119 /** @defgroup UTILS_LL_Private_Functions UTILS Private functions
120   * @{
121   */
122 static uint32_t    UTILS_GetPLLOutputFrequency(uint32_t PLL_InputFrequency,
123                                                LL_UTILS_PLLInitTypeDef *UTILS_PLLInitStruct);
124 static ErrorStatus UTILS_EnablePLLAndSwitchSystem(uint32_t SYSCLK_Frequency, LL_UTILS_ClkInitTypeDef *UTILS_ClkInitStruct);
125 static ErrorStatus UTILS_PLL_IsBusy(void);
126 /**
127   * @}
128   */
129 
130 /* Exported functions --------------------------------------------------------*/
131 /** @addtogroup UTILS_LL_Exported_Functions
132   * @{
133   */
134 
135 /** @addtogroup UTILS_LL_EF_DELAY
136   * @{
137   */
138 
139 /**
140   * @brief  This function configures the Cortex-M SysTick source to have 1ms time base.
141   * @note   When a RTOS is used, it is recommended to avoid changing the Systick
142   *         configuration by calling this function, for a delay use rather osDelay RTOS service.
143   * @param  HCLKFrequency HCLK frequency in Hz
144   * @note   HCLK frequency can be calculated thanks to RCC helper macro or function @ref LL_RCC_GetSystemClocksFreq
145   * @retval None
146   */
LL_Init1msTick(uint32_t HCLKFrequency)147 void LL_Init1msTick(uint32_t HCLKFrequency)
148 {
149   /* Use frequency provided in argument */
150   LL_InitTick(HCLKFrequency, 1000U);
151 }
152 
153 /**
154   * @brief  This function provides accurate delay (in milliseconds) based
155   *         on SysTick counter flag
156   * @note   When a RTOS is used, it is recommended to avoid using blocking delay
157   *         and use rather osDelay service.
158   * @note   To respect 1ms timebase, user should call @ref LL_Init1msTick function which
159   *         will configure Systick to 1ms
160   * @param  Delay specifies the delay time length, in milliseconds.
161   * @retval None
162   */
LL_mDelay(uint32_t Delay)163 void LL_mDelay(uint32_t Delay)
164 {
165   __IO uint32_t  tmp = SysTick->CTRL;  /* Clear the COUNTFLAG first */
166   uint32_t tmpDelay = Delay;
167 
168   /* Add this code to indicate that local variable is not used */
169   ((void)tmp);
170 
171   /* Add a period to guaranty minimum wait */
172   if(tmpDelay < LL_MAX_DELAY)
173   {
174     tmpDelay++;
175   }
176 
177   while (tmpDelay != 0U)
178   {
179     if((SysTick->CTRL & SysTick_CTRL_COUNTFLAG_Msk) != 0U)
180     {
181       tmpDelay--;
182     }
183   }
184 }
185 
186 /**
187   * @}
188   */
189 
190 /** @addtogroup UTILS_EF_SYSTEM
191   *  @brief    System Configuration functions
192   *
193   @verbatim
194  ===============================================================================
195            ##### System Configuration functions #####
196  ===============================================================================
197     [..]
198          System, AHB and APB buses clocks configuration
199 
200          (+) The maximum frequency of the SYSCLK, HCLK, PCLK1 and PCLK2 is 32000000 Hz.
201   @endverbatim
202   @internal
203              Depending on the device voltage range, the maximum frequency should be
204              adapted accordingly:
205              (++) +----------------------------------------------------------------+
206              (++) |  Wait states  |                HCLK clock frequency (MHz)      |
207              (++) |               |------------------------------------------------|
208              (++) |   (Latency)   |            voltage range       | voltage range |
209              (++) |               |            1.65 V - 3.6 V      | 2.0 V - 3.6 V |
210              (++) |               |----------------|---------------|---------------|
211              (++) |               |  VCORE = 1.2 V | VCORE = 1.5 V | VCORE = 1.8 V |
212              (++) |-------------- |----------------|---------------|---------------|
213              (++) |0WS(1CPU cycle)|0 < HCLK <= 2   |0 < HCLK <= 8  |0 < HCLK <= 16 |
214              (++) |---------------|----------------|---------------|---------------|
215              (++) |1WS(2CPU cycle)|2 < HCLK <= 4   |8 < HCLK <= 16 |16 < HCLK <= 32|
216              (++) +----------------------------------------------------------------+
217   @endinternal
218   * @{
219   */
220 
221 /**
222   * @brief  This function sets directly SystemCoreClock CMSIS variable.
223   * @note   Variable can be calculated also through SystemCoreClockUpdate function.
224   * @param  HCLKFrequency HCLK frequency in Hz (can be calculated thanks to RCC helper macro)
225   * @retval None
226   */
LL_SetSystemCoreClock(uint32_t HCLKFrequency)227 void LL_SetSystemCoreClock(uint32_t HCLKFrequency)
228 {
229   /* HCLK clock frequency */
230   SystemCoreClock = HCLKFrequency;
231 }
232 
233 /**
234   * @brief  Update number of Flash wait states in line with new frequency and current
235             voltage range.
236   * @param  Frequency  HCLK frequency
237   * @retval An ErrorStatus enumeration value:
238   *          - SUCCESS: Latency has been modified
239   *          - ERROR: Latency cannot be modified
240   */
241 #if defined(FLASH_ACR_LATENCY)
LL_SetFlashLatency(uint32_t Frequency)242 ErrorStatus LL_SetFlashLatency(uint32_t Frequency)
243 {
244   ErrorStatus status = SUCCESS;
245 
246   uint32_t latency = LL_FLASH_LATENCY_0;  /* default value 0WS */
247 
248   /* Frequency cannot be equal to 0 or greater than max clock */
249   if ((Frequency == 0U) || (Frequency > UTILS_MAX_FREQUENCY_SCALE1))
250   {
251     status = ERROR;
252   }
253   else
254   {
255     if (LL_PWR_GetRegulVoltageScaling() == LL_PWR_REGU_VOLTAGE_SCALE1)
256     {
257       if (Frequency > UTILS_SCALE1_LATENCY1_FREQ)
258       {
259         /* 16 < HCLK <= 32 => 1WS (2 CPU cycles) */
260         latency = LL_FLASH_LATENCY_1;
261       }
262       /* else HCLK < 16MHz default LL_FLASH_LATENCY_0 0WS */
263      }
264     else if (LL_PWR_GetRegulVoltageScaling() == LL_PWR_REGU_VOLTAGE_SCALE2)
265     {
266       if (Frequency > UTILS_SCALE2_LATENCY1_FREQ)
267       {
268         /* 8 < HCLK <= 16 => 1WS (2 CPU cycles) */
269         latency = LL_FLASH_LATENCY_1;
270       }
271       /* else HCLK < 8MHz default LL_FLASH_LATENCY_0 0WS */
272     }
273     else
274     {
275       if (Frequency > UTILS_SCALE3_LATENCY1_FREQ)
276       {
277         /* 2 < HCLK <= 4 => 1WS (2 CPU cycles) */
278         latency = LL_FLASH_LATENCY_1;
279       }
280       /* else HCLK < 4MHz default LL_FLASH_LATENCY_0 0WS */
281     }
282 
283     /* Latency cannot be set to 1WS only if 64-bit access bit is enabled */
284     if (latency == LL_FLASH_LATENCY_1)
285     {
286       LL_FLASH_Enable64bitAccess();
287     }
288 
289     LL_FLASH_SetLatency(latency);
290 
291     /* Check that the new number of wait states is taken into account to access the Flash
292        memory by reading the FLASH_ACR register */
293     if (LL_FLASH_GetLatency() != latency)
294     {
295       status = ERROR;
296     }
297   }
298   return status;
299 }
300 #endif /* FLASH_ACR_LATENCY */
301 
302 /**
303   * @brief  This function configures system clock with HSI as clock source of the PLL
304   * @note   The application need to ensure that PLL is disabled.
305   * @note   Function is based on the following formula:
306   *         - PLL output frequency = ((HSI frequency * PLLMul) / PLLDiv)
307   *         - PLLMul: The application software must set correctly the PLL multiplication factor to avoid exceeding
308   *           - 96 MHz as PLLVCO when the product is in range 1,
309   *           - 48 MHz as PLLVCO when the product is in range 2,
310   *           - 24 MHz when the product is in range 3
311   * @note   FLASH latency can be modified through this function.
312   * @note   If this latency increases to 1WS, FLASH 64-bit access will be automatically enabled.
313   *         A decrease of FLASH latency to 0WS will not disable 64-bit access. If needed, user should call
314   *         the following function @ref LL_FLASH_Disable64bitAccess.
315   * @param  UTILS_PLLInitStruct pointer to a @ref LL_UTILS_PLLInitTypeDef structure that contains
316   *                             the configuration information for the PLL.
317   * @param  UTILS_ClkInitStruct pointer to a @ref LL_UTILS_ClkInitTypeDef structure that contains
318   *                             the configuration information for the BUS prescalers.
319   * @retval An ErrorStatus enumeration value:
320   *          - SUCCESS: Max frequency configuration done
321   *          - ERROR: Max frequency configuration not done
322   */
LL_PLL_ConfigSystemClock_HSI(LL_UTILS_PLLInitTypeDef * UTILS_PLLInitStruct,LL_UTILS_ClkInitTypeDef * UTILS_ClkInitStruct)323 ErrorStatus LL_PLL_ConfigSystemClock_HSI(LL_UTILS_PLLInitTypeDef *UTILS_PLLInitStruct,
324                                          LL_UTILS_ClkInitTypeDef *UTILS_ClkInitStruct)
325 {
326   ErrorStatus status;
327   uint32_t pllfreq;
328 
329   /* Check if one of the PLL is enabled */
330   if (UTILS_PLL_IsBusy() == SUCCESS)
331   {
332     /* Calculate the new PLL output frequency */
333     pllfreq = UTILS_GetPLLOutputFrequency(HSI_VALUE, UTILS_PLLInitStruct);
334 
335     /* Enable HSI if not enabled */
336     if (LL_RCC_HSI_IsReady() != 1U)
337     {
338       LL_RCC_HSI_Enable();
339       while (LL_RCC_HSI_IsReady() != 1U)
340       {
341         /* Wait for HSI ready */
342       }
343     }
344 
345     /* Configure PLL */
346     LL_RCC_PLL_ConfigDomain_SYS(LL_RCC_PLLSOURCE_HSI, UTILS_PLLInitStruct->PLLMul, UTILS_PLLInitStruct->PLLDiv);
347 
348     /* Enable PLL and switch system clock to PLL */
349     status = UTILS_EnablePLLAndSwitchSystem(pllfreq, UTILS_ClkInitStruct);
350   }
351   else
352   {
353     /* Current PLL configuration cannot be modified */
354     status = ERROR;
355   }
356 
357   return status;
358 }
359 
360 /**
361   * @brief  This function configures system clock with HSE as clock source of the PLL
362   * @note   The application need to ensure that PLL is disabled.
363   * @note   Function is based on the following formula:
364   *         - PLL output frequency = ((HSE frequency * PLLMul) / PLLDiv)
365   *         - PLLMul: The application software must set correctly the PLL multiplication factor to avoid exceeding
366   *           - 96 MHz as PLLVCO when the product is in range 1,
367   *           - 48 MHz as PLLVCO when the product is in range 2,
368   *           - 24 MHz when the product is in range 3
369   * @note   FLASH latency can be modified through this function.
370   * @note   If this latency increases to 1WS, FLASH 64-bit access will be automatically enabled.
371   *         A decrease of FLASH latency to 0WS will not disable 64-bit access. If needed, user should call
372   *         the following function @ref LL_FLASH_Disable64bitAccess.
373   * @param  HSEFrequency Value between Min_Data = 1000000 and Max_Data = 24000000
374   * @param  HSEBypass This parameter can be one of the following values:
375   *         @arg @ref LL_UTILS_HSEBYPASS_ON
376   *         @arg @ref LL_UTILS_HSEBYPASS_OFF
377   * @param  UTILS_PLLInitStruct pointer to a @ref LL_UTILS_PLLInitTypeDef structure that contains
378   *                             the configuration information for the PLL.
379   * @param  UTILS_ClkInitStruct pointer to a @ref LL_UTILS_ClkInitTypeDef structure that contains
380   *                             the configuration information for the BUS prescalers.
381   * @retval An ErrorStatus enumeration value:
382   *          - SUCCESS: Max frequency configuration done
383   *          - ERROR: Max frequency configuration not done
384   */
LL_PLL_ConfigSystemClock_HSE(uint32_t HSEFrequency,uint32_t HSEBypass,LL_UTILS_PLLInitTypeDef * UTILS_PLLInitStruct,LL_UTILS_ClkInitTypeDef * UTILS_ClkInitStruct)385 ErrorStatus LL_PLL_ConfigSystemClock_HSE(uint32_t HSEFrequency, uint32_t HSEBypass,
386                                          LL_UTILS_PLLInitTypeDef *UTILS_PLLInitStruct, LL_UTILS_ClkInitTypeDef *UTILS_ClkInitStruct)
387 {
388   ErrorStatus status;
389   uint32_t pllfreq;
390 
391   /* Check the parameters */
392   assert_param(IS_LL_UTILS_HSE_FREQUENCY(HSEFrequency));
393   assert_param(IS_LL_UTILS_HSE_BYPASS(HSEBypass));
394 
395   /* Check if one of the PLL is enabled */
396   if (UTILS_PLL_IsBusy() == SUCCESS)
397   {
398 
399     /* Calculate the new PLL output frequency */
400     pllfreq = UTILS_GetPLLOutputFrequency(HSEFrequency, UTILS_PLLInitStruct);
401 
402     /* Enable HSE if not enabled */
403     if (LL_RCC_HSE_IsReady() != 1U)
404     {
405       /* Check if need to enable HSE bypass feature or not */
406       if (HSEBypass == LL_UTILS_HSEBYPASS_ON)
407       {
408         LL_RCC_HSE_EnableBypass();
409       }
410       else
411       {
412         LL_RCC_HSE_DisableBypass();
413       }
414 
415       /* Enable HSE */
416       LL_RCC_HSE_Enable();
417       while (LL_RCC_HSE_IsReady() != 1U)
418       {
419         /* Wait for HSE ready */
420       }
421     }
422 
423       /* Configure PLL */
424       LL_RCC_PLL_ConfigDomain_SYS(LL_RCC_PLLSOURCE_HSE, UTILS_PLLInitStruct->PLLMul, UTILS_PLLInitStruct->PLLDiv);
425 
426     /* Enable PLL and switch system clock to PLL */
427     status = UTILS_EnablePLLAndSwitchSystem(pllfreq, UTILS_ClkInitStruct);
428   }
429   else
430   {
431     /* Current PLL configuration cannot be modified */
432     status = ERROR;
433   }
434 
435   return status;
436 }
437 
438 /**
439   * @}
440   */
441 
442 /**
443   * @}
444   */
445 
446 /** @addtogroup UTILS_LL_Private_Functions
447   * @{
448   */
449 
450 /**
451   * @brief  Function to check that PLL can be modified
452   * @param  PLL_InputFrequency  PLL input frequency (in Hz)
453   * @param  UTILS_PLLInitStruct pointer to a @ref LL_UTILS_PLLInitTypeDef structure that contains
454   *                             the configuration information for the PLL.
455   * @retval PLL output frequency (in Hz)
456   */
UTILS_GetPLLOutputFrequency(uint32_t PLL_InputFrequency,LL_UTILS_PLLInitTypeDef * UTILS_PLLInitStruct)457 static uint32_t UTILS_GetPLLOutputFrequency(uint32_t PLL_InputFrequency, LL_UTILS_PLLInitTypeDef *UTILS_PLLInitStruct)
458 {
459   uint32_t pllfreq;
460 
461   /* Check the parameters */
462   assert_param(IS_LL_UTILS_PLLMUL_VALUE(UTILS_PLLInitStruct->PLLMul));
463   assert_param(IS_LL_UTILS_PLLDIV_VALUE(UTILS_PLLInitStruct->PLLDiv));
464 
465   /* Check different PLL parameters according to RM                          */
466   /* The application software must set correctly the PLL multiplication factor to avoid exceeding
467      96 MHz as PLLVCO when the product is in range 1,
468      48 MHz as PLLVCO when the product is in range 2,
469      24 MHz when the product is in range 3. */
470   pllfreq = PLL_InputFrequency * (PLLMulTable[UTILS_PLLInitStruct->PLLMul >> RCC_CFGR_PLLMUL_Pos]);
471   assert_param(IS_LL_UTILS_PLLVCO_OUTPUT(pllfreq));
472 
473   /* The application software must set correctly the PLL multiplication factor to avoid exceeding
474      maximum frequency 32000000 in range 1 */
475   pllfreq = pllfreq / ((UTILS_PLLInitStruct->PLLDiv >> RCC_CFGR_PLLDIV_Pos)+1U);
476   assert_param(IS_LL_UTILS_PLL_FREQUENCY(pllfreq));
477 
478   return pllfreq;
479 }
480 
481 /**
482   * @brief  Function to check that PLL can be modified
483   * @retval An ErrorStatus enumeration value:
484   *          - SUCCESS: PLL modification can be done
485   *          - ERROR: PLL is busy
486   */
UTILS_PLL_IsBusy(void)487 static ErrorStatus UTILS_PLL_IsBusy(void)
488 {
489   ErrorStatus status = SUCCESS;
490 
491   /* Check if PLL is busy*/
492   if (LL_RCC_PLL_IsReady() != 0U)
493   {
494     /* PLL configuration cannot be modified */
495     status = ERROR;
496   }
497 
498   return status;
499 }
500 
501 /**
502   * @brief  Function to enable PLL and switch system clock to PLL
503   * @param  SYSCLK_Frequency SYSCLK frequency
504   * @param  UTILS_ClkInitStruct pointer to a @ref LL_UTILS_ClkInitTypeDef structure that contains
505   *                             the configuration information for the BUS prescalers.
506   * @retval An ErrorStatus enumeration value:
507   *          - SUCCESS: No problem to switch system to PLL
508   *          - ERROR: Problem to switch system to PLL
509   */
UTILS_EnablePLLAndSwitchSystem(uint32_t SYSCLK_Frequency,LL_UTILS_ClkInitTypeDef * UTILS_ClkInitStruct)510 static ErrorStatus UTILS_EnablePLLAndSwitchSystem(uint32_t SYSCLK_Frequency, LL_UTILS_ClkInitTypeDef *UTILS_ClkInitStruct)
511 {
512   ErrorStatus status = SUCCESS;
513   uint32_t hclk_frequency;
514 
515   assert_param(IS_LL_UTILS_SYSCLK_DIV(UTILS_ClkInitStruct->AHBCLKDivider));
516   assert_param(IS_LL_UTILS_APB1_DIV(UTILS_ClkInitStruct->APB1CLKDivider));
517   assert_param(IS_LL_UTILS_APB2_DIV(UTILS_ClkInitStruct->APB2CLKDivider));
518 
519   /* Calculate HCLK frequency */
520   hclk_frequency = __LL_RCC_CALC_HCLK_FREQ(SYSCLK_Frequency, UTILS_ClkInitStruct->AHBCLKDivider);
521 
522   /* Increasing the number of wait states because of higher CPU frequency */
523   if (SystemCoreClock < hclk_frequency)
524   {
525     /* Set FLASH latency to highest latency */
526     status = LL_SetFlashLatency(hclk_frequency);
527   }
528 
529   /* Update system clock configuration */
530   if (status == SUCCESS)
531   {
532     /* Enable PLL */
533     LL_RCC_PLL_Enable();
534     while (LL_RCC_PLL_IsReady() != 1U)
535     {
536       /* Wait for PLL ready */
537     }
538 
539     /* Sysclk activation on the main PLL */
540     LL_RCC_SetAHBPrescaler(UTILS_ClkInitStruct->AHBCLKDivider);
541     LL_RCC_SetSysClkSource(LL_RCC_SYS_CLKSOURCE_PLL);
542     while (LL_RCC_GetSysClkSource() != LL_RCC_SYS_CLKSOURCE_STATUS_PLL)
543     {
544       /* Wait for system clock switch to PLL */
545     }
546 
547     /* Set APB1 & APB2 prescaler*/
548     LL_RCC_SetAPB1Prescaler(UTILS_ClkInitStruct->APB1CLKDivider);
549     LL_RCC_SetAPB2Prescaler(UTILS_ClkInitStruct->APB2CLKDivider);
550   }
551 
552   /* Decreasing the number of wait states because of lower CPU frequency */
553   if (SystemCoreClock > hclk_frequency)
554   {
555     /* Set FLASH latency to lowest latency */
556     status = LL_SetFlashLatency(hclk_frequency);
557   }
558 
559   /* Update SystemCoreClock variable */
560   if (status == SUCCESS)
561   {
562     LL_SetSystemCoreClock(hclk_frequency);
563   }
564 
565   return status;
566 }
567 
568 /**
569   * @}
570   */
571 
572 /**
573   * @}
574   */
575 
576 /**
577   * @}
578   */
579 
580 /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
581