1 /**
2   ******************************************************************************
3   * @file    stm32l0xx_ll_utils.c
4   * @author  MCD Application Team
5   * @brief   UTILS LL module driver.
6   ******************************************************************************
7   * @attention
8   *
9   * Copyright (c) 2016 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 "stm32l0xx_ll_rcc.h"
20 #include "stm32l0xx_ll_utils.h"
21 #include "stm32l0xx_ll_system.h"
22 #include "stm32l0xx_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 STM32L0xx_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  (4194304U)         /*!< 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   /* Add this code to indicate that local variable is not used */
166   ((void)tmp);
167 
168   /* Add a period to guaranty minimum wait */
169   if (Delay < LL_MAX_DELAY)
170   {
171     Delay++;
172   }
173 
174   while (Delay)
175   {
176     if ((SysTick->CTRL & SysTick_CTRL_COUNTFLAG_Msk) != 0U)
177     {
178       Delay--;
179     }
180   }
181 }
182 
183 /**
184   * @}
185   */
186 
187 /** @addtogroup UTILS_EF_SYSTEM
188   *  @brief    System Configuration functions
189   *
190   @verbatim
191  ===============================================================================
192            ##### System Configuration functions #####
193  ===============================================================================
194     [..]
195          System, AHB and APB buses clocks configuration
196 
197          (+) The maximum frequency of the SYSCLK, HCLK, PCLK1 and PCLK2 is 32000000 Hz.
198   @endverbatim
199   @internal
200              Depending on the device voltage range, the maximum frequency should be
201              adapted accordingly:
202              (++) +----------------------------------------------------------------+
203              (++) |  Wait states  |                HCLK clock frequency (MHz)      |
204              (++) |               |------------------------------------------------|
205              (++) |   (Latency)   |            voltage range       | voltage range |
206              (++) |               |            1.65 V - 3.6 V      | 2.0 V - 3.6 V |
207              (++) |               |----------------|---------------|---------------|
208              (++) |               |  VCORE = 1.2 V | VCORE = 1.5 V | VCORE = 1.8 V |
209              (++) |-------------- |----------------|---------------|---------------|
210              (++) |0WS(1CPU cycle)|0 < HCLK <= 2   |0 < HCLK <= 8  |0 < HCLK <= 16 |
211              (++) |---------------|----------------|---------------|---------------|
212              (++) |1WS(2CPU cycle)|2 < HCLK <= 4   |8 < HCLK <= 16 |16 < HCLK <= 32|
213              (++) +----------------------------------------------------------------+
214   @endinternal
215   * @{
216   */
217 
218 /**
219   * @brief  This function sets directly SystemCoreClock CMSIS variable.
220   * @note   Variable can be calculated also through SystemCoreClockUpdate function.
221   * @param  HCLKFrequency HCLK frequency in Hz (can be calculated thanks to RCC helper macro)
222   * @retval None
223   */
LL_SetSystemCoreClock(uint32_t HCLKFrequency)224 void LL_SetSystemCoreClock(uint32_t HCLKFrequency)
225 {
226   /* HCLK clock frequency */
227   SystemCoreClock = HCLKFrequency;
228 }
229 
230 /**
231   * @brief  Update number of Flash wait states in line with new frequency and current
232             voltage range.
233   * @param  Frequency  HCLK frequency
234   * @retval An ErrorStatus enumeration value:
235   *          - SUCCESS: Latency has been modified
236   *          - ERROR: Latency cannot be modified
237   */
LL_SetFlashLatency(uint32_t Frequency)238 ErrorStatus LL_SetFlashLatency(uint32_t Frequency)
239 {
240   uint32_t timeout;
241   uint32_t getlatency;
242   uint32_t latency;
243   ErrorStatus status = SUCCESS;
244 
245   /* Frequency cannot be equal to 0 */
246   if ((Frequency == 0U) || (Frequency > UTILS_MAX_FREQUENCY_SCALE1))
247   {
248     status = ERROR;
249   }
250   else
251   {
252     if (LL_PWR_GetRegulVoltageScaling() == LL_PWR_REGU_VOLTAGE_SCALE1)
253     {
254       if (Frequency > UTILS_SCALE1_LATENCY1_FREQ)
255       {
256         /* 16 < HCLK <= 32 => 1WS (2 CPU cycles) */
257         latency = LL_FLASH_LATENCY_1;
258       }
259       else
260       {
261         /* else HCLK < 16MHz default LL_FLASH_LATENCY_0 0WS */
262         latency = LL_FLASH_LATENCY_0;
263       }
264     }
265     else if (LL_PWR_GetRegulVoltageScaling() == LL_PWR_REGU_VOLTAGE_SCALE2)
266     {
267       if (Frequency > UTILS_SCALE2_LATENCY1_FREQ)
268       {
269         /* 8 < HCLK <= 16 => 1WS (2 CPU cycles) */
270         latency = LL_FLASH_LATENCY_1;
271       }
272       else
273       {
274         /* else HCLK < 8MHz default LL_FLASH_LATENCY_0 0WS */
275         latency = LL_FLASH_LATENCY_0;
276       }
277     }
278     else
279     {
280       if (Frequency > UTILS_SCALE3_LATENCY1_FREQ)
281       {
282         /* 2 < HCLK <= 4 => 1WS (2 CPU cycles) */
283         latency = LL_FLASH_LATENCY_1;
284       }
285       else
286       {
287         /* else HCLK < 2MHz default LL_FLASH_LATENCY_0 0WS */
288         latency = LL_FLASH_LATENCY_0;
289       }
290     }
291 
292     if (status != ERROR)
293     {
294       LL_FLASH_SetLatency(latency);
295 
296       /* Check that the new number of wait states is taken into account to access the Flash
297            memory by reading the FLASH_ACR register */
298       timeout = 2;
299       do
300       {
301       /* Wait for Flash latency to be updated */
302       getlatency = LL_FLASH_GetLatency();
303       timeout--;
304       } while ((getlatency != latency) && (timeout > 0));
305 
306       if(getlatency != latency)
307       {
308         status = ERROR;
309       }
310     }
311   }
312   return status;
313 }
314 
315 /**
316   * @brief  This function configures system clock with HSI as clock source of the PLL
317   * @note   The application need to ensure that PLL is disabled.
318   * @note   Function is based on the following formula:
319   *         - PLL output frequency = ((HSI frequency * PLLMul) / PLLDiv)
320   *         - PLLMul: The application software must set correctly the PLL multiplication factor to ensure
321   *           - PLLVCO does not exceed 96 MHz when the product is in range 1,
322   *           - PLLVCO does not exceed 48 MHz when the product is in range 2,
323   *           - PLLVCO does not exceed 24 MHz when the product is in range 3
324   * @note   FLASH latency can be modified through this function.
325   * @param  UTILS_PLLInitStruct pointer to a @ref LL_UTILS_PLLInitTypeDef structure that contains
326   *                             the configuration information for the PLL.
327   * @param  UTILS_ClkInitStruct pointer to a @ref LL_UTILS_ClkInitTypeDef structure that contains
328   *                             the configuration information for the BUS prescalers.
329   * @retval An ErrorStatus enumeration value:
330   *          - SUCCESS: Max frequency configuration done
331   *          - ERROR: Max frequency configuration not done
332   */
LL_PLL_ConfigSystemClock_HSI(LL_UTILS_PLLInitTypeDef * UTILS_PLLInitStruct,LL_UTILS_ClkInitTypeDef * UTILS_ClkInitStruct)333 ErrorStatus LL_PLL_ConfigSystemClock_HSI(LL_UTILS_PLLInitTypeDef *UTILS_PLLInitStruct,
334                                          LL_UTILS_ClkInitTypeDef *UTILS_ClkInitStruct)
335 {
336   ErrorStatus status = SUCCESS;
337   uint32_t pllfreq = 0U;
338 
339   /* Check if one of the PLL is enabled */
340   if (UTILS_PLL_IsBusy() == SUCCESS)
341   {
342     /* Calculate the new PLL output frequency */
343     pllfreq = UTILS_GetPLLOutputFrequency(HSI_VALUE, UTILS_PLLInitStruct);
344 
345     /* Enable HSI if not enabled */
346     if (LL_RCC_HSI_IsReady() != 1U)
347     {
348       LL_RCC_HSI_Enable();
349       while (LL_RCC_HSI_IsReady() != 1U)
350       {
351         /* Wait for HSI ready */
352       }
353     }
354 
355     /* Configure PLL */
356     LL_RCC_PLL_ConfigDomain_SYS(LL_RCC_PLLSOURCE_HSI, UTILS_PLLInitStruct->PLLMul, UTILS_PLLInitStruct->PLLDiv);
357 
358     /* Enable PLL and switch system clock to PLL */
359     status = UTILS_EnablePLLAndSwitchSystem(pllfreq, UTILS_ClkInitStruct);
360   }
361   else
362   {
363     /* Current PLL configuration cannot be modified */
364     status = ERROR;
365   }
366 
367   return status;
368 }
369 
370 /**
371   * @brief  This function configures system clock with HSE as clock source of the PLL
372   * @note   The application need to ensure that PLL is disabled.
373   * @note   Function is based on the following formula:
374   *         - PLL output frequency = ((HSE frequency * PLLMul) / PLLDiv)
375   *         - PLLMul: The application software must set correctly the PLL multiplication factor to to ensure
376   *           - PLLVCO does not exceed 96 MHz when the product is in range 1,
377   *           - PLLVCO does not exceed 48 MHz when the product is in range 2,
378   *           - PLLVCO does not exceed 24 MHz when the product is in range 3
379   * @note   FLASH latency can be modified through this function.
380   * @param  HSEFrequency Value between Min_Data = 1000000 and Max_Data = 24000000
381   * @param  HSEBypass This parameter can be one of the following values:
382   *         @arg @ref LL_UTILS_HSEBYPASS_ON
383   *         @arg @ref LL_UTILS_HSEBYPASS_OFF
384   * @param  UTILS_PLLInitStruct pointer to a @ref LL_UTILS_PLLInitTypeDef structure that contains
385   *                             the configuration information for the PLL.
386   * @param  UTILS_ClkInitStruct pointer to a @ref LL_UTILS_ClkInitTypeDef structure that contains
387   *                             the configuration information for the BUS prescalers.
388   * @retval An ErrorStatus enumeration value:
389   *          - SUCCESS: Max frequency configuration done
390   *          - ERROR: Max frequency configuration not done
391   */
LL_PLL_ConfigSystemClock_HSE(uint32_t HSEFrequency,uint32_t HSEBypass,LL_UTILS_PLLInitTypeDef * UTILS_PLLInitStruct,LL_UTILS_ClkInitTypeDef * UTILS_ClkInitStruct)392 ErrorStatus LL_PLL_ConfigSystemClock_HSE(uint32_t HSEFrequency, uint32_t HSEBypass,
393                                          LL_UTILS_PLLInitTypeDef *UTILS_PLLInitStruct, LL_UTILS_ClkInitTypeDef *UTILS_ClkInitStruct)
394 {
395   ErrorStatus status = SUCCESS;
396   uint32_t pllfreq = 0U;
397 
398   /* Check the parameters */
399   assert_param(IS_LL_UTILS_HSE_FREQUENCY(HSEFrequency));
400   assert_param(IS_LL_UTILS_HSE_BYPASS(HSEBypass));
401 
402   /* Check if one of the PLL is enabled */
403   if (UTILS_PLL_IsBusy() == SUCCESS)
404   {
405     /* Calculate the new PLL output frequency */
406     pllfreq = UTILS_GetPLLOutputFrequency(HSEFrequency, UTILS_PLLInitStruct);
407 
408     /* Enable HSE if not enabled */
409     if (LL_RCC_HSE_IsReady() != 1U)
410     {
411       /* Check if need to enable HSE bypass feature or not */
412       if (HSEBypass == LL_UTILS_HSEBYPASS_ON)
413       {
414         LL_RCC_HSE_EnableBypass();
415       }
416       else
417       {
418         LL_RCC_HSE_DisableBypass();
419       }
420 
421       /* Enable HSE */
422       LL_RCC_HSE_Enable();
423       while (LL_RCC_HSE_IsReady() != 1U)
424       {
425         /* Wait for HSE ready */
426       }
427     }
428 
429       /* Configure PLL */
430       LL_RCC_PLL_ConfigDomain_SYS(LL_RCC_PLLSOURCE_HSE, UTILS_PLLInitStruct->PLLMul, UTILS_PLLInitStruct->PLLDiv);
431 
432     /* Enable PLL and switch system clock to PLL */
433     status = UTILS_EnablePLLAndSwitchSystem(pllfreq, UTILS_ClkInitStruct);
434   }
435   else
436   {
437     /* Current PLL configuration cannot be modified */
438     status = ERROR;
439   }
440 
441   return status;
442 }
443 
444 /**
445   * @}
446   */
447 
448 /**
449   * @}
450   */
451 
452 /** @addtogroup UTILS_LL_Private_Functions
453   * @{
454   */
455 /**
456   * @brief  Function to check that PLL can be modified
457   * @param  PLL_InputFrequency  PLL input frequency (in Hz)
458   * @param  UTILS_PLLInitStruct pointer to a @ref LL_UTILS_PLLInitTypeDef structure that contains
459   *                             the configuration information for the PLL.
460   * @retval PLL output frequency (in Hz)
461   */
UTILS_GetPLLOutputFrequency(uint32_t PLL_InputFrequency,LL_UTILS_PLLInitTypeDef * UTILS_PLLInitStruct)462 static uint32_t UTILS_GetPLLOutputFrequency(uint32_t PLL_InputFrequency, LL_UTILS_PLLInitTypeDef *UTILS_PLLInitStruct)
463 {
464   uint32_t pllfreq = 0U;
465 
466   /* Check the parameters */
467   assert_param(IS_LL_UTILS_PLLMUL_VALUE(UTILS_PLLInitStruct->PLLMul));
468   assert_param(IS_LL_UTILS_PLLDIV_VALUE(UTILS_PLLInitStruct->PLLDiv));
469 
470   /* Check different PLL parameters according to RM                          */
471   /* The application software must set correctly the PLL multiplication factor to avoid exceeding
472      96 MHz as PLLVCO when the product is in range 1,
473      48 MHz as PLLVCO when the product is in range 2,
474      24 MHz when the product is in range 3. */
475   pllfreq = PLL_InputFrequency * (PLLMulTable[UTILS_PLLInitStruct->PLLMul >> RCC_CFGR_PLLMUL_Pos]);
476   assert_param(IS_LL_UTILS_PLLVCO_OUTPUT(pllfreq));
477 
478   /* The application software must set correctly the PLL multiplication factor to avoid exceeding
479      maximum frequency 32000000 in range 1 */
480   pllfreq = pllfreq / ((UTILS_PLLInitStruct->PLLDiv >> RCC_CFGR_PLLDIV_Pos)+1U);
481   assert_param(IS_LL_UTILS_PLL_FREQUENCY(pllfreq));
482 
483   return pllfreq;
484 }
485 
486 /**
487   * @brief  Function to check that PLL can be modified
488   * @retval An ErrorStatus enumeration value:
489   *          - SUCCESS: PLL modification can be done
490   *          - ERROR: PLL is busy
491   */
UTILS_PLL_IsBusy(void)492 static ErrorStatus UTILS_PLL_IsBusy(void)
493 {
494   ErrorStatus status = SUCCESS;
495 
496   /* Check if PLL is busy*/
497   if (LL_RCC_PLL_IsReady() != 0U)
498   {
499     /* PLL configuration cannot be modified */
500     status = ERROR;
501   }
502 
503 
504   return status;
505 }
506 
507 /**
508   * @brief  Function to enable PLL and switch system clock to PLL
509   * @param  SYSCLK_Frequency SYSCLK frequency
510   * @param  UTILS_ClkInitStruct pointer to a @ref LL_UTILS_ClkInitTypeDef structure that contains
511   *                             the configuration information for the BUS prescalers.
512   * @retval An ErrorStatus enumeration value:
513   *          - SUCCESS: No problem to switch system to PLL
514   *          - ERROR: Problem to switch system to PLL
515   */
UTILS_EnablePLLAndSwitchSystem(uint32_t SYSCLK_Frequency,LL_UTILS_ClkInitTypeDef * UTILS_ClkInitStruct)516 static ErrorStatus UTILS_EnablePLLAndSwitchSystem(uint32_t SYSCLK_Frequency, LL_UTILS_ClkInitTypeDef *UTILS_ClkInitStruct)
517 {
518   ErrorStatus status = SUCCESS;
519   uint32_t hclk_frequency = 0U;
520 
521   assert_param(IS_LL_UTILS_SYSCLK_DIV(UTILS_ClkInitStruct->AHBCLKDivider));
522   assert_param(IS_LL_UTILS_APB1_DIV(UTILS_ClkInitStruct->APB1CLKDivider));
523   assert_param(IS_LL_UTILS_APB2_DIV(UTILS_ClkInitStruct->APB2CLKDivider));
524 
525   /* Calculate HCLK frequency */
526   hclk_frequency = __LL_RCC_CALC_HCLK_FREQ(SYSCLK_Frequency, UTILS_ClkInitStruct->AHBCLKDivider);
527 
528   /* Increasing the number of wait states because of higher CPU frequency */
529   if (SystemCoreClock < hclk_frequency)
530   {
531     /* Set FLASH latency to highest latency */
532     status = LL_SetFlashLatency(hclk_frequency);
533   }
534 
535   /* Update system clock configuration */
536   if (status == SUCCESS)
537   {
538     /* Enable PLL */
539     LL_RCC_PLL_Enable();
540     while (LL_RCC_PLL_IsReady() != 1U)
541     {
542       /* Wait for PLL ready */
543     }
544 
545     /* Sysclk activation on the main PLL */
546     LL_RCC_SetAHBPrescaler(UTILS_ClkInitStruct->AHBCLKDivider);
547     LL_RCC_SetSysClkSource(LL_RCC_SYS_CLKSOURCE_PLL);
548     while (LL_RCC_GetSysClkSource() != LL_RCC_SYS_CLKSOURCE_STATUS_PLL)
549     {
550       /* Wait for system clock switch to PLL */
551     }
552 
553     /* Set APB1 & APB2 prescaler*/
554     LL_RCC_SetAPB1Prescaler(UTILS_ClkInitStruct->APB1CLKDivider);
555     LL_RCC_SetAPB2Prescaler(UTILS_ClkInitStruct->APB2CLKDivider);
556   }
557 
558   /* Decreasing the number of wait states because of lower CPU frequency */
559   if (SystemCoreClock > hclk_frequency)
560   {
561     /* Set FLASH latency to lowest latency */
562     status = LL_SetFlashLatency(hclk_frequency);
563   }
564 
565   /* Update SystemCoreClock variable */
566   if (status == SUCCESS)
567   {
568     LL_SetSystemCoreClock(hclk_frequency);
569   }
570 
571   return status;
572 }
573 
574 /**
575   * @}
576   */
577 
578 /**
579   * @}
580   */
581 
582 /**
583   * @}
584   */
585