Merge pull request #11189 from klutvott123/move-telemetry-displayport-init
[betaflight.git] / lib / main / STM32G4 / Drivers / STM32G4xx_HAL_Driver / Src / stm32g4xx_ll_utils.c
blob0f29ff67cf8d9ad527380017601b094797cac198
1 /**
2 ******************************************************************************
3 * @file stm32g4xx_ll_utils.c
4 * @author MCD Application Team
5 * @brief UTILS LL module driver.
6 ******************************************************************************
7 * @attention
9 * <h2><center>&copy; Copyright (c) 2017 STMicroelectronics.
10 * All rights reserved.</center></h2>
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
17 ******************************************************************************
20 /* Includes ------------------------------------------------------------------*/
21 #include "stm32g4xx_ll_utils.h"
22 #include "stm32g4xx_ll_rcc.h"
23 #include "stm32g4xx_ll_system.h"
24 #include "stm32g4xx_ll_pwr.h"
25 #ifdef USE_FULL_ASSERT
26 #include "stm32_assert.h"
27 #else
28 #define assert_param(expr) ((void)0U)
29 #endif /* USE_FULL_ASSERT */
31 /** @addtogroup STM32G4xx_LL_Driver
32 * @{
35 /** @addtogroup UTILS_LL
36 * @{
39 /* Private types -------------------------------------------------------------*/
40 /* Private variables ---------------------------------------------------------*/
41 /* Private constants ---------------------------------------------------------*/
42 /** @addtogroup UTILS_LL_Private_Constants
43 * @{
45 #define UTILS_MAX_FREQUENCY_SCALE1 170000000U /*!< Maximum frequency for system clock at power scale1, in Hz */
46 #define UTILS_MAX_FREQUENCY_SCALE2 26000000U /*!< Maximum frequency for system clock at power scale2, in Hz */
48 /* Defines used for PLL range */
49 #define UTILS_PLLVCO_INPUT_MIN 2660000U /*!< Frequency min for PLLVCO input, in Hz */
50 #define UTILS_PLLVCO_INPUT_MAX 8000000U /*!< Frequency max for PLLVCO input, in Hz */
51 #define UTILS_PLLVCO_OUTPUT_MIN 64000000U /*!< Frequency min for PLLVCO output, in Hz */
52 #define UTILS_PLLVCO_OUTPUT_MAX 344000000U /*!< Frequency max for PLLVCO output, in Hz */
54 /* Defines used for HSE range */
55 #define UTILS_HSE_FREQUENCY_MIN 4000000U /*!< Frequency min for HSE frequency, in Hz */
56 #define UTILS_HSE_FREQUENCY_MAX 48000000U /*!< Frequency max for HSE frequency, in Hz */
58 /* Defines used for FLASH latency according to HCLK Frequency */
59 #define UTILS_SCALE1_LATENCY1_FREQ 20000000U /*!< HCLK frequency to set FLASH latency 1 in power scale 1 */
60 #define UTILS_SCALE1_LATENCY2_FREQ 40000000U /*!< HCLK frequency to set FLASH latency 2 in power scale 1 */
61 #define UTILS_SCALE1_LATENCY3_FREQ 60000000U /*!< HCLK frequency to set FLASH latency 3 in power scale 1 */
62 #define UTILS_SCALE1_LATENCY4_FREQ 80000000U /*!< HCLK frequency to set FLASH latency 4 in power scale 1 */
63 #define UTILS_SCALE1_LATENCY5_FREQ 100000000U /*!< HCLK frequency to set FLASH latency 5 in power scale 1 */
64 #define UTILS_SCALE1_LATENCY6_FREQ 120000000U /*!< HCLK frequency to set FLASH latency 6 in power scale 1 */
65 #define UTILS_SCALE1_LATENCY7_FREQ 140000000U /*!< HCLK frequency to set FLASH latency 7 in power scale 1 */
66 #define UTILS_SCALE1_LATENCY8_FREQ 160000000U /*!< HCLK frequency to set FLASH latency 8 in power scale 1 */
67 #define UTILS_SCALE1_LATENCY9_FREQ 170000000U /*!< HCLK frequency to set FLASH latency 9 in power scale 1 */
68 #define UTILS_SCALE2_LATENCY1_FREQ 8000000U /*!< HCLK frequency to set FLASH latency 1 in power scale 2 */
69 #define UTILS_SCALE2_LATENCY2_FREQ 16000000U /*!< HCLK frequency to set FLASH latency 2 in power scale 2 */
70 #define UTILS_SCALE2_LATENCY3_FREQ 26000000U /*!< HCLK frequency to set FLASH latency 2 in power scale 2 */
71 /**
72 * @}
75 /* Private macros ------------------------------------------------------------*/
76 /** @addtogroup UTILS_LL_Private_Macros
77 * @{
79 #define IS_LL_UTILS_SYSCLK_DIV(__VALUE__) (((__VALUE__) == LL_RCC_SYSCLK_DIV_1) \
80 || ((__VALUE__) == LL_RCC_SYSCLK_DIV_2) \
81 || ((__VALUE__) == LL_RCC_SYSCLK_DIV_4) \
82 || ((__VALUE__) == LL_RCC_SYSCLK_DIV_8) \
83 || ((__VALUE__) == LL_RCC_SYSCLK_DIV_16) \
84 || ((__VALUE__) == LL_RCC_SYSCLK_DIV_64) \
85 || ((__VALUE__) == LL_RCC_SYSCLK_DIV_128) \
86 || ((__VALUE__) == LL_RCC_SYSCLK_DIV_256) \
87 || ((__VALUE__) == LL_RCC_SYSCLK_DIV_512))
89 #define IS_LL_UTILS_APB1_DIV(__VALUE__) (((__VALUE__) == LL_RCC_APB1_DIV_1) \
90 || ((__VALUE__) == LL_RCC_APB1_DIV_2) \
91 || ((__VALUE__) == LL_RCC_APB1_DIV_4) \
92 || ((__VALUE__) == LL_RCC_APB1_DIV_8) \
93 || ((__VALUE__) == LL_RCC_APB1_DIV_16))
95 #define IS_LL_UTILS_APB2_DIV(__VALUE__) (((__VALUE__) == LL_RCC_APB2_DIV_1) \
96 || ((__VALUE__) == LL_RCC_APB2_DIV_2) \
97 || ((__VALUE__) == LL_RCC_APB2_DIV_4) \
98 || ((__VALUE__) == LL_RCC_APB2_DIV_8) \
99 || ((__VALUE__) == LL_RCC_APB2_DIV_16))
101 #define IS_LL_UTILS_PLLM_VALUE(__VALUE__) (((__VALUE__) == LL_RCC_PLLM_DIV_1) \
102 || ((__VALUE__) == LL_RCC_PLLM_DIV_2) \
103 || ((__VALUE__) == LL_RCC_PLLM_DIV_3) \
104 || ((__VALUE__) == LL_RCC_PLLM_DIV_4) \
105 || ((__VALUE__) == LL_RCC_PLLM_DIV_5) \
106 || ((__VALUE__) == LL_RCC_PLLM_DIV_6) \
107 || ((__VALUE__) == LL_RCC_PLLM_DIV_7) \
108 || ((__VALUE__) == LL_RCC_PLLM_DIV_8) \
109 || ((__VALUE__) == LL_RCC_PLLM_DIV_9) \
110 || ((__VALUE__) == LL_RCC_PLLM_DIV_10) \
111 || ((__VALUE__) == LL_RCC_PLLM_DIV_11) \
112 || ((__VALUE__) == LL_RCC_PLLM_DIV_12) \
113 || ((__VALUE__) == LL_RCC_PLLM_DIV_13) \
114 || ((__VALUE__) == LL_RCC_PLLM_DIV_14) \
115 || ((__VALUE__) == LL_RCC_PLLM_DIV_15) \
116 || ((__VALUE__) == LL_RCC_PLLM_DIV_16))
118 #define IS_LL_UTILS_PLLN_VALUE(__VALUE__) ((8U <= (__VALUE__)) && ((__VALUE__) <= 127U))
120 #define IS_LL_UTILS_PLLR_VALUE(__VALUE__) (((__VALUE__) == LL_RCC_PLLR_DIV_2) \
121 || ((__VALUE__) == LL_RCC_PLLR_DIV_4) \
122 || ((__VALUE__) == LL_RCC_PLLR_DIV_6) \
123 || ((__VALUE__) == LL_RCC_PLLR_DIV_8))
125 #define IS_LL_UTILS_PLLVCO_INPUT(__VALUE__) ((UTILS_PLLVCO_INPUT_MIN <= (__VALUE__)) && ((__VALUE__) <= UTILS_PLLVCO_INPUT_MAX))
127 #define IS_LL_UTILS_PLLVCO_OUTPUT(__VALUE__) ((UTILS_PLLVCO_OUTPUT_MIN <= (__VALUE__)) && ((__VALUE__) <= UTILS_PLLVCO_OUTPUT_MAX))
129 #define IS_LL_UTILS_PLL_FREQUENCY(__VALUE__) ((LL_PWR_GetRegulVoltageScaling() == LL_PWR_REGU_VOLTAGE_SCALE1) ? ((__VALUE__) <= UTILS_MAX_FREQUENCY_SCALE1) : \
130 ((__VALUE__) <= UTILS_MAX_FREQUENCY_SCALE2))
132 #define IS_LL_UTILS_HSE_BYPASS(__STATE__) (((__STATE__) == LL_UTILS_HSEBYPASS_ON) \
133 || ((__STATE__) == LL_UTILS_HSEBYPASS_OFF))
135 #define IS_LL_UTILS_HSE_FREQUENCY(__FREQUENCY__) (((__FREQUENCY__) >= UTILS_HSE_FREQUENCY_MIN) && ((__FREQUENCY__) <= UTILS_HSE_FREQUENCY_MAX))
137 * @}
139 /* Private function prototypes -----------------------------------------------*/
140 /** @defgroup UTILS_LL_Private_Functions UTILS Private functions
141 * @{
143 static uint32_t UTILS_GetPLLOutputFrequency(uint32_t PLL_InputFrequency,
144 LL_UTILS_PLLInitTypeDef *UTILS_PLLInitStruct);
145 static ErrorStatus UTILS_SetFlashLatency(uint32_t HCLK_Frequency);
146 static ErrorStatus UTILS_EnablePLLAndSwitchSystem(uint32_t SYSCLK_Frequency, LL_UTILS_ClkInitTypeDef *UTILS_ClkInitStruct);
147 static ErrorStatus UTILS_PLL_IsBusy(void);
149 * @}
152 /* Exported functions --------------------------------------------------------*/
153 /** @addtogroup UTILS_LL_Exported_Functions
154 * @{
157 /** @addtogroup UTILS_LL_EF_DELAY
158 * @{
162 * @brief This function configures the Cortex-M SysTick source to have 1ms time base.
163 * @note When a RTOS is used, it is recommended to avoid changing the Systick
164 * configuration by calling this function, for a delay use rather osDelay RTOS service.
165 * @param HCLKFrequency HCLK frequency in Hz
166 * @note HCLK frequency can be calculated thanks to RCC helper macro or function @ref LL_RCC_GetSystemClocksFreq
167 * @retval None
169 void LL_Init1msTick(uint32_t HCLKFrequency)
171 /* Use frequency provided in argument */
172 LL_InitTick(HCLKFrequency, 1000U);
176 * @brief This function provides accurate delay (in milliseconds) based
177 * on SysTick counter flag
178 * @note When a RTOS is used, it is recommended to avoid using blocking delay
179 * and use rather osDelay service.
180 * @note To respect 1ms timebase, user should call @ref LL_Init1msTick function which
181 * will configure Systick to 1ms
182 * @param Delay specifies the delay time length, in milliseconds.
183 * @retval None
185 void LL_mDelay(uint32_t Delay)
187 __IO uint32_t tmp = SysTick->CTRL; /* Clear the COUNTFLAG first */
188 uint32_t tmpDelay; /* MISRAC2012-Rule-17.8 */
189 /* Add this code to indicate that local variable is not used */
190 ((void)tmp);
191 tmpDelay = Delay;
192 /* Add a period to guaranty minimum wait */
193 if(tmpDelay < LL_MAX_DELAY)
195 tmpDelay++;
198 while (tmpDelay != 0U)
200 if((SysTick->CTRL & SysTick_CTRL_COUNTFLAG_Msk) != 0U)
202 tmpDelay--;
208 * @}
211 /** @addtogroup UTILS_EF_SYSTEM
212 * @brief System Configuration functions
214 @verbatim
215 ===============================================================================
216 ##### System Configuration functions #####
217 ===============================================================================
218 [..]
219 System, AHB and APB buses clocks configuration
221 (+) The maximum frequency of the SYSCLK, HCLK, PCLK1 and PCLK2 is
222 170000000 Hz for STM32G4xx.
223 @endverbatim
224 @internal
225 Depending on the device voltage range, the maximum frequency should be
226 adapted accordingly:
228 (++) Table 1. HCLK clock frequency for STM32G4xx devices
229 (++) +--------------------------------------------------------+
230 (++) | Latency | HCLK clock frequency (MHz) |
231 (++) | |--------------------------------------|
232 (++) | | voltage range 1 | voltage range 2 |
233 (++) | | 1.2 V | 1.0 V |
234 (++) |-----------------|-------------------|------------------|
235 (++) |0WS(1 CPU cycles)| 0 < HCLK <= 20 | 0 < HCLK <= 8 |
236 (++) |-----------------|-------------------|------------------|
237 (++) |1WS(2 CPU cycles)| 20 < HCLK <= 40 | 8 < HCLK <= 16 |
238 (++) |-----------------|-------------------|------------------|
239 (++) |2WS(3 CPU cycles)| 40 < HCLK <= 60 | 16 < HCLK <= 26 |
240 (++) |-----------------|-------------------|------------------|
241 (++) |3WS(4 CPU cycles)| 60 < HCLK <= 80 | 16 < HCLK <= 26 |
242 (++) |-----------------|-------------------|------------------|
243 (++) |4WS(5 CPU cycles)| 80 < HCLK <= 100 | 16 < HCLK <= 26 |
244 (++) |-----------------|-------------------|------------------|
245 (++) |5WS(6 CPU cycles)| 100 < HCLK <= 120 | 16 < HCLK <= 26 |
246 (++) |-----------------|-------------------|------------------|
247 (++) |6WS(7 CPU cycles)| 120 < HCLK <= 140 | 16 < HCLK <= 26 |
248 (++) |-----------------|-------------------|------------------|
249 (++) |7WS(8 CPU cycles)| 140 < HCLK <= 160 | 16 < HCLK <= 26 |
250 (++) |-----------------|-------------------|------------------|
251 (++) |8WS(9 CPU cycles)| 160 < HCLK <= 170 | 16 < HCLK <= 26 |
252 (++) +--------------------------------------------------------+
255 @endinternal
256 * @{
260 * @brief This function sets directly SystemCoreClock CMSIS variable.
261 * @note Variable can be calculated also through SystemCoreClockUpdate function.
262 * @param HCLKFrequency HCLK frequency in Hz (can be calculated thanks to RCC helper macro)
263 * @retval None
265 void LL_SetSystemCoreClock(uint32_t HCLKFrequency)
267 /* HCLK clock frequency */
268 SystemCoreClock = HCLKFrequency;
272 * @brief This function configures system clock at maximum frequency with HSI as clock source of the PLL
273 * @note The application need to ensure that PLL is disabled.
274 * @note Function is based on the following formula:
275 * - PLL output frequency = (((HSI frequency / PLLM) * PLLN) / PLLR)
276 * - PLLM: ensure that the VCO input frequency ranges from 2.66 to 8 MHz (PLLVCO_input = HSI frequency / PLLM)
277 * - PLLN: ensure that the VCO output frequency is between 64 and 344 MHz (PLLVCO_output = PLLVCO_input * PLLN)
278 * - PLLR: ensure that max frequency at 170000000 Hz is reach (PLLVCO_output / PLLR)
279 * @param UTILS_PLLInitStruct pointer to a @ref LL_UTILS_PLLInitTypeDef structure that contains
280 * the configuration information for the PLL.
281 * @param UTILS_ClkInitStruct pointer to a @ref LL_UTILS_ClkInitTypeDef structure that contains
282 * the configuration information for the BUS prescalers.
283 * @retval An ErrorStatus enumeration value:
284 * - SUCCESS: Max frequency configuration done
285 * - ERROR: Max frequency configuration not done
287 ErrorStatus LL_PLL_ConfigSystemClock_HSI(LL_UTILS_PLLInitTypeDef *UTILS_PLLInitStruct,
288 LL_UTILS_ClkInitTypeDef *UTILS_ClkInitStruct)
290 ErrorStatus status;
291 uint32_t pllfreq;
292 uint32_t hpre = 0U;
294 /* Check if one of the PLL is enabled */
295 if(UTILS_PLL_IsBusy() == SUCCESS)
297 /* Calculate the new PLL output frequency */
298 pllfreq = UTILS_GetPLLOutputFrequency(HSI_VALUE, UTILS_PLLInitStruct);
300 /* Enable HSI if not enabled */
301 if(LL_RCC_HSI_IsReady() != 1U)
303 LL_RCC_HSI_Enable();
304 while (LL_RCC_HSI_IsReady() != 1U)
306 /* Wait for HSI ready */
310 /* Configure PLL */
311 LL_RCC_PLL_ConfigDomain_SYS(LL_RCC_PLLSOURCE_HSI, UTILS_PLLInitStruct->PLLM, UTILS_PLLInitStruct->PLLN,
312 UTILS_PLLInitStruct->PLLR);
314 /* Prevent undershoot at highest frequency by applying intermediate AHB prescaler 2 */
315 if(pllfreq > 80000000U)
317 hpre = UTILS_ClkInitStruct->AHBCLKDivider;
318 if(hpre == LL_RCC_SYSCLK_DIV_1)
320 UTILS_ClkInitStruct->AHBCLKDivider = LL_RCC_SYSCLK_DIV_2;
324 /* Enable PLL and switch system clock to PLL */
325 status = UTILS_EnablePLLAndSwitchSystem(pllfreq, UTILS_ClkInitStruct);
327 /* Apply definitive AHB prescaler value if necessary */
328 if((status == SUCCESS) && (hpre != 0U))
330 UTILS_ClkInitStruct->AHBCLKDivider = LL_RCC_SYSCLK_DIV_1;
331 LL_RCC_SetAHBPrescaler(UTILS_ClkInitStruct->AHBCLKDivider);
334 else
336 /* Current PLL configuration cannot be modified */
337 status = ERROR;
340 return status;
344 * @brief This function configures system clock with HSE as clock source of the PLL
345 * @note The application need to ensure that PLL is disabled.
346 * @note Function is based on the following formula:
347 * - PLL output frequency = (((HSE frequency / PLLM) * PLLN) / PLLR)
348 * - PLLM: ensure that the VCO input frequency ranges from 2.66 to 8 MHz (PLLVCO_input = HSE frequency / PLLM)
349 * - PLLN: ensure that the VCO output frequency is between 64 and 344 MHz (PLLVCO_output = PLLVCO_input * PLLN)
350 * - PLLR: ensure that max frequency at 170000000 Hz is reached (PLLVCO_output / PLLR)
351 * @param HSEFrequency Value between Min_Data = 4000000 and Max_Data = 48000000
352 * @param HSEBypass This parameter can be one of the following values:
353 * @arg @ref LL_UTILS_HSEBYPASS_ON
354 * @arg @ref LL_UTILS_HSEBYPASS_OFF
355 * @param UTILS_PLLInitStruct pointer to a @ref LL_UTILS_PLLInitTypeDef structure that contains
356 * the configuration information for the PLL.
357 * @param UTILS_ClkInitStruct pointer to a @ref LL_UTILS_ClkInitTypeDef structure that contains
358 * the configuration information for the BUS prescalers.
359 * @retval An ErrorStatus enumeration value:
360 * - SUCCESS: Max frequency configuration done
361 * - ERROR: Max frequency configuration not done
363 ErrorStatus LL_PLL_ConfigSystemClock_HSE(uint32_t HSEFrequency, uint32_t HSEBypass,
364 LL_UTILS_PLLInitTypeDef *UTILS_PLLInitStruct, LL_UTILS_ClkInitTypeDef *UTILS_ClkInitStruct)
366 ErrorStatus status;
367 uint32_t pllfreq;
368 uint32_t hpre = 0U;
370 /* Check the parameters */
371 assert_param(IS_LL_UTILS_HSE_FREQUENCY(HSEFrequency));
372 assert_param(IS_LL_UTILS_HSE_BYPASS(HSEBypass));
374 /* Check if one of the PLL is enabled */
375 if(UTILS_PLL_IsBusy() == SUCCESS)
377 /* Calculate the new PLL output frequency */
378 pllfreq = UTILS_GetPLLOutputFrequency(HSEFrequency, UTILS_PLLInitStruct);
380 /* Enable HSE if not enabled */
381 if(LL_RCC_HSE_IsReady() != 1U)
383 /* Check if need to enable HSE bypass feature or not */
384 if(HSEBypass == LL_UTILS_HSEBYPASS_ON)
386 LL_RCC_HSE_EnableBypass();
388 else
390 LL_RCC_HSE_DisableBypass();
393 /* Enable HSE */
394 LL_RCC_HSE_Enable();
395 while (LL_RCC_HSE_IsReady() != 1U)
397 /* Wait for HSE ready */
401 /* Configure PLL */
402 LL_RCC_PLL_ConfigDomain_SYS(LL_RCC_PLLSOURCE_HSE, UTILS_PLLInitStruct->PLLM, UTILS_PLLInitStruct->PLLN,
403 UTILS_PLLInitStruct->PLLR);
405 /* Prevent undershoot at highest frequency by applying intermediate AHB prescaler 2 */
406 if(pllfreq > 80000000U)
408 hpre = UTILS_ClkInitStruct->AHBCLKDivider;
409 if(hpre == LL_RCC_SYSCLK_DIV_1)
411 UTILS_ClkInitStruct->AHBCLKDivider = LL_RCC_SYSCLK_DIV_2;
415 /* Enable PLL and switch system clock to PLL */
416 status = UTILS_EnablePLLAndSwitchSystem(pllfreq, UTILS_ClkInitStruct);
418 /* Apply definitive AHB prescaler value if necessary */
419 if((status == SUCCESS) && (hpre != 0U))
421 UTILS_ClkInitStruct->AHBCLKDivider = LL_RCC_SYSCLK_DIV_1;
422 LL_RCC_SetAHBPrescaler(UTILS_ClkInitStruct->AHBCLKDivider);
425 else
427 /* Current PLL configuration cannot be modified */
428 status = ERROR;
431 return status;
435 * @}
439 * @}
442 /** @addtogroup UTILS_LL_Private_Functions
443 * @{
446 * @brief Update number of Flash wait states in line with new frequency and current
447 voltage range.
448 * @param HCLK_Frequency HCLK frequency
449 * @retval An ErrorStatus enumeration value:
450 * - SUCCESS: Latency has been modified
451 * - ERROR: Latency cannot be modified
453 static ErrorStatus UTILS_SetFlashLatency(uint32_t HCLK_Frequency)
455 ErrorStatus status = SUCCESS;
457 uint32_t latency = LL_FLASH_LATENCY_0; /* default value 0WS */
459 /* Frequency cannot be equal to 0 */
460 if(HCLK_Frequency == 0U)
462 status = ERROR;
464 else
466 if(LL_PWR_GetRegulVoltageScaling() == LL_PWR_REGU_VOLTAGE_SCALE1)
468 if(HCLK_Frequency > UTILS_SCALE1_LATENCY8_FREQ)
470 /* 160 < HCLK <= 170 => 8WS (9 CPU cycles) */
471 latency = LL_FLASH_LATENCY_8;
473 else if(HCLK_Frequency > UTILS_SCALE1_LATENCY7_FREQ)
475 /* 140 < HCLK <= 160 => 7WS (8 CPU cycles) */
476 latency = LL_FLASH_LATENCY_7;
478 else if(HCLK_Frequency > UTILS_SCALE1_LATENCY6_FREQ)
480 /* 120 < HCLK <= 140 => 6WS (7 CPU cycles) */
481 latency = LL_FLASH_LATENCY_6;
483 else if(HCLK_Frequency > UTILS_SCALE1_LATENCY5_FREQ)
485 /* 100 < HCLK <= 120 => 5WS (6 CPU cycles) */
486 latency = LL_FLASH_LATENCY_5;
488 else if(HCLK_Frequency > UTILS_SCALE1_LATENCY4_FREQ)
490 /* 80 < HCLK <= 100 => 4WS (5 CPU cycles) */
491 latency = LL_FLASH_LATENCY_4;
493 else if(HCLK_Frequency > UTILS_SCALE1_LATENCY3_FREQ)
495 /* 60 < HCLK <= 80 => 3WS (4 CPU cycles) */
496 latency = LL_FLASH_LATENCY_3;
498 else if(HCLK_Frequency > UTILS_SCALE1_LATENCY2_FREQ)
500 /* 40 < HCLK <= 60 => 2WS (3 CPU cycles) */
501 latency = LL_FLASH_LATENCY_2;
503 else
505 if(HCLK_Frequency > UTILS_SCALE1_LATENCY1_FREQ)
507 /* 20 < HCLK <= 40 => 1WS (2 CPU cycles) */
508 latency = LL_FLASH_LATENCY_1;
510 /* else HCLK_Frequency <= 10MHz default LL_FLASH_LATENCY_0 0WS */
513 else /* SCALE2 */
515 if(HCLK_Frequency > UTILS_SCALE2_LATENCY2_FREQ)
517 /* 16 < HCLK <= 26 => 2WS (3 CPU cycles) */
518 latency = LL_FLASH_LATENCY_2;
520 else
522 if(HCLK_Frequency > UTILS_SCALE2_LATENCY1_FREQ)
524 /* 8 < HCLK <= 16 => 1WS (2 CPU cycles) */
525 latency = LL_FLASH_LATENCY_1;
527 /* else HCLK_Frequency <= 8MHz default LL_FLASH_LATENCY_0 0WS */
531 LL_FLASH_SetLatency(latency);
533 /* Check that the new number of wait states is taken into account to access the Flash
534 memory by reading the FLASH_ACR register */
535 if(LL_FLASH_GetLatency() != latency)
537 status = ERROR;
540 return status;
544 * @brief Function to check that PLL can be modified
545 * @param PLL_InputFrequency PLL input frequency (in Hz)
546 * @param UTILS_PLLInitStruct pointer to a @ref LL_UTILS_PLLInitTypeDef structure that contains
547 * the configuration information for the PLL.
548 * @retval PLL output frequency (in Hz)
550 static uint32_t UTILS_GetPLLOutputFrequency(uint32_t PLL_InputFrequency, LL_UTILS_PLLInitTypeDef *UTILS_PLLInitStruct)
552 uint32_t pllfreq;
554 /* Check the parameters */
555 assert_param(IS_LL_UTILS_PLLM_VALUE(UTILS_PLLInitStruct->PLLM));
556 assert_param(IS_LL_UTILS_PLLN_VALUE(UTILS_PLLInitStruct->PLLN));
557 assert_param(IS_LL_UTILS_PLLR_VALUE(UTILS_PLLInitStruct->PLLR));
559 /* Check different PLL parameters according to RM */
560 /* - PLLM: ensure that the VCO input frequency ranges from 2.66 to 8 MHz. */
561 pllfreq = PLL_InputFrequency / (((UTILS_PLLInitStruct->PLLM >> RCC_PLLCFGR_PLLM_Pos) + 1U));
562 assert_param(IS_LL_UTILS_PLLVCO_INPUT(pllfreq));
564 /* - PLLN: ensure that the VCO output frequency is between 64 and 344 MHz.*/
565 pllfreq = pllfreq * (UTILS_PLLInitStruct->PLLN & (RCC_PLLCFGR_PLLN >> RCC_PLLCFGR_PLLN_Pos));
566 assert_param(IS_LL_UTILS_PLLVCO_OUTPUT(pllfreq));
568 /* - PLLR: ensure that max frequency at 170000000 Hz is reached */
569 pllfreq = pllfreq / (((UTILS_PLLInitStruct->PLLR >> RCC_PLLCFGR_PLLR_Pos) + 1U) * 2U);
570 assert_param(IS_LL_UTILS_PLL_FREQUENCY(pllfreq));
572 return pllfreq;
576 * @brief Function to check that PLL can be modified
577 * @retval An ErrorStatus enumeration value:
578 * - SUCCESS: PLL modification can be done
579 * - ERROR: PLL is busy
581 static ErrorStatus UTILS_PLL_IsBusy(void)
583 ErrorStatus status = SUCCESS;
585 /* Check if PLL is busy*/
586 if(LL_RCC_PLL_IsReady() != 0U)
588 /* PLL configuration cannot be modified */
589 status = ERROR;
592 return status;
596 * @brief Function to enable PLL and switch system clock to PLL
597 * @param SYSCLK_Frequency SYSCLK frequency
598 * @param UTILS_ClkInitStruct pointer to a @ref LL_UTILS_ClkInitTypeDef structure that contains
599 * the configuration information for the BUS prescalers.
600 * @retval An ErrorStatus enumeration value:
601 * - SUCCESS: No problem to switch system to PLL
602 * - ERROR: Problem to switch system to PLL
604 static ErrorStatus UTILS_EnablePLLAndSwitchSystem(uint32_t SYSCLK_Frequency, LL_UTILS_ClkInitTypeDef *UTILS_ClkInitStruct)
606 ErrorStatus status = SUCCESS;
607 uint32_t hclk_frequency;
609 assert_param(IS_LL_UTILS_SYSCLK_DIV(UTILS_ClkInitStruct->AHBCLKDivider));
610 assert_param(IS_LL_UTILS_APB1_DIV(UTILS_ClkInitStruct->APB1CLKDivider));
611 assert_param(IS_LL_UTILS_APB2_DIV(UTILS_ClkInitStruct->APB2CLKDivider));
613 /* Calculate HCLK frequency */
614 hclk_frequency = __LL_RCC_CALC_HCLK_FREQ(SYSCLK_Frequency, UTILS_ClkInitStruct->AHBCLKDivider);
616 /* Increasing the number of wait states because of higher CPU frequency */
617 if(SystemCoreClock < hclk_frequency)
619 /* Set FLASH latency to highest latency */
620 status = UTILS_SetFlashLatency(hclk_frequency);
623 /* Update system clock configuration */
624 if(status == SUCCESS)
626 /* Enable PLL */
627 LL_RCC_PLL_Enable();
628 LL_RCC_PLL_EnableDomain_SYS();
629 while (LL_RCC_PLL_IsReady() != 1U)
631 /* Wait for PLL ready */
634 /* Sysclk activation on the main PLL */
635 LL_RCC_SetAHBPrescaler(UTILS_ClkInitStruct->AHBCLKDivider);
636 LL_RCC_SetSysClkSource(LL_RCC_SYS_CLKSOURCE_PLL);
637 while (LL_RCC_GetSysClkSource() != LL_RCC_SYS_CLKSOURCE_STATUS_PLL)
639 /* Wait for system clock switch to PLL */
642 /* Set APB1 & APB2 prescaler*/
643 LL_RCC_SetAPB1Prescaler(UTILS_ClkInitStruct->APB1CLKDivider);
644 LL_RCC_SetAPB2Prescaler(UTILS_ClkInitStruct->APB2CLKDivider);
647 /* Decreasing the number of wait states because of lower CPU frequency */
648 if(SystemCoreClock > hclk_frequency)
650 /* Set FLASH latency to lowest latency */
651 status = UTILS_SetFlashLatency(hclk_frequency);
654 /* Update SystemCoreClock variable */
655 if(status == SUCCESS)
657 LL_SetSystemCoreClock(hclk_frequency);
660 return status;
664 * @}
668 * @}
672 * @}
675 /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/