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