1 /**
2   ******************************************************************************
3   * @file    stm32l4xx_ll_utils.c
4   * @author  MCD Application Team
5   * @brief   UTILS LL module driver.
6   ******************************************************************************
7   * @attention
8   *
9   * Copyright (c) 2017 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 "stm32l4xx_ll_utils.h"
20 #include "stm32l4xx_ll_rcc.h"
21 #include "stm32l4xx_ll_system.h"
22 #include "stm32l4xx_ll_pwr.h"
23 #ifdef  USE_FULL_ASSERT
24 #include "stm32_assert.h"
25 #else
26 #define assert_param(expr) ((void)0U)
27 #endif /* USE_FULL_ASSERT */
28 
29 /** @addtogroup STM32L4xx_LL_Driver
30   * @{
31   */
32 
33 /** @addtogroup UTILS_LL
34   * @{
35   */
36 
37 /* Private types -------------------------------------------------------------*/
38 /* Private variables ---------------------------------------------------------*/
39 /* Private constants ---------------------------------------------------------*/
40 /** @addtogroup UTILS_LL_Private_Constants
41   * @{
42   */
43 #if defined(STM32L4P5xx) || defined(STM32L4Q5xx) || \
44     defined(STM32L4R5xx) || defined(STM32L4R7xx) || defined(STM32L4R9xx) || defined(STM32L4S5xx) || defined(STM32L4S7xx) || defined(STM32L4S9xx)
45 #define UTILS_MAX_FREQUENCY_SCALE1  120000000U       /*!< Maximum frequency for system clock at power scale1, in Hz */
46 #define UTILS_MAX_FREQUENCY_SCALE2   26000000U       /*!< Maximum frequency for system clock at power scale2, in Hz */
47 #else
48 #define UTILS_MAX_FREQUENCY_SCALE1   80000000U       /*!< Maximum frequency for system clock at power scale1, in Hz */
49 #define UTILS_MAX_FREQUENCY_SCALE2   26000000U       /*!< Maximum frequency for system clock at power scale2, in Hz */
50 #endif
51 
52 /* Defines used for PLL range */
53 #define UTILS_PLLVCO_INPUT_MIN        4000000U       /*!< Frequency min for PLLVCO input, in Hz   */
54 #define UTILS_PLLVCO_INPUT_MAX       16000000U       /*!< Frequency max for PLLVCO input, in Hz   */
55 #define UTILS_PLLVCO_OUTPUT_MIN      64000000U       /*!< Frequency min for PLLVCO output, in Hz  */
56 #define UTILS_PLLVCO_OUTPUT_MAX     344000000U       /*!< Frequency max for PLLVCO output, in Hz  */
57 
58 /* Defines used for HSE range */
59 #define UTILS_HSE_FREQUENCY_MIN      4000000U        /*!< Frequency min for HSE frequency, in Hz   */
60 #define UTILS_HSE_FREQUENCY_MAX     48000000U        /*!< Frequency max for HSE frequency, in Hz   */
61 
62 /* Defines used for FLASH latency according to HCLK Frequency */
63 #if defined(STM32L4P5xx) || defined(STM32L4Q5xx) || \
64     defined(STM32L4R5xx) || defined(STM32L4R7xx) || defined(STM32L4R9xx) || defined(STM32L4S5xx) || defined(STM32L4S7xx) || defined(STM32L4S9xx)
65 #define UTILS_SCALE1_LATENCY1_FREQ   20000000U       /*!< HCLK frequency to set FLASH latency 1 in power scale 1 */
66 #define UTILS_SCALE1_LATENCY2_FREQ   40000000U       /*!< HCLK frequency to set FLASH latency 2 in power scale 1 */
67 #define UTILS_SCALE1_LATENCY3_FREQ   60000000U       /*!< HCLK frequency to set FLASH latency 3 in power scale 1 */
68 #define UTILS_SCALE1_LATENCY4_FREQ   80000000U       /*!< HCLK frequency to set FLASH latency 4 in power scale 1 */
69 #define UTILS_SCALE1_LATENCY5_FREQ  100000000U       /*!< HCLK frequency to set FLASH latency 4 in power scale 1 */
70 #define UTILS_SCALE2_LATENCY1_FREQ    8000000U       /*!< HCLK frequency to set FLASH latency 1 in power scale 2 */
71 #define UTILS_SCALE2_LATENCY2_FREQ   16000000U       /*!< HCLK frequency to set FLASH latency 2 in power scale 2 */
72 #else
73 #define UTILS_SCALE1_LATENCY1_FREQ   16000000U       /*!< HCLK frequency to set FLASH latency 1 in power scale 1 */
74 #define UTILS_SCALE1_LATENCY2_FREQ   32000000U       /*!< HCLK frequency to set FLASH latency 2 in power scale 1 */
75 #define UTILS_SCALE1_LATENCY3_FREQ   48000000U       /*!< HCLK frequency to set FLASH latency 3 in power scale 1 */
76 #define UTILS_SCALE1_LATENCY4_FREQ   64000000U       /*!< HCLK frequency to set FLASH latency 4 in power scale 1 */
77 #define UTILS_SCALE2_LATENCY1_FREQ    6000000U       /*!< HCLK frequency to set FLASH latency 1 in power scale 2 */
78 #define UTILS_SCALE2_LATENCY2_FREQ   12000000U       /*!< HCLK frequency to set FLASH latency 2 in power scale 2 */
79 #define UTILS_SCALE2_LATENCY3_FREQ   18000000U       /*!< HCLK frequency to set FLASH latency 3 in power scale 2 */
80 #endif
81 /**
82   * @}
83   */
84 
85 /* Private macros ------------------------------------------------------------*/
86 /** @addtogroup UTILS_LL_Private_Macros
87   * @{
88   */
89 #define IS_LL_UTILS_SYSCLK_DIV(__VALUE__) (((__VALUE__) == LL_RCC_SYSCLK_DIV_1)   \
90                                         || ((__VALUE__) == LL_RCC_SYSCLK_DIV_2)   \
91                                         || ((__VALUE__) == LL_RCC_SYSCLK_DIV_4)   \
92                                         || ((__VALUE__) == LL_RCC_SYSCLK_DIV_8)   \
93                                         || ((__VALUE__) == LL_RCC_SYSCLK_DIV_16)  \
94                                         || ((__VALUE__) == LL_RCC_SYSCLK_DIV_64)  \
95                                         || ((__VALUE__) == LL_RCC_SYSCLK_DIV_128) \
96                                         || ((__VALUE__) == LL_RCC_SYSCLK_DIV_256) \
97                                         || ((__VALUE__) == LL_RCC_SYSCLK_DIV_512))
98 
99 #define IS_LL_UTILS_APB1_DIV(__VALUE__) (((__VALUE__) == LL_RCC_APB1_DIV_1) \
100                                       || ((__VALUE__) == LL_RCC_APB1_DIV_2) \
101                                       || ((__VALUE__) == LL_RCC_APB1_DIV_4) \
102                                       || ((__VALUE__) == LL_RCC_APB1_DIV_8) \
103                                       || ((__VALUE__) == LL_RCC_APB1_DIV_16))
104 
105 #define IS_LL_UTILS_APB2_DIV(__VALUE__) (((__VALUE__) == LL_RCC_APB2_DIV_1) \
106                                       || ((__VALUE__) == LL_RCC_APB2_DIV_2) \
107                                       || ((__VALUE__) == LL_RCC_APB2_DIV_4) \
108                                       || ((__VALUE__) == LL_RCC_APB2_DIV_8) \
109                                       || ((__VALUE__) == LL_RCC_APB2_DIV_16))
110 
111 #define IS_LL_UTILS_PLLM_VALUE(__VALUE__) (((__VALUE__) == LL_RCC_PLLM_DIV_1) \
112                                         || ((__VALUE__) == LL_RCC_PLLM_DIV_2) \
113                                         || ((__VALUE__) == LL_RCC_PLLM_DIV_3) \
114                                         || ((__VALUE__) == LL_RCC_PLLM_DIV_4) \
115                                         || ((__VALUE__) == LL_RCC_PLLM_DIV_5) \
116                                         || ((__VALUE__) == LL_RCC_PLLM_DIV_6) \
117                                         || ((__VALUE__) == LL_RCC_PLLM_DIV_7) \
118                                         || ((__VALUE__) == LL_RCC_PLLM_DIV_8))
119 
120 #define IS_LL_UTILS_PLLN_VALUE(__VALUE__) ((8U <= (__VALUE__)) && ((__VALUE__) <= 86U))
121 
122 #define IS_LL_UTILS_PLLR_VALUE(__VALUE__) (((__VALUE__) == LL_RCC_PLLR_DIV_2) \
123                                         || ((__VALUE__) == LL_RCC_PLLR_DIV_4) \
124                                         || ((__VALUE__) == LL_RCC_PLLR_DIV_6) \
125                                         || ((__VALUE__) == LL_RCC_PLLR_DIV_8))
126 
127 #define IS_LL_UTILS_PLLVCO_INPUT(__VALUE__)  ((UTILS_PLLVCO_INPUT_MIN <= (__VALUE__)) && ((__VALUE__) <= UTILS_PLLVCO_INPUT_MAX))
128 
129 #define IS_LL_UTILS_PLLVCO_OUTPUT(__VALUE__) ((UTILS_PLLVCO_OUTPUT_MIN <= (__VALUE__)) && ((__VALUE__) <= UTILS_PLLVCO_OUTPUT_MAX))
130 
131 #define IS_LL_UTILS_PLL_FREQUENCY(__VALUE__) ((LL_PWR_GetRegulVoltageScaling() == LL_PWR_REGU_VOLTAGE_SCALE1) ? ((__VALUE__) <= UTILS_MAX_FREQUENCY_SCALE1) : \
132                                              ((__VALUE__) <= UTILS_MAX_FREQUENCY_SCALE2))
133 
134 #define IS_LL_UTILS_HSE_BYPASS(__STATE__) (((__STATE__) == LL_UTILS_HSEBYPASS_ON) \
135                                         || ((__STATE__) == LL_UTILS_HSEBYPASS_OFF))
136 
137 #define IS_LL_UTILS_HSE_FREQUENCY(__FREQUENCY__) (((__FREQUENCY__) >= UTILS_HSE_FREQUENCY_MIN) && ((__FREQUENCY__) <= UTILS_HSE_FREQUENCY_MAX))
138 /**
139   * @}
140   */
141 /* Private function prototypes -----------------------------------------------*/
142 /** @defgroup UTILS_LL_Private_Functions UTILS Private functions
143   * @{
144   */
145 static uint32_t    UTILS_GetPLLOutputFrequency(uint32_t PLL_InputFrequency,
146                                                LL_UTILS_PLLInitTypeDef *UTILS_PLLInitStruct);
147 static ErrorStatus UTILS_EnablePLLAndSwitchSystem(uint32_t SYSCLK_Frequency, 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   */
LL_mDelay(uint32_t Delay)186 void LL_mDelay(uint32_t Delay)
187 {
188   __IO uint32_t  tmp = SysTick->CTRL;  /* Clear the COUNTFLAG first */
189   uint32_t tmpDelay = Delay;
190 
191   /* Add this code to indicate that local variable is not used */
192   ((void)tmp);
193 
194   /* Add a period to guaranty minimum wait */
195   if(tmpDelay < LL_MAX_DELAY)
196   {
197     tmpDelay++;
198   }
199 
200   while (tmpDelay != 0U)
201   {
202     if((SysTick->CTRL & SysTick_CTRL_COUNTFLAG_Msk) != 0U)
203     {
204       tmpDelay--;
205     }
206   }
207 }
208 
209 /**
210   * @}
211   */
212 
213 /** @addtogroup UTILS_EF_SYSTEM
214   *  @brief    System Configuration functions
215   *
216   @verbatim
217  ===============================================================================
218            ##### System Configuration functions #####
219  ===============================================================================
220     [..]
221          System, AHB and APB buses clocks configuration
222 
223          (+) The maximum frequency of the SYSCLK, HCLK, PCLK1 and PCLK2 is
224              120000000 Hz for STM32L4Rx/STM32L4Sx devices and 80000000 Hz for others.
225   @endverbatim
226   @internal
227              Depending on the device voltage range, the maximum frequency should be
228              adapted accordingly:
229 
230              (++) Table 1. HCLK clock frequency for STM32L4+ Series devices
231              (++) +--------------------------------------------------------+
232              (++) | Latency         |     HCLK clock frequency (MHz)       |
233              (++) |                 |--------------------------------------|
234              (++) |                 |  voltage range 1  | voltage range 2  |
235              (++) |                 |       1.2 V       |     1.0 V        |
236              (++) |-----------------|-------------------|------------------|
237              (++) |0WS(1 CPU cycles)|   0 < HCLK <= 20  |  0 < HCLK <= 8   |
238              (++) |-----------------|-------------------|------------------|
239              (++) |1WS(2 CPU cycles)|  20 < HCLK <= 40  |  8 < HCLK <= 16  |
240              (++) |-----------------|-------------------|------------------|
241              (++) |2WS(3 CPU cycles)|  40 < HCLK <= 60  | 16 < HCLK <= 26  |
242              (++) |-----------------|-------------------|------------------|
243              (++) |3WS(4 CPU cycles)|  60 < HCLK <= 80  | 16 < HCLK <= 26  |
244              (++) |-----------------|-------------------|------------------|
245              (++) |4WS(5 CPU cycles)|  80 < HCLK <= 100 | 16 < HCLK <= 26  |
246              (++) |-----------------|-------------------|------------------|
247              (++) |5WS(6 CPU cycles)| 100 < HCLK <= 120 | 16 < HCLK <= 26  |
248              (++) +--------------------------------------------------------+
249 
250              (++) Table 2. HCLK clock frequency for STM32L4 Series devices
251              (++) +-------------------------------------------------------+
252              (++) | Latency         |    HCLK clock frequency (MHz)       |
253              (++) |                 |-------------------------------------|
254              (++) |                 | voltage range 1  | voltage range 2  |
255              (++) |                 |      1.2 V       |     1.0 V        |
256              (++) |-----------------|------------------|------------------|
257              (++) |0WS(1 CPU cycles)|  0 < HCLK <= 16  |  0 < HCLK <= 6   |
258              (++) |-----------------|------------------|------------------|
259              (++) |1WS(2 CPU cycles)| 16 < HCLK <= 32  |  6 < HCLK <= 12  |
260              (++) |-----------------|------------------|------------------|
261              (++) |2WS(3 CPU cycles)| 32 < HCLK <= 48  | 12 < HCLK <= 18  |
262              (++) |-----------------|------------------|------------------|
263              (++) |3WS(4 CPU cycles)| 48 < HCLK <= 64  | 18 < HCLK <= 26  |
264              (++) |-----------------|------------------|------------------|
265              (++) |4WS(5 CPU cycles)| 64 < HCLK <= 80  | 18 < HCLK <= 26  |
266              (++) +-------------------------------------------------------+
267 
268   @endinternal
269   * @{
270   */
271 
272 /**
273   * @brief  This function sets directly SystemCoreClock CMSIS variable.
274   * @note   Variable can be calculated also through SystemCoreClockUpdate function.
275   * @param  HCLKFrequency HCLK frequency in Hz (can be calculated thanks to RCC helper macro)
276   * @retval None
277   */
LL_SetSystemCoreClock(uint32_t HCLKFrequency)278 void LL_SetSystemCoreClock(uint32_t HCLKFrequency)
279 {
280   /* HCLK clock frequency */
281   SystemCoreClock = HCLKFrequency;
282 }
283 
284 /**
285   * @brief  Update number of Flash wait states in line with new frequency and current
286             voltage range.
287   * @param  HCLKFrequency  HCLK frequency
288   * @retval An ErrorStatus enumeration value:
289   *          - SUCCESS: Latency has been modified
290   *          - ERROR: Latency cannot be modified
291   */
LL_SetFlashLatency(uint32_t HCLKFrequency)292 ErrorStatus LL_SetFlashLatency(uint32_t HCLKFrequency)
293 {
294   ErrorStatus status = SUCCESS;
295 
296   uint32_t latency = LL_FLASH_LATENCY_0;  /* default value 0WS */
297 
298   /* Frequency cannot be equal to 0 or greater than max clock */
299   if ((HCLKFrequency == 0U) || (HCLKFrequency > UTILS_MAX_FREQUENCY_SCALE1))
300   {
301     status = ERROR;
302   }
303   else
304   {
305     if(LL_PWR_GetRegulVoltageScaling() == LL_PWR_REGU_VOLTAGE_SCALE1)
306     {
307 #if defined(STM32L4P5xx) || defined(STM32L4Q5xx) || \
308     defined(STM32L4R5xx) || defined(STM32L4R7xx) || defined(STM32L4R9xx) || defined(STM32L4S5xx) || defined(STM32L4S7xx) || defined(STM32L4S9xx)
309       if(HCLKFrequency > UTILS_SCALE1_LATENCY5_FREQ)
310       {
311         /* 100 < HCLK <= 120 => 5WS (6 CPU cycles) */
312         latency = LL_FLASH_LATENCY_5;
313       }
314       else if(HCLKFrequency > UTILS_SCALE1_LATENCY4_FREQ)
315       {
316         /* 80 < HCLK <= 100 => 4WS (5 CPU cycles) */
317         latency = LL_FLASH_LATENCY_4;
318       }
319       else if(HCLKFrequency > UTILS_SCALE1_LATENCY3_FREQ)
320       {
321         /* 60 < HCLK <= 80 => 3WS (4 CPU cycles) */
322         latency = LL_FLASH_LATENCY_3;
323       }
324       else if(HCLKFrequency > UTILS_SCALE1_LATENCY2_FREQ)
325       {
326         /* 40 < HCLK <= 20 => 2WS (3 CPU cycles) */
327         latency = LL_FLASH_LATENCY_2;
328       }
329       else
330       {
331         if(HCLKFrequency > UTILS_SCALE1_LATENCY1_FREQ)
332         {
333           /* 20 < HCLK <= 40 => 1WS (2 CPU cycles) */
334           latency = LL_FLASH_LATENCY_1;
335         }
336         /* else HCLKFrequency <= 10MHz default LL_FLASH_LATENCY_0 0WS */
337       }
338 #else
339       if(HCLKFrequency > UTILS_SCALE1_LATENCY4_FREQ)
340       {
341         /* 64 < HCLK <= 80 => 4WS (5 CPU cycles) */
342         latency = LL_FLASH_LATENCY_4;
343       }
344       else if(HCLKFrequency > UTILS_SCALE1_LATENCY3_FREQ)
345       {
346         /* 48 < HCLK <= 64 => 3WS (4 CPU cycles) */
347         latency = LL_FLASH_LATENCY_3;
348       }
349       else if(HCLKFrequency > UTILS_SCALE1_LATENCY2_FREQ)
350       {
351         /* 32 < HCLK <= 48 => 2WS (3 CPU cycles) */
352         latency = LL_FLASH_LATENCY_2;
353       }
354       else
355       {
356         if(HCLKFrequency > UTILS_SCALE1_LATENCY1_FREQ)
357         {
358           /* 16 < HCLK <= 32 => 1WS (2 CPU cycles) */
359           latency = LL_FLASH_LATENCY_1;
360         }
361         /* else HCLKFrequency <= 16MHz default LL_FLASH_LATENCY_0 0WS */
362       }
363 #endif
364     }
365     else /* SCALE2 */
366     {
367 #if defined(STM32L4P5xx) || defined(STM32L4Q5xx) || \
368     defined(STM32L4R5xx) || defined(STM32L4R7xx) || defined(STM32L4R9xx) || defined(STM32L4S5xx) || defined(STM32L4S7xx) || defined(STM32L4S9xx)
369       if(HCLKFrequency > UTILS_MAX_FREQUENCY_SCALE2)
370       {
371         /* Unexpected HCLK > 26 */
372         status = ERROR;
373       }
374       else if(HCLKFrequency > UTILS_SCALE2_LATENCY2_FREQ)
375       {
376         /* 16 < HCLK <= 26 => 2WS (3 CPU cycles) */
377         latency = LL_FLASH_LATENCY_2;
378       }
379       else
380       {
381         if(HCLKFrequency > UTILS_SCALE2_LATENCY1_FREQ)
382         {
383           /* 8 < HCLK <= 16 => 1WS (2 CPU cycles) */
384           latency = LL_FLASH_LATENCY_1;
385         }
386         /* else HCLKFrequency <= 8MHz default LL_FLASH_LATENCY_0 0WS */
387       }
388 #else
389       if(HCLKFrequency > UTILS_MAX_FREQUENCY_SCALE2)
390       {
391         /* Unexpected HCLK > 26 */
392         status = ERROR;
393       }
394       else if(HCLKFrequency > UTILS_SCALE2_LATENCY3_FREQ)
395       {
396         /* 18 < HCLK <= 26 => 3WS (4 CPU cycles) */
397         latency = LL_FLASH_LATENCY_3;
398       }
399       else if(HCLKFrequency > UTILS_SCALE2_LATENCY2_FREQ)
400       {
401         /* 12 < HCLK <= 18 => 2WS (3 CPU cycles) */
402         latency = LL_FLASH_LATENCY_2;
403       }
404       else
405       {
406         if(HCLKFrequency > UTILS_SCALE2_LATENCY1_FREQ)
407         {
408           /* 6 < HCLK <= 12 => 1WS (2 CPU cycles) */
409           latency = LL_FLASH_LATENCY_1;
410         }
411         /* else HCLKFrequency <= 6MHz default LL_FLASH_LATENCY_0 0WS */
412       }
413 #endif
414     }
415 
416     LL_FLASH_SetLatency(latency);
417 
418     /* Check that the new number of wait states is taken into account to access the Flash
419        memory by reading the FLASH_ACR register */
420     if(LL_FLASH_GetLatency() != latency)
421     {
422       status = ERROR;
423     }
424   }
425   return status;
426 }
427 
428 /**
429   * @brief  This function configures system clock with MSI as clock source of the PLL
430   * @note   The application needs to ensure that PLL, PLLSAI1 and/or PLLSAI2 are disabled.
431   * @note   Function is based on the following formula:
432   *         - PLL output frequency = (((MSI frequency / PLLM) * PLLN) / PLLR)
433   *         - PLLM: ensure that the VCO input frequency ranges from 4 to 16 MHz (PLLVCO_input = MSI frequency / PLLM)
434   *         - PLLN: ensure that the VCO output frequency is between 64 and 344 MHz (PLLVCO_output = PLLVCO_input * PLLN)
435   *         - PLLR: ensure that max frequency at 120000000 Hz is reached (PLLVCO_output / PLLR)
436   * @param  UTILS_PLLInitStruct pointer to a @ref LL_UTILS_PLLInitTypeDef structure that contains
437   *                             the configuration information for the PLL.
438   * @param  UTILS_ClkInitStruct pointer to a @ref LL_UTILS_ClkInitTypeDef structure that contains
439   *                             the configuration information for the BUS prescalers.
440   * @retval An ErrorStatus enumeration value:
441   *          - SUCCESS: Max frequency configuration done
442   *          - ERROR: Max frequency configuration not done
443   */
LL_PLL_ConfigSystemClock_MSI(LL_UTILS_PLLInitTypeDef * UTILS_PLLInitStruct,LL_UTILS_ClkInitTypeDef * UTILS_ClkInitStruct)444 ErrorStatus LL_PLL_ConfigSystemClock_MSI(LL_UTILS_PLLInitTypeDef *UTILS_PLLInitStruct,
445                                          LL_UTILS_ClkInitTypeDef *UTILS_ClkInitStruct)
446 {
447   ErrorStatus status = SUCCESS;
448   uint32_t pllfreq, msi_range;
449 #if defined(STM32L4P5xx) || defined(STM32L4Q5xx) || \
450     defined(STM32L4R5xx) || defined(STM32L4R7xx) || defined(STM32L4R9xx) || defined(STM32L4S5xx) || defined(STM32L4S7xx) || defined(STM32L4S9xx)
451   uint32_t hpre = 0U;  /* Set default value */
452 #endif
453 
454   /* Check if one of the PLL is enabled */
455   if(UTILS_PLL_IsBusy() == SUCCESS)
456   {
457     /* Get the current MSI range */
458     if(LL_RCC_MSI_IsEnabledRangeSelect() != 0U)
459     {
460       msi_range =  LL_RCC_MSI_GetRange();
461       switch (msi_range)
462       {
463         case LL_RCC_MSIRANGE_0:     /* MSI = 100 KHz  */
464         case LL_RCC_MSIRANGE_1:     /* MSI = 200 KHz  */
465         case LL_RCC_MSIRANGE_2:     /* MSI = 400 KHz  */
466         case LL_RCC_MSIRANGE_3:     /* MSI = 800 KHz  */
467         case LL_RCC_MSIRANGE_4:     /* MSI = 1 MHz    */
468         case LL_RCC_MSIRANGE_5:     /* MSI = 2 MHz    */
469           /* PLLVCO input frequency is not in the range from 4 to 16 MHz*/
470           status = ERROR;
471           break;
472 
473         case LL_RCC_MSIRANGE_6:     /* MSI = 4 MHz    */
474         case LL_RCC_MSIRANGE_7:     /* MSI = 8 MHz    */
475         case LL_RCC_MSIRANGE_8:     /* MSI = 16 MHz   */
476         case LL_RCC_MSIRANGE_9:     /* MSI = 24 MHz   */
477         case LL_RCC_MSIRANGE_10:    /* MSI = 32 MHz   */
478         case LL_RCC_MSIRANGE_11:    /* MSI = 48 MHz   */
479         default:
480           break;
481       }
482     }
483     else
484     {
485       msi_range = LL_RCC_MSI_GetRangeAfterStandby();
486       switch (msi_range)
487       {
488         case LL_RCC_MSISRANGE_4:    /* MSI = 1 MHz    */
489         case LL_RCC_MSISRANGE_5:    /* MSI = 2 MHz    */
490           /* PLLVCO input frequency is not in the range from 4 to 16 MHz*/
491           status = ERROR;
492           break;
493 
494         case LL_RCC_MSISRANGE_7:    /* MSI = 8 MHz    */
495         case LL_RCC_MSISRANGE_6:    /* MSI = 4 MHz    */
496         default:
497           break;
498       }
499     }
500 
501     /* Main PLL configuration and activation */
502     if(status != ERROR)
503     {
504       /* Calculate the new PLL output frequency */
505       pllfreq = UTILS_GetPLLOutputFrequency(__LL_RCC_CALC_MSI_FREQ(LL_RCC_MSI_IsEnabledRangeSelect(), msi_range),
506                                             UTILS_PLLInitStruct);
507 
508       /* Enable MSI if not enabled */
509       if(LL_RCC_MSI_IsReady() != 1U)
510       {
511         LL_RCC_MSI_Enable();
512         while ((LL_RCC_MSI_IsReady() != 1U))
513         {
514           /* Wait for MSI ready */
515         }
516       }
517 
518       /* Configure PLL */
519       LL_RCC_PLL_ConfigDomain_SYS(LL_RCC_PLLSOURCE_MSI, UTILS_PLLInitStruct->PLLM, UTILS_PLLInitStruct->PLLN,
520                                   UTILS_PLLInitStruct->PLLR);
521 
522 #if defined(STM32L4P5xx) || defined(STM32L4Q5xx) || \
523     defined(STM32L4R5xx) || defined(STM32L4R7xx) || defined(STM32L4R9xx) || defined(STM32L4S5xx) || defined(STM32L4S7xx) || defined(STM32L4S9xx)
524       /* Prevent undershoot at highest frequency by applying intermediate AHB prescaler 2 */
525       if(pllfreq > 80000000U)
526       {
527         if(UTILS_ClkInitStruct->AHBCLKDivider == LL_RCC_SYSCLK_DIV_1)
528         {
529           UTILS_ClkInitStruct->AHBCLKDivider = LL_RCC_SYSCLK_DIV_2;
530           hpre = LL_RCC_SYSCLK_DIV_2;
531         }
532       }
533 #endif
534       /* Enable PLL and switch system clock to PLL */
535       status = UTILS_EnablePLLAndSwitchSystem(pllfreq, UTILS_ClkInitStruct);
536 
537 #if defined(STM32L4P5xx) || defined(STM32L4Q5xx) || \
538     defined(STM32L4R5xx) || defined(STM32L4R7xx) || defined(STM32L4R9xx) || defined(STM32L4S5xx) || defined(STM32L4S7xx) || defined(STM32L4S9xx)
539       /* Apply definitive AHB prescaler value if necessary */
540       if((status == SUCCESS) && (hpre != LL_RCC_SYSCLK_DIV_1))
541       {
542         /* Set FLASH latency to highest latency */
543         status = LL_SetFlashLatency(pllfreq);
544         if(status == SUCCESS)
545         {
546           UTILS_ClkInitStruct->AHBCLKDivider = LL_RCC_SYSCLK_DIV_1;
547           LL_RCC_SetAHBPrescaler(UTILS_ClkInitStruct->AHBCLKDivider);
548           LL_SetSystemCoreClock(pllfreq);
549         }
550       }
551 #endif
552     }
553   }
554   else
555   {
556     /* Current PLL configuration cannot be modified */
557     status = ERROR;
558   }
559 
560   return status;
561 }
562 
563 /**
564   * @brief  This function configures system clock at maximum frequency with HSI as clock source of the PLL
565   * @note   The application need to ensure that PLL, PLLSAI1 and/or PLLSAI2 are disabled.
566   * @note   Function is based on the following formula:
567   *         - PLL output frequency = (((HSI frequency / PLLM) * PLLN) / PLLR)
568   *         - PLLM: ensure that the VCO input frequency ranges from 4 to 16 MHz (PLLVCO_input = HSI frequency / PLLM)
569   *         - PLLN: ensure that the VCO output frequency is between 64 and 344 MHz (PLLVCO_output = PLLVCO_input * PLLN)
570   *         - PLLR: ensure that max frequency at 120000000 Hz is reach (PLLVCO_output / PLLR)
571   * @param  UTILS_PLLInitStruct pointer to a @ref LL_UTILS_PLLInitTypeDef structure that contains
572   *                             the configuration information for the PLL.
573   * @param  UTILS_ClkInitStruct pointer to a @ref LL_UTILS_ClkInitTypeDef structure that contains
574   *                             the configuration information for the BUS prescalers.
575   * @retval An ErrorStatus enumeration value:
576   *          - SUCCESS: Max frequency configuration done
577   *          - ERROR: Max frequency configuration not done
578   */
LL_PLL_ConfigSystemClock_HSI(LL_UTILS_PLLInitTypeDef * UTILS_PLLInitStruct,LL_UTILS_ClkInitTypeDef * UTILS_ClkInitStruct)579 ErrorStatus LL_PLL_ConfigSystemClock_HSI(LL_UTILS_PLLInitTypeDef *UTILS_PLLInitStruct,
580                                          LL_UTILS_ClkInitTypeDef *UTILS_ClkInitStruct)
581 {
582   ErrorStatus status;
583   uint32_t pllfreq;
584 #if defined(STM32L4P5xx) || defined(STM32L4Q5xx) || \
585     defined(STM32L4R5xx) || defined(STM32L4R7xx) || defined(STM32L4R9xx) || defined(STM32L4S5xx) || defined(STM32L4S7xx) || defined(STM32L4S9xx)
586   uint32_t hpre = LL_RCC_SYSCLK_DIV_1;  /* Set default value */
587 #endif
588 
589   /* Check if one of the PLL is enabled */
590   if(UTILS_PLL_IsBusy() == SUCCESS)
591   {
592     /* Calculate the new PLL output frequency */
593     pllfreq = UTILS_GetPLLOutputFrequency(HSI_VALUE, UTILS_PLLInitStruct);
594 
595     /* Enable HSI if not enabled */
596     if(LL_RCC_HSI_IsReady() != 1U)
597     {
598       LL_RCC_HSI_Enable();
599       while (LL_RCC_HSI_IsReady() != 1U)
600       {
601         /* Wait for HSI ready */
602       }
603     }
604 
605     /* Configure PLL */
606     LL_RCC_PLL_ConfigDomain_SYS(LL_RCC_PLLSOURCE_HSI, UTILS_PLLInitStruct->PLLM, UTILS_PLLInitStruct->PLLN,
607                                 UTILS_PLLInitStruct->PLLR);
608 
609 #if defined(STM32L4P5xx) || defined(STM32L4Q5xx) || \
610     defined(STM32L4R5xx) || defined(STM32L4R7xx) || defined(STM32L4R9xx) || defined(STM32L4S5xx) || defined(STM32L4S7xx) || defined(STM32L4S9xx)
611     /* Prevent undershoot at highest frequency by applying intermediate AHB prescaler 2 */
612     if(pllfreq > 80000000U)
613     {
614       if(UTILS_ClkInitStruct->AHBCLKDivider == LL_RCC_SYSCLK_DIV_1)
615       {
616         UTILS_ClkInitStruct->AHBCLKDivider = LL_RCC_SYSCLK_DIV_2;
617         hpre = LL_RCC_SYSCLK_DIV_2;
618       }
619     }
620 #endif
621     /* Enable PLL and switch system clock to PLL */
622     status = UTILS_EnablePLLAndSwitchSystem(pllfreq, UTILS_ClkInitStruct);
623 
624 #if defined(STM32L4P5xx) || defined(STM32L4Q5xx) || \
625     defined(STM32L4R5xx) || defined(STM32L4R7xx) || defined(STM32L4R9xx) || defined(STM32L4S5xx) || defined(STM32L4S7xx) || defined(STM32L4S9xx)
626     /* Apply definitive AHB prescaler value if necessary */
627     if((status == SUCCESS) && (hpre != LL_RCC_SYSCLK_DIV_1))
628     {
629       /* Set FLASH latency to highest latency */
630       status = LL_SetFlashLatency(pllfreq);
631       if(status == SUCCESS)
632       {
633         UTILS_ClkInitStruct->AHBCLKDivider = LL_RCC_SYSCLK_DIV_1;
634         LL_RCC_SetAHBPrescaler(UTILS_ClkInitStruct->AHBCLKDivider);
635         LL_SetSystemCoreClock(pllfreq);
636       }
637     }
638 #endif
639   }
640   else
641   {
642     /* Current PLL configuration cannot be modified */
643     status = ERROR;
644   }
645 
646   return status;
647 }
648 
649 /**
650   * @brief  This function configures system clock with HSE as clock source of the PLL
651   * @note   The application need to ensure that PLL, PLLSAI1 and/or PLLSAI2 are disabled.
652   * @note   Function is based on the following formula:
653   *         - PLL output frequency = (((HSE frequency / PLLM) * PLLN) / PLLR)
654   *         - PLLM: ensure that the VCO input frequency ranges from 4 to 16 MHz (PLLVCO_input = HSE frequency / PLLM)
655   *         - PLLN: ensure that the VCO output frequency is between 64 and 344 MHz (PLLVCO_output = PLLVCO_input * PLLN)
656   *         - PLLR: ensure that max frequency at 120000000 Hz is reached (PLLVCO_output / PLLR)
657   * @param  HSEFrequency Value between Min_Data = 4000000 and Max_Data = 48000000
658   * @param  HSEBypass This parameter can be one of the following values:
659   *         @arg @ref LL_UTILS_HSEBYPASS_ON
660   *         @arg @ref LL_UTILS_HSEBYPASS_OFF
661   * @param  UTILS_PLLInitStruct pointer to a @ref LL_UTILS_PLLInitTypeDef structure that contains
662   *                             the configuration information for the PLL.
663   * @param  UTILS_ClkInitStruct pointer to a @ref LL_UTILS_ClkInitTypeDef structure that contains
664   *                             the configuration information for the BUS prescalers.
665   * @retval An ErrorStatus enumeration value:
666   *          - SUCCESS: Max frequency configuration done
667   *          - ERROR: Max frequency configuration not done
668   */
LL_PLL_ConfigSystemClock_HSE(uint32_t HSEFrequency,uint32_t HSEBypass,LL_UTILS_PLLInitTypeDef * UTILS_PLLInitStruct,LL_UTILS_ClkInitTypeDef * UTILS_ClkInitStruct)669 ErrorStatus LL_PLL_ConfigSystemClock_HSE(uint32_t HSEFrequency, uint32_t HSEBypass,
670                                          LL_UTILS_PLLInitTypeDef *UTILS_PLLInitStruct, LL_UTILS_ClkInitTypeDef *UTILS_ClkInitStruct)
671 {
672   ErrorStatus status;
673   uint32_t pllfreq;
674 #if defined(STM32L4P5xx) || defined(STM32L4Q5xx) || \
675     defined(STM32L4R5xx) || defined(STM32L4R7xx) || defined(STM32L4R9xx) || defined(STM32L4S5xx) || defined(STM32L4S7xx) || defined(STM32L4S9xx)
676   uint32_t hpre = 0U;  /* Set default value */
677 #endif
678 
679   /* Check the parameters */
680   assert_param(IS_LL_UTILS_HSE_FREQUENCY(HSEFrequency));
681   assert_param(IS_LL_UTILS_HSE_BYPASS(HSEBypass));
682 
683   /* Check if one of the PLL is enabled */
684   if(UTILS_PLL_IsBusy() == SUCCESS)
685   {
686     /* Calculate the new PLL output frequency */
687     pllfreq = UTILS_GetPLLOutputFrequency(HSEFrequency, UTILS_PLLInitStruct);
688 
689     /* Enable HSE if not enabled */
690     if(LL_RCC_HSE_IsReady() != 1U)
691     {
692       /* Check if need to enable HSE bypass feature or not */
693       if(HSEBypass == LL_UTILS_HSEBYPASS_ON)
694       {
695         LL_RCC_HSE_EnableBypass();
696       }
697       else
698       {
699         LL_RCC_HSE_DisableBypass();
700       }
701 
702       /* Enable HSE */
703       LL_RCC_HSE_Enable();
704       while (LL_RCC_HSE_IsReady() != 1U)
705       {
706         /* Wait for HSE ready */
707       }
708     }
709 
710     /* Configure PLL */
711     LL_RCC_PLL_ConfigDomain_SYS(LL_RCC_PLLSOURCE_HSE, UTILS_PLLInitStruct->PLLM, UTILS_PLLInitStruct->PLLN,
712                                 UTILS_PLLInitStruct->PLLR);
713 
714 #if defined(STM32L4P5xx) || defined(STM32L4Q5xx) || \
715     defined(STM32L4R5xx) || defined(STM32L4R7xx) || defined(STM32L4R9xx) || defined(STM32L4S5xx) || defined(STM32L4S7xx) || defined(STM32L4S9xx)
716     /* Prevent undershoot at highest frequency by applying intermediate AHB prescaler 2 */
717     if(pllfreq > 80000000U)
718     {
719       if(UTILS_ClkInitStruct->AHBCLKDivider == LL_RCC_SYSCLK_DIV_1)
720       {
721         UTILS_ClkInitStruct->AHBCLKDivider = LL_RCC_SYSCLK_DIV_2;
722         hpre = LL_RCC_SYSCLK_DIV_2;
723       }
724     }
725 #endif
726     /* Enable PLL and switch system clock to PLL */
727     status = UTILS_EnablePLLAndSwitchSystem(pllfreq, UTILS_ClkInitStruct);
728 
729 #if defined(STM32L4P5xx) || defined(STM32L4Q5xx) || \
730     defined(STM32L4R5xx) || defined(STM32L4R7xx) || defined(STM32L4R9xx) || defined(STM32L4S5xx) || defined(STM32L4S7xx) || defined(STM32L4S9xx)
731     /* Apply definitive AHB prescaler value if necessary */
732     if((status == SUCCESS) && (hpre != LL_RCC_SYSCLK_DIV_1))
733     {
734       /* Set FLASH latency to highest latency */
735       status = LL_SetFlashLatency(pllfreq);
736       if(status == SUCCESS)
737       {
738         UTILS_ClkInitStruct->AHBCLKDivider = LL_RCC_SYSCLK_DIV_1;
739         LL_RCC_SetAHBPrescaler(UTILS_ClkInitStruct->AHBCLKDivider);
740         LL_SetSystemCoreClock(pllfreq);
741       }
742     }
743 #endif
744   }
745   else
746   {
747     /* Current PLL configuration cannot be modified */
748     status = ERROR;
749   }
750 
751   return status;
752 }
753 
754 /**
755   * @}
756   */
757 
758 /**
759   * @}
760   */
761 
762 /** @addtogroup UTILS_LL_Private_Functions
763   * @{
764   */
765 /**
766   * @brief  Function to check that PLL can be modified
767   * @param  PLL_InputFrequency  PLL input frequency (in Hz)
768   * @param  UTILS_PLLInitStruct pointer to a @ref LL_UTILS_PLLInitTypeDef structure that contains
769   *                             the configuration information for the PLL.
770   * @retval PLL output frequency (in Hz)
771   */
UTILS_GetPLLOutputFrequency(uint32_t PLL_InputFrequency,LL_UTILS_PLLInitTypeDef * UTILS_PLLInitStruct)772 static uint32_t UTILS_GetPLLOutputFrequency(uint32_t PLL_InputFrequency, LL_UTILS_PLLInitTypeDef *UTILS_PLLInitStruct)
773 {
774   uint32_t pllfreq;
775 
776   /* Check the parameters */
777   assert_param(IS_LL_UTILS_PLLM_VALUE(UTILS_PLLInitStruct->PLLM));
778   assert_param(IS_LL_UTILS_PLLN_VALUE(UTILS_PLLInitStruct->PLLN));
779   assert_param(IS_LL_UTILS_PLLR_VALUE(UTILS_PLLInitStruct->PLLR));
780 
781   /* Check different PLL parameters according to RM                          */
782   /*  - PLLM: ensure that the VCO input frequency ranges from 4 to 16 MHz.   */
783   pllfreq = PLL_InputFrequency / (((UTILS_PLLInitStruct->PLLM >> RCC_PLLCFGR_PLLM_Pos) + 1U));
784   assert_param(IS_LL_UTILS_PLLVCO_INPUT(pllfreq));
785 
786   /*  - PLLN: ensure that the VCO output frequency is between 64 and 344 MHz.*/
787   pllfreq = pllfreq * (UTILS_PLLInitStruct->PLLN & (RCC_PLLCFGR_PLLN >> RCC_PLLCFGR_PLLN_Pos));
788   assert_param(IS_LL_UTILS_PLLVCO_OUTPUT(pllfreq));
789 
790   /*  - PLLR: ensure that max frequency at 120000000 Hz is reached                   */
791   pllfreq = pllfreq / (((UTILS_PLLInitStruct->PLLR >> RCC_PLLCFGR_PLLR_Pos) + 1U) * 2U);
792   assert_param(IS_LL_UTILS_PLL_FREQUENCY(pllfreq));
793 
794   return pllfreq;
795 }
796 
797 /**
798   * @brief  Function to check that PLL can be modified
799   * @retval An ErrorStatus enumeration value:
800   *          - SUCCESS: PLL modification can be done
801   *          - ERROR: PLL is busy
802   */
UTILS_PLL_IsBusy(void)803 static ErrorStatus UTILS_PLL_IsBusy(void)
804 {
805   ErrorStatus status = SUCCESS;
806 
807   /* Check if PLL is busy*/
808   if(LL_RCC_PLL_IsReady() != 0U)
809   {
810     /* PLL configuration cannot be modified */
811     status = ERROR;
812   }
813 
814 #if defined(RCC_PLLSAI1_SUPPORT)
815   /* Check if PLLSAI1 is busy*/
816   if(LL_RCC_PLLSAI1_IsReady() != 0U)
817   {
818     /* PLLSAI1 configuration cannot be modified */
819     status = ERROR;
820   }
821 #endif /*RCC_PLLSAI1_SUPPORT*/
822 #if defined(RCC_PLLSAI2_SUPPORT)
823 
824   /* Check if PLLSAI2 is busy*/
825   if(LL_RCC_PLLSAI2_IsReady() != 0U)
826   {
827     /* PLLSAI2 configuration cannot be modified */
828     status = ERROR;
829   }
830 #endif /*RCC_PLLSAI2_SUPPORT*/
831 
832   return status;
833 }
834 
835 /**
836   * @brief  Function to enable PLL and switch system clock to PLL
837   * @param  SYSCLK_Frequency SYSCLK frequency
838   * @param  UTILS_ClkInitStruct pointer to a @ref LL_UTILS_ClkInitTypeDef structure that contains
839   *                             the configuration information for the BUS prescalers.
840   * @retval An ErrorStatus enumeration value:
841   *          - SUCCESS: No problem to switch system to PLL
842   *          - ERROR: Problem to switch system to PLL
843   */
UTILS_EnablePLLAndSwitchSystem(uint32_t SYSCLK_Frequency,LL_UTILS_ClkInitTypeDef * UTILS_ClkInitStruct)844 static ErrorStatus UTILS_EnablePLLAndSwitchSystem(uint32_t SYSCLK_Frequency, LL_UTILS_ClkInitTypeDef *UTILS_ClkInitStruct)
845 {
846   ErrorStatus status = SUCCESS;
847   uint32_t hclk_frequency;
848 
849   assert_param(IS_LL_UTILS_SYSCLK_DIV(UTILS_ClkInitStruct->AHBCLKDivider));
850   assert_param(IS_LL_UTILS_APB1_DIV(UTILS_ClkInitStruct->APB1CLKDivider));
851   assert_param(IS_LL_UTILS_APB2_DIV(UTILS_ClkInitStruct->APB2CLKDivider));
852 
853   /* Calculate HCLK frequency */
854   hclk_frequency = __LL_RCC_CALC_HCLK_FREQ(SYSCLK_Frequency, UTILS_ClkInitStruct->AHBCLKDivider);
855 
856   /* Increasing the number of wait states because of higher CPU frequency */
857   if(SystemCoreClock < hclk_frequency)
858   {
859     /* Set FLASH latency to highest latency */
860     status = LL_SetFlashLatency(hclk_frequency);
861   }
862 
863   /* Update system clock configuration */
864   if(status == SUCCESS)
865   {
866     /* Enable PLL */
867     LL_RCC_PLL_Enable();
868     LL_RCC_PLL_EnableDomain_SYS();
869     while (LL_RCC_PLL_IsReady() != 1U)
870     {
871       /* Wait for PLL ready */
872     }
873 
874     /* Sysclk activation on the main PLL */
875     LL_RCC_SetAHBPrescaler(UTILS_ClkInitStruct->AHBCLKDivider);
876     LL_RCC_SetSysClkSource(LL_RCC_SYS_CLKSOURCE_PLL);
877     while (LL_RCC_GetSysClkSource() != LL_RCC_SYS_CLKSOURCE_STATUS_PLL)
878     {
879       /* Wait for system clock switch to PLL */
880     }
881 
882     /* Set APB1 & APB2 prescaler*/
883     LL_RCC_SetAPB1Prescaler(UTILS_ClkInitStruct->APB1CLKDivider);
884     LL_RCC_SetAPB2Prescaler(UTILS_ClkInitStruct->APB2CLKDivider);
885   }
886 
887   /* Decreasing the number of wait states because of lower CPU frequency */
888   if(SystemCoreClock > hclk_frequency)
889   {
890     /* Set FLASH latency to lowest latency */
891     status = LL_SetFlashLatency(hclk_frequency);
892   }
893 
894   /* Update SystemCoreClock variable */
895   if(status == SUCCESS)
896   {
897     LL_SetSystemCoreClock(hclk_frequency);
898   }
899 
900   return status;
901 }
902 
903 /**
904   * @}
905   */
906 
907 /**
908   * @}
909   */
910 
911 /**
912   * @}
913   */
914