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