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