Subversion Repositories dashGPS

Rev

Rev 2 | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
2 mjames 1
/**
2
  ******************************************************************************
3
  * @file    stm32f1xx_ll_utils.c
4
  * @author  MCD Application Team
5
  * @brief   UTILS LL module driver.
6
  ******************************************************************************
7
  * @attention
8
  *
9
  * <h2><center>&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 "stm32f1xx_ll_rcc.h"
22
#include "stm32f1xx_ll_utils.h"
23
#include "stm32f1xx_ll_system.h"
24
#ifdef  USE_FULL_ASSERT
25
#include "stm32_assert.h"
26
#else
27
#define assert_param(expr) ((void)0U)
28
#endif
29
 
30
/** @addtogroup STM32F1xx_LL_Driver
31
  * @{
32
  */
33
 
34
/** @addtogroup UTILS_LL
35
  * @{
36
  */
37
 
38
/* Private types -------------------------------------------------------------*/
39
/* Private variables ---------------------------------------------------------*/
40
/* Private constants ---------------------------------------------------------*/
41
/** @addtogroup UTILS_LL_Private_Constants
42
  * @{
43
  */
44
 
45
/* Defines used for PLL range */
46
#define UTILS_PLL_OUTPUT_MAX        RCC_MAX_FREQUENCY    /*!< Frequency max for PLL output, in Hz  */
47
 
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
 
130
#define IS_LL_UTILS_HSE_BYPASS(__STATE__) (((__STATE__) == LL_UTILS_HSEBYPASS_ON) \
131
                                        || ((__STATE__) == LL_UTILS_HSEBYPASS_OFF))
132
 
133
#define IS_LL_UTILS_HSE_FREQUENCY(__FREQUENCY__) (((__FREQUENCY__) >= UTILS_HSE_FREQUENCY_MIN) && ((__FREQUENCY__) <= UTILS_HSE_FREQUENCY_MAX))
134
/**
135
  * @}
136
  */
137
/* Private function prototypes -----------------------------------------------*/
138
/** @defgroup UTILS_LL_Private_Functions UTILS Private functions
139
  * @{
140
  */
141
static uint32_t    UTILS_GetPLLOutputFrequency(uint32_t PLL_InputFrequency,
142
                                               LL_UTILS_PLLInitTypeDef *UTILS_PLLInitStruct);
143
#if defined(FLASH_ACR_LATENCY)
144
static ErrorStatus UTILS_SetFlashLatency(uint32_t Frequency);
145
#endif /* FLASH_ACR_LATENCY */
146
static ErrorStatus UTILS_EnablePLLAndSwitchSystem(uint32_t SYSCLK_Frequency, LL_UTILS_ClkInitTypeDef *UTILS_ClkInitStruct);
147
static ErrorStatus UTILS_PLL_IsBusy(void);
148
/**
149
  * @}
150
  */
151
 
152
/* Exported functions --------------------------------------------------------*/
153
/** @addtogroup UTILS_LL_Exported_Functions
154
  * @{
155
  */
156
 
157
/** @addtogroup UTILS_LL_EF_DELAY
158
  * @{
159
  */
160
 
161
/**
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
168
  */
169
void LL_Init1msTick(uint32_t HCLKFrequency)
170
{
171
  /* Use frequency provided in argument */
172
  LL_InitTick(HCLKFrequency, 1000U);
173
}
174
 
175
/**
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
184
  */
185
void LL_mDelay(uint32_t Delay)
186
{
187
  __IO uint32_t  tmp = SysTick->CTRL;  /* Clear the COUNTFLAG first */
188
  /* Add this code to indicate that local variable is not used */
189
  ((void)tmp);
190
 
191
  /* Add a period to guaranty minimum wait */
192
  if (Delay < LL_MAX_DELAY)
193
  {
194
    Delay++;
195
  }
196
 
197
  while (Delay)
198
  {
199
    if ((SysTick->CTRL & SysTick_CTRL_COUNTFLAG_Msk) != 0U)
200
    {
201
      Delay--;
202
    }
203
  }
204
}
205
 
206
/**
207
  * @}
208
  */
209
 
