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