1 /**
2 ******************************************************************************
3 * @file stm32n6xx_ll_utils.c
4 * @author MCD Application Team
5 * @brief UTILS LL module driver.
6 ******************************************************************************
7 * @attention
8 *
9 * Copyright (c) 2023 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 "stm32n6xx_ll_utils.h"
20 #include "stm32n6xx_ll_pwr.h"
21
22 #ifdef USE_FULL_ASSERT
23 #include "stm32_assert.h"
24 #else
25 #define assert_param(expr) ((void)0U)
26 #endif /* USE_FULL_ASSERT */
27
28 /** @addtogroup STM32N6xx_LL_Driver
29 * @{
30 */
31
32 /** @addtogroup UTILS_LL
33 * @{
34 */
35
36 /* Private types -------------------------------------------------------------*/
37 /* Private variables ---------------------------------------------------------*/
38 /* Private constants ---------------------------------------------------------*/
39 /** @addtogroup UTILS_LL_Private_Constants
40 * @{
41 */
42 #define UTILS_MAX_FREQUENCY_SCALE0 800000000U /*!< Maximum frequency for system clock at power scale 0, in Hz */
43 #define UTILS_MAX_FREQUENCY_SCALE1 600000000U /*!< Maximum frequency for system clock at power scale 1, in Hz */
44
45 #define UTILS_PLLVCO_INPUT_MAX 50000000U /*!< Frequency max for the PLLVCO input, in Hz */
46 #define UTILS_PLLVCO_OUTPUT_MAX 3200000000U /*!< Frequency max for the PLLVCO output, in Hz */
47 /* Defines used for HSE range */
48 #define UTILS_HSE_FREQUENCY_MIN 16000000U /*!< Frequency min for HSE frequency, in Hz */
49 #define UTILS_HSE_FREQUENCY_MAX 48000000U /*!< Frequency max for HSE frequency, in Hz */
50
51 /**
52 * @}
53 */
54
55 /* Private macros ------------------------------------------------------------*/
56 /** @addtogroup UTILS_LL_Private_Macros
57 * @{
58 */
59 #define IS_LL_UTILS_AHB_DIV(__VALUE__) (((__VALUE__) == LL_RCC_AHB_DIV_1) \
60 || ((__VALUE__) == LL_RCC_AHB_DIV_2) \
61 || ((__VALUE__) == LL_RCC_AHB_DIV_4) \
62 || ((__VALUE__) == LL_RCC_AHB_DIV_8) \
63 || ((__VALUE__) == LL_RCC_AHB_DIV_16) \
64 || ((__VALUE__) == LL_RCC_AHB_DIV_64) \
65 || ((__VALUE__) == LL_RCC_AHB_DIV_128))
66
67 #define IS_LL_UTILS_APB1_DIV(__VALUE__) (((__VALUE__) == LL_RCC_APB1_DIV_1) \
68 || ((__VALUE__) == LL_RCC_APB1_DIV_2) \
69 || ((__VALUE__) == LL_RCC_APB1_DIV_4) \
70 || ((__VALUE__) == LL_RCC_APB1_DIV_8) \
71 || ((__VALUE__) == LL_RCC_APB1_DIV_16) \
72 || ((__VALUE__) == LL_RCC_APB1_DIV_32) \
73 || ((__VALUE__) == LL_RCC_APB1_DIV_64) \
74 || ((__VALUE__) == LL_RCC_APB1_DIV_128))
75
76 #define IS_LL_UTILS_APB2_DIV(__VALUE__) (((__VALUE__) == LL_RCC_APB2_DIV_1) \
77 || ((__VALUE__) == LL_RCC_APB2_DIV_2) \
78 || ((__VALUE__) == LL_RCC_APB2_DIV_4) \
79 || ((__VALUE__) == LL_RCC_APB2_DIV_8) \
80 || ((__VALUE__) == LL_RCC_APB2_DIV_16) \
81 || ((__VALUE__) == LL_RCC_APB2_DIV_32) \
82 || ((__VALUE__) == LL_RCC_APB2_DIV_64) \
83 || ((__VALUE__) == LL_RCC_APB2_DIV_128))
84
85 #define IS_LL_UTILS_APB4_DIV(__VALUE__) (((__VALUE__) == LL_RCC_APB4_DIV_1) \
86 || ((__VALUE__) == LL_RCC_APB4_DIV_2) \
87 || ((__VALUE__) == LL_RCC_APB4_DIV_4) \
88 || ((__VALUE__) == LL_RCC_APB4_DIV_8) \
89 || ((__VALUE__) == LL_RCC_APB4_DIV_16) \
90 || ((__VALUE__) == LL_RCC_APB4_DIV_32) \
91 || ((__VALUE__) == LL_RCC_APB4_DIV_64) \
92 || ((__VALUE__) == LL_RCC_APB4_DIV_128))
93
94 #define IS_LL_UTILS_APB5_DIV(__VALUE__) (((__VALUE__) == LL_RCC_APB5_DIV_1) \
95 || ((__VALUE__) == LL_RCC_APB5_DIV_2) \
96 || ((__VALUE__) == LL_RCC_APB5_DIV_4) \
97 || ((__VALUE__) == LL_RCC_APB5_DIV_8) \
98 || ((__VALUE__) == LL_RCC_APB5_DIV_16) \
99 || ((__VALUE__) == LL_RCC_APB5_DIV_32) \
100 || ((__VALUE__) == LL_RCC_APB5_DIV_64) \
101 || ((__VALUE__) == LL_RCC_APB5_DIV_128))
102
103 /* Values expected to use PLL in Integer mode */
104 #define IS_LL_UTILS_PLLM_VALUE(__VALUE__) ((1U <= (__VALUE__)) && ((__VALUE__) <= 63U))
105
106 #define IS_LL_UTILS_PLLN_VALUE(__VALUE__) ((16U <= (__VALUE__)) && ((__VALUE__) <= 640U))
107
108 #define IS_LL_UTILS_PLLP_VALUE(__VALUE__) ((1U <= (__VALUE__)) && ((__VALUE__) <= 7U))
109
110 #define IS_LL_UTILS_FRACN_VALUE(__VALUE__) ((__VALUE__) == 0U)
111
112 #define IS_LL_UTILS_PLLVCO_INPUT(__VALUE__) ((__VALUE__) <= UTILS_PLLVCO_INPUT_MAX)
113
114 #define IS_LL_UTILS_PLLVCO_OUTPUT(__VALUE__) ((__VALUE__) <= UTILS_PLLVCO_OUTPUT_MAX)
115
116 #define IS_LL_UTILS_HSE_BYPASS(__STATE__) \
117 (((__STATE__) == LL_UTILS_HSEBYPASS_ON) || ((__STATE__) == LL_UTILS_HSEBYPASS_OFF))
118
119 #define IS_LL_UTILS_HSE_FREQUENCY(__FREQUENCY__) \
120 (((__FREQUENCY__) >= UTILS_HSE_FREQUENCY_MIN) && ((__FREQUENCY__) <= UTILS_HSE_FREQUENCY_MAX))
121 /**
122 * @}
123 */
124
125 /* Private function prototypes -----------------------------------------------*/
126 /** @defgroup UTILS_LL_Private_Functions UTILS Private functions
127 * @{
128 */
129 static void UTILS_ConfigurePLL1InIntegerMode(const LL_UTILS_PLLInitTypeDef *pUTILS_ClkInitStruct);
130 static void UTILS_ConfigureIC(const LL_UTILS_ICInitTypeDef *pUTILS_ICInitStruct);
131 static ErrorStatus UTILS_EnablePLL1AndSwitchSystem(uint32_t CPU_Frequency,
132 const LL_UTILS_ClkInitTypeDef *pUTILS_ClkInitStruct);
133 /**
134 * @}
135 */
136
137 /* Exported functions --------------------------------------------------------*/
138 /** @addtogroup UTILS_LL_Exported_Functions
139 * @{
140 */
141
142 /** @addtogroup UTILS_LL_EF_DELAY
143 * @{
144 */
145 /**
146 * @brief This function configures the Cortex-M SysTick source to have 1ms time base.
147 * @note When a RTOS is used, it is recommended to avoid changing the Systick
148 * configuration by calling this function, for a delay use rather osDelay RTOS service.
149 * @param CPU_Frequency Core frequency in Hz
150 * @note CPU_Frequency can be calculated thanks to RCC helper macro or function
151 * @ref LL_RCC_GetSystemClocksFreq
152 * @retval None
153 */
LL_Init1msTick(uint32_t CPU_Frequency)154 void LL_Init1msTick(uint32_t CPU_Frequency)
155 {
156 /* Use frequency provided in argument */
157 LL_InitTick(CPU_Frequency, 1000U);
158 }
159
160
161 /**
162 * @brief This function provides accurate delay (in milliseconds) based
163 * on SysTick counter flag
164 * @note When a RTOS is used, it is recommended to avoid using blocking delay
165 * and use rather osDelay service.
166 * @note To respect 1ms timebase, user should call @ref LL_Init1msTick function which
167 * will configure Systick to 1ms
168 * @param Delay specifies the delay time length, in milliseconds.
169 * @retval None
170 */
LL_mDelay(uint32_t Delay)171 void LL_mDelay(uint32_t Delay)
172 {
173 uint32_t count = Delay;
174 __IO uint32_t tmp = SysTick->CTRL; /* Clear the COUNTFLAG first */
175 /* Add this code to indicate that local variable is not used */
176 ((void)tmp);
177
178 /* Add a period to guaranty minimum wait */
179 if (count < LL_MAX_DELAY)
180 {
181 count++;
182 }
183
184 while (count != 0U)
185 {
186 if ((SysTick->CTRL & SysTick_CTRL_COUNTFLAG_Msk) != 0U)
187 {
188 count--;
189 }
190 }
191 }
192
193 /**
194 * @}
195 */
196
197 /** @addtogroup UTILS_EF_SYSTEM
198 * @brief System Configuration functions
199 *
200 @verbatim
201 ===============================================================================
202 ##### System Configuration functions #####
203 ===============================================================================
204 [..]
205 System, AXI, AHB and APB buses clocks configuration
206
207 (+) The maximum frequency of the CPU is 800 MHz and AXI is 400 MHz.
208 (+) The maximum frequency of the HCLK, PCLK1, PCLK2, PCLK4 and PCLK5 is 200 MHz.
209 @endverbatim
210 * @{
211 */
212
213 /**
214 * @brief This function sets directly SystemCoreClock CMSIS variable.
215 * @note Variable can be calculated also through SystemCoreClockUpdate function.
216 * @param CPU_Frequency Core frequency in Hz
217 * @note CPU_Frequency can be calculated thanks to RCC helper macro or function
218 * @ref LL_RCC_GetSystemClocksFreq
219 * @retval None
220 */
LL_SetSystemCoreClock(uint32_t CPU_Frequency)221 void LL_SetSystemCoreClock(uint32_t CPU_Frequency)
222 {
223 /* CPU clock frequency */
224 SystemCoreClock = CPU_Frequency;
225 }
226
227 /**
228 * @brief This function configures the CPU system clock with HSI as clock source of the PLL1
229 * used in integer mode.
230 * @note The application needs to ensure that PLL1 is disabled.
231 * @note Function is based on the following formula:
232 * - PLL output frequency = (((HSI frequency / PLLM) * PLLN) / PLLP1 / PLLP2)
233 * - PLLM: ensure that the VCO input frequency ranges from 1 to 50 MHz (PLLVCO_input = HSI frequency / PLLM)
234 * - PLLN: ensure that the VCO output frequency is maximum 3200 MHz (PLLVCO_output = PLLVCO_input * PLLN)
235 * - PLLP1, PLLP2: ensure that max frequency at 800 MHz is reached (PLLVCO_output / PLLP1 / PLLP2)
236 * @param pUTILS_PLLInitStruct pointer to a @ref LL_UTILS_PLLInitTypeDef structure that contains
237 * the configuration information for the PLL.
238 * @param pUTILS_ICInitStruct pointer to a @ref LL_UTILS_ICInitTypeDef structure that contains
239 * the configuration information for the IC.
240 * @param pUTILS_ClkInitStruct pointer to a @ref LL_UTILS_ClkInitTypeDef structure that contains
241 * the configuration information for the BUS prescalers.
242 * @retval An ErrorStatus enumeration value:
243 * - SUCCESS: Max frequency configuration done
244 * - ERROR: Max frequency configuration not done
245 *
246 */
LL_PLL_ConfigSystemClock_HSI(const LL_UTILS_PLLInitTypeDef * pUTILS_PLLInitStruct,const LL_UTILS_ICInitTypeDef * pUTILS_ICInitStruct,const LL_UTILS_ClkInitTypeDef * pUTILS_ClkInitStruct)247 ErrorStatus LL_PLL_ConfigSystemClock_HSI(const LL_UTILS_PLLInitTypeDef *pUTILS_PLLInitStruct,
248 const LL_UTILS_ICInitTypeDef *pUTILS_ICInitStruct,
249 const LL_UTILS_ClkInitTypeDef *pUTILS_ClkInitStruct)
250 {
251 ErrorStatus status;
252 uint32_t pllfreq;
253 uint32_t hsi_clk;
254
255 /* Check the PLL parameters */
256 assert_param(IS_LL_UTILS_PLLM_VALUE(pUTILS_PLLInitStruct->PLLM));
257 assert_param(IS_LL_UTILS_PLLN_VALUE(pUTILS_PLLInitStruct->PLLN));
258 assert_param(IS_LL_UTILS_PLLP_VALUE(pUTILS_PLLInitStruct->PLLP1));
259 assert_param(IS_LL_UTILS_PLLP_VALUE(pUTILS_PLLInitStruct->PLLP2));
260 assert_param(IS_LL_UTILS_FRACN_VALUE(pUTILS_PLLInitStruct->FRACN));
261
262 hsi_clk = (HSI_VALUE >> (LL_RCC_HSI_GetDivider() >> RCC_HSICFGR_HSIDIV_Pos));
263
264 /* Check VCO Input frequency */
265 assert_param(IS_LL_UTILS_PLLVCO_INPUT(hsi_clk / pUTILS_PLLInitStruct->PLLM));
266
267 /* Check that PLL1 is not enabled and thus ready for configuration */
268 if (LL_RCC_PLL1_IsReady() != 1U)
269 {
270 /* Integer mode only */
271 if (pUTILS_PLLInitStruct->FRACN == 0U)
272 {
273 /* Calculate the new PLL output frequency */
274 pllfreq = LL_RCC_CalcPLLClockFreq(hsi_clk, pUTILS_PLLInitStruct->PLLM,
275 pUTILS_PLLInitStruct->PLLN, pUTILS_PLLInitStruct->FRACN,
276 pUTILS_PLLInitStruct->PLLP1, pUTILS_PLLInitStruct->PLLP2);
277 /* Check VCO Output frequency */
278 assert_param(IS_LL_UTILS_PLLVCO_OUTPUT(pllfreq * pUTILS_PLLInitStruct->PLLP1 * pUTILS_PLLInitStruct->PLLP2));
279
280 /* Enable HSI if not enabled */
281 if (LL_RCC_HSI_IsReady() != 1U)
282 {
283 LL_RCC_HSI_Enable();
284 while (LL_RCC_HSI_IsReady() != 1U)
285 {
286 /* Wait for HSI ready */
287 }
288 }
289
290 /* Configure PLL1 */
291 LL_RCC_PLL1_SetSource(LL_RCC_PLLSOURCE_HSI);
292
293 UTILS_ConfigurePLL1InIntegerMode(pUTILS_PLLInitStruct);
294
295 UTILS_ConfigureIC(pUTILS_ICInitStruct);
296
297 /* Enable PLL and switch CPU/system clock to PLL */
298 status = UTILS_EnablePLL1AndSwitchSystem(pllfreq, pUTILS_ClkInitStruct);
299 }
300 else
301 {
302 status = ERROR;
303 }
304 }
305 else
306 {
307 /* Current PLL configuration cannot be modified */
308 status = ERROR;
309 }
310
311 return status;
312 }
313
314 /**
315 * @brief This function configures the CPU system clock with MSI as clock source of the PLL1
316 * used in integer mode.
317 * @note The application needs to ensure that PLL1 is disabled.
318 * @note Function is based on the following formula:
319 * - PLL output frequency = (((MSI frequency / PLLM) * PLLN) / PLLP1 / PLLP2)
320 * - PLLM: ensure that the VCO input frequency ranges from 1 to 50 MHz (PLLVCO_input = MSI frequency / PLLM)
321 * - PLLN: ensure that the VCO output frequency is maximum 3200 MHz (PLLVCO_output = PLLVCO_input * PLLN)
322 * - PLLP1, PLLP2: ensure that max frequency at 800 MHz is reached (PLLVCO_output / PLLP1 / PLLP2)
323 * @param pUTILS_PLLInitStruct pointer to a @ref LL_UTILS_PLLInitTypeDef structure that contains
324 * the configuration information for the PLL.
325 * @param pUTILS_ICInitStruct pointer to a @ref LL_UTILS_ICInitTypeDef structure that contains
326 * the configuration information for the IC.
327 * @param pUTILS_ClkInitStruct pointer to a @ref LL_UTILS_ClkInitTypeDef structure that contains
328 * the configuration information for the BUS prescalers.
329 * @retval An ErrorStatus enumeration value:
330 * - SUCCESS: Max frequency configuration done
331 * - ERROR: Max frequency configuration not done
332 *
333 */
LL_PLL_ConfigSystemClock_MSI(const LL_UTILS_PLLInitTypeDef * pUTILS_PLLInitStruct,const LL_UTILS_ICInitTypeDef * pUTILS_ICInitStruct,const LL_UTILS_ClkInitTypeDef * pUTILS_ClkInitStruct)334 ErrorStatus LL_PLL_ConfigSystemClock_MSI(const LL_UTILS_PLLInitTypeDef *pUTILS_PLLInitStruct,
335 const LL_UTILS_ICInitTypeDef *pUTILS_ICInitStruct,
336 const LL_UTILS_ClkInitTypeDef *pUTILS_ClkInitStruct)
337 {
338 ErrorStatus status;
339 uint32_t pllfreq;
340
341 /* Check the PLL parameters */
342 assert_param(IS_LL_UTILS_PLLM_VALUE(pUTILS_PLLInitStruct->PLLM));
343 assert_param(IS_LL_UTILS_PLLN_VALUE(pUTILS_PLLInitStruct->PLLN));
344 assert_param(IS_LL_UTILS_PLLP_VALUE(pUTILS_PLLInitStruct->PLLP1));
345 assert_param(IS_LL_UTILS_PLLP_VALUE(pUTILS_PLLInitStruct->PLLP2));
346 assert_param(IS_LL_UTILS_FRACN_VALUE(pUTILS_PLLInitStruct->FRACN));
347
348 /* Check VCO Input frequency */
349 assert_param(IS_LL_UTILS_PLLVCO_INPUT(MSI_VALUE / pUTILS_PLLInitStruct->PLLM));
350
351 /* Check that PLL1 is not enabled and thus ready for configuration */
352 if (LL_RCC_PLL1_IsReady() != 1U)
353 {
354 /* Integer mode only */
355 if (pUTILS_PLLInitStruct->FRACN == 0U)
356 {
357 /* Calculate the new PLL output frequency */
358 pllfreq = LL_RCC_CalcPLLClockFreq(MSI_VALUE, pUTILS_PLLInitStruct->PLLM,
359 pUTILS_PLLInitStruct->PLLN, pUTILS_PLLInitStruct->FRACN,
360 pUTILS_PLLInitStruct->PLLP1, pUTILS_PLLInitStruct->PLLP2);
361
362 /* Check VCO Output frequency */
363 assert_param(IS_LL_UTILS_PLLVCO_OUTPUT(pllfreq * pUTILS_PLLInitStruct->PLLP1 * pUTILS_PLLInitStruct->PLLP2));
364
365 /* Enable MSI if not enabled */
366 if (LL_RCC_MSI_IsReady() != 1U)
367 {
368 LL_RCC_MSI_Enable();
369 while (LL_RCC_MSI_IsReady() != 1U)
370 {
371 /* Wait for MSI ready */
372 }
373 }
374
375 /* Configure PLL1 */
376 LL_RCC_PLL1_SetSource(LL_RCC_PLLSOURCE_MSI);
377
378 UTILS_ConfigurePLL1InIntegerMode(pUTILS_PLLInitStruct);
379
380 UTILS_ConfigureIC(pUTILS_ICInitStruct);
381
382 /* Enable PLL and switch system clock to PLL */
383 status = UTILS_EnablePLL1AndSwitchSystem(pllfreq, pUTILS_ClkInitStruct);
384 }
385 else
386 {
387 status = ERROR;
388 }
389 }
390 else
391 {
392 /* Current PLL configuration cannot be modified */
393 status = ERROR;
394 }
395
396 return status;
397 }
398
399 /**
400 * @brief This function configures the CPU system clock with HSE as clock source of the PLL1
401 * used in integer mode.
402 * @note The application needs to ensure that PLL1 is disabled.
403 * @note Function is based on the following formula:
404 * - PLL output frequency = (((HSE frequency / PLLM) * PLLN) / PLLP1 / PLLP2)
405 * - PLLM: ensure that the VCO input frequency ranges from 1 to 50 MHz (PLLVCO_input = HSE frequency / PLLM)
406 * - PLLN: ensure that the VCO output frequency is maximum 3200 MHz (PLLVCO_output = PLLVCO_input * PLLN)
407 * - PLLP1, PLLP2: ensure that max frequency at 800 MHz is reached (PLLVCO_output / PLLP1 / PLLP2)
408 * @param HSEFrequency Value between Min_Data = 4000000 and Max_Data = 50000000
409 * @param HSEBypass This parameter can be one of the following values:
410 * @arg @ref LL_UTILS_HSEBYPASS_ON
411 * @arg @ref LL_UTILS_HSEBYPASS_OFF
412 * @param pUTILS_PLLInitStruct pointer to a @ref LL_UTILS_PLLInitTypeDef structure that contains
413 * the configuration information for the PLL.
414 * @param pUTILS_ICInitStruct pointer to a @ref LL_UTILS_ICInitTypeDef structure that contains
415 * the configuration information for the IC.
416 * @param pUTILS_ClkInitStruct pointer to a @ref LL_UTILS_ClkInitTypeDef structure that contains
417 * the configuration information for the BUS prescalers.
418 * @retval An ErrorStatus enumeration value:
419 * - SUCCESS: Max frequency configuration done
420 * - ERROR: Max frequency configuration not done
421 *
422 */
LL_PLL_ConfigSystemClock_HSE(uint32_t HSEFrequency,uint32_t HSEBypass,const LL_UTILS_PLLInitTypeDef * pUTILS_PLLInitStruct,const LL_UTILS_ICInitTypeDef * pUTILS_ICInitStruct,const LL_UTILS_ClkInitTypeDef * pUTILS_ClkInitStruct)423 ErrorStatus LL_PLL_ConfigSystemClock_HSE(uint32_t HSEFrequency, uint32_t HSEBypass,
424 const LL_UTILS_PLLInitTypeDef *pUTILS_PLLInitStruct,
425 const LL_UTILS_ICInitTypeDef *pUTILS_ICInitStruct,
426 const LL_UTILS_ClkInitTypeDef *pUTILS_ClkInitStruct)
427 {
428 ErrorStatus status;
429 uint32_t pllfreq;
430
431 /* Check the HSE parameters */
432 assert_param(IS_LL_UTILS_HSE_FREQUENCY(HSEFrequency));
433 assert_param(IS_LL_UTILS_HSE_BYPASS(HSEBypass));
434 /* Check the PLL parameters */
435 assert_param(IS_LL_UTILS_PLLM_VALUE(pUTILS_PLLInitStruct->PLLM));
436 assert_param(IS_LL_UTILS_PLLN_VALUE(pUTILS_PLLInitStruct->PLLN));
437 assert_param(IS_LL_UTILS_PLLP_VALUE(pUTILS_PLLInitStruct->PLLP1));
438 assert_param(IS_LL_UTILS_PLLP_VALUE(pUTILS_PLLInitStruct->PLLP2));
439 assert_param(IS_LL_UTILS_FRACN_VALUE(pUTILS_PLLInitStruct->FRACN));
440
441 /* Check VCO Input frequency */
442 assert_param(IS_LL_UTILS_PLLVCO_INPUT(HSEFrequency / pUTILS_PLLInitStruct->PLLM));
443
444 /* Check that PLL1 is not enabled and thus ready for configuration */
445 if (LL_RCC_PLL1_IsReady() != 1U)
446 {
447 /* Integer mode only */
448 if (pUTILS_PLLInitStruct->FRACN == 0U)
449 {
450 /* Calculate the new PLL output frequency */
451 pllfreq = LL_RCC_CalcPLLClockFreq(HSEFrequency, pUTILS_PLLInitStruct->PLLM,
452 pUTILS_PLLInitStruct->PLLN, pUTILS_PLLInitStruct->FRACN,
453 pUTILS_PLLInitStruct->PLLP1, pUTILS_PLLInitStruct->PLLP2);
454
455 /* Check VCO Output frequency */
456 assert_param(IS_LL_UTILS_PLLVCO_OUTPUT(pllfreq * pUTILS_PLLInitStruct->PLLP1 * pUTILS_PLLInitStruct->PLLP2));
457
458 /* Enable HSE if not enabled */
459 if (LL_RCC_HSE_IsReady() != 1U)
460 {
461 /* Check if need to enable HSE bypass feature or not */
462 if (HSEBypass == LL_UTILS_HSEBYPASS_ON)
463 {
464 LL_RCC_HSE_EnableBypass();
465 }
466 else
467 {
468 LL_RCC_HSE_DisableBypass();
469 }
470
471 /* Enable HSE */
472 LL_RCC_HSE_Enable();
473 while (LL_RCC_HSE_IsReady() != 1U)
474 {
475 /* Wait for HSE ready */
476 }
477 }
478
479 /* Configure PLL1 */
480 LL_RCC_PLL1_SetSource(LL_RCC_PLLSOURCE_HSE);
481
482 UTILS_ConfigurePLL1InIntegerMode(pUTILS_PLLInitStruct);
483
484 UTILS_ConfigureIC(pUTILS_ICInitStruct);
485
486 /* Enable PLL and switch system clock to PLL */
487 status = UTILS_EnablePLL1AndSwitchSystem(pllfreq, pUTILS_ClkInitStruct);
488 }
489 else
490 {
491 status = ERROR;
492 }
493 }
494 else
495 {
496 /* Current PLL configuration cannot be modified */
497 status = ERROR;
498 }
499
500 return status;
501 }
502
503 /**
504 * @}
505 */
506
507 /**
508 * @}
509 */
510
511 /** @addtogroup UTILS_LL_Private_Functions
512 * @{
513 */
514
515
516 /**
517 * @brief Function to configure PLL1 in Integer mode
518 * @param pUTILS_PLLInitStruct pointer to a @ref LL_UTILS_PLLInitTypeDef structure that contains
519 * the configuration information for the PLL.
520 * @retval None
521 */
UTILS_ConfigurePLL1InIntegerMode(const LL_UTILS_PLLInitTypeDef * pUTILS_PLLInitStruct)522 static void UTILS_ConfigurePLL1InIntegerMode(const LL_UTILS_PLLInitTypeDef *pUTILS_PLLInitStruct)
523 {
524 LL_RCC_PLL1_DisableModulationSpreadSpectrum();
525 LL_RCC_PLL1_SetM(pUTILS_PLLInitStruct->PLLM);
526 LL_RCC_PLL1_SetN(pUTILS_PLLInitStruct->PLLN);
527 LL_RCC_PLL1_SetFRACN(pUTILS_PLLInitStruct->FRACN);
528 LL_RCC_PLL1_DisableFractionalModulationSpreadSpectrum();
529 LL_RCC_PLL1_AssertModulationSpreadSpectrumReset();
530 LL_RCC_PLL1_SetP1(pUTILS_PLLInitStruct->PLLP1);
531 LL_RCC_PLL1_SetP2(pUTILS_PLLInitStruct->PLLP2);
532 }
533
534 /**
535 * @brief Function to configure IC for CPU/System buses clocks
536 * @param pUTILS_ICInitStruct pointer to a @ref LL_UTILS_ICInitTypeDef structure that contains
537 * the configuration information for the IC (IC1, IC2, IC6 and IC11).
538 * @retval None
539 */
UTILS_ConfigureIC(const LL_UTILS_ICInitTypeDef * pUTILS_ICInitStruct)540 static void UTILS_ConfigureIC(const LL_UTILS_ICInitTypeDef *pUTILS_ICInitStruct)
541 {
542 /* Configure and enable each IC used for CPU/System buses clocks */
543 LL_RCC_IC1_SetSource(pUTILS_ICInitStruct->IC1Source);
544 LL_RCC_IC1_SetDivider(pUTILS_ICInitStruct->IC1Divider);
545 LL_RCC_IC1_Enable();
546 LL_RCC_IC2_SetSource(pUTILS_ICInitStruct->IC2Source);
547 LL_RCC_IC2_SetDivider(pUTILS_ICInitStruct->IC2Divider);
548 LL_RCC_IC2_Enable();
549 LL_RCC_IC6_SetSource(pUTILS_ICInitStruct->IC6Source);
550 LL_RCC_IC6_SetDivider(pUTILS_ICInitStruct->IC6Divider);
551 LL_RCC_IC6_Enable();
552 LL_RCC_IC11_SetSource(pUTILS_ICInitStruct->IC11Source);
553 LL_RCC_IC11_SetDivider(pUTILS_ICInitStruct->IC11Divider);
554 LL_RCC_IC11_Enable();
555 }
556
557 /**
558 * @brief Function to enable PLL1 and switch CPU/system clock to PLL
559 * @param CPU_Frequency CPU frequency
560 * @param pUTILS_ClkInitStruct pointer to a @ref LL_UTILS_ClkInitTypeDef structure that contains
561 * the configuration information for the BUS prescalers.
562 * @retval An ErrorStatus enumeration value:
563 * - SUCCESS: No problem to switch system to PLL
564 * - ERROR: Problem to switch system to PLL
565 */
UTILS_EnablePLL1AndSwitchSystem(uint32_t CPU_Frequency,const LL_UTILS_ClkInitTypeDef * pUTILS_ClkInitStruct)566 static ErrorStatus UTILS_EnablePLL1AndSwitchSystem(uint32_t CPU_Frequency,
567 const LL_UTILS_ClkInitTypeDef *pUTILS_ClkInitStruct)
568 {
569 ErrorStatus status = SUCCESS;
570
571 assert_param(IS_LL_UTILS_AHB_DIV(pUTILS_ClkInitStruct->AHBCLKDivider));
572 assert_param(IS_LL_UTILS_APB1_DIV(pUTILS_ClkInitStruct->APB1CLKDivider));
573 assert_param(IS_LL_UTILS_APB2_DIV(pUTILS_ClkInitStruct->APB2CLKDivider));
574 assert_param(IS_LL_UTILS_APB4_DIV(pUTILS_ClkInitStruct->APB4CLKDivider));
575 assert_param(IS_LL_UTILS_APB5_DIV(pUTILS_ClkInitStruct->APB5CLKDivider));
576
577 /* Update system clock configuration */
578 /* Enable PLL1 */
579 LL_RCC_PLL1_Enable();
580 while (LL_RCC_PLL1_IsReady() != 1U)
581 {
582 /* Wait for PLL1 ready */
583 }
584
585 LL_RCC_PLL1P_Enable();
586
587 /* Set APBx prescalers to the highest divider */
588 LL_RCC_SetAPB1Prescaler(LL_RCC_APB1_DIV_128);
589 LL_RCC_SetAPB2Prescaler(LL_RCC_APB2_DIV_128);
590 LL_RCC_SetAPB4Prescaler(LL_RCC_APB4_DIV_128);
591 LL_RCC_SetAPB5Prescaler(LL_RCC_APB5_DIV_128);
592
593 /* Set AHB prescaler*/
594 LL_RCC_SetAHBPrescaler(pUTILS_ClkInitStruct->AHBCLKDivider);
595
596 /* CPU clock switch on the IC1 */
597 LL_RCC_SetCpuClkSource(LL_RCC_CPU_CLKSOURCE_IC1);
598 while (LL_RCC_GetCpuClkSource() != LL_RCC_CPU_CLKSOURCE_STATUS_IC1)
599 {
600 /* Wait for CPU clock switch to IC1 */
601 }
602
603 /* System buses clock switch on the IC2, IC6 and IC11 */
604 LL_RCC_SetSysClkSource(LL_RCC_SYS_CLKSOURCE_IC2_IC6_IC11);
605 while (LL_RCC_GetSysClkSource() != LL_RCC_SYS_CLKSOURCE_STATUS_IC2_IC6_IC11)
606 {
607 /* Wait for System buses clock switch to IC2, IC6 and IC11 */
608 }
609
610 LL_SetSystemCoreClock(CPU_Frequency);
611
612 /* Set APBx prescalers */
613 LL_RCC_SetAPB1Prescaler(pUTILS_ClkInitStruct->APB1CLKDivider);
614 LL_RCC_SetAPB2Prescaler(pUTILS_ClkInitStruct->APB2CLKDivider);
615 LL_RCC_SetAPB4Prescaler(pUTILS_ClkInitStruct->APB4CLKDivider);
616 LL_RCC_SetAPB5Prescaler(pUTILS_ClkInitStruct->APB5CLKDivider);
617
618 return status;
619 }
620
621 /**
622 * @}
623 */
624
625 /**
626 * @}
627 */
628
629 /**
630 * @}
631 */
632