210
/** @addtogroup UTILS_EF_SYSTEM
211
  *  @brief    System Configuration functions
212
  *
213
  @verbatim
214
 ===============================================================================
215
           ##### System Configuration functions #####
216
 ===============================================================================
217
    [..]
218
         System, AHB and APB buses clocks configuration
219
 
220
         (+) The maximum frequency of the SYSCLK, HCLK, PCLK1 and PCLK2 is RCC_MAX_FREQUENCY Hz.
221
  @endverbatim
222
  @internal
223
             Depending on the SYSCLK frequency, the flash latency should be adapted accordingly:
224
             (++) +-----------------------------------------------+
225
             (++) | Latency       | SYSCLK clock frequency (MHz)  |
226
             (++) |---------------|-------------------------------|
227
             (++) |0WS(1CPU cycle)|       0 < SYSCLK <= 24        |
228
             (++) |---------------|-------------------------------|
229
             (++) |1WS(2CPU cycle)|      24 < SYSCLK <= 48        |
230
             (++) |---------------|-------------------------------|
231
             (++) |2WS(3CPU cycle)|      48 < SYSCLK <= 72        |
232
             (++) +-----------------------------------------------+
233
  @endinternal
234
  * @{
235
  */
236
 
237
/**
238
  * @brief  This function sets directly SystemCoreClock CMSIS variable.
239
  * @note   Variable can be calculated also through SystemCoreClockUpdate function.
240
  * @param  HCLKFrequency HCLK frequency in Hz (can be calculated thanks to RCC helper macro)
241
  * @retval None
242
  */
243
void LL_SetSystemCoreClock(uint32_t HCLKFrequency)
244
{
245
  /* HCLK clock frequency */
246
  SystemCoreClock = HCLKFrequency;
247
}
248
 
249
/**
250
  * @brief  This function configures system clock with HSI as clock source of the PLL
251
  * @note   The application need to ensure that PLL is disabled.
252
  * @note   Function is based on the following formula:
253
  *         - PLL output frequency = ((HSI frequency / PREDIV) * PLLMUL)
254
  *         - PREDIV: Set to 2 for few devices
255
  *         - PLLMUL: The application software must set correctly the PLL multiplication factor to
256
  *                   not exceed 72MHz
257
  * @note   FLASH latency can be modified through this function.
258
  * @param  UTILS_PLLInitStruct pointer to a @ref LL_UTILS_PLLInitTypeDef structure that contains
259
  *                             the configuration information for the PLL.
260
  * @param  UTILS_ClkInitStruct pointer to a @ref LL_UTILS_ClkInitTypeDef structure that contains
261
  *                             the configuration information for the BUS prescalers.
262
  * @retval An ErrorStatus enumeration value:
263
  *          - SUCCESS: Max frequency configuration done
264
  *          - ERROR: Max frequency configuration not done
265
  */
266
ErrorStatus LL_PLL_ConfigSystemClock_HSI(LL_UTILS_PLLInitTypeDef *UTILS_PLLInitStruct,
267
                                         LL_UTILS_ClkInitTypeDef *UTILS_ClkInitStruct)
268
{
269
  ErrorStatus status = SUCCESS;
270
  uint32_t pllfreq = 0U;
271
 
272
  /* Check if one of the PLL is enabled */
273
  if (UTILS_PLL_IsBusy() == SUCCESS)
274
  {
275
#if defined(RCC_PLLSRC_PREDIV1_SUPPORT)
276
    /* Check PREDIV value */
277
    assert_param(IS_LL_UTILS_PREDIV_VALUE(UTILS_PLLInitStruct->PLLDiv));
278
#else
279
    /* Force PREDIV value to 2 */
280
    UTILS_PLLInitStruct->Prediv = LL_RCC_PREDIV_DIV_2;
281
#endif /*RCC_PLLSRC_PREDIV1_SUPPORT*/
282
    /* Calculate the new PLL output frequency */
283
    pllfreq = UTILS_GetPLLOutputFrequency(HSI_VALUE, UTILS_PLLInitStruct);
284
 
285
    /* Enable HSI if not enabled */
286
    if (LL_RCC_HSI_IsReady() != 1U)
287
    {
288
      LL_RCC_HSI_Enable();
289
      while (LL_RCC_HSI_IsReady() != 1U)
290
      {
291
        /* Wait for HSI ready */
292
      }
293
    }
294
 
295
    /* Configure PLL */
296
    LL_RCC_PLL_ConfigDomain_SYS(LL_RCC_PLLSOURCE_HSI_DIV_2, UTILS_PLLInitStruct->PLLMul);
297
 
298
    /* Enable PLL and switch system clock to PLL */
299
    status = UTILS_EnablePLLAndSwitchSystem(pllfreq, UTILS_ClkInitStruct);
300
  }
301
  else
302
  {
303
    /* Current PLL configuration cannot be modified */
304
    status = ERROR;
305
  }
306
 
307
  return status;
308
}
309
 
