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 if (status != ERROR)
270 {
271 LL_FLASH_SetLatency(latency);
272
273 /* Check that the new number of wait states is taken into account to access the Flash
274 memory by reading the FLASH_ACR register */
275 timeout = 2;
276 do
277 {
278 /* Wait for Flash latency to be updated */
279 getlatency = LL_FLASH_GetLatency();
280 timeout--;
281 } while ((getlatency != latency) && (timeout > 0));
282
283 if(getlatency != latency)
284 {
285 status = ERROR;
286 }
287 }
288 }
289
290 return status;
291 }
292 #endif /* FLASH_ACR_LATENCY */
293
294 /**
295 * @brief This function configures system clock with HSI as clock source of the PLL
296 * @note The application need to ensure that PLL is disabled.
297 * @note Function is based on the following formula:
298 * - PLL output frequency = ((HSI frequency / PREDIV) * PLLMUL)
299 * - PREDIV: Set to 2 for few devices
300 * - PLLMUL: The application software must set correctly the PLL multiplication factor to
301 * not exceed 72MHz
302 * @note FLASH latency can be modified through this function.
303 * @param UTILS_PLLInitStruct pointer to a @ref LL_UTILS_PLLInitTypeDef structure that contains
304 * the configuration information for the PLL.
305 * @param UTILS_ClkInitStruct pointer to a @ref LL_UTILS_ClkInitTypeDef structure that contains
306 * the configuration information for the BUS prescalers.
307 * @retval An ErrorStatus enumeration value:
308 * - SUCCESS: Max frequency configuration done
309 * - ERROR: Max frequency configuration not done
310 */
LL_PLL_ConfigSystemClock_HSI(LL_UTILS_PLLInitTypeDef * UTILS_PLLInitStruct,LL_UTILS_ClkInitTypeDef * UTILS_ClkInitStruct)311 ErrorStatus LL_PLL_ConfigSystemClock_HSI(LL_UTILS_PLLInitTypeDef *UTILS_PLLInitStruct,
312 LL_UTILS_ClkInitTypeDef *UTILS_ClkInitStruct)
313 {
314 ErrorStatus status = SUCCESS;
315 uint32_t pllfreq = 0U;
316
317 /* Check if one of the PLL is enabled */
318 if (UTILS_PLL_IsBusy() == SUCCESS)
319 {
320 #if defined(RCC_PLLSRC_PREDIV1_SUPPORT)
321 /* Check PREDIV value */
322 assert_param(IS_LL_UTILS_PREDIV_VALUE(UTILS_PLLInitStruct->PLLDiv));
323 #else
324 /* Force PREDIV value to 2 */
325 UTILS_PLLInitStruct->Prediv = LL_RCC_PREDIV_DIV_2;
326 #endif /*RCC_PLLSRC_PREDIV1_SUPPORT*/
327 /* Calculate the new PLL output frequency */
328 pllfreq = UTILS_GetPLLOutputFrequency(HSI_VALUE, UTILS_PLLInitStruct);
329
330 /* Enable HSI if not enabled */
331 if (LL_RCC_HSI_IsReady() != 1U)
332 {
333 LL_RCC_HSI_Enable();
334 while (LL_RCC_HSI_IsReady() != 1U)
335 {
336 /* Wait for HSI ready */
337 }
338 }
339
340 /* Configure PLL */
341 #if defined(RCC_PLLSRC_PREDIV1_SUPPORT)
342 LL_RCC_PLL_ConfigDomain_SYS(LL_RCC_PLLSOURCE_HSI, UTILS_PLLInitStruct->PLLMul, UTILS_PLLInitStruct->PLLDiv);
343 #else
344 LL_RCC_PLL_ConfigDomain_SYS(LL_RCC_PLLSOURCE_HSI_DIV_2, UTILS_PLLInitStruct->PLLMul);
345 #endif /*RCC_PLLSRC_PREDIV1_SUPPORT*/
346
347 /* Enable PLL and switch system clock to PLL */
348 status = UTILS_EnablePLLAndSwitchSystem(pllfreq, UTILS_ClkInitStruct);
349 }
350 else
351 {
352 /* Current PLL configuration cannot be modified */
353 status = ERROR;
354 }
355
356 return status;
357 }
358
359 /**
360 * @brief This function configures system clock with HSE as clock source of the PLL
361 * @note The application need to ensure that PLL is disabled.
362 * @note Function is based on the following formula:
363 * - PLL output frequency = ((HSI frequency / PREDIV) * PLLMUL)
364 * - PREDIV: Set to 2 for few devices
365 * - PLLMUL: The application software must set correctly the PLL multiplication factor to
366 * not exceed @ref UTILS_PLL_OUTPUT_MAX
367 * @note FLASH latency can be modified through this function.
368 * @param HSEFrequency Value between Min_Data = 4000000 and Max_Data = 32000000
369 * @param HSEBypass This parameter can be one of the following values:
370 * @arg @ref LL_UTILS_HSEBYPASS_ON
371 * @arg @ref LL_UTILS_HSEBYPASS_OFF
372 * @param UTILS_PLLInitStruct pointer to a @ref LL_UTILS_PLLInitTypeDef structure that contains
373 * the configuration information for the PLL.
374 * @param UTILS_ClkInitStruct pointer to a @ref LL_UTILS_ClkInitTypeDef structure that contains
375 * the configuration information for the BUS prescalers.
376 * @retval An ErrorStatus enumeration value:
377 * - SUCCESS: Max frequency configuration done
378 * - ERROR: Max frequency configuration not done
379 */
LL_PLL_ConfigSystemClock_HSE(uint32_t HSEFrequency,uint32_t HSEBypass,LL_UTILS_PLLInitTypeDef * UTILS_PLLInitStruct,LL_UTILS_ClkInitTypeDef * UTILS_ClkInitStruct)380 ErrorStatus LL_PLL_ConfigSystemClock_HSE(uint32_t HSEFrequency, uint32_t HSEBypass,
381 LL_UTILS_PLLInitTypeDef *UTILS_PLLInitStruct, LL_UTILS_ClkInitTypeDef *UTILS_ClkInitStruct)
382 {
383 ErrorStatus status = SUCCESS;
384 uint32_t pllfreq = 0U;
385
386 /* Check the parameters */
387 assert_param(IS_LL_UTILS_HSE_FREQUENCY(HSEFrequency));
388 assert_param(IS_LL_UTILS_HSE_BYPASS(HSEBypass));
389
390 /* Check if one of the PLL is enabled */
391 if (UTILS_PLL_IsBusy() == SUCCESS)
392 {
393 /* Check PREDIV value */
394 #if defined(RCC_PLLSRC_PREDIV1_SUPPORT)
395 assert_param(IS_LL_UTILS_PREDIV_VALUE(UTILS_PLLInitStruct->PLLDiv));
396 #else
397 assert_param(IS_LL_UTILS_PREDIV_VALUE(UTILS_PLLInitStruct->Prediv));
398 #endif /*RCC_PLLSRC_PREDIV1_SUPPORT*/
399
400 /* Calculate the new PLL output frequency */
401 pllfreq = UTILS_GetPLLOutputFrequency(HSEFrequency, UTILS_PLLInitStruct);
402
403 /* Enable HSE if not enabled */
404 if (LL_RCC_HSE_IsReady() != 1U)
405 {
406 /* Check if need to enable HSE bypass feature or not */
407 if (HSEBypass == LL_UTILS_HSEBYPASS_ON)
408 {
409 LL_RCC_HSE_EnableBypass();
410 }
411 else
412 {
413 LL_RCC_HSE_DisableBypass();
414 }
415
416 /* Enable HSE */
417 LL_RCC_HSE_Enable();
418 while (LL_RCC_HSE_IsReady() != 1U)
419 {
420 /* Wait for HSE ready */
421 }
422 }
423
424 /* Configure PLL */
425 #if defined(RCC_PLLSRC_PREDIV1_SUPPORT)
426 LL_RCC_PLL_ConfigDomain_SYS(LL_RCC_PLLSOURCE_HSE, UTILS_PLLInitStruct->PLLMul, UTILS_PLLInitStruct->PLLDiv);
427 #else
428 LL_RCC_PLL_ConfigDomain_SYS((RCC_CFGR_PLLSRC_HSE_PREDIV | UTILS_PLLInitStruct->Prediv), UTILS_PLLInitStruct->PLLMul);
429 #endif /*RCC_PLLSRC_PREDIV1_SUPPORT*/
430
431 /* Enable PLL and switch system clock to PLL */
432 status = UTILS_EnablePLLAndSwitchSystem(pllfreq, UTILS_ClkInitStruct);
433 }
434 else
435 {
436 /* Current PLL configuration cannot be modified */
437 status = ERROR;
438 }
439
440 return status;
441 }
442
443 /**
444 * @}
445 */
446
447 /**
448 * @}
449 */
450
451 /** @addtogroup UTILS_LL_Private_Functions
452 * @{
453 */
454 /**
455 * @brief Function to check that PLL can be modified
456 * @param PLL_InputFrequency PLL input frequency (in Hz)
457 * @param UTILS_PLLInitStruct pointer to a @ref LL_UTILS_PLLInitTypeDef structure that contains
458 * the configuration information for the PLL.
459 * @retval PLL output frequency (in Hz)
460 */
UTILS_GetPLLOutputFrequency(uint32_t PLL_InputFrequency,LL_UTILS_PLLInitTypeDef * UTILS_PLLInitStruct)461 static uint32_t UTILS_GetPLLOutputFrequency(uint32_t PLL_InputFrequency, LL_UTILS_PLLInitTypeDef *UTILS_PLLInitStruct)
462 {
463 uint32_t pllfreq = 0U;
464
465 /* Check the parameters */
466 assert_param(IS_LL_UTILS_PLLMUL_VALUE(UTILS_PLLInitStruct->PLLMul));
467
468 /* Check different PLL parameters according to RM */
469 /* The application software must set correctly the PLL multiplication factor to
470 not exceed @ref UTILS_PLL_OUTPUT_MAX */
471 #if defined(RCC_PLLSRC_PREDIV1_SUPPORT)
472 pllfreq = __LL_RCC_CALC_PLLCLK_FREQ(PLL_InputFrequency, UTILS_PLLInitStruct->PLLMul, UTILS_PLLInitStruct->PLLDiv);
473 #else
474 pllfreq = __LL_RCC_CALC_PLLCLK_FREQ(PLL_InputFrequency / (UTILS_PLLInitStruct->Prediv + 1U), UTILS_PLLInitStruct->PLLMul);
475 #endif /*RCC_PLLSRC_PREDIV1_SUPPORT*/
476 assert_param(IS_LL_UTILS_PLL_FREQUENCY(pllfreq));
477
478 return pllfreq;
479 }
480
481 /**
482 * @brief Function to check that PLL can be modified
483 * @retval An ErrorStatus enumeration value:
484 * - SUCCESS: PLL modification can be done
485 * - ERROR: PLL is busy
486 */
UTILS_PLL_IsBusy(void)487 static ErrorStatus UTILS_PLL_IsBusy(void)
488 {
489 ErrorStatus status = SUCCESS;
490
491 /* Check if PLL is busy*/
492 if (LL_RCC_PLL_IsReady() != 0U)
493 {
494 /* PLL configuration cannot be modified */
495 status = ERROR;
496 }
497
498 return status;
499 }
500
501 /**
502 * @brief Function to enable PLL and switch system clock to PLL
503 * @param SYSCLK_Frequency SYSCLK frequency
504 * @param UTILS_ClkInitStruct pointer to a @ref LL_UTILS_ClkInitTypeDef structure that contains
505 * the configuration information for the BUS prescalers.
506 * @retval An ErrorStatus enumeration value:
507 * - SUCCESS: No problem to switch system to PLL
508 * - ERROR: Problem to switch system to PLL
509 */
UTILS_EnablePLLAndSwitchSystem(uint32_t SYSCLK_Frequency,LL_UTILS_ClkInitTypeDef * UTILS_ClkInitStruct)510 static ErrorStatus UTILS_EnablePLLAndSwitchSystem(uint32_t SYSCLK_Frequency, LL_UTILS_ClkInitTypeDef *UTILS_ClkInitStruct)
511 {
512 ErrorStatus status = SUCCESS;
513 uint32_t sysclk_frequency_current = 0U;
514
515 assert_param(IS_LL_UTILS_SYSCLK_DIV(UTILS_ClkInitStruct->AHBCLKDivider));
516 assert_param(IS_LL_UTILS_APB1_DIV(UTILS_ClkInitStruct->APB1CLKDivider));
517 assert_param(IS_LL_UTILS_APB2_DIV(UTILS_ClkInitStruct->APB2CLKDivider));
518
519 /* Calculate current SYSCLK frequency */
520 sysclk_frequency_current = (SystemCoreClock << AHBPrescTable[LL_RCC_GetAHBPrescaler() >> RCC_POSITION_HPRE]);
521
522 /* Increasing the number of wait states because of higher CPU frequency */
523 if (sysclk_frequency_current < SYSCLK_Frequency)
524 {
525 /* Set FLASH latency to highest latency */
526 status = LL_SetFlashLatency(SYSCLK_Frequency);
527 }
528
529 /* Update system clock configuration */
530 if (status == SUCCESS)
531 {
532 /* Enable PLL */
533 LL_RCC_PLL_Enable();
534 while (LL_RCC_PLL_IsReady() != 1U)
535 {
536 /* Wait for PLL ready */
537 }
538
539 /* Sysclk activation on the main PLL */
540 LL_RCC_SetAHBPrescaler(UTILS_ClkInitStruct->AHBCLKDivider);
541 LL_RCC_SetSysClkSource(LL_RCC_SYS_CLKSOURCE_PLL);
542 while (LL_RCC_GetSysClkSource() != LL_RCC_SYS_CLKSOURCE_STATUS_PLL)
543 {
544 /* Wait for system clock switch to PLL */
545 }
546
547 /* Set APB1 & APB2 prescaler*/
548 LL_RCC_SetAPB1Prescaler(UTILS_ClkInitStruct->APB1CLKDivider);
549 LL_RCC_SetAPB2Prescaler(UTILS_ClkInitStruct->APB2CLKDivider);
550 }
551
552 /* Decreasing the number of wait states because of lower CPU frequency */
553 if (sysclk_frequency_current > SYSCLK_Frequency)
554 {
555 /* Set FLASH latency to lowest latency */
556 status = LL_SetFlashLatency(SYSCLK_Frequency);
557 }
558
559 /* Update SystemCoreClock variable */
560 if (status == SUCCESS)
561 {
562 LL_SetSystemCoreClock(__LL_RCC_CALC_HCLK_FREQ(SYSCLK_Frequency, UTILS_ClkInitStruct->AHBCLKDivider));
563 }
564
565 return status;
566 }
567
568 /**
569 * @}
570 */
571
572 /**
573 * @}
574 */
575
576 /**
577 * @}
578 */
579