1 /**
2   ******************************************************************************
3   * @file    stm32g4xx_ll_utils.c
4   * @author  MCD Application Team
5   * @brief   UTILS LL module driver.
6   ******************************************************************************
7   * @attention
8   *
9   * Copyright (c) 2019 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 
19 /* Includes ------------------------------------------------------------------*/
20 #include "stm32g4xx_ll_utils.h"
21 #include "stm32g4xx_ll_rcc.h"
22 #include "stm32g4xx_ll_system.h"
23 #include "stm32g4xx_ll_pwr.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 STM32G4xx_LL_Driver
31   * @{
32   */
33 
34 /** @addtogroup UTILS_LL
35   * @{
36   */
37 
38 /* Private types -------------------------------------------------------------*/
39 /* Private variables ---------------------------------------------------------*/
40 /* Private constants ---------------------------------------------------------*/
41 /** @addtogroup UTILS_LL_Private_Constants
42   * @{
43   */
44 #define UTILS_MAX_FREQUENCY_SCALE1  170000000U       /*!< Maximum frequency for system clock at power scale1, in Hz */
45 #define UTILS_MAX_FREQUENCY_SCALE2   26000000U       /*!< Maximum frequency for system clock at power scale2, in Hz */
46 
47 /* Defines used for PLL range */
48 #define UTILS_PLLVCO_INPUT_MIN        2660000U       /*!< Frequency min for PLLVCO input, in Hz   */
49 #define UTILS_PLLVCO_INPUT_MAX       16000000U       /*!< Frequency max for PLLVCO input, in Hz   */
50 #define UTILS_PLLVCO_OUTPUT_MIN      64000000U       /*!< Frequency min for PLLVCO output, in Hz  */
51 #define UTILS_PLLVCO_OUTPUT_MAX     344000000U       /*!< Frequency max for PLLVCO output, in Hz  */
52 
53 /* Defines used for HSE range */
54 #define UTILS_HSE_FREQUENCY_MIN      4000000U        /*!< Frequency min for HSE frequency, in Hz   */
55 #define UTILS_HSE_FREQUENCY_MAX     48000000U        /*!< Frequency max for HSE frequency, in Hz   */
56 
57 /* Defines used for FLASH latency according to HCLK Frequency */
58 #define UTILS_SCALE1_LATENCY1_BOOST_FREQ   34000000U       /*!< HCLK frequency to set FLASH latency 1 in power scale 1 */
59 #define UTILS_SCALE1_LATENCY2_BOOST_FREQ   68000000U       /*!< HCLK frequency to set FLASH latency 2 in power scale 1 */
60 #define UTILS_SCALE1_LATENCY3_BOOST_FREQ  102000000U       /*!< HCLK frequency to set FLASH latency 3 in power scale 1 */
61 #define UTILS_SCALE1_LATENCY4_BOOST_FREQ  136000000U       /*!< HCLK frequency to set FLASH latency 4 in power scale 1 */
62 #define UTILS_SCALE1_LATENCY5_BOOST_FREQ  170000000U       /*!< HCLK frequency to set FLASH latency 5 in power scale 1 */
63 
64 #define UTILS_SCALE1_LATENCY1_FREQ   30000000U       /*!< HCLK frequency to set FLASH latency 1 in power scale 1 normal mode */
65 #define UTILS_SCALE1_LATENCY2_FREQ   60000000U       /*!< HCLK frequency to set FLASH latency 2 in power scale 1 normal mode */
66 #define UTILS_SCALE1_LATENCY3_FREQ   90000000U       /*!< HCLK frequency to set FLASH latency 3 in power scale 1 normal mode */
67 #define UTILS_SCALE1_LATENCY4_FREQ  120000000U       /*!< HCLK frequency to set FLASH latency 4 in power scale 1 normal mode */
68 #define UTILS_SCALE1_LATENCY5_FREQ  150000000U       /*!< HCLK frequency to set FLASH latency 5 in power scale 1 normal mode */
69 
70 #define UTILS_SCALE2_LATENCY1_FREQ   12000000U       /*!< HCLK frequency to set FLASH latency 1 in power scale 2 */
71 #define UTILS_SCALE2_LATENCY2_FREQ   24000000U       /*!< HCLK frequency to set FLASH latency 2 in power scale 2 */
72 #define UTILS_SCALE2_LATENCY3_FREQ   26000000U       /*!< HCLK frequency to set FLASH latency 3 in power scale 2 */
73 /**
74   * @}
75   */
76 
77 /* Private macros ------------------------------------------------------------*/
78 /** @addtogroup UTILS_LL_Private_Macros
79   * @{
80   */
81 #define IS_LL_UTILS_SYSCLK_DIV(__VALUE__) (((__VALUE__) == LL_RCC_SYSCLK_DIV_1)   \
82                                         || ((__VALUE__) == LL_RCC_SYSCLK_DIV_2)   \
83                                         || ((__VALUE__) == LL_RCC_SYSCLK_DIV_4)   \
84                                         || ((__VALUE__) == LL_RCC_SYSCLK_DIV_8)   \
85                                         || ((__VALUE__) == LL_RCC_SYSCLK_DIV_16)  \
86                                         || ((__VALUE__) == LL_RCC_SYSCLK_DIV_64)  \
87                                         || ((__VALUE__) == LL_RCC_SYSCLK_DIV_128) \
88                                         || ((__VALUE__) == LL_RCC_SYSCLK_DIV_256) \
89                                         || ((__VALUE__) == LL_RCC_SYSCLK_DIV_512))
90 
91 #define IS_LL_UTILS_APB1_DIV(__VALUE__) (((__VALUE__) == LL_RCC_APB1_DIV_1) \
92                                       || ((__VALUE__) == LL_RCC_APB1_DIV_2) \
93                                       || ((__VALUE__) == LL_RCC_APB1_DIV_4) \
94                                       || ((__VALUE__) == LL_RCC_APB1_DIV_8) \
95                                       || ((__VALUE__) == LL_RCC_APB1_DIV_16))
96 
97 #define IS_LL_UTILS_APB2_DIV(__VALUE__) (((__VALUE__) == LL_RCC_APB2_DIV_1) \
98                                       || ((__VALUE__) == LL_RCC_APB2_DIV_2) \
99                                       || ((__VALUE__) == LL_RCC_APB2_DIV_4) \
100                                       || ((__VALUE__) == LL_RCC_APB2_DIV_8) \
101                                       || ((__VALUE__) == LL_RCC_APB2_DIV_16))
102 
103 #define IS_LL_UTILS_PLLM_VALUE(__VALUE__) (((__VALUE__) == LL_RCC_PLLM_DIV_1) \
104                                         || ((__VALUE__) == LL_RCC_PLLM_DIV_2) \
105                                         || ((__VALUE__) == LL_RCC_PLLM_DIV_3) \
106                                         || ((__VALUE__) == LL_RCC_PLLM_DIV_4) \
107                                         || ((__VALUE__) == LL_RCC_PLLM_DIV_5) \
108                                         || ((__VALUE__) == LL_RCC_PLLM_DIV_6) \
109                                         || ((__VALUE__) == LL_RCC_PLLM_DIV_7) \
110                                         || ((__VALUE__) == LL_RCC_PLLM_DIV_8) \
111                                         || ((__VALUE__) == LL_RCC_PLLM_DIV_9) \
112                                         || ((__VALUE__) == LL_RCC_PLLM_DIV_10) \
113                                         || ((__VALUE__) == LL_RCC_PLLM_DIV_11) \
114                                         || ((__VALUE__) == LL_RCC_PLLM_DIV_12) \
115                                         || ((__VALUE__) == LL_RCC_PLLM_DIV_13) \
116                                         || ((__VALUE__) == LL_RCC_PLLM_DIV_14) \
117                                         || ((__VALUE__) == LL_RCC_PLLM_DIV_15) \
118                                         || ((__VALUE__) == LL_RCC_PLLM_DIV_16))
119 
120 #define IS_LL_UTILS_PLLN_VALUE(__VALUE__) ((8U <= (__VALUE__)) && ((__VALUE__) <= 127U))
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; /* MISRAC2012-Rule-17.8 */
190   /* Add this code to indicate that local variable is not used */
191   ((void)tmp);
192   tmpDelay = Delay;
193   /* Add a period to guaranty minimum wait */
194   if(tmpDelay < LL_MAX_DELAY)
195   {
196     tmpDelay++;
197   }
198 
199   while (tmpDelay != 0U)
200   {
201     if((SysTick->CTRL & SysTick_CTRL_COUNTFLAG_Msk) != 0U)
202     {
203       tmpDelay--;
204     }
205   }
206 }
207 
208 /**
209   * @}
210   */
211 
212 /** @addtogroup UTILS_EF_SYSTEM
213   *  @brief    System Configuration functions
214   *
215   @verbatim
216  ===============================================================================
217            ##### System Configuration functions #####
218  ===============================================================================
219     [..]
220          System, AHB and APB buses clocks configuration
221 
222          (+) The maximum frequency of the SYSCLK, HCLK, PCLK1 and PCLK2 is
223              170000000 Hz for STM32G4xx.
224   @endverbatim
225   @internal
226              Depending on the device voltage range, the maximum frequency should be
227              adapted accordingly:
228 
229            +----------------------------------------------------------------------------+
230            | Latency         |            HCLK clock frequency (MHz)                    |
231            |                 |----------------------------------------------------------|
232            |                 |  voltage range 1  |  voltage range 1  | voltage range 2  |
233            |                 | boost mode 1.28 V | normal mode 1.2 V |     1.0 V        |
234            |-----------------|-------------------|-------------------|------------------|
235            |0WS(1 CPU cycles)|    HCLK <= 34     |    HCLK <= 30     |    HCLK <= 12    |
236            |-----------------|-------------------|-------------------|------------------|
237            |1WS(2 CPU cycles)|    HCLK <= 68     |    HCLK <= 60     |    HCLK <= 24    |
238            |-----------------|-------------------|-------------------|------------------|
239            |2WS(3 CPU cycles)|    HCLK <= 102    |    HCLK <= 90     |    HCLK <= 26    |
240            |-----------------|-------------------|-------------------|------------------|
241            |3WS(4 CPU cycles)|    HCLK <= 136    |    HCLK <= 120    |        -         |
242            |-----------------|-------------------|-------------------|------------------|
243            |4WS(5 CPU cycles)|    HCLK <= 170    |    HCLK <= 150    |        -         |
244            +----------------------------------------------------------------------------+
245 
246 
247   @endinternal
248   * @{
249   */
250 
251 /**
252   * @brief  This function sets directly SystemCoreClock CMSIS variable.
253   * @note   Variable can be calculated also through SystemCoreClockUpdate function.
254   * @param  HCLKFrequency HCLK frequency in Hz (can be calculated thanks to RCC helper macro)
255   * @retval None
256   */
LL_SetSystemCoreClock(uint32_t HCLKFrequency)257 void LL_SetSystemCoreClock(uint32_t HCLKFrequency)
258 {
259   /* HCLK clock frequency */
260   SystemCoreClock = HCLKFrequency;
261 }
262 
263 /**
264   * @brief  Update number of Flash wait states in line with new frequency and current
265             voltage range.
266   * @param  HCLKFrequency  HCLK frequency
267   * @retval An ErrorStatus enumeration value:
268   *          - SUCCESS: Latency has been modified
269   *          - ERROR: Latency cannot be modified
270   */
LL_SetFlashLatency(uint32_t HCLKFrequency)271 ErrorStatus LL_SetFlashLatency(uint32_t HCLKFrequency)
272 {
273   uint32_t timeout;
274   uint32_t getlatency;
275   ErrorStatus status = SUCCESS;
276   uint32_t regulatorstatus = LL_PWR_GetRegulVoltageScaling();
277   uint32_t regulatorbooststatus = LL_PWR_IsEnabledRange1BoostMode();
278 
279   uint32_t latency = LL_FLASH_LATENCY_0;  /* default value 0WS */
280 
281   /* Frequency cannot be equal to 0 or greater than max clock */
282   if((HCLKFrequency == 0U) || (HCLKFrequency > UTILS_SCALE1_LATENCY5_BOOST_FREQ))
283   {
284     status = ERROR;
285   }
286   else
287   {
288     if((regulatorstatus == LL_PWR_REGU_VOLTAGE_SCALE1) && (regulatorbooststatus == 1U))
289     {
290       if(HCLKFrequency > UTILS_SCALE1_LATENCY4_BOOST_FREQ)
291       {
292         /* 136 < HCLK <= 170 => 4WS (5 CPU cycles) */
293         latency = LL_FLASH_LATENCY_4;
294       }
295       else if(HCLKFrequency > UTILS_SCALE1_LATENCY3_BOOST_FREQ)
296       {
297         /* 102 < HCLK <= 136 => 3WS (4 CPU cycles) */
298         latency = LL_FLASH_LATENCY_3;
299       }
300       else if(HCLKFrequency > UTILS_SCALE1_LATENCY2_BOOST_FREQ)
301       {
302         /* 68 < HCLK <= 102 => 2WS (3 CPU cycles) */
303         latency = LL_FLASH_LATENCY_2;
304       }
305       else
306       {
307         if(HCLKFrequency > UTILS_SCALE1_LATENCY1_BOOST_FREQ)
308         {
309           /* 34 < HCLK <= 68 => 1WS (2 CPU cycles) */
310           latency = LL_FLASH_LATENCY_1;
311         }
312         /* else HCLKFrequency <= 10MHz default LL_FLASH_LATENCY_0 0WS */
313       }
314     }
315     /* SCALE1 normal mode*/
316     else if(regulatorstatus == LL_PWR_REGU_VOLTAGE_SCALE1)
317     {
318       if(HCLKFrequency > UTILS_SCALE1_LATENCY4_FREQ)
319       {
320         /* 120 < HCLK <= 150 => 4WS (5 CPU cycles) */
321         latency = LL_FLASH_LATENCY_4;
322       }
323       else if(HCLKFrequency > UTILS_SCALE1_LATENCY3_FREQ)
324       {
325         /* 90 < HCLK <= 120 => 3WS (4 CPU cycles) */
326         latency = LL_FLASH_LATENCY_3;
327       }
328       else if(HCLKFrequency > UTILS_SCALE1_LATENCY2_FREQ)
329       {
330         /* 60 < HCLK <= 90 => 2WS (3 CPU cycles) */
331         latency = LL_FLASH_LATENCY_2;
332       }
333       else
334       {
335         if(HCLKFrequency > UTILS_SCALE1_LATENCY1_FREQ)
336         {
337           /* 30 < HCLK <= 60 => 1WS (2 CPU cycles) */
338           latency = LL_FLASH_LATENCY_1;
339         }
340         /* else HCLKFrequency <= 10MHz default LL_FLASH_LATENCY_0 0WS */
341       }
342     }
343     /* SCALE2 */
344     else if(regulatorstatus == LL_PWR_REGU_VOLTAGE_SCALE2)
345     {
346       if(HCLKFrequency > UTILS_SCALE2_LATENCY2_FREQ)
347       {
348         /* 24 < HCLK <= 26 => 2WS (3 CPU cycles) */
349         latency = LL_FLASH_LATENCY_2;
350       }
351       else
352       {
353         if(HCLKFrequency > UTILS_SCALE2_LATENCY1_FREQ)
354         {
355           /* 12 < HCLK <= 24 => 1WS (2 CPU cycles) */
356           latency = LL_FLASH_LATENCY_1;
357         }
358         /* else HCLKFrequency <= 8MHz default LL_FLASH_LATENCY_0 0WS */
359       }
360     }
361     else
362     {
363      /* Nothing to do */
364     }
365 
366     if (status != ERROR)
367     {
368       LL_FLASH_SetLatency(latency);
369 
370       /* Check that the new number of wait states is taken into account to access the Flash
371          memory by reading the FLASH_ACR register */
372       timeout = 2U;
373       do
374       {
375         /* Wait for Flash latency to be updated */
376         getlatency = LL_FLASH_GetLatency();
377         timeout--;
378       } while ((getlatency != latency) && (timeout > 0U));
379 
380       if(getlatency != latency)
381       {
382         status = ERROR;
383       }
384     }
385   }
386 
387   return status;
388 }
389 
390 /**
391   * @brief  This function configures system clock at maximum frequency with HSI as clock source of the PLL
392   * @note   The application need to ensure that PLL is disabled.
393   * @note   Function is based on the following formula:
394   *         - PLL output frequency = (((HSI frequency / PLLM) * PLLN) / PLLR)
395   *         - PLLM: ensure that the VCO input frequency ranges from 2.66 to 8 MHz (PLLVCO_input = HSI frequency / PLLM)
396   *         - PLLN: ensure that the VCO output frequency is between 64 and 344 MHz (PLLVCO_output = PLLVCO_input * PLLN)
397   *         - PLLR: ensure that max frequency at 170000000 Hz is reach (PLLVCO_output / PLLR)
398   * @param  UTILS_PLLInitStruct pointer to a @ref LL_UTILS_PLLInitTypeDef structure that contains
399   *                             the configuration information for the PLL.
400   * @param  UTILS_ClkInitStruct pointer to a @ref LL_UTILS_ClkInitTypeDef structure that contains
401   *                             the configuration information for the BUS prescalers.
402   * @retval An ErrorStatus enumeration value:
403   *          - SUCCESS: Max frequency configuration done
404   *          - ERROR: Max frequency configuration not done
405   */
LL_PLL_ConfigSystemClock_HSI(LL_UTILS_PLLInitTypeDef * UTILS_PLLInitStruct,LL_UTILS_ClkInitTypeDef * UTILS_ClkInitStruct)406 ErrorStatus LL_PLL_ConfigSystemClock_HSI(LL_UTILS_PLLInitTypeDef *UTILS_PLLInitStruct,
407                                          LL_UTILS_ClkInitTypeDef *UTILS_ClkInitStruct)
408 {
409   ErrorStatus status;
410   uint32_t pllfreq;
411   uint32_t hpre = LL_RCC_SYSCLK_DIV_1;
412 
413   /* Check if one of the PLL is enabled */
414   if(UTILS_PLL_IsBusy() == SUCCESS)
415   {
416     /* Calculate the new PLL output frequency */
417     pllfreq = UTILS_GetPLLOutputFrequency(HSI_VALUE, UTILS_PLLInitStruct);
418 
419     /* Enable HSI if not enabled */
420     if(LL_RCC_HSI_IsReady() != 1U)
421     {
422       LL_RCC_HSI_Enable();
423       while (LL_RCC_HSI_IsReady() != 1U)
424       {
425         /* Wait for HSI ready */
426       }
427     }
428 
429     /* Configure PLL */
430     LL_RCC_PLL_ConfigDomain_SYS(LL_RCC_PLLSOURCE_HSI, UTILS_PLLInitStruct->PLLM, UTILS_PLLInitStruct->PLLN,
431                                 UTILS_PLLInitStruct->PLLR);
432 
433     /* Prevent undershoot at highest frequency by applying intermediate AHB prescaler 2 */
434     if(pllfreq > 80000000U)
435     {
436       if (UTILS_ClkInitStruct->AHBCLKDivider == LL_RCC_SYSCLK_DIV_1)
437       {
438         UTILS_ClkInitStruct->AHBCLKDivider = LL_RCC_SYSCLK_DIV_2;
439         hpre = LL_RCC_SYSCLK_DIV_2;
440       }
441     }
442 
443     /* Enable PLL and switch system clock to PLL */
444     status = UTILS_EnablePLLAndSwitchSystem(pllfreq, UTILS_ClkInitStruct);
445 
446     /* Apply definitive AHB prescaler value if necessary */
447     if ((status == SUCCESS) && (hpre != LL_RCC_SYSCLK_DIV_1))
448     {
449       /* Set FLASH latency to highest latency */
450       status = LL_SetFlashLatency(pllfreq);
451       if (status == SUCCESS)
452       {
453         UTILS_ClkInitStruct->AHBCLKDivider = LL_RCC_SYSCLK_DIV_1;
454         LL_RCC_SetAHBPrescaler(UTILS_ClkInitStruct->AHBCLKDivider);
455         LL_SetSystemCoreClock(pllfreq);
456       }
457     }
458   }
459   else
460   {
461     /* Current PLL configuration cannot be modified */
462     status = ERROR;
463   }
464 
465   return status;
466 }
467 
468 /**
469   * @brief  This function configures system clock with HSE as clock source of the PLL
470   * @note   The application need to ensure that PLL is disabled.
471   * @note   Function is based on the following formula:
472   *         - PLL output frequency = (((HSE frequency / PLLM) * PLLN) / PLLR)
473   *         - PLLM: ensure that the VCO input frequency ranges from 2.66 to 8 MHz (PLLVCO_input = HSE frequency / PLLM)
474   *         - PLLN: ensure that the VCO output frequency is between 64 and 344 MHz (PLLVCO_output = PLLVCO_input * PLLN)
475   *         - PLLR: ensure that max frequency at 170000000 Hz is reached (PLLVCO_output / PLLR)
476   * @param  HSEFrequency Value between Min_Data = 4000000 and Max_Data = 48000000
477   * @param  HSEBypass This parameter can be one of the following values:
478   *         @arg @ref LL_UTILS_HSEBYPASS_ON
479   *         @arg @ref LL_UTILS_HSEBYPASS_OFF
480   * @param  UTILS_PLLInitStruct pointer to a @ref LL_UTILS_PLLInitTypeDef structure that contains
481   *                             the configuration information for the PLL.
482   * @param  UTILS_ClkInitStruct pointer to a @ref LL_UTILS_ClkInitTypeDef structure that contains
483   *                             the configuration information for the BUS prescalers.
484   * @retval An ErrorStatus enumeration value:
485   *          - SUCCESS: Max frequency configuration done
486   *          - ERROR: Max frequency configuration not done
487   */
LL_PLL_ConfigSystemClock_HSE(uint32_t HSEFrequency,uint32_t HSEBypass,LL_UTILS_PLLInitTypeDef * UTILS_PLLInitStruct,LL_UTILS_ClkInitTypeDef * UTILS_ClkInitStruct)488 ErrorStatus LL_PLL_ConfigSystemClock_HSE(uint32_t HSEFrequency, uint32_t HSEBypass,
489                                          LL_UTILS_PLLInitTypeDef *UTILS_PLLInitStruct, LL_UTILS_ClkInitTypeDef *UTILS_ClkInitStruct)
490 {
491   ErrorStatus status;
492   uint32_t pllfreq;
493   uint32_t hpre = LL_RCC_SYSCLK_DIV_1;
494 
495   /* Check the parameters */
496   assert_param(IS_LL_UTILS_HSE_FREQUENCY(HSEFrequency));
497   assert_param(IS_LL_UTILS_HSE_BYPASS(HSEBypass));
498 
499   /* Check if one of the PLL is enabled */
500   if(UTILS_PLL_IsBusy() == SUCCESS)
501   {
502     /* Calculate the new PLL output frequency */
503     pllfreq = UTILS_GetPLLOutputFrequency(HSEFrequency, UTILS_PLLInitStruct);
504 
505     /* Enable HSE if not enabled */
506     if(LL_RCC_HSE_IsReady() != 1U)
507     {
508       /* Check if need to enable HSE bypass feature or not */
509       if(HSEBypass == LL_UTILS_HSEBYPASS_ON)
510       {
511         LL_RCC_HSE_EnableBypass();
512       }
513       else
514       {
515         LL_RCC_HSE_DisableBypass();
516       }
517 
518       /* Enable HSE */
519       LL_RCC_HSE_Enable();
520       while (LL_RCC_HSE_IsReady() != 1U)
521       {
522         /* Wait for HSE ready */
523       }
524     }
525 
526     /* Configure PLL */
527     LL_RCC_PLL_ConfigDomain_SYS(LL_RCC_PLLSOURCE_HSE, UTILS_PLLInitStruct->PLLM, UTILS_PLLInitStruct->PLLN,
528                                 UTILS_PLLInitStruct->PLLR);
529 
530     /* Prevent undershoot at highest frequency by applying intermediate AHB prescaler 2 */
531     if(pllfreq > 80000000U)
532     {
533       if (UTILS_ClkInitStruct->AHBCLKDivider == LL_RCC_SYSCLK_DIV_1)
534       {
535         UTILS_ClkInitStruct->AHBCLKDivider = LL_RCC_SYSCLK_DIV_2;
536         hpre = LL_RCC_SYSCLK_DIV_2;
537       }
538     }
539 
540     /* Enable PLL and switch system clock to PLL */
541     status = UTILS_EnablePLLAndSwitchSystem(pllfreq, UTILS_ClkInitStruct);
542 
543     /* Apply definitive AHB prescaler value if necessary */
544     if ((status == SUCCESS) && (hpre != LL_RCC_SYSCLK_DIV_1))
545     {
546       /* Set FLASH latency to highest latency */
547       status = LL_SetFlashLatency(pllfreq);
548       if (status == SUCCESS)
549       {
550         UTILS_ClkInitStruct->AHBCLKDivider = LL_RCC_SYSCLK_DIV_1;
551         LL_RCC_SetAHBPrescaler(UTILS_ClkInitStruct->AHBCLKDivider);
552         LL_SetSystemCoreClock(pllfreq);
553       }
554     }
555   }
556   else
557   {
558     /* Current PLL configuration cannot be modified */
559     status = ERROR;
560   }
561 
562   return status;
563 }
564 
565 /**
566   * @}
567   */
568 
569 /**
570   * @}
571   */
572 
573 /** @addtogroup UTILS_LL_Private_Functions
574   * @{
575   */
576 
577 /**
578   * @brief  Function to check that PLL can be modified
579   * @param  PLL_InputFrequency  PLL input frequency (in Hz)
580   * @param  UTILS_PLLInitStruct pointer to a @ref LL_UTILS_PLLInitTypeDef structure that contains
581   *                             the configuration information for the PLL.
582   * @retval PLL output frequency (in Hz)
583   */
UTILS_GetPLLOutputFrequency(uint32_t PLL_InputFrequency,LL_UTILS_PLLInitTypeDef * UTILS_PLLInitStruct)584 static uint32_t UTILS_GetPLLOutputFrequency(uint32_t PLL_InputFrequency, LL_UTILS_PLLInitTypeDef *UTILS_PLLInitStruct)
585 {
586   uint32_t pllfreq;
587 
588   /* Check the parameters */
589   assert_param(IS_LL_UTILS_PLLM_VALUE(UTILS_PLLInitStruct->PLLM));
590   assert_param(IS_LL_UTILS_PLLN_VALUE(UTILS_PLLInitStruct->PLLN));
591   assert_param(IS_LL_UTILS_PLLR_VALUE(UTILS_PLLInitStruct->PLLR));
592 
593   /* Check different PLL parameters according to RM                          */
594   /*  - PLLM: ensure that the VCO input frequency ranges from 2.66 to 8 MHz.   */
595   pllfreq = PLL_InputFrequency / (((UTILS_PLLInitStruct->PLLM >> RCC_PLLCFGR_PLLM_Pos) + 1U));
596   assert_param(IS_LL_UTILS_PLLVCO_INPUT(pllfreq));
597 
598   /*  - PLLN: ensure that the VCO output frequency is between 64 and 344 MHz.*/
599   pllfreq = pllfreq * (UTILS_PLLInitStruct->PLLN & (RCC_PLLCFGR_PLLN >> RCC_PLLCFGR_PLLN_Pos));
600   assert_param(IS_LL_UTILS_PLLVCO_OUTPUT(pllfreq));
601 
602   /*  - PLLR: ensure that max frequency at 170000000 Hz is reached                   */
603   pllfreq = pllfreq / (((UTILS_PLLInitStruct->PLLR >> RCC_PLLCFGR_PLLR_Pos) + 1U) * 2U);
604   assert_param(IS_LL_UTILS_PLL_FREQUENCY(pllfreq));
605 
606   return pllfreq;
607 }
608 
609 /**
610   * @brief  Function to check that PLL can be modified
611   * @retval An ErrorStatus enumeration value:
612   *          - SUCCESS: PLL modification can be done
613   *          - ERROR: PLL is busy
614   */
UTILS_PLL_IsBusy(void)615 static ErrorStatus UTILS_PLL_IsBusy(void)
616 {
617   ErrorStatus status = SUCCESS;
618 
619   /* Check if PLL is busy*/
620   if(LL_RCC_PLL_IsReady() != 0U)
621   {
622     /* PLL configuration cannot be modified */
623     status = ERROR;
624   }
625 
626   return status;
627 }
628 
629 /**
630   * @brief  Function to enable PLL and switch system clock to PLL
631   * @param  SYSCLK_Frequency SYSCLK frequency
632   * @param  UTILS_ClkInitStruct pointer to a @ref LL_UTILS_ClkInitTypeDef structure that contains
633   *                             the configuration information for the BUS prescalers.
634   * @retval An ErrorStatus enumeration value:
635   *          - SUCCESS: No problem to switch system to PLL
636   *          - ERROR: Problem to switch system to PLL
637   */
UTILS_EnablePLLAndSwitchSystem(uint32_t SYSCLK_Frequency,LL_UTILS_ClkInitTypeDef * UTILS_ClkInitStruct)638 static ErrorStatus UTILS_EnablePLLAndSwitchSystem(uint32_t SYSCLK_Frequency, LL_UTILS_ClkInitTypeDef *UTILS_ClkInitStruct)
639 {
640   ErrorStatus status = SUCCESS;
641   uint32_t hclk_frequency;
642 
643   assert_param(IS_LL_UTILS_SYSCLK_DIV(UTILS_ClkInitStruct->AHBCLKDivider));
644   assert_param(IS_LL_UTILS_APB1_DIV(UTILS_ClkInitStruct->APB1CLKDivider));
645   assert_param(IS_LL_UTILS_APB2_DIV(UTILS_ClkInitStruct->APB2CLKDivider));
646 
647   /* Calculate HCLK frequency */
648   hclk_frequency = __LL_RCC_CALC_HCLK_FREQ(SYSCLK_Frequency, UTILS_ClkInitStruct->AHBCLKDivider);
649 
650   /* Increasing the number of wait states because of higher CPU frequency */
651   if(SystemCoreClock < hclk_frequency)
652   {
653     /* Set FLASH latency to highest latency */
654     status = LL_SetFlashLatency(hclk_frequency);
655   }
656 
657   /* Update system clock configuration */
658   if(status == SUCCESS)
659   {
660     /* Enable PLL */
661     LL_RCC_PLL_Enable();
662     LL_RCC_PLL_EnableDomain_SYS();
663     while (LL_RCC_PLL_IsReady() != 1U)
664     {
665       /* Wait for PLL ready */
666     }
667 
668     /* Sysclk activation on the main PLL */
669     LL_RCC_SetAHBPrescaler(UTILS_ClkInitStruct->AHBCLKDivider);
670     LL_RCC_SetSysClkSource(LL_RCC_SYS_CLKSOURCE_PLL);
671     while (LL_RCC_GetSysClkSource() != LL_RCC_SYS_CLKSOURCE_STATUS_PLL)
672     {
673       /* Wait for system clock switch to PLL */
674     }
675 
676     /* Set APB1 & APB2 prescaler*/
677     LL_RCC_SetAPB1Prescaler(UTILS_ClkInitStruct->APB1CLKDivider);
678     LL_RCC_SetAPB2Prescaler(UTILS_ClkInitStruct->APB2CLKDivider);
679   }
680 
681   /* Decreasing the number of wait states because of lower CPU frequency */
682   if(SystemCoreClock > hclk_frequency)
683   {
684     /* Set FLASH latency to lowest latency */
685     status = LL_SetFlashLatency(hclk_frequency);
686   }
687 
688   /* Update SystemCoreClock variable */
689   if(status == SUCCESS)
690   {
691     LL_SetSystemCoreClock(hclk_frequency);
692   }
693 
694   return status;
695 }
696 
697 /**
698   * @}
699   */
700 
701 /**
702   * @}
703   */
704 
705 /**
706   * @}
707   */
708 
709