1 /**
2 ******************************************************************************
3 * @file stm32l1xx_ll_utils.c
4 * @author MCD Application Team
5 * @brief UTILS LL module driver.
6 ******************************************************************************
7 * @attention
8 *
9 * <h2><center>© Copyright(c) 2017 STMicroelectronics.
10 * All rights reserved.</center></h2>
11 *
12 * This software component is licensed by ST under BSD 3-Clause license,
13 * the "License"; You may not use this file except in compliance with the
14 * License. You may obtain a copy of the License at:
15 * opensource.org/licenses/BSD-3-Clause
16 *
17 ******************************************************************************
18 */
19 /* Includes ------------------------------------------------------------------*/
20 #include "stm32l1xx_ll_rcc.h"
21 #include "stm32l1xx_ll_utils.h"
22 #include "stm32l1xx_ll_system.h"
23 #include "stm32l1xx_ll_pwr.h"
24 #ifdef USE_FULL_ASSERT
25 #include "stm32_assert.h"
26 #else
27 #define assert_param(expr) ((void)0U)
28 #endif
29
30 /** @addtogroup STM32L1xx_LL_Driver
31 * @{
32 */
33
34 /** @addtogroup UTILS_LL
35 * @{
36 */
37
38 /* Private types -------------------------------------------------------------*/
39 /* Private variables ---------------------------------------------------------*/
40 /* Private constants ---------------------------------------------------------*/
41 /** @addtogroup UTILS_LL_Private_Constants
42 * @{
43 */
44 #define UTILS_MAX_FREQUENCY_SCALE1 32000000U /*!< Maximum frequency for system clock at power scale1, in Hz */
45 #define UTILS_MAX_FREQUENCY_SCALE2 16000000U /*!< Maximum frequency for system clock at power scale2, in Hz */
46 #define UTILS_MAX_FREQUENCY_SCALE3 4000000U /*!< Maximum frequency for system clock at power scale3, in Hz */
47
48 /* Defines used for PLL range */
49 #define UTILS_PLLVCO_OUTPUT_SCALE1 96000000U /*!< Frequency max for PLLVCO output at power scale1, in Hz */
50 #define UTILS_PLLVCO_OUTPUT_SCALE2 48000000U /*!< Frequency max for PLLVCO output at power scale2, in Hz */
51 #define UTILS_PLLVCO_OUTPUT_SCALE3 24000000U /*!< Frequency max for PLLVCO output at power scale3, in Hz */
52
53 /* Defines used for HSE range */
54 #define UTILS_HSE_FREQUENCY_MIN 1000000U /*!< Frequency min for HSE frequency, in Hz */
55 #define UTILS_HSE_FREQUENCY_MAX 24000000U /*!< Frequency max for HSE frequency, in Hz */
56
57 /* Defines used for FLASH latency according to HCLK Frequency */
58 #define UTILS_SCALE1_LATENCY1_FREQ 16000000U /*!< HCLK frequency to set FLASH latency 1 in power scale 1 */
59 #define UTILS_SCALE2_LATENCY1_FREQ 8000000U /*!< HCLK frequency to set FLASH latency 1 in power scale 2 */
60 #define UTILS_SCALE3_LATENCY1_FREQ 2000000U /*!< HCLK frequency to set FLASH latency 1 in power scale 3 */
61 /**
62 * @}
63 */
64 /* Private macros ------------------------------------------------------------*/
65 /** @addtogroup UTILS_LL_Private_Macros
66 * @{
67 */
68 #define IS_LL_UTILS_SYSCLK_DIV(__VALUE__) (((__VALUE__) == LL_RCC_SYSCLK_DIV_1) \
69 || ((__VALUE__) == LL_RCC_SYSCLK_DIV_2) \
70 || ((__VALUE__) == LL_RCC_SYSCLK_DIV_4) \
71 || ((__VALUE__) == LL_RCC_SYSCLK_DIV_8) \
72 || ((__VALUE__) == LL_RCC_SYSCLK_DIV_16) \
73 || ((__VALUE__) == LL_RCC_SYSCLK_DIV_64) \
74 || ((__VALUE__) == LL_RCC_SYSCLK_DIV_128) \
75 || ((__VALUE__) == LL_RCC_SYSCLK_DIV_256) \
76 || ((__VALUE__) == LL_RCC_SYSCLK_DIV_512))
77
78 #define IS_LL_UTILS_APB1_DIV(__VALUE__) (((__VALUE__) == LL_RCC_APB1_DIV_1) \
79 || ((__VALUE__) == LL_RCC_APB1_DIV_2) \
80 || ((__VALUE__) == LL_RCC_APB1_DIV_4) \
81 || ((__VALUE__) == LL_RCC_APB1_DIV_8) \
82 || ((__VALUE__) == LL_RCC_APB1_DIV_16))
83
84 #define IS_LL_UTILS_APB2_DIV(__VALUE__) (((__VALUE__) == LL_RCC_APB2_DIV_1) \
85 || ((__VALUE__) == LL_RCC_APB2_DIV_2) \
86 || ((__VALUE__) == LL_RCC_APB2_DIV_4) \
87 || ((__VALUE__) == LL_RCC_APB2_DIV_8) \
88 || ((__VALUE__) == LL_RCC_APB2_DIV_16))
89
90 #define IS_LL_UTILS_PLLMUL_VALUE(__VALUE__) (((__VALUE__) == LL_RCC_PLL_MUL_3) \
91 || ((__VALUE__) == LL_RCC_PLL_MUL_4) \
92 || ((__VALUE__) == LL_RCC_PLL_MUL_6) \
93 || ((__VALUE__) == LL_RCC_PLL_MUL_8) \
94 || ((__VALUE__) == LL_RCC_PLL_MUL_12) \
95 || ((__VALUE__) == LL_RCC_PLL_MUL_16) \
96 || ((__VALUE__) == LL_RCC_PLL_MUL_24) \
97 || ((__VALUE__) == LL_RCC_PLL_MUL_32) \
98 || ((__VALUE__) == LL_RCC_PLL_MUL_48))
99
100 #define IS_LL_UTILS_PLLDIV_VALUE(__VALUE__) (((__VALUE__) == LL_RCC_PLL_DIV_2) || ((__VALUE__) == LL_RCC_PLL_DIV_3) || \
101 ((__VALUE__) == LL_RCC_PLL_DIV_4))
102
103 #define IS_LL_UTILS_PLLVCO_OUTPUT(__VALUE__) ((LL_PWR_GetRegulVoltageScaling() == LL_PWR_REGU_VOLTAGE_SCALE1) ? ((__VALUE__) <= UTILS_PLLVCO_OUTPUT_SCALE1) : \
104 ((LL_PWR_GetRegulVoltageScaling() == LL_PWR_REGU_VOLTAGE_SCALE2) ? ((__VALUE__) <= UTILS_PLLVCO_OUTPUT_SCALE2) : \
105 ((__VALUE__) <= UTILS_PLLVCO_OUTPUT_SCALE3)))
106
107 #define IS_LL_UTILS_PLL_FREQUENCY(__VALUE__) ((LL_PWR_GetRegulVoltageScaling() == LL_PWR_REGU_VOLTAGE_SCALE1) ? ((__VALUE__) <= UTILS_MAX_FREQUENCY_SCALE1) : \
108 ((LL_PWR_GetRegulVoltageScaling() == LL_PWR_REGU_VOLTAGE_SCALE2) ? ((__VALUE__) <= UTILS_MAX_FREQUENCY_SCALE2) : \
109 ((__VALUE__) <= UTILS_MAX_FREQUENCY_SCALE3)))
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 uint32_t tmpDelay = Delay;
167
168 /* Add this code to indicate that local variable is not used */
169 ((void)tmp);
170
171 /* Add a period to guaranty minimum wait */
172 if(tmpDelay < LL_MAX_DELAY)
173 {
174 tmpDelay++;
175 }
176
177 while (tmpDelay != 0U)
178 {
179 if((SysTick->CTRL & SysTick_CTRL_COUNTFLAG_Msk) != 0U)
180 {
181 tmpDelay--;
182 }
183 }
184 }
185
186 /**
187 * @}
188 */
189
190 /** @addtogroup UTILS_EF_SYSTEM
191 * @brief System Configuration functions
192 *
193 @verbatim
194 ===============================================================================
195 ##### System Configuration functions #####
196 ===============================================================================
197 [..]
198 System, AHB and APB buses clocks configuration
199
200 (+) The maximum frequency of the SYSCLK, HCLK, PCLK1 and PCLK2 is 32000000 Hz.
201 @endverbatim
202 @internal
203 Depending on the device voltage range, the maximum frequency should be
204 adapted accordingly:
205 (++) +----------------------------------------------------------------+
206 (++) | Wait states | HCLK clock frequency (MHz) |
207 (++) | |------------------------------------------------|
208 (++) | (Latency) | voltage range | voltage range |
209 (++) | | 1.65 V - 3.6 V | 2.0 V - 3.6 V |
210 (++) | |----------------|---------------|---------------|
211 (++) | | VCORE = 1.2 V | VCORE = 1.5 V | VCORE = 1.8 V |
212 (++) |-------------- |----------------|---------------|---------------|
213 (++) |0WS(1CPU cycle)|0 < HCLK <= 2 |0 < HCLK <= 8 |0 < HCLK <= 16 |
214 (++) |---------------|----------------|---------------|---------------|
215 (++) |1WS(2CPU cycle)|2 < HCLK <= 4 |8 < HCLK <= 16 |16 < HCLK <= 32|
216 (++) +----------------------------------------------------------------+
217 @endinternal
218 * @{
219 */
220
221 /**
222 * @brief This function sets directly SystemCoreClock CMSIS variable.
223 * @note Variable can be calculated also through SystemCoreClockUpdate function.
224 * @param HCLKFrequency HCLK frequency in Hz (can be calculated thanks to RCC helper macro)
225 * @retval None
226 */
LL_SetSystemCoreClock(uint32_t HCLKFrequency)227 void LL_SetSystemCoreClock(uint32_t HCLKFrequency)
228 {
229 /* HCLK clock frequency */
230 SystemCoreClock = HCLKFrequency;
231 }
232
233 /**
234 * @brief Update number of Flash wait states in line with new frequency and current
235 voltage range.
236 * @param Frequency HCLK frequency
237 * @retval An ErrorStatus enumeration value:
238 * - SUCCESS: Latency has been modified
239 * - ERROR: Latency cannot be modified
240 */
241 #if defined(FLASH_ACR_LATENCY)
LL_SetFlashLatency(uint32_t Frequency)242 ErrorStatus LL_SetFlashLatency(uint32_t Frequency)
243 {
244 ErrorStatus status = SUCCESS;
245
246 uint32_t latency = LL_FLASH_LATENCY_0; /* default value 0WS */
247
248 /* Frequency cannot be equal to 0 or greater than max clock */
249 if ((Frequency == 0U) || (Frequency > UTILS_MAX_FREQUENCY_SCALE1))
250 {
251 status = ERROR;
252 }
253 else
254 {
255 if (LL_PWR_GetRegulVoltageScaling() == LL_PWR_REGU_VOLTAGE_SCALE1)
256 {
257 if (Frequency > UTILS_SCALE1_LATENCY1_FREQ)
258 {
259 /* 16 < HCLK <= 32 => 1WS (2 CPU cycles) */
260 latency = LL_FLASH_LATENCY_1;
261 }
262 /* else HCLK < 16MHz default LL_FLASH_LATENCY_0 0WS */
263 }
264 else if (LL_PWR_GetRegulVoltageScaling() == LL_PWR_REGU_VOLTAGE_SCALE2)
265 {
266 if (Frequency > UTILS_SCALE2_LATENCY1_FREQ)
267 {
268 /* 8 < HCLK <= 16 => 1WS (2 CPU cycles) */
269 latency = LL_FLASH_LATENCY_1;
270 }
271 /* else HCLK < 8MHz default LL_FLASH_LATENCY_0 0WS */
272 }
273 else
274 {
275 if (Frequency > UTILS_SCALE3_LATENCY1_FREQ)
276 {
277 /* 2 < HCLK <= 4 => 1WS (2 CPU cycles) */
278 latency = LL_FLASH_LATENCY_1;
279 }
280 /* else HCLK < 4MHz default LL_FLASH_LATENCY_0 0WS */
281 }
282
283 /* Latency cannot be set to 1WS only if 64-bit access bit is enabled */
284 if (latency == LL_FLASH_LATENCY_1)
285 {
286 LL_FLASH_Enable64bitAccess();
287 }
288
289 LL_FLASH_SetLatency(latency);
290
291 /* Check that the new number of wait states is taken into account to access the Flash
292 memory by reading the FLASH_ACR register */
293 if (LL_FLASH_GetLatency() != latency)
294 {
295 status = ERROR;
296 }
297 }
298 return status;
299 }
300 #endif /* FLASH_ACR_LATENCY */
301
302 /**
303 * @brief This function configures system clock with HSI as clock source of the PLL
304 * @note The application need to ensure that PLL is disabled.
305 * @note Function is based on the following formula:
306 * - PLL output frequency = ((HSI frequency * PLLMul) / PLLDiv)
307 * - PLLMul: The application software must set correctly the PLL multiplication factor to avoid exceeding
308 * - 96 MHz as PLLVCO when the product is in range 1,
309 * - 48 MHz as PLLVCO when the product is in range 2,
310 * - 24 MHz when the product is in range 3
311 * @note FLASH latency can be modified through this function.
312 * @note If this latency increases to 1WS, FLASH 64-bit access will be automatically enabled.
313 * A decrease of FLASH latency to 0WS will not disable 64-bit access. If needed, user should call
314 * the following function @ref LL_FLASH_Disable64bitAccess.
315 * @param UTILS_PLLInitStruct pointer to a @ref LL_UTILS_PLLInitTypeDef structure that contains
316 * the configuration information for the PLL.
317 * @param UTILS_ClkInitStruct pointer to a @ref LL_UTILS_ClkInitTypeDef structure that contains
318 * the configuration information for the BUS prescalers.
319 * @retval An ErrorStatus enumeration value:
320 * - SUCCESS: Max frequency configuration done
321 * - ERROR: Max frequency configuration not done
322 */
LL_PLL_ConfigSystemClock_HSI(LL_UTILS_PLLInitTypeDef * UTILS_PLLInitStruct,LL_UTILS_ClkInitTypeDef * UTILS_ClkInitStruct)323 ErrorStatus LL_PLL_ConfigSystemClock_HSI(LL_UTILS_PLLInitTypeDef *UTILS_PLLInitStruct,
324 LL_UTILS_ClkInitTypeDef *UTILS_ClkInitStruct)
325 {
326 ErrorStatus status;
327 uint32_t pllfreq;
328
329 /* Check if one of the PLL is enabled */
330 if (UTILS_PLL_IsBusy() == SUCCESS)
331 {
332 /* Calculate the new PLL output frequency */
333 pllfreq = UTILS_GetPLLOutputFrequency(HSI_VALUE, UTILS_PLLInitStruct);
334
335 /* Enable HSI if not enabled */
336 if (LL_RCC_HSI_IsReady() != 1U)
337 {
338 LL_RCC_HSI_Enable();
339 while (LL_RCC_HSI_IsReady() != 1U)
340 {
341 /* Wait for HSI ready */
342 }
343 }
344
345 /* Configure PLL */
346 LL_RCC_PLL_ConfigDomain_SYS(LL_RCC_PLLSOURCE_HSI, UTILS_PLLInitStruct->PLLMul, UTILS_PLLInitStruct->PLLDiv);
347
348 /* Enable PLL and switch system clock to PLL */
349 status = UTILS_EnablePLLAndSwitchSystem(pllfreq, UTILS_ClkInitStruct);
350 }
351 else
352 {
353 /* Current PLL configuration cannot be modified */
354 status = ERROR;
355 }
356
357 return status;
358 }
359
360 /**
361 * @brief This function configures system clock with HSE as clock source of the PLL
362 * @note The application need to ensure that PLL is disabled.
363 * @note Function is based on the following formula:
364 * - PLL output frequency = ((HSE frequency * PLLMul) / PLLDiv)
365 * - PLLMul: The application software must set correctly the PLL multiplication factor to avoid exceeding
366 * - 96 MHz as PLLVCO when the product is in range 1,
367 * - 48 MHz as PLLVCO when the product is in range 2,
368 * - 24 MHz when the product is in range 3
369 * @note FLASH latency can be modified through this function.
370 * @note If this latency increases to 1WS, FLASH 64-bit access will be automatically enabled.
371 * A decrease of FLASH latency to 0WS will not disable 64-bit access. If needed, user should call
372 * the following function @ref LL_FLASH_Disable64bitAccess.
373 * @param HSEFrequency Value between Min_Data = 1000000 and Max_Data = 24000000
374 * @param HSEBypass This parameter can be one of the following values:
375 * @arg @ref LL_UTILS_HSEBYPASS_ON
376 * @arg @ref LL_UTILS_HSEBYPASS_OFF
377 * @param UTILS_PLLInitStruct pointer to a @ref LL_UTILS_PLLInitTypeDef structure that contains
378 * the configuration information for the PLL.
379 * @param UTILS_ClkInitStruct pointer to a @ref LL_UTILS_ClkInitTypeDef structure that contains
380 * the configuration information for the BUS prescalers.
381 * @retval An ErrorStatus enumeration value:
382 * - SUCCESS: Max frequency configuration done
383 * - ERROR: Max frequency configuration not done
384 */
LL_PLL_ConfigSystemClock_HSE(uint32_t HSEFrequency,uint32_t HSEBypass,LL_UTILS_PLLInitTypeDef * UTILS_PLLInitStruct,LL_UTILS_ClkInitTypeDef * UTILS_ClkInitStruct)385 ErrorStatus LL_PLL_ConfigSystemClock_HSE(uint32_t HSEFrequency, uint32_t HSEBypass,
386 LL_UTILS_PLLInitTypeDef *UTILS_PLLInitStruct, LL_UTILS_ClkInitTypeDef *UTILS_ClkInitStruct)
387 {
388 ErrorStatus status;
389 uint32_t pllfreq;
390
391 /* Check the parameters */
392 assert_param(IS_LL_UTILS_HSE_FREQUENCY(HSEFrequency));
393 assert_param(IS_LL_UTILS_HSE_BYPASS(HSEBypass));
394
395 /* Check if one of the PLL is enabled */
396 if (UTILS_PLL_IsBusy() == SUCCESS)
397 {
398
399 /* Calculate the new PLL output frequency */
400 pllfreq = UTILS_GetPLLOutputFrequency(HSEFrequency, UTILS_PLLInitStruct);
401
402 /* Enable HSE if not enabled */
403 if (LL_RCC_HSE_IsReady() != 1U)
404 {
405 /* Check if need to enable HSE bypass feature or not */
406 if (HSEBypass == LL_UTILS_HSEBYPASS_ON)
407 {
408 LL_RCC_HSE_EnableBypass();
409 }
410 else
411 {
412 LL_RCC_HSE_DisableBypass();
413 }
414
415 /* Enable HSE */
416 LL_RCC_HSE_Enable();
417 while (LL_RCC_HSE_IsReady() != 1U)
418 {
419 /* Wait for HSE ready */
420 }
421 }
422
423 /* Configure PLL */
424 LL_RCC_PLL_ConfigDomain_SYS(LL_RCC_PLLSOURCE_HSE, UTILS_PLLInitStruct->PLLMul, UTILS_PLLInitStruct->PLLDiv);
425
426 /* Enable PLL and switch system clock to PLL */
427 status = UTILS_EnablePLLAndSwitchSystem(pllfreq, UTILS_ClkInitStruct);
428 }
429 else
430 {
431 /* Current PLL configuration cannot be modified */
432 status = ERROR;
433 }
434
435 return status;
436 }
437
438 /**
439 * @}
440 */
441
442 /**
443 * @}
444 */
445
446 /** @addtogroup UTILS_LL_Private_Functions
447 * @{
448 */
449
450 /**
451 * @brief Function to check that PLL can be modified
452 * @param PLL_InputFrequency PLL input frequency (in Hz)
453 * @param UTILS_PLLInitStruct pointer to a @ref LL_UTILS_PLLInitTypeDef structure that contains
454 * the configuration information for the PLL.
455 * @retval PLL output frequency (in Hz)
456 */
UTILS_GetPLLOutputFrequency(uint32_t PLL_InputFrequency,LL_UTILS_PLLInitTypeDef * UTILS_PLLInitStruct)457 static uint32_t UTILS_GetPLLOutputFrequency(uint32_t PLL_InputFrequency, LL_UTILS_PLLInitTypeDef *UTILS_PLLInitStruct)
458 {
459 uint32_t pllfreq;
460
461 /* Check the parameters */
462 assert_param(IS_LL_UTILS_PLLMUL_VALUE(UTILS_PLLInitStruct->PLLMul));
463 assert_param(IS_LL_UTILS_PLLDIV_VALUE(UTILS_PLLInitStruct->PLLDiv));
464
465 /* Check different PLL parameters according to RM */
466 /* The application software must set correctly the PLL multiplication factor to avoid exceeding
467 96 MHz as PLLVCO when the product is in range 1,
468 48 MHz as PLLVCO when the product is in range 2,
469 24 MHz when the product is in range 3. */
470 pllfreq = PLL_InputFrequency * (PLLMulTable[UTILS_PLLInitStruct->PLLMul >> RCC_CFGR_PLLMUL_Pos]);
471 assert_param(IS_LL_UTILS_PLLVCO_OUTPUT(pllfreq));
472
473 /* The application software must set correctly the PLL multiplication factor to avoid exceeding
474 maximum frequency 32000000 in range 1 */
475 pllfreq = pllfreq / ((UTILS_PLLInitStruct->PLLDiv >> RCC_CFGR_PLLDIV_Pos)+1U);
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 hclk_frequency;
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 HCLK frequency */
520 hclk_frequency = __LL_RCC_CALC_HCLK_FREQ(SYSCLK_Frequency, UTILS_ClkInitStruct->AHBCLKDivider);
521
522 /* Increasing the number of wait states because of higher CPU frequency */
523 if (SystemCoreClock < hclk_frequency)
524 {
525 /* Set FLASH latency to highest latency */
526 status = LL_SetFlashLatency(hclk_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 (SystemCoreClock > hclk_frequency)
554 {
555 /* Set FLASH latency to lowest latency */
556 status = LL_SetFlashLatency(hclk_frequency);
557 }
558
559 /* Update SystemCoreClock variable */
560 if (status == SUCCESS)
561 {
562 LL_SetSystemCoreClock(hclk_frequency);
563 }
564
565 return status;
566 }
567
568 /**
569 * @}
570 */
571
572 /**
573 * @}
574 */
575
576 /**
577 * @}
578 */
579
580 /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
581