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