Subversion Repositories LedShow

Rev

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