310
/**
311
  * @brief  This function configures system clock with HSE as clock source of the PLL
312
  * @note   The application need to ensure that PLL is disabled.
313
  * @note   Function is based on the following formula:
314
  *         - PLL output frequency = ((HSI frequency / PREDIV) * PLLMUL)
315
  *         - PREDIV: Set to 2 for few devices
316
  *         - PLLMUL: The application software must set correctly the PLL multiplication factor to
317
  *                   not exceed @ref UTILS_PLL_OUTPUT_MAX
318
  * @note   FLASH latency can be modified through this function.
319
  * @param  HSEFrequency Value between Min_Data = RCC_HSE_MIN and Max_Data = RCC_HSE_MAX
320
  * @param  HSEBypass This parameter can be one of the following values:
321
  *         @arg @ref LL_UTILS_HSEBYPASS_ON
322
  *         @arg @ref LL_UTILS_HSEBYPASS_OFF
323
  * @param  UTILS_PLLInitStruct pointer to a @ref LL_UTILS_PLLInitTypeDef structure that contains
324
  *                             the configuration information for the PLL.
325
  * @param  UTILS_ClkInitStruct pointer to a @ref LL_UTILS_ClkInitTypeDef structure that contains
326
  *                             the configuration information for the BUS prescalers.
327
  * @retval An ErrorStatus enumeration value:
328
  *          - SUCCESS: Max frequency configuration done
329
  *          - ERROR: Max frequency configuration not done
330
  */
331
ErrorStatus LL_PLL_ConfigSystemClock_HSE(uint32_t HSEFrequency, uint32_t HSEBypass,
332
                                         LL_UTILS_PLLInitTypeDef *UTILS_PLLInitStruct, LL_UTILS_ClkInitTypeDef *UTILS_ClkInitStruct)
333
{
334
  ErrorStatus status = SUCCESS;
335
  uint32_t pllfreq = 0U;
336
 
337
  /* Check the parameters */
338
  assert_param(IS_LL_UTILS_HSE_FREQUENCY(HSEFrequency));
339
  assert_param(IS_LL_UTILS_HSE_BYPASS(HSEBypass));
340
 
341
  /* Check if one of the PLL is enabled */
342
  if (UTILS_PLL_IsBusy() == SUCCESS)
343
  {
344
    assert_param(IS_LL_UTILS_PREDIV_VALUE(UTILS_PLLInitStruct->Prediv));
345
 
346
    /* Calculate the new PLL output frequency */
347
    pllfreq = UTILS_GetPLLOutputFrequency(HSEFrequency, UTILS_PLLInitStruct);
348
 
349
    /* Enable HSE if not enabled */
350
    if (LL_RCC_HSE_IsReady() != 1U)
351
    {
352
      /* Check if need to enable HSE bypass feature or not */
353
      if (HSEBypass == LL_UTILS_HSEBYPASS_ON)
354
      {
355
        LL_RCC_HSE_EnableBypass();
356
      }
357
      else
358
      {
359
        LL_RCC_HSE_DisableBypass();
360
      }
361
 
362
      /* Enable HSE */
363
      LL_RCC_HSE_Enable();
364
      while (LL_RCC_HSE_IsReady() != 1U)
365
      {
366
        /* Wait for HSE ready */
367
      }
368
    }
369
 
370
    /* Configure PLL */
371
    LL_RCC_PLL_ConfigDomain_SYS((RCC_CFGR_PLLSRC | UTILS_PLLInitStruct->Prediv), UTILS_PLLInitStruct->PLLMul);
372
 
373
    /* Enable PLL and switch system clock to PLL */
374
    status = UTILS_EnablePLLAndSwitchSystem(pllfreq, UTILS_ClkInitStruct);
375
  }
376
  else
377
  {
378
    /* Current PLL configuration cannot be modified */
379
    status = ERROR;
380
  }
381
 
382
  return status;
383
}
384
 
385
/**
386
  * @}
387
  */
388
 
389
/**
390
  * @}
391
  */
392
 
393
/** @addtogroup UTILS_LL_Private_Functions
394
  * @{
395
  */
396
/**
397
  * @brief  Update number of Flash wait states in line with new frequency and current
398
            voltage range.
399
  * @param  Frequency  SYSCLK frequency
400
  * @retval An ErrorStatus enumeration value:
401
  *          - SUCCESS: Latency has been modified
402
  *          - ERROR: Latency cannot be modified
403
  */
