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_hal_rcc.c
4
  * @author  MCD Application Team
5
  * @brief   RCC HAL module driver.
6
  *          This file provides firmware functions to manage the following
7
  *          functionalities of the Reset and Clock Control (RCC) peripheral:
8
  *           + Initialization and de-initialization functions
9
  *           + Peripheral Control functions
10
  *
11
  @verbatim
12
  ==============================================================================
13
                      ##### RCC specific features #####
14
  ==============================================================================
15
    [..]
16
      After reset the device is running from Internal High Speed oscillator
17
      (HSI 8MHz) with Flash 0 wait state, Flash prefetch buffer is enabled,
18
      and all peripherals are off except internal SRAM, Flash and JTAG.
19
      (+) There is no prescaler on High speed (AHB) and Low speed (APB) buses;
20
          all peripherals mapped on these buses are running at HSI speed.
21
      (+) The clock for all peripherals is switched off, except the SRAM and FLASH.
22
      (+) All GPIOs are in input floating state, except the JTAG pins which
23
          are assigned to be used for debug purpose.
24
    [..] Once the device started from reset, the user application has to:
25
      (+) Configure the clock source to be used to drive the System clock
26
          (if the application needs higher frequency/performance)
27
      (+) Configure the System clock frequency and Flash settings
28
      (+) Configure the AHB and APB buses prescalers
29
      (+) Enable the clock for the peripheral(s) to be used
30
      (+) Configure the clock source(s) for peripherals whose clocks are not
31
          derived from the System clock (I2S, RTC, ADC, USB OTG FS)
32
 
33
                      ##### RCC Limitations #####
34
  ==============================================================================
35
    [..]
36
      A delay between an RCC peripheral clock enable and the effective peripheral
37
      enabling should be taken into account in order to manage the peripheral read/write
38
      from/to registers.
39
      (+) This delay depends on the peripheral mapping.
40
        (++) AHB & APB peripherals, 1 dummy read is necessary
41
 
42
    [..]
43
      Workarounds:
