1 /**
2   ******************************************************************************
3   * @file    stm32f1xx_ll_utils.c
4   * @author  MCD Application Team
5   * @brief   UTILS LL module driver.
6   ******************************************************************************
7   * @attention
8   *
9   * <h2><center>&copy; Copyright (c) 2016 STMicroelectronics.
10   * All rights reserved.</center></h2>
11   *
12   * This software component is licensed by ST under BSD 3-Clause license,
13   * the "License"; You may not use this file except in compliance with the
14   * License. You may obtain a copy of the License at:
15   *                        opensource.org/licenses/BSD-3-Clause
16   *
17   ******************************************************************************
18   */
19 
20 /* Includes ------------------------------------------------------------------*/
21 #include "stm32f1xx_ll_rcc.h"
22 #include "stm32f1xx_ll_utils.h"
23 #include "stm32f1xx_ll_system.h"
24 #ifdef  USE_FULL_ASSERT
25 #include "stm32_assert.h"
26 #else
27 #define assert_param(expr) ((void)0U)
28 #endif
29 
30 /** @addtogroup STM32F1xx_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 
45 /* Defines used for PLL range */
46 #define UTILS_PLL_OUTPUT_MAX        RCC_MAX_FREQUENCY    /*!< Frequency max for PLL output, in Hz  */
47 #define UTILS_PLL2_OUTPUT_MAX       RCC_MAX_FREQUENCY    /*!< Frequency max for PLL2 output, in Hz  */
48 
49 /* Defines used for HSE range */
50 #define UTILS_HSE_FREQUENCY_MIN     RCC_HSE_MIN       /*!< Frequency min for HSE frequency, in Hz   */
51 #define UTILS_HSE_FREQUENCY_MAX     RCC_HSE_MAX       /*!< Frequency max for HSE frequency, in Hz   */
52 
53 /* Defines used for FLASH latency according to HCLK Frequency */
54 #if defined(FLASH_ACR_LATENCY)
55 #define UTILS_LATENCY1_FREQ         24000000U        /*!< SYSCLK frequency to set FLASH latency 1 */
56 #define UTILS_LATENCY2_FREQ         48000000U        /*!< SYSCLK frequency to set FLASH latency 2 */
57 #else
58 /*!< No Latency Configuration in this device */
59 #endif
60 /**
61   * @}
62   */
63 /* Private macros ------------------------------------------------------------*/
64 /** @addtogroup UTILS_LL_Private_Macros
65   * @{
66   */
67 #define IS_LL_UTILS_SYSCLK_DIV(__VALUE__) (((__VALUE__) == LL_RCC_SYSCLK_DIV_1)   \
68                                         || ((__VALUE__) == LL_RCC_SYSCLK_DIV_2)   \
69                                         || ((__VALUE__) == LL_RCC_SYSCLK_DIV_4)   \
70                                         || ((__VALUE__) == LL_RCC_SYSCLK_DIV_8)   \
71                                         || ((__VALUE__) == LL_RCC_SYSCLK_DIV_16)  \
72                                         || ((__VALUE__) == LL_RCC_SYSCLK_DIV_64)  \
73                                         || ((__VALUE__) == LL_RCC_SYSCLK_DIV_128) \
74                                         || ((__VALUE__) == LL_RCC_SYSCLK_DIV_256) \
75                                         || ((__VALUE__) == LL_RCC_SYSCLK_DIV_512))
76 
77 #define IS_LL_UTILS_APB1_DIV(__VALUE__) (((__VALUE__) == LL_RCC_APB1_DIV_1) \
78                                       || ((__VALUE__) == LL_RCC_APB1_DIV_2) \
79                                       || ((__VALUE__) == LL_RCC_APB1_DIV_4) \
80                                       || ((__VALUE__) == LL_RCC_APB1_DIV_8) \
81                                       || ((__VALUE__) == LL_RCC_APB1_DIV_16))
82 
83 #define IS_LL_UTILS_APB2_DIV(__VALUE__) (((__VALUE__) == LL_RCC_APB2_DIV_1) \
84                                       || ((__VALUE__) == LL_RCC_APB2_DIV_2) \
85                                       || ((__VALUE__) == LL_RCC_APB2_DIV_4) \
86                                       || ((__VALUE__) == LL_RCC_APB2_DIV_8) \
87                                       || ((__VALUE__) == LL_RCC_APB2_DIV_16))
88 
89 #if defined(RCC_CFGR_PLLMULL6_5)
90 #define IS_LL_UTILS_PLLMUL_VALUE(__VALUE__) (((__VALUE__) == LL_RCC_PLL_MUL_4) \
91                                           || ((__VALUE__) == LL_RCC_PLL_MUL_5) \
92                                           || ((__VALUE__) == LL_RCC_PLL_MUL_6) \
93                                           || ((__VALUE__) == LL_RCC_PLL_MUL_7) \
94                                           || ((__VALUE__) == LL_RCC_PLL_MUL_8) \
95                                           || ((__VALUE__) == LL_RCC_PLL_MUL_9) \
96                                           || ((__VALUE__) == LL_RCC_PLL_MUL_6_5))
97 #else
98 #define IS_LL_UTILS_PLLMUL_VALUE(__VALUE__) (((__VALUE__) == LL_RCC_PLL_MUL_2) \
99                                           || ((__VALUE__) == LL_RCC_PLL_MUL_3) \
100                                           || ((__VALUE__) == LL_RCC_PLL_MUL_4) \
101                                           || ((__VALUE__) == LL_RCC_PLL_MUL_5) \
102                                           || ((__VALUE__) == LL_RCC_PLL_MUL_6) \
103                                           || ((__VALUE__) == LL_RCC_PLL_MUL_7) \
104                                           || ((__VALUE__) == LL_RCC_PLL_MUL_8) \
105                                           || ((__VALUE__) == LL_RCC_PLL_MUL_9) \
106                                           || ((__VALUE__) == LL_RCC_PLL_MUL_10) \
107                                           || ((__VALUE__) == LL_RCC_PLL_MUL_11) \
108                                           || ((__VALUE__) == LL_RCC_PLL_MUL_12) \
109                                           || ((__VALUE__) == LL_RCC_PLL_MUL_13) \
110                                           || ((__VALUE__) == LL_RCC_PLL_MUL_14) \
111                                           || ((__VALUE__) == LL_RCC_PLL_MUL_15) \
112                                           || ((__VALUE__) == LL_RCC_PLL_MUL_16))
113 #endif /* RCC_CFGR_PLLMULL6_5 */
114 
115 #if defined(RCC_CFGR2_PREDIV1)
116 #define IS_LL_UTILS_PREDIV_VALUE(__VALUE__) (((__VALUE__) == LL_RCC_PREDIV_DIV_1)  || ((__VALUE__) == LL_RCC_PREDIV_DIV_2)   || \
117                                              ((__VALUE__) == LL_RCC_PREDIV_DIV_3)  || ((__VALUE__) == LL_RCC_PREDIV_DIV_4)   || \
118                                              ((__VALUE__) == LL_RCC_PREDIV_DIV_5)  || ((__VALUE__) == LL_RCC_PREDIV_DIV_6)   || \
119                                              ((__VALUE__) == LL_RCC_PREDIV_DIV_7)  || ((__VALUE__) == LL_RCC_PREDIV_DIV_8)   || \
120                                              ((__VALUE__) == LL_RCC_PREDIV_DIV_9)  || ((__VALUE__) == LL_RCC_PREDIV_DIV_10)  || \
121                                              ((__VALUE__) == LL_RCC_PREDIV_DIV_11) || ((__VALUE__) == LL_RCC_PREDIV_DIV_12)  || \
122                                              ((__VALUE__) == LL_RCC_PREDIV_DIV_13) || ((__VALUE__) == LL_RCC_PREDIV_DIV_14)  || \
123                                              ((__VALUE__) == LL_RCC_PREDIV_DIV_15) || ((__VALUE__) == LL_RCC_PREDIV_DIV_16))
124 #else
125 #define IS_LL_UTILS_PREDIV_VALUE(__VALUE__) (((__VALUE__) == LL_RCC_PREDIV_DIV_1)  || ((__VALUE__) == LL_RCC_PREDIV_DIV_2))
126 #endif /*RCC_PREDIV1_DIV_2_16_SUPPORT*/
127 
128 #define IS_LL_UTILS_PLL_FREQUENCY(__VALUE__) ((__VALUE__) <= UTILS_PLL_OUTPUT_MAX)
129 
130 #if defined(RCC_PLL2_SUPPORT)
131 #define IS_LL_UTILS_PLL2MUL_VALUE(__VALUE__) (((__VALUE__) == LL_RCC_PLL2_MUL_8) \
132                                            || ((__VALUE__) == LL_RCC_PLL2_MUL_9) \
133                                            || ((__VALUE__) == LL_RCC_PLL2_MUL_10) \
134                                            || ((__VALUE__) == LL_RCC_PLL2_MUL_11) \
135                                            || ((__VALUE__) == LL_RCC_PLL2_MUL_12) \
136                                            || ((__VALUE__) == LL_RCC_PLL2_MUL_13) \
137                                            || ((__VALUE__) == LL_RCC_PLL2_MUL_14) \
138                                            || ((__VALUE__) == LL_RCC_PLL2_MUL_16) \
139                                            || ((__VALUE__) == LL_RCC_PLL2_MUL_20))
140 
141 #define IS_LL_UTILS_PREDIV2_VALUE(__VALUE__) (((__VALUE__) == LL_RCC_HSE_PREDIV2_DIV_1)  || ((__VALUE__) == LL_RCC_HSE_PREDIV2_DIV_2)   || \
142                                               ((__VALUE__) == LL_RCC_HSE_PREDIV2_DIV_3)  || ((__VALUE__) == LL_RCC_HSE_PREDIV2_DIV_4)   || \
143                                               ((__VALUE__) == LL_RCC_HSE_PREDIV2_DIV_5)  || ((__VALUE__) == LL_RCC_HSE_PREDIV2_DIV_6)   || \
144                                               ((__VALUE__) == LL_RCC_HSE_PREDIV2_DIV_7)  || ((__VALUE__) == LL_RCC_HSE_PREDIV2_DIV_8)   || \
145                                               ((__VALUE__) == LL_RCC_HSE_PREDIV2_DIV_9)  || ((__VALUE__) == LL_RCC_HSE_PREDIV2_DIV_10)  || \
146                                               ((__VALUE__) == LL_RCC_HSE_PREDIV2_DIV_11) || ((__VALUE__) == LL_RCC_HSE_PREDIV2_DIV_12)  || \
147                                               ((__VALUE__) == LL_RCC_HSE_PREDIV2_DIV_13) || ((__VALUE__) == LL_RCC_HSE_PREDIV2_DIV_14)  || \
148                                               ((__VALUE__) == LL_RCC_HSE_PREDIV2_DIV_15) || ((__VALUE__) == LL_RCC_HSE_PREDIV2_DIV_16))
149 
150 #define IS_LL_UTILS_PLL2_FREQUENCY(__VALUE__) ((__VALUE__) <= UTILS_PLL2_OUTPUT_MAX)
151 #endif /* RCC_PLL2_SUPPORT */
152 
153 #define IS_LL_UTILS_HSE_BYPASS(__STATE__) (((__STATE__) == LL_UTILS_HSEBYPASS_ON) \
154                                         || ((__STATE__) == LL_UTILS_HSEBYPASS_OFF))
155 
156 #define IS_LL_UTILS_HSE_FREQUENCY(__FREQUENCY__) (((__FREQUENCY__) >= UTILS_HSE_FREQUENCY_MIN) && ((__FREQUENCY__) <= UTILS_HSE_FREQUENCY_MAX))
157 /**
158   * @}
159   */
160 /* Private function prototypes -----------------------------------------------*/
161 /** @defgroup UTILS_LL_Private_Functions UTILS Private functions
162   * @{
163   */
164 static uint32_t    UTILS_GetPLLOutputFrequency(uint32_t PLL_InputFrequency,
165                                                LL_UTILS_PLLInitTypeDef *UTILS_PLLInitStruct);
166 static ErrorStatus UTILS_PLL_HSE_ConfigSystemClock(uint32_t PLL_InputFrequency, uint32_t HSEBypass,
167                                                    LL_UTILS_PLLInitTypeDef *UTILS_PLLInitStruct,
168                                                    LL_UTILS_ClkInitTypeDef *UTILS_ClkInitStruct);
169 #if defined(RCC_PLL2_SUPPORT)
170 static uint32_t    UTILS_GetPLL2OutputFrequency(uint32_t PLL2_InputFrequency,
171                                                 LL_UTILS_PLLInitTypeDef *UTILS_PLL2InitStruct);
172 #endif /* RCC_PLL2_SUPPORT */
173 static ErrorStatus UTILS_EnablePLLAndSwitchSystem(uint32_t SYSCLK_Frequency, LL_UTILS_ClkInitTypeDef *UTILS_ClkInitStruct);
174 static ErrorStatus UTILS_PLL_IsBusy(void);
175 /**
176   * @}
177   */
178 
179 /* Exported functions --------------------------------------------------------*/
180 /** @addtogroup UTILS_LL_Exported_Functions
181   * @{
182   */
183 
184 /** @addtogroup UTILS_LL_EF_DELAY
185   * @{
186   */
187 
188 /**
189   * @brief  This function configures the Cortex-M SysTick source to have 1ms time base.
190   * @note   When a RTOS is used, it is recommended to avoid changing the Systick
191   *         configuration by calling this function, for a delay use rather osDelay RTOS service.
192   * @param  HCLKFrequency HCLK frequency in Hz
193   * @note   HCLK frequency can be calculated thanks to RCC helper macro or function @ref LL_RCC_GetSystemClocksFreq
194   * @retval None
195   */
LL_Init1msTick(uint32_t HCLKFrequency)196 void LL_Init1msTick(uint32_t HCLKFrequency)
197 {
198   /* Use frequency provided in argument */
199   LL_InitTick(HCLKFrequency, 1000U);
200 }
201 
202 /**
203   * @brief  This function provides accurate delay (in milliseconds) based
204   *         on SysTick counter flag
205   * @note   When a RTOS is used, it is recommended to avoid using blocking delay
206   *         and use rather osDelay service.
207   * @note   To respect 1ms timebase, user should call @ref LL_Init1msTick function which
208   *         will configure Systick to 1ms
209   * @param  Delay specifies the delay time length, in milliseconds.
210   * @retval None
211   */
LL_mDelay(uint32_t Delay)212 void LL_mDelay(uint32_t Delay)
213 {
214   __IO uint32_t  tmp = SysTick->CTRL;  /* Clear the COUNTFLAG first */
215   /* Add this code to indicate that local variable is not used */
216   ((void)tmp);
217 
218   /* Add a period to guaranty minimum wait */
219   if (Delay < LL_MAX_DELAY)
220   {
221     Delay++;
222   }
223 
224   while (Delay)
225   {
226     if ((SysTick->CTRL & SysTick_CTRL_COUNTFLAG_Msk) != 0U)
227     {
228       Delay--;
229     }
230   }
231 }
232 
233 /**
234   * @}
235   */
236 
237 /** @addtogroup UTILS_EF_SYSTEM
238   *  @brief    System Configuration functions
239   *
240   @verbatim
241  ===============================================================================
242            ##### System Configuration functions #####
243  ===============================================================================
244     [..]
245          System, AHB and APB buses clocks configuration
246 
247          (+) The maximum frequency of the SYSCLK, HCLK, PCLK1 and PCLK2 is RCC_MAX_FREQUENCY Hz.
248   @endverbatim
249   @internal
250              Depending on the SYSCLK frequency, the flash latency should be adapted accordingly:
251              (++) +-----------------------------------------------+
252              (++) | Latency       | SYSCLK clock frequency (MHz)  |
253              (++) |---------------|-------------------------------|
254              (++) |0WS(1CPU cycle)|       0 < SYSCLK <= 24        |
255              (++) |---------------|-------------------------------|
256              (++) |1WS(2CPU cycle)|      24 < SYSCLK <= 48        |
257              (++) |---------------|-------------------------------|
258              (++) |2WS(3CPU cycle)|      48 < SYSCLK <= 72        |
259              (++) +-----------------------------------------------+
260   @endinternal
261   * @{
262   */
263 
264 /**
265   * @brief  This function sets directly SystemCoreClock CMSIS variable.
266   * @note   Variable can be calculated also through SystemCoreClockUpdate function.
267   * @param  HCLKFrequency HCLK frequency in Hz (can be calculated thanks to RCC helper macro)
268   * @retval None
269   */
LL_SetSystemCoreClock(uint32_t HCLKFrequency)270 void LL_SetSystemCoreClock(uint32_t HCLKFrequency)
271 {
272   /* HCLK clock frequency */
273   SystemCoreClock = HCLKFrequency;
274 }
275 
276 /**
277   * @brief  Update number of Flash wait states in line with new frequency and current
278             voltage range.
279   * @param  Frequency  SYSCLK frequency
280   * @retval An ErrorStatus enumeration value:
281   *          - SUCCESS: Latency has been modified
282   *          - ERROR: Latency cannot be modified
283   */
284 #if defined(FLASH_ACR_LATENCY)
LL_SetFlashLatency(uint32_t Frequency)285 ErrorStatus LL_SetFlashLatency(uint32_t Frequency)
286 {
287   uint32_t timeout;
288   uint32_t getlatency;
289   uint32_t latency = LL_FLASH_LATENCY_0; /* default value 0WS */
290   ErrorStatus status = SUCCESS;
291 
292   /* Frequency cannot be equal to 0 */
293   if (Frequency == 0U)
294   {
295     status = ERROR;
296   }
297   else
298   {
299     if (Frequency > UTILS_LATENCY2_FREQ)
300     {
301       /* 48 < SYSCLK <= 72 => 2WS (3 CPU cycles) */
302       latency = LL_FLASH_LATENCY_2;
303     }
304     else
305     {
306       if (Frequency > UTILS_LATENCY1_FREQ)
307       {
308         /* 24 < SYSCLK <= 48 => 1WS (2 CPU cycles) */
309         latency = LL_FLASH_LATENCY_1;
310       }
311       else
312       {
313         /* else SYSCLK < 24MHz default LL_FLASH_LATENCY_0 0WS */
314         latency = LL_FLASH_LATENCY_0;
315       }
316     }
317 
318     if (status != ERROR)
319     {
320       LL_FLASH_SetLatency(latency);
321 
322       /* Check that the new number of wait states is taken into account to access the Flash
323          memory by reading the FLASH_ACR register */
324       timeout = 2;
325       do
326       {
327         /* Wait for Flash latency to be updated */
328         getlatency = LL_FLASH_GetLatency();
329         timeout--;
330       }
331       while ((getlatency != latency) && (timeout > 0));
332 
333       if (getlatency != latency)
334       {
335         status = ERROR;
336       }
337       else
338       {
339         status = SUCCESS;
340       }
341     }
342   }
343 
344   return status;
345 }
346 #endif /* FLASH_ACR_LATENCY */
347 
348 /**
349   * @brief  This function configures system clock with HSI as clock source of the PLL
350   * @note   The application need to ensure that PLL is disabled.
351   * @note   Function is based on the following formula:
352   *         - PLL output frequency = ((HSI frequency / PREDIV) * PLLMUL)
353   *         - PREDIV: Set to 2 for few devices
354   *         - PLLMUL: The application software must set correctly the PLL multiplication factor to
355   *                   not exceed 72MHz
356   * @note   FLASH latency can be modified through this function.
357   * @param  UTILS_PLLInitStruct pointer to a @ref LL_UTILS_PLLInitTypeDef structure that contains
358   *                             the configuration information for the PLL.
359   * @param  UTILS_ClkInitStruct pointer to a @ref LL_UTILS_ClkInitTypeDef structure that contains
360   *                             the configuration information for the BUS prescalers.
361   * @retval An ErrorStatus enumeration value:
362   *          - SUCCESS: Max frequency configuration done
363   *          - ERROR: Max frequency configuration not done
364   */
LL_PLL_ConfigSystemClock_HSI(LL_UTILS_PLLInitTypeDef * UTILS_PLLInitStruct,LL_UTILS_ClkInitTypeDef * UTILS_ClkInitStruct)365 ErrorStatus LL_PLL_ConfigSystemClock_HSI(LL_UTILS_PLLInitTypeDef *UTILS_PLLInitStruct,
366                                          LL_UTILS_ClkInitTypeDef *UTILS_ClkInitStruct)
367 {
368   ErrorStatus status = SUCCESS;
369   uint32_t pllfreq = 0U;
370 
371   /* Check if one of the PLL is enabled */
372   if (UTILS_PLL_IsBusy() == SUCCESS)
373   {
374 #if defined(RCC_PLLSRC_PREDIV1_SUPPORT)
375     /* Check PREDIV value */
376     assert_param(IS_LL_UTILS_PREDIV_VALUE(UTILS_PLLInitStruct->PLLDiv));
377 #else
378     /* Force PREDIV value to 2 */
379     UTILS_PLLInitStruct->Prediv = LL_RCC_PREDIV_DIV_2;
380 #endif /*RCC_PLLSRC_PREDIV1_SUPPORT*/
381     /* Calculate the new PLL output frequency */
382     pllfreq = UTILS_GetPLLOutputFrequency(HSI_VALUE, UTILS_PLLInitStruct);
383 
384     /* Enable HSI if not enabled */
385     if (LL_RCC_HSI_IsReady() != 1U)
386     {
387       LL_RCC_HSI_Enable();
388       while (LL_RCC_HSI_IsReady() != 1U)
389       {
390         /* Wait for HSI ready */
391       }
392     }
393 
394     /* Configure PLL */
395     LL_RCC_PLL_ConfigDomain_SYS(LL_RCC_PLLSOURCE_HSI_DIV_2, UTILS_PLLInitStruct->PLLMul);
396 
397     /* Enable PLL and switch system clock to PLL */
398     status = UTILS_EnablePLLAndSwitchSystem(pllfreq, UTILS_ClkInitStruct);
399   }
400   else
401   {
402     /* Current PLL configuration cannot be modified */
403     status = ERROR;
404   }
405 
406   return status;
407 }
408 
409 /**
410   * @brief  This function configures system clock with HSE as clock source of the PLL
411   * @note   The application need to ensure that PLL is disabled.
412   * @note   Function is based on the following formula:
413   *         - PLL output frequency = ((HSI frequency / PREDIV) * PLLMUL)
414   *         - PREDIV: Set to 2 for few devices
415   *         - PLLMUL: The application software must set correctly the PLL multiplication factor to
416   *                   not exceed @ref UTILS_PLL_OUTPUT_MAX
417   * @note   FLASH latency can be modified through this function.
418   * @param  HSEFrequency Value between Min_Data = RCC_HSE_MIN and Max_Data = RCC_HSE_MAX
419   * @param  HSEBypass This parameter can be one of the following values:
420   *         @arg @ref LL_UTILS_HSEBYPASS_ON
421   *         @arg @ref LL_UTILS_HSEBYPASS_OFF
422   * @param  UTILS_PLLInitStruct pointer to a @ref LL_UTILS_PLLInitTypeDef structure that contains
423   *                             the configuration information for the PLL.
424   * @param  UTILS_ClkInitStruct pointer to a @ref LL_UTILS_ClkInitTypeDef structure that contains
425   *                             the configuration information for the BUS prescalers.
426   * @retval An ErrorStatus enumeration value:
427   *          - SUCCESS: Max frequency configuration done
428   *          - ERROR: Max frequency configuration not done
429   */
LL_PLL_ConfigSystemClock_HSE(uint32_t HSEFrequency,uint32_t HSEBypass,LL_UTILS_PLLInitTypeDef * UTILS_PLLInitStruct,LL_UTILS_ClkInitTypeDef * UTILS_ClkInitStruct)430 ErrorStatus LL_PLL_ConfigSystemClock_HSE(uint32_t HSEFrequency, uint32_t HSEBypass,
431                                          LL_UTILS_PLLInitTypeDef *UTILS_PLLInitStruct, LL_UTILS_ClkInitTypeDef *UTILS_ClkInitStruct)
432 {
433   ErrorStatus status = SUCCESS;
434   uint32_t pllfrequency = 0U;
435 
436   /* Check the parameters */
437   assert_param(IS_LL_UTILS_HSE_FREQUENCY(HSEFrequency));
438   assert_param(IS_LL_UTILS_HSE_BYPASS(HSEBypass));
439   assert_param(IS_LL_UTILS_PREDIV_VALUE(UTILS_PLLInitStruct->Prediv));
440 
441   /* Calculate the new PLL output frequency */
442   pllfrequency = UTILS_GetPLLOutputFrequency(HSEFrequency, UTILS_PLLInitStruct);
443 
444   /* Enable HSE if not enabled */
445   status = UTILS_PLL_HSE_ConfigSystemClock(HSEFrequency, HSEBypass, UTILS_PLLInitStruct, UTILS_ClkInitStruct);
446 
447   /* Check if HSE is not enabled*/
448   if (status == SUCCESS)
449   {
450     /* Configure PLL */
451     LL_RCC_PLL_ConfigDomain_SYS((LL_RCC_PLLSOURCE_HSE | UTILS_PLLInitStruct->Prediv), UTILS_PLLInitStruct->PLLMul);
452 
453     /* Enable PLL and switch system clock to PLL */
454     status = UTILS_EnablePLLAndSwitchSystem(pllfrequency, UTILS_ClkInitStruct);
455   }
456 
457   return status;
458 }
459 
460 #if defined(RCC_PLL2_SUPPORT)
461 /**
462   * @brief  This function configures system clock with HSE as clock source of the PLL, via PLL2
463   * @note   The application need to ensure that PLL and PLL2 are disabled.
464   * @note   Function is based on the following formula:
465   *         - PLL output frequency = ((((HSE frequency / PREDIV2) * PLL2MUL) / PREDIV) * PLLMUL)
466   *         - PREDIV, PLLMUL, PREDIV2, PLL2MUL: The application software must set correctly the
467   *                   PLL multiplication factor to not exceed @ref UTILS_PLL_OUTPUT_MAX
468   * @note   FLASH latency can be modified through this function.
469   * @param  HSEFrequency Value between Min_Data = RCC_HSE_MIN and Max_Data = RCC_HSE_MAX
470   * @param  HSEBypass This parameter can be one of the following values:
471   *         @arg @ref LL_UTILS_HSEBYPASS_ON
472   *         @arg @ref LL_UTILS_HSEBYPASS_OFF
473   * @param  UTILS_PLLInitStruct  pointer to a @ref LL_UTILS_PLLInitTypeDef structure that contains
474   *                              the configuration information for the PLL.
475   * @param  UTILS_PLL2InitStruct pointer to a @ref LL_UTILS_PLLInitTypeDef structure that contains
476   *                              the configuration information for the PLL2.
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_PLL2(uint32_t HSEFrequency,uint32_t HSEBypass,LL_UTILS_PLLInitTypeDef * UTILS_PLLInitStruct,LL_UTILS_PLLInitTypeDef * UTILS_PLL2InitStruct,LL_UTILS_ClkInitTypeDef * UTILS_ClkInitStruct)483 ErrorStatus LL_PLL_ConfigSystemClock_PLL2(uint32_t HSEFrequency, uint32_t HSEBypass,
484                                           LL_UTILS_PLLInitTypeDef *UTILS_PLLInitStruct,
485                                           LL_UTILS_PLLInitTypeDef *UTILS_PLL2InitStruct,
486                                           LL_UTILS_ClkInitTypeDef *UTILS_ClkInitStruct)
487 {
488   ErrorStatus status = SUCCESS;
489   uint32_t pllfrequency = 0U;
490 
491   /* Check the parameters */
492   assert_param(IS_LL_UTILS_HSE_FREQUENCY(HSEFrequency));
493   assert_param(IS_LL_UTILS_HSE_BYPASS(HSEBypass));
494   assert_param(IS_LL_UTILS_PREDIV_VALUE(UTILS_PLLInitStruct->Prediv));
495   assert_param(IS_LL_UTILS_PREDIV2_VALUE(UTILS_PLL2InitStruct->Prediv));
496 
497   /* Calculate the new PLL output frequency */
498   pllfrequency = UTILS_GetPLLOutputFrequency(HSEFrequency, UTILS_PLLInitStruct);
499 
500   /* Enable HSE if not enabled */
501   status = UTILS_PLL_HSE_ConfigSystemClock(HSEFrequency, HSEBypass, UTILS_PLLInitStruct, UTILS_ClkInitStruct);
502 
503   /* Check if HSE is not enabled*/
504   if (status == SUCCESS)
505   {
506     /* Configure PLL */
507     LL_RCC_PLL_ConfigDomain_PLL2(UTILS_PLL2InitStruct->Prediv, UTILS_PLL2InitStruct->PLLMul);
508     LL_RCC_PLL_ConfigDomain_SYS((LL_RCC_PLLSOURCE_PLL2 | UTILS_PLLInitStruct->Prediv), UTILS_PLLInitStruct->PLLMul);
509 
510     /* Calculate the new PLL output frequency */
511     pllfrequency  = UTILS_GetPLL2OutputFrequency(pllfrequency, UTILS_PLL2InitStruct);
512 
513     /* Enable PLL and switch system clock to PLL */
514     status = UTILS_EnablePLLAndSwitchSystem(pllfrequency, UTILS_ClkInitStruct);
515   }
516 
517   return status;
518 }
519 #endif /* RCC_PLL2_SUPPORT */
520 
521 /**
522   * @}
523   */
524 
525 /**
526   * @}
527   */
528 
529 /** @addtogroup UTILS_LL_Private_Functions
530   * @{
531   */
532 /**
533   * @brief  Function to check that PLL can be modified
534   * @param  PLL_InputFrequency  PLL input frequency (in Hz)
535   * @param  UTILS_PLLInitStruct pointer to a @ref LL_UTILS_PLLInitTypeDef structure that contains
536   *                             the configuration information for the PLL.
537   * @retval PLL output frequency (in Hz)
538   */
UTILS_GetPLLOutputFrequency(uint32_t PLL_InputFrequency,LL_UTILS_PLLInitTypeDef * UTILS_PLLInitStruct)539 static uint32_t UTILS_GetPLLOutputFrequency(uint32_t PLL_InputFrequency, LL_UTILS_PLLInitTypeDef *UTILS_PLLInitStruct)
540 {
541   uint32_t pllfreq = 0U;
542 
543   /* Check the parameters */
544   assert_param(IS_LL_UTILS_PLLMUL_VALUE(UTILS_PLLInitStruct->PLLMul));
545 
546   /* Check different PLL parameters according to RM                          */
547 #if defined (RCC_CFGR2_PREDIV1)
548   pllfreq = __LL_RCC_CALC_PLLCLK_FREQ(PLL_InputFrequency / (UTILS_PLLInitStruct->Prediv + 1U), UTILS_PLLInitStruct->PLLMul);
549 #else
550   pllfreq = __LL_RCC_CALC_PLLCLK_FREQ(PLL_InputFrequency / ((UTILS_PLLInitStruct->Prediv >> RCC_CFGR_PLLXTPRE_Pos) + 1U), UTILS_PLLInitStruct->PLLMul);
551 #endif /*RCC_CFGR2_PREDIV1SRC*/
552   assert_param(IS_LL_UTILS_PLL_FREQUENCY(pllfreq));
553 
554   return pllfreq;
555 }
556 
557 /**
558   * @brief  This function enable the HSE when it is used by PLL or PLL2
559   * @note   The application need to ensure that PLL is disabled.
560   * @param  HSEFrequency Value between Min_Data = RCC_HSE_MIN and Max_Data = RCC_HSE_MAX
561   * @param  HSEBypass This parameter can be one of the following values:
562   *         @arg @ref LL_UTILS_HSEBYPASS_ON
563   *         @arg @ref LL_UTILS_HSEBYPASS_OFF
564   * @param  UTILS_PLLInitStruct pointer to a @ref LL_UTILS_PLLInitTypeDef structure that contains
565   *                             the configuration information for the PLL.
566   * @param  UTILS_ClkInitStruct pointer to a @ref LL_UTILS_ClkInitTypeDef structure that contains
567   *                             the configuration information for the BUS prescalers.
568   * @retval An ErrorStatus enumeration value:
569   *          - SUCCESS: HSE configuration done
570   *          - ERROR: HSE configuration not done
571   */
UTILS_PLL_HSE_ConfigSystemClock(uint32_t PLL_InputFrequency,uint32_t HSEBypass,LL_UTILS_PLLInitTypeDef * UTILS_PLLInitStruct,LL_UTILS_ClkInitTypeDef * UTILS_ClkInitStruct)572 static ErrorStatus UTILS_PLL_HSE_ConfigSystemClock(uint32_t PLL_InputFrequency, uint32_t HSEBypass,
573                                                    LL_UTILS_PLLInitTypeDef *UTILS_PLLInitStruct,
574                                                    LL_UTILS_ClkInitTypeDef *UTILS_ClkInitStruct)
575 {
576   ErrorStatus status = SUCCESS;
577 
578   /* Check if one of the PLL is enabled */
579   if (UTILS_PLL_IsBusy() == SUCCESS)
580   {
581     /* Enable HSE if not enabled */
582     if (LL_RCC_HSE_IsReady() != 1U)
583     {
584       /* Check if need to enable HSE bypass feature or not */
585       if (HSEBypass == LL_UTILS_HSEBYPASS_ON)
586       {
587         LL_RCC_HSE_EnableBypass();
588       }
589       else
590       {
591         LL_RCC_HSE_DisableBypass();
592       }
593 
594       /* Enable HSE */
595       LL_RCC_HSE_Enable();
596       while (LL_RCC_HSE_IsReady() != 1U)
597       {
598         /* Wait for HSE ready */
599       }
600     }
601   }
602   else
603   {
604     /* Current PLL configuration cannot be modified */
605     status = ERROR;
606   }
607 
608   return status;
609 }
610 
611 #if defined(RCC_PLL2_SUPPORT)
612 /**
613   * @brief  Function to check that PLL2 can be modified
614   * @param  PLL2_InputFrequency  PLL2 input frequency (in Hz)
615   * @param  UTILS_PLL2InitStruct pointer to a @ref LL_UTILS_PLLInitTypeDef structure that contains
616   *                              the configuration information for the PLL.
617   * @retval PLL2 output frequency (in Hz)
618   */
UTILS_GetPLL2OutputFrequency(uint32_t PLL2_InputFrequency,LL_UTILS_PLLInitTypeDef * UTILS_PLL2InitStruct)619 static uint32_t UTILS_GetPLL2OutputFrequency(uint32_t PLL2_InputFrequency, LL_UTILS_PLLInitTypeDef *UTILS_PLL2InitStruct)
620 {
621   uint32_t pll2freq = 0U;
622 
623   /* Check the parameters */
624   assert_param(IS_LL_UTILS_PLL2MUL_VALUE(UTILS_PLL2InitStruct->PLLMul));
625   assert_param(IS_LL_UTILS_PREDIV2_VALUE(UTILS_PLL2InitStruct->Prediv));
626 
627   /* Check different PLL2 parameters according to RM */
628   pll2freq = __LL_RCC_CALC_PLL2CLK_FREQ(PLL2_InputFrequency, UTILS_PLL2InitStruct->PLLMul, UTILS_PLL2InitStruct->Prediv);
629   assert_param(IS_LL_UTILS_PLL2_FREQUENCY(pll2freq));
630 
631   return pll2freq;
632 }
633 #endif /* RCC_PLL2_SUPPORT */
634 
635 /**
636   * @brief  Function to check that PLL can be modified
637   * @retval An ErrorStatus enumeration value:
638   *          - SUCCESS: PLL modification can be done
639   *          - ERROR: PLL is busy
640   */
UTILS_PLL_IsBusy(void)641 static ErrorStatus UTILS_PLL_IsBusy(void)
642 {
643   ErrorStatus status = SUCCESS;
644 
645   /* Check if PLL is busy*/
646   if (LL_RCC_PLL_IsReady() != 0U)
647   {
648     /* PLL configuration cannot be modified */
649     status = ERROR;
650   }
651 #if defined(RCC_PLL2_SUPPORT)
652   /* Check if PLL2 is busy*/
653   if (LL_RCC_PLL2_IsReady() != 0U)
654   {
655     /* PLL2 configuration cannot be modified */
656     status = ERROR;
657   }
658 #endif /* RCC_PLL2_SUPPORT */
659 
660 #if defined(RCC_PLLI2S_SUPPORT)
661   /* Check if PLLI2S  is busy*/
662   if (LL_RCC_PLLI2S_IsReady() != 0U)
663   {
664     /* PLLI2S configuration cannot be modified */
665     status = ERROR;
666   }
667 #endif /* RCC_PLLI2S_SUPPORT */
668 
669   return status;
670 }
671 
672 /**
673   * @brief  Function to enable PLL and switch system clock to PLL
674   * @param  SYSCLK_Frequency SYSCLK frequency
675   * @param  UTILS_ClkInitStruct pointer to a @ref LL_UTILS_ClkInitTypeDef structure that contains
676   *                             the configuration information for the BUS prescalers.
677   * @retval An ErrorStatus enumeration value:
678   *          - SUCCESS: No problem to switch system to PLL
679   *          - ERROR: Problem to switch system to PLL
680   */
UTILS_EnablePLLAndSwitchSystem(uint32_t SYSCLK_Frequency,LL_UTILS_ClkInitTypeDef * UTILS_ClkInitStruct)681 static ErrorStatus UTILS_EnablePLLAndSwitchSystem(uint32_t SYSCLK_Frequency, LL_UTILS_ClkInitTypeDef *UTILS_ClkInitStruct)
682 {
683   ErrorStatus status = SUCCESS;
684 #if defined(FLASH_ACR_LATENCY)
685   uint32_t sysclk_frequency_current = 0U;
686 #endif /* FLASH_ACR_LATENCY */
687 
688   assert_param(IS_LL_UTILS_SYSCLK_DIV(UTILS_ClkInitStruct->AHBCLKDivider));
689   assert_param(IS_LL_UTILS_APB1_DIV(UTILS_ClkInitStruct->APB1CLKDivider));
690   assert_param(IS_LL_UTILS_APB2_DIV(UTILS_ClkInitStruct->APB2CLKDivider));
691 
692 #if defined(FLASH_ACR_LATENCY)
693   /* Calculate current SYSCLK frequency */
694   sysclk_frequency_current = (SystemCoreClock << AHBPrescTable[LL_RCC_GetAHBPrescaler() >> RCC_CFGR_HPRE_Pos]);
695 #endif /* FLASH_ACR_LATENCY */
696 
697   /* Increasing the number of wait states because of higher CPU frequency */
698 #if defined (FLASH_ACR_LATENCY)
699   if (sysclk_frequency_current < SYSCLK_Frequency)
700   {
701     /* Set FLASH latency to highest latency */
702     status = LL_SetFlashLatency(SYSCLK_Frequency);
703   }
704 #endif /* FLASH_ACR_LATENCY */
705 
706   /* Update system clock configuration */
707   if (status == SUCCESS)
708   {
709 #if defined(RCC_PLL2_SUPPORT)
710     if (LL_RCC_PLL_GetMainSource() != LL_RCC_PLLSOURCE_HSI_DIV_2)
711     {
712       /* Enable PLL2 */
713       LL_RCC_PLL2_Enable();
714       while (LL_RCC_PLL2_IsReady() != 1U)
715       {
716         /* Wait for PLL2 ready */
717       }
718     }
719 #endif /* RCC_PLL2_SUPPORT */
720     /* Enable PLL */
721     LL_RCC_PLL_Enable();
722     while (LL_RCC_PLL_IsReady() != 1U)
723     {
724       /* Wait for PLL ready */
725     }
726 
727     /* Sysclk activation on the main PLL */
728     LL_RCC_SetAHBPrescaler(UTILS_ClkInitStruct->AHBCLKDivider);
729     LL_RCC_SetSysClkSource(LL_RCC_SYS_CLKSOURCE_PLL);
730     while (LL_RCC_GetSysClkSource() != LL_RCC_SYS_CLKSOURCE_STATUS_PLL)
731     {
732       /* Wait for system clock switch to PLL */
733     }
734 
735     /* Set APB1 & APB2 prescaler*/
736     LL_RCC_SetAPB1Prescaler(UTILS_ClkInitStruct->APB1CLKDivider);
737     LL_RCC_SetAPB2Prescaler(UTILS_ClkInitStruct->APB2CLKDivider);
738   }
739 
740   /* Decreasing the number of wait states because of lower CPU frequency */
741 #if defined (FLASH_ACR_LATENCY)
742   if (sysclk_frequency_current > SYSCLK_Frequency)
743   {
744     /* Set FLASH latency to lowest latency */
745     status = LL_SetFlashLatency(SYSCLK_Frequency);
746   }
747 #endif /* FLASH_ACR_LATENCY */
748 
749   /* Update SystemCoreClock variable */
750   if (status == SUCCESS)
751   {
752     LL_SetSystemCoreClock(__LL_RCC_CALC_HCLK_FREQ(SYSCLK_Frequency, UTILS_ClkInitStruct->AHBCLKDivider));
753   }
754 
755   return status;
756 }
757 
758 /**
759   * @}
760   */
761 
762 /**
763   * @}
764   */
765 
766 /**
767   * @}
768   */
769 
770 /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
771