1 /**
2 ******************************************************************************
3 * @file stm32h7rsxx_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 "stm32h7rsxx_ll_utils.h"
20 #include "stm32h7rsxx_ll_rcc.h"
21 #include "stm32h7rsxx_ll_pwr.h"
22
23 #ifdef USE_FULL_ASSERT
24 #include "stm32_assert.h"
25 #else
26 #define assert_param(expr) ((void)0U)
27 #endif /* USE_FULL_ASSERT */
28
29 /** @addtogroup STM32H7RSxx_LL_Driver
30 * @{
31 */
32
33 /** @addtogroup UTILS_LL
34 * @{
35 */
36
37 /* Private types -------------------------------------------------------------*/
38 /* Private variables ---------------------------------------------------------*/
39 /* Private constants ---------------------------------------------------------*/
40 /** @addtogroup UTILS_LL_Private_Constants
41 * @{
42 */
43 #define UTILS_MAX_FREQUENCY_SCALE0 467000000U /*!< Maximum frequency for system clock at power scale 0, in Hz */
44 #define UTILS_MAX_FREQUENCY_SCALE1 365000000U /*!< Maximum frequency for system clock at power scale 1, in Hz */
45
46 /* Defines used for PLL range */
47 #define UTILS_PLLVCO_INPUT_MIN1 1000000U /*!< Frequency min for the medium range PLLVCO input, in Hz */
48 #define UTILS_PLLVCO_INPUT_MAX1 2000000U /*!< Frequency max for the medium range PLLVCO input, in Hz */
49 #define UTILS_PLLVCO_INPUT_MIN2 2000000U /*!< Frequency min for the wide range PLLVCO input, in Hz */
50 #define UTILS_PLLVCO_INPUT_MAX2 4000000U /*!< Frequency max for the wide range PLLVCO input, in Hz */
51 #define UTILS_PLLVCO_INPUT_MIN3 4000000U /*!< Frequency min for the wide range PLLVCO input, in Hz */
52 #define UTILS_PLLVCO_INPUT_MAX3 8000000U /*!< Frequency max for the wide range PLLVCO input, in Hz */
53 #define UTILS_PLLVCO_INPUT_MIN4 8000000U /*!< Frequency min for the wide range PLLVCO input, in Hz */
54 #define UTILS_PLLVCO_INPUT_MAX4 16000000U /*!< Frequency max for the wide range PLLVCO input, in Hz */
55
56 #define UTILS_PLLVCO_MEDIUM_OUTPUT_MIN 150000000U /*!< Frequency min for the medium range PLLVCO output, in Hz */
57 #define UTILS_PLLVCO_WIDE_OUTPUT_MIN 400000000U /*!< Frequency min for the wide range PLLVCO output, in Hz */
58 #define UTILS_PLLVCO_MEDIUM_OUTPUT_MAX 420000000U /*!< Frequency max for the medium range PLLVCO output, in Hz */
59 #define UTILS_PLLVCO_WIDE_OUTPUT_MAX 1600000000U /*!< Frequency max for the wide range PLLVCO output, in Hz */
60
61 /* Defines used for HSE range */
62 #define UTILS_HSE_FREQUENCY_MIN 4000000U /*!< Frequency min for HSE frequency, in Hz */
63 #define UTILS_HSE_FREQUENCY_MAX 50000000U /*!< Frequency max for HSE frequency, in Hz */
64
65 /* Defines used for FLASH latency according to HCLK Frequency at */
66 /* VOS0 (highest power/frequency) or VOS1 (lowest power/frequency) */
67 #define UTILS_SCALE0_LATENCY0_FREQ 40000000U /*!< HCLK frequency to set FLASH latency 0 in power scale 0 */
68 #define UTILS_SCALE0_LATENCY1_FREQ 80000000U /*!< HCLK frequency to set FLASH latency 1 in power scale 0 */
69 #define UTILS_SCALE0_LATENCY2_FREQ 120000000U /*!< HCLK frequency to set FLASH latency 2 in power scale 0 */
70 #define UTILS_SCALE0_LATENCY3_FREQ 160000000U /*!< HCLK frequency to set FLASH latency 3 in power scale 0 */
71 #define UTILS_SCALE0_LATENCY4_FREQ 200000000U /*!< HCLK frequency to set FLASH latency 4 in power scale 0 */
72 #define UTILS_SCALE0_LATENCY5_FREQ 234000000U /*!< HCLK frequency to set FLASH latency 5 in power scale 0 */
73
74 #define UTILS_SCALE1_LATENCY0_FREQ 36000000U /*!< HCLK frequency to set FLASH latency 0 in power scale 1 */
75 #define UTILS_SCALE1_LATENCY1_FREQ 72000000U /*!< HCLK frequency to set FLASH latency 1 in power scale 1 */
76 #define UTILS_SCALE1_LATENCY2_FREQ 108000000U /*!< HCLK frequency to set FLASH latency 2 in power scale 1 */
77 #define UTILS_SCALE1_LATENCY3_FREQ 144000000U /*!< HCLK frequency to set FLASH latency 3 in power scale 1 */
78 #define UTILS_SCALE1_LATENCY4_FREQ 180000000U /*!< HCLK frequency to set FLASH latency 4 in power scale 1 */
79 #define UTILS_SCALE1_LATENCY5_FREQ 183000000U /*!< HCLK frequency to set FLASH latency 5 in power scale 1 */
80 /**
81 * @}
82 */
83
84 /* Private macros ------------------------------------------------------------*/
85 /** @addtogroup UTILS_LL_Private_Macros
86 * @{
87 */
88 #define IS_LL_UTILS_SYSCLK_DIV(__VALUE__) (((__VALUE__) == LL_RCC_SYSCLK_DIV_1) \
89 || ((__VALUE__) == LL_RCC_SYSCLK_DIV_2) \
90 || ((__VALUE__) == LL_RCC_SYSCLK_DIV_4) \
91 || ((__VALUE__) == LL_RCC_SYSCLK_DIV_8) \
92 || ((__VALUE__) == LL_RCC_SYSCLK_DIV_16) \
93 || ((__VALUE__) == LL_RCC_SYSCLK_DIV_64) \
94 || ((__VALUE__) == LL_RCC_SYSCLK_DIV_128) \
95 || ((__VALUE__) == LL_RCC_SYSCLK_DIV_256) \
96 || ((__VALUE__) == LL_RCC_SYSCLK_DIV_512))
97
98 #define IS_LL_UTILS_AHB_DIV(__VALUE__) (((__VALUE__) == LL_RCC_AHB_DIV_1) \
99 || ((__VALUE__) == LL_RCC_AHB_DIV_2) \
100 || ((__VALUE__) == LL_RCC_AHB_DIV_4) \
101 || ((__VALUE__) == LL_RCC_AHB_DIV_8) \
102 || ((__VALUE__) == LL_RCC_AHB_DIV_16) \
103 || ((__VALUE__) == LL_RCC_AHB_DIV_64) \
104 || ((__VALUE__) == LL_RCC_AHB_DIV_128) \
105 || ((__VALUE__) == LL_RCC_AHB_DIV_256) \
106 || ((__VALUE__) == LL_RCC_AHB_DIV_512))
107
108 #define IS_LL_UTILS_APB1_DIV(__VALUE__) (((__VALUE__) == LL_RCC_APB1_DIV_1) \
109 || ((__VALUE__) == LL_RCC_APB1_DIV_2) \
110 || ((__VALUE__) == LL_RCC_APB1_DIV_4) \
111 || ((__VALUE__) == LL_RCC_APB1_DIV_8) \
112 || ((__VALUE__) == LL_RCC_APB1_DIV_16))
113
114 #define IS_LL_UTILS_APB2_DIV(__VALUE__) (((__VALUE__) == LL_RCC_APB2_DIV_1) \
115 || ((__VALUE__) == LL_RCC_APB2_DIV_2) \
116 || ((__VALUE__) == LL_RCC_APB2_DIV_4) \
117 || ((__VALUE__) == LL_RCC_APB2_DIV_8) \
118 || ((__VALUE__) == LL_RCC_APB2_DIV_16))
119
120 #define IS_LL_UTILS_APB4_DIV(__VALUE__) (((__VALUE__) == LL_RCC_APB4_DIV_1) \
121 || ((__VALUE__) == LL_RCC_APB4_DIV_2) \
122 || ((__VALUE__) == LL_RCC_APB4_DIV_4) \
123 || ((__VALUE__) == LL_RCC_APB4_DIV_8) \
124 || ((__VALUE__) == LL_RCC_APB4_DIV_16))
125
126 #define IS_LL_UTILS_APB5_DIV(__VALUE__) (((__VALUE__) == LL_RCC_APB5_DIV_1) \
127 || ((__VALUE__) == LL_RCC_APB5_DIV_2) \
128 || ((__VALUE__) == LL_RCC_APB5_DIV_4) \
129 || ((__VALUE__) == LL_RCC_APB5_DIV_8) \
130 || ((__VALUE__) == LL_RCC_APB5_DIV_16))
131
132 #define IS_LL_UTILS_PLLM_VALUE(__VALUE__) ((1U <= (__VALUE__)) && ((__VALUE__) <= 63U))
133
134 #define IS_LL_UTILS_PLLN_VALUE(__VALUE__) ((8U <= (__VALUE__)) && ((__VALUE__) <= 420U))
135
136 #define IS_LL_UTILS_PLLP_VALUE(__VALUE__) ((1U <= (__VALUE__)) && ((__VALUE__) <= 128U))
137
138 #define IS_LL_UTILS_FRACN_VALUE(__VALUE__) ((__VALUE__) <= 0x1FFFU)
139
140 #define IS_LL_UTILS_PLLVCO_INPUT(__VALUE__, __RANGE__) \
141 ((((__RANGE__) == LL_RCC_PLLINPUTRANGE_1_2) && \
142 (UTILS_PLLVCO_INPUT_MIN1 <= (__VALUE__)) && ((__VALUE__) <= UTILS_PLLVCO_INPUT_MAX1)) || \
143 (((__RANGE__) == LL_RCC_PLLINPUTRANGE_2_4) && \
144 (UTILS_PLLVCO_INPUT_MIN2 <= (__VALUE__)) && ((__VALUE__) <= UTILS_PLLVCO_INPUT_MAX2)) || \
145 (((__RANGE__) == LL_RCC_PLLINPUTRANGE_4_8) && \
146 (UTILS_PLLVCO_INPUT_MIN3 <= (__VALUE__)) && ((__VALUE__) <= UTILS_PLLVCO_INPUT_MAX3)) || \
147 (((__RANGE__) == LL_RCC_PLLINPUTRANGE_8_16) && \
148 (UTILS_PLLVCO_INPUT_MIN4 <= (__VALUE__)) && ((__VALUE__) <= UTILS_PLLVCO_INPUT_MAX4)))
149
150 #define IS_LL_UTILS_PLLVCO_OUTPUT(__VALUE__, __RANGE__) \
151 ((((__RANGE__) == LL_RCC_PLLVCORANGE_MEDIUM) && \
152 (UTILS_PLLVCO_MEDIUM_OUTPUT_MIN <= (__VALUE__)) && ((__VALUE__) <= UTILS_PLLVCO_MEDIUM_OUTPUT_MAX)) || \
153 (((__RANGE__) == LL_RCC_PLLVCORANGE_WIDE) && \
154 (UTILS_PLLVCO_WIDE_OUTPUT_MIN <= (__VALUE__)) && ((__VALUE__) <= UTILS_PLLVCO_WIDE_OUTPUT_MAX)))
155
156 #define IS_LL_UTILS_CHECK_VCO_RANGES(__RANGEIN__, __RANGEOUT__) \
157 ((((__RANGEIN__) == LL_RCC_PLLINPUTRANGE_1_2) && \
158 ((__RANGEOUT__) == LL_RCC_PLLVCORANGE_MEDIUM)) || \
159 (((__RANGEIN__) != LL_RCC_PLLINPUTRANGE_1_2) && \
160 ((__RANGEOUT__) == LL_RCC_PLLVCORANGE_WIDE)))
161
162 #define IS_LL_UTILS_PLL_FREQUENCY(__VALUE__) \
163 ((LL_PWR_GetRegulVoltageScaling() == LL_PWR_REGU_VOLTAGE_SCALE0) ? \
164 ((__VALUE__) <= UTILS_MAX_FREQUENCY_SCALE0) : ((__VALUE__) <= UTILS_MAX_FREQUENCY_SCALE1))
165
166 #define IS_LL_UTILS_HSE_BYPASS(__STATE__) \
167 (((__STATE__) == LL_UTILS_HSEBYPASS_ON) || ((__STATE__) == LL_UTILS_HSEBYPASS_OFF))
168
169 #define IS_LL_UTILS_HSE_FREQUENCY(__FREQUENCY__) \
170 (((__FREQUENCY__) >= UTILS_HSE_FREQUENCY_MIN) && ((__FREQUENCY__) <= UTILS_HSE_FREQUENCY_MAX))
171 /**
172 * @}
173 */
174
175 /* Private function prototypes -----------------------------------------------*/
176 /** @defgroup UTILS_LL_Private_Functions UTILS Private functions
177 * @{
178 */
179 static uint32_t UTILS_GetPLLOutputFrequency(uint32_t PLL_InputFrequency,
180 const LL_UTILS_PLLInitTypeDef *UTILS_PLLInitStruct);
181 static ErrorStatus UTILS_EnablePLLAndSwitchSystem(uint32_t SYSCLK_Frequency,
182 LL_UTILS_ClkInitTypeDef *UTILS_ClkInitStruct);
183 static ErrorStatus UTILS_IsPLLsNotBusy(void);
184 /**
185 * @}
186 */
187
188 /* Exported functions --------------------------------------------------------*/
189 /** @addtogroup UTILS_LL_Exported_Functions
190 * @{
191 */
192
193 /** @addtogroup UTILS_LL_EF_DELAY
194 * @{
195 */
196 /**
197 * @brief This function configures the Cortex-M SysTick source to have 1ms time base.
198 * @note When a RTOS is used, it is recommended to avoid changing the Systick
199 * configuration by calling this function, for a delay use rather osDelay RTOS service.
200 * @param CPU_Frequency Core frequency in Hz
201 * @note CPU_Frequency can be calculated thanks to RCC helper macro or function
202 * @ref LL_RCC_GetSystemClocksFreq
203 * @retval None
204 */
LL_Init1msTick(uint32_t CPU_Frequency)205 void LL_Init1msTick(uint32_t CPU_Frequency)
206 {
207 /* Use frequency provided in argument */
208 LL_InitTick(CPU_Frequency, 1000U);
209 }
210
211
212 /**
213 * @brief This function provides accurate delay (in milliseconds) based
214 * on SysTick counter flag
215 * @note When a RTOS is used, it is recommended to avoid using blocking delay
216 * and use rather osDelay service.
217 * @note To respect 1ms timebase, user should call @ref LL_Init1msTick function which
218 * will configure Systick to 1ms
219 * @param Delay specifies the delay time length, in milliseconds.
220 * @retval None
221 */
LL_mDelay(uint32_t Delay)222 void LL_mDelay(uint32_t Delay)
223 {
224 uint32_t count = Delay;
225 __IO uint32_t tmp = SysTick->CTRL; /* Clear the COUNTFLAG first */
226 /* Add this code to indicate that local variable is not used */
227 ((void)tmp);
228
229 /* Add a period to ensure minimum wait */
230 if (count < LL_MAX_DELAY)
231 {
232 count++;
233 }
234
235 while (count != 0U)
236 {
237 if ((SysTick->CTRL & SysTick_CTRL_COUNTFLAG_Msk) != 0U)
238 {
239 count--;
240 }
241 }
242 }
243
244 /**
245 * @}
246 */
247
248 /** @addtogroup UTILS_EF_SYSTEM
249 * @brief System Configuration functions
250 *
251 @verbatim
252 ===============================================================================
253 ##### System Configuration functions #####
254 ===============================================================================
255 [..]
256 System, AXI, AHB and APB buses clocks configuration
257
258 (+) The maximum frequency of the SYSCLK is 464 MHz and HCLK is 232 MHz.
259 (+) The maximum frequency of the PCLK1, PCLK2, PCLK4 and PCLK5 is 116 MHz.
260 @endverbatim
261 @internal
262 Depending on the device voltage range, the maximum frequency should be
263 adapted accordingly:
264 (++) +---------------------------------------------------------------------------+
265 (++) | Wait states | AXI interface clock frequency (MHz) vs Vcore range |
266 (++) | |-----------------------------------------------------|
267 (++) | (Latency) | voltage scale 1 | voltage scale 0 |
268 (++) | | 1.15V - 1.26V | 1.26V - 1.40V |
269 (++) |---------------------|--------------------------|--------------------------|
270 (++) | 0WS (1 CPU cycle) | 0 < HCLK <= 36 | 0 < HCLK <= 40 |
271 (++) |---------------------|--------------------------|--------------------------|
272 (++) | 1WS (2 CPU cycles) | 36 < HCLK <= 72 | 40 < HCLK <= 80 |
273 (++) |---------------------|--------------------------|--------------------------|
274 (++) | 2WS (3 CPU cycles) | 72 < HCLK <= 108 | 80 < HCLK <= 120 |
275 (++) |---------------------|--------------------------|--------------------------|
276 (++) | 3WS (4 CPU cycles) | 108 < HCLK <= 144 | 120 < HCLK <= 160 |
277 (++) |---------------------|--------------------------|--------------------------|
278 (++) | 4WS (5 CPU cycles) | 144 < HCLK <= 180 | 160 < HCLK <= 200 |
279 (++) |---------------------|--------------------------|--------------------------|
280 (++) | 5WS (6 CPU cycles) | 180 < HCLK <= 216 | 200 < HCLK <= 240 |
281 (++) |---------------------|--------------------------|--------------------------|
282 (++) | 6WS (7 CPU cycles) | 216 < HCLK <= 252 | |
283 (++) |---------------------|--------------------------|--------------------------|
284
285 @endinternal
286 * @{
287 */
288
289 /**
290 * @brief This function sets directly SystemCoreClock CMSIS variable.
291 * @note Variable can be calculated also through SystemCoreClockUpdate function.
292 * @param CPU_Frequency Core frequency in Hz
293 * @note CPU_Frequency can be calculated thanks to RCC helper macro or function
294 * @ref LL_RCC_GetSystemClocksFreq
295 * @retval None
296 */
LL_SetSystemCoreClock(uint32_t CPU_Frequency)297 void LL_SetSystemCoreClock(uint32_t CPU_Frequency)
298 {
299 /* SYSCLK clock frequency */
300 SystemCoreClock = CPU_Frequency;
301 }
302
303 /**
304 * @brief This function configures system clock at maximum frequency with HSI as clock source of the PLL
305 * @note The application need to ensure that PLL is disabled.
306 * @note Function is based on the following formula:
307 * - PLL output frequency = (((HSI frequency / PLLM) * PLLN) / PLLP)
308 * - PLLM: ensure that the VCO input frequency ranges from 1 to 16 MHz (PLLVCO_input = HSI frequency / PLLM)
309 * - PLLN: ensure that the VCO output frequency is
310 * between 150 and 420 MHz (Medium) or
311 * between 400 to 1600 MHz (Wide) (PLLVCO_output = PLLVCO_input * PLLN)
312 * - PLLP: ensure that max frequency at 464 MHz is reached (PLLVCO_output / PLLP)
313 * @param UTILS_PLLInitStruct pointer to a @ref LL_UTILS_PLLInitTypeDef structure that contains
314 * the configuration information for the PLL.
315 * @param UTILS_ClkInitStruct pointer to a @ref LL_UTILS_ClkInitTypeDef structure that contains
316 * the configuration information for the BUS prescalers.
317 * @retval An ErrorStatus enumeration value:
318 * - SUCCESS: Max frequency configuration done
319 * - ERROR: Max frequency configuration not done
320 *
321 */
LL_PLL_ConfigSystemClock_HSI(LL_UTILS_PLLInitTypeDef * UTILS_PLLInitStruct,LL_UTILS_ClkInitTypeDef * UTILS_ClkInitStruct)322 ErrorStatus LL_PLL_ConfigSystemClock_HSI(LL_UTILS_PLLInitTypeDef *UTILS_PLLInitStruct,
323 LL_UTILS_ClkInitTypeDef *UTILS_ClkInitStruct)
324 {
325 ErrorStatus status;
326 #ifdef USE_FULL_ASSERT
327 uint32_t vcoinput_freq;
328 uint32_t vcooutput_freq;
329 #endif /* USE_FULL_ASSERT */
330 uint32_t pllfreq;
331 uint32_t hsi_clk;
332
333 /* Check the parameters */
334 assert_param(IS_LL_UTILS_PLLM_VALUE(UTILS_PLLInitStruct->PLLM));
335 assert_param(IS_LL_UTILS_PLLN_VALUE(UTILS_PLLInitStruct->PLLN));
336 assert_param(IS_LL_UTILS_PLLP_VALUE(UTILS_PLLInitStruct->PLLP));
337 assert_param(IS_LL_UTILS_FRACN_VALUE(UTILS_PLLInitStruct->FRACN));
338
339 hsi_clk = (HSI_VALUE >> (LL_RCC_HSI_GetDivider() >> RCC_CR_HSIDIV_Pos));
340
341 /* Check VCO Input frequency */
342 #ifdef USE_FULL_ASSERT
343 vcoinput_freq = hsi_clk / UTILS_PLLInitStruct->PLLM;
344 assert_param(IS_LL_UTILS_PLLVCO_INPUT(vcoinput_freq, UTILS_PLLInitStruct->VCO_Input));
345 #endif /* USE_FULL_ASSERT */
346
347 /* Check VCO Output frequency */
348 #ifdef USE_FULL_ASSERT
349 vcooutput_freq = LL_RCC_CalcPLLClockFreq(hsi_clk, UTILS_PLLInitStruct->PLLM, UTILS_PLLInitStruct->PLLN,
350 UTILS_PLLInitStruct->FRACN, 1UL);
351 assert_param(IS_LL_UTILS_PLLVCO_OUTPUT(vcooutput_freq, UTILS_PLLInitStruct->VCO_Output));
352 #endif /* USE_FULL_ASSERT */
353
354 /* Check VCO Input ranges */
355 assert_param(IS_LL_UTILS_CHECK_VCO_RANGES(UTILS_PLLInitStruct->VCO_Input, UTILS_PLLInitStruct->VCO_Output));
356
357 /* Check that no PLL is enabled and thus ready for configuration */
358 if (UTILS_IsPLLsNotBusy() == SUCCESS)
359 {
360 /* Calculate the new PLL output frequency */
361 pllfreq = UTILS_GetPLLOutputFrequency(hsi_clk, UTILS_PLLInitStruct);
362
363 /* Enable HSI if not enabled */
364 if (LL_RCC_HSI_IsReady() != 1U)
365 {
366 LL_RCC_HSI_Enable();
367 while (LL_RCC_HSI_IsReady() != 1U)
368 {
369 /* Wait for HSI ready */
370 }
371 }
372
373 /* Configure PLL */
374 LL_RCC_PLL1FRACN_Disable();
375 LL_RCC_PLL_SetSource(LL_RCC_PLLSOURCE_HSI);
376 LL_RCC_PLL1_SetVCOInputRange(UTILS_PLLInitStruct->VCO_Input);
377 LL_RCC_PLL1_SetVCOOutputRange(UTILS_PLLInitStruct->VCO_Output);
378 LL_RCC_PLL1_SetM(UTILS_PLLInitStruct->PLLM);
379 LL_RCC_PLL1_SetN(UTILS_PLLInitStruct->PLLN);
380 LL_RCC_PLL1_SetP(UTILS_PLLInitStruct->PLLP);
381 LL_RCC_PLL1_SetFRACN(UTILS_PLLInitStruct->FRACN);
382 LL_RCC_PLL1FRACN_Enable();
383 LL_RCC_PLL1_SetFRACN(UTILS_PLLInitStruct->FRACN);
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 * @brief This function configures system clock at maximum frequency with CSI as clock source of the PLL
399 * @note The application need to ensure that PLL is disabled.
400 * @note Function is based on the following formula:
401 * - PLL output frequency = (((CSI frequency / PLLM) * PLLN) / PLLP)
402 * - PLLM: ensure that the VCO input frequency ranges from 1 to 4 MHz (PLLVCO_input = CSI frequency / PLLM)
403 * - PLLN: ensure that the VCO output frequency is
404 * between 150 and 420 MHz (Medium) or
405 * between 400 to 1600 MHz (Wide) (PLLVCO_output = PLLVCO_input * PLLN)
406 * - PLLP: ensure that max frequency at 464 MHz is reached (PLLVCO_output / PLLP)
407 * @param UTILS_PLLInitStruct pointer to a @ref LL_UTILS_PLLInitTypeDef structure that contains
408 * the configuration information for the PLL.
409 * @param UTILS_ClkInitStruct pointer to a @ref LL_UTILS_ClkInitTypeDef structure that contains
410 * the configuration information for the BUS prescalers.
411 * @retval An ErrorStatus enumeration value:
412 * - SUCCESS: Max frequency configuration done
413 * - ERROR: Max frequency configuration not done
414 *
415 */
LL_PLL_ConfigSystemClock_CSI(LL_UTILS_PLLInitTypeDef * UTILS_PLLInitStruct,LL_UTILS_ClkInitTypeDef * UTILS_ClkInitStruct)416 ErrorStatus LL_PLL_ConfigSystemClock_CSI(LL_UTILS_PLLInitTypeDef *UTILS_PLLInitStruct,
417 LL_UTILS_ClkInitTypeDef *UTILS_ClkInitStruct)
418 {
419 ErrorStatus status;
420 #ifdef USE_FULL_ASSERT
421 uint32_t vcoinput_freq;
422 uint32_t vcooutput_freq;
423 #endif /* USE_FULL_ASSERT */
424 uint32_t pllfreq;
425
426 /* Check the parameters */
427 assert_param(IS_LL_UTILS_PLLM_VALUE(UTILS_PLLInitStruct->PLLM));
428 assert_param(IS_LL_UTILS_PLLN_VALUE(UTILS_PLLInitStruct->PLLN));
429 assert_param(IS_LL_UTILS_PLLP_VALUE(UTILS_PLLInitStruct->PLLP));
430 assert_param(IS_LL_UTILS_FRACN_VALUE(UTILS_PLLInitStruct->FRACN));
431
432 /* Check VCO Input frequency */
433 #ifdef USE_FULL_ASSERT
434 vcoinput_freq = CSI_VALUE / UTILS_PLLInitStruct->PLLM;
435 assert_param(IS_LL_UTILS_PLLVCO_INPUT(vcoinput_freq, UTILS_PLLInitStruct->VCO_Input));
436 #endif /* USE_FULL_ASSERT */
437
438 /* Check VCO Output frequency */
439 #ifdef USE_FULL_ASSERT
440 vcooutput_freq = LL_RCC_CalcPLLClockFreq(CSI_VALUE, UTILS_PLLInitStruct->PLLM, UTILS_PLLInitStruct->PLLN,
441 UTILS_PLLInitStruct->FRACN, 1UL);
442 assert_param(IS_LL_UTILS_PLLVCO_OUTPUT(vcooutput_freq, UTILS_PLLInitStruct->VCO_Output));
443 #endif /* USE_FULL_ASSERT */
444
445 /* Check VCO Input ranges */
446 assert_param(IS_LL_UTILS_CHECK_VCO_RANGES(UTILS_PLLInitStruct->VCO_Input, UTILS_PLLInitStruct->VCO_Output));
447
448 /* Check that no PLL is enabled and thus ready for configuration */
449 if (UTILS_IsPLLsNotBusy() == SUCCESS)
450 {
451 /* Calculate the new PLL output frequency */
452 pllfreq = UTILS_GetPLLOutputFrequency(CSI_VALUE, UTILS_PLLInitStruct);
453
454 /* Enable CSI if not enabled */
455 if (LL_RCC_CSI_IsReady() != 1U)
456 {
457 LL_RCC_CSI_Enable();
458 while (LL_RCC_CSI_IsReady() != 1U)
459 {
460 /* Wait for CSI ready */
461 }
462 }
463
464 /* Configure PLL */
465 LL_RCC_PLL1FRACN_Disable();
466 LL_RCC_PLL_SetSource(LL_RCC_PLLSOURCE_CSI);
467 LL_RCC_PLL1_SetVCOInputRange(UTILS_PLLInitStruct->VCO_Input);
468 LL_RCC_PLL1_SetVCOOutputRange(UTILS_PLLInitStruct->VCO_Output);
469 LL_RCC_PLL1_SetM(UTILS_PLLInitStruct->PLLM);
470 LL_RCC_PLL1_SetN(UTILS_PLLInitStruct->PLLN);
471 LL_RCC_PLL1_SetP(UTILS_PLLInitStruct->PLLP);
472 LL_RCC_PLL1_SetFRACN(UTILS_PLLInitStruct->FRACN);
473 LL_RCC_PLL1FRACN_Enable();
474 LL_RCC_PLL1_SetFRACN(UTILS_PLLInitStruct->FRACN);
475
476 /* Enable PLL and switch system clock to PLL */
477 status = UTILS_EnablePLLAndSwitchSystem(pllfreq, UTILS_ClkInitStruct);
478 }
479 else
480 {
481 /* Current PLL configuration cannot be modified */
482 status = ERROR;
483 }
484
485 return status;
486 }
487
488 /**
489 * @brief This function configures system clock with HSE as clock source of the PLL
490 * @note The application need to ensure that PLL is disabled.
491 * @note Function is based on the following formula:
492 * - PLL output frequency = (((HSE frequency / PLLM) * PLLN) / PLLP)
493 * - PLLM: ensure that the VCO input frequency ranges from 1 to 4 MHz (PLLVCO_input = CSI frequency / PLLM)
494 * - PLLN: ensure that the VCO output frequency is
495 * between 150 and 420 MHz (Medium) or
496 * between 400 to 1600 MHz (Wide) (PLLVCO_output = PLLVCO_input * PLLN)
497 * - PLLP: ensure that max frequency at 464 MHz is reached (PLLVCO_output / PLLP)
498 * @param HSEFrequency Value between Min_Data = 4000000 and Max_Data = 50000000
499 * @param HSEBypass This parameter can be one of the following values:
500 * @arg @ref LL_UTILS_HSEBYPASS_ON
501 * @arg @ref LL_UTILS_HSEBYPASS_OFF
502 * @param UTILS_PLLInitStruct pointer to a @ref LL_UTILS_PLLInitTypeDef structure that contains
503 * the configuration information for the PLL.
504 * @param UTILS_ClkInitStruct pointer to a @ref LL_UTILS_ClkInitTypeDef structure that contains
505 * the configuration information for the BUS prescalers.
506 * @retval An ErrorStatus enumeration value:
507 * - SUCCESS: Max frequency configuration done
508 * - ERROR: Max frequency configuration not done
509 *
510 */
LL_PLL_ConfigSystemClock_HSE(uint32_t HSEFrequency,uint32_t HSEBypass,LL_UTILS_PLLInitTypeDef * UTILS_PLLInitStruct,LL_UTILS_ClkInitTypeDef * UTILS_ClkInitStruct)511 ErrorStatus LL_PLL_ConfigSystemClock_HSE(uint32_t HSEFrequency, uint32_t HSEBypass,
512 LL_UTILS_PLLInitTypeDef *UTILS_PLLInitStruct,
513 LL_UTILS_ClkInitTypeDef *UTILS_ClkInitStruct)
514 {
515 ErrorStatus status;
516 #ifdef USE_FULL_ASSERT
517 uint32_t vcoinput_freq;
518 uint32_t vcooutput_freq;
519 #endif /* USE_FULL_ASSERT */
520 uint32_t pllfreq;
521
522 /* Check the parameters */
523 assert_param(IS_LL_UTILS_PLLM_VALUE(UTILS_PLLInitStruct->PLLM));
524 assert_param(IS_LL_UTILS_PLLN_VALUE(UTILS_PLLInitStruct->PLLN));
525 assert_param(IS_LL_UTILS_PLLP_VALUE(UTILS_PLLInitStruct->PLLP));
526 assert_param(IS_LL_UTILS_FRACN_VALUE(UTILS_PLLInitStruct->FRACN));
527 assert_param(IS_LL_UTILS_HSE_FREQUENCY(HSEFrequency));
528 assert_param(IS_LL_UTILS_HSE_BYPASS(HSEBypass));
529
530 /* Check VCO Input frequency */
531 #ifdef USE_FULL_ASSERT
532 vcoinput_freq = HSEFrequency / UTILS_PLLInitStruct->PLLM;
533 assert_param(IS_LL_UTILS_PLLVCO_INPUT(vcoinput_freq, UTILS_PLLInitStruct->VCO_Input));
534 #endif /* USE_FULL_ASSERT */
535
536 /* Check VCO output frequency */
537 #ifdef USE_FULL_ASSERT
538 vcooutput_freq = LL_RCC_CalcPLLClockFreq(HSEFrequency, UTILS_PLLInitStruct->PLLM, UTILS_PLLInitStruct->PLLN,
539 UTILS_PLLInitStruct->FRACN, 1U);
540 assert_param(IS_LL_UTILS_PLLVCO_OUTPUT(vcooutput_freq, UTILS_PLLInitStruct->VCO_Output));
541 #endif /* USE_FULL_ASSERT */
542
543 /* Check VCO Input/output ranges compatibility */
544 assert_param(IS_LL_UTILS_CHECK_VCO_RANGES(UTILS_PLLInitStruct->VCO_Input, UTILS_PLLInitStruct->VCO_Output));
545
546 /* Check that no PLL is enabled and thus ready for configuration */
547 if (UTILS_IsPLLsNotBusy() == SUCCESS)
548 {
549 /* Calculate the new PLL output frequency */
550 pllfreq = UTILS_GetPLLOutputFrequency(HSEFrequency, UTILS_PLLInitStruct);
551
552 /* Enable HSE if not enabled */
553 if (LL_RCC_HSE_IsReady() != 1U)
554 {
555 /* Check if need to enable HSE bypass feature or not */
556 if (HSEBypass == LL_UTILS_HSEBYPASS_ON)
557 {
558 LL_RCC_HSE_EnableBypass();
559 }
560 else
561 {
562 LL_RCC_HSE_DisableBypass();
563 }
564
565 /* Enable HSE */
566 LL_RCC_HSE_Enable();
567 while (LL_RCC_HSE_IsReady() != 1U)
568 {
569 /* Wait for HSE ready */
570 }
571 }
572
573 /* Configure PLL */
574 LL_RCC_PLL1FRACN_Disable();
575 LL_RCC_PLL_SetSource(LL_RCC_PLLSOURCE_HSE);
576 LL_RCC_PLL1_SetVCOInputRange(UTILS_PLLInitStruct->VCO_Input);
577 LL_RCC_PLL1_SetVCOOutputRange(UTILS_PLLInitStruct->VCO_Output);
578 LL_RCC_PLL1_SetM(UTILS_PLLInitStruct->PLLM);
579 LL_RCC_PLL1_SetN(UTILS_PLLInitStruct->PLLN);
580 LL_RCC_PLL1_SetP(UTILS_PLLInitStruct->PLLP);
581 LL_RCC_PLL1_SetFRACN(UTILS_PLLInitStruct->FRACN);
582 LL_RCC_PLL1FRACN_Enable();
583 LL_RCC_PLL1_SetFRACN(UTILS_PLLInitStruct->FRACN);
584 LL_RCC_PLL1FRACN_Enable();
585
586 /* Enable PLL and switch system clock to PLL */
587 status = UTILS_EnablePLLAndSwitchSystem(pllfreq, UTILS_ClkInitStruct);
588 }
589 else
590 {
591 /* Current PLL configuration cannot be modified */
592 status = ERROR;
593 }
594
595 return status;
596 }
597
598 /**
599 * @}
600 */
601
602 /**
603 * @brief Update number of Flash wait states in line with new frequency and current
604 voltage range.
605 * @param HCLK_Frequency HCLK frequency
606 * @retval An ErrorStatus enumeration value:
607 * - SUCCESS: Latency has been modified
608 * - ERROR: Latency cannot be modified
609 */
LL_SetFlashLatency(uint32_t HCLK_Frequency)610 ErrorStatus LL_SetFlashLatency(uint32_t HCLK_Frequency)
611 {
612 ErrorStatus status = SUCCESS;
613 uint32_t timeout;
614 uint32_t getlatency;
615 uint32_t latency;
616
617 /* Frequency cannot be equal to 0 */
618 if (HCLK_Frequency == 0U)
619 {
620 status = ERROR;
621 }
622 else
623 {
624 if (LL_PWR_GetRegulVoltageScaling() == LL_PWR_REGU_VOLTAGE_SCALE0) /* Scale 0 */
625 {
626 if ((HCLK_Frequency > UTILS_SCALE0_LATENCY4_FREQ) && (HCLK_Frequency <= UTILS_SCALE0_LATENCY5_FREQ))
627 {
628 latency = LL_FLASH_LATENCY_5; /* 5WS (6 CPU cycles) */
629 }
630 else if ((HCLK_Frequency > UTILS_SCALE0_LATENCY3_FREQ) && (HCLK_Frequency <= UTILS_SCALE0_LATENCY4_FREQ))
631 {
632 latency = LL_FLASH_LATENCY_4; /* 4WS (5 CPU cycles) */
633 }
634 else if ((HCLK_Frequency > UTILS_SCALE0_LATENCY2_FREQ) && (HCLK_Frequency <= UTILS_SCALE0_LATENCY3_FREQ))
635 {
636 latency = LL_FLASH_LATENCY_3; /* 3WS (4 CPU cycles) */
637 }
638 else if ((HCLK_Frequency > UTILS_SCALE0_LATENCY1_FREQ) && (HCLK_Frequency <= UTILS_SCALE0_LATENCY2_FREQ))
639 {
640 latency = LL_FLASH_LATENCY_2; /* 2WS (3 CPU cycles) */
641 }
642 else if ((HCLK_Frequency > UTILS_SCALE0_LATENCY0_FREQ) && (HCLK_Frequency <= UTILS_SCALE0_LATENCY1_FREQ))
643 {
644 latency = LL_FLASH_LATENCY_1; /* 1WS (2 CPU cycles) */
645 }
646 else
647 {
648 latency = LL_FLASH_LATENCY_0; /* 0WS (1 CPU cycles) */
649 }
650 }
651 else /* Scale 1 */
652 {
653 if ((HCLK_Frequency > UTILS_SCALE1_LATENCY4_FREQ) && (HCLK_Frequency <= UTILS_SCALE1_LATENCY5_FREQ))
654 {
655 latency = LL_FLASH_LATENCY_5; /* 5WS (6 CPU cycles) */
656 }
657 else if ((HCLK_Frequency > UTILS_SCALE1_LATENCY3_FREQ) && (HCLK_Frequency <= UTILS_SCALE1_LATENCY4_FREQ))
658 {
659 latency = LL_FLASH_LATENCY_4; /* 4WS (5 CPU cycles) */
660 }
661 else if ((HCLK_Frequency > UTILS_SCALE1_LATENCY2_FREQ) && (HCLK_Frequency <= UTILS_SCALE1_LATENCY3_FREQ))
662 {
663 latency = LL_FLASH_LATENCY_3; /* 3WS (4 CPU cycles) */
664 }
665 else if ((HCLK_Frequency > UTILS_SCALE1_LATENCY1_FREQ) && (HCLK_Frequency <= UTILS_SCALE1_LATENCY2_FREQ))
666 {
667 latency = LL_FLASH_LATENCY_2; /* 2WS (3 CPU cycles) */
668 }
669 else if ((HCLK_Frequency > UTILS_SCALE1_LATENCY0_FREQ) && (HCLK_Frequency <= UTILS_SCALE1_LATENCY1_FREQ))
670 {
671 latency = LL_FLASH_LATENCY_1; /* 1WS (2 CPU cycles) */
672 }
673 else
674 {
675 latency = LL_FLASH_LATENCY_0; /* 0WS (1 CPU cycles) */
676 }
677 }
678
679 LL_FLASH_SetLatency(latency);
680
681 /* Check that the new number of wait states is taken into account to access the Flash
682 memory by reading the FLASH_ACR register */
683 timeout = 2;
684 do
685 {
686 /* Wait for Flash latency to be updated */
687 getlatency = LL_FLASH_GetLatency();
688 timeout--;
689 } while ((getlatency != latency) && (timeout > 0U));
690
691 if (getlatency != latency)
692 {
693 status = ERROR;
694 }
695 }
696
697 return status;
698 }
699
700
701 /**
702 * @}
703 */
704
705 /** @addtogroup UTILS_LL_Private_Functions
706 * @{
707 */
708
709
710 /**
711 * @brief Function to Get PLL Output frequency
712 * @param PLL_InputFrequency PLL input frequency (in Hz)
713 * @param UTILS_PLLInitStruct pointer to a @ref LL_UTILS_PLLInitTypeDef structure that contains
714 * the configuration information for the PLL.
715 * @retval PLL output frequency (in Hz)
716 */
UTILS_GetPLLOutputFrequency(uint32_t PLL_InputFrequency,const LL_UTILS_PLLInitTypeDef * UTILS_PLLInitStruct)717 static uint32_t UTILS_GetPLLOutputFrequency(uint32_t PLL_InputFrequency,
718 const LL_UTILS_PLLInitTypeDef *UTILS_PLLInitStruct)
719 {
720 uint32_t pllfreq;
721
722 /* Check the parameters */
723 assert_param(IS_LL_UTILS_PLLM_VALUE(UTILS_PLLInitStruct->PLLM));
724 assert_param(IS_LL_UTILS_PLLN_VALUE(UTILS_PLLInitStruct->PLLN));
725 assert_param(IS_LL_UTILS_PLLP_VALUE(UTILS_PLLInitStruct->PLLP));
726 assert_param(IS_LL_UTILS_FRACN_VALUE(UTILS_PLLInitStruct->FRACN));
727
728 pllfreq = LL_RCC_CalcPLLClockFreq(PLL_InputFrequency, UTILS_PLLInitStruct->PLLM, UTILS_PLLInitStruct->PLLN,
729 UTILS_PLLInitStruct->FRACN, UTILS_PLLInitStruct->PLLP);
730
731 return pllfreq;
732 }
733
734 /**
735 * @brief Check that all PLLs are not busy therefore configuration can be done
736 * @retval An ErrorStatus enumeration value:
737 * - SUCCESS: All PLLs are ready so configuration can be done
738 * - ERROR: One PLL at least is busy
739 */
UTILS_IsPLLsNotBusy(void)740 static ErrorStatus UTILS_IsPLLsNotBusy(void)
741 {
742 ErrorStatus status = SUCCESS;
743
744 /* Check if one of the PLL1 is busy */
745 if (LL_RCC_PLL1_IsReady() != 0U)
746 {
747 /* PLL1 configuration cannot be done */
748 status = ERROR;
749 }
750
751 /* Check if one of the PLL2 is busy */
752 if (LL_RCC_PLL2_IsReady() != 0U)
753 {
754 /* PLL2 configuration cannot be done */
755 status = ERROR;
756 }
757
758 /* Check if one of the PLL3 is busy */
759 if (LL_RCC_PLL3_IsReady() != 0U)
760 {
761 /* PLL3 configuration cannot be done */
762 status = ERROR;
763 }
764
765 return status;
766 }
767
768 /**
769 * @brief Function to enable PLL and switch system clock to PLL
770 * @param SYSCLK_Frequency SYSCLK frequency
771 * @param UTILS_ClkInitStruct pointer to a @ref LL_UTILS_ClkInitTypeDef structure that contains
772 * the configuration information for the BUS prescalers.
773 * @retval An ErrorStatus enumeration value:
774 * - SUCCESS: No problem to switch system to PLL
775 * - ERROR: Problem to switch system to PLL
776 */
UTILS_EnablePLLAndSwitchSystem(uint32_t SYSCLK_Frequency,LL_UTILS_ClkInitTypeDef * UTILS_ClkInitStruct)777 static ErrorStatus UTILS_EnablePLLAndSwitchSystem(uint32_t SYSCLK_Frequency,
778 LL_UTILS_ClkInitTypeDef *UTILS_ClkInitStruct)
779 {
780 ErrorStatus status = SUCCESS;
781 uint32_t new_sysclk_frequency;
782 uint32_t new_hclk_frequency;
783
784 assert_param(IS_LL_UTILS_SYSCLK_DIV(UTILS_ClkInitStruct->SYSCLKDivider));
785 assert_param(IS_LL_UTILS_AHB_DIV(UTILS_ClkInitStruct->AHBCLKDivider));
786 assert_param(IS_LL_UTILS_APB1_DIV(UTILS_ClkInitStruct->APB1CLKDivider));
787 assert_param(IS_LL_UTILS_APB2_DIV(UTILS_ClkInitStruct->APB2CLKDivider));
788 assert_param(IS_LL_UTILS_APB4_DIV(UTILS_ClkInitStruct->APB4CLKDivider));
789 assert_param(IS_LL_UTILS_APB5_DIV(UTILS_ClkInitStruct->APB5CLKDivider));
790
791 /* Calculate the new HCLK frequency */
792 new_sysclk_frequency = LL_RCC_CALC_SYSCLK_FREQ(SYSCLK_Frequency, UTILS_ClkInitStruct->SYSCLKDivider);
793 new_hclk_frequency = LL_RCC_CALC_HCLK_FREQ(new_sysclk_frequency, UTILS_ClkInitStruct->AHBCLKDivider);
794
795 /* Increasing the number of wait states because of higher CPU frequency */
796 if (SystemCoreClock < new_sysclk_frequency)
797 {
798 /* Set FLASH latency to highest latency */
799 status = LL_SetFlashLatency(new_hclk_frequency);
800 }
801
802 /* Update system clock configuration */
803 if (status == SUCCESS)
804 {
805 /* Enable PLL */
806 LL_RCC_PLL1_Enable();
807 while (LL_RCC_PLL1_IsReady() != 1U)
808 {
809 /* Wait for PLL ready */
810 }
811
812 LL_RCC_PLL1P_Enable();
813
814 /* Set All APBxPrescaler to the Highest Divider */
815 LL_RCC_SetAPB1Prescaler(LL_RCC_APB1_DIV_16);
816 LL_RCC_SetAPB2Prescaler(LL_RCC_APB2_DIV_16);
817 LL_RCC_SetAPB4Prescaler(LL_RCC_APB4_DIV_16);
818 LL_RCC_SetAPB5Prescaler(LL_RCC_APB5_DIV_16);
819
820 /* Set SYS prescaler*/
821 LL_RCC_SetSysPrescaler(UTILS_ClkInitStruct->SYSCLKDivider);
822
823 /* Set AHB prescaler*/
824 LL_RCC_SetAHBPrescaler(UTILS_ClkInitStruct->AHBCLKDivider);
825
826 /* Sysclk activation on the main PLL */
827 LL_RCC_SetSysClkSource(LL_RCC_SYS_CLKSOURCE_PLL1);
828 while (LL_RCC_GetSysClkSource() != LL_RCC_SYS_CLKSOURCE_STATUS_PLL1)
829 {
830 /* Wait for system clock switch to PLL */
831 }
832
833 /* Set APBn prescaler*/
834 LL_RCC_SetAPB1Prescaler(UTILS_ClkInitStruct->APB1CLKDivider);
835 LL_RCC_SetAPB2Prescaler(UTILS_ClkInitStruct->APB2CLKDivider);
836 LL_RCC_SetAPB4Prescaler(UTILS_ClkInitStruct->APB4CLKDivider);
837 LL_RCC_SetAPB5Prescaler(UTILS_ClkInitStruct->APB5CLKDivider);
838
839 /* Decreasing the number of wait states because of lower CPU frequency */
840 if (SystemCoreClock > new_sysclk_frequency)
841 {
842 /* Set FLASH latency to lowest latency */
843 status = LL_SetFlashLatency(new_hclk_frequency);
844 }
845
846 /* Update SystemCoreClock variable */
847 if (status == SUCCESS)
848 {
849 LL_SetSystemCoreClock(new_sysclk_frequency);
850 }
851 }
852
853 return status;
854 }
855
856 /**
857 * @}
858 */
859
860 /**
861 * @}
862 */
863
864 /**
865 * @}
866 */
867