STM32F439xx HAL User Manual
stm32f4xx_hal_rcc_ex.c
Go to the documentation of this file.
00001 /**
00002   ******************************************************************************
00003   * @file    stm32f4xx_hal_rcc_ex.c
00004   * @author  MCD Application Team
00005   * @brief   Extension 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) 2017 STMicroelectronics</center></h2>
00014   *
00015   * Redistribution and use in source and binary forms, with or without modification,
00016   * are permitted provided that the following conditions are met:
00017   *   1. Redistributions of source code must retain the above copyright notice,
00018   *      this list of conditions and the following disclaimer.
00019   *   2. Redistributions in binary form must reproduce the above copyright notice,
00020   *      this list of conditions and the following disclaimer in the documentation
00021   *      and/or other materials provided with the distribution.
00022   *   3. Neither the name of STMicroelectronics nor the names of its contributors
00023   *      may be used to endorse or promote products derived from this software
00024   *      without specific prior written permission.
00025   *
00026   * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
00027   * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
00028   * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
00029   * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
00030   * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
00031   * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
00032   * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
00033   * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
00034   * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
00035   * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
00036   *
00037   ******************************************************************************
00038   */
00039 
00040 /* Includes ------------------------------------------------------------------*/
00041 #include "stm32f4xx_hal.h"
00042 
00043 /** @addtogroup STM32F4xx_HAL_Driver
00044   * @{
00045   */
00046 
00047 /** @defgroup RCCEx RCCEx
00048   * @brief RCCEx HAL module driver
00049   * @{
00050   */
00051 
00052 #ifdef HAL_RCC_MODULE_ENABLED
00053 
00054 /* Private typedef -----------------------------------------------------------*/
00055 /* Private define ------------------------------------------------------------*/
00056 /** @addtogroup RCCEx_Private_Constants
00057   * @{
00058   */
00059 /**
00060   * @}
00061   */
00062 /* Private macro -------------------------------------------------------------*/
00063 /* Private variables ---------------------------------------------------------*/
00064 /* Private function prototypes -----------------------------------------------*/
00065 /* Private functions ---------------------------------------------------------*/
00066 /** @defgroup RCCEx_Exported_Functions RCCEx Exported Functions
00067   *  @{
00068   */
00069 
00070 /** @defgroup RCCEx_Exported_Functions_Group1 Extended Peripheral Control functions
00071  *  @brief  Extended Peripheral Control functions
00072  *
00073 @verbatim
00074  ===============================================================================
00075                 ##### Extended Peripheral Control functions  #####
00076  ===============================================================================
00077     [..]
00078     This subsection provides a set of functions allowing to control the RCC Clocks
00079     frequencies.
00080     [..]
00081     (@) Important note: Care must be taken when HAL_RCCEx_PeriphCLKConfig() is used to
00082         select the RTC clock source; in this case the Backup domain will be reset in
00083         order to modify the RTC Clock source, as consequence RTC registers (including
00084         the backup registers) and RCC_BDCR register are set to their reset values.
00085 
00086 @endverbatim
00087   * @{
00088   */
00089 
00090 #if defined(STM32F446xx)
00091 /**
00092   * @brief  Initializes the RCC extended peripherals clocks according to the specified
00093   *         parameters in the RCC_PeriphCLKInitTypeDef.
00094   * @param  PeriphClkInit pointer to an RCC_PeriphCLKInitTypeDef structure that
00095   *         contains the configuration information for the Extended Peripherals
00096   *         clocks(I2S, SAI, LTDC RTC and TIM).
00097   *
00098   * @note   Care must be taken when HAL_RCCEx_PeriphCLKConfig() is used to select
00099   *         the RTC clock source; in this case the Backup domain will be reset in
00100   *         order to modify the RTC Clock source, as consequence RTC registers (including
00101   *         the backup registers) and RCC_BDCR register are set to their reset values.
00102   *
00103   * @retval HAL status
00104   */
00105 HAL_StatusTypeDef HAL_RCCEx_PeriphCLKConfig(RCC_PeriphCLKInitTypeDef  *PeriphClkInit)
00106 {
00107   uint32_t tickstart = 0U;
00108   uint32_t tmpreg1 = 0U;
00109   uint32_t plli2sp = 0U;
00110   uint32_t plli2sq = 0U;
00111   uint32_t plli2sr = 0U;
00112   uint32_t pllsaip = 0U;
00113   uint32_t pllsaiq = 0U;
00114   uint32_t plli2sused = 0U;
00115   uint32_t pllsaiused = 0U;
00116 
00117   /* Check the peripheral clock selection parameters */
00118   assert_param(IS_RCC_PERIPHCLOCK(PeriphClkInit->PeriphClockSelection));
00119 
00120   /*------------------------ I2S APB1 configuration --------------------------*/
00121   if(((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_I2S_APB1) == (RCC_PERIPHCLK_I2S_APB1))
00122   {
00123     /* Check the parameters */
00124     assert_param(IS_RCC_I2SAPB1CLKSOURCE(PeriphClkInit->I2sApb1ClockSelection));
00125 
00126     /* Configure I2S Clock source */
00127     __HAL_RCC_I2S_APB1_CONFIG(PeriphClkInit->I2sApb1ClockSelection);
00128     /* Enable the PLLI2S when it's used as clock source for I2S */
00129     if(PeriphClkInit->I2sApb1ClockSelection == RCC_I2SAPB1CLKSOURCE_PLLI2S)
00130     {
00131       plli2sused = 1U;
00132     }
00133   }
00134   /*--------------------------------------------------------------------------*/
00135 
00136   /*---------------------------- I2S APB2 configuration ----------------------*/
00137   if(((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_I2S_APB2) == (RCC_PERIPHCLK_I2S_APB2))
00138   {
00139     /* Check the parameters */
00140     assert_param(IS_RCC_I2SAPB2CLKSOURCE(PeriphClkInit->I2sApb2ClockSelection));
00141 
00142     /* Configure I2S Clock source */
00143     __HAL_RCC_I2S_APB2_CONFIG(PeriphClkInit->I2sApb2ClockSelection);
00144     /* Enable the PLLI2S when it's used as clock source for I2S */
00145     if(PeriphClkInit->I2sApb2ClockSelection == RCC_I2SAPB2CLKSOURCE_PLLI2S)
00146     {
00147       plli2sused = 1U;
00148     }
00149   }
00150   /*--------------------------------------------------------------------------*/
00151 
00152   /*--------------------------- SAI1 configuration ---------------------------*/
00153   if(((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_SAI1) == (RCC_PERIPHCLK_SAI1))
00154   {
00155     /* Check the parameters */
00156     assert_param(IS_RCC_SAI1CLKSOURCE(PeriphClkInit->Sai1ClockSelection));
00157 
00158     /* Configure SAI1 Clock source */
00159     __HAL_RCC_SAI1_CONFIG(PeriphClkInit->Sai1ClockSelection);
00160     /* Enable the PLLI2S when it's used as clock source for SAI */
00161     if(PeriphClkInit->Sai1ClockSelection == RCC_SAI1CLKSOURCE_PLLI2S)
00162     {
00163       plli2sused = 1U;
00164     }
00165     /* Enable the PLLSAI when it's used as clock source for SAI */
00166     if(PeriphClkInit->Sai1ClockSelection == RCC_SAI1CLKSOURCE_PLLSAI)
00167     {
00168       pllsaiused = 1U;
00169     }
00170   }
00171   /*--------------------------------------------------------------------------*/
00172 
00173   /*-------------------------- SAI2 configuration ----------------------------*/
00174   if(((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_SAI2) == (RCC_PERIPHCLK_SAI2))
00175   {
00176     /* Check the parameters */
00177     assert_param(IS_RCC_SAI2CLKSOURCE(PeriphClkInit->Sai2ClockSelection));
00178 
00179     /* Configure SAI2 Clock source */
00180     __HAL_RCC_SAI2_CONFIG(PeriphClkInit->Sai2ClockSelection);
00181 
00182     /* Enable the PLLI2S when it's used as clock source for SAI */
00183     if(PeriphClkInit->Sai2ClockSelection == RCC_SAI2CLKSOURCE_PLLI2S)
00184     {
00185       plli2sused = 1U;
00186     }
00187     /* Enable the PLLSAI when it's used as clock source for SAI */
00188     if(PeriphClkInit->Sai2ClockSelection == RCC_SAI2CLKSOURCE_PLLSAI)
00189     {
00190       pllsaiused = 1U;
00191     }
00192   }
00193   /*--------------------------------------------------------------------------*/
00194 
00195   /*----------------------------- RTC configuration --------------------------*/
00196   if(((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_RTC) == (RCC_PERIPHCLK_RTC))
00197   {
00198     /* Check for RTC Parameters used to output RTCCLK */
00199     assert_param(IS_RCC_RTCCLKSOURCE(PeriphClkInit->RTCClockSelection));
00200 
00201     /* Enable Power Clock*/
00202     __HAL_RCC_PWR_CLK_ENABLE();
00203 
00204     /* Enable write access to Backup domain */
00205     PWR->CR |= PWR_CR_DBP;
00206 
00207     /* Get tick */
00208     tickstart = HAL_GetTick();
00209 
00210     while((PWR->CR & PWR_CR_DBP) == RESET)
00211     {
00212       if((HAL_GetTick() - tickstart ) > RCC_DBP_TIMEOUT_VALUE)
00213       {
00214         return HAL_TIMEOUT;
00215       }
00216     }
00217     /* Reset the Backup domain only if the RTC Clock source selection is modified from reset value */
00218     tmpreg1 = (RCC->BDCR & RCC_BDCR_RTCSEL);
00219     if((tmpreg1 != 0x00000000U) && ((tmpreg1) != (PeriphClkInit->RTCClockSelection & RCC_BDCR_RTCSEL)))
00220     {
00221       /* Store the content of BDCR register before the reset of Backup Domain */
00222       tmpreg1 = (RCC->BDCR & ~(RCC_BDCR_RTCSEL));
00223       /* RTC Clock selection can be changed only if the Backup Domain is reset */
00224       __HAL_RCC_BACKUPRESET_FORCE();
00225       __HAL_RCC_BACKUPRESET_RELEASE();
00226       /* Restore the Content of BDCR register */
00227       RCC->BDCR = tmpreg1;
00228 
00229       /* Wait for LSE reactivation if LSE was enable prior to Backup Domain reset */
00230       if(HAL_IS_BIT_SET(RCC->BDCR, RCC_BDCR_LSEON))
00231       {
00232         /* Get tick */
00233         tickstart = HAL_GetTick();
00234 
00235         /* Wait till LSE is ready */
00236         while(__HAL_RCC_GET_FLAG(RCC_FLAG_LSERDY) == RESET)
00237         {
00238           if((HAL_GetTick() - tickstart ) > RCC_LSE_TIMEOUT_VALUE)
00239           {
00240             return HAL_TIMEOUT;
00241           }
00242         }
00243       }
00244     }
00245     __HAL_RCC_RTC_CONFIG(PeriphClkInit->RTCClockSelection);
00246   }
00247   /*--------------------------------------------------------------------------*/
00248 
00249   /*---------------------------- TIM configuration ---------------------------*/
00250   if(((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_TIM) == (RCC_PERIPHCLK_TIM))
00251   {
00252     /* Configure Timer Prescaler */
00253     __HAL_RCC_TIMCLKPRESCALER(PeriphClkInit->TIMPresSelection);
00254   }
00255   /*--------------------------------------------------------------------------*/
00256 
00257   /*---------------------------- FMPI2C1 Configuration -----------------------*/
00258   if(((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_FMPI2C1) == RCC_PERIPHCLK_FMPI2C1)
00259   {
00260     /* Check the parameters */
00261     assert_param(IS_RCC_FMPI2C1CLKSOURCE(PeriphClkInit->Fmpi2c1ClockSelection));
00262 
00263     /* Configure the FMPI2C1 clock source */
00264     __HAL_RCC_FMPI2C1_CONFIG(PeriphClkInit->Fmpi2c1ClockSelection);
00265   }
00266   /*--------------------------------------------------------------------------*/
00267 
00268   /*------------------------------ CEC Configuration -------------------------*/
00269   if(((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_CEC) == RCC_PERIPHCLK_CEC)
00270   {
00271     /* Check the parameters */
00272     assert_param(IS_RCC_CECCLKSOURCE(PeriphClkInit->CecClockSelection));
00273 
00274     /* Configure the CEC clock source */
00275     __HAL_RCC_CEC_CONFIG(PeriphClkInit->CecClockSelection);
00276   }
00277   /*--------------------------------------------------------------------------*/
00278 
00279   /*----------------------------- CLK48 Configuration ------------------------*/
00280   if(((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_CLK48) == RCC_PERIPHCLK_CLK48)
00281   {
00282     /* Check the parameters */
00283     assert_param(IS_RCC_CLK48CLKSOURCE(PeriphClkInit->Clk48ClockSelection));
00284 
00285     /* Configure the CLK48 clock source */
00286     __HAL_RCC_CLK48_CONFIG(PeriphClkInit->Clk48ClockSelection);
00287 
00288     /* Enable the PLLSAI when it's used as clock source for CLK48 */
00289     if(PeriphClkInit->Clk48ClockSelection == RCC_CLK48CLKSOURCE_PLLSAIP)
00290     {
00291       pllsaiused = 1U;
00292     }
00293   }
00294   /*--------------------------------------------------------------------------*/
00295 
00296   /*----------------------------- SDIO Configuration -------------------------*/
00297   if(((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_SDIO) == RCC_PERIPHCLK_SDIO)
00298   {
00299     /* Check the parameters */
00300     assert_param(IS_RCC_SDIOCLKSOURCE(PeriphClkInit->SdioClockSelection));
00301 
00302     /* Configure the SDIO clock source */
00303     __HAL_RCC_SDIO_CONFIG(PeriphClkInit->SdioClockSelection);
00304   }
00305   /*--------------------------------------------------------------------------*/
00306 
00307   /*------------------------------ SPDIFRX Configuration ---------------------*/
00308   if(((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_SPDIFRX) == RCC_PERIPHCLK_SPDIFRX)
00309   {
00310     /* Check the parameters */
00311     assert_param(IS_RCC_SPDIFRXCLKSOURCE(PeriphClkInit->SpdifClockSelection));
00312 
00313     /* Configure the SPDIFRX clock source */
00314     __HAL_RCC_SPDIFRX_CONFIG(PeriphClkInit->SpdifClockSelection);
00315     /* Enable the PLLI2S when it's used as clock source for SPDIFRX */
00316     if(PeriphClkInit->SpdifClockSelection == RCC_SPDIFRXCLKSOURCE_PLLI2SP)
00317     {
00318       plli2sused = 1U;
00319     }
00320   }
00321   /*--------------------------------------------------------------------------*/
00322 
00323   /*---------------------------- PLLI2S Configuration ------------------------*/
00324   /* PLLI2S is configured when a peripheral will use it as source clock : SAI1, SAI2, I2S on APB1,
00325      I2S on APB2 or SPDIFRX */
00326   if((plli2sused == 1U) || (PeriphClkInit->PeriphClockSelection == RCC_PERIPHCLK_PLLI2S))
00327   {
00328     /* Disable the PLLI2S */
00329     __HAL_RCC_PLLI2S_DISABLE();
00330     /* Get tick */
00331     tickstart = HAL_GetTick();
00332     /* Wait till PLLI2S is disabled */
00333     while(__HAL_RCC_GET_FLAG(RCC_FLAG_PLLI2SRDY)  != RESET)
00334     {
00335       if((HAL_GetTick() - tickstart ) > PLLI2S_TIMEOUT_VALUE)
00336       {
00337         /* return in case of Timeout detected */
00338         return HAL_TIMEOUT;
00339       }
00340     }
00341 
00342     /* check for common PLLI2S Parameters */
00343     assert_param(IS_RCC_PLLI2SM_VALUE(PeriphClkInit->PLLI2S.PLLI2SM));
00344     assert_param(IS_RCC_PLLI2SN_VALUE(PeriphClkInit->PLLI2S.PLLI2SN));
00345 
00346     /*------ In Case of PLLI2S is selected as source clock for I2S -----------*/
00347     if(((((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_I2S_APB1) == RCC_PERIPHCLK_I2S_APB1) && (PeriphClkInit->I2sApb1ClockSelection == RCC_I2SAPB1CLKSOURCE_PLLI2S)) ||
00348        ((((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_I2S_APB2) == RCC_PERIPHCLK_I2S_APB2) && (PeriphClkInit->I2sApb2ClockSelection == RCC_I2SAPB2CLKSOURCE_PLLI2S)))
00349     {
00350       /* check for Parameters */
00351       assert_param(IS_RCC_PLLI2SR_VALUE(PeriphClkInit->PLLI2S.PLLI2SR));
00352 
00353       /* Read PLLI2SP/PLLI2SQ value from PLLI2SCFGR register (this value is not needed for I2S configuration) */
00354       plli2sp = ((((RCC->PLLI2SCFGR & RCC_PLLI2SCFGR_PLLI2SP) >> RCC_PLLI2SCFGR_PLLI2SP_Pos) + 1U) << 1U);
00355       plli2sq = ((RCC->PLLI2SCFGR & RCC_PLLI2SCFGR_PLLI2SQ) >> RCC_PLLI2SCFGR_PLLI2SQ_Pos);
00356       /* Configure the PLLI2S division factors */
00357       /* PLLI2S_VCO = f(VCO clock) = f(PLLI2S clock input) * (PLLI2SN/PLLI2SM) */
00358       /* I2SCLK = f(PLLI2S clock output) = f(VCO clock) / PLLI2SR */
00359       __HAL_RCC_PLLI2S_CONFIG(PeriphClkInit->PLLI2S.PLLI2SM, PeriphClkInit->PLLI2S.PLLI2SN , plli2sp, plli2sq, PeriphClkInit->PLLI2S.PLLI2SR);
00360     }
00361 
00362     /*------- In Case of PLLI2S is selected as source clock for SAI ----------*/
00363     if(((((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_SAI1) == RCC_PERIPHCLK_SAI1) && (PeriphClkInit->Sai1ClockSelection == RCC_SAI1CLKSOURCE_PLLI2S)) ||
00364        ((((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_SAI2) == RCC_PERIPHCLK_SAI2) && (PeriphClkInit->Sai2ClockSelection == RCC_SAI2CLKSOURCE_PLLI2S)))
00365     {
00366       /* Check for PLLI2S Parameters */
00367       assert_param(IS_RCC_PLLI2SQ_VALUE(PeriphClkInit->PLLI2S.PLLI2SQ));
00368       /* Check for PLLI2S/DIVQ parameters */
00369       assert_param(IS_RCC_PLLI2S_DIVQ_VALUE(PeriphClkInit->PLLI2SDivQ));
00370 
00371       /* Read PLLI2SP/PLLI2SR value from PLLI2SCFGR register (this value is not needed for SAI configuration) */
00372       plli2sp = ((((RCC->PLLI2SCFGR & RCC_PLLI2SCFGR_PLLI2SP) >> RCC_PLLI2SCFGR_PLLI2SP_Pos) + 1U) << 1U);
00373       plli2sr = ((RCC->PLLI2SCFGR & RCC_PLLI2SCFGR_PLLI2SR) >> RCC_PLLI2SCFGR_PLLI2SR_Pos);
00374       /* Configure the PLLI2S division factors */
00375       /* PLLI2S_VCO Input  = PLL_SOURCE/PLLI2SM */
00376       /* PLLI2S_VCO Output = PLLI2S_VCO Input * PLLI2SN */
00377       /* SAI_CLK(first level) = PLLI2S_VCO Output/PLLI2SQ */
00378       __HAL_RCC_PLLI2S_CONFIG(PeriphClkInit->PLLI2S.PLLI2SM, PeriphClkInit->PLLI2S.PLLI2SN , plli2sp, PeriphClkInit->PLLI2S.PLLI2SQ, plli2sr);
00379 
00380       /* SAI_CLK_x = SAI_CLK(first level)/PLLI2SDIVQ */
00381       __HAL_RCC_PLLI2S_PLLSAICLKDIVQ_CONFIG(PeriphClkInit->PLLI2SDivQ);
00382     }
00383 
00384     /*------ In Case of PLLI2S is selected as source clock for SPDIFRX -------*/
00385     if((((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_SPDIFRX) == RCC_PERIPHCLK_SPDIFRX) && (PeriphClkInit->SpdifClockSelection == RCC_SPDIFRXCLKSOURCE_PLLI2SP))
00386     {
00387       /* check for Parameters */
00388       assert_param(IS_RCC_PLLI2SP_VALUE(PeriphClkInit->PLLI2S.PLLI2SP));
00389       /* Read PLLI2SR value from PLLI2SCFGR register (this value is not need for SAI configuration) */
00390       plli2sq = ((((RCC->PLLI2SCFGR & RCC_PLLI2SCFGR_PLLI2SP) >> RCC_PLLI2SCFGR_PLLI2SP_Pos) + 1U) << 1U);
00391       plli2sr = ((RCC->PLLI2SCFGR & RCC_PLLI2SCFGR_PLLI2SR) >> RCC_PLLI2SCFGR_PLLI2SR_Pos);
00392       /* Configure the PLLI2S division factors */
00393       /* PLLI2S_VCO = f(VCO clock) = f(PLLI2S clock input) * (PLLI2SN/PLLI2SM) */
00394       /* SPDIFRXCLK = f(PLLI2S clock output) = f(VCO clock) / PLLI2SP */
00395       __HAL_RCC_PLLI2S_CONFIG(PeriphClkInit->PLLI2S.PLLI2SM, PeriphClkInit->PLLI2S.PLLI2SN , PeriphClkInit->PLLI2S.PLLI2SP, plli2sq, plli2sr);
00396     }
00397 
00398      /*----------------- In Case of PLLI2S is just selected  -----------------*/
00399     if((PeriphClkInit->PeriphClockSelection & RCC_PERIPHCLK_PLLI2S) == RCC_PERIPHCLK_PLLI2S)
00400     {
00401       /* Check for Parameters */
00402       assert_param(IS_RCC_PLLI2SP_VALUE(PeriphClkInit->PLLI2S.PLLI2SP));
00403       assert_param(IS_RCC_PLLI2SR_VALUE(PeriphClkInit->PLLI2S.PLLI2SR));
00404       assert_param(IS_RCC_PLLI2SQ_VALUE(PeriphClkInit->PLLI2S.PLLI2SQ));
00405 
00406       /* Configure the PLLI2S division factors */
00407       /* PLLI2S_VCO = f(VCO clock) = f(PLLI2S clock input) * (PLLI2SN/PLLI2SM) */
00408       __HAL_RCC_PLLI2S_CONFIG(PeriphClkInit->PLLI2S.PLLI2SM, PeriphClkInit->PLLI2S.PLLI2SN , PeriphClkInit->PLLI2S.PLLI2SP, PeriphClkInit->PLLI2S.PLLI2SQ, PeriphClkInit->PLLI2S.PLLI2SR);
00409     }
00410 
00411     /* Enable the PLLI2S */
00412     __HAL_RCC_PLLI2S_ENABLE();
00413     /* Get tick */
00414     tickstart = HAL_GetTick();
00415     /* Wait till PLLI2S is ready */
00416     while(__HAL_RCC_GET_FLAG(RCC_FLAG_PLLI2SRDY)  == RESET)
00417     {
00418       if((HAL_GetTick() - tickstart ) > PLLI2S_TIMEOUT_VALUE)
00419       {
00420         /* return in case of Timeout detected */
00421         return HAL_TIMEOUT;
00422       }
00423     }
00424   }
00425   /*--------------------------------------------------------------------------*/
00426 
00427   /*----------------------------- PLLSAI Configuration -----------------------*/
00428   /* PLLSAI is configured when a peripheral will use it as source clock : SAI1, SAI2, CLK48 or SDIO */
00429   if(pllsaiused == 1U)
00430   {
00431     /* Disable PLLSAI Clock */
00432     __HAL_RCC_PLLSAI_DISABLE();
00433     /* Get tick */
00434     tickstart = HAL_GetTick();
00435     /* Wait till PLLSAI is disabled */
00436     while(__HAL_RCC_PLLSAI_GET_FLAG() != RESET)
00437     {
00438       if((HAL_GetTick() - tickstart ) > PLLSAI_TIMEOUT_VALUE)
00439       {
00440         /* return in case of Timeout detected */
00441         return HAL_TIMEOUT;
00442       }
00443     }
00444 
00445     /* Check the PLLSAI division factors */
00446     assert_param(IS_RCC_PLLSAIM_VALUE(PeriphClkInit->PLLSAI.PLLSAIM));
00447     assert_param(IS_RCC_PLLSAIN_VALUE(PeriphClkInit->PLLSAI.PLLSAIN));
00448 
00449     /*------ In Case of PLLSAI is selected as source clock for SAI -----------*/
00450     if(((((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_SAI1) == RCC_PERIPHCLK_SAI1) && (PeriphClkInit->Sai1ClockSelection == RCC_SAI1CLKSOURCE_PLLSAI)) ||
00451        ((((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_SAI2) == RCC_PERIPHCLK_SAI2) && (PeriphClkInit->Sai2ClockSelection == RCC_SAI2CLKSOURCE_PLLSAI)))
00452     {
00453       /* check for PLLSAIQ Parameter */
00454       assert_param(IS_RCC_PLLSAIQ_VALUE(PeriphClkInit->PLLSAI.PLLSAIQ));
00455       /* check for PLLSAI/DIVQ Parameter */
00456       assert_param(IS_RCC_PLLSAI_DIVQ_VALUE(PeriphClkInit->PLLSAIDivQ));
00457 
00458       /* Read PLLSAIP value from PLLSAICFGR register (this value is not needed for SAI configuration) */
00459       pllsaip = ((((RCC->PLLSAICFGR & RCC_PLLSAICFGR_PLLSAIP) >> RCC_PLLSAICFGR_PLLSAIP_Pos) + 1U) << 1U);
00460       /* PLLSAI_VCO Input  = PLL_SOURCE/PLLM */
00461       /* PLLSAI_VCO Output = PLLSAI_VCO Input * PLLSAIN */
00462       /* SAI_CLK(first level) = PLLSAI_VCO Output/PLLSAIQ */
00463       __HAL_RCC_PLLSAI_CONFIG(PeriphClkInit->PLLSAI.PLLSAIM, PeriphClkInit->PLLSAI.PLLSAIN , pllsaip, PeriphClkInit->PLLSAI.PLLSAIQ, 0U);
00464 
00465       /* SAI_CLK_x = SAI_CLK(first level)/PLLSAIDIVQ */
00466       __HAL_RCC_PLLSAI_PLLSAICLKDIVQ_CONFIG(PeriphClkInit->PLLSAIDivQ);
00467     }
00468 
00469     /*------ In Case of PLLSAI is selected as source clock for CLK48 ---------*/
00470     /* In Case of PLLI2S is selected as source clock for CLK48 */
00471     if((((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_CLK48) == RCC_PERIPHCLK_CLK48) && (PeriphClkInit->Clk48ClockSelection == RCC_CLK48CLKSOURCE_PLLSAIP))
00472     {
00473       /* check for Parameters */
00474       assert_param(IS_RCC_PLLSAIP_VALUE(PeriphClkInit->PLLSAI.PLLSAIP));
00475       /* Read PLLSAIQ value from PLLI2SCFGR register (this value is not need for SAI configuration) */
00476       pllsaiq = ((RCC->PLLSAICFGR & RCC_PLLSAICFGR_PLLSAIQ) >> RCC_PLLSAICFGR_PLLSAIQ_Pos);
00477       /* Configure the PLLSAI division factors */
00478       /* PLLSAI_VCO = f(VCO clock) = f(PLLSAI clock input) * (PLLI2SN/PLLSAIM) */
00479       /* 48CLK = f(PLLSAI clock output) = f(VCO clock) / PLLSAIP */
00480       __HAL_RCC_PLLSAI_CONFIG(PeriphClkInit->PLLSAI.PLLSAIM, PeriphClkInit->PLLSAI.PLLSAIN , PeriphClkInit->PLLSAI.PLLSAIP, pllsaiq, 0U);
00481     }
00482 
00483     /* Enable PLLSAI Clock */
00484     __HAL_RCC_PLLSAI_ENABLE();
00485     /* Get tick */
00486     tickstart = HAL_GetTick();
00487     /* Wait till PLLSAI is ready */
00488     while(__HAL_RCC_PLLSAI_GET_FLAG() == RESET)
00489     {
00490       if((HAL_GetTick() - tickstart ) > PLLSAI_TIMEOUT_VALUE)
00491       {
00492         /* return in case of Timeout detected */
00493         return HAL_TIMEOUT;
00494       }
00495     }
00496   }
00497   return HAL_OK;
00498 }
00499 
00500 /**
00501   * @brief  Get the RCC_PeriphCLKInitTypeDef according to the internal
00502   *         RCC configuration registers.
00503   * @param  PeriphClkInit pointer to an RCC_PeriphCLKInitTypeDef structure that
00504   *         will be configured.
00505   * @retval None
00506   */
00507 void HAL_RCCEx_GetPeriphCLKConfig(RCC_PeriphCLKInitTypeDef  *PeriphClkInit)
00508 {
00509   uint32_t tempreg;
00510 
00511   /* Set all possible values for the extended clock type parameter------------*/
00512   PeriphClkInit->PeriphClockSelection = RCC_PERIPHCLK_I2S_APB1 | RCC_PERIPHCLK_I2S_APB2 |\
00513                                         RCC_PERIPHCLK_SAI1     | RCC_PERIPHCLK_SAI2     |\
00514                                         RCC_PERIPHCLK_TIM      | RCC_PERIPHCLK_RTC      |\
00515                                         RCC_PERIPHCLK_CEC      | RCC_PERIPHCLK_FMPI2C1  |\
00516                                         RCC_PERIPHCLK_CLK48     | RCC_PERIPHCLK_SDIO     |\
00517                                         RCC_PERIPHCLK_SPDIFRX;
00518 
00519   /* Get the PLLI2S Clock configuration --------------------------------------*/
00520   PeriphClkInit->PLLI2S.PLLI2SM = (uint32_t)((RCC->PLLI2SCFGR & RCC_PLLI2SCFGR_PLLI2SM) >> RCC_PLLI2SCFGR_PLLI2SM_Pos);
00521   PeriphClkInit->PLLI2S.PLLI2SN = (uint32_t)((RCC->PLLI2SCFGR & RCC_PLLI2SCFGR_PLLI2SN) >> RCC_PLLI2SCFGR_PLLI2SN_Pos);
00522   PeriphClkInit->PLLI2S.PLLI2SP = (uint32_t)((((RCC->PLLI2SCFGR & RCC_PLLI2SCFGR_PLLI2SP) >> RCC_PLLI2SCFGR_PLLI2SP_Pos) + 1U) << 1U);
00523   PeriphClkInit->PLLI2S.PLLI2SQ = (uint32_t)((RCC->PLLI2SCFGR & RCC_PLLI2SCFGR_PLLI2SQ) >> RCC_PLLI2SCFGR_PLLI2SQ_Pos);
00524   PeriphClkInit->PLLI2S.PLLI2SR = (uint32_t)((RCC->PLLI2SCFGR & RCC_PLLI2SCFGR_PLLI2SR) >> RCC_PLLI2SCFGR_PLLI2SR_Pos);
00525   /* Get the PLLSAI Clock configuration --------------------------------------*/
00526   PeriphClkInit->PLLSAI.PLLSAIM = (uint32_t)((RCC->PLLSAICFGR & RCC_PLLSAICFGR_PLLSAIM) >> RCC_PLLSAICFGR_PLLSAIM_Pos);
00527   PeriphClkInit->PLLSAI.PLLSAIN = (uint32_t)((RCC->PLLSAICFGR & RCC_PLLSAICFGR_PLLSAIN) >> RCC_PLLSAICFGR_PLLSAIN_Pos);
00528   PeriphClkInit->PLLSAI.PLLSAIP = (uint32_t)((((RCC->PLLSAICFGR & RCC_PLLSAICFGR_PLLSAIP) >> RCC_PLLSAICFGR_PLLSAIP_Pos) + 1U) << 1U);
00529   PeriphClkInit->PLLSAI.PLLSAIQ = (uint32_t)((RCC->PLLSAICFGR & RCC_PLLSAICFGR_PLLSAIQ) >> RCC_PLLSAICFGR_PLLSAIQ_Pos);
00530   /* Get the PLLSAI/PLLI2S division factors ----------------------------------*/
00531   PeriphClkInit->PLLI2SDivQ = (uint32_t)((RCC->DCKCFGR & RCC_DCKCFGR_PLLI2SDIVQ) >> RCC_DCKCFGR_PLLI2SDIVQ_Pos);
00532   PeriphClkInit->PLLSAIDivQ = (uint32_t)((RCC->DCKCFGR & RCC_DCKCFGR_PLLSAIDIVQ) >> RCC_DCKCFGR_PLLSAIDIVQ_Pos);
00533 
00534   /* Get the SAI1 clock configuration ----------------------------------------*/
00535   PeriphClkInit->Sai1ClockSelection = __HAL_RCC_GET_SAI1_SOURCE();
00536 
00537   /* Get the SAI2 clock configuration ----------------------------------------*/
00538   PeriphClkInit->Sai2ClockSelection = __HAL_RCC_GET_SAI2_SOURCE();
00539 
00540   /* Get the I2S APB1 clock configuration ------------------------------------*/
00541   PeriphClkInit->I2sApb1ClockSelection = __HAL_RCC_GET_I2S_APB1_SOURCE();
00542 
00543   /* Get the I2S APB2 clock configuration ------------------------------------*/
00544   PeriphClkInit->I2sApb2ClockSelection = __HAL_RCC_GET_I2S_APB2_SOURCE();
00545 
00546   /* Get the RTC Clock configuration -----------------------------------------*/
00547   tempreg = (RCC->CFGR & RCC_CFGR_RTCPRE);
00548   PeriphClkInit->RTCClockSelection = (uint32_t)((tempreg) | (RCC->BDCR & RCC_BDCR_RTCSEL));
00549 
00550   /* Get the CEC clock configuration -----------------------------------------*/
00551   PeriphClkInit->CecClockSelection = __HAL_RCC_GET_CEC_SOURCE();
00552 
00553   /* Get the FMPI2C1 clock configuration -------------------------------------*/
00554   PeriphClkInit->Fmpi2c1ClockSelection = __HAL_RCC_GET_FMPI2C1_SOURCE();
00555 
00556   /* Get the CLK48 clock configuration ----------------------------------------*/
00557   PeriphClkInit->Clk48ClockSelection = __HAL_RCC_GET_CLK48_SOURCE();
00558 
00559   /* Get the SDIO clock configuration ----------------------------------------*/
00560   PeriphClkInit->SdioClockSelection = __HAL_RCC_GET_SDIO_SOURCE();
00561 
00562   /* Get the SPDIFRX clock configuration -------------------------------------*/
00563   PeriphClkInit->SpdifClockSelection = __HAL_RCC_GET_SPDIFRX_SOURCE();
00564 
00565   /* Get the TIM Prescaler configuration -------------------------------------*/
00566   if ((RCC->DCKCFGR & RCC_DCKCFGR_TIMPRE) == RESET)
00567   {
00568     PeriphClkInit->TIMPresSelection = RCC_TIMPRES_DESACTIVATED;
00569   }
00570   else
00571   {
00572     PeriphClkInit->TIMPresSelection = RCC_TIMPRES_ACTIVATED;
00573   }
00574 }
00575 
00576 /**
00577   * @brief  Return the peripheral clock frequency for a given peripheral(SAI..)
00578   * @note   Return 0 if peripheral clock identifier not managed by this API
00579   * @param  PeriphClk Peripheral clock identifier
00580   *         This parameter can be one of the following values:
00581   *            @arg RCC_PERIPHCLK_SAI1: SAI1 peripheral clock
00582   *            @arg RCC_PERIPHCLK_SAI2: SAI2 peripheral clock
00583   *            @arg RCC_PERIPHCLK_I2S_APB1: I2S APB1 peripheral clock
00584   *            @arg RCC_PERIPHCLK_I2S_APB2: I2S APB2 peripheral clock
00585   * @retval Frequency in KHz
00586   */
00587 uint32_t HAL_RCCEx_GetPeriphCLKFreq(uint32_t PeriphClk)
00588 {
00589   uint32_t tmpreg1 = 0U;
00590   /* This variable used to store the SAI clock frequency (value in Hz) */
00591   uint32_t frequency = 0U;
00592   /* This variable used to store the VCO Input (value in Hz) */
00593   uint32_t vcoinput = 0U;
00594   /* This variable used to store the SAI clock source */
00595   uint32_t saiclocksource = 0U;
00596   uint32_t srcclk = 0U;
00597   /* This variable used to store the VCO Output (value in Hz) */
00598   uint32_t vcooutput = 0U;
00599   switch (PeriphClk)
00600   {
00601   case RCC_PERIPHCLK_SAI1:
00602   case RCC_PERIPHCLK_SAI2:
00603     {
00604       saiclocksource = RCC->DCKCFGR;
00605       saiclocksource &= (RCC_DCKCFGR_SAI1SRC | RCC_DCKCFGR_SAI2SRC);
00606       switch (saiclocksource)
00607       {
00608       case 0U: /* PLLSAI is the clock source for SAI*/
00609         {
00610           /* Configure the PLLSAI division factor */
00611           /* PLLSAI_VCO Input  = PLL_SOURCE/PLLSAIM */
00612           if((RCC->PLLCFGR & RCC_PLLCFGR_PLLSRC) == RCC_PLLSOURCE_HSI)
00613           {
00614             /* In Case the PLL Source is HSI (Internal Clock) */
00615             vcoinput = (HSI_VALUE / (uint32_t)(RCC->PLLSAICFGR & RCC_PLLSAICFGR_PLLSAIM));
00616           }
00617           else
00618           {
00619             /* In Case the PLL Source is HSE (External Clock) */
00620             vcoinput = ((HSE_VALUE / (uint32_t)(RCC->PLLSAICFGR & RCC_PLLSAICFGR_PLLSAIM)));
00621           }
00622           /* PLLSAI_VCO Output = PLLSAI_VCO Input * PLLSAIN */
00623           /* SAI_CLK(first level) = PLLSAI_VCO Output/PLLSAIQ */
00624           tmpreg1 = (RCC->PLLSAICFGR & RCC_PLLSAICFGR_PLLSAIQ) >> 24U;
00625           frequency = (vcoinput * ((RCC->PLLSAICFGR & RCC_PLLSAICFGR_PLLSAIN) >> 6U))/(tmpreg1);
00626 
00627           /* SAI_CLK_x = SAI_CLK(first level)/PLLSAIDIVQ */
00628           tmpreg1 = (((RCC->DCKCFGR & RCC_DCKCFGR_PLLSAIDIVQ) >> 8U) + 1U);
00629           frequency = frequency/(tmpreg1);
00630           break;
00631         }
00632       case RCC_DCKCFGR_SAI1SRC_0: /* PLLI2S is the clock source for SAI*/
00633       case RCC_DCKCFGR_SAI2SRC_0: /* PLLI2S is the clock source for SAI*/
00634         {
00635           /* Configure the PLLI2S division factor */
00636           /* PLLI2S_VCO Input  = PLL_SOURCE/PLLI2SM */
00637           if((RCC->PLLCFGR & RCC_PLLCFGR_PLLSRC) == RCC_PLLSOURCE_HSI)
00638           {
00639             /* In Case the PLL Source is HSI (Internal Clock) */
00640             vcoinput = (HSI_VALUE / (uint32_t)(RCC->PLLI2SCFGR & RCC_PLLI2SCFGR_PLLI2SM));
00641           }
00642           else
00643           {
00644             /* In Case the PLL Source is HSE (External Clock) */
00645             vcoinput = ((HSE_VALUE / (uint32_t)(RCC->PLLI2SCFGR & RCC_PLLI2SCFGR_PLLI2SM)));
00646           }
00647 
00648           /* PLLI2S_VCO Output = PLLI2S_VCO Input * PLLI2SN */
00649           /* SAI_CLK(first level) = PLLI2S_VCO Output/PLLI2SQ */
00650           tmpreg1 = (RCC->PLLI2SCFGR & RCC_PLLI2SCFGR_PLLI2SQ) >> 24U;
00651           frequency = (vcoinput * ((RCC->PLLI2SCFGR & RCC_PLLI2SCFGR_PLLI2SN) >> 6U))/(tmpreg1);
00652 
00653           /* SAI_CLK_x = SAI_CLK(first level)/PLLI2SDIVQ */
00654           tmpreg1 = ((RCC->DCKCFGR & RCC_DCKCFGR_PLLI2SDIVQ) + 1U);
00655           frequency = frequency/(tmpreg1);
00656           break;
00657         }
00658       case RCC_DCKCFGR_SAI1SRC_1: /* PLLR is the clock source for SAI*/
00659       case RCC_DCKCFGR_SAI2SRC_1: /* PLLR is the clock source for SAI*/
00660         {
00661           /* Configure the PLLI2S division factor */
00662           /* PLL_VCO Input  = PLL_SOURCE/PLLM */
00663           if((RCC->PLLCFGR & RCC_PLLCFGR_PLLSRC) == RCC_PLLSOURCE_HSI)
00664           {
00665             /* In Case the PLL Source is HSI (Internal Clock) */
00666             vcoinput = (HSI_VALUE / (uint32_t)(RCC->PLLCFGR & RCC_PLLCFGR_PLLM));
00667           }
00668           else
00669           {
00670             /* In Case the PLL Source is HSE (External Clock) */
00671             vcoinput = ((HSE_VALUE / (uint32_t)(RCC->PLLCFGR & RCC_PLLCFGR_PLLM)));
00672           }
00673 
00674           /* PLL_VCO Output = PLL_VCO Input * PLLN */
00675           /* SAI_CLK_x = PLL_VCO Output/PLLR */
00676           tmpreg1 = (RCC->PLLCFGR & RCC_PLLCFGR_PLLR) >> 28U;
00677           frequency = (vcoinput * ((RCC->PLLCFGR & RCC_PLLCFGR_PLLN) >> 6U))/(tmpreg1);
00678           break;
00679         }
00680       case RCC_DCKCFGR_SAI1SRC: /* External clock is the clock source for SAI*/
00681         {
00682           frequency = EXTERNAL_CLOCK_VALUE;
00683           break;
00684         }
00685       case RCC_DCKCFGR_SAI2SRC: /* PLLSRC(HSE or HSI) is the clock source for SAI*/
00686         {
00687           if((RCC->PLLCFGR & RCC_PLLCFGR_PLLSRC) == RCC_PLLSOURCE_HSI)
00688           {
00689             /* In Case the PLL Source is HSI (Internal Clock) */
00690             frequency = (uint32_t)(HSI_VALUE);
00691           }
00692           else
00693           {
00694             /* In Case the PLL Source is HSE (External Clock) */
00695             frequency = (uint32_t)(HSE_VALUE);
00696           }
00697           break;
00698         }
00699       default :
00700         {
00701           break;
00702         }
00703       }
00704       break;
00705     }
00706   case RCC_PERIPHCLK_I2S_APB1:
00707     {
00708       /* Get the current I2S source */
00709       srcclk = __HAL_RCC_GET_I2S_APB1_SOURCE();
00710       switch (srcclk)
00711       {
00712       /* Check if I2S clock selection is External clock mapped on the I2S_CKIN pin used as I2S clock */
00713       case RCC_I2SAPB1CLKSOURCE_EXT:
00714         {
00715           /* Set the I2S clock to the external clock  value */
00716           frequency = EXTERNAL_CLOCK_VALUE;
00717           break;
00718         }
00719       /* Check if I2S clock selection is PLLI2S VCO output clock divided by PLLI2SR used as I2S clock */
00720       case RCC_I2SAPB1CLKSOURCE_PLLI2S:
00721         {
00722           /* Configure the PLLI2S division factor */
00723           /* PLLI2S_VCO Input  = PLL_SOURCE/PLLI2SM */
00724           if((RCC->PLLCFGR & RCC_PLLCFGR_PLLSRC) == RCC_PLLSOURCE_HSE)
00725           {
00726             /* Get the I2S source clock value */
00727             vcoinput = (uint32_t)(HSE_VALUE / (uint32_t)(RCC->PLLI2SCFGR & RCC_PLLI2SCFGR_PLLI2SM));
00728           }
00729           else
00730           {
00731             /* Get the I2S source clock value */
00732             vcoinput = (uint32_t)(HSI_VALUE / (uint32_t)(RCC->PLLI2SCFGR & RCC_PLLI2SCFGR_PLLI2SM));
00733           }
00734 
00735           /* PLLI2S_VCO Output = PLLI2S_VCO Input * PLLI2SN */
00736           vcooutput = (uint32_t)(vcoinput * (((RCC->PLLI2SCFGR & RCC_PLLI2SCFGR_PLLI2SN) >> 6U) & (RCC_PLLI2SCFGR_PLLI2SN >> 6U)));
00737           /* I2S_CLK = PLLI2S_VCO Output/PLLI2SR */
00738           frequency = (uint32_t)(vcooutput /(((RCC->PLLI2SCFGR & RCC_PLLI2SCFGR_PLLI2SR) >> 28U) & (RCC_PLLI2SCFGR_PLLI2SR >> 28U)));
00739           break;
00740         }
00741       /* Check if I2S clock selection is PLL VCO Output divided by PLLR used as I2S clock */
00742       case RCC_I2SAPB1CLKSOURCE_PLLR:
00743         {
00744           /* Configure the PLL division factor R */
00745           /* PLL_VCO Input  = PLL_SOURCE/PLLM */
00746           if((RCC->PLLCFGR & RCC_PLLCFGR_PLLSRC) == RCC_PLLSOURCE_HSE)
00747           {
00748             /* Get the I2S source clock value */
00749             vcoinput = (uint32_t)(HSE_VALUE / (uint32_t)(RCC->PLLCFGR & RCC_PLLCFGR_PLLM));
00750           }
00751           else
00752           {
00753             /* Get the I2S source clock value */
00754             vcoinput = (uint32_t)(HSI_VALUE / (uint32_t)(RCC->PLLCFGR & RCC_PLLCFGR_PLLM));
00755           }
00756 
00757           /* PLL_VCO Output = PLL_VCO Input * PLLN */
00758           vcooutput = (uint32_t)(vcoinput * (((RCC->PLLCFGR & RCC_PLLCFGR_PLLN) >> 6U) & (RCC_PLLCFGR_PLLN >> 6U)));
00759           /* I2S_CLK = PLL_VCO Output/PLLR */
00760           frequency = (uint32_t)(vcooutput /(((RCC->PLLCFGR & RCC_PLLCFGR_PLLR) >> 28U) & (RCC_PLLCFGR_PLLR >> 28U)));
00761           break;
00762         }
00763       /* Check if I2S clock selection is HSI or HSE depending from PLL source Clock */
00764       case RCC_I2SAPB1CLKSOURCE_PLLSRC:
00765         {
00766           if((RCC->PLLCFGR & RCC_PLLCFGR_PLLSRC) == RCC_PLLSOURCE_HSE)
00767           {
00768             frequency = HSE_VALUE;
00769           }
00770           else
00771           {
00772             frequency = HSI_VALUE;
00773           }
00774           break;
00775         }
00776         /* Clock not enabled for I2S*/
00777       default:
00778         {
00779           frequency = 0U;
00780           break;
00781         }
00782       }
00783       break;
00784     }
00785   case RCC_PERIPHCLK_I2S_APB2:
00786     {
00787       /* Get the current I2S source */
00788       srcclk = __HAL_RCC_GET_I2S_APB2_SOURCE();
00789       switch (srcclk)
00790       {
00791         /* Check if I2S clock selection is External clock mapped on the I2S_CKIN pin used as I2S clock */
00792       case RCC_I2SAPB2CLKSOURCE_EXT:
00793         {
00794           /* Set the I2S clock to the external clock  value */
00795           frequency = EXTERNAL_CLOCK_VALUE;
00796           break;
00797         }
00798         /* Check if I2S clock selection is PLLI2S VCO output clock divided by PLLI2SR used as I2S clock */
00799       case RCC_I2SAPB2CLKSOURCE_PLLI2S:
00800         {
00801           /* Configure the PLLI2S division factor */
00802           /* PLLI2S_VCO Input  = PLL_SOURCE/PLLI2SM */
00803           if((RCC->PLLCFGR & RCC_PLLCFGR_PLLSRC) == RCC_PLLSOURCE_HSE)
00804           {
00805             /* Get the I2S source clock value */
00806             vcoinput = (uint32_t)(HSE_VALUE / (uint32_t)(RCC->PLLI2SCFGR & RCC_PLLI2SCFGR_PLLI2SM));
00807           }
00808           else
00809           {
00810             /* Get the I2S source clock value */
00811             vcoinput = (uint32_t)(HSI_VALUE / (uint32_t)(RCC->PLLI2SCFGR & RCC_PLLI2SCFGR_PLLI2SM));
00812           }
00813 
00814           /* PLLI2S_VCO Output = PLLI2S_VCO Input * PLLI2SN */
00815           vcooutput = (uint32_t)(vcoinput * (((RCC->PLLI2SCFGR & RCC_PLLI2SCFGR_PLLI2SN) >> 6U) & (RCC_PLLI2SCFGR_PLLI2SN >> 6U)));
00816           /* I2S_CLK = PLLI2S_VCO Output/PLLI2SR */
00817           frequency = (uint32_t)(vcooutput /(((RCC->PLLI2SCFGR & RCC_PLLI2SCFGR_PLLI2SR) >> 28U) & (RCC_PLLI2SCFGR_PLLI2SR >> 28U)));
00818           break;
00819         }
00820         /* Check if I2S clock selection is PLL VCO Output divided by PLLR used as I2S clock */
00821       case RCC_I2SAPB2CLKSOURCE_PLLR:
00822         {
00823           /* Configure the PLL division factor R */
00824           /* PLL_VCO Input  = PLL_SOURCE/PLLM */
00825           if((RCC->PLLCFGR & RCC_PLLCFGR_PLLSRC) == RCC_PLLSOURCE_HSE)
00826           {
00827             /* Get the I2S source clock value */
00828             vcoinput = (uint32_t)(HSE_VALUE / (uint32_t)(RCC->PLLCFGR & RCC_PLLCFGR_PLLM));
00829           }
00830           else
00831           {
00832             /* Get the I2S source clock value */
00833             vcoinput = (uint32_t)(HSI_VALUE / (uint32_t)(RCC->PLLCFGR & RCC_PLLCFGR_PLLM));
00834           }
00835 
00836           /* PLL_VCO Output = PLL_VCO Input * PLLN */
00837           vcooutput = (uint32_t)(vcoinput * (((RCC->PLLCFGR & RCC_PLLCFGR_PLLN) >> 6U) & (RCC_PLLCFGR_PLLN >> 6U)));
00838           /* I2S_CLK = PLL_VCO Output/PLLR */
00839           frequency = (uint32_t)(vcooutput /(((RCC->PLLCFGR & RCC_PLLCFGR_PLLR) >> 28U) & (RCC_PLLCFGR_PLLR >> 28U)));
00840           break;
00841         }
00842         /* Check if I2S clock selection is HSI or HSE depending from PLL source Clock */
00843       case RCC_I2SAPB2CLKSOURCE_PLLSRC:
00844         {
00845           if((RCC->PLLCFGR & RCC_PLLCFGR_PLLSRC) == RCC_PLLSOURCE_HSE)
00846           {
00847             frequency = HSE_VALUE;
00848           }
00849           else
00850           {
00851             frequency = HSI_VALUE;
00852           }
00853           break;
00854         }
00855         /* Clock not enabled for I2S*/
00856       default:
00857         {
00858           frequency = 0U;
00859           break;
00860         }
00861       }
00862       break;
00863     }
00864   }
00865   return frequency;
00866 }
00867 #endif /* STM32F446xx */
00868 
00869 #if defined(STM32F469xx) || defined(STM32F479xx)
00870 /**
00871   * @brief  Initializes the RCC extended peripherals clocks according to the specified
00872   *         parameters in the RCC_PeriphCLKInitTypeDef.
00873   * @param  PeriphClkInit pointer to an RCC_PeriphCLKInitTypeDef structure that
00874   *         contains the configuration information for the Extended Peripherals
00875   *         clocks(I2S, SAI, LTDC, RTC and TIM).
00876   *
00877   * @note   Care must be taken when HAL_RCCEx_PeriphCLKConfig() is used to select
00878   *         the RTC clock source; in this case the Backup domain will be reset in
00879   *         order to modify the RTC Clock source, as consequence RTC registers (including
00880   *         the backup registers) and RCC_BDCR register are set to their reset values.
00881   *
00882   * @retval HAL status
00883   */
00884 HAL_StatusTypeDef HAL_RCCEx_PeriphCLKConfig(RCC_PeriphCLKInitTypeDef  *PeriphClkInit)
00885 {
00886   uint32_t tickstart = 0U;
00887   uint32_t tmpreg1 = 0U;
00888   uint32_t pllsaip = 0U;
00889   uint32_t pllsaiq = 0U;
00890   uint32_t pllsair = 0U;
00891 
00892   /* Check the parameters */
00893   assert_param(IS_RCC_PERIPHCLOCK(PeriphClkInit->PeriphClockSelection));
00894 
00895   /*--------------------------- CLK48 Configuration --------------------------*/
00896   if(((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_CLK48) == RCC_PERIPHCLK_CLK48)
00897   {
00898     /* Check the parameters */
00899     assert_param(IS_RCC_CLK48CLKSOURCE(PeriphClkInit->Clk48ClockSelection));
00900 
00901     /* Configure the CLK48 clock source */
00902     __HAL_RCC_CLK48_CONFIG(PeriphClkInit->Clk48ClockSelection);
00903   }
00904   /*--------------------------------------------------------------------------*/
00905 
00906   /*------------------------------ SDIO Configuration ------------------------*/
00907   if(((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_SDIO) == RCC_PERIPHCLK_SDIO)
00908   {
00909     /* Check the parameters */
00910     assert_param(IS_RCC_SDIOCLKSOURCE(PeriphClkInit->SdioClockSelection));
00911 
00912     /* Configure the SDIO clock source */
00913     __HAL_RCC_SDIO_CONFIG(PeriphClkInit->SdioClockSelection);
00914   }
00915   /*--------------------------------------------------------------------------*/
00916 
00917   /*----------------------- SAI/I2S Configuration (PLLI2S) -------------------*/
00918   /*------------------- Common configuration SAI/I2S -------------------------*/
00919   /* In Case of SAI or I2S Clock Configuration through PLLI2S, PLLI2SN division
00920      factor is common parameters for both peripherals */
00921   if((((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_I2S) == RCC_PERIPHCLK_I2S) ||
00922      (((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_SAI_PLLI2S) == RCC_PERIPHCLK_SAI_PLLI2S) ||
00923      (((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_PLLI2S) == RCC_PERIPHCLK_PLLI2S))
00924   {
00925     /* check for Parameters */
00926     assert_param(IS_RCC_PLLI2SN_VALUE(PeriphClkInit->PLLI2S.PLLI2SN));
00927 
00928     /* Disable the PLLI2S */
00929     __HAL_RCC_PLLI2S_DISABLE();
00930     /* Get tick */
00931     tickstart = HAL_GetTick();
00932     /* Wait till PLLI2S is disabled */
00933     while(__HAL_RCC_GET_FLAG(RCC_FLAG_PLLI2SRDY)  != RESET)
00934     {
00935       if((HAL_GetTick() - tickstart ) > PLLI2S_TIMEOUT_VALUE)
00936       {
00937         /* return in case of Timeout detected */
00938         return HAL_TIMEOUT;
00939       }
00940     }
00941 
00942     /*---------------------- I2S configuration -------------------------------*/
00943     /* In Case of I2S Clock Configuration through PLLI2S, PLLI2SR must be added
00944       only for I2S configuration */
00945     if(((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_I2S) == (RCC_PERIPHCLK_I2S))
00946     {
00947       /* check for Parameters */
00948       assert_param(IS_RCC_PLLI2SR_VALUE(PeriphClkInit->PLLI2S.PLLI2SR));
00949       /* Configure the PLLI2S division factors */
00950       /* PLLI2S_VCO = f(VCO clock) = f(PLLI2S clock input) x (PLLI2SN/PLLM) */
00951       /* I2SCLK = f(PLLI2S clock output) = f(VCO clock) / PLLI2SR */
00952       __HAL_RCC_PLLI2S_CONFIG(PeriphClkInit->PLLI2S.PLLI2SN , PeriphClkInit->PLLI2S.PLLI2SR);
00953     }
00954 
00955     /*---------------------------- SAI configuration -------------------------*/
00956     /* In Case of SAI Clock Configuration through PLLI2S, PLLI2SQ and PLLI2S_DIVQ must
00957        be added only for SAI configuration */
00958     if(((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_SAI_PLLI2S) == (RCC_PERIPHCLK_SAI_PLLI2S))
00959     {
00960       /* Check the PLLI2S division factors */
00961       assert_param(IS_RCC_PLLI2SQ_VALUE(PeriphClkInit->PLLI2S.PLLI2SQ));
00962       assert_param(IS_RCC_PLLI2S_DIVQ_VALUE(PeriphClkInit->PLLI2SDivQ));
00963 
00964       /* Read PLLI2SR value from PLLI2SCFGR register (this value is not need for SAI configuration) */
00965       tmpreg1 = ((RCC->PLLI2SCFGR & RCC_PLLI2SCFGR_PLLI2SR) >> RCC_PLLI2SCFGR_PLLI2SR_Pos);
00966       /* Configure the PLLI2S division factors */
00967       /* PLLI2S_VCO Input  = PLL_SOURCE/PLLM */
00968       /* PLLI2S_VCO Output = PLLI2S_VCO Input * PLLI2SN */
00969       /* SAI_CLK(first level) = PLLI2S_VCO Output/PLLI2SQ */
00970       __HAL_RCC_PLLI2S_SAICLK_CONFIG(PeriphClkInit->PLLI2S.PLLI2SN , PeriphClkInit->PLLI2S.PLLI2SQ , tmpreg1);
00971       /* SAI_CLK_x = SAI_CLK(first level)/PLLI2SDIVQ */
00972       __HAL_RCC_PLLI2S_PLLSAICLKDIVQ_CONFIG(PeriphClkInit->PLLI2SDivQ);
00973     }
00974 
00975     /*----------------- In Case of PLLI2S is just selected  -----------------*/
00976     if((PeriphClkInit->PeriphClockSelection & RCC_PERIPHCLK_PLLI2S) == RCC_PERIPHCLK_PLLI2S)
00977     {
00978       /* Check for Parameters */
00979       assert_param(IS_RCC_PLLI2SQ_VALUE(PeriphClkInit->PLLI2S.PLLI2SQ));
00980       assert_param(IS_RCC_PLLI2SR_VALUE(PeriphClkInit->PLLI2S.PLLI2SR));
00981 
00982       /* Configure the PLLI2S multiplication and division factors */
00983       __HAL_RCC_PLLI2S_SAICLK_CONFIG(PeriphClkInit->PLLI2S.PLLI2SN, PeriphClkInit->PLLI2S.PLLI2SQ, PeriphClkInit->PLLI2S.PLLI2SR);
00984     }
00985 
00986     /* Enable the PLLI2S */
00987     __HAL_RCC_PLLI2S_ENABLE();
00988     /* Get tick */
00989     tickstart = HAL_GetTick();
00990     /* Wait till PLLI2S is ready */
00991     while(__HAL_RCC_GET_FLAG(RCC_FLAG_PLLI2SRDY)  == RESET)
00992     {
00993       if((HAL_GetTick() - tickstart ) > PLLI2S_TIMEOUT_VALUE)
00994       {
00995         /* return in case of Timeout detected */
00996         return HAL_TIMEOUT;
00997       }
00998     }
00999   }
01000   /*--------------------------------------------------------------------------*/
01001 
01002   /*----------------------- SAI/LTDC Configuration (PLLSAI) ------------------*/
01003   /*----------------------- Common configuration SAI/LTDC --------------------*/
01004   /* In Case of SAI, LTDC or CLK48 Clock Configuration through PLLSAI, PLLSAIN division
01005      factor is common parameters for these peripherals */
01006   if((((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_SAI_PLLSAI) == RCC_PERIPHCLK_SAI_PLLSAI) ||
01007      (((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_LTDC) == RCC_PERIPHCLK_LTDC)             ||
01008      ((((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_CLK48) == RCC_PERIPHCLK_CLK48)          &&
01009       (PeriphClkInit->Clk48ClockSelection == RCC_CLK48CLKSOURCE_PLLSAIP)))
01010   {
01011     /* Check the PLLSAI division factors */
01012     assert_param(IS_RCC_PLLSAIN_VALUE(PeriphClkInit->PLLSAI.PLLSAIN));
01013 
01014     /* Disable PLLSAI Clock */
01015     __HAL_RCC_PLLSAI_DISABLE();
01016     /* Get tick */
01017     tickstart = HAL_GetTick();
01018     /* Wait till PLLSAI is disabled */
01019     while(__HAL_RCC_PLLSAI_GET_FLAG() != RESET)
01020     {
01021       if((HAL_GetTick() - tickstart ) > PLLSAI_TIMEOUT_VALUE)
01022       {
01023         /* return in case of Timeout detected */
01024         return HAL_TIMEOUT;
01025       }
01026     }
01027 
01028     /*---------------------------- SAI configuration -------------------------*/
01029     /* In Case of SAI Clock Configuration through PLLSAI, PLLSAIQ and PLLSAI_DIVQ must
01030        be added only for SAI configuration */
01031     if(((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_SAI_PLLSAI) == (RCC_PERIPHCLK_SAI_PLLSAI))
01032     {
01033       assert_param(IS_RCC_PLLSAIQ_VALUE(PeriphClkInit->PLLSAI.PLLSAIQ));
01034       assert_param(IS_RCC_PLLSAI_DIVQ_VALUE(PeriphClkInit->PLLSAIDivQ));
01035 
01036       /* Read PLLSAIP value from PLLSAICFGR register (this value is not needed for SAI configuration) */
01037       pllsaip = ((((RCC->PLLSAICFGR & RCC_PLLSAICFGR_PLLSAIP) >> RCC_PLLSAICFGR_PLLSAIP_Pos) + 1U) << 1U);
01038       /* Read PLLSAIR value from PLLSAICFGR register (this value is not need for SAI configuration) */
01039       pllsair = ((RCC->PLLSAICFGR & RCC_PLLSAICFGR_PLLSAIR) >> RCC_PLLSAICFGR_PLLSAIR_Pos);
01040       /* PLLSAI_VCO Input  = PLL_SOURCE/PLLM */
01041       /* PLLSAI_VCO Output = PLLSAI_VCO Input * PLLSAIN */
01042       /* SAI_CLK(first level) = PLLSAI_VCO Output/PLLSAIQ */
01043       __HAL_RCC_PLLSAI_CONFIG(PeriphClkInit->PLLSAI.PLLSAIN, pllsaip, PeriphClkInit->PLLSAI.PLLSAIQ, pllsair);
01044       /* SAI_CLK_x = SAI_CLK(first level)/PLLSAIDIVQ */
01045       __HAL_RCC_PLLSAI_PLLSAICLKDIVQ_CONFIG(PeriphClkInit->PLLSAIDivQ);
01046     }
01047 
01048     /*---------------------------- LTDC configuration ------------------------*/
01049     if(((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_LTDC) == (RCC_PERIPHCLK_LTDC))
01050     {
01051       assert_param(IS_RCC_PLLSAIR_VALUE(PeriphClkInit->PLLSAI.PLLSAIR));
01052       assert_param(IS_RCC_PLLSAI_DIVR_VALUE(PeriphClkInit->PLLSAIDivR));
01053 
01054       /* Read PLLSAIP value from PLLSAICFGR register (this value is not needed for SAI configuration) */
01055       pllsaip = ((((RCC->PLLSAICFGR & RCC_PLLSAICFGR_PLLSAIP) >> RCC_PLLSAICFGR_PLLSAIP_Pos) + 1U) << 1U);
01056       /* Read PLLSAIQ value from PLLSAICFGR register (this value is not need for SAI configuration) */
01057       pllsaiq = ((RCC->PLLSAICFGR & RCC_PLLSAICFGR_PLLSAIQ) >> RCC_PLLSAICFGR_PLLSAIQ_Pos);
01058       /* PLLSAI_VCO Input  = PLL_SOURCE/PLLM */
01059       /* PLLSAI_VCO Output = PLLSAI_VCO Input * PLLSAIN */
01060       /* LTDC_CLK(first level) = PLLSAI_VCO Output/PLLSAIR */
01061       __HAL_RCC_PLLSAI_CONFIG(PeriphClkInit->PLLSAI.PLLSAIN, pllsaip, pllsaiq, PeriphClkInit->PLLSAI.PLLSAIR);
01062       /* LTDC_CLK = LTDC_CLK(first level)/PLLSAIDIVR */
01063       __HAL_RCC_PLLSAI_PLLSAICLKDIVR_CONFIG(PeriphClkInit->PLLSAIDivR);
01064     }
01065 
01066     /*---------------------------- CLK48 configuration ------------------------*/
01067     /* Configure the PLLSAI when it is used as clock source for CLK48 */
01068     if((((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_CLK48) == (RCC_PERIPHCLK_CLK48)) &&
01069        (PeriphClkInit->Clk48ClockSelection == RCC_CLK48CLKSOURCE_PLLSAIP))
01070     {
01071       assert_param(IS_RCC_PLLSAIP_VALUE(PeriphClkInit->PLLSAI.PLLSAIP));
01072 
01073       /* Read PLLSAIQ value from PLLSAICFGR register (this value is not need for SAI configuration) */
01074       pllsaiq = ((RCC->PLLSAICFGR & RCC_PLLSAICFGR_PLLSAIQ) >> RCC_PLLSAICFGR_PLLSAIQ_Pos);
01075       /* Read PLLSAIR value from PLLSAICFGR register (this value is not need for SAI configuration) */
01076       pllsair = ((RCC->PLLSAICFGR & RCC_PLLSAICFGR_PLLSAIR) >> RCC_PLLSAICFGR_PLLSAIR_Pos);
01077       /* PLLSAI_VCO Input  = PLL_SOURCE/PLLM */
01078       /* PLLSAI_VCO Output = PLLSAI_VCO Input * PLLSAIN */
01079       /* CLK48_CLK(first level) = PLLSAI_VCO Output/PLLSAIP */
01080       __HAL_RCC_PLLSAI_CONFIG(PeriphClkInit->PLLSAI.PLLSAIN, PeriphClkInit->PLLSAI.PLLSAIP, pllsaiq, pllsair);
01081     }
01082 
01083     /* Enable PLLSAI Clock */
01084     __HAL_RCC_PLLSAI_ENABLE();
01085     /* Get tick */
01086     tickstart = HAL_GetTick();
01087     /* Wait till PLLSAI is ready */
01088     while(__HAL_RCC_PLLSAI_GET_FLAG() == RESET)
01089     {
01090       if((HAL_GetTick() - tickstart ) > PLLSAI_TIMEOUT_VALUE)
01091       {
01092         /* return in case of Timeout detected */
01093         return HAL_TIMEOUT;
01094       }
01095     }
01096   }
01097 
01098   /*--------------------------------------------------------------------------*/
01099 
01100   /*---------------------------- RTC configuration ---------------------------*/
01101   if(((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_RTC) == (RCC_PERIPHCLK_RTC))
01102   {
01103     /* Check for RTC Parameters used to output RTCCLK */
01104     assert_param(IS_RCC_RTCCLKSOURCE(PeriphClkInit->RTCClockSelection));
01105 
01106     /* Enable Power Clock*/
01107     __HAL_RCC_PWR_CLK_ENABLE();
01108 
01109     /* Enable write access to Backup domain */
01110     PWR->CR |= PWR_CR_DBP;
01111 
01112     /* Get tick */
01113     tickstart = HAL_GetTick();
01114 
01115     while((PWR->CR & PWR_CR_DBP) == RESET)
01116     {
01117       if((HAL_GetTick() - tickstart ) > RCC_DBP_TIMEOUT_VALUE)
01118       {
01119         return HAL_TIMEOUT;
01120       }
01121     }
01122     /* Reset the Backup domain only if the RTC Clock source selection is modified from reset value */
01123     tmpreg1 = (RCC->BDCR & RCC_BDCR_RTCSEL);
01124     if((tmpreg1 != 0x00000000U) && ((tmpreg1) != (PeriphClkInit->RTCClockSelection & RCC_BDCR_RTCSEL)))
01125     {
01126       /* Store the content of BDCR register before the reset of Backup Domain */
01127       tmpreg1 = (RCC->BDCR & ~(RCC_BDCR_RTCSEL));
01128       /* RTC Clock selection can be changed only if the Backup Domain is reset */
01129       __HAL_RCC_BACKUPRESET_FORCE();
01130       __HAL_RCC_BACKUPRESET_RELEASE();
01131       /* Restore the Content of BDCR register */
01132       RCC->BDCR = tmpreg1;
01133 
01134       /* Wait for LSE reactivation if LSE was enable prior to Backup Domain reset */
01135       if(HAL_IS_BIT_SET(RCC->BDCR, RCC_BDCR_LSEON))
01136       {
01137         /* Get tick */
01138         tickstart = HAL_GetTick();
01139 
01140         /* Wait till LSE is ready */
01141         while(__HAL_RCC_GET_FLAG(RCC_FLAG_LSERDY) == RESET)
01142         {
01143           if((HAL_GetTick() - tickstart ) > RCC_LSE_TIMEOUT_VALUE)
01144           {
01145             return HAL_TIMEOUT;
01146           }
01147         }
01148       }
01149     }
01150     __HAL_RCC_RTC_CONFIG(PeriphClkInit->RTCClockSelection);
01151   }
01152   /*--------------------------------------------------------------------------*/
01153 
01154   /*---------------------------- TIM configuration ---------------------------*/
01155   if(((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_TIM) == (RCC_PERIPHCLK_TIM))
01156   {
01157     __HAL_RCC_TIMCLKPRESCALER(PeriphClkInit->TIMPresSelection);
01158   }
01159   return HAL_OK;
01160 }
01161 
01162 /**
01163   * @brief  Configures the RCC_PeriphCLKInitTypeDef according to the internal
01164   * RCC configuration registers.
01165   * @param  PeriphClkInit pointer to an RCC_PeriphCLKInitTypeDef structure that
01166   *         will be configured.
01167   * @retval None
01168   */
01169 void HAL_RCCEx_GetPeriphCLKConfig(RCC_PeriphCLKInitTypeDef  *PeriphClkInit)
01170 {
01171   uint32_t tempreg;
01172 
01173   /* Set all possible values for the extended clock type parameter------------*/
01174   PeriphClkInit->PeriphClockSelection = RCC_PERIPHCLK_I2S        | RCC_PERIPHCLK_SAI_PLLSAI |\
01175                                         RCC_PERIPHCLK_SAI_PLLI2S | RCC_PERIPHCLK_LTDC       |\
01176                                         RCC_PERIPHCLK_TIM        | RCC_PERIPHCLK_RTC        |\
01177                                         RCC_PERIPHCLK_CLK48       | RCC_PERIPHCLK_SDIO;
01178 
01179   /* Get the PLLI2S Clock configuration --------------------------------------*/
01180   PeriphClkInit->PLLI2S.PLLI2SN = (uint32_t)((RCC->PLLI2SCFGR & RCC_PLLI2SCFGR_PLLI2SN) >> RCC_PLLI2SCFGR_PLLI2SN_Pos);
01181   PeriphClkInit->PLLI2S.PLLI2SR = (uint32_t)((RCC->PLLI2SCFGR & RCC_PLLI2SCFGR_PLLI2SR) >> RCC_PLLI2SCFGR_PLLI2SR_Pos);
01182   PeriphClkInit->PLLI2S.PLLI2SQ = (uint32_t)((RCC->PLLI2SCFGR & RCC_PLLI2SCFGR_PLLI2SQ) >> RCC_PLLI2SCFGR_PLLI2SQ_Pos);
01183   /* Get the PLLSAI Clock configuration --------------------------------------*/
01184   PeriphClkInit->PLLSAI.PLLSAIN = (uint32_t)((RCC->PLLSAICFGR & RCC_PLLSAICFGR_PLLSAIN) >> RCC_PLLSAICFGR_PLLSAIN_Pos);
01185   PeriphClkInit->PLLSAI.PLLSAIR = (uint32_t)((RCC->PLLSAICFGR & RCC_PLLSAICFGR_PLLSAIR) >> RCC_PLLSAICFGR_PLLSAIR_Pos);
01186   PeriphClkInit->PLLSAI.PLLSAIQ = (uint32_t)((RCC->PLLSAICFGR & RCC_PLLSAICFGR_PLLSAIQ) >> RCC_PLLSAICFGR_PLLSAIQ_Pos);
01187   /* Get the PLLSAI/PLLI2S division factors ----------------------------------*/
01188   PeriphClkInit->PLLI2SDivQ = (uint32_t)((RCC->DCKCFGR & RCC_DCKCFGR_PLLI2SDIVQ) >> RCC_DCKCFGR_PLLI2SDIVQ_Pos);
01189   PeriphClkInit->PLLSAIDivQ = (uint32_t)((RCC->DCKCFGR & RCC_DCKCFGR_PLLSAIDIVQ) >> RCC_DCKCFGR_PLLSAIDIVQ_Pos);
01190   PeriphClkInit->PLLSAIDivR = (uint32_t)(RCC->DCKCFGR & RCC_DCKCFGR_PLLSAIDIVR);
01191   /* Get the RTC Clock configuration -----------------------------------------*/
01192   tempreg = (RCC->CFGR & RCC_CFGR_RTCPRE);
01193   PeriphClkInit->RTCClockSelection = (uint32_t)((tempreg) | (RCC->BDCR & RCC_BDCR_RTCSEL));
01194 
01195     /* Get the CLK48 clock configuration -------------------------------------*/
01196   PeriphClkInit->Clk48ClockSelection = __HAL_RCC_GET_CLK48_SOURCE();
01197 
01198   /* Get the SDIO clock configuration ----------------------------------------*/
01199   PeriphClkInit->SdioClockSelection = __HAL_RCC_GET_SDIO_SOURCE();
01200 
01201   if ((RCC->DCKCFGR & RCC_DCKCFGR_TIMPRE) == RESET)
01202   {
01203     PeriphClkInit->TIMPresSelection = RCC_TIMPRES_DESACTIVATED;
01204   }
01205   else
01206   {
01207     PeriphClkInit->TIMPresSelection = RCC_TIMPRES_ACTIVATED;
01208   }
01209 }
01210 
01211 /**
01212   * @brief  Return the peripheral clock frequency for a given peripheral(SAI..)
01213   * @note   Return 0 if peripheral clock identifier not managed by this API
01214   * @param  PeriphClk Peripheral clock identifier
01215   *         This parameter can be one of the following values:
01216   *            @arg RCC_PERIPHCLK_I2S: I2S peripheral clock
01217   * @retval Frequency in KHz
01218   */
01219 uint32_t HAL_RCCEx_GetPeriphCLKFreq(uint32_t PeriphClk)
01220 {
01221   /* This variable used to store the I2S clock frequency (value in Hz) */
01222   uint32_t frequency = 0U;
01223   /* This variable used to store the VCO Input (value in Hz) */
01224   uint32_t vcoinput = 0U;
01225   uint32_t srcclk = 0U;
01226   /* This variable used to store the VCO Output (value in Hz) */
01227   uint32_t vcooutput = 0U;
01228   switch (PeriphClk)
01229   {
01230   case RCC_PERIPHCLK_I2S:
01231     {
01232       /* Get the current I2S source */
01233       srcclk = __HAL_RCC_GET_I2S_SOURCE();
01234       switch (srcclk)
01235       {
01236       /* Check if I2S clock selection is External clock mapped on the I2S_CKIN pin used as I2S clock */
01237       case RCC_I2SCLKSOURCE_EXT:
01238         {
01239           /* Set the I2S clock to the external clock  value */
01240           frequency = EXTERNAL_CLOCK_VALUE;
01241           break;
01242         }
01243       /* Check if I2S clock selection is PLLI2S VCO output clock divided by PLLI2SR used as I2S clock */
01244       case RCC_I2SCLKSOURCE_PLLI2S:
01245         {
01246           /* Configure the PLLI2S division factor */
01247           /* PLLI2S_VCO Input  = PLL_SOURCE/PLLI2SM */
01248           if((RCC->PLLCFGR & RCC_PLLCFGR_PLLSRC) == RCC_PLLSOURCE_HSE)
01249           {
01250             /* Get the I2S source clock value */
01251             vcoinput = (uint32_t)(HSE_VALUE / (uint32_t)(RCC->PLLCFGR & RCC_PLLCFGR_PLLM));
01252           }
01253           else
01254           {
01255             /* Get the I2S source clock value */
01256             vcoinput = (uint32_t)(HSI_VALUE / (uint32_t)(RCC->PLLCFGR & RCC_PLLCFGR_PLLM));
01257           }
01258 
01259           /* PLLI2S_VCO Output = PLLI2S_VCO Input * PLLI2SN */
01260           vcooutput = (uint32_t)(vcoinput * (((RCC->PLLI2SCFGR & RCC_PLLI2SCFGR_PLLI2SN) >> 6U) & (RCC_PLLI2SCFGR_PLLI2SN >> 6U)));
01261           /* I2S_CLK = PLLI2S_VCO Output/PLLI2SR */
01262           frequency = (uint32_t)(vcooutput /(((RCC->PLLI2SCFGR & RCC_PLLI2SCFGR_PLLI2SR) >> 28U) & (RCC_PLLI2SCFGR_PLLI2SR >> 28U)));
01263           break;
01264         }
01265         /* Clock not enabled for I2S*/
01266       default:
01267         {
01268           frequency = 0U;
01269           break;
01270         }
01271       }
01272       break;
01273     }
01274   }
01275   return frequency;
01276 }
01277 #endif /* STM32F469xx || STM32F479xx */
01278 
01279 #if defined(STM32F412Zx) || defined(STM32F412Vx) || defined(STM32F412Rx) || defined(STM32F412Cx) || defined(STM32F413xx) || defined(STM32F423xx)
01280 /**
01281   * @brief  Initializes the RCC extended peripherals clocks according to the specified
01282   *         parameters in the RCC_PeriphCLKInitTypeDef.
01283   * @param  PeriphClkInit pointer to an RCC_PeriphCLKInitTypeDef structure that
01284   *         contains the configuration information for the Extended Peripherals
01285   *         clocks(I2S, LTDC RTC and TIM).
01286   *
01287   * @note   Care must be taken when HAL_RCCEx_PeriphCLKConfig() is used to select
01288   *         the RTC clock source; in this case the Backup domain will be reset in
01289   *         order to modify the RTC Clock source, as consequence RTC registers (including
01290   *         the backup registers) and RCC_BDCR register are set to their reset values.
01291   *
01292   * @retval HAL status
01293   */
01294 HAL_StatusTypeDef HAL_RCCEx_PeriphCLKConfig(RCC_PeriphCLKInitTypeDef  *PeriphClkInit)
01295 {
01296   uint32_t tickstart = 0U;
01297   uint32_t tmpreg1 = 0U;
01298 #if defined(STM32F413xx) || defined(STM32F423xx)
01299   uint32_t plli2sq = 0U;
01300 #endif /* STM32F413xx || STM32F423xx */
01301   uint32_t plli2sused = 0U;
01302 
01303   /* Check the peripheral clock selection parameters */
01304   assert_param(IS_RCC_PERIPHCLOCK(PeriphClkInit->PeriphClockSelection));
01305 
01306   /*----------------------------------- I2S APB1 configuration ---------------*/
01307   if(((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_I2S_APB1) == (RCC_PERIPHCLK_I2S_APB1))
01308   {
01309     /* Check the parameters */
01310     assert_param(IS_RCC_I2SAPB1CLKSOURCE(PeriphClkInit->I2sApb1ClockSelection));
01311 
01312     /* Configure I2S Clock source */
01313     __HAL_RCC_I2S_APB1_CONFIG(PeriphClkInit->I2sApb1ClockSelection);
01314     /* Enable the PLLI2S when it's used as clock source for I2S */
01315     if(PeriphClkInit->I2sApb1ClockSelection == RCC_I2SAPB1CLKSOURCE_PLLI2S)
01316     {
01317       plli2sused = 1U;
01318     }
01319   }
01320   /*--------------------------------------------------------------------------*/
01321 
01322   /*----------------------------------- I2S APB2 configuration ---------------*/
01323   if(((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_I2S_APB2) == (RCC_PERIPHCLK_I2S_APB2))
01324   {
01325     /* Check the parameters */
01326     assert_param(IS_RCC_I2SAPB2CLKSOURCE(PeriphClkInit->I2sApb2ClockSelection));
01327 
01328     /* Configure I2S Clock source */
01329     __HAL_RCC_I2S_APB2_CONFIG(PeriphClkInit->I2sApb2ClockSelection);
01330     /* Enable the PLLI2S when it's used as clock source for I2S */
01331     if(PeriphClkInit->I2sApb2ClockSelection == RCC_I2SAPB2CLKSOURCE_PLLI2S)
01332     {
01333       plli2sused = 1U;
01334     }
01335   }
01336   /*--------------------------------------------------------------------------*/
01337 
01338 #if defined(STM32F413xx) || defined(STM32F423xx)
01339   /*----------------------- SAI1 Block A configuration -----------------------*/
01340   if(((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_SAIA) == (RCC_PERIPHCLK_SAIA))
01341   {
01342     /* Check the parameters */
01343     assert_param(IS_RCC_SAIACLKSOURCE(PeriphClkInit->SaiAClockSelection));
01344 
01345     /* Configure SAI1 Clock source */
01346     __HAL_RCC_SAI_BLOCKACLKSOURCE_CONFIG(PeriphClkInit->SaiAClockSelection);
01347     /* Enable the PLLI2S when it's used as clock source for SAI */
01348     if(PeriphClkInit->SaiAClockSelection == RCC_SAIACLKSOURCE_PLLI2SR)
01349     {
01350       plli2sused = 1U;
01351     }
01352     /* Enable the PLLSAI when it's used as clock source for SAI */
01353     if(PeriphClkInit->SaiAClockSelection == RCC_SAIACLKSOURCE_PLLR)
01354     {
01355       /* Check for PLL/DIVR parameters */
01356       assert_param(IS_RCC_PLL_DIVR_VALUE(PeriphClkInit->PLLDivR));
01357 
01358       /* SAI_CLK_x = SAI_CLK(first level)/PLLDIVR */
01359       __HAL_RCC_PLL_PLLSAICLKDIVR_CONFIG(PeriphClkInit->PLLDivR);
01360     }
01361   }
01362   /*--------------------------------------------------------------------------*/
01363 
01364   /*---------------------- SAI1 Block B configuration ------------------------*/
01365   if(((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_SAIB) == (RCC_PERIPHCLK_SAIB))
01366   {
01367     /* Check the parameters */
01368     assert_param(IS_RCC_SAIBCLKSOURCE(PeriphClkInit->SaiBClockSelection));
01369 
01370     /* Configure SAI1 Clock source */
01371     __HAL_RCC_SAI_BLOCKBCLKSOURCE_CONFIG(PeriphClkInit->SaiBClockSelection);
01372     /* Enable the PLLI2S when it's used as clock source for SAI */
01373     if(PeriphClkInit->SaiBClockSelection == RCC_SAIBCLKSOURCE_PLLI2SR)
01374     {
01375       plli2sused = 1U;
01376     }
01377     /* Enable the PLLSAI when it's used as clock source for SAI */
01378     if(PeriphClkInit->SaiBClockSelection == RCC_SAIBCLKSOURCE_PLLR)
01379     {
01380       /* Check for PLL/DIVR parameters */
01381       assert_param(IS_RCC_PLL_DIVR_VALUE(PeriphClkInit->PLLDivR));
01382 
01383       /* SAI_CLK_x = SAI_CLK(first level)/PLLDIVR */
01384       __HAL_RCC_PLL_PLLSAICLKDIVR_CONFIG(PeriphClkInit->PLLDivR);
01385     }
01386   }
01387   /*--------------------------------------------------------------------------*/
01388 #endif /* STM32F413xx || STM32F423xx */
01389 
01390   /*------------------------------------ RTC configuration -------------------*/
01391   if(((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_RTC) == (RCC_PERIPHCLK_RTC))
01392   {
01393     /* Check for RTC Parameters used to output RTCCLK */
01394     assert_param(IS_RCC_RTCCLKSOURCE(PeriphClkInit->RTCClockSelection));
01395 
01396     /* Enable Power Clock*/
01397     __HAL_RCC_PWR_CLK_ENABLE();
01398 
01399     /* Enable write access to Backup domain */
01400     PWR->CR |= PWR_CR_DBP;
01401 
01402     /* Get tick */
01403     tickstart = HAL_GetTick();
01404 
01405     while((PWR->CR & PWR_CR_DBP) == RESET)
01406     {
01407       if((HAL_GetTick() - tickstart ) > RCC_DBP_TIMEOUT_VALUE)
01408       {
01409         return HAL_TIMEOUT;
01410       }
01411     }
01412     /* Reset the Backup domain only if the RTC Clock source selection is modified from reset value */
01413     tmpreg1 = (RCC->BDCR & RCC_BDCR_RTCSEL);
01414     if((tmpreg1 != 0x00000000U) && ((tmpreg1) != (PeriphClkInit->RTCClockSelection & RCC_BDCR_RTCSEL)))
01415     {
01416       /* Store the content of BDCR register before the reset of Backup Domain */
01417       tmpreg1 = (RCC->BDCR & ~(RCC_BDCR_RTCSEL));
01418       /* RTC Clock selection can be changed only if the Backup Domain is reset */
01419       __HAL_RCC_BACKUPRESET_FORCE();
01420       __HAL_RCC_BACKUPRESET_RELEASE();
01421       /* Restore the Content of BDCR register */
01422       RCC->BDCR = tmpreg1;
01423 
01424       /* Wait for LSE reactivation if LSE was enable prior to Backup Domain reset */
01425       if(HAL_IS_BIT_SET(RCC->BDCR, RCC_BDCR_LSEON))
01426       {
01427         /* Get tick */
01428         tickstart = HAL_GetTick();
01429 
01430         /* Wait till LSE is ready */
01431         while(__HAL_RCC_GET_FLAG(RCC_FLAG_LSERDY) == RESET)
01432         {
01433           if((HAL_GetTick() - tickstart ) > RCC_LSE_TIMEOUT_VALUE)
01434           {
01435             return HAL_TIMEOUT;
01436           }
01437         }
01438       }
01439     }
01440     __HAL_RCC_RTC_CONFIG(PeriphClkInit->RTCClockSelection);
01441   }
01442   /*--------------------------------------------------------------------------*/
01443 
01444   /*------------------------------------ TIM configuration -------------------*/
01445   if(((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_TIM) == (RCC_PERIPHCLK_TIM))
01446   {
01447     /* Configure Timer Prescaler */
01448     __HAL_RCC_TIMCLKPRESCALER(PeriphClkInit->TIMPresSelection);
01449   }
01450   /*--------------------------------------------------------------------------*/
01451 
01452   /*------------------------------------- FMPI2C1 Configuration --------------*/
01453   if(((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_FMPI2C1) == RCC_PERIPHCLK_FMPI2C1)
01454   {
01455     /* Check the parameters */
01456     assert_param(IS_RCC_FMPI2C1CLKSOURCE(PeriphClkInit->Fmpi2c1ClockSelection));
01457 
01458     /* Configure the FMPI2C1 clock source */
01459     __HAL_RCC_FMPI2C1_CONFIG(PeriphClkInit->Fmpi2c1ClockSelection);
01460   }
01461   /*--------------------------------------------------------------------------*/
01462 
01463   /*------------------------------------- CLK48 Configuration ----------------*/
01464   if(((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_CLK48) == RCC_PERIPHCLK_CLK48)
01465   {
01466     /* Check the parameters */
01467     assert_param(IS_RCC_CLK48CLKSOURCE(PeriphClkInit->Clk48ClockSelection));
01468 
01469     /* Configure the SDIO clock source */
01470     __HAL_RCC_CLK48_CONFIG(PeriphClkInit->Clk48ClockSelection);
01471 
01472     /* Enable the PLLI2S when it's used as clock source for CLK48 */
01473     if(PeriphClkInit->Clk48ClockSelection == RCC_CLK48CLKSOURCE_PLLI2SQ)
01474     {
01475       plli2sused = 1U;
01476     }
01477   }
01478   /*--------------------------------------------------------------------------*/
01479 
01480   /*------------------------------------- SDIO Configuration -----------------*/
01481   if(((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_SDIO) == RCC_PERIPHCLK_SDIO)
01482   {
01483     /* Check the parameters */
01484     assert_param(IS_RCC_SDIOCLKSOURCE(PeriphClkInit->SdioClockSelection));
01485 
01486     /* Configure the SDIO clock source */
01487     __HAL_RCC_SDIO_CONFIG(PeriphClkInit->SdioClockSelection);
01488   }
01489   /*--------------------------------------------------------------------------*/
01490 
01491   /*-------------------------------------- PLLI2S Configuration --------------*/
01492   /* PLLI2S is configured when a peripheral will use it as source clock : I2S on APB1 or
01493      I2S on APB2*/
01494   if((plli2sused == 1U) || (PeriphClkInit->PeriphClockSelection == RCC_PERIPHCLK_PLLI2S))
01495   {
01496     /* Disable the PLLI2S */
01497     __HAL_RCC_PLLI2S_DISABLE();
01498     /* Get tick */
01499     tickstart = HAL_GetTick();
01500     /* Wait till PLLI2S is disabled */
01501     while(__HAL_RCC_GET_FLAG(RCC_FLAG_PLLI2SRDY)  != RESET)
01502     {
01503       if((HAL_GetTick() - tickstart ) > PLLI2S_TIMEOUT_VALUE)
01504       {
01505         /* return in case of Timeout detected */
01506         return HAL_TIMEOUT;
01507       }
01508     }
01509 
01510     /* check for common PLLI2S Parameters */
01511     assert_param(IS_RCC_PLLI2SCLKSOURCE(PeriphClkInit->PLLI2SSelection));
01512     assert_param(IS_RCC_PLLI2SM_VALUE(PeriphClkInit->PLLI2S.PLLI2SM));
01513     assert_param(IS_RCC_PLLI2SN_VALUE(PeriphClkInit->PLLI2S.PLLI2SN));
01514     /*-------------------- Set the PLL I2S clock -----------------------------*/
01515     __HAL_RCC_PLL_I2S_CONFIG(PeriphClkInit->PLLI2SSelection);
01516 
01517     /*------- In Case of PLLI2S is selected as source clock for I2S ----------*/
01518     if(((((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_I2S_APB1) == RCC_PERIPHCLK_I2S_APB1) && (PeriphClkInit->I2sApb1ClockSelection == RCC_I2SAPB1CLKSOURCE_PLLI2S)) ||
01519        ((((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_I2S_APB2) == RCC_PERIPHCLK_I2S_APB2) && (PeriphClkInit->I2sApb2ClockSelection == RCC_I2SAPB2CLKSOURCE_PLLI2S)) ||
01520        ((((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_CLK48) == RCC_PERIPHCLK_CLK48) && (PeriphClkInit->Clk48ClockSelection == RCC_CLK48CLKSOURCE_PLLI2SQ)) ||
01521        ((((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_SDIO) == RCC_PERIPHCLK_SDIO) && (PeriphClkInit->SdioClockSelection == RCC_SDIOCLKSOURCE_CLK48) && (PeriphClkInit->Clk48ClockSelection == RCC_CLK48CLKSOURCE_PLLI2SQ)))
01522     {
01523       /* check for Parameters */
01524       assert_param(IS_RCC_PLLI2SR_VALUE(PeriphClkInit->PLLI2S.PLLI2SR));
01525       assert_param(IS_RCC_PLLI2SQ_VALUE(PeriphClkInit->PLLI2S.PLLI2SQ));
01526 
01527       /* Configure the PLLI2S division factors */
01528       /* PLLI2S_VCO = f(VCO clock) = f(PLLI2S clock input) * (PLLI2SN/PLLI2SM)*/
01529       /* I2SCLK = f(PLLI2S clock output) = f(VCO clock) / PLLI2SR */
01530       __HAL_RCC_PLLI2S_CONFIG(PeriphClkInit->PLLI2S.PLLI2SM, PeriphClkInit->PLLI2S.PLLI2SN , PeriphClkInit->PLLI2S.PLLI2SQ, PeriphClkInit->PLLI2S.PLLI2SR);
01531     }
01532 
01533 #if defined(STM32F413xx) || defined(STM32F423xx)
01534     /*------- In Case of PLLI2S is selected as source clock for SAI ----------*/
01535     if(((((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_SAIA) == RCC_PERIPHCLK_SAIA) && (PeriphClkInit->SaiAClockSelection == RCC_SAIACLKSOURCE_PLLI2SR)) ||
01536        ((((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_SAIB) == RCC_PERIPHCLK_SAIB) && (PeriphClkInit->SaiBClockSelection == RCC_SAIBCLKSOURCE_PLLI2SR)))
01537     {
01538       /* Check for PLLI2S Parameters */
01539       assert_param(IS_RCC_PLLI2SR_VALUE(PeriphClkInit->PLLI2S.PLLI2SR));
01540       /* Check for PLLI2S/DIVR parameters */
01541       assert_param(IS_RCC_PLLI2S_DIVR_VALUE(PeriphClkInit->PLLI2SDivR));
01542 
01543       /* Read PLLI2SQ value from PLLI2SCFGR register (this value is not needed for SAI configuration) */
01544       plli2sq = ((RCC->PLLI2SCFGR & RCC_PLLI2SCFGR_PLLI2SQ) >> RCC_PLLI2SCFGR_PLLI2SQ_Pos);
01545       /* Configure the PLLI2S division factors */
01546       /* PLLI2S_VCO Input  = PLL_SOURCE/PLLI2SM */
01547       /* PLLI2S_VCO Output = PLLI2S_VCO Input * PLLI2SN */
01548       /* SAI_CLK(first level) = PLLI2S_VCO Output/PLLI2SQ */
01549       __HAL_RCC_PLLI2S_CONFIG(PeriphClkInit->PLLI2S.PLLI2SM, PeriphClkInit->PLLI2S.PLLI2SN, plli2sq, PeriphClkInit->PLLI2S.PLLI2SR);
01550 
01551       /* SAI_CLK_x = SAI_CLK(first level)/PLLI2SDIVR */
01552       __HAL_RCC_PLLI2S_PLLSAICLKDIVR_CONFIG(PeriphClkInit->PLLI2SDivR);
01553     }
01554 #endif /* STM32F413xx || STM32F423xx */
01555 
01556     /*----------------- In Case of PLLI2S is just selected  ------------------*/
01557     if((PeriphClkInit->PeriphClockSelection & RCC_PERIPHCLK_PLLI2S) == RCC_PERIPHCLK_PLLI2S)
01558     {
01559       /* Check for Parameters */
01560       assert_param(IS_RCC_PLLI2SR_VALUE(PeriphClkInit->PLLI2S.PLLI2SR));
01561       assert_param(IS_RCC_PLLI2SQ_VALUE(PeriphClkInit->PLLI2S.PLLI2SQ));
01562 
01563       /* Configure the PLLI2S division factors */
01564       /* PLLI2S_VCO = f(VCO clock) = f(PLLI2S clock input) * (PLLI2SN/PLLI2SM)*/
01565       /* SPDIFRXCLK = f(PLLI2S clock output) = f(VCO clock) / PLLI2SP */
01566       __HAL_RCC_PLLI2S_CONFIG(PeriphClkInit->PLLI2S.PLLI2SM, PeriphClkInit->PLLI2S.PLLI2SN , PeriphClkInit->PLLI2S.PLLI2SQ, PeriphClkInit->PLLI2S.PLLI2SR);
01567     }
01568 
01569     /* Enable the PLLI2S */
01570     __HAL_RCC_PLLI2S_ENABLE();
01571     /* Get tick */
01572     tickstart = HAL_GetTick();
01573     /* Wait till PLLI2S is ready */
01574     while(__HAL_RCC_GET_FLAG(RCC_FLAG_PLLI2SRDY)  == RESET)
01575     {
01576       if((HAL_GetTick() - tickstart ) > PLLI2S_TIMEOUT_VALUE)
01577       {
01578         /* return in case of Timeout detected */
01579         return HAL_TIMEOUT;
01580       }
01581     }
01582   }
01583   /*--------------------------------------------------------------------------*/
01584 
01585   /*-------------------- DFSDM1 clock source configuration -------------------*/
01586   if(((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_DFSDM1) == RCC_PERIPHCLK_DFSDM1)
01587   {
01588     /* Check the parameters */
01589     assert_param(IS_RCC_DFSDM1CLKSOURCE(PeriphClkInit->Dfsdm1ClockSelection));
01590 
01591     /* Configure the DFSDM1 interface clock source */
01592     __HAL_RCC_DFSDM1_CONFIG(PeriphClkInit->Dfsdm1ClockSelection);
01593   }
01594   /*--------------------------------------------------------------------------*/
01595 
01596   /*-------------------- DFSDM1 Audio clock source configuration -------------*/
01597   if(((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_DFSDM1_AUDIO) == RCC_PERIPHCLK_DFSDM1_AUDIO)
01598   {
01599     /* Check the parameters */
01600     assert_param(IS_RCC_DFSDM1AUDIOCLKSOURCE(PeriphClkInit->Dfsdm1AudioClockSelection));
01601 
01602     /* Configure the DFSDM1 Audio interface clock source */
01603     __HAL_RCC_DFSDM1AUDIO_CONFIG(PeriphClkInit->Dfsdm1AudioClockSelection);
01604   }
01605   /*--------------------------------------------------------------------------*/
01606 
01607 #if defined(STM32F413xx) || defined(STM32F423xx)
01608   /*-------------------- DFSDM2 clock source configuration -------------------*/
01609   if(((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_DFSDM2) == RCC_PERIPHCLK_DFSDM2)
01610   {
01611     /* Check the parameters */
01612     assert_param(IS_RCC_DFSDM2CLKSOURCE(PeriphClkInit->Dfsdm2ClockSelection));
01613 
01614     /* Configure the DFSDM1 interface clock source */
01615     __HAL_RCC_DFSDM2_CONFIG(PeriphClkInit->Dfsdm2ClockSelection);
01616   }
01617   /*--------------------------------------------------------------------------*/
01618 
01619   /*-------------------- DFSDM2 Audio clock source configuration -------------*/
01620   if(((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_DFSDM2_AUDIO) == RCC_PERIPHCLK_DFSDM2_AUDIO)
01621   {
01622     /* Check the parameters */
01623     assert_param(IS_RCC_DFSDM2AUDIOCLKSOURCE(PeriphClkInit->Dfsdm2AudioClockSelection));
01624 
01625     /* Configure the DFSDM1 Audio interface clock source */
01626     __HAL_RCC_DFSDM2AUDIO_CONFIG(PeriphClkInit->Dfsdm2AudioClockSelection);
01627   }
01628   /*--------------------------------------------------------------------------*/
01629 
01630   /*---------------------------- LPTIM1 Configuration ------------------------*/
01631   if(((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_LPTIM1) == RCC_PERIPHCLK_LPTIM1)
01632   {
01633     /* Check the parameters */
01634     assert_param(IS_RCC_LPTIM1CLKSOURCE(PeriphClkInit->Lptim1ClockSelection));
01635 
01636     /* Configure the LPTIM1 clock source */
01637     __HAL_RCC_LPTIM1_CONFIG(PeriphClkInit->Lptim1ClockSelection);
01638   }
01639   /*--------------------------------------------------------------------------*/
01640 #endif /* STM32F413xx || STM32F423xx */
01641 
01642   return HAL_OK;
01643 }
01644 
01645 /**
01646   * @brief  Get the RCC_PeriphCLKInitTypeDef according to the internal
01647   *         RCC configuration registers.
01648   * @param  PeriphClkInit pointer to an RCC_PeriphCLKInitTypeDef structure that
01649   *         will be configured.
01650   * @retval None
01651   */
01652 void HAL_RCCEx_GetPeriphCLKConfig(RCC_PeriphCLKInitTypeDef  *PeriphClkInit)
01653 {
01654   uint32_t tempreg;
01655 
01656   /* Set all possible values for the extended clock type parameter------------*/
01657 #if defined(STM32F413xx) || defined(STM32F423xx)
01658   PeriphClkInit->PeriphClockSelection = RCC_PERIPHCLK_I2S_APB1     | RCC_PERIPHCLK_I2S_APB2 |\
01659                                         RCC_PERIPHCLK_TIM          | RCC_PERIPHCLK_RTC      |\
01660                                         RCC_PERIPHCLK_FMPI2C1      | RCC_PERIPHCLK_CLK48    |\
01661                                         RCC_PERIPHCLK_SDIO         | RCC_PERIPHCLK_DFSDM1   |\
01662                                         RCC_PERIPHCLK_DFSDM1_AUDIO | RCC_PERIPHCLK_DFSDM2   |\
01663                                         RCC_PERIPHCLK_DFSDM2_AUDIO | RCC_PERIPHCLK_LPTIM1   |\
01664                                         RCC_PERIPHCLK_SAIA         | RCC_PERIPHCLK_SAIB;
01665 #else /* STM32F412Zx || STM32F412Vx || STM32F412Rx || STM32F412Cx */
01666   PeriphClkInit->PeriphClockSelection = RCC_PERIPHCLK_I2S_APB1 | RCC_PERIPHCLK_I2S_APB2 |\
01667                                         RCC_PERIPHCLK_TIM      | RCC_PERIPHCLK_RTC      |\
01668                                         RCC_PERIPHCLK_FMPI2C1  | RCC_PERIPHCLK_CLK48    |\
01669                                         RCC_PERIPHCLK_SDIO     | RCC_PERIPHCLK_DFSDM1   |\
01670                                         RCC_PERIPHCLK_DFSDM1_AUDIO;
01671 #endif /* STM32F413xx || STM32F423xx */
01672 
01673 
01674 
01675   /* Get the PLLI2S Clock configuration --------------------------------------*/
01676   PeriphClkInit->PLLI2S.PLLI2SM = (uint32_t)((RCC->PLLI2SCFGR & RCC_PLLI2SCFGR_PLLI2SM) >> RCC_PLLI2SCFGR_PLLI2SM_Pos);
01677   PeriphClkInit->PLLI2S.PLLI2SN = (uint32_t)((RCC->PLLI2SCFGR & RCC_PLLI2SCFGR_PLLI2SN) >> RCC_PLLI2SCFGR_PLLI2SN_Pos);
01678   PeriphClkInit->PLLI2S.PLLI2SQ = (uint32_t)((RCC->PLLI2SCFGR & RCC_PLLI2SCFGR_PLLI2SQ) >> RCC_PLLI2SCFGR_PLLI2SQ_Pos);
01679   PeriphClkInit->PLLI2S.PLLI2SR = (uint32_t)((RCC->PLLI2SCFGR & RCC_PLLI2SCFGR_PLLI2SR) >> RCC_PLLI2SCFGR_PLLI2SR_Pos);
01680 #if defined(STM32F413xx) || defined(STM32F423xx)
01681   /* Get the PLL/PLLI2S division factors -------------------------------------*/
01682   PeriphClkInit->PLLI2SDivR = (uint32_t)((RCC->DCKCFGR & RCC_DCKCFGR_PLLI2SDIVR) >> RCC_DCKCFGR_PLLI2SDIVR_Pos);
01683   PeriphClkInit->PLLDivR = (uint32_t)((RCC->DCKCFGR & RCC_DCKCFGR_PLLDIVR) >> RCC_DCKCFGR_PLLDIVR_Pos);
01684 #endif /* STM32F413xx || STM32F423xx */
01685 
01686   /* Get the I2S APB1 clock configuration ------------------------------------*/
01687   PeriphClkInit->I2sApb1ClockSelection = __HAL_RCC_GET_I2S_APB1_SOURCE();
01688 
01689   /* Get the I2S APB2 clock configuration ------------------------------------*/
01690   PeriphClkInit->I2sApb2ClockSelection = __HAL_RCC_GET_I2S_APB2_SOURCE();
01691 
01692   /* Get the RTC Clock configuration -----------------------------------------*/
01693   tempreg = (RCC->CFGR & RCC_CFGR_RTCPRE);
01694   PeriphClkInit->RTCClockSelection = (uint32_t)((tempreg) | (RCC->BDCR & RCC_BDCR_RTCSEL));
01695 
01696   /* Get the FMPI2C1 clock configuration -------------------------------------*/
01697   PeriphClkInit->Fmpi2c1ClockSelection = __HAL_RCC_GET_FMPI2C1_SOURCE();
01698 
01699   /* Get the CLK48 clock configuration ---------------------------------------*/
01700   PeriphClkInit->Clk48ClockSelection = __HAL_RCC_GET_CLK48_SOURCE();
01701 
01702   /* Get the SDIO clock configuration ----------------------------------------*/
01703   PeriphClkInit->SdioClockSelection = __HAL_RCC_GET_SDIO_SOURCE();
01704 
01705   /* Get the DFSDM1 clock configuration --------------------------------------*/
01706   PeriphClkInit->Dfsdm1ClockSelection = __HAL_RCC_GET_DFSDM1_SOURCE();
01707 
01708   /* Get the DFSDM1 Audio clock configuration --------------------------------*/
01709   PeriphClkInit->Dfsdm1AudioClockSelection = __HAL_RCC_GET_DFSDM1AUDIO_SOURCE();
01710 
01711 #if defined(STM32F413xx) || defined(STM32F423xx)
01712   /* Get the DFSDM2 clock configuration --------------------------------------*/
01713   PeriphClkInit->Dfsdm2ClockSelection = __HAL_RCC_GET_DFSDM2_SOURCE();
01714 
01715   /* Get the DFSDM2 Audio clock configuration --------------------------------*/
01716   PeriphClkInit->Dfsdm2AudioClockSelection = __HAL_RCC_GET_DFSDM2AUDIO_SOURCE();
01717 
01718   /* Get the LPTIM1 clock configuration --------------------------------------*/
01719   PeriphClkInit->Lptim1ClockSelection = __HAL_RCC_GET_LPTIM1_SOURCE();
01720 
01721   /* Get the SAI1 Block Aclock configuration ---------------------------------*/
01722   PeriphClkInit->SaiAClockSelection = __HAL_RCC_GET_SAI_BLOCKA_SOURCE();
01723 
01724   /* Get the SAI1 Block B clock configuration --------------------------------*/
01725   PeriphClkInit->SaiBClockSelection = __HAL_RCC_GET_SAI_BLOCKB_SOURCE();
01726 #endif /* STM32F413xx || STM32F423xx */
01727 
01728   /* Get the TIM Prescaler configuration -------------------------------------*/
01729   if ((RCC->DCKCFGR & RCC_DCKCFGR_TIMPRE) == RESET)
01730   {
01731     PeriphClkInit->TIMPresSelection = RCC_TIMPRES_DESACTIVATED;
01732   }
01733   else
01734   {
01735     PeriphClkInit->TIMPresSelection = RCC_TIMPRES_ACTIVATED;
01736   }
01737 }
01738 
01739 /**
01740   * @brief  Return the peripheral clock frequency for a given peripheral(I2S..)
01741   * @note   Return 0 if peripheral clock identifier not managed by this API
01742   * @param  PeriphClk Peripheral clock identifier
01743   *         This parameter can be one of the following values:
01744   *            @arg RCC_PERIPHCLK_I2S_APB1: I2S APB1 peripheral clock
01745   *            @arg RCC_PERIPHCLK_I2S_APB2: I2S APB2 peripheral clock
01746   * @retval Frequency in KHz
01747   */
01748 uint32_t HAL_RCCEx_GetPeriphCLKFreq(uint32_t PeriphClk)
01749 {
01750   /* This variable used to store the I2S clock frequency (value in Hz) */
01751   uint32_t frequency = 0U;
01752   /* This variable used to store the VCO Input (value in Hz) */
01753   uint32_t vcoinput = 0U;
01754   uint32_t srcclk = 0U;
01755   /* This variable used to store the VCO Output (value in Hz) */
01756   uint32_t vcooutput = 0U;
01757   switch (PeriphClk)
01758   {
01759   case RCC_PERIPHCLK_I2S_APB1:
01760     {
01761       /* Get the current I2S source */
01762       srcclk = __HAL_RCC_GET_I2S_APB1_SOURCE();
01763       switch (srcclk)
01764       {
01765       /* Check if I2S clock selection is External clock mapped on the I2S_CKIN pin used as I2S clock */
01766       case RCC_I2SAPB1CLKSOURCE_EXT:
01767         {
01768           /* Set the I2S clock to the external clock  value */
01769           frequency = EXTERNAL_CLOCK_VALUE;
01770           break;
01771         }
01772       /* Check if I2S clock selection is PLLI2S VCO output clock divided by PLLI2SR used as I2S clock */
01773       case RCC_I2SAPB1CLKSOURCE_PLLI2S:
01774         {
01775           if((RCC->PLLI2SCFGR & RCC_PLLI2SCFGR_PLLI2SSRC) == RCC_PLLI2SCFGR_PLLI2SSRC)
01776           {
01777             /* Get the I2S source clock value */
01778             vcoinput = (uint32_t)(EXTERNAL_CLOCK_VALUE / (uint32_t)(RCC->PLLI2SCFGR & RCC_PLLI2SCFGR_PLLI2SM));
01779           }
01780           else
01781           {
01782             /* Configure the PLLI2S division factor */
01783             /* PLLI2S_VCO Input  = PLL_SOURCE/PLLI2SM */
01784             if((RCC->PLLCFGR & RCC_PLLCFGR_PLLSRC) == RCC_PLLSOURCE_HSE)
01785             {
01786               /* Get the I2S source clock value */
01787               vcoinput = (uint32_t)(HSE_VALUE / (uint32_t)(RCC->PLLI2SCFGR & RCC_PLLI2SCFGR_PLLI2SM));
01788             }
01789             else
01790             {
01791               /* Get the I2S source clock value */
01792               vcoinput = (uint32_t)(HSI_VALUE / (uint32_t)(RCC->PLLI2SCFGR & RCC_PLLI2SCFGR_PLLI2SM));
01793             }
01794           }
01795           /* PLLI2S_VCO Output = PLLI2S_VCO Input * PLLI2SN */
01796           vcooutput = (uint32_t)(vcoinput * (((RCC->PLLI2SCFGR & RCC_PLLI2SCFGR_PLLI2SN) >> 6U) & (RCC_PLLI2SCFGR_PLLI2SN >> 6U)));
01797           /* I2S_CLK = PLLI2S_VCO Output/PLLI2SR */
01798           frequency = (uint32_t)(vcooutput /(((RCC->PLLI2SCFGR & RCC_PLLI2SCFGR_PLLI2SR) >> 28U) & (RCC_PLLI2SCFGR_PLLI2SR >> 28U)));
01799           break;
01800         }
01801       /* Check if I2S clock selection is PLL VCO Output divided by PLLR used as I2S clock */
01802       case RCC_I2SAPB1CLKSOURCE_PLLR:
01803         {
01804           /* Configure the PLL division factor R */
01805           /* PLL_VCO Input  = PLL_SOURCE/PLLM */
01806           if((RCC->PLLCFGR & RCC_PLLCFGR_PLLSRC) == RCC_PLLSOURCE_HSE)
01807           {
01808             /* Get the I2S source clock value */
01809             vcoinput = (uint32_t)(HSE_VALUE / (uint32_t)(RCC->PLLCFGR & RCC_PLLCFGR_PLLM));
01810           }
01811           else
01812           {
01813             /* Get the I2S source clock value */
01814             vcoinput = (uint32_t)(HSI_VALUE / (uint32_t)(RCC->PLLCFGR & RCC_PLLCFGR_PLLM));
01815           }
01816 
01817           /* PLL_VCO Output = PLL_VCO Input * PLLN */
01818           vcooutput = (uint32_t)(vcoinput * (((RCC->PLLCFGR & RCC_PLLCFGR_PLLN) >> 6U) & (RCC_PLLCFGR_PLLN >> 6U)));
01819           /* I2S_CLK = PLL_VCO Output/PLLR */
01820           frequency = (uint32_t)(vcooutput /(((RCC->PLLCFGR & RCC_PLLCFGR_PLLR) >> 28U) & (RCC_PLLCFGR_PLLR >> 28U)));
01821           break;
01822         }
01823       /* Check if I2S clock selection is HSI or HSE depending from PLL source Clock */
01824       case RCC_I2SAPB1CLKSOURCE_PLLSRC:
01825         {
01826           if((RCC->PLLCFGR & RCC_PLLCFGR_PLLSRC) == RCC_PLLSOURCE_HSE)
01827           {
01828             frequency = HSE_VALUE;
01829           }
01830           else
01831           {
01832             frequency = HSI_VALUE;
01833           }
01834           break;
01835         }
01836         /* Clock not enabled for I2S*/
01837       default:
01838         {
01839           frequency = 0U;
01840           break;
01841         }
01842       }
01843       break;
01844     }
01845   case RCC_PERIPHCLK_I2S_APB2:
01846     {
01847       /* Get the current I2S source */
01848       srcclk = __HAL_RCC_GET_I2S_APB2_SOURCE();
01849       switch (srcclk)
01850       {
01851         /* Check if I2S clock selection is External clock mapped on the I2S_CKIN pin used as I2S clock */
01852       case RCC_I2SAPB2CLKSOURCE_EXT:
01853         {
01854           /* Set the I2S clock to the external clock  value */
01855           frequency = EXTERNAL_CLOCK_VALUE;
01856           break;
01857         }
01858         /* Check if I2S clock selection is PLLI2S VCO output clock divided by PLLI2SR used as I2S clock */
01859       case RCC_I2SAPB2CLKSOURCE_PLLI2S:
01860         {
01861           if((RCC->PLLI2SCFGR & RCC_PLLI2SCFGR_PLLI2SSRC) == RCC_PLLI2SCFGR_PLLI2SSRC)
01862           {
01863             /* Get the I2S source clock value */
01864             vcoinput = (uint32_t)(EXTERNAL_CLOCK_VALUE / (uint32_t)(RCC->PLLI2SCFGR & RCC_PLLI2SCFGR_PLLI2SM));
01865           }
01866           else
01867           {
01868             /* Configure the PLLI2S division factor */
01869             /* PLLI2S_VCO Input  = PLL_SOURCE/PLLI2SM */
01870             if((RCC->PLLCFGR & RCC_PLLCFGR_PLLSRC) == RCC_PLLSOURCE_HSE)
01871             {
01872               /* Get the I2S source clock value */
01873               vcoinput = (uint32_t)(HSE_VALUE / (uint32_t)(RCC->PLLI2SCFGR & RCC_PLLI2SCFGR_PLLI2SM));
01874             }
01875             else
01876             {
01877               /* Get the I2S source clock value */
01878               vcoinput = (uint32_t)(HSI_VALUE / (uint32_t)(RCC->PLLI2SCFGR & RCC_PLLI2SCFGR_PLLI2SM));
01879             }
01880           }
01881           /* PLLI2S_VCO Output = PLLI2S_VCO Input * PLLI2SN */
01882           vcooutput = (uint32_t)(vcoinput * (((RCC->PLLI2SCFGR & RCC_PLLI2SCFGR_PLLI2SN) >> 6U) & (RCC_PLLI2SCFGR_PLLI2SN >> 6U)));
01883           /* I2S_CLK = PLLI2S_VCO Output/PLLI2SR */
01884           frequency = (uint32_t)(vcooutput /(((RCC->PLLI2SCFGR & RCC_PLLI2SCFGR_PLLI2SR) >> 28U) & (RCC_PLLI2SCFGR_PLLI2SR >> 28U)));
01885           break;
01886         }
01887         /* Check if I2S clock selection is PLL VCO Output divided by PLLR used as I2S clock */
01888       case RCC_I2SAPB2CLKSOURCE_PLLR:
01889         {
01890           /* Configure the PLL division factor R */
01891           /* PLL_VCO Input  = PLL_SOURCE/PLLM */
01892           if((RCC->PLLCFGR & RCC_PLLCFGR_PLLSRC) == RCC_PLLSOURCE_HSE)
01893           {
01894             /* Get the I2S source clock value */
01895             vcoinput = (uint32_t)(HSE_VALUE / (uint32_t)(RCC->PLLCFGR & RCC_PLLCFGR_PLLM));
01896           }
01897           else
01898           {
01899             /* Get the I2S source clock value */
01900             vcoinput = (uint32_t)(HSI_VALUE / (uint32_t)(RCC->PLLCFGR & RCC_PLLCFGR_PLLM));
01901           }
01902 
01903           /* PLL_VCO Output = PLL_VCO Input * PLLN */
01904           vcooutput = (uint32_t)(vcoinput * (((RCC->PLLCFGR & RCC_PLLCFGR_PLLN) >> 6U) & (RCC_PLLCFGR_PLLN >> 6U)));
01905           /* I2S_CLK = PLL_VCO Output/PLLR */
01906           frequency = (uint32_t)(vcooutput /(((RCC->PLLCFGR & RCC_PLLCFGR_PLLR) >> 28U) & (RCC_PLLCFGR_PLLR >> 28U)));
01907           break;
01908         }
01909         /* Check if I2S clock selection is HSI or HSE depending from PLL source Clock */
01910       case RCC_I2SAPB2CLKSOURCE_PLLSRC:
01911         {
01912           if((RCC->PLLCFGR & RCC_PLLCFGR_PLLSRC) == RCC_PLLSOURCE_HSE)
01913           {
01914             frequency = HSE_VALUE;
01915           }
01916           else
01917           {
01918             frequency = HSI_VALUE;
01919           }
01920           break;
01921         }
01922       /* Clock not enabled for I2S*/
01923       default:
01924         {
01925           frequency = 0U;
01926           break;
01927         }
01928       }
01929       break;
01930     }
01931   }
01932   return frequency;
01933 }
01934 #endif /* STM32F412Zx || STM32F412Vx || STM32F412Rx || STM32F412Cx || STM32F413xx || STM32F423xx */
01935 
01936 #if defined(STM32F410Tx) || defined(STM32F410Cx) || defined(STM32F410Rx)
01937 /**
01938   * @brief  Initializes the RCC extended peripherals clocks according to the specified parameters in the
01939   *         RCC_PeriphCLKInitTypeDef.
01940   * @param  PeriphClkInit pointer to an RCC_PeriphCLKInitTypeDef structure that
01941   *         contains the configuration information for the Extended Peripherals clocks(I2S and RTC clocks).
01942   *
01943   * @note   A caution to be taken when HAL_RCCEx_PeriphCLKConfig() is used to select RTC clock selection, in this case
01944   *         the Reset of Backup domain will be applied in order to modify the RTC Clock source as consequence all backup
01945   *        domain (RTC and RCC_BDCR register expect BKPSRAM) will be reset
01946   *
01947   * @retval HAL status
01948   */
01949 HAL_StatusTypeDef HAL_RCCEx_PeriphCLKConfig(RCC_PeriphCLKInitTypeDef  *PeriphClkInit)
01950 {
01951   uint32_t tickstart = 0U;
01952   uint32_t tmpreg1 = 0U;
01953 
01954   /* Check the parameters */
01955   assert_param(IS_RCC_PERIPHCLOCK(PeriphClkInit->PeriphClockSelection));
01956 
01957   /*---------------------------- RTC configuration ---------------------------*/
01958   if(((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_RTC) == (RCC_PERIPHCLK_RTC))
01959   {
01960     /* Check for RTC Parameters used to output RTCCLK */
01961     assert_param(IS_RCC_RTCCLKSOURCE(PeriphClkInit->RTCClockSelection));
01962 
01963     /* Enable Power Clock*/
01964     __HAL_RCC_PWR_CLK_ENABLE();
01965 
01966     /* Enable write access to Backup domain */
01967     PWR->CR |= PWR_CR_DBP;
01968 
01969     /* Get tick */
01970     tickstart = HAL_GetTick();
01971 
01972     while((PWR->CR & PWR_CR_DBP) == RESET)
01973     {
01974       if((HAL_GetTick() - tickstart ) > RCC_DBP_TIMEOUT_VALUE)
01975       {
01976         return HAL_TIMEOUT;
01977       }
01978     }
01979     /* Reset the Backup domain only if the RTC Clock source selection is modified from reset value */
01980     tmpreg1 = (RCC->BDCR & RCC_BDCR_RTCSEL);
01981     if((tmpreg1 != 0x00000000U) && ((tmpreg1) != (PeriphClkInit->RTCClockSelection & RCC_BDCR_RTCSEL)))
01982     {
01983       /* Store the content of BDCR register before the reset of Backup Domain */
01984       tmpreg1 = (RCC->BDCR & ~(RCC_BDCR_RTCSEL));
01985       /* RTC Clock selection can be changed only if the Backup Domain is reset */
01986       __HAL_RCC_BACKUPRESET_FORCE();
01987       __HAL_RCC_BACKUPRESET_RELEASE();
01988       /* Restore the Content of BDCR register */
01989       RCC->BDCR = tmpreg1;
01990 
01991       /* Wait for LSE reactivation if LSE was enable prior to Backup Domain reset */
01992       if(HAL_IS_BIT_SET(RCC->BDCR, RCC_BDCR_LSEON))
01993       {
01994         /* Get tick */
01995         tickstart = HAL_GetTick();
01996 
01997         /* Wait till LSE is ready */
01998         while(__HAL_RCC_GET_FLAG(RCC_FLAG_LSERDY) == RESET)
01999         {
02000           if((HAL_GetTick() - tickstart ) > RCC_LSE_TIMEOUT_VALUE)
02001           {
02002             return HAL_TIMEOUT;
02003           }
02004         }
02005       }
02006     }
02007     __HAL_RCC_RTC_CONFIG(PeriphClkInit->RTCClockSelection);
02008   }
02009   /*--------------------------------------------------------------------------*/
02010 
02011   /*---------------------------- TIM configuration ---------------------------*/
02012   if(((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_TIM) == (RCC_PERIPHCLK_TIM))
02013   {
02014     __HAL_RCC_TIMCLKPRESCALER(PeriphClkInit->TIMPresSelection);
02015   }
02016   /*--------------------------------------------------------------------------*/
02017 
02018   /*---------------------------- FMPI2C1 Configuration -----------------------*/
02019   if(((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_FMPI2C1) == RCC_PERIPHCLK_FMPI2C1)
02020   {
02021     /* Check the parameters */
02022     assert_param(IS_RCC_FMPI2C1CLKSOURCE(PeriphClkInit->Fmpi2c1ClockSelection));
02023 
02024     /* Configure the FMPI2C1 clock source */
02025     __HAL_RCC_FMPI2C1_CONFIG(PeriphClkInit->Fmpi2c1ClockSelection);
02026   }
02027   /*--------------------------------------------------------------------------*/
02028 
02029   /*---------------------------- LPTIM1 Configuration ------------------------*/
02030   if(((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_LPTIM1) == RCC_PERIPHCLK_LPTIM1)
02031   {
02032     /* Check the parameters */
02033     assert_param(IS_RCC_LPTIM1CLKSOURCE(PeriphClkInit->Lptim1ClockSelection));
02034 
02035     /* Configure the LPTIM1 clock source */
02036     __HAL_RCC_LPTIM1_CONFIG(PeriphClkInit->Lptim1ClockSelection);
02037   }
02038 
02039   /*---------------------------- I2S Configuration ---------------------------*/
02040   if(((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_I2S) == RCC_PERIPHCLK_I2S)
02041   {
02042     /* Check the parameters */
02043     assert_param(IS_RCC_I2SAPBCLKSOURCE(PeriphClkInit->I2SClockSelection));
02044 
02045     /* Configure the I2S clock source */
02046     __HAL_RCC_I2S_CONFIG(PeriphClkInit->I2SClockSelection);
02047   }
02048 
02049   return HAL_OK;
02050 }
02051 
02052 /**
02053   * @brief  Configures the RCC_OscInitStruct according to the internal
02054   * RCC configuration registers.
02055   * @param  PeriphClkInit pointer to an RCC_PeriphCLKInitTypeDef structure that
02056   * will be configured.
02057   * @retval None
02058   */
02059 void HAL_RCCEx_GetPeriphCLKConfig(RCC_PeriphCLKInitTypeDef  *PeriphClkInit)
02060 {
02061   uint32_t tempreg;
02062 
02063   /* Set all possible values for the extended clock type parameter------------*/
02064   PeriphClkInit->PeriphClockSelection = RCC_PERIPHCLK_FMPI2C1 | RCC_PERIPHCLK_LPTIM1 | RCC_PERIPHCLK_TIM | RCC_PERIPHCLK_RTC;
02065 
02066   tempreg = (RCC->CFGR & RCC_CFGR_RTCPRE);
02067   PeriphClkInit->RTCClockSelection = (uint32_t)((tempreg) | (RCC->BDCR & RCC_BDCR_RTCSEL));
02068 
02069   if ((RCC->DCKCFGR & RCC_DCKCFGR_TIMPRE) == RESET)
02070   {
02071     PeriphClkInit->TIMPresSelection = RCC_TIMPRES_DESACTIVATED;
02072   }
02073   else
02074   {
02075     PeriphClkInit->TIMPresSelection = RCC_TIMPRES_ACTIVATED;
02076   }
02077   /* Get the FMPI2C1 clock configuration -------------------------------------*/
02078   PeriphClkInit->Fmpi2c1ClockSelection = __HAL_RCC_GET_FMPI2C1_SOURCE();
02079 
02080   /* Get the I2S clock configuration -----------------------------------------*/
02081   PeriphClkInit->I2SClockSelection = __HAL_RCC_GET_I2S_SOURCE();
02082 
02083 
02084 }
02085 /**
02086   * @brief  Return the peripheral clock frequency for a given peripheral(SAI..)
02087   * @note   Return 0 if peripheral clock identifier not managed by this API
02088   * @param  PeriphClk Peripheral clock identifier
02089   *         This parameter can be one of the following values:
02090   *            @arg RCC_PERIPHCLK_I2S: I2S peripheral clock
02091   * @retval Frequency in KHz
02092   */
02093 uint32_t HAL_RCCEx_GetPeriphCLKFreq(uint32_t PeriphClk)
02094 {
02095   /* This variable used to store the I2S clock frequency (value in Hz) */
02096   uint32_t frequency = 0U;
02097   /* This variable used to store the VCO Input (value in Hz) */
02098   uint32_t vcoinput = 0U;
02099   uint32_t srcclk = 0U;
02100   /* This variable used to store the VCO Output (value in Hz) */
02101   uint32_t vcooutput = 0U;
02102   switch (PeriphClk)
02103   {
02104   case RCC_PERIPHCLK_I2S:
02105     {
02106       /* Get the current I2S source */
02107       srcclk = __HAL_RCC_GET_I2S_SOURCE();
02108       switch (srcclk)
02109       {
02110       /* Check if I2S clock selection is External clock mapped on the I2S_CKIN pin used as I2S clock */
02111       case RCC_I2SAPBCLKSOURCE_EXT:
02112         {
02113           /* Set the I2S clock to the external clock  value */
02114           frequency = EXTERNAL_CLOCK_VALUE;
02115           break;
02116         }
02117       /* Check if I2S clock selection is PLL VCO Output divided by PLLR used as I2S clock */
02118       case RCC_I2SAPBCLKSOURCE_PLLR:
02119         {
02120           /* Configure the PLL division factor R */
02121           /* PLL_VCO Input  = PLL_SOURCE/PLLM */
02122           if((RCC->PLLCFGR & RCC_PLLCFGR_PLLSRC) == RCC_PLLSOURCE_HSE)
02123           {
02124             /* Get the I2S source clock value */
02125             vcoinput = (uint32_t)(HSE_VALUE / (uint32_t)(RCC->PLLCFGR & RCC_PLLCFGR_PLLM));
02126           }
02127           else
02128           {
02129             /* Get the I2S source clock value */
02130             vcoinput = (uint32_t)(HSI_VALUE / (uint32_t)(RCC->PLLCFGR & RCC_PLLCFGR_PLLM));
02131           }
02132 
02133           /* PLL_VCO Output = PLL_VCO Input * PLLN */
02134           vcooutput = (uint32_t)(vcoinput * (((RCC->PLLCFGR & RCC_PLLCFGR_PLLN) >> 6U) & (RCC_PLLCFGR_PLLN >> 6U)));
02135           /* I2S_CLK = PLL_VCO Output/PLLR */
02136           frequency = (uint32_t)(vcooutput /(((RCC->PLLCFGR & RCC_PLLCFGR_PLLR) >> 28U) & (RCC_PLLCFGR_PLLR >> 28U)));
02137           break;
02138         }
02139       /* Check if I2S clock selection is HSI or HSE depending from PLL source Clock */
02140       case RCC_I2SAPBCLKSOURCE_PLLSRC:
02141         {
02142           if((RCC->PLLCFGR & RCC_PLLCFGR_PLLSRC) == RCC_PLLSOURCE_HSE)
02143           {
02144             frequency = HSE_VALUE;
02145           }
02146           else
02147           {
02148             frequency = HSI_VALUE;
02149           }
02150           break;
02151         }
02152         /* Clock not enabled for I2S*/
02153       default:
02154         {
02155           frequency = 0U;
02156           break;
02157         }
02158       }
02159       break;
02160     }
02161   }
02162   return frequency;
02163 }
02164 #endif /* STM32F410Tx || STM32F410Cx || STM32F410Rx */
02165 
02166 #if defined(STM32F427xx) || defined(STM32F437xx) || defined(STM32F429xx) || defined(STM32F439xx)
02167 /**
02168   * @brief  Initializes the RCC extended peripherals clocks according to the specified
02169   *         parameters in the RCC_PeriphCLKInitTypeDef.
02170   * @param  PeriphClkInit pointer to an RCC_PeriphCLKInitTypeDef structure that
02171   *         contains the configuration information for the Extended Peripherals
02172   *         clocks(I2S, SAI, LTDC RTC and TIM).
02173   *
02174   * @note   Care must be taken when HAL_RCCEx_PeriphCLKConfig() is used to select
02175   *         the RTC clock source; in this case the Backup domain will be reset in
02176   *         order to modify the RTC Clock source, as consequence RTC registers (including
02177   *         the backup registers) and RCC_BDCR register are set to their reset values.
02178   *
02179   * @retval HAL status
02180   */
02181 HAL_StatusTypeDef HAL_RCCEx_PeriphCLKConfig(RCC_PeriphCLKInitTypeDef  *PeriphClkInit)
02182 {
02183   uint32_t tickstart = 0U;
02184   uint32_t tmpreg1 = 0U;
02185 
02186   /* Check the parameters */
02187   assert_param(IS_RCC_PERIPHCLOCK(PeriphClkInit->PeriphClockSelection));
02188 
02189   /*----------------------- SAI/I2S Configuration (PLLI2S) -------------------*/
02190   /*----------------------- Common configuration SAI/I2S ---------------------*/
02191   /* In Case of SAI or I2S Clock Configuration through PLLI2S, PLLI2SN division
02192      factor is common parameters for both peripherals */
02193   if((((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_I2S) == RCC_PERIPHCLK_I2S) ||
02194      (((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_SAI_PLLI2S) == RCC_PERIPHCLK_SAI_PLLI2S))
02195   {
02196     /* check for Parameters */
02197     assert_param(IS_RCC_PLLI2SN_VALUE(PeriphClkInit->PLLI2S.PLLI2SN));
02198 
02199     /* Disable the PLLI2S */
02200     __HAL_RCC_PLLI2S_DISABLE();
02201     /* Get tick */
02202     tickstart = HAL_GetTick();
02203     /* Wait till PLLI2S is disabled */
02204     while(__HAL_RCC_GET_FLAG(RCC_FLAG_PLLI2SRDY)  != RESET)
02205     {
02206       if((HAL_GetTick() - tickstart ) > PLLI2S_TIMEOUT_VALUE)
02207       {
02208         /* return in case of Timeout detected */
02209         return HAL_TIMEOUT;
02210       }
02211     }
02212 
02213     /*---------------------------- I2S configuration -------------------------*/
02214     /* In Case of I2S Clock Configuration through PLLI2S, PLLI2SR must be added
02215       only for I2S configuration */
02216     if(((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_I2S) == (RCC_PERIPHCLK_I2S))
02217     {
02218       /* check for Parameters */
02219       assert_param(IS_RCC_PLLI2SR_VALUE(PeriphClkInit->PLLI2S.PLLI2SR));
02220       /* Configure the PLLI2S division factors */
02221       /* PLLI2S_VCO = f(VCO clock) = f(PLLI2S clock input) * (PLLI2SN/PLLM) */
02222       /* I2SCLK = f(PLLI2S clock output) = f(VCO clock) / PLLI2SR */
02223       __HAL_RCC_PLLI2S_CONFIG(PeriphClkInit->PLLI2S.PLLI2SN , PeriphClkInit->PLLI2S.PLLI2SR);
02224     }
02225 
02226     /*---------------------------- SAI configuration -------------------------*/
02227     /* In Case of SAI Clock Configuration through PLLI2S, PLLI2SQ and PLLI2S_DIVQ must
02228        be added only for SAI configuration */
02229     if(((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_SAI_PLLI2S) == (RCC_PERIPHCLK_SAI_PLLI2S))
02230     {
02231       /* Check the PLLI2S division factors */
02232       assert_param(IS_RCC_PLLI2SQ_VALUE(PeriphClkInit->PLLI2S.PLLI2SQ));
02233       assert_param(IS_RCC_PLLI2S_DIVQ_VALUE(PeriphClkInit->PLLI2SDivQ));
02234 
02235       /* Read PLLI2SR value from PLLI2SCFGR register (this value is not need for SAI configuration) */
02236       tmpreg1 = ((RCC->PLLI2SCFGR & RCC_PLLI2SCFGR_PLLI2SR) >> RCC_PLLI2SCFGR_PLLI2SR_Pos);
02237       /* Configure the PLLI2S division factors */
02238       /* PLLI2S_VCO Input  = PLL_SOURCE/PLLM */
02239       /* PLLI2S_VCO Output = PLLI2S_VCO Input * PLLI2SN */
02240       /* SAI_CLK(first level) = PLLI2S_VCO Output/PLLI2SQ */
02241       __HAL_RCC_PLLI2S_SAICLK_CONFIG(PeriphClkInit->PLLI2S.PLLI2SN , PeriphClkInit->PLLI2S.PLLI2SQ , tmpreg1);
02242       /* SAI_CLK_x = SAI_CLK(first level)/PLLI2SDIVQ */
02243       __HAL_RCC_PLLI2S_PLLSAICLKDIVQ_CONFIG(PeriphClkInit->PLLI2SDivQ);
02244     }
02245 
02246     /* Enable the PLLI2S */
02247     __HAL_RCC_PLLI2S_ENABLE();
02248     /* Get tick */
02249     tickstart = HAL_GetTick();
02250     /* Wait till PLLI2S is ready */
02251     while(__HAL_RCC_GET_FLAG(RCC_FLAG_PLLI2SRDY)  == RESET)
02252     {
02253       if((HAL_GetTick() - tickstart ) > PLLI2S_TIMEOUT_VALUE)
02254       {
02255         /* return in case of Timeout detected */
02256         return HAL_TIMEOUT;
02257       }
02258     }
02259   }
02260   /*--------------------------------------------------------------------------*/
02261 
02262   /*----------------------- SAI/LTDC Configuration (PLLSAI) ------------------*/
02263   /*----------------------- Common configuration SAI/LTDC --------------------*/
02264   /* In Case of SAI or LTDC Clock Configuration through PLLSAI, PLLSAIN division
02265      factor is common parameters for both peripherals */
02266   if((((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_SAI_PLLSAI) == RCC_PERIPHCLK_SAI_PLLSAI) ||
02267      (((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_LTDC) == RCC_PERIPHCLK_LTDC))
02268   {
02269     /* Check the PLLSAI division factors */
02270     assert_param(IS_RCC_PLLSAIN_VALUE(PeriphClkInit->PLLSAI.PLLSAIN));
02271 
02272     /* Disable PLLSAI Clock */
02273     __HAL_RCC_PLLSAI_DISABLE();
02274     /* Get tick */
02275     tickstart = HAL_GetTick();
02276     /* Wait till PLLSAI is disabled */
02277     while(__HAL_RCC_PLLSAI_GET_FLAG() != RESET)
02278     {
02279       if((HAL_GetTick() - tickstart ) > PLLSAI_TIMEOUT_VALUE)
02280       {
02281         /* return in case of Timeout detected */
02282         return HAL_TIMEOUT;
02283       }
02284     }
02285 
02286     /*---------------------------- SAI configuration -------------------------*/
02287     /* In Case of SAI Clock Configuration through PLLSAI, PLLSAIQ and PLLSAI_DIVQ must
02288        be added only for SAI configuration */
02289     if(((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_SAI_PLLSAI) == (RCC_PERIPHCLK_SAI_PLLSAI))
02290     {
02291       assert_param(IS_RCC_PLLSAIQ_VALUE(PeriphClkInit->PLLSAI.PLLSAIQ));
02292       assert_param(IS_RCC_PLLSAI_DIVQ_VALUE(PeriphClkInit->PLLSAIDivQ));
02293 
02294       /* Read PLLSAIR value from PLLSAICFGR register (this value is not need for SAI configuration) */
02295       tmpreg1 = ((RCC->PLLSAICFGR & RCC_PLLSAICFGR_PLLSAIR) >> RCC_PLLSAICFGR_PLLSAIR_Pos);
02296       /* PLLSAI_VCO Input  = PLL_SOURCE/PLLM */
02297       /* PLLSAI_VCO Output = PLLSAI_VCO Input * PLLSAIN */
02298       /* SAI_CLK(first level) = PLLSAI_VCO Output/PLLSAIQ */
02299       __HAL_RCC_PLLSAI_CONFIG(PeriphClkInit->PLLSAI.PLLSAIN , PeriphClkInit->PLLSAI.PLLSAIQ, tmpreg1);
02300       /* SAI_CLK_x = SAI_CLK(first level)/PLLSAIDIVQ */
02301       __HAL_RCC_PLLSAI_PLLSAICLKDIVQ_CONFIG(PeriphClkInit->PLLSAIDivQ);
02302     }
02303 
02304     /*---------------------------- LTDC configuration ------------------------*/
02305     if(((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_LTDC) == (RCC_PERIPHCLK_LTDC))
02306     {
02307       assert_param(IS_RCC_PLLSAIR_VALUE(PeriphClkInit->PLLSAI.PLLSAIR));
02308       assert_param(IS_RCC_PLLSAI_DIVR_VALUE(PeriphClkInit->PLLSAIDivR));
02309 
02310       /* Read PLLSAIR value from PLLSAICFGR register (this value is not need for SAI configuration) */
02311       tmpreg1 = ((RCC->PLLSAICFGR & RCC_PLLSAICFGR_PLLSAIQ) >> RCC_PLLSAICFGR_PLLSAIQ_Pos);
02312       /* PLLSAI_VCO Input  = PLL_SOURCE/PLLM */
02313       /* PLLSAI_VCO Output = PLLSAI_VCO Input * PLLSAIN */
02314       /* LTDC_CLK(first level) = PLLSAI_VCO Output/PLLSAIR */
02315       __HAL_RCC_PLLSAI_CONFIG(PeriphClkInit->PLLSAI.PLLSAIN , tmpreg1, PeriphClkInit->PLLSAI.PLLSAIR);
02316       /* LTDC_CLK = LTDC_CLK(first level)/PLLSAIDIVR */
02317       __HAL_RCC_PLLSAI_PLLSAICLKDIVR_CONFIG(PeriphClkInit->PLLSAIDivR);
02318     }
02319     /* Enable PLLSAI Clock */
02320     __HAL_RCC_PLLSAI_ENABLE();
02321     /* Get tick */
02322     tickstart = HAL_GetTick();
02323     /* Wait till PLLSAI is ready */
02324     while(__HAL_RCC_PLLSAI_GET_FLAG() == RESET)
02325     {
02326       if((HAL_GetTick() - tickstart ) > PLLSAI_TIMEOUT_VALUE)
02327       {
02328         /* return in case of Timeout detected */
02329         return HAL_TIMEOUT;
02330       }
02331     }
02332   }
02333   /*--------------------------------------------------------------------------*/
02334 
02335   /*---------------------------- RTC configuration ---------------------------*/
02336   if(((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_RTC) == (RCC_PERIPHCLK_RTC))
02337   {
02338     /* Check for RTC Parameters used to output RTCCLK */
02339     assert_param(IS_RCC_RTCCLKSOURCE(PeriphClkInit->RTCClockSelection));
02340 
02341     /* Enable Power Clock*/
02342     __HAL_RCC_PWR_CLK_ENABLE();
02343 
02344     /* Enable write access to Backup domain */
02345     PWR->CR |= PWR_CR_DBP;
02346 
02347     /* Get tick */
02348     tickstart = HAL_GetTick();
02349 
02350     while((PWR->CR & PWR_CR_DBP) == RESET)
02351     {
02352       if((HAL_GetTick() - tickstart ) > RCC_DBP_TIMEOUT_VALUE)
02353       {
02354         return HAL_TIMEOUT;
02355       }
02356     }
02357     /* Reset the Backup domain only if the RTC Clock source selection is modified from reset value */
02358     tmpreg1 = (RCC->BDCR & RCC_BDCR_RTCSEL);
02359     if((tmpreg1 != 0x00000000U) && ((tmpreg1) != (PeriphClkInit->RTCClockSelection & RCC_BDCR_RTCSEL)))
02360     {
02361       /* Store the content of BDCR register before the reset of Backup Domain */
02362       tmpreg1 = (RCC->BDCR & ~(RCC_BDCR_RTCSEL));
02363       /* RTC Clock selection can be changed only if the Backup Domain is reset */
02364       __HAL_RCC_BACKUPRESET_FORCE();
02365       __HAL_RCC_BACKUPRESET_RELEASE();
02366       /* Restore the Content of BDCR register */
02367       RCC->BDCR = tmpreg1;
02368 
02369       /* Wait for LSE reactivation if LSE was enable prior to Backup Domain reset */
02370       if(HAL_IS_BIT_SET(RCC->BDCR, RCC_BDCR_LSEON))
02371       {
02372         /* Get tick */
02373         tickstart = HAL_GetTick();
02374 
02375         /* Wait till LSE is ready */
02376         while(__HAL_RCC_GET_FLAG(RCC_FLAG_LSERDY) == RESET)
02377         {
02378           if((HAL_GetTick() - tickstart ) > RCC_LSE_TIMEOUT_VALUE)
02379           {
02380             return HAL_TIMEOUT;
02381           }
02382         }
02383       }
02384     }
02385     __HAL_RCC_RTC_CONFIG(PeriphClkInit->RTCClockSelection);
02386   }
02387   /*--------------------------------------------------------------------------*/
02388 
02389   /*---------------------------- TIM configuration ---------------------------*/
02390   if(((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_TIM) == (RCC_PERIPHCLK_TIM))
02391   {
02392     __HAL_RCC_TIMCLKPRESCALER(PeriphClkInit->TIMPresSelection);
02393   }
02394   return HAL_OK;
02395 }
02396 
02397 /**
02398   * @brief  Configures the PeriphClkInit according to the internal
02399   * RCC configuration registers.
02400   * @param  PeriphClkInit pointer to an RCC_PeriphCLKInitTypeDef structure that
02401   *         will be configured.
02402   * @retval None
02403   */
02404 void HAL_RCCEx_GetPeriphCLKConfig(RCC_PeriphCLKInitTypeDef  *PeriphClkInit)
02405 {
02406   uint32_t tempreg;
02407 
02408   /* Set all possible values for the extended clock type parameter------------*/
02409   PeriphClkInit->PeriphClockSelection = RCC_PERIPHCLK_I2S | RCC_PERIPHCLK_SAI_PLLSAI | RCC_PERIPHCLK_SAI_PLLI2S | RCC_PERIPHCLK_LTDC | RCC_PERIPHCLK_TIM | RCC_PERIPHCLK_RTC;
02410 
02411   /* Get the PLLI2S Clock configuration -----------------------------------------------*/
02412   PeriphClkInit->PLLI2S.PLLI2SN = (uint32_t)((RCC->PLLI2SCFGR & RCC_PLLI2SCFGR_PLLI2SN) >> RCC_PLLI2SCFGR_PLLI2SN_Pos);
02413   PeriphClkInit->PLLI2S.PLLI2SR = (uint32_t)((RCC->PLLI2SCFGR & RCC_PLLI2SCFGR_PLLI2SR) >> RCC_PLLI2SCFGR_PLLI2SR_Pos);
02414   PeriphClkInit->PLLI2S.PLLI2SQ = (uint32_t)((RCC->PLLI2SCFGR & RCC_PLLI2SCFGR_PLLI2SQ) >> RCC_PLLI2SCFGR_PLLI2SQ_Pos);
02415   /* Get the PLLSAI Clock configuration -----------------------------------------------*/
02416   PeriphClkInit->PLLSAI.PLLSAIN = (uint32_t)((RCC->PLLSAICFGR & RCC_PLLSAICFGR_PLLSAIN) >> RCC_PLLSAICFGR_PLLSAIN_Pos);
02417   PeriphClkInit->PLLSAI.PLLSAIR = (uint32_t)((RCC->PLLSAICFGR & RCC_PLLSAICFGR_PLLSAIR) >> RCC_PLLSAICFGR_PLLSAIR_Pos);
02418   PeriphClkInit->PLLSAI.PLLSAIQ = (uint32_t)((RCC->PLLSAICFGR & RCC_PLLSAICFGR_PLLSAIQ) >> RCC_PLLSAICFGR_PLLSAIQ_Pos);
02419   /* Get the PLLSAI/PLLI2S division factors -----------------------------------------------*/
02420   PeriphClkInit->PLLI2SDivQ = (uint32_t)((RCC->DCKCFGR & RCC_DCKCFGR_PLLI2SDIVQ) >> RCC_DCKCFGR_PLLI2SDIVQ_Pos);
02421   PeriphClkInit->PLLSAIDivQ = (uint32_t)((RCC->DCKCFGR & RCC_DCKCFGR_PLLSAIDIVQ) >> RCC_DCKCFGR_PLLSAIDIVQ_Pos);
02422   PeriphClkInit->PLLSAIDivR = (uint32_t)(RCC->DCKCFGR & RCC_DCKCFGR_PLLSAIDIVR);
02423   /* Get the RTC Clock configuration -----------------------------------------------*/
02424   tempreg = (RCC->CFGR & RCC_CFGR_RTCPRE);
02425   PeriphClkInit->RTCClockSelection = (uint32_t)((tempreg) | (RCC->BDCR & RCC_BDCR_RTCSEL));
02426 
02427   if ((RCC->DCKCFGR & RCC_DCKCFGR_TIMPRE) == RESET)
02428   {
02429     PeriphClkInit->TIMPresSelection = RCC_TIMPRES_DESACTIVATED;
02430   }
02431   else
02432   {
02433     PeriphClkInit->TIMPresSelection = RCC_TIMPRES_ACTIVATED;
02434   }
02435 }
02436 
02437 /**
02438   * @brief  Return the peripheral clock frequency for a given peripheral(SAI..)
02439   * @note   Return 0 if peripheral clock identifier not managed by this API
02440   * @param  PeriphClk Peripheral clock identifier
02441   *         This parameter can be one of the following values:
02442   *            @arg RCC_PERIPHCLK_I2S: I2S peripheral clock
02443   * @retval Frequency in KHz
02444   */
02445 uint32_t HAL_RCCEx_GetPeriphCLKFreq(uint32_t PeriphClk)
02446 {
02447   /* This variable used to store the I2S clock frequency (value in Hz) */
02448   uint32_t frequency = 0U;
02449   /* This variable used to store the VCO Input (value in Hz) */
02450   uint32_t vcoinput = 0U;
02451   uint32_t srcclk = 0U;
02452   /* This variable used to store the VCO Output (value in Hz) */
02453   uint32_t vcooutput = 0U;
02454   switch (PeriphClk)
02455   {
02456   case RCC_PERIPHCLK_I2S:
02457     {
02458       /* Get the current I2S source */
02459       srcclk = __HAL_RCC_GET_I2S_SOURCE();
02460       switch (srcclk)
02461       {
02462       /* Check if I2S clock selection is External clock mapped on the I2S_CKIN pin used as I2S clock */
02463       case RCC_I2SCLKSOURCE_EXT:
02464         {
02465           /* Set the I2S clock to the external clock  value */
02466           frequency = EXTERNAL_CLOCK_VALUE;
02467           break;
02468         }
02469       /* Check if I2S clock selection is PLLI2S VCO output clock divided by PLLI2SR used as I2S clock */
02470       case RCC_I2SCLKSOURCE_PLLI2S:
02471         {
02472           /* Configure the PLLI2S division factor */
02473           /* PLLI2S_VCO Input  = PLL_SOURCE/PLLM */
02474           if((RCC->PLLCFGR & RCC_PLLCFGR_PLLSRC) == RCC_PLLSOURCE_HSE)
02475           {
02476             /* Get the I2S source clock value */
02477             vcoinput = (uint32_t)(HSE_VALUE / (uint32_t)(RCC->PLLCFGR & RCC_PLLCFGR_PLLM));
02478           }
02479           else
02480           {
02481             /* Get the I2S source clock value */
02482             vcoinput = (uint32_t)(HSI_VALUE / (uint32_t)(RCC->PLLCFGR & RCC_PLLCFGR_PLLM));
02483           }
02484 
02485           /* PLLI2S_VCO Output = PLLI2S_VCO Input * PLLI2SN */
02486           vcooutput = (uint32_t)(vcoinput * (((RCC->PLLI2SCFGR & RCC_PLLI2SCFGR_PLLI2SN) >> 6U) & (RCC_PLLI2SCFGR_PLLI2SN >> 6U)));
02487           /* I2S_CLK = PLLI2S_VCO Output/PLLI2SR */
02488           frequency = (uint32_t)(vcooutput /(((RCC->PLLI2SCFGR & RCC_PLLI2SCFGR_PLLI2SR) >> 28U) & (RCC_PLLI2SCFGR_PLLI2SR >> 28U)));
02489           break;
02490         }
02491         /* Clock not enabled for I2S */
02492       default:
02493         {
02494           frequency = 0U;
02495           break;
02496         }
02497       }
02498       break;
02499     }
02500   }
02501   return frequency;
02502 }
02503 #endif /* STM32F427xx || STM32F437xx || STM32F429xx || STM32F439xx */
02504 
02505 #if defined(STM32F405xx) || defined(STM32F415xx) || defined(STM32F407xx)|| defined(STM32F417xx) ||\
02506     defined(STM32F401xC) || defined(STM32F401xE) || defined(STM32F411xE)
02507 /**
02508   * @brief  Initializes the RCC extended peripherals clocks according to the specified parameters in the
02509   *         RCC_PeriphCLKInitTypeDef.
02510   * @param  PeriphClkInit pointer to an RCC_PeriphCLKInitTypeDef structure that
02511   *         contains the configuration information for the Extended Peripherals clocks(I2S and RTC clocks).
02512   *
02513   * @note   A caution to be taken when HAL_RCCEx_PeriphCLKConfig() is used to select RTC clock selection, in this case
02514   *         the Reset of Backup domain will be applied in order to modify the RTC Clock source as consequence all backup
02515   *        domain (RTC and RCC_BDCR register expect BKPSRAM) will be reset
02516   *
02517   * @retval HAL status
02518   */
02519 HAL_StatusTypeDef HAL_RCCEx_PeriphCLKConfig(RCC_PeriphCLKInitTypeDef  *PeriphClkInit)
02520 {
02521   uint32_t tickstart = 0U;
02522   uint32_t tmpreg1 = 0U;
02523 
02524   /* Check the parameters */
02525   assert_param(IS_RCC_PERIPHCLOCK(PeriphClkInit->PeriphClockSelection));
02526 
02527   /*---------------------------- I2S configuration ---------------------------*/
02528   if((((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_I2S) == RCC_PERIPHCLK_I2S) ||
02529      (((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_PLLI2S) == RCC_PERIPHCLK_PLLI2S))
02530   {
02531     /* check for Parameters */
02532     assert_param(IS_RCC_PLLI2SR_VALUE(PeriphClkInit->PLLI2S.PLLI2SR));
02533     assert_param(IS_RCC_PLLI2SN_VALUE(PeriphClkInit->PLLI2S.PLLI2SN));
02534 #if defined(STM32F411xE)
02535     assert_param(IS_RCC_PLLI2SM_VALUE(PeriphClkInit->PLLI2S.PLLI2SM));
02536 #endif /* STM32F411xE */
02537     /* Disable the PLLI2S */
02538     __HAL_RCC_PLLI2S_DISABLE();
02539     /* Get tick */
02540     tickstart = HAL_GetTick();
02541     /* Wait till PLLI2S is disabled */
02542     while(__HAL_RCC_GET_FLAG(RCC_FLAG_PLLI2SRDY)  != RESET)
02543     {
02544       if((HAL_GetTick() - tickstart ) > PLLI2S_TIMEOUT_VALUE)
02545       {
02546         /* return in case of Timeout detected */
02547         return HAL_TIMEOUT;
02548       }
02549     }
02550 
02551 #if defined(STM32F411xE)
02552     /* Configure the PLLI2S division factors */
02553     /* PLLI2S_VCO = f(VCO clock) = f(PLLI2S clock input) * (PLLI2SN/PLLI2SM) */
02554     /* I2SCLK = f(PLLI2S clock output) = f(VCO clock) / PLLI2SR */
02555     __HAL_RCC_PLLI2S_I2SCLK_CONFIG(PeriphClkInit->PLLI2S.PLLI2SM, PeriphClkInit->PLLI2S.PLLI2SN, PeriphClkInit->PLLI2S.PLLI2SR);
02556 #else
02557     /* Configure the PLLI2S division factors */
02558     /* PLLI2S_VCO = f(VCO clock) = f(PLLI2S clock input) * (PLLI2SN/PLLM) */
02559     /* I2SCLK = f(PLLI2S clock output) = f(VCO clock) / PLLI2SR */
02560     __HAL_RCC_PLLI2S_CONFIG(PeriphClkInit->PLLI2S.PLLI2SN , PeriphClkInit->PLLI2S.PLLI2SR);
02561 #endif /* STM32F411xE */
02562 
02563     /* Enable the PLLI2S */
02564     __HAL_RCC_PLLI2S_ENABLE();
02565     /* Get tick */
02566     tickstart = HAL_GetTick();
02567     /* Wait till PLLI2S is ready */
02568     while(__HAL_RCC_GET_FLAG(RCC_FLAG_PLLI2SRDY)  == RESET)
02569     {
02570       if((HAL_GetTick() - tickstart ) > PLLI2S_TIMEOUT_VALUE)
02571       {
02572         /* return in case of Timeout detected */
02573         return HAL_TIMEOUT;
02574       }
02575     }
02576   }
02577 
02578   /*---------------------------- RTC configuration ---------------------------*/
02579   if(((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_RTC) == (RCC_PERIPHCLK_RTC))
02580   {
02581     /* Check for RTC Parameters used to output RTCCLK */
02582     assert_param(IS_RCC_RTCCLKSOURCE(PeriphClkInit->RTCClockSelection));
02583 
02584     /* Enable Power Clock*/
02585     __HAL_RCC_PWR_CLK_ENABLE();
02586 
02587     /* Enable write access to Backup domain */
02588     PWR->CR |= PWR_CR_DBP;
02589 
02590     /* Get tick */
02591     tickstart = HAL_GetTick();
02592 
02593     while((PWR->CR & PWR_CR_DBP) == RESET)
02594     {
02595       if((HAL_GetTick() - tickstart ) > RCC_DBP_TIMEOUT_VALUE)
02596       {
02597         return HAL_TIMEOUT;
02598       }
02599     }
02600     /* Reset the Backup domain only if the RTC Clock source selection is modified from reset value */
02601     tmpreg1 = (RCC->BDCR & RCC_BDCR_RTCSEL);
02602     if((tmpreg1 != 0x00000000U) && ((tmpreg1) != (PeriphClkInit->RTCClockSelection & RCC_BDCR_RTCSEL)))
02603     {
02604       /* Store the content of BDCR register before the reset of Backup Domain */
02605       tmpreg1 = (RCC->BDCR & ~(RCC_BDCR_RTCSEL));
02606       /* RTC Clock selection can be changed only if the Backup Domain is reset */
02607       __HAL_RCC_BACKUPRESET_FORCE();
02608       __HAL_RCC_BACKUPRESET_RELEASE();
02609       /* Restore the Content of BDCR register */
02610       RCC->BDCR = tmpreg1;
02611 
02612       /* Wait for LSE reactivation if LSE was enable prior to Backup Domain reset */
02613       if(HAL_IS_BIT_SET(RCC->BDCR, RCC_BDCR_LSEON))
02614       {
02615         /* Get tick */
02616         tickstart = HAL_GetTick();
02617 
02618         /* Wait till LSE is ready */
02619         while(__HAL_RCC_GET_FLAG(RCC_FLAG_LSERDY) == RESET)
02620         {
02621           if((HAL_GetTick() - tickstart ) > RCC_LSE_TIMEOUT_VALUE)
02622           {
02623             return HAL_TIMEOUT;
02624           }
02625         }
02626       }
02627     }
02628     __HAL_RCC_RTC_CONFIG(PeriphClkInit->RTCClockSelection);
02629   }
02630 #if defined(STM32F401xC) || defined(STM32F401xE) || defined(STM32F411xE)
02631   /*---------------------------- TIM configuration ---------------------------*/
02632   if(((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_TIM) == (RCC_PERIPHCLK_TIM))
02633   {
02634     __HAL_RCC_TIMCLKPRESCALER(PeriphClkInit->TIMPresSelection);
02635   }
02636 #endif /* STM32F401xC || STM32F401xE || STM32F411xE */
02637   return HAL_OK;
02638 }
02639 
02640 /**
02641   * @brief  Configures the RCC_OscInitStruct according to the internal
02642   * RCC configuration registers.
02643   * @param  PeriphClkInit pointer to an RCC_PeriphCLKInitTypeDef structure that
02644   * will be configured.
02645   * @retval None
02646   */
02647 void HAL_RCCEx_GetPeriphCLKConfig(RCC_PeriphCLKInitTypeDef  *PeriphClkInit)
02648 {
02649   uint32_t tempreg;
02650 
02651   /* Set all possible values for the extended clock type parameter------------*/
02652   PeriphClkInit->PeriphClockSelection = RCC_PERIPHCLK_I2S | RCC_PERIPHCLK_RTC;
02653 
02654   /* Get the PLLI2S Clock configuration --------------------------------------*/
02655   PeriphClkInit->PLLI2S.PLLI2SN = (uint32_t)((RCC->PLLI2SCFGR & RCC_PLLI2SCFGR_PLLI2SN) >> RCC_PLLI2SCFGR_PLLI2SN_Pos);
02656   PeriphClkInit->PLLI2S.PLLI2SR = (uint32_t)((RCC->PLLI2SCFGR & RCC_PLLI2SCFGR_PLLI2SR) >> RCC_PLLI2SCFGR_PLLI2SR_Pos);
02657 #if defined(STM32F411xE)
02658   PeriphClkInit->PLLI2S.PLLI2SM = (uint32_t)(RCC->PLLI2SCFGR & RCC_PLLI2SCFGR_PLLI2SM);
02659 #endif /* STM32F411xE */
02660   /* Get the RTC Clock configuration -----------------------------------------*/
02661   tempreg = (RCC->CFGR & RCC_CFGR_RTCPRE);
02662   PeriphClkInit->RTCClockSelection = (uint32_t)((tempreg) | (RCC->BDCR & RCC_BDCR_RTCSEL));
02663 
02664 #if defined(STM32F401xC) || defined(STM32F401xE) || defined(STM32F411xE)
02665   /* Get the TIM Prescaler configuration -------------------------------------*/
02666   if ((RCC->DCKCFGR & RCC_DCKCFGR_TIMPRE) == RESET)
02667   {
02668     PeriphClkInit->TIMPresSelection = RCC_TIMPRES_DESACTIVATED;
02669   }
02670   else
02671   {
02672     PeriphClkInit->TIMPresSelection = RCC_TIMPRES_ACTIVATED;
02673   }
02674 #endif /* STM32F401xC || STM32F401xE || STM32F411xE */
02675 }
02676 
02677 /**
02678   * @brief  Return the peripheral clock frequency for a given peripheral(SAI..)
02679   * @note   Return 0 if peripheral clock identifier not managed by this API
02680   * @param  PeriphClk Peripheral clock identifier
02681   *         This parameter can be one of the following values:
02682   *            @arg RCC_PERIPHCLK_I2S: I2S peripheral clock
02683   * @retval Frequency in KHz
02684   */
02685 uint32_t HAL_RCCEx_GetPeriphCLKFreq(uint32_t PeriphClk)
02686 {
02687   /* This variable used to store the I2S clock frequency (value in Hz) */
02688   uint32_t frequency = 0U;
02689   /* This variable used to store the VCO Input (value in Hz) */
02690   uint32_t vcoinput = 0U;
02691   uint32_t srcclk = 0U;
02692   /* This variable used to store the VCO Output (value in Hz) */
02693   uint32_t vcooutput = 0U;
02694   switch (PeriphClk)
02695   {
02696   case RCC_PERIPHCLK_I2S:
02697     {
02698       /* Get the current I2S source */
02699       srcclk = __HAL_RCC_GET_I2S_SOURCE();
02700       switch (srcclk)
02701       {
02702       /* Check if I2S clock selection is External clock mapped on the I2S_CKIN pin used as I2S clock */
02703       case RCC_I2SCLKSOURCE_EXT:
02704         {
02705           /* Set the I2S clock to the external clock  value */
02706           frequency = EXTERNAL_CLOCK_VALUE;
02707           break;
02708         }
02709       /* Check if I2S clock selection is PLLI2S VCO output clock divided by PLLI2SR used as I2S clock */
02710       case RCC_I2SCLKSOURCE_PLLI2S:
02711         {
02712 #if defined(STM32F411xE)
02713           /* Configure the PLLI2S division factor */
02714           /* PLLI2S_VCO Input  = PLL_SOURCE/PLLI2SM */
02715           if((RCC->PLLCFGR & RCC_PLLCFGR_PLLSRC) == RCC_PLLSOURCE_HSE)
02716           {
02717             /* Get the I2S source clock value */
02718             vcoinput = (uint32_t)(HSE_VALUE / (uint32_t)(RCC->PLLI2SCFGR & RCC_PLLI2SCFGR_PLLI2SM));
02719           }
02720           else
02721           {
02722             /* Get the I2S source clock value */
02723             vcoinput = (uint32_t)(HSI_VALUE / (uint32_t)(RCC->PLLI2SCFGR & RCC_PLLI2SCFGR_PLLI2SM));
02724           }
02725 #else
02726           /* Configure the PLLI2S division factor */
02727           /* PLLI2S_VCO Input  = PLL_SOURCE/PLLM */
02728           if((RCC->PLLCFGR & RCC_PLLCFGR_PLLSRC) == RCC_PLLSOURCE_HSE)
02729           {
02730             /* Get the I2S source clock value */
02731             vcoinput = (uint32_t)(HSE_VALUE / (uint32_t)(RCC->PLLCFGR & RCC_PLLCFGR_PLLM));
02732           }
02733           else
02734           {
02735             /* Get the I2S source clock value */
02736             vcoinput = (uint32_t)(HSI_VALUE / (uint32_t)(RCC->PLLCFGR & RCC_PLLCFGR_PLLM));
02737           }
02738 #endif /* STM32F411xE */
02739           /* PLLI2S_VCO Output = PLLI2S_VCO Input * PLLI2SN */
02740           vcooutput = (uint32_t)(vcoinput * (((RCC->PLLI2SCFGR & RCC_PLLI2SCFGR_PLLI2SN) >> 6U) & (RCC_PLLI2SCFGR_PLLI2SN >> 6U)));
02741           /* I2S_CLK = PLLI2S_VCO Output/PLLI2SR */
02742           frequency = (uint32_t)(vcooutput /(((RCC->PLLI2SCFGR & RCC_PLLI2SCFGR_PLLI2SR) >> 28U) & (RCC_PLLI2SCFGR_PLLI2SR >> 28U)));
02743           break;
02744         }
02745         /* Clock not enabled for I2S*/
02746       default:
02747         {
02748           frequency = 0U;
02749           break;
02750         }
02751       }
02752       break;
02753     }
02754   }
02755   return frequency;
02756 }
02757 #endif /* STM32F405xx || STM32F415xx || STM32F407xx || STM32F417xx || STM32F401xC || STM32F401xE  || STM32F411xE */
02758 
02759 #if defined(STM32F410Tx) || defined(STM32F410Cx) || defined(STM32F410Rx) || defined(STM32F411xE) || defined(STM32F446xx) || defined(STM32F469xx) || defined(STM32F479xx) || defined(STM32F412Zx) ||\
02760     defined(STM32F412Vx) || defined(STM32F412Rx) || defined(STM32F412Cx) || defined(STM32F413xx) || defined(STM32F423xx)
02761 /**
02762   * @brief  Select LSE mode
02763   *
02764   * @note   This mode is only available for STM32F410xx/STM32F411xx/STM32F446xx/STM32F469xx/STM32F479xx/STM32F412Zx/STM32F412Vx/STM32F412Rx/STM32F412Cx  devices.
02765   *
02766   * @param  Mode specifies the LSE mode.
02767   *          This parameter can be one of the following values:
02768   *            @arg RCC_LSE_LOWPOWER_MODE:  LSE oscillator in low power mode selection
02769   *            @arg RCC_LSE_HIGHDRIVE_MODE: LSE oscillator in High Drive mode selection
02770   * @retval None
02771   */
02772 void HAL_RCCEx_SelectLSEMode(uint8_t Mode)
02773 {
02774   /* Check the parameters */
02775   assert_param(IS_RCC_LSE_MODE(Mode));
02776   if(Mode == RCC_LSE_HIGHDRIVE_MODE)
02777   {
02778     SET_BIT(RCC->BDCR, RCC_BDCR_LSEMOD);
02779   }
02780   else
02781   {
02782     CLEAR_BIT(RCC->BDCR, RCC_BDCR_LSEMOD);
02783   }
02784 }
02785 
02786 #endif /* STM32F410xx || STM32F411xE || STM32F446xx || STM32F469xx || STM32F479xx || STM32F412Zx || STM32F412Vx || STM32F412Rx || STM32F412Cx || STM32F413xx || STM32F423xx */
02787 
02788 /** @defgroup RCCEx_Exported_Functions_Group2 Extended Clock management functions
02789  *  @brief  Extended Clock management functions
02790  *
02791 @verbatim   
02792  ===============================================================================
02793                 ##### Extended clock management functions  #####
02794  ===============================================================================
02795     [..]
02796     This subsection provides a set of functions allowing to control the 
02797     activation or deactivation of PLLI2S, PLLSAI.
02798 @endverbatim
02799   * @{
02800   */
02801 
02802 #if defined(RCC_PLLI2S_SUPPORT)
02803 /**
02804   * @brief  Enable PLLI2S.
02805   * @param  PLLI2SInit  pointer to an RCC_PLLI2SInitTypeDef structure that
02806   *         contains the configuration information for the PLLI2S
02807   * @retval HAL status
02808   */
02809 HAL_StatusTypeDef HAL_RCCEx_EnablePLLI2S(RCC_PLLI2SInitTypeDef  *PLLI2SInit)
02810 {
02811   uint32_t tickstart;
02812 
02813   /* Check for parameters */
02814   assert_param(IS_RCC_PLLI2SN_VALUE(PLLI2SInit->PLLI2SN));
02815   assert_param(IS_RCC_PLLI2SR_VALUE(PLLI2SInit->PLLI2SR));
02816 #if defined(RCC_PLLI2SCFGR_PLLI2SM)
02817   assert_param(IS_RCC_PLLI2SM_VALUE(PLLI2SInit->PLLI2SM));
02818 #endif /* RCC_PLLI2SCFGR_PLLI2SM */
02819 #if defined(RCC_PLLI2SCFGR_PLLI2SP)
02820   assert_param(IS_RCC_PLLI2SP_VALUE(PLLI2SInit->PLLI2SP));
02821 #endif /* RCC_PLLI2SCFGR_PLLI2SP */
02822 #if defined(RCC_PLLI2SCFGR_PLLI2SQ)
02823   assert_param(IS_RCC_PLLI2SQ_VALUE(PLLI2SInit->PLLI2SQ));
02824 #endif /* RCC_PLLI2SCFGR_PLLI2SQ */
02825 
02826   /* Disable the PLLI2S */
02827   __HAL_RCC_PLLI2S_DISABLE();
02828 
02829   /* Wait till PLLI2S is disabled */
02830   tickstart = HAL_GetTick();
02831   while(__HAL_RCC_GET_FLAG(RCC_FLAG_PLLI2SRDY) != RESET)
02832   {
02833     if((HAL_GetTick() - tickstart ) > PLLI2S_TIMEOUT_VALUE)
02834     {
02835       /* return in case of Timeout detected */
02836       return HAL_TIMEOUT;
02837     }
02838   }
02839 
02840   /* Configure the PLLI2S division factors */
02841 #if defined(STM32F446xx)
02842   /* PLLI2S_VCO = f(VCO clock) = f(PLLI2S clock input) * (PLLI2SN/PLLI2SM) */
02843   /* I2SPCLK = PLLI2S_VCO / PLLI2SP */
02844   /* I2SQCLK = PLLI2S_VCO / PLLI2SQ */
02845   /* I2SRCLK = PLLI2S_VCO / PLLI2SR */
02846   __HAL_RCC_PLLI2S_CONFIG(PLLI2SInit->PLLI2SM, PLLI2SInit->PLLI2SN, \
02847                           PLLI2SInit->PLLI2SP, PLLI2SInit->PLLI2SQ, PLLI2SInit->PLLI2SR);
02848 #elif defined(STM32F412Zx) || defined(STM32F412Vx) || defined(STM32F412Rx) || defined(STM32F412Cx) ||\
02849       defined(STM32F413xx) || defined(STM32F423xx)
02850   /* PLLI2S_VCO = f(VCO clock) = f(PLLI2S clock input) * (PLLI2SN/PLLI2SM)*/
02851   /* I2SQCLK = PLLI2S_VCO / PLLI2SQ */
02852   /* I2SRCLK = PLLI2S_VCO / PLLI2SR */
02853   __HAL_RCC_PLLI2S_CONFIG(PLLI2SInit->PLLI2SM, PLLI2SInit->PLLI2SN, \
02854                           PLLI2SInit->PLLI2SQ, PLLI2SInit->PLLI2SR);
02855 #elif defined(STM32F427xx) || defined(STM32F437xx) || defined(STM32F429xx) || defined(STM32F439xx) ||\
02856       defined(STM32F469xx) || defined(STM32F479xx)
02857   /* PLLI2S_VCO = f(VCO clock) = f(PLLI2S clock input) * PLLI2SN */
02858   /* I2SQCLK = PLLI2S_VCO / PLLI2SQ */
02859   /* I2SRCLK = PLLI2S_VCO / PLLI2SR */
02860   __HAL_RCC_PLLI2S_SAICLK_CONFIG(PLLI2SInit->PLLI2SN, PLLI2SInit->PLLI2SQ, PLLI2SInit->PLLI2SR);
02861 #elif defined(STM32F411xE)
02862   /* PLLI2S_VCO = f(VCO clock) = f(PLLI2S clock input) * (PLLI2SN/PLLI2SM) */
02863   /* I2SRCLK = PLLI2S_VCO / PLLI2SR */
02864   __HAL_RCC_PLLI2S_I2SCLK_CONFIG(PLLI2SInit->PLLI2SM, PLLI2SInit->PLLI2SN, PLLI2SInit->PLLI2SR);
02865 #else
02866   /* PLLI2S_VCO = f(VCO clock) = f(PLLI2S clock input) x PLLI2SN */
02867   /* I2SRCLK = PLLI2S_VCO / PLLI2SR */
02868   __HAL_RCC_PLLI2S_CONFIG(PLLI2SInit->PLLI2SN, PLLI2SInit->PLLI2SR);
02869 #endif /* STM32F446xx */
02870 
02871   /* Enable the PLLI2S */
02872   __HAL_RCC_PLLI2S_ENABLE();
02873 
02874   /* Wait till PLLI2S is ready */
02875   tickstart = HAL_GetTick();
02876   while(__HAL_RCC_GET_FLAG(RCC_FLAG_PLLI2SRDY) == RESET)
02877   {
02878     if((HAL_GetTick() - tickstart ) > PLLI2S_TIMEOUT_VALUE)
02879     {
02880       /* return in case of Timeout detected */
02881       return HAL_TIMEOUT;
02882     }
02883   }
02884 
02885  return HAL_OK;
02886 }
02887 
02888 /**
02889   * @brief  Disable PLLI2S.
02890   * @retval HAL status
02891   */
02892 HAL_StatusTypeDef HAL_RCCEx_DisablePLLI2S(void)
02893 {
02894   uint32_t tickstart;
02895 
02896   /* Disable the PLLI2S */
02897   __HAL_RCC_PLLI2S_DISABLE();
02898 
02899   /* Wait till PLLI2S is disabled */
02900   tickstart = HAL_GetTick();
02901   while(READ_BIT(RCC->CR, RCC_CR_PLLI2SRDY) != RESET)
02902   {
02903     if((HAL_GetTick() - tickstart) > PLLI2S_TIMEOUT_VALUE)
02904     {
02905       /* return in case of Timeout detected */
02906       return HAL_TIMEOUT;
02907     }
02908   }
02909 
02910   return HAL_OK;
02911 }
02912 
02913 #endif /* RCC_PLLI2S_SUPPORT */
02914 
02915 #if defined(RCC_PLLSAI_SUPPORT)
02916 /**
02917   * @brief  Enable PLLSAI.
02918   * @param  PLLSAIInit  pointer to an RCC_PLLSAIInitTypeDef structure that
02919   *         contains the configuration information for the PLLSAI
02920   * @retval HAL status
02921   */
02922 HAL_StatusTypeDef HAL_RCCEx_EnablePLLSAI(RCC_PLLSAIInitTypeDef  *PLLSAIInit)
02923 {
02924   uint32_t tickstart;
02925 
02926   /* Check for parameters */
02927   assert_param(IS_RCC_PLLSAIN_VALUE(PLLSAIInit->PLLSAIN));
02928   assert_param(IS_RCC_PLLSAIQ_VALUE(PLLSAIInit->PLLSAIQ));
02929 #if defined(RCC_PLLSAICFGR_PLLSAIM)
02930   assert_param(IS_RCC_PLLSAIM_VALUE(PLLSAIInit->PLLSAIM));
02931 #endif /* RCC_PLLSAICFGR_PLLSAIM */
02932 #if defined(RCC_PLLSAICFGR_PLLSAIP)
02933   assert_param(IS_RCC_PLLSAIP_VALUE(PLLSAIInit->PLLSAIP));
02934 #endif /* RCC_PLLSAICFGR_PLLSAIP */
02935 #if defined(RCC_PLLSAICFGR_PLLSAIR)
02936   assert_param(IS_RCC_PLLSAIR_VALUE(PLLSAIInit->PLLSAIR));
02937 #endif /* RCC_PLLSAICFGR_PLLSAIR */
02938 
02939   /* Disable the PLLSAI */
02940   __HAL_RCC_PLLSAI_DISABLE();
02941 
02942   /* Wait till PLLSAI is disabled */
02943   tickstart = HAL_GetTick();
02944   while(__HAL_RCC_PLLSAI_GET_FLAG() != RESET)
02945   {
02946     if((HAL_GetTick() - tickstart ) > PLLSAI_TIMEOUT_VALUE)
02947     {
02948       /* return in case of Timeout detected */
02949       return HAL_TIMEOUT;
02950     }
02951   }
02952 
02953   /* Configure the PLLSAI division factors */
02954 #if defined(STM32F446xx)
02955   /* PLLSAI_VCO = f(VCO clock) = f(PLLSAI clock input) * (PLLSAIN/PLLSAIM) */
02956   /* SAIPCLK = PLLSAI_VCO / PLLSAIP */
02957   /* SAIQCLK = PLLSAI_VCO / PLLSAIQ */
02958   /* SAIRCLK = PLLSAI_VCO / PLLSAIR */
02959   __HAL_RCC_PLLSAI_CONFIG(PLLSAIInit->PLLSAIM, PLLSAIInit->PLLSAIN, \
02960                           PLLSAIInit->PLLSAIP, PLLSAIInit->PLLSAIQ, 0U);
02961 #elif defined(STM32F469xx) || defined(STM32F479xx)
02962   /* PLLSAI_VCO = f(VCO clock) = f(PLLSAI clock input) * PLLSAIN */
02963   /* SAIPCLK = PLLSAI_VCO / PLLSAIP */
02964   /* SAIQCLK = PLLSAI_VCO / PLLSAIQ */
02965   /* SAIRCLK = PLLSAI_VCO / PLLSAIR */
02966   __HAL_RCC_PLLSAI_CONFIG(PLLSAIInit->PLLSAIN, PLLSAIInit->PLLSAIP, \
02967                           PLLSAIInit->PLLSAIQ, PLLSAIInit->PLLSAIR);
02968 #else
02969   /* PLLSAI_VCO = f(VCO clock) = f(PLLSAI clock input) x PLLSAIN */
02970   /* SAIQCLK = PLLSAI_VCO / PLLSAIQ */
02971   /* SAIRCLK = PLLSAI_VCO / PLLSAIR */
02972   __HAL_RCC_PLLSAI_CONFIG(PLLSAIInit->PLLSAIN, PLLSAIInit->PLLSAIQ, PLLSAIInit->PLLSAIR);
02973 #endif /* STM32F446xx */
02974 
02975   /* Enable the PLLSAI */
02976   __HAL_RCC_PLLSAI_ENABLE();
02977 
02978   /* Wait till PLLSAI is ready */
02979   tickstart = HAL_GetTick();
02980   while(__HAL_RCC_PLLSAI_GET_FLAG() == RESET)
02981   {
02982     if((HAL_GetTick() - tickstart ) > PLLSAI_TIMEOUT_VALUE)
02983     {
02984       /* return in case of Timeout detected */
02985       return HAL_TIMEOUT;
02986     }
02987   }
02988 
02989  return HAL_OK;
02990 }
02991 
02992 /**
02993   * @brief  Disable PLLSAI.
02994   * @retval HAL status
02995   */
02996 HAL_StatusTypeDef HAL_RCCEx_DisablePLLSAI(void)
02997 {
02998   uint32_t tickstart;
02999 
03000   /* Disable the PLLSAI */
03001   __HAL_RCC_PLLSAI_DISABLE();
03002 
03003   /* Wait till PLLSAI is disabled */
03004   tickstart = HAL_GetTick();
03005   while(__HAL_RCC_PLLSAI_GET_FLAG() != RESET)
03006   {
03007     if((HAL_GetTick() - tickstart) > PLLSAI_TIMEOUT_VALUE)
03008     {
03009       /* return in case of Timeout detected */
03010       return HAL_TIMEOUT;
03011     }
03012   }
03013 
03014   return HAL_OK;
03015 }
03016 
03017 #endif /* RCC_PLLSAI_SUPPORT */
03018 
03019 /**
03020   * @}
03021   */
03022 
03023 #if defined(STM32F446xx)
03024 /**
03025   * @brief  Returns the SYSCLK frequency
03026   *
03027   * @note   This function implementation is valid only for STM32F446xx devices.
03028   * @note   This function add the PLL/PLLR System clock source
03029   *
03030   * @note   The system frequency computed by this function is not the real
03031   *         frequency in the chip. It is calculated based on the predefined
03032   *         constant and the selected clock source:
03033   * @note     If SYSCLK source is HSI, function returns values based on HSI_VALUE(*)
03034   * @note     If SYSCLK source is HSE, function returns values based on HSE_VALUE(**)
03035   * @note     If SYSCLK source is PLL or PLLR, function returns values based on HSE_VALUE(**)
03036   *           or HSI_VALUE(*) multiplied/divided by the PLL factors.
03037   * @note     (*) HSI_VALUE is a constant defined in stm32f4xx_hal_conf.h file (default value
03038   *               16 MHz) but the real value may vary depending on the variations
03039   *               in voltage and temperature.
03040   * @note     (**) HSE_VALUE is a constant defined in stm32f4xx_hal_conf.h file (default value
03041   *                25 MHz), user has to ensure that HSE_VALUE is same as the real
03042   *                frequency of the crystal used. Otherwise, this function may
03043   *                have wrong result.
03044   *
03045   * @note   The result of this function could be not correct when using fractional
03046   *         value for HSE crystal.
03047   *
03048   * @note   This function can be used by the user application to compute the
03049   *         baudrate for the communication peripherals or configure other parameters.
03050   *
03051   * @note   Each time SYSCLK changes, this function must be called to update the
03052   *         right SYSCLK value. Otherwise, any configuration based on this function will be incorrect.
03053   *
03054   *
03055   * @retval SYSCLK frequency
03056   */
03057 uint32_t HAL_RCC_GetSysClockFreq(void)
03058 {
03059   uint32_t pllm = 0U;
03060   uint32_t pllvco = 0U;
03061   uint32_t pllp = 0U;
03062   uint32_t pllr = 0U;
03063   uint32_t sysclockfreq = 0U;
03064 
03065   /* Get SYSCLK source -------------------------------------------------------*/
03066   switch (RCC->CFGR & RCC_CFGR_SWS)
03067   {
03068     case RCC_CFGR_SWS_HSI:  /* HSI used as system clock source */
03069     {
03070       sysclockfreq = HSI_VALUE;
03071        break;
03072     }
03073     case RCC_CFGR_SWS_HSE:  /* HSE used as system clock  source */
03074     {
03075       sysclockfreq = HSE_VALUE;
03076       break;
03077     }
03078     case RCC_CFGR_SWS_PLL:  /* PLL/PLLP used as system clock  source */
03079     {
03080       /* PLL_VCO = (HSE_VALUE or HSI_VALUE / PLLM) * PLLN
03081       SYSCLK = PLL_VCO / PLLP */
03082       pllm = RCC->PLLCFGR & RCC_PLLCFGR_PLLM;
03083       if(__HAL_RCC_GET_PLL_OSCSOURCE() != RCC_PLLSOURCE_HSI)
03084       {
03085         /* HSE used as PLL clock source */
03086         pllvco = (uint32_t) ((((uint64_t) HSE_VALUE * ((uint64_t) ((RCC->PLLCFGR & RCC_PLLCFGR_PLLN) >> RCC_PLLCFGR_PLLN_Pos)))) / (uint64_t)pllm);
03087       }
03088       else
03089       {
03090         /* HSI used as PLL clock source */
03091         pllvco = (uint32_t) ((((uint64_t) HSI_VALUE * ((uint64_t) ((RCC->PLLCFGR & RCC_PLLCFGR_PLLN) >> RCC_PLLCFGR_PLLN_Pos)))) / (uint64_t)pllm);
03092       }
03093       pllp = ((((RCC->PLLCFGR & RCC_PLLCFGR_PLLP) >> RCC_PLLCFGR_PLLP_Pos) + 1U) *2U);
03094 
03095       sysclockfreq = pllvco/pllp;
03096       break;
03097     }
03098     case RCC_CFGR_SWS_PLLR:  /* PLL/PLLR used as system clock  source */
03099     {
03100       /* PLL_VCO = (HSE_VALUE or HSI_VALUE / PLLM) * PLLN
03101       SYSCLK = PLL_VCO / PLLR */
03102       pllm = RCC->PLLCFGR & RCC_PLLCFGR_PLLM;
03103       if(__HAL_RCC_GET_PLL_OSCSOURCE() != RCC_PLLSOURCE_HSI)
03104       {
03105         /* HSE used as PLL clock source */
03106         pllvco = (uint32_t) ((((uint64_t) HSE_VALUE * ((uint64_t) ((RCC->PLLCFGR & RCC_PLLCFGR_PLLN) >> RCC_PLLCFGR_PLLN_Pos)))) / (uint64_t)pllm);
03107       }
03108       else
03109       {
03110         /* HSI used as PLL clock source */
03111         pllvco = (uint32_t) ((((uint64_t) HSI_VALUE * ((uint64_t) ((RCC->PLLCFGR & RCC_PLLCFGR_PLLN) >> RCC_PLLCFGR_PLLN_Pos)))) / (uint64_t)pllm);
03112       }
03113       pllr = ((RCC->PLLCFGR & RCC_PLLCFGR_PLLR) >> RCC_PLLCFGR_PLLR_Pos);
03114 
03115       sysclockfreq = pllvco/pllr;
03116       break;
03117     }
03118     default:
03119     {
03120       sysclockfreq = HSI_VALUE;
03121       break;
03122     }
03123   }
03124   return sysclockfreq;
03125 }
03126 #endif /* STM32F446xx */
03127 
03128 /**
03129   * @}
03130   */
03131 
03132 /**
03133   * @}
03134   */
03135 
03136 /**
03137   * @brief  Resets the RCC clock configuration to the default reset state.
03138   * @note   The default reset state of the clock configuration is given below:
03139   *            - HSI ON and used as system clock source
03140   *            - HSE, PLL, PLLI2S and PLLSAI OFF
03141   *            - AHB, APB1 and APB2 prescaler set to 1.
03142   *            - CSS, MCO1 and MCO2 OFF
03143   *            - All interrupts disabled
03144   * @note   This function doesn't modify the configuration of the
03145   *            - Peripheral clocks
03146   *            - LSI, LSE and RTC clocks
03147   * @retval HAL status
03148   */
03149 HAL_StatusTypeDef HAL_RCC_DeInit(void)
03150 {
03151   uint32_t tickstart;
03152 
03153   /* Get Start Tick */
03154   tickstart = HAL_GetTick();
03155 
03156   /* Set HSION bit to the reset value */
03157   SET_BIT(RCC->CR, RCC_CR_HSION);
03158 
03159   /* Wait till HSI is ready */
03160   while (READ_BIT(RCC->CR, RCC_CR_HSIRDY) == RESET)
03161   {
03162     if ((HAL_GetTick() - tickstart) > HSI_TIMEOUT_VALUE)
03163     {
03164       return HAL_TIMEOUT;
03165     }
03166   }
03167 
03168   /* Set HSITRIM[4:0] bits to the reset value */
03169   SET_BIT(RCC->CR, RCC_CR_HSITRIM_4);
03170 
03171   /* Get Start Tick */
03172   tickstart = HAL_GetTick();
03173 
03174   /* Reset CFGR register */
03175   CLEAR_REG(RCC->CFGR);
03176 
03177   /* Wait till clock switch is ready */
03178   while (READ_BIT(RCC->CFGR, RCC_CFGR_SWS) != RESET)
03179   {
03180     if ((HAL_GetTick() - tickstart) > CLOCKSWITCH_TIMEOUT_VALUE)
03181     {
03182       return HAL_TIMEOUT;
03183     }
03184   }
03185 
03186   /* Get Start Tick */
03187   tickstart = HAL_GetTick();
03188 
03189   /* Clear HSEON, HSEBYP and CSSON bits */
03190   CLEAR_BIT(RCC->CR, RCC_CR_HSEON | RCC_CR_HSEBYP | RCC_CR_CSSON);
03191 
03192   /* Wait till HSE is disabled */
03193   while (READ_BIT(RCC->CR, RCC_CR_HSERDY) != RESET)
03194   {
03195     if ((HAL_GetTick() - tickstart) > HSE_TIMEOUT_VALUE)
03196     {
03197       return HAL_TIMEOUT;
03198     }
03199   }
03200 
03201   /* Get Start Tick */
03202   tickstart = HAL_GetTick();
03203 
03204   /* Clear PLLON bit */
03205   CLEAR_BIT(RCC->CR, RCC_CR_PLLON);
03206 
03207   /* Wait till PLL is disabled */
03208   while (READ_BIT(RCC->CR, RCC_CR_PLLRDY) != RESET)
03209   {
03210     if ((HAL_GetTick() - tickstart) > PLL_TIMEOUT_VALUE)
03211     {
03212       return HAL_TIMEOUT;
03213     }
03214   }
03215 
03216 #if defined(RCC_PLLI2S_SUPPORT)
03217   /* Get Start Tick */
03218   tickstart = HAL_GetTick();
03219 
03220   /* Reset PLLI2SON bit */
03221   CLEAR_BIT(RCC->CR, RCC_CR_PLLI2SON);
03222 
03223   /* Wait till PLLI2S is disabled */
03224   while (READ_BIT(RCC->CR, RCC_CR_PLLI2SRDY) != RESET)
03225   {
03226     if ((HAL_GetTick() - tickstart) > PLLI2S_TIMEOUT_VALUE)
03227     {
03228       return HAL_TIMEOUT;
03229     }
03230   }
03231 #endif /* RCC_PLLI2S_SUPPORT */
03232 
03233 #if defined(RCC_PLLSAI_SUPPORT)
03234   /* Get Start Tick */
03235   tickstart = HAL_GetTick();
03236 
03237   /* Reset PLLSAI bit */
03238   CLEAR_BIT(RCC->CR, RCC_CR_PLLSAION);
03239 
03240   /* Wait till PLLSAI is disabled */
03241   while (READ_BIT(RCC->CR, RCC_CR_PLLSAIRDY) != RESET)
03242   {
03243     if ((HAL_GetTick() - tickstart) > PLLSAI_TIMEOUT_VALUE)
03244     {
03245       return HAL_TIMEOUT;
03246     }
03247   }
03248 #endif /* RCC_PLLSAI_SUPPORT */
03249 
03250   /* Once PLL, PLLI2S and PLLSAI are OFF, reset PLLCFGR register to default value */
03251 #if defined(STM32F412Cx) || defined(STM32F412Rx) || defined(STM32F412Vx) || defined(STM32F412Zx) || defined(STM32F413xx) || \
03252     defined(STM32F423xx) || defined(STM32F446xx) || defined(STM32F469xx) || defined(STM32F479xx)
03253   RCC->PLLCFGR = RCC_PLLCFGR_PLLM_4 | RCC_PLLCFGR_PLLN_6 | RCC_PLLCFGR_PLLN_7 | RCC_PLLCFGR_PLLQ_2 | RCC_PLLCFGR_PLLR_1;
03254 #elif defined(STM32F410Tx) || defined(STM32F410Cx) || defined(STM32F410Rx)
03255   RCC->PLLCFGR = RCC_PLLCFGR_PLLR_0 | RCC_PLLCFGR_PLLR_1 | RCC_PLLCFGR_PLLR_2 | RCC_PLLCFGR_PLLM_4 | RCC_PLLCFGR_PLLN_6 | RCC_PLLCFGR_PLLN_7 | RCC_PLLCFGR_PLLQ_0 | RCC_PLLCFGR_PLLQ_1 | RCC_PLLCFGR_PLLQ_2 | RCC_PLLCFGR_PLLQ_3;
03256 #else
03257   RCC->PLLCFGR = RCC_PLLCFGR_PLLM_4 | RCC_PLLCFGR_PLLN_6 | RCC_PLLCFGR_PLLN_7 | RCC_PLLCFGR_PLLQ_2;
03258 #endif /* STM32F412Cx || STM32F412Rx || STM32F412Vx || STM32F412Zx || STM32F413xx || STM32F423xx || STM32F446xx || STM32F469xx || STM32F479xx */
03259 
03260   /* Reset PLLI2SCFGR register to default value */
03261 #if defined(STM32F412Cx) || defined(STM32F412Rx) || defined(STM32F412Vx) || defined(STM32F412Zx) || defined(STM32F413xx) || \
03262     defined(STM32F423xx) || defined(STM32F446xx)
03263   RCC->PLLI2SCFGR = RCC_PLLI2SCFGR_PLLI2SM_4 | RCC_PLLI2SCFGR_PLLI2SN_6 | RCC_PLLI2SCFGR_PLLI2SN_7 | RCC_PLLI2SCFGR_PLLI2SQ_2 | RCC_PLLI2SCFGR_PLLI2SR_1;
03264 #elif defined(STM32F401xC) || defined(STM32F401xE) || defined(STM32F405xx) || defined(STM32F415xx) || defined(STM32F407xx) || defined(STM32F417xx)
03265   RCC->PLLI2SCFGR = RCC_PLLI2SCFGR_PLLI2SN_6 | RCC_PLLI2SCFGR_PLLI2SN_7 | RCC_PLLI2SCFGR_PLLI2SR_1;
03266 #elif defined(STM32F427xx) || defined(STM32F437xx) || defined(STM32F429xx) || defined(STM32F439xx) || defined(STM32F469xx) || defined(STM32F479xx)
03267   RCC->PLLI2SCFGR = RCC_PLLI2SCFGR_PLLI2SN_6 | RCC_PLLI2SCFGR_PLLI2SN_7 | RCC_PLLI2SCFGR_PLLI2SQ_2 | RCC_PLLI2SCFGR_PLLI2SR_1;
03268 #elif defined(STM32F411xE)
03269   RCC->PLLI2SCFGR = RCC_PLLI2SCFGR_PLLI2SM_4 | RCC_PLLI2SCFGR_PLLI2SN_6 | RCC_PLLI2SCFGR_PLLI2SN_7 | RCC_PLLI2SCFGR_PLLI2SR_1;
03270 #endif /* STM32F412Cx || STM32F412Rx || STM32F412Vx || STM32F412Zx || STM32F413xx || STM32F423xx || STM32F446xx */
03271 
03272   /* Reset PLLSAICFGR register */
03273 #if defined(STM32F427xx) || defined(STM32F429xx) || defined(STM32F437xx) || defined(STM32F439xx) || defined(STM32F469xx) || defined(STM32F479xx)
03274   RCC->PLLSAICFGR = RCC_PLLSAICFGR_PLLSAIN_6 | RCC_PLLSAICFGR_PLLSAIN_7 | RCC_PLLSAICFGR_PLLSAIQ_2 | RCC_PLLSAICFGR_PLLSAIR_1;
03275 #elif defined(STM32F446xx)
03276   RCC->PLLSAICFGR = RCC_PLLSAICFGR_PLLSAIM_4 | RCC_PLLSAICFGR_PLLSAIN_6 | RCC_PLLSAICFGR_PLLSAIN_7 | RCC_PLLSAICFGR_PLLSAIQ_2;
03277 #endif /* STM32F427xx || STM32F429xx || STM32F437xx || STM32F439xx || STM32F469xx || STM32F479xx */
03278 
03279   /* Disable all interrupts */
03280   CLEAR_BIT(RCC->CIR, RCC_CIR_LSIRDYIE | RCC_CIR_LSERDYIE | RCC_CIR_HSIRDYIE | RCC_CIR_HSERDYIE | RCC_CIR_PLLRDYIE);
03281 
03282 #if defined(RCC_CIR_PLLI2SRDYIE)
03283   CLEAR_BIT(RCC->CIR, RCC_CIR_PLLI2SRDYIE);
03284 #endif /* RCC_CIR_PLLI2SRDYIE */
03285 
03286 #if defined(RCC_CIR_PLLSAIRDYIE)
03287   CLEAR_BIT(RCC->CIR, RCC_CIR_PLLSAIRDYIE);
03288 #endif /* RCC_CIR_PLLSAIRDYIE */
03289 
03290   /* Clear all interrupt flags */
03291   SET_BIT(RCC->CIR, RCC_CIR_LSIRDYC | RCC_CIR_LSERDYC | RCC_CIR_HSIRDYC | RCC_CIR_HSERDYC | RCC_CIR_PLLRDYC | RCC_CIR_CSSC);
03292 
03293 #if defined(RCC_CIR_PLLI2SRDYC)
03294   SET_BIT(RCC->CIR, RCC_CIR_PLLI2SRDYC);
03295 #endif /* RCC_CIR_PLLI2SRDYC */
03296 
03297 #if defined(RCC_CIR_PLLSAIRDYC)
03298   SET_BIT(RCC->CIR, RCC_CIR_PLLSAIRDYC);
03299 #endif /* RCC_CIR_PLLSAIRDYC */
03300 
03301   /* Clear LSION bit */
03302   CLEAR_BIT(RCC->CSR, RCC_CSR_LSION);
03303 
03304   /* Reset all CSR flags */
03305   SET_BIT(RCC->CSR, RCC_CSR_RMVF);
03306 
03307   /* Update the SystemCoreClock global variable */
03308   SystemCoreClock = HSI_VALUE;
03309 
03310   /* Adapt Systick interrupt period */
03311   if(HAL_InitTick(TICK_INT_PRIORITY) != HAL_OK)
03312   {
03313     return HAL_ERROR;
03314   }
03315   else
03316   {
03317     return HAL_OK;
03318   }
03319 }
03320 
03321 #if defined(STM32F410Tx) || defined(STM32F410Cx) || defined(STM32F410Rx) || defined(STM32F446xx) || defined(STM32F469xx) || defined(STM32F479xx) || defined(STM32F412Zx) ||\
03322     defined(STM32F412Vx) || defined(STM32F412Rx) || defined(STM32F412Cx) || defined(STM32F413xx) || defined(STM32F423xx)
03323 /**
03324   * @brief  Initializes the RCC Oscillators according to the specified parameters in the
03325   *         RCC_OscInitTypeDef.
03326   * @param  RCC_OscInitStruct pointer to an RCC_OscInitTypeDef structure that
03327   *         contains the configuration information for the RCC Oscillators.
03328   * @note   The PLL is not disabled when used as system clock.
03329   * @note   Transitions LSE Bypass to LSE On and LSE On to LSE Bypass are not
03330   *         supported by this API. User should request a transition to LSE Off
03331   *         first and then LSE On or LSE Bypass.
03332   * @note   Transition HSE Bypass to HSE On and HSE On to HSE Bypass are not
03333   *         supported by this API. User should request a transition to HSE Off
03334   *         first and then HSE On or HSE Bypass.
03335   * @note   This function add the PLL/PLLR factor management during PLL configuration this feature
03336   *         is only available in STM32F410xx/STM32F446xx/STM32F469xx/STM32F479xx/STM32F412Zx/STM32F412Vx/STM32F412Rx/STM32F412Cx devices
03337   * @retval HAL status
03338   */
03339 HAL_StatusTypeDef HAL_RCC_OscConfig(RCC_OscInitTypeDef  *RCC_OscInitStruct)
03340 {
03341   uint32_t tickstart = 0U;
03342 
03343   /* Check the parameters */
03344   assert_param(IS_RCC_OSCILLATORTYPE(RCC_OscInitStruct->OscillatorType));
03345   /*------------------------------- HSE Configuration ------------------------*/
03346   if(((RCC_OscInitStruct->OscillatorType) & RCC_OSCILLATORTYPE_HSE) == RCC_OSCILLATORTYPE_HSE)
03347   {
03348     /* Check the parameters */
03349     assert_param(IS_RCC_HSE(RCC_OscInitStruct->HSEState));
03350     /* When the HSE is used as system clock or clock source for PLL in these cases HSE will not disabled */
03351 #if defined(STM32F446xx)
03352     if((__HAL_RCC_GET_SYSCLK_SOURCE() == RCC_CFGR_SWS_HSE)                                                                     ||\
03353       ((__HAL_RCC_GET_SYSCLK_SOURCE() == RCC_CFGR_SWS_PLL) && ((RCC->PLLCFGR & RCC_PLLCFGR_PLLSRC) == RCC_PLLCFGR_PLLSRC_HSE)) ||\
03354       ((__HAL_RCC_GET_SYSCLK_SOURCE() == RCC_CFGR_SWS_PLLR) && ((RCC->PLLCFGR & RCC_PLLCFGR_PLLSRC) == RCC_PLLCFGR_PLLSRC_HSE)))
03355 #else
03356     if((__HAL_RCC_GET_SYSCLK_SOURCE() == RCC_CFGR_SWS_HSE)                                                                     ||\
03357       ((__HAL_RCC_GET_SYSCLK_SOURCE() == RCC_CFGR_SWS_PLL) && ((RCC->PLLCFGR & RCC_PLLCFGR_PLLSRC) == RCC_PLLCFGR_PLLSRC_HSE)))
03358 #endif /* STM32F446xx */
03359     {
03360       if((__HAL_RCC_GET_FLAG(RCC_FLAG_HSERDY) != RESET) && (RCC_OscInitStruct->HSEState == RCC_HSE_OFF))
03361       {
03362         return HAL_ERROR;
03363       }
03364     }
03365     else
03366     {
03367       /* Set the new HSE configuration ---------------------------------------*/
03368       __HAL_RCC_HSE_CONFIG(RCC_OscInitStruct->HSEState);
03369 
03370       /* Check the HSE State */
03371       if((RCC_OscInitStruct->HSEState) != RCC_HSE_OFF)
03372       {
03373         /* Get Start Tick*/
03374         tickstart = HAL_GetTick();
03375 
03376         /* Wait till HSE is ready */
03377         while(__HAL_RCC_GET_FLAG(RCC_FLAG_HSERDY) == RESET)
03378         {
03379           if((HAL_GetTick() - tickstart ) > HSE_TIMEOUT_VALUE)
03380           {
03381             return HAL_TIMEOUT;
03382           }
03383         }
03384       }
03385       else
03386       {
03387         /* Get Start Tick*/
03388         tickstart = HAL_GetTick();
03389 
03390         /* Wait till HSE is bypassed or disabled */
03391         while(__HAL_RCC_GET_FLAG(RCC_FLAG_HSERDY) != RESET)
03392         {
03393           if((HAL_GetTick() - tickstart ) > HSE_TIMEOUT_VALUE)
03394           {
03395             return HAL_TIMEOUT;
03396           }
03397         }
03398       }
03399     }
03400   }
03401   /*----------------------------- HSI Configuration --------------------------*/
03402   if(((RCC_OscInitStruct->OscillatorType) & RCC_OSCILLATORTYPE_HSI) == RCC_OSCILLATORTYPE_HSI)
03403   {
03404     /* Check the parameters */
03405     assert_param(IS_RCC_HSI(RCC_OscInitStruct->HSIState));
03406     assert_param(IS_RCC_CALIBRATION_VALUE(RCC_OscInitStruct->HSICalibrationValue));
03407 
03408     /* Check if HSI is used as system clock or as PLL source when PLL is selected as system clock */
03409 #if defined(STM32F446xx)
03410     if((__HAL_RCC_GET_SYSCLK_SOURCE() == RCC_CFGR_SWS_HSI)                                                                     ||\
03411       ((__HAL_RCC_GET_SYSCLK_SOURCE() == RCC_CFGR_SWS_PLL) && ((RCC->PLLCFGR & RCC_PLLCFGR_PLLSRC) == RCC_PLLCFGR_PLLSRC_HSI)) ||\
03412       ((__HAL_RCC_GET_SYSCLK_SOURCE() == RCC_CFGR_SWS_PLLR) && ((RCC->PLLCFGR & RCC_PLLCFGR_PLLSRC) == RCC_PLLCFGR_PLLSRC_HSI)))
03413 #else
03414     if((__HAL_RCC_GET_SYSCLK_SOURCE() == RCC_CFGR_SWS_HSI)                                                                     ||\
03415       ((__HAL_RCC_GET_SYSCLK_SOURCE() == RCC_CFGR_SWS_PLL) && ((RCC->PLLCFGR & RCC_PLLCFGR_PLLSRC) == RCC_PLLCFGR_PLLSRC_HSI)))
03416 #endif /* STM32F446xx */
03417     {
03418       /* When HSI is used as system clock it will not disabled */
03419       if((__HAL_RCC_GET_FLAG(RCC_FLAG_HSIRDY) != RESET) && (RCC_OscInitStruct->HSIState != RCC_HSI_ON))
03420       {
03421         return HAL_ERROR;
03422       }
03423       /* Otherwise, just the calibration is allowed */
03424       else
03425       {
03426         /* Adjusts the Internal High Speed oscillator (HSI) calibration value.*/
03427         __HAL_RCC_HSI_CALIBRATIONVALUE_ADJUST(RCC_OscInitStruct->HSICalibrationValue);
03428       }
03429     }
03430     else
03431     {
03432       /* Check the HSI State */
03433       if((RCC_OscInitStruct->HSIState)!= RCC_HSI_OFF)
03434       {
03435         /* Enable the Internal High Speed oscillator (HSI). */
03436         __HAL_RCC_HSI_ENABLE();
03437 
03438         /* Get Start Tick*/
03439         tickstart = HAL_GetTick();
03440 
03441         /* Wait till HSI is ready */
03442         while(__HAL_RCC_GET_FLAG(RCC_FLAG_HSIRDY) == RESET)
03443         {
03444           if((HAL_GetTick() - tickstart ) > HSI_TIMEOUT_VALUE)
03445           {
03446             return HAL_TIMEOUT;
03447           }
03448         }
03449 
03450         /* Adjusts the Internal High Speed oscillator (HSI) calibration value.*/
03451         __HAL_RCC_HSI_CALIBRATIONVALUE_ADJUST(RCC_OscInitStruct->HSICalibrationValue);
03452       }
03453       else
03454       {
03455         /* Disable the Internal High Speed oscillator (HSI). */
03456         __HAL_RCC_HSI_DISABLE();
03457 
03458         /* Get Start Tick*/
03459         tickstart = HAL_GetTick();
03460 
03461         /* Wait till HSI is ready */
03462         while(__HAL_RCC_GET_FLAG(RCC_FLAG_HSIRDY) != RESET)
03463         {
03464           if((HAL_GetTick() - tickstart ) > HSI_TIMEOUT_VALUE)
03465           {
03466             return HAL_TIMEOUT;
03467           }
03468         }
03469       }
03470     }
03471   }
03472   /*------------------------------ LSI Configuration -------------------------*/
03473   if(((RCC_OscInitStruct->OscillatorType) & RCC_OSCILLATORTYPE_LSI) == RCC_OSCILLATORTYPE_LSI)
03474   {
03475     /* Check the parameters */
03476     assert_param(IS_RCC_LSI(RCC_OscInitStruct->LSIState));
03477 
03478     /* Check the LSI State */
03479     if((RCC_OscInitStruct->LSIState)!= RCC_LSI_OFF)
03480     {
03481       /* Enable the Internal Low Speed oscillator (LSI). */
03482       __HAL_RCC_LSI_ENABLE();
03483 
03484       /* Get Start Tick*/
03485       tickstart = HAL_GetTick();
03486 
03487       /* Wait till LSI is ready */
03488       while(__HAL_RCC_GET_FLAG(RCC_FLAG_LSIRDY) == RESET)
03489       {
03490         if((HAL_GetTick() - tickstart ) > LSI_TIMEOUT_VALUE)
03491         {
03492           return HAL_TIMEOUT;
03493         }
03494       }
03495     }
03496     else
03497     {
03498       /* Disable the Internal Low Speed oscillator (LSI). */
03499       __HAL_RCC_LSI_DISABLE();
03500 
03501       /* Get Start Tick*/
03502       tickstart = HAL_GetTick();
03503 
03504       /* Wait till LSI is ready */
03505       while(__HAL_RCC_GET_FLAG(RCC_FLAG_LSIRDY) != RESET)
03506       {
03507         if((HAL_GetTick() - tickstart ) > LSI_TIMEOUT_VALUE)
03508         {
03509           return HAL_TIMEOUT;
03510         }
03511       }
03512     }
03513   }
03514   /*------------------------------ LSE Configuration -------------------------*/
03515   if(((RCC_OscInitStruct->OscillatorType) & RCC_OSCILLATORTYPE_LSE) == RCC_OSCILLATORTYPE_LSE)
03516   {
03517     FlagStatus       pwrclkchanged = RESET;
03518 
03519     /* Check the parameters */
03520     assert_param(IS_RCC_LSE(RCC_OscInitStruct->LSEState));
03521 
03522     /* Update LSE configuration in Backup Domain control register    */
03523     /* Requires to enable write access to Backup Domain of necessary */
03524     if(__HAL_RCC_PWR_IS_CLK_DISABLED())
03525     {
03526       __HAL_RCC_PWR_CLK_ENABLE();
03527       pwrclkchanged = SET;
03528     }
03529 
03530     if(HAL_IS_BIT_CLR(PWR->CR, PWR_CR_DBP))
03531     {
03532       /* Enable write access to Backup domain */
03533       SET_BIT(PWR->CR, PWR_CR_DBP);
03534 
03535       /* Wait for Backup domain Write protection disable */
03536       tickstart = HAL_GetTick();
03537 
03538       while(HAL_IS_BIT_CLR(PWR->CR, PWR_CR_DBP))
03539       {
03540         if((HAL_GetTick() - tickstart) > RCC_DBP_TIMEOUT_VALUE)
03541         {
03542           return HAL_TIMEOUT;
03543         }
03544       }
03545     }
03546 
03547     /* Set the new LSE configuration -----------------------------------------*/
03548     __HAL_RCC_LSE_CONFIG(RCC_OscInitStruct->LSEState);
03549     /* Check the LSE State */
03550     if((RCC_OscInitStruct->LSEState) != RCC_LSE_OFF)
03551     {
03552       /* Get Start Tick*/
03553       tickstart = HAL_GetTick();
03554 
03555       /* Wait till LSE is ready */
03556       while(__HAL_RCC_GET_FLAG(RCC_FLAG_LSERDY) == RESET)
03557       {
03558         if((HAL_GetTick() - tickstart ) > RCC_LSE_TIMEOUT_VALUE)
03559         {
03560           return HAL_TIMEOUT;
03561         }
03562       }
03563     }
03564     else
03565     {
03566       /* Get Start Tick*/
03567       tickstart = HAL_GetTick();
03568 
03569       /* Wait till LSE is ready */
03570       while(__HAL_RCC_GET_FLAG(RCC_FLAG_LSERDY) != RESET)
03571       {
03572         if((HAL_GetTick() - tickstart ) > RCC_LSE_TIMEOUT_VALUE)
03573         {
03574           return HAL_TIMEOUT;
03575         }
03576       }
03577     }
03578 
03579     /* Restore clock configuration if changed */
03580     if(pwrclkchanged == SET)
03581     {
03582       __HAL_RCC_PWR_CLK_DISABLE();
03583     }
03584   }
03585   /*-------------------------------- PLL Configuration -----------------------*/
03586   /* Check the parameters */
03587   assert_param(IS_RCC_PLL(RCC_OscInitStruct->PLL.PLLState));
03588   if ((RCC_OscInitStruct->PLL.PLLState) != RCC_PLL_NONE)
03589   {
03590     /* Check if the PLL is used as system clock or not */
03591     if(__HAL_RCC_GET_SYSCLK_SOURCE() != RCC_CFGR_SWS_PLL)
03592     {
03593       if((RCC_OscInitStruct->PLL.PLLState) == RCC_PLL_ON)
03594       {
03595         /* Check the parameters */
03596         assert_param(IS_RCC_PLLSOURCE(RCC_OscInitStruct->PLL.PLLSource));
03597         assert_param(IS_RCC_PLLM_VALUE(RCC_OscInitStruct->PLL.PLLM));
03598         assert_param(IS_RCC_PLLN_VALUE(RCC_OscInitStruct->PLL.PLLN));
03599         assert_param(IS_RCC_PLLP_VALUE(RCC_OscInitStruct->PLL.PLLP));
03600         assert_param(IS_RCC_PLLQ_VALUE(RCC_OscInitStruct->PLL.PLLQ));
03601         assert_param(IS_RCC_PLLR_VALUE(RCC_OscInitStruct->PLL.PLLR));
03602 
03603         /* Disable the main PLL. */
03604         __HAL_RCC_PLL_DISABLE();
03605 
03606         /* Get Start Tick*/
03607         tickstart = HAL_GetTick();
03608 
03609         /* Wait till PLL is ready */
03610         while(__HAL_RCC_GET_FLAG(RCC_FLAG_PLLRDY) != RESET)
03611         {
03612           if((HAL_GetTick() - tickstart ) > PLL_TIMEOUT_VALUE)
03613           {
03614             return HAL_TIMEOUT;
03615           }
03616         }
03617 
03618         /* Configure the main PLL clock source, multiplication and division factors. */
03619         __HAL_RCC_PLL_CONFIG(RCC_OscInitStruct->PLL.PLLSource,
03620                              RCC_OscInitStruct->PLL.PLLM,
03621                              RCC_OscInitStruct->PLL.PLLN,
03622                              RCC_OscInitStruct->PLL.PLLP,
03623                              RCC_OscInitStruct->PLL.PLLQ,
03624                              RCC_OscInitStruct->PLL.PLLR);
03625 
03626         /* Enable the main PLL. */
03627         __HAL_RCC_PLL_ENABLE();
03628 
03629         /* Get Start Tick*/
03630         tickstart = HAL_GetTick();
03631 
03632         /* Wait till PLL is ready */
03633         while(__HAL_RCC_GET_FLAG(RCC_FLAG_PLLRDY) == RESET)
03634         {
03635           if((HAL_GetTick() - tickstart ) > PLL_TIMEOUT_VALUE)
03636           {
03637             return HAL_TIMEOUT;
03638           }
03639         }
03640       }
03641       else
03642       {
03643         /* Disable the main PLL. */
03644         __HAL_RCC_PLL_DISABLE();
03645 
03646         /* Get Start Tick*/
03647         tickstart = HAL_GetTick();
03648 
03649         /* Wait till PLL is ready */
03650         while(__HAL_RCC_GET_FLAG(RCC_FLAG_PLLRDY) != RESET)
03651         {
03652           if((HAL_GetTick() - tickstart ) > PLL_TIMEOUT_VALUE)
03653           {
03654             return HAL_TIMEOUT;
03655           }
03656         }
03657       }
03658     }
03659     else
03660     {
03661       return HAL_ERROR;
03662     }
03663   }
03664   return HAL_OK;
03665 }
03666 
03667 /**
03668   * @brief  Configures the RCC_OscInitStruct according to the internal
03669   * RCC configuration registers.
03670   * @param  RCC_OscInitStruct pointer to an RCC_OscInitTypeDef structure that will be configured.
03671   *
03672   * @note   This function is only available in case of STM32F410xx/STM32F446xx/STM32F469xx/STM32F479xx/STM32F412Zx/STM32F412Vx/STM32F412Rx/STM32F412Cx devices.
03673   * @note   This function add the PLL/PLLR factor management
03674   * @retval None
03675   */
03676 void HAL_RCC_GetOscConfig(RCC_OscInitTypeDef  *RCC_OscInitStruct)
03677 {
03678   /* Set all possible values for the Oscillator type parameter ---------------*/
03679   RCC_OscInitStruct->OscillatorType = RCC_OSCILLATORTYPE_HSE | RCC_OSCILLATORTYPE_HSI | RCC_OSCILLATORTYPE_LSE | RCC_OSCILLATORTYPE_LSI;
03680 
03681   /* Get the HSE configuration -----------------------------------------------*/
03682   if((RCC->CR &RCC_CR_HSEBYP) == RCC_CR_HSEBYP)
03683   {
03684     RCC_OscInitStruct->HSEState = RCC_HSE_BYPASS;
03685   }
03686   else if((RCC->CR &RCC_CR_HSEON) == RCC_CR_HSEON)
03687   {
03688     RCC_OscInitStruct->HSEState = RCC_HSE_ON;
03689   }
03690   else
03691   {
03692     RCC_OscInitStruct->HSEState = RCC_HSE_OFF;
03693   }
03694 
03695   /* Get the HSI configuration -----------------------------------------------*/
03696   if((RCC->CR &RCC_CR_HSION) == RCC_CR_HSION)
03697   {
03698     RCC_OscInitStruct->HSIState = RCC_HSI_ON;
03699   }
03700   else
03701   {
03702     RCC_OscInitStruct->HSIState = RCC_HSI_OFF;
03703   }
03704 
03705   RCC_OscInitStruct->HSICalibrationValue = (uint32_t)((RCC->CR &RCC_CR_HSITRIM) >> RCC_CR_HSITRIM_Pos);
03706 
03707   /* Get the LSE configuration -----------------------------------------------*/
03708   if((RCC->BDCR &RCC_BDCR_LSEBYP) == RCC_BDCR_LSEBYP)
03709   {
03710     RCC_OscInitStruct->LSEState = RCC_LSE_BYPASS;
03711   }
03712   else if((RCC->BDCR &RCC_BDCR_LSEON) == RCC_BDCR_LSEON)
03713   {
03714     RCC_OscInitStruct->LSEState = RCC_LSE_ON;
03715   }
03716   else
03717   {
03718     RCC_OscInitStruct->LSEState = RCC_LSE_OFF;
03719   }
03720 
03721   /* Get the LSI configuration -----------------------------------------------*/
03722   if((RCC->CSR &RCC_CSR_LSION) == RCC_CSR_LSION)
03723   {
03724     RCC_OscInitStruct->LSIState = RCC_LSI_ON;
03725   }
03726   else
03727   {
03728     RCC_OscInitStruct->LSIState = RCC_LSI_OFF;
03729   }
03730 
03731   /* Get the PLL configuration -----------------------------------------------*/
03732   if((RCC->CR &RCC_CR_PLLON) == RCC_CR_PLLON)
03733   {
03734     RCC_OscInitStruct->PLL.PLLState = RCC_PLL_ON;
03735   }
03736   else
03737   {
03738     RCC_OscInitStruct->PLL.PLLState = RCC_PLL_OFF;
03739   }
03740   RCC_OscInitStruct->PLL.PLLSource = (uint32_t)(RCC->PLLCFGR & RCC_PLLCFGR_PLLSRC);
03741   RCC_OscInitStruct->PLL.PLLM = (uint32_t)(RCC->PLLCFGR & RCC_PLLCFGR_PLLM);
03742   RCC_OscInitStruct->PLL.PLLN = (uint32_t)((RCC->PLLCFGR & RCC_PLLCFGR_PLLN) >> RCC_PLLCFGR_PLLN_Pos);
03743   RCC_OscInitStruct->PLL.PLLP = (uint32_t)((((RCC->PLLCFGR & RCC_PLLCFGR_PLLP) + RCC_PLLCFGR_PLLP_0) << 1U) >> RCC_PLLCFGR_PLLP_Pos);
03744   RCC_OscInitStruct->PLL.PLLQ = (uint32_t)((RCC->PLLCFGR & RCC_PLLCFGR_PLLQ) >> RCC_PLLCFGR_PLLQ_Pos);
03745   RCC_OscInitStruct->PLL.PLLR = (uint32_t)((RCC->PLLCFGR & RCC_PLLCFGR_PLLR) >> RCC_PLLCFGR_PLLR_Pos);
03746 }
03747 #endif /* STM32F410xx || STM32F446xx || STM32F469xx || STM32F479xx || STM32F412Zx || STM32F412Vx || STM32F412Rx || STM32F412Cx || STM32F413xx || STM32F423xx */
03748 
03749 #endif /* HAL_RCC_MODULE_ENABLED */
03750 /**
03751   * @}
03752   */
03753 
03754 /**
03755   * @}
03756   */
03757 
03758 /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/