1 /**
2 ******************************************************************************
3 * @file stm32l0xx_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 /* Includes ------------------------------------------------------------------*/
19 #include "stm32l0xx_ll_rcc.h"
20 #include "stm32l0xx_ll_utils.h"
21 #include "stm32l0xx_ll_system.h"
22 #include "stm32l0xx_ll_pwr.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 STM32L0xx_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 #define UTILS_MAX_FREQUENCY_SCALE1 (32000000U) /*!< Maximum frequency for system clock at power scale1, in Hz */
44 #define UTILS_MAX_FREQUENCY_SCALE2 (16000000U) /*!< Maximum frequency for system clock at power scale2, in Hz */
45 #define UTILS_MAX_FREQUENCY_SCALE3 (4194304U) /*!< Maximum frequency for system clock at power scale3, in Hz */
46
47 /* Defines used for PLL range */
48 #define UTILS_PLLVCO_OUTPUT_SCALE1 (96000000U) /*!< Frequency max for PLLVCO output at power scale1, in Hz */
49 #define UTILS_PLLVCO_OUTPUT_SCALE2 (48000000U) /*!< Frequency max for PLLVCO output at power scale2, in Hz */
50 #define UTILS_PLLVCO_OUTPUT_SCALE3 (24000000U) /*!< Frequency max for PLLVCO output at power scale3, in Hz */
51
52 /* Defines used for HSE range */
53 #define UTILS_HSE_FREQUENCY_MIN (1000000U) /*!< Frequency min for HSE frequency, in Hz */
54 #define UTILS_HSE_FREQUENCY_MAX (24000000U) /*!< Frequency max for HSE frequency, in Hz */
55
56 /* Defines used for FLASH latency according to HCLK Frequency */
57 #define UTILS_SCALE1_LATENCY1_FREQ (16000000U) /*!< HCLK frequency to set FLASH latency 1 in power scale 1 */
58 #define UTILS_SCALE2_LATENCY1_FREQ (8000000U) /*!< HCLK frequency to set FLASH latency 1 in power scale 2 */
59 #define UTILS_SCALE3_LATENCY1_FREQ (2000000U) /*!< HCLK frequency to set FLASH latency 1 in power scale 3 */
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 #define IS_LL_UTILS_PLLMUL_VALUE(__VALUE__) (((__VALUE__) == LL_RCC_PLL_MUL_3) \
90 || ((__VALUE__) == LL_RCC_PLL_MUL_4) \
91 || ((__VALUE__) == LL_RCC_PLL_MUL_6) \
92 || ((__VALUE__) == LL_RCC_PLL_MUL_8) \
93 || ((__VALUE__) == LL_RCC_PLL_MUL_12) \
94 || ((__VALUE__) == LL_RCC_PLL_MUL_16) \
95 || ((__VALUE__) == LL_RCC_PLL_MUL_24) \
96 || ((__VALUE__) == LL_RCC_PLL_MUL_32) \
97 || ((__VALUE__) == LL_RCC_PLL_MUL_48))
98
99 #define IS_LL_UTILS_PLLDIV_VALUE(__VALUE__) (((__VALUE__) == LL_RCC_PLL_DIV_2) || ((__VALUE__) == LL_RCC_PLL_DIV_3) || \
100 ((__VALUE__) == LL_RCC_PLL_DIV_4))
101
102 #define IS_LL_UTILS_PLLVCO_OUTPUT(__VALUE__) ((LL_PWR_GetRegulVoltageScaling() == LL_PWR_REGU_VOLTAGE_SCALE1) ? ((__VALUE__) <= UTILS_PLLVCO_OUTPUT_SCALE1) : \
103 ((LL_PWR_GetRegulVoltageScaling() == LL_PWR_REGU_VOLTAGE_SCALE2) ? ((__VALUE__) <= UTILS_PLLVCO_OUTPUT_SCALE2) : \
104 ((__VALUE__) <= UTILS_PLLVCO_OUTPUT_SCALE3)))
105
106 #define IS_LL_UTILS_PLL_FREQUENCY(__VALUE__) ((LL_PWR_GetRegulVoltageScaling() == LL_PWR_REGU_VOLTAGE_SCALE1) ? ((__VALUE__) <= UTILS_MAX_FREQUENCY_SCALE1) : \
107 ((LL_PWR_GetRegulVoltageScaling() == LL_PWR_REGU_VOLTAGE_SCALE2) ? ((__VALUE__) <= UTILS_MAX_FREQUENCY_SCALE2) : \
108 ((__VALUE__) <= UTILS_MAX_FREQUENCY_SCALE3)))
109
110 #define IS_LL_UTILS_HSE_BYPASS(__STATE__) (((__STATE__) == LL_UTILS_HSEBYPASS_ON) \
111 || ((__STATE__) == LL_UTILS_HSEBYPASS_OFF))
112
113 #define IS_LL_UTILS_HSE_FREQUENCY(__FREQUENCY__) (((__FREQUENCY__) >= UTILS_HSE_FREQUENCY_MIN) && ((__FREQUENCY__) <= UTILS_HSE_FREQUENCY_MAX))
114 /**
115 * @}
116 */
117 /* Private function prototypes -----------------------------------------------*/
118 /** @defgroup UTILS_LL_Private_Functions UTILS Private functions
119 * @{
120 */
121 static uint32_t UTILS_GetPLLOutputFrequency(uint32_t PLL_InputFrequency,
122 LL_UTILS_PLLInitTypeDef *UTILS_PLLInitStruct);
123 static ErrorStatus UTILS_EnablePLLAndSwitchSystem(uint32_t SYSCLK_Frequency, LL_UTILS_ClkInitTypeDef *UTILS_ClkInitStruct);
124 static ErrorStatus UTILS_PLL_IsBusy(void);
125 /**
126 * @}
127 */
128
129 /* Exported functions --------------------------------------------------------*/
130 /** @addtogroup UTILS_LL_Exported_Functions
131 * @{
132 */
133
134 /** @addtogroup UTILS_LL_EF_DELAY
135 * @{
136 */
137
138 /**
139 * @brief This function configures the Cortex-M SysTick source to have 1ms time base.
140 * @note When a RTOS is used, it is recommended to avoid changing the Systick
141 * configuration by calling this function, for a delay use rather osDelay RTOS service.
142 * @param HCLKFrequency HCLK frequency in Hz
143 * @note HCLK frequency can be calculated thanks to RCC helper macro or function @ref LL_RCC_GetSystemClocksFreq
144 * @retval None
145 */
LL_Init1msTick(uint32_t HCLKFrequency)146 void LL_Init1msTick(uint32_t HCLKFrequency)
147 {
148 /* Use frequency provided in argument */
149 LL_InitTick(HCLKFrequency, 1000U);
150 }
151
152 /**
153 * @brief This function provides accurate delay (in milliseconds) based
154 * on SysTick counter flag
155 * @note When a RTOS is used, it is recommended to avoid using blocking delay
156 * and use rather osDelay service.
157 * @note To respect 1ms timebase, user should call @ref LL_Init1msTick function which
158 * will configure Systick to 1ms
159 * @param Delay specifies the delay time length, in milliseconds.
160 * @retval None
161 */
LL_mDelay(uint32_t Delay)162 void LL_mDelay(uint32_t Delay)
163 {
164 __IO uint32_t tmp = SysTick->CTRL; /* Clear the COUNTFLAG first */
165 /* Add this code to indicate that local variable is not used */
166 ((void)tmp);
167
168 /* Add a period to guaranty minimum wait */
169 if (Delay < LL_MAX_DELAY)
170 {
171 Delay++;
172 }
173
174 while (Delay)
175 {
176 if ((SysTick->CTRL & SysTick_CTRL_COUNTFLAG_Msk) != 0U)
177 {
178 Delay--;
179 }
180 }
181 }
182
183 /**
184 * @}
185 */
186
187 /** @addtogroup UTILS_EF_SYSTEM
188 * @brief System Configuration functions
189 *
190 @verbatim
191 ===============================================================================
192 ##### System Configuration functions #####
193 ===============================================================================
194 [..]
195 System, AHB and APB buses clocks configuration
196
197 (+) The maximum frequency of the SYSCLK, HCLK, PCLK1 and PCLK2 is 32000000 Hz.
198 @endverbatim
199 @internal
200 Depending on the device voltage range, the maximum frequency should be
201 adapted accordingly:
202 (++) +----------------------------------------------------------------+
203 (++) | Wait states | HCLK clock frequency (MHz) |
204 (++) | |------------------------------------------------|
205 (++) | (Latency) | voltage range | voltage range |
206 (++) | | 1.65 V - 3.6 V | 2.0 V - 3.6 V |
207 (++) | |----------------|---------------|---------------|
208 (++) | | VCORE = 1.2 V | VCORE = 1.5 V | VCORE = 1.8 V |
209 (++) |-------------- |----------------|---------------|---------------|
210 (++) |0WS(1CPU cycle)|0 < HCLK <= 2 |0 < HCLK <= 8 |0 < HCLK <= 16 |
211 (++) |---------------|----------------|---------------|---------------|
212 (++) |1WS(2CPU cycle)|2 < HCLK <= 4 |8 < HCLK <= 16 |16 < HCLK <= 32|
213 (++) +----------------------------------------------------------------+
214 @endinternal
215 * @{
216 */
217
218 /**
219 * @brief This function sets directly SystemCoreClock CMSIS variable.
220 * @note Variable can be calculated also through SystemCoreClockUpdate function.
221 * @param HCLKFrequency HCLK frequency in Hz (can be calculated thanks to RCC helper macro)
222 * @retval None
223 */
LL_SetSystemCoreClock(uint32_t HCLKFrequency)224 void LL_SetSystemCoreClock(uint32_t HCLKFrequency)
225 {
226 /* HCLK clock frequency */
227 SystemCoreClock = HCLKFrequency;
228 }
229
230 /**
231 * @brief Update number of Flash wait states in line with new frequency and current
232 voltage range.
233 * @param Frequency HCLK frequency
234 * @retval An ErrorStatus enumeration value:
235 * - SUCCESS: Latency has been modified
236 * - ERROR: Latency cannot be modified
237 */
LL_SetFlashLatency(uint32_t Frequency)238 ErrorStatus LL_SetFlashLatency(uint32_t Frequency)
239 {
240 uint32_t timeout;
241 uint32_t getlatency;
242 uint32_t latency;
243 ErrorStatus status = SUCCESS;
244
245 /* Frequency cannot be equal to 0 */
246 if ((Frequency == 0U) || (Frequency > UTILS_MAX_FREQUENCY_SCALE1))
247 {
248 status = ERROR;
249 }
250 else
251 {
252 if (LL_PWR_GetRegulVoltageScaling() == LL_PWR_REGU_VOLTAGE_SCALE1)
253 {
254 if (Frequency > UTILS_SCALE1_LATENCY1_FREQ)
255 {
256 /* 16 < HCLK <= 32 => 1WS (2 CPU cycles) */
257 latency = LL_FLASH_LATENCY_1;
258 }
259 else
260 {
261 /* else HCLK < 16MHz default LL_FLASH_LATENCY_0 0WS */
262 latency = LL_FLASH_LATENCY_0;
263 }
264 }
265 else if (LL_PWR_GetRegulVoltageScaling() == LL_PWR_REGU_VOLTAGE_SCALE2)
266 {
267 if (Frequency > UTILS_SCALE2_LATENCY1_FREQ)
268 {
269 /* 8 < HCLK <= 16 => 1WS (2 CPU cycles) */
270 latency = LL_FLASH_LATENCY_1;
271 }
272 else
273 {
274 /* else HCLK < 8MHz default LL_FLASH_LATENCY_0 0WS */
275 latency = LL_FLASH_LATENCY_0;
276 }
277 }
278 else
279 {
280 if (Frequency > UTILS_SCALE3_LATENCY1_FREQ)
281 {
282 /* 2 < HCLK <= 4 => 1WS (2 CPU cycles) */
283 latency = LL_FLASH_LATENCY_1;
284 }
285 else
286 {
287 /* else HCLK < 2MHz default LL_FLASH_LATENCY_0 0WS */
288 latency = LL_FLASH_LATENCY_0;
289 }
290 }
291
292 if (status != ERROR)
293 {
294 LL_FLASH_SetLatency(latency);
295
296 /* Check that the new number of wait states is taken into account to access the Flash
297 memory by reading the FLASH_ACR register */
298 timeout = 2;
299 do
300 {
301 /* Wait for Flash latency to be updated */
302 getlatency = LL_FLASH_GetLatency();
303 timeout--;
304 } while ((getlatency != latency) && (timeout > 0));
305
306 if(getlatency != latency)
307 {
308 status = ERROR;
309 }
310 }
311 }
312 return status;
313 }
314
315 /**
316 * @brief This function configures system clock with HSI as clock source of the PLL
317 * @note The application need to ensure that PLL is disabled.
318 * @note Function is based on the following formula:
319 * - PLL output frequency = ((HSI frequency * PLLMul) / PLLDiv)
320 * - PLLMul: The application software must set correctly the PLL multiplication factor to ensure
321 * - PLLVCO does not exceed 96 MHz when the product is in range 1,
322 * - PLLVCO does not exceed 48 MHz when the product is in range 2,
323 * - PLLVCO does not exceed 24 MHz when the product is in range 3
324 * @note FLASH latency can be modified through this function.
325 * @param UTILS_PLLInitStruct pointer to a @ref LL_UTILS_PLLInitTypeDef structure that contains
326 * the configuration information for the PLL.
327 * @param UTILS_ClkInitStruct pointer to a @ref LL_UTILS_ClkInitTypeDef structure that contains
328 * the configuration information for the BUS prescalers.
329 * @retval An ErrorStatus enumeration value:
330 * - SUCCESS: Max frequency configuration done
331 * - ERROR: Max frequency configuration not done
332 */
LL_PLL_ConfigSystemClock_HSI(LL_UTILS_PLLInitTypeDef * UTILS_PLLInitStruct,LL_UTILS_ClkInitTypeDef * UTILS_ClkInitStruct)333 ErrorStatus LL_PLL_ConfigSystemClock_HSI(LL_UTILS_PLLInitTypeDef *UTILS_PLLInitStruct,
334 LL_UTILS_ClkInitTypeDef *UTILS_ClkInitStruct)
335 {
336 ErrorStatus status = SUCCESS;
337 uint32_t pllfreq = 0U;
338
339 /* Check if one of the PLL is enabled */
340 if (UTILS_PLL_IsBusy() == SUCCESS)
341 {
342 /* Calculate the new PLL output frequency */
343 pllfreq = UTILS_GetPLLOutputFrequency(HSI_VALUE, UTILS_PLLInitStruct);
344
345 /* Enable HSI if not enabled */
346 if (LL_RCC_HSI_IsReady() != 1U)
347 {
348 LL_RCC_HSI_Enable();
349 while (LL_RCC_HSI_IsReady() != 1U)
350 {
351 /* Wait for HSI ready */
352 }
353 }
354
355 /* Configure PLL */
356 LL_RCC_PLL_ConfigDomain_SYS(LL_RCC_PLLSOURCE_HSI, UTILS_PLLInitStruct->PLLMul, UTILS_PLLInitStruct->PLLDiv);
357
358 /* Enable PLL and switch system clock to PLL */
359 status = UTILS_EnablePLLAndSwitchSystem(pllfreq, UTILS_ClkInitStruct);
360 }
361 else
362 {
363 /* Current PLL configuration cannot be modified */
364 status = ERROR;
365 }
366
367 return status;
368 }
369
370 /**
371 * @brief This function configures system clock with HSE as clock source of the PLL
372 * @note The application need to ensure that PLL is disabled.
373 * @note Function is based on the following formula:
374 * - PLL output frequency = ((HSE frequency * PLLMul) / PLLDiv)
375 * - PLLMul: The application software must set correctly the PLL multiplication factor to to ensure
376 * - PLLVCO does not exceed 96 MHz when the product is in range 1,
377 * - PLLVCO does not exceed 48 MHz when the product is in range 2,
378 * - PLLVCO does not exceed 24 MHz when the product is in range 3
379 * @note FLASH latency can be modified through this function.
380 * @param HSEFrequency Value between Min_Data = 1000000 and Max_Data = 24000000
381 * @param HSEBypass This parameter can be one of the following values:
382 * @arg @ref LL_UTILS_HSEBYPASS_ON
383 * @arg @ref LL_UTILS_HSEBYPASS_OFF
384 * @param UTILS_PLLInitStruct pointer to a @ref LL_UTILS_PLLInitTypeDef structure that contains
385 * the configuration information for the PLL.
386 * @param UTILS_ClkInitStruct pointer to a @ref LL_UTILS_ClkInitTypeDef structure that contains
387 * the configuration information for the BUS prescalers.
388 * @retval An ErrorStatus enumeration value:
389 * - SUCCESS: Max frequency configuration done
390 * - ERROR: Max frequency configuration not done
391 */
LL_PLL_ConfigSystemClock_HSE(uint32_t HSEFrequency,uint32_t HSEBypass,LL_UTILS_PLLInitTypeDef * UTILS_PLLInitStruct,LL_UTILS_ClkInitTypeDef * UTILS_ClkInitStruct)392 ErrorStatus LL_PLL_ConfigSystemClock_HSE(uint32_t HSEFrequency, uint32_t HSEBypass,
393 LL_UTILS_PLLInitTypeDef *UTILS_PLLInitStruct, LL_UTILS_ClkInitTypeDef *UTILS_ClkInitStruct)
394 {
395 ErrorStatus status = SUCCESS;
396 uint32_t pllfreq = 0U;
397
398 /* Check the parameters */
399 assert_param(IS_LL_UTILS_HSE_FREQUENCY(HSEFrequency));
400 assert_param(IS_LL_UTILS_HSE_BYPASS(HSEBypass));
401
402 /* Check if one of the PLL is enabled */
403 if (UTILS_PLL_IsBusy() == SUCCESS)
404 {
405 /* Calculate the new PLL output frequency */
406 pllfreq = UTILS_GetPLLOutputFrequency(HSEFrequency, UTILS_PLLInitStruct);
407
408 /* Enable HSE if not enabled */
409 if (LL_RCC_HSE_IsReady() != 1U)
410 {
411 /* Check if need to enable HSE bypass feature or not */
412 if (HSEBypass == LL_UTILS_HSEBYPASS_ON)
413 {
414 LL_RCC_HSE_EnableBypass();
415 }
416 else
417 {
418 LL_RCC_HSE_DisableBypass();
419 }
420
421 /* Enable HSE */
422 LL_RCC_HSE_Enable();
423 while (LL_RCC_HSE_IsReady() != 1U)
424 {
425 /* Wait for HSE ready */
426 }
427 }
428
429 /* Configure PLL */
430 LL_RCC_PLL_ConfigDomain_SYS(LL_RCC_PLLSOURCE_HSE, UTILS_PLLInitStruct->PLLMul, UTILS_PLLInitStruct->PLLDiv);
431
432 /* Enable PLL and switch system clock to PLL */
433 status = UTILS_EnablePLLAndSwitchSystem(pllfreq, UTILS_ClkInitStruct);
434 }
435 else
436 {
437 /* Current PLL configuration cannot be modified */
438 status = ERROR;
439 }
440
441 return status;
442 }
443
444 /**
445 * @}
446 */
447
448 /**
449 * @}
450 */
451
452 /** @addtogroup UTILS_LL_Private_Functions
453 * @{
454 */
455 /**
456 * @brief Function to check that PLL can be modified
457 * @param PLL_InputFrequency PLL input frequency (in Hz)
458 * @param UTILS_PLLInitStruct pointer to a @ref LL_UTILS_PLLInitTypeDef structure that contains
459 * the configuration information for the PLL.
460 * @retval PLL output frequency (in Hz)
461 */
UTILS_GetPLLOutputFrequency(uint32_t PLL_InputFrequency,LL_UTILS_PLLInitTypeDef * UTILS_PLLInitStruct)462 static uint32_t UTILS_GetPLLOutputFrequency(uint32_t PLL_InputFrequency, LL_UTILS_PLLInitTypeDef *UTILS_PLLInitStruct)
463 {
464 uint32_t pllfreq = 0U;
465
466 /* Check the parameters */
467 assert_param(IS_LL_UTILS_PLLMUL_VALUE(UTILS_PLLInitStruct->PLLMul));
468 assert_param(IS_LL_UTILS_PLLDIV_VALUE(UTILS_PLLInitStruct->PLLDiv));
469
470 /* Check different PLL parameters according to RM */
471 /* The application software must set correctly the PLL multiplication factor to avoid exceeding
472 96 MHz as PLLVCO when the product is in range 1,
473 48 MHz as PLLVCO when the product is in range 2,
474 24 MHz when the product is in range 3. */
475 pllfreq = PLL_InputFrequency * (PLLMulTable[UTILS_PLLInitStruct->PLLMul >> RCC_CFGR_PLLMUL_Pos]);
476 assert_param(IS_LL_UTILS_PLLVCO_OUTPUT(pllfreq));
477
478 /* The application software must set correctly the PLL multiplication factor to avoid exceeding
479 maximum frequency 32000000 in range 1 */
480 pllfreq = pllfreq / ((UTILS_PLLInitStruct->PLLDiv >> RCC_CFGR_PLLDIV_Pos)+1U);
481 assert_param(IS_LL_UTILS_PLL_FREQUENCY(pllfreq));
482
483 return pllfreq;
484 }
485
486 /**
487 * @brief Function to check that PLL can be modified
488 * @retval An ErrorStatus enumeration value:
489 * - SUCCESS: PLL modification can be done
490 * - ERROR: PLL is busy
491 */
UTILS_PLL_IsBusy(void)492 static ErrorStatus UTILS_PLL_IsBusy(void)
493 {
494 ErrorStatus status = SUCCESS;
495
496 /* Check if PLL is busy*/
497 if (LL_RCC_PLL_IsReady() != 0U)
498 {
499 /* PLL configuration cannot be modified */
500 status = ERROR;
501 }
502
503
504 return status;
505 }
506
507 /**
508 * @brief Function to enable PLL and switch system clock to PLL
509 * @param SYSCLK_Frequency SYSCLK frequency
510 * @param UTILS_ClkInitStruct pointer to a @ref LL_UTILS_ClkInitTypeDef structure that contains
511 * the configuration information for the BUS prescalers.
512 * @retval An ErrorStatus enumeration value:
513 * - SUCCESS: No problem to switch system to PLL
514 * - ERROR: Problem to switch system to PLL
515 */
UTILS_EnablePLLAndSwitchSystem(uint32_t SYSCLK_Frequency,LL_UTILS_ClkInitTypeDef * UTILS_ClkInitStruct)516 static ErrorStatus UTILS_EnablePLLAndSwitchSystem(uint32_t SYSCLK_Frequency, LL_UTILS_ClkInitTypeDef *UTILS_ClkInitStruct)
517 {
518 ErrorStatus status = SUCCESS;
519 uint32_t hclk_frequency = 0U;
520
521 assert_param(IS_LL_UTILS_SYSCLK_DIV(UTILS_ClkInitStruct->AHBCLKDivider));
522 assert_param(IS_LL_UTILS_APB1_DIV(UTILS_ClkInitStruct->APB1CLKDivider));
523 assert_param(IS_LL_UTILS_APB2_DIV(UTILS_ClkInitStruct->APB2CLKDivider));
524
525 /* Calculate HCLK frequency */
526 hclk_frequency = __LL_RCC_CALC_HCLK_FREQ(SYSCLK_Frequency, UTILS_ClkInitStruct->AHBCLKDivider);
527
528 /* Increasing the number of wait states because of higher CPU frequency */
529 if (SystemCoreClock < hclk_frequency)
530 {
531 /* Set FLASH latency to highest latency */
532 status = LL_SetFlashLatency(hclk_frequency);
533 }
534
535 /* Update system clock configuration */
536 if (status == SUCCESS)
537 {
538 /* Enable PLL */
539 LL_RCC_PLL_Enable();
540 while (LL_RCC_PLL_IsReady() != 1U)
541 {
542 /* Wait for PLL ready */
543 }
544
545 /* Sysclk activation on the main PLL */
546 LL_RCC_SetAHBPrescaler(UTILS_ClkInitStruct->AHBCLKDivider);
547 LL_RCC_SetSysClkSource(LL_RCC_SYS_CLKSOURCE_PLL);
548 while (LL_RCC_GetSysClkSource() != LL_RCC_SYS_CLKSOURCE_STATUS_PLL)
549 {
550 /* Wait for system clock switch to PLL */
551 }
552
553 /* Set APB1 & APB2 prescaler*/
554 LL_RCC_SetAPB1Prescaler(UTILS_ClkInitStruct->APB1CLKDivider);
555 LL_RCC_SetAPB2Prescaler(UTILS_ClkInitStruct->APB2CLKDivider);
556 }
557
558 /* Decreasing the number of wait states because of lower CPU frequency */
559 if (SystemCoreClock > hclk_frequency)
560 {
561 /* Set FLASH latency to lowest latency */
562 status = LL_SetFlashLatency(hclk_frequency);
563 }
564
565 /* Update SystemCoreClock variable */
566 if (status == SUCCESS)
567 {
568 LL_SetSystemCoreClock(hclk_frequency);
569 }
570
571 return status;
572 }
573
574 /**
575 * @}
576 */
577
578 /**
579 * @}
580 */
581
582 /**
583 * @}
584 */
585