1 /**
2 ******************************************************************************
3 * @file stm32mp1xx_ll_utils.c
4 * @author MCD Application Team
5 * @brief UTILS LL module driver.
6 ******************************************************************************
7 * @attention
8 *
9 * Copyright (c) 2019 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 "stm32mp1xx_ll_utils.h"
20 #include "stm32mp1xx_ll_system.h"
21 #include "stm32mp1xx_ll_bus.h"
22 #include "stm32mp1xx_ll_rcc.h"
23
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 STM32MP1xx_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
45 /* Defines used for PLL type */
46 #define UTILS_PLL_1600_TYPE 00000000U
47 #define UTILS_PLL_800_TYPE 00000001U
48
49 /* Defines used for PLL range */
50 #define UTILS_PLL1600_INPUT_MIN 8000000U /*!< Frequency min for PLL1600 type input, in Hz */
51 #define UTILS_PLL1600_INPUT_MAX 16000000U /*!< Frequency max for PLL1600 type input, in Hz */
52 #define UTILS_PLL800_INPUT_MIN 4000000U /*!< Frequency min for PLL800 type input, in Hz */
53 #define UTILS_PLL800_INPUT_MED 8000000U /*!< Frequency medium range for PLL800 type input, in Hz */
54 #define UTILS_PLL800_INPUT_MAX 16000000U /*!< Frequency max for PLL800 type input, in Hz */
55
56 #define UTILS_PLL1600_OUTPUT_MIN 800000000U /*!< Frequency min for PLL1600 type output, in Hz */
57 #define UTILS_PLL1600_OUTPUT_MAX 1600000000U /*!< Frequency max for PLL1600 type output, in Hz */
58 #define UTILS_PLL800_OUTPUT_MIN 400000000U /*!< Frequency min for PLL800 type output, in Hz */
59 #define UTILS_PLL800_OUTPUT_MAX 800000000U /*!< Frequency max for PLL800 type output, in Hz */
60
61 /* Defines used for HSE range */
62 #define UTILS_HSE_FREQUENCY_MIN 8000000U /*!< Frequency min for HSE frequency, in Hz */
63 #define UTILS_HSE_FREQUENCY_MAX 48000000U /*!< Frequency max for HSE frequency, in Hz */
64
65 /**
66 * @}
67 */
68
69 /* Private macros ------------------------------------------------------------*/
70 /** @addtogroup UTILS_LL_Private_Macros
71 * @{
72 */
73 #define IS_LL_UTILS_APB1_DIV(__VALUE__) (((__VALUE__) == LL_RCC_APB1_DIV_1) \
74 || ((__VALUE__) == LL_RCC_APB1_DIV_2) \
75 || ((__VALUE__) == LL_RCC_APB1_DIV_4) \
76 || ((__VALUE__) == LL_RCC_APB1_DIV_8) \
77 || ((__VALUE__) == LL_RCC_APB1_DIV_16))
78
79 #define IS_LL_UTILS_APB2_DIV(__VALUE__) (((__VALUE__) == LL_RCC_APB2_DIV_1) \
80 || ((__VALUE__) == LL_RCC_APB2_DIV_2) \
81 || ((__VALUE__) == LL_RCC_APB2_DIV_4) \
82 || ((__VALUE__) == LL_RCC_APB2_DIV_8) \
83 || ((__VALUE__) == LL_RCC_APB2_DIV_16))
84
85 #define IS_LL_UTILS_APB3_DIV(__VALUE__) (((__VALUE__) == LL_RCC_APB3_DIV_1) \
86 || ((__VALUE__) == LL_RCC_APB3_DIV_2) \
87 || ((__VALUE__) == LL_RCC_APB3_DIV_4) \
88 || ((__VALUE__) == LL_RCC_APB3_DIV_8) \
89 || ((__VALUE__) == LL_RCC_APB3_DIV_16))
90
91 #define IS_LL_UTILS_APB4_DIV(__VALUE__) (((__VALUE__) == LL_RCC_APB4_DIV_1) \
92 || ((__VALUE__) == LL_RCC_APB4_DIV_2) \
93 || ((__VALUE__) == LL_RCC_APB4_DIV_4) \
94 || ((__VALUE__) == LL_RCC_APB4_DIV_8) \
95 || ((__VALUE__) == LL_RCC_APB4_DIV_16))
96
97 #define IS_LL_UTILS_APB5_DIV(__VALUE__) (((__VALUE__) == LL_RCC_APB5_DIV_1) \
98 || ((__VALUE__) == LL_RCC_APB5_DIV_2) \
99 || ((__VALUE__) == LL_RCC_APB5_DIV_4) \
100 || ((__VALUE__) == LL_RCC_APB5_DIV_8) \
101 || ((__VALUE__) == LL_RCC_APB5_DIV_16))
102
103 #define IS_LL_UTILS_PLLM_VALUE(__VALUE__) ((1U <= (__VALUE__)) && ((__VALUE__) <= 64U))
104
105 #define IS_LL_UTILS_PLLN_VALUE(__VALUE__) ((4U <= (__VALUE__)) && ((__VALUE__) <= 512U))
106
107 #define IS_LL_UTILS_PLLP_VALUE(__VALUE__) ((1U <= (__VALUE__)) && ((__VALUE__) <= 128U))
108
109 #define IS_LL_UTILS_FRACV_VALUE(__VALUE__) ((__VALUE__) <= 0x1FFFU)
110
111 #define IS_LL_UTILS_PLLVCO_INPUT(__VALUE__, __TYPE__) ( \
112 (((__TYPE__) == UTILS_PLL_1600_TYPE) && (UTILS_PLL1600_INPUT_MIN <= (__VALUE__)) && ((__VALUE__) <= UTILS_PLL1600_INPUT_MAX)) || \
113 (((__TYPE__) == UTILS_PLL_800_TYPE) && (UTILS_PLL800_INPUT_MIN <= (__VALUE__)) && ((__VALUE__) <= UTILS_PLL800_INPUT_MAX)))
114
115 #define IS_LL_UTILS_PLLVCO_OUTPUT(__VALUE__, __TYPE__) ( \
116 (((__TYPE__) == UTILS_PLL_1600_TYPE) && (UTILS_PLL1600_OUTPUT_MIN <= (__VALUE__)) && ((__VALUE__) <= UTILS_PLL1600_OUTPUT_MAX)) || \
117 (((__TYPE__) == UTILS_PLL_800_TYPE) && (UTILS_PLL800_OUTPUT_MIN <= (__VALUE__)) && ((__VALUE__) <= UTILS_PLL800_OUTPUT_MAX)))
118
119 #define IS_LL_UTILS_HSE_BYPASS(__STATE__) (((__STATE__) == LL_UTILS_HSEBYPASS_ON) || \
120 ((__STATE__) == LL_UTILS_HSEBYPASSDIG_ON) || \
121 ((__STATE__) == LL_UTILS_HSEBYPASS_OFF))
122
123 #define IS_LL_UTILS_HSE_FREQUENCY(__FREQUENCY__) (((__FREQUENCY__) >= UTILS_HSE_FREQUENCY_MIN) && ((__FREQUENCY__) <= UTILS_HSE_FREQUENCY_MAX))
124 /**
125 * @}
126 */
127 /* Private function prototypes -----------------------------------------------*/
128 /** @defgroup UTILS_LL_Private_Functions UTILS Private functions
129 * @{
130 */
131 static void UTILS_CheckPLLParameters(LL_UTILS_PLLTypeDef *UTILS_PLLStruct);
132 static uint32_t UTILS_GetPLLOutputFrequency(uint32_t PLL_InputFrequency, LL_UTILS_PLLTypeDef *UTILS_PLLStruct);
133 static void UTILS_EnablePLLAndSwitchSystem(uint32_t SYSCLK_Frequency, LL_UTILS_ClkInitTypeDef *UTILS_ClkInitStruct);
134 static ErrorStatus UTILS_IsPLLsReady(void);
135 /**
136 * @}
137 */
138
139 /* Exported functions --------------------------------------------------------*/
140 /** @addtogroup UTILS_LL_Exported_Functions
141 * @{
142 */
143
144 /** @addtogroup UTILS_LL_EF_DELAY
145 * @{
146 */
147 #if defined(CORE_CM4)
148 /**
149 * @brief This function configures the Cortex-M SysTick source to have 1ms time base.
150 * @note When a RTOS is used, it is recommended to avoid changing the Systick
151 * configuration by calling this function, for a delay use rather osDelay RTOS service.
152 * @param CPU_Frequency Core frequency in Hz
153 * @note CPU_Frequency can be calculated thanks to RCC helper macro or function
154 * @ref LL_RCC_GetSystemClocksFreq
155 * - Use MCU_Frequency structure element returned by function above
156 * @retval None
157 */
LL_Init1msTick(uint32_t CPU_Frequency)158 void LL_Init1msTick(uint32_t CPU_Frequency)
159 {
160 /* Use frequency provided in argument */
161 LL_InitTick(CPU_Frequency, 1000U);
162 }
163
164 /**
165 * @brief This function provides accurate delay (in milliseconds) based
166 * on SysTick counter flag for Cortex-M processor
167 * @note When a RTOS is used, it is recommended to avoid using blocking delay
168 * and use rather osDelay service.
169 * @note To respect 1ms timebase, user should call @ref LL_Init1msTick function which
170 * will configure Systick to 1ms
171 * @param Delay specifies the delay time length, in milliseconds.
172 * @retval None
173 */
LL_mDelay(uint32_t Delay)174 void LL_mDelay(uint32_t Delay)
175 {
176 uint32_t count = Delay;
177 __IO uint32_t tmp = SysTick->CTRL; /* Clear the COUNTFLAG first */
178 /* Add this code to indicate that local variable is not used */
179 ((void)tmp);
180
181 /* Add a period to guaranty minimum wait */
182 if (count < LL_MAX_DELAY)
183 {
184 count++;
185 }
186
187 while (count != 0U)
188 {
189 if ((SysTick->CTRL & SysTick_CTRL_COUNTFLAG_Msk) != 0U)
190 {
191 count--;
192 }
193 }
194 }
195 #endif /* CORE_CM4 */
196 /**
197 * @}
198 */
199
200 /** @addtogroup UTILS_EF_SYSTEM
201 * @brief System Configuration functions
202 *
203 @verbatim
204 ===============================================================================
205 ##### System Configuration functions #####
206 ===============================================================================
207 [..]
208 MPUSS core (CA7), MCU core (CM4), ACLK, HCLK and APB buses clocks
209 configuration
210
211 (+) The maximum frequency of the SystemCoreClock MPUSS (CA7) is 800 MHz
212 (+) The maximum frequency of the ACLK (plus HCLK5 and HCLK6) is 266 MHz.
213 (+) The maximum frequency of the SystemCoreClock MCU (CM4) is 209 MHz
214 (+) The maximum frequency of the PCLK1, PCLK2 and PCLK3 is 104.5 MHz.
215 (+) The maximum frequency of the PCLK4 and PCLK5 is 133 MHz.
216 @endverbatim
217 * @{
218 */
219 /**
220 * @brief This function sets directly SystemCoreClock CMSIS variable.
221 * @note Variable can be calculated also through SystemCoreClockUpdate function.
222 * @param CPU_Frequency Core frequency in Hz
223 * @note CPU_Frequency can be calculated thanks to RCC helper macro or function
224 * @ref LL_RCC_GetSystemClocksFreq
225 * - When code runs on CM4 core, use MCU_Frequency structure element
226 * returned by function above
227 * - When code runs on CA7 core, use MPUSS_Frequency structure element
228 * returned by function above
229 * @retval None
230 */
LL_SetSystemCoreClock(uint32_t CPU_Frequency)231 void LL_SetSystemCoreClock(uint32_t CPU_Frequency)
232 {
233 /* System core clock frequency */
234 SystemCoreClock = CPU_Frequency;
235 }
236
237 /**
238 * @brief This function configures system clocks with HSE as clock source of the PLLs
239 * @note The application need to ensure that PLLs are disabled.
240 * @note Function is based on the following formula where x = {1,2,3,4} and Y = {P,Q,R}:
241 * - PLLxY output frequency = (((HSE frequency / PLLxM) * (PLLxN + (FRACV / 8192))) / PLLxY)
242 * - PLLxM: ensure that the VCO input frequency ranges from 8 to 16 MHz
243 * for PLL1600 type and from 4 to 16 MHz for PLL_800 type
244 * (PLLxVCO_input = HSE frequency / PLLxM)
245 * - PLLxN: ensure that the VCO output frequency is between 800 and 1600
246 * MHz for PLL_1600 type and between 400 and 800 MHz for PLL_800 type
247 * (PLLxVCO_output = PLLVCO_input * (PLLxN + (FRACV / 8192)))
248 * - PLLxP: ensure that max frequency is reached (PLLxVCO_output / PLLxP)
249 * - PLL1P output max frequency is 800000000 Hz
250 * - PLL2P output max frequency is 266000000 Hz
251 * - PLL2Q output max frequency is 533000000 Hz
252 * - PLL2R output max frequency is 533000000 Hz
253 * - PLL3P output max frequency is 209000000 Hz
254 * @param HSEFrequency Value between 8000000 Hz and 48000000 Hz
255 * @param HSEBypass This parameter can be one of the following values:
256 * @arg @ref LL_UTILS_HSEBYPASS_ON
257 * @arg @ref LL_UTILS_HSEBYPASSDIG_ON
258 * @arg @ref LL_UTILS_HSEBYPASS_OFF
259 * @param UTILS_PLLsInitStruct pointer to a @ref LL_UTILS_PLLsInitTypeDef structure that contains
260 * the configuration information for the PLL.
261 * @param UTILS_ClkInitStruct pointer to a @ref LL_UTILS_ClkInitTypeDef structure that contains
262 * the configuration information for the BUS prescalers.
263 * @retval An ErrorStatus enumeration value:
264 * - SUCCESS: Max frequency configuration done
265 * - ERROR: Max frequency configuration not done
266 */
LL_PLL_ConfigSystemClock_HSE(uint32_t HSEFrequency,uint32_t HSEBypass,LL_UTILS_PLLsInitTypeDef * UTILS_PLLsInitStruct,LL_UTILS_ClkInitTypeDef * UTILS_ClkInitStruct)267 ErrorStatus LL_PLL_ConfigSystemClock_HSE(uint32_t HSEFrequency, uint32_t HSEBypass,
268 LL_UTILS_PLLsInitTypeDef *UTILS_PLLsInitStruct,
269 LL_UTILS_ClkInitTypeDef *UTILS_ClkInitStruct)
270 {
271 ErrorStatus status = SUCCESS;
272 uint32_t pllfreq;
273 uint32_t vcoinput_freqPLL3, vcoinput_freqPLL4;
274 #ifdef USE_FULL_ASSERT
275 uint32_t vcoinput_freq, vcooutput_freq;
276 #endif
277
278 /* Check the parameters */
279 UTILS_CheckPLLParameters(&UTILS_PLLsInitStruct->PLL1);
280 UTILS_CheckPLLParameters(&UTILS_PLLsInitStruct->PLL2);
281 UTILS_CheckPLLParameters(&UTILS_PLLsInitStruct->PLL3);
282 UTILS_CheckPLLParameters(&UTILS_PLLsInitStruct->PLL4);
283 assert_param(IS_LL_UTILS_HSE_FREQUENCY(HSEFrequency));
284 assert_param(IS_LL_UTILS_HSE_BYPASS(HSEBypass));
285
286 vcoinput_freqPLL3 = HSEFrequency / UTILS_PLLsInitStruct->PLL3.PLLM;
287 vcoinput_freqPLL4 = HSEFrequency / UTILS_PLLsInitStruct->PLL4.PLLM;
288
289 #ifdef USE_FULL_ASSERT
290 /* Check VCO Input frequency */
291 vcoinput_freq = HSEFrequency / UTILS_PLLsInitStruct->PLL1.PLLM;
292 assert_param(IS_LL_UTILS_PLLVCO_INPUT(vcoinput_freq, UTILS_PLL_1600_TYPE));
293
294 vcoinput_freq = HSEFrequency / UTILS_PLLsInitStruct->PLL2.PLLM;
295 assert_param(IS_LL_UTILS_PLLVCO_INPUT(vcoinput_freq, UTILS_PLL_1600_TYPE));
296
297 assert_param(IS_LL_UTILS_PLLVCO_INPUT(vcoinput_freqPLL3, UTILS_PLL_800_TYPE));
298 assert_param(IS_LL_UTILS_PLLVCO_INPUT(vcoinput_freqPLL4, UTILS_PLL_800_TYPE));
299
300 /* Check VCO Output frequency */
301 vcooutput_freq = (LL_RCC_CalcPLLClockFreq(
302 HSEFrequency,
303 UTILS_PLLsInitStruct->PLL1.PLLM,
304 UTILS_PLLsInitStruct->PLL1.PLLN,
305 UTILS_PLLsInitStruct->PLL1.PLLFRACV,
306 1U) * 2U);
307 assert_param(IS_LL_UTILS_PLLVCO_OUTPUT(vcooutput_freq, UTILS_PLL_1600_TYPE));
308
309 vcooutput_freq = (LL_RCC_CalcPLLClockFreq(
310 HSEFrequency,
311 UTILS_PLLsInitStruct->PLL2.PLLM,
312 UTILS_PLLsInitStruct->PLL2.PLLN,
313 UTILS_PLLsInitStruct->PLL2.PLLFRACV,
314 1U) * 2U);
315 assert_param(IS_LL_UTILS_PLLVCO_OUTPUT(vcooutput_freq, UTILS_PLL_1600_TYPE));
316
317 vcooutput_freq = LL_RCC_CalcPLLClockFreq(
318 HSEFrequency,
319 UTILS_PLLsInitStruct->PLL3.PLLM,
320 UTILS_PLLsInitStruct->PLL3.PLLN,
321 UTILS_PLLsInitStruct->PLL3.PLLFRACV,
322 1U);
323 assert_param(IS_LL_UTILS_PLLVCO_OUTPUT(vcooutput_freq, UTILS_PLL_800_TYPE));
324
325 vcooutput_freq = LL_RCC_CalcPLLClockFreq(
326 HSEFrequency,
327 UTILS_PLLsInitStruct->PLL4.PLLM,
328 UTILS_PLLsInitStruct->PLL4.PLLN,
329 UTILS_PLLsInitStruct->PLL4.PLLFRACV,
330 1U);
331 assert_param(IS_LL_UTILS_PLLVCO_OUTPUT(vcooutput_freq, UTILS_PLL_800_TYPE));
332 #endif /* USE_FULL_ASSERT */
333
334 /* Check if one of the PLL is enabled */
335 if (UTILS_IsPLLsReady() == SUCCESS)
336 {
337 /* Check if need to enable HSE bypass feature or not */
338 if (HSEBypass == LL_UTILS_HSEBYPASS_ON)
339 {
340 LL_RCC_HSE_EnableBypass();
341 }
342 else if (HSEBypass == LL_UTILS_HSEBYPASSDIG_ON)
343 {
344 LL_RCC_HSE_EnableDigBypass();
345 }
346 else
347 {
348 /* Clear HSE BYPASS and HSE BYPASS DIGITAL bits */
349 LL_RCC_HSE_DisableDigBypass();
350 }
351
352 /* Enable HSE if not enabled */
353 if (LL_RCC_HSE_IsReady() != 1U)
354 {
355 LL_RCC_HSE_Enable();
356 while (LL_RCC_HSE_IsReady() != 1U)
357 {
358 /* Wait for HSE ready */
359 }
360 }
361
362 /* Configure PLL1 */
363 LL_RCC_PLL12_SetSource(LL_RCC_PLL12SOURCE_HSE);
364
365 LL_RCC_PLL1_SetM(UTILS_PLLsInitStruct->PLL1.PLLM);
366 LL_RCC_PLL1_SetN(UTILS_PLLsInitStruct->PLL1.PLLN);
367 LL_RCC_PLL1_SetP(UTILS_PLLsInitStruct->PLL1.PLLP);
368
369 LL_RCC_PLL1FRACV_Disable();
370 LL_RCC_PLL1_SetFRACV(UTILS_PLLsInitStruct->PLL1.PLLFRACV);
371 LL_RCC_PLL1FRACV_Enable();
372
373 LL_RCC_PLL1CSG_Disable();
374
375 /* Configure PLL2 */
376 LL_RCC_PLL2_SetM(UTILS_PLLsInitStruct->PLL2.PLLM);
377 LL_RCC_PLL2_SetN(UTILS_PLLsInitStruct->PLL2.PLLN);
378 LL_RCC_PLL2_SetP(UTILS_PLLsInitStruct->PLL2.PLLP);
379 LL_RCC_PLL2_SetQ(UTILS_PLLsInitStruct->PLL2.PLLQ);
380 LL_RCC_PLL2_SetR(UTILS_PLLsInitStruct->PLL2.PLLR);
381
382 LL_RCC_PLL2FRACV_Disable();
383 LL_RCC_PLL2_SetFRACV(UTILS_PLLsInitStruct->PLL2.PLLFRACV);
384 LL_RCC_PLL2FRACV_Enable();
385
386 LL_RCC_PLL2CSG_Disable();
387
388 /* Configure PLL3 */
389 LL_RCC_PLL3_SetSource(LL_RCC_PLL3SOURCE_HSE);
390
391 LL_RCC_PLL3_SetM(UTILS_PLLsInitStruct->PLL3.PLLM);
392 LL_RCC_PLL3_SetN(UTILS_PLLsInitStruct->PLL3.PLLN);
393 LL_RCC_PLL3_SetP(UTILS_PLLsInitStruct->PLL3.PLLP);
394 LL_RCC_PLL3_SetQ(UTILS_PLLsInitStruct->PLL3.PLLQ);
395 LL_RCC_PLL3_SetR(UTILS_PLLsInitStruct->PLL3.PLLR);
396
397 LL_RCC_PLL3FRACV_Disable();
398 LL_RCC_PLL3_SetFRACV(UTILS_PLLsInitStruct->PLL3.PLLFRACV);
399 LL_RCC_PLL3FRACV_Enable();
400
401 LL_RCC_PLL3CSG_Disable();
402
403 if (vcoinput_freqPLL3 >= UTILS_PLL800_INPUT_MED)
404 {
405 LL_RCC_PLL3_SetIFRGE(LL_RCC_PLL3IFRANGE_1);
406 }
407 else
408 {
409 LL_RCC_PLL3_SetIFRGE(LL_RCC_PLL3IFRANGE_0);
410 }
411
412 /* Configure PLL4 */
413 LL_RCC_PLL4_SetSource(LL_RCC_PLL4SOURCE_HSE);
414
415 LL_RCC_PLL4_SetM(UTILS_PLLsInitStruct->PLL4.PLLM);
416 LL_RCC_PLL4_SetN(UTILS_PLLsInitStruct->PLL4.PLLN);
417 LL_RCC_PLL4_SetP(UTILS_PLLsInitStruct->PLL4.PLLP);
418 LL_RCC_PLL4_SetQ(UTILS_PLLsInitStruct->PLL4.PLLQ);
419 LL_RCC_PLL4_SetR(UTILS_PLLsInitStruct->PLL4.PLLR);
420
421 LL_RCC_PLL4FRACV_Disable();
422 LL_RCC_PLL4_SetFRACV(UTILS_PLLsInitStruct->PLL4.PLLFRACV);
423 LL_RCC_PLL4FRACV_Enable();
424
425 LL_RCC_PLL4CSG_Disable();
426
427 if (vcoinput_freqPLL4 >= UTILS_PLL800_INPUT_MED)
428 {
429 LL_RCC_PLL4_SetIFRGE(LL_RCC_PLL4IFRANGE_1);
430 }
431 else
432 {
433 LL_RCC_PLL4_SetIFRGE(LL_RCC_PLL4IFRANGE_0);
434 }
435
436 /* Calculate the new PLL output frequency */
437 #if defined(CORE_CM4)
438 pllfreq = UTILS_GetPLLOutputFrequency(HSEFrequency, &UTILS_PLLsInitStruct->PLL3);
439 #else
440 #if defined(CORE_CA7)
441 pllfreq = UTILS_GetPLLOutputFrequency(HSEFrequency, &UTILS_PLLsInitStruct->PLL1);
442 #endif /* CORE_CA7 */
443 #endif /* CORE_CM4 */
444
445 /* Enable PLL and switch system clock to PLL */
446 UTILS_EnablePLLAndSwitchSystem(pllfreq, UTILS_ClkInitStruct);
447 }
448 else
449 {
450 /* Current PLL configuration cannot be modified */
451 status = ERROR;
452 }
453
454 return status;
455 }
456
457 /**
458 * @}
459 */
460
461 /**
462 * @}
463 */
464
465 /** @addtogroup UTILS_LL_Private_Functions
466 * @{
467 */
468
469 /**
470 * @brief Function to check PLL parameters
471 * @param UTILS_PLLStruct pointer to a @ref LL_UTILS_PLLTypeDef
472 * structure that contains the configuration information for the PLL.
473 * @retval None
474 */
UTILS_CheckPLLParameters(LL_UTILS_PLLTypeDef * UTILS_PLLStruct)475 void UTILS_CheckPLLParameters(LL_UTILS_PLLTypeDef *UTILS_PLLStruct)
476 {
477 /* Check the parameters */
478 assert_param(IS_LL_UTILS_PLLM_VALUE(UTILS_PLLStruct->PLLM));
479 assert_param(IS_LL_UTILS_PLLN_VALUE(UTILS_PLLStruct->PLLN));
480 assert_param(IS_LL_UTILS_PLLP_VALUE(UTILS_PLLStruct->PLLP));
481 assert_param(IS_LL_UTILS_FRACV_VALUE(UTILS_PLLStruct->PLLFRACV));
482 }
483
484 /**
485 * @brief Function to check that PLL can be modified
486 * @param PLL_InputFrequency PLL input frequency (in Hz)
487 * @param UTILS_PLLStruct pointer to a @ref LL_UTILS_PLLTypeDef
488 * structure that contains the configuration information for the PLL.
489 * @retval PLL output frequency (in Hz)
490 */
UTILS_GetPLLOutputFrequency(uint32_t PLL_InputFrequency,LL_UTILS_PLLTypeDef * UTILS_PLLStruct)491 static uint32_t UTILS_GetPLLOutputFrequency(uint32_t PLL_InputFrequency, LL_UTILS_PLLTypeDef *UTILS_PLLStruct)
492 {
493 uint32_t pllfreq;
494
495 /* Check the parameters */
496 UTILS_CheckPLLParameters(UTILS_PLLStruct);
497
498 pllfreq = LL_RCC_CalcPLLClockFreq(PLL_InputFrequency,
499 UTILS_PLLStruct->PLLM,
500 UTILS_PLLStruct->PLLN,
501 UTILS_PLLStruct->PLLFRACV,
502 UTILS_PLLStruct->PLLP);
503
504 return pllfreq;
505 }
506
507 /**
508 * @brief Check that all PLLs are ready therefore configuration can be done
509 * @retval An ErrorStatus enumeration value:
510 * - SUCCESS: All PLLs are ready so configuration can be done
511 * - ERROR: One PLL at least is busy
512 */
UTILS_IsPLLsReady(void)513 static ErrorStatus UTILS_IsPLLsReady(void)
514 {
515 ErrorStatus status = SUCCESS;
516
517 /* Check if one of the PLL1 is busy */
518 if (LL_RCC_PLL1_IsReady() != 0U)
519 {
520 /* PLL1 configuration cannot be done */
521 status = ERROR;
522 }
523
524 /* Check if one of the PLL2 is busy */
525 if (LL_RCC_PLL2_IsReady() != 0U)
526 {
527 /* PLL2 configuration cannot be done */
528 status = ERROR;
529 }
530
531 /* Check if one of the PLL3 is busy */
532 if (LL_RCC_PLL3_IsReady() != 0U)
533 {
534 /* PLL3 configuration cannot be done */
535 status = ERROR;
536 }
537
538 /* Check if one of the PLL4 is busy */
539 if (LL_RCC_PLL4_IsReady() != 0U)
540 {
541 /* PLL4 configuration cannot be done */
542 status = ERROR;
543 }
544
545 return status;
546 }
547
548 /**
549 * @brief Function to enable PLL and switch system core clock to PLL
550 * @param SYSCLK_CoreFrequency SYSCLK frequency
551 * @param UTILS_ClkInitStruct pointer to a @ref LL_UTILS_ClkInitTypeDef
552 * structure that contains the configuration information for the BUS
553 * prescalers.
554 * @retval None
555 */
UTILS_EnablePLLAndSwitchSystem(uint32_t SYSCLK_CoreFrequency,LL_UTILS_ClkInitTypeDef * UTILS_ClkInitStruct)556 static void UTILS_EnablePLLAndSwitchSystem(
557 uint32_t SYSCLK_CoreFrequency,
558 LL_UTILS_ClkInitTypeDef *UTILS_ClkInitStruct)
559 {
560 assert_param(IS_LL_UTILS_APB1_DIV(UTILS_ClkInitStruct->APB1CLKDivider));
561 assert_param(IS_LL_UTILS_APB2_DIV(UTILS_ClkInitStruct->APB2CLKDivider));
562 assert_param(IS_LL_UTILS_APB3_DIV(UTILS_ClkInitStruct->APB3CLKDivider));
563 assert_param(IS_LL_UTILS_APB4_DIV(UTILS_ClkInitStruct->APB4CLKDivider));
564 assert_param(IS_LL_UTILS_APB5_DIV(UTILS_ClkInitStruct->APB5CLKDivider));
565
566
567 /* Enable PLL1 */
568 LL_RCC_PLL1_Enable();
569 while (LL_RCC_PLL1_IsReady() != 1U)
570 {
571 /* Wait for PLL1 ready */
572 }
573 LL_RCC_PLL1P_Enable();
574
575 /* Enable PLL2 */
576 LL_RCC_PLL2_Enable();
577 while (LL_RCC_PLL2_IsReady() != 1U)
578 {
579 /* Wait for PLL2 ready */
580 }
581 LL_RCC_PLL2P_Enable();
582 LL_RCC_PLL2Q_Enable();
583 LL_RCC_PLL2R_Enable();
584
585 /* Enable PLL3 */
586 LL_RCC_PLL3_Enable();
587 while (LL_RCC_PLL3_IsReady() != 1U)
588 {
589 /* Wait for PLL3 ready */
590 }
591 LL_RCC_PLL3P_Enable();
592 LL_RCC_PLL3Q_Enable();
593 LL_RCC_PLL3R_Enable();
594
595 /* Enable PLL4 */
596 LL_RCC_PLL4_Enable();
597 while (LL_RCC_PLL4_IsReady() != 1U)
598 {
599 /* Wait for PLL4 ready */
600 }
601 LL_RCC_PLL4P_Enable();
602 LL_RCC_PLL4Q_Enable();
603 LL_RCC_PLL4R_Enable();
604
605 /* Set All APBxPrescaler to the Highest Divider */
606 LL_RCC_SetAPB1Prescaler(LL_RCC_APB1_DIV_16);
607 LL_RCC_SetAPB2Prescaler(LL_RCC_APB2_DIV_16);
608 LL_RCC_SetAPB3Prescaler(LL_RCC_APB3_DIV_16);
609 LL_RCC_SetAPB4Prescaler(LL_RCC_APB4_DIV_16);
610 LL_RCC_SetAPB5Prescaler(LL_RCC_APB5_DIV_16);
611
612 /* Set MPU Clock Selection */
613 LL_RCC_SetMPUClkSource(LL_RCC_MPU_CLKSOURCE_PLL1);
614 while (LL_RCC_GetMPUClkSource() != LL_RCC_MPU_CLKSOURCE_PLL1)
615 {}
616
617 /* Set AXI Sub-System Clock Selection */
618 LL_RCC_SetAXISSClkSource(LL_RCC_AXISS_CLKSOURCE_PLL2);
619 while (LL_RCC_GetAXISSClkSource() != LL_RCC_AXISS_CLKSOURCE_PLL2)
620 {}
621
622 /* Set MCU Sub-System Clock Selection */
623 LL_RCC_SetMCUSSClkSource(LL_RCC_MCUSS_CLKSOURCE_PLL3);
624 while (LL_RCC_GetMCUSSClkSource() != LL_RCC_MCUSS_CLKSOURCE_PLL3)
625 {}
626
627 /* Set APBn prescaler*/
628 LL_RCC_SetAPB1Prescaler(UTILS_ClkInitStruct->APB1CLKDivider);
629 LL_RCC_SetAPB2Prescaler(UTILS_ClkInitStruct->APB2CLKDivider);
630 LL_RCC_SetAPB3Prescaler(UTILS_ClkInitStruct->APB3CLKDivider);
631 LL_RCC_SetAPB4Prescaler(UTILS_ClkInitStruct->APB4CLKDivider);
632 LL_RCC_SetAPB5Prescaler(UTILS_ClkInitStruct->APB5CLKDivider);
633
634 /* Update SystemCoreClock variable */
635 LL_SetSystemCoreClock(SYSCLK_CoreFrequency);
636 }
637
638 /**
639 * @}
640 */
641
642 /**
643 * @}
644 */
645
646 /**
647 * @}
648 */
649
650