1 /**
2   ******************************************************************************
3   * @file    stm32h5xx_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 "stm32h5xx_ll_utils.h"
20 #include "stm32h5xx_ll_rcc.h"
21 #include "stm32h5xx_ll_system.h"
22 #include "stm32h5xx_ll_pwr.h"
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 STM32H5xx_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  250000000U         /*!< Maximum frequency for system clock at power scale0, in Hz */
44 #define UTILS_MAX_FREQUENCY_SCALE1  200000000U         /*!< Maximum frequency for system clock at power scale1, in Hz */
45 #define UTILS_MAX_FREQUENCY_SCALE2  150000000U         /*!< Maximum frequency for system clock at power scale2, in Hz */
46 #define UTILS_MAX_FREQUENCY_SCALE3  100000000U         /*!< Maximum frequency for system clock at power scale3, in Hz */
47 
48 /* Defines used for PLL range */
49 #define UTILS_PLLVCO_INPUT_MIN1       1000000U      /*!< Frequency min for the low range PLLVCO input, in Hz    */
50 #define UTILS_PLLVCO_INPUT_MAX1       2000000U      /*!< Frequency max for the wide range PLLVCO input, in Hz   */
51 #define UTILS_PLLVCO_INPUT_MIN2       2000000U      /*!< Frequency min for the low range PLLVCO input, in Hz    */
52 #define UTILS_PLLVCO_INPUT_MAX2       4000000U      /*!< Frequency max for the wide range PLLVCO input, in Hz   */
53 #define UTILS_PLLVCO_INPUT_MIN3       4000000U      /*!< Frequency min for the low range PLLVCO input, in Hz    */
54 #define UTILS_PLLVCO_INPUT_MAX3       8000000U      /*!< Frequency max for the wide range PLLVCO input, in Hz   */
55 #define UTILS_PLLVCO_INPUT_MIN4       8000000U      /*!< Frequency min for the low range PLLVCO input, in Hz    */
56 #define UTILS_PLLVCO_INPUT_MAX4      16000000U      /*!< Frequency max for the wide range PLLVCO input, in Hz   */
57 
58 #define UTILS_PLLVCO_MEDIUM_OUTPUT_MIN    150000000U    /*!< Frequency min for the medium range PLLVCO output, in Hz  */
59 #define UTILS_PLLVCO_WIDE_OUTPUT_MIN      192000000U    /*!< Frequency min for the wide range PLLVCO output, in Hz    */
60 #define UTILS_PLLVCO_MEDIUM_OUTPUT_MAX    420000000U    /*!< Frequency max for the medium range PLLVCO output, in Hz  */
61 #define UTILS_PLLVCO_WIDE_OUTPUT_MAX      836000000U    /*!< Frequency max for the wide range PLLVCO output, in Hz    */
62 /* Defines used for HSE range */
63 #define UTILS_HSE_FREQUENCY_MIN             4000000U      /*!< Frequency min for HSE frequency, in Hz   */
64 #define UTILS_HSE_FREQUENCY_MAX            50000000U      /*!< Frequency max for HSE frequency, in Hz   */
65 
66 /* Defines used for FLASH latency according to HCLK Frequency */
67 #define UTILS_SCALE0_LATENCY0_FREQ     42000000U       /*!< HCLK frequency to set FLASH latency 0 in power scale 0 */
68 #define UTILS_SCALE0_LATENCY1_FREQ     84000000U       /*!< HCLK frequency to set FLASH latency 1 in power scale 0 */
69 #define UTILS_SCALE0_LATENCY2_FREQ    126000000U       /*!< HCLK frequency to set FLASH latency 2 in power scale 0 */
70 #define UTILS_SCALE0_LATENCY3_FREQ    168000000U       /*!< HCLK frequency to set FLASH latency 3 in power scale 0 */
71 #define UTILS_SCALE0_LATENCY4_FREQ    210000000U       /*!< HCLK frequency to set FLASH latency 4 in power scale 0 */
72 #define UTILS_SCALE0_LATENCY5_FREQ    250000000U       /*!< HCLK frequency to set FLASH latency 5 in power scale 0 */
73 
74 #define UTILS_SCALE1_LATENCY0_FREQ     34000000U       /*!< HCLK frequency to set FLASH latency 0 in power scale 1 */
75 #define UTILS_SCALE1_LATENCY1_FREQ     68000000U       /*!< HCLK frequency to set FLASH latency 1 in power scale 1 */
76 #define UTILS_SCALE1_LATENCY2_FREQ    102000000U       /*!< HCLK frequency to set FLASH latency 2 in power scale 1 */
77 #define UTILS_SCALE1_LATENCY3_FREQ    136000000U       /*!< HCLK frequency to set FLASH latency 3 in power scale 1 */
78 #define UTILS_SCALE1_LATENCY4_FREQ    170000000U       /*!< HCLK frequency to set FLASH latency 4 in power scale 1 */
79 #define UTILS_SCALE1_LATENCY5_FREQ    200000000U       /*!< HCLK frequency to set FLASH latency 5 in power scale 1 */
80 
81 #define UTILS_SCALE2_LATENCY0_FREQ     30000000U       /*!< HCLK frequency to set FLASH latency 0 in power scale 2 */
82 #define UTILS_SCALE2_LATENCY1_FREQ     60000000U       /*!< HCLK frequency to set FLASH latency 1 in power scale 2 */
83 #define UTILS_SCALE2_LATENCY2_FREQ     90000000U       /*!< HCLK frequency to set FLASH latency 2 in power scale 2 */
84 #define UTILS_SCALE2_LATENCY3_FREQ    120000000U       /*!< HCLK frequency to set FLASH latency 3 in power scale 2 */
85 #define UTILS_SCALE2_LATENCY4_FREQ    150000000U       /*!< HCLK frequency to set FLASH latency 4 in power scale 2 */
86 
87 #define UTILS_SCALE3_LATENCY0_FREQ     20000000U       /*!< HCLK frequency to set FLASH latency 0 in power scale 3 */
88 #define UTILS_SCALE3_LATENCY1_FREQ     40000000U       /*!< HCLK frequency to set FLASH latency 1 in power scale 3 */
89 #define UTILS_SCALE3_LATENCY2_FREQ     60000000U       /*!< HCLK frequency to set FLASH latency 2 in power scale 3 */
90 #define UTILS_SCALE3_LATENCY3_FREQ     80000000U       /*!< HCLK frequency to set FLASH latency 3 in power scale 3 */
91 #define UTILS_SCALE3_LATENCY4_FREQ    100000000U       /*!< HCLK frequency to set FLASH latency 4 in power scale 3 */
92 /**
93   * @}
94   */
95 
96 /* Private macros ------------------------------------------------------------*/
97 /** @addtogroup UTILS_LL_Private_Macros
98   * @{
99   */
100 #define IS_LL_UTILS_SYSCLK_DIV(__VALUE__) (((__VALUE__) == LL_RCC_SYSCLK_DIV_1)      \
101                                            || ((__VALUE__) == LL_RCC_SYSCLK_DIV_2)   \
102                                            || ((__VALUE__) == LL_RCC_SYSCLK_DIV_4)   \
103                                            || ((__VALUE__) == LL_RCC_SYSCLK_DIV_8)   \
104                                            || ((__VALUE__) == LL_RCC_SYSCLK_DIV_16)  \
105                                            || ((__VALUE__) == LL_RCC_SYSCLK_DIV_64)  \
106                                            || ((__VALUE__) == LL_RCC_SYSCLK_DIV_128) \
107                                            || ((__VALUE__) == LL_RCC_SYSCLK_DIV_256) \
108                                            || ((__VALUE__) == LL_RCC_SYSCLK_DIV_512))
109 
110 #define IS_LL_UTILS_APB1_DIV(__VALUE__) (((__VALUE__) == LL_RCC_APB1_DIV_1)    \
111                                          || ((__VALUE__) == LL_RCC_APB1_DIV_2) \
112                                          || ((__VALUE__) == LL_RCC_APB1_DIV_4) \
113                                          || ((__VALUE__) == LL_RCC_APB1_DIV_8) \
114                                          || ((__VALUE__) == LL_RCC_APB1_DIV_16))
115 
116 #define IS_LL_UTILS_APB2_DIV(__VALUE__) (((__VALUE__) == LL_RCC_APB2_DIV_1)    \
117                                          || ((__VALUE__) == LL_RCC_APB2_DIV_2) \
118                                          || ((__VALUE__) == LL_RCC_APB2_DIV_4) \
119                                          || ((__VALUE__) == LL_RCC_APB2_DIV_8) \
120                                          || ((__VALUE__) == LL_RCC_APB2_DIV_16))
121 
122 #define IS_LL_UTILS_APB3_DIV(__VALUE__) (((__VALUE__) == LL_RCC_APB3_DIV_1)    \
123                                          || ((__VALUE__) == LL_RCC_APB3_DIV_2) \
124                                          || ((__VALUE__) == LL_RCC_APB3_DIV_4) \
125                                          || ((__VALUE__) == LL_RCC_APB3_DIV_8) \
126                                          || ((__VALUE__) == LL_RCC_APB3_DIV_16))
127 
128 #define IS_LL_UTILS_PLLM_VALUE(__VALUE__) ((1U <= (__VALUE__)) && ((__VALUE__) <= 63U))
129 
130 #define IS_LL_UTILS_PLLN_VALUE(__VALUE__) ((4U <= (__VALUE__)) && ((__VALUE__) <= 512U))
131 
132 #define IS_LL_UTILS_PLLP_VALUE(__VALUE__) ((2U <= (__VALUE__)) && ((__VALUE__) <= 128U))
133 
134 #define IS_LL_UTILS_FRACN_VALUE(__VALUE__) ((__VALUE__) <= 0x1FFFU)
135 
136 #define IS_LL_UTILS_PLLVCO_INPUT(__VALUE__, __RANGE__)  ( \
137                                                           (((__RANGE__) == LL_RCC_PLLINPUTRANGE_1_2)  && \
138                                                            (UTILS_PLLVCO_INPUT_MIN1 <= (__VALUE__))   && \
139                                                            ((__VALUE__) <= UTILS_PLLVCO_INPUT_MAX1))  || \
140                                                           (((__RANGE__) == LL_RCC_PLLINPUTRANGE_2_4)  && \
141                                                            (UTILS_PLLVCO_INPUT_MIN2 <= (__VALUE__))   && \
142                                                            ((__VALUE__) <= UTILS_PLLVCO_INPUT_MAX2))  || \
143                                                           (((__RANGE__) == LL_RCC_PLLINPUTRANGE_4_8)  && \
144                                                            (UTILS_PLLVCO_INPUT_MIN3 <= (__VALUE__))   && \
145                                                            ((__VALUE__) <= UTILS_PLLVCO_INPUT_MAX3))  || \
146                                                           (((__RANGE__) == LL_RCC_PLLINPUTRANGE_8_16) && \
147                                                            (UTILS_PLLVCO_INPUT_MIN4 <= (__VALUE__))   && \
148                                                            ((__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__))  && \
153                                                            ((__VALUE__) <= UTILS_PLLVCO_MEDIUM_OUTPUT_MAX)) || \
154                                                           (((__RANGE__) == LL_RCC_PLLVCORANGE_WIDE)         && \
155                                                            (UTILS_PLLVCO_WIDE_OUTPUT_MIN <= (__VALUE__))    && \
156                                                            ((__VALUE__) <= UTILS_PLLVCO_WIDE_OUTPUT_MAX)))
157 
158 #define IS_LL_UTILS_CHECK_VCO_RANGES(__RANGEIN__, __RANGEOUT__) ( \
159                                                                   (((__RANGEIN__) == LL_RCC_PLLINPUTRANGE_1_2)   && \
160                                                                    ((__RANGEOUT__) == LL_RCC_PLLVCORANGE_MEDIUM)) || \
161                                                                   (((__RANGEIN__) != LL_RCC_PLLINPUTRANGE_1_2)   && \
162                                                                    ((__RANGEOUT__) == LL_RCC_PLLVCORANGE_WIDE)))
163 
164 #define IS_LL_UTILS_PLL_FREQUENCY(__VALUE__) ((LL_PWR_GetRegulVoltageScaling() == LL_PWR_REGU_VOLTAGE_SCALE0) ? \
165                                               ((__VALUE__) <= UTILS_MAX_FREQUENCY_SCALE0) : \
166                                               (LL_PWR_GetRegulVoltageScaling() == LL_PWR_REGU_VOLTAGE_SCALE1) ? \
167                                               ((__VALUE__) <= UTILS_MAX_FREQUENCY_SCALE1) : \
168                                               (LL_PWR_GetRegulVoltageScaling() == LL_PWR_REGU_VOLTAGE_SCALE2) ? \
169                                               ((__VALUE__) <= UTILS_MAX_FREQUENCY_SCALE2) : \
170                                               ((__VALUE__) <= UTILS_MAX_FREQUENCY_SCALE3))
171 
172 #define IS_LL_UTILS_HSE_BYPASS(__STATE__) (((__STATE__) == LL_UTILS_HSEBYPASS_ON)         \
173                                            || ((__STATE__) == LL_UTILS_HSEBYPASS_DIGITAL_ON) \
174                                            || ((__STATE__) == LL_UTILS_HSEBYPASS_OFF))
175 
176 #define IS_LL_UTILS_HSE_FREQUENCY(__FREQUENCY__) (((__FREQUENCY__) >= UTILS_HSE_FREQUENCY_MIN) &&\
177                                                   ((__FREQUENCY__) <= UTILS_HSE_FREQUENCY_MAX))
178 /**
179   * @}
180   */
181 /* Private function prototypes -----------------------------------------------*/
182 /** @defgroup UTILS_LL_Private_Functions UTILS Private functions
183   * @{
184   */
185 static uint32_t    UTILS_GetPLLOutputFrequency(uint32_t PLL_InputFrequency,
186                                                const LL_UTILS_PLLInitTypeDef *UTILS_PLLInitStruct);
187 static ErrorStatus UTILS_EnablePLLAndSwitchSystem(uint32_t SYSCLK_Frequency,
188                                                   LL_UTILS_ClkInitTypeDef *UTILS_ClkInitStruct);
189 static ErrorStatus UTILS_PLL_IsBusy(void);
190 /**
191   * @}
192   */
193 
194 /* Exported functions --------------------------------------------------------*/
195 /** @addtogroup UTILS_LL_Exported_Functions
196   * @{
197   */
198 
199 /** @addtogroup UTILS_LL_EF_DELAY
200   * @{
201   */
202 
203 /**
204   * @brief  This function configures the Cortex-M SysTick source to have 1ms time base with HCLK
205   *         as SysTick clock source.
206   * @note   When a RTOS is used, it is recommended to avoid changing the Systick
207   *         configuration by calling this function, for a delay use rather osDelay RTOS service.
208   * @param  HCLKFrequency HCLK frequency in Hz
209   * @note   HCLK frequency can be calculated thanks to RCC helper macro or function @ref LL_RCC_GetSystemClocksFreq
210   * @retval None
211   */
LL_Init1msTick(uint32_t HCLKFrequency)212 void LL_Init1msTick(uint32_t HCLKFrequency)
213 {
214   /* Use frequency provided in argument */
215   LL_InitTick(HCLKFrequency, 1000U);
216 }
217 
218 /**
219   * @brief  This function configures the Cortex-M SysTick source to have 1ms time base with HCLK/8
220   *         as SysTick clock source.
221   * @note   When a RTOS is used, it is recommended to avoid changing the Systick
222   *         configuration by calling this function, for a delay use rather osDelay RTOS service.
223   * @param  HCLKFrequency HCLK frequency in Hz
224   * @retval None
225   */
LL_Init1msTick_HCLK_Div8(uint32_t HCLKFrequency)226 void LL_Init1msTick_HCLK_Div8(uint32_t HCLKFrequency)
227 {
228   /* Configure the SysTick to have 1ms time base with HCLK/8 as SysTick clock source */
229   SysTick->LOAD = (uint32_t)((HCLKFrequency / 8000U) - 1UL);
230   SysTick->VAL = 0UL;
231   SysTick->CTRL = SysTick_CTRL_ENABLE_Msk;
232 }
233 
234 /**
235   * @brief  This function configures the Cortex-M SysTick source to have 1ms time base with LSE as SysTick clock source.
236   * @note   When a RTOS is used, it is recommended to avoid changing the Systick
237   *         configuration by calling this function, for a delay use rather osDelay RTOS service.
238   * @retval None
239   */
LL_Init1msTick_LSE(void)240 void LL_Init1msTick_LSE(void)
241 {
242   /* Configure the SysTick to have 1ms time base with LSE as SysTick clock source */
243   SysTick->LOAD = (uint32_t)((LSE_VALUE / 1000U) - 1UL);
244   SysTick->VAL = 0UL;
245   SysTick->CTRL = SysTick_CTRL_ENABLE_Msk;
246 }
247 
248 /**
249   * @brief  This function configures the Cortex-M SysTick source to have 1ms time base with LSI as SysTick clock source.
250   * @note   When a RTOS is used, it is recommended to avoid changing the Systick
251   *         configuration by calling this function, for a delay use rather osDelay RTOS service.
252   * @retval None
253   */
LL_Init1msTick_LSI(void)254 void LL_Init1msTick_LSI(void)
255 {
256   /* Configure the SysTick to have 1ms time base with LSI as SysTick clock source */
257   SysTick->LOAD = (uint32_t)((LSI_VALUE / 1000U) - 1UL);
258   SysTick->VAL = 0UL;
259   SysTick->CTRL = SysTick_CTRL_ENABLE_Msk;
260 }
261 
262 /**
263   * @brief  This function provides minimum delay (in milliseconds) based
264   *         on SysTick counter flag
265   * @note   When a RTOS is used, it is recommended to avoid using blocking delay
266   *         and use rather osDelay service.
267   * @note   To respect 1ms timebase, user should call @ref LL_Init1msTick function which
268   *         will configure Systick to 1ms
269   * @param  Delay specifies the minimum delay time length, in milliseconds.
270   * @retval None
271   */
LL_mDelay(uint32_t Delay)272 void LL_mDelay(uint32_t Delay)
273 {
274   __IO uint32_t  tmp = SysTick->CTRL;  /* Clear the COUNTFLAG first */
275   uint32_t tmpDelay = Delay;
276 
277   /* Add this code to indicate that local variable is not used */
278   ((void)tmp);
279 
280   /* Add a period to guaranty minimum wait */
281   if (tmpDelay < LL_MAX_DELAY)
282   {
283     tmpDelay++;
284   }
285 
286   while (tmpDelay != 0U)
287   {
288     if ((SysTick->CTRL & SysTick_CTRL_COUNTFLAG_Msk) != 0U)
289     {
290       tmpDelay--;
291     }
292   }
293 }
294 
295 /**
296   * @}
297   */
298 
299 /** @addtogroup UTILS_EF_SYSTEM
300   *  @brief    System Configuration functions
301   *
302   @verbatim
303  ===============================================================================
304            ##### System Configuration functions #####
305  ===============================================================================
306     [..]
307          System, AHB and APB buses clocks configuration
308 
309          (+) The maximum frequency of the SYSCLK is 250 MHz and HCLK is 250 MHz.
310          (+) The maximum frequency of the PCLK1, PCLK2 and PCLK3 is 250 MHz.
311   @endverbatim
312   @internal
313              Depending on the device voltage range, the maximum frequency should be
314              adapted accordingly:
315 
316              (++) Table 1. HCLK clock frequency for STM32H5 devices
317              (++) +-----------------------------------------------------------------------------------------------+
318              (++) | Latency         |                          HCLK clock frequency (MHz)                         |
319              (++) |                 |-----------------------------------------------------------------------------|
320              (++) |                 |  voltage range 0  |  voltage range 1 | voltage range 2  | voltage range 3   |
321              (++) |                 |    1.30 - 1.40V   |   1.15 - 1.26V   |   1.05 - 1.15V   |   0,95 - 1,05V    |
322              (++) |-----------------|-------------------|------------------|------------------|-------------------|
323              (++) |0WS(1 CPU cycles)|   0 < HCLK <= 42  |  0 < HCLK <= 34  |  0 < HCLK <= 30  | 0 < HCLK <= 20    |
324              (++) |-----------------|-------------------|------------------|------------------|-------------------|
325              (++) |1WS(2 CPU cycles)|  42 < HCLK <= 84  | 34 < HCLK <= 68  | 30 < HCLK <= 60  | 20 < HCLK <= 40   |
326              (++) |-----------------|-------------------|------------------|------------------|-------------------|
327              (++) |2WS(3 CPU cycles)|  84 < HCLK <= 126 | 68 < HCLK <= 102 | 60 < HCLK <= 90  | 40 < HCLK <= 60   |
328              (++) |-----------------|-------------------|------------------|------------------|-------------------|
329              (++) |3WS(4 CPU cycles)| 126 < HCLK <= 168 | 102 < HCLK <= 136| 90 < HCLK <= 120 | 60 < HCLK <= 80   |
330              (++) |-----------------|-------------------|------------------|------------------|-------------------|
331              (++) |4WS(5 CPU cycles)|  168 < HCLK <= 210| 136 < HCLK <= 170| 120 < HCLK <= 150| 80 < HCLK <= 100  |
332              (++) |-----------------|-------------------|------------------|------------------|-------------------|
333              (++) |5WS(6 CPU cycles)|  210 < HCLK <= 250| 170 < HCLK <= 200|        NA        |         NA        |
334              (++) +-----------------+-------------------+------------------+------------------+-------------------+
335 
336   @endinternal
337   * @{
338   */
339 
340 /**
341   * @brief  This function sets directly SystemCoreClock CMSIS variable.
342   * @note   Variable can be calculated also through SystemCoreClockUpdate function.
343   * @param  HCLKFrequency HCLK frequency in Hz (can be calculated thanks to RCC helper macro)
344   * @retval None
345   */
LL_SetSystemCoreClock(uint32_t HCLKFrequency)346 void LL_SetSystemCoreClock(uint32_t HCLKFrequency)
347 {
348   /* HCLK clock frequency */
349   SystemCoreClock = HCLKFrequency;
350 }
351 
352 /**
353   * @brief  This function configures system clock at maximum frequency with CSI as clock source of the PLL1
354   * @note   The application needs to ensure that all PLLs is disabled.
355   * @note   Function is based on the following formula:
356   *         - PLL1 output frequency = (((CSI frequency / PLL1M) * PLL1N) / PLL1P)
357   *         - PLL1M: ensure that the VCO input frequency ranges from 1 to 16 MHz (PLL1VCO_input = CSI frequency / PLL1M)
358   *         - PLL1N: ensure that the VCO output frequency is between 192 and 836 MHz
359   *          (PLL1VCO_output = PLL1VCO_input * PLL1N)
360   *         - PLL1P: ensure that max frequency at 250 MHz is reached (PLL1VCO_output / PLL1P)
361   * @param  UTILS_PLLInitStruct pointer to a @ref LL_UTILS_PLLInitTypeDef structure that contains
362   *                             the configuration information for the PLL.
363   * @param  UTILS_ClkInitStruct pointer to a @ref LL_UTILS_ClkInitTypeDef structure that contains
364   *                             the configuration information for the BUS prescalers.
365   * @retval An ErrorStatus enumeration value:
366   *          - SUCCESS: Max frequency configuration done
367   *          - ERROR: Max frequency configuration not done
368   */
LL_PLL_ConfigSystemClock_CSI(LL_UTILS_PLLInitTypeDef * UTILS_PLLInitStruct,LL_UTILS_ClkInitTypeDef * UTILS_ClkInitStruct)369 ErrorStatus LL_PLL_ConfigSystemClock_CSI(LL_UTILS_PLLInitTypeDef *UTILS_PLLInitStruct,
370                                          LL_UTILS_ClkInitTypeDef *UTILS_ClkInitStruct)
371 {
372   ErrorStatus status;
373 #ifdef  USE_FULL_ASSERT
374   uint32_t vcoinput_freq;
375   uint32_t vcooutput_freq;
376 #endif /* USE_FULL_ASSERT */
377   uint32_t pllfreq;
378 
379   /* Check the parameters */
380   assert_param(IS_LL_UTILS_PLLM_VALUE(UTILS_PLLInitStruct->PLLM));
381   assert_param(IS_LL_UTILS_PLLN_VALUE(UTILS_PLLInitStruct->PLLN));
382   assert_param(IS_LL_UTILS_PLLP_VALUE(UTILS_PLLInitStruct->PLLP));
383   assert_param(IS_LL_UTILS_FRACN_VALUE(UTILS_PLLInitStruct->FRACN));
384 
385   /* Check VCO Input frequency */
386 #ifdef  USE_FULL_ASSERT
387   vcoinput_freq = CSI_VALUE / UTILS_PLLInitStruct->PLLM;
388 #endif /* USE_FULL_ASSERT */
389   assert_param(IS_LL_UTILS_PLLVCO_INPUT(vcoinput_freq, UTILS_PLLInitStruct->VCO_Input));
390 
391   /* Check VCO Input ranges */
392   assert_param(IS_LL_UTILS_CHECK_VCO_RANGES(UTILS_PLLInitStruct->VCO_Input, UTILS_PLLInitStruct->VCO_Output));
393 
394   /* Check VCO Output frequency */
395 #ifdef  USE_FULL_ASSERT
396   vcooutput_freq = LL_RCC_CalcPLLClockFreq(CSI_VALUE, UTILS_PLLInitStruct->PLLM, UTILS_PLLInitStruct->PLLN,
397                                            UTILS_PLLInitStruct->FRACN, 1U);
398   /* PLL1P Set to 1 to check the assert param (VCO_output)*/
399 #endif /* USE_FULL_ASSERT */
400   assert_param(IS_LL_UTILS_PLLVCO_OUTPUT(vcooutput_freq, UTILS_PLLInitStruct->VCO_Output));
401 
402   /* Check if the main PLL is enabled */
403   if (UTILS_PLL_IsBusy() == SUCCESS)
404   {
405     /* Calculate the new PLL output frequency */
406     pllfreq = UTILS_GetPLLOutputFrequency(CSI_VALUE, UTILS_PLLInitStruct);
407 
408     /* Enable CSI if not enabled */
409     if (LL_RCC_CSI_IsReady() != 1U)
410     {
411       LL_RCC_CSI_Enable();
412       while (LL_RCC_CSI_IsReady() != 1U)
413       {
414         /* Wait for CSI ready */
415       }
416     }
417 
418     /* Configure PLL */
419     LL_RCC_PLL1_ConfigDomain_SYS(LL_RCC_PLL1SOURCE_CSI, UTILS_PLLInitStruct->PLLM, UTILS_PLLInitStruct->PLLN,
420                                  UTILS_PLLInitStruct->PLLP);
421     LL_RCC_PLL1FRACN_Disable();
422     LL_RCC_PLL1_SetFRACN(UTILS_PLLInitStruct->FRACN);
423     LL_RCC_PLL1FRACN_Enable();
424     LL_RCC_PLL1_SetVCOInputRange(UTILS_PLLInitStruct->VCO_Input);
425     LL_RCC_PLL1_SetVCOOutputRange(UTILS_PLLInitStruct->VCO_Output);
426 
427     /* Enable PLL and switch system clock to PLL */
428     status = UTILS_EnablePLLAndSwitchSystem(pllfreq, UTILS_ClkInitStruct);
429   }
430   else
431   {
432     /* Current PLL configuration cannot be modified */
433     status = ERROR;
434   }
435 
436   return status;
437 }
438 
439 
440 /**
441   * @brief  This function configures system clock at maximum frequency with HSI as clock source of the PLL1
442   * @note   The application need to ensure that all PLLs are disabled.
443   * @note   Function is based on the following formula:
444   *         - PLL1 output frequency = (((HSI frequency / PLL1M) * PLL1N) / PLL1P)
445   *         - PLL1M: ensure that the VCO input frequency ranges from 1 to 16 MHz (PLL1VCO_input = HSI frequency / PLL1M)
446   *         - PLL1N: ensure that the VCO output frequency is between 150 and 836 MHz
447   *          (PLL1VCO_output = PLL1VCO_input * PLL1N)
448   *         - PLL1P: ensure that max frequency at 250 MHz is reach (PLL1VCO_output / PLL1P)
449   * @param  UTILS_PLLInitStruct pointer to a @ref LL_UTILS_PLLInitTypeDef structure that contains
450   *                             the configuration information for the PLL1.
451   * @param  UTILS_ClkInitStruct pointer to a @ref LL_UTILS_ClkInitTypeDef structure that contains
452   *                             the configuration information for the BUS prescalers.
453   * @retval An ErrorStatus enumeration value:
454   *          - SUCCESS: Max frequency configuration done
455   *          - ERROR: Max frequency configuration not done
456   *
457   *
458   */
LL_PLL_ConfigSystemClock_HSI(LL_UTILS_PLLInitTypeDef * UTILS_PLLInitStruct,LL_UTILS_ClkInitTypeDef * UTILS_ClkInitStruct)459 ErrorStatus LL_PLL_ConfigSystemClock_HSI(LL_UTILS_PLLInitTypeDef *UTILS_PLLInitStruct,
460                                          LL_UTILS_ClkInitTypeDef *UTILS_ClkInitStruct)
461 {
462   ErrorStatus status;
463 #ifdef  USE_FULL_ASSERT
464   uint32_t vcoinput_freq;
465   uint32_t vcooutput_freq;
466 #endif /* USE_FULL_ASSERT */
467   uint32_t pllfreq;
468   uint32_t hsi_clk;
469 
470   /* Check the parameters */
471   assert_param(IS_LL_UTILS_PLLM_VALUE(UTILS_PLLInitStruct->PLLM));
472   assert_param(IS_LL_UTILS_PLLN_VALUE(UTILS_PLLInitStruct->PLLN));
473   assert_param(IS_LL_UTILS_PLLP_VALUE(UTILS_PLLInitStruct->PLLP));
474   assert_param(IS_LL_UTILS_FRACN_VALUE(UTILS_PLLInitStruct->FRACN));
475 
476   hsi_clk = (HSI_VALUE >> (LL_RCC_HSI_GetDivider() >> RCC_CR_HSIDIV_Pos));
477 
478   /* Check VCO Input frequency */
479 #ifdef  USE_FULL_ASSERT
480   vcoinput_freq = hsi_clk / UTILS_PLLInitStruct->PLLM;
481 #endif /* USE_FULL_ASSERT */
482   assert_param(IS_LL_UTILS_PLLVCO_INPUT(vcoinput_freq, UTILS_PLLInitStruct->VCO_Input));
483 
484   /* Check VCO Input ranges */
485   assert_param(IS_LL_UTILS_CHECK_VCO_RANGES(UTILS_PLLInitStruct->VCO_Input, UTILS_PLLInitStruct->VCO_Output));
486 
487   /* Check VCO Output frequency */
488 #ifdef  USE_FULL_ASSERT
489   vcooutput_freq = LL_RCC_CalcPLLClockFreq(hsi_clk, UTILS_PLLInitStruct->PLLM, UTILS_PLLInitStruct->PLLN,
490                                            UTILS_PLLInitStruct->FRACN, 1UL);
491   /* PLL1P Set to 1 to check the assert param (VCO_output)*/
492 #endif /* USE_FULL_ASSERT */
493   assert_param(IS_LL_UTILS_PLLVCO_OUTPUT(vcooutput_freq, UTILS_PLLInitStruct->VCO_Output));
494 
495   /* Check if the main PLL is enabled */
496   if (UTILS_PLL_IsBusy() == SUCCESS)
497   {
498     /* Calculate the new PLL output frequency */
499     pllfreq = UTILS_GetPLLOutputFrequency(hsi_clk, UTILS_PLLInitStruct);
500 
501     /* Enable HSI if not enabled */
502     if (LL_RCC_HSI_IsReady() != 1U)
503     {
504       LL_RCC_HSI_Enable();
505       while (LL_RCC_HSI_IsReady() != 1U)
506       {
507         /* Wait for HSI ready */
508       }
509     }
510 
511     /* Configure PLL */
512     LL_RCC_PLL1_ConfigDomain_SYS(LL_RCC_PLL1SOURCE_HSI, UTILS_PLLInitStruct->PLLM, UTILS_PLLInitStruct->PLLN,
513                                  UTILS_PLLInitStruct->PLLP);
514     LL_RCC_PLL1FRACN_Disable();
515     LL_RCC_PLL1_SetFRACN(UTILS_PLLInitStruct->FRACN);
516     LL_RCC_PLL1FRACN_Enable();
517     LL_RCC_PLL1_SetVCOInputRange(UTILS_PLLInitStruct->VCO_Input);
518     LL_RCC_PLL1_SetVCOOutputRange(UTILS_PLLInitStruct->VCO_Output);
519 
520     /* Enable PLL and switch system clock to PLL */
521     status = UTILS_EnablePLLAndSwitchSystem(pllfreq, UTILS_ClkInitStruct);
522   }
523   else
524   {
525     /* Current PLL configuration cannot be modified */
526     status = ERROR;
527   }
528 
529   return status;
530 }
531 
532 /**
533   * @brief  This function configures system clock with HSE as clock source of the PLL1
534   * @note   The application needs to ensure that the PLL1 is disabled.
535   * @note   Function is based on the following formula:
536   *         - PLL1 output frequency = (((HSE frequency / PLL1M) * PLL1N) / PLL1P)
537   *         - PLL1M: ensure that the VCO input frequency ranges from 1 to 16 MHz (PLL1VCO_input = HSE frequency / PLL1M)
538   *         - PLL1N: ensure that the VCO output frequency is between 192 and 836 MHz
539   *          (PLL1VCO_output = PLL1VCO_input * PLL1N)
540   *         - PLL1P: ensure that max frequency at 250 MHz is reached (PLL1VCO_output / PLL1P)
541   * @param  HSEFrequency Value between Min_Data = 4000000 and Max_Data = 50000000
542   * @param  HSEBypass This parameter can be one of the following values:
543   *         @arg @ref LL_UTILS_HSEBYPASS_ON
544   *         @arg @ref LL_UTILS_HSEBYPASS_OFF
545   * @param  UTILS_PLLInitStruct pointer to a @ref LL_UTILS_PLLInitTypeDef structure that contains
546   *                             the configuration information for the PLL.
547   * @param  UTILS_ClkInitStruct pointer to a @ref LL_UTILS_ClkInitTypeDef structure that contains
548   *                             the configuration information for the BUS prescalers.
549   * @retval An ErrorStatus enumeration value:
550   *          - SUCCESS: Max frequency configuration done
551   *          - ERROR: Max frequency configuration not done
552   */
LL_PLL_ConfigSystemClock_HSE(uint32_t HSEFrequency,uint32_t HSEBypass,LL_UTILS_PLLInitTypeDef * UTILS_PLLInitStruct,LL_UTILS_ClkInitTypeDef * UTILS_ClkInitStruct)553 ErrorStatus LL_PLL_ConfigSystemClock_HSE(uint32_t HSEFrequency, uint32_t HSEBypass,
554                                          LL_UTILS_PLLInitTypeDef *UTILS_PLLInitStruct,
555                                          LL_UTILS_ClkInitTypeDef *UTILS_ClkInitStruct)
556 {
557   ErrorStatus status;
558 #ifdef  USE_FULL_ASSERT
559   uint32_t vcoinput_freq;
560   uint32_t vcooutput_freq;
561 #endif /* USE_FULL_ASSERT */
562   uint32_t pllfreq;
563 
564   /* Check the parameters */
565   assert_param(IS_LL_UTILS_PLLM_VALUE(UTILS_PLLInitStruct->PLLM));
566   assert_param(IS_LL_UTILS_PLLN_VALUE(UTILS_PLLInitStruct->PLLN));
567   assert_param(IS_LL_UTILS_PLLP_VALUE(UTILS_PLLInitStruct->PLLP));
568   assert_param(IS_LL_UTILS_FRACN_VALUE(UTILS_PLLInitStruct->FRACN));
569   assert_param(IS_LL_UTILS_HSE_FREQUENCY(HSEFrequency));
570   assert_param(IS_LL_UTILS_HSE_BYPASS(HSEBypass));
571 
572   /* Check VCO Input frequency */
573 #ifdef  USE_FULL_ASSERT
574   vcoinput_freq = HSEFrequency / UTILS_PLLInitStruct->PLLM;
575 #endif /* USE_FULL_ASSERT */
576   assert_param(IS_LL_UTILS_PLLVCO_INPUT(vcoinput_freq, UTILS_PLLInitStruct->VCO_Input));
577 
578   /* Check VCO Input/output ranges compatibility */
579   assert_param(IS_LL_UTILS_CHECK_VCO_RANGES(UTILS_PLLInitStruct->VCO_Input, UTILS_PLLInitStruct->VCO_Output));
580 
581   /* Check VCO output frequency */
582 #ifdef  USE_FULL_ASSERT
583   vcooutput_freq = LL_RCC_CalcPLLClockFreq(HSEFrequency, UTILS_PLLInitStruct->PLLM, UTILS_PLLInitStruct->PLLN,
584                                            UTILS_PLLInitStruct->FRACN, 1U);
585   /* PLL1P Set to 1 to check the assert param (VCO_output)*/
586 #endif /* USE_FULL_ASSERT */
587   assert_param(IS_LL_UTILS_PLLVCO_OUTPUT(vcooutput_freq, UTILS_PLLInitStruct->VCO_Output));
588 
589   /* Check if the main PLL is enabled */
590   if (UTILS_PLL_IsBusy() == SUCCESS)
591   {
592     /* Calculate the new PLL output frequency */
593     pllfreq = UTILS_GetPLLOutputFrequency(HSEFrequency, UTILS_PLLInitStruct);
594 
595     /* Enable HSE if not enabled */
596     if (LL_RCC_HSE_IsReady() != 1U)
597     {
598       /* Check if need to enable HSE bypass feature or not */
599       if (HSEBypass == LL_UTILS_HSEBYPASS_ON)
600       {
601         LL_RCC_HSE_EnableBypass();
602         LL_RCC_HSE_SetExternalClockType(LL_RCC_HSE_ANALOG_TYPE);
603       }
604       else if (HSEBypass == LL_UTILS_HSEBYPASS_DIGITAL_ON)
605       {
606         LL_RCC_HSE_EnableBypass();
607         LL_RCC_HSE_SetExternalClockType(LL_RCC_HSE_DIGITAL_TYPE);
608       }
609       else
610       {
611         LL_RCC_HSE_DisableBypass();
612       }
613 
614       /* Enable HSE */
615       LL_RCC_HSE_Enable();
616       while (LL_RCC_HSE_IsReady() != 1U)
617       {
618         /* Wait for HSE ready */
619       }
620     }
621 
622     /* Configure PLL */
623     LL_RCC_PLL1_ConfigDomain_SYS(LL_RCC_PLL1SOURCE_HSE, UTILS_PLLInitStruct->PLLM, UTILS_PLLInitStruct->PLLN,
624                                  UTILS_PLLInitStruct->PLLP);
625     LL_RCC_PLL1FRACN_Disable();
626     LL_RCC_PLL1_SetFRACN(UTILS_PLLInitStruct->FRACN);
627     LL_RCC_PLL1FRACN_Enable();
628     LL_RCC_PLL1_SetVCOInputRange(UTILS_PLLInitStruct->VCO_Input);
629     LL_RCC_PLL1_SetVCOOutputRange(UTILS_PLLInitStruct->VCO_Output);
630 
631     /* Enable PLL and switch system clock to PLL */
632     status = UTILS_EnablePLLAndSwitchSystem(pllfreq, UTILS_ClkInitStruct);
633   }
634   else
635   {
636     /* Current PLL configuration cannot be modified */
637     status = ERROR;
638   }
639 
640   return status;
641 }
642 
643 /**
644   * @}
645   */
646 
647 /**
648   * @}
649   */
650 
651 /**
652   * @brief  Update number of Flash wait states in line with new frequency and current
653             voltage range.
654   * @param  HCLK_Frequency  HCLK frequency
655   * @retval An ErrorStatus enumeration value:
656   *          - SUCCESS: Latency has been modified
657   *          - ERROR: Latency cannot be modified
658   */
LL_SetFlashLatency(uint32_t HCLK_Frequency)659 ErrorStatus LL_SetFlashLatency(uint32_t HCLK_Frequency)
660 {
661   ErrorStatus status = SUCCESS;
662   uint32_t timeout;
663   uint32_t getlatency;
664   uint32_t latency = LL_FLASH_LATENCY_0;  /* default value 0WS */
665 
666   /* Frequency cannot be equal to 0 */
667   if (HCLK_Frequency == 0U)
668   {
669     status = ERROR;
670   }
671   else
672   {
673     if (LL_PWR_GetRegulVoltageScaling() == LL_PWR_REGU_VOLTAGE_SCALE0)
674     {
675       if (HCLK_Frequency <= UTILS_SCALE0_LATENCY0_FREQ)
676       {
677         /* 0 < HCLK <= 42 => 0WS (1 CPU cycles) : Do nothing, keep latency to default  LL_FLASH_LATENCY_0 */
678       }
679       else if ((HCLK_Frequency <= UTILS_SCALE0_LATENCY1_FREQ))
680       {
681         /* 42 < HCLK <=84  => 1WS (2 CPU cycles) */
682         latency = LL_FLASH_LATENCY_1;
683       }
684       else if (HCLK_Frequency <= UTILS_SCALE0_LATENCY2_FREQ)
685       {
686         /* 84 < HCLK <= 126 => 2WS (3 CPU cycles) */
687         latency = LL_FLASH_LATENCY_2;
688       }
689       else if (HCLK_Frequency <= UTILS_SCALE0_LATENCY3_FREQ)
690       {
691         /* 126 < HCLK <= 168 => 3WS (4 CPU cycles) */
692         latency = LL_FLASH_LATENCY_3;
693       }
694       else if (HCLK_Frequency <= UTILS_SCALE0_LATENCY4_FREQ)
695       {
696         /* 168 < HCLK <= 210 => 4WS (5 CPU cycles) */
697         latency = LL_FLASH_LATENCY_4;
698       }
699       else if (HCLK_Frequency <= UTILS_SCALE0_LATENCY5_FREQ)
700       {
701         /* 210 < HCLK <= 250 => 5WS (6 CPU cycles) */
702         latency = LL_FLASH_LATENCY_5;
703       }
704       else
705       {
706         status = ERROR;
707       }
708     }
709     else if (LL_PWR_GetRegulVoltageScaling() == LL_PWR_REGU_VOLTAGE_SCALE1)
710     {
711       if (HCLK_Frequency <= UTILS_SCALE1_LATENCY0_FREQ)
712       {
713         /* 0 < HCLK <= 34 => 0WS (1 CPU cycles) : Do nothing, keep latency to default  LL_FLASH_LATENCY_0 */
714       }
715       else if (HCLK_Frequency <= UTILS_SCALE1_LATENCY1_FREQ)
716       {
717         /* 34 < HCLK <=68  => 1WS (2 CPU cycles) */
718         latency = LL_FLASH_LATENCY_1;
719       }
720       else if (HCLK_Frequency <= UTILS_SCALE1_LATENCY2_FREQ)
721       {
722         /* 68 < HCLK <= 102 => 2WS (3 CPU cycles) */
723         latency = LL_FLASH_LATENCY_2;
724       }
725       else if (HCLK_Frequency <= UTILS_SCALE1_LATENCY3_FREQ)
726       {
727         /* 102 < HCLK <= 136 => 3WS (4 CPU cycles) */
728         latency = LL_FLASH_LATENCY_3;
729       }
730       else if (HCLK_Frequency <= UTILS_SCALE1_LATENCY4_FREQ)
731       {
732         /* 136 < HCLK <= 170 => 4WS (5 CPU cycles) */
733         latency = LL_FLASH_LATENCY_4;
734       }
735       else if (HCLK_Frequency <= UTILS_SCALE1_LATENCY5_FREQ)
736       {
737         /* 170 < HCLK <= 200 => 5WS (6 CPU cycles) */
738         latency = LL_FLASH_LATENCY_5;
739       }
740       else
741       {
742         status = ERROR;
743       }
744     }
745     else if (LL_PWR_GetRegulVoltageScaling() == LL_PWR_REGU_VOLTAGE_SCALE2)
746     {
747       if (HCLK_Frequency <= UTILS_SCALE2_LATENCY0_FREQ)
748       {
749         /* 0 < HCLK <= 30 => 0WS (1 CPU cycles) : Do nothing, keep latency to default  LL_FLASH_LATENCY_0 */
750       }
751       else if (HCLK_Frequency <= UTILS_SCALE2_LATENCY1_FREQ)
752       {
753         /* 30 < HCLK <= 60 => 1WS (2 CPU cycles) */
754         latency = LL_FLASH_LATENCY_1;
755       }
756       else if (HCLK_Frequency <= UTILS_SCALE2_LATENCY2_FREQ)
757       {
758         /* 60 < HCLK <= 90 => 2WS (3 CPU cycles) */
759         latency = LL_FLASH_LATENCY_2;
760       }
761       else if (HCLK_Frequency <= UTILS_SCALE2_LATENCY3_FREQ)
762       {
763         /* 90 < HCLK <= 120 => 3WS (4 CPU cycles) */
764         latency = LL_FLASH_LATENCY_3;
765       }
766       else if (HCLK_Frequency <= UTILS_SCALE2_LATENCY4_FREQ)
767       {
768         /* 120 < HCLK <= 150 => 4WS (5 CPU cycles) */
769         latency = LL_FLASH_LATENCY_4;
770       }
771       else
772       {
773         status = ERROR;
774       }
775     }
776     else /* Voltage Scale 3 */
777     {
778       if (HCLK_Frequency  <= UTILS_SCALE3_LATENCY0_FREQ)
779       {
780         /* 0 < HCLK <= 20 => 0WS (1 CPU cycles) : Do nothing, keep latency to default  LL_FLASH_LATENCY_0 */
781       }
782       else if (HCLK_Frequency <= UTILS_SCALE3_LATENCY1_FREQ)
783       {
784         /* 20 < HCLK <= 40 => 1WS (2 CPU cycles) */
785         latency = LL_FLASH_LATENCY_1;
786       }
787       else if (HCLK_Frequency <= UTILS_SCALE3_LATENCY2_FREQ)
788       {
789         /* 40 < HCLK <= 60 => 2WS (3 CPU cycles) */
790         latency = LL_FLASH_LATENCY_2;
791       }
792       else if (HCLK_Frequency <= UTILS_SCALE3_LATENCY3_FREQ)
793       {
794         /* 60 < HCLK <= 80 => 3WS (4 CPU cycles) */
795         latency = LL_FLASH_LATENCY_3;
796       }
797       else if (HCLK_Frequency <= UTILS_SCALE3_LATENCY4_FREQ)
798       {
799         /* 80 < HCLK <= 100 => 4WS (5 CPU cycles) */
800         latency = LL_FLASH_LATENCY_4;
801       }
802       else
803       {
804         status = ERROR;
805       }
806     }
807   }
808 
809   if (status == SUCCESS)
810   {
811     LL_FLASH_SetLatency(latency);
812 
813     /* Check that the new number of wait states is taken into account to access the Flash
814     memory by reading the FLASH_ACR register */
815     timeout = 2;
816     do
817     {
818       /* Wait for Flash latency to be updated */
819       getlatency = LL_FLASH_GetLatency();
820       timeout--;
821     } while ((getlatency != latency) && (timeout > 0U));
822 
823     if (getlatency != latency)
824     {
825       status = ERROR;
826     }
827   }
828   return status;
829 }
830 
831 /** @addtogroup UTILS_LL_Private_Functions
832   * @{
833   */
834 /**
835   * @brief  Function to Get PLL1 Output frequency
836   * @param  PLL_InputFrequency  PLL1 input frequency (in Hz)
837   * @param  UTILS_PLLInitStruct pointer to a @ref LL_UTILS_PLLInitTypeDef structure that contains
838   *                             the configuration information for the PLL.
839   * @retval PLL output frequency (in Hz)
840   */
UTILS_GetPLLOutputFrequency(uint32_t PLL_InputFrequency,const LL_UTILS_PLLInitTypeDef * UTILS_PLLInitStruct)841 static uint32_t UTILS_GetPLLOutputFrequency(uint32_t PLL_InputFrequency,
842                                             const LL_UTILS_PLLInitTypeDef *UTILS_PLLInitStruct)
843 {
844   uint32_t pllfreq;
845 
846   /* Check the parameters */
847   assert_param(IS_LL_UTILS_PLLM_VALUE(UTILS_PLLInitStruct->PLLM));
848   assert_param(IS_LL_UTILS_PLLN_VALUE(UTILS_PLLInitStruct->PLLN));
849   assert_param(IS_LL_UTILS_PLLP_VALUE(UTILS_PLLInitStruct->PLLP));
850   assert_param(IS_LL_UTILS_FRACN_VALUE(UTILS_PLLInitStruct->FRACN));
851 
852   /* Check different PLL parameters according to RM                          */
853   /*  - PLLM: ensure that the VCO input frequency is in the correct range.   */
854   pllfreq = PLL_InputFrequency / (UTILS_PLLInitStruct->PLLM);
855   assert_param(IS_LL_UTILS_PLLVCO_INPUT(pllfreq,  UTILS_PLLInitStruct->VCO_Input));
856 
857   /*  - PLLN: ensure that the VCO output frequency is in the correct range.  */
858   pllfreq = pllfreq * (UTILS_PLLInitStruct->PLLN);
859   assert_param(IS_LL_UTILS_PLLVCO_OUTPUT(pllfreq,  UTILS_PLLInitStruct->VCO_Output));
860 
861   /*  - PLLP: ensure that PLL1P output frequency does not exceed the corresponding maximum voltage scale frequency.  */
862   pllfreq = pllfreq / (UTILS_PLLInitStruct->PLLP);
863   assert_param(IS_LL_UTILS_PLL_FREQUENCY(pllfreq));
864 
865   return pllfreq;
866 }
867 
868 /**
869   * @brief  Function to check that main PLL can be modified
870   * @retval An ErrorStatus enumeration value:
871   *          - SUCCESS: Main PLL modification can be done
872   *          - ERROR: Main PLL is busy
873   */
UTILS_PLL_IsBusy(void)874 static ErrorStatus UTILS_PLL_IsBusy(void)
875 {
876   ErrorStatus status = SUCCESS;
877 
878   /* Check if PLL1 is busy*/
879   if (LL_RCC_PLL1_IsReady() != 0U)
880   {
881     /* PLL configuration cannot be modified */
882     status = ERROR;
883   }
884 
885   return status;
886 }
887 
888 /**
889   * @brief  Function to enable PLL1 and switch system clock to PLL1
890   * @param  SYSCLK_Frequency SYSCLK frequency
891   * @param  UTILS_ClkInitStruct pointer to a @ref LL_UTILS_ClkInitTypeDef structure that contains
892   *                             the configuration information for the BUS prescalers.
893   * @retval An ErrorStatus enumeration value:
894   *          - SUCCESS: No problem to switch system to PLL1
895   *          - ERROR: Problem to switch system to PLL1
896   */
UTILS_EnablePLLAndSwitchSystem(uint32_t SYSCLK_Frequency,LL_UTILS_ClkInitTypeDef * UTILS_ClkInitStruct)897 static ErrorStatus UTILS_EnablePLLAndSwitchSystem(uint32_t SYSCLK_Frequency,
898                                                   LL_UTILS_ClkInitTypeDef *UTILS_ClkInitStruct)
899 {
900   ErrorStatus status = SUCCESS;
901   uint32_t hclk_frequency;
902 
903   assert_param(IS_LL_UTILS_SYSCLK_DIV(UTILS_ClkInitStruct->SYSCLKDivider));
904   assert_param(IS_LL_UTILS_APB1_DIV(UTILS_ClkInitStruct->APB1CLKDivider));
905   assert_param(IS_LL_UTILS_APB2_DIV(UTILS_ClkInitStruct->APB2CLKDivider));
906   assert_param(IS_LL_UTILS_APB3_DIV(UTILS_ClkInitStruct->APB3CLKDivider));
907 
908   /* Calculate HCLK frequency */
909   hclk_frequency = __LL_RCC_CALC_HCLK_FREQ(SYSCLK_Frequency, UTILS_ClkInitStruct->SYSCLKDivider);
910 
911   /* Increasing the number of wait states because of higher CPU frequency */
912   if (SystemCoreClock < hclk_frequency)
913   {
914     /* Set FLASH latency to highest latency */
915     status = LL_SetFlashLatency(hclk_frequency);
916   }
917 
918   /* Update system clock configuration */
919   if (status == SUCCESS)
920   {
921     /* Enable PLL1 */
922     LL_RCC_PLL1_Enable();
923     LL_RCC_PLL1P_Enable();
924     while (LL_RCC_PLL1_IsReady() != 1U)
925     {
926       /* Wait for PLL ready */
927     }
928 
929     /* Set All APBxPrescaler to the Highest Divider */
930     LL_RCC_SetAPB1Prescaler(LL_RCC_APB1_DIV_16);
931     LL_RCC_SetAPB2Prescaler(LL_RCC_APB2_DIV_16);
932     LL_RCC_SetAPB3Prescaler(LL_RCC_APB3_DIV_16);
933 
934     /* Set AHB prescaler*/
935     LL_RCC_SetAHBPrescaler(UTILS_ClkInitStruct->SYSCLKDivider);
936 
937     /* Sysclk activation on the main PLL */
938     LL_RCC_SetSysClkSource(LL_RCC_SYS_CLKSOURCE_PLL1);
939     while (LL_RCC_GetSysClkSource() != LL_RCC_SYS_CLKSOURCE_STATUS_PLL1)
940     {
941       /* Wait for system clock switch to PLL */
942     }
943 
944     /* Set APB1, APB2 & APB3 prescaler*/
945     LL_RCC_SetAPB1Prescaler(UTILS_ClkInitStruct->APB1CLKDivider);
946     LL_RCC_SetAPB2Prescaler(UTILS_ClkInitStruct->APB2CLKDivider);
947     LL_RCC_SetAPB3Prescaler(UTILS_ClkInitStruct->APB3CLKDivider);
948   }
949 
950   /* Decreasing the number of wait states because of lower CPU frequency */
951   if (SystemCoreClock > hclk_frequency)
952   {
953     /* Set FLASH latency to lowest latency */
954     status = LL_SetFlashLatency(hclk_frequency);
955   }
956 
957   /* Update SystemCoreClock variable */
958   if (status == SUCCESS)
959   {
960     LL_SetSystemCoreClock(hclk_frequency);
961   }
962 
963   return status;
964 }
965 
966 /**
967   * @}
968   */
969 
970 /**
971   * @}
972   */
973 
974 /**
975   * @}
976   */
977