Subversion Repositories DashDisplay

Rev

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

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