44
      (#) For AHB & APB peripherals, a dummy read to the peripheral register has been
45
          inserted in each __HAL_RCC_PPP_CLK_ENABLE() macro.
46
 
47
  @endverbatim
48
  ******************************************************************************
49
  * @attention
50
  *
51
  * <h2><center>&copy; Copyright (c) 2016 STMicroelectronics.
52
  * All rights reserved.</center></h2>
53
  *
54
  * This software component is licensed by ST under BSD 3-Clause license,
55
  * the "License"; You may not use this file except in compliance with the
56
  * License. You may obtain a copy of the License at:
57
  *                        opensource.org/licenses/BSD-3-Clause
58
  *
59
  ******************************************************************************
60
  */
61
 
62
/* Includes ------------------------------------------------------------------*/
63
#include "stm32f1xx_hal.h"
64
 
65
/** @addtogroup STM32F1xx_HAL_Driver
66
  * @{
67
  */
68
 
69
/** @defgroup RCC RCC
70
* @brief RCC HAL module driver
71
  * @{
72
  */
73
 
74
#ifdef HAL_RCC_MODULE_ENABLED
75
 
76
/* Private typedef -----------------------------------------------------------*/
77
/* Private define ------------------------------------------------------------*/
78
/** @defgroup RCC_Private_Constants RCC Private Constants
79
 * @{
80
 */
81
/**
82
  * @}
83
  */
84
/* Private macro -------------------------------------------------------------*/
85
/** @defgroup RCC_Private_Macros RCC Private Macros
86
  * @{
87
  */
88
 
89
#define MCO1_CLK_ENABLE()     __HAL_RCC_GPIOA_CLK_ENABLE()
90
#define MCO1_GPIO_PORT        GPIOA
91
#define MCO1_PIN              GPIO_PIN_8
92
 
93
/**
94
  * @}
95
  */
96
 
97
/* Private variables ---------------------------------------------------------*/
98
/** @defgroup RCC_Private_Variables RCC Private Variables
99
  * @{
100
  */
101
/**
102
  * @}
103
  */
104
 
105
/* Private function prototypes -----------------------------------------------*/
106
static void RCC_Delay(uint32_t mdelay);
107
 
108
/* Exported functions --------------------------------------------------------*/
109
 
110
/** @defgroup RCC_Exported_Functions RCC Exported Functions
111
  * @{
112
  */
113
 
114
/** @defgroup RCC_Exported_Functions_Group1 Initialization and de-initialization functions
115
  *  @brief    Initialization and Configuration functions
116
  *
117
  @verbatim
118
  ===============================================================================
119
           ##### Initialization and de-initialization functions #####
120
  ===============================================================================
121
    [..]
122
      This section provides functions allowing to configure the internal/external oscillators
123
      (HSE, HSI, LSE, LSI, PLL, CSS and MCO) and the System buses clocks (SYSCLK, AHB, APB1
124
      and APB2).
125
 
126
    [..] Internal/external clock and PLL configuration
127
      (#) HSI (high-speed internal), 8 MHz factory-trimmed RC used directly or through
128
          the PLL as System clock source.
129
      (#) LSI (low-speed internal), ~40 KHz low consumption RC used as IWDG and/or RTC
130
          clock source.
131
 
132
      (#) HSE (high-speed external), 4 to 24 MHz (STM32F100xx) or 4 to 16 MHz (STM32F101x/STM32F102x/STM32F103x) or 3 to 25 MHz (STM32F105x/STM32F107x)  crystal oscillator used directly or
133
          through the PLL as System clock source. Can be used also as RTC clock source.
134
 
135
      (#) LSE (low-speed external), 32 KHz oscillator used as RTC clock source.
136
 
137
      (#) PLL (clocked by HSI or HSE), featuring different output clocks:
138
        (++) The first output is used to generate the high speed system clock (up to 72 MHz for STM32F10xxx or up to 24 MHz for STM32F100xx)
139
        (++) The second output is used to generate the clock for the USB OTG FS (48 MHz)
140
 
141
      (#) CSS (Clock security system), once enable using the macro __HAL_RCC_CSS_ENABLE()
142
          and if a HSE clock failure occurs(HSE used directly or through PLL as System
143
          clock source), the System clocks automatically switched to HSI and an interrupt
144
          is generated if enabled. The interrupt is linked to the Cortex-M3 NMI
145
          (Non-Maskable Interrupt) exception vector.
146
 
147
      (#) MCO1 (microcontroller clock output), used to output SYSCLK, HSI,
148
          HSE or PLL clock (divided by 2) on PA8 pin + PLL2CLK, PLL3CLK/2, PLL3CLK and XTI for STM32F105x/STM32F107x
149
 
150
    [..] System, AHB and APB buses clocks configuration
151
      (#) Several clock sources can be used to drive the System clock (SYSCLK): HSI,
152
          HSE and PLL.
153
          The AHB clock (HCLK) is derived from System clock through configurable
154
          prescaler and used to clock the CPU, memory and peripherals mapped
155
          on AHB bus (DMA, GPIO...). APB1 (PCLK1) and APB2 (PCLK2) clocks are derived
156
          from AHB clock through configurable prescalers and used to clock
157
          the peripherals mapped on these buses. You can use
158
          "@ref HAL_RCC_GetSysClockFreq()" function to retrieve the frequencies of these clocks.
159
 
160
      -@- All the peripheral clocks are derived from the System clock (SYSCLK) except:
161
          (+@) RTC: RTC clock can be derived either from the LSI, LSE or HSE clock
162
              divided by 128.
163
          (+@) USB OTG FS and RTC: USB OTG FS require a frequency equal to 48 MHz
164
              to work correctly. This clock is derived of the main PLL through PLL Multiplier.
165
          (+@) I2S interface on STM32F105x/STM32F107x can be derived from PLL3CLK
166
          (+@) IWDG clock which is always the LSI clock.
167
 
168
      (#) For STM32F10xxx, the maximum frequency of the SYSCLK and HCLK/PCLK2 is 72 MHz, PCLK1 36 MHz.
169
          For STM32F100xx, the maximum frequency of the SYSCLK and HCLK/PCLK1/PCLK2 is 24 MHz.
170
          Depending on the SYSCLK frequency, the flash latency should be adapted accordingly.
171
  @endverbatim
172
  * @{
173
  */
174
 
175
/*
176
  Additional consideration on the SYSCLK based on Latency settings:
177
        +-----------------------------------------------+
178
        | Latency       | SYSCLK clock frequency (MHz)  |
179
        |---------------|-------------------------------|
180
        |0WS(1CPU cycle)|       0 < SYSCLK <= 24        |
181
        |---------------|-------------------------------|
182
        |1WS(2CPU cycle)|      24 < SYSCLK <= 48        |
183
        |---------------|-------------------------------|
184
        |2WS(3CPU cycle)|      48 < SYSCLK <= 72        |
185
        +-----------------------------------------------+
186
  */
187
 
188
/**
189
  * @brief  Resets the RCC clock configuration to the default reset state.
190
  * @note   The default reset state of the clock configuration is given below:
191
  *            - HSI ON and used as system clock source
192
  *            - HSE, PLL, PLL2 and PLL3 are OFF
193
  *            - AHB, APB1 and APB2 prescaler set to 1.
194
  *            - CSS and MCO1 OFF
195
  *            - All interrupts disabled
196
  *            - All flags are cleared
197
  * @note   This function does not modify the configuration of the
198
  *            - Peripheral clocks
199
  *            - LSI, LSE and RTC clocks
200
  * @retval HAL_StatusTypeDef
201
  */
202
HAL_StatusTypeDef HAL_RCC_DeInit(void)
203
{
204
  uint32_t tickstart;
205
 
206
  /* Get Start Tick */
207
  tickstart = HAL_GetTick();
208
 
209
  /* Set HSION bit */
210
  SET_BIT(RCC->CR, RCC_CR_HSION);
211
 
212
  /* Wait till HSI is ready */
213
  while (READ_BIT(RCC->CR, RCC_CR_HSIRDY) == RESET)
214
  {
215
    if ((HAL_GetTick() - tickstart) > HSI_TIMEOUT_VALUE)
216
    {
217
      return HAL_TIMEOUT;
218
    }
219
  }
220
 
221
  /* Set HSITRIM bits to the reset value */
222
  MODIFY_REG(RCC->CR, RCC_CR_HSITRIM, (0x10U << RCC_CR_HSITRIM_Pos));
223
 
224
  /* Get Start Tick */
225
  tickstart = HAL_GetTick();
226
 
227
  /* Reset CFGR register */
228
  CLEAR_REG(RCC->CFGR);
229
 
230
  /* Wait till clock switch is ready */
231
  while (READ_BIT(RCC->CFGR, RCC_CFGR_SWS) != RESET)
232
  {
233
    if ((HAL_GetTick() - tickstart) > CLOCKSWITCH_TIMEOUT_VALUE)
234
    {
235
      return HAL_TIMEOUT;
236
    }
237
  }
238
 
239
  /* Update the SystemCoreClock global variable */
240
  SystemCoreClock = HSI_VALUE;
241
 
242
  /* Adapt Systick interrupt period */
243
  if (HAL_InitTick(uwTickPrio) != HAL_OK)
244
  {
245
    return HAL_ERROR;
246
  }
247
 
248
  /* Get Start Tick */
249
  tickstart = HAL_GetTick();
250
 
251
  /* Second step is to clear PLLON bit */
252
  CLEAR_BIT(RCC->CR, RCC_CR_PLLON);
253
 
254
  /* Wait till PLL is disabled */
255
  while (READ_BIT(RCC->CR, RCC_CR_PLLRDY) != RESET)
256
  {
257
    if ((HAL_GetTick() - tickstart) > PLL_TIMEOUT_VALUE)
258
    {
259
      return HAL_TIMEOUT;
260
    }
261
  }
262
 
263
  /* Ensure to reset PLLSRC and PLLMUL bits */
264
  CLEAR_REG(RCC->CFGR);
265
 
266
  /* Get Start Tick */
267
  tickstart = HAL_GetTick();
268
 
269
  /* Reset HSEON & CSSON bits */
270
  CLEAR_BIT(RCC->CR, RCC_CR_HSEON | RCC_CR_CSSON);
271
 
272
  /* Wait till HSE is disabled */
273
  while (READ_BIT(RCC->CR, RCC_CR_HSERDY) != RESET)
274
  {
275
    if ((HAL_GetTick() - tickstart) > HSE_TIMEOUT_VALUE)
276
    {
277
      return HAL_TIMEOUT;
278
    }
279
  }
280
 
281
  /* Reset HSEBYP bit */
282
  CLEAR_BIT(RCC->CR, RCC_CR_HSEBYP);
283
 
284
#if defined(RCC_PLL2_SUPPORT)
285
  /* Get Start Tick */
286
  tickstart = HAL_GetTick();
287
 
288
  /* Clear PLL2ON bit */
289
  CLEAR_BIT(RCC->CR, RCC_CR_PLL2ON);
290
 
291
  /* Wait till PLL2 is disabled */
292
  while (READ_BIT(RCC->CR, RCC_CR_PLL2RDY) != RESET)
293
  {
294
    if ((HAL_GetTick() - tickstart) > PLL2_TIMEOUT_VALUE)
295
    {
296
      return HAL_TIMEOUT;
297
    }
298
  }
299
#endif /* RCC_PLL2_SUPPORT */
300
 
301
#if defined(RCC_PLLI2S_SUPPORT)
302
  /* Get Start Tick */
303
  tickstart = HAL_GetTick();
304
 
305
  /* Clear PLL3ON bit */
306
  CLEAR_BIT(RCC->CR, RCC_CR_PLL3ON);
307
 
308
  /* Wait till PLL3 is disabled */
309
  while (READ_BIT(RCC->CR, RCC_CR_PLL3RDY) != RESET)
310
  {
311
    if ((HAL_GetTick() - tickstart) > PLLI2S_TIMEOUT_VALUE)
312
    {
313
      return HAL_TIMEOUT;
314
    }
315
  }
316
#endif /* RCC_PLLI2S_SUPPORT */
317
 
318
#if defined(RCC_CFGR2_PREDIV1)
319
  /* Reset CFGR2 register */
320
  CLEAR_REG(RCC->CFGR2);
321
#endif /* RCC_CFGR2_PREDIV1 */
322
 
323
  /* Reset all CSR flags */
324
  SET_BIT(RCC->CSR, RCC_CSR_RMVF);
325
 
326
  /* Disable all interrupts */
327
  CLEAR_REG(RCC->CIR);
328
 
329
  return HAL_OK;
330
}
331
 
332
/**
333
  * @brief  Initializes the RCC Oscillators according to the specified parameters in the
334
  *         RCC_OscInitTypeDef.
335
  * @param  RCC_OscInitStruct pointer to an RCC_OscInitTypeDef structure that
336
  *         contains the configuration information for the RCC Oscillators.
337
  * @note   The PLL is not disabled when used as system clock.
338
  * @note   The PLL is not disabled when USB OTG FS clock is enabled (specific to devices with USB FS)
339
  * @note   Transitions LSE Bypass to LSE On and LSE On to LSE Bypass are not
340
  *         supported by this macro. User should request a transition to LSE Off
341
  *         first and then LSE On or LSE Bypass.
342
  * @note   Transition HSE Bypass to HSE On and HSE On to HSE Bypass are not
343
  *         supported by this macro. User should request a transition to HSE Off
344
  *         first and then HSE On or HSE Bypass.
345
  * @retval HAL status
346
  */
347
HAL_StatusTypeDef HAL_RCC_OscConfig(RCC_OscInitTypeDef  *RCC_OscInitStruct)
348
{
349
  uint32_t tickstart;
350
  uint32_t pll_config;
351
 
352
  /* Check Null pointer */
353
  if (RCC_OscInitStruct == NULL)
354
  {
355
    return HAL_ERROR;
356
  }
357
 
358
  /* Check the parameters */
359
  assert_param(IS_RCC_OSCILLATORTYPE(RCC_OscInitStruct->OscillatorType));
360
 
361
  /*------------------------------- HSE Configuration ------------------------*/
362
  if (((RCC_OscInitStruct->OscillatorType) & RCC_OSCILLATORTYPE_HSE) == RCC_OSCILLATORTYPE_HSE)
363
  {
364
    /* Check the parameters */
365
    assert_param(IS_RCC_HSE(RCC_OscInitStruct->HSEState));
366
 
367
    /* When the HSE is used as system clock or clock source for PLL in these cases it is not allowed to be disabled */
368
    if ((__HAL_RCC_GET_SYSCLK_SOURCE() == RCC_SYSCLKSOURCE_STATUS_HSE)
369
        || ((__HAL_RCC_GET_SYSCLK_SOURCE() == RCC_SYSCLKSOURCE_STATUS_PLLCLK) && (__HAL_RCC_GET_PLL_OSCSOURCE() == RCC_PLLSOURCE_HSE)))
370
    {
371
      if ((__HAL_RCC_GET_FLAG(RCC_FLAG_HSERDY) != RESET) && (RCC_OscInitStruct->HSEState == RCC_HSE_OFF))
372
      {
373
        return HAL_ERROR;
374
      }
375
    }
376
    else
377
    {
378
      /* Set the new HSE configuration ---------------------------------------*/
379
      __HAL_RCC_HSE_CONFIG(RCC_OscInitStruct->HSEState);
380
 
381
 
382
      /* Check the HSE State */
383
      if (RCC_OscInitStruct->HSEState != RCC_HSE_OFF)
384
      {
385
        /* Get Start Tick */
386
        tickstart = HAL_GetTick();
387
 
388
        /* Wait till HSE is ready */
389
        while (__HAL_RCC_GET_FLAG(RCC_FLAG_HSERDY) == RESET)
390
        {
391
          if ((HAL_GetTick() - tickstart) > HSE_TIMEOUT_VALUE)
392
          {
393
            return HAL_TIMEOUT;
394
          }
395
        }
396
      }
397
      else
398
      {
399
        /* Get Start Tick */
400
        tickstart = HAL_GetTick();
401
 
402
        /* Wait till HSE is disabled */
403
        while (__HAL_RCC_GET_FLAG(RCC_FLAG_HSERDY) != RESET)
404
        {
405
          if ((HAL_GetTick() - tickstart) > HSE_TIMEOUT_VALUE)
406
          {
407
            return HAL_TIMEOUT;
408
          }
409
        }
410
      }
411
    }
412
  }
413
  /*----------------------------- HSI Configuration --------------------------*/
414
  if (((RCC_OscInitStruct->OscillatorType) & RCC_OSCILLATORTYPE_HSI) == RCC_OSCILLATORTYPE_HSI)
415
  {
416
    /* Check the parameters */
417
    assert_param(IS_RCC_HSI(RCC_OscInitStruct->HSIState));
418
    assert_param(IS_RCC_CALIBRATION_VALUE(RCC_OscInitStruct->HSICalibrationValue));
419
 
420
    /* Check if HSI is used as system clock or as PLL source when PLL is selected as system clock */
421
    if ((__HAL_RCC_GET_SYSCLK_SOURCE() == RCC_SYSCLKSOURCE_STATUS_HSI)
422
        || ((__HAL_RCC_GET_SYSCLK_SOURCE() == RCC_SYSCLKSOURCE_STATUS_PLLCLK) && (__HAL_RCC_GET_PLL_OSCSOURCE() == RCC_PLLSOURCE_HSI_DIV2)))
423
    {
424
      /* When HSI is used as system clock it will not disabled */
425
      if ((__HAL_RCC_GET_FLAG(RCC_FLAG_HSIRDY) != RESET) && (RCC_OscInitStruct->HSIState != RCC_HSI_ON))
426
      {
427
        return HAL_ERROR;
428
      }
429
      /* Otherwise, just the calibration is allowed */
430
      else
431
      {
432
        /* Adjusts the Internal High Speed oscillator (HSI) calibration value.*/
433
        __HAL_RCC_HSI_CALIBRATIONVALUE_ADJUST(RCC_OscInitStruct->HSICalibrationValue);
434
      }
435
    }
436
    else
437
    {
438
      /* Check the HSI State */
439
      if (RCC_OscInitStruct->HSIState != RCC_HSI_OFF)
440
      {
441
        /* Enable the Internal High Speed oscillator (HSI). */
442
        __HAL_RCC_HSI_ENABLE();
443
 
444
        /* Get Start Tick */
445
        tickstart = HAL_GetTick();
446
 
447
        /* Wait till HSI is ready */
448
        while (__HAL_RCC_GET_FLAG(RCC_FLAG_HSIRDY) == RESET)
449
        {
450
          if ((HAL_GetTick() - tickstart) > HSI_TIMEOUT_VALUE)
451
          {
452
            return HAL_TIMEOUT;
453
          }
454
        }
455
 
456
        /* Adjusts the Internal High Speed oscillator (HSI) calibration value.*/
457
        __HAL_RCC_HSI_CALIBRATIONVALUE_ADJUST(RCC_OscInitStruct->HSICalibrationValue);
458
      }
459
      else
460
      {
461
        /* Disable the Internal High Speed oscillator (HSI). */
462
        __HAL_RCC_HSI_DISABLE();
463
 
464
        /* Get Start Tick */
465
        tickstart = HAL_GetTick();
466
 
467
        /* Wait till HSI is disabled */
468
        while (__HAL_RCC_GET_FLAG(RCC_FLAG_HSIRDY) != RESET)
469
        {
470
          if ((HAL_GetTick() - tickstart) > HSI_TIMEOUT_VALUE)
471
          {
472
            return HAL_TIMEOUT;
473
          }
474
        }
475
      }
476
    }
477
  }
478
  /*------------------------------ LSI Configuration -------------------------*/
479
  if (((RCC_OscInitStruct->OscillatorType) & RCC_OSCILLATORTYPE_LSI) == RCC_OSCILLATORTYPE_LSI)
480
  {
481
    /* Check the parameters */
482
    assert_param(IS_RCC_LSI(RCC_OscInitStruct->LSIState));
483
 
484
    /* Check the LSI State */
485
    if (RCC_OscInitStruct->LSIState != RCC_LSI_OFF)
486
    {
487
      /* Enable the Internal Low Speed oscillator (LSI). */
488
      __HAL_RCC_LSI_ENABLE();
489
 
490
      /* Get Start Tick */
491
      tickstart = HAL_GetTick();
492
 
493
      /* Wait till LSI is ready */
494
      while (__HAL_RCC_GET_FLAG(RCC_FLAG_LSIRDY) == RESET)
495
      {
496
        if ((HAL_GetTick() - tickstart) > LSI_TIMEOUT_VALUE)
497
        {
498
          return HAL_TIMEOUT;
499
        }
500
      }
501
      /*  To have a fully stabilized clock in the specified range, a software delay of 1ms
502
          should be added.*/
503
      RCC_Delay(1);
504
    }
505
    else
506
    {
507
      /* Disable the Internal Low Speed oscillator (LSI). */
508
      __HAL_RCC_LSI_DISABLE();
509
 
510
      /* Get Start Tick */
511
      tickstart = HAL_GetTick();
512
 
513
      /* Wait till LSI is disabled */
514
      while (__HAL_RCC_GET_FLAG(RCC_FLAG_LSIRDY) != RESET)
515
      {
516
        if ((HAL_GetTick() - tickstart) > LSI_TIMEOUT_VALUE)
517
        {
518
          return HAL_TIMEOUT;
519
        }
520
      }
521
    }
522
  }
523
  /*------------------------------ LSE Configuration -------------------------*/
524
  if (((RCC_OscInitStruct->OscillatorType) & RCC_OSCILLATORTYPE_LSE) == RCC_OSCILLATORTYPE_LSE)
525
  {
526
    FlagStatus       pwrclkchanged = RESET;
527
 
528
    /* Check the parameters */
529
    assert_param(IS_RCC_LSE(RCC_OscInitStruct->LSEState));
530
 
531
    /* Update LSE configuration in Backup Domain control register    */
532
    /* Requires to enable write access to Backup Domain of necessary */
533
    if (__HAL_RCC_PWR_IS_CLK_DISABLED())
534
    {
535
      __HAL_RCC_PWR_CLK_ENABLE();
536
      pwrclkchanged = SET;
537
    }
538
 
539
    if (HAL_IS_BIT_CLR(PWR->CR, PWR_CR_DBP))
540
    {
541
      /* Enable write access to Backup domain */
542
      SET_BIT(PWR->CR, PWR_CR_DBP);
543
 
544
      /* Wait for Backup domain Write protection disable */
545
      tickstart = HAL_GetTick();
546
 
547
      while (HAL_IS_BIT_CLR(PWR->CR, PWR_CR_DBP))
548
      {
549
        if ((HAL_GetTick() - tickstart) > RCC_DBP_TIMEOUT_VALUE)
550
        {
551
          return HAL_TIMEOUT;
552
        }
553
      }
554
    }
555
 
556
    /* Set the new LSE configuration -----------------------------------------*/
557
    __HAL_RCC_LSE_CONFIG(RCC_OscInitStruct->LSEState);
558
    /* Check the LSE State */
559
    if (RCC_OscInitStruct->LSEState != RCC_LSE_OFF)
560
    {
561
      /* Get Start Tick */
562
      tickstart = HAL_GetTick();
563
 
564
      /* Wait till LSE is ready */
565
      while (__HAL_RCC_GET_FLAG(RCC_FLAG_LSERDY) == RESET)
566
      {
567
        if ((HAL_GetTick() - tickstart) > RCC_LSE_TIMEOUT_VALUE)
568
        {
569
          return HAL_TIMEOUT;
570
        }
571
      }
572
    }
573
    else
574
    {
575
      /* Get Start Tick */
576
      tickstart = HAL_GetTick();
577
 
578
      /* Wait till LSE is disabled */
579
      while (__HAL_RCC_GET_FLAG(RCC_FLAG_LSERDY) != RESET)
580
      {
581
        if ((HAL_GetTick() - tickstart) > RCC_LSE_TIMEOUT_VALUE)
582
        {
583
          return HAL_TIMEOUT;
584
        }
585
      }
586
    }
587
 
588
    /* Require to disable power clock if necessary */
589
    if (pwrclkchanged == SET)
590
    {
591
      __HAL_RCC_PWR_CLK_DISABLE();
592
    }
593
  }
594
 
595
#if defined(RCC_CR_PLL2ON)
596
  /*-------------------------------- PLL2 Configuration -----------------------*/
597
  /* Check the parameters */
598
  assert_param(IS_RCC_PLL2(RCC_OscInitStruct->PLL2.PLL2State));
599
  if ((RCC_OscInitStruct->PLL2.PLL2State) != RCC_PLL2_NONE)
600
  {
601
    /* This bit can not be cleared if the PLL2 clock is used indirectly as system
602
      clock (i.e. it is used as PLL clock entry that is used as system clock). */
603
    if ((__HAL_RCC_GET_PLL_OSCSOURCE() == RCC_PLLSOURCE_HSE) && \
604
        (__HAL_RCC_GET_SYSCLK_SOURCE() == RCC_SYSCLKSOURCE_STATUS_PLLCLK) && \
605
        ((READ_BIT(RCC->CFGR2, RCC_CFGR2_PREDIV1SRC)) == RCC_CFGR2_PREDIV1SRC_PLL2))
606
    {
607
      return HAL_ERROR;
608
    }
609
    else
610
    {
611
      if ((RCC_OscInitStruct->PLL2.PLL2State) == RCC_PLL2_ON)
612
      {
613
        /* Check the parameters */
614
        assert_param(IS_RCC_PLL2_MUL(RCC_OscInitStruct->PLL2.PLL2MUL));
615
        assert_param(IS_RCC_HSE_PREDIV2(RCC_OscInitStruct->PLL2.HSEPrediv2Value));
616
 
617
        /* Prediv2 can be written only when the PLLI2S is disabled. */
618
        /* Return an error only if new value is different from the programmed value */
619
        if (HAL_IS_BIT_SET(RCC->CR, RCC_CR_PLL3ON) && \
620
            (__HAL_RCC_HSE_GET_PREDIV2() != RCC_OscInitStruct->PLL2.HSEPrediv2Value))
621
        {
622
          return HAL_ERROR;
623
        }
624
 
625
        /* Disable the main PLL2. */
626
        __HAL_RCC_PLL2_DISABLE();
627
 
628
        /* Get Start Tick */
629
        tickstart = HAL_GetTick();
630
 
631
        /* Wait till PLL2 is disabled */
632
        while (__HAL_RCC_GET_FLAG(RCC_FLAG_PLL2RDY) != RESET)
633
        {
634
          if ((HAL_GetTick() - tickstart) > PLL2_TIMEOUT_VALUE)
635
          {
636
            return HAL_TIMEOUT;
637
          }
638
        }
639
 
640
        /* Configure the HSE prediv2 factor --------------------------------*/
641
        __HAL_RCC_HSE_PREDIV2_CONFIG(RCC_OscInitStruct->PLL2.HSEPrediv2Value);
642
 
643
        /* Configure the main PLL2 multiplication factors. */
644
        __HAL_RCC_PLL2_CONFIG(RCC_OscInitStruct->PLL2.PLL2MUL);
645
 
646
        /* Enable the main PLL2. */
647
        __HAL_RCC_PLL2_ENABLE();
648
 
649
        /* Get Start Tick */
650
        tickstart = HAL_GetTick();
651
 
652
        /* Wait till PLL2 is ready */
653
        while (__HAL_RCC_GET_FLAG(RCC_FLAG_PLL2RDY)  == RESET)
654
        {
655
          if ((HAL_GetTick() - tickstart) > PLL2_TIMEOUT_VALUE)
656
          {
657
            return HAL_TIMEOUT;
658
          }
659
        }
660
      }
661
      else
662
      {
663
        /* Set PREDIV1 source to HSE */
664
        CLEAR_BIT(RCC->CFGR2, RCC_CFGR2_PREDIV1SRC);
665
 
666
        /* Disable the main PLL2. */
667
        __HAL_RCC_PLL2_DISABLE();
668
 
669
        /* Get Start Tick */
670
        tickstart = HAL_GetTick();
671
 
672
        /* Wait till PLL2 is disabled */
673
        while (__HAL_RCC_GET_FLAG(RCC_FLAG_PLL2RDY)  != RESET)
674
        {
675
          if ((HAL_GetTick() - tickstart) > PLL2_TIMEOUT_VALUE)
676
          {
677
            return HAL_TIMEOUT;
678
          }
679
        }
680
      }
681
    }
682
  }
683
 
684
#endif /* RCC_CR_PLL2ON */
685
  /*-------------------------------- PLL Configuration -----------------------*/
686
  /* Check the parameters */
687
  assert_param(IS_RCC_PLL(RCC_OscInitStruct->PLL.PLLState));
688
  if ((RCC_OscInitStruct->PLL.PLLState) != RCC_PLL_NONE)
689
  {
690
    /* Check if the PLL is used as system clock or not */
691
    if (__HAL_RCC_GET_SYSCLK_SOURCE() != RCC_SYSCLKSOURCE_STATUS_PLLCLK)
692
    {
693
      if ((RCC_OscInitStruct->PLL.PLLState) == RCC_PLL_ON)
694
      {
695
        /* Check the parameters */
696
        assert_param(IS_RCC_PLLSOURCE(RCC_OscInitStruct->PLL.PLLSource));
697
        assert_param(IS_RCC_PLL_MUL(RCC_OscInitStruct->PLL.PLLMUL));
698
 
699
        /* Disable the main PLL. */
700
        __HAL_RCC_PLL_DISABLE();
701
 
702
        /* Get Start Tick */
703
        tickstart = HAL_GetTick();
704
 
705
        /* Wait till PLL is disabled */
706
        while (__HAL_RCC_GET_FLAG(RCC_FLAG_PLLRDY)  != RESET)
707
        {
708
          if ((HAL_GetTick() - tickstart) > PLL_TIMEOUT_VALUE)
709
          {
710
            return HAL_TIMEOUT;
711
          }
712
        }
713
 
714
        /* Configure the HSE prediv factor --------------------------------*/
715
        /* It can be written only when the PLL is disabled. Not used in PLL source is different than HSE */
716
        if (RCC_OscInitStruct->PLL.PLLSource == RCC_PLLSOURCE_HSE)
717
        {
718
          /* Check the parameter */
719
          assert_param(IS_RCC_HSE_PREDIV(RCC_OscInitStruct->HSEPredivValue));
720
#if defined(RCC_CFGR2_PREDIV1SRC)
721
          assert_param(IS_RCC_PREDIV1_SOURCE(RCC_OscInitStruct->Prediv1Source));
722
 
723
          /* Set PREDIV1 source */
724
          SET_BIT(RCC->CFGR2, RCC_OscInitStruct->Prediv1Source);
725
#endif /* RCC_CFGR2_PREDIV1SRC */
726
 
727
          /* Set PREDIV1 Value */
728
          __HAL_RCC_HSE_PREDIV_CONFIG(RCC_OscInitStruct->HSEPredivValue);
729
        }
730
 
731
        /* Configure the main PLL clock source and multiplication factors. */
732
        __HAL_RCC_PLL_CONFIG(RCC_OscInitStruct->PLL.PLLSource,
733
                             RCC_OscInitStruct->PLL.PLLMUL);
734
        /* Enable the main PLL. */
735
        __HAL_RCC_PLL_ENABLE();
736
 
737
        /* Get Start Tick */
738
        tickstart = HAL_GetTick();
739
 
740
        /* Wait till PLL is ready */
741
        while (__HAL_RCC_GET_FLAG(RCC_FLAG_PLLRDY)  == RESET)
742
        {
743
          if ((HAL_GetTick() - tickstart) > PLL_TIMEOUT_VALUE)
744
          {
745
            return HAL_TIMEOUT;
746
          }
747
        }
748
      }
749
      else
750
      {
751
        /* Disable the main PLL. */
752
        __HAL_RCC_PLL_DISABLE();
753
 
754
        /* Get Start Tick */
755
        tickstart = HAL_GetTick();
756
 
757
        /* Wait till PLL is disabled */
758
        while (__HAL_RCC_GET_FLAG(RCC_FLAG_PLLRDY)  != RESET)
759
        {
760
          if ((HAL_GetTick() - tickstart) > PLL_TIMEOUT_VALUE)
761
          {
762
            return HAL_TIMEOUT;
763
          }
764
        }
765
      }
766
    }
767
    else
768
    {
769
      /* Check if there is a request to disable the PLL used as System clock source */
770
      if ((RCC_OscInitStruct->PLL.PLLState) == RCC_PLL_OFF)
771
      {
772
        return HAL_ERROR;
773
      }
774
      else
775
      {
776
        /* Do not return HAL_ERROR if request repeats the current configuration */
777
        pll_config = RCC->CFGR;
778
        if ((READ_BIT(pll_config, RCC_CFGR_PLLSRC) != RCC_OscInitStruct->PLL.PLLSource) ||
779
            (READ_BIT(pll_config, RCC_CFGR_PLLMULL) != RCC_OscInitStruct->PLL.PLLMUL))
780
        {
781
          return HAL_ERROR;
782
        }
783
      }
784
    }
785
  }
786
 
787
  return HAL_OK;
788
}
789
 
790
/**
791
  * @brief  Initializes the CPU, AHB and APB buses clocks according to the specified
792
  *         parameters in the RCC_ClkInitStruct.
793
  * @param  RCC_ClkInitStruct pointer to an RCC_OscInitTypeDef structure that
794
  *         contains the configuration information for the RCC peripheral.
795
  * @param  FLatency FLASH Latency
796
  *          The value of this parameter depend on device used within the same series
797
  * @note   The SystemCoreClock CMSIS variable is used to store System Clock Frequency
798
  *         and updated by @ref HAL_RCC_GetHCLKFreq() function called within this function
799
  *
800
  * @note   The HSI is used (enabled by hardware) as system clock source after
801
  *         start-up from Reset, wake-up from STOP and STANDBY mode, or in case
802
  *         of failure of the HSE used directly or indirectly as system clock
803
  *         (if the Clock Security System CSS is enabled).
804
  *
805
  * @note   A switch from one clock source to another occurs only if the target
806
  *         clock source is ready (clock stable after start-up delay or PLL locked).
807
  *         If a clock source which is not yet ready is selected, the switch will
808
  *         occur when the clock source will be ready.
809
  *         You can use @ref HAL_RCC_GetClockConfig() function to know which clock is
810
  *         currently used as system clock source.
811
  * @retval HAL status
812
  */
813
HAL_StatusTypeDef HAL_RCC_ClockConfig(RCC_ClkInitTypeDef  *RCC_ClkInitStruct, uint32_t FLatency)
814
{
815
  uint32_t tickstart;
816
 
817
  /* Check Null pointer */
818
  if (RCC_ClkInitStruct == NULL)
819
  {
820
    return HAL_ERROR;
821
  }
822
 
823
  /* Check the parameters */
824
  assert_param(IS_RCC_CLOCKTYPE(RCC_ClkInitStruct->ClockType));
825
  assert_param(IS_FLASH_LATENCY(FLatency));
826
 
827
  /* To correctly read data from FLASH memory, the number of wait states (LATENCY)
828
  must be correctly programmed according to the frequency of the CPU clock
829
    (HCLK) of the device. */
830
 
831
#if defined(FLASH_ACR_LATENCY)
832
  /* Increasing the number of wait states because of higher CPU frequency */
833
  if (FLatency > __HAL_FLASH_GET_LATENCY())
834
  {
835
    /* Program the new number of wait states to the LATENCY bits in the FLASH_ACR register */
836
    __HAL_FLASH_SET_LATENCY(FLatency);
837
 
838
    /* Check that the new number of wait states is taken into account to access the Flash
839
    memory by reading the FLASH_ACR register */
840
    if (__HAL_FLASH_GET_LATENCY() != FLatency)
841
  {
842
    return HAL_ERROR;
843
  }
844
}
845
 
846
#endif /* FLASH_ACR_LATENCY */
847
/*-------------------------- HCLK Configuration --------------------------*/
848
if (((RCC_ClkInitStruct->ClockType) & RCC_CLOCKTYPE_HCLK) == RCC_CLOCKTYPE_HCLK)
849
  {
850
    /* Set the highest APBx dividers in order to ensure that we do not go through
851
    a non-spec phase whatever we decrease or increase HCLK. */
852
    if (((RCC_ClkInitStruct->ClockType) & RCC_CLOCKTYPE_PCLK1) == RCC_CLOCKTYPE_PCLK1)
853
    {
854
      MODIFY_REG(RCC->CFGR, RCC_CFGR_PPRE1, RCC_HCLK_DIV16);
855
    }
856
 
857
    if (((RCC_ClkInitStruct->ClockType) & RCC_CLOCKTYPE_PCLK2) == RCC_CLOCKTYPE_PCLK2)
858
    {
859
      MODIFY_REG(RCC->CFGR, RCC_CFGR_PPRE2, (RCC_HCLK_DIV16 << 3));
860
    }
861
 
862
    /* Set the new HCLK clock divider */
863
    assert_param(IS_RCC_HCLK(RCC_ClkInitStruct->AHBCLKDivider));
864
    MODIFY_REG(RCC->CFGR, RCC_CFGR_HPRE, RCC_ClkInitStruct->AHBCLKDivider);
865
  }
866
 
867
  /*------------------------- SYSCLK Configuration ---------------------------*/
868
  if (((RCC_ClkInitStruct->ClockType) & RCC_CLOCKTYPE_SYSCLK) == RCC_CLOCKTYPE_SYSCLK)
869
  {
870
    assert_param(IS_RCC_SYSCLKSOURCE(RCC_ClkInitStruct->SYSCLKSource));
871
 
872
    /* HSE is selected as System Clock Source */
873
    if (RCC_ClkInitStruct->SYSCLKSource == RCC_SYSCLKSOURCE_HSE)
874
    {
875
      /* Check the HSE ready flag */
876
      if (__HAL_RCC_GET_FLAG(RCC_FLAG_HSERDY) == RESET)
877
      {
878
        return HAL_ERROR;
879
      }
880
    }
881
    /* PLL is selected as System Clock Source */
882
    else if (RCC_ClkInitStruct->SYSCLKSource == RCC_SYSCLKSOURCE_PLLCLK)
883
    {
884
      /* Check the PLL ready flag */
885
      if (__HAL_RCC_GET_FLAG(RCC_FLAG_PLLRDY) == RESET)
886
      {
887
        return HAL_ERROR;
888
      }
889
    }
890
    /* HSI is selected as System Clock Source */
891
    else
892
    {
893
      /* Check the HSI ready flag */
894
      if (__HAL_RCC_GET_FLAG(RCC_FLAG_HSIRDY) == RESET)
895
      {
896
        return HAL_ERROR;
897
      }
898
    }
899
    __HAL_RCC_SYSCLK_CONFIG(RCC_ClkInitStruct->SYSCLKSource);
900
 
901
    /* Get Start Tick */
902
    tickstart = HAL_GetTick();
903
 
904
    while (__HAL_RCC_GET_SYSCLK_SOURCE() != (RCC_ClkInitStruct->SYSCLKSource << RCC_CFGR_SWS_Pos))
905
    {
906
      if ((HAL_GetTick() - tickstart) > CLOCKSWITCH_TIMEOUT_VALUE)
907
      {
908
        return HAL_TIMEOUT;
909
      }
910
    }
911
  }
912
 
913
#if defined(FLASH_ACR_LATENCY)
914
  /* Decreasing the number of wait states because of lower CPU frequency */
915
  if (FLatency < __HAL_FLASH_GET_LATENCY())
916
  {
917
    /* Program the new number of wait states to the LATENCY bits in the FLASH_ACR register */
918
    __HAL_FLASH_SET_LATENCY(FLatency);
919
 
920
    /* Check that the new number of wait states is taken into account to access the Flash
921
    memory by reading the FLASH_ACR register */
922
    if (__HAL_FLASH_GET_LATENCY() != FLatency)
923
  {
924
    return HAL_ERROR;
925
  }
926
}
927
#endif /* FLASH_ACR_LATENCY */
928
 
929
/*-------------------------- PCLK1 Configuration ---------------------------*/
930
if (((RCC_ClkInitStruct->ClockType) & RCC_CLOCKTYPE_PCLK1) == RCC_CLOCKTYPE_PCLK1)
931
  {
932
    assert_param(IS_RCC_PCLK(RCC_ClkInitStruct->APB1CLKDivider));
933
    MODIFY_REG(RCC->CFGR, RCC_CFGR_PPRE1, RCC_ClkInitStruct->APB1CLKDivider);
934
  }
935
 
936
  /*-------------------------- PCLK2 Configuration ---------------------------*/
937
  if (((RCC_ClkInitStruct->ClockType) & RCC_CLOCKTYPE_PCLK2) == RCC_CLOCKTYPE_PCLK2)
938
  {
939
    assert_param(IS_RCC_PCLK(RCC_ClkInitStruct->APB2CLKDivider));
940
    MODIFY_REG(RCC->CFGR, RCC_CFGR_PPRE2, ((RCC_ClkInitStruct->APB2CLKDivider) << 3));
941
  }
942
 
943
  /* Update the SystemCoreClock global variable */
944
  SystemCoreClock = HAL_RCC_GetSysClockFreq() >> AHBPrescTable[(RCC->CFGR & RCC_CFGR_HPRE) >> RCC_CFGR_HPRE_Pos];
945
 
946
  /* Configure the source of time base considering new system clocks settings*/
947
  HAL_InitTick(uwTickPrio);
948
 
949
  return HAL_OK;
950
}
951
 
952
/**
953
  * @}
954
  */
955
 
956
/** @defgroup RCC_Exported_Functions_Group2 Peripheral Control functions
957
  *  @brief   RCC clocks control functions
958
  *
959
  @verbatim
960
  ===============================================================================
961
                  ##### Peripheral Control functions #####
962
  ===============================================================================
963
    [..]
964
    This subsection provides a set of functions allowing to control the RCC Clocks
965
    frequencies.
966
 
967
  @endverbatim
968
  * @{
969
  */
970
 
971
/**
972
  * @brief  Selects the clock source to output on MCO pin.
973
  * @note   MCO pin should be configured in alternate function mode.
974
  * @param  RCC_MCOx specifies the output direction for the clock source.
975
  *          This parameter can be one of the following values:
976
  *            @arg @ref RCC_MCO1 Clock source to output on MCO1 pin(PA8).
977
  * @param  RCC_MCOSource specifies the clock source to output.
978
  *          This parameter can be one of the following values:
979
  *            @arg @ref RCC_MCO1SOURCE_NOCLOCK     No clock selected as MCO clock
980
  *            @arg @ref RCC_MCO1SOURCE_SYSCLK      System clock selected as MCO clock
981
  *            @arg @ref RCC_MCO1SOURCE_HSI         HSI selected as MCO clock
982
  *            @arg @ref RCC_MCO1SOURCE_HSE         HSE selected as MCO clock
983
  @if STM32F105xC
984
  *            @arg @ref RCC_MCO1SOURCE_PLLCLK       PLL clock divided by 2 selected as MCO source
985
  *            @arg @ref RCC_MCO1SOURCE_PLL2CLK      PLL2 clock selected as MCO source
986
  *            @arg @ref RCC_MCO1SOURCE_PLL3CLK_DIV2 PLL3 clock divided by 2 selected as MCO source
987
  *            @arg @ref RCC_MCO1SOURCE_EXT_HSE      XT1 external 3-25 MHz oscillator clock selected as MCO source
988
  *            @arg @ref RCC_MCO1SOURCE_PLL3CLK      PLL3 clock selected as MCO source
989
  @endif
990
  @if STM32F107xC
991
  *            @arg @ref RCC_MCO1SOURCE_PLLCLK       PLL clock divided by 2 selected as MCO source
992
  *            @arg @ref RCC_MCO1SOURCE_PLL2CLK      PLL2 clock selected as MCO source
993
  *            @arg @ref RCC_MCO1SOURCE_PLL3CLK_DIV2 PLL3 clock divided by 2 selected as MCO source
994
  *            @arg @ref RCC_MCO1SOURCE_EXT_HSE XT1  external 3-25 MHz oscillator clock selected as MCO source
995
  *            @arg @ref RCC_MCO1SOURCE_PLL3CLK      PLL3 clock selected as MCO source
996
  @endif
997
  * @param  RCC_MCODiv specifies the MCO DIV.
998
  *          This parameter can be one of the following values:
999
  *            @arg @ref RCC_MCODIV_1 no division applied to MCO clock
1000
  * @retval None
1001
  */
1002
void HAL_RCC_MCOConfig(uint32_t RCC_MCOx, uint32_t RCC_MCOSource, uint32_t RCC_MCODiv)
1003
{
1004
  GPIO_InitTypeDef gpio = {0U};
1005
 
1006
  /* Check the parameters */
1007
  assert_param(IS_RCC_MCO(RCC_MCOx));
1008
  assert_param(IS_RCC_MCODIV(RCC_MCODiv));
1009
  assert_param(IS_RCC_MCO1SOURCE(RCC_MCOSource));
1010
 
1011
  /* Prevent unused argument(s) compilation warning */
1012
  UNUSED(RCC_MCOx);
1013
  UNUSED(RCC_MCODiv);
1014
 
1015
  /* Configure the MCO1 pin in alternate function mode */
1016
  gpio.Mode      = GPIO_MODE_AF_PP;
1017
  gpio.Speed     = GPIO_SPEED_FREQ_HIGH;
1018
  gpio.Pull      = GPIO_NOPULL;
1019
  gpio.Pin       = MCO1_PIN;
1020
 
1021
  /* MCO1 Clock Enable */
1022
  MCO1_CLK_ENABLE();
1023
 
1024
  HAL_GPIO_Init(MCO1_GPIO_PORT, &gpio);
1025
 
1026
  /* Configure the MCO clock source */
1027
  __HAL_RCC_MCO1_CONFIG(RCC_MCOSource, RCC_MCODiv);
1028
}
1029
 
1030
/**
1031
  * @brief  Enables the Clock Security System.
1032
  * @note   If a failure is detected on the HSE oscillator clock, this oscillator
1033
  *         is automatically disabled and an interrupt is generated to inform the
1034
  *         software about the failure (Clock Security System Interrupt, CSSI),
1035
  *         allowing the MCU to perform rescue operations. The CSSI is linked to
1036
  *         the Cortex-M3 NMI (Non-Maskable Interrupt) exception vector.
1037
  * @retval None
1038
  */
1039
void HAL_RCC_EnableCSS(void)
1040
{
1041
  *(__IO uint32_t *) RCC_CR_CSSON_BB = (uint32_t)ENABLE;
1042
}
1043
 
1044
/**
1045
  * @brief  Disables the Clock Security System.
1046
  * @retval None
1047
  */
1048
void HAL_RCC_DisableCSS(void)
1049
{
1050
  *(__IO uint32_t *) RCC_CR_CSSON_BB = (uint32_t)DISABLE;
1051
}
1052
 
1053
/**
1054
  * @brief  Returns the SYSCLK frequency
1055
  * @note   The system frequency computed by this function is not the real
1056
  *         frequency in the chip. It is calculated based on the predefined
1057
  *         constant and the selected clock source:
1058
  * @note     If SYSCLK source is HSI, function returns values based on HSI_VALUE(*)
1059
  * @note     If SYSCLK source is HSE, function returns a value based on HSE_VALUE
1060
  *           divided by PREDIV factor(**)
1061
  * @note     If SYSCLK source is PLL, function returns a value based on HSE_VALUE
1062
  *           divided by PREDIV factor(**) or HSI_VALUE(*) multiplied by the PLL factor.
1063
  * @note     (*) HSI_VALUE is a constant defined in stm32f1xx_hal_conf.h file (default value
1064
  *               8 MHz) but the real value may vary depending on the variations
1065
  *               in voltage and temperature.
1066
  * @note     (**) HSE_VALUE is a constant defined in stm32f1xx_hal_conf.h file (default value
1067
  *                8 MHz), user has to ensure that HSE_VALUE is same as the real
1068
  *                frequency of the crystal used. Otherwise, this function may
1069
  *                have wrong result.
1070
  *
1071
  * @note   The result of this function could be not correct when using fractional
1072
  *         value for HSE crystal.
1073
  *
1074
  * @note   This function can be used by the user application to compute the
1075
  *         baud-rate for the communication peripherals or configure other parameters.
1076
  *
1077
  * @note   Each time SYSCLK changes, this function must be called to update the
1078
  *         right SYSCLK value. Otherwise, any configuration based on this function will be incorrect.
1079
  *
1080
  * @retval SYSCLK frequency
1081
  */
1082
uint32_t HAL_RCC_GetSysClockFreq(void)
1083
{
1084
#if defined(RCC_CFGR2_PREDIV1SRC)
1085
  const uint8_t aPLLMULFactorTable[14] = {0, 0, 4, 5, 6, 7, 8, 9, 0, 0, 0, 0, 0, 13};
1086
  const uint8_t aPredivFactorTable[16] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16};
1087
#else
1088
  const uint8_t aPLLMULFactorTable[16] = {2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 16};
1089
#if defined(RCC_CFGR2_PREDIV1)
1090
  const uint8_t aPredivFactorTable[16] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16};