404
#if defined(FLASH_ACR_LATENCY)
405
static ErrorStatus UTILS_SetFlashLatency(uint32_t Frequency)
406
{
407
  ErrorStatus status = SUCCESS;
408
 
409
  uint32_t latency = LL_FLASH_LATENCY_0;  /* default value 0WS */
410
 
411
  /* Frequency cannot be equal to 0 */
412
  if (Frequency == 0U)
413
  {
414
    status = ERROR;
415
  }
416
  else
417
  {
418
    if (Frequency > UTILS_LATENCY2_FREQ)
419
    {
420
      /* 48 < SYSCLK <= 72 => 2WS (3 CPU cycles) */
421
      latency = LL_FLASH_LATENCY_2;
422
    }
423
    else
424
    {
425
      if (Frequency > UTILS_LATENCY1_FREQ)
426
      {
427
        /* 24 < SYSCLK <= 48 => 1WS (2 CPU cycles) */
428
        latency = LL_FLASH_LATENCY_1;
429
      }
430
      /* else SYSCLK < 24MHz default LL_FLASH_LATENCY_0 0WS */
431
    }
432
 
433
    LL_FLASH_SetLatency(latency);
434
 
435
    /* Check that the new number of wait states is taken into account to access the Flash
436
       memory by reading the FLASH_ACR register */
437
    if (LL_FLASH_GetLatency() != latency)
438
    {
439
      status = ERROR;
440
    }
441
  }
442
  return status;
443
}
444
#endif /* FLASH_ACR_LATENCY */
445
 
446
/**
447
  * @brief  Function to check that PLL can be modified
448
  * @param  PLL_InputFrequency  PLL input frequency (in Hz)
449
  * @param  UTILS_PLLInitStruct pointer to a @ref LL_UTILS_PLLInitTypeDef structure that contains
450
  *                             the configuration information for the PLL.
451
  * @retval PLL output frequency (in Hz)
452
  */
453
static uint32_t UTILS_GetPLLOutputFrequency(uint32_t PLL_InputFrequency, LL_UTILS_PLLInitTypeDef *UTILS_PLLInitStruct)
454
{
455
  uint32_t pllfreq = 0U;
456
 
457
  /* Check the parameters */
458
  assert_param(IS_LL_UTILS_PLLMUL_VALUE(UTILS_PLLInitStruct->PLLMul));
459
 
460
  /* Check different PLL parameters according to RM                          */
461
#if defined (RCC_CFGR2_PREDIV1)
462
  pllfreq = __LL_RCC_CALC_PLLCLK_FREQ(PLL_InputFrequency / (UTILS_PLLInitStruct->Prediv + 1U), UTILS_PLLInitStruct->PLLMul);
463
#else
464
  pllfreq = __LL_RCC_CALC_PLLCLK_FREQ(PLL_InputFrequency / ((UTILS_PLLInitStruct->Prediv >> RCC_CFGR_PLLXTPRE_Pos) + 1U), UTILS_PLLInitStruct->PLLMul);
465
#endif /*RCC_CFGR2_PREDIV1SRC*/
466
  assert_param(IS_LL_UTILS_PLL_FREQUENCY(pllfreq));
467
 
468
  return pllfreq;
469
}
470
 
471
/**
472
  * @brief  Function to check that PLL can be modified
473
  * @retval An ErrorStatus enumeration value:
474
  *          - SUCCESS: PLL modification can be done
475
  *          - ERROR: PLL is busy
476
  */
477
static ErrorStatus UTILS_PLL_IsBusy(void)
478
{
479
  ErrorStatus status = SUCCESS;
480
 
481
  /* Check if PLL is busy*/
482
  if (LL_RCC_PLL_IsReady() != 0U)
483
  {
484
    /* PLL configuration cannot be modified */
485
    status = ERROR;
486
  }
487
#if defined(RCC_PLL2_SUPPORT)
488
  /* Check if PLL2 is busy*/
489
  if (LL_RCC_PLL2_IsReady() != 0U)
490
  {
491
    /* PLL2 configuration cannot be modified */
492
    status = ERROR;
493
  }
494
#endif /* RCC_PLL2_SUPPORT */
495
 
496
#if defined(RCC_PLLI2S_SUPPORT)
497
  /* Check if PLLI2S  is busy*/
498
  if (LL_RCC_PLLI2S_IsReady() != 0U)
499
  {
500
    /* PLLI2S configuration cannot be modified */
501
    status = ERROR;
502
  }
503
#endif /* RCC_PLLI2S_SUPPORT */
504
 
505
  return status;
506
}
507
 
