Subversion Repositories FuelGauge

Rev

Go to most recent revision | Details | Last modification | View Log | RSS feed

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