1091
#else
1092
  const uint8_t aPredivFactorTable[2] = {1, 2};
1093
#endif /*RCC_CFGR2_PREDIV1*/
1094
 
1095
#endif
1096
  uint32_t tmpreg = 0U, prediv = 0U, pllclk = 0U, pllmul = 0U;
1097
  uint32_t sysclockfreq = 0U;
1098
#if defined(RCC_CFGR2_PREDIV1SRC)
1099
  uint32_t prediv2 = 0U, pll2mul = 0U;
1100
#endif /*RCC_CFGR2_PREDIV1SRC*/
1101
 
1102
  tmpreg = RCC->CFGR;
1103
 
1104
  /* Get SYSCLK source -------------------------------------------------------*/
1105
  switch (tmpreg & RCC_CFGR_SWS)
1106
  {
1107
    case RCC_SYSCLKSOURCE_STATUS_HSE:  /* HSE used as system clock */
1108
    {
1109
      sysclockfreq = HSE_VALUE;
1110
      break;
1111
    }
1112
    case RCC_SYSCLKSOURCE_STATUS_PLLCLK:  /* PLL used as system clock */
1113
    {
1114
      pllmul = aPLLMULFactorTable[(uint32_t)(tmpreg & RCC_CFGR_PLLMULL) >> RCC_CFGR_PLLMULL_Pos];
1115
      if ((tmpreg & RCC_CFGR_PLLSRC) != RCC_PLLSOURCE_HSI_DIV2)
1116
      {
1117
#if defined(RCC_CFGR2_PREDIV1)
1118
        prediv = aPredivFactorTable[(uint32_t)(RCC->CFGR2 & RCC_CFGR2_PREDIV1) >> RCC_CFGR2_PREDIV1_Pos];
1119
#else
1120
        prediv = aPredivFactorTable[(uint32_t)(RCC->CFGR & RCC_CFGR_PLLXTPRE) >> RCC_CFGR_PLLXTPRE_Pos];
1121
#endif /*RCC_CFGR2_PREDIV1*/
1122
#if defined(RCC_CFGR2_PREDIV1SRC)
1123
 
1124
        if (HAL_IS_BIT_SET(RCC->CFGR2, RCC_CFGR2_PREDIV1SRC))
1125
        {
1126
          /* PLL2 selected as Prediv1 source */
1127
          /* PLLCLK = PLL2CLK / PREDIV1 * PLLMUL with PLL2CLK = HSE/PREDIV2 * PLL2MUL */
1128
          prediv2 = ((RCC->CFGR2 & RCC_CFGR2_PREDIV2) >> RCC_CFGR2_PREDIV2_Pos) + 1;
1129
          pll2mul = ((RCC->CFGR2 & RCC_CFGR2_PLL2MUL) >> RCC_CFGR2_PLL2MUL_Pos) + 2;
1130
          pllclk = (uint32_t)(((uint64_t)HSE_VALUE * (uint64_t)pll2mul * (uint64_t)pllmul) / ((uint64_t)prediv2 * (uint64_t)prediv));
1131
        }
1132
        else
1133
        {
1134
          /* HSE used as PLL clock source : PLLCLK = HSE/PREDIV1 * PLLMUL */
1135
          pllclk = (uint32_t)((HSE_VALUE * pllmul) / prediv);
1136
        }
1137
 
1138
        /* If PLLMUL was set to 13 means that it was to cover the case PLLMUL 6.5 (avoid using float) */
1139
        /* In this case need to divide pllclk by 2 */
1140
        if (pllmul == aPLLMULFactorTable[(uint32_t)(RCC_CFGR_PLLMULL6_5) >> RCC_CFGR_PLLMULL_Pos])
1141
        {
1142
          pllclk = pllclk / 2;
1143
        }
1144
#else
1145
        /* HSE used as PLL clock source : PLLCLK = HSE/PREDIV1 * PLLMUL */
1146
        pllclk = (uint32_t)((HSE_VALUE  * pllmul) / prediv);
1147
#endif /*RCC_CFGR2_PREDIV1SRC*/
1148
      }
1149
      else
1150
      {
1151
        /* HSI used as PLL clock source : PLLCLK = HSI/2 * PLLMUL */
1152
        pllclk = (uint32_t)((HSI_VALUE >> 1) * pllmul);
1153
      }
1154
      sysclockfreq = pllclk;
1155
      break;
1156
    }
1157
    case RCC_SYSCLKSOURCE_STATUS_HSI:  /* HSI used as system clock source */
1158
    default: /* HSI used as system clock */
1159
    {
1160
      sysclockfreq = HSI_VALUE;
1161
      break;
1162
    }
1163
  }
