1 /**
2   ******************************************************************************
3   * @file    stm32u5xx_ll_utils.c
4   * @author  MCD Application Team
5   * @brief   UTILS LL module driver.
6   ******************************************************************************
7   * @attention
8   *
9   * Copyright (c) 2021 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 "stm32u5xx_ll_utils.h"
20 #include "stm32u5xx_ll_rcc.h"
21 #include "stm32u5xx_ll_system.h"
22 #include "stm32u5xx_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 STM32U5xx_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_SCALE0  160000000U         /*!< Maximum frequency for system clock at power scale0, in Hz */
45 #define UTILS_MAX_FREQUENCY_SCALE1  100000000U         /*!< Maximum frequency for system clock at power scale1, in Hz */
46 #define UTILS_MAX_FREQUENCY_SCALE2   50000000U         /*!< Maximum frequency for system clock at power scale2, in Hz */
47 #define UTILS_MAX_FREQUENCY_SCALE3   24000000U         /*!< Maximum frequency for system clock at power scale3, in Hz */
48 
49 /* Defines used for PLL range */
50 #define UTILS_PLLVCO_INPUT_MIN        4000000U         /*!< Frequency min for PLLVCO input, in Hz   */
51 #define UTILS_PLLVCO_INPUT_MAX       16000000U         /*!< Frequency max for PLLVCO input, in Hz   */
52 #define UTILS_PLLVCO_OUTPUT_MIN      64000000U         /*!< Frequency min for PLLVCO output, in Hz  */
53 #define UTILS_PLLVCO_OUTPUT_MAX      344000000U        /*!< Frequency max for PLLVCO output, in Hz  */
54 
55 /* Defines used for HSE range */
56 #define UTILS_HSE_FREQUENCY_MIN      4000000U          /*!< Frequency min for HSE frequency, in Hz   */
57 #define UTILS_HSE_FREQUENCY_MAX      50000000U         /*!< Frequency max for HSE frequency, in Hz   */
58 
59 /* Defines used for FLASH latency according to HCLK Frequency */
60 #define UTILS_SCALE1_LATENCY0_FREQ    (32000000U)      /*!< HCLK frequency to set FLASH latency 0 in power scale 1 */
61 #define UTILS_SCALE1_LATENCY1_FREQ    (64000000U)      /*!< HCLK frequency to set FLASH latency 1 in power scale 1 */
62 #define UTILS_SCALE1_LATENCY2_FREQ    (96000000U)      /*!< HCLK frequency to set FLASH latency 2 in power scale 1 */
63 #define UTILS_SCALE1_LATENCY3_FREQ    (128000000U)     /*!< HCLK frequency to set FLASH latency 3 in power scale 1 */
64 #define UTILS_SCALE1_LATENCY4_FREQ    (160000000U)     /*!< HCLK frequency to set FLASH latency 4 in power scale 1 */
65 #define UTILS_SCALE2_LATENCY0_FREQ    (25000000U)      /*!< HCLK frequency to set FLASH latency 0 in power scale 2 */
66 #define UTILS_SCALE2_LATENCY1_FREQ    (50000000U)      /*!< HCLK frequency to set FLASH latency 1 in power scale 2 */
67 #define UTILS_SCALE2_LATENCY2_FREQ    (75000000U)      /*!< HCLK frequency to set FLASH latency 2 in power scale 2 */
68 #define UTILS_SCALE2_LATENCY3_FREQ    (100000000U)     /*!< HCLK frequency to set FLASH latency 3 in power scale 2 */
69 #define UTILS_SCALE3_LATENCY0_FREQ    (12500000U)       /*!< HCLK frequency to set FLASH latency 0 in power scale 3 */
70 #define UTILS_SCALE3_LATENCY1_FREQ    (25000000U)      /*!< HCLK frequency to set FLASH latency 1 in power scale 3 */
71 #define UTILS_SCALE3_LATENCY2_FREQ    (37500000U)       /*!< HCLK frequency to set FLASH latency 2 in power scale 3 */
72 #define UTILS_SCALE3_LATENCY3_FREQ    (50000000U)      /*!< HCLK frequency to set FLASH latency 3 in power scale 3 */
73 #define UTILS_SCALE4_LATENCY0_FREQ    (8000000U)       /*!< HCLK frequency to set FLASH latency 0 in power scale 4 */
74 #define UTILS_SCALE4_LATENCY1_FREQ    (16000000U)      /*!< HCLK frequency to set FLASH latency 1 in power scale 4 */
75 #define UTILS_SCALE4_LATENCY2_FREQ    (24000000U)      /*!< HCLK frequency to set FLASH latency 2 in power scale 4 */
76 /**
77   * @}
78   */
79 
80 /* Private macros ------------------------------------------------------------*/
81 /** @addtogroup UTILS_LL_Private_Macros
82   * @{
83   */
84 #define IS_LL_UTILS_SYSCLK_DIV(__VALUE__) (((__VALUE__) == LL_RCC_SYSCLK_DIV_1)   \
85                                            || ((__VALUE__) == LL_RCC_SYSCLK_DIV_2)   \
86                                            || ((__VALUE__) == LL_RCC_SYSCLK_DIV_4)   \
87                                            || ((__VALUE__) == LL_RCC_SYSCLK_DIV_8)   \
88                                            || ((__VALUE__) == LL_RCC_SYSCLK_DIV_16)  \
89                                            || ((__VALUE__) == LL_RCC_SYSCLK_DIV_64)  \
90                                            || ((__VALUE__) == LL_RCC_SYSCLK_DIV_128) \
91                                            || ((__VALUE__) == LL_RCC_SYSCLK_DIV_256) \
92                                            || ((__VALUE__) == LL_RCC_SYSCLK_DIV_512))
93 
94 #define IS_LL_UTILS_APB1_DIV(__VALUE__) (((__VALUE__) == LL_RCC_APB1_DIV_1) \
95                                          || ((__VALUE__) == LL_RCC_APB1_DIV_2) \
96                                          || ((__VALUE__) == LL_RCC_APB1_DIV_4) \
97                                          || ((__VALUE__) == LL_RCC_APB1_DIV_8) \
98                                          || ((__VALUE__) == LL_RCC_APB1_DIV_16))
99 
100 #define IS_LL_UTILS_APB2_DIV(__VALUE__) (((__VALUE__) == LL_RCC_APB2_DIV_1) \
101                                          || ((__VALUE__) == LL_RCC_APB2_DIV_2) \
102                                          || ((__VALUE__) == LL_RCC_APB2_DIV_4) \
103                                          || ((__VALUE__) == LL_RCC_APB2_DIV_8) \
104                                          || ((__VALUE__) == LL_RCC_APB2_DIV_16))
105 
106 #define IS_LL_UTILS_APB3_DIV(__VALUE__) (((__VALUE__) == LL_RCC_APB3_DIV_1) \
107                                          || ((__VALUE__) == LL_RCC_APB3_DIV_2) \
108                                          || ((__VALUE__) == LL_RCC_APB3_DIV_4) \
109                                          || ((__VALUE__) == LL_RCC_APB3_DIV_8) \
110                                          || ((__VALUE__) == LL_RCC_APB3_DIV_16))
111 
112 #define IS_LL_UTILS_PLLM_VALUE(__VALUE__) ((1U <= (__VALUE__)) && ((__VALUE__) <= 16U))
113 
114 #define IS_LL_UTILS_PLLN_VALUE(__VALUE__) ((4U <= (__VALUE__)) && ((__VALUE__) <= 512U))
115 
116 #define IS_LL_UTILS_PLLR_VALUE(__VALUE__) ((1U <= (__VALUE__)) && ((__VALUE__) <= 128U))
117 
118 #define IS_LL_UTILS_PLLVCO_INPUT(__VALUE__)  ((UTILS_PLLVCO_INPUT_MIN <= (__VALUE__))\
119                                               && ((__VALUE__) <= UTILS_PLLVCO_INPUT_MAX))
120 
121 #define IS_LL_UTILS_PLLVCO_OUTPUT(__VALUE__) ((UTILS_PLLVCO_OUTPUT_MIN <= (__VALUE__))\
122                                               && ((__VALUE__) <= UTILS_PLLVCO_OUTPUT_MAX))
123 
124 #define IS_LL_UTILS_PLL_FREQUENCY(__VALUE__) ((LL_PWR_GetRegulVoltageScaling() == LL_PWR_REGU_VOLTAGE_SCALE4) ? \
125                                               ((__VALUE__) <= UTILS_MAX_FREQUENCY_SCALE0) : \
126                                               (LL_PWR_GetRegulVoltageScaling() == LL_PWR_REGU_VOLTAGE_SCALE1) ? \
127                                               ((__VALUE__) <= UTILS_MAX_FREQUENCY_SCALE1) : \
128                                               (LL_PWR_GetRegulVoltageScaling() == LL_PWR_REGU_VOLTAGE_SCALE2) ? \
129                                               ((__VALUE__) <= UTILS_MAX_FREQUENCY_SCALE2) : \
130                                               ((__VALUE__) <= UTILS_MAX_FREQUENCY_SCALE3))
131 
132 #define IS_LL_UTILS_HSE_BYPASS(__STATE__) (((__STATE__) == LL_UTILS_HSEBYPASS_ON) \
133                                            || ((__STATE__) == LL_UTILS_HSEBYPASS_OFF))
134 
135 #define IS_LL_UTILS_HSE_FREQUENCY(__FREQUENCY__) (((__FREQUENCY__) >= UTILS_HSE_FREQUENCY_MIN)\
136                                                   && ((__FREQUENCY__) <= UTILS_HSE_FREQUENCY_MAX))
137 /**
138   * @}
139   */
140 /* Private function prototypes -----------------------------------------------*/
141 /** @defgroup UTILS_LL_Private_Functions UTILS Private functions
142   * @{
143   */
144 static uint32_t    UTILS_GetPLLOutputFrequency(uint32_t PLL_InputFrequency,
145                                                LL_UTILS_PLLInitTypeDef *UTILS_PLLInitStruct);
146 static ErrorStatus UTILS_EnablePLLAndSwitchSystem(uint32_t SYSCLK_Frequency,
147                                                   LL_UTILS_ClkInitTypeDef *UTILS_ClkInitStruct);
148 static ErrorStatus UTILS_PLL_IsBusy(void);
149 /**
150   * @}
151   */
152 
153 /* Exported functions --------------------------------------------------------*/
154 /** @addtogroup UTILS_LL_Exported_Functions
155   * @{
156   */
157 
158 /** @addtogroup UTILS_LL_EF_DELAY
159   * @{
160   */
161 
162 /**
163   * @brief  This function configures the Cortex-M SysTick source to have 1ms time base.
164   * @note   When a RTOS is used, it is recommended to avoid changing the Systick
165   *         configuration by calling this function, for a delay use rather osDelay RTOS service.
166   * @param  HCLKFrequency HCLK frequency in Hz
167   * @note   HCLK frequency can be calculated thanks to RCC helper macro or function @ref LL_RCC_GetSystemClocksFreq
168   * @retval None
169   */
LL_Init1msTick(uint32_t HCLKFrequency)170 void LL_Init1msTick(uint32_t HCLKFrequency)
171 {
172   /* Use frequency provided in argument */
173   LL_InitTick(HCLKFrequency, 1000U);
174 }
175 
176 /**
177   * @brief  This function provides accurate delay (in milliseconds) based
178   *         on SysTick counter flag
179   * @note   When a RTOS is used, it is recommended to avoid using blocking delay
180   *         and use rather osDelay service.
181   * @note   To respect 1ms timebase, user should call @ref LL_Init1msTick function which
182   *         will configure Systick to 1ms
183   * @param  Delay specifies the delay time length, in milliseconds.
184   * @retval None
185   */
186 
LL_mDelay(uint32_t Delay)187 void LL_mDelay(uint32_t Delay)
188 {
189   __IO uint32_t  tmp = SysTick->CTRL;  /* Clear the COUNTFLAG first */
190   uint32_t tmpDelay = Delay;
191 
192   /* Add this code to indicate that local variable is not used */
193   ((void)tmp);
194 
195   /* Add a period to guaranty minimum wait */
196   if (tmpDelay < LL_MAX_DELAY)
197   {
198     tmpDelay++;
199   }
200 
201   while (tmpDelay != 0U)
202   {
203     if ((SysTick->CTRL & SysTick_CTRL_COUNTFLAG_Msk) != 0U)
204     {
205       tmpDelay--;
206     }
207   }
208 }
209 
210 /**
211   * @}
212   */
213 
214 /** @addtogroup UTILS_EF_SYSTEM
215   *  @brief    System Configuration functions
216   *
217   @verbatim
218  ===============================================================================
219            ##### System Configuration functions #####
220  ===============================================================================
221     [..]
222          System, AHB and APB buses clocks configuration
223 
224          (+) The maximum frequency of the SYSCLK, HCLK, PCLK1 and PCLK2, PCLK3 is
225              160000000 Hz.
226   @endverbatim
227   @internal
228              Depending on the device voltage range, the maximum frequency should be
229              adapted accordingly:
230 
231              (++) Table 1. HCLK clock frequency for STM32U5 devices
232              (++) +-----------------------------------------------------------------------------------------------+
233              (++) | Latency         |                          HCLK clock frequency (MHz)                         |
234              (++) |                 |-----------------------------------------------------------------------------|
235              (++) |                 |  voltage range 1  |  voltage range 2 | voltage range 3  | voltage range 4   |
236              (++) |                 |       1.2 V       |       1.1 V      |     1.0 V        |      0.9 V        |
237              (++) |-----------------|-------------------|------------------|------------------|-------------------|
238              (++) |0WS(1 CPU cycles)|   0 < HCLK <= 32  |  0 < HCLK <= 25  |  0 < HCLK <= 12.5| 0 < HCLK <= 8     |
239              (++) |-----------------|-------------------|------------------|------------------|-------------------|
240              (++) |1WS(2 CPU cycles)|  32 < HCLK <= 64  |  25 < HCLK <= 50 | 12.5 < HCLK <= 25| 0 < HCLK <= 16    |
241              (++) |-----------------|-------------------|------------------|------------------|-------------------|
242              (++) |2WS(3 CPU cycles)|  64 < HCLK <= 96  |  50 < HCLK <= 75 | 25 < HCLK <= 37.5| 0 < HCLK <= 24    |
243              (++) |-----------------|-------------------|------------------|------------------|-------------------|
244              (++) |3WS(4 CPU cycles)|  96 < HCLK <= 128 |  75 < HCLK <= 100| 37.5 < HCLK <= 50|                   |
245              (++) |-----------------|-------------------|------------------|------------------|                   |
246              (++) |4WS(5 CPU cycles)|  128 < HCLK <= 160|                  |                  |                   |
247              (++) +-----------------+-------------------+------------------+------------------+-------------------+
248 
249   @endinternal
250   * @{
251   */
252 
253 /**
254   * @brief  This function sets directly SystemCoreClock CMSIS variable.
255   * @note   Variable can be calculated also through SystemCoreClockUpdate function.
256   * @param  HCLKFrequency HCLK frequency in Hz (can be calculated thanks to RCC helper macro)
257   * @retval None
258   */
LL_SetSystemCoreClock(uint32_t HCLKFrequency)259 void LL_SetSystemCoreClock(uint32_t HCLKFrequency)
260 {
261   /* HCLK clock frequency */
262   SystemCoreClock = HCLKFrequency;
263 }
264 
265 /**
266   * @brief  Update number of Flash wait states in line with new frequency and current
267             voltage range.
268   * @param  HCLK_Frequency  HCLK frequency
269   * @retval An ErrorStatus enumeration value:
270   *          - SUCCESS: Latency has been modified
271   *          - ERROR: Latency cannot be modified
272   */
LL_SetFlashLatency(uint32_t HCLK_Frequency)273 ErrorStatus LL_SetFlashLatency(uint32_t HCLK_Frequency)
274 {
275   ErrorStatus status = SUCCESS;
276   uint32_t timeout;
277   uint32_t getlatency;
278   uint32_t latency = LL_FLASH_LATENCY_0;  /* default value 0WS */
279 
280   /* Frequency cannot be equal to 0 */
281   if (HCLK_Frequency == 0U)
282   {
283     status = ERROR;
284   }
285   else
286   {
287     if (LL_PWR_GetRegulVoltageScaling() == LL_PWR_REGU_VOLTAGE_SCALE1)
288     {
289       if (HCLK_Frequency <= UTILS_SCALE1_LATENCY0_FREQ)
290       {
291         /* 0 < HCLK <= 32 => 0WS (1 CPU cycles) : Do nothing, keep latency to default  LL_FLASH_LATENCY_0 */
292       }
293       else if ((HCLK_Frequency <= UTILS_SCALE1_LATENCY1_FREQ))
294       {
295         /* 32 < HCLK <=64  => 1WS (2 CPU cycles) */
296         latency = LL_FLASH_LATENCY_1;
297       }
298       else if (HCLK_Frequency <= UTILS_SCALE1_LATENCY2_FREQ)
299       {
300         /* 64 < HCLK <= 96 => 2WS (3 CPU cycles) */
301         latency = LL_FLASH_LATENCY_2;
302       }
303       else if (HCLK_Frequency <= UTILS_SCALE1_LATENCY3_FREQ)
304       {
305         /* 96 < HCLK <= 128 => 3WS (4 CPU cycles) */
306         latency = LL_FLASH_LATENCY_3;
307       }
308       else if (HCLK_Frequency <= UTILS_SCALE1_LATENCY4_FREQ)
309       {
310         /* 128 < HCLK <= 160 => 4WS (5 CPU cycles) */
311         latency = LL_FLASH_LATENCY_4;
312       }
313       else
314       {
315         status = ERROR;
316       }
317       /* else HCLK_Frequency <= 10MHz default LL_FLASH_LATENCY_0 0WS */
318     }
319     else if (LL_PWR_GetRegulVoltageScaling() == LL_PWR_REGU_VOLTAGE_SCALE2)
320     {
321       if (HCLK_Frequency <= UTILS_SCALE2_LATENCY0_FREQ)
322       {
323         /* 0 < HCLK <= 25 => 0WS (1 CPU cycles) : Do nothing, keep latency to default  LL_FLASH_LATENCY_0 */
324       }
325       else if (HCLK_Frequency <= UTILS_SCALE2_LATENCY1_FREQ)
326       {
327         /* 25 < HCLK <= 50 => 1WS (2 CPU cycles) */
328         latency = LL_FLASH_LATENCY_1;
329       }
330       else if (HCLK_Frequency <= UTILS_SCALE2_LATENCY2_FREQ)
331       {
332         /* 50 < HCLK <= 75 => 2WS (3 CPU cycles) */
333         latency = LL_FLASH_LATENCY_2;
334       }
335       else if (HCLK_Frequency <= UTILS_SCALE2_LATENCY3_FREQ)
336       {
337         /* 75 < HCLK <= 100 => 3WS (4 CPU cycles) */
338         latency = LL_FLASH_LATENCY_3;
339       }
340       else
341       {
342         status = ERROR;
343       }
344       /* else HCLK_Frequency <= 10MHz default LL_FLASH_LATENCY_0 0WS */
345     }
346     else if (LL_PWR_GetRegulVoltageScaling() == LL_PWR_REGU_VOLTAGE_SCALE3)
347     {
348       if (HCLK_Frequency  <= UTILS_SCALE3_LATENCY0_FREQ)
349       {
350         /* 0 < HCLK <= 12.5 => 0WS (1 CPU cycles) : Do nothing, keep latency to default  LL_FLASH_LATENCY_0 */
351       }
352       else if (HCLK_Frequency <= UTILS_SCALE3_LATENCY1_FREQ)
353       {
354         /* 12.5 < HCLK <= 25 => 1WS (2 CPU cycles) */
355         latency = LL_FLASH_LATENCY_1;
356       }
357       else if (HCLK_Frequency <= UTILS_SCALE3_LATENCY2_FREQ)
358       {
359         /* 25 < HCLK <= 37.5 => 2WS (3 CPU cycles) */
360         latency = LL_FLASH_LATENCY_2;
361       }
362       else if (HCLK_Frequency <= UTILS_SCALE3_LATENCY3_FREQ)
363       {
364         /* 37.5 < HCLK <= 50 => 3WS (4 CPU cycles) */
365         latency = LL_FLASH_LATENCY_3;
366       }
367       else
368       {
369         status = ERROR;
370       }
371       /* else HCLK_Frequency <= 10MHz default LL_FLASH_LATENCY_0 0WS */
372     }
373     else
374     {
375       if (HCLK_Frequency <= UTILS_SCALE4_LATENCY0_FREQ)
376       {
377         /* 0 < HCLK <= 8 => 0WS (1 CPU cycles) : Do nothing, keep latency to default  LL_FLASH_LATENCY_0 */
378       }
379       else if (HCLK_Frequency <= UTILS_SCALE4_LATENCY1_FREQ)
380       {
381         /* 8 < HCLK <= 16 => 1WS (2 CPU cycles) */
382         latency = LL_FLASH_LATENCY_1;
383       }
384       else if (HCLK_Frequency <= UTILS_SCALE4_LATENCY2_FREQ)
385       {
386         /* 16 < HCLK <= 24 => 2WS (3 CPU cycles) */
387         latency = LL_FLASH_LATENCY_2;
388       }
389       else
390       {
391         status = ERROR;
392       }
393       /* else HCLK_Frequency <= 10MHz default LL_FLASH_LATENCY_0 0WS */
394     }
395   }
396 
397   if (status == SUCCESS)
398   {
399     LL_FLASH_SetLatency(latency);
400 
401     /* Check that the new number of wait states is taken into account to access the Flash
402     memory by reading the FLASH_ACR register */
403     timeout = 2;
404     do
405     {
406       /* Wait for Flash latency to be updated */
407       getlatency = LL_FLASH_GetLatency();
408       timeout--;
409     } while ((getlatency != latency) && (timeout > 0U));
410 
411     if (getlatency != latency)
412     {
413       status = ERROR;
414     }
415   }
416 
417   return status;
418 }
419 
420 /**
421   * @brief  This function configures system clock with MSI as clock source of the PLL
422   * @note   The application needs to ensure that PLL1, PLL2 and/or PLL3 are disabled.
423   * @note   Function is based on the following formula:
424   *         - PLL1 output frequency = (((MSI frequency / PLL1M) * PLL1N) / PLL1R)
425   *         - PLL1M: ensure that the VCO input frequency ranges from 1 to 16 MHz (PLL1VCO_input = MSI frequency / PLL1M)
426   *         - PLL1N: ensure that the VCO output frequency is between 4 and 512 MHz
427              (PLL1VCO_output = PLL1VCO_input * PLL1N)
428   *         - PLL1R: ensure that max frequency at 160 MHz is reached (PLL1VCO_output / PLL1R)
429   * @param  UTILS_PLLInitStruct pointer to a @ref LL_UTILS_PLLInitTypeDef structure that contains
430   *                             the configuration information for the PLL1.
431   * @param  UTILS_ClkInitStruct pointer to a @ref LL_UTILS_ClkInitTypeDef structure that contains
432   *                             the configuration information for the BUS prescalers.
433   * @retval An ErrorStatus enumeration value:
434   *          - SUCCESS: Max frequency configuration done
435   *          - ERROR: Max frequency configuration not done
436   */
LL_PLL_ConfigSystemClock_MSI(LL_UTILS_PLLInitTypeDef * UTILS_PLLInitStruct,LL_UTILS_ClkInitTypeDef * UTILS_ClkInitStruct)437 ErrorStatus LL_PLL_ConfigSystemClock_MSI(LL_UTILS_PLLInitTypeDef *UTILS_PLLInitStruct,
438                                          LL_UTILS_ClkInitTypeDef *UTILS_ClkInitStruct)
439 {
440   ErrorStatus status = SUCCESS;
441   uint32_t pllfreq;
442   uint32_t msi_range;
443    uint32_t hpre = LL_RCC_SYSCLK_DIV_1;
444 
445   /* Check if one of the PLL is enabled */
446   if (UTILS_PLL_IsBusy() == SUCCESS)
447   {
448     /* Get the current MSI range */
449     if (LL_RCC_MSI_IsEnabledRangeSelect() != 0U)
450     {
451       msi_range =  LL_RCC_MSIS_GetRange();
452       switch (msi_range)
453       {
454         case LL_RCC_MSISRANGE_15:    /* MSI = 100 kHz  */
455         case LL_RCC_MSISRANGE_14:    /* MSI = 150 kHz  */
456         case LL_RCC_MSISRANGE_13:    /* MSI = 200 kHz  */
457         case LL_RCC_MSISRANGE_12:    /* MSI = 400 kHz  */
458         case LL_RCC_MSISRANGE_11:    /* MSI = 768 kHz  */
459         case LL_RCC_MSISRANGE_10:    /* MSI = 1.024 MHz*/
460         case LL_RCC_MSISRANGE_9:     /* MSI = 1.536 MHz*/
461         case LL_RCC_MSISRANGE_8:     /* MSI = 3.072 MHz*/
462         case LL_RCC_MSISRANGE_7:     /* MSI = 1 MHz    */
463         case LL_RCC_MSISRANGE_6:     /* MSI = 1.5 MHz  */
464         case LL_RCC_MSISRANGE_5:     /* MSI = 2 MHz    */
465           /* PLLVCO input frequency is less then 4 MHz*/
466           status = ERROR;
467           break;
468 
469         case LL_RCC_MSISRANGE_0:     /* MSI = 48 MHz   */
470         case LL_RCC_MSISRANGE_1:     /* MSI = 24 MHz   */
471         case LL_RCC_MSISRANGE_2:     /* MSI = 16 MHz   */
472         case LL_RCC_MSISRANGE_3:     /* MSI = 12 MHz   */
473         case LL_RCC_MSISRANGE_4:     /* MSI = 4 MHz    */
474         default:
475           break;
476       }
477     }
478     else
479     {
480       msi_range = LL_RCC_MSIS_GetRangeAfterStandby();
481       switch (msi_range)
482       {
483         case LL_RCC_MSISSRANGE_5:    /* MSI = 2 MHz    */
484         case LL_RCC_MSISSRANGE_6:    /* MSI = 1.5 MHz  */
485         case LL_RCC_MSISSRANGE_7:    /* MSI = 1 MHz    */
486         case LL_RCC_MSISSRANGE_8:    /* MSI = 3.072 MHz*/
487           /* PLLVCO input frequency is less then 4 MHz */
488           status = ERROR;
489           break;
490 
491         case LL_RCC_MSISSRANGE_4:    /* MSI = 4 MHz    */
492         default:
493           break;
494       }
495     }
496 
497     /* Main PLL configuration and activation */
498     if (status != ERROR)
499     {
500       /* Calculate the new PLL output frequency */
501       pllfreq = UTILS_GetPLLOutputFrequency(__LL_RCC_CALC_MSIS_FREQ(LL_RCC_MSI_IsEnabledRangeSelect(), msi_range),
502                                             UTILS_PLLInitStruct);
503 
504       /* Enable MSI if not enabled */
505       if (LL_RCC_MSIS_IsReady() != 1U)
506       {
507         LL_RCC_MSIS_Enable();
508         while ((LL_RCC_MSIS_IsReady() != 1U))
509         {
510           /* Wait for MSI ready */
511         }
512       }
513 
514       /* Configure PLL1 */
515       LL_RCC_PLL1_ConfigDomain_SYS(LL_RCC_PLL1SOURCE_MSIS, UTILS_PLLInitStruct->PLLM, UTILS_PLLInitStruct->PLLN,
516                                    UTILS_PLLInitStruct->PLLR);
517 
518       /* Prevent undershoot at highest frequency by applying intermediate AHB prescaler 2 */
519       if (pllfreq > 80000000U)
520       {
521         if (UTILS_ClkInitStruct->AHBCLKDivider == LL_RCC_SYSCLK_DIV_1)
522         {
523           UTILS_ClkInitStruct->AHBCLKDivider = LL_RCC_SYSCLK_DIV_2;
524           hpre = LL_RCC_SYSCLK_DIV_2;
525         }
526       }
527       /* Enable PLL and switch system clock to PLL */
528       status = UTILS_EnablePLLAndSwitchSystem(pllfreq, UTILS_ClkInitStruct);
529 
530       /* Apply definitive AHB prescaler value if necessary */
531       if ((status == SUCCESS) && (hpre != LL_RCC_SYSCLK_DIV_1))
532       {
533         /* Set FLASH latency to highest latency */
534         status = LL_SetFlashLatency(pllfreq);
535         if (status == SUCCESS)
536         {
537           UTILS_ClkInitStruct->AHBCLKDivider = LL_RCC_SYSCLK_DIV_1;
538           LL_RCC_SetAHBPrescaler(UTILS_ClkInitStruct->AHBCLKDivider);
539           LL_SetSystemCoreClock(pllfreq);
540         }
541       }
542     }
543   }
544   else
545   {
546     /* Current PLL configuration cannot be modified */
547     status = ERROR;
548   }
549 
550   return status;
551 }
552 
553 /**
554   * @brief  This function configures system clock at maximum frequency with HSI as clock source of the PLL
555   * @note   The application need to ensure that PLL1, PLL2 and/or PLL3 are disabled.
556   * @note   Function is based on the following formula:
557   *         - PLL output frequency = (((HSI frequency / PLLM) * PLLN) / PLLR)
558   *         - PLL1M: ensure that the VCO input frequency ranges from 1 to 16 MHz (PLL1VCO_input = MSI frequency / PLL1M)
559   *         - PLL1N: ensure that the VCO output frequency is between 4 and 512 MHz
560              (PLL1VCO_output = PLL1VCO_input * PLL1N)
561   *         - PLL1R: ensure that max frequency at 160 MHz is reached (PLL1VCO_output / PLL1R)
562   * @param  UTILS_PLLInitStruct pointer to a @ref LL_UTILS_PLLInitTypeDef structure that contains
563   *                             the configuration information for the PLL.
564   * @param  UTILS_ClkInitStruct pointer to a @ref LL_UTILS_ClkInitTypeDef structure that contains
565   *                             the configuration information for the BUS prescalers.
566   * @retval An ErrorStatus enumeration value:
567   *          - SUCCESS: Max frequency configuration done
568   *          - ERROR: Max frequency configuration not done
569   */
LL_PLL_ConfigSystemClock_HSI(LL_UTILS_PLLInitTypeDef * UTILS_PLLInitStruct,LL_UTILS_ClkInitTypeDef * UTILS_ClkInitStruct)570 ErrorStatus LL_PLL_ConfigSystemClock_HSI(LL_UTILS_PLLInitTypeDef *UTILS_PLLInitStruct,
571                                          LL_UTILS_ClkInitTypeDef *UTILS_ClkInitStruct)
572 {
573   ErrorStatus status;
574   uint32_t pllfreq;
575 
576   /* Check if one of the PLL is enabled */
577   if (UTILS_PLL_IsBusy() == SUCCESS)
578   {
579     /* Calculate the new PLL output frequency */
580     pllfreq = UTILS_GetPLLOutputFrequency(HSI_VALUE, UTILS_PLLInitStruct);
581 
582     /* Enable HSI if not enabled */
583     if (LL_RCC_HSI_IsReady() != 1U)
584     {
585       LL_RCC_HSI_Enable();
586       while (LL_RCC_HSI_IsReady() != 1U)
587       {
588         /* Wait for HSI ready */
589       }
590     }
591 
592     /* Configure PLL */
593     LL_RCC_PLL1_ConfigDomain_SYS(LL_RCC_PLL1SOURCE_HSI, UTILS_PLLInitStruct->PLLM, UTILS_PLLInitStruct->PLLN,
594                                  UTILS_PLLInitStruct->PLLR);
595 
596     /* Enable PLL and switch system clock to PLL */
597     status = UTILS_EnablePLLAndSwitchSystem(pllfreq, UTILS_ClkInitStruct);
598   }
599   else
600   {
601     /* Current PLL configuration cannot be modified */
602     status = ERROR;
603   }
604 
605   return status;
606 }
607 
608 /**
609   * @brief  This function configures system clock with HSE as clock source of the PLL
610   * @note   The application need to ensure that PLL, PLLSAI1 and/or PLLSAI2 are disabled.
611   * @note   Function is based on the following formula:
612   *         - PLL output frequency = (((HSE frequency / PLLM) * PLLN) / PLLR)
613   *         - PLL1M: ensure that the VCO input frequency ranges from 1 to 16 MHz (PLL1VCO_input = MSI frequency / PLL1M)
614   *         - PLL1N: ensure that the VCO output frequency is between 4 and 512 MHz
615              (PLL1VCO_output = PLL1VCO_input * PLL1N)
616   *         - PLL1R: ensure that max frequency at 160 MHz is reached (PLL1VCO_output / PLL1R)
617   * @param  HSEFrequency Value between Min_Data = 4000000 and Max_Data = 50000000
618   * @param  HSEBypass This parameter can be one of the following values:
619   *         @arg @ref LL_UTILS_HSEBYPASS_ON
620   *         @arg @ref LL_UTILS_HSEBYPASS_OFF
621   * @param  UTILS_PLLInitStruct pointer to a @ref LL_UTILS_PLLInitTypeDef structure that contains
622   *                             the configuration information for the PLL.
623   * @param  UTILS_ClkInitStruct pointer to a @ref LL_UTILS_ClkInitTypeDef structure that contains
624   *                             the configuration information for the BUS prescalers.
625   * @retval An ErrorStatus enumeration value:
626   *          - SUCCESS: Max frequency configuration done
627   *          - ERROR: Max frequency configuration not done
628   */
LL_PLL_ConfigSystemClock_HSE(uint32_t HSEFrequency,uint32_t HSEBypass,LL_UTILS_PLLInitTypeDef * UTILS_PLLInitStruct,LL_UTILS_ClkInitTypeDef * UTILS_ClkInitStruct)629 ErrorStatus LL_PLL_ConfigSystemClock_HSE(uint32_t HSEFrequency, uint32_t HSEBypass,
630                                          LL_UTILS_PLLInitTypeDef *UTILS_PLLInitStruct,
631                                          LL_UTILS_ClkInitTypeDef *UTILS_ClkInitStruct)
632 {
633   ErrorStatus status;
634   uint32_t pllfreq;
635 
636   /* Check the parameters */
637   assert_param(IS_LL_UTILS_HSE_FREQUENCY(HSEFrequency));
638   assert_param(IS_LL_UTILS_HSE_BYPASS(HSEBypass));
639 
640   /* Check if one of the PLL is enabled */
641   if (UTILS_PLL_IsBusy() == SUCCESS)
642   {
643     /* Calculate the new PLL output frequency */
644     pllfreq = UTILS_GetPLLOutputFrequency(HSEFrequency, UTILS_PLLInitStruct);
645 
646     /* Enable HSE if not enabled */
647     if (LL_RCC_HSE_IsReady() != 1U)
648     {
649       /* Check if need to enable HSE bypass feature or not */
650       if (HSEBypass == LL_UTILS_HSEBYPASS_ON)
651       {
652         LL_RCC_HSE_EnableBypass();
653       }
654       else
655       {
656         LL_RCC_HSE_DisableBypass();
657       }
658 
659       /* Enable HSE */
660       LL_RCC_HSE_Enable();
661       while (LL_RCC_HSE_IsReady() != 1U)
662       {
663         /* Wait for HSE ready */
664       }
665     }
666 
667     /* Configure PLL */
668     LL_RCC_PLL1_ConfigDomain_SYS(LL_RCC_PLL1SOURCE_HSE, UTILS_PLLInitStruct->PLLM, UTILS_PLLInitStruct->PLLN,
669                                  UTILS_PLLInitStruct->PLLR);
670 
671     /* Enable PLL and switch system clock to PLL */
672     status = UTILS_EnablePLLAndSwitchSystem(pllfreq, UTILS_ClkInitStruct);
673   }
674   else
675   {
676     /* Current PLL configuration cannot be modified */
677     status = ERROR;
678   }
679 
680   return status;
681 }
682 
683 /**
684   * @}
685   */
686 
687 /**
688   * @}
689   */
690 
691 /** @addtogroup UTILS_LL_Private_Functions
692   * @{
693   */
694 
695 /**
696   * @brief  Function to check that PLL can be modified
697   * @param  PLL_InputFrequency  PLL input frequency (in Hz)
698   * @param  UTILS_PLLInitStruct pointer to a @ref LL_UTILS_PLLInitTypeDef structure that contains
699   *                             the configuration information for the PLL.
700   * @retval PLL output frequency (in Hz)
701   */
UTILS_GetPLLOutputFrequency(uint32_t PLL_InputFrequency,LL_UTILS_PLLInitTypeDef * UTILS_PLLInitStruct)702 static uint32_t UTILS_GetPLLOutputFrequency(uint32_t PLL_InputFrequency, LL_UTILS_PLLInitTypeDef *UTILS_PLLInitStruct)
703 {
704   uint32_t pllfreq;
705 
706   /* Check the parameters */
707   assert_param(IS_LL_UTILS_PLLM_VALUE(UTILS_PLLInitStruct->PLLM));
708   assert_param(IS_LL_UTILS_PLLN_VALUE(UTILS_PLLInitStruct->PLLN));
709   assert_param(IS_LL_UTILS_PLLR_VALUE(UTILS_PLLInitStruct->PLLR));
710 
711   /* Check different PLL parameters according to RM                          */
712   /*  - PLLM: ensure that the VCO input frequency ranges from 1 to 16 MHz.   */
713   pllfreq = PLL_InputFrequency / (UTILS_PLLInitStruct->PLLM);
714   assert_param(IS_LL_UTILS_PLLVCO_INPUT(pllfreq));
715 
716   /*  - PLLN: ensure that the VCO output frequency is between 4 and 512 MHz.*/
717   pllfreq = pllfreq * (UTILS_PLLInitStruct->PLLN);
718   assert_param(IS_LL_UTILS_PLLVCO_OUTPUT(pllfreq));
719 
720   /*  - PLLR: ensure that max frequency at 160 MHz is reached                   */
721   pllfreq = pllfreq / (UTILS_PLLInitStruct->PLLR);
722   assert_param(IS_LL_UTILS_PLL_FREQUENCY(pllfreq));
723 
724   return pllfreq;
725 }
726 
727 /**
728   * @brief  Function to check that PLL can be modified
729   * @retval An ErrorStatus enumeration value:
730   *          - SUCCESS: PLL modification can be done
731   *          - ERROR: PLL is busy
732   */
UTILS_PLL_IsBusy(void)733 static ErrorStatus UTILS_PLL_IsBusy(void)
734 {
735   ErrorStatus status = SUCCESS;
736 
737   /* Check if PLL1 is busy*/
738   if (LL_RCC_PLL1_IsReady() != 0U)
739   {
740     /* PLL configuration cannot be modified */
741     status = ERROR;
742   }
743 
744   /* Check if PLL2 is busy*/
745   if (LL_RCC_PLL2_IsReady() != 0U)
746   {
747     /* PLL2 configuration cannot be modified */
748     status = ERROR;
749   }
750 
751   /* Check if PLL3 is busy*/
752   if (LL_RCC_PLL3_IsReady() != 0U)
753   {
754     /* PLL3 configuration cannot be modified */
755     status = ERROR;
756   }
757 
758   return status;
759 }
760 
761 /**
762   * @brief  Function to enable PLL and switch system clock to PLL
763   * @param  SYSCLK_Frequency SYSCLK frequency
764   * @param  UTILS_ClkInitStruct pointer to a @ref LL_UTILS_ClkInitTypeDef structure that contains
765   *                             the configuration information for the BUS prescalers.
766   * @retval An ErrorStatus enumeration value:
767   *          - SUCCESS: No problem to switch system to PLL
768   *          - ERROR: Problem to switch system to PLL
769   */
UTILS_EnablePLLAndSwitchSystem(uint32_t SYSCLK_Frequency,LL_UTILS_ClkInitTypeDef * UTILS_ClkInitStruct)770 static ErrorStatus UTILS_EnablePLLAndSwitchSystem(uint32_t SYSCLK_Frequency,
771                                                   LL_UTILS_ClkInitTypeDef *UTILS_ClkInitStruct)
772 {
773   ErrorStatus status = SUCCESS;
774   uint32_t hclk_frequency;
775 
776   assert_param(IS_LL_UTILS_SYSCLK_DIV(UTILS_ClkInitStruct->AHBCLKDivider));
777   assert_param(IS_LL_UTILS_APB1_DIV(UTILS_ClkInitStruct->APB1CLKDivider));
778   assert_param(IS_LL_UTILS_APB2_DIV(UTILS_ClkInitStruct->APB2CLKDivider));
779   assert_param(IS_LL_UTILS_APB3_DIV(UTILS_ClkInitStruct->APB3CLKDivider));
780 
781   /* Calculate HCLK frequency */
782   hclk_frequency = __LL_RCC_CALC_HCLK_FREQ(SYSCLK_Frequency, UTILS_ClkInitStruct->AHBCLKDivider);
783 
784   /* Increasing the number of wait states because of higher CPU frequency */
785   if (SystemCoreClock < hclk_frequency)
786   {
787     /* Set FLASH latency to highest latency */
788     status = LL_SetFlashLatency(hclk_frequency);
789   }
790 
791   /* Update system clock configuration */
792   if (status == SUCCESS)
793   {
794     /* Enable PLL1 */
795     LL_RCC_PLL1_Enable();
796     LL_RCC_PLL1_EnableDomain_SYS();
797     while (LL_RCC_PLL1_IsReady() != 1U)
798     {
799       /* Wait for PLL ready */
800     }
801 
802     /* Sysclk activation on the main PLL */
803     LL_RCC_SetAHBPrescaler(UTILS_ClkInitStruct->AHBCLKDivider);
804     LL_RCC_SetSysClkSource(LL_RCC_SYS_CLKSOURCE_PLL1);
805     while (LL_RCC_GetSysClkSource() != LL_RCC_SYS_CLKSOURCE_STATUS_PLL1)
806     {
807       /* Wait for system clock switch to PLL */
808     }
809 
810     /* Set APB1, APB2 & APB3 prescaler*/
811     LL_RCC_SetAPB1Prescaler(UTILS_ClkInitStruct->APB1CLKDivider);
812     LL_RCC_SetAPB2Prescaler(UTILS_ClkInitStruct->APB2CLKDivider);
813     LL_RCC_SetAPB3Prescaler(UTILS_ClkInitStruct->APB3CLKDivider);
814   }
815 
816   /* Decreasing the number of wait states because of lower CPU frequency */
817   if (SystemCoreClock > hclk_frequency)
818   {
819     /* Set FLASH latency to lowest latency */
820     status = LL_SetFlashLatency(hclk_frequency);
821   }
822 
823   /* Update SystemCoreClock variable */
824   if (status == SUCCESS)
825   {
826     LL_SetSystemCoreClock(hclk_frequency);
827   }
828 
829   return status;
830 }
831 
832 /**
833   * @}
834   */
835 
836 /**
837   * @}
838   */
839 
840 /**
841   * @}
842   */
843