QuakeGod
2022-10-17 d69aae90ede578aaebc355dafd3496993ccea126
提交 | 用户 | age
bfc108 1 /**
Q 2   ******************************************************************************
3   * @file    stm32f0xx_ll_utils.c
4   * @author  MCD Application Team
5   * @brief   UTILS LL module driver.
6   ******************************************************************************
7   * @attention
8   *
9   * <h2><center>&copy; COPYRIGHT(c) 2016 STMicroelectronics</center></h2>
10   *
11   * Redistribution and use in source and binary forms, with or without modification,
12   * are permitted provided that the following conditions are met:
13   *   1. Redistributions of source code must retain the above copyright notice,
14   *      this list of conditions and the following disclaimer.
15   *   2. Redistributions in binary form must reproduce the above copyright notice,
16   *      this list of conditions and the following disclaimer in the documentation
17   *      and/or other materials provided with the distribution.
18   *   3. Neither the name of STMicroelectronics nor the names of its contributors
19   *      may be used to endorse or promote products derived from this software
20   *      without specific prior written permission.
21   *
22   * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
23   * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
24   * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
25   * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
26   * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
27   * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
28   * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
29   * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
30   * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
31   * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
32   *
33   ******************************************************************************
34   */
35 /* Includes ------------------------------------------------------------------*/
36 #include "stm32f0xx_ll_rcc.h"
37 #include "stm32f0xx_ll_utils.h"
38 #include "stm32f0xx_ll_system.h"
39 #ifdef  USE_FULL_ASSERT
40 #include "stm32_assert.h"
41 #else
42 #define assert_param(expr) ((void)0U)
43 #endif
44
45 /** @addtogroup STM32F0xx_LL_Driver
46   * @{
47   */
48
49 /** @addtogroup UTILS_LL
50   * @{
51   */
52
53 /* Private types -------------------------------------------------------------*/
54 /* Private variables ---------------------------------------------------------*/
55 /* Private constants ---------------------------------------------------------*/
56 /** @addtogroup UTILS_LL_Private_Constants
57   * @{
58   */
59
60 /* Defines used for PLL range */
61 #define UTILS_PLL_OUTPUT_MIN        16000000U           /*!< Frequency min for PLL output, in Hz  */
62 #define UTILS_PLL_OUTPUT_MAX        48000000U    /*!< Frequency max for PLL output, in Hz  */
63
64 /* Defines used for HSE range */
65 #define UTILS_HSE_FREQUENCY_MIN      4000000U       /*!< Frequency min for HSE frequency, in Hz   */
66 #define UTILS_HSE_FREQUENCY_MAX     32000000U       /*!< Frequency max for HSE frequency, in Hz   */
67
68 /* Defines used for FLASH latency according to SYSCLK Frequency */
69 #define UTILS_LATENCY1_FREQ         24000000U        /*!< SYSCLK frequency to set FLASH latency 1 */
70 /**
71   * @}
72   */
73 /* Private macros ------------------------------------------------------------*/
74 /** @addtogroup UTILS_LL_Private_Macros
75   * @{
76   */
77 #define IS_LL_UTILS_SYSCLK_DIV(__VALUE__) (((__VALUE__) == LL_RCC_SYSCLK_DIV_1)   \
78                                         || ((__VALUE__) == LL_RCC_SYSCLK_DIV_2)   \
79                                         || ((__VALUE__) == LL_RCC_SYSCLK_DIV_4)   \
80                                         || ((__VALUE__) == LL_RCC_SYSCLK_DIV_8)   \
81                                         || ((__VALUE__) == LL_RCC_SYSCLK_DIV_16)  \
82                                         || ((__VALUE__) == LL_RCC_SYSCLK_DIV_64)  \
83                                         || ((__VALUE__) == LL_RCC_SYSCLK_DIV_128) \
84                                         || ((__VALUE__) == LL_RCC_SYSCLK_DIV_256) \
85                                         || ((__VALUE__) == LL_RCC_SYSCLK_DIV_512))
86
87 #define IS_LL_UTILS_APB1_DIV(__VALUE__) (((__VALUE__) == LL_RCC_APB1_DIV_1) \
88                                       || ((__VALUE__) == LL_RCC_APB1_DIV_2) \
89                                       || ((__VALUE__) == LL_RCC_APB1_DIV_4) \
90                                       || ((__VALUE__) == LL_RCC_APB1_DIV_8) \
91                                       || ((__VALUE__) == LL_RCC_APB1_DIV_16))
92
93 #define IS_LL_UTILS_PLLMUL_VALUE(__VALUE__) (((__VALUE__) == LL_RCC_PLL_MUL_2) \
94                                           || ((__VALUE__) == LL_RCC_PLL_MUL_3) \
95                                           || ((__VALUE__) == LL_RCC_PLL_MUL_4) \
96                                           || ((__VALUE__) == LL_RCC_PLL_MUL_5) \
97                                           || ((__VALUE__) == LL_RCC_PLL_MUL_6) \
98                                           || ((__VALUE__) == LL_RCC_PLL_MUL_7) \
99                                           || ((__VALUE__) == LL_RCC_PLL_MUL_8) \
100                                           || ((__VALUE__) == LL_RCC_PLL_MUL_9) \
101                                           || ((__VALUE__) == LL_RCC_PLL_MUL_10) \
102                                           || ((__VALUE__) == LL_RCC_PLL_MUL_11) \
103                                           || ((__VALUE__) == LL_RCC_PLL_MUL_12) \
104                                           || ((__VALUE__) == LL_RCC_PLL_MUL_13) \
105                                           || ((__VALUE__) == LL_RCC_PLL_MUL_14) \
106                                           || ((__VALUE__) == LL_RCC_PLL_MUL_15) \
107                                           || ((__VALUE__) == LL_RCC_PLL_MUL_16))
108
109 #define IS_LL_UTILS_PREDIV_VALUE(__VALUE__) (((__VALUE__) == LL_RCC_PREDIV_DIV_1)  || ((__VALUE__) == LL_RCC_PREDIV_DIV_2)   || \
110                                              ((__VALUE__) == LL_RCC_PREDIV_DIV_3)  || ((__VALUE__) == LL_RCC_PREDIV_DIV_4)   || \
111                                              ((__VALUE__) == LL_RCC_PREDIV_DIV_5)  || ((__VALUE__) == LL_RCC_PREDIV_DIV_6)   || \
112                                              ((__VALUE__) == LL_RCC_PREDIV_DIV_7)  || ((__VALUE__) == LL_RCC_PREDIV_DIV_8)   || \
113                                              ((__VALUE__) == LL_RCC_PREDIV_DIV_9)  || ((__VALUE__) == LL_RCC_PREDIV_DIV_10)  || \
114                                              ((__VALUE__) == LL_RCC_PREDIV_DIV_11) || ((__VALUE__) == LL_RCC_PREDIV_DIV_12)  || \
115                                              ((__VALUE__) == LL_RCC_PREDIV_DIV_13) || ((__VALUE__) == LL_RCC_PREDIV_DIV_14)  || \
116                                              ((__VALUE__) == LL_RCC_PREDIV_DIV_15) || ((__VALUE__) == LL_RCC_PREDIV_DIV_16))
117
118 #define IS_LL_UTILS_PLL_FREQUENCY(__VALUE__) ((UTILS_PLL_OUTPUT_MIN <= (__VALUE__)) && ((__VALUE__) <= UTILS_PLL_OUTPUT_MAX))
119
120
121 #define IS_LL_UTILS_HSE_BYPASS(__STATE__) (((__STATE__) == LL_UTILS_HSEBYPASS_ON) \
122                                         || ((__STATE__) == LL_UTILS_HSEBYPASS_OFF))
123
124 #define IS_LL_UTILS_HSE_FREQUENCY(__FREQUENCY__) (((__FREQUENCY__) >= UTILS_HSE_FREQUENCY_MIN) && ((__FREQUENCY__) <= UTILS_HSE_FREQUENCY_MAX))
125 /**
126   * @}
127   */
128 /* Private function prototypes -----------------------------------------------*/
129 /** @defgroup UTILS_LL_Private_Functions UTILS Private functions
130   * @{
131   */
132 static uint32_t    UTILS_GetPLLOutputFrequency(uint32_t PLL_InputFrequency,
133                                                LL_UTILS_PLLInitTypeDef *UTILS_PLLInitStruct);
134 #if defined(FLASH_ACR_LATENCY)
135 static ErrorStatus UTILS_SetFlashLatency(uint32_t Frequency);
136 #endif /* FLASH_ACR_LATENCY */
137 static ErrorStatus UTILS_EnablePLLAndSwitchSystem(uint32_t SYSCLK_Frequency, LL_UTILS_ClkInitTypeDef *UTILS_ClkInitStruct);
138 static ErrorStatus UTILS_PLL_IsBusy(void);
139 /**
140   * @}
141   */
142
143 /* Exported functions --------------------------------------------------------*/
144 /** @addtogroup UTILS_LL_Exported_Functions
145   * @{
146   */
147
148 /** @addtogroup UTILS_LL_EF_DELAY
149   * @{
150   */
151
152 /**
153   * @brief  This function configures the Cortex-M SysTick source to have 1ms time base.
154   * @note   When a RTOS is used, it is recommended to avoid changing the Systick
155   *         configuration by calling this function, for a delay use rather osDelay RTOS service.
156   * @param  HCLKFrequency HCLK frequency in Hz
157   * @note   HCLK frequency can be calculated thanks to RCC helper macro or function @ref LL_RCC_GetSystemClocksFreq
158   * @retval None
159   */
160 void LL_Init1msTick(uint32_t HCLKFrequency)
161 {
162   /* Use frequency provided in argument */
163   LL_InitTick(HCLKFrequency, 1000U);
164 }
165
166 /**
167   * @brief  This function provides accurate delay (in milliseconds) based
168   *         on SysTick counter flag
169   * @note   When a RTOS is used, it is recommended to avoid using blocking delay
170   *         and use rather osDelay service.
171   * @note   To respect 1ms timebase, user should call @ref LL_Init1msTick function which
172   *         will configure Systick to 1ms
173   * @param  Delay specifies the delay time length, in milliseconds.
174   * @retval None
175   */
176 void LL_mDelay(uint32_t Delay)
177 {
178   __IO uint32_t  tmp = SysTick->CTRL;  /* Clear the COUNTFLAG first */
179   /* Add this code to indicate that local variable is not used */
180   ((void)tmp);
181
182   /* Add a period to guaranty minimum wait */
183   if (Delay < LL_MAX_DELAY)
184   {
185     Delay++;
186   }
187
188   while (Delay)
189   {
190     if ((SysTick->CTRL & SysTick_CTRL_COUNTFLAG_Msk) != 0U)
191     {
192       Delay--;
193     }
194   }
195 }
196
197 /**
198   * @}
199   */
200
201 /** @addtogroup UTILS_EF_SYSTEM
202   *  @brief    System Configuration functions
203   *
204   @verbatim
205  ===============================================================================
206            ##### System Configuration functions #####
207  ===============================================================================
208     [..]
209          System, AHB and APB buses clocks configuration
210
211          (+) The maximum frequency of the SYSCLK, HCLK, PCLK1 and PCLK2 is 48000000 Hz.
212   @endverbatim
213   @internal
214              Depending on the SYSCLK frequency, the flash latency should be adapted accordingly:
215              (++) +-----------------------------------------------+
216              (++) | Latency       | SYSCLK clock frequency (MHz)  |
217              (++) |---------------|-------------------------------|
218              (++) |0WS(1CPU cycle)|       0 < SYSCLK <= 24        |
219              (++) |---------------|-------------------------------|
220              (++) |1WS(2CPU cycle)|      24 < SYSCLK <= 48        |
221              (++) +-----------------------------------------------+
222   @endinternal
223   * @{
224   */
225
226 /**
227   * @brief  This function sets directly SystemCoreClock CMSIS variable.
228   * @note   Variable can be calculated also through SystemCoreClockUpdate function.
229   * @param  HCLKFrequency HCLK frequency in Hz (can be calculated thanks to RCC helper macro)
230   * @retval None
231   */
232 void LL_SetSystemCoreClock(uint32_t HCLKFrequency)
233 {
234   /* HCLK clock frequency */
235   SystemCoreClock = HCLKFrequency;
236 }
237
238 /**
239   * @brief  This function configures system clock with HSI as clock source of the PLL
240   * @note   The application need to ensure that PLL is disabled.
241   * @note   Function is based on the following formula:
242   *         - PLL output frequency = ((HSI frequency / PREDIV) * PLLMUL)
243   *         - PREDIV: Set to 2 for few devices
244   *         - PLLMUL: The application software must set correctly the PLL multiplication factor to 
245   *                   be in the range 16-48MHz
246   * @note   FLASH latency can be modified through this function. 
247   * @param  UTILS_PLLInitStruct pointer to a @ref LL_UTILS_PLLInitTypeDef structure that contains
248   *                             the configuration information for the PLL.
249   * @param  UTILS_ClkInitStruct pointer to a @ref LL_UTILS_ClkInitTypeDef structure that contains
250   *                             the configuration information for the BUS prescalers.
251   * @retval An ErrorStatus enumeration value:
252   *          - SUCCESS: Max frequency configuration done
253   *          - ERROR: Max frequency configuration not done
254   */
255 ErrorStatus LL_PLL_ConfigSystemClock_HSI(LL_UTILS_PLLInitTypeDef *UTILS_PLLInitStruct,
256                                          LL_UTILS_ClkInitTypeDef *UTILS_ClkInitStruct)
257 {
258   ErrorStatus status = SUCCESS;
259   uint32_t pllfreq = 0U;
260
261   /* Check if one of the PLL is enabled */
262   if (UTILS_PLL_IsBusy() == SUCCESS)
263   {
264 #if defined(RCC_PLLSRC_PREDIV1_SUPPORT)
265     /* Check PREDIV value */
266     assert_param(IS_LL_UTILS_PREDIV_VALUE(UTILS_PLLInitStruct->PLLDiv));
267 #else
268     /* Force PREDIV value to 2 */
269     UTILS_PLLInitStruct->Prediv = LL_RCC_PREDIV_DIV_2;
270 #endif /*RCC_PLLSRC_PREDIV1_SUPPORT*/
271     /* Calculate the new PLL output frequency */
272     pllfreq = UTILS_GetPLLOutputFrequency(HSI_VALUE, UTILS_PLLInitStruct);
273
274     /* Enable HSI if not enabled */
275     if (LL_RCC_HSI_IsReady() != 1U)
276     {
277       LL_RCC_HSI_Enable();
278       while (LL_RCC_HSI_IsReady() != 1U)
279       {
280         /* Wait for HSI ready */
281       }
282     }
283
284     /* Configure PLL */
285 #if defined(RCC_PLLSRC_PREDIV1_SUPPORT)
286     LL_RCC_PLL_ConfigDomain_SYS(LL_RCC_PLLSOURCE_HSI, UTILS_PLLInitStruct->PLLMul, UTILS_PLLInitStruct->PLLDiv);
287 #else
288     LL_RCC_PLL_ConfigDomain_SYS(LL_RCC_PLLSOURCE_HSI_DIV_2, UTILS_PLLInitStruct->PLLMul);
289 #endif /*RCC_PLLSRC_PREDIV1_SUPPORT*/
290
291     /* Enable PLL and switch system clock to PLL */
292     status = UTILS_EnablePLLAndSwitchSystem(pllfreq, UTILS_ClkInitStruct);
293   }
294   else
295   {
296     /* Current PLL configuration cannot be modified */
297     status = ERROR;
298   }
299
300   return status;
301 }
302
303 #if defined(RCC_CFGR_SW_HSI48)
304 /**
305   * @brief  This function configures system clock with HSI48 as clock source of the PLL
306   * @note   The application need to ensure that PLL is disabled.
307   * @note   Function is based on the following formula:
308   *         - PLL output frequency = ((HSI48 frequency / PREDIV) * PLLMUL)
309   *         - PLLMUL: The application software must set correctly the PLL multiplication factor to 
310   *                   be in the range 16-48MHz
311   * @param  UTILS_PLLInitStruct pointer to a @ref LL_UTILS_PLLInitTypeDef structure that contains
312   *                             the configuration information for the PLL.
313   * @param  UTILS_ClkInitStruct pointer to a @ref LL_UTILS_ClkInitTypeDef structure that contains
314   *                             the configuration information for the BUS prescalers.
315   * @retval An ErrorStatus enumeration value:
316   *          - SUCCESS: Max frequency configuration done
317   *          - ERROR: Max frequency configuration not done
318   */
319 ErrorStatus LL_PLL_ConfigSystemClock_HSI48(LL_UTILS_PLLInitTypeDef *UTILS_PLLInitStruct,
320                                          LL_UTILS_ClkInitTypeDef *UTILS_ClkInitStruct)
321 {
322   ErrorStatus status = SUCCESS;
323   uint32_t pllfreq = 0U;
324
325   /* Check if one of the PLL is enabled */
326   if (UTILS_PLL_IsBusy() == SUCCESS)
327   {
328     /* Check PREDIV value */
329     assert_param(IS_LL_UTILS_PREDIV_VALUE(UTILS_PLLInitStruct->PLLDiv));
330
331     /* Calculate the new PLL output frequency */
332     pllfreq = UTILS_GetPLLOutputFrequency(HSI48_VALUE, UTILS_PLLInitStruct);
333
334     /* Enable HSI48 if not enabled */
335     if (LL_RCC_HSI48_IsReady() != 1U)
336     {
337       LL_RCC_HSI48_Enable();
338       while (LL_RCC_HSI48_IsReady() != 1U)
339       {
340         /* Wait for HSI48 ready */
341       }
342     }
343
344     /* Configure PLL */
345     LL_RCC_PLL_ConfigDomain_SYS(LL_RCC_PLLSOURCE_HSI48, UTILS_PLLInitStruct->PLLMul, UTILS_PLLInitStruct->PLLDiv);
346
347     /* Enable PLL and switch system clock to PLL */
348     status = UTILS_EnablePLLAndSwitchSystem(pllfreq, UTILS_ClkInitStruct);
349   }
350   else
351   {
352     /* Current PLL configuration cannot be modified */
353     status = ERROR;
354   }
355
356   return status;
357 }
358
359 #endif /*RCC_CFGR_SW_HSI48*/
360 /**
361   * @brief  This function configures system clock with HSE as clock source of the PLL
362   * @note   The application need to ensure that PLL is disabled.
363   * @note   Function is based on the following formula:
364   *         - PLL output frequency = ((HSE frequency / PREDIV) * PLLMUL)
365   *         - PLLMUL: The application software must set correctly the PLL multiplication factor to 
366   *                   be in the range 16-48MHz
367   * @note   FLASH latency can be modified through this function. 
368   * @param  HSEFrequency Value between Min_Data = 4000000 and Max_Data = 32000000
369   * @param  HSEBypass This parameter can be one of the following values:
370   *         @arg @ref LL_UTILS_HSEBYPASS_ON
371   *         @arg @ref LL_UTILS_HSEBYPASS_OFF
372   * @param  UTILS_PLLInitStruct pointer to a @ref LL_UTILS_PLLInitTypeDef structure that contains
373   *                             the configuration information for the PLL.
374   * @param  UTILS_ClkInitStruct pointer to a @ref LL_UTILS_ClkInitTypeDef structure that contains
375   *                             the configuration information for the BUS prescalers.
376   * @retval An ErrorStatus enumeration value:
377   *          - SUCCESS: Max frequency configuration done
378   *          - ERROR: Max frequency configuration not done
379   */
380 ErrorStatus LL_PLL_ConfigSystemClock_HSE(uint32_t HSEFrequency, uint32_t HSEBypass,
381                                          LL_UTILS_PLLInitTypeDef *UTILS_PLLInitStruct, LL_UTILS_ClkInitTypeDef *UTILS_ClkInitStruct)
382 {
383   ErrorStatus status = SUCCESS;
384   uint32_t pllfreq = 0U;
385
386   /* Check the parameters */
387   assert_param(IS_LL_UTILS_HSE_FREQUENCY(HSEFrequency));
388   assert_param(IS_LL_UTILS_HSE_BYPASS(HSEBypass));
389
390   /* Check if one of the PLL is enabled */
391   if (UTILS_PLL_IsBusy() == SUCCESS)
392   {
393     /* Check PREDIV value */
394 #if defined(RCC_PLLSRC_PREDIV1_SUPPORT)
395     assert_param(IS_LL_UTILS_PREDIV_VALUE(UTILS_PLLInitStruct->PLLDiv));
396 #else
397     assert_param(IS_LL_UTILS_PREDIV_VALUE(UTILS_PLLInitStruct->Prediv));
398 #endif /*RCC_PLLSRC_PREDIV1_SUPPORT*/
399
400     /* Calculate the new PLL output frequency */
401     pllfreq = UTILS_GetPLLOutputFrequency(HSEFrequency, UTILS_PLLInitStruct);
402
403     /* Enable HSE if not enabled */
404     if (LL_RCC_HSE_IsReady() != 1U)
405     {
406       /* Check if need to enable HSE bypass feature or not */
407       if (HSEBypass == LL_UTILS_HSEBYPASS_ON)
408       {
409         LL_RCC_HSE_EnableBypass();
410       }
411       else
412       {
413         LL_RCC_HSE_DisableBypass();
414       }
415
416       /* Enable HSE */
417       LL_RCC_HSE_Enable();
418       while (LL_RCC_HSE_IsReady() != 1U)
419       {
420         /* Wait for HSE ready */
421       }
422     }
423
424       /* Configure PLL */
425 #if defined(RCC_PLLSRC_PREDIV1_SUPPORT)
426       LL_RCC_PLL_ConfigDomain_SYS(LL_RCC_PLLSOURCE_HSE, UTILS_PLLInitStruct->PLLMul, UTILS_PLLInitStruct->PLLDiv);
427 #else
428     LL_RCC_PLL_ConfigDomain_SYS((RCC_CFGR_PLLSRC_HSE_PREDIV | UTILS_PLLInitStruct->Prediv), UTILS_PLLInitStruct->PLLMul);
429 #endif /*RCC_PLLSRC_PREDIV1_SUPPORT*/
430
431     /* Enable PLL and switch system clock to PLL */
432     status = UTILS_EnablePLLAndSwitchSystem(pllfreq, UTILS_ClkInitStruct);
433   }
434   else
435   {
436     /* Current PLL configuration cannot be modified */
437     status = ERROR;
438   }
439
440   return status;
441 }
442
443 /**
444   * @}
445   */
446
447 /**
448   * @}
449   */
450
451 /** @addtogroup UTILS_LL_Private_Functions
452   * @{
453   */
454 /**
455   * @brief  Update number of Flash wait states in line with new frequency and current
456             voltage range.
457   * @param  Frequency  SYSCLK frequency
458   * @retval An ErrorStatus enumeration value:
459   *          - SUCCESS: Latency has been modified
460   *          - ERROR: Latency cannot be modified
461   */
462 #if defined(FLASH_ACR_LATENCY)
463 static ErrorStatus UTILS_SetFlashLatency(uint32_t Frequency)
464 {
465   ErrorStatus status = SUCCESS;
466
467   uint32_t latency = LL_FLASH_LATENCY_0;  /* default value 0WS */
468
469   /* Frequency cannot be equal to 0 */
470   if (Frequency == 0U)
471   {
472     status = ERROR;
473   }
474   else
475   {
476     if (Frequency > UTILS_LATENCY1_FREQ)
477     {
478       /* 24 < SYSCLK <= 48 => 1WS (2 CPU cycles) */
479       latency = LL_FLASH_LATENCY_1;
480     }
481     /* else SYSCLK < 24MHz default LL_FLASH_LATENCY_0 0WS */
482
483     LL_FLASH_SetLatency(latency);
484
485     /* Check that the new number of wait states is taken into account to access the Flash
486        memory by reading the FLASH_ACR register */
487     if (LL_FLASH_GetLatency() != latency)
488     {
489       status = ERROR;
490     }
491   }
492   return status;
493 }
494 #endif /* FLASH_ACR_LATENCY */
495
496 /**
497   * @brief  Function to check that PLL can be modified
498   * @param  PLL_InputFrequency  PLL input frequency (in Hz)
499   * @param  UTILS_PLLInitStruct pointer to a @ref LL_UTILS_PLLInitTypeDef structure that contains
500   *                             the configuration information for the PLL.
501   * @retval PLL output frequency (in Hz)
502   */
503 static uint32_t UTILS_GetPLLOutputFrequency(uint32_t PLL_InputFrequency, LL_UTILS_PLLInitTypeDef *UTILS_PLLInitStruct)
504 {
505   uint32_t pllfreq = 0U;
506
507   /* Check the parameters */
508   assert_param(IS_LL_UTILS_PLLMUL_VALUE(UTILS_PLLInitStruct->PLLMul));
509
510   /* Check different PLL parameters according to RM                          */
511   /* The application software must set correctly the PLL multiplication factor to 
512      be in the range 16-48MHz */
513 #if defined(RCC_PLLSRC_PREDIV1_SUPPORT)
514   pllfreq = __LL_RCC_CALC_PLLCLK_FREQ(PLL_InputFrequency, UTILS_PLLInitStruct->PLLMul, UTILS_PLLInitStruct->PLLDiv);
515 #else
516   pllfreq = __LL_RCC_CALC_PLLCLK_FREQ(PLL_InputFrequency / (UTILS_PLLInitStruct->Prediv + 1U), UTILS_PLLInitStruct->PLLMul);
517 #endif /*RCC_PLLSRC_PREDIV1_SUPPORT*/
518   assert_param(IS_LL_UTILS_PLL_FREQUENCY(pllfreq));
519
520   return pllfreq;
521 }
522
523 /**
524   * @brief  Function to check that PLL can be modified
525   * @retval An ErrorStatus enumeration value:
526   *          - SUCCESS: PLL modification can be done
527   *          - ERROR: PLL is busy
528   */
529 static ErrorStatus UTILS_PLL_IsBusy(void)
530 {
531   ErrorStatus status = SUCCESS;
532
533   /* Check if PLL is busy*/
534   if (LL_RCC_PLL_IsReady() != 0U)
535   {
536     /* PLL configuration cannot be modified */
537     status = ERROR;
538   }
539
540   return status;
541 }
542
543 /**
544   * @brief  Function to enable PLL and switch system clock to PLL
545   * @param  SYSCLK_Frequency SYSCLK frequency
546   * @param  UTILS_ClkInitStruct pointer to a @ref LL_UTILS_ClkInitTypeDef structure that contains
547   *                             the configuration information for the BUS prescalers.
548   * @retval An ErrorStatus enumeration value:
549   *          - SUCCESS: No problem to switch system to PLL
550   *          - ERROR: Problem to switch system to PLL
551   */
552 static ErrorStatus UTILS_EnablePLLAndSwitchSystem(uint32_t SYSCLK_Frequency, LL_UTILS_ClkInitTypeDef *UTILS_ClkInitStruct)
553 {
554   ErrorStatus status = SUCCESS;
555   uint32_t sysclk_frequency_current = 0U;
556
557   assert_param(IS_LL_UTILS_SYSCLK_DIV(UTILS_ClkInitStruct->AHBCLKDivider));
558   assert_param(IS_LL_UTILS_APB1_DIV(UTILS_ClkInitStruct->APB1CLKDivider));
559
560   /* Calculate current SYSCLK frequency */
561   sysclk_frequency_current = (SystemCoreClock << AHBPrescTable[LL_RCC_GetAHBPrescaler() >> RCC_POSITION_HPRE]);
562
563   /* Increasing the number of wait states because of higher CPU frequency */
564   if (sysclk_frequency_current < SYSCLK_Frequency)
565   {
566     /* Set FLASH latency to highest latency */
567     status = UTILS_SetFlashLatency(SYSCLK_Frequency);
568   }
569
570   /* Update system clock configuration */
571   if (status == SUCCESS)
572   {
573     /* Enable PLL */
574     LL_RCC_PLL_Enable();
575     while (LL_RCC_PLL_IsReady() != 1U)
576     {
577       /* Wait for PLL ready */
578     }
579
580     /* Sysclk activation on the main PLL */
581     LL_RCC_SetAHBPrescaler(UTILS_ClkInitStruct->AHBCLKDivider);
582     LL_RCC_SetSysClkSource(LL_RCC_SYS_CLKSOURCE_PLL);
583     while (LL_RCC_GetSysClkSource() != LL_RCC_SYS_CLKSOURCE_STATUS_PLL)
584     {
585       /* Wait for system clock switch to PLL */
586     }
587
588     /* Set APB1 & APB2 prescaler*/
589     LL_RCC_SetAPB1Prescaler(UTILS_ClkInitStruct->APB1CLKDivider);
590   }
591
592   /* Decreasing the number of wait states because of lower CPU frequency */
593   if (sysclk_frequency_current > SYSCLK_Frequency)
594   {
595     /* Set FLASH latency to lowest latency */
596     status = UTILS_SetFlashLatency(SYSCLK_Frequency);
597   }
598
599   /* Update SystemCoreClock variable */
600   if (status == SUCCESS)
601   {
602     LL_SetSystemCoreClock(__LL_RCC_CALC_HCLK_FREQ(SYSCLK_Frequency, UTILS_ClkInitStruct->AHBCLKDivider));
603   }
604
605   return status;
606 }
607
608 /**
609   * @}
610   */
611
612 /**
613   * @}
614   */
615
616 /**
617   * @}
618   */
619
620 /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/