1164
  return sysclockfreq;
1165
}
1166
 
1167
/**
1168
  * @brief  Returns the HCLK frequency
1169
  * @note   Each time HCLK changes, this function must be called to update the
1170
  *         right HCLK value. Otherwise, any configuration based on this function will be incorrect.
1171
  *
1172
  * @note   The SystemCoreClock CMSIS variable is used to store System Clock Frequency
1173
  *         and updated within this function
1174
  * @retval HCLK frequency
1175
  */
1176
uint32_t HAL_RCC_GetHCLKFreq(void)
1177
{
1178
  return SystemCoreClock;
1179
}
1180
 
1181
/**
1182
  * @brief  Returns the PCLK1 frequency
1183
  * @note   Each time PCLK1 changes, this function must be called to update the
1184
  *         right PCLK1 value. Otherwise, any configuration based on this function will be incorrect.
1185
  * @retval PCLK1 frequency
1186
  */
1187
uint32_t HAL_RCC_GetPCLK1Freq(void)
1188
{
1189
  /* Get HCLK source and Compute PCLK1 frequency ---------------------------*/
1190
  return (HAL_RCC_GetHCLKFreq() >> APBPrescTable[(RCC->CFGR & RCC_CFGR_PPRE1) >> RCC_CFGR_PPRE1_Pos]);
1191
}
1192
 
