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