Arrow / Mbed OS DAPLink Reset
Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers stm32f1xx_hal_rcc_ex.c Source File

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