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