1 /**
2 ******************************************************************************
3 * @file stm32u5xx_ll_utils.c
4 * @author MCD Application Team
5 * @brief UTILS LL module driver.
6 ******************************************************************************
7 * @attention
8 *
9 * Copyright (c) 2021 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 "stm32u5xx_ll_utils.h"
20 #include "stm32u5xx_ll_rcc.h"
21 #include "stm32u5xx_ll_system.h"
22 #include "stm32u5xx_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 STM32U5xx_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_SCALE0 160000000U /*!< Maximum frequency for system clock at power scale0, in Hz */
45 #define UTILS_MAX_FREQUENCY_SCALE1 100000000U /*!< Maximum frequency for system clock at power scale1, in Hz */
46 #define UTILS_MAX_FREQUENCY_SCALE2 50000000U /*!< Maximum frequency for system clock at power scale2, in Hz */
47 #define UTILS_MAX_FREQUENCY_SCALE3 24000000U /*!< Maximum frequency for system clock at power scale3, in Hz */
48
49 /* Defines used for PLL range */
50 #define UTILS_PLLVCO_INPUT_MIN 4000000U /*!< Frequency min for PLLVCO input, in Hz */
51 #define UTILS_PLLVCO_INPUT_MAX 16000000U /*!< Frequency max for PLLVCO input, in Hz */
52 #define UTILS_PLLVCO_OUTPUT_MIN 64000000U /*!< Frequency min for PLLVCO output, in Hz */
53 #define UTILS_PLLVCO_OUTPUT_MAX 344000000U /*!< Frequency max for PLLVCO output, in Hz */
54
55 /* Defines used for HSE range */
56 #define UTILS_HSE_FREQUENCY_MIN 4000000U /*!< Frequency min for HSE frequency, in Hz */
57 #define UTILS_HSE_FREQUENCY_MAX 50000000U /*!< Frequency max for HSE frequency, in Hz */
58
59 /* Defines used for FLASH latency according to HCLK Frequency */
60 #define UTILS_SCALE1_LATENCY0_FREQ (32000000U) /*!< HCLK frequency to set FLASH latency 0 in power scale 1 */
61 #define UTILS_SCALE1_LATENCY1_FREQ (64000000U) /*!< HCLK frequency to set FLASH latency 1 in power scale 1 */
62 #define UTILS_SCALE1_LATENCY2_FREQ (96000000U) /*!< HCLK frequency to set FLASH latency 2 in power scale 1 */
63 #define UTILS_SCALE1_LATENCY3_FREQ (128000000U) /*!< HCLK frequency to set FLASH latency 3 in power scale 1 */
64 #define UTILS_SCALE1_LATENCY4_FREQ (160000000U) /*!< HCLK frequency to set FLASH latency 4 in power scale 1 */
65 #define UTILS_SCALE2_LATENCY0_FREQ (25000000U) /*!< HCLK frequency to set FLASH latency 0 in power scale 2 */
66 #define UTILS_SCALE2_LATENCY1_FREQ (50000000U) /*!< HCLK frequency to set FLASH latency 1 in power scale 2 */
67 #define UTILS_SCALE2_LATENCY2_FREQ (75000000U) /*!< HCLK frequency to set FLASH latency 2 in power scale 2 */
68 #define UTILS_SCALE2_LATENCY3_FREQ (100000000U) /*!< HCLK frequency to set FLASH latency 3 in power scale 2 */
69 #define UTILS_SCALE3_LATENCY0_FREQ (12500000U) /*!< HCLK frequency to set FLASH latency 0 in power scale 3 */
70 #define UTILS_SCALE3_LATENCY1_FREQ (25000000U) /*!< HCLK frequency to set FLASH latency 1 in power scale 3 */
71 #define UTILS_SCALE3_LATENCY2_FREQ (37500000U) /*!< HCLK frequency to set FLASH latency 2 in power scale 3 */
72 #define UTILS_SCALE3_LATENCY3_FREQ (50000000U) /*!< HCLK frequency to set FLASH latency 3 in power scale 3 */
73 #define UTILS_SCALE4_LATENCY0_FREQ (8000000U) /*!< HCLK frequency to set FLASH latency 0 in power scale 4 */
74 #define UTILS_SCALE4_LATENCY1_FREQ (16000000U) /*!< HCLK frequency to set FLASH latency 1 in power scale 4 */
75 #define UTILS_SCALE4_LATENCY2_FREQ (24000000U) /*!< HCLK frequency to set FLASH latency 2 in power scale 4 */
76 /**
77 * @}
78 */
79
80 /* Private macros ------------------------------------------------------------*/
81 /** @addtogroup UTILS_LL_Private_Macros
82 * @{
83 */
84 #define IS_LL_UTILS_SYSCLK_DIV(__VALUE__) (((__VALUE__) == LL_RCC_SYSCLK_DIV_1) \
85 || ((__VALUE__) == LL_RCC_SYSCLK_DIV_2) \
86 || ((__VALUE__) == LL_RCC_SYSCLK_DIV_4) \
87 || ((__VALUE__) == LL_RCC_SYSCLK_DIV_8) \
88 || ((__VALUE__) == LL_RCC_SYSCLK_DIV_16) \
89 || ((__VALUE__) == LL_RCC_SYSCLK_DIV_64) \
90 || ((__VALUE__) == LL_RCC_SYSCLK_DIV_128) \
91 || ((__VALUE__) == LL_RCC_SYSCLK_DIV_256) \
92 || ((__VALUE__) == LL_RCC_SYSCLK_DIV_512))
93
94 #define IS_LL_UTILS_APB1_DIV(__VALUE__) (((__VALUE__) == LL_RCC_APB1_DIV_1) \
95 || ((__VALUE__) == LL_RCC_APB1_DIV_2) \
96 || ((__VALUE__) == LL_RCC_APB1_DIV_4) \
97 || ((__VALUE__) == LL_RCC_APB1_DIV_8) \
98 || ((__VALUE__) == LL_RCC_APB1_DIV_16))
99
100 #define IS_LL_UTILS_APB2_DIV(__VALUE__) (((__VALUE__) == LL_RCC_APB2_DIV_1) \
101 || ((__VALUE__) == LL_RCC_APB2_DIV_2) \
102 || ((__VALUE__) == LL_RCC_APB2_DIV_4) \
103 || ((__VALUE__) == LL_RCC_APB2_DIV_8) \
104 || ((__VALUE__) == LL_RCC_APB2_DIV_16))
105
106 #define IS_LL_UTILS_APB3_DIV(__VALUE__) (((__VALUE__) == LL_RCC_APB3_DIV_1) \
107 || ((__VALUE__) == LL_RCC_APB3_DIV_2) \
108 || ((__VALUE__) == LL_RCC_APB3_DIV_4) \
109 || ((__VALUE__) == LL_RCC_APB3_DIV_8) \
110 || ((__VALUE__) == LL_RCC_APB3_DIV_16))
111
112 #define IS_LL_UTILS_PLLM_VALUE(__VALUE__) ((1U <= (__VALUE__)) && ((__VALUE__) <= 16U))
113
114 #define IS_LL_UTILS_PLLN_VALUE(__VALUE__) ((4U <= (__VALUE__)) && ((__VALUE__) <= 512U))
115
116 #define IS_LL_UTILS_PLLR_VALUE(__VALUE__) ((1U <= (__VALUE__)) && ((__VALUE__) <= 128U))
117
118 #define IS_LL_UTILS_PLLVCO_INPUT(__VALUE__) ((UTILS_PLLVCO_INPUT_MIN <= (__VALUE__))\
119 && ((__VALUE__) <= UTILS_PLLVCO_INPUT_MAX))
120
121 #define IS_LL_UTILS_PLLVCO_OUTPUT(__VALUE__) ((UTILS_PLLVCO_OUTPUT_MIN <= (__VALUE__))\
122 && ((__VALUE__) <= UTILS_PLLVCO_OUTPUT_MAX))
123
124 #define IS_LL_UTILS_PLL_FREQUENCY(__VALUE__) ((LL_PWR_GetRegulVoltageScaling() == LL_PWR_REGU_VOLTAGE_SCALE4) ? \
125 ((__VALUE__) <= UTILS_MAX_FREQUENCY_SCALE0) : \
126 (LL_PWR_GetRegulVoltageScaling() == LL_PWR_REGU_VOLTAGE_SCALE1) ? \
127 ((__VALUE__) <= UTILS_MAX_FREQUENCY_SCALE1) : \
128 (LL_PWR_GetRegulVoltageScaling() == LL_PWR_REGU_VOLTAGE_SCALE2) ? \
129 ((__VALUE__) <= UTILS_MAX_FREQUENCY_SCALE2) : \
130 ((__VALUE__) <= UTILS_MAX_FREQUENCY_SCALE3))
131
132 #define IS_LL_UTILS_HSE_BYPASS(__STATE__) (((__STATE__) == LL_UTILS_HSEBYPASS_ON) \
133 || ((__STATE__) == LL_UTILS_HSEBYPASS_OFF))
134
135 #define IS_LL_UTILS_HSE_FREQUENCY(__FREQUENCY__) (((__FREQUENCY__) >= UTILS_HSE_FREQUENCY_MIN)\
136 && ((__FREQUENCY__) <= UTILS_HSE_FREQUENCY_MAX))
137 /**
138 * @}
139 */
140 /* Private function prototypes -----------------------------------------------*/
141 /** @defgroup UTILS_LL_Private_Functions UTILS Private functions
142 * @{
143 */
144 static uint32_t UTILS_GetPLLOutputFrequency(uint32_t PLL_InputFrequency,
145 LL_UTILS_PLLInitTypeDef *UTILS_PLLInitStruct);
146 static ErrorStatus UTILS_EnablePLLAndSwitchSystem(uint32_t SYSCLK_Frequency,
147 LL_UTILS_ClkInitTypeDef *UTILS_ClkInitStruct);
148 static ErrorStatus UTILS_PLL_IsBusy(void);
149 /**
150 * @}
151 */
152
153 /* Exported functions --------------------------------------------------------*/
154 /** @addtogroup UTILS_LL_Exported_Functions
155 * @{
156 */
157
158 /** @addtogroup UTILS_LL_EF_DELAY
159 * @{
160 */
161
162 /**
163 * @brief This function configures the Cortex-M SysTick source to have 1ms time base.
164 * @note When a RTOS is used, it is recommended to avoid changing the Systick
165 * configuration by calling this function, for a delay use rather osDelay RTOS service.
166 * @param HCLKFrequency HCLK frequency in Hz
167 * @note HCLK frequency can be calculated thanks to RCC helper macro or function @ref LL_RCC_GetSystemClocksFreq
168 * @retval None
169 */
LL_Init1msTick(uint32_t HCLKFrequency)170 void LL_Init1msTick(uint32_t HCLKFrequency)
171 {
172 /* Use frequency provided in argument */
173 LL_InitTick(HCLKFrequency, 1000U);
174 }
175
176 /**
177 * @brief This function provides accurate delay (in milliseconds) based
178 * on SysTick counter flag
179 * @note When a RTOS is used, it is recommended to avoid using blocking delay
180 * and use rather osDelay service.
181 * @note To respect 1ms timebase, user should call @ref LL_Init1msTick function which
182 * will configure Systick to 1ms
183 * @param Delay specifies the delay time length, in milliseconds.
184 * @retval None
185 */
186
LL_mDelay(uint32_t Delay)187 void LL_mDelay(uint32_t Delay)
188 {
189 __IO uint32_t tmp = SysTick->CTRL; /* Clear the COUNTFLAG first */
190 uint32_t tmpDelay = Delay;
191
192 /* Add this code to indicate that local variable is not used */
193 ((void)tmp);
194
195 /* Add a period to guaranty minimum wait */
196 if (tmpDelay < LL_MAX_DELAY)
197 {
198 tmpDelay++;
199 }
200
201 while (tmpDelay != 0U)
202 {
203 if ((SysTick->CTRL & SysTick_CTRL_COUNTFLAG_Msk) != 0U)
204 {
205 tmpDelay--;
206 }
207 }
208 }
209
210 /**
211 * @}
212 */
213
214 /** @addtogroup UTILS_EF_SYSTEM
215 * @brief System Configuration functions
216 *
217 @verbatim
218 ===============================================================================
219 ##### System Configuration functions #####
220 ===============================================================================
221 [..]
222 System, AHB and APB buses clocks configuration
223
224 (+) The maximum frequency of the SYSCLK, HCLK, PCLK1 and PCLK2, PCLK3 is
225 160000000 Hz.
226 @endverbatim
227 @internal
228 Depending on the device voltage range, the maximum frequency should be
229 adapted accordingly:
230
231 (++) Table 1. HCLK clock frequency for STM32U5 devices
232 (++) +-----------------------------------------------------------------------------------------------+
233 (++) | Latency | HCLK clock frequency (MHz) |
234 (++) | |-----------------------------------------------------------------------------|
235 (++) | | voltage range 1 | voltage range 2 | voltage range 3 | voltage range 4 |
236 (++) | | 1.2 V | 1.1 V | 1.0 V | 0.9 V |
237 (++) |-----------------|-------------------|------------------|------------------|-------------------|
238 (++) |0WS(1 CPU cycles)| 0 < HCLK <= 32 | 0 < HCLK <= 25 | 0 < HCLK <= 12.5| 0 < HCLK <= 8 |
239 (++) |-----------------|-------------------|------------------|------------------|-------------------|
240 (++) |1WS(2 CPU cycles)| 32 < HCLK <= 64 | 25 < HCLK <= 50 | 12.5 < HCLK <= 25| 0 < HCLK <= 16 |
241 (++) |-----------------|-------------------|------------------|------------------|-------------------|
242 (++) |2WS(3 CPU cycles)| 64 < HCLK <= 96 | 50 < HCLK <= 75 | 25 < HCLK <= 37.5| 0 < HCLK <= 24 |
243 (++) |-----------------|-------------------|------------------|------------------|-------------------|
244 (++) |3WS(4 CPU cycles)| 96 < HCLK <= 128 | 75 < HCLK <= 100| 37.5 < HCLK <= 50| |
245 (++) |-----------------|-------------------|------------------|------------------| |
246 (++) |4WS(5 CPU cycles)| 128 < HCLK <= 160| | | |
247 (++) +-----------------+-------------------+------------------+------------------+-------------------+
248
249 @endinternal
250 * @{
251 */
252
253 /**
254 * @brief This function sets directly SystemCoreClock CMSIS variable.
255 * @note Variable can be calculated also through SystemCoreClockUpdate function.
256 * @param HCLKFrequency HCLK frequency in Hz (can be calculated thanks to RCC helper macro)
257 * @retval None
258 */
LL_SetSystemCoreClock(uint32_t HCLKFrequency)259 void LL_SetSystemCoreClock(uint32_t HCLKFrequency)
260 {
261 /* HCLK clock frequency */
262 SystemCoreClock = HCLKFrequency;
263 }
264
265 /**
266 * @brief Update number of Flash wait states in line with new frequency and current
267 voltage range.
268 * @param HCLK_Frequency HCLK frequency
269 * @retval An ErrorStatus enumeration value:
270 * - SUCCESS: Latency has been modified
271 * - ERROR: Latency cannot be modified
272 */
LL_SetFlashLatency(uint32_t HCLK_Frequency)273 ErrorStatus LL_SetFlashLatency(uint32_t HCLK_Frequency)
274 {
275 ErrorStatus status = SUCCESS;
276 uint32_t timeout;
277 uint32_t getlatency;
278 uint32_t latency = LL_FLASH_LATENCY_0; /* default value 0WS */
279
280 /* Frequency cannot be equal to 0 */
281 if (HCLK_Frequency == 0U)
282 {
283 status = ERROR;
284 }
285 else
286 {
287 if (LL_PWR_GetRegulVoltageScaling() == LL_PWR_REGU_VOLTAGE_SCALE1)
288 {
289 if (HCLK_Frequency <= UTILS_SCALE1_LATENCY0_FREQ)
290 {
291 /* 0 < HCLK <= 32 => 0WS (1 CPU cycles) : Do nothing, keep latency to default LL_FLASH_LATENCY_0 */
292 }
293 else if ((HCLK_Frequency <= UTILS_SCALE1_LATENCY1_FREQ))
294 {
295 /* 32 < HCLK <=64 => 1WS (2 CPU cycles) */
296 latency = LL_FLASH_LATENCY_1;
297 }
298 else if (HCLK_Frequency <= UTILS_SCALE1_LATENCY2_FREQ)
299 {
300 /* 64 < HCLK <= 96 => 2WS (3 CPU cycles) */
301 latency = LL_FLASH_LATENCY_2;
302 }
303 else if (HCLK_Frequency <= UTILS_SCALE1_LATENCY3_FREQ)
304 {
305 /* 96 < HCLK <= 128 => 3WS (4 CPU cycles) */
306 latency = LL_FLASH_LATENCY_3;
307 }
308 else if (HCLK_Frequency <= UTILS_SCALE1_LATENCY4_FREQ)
309 {
310 /* 128 < HCLK <= 160 => 4WS (5 CPU cycles) */
311 latency = LL_FLASH_LATENCY_4;
312 }
313 else
314 {
315 status = ERROR;
316 }
317 /* else HCLK_Frequency <= 10MHz default LL_FLASH_LATENCY_0 0WS */
318 }
319 else if (LL_PWR_GetRegulVoltageScaling() == LL_PWR_REGU_VOLTAGE_SCALE2)
320 {
321 if (HCLK_Frequency <= UTILS_SCALE2_LATENCY0_FREQ)
322 {
323 /* 0 < HCLK <= 25 => 0WS (1 CPU cycles) : Do nothing, keep latency to default LL_FLASH_LATENCY_0 */
324 }
325 else if (HCLK_Frequency <= UTILS_SCALE2_LATENCY1_FREQ)
326 {
327 /* 25 < HCLK <= 50 => 1WS (2 CPU cycles) */
328 latency = LL_FLASH_LATENCY_1;
329 }
330 else if (HCLK_Frequency <= UTILS_SCALE2_LATENCY2_FREQ)
331 {
332 /* 50 < HCLK <= 75 => 2WS (3 CPU cycles) */
333 latency = LL_FLASH_LATENCY_2;
334 }
335 else if (HCLK_Frequency <= UTILS_SCALE2_LATENCY3_FREQ)
336 {
337 /* 75 < HCLK <= 100 => 3WS (4 CPU cycles) */
338 latency = LL_FLASH_LATENCY_3;
339 }
340 else
341 {
342 status = ERROR;
343 }
344 /* else HCLK_Frequency <= 10MHz default LL_FLASH_LATENCY_0 0WS */
345 }
346 else if (LL_PWR_GetRegulVoltageScaling() == LL_PWR_REGU_VOLTAGE_SCALE3)
347 {
348 if (HCLK_Frequency <= UTILS_SCALE3_LATENCY0_FREQ)
349 {
350 /* 0 < HCLK <= 12.5 => 0WS (1 CPU cycles) : Do nothing, keep latency to default LL_FLASH_LATENCY_0 */
351 }
352 else if (HCLK_Frequency <= UTILS_SCALE3_LATENCY1_FREQ)
353 {
354 /* 12.5 < HCLK <= 25 => 1WS (2 CPU cycles) */
355 latency = LL_FLASH_LATENCY_1;
356 }
357 else if (HCLK_Frequency <= UTILS_SCALE3_LATENCY2_FREQ)
358 {
359 /* 25 < HCLK <= 37.5 => 2WS (3 CPU cycles) */
360 latency = LL_FLASH_LATENCY_2;
361 }
362 else if (HCLK_Frequency <= UTILS_SCALE3_LATENCY3_FREQ)
363 {
364 /* 37.5 < HCLK <= 50 => 3WS (4 CPU cycles) */
365 latency = LL_FLASH_LATENCY_3;
366 }
367 else
368 {
369 status = ERROR;
370 }
371 /* else HCLK_Frequency <= 10MHz default LL_FLASH_LATENCY_0 0WS */
372 }
373 else
374 {
375 if (HCLK_Frequency <= UTILS_SCALE4_LATENCY0_FREQ)
376 {
377 /* 0 < HCLK <= 8 => 0WS (1 CPU cycles) : Do nothing, keep latency to default LL_FLASH_LATENCY_0 */
378 }
379 else if (HCLK_Frequency <= UTILS_SCALE4_LATENCY1_FREQ)
380 {
381 /* 8 < HCLK <= 16 => 1WS (2 CPU cycles) */
382 latency = LL_FLASH_LATENCY_1;
383 }
384 else if (HCLK_Frequency <= UTILS_SCALE4_LATENCY2_FREQ)
385 {
386 /* 16 < HCLK <= 24 => 2WS (3 CPU cycles) */
387 latency = LL_FLASH_LATENCY_2;
388 }
389 else
390 {
391 status = ERROR;
392 }
393 /* else HCLK_Frequency <= 10MHz default LL_FLASH_LATENCY_0 0WS */
394 }
395 }
396
397 if (status == SUCCESS)
398 {
399 LL_FLASH_SetLatency(latency);
400
401 /* Check that the new number of wait states is taken into account to access the Flash
402 memory by reading the FLASH_ACR register */
403 timeout = 2;
404 do
405 {
406 /* Wait for Flash latency to be updated */
407 getlatency = LL_FLASH_GetLatency();
408 timeout--;
409 } while ((getlatency != latency) && (timeout > 0U));
410
411 if (getlatency != latency)
412 {
413 status = ERROR;
414 }
415 }
416
417 return status;
418 }
419
420 /**
421 * @brief This function configures system clock with MSI as clock source of the PLL
422 * @note The application needs to ensure that PLL1, PLL2 and/or PLL3 are disabled.
423 * @note Function is based on the following formula:
424 * - PLL1 output frequency = (((MSI frequency / PLL1M) * PLL1N) / PLL1R)
425 * - PLL1M: ensure that the VCO input frequency ranges from 1 to 16 MHz (PLL1VCO_input = MSI frequency / PLL1M)
426 * - PLL1N: ensure that the VCO output frequency is between 4 and 512 MHz
427 (PLL1VCO_output = PLL1VCO_input * PLL1N)
428 * - PLL1R: ensure that max frequency at 160 MHz is reached (PLL1VCO_output / PLL1R)
429 * @param UTILS_PLLInitStruct pointer to a @ref LL_UTILS_PLLInitTypeDef structure that contains
430 * the configuration information for the PLL1.
431 * @param UTILS_ClkInitStruct pointer to a @ref LL_UTILS_ClkInitTypeDef structure that contains
432 * the configuration information for the BUS prescalers.
433 * @retval An ErrorStatus enumeration value:
434 * - SUCCESS: Max frequency configuration done
435 * - ERROR: Max frequency configuration not done
436 */
LL_PLL_ConfigSystemClock_MSI(LL_UTILS_PLLInitTypeDef * UTILS_PLLInitStruct,LL_UTILS_ClkInitTypeDef * UTILS_ClkInitStruct)437 ErrorStatus LL_PLL_ConfigSystemClock_MSI(LL_UTILS_PLLInitTypeDef *UTILS_PLLInitStruct,
438 LL_UTILS_ClkInitTypeDef *UTILS_ClkInitStruct)
439 {
440 ErrorStatus status = SUCCESS;
441 uint32_t pllfreq;
442 uint32_t msi_range;
443 uint32_t hpre = LL_RCC_SYSCLK_DIV_1;
444
445 /* Check if one of the PLL is enabled */
446 if (UTILS_PLL_IsBusy() == SUCCESS)
447 {
448 /* Get the current MSI range */
449 if (LL_RCC_MSI_IsEnabledRangeSelect() != 0U)
450 {
451 msi_range = LL_RCC_MSIS_GetRange();
452 switch (msi_range)
453 {
454 case LL_RCC_MSISRANGE_15: /* MSI = 100 kHz */
455 case LL_RCC_MSISRANGE_14: /* MSI = 150 kHz */
456 case LL_RCC_MSISRANGE_13: /* MSI = 200 kHz */
457 case LL_RCC_MSISRANGE_12: /* MSI = 400 kHz */
458 case LL_RCC_MSISRANGE_11: /* MSI = 768 kHz */
459 case LL_RCC_MSISRANGE_10: /* MSI = 1.024 MHz*/
460 case LL_RCC_MSISRANGE_9: /* MSI = 1.536 MHz*/
461 case LL_RCC_MSISRANGE_8: /* MSI = 3.072 MHz*/
462 case LL_RCC_MSISRANGE_7: /* MSI = 1 MHz */
463 case LL_RCC_MSISRANGE_6: /* MSI = 1.5 MHz */
464 case LL_RCC_MSISRANGE_5: /* MSI = 2 MHz */
465 /* PLLVCO input frequency is less then 4 MHz*/
466 status = ERROR;
467 break;
468
469 case LL_RCC_MSISRANGE_0: /* MSI = 48 MHz */
470 case LL_RCC_MSISRANGE_1: /* MSI = 24 MHz */
471 case LL_RCC_MSISRANGE_2: /* MSI = 16 MHz */
472 case LL_RCC_MSISRANGE_3: /* MSI = 12 MHz */
473 case LL_RCC_MSISRANGE_4: /* MSI = 4 MHz */
474 default:
475 break;
476 }
477 }
478 else
479 {
480 msi_range = LL_RCC_MSIS_GetRangeAfterStandby();
481 switch (msi_range)
482 {
483 case LL_RCC_MSISSRANGE_5: /* MSI = 2 MHz */
484 case LL_RCC_MSISSRANGE_6: /* MSI = 1.5 MHz */
485 case LL_RCC_MSISSRANGE_7: /* MSI = 1 MHz */
486 case LL_RCC_MSISSRANGE_8: /* MSI = 3.072 MHz*/
487 /* PLLVCO input frequency is less then 4 MHz */
488 status = ERROR;
489 break;
490
491 case LL_RCC_MSISSRANGE_4: /* MSI = 4 MHz */
492 default:
493 break;
494 }
495 }
496
497 /* Main PLL configuration and activation */
498 if (status != ERROR)
499 {
500 /* Calculate the new PLL output frequency */
501 pllfreq = UTILS_GetPLLOutputFrequency(__LL_RCC_CALC_MSIS_FREQ(LL_RCC_MSI_IsEnabledRangeSelect(), msi_range),
502 UTILS_PLLInitStruct);
503
504 /* Enable MSI if not enabled */
505 if (LL_RCC_MSIS_IsReady() != 1U)
506 {
507 LL_RCC_MSIS_Enable();
508 while ((LL_RCC_MSIS_IsReady() != 1U))
509 {
510 /* Wait for MSI ready */
511 }
512 }
513
514 /* Configure PLL1 */
515 LL_RCC_PLL1_ConfigDomain_SYS(LL_RCC_PLL1SOURCE_MSIS, UTILS_PLLInitStruct->PLLM, UTILS_PLLInitStruct->PLLN,
516 UTILS_PLLInitStruct->PLLR);
517
518 /* Prevent undershoot at highest frequency by applying intermediate AHB prescaler 2 */
519 if (pllfreq > 80000000U)
520 {
521 if (UTILS_ClkInitStruct->AHBCLKDivider == LL_RCC_SYSCLK_DIV_1)
522 {
523 UTILS_ClkInitStruct->AHBCLKDivider = LL_RCC_SYSCLK_DIV_2;
524 hpre = LL_RCC_SYSCLK_DIV_2;
525 }
526 }
527 /* Enable PLL and switch system clock to PLL */
528 status = UTILS_EnablePLLAndSwitchSystem(pllfreq, UTILS_ClkInitStruct);
529
530 /* Apply definitive AHB prescaler value if necessary */
531 if ((status == SUCCESS) && (hpre != LL_RCC_SYSCLK_DIV_1))
532 {
533 /* Set FLASH latency to highest latency */
534 status = LL_SetFlashLatency(pllfreq);
535 if (status == SUCCESS)
536 {
537 UTILS_ClkInitStruct->AHBCLKDivider = LL_RCC_SYSCLK_DIV_1;
538 LL_RCC_SetAHBPrescaler(UTILS_ClkInitStruct->AHBCLKDivider);
539 LL_SetSystemCoreClock(pllfreq);
540 }
541 }
542 }
543 }
544 else
545 {
546 /* Current PLL configuration cannot be modified */
547 status = ERROR;
548 }
549
550 return status;
551 }
552
553 /**
554 * @brief This function configures system clock at maximum frequency with HSI as clock source of the PLL
555 * @note The application need to ensure that PLL1, PLL2 and/or PLL3 are disabled.
556 * @note Function is based on the following formula:
557 * - PLL output frequency = (((HSI frequency / PLLM) * PLLN) / PLLR)
558 * - PLL1M: ensure that the VCO input frequency ranges from 1 to 16 MHz (PLL1VCO_input = MSI frequency / PLL1M)
559 * - PLL1N: ensure that the VCO output frequency is between 4 and 512 MHz
560 (PLL1VCO_output = PLL1VCO_input * PLL1N)
561 * - PLL1R: ensure that max frequency at 160 MHz is reached (PLL1VCO_output / PLL1R)
562 * @param UTILS_PLLInitStruct pointer to a @ref LL_UTILS_PLLInitTypeDef structure that contains
563 * the configuration information for the PLL.
564 * @param UTILS_ClkInitStruct pointer to a @ref LL_UTILS_ClkInitTypeDef structure that contains
565 * the configuration information for the BUS prescalers.
566 * @retval An ErrorStatus enumeration value:
567 * - SUCCESS: Max frequency configuration done
568 * - ERROR: Max frequency configuration not done
569 */
LL_PLL_ConfigSystemClock_HSI(LL_UTILS_PLLInitTypeDef * UTILS_PLLInitStruct,LL_UTILS_ClkInitTypeDef * UTILS_ClkInitStruct)570 ErrorStatus LL_PLL_ConfigSystemClock_HSI(LL_UTILS_PLLInitTypeDef *UTILS_PLLInitStruct,
571 LL_UTILS_ClkInitTypeDef *UTILS_ClkInitStruct)
572 {
573 ErrorStatus status;
574 uint32_t pllfreq;
575
576 /* Check if one of the PLL is enabled */
577 if (UTILS_PLL_IsBusy() == SUCCESS)
578 {
579 /* Calculate the new PLL output frequency */
580 pllfreq = UTILS_GetPLLOutputFrequency(HSI_VALUE, UTILS_PLLInitStruct);
581
582 /* Enable HSI if not enabled */
583 if (LL_RCC_HSI_IsReady() != 1U)
584 {
585 LL_RCC_HSI_Enable();
586 while (LL_RCC_HSI_IsReady() != 1U)
587 {
588 /* Wait for HSI ready */
589 }
590 }
591
592 /* Configure PLL */
593 LL_RCC_PLL1_ConfigDomain_SYS(LL_RCC_PLL1SOURCE_HSI, UTILS_PLLInitStruct->PLLM, UTILS_PLLInitStruct->PLLN,
594 UTILS_PLLInitStruct->PLLR);
595
596 /* Enable PLL and switch system clock to PLL */
597 status = UTILS_EnablePLLAndSwitchSystem(pllfreq, UTILS_ClkInitStruct);
598 }
599 else
600 {
601 /* Current PLL configuration cannot be modified */
602 status = ERROR;
603 }
604
605 return status;
606 }
607
608 /**
609 * @brief This function configures system clock with HSE as clock source of the PLL
610 * @note The application need to ensure that PLL, PLLSAI1 and/or PLLSAI2 are disabled.
611 * @note Function is based on the following formula:
612 * - PLL output frequency = (((HSE frequency / PLLM) * PLLN) / PLLR)
613 * - PLL1M: ensure that the VCO input frequency ranges from 1 to 16 MHz (PLL1VCO_input = MSI frequency / PLL1M)
614 * - PLL1N: ensure that the VCO output frequency is between 4 and 512 MHz
615 (PLL1VCO_output = PLL1VCO_input * PLL1N)
616 * - PLL1R: ensure that max frequency at 160 MHz is reached (PLL1VCO_output / PLL1R)
617 * @param HSEFrequency Value between Min_Data = 4000000 and Max_Data = 50000000
618 * @param HSEBypass This parameter can be one of the following values:
619 * @arg @ref LL_UTILS_HSEBYPASS_ON
620 * @arg @ref LL_UTILS_HSEBYPASS_OFF
621 * @param UTILS_PLLInitStruct pointer to a @ref LL_UTILS_PLLInitTypeDef structure that contains
622 * the configuration information for the PLL.
623 * @param UTILS_ClkInitStruct pointer to a @ref LL_UTILS_ClkInitTypeDef structure that contains
624 * the configuration information for the BUS prescalers.
625 * @retval An ErrorStatus enumeration value:
626 * - SUCCESS: Max frequency configuration done
627 * - ERROR: Max frequency configuration not done
628 */
LL_PLL_ConfigSystemClock_HSE(uint32_t HSEFrequency,uint32_t HSEBypass,LL_UTILS_PLLInitTypeDef * UTILS_PLLInitStruct,LL_UTILS_ClkInitTypeDef * UTILS_ClkInitStruct)629 ErrorStatus LL_PLL_ConfigSystemClock_HSE(uint32_t HSEFrequency, uint32_t HSEBypass,
630 LL_UTILS_PLLInitTypeDef *UTILS_PLLInitStruct,
631 LL_UTILS_ClkInitTypeDef *UTILS_ClkInitStruct)
632 {
633 ErrorStatus status;
634 uint32_t pllfreq;
635
636 /* Check the parameters */
637 assert_param(IS_LL_UTILS_HSE_FREQUENCY(HSEFrequency));
638 assert_param(IS_LL_UTILS_HSE_BYPASS(HSEBypass));
639
640 /* Check if one of the PLL is enabled */
641 if (UTILS_PLL_IsBusy() == SUCCESS)
642 {
643 /* Calculate the new PLL output frequency */
644 pllfreq = UTILS_GetPLLOutputFrequency(HSEFrequency, UTILS_PLLInitStruct);
645
646 /* Enable HSE if not enabled */
647 if (LL_RCC_HSE_IsReady() != 1U)
648 {
649 /* Check if need to enable HSE bypass feature or not */
650 if (HSEBypass == LL_UTILS_HSEBYPASS_ON)
651 {
652 LL_RCC_HSE_EnableBypass();
653 }
654 else
655 {
656 LL_RCC_HSE_DisableBypass();
657 }
658
659 /* Enable HSE */
660 LL_RCC_HSE_Enable();
661 while (LL_RCC_HSE_IsReady() != 1U)
662 {
663 /* Wait for HSE ready */
664 }
665 }
666
667 /* Configure PLL */
668 LL_RCC_PLL1_ConfigDomain_SYS(LL_RCC_PLL1SOURCE_HSE, UTILS_PLLInitStruct->PLLM, UTILS_PLLInitStruct->PLLN,
669 UTILS_PLLInitStruct->PLLR);
670
671 /* Enable PLL and switch system clock to PLL */
672 status = UTILS_EnablePLLAndSwitchSystem(pllfreq, UTILS_ClkInitStruct);
673 }
674 else
675 {
676 /* Current PLL configuration cannot be modified */
677 status = ERROR;
678 }
679
680 return status;
681 }
682
683 /**
684 * @}
685 */
686
687 /**
688 * @}
689 */
690
691 /** @addtogroup UTILS_LL_Private_Functions
692 * @{
693 */
694
695 /**
696 * @brief Function to check that PLL can be modified
697 * @param PLL_InputFrequency PLL input frequency (in Hz)
698 * @param UTILS_PLLInitStruct pointer to a @ref LL_UTILS_PLLInitTypeDef structure that contains
699 * the configuration information for the PLL.
700 * @retval PLL output frequency (in Hz)
701 */
UTILS_GetPLLOutputFrequency(uint32_t PLL_InputFrequency,LL_UTILS_PLLInitTypeDef * UTILS_PLLInitStruct)702 static uint32_t UTILS_GetPLLOutputFrequency(uint32_t PLL_InputFrequency, LL_UTILS_PLLInitTypeDef *UTILS_PLLInitStruct)
703 {
704 uint32_t pllfreq;
705
706 /* Check the parameters */
707 assert_param(IS_LL_UTILS_PLLM_VALUE(UTILS_PLLInitStruct->PLLM));
708 assert_param(IS_LL_UTILS_PLLN_VALUE(UTILS_PLLInitStruct->PLLN));
709 assert_param(IS_LL_UTILS_PLLR_VALUE(UTILS_PLLInitStruct->PLLR));
710
711 /* Check different PLL parameters according to RM */
712 /* - PLLM: ensure that the VCO input frequency ranges from 1 to 16 MHz. */
713 pllfreq = PLL_InputFrequency / (UTILS_PLLInitStruct->PLLM);
714 assert_param(IS_LL_UTILS_PLLVCO_INPUT(pllfreq));
715
716 /* - PLLN: ensure that the VCO output frequency is between 4 and 512 MHz.*/
717 pllfreq = pllfreq * (UTILS_PLLInitStruct->PLLN);
718 assert_param(IS_LL_UTILS_PLLVCO_OUTPUT(pllfreq));
719
720 /* - PLLR: ensure that max frequency at 160 MHz is reached */
721 pllfreq = pllfreq / (UTILS_PLLInitStruct->PLLR);
722 assert_param(IS_LL_UTILS_PLL_FREQUENCY(pllfreq));
723
724 return pllfreq;
725 }
726
727 /**
728 * @brief Function to check that PLL can be modified
729 * @retval An ErrorStatus enumeration value:
730 * - SUCCESS: PLL modification can be done
731 * - ERROR: PLL is busy
732 */
UTILS_PLL_IsBusy(void)733 static ErrorStatus UTILS_PLL_IsBusy(void)
734 {
735 ErrorStatus status = SUCCESS;
736
737 /* Check if PLL1 is busy*/
738 if (LL_RCC_PLL1_IsReady() != 0U)
739 {
740 /* PLL configuration cannot be modified */
741 status = ERROR;
742 }
743
744 /* Check if PLL2 is busy*/
745 if (LL_RCC_PLL2_IsReady() != 0U)
746 {
747 /* PLL2 configuration cannot be modified */
748 status = ERROR;
749 }
750
751 /* Check if PLL3 is busy*/
752 if (LL_RCC_PLL3_IsReady() != 0U)
753 {
754 /* PLL3 configuration cannot be modified */
755 status = ERROR;
756 }
757
758 return status;
759 }
760
761 /**
762 * @brief Function to enable PLL and switch system clock to PLL
763 * @param SYSCLK_Frequency SYSCLK frequency
764 * @param UTILS_ClkInitStruct pointer to a @ref LL_UTILS_ClkInitTypeDef structure that contains
765 * the configuration information for the BUS prescalers.
766 * @retval An ErrorStatus enumeration value:
767 * - SUCCESS: No problem to switch system to PLL
768 * - ERROR: Problem to switch system to PLL
769 */
UTILS_EnablePLLAndSwitchSystem(uint32_t SYSCLK_Frequency,LL_UTILS_ClkInitTypeDef * UTILS_ClkInitStruct)770 static ErrorStatus UTILS_EnablePLLAndSwitchSystem(uint32_t SYSCLK_Frequency,
771 LL_UTILS_ClkInitTypeDef *UTILS_ClkInitStruct)
772 {
773 ErrorStatus status = SUCCESS;
774 uint32_t hclk_frequency;
775
776 assert_param(IS_LL_UTILS_SYSCLK_DIV(UTILS_ClkInitStruct->AHBCLKDivider));
777 assert_param(IS_LL_UTILS_APB1_DIV(UTILS_ClkInitStruct->APB1CLKDivider));
778 assert_param(IS_LL_UTILS_APB2_DIV(UTILS_ClkInitStruct->APB2CLKDivider));
779 assert_param(IS_LL_UTILS_APB3_DIV(UTILS_ClkInitStruct->APB3CLKDivider));
780
781 /* Calculate HCLK frequency */
782 hclk_frequency = __LL_RCC_CALC_HCLK_FREQ(SYSCLK_Frequency, UTILS_ClkInitStruct->AHBCLKDivider);
783
784 /* Increasing the number of wait states because of higher CPU frequency */
785 if (SystemCoreClock < hclk_frequency)
786 {
787 /* Set FLASH latency to highest latency */
788 status = LL_SetFlashLatency(hclk_frequency);
789 }
790
791 /* Update system clock configuration */
792 if (status == SUCCESS)
793 {
794 /* Enable PLL1 */
795 LL_RCC_PLL1_Enable();
796 LL_RCC_PLL1_EnableDomain_SYS();
797 while (LL_RCC_PLL1_IsReady() != 1U)
798 {
799 /* Wait for PLL ready */
800 }
801
802 /* Sysclk activation on the main PLL */
803 LL_RCC_SetAHBPrescaler(UTILS_ClkInitStruct->AHBCLKDivider);
804 LL_RCC_SetSysClkSource(LL_RCC_SYS_CLKSOURCE_PLL1);
805 while (LL_RCC_GetSysClkSource() != LL_RCC_SYS_CLKSOURCE_STATUS_PLL1)
806 {
807 /* Wait for system clock switch to PLL */
808 }
809
810 /* Set APB1, APB2 & APB3 prescaler*/
811 LL_RCC_SetAPB1Prescaler(UTILS_ClkInitStruct->APB1CLKDivider);
812 LL_RCC_SetAPB2Prescaler(UTILS_ClkInitStruct->APB2CLKDivider);
813 LL_RCC_SetAPB3Prescaler(UTILS_ClkInitStruct->APB3CLKDivider);
814 }
815
816 /* Decreasing the number of wait states because of lower CPU frequency */
817 if (SystemCoreClock > hclk_frequency)
818 {
819 /* Set FLASH latency to lowest latency */
820 status = LL_SetFlashLatency(hclk_frequency);
821 }
822
823 /* Update SystemCoreClock variable */
824 if (status == SUCCESS)
825 {
826 LL_SetSystemCoreClock(hclk_frequency);
827 }
828
829 return status;
830 }
831
832 /**
833 * @}
834 */
835
836 /**
837 * @}
838 */
839
840 /**
841 * @}
842 */
843