1 /**
2   ******************************************************************************
3   * @file    stm32g0xx_ll_utils.c
4   * @author  MCD Application Team
5   * @brief   UTILS LL module driver.
6   ******************************************************************************
7   * @attention
8   *
9   * Copyright (c) 2018 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 "stm32g0xx_ll_utils.h"
20 #include "stm32g0xx_ll_rcc.h"
21 #include "stm32g0xx_ll_system.h"
22 #include "stm32g0xx_ll_pwr.h"
23 #ifdef  USE_FULL_ASSERT
24 #include "stm32_assert.h"
25 #else
26 #define assert_param(expr) ((void)0U)
27 #endif /* USE_FULL_ASSERT */
28 
29 /** @addtogroup STM32G0xx_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          64000000U     /*!< Maximum frequency for system clock, in Hz */
44 
45 /* Defines used for PLL range */
46 #define UTILS_PLLVCO_INPUT_MIN       4000000U      /*!< Frequency min for PLLVCO input, in Hz   */
47 #define UTILS_PLLVCO_INPUT_MAX       8000000U      /*!< Frequency max for PLLVCO input, in Hz   */
48 #define UTILS_PLLVCO_OUTPUT_MIN      64000000U     /*!< Frequency min for PLLVCO output, in Hz  */
49 #define UTILS_PLLVCO_OUTPUT_MAX      344000000U    /*!< Frequency max for PLLVCO output, in Hz  */
50 
51 /* Defines used for HSE range */
52 #define UTILS_HSE_FREQUENCY_MIN      4000000U      /*!< Frequency min for HSE frequency, in Hz   */
53 #define UTILS_HSE_FREQUENCY_MAX      48000000U     /*!< Frequency max for HSE frequency, in Hz   */
54 
55 /* Defines used for FLASH latency according to HCLK Frequency */
56 #define UTILS_SCALE1_LATENCY1_FREQ  24000000U       /*!< HCLK frequency to set FLASH latency 1 in power scale 1  */
57 #define UTILS_SCALE1_LATENCY2_FREQ  48000000U       /*!< HCLK frequency to set FLASH latency 2 in power scale 1  */
58 #define UTILS_SCALE1_LATENCY3_FREQ  64000000U       /*!< HCLK frequency to set FLASH latency 3 in power scale 1  */
59 /**
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_HSI_DIV(__VALUE__)  (((__VALUE__) == LL_RCC_HSI_DIV_1)  \
84                                       || ((__VALUE__) == LL_RCC_HSI_DIV_2)  \
85                                       || ((__VALUE__) == LL_RCC_HSI_DIV_4)  \
86                                       || ((__VALUE__) == LL_RCC_HSI_DIV_8)  \
87                                       || ((__VALUE__) == LL_RCC_HSI_DIV_16) \
88                                       || ((__VALUE__) == LL_RCC_HSI_DIV_32) \
89                                       || ((__VALUE__) == LL_RCC_HSI_DIV_64) \
90                                       || ((__VALUE__) == LL_RCC_HSI_DIV_128))
91 
92 #define IS_LL_UTILS_PLLM_VALUE(__VALUE__) (((__VALUE__) == LL_RCC_PLLM_DIV_1) \
93                                         || ((__VALUE__) == LL_RCC_PLLM_DIV_2) \
94                                         || ((__VALUE__) == LL_RCC_PLLM_DIV_3) \
95                                         || ((__VALUE__) == LL_RCC_PLLM_DIV_4) \
96                                         || ((__VALUE__) == LL_RCC_PLLM_DIV_5) \
97                                         || ((__VALUE__) == LL_RCC_PLLM_DIV_6) \
98                                         || ((__VALUE__) == LL_RCC_PLLM_DIV_7) \
99                                         || ((__VALUE__) == LL_RCC_PLLM_DIV_8))
100 
101 #define IS_LL_UTILS_PLLN_VALUE(__VALUE__) ((8U <= (__VALUE__)) && ((__VALUE__) <= 86U))
102 
103 #define IS_LL_UTILS_PLLR_VALUE(__VALUE__) (((__VALUE__) == LL_RCC_PLLR_DIV_2) \
104                                         || ((__VALUE__) == LL_RCC_PLLR_DIV_3) \
105                                         || ((__VALUE__) == LL_RCC_PLLR_DIV_4) \
106                                         || ((__VALUE__) == LL_RCC_PLLR_DIV_5) \
107                                         || ((__VALUE__) == LL_RCC_PLLR_DIV_6) \
108                                         || ((__VALUE__) == LL_RCC_PLLR_DIV_7) \
109                                         || ((__VALUE__) == LL_RCC_PLLR_DIV_8))
110 
111 #define IS_LL_UTILS_PLLVCO_INPUT(__VALUE__)  ((UTILS_PLLVCO_INPUT_MIN <= (__VALUE__)) && ((__VALUE__) <= UTILS_PLLVCO_INPUT_MAX))
112 
113 #define IS_LL_UTILS_PLLVCO_OUTPUT(__VALUE__) ((UTILS_PLLVCO_OUTPUT_MIN <= (__VALUE__)) && ((__VALUE__) <= UTILS_PLLVCO_OUTPUT_MAX))
114 
115 #define IS_LL_UTILS_PLL_FREQUENCY(__VALUE__) ((__VALUE__) <= UTILS_MAX_FREQUENCY)
116 
117 #define IS_LL_UTILS_HSE_BYPASS(__STATE__) (((__STATE__) == LL_UTILS_HSEBYPASS_ON) \
118                                         || ((__STATE__) == LL_UTILS_HSEBYPASS_OFF))
119 
120 #define IS_LL_UTILS_HSE_FREQUENCY(__FREQUENCY__) (((__FREQUENCY__) >= UTILS_HSE_FREQUENCY_MIN) && ((__FREQUENCY__) <= UTILS_HSE_FREQUENCY_MAX))
121 /**
122   * @}
123   */
124 /* Private function prototypes -----------------------------------------------*/
125 /** @defgroup UTILS_LL_Private_Functions UTILS Private functions
126   * @{
127   */
128 static uint32_t    UTILS_GetPLLOutputFrequency(uint32_t PLL_InputFrequency,
129                                                LL_UTILS_PLLInitTypeDef *UTILS_PLLInitStruct);
130 static ErrorStatus UTILS_EnablePLLAndSwitchSystem(uint32_t SYSCLK_Frequency, LL_UTILS_ClkInitTypeDef *UTILS_ClkInitStruct);
131 static ErrorStatus UTILS_PLL_IsBusy(void);
132 /**
133   * @}
134   */
135 
136 /* Exported functions --------------------------------------------------------*/
137 /** @addtogroup UTILS_LL_Exported_Functions
138   * @{
139   */
140 
141 /** @addtogroup UTILS_LL_EF_DELAY
142   * @{
143   */
144 
145 /**
146   * @brief  This function configures the Cortex-M SysTick source to have 1ms time base.
147   * @note   When a RTOS is used, it is recommended to avoid changing the Systick
148   *         configuration by calling this function, for a delay use rather osDelay RTOS service.
149   * @param  HCLKFrequency HCLK frequency in Hz
150   * @note   HCLK frequency can be calculated thanks to RCC helper macro or function @ref LL_RCC_GetSystemClocksFreq
151   * @retval None
152   */
LL_Init1msTick(uint32_t HCLKFrequency)153 void LL_Init1msTick(uint32_t HCLKFrequency)
154 {
155   /* Use frequency provided in argument */
156   LL_InitTick(HCLKFrequency, 1000U);
157 }
158 
159 /**
160   * @brief  This function provides accurate delay (in milliseconds) based
161   *         on SysTick counter flag
162   * @note   When a RTOS is used, it is recommended to avoid using blocking delay
163   *         and use rather osDelay service.
164   * @note   To respect 1ms timebase, user should call @ref LL_Init1msTick function which
165   *         will configure Systick to 1ms
166   * @param  Delay specifies the delay time length, in milliseconds.
167   * @retval None
168   */
LL_mDelay(uint32_t Delay)169 void LL_mDelay(uint32_t Delay)
170 {
171   __IO uint32_t  tmp = SysTick->CTRL;  /* Clear the COUNTFLAG first */
172    uint32_t tmpDelay; /* MISRAC2012-Rule-17.8 */
173   /* Add this code to indicate that local variable is not used */
174   ((void)tmp);
175   tmpDelay  = Delay;
176   /* Add a period to guaranty minimum wait */
177   if (tmpDelay  < LL_MAX_DELAY)
178   {
179     tmpDelay ++;
180   }
181 
182   while (tmpDelay  != 0U)
183   {
184     if ((SysTick->CTRL & SysTick_CTRL_COUNTFLAG_Msk) != 0U)
185     {
186       tmpDelay --;
187     }
188   }
189 }
190 
191 /**
192   * @}
193   */
194 
195 /** @addtogroup UTILS_EF_SYSTEM
196   *  @brief    System Configuration functions
197   *
198   @verbatim
199  ===============================================================================
200            ##### System Configuration functions #####
201  ===============================================================================
202     [..]
203          System, AHB and APB buses clocks configuration
204 
205          (+) The maximum frequency of the SYSCLK, HCLK, PCLK1 is 64000000 Hz.
206   @endverbatim
207   @internal
208              Depending on the device voltage range, the maximum frequency should be
209              adapted accordingly:
210 
211              (++)  Table 1. HCLK clock frequency.
212              (++)  +-------------------------------------------------------+
213              (++)  | Latency         |    HCLK clock frequency (MHz)       |
214              (++)  |                 |-------------------------------------|
215              (++)  |                 | voltage range 1  | voltage range 2  |
216              (++)  |                 |   1.08V - 1.32V  |  0.9 V - 1.10V   |
217              (++)  |-----------------|------------------|------------------|
218              (++)  |0WS(1 CPU cycles)|      HCLK <= 24  |      HCLK <= 8   |
219              (++)  |-----------------|------------------|------------------|
220              (++)  |1WS(2 CPU cycles)|      HCLK <= 48  |      HCLK <= 16  |
221              (++)  |-----------------|------------------|------------------|
222              (++)  |2WS(3 CPU cycles)|      HCLK <= 64  |        -         |
223              (++)  |-----------------|------------------|------------------|
224 
225   @endinternal
226   * @{
227   */
228 
229 /**
230   * @brief  This function sets directly SystemCoreClock CMSIS variable.
231   * @note   Variable can be calculated also through SystemCoreClockUpdate function.
232   * @param  HCLKFrequency HCLK frequency in Hz (can be calculated thanks to RCC helper macro)
233   * @retval None
234   */
LL_SetSystemCoreClock(uint32_t HCLKFrequency)235 void LL_SetSystemCoreClock(uint32_t HCLKFrequency)
236 {
237   /* HCLK clock frequency */
238   SystemCoreClock = HCLKFrequency;
239 }
240 
241 /**
242   * @brief  This function configures system clock at maximum frequency with HSI as clock source of the PLL
243   * @note   The application need to ensure that PLL is disabled.
244   * @note   Function is based on the following formula:
245   *         - PLL output frequency = (((HSI frequency / PLLM) * PLLN) / PLLR)
246   *         - PLLM: ensure that the VCO input frequency ranges from 4 to 16 MHz (PLLVCO_input = HSI frequency / PLLM)
247   *         - PLLN: ensure that the VCO output frequency is between 64 and 344 MHz (PLLVCO_output = PLLVCO_input * PLLN)
248   *         - PLLR: ensure that max frequency at 64000000 Hz is reach (PLLVCO_output / PLLR)
249   * @param  UTILS_PLLInitStruct pointer to a @ref LL_UTILS_PLLInitTypeDef structure that contains
250   *                             the configuration information for the PLL.
251   * @param  UTILS_ClkInitStruct pointer to a @ref LL_UTILS_ClkInitTypeDef structure that contains
252   *                             the configuration information for the BUS prescalers.
253   * @retval An ErrorStatus enumeration value:
254   *          - SUCCESS: Max frequency configuration done
255   *          - ERROR: Max frequency configuration not done
256   */
LL_PLL_ConfigSystemClock_HSI(LL_UTILS_PLLInitTypeDef * UTILS_PLLInitStruct,LL_UTILS_ClkInitTypeDef * UTILS_ClkInitStruct)257 ErrorStatus LL_PLL_ConfigSystemClock_HSI(LL_UTILS_PLLInitTypeDef *UTILS_PLLInitStruct,
258                                          LL_UTILS_ClkInitTypeDef *UTILS_ClkInitStruct)
259 {
260   ErrorStatus status;
261   uint32_t pllfreq;
262 
263   /* Check if one of the PLL is enabled */
264   if (UTILS_PLL_IsBusy() == SUCCESS)
265   {
266     /* Calculate the new PLL output frequency */
267     pllfreq = UTILS_GetPLLOutputFrequency(HSI_VALUE, UTILS_PLLInitStruct);
268 
269     /* Enable HSI if not enabled */
270     if (LL_RCC_HSI_IsReady() != 1U)
271     {
272       LL_RCC_HSI_Enable();
273       while (LL_RCC_HSI_IsReady() != 1U)
274       {
275         /* Wait for HSI ready */
276       }
277     }
278 
279     /* Configure PLL */
280     LL_RCC_PLL_ConfigDomain_SYS(LL_RCC_PLLSOURCE_HSI, UTILS_PLLInitStruct->PLLM, UTILS_PLLInitStruct->PLLN,
281                                 UTILS_PLLInitStruct->PLLR);
282 
283     /* Enable PLL and switch system clock to PLL */
284     status = UTILS_EnablePLLAndSwitchSystem(pllfreq, UTILS_ClkInitStruct);
285   }
286   else
287   {
288     /* Current PLL configuration cannot be modified */
289     status = ERROR;
290   }
291 
292   return status;
293 }
294 
295 /**
296   * @brief  This function configures system clock with HSE as clock source of the PLL
297   * @note   The application need to ensure that PLL is disabled.
298   * @note   Function is based on the following formula:
299   *         - PLL output frequency = (((HSE frequency / PLLM) * PLLN) / PLLR)
300   *         - PLLM: ensure that the VCO input frequency ranges from 4 to 16 MHz (PLLVCO_input = HSE frequency / PLLM)
301   *         - PLLN: ensure that the VCO output frequency is between 64 and 344 MHz (PLLVCO_output = PLLVCO_input * PLLN)
302   *         - PLLR: ensure that max frequency at 64000000 Hz is reached (PLLVCO_output / PLLR)
303   * @param  HSEFrequency Value between Min_Data = 4000000 and Max_Data = 48000000
304   * @param  HSEBypass This parameter can be one of the following values:
305   *         @arg @ref LL_UTILS_HSEBYPASS_ON
306   *         @arg @ref LL_UTILS_HSEBYPASS_OFF
307   * @param  UTILS_PLLInitStruct pointer to a @ref LL_UTILS_PLLInitTypeDef structure that contains
308   *                             the configuration information for the PLL.
309   * @param  UTILS_ClkInitStruct pointer to a @ref LL_UTILS_ClkInitTypeDef structure that contains
310   *                             the configuration information for the BUS prescalers.
311   * @retval An ErrorStatus enumeration value:
312   *          - SUCCESS: Max frequency configuration done
313   *          - ERROR: Max frequency configuration not done
314   */
LL_PLL_ConfigSystemClock_HSE(uint32_t HSEFrequency,uint32_t HSEBypass,LL_UTILS_PLLInitTypeDef * UTILS_PLLInitStruct,LL_UTILS_ClkInitTypeDef * UTILS_ClkInitStruct)315 ErrorStatus LL_PLL_ConfigSystemClock_HSE(uint32_t HSEFrequency, uint32_t HSEBypass,
316                                          LL_UTILS_PLLInitTypeDef *UTILS_PLLInitStruct, LL_UTILS_ClkInitTypeDef *UTILS_ClkInitStruct)
317 {
318   ErrorStatus status;
319   uint32_t pllfreq;
320 
321   /* Check the parameters */
322   assert_param(IS_LL_UTILS_HSE_FREQUENCY(HSEFrequency));
323   assert_param(IS_LL_UTILS_HSE_BYPASS(HSEBypass));
324 
325   /* Check if one of the PLL is enabled */
326   if (UTILS_PLL_IsBusy() == SUCCESS)
327   {
328     /* Calculate the new PLL output frequency */
329     pllfreq = UTILS_GetPLLOutputFrequency(HSEFrequency, UTILS_PLLInitStruct);
330 
331     /* Enable HSE if not enabled */
332     if (LL_RCC_HSE_IsReady() != 1U)
333     {
334       /* Check if need to enable HSE bypass feature or not */
335       if (HSEBypass == LL_UTILS_HSEBYPASS_ON)
336       {
337         LL_RCC_HSE_EnableBypass();
338       }
339       else
340       {
341         LL_RCC_HSE_DisableBypass();
342       }
343 
344       /* Enable HSE */
345       LL_RCC_HSE_Enable();
346       while (LL_RCC_HSE_IsReady() != 1U)
347       {
348         /* Wait for HSE ready */
349       }
350     }
351 
352     /* Configure PLL */
353     LL_RCC_PLL_ConfigDomain_SYS(LL_RCC_PLLSOURCE_HSE, UTILS_PLLInitStruct->PLLM, UTILS_PLLInitStruct->PLLN,
354                                 UTILS_PLLInitStruct->PLLR);
355 
356     /* Enable PLL and switch system clock to PLL */
357     status = UTILS_EnablePLLAndSwitchSystem(pllfreq, UTILS_ClkInitStruct);
358   }
359   else
360   {
361     /* Current PLL configuration cannot be modified */
362     status = ERROR;
363   }
364 
365   return status;
366 }
367 
368 /**
369   * @brief  Update number of Flash wait states in line with new frequency and current
370   *         voltage range.
371   * @param  HCLKFrequency  HCLK frequency
372   * @retval An ErrorStatus enumeration value:
373   *          - SUCCESS: Latency has been modified
374   *          - ERROR: Latency cannot be modified
375   */
LL_SetFlashLatency(uint32_t HCLKFrequency)376 ErrorStatus LL_SetFlashLatency(uint32_t HCLKFrequency)
377 {
378   uint32_t timeout;
379   uint32_t getlatency;
380   uint32_t latency;
381   ErrorStatus status;
382 
383   /* Frequency cannot be equal to 0 or greater than max clock */
384   if ((HCLKFrequency == 0U) || (HCLKFrequency > UTILS_SCALE1_LATENCY3_FREQ))
385   {
386     status = ERROR;
387   }
388   else
389   {
390     if (HCLKFrequency > UTILS_SCALE1_LATENCY2_FREQ)
391     {
392       /* 48 < HCLK <= 64 => 2WS (3 CPU cycles) */
393       latency = LL_FLASH_LATENCY_2;
394     }
395     else
396     {
397       if (HCLKFrequency > UTILS_SCALE1_LATENCY1_FREQ)
398       {
399         /* 24 < HCLK <= 48 => 1WS (2 CPU cycles) */
400         latency = LL_FLASH_LATENCY_1;
401       }
402       else
403       {
404         /* else HCLKFrequency < 24MHz default LL_FLASH_LATENCY_0 0WS */
405         latency = LL_FLASH_LATENCY_0;
406       }
407     }
408 
409     LL_FLASH_SetLatency(latency);
410 
411     /* Check that the new number of wait states is taken into account to access the Flash
412        memory by reading the FLASH_ACR register */
413     timeout = 2u;
414     do
415     {
416       /* Wait for Flash latency to be updated */
417       getlatency = LL_FLASH_GetLatency();
418       timeout--;
419     } while ((getlatency != latency) && (timeout > 0u));
420 
421     if(getlatency != latency)
422     {
423       status = ERROR;
424     }
425     else
426     {
427       status = SUCCESS;
428     }
429   }
430 
431   return status;
432 }
433 
434 /**
435   * @}
436   */
437 
438 /**
439   * @}
440   */
441 
442 /** @addtogroup UTILS_LL_Private_Functions
443   * @{
444   */
445 
446 /**
447   * @brief  Function to check that PLL can be modified
448   * @param  PLL_InputFrequency  PLL input frequency (in Hz)
449   * @param  UTILS_PLLInitStruct pointer to a @ref LL_UTILS_PLLInitTypeDef structure that contains
450   *                             the configuration information for the PLL.
451   * @retval PLL output frequency (in Hz)
452   */
UTILS_GetPLLOutputFrequency(uint32_t PLL_InputFrequency,LL_UTILS_PLLInitTypeDef * UTILS_PLLInitStruct)453 static uint32_t UTILS_GetPLLOutputFrequency(uint32_t PLL_InputFrequency, LL_UTILS_PLLInitTypeDef *UTILS_PLLInitStruct)
454 {
455   uint32_t pllfreq;
456 
457   /* Check the parameters */
458   assert_param(IS_LL_UTILS_PLLM_VALUE(UTILS_PLLInitStruct->PLLM));
459   assert_param(IS_LL_UTILS_PLLN_VALUE(UTILS_PLLInitStruct->PLLN));
460   assert_param(IS_LL_UTILS_PLLR_VALUE(UTILS_PLLInitStruct->PLLR));
461 
462   /* Check different PLL parameters according to RM                          */
463   /*  - PLLM: ensure that the VCO input frequency ranges from 4 to 16 MHz.   */
464   pllfreq = PLL_InputFrequency / (((UTILS_PLLInitStruct->PLLM >> RCC_PLLCFGR_PLLM_Pos) + 1U));
465   assert_param(IS_LL_UTILS_PLLVCO_INPUT(pllfreq));
466 
467   /*  - PLLN: ensure that the VCO output frequency is between 64 and 344 MHz.*/
468   pllfreq = pllfreq * (UTILS_PLLInitStruct->PLLN & (RCC_PLLCFGR_PLLN >> RCC_PLLCFGR_PLLN_Pos));
469   assert_param(IS_LL_UTILS_PLLVCO_OUTPUT(pllfreq));
470 
471   /*  - PLLR: ensure that max frequency at 64000000 Hz is reached                   */
472   pllfreq = pllfreq / (((UTILS_PLLInitStruct->PLLR >> RCC_PLLCFGR_PLLR_Pos) + 1U));
473   assert_param(IS_LL_UTILS_PLL_FREQUENCY(pllfreq));
474 
475   return pllfreq;
476 }
477 
478 /**
479   * @brief  Function to check that PLL can be modified
480   * @retval An ErrorStatus enumeration value:
481   *          - SUCCESS: PLL modification can be done
482   *          - ERROR: PLL is busy
483   */
UTILS_PLL_IsBusy(void)484 static ErrorStatus UTILS_PLL_IsBusy(void)
485 {
486   ErrorStatus status = SUCCESS;
487 
488   /* Check if PLL is busy*/
489   if (LL_RCC_PLL_IsReady() != 0U)
490   {
491     /* PLL configuration cannot be modified */
492     status = ERROR;
493   }
494 
495   return status;
496 }
497 
498 /**
499   * @brief  Function to enable PLL and switch system clock to PLL
500   * @param  SYSCLK_Frequency SYSCLK frequency
501   * @param  UTILS_ClkInitStruct pointer to a @ref LL_UTILS_ClkInitTypeDef structure that contains
502   *                             the configuration information for the BUS prescalers.
503   * @retval An ErrorStatus enumeration value:
504   *          - SUCCESS: No problem to switch system to PLL
505   *          - ERROR: Problem to switch system to PLL
506   */
UTILS_EnablePLLAndSwitchSystem(uint32_t SYSCLK_Frequency,LL_UTILS_ClkInitTypeDef * UTILS_ClkInitStruct)507 static ErrorStatus UTILS_EnablePLLAndSwitchSystem(uint32_t SYSCLK_Frequency, LL_UTILS_ClkInitTypeDef *UTILS_ClkInitStruct)
508 {
509   ErrorStatus status = SUCCESS;
510   uint32_t hclk_frequency;
511 
512   assert_param(IS_LL_UTILS_SYSCLK_DIV(UTILS_ClkInitStruct->AHBCLKDivider));
513   assert_param(IS_LL_UTILS_APB1_DIV(UTILS_ClkInitStruct->APB1CLKDivider));
514 
515   /* Calculate HCLK frequency */
516   hclk_frequency = __LL_RCC_CALC_HCLK_FREQ(SYSCLK_Frequency, UTILS_ClkInitStruct->AHBCLKDivider);
517 
518   /* Increasing the number of wait states because of higher CPU frequency */
519   if (SystemCoreClock < hclk_frequency)
520   {
521     /* Set FLASH latency to highest latency */
522     status = LL_SetFlashLatency(hclk_frequency);
523   }
524 
525   /* Update system clock configuration */
526   if (status == SUCCESS)
527   {
528     /* Enable PLL */
529     LL_RCC_PLL_Enable();
530     LL_RCC_PLL_EnableDomain_SYS();
531     while (LL_RCC_PLL_IsReady() != 1U)
532     {
533       /* Wait for PLL ready */
534     }
535 
536     /* Sysclk activation on the main PLL */
537     LL_RCC_SetAHBPrescaler(UTILS_ClkInitStruct->AHBCLKDivider);
538     LL_RCC_SetSysClkSource(LL_RCC_SYS_CLKSOURCE_PLL);
539     while (LL_RCC_GetSysClkSource() != LL_RCC_SYS_CLKSOURCE_STATUS_PLL)
540     {
541       /* Wait for system clock switch to PLL */
542     }
543 
544     /* Set APB1 & APB2 prescaler*/
545     LL_RCC_SetAPB1Prescaler(UTILS_ClkInitStruct->APB1CLKDivider);
546   }
547 
548   /* Decreasing the number of wait states because of lower CPU frequency */
549   if (SystemCoreClock > hclk_frequency)
550   {
551     /* Set FLASH latency to lowest latency */
552     status = LL_SetFlashLatency(hclk_frequency);
553   }
554 
555   /* Update SystemCoreClock variable */
556   if (status == SUCCESS)
557   {
558     LL_SetSystemCoreClock(hclk_frequency);
559   }
560 
561   return status;
562 }
563 
564 /**
565   * @}
566   */
567 
568 /**
569   * @}
570   */
571 
572 /**
573   * @}
574   */
575