1193
/**
1194
  * @brief  Returns the PCLK2 frequency
1195
  * @note   Each time PCLK2 changes, this function must be called to update the
1196
  *         right PCLK2 value. Otherwise, any configuration based on this function will be incorrect.
1197
  * @retval PCLK2 frequency
1198
  */
1199
uint32_t HAL_RCC_GetPCLK2Freq(void)
1200
{
1201
  /* Get HCLK source and Compute PCLK2 frequency ---------------------------*/
1202
  return (HAL_RCC_GetHCLKFreq() >> APBPrescTable[(RCC->CFGR & RCC_CFGR_PPRE2) >> RCC_CFGR_PPRE2_Pos]);
1203
}
1204
 
1205
/**
1206
  * @brief  Configures the RCC_OscInitStruct according to the internal
1207
  * RCC configuration registers.
1208
  * @param  RCC_OscInitStruct pointer to an RCC_OscInitTypeDef structure that
1209
  * will be configured.
1210
  * @retval None
1211
  */
1212
void HAL_RCC_GetOscConfig(RCC_OscInitTypeDef  *RCC_OscInitStruct)
1213
{
1214
  /* Check the parameters */
1215
  assert_param(RCC_OscInitStruct != NULL);
1216
 
1217
  /* Set all possible values for the Oscillator type parameter ---------------*/
1218
  RCC_OscInitStruct->OscillatorType = RCC_OSCILLATORTYPE_HSE | RCC_OSCILLATORTYPE_HSI  \
1219
                                      | RCC_OSCILLATORTYPE_LSE | RCC_OSCILLATORTYPE_LSI;
1220
 
1221
#if defined(RCC_CFGR2_PREDIV1SRC)
1222
  /* Get the Prediv1 source --------------------------------------------------*/
1223
  RCC_OscInitStruct->Prediv1Source = READ_BIT(RCC->CFGR2, RCC_CFGR2_PREDIV1SRC);
1224
#endif /* RCC_CFGR2_PREDIV1SRC */
1225
 
1226
  /* Get the HSE configuration -----------------------------------------------*/
1227
  if ((RCC->CR & RCC_CR_HSEBYP) == RCC_CR_HSEBYP)
1228
  {
1229
    RCC_OscInitStruct->HSEState = RCC_HSE_BYPASS;
1230
  }
1231
  else if ((RCC->CR & RCC_CR_HSEON) == RCC_CR_HSEON)
1232
  {
1233
    RCC_OscInitStruct->HSEState = RCC_HSE_ON;
1234
  }
1235
  else
1236
  {
1237
    RCC_OscInitStruct->HSEState = RCC_HSE_OFF;
1238
  }
1239
  RCC_OscInitStruct->HSEPredivValue = __HAL_RCC_HSE_GET_PREDIV();
1240
 
1241
  /* Get the HSI configuration -----------------------------------------------*/
1242
  if ((RCC->CR & RCC_CR_HSION) == RCC_CR_HSION)
1243
  {
1244
    RCC_OscInitStruct->HSIState = RCC_HSI_ON;
1245
  }
1246
  else
1247
  {
1248
    RCC_OscInitStruct->HSIState = RCC_HSI_OFF;
1249
  }
1250
 
1251
  RCC_OscInitStruct->HSICalibrationValue = (uint32_t)((RCC->CR & RCC_CR_HSITRIM) >> RCC_CR_HSITRIM_Pos);
1252
 
1253
  /* Get the LSE configuration -----------------------------------------------*/
1254
  if ((RCC->BDCR & RCC_BDCR_LSEBYP) == RCC_BDCR_LSEBYP)
1255
  {
1256
    RCC_OscInitStruct->LSEState = RCC_LSE_BYPASS;
1257
  }
1258
  else if ((RCC->BDCR & RCC_BDCR_LSEON) == RCC_BDCR_LSEON)
1259
  {
1260
    RCC_OscInitStruct->LSEState = RCC_LSE_ON;
1261
  }
1262
  else
1263
  {
1264
    RCC_OscInitStruct->LSEState = RCC_LSE_OFF;
1265
  }
1266
 
1267
  /* Get the LSI configuration -----------------------------------------------*/
1268
  if ((RCC->CSR & RCC_CSR_LSION) == RCC_CSR_LSION)
1269
  {
1270
    RCC_OscInitStruct->LSIState = RCC_LSI_ON;
1271
  }
1272
  else
1273
  {
1274
    RCC_OscInitStruct->LSIState = RCC_LSI_OFF;
1275
  }
1276
 
1277
 
1278
  /* Get the PLL configuration -----------------------------------------------*/
1279
  if ((RCC->CR & RCC_CR_PLLON) == RCC_CR_PLLON)
1280
  {
1281
    RCC_OscInitStruct->PLL.PLLState = RCC_PLL_ON;
1282
  }
1283
  else
1284
  {
1285
    RCC_OscInitStruct->PLL.PLLState = RCC_PLL_OFF;
1286
  }
1287
  RCC_OscInitStruct->PLL.PLLSource = (uint32_t)(RCC->CFGR & RCC_CFGR_PLLSRC);
1288
  RCC_OscInitStruct->PLL.PLLMUL = (uint32_t)(RCC->CFGR & RCC_CFGR_PLLMULL);
1289
#if defined(RCC_CR_PLL2ON)
1290
  /* Get the PLL2 configuration -----------------------------------------------*/
1291
  if ((RCC->CR & RCC_CR_PLL2ON) == RCC_CR_PLL2ON)
1292
  {
1293
    RCC_OscInitStruct->PLL2.PLL2State = RCC_PLL2_ON;
1294
  }
1295
  else
1296
  {
1297
    RCC_OscInitStruct->PLL2.PLL2State = RCC_PLL2_OFF;
1298
  }
1299
  RCC_OscInitStruct->PLL2.HSEPrediv2Value = __HAL_RCC_HSE_GET_PREDIV2();
1300
  RCC_OscInitStruct->PLL2.PLL2MUL = (uint32_t)(RCC->CFGR2 & RCC_CFGR2_PLL2MUL);
1301
#endif /* RCC_CR_PLL2ON */
1302
}
1303
 
