1 /**
2 ******************************************************************************
3 * @file stm32f1xx_ll_utils.c
4 * @author MCD Application Team
5 * @brief UTILS LL module driver.
6 ******************************************************************************
7 * @attention
8 *
9 * <h2><center>© Copyright (c) 2016 STMicroelectronics.
10 * All rights reserved.</center></h2>
11 *
12 * This software component is licensed by ST under BSD 3-Clause license,
13 * the "License"; You may not use this file except in compliance with the
14 * License. You may obtain a copy of the License at:
15 * opensource.org/licenses/BSD-3-Clause
16 *
17 ******************************************************************************
18 */
19
20 /* Includes ------------------------------------------------------------------*/
21 #include "stm32f1xx_ll_rcc.h"
22 #include "stm32f1xx_ll_utils.h"
23 #include "stm32f1xx_ll_system.h"
24 #ifdef USE_FULL_ASSERT
25 #include "stm32_assert.h"
26 #else
27 #define assert_param(expr) ((void)0U)
28 #endif
29
30 /** @addtogroup STM32F1xx_LL_Driver
31 * @{
32 */
33
34 /** @addtogroup UTILS_LL
35 * @{
36 */
37
38 /* Private types -------------------------------------------------------------*/
39 /* Private variables ---------------------------------------------------------*/
40 /* Private constants ---------------------------------------------------------*/
41 /** @addtogroup UTILS_LL_Private_Constants
42 * @{
43 */
44
45 /* Defines used for PLL range */
46 #define UTILS_PLL_OUTPUT_MAX RCC_MAX_FREQUENCY /*!< Frequency max for PLL output, in Hz */
47 #define UTILS_PLL2_OUTPUT_MAX RCC_MAX_FREQUENCY /*!< Frequency max for PLL2 output, in Hz */
48
49 /* Defines used for HSE range */
50 #define UTILS_HSE_FREQUENCY_MIN RCC_HSE_MIN /*!< Frequency min for HSE frequency, in Hz */
51 #define UTILS_HSE_FREQUENCY_MAX RCC_HSE_MAX /*!< Frequency max for HSE frequency, in Hz */
52
53 /* Defines used for FLASH latency according to HCLK Frequency */
54 #if defined(FLASH_ACR_LATENCY)
55 #define UTILS_LATENCY1_FREQ 24000000U /*!< SYSCLK frequency to set FLASH latency 1 */
56 #define UTILS_LATENCY2_FREQ 48000000U /*!< SYSCLK frequency to set FLASH latency 2 */
57 #else
58 /*!< No Latency Configuration in this device */
59 #endif
60 /**
61 * @}
62 */
63 /* Private macros ------------------------------------------------------------*/
64 /** @addtogroup UTILS_LL_Private_Macros
65 * @{
66 */
67 #define IS_LL_UTILS_SYSCLK_DIV(__VALUE__) (((__VALUE__) == LL_RCC_SYSCLK_DIV_1) \
68 || ((__VALUE__) == LL_RCC_SYSCLK_DIV_2) \
69 || ((__VALUE__) == LL_RCC_SYSCLK_DIV_4) \
70 || ((__VALUE__) == LL_RCC_SYSCLK_DIV_8) \
71 || ((__VALUE__) == LL_RCC_SYSCLK_DIV_16) \
72 || ((__VALUE__) == LL_RCC_SYSCLK_DIV_64) \
73 || ((__VALUE__) == LL_RCC_SYSCLK_DIV_128) \
74 || ((__VALUE__) == LL_RCC_SYSCLK_DIV_256) \
75 || ((__VALUE__) == LL_RCC_SYSCLK_DIV_512))
76
77 #define IS_LL_UTILS_APB1_DIV(__VALUE__) (((__VALUE__) == LL_RCC_APB1_DIV_1) \
78 || ((__VALUE__) == LL_RCC_APB1_DIV_2) \
79 || ((__VALUE__) == LL_RCC_APB1_DIV_4) \
80 || ((__VALUE__) == LL_RCC_APB1_DIV_8) \
81 || ((__VALUE__) == LL_RCC_APB1_DIV_16))
82
83 #define IS_LL_UTILS_APB2_DIV(__VALUE__) (((__VALUE__) == LL_RCC_APB2_DIV_1) \
84 || ((__VALUE__) == LL_RCC_APB2_DIV_2) \
85 || ((__VALUE__) == LL_RCC_APB2_DIV_4) \
86 || ((__VALUE__) == LL_RCC_APB2_DIV_8) \
87 || ((__VALUE__) == LL_RCC_APB2_DIV_16))
88
89 #if defined(RCC_CFGR_PLLMULL6_5)
90 #define IS_LL_UTILS_PLLMUL_VALUE(__VALUE__) (((__VALUE__) == LL_RCC_PLL_MUL_4) \
91 || ((__VALUE__) == LL_RCC_PLL_MUL_5) \
92 || ((__VALUE__) == LL_RCC_PLL_MUL_6) \
93 || ((__VALUE__) == LL_RCC_PLL_MUL_7) \
94 || ((__VALUE__) == LL_RCC_PLL_MUL_8) \
95 || ((__VALUE__) == LL_RCC_PLL_MUL_9) \
96 || ((__VALUE__) == LL_RCC_PLL_MUL_6_5))
97 #else
98 #define IS_LL_UTILS_PLLMUL_VALUE(__VALUE__) (((__VALUE__) == LL_RCC_PLL_MUL_2) \
99 || ((__VALUE__) == LL_RCC_PLL_MUL_3) \
100 || ((__VALUE__) == LL_RCC_PLL_MUL_4) \
101 || ((__VALUE__) == LL_RCC_PLL_MUL_5) \
102 || ((__VALUE__) == LL_RCC_PLL_MUL_6) \
103 || ((__VALUE__) == LL_RCC_PLL_MUL_7) \
104 || ((__VALUE__) == LL_RCC_PLL_MUL_8) \
105 || ((__VALUE__) == LL_RCC_PLL_MUL_9) \
106 || ((__VALUE__) == LL_RCC_PLL_MUL_10) \
107 || ((__VALUE__) == LL_RCC_PLL_MUL_11) \
108 || ((__VALUE__) == LL_RCC_PLL_MUL_12) \
109 || ((__VALUE__) == LL_RCC_PLL_MUL_13) \
110 || ((__VALUE__) == LL_RCC_PLL_MUL_14) \
111 || ((__VALUE__) == LL_RCC_PLL_MUL_15) \
112 || ((__VALUE__) == LL_RCC_PLL_MUL_16))
113 #endif /* RCC_CFGR_PLLMULL6_5 */
114
115 #if defined(RCC_CFGR2_PREDIV1)
116 #define IS_LL_UTILS_PREDIV_VALUE(__VALUE__) (((__VALUE__) == LL_RCC_PREDIV_DIV_1) || ((__VALUE__) == LL_RCC_PREDIV_DIV_2) || \
117 ((__VALUE__) == LL_RCC_PREDIV_DIV_3) || ((__VALUE__) == LL_RCC_PREDIV_DIV_4) || \
118 ((__VALUE__) == LL_RCC_PREDIV_DIV_5) || ((__VALUE__) == LL_RCC_PREDIV_DIV_6) || \
119 ((__VALUE__) == LL_RCC_PREDIV_DIV_7) || ((__VALUE__) == LL_RCC_PREDIV_DIV_8) || \
120 ((__VALUE__) == LL_RCC_PREDIV_DIV_9) || ((__VALUE__) == LL_RCC_PREDIV_DIV_10) || \
121 ((__VALUE__) == LL_RCC_PREDIV_DIV_11) || ((__VALUE__) == LL_RCC_PREDIV_DIV_12) || \
122 ((__VALUE__) == LL_RCC_PREDIV_DIV_13) || ((__VALUE__) == LL_RCC_PREDIV_DIV_14) || \
123 ((__VALUE__) == LL_RCC_PREDIV_DIV_15) || ((__VALUE__) == LL_RCC_PREDIV_DIV_16))
124 #else
125 #define IS_LL_UTILS_PREDIV_VALUE(__VALUE__) (((__VALUE__) == LL_RCC_PREDIV_DIV_1) || ((__VALUE__) == LL_RCC_PREDIV_DIV_2))
126 #endif /*RCC_PREDIV1_DIV_2_16_SUPPORT*/
127
128 #define IS_LL_UTILS_PLL_FREQUENCY(__VALUE__) ((__VALUE__) <= UTILS_PLL_OUTPUT_MAX)
129
130 #if defined(RCC_PLL2_SUPPORT)
131 #define IS_LL_UTILS_PLL2MUL_VALUE(__VALUE__) (((__VALUE__) == LL_RCC_PLL2_MUL_8) \
132 || ((__VALUE__) == LL_RCC_PLL2_MUL_9) \
133 || ((__VALUE__) == LL_RCC_PLL2_MUL_10) \
134 || ((__VALUE__) == LL_RCC_PLL2_MUL_11) \
135 || ((__VALUE__) == LL_RCC_PLL2_MUL_12) \
136 || ((__VALUE__) == LL_RCC_PLL2_MUL_13) \
137 || ((__VALUE__) == LL_RCC_PLL2_MUL_14) \
138 || ((__VALUE__) == LL_RCC_PLL2_MUL_16) \
139 || ((__VALUE__) == LL_RCC_PLL2_MUL_20))
140
141 #define IS_LL_UTILS_PREDIV2_VALUE(__VALUE__) (((__VALUE__) == LL_RCC_HSE_PREDIV2_DIV_1) || ((__VALUE__) == LL_RCC_HSE_PREDIV2_DIV_2) || \
142 ((__VALUE__) == LL_RCC_HSE_PREDIV2_DIV_3) || ((__VALUE__) == LL_RCC_HSE_PREDIV2_DIV_4) || \
143 ((__VALUE__) == LL_RCC_HSE_PREDIV2_DIV_5) || ((__VALUE__) == LL_RCC_HSE_PREDIV2_DIV_6) || \
144 ((__VALUE__) == LL_RCC_HSE_PREDIV2_DIV_7) || ((__VALUE__) == LL_RCC_HSE_PREDIV2_DIV_8) || \
145 ((__VALUE__) == LL_RCC_HSE_PREDIV2_DIV_9) || ((__VALUE__) == LL_RCC_HSE_PREDIV2_DIV_10) || \
146 ((__VALUE__) == LL_RCC_HSE_PREDIV2_DIV_11) || ((__VALUE__) == LL_RCC_HSE_PREDIV2_DIV_12) || \
147 ((__VALUE__) == LL_RCC_HSE_PREDIV2_DIV_13) || ((__VALUE__) == LL_RCC_HSE_PREDIV2_DIV_14) || \
148 ((__VALUE__) == LL_RCC_HSE_PREDIV2_DIV_15) || ((__VALUE__) == LL_RCC_HSE_PREDIV2_DIV_16))
149
150 #define IS_LL_UTILS_PLL2_FREQUENCY(__VALUE__) ((__VALUE__) <= UTILS_PLL2_OUTPUT_MAX)
151 #endif /* RCC_PLL2_SUPPORT */
152
153 #define IS_LL_UTILS_HSE_BYPASS(__STATE__) (((__STATE__) == LL_UTILS_HSEBYPASS_ON) \
154 || ((__STATE__) == LL_UTILS_HSEBYPASS_OFF))
155
156 #define IS_LL_UTILS_HSE_FREQUENCY(__FREQUENCY__) (((__FREQUENCY__) >= UTILS_HSE_FREQUENCY_MIN) && ((__FREQUENCY__) <= UTILS_HSE_FREQUENCY_MAX))
157 /**
158 * @}
159 */
160 /* Private function prototypes -----------------------------------------------*/
161 /** @defgroup UTILS_LL_Private_Functions UTILS Private functions
162 * @{
163 */
164 static uint32_t UTILS_GetPLLOutputFrequency(uint32_t PLL_InputFrequency,
165 LL_UTILS_PLLInitTypeDef *UTILS_PLLInitStruct);
166 static ErrorStatus UTILS_PLL_HSE_ConfigSystemClock(uint32_t PLL_InputFrequency, uint32_t HSEBypass,
167 LL_UTILS_PLLInitTypeDef *UTILS_PLLInitStruct,
168 LL_UTILS_ClkInitTypeDef *UTILS_ClkInitStruct);
169 #if defined(RCC_PLL2_SUPPORT)
170 static uint32_t UTILS_GetPLL2OutputFrequency(uint32_t PLL2_InputFrequency,
171 LL_UTILS_PLLInitTypeDef *UTILS_PLL2InitStruct);
172 #endif /* RCC_PLL2_SUPPORT */
173 static ErrorStatus UTILS_EnablePLLAndSwitchSystem(uint32_t SYSCLK_Frequency, LL_UTILS_ClkInitTypeDef *UTILS_ClkInitStruct);
174 static ErrorStatus UTILS_PLL_IsBusy(void);
175 /**
176 * @}
177 */
178
179 /* Exported functions --------------------------------------------------------*/
180 /** @addtogroup UTILS_LL_Exported_Functions
181 * @{
182 */
183
184 /** @addtogroup UTILS_LL_EF_DELAY
185 * @{
186 */
187
188 /**
189 * @brief This function configures the Cortex-M SysTick source to have 1ms time base.
190 * @note When a RTOS is used, it is recommended to avoid changing the Systick
191 * configuration by calling this function, for a delay use rather osDelay RTOS service.
192 * @param HCLKFrequency HCLK frequency in Hz
193 * @note HCLK frequency can be calculated thanks to RCC helper macro or function @ref LL_RCC_GetSystemClocksFreq
194 * @retval None
195 */
LL_Init1msTick(uint32_t HCLKFrequency)196 void LL_Init1msTick(uint32_t HCLKFrequency)
197 {
198 /* Use frequency provided in argument */
199 LL_InitTick(HCLKFrequency, 1000U);
200 }
201
202 /**
203 * @brief This function provides accurate delay (in milliseconds) based
204 * on SysTick counter flag
205 * @note When a RTOS is used, it is recommended to avoid using blocking delay
206 * and use rather osDelay service.
207 * @note To respect 1ms timebase, user should call @ref LL_Init1msTick function which
208 * will configure Systick to 1ms
209 * @param Delay specifies the delay time length, in milliseconds.
210 * @retval None
211 */
LL_mDelay(uint32_t Delay)212 void LL_mDelay(uint32_t Delay)
213 {
214 __IO uint32_t tmp = SysTick->CTRL; /* Clear the COUNTFLAG first */
215 /* Add this code to indicate that local variable is not used */
216 ((void)tmp);
217
218 /* Add a period to guaranty minimum wait */
219 if (Delay < LL_MAX_DELAY)
220 {
221 Delay++;
222 }
223
224 while (Delay)
225 {
226 if ((SysTick->CTRL & SysTick_CTRL_COUNTFLAG_Msk) != 0U)
227 {
228 Delay--;
229 }
230 }
231 }
232
233 /**
234 * @}
235 */
236
237 /** @addtogroup UTILS_EF_SYSTEM
238 * @brief System Configuration functions
239 *
240 @verbatim
241 ===============================================================================
242 ##### System Configuration functions #####
243 ===============================================================================
244 [..]
245 System, AHB and APB buses clocks configuration
246
247 (+) The maximum frequency of the SYSCLK, HCLK, PCLK1 and PCLK2 is RCC_MAX_FREQUENCY Hz.
248 @endverbatim
249 @internal
250 Depending on the SYSCLK frequency, the flash latency should be adapted accordingly:
251 (++) +-----------------------------------------------+
252 (++) | Latency | SYSCLK clock frequency (MHz) |
253 (++) |---------------|-------------------------------|
254 (++) |0WS(1CPU cycle)| 0 < SYSCLK <= 24 |
255 (++) |---------------|-------------------------------|
256 (++) |1WS(2CPU cycle)| 24 < SYSCLK <= 48 |
257 (++) |---------------|-------------------------------|
258 (++) |2WS(3CPU cycle)| 48 < SYSCLK <= 72 |
259 (++) +-----------------------------------------------+
260 @endinternal
261 * @{
262 */
263
264 /**
265 * @brief This function sets directly SystemCoreClock CMSIS variable.
266 * @note Variable can be calculated also through SystemCoreClockUpdate function.
267 * @param HCLKFrequency HCLK frequency in Hz (can be calculated thanks to RCC helper macro)
268 * @retval None
269 */
LL_SetSystemCoreClock(uint32_t HCLKFrequency)270 void LL_SetSystemCoreClock(uint32_t HCLKFrequency)
271 {
272 /* HCLK clock frequency */
273 SystemCoreClock = HCLKFrequency;
274 }
275
276 /**
277 * @brief Update number of Flash wait states in line with new frequency and current
278 voltage range.
279 * @param Frequency SYSCLK frequency
280 * @retval An ErrorStatus enumeration value:
281 * - SUCCESS: Latency has been modified
282 * - ERROR: Latency cannot be modified
283 */
284 #if defined(FLASH_ACR_LATENCY)
LL_SetFlashLatency(uint32_t Frequency)285 ErrorStatus LL_SetFlashLatency(uint32_t Frequency)
286 {
287 uint32_t timeout;
288 uint32_t getlatency;
289 uint32_t latency = LL_FLASH_LATENCY_0; /* default value 0WS */
290 ErrorStatus status = SUCCESS;
291
292 /* Frequency cannot be equal to 0 */
293 if (Frequency == 0U)
294 {
295 status = ERROR;
296 }
297 else
298 {
299 if (Frequency > UTILS_LATENCY2_FREQ)
300 {
301 /* 48 < SYSCLK <= 72 => 2WS (3 CPU cycles) */
302 latency = LL_FLASH_LATENCY_2;
303 }
304 else
305 {
306 if (Frequency > UTILS_LATENCY1_FREQ)
307 {
308 /* 24 < SYSCLK <= 48 => 1WS (2 CPU cycles) */
309 latency = LL_FLASH_LATENCY_1;
310 }
311 else
312 {
313 /* else SYSCLK < 24MHz default LL_FLASH_LATENCY_0 0WS */
314 latency = LL_FLASH_LATENCY_0;
315 }
316 }
317
318 if (status != ERROR)
319 {
320 LL_FLASH_SetLatency(latency);
321
322 /* Check that the new number of wait states is taken into account to access the Flash
323 memory by reading the FLASH_ACR register */
324 timeout = 2;
325 do
326 {
327 /* Wait for Flash latency to be updated */
328 getlatency = LL_FLASH_GetLatency();
329 timeout--;
330 }
331 while ((getlatency != latency) && (timeout > 0));
332
333 if (getlatency != latency)
334 {
335 status = ERROR;
336 }
337 else
338 {
339 status = SUCCESS;
340 }
341 }
342 }
343
344 return status;
345 }
346 #endif /* FLASH_ACR_LATENCY */
347
348 /**
349 * @brief This function configures system clock with HSI as clock source of the PLL
350 * @note The application need to ensure that PLL is disabled.
351 * @note Function is based on the following formula:
352 * - PLL output frequency = ((HSI frequency / PREDIV) * PLLMUL)
353 * - PREDIV: Set to 2 for few devices
354 * - PLLMUL: The application software must set correctly the PLL multiplication factor to
355 * not exceed 72MHz
356 * @note FLASH latency can be modified through this function.
357 * @param UTILS_PLLInitStruct pointer to a @ref LL_UTILS_PLLInitTypeDef structure that contains
358 * the configuration information for the PLL.
359 * @param UTILS_ClkInitStruct pointer to a @ref LL_UTILS_ClkInitTypeDef structure that contains
360 * the configuration information for the BUS prescalers.
361 * @retval An ErrorStatus enumeration value:
362 * - SUCCESS: Max frequency configuration done
363 * - ERROR: Max frequency configuration not done
364 */
LL_PLL_ConfigSystemClock_HSI(LL_UTILS_PLLInitTypeDef * UTILS_PLLInitStruct,LL_UTILS_ClkInitTypeDef * UTILS_ClkInitStruct)365 ErrorStatus LL_PLL_ConfigSystemClock_HSI(LL_UTILS_PLLInitTypeDef *UTILS_PLLInitStruct,
366 LL_UTILS_ClkInitTypeDef *UTILS_ClkInitStruct)
367 {
368 ErrorStatus status = SUCCESS;
369 uint32_t pllfreq = 0U;
370
371 /* Check if one of the PLL is enabled */
372 if (UTILS_PLL_IsBusy() == SUCCESS)
373 {
374 #if defined(RCC_PLLSRC_PREDIV1_SUPPORT)
375 /* Check PREDIV value */
376 assert_param(IS_LL_UTILS_PREDIV_VALUE(UTILS_PLLInitStruct->PLLDiv));
377 #else
378 /* Force PREDIV value to 2 */
379 UTILS_PLLInitStruct->Prediv = LL_RCC_PREDIV_DIV_2;
380 #endif /*RCC_PLLSRC_PREDIV1_SUPPORT*/
381 /* Calculate the new PLL output frequency */
382 pllfreq = UTILS_GetPLLOutputFrequency(HSI_VALUE, UTILS_PLLInitStruct);
383
384 /* Enable HSI if not enabled */
385 if (LL_RCC_HSI_IsReady() != 1U)
386 {
387 LL_RCC_HSI_Enable();
388 while (LL_RCC_HSI_IsReady() != 1U)
389 {
390 /* Wait for HSI ready */
391 }
392 }
393
394 /* Configure PLL */
395 LL_RCC_PLL_ConfigDomain_SYS(LL_RCC_PLLSOURCE_HSI_DIV_2, UTILS_PLLInitStruct->PLLMul);
396
397 /* Enable PLL and switch system clock to PLL */
398 status = UTILS_EnablePLLAndSwitchSystem(pllfreq, UTILS_ClkInitStruct);
399 }
400 else
401 {
402 /* Current PLL configuration cannot be modified */
403 status = ERROR;
404 }
405
406 return status;
407 }
408
409 /**
410 * @brief This function configures system clock with HSE as clock source of the PLL
411 * @note The application need to ensure that PLL is disabled.
412 * @note Function is based on the following formula:
413 * - PLL output frequency = ((HSI frequency / PREDIV) * PLLMUL)
414 * - PREDIV: Set to 2 for few devices
415 * - PLLMUL: The application software must set correctly the PLL multiplication factor to
416 * not exceed @ref UTILS_PLL_OUTPUT_MAX
417 * @note FLASH latency can be modified through this function.
418 * @param HSEFrequency Value between Min_Data = RCC_HSE_MIN and Max_Data = RCC_HSE_MAX
419 * @param HSEBypass This parameter can be one of the following values:
420 * @arg @ref LL_UTILS_HSEBYPASS_ON
421 * @arg @ref LL_UTILS_HSEBYPASS_OFF
422 * @param UTILS_PLLInitStruct pointer to a @ref LL_UTILS_PLLInitTypeDef structure that contains
423 * the configuration information for the PLL.
424 * @param UTILS_ClkInitStruct pointer to a @ref LL_UTILS_ClkInitTypeDef structure that contains
425 * the configuration information for the BUS prescalers.
426 * @retval An ErrorStatus enumeration value:
427 * - SUCCESS: Max frequency configuration done
428 * - ERROR: Max frequency configuration not done
429 */
LL_PLL_ConfigSystemClock_HSE(uint32_t HSEFrequency,uint32_t HSEBypass,LL_UTILS_PLLInitTypeDef * UTILS_PLLInitStruct,LL_UTILS_ClkInitTypeDef * UTILS_ClkInitStruct)430 ErrorStatus LL_PLL_ConfigSystemClock_HSE(uint32_t HSEFrequency, uint32_t HSEBypass,
431 LL_UTILS_PLLInitTypeDef *UTILS_PLLInitStruct, LL_UTILS_ClkInitTypeDef *UTILS_ClkInitStruct)
432 {
433 ErrorStatus status = SUCCESS;
434 uint32_t pllfrequency = 0U;
435
436 /* Check the parameters */
437 assert_param(IS_LL_UTILS_HSE_FREQUENCY(HSEFrequency));
438 assert_param(IS_LL_UTILS_HSE_BYPASS(HSEBypass));
439 assert_param(IS_LL_UTILS_PREDIV_VALUE(UTILS_PLLInitStruct->Prediv));
440
441 /* Calculate the new PLL output frequency */
442 pllfrequency = UTILS_GetPLLOutputFrequency(HSEFrequency, UTILS_PLLInitStruct);
443
444 /* Enable HSE if not enabled */
445 status = UTILS_PLL_HSE_ConfigSystemClock(HSEFrequency, HSEBypass, UTILS_PLLInitStruct, UTILS_ClkInitStruct);
446
447 /* Check if HSE is not enabled*/
448 if (status == SUCCESS)
449 {
450 /* Configure PLL */
451 LL_RCC_PLL_ConfigDomain_SYS((LL_RCC_PLLSOURCE_HSE | UTILS_PLLInitStruct->Prediv), UTILS_PLLInitStruct->PLLMul);
452
453 /* Enable PLL and switch system clock to PLL */
454 status = UTILS_EnablePLLAndSwitchSystem(pllfrequency, UTILS_ClkInitStruct);
455 }
456
457 return status;
458 }
459
460 #if defined(RCC_PLL2_SUPPORT)
461 /**
462 * @brief This function configures system clock with HSE as clock source of the PLL, via PLL2
463 * @note The application need to ensure that PLL and PLL2 are disabled.
464 * @note Function is based on the following formula:
465 * - PLL output frequency = ((((HSE frequency / PREDIV2) * PLL2MUL) / PREDIV) * PLLMUL)
466 * - PREDIV, PLLMUL, PREDIV2, PLL2MUL: The application software must set correctly the
467 * PLL multiplication factor to not exceed @ref UTILS_PLL_OUTPUT_MAX
468 * @note FLASH latency can be modified through this function.
469 * @param HSEFrequency Value between Min_Data = RCC_HSE_MIN and Max_Data = RCC_HSE_MAX
470 * @param HSEBypass This parameter can be one of the following values:
471 * @arg @ref LL_UTILS_HSEBYPASS_ON
472 * @arg @ref LL_UTILS_HSEBYPASS_OFF
473 * @param UTILS_PLLInitStruct pointer to a @ref LL_UTILS_PLLInitTypeDef structure that contains
474 * the configuration information for the PLL.
475 * @param UTILS_PLL2InitStruct pointer to a @ref LL_UTILS_PLLInitTypeDef structure that contains
476 * the configuration information for the PLL2.
477 * @param UTILS_ClkInitStruct pointer to a @ref LL_UTILS_ClkInitTypeDef structure that contains
478 * the configuration information for the BUS prescalers.
479 * @retval An ErrorStatus enumeration value:
480 * - SUCCESS: Max frequency configuration done
481 * - ERROR: Max frequency configuration not done
482 */
LL_PLL_ConfigSystemClock_PLL2(uint32_t HSEFrequency,uint32_t HSEBypass,LL_UTILS_PLLInitTypeDef * UTILS_PLLInitStruct,LL_UTILS_PLLInitTypeDef * UTILS_PLL2InitStruct,LL_UTILS_ClkInitTypeDef * UTILS_ClkInitStruct)483 ErrorStatus LL_PLL_ConfigSystemClock_PLL2(uint32_t HSEFrequency, uint32_t HSEBypass,
484 LL_UTILS_PLLInitTypeDef *UTILS_PLLInitStruct,
485 LL_UTILS_PLLInitTypeDef *UTILS_PLL2InitStruct,
486 LL_UTILS_ClkInitTypeDef *UTILS_ClkInitStruct)
487 {
488 ErrorStatus status = SUCCESS;
489 uint32_t pllfrequency = 0U;
490
491 /* Check the parameters */
492 assert_param(IS_LL_UTILS_HSE_FREQUENCY(HSEFrequency));
493 assert_param(IS_LL_UTILS_HSE_BYPASS(HSEBypass));
494 assert_param(IS_LL_UTILS_PREDIV_VALUE(UTILS_PLLInitStruct->Prediv));
495 assert_param(IS_LL_UTILS_PREDIV2_VALUE(UTILS_PLL2InitStruct->Prediv));
496
497 /* Calculate the new PLL output frequency */
498 pllfrequency = UTILS_GetPLLOutputFrequency(HSEFrequency, UTILS_PLLInitStruct);
499
500 /* Enable HSE if not enabled */
501 status = UTILS_PLL_HSE_ConfigSystemClock(HSEFrequency, HSEBypass, UTILS_PLLInitStruct, UTILS_ClkInitStruct);
502
503 /* Check if HSE is not enabled*/
504 if (status == SUCCESS)
505 {
506 /* Configure PLL */
507 LL_RCC_PLL_ConfigDomain_PLL2(UTILS_PLL2InitStruct->Prediv, UTILS_PLL2InitStruct->PLLMul);
508 LL_RCC_PLL_ConfigDomain_SYS((LL_RCC_PLLSOURCE_PLL2 | UTILS_PLLInitStruct->Prediv), UTILS_PLLInitStruct->PLLMul);
509
510 /* Calculate the new PLL output frequency */
511 pllfrequency = UTILS_GetPLL2OutputFrequency(pllfrequency, UTILS_PLL2InitStruct);
512
513 /* Enable PLL and switch system clock to PLL */
514 status = UTILS_EnablePLLAndSwitchSystem(pllfrequency, UTILS_ClkInitStruct);
515 }
516
517 return status;
518 }
519 #endif /* RCC_PLL2_SUPPORT */
520
521 /**
522 * @}
523 */
524
525 /**
526 * @}
527 */
528
529 /** @addtogroup UTILS_LL_Private_Functions
530 * @{
531 */
532 /**
533 * @brief Function to check that PLL can be modified
534 * @param PLL_InputFrequency PLL input frequency (in Hz)
535 * @param UTILS_PLLInitStruct pointer to a @ref LL_UTILS_PLLInitTypeDef structure that contains
536 * the configuration information for the PLL.
537 * @retval PLL output frequency (in Hz)
538 */
UTILS_GetPLLOutputFrequency(uint32_t PLL_InputFrequency,LL_UTILS_PLLInitTypeDef * UTILS_PLLInitStruct)539 static uint32_t UTILS_GetPLLOutputFrequency(uint32_t PLL_InputFrequency, LL_UTILS_PLLInitTypeDef *UTILS_PLLInitStruct)
540 {
541 uint32_t pllfreq = 0U;
542
543 /* Check the parameters */
544 assert_param(IS_LL_UTILS_PLLMUL_VALUE(UTILS_PLLInitStruct->PLLMul));
545
546 /* Check different PLL parameters according to RM */
547 #if defined (RCC_CFGR2_PREDIV1)
548 pllfreq = __LL_RCC_CALC_PLLCLK_FREQ(PLL_InputFrequency / (UTILS_PLLInitStruct->Prediv + 1U), UTILS_PLLInitStruct->PLLMul);
549 #else
550 pllfreq = __LL_RCC_CALC_PLLCLK_FREQ(PLL_InputFrequency / ((UTILS_PLLInitStruct->Prediv >> RCC_CFGR_PLLXTPRE_Pos) + 1U), UTILS_PLLInitStruct->PLLMul);
551 #endif /*RCC_CFGR2_PREDIV1SRC*/
552 assert_param(IS_LL_UTILS_PLL_FREQUENCY(pllfreq));
553
554 return pllfreq;
555 }
556
557 /**
558 * @brief This function enable the HSE when it is used by PLL or PLL2
559 * @note The application need to ensure that PLL is disabled.
560 * @param HSEFrequency Value between Min_Data = RCC_HSE_MIN and Max_Data = RCC_HSE_MAX
561 * @param HSEBypass This parameter can be one of the following values:
562 * @arg @ref LL_UTILS_HSEBYPASS_ON
563 * @arg @ref LL_UTILS_HSEBYPASS_OFF
564 * @param UTILS_PLLInitStruct pointer to a @ref LL_UTILS_PLLInitTypeDef structure that contains
565 * the configuration information for the PLL.
566 * @param UTILS_ClkInitStruct pointer to a @ref LL_UTILS_ClkInitTypeDef structure that contains
567 * the configuration information for the BUS prescalers.
568 * @retval An ErrorStatus enumeration value:
569 * - SUCCESS: HSE configuration done
570 * - ERROR: HSE configuration not done
571 */
UTILS_PLL_HSE_ConfigSystemClock(uint32_t PLL_InputFrequency,uint32_t HSEBypass,LL_UTILS_PLLInitTypeDef * UTILS_PLLInitStruct,LL_UTILS_ClkInitTypeDef * UTILS_ClkInitStruct)572 static ErrorStatus UTILS_PLL_HSE_ConfigSystemClock(uint32_t PLL_InputFrequency, uint32_t HSEBypass,
573 LL_UTILS_PLLInitTypeDef *UTILS_PLLInitStruct,
574 LL_UTILS_ClkInitTypeDef *UTILS_ClkInitStruct)
575 {
576 ErrorStatus status = SUCCESS;
577
578 /* Check if one of the PLL is enabled */
579 if (UTILS_PLL_IsBusy() == SUCCESS)
580 {
581 /* Enable HSE if not enabled */
582 if (LL_RCC_HSE_IsReady() != 1U)
583 {
584 /* Check if need to enable HSE bypass feature or not */
585 if (HSEBypass == LL_UTILS_HSEBYPASS_ON)
586 {
587 LL_RCC_HSE_EnableBypass();
588 }
589 else
590 {
591 LL_RCC_HSE_DisableBypass();
592 }
593
594 /* Enable HSE */
595 LL_RCC_HSE_Enable();
596 while (LL_RCC_HSE_IsReady() != 1U)
597 {
598 /* Wait for HSE ready */
599 }
600 }
601 }
602 else
603 {
604 /* Current PLL configuration cannot be modified */
605 status = ERROR;
606 }
607
608 return status;
609 }
610
611 #if defined(RCC_PLL2_SUPPORT)
612 /**
613 * @brief Function to check that PLL2 can be modified
614 * @param PLL2_InputFrequency PLL2 input frequency (in Hz)
615 * @param UTILS_PLL2InitStruct pointer to a @ref LL_UTILS_PLLInitTypeDef structure that contains
616 * the configuration information for the PLL.
617 * @retval PLL2 output frequency (in Hz)
618 */
UTILS_GetPLL2OutputFrequency(uint32_t PLL2_InputFrequency,LL_UTILS_PLLInitTypeDef * UTILS_PLL2InitStruct)619 static uint32_t UTILS_GetPLL2OutputFrequency(uint32_t PLL2_InputFrequency, LL_UTILS_PLLInitTypeDef *UTILS_PLL2InitStruct)
620 {
621 uint32_t pll2freq = 0U;
622
623 /* Check the parameters */
624 assert_param(IS_LL_UTILS_PLL2MUL_VALUE(UTILS_PLL2InitStruct->PLLMul));
625 assert_param(IS_LL_UTILS_PREDIV2_VALUE(UTILS_PLL2InitStruct->Prediv));
626
627 /* Check different PLL2 parameters according to RM */
628 pll2freq = __LL_RCC_CALC_PLL2CLK_FREQ(PLL2_InputFrequency, UTILS_PLL2InitStruct->PLLMul, UTILS_PLL2InitStruct->Prediv);
629 assert_param(IS_LL_UTILS_PLL2_FREQUENCY(pll2freq));
630
631 return pll2freq;
632 }
633 #endif /* RCC_PLL2_SUPPORT */
634
635 /**
636 * @brief Function to check that PLL can be modified
637 * @retval An ErrorStatus enumeration value:
638 * - SUCCESS: PLL modification can be done
639 * - ERROR: PLL is busy
640 */
UTILS_PLL_IsBusy(void)641 static ErrorStatus UTILS_PLL_IsBusy(void)
642 {
643 ErrorStatus status = SUCCESS;
644
645 /* Check if PLL is busy*/
646 if (LL_RCC_PLL_IsReady() != 0U)
647 {
648 /* PLL configuration cannot be modified */
649 status = ERROR;
650 }
651 #if defined(RCC_PLL2_SUPPORT)
652 /* Check if PLL2 is busy*/
653 if (LL_RCC_PLL2_IsReady() != 0U)
654 {
655 /* PLL2 configuration cannot be modified */
656 status = ERROR;
657 }
658 #endif /* RCC_PLL2_SUPPORT */
659
660 #if defined(RCC_PLLI2S_SUPPORT)
661 /* Check if PLLI2S is busy*/
662 if (LL_RCC_PLLI2S_IsReady() != 0U)
663 {
664 /* PLLI2S configuration cannot be modified */
665 status = ERROR;
666 }
667 #endif /* RCC_PLLI2S_SUPPORT */
668
669 return status;
670 }
671
672 /**
673 * @brief Function to enable PLL and switch system clock to PLL
674 * @param SYSCLK_Frequency SYSCLK frequency
675 * @param UTILS_ClkInitStruct pointer to a @ref LL_UTILS_ClkInitTypeDef structure that contains
676 * the configuration information for the BUS prescalers.
677 * @retval An ErrorStatus enumeration value:
678 * - SUCCESS: No problem to switch system to PLL
679 * - ERROR: Problem to switch system to PLL
680 */
UTILS_EnablePLLAndSwitchSystem(uint32_t SYSCLK_Frequency,LL_UTILS_ClkInitTypeDef * UTILS_ClkInitStruct)681 static ErrorStatus UTILS_EnablePLLAndSwitchSystem(uint32_t SYSCLK_Frequency, LL_UTILS_ClkInitTypeDef *UTILS_ClkInitStruct)
682 {
683 ErrorStatus status = SUCCESS;
684 #if defined(FLASH_ACR_LATENCY)
685 uint32_t sysclk_frequency_current = 0U;
686 #endif /* FLASH_ACR_LATENCY */
687
688 assert_param(IS_LL_UTILS_SYSCLK_DIV(UTILS_ClkInitStruct->AHBCLKDivider));
689 assert_param(IS_LL_UTILS_APB1_DIV(UTILS_ClkInitStruct->APB1CLKDivider));
690 assert_param(IS_LL_UTILS_APB2_DIV(UTILS_ClkInitStruct->APB2CLKDivider));
691
692 #if defined(FLASH_ACR_LATENCY)
693 /* Calculate current SYSCLK frequency */
694 sysclk_frequency_current = (SystemCoreClock << AHBPrescTable[LL_RCC_GetAHBPrescaler() >> RCC_CFGR_HPRE_Pos]);
695 #endif /* FLASH_ACR_LATENCY */
696
697 /* Increasing the number of wait states because of higher CPU frequency */
698 #if defined (FLASH_ACR_LATENCY)
699 if (sysclk_frequency_current < SYSCLK_Frequency)
700 {
701 /* Set FLASH latency to highest latency */
702 status = LL_SetFlashLatency(SYSCLK_Frequency);
703 }
704 #endif /* FLASH_ACR_LATENCY */
705
706 /* Update system clock configuration */
707 if (status == SUCCESS)
708 {
709 #if defined(RCC_PLL2_SUPPORT)
710 if (LL_RCC_PLL_GetMainSource() != LL_RCC_PLLSOURCE_HSI_DIV_2)
711 {
712 /* Enable PLL2 */
713 LL_RCC_PLL2_Enable();
714 while (LL_RCC_PLL2_IsReady() != 1U)
715 {
716 /* Wait for PLL2 ready */
717 }
718 }
719 #endif /* RCC_PLL2_SUPPORT */
720 /* Enable PLL */
721 LL_RCC_PLL_Enable();
722 while (LL_RCC_PLL_IsReady() != 1U)
723 {
724 /* Wait for PLL ready */
725 }
726
727 /* Sysclk activation on the main PLL */
728 LL_RCC_SetAHBPrescaler(UTILS_ClkInitStruct->AHBCLKDivider);
729 LL_RCC_SetSysClkSource(LL_RCC_SYS_CLKSOURCE_PLL);
730 while (LL_RCC_GetSysClkSource() != LL_RCC_SYS_CLKSOURCE_STATUS_PLL)
731 {
732 /* Wait for system clock switch to PLL */
733 }
734
735 /* Set APB1 & APB2 prescaler*/
736 LL_RCC_SetAPB1Prescaler(UTILS_ClkInitStruct->APB1CLKDivider);
737 LL_RCC_SetAPB2Prescaler(UTILS_ClkInitStruct->APB2CLKDivider);
738 }
739
740 /* Decreasing the number of wait states because of lower CPU frequency */
741 #if defined (FLASH_ACR_LATENCY)
742 if (sysclk_frequency_current > SYSCLK_Frequency)
743 {
744 /* Set FLASH latency to lowest latency */
745 status = LL_SetFlashLatency(SYSCLK_Frequency);
746 }
747 #endif /* FLASH_ACR_LATENCY */
748
749 /* Update SystemCoreClock variable */
750 if (status == SUCCESS)
751 {
752 LL_SetSystemCoreClock(__LL_RCC_CALC_HCLK_FREQ(SYSCLK_Frequency, UTILS_ClkInitStruct->AHBCLKDivider));
753 }
754
755 return status;
756 }
757
758 /**
759 * @}
760 */
761
762 /**
763 * @}
764 */
765
766 /**
767 * @}
768 */
769
770 /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
771