STM32F103xB HAL User Manual
stm32f1xx_hal_rcc_ex.c
Go to the documentation of this file.
00001 /**
00002   ******************************************************************************
00003   * @file    stm32f1xx_hal_rcc_ex.c
00004   * @author  MCD Application Team
00005   * @brief   Extended RCC HAL module driver.
00006   *          This file provides firmware functions to manage the following
00007   *          functionalities RCC extension peripheral:
00008   *           + Extended Peripheral Control functions
00009   *
00010   ******************************************************************************
00011   * @attention
00012   *
00013   * <h2><center>&copy; Copyright (c) 2016 STMicroelectronics.
00014   * All rights reserved.</center></h2>
00015   *
00016   * This software component is licensed by ST under BSD 3-Clause license,
00017   * the "License"; You may not use this file except in compliance with the
00018   * License. You may obtain a copy of the License at:
00019   *                        opensource.org/licenses/BSD-3-Clause
00020   *
00021   ******************************************************************************
00022   */
00023 
00024 /* Includes ------------------------------------------------------------------*/
00025 #include "stm32f1xx_hal.h"
00026 
00027 /** @addtogroup STM32F1xx_HAL_Driver
00028   * @{
00029   */
00030 
00031 #ifdef HAL_RCC_MODULE_ENABLED
00032 
00033 /** @defgroup RCCEx RCCEx
00034   * @brief RCC Extension HAL module driver.
00035   * @{
00036   */
00037 
00038 /* Private typedef -----------------------------------------------------------*/
00039 /* Private define ------------------------------------------------------------*/
00040 /** @defgroup RCCEx_Private_Constants RCCEx Private Constants
00041   * @{
00042   */
00043 /**
00044   * @}
00045   */
00046 
00047 /* Private macro -------------------------------------------------------------*/
00048 /** @defgroup RCCEx_Private_Macros RCCEx Private Macros
00049   * @{
00050   */
00051 /**
00052   * @}
00053   */
00054 
00055 /* Private variables ---------------------------------------------------------*/
00056 /* Private function prototypes -----------------------------------------------*/
00057 /* Private functions ---------------------------------------------------------*/
00058 
00059 /** @defgroup RCCEx_Exported_Functions RCCEx Exported Functions
00060   * @{
00061   */
00062 
00063 /** @defgroup RCCEx_Exported_Functions_Group1 Peripheral Control functions
00064   *  @brief  Extended Peripheral Control functions
00065   *
00066 @verbatim
00067  ===============================================================================
00068                 ##### Extended Peripheral Control functions  #####
00069  ===============================================================================
00070     [..]
00071     This subsection provides a set of functions allowing to control the RCC Clocks
00072     frequencies.
00073     [..]
00074     (@) Important note: Care must be taken when HAL_RCCEx_PeriphCLKConfig() is used to
00075         select the RTC clock source; in this case the Backup domain will be reset in
00076         order to modify the RTC Clock source, as consequence RTC registers (including
00077         the backup registers) are set to their reset values.
00078 
00079 @endverbatim
00080   * @{
00081   */
00082 
00083 /**
00084   * @brief  Initializes the RCC extended peripherals clocks according to the specified parameters in the
00085   *         RCC_PeriphCLKInitTypeDef.
00086   * @param  PeriphClkInit pointer to an RCC_PeriphCLKInitTypeDef structure that
00087   *         contains the configuration information for the Extended Peripherals clocks(RTC clock).
00088   *
00089   * @note   Care must be taken when HAL_RCCEx_PeriphCLKConfig() is used to select
00090   *         the RTC clock source; in this case the Backup domain will be reset in
00091   *         order to modify the RTC Clock source, as consequence RTC registers (including
00092   *         the backup registers) are set to their reset values.
00093   *
00094   * @note   In case of STM32F105xC or STM32F107xC devices, PLLI2S will be enabled if requested on
00095   *         one of 2 I2S interfaces. When PLLI2S is enabled, you need to call HAL_RCCEx_DisablePLLI2S to
00096   *         manually disable it.
00097   *
00098   * @retval HAL status
00099   */
00100 HAL_StatusTypeDef HAL_RCCEx_PeriphCLKConfig(RCC_PeriphCLKInitTypeDef  *PeriphClkInit)
00101 {
00102   uint32_t tickstart = 0U, temp_reg = 0U;
00103 #if defined(STM32F105xC) || defined(STM32F107xC)
00104   uint32_t  pllactive = 0U;
00105 #endif /* STM32F105xC || STM32F107xC */
00106 
00107   /* Check the parameters */
00108   assert_param(IS_RCC_PERIPHCLOCK(PeriphClkInit->PeriphClockSelection));
00109 
00110   /*------------------------------- RTC/LCD Configuration ------------------------*/
00111   if ((((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_RTC) == RCC_PERIPHCLK_RTC))
00112   {
00113     FlagStatus pwrclkchanged = RESET;
00114 
00115     /* check for RTC Parameters used to output RTCCLK */
00116     assert_param(IS_RCC_RTCCLKSOURCE(PeriphClkInit->RTCClockSelection));
00117 
00118     /* As soon as function is called to change RTC clock source, activation of the
00119        power domain is done. */
00120     /* Requires to enable write access to Backup Domain of necessary */
00121     if (__HAL_RCC_PWR_IS_CLK_DISABLED())
00122     {
00123       __HAL_RCC_PWR_CLK_ENABLE();
00124       pwrclkchanged = SET;
00125     }
00126 
00127     if (HAL_IS_BIT_CLR(PWR->CR, PWR_CR_DBP))
00128     {
00129       /* Enable write access to Backup domain */
00130       SET_BIT(PWR->CR, PWR_CR_DBP);
00131 
00132       /* Wait for Backup domain Write protection disable */
00133       tickstart = HAL_GetTick();
00134 
00135       while (HAL_IS_BIT_CLR(PWR->CR, PWR_CR_DBP))
00136       {
00137         if ((HAL_GetTick() - tickstart) > RCC_DBP_TIMEOUT_VALUE)
00138         {
00139           return HAL_TIMEOUT;
00140         }
00141       }
00142     }
00143 
00144     /* Reset the Backup domain only if the RTC Clock source selection is modified from reset value */
00145     temp_reg = (RCC->BDCR & RCC_BDCR_RTCSEL);
00146     if ((temp_reg != 0x00000000U) && (temp_reg != (PeriphClkInit->RTCClockSelection & RCC_BDCR_RTCSEL)))
00147     {
00148       /* Store the content of BDCR register before the reset of Backup Domain */
00149       temp_reg = (RCC->BDCR & ~(RCC_BDCR_RTCSEL));
00150       /* RTC Clock selection can be changed only if the Backup Domain is reset */
00151       __HAL_RCC_BACKUPRESET_FORCE();
00152       __HAL_RCC_BACKUPRESET_RELEASE();
00153       /* Restore the Content of BDCR register */
00154       RCC->BDCR = temp_reg;
00155 
00156       /* Wait for LSERDY if LSE was enabled */
00157       if (HAL_IS_BIT_SET(temp_reg, RCC_BDCR_LSEON))
00158       {
00159         /* Get Start Tick */
00160         tickstart = HAL_GetTick();
00161 
00162         /* Wait till LSE is ready */
00163         while (__HAL_RCC_GET_FLAG(RCC_FLAG_LSERDY) == RESET)
00164         {
00165           if ((HAL_GetTick() - tickstart) > RCC_LSE_TIMEOUT_VALUE)
00166           {
00167             return HAL_TIMEOUT;
00168           }
00169         }
00170       }
00171     }
00172     __HAL_RCC_RTC_CONFIG(PeriphClkInit->RTCClockSelection);
00173 
00174     /* Require to disable power clock if necessary */
00175     if (pwrclkchanged == SET)
00176     {
00177       __HAL_RCC_PWR_CLK_DISABLE();
00178     }
00179   }
00180 
00181   /*------------------------------ ADC clock Configuration ------------------*/
00182   if (((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_ADC) == RCC_PERIPHCLK_ADC)
00183   {
00184     /* Check the parameters */
00185     assert_param(IS_RCC_ADCPLLCLK_DIV(PeriphClkInit->AdcClockSelection));
00186 
00187     /* Configure the ADC clock source */
00188     __HAL_RCC_ADC_CONFIG(PeriphClkInit->AdcClockSelection);
00189   }
00190 
00191 #if defined(STM32F105xC) || defined(STM32F107xC)
00192   /*------------------------------ I2S2 Configuration ------------------------*/
00193   if (((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_I2S2) == RCC_PERIPHCLK_I2S2)
00194   {
00195     /* Check the parameters */
00196     assert_param(IS_RCC_I2S2CLKSOURCE(PeriphClkInit->I2s2ClockSelection));
00197 
00198     /* Configure the I2S2 clock source */
00199     __HAL_RCC_I2S2_CONFIG(PeriphClkInit->I2s2ClockSelection);
00200   }
00201 
00202   /*------------------------------ I2S3 Configuration ------------------------*/
00203   if (((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_I2S3) == RCC_PERIPHCLK_I2S3)
00204   {
00205     /* Check the parameters */
00206     assert_param(IS_RCC_I2S3CLKSOURCE(PeriphClkInit->I2s3ClockSelection));
00207 
00208     /* Configure the I2S3 clock source */
00209     __HAL_RCC_I2S3_CONFIG(PeriphClkInit->I2s3ClockSelection);
00210   }
00211 
00212   /*------------------------------ PLL I2S Configuration ----------------------*/
00213   /* Check that PLLI2S need to be enabled */
00214   if (HAL_IS_BIT_SET(RCC->CFGR2, RCC_CFGR2_I2S2SRC) || HAL_IS_BIT_SET(RCC->CFGR2, RCC_CFGR2_I2S3SRC))
00215   {
00216     /* Update flag to indicate that PLL I2S should be active */
00217     pllactive = 1;
00218   }
00219 
00220   /* Check if PLL I2S need to be enabled */
00221   if (pllactive == 1)
00222   {
00223     /* Enable PLL I2S only if not active */
00224     if (HAL_IS_BIT_CLR(RCC->CR, RCC_CR_PLL3ON))
00225     {
00226       /* Check the parameters */
00227       assert_param(IS_RCC_PLLI2S_MUL(PeriphClkInit->PLLI2S.PLLI2SMUL));
00228       assert_param(IS_RCC_HSE_PREDIV2(PeriphClkInit->PLLI2S.HSEPrediv2Value));
00229 
00230       /* Prediv2 can be written only when the PLL2 is disabled. */
00231       /* Return an error only if new value is different from the programmed value */
00232       if (HAL_IS_BIT_SET(RCC->CR, RCC_CR_PLL2ON) && \
00233           (__HAL_RCC_HSE_GET_PREDIV2() != PeriphClkInit->PLLI2S.HSEPrediv2Value))
00234       {
00235         return HAL_ERROR;
00236       }
00237 
00238       /* Configure the HSE prediv2 factor --------------------------------*/
00239       __HAL_RCC_HSE_PREDIV2_CONFIG(PeriphClkInit->PLLI2S.HSEPrediv2Value);
00240 
00241       /* Configure the main PLLI2S multiplication factors. */
00242       __HAL_RCC_PLLI2S_CONFIG(PeriphClkInit->PLLI2S.PLLI2SMUL);
00243 
00244       /* Enable the main PLLI2S. */
00245       __HAL_RCC_PLLI2S_ENABLE();
00246 
00247       /* Get Start Tick*/
00248       tickstart = HAL_GetTick();
00249 
00250       /* Wait till PLLI2S is ready */
00251       while (__HAL_RCC_GET_FLAG(RCC_FLAG_PLLI2SRDY)  == RESET)
00252       {
00253         if ((HAL_GetTick() - tickstart) > PLLI2S_TIMEOUT_VALUE)
00254         {
00255           return HAL_TIMEOUT;
00256         }
00257       }
00258     }
00259     else
00260     {
00261       /* Return an error only if user wants to change the PLLI2SMUL whereas PLLI2S is active */
00262       if (READ_BIT(RCC->CFGR2, RCC_CFGR2_PLL3MUL) != PeriphClkInit->PLLI2S.PLLI2SMUL)
00263       {
00264         return HAL_ERROR;
00265       }
00266     }
00267   }
00268 #endif /* STM32F105xC || STM32F107xC */
00269 
00270 #if defined(STM32F102x6) || defined(STM32F102xB) || defined(STM32F103x6)\
00271  || defined(STM32F103xB) || defined(STM32F103xE) || defined(STM32F103xG)\
00272  || defined(STM32F105xC) || defined(STM32F107xC)
00273   /*------------------------------ USB clock Configuration ------------------*/
00274   if (((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_USB) == RCC_PERIPHCLK_USB)
00275   {
00276     /* Check the parameters */
00277     assert_param(IS_RCC_USBPLLCLK_DIV(PeriphClkInit->UsbClockSelection));
00278 
00279     /* Configure the USB clock source */
00280     __HAL_RCC_USB_CONFIG(PeriphClkInit->UsbClockSelection);
00281   }
00282 #endif /* STM32F102x6 || STM32F102xB || STM32F103x6 || STM32F103xB || STM32F103xE || STM32F103xG || STM32F105xC || STM32F107xC */
00283 
00284   return HAL_OK;
00285 }
00286 
00287 /**
00288   * @brief  Get the PeriphClkInit according to the internal
00289   * RCC configuration registers.
00290   * @param  PeriphClkInit pointer to an RCC_PeriphCLKInitTypeDef structure that
00291   *         returns the configuration information for the Extended Peripherals clocks(RTC, I2S, ADC clocks).
00292   * @retval None
00293   */
00294 void HAL_RCCEx_GetPeriphCLKConfig(RCC_PeriphCLKInitTypeDef  *PeriphClkInit)
00295 {
00296   uint32_t srcclk = 0U;
00297 
00298   /* Set all possible values for the extended clock type parameter------------*/
00299   PeriphClkInit->PeriphClockSelection = RCC_PERIPHCLK_RTC;
00300 
00301   /* Get the RTC configuration -----------------------------------------------*/
00302   srcclk = __HAL_RCC_GET_RTC_SOURCE();
00303   /* Source clock is LSE or LSI*/
00304   PeriphClkInit->RTCClockSelection = srcclk;
00305 
00306   /* Get the ADC clock configuration -----------------------------------------*/
00307   PeriphClkInit->PeriphClockSelection |= RCC_PERIPHCLK_ADC;
00308   PeriphClkInit->AdcClockSelection = __HAL_RCC_GET_ADC_SOURCE();
00309 
00310 #if defined(STM32F105xC) || defined(STM32F107xC)
00311   /* Get the I2S2 clock configuration -----------------------------------------*/
00312   PeriphClkInit->PeriphClockSelection |= RCC_PERIPHCLK_I2S2;
00313   PeriphClkInit->I2s2ClockSelection = __HAL_RCC_GET_I2S2_SOURCE();
00314 
00315   /* Get the I2S3 clock configuration -----------------------------------------*/
00316   PeriphClkInit->PeriphClockSelection |= RCC_PERIPHCLK_I2S3;
00317   PeriphClkInit->I2s3ClockSelection = __HAL_RCC_GET_I2S3_SOURCE();
00318 
00319 #endif /* STM32F105xC || STM32F107xC */
00320 
00321 #if defined(STM32F103xE) || defined(STM32F103xG)
00322   /* Get the I2S2 clock configuration -----------------------------------------*/
00323   PeriphClkInit->PeriphClockSelection |= RCC_PERIPHCLK_I2S2;
00324   PeriphClkInit->I2s2ClockSelection = RCC_I2S2CLKSOURCE_SYSCLK;
00325 
00326   /* Get the I2S3 clock configuration -----------------------------------------*/
00327   PeriphClkInit->PeriphClockSelection |= RCC_PERIPHCLK_I2S3;
00328   PeriphClkInit->I2s3ClockSelection = RCC_I2S3CLKSOURCE_SYSCLK;
00329 
00330 #endif /* STM32F103xE || STM32F103xG */
00331 
00332 #if defined(STM32F102x6) || defined(STM32F102xB) || defined(STM32F103x6)\
00333  || defined(STM32F103xB) || defined(STM32F103xE) || defined(STM32F103xG)\
00334  || defined(STM32F105xC) || defined(STM32F107xC)
00335   /* Get the USB clock configuration -----------------------------------------*/
00336   PeriphClkInit->PeriphClockSelection |= RCC_PERIPHCLK_USB;
00337   PeriphClkInit->UsbClockSelection = __HAL_RCC_GET_USB_SOURCE();
00338 #endif /* STM32F102x6 || STM32F102xB || STM32F103x6 || STM32F103xB || STM32F103xE || STM32F103xG || STM32F105xC || STM32F107xC */
00339 }
00340 
00341 /**
00342   * @brief  Returns the peripheral clock frequency
00343   * @note   Returns 0 if peripheral clock is unknown
00344   * @param  PeriphClk Peripheral clock identifier
00345   *         This parameter can be one of the following values:
00346   *            @arg @ref RCC_PERIPHCLK_RTC  RTC peripheral clock
00347   *            @arg @ref RCC_PERIPHCLK_ADC  ADC peripheral clock
00348   @if STM32F103xE
00349   *            @arg @ref RCC_PERIPHCLK_I2S2 I2S2 peripheral clock
00350   *            @arg @ref RCC_PERIPHCLK_I2S3 I2S3 peripheral clock
00351   *            @arg @ref RCC_PERIPHCLK_I2S3 I2S3 peripheral clock
00352   @endif
00353   @if STM32F103xG
00354   *            @arg @ref RCC_PERIPHCLK_I2S2 I2S2 peripheral clock
00355   *            @arg @ref RCC_PERIPHCLK_I2S3 I2S3 peripheral clock
00356   *            @arg @ref RCC_PERIPHCLK_I2S3 I2S3 peripheral clock
00357   *            @arg @ref RCC_PERIPHCLK_I2S2 I2S2 peripheral clock
00358   @endif
00359   @if STM32F105xC
00360   *            @arg @ref RCC_PERIPHCLK_I2S2 I2S2 peripheral clock
00361   *            @arg @ref RCC_PERIPHCLK_I2S3 I2S3 peripheral clock
00362   *            @arg @ref RCC_PERIPHCLK_I2S3 I2S3 peripheral clock
00363   *            @arg @ref RCC_PERIPHCLK_I2S2 I2S2 peripheral clock
00364   *            @arg @ref RCC_PERIPHCLK_I2S3 I2S3 peripheral clock
00365   *            @arg @ref RCC_PERIPHCLK_I2S3 I2S3 peripheral clock
00366   *            @arg @ref RCC_PERIPHCLK_I2S2 I2S2 peripheral clock
00367   *            @arg @ref RCC_PERIPHCLK_USB  USB peripheral clock
00368   @endif
00369   @if STM32F107xC
00370   *            @arg @ref RCC_PERIPHCLK_I2S2 I2S2 peripheral clock
00371   *            @arg @ref RCC_PERIPHCLK_I2S3 I2S3 peripheral clock
00372   *            @arg @ref RCC_PERIPHCLK_I2S3 I2S3 peripheral clock
00373   *            @arg @ref RCC_PERIPHCLK_I2S2 I2S2 peripheral clock
00374   *            @arg @ref RCC_PERIPHCLK_I2S3 I2S3 peripheral clock
00375   *            @arg @ref RCC_PERIPHCLK_I2S3 I2S3 peripheral clock
00376   *            @arg @ref RCC_PERIPHCLK_I2S2 I2S2 peripheral clock
00377   *            @arg @ref RCC_PERIPHCLK_USB  USB peripheral clock
00378   @endif
00379   @if STM32F102xx
00380   *            @arg @ref RCC_PERIPHCLK_USB  USB peripheral clock
00381   @endif
00382   @if STM32F103xx
00383   *            @arg @ref RCC_PERIPHCLK_USB  USB peripheral clock
00384   @endif
00385   * @retval Frequency in Hz (0: means that no available frequency for the peripheral)
00386   */
00387 uint32_t HAL_RCCEx_GetPeriphCLKFreq(uint32_t PeriphClk)
00388 {
00389 #if defined(STM32F105xC) || defined(STM32F107xC)
00390   const uint8_t aPLLMULFactorTable[14] = {0, 0, 4, 5, 6, 7, 8, 9, 0, 0, 0, 0, 0, 13};
00391   const uint8_t aPredivFactorTable[16] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16};
00392 
00393   uint32_t prediv1 = 0U, pllclk = 0U, pllmul = 0U;
00394   uint32_t pll2mul = 0U, pll3mul = 0U, prediv2 = 0U;
00395 #endif /* STM32F105xC || STM32F107xC */
00396 #if defined(STM32F102x6) || defined(STM32F102xB) || defined(STM32F103x6) || \
00397     defined(STM32F103xB) || defined(STM32F103xE) || defined(STM32F103xG)
00398   const uint8_t aPLLMULFactorTable[16] = {2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 16};
00399   const uint8_t aPredivFactorTable[2] = {1, 2};
00400 
00401   uint32_t prediv1 = 0U, pllclk = 0U, pllmul = 0U;
00402 #endif /* STM32F102x6 || STM32F102xB || STM32F103x6 || STM32F103xB || STM32F103xE || STM32F103xG */
00403   uint32_t temp_reg = 0U, frequency = 0U;
00404 
00405   /* Check the parameters */
00406   assert_param(IS_RCC_PERIPHCLOCK(PeriphClk));
00407 
00408   switch (PeriphClk)
00409   {
00410 #if defined(STM32F102x6) || defined(STM32F102xB) || defined(STM32F103x6)\
00411  || defined(STM32F103xB) || defined(STM32F103xE) || defined(STM32F103xG)\
00412  || defined(STM32F105xC) || defined(STM32F107xC)
00413     case RCC_PERIPHCLK_USB:
00414     {
00415       /* Get RCC configuration ------------------------------------------------------*/
00416       temp_reg = RCC->CFGR;
00417 
00418       /* Check if PLL is enabled */
00419       if (HAL_IS_BIT_SET(RCC->CR, RCC_CR_PLLON))
00420       {
00421         pllmul = aPLLMULFactorTable[(uint32_t)(temp_reg & RCC_CFGR_PLLMULL) >> RCC_CFGR_PLLMULL_Pos];
00422         if ((temp_reg & RCC_CFGR_PLLSRC) != RCC_PLLSOURCE_HSI_DIV2)
00423         {
00424 #if defined(STM32F105xC) || defined(STM32F107xC) || defined(STM32F100xB)\
00425  || defined(STM32F100xE)
00426           prediv1 = aPredivFactorTable[(uint32_t)(RCC->CFGR2 & RCC_CFGR2_PREDIV1) >> RCC_CFGR2_PREDIV1_Pos];
00427 #else
00428           prediv1 = aPredivFactorTable[(uint32_t)(RCC->CFGR & RCC_CFGR_PLLXTPRE) >> RCC_CFGR_PLLXTPRE_Pos];
00429 #endif /* STM32F105xC || STM32F107xC || STM32F100xB || STM32F100xE */
00430 
00431 #if defined(STM32F105xC) || defined(STM32F107xC)
00432           if (HAL_IS_BIT_SET(RCC->CFGR2, RCC_CFGR2_PREDIV1SRC))
00433           {
00434             /* PLL2 selected as Prediv1 source */
00435             /* PLLCLK = PLL2CLK / PREDIV1 * PLLMUL with PLL2CLK = HSE/PREDIV2 * PLL2MUL */
00436             prediv2 = ((RCC->CFGR2 & RCC_CFGR2_PREDIV2) >> RCC_CFGR2_PREDIV2_Pos) + 1;
00437             pll2mul = ((RCC->CFGR2 & RCC_CFGR2_PLL2MUL) >> RCC_CFGR2_PLL2MUL_Pos) + 2;
00438             pllclk = (uint32_t)((((HSE_VALUE / prediv2) * pll2mul) / prediv1) * pllmul);
00439           }
00440           else
00441           {
00442             /* HSE used as PLL clock source : PLLCLK = HSE/PREDIV1 * PLLMUL */
00443             pllclk = (uint32_t)((HSE_VALUE / prediv1) * pllmul);
00444           }
00445 
00446           /* If PLLMUL was set to 13 means that it was to cover the case PLLMUL 6.5 (avoid using float) */
00447           /* In this case need to divide pllclk by 2 */
00448           if (pllmul == aPLLMULFactorTable[(uint32_t)(RCC_CFGR_PLLMULL6_5) >> RCC_CFGR_PLLMULL_Pos])
00449           {
00450             pllclk = pllclk / 2;
00451           }
00452 #else
00453           if ((temp_reg & RCC_CFGR_PLLSRC) != RCC_PLLSOURCE_HSI_DIV2)
00454           {
00455             /* HSE used as PLL clock source : PLLCLK = HSE/PREDIV1 * PLLMUL */
00456             pllclk = (uint32_t)((HSE_VALUE / prediv1) * pllmul);
00457           }
00458 #endif /* STM32F105xC || STM32F107xC */
00459         }
00460         else
00461         {
00462           /* HSI used as PLL clock source : PLLCLK = HSI/2 * PLLMUL */
00463           pllclk = (uint32_t)((HSI_VALUE >> 1) * pllmul);
00464         }
00465 
00466         /* Calcul of the USB frequency*/
00467 #if defined(STM32F105xC) || defined(STM32F107xC)
00468         /* USBCLK = PLLVCO = (2 x PLLCLK) / USB prescaler */
00469         if (__HAL_RCC_GET_USB_SOURCE() == RCC_USBCLKSOURCE_PLL_DIV2)
00470         {
00471           /* Prescaler of 2 selected for USB */
00472           frequency = pllclk;
00473         }
00474         else
00475         {
00476           /* Prescaler of 3 selected for USB */
00477           frequency = (2 * pllclk) / 3;
00478         }
00479 #else
00480         /* USBCLK = PLLCLK / USB prescaler */
00481         if (__HAL_RCC_GET_USB_SOURCE() == RCC_USBCLKSOURCE_PLL)
00482         {
00483           /* No prescaler selected for USB */
00484           frequency = pllclk;
00485         }
00486         else
00487         {
00488           /* Prescaler of 1.5 selected for USB */
00489           frequency = (pllclk * 2) / 3;
00490         }
00491 #endif
00492       }
00493       break;
00494     }
00495 #endif /* STM32F102x6 || STM32F102xB || STM32F103x6 || STM32F103xB || STM32F103xE || STM32F103xG || STM32F105xC || STM32F107xC */
00496 #if defined(STM32F103xE) || defined(STM32F103xG) || defined(STM32F105xC) || defined(STM32F107xC)
00497     case RCC_PERIPHCLK_I2S2:
00498     {
00499 #if defined(STM32F103xE) || defined(STM32F103xG)
00500       /* SYSCLK used as source clock for I2S2 */
00501       frequency = HAL_RCC_GetSysClockFreq();
00502 #else
00503       if (__HAL_RCC_GET_I2S2_SOURCE() == RCC_I2S2CLKSOURCE_SYSCLK)
00504       {
00505         /* SYSCLK used as source clock for I2S2 */
00506         frequency = HAL_RCC_GetSysClockFreq();
00507       }
00508       else
00509       {
00510         /* Check if PLLI2S is enabled */
00511         if (HAL_IS_BIT_SET(RCC->CR, RCC_CR_PLL3ON))
00512         {
00513           /* PLLI2SVCO = 2 * PLLI2SCLK = 2 * (HSE/PREDIV2 * PLL3MUL) */
00514           prediv2 = ((RCC->CFGR2 & RCC_CFGR2_PREDIV2) >> RCC_CFGR2_PREDIV2_Pos) + 1;
00515           pll3mul = ((RCC->CFGR2 & RCC_CFGR2_PLL3MUL) >> RCC_CFGR2_PLL3MUL_Pos) + 2;
00516           frequency = (uint32_t)(2 * ((HSE_VALUE / prediv2) * pll3mul));
00517         }
00518       }
00519 #endif /* STM32F103xE || STM32F103xG */
00520       break;
00521     }
00522     case RCC_PERIPHCLK_I2S3:
00523     {
00524 #if defined(STM32F103xE) || defined(STM32F103xG)
00525       /* SYSCLK used as source clock for I2S3 */
00526       frequency = HAL_RCC_GetSysClockFreq();
00527 #else
00528       if (__HAL_RCC_GET_I2S3_SOURCE() == RCC_I2S3CLKSOURCE_SYSCLK)
00529       {
00530         /* SYSCLK used as source clock for I2S3 */
00531         frequency = HAL_RCC_GetSysClockFreq();
00532       }
00533       else
00534       {
00535         /* Check if PLLI2S is enabled */
00536         if (HAL_IS_BIT_SET(RCC->CR, RCC_CR_PLL3ON))
00537         {
00538           /* PLLI2SVCO = 2 * PLLI2SCLK = 2 * (HSE/PREDIV2 * PLL3MUL) */
00539           prediv2 = ((RCC->CFGR2 & RCC_CFGR2_PREDIV2) >> RCC_CFGR2_PREDIV2_Pos) + 1;
00540           pll3mul = ((RCC->CFGR2 & RCC_CFGR2_PLL3MUL) >> RCC_CFGR2_PLL3MUL_Pos) + 2;
00541           frequency = (uint32_t)(2 * ((HSE_VALUE / prediv2) * pll3mul));
00542         }
00543       }
00544 #endif /* STM32F103xE || STM32F103xG */
00545       break;
00546     }
00547 #endif /* STM32F103xE || STM32F103xG || STM32F105xC || STM32F107xC */
00548     case RCC_PERIPHCLK_RTC:
00549     {
00550       /* Get RCC BDCR configuration ------------------------------------------------------*/
00551       temp_reg = RCC->BDCR;
00552 
00553       /* Check if LSE is ready if RTC clock selection is LSE */
00554       if (((temp_reg & RCC_BDCR_RTCSEL) == RCC_RTCCLKSOURCE_LSE) && (HAL_IS_BIT_SET(temp_reg, RCC_BDCR_LSERDY)))
00555       {
00556         frequency = LSE_VALUE;
00557       }
00558       /* Check if LSI is ready if RTC clock selection is LSI */
00559       else if (((temp_reg & RCC_BDCR_RTCSEL) == RCC_RTCCLKSOURCE_LSI) && (HAL_IS_BIT_SET(RCC->CSR, RCC_CSR_LSIRDY)))
00560       {
00561         frequency = LSI_VALUE;
00562       }
00563       else if (((temp_reg & RCC_BDCR_RTCSEL) == RCC_RTCCLKSOURCE_HSE_DIV128) && (HAL_IS_BIT_SET(RCC->CR, RCC_CR_HSERDY)))
00564       {
00565         frequency = HSE_VALUE / 128U;
00566       }
00567       /* Clock not enabled for RTC*/
00568       else
00569       {
00570         /* nothing to do: frequency already initialized to 0U */
00571       }
00572       break;
00573     }
00574     case RCC_PERIPHCLK_ADC:
00575     {
00576       frequency = HAL_RCC_GetPCLK2Freq() / (((__HAL_RCC_GET_ADC_SOURCE() >> RCC_CFGR_ADCPRE_Pos) + 1) * 2);
00577       break;
00578     }
00579     default:
00580     {
00581       break;
00582     }
00583   }
00584   return (frequency);
00585 }
00586 
00587 /**
00588   * @}
00589   */
00590 
00591 #if defined(STM32F105xC) || defined(STM32F107xC)
00592 /** @defgroup RCCEx_Exported_Functions_Group2 PLLI2S Management function
00593   *  @brief  PLLI2S Management functions
00594   *
00595 @verbatim
00596  ===============================================================================
00597                 ##### Extended PLLI2S Management functions  #####
00598  ===============================================================================
00599     [..]
00600     This subsection provides a set of functions allowing to control the PLLI2S
00601     activation or deactivation
00602 @endverbatim
00603   * @{
00604   */
00605 
00606 /**
00607   * @brief  Enable PLLI2S
00608   * @param  PLLI2SInit pointer to an RCC_PLLI2SInitTypeDef structure that
00609   *         contains the configuration information for the PLLI2S
00610   * @note   The PLLI2S configuration not modified if used by I2S2 or I2S3 Interface.
00611   * @retval HAL status
00612   */
00613 HAL_StatusTypeDef HAL_RCCEx_EnablePLLI2S(RCC_PLLI2SInitTypeDef  *PLLI2SInit)
00614 {
00615   uint32_t tickstart = 0U;
00616 
00617   /* Check that PLL I2S has not been already enabled by I2S2 or I2S3*/
00618   if (HAL_IS_BIT_CLR(RCC->CFGR2, RCC_CFGR2_I2S2SRC) && HAL_IS_BIT_CLR(RCC->CFGR2, RCC_CFGR2_I2S3SRC))
00619   {
00620     /* Check the parameters */
00621     assert_param(IS_RCC_PLLI2S_MUL(PLLI2SInit->PLLI2SMUL));
00622     assert_param(IS_RCC_HSE_PREDIV2(PLLI2SInit->HSEPrediv2Value));
00623 
00624     /* Prediv2 can be written only when the PLL2 is disabled. */
00625     /* Return an error only if new value is different from the programmed value */
00626     if (HAL_IS_BIT_SET(RCC->CR, RCC_CR_PLL2ON) && \
00627         (__HAL_RCC_HSE_GET_PREDIV2() != PLLI2SInit->HSEPrediv2Value))
00628     {
00629       return HAL_ERROR;
00630     }
00631 
00632     /* Disable the main PLLI2S. */
00633     __HAL_RCC_PLLI2S_DISABLE();
00634 
00635     /* Get Start Tick*/
00636     tickstart = HAL_GetTick();
00637 
00638     /* Wait till PLLI2S is ready */
00639     while (__HAL_RCC_GET_FLAG(RCC_FLAG_PLLI2SRDY)  != RESET)
00640     {
00641       if ((HAL_GetTick() - tickstart) > PLLI2S_TIMEOUT_VALUE)
00642       {
00643         return HAL_TIMEOUT;
00644       }
00645     }
00646 
00647     /* Configure the HSE prediv2 factor --------------------------------*/
00648     __HAL_RCC_HSE_PREDIV2_CONFIG(PLLI2SInit->HSEPrediv2Value);
00649 
00650 
00651     /* Configure the main PLLI2S multiplication factors. */
00652     __HAL_RCC_PLLI2S_CONFIG(PLLI2SInit->PLLI2SMUL);
00653 
00654     /* Enable the main PLLI2S. */
00655     __HAL_RCC_PLLI2S_ENABLE();
00656 
00657     /* Get Start Tick*/
00658     tickstart = HAL_GetTick();
00659 
00660     /* Wait till PLLI2S is ready */
00661     while (__HAL_RCC_GET_FLAG(RCC_FLAG_PLLI2SRDY)  == RESET)
00662     {
00663       if ((HAL_GetTick() - tickstart) > PLLI2S_TIMEOUT_VALUE)
00664       {
00665         return HAL_TIMEOUT;
00666       }
00667     }
00668   }
00669   else
00670   {
00671     /* PLLI2S cannot be modified as already used by I2S2 or I2S3 */
00672     return HAL_ERROR;
00673   }
00674 
00675   return HAL_OK;
00676 }
00677 
00678 /**
00679   * @brief  Disable PLLI2S
00680   * @note   PLLI2S is not disabled if used by I2S2 or I2S3 Interface.
00681   * @retval HAL status
00682   */
00683 HAL_StatusTypeDef HAL_RCCEx_DisablePLLI2S(void)
00684 {
00685   uint32_t tickstart = 0U;
00686 
00687   /* Disable PLL I2S as not requested by I2S2 or I2S3*/
00688   if (HAL_IS_BIT_CLR(RCC->CFGR2, RCC_CFGR2_I2S2SRC) && HAL_IS_BIT_CLR(RCC->CFGR2, RCC_CFGR2_I2S3SRC))
00689   {
00690     /* Disable the main PLLI2S. */
00691     __HAL_RCC_PLLI2S_DISABLE();
00692 
00693     /* Get Start Tick*/
00694     tickstart = HAL_GetTick();
00695 
00696     /* Wait till PLLI2S is ready */
00697     while (__HAL_RCC_GET_FLAG(RCC_FLAG_PLLI2SRDY)  != RESET)
00698     {
00699       if ((HAL_GetTick() - tickstart) > PLLI2S_TIMEOUT_VALUE)
00700       {
00701         return HAL_TIMEOUT;
00702       }
00703     }
00704   }
00705   else
00706   {
00707     /* PLLI2S is currently used by I2S2 or I2S3. Cannot be disabled.*/
00708     return HAL_ERROR;
00709   }
00710 
00711   return HAL_OK;
00712 }
00713 
00714 /**
00715   * @}
00716   */
00717 
00718 /** @defgroup RCCEx_Exported_Functions_Group3 PLL2 Management function
00719   *  @brief  PLL2 Management functions
00720   *
00721 @verbatim
00722  ===============================================================================
00723                 ##### Extended PLL2 Management functions  #####
00724  ===============================================================================
00725     [..]
00726     This subsection provides a set of functions allowing to control the PLL2
00727     activation or deactivation
00728 @endverbatim
00729   * @{
00730   */
00731 
00732 /**
00733   * @brief  Enable PLL2
00734   * @param  PLL2Init pointer to an RCC_PLL2InitTypeDef structure that
00735   *         contains the configuration information for the PLL2
00736   * @note   The PLL2 configuration not modified if used indirectly as system clock.
00737   * @retval HAL status
00738   */
00739 HAL_StatusTypeDef HAL_RCCEx_EnablePLL2(RCC_PLL2InitTypeDef  *PLL2Init)
00740 {
00741   uint32_t tickstart = 0U;
00742 
00743   /* This bit can not be cleared if the PLL2 clock is used indirectly as system
00744     clock (i.e. it is used as PLL clock entry that is used as system clock). */
00745   if ((__HAL_RCC_GET_PLL_OSCSOURCE() == RCC_PLLSOURCE_HSE) && \
00746       (__HAL_RCC_GET_SYSCLK_SOURCE() == RCC_SYSCLKSOURCE_STATUS_PLLCLK) && \
00747       ((READ_BIT(RCC->CFGR2, RCC_CFGR2_PREDIV1SRC)) == RCC_CFGR2_PREDIV1SRC_PLL2))
00748   {
00749     return HAL_ERROR;
00750   }
00751   else
00752   {
00753     /* Check the parameters */
00754     assert_param(IS_RCC_PLL2_MUL(PLL2Init->PLL2MUL));
00755     assert_param(IS_RCC_HSE_PREDIV2(PLL2Init->HSEPrediv2Value));
00756 
00757     /* Prediv2 can be written only when the PLLI2S is disabled. */
00758     /* Return an error only if new value is different from the programmed value */
00759     if (HAL_IS_BIT_SET(RCC->CR, RCC_CR_PLL3ON) && \
00760         (__HAL_RCC_HSE_GET_PREDIV2() != PLL2Init->HSEPrediv2Value))
00761     {
00762       return HAL_ERROR;
00763     }
00764 
00765     /* Disable the main PLL2. */
00766     __HAL_RCC_PLL2_DISABLE();
00767 
00768     /* Get Start Tick*/
00769     tickstart = HAL_GetTick();
00770 
00771     /* Wait till PLL2 is disabled */
00772     while (__HAL_RCC_GET_FLAG(RCC_FLAG_PLL2RDY) != RESET)
00773     {
00774       if ((HAL_GetTick() - tickstart) > PLL2_TIMEOUT_VALUE)
00775       {
00776         return HAL_TIMEOUT;
00777       }
00778     }
00779 
00780     /* Configure the HSE prediv2 factor --------------------------------*/
00781     __HAL_RCC_HSE_PREDIV2_CONFIG(PLL2Init->HSEPrediv2Value);
00782 
00783     /* Configure the main PLL2 multiplication factors. */
00784     __HAL_RCC_PLL2_CONFIG(PLL2Init->PLL2MUL);
00785 
00786     /* Enable the main PLL2. */
00787     __HAL_RCC_PLL2_ENABLE();
00788 
00789     /* Get Start Tick*/
00790     tickstart = HAL_GetTick();
00791 
00792     /* Wait till PLL2 is ready */
00793     while (__HAL_RCC_GET_FLAG(RCC_FLAG_PLL2RDY)  == RESET)
00794     {
00795       if ((HAL_GetTick() - tickstart) > PLL2_TIMEOUT_VALUE)
00796       {
00797         return HAL_TIMEOUT;
00798       }
00799     }
00800   }
00801 
00802   return HAL_OK;
00803 }
00804 
00805 /**
00806   * @brief  Disable PLL2
00807   * @note   PLL2 is not disabled if used indirectly as system clock.
00808   * @retval HAL status
00809   */
00810 HAL_StatusTypeDef HAL_RCCEx_DisablePLL2(void)
00811 {
00812   uint32_t tickstart = 0U;
00813 
00814   /* This bit can not be cleared if the PLL2 clock is used indirectly as system
00815     clock (i.e. it is used as PLL clock entry that is used as system clock). */
00816   if ((__HAL_RCC_GET_PLL_OSCSOURCE() == RCC_PLLSOURCE_HSE) && \
00817       (__HAL_RCC_GET_SYSCLK_SOURCE() == RCC_SYSCLKSOURCE_STATUS_PLLCLK) && \
00818       ((READ_BIT(RCC->CFGR2, RCC_CFGR2_PREDIV1SRC)) == RCC_CFGR2_PREDIV1SRC_PLL2))
00819   {
00820     return HAL_ERROR;
00821   }
00822   else
00823   {
00824     /* Disable the main PLL2. */
00825     __HAL_RCC_PLL2_DISABLE();
00826 
00827     /* Get Start Tick*/
00828     tickstart = HAL_GetTick();
00829 
00830     /* Wait till PLL2 is disabled */
00831     while (__HAL_RCC_GET_FLAG(RCC_FLAG_PLL2RDY)  != RESET)
00832     {
00833       if ((HAL_GetTick() - tickstart) > PLL2_TIMEOUT_VALUE)
00834       {
00835         return HAL_TIMEOUT;
00836       }
00837     }
00838   }
00839 
00840   return HAL_OK;
00841 }
00842 
00843 /**
00844   * @}
00845   */
00846 #endif /* STM32F105xC || STM32F107xC */
00847 
00848 /**
00849   * @}
00850   */
00851 
00852 /**
00853   * @}
00854   */
00855 
00856 #endif /* HAL_RCC_MODULE_ENABLED */
00857 
00858 /**
00859   * @}
00860   */
00861 
00862 /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
00863