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 with HCLK as SysTick clock source.
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 configures the Cortex-M SysTick source to have 1ms time base with HCLK/8 as SysTick clock source.
151 * @note When a RTOS is used, it is recommended to avoid changing the Systick
152 * configuration by calling this function, for a delay use rather osDelay RTOS service.
153 * @param HCLKFrequency HCLK frequency in Hz
154 * @retval None
155 */
LL_Init1msTick_HCLK_Div8(uint32_t HCLKFrequency)156 void LL_Init1msTick_HCLK_Div8(uint32_t HCLKFrequency)
157 {
158 /* Configure the SysTick to have 1ms time base with HCLK/8 as SysTick clock source */
159 SysTick->LOAD = (uint32_t)((HCLKFrequency / 8000U) - 1UL);
160 SysTick->VAL = 0UL;
161 SysTick->CTRL = SysTick_CTRL_ENABLE_Msk;
162 }
163
164 /**
165 * @brief This function configures the Cortex-M SysTick source to have 1ms time base with LSE as SysTick clock source.
166 * @note When a RTOS is used, it is recommended to avoid changing the Systick
167 * configuration by calling this function, for a delay use rather osDelay RTOS service.
168 * @retval None
169 */
LL_Init1msTick_LSE(void)170 void LL_Init1msTick_LSE(void)
171 {
172 /* Configure the SysTick to have 1ms time base with LSE as SysTick clock source */
173 SysTick->LOAD = (uint32_t)((LSE_VALUE / 1000U) - 1UL);
174 SysTick->VAL = 0UL;
175 SysTick->CTRL = SysTick_CTRL_ENABLE_Msk;
176 }
177
178 /**
179 * @brief This function configures the Cortex-M SysTick source to have 1ms time base with LSI as SysTick clock source.
180 * @note When a RTOS is used, it is recommended to avoid changing the Systick
181 * configuration by calling this function, for a delay use rather osDelay RTOS service.
182 * @retval None
183 */
LL_Init1msTick_LSI(void)184 void LL_Init1msTick_LSI(void)
185 {
186 /* Configure the SysTick to have 1ms time base with LSI as SysTick clock source */
187 SysTick->LOAD = (uint32_t)((LSI_VALUE / 1000U) - 1UL);
188 SysTick->VAL = 0UL;
189 SysTick->CTRL = SysTick_CTRL_ENABLE_Msk;
190 }
191
192 /**
193 * @brief This function provides minimum delay (in milliseconds) based
194 * on SysTick counter flag
195 * @note When a RTOS is used, it is recommended to avoid using blocking delay
196 * and use rather osDelay service.
197 * @note To respect 1ms timebase, user should call @ref LL_Init1msTick function which
198 * will configure Systick to 1ms
199 * @param Delay specifies the minimum delay time length, in milliseconds.
200 * @retval None
201 */
LL_mDelay(uint32_t Delay)202 void LL_mDelay(uint32_t Delay)
203 {
204 __IO uint32_t tmp = SysTick->CTRL; /* Clear the COUNTFLAG first */
205 uint32_t tmpDelay = Delay;
206
207 /* Add this code to indicate that local variable is not used */
208 ((void)tmp);
209
210 /* Add a period to guaranty minimum wait */
211 if (tmpDelay < LL_MAX_DELAY)
212 {
213 tmpDelay++;
214 }
215
216 while (tmpDelay != 0U)
217 {
218 if ((SysTick->CTRL & SysTick_CTRL_COUNTFLAG_Msk) != 0U)
219 {
220 tmpDelay--;
221 }
222 }
223 }
224
225 /**
226 * @}
227 */
228
229 /** @addtogroup UTILS_EF_SYSTEM
230 * @brief System Configuration functions
231 *
232 @verbatim
233 ===============================================================================
234 ##### System Configuration functions #####
235 ===============================================================================
236 [..]
237 System, AHB and APB buses clocks configuration
238
239 (+) The maximum frequency of the SYSCLK, HCLK, PCLK1 and PCLK2, PCLK7 is
240 100000000 Hz.
241 @endverbatim
242 @internal
243 Depending on the device voltage range, the maximum frequency should be
244 adapted accordingly:
245
246 (++) Table 1. HCLK clock frequency for STM32WBA devices
247 (++) +----------------------------------------------------------+
248 (++) | Latency | HCLK clock frequency (MHz) |
249 (++) | |--------------------------------------|
250 (++) | | voltage range 1 | voltage range 2 |
251 (++) | | 1.2 V | 1.1 V |
252 (++) |-------------------|-------------------|------------------|
253 (++) |0 WS (1 CPU cycles)| 0 < HCLK <= 32 | 0 < HCLK <= 8 |
254 (++) |-------------------|-------------------|------------------|
255 (++) |1 WS (2 CPU cycles)| 32 < HCLK <= 64 | 25 < HCLK <= 16 |
256 (++) |-------------------|-------------------|------------------|
257 (++) |2 WS (3 CPU cycles)| 64 < HCLK <= 96 | 50 < HCLK <= 24 |
258 (++) |-------------------|-------------------|------------------|
259 (++) |3 WS (4 CPU cycles)| 96 < HCLK <= 100 |
260 (++) |-------------------|-------------------|
261
262
263 @endinternal
264 * @{
265 */
266
267 /**
268 * @brief This function sets directly SystemCoreClock CMSIS variable.
269 * @note Variable can be calculated also through SystemCoreClockUpdate function.
270 * @param HCLKFrequency HCLK frequency in Hz (can be calculated thanks to RCC helper macro)
271 * @retval None
272 */
LL_SetSystemCoreClock(uint32_t HCLKFrequency)273 void LL_SetSystemCoreClock(uint32_t HCLKFrequency)
274 {
275 /* HCLK clock frequency */
276 SystemCoreClock = HCLKFrequency;
277 }
278
279
280
281 /**
282 * @brief This function configures system clock at maximum frequency with HSI as clock source of the PLL
283 * @note The application need to ensure that PLL1, PLL2 and/or PLL3 are disabled.
284 * @note Function is based on the following formula:
285 * - PLL output frequency = (((HSI frequency / PLLM) * PLLN) / PLLR)
286 * - PLL1M: ensure that the VCO input frequency ranges from 4 to 16 MHz (PLL1VCO_input = HSI frequency / PLL1M)
287 * - PLL1N: ensure that the VCO output frequency is between 128 and 544 MHz
288 (PLL1VCO_output = PLL1VCO_input * PLL1N)
289 * - PLL1R: ensure that max frequency at 100 MHz is reached (PLL1VCO_output / PLL1R)
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_PLL1_ConfigSystemClock_HSI(LL_UTILS_PLLInitTypeDef * UTILS_PLLInitStruct,LL_UTILS_ClkInitTypeDef * UTILS_ClkInitStruct)298 ErrorStatus LL_PLL1_ConfigSystemClock_HSI(LL_UTILS_PLLInitTypeDef *UTILS_PLLInitStruct,
299 LL_UTILS_ClkInitTypeDef *UTILS_ClkInitStruct)
300 {
301 ErrorStatus status;
302 uint32_t pllfreq;
303
304 /* Check if one of the PLL is enabled */
305 if (UTILS_PLL_IsBusy() == SUCCESS)
306 {
307 /* Calculate the new PLL output frequency */
308 pllfreq = UTILS_GetPLLOutputFrequency(HSI_VALUE, UTILS_PLLInitStruct);
309
310 /* Enable HSI if not enabled */
311 if (LL_RCC_HSI_IsReady() != 1U)
312 {
313 LL_RCC_HSI_Enable();
314 while (LL_RCC_HSI_IsReady() != 1U)
315 {
316 /* Wait for HSI ready */
317 }
318 }
319
320 /* Configure PLL */
321 LL_RCC_PLL1_ConfigDomain_SYS(LL_RCC_PLL1SOURCE_HSI, UTILS_PLLInitStruct->PLLM, UTILS_PLLInitStruct->PLLN,
322 UTILS_PLLInitStruct->PLLR);
323
324 /* Enable PLL and switch system clock to PLL */
325 status = UTILS_EnablePLLAndSwitchSystem(pllfreq, UTILS_ClkInitStruct);
326 }
327 else
328 {
329 /* Current PLL configuration cannot be modified */
330 status = ERROR;
331 }
332
333 return status;
334 }
335
336 /**
337 * @brief This function configures system clock with HSE as clock source of the PLL
338 * @note The application need to ensure that PLL, PLLSAI1 and/or PLLSAI2 are disabled.
339 * @note Function is based on the following formula:
340 * - PLL output frequency = (((HSE frequency / PLLM) * PLLN) / PLLR)
341 * - PLL1M: ensure that the VCO input frequency ranges from 4 to 16 MHz (PLL1VCO_input = HSE frequency / PLL1M)
342 * - PLL1N: ensure that the VCO output frequency is between 128 and 544 MHz
343 (PLL1VCO_output = PLL1VCO_input * PLL1N)
344 * - PLL1R: ensure that max frequency at 100 MHz is reached (PLL1VCO_output / PLL1R)
345 * @param HSEFrequency Value at 32000000
346 * @param UTILS_PLLInitStruct pointer to a @ref LL_UTILS_PLLInitTypeDef structure that contains
347 * the configuration information for the PLL.
348 * @param UTILS_ClkInitStruct pointer to a @ref LL_UTILS_ClkInitTypeDef structure that contains
349 * the configuration information for the BUS prescalers.
350 * @retval An ErrorStatus enumeration value:
351 * - SUCCESS: Max frequency configuration done
352 * - ERROR: Max frequency configuration not done
353 */
LL_PLL1_ConfigSystemClock_HSE(uint32_t HSEFrequency,LL_UTILS_PLLInitTypeDef * UTILS_PLLInitStruct,LL_UTILS_ClkInitTypeDef * UTILS_ClkInitStruct)354 ErrorStatus LL_PLL1_ConfigSystemClock_HSE(uint32_t HSEFrequency,
355 LL_UTILS_PLLInitTypeDef *UTILS_PLLInitStruct,
356 LL_UTILS_ClkInitTypeDef *UTILS_ClkInitStruct)
357 {
358 ErrorStatus status;
359 uint32_t pllfreq;
360
361 /* Check the parameters */
362 assert_param(IS_LL_UTILS_HSE_FREQUENCY(HSEFrequency));
363
364 /* Check if one of the PLL is enabled */
365 if (UTILS_PLL_IsBusy() == SUCCESS)
366 {
367 /* Calculate the new PLL output frequency */
368 pllfreq = UTILS_GetPLLOutputFrequency(HSEFrequency, UTILS_PLLInitStruct);
369
370 /* Enable HSE if not enabled */
371 if (LL_RCC_HSE_IsReady() != 1U)
372 {
373 /* Enable HSE */
374 LL_RCC_HSE_Enable();
375 while (LL_RCC_HSE_IsReady() != 1U)
376 {
377 /* Wait for HSE ready */
378 }
379 }
380
381 /* Configure PLL */
382 LL_RCC_PLL1_ConfigDomain_SYS(LL_RCC_PLL1SOURCE_HSE, UTILS_PLLInitStruct->PLLM, UTILS_PLLInitStruct->PLLN,
383 UTILS_PLLInitStruct->PLLR);
384
385 /* Enable PLL and switch system clock to PLL */
386 status = UTILS_EnablePLLAndSwitchSystem(pllfreq, UTILS_ClkInitStruct);
387 }
388 else
389 {
390 /* Current PLL configuration cannot be modified */
391 status = ERROR;
392 }
393
394 return status;
395 }
396
397 /**
398 * @}
399 */
400
401 /**
402 * @}
403 */
404
405 /**
406 * @brief Update number of Flash wait states in line with new frequency and current
407 voltage range.
408 * @param HCLK_Frequency HCLK frequency
409 * @retval An ErrorStatus enumeration value:
410 * - SUCCESS: Latency has been modified
411 * - ERROR: Latency cannot be modified
412 */
LL_SetFlashLatency(uint32_t HCLK_Frequency)413 ErrorStatus LL_SetFlashLatency(uint32_t HCLK_Frequency)
414 {
415 ErrorStatus status = SUCCESS;
416 uint32_t latency;
417
418 /* Frequency cannot be equal to 0 */
419 if (HCLK_Frequency == 0U)
420 {
421 status = ERROR;
422 }
423 else
424 {
425 if (LL_PWR_GetRegulVoltageScaling() == LL_PWR_REGU_VOLTAGE_SCALE1)
426 {
427 if ((HCLK_Frequency > UTILS_SCALE1_LATENCY2_FREQ) && (HCLK_Frequency <= UTILS_SCALE1_LATENCY3_FREQ))
428 {
429 /* 96MHz < HCLK <= 100MHz => 3WS (4 CPU cycles) */
430 latency = LL_FLASH_LATENCY_3;
431 }
432 else if ((HCLK_Frequency > UTILS_SCALE1_LATENCY1_FREQ) && (HCLK_Frequency <= UTILS_SCALE1_LATENCY2_FREQ))
433 {
434 /* 64MHz < HCLK <= 96MHz => 2WS (3 CPU cycles) */
435 latency = LL_FLASH_LATENCY_2;
436 }
437 else if ((HCLK_Frequency > UTILS_SCALE1_LATENCY0_FREQ) && (HCLK_Frequency <= UTILS_SCALE1_LATENCY1_FREQ))
438 {
439 /* 32MHz < HCLK <= 64MHz => 1WS (2 CPU cycles) */
440 latency = LL_FLASH_LATENCY_1;
441 }
442 else if (HCLK_Frequency <= UTILS_SCALE1_LATENCY0_FREQ)
443 {
444 /* HCLK <= 32MHz => 0WS (1 CPU cycle) */
445 latency = LL_FLASH_LATENCY_0;
446 }
447 else
448 {
449 status = ERROR;
450 }
451 }
452 else /* LL_PWR_GetRegulVoltageScaling() == LL_PWR_REGU_VOLTAGE_SCALE2 */
453 {
454 if ((HCLK_Frequency > UTILS_SCALE2_LATENCY0_FREQ) && (HCLK_Frequency <= UTILS_SCALE2_LATENCY1_FREQ))
455 {
456 /* 8MHz < HCLK <= 16MHz => 1WS (2 CPU cycles) */
457 latency = LL_FLASH_LATENCY_1;
458 }
459 else if (HCLK_Frequency <= UTILS_SCALE2_LATENCY0_FREQ)
460 {
461 /* HCLK <= 8MHz => 0WS (1 CPU cycle) */
462 latency = LL_FLASH_LATENCY_0;
463 }
464 else
465 {
466 status = ERROR;
467 }
468 }
469 }
470
471 if (status == SUCCESS)
472 {
473 LL_FLASH_SetLatency(latency);
474
475 /* Check that the new number of wait states is taken into account to access the Flash
476 memory by reading the FLASH_ACR register */
477 if (LL_FLASH_GetLatency() != latency)
478 {
479 status = ERROR;
480 }
481 }
482
483 return status;
484 }
485
486 /** @addtogroup UTILS_LL_Private_Functions
487 * @{
488 */
489 /**
490 * @brief Function to check that PLL can be modified
491 * @param PLL_InputFrequency PLL input frequency (in Hz)
492 * @param UTILS_PLLInitStruct pointer to a @ref LL_UTILS_PLLInitTypeDef structure that contains
493 * the configuration information for the PLL.
494 * @retval PLL output frequency (in Hz)
495 */
UTILS_GetPLLOutputFrequency(uint32_t PLL_InputFrequency,const LL_UTILS_PLLInitTypeDef * UTILS_PLLInitStruct)496 static uint32_t UTILS_GetPLLOutputFrequency(uint32_t PLL_InputFrequency, const LL_UTILS_PLLInitTypeDef *UTILS_PLLInitStruct)
497 {
498 uint32_t pllfreq;
499
500 /* Check the parameters */
501 assert_param(IS_LL_UTILS_PLLM_VALUE(UTILS_PLLInitStruct->PLLM));
502 assert_param(IS_LL_UTILS_PLLN_VALUE(UTILS_PLLInitStruct->PLLN));
503 assert_param(IS_LL_UTILS_PLLR_VALUE(UTILS_PLLInitStruct->PLLR));
504
505 /* Check different PLL parameters according to RM */
506 /* - PLLM: ensure that the VCO input frequency ranges from 4 to 16 MHz. */
507 pllfreq = PLL_InputFrequency / (UTILS_PLLInitStruct->PLLM);
508 assert_param(IS_LL_UTILS_PLLVCO_INPUT(pllfreq));
509
510 /* - PLLN: ensure that the VCO output frequency is between 128 and 544 MHz.*/
511 pllfreq = pllfreq * (UTILS_PLLInitStruct->PLLN);
512 assert_param(IS_LL_UTILS_PLLVCO_OUTPUT(pllfreq));
513
514 /* - PLLR: ensure that max frequency at 100 MHz is reached */
515 pllfreq = pllfreq / (UTILS_PLLInitStruct->PLLR);
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 PLL1 is busy*/
532 if (LL_RCC_PLL1_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,
551 LL_UTILS_ClkInitTypeDef *UTILS_ClkInitStruct)
552 {
553 ErrorStatus status = SUCCESS;
554 uint32_t hclk_frequency;
555
556 assert_param(IS_LL_UTILS_SYSCLK_DIV(UTILS_ClkInitStruct->AHBCLKDivider));
557 assert_param(IS_LL_UTILS_APB1_DIV(UTILS_ClkInitStruct->APB1CLKDivider));
558 assert_param(IS_LL_UTILS_APB2_DIV(UTILS_ClkInitStruct->APB2CLKDivider));
559 assert_param(IS_LL_UTILS_APB7_DIV(UTILS_ClkInitStruct->APB7CLKDivider));
560
561 /* Calculate HCLK frequency */
562 hclk_frequency = __LL_RCC_CALC_HCLK_FREQ(SYSCLK_Frequency, UTILS_ClkInitStruct->AHBCLKDivider);
563
564 /* Increasing the number of wait states because of higher CPU frequency */
565 if (SystemCoreClock < hclk_frequency)
566 {
567 /* Set FLASH latency to highest latency */
568 status = LL_SetFlashLatency(hclk_frequency);
569 }
570
571 /* Update system clock configuration */
572 if (status == SUCCESS)
573 {
574 /* Enable PLL1 */
575 LL_RCC_PLL1_Enable();
576 LL_RCC_PLL1_EnableDomain_PLL1R();
577 while (LL_RCC_PLL1_IsReady() != 1U)
578 {
579 /* Wait for PLL ready */
580 }
581
582 /* Sysclk activation on the main PLL */
583 LL_RCC_SetAHBPrescaler(UTILS_ClkInitStruct->AHBCLKDivider);
584 LL_RCC_SetSysClkSource(LL_RCC_SYS_CLKSOURCE_PLL1R);
585 while (LL_RCC_GetSysClkSource() != LL_RCC_SYS_CLKSOURCE_STATUS_PLL1R)
586 {
587 /* Wait for system clock switch to PLL */
588 }
589
590 /* Set APB1, APB2 & APB7 prescaler*/
591 LL_RCC_SetAPB1Prescaler(UTILS_ClkInitStruct->APB1CLKDivider);
592 LL_RCC_SetAPB2Prescaler(UTILS_ClkInitStruct->APB2CLKDivider);
593 LL_RCC_SetAPB7Prescaler(UTILS_ClkInitStruct->APB7CLKDivider);
594 }
595
596 /* Decreasing the number of wait states because of lower CPU frequency */
597 if (SystemCoreClock > hclk_frequency)
598 {
599 /* Set FLASH latency to lowest latency */
600 status = LL_SetFlashLatency(hclk_frequency);
601 }
602
603 /* Update SystemCoreClock variable */
604 if (status == SUCCESS)
605 {
606 LL_SetSystemCoreClock(hclk_frequency);
607 }
608
609 return status;
610 }
611
612 /**
613 * @}
614 */
615
616 /**
617 * @}
618 */
619
620 /**
621 * @}
622 */
623
624