STM32F103xB HAL User Manual
stm32f1xx_hal_rcc.c
Go to the documentation of this file.
00001 /**
00002   ******************************************************************************
00003   * @file    stm32f1xx_hal_rcc.c
00004   * @author  MCD Application Team
00005   * @brief   RCC HAL module driver.
00006   *          This file provides firmware functions to manage the following
00007   *          functionalities of the Reset and Clock Control (RCC) peripheral:
00008   *           + Initialization and de-initialization functions
00009   *           + Peripheral Control functions
00010   *
00011   @verbatim
00012   ==============================================================================
00013                       ##### RCC specific features #####
00014   ==============================================================================
00015     [..]
00016       After reset the device is running from Internal High Speed oscillator
00017       (HSI 8MHz) with Flash 0 wait state, Flash prefetch buffer is enabled,
00018       and all peripherals are off except internal SRAM, Flash and JTAG.
00019       (+) There is no prescaler on High speed (AHB) and Low speed (APB) buses;
00020           all peripherals mapped on these buses are running at HSI speed.
00021       (+) The clock for all peripherals is switched off, except the SRAM and FLASH.
00022       (+) All GPIOs are in input floating state, except the JTAG pins which
00023           are assigned to be used for debug purpose.
00024     [..] Once the device started from reset, the user application has to:
00025       (+) Configure the clock source to be used to drive the System clock
00026           (if the application needs higher frequency/performance)
00027       (+) Configure the System clock frequency and Flash settings
00028       (+) Configure the AHB and APB buses prescalers
00029       (+) Enable the clock for the peripheral(s) to be used
00030       (+) Configure the clock source(s) for peripherals whose clocks are not
00031           derived from the System clock (I2S, RTC, ADC, USB OTG FS)
00032 
00033                       ##### RCC Limitations #####
00034   ==============================================================================
00035     [..]
00036       A delay between an RCC peripheral clock enable and the effective peripheral
00037       enabling should be taken into account in order to manage the peripheral read/write
00038       from/to registers.
00039       (+) This delay depends on the peripheral mapping.
00040         (++) AHB & APB peripherals, 1 dummy read is necessary
00041 
00042     [..]
00043       Workarounds:
00044       (#) For AHB & APB peripherals, a dummy read to the peripheral register has been
00045           inserted in each __HAL_RCC_PPP_CLK_ENABLE() macro.
00046 
00047   @endverbatim
00048   ******************************************************************************
00049   * @attention
00050   *
00051   * <h2><center>&copy; Copyright (c) 2016 STMicroelectronics.
00052   * All rights reserved.</center></h2>
00053   *
00054   * This software component is licensed by ST under BSD 3-Clause license,
00055   * the "License"; You may not use this file except in compliance with the
00056   * License. You may obtain a copy of the License at:
00057   *                        opensource.org/licenses/BSD-3-Clause
00058   *
00059   ******************************************************************************
00060   */
00061 
00062 /* Includes ------------------------------------------------------------------*/
00063 #include "stm32f1xx_hal.h"
00064 
00065 /** @addtogroup STM32F1xx_HAL_Driver
00066   * @{
00067   */
00068 
00069 /** @defgroup RCC RCC
00070 * @brief RCC HAL module driver
00071   * @{
00072   */
00073 
00074 #ifdef HAL_RCC_MODULE_ENABLED
00075 
00076 /* Private typedef -----------------------------------------------------------*/
00077 /* Private define ------------------------------------------------------------*/
00078 /** @defgroup RCC_Private_Constants RCC Private Constants
00079  * @{
00080  */
00081 /**
00082   * @}
00083   */
00084 /* Private macro -------------------------------------------------------------*/
00085 /** @defgroup RCC_Private_Macros RCC Private Macros
00086   * @{
00087   */
00088 
00089 #define MCO1_CLK_ENABLE()     __HAL_RCC_GPIOA_CLK_ENABLE()
00090 #define MCO1_GPIO_PORT        GPIOA
00091 #define MCO1_PIN              GPIO_PIN_8
00092 
00093 /**
00094   * @}
00095   */
00096 
00097 /* Private variables ---------------------------------------------------------*/
00098 /** @defgroup RCC_Private_Variables RCC Private Variables
00099   * @{
00100   */
00101 /**
00102   * @}
00103   */
00104 
00105 /* Private function prototypes -----------------------------------------------*/
00106 static void RCC_Delay(uint32_t mdelay);
00107 
00108 /* Exported functions --------------------------------------------------------*/
00109 
00110 /** @defgroup RCC_Exported_Functions RCC Exported Functions
00111   * @{
00112   */
00113 
00114 /** @defgroup RCC_Exported_Functions_Group1 Initialization and de-initialization functions
00115   *  @brief    Initialization and Configuration functions
00116   *
00117   @verbatim
00118   ===============================================================================
00119            ##### Initialization and de-initialization functions #####
00120   ===============================================================================
00121     [..]
00122       This section provides functions allowing to configure the internal/external oscillators
00123       (HSE, HSI, LSE, LSI, PLL, CSS and MCO) and the System buses clocks (SYSCLK, AHB, APB1
00124       and APB2).
00125 
00126     [..] Internal/external clock and PLL configuration
00127       (#) HSI (high-speed internal), 8 MHz factory-trimmed RC used directly or through
00128           the PLL as System clock source.
00129       (#) LSI (low-speed internal), ~40 KHz low consumption RC used as IWDG and/or RTC
00130           clock source.
00131 
00132       (#) HSE (high-speed external), 4 to 24 MHz (STM32F100xx) or 4 to 16 MHz (STM32F101x/STM32F102x/STM32F103x) or 3 to 25 MHz (STM32F105x/STM32F107x)  crystal oscillator used directly or
00133           through the PLL as System clock source. Can be used also as RTC clock source.
00134 
00135       (#) LSE (low-speed external), 32 KHz oscillator used as RTC clock source.
00136 
00137       (#) PLL (clocked by HSI or HSE), featuring different output clocks:
00138         (++) The first output is used to generate the high speed system clock (up to 72 MHz for STM32F10xxx or up to 24 MHz for STM32F100xx)
00139         (++) The second output is used to generate the clock for the USB OTG FS (48 MHz)
00140 
00141       (#) CSS (Clock security system), once enable using the macro __HAL_RCC_CSS_ENABLE()
00142           and if a HSE clock failure occurs(HSE used directly or through PLL as System
00143           clock source), the System clocks automatically switched to HSI and an interrupt
00144           is generated if enabled. The interrupt is linked to the Cortex-M3 NMI
00145           (Non-Maskable Interrupt) exception vector.
00146 
00147       (#) MCO1 (microcontroller clock output), used to output SYSCLK, HSI,
00148           HSE or PLL clock (divided by 2) on PA8 pin + PLL2CLK, PLL3CLK/2, PLL3CLK and XTI for STM32F105x/STM32F107x
00149 
00150     [..] System, AHB and APB buses clocks configuration
00151       (#) Several clock sources can be used to drive the System clock (SYSCLK): HSI,
00152           HSE and PLL.
00153           The AHB clock (HCLK) is derived from System clock through configurable
00154           prescaler and used to clock the CPU, memory and peripherals mapped
00155           on AHB bus (DMA, GPIO...). APB1 (PCLK1) and APB2 (PCLK2) clocks are derived
00156           from AHB clock through configurable prescalers and used to clock
00157           the peripherals mapped on these buses. You can use
00158           "@ref HAL_RCC_GetSysClockFreq()" function to retrieve the frequencies of these clocks.
00159 
00160       -@- All the peripheral clocks are derived from the System clock (SYSCLK) except:
00161           (+@) RTC: RTC clock can be derived either from the LSI, LSE or HSE clock
00162               divided by 128.
00163           (+@) USB OTG FS and RTC: USB OTG FS require a frequency equal to 48 MHz
00164               to work correctly. This clock is derived of the main PLL through PLL Multiplier.
00165           (+@) I2S interface on STM32F105x/STM32F107x can be derived from PLL3CLK
00166           (+@) IWDG clock which is always the LSI clock.
00167 
00168       (#) For STM32F10xxx, the maximum frequency of the SYSCLK and HCLK/PCLK2 is 72 MHz, PCLK1 36 MHz.
00169           For STM32F100xx, the maximum frequency of the SYSCLK and HCLK/PCLK1/PCLK2 is 24 MHz.
00170           Depending on the SYSCLK frequency, the flash latency should be adapted accordingly.
00171   @endverbatim
00172   * @{
00173   */
00174 
00175 /*
00176   Additional consideration on the SYSCLK based on Latency settings:
00177         +-----------------------------------------------+
00178         | Latency       | SYSCLK clock frequency (MHz)  |
00179         |---------------|-------------------------------|
00180         |0WS(1CPU cycle)|       0 < SYSCLK <= 24        |
00181         |---------------|-------------------------------|
00182         |1WS(2CPU cycle)|      24 < SYSCLK <= 48        |
00183         |---------------|-------------------------------|
00184         |2WS(3CPU cycle)|      48 < SYSCLK <= 72        |
00185         +-----------------------------------------------+
00186   */
00187 
00188 /**
00189   * @brief  Resets the RCC clock configuration to the default reset state.
00190   * @note   The default reset state of the clock configuration is given below:
00191   *            - HSI ON and used as system clock source
00192   *            - HSE, PLL, PLL2 and PLL3 are OFF
00193   *            - AHB, APB1 and APB2 prescaler set to 1.
00194   *            - CSS and MCO1 OFF
00195   *            - All interrupts disabled
00196   *            - All flags are cleared
00197   * @note   This function does not modify the configuration of the
00198   *            - Peripheral clocks
00199   *            - LSI, LSE and RTC clocks
00200   * @retval HAL_StatusTypeDef
00201   */
00202 HAL_StatusTypeDef HAL_RCC_DeInit(void)
00203 {
00204   uint32_t tickstart;
00205 
00206   /* Get Start Tick */
00207   tickstart = HAL_GetTick();
00208 
00209   /* Set HSION bit */
00210   SET_BIT(RCC->CR, RCC_CR_HSION);
00211 
00212   /* Wait till HSI is ready */
00213   while (READ_BIT(RCC->CR, RCC_CR_HSIRDY) == RESET)
00214   {
00215     if ((HAL_GetTick() - tickstart) > HSI_TIMEOUT_VALUE)
00216     {
00217       return HAL_TIMEOUT;
00218     }
00219   }
00220 
00221   /* Set HSITRIM bits to the reset value */
00222   MODIFY_REG(RCC->CR, RCC_CR_HSITRIM, (0x10U << RCC_CR_HSITRIM_Pos));
00223 
00224   /* Get Start Tick */
00225   tickstart = HAL_GetTick();
00226 
00227   /* Reset CFGR register */
00228   CLEAR_REG(RCC->CFGR);
00229 
00230   /* Wait till clock switch is ready */
00231   while (READ_BIT(RCC->CFGR, RCC_CFGR_SWS) != RESET)
00232   {
00233     if ((HAL_GetTick() - tickstart) > CLOCKSWITCH_TIMEOUT_VALUE)
00234     {
00235       return HAL_TIMEOUT;
00236     }
00237   }
00238 
00239   /* Update the SystemCoreClock global variable */
00240   SystemCoreClock = HSI_VALUE;
00241 
00242   /* Adapt Systick interrupt period */
00243   if (HAL_InitTick(uwTickPrio) != HAL_OK)
00244   {
00245     return HAL_ERROR;
00246   }
00247 
00248   /* Get Start Tick */
00249   tickstart = HAL_GetTick();
00250 
00251   /* Second step is to clear PLLON bit */
00252   CLEAR_BIT(RCC->CR, RCC_CR_PLLON);
00253 
00254   /* Wait till PLL is disabled */
00255   while (READ_BIT(RCC->CR, RCC_CR_PLLRDY) != RESET)
00256   {
00257     if ((HAL_GetTick() - tickstart) > PLL_TIMEOUT_VALUE)
00258     {
00259       return HAL_TIMEOUT;
00260     }
00261   }
00262 
00263   /* Ensure to reset PLLSRC and PLLMUL bits */
00264   CLEAR_REG(RCC->CFGR);
00265 
00266   /* Get Start Tick */
00267   tickstart = HAL_GetTick();
00268 
00269   /* Reset HSEON & CSSON bits */
00270   CLEAR_BIT(RCC->CR, RCC_CR_HSEON | RCC_CR_CSSON);
00271 
00272   /* Wait till HSE is disabled */
00273   while (READ_BIT(RCC->CR, RCC_CR_HSERDY) != RESET)
00274   {
00275     if ((HAL_GetTick() - tickstart) > HSE_TIMEOUT_VALUE)
00276     {
00277       return HAL_TIMEOUT;
00278     }
00279   }
00280 
00281   /* Reset HSEBYP bit */
00282   CLEAR_BIT(RCC->CR, RCC_CR_HSEBYP);
00283 
00284 #if defined(RCC_PLL2_SUPPORT)
00285   /* Get Start Tick */
00286   tickstart = HAL_GetTick();
00287 
00288   /* Clear PLL2ON bit */
00289   CLEAR_BIT(RCC->CR, RCC_CR_PLL2ON);
00290 
00291   /* Wait till PLL2 is disabled */
00292   while (READ_BIT(RCC->CR, RCC_CR_PLL2RDY) != RESET)
00293   {
00294     if ((HAL_GetTick() - tickstart) > PLL2_TIMEOUT_VALUE)
00295     {
00296       return HAL_TIMEOUT;
00297     }
00298   }
00299 #endif /* RCC_PLL2_SUPPORT */
00300 
00301 #if defined(RCC_PLLI2S_SUPPORT)
00302   /* Get Start Tick */
00303   tickstart = HAL_GetTick();
00304 
00305   /* Clear PLL3ON bit */
00306   CLEAR_BIT(RCC->CR, RCC_CR_PLL3ON);
00307 
00308   /* Wait till PLL3 is disabled */
00309   while (READ_BIT(RCC->CR, RCC_CR_PLL3RDY) != RESET)
00310   {
00311     if ((HAL_GetTick() - tickstart) > PLLI2S_TIMEOUT_VALUE)
00312     {
00313       return HAL_TIMEOUT;
00314     }
00315   }
00316 #endif /* RCC_PLLI2S_SUPPORT */
00317 
00318 #if defined(RCC_CFGR2_PREDIV1)
00319   /* Reset CFGR2 register */
00320   CLEAR_REG(RCC->CFGR2);
00321 #endif /* RCC_CFGR2_PREDIV1 */
00322 
00323   /* Reset all CSR flags */
00324   SET_BIT(RCC->CSR, RCC_CSR_RMVF);
00325 
00326   /* Disable all interrupts */
00327   CLEAR_REG(RCC->CIR);
00328 
00329   return HAL_OK;
00330 }
00331 
00332 /**
00333   * @brief  Initializes the RCC Oscillators according to the specified parameters in the
00334   *         RCC_OscInitTypeDef.
00335   * @param  RCC_OscInitStruct pointer to an RCC_OscInitTypeDef structure that
00336   *         contains the configuration information for the RCC Oscillators.
00337   * @note   The PLL is not disabled when used as system clock.
00338   * @note   The PLL is not disabled when USB OTG FS clock is enabled (specific to devices with USB FS)
00339   * @note   Transitions LSE Bypass to LSE On and LSE On to LSE Bypass are not
00340   *         supported by this macro. User should request a transition to LSE Off
00341   *         first and then LSE On or LSE Bypass.
00342   * @note   Transition HSE Bypass to HSE On and HSE On to HSE Bypass are not
00343   *         supported by this macro. User should request a transition to HSE Off
00344   *         first and then HSE On or HSE Bypass.
00345   * @retval HAL status
00346   */
00347 HAL_StatusTypeDef HAL_RCC_OscConfig(RCC_OscInitTypeDef  *RCC_OscInitStruct)
00348 {
00349   uint32_t tickstart;
00350   uint32_t pll_config;
00351 
00352   /* Check Null pointer */
00353   if (RCC_OscInitStruct == NULL)
00354   {
00355     return HAL_ERROR;
00356   }
00357 
00358   /* Check the parameters */
00359   assert_param(IS_RCC_OSCILLATORTYPE(RCC_OscInitStruct->OscillatorType));
00360 
00361   /*------------------------------- HSE Configuration ------------------------*/
00362   if (((RCC_OscInitStruct->OscillatorType) & RCC_OSCILLATORTYPE_HSE) == RCC_OSCILLATORTYPE_HSE)
00363   {
00364     /* Check the parameters */
00365     assert_param(IS_RCC_HSE(RCC_OscInitStruct->HSEState));
00366 
00367     /* When the HSE is used as system clock or clock source for PLL in these cases it is not allowed to be disabled */
00368     if ((__HAL_RCC_GET_SYSCLK_SOURCE() == RCC_SYSCLKSOURCE_STATUS_HSE)
00369         || ((__HAL_RCC_GET_SYSCLK_SOURCE() == RCC_SYSCLKSOURCE_STATUS_PLLCLK) && (__HAL_RCC_GET_PLL_OSCSOURCE() == RCC_PLLSOURCE_HSE)))
00370     {
00371       if ((__HAL_RCC_GET_FLAG(RCC_FLAG_HSERDY) != RESET) && (RCC_OscInitStruct->HSEState == RCC_HSE_OFF))
00372       {
00373         return HAL_ERROR;
00374       }
00375     }
00376     else
00377     {
00378       /* Set the new HSE configuration ---------------------------------------*/
00379       __HAL_RCC_HSE_CONFIG(RCC_OscInitStruct->HSEState);
00380 
00381 
00382       /* Check the HSE State */
00383       if (RCC_OscInitStruct->HSEState != RCC_HSE_OFF)
00384       {
00385         /* Get Start Tick */
00386         tickstart = HAL_GetTick();
00387 
00388         /* Wait till HSE is ready */
00389         while (__HAL_RCC_GET_FLAG(RCC_FLAG_HSERDY) == RESET)
00390         {
00391           if ((HAL_GetTick() - tickstart) > HSE_TIMEOUT_VALUE)
00392           {
00393             return HAL_TIMEOUT;
00394           }
00395         }
00396       }
00397       else
00398       {
00399         /* Get Start Tick */
00400         tickstart = HAL_GetTick();
00401 
00402         /* Wait till HSE is disabled */
00403         while (__HAL_RCC_GET_FLAG(RCC_FLAG_HSERDY) != RESET)
00404         {
00405           if ((HAL_GetTick() - tickstart) > HSE_TIMEOUT_VALUE)
00406           {
00407             return HAL_TIMEOUT;
00408           }
00409         }
00410       }
00411     }
00412   }
00413   /*----------------------------- HSI Configuration --------------------------*/
00414   if (((RCC_OscInitStruct->OscillatorType) & RCC_OSCILLATORTYPE_HSI) == RCC_OSCILLATORTYPE_HSI)
00415   {
00416     /* Check the parameters */
00417     assert_param(IS_RCC_HSI(RCC_OscInitStruct->HSIState));
00418     assert_param(IS_RCC_CALIBRATION_VALUE(RCC_OscInitStruct->HSICalibrationValue));
00419 
00420     /* Check if HSI is used as system clock or as PLL source when PLL is selected as system clock */
00421     if ((__HAL_RCC_GET_SYSCLK_SOURCE() == RCC_SYSCLKSOURCE_STATUS_HSI)
00422         || ((__HAL_RCC_GET_SYSCLK_SOURCE() == RCC_SYSCLKSOURCE_STATUS_PLLCLK) && (__HAL_RCC_GET_PLL_OSCSOURCE() == RCC_PLLSOURCE_HSI_DIV2)))
00423     {
00424       /* When HSI is used as system clock it will not disabled */
00425       if ((__HAL_RCC_GET_FLAG(RCC_FLAG_HSIRDY) != RESET) && (RCC_OscInitStruct->HSIState != RCC_HSI_ON))
00426       {
00427         return HAL_ERROR;
00428       }
00429       /* Otherwise, just the calibration is allowed */
00430       else
00431       {
00432         /* Adjusts the Internal High Speed oscillator (HSI) calibration value.*/
00433         __HAL_RCC_HSI_CALIBRATIONVALUE_ADJUST(RCC_OscInitStruct->HSICalibrationValue);
00434       }
00435     }
00436     else
00437     {
00438       /* Check the HSI State */
00439       if (RCC_OscInitStruct->HSIState != RCC_HSI_OFF)
00440       {
00441         /* Enable the Internal High Speed oscillator (HSI). */
00442         __HAL_RCC_HSI_ENABLE();
00443 
00444         /* Get Start Tick */
00445         tickstart = HAL_GetTick();
00446 
00447         /* Wait till HSI is ready */
00448         while (__HAL_RCC_GET_FLAG(RCC_FLAG_HSIRDY) == RESET)
00449         {
00450           if ((HAL_GetTick() - tickstart) > HSI_TIMEOUT_VALUE)
00451           {
00452             return HAL_TIMEOUT;
00453           }
00454         }
00455 
00456         /* Adjusts the Internal High Speed oscillator (HSI) calibration value.*/
00457         __HAL_RCC_HSI_CALIBRATIONVALUE_ADJUST(RCC_OscInitStruct->HSICalibrationValue);
00458       }
00459       else
00460       {
00461         /* Disable the Internal High Speed oscillator (HSI). */
00462         __HAL_RCC_HSI_DISABLE();
00463 
00464         /* Get Start Tick */
00465         tickstart = HAL_GetTick();
00466 
00467         /* Wait till HSI is disabled */
00468         while (__HAL_RCC_GET_FLAG(RCC_FLAG_HSIRDY) != RESET)
00469         {
00470           if ((HAL_GetTick() - tickstart) > HSI_TIMEOUT_VALUE)
00471           {
00472             return HAL_TIMEOUT;
00473           }
00474         }
00475       }
00476     }
00477   }
00478   /*------------------------------ LSI Configuration -------------------------*/
00479   if (((RCC_OscInitStruct->OscillatorType) & RCC_OSCILLATORTYPE_LSI) == RCC_OSCILLATORTYPE_LSI)
00480   {
00481     /* Check the parameters */
00482     assert_param(IS_RCC_LSI(RCC_OscInitStruct->LSIState));
00483 
00484     /* Check the LSI State */
00485     if (RCC_OscInitStruct->LSIState != RCC_LSI_OFF)
00486     {
00487       /* Enable the Internal Low Speed oscillator (LSI). */
00488       __HAL_RCC_LSI_ENABLE();
00489 
00490       /* Get Start Tick */
00491       tickstart = HAL_GetTick();
00492 
00493       /* Wait till LSI is ready */
00494       while (__HAL_RCC_GET_FLAG(RCC_FLAG_LSIRDY) == RESET)
00495       {
00496         if ((HAL_GetTick() - tickstart) > LSI_TIMEOUT_VALUE)
00497         {
00498           return HAL_TIMEOUT;
00499         }
00500       }
00501       /*  To have a fully stabilized clock in the specified range, a software delay of 1ms
00502           should be added.*/
00503       RCC_Delay(1);
00504     }
00505     else
00506     {
00507       /* Disable the Internal Low Speed oscillator (LSI). */
00508       __HAL_RCC_LSI_DISABLE();
00509 
00510       /* Get Start Tick */
00511       tickstart = HAL_GetTick();
00512 
00513       /* Wait till LSI is disabled */
00514       while (__HAL_RCC_GET_FLAG(RCC_FLAG_LSIRDY) != RESET)
00515       {
00516         if ((HAL_GetTick() - tickstart) > LSI_TIMEOUT_VALUE)
00517         {
00518           return HAL_TIMEOUT;
00519         }
00520       }
00521     }
00522   }
00523   /*------------------------------ LSE Configuration -------------------------*/
00524   if (((RCC_OscInitStruct->OscillatorType) & RCC_OSCILLATORTYPE_LSE) == RCC_OSCILLATORTYPE_LSE)
00525   {
00526     FlagStatus       pwrclkchanged = RESET;
00527 
00528     /* Check the parameters */
00529     assert_param(IS_RCC_LSE(RCC_OscInitStruct->LSEState));
00530 
00531     /* Update LSE configuration in Backup Domain control register    */
00532     /* Requires to enable write access to Backup Domain of necessary */
00533     if (__HAL_RCC_PWR_IS_CLK_DISABLED())
00534     {
00535       __HAL_RCC_PWR_CLK_ENABLE();
00536       pwrclkchanged = SET;
00537     }
00538 
00539     if (HAL_IS_BIT_CLR(PWR->CR, PWR_CR_DBP))
00540     {
00541       /* Enable write access to Backup domain */
00542       SET_BIT(PWR->CR, PWR_CR_DBP);
00543 
00544       /* Wait for Backup domain Write protection disable */
00545       tickstart = HAL_GetTick();
00546 
00547       while (HAL_IS_BIT_CLR(PWR->CR, PWR_CR_DBP))
00548       {
00549         if ((HAL_GetTick() - tickstart) > RCC_DBP_TIMEOUT_VALUE)
00550         {
00551           return HAL_TIMEOUT;
00552         }
00553       }
00554     }
00555 
00556     /* Set the new LSE configuration -----------------------------------------*/
00557     __HAL_RCC_LSE_CONFIG(RCC_OscInitStruct->LSEState);
00558     /* Check the LSE State */
00559     if (RCC_OscInitStruct->LSEState != RCC_LSE_OFF)
00560     {
00561       /* Get Start Tick */
00562       tickstart = HAL_GetTick();
00563 
00564       /* Wait till LSE is ready */
00565       while (__HAL_RCC_GET_FLAG(RCC_FLAG_LSERDY) == RESET)
00566       {
00567         if ((HAL_GetTick() - tickstart) > RCC_LSE_TIMEOUT_VALUE)
00568         {
00569           return HAL_TIMEOUT;
00570         }
00571       }
00572     }
00573     else
00574     {
00575       /* Get Start Tick */
00576       tickstart = HAL_GetTick();
00577 
00578       /* Wait till LSE is disabled */
00579       while (__HAL_RCC_GET_FLAG(RCC_FLAG_LSERDY) != RESET)
00580       {
00581         if ((HAL_GetTick() - tickstart) > RCC_LSE_TIMEOUT_VALUE)
00582         {
00583           return HAL_TIMEOUT;
00584         }
00585       }
00586     }
00587 
00588     /* Require to disable power clock if necessary */
00589     if (pwrclkchanged == SET)
00590     {
00591       __HAL_RCC_PWR_CLK_DISABLE();
00592     }
00593   }
00594 
00595 #if defined(RCC_CR_PLL2ON)
00596   /*-------------------------------- PLL2 Configuration -----------------------*/
00597   /* Check the parameters */
00598   assert_param(IS_RCC_PLL2(RCC_OscInitStruct->PLL2.PLL2State));
00599   if ((RCC_OscInitStruct->PLL2.PLL2State) != RCC_PLL2_NONE)
00600   {
00601     /* This bit can not be cleared if the PLL2 clock is used indirectly as system
00602       clock (i.e. it is used as PLL clock entry that is used as system clock). */
00603     if ((__HAL_RCC_GET_PLL_OSCSOURCE() == RCC_PLLSOURCE_HSE) && \
00604         (__HAL_RCC_GET_SYSCLK_SOURCE() == RCC_SYSCLKSOURCE_STATUS_PLLCLK) && \
00605         ((READ_BIT(RCC->CFGR2, RCC_CFGR2_PREDIV1SRC)) == RCC_CFGR2_PREDIV1SRC_PLL2))
00606     {
00607       return HAL_ERROR;
00608     }
00609     else
00610     {
00611       if ((RCC_OscInitStruct->PLL2.PLL2State) == RCC_PLL2_ON)
00612       {
00613         /* Check the parameters */
00614         assert_param(IS_RCC_PLL2_MUL(RCC_OscInitStruct->PLL2.PLL2MUL));
00615         assert_param(IS_RCC_HSE_PREDIV2(RCC_OscInitStruct->PLL2.HSEPrediv2Value));
00616 
00617         /* Prediv2 can be written only when the PLLI2S is disabled. */
00618         /* Return an error only if new value is different from the programmed value */
00619         if (HAL_IS_BIT_SET(RCC->CR, RCC_CR_PLL3ON) && \
00620             (__HAL_RCC_HSE_GET_PREDIV2() != RCC_OscInitStruct->PLL2.HSEPrediv2Value))
00621         {
00622           return HAL_ERROR;
00623         }
00624 
00625         /* Disable the main PLL2. */
00626         __HAL_RCC_PLL2_DISABLE();
00627 
00628         /* Get Start Tick */
00629         tickstart = HAL_GetTick();
00630 
00631         /* Wait till PLL2 is disabled */
00632         while (__HAL_RCC_GET_FLAG(RCC_FLAG_PLL2RDY) != RESET)
00633         {
00634           if ((HAL_GetTick() - tickstart) > PLL2_TIMEOUT_VALUE)
00635           {
00636             return HAL_TIMEOUT;
00637           }
00638         }
00639 
00640         /* Configure the HSE prediv2 factor --------------------------------*/
00641         __HAL_RCC_HSE_PREDIV2_CONFIG(RCC_OscInitStruct->PLL2.HSEPrediv2Value);
00642 
00643         /* Configure the main PLL2 multiplication factors. */
00644         __HAL_RCC_PLL2_CONFIG(RCC_OscInitStruct->PLL2.PLL2MUL);
00645 
00646         /* Enable the main PLL2. */
00647         __HAL_RCC_PLL2_ENABLE();
00648 
00649         /* Get Start Tick */
00650         tickstart = HAL_GetTick();
00651 
00652         /* Wait till PLL2 is ready */
00653         while (__HAL_RCC_GET_FLAG(RCC_FLAG_PLL2RDY)  == RESET)
00654         {
00655           if ((HAL_GetTick() - tickstart) > PLL2_TIMEOUT_VALUE)
00656           {
00657             return HAL_TIMEOUT;
00658           }
00659         }
00660       }
00661       else
00662       {
00663         /* Set PREDIV1 source to HSE */
00664         CLEAR_BIT(RCC->CFGR2, RCC_CFGR2_PREDIV1SRC);
00665 
00666         /* Disable the main PLL2. */
00667         __HAL_RCC_PLL2_DISABLE();
00668 
00669         /* Get Start Tick */
00670         tickstart = HAL_GetTick();
00671 
00672         /* Wait till PLL2 is disabled */
00673         while (__HAL_RCC_GET_FLAG(RCC_FLAG_PLL2RDY)  != RESET)
00674         {
00675           if ((HAL_GetTick() - tickstart) > PLL2_TIMEOUT_VALUE)
00676           {
00677             return HAL_TIMEOUT;
00678           }
00679         }
00680       }
00681     }
00682   }
00683 
00684 #endif /* RCC_CR_PLL2ON */
00685   /*-------------------------------- PLL Configuration -----------------------*/
00686   /* Check the parameters */
00687   assert_param(IS_RCC_PLL(RCC_OscInitStruct->PLL.PLLState));
00688   if ((RCC_OscInitStruct->PLL.PLLState) != RCC_PLL_NONE)
00689   {
00690     /* Check if the PLL is used as system clock or not */
00691     if (__HAL_RCC_GET_SYSCLK_SOURCE() != RCC_SYSCLKSOURCE_STATUS_PLLCLK)
00692     {
00693       if ((RCC_OscInitStruct->PLL.PLLState) == RCC_PLL_ON)
00694       {
00695         /* Check the parameters */
00696         assert_param(IS_RCC_PLLSOURCE(RCC_OscInitStruct->PLL.PLLSource));
00697         assert_param(IS_RCC_PLL_MUL(RCC_OscInitStruct->PLL.PLLMUL));
00698 
00699         /* Disable the main PLL. */
00700         __HAL_RCC_PLL_DISABLE();
00701 
00702         /* Get Start Tick */
00703         tickstart = HAL_GetTick();
00704 
00705         /* Wait till PLL is disabled */
00706         while (__HAL_RCC_GET_FLAG(RCC_FLAG_PLLRDY)  != RESET)
00707         {
00708           if ((HAL_GetTick() - tickstart) > PLL_TIMEOUT_VALUE)
00709           {
00710             return HAL_TIMEOUT;
00711           }
00712         }
00713 
00714         /* Configure the HSE prediv factor --------------------------------*/
00715         /* It can be written only when the PLL is disabled. Not used in PLL source is different than HSE */
00716         if (RCC_OscInitStruct->PLL.PLLSource == RCC_PLLSOURCE_HSE)
00717         {
00718           /* Check the parameter */
00719           assert_param(IS_RCC_HSE_PREDIV(RCC_OscInitStruct->HSEPredivValue));
00720 #if defined(RCC_CFGR2_PREDIV1SRC)
00721           assert_param(IS_RCC_PREDIV1_SOURCE(RCC_OscInitStruct->Prediv1Source));
00722 
00723           /* Set PREDIV1 source */
00724           SET_BIT(RCC->CFGR2, RCC_OscInitStruct->Prediv1Source);
00725 #endif /* RCC_CFGR2_PREDIV1SRC */
00726 
00727           /* Set PREDIV1 Value */
00728           __HAL_RCC_HSE_PREDIV_CONFIG(RCC_OscInitStruct->HSEPredivValue);
00729         }
00730 
00731         /* Configure the main PLL clock source and multiplication factors. */
00732         __HAL_RCC_PLL_CONFIG(RCC_OscInitStruct->PLL.PLLSource,
00733                              RCC_OscInitStruct->PLL.PLLMUL);
00734         /* Enable the main PLL. */
00735         __HAL_RCC_PLL_ENABLE();
00736 
00737         /* Get Start Tick */
00738         tickstart = HAL_GetTick();
00739 
00740         /* Wait till PLL is ready */
00741         while (__HAL_RCC_GET_FLAG(RCC_FLAG_PLLRDY)  == RESET)
00742         {
00743           if ((HAL_GetTick() - tickstart) > PLL_TIMEOUT_VALUE)
00744           {
00745             return HAL_TIMEOUT;
00746           }
00747         }
00748       }
00749       else
00750       {
00751         /* Disable the main PLL. */
00752         __HAL_RCC_PLL_DISABLE();
00753 
00754         /* Get Start Tick */
00755         tickstart = HAL_GetTick();
00756 
00757         /* Wait till PLL is disabled */
00758         while (__HAL_RCC_GET_FLAG(RCC_FLAG_PLLRDY)  != RESET)
00759         {
00760           if ((HAL_GetTick() - tickstart) > PLL_TIMEOUT_VALUE)
00761           {
00762             return HAL_TIMEOUT;
00763           }
00764         }
00765       }
00766     }
00767     else
00768     {
00769       /* Check if there is a request to disable the PLL used as System clock source */
00770       if ((RCC_OscInitStruct->PLL.PLLState) == RCC_PLL_OFF)
00771       {
00772         return HAL_ERROR;
00773       }
00774       else
00775       {
00776         /* Do not return HAL_ERROR if request repeats the current configuration */
00777         pll_config = RCC->CFGR;
00778         if ((READ_BIT(pll_config, RCC_CFGR_PLLSRC) != RCC_OscInitStruct->PLL.PLLSource) ||
00779             (READ_BIT(pll_config, RCC_CFGR_PLLMULL) != RCC_OscInitStruct->PLL.PLLMUL))
00780         {
00781           return HAL_ERROR;
00782         }
00783       }
00784     }
00785   }
00786 
00787   return HAL_OK;
00788 }
00789 
00790 /**
00791   * @brief  Initializes the CPU, AHB and APB buses clocks according to the specified
00792   *         parameters in the RCC_ClkInitStruct.
00793   * @param  RCC_ClkInitStruct pointer to an RCC_OscInitTypeDef structure that
00794   *         contains the configuration information for the RCC peripheral.
00795   * @param  FLatency FLASH Latency
00796   *          The value of this parameter depend on device used within the same series
00797   * @note   The SystemCoreClock CMSIS variable is used to store System Clock Frequency
00798   *         and updated by @ref HAL_RCC_GetHCLKFreq() function called within this function
00799   *
00800   * @note   The HSI is used (enabled by hardware) as system clock source after
00801   *         start-up from Reset, wake-up from STOP and STANDBY mode, or in case
00802   *         of failure of the HSE used directly or indirectly as system clock
00803   *         (if the Clock Security System CSS is enabled).
00804   *
00805   * @note   A switch from one clock source to another occurs only if the target
00806   *         clock source is ready (clock stable after start-up delay or PLL locked).
00807   *         If a clock source which is not yet ready is selected, the switch will
00808   *         occur when the clock source will be ready.
00809   *         You can use @ref HAL_RCC_GetClockConfig() function to know which clock is
00810   *         currently used as system clock source.
00811   * @retval HAL status
00812   */
00813 HAL_StatusTypeDef HAL_RCC_ClockConfig(RCC_ClkInitTypeDef  *RCC_ClkInitStruct, uint32_t FLatency)
00814 {
00815   uint32_t tickstart;
00816 
00817   /* Check Null pointer */
00818   if (RCC_ClkInitStruct == NULL)
00819   {
00820     return HAL_ERROR;
00821   }
00822 
00823   /* Check the parameters */
00824   assert_param(IS_RCC_CLOCKTYPE(RCC_ClkInitStruct->ClockType));
00825   assert_param(IS_FLASH_LATENCY(FLatency));
00826 
00827   /* To correctly read data from FLASH memory, the number of wait states (LATENCY)
00828   must be correctly programmed according to the frequency of the CPU clock
00829     (HCLK) of the device. */
00830 
00831 #if defined(FLASH_ACR_LATENCY)
00832   /* Increasing the number of wait states because of higher CPU frequency */
00833   if (FLatency > __HAL_FLASH_GET_LATENCY())
00834   {
00835     /* Program the new number of wait states to the LATENCY bits in the FLASH_ACR register */
00836     __HAL_FLASH_SET_LATENCY(FLatency);
00837 
00838     /* Check that the new number of wait states is taken into account to access the Flash
00839     memory by reading the FLASH_ACR register */
00840     if (__HAL_FLASH_GET_LATENCY() != FLatency)
00841   {
00842     return HAL_ERROR;
00843   }
00844 }
00845 
00846 #endif /* FLASH_ACR_LATENCY */
00847 /*-------------------------- HCLK Configuration --------------------------*/
00848 if (((RCC_ClkInitStruct->ClockType) & RCC_CLOCKTYPE_HCLK) == RCC_CLOCKTYPE_HCLK)
00849   {
00850     /* Set the highest APBx dividers in order to ensure that we do not go through
00851     a non-spec phase whatever we decrease or increase HCLK. */
00852     if (((RCC_ClkInitStruct->ClockType) & RCC_CLOCKTYPE_PCLK1) == RCC_CLOCKTYPE_PCLK1)
00853     {
00854       MODIFY_REG(RCC->CFGR, RCC_CFGR_PPRE1, RCC_HCLK_DIV16);
00855     }
00856 
00857     if (((RCC_ClkInitStruct->ClockType) & RCC_CLOCKTYPE_PCLK2) == RCC_CLOCKTYPE_PCLK2)
00858     {
00859       MODIFY_REG(RCC->CFGR, RCC_CFGR_PPRE2, (RCC_HCLK_DIV16 << 3));
00860     }
00861 
00862     /* Set the new HCLK clock divider */
00863     assert_param(IS_RCC_HCLK(RCC_ClkInitStruct->AHBCLKDivider));
00864     MODIFY_REG(RCC->CFGR, RCC_CFGR_HPRE, RCC_ClkInitStruct->AHBCLKDivider);
00865   }
00866 
00867   /*------------------------- SYSCLK Configuration ---------------------------*/
00868   if (((RCC_ClkInitStruct->ClockType) & RCC_CLOCKTYPE_SYSCLK) == RCC_CLOCKTYPE_SYSCLK)
00869   {
00870     assert_param(IS_RCC_SYSCLKSOURCE(RCC_ClkInitStruct->SYSCLKSource));
00871 
00872     /* HSE is selected as System Clock Source */
00873     if (RCC_ClkInitStruct->SYSCLKSource == RCC_SYSCLKSOURCE_HSE)
00874     {
00875       /* Check the HSE ready flag */
00876       if (__HAL_RCC_GET_FLAG(RCC_FLAG_HSERDY) == RESET)
00877       {
00878         return HAL_ERROR;
00879       }
00880     }
00881     /* PLL is selected as System Clock Source */
00882     else if (RCC_ClkInitStruct->SYSCLKSource == RCC_SYSCLKSOURCE_PLLCLK)
00883     {
00884       /* Check the PLL ready flag */
00885       if (__HAL_RCC_GET_FLAG(RCC_FLAG_PLLRDY) == RESET)
00886       {
00887         return HAL_ERROR;
00888       }
00889     }
00890     /* HSI is selected as System Clock Source */
00891     else
00892     {
00893       /* Check the HSI ready flag */
00894       if (__HAL_RCC_GET_FLAG(RCC_FLAG_HSIRDY) == RESET)
00895       {
00896         return HAL_ERROR;
00897       }
00898     }
00899     __HAL_RCC_SYSCLK_CONFIG(RCC_ClkInitStruct->SYSCLKSource);
00900 
00901     /* Get Start Tick */
00902     tickstart = HAL_GetTick();
00903 
00904     while (__HAL_RCC_GET_SYSCLK_SOURCE() != (RCC_ClkInitStruct->SYSCLKSource << RCC_CFGR_SWS_Pos))
00905     {
00906       if ((HAL_GetTick() - tickstart) > CLOCKSWITCH_TIMEOUT_VALUE)
00907       {
00908         return HAL_TIMEOUT;
00909       }
00910     }
00911   }
00912 
00913 #if defined(FLASH_ACR_LATENCY)
00914   /* Decreasing the number of wait states because of lower CPU frequency */
00915   if (FLatency < __HAL_FLASH_GET_LATENCY())
00916   {
00917     /* Program the new number of wait states to the LATENCY bits in the FLASH_ACR register */
00918     __HAL_FLASH_SET_LATENCY(FLatency);
00919 
00920     /* Check that the new number of wait states is taken into account to access the Flash
00921     memory by reading the FLASH_ACR register */
00922     if (__HAL_FLASH_GET_LATENCY() != FLatency)
00923   {
00924     return HAL_ERROR;
00925   }
00926 }
00927 #endif /* FLASH_ACR_LATENCY */
00928 
00929 /*-------------------------- PCLK1 Configuration ---------------------------*/
00930 if (((RCC_ClkInitStruct->ClockType) & RCC_CLOCKTYPE_PCLK1) == RCC_CLOCKTYPE_PCLK1)
00931   {
00932     assert_param(IS_RCC_PCLK(RCC_ClkInitStruct->APB1CLKDivider));
00933     MODIFY_REG(RCC->CFGR, RCC_CFGR_PPRE1, RCC_ClkInitStruct->APB1CLKDivider);
00934   }
00935 
00936   /*-------------------------- PCLK2 Configuration ---------------------------*/
00937   if (((RCC_ClkInitStruct->ClockType) & RCC_CLOCKTYPE_PCLK2) == RCC_CLOCKTYPE_PCLK2)
00938   {
00939     assert_param(IS_RCC_PCLK(RCC_ClkInitStruct->APB2CLKDivider));
00940     MODIFY_REG(RCC->CFGR, RCC_CFGR_PPRE2, ((RCC_ClkInitStruct->APB2CLKDivider) << 3));
00941   }
00942 
00943   /* Update the SystemCoreClock global variable */
00944   SystemCoreClock = HAL_RCC_GetSysClockFreq() >> AHBPrescTable[(RCC->CFGR & RCC_CFGR_HPRE) >> RCC_CFGR_HPRE_Pos];
00945 
00946   /* Configure the source of time base considering new system clocks settings*/
00947   HAL_InitTick(uwTickPrio);
00948 
00949   return HAL_OK;
00950 }
00951 
00952 /**
00953   * @}
00954   */
00955 
00956 /** @defgroup RCC_Exported_Functions_Group2 Peripheral Control functions
00957   *  @brief   RCC clocks control functions
00958   *
00959   @verbatim
00960   ===============================================================================
00961                   ##### Peripheral Control functions #####
00962   ===============================================================================
00963     [..]
00964     This subsection provides a set of functions allowing to control the RCC Clocks
00965     frequencies.
00966 
00967   @endverbatim
00968   * @{
00969   */
00970 
00971 /**
00972   * @brief  Selects the clock source to output on MCO pin.
00973   * @note   MCO pin should be configured in alternate function mode.
00974   * @param  RCC_MCOx specifies the output direction for the clock source.
00975   *          This parameter can be one of the following values:
00976   *            @arg @ref RCC_MCO1 Clock source to output on MCO1 pin(PA8).
00977   * @param  RCC_MCOSource specifies the clock source to output.
00978   *          This parameter can be one of the following values:
00979   *            @arg @ref RCC_MCO1SOURCE_NOCLOCK     No clock selected as MCO clock
00980   *            @arg @ref RCC_MCO1SOURCE_SYSCLK      System clock selected as MCO clock
00981   *            @arg @ref RCC_MCO1SOURCE_HSI         HSI selected as MCO clock
00982   *            @arg @ref RCC_MCO1SOURCE_HSE         HSE selected as MCO clock
00983   @if STM32F105xC
00984   *            @arg @ref RCC_MCO1SOURCE_PLLCLK       PLL clock divided by 2 selected as MCO source
00985   *            @arg @ref RCC_MCO1SOURCE_PLL2CLK      PLL2 clock selected as MCO source
00986   *            @arg @ref RCC_MCO1SOURCE_PLL3CLK_DIV2 PLL3 clock divided by 2 selected as MCO source
00987   *            @arg @ref RCC_MCO1SOURCE_EXT_HSE      XT1 external 3-25 MHz oscillator clock selected as MCO source
00988   *            @arg @ref RCC_MCO1SOURCE_PLL3CLK      PLL3 clock selected as MCO source
00989   @endif
00990   @if STM32F107xC
00991   *            @arg @ref RCC_MCO1SOURCE_PLLCLK       PLL clock divided by 2 selected as MCO source
00992   *            @arg @ref RCC_MCO1SOURCE_PLL2CLK      PLL2 clock selected as MCO source
00993   *            @arg @ref RCC_MCO1SOURCE_PLL3CLK_DIV2 PLL3 clock divided by 2 selected as MCO source
00994   *            @arg @ref RCC_MCO1SOURCE_EXT_HSE XT1  external 3-25 MHz oscillator clock selected as MCO source
00995   *            @arg @ref RCC_MCO1SOURCE_PLL3CLK      PLL3 clock selected as MCO source
00996   @endif
00997   * @param  RCC_MCODiv specifies the MCO DIV.
00998   *          This parameter can be one of the following values:
00999   *            @arg @ref RCC_MCODIV_1 no division applied to MCO clock
01000   * @retval None
01001   */
01002 void HAL_RCC_MCOConfig(uint32_t RCC_MCOx, uint32_t RCC_MCOSource, uint32_t RCC_MCODiv)
01003 {
01004   GPIO_InitTypeDef gpio = {0U};
01005 
01006   /* Check the parameters */
01007   assert_param(IS_RCC_MCO(RCC_MCOx));
01008   assert_param(IS_RCC_MCODIV(RCC_MCODiv));
01009   assert_param(IS_RCC_MCO1SOURCE(RCC_MCOSource));
01010 
01011   /* Prevent unused argument(s) compilation warning */
01012   UNUSED(RCC_MCOx);
01013   UNUSED(RCC_MCODiv);
01014 
01015   /* Configure the MCO1 pin in alternate function mode */
01016   gpio.Mode      = GPIO_MODE_AF_PP;
01017   gpio.Speed     = GPIO_SPEED_FREQ_HIGH;
01018   gpio.Pull      = GPIO_NOPULL;
01019   gpio.Pin       = MCO1_PIN;
01020 
01021   /* MCO1 Clock Enable */
01022   MCO1_CLK_ENABLE();
01023 
01024   HAL_GPIO_Init(MCO1_GPIO_PORT, &gpio);
01025 
01026   /* Configure the MCO clock source */
01027   __HAL_RCC_MCO1_CONFIG(RCC_MCOSource, RCC_MCODiv);
01028 }
01029 
01030 /**
01031   * @brief  Enables the Clock Security System.
01032   * @note   If a failure is detected on the HSE oscillator clock, this oscillator
01033   *         is automatically disabled and an interrupt is generated to inform the
01034   *         software about the failure (Clock Security System Interrupt, CSSI),
01035   *         allowing the MCU to perform rescue operations. The CSSI is linked to
01036   *         the Cortex-M3 NMI (Non-Maskable Interrupt) exception vector.
01037   * @retval None
01038   */
01039 void HAL_RCC_EnableCSS(void)
01040 {
01041   *(__IO uint32_t *) RCC_CR_CSSON_BB = (uint32_t)ENABLE;
01042 }
01043 
01044 /**
01045   * @brief  Disables the Clock Security System.
01046   * @retval None
01047   */
01048 void HAL_RCC_DisableCSS(void)
01049 {
01050   *(__IO uint32_t *) RCC_CR_CSSON_BB = (uint32_t)DISABLE;
01051 }
01052 
01053 /**
01054   * @brief  Returns the SYSCLK frequency
01055   * @note   The system frequency computed by this function is not the real
01056   *         frequency in the chip. It is calculated based on the predefined
01057   *         constant and the selected clock source:
01058   * @note     If SYSCLK source is HSI, function returns values based on HSI_VALUE(*)
01059   * @note     If SYSCLK source is HSE, function returns a value based on HSE_VALUE
01060   *           divided by PREDIV factor(**)
01061   * @note     If SYSCLK source is PLL, function returns a value based on HSE_VALUE
01062   *           divided by PREDIV factor(**) or HSI_VALUE(*) multiplied by the PLL factor.
01063   * @note     (*) HSI_VALUE is a constant defined in stm32f1xx_hal_conf.h file (default value
01064   *               8 MHz) but the real value may vary depending on the variations
01065   *               in voltage and temperature.
01066   * @note     (**) HSE_VALUE is a constant defined in stm32f1xx_hal_conf.h file (default value
01067   *                8 MHz), user has to ensure that HSE_VALUE is same as the real
01068   *                frequency of the crystal used. Otherwise, this function may
01069   *                have wrong result.
01070   *
01071   * @note   The result of this function could be not correct when using fractional
01072   *         value for HSE crystal.
01073   *
01074   * @note   This function can be used by the user application to compute the
01075   *         baud-rate for the communication peripherals or configure other parameters.
01076   *
01077   * @note   Each time SYSCLK changes, this function must be called to update the
01078   *         right SYSCLK value. Otherwise, any configuration based on this function will be incorrect.
01079   *
01080   * @retval SYSCLK frequency
01081   */
01082 uint32_t HAL_RCC_GetSysClockFreq(void)
01083 {
01084 #if defined(RCC_CFGR2_PREDIV1SRC)
01085   const uint8_t aPLLMULFactorTable[14] = {0, 0, 4, 5, 6, 7, 8, 9, 0, 0, 0, 0, 0, 13};
01086   const uint8_t aPredivFactorTable[16] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16};
01087 #else
01088   const uint8_t aPLLMULFactorTable[16] = {2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 16};
01089 #if defined(RCC_CFGR2_PREDIV1)
01090   const uint8_t aPredivFactorTable[16] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16};
01091 #else
01092   const uint8_t aPredivFactorTable[2] = {1, 2};
01093 #endif /*RCC_CFGR2_PREDIV1*/
01094 
01095 #endif
01096   uint32_t tmpreg = 0U, prediv = 0U, pllclk = 0U, pllmul = 0U;
01097   uint32_t sysclockfreq = 0U;
01098 #if defined(RCC_CFGR2_PREDIV1SRC)
01099   uint32_t prediv2 = 0U, pll2mul = 0U;
01100 #endif /*RCC_CFGR2_PREDIV1SRC*/
01101 
01102   tmpreg = RCC->CFGR;
01103 
01104   /* Get SYSCLK source -------------------------------------------------------*/
01105   switch (tmpreg & RCC_CFGR_SWS)
01106   {
01107     case RCC_SYSCLKSOURCE_STATUS_HSE:  /* HSE used as system clock */
01108     {
01109       sysclockfreq = HSE_VALUE;
01110       break;
01111     }
01112     case RCC_SYSCLKSOURCE_STATUS_PLLCLK:  /* PLL used as system clock */
01113     {
01114       pllmul = aPLLMULFactorTable[(uint32_t)(tmpreg & RCC_CFGR_PLLMULL) >> RCC_CFGR_PLLMULL_Pos];
01115       if ((tmpreg & RCC_CFGR_PLLSRC) != RCC_PLLSOURCE_HSI_DIV2)
01116       {
01117 #if defined(RCC_CFGR2_PREDIV1)
01118         prediv = aPredivFactorTable[(uint32_t)(RCC->CFGR2 & RCC_CFGR2_PREDIV1) >> RCC_CFGR2_PREDIV1_Pos];
01119 #else
01120         prediv = aPredivFactorTable[(uint32_t)(RCC->CFGR & RCC_CFGR_PLLXTPRE) >> RCC_CFGR_PLLXTPRE_Pos];
01121 #endif /*RCC_CFGR2_PREDIV1*/
01122 #if defined(RCC_CFGR2_PREDIV1SRC)
01123 
01124         if (HAL_IS_BIT_SET(RCC->CFGR2, RCC_CFGR2_PREDIV1SRC))
01125         {
01126           /* PLL2 selected as Prediv1 source */
01127           /* PLLCLK = PLL2CLK / PREDIV1 * PLLMUL with PLL2CLK = HSE/PREDIV2 * PLL2MUL */
01128           prediv2 = ((RCC->CFGR2 & RCC_CFGR2_PREDIV2) >> RCC_CFGR2_PREDIV2_Pos) + 1;
01129           pll2mul = ((RCC->CFGR2 & RCC_CFGR2_PLL2MUL) >> RCC_CFGR2_PLL2MUL_Pos) + 2;
01130           pllclk = (uint32_t)(((uint64_t)HSE_VALUE * (uint64_t)pll2mul * (uint64_t)pllmul) / ((uint64_t)prediv2 * (uint64_t)prediv));
01131         }
01132         else
01133         {
01134           /* HSE used as PLL clock source : PLLCLK = HSE/PREDIV1 * PLLMUL */
01135           pllclk = (uint32_t)((HSE_VALUE * pllmul) / prediv);
01136         }
01137 
01138         /* If PLLMUL was set to 13 means that it was to cover the case PLLMUL 6.5 (avoid using float) */
01139         /* In this case need to divide pllclk by 2 */
01140         if (pllmul == aPLLMULFactorTable[(uint32_t)(RCC_CFGR_PLLMULL6_5) >> RCC_CFGR_PLLMULL_Pos])
01141         {
01142           pllclk = pllclk / 2;
01143         }
01144 #else
01145         /* HSE used as PLL clock source : PLLCLK = HSE/PREDIV1 * PLLMUL */
01146         pllclk = (uint32_t)((HSE_VALUE  * pllmul) / prediv);
01147 #endif /*RCC_CFGR2_PREDIV1SRC*/
01148       }
01149       else
01150       {
01151         /* HSI used as PLL clock source : PLLCLK = HSI/2 * PLLMUL */
01152         pllclk = (uint32_t)((HSI_VALUE >> 1) * pllmul);
01153       }
01154       sysclockfreq = pllclk;
01155       break;
01156     }
01157     case RCC_SYSCLKSOURCE_STATUS_HSI:  /* HSI used as system clock source */
01158     default: /* HSI used as system clock */
01159     {
01160       sysclockfreq = HSI_VALUE;
01161       break;
01162     }
01163   }
01164   return sysclockfreq;
01165 }
01166 
01167 /**
01168   * @brief  Returns the HCLK frequency
01169   * @note   Each time HCLK changes, this function must be called to update the
01170   *         right HCLK value. Otherwise, any configuration based on this function will be incorrect.
01171   *
01172   * @note   The SystemCoreClock CMSIS variable is used to store System Clock Frequency
01173   *         and updated within this function
01174   * @retval HCLK frequency
01175   */
01176 uint32_t HAL_RCC_GetHCLKFreq(void)
01177 {
01178   return SystemCoreClock;
01179 }
01180 
01181 /**
01182   * @brief  Returns the PCLK1 frequency
01183   * @note   Each time PCLK1 changes, this function must be called to update the
01184   *         right PCLK1 value. Otherwise, any configuration based on this function will be incorrect.
01185   * @retval PCLK1 frequency
01186   */
01187 uint32_t HAL_RCC_GetPCLK1Freq(void)
01188 {
01189   /* Get HCLK source and Compute PCLK1 frequency ---------------------------*/
01190   return (HAL_RCC_GetHCLKFreq() >> APBPrescTable[(RCC->CFGR & RCC_CFGR_PPRE1) >> RCC_CFGR_PPRE1_Pos]);
01191 }
01192 
01193 /**
01194   * @brief  Returns the PCLK2 frequency
01195   * @note   Each time PCLK2 changes, this function must be called to update the
01196   *         right PCLK2 value. Otherwise, any configuration based on this function will be incorrect.
01197   * @retval PCLK2 frequency
01198   */
01199 uint32_t HAL_RCC_GetPCLK2Freq(void)
01200 {
01201   /* Get HCLK source and Compute PCLK2 frequency ---------------------------*/
01202   return (HAL_RCC_GetHCLKFreq() >> APBPrescTable[(RCC->CFGR & RCC_CFGR_PPRE2) >> RCC_CFGR_PPRE2_Pos]);
01203 }
01204 
01205 /**
01206   * @brief  Configures the RCC_OscInitStruct according to the internal
01207   * RCC configuration registers.
01208   * @param  RCC_OscInitStruct pointer to an RCC_OscInitTypeDef structure that
01209   * will be configured.
01210   * @retval None
01211   */
01212 void HAL_RCC_GetOscConfig(RCC_OscInitTypeDef  *RCC_OscInitStruct)
01213 {
01214   /* Check the parameters */
01215   assert_param(RCC_OscInitStruct != NULL);
01216 
01217   /* Set all possible values for the Oscillator type parameter ---------------*/
01218   RCC_OscInitStruct->OscillatorType = RCC_OSCILLATORTYPE_HSE | RCC_OSCILLATORTYPE_HSI  \
01219                                       | RCC_OSCILLATORTYPE_LSE | RCC_OSCILLATORTYPE_LSI;
01220 
01221 #if defined(RCC_CFGR2_PREDIV1SRC)
01222   /* Get the Prediv1 source --------------------------------------------------*/
01223   RCC_OscInitStruct->Prediv1Source = READ_BIT(RCC->CFGR2, RCC_CFGR2_PREDIV1SRC);
01224 #endif /* RCC_CFGR2_PREDIV1SRC */
01225 
01226   /* Get the HSE configuration -----------------------------------------------*/
01227   if ((RCC->CR & RCC_CR_HSEBYP) == RCC_CR_HSEBYP)
01228   {
01229     RCC_OscInitStruct->HSEState = RCC_HSE_BYPASS;
01230   }
01231   else if ((RCC->CR & RCC_CR_HSEON) == RCC_CR_HSEON)
01232   {
01233     RCC_OscInitStruct->HSEState = RCC_HSE_ON;
01234   }
01235   else
01236   {
01237     RCC_OscInitStruct->HSEState = RCC_HSE_OFF;
01238   }
01239   RCC_OscInitStruct->HSEPredivValue = __HAL_RCC_HSE_GET_PREDIV();
01240 
01241   /* Get the HSI configuration -----------------------------------------------*/
01242   if ((RCC->CR & RCC_CR_HSION) == RCC_CR_HSION)
01243   {
01244     RCC_OscInitStruct->HSIState = RCC_HSI_ON;
01245   }
01246   else
01247   {
01248     RCC_OscInitStruct->HSIState = RCC_HSI_OFF;
01249   }
01250 
01251   RCC_OscInitStruct->HSICalibrationValue = (uint32_t)((RCC->CR & RCC_CR_HSITRIM) >> RCC_CR_HSITRIM_Pos);
01252 
01253   /* Get the LSE configuration -----------------------------------------------*/
01254   if ((RCC->BDCR & RCC_BDCR_LSEBYP) == RCC_BDCR_LSEBYP)
01255   {
01256     RCC_OscInitStruct->LSEState = RCC_LSE_BYPASS;
01257   }
01258   else if ((RCC->BDCR & RCC_BDCR_LSEON) == RCC_BDCR_LSEON)
01259   {
01260     RCC_OscInitStruct->LSEState = RCC_LSE_ON;
01261   }
01262   else
01263   {
01264     RCC_OscInitStruct->LSEState = RCC_LSE_OFF;
01265   }
01266 
01267   /* Get the LSI configuration -----------------------------------------------*/
01268   if ((RCC->CSR & RCC_CSR_LSION) == RCC_CSR_LSION)
01269   {
01270     RCC_OscInitStruct->LSIState = RCC_LSI_ON;
01271   }
01272   else
01273   {
01274     RCC_OscInitStruct->LSIState = RCC_LSI_OFF;
01275   }
01276 
01277 
01278   /* Get the PLL configuration -----------------------------------------------*/
01279   if ((RCC->CR & RCC_CR_PLLON) == RCC_CR_PLLON)
01280   {
01281     RCC_OscInitStruct->PLL.PLLState = RCC_PLL_ON;
01282   }
01283   else
01284   {
01285     RCC_OscInitStruct->PLL.PLLState = RCC_PLL_OFF;
01286   }
01287   RCC_OscInitStruct->PLL.PLLSource = (uint32_t)(RCC->CFGR & RCC_CFGR_PLLSRC);
01288   RCC_OscInitStruct->PLL.PLLMUL = (uint32_t)(RCC->CFGR & RCC_CFGR_PLLMULL);
01289 #if defined(RCC_CR_PLL2ON)
01290   /* Get the PLL2 configuration -----------------------------------------------*/
01291   if ((RCC->CR & RCC_CR_PLL2ON) == RCC_CR_PLL2ON)
01292   {
01293     RCC_OscInitStruct->PLL2.PLL2State = RCC_PLL2_ON;
01294   }
01295   else
01296   {
01297     RCC_OscInitStruct->PLL2.PLL2State = RCC_PLL2_OFF;
01298   }
01299   RCC_OscInitStruct->PLL2.HSEPrediv2Value = __HAL_RCC_HSE_GET_PREDIV2();
01300   RCC_OscInitStruct->PLL2.PLL2MUL = (uint32_t)(RCC->CFGR2 & RCC_CFGR2_PLL2MUL);
01301 #endif /* RCC_CR_PLL2ON */
01302 }
01303 
01304 /**
01305   * @brief  Get the RCC_ClkInitStruct according to the internal
01306   * RCC configuration registers.
01307   * @param  RCC_ClkInitStruct pointer to an RCC_ClkInitTypeDef structure that
01308   * contains the current clock configuration.
01309   * @param  pFLatency Pointer on the Flash Latency.
01310   * @retval None
01311   */
01312 void HAL_RCC_GetClockConfig(RCC_ClkInitTypeDef  *RCC_ClkInitStruct, uint32_t *pFLatency)
01313 {
01314   /* Check the parameters */
01315   assert_param(RCC_ClkInitStruct != NULL);
01316   assert_param(pFLatency != NULL);
01317 
01318   /* Set all possible values for the Clock type parameter --------------------*/
01319   RCC_ClkInitStruct->ClockType = RCC_CLOCKTYPE_SYSCLK | RCC_CLOCKTYPE_HCLK | RCC_CLOCKTYPE_PCLK1 | RCC_CLOCKTYPE_PCLK2;
01320 
01321   /* Get the SYSCLK configuration --------------------------------------------*/
01322   RCC_ClkInitStruct->SYSCLKSource = (uint32_t)(RCC->CFGR & RCC_CFGR_SW);
01323 
01324   /* Get the HCLK configuration ----------------------------------------------*/
01325   RCC_ClkInitStruct->AHBCLKDivider = (uint32_t)(RCC->CFGR & RCC_CFGR_HPRE);
01326 
01327   /* Get the APB1 configuration ----------------------------------------------*/
01328   RCC_ClkInitStruct->APB1CLKDivider = (uint32_t)(RCC->CFGR & RCC_CFGR_PPRE1);
01329 
01330   /* Get the APB2 configuration ----------------------------------------------*/
01331   RCC_ClkInitStruct->APB2CLKDivider = (uint32_t)((RCC->CFGR & RCC_CFGR_PPRE2) >> 3);
01332 
01333 #if   defined(FLASH_ACR_LATENCY)
01334   /* Get the Flash Wait State (Latency) configuration ------------------------*/
01335   *pFLatency = (uint32_t)(FLASH->ACR & FLASH_ACR_LATENCY);
01336 #else
01337   /* For VALUE lines devices, only LATENCY_0 can be set*/
01338   *pFLatency = (uint32_t)FLASH_LATENCY_0;
01339 #endif
01340 }
01341 
01342 /**
01343   * @brief This function handles the RCC CSS interrupt request.
01344   * @note This API should be called under the NMI_Handler().
01345   * @retval None
01346   */
01347 void HAL_RCC_NMI_IRQHandler(void)
01348 {
01349   /* Check RCC CSSF flag  */
01350   if (__HAL_RCC_GET_IT(RCC_IT_CSS))
01351   {
01352     /* RCC Clock Security System interrupt user callback */
01353     HAL_RCC_CSSCallback();
01354 
01355     /* Clear RCC CSS pending bit */
01356     __HAL_RCC_CLEAR_IT(RCC_IT_CSS);
01357   }
01358 }
01359 
01360 /**
01361   * @brief  This function provides delay (in milliseconds) based on CPU cycles method.
01362   * @param  mdelay: specifies the delay time length, in milliseconds.
01363   * @retval None
01364   */
01365 static void RCC_Delay(uint32_t mdelay)
01366 {
01367   __IO uint32_t Delay = mdelay * (SystemCoreClock / 8U / 1000U);
01368   do
01369   {
01370     __NOP();
01371   }
01372   while (Delay --);
01373 }
01374 
01375 /**
01376   * @brief  RCC Clock Security System interrupt callback
01377   * @retval none
01378   */
01379 __weak void HAL_RCC_CSSCallback(void)
01380 {
01381   /* NOTE : This function Should not be modified, when the callback is needed,
01382     the HAL_RCC_CSSCallback could be implemented in the user file
01383     */
01384 }
01385 
01386 /**
01387   * @}
01388   */
01389 
01390 /**
01391   * @}
01392   */
01393 
01394 #endif /* HAL_RCC_MODULE_ENABLED */
01395 /**
01396   * @}
01397   */
01398 
01399 /**
01400   * @}
01401   */
01402 
01403 /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/