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