Subversion Repositories EngineBay2

Rev

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

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