1304
/**
1305
  * @brief  Get the RCC_ClkInitStruct according to the internal
1306
  * RCC configuration registers.
1307
  * @param  RCC_ClkInitStruct pointer to an RCC_ClkInitTypeDef structure that
1308
  * contains the current clock configuration.
1309
  * @param  pFLatency Pointer on the Flash Latency.
1310
  * @retval None
1311
  */
1312
void HAL_RCC_GetClockConfig(RCC_ClkInitTypeDef  *RCC_ClkInitStruct, uint32_t *pFLatency)
1313
{
1314
  /* Check the parameters */
1315
  assert_param(RCC_ClkInitStruct != NULL);
1316
  assert_param(pFLatency != NULL);
1317
 
1318
  /* Set all possible values for the Clock type parameter --------------------*/
1319
  RCC_ClkInitStruct->ClockType = RCC_CLOCKTYPE_SYSCLK | RCC_CLOCKTYPE_HCLK | RCC_CLOCKTYPE_PCLK1 | RCC_CLOCKTYPE_PCLK2;
1320
 
1321
  /* Get the SYSCLK configuration --------------------------------------------*/
1322
  RCC_ClkInitStruct->SYSCLKSource = (uint32_t)(RCC->CFGR & RCC_CFGR_SW);
1323
 
1324
  /* Get the HCLK configuration ----------------------------------------------*/
1325
  RCC_ClkInitStruct->AHBCLKDivider = (uint32_t)(RCC->CFGR & RCC_CFGR_HPRE);
1326
 
1327
  /* Get the APB1 configuration ----------------------------------------------*/
1328
  RCC_ClkInitStruct->APB1CLKDivider = (uint32_t)(RCC->CFGR & RCC_CFGR_PPRE1);
1329
 
1330
  /* Get the APB2 configuration ----------------------------------------------*/
1331
  RCC_ClkInitStruct->APB2CLKDivider = (uint32_t)((RCC->CFGR & RCC_CFGR_PPRE2) >> 3);
1332
 
1333
#if   defined(FLASH_ACR_LATENCY)
1334
  /* Get the Flash Wait State (Latency) configuration ------------------------*/
1335
  *pFLatency = (uint32_t)(FLASH->ACR & FLASH_ACR_LATENCY);
1336
#else
1337
  /* For VALUE lines devices, only LATENCY_0 can be set*/
1338
  *pFLatency = (uint32_t)FLASH_LATENCY_0;
1339
#endif
1340
}
1341
 
