TUKS MCU Introductory course / TUKS-COURSE-2-LED
Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers stm32l4xx_hal_rcc_ex.c Source File

stm32l4xx_hal_rcc_ex.c

Go to the documentation of this file.
00001 /**
00002   ******************************************************************************
00003   * @file    stm32l4xx_hal_rcc_ex.c
00004   * @author  MCD Application Team
00005   * @version V1.5.1
00006   * @date    31-May-2016
00007   * @brief   Extended RCC HAL module driver.
00008   *          This file provides firmware functions to manage the following
00009   *          functionalities RCC extended peripheral:
00010   *           + Extended Peripheral Control functions
00011   *           + Extended Clock management functions
00012   *           + Extended Clock Recovery System Control functions
00013   *
00014   ******************************************************************************
00015   * @attention
00016   *
00017   * <h2><center>&copy; COPYRIGHT(c) 2016 STMicroelectronics</center></h2>
00018   *
00019   * Redistribution and use in source and binary forms, with or without modification,
00020   * are permitted provided that the following conditions are met:
00021   *   1. Redistributions of source code must retain the above copyright notice,
00022   *      this list of conditions and the following disclaimer.
00023   *   2. Redistributions in binary form must reproduce the above copyright notice,
00024   *      this list of conditions and the following disclaimer in the documentation
00025   *      and/or other materials provided with the distribution.
00026   *   3. Neither the name of STMicroelectronics nor the names of its contributors
00027   *      may be used to endorse or promote products derived from this software
00028   *      without specific prior written permission.
00029   *
00030   * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
00031   * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
00032   * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
00033   * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
00034   * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
00035   * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
00036   * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
00037   * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
00038   * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
00039   * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
00040   *
00041   ******************************************************************************
00042   */
00043 
00044 /* Includes ------------------------------------------------------------------*/
00045 #include "stm32l4xx_hal.h"
00046 
00047 /** @addtogroup STM32L4xx_HAL_Driver
00048   * @{
00049   */
00050 
00051 /** @defgroup RCCEx RCCEx
00052   * @brief RCC Extended HAL module driver
00053   * @{
00054   */
00055 
00056 #ifdef HAL_RCC_MODULE_ENABLED
00057 
00058 /* Private typedef -----------------------------------------------------------*/
00059 /* Private defines -----------------------------------------------------------*/
00060 /** @defgroup RCCEx_Private_Constants RCCEx Private Constants
00061  * @{
00062  */
00063 #define PLLSAI1_TIMEOUT_VALUE    ((uint32_t)2U)    /* 2 ms (minimum Tick + 1) */
00064 #define PLLSAI2_TIMEOUT_VALUE    ((uint32_t)2U)    /* 2 ms (minimum Tick + 1) */
00065 #define PLL_TIMEOUT_VALUE        ((uint32_t)2U)    /* 2 ms (minimum Tick + 1) */
00066 
00067 #define DIVIDER_P_UPDATE          0U
00068 #define DIVIDER_Q_UPDATE          1U
00069 #define DIVIDER_R_UPDATE          2U
00070 
00071 #define __LSCO_CLK_ENABLE()       __HAL_RCC_GPIOA_CLK_ENABLE()
00072 #define LSCO_GPIO_PORT            GPIOA
00073 #define LSCO_PIN                  GPIO_PIN_2
00074 /**
00075   * @}
00076   */
00077 
00078 /* Private macros ------------------------------------------------------------*/
00079 /* Private variables ---------------------------------------------------------*/
00080 /* Private function prototypes -----------------------------------------------*/
00081 /** @defgroup RCCEx_Private_Functions RCCEx Private Functions
00082  * @{
00083  */
00084 static HAL_StatusTypeDef RCCEx_PLLSAI1_Config(RCC_PLLSAI1InitTypeDef *PllSai1, uint32_t Divider);
00085 
00086 #if defined(RCC_PLLSAI2_SUPPORT)
00087 
00088 static HAL_StatusTypeDef RCCEx_PLLSAI2_Config(RCC_PLLSAI2InitTypeDef *PllSai2, uint32_t Divider);
00089 
00090 #endif /* RCC_PLLSAI2_SUPPORT */
00091 
00092 /**
00093   * @}
00094   */
00095 
00096 /* Exported functions --------------------------------------------------------*/
00097 
00098 /** @defgroup RCCEx_Exported_Functions RCCEx Exported Functions
00099   * @{
00100   */
00101 
00102 /** @defgroup RCCEx_Exported_Functions_Group1 Extended Peripheral Control functions 
00103  *  @brief  Extended Peripheral Control functions
00104  *
00105 @verbatim
00106  ===============================================================================
00107                 ##### Extended Peripheral Control functions  #####
00108  ===============================================================================
00109     [..]
00110     This subsection provides a set of functions allowing to control the RCC Clocks
00111     frequencies.
00112     [..]
00113     (@) Important note: Care must be taken when HAL_RCCEx_PeriphCLKConfig() is used to
00114         select the RTC clock source; in this case the Backup domain will be reset in
00115         order to modify the RTC Clock source, as consequence RTC registers (including
00116         the backup registers) are set to their reset values.
00117 
00118 @endverbatim
00119   * @{
00120   */
00121 /**
00122   * @brief  Initialize the RCC extended peripherals clocks according to the specified
00123   *         parameters in the RCC_PeriphCLKInitTypeDef.
00124   * @param  PeriphClkInit  pointer to an RCC_PeriphCLKInitTypeDef structure that
00125   *         contains a field PeriphClockSelection which can be a combination of the following values:
00126   *            @arg @ref RCC_PERIPHCLK_RTC  RTC peripheral clock
00127   *            @arg @ref RCC_PERIPHCLK_ADC  ADC peripheral clock
00128   @if STM32L486xx
00129   *            @arg @ref RCC_PERIPHCLK_DFSDM1  DFSDM1 peripheral clock (only for devices with DFSDM1)
00130   @endif
00131   *            @arg @ref RCC_PERIPHCLK_I2C1  I2C1 peripheral clock
00132   *            @arg @ref RCC_PERIPHCLK_I2C2  I2C2 peripheral clock
00133   *            @arg @ref RCC_PERIPHCLK_I2C3  I2C3 peripheral clock
00134   *            @arg @ref RCC_PERIPHCLK_LPTIM1  LPTIM1 peripheral clock
00135   *            @arg @ref RCC_PERIPHCLK_LPTIM2  LPTIM2 peripheral clock
00136   *            @arg @ref RCC_PERIPHCLK_LPUART1  LPUART1 peripheral clock
00137   *            @arg @ref RCC_PERIPHCLK_RNG  RNG peripheral clock
00138   *            @arg @ref RCC_PERIPHCLK_SAI1  SAI1 peripheral clock
00139   @if STM32L486xx
00140   *            @arg @ref RCC_PERIPHCLK_SAI2  SAI2 peripheral clock (only for devices with SAI2)
00141   @endif
00142   *            @arg @ref RCC_PERIPHCLK_SDMMC1  SDMMC1 peripheral clock
00143   @if STM32L443xx
00144   *            @arg @ref RCC_PERIPHCLK_SWPMI1  SWPMI1 peripheral clock (only for devices with SWPMI1)
00145   @endif
00146   @if STM32L486xx
00147   *            @arg @ref RCC_PERIPHCLK_SWPMI1  SWPMI1 peripheral clock (only for devices with SWPMI1)
00148   @endif
00149   *            @arg @ref RCC_PERIPHCLK_USART1  USART1 peripheral clock
00150   *            @arg @ref RCC_PERIPHCLK_USART2  USART1 peripheral clock
00151   *            @arg @ref RCC_PERIPHCLK_USART3  USART1 peripheral clock
00152   @if STM32L486xx
00153   *            @arg @ref RCC_PERIPHCLK_UART4  USART1 peripheral clock (only for devices with UART4)
00154   *            @arg @ref RCC_PERIPHCLK_UART5  USART1 peripheral clock (only for devices with UART5)
00155   *            @arg @ref RCC_PERIPHCLK_USB  USB peripheral clock (only for devices with USB)
00156   @endif
00157   *
00158   * @note   Care must be taken when HAL_RCCEx_PeriphCLKConfig() is used to select
00159   *         the RTC clock source: in this case the access to Backup domain is enabled.
00160   *
00161   * @retval HAL status
00162   */
00163 HAL_StatusTypeDef HAL_RCCEx_PeriphCLKConfig(RCC_PeriphCLKInitTypeDef  *PeriphClkInit)
00164 {
00165   uint32_t tmpregister = 0;
00166   uint32_t tickstart = 0U;
00167   HAL_StatusTypeDef ret = HAL_OK;      /* Intermediate status */
00168   HAL_StatusTypeDef status = HAL_OK;   /* Final status */
00169 
00170   /* Check the parameters */
00171   assert_param(IS_RCC_PERIPHCLOCK(PeriphClkInit->PeriphClockSelection));
00172 
00173   /*-------------------------- SAI1 clock source configuration ---------------------*/
00174   if((((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_SAI1) == RCC_PERIPHCLK_SAI1))
00175   {
00176     /* Check the parameters */
00177     assert_param(IS_RCC_SAI1CLK(PeriphClkInit->Sai1ClockSelection));
00178 
00179     switch(PeriphClkInit->Sai1ClockSelection)
00180     {
00181     case RCC_SAI1CLKSOURCE_PLL:      /* PLL is used as clock source for SAI1*/
00182       /* Enable SAI Clock output generated form System PLL . */
00183 #if defined(RCC_PLLSAI2_SUPPORT)
00184       __HAL_RCC_PLLCLKOUT_ENABLE(RCC_PLL_SAI3CLK);
00185 #else
00186       __HAL_RCC_PLLCLKOUT_ENABLE(RCC_PLL_SAI2CLK);
00187 #endif /* RCC_PLLSAI2_SUPPORT */
00188       /* SAI1 clock source config set later after clock selection check */
00189       break;
00190 
00191     case RCC_SAI1CLKSOURCE_PLLSAI1: /* PLLSAI1 is used as clock source for SAI1*/
00192       /* PLLSAI1 input clock, parameters M, N & P configuration and clock output (PLLSAI1ClockOut) */
00193       ret = RCCEx_PLLSAI1_Config(&(PeriphClkInit->PLLSAI1), DIVIDER_P_UPDATE);
00194       /* SAI1 clock source config set later after clock selection check */
00195       break;
00196 
00197 #if defined(RCC_PLLSAI2_SUPPORT)
00198 
00199     case RCC_SAI1CLKSOURCE_PLLSAI2:  /* PLLSAI2 is used as clock source for SAI1*/
00200       /* PLLSAI2 input clock, parameters M, N & P configuration clock output (PLLSAI2ClockOut) */
00201       ret = RCCEx_PLLSAI2_Config(&(PeriphClkInit->PLLSAI2), DIVIDER_P_UPDATE);
00202       /* SAI1 clock source config set later after clock selection check */
00203       break;
00204 
00205 #endif /* RCC_PLLSAI2_SUPPORT */
00206 
00207     case RCC_SAI1CLKSOURCE_PIN:      /* External clock is used as source of SAI1 clock*/
00208       /* SAI1 clock source config set later after clock selection check */
00209       break;
00210 
00211     default:
00212       ret = HAL_ERROR;
00213       break;
00214     }
00215 
00216     if(ret == HAL_OK)
00217     {
00218       /* Set the source of SAI1 clock*/
00219       __HAL_RCC_SAI1_CONFIG(PeriphClkInit->Sai1ClockSelection);
00220     }
00221     else
00222     {
00223       /* set overall return value */
00224       status = ret;
00225     }
00226   }
00227 
00228 #if defined(SAI2)
00229 
00230   /*-------------------------- SAI2 clock source configuration ---------------------*/
00231   if((((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_SAI2) == RCC_PERIPHCLK_SAI2))
00232   {
00233     /* Check the parameters */
00234     assert_param(IS_RCC_SAI2CLK(PeriphClkInit->Sai2ClockSelection));
00235 
00236     switch(PeriphClkInit->Sai2ClockSelection)
00237     {
00238     case RCC_SAI2CLKSOURCE_PLL:      /* PLL is used as clock source for SAI2*/
00239       /* Enable SAI Clock output generated form System PLL . */
00240       __HAL_RCC_PLLCLKOUT_ENABLE(RCC_PLL_SAI3CLK);
00241       /* SAI2 clock source config set later after clock selection check */
00242       break;
00243 
00244     case RCC_SAI2CLKSOURCE_PLLSAI1: /* PLLSAI1 is used as clock source for SAI2*/
00245       /* PLLSAI1 input clock, parameters M, N & P configuration and clock output (PLLSAI1ClockOut) */
00246       ret = RCCEx_PLLSAI1_Config(&(PeriphClkInit->PLLSAI1), DIVIDER_P_UPDATE);
00247       /* SAI2 clock source config set later after clock selection check */
00248       break;
00249 
00250     case RCC_SAI2CLKSOURCE_PLLSAI2:  /* PLLSAI2 is used as clock source for SAI2*/
00251       /* PLLSAI2 input clock, parameters M, N & P configuration and clock output (PLLSAI2ClockOut) */
00252       ret = RCCEx_PLLSAI2_Config(&(PeriphClkInit->PLLSAI2), DIVIDER_P_UPDATE);
00253       /* SAI2 clock source config set later after clock selection check */
00254       break;
00255 
00256     case RCC_SAI2CLKSOURCE_PIN:      /* External clock is used as source of SAI2 clock*/
00257       /* SAI2 clock source config set later after clock selection check */
00258       break;
00259 
00260     default:
00261       ret = HAL_ERROR;
00262       break;
00263     }
00264 
00265     if(ret == HAL_OK)
00266     {
00267       /* Set the source of SAI2 clock*/
00268       __HAL_RCC_SAI2_CONFIG(PeriphClkInit->Sai2ClockSelection);
00269     }
00270     else
00271     {
00272       /* set overall return value */
00273       status = ret;
00274     }
00275   }
00276 #endif /* SAI2 */
00277 
00278   /*-------------------------- RTC clock source configuration ----------------------*/
00279   if((PeriphClkInit->PeriphClockSelection & RCC_PERIPHCLK_RTC) == RCC_PERIPHCLK_RTC)
00280   {
00281     FlagStatus       pwrclkchanged = RESET;
00282     
00283     /* Check for RTC Parameters used to output RTCCLK */
00284     assert_param(IS_RCC_RTCCLKSOURCE(PeriphClkInit->RTCClockSelection));
00285 
00286     /* Enable Power Clock */
00287     if(__HAL_RCC_PWR_IS_CLK_DISABLED())
00288     {
00289       __HAL_RCC_PWR_CLK_ENABLE();
00290       pwrclkchanged = SET;
00291     }
00292       
00293     /* Enable write access to Backup domain */
00294     SET_BIT(PWR->CR1, PWR_CR1_DBP);
00295 
00296     /* Wait for Backup domain Write protection disable */
00297     tickstart = HAL_GetTick();
00298 
00299     while((PWR->CR1 & PWR_CR1_DBP) == RESET)
00300     {
00301       if((HAL_GetTick() - tickstart) > RCC_DBP_TIMEOUT_VALUE)
00302       {
00303         ret = HAL_TIMEOUT;
00304         break;
00305       }
00306     }
00307 
00308     if(ret == HAL_OK)
00309     { 
00310       /* Reset the Backup domain only if the RTC Clock source selection is modified from default */
00311       tmpregister = READ_BIT(RCC->BDCR, RCC_BDCR_RTCSEL);
00312       
00313       if((tmpregister != RCC_RTCCLKSOURCE_NO_CLK) && (tmpregister != PeriphClkInit->RTCClockSelection))
00314       {
00315         /* Store the content of BDCR register before the reset of Backup Domain */
00316         tmpregister = READ_BIT(RCC->BDCR, ~(RCC_BDCR_RTCSEL));
00317         /* RTC Clock selection can be changed only if the Backup Domain is reset */
00318         __HAL_RCC_BACKUPRESET_FORCE();
00319         __HAL_RCC_BACKUPRESET_RELEASE();
00320         /* Restore the Content of BDCR register */
00321         RCC->BDCR = tmpregister;
00322       }
00323 
00324       /* Wait for LSE reactivation if LSE was enable prior to Backup Domain reset */
00325       if (HAL_IS_BIT_SET(tmpregister, RCC_BDCR_LSEON))
00326       {
00327         /* Get Start Tick*/
00328         tickstart = HAL_GetTick();
00329 
00330         /* Wait till LSE is ready */
00331         while(READ_BIT(RCC->BDCR, RCC_BDCR_LSERDY) == RESET)
00332         {
00333           if((HAL_GetTick() - tickstart) > RCC_LSE_TIMEOUT_VALUE)
00334           {
00335             ret = HAL_TIMEOUT;
00336             break;
00337           }
00338         }
00339       }
00340       
00341       if(ret == HAL_OK)
00342       {
00343         /* Apply new RTC clock source selection */
00344         __HAL_RCC_RTC_CONFIG(PeriphClkInit->RTCClockSelection);
00345       }
00346       else
00347       {
00348         /* set overall return value */
00349         status = ret;
00350       }
00351     }
00352     else
00353     {
00354       /* set overall return value */
00355       status = ret;
00356     }
00357 
00358     /* Restore clock configuration if changed */
00359     if(pwrclkchanged == SET)
00360     {
00361       __HAL_RCC_PWR_CLK_DISABLE();
00362     }
00363   }
00364 
00365   /*-------------------------- USART1 clock source configuration -------------------*/
00366   if(((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_USART1) == RCC_PERIPHCLK_USART1)
00367   {
00368     /* Check the parameters */
00369     assert_param(IS_RCC_USART1CLKSOURCE(PeriphClkInit->Usart1ClockSelection));
00370 
00371     /* Configure the USART1 clock source */
00372     __HAL_RCC_USART1_CONFIG(PeriphClkInit->Usart1ClockSelection);
00373   }
00374 
00375   /*-------------------------- USART2 clock source configuration -------------------*/
00376   if(((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_USART2) == RCC_PERIPHCLK_USART2)
00377   {
00378     /* Check the parameters */
00379     assert_param(IS_RCC_USART2CLKSOURCE(PeriphClkInit->Usart2ClockSelection));
00380 
00381     /* Configure the USART2 clock source */
00382     __HAL_RCC_USART2_CONFIG(PeriphClkInit->Usart2ClockSelection);
00383   }
00384 
00385 #if defined(USART3)
00386 
00387   /*-------------------------- USART3 clock source configuration -------------------*/
00388   if(((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_USART3) == RCC_PERIPHCLK_USART3)
00389   {
00390     /* Check the parameters */
00391     assert_param(IS_RCC_USART3CLKSOURCE(PeriphClkInit->Usart3ClockSelection));
00392 
00393     /* Configure the USART3 clock source */
00394     __HAL_RCC_USART3_CONFIG(PeriphClkInit->Usart3ClockSelection);
00395   }
00396 
00397 #endif /* USART3 */
00398 
00399 #if defined(UART4)
00400 
00401   /*-------------------------- UART4 clock source configuration --------------------*/
00402   if(((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_UART4) == RCC_PERIPHCLK_UART4)
00403   {
00404     /* Check the parameters */
00405     assert_param(IS_RCC_UART4CLKSOURCE(PeriphClkInit->Uart4ClockSelection));
00406 
00407     /* Configure the UART4 clock source */
00408     __HAL_RCC_UART4_CONFIG(PeriphClkInit->Uart4ClockSelection);
00409   }
00410 
00411 #endif /* UART4 */
00412 
00413 #if defined(UART5)
00414 
00415   /*-------------------------- UART5 clock source configuration --------------------*/
00416   if(((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_UART5) == RCC_PERIPHCLK_UART5)
00417   {
00418     /* Check the parameters */
00419     assert_param(IS_RCC_UART5CLKSOURCE(PeriphClkInit->Uart5ClockSelection));
00420 
00421     /* Configure the UART5 clock source */
00422     __HAL_RCC_UART5_CONFIG(PeriphClkInit->Uart5ClockSelection);
00423   }
00424 
00425 #endif /* UART5 */
00426 
00427   /*-------------------------- LPUART1 clock source configuration ------------------*/
00428   if(((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_LPUART1) == RCC_PERIPHCLK_LPUART1)
00429   {
00430     /* Check the parameters */
00431     assert_param(IS_RCC_LPUART1CLKSOURCE(PeriphClkInit->Lpuart1ClockSelection));
00432 
00433     /* Configure the LPUAR1 clock source */
00434     __HAL_RCC_LPUART1_CONFIG(PeriphClkInit->Lpuart1ClockSelection);
00435   }
00436 
00437   /*-------------------------- LPTIM1 clock source configuration -------------------*/
00438   if(((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_LPTIM1) == (RCC_PERIPHCLK_LPTIM1))
00439   {
00440     assert_param(IS_RCC_LPTIM1CLK(PeriphClkInit->Lptim1ClockSelection));
00441     __HAL_RCC_LPTIM1_CONFIG(PeriphClkInit->Lptim1ClockSelection);
00442   }
00443 
00444   /*-------------------------- LPTIM2 clock source configuration -------------------*/
00445   if(((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_LPTIM2) == (RCC_PERIPHCLK_LPTIM2))
00446   {
00447     assert_param(IS_RCC_LPTIM2CLK(PeriphClkInit->Lptim2ClockSelection));
00448     __HAL_RCC_LPTIM2_CONFIG(PeriphClkInit->Lptim2ClockSelection);
00449   }
00450 
00451   /*-------------------------- I2C1 clock source configuration ---------------------*/
00452   if(((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_I2C1) == RCC_PERIPHCLK_I2C1)
00453   {
00454     /* Check the parameters */
00455     assert_param(IS_RCC_I2C1CLKSOURCE(PeriphClkInit->I2c1ClockSelection));
00456 
00457     /* Configure the I2C1 clock source */
00458     __HAL_RCC_I2C1_CONFIG(PeriphClkInit->I2c1ClockSelection);
00459   }
00460 
00461 #if defined(I2C2)  
00462 
00463   /*-------------------------- I2C2 clock source configuration ---------------------*/
00464   if(((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_I2C2) == RCC_PERIPHCLK_I2C2)
00465   {
00466     /* Check the parameters */
00467     assert_param(IS_RCC_I2C2CLKSOURCE(PeriphClkInit->I2c2ClockSelection));
00468 
00469     /* Configure the I2C2 clock source */
00470     __HAL_RCC_I2C2_CONFIG(PeriphClkInit->I2c2ClockSelection);
00471   }
00472 
00473 #endif /* I2C2 */
00474 
00475   /*-------------------------- I2C3 clock source configuration ---------------------*/
00476   if(((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_I2C3) == RCC_PERIPHCLK_I2C3)
00477   {
00478     /* Check the parameters */
00479     assert_param(IS_RCC_I2C3CLKSOURCE(PeriphClkInit->I2c3ClockSelection));
00480 
00481     /* Configure the I2C3 clock source */
00482     __HAL_RCC_I2C3_CONFIG(PeriphClkInit->I2c3ClockSelection);
00483   }
00484 
00485 #if defined(USB_OTG_FS) || defined(USB)
00486 
00487   /*-------------------------- USB clock source configuration ----------------------*/
00488   if(((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_USB) == (RCC_PERIPHCLK_USB))
00489   {
00490     assert_param(IS_RCC_USBCLKSOURCE(PeriphClkInit->UsbClockSelection));
00491     __HAL_RCC_USB_CONFIG(PeriphClkInit->UsbClockSelection);
00492 
00493     if(PeriphClkInit->UsbClockSelection == RCC_USBCLKSOURCE_PLL)
00494     {
00495       /* Enable PLL48M1CLK output */
00496       __HAL_RCC_PLLCLKOUT_ENABLE(RCC_PLL_48M1CLK);
00497     }
00498     else if(PeriphClkInit->UsbClockSelection == RCC_USBCLKSOURCE_PLLSAI1)
00499     {
00500       /* PLLSAI1 input clock, parameters M, N & Q configuration and clock output (PLLSAI1ClockOut) */
00501       ret = RCCEx_PLLSAI1_Config(&(PeriphClkInit->PLLSAI1), DIVIDER_Q_UPDATE);
00502       
00503       if(ret != HAL_OK)
00504       {
00505         /* set overall return value */
00506         status = ret;
00507       }
00508     }
00509   }
00510 
00511 #endif /* USB_OTG_FS || USB */
00512 
00513 #if defined(SDMMC1)
00514 
00515   /*-------------------------- SDMMC1 clock source configuration -------------------*/
00516   if(((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_SDMMC1) == (RCC_PERIPHCLK_SDMMC1))
00517   {
00518     assert_param(IS_RCC_SDMMC1CLKSOURCE(PeriphClkInit->Sdmmc1ClockSelection));
00519     __HAL_RCC_SDMMC1_CONFIG(PeriphClkInit->Sdmmc1ClockSelection);
00520     
00521     if(PeriphClkInit->Sdmmc1ClockSelection == RCC_SDMMC1CLKSOURCE_PLL)
00522     {
00523       /* Enable PLL48M1CLK output */
00524       __HAL_RCC_PLLCLKOUT_ENABLE(RCC_PLL_48M1CLK);
00525     }
00526     else if(PeriphClkInit->Sdmmc1ClockSelection == RCC_SDMMC1CLKSOURCE_PLLSAI1)
00527     {
00528       /* PLLSAI1 input clock, parameters M, N & Q configuration and clock output (PLLSAI1ClockOut) */
00529       ret = RCCEx_PLLSAI1_Config(&(PeriphClkInit->PLLSAI1), DIVIDER_Q_UPDATE);
00530       
00531       if(ret != HAL_OK)
00532       {
00533         /* set overall return value */
00534         status = ret;
00535       }
00536     }
00537   }
00538 
00539 #endif /* SDMMC1 */
00540 
00541   /*-------------------------- RNG clock source configuration ----------------------*/
00542   if(((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_RNG) == (RCC_PERIPHCLK_RNG))
00543   {
00544     assert_param(IS_RCC_RNGCLKSOURCE(PeriphClkInit->RngClockSelection));
00545     __HAL_RCC_RNG_CONFIG(PeriphClkInit->RngClockSelection);
00546 
00547     if(PeriphClkInit->RngClockSelection == RCC_RNGCLKSOURCE_PLL)
00548     {
00549       /* Enable PLL48M1CLK output */
00550       __HAL_RCC_PLLCLKOUT_ENABLE(RCC_PLL_48M1CLK);
00551     }
00552     else if(PeriphClkInit->RngClockSelection == RCC_RNGCLKSOURCE_PLLSAI1)
00553     {
00554       /* PLLSAI1 input clock, parameters M, N & Q configuration and clock output (PLLSAI1ClockOut) */
00555       ret = RCCEx_PLLSAI1_Config(&(PeriphClkInit->PLLSAI1), DIVIDER_Q_UPDATE);
00556       
00557       if(ret != HAL_OK)
00558       {
00559         /* set overall return value */
00560         status = ret;
00561       }
00562     }
00563   }
00564 
00565   /*-------------------------- ADC clock source configuration ----------------------*/
00566   if(((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_ADC) == RCC_PERIPHCLK_ADC)
00567   {
00568     /* Check the parameters */
00569     assert_param(IS_RCC_ADCCLKSOURCE(PeriphClkInit->AdcClockSelection));
00570 
00571     /* Configure the ADC interface clock source */
00572     __HAL_RCC_ADC_CONFIG(PeriphClkInit->AdcClockSelection);
00573     
00574     if(PeriphClkInit->AdcClockSelection == RCC_ADCCLKSOURCE_PLLSAI1)
00575     {
00576       /* PLLSAI1 input clock, parameters M, N & R configuration and clock output (PLLSAI1ClockOut) */
00577       ret = RCCEx_PLLSAI1_Config(&(PeriphClkInit->PLLSAI1), DIVIDER_R_UPDATE);
00578 
00579       if(ret != HAL_OK)
00580       {
00581         /* set overall return value */
00582         status = ret;
00583       }
00584     }
00585 
00586 #if defined(STM32L471xx) || defined(STM32L475xx) || defined(STM32L476xx) || defined(STM32L485xx) || defined(STM32L486xx)
00587 
00588     else if(PeriphClkInit->AdcClockSelection == RCC_ADCCLKSOURCE_PLLSAI2)
00589     {
00590       /* PLLSAI2 input clock, parameters M, N & R configuration and clock output (PLLSAI2ClockOut) */
00591       ret = RCCEx_PLLSAI2_Config(&(PeriphClkInit->PLLSAI2), DIVIDER_R_UPDATE);
00592       
00593       if(ret != HAL_OK)
00594       {
00595         /* set overall return value */
00596         status = ret;
00597       }
00598     }
00599 
00600 #endif /* STM32L471xx || STM32L475xx || STM32L476xx || STM32L485xx || STM32L486xx */
00601 
00602   }
00603 
00604 #if defined(SWPMI1)
00605 
00606   /*-------------------------- SWPMI1 clock source configuration -------------------*/
00607   if(((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_SWPMI1) == RCC_PERIPHCLK_SWPMI1)
00608   {
00609     /* Check the parameters */
00610     assert_param(IS_RCC_SWPMI1CLKSOURCE(PeriphClkInit->Swpmi1ClockSelection));
00611 
00612     /* Configure the SWPMI1 clock source */
00613     __HAL_RCC_SWPMI1_CONFIG(PeriphClkInit->Swpmi1ClockSelection);
00614   }
00615 
00616 #endif /* SWPMI1 */
00617 
00618 #if defined(DFSDM1_Filter0)
00619 
00620   /*-------------------------- DFSDM1 clock source configuration -------------------*/
00621   if(((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_DFSDM1) == RCC_PERIPHCLK_DFSDM1)
00622   {
00623     /* Check the parameters */
00624     assert_param(IS_RCC_DFSDM1CLKSOURCE(PeriphClkInit->Dfsdm1ClockSelection));
00625 
00626     /* Configure the DFSDM1 interface clock source */
00627     __HAL_RCC_DFSDM1_CONFIG(PeriphClkInit->Dfsdm1ClockSelection);
00628   }
00629 
00630 #endif /* DFSDM1_Filter0 */
00631 
00632   return status;
00633 }
00634 
00635 /**
00636   * @brief  Get the RCC_ClkInitStruct according to the internal RCC configuration registers.
00637   * @param  PeriphClkInit  pointer to an RCC_PeriphCLKInitTypeDef structure that
00638   *         returns the configuration information for the Extended Peripherals
00639   *         clocks(SAI1, SAI2, LPTIM1, LPTIM2, I2C1, I2C2, I2C3, LPUART,
00640   *         USART1, USART2, USART3, UART4, UART5, RTC, ADCx, DFSDMx, SWPMI1, USB, SDMMC1 and RNG).
00641   * @retval None
00642   */
00643 void HAL_RCCEx_GetPeriphCLKConfig(RCC_PeriphCLKInitTypeDef  *PeriphClkInit)
00644 {
00645   /* Set all possible values for the extended clock type parameter------------*/
00646 
00647 #if defined(STM32L431xx)
00648 
00649   PeriphClkInit->PeriphClockSelection = RCC_PERIPHCLK_USART1  | RCC_PERIPHCLK_USART2 | RCC_PERIPHCLK_USART3 |                                               \
00650                                         RCC_PERIPHCLK_LPUART1 | RCC_PERIPHCLK_I2C1   | RCC_PERIPHCLK_I2C2   | RCC_PERIPHCLK_I2C3   |                        \
00651                                         RCC_PERIPHCLK_LPTIM1  | RCC_PERIPHCLK_LPTIM2 | RCC_PERIPHCLK_SAI1   |                                               \
00652                                         RCC_PERIPHCLK_SDMMC1  | RCC_PERIPHCLK_RNG    | RCC_PERIPHCLK_ADC    | RCC_PERIPHCLK_SWPMI1 |                        \
00653                                         RCC_PERIPHCLK_RTC ;
00654 
00655 #elif defined(STM32L432xx) || defined(STM32L442xx)
00656 
00657   PeriphClkInit->PeriphClockSelection = RCC_PERIPHCLK_USART1  | RCC_PERIPHCLK_USART2 |                                                                      \
00658                                         RCC_PERIPHCLK_LPUART1 | RCC_PERIPHCLK_I2C1   |                        RCC_PERIPHCLK_I2C3   |                        \
00659                                         RCC_PERIPHCLK_LPTIM1  | RCC_PERIPHCLK_LPTIM2 | RCC_PERIPHCLK_SAI1   |                        RCC_PERIPHCLK_USB    | \
00660                                                                 RCC_PERIPHCLK_RNG    | RCC_PERIPHCLK_ADC    | RCC_PERIPHCLK_SWPMI1 |                        \
00661                                         RCC_PERIPHCLK_RTC ;
00662 
00663 #elif defined(STM32L433xx) || defined(STM32L443xx)
00664 
00665   PeriphClkInit->PeriphClockSelection = RCC_PERIPHCLK_USART1  | RCC_PERIPHCLK_USART2 | RCC_PERIPHCLK_USART3 |                                               \
00666                                         RCC_PERIPHCLK_LPUART1 | RCC_PERIPHCLK_I2C1   | RCC_PERIPHCLK_I2C2   | RCC_PERIPHCLK_I2C3   |                        \
00667                                         RCC_PERIPHCLK_LPTIM1  | RCC_PERIPHCLK_LPTIM2 | RCC_PERIPHCLK_SAI1   |                        RCC_PERIPHCLK_USB    | \
00668                                         RCC_PERIPHCLK_SDMMC1  | RCC_PERIPHCLK_RNG    | RCC_PERIPHCLK_ADC    | RCC_PERIPHCLK_SWPMI1 |                        \
00669                                         RCC_PERIPHCLK_RTC ;
00670 #elif defined(STM32L471xx)
00671 
00672   PeriphClkInit->PeriphClockSelection = RCC_PERIPHCLK_USART1  | RCC_PERIPHCLK_USART2 | RCC_PERIPHCLK_USART3 | RCC_PERIPHCLK_UART4  | RCC_PERIPHCLK_UART5  | \
00673                                         RCC_PERIPHCLK_LPUART1 | RCC_PERIPHCLK_I2C1   | RCC_PERIPHCLK_I2C2   | RCC_PERIPHCLK_I2C3                          | \
00674                                         RCC_PERIPHCLK_LPTIM1  | RCC_PERIPHCLK_LPTIM2 | RCC_PERIPHCLK_SAI1   | RCC_PERIPHCLK_SAI2                          | \
00675                                         RCC_PERIPHCLK_SDMMC1  | RCC_PERIPHCLK_RNG    | RCC_PERIPHCLK_ADC    | RCC_PERIPHCLK_SWPMI1 | RCC_PERIPHCLK_DFSDM1 | \
00676                                         RCC_PERIPHCLK_RTC ;
00677   
00678 #elif defined(STM32L475xx) || defined(STM32L476xx) || defined(STM32L485xx) || defined(STM32L486xx)
00679 
00680   PeriphClkInit->PeriphClockSelection = RCC_PERIPHCLK_USART1  | RCC_PERIPHCLK_USART2 | RCC_PERIPHCLK_USART3 | RCC_PERIPHCLK_UART4  | RCC_PERIPHCLK_UART5  | \
00681                                         RCC_PERIPHCLK_LPUART1 | RCC_PERIPHCLK_I2C1   | RCC_PERIPHCLK_I2C2   | RCC_PERIPHCLK_I2C3   |                        \
00682                                         RCC_PERIPHCLK_LPTIM1  | RCC_PERIPHCLK_LPTIM2 | RCC_PERIPHCLK_SAI1   | RCC_PERIPHCLK_SAI2   | RCC_PERIPHCLK_USB    | \
00683                                         RCC_PERIPHCLK_SDMMC1  | RCC_PERIPHCLK_RNG    | RCC_PERIPHCLK_ADC    | RCC_PERIPHCLK_SWPMI1 | RCC_PERIPHCLK_DFSDM1 | \
00684                                         RCC_PERIPHCLK_RTC ;
00685 
00686 #endif /* STM32L431xx */
00687 
00688   /* Get the PLLSAI1 Clock configuration -----------------------------------------------*/
00689   
00690   PeriphClkInit->PLLSAI1.PLLSAI1Source = (uint32_t)((RCC->PLLCFGR & RCC_PLLCFGR_PLLSRC) >> POSITION_VAL(RCC_PLLCFGR_PLLSRC));
00691   PeriphClkInit->PLLSAI1.PLLSAI1M = (uint32_t)((RCC->PLLCFGR & RCC_PLLCFGR_PLLM) >> POSITION_VAL(RCC_PLLCFGR_PLLM)) + 1U;
00692   PeriphClkInit->PLLSAI1.PLLSAI1N = (uint32_t)((RCC->PLLSAI1CFGR & RCC_PLLSAI1CFGR_PLLSAI1N) >> POSITION_VAL(RCC_PLLSAI1CFGR_PLLSAI1N));
00693   PeriphClkInit->PLLSAI1.PLLSAI1P = (uint32_t)(((RCC->PLLSAI1CFGR & RCC_PLLSAI1CFGR_PLLSAI1P) >> POSITION_VAL(RCC_PLLSAI1CFGR_PLLSAI1P)) << 4U) + 7U;
00694   PeriphClkInit->PLLSAI1.PLLSAI1Q = (uint32_t)(((RCC->PLLSAI1CFGR & RCC_PLLSAI1CFGR_PLLSAI1Q) >> POSITION_VAL(RCC_PLLSAI1CFGR_PLLSAI1Q))+1U) * 2U;
00695   PeriphClkInit->PLLSAI1.PLLSAI1R = (uint32_t)(((RCC->PLLSAI1CFGR & RCC_PLLSAI1CFGR_PLLSAI1R) >> POSITION_VAL(RCC_PLLSAI1CFGR_PLLSAI1R))+1U) * 2U;
00696 
00697 #if defined(RCC_PLLSAI2_SUPPORT)
00698 
00699   /* Get the PLLSAI2 Clock configuration -----------------------------------------------*/
00700 
00701   PeriphClkInit->PLLSAI2.PLLSAI2Source = PeriphClkInit->PLLSAI1.PLLSAI1Source;
00702   PeriphClkInit->PLLSAI2.PLLSAI2M = PeriphClkInit->PLLSAI1.PLLSAI1M;
00703   PeriphClkInit->PLLSAI2.PLLSAI2N = (uint32_t)((RCC->PLLSAI2CFGR & RCC_PLLSAI2CFGR_PLLSAI2N) >> POSITION_VAL(RCC_PLLSAI2CFGR_PLLSAI2N));
00704   PeriphClkInit->PLLSAI2.PLLSAI2P = (uint32_t)(((RCC->PLLSAI2CFGR & RCC_PLLSAI2CFGR_PLLSAI2P) >> POSITION_VAL(RCC_PLLSAI2CFGR_PLLSAI2P)) << 4U) + 7U;
00705   PeriphClkInit->PLLSAI2.PLLSAI2R = (uint32_t)(((RCC->PLLSAI2CFGR & RCC_PLLSAI2CFGR_PLLSAI2R)>> POSITION_VAL(RCC_PLLSAI2CFGR_PLLSAI2R))+1U) * 2U;
00706 
00707 #endif /* RCC_PLLSAI2_SUPPORT */
00708 
00709   /* Get the USART1 clock source ---------------------------------------------*/
00710   PeriphClkInit->Usart1ClockSelection  = __HAL_RCC_GET_USART1_SOURCE();
00711   /* Get the USART2 clock source ---------------------------------------------*/
00712   PeriphClkInit->Usart2ClockSelection  = __HAL_RCC_GET_USART2_SOURCE();
00713 
00714 #if defined(USART3)
00715   /* Get the USART3 clock source ---------------------------------------------*/
00716   PeriphClkInit->Usart3ClockSelection  = __HAL_RCC_GET_USART3_SOURCE();
00717 #endif /* USART3 */
00718 
00719 #if defined(UART4)
00720   /* Get the UART4 clock source ----------------------------------------------*/
00721   PeriphClkInit->Uart4ClockSelection   = __HAL_RCC_GET_UART4_SOURCE();
00722 #endif /* UART4 */
00723 
00724 #if defined(UART5)
00725   /* Get the UART5 clock source ----------------------------------------------*/
00726   PeriphClkInit->Uart5ClockSelection   = __HAL_RCC_GET_UART5_SOURCE();
00727 #endif /* UART5 */
00728   
00729   /* Get the LPUART1 clock source --------------------------------------------*/
00730   PeriphClkInit->Lpuart1ClockSelection = __HAL_RCC_GET_LPUART1_SOURCE();
00731 
00732   /* Get the I2C1 clock source -----------------------------------------------*/
00733   PeriphClkInit->I2c1ClockSelection    = __HAL_RCC_GET_I2C1_SOURCE();
00734 
00735 #if defined(I2C2)
00736    /* Get the I2C2 clock source ----------------------------------------------*/
00737   PeriphClkInit->I2c2ClockSelection    = __HAL_RCC_GET_I2C2_SOURCE();
00738 #endif /* I2C2 */
00739 
00740   /* Get the I2C3 clock source -----------------------------------------------*/
00741   PeriphClkInit->I2c3ClockSelection    = __HAL_RCC_GET_I2C3_SOURCE();
00742 
00743   /* Get the LPTIM1 clock source ---------------------------------------------*/
00744   PeriphClkInit->Lptim1ClockSelection  = __HAL_RCC_GET_LPTIM1_SOURCE();
00745 
00746   /* Get the LPTIM2 clock source ---------------------------------------------*/
00747   PeriphClkInit->Lptim2ClockSelection  = __HAL_RCC_GET_LPTIM2_SOURCE();
00748 
00749   /* Get the SAI1 clock source -----------------------------------------------*/
00750   PeriphClkInit->Sai1ClockSelection    = __HAL_RCC_GET_SAI1_SOURCE();
00751 
00752 #if defined(SAI2)
00753   /* Get the SAI2 clock source -----------------------------------------------*/
00754   PeriphClkInit->Sai2ClockSelection    = __HAL_RCC_GET_SAI2_SOURCE();
00755 #endif /* SAI2 */
00756 
00757   /* Get the RTC clock source ------------------------------------------------*/
00758   PeriphClkInit->RTCClockSelection     = __HAL_RCC_GET_RTC_SOURCE();
00759 
00760 #if defined(USB_OTG_FS) || defined(USB)
00761   /* Get the USB clock source ------------------------------------------------*/
00762   PeriphClkInit->UsbClockSelection   = __HAL_RCC_GET_USB_SOURCE();
00763 #endif /* USB_OTG_FS || USB */
00764 
00765 #if defined(SDMMC1)
00766   /* Get the SDMMC1 clock source ---------------------------------------------*/
00767   PeriphClkInit->Sdmmc1ClockSelection   = __HAL_RCC_GET_SDMMC1_SOURCE();
00768 #endif /* SDMMC1 */
00769 
00770   /* Get the RNG clock source ------------------------------------------------*/
00771   PeriphClkInit->RngClockSelection   = __HAL_RCC_GET_RNG_SOURCE();
00772 
00773   /* Get the ADC clock source ------------------------------------------------*/
00774   PeriphClkInit->AdcClockSelection     = __HAL_RCC_GET_ADC_SOURCE();
00775 
00776 #if defined(SWPMI1)
00777   /* Get the SWPMI1 clock source ---------------------------------------------*/
00778   PeriphClkInit->Swpmi1ClockSelection  = __HAL_RCC_GET_SWPMI1_SOURCE();
00779 #endif /* SWPMI1 */
00780 
00781 #if defined(DFSDM1_Filter0)
00782   /* Get the DFSDM1 clock source ---------------------------------------------*/
00783   PeriphClkInit->Dfsdm1ClockSelection  = __HAL_RCC_GET_DFSDM1_SOURCE();
00784 #endif /* DFSDM1_Filter0 */
00785 }
00786 
00787 /**
00788   * @brief  Return the peripheral clock frequency for peripherals with clock source from PLLSAIs 
00789   * @note   Return 0 if peripheral clock identifier not managed by this API
00790   * @param  PeriphClk  Peripheral clock identifier
00791   *         This parameter can be one of the following values:
00792   *            @arg @ref RCC_PERIPHCLK_RTC  RTC peripheral clock
00793   *            @arg @ref RCC_PERIPHCLK_ADC  ADC peripheral clock
00794   @if STM32L486xx
00795   *            @arg @ref RCC_PERIPHCLK_DFSDM1  DFSDM1 peripheral clock (only for devices with DFSDM)
00796   @endif
00797   *            @arg @ref RCC_PERIPHCLK_I2C1  I2C1 peripheral clock
00798   *            @arg @ref RCC_PERIPHCLK_I2C2  I2C2 peripheral clock
00799   *            @arg @ref RCC_PERIPHCLK_I2C3  I2C3 peripheral clock
00800   *            @arg @ref RCC_PERIPHCLK_LPTIM1  LPTIM1 peripheral clock
00801   *            @arg @ref RCC_PERIPHCLK_LPTIM2  LPTIM2 peripheral clock
00802   *            @arg @ref RCC_PERIPHCLK_LPUART1  LPUART1 peripheral clock
00803   *            @arg @ref RCC_PERIPHCLK_RNG  RNG peripheral clock
00804   *            @arg @ref RCC_PERIPHCLK_SAI1  SAI1 peripheral clock
00805   @if STM32L486xx
00806   *            @arg @ref RCC_PERIPHCLK_SAI2  SAI2 peripheral clock (only for devices with SAI2)
00807   @endif
00808   *            @arg @ref RCC_PERIPHCLK_SDMMC1  SDMMC1 peripheral clock
00809   *            @arg @ref RCC_PERIPHCLK_SWPMI1  SWPMI1 peripheral clock
00810   *            @arg @ref RCC_PERIPHCLK_USART1  USART1 peripheral clock
00811   *            @arg @ref RCC_PERIPHCLK_USART2  USART1 peripheral clock
00812   *            @arg @ref RCC_PERIPHCLK_USART3  USART1 peripheral clock
00813   @if STM32L486xx
00814   *            @arg @ref RCC_PERIPHCLK_UART4  UART4 peripheral clock (only for devices with UART4)
00815   *            @arg @ref RCC_PERIPHCLK_UART5  UART5 peripheral clock (only for devices with UART5)
00816   *            @arg @ref RCC_PERIPHCLK_USB  USB peripheral clock (only for devices with USB)
00817   @endif
00818   * @retval Frequency in Hz
00819   */
00820 uint32_t HAL_RCCEx_GetPeriphCLKFreq(uint32_t PeriphClk)
00821 {
00822   uint32_t frequency = 0U;
00823   uint32_t srcclk = 0U;
00824   uint32_t pllvco = 0U, plln = 0U, pllp = 0U;
00825 
00826   /* Check the parameters */
00827   assert_param(IS_RCC_PERIPHCLOCK(PeriphClk));
00828 
00829   if(PeriphClk == RCC_PERIPHCLK_RTC)
00830   {
00831     /* Get the current RTC source */
00832     srcclk = __HAL_RCC_GET_RTC_SOURCE();
00833 
00834     /* Check if LSE is ready and if RTC clock selection is LSE */
00835     if ((srcclk == RCC_RTCCLKSOURCE_LSE) && (HAL_IS_BIT_SET(RCC->BDCR, RCC_BDCR_LSERDY)))
00836     {
00837       frequency = LSE_VALUE;
00838     }
00839     /* Check if LSI is ready and if RTC clock selection is LSI */
00840     else if ((srcclk == RCC_RTCCLKSOURCE_LSI) && (HAL_IS_BIT_SET(RCC->CSR, RCC_CSR_LSIRDY)))
00841     {
00842       frequency = LSI_VALUE;
00843     }
00844     /* Check if HSE is ready  and if RTC clock selection is HSI_DIV32*/
00845     else if ((srcclk == RCC_RTCCLKSOURCE_HSE_DIV32) && (HAL_IS_BIT_SET(RCC->CR, RCC_CR_HSERDY)))
00846     {
00847       frequency = HSE_VALUE / 32;
00848     }
00849     /* Clock not enabled for RTC*/
00850     else
00851     {
00852       frequency = 0U;
00853     }
00854   }
00855   else
00856   {
00857     /* Other external peripheral clock source than RTC */
00858     
00859     /* Compute PLL clock input */
00860     if(__HAL_RCC_GET_PLL_OSCSOURCE() == RCC_PLLSOURCE_MSI)        /* MSI ? */
00861     {
00862       if(HAL_IS_BIT_SET(RCC->CR, RCC_CR_MSIRDY))
00863       {
00864         pllvco = (1U << ((__HAL_RCC_GET_MSI_RANGE() >> 4U) - 4U)) * 1000000U;
00865       }
00866       else
00867       {
00868         pllvco = 0U;
00869       }
00870     }
00871     else if(__HAL_RCC_GET_PLL_OSCSOURCE() == RCC_PLLSOURCE_HSI)   /* HSI ? */
00872     {
00873       if(HAL_IS_BIT_SET(RCC->CR, RCC_CR_HSIRDY))
00874       {
00875         pllvco = HSI_VALUE;
00876       }
00877       else
00878       {
00879         pllvco = 0U;
00880       }
00881     }
00882     else if(__HAL_RCC_GET_PLL_OSCSOURCE() == RCC_PLLSOURCE_HSE)   /* HSE ? */
00883     {
00884       if(HAL_IS_BIT_SET(RCC->CR, RCC_CR_HSERDY))
00885       {
00886         pllvco = HSE_VALUE;
00887       }
00888       else
00889       {
00890         pllvco = 0U;
00891       }
00892     }
00893     else /* No source */
00894     {
00895       pllvco = 0U;
00896     }
00897 
00898     /* f(PLL Source) / PLLM */
00899     pllvco = (pllvco / ((READ_BIT(RCC->PLLCFGR, RCC_PLLCFGR_PLLM) >> POSITION_VAL(RCC_PLLCFGR_PLLM)) + 1U));
00900 
00901     switch(PeriphClk)
00902     {
00903 #if defined(SAI2)
00904 
00905     case RCC_PERIPHCLK_SAI1:
00906     case RCC_PERIPHCLK_SAI2:
00907 
00908       if(PeriphClk == RCC_PERIPHCLK_SAI1)
00909       {
00910         srcclk = __HAL_RCC_GET_SAI1_SOURCE();
00911           
00912         if(srcclk == RCC_SAI1CLKSOURCE_PIN)
00913         {
00914           frequency = EXTERNAL_SAI1_CLOCK_VALUE;
00915         }
00916         /* Else, PLL clock output to check below */
00917       }
00918       else /* RCC_PERIPHCLK_SAI2 */
00919       {
00920         srcclk = __HAL_RCC_GET_SAI2_SOURCE();
00921           
00922         if(srcclk == RCC_SAI2CLKSOURCE_PIN)
00923         {
00924           frequency = EXTERNAL_SAI2_CLOCK_VALUE;
00925         }
00926         /* Else, PLL clock output to check below */
00927       }
00928   
00929 #else
00930 
00931     case RCC_PERIPHCLK_SAI1:
00932 
00933       if(PeriphClk == RCC_PERIPHCLK_SAI1)
00934       {
00935         srcclk = READ_BIT(RCC->CCIPR, RCC_CCIPR_SAI1SEL);
00936           
00937         if(srcclk == RCC_SAI1CLKSOURCE_PIN)
00938         {
00939           frequency = EXTERNAL_SAI1_CLOCK_VALUE;
00940         }
00941         /* Else, PLL clock output to check below */
00942       }
00943       
00944 #endif /* SAI2 */
00945 
00946       if(frequency == 0U)
00947       {
00948 #if defined(SAI2)
00949         if((srcclk == RCC_SAI1CLKSOURCE_PLL) || (srcclk == RCC_SAI2CLKSOURCE_PLL))
00950         {
00951           if(__HAL_RCC_GET_PLLCLKOUT_CONFIG(RCC_PLL_SAI3CLK) != RESET)
00952           {
00953             /* f(PLLSAI3CLK) = f(VCO input) * PLLN / PLLP */
00954             plln = READ_BIT(RCC->PLLCFGR, RCC_PLLCFGR_PLLN) >> POSITION_VAL(RCC_PLLCFGR_PLLN);
00955 #if defined(RCC_PLLP_DIV_2_31_SUPPORT)
00956             pllp = READ_BIT(RCC->PLLCFGR, RCC_PLLCFGR_PLLPDIV) >> POSITION_VAL(RCC_PLLCFGR_PLLPDIV);
00957 #endif             
00958             if(pllp == 0U)
00959             {
00960               if(READ_BIT(RCC->PLLCFGR, RCC_PLLCFGR_PLLP) != RESET)
00961               {
00962                 pllp = 17U;
00963               }
00964               else
00965               {
00966                 pllp = 7U;
00967               }
00968             }
00969             frequency = (pllvco * plln) / pllp;
00970           }
00971         }
00972         else if(srcclk == 0U)  /* RCC_SAI1CLKSOURCE_PLLSAI1 || RCC_SAI2CLKSOURCE_PLLSAI1 */
00973         {
00974           if(__HAL_RCC_GET_PLLSAI1CLKOUT_CONFIG(RCC_PLLSAI1_SAI1CLK) != RESET)
00975           {
00976             /* f(PLLSAI1CLK) = f(VCOSAI1 input) * PLLSAI1N / PLLSAI1P */
00977             plln = READ_BIT(RCC->PLLSAI1CFGR, RCC_PLLSAI1CFGR_PLLSAI1N) >> POSITION_VAL(RCC_PLLSAI1CFGR_PLLSAI1N);
00978 #if defined(RCC_PLLSAI1P_DIV_2_31_SUPPORT)
00979             pllp = READ_BIT(RCC->PLLSAI1CFGR, RCC_PLLSAI1CFGR_PLLSAI1PDIV) >> POSITION_VAL(RCC_PLLSAI1CFGR_PLLSAI1PDIV);
00980 #endif             
00981             if(pllp == 0U)
00982             {
00983               if(READ_BIT(RCC->PLLSAI1CFGR, RCC_PLLSAI1CFGR_PLLSAI1P) != RESET)
00984               {
00985                 pllp = 17U;
00986               }
00987               else
00988               {
00989                 pllp = 7U;
00990               }
00991             }
00992             frequency = (pllvco * plln) / pllp;
00993           }
00994         }
00995 #else
00996         if(srcclk == RCC_SAI1CLKSOURCE_PLL)
00997         {
00998           if(__HAL_RCC_GET_PLLCLKOUT_CONFIG(RCC_PLL_SAI2CLK) != RESET)
00999           {
01000             /* f(PLLSAI2CLK) = f(VCO input) * PLLN / PLLP */
01001             plln = READ_BIT(RCC->PLLCFGR, RCC_PLLCFGR_PLLN) >> POSITION_VAL(RCC_PLLCFGR_PLLN);
01002 #if defined(RCC_PLLP_DIV_2_31_SUPPORT)
01003             pllp = READ_BIT(RCC->PLLCFGR, RCC_PLLCFGR_PLLPDIV) >> POSITION_VAL(RCC_PLLCFGR_PLLPDIV);
01004 #endif             
01005             if(pllp == 0U)
01006             {
01007               if(READ_BIT(RCC->PLLCFGR, RCC_PLLCFGR_PLLP) != RESET)
01008               {
01009                 pllp = 17U;
01010               }
01011               else
01012               {
01013                 pllp = 7U;
01014               }
01015             }
01016         
01017             frequency = (pllvco * plln) / pllp;
01018           }
01019           else if(HAL_IS_BIT_SET(RCC->CR, RCC_CR_HSIRDY))
01020           {
01021             /* HSI automatically selected as clock source if PLLs not enabled */
01022             frequency = HSI_VALUE;
01023           }
01024           else
01025           {
01026             /* No clock source */
01027             frequency = 0U;
01028           }          
01029         }
01030         else if(srcclk == RCC_SAI1CLKSOURCE_PLLSAI1)
01031         {
01032           if(__HAL_RCC_GET_PLLSAI1CLKOUT_CONFIG(RCC_PLLSAI1_SAI1CLK) != RESET)
01033           {
01034             /* f(PLLSAI1CLK) = f(VCOSAI1 input) * PLLSAI1N / PLLSAI1P */
01035             plln = READ_BIT(RCC->PLLSAI1CFGR, RCC_PLLSAI1CFGR_PLLSAI1N) >> POSITION_VAL(RCC_PLLSAI1CFGR_PLLSAI1N);
01036 #if defined(RCC_PLLSAI1P_DIV_2_31_SUPPORT)
01037             pllp = READ_BIT(RCC->PLLSAI1CFGR, RCC_PLLSAI1CFGR_PLLSAI1PDIV) >> POSITION_VAL(RCC_PLLSAI1CFGR_PLLSAI1PDIV);
01038 #endif             
01039             if(pllp == 0U)
01040             {
01041               if(READ_BIT(RCC->PLLSAI1CFGR, RCC_PLLSAI1CFGR_PLLSAI1P) != RESET)
01042               {
01043                 pllp = 17U;
01044               }
01045               else
01046               {
01047                 pllp = 7U;
01048               }
01049             }
01050         
01051            frequency = (pllvco * plln) / pllp;
01052           }
01053           else if(HAL_IS_BIT_SET(RCC->CR, RCC_CR_HSIRDY))
01054           {
01055             /* HSI automatically selected as clock source if PLLs not enabled */
01056             frequency = HSI_VALUE;
01057           }
01058           else
01059           {
01060             /* No clock source */
01061             frequency = 0U;
01062           }                     
01063         }
01064 #endif /* SAI2 */
01065 
01066 #if defined(RCC_PLLSAI2_SUPPORT)
01067 
01068         else if((srcclk == RCC_SAI1CLKSOURCE_PLLSAI2) || (srcclk == RCC_SAI2CLKSOURCE_PLLSAI2))
01069         {
01070           if(__HAL_RCC_GET_PLLSAI2CLKOUT_CONFIG(RCC_PLLSAI2_SAI2CLK) != RESET)
01071           {
01072             /* f(PLLSAI2CLK) = f(VCOSAI2 input) * PLLSAI2N / PLLSAI2P */
01073             plln = READ_BIT(RCC->PLLSAI2CFGR, RCC_PLLSAI2CFGR_PLLSAI2N) >> POSITION_VAL(RCC_PLLSAI2CFGR_PLLSAI2N);
01074 #if defined(RCC_PLLSAI2P_DIV_2_31_SUPPORT)
01075             pllp = READ_BIT(RCC->PLLSAI2CFGR, RCC_PLLSAI2CFGR_PLLSAI2PDIV) >> POSITION_VAL(RCC_PLLSAI2CFGR_PLLSAI2PDIV);
01076 #endif             
01077             if(pllp == 0U)
01078             {
01079               if(READ_BIT(RCC->PLLSAI2CFGR, RCC_PLLSAI2CFGR_PLLSAI2P) != RESET)
01080               {
01081                 pllp = 17U;
01082               }
01083               else
01084               {
01085                 pllp = 7U;
01086               }
01087             }
01088             frequency = (pllvco * plln) / pllp;
01089           }
01090         }
01091 
01092 #endif /* RCC_PLLSAI2_SUPPORT */
01093 
01094         else
01095         {
01096           /* No clock source */
01097           frequency = 0U;
01098         }
01099       }
01100       break;
01101     
01102 #if defined(USB_OTG_FS) || defined(USB)
01103     
01104     case RCC_PERIPHCLK_USB:
01105 
01106 #endif /* USB_OTG_FS || USB */
01107 
01108     case RCC_PERIPHCLK_RNG:
01109 
01110 #if defined(SDMMC1)
01111 
01112     case RCC_PERIPHCLK_SDMMC1:
01113 
01114 #endif /* SDMMC1 */
01115 
01116       srcclk = READ_BIT(RCC->CCIPR, RCC_CCIPR_CLK48SEL);
01117       
01118       if(srcclk == RCC_CCIPR_CLK48SEL)   /* MSI ? */
01119       {
01120         if(HAL_IS_BIT_SET(RCC->CR, RCC_CR_MSIRDY))
01121         {
01122           frequency = (1U << ((__HAL_RCC_GET_MSI_RANGE() >> 4U) - 4U)) * 1000000U;
01123         }
01124         else
01125         {
01126           frequency = 0U;
01127         }
01128       }
01129       else if(srcclk == RCC_CCIPR_CLK48SEL_1)  /* PLL ? */
01130       {
01131         if(HAL_IS_BIT_SET(RCC->CR, RCC_CR_PLLRDY) && HAL_IS_BIT_SET(RCC->PLLCFGR, RCC_PLLCFGR_PLLQEN))
01132         {
01133           /* f(PLL48M1CLK) = f(VCO input) * PLLN / PLLQ */
01134           plln = READ_BIT(RCC->PLLCFGR, RCC_PLLCFGR_PLLN) >> POSITION_VAL(RCC_PLLCFGR_PLLN);
01135           frequency = (pllvco * plln) / (((READ_BIT(RCC->PLLCFGR, RCC_PLLCFGR_PLLQ) >> POSITION_VAL(RCC_PLLCFGR_PLLQ)) + 1U) << 1U);
01136         }
01137         else
01138         {
01139           frequency = 0U;
01140         }
01141       }
01142       else if(srcclk == RCC_CCIPR_CLK48SEL_0)  /* PLLSAI1 ? */
01143       {
01144         if(HAL_IS_BIT_SET(RCC->CR, RCC_CR_PLLSAI1RDY) && HAL_IS_BIT_SET(RCC->PLLSAI1CFGR, RCC_PLLSAI1CFGR_PLLSAI1QEN))
01145         {
01146           /* f(PLL48M2CLK) = f(VCOSAI1 input) * PLLSAI1N / PLLSAI1Q */
01147           plln = READ_BIT(RCC->PLLSAI1CFGR, RCC_PLLSAI1CFGR_PLLSAI1N) >> POSITION_VAL(RCC_PLLSAI1CFGR_PLLSAI1N);
01148           frequency = (pllvco * plln) / (((READ_BIT(RCC->PLLSAI1CFGR, RCC_PLLSAI1CFGR_PLLSAI1Q) >> POSITION_VAL(RCC_PLLSAI1CFGR_PLLSAI1Q)) + 1U) << 1U);
01149         }
01150         else
01151         {
01152           frequency = 0U;
01153         }
01154       }
01155 #if defined(RCC_HSI48_SUPPORT)
01156       else if((srcclk == 0U) && (HAL_IS_BIT_SET(RCC->CRRCR, RCC_CRRCR_HSI48RDY))) /* HSI48 ? */
01157       {
01158         frequency = HSI48_VALUE;
01159       }
01160       else /* No clock source */
01161       {
01162         frequency = 0U;
01163       }
01164 #else
01165       else /* No clock source */
01166       {
01167         frequency = 0U;
01168       }
01169 #endif /* RCC_HSI48_SUPPORT */
01170       break;
01171       
01172     case RCC_PERIPHCLK_USART1:
01173       /* Get the current USART1 source */
01174       srcclk = __HAL_RCC_GET_USART1_SOURCE();
01175       
01176       if(srcclk == RCC_USART1CLKSOURCE_PCLK2)
01177       {
01178         frequency = HAL_RCC_GetPCLK2Freq();
01179       }
01180       else if(srcclk == RCC_USART1CLKSOURCE_SYSCLK)
01181       {
01182         frequency = HAL_RCC_GetSysClockFreq();
01183       }
01184       else if((srcclk == RCC_USART1CLKSOURCE_HSI) && (HAL_IS_BIT_SET(RCC->CR, RCC_CR_HSIRDY)))
01185       {
01186         frequency = HSI_VALUE;
01187       }
01188       else if((srcclk == RCC_USART1CLKSOURCE_LSE) && (HAL_IS_BIT_SET(RCC->BDCR, RCC_BDCR_LSERDY)))
01189       {
01190         frequency = LSE_VALUE;
01191       }
01192       /* Clock not enabled for USART1 */
01193       else
01194       {
01195         frequency = 0U;
01196       }
01197       break;
01198 
01199     case RCC_PERIPHCLK_USART2:
01200       /* Get the current USART2 source */
01201       srcclk = __HAL_RCC_GET_USART2_SOURCE();
01202       
01203       if(srcclk == RCC_USART2CLKSOURCE_PCLK1)
01204       {
01205         frequency = HAL_RCC_GetPCLK1Freq();
01206       }
01207       else if(srcclk == RCC_USART2CLKSOURCE_SYSCLK)
01208       {
01209         frequency = HAL_RCC_GetSysClockFreq();
01210       }
01211       else if((srcclk == RCC_USART2CLKSOURCE_HSI) && (HAL_IS_BIT_SET(RCC->CR, RCC_CR_HSIRDY)))
01212       {
01213         frequency = HSI_VALUE;
01214       }
01215       else if((srcclk == RCC_USART2CLKSOURCE_LSE) && (HAL_IS_BIT_SET(RCC->BDCR, RCC_BDCR_LSERDY)))
01216       {
01217         frequency = LSE_VALUE;
01218       }
01219       /* Clock not enabled for USART2 */
01220       else
01221       {
01222         frequency = 0U;
01223       }
01224       break;
01225 
01226 #if defined(USART3)
01227 
01228     case RCC_PERIPHCLK_USART3:
01229       /* Get the current USART3 source */
01230       srcclk = __HAL_RCC_GET_USART3_SOURCE();
01231       
01232       if(srcclk == RCC_USART3CLKSOURCE_PCLK1)
01233       {
01234         frequency = HAL_RCC_GetPCLK1Freq();
01235       }
01236       else if(srcclk == RCC_USART3CLKSOURCE_SYSCLK)
01237       {
01238         frequency = HAL_RCC_GetSysClockFreq();
01239       }
01240       else if((srcclk == RCC_USART3CLKSOURCE_HSI) && (HAL_IS_BIT_SET(RCC->CR, RCC_CR_HSIRDY)))
01241       {
01242         frequency = HSI_VALUE;
01243       }
01244       else if((srcclk == RCC_USART3CLKSOURCE_LSE) && (HAL_IS_BIT_SET(RCC->BDCR, RCC_BDCR_LSERDY)))
01245       {
01246         frequency = LSE_VALUE;
01247       }
01248       /* Clock not enabled for USART3 */
01249       else
01250       {
01251         frequency = 0U;
01252       }
01253       break;
01254 
01255 #endif /* USART3 */
01256 
01257 #if defined(UART4)
01258 
01259     case RCC_PERIPHCLK_UART4:
01260       /* Get the current UART4 source */
01261       srcclk = __HAL_RCC_GET_UART4_SOURCE();
01262       
01263       if(srcclk == RCC_UART4CLKSOURCE_PCLK1)
01264       {
01265         frequency = HAL_RCC_GetPCLK1Freq();
01266       }
01267       else if(srcclk == RCC_UART4CLKSOURCE_SYSCLK)
01268       {
01269         frequency = HAL_RCC_GetSysClockFreq();
01270       }
01271       else if((srcclk == RCC_UART4CLKSOURCE_HSI) && (HAL_IS_BIT_SET(RCC->CR, RCC_CR_HSIRDY)))
01272       {
01273         frequency = HSI_VALUE;
01274       }
01275       else if((srcclk == RCC_UART4CLKSOURCE_LSE) && (HAL_IS_BIT_SET(RCC->BDCR, RCC_BDCR_LSERDY)))
01276       {
01277         frequency = LSE_VALUE;
01278       }
01279       /* Clock not enabled for UART4 */
01280       else
01281       {
01282         frequency = 0U;
01283       }
01284       break;
01285 
01286 #endif /* UART4 */
01287 
01288 #if defined(UART5)
01289 
01290     case RCC_PERIPHCLK_UART5:
01291       /* Get the current UART5 source */
01292       srcclk = __HAL_RCC_GET_UART5_SOURCE();
01293       
01294       if(srcclk == RCC_UART5CLKSOURCE_PCLK1)
01295       {
01296         frequency = HAL_RCC_GetPCLK1Freq();
01297       }
01298       else if(srcclk == RCC_UART5CLKSOURCE_SYSCLK)
01299       {
01300         frequency = HAL_RCC_GetSysClockFreq();
01301       }
01302       else if((srcclk == RCC_UART5CLKSOURCE_HSI) && (HAL_IS_BIT_SET(RCC->CR, RCC_CR_HSIRDY)))
01303       {
01304         frequency = HSI_VALUE;
01305       }
01306       else if((srcclk == RCC_UART5CLKSOURCE_LSE) && (HAL_IS_BIT_SET(RCC->BDCR, RCC_BDCR_LSERDY)))
01307       {
01308         frequency = LSE_VALUE;
01309       }
01310       /* Clock not enabled for UART5 */
01311       else
01312       {
01313         frequency = 0U;
01314       }
01315       break;
01316 
01317 #endif /* UART5 */
01318       
01319     case RCC_PERIPHCLK_LPUART1:
01320       /* Get the current LPUART1 source */
01321       srcclk = __HAL_RCC_GET_LPUART1_SOURCE();
01322       
01323       if(srcclk == RCC_LPUART1CLKSOURCE_PCLK1)
01324       {
01325         frequency = HAL_RCC_GetPCLK1Freq();
01326       }
01327       else if(srcclk == RCC_LPUART1CLKSOURCE_SYSCLK)
01328       {
01329         frequency = HAL_RCC_GetSysClockFreq();
01330       }
01331       else if((srcclk == RCC_LPUART1CLKSOURCE_HSI) && (HAL_IS_BIT_SET(RCC->CR, RCC_CR_HSIRDY)))
01332       {
01333         frequency = HSI_VALUE;
01334       }
01335       else if((srcclk == RCC_LPUART1CLKSOURCE_LSE) && (HAL_IS_BIT_SET(RCC->BDCR, RCC_BDCR_LSERDY)))
01336       {
01337         frequency = LSE_VALUE;
01338       }
01339       /* Clock not enabled for LPUART1 */
01340       else
01341       {
01342         frequency = 0U;
01343       }
01344       break;
01345 
01346     case RCC_PERIPHCLK_ADC:
01347     
01348       srcclk = __HAL_RCC_GET_ADC_SOURCE();
01349       
01350       if(srcclk == RCC_ADCCLKSOURCE_SYSCLK)
01351       {
01352         frequency = HAL_RCC_GetSysClockFreq();
01353       }
01354       else if(srcclk == RCC_ADCCLKSOURCE_PLLSAI1)
01355       {
01356         if(__HAL_RCC_GET_PLLSAI1CLKOUT_CONFIG(RCC_PLLSAI1_ADC1CLK) != RESET)
01357         {
01358           /* f(PLLADC1CLK) = f(VCOSAI1 input) * PLLSAI1N / PLLSAI1R */
01359           plln = READ_BIT(RCC->PLLSAI1CFGR, RCC_PLLSAI1CFGR_PLLSAI1N) >> POSITION_VAL(RCC_PLLSAI1CFGR_PLLSAI1N);
01360           frequency = (pllvco * plln) / (((READ_BIT(RCC->PLLSAI1CFGR, RCC_PLLSAI1CFGR_PLLSAI1R) >> POSITION_VAL(RCC_PLLSAI1CFGR_PLLSAI1R)) + 1U) << 1U);
01361         }
01362       }
01363 #if defined(STM32L471xx) || defined(STM32L475xx) || defined(STM32L476xx) || defined(STM32L485xx) || defined(STM32L486xx)
01364       else if(srcclk == RCC_ADCCLKSOURCE_PLLSAI2)
01365       {
01366         if(__HAL_RCC_GET_PLLSAI2CLKOUT_CONFIG(RCC_PLLSAI2_ADC2CLK) != RESET)
01367         {
01368           /* f(PLLADC2CLK) = f(VCOSAI2 input) * PLLSAI2N / PLLSAI2R */
01369           plln = READ_BIT(RCC->PLLSAI2CFGR, RCC_PLLSAI2CFGR_PLLSAI2N) >> POSITION_VAL(RCC_PLLSAI2CFGR_PLLSAI2N);
01370           frequency = (pllvco * plln) / (((READ_BIT(RCC->PLLSAI2CFGR, RCC_PLLSAI2CFGR_PLLSAI2R) >> POSITION_VAL(RCC_PLLSAI2CFGR_PLLSAI2R)) + 1U) << 1U);
01371         }
01372       }
01373 #endif /* STM32L471xx || STM32L475xx || STM32L476xx || STM32L485xx || STM32L486xx */
01374       /* Clock not enabled for ADC */
01375       else
01376       {
01377         frequency = 0U;
01378       }
01379       break;
01380 
01381 #if defined(DFSDM1_Filter0)
01382 
01383     case RCC_PERIPHCLK_DFSDM1:
01384       /* Get the current DFSDM1 source */
01385       srcclk = __HAL_RCC_GET_DFSDM1_SOURCE();
01386       
01387       if(srcclk == RCC_DFSDM1CLKSOURCE_PCLK)
01388       {
01389         frequency = HAL_RCC_GetPCLK1Freq();
01390       }
01391       else
01392       {
01393         frequency = HAL_RCC_GetSysClockFreq();
01394       }
01395       break;
01396 
01397 #endif /* DFSDM1_Filter0 */
01398 
01399     case RCC_PERIPHCLK_I2C1:
01400       /* Get the current I2C1 source */
01401       srcclk = __HAL_RCC_GET_I2C1_SOURCE();
01402       
01403       if(srcclk == RCC_I2C1CLKSOURCE_PCLK1)
01404       {
01405         frequency = HAL_RCC_GetPCLK1Freq();
01406       }
01407       else if(srcclk == RCC_I2C1CLKSOURCE_SYSCLK)
01408       {
01409         frequency = HAL_RCC_GetSysClockFreq();
01410       }
01411       else if((srcclk == RCC_I2C1CLKSOURCE_HSI) && (HAL_IS_BIT_SET(RCC->CR, RCC_CR_HSIRDY)))
01412       {
01413         frequency = HSI_VALUE;
01414       }
01415       /* Clock not enabled for I2C1 */
01416       else
01417       {
01418         frequency = 0U;
01419       }
01420       break;
01421 
01422 #if defined(I2C2)
01423 
01424     case RCC_PERIPHCLK_I2C2:
01425       /* Get the current I2C2 source */
01426       srcclk = __HAL_RCC_GET_I2C2_SOURCE();
01427       
01428       if(srcclk == RCC_I2C2CLKSOURCE_PCLK1)
01429       {
01430         frequency = HAL_RCC_GetPCLK1Freq();
01431       }
01432       else if(srcclk == RCC_I2C2CLKSOURCE_SYSCLK)
01433       {
01434         frequency = HAL_RCC_GetSysClockFreq();
01435       }
01436       else if((srcclk == RCC_I2C2CLKSOURCE_HSI) && (HAL_IS_BIT_SET(RCC->CR, RCC_CR_HSIRDY)))
01437       {
01438         frequency = HSI_VALUE;
01439       }
01440       /* Clock not enabled for I2C2 */
01441       else
01442       {
01443         frequency = 0U;
01444       }
01445       break;
01446 
01447 #endif /* I2C2 */
01448 
01449     case RCC_PERIPHCLK_I2C3:
01450       /* Get the current I2C3 source */
01451       srcclk = __HAL_RCC_GET_I2C3_SOURCE();
01452       
01453       if(srcclk == RCC_I2C3CLKSOURCE_PCLK1)
01454       {
01455         frequency = HAL_RCC_GetPCLK1Freq();
01456       }
01457       else if(srcclk == RCC_I2C3CLKSOURCE_SYSCLK)
01458       {
01459         frequency = HAL_RCC_GetSysClockFreq();
01460       }
01461       else if((srcclk == RCC_I2C3CLKSOURCE_HSI) && (HAL_IS_BIT_SET(RCC->CR, RCC_CR_HSIRDY)))
01462       {
01463         frequency = HSI_VALUE;
01464       }
01465       /* Clock not enabled for I2C3 */
01466       else
01467       {
01468         frequency = 0U;
01469       }
01470       break;
01471 
01472     case RCC_PERIPHCLK_LPTIM1:
01473       /* Get the current LPTIM1 source */
01474       srcclk = __HAL_RCC_GET_LPTIM1_SOURCE();
01475       
01476       if(srcclk == RCC_LPTIM1CLKSOURCE_PCLK)
01477       {
01478         frequency = HAL_RCC_GetPCLK1Freq();
01479       }
01480       else if((srcclk == RCC_LPTIM1CLKSOURCE_LSI) && (HAL_IS_BIT_SET(RCC->CSR, RCC_CSR_LSIRDY)))
01481       {
01482         frequency = LSI_VALUE;
01483       }
01484       else if((srcclk == RCC_LPTIM1CLKSOURCE_HSI) && (HAL_IS_BIT_SET(RCC->CR, RCC_CR_HSIRDY)))
01485       {
01486         frequency = HSI_VALUE;
01487       }
01488       else if ((srcclk == RCC_LPTIM1CLKSOURCE_LSE) && (HAL_IS_BIT_SET(RCC->BDCR, RCC_BDCR_LSERDY)))
01489       {
01490         frequency = LSE_VALUE;
01491       }
01492       /* Clock not enabled for LPTIM1 */
01493       else
01494       {
01495         frequency = 0U;
01496       }
01497       break;
01498 
01499     case RCC_PERIPHCLK_LPTIM2:
01500       /* Get the current LPTIM2 source */
01501       srcclk = __HAL_RCC_GET_LPTIM2_SOURCE();
01502       
01503       if(srcclk == RCC_LPTIM2CLKSOURCE_PCLK)
01504       {
01505         frequency = HAL_RCC_GetPCLK1Freq();
01506       }
01507       else if((srcclk == RCC_LPTIM2CLKSOURCE_LSI) && (HAL_IS_BIT_SET(RCC->CSR, RCC_CSR_LSIRDY)))
01508       {
01509         frequency = LSI_VALUE;
01510       }
01511       else if((srcclk == RCC_LPTIM2CLKSOURCE_HSI) && (HAL_IS_BIT_SET(RCC->CR, RCC_CR_HSIRDY)))
01512       {
01513         frequency = HSI_VALUE;
01514       }
01515       else if ((srcclk == RCC_LPTIM2CLKSOURCE_LSE) && (HAL_IS_BIT_SET(RCC->BDCR, RCC_BDCR_LSERDY)))
01516       {
01517         frequency = LSE_VALUE;
01518       }
01519       /* Clock not enabled for LPTIM2 */
01520       else
01521       {
01522         frequency = 0U;
01523       }
01524       break;
01525 
01526 #if defined(SWPMI1)
01527 
01528     case RCC_PERIPHCLK_SWPMI1:
01529       /* Get the current SWPMI1 source */
01530       srcclk = __HAL_RCC_GET_SWPMI1_SOURCE();
01531       
01532       if(srcclk == RCC_SWPMI1CLKSOURCE_PCLK)
01533       {
01534         frequency = HAL_RCC_GetPCLK1Freq();
01535       }
01536       else if((srcclk == RCC_SWPMI1CLKSOURCE_HSI) && (HAL_IS_BIT_SET(RCC->CR, RCC_CR_HSIRDY)))
01537       {
01538         frequency = HSI_VALUE;
01539       }
01540       /* Clock not enabled for SWPMI1 */
01541       else
01542       {
01543         frequency = 0U;
01544       }
01545       break;
01546 
01547 #endif /* SWPMI1 */
01548 
01549     default:
01550       break;
01551     }
01552   }
01553 
01554   return(frequency);
01555 }
01556 
01557 /**
01558   * @}
01559   */
01560 
01561 /** @defgroup RCCEx_Exported_Functions_Group2 Extended Clock management functions
01562  *  @brief  Extended Clock management functions
01563  *
01564 @verbatim   
01565  ===============================================================================
01566                 ##### Extended clock management functions  #####
01567  ===============================================================================
01568     [..]
01569     This subsection provides a set of functions allowing to control the 
01570     activation or deactivation of MSI PLL-mode, PLLSAI1, PLLSAI2, LSE CSS,
01571     Low speed clock output and clock after wake-up from STOP mode.
01572 @endverbatim
01573   * @{
01574   */
01575 
01576 /**
01577   * @brief  Enable PLLSAI1.
01578   * @param  PLLSAI1Init  pointer to an RCC_PLLSAI1InitTypeDef structure that
01579   *         contains the configuration information for the PLLSAI1
01580   * @retval HAL status
01581   */
01582 HAL_StatusTypeDef HAL_RCCEx_EnablePLLSAI1(RCC_PLLSAI1InitTypeDef  *PLLSAI1Init)
01583 {
01584   uint32_t tickstart = 0U;
01585   HAL_StatusTypeDef status = HAL_OK;
01586 
01587   /* check for PLLSAI1 Parameters used to output PLLSAI1CLK */
01588   assert_param(IS_RCC_PLLSAI1SOURCE(PLLSAI1Init->PLLSAI1Source));
01589   assert_param(IS_RCC_PLLSAI1M_VALUE(PLLSAI1Init->PLLSAI1M));
01590   assert_param(IS_RCC_PLLSAI1N_VALUE(PLLSAI1Init->PLLSAI1N));
01591   assert_param(IS_RCC_PLLSAI1P_VALUE(PLLSAI1Init->PLLSAI1P));
01592   assert_param(IS_RCC_PLLSAI1Q_VALUE(PLLSAI1Init->PLLSAI1Q));
01593   assert_param(IS_RCC_PLLSAI1R_VALUE(PLLSAI1Init->PLLSAI1R));
01594   assert_param(IS_RCC_PLLSAI1CLOCKOUT_VALUE(PLLSAI1Init->PLLSAI1ClockOut));
01595 
01596   /* Disable the PLLSAI1 */
01597   __HAL_RCC_PLLSAI1_DISABLE();
01598 
01599   /* Get Start Tick*/
01600   tickstart = HAL_GetTick();
01601 
01602   /* Wait till PLLSAI1 is ready to be updated */
01603   while(READ_BIT(RCC->CR, RCC_CR_PLLSAI1RDY) != RESET)
01604   {
01605     if((HAL_GetTick() - tickstart) > PLLSAI1_TIMEOUT_VALUE)
01606     {
01607       status = HAL_TIMEOUT;
01608       break;
01609     }
01610   }
01611 
01612   if(status == HAL_OK)    
01613   {
01614     /* Configure the PLLSAI1 Multiplication factor N */
01615     /* Configure the PLLSAI1 Division factors P, Q and R */
01616     __HAL_RCC_PLLSAI1_CONFIG(PLLSAI1Init->PLLSAI1N, PLLSAI1Init->PLLSAI1P, PLLSAI1Init->PLLSAI1Q, PLLSAI1Init->PLLSAI1R);
01617     /* Configure the PLLSAI1 Clock output(s) */    
01618     __HAL_RCC_PLLSAI1CLKOUT_ENABLE(PLLSAI1Init->PLLSAI1ClockOut);
01619 
01620     /* Enable the PLLSAI1 again by setting PLLSAI1ON to 1*/
01621     __HAL_RCC_PLLSAI1_ENABLE();
01622 
01623     /* Get Start Tick*/
01624     tickstart = HAL_GetTick();
01625 
01626     /* Wait till PLLSAI1 is ready */
01627     while(READ_BIT(RCC->CR, RCC_CR_PLLSAI1RDY) == RESET)
01628     {
01629       if((HAL_GetTick() - tickstart) > PLLSAI1_TIMEOUT_VALUE)
01630       {
01631         status = HAL_TIMEOUT;
01632         break;
01633       }
01634     }
01635   }
01636   
01637   return status;
01638 }
01639 
01640 /**
01641   * @brief  Disable PLLSAI1.
01642   * @retval HAL status
01643   */
01644 HAL_StatusTypeDef HAL_RCCEx_DisablePLLSAI1(void)
01645 {
01646   uint32_t tickstart = 0U;
01647   HAL_StatusTypeDef status = HAL_OK;
01648 
01649   /* Disable the PLLSAI1 */
01650   __HAL_RCC_PLLSAI1_DISABLE();
01651 
01652   /* Get Start Tick*/
01653   tickstart = HAL_GetTick();
01654 
01655   /* Wait till PLLSAI1 is ready */
01656   while(READ_BIT(RCC->CR, RCC_CR_PLLSAI1RDY) != RESET)
01657   {
01658     if((HAL_GetTick() - tickstart) > PLLSAI1_TIMEOUT_VALUE)
01659     {
01660       status = HAL_TIMEOUT;
01661       break;
01662     }
01663   }
01664   
01665   /* Disable the PLLSAI1 Clock outputs */    
01666   __HAL_RCC_PLLSAI1CLKOUT_DISABLE(RCC_PLLSAI1CFGR_PLLSAI1PEN|RCC_PLLSAI1CFGR_PLLSAI1QEN|RCC_PLLSAI1CFGR_PLLSAI1REN);
01667 
01668   /* Reset PLL source to save power if no PLLs on */
01669   if((READ_BIT(RCC->CR, RCC_CR_PLLRDY) == RESET)
01670 #if defined(RCC_PLLSAI2_SUPPORT)
01671       && 
01672      (READ_BIT(RCC->CR, RCC_CR_PLLSAI2RDY) == RESET)
01673 #endif /* RCC_PLLSAI2_SUPPORT */
01674     )
01675   {  
01676     MODIFY_REG(RCC->PLLCFGR, RCC_PLLCFGR_PLLSRC, RCC_PLLSOURCE_NONE);
01677   }
01678   
01679   return status;
01680 }
01681 
01682 #if defined(RCC_PLLSAI2_SUPPORT)
01683 
01684 /**
01685   * @brief  Enable PLLSAI2.
01686   * @param  PLLSAI2Init  pointer to an RCC_PLLSAI2InitTypeDef structure that
01687   *         contains the configuration information for the PLLSAI2
01688   * @retval HAL status
01689   */
01690 HAL_StatusTypeDef HAL_RCCEx_EnablePLLSAI2(RCC_PLLSAI2InitTypeDef  *PLLSAI2Init)
01691 {
01692   uint32_t tickstart = 0U;
01693   HAL_StatusTypeDef status = HAL_OK;
01694 
01695   /* check for PLLSAI2 Parameters used to output PLLSAI2CLK */
01696   assert_param(IS_RCC_PLLSAI2SOURCE(PLLSAI2Init->PLLSAI2Source));
01697   assert_param(IS_RCC_PLLSAI2M_VALUE(PLLSAI2Init->PLLSAI2M));
01698   assert_param(IS_RCC_PLLSAI2N_VALUE(PLLSAI2Init->PLLSAI2N));
01699   assert_param(IS_RCC_PLLSAI2P_VALUE(PLLSAI2Init->PLLSAI2P));
01700   assert_param(IS_RCC_PLLSAI2R_VALUE(PLLSAI2Init->PLLSAI2R));
01701   assert_param(IS_RCC_PLLSAI2CLOCKOUT_VALUE(PLLSAI2Init->PLLSAI2ClockOut));
01702 
01703   /* Disable the PLLSAI2 */
01704   __HAL_RCC_PLLSAI2_DISABLE();
01705 
01706   /* Get Start Tick*/
01707   tickstart = HAL_GetTick();
01708 
01709   /* Wait till PLLSAI2 is ready to be updated */
01710   while(READ_BIT(RCC->CR, RCC_CR_PLLSAI2RDY) != RESET)
01711   {
01712     if((HAL_GetTick() - tickstart) > PLLSAI2_TIMEOUT_VALUE)
01713     {
01714       status = HAL_TIMEOUT;
01715       break;
01716     }
01717   }
01718 
01719   if(status == HAL_OK)    
01720   {
01721     /* Configure the PLLSAI2 Multiplication factor N */
01722     /* Configure the PLLSAI2 Division factors P and R */
01723     __HAL_RCC_PLLSAI2_CONFIG(PLLSAI2Init->PLLSAI2N, PLLSAI2Init->PLLSAI2P, PLLSAI2Init->PLLSAI2R);
01724     /* Configure the PLLSAI2 Clock output(s) */    
01725     __HAL_RCC_PLLSAI2CLKOUT_ENABLE(PLLSAI2Init->PLLSAI2ClockOut);
01726 
01727     /* Enable the PLLSAI2 again by setting PLLSAI2ON to 1*/
01728     __HAL_RCC_PLLSAI2_ENABLE();
01729 
01730     /* Get Start Tick*/
01731     tickstart = HAL_GetTick();
01732 
01733     /* Wait till PLLSAI2 is ready */
01734     while(READ_BIT(RCC->CR, RCC_CR_PLLSAI2RDY) == RESET)
01735     {
01736       if((HAL_GetTick() - tickstart) > PLLSAI2_TIMEOUT_VALUE)
01737       {
01738         status = HAL_TIMEOUT;
01739         break;
01740       }
01741     }
01742   }
01743   
01744   return status;
01745 }
01746 
01747 /**
01748   * @brief  Disable PLLISAI2.
01749   * @retval HAL status
01750   */
01751 HAL_StatusTypeDef HAL_RCCEx_DisablePLLSAI2(void)
01752 {
01753   uint32_t tickstart = 0U;
01754   HAL_StatusTypeDef status = HAL_OK;
01755 
01756   /* Disable the PLLSAI2 */
01757   __HAL_RCC_PLLSAI2_DISABLE();
01758 
01759   /* Get Start Tick*/
01760   tickstart = HAL_GetTick();
01761 
01762   /* Wait till PLLSAI2 is ready */
01763   while(READ_BIT(RCC->CR, RCC_CR_PLLSAI2RDY) != RESET)
01764   {
01765     if((HAL_GetTick() - tickstart) > PLLSAI2_TIMEOUT_VALUE)
01766     {
01767       status = HAL_TIMEOUT;
01768       break;
01769     }
01770   }
01771   
01772   /* Disable the PLLSAI2 Clock outputs */    
01773   __HAL_RCC_PLLSAI2CLKOUT_DISABLE(RCC_PLLSAI2CFGR_PLLSAI2PEN|RCC_PLLSAI2CFGR_PLLSAI2REN);
01774 
01775   /* Reset PLL source to save power if no PLLs on */
01776   if((READ_BIT(RCC->CR, RCC_CR_PLLRDY) == RESET)
01777       && 
01778      (READ_BIT(RCC->CR, RCC_CR_PLLSAI1RDY) == RESET)
01779     )
01780   {  
01781     MODIFY_REG(RCC->PLLCFGR, RCC_PLLCFGR_PLLSRC, RCC_PLLSOURCE_NONE);
01782   }
01783   
01784   return status;
01785 }
01786 
01787 #endif /* RCC_PLLSAI2_SUPPORT */
01788 
01789 /**
01790   * @brief  Configure the oscillator clock source for wakeup from Stop and CSS backup clock.
01791   * @param  WakeUpClk  Wakeup clock 
01792   *         This parameter can be one of the following values:
01793   *            @arg @ref RCC_STOP_WAKEUPCLOCK_MSI  MSI oscillator selection
01794   *            @arg @ref RCC_STOP_WAKEUPCLOCK_HSI  HSI oscillator selection
01795   * @note   This function shall not be called after the Clock Security System on HSE has been
01796   *         enabled.
01797   * @retval None
01798   */
01799 void HAL_RCCEx_WakeUpStopCLKConfig(uint32_t WakeUpClk)
01800 {
01801   assert_param(IS_RCC_STOP_WAKEUPCLOCK(WakeUpClk));
01802   
01803   __HAL_RCC_WAKEUPSTOP_CLK_CONFIG(WakeUpClk);
01804 }
01805 
01806 /**
01807   * @brief  Configure the MSI range after standby mode.
01808   * @note   After Standby its frequency can be selected between 4 possible values (1, 2, 4 or 8 MHz).
01809   * @param  MSIRange  MSI range 
01810   *         This parameter can be one of the following values:
01811   *            @arg @ref RCC_MSIRANGE_4  Range 4 around 1 MHz
01812   *            @arg @ref RCC_MSIRANGE_5  Range 5 around 2 MHz
01813   *            @arg @ref RCC_MSIRANGE_6  Range 6 around 4 MHz (reset value)
01814   *            @arg @ref RCC_MSIRANGE_7  Range 7 around 8 MHz
01815   * @retval None
01816   */
01817 void HAL_RCCEx_StandbyMSIRangeConfig(uint32_t MSIRange)
01818 {
01819   assert_param(IS_RCC_MSI_STANDBY_CLOCK_RANGE(MSIRange));
01820   
01821   __HAL_RCC_MSI_STANDBY_RANGE_CONFIG(MSIRange);
01822 }
01823 
01824 /**
01825   * @brief  Enable the LSE Clock Security System.
01826   * @note   Prior to enable the LSE Clock Security System, LSE oscillator is to be enabled
01827   *         with HAL_RCC_OscConfig() and the LSE oscillator clock is to be selected as RTC
01828   *         clock with HAL_RCCEx_PeriphCLKConfig().
01829   * @retval None
01830   */
01831 void HAL_RCCEx_EnableLSECSS(void)
01832 {
01833   SET_BIT(RCC->BDCR, RCC_BDCR_LSECSSON) ;
01834 }
01835 
01836 /**
01837   * @brief  Disable the LSE Clock Security System.
01838   * @note   LSE Clock Security System can only be disabled after a LSE failure detection.
01839   * @retval None
01840   */
01841 void HAL_RCCEx_DisableLSECSS(void)
01842 {
01843   CLEAR_BIT(RCC->BDCR, RCC_BDCR_LSECSSON) ;
01844   
01845   /* Disable LSE CSS IT if any */
01846   __HAL_RCC_DISABLE_IT(RCC_IT_LSECSS);
01847 }
01848 
01849 /**
01850   * @brief  Enable the LSE Clock Security System Interrupt & corresponding EXTI line.
01851   * @note   LSE Clock Security System Interrupt is mapped on RTC EXTI line 19
01852   * @retval None
01853   */
01854 void HAL_RCCEx_EnableLSECSS_IT(void)
01855 {
01856   /* Enable LSE CSS */
01857   SET_BIT(RCC->BDCR, RCC_BDCR_LSECSSON) ;
01858 
01859   /* Enable LSE CSS IT */
01860   __HAL_RCC_ENABLE_IT(RCC_IT_LSECSS);
01861   
01862   /* Enable IT on EXTI Line 19 */
01863   __HAL_RCC_LSECSS_EXTI_ENABLE_IT();
01864   __HAL_RCC_LSECSS_EXTI_ENABLE_RISING_EDGE();
01865 }
01866 
01867 /**
01868   * @brief Handle the RCC LSE Clock Security System interrupt request.
01869   * @retval None
01870   */
01871 void HAL_RCCEx_LSECSS_IRQHandler(void)
01872 {
01873   /* Check RCC LSE CSSF flag  */
01874   if(__HAL_RCC_GET_IT(RCC_IT_LSECSS))
01875   {
01876     /* RCC LSE Clock Security System interrupt user callback */
01877     HAL_RCCEx_LSECSS_Callback();
01878 
01879     /* Clear RCC LSE CSS pending bit */
01880     __HAL_RCC_CLEAR_IT(RCC_IT_LSECSS);
01881   }
01882 }                                                                            
01883 
01884 /**
01885   * @brief  RCCEx LSE Clock Security System interrupt callback.
01886   * @retval none
01887   */
01888 __weak void HAL_RCCEx_LSECSS_Callback(void)
01889 {
01890   /* NOTE : This function should not be modified, when the callback is needed,
01891             the @ref HAL_RCCEx_LSECSS_Callback should be implemented in the user file
01892    */
01893 }
01894 
01895 /**
01896   * @brief  Select the Low Speed clock source to output on LSCO pin (PA2).
01897   * @param  LSCOSource  specifies the Low Speed clock source to output.
01898   *          This parameter can be one of the following values:
01899   *            @arg @ref RCC_LSCOSOURCE_LSI  LSI clock selected as LSCO source
01900   *            @arg @ref RCC_LSCOSOURCE_LSE  LSE clock selected as LSCO source
01901   * @retval None
01902   */
01903 void HAL_RCCEx_EnableLSCO(uint32_t LSCOSource)
01904 {
01905   GPIO_InitTypeDef GPIO_InitStruct;
01906   FlagStatus       pwrclkchanged = RESET;
01907   FlagStatus       backupchanged = RESET;
01908   
01909   /* Check the parameters */
01910   assert_param(IS_RCC_LSCOSOURCE(LSCOSource));
01911 
01912   /* LSCO Pin Clock Enable */
01913   __LSCO_CLK_ENABLE();
01914 
01915   /* Configue the LSCO pin in analog mode */
01916   GPIO_InitStruct.Pin = LSCO_PIN;
01917   GPIO_InitStruct.Mode = GPIO_MODE_ANALOG;
01918   GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;
01919   GPIO_InitStruct.Pull = GPIO_NOPULL;
01920   HAL_GPIO_Init(LSCO_GPIO_PORT, &GPIO_InitStruct);
01921 
01922   /* Update LSCOSEL clock source in Backup Domain control register */
01923   if(__HAL_RCC_PWR_IS_CLK_DISABLED())
01924   {
01925     __HAL_RCC_PWR_CLK_ENABLE();
01926     pwrclkchanged = SET;
01927   }
01928   if(HAL_IS_BIT_CLR(PWR->CR1, PWR_CR1_DBP))
01929   {
01930     HAL_PWR_EnableBkUpAccess();
01931     backupchanged = SET;
01932   }
01933   
01934   MODIFY_REG(RCC->BDCR, RCC_BDCR_LSCOSEL | RCC_BDCR_LSCOEN, LSCOSource | RCC_BDCR_LSCOEN);
01935   
01936   if(backupchanged == SET)
01937   {
01938     HAL_PWR_DisableBkUpAccess();
01939   }
01940   if(pwrclkchanged == SET)
01941   {
01942     __HAL_RCC_PWR_CLK_DISABLE();
01943   }
01944 }
01945 
01946 /**
01947   * @brief  Disable the Low Speed clock output.
01948   * @retval None
01949   */
01950 void HAL_RCCEx_DisableLSCO(void)
01951 {
01952   FlagStatus       pwrclkchanged = RESET;
01953   FlagStatus       backupchanged = RESET;
01954   
01955   /* Update LSCOEN bit in Backup Domain control register */
01956   if(__HAL_RCC_PWR_IS_CLK_DISABLED())
01957   {
01958     __HAL_RCC_PWR_CLK_ENABLE();
01959     pwrclkchanged = SET;
01960   }
01961   if(HAL_IS_BIT_CLR(PWR->CR1, PWR_CR1_DBP))
01962   {
01963     /* Enable access to the backup domain */
01964     HAL_PWR_EnableBkUpAccess();
01965     backupchanged = SET;
01966   }
01967   
01968   CLEAR_BIT(RCC->BDCR, RCC_BDCR_LSCOEN);
01969   
01970   /* Restore previous configuration */
01971   if(backupchanged == SET)
01972   {
01973     /* Disable access to the backup domain */
01974     HAL_PWR_DisableBkUpAccess();
01975   }
01976   if(pwrclkchanged == SET)
01977   {
01978     __HAL_RCC_PWR_CLK_DISABLE();
01979   }
01980 }
01981 
01982 /**
01983   * @brief  Enable the PLL-mode of the MSI.
01984   * @note   Prior to enable the PLL-mode of the MSI for automatic hardware
01985   *         calibration LSE oscillator is to be enabled with HAL_RCC_OscConfig().
01986   * @retval None
01987   */
01988 void HAL_RCCEx_EnableMSIPLLMode(void)
01989 {
01990   SET_BIT(RCC->CR, RCC_CR_MSIPLLEN) ;
01991 }
01992 
01993 /**
01994   * @brief  Disable the PLL-mode of the MSI.
01995   * @note   PLL-mode of the MSI is automatically reset when LSE oscillator is disabled.
01996   * @retval None
01997   */
01998 void HAL_RCCEx_DisableMSIPLLMode(void)
01999 {
02000   CLEAR_BIT(RCC->CR, RCC_CR_MSIPLLEN) ;
02001 }
02002 
02003 /**
02004   * @}
02005   */
02006 
02007 #if defined(CRS)
02008 
02009 /** @defgroup RCCEx_Exported_Functions_Group3 Extended Clock Recovery System Control functions 
02010  *  @brief  Extended Clock Recovery System Control functions
02011  *
02012 @verbatim
02013  ===============================================================================
02014                 ##### Extended Clock Recovery System Control functions  #####
02015  ===============================================================================
02016     [..]
02017       For devices with Clock Recovery System feature (CRS), RCC Extention HAL driver can be used as follows:
02018 
02019       (#) In System clock config, HSI48 needs to be enabled
02020 
02021       (#) Enable CRS clock in IP MSP init which will use CRS functions
02022 
02023       (#) Call CRS functions as follows:
02024           (##) Prepare synchronization configuration necessary for HSI48 calibration
02025               (+++) Default values can be set for frequency Error Measurement (reload and error limit)
02026                         and also HSI48 oscillator smooth trimming.
02027               (+++) Macro __HAL_RCC_CRS_RELOADVALUE_CALCULATE can be also used to calculate 
02028                         directly reload value with target and sychronization frequencies values
02029           (##) Call function HAL_RCCEx_CRSConfig which
02030               (+++) Resets CRS registers to their default values.
02031               (+++) Configures CRS registers with synchronization configuration 
02032               (+++) Enables automatic calibration and frequency error counter feature
02033            Note: When using USB LPM (Link Power Management) and the device is in Sleep mode, the
02034            periodic USB SOF will not be generated by the host. No SYNC signal will therefore be
02035            provided to the CRS to calibrate the HSI48 on the run. To guarantee the required clock
02036            precision after waking up from Sleep mode, the LSE or reference clock on the GPIOs
02037            should be used as SYNC signal.
02038 
02039           (##) A polling function is provided to wait for complete synchronization
02040               (+++) Call function HAL_RCCEx_CRSWaitSynchronization()
02041               (+++) According to CRS status, user can decide to adjust again the calibration or continue
02042                         application if synchronization is OK
02043               
02044       (#) User can retrieve information related to synchronization in calling function
02045             HAL_RCCEx_CRSGetSynchronizationInfo()
02046 
02047       (#) Regarding synchronization status and synchronization information, user can try a new calibration
02048            in changing synchronization configuration and call again HAL_RCCEx_CRSConfig.
02049            Note: When the SYNC event is detected during the downcounting phase (before reaching the zero value), 
02050            it means that the actual frequency is lower than the target (and so, that the TRIM value should be 
02051            incremented), while when it is detected during the upcounting phase it means that the actual frequency 
02052            is higher (and that the TRIM value should be decremented).
02053 
02054       (#) In interrupt mode, user can resort to the available macros (__HAL_RCC_CRS_XXX_IT). Interrupts will go 
02055           through CRS Handler (CRS_IRQn/CRS_IRQHandler)
02056               (++) Call function HAL_RCCEx_CRSConfig()
02057               (++) Enable CRS_IRQn (thanks to NVIC functions)
02058               (++) Enable CRS interrupt (__HAL_RCC_CRS_ENABLE_IT)
02059               (++) Implement CRS status management in the following user callbacks called from 
02060                    HAL_RCCEx_CRS_IRQHandler():
02061                    (+++) HAL_RCCEx_CRS_SyncOkCallback()
02062                    (+++) HAL_RCCEx_CRS_SyncWarnCallback()
02063                    (+++) HAL_RCCEx_CRS_ExpectedSyncCallback()
02064                    (+++) HAL_RCCEx_CRS_ErrorCallback()
02065 
02066       (#) To force a SYNC EVENT, user can use the function HAL_RCCEx_CRSSoftwareSynchronizationGenerate().
02067           This function can be called before calling HAL_RCCEx_CRSConfig (for instance in Systick handler)
02068             
02069 @endverbatim
02070  * @{
02071  */
02072 
02073 /**
02074   * @brief  Start automatic synchronization for polling mode
02075   * @param  pInit Pointer on RCC_CRSInitTypeDef structure
02076   * @retval None
02077   */
02078 void HAL_RCCEx_CRSConfig(RCC_CRSInitTypeDef *pInit)
02079 {
02080   uint32_t value = 0;
02081   
02082   /* Check the parameters */
02083   assert_param(IS_RCC_CRS_SYNC_DIV(pInit->Prescaler));
02084   assert_param(IS_RCC_CRS_SYNC_SOURCE(pInit->Source));
02085   assert_param(IS_RCC_CRS_SYNC_POLARITY(pInit->Polarity));
02086   assert_param(IS_RCC_CRS_RELOADVALUE(pInit->ReloadValue));
02087   assert_param(IS_RCC_CRS_ERRORLIMIT(pInit->ErrorLimitValue));
02088   assert_param(IS_RCC_CRS_HSI48CALIBRATION(pInit->HSI48CalibrationValue));
02089 
02090   /* CONFIGURATION */
02091 
02092   /* Before configuration, reset CRS registers to their default values*/
02093   __HAL_RCC_CRS_FORCE_RESET();
02094   __HAL_RCC_CRS_RELEASE_RESET();
02095 
02096   /* Set the SYNCDIV[2:0] bits according to Prescaler value */
02097   /* Set the SYNCSRC[1:0] bits according to Source value */
02098   /* Set the SYNCSPOL bit according to Polarity value */
02099   value = (pInit->Prescaler | pInit->Source | pInit->Polarity);
02100   /* Set the RELOAD[15:0] bits according to ReloadValue value */
02101   value |= pInit->ReloadValue;
02102   /* Set the FELIM[7:0] bits according to ErrorLimitValue value */
02103   value |= (pInit->ErrorLimitValue << POSITION_VAL(CRS_CFGR_FELIM));
02104   WRITE_REG(CRS->CFGR, value);
02105 
02106   /* Adjust HSI48 oscillator smooth trimming */
02107   /* Set the TRIM[5:0] bits according to RCC_CRS_HSI48CalibrationValue value */
02108   MODIFY_REG(CRS->CR, CRS_CR_TRIM, (pInit->HSI48CalibrationValue << POSITION_VAL(CRS_CR_TRIM)));
02109   
02110   /* START AUTOMATIC SYNCHRONIZATION*/
02111   
02112   /* Enable Automatic trimming & Frequency error counter */
02113   SET_BIT(CRS->CR, CRS_CR_AUTOTRIMEN | CRS_CR_CEN);
02114 }
02115 
02116 /**
02117   * @brief  Generate the software synchronization event
02118   * @retval None
02119   */
02120 void HAL_RCCEx_CRSSoftwareSynchronizationGenerate(void)
02121 {
02122   SET_BIT(CRS->CR, CRS_CR_SWSYNC);
02123 }
02124 
02125 /**
02126   * @brief  Return synchronization info 
02127   * @param  pSynchroInfo Pointer on RCC_CRSSynchroInfoTypeDef structure
02128   * @retval None
02129   */
02130 void HAL_RCCEx_CRSGetSynchronizationInfo(RCC_CRSSynchroInfoTypeDef *pSynchroInfo)
02131 {
02132   /* Check the parameter */
02133   assert_param(pSynchroInfo != NULL);
02134   
02135   /* Get the reload value */
02136   pSynchroInfo->ReloadValue = (uint32_t)(READ_BIT(CRS->CFGR, CRS_CFGR_RELOAD));
02137   
02138   /* Get HSI48 oscillator smooth trimming */
02139   pSynchroInfo->HSI48CalibrationValue = (uint32_t)(READ_BIT(CRS->CR, CRS_CR_TRIM) >> POSITION_VAL(CRS_CR_TRIM));
02140 
02141   /* Get Frequency error capture */
02142   pSynchroInfo->FreqErrorCapture = (uint32_t)(READ_BIT(CRS->ISR, CRS_ISR_FECAP) >> POSITION_VAL(CRS_ISR_FECAP));
02143 
02144   /* Get Frequency error direction */
02145   pSynchroInfo->FreqErrorDirection = (uint32_t)(READ_BIT(CRS->ISR, CRS_ISR_FEDIR));
02146 }
02147 
02148 /**
02149 * @brief Wait for CRS Synchronization status.
02150 * @param Timeout  Duration of the timeout
02151 * @note  Timeout is based on the maximum time to receive a SYNC event based on synchronization
02152 *        frequency.
02153 * @note    If Timeout set to HAL_MAX_DELAY, HAL_TIMEOUT will be never returned.
02154 * @retval Combination of Synchronization status
02155 *          This parameter can be a combination of the following values:
02156 *            @arg @ref RCC_CRS_TIMEOUT
02157 *            @arg @ref RCC_CRS_SYNCOK
02158 *            @arg @ref RCC_CRS_SYNCWARN
02159 *            @arg @ref RCC_CRS_SYNCERR
02160 *            @arg @ref RCC_CRS_SYNCMISS
02161 *            @arg @ref RCC_CRS_TRIMOVF
02162 */
02163 uint32_t HAL_RCCEx_CRSWaitSynchronization(uint32_t Timeout)
02164 {
02165   uint32_t crsstatus = RCC_CRS_NONE;
02166   uint32_t tickstart = 0U;
02167   
02168   /* Get timeout */
02169   tickstart = HAL_GetTick();
02170   
02171   /* Wait for CRS flag or timeout detection */
02172   do
02173   {
02174     if(Timeout != HAL_MAX_DELAY)
02175     {
02176       if((Timeout == 0U) || ((HAL_GetTick() - tickstart) > Timeout))
02177       {
02178         crsstatus = RCC_CRS_TIMEOUT;
02179       }
02180     }
02181     /* Check CRS SYNCOK flag  */
02182     if(__HAL_RCC_CRS_GET_FLAG(RCC_CRS_FLAG_SYNCOK))
02183     {
02184       /* CRS SYNC event OK */
02185       crsstatus |= RCC_CRS_SYNCOK;
02186     
02187       /* Clear CRS SYNC event OK bit */
02188       __HAL_RCC_CRS_CLEAR_FLAG(RCC_CRS_FLAG_SYNCOK);
02189     }
02190     
02191     /* Check CRS SYNCWARN flag  */
02192     if(__HAL_RCC_CRS_GET_FLAG(RCC_CRS_FLAG_SYNCWARN))
02193     {
02194       /* CRS SYNC warning */
02195       crsstatus |= RCC_CRS_SYNCWARN;
02196     
02197       /* Clear CRS SYNCWARN bit */
02198       __HAL_RCC_CRS_CLEAR_FLAG(RCC_CRS_FLAG_SYNCWARN);
02199     }
02200     
02201     /* Check CRS TRIM overflow flag  */
02202     if(__HAL_RCC_CRS_GET_FLAG(RCC_CRS_FLAG_TRIMOVF))
02203     {
02204       /* CRS SYNC Error */
02205       crsstatus |= RCC_CRS_TRIMOVF;
02206     
02207       /* Clear CRS Error bit */
02208       __HAL_RCC_CRS_CLEAR_FLAG(RCC_CRS_FLAG_TRIMOVF);
02209     }
02210     
02211     /* Check CRS Error flag  */
02212     if(__HAL_RCC_CRS_GET_FLAG(RCC_CRS_FLAG_SYNCERR))
02213     {
02214       /* CRS SYNC Error */
02215       crsstatus |= RCC_CRS_SYNCERR;
02216     
02217       /* Clear CRS Error bit */
02218       __HAL_RCC_CRS_CLEAR_FLAG(RCC_CRS_FLAG_SYNCERR);
02219     }
02220     
02221     /* Check CRS SYNC Missed flag  */
02222     if(__HAL_RCC_CRS_GET_FLAG(RCC_CRS_FLAG_SYNCMISS))
02223     {
02224       /* CRS SYNC Missed */
02225       crsstatus |= RCC_CRS_SYNCMISS;
02226     
02227       /* Clear CRS SYNC Missed bit */
02228       __HAL_RCC_CRS_CLEAR_FLAG(RCC_CRS_FLAG_SYNCMISS);
02229     }
02230     
02231     /* Check CRS Expected SYNC flag  */
02232     if(__HAL_RCC_CRS_GET_FLAG(RCC_CRS_FLAG_ESYNC))
02233     {
02234       /* frequency error counter reached a zero value */
02235       __HAL_RCC_CRS_CLEAR_FLAG(RCC_CRS_FLAG_ESYNC);
02236     }
02237   } while(RCC_CRS_NONE == crsstatus);
02238 
02239   return crsstatus;
02240 }
02241 
02242 /**
02243   * @brief Handle the Clock Recovery System interrupt request.
02244   * @retval None
02245   */
02246 void HAL_RCCEx_CRS_IRQHandler(void)
02247 {
02248   uint32_t crserror = RCC_CRS_NONE;
02249   /* Get current IT flags and IT sources values */
02250   uint32_t itflags = READ_REG(CRS->ISR);
02251   uint32_t itsources = READ_REG(CRS->CR);
02252 
02253   /* Check CRS SYNCOK flag  */
02254   if(((itflags & RCC_CRS_FLAG_SYNCOK) != RESET) && ((itsources & RCC_CRS_IT_SYNCOK) != RESET))
02255   {
02256     /* Clear CRS SYNC event OK flag */
02257     WRITE_REG(CRS->ICR, CRS_ICR_SYNCOKC);
02258 
02259     /* user callback */
02260     HAL_RCCEx_CRS_SyncOkCallback();
02261   }
02262   /* Check CRS SYNCWARN flag  */
02263   else if(((itflags & RCC_CRS_FLAG_SYNCWARN) != RESET) && ((itsources & RCC_CRS_IT_SYNCWARN) != RESET))
02264   {
02265     /* Clear CRS SYNCWARN flag */
02266     WRITE_REG(CRS->ICR, CRS_ICR_SYNCWARNC);
02267 
02268     /* user callback */
02269     HAL_RCCEx_CRS_SyncWarnCallback();
02270   }
02271   /* Check CRS Expected SYNC flag  */
02272   else if(((itflags & RCC_CRS_FLAG_ESYNC) != RESET) && ((itsources & RCC_CRS_IT_ESYNC) != RESET))
02273   {
02274     /* frequency error counter reached a zero value */
02275     WRITE_REG(CRS->ICR, CRS_ICR_ESYNCC);
02276 
02277     /* user callback */
02278     HAL_RCCEx_CRS_ExpectedSyncCallback();
02279   }
02280   /* Check CRS Error flags  */
02281   else
02282   {
02283     if(((itflags & RCC_CRS_FLAG_ERR) != RESET) && ((itsources & RCC_CRS_IT_ERR) != RESET))
02284     {
02285       if((itflags & RCC_CRS_FLAG_SYNCERR) != RESET)
02286       {
02287         crserror |= RCC_CRS_SYNCERR;
02288       }
02289       if((itflags & RCC_CRS_FLAG_SYNCMISS) != RESET)
02290       {
02291         crserror |= RCC_CRS_SYNCMISS;
02292       }
02293       if((itflags & RCC_CRS_FLAG_TRIMOVF) != RESET)
02294       {
02295         crserror |= RCC_CRS_TRIMOVF;
02296       }
02297 
02298       /* Clear CRS Error flags */
02299       WRITE_REG(CRS->ICR, CRS_ICR_ERRC);
02300     
02301       /* user error callback */
02302       HAL_RCCEx_CRS_ErrorCallback(crserror);
02303     }
02304   }
02305 }
02306 
02307 /**
02308   * @brief  RCCEx Clock Recovery System SYNCOK interrupt callback.
02309   * @retval none
02310   */
02311 __weak void HAL_RCCEx_CRS_SyncOkCallback(void)
02312 {
02313   /* NOTE : This function should not be modified, when the callback is needed,
02314             the @ref HAL_RCCEx_CRS_SyncOkCallback should be implemented in the user file
02315    */
02316 }
02317 
02318 /**
02319   * @brief  RCCEx Clock Recovery System SYNCWARN interrupt callback.
02320   * @retval none
02321   */
02322 __weak void HAL_RCCEx_CRS_SyncWarnCallback(void)
02323 {
02324   /* NOTE : This function should not be modified, when the callback is needed,
02325             the @ref HAL_RCCEx_CRS_SyncWarnCallback should be implemented in the user file
02326    */
02327 }
02328 
02329 /**
02330   * @brief  RCCEx Clock Recovery System Expected SYNC interrupt callback.
02331   * @retval none
02332   */
02333 __weak void HAL_RCCEx_CRS_ExpectedSyncCallback(void)
02334 {
02335   /* NOTE : This function should not be modified, when the callback is needed,
02336             the @ref HAL_RCCEx_CRS_ExpectedSyncCallback should be implemented in the user file
02337    */
02338 }
02339 
02340 /**
02341   * @brief  RCCEx Clock Recovery System Error interrupt callback.
02342   * @param  Error Combination of Error status. 
02343   *         This parameter can be a combination of the following values:
02344   *           @arg @ref RCC_CRS_SYNCERR
02345   *           @arg @ref RCC_CRS_SYNCMISS
02346   *           @arg @ref RCC_CRS_TRIMOVF
02347   * @retval none
02348   */
02349 __weak void HAL_RCCEx_CRS_ErrorCallback(uint32_t Error)
02350 {
02351   /* Prevent unused argument(s) compilation warning */
02352   UNUSED(Error);
02353 
02354   /* NOTE : This function should not be modified, when the callback is needed,
02355             the @ref HAL_RCCEx_CRS_ErrorCallback should be implemented in the user file
02356    */
02357 }
02358 
02359 /**
02360   * @}
02361   */
02362   
02363 #endif /* CRS */
02364 
02365 /**
02366   * @}
02367   */
02368 
02369 /** @addtogroup RCCEx_Private_Functions
02370  * @{
02371  */
02372 
02373 /**
02374   * @brief  Configure the parameters N & P & optionally M of PLLSAI1 and enable PLLSAI1 output clock(s).
02375   * @param  PllSai1  pointer to an RCC_PLLSAI1InitTypeDef structure that
02376   *         contains the configuration parameters N & P & optionally M as well as PLLSAI1 output clock(s)
02377   * @param  Divider  divider parameter to be updated
02378   *
02379   * @note   PLLSAI1 is temporary disable to apply new parameters
02380   *
02381   * @retval HAL status
02382   */
02383 static HAL_StatusTypeDef RCCEx_PLLSAI1_Config(RCC_PLLSAI1InitTypeDef *PllSai1, uint32_t Divider)
02384 {
02385   uint32_t tickstart = 0U;
02386   HAL_StatusTypeDef status = HAL_OK;
02387 
02388   /* check for PLLSAI1 Parameters used to output PLLSAI1CLK */
02389   /* P, Q and R dividers are verified in each specific divider case below */
02390   assert_param(IS_RCC_PLLSAI1SOURCE(PllSai1->PLLSAI1Source));
02391   assert_param(IS_RCC_PLLSAI1M_VALUE(PllSai1->PLLSAI1M));
02392   assert_param(IS_RCC_PLLSAI1N_VALUE(PllSai1->PLLSAI1N));
02393   assert_param(IS_RCC_PLLSAI1CLOCKOUT_VALUE(PllSai1->PLLSAI1ClockOut));
02394   
02395   /* Check that PLLSAI1 clock source and divider M can be applied */
02396   if(__HAL_RCC_GET_PLL_OSCSOURCE() != RCC_PLLSOURCE_NONE)
02397   {
02398     /* PLL clock source and divider M already set, check that no request for change  */ 
02399     if((__HAL_RCC_GET_PLL_OSCSOURCE() != PllSai1->PLLSAI1Source)
02400        || 
02401        (PllSai1->PLLSAI1Source == RCC_PLLSOURCE_NONE)
02402        || 
02403        (((READ_BIT(RCC->PLLCFGR, RCC_PLLCFGR_PLLM) >> POSITION_VAL(RCC_PLLCFGR_PLLM)) + 1U) != PllSai1->PLLSAI1M)
02404       )
02405     {
02406       status = HAL_ERROR;
02407     }
02408   }
02409   else
02410   {
02411     /* Check PLLSAI1 clock source availability */
02412     switch(PllSai1->PLLSAI1Source)
02413     {
02414     case RCC_PLLSOURCE_MSI:
02415       if(HAL_IS_BIT_CLR(RCC->CR, RCC_CR_MSIRDY))
02416       {
02417         status = HAL_ERROR;
02418       }
02419       break;
02420     case RCC_PLLSOURCE_HSI:
02421       if(HAL_IS_BIT_CLR(RCC->CR, RCC_CR_HSIRDY))
02422       {
02423         status = HAL_ERROR;
02424       }
02425       break;
02426     case RCC_PLLSOURCE_HSE:
02427       if(HAL_IS_BIT_CLR(RCC->CR, RCC_CR_HSERDY) && HAL_IS_BIT_CLR(RCC->CR, RCC_CR_HSEBYP))
02428       {
02429         status = HAL_ERROR;
02430       }
02431       break;
02432     default:
02433       status = HAL_ERROR;
02434       break;
02435     }
02436     
02437     if(status == HAL_OK)
02438     {
02439       /* Set PLLSAI1 clock source and divider M */
02440       MODIFY_REG(RCC->PLLCFGR, RCC_PLLCFGR_PLLSRC | RCC_PLLCFGR_PLLM, PllSai1->PLLSAI1Source | (PllSai1->PLLSAI1M - 1U) << POSITION_VAL(RCC_PLLCFGR_PLLM));
02441     }
02442   }
02443   
02444   if(status == HAL_OK)
02445   {
02446     /* Disable the PLLSAI1 */
02447     __HAL_RCC_PLLSAI1_DISABLE();
02448 
02449     /* Get Start Tick*/
02450     tickstart = HAL_GetTick();
02451 
02452     /* Wait till PLLSAI1 is ready to be updated */
02453     while(READ_BIT(RCC->CR, RCC_CR_PLLSAI1RDY) != RESET)
02454     {
02455       if((HAL_GetTick() - tickstart) > PLLSAI1_TIMEOUT_VALUE)
02456       {
02457         status = HAL_TIMEOUT;
02458         break;
02459       }
02460     }
02461 
02462     if(status == HAL_OK)    
02463     {
02464       if(Divider == DIVIDER_P_UPDATE)
02465       {
02466         assert_param(IS_RCC_PLLSAI1P_VALUE(PllSai1->PLLSAI1P));
02467         /* Configure the PLLSAI1 Division factor P and Multiplication factor N*/
02468 #if defined(RCC_PLLSAI1P_DIV_2_31_SUPPORT)
02469         MODIFY_REG(RCC->PLLSAI1CFGR, 
02470                    RCC_PLLSAI1CFGR_PLLSAI1N | RCC_PLLSAI1CFGR_PLLSAI1PDIV, 
02471                    (PllSai1->PLLSAI1N << POSITION_VAL(RCC_PLLSAI1CFGR_PLLSAI1N)) | 
02472                    (PllSai1->PLLSAI1P << POSITION_VAL(RCC_PLLSAI1CFGR_PLLSAI1PDIV)));
02473 #else
02474         MODIFY_REG(RCC->PLLSAI1CFGR, 
02475                    RCC_PLLSAI1CFGR_PLLSAI1N | RCC_PLLSAI1CFGR_PLLSAI1P, 
02476                    (PllSai1->PLLSAI1N << POSITION_VAL(RCC_PLLSAI1CFGR_PLLSAI1N)) | 
02477                    ((PllSai1->PLLSAI1P >> 4U) << POSITION_VAL(RCC_PLLSAI1CFGR_PLLSAI1P)));
02478 #endif /* RCC_PLLSAI1P_DIV_2_31_SUPPORT */
02479       }
02480       else if(Divider == DIVIDER_Q_UPDATE)
02481       {
02482         assert_param(IS_RCC_PLLSAI1Q_VALUE(PllSai1->PLLSAI1Q));
02483         /* Configure the PLLSAI1 Division factor Q and Multiplication factor N*/
02484         MODIFY_REG(RCC->PLLSAI1CFGR, 
02485                    RCC_PLLSAI1CFGR_PLLSAI1N | RCC_PLLSAI1CFGR_PLLSAI1Q, 
02486                    (PllSai1->PLLSAI1N << POSITION_VAL(RCC_PLLSAI1CFGR_PLLSAI1N)) | 
02487                    (((PllSai1->PLLSAI1Q >> 1U) - 1U) << POSITION_VAL(RCC_PLLSAI1CFGR_PLLSAI1Q)));
02488       }
02489       else
02490       {
02491         assert_param(IS_RCC_PLLSAI1R_VALUE(PllSai1->PLLSAI1R));
02492         /* Configure the PLLSAI1 Division factor R and Multiplication factor N*/
02493         MODIFY_REG(RCC->PLLSAI1CFGR, 
02494                    RCC_PLLSAI1CFGR_PLLSAI1N | RCC_PLLSAI1CFGR_PLLSAI1R, 
02495                    (PllSai1->PLLSAI1N << POSITION_VAL(RCC_PLLSAI1CFGR_PLLSAI1N)) | 
02496                    (((PllSai1->PLLSAI1R >> 1U) - 1U) << POSITION_VAL(RCC_PLLSAI1CFGR_PLLSAI1R)));
02497       }
02498 
02499       /* Enable the PLLSAI1 again by setting PLLSAI1ON to 1*/
02500       __HAL_RCC_PLLSAI1_ENABLE();
02501 
02502       /* Get Start Tick*/
02503       tickstart = HAL_GetTick();
02504 
02505       /* Wait till PLLSAI1 is ready */
02506       while(READ_BIT(RCC->CR, RCC_CR_PLLSAI1RDY) == RESET)
02507       {
02508         if((HAL_GetTick() - tickstart) > PLLSAI1_TIMEOUT_VALUE)
02509         {
02510           status = HAL_TIMEOUT;
02511           break;
02512         }
02513       }
02514 
02515       if(status == HAL_OK)    
02516       {
02517         /* Configure the PLLSAI1 Clock output(s) */
02518         __HAL_RCC_PLLSAI1CLKOUT_ENABLE(PllSai1->PLLSAI1ClockOut);
02519       }
02520     }
02521   }
02522   
02523   return status;
02524 }
02525 
02526 #if defined(RCC_PLLSAI2_SUPPORT)
02527 
02528 /**
02529   * @brief  Configure the parameters N & P & optionally M of PLLSAI2 and enable PLLSAI2 output clock(s).
02530   * @param  PllSai2  pointer to an RCC_PLLSAI2InitTypeDef structure that
02531   *         contains the configuration parameters N & P & optionally M as well as PLLSAI2 output clock(s)
02532   * @param  Divider  divider parameter to be updated
02533   *
02534   * @note   PLLSAI2 is temporary disable to apply new parameters
02535   *
02536   * @retval HAL status
02537   */
02538 static HAL_StatusTypeDef RCCEx_PLLSAI2_Config(RCC_PLLSAI2InitTypeDef *PllSai2, uint32_t Divider)
02539 {
02540   uint32_t tickstart = 0U;
02541   HAL_StatusTypeDef status = HAL_OK;
02542 
02543   /* check for PLLSAI2 Parameters used to output PLLSAI2CLK */
02544   /* P, Q and R dividers are verified in each specific divider case below */
02545   assert_param(IS_RCC_PLLSAI2SOURCE(PllSai2->PLLSAI2Source));
02546   assert_param(IS_RCC_PLLSAI2M_VALUE(PllSai2->PLLSAI2M));
02547   assert_param(IS_RCC_PLLSAI2N_VALUE(PllSai2->PLLSAI2N));
02548   assert_param(IS_RCC_PLLSAI2CLOCKOUT_VALUE(PllSai2->PLLSAI2ClockOut));
02549   
02550   /* Check that PLLSAI2 clock source and divider M can be applied */
02551   if(__HAL_RCC_GET_PLL_OSCSOURCE() != RCC_PLLSOURCE_NONE)
02552   {
02553     /* PLL clock source and divider M already set, check that no request for change  */ 
02554     if((__HAL_RCC_GET_PLL_OSCSOURCE() != PllSai2->PLLSAI2Source)
02555        || 
02556        (PllSai2->PLLSAI2Source == RCC_PLLSOURCE_NONE)
02557        || 
02558        (((READ_BIT(RCC->PLLCFGR, RCC_PLLCFGR_PLLM) >> POSITION_VAL(RCC_PLLCFGR_PLLM)) + 1U) != PllSai2->PLLSAI2M)
02559       )
02560     {
02561       status = HAL_ERROR;
02562     }
02563   }
02564   else
02565   {
02566     /* Check PLLSAI2 clock source availability */
02567     switch(PllSai2->PLLSAI2Source)
02568     {
02569     case RCC_PLLSOURCE_MSI:
02570       if(HAL_IS_BIT_CLR(RCC->CR, RCC_CR_MSIRDY))
02571       {
02572         status = HAL_ERROR;
02573       }
02574       break;
02575     case RCC_PLLSOURCE_HSI:
02576       if(HAL_IS_BIT_CLR(RCC->CR, RCC_CR_HSIRDY))
02577       {
02578         status = HAL_ERROR;
02579       }
02580       break;
02581     case RCC_PLLSOURCE_HSE:
02582       if(HAL_IS_BIT_CLR(RCC->CR, RCC_CR_HSERDY) && HAL_IS_BIT_CLR(RCC->CR, RCC_CR_HSEBYP))
02583       {
02584         status = HAL_ERROR;
02585       }
02586       break;
02587     default:
02588       status = HAL_ERROR;
02589       break;
02590     }
02591     
02592     if(status == HAL_OK)
02593     {
02594       /* Set PLLSAI2 clock source and divider M */
02595       MODIFY_REG(RCC->PLLCFGR, RCC_PLLCFGR_PLLSRC | RCC_PLLCFGR_PLLM, PllSai2->PLLSAI2Source | (PllSai2->PLLSAI2M - 1U) << POSITION_VAL(RCC_PLLCFGR_PLLM));
02596     }
02597   }
02598   
02599   if(status == HAL_OK)
02600   {
02601     /* Disable the PLLSAI2 */
02602     __HAL_RCC_PLLSAI2_DISABLE();
02603 
02604     /* Get Start Tick*/
02605     tickstart = HAL_GetTick();
02606 
02607     /* Wait till PLLSAI2 is ready to be updated */
02608     while(READ_BIT(RCC->CR, RCC_CR_PLLSAI2RDY) != RESET)
02609     {
02610       if((HAL_GetTick() - tickstart) > PLLSAI2_TIMEOUT_VALUE)
02611       {
02612         status = HAL_TIMEOUT;
02613         break;
02614       }
02615     }
02616 
02617     if(status == HAL_OK)    
02618     {
02619       if(Divider == DIVIDER_P_UPDATE)
02620       {
02621         assert_param(IS_RCC_PLLSAI2P_VALUE(PllSai2->PLLSAI2P));
02622         /* Configure the PLLSAI2 Division factor P and Multiplication factor N*/
02623 #if defined(RCC_PLLSAI2P_DIV_2_31_SUPPORT)
02624         MODIFY_REG(RCC->PLLSAI2CFGR, 
02625                    RCC_PLLSAI2CFGR_PLLSAI2N | RCC_PLLSAI2CFGR_PLLSAI2PDIV, 
02626                    (PllSai2->PLLSAI2N << POSITION_VAL(RCC_PLLSAI2CFGR_PLLSAI2N)) | 
02627                    (PllSai2->PLLSAI2P << POSITION_VAL(RCC_PLLSAI2CFGR_PLLSAI2PDIV)));
02628 #else
02629         MODIFY_REG(RCC->PLLSAI2CFGR, 
02630                    RCC_PLLSAI2CFGR_PLLSAI2N | RCC_PLLSAI2CFGR_PLLSAI2P, 
02631                    (PllSai2->PLLSAI2N << POSITION_VAL(RCC_PLLSAI2CFGR_PLLSAI2N)) | 
02632                    ((PllSai2->PLLSAI2P >> 4U) << POSITION_VAL(RCC_PLLSAI2CFGR_PLLSAI2P)));
02633 #endif /* RCC_PLLSAI2P_DIV_2_31_SUPPORT */
02634       }
02635       else
02636       {
02637         assert_param(IS_RCC_PLLSAI2R_VALUE(PllSai2->PLLSAI2R));
02638         /* Configure the PLLSAI2 Division factor R and Multiplication factor N*/
02639         MODIFY_REG(RCC->PLLSAI2CFGR, 
02640                    RCC_PLLSAI2CFGR_PLLSAI2N | RCC_PLLSAI2CFGR_PLLSAI2R, 
02641                    (PllSai2->PLLSAI2N << POSITION_VAL(RCC_PLLSAI2CFGR_PLLSAI2N)) | 
02642                    (((PllSai2->PLLSAI2R >> 1U) - 1U) << POSITION_VAL(RCC_PLLSAI2CFGR_PLLSAI2R)));
02643       }
02644 
02645       /* Enable the PLLSAI2 again by setting PLLSAI2ON to 1*/
02646       __HAL_RCC_PLLSAI2_ENABLE();
02647 
02648       /* Get Start Tick*/
02649       tickstart = HAL_GetTick();
02650 
02651       /* Wait till PLLSAI2 is ready */
02652       while(READ_BIT(RCC->CR, RCC_CR_PLLSAI2RDY) == RESET)
02653       {
02654         if((HAL_GetTick() - tickstart) > PLLSAI2_TIMEOUT_VALUE)
02655         {
02656           status = HAL_TIMEOUT;
02657           break;
02658         }
02659       }
02660 
02661       if(status == HAL_OK)    
02662       {
02663         /* Configure the PLLSAI2 Clock output(s) */
02664         __HAL_RCC_PLLSAI2CLKOUT_ENABLE(PllSai2->PLLSAI2ClockOut);
02665       }
02666     }
02667   }
02668   
02669   return status;
02670 }
02671 
02672 #endif /* RCC_PLLSAI2_SUPPORT */
02673 
02674 /**
02675   * @}
02676   */
02677 
02678 /**
02679   * @}
02680   */
02681 
02682 #endif /* HAL_RCC_MODULE_ENABLED */
02683 /**
02684   * @}
02685   */
02686 
02687 /**
02688   * @}
02689   */
02690 
02691 /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
02692