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