1342
/**
1343
  * @brief This function handles the RCC CSS interrupt request.
1344
  * @note This API should be called under the NMI_Handler().
1345
  * @retval None
1346
  */
1347
void HAL_RCC_NMI_IRQHandler(void)
1348
{
1349
  /* Check RCC CSSF flag  */
1350
  if (__HAL_RCC_GET_IT(RCC_IT_CSS))
1351
  {
1352
    /* RCC Clock Security System interrupt user callback */
1353
    HAL_RCC_CSSCallback();
1354
 
1355
    /* Clear RCC CSS pending bit */
1356
    __HAL_RCC_CLEAR_IT(RCC_IT_CSS);
1357
  }
1358
}
1359
 
1360
/**
1361
  * @brief  This function provides delay (in milliseconds) based on CPU cycles method.
1362
  * @param  mdelay: specifies the delay time length, in milliseconds.
1363
  * @retval None
1364
  */
1365
static void RCC_Delay(uint32_t mdelay)
1366
{
1367
  __IO uint32_t Delay = mdelay * (SystemCoreClock / 8U / 1000U);
1368
  do
1369
  {
1370
    __NOP();
1371
  }
1372
  while (Delay --);
1373
}
1374
 
1375
/**
1376
  * @brief  RCC Clock Security System interrupt callback
1377
  * @retval none
1378
  */
1379
__weak void HAL_RCC_CSSCallback(void)
1380
{
1381
  /* NOTE : This function Should not be modified, when the callback is needed,
1382
    the HAL_RCC_CSSCallback could be implemented in the user file
1383
    */
1384
}
1385
 
1386
/**
1387
  * @}
1388
  */
1389
 
1390
/**
1391
  * @}
1392
  */
1393
 
1394
#endif /* HAL_RCC_MODULE_ENABLED */
1395
/**
1396
  * @}
1397
  */
1398
 
1399
/**
1400
  * @}
1401
  */
1402
 
1403
/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/