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