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