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