1 /**
2   ******************************************************************************
3   * @file    stm32wbaxx_ll_utils.c
4   * @author  MCD Application Team
5   * @brief   UTILS LL module driver.
6   ******************************************************************************
7   * @attention
8   *
9   * Copyright (c) 2022 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 "stm32wbaxx_ll_utils.h"
20 #include "stm32wbaxx_ll_rcc.h"
21 #include "stm32wbaxx_ll_system.h"
22 #include "stm32wbaxx_ll_pwr.h"
23 #include <math.h>
24 #ifdef  USE_FULL_ASSERT
25 #include "stm32_assert.h"
26 #else
27 #define assert_param(expr) ((void)0U)
28 #endif /* USE_FULL_ASSERT */
29 
30 /** @addtogroup STM32WBAxx_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  100000000U  /*!< 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 
47 /* Defines used for PLL range */
48 #define UTILS_PLLVCO_INPUT_MIN        4000000U  /*!< Frequency min for PLLVCO input, in Hz   */
49 #define UTILS_PLLVCO_INPUT_MAX       16000000U  /*!< Frequency max for PLLVCO input, in Hz   */
50 #define UTILS_PLLVCO_OUTPUT_MIN     128000000U  /*!< Frequency min for PLLVCO output, in Hz  */
51 #define UTILS_PLLVCO_OUTPUT_MAX     544000000U  /*!< Frequency max for PLLVCO output, in Hz  */
52 
53 /* Defines used for FLASH latency according to HCLK Frequency */
54 #define UTILS_SCALE1_LATENCY0_FREQ   32000000U  /*!< HCLK frequency to set FLASH latency 0 in power scale 1 */
55 #define UTILS_SCALE1_LATENCY1_FREQ   64000000U  /*!< HCLK frequency to set FLASH latency 1 in power scale 1 */
56 #define UTILS_SCALE1_LATENCY2_FREQ   96000000U  /*!< HCLK frequency to set FLASH latency 2 in power scale 1 */
57 #define UTILS_SCALE1_LATENCY3_FREQ  100000000U  /*!< HCLK frequency to set FLASH latency 3 in power scale 1 */
58 #define UTILS_SCALE2_LATENCY0_FREQ    8000000U  /*!< HCLK frequency to set FLASH latency 0 in power scale 2 */
59 #define UTILS_SCALE2_LATENCY1_FREQ   16000000U  /*!< HCLK frequency to set FLASH latency 1 in power scale 2 */
60 
61 /**
62   * @}
63   */
64 
65 /* Private macros ------------------------------------------------------------*/
66 /** @addtogroup UTILS_LL_Private_Macros
67   * @{
68   */
69 #define IS_LL_UTILS_SYSCLK_DIV(__VALUE__) (((__VALUE__) == LL_RCC_SYSCLK_DIV_1)   \
70                                            || ((__VALUE__) == LL_RCC_SYSCLK_DIV_2)   \
71                                            || ((__VALUE__) == LL_RCC_SYSCLK_DIV_4)   \
72                                            || ((__VALUE__) == LL_RCC_SYSCLK_DIV_8)   \
73                                            || ((__VALUE__) == LL_RCC_SYSCLK_DIV_16))
74 
75 #define IS_LL_UTILS_APB1_DIV(__VALUE__) (((__VALUE__) == LL_RCC_APB1_DIV_1) \
76                                          || ((__VALUE__) == LL_RCC_APB1_DIV_2) \
77                                          || ((__VALUE__) == LL_RCC_APB1_DIV_4) \
78                                          || ((__VALUE__) == LL_RCC_APB1_DIV_8) \
79                                          || ((__VALUE__) == LL_RCC_APB1_DIV_16))
80 
81 #define IS_LL_UTILS_APB2_DIV(__VALUE__) (((__VALUE__) == LL_RCC_APB2_DIV_1) \
82                                          || ((__VALUE__) == LL_RCC_APB2_DIV_2) \
83                                          || ((__VALUE__) == LL_RCC_APB2_DIV_4) \
84                                          || ((__VALUE__) == LL_RCC_APB2_DIV_8) \
85                                          || ((__VALUE__) == LL_RCC_APB2_DIV_16))
86 
87 #define IS_LL_UTILS_APB7_DIV(__VALUE__) (((__VALUE__) == LL_RCC_APB7_DIV_1) \
88                                          || ((__VALUE__) == LL_RCC_APB7_DIV_2) \
89                                          || ((__VALUE__) == LL_RCC_APB7_DIV_4) \
90                                          || ((__VALUE__) == LL_RCC_APB7_DIV_8) \
91                                          || ((__VALUE__) == LL_RCC_APB7_DIV_16))
92 
93 #define IS_LL_UTILS_PLLM_VALUE(__VALUE__) ((1U <= (__VALUE__)) && ((__VALUE__) <= 16U))
94 
95 #define IS_LL_UTILS_PLLN_VALUE(__VALUE__) ((4U <= (__VALUE__)) && ((__VALUE__) <= 512U))
96 
97 #define IS_LL_UTILS_PLLR_VALUE(__VALUE__) ((1U <= (__VALUE__)) && ((__VALUE__) <= 128U))
98 
99 #define IS_LL_UTILS_PLLVCO_INPUT(__VALUE__)  ((UTILS_PLLVCO_INPUT_MIN <= (__VALUE__))\
100                                               && ((__VALUE__) <= UTILS_PLLVCO_INPUT_MAX))
101 
102 #define IS_LL_UTILS_PLLVCO_OUTPUT(__VALUE__) ((UTILS_PLLVCO_OUTPUT_MIN <= (__VALUE__))\
103                                               && ((__VALUE__) <= UTILS_PLLVCO_OUTPUT_MAX))
104 
105 #define IS_LL_UTILS_PLL_FREQUENCY(__VALUE__) ((LL_PWR_GetRegulVoltageScaling() == LL_PWR_REGU_VOLTAGE_SCALE1) ? \
106                                               ((__VALUE__) <= UTILS_MAX_FREQUENCY_SCALE1) : \
107                                               ((__VALUE__) <= UTILS_MAX_FREQUENCY_SCALE2))
108 
109 #define IS_LL_UTILS_HSE_FREQUENCY(__FREQUENCY__) ((__FREQUENCY__) == 32000000U)
110 /**
111   * @}
112   */
113 /* Private function prototypes -----------------------------------------------*/
114 /** @defgroup UTILS_LL_Private_Functions UTILS Private functions
115   * @{
116   */
117 static uint32_t    UTILS_GetPLLOutputFrequency(uint32_t PLL_InputFrequency,
118                                                const LL_UTILS_PLLInitTypeDef *UTILS_PLLInitStruct);
119 static ErrorStatus UTILS_EnablePLLAndSwitchSystem(uint32_t SYSCLK_Frequency,
120                                                   LL_UTILS_ClkInitTypeDef *UTILS_ClkInitStruct);
121 static ErrorStatus UTILS_PLL_IsBusy(void);
122 /**
123   * @}
124   */
125 
126 /* Exported functions --------------------------------------------------------*/
127 /** @addtogroup UTILS_LL_Exported_Functions
128   * @{
129   */
130 
131 /** @addtogroup UTILS_LL_EF_DELAY
132   * @{
133   */
134 
135 /**
136   * @brief  This function configures the Cortex-M SysTick source to have 1ms time base.
137   * @note   When a RTOS is used, it is recommended to avoid changing the Systick
138   *         configuration by calling this function, for a delay use rather osDelay RTOS service.
139   * @param  HCLKFrequency HCLK frequency in Hz
140   * @note   HCLK frequency can be calculated thanks to RCC helper macro or function @ref LL_RCC_GetSystemClocksFreq
141   * @retval None
142   */
LL_Init1msTick(uint32_t HCLKFrequency)143 void LL_Init1msTick(uint32_t HCLKFrequency)
144 {
145   /* Use frequency provided in argument */
146   LL_InitTick(HCLKFrequency, 1000U);
147 }
148 
149 /**
150   * @brief  This function provides accurate delay (in milliseconds) based
151   *         on SysTick counter flag
152   * @note   When a RTOS is used, it is recommended to avoid using blocking delay
153   *         and use rather osDelay service.
154   * @note   To respect 1ms timebase, user should call @ref LL_Init1msTick function which
155   *         will configure Systick to 1ms
156   * @param  Delay specifies the delay time length, in milliseconds.
157   * @retval None
158   */
159 
LL_mDelay(uint32_t Delay)160 void LL_mDelay(uint32_t Delay)
161 {
162   __IO uint32_t  tmp = SysTick->CTRL;  /* Clear the COUNTFLAG first */
163   uint32_t tmpDelay = Delay;
164 
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 (tmpDelay < LL_MAX_DELAY)
170   {
171     tmpDelay++;
172   }
173 
174   while (tmpDelay != 0U)
175   {
176     if ((SysTick->CTRL & SysTick_CTRL_COUNTFLAG_Msk) != 0U)
177     {
178       tmpDelay--;
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, PCLK7 is
198              100000000 Hz.
199   @endverbatim
200   @internal
201              Depending on the device voltage range, the maximum frequency should be
202              adapted accordingly:
203 
204              (++) Table 1. HCLK clock frequency for STM32WBA devices
205              (++) +----------------------------------------------------------+
206              (++) | Latency           |       HCLK clock frequency (MHz)     |
207              (++) |                   |--------------------------------------|
208              (++) |                   |  voltage range 1  |  voltage range 2 |
209              (++) |                   |       1.2 V       |       1.1 V      |
210              (++) |-------------------|-------------------|------------------|
211              (++) |0 WS (1 CPU cycles)|   0 < HCLK <= 32  |  0 < HCLK <= 8   |
212              (++) |-------------------|-------------------|------------------|
213              (++) |1 WS (2 CPU cycles)|  32 < HCLK <= 64  |  25 < HCLK <= 16 |
214              (++) |-------------------|-------------------|------------------|
215              (++) |2 WS (3 CPU cycles)|  64 < HCLK <= 96  |  50 < HCLK <= 24 |
216              (++) |-------------------|-------------------|------------------|
217              (++) |3 WS (4 CPU cycles)|  96 < HCLK <= 100 |
218              (++) |-------------------|-------------------|
219 
220 
221   @endinternal
222   * @{
223   */
224 
225 /**
226   * @brief  This function sets directly SystemCoreClock CMSIS variable.
227   * @note   Variable can be calculated also through SystemCoreClockUpdate function.
228   * @param  HCLKFrequency HCLK frequency in Hz (can be calculated thanks to RCC helper macro)
229   * @retval None
230   */
LL_SetSystemCoreClock(uint32_t HCLKFrequency)231 void LL_SetSystemCoreClock(uint32_t HCLKFrequency)
232 {
233   /* HCLK clock frequency */
234   SystemCoreClock = HCLKFrequency;
235 }
236 
237 
238 
239 /**
240   * @brief  This function configures system clock at maximum frequency with HSI as clock source of the PLL
241   * @note   The application need to ensure that PLL1, PLL2 and/or PLL3 are disabled.
242   * @note   Function is based on the following formula:
243   *         - PLL output frequency = (((HSI frequency / PLLM) * PLLN) / PLLR)
244   *         - PLL1M: ensure that the VCO input frequency ranges from 4 to 16 MHz (PLL1VCO_input = HSI frequency / PLL1M)
245   *         - PLL1N: ensure that the VCO output frequency is between 128 and 544 MHz
246              (PLL1VCO_output = PLL1VCO_input * PLL1N)
247   *         - PLL1R: ensure that max frequency at 100 MHz is reached (PLL1VCO_output / PLL1R)
248   * @param  UTILS_PLLInitStruct pointer to a @ref LL_UTILS_PLLInitTypeDef structure that contains
249   *                             the configuration information for the PLL.
250   * @param  UTILS_ClkInitStruct pointer to a @ref LL_UTILS_ClkInitTypeDef structure that contains
251   *                             the configuration information for the BUS prescalers.
252   * @retval An ErrorStatus enumeration value:
253   *          - SUCCESS: Max frequency configuration done
254   *          - ERROR: Max frequency configuration not done
255   */
LL_PLL1_ConfigSystemClock_HSI(LL_UTILS_PLLInitTypeDef * UTILS_PLLInitStruct,LL_UTILS_ClkInitTypeDef * UTILS_ClkInitStruct)256 ErrorStatus LL_PLL1_ConfigSystemClock_HSI(LL_UTILS_PLLInitTypeDef *UTILS_PLLInitStruct,
257                                           LL_UTILS_ClkInitTypeDef *UTILS_ClkInitStruct)
258 {
259   ErrorStatus status;
260   uint32_t pllfreq;
261 
262   /* Check if one of the PLL is enabled */
263   if (UTILS_PLL_IsBusy() == SUCCESS)
264   {
265     /* Calculate the new PLL output frequency */
266     pllfreq = UTILS_GetPLLOutputFrequency(HSI_VALUE, UTILS_PLLInitStruct);
267 
268     /* Enable HSI if not enabled */
269     if (LL_RCC_HSI_IsReady() != 1U)
270     {
271       LL_RCC_HSI_Enable();
272       while (LL_RCC_HSI_IsReady() != 1U)
273       {
274         /* Wait for HSI ready */
275       }
276     }
277 
278     /* Configure PLL */
279     LL_RCC_PLL1_ConfigDomain_SYS(LL_RCC_PLL1SOURCE_HSI, UTILS_PLLInitStruct->PLLM, UTILS_PLLInitStruct->PLLN,
280                                  UTILS_PLLInitStruct->PLLR);
281 
282     /* Enable PLL and switch system clock to PLL */
283     status = UTILS_EnablePLLAndSwitchSystem(pllfreq, UTILS_ClkInitStruct);
284   }
285   else
286   {
287     /* Current PLL configuration cannot be modified */
288     status = ERROR;
289   }
290 
291   return status;
292 }
293 
294 /**
295   * @brief  This function configures system clock with HSE as clock source of the PLL
296   * @note   The application need to ensure that PLL, PLLSAI1 and/or PLLSAI2 are disabled.
297   * @note   Function is based on the following formula:
298   *         - PLL output frequency = (((HSE frequency / PLLM) * PLLN) / PLLR)
299   *         - PLL1M: ensure that the VCO input frequency ranges from 4 to 16 MHz (PLL1VCO_input = HSE frequency / PLL1M)
300   *         - PLL1N: ensure that the VCO output frequency is between 128 and 544 MHz
301              (PLL1VCO_output = PLL1VCO_input * PLL1N)
302   *         - PLL1R: ensure that max frequency at 100 MHz is reached (PLL1VCO_output / PLL1R)
303   * @param  HSEFrequency Value at 32000000
304   * @param  UTILS_PLLInitStruct pointer to a @ref LL_UTILS_PLLInitTypeDef structure that contains
305   *                             the configuration information for the PLL.
306   * @param  UTILS_ClkInitStruct pointer to a @ref LL_UTILS_ClkInitTypeDef structure that contains
307   *                             the configuration information for the BUS prescalers.
308   * @retval An ErrorStatus enumeration value:
309   *          - SUCCESS: Max frequency configuration done
310   *          - ERROR: Max frequency configuration not done
311   */
LL_PLL1_ConfigSystemClock_HSE(uint32_t HSEFrequency,LL_UTILS_PLLInitTypeDef * UTILS_PLLInitStruct,LL_UTILS_ClkInitTypeDef * UTILS_ClkInitStruct)312 ErrorStatus LL_PLL1_ConfigSystemClock_HSE(uint32_t HSEFrequency,
313                                           LL_UTILS_PLLInitTypeDef *UTILS_PLLInitStruct,
314                                           LL_UTILS_ClkInitTypeDef *UTILS_ClkInitStruct)
315 {
316   ErrorStatus status;
317   uint32_t pllfreq;
318 
319   /* Check the parameters */
320   assert_param(IS_LL_UTILS_HSE_FREQUENCY(HSEFrequency));
321 
322   /* Check if one of the PLL is enabled */
323   if (UTILS_PLL_IsBusy() == SUCCESS)
324   {
325     /* Calculate the new PLL output frequency */
326     pllfreq = UTILS_GetPLLOutputFrequency(HSEFrequency, UTILS_PLLInitStruct);
327 
328     /* Enable HSE if not enabled */
329     if (LL_RCC_HSE_IsReady() != 1U)
330     {
331       /* Enable HSE */
332       LL_RCC_HSE_Enable();
333       while (LL_RCC_HSE_IsReady() != 1U)
334       {
335         /* Wait for HSE ready */
336       }
337     }
338 
339     /* Configure PLL */
340     LL_RCC_PLL1_ConfigDomain_SYS(LL_RCC_PLL1SOURCE_HSE, UTILS_PLLInitStruct->PLLM, UTILS_PLLInitStruct->PLLN,
341                                  UTILS_PLLInitStruct->PLLR);
342 
343     /* Enable PLL and switch system clock to PLL */
344     status = UTILS_EnablePLLAndSwitchSystem(pllfreq, UTILS_ClkInitStruct);
345   }
346   else
347   {
348     /* Current PLL configuration cannot be modified */
349     status = ERROR;
350   }
351 
352   return status;
353 }
354 
355 /**
356   * @}
357   */
358 
359 /**
360   * @}
361   */
362 
363 /**
364   * @brief  Update number of Flash wait states in line with new frequency and current
365             voltage range.
366   * @param  HCLK_Frequency  HCLK frequency
367   * @retval An ErrorStatus enumeration value:
368   *          - SUCCESS: Latency has been modified
369   *          - ERROR: Latency cannot be modified
370   */
LL_SetFlashLatency(uint32_t HCLK_Frequency)371 ErrorStatus LL_SetFlashLatency(uint32_t HCLK_Frequency)
372 {
373   ErrorStatus status = SUCCESS;
374   uint32_t latency;
375 
376   /* Frequency cannot be equal to 0 */
377   if (HCLK_Frequency == 0U)
378   {
379     status = ERROR;
380   }
381   else
382   {
383     if (LL_PWR_GetRegulVoltageScaling() == LL_PWR_REGU_VOLTAGE_SCALE1)
384     {
385       if ((HCLK_Frequency > UTILS_SCALE1_LATENCY2_FREQ) && (HCLK_Frequency <= UTILS_SCALE1_LATENCY3_FREQ))
386       {
387         /* 96MHz < HCLK <= 100MHz => 3WS (4 CPU cycles) */
388         latency = LL_FLASH_LATENCY_3;
389       }
390       else if ((HCLK_Frequency > UTILS_SCALE1_LATENCY1_FREQ) && (HCLK_Frequency <= UTILS_SCALE1_LATENCY2_FREQ))
391       {
392         /* 64MHz < HCLK <= 96MHz => 2WS (3 CPU cycles) */
393         latency = LL_FLASH_LATENCY_2;
394       }
395       else if ((HCLK_Frequency > UTILS_SCALE1_LATENCY0_FREQ) && (HCLK_Frequency <= UTILS_SCALE1_LATENCY1_FREQ))
396       {
397         /* 32MHz < HCLK <= 64MHz  => 1WS (2 CPU cycles) */
398         latency = LL_FLASH_LATENCY_1;
399       }
400       else if (HCLK_Frequency <= UTILS_SCALE1_LATENCY0_FREQ)
401       {
402         /* HCLK <= 32MHz => 0WS (1 CPU cycle) */
403         latency = LL_FLASH_LATENCY_0;
404       }
405       else
406       {
407         status = ERROR;
408       }
409     }
410     else /* LL_PWR_GetRegulVoltageScaling() == LL_PWR_REGU_VOLTAGE_SCALE2 */
411     {
412       if ((HCLK_Frequency > UTILS_SCALE2_LATENCY0_FREQ) && (HCLK_Frequency <= UTILS_SCALE2_LATENCY1_FREQ))
413       {
414         /* 8MHz < HCLK <= 16MHz => 1WS (2 CPU cycles) */
415         latency = LL_FLASH_LATENCY_1;
416       }
417       else if (HCLK_Frequency <= UTILS_SCALE2_LATENCY0_FREQ)
418       {
419         /* HCLK <= 8MHz => 0WS (1 CPU cycle) */
420         latency = LL_FLASH_LATENCY_0;
421       }
422       else
423       {
424         status = ERROR;
425       }
426     }
427   }
428 
429   if (status == SUCCESS)
430   {
431     LL_FLASH_SetLatency(latency);
432 
433     /* Check that the new number of wait states is taken into account to access the Flash
434     memory by reading the FLASH_ACR register */
435     if (LL_FLASH_GetLatency() != latency)
436     {
437       status = ERROR;
438     }
439   }
440 
441   return status;
442 }
443 
444 /** @addtogroup UTILS_LL_Private_Functions
445   * @{
446   */
447 /**
448   * @brief  Function to check that PLL can be modified
449   * @param  PLL_InputFrequency  PLL input frequency (in Hz)
450   * @param  UTILS_PLLInitStruct pointer to a @ref LL_UTILS_PLLInitTypeDef structure that contains
451   *                             the configuration information for the PLL.
452   * @retval PLL output frequency (in Hz)
453   */
UTILS_GetPLLOutputFrequency(uint32_t PLL_InputFrequency,const LL_UTILS_PLLInitTypeDef * UTILS_PLLInitStruct)454 static uint32_t UTILS_GetPLLOutputFrequency(uint32_t PLL_InputFrequency, const LL_UTILS_PLLInitTypeDef *UTILS_PLLInitStruct)
455 {
456   uint32_t pllfreq;
457 
458   /* Check the parameters */
459   assert_param(IS_LL_UTILS_PLLM_VALUE(UTILS_PLLInitStruct->PLLM));
460   assert_param(IS_LL_UTILS_PLLN_VALUE(UTILS_PLLInitStruct->PLLN));
461   assert_param(IS_LL_UTILS_PLLR_VALUE(UTILS_PLLInitStruct->PLLR));
462 
463   /* Check different PLL parameters according to RM                          */
464   /*  - PLLM: ensure that the VCO input frequency ranges from 4 to 16 MHz.   */
465   pllfreq = PLL_InputFrequency / (UTILS_PLLInitStruct->PLLM);
466   assert_param(IS_LL_UTILS_PLLVCO_INPUT(pllfreq));
467 
468   /*  - PLLN: ensure that the VCO output frequency is between 128 and 544 MHz.*/
469   pllfreq = pllfreq * (UTILS_PLLInitStruct->PLLN);
470   assert_param(IS_LL_UTILS_PLLVCO_OUTPUT(pllfreq));
471 
472   /*  - PLLR: ensure that max frequency at 100 MHz is reached                   */
473   pllfreq = pllfreq / (UTILS_PLLInitStruct->PLLR);
474   assert_param(IS_LL_UTILS_PLL_FREQUENCY(pllfreq));
475 
476   return pllfreq;
477 }
478 
479 /**
480   * @brief  Function to check that PLL can be modified
481   * @retval An ErrorStatus enumeration value:
482   *          - SUCCESS: PLL modification can be done
483   *          - ERROR: PLL is busy
484   */
UTILS_PLL_IsBusy(void)485 static ErrorStatus UTILS_PLL_IsBusy(void)
486 {
487   ErrorStatus status = SUCCESS;
488 
489   /* Check if PLL1 is busy*/
490   if (LL_RCC_PLL1_IsReady() != 0U)
491   {
492     /* PLL configuration cannot be modified */
493     status = ERROR;
494   }
495 
496   return status;
497 }
498 
499 /**
500   * @brief  Function to enable PLL and switch system clock to PLL
501   * @param  SYSCLK_Frequency SYSCLK frequency
502   * @param  UTILS_ClkInitStruct pointer to a @ref LL_UTILS_ClkInitTypeDef structure that contains
503   *                             the configuration information for the BUS prescalers.
504   * @retval An ErrorStatus enumeration value:
505   *          - SUCCESS: No problem to switch system to PLL
506   *          - ERROR: Problem to switch system to PLL
507   */
UTILS_EnablePLLAndSwitchSystem(uint32_t SYSCLK_Frequency,LL_UTILS_ClkInitTypeDef * UTILS_ClkInitStruct)508 static ErrorStatus UTILS_EnablePLLAndSwitchSystem(uint32_t SYSCLK_Frequency,
509                                                   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   assert_param(IS_LL_UTILS_APB7_DIV(UTILS_ClkInitStruct->APB7CLKDivider));
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 PLL1 */
533     LL_RCC_PLL1_Enable();
534     LL_RCC_PLL1_EnableDomain_PLL1R();
535     while (LL_RCC_PLL1_IsReady() != 1U)
536     {
537       /* Wait for PLL ready */
538     }
539 
540     /* Sysclk activation on the main PLL */
541     LL_RCC_SetAHBPrescaler(UTILS_ClkInitStruct->AHBCLKDivider);
542     LL_RCC_SetSysClkSource(LL_RCC_SYS_CLKSOURCE_PLL1R);
543     while (LL_RCC_GetSysClkSource() != LL_RCC_SYS_CLKSOURCE_STATUS_PLL1R)
544     {
545       /* Wait for system clock switch to PLL */
546     }
547 
548     /* Set APB1, APB2 & APB7 prescaler*/
549     LL_RCC_SetAPB1Prescaler(UTILS_ClkInitStruct->APB1CLKDivider);
550     LL_RCC_SetAPB2Prescaler(UTILS_ClkInitStruct->APB2CLKDivider);
551     LL_RCC_SetAPB7Prescaler(UTILS_ClkInitStruct->APB7CLKDivider);
552   }
553 
554   /* Decreasing the number of wait states because of lower CPU frequency */
555   if (SystemCoreClock > hclk_frequency)
556   {
557     /* Set FLASH latency to lowest latency */
558     status = LL_SetFlashLatency(hclk_frequency);
559   }
560 
561   /* Update SystemCoreClock variable */
562   if (status == SUCCESS)
563   {
564     LL_SetSystemCoreClock(hclk_frequency);
565   }
566 
567   return status;
568 }
569 
570 /**
571   * @}
572   */
573 
574 /**
575   * @}
576   */
577 
578 /**
579   * @}
580   */
581 
582