1 /**
2 ******************************************************************************
3 * @file stm32wbaxx_ll_utils.c
4 * @author MCD Application Team
5 * @brief UTILS LL module driver.
6 ******************************************************************************
7 * @attention
8 *
9 * Copyright (c) 2022 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 "stm32wbaxx_ll_utils.h"
20 #include "stm32wbaxx_ll_rcc.h"
21 #include "stm32wbaxx_ll_system.h"
22 #include "stm32wbaxx_ll_pwr.h"
23 #include <math.h>
24 #ifdef USE_FULL_ASSERT
25 #include "stm32_assert.h"
26 #else
27 #define assert_param(expr) ((void)0U)
28 #endif /* USE_FULL_ASSERT */
29
30 /** @addtogroup STM32WBAxx_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 100000000U /*!< 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
47 /* Defines used for PLL range */
48 #define UTILS_PLLVCO_INPUT_MIN 4000000U /*!< Frequency min for PLLVCO input, in Hz */
49 #define UTILS_PLLVCO_INPUT_MAX 16000000U /*!< Frequency max for PLLVCO input, in Hz */
50 #define UTILS_PLLVCO_OUTPUT_MIN 128000000U /*!< Frequency min for PLLVCO output, in Hz */
51 #define UTILS_PLLVCO_OUTPUT_MAX 544000000U /*!< Frequency max for PLLVCO output, in Hz */
52
53 /* Defines used for FLASH latency according to HCLK Frequency */
54 #define UTILS_SCALE1_LATENCY0_FREQ 32000000U /*!< HCLK frequency to set FLASH latency 0 in power scale 1 */
55 #define UTILS_SCALE1_LATENCY1_FREQ 64000000U /*!< HCLK frequency to set FLASH latency 1 in power scale 1 */
56 #define UTILS_SCALE1_LATENCY2_FREQ 96000000U /*!< HCLK frequency to set FLASH latency 2 in power scale 1 */
57 #define UTILS_SCALE1_LATENCY3_FREQ 100000000U /*!< HCLK frequency to set FLASH latency 3 in power scale 1 */
58 #define UTILS_SCALE2_LATENCY0_FREQ 8000000U /*!< HCLK frequency to set FLASH latency 0 in power scale 2 */
59 #define UTILS_SCALE2_LATENCY1_FREQ 16000000U /*!< HCLK frequency to set FLASH latency 1 in power scale 2 */
60
61 /**
62 * @}
63 */
64
65 /* Private macros ------------------------------------------------------------*/
66 /** @addtogroup UTILS_LL_Private_Macros
67 * @{
68 */
69 #define IS_LL_UTILS_SYSCLK_DIV(__VALUE__) (((__VALUE__) == LL_RCC_SYSCLK_DIV_1) \
70 || ((__VALUE__) == LL_RCC_SYSCLK_DIV_2) \
71 || ((__VALUE__) == LL_RCC_SYSCLK_DIV_4) \
72 || ((__VALUE__) == LL_RCC_SYSCLK_DIV_8) \
73 || ((__VALUE__) == LL_RCC_SYSCLK_DIV_16))
74
75 #define IS_LL_UTILS_APB1_DIV(__VALUE__) (((__VALUE__) == LL_RCC_APB1_DIV_1) \
76 || ((__VALUE__) == LL_RCC_APB1_DIV_2) \
77 || ((__VALUE__) == LL_RCC_APB1_DIV_4) \
78 || ((__VALUE__) == LL_RCC_APB1_DIV_8) \
79 || ((__VALUE__) == LL_RCC_APB1_DIV_16))
80
81 #define IS_LL_UTILS_APB2_DIV(__VALUE__) (((__VALUE__) == LL_RCC_APB2_DIV_1) \
82 || ((__VALUE__) == LL_RCC_APB2_DIV_2) \
83 || ((__VALUE__) == LL_RCC_APB2_DIV_4) \
84 || ((__VALUE__) == LL_RCC_APB2_DIV_8) \
85 || ((__VALUE__) == LL_RCC_APB2_DIV_16))
86
87 #define IS_LL_UTILS_APB7_DIV(__VALUE__) (((__VALUE__) == LL_RCC_APB7_DIV_1) \
88 || ((__VALUE__) == LL_RCC_APB7_DIV_2) \
89 || ((__VALUE__) == LL_RCC_APB7_DIV_4) \
90 || ((__VALUE__) == LL_RCC_APB7_DIV_8) \
91 || ((__VALUE__) == LL_RCC_APB7_DIV_16))
92
93 #define IS_LL_UTILS_PLLM_VALUE(__VALUE__) ((1U <= (__VALUE__)) && ((__VALUE__) <= 16U))
94
95 #define IS_LL_UTILS_PLLN_VALUE(__VALUE__) ((4U <= (__VALUE__)) && ((__VALUE__) <= 512U))
96
97 #define IS_LL_UTILS_PLLR_VALUE(__VALUE__) ((1U <= (__VALUE__)) && ((__VALUE__) <= 128U))
98
99 #define IS_LL_UTILS_PLLVCO_INPUT(__VALUE__) ((UTILS_PLLVCO_INPUT_MIN <= (__VALUE__))\
100 && ((__VALUE__) <= UTILS_PLLVCO_INPUT_MAX))
101
102 #define IS_LL_UTILS_PLLVCO_OUTPUT(__VALUE__) ((UTILS_PLLVCO_OUTPUT_MIN <= (__VALUE__))\
103 && ((__VALUE__) <= UTILS_PLLVCO_OUTPUT_MAX))
104
105 #define IS_LL_UTILS_PLL_FREQUENCY(__VALUE__) ((LL_PWR_GetRegulVoltageScaling() == LL_PWR_REGU_VOLTAGE_SCALE1) ? \
106 ((__VALUE__) <= UTILS_MAX_FREQUENCY_SCALE1) : \
107 ((__VALUE__) <= UTILS_MAX_FREQUENCY_SCALE2))
108
109 #define IS_LL_UTILS_HSE_FREQUENCY(__FREQUENCY__) ((__FREQUENCY__) == 32000000U)
110 /**
111 * @}
112 */
113 /* Private function prototypes -----------------------------------------------*/
114 /** @defgroup UTILS_LL_Private_Functions UTILS Private functions
115 * @{
116 */
117 static uint32_t UTILS_GetPLLOutputFrequency(uint32_t PLL_InputFrequency,
118 const LL_UTILS_PLLInitTypeDef *UTILS_PLLInitStruct);
119 static ErrorStatus UTILS_EnablePLLAndSwitchSystem(uint32_t SYSCLK_Frequency,
120 LL_UTILS_ClkInitTypeDef *UTILS_ClkInitStruct);
121 static ErrorStatus UTILS_PLL_IsBusy(void);
122 /**
123 * @}
124 */
125
126 /* Exported functions --------------------------------------------------------*/
127 /** @addtogroup UTILS_LL_Exported_Functions
128 * @{
129 */
130
131 /** @addtogroup UTILS_LL_EF_DELAY
132 * @{
133 */
134
135 /**
136 * @brief This function configures the Cortex-M SysTick source to have 1ms time base.
137 * @note When a RTOS is used, it is recommended to avoid changing the Systick
138 * configuration by calling this function, for a delay use rather osDelay RTOS service.
139 * @param HCLKFrequency HCLK frequency in Hz
140 * @note HCLK frequency can be calculated thanks to RCC helper macro or function @ref LL_RCC_GetSystemClocksFreq
141 * @retval None
142 */
LL_Init1msTick(uint32_t HCLKFrequency)143 void LL_Init1msTick(uint32_t HCLKFrequency)
144 {
145 /* Use frequency provided in argument */
146 LL_InitTick(HCLKFrequency, 1000U);
147 }
148
149 /**
150 * @brief This function provides accurate delay (in milliseconds) based
151 * on SysTick counter flag
152 * @note When a RTOS is used, it is recommended to avoid using blocking delay
153 * and use rather osDelay service.
154 * @note To respect 1ms timebase, user should call @ref LL_Init1msTick function which
155 * will configure Systick to 1ms
156 * @param Delay specifies the delay time length, in milliseconds.
157 * @retval None
158 */
159
LL_mDelay(uint32_t Delay)160 void LL_mDelay(uint32_t Delay)
161 {
162 __IO uint32_t tmp = SysTick->CTRL; /* Clear the COUNTFLAG first */
163 uint32_t tmpDelay = Delay;
164
165 /* Add this code to indicate that local variable is not used */
166 ((void)tmp);
167
168 /* Add a period to guaranty minimum wait */
169 if (tmpDelay < LL_MAX_DELAY)
170 {
171 tmpDelay++;
172 }
173
174 while (tmpDelay != 0U)
175 {
176 if ((SysTick->CTRL & SysTick_CTRL_COUNTFLAG_Msk) != 0U)
177 {
178 tmpDelay--;
179 }
180 }
181 }
182
183 /**
184 * @}
185 */
186
187 /** @addtogroup UTILS_EF_SYSTEM
188 * @brief System Configuration functions
189 *
190 @verbatim
191 ===============================================================================
192 ##### System Configuration functions #####
193 ===============================================================================
194 [..]
195 System, AHB and APB buses clocks configuration
196
197 (+) The maximum frequency of the SYSCLK, HCLK, PCLK1 and PCLK2, PCLK7 is
198 100000000 Hz.
199 @endverbatim
200 @internal
201 Depending on the device voltage range, the maximum frequency should be
202 adapted accordingly:
203
204 (++) Table 1. HCLK clock frequency for STM32WBA devices
205 (++) +----------------------------------------------------------+
206 (++) | Latency | HCLK clock frequency (MHz) |
207 (++) | |--------------------------------------|
208 (++) | | voltage range 1 | voltage range 2 |
209 (++) | | 1.2 V | 1.1 V |
210 (++) |-------------------|-------------------|------------------|
211 (++) |0 WS (1 CPU cycles)| 0 < HCLK <= 32 | 0 < HCLK <= 8 |
212 (++) |-------------------|-------------------|------------------|
213 (++) |1 WS (2 CPU cycles)| 32 < HCLK <= 64 | 25 < HCLK <= 16 |
214 (++) |-------------------|-------------------|------------------|
215 (++) |2 WS (3 CPU cycles)| 64 < HCLK <= 96 | 50 < HCLK <= 24 |
216 (++) |-------------------|-------------------|------------------|
217 (++) |3 WS (4 CPU cycles)| 96 < HCLK <= 100 |
218 (++) |-------------------|-------------------|
219
220
221 @endinternal
222 * @{
223 */
224
225 /**
226 * @brief This function sets directly SystemCoreClock CMSIS variable.
227 * @note Variable can be calculated also through SystemCoreClockUpdate function.
228 * @param HCLKFrequency HCLK frequency in Hz (can be calculated thanks to RCC helper macro)
229 * @retval None
230 */
LL_SetSystemCoreClock(uint32_t HCLKFrequency)231 void LL_SetSystemCoreClock(uint32_t HCLKFrequency)
232 {
233 /* HCLK clock frequency */
234 SystemCoreClock = HCLKFrequency;
235 }
236
237
238
239 /**
240 * @brief This function configures system clock at maximum frequency with HSI as clock source of the PLL
241 * @note The application need to ensure that PLL1, PLL2 and/or PLL3 are disabled.
242 * @note Function is based on the following formula:
243 * - PLL output frequency = (((HSI frequency / PLLM) * PLLN) / PLLR)
244 * - PLL1M: ensure that the VCO input frequency ranges from 4 to 16 MHz (PLL1VCO_input = HSI frequency / PLL1M)
245 * - PLL1N: ensure that the VCO output frequency is between 128 and 544 MHz
246 (PLL1VCO_output = PLL1VCO_input * PLL1N)
247 * - PLL1R: ensure that max frequency at 100 MHz is reached (PLL1VCO_output / PLL1R)
248 * @param UTILS_PLLInitStruct pointer to a @ref LL_UTILS_PLLInitTypeDef structure that contains
249 * the configuration information for the PLL.
250 * @param UTILS_ClkInitStruct pointer to a @ref LL_UTILS_ClkInitTypeDef structure that contains
251 * the configuration information for the BUS prescalers.
252 * @retval An ErrorStatus enumeration value:
253 * - SUCCESS: Max frequency configuration done
254 * - ERROR: Max frequency configuration not done
255 */
LL_PLL1_ConfigSystemClock_HSI(LL_UTILS_PLLInitTypeDef * UTILS_PLLInitStruct,LL_UTILS_ClkInitTypeDef * UTILS_ClkInitStruct)256 ErrorStatus LL_PLL1_ConfigSystemClock_HSI(LL_UTILS_PLLInitTypeDef *UTILS_PLLInitStruct,
257 LL_UTILS_ClkInitTypeDef *UTILS_ClkInitStruct)
258 {
259 ErrorStatus status;
260 uint32_t pllfreq;
261
262 /* Check if one of the PLL is enabled */
263 if (UTILS_PLL_IsBusy() == SUCCESS)
264 {
265 /* Calculate the new PLL output frequency */
266 pllfreq = UTILS_GetPLLOutputFrequency(HSI_VALUE, UTILS_PLLInitStruct);
267
268 /* Enable HSI if not enabled */
269 if (LL_RCC_HSI_IsReady() != 1U)
270 {
271 LL_RCC_HSI_Enable();
272 while (LL_RCC_HSI_IsReady() != 1U)
273 {
274 /* Wait for HSI ready */
275 }
276 }
277
278 /* Configure PLL */
279 LL_RCC_PLL1_ConfigDomain_SYS(LL_RCC_PLL1SOURCE_HSI, UTILS_PLLInitStruct->PLLM, UTILS_PLLInitStruct->PLLN,
280 UTILS_PLLInitStruct->PLLR);
281
282 /* Enable PLL and switch system clock to PLL */
283 status = UTILS_EnablePLLAndSwitchSystem(pllfreq, UTILS_ClkInitStruct);
284 }
285 else
286 {
287 /* Current PLL configuration cannot be modified */
288 status = ERROR;
289 }
290
291 return status;
292 }
293
294 /**
295 * @brief This function configures system clock with HSE as clock source of the PLL
296 * @note The application need to ensure that PLL, PLLSAI1 and/or PLLSAI2 are disabled.
297 * @note Function is based on the following formula:
298 * - PLL output frequency = (((HSE frequency / PLLM) * PLLN) / PLLR)
299 * - PLL1M: ensure that the VCO input frequency ranges from 4 to 16 MHz (PLL1VCO_input = HSE frequency / PLL1M)
300 * - PLL1N: ensure that the VCO output frequency is between 128 and 544 MHz
301 (PLL1VCO_output = PLL1VCO_input * PLL1N)
302 * - PLL1R: ensure that max frequency at 100 MHz is reached (PLL1VCO_output / PLL1R)
303 * @param HSEFrequency Value at 32000000
304 * @param UTILS_PLLInitStruct pointer to a @ref LL_UTILS_PLLInitTypeDef structure that contains
305 * the configuration information for the PLL.
306 * @param UTILS_ClkInitStruct pointer to a @ref LL_UTILS_ClkInitTypeDef structure that contains
307 * the configuration information for the BUS prescalers.
308 * @retval An ErrorStatus enumeration value:
309 * - SUCCESS: Max frequency configuration done
310 * - ERROR: Max frequency configuration not done
311 */
LL_PLL1_ConfigSystemClock_HSE(uint32_t HSEFrequency,LL_UTILS_PLLInitTypeDef * UTILS_PLLInitStruct,LL_UTILS_ClkInitTypeDef * UTILS_ClkInitStruct)312 ErrorStatus LL_PLL1_ConfigSystemClock_HSE(uint32_t HSEFrequency,
313 LL_UTILS_PLLInitTypeDef *UTILS_PLLInitStruct,
314 LL_UTILS_ClkInitTypeDef *UTILS_ClkInitStruct)
315 {
316 ErrorStatus status;
317 uint32_t pllfreq;
318
319 /* Check the parameters */
320 assert_param(IS_LL_UTILS_HSE_FREQUENCY(HSEFrequency));
321
322 /* Check if one of the PLL is enabled */
323 if (UTILS_PLL_IsBusy() == SUCCESS)
324 {
325 /* Calculate the new PLL output frequency */
326 pllfreq = UTILS_GetPLLOutputFrequency(HSEFrequency, UTILS_PLLInitStruct);
327
328 /* Enable HSE if not enabled */
329 if (LL_RCC_HSE_IsReady() != 1U)
330 {
331 /* Enable HSE */
332 LL_RCC_HSE_Enable();
333 while (LL_RCC_HSE_IsReady() != 1U)
334 {
335 /* Wait for HSE ready */
336 }
337 }
338
339 /* Configure PLL */
340 LL_RCC_PLL1_ConfigDomain_SYS(LL_RCC_PLL1SOURCE_HSE, UTILS_PLLInitStruct->PLLM, UTILS_PLLInitStruct->PLLN,
341 UTILS_PLLInitStruct->PLLR);
342
343 /* Enable PLL and switch system clock to PLL */
344 status = UTILS_EnablePLLAndSwitchSystem(pllfreq, UTILS_ClkInitStruct);
345 }
346 else
347 {
348 /* Current PLL configuration cannot be modified */
349 status = ERROR;
350 }
351
352 return status;
353 }
354
355 /**
356 * @}
357 */
358
359 /**
360 * @}
361 */
362
363 /**
364 * @brief Update number of Flash wait states in line with new frequency and current
365 voltage range.
366 * @param HCLK_Frequency HCLK frequency
367 * @retval An ErrorStatus enumeration value:
368 * - SUCCESS: Latency has been modified
369 * - ERROR: Latency cannot be modified
370 */
LL_SetFlashLatency(uint32_t HCLK_Frequency)371 ErrorStatus LL_SetFlashLatency(uint32_t HCLK_Frequency)
372 {
373 ErrorStatus status = SUCCESS;
374 uint32_t latency;
375
376 /* Frequency cannot be equal to 0 */
377 if (HCLK_Frequency == 0U)
378 {
379 status = ERROR;
380 }
381 else
382 {
383 if (LL_PWR_GetRegulVoltageScaling() == LL_PWR_REGU_VOLTAGE_SCALE1)
384 {
385 if ((HCLK_Frequency > UTILS_SCALE1_LATENCY2_FREQ) && (HCLK_Frequency <= UTILS_SCALE1_LATENCY3_FREQ))
386 {
387 /* 96MHz < HCLK <= 100MHz => 3WS (4 CPU cycles) */
388 latency = LL_FLASH_LATENCY_3;
389 }
390 else if ((HCLK_Frequency > UTILS_SCALE1_LATENCY1_FREQ) && (HCLK_Frequency <= UTILS_SCALE1_LATENCY2_FREQ))
391 {
392 /* 64MHz < HCLK <= 96MHz => 2WS (3 CPU cycles) */
393 latency = LL_FLASH_LATENCY_2;
394 }
395 else if ((HCLK_Frequency > UTILS_SCALE1_LATENCY0_FREQ) && (HCLK_Frequency <= UTILS_SCALE1_LATENCY1_FREQ))
396 {
397 /* 32MHz < HCLK <= 64MHz => 1WS (2 CPU cycles) */
398 latency = LL_FLASH_LATENCY_1;
399 }
400 else if (HCLK_Frequency <= UTILS_SCALE1_LATENCY0_FREQ)
401 {
402 /* HCLK <= 32MHz => 0WS (1 CPU cycle) */
403 latency = LL_FLASH_LATENCY_0;
404 }
405 else
406 {
407 status = ERROR;
408 }
409 }
410 else /* LL_PWR_GetRegulVoltageScaling() == LL_PWR_REGU_VOLTAGE_SCALE2 */
411 {
412 if ((HCLK_Frequency > UTILS_SCALE2_LATENCY0_FREQ) && (HCLK_Frequency <= UTILS_SCALE2_LATENCY1_FREQ))
413 {
414 /* 8MHz < HCLK <= 16MHz => 1WS (2 CPU cycles) */
415 latency = LL_FLASH_LATENCY_1;
416 }
417 else if (HCLK_Frequency <= UTILS_SCALE2_LATENCY0_FREQ)
418 {
419 /* HCLK <= 8MHz => 0WS (1 CPU cycle) */
420 latency = LL_FLASH_LATENCY_0;
421 }
422 else
423 {
424 status = ERROR;
425 }
426 }
427 }
428
429 if (status == SUCCESS)
430 {
431 LL_FLASH_SetLatency(latency);
432
433 /* Check that the new number of wait states is taken into account to access the Flash
434 memory by reading the FLASH_ACR register */
435 if (LL_FLASH_GetLatency() != latency)
436 {
437 status = ERROR;
438 }
439 }
440
441 return status;
442 }
443
444 /** @addtogroup UTILS_LL_Private_Functions
445 * @{
446 */
447 /**
448 * @brief Function to check that PLL can be modified
449 * @param PLL_InputFrequency PLL input frequency (in Hz)
450 * @param UTILS_PLLInitStruct pointer to a @ref LL_UTILS_PLLInitTypeDef structure that contains
451 * the configuration information for the PLL.
452 * @retval PLL output frequency (in Hz)
453 */
UTILS_GetPLLOutputFrequency(uint32_t PLL_InputFrequency,const LL_UTILS_PLLInitTypeDef * UTILS_PLLInitStruct)454 static uint32_t UTILS_GetPLLOutputFrequency(uint32_t PLL_InputFrequency, const LL_UTILS_PLLInitTypeDef *UTILS_PLLInitStruct)
455 {
456 uint32_t pllfreq;
457
458 /* Check the parameters */
459 assert_param(IS_LL_UTILS_PLLM_VALUE(UTILS_PLLInitStruct->PLLM));
460 assert_param(IS_LL_UTILS_PLLN_VALUE(UTILS_PLLInitStruct->PLLN));
461 assert_param(IS_LL_UTILS_PLLR_VALUE(UTILS_PLLInitStruct->PLLR));
462
463 /* Check different PLL parameters according to RM */
464 /* - PLLM: ensure that the VCO input frequency ranges from 4 to 16 MHz. */
465 pllfreq = PLL_InputFrequency / (UTILS_PLLInitStruct->PLLM);
466 assert_param(IS_LL_UTILS_PLLVCO_INPUT(pllfreq));
467
468 /* - PLLN: ensure that the VCO output frequency is between 128 and 544 MHz.*/
469 pllfreq = pllfreq * (UTILS_PLLInitStruct->PLLN);
470 assert_param(IS_LL_UTILS_PLLVCO_OUTPUT(pllfreq));
471
472 /* - PLLR: ensure that max frequency at 100 MHz is reached */
473 pllfreq = pllfreq / (UTILS_PLLInitStruct->PLLR);
474 assert_param(IS_LL_UTILS_PLL_FREQUENCY(pllfreq));
475
476 return pllfreq;
477 }
478
479 /**
480 * @brief Function to check that PLL can be modified
481 * @retval An ErrorStatus enumeration value:
482 * - SUCCESS: PLL modification can be done
483 * - ERROR: PLL is busy
484 */
UTILS_PLL_IsBusy(void)485 static ErrorStatus UTILS_PLL_IsBusy(void)
486 {
487 ErrorStatus status = SUCCESS;
488
489 /* Check if PLL1 is busy*/
490 if (LL_RCC_PLL1_IsReady() != 0U)
491 {
492 /* PLL configuration cannot be modified */
493 status = ERROR;
494 }
495
496 return status;
497 }
498
499 /**
500 * @brief Function to enable PLL and switch system clock to PLL
501 * @param SYSCLK_Frequency SYSCLK frequency
502 * @param UTILS_ClkInitStruct pointer to a @ref LL_UTILS_ClkInitTypeDef structure that contains
503 * the configuration information for the BUS prescalers.
504 * @retval An ErrorStatus enumeration value:
505 * - SUCCESS: No problem to switch system to PLL
506 * - ERROR: Problem to switch system to PLL
507 */
UTILS_EnablePLLAndSwitchSystem(uint32_t SYSCLK_Frequency,LL_UTILS_ClkInitTypeDef * UTILS_ClkInitStruct)508 static ErrorStatus UTILS_EnablePLLAndSwitchSystem(uint32_t SYSCLK_Frequency,
509 LL_UTILS_ClkInitTypeDef *UTILS_ClkInitStruct)
510 {
511 ErrorStatus status = SUCCESS;
512 uint32_t hclk_frequency;
513
514 assert_param(IS_LL_UTILS_SYSCLK_DIV(UTILS_ClkInitStruct->AHBCLKDivider));
515 assert_param(IS_LL_UTILS_APB1_DIV(UTILS_ClkInitStruct->APB1CLKDivider));
516 assert_param(IS_LL_UTILS_APB2_DIV(UTILS_ClkInitStruct->APB2CLKDivider));
517 assert_param(IS_LL_UTILS_APB7_DIV(UTILS_ClkInitStruct->APB7CLKDivider));
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 PLL1 */
533 LL_RCC_PLL1_Enable();
534 LL_RCC_PLL1_EnableDomain_PLL1R();
535 while (LL_RCC_PLL1_IsReady() != 1U)
536 {
537 /* Wait for PLL ready */
538 }
539
540 /* Sysclk activation on the main PLL */
541 LL_RCC_SetAHBPrescaler(UTILS_ClkInitStruct->AHBCLKDivider);
542 LL_RCC_SetSysClkSource(LL_RCC_SYS_CLKSOURCE_PLL1R);
543 while (LL_RCC_GetSysClkSource() != LL_RCC_SYS_CLKSOURCE_STATUS_PLL1R)
544 {
545 /* Wait for system clock switch to PLL */
546 }
547
548 /* Set APB1, APB2 & APB7 prescaler*/
549 LL_RCC_SetAPB1Prescaler(UTILS_ClkInitStruct->APB1CLKDivider);
550 LL_RCC_SetAPB2Prescaler(UTILS_ClkInitStruct->APB2CLKDivider);
551 LL_RCC_SetAPB7Prescaler(UTILS_ClkInitStruct->APB7CLKDivider);
552 }
553
554 /* Decreasing the number of wait states because of lower CPU frequency */
555 if (SystemCoreClock > hclk_frequency)
556 {
557 /* Set FLASH latency to lowest latency */
558 status = LL_SetFlashLatency(hclk_frequency);
559 }
560
561 /* Update SystemCoreClock variable */
562 if (status == SUCCESS)
563 {
564 LL_SetSystemCoreClock(hclk_frequency);
565 }
566
567 return status;
568 }
569
570 /**
571 * @}
572 */
573
574 /**
575 * @}
576 */
577
578 /**
579 * @}
580 */
581
582