508
/**
509
  * @brief  Function to enable PLL and switch system clock to PLL
510
  * @param  SYSCLK_Frequency SYSCLK frequency
511
  * @param  UTILS_ClkInitStruct pointer to a @ref LL_UTILS_ClkInitTypeDef structure that contains
512
  *                             the configuration information for the BUS prescalers.
513
  * @retval An ErrorStatus enumeration value:
514
  *          - SUCCESS: No problem to switch system to PLL
515
  *          - ERROR: Problem to switch system to PLL
516
  */
517
static ErrorStatus UTILS_EnablePLLAndSwitchSystem(uint32_t SYSCLK_Frequency, LL_UTILS_ClkInitTypeDef *UTILS_ClkInitStruct)
518
{
519
  ErrorStatus status = SUCCESS;
520
#if defined(FLASH_ACR_LATENCY)
521
  uint32_t sysclk_frequency_current = 0U;
522
#endif /* FLASH_ACR_LATENCY */
523
 
524
  assert_param(IS_LL_UTILS_SYSCLK_DIV(UTILS_ClkInitStruct->AHBCLKDivider));
525
  assert_param(IS_LL_UTILS_APB1_DIV(UTILS_ClkInitStruct->APB1CLKDivider));
526
  assert_param(IS_LL_UTILS_APB2_DIV(UTILS_ClkInitStruct->APB2CLKDivider));
527
 
528
#if defined(FLASH_ACR_LATENCY)
529
  /* Calculate current SYSCLK frequency */
530
  sysclk_frequency_current = (SystemCoreClock << AHBPrescTable[LL_RCC_GetAHBPrescaler() >> RCC_CFGR_HPRE_Pos]);
531
#endif /* FLASH_ACR_LATENCY */
532
 
533
  /* Increasing the number of wait states because of higher CPU frequency */
534
#if defined (FLASH_ACR_LATENCY)
535
  if (sysclk_frequency_current < SYSCLK_Frequency)
536
  {
537
    /* Set FLASH latency to highest latency */
538
    status = UTILS_SetFlashLatency(SYSCLK_Frequency);
539
  }
540
#endif /* FLASH_ACR_LATENCY */
541
 
542
  /* Update system clock configuration */
543
  if (status == SUCCESS)
544
  {
545
#if defined(RCC_PLL2_SUPPORT)
546
    if (LL_RCC_PLL_GetMainSource() != LL_RCC_PLLSOURCE_HSI_DIV_2)
547
    {
548
      /* Enable PLL2 */
549
      LL_RCC_PLL2_Enable();
550
      while (LL_RCC_PLL2_IsReady() != 1U)
551
      {
552
        /* Wait for PLL2 ready */
553
      }
554
    }
555
#endif /* RCC_PLL2_SUPPORT */
556
    /* Enable PLL */
557
    LL_RCC_PLL_Enable();
558
    while (LL_RCC_PLL_IsReady() != 1U)
559
    {
560
      /* Wait for PLL ready */
561
    }
562
 
563
    /* Sysclk activation on the main PLL */
564
    LL_RCC_SetAHBPrescaler(UTILS_ClkInitStruct->AHBCLKDivider);
565
    LL_RCC_SetSysClkSource(LL_RCC_SYS_CLKSOURCE_PLL);
566
    while (LL_RCC_GetSysClkSource() != LL_RCC_SYS_CLKSOURCE_STATUS_PLL)
567
    {
568
      /* Wait for system clock switch to PLL */
569
    }
570
 
571
    /* Set APB1 & APB2 prescaler*/
572
    LL_RCC_SetAPB1Prescaler(UTILS_ClkInitStruct->APB1CLKDivider);
573
    LL_RCC_SetAPB2Prescaler(UTILS_ClkInitStruct->APB2CLKDivider);
574
  }
575
 
576
  /* Decreasing the number of wait states because of lower CPU frequency */
577
#if defined (FLASH_ACR_LATENCY)
578
  if (sysclk_frequency_current > SYSCLK_Frequency)
579
  {
580
    /* Set FLASH latency to lowest latency */
581
    status = UTILS_SetFlashLatency(SYSCLK_Frequency);
582
  }
583
#endif /* FLASH_ACR_LATENCY */
584
 
585
  /* Update SystemCoreClock variable */
586
  if (status == SUCCESS)
587
  {
588
    LL_SetSystemCoreClock(__LL_RCC_CALC_HCLK_FREQ(SYSCLK_Frequency, UTILS_ClkInitStruct->AHBCLKDivider));
589
  }
590
 
591
  return status;
592
}
593
 
594
/**
595
  * @}
596
  */
597
 
598
/**
599
  * @}
600
  */
601
 
602
/**
603
  * @}
604
  */
605
 
606
/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/