STM32L443xx HAL User Manual
stm32l4xx_hal_rcc.c
Go to the documentation of this file.
00001 /**
00002   ******************************************************************************
00003   * @file    stm32l4xx_hal_rcc.c
00004   * @author  MCD Application Team
00005   * @brief   RCC HAL module driver.
00006   *          This file provides firmware functions to manage the following
00007   *          functionalities of the Reset and Clock Control (RCC) peripheral:
00008   *           + Initialization and de-initialization functions
00009   *           + Peripheral Control functions
00010   *
00011   @verbatim
00012   ==============================================================================
00013                       ##### RCC specific features #####
00014   ==============================================================================
00015     [..]
00016       After reset the device is running from Multiple Speed Internal oscillator
00017       (4 MHz) with Flash 0 wait state. Flash prefetch buffer, D-Cache
00018       and I-Cache are disabled, and all peripherals are off except internal
00019       SRAM, Flash and JTAG.
00020 
00021       (+) There is no prescaler on High speed (AHBs) and Low speed (APBs) busses:
00022           all peripherals mapped on these busses are running at MSI speed.
00023       (+) The clock for all peripherals is switched off, except the SRAM and FLASH.
00024       (+) All GPIOs are in analog mode, except the JTAG pins which
00025           are assigned to be used for debug purpose.
00026 
00027     [..]
00028       Once the device started from reset, the user application has to:
00029       (+) Configure the clock source to be used to drive the System clock
00030           (if the application needs higher frequency/performance)
00031       (+) Configure the System clock frequency and Flash settings
00032       (+) Configure the AHB and APB busses prescalers
00033       (+) Enable the clock for the peripheral(s) to be used
00034       (+) Configure the clock source(s) for peripherals which clocks are not
00035           derived from the System clock (SAIx, RTC, ADC, USB OTG FS/SDMMC1/RNG)
00036 
00037   @endverbatim
00038   ******************************************************************************
00039   * @attention
00040   *
00041   * Copyright (c) 2017 STMicroelectronics.
00042   * All rights reserved.
00043   *
00044   * This software is licensed under terms that can be found in the LICENSE file in
00045   * the root directory of this software component.
00046   * If no LICENSE file comes with this software, it is provided AS-IS.
00047   ******************************************************************************
00048   */
00049 
00050 /* Includes ------------------------------------------------------------------*/
00051 #include "stm32l4xx_hal.h"
00052 
00053 /** @addtogroup STM32L4xx_HAL_Driver
00054   * @{
00055   */
00056 
00057 /** @defgroup RCC RCC
00058   * @brief RCC HAL module driver
00059   * @{
00060   */
00061 
00062 #ifdef HAL_RCC_MODULE_ENABLED
00063 
00064 /* Private typedef -----------------------------------------------------------*/
00065 /* Private define ------------------------------------------------------------*/
00066 /** @defgroup RCC_Private_Constants RCC Private Constants
00067  * @{
00068  */
00069 #define HSE_TIMEOUT_VALUE          HSE_STARTUP_TIMEOUT
00070 #define HSI_TIMEOUT_VALUE          2U    /* 2 ms (minimum Tick + 1) */
00071 #define MSI_TIMEOUT_VALUE          2U    /* 2 ms (minimum Tick + 1) */
00072 #if defined(RCC_CSR_LSIPREDIV)
00073 #define LSI_TIMEOUT_VALUE          17U   /* 17 ms (16 ms starting time + 1) */
00074 #else
00075 #define LSI_TIMEOUT_VALUE          2U    /* 2 ms (minimum Tick + 1) */
00076 #endif /* RCC_CSR_LSIPREDIV */
00077 #define HSI48_TIMEOUT_VALUE        2U    /* 2 ms (minimum Tick + 1) */
00078 #define PLL_TIMEOUT_VALUE          2U    /* 2 ms (minimum Tick + 1) */
00079 #define CLOCKSWITCH_TIMEOUT_VALUE  5000U /* 5 s    */
00080 /**
00081   * @}
00082   */
00083 
00084 /* Private macro -------------------------------------------------------------*/
00085 /** @defgroup RCC_Private_Macros RCC Private Macros
00086   * @{
00087   */
00088 #define __MCO1_CLK_ENABLE()   __HAL_RCC_GPIOA_CLK_ENABLE()
00089 #define MCO1_GPIO_PORT        GPIOA
00090 #define MCO1_PIN              GPIO_PIN_8
00091 
00092 #define RCC_PLL_OSCSOURCE_CONFIG(__HAL_RCC_PLLSOURCE__) \
00093             (MODIFY_REG(RCC->PLLCFGR, RCC_PLLCFGR_PLLSRC, (__HAL_RCC_PLLSOURCE__)))
00094 /**
00095   * @}
00096   */
00097 
00098 /* Private variables ---------------------------------------------------------*/
00099 
00100 /* Private function prototypes -----------------------------------------------*/
00101 /** @defgroup RCC_Private_Functions RCC Private Functions
00102   * @{
00103   */
00104 static HAL_StatusTypeDef RCC_SetFlashLatencyFromMSIRange(uint32_t msirange);
00105 #if defined(STM32L4P5xx) || defined(STM32L4Q5xx) || \
00106     defined(STM32L4R5xx) || defined(STM32L4R7xx) || defined(STM32L4R9xx) || defined(STM32L4S5xx) || defined(STM32L4S7xx) || defined(STM32L4S9xx)
00107 static uint32_t          RCC_GetSysClockFreqFromPLLSource(void);
00108 #endif
00109 /**
00110   * @}
00111   */
00112 
00113 /* Exported functions --------------------------------------------------------*/
00114 
00115 /** @defgroup RCC_Exported_Functions RCC Exported Functions
00116   * @{
00117   */
00118 
00119 /** @defgroup RCC_Exported_Functions_Group1 Initialization and de-initialization functions
00120   *  @brief    Initialization and Configuration functions
00121   *
00122   @verbatim
00123  ===============================================================================
00124            ##### Initialization and de-initialization functions #####
00125  ===============================================================================
00126     [..]
00127       This section provides functions allowing to configure the internal and external oscillators
00128       (HSE, HSI, LSE, MSI, LSI, PLL, CSS and MCO) and the System busses clocks (SYSCLK, AHB, APB1
00129        and APB2).
00130 
00131     [..] Internal/external clock and PLL configuration
00132          (+) HSI (high-speed internal): 16 MHz factory-trimmed RC used directly or through
00133              the PLL as System clock source.
00134 
00135          (+) MSI (Mutiple Speed Internal): Its frequency is software trimmable from 100KHZ to 48MHZ.
00136              It can be used to generate the clock for the USB OTG FS (48 MHz).
00137              The number of flash wait states is automatically adjusted when MSI range is updated with
00138              HAL_RCC_OscConfig() and the MSI is used as System clock source.
00139 
00140          (+) LSI (low-speed internal): 32 KHz low consumption RC used as IWDG and/or RTC
00141              clock source.
00142 
00143          (+) HSE (high-speed external): 4 to 48 MHz crystal oscillator used directly or
00144              through the PLL as System clock source. Can be used also optionally as RTC clock source.
00145 
00146          (+) LSE (low-speed external): 32.768 KHz oscillator used optionally as RTC clock source.
00147 
00148          (+) PLL (clocked by HSI, HSE or MSI) providing up to three independent output clocks:
00149            (++) The first output is used to generate the high speed system clock (up to 80MHz).
00150            (++) The second output is used to generate the clock for the USB OTG FS (48 MHz),
00151                 the random analog generator (<=48 MHz) and the SDMMC1 (<= 48 MHz).
00152            (++) The third output is used to generate an accurate clock to achieve
00153                 high-quality audio performance on SAI interface.
00154 
00155          (+) PLLSAI1 (clocked by HSI, HSE or MSI) providing up to three independent output clocks:
00156            (++) The first output is used to generate SAR ADC1 clock.
00157            (++) The second output is used to generate the clock for the USB OTG FS (48 MHz),
00158                 the random analog generator (<=48 MHz) and the SDMMC1 (<= 48 MHz).
00159            (++) The third output is used to generate an accurate clock to achieve
00160                 high-quality audio performance on SAI interface.
00161 
00162          (+) PLLSAI2 (clocked by HSI, HSE or MSI) providing up to three independent output clocks:
00163            (++) The first output is used to generate an accurate clock to achieve
00164                 high-quality audio performance on SAI interface.
00165            (++) The second output is used to generate either SAR ADC2 clock if ADC2 is present
00166                 or LCD clock if LTDC is present.
00167            (++) The third output is used to generate DSI clock if DSI is present.
00168 
00169          (+) CSS (Clock security system): once enabled, if a HSE clock failure occurs
00170             (HSE used directly or through PLL as System clock source), the System clock
00171              is automatically switched to HSI and an interrupt is generated if enabled.
00172              The interrupt is linked to the Cortex-M4 NMI (Non-Maskable Interrupt)
00173              exception vector.
00174 
00175          (+) MCO (microcontroller clock output): used to output MSI, LSI, HSI, LSE, HSE or
00176              main PLL clock (through a configurable prescaler) on PA8 pin.
00177 
00178     [..] System, AHB and APB busses clocks configuration
00179          (+) Several clock sources can be used to drive the System clock (SYSCLK): MSI, HSI,
00180              HSE and main PLL.
00181              The AHB clock (HCLK) is derived from System clock through configurable
00182              prescaler and used to clock the CPU, memory and peripherals mapped
00183              on AHB bus (DMA, GPIO...). APB1 (PCLK1) and APB2 (PCLK2) clocks are derived
00184              from AHB clock through configurable prescalers and used to clock
00185              the peripherals mapped on these busses. You can use
00186              "HAL_RCC_GetSysClockFreq()" function to retrieve the frequencies of these clocks.
00187 
00188          -@- All the peripheral clocks are derived from the System clock (SYSCLK) except:
00189 
00190            (+@) SAI: the SAI clock can be derived either from a specific PLL (PLLSAI1) or (PLLSAI2) or
00191                 from an external clock mapped on the SAI_CKIN pin.
00192                 You have to use HAL_RCCEx_PeriphCLKConfig() function to configure this clock.
00193            (+@) RTC: the RTC clock can be derived either from the LSI, LSE or HSE clock
00194                 divided by 2 to 31.
00195                 You have to use __HAL_RCC_RTC_ENABLE() and HAL_RCCEx_PeriphCLKConfig() function
00196                 to configure this clock.
00197            (+@) USB OTG FS, SDMMC1 and RNG: USB OTG FS requires a frequency equal to 48 MHz
00198                 to work correctly, while the SDMMC1 and RNG peripherals require a frequency
00199                 equal or lower than to 48 MHz. This clock is derived of the main PLL or PLLSAI1
00200                 through PLLQ divider. You have to enable the peripheral clock and use
00201                 HAL_RCCEx_PeriphCLKConfig() function to configure this clock.
00202            (+@) IWDG clock which is always the LSI clock.
00203 
00204 
00205          (+) The maximum frequency of the SYSCLK, HCLK, PCLK1 and PCLK2 is 80 MHz.
00206              The clock source frequency should be adapted depending on the device voltage range
00207              as listed in the Reference Manual "Clock source frequency versus voltage scaling" chapter.
00208 
00209   @endverbatim
00210 
00211            Table 1. HCLK clock frequency for other STM32L4 devices
00212            +-------------------------------------------------------+
00213            | Latency         |    HCLK clock frequency (MHz)       |
00214            |                 |-------------------------------------|
00215            |                 | voltage range 1  | voltage range 2  |
00216            |                 |      1.2 V       |     1.0 V        |
00217            |-----------------|------------------|------------------|
00218            |0WS(1 CPU cycles)|  0 < HCLK <= 16  |  0 < HCLK <= 6   |
00219            |-----------------|------------------|------------------|
00220            |1WS(2 CPU cycles)| 16 < HCLK <= 32  |  6 < HCLK <= 12  |
00221            |-----------------|------------------|------------------|
00222            |2WS(3 CPU cycles)| 32 < HCLK <= 48  | 12 < HCLK <= 18  |
00223            |-----------------|------------------|------------------|
00224            |3WS(4 CPU cycles)| 48 < HCLK <= 64  | 18 < HCLK <= 26  |
00225            |-----------------|------------------|------------------|
00226            |4WS(5 CPU cycles)| 64 < HCLK <= 80  | 18 < HCLK <= 26  |
00227            +-------------------------------------------------------+
00228 
00229            Table 2. HCLK clock frequency for STM32L4+ devices
00230            +--------------------------------------------------------+
00231            | Latency         |     HCLK clock frequency (MHz)       |
00232            |                 |--------------------------------------|
00233            |                 |  voltage range 1  | voltage range 2  |
00234            |                 |       1.2 V       |     1.0 V        |
00235            |-----------------|-------------------|------------------|
00236            |0WS(1 CPU cycles)|   0 < HCLK <= 20  |  0 < HCLK <= 8   |
00237            |-----------------|-------------------|------------------|
00238            |1WS(2 CPU cycles)|  20 < HCLK <= 40  |  8 < HCLK <= 16  |
00239            |-----------------|-------------------|------------------|
00240            |2WS(3 CPU cycles)|  40 < HCLK <= 60  | 16 < HCLK <= 26  |
00241            |-----------------|-------------------|------------------|
00242            |3WS(4 CPU cycles)|  60 < HCLK <= 80  | 16 < HCLK <= 26  |
00243            |-----------------|-------------------|------------------|
00244            |4WS(5 CPU cycles)|  80 < HCLK <= 100 | 16 < HCLK <= 26  |
00245            |-----------------|-------------------|------------------|
00246            |5WS(6 CPU cycles)| 100 < HCLK <= 120 | 16 < HCLK <= 26  |
00247            +--------------------------------------------------------+
00248   * @{
00249   */
00250 
00251 /**
00252   * @brief  Reset the RCC clock configuration to the default reset state.
00253   * @note   The default reset state of the clock configuration is given below:
00254   *            - MSI ON and used as system clock source
00255   *            - HSE, HSI, PLL, PLLSAI1 and PLLSAI2 OFF
00256   *            - AHB, APB1 and APB2 prescalers set to 1.
00257   *            - CSS, MCO1 OFF
00258   *            - All interrupts disabled
00259   *            - All interrupt and reset flags cleared
00260   * @note   This function does not modify the configuration of the
00261   *            - Peripheral clock sources
00262   *            - LSI, LSE and RTC clocks (Backup domain)
00263   * @retval HAL status
00264   */
00265 HAL_StatusTypeDef HAL_RCC_DeInit(void)
00266 {
00267   uint32_t tickstart;
00268 
00269   /* Reset to default System clock */
00270   /* Set MSION bit */
00271   SET_BIT(RCC->CR, RCC_CR_MSION);
00272 
00273   /* Insure MSIRDY bit is set before writing default MSIRANGE value */
00274   /* Get start tick */
00275   tickstart = HAL_GetTick();
00276 
00277   /* Wait till MSI is ready */
00278   while(READ_BIT(RCC->CR, RCC_CR_MSIRDY) == 0U)
00279   {
00280     if((HAL_GetTick() - tickstart) > MSI_TIMEOUT_VALUE)
00281     {
00282       return HAL_TIMEOUT;
00283     }
00284   }
00285 
00286   /* Set MSIRANGE default value */
00287   MODIFY_REG(RCC->CR, RCC_CR_MSIRANGE, RCC_MSIRANGE_6);
00288 
00289   /* Reset CFGR register (MSI is selected as system clock source) */
00290   CLEAR_REG(RCC->CFGR);
00291 
00292   /* Update the SystemCoreClock global variable for MSI as system clock source */
00293   SystemCoreClock = MSI_VALUE;
00294 
00295   /* Configure the source of time base considering new system clock settings  */
00296   if(HAL_InitTick(uwTickPrio) != HAL_OK)
00297   {
00298     return HAL_ERROR;
00299   }
00300 
00301   /* Insure MSI selected as system clock source */
00302   /* Get start tick */
00303   tickstart = HAL_GetTick();
00304 
00305   /* Wait till system clock source is ready */
00306   while(READ_BIT(RCC->CFGR, RCC_CFGR_SWS) != RCC_CFGR_SWS_MSI)
00307   {
00308     if((HAL_GetTick() - tickstart) > CLOCKSWITCH_TIMEOUT_VALUE)
00309     {
00310       return HAL_TIMEOUT;
00311     }
00312   }
00313 
00314   /* Reset HSION, HSIKERON, HSIASFS, HSEON, HSECSSON, PLLON, PLLSAIxON bits */
00315 #if defined(RCC_PLLSAI2_SUPPORT)
00316 
00317   CLEAR_BIT(RCC->CR, RCC_CR_HSEON | RCC_CR_HSION | RCC_CR_HSIKERON| RCC_CR_HSIASFS | RCC_CR_PLLON | RCC_CR_PLLSAI1ON | RCC_CR_PLLSAI2ON);
00318 
00319 #elif defined(RCC_PLLSAI1_SUPPORT)
00320 
00321   CLEAR_BIT(RCC->CR, RCC_CR_HSEON | RCC_CR_HSION | RCC_CR_HSIKERON| RCC_CR_HSIASFS | RCC_CR_PLLON | RCC_CR_PLLSAI1ON);
00322 
00323 #else
00324 
00325   CLEAR_BIT(RCC->CR, RCC_CR_HSEON | RCC_CR_HSION | RCC_CR_HSIKERON| RCC_CR_HSIASFS | RCC_CR_PLLON);
00326 
00327 #endif /* RCC_PLLSAI2_SUPPORT */
00328 
00329   /* Insure PLLRDY, PLLSAI1RDY and PLLSAI2RDY (if present) are reset */
00330   /* Get start tick */
00331   tickstart = HAL_GetTick();
00332 
00333 #if defined(RCC_PLLSAI2_SUPPORT)
00334 
00335   while(READ_BIT(RCC->CR, RCC_CR_PLLRDY | RCC_CR_PLLSAI1RDY | RCC_CR_PLLSAI2RDY) != 0U)
00336 
00337 #elif defined(RCC_PLLSAI1_SUPPORT)
00338 
00339   while(READ_BIT(RCC->CR, RCC_CR_PLLRDY | RCC_CR_PLLSAI1RDY) != 0U)
00340 
00341 #else
00342 
00343   while(READ_BIT(RCC->CR, RCC_CR_PLLRDY) != 0U)
00344 
00345 #endif
00346   {
00347     if((HAL_GetTick() - tickstart) > PLL_TIMEOUT_VALUE)
00348     {
00349       return HAL_TIMEOUT;
00350     }
00351   }
00352 
00353   /* Reset PLLCFGR register */
00354   CLEAR_REG(RCC->PLLCFGR);
00355   SET_BIT(RCC->PLLCFGR, RCC_PLLCFGR_PLLN_4 );
00356 
00357 #if defined(RCC_PLLSAI1_SUPPORT)
00358 
00359   /* Reset PLLSAI1CFGR register */
00360   CLEAR_REG(RCC->PLLSAI1CFGR);
00361   SET_BIT(RCC->PLLSAI1CFGR,  RCC_PLLSAI1CFGR_PLLSAI1N_4 );
00362 
00363 #endif /* RCC_PLLSAI1_SUPPORT */
00364 
00365 #if defined(RCC_PLLSAI2_SUPPORT)
00366 
00367   /* Reset PLLSAI2CFGR register */
00368   CLEAR_REG(RCC->PLLSAI2CFGR);
00369   SET_BIT(RCC->PLLSAI2CFGR,  RCC_PLLSAI2CFGR_PLLSAI2N_4 );
00370 
00371 #endif /* RCC_PLLSAI2_SUPPORT */
00372 
00373   /* Reset HSEBYP bit */
00374   CLEAR_BIT(RCC->CR, RCC_CR_HSEBYP);
00375 
00376   /* Disable all interrupts */
00377   CLEAR_REG(RCC->CIER);
00378 
00379   /* Clear all interrupt flags */
00380   WRITE_REG(RCC->CICR, 0xFFFFFFFFU);
00381 
00382   /* Clear all reset flags */
00383   SET_BIT(RCC->CSR, RCC_CSR_RMVF);
00384 
00385   return HAL_OK;
00386 }
00387 
00388 /**
00389   * @brief  Initialize the RCC Oscillators according to the specified parameters in the
00390   *         RCC_OscInitTypeDef.
00391   * @param  RCC_OscInitStruct  pointer to an RCC_OscInitTypeDef structure that
00392   *         contains the configuration information for the RCC Oscillators.
00393   * @note   The PLL is not disabled when used as system clock.
00394   * @note   The PLL source is not updated when used as PLLSAI(s) clock source.
00395   * @note   Transitions LSE Bypass to LSE On and LSE On to LSE Bypass are not
00396   *         supported by this macro. User should request a transition to LSE Off
00397   *         first and then LSE On or LSE Bypass.
00398   * @note   Transition HSE Bypass to HSE On and HSE On to HSE Bypass are not
00399   *         supported by this macro. User should request a transition to HSE Off
00400   *         first and then HSE On or HSE Bypass.
00401   * @retval HAL status
00402   */
00403 HAL_StatusTypeDef HAL_RCC_OscConfig(RCC_OscInitTypeDef  *RCC_OscInitStruct)
00404 {
00405   uint32_t tickstart;
00406   HAL_StatusTypeDef status;
00407   uint32_t sysclk_source, pll_config;
00408 
00409   /* Check Null pointer */
00410   if(RCC_OscInitStruct == NULL)
00411   {
00412     return HAL_ERROR;
00413   }
00414 
00415   /* Check the parameters */
00416   assert_param(IS_RCC_OSCILLATORTYPE(RCC_OscInitStruct->OscillatorType));
00417 
00418   sysclk_source = __HAL_RCC_GET_SYSCLK_SOURCE();
00419   pll_config = __HAL_RCC_GET_PLL_OSCSOURCE();
00420 
00421   /*----------------------------- MSI Configuration --------------------------*/
00422   if(((RCC_OscInitStruct->OscillatorType) & RCC_OSCILLATORTYPE_MSI) == RCC_OSCILLATORTYPE_MSI)
00423   {
00424     /* Check the parameters */
00425     assert_param(IS_RCC_MSI(RCC_OscInitStruct->MSIState));
00426     assert_param(IS_RCC_MSICALIBRATION_VALUE(RCC_OscInitStruct->MSICalibrationValue));
00427     assert_param(IS_RCC_MSI_CLOCK_RANGE(RCC_OscInitStruct->MSIClockRange));
00428 
00429     /* Check if MSI is used as system clock or as PLL source when PLL is selected as system clock */
00430     if((sysclk_source == RCC_CFGR_SWS_MSI) ||
00431        ((sysclk_source == RCC_CFGR_SWS_PLL) && (pll_config == RCC_PLLSOURCE_MSI)))
00432     {
00433       if((READ_BIT(RCC->CR, RCC_CR_MSIRDY) != 0U) && (RCC_OscInitStruct->MSIState == RCC_MSI_OFF))
00434       {
00435         return HAL_ERROR;
00436       }
00437 
00438        /* Otherwise, just the calibration and MSI range change are allowed */
00439       else
00440       {
00441         /* To correctly read data from FLASH memory, the number of wait states (LATENCY)
00442            must be correctly programmed according to the frequency of the CPU clock
00443            (HCLK) and the supply voltage of the device. */
00444         if(RCC_OscInitStruct->MSIClockRange > __HAL_RCC_GET_MSI_RANGE())
00445         {
00446           /* First increase number of wait states update if necessary */
00447           if(RCC_SetFlashLatencyFromMSIRange(RCC_OscInitStruct->MSIClockRange) != HAL_OK)
00448           {
00449             return HAL_ERROR;
00450           }
00451 
00452           /* Selects the Multiple Speed oscillator (MSI) clock range .*/
00453           __HAL_RCC_MSI_RANGE_CONFIG(RCC_OscInitStruct->MSIClockRange);
00454           /* Adjusts the Multiple Speed oscillator (MSI) calibration value.*/
00455           __HAL_RCC_MSI_CALIBRATIONVALUE_ADJUST(RCC_OscInitStruct->MSICalibrationValue);
00456         }
00457         else
00458         {
00459           /* Else, keep current flash latency while decreasing applies */
00460           /* Selects the Multiple Speed oscillator (MSI) clock range .*/
00461           __HAL_RCC_MSI_RANGE_CONFIG(RCC_OscInitStruct->MSIClockRange);
00462           /* Adjusts the Multiple Speed oscillator (MSI) calibration value.*/
00463           __HAL_RCC_MSI_CALIBRATIONVALUE_ADJUST(RCC_OscInitStruct->MSICalibrationValue);
00464 
00465           /* Decrease number of wait states update if necessary */
00466           /* Only possible when MSI is the System clock source  */
00467           if(sysclk_source == RCC_CFGR_SWS_MSI)
00468           {
00469             if(RCC_SetFlashLatencyFromMSIRange(RCC_OscInitStruct->MSIClockRange) != HAL_OK)
00470             {
00471               return HAL_ERROR;
00472             }
00473           }
00474         }
00475 
00476         /* Update the SystemCoreClock global variable */
00477         SystemCoreClock = HAL_RCC_GetSysClockFreq() >> (AHBPrescTable[READ_BIT(RCC->CFGR, RCC_CFGR_HPRE) >> RCC_CFGR_HPRE_Pos] & 0x1FU);
00478 
00479         /* Configure the source of time base considering new system clocks settings*/
00480         status = HAL_InitTick(uwTickPrio);
00481         if(status != HAL_OK)
00482         {
00483           return status;
00484         }
00485       }
00486     }
00487     else
00488     {
00489       /* Check the MSI State */
00490       if(RCC_OscInitStruct->MSIState != RCC_MSI_OFF)
00491       {
00492         /* Enable the Internal High Speed oscillator (MSI). */
00493         __HAL_RCC_MSI_ENABLE();
00494 
00495         /* Get timeout */
00496         tickstart = HAL_GetTick();
00497 
00498         /* Wait till MSI is ready */
00499         while(READ_BIT(RCC->CR, RCC_CR_MSIRDY) == 0U)
00500         {
00501           if((HAL_GetTick() - tickstart) > MSI_TIMEOUT_VALUE)
00502           {
00503             return HAL_TIMEOUT;
00504           }
00505         }
00506          /* Selects the Multiple Speed oscillator (MSI) clock range .*/
00507         __HAL_RCC_MSI_RANGE_CONFIG(RCC_OscInitStruct->MSIClockRange);
00508          /* Adjusts the Multiple Speed oscillator (MSI) calibration value.*/
00509         __HAL_RCC_MSI_CALIBRATIONVALUE_ADJUST(RCC_OscInitStruct->MSICalibrationValue);
00510 
00511       }
00512       else
00513       {
00514         /* Disable the Internal High Speed oscillator (MSI). */
00515         __HAL_RCC_MSI_DISABLE();
00516 
00517         /* Get timeout */
00518         tickstart = HAL_GetTick();
00519 
00520         /* Wait till MSI is ready */
00521         while(READ_BIT(RCC->CR, RCC_CR_MSIRDY) != 0U)
00522         {
00523           if((HAL_GetTick() - tickstart) > MSI_TIMEOUT_VALUE)
00524           {
00525             return HAL_TIMEOUT;
00526           }
00527         }
00528       }
00529     }
00530   }
00531   /*------------------------------- HSE Configuration ------------------------*/
00532   if(((RCC_OscInitStruct->OscillatorType) & RCC_OSCILLATORTYPE_HSE) == RCC_OSCILLATORTYPE_HSE)
00533   {
00534     /* Check the parameters */
00535     assert_param(IS_RCC_HSE(RCC_OscInitStruct->HSEState));
00536 
00537     /* When the HSE is used as system clock or clock source for PLL in these cases it is not allowed to be disabled */
00538     if((sysclk_source == RCC_CFGR_SWS_HSE) ||
00539        ((sysclk_source == RCC_CFGR_SWS_PLL) && (pll_config == RCC_PLLSOURCE_HSE)))
00540     {
00541       if((READ_BIT(RCC->CR, RCC_CR_HSERDY) != 0U) && (RCC_OscInitStruct->HSEState == RCC_HSE_OFF))
00542       {
00543         return HAL_ERROR;
00544       }
00545     }
00546     else
00547     {
00548       /* Set the new HSE configuration ---------------------------------------*/
00549       __HAL_RCC_HSE_CONFIG(RCC_OscInitStruct->HSEState);
00550 
00551       /* Check the HSE State */
00552       if(RCC_OscInitStruct->HSEState != RCC_HSE_OFF)
00553       {
00554         /* Get Start Tick*/
00555         tickstart = HAL_GetTick();
00556 
00557         /* Wait till HSE is ready */
00558         while(READ_BIT(RCC->CR, RCC_CR_HSERDY) == 0U)
00559         {
00560           if((HAL_GetTick() - tickstart) > HSE_TIMEOUT_VALUE)
00561           {
00562             return HAL_TIMEOUT;
00563           }
00564         }
00565       }
00566       else
00567       {
00568         /* Get Start Tick*/
00569         tickstart = HAL_GetTick();
00570 
00571         /* Wait till HSE is disabled */
00572         while(READ_BIT(RCC->CR, RCC_CR_HSERDY) != 0U)
00573         {
00574           if((HAL_GetTick() - tickstart) > HSE_TIMEOUT_VALUE)
00575           {
00576             return HAL_TIMEOUT;
00577           }
00578         }
00579       }
00580     }
00581   }
00582   /*----------------------------- HSI Configuration --------------------------*/
00583   if(((RCC_OscInitStruct->OscillatorType) & RCC_OSCILLATORTYPE_HSI) == RCC_OSCILLATORTYPE_HSI)
00584   {
00585     /* Check the parameters */
00586     assert_param(IS_RCC_HSI(RCC_OscInitStruct->HSIState));
00587     assert_param(IS_RCC_HSI_CALIBRATION_VALUE(RCC_OscInitStruct->HSICalibrationValue));
00588 
00589     /* Check if HSI is used as system clock or as PLL source when PLL is selected as system clock */
00590     if((sysclk_source == RCC_CFGR_SWS_HSI) ||
00591        ((sysclk_source == RCC_CFGR_SWS_PLL) && (pll_config == RCC_PLLSOURCE_HSI)))
00592     {
00593       /* When HSI is used as system clock it will not be disabled */
00594       if((READ_BIT(RCC->CR, RCC_CR_HSIRDY) != 0U) && (RCC_OscInitStruct->HSIState == RCC_HSI_OFF))
00595       {
00596         return HAL_ERROR;
00597       }
00598       /* Otherwise, just the calibration is allowed */
00599       else
00600       {
00601         /* Adjusts the Internal High Speed oscillator (HSI) calibration value.*/
00602         __HAL_RCC_HSI_CALIBRATIONVALUE_ADJUST(RCC_OscInitStruct->HSICalibrationValue);
00603       }
00604     }
00605     else
00606     {
00607       /* Check the HSI State */
00608       if(RCC_OscInitStruct->HSIState != RCC_HSI_OFF)
00609       {
00610         /* Enable the Internal High Speed oscillator (HSI). */
00611         __HAL_RCC_HSI_ENABLE();
00612 
00613         /* Get Start Tick*/
00614         tickstart = HAL_GetTick();
00615 
00616         /* Wait till HSI is ready */
00617         while(READ_BIT(RCC->CR, RCC_CR_HSIRDY) == 0U)
00618         {
00619           if((HAL_GetTick() - tickstart) > HSI_TIMEOUT_VALUE)
00620           {
00621             return HAL_TIMEOUT;
00622           }
00623         }
00624 
00625         /* Adjusts the Internal High Speed oscillator (HSI) calibration value.*/
00626         __HAL_RCC_HSI_CALIBRATIONVALUE_ADJUST(RCC_OscInitStruct->HSICalibrationValue);
00627       }
00628       else
00629       {
00630         /* Disable the Internal High Speed oscillator (HSI). */
00631         __HAL_RCC_HSI_DISABLE();
00632 
00633         /* Get Start Tick*/
00634         tickstart = HAL_GetTick();
00635 
00636         /* Wait till HSI is disabled */
00637         while(READ_BIT(RCC->CR, RCC_CR_HSIRDY) != 0U)
00638         {
00639           if((HAL_GetTick() - tickstart) > HSI_TIMEOUT_VALUE)
00640           {
00641             return HAL_TIMEOUT;
00642           }
00643         }
00644       }
00645     }
00646   }
00647   /*------------------------------ LSI Configuration -------------------------*/
00648   if(((RCC_OscInitStruct->OscillatorType) & RCC_OSCILLATORTYPE_LSI) == RCC_OSCILLATORTYPE_LSI)
00649   {
00650     /* Check the parameters */
00651     assert_param(IS_RCC_LSI(RCC_OscInitStruct->LSIState));
00652 
00653     /* Check the LSI State */
00654     if(RCC_OscInitStruct->LSIState != RCC_LSI_OFF)
00655     {
00656 #if defined(RCC_CSR_LSIPREDIV)
00657       uint32_t csr_temp = RCC->CSR;
00658 
00659       /* Check LSI division factor */
00660       assert_param(IS_RCC_LSIDIV(RCC_OscInitStruct->LSIDiv));
00661 
00662       if (RCC_OscInitStruct->LSIDiv != (csr_temp & RCC_CSR_LSIPREDIV))
00663       {
00664         if (((csr_temp & RCC_CSR_LSIRDY) == RCC_CSR_LSIRDY) && \
00665             ((csr_temp & RCC_CSR_LSION) != RCC_CSR_LSION))
00666         {
00667            /* If LSIRDY is set while LSION is not enabled,
00668               LSIPREDIV can't be updated  */
00669           return HAL_ERROR;
00670         }
00671 
00672         /* Turn off LSI before changing RCC_CSR_LSIPREDIV */
00673         if ((csr_temp & RCC_CSR_LSION) == RCC_CSR_LSION)
00674         {
00675           __HAL_RCC_LSI_DISABLE();
00676 
00677           /* Get Start Tick*/
00678           tickstart = HAL_GetTick();
00679 
00680           /* Wait till LSI is disabled */
00681           while(READ_BIT(RCC->CSR, RCC_CSR_LSIRDY) != 0U)
00682           {
00683             if((HAL_GetTick() - tickstart) > LSI_TIMEOUT_VALUE)
00684             {
00685               return HAL_TIMEOUT;
00686             }
00687           }
00688         }
00689 
00690         /* Set LSI division factor */
00691         MODIFY_REG(RCC->CSR, RCC_CSR_LSIPREDIV, RCC_OscInitStruct->LSIDiv);
00692       }
00693 #endif /* RCC_CSR_LSIPREDIV */
00694 
00695       /* Enable the Internal Low Speed oscillator (LSI). */
00696       __HAL_RCC_LSI_ENABLE();
00697 
00698       /* Get Start Tick*/
00699       tickstart = HAL_GetTick();
00700 
00701       /* Wait till LSI is ready */
00702       while(READ_BIT(RCC->CSR, RCC_CSR_LSIRDY) == 0U)
00703       {
00704         if((HAL_GetTick() - tickstart) > LSI_TIMEOUT_VALUE)
00705         {
00706           return HAL_TIMEOUT;
00707         }
00708       }
00709     }
00710     else
00711     {
00712       /* Disable the Internal Low Speed oscillator (LSI). */
00713       __HAL_RCC_LSI_DISABLE();
00714 
00715       /* Get Start Tick*/
00716       tickstart = HAL_GetTick();
00717 
00718       /* Wait till LSI is disabled */
00719       while(READ_BIT(RCC->CSR, RCC_CSR_LSIRDY) != 0U)
00720       {
00721         if((HAL_GetTick() - tickstart) > LSI_TIMEOUT_VALUE)
00722         {
00723           return HAL_TIMEOUT;
00724         }
00725       }
00726     }
00727   }
00728   /*------------------------------ LSE Configuration -------------------------*/
00729   if(((RCC_OscInitStruct->OscillatorType) & RCC_OSCILLATORTYPE_LSE) == RCC_OSCILLATORTYPE_LSE)
00730   {
00731     FlagStatus       pwrclkchanged = RESET;
00732 
00733     /* Check the parameters */
00734     assert_param(IS_RCC_LSE(RCC_OscInitStruct->LSEState));
00735 
00736     /* Update LSE configuration in Backup Domain control register    */
00737     /* Requires to enable write access to Backup Domain of necessary */
00738     if(HAL_IS_BIT_CLR(RCC->APB1ENR1, RCC_APB1ENR1_PWREN))
00739     {
00740       __HAL_RCC_PWR_CLK_ENABLE();
00741       pwrclkchanged = SET;
00742     }
00743 
00744     if(HAL_IS_BIT_CLR(PWR->CR1, PWR_CR1_DBP))
00745     {
00746       /* Enable write access to Backup domain */
00747       SET_BIT(PWR->CR1, PWR_CR1_DBP);
00748 
00749       /* Wait for Backup domain Write protection disable */
00750       tickstart = HAL_GetTick();
00751 
00752       while(HAL_IS_BIT_CLR(PWR->CR1, PWR_CR1_DBP))
00753       {
00754         if((HAL_GetTick() - tickstart) > RCC_DBP_TIMEOUT_VALUE)
00755         {
00756           return HAL_TIMEOUT;
00757         }
00758       }
00759     }
00760 
00761     /* Set the new LSE configuration -----------------------------------------*/
00762 #if defined(RCC_BDCR_LSESYSDIS)
00763     if((RCC_OscInitStruct->LSEState & RCC_BDCR_LSEON) != 0U)
00764     {
00765       /* Set LSESYSDIS bit according to LSE propagation option (enabled or disabled) */
00766       MODIFY_REG(RCC->BDCR, RCC_BDCR_LSESYSDIS, (RCC_OscInitStruct->LSEState & RCC_BDCR_LSESYSDIS));
00767 
00768       if((RCC_OscInitStruct->LSEState & RCC_BDCR_LSEBYP) != 0U)
00769       {
00770         /* LSE oscillator bypass enable */
00771         SET_BIT(RCC->BDCR, RCC_BDCR_LSEBYP);
00772         SET_BIT(RCC->BDCR, RCC_BDCR_LSEON);
00773       }
00774       else
00775       {
00776         /* LSE oscillator enable */
00777         SET_BIT(RCC->BDCR, RCC_BDCR_LSEON);
00778       }
00779     }
00780     else
00781     {
00782       CLEAR_BIT(RCC->BDCR, RCC_BDCR_LSEON);
00783       CLEAR_BIT(RCC->BDCR, RCC_BDCR_LSEBYP);
00784     }
00785 #else
00786     __HAL_RCC_LSE_CONFIG(RCC_OscInitStruct->LSEState);
00787 #endif /* RCC_BDCR_LSESYSDIS */
00788 
00789     /* Check the LSE State */
00790     if(RCC_OscInitStruct->LSEState != RCC_LSE_OFF)
00791     {
00792       /* Get Start Tick*/
00793       tickstart = HAL_GetTick();
00794 
00795       /* Wait till LSE is ready */
00796       while(READ_BIT(RCC->BDCR, RCC_BDCR_LSERDY) == 0U)
00797       {
00798         if((HAL_GetTick() - tickstart) > RCC_LSE_TIMEOUT_VALUE)
00799         {
00800           return HAL_TIMEOUT;
00801         }
00802       }
00803     }
00804     else
00805     {
00806       /* Get Start Tick*/
00807       tickstart = HAL_GetTick();
00808 
00809       /* Wait till LSE is disabled */
00810       while(READ_BIT(RCC->BDCR, RCC_BDCR_LSERDY) != 0U)
00811       {
00812         if((HAL_GetTick() - tickstart) > RCC_LSE_TIMEOUT_VALUE)
00813         {
00814           return HAL_TIMEOUT;
00815         }
00816       }
00817 
00818 #if defined(RCC_BDCR_LSESYSDIS)
00819       /* By default, stop disabling LSE propagation */
00820       CLEAR_BIT(RCC->BDCR, RCC_BDCR_LSESYSDIS);
00821 #endif /* RCC_BDCR_LSESYSDIS */
00822     }
00823 
00824     /* Restore clock configuration if changed */
00825     if(pwrclkchanged == SET)
00826     {
00827       __HAL_RCC_PWR_CLK_DISABLE();
00828     }
00829   }
00830 #if defined(RCC_HSI48_SUPPORT)
00831   /*------------------------------ HSI48 Configuration -----------------------*/
00832   if(((RCC_OscInitStruct->OscillatorType) & RCC_OSCILLATORTYPE_HSI48) == RCC_OSCILLATORTYPE_HSI48)
00833   {
00834     /* Check the parameters */
00835     assert_param(IS_RCC_HSI48(RCC_OscInitStruct->HSI48State));
00836 
00837     /* Check the LSI State */
00838     if(RCC_OscInitStruct->HSI48State != RCC_HSI48_OFF)
00839     {
00840       /* Enable the Internal Low Speed oscillator (HSI48). */
00841       __HAL_RCC_HSI48_ENABLE();
00842 
00843       /* Get Start Tick*/
00844       tickstart = HAL_GetTick();
00845 
00846       /* Wait till HSI48 is ready */
00847       while(READ_BIT(RCC->CRRCR, RCC_CRRCR_HSI48RDY) == 0U)
00848       {
00849         if((HAL_GetTick() - tickstart) > HSI48_TIMEOUT_VALUE)
00850         {
00851           return HAL_TIMEOUT;
00852         }
00853       }
00854     }
00855     else
00856     {
00857       /* Disable the Internal Low Speed oscillator (HSI48). */
00858       __HAL_RCC_HSI48_DISABLE();
00859 
00860       /* Get Start Tick*/
00861       tickstart = HAL_GetTick();
00862 
00863       /* Wait till HSI48 is disabled */
00864       while(READ_BIT(RCC->CRRCR, RCC_CRRCR_HSI48RDY) != 0U)
00865       {
00866         if((HAL_GetTick() - tickstart) > HSI48_TIMEOUT_VALUE)
00867         {
00868           return HAL_TIMEOUT;
00869         }
00870       }
00871     }
00872   }
00873 #endif /* RCC_HSI48_SUPPORT */
00874   /*-------------------------------- PLL Configuration -----------------------*/
00875   /* Check the parameters */
00876   assert_param(IS_RCC_PLL(RCC_OscInitStruct->PLL.PLLState));
00877 
00878   if(RCC_OscInitStruct->PLL.PLLState != RCC_PLL_NONE)
00879   {
00880     /* PLL On ? */
00881     if(RCC_OscInitStruct->PLL.PLLState == RCC_PLL_ON)
00882     {
00883       /* Check the parameters */
00884       assert_param(IS_RCC_PLLSOURCE(RCC_OscInitStruct->PLL.PLLSource));
00885       assert_param(IS_RCC_PLLM_VALUE(RCC_OscInitStruct->PLL.PLLM));
00886       assert_param(IS_RCC_PLLN_VALUE(RCC_OscInitStruct->PLL.PLLN));
00887 #if defined(RCC_PLLP_SUPPORT)
00888       assert_param(IS_RCC_PLLP_VALUE(RCC_OscInitStruct->PLL.PLLP));
00889 #endif /* RCC_PLLP_SUPPORT */
00890       assert_param(IS_RCC_PLLQ_VALUE(RCC_OscInitStruct->PLL.PLLQ));
00891       assert_param(IS_RCC_PLLR_VALUE(RCC_OscInitStruct->PLL.PLLR));
00892 
00893       /* Do nothing if PLL configuration is the unchanged */
00894       pll_config = RCC->PLLCFGR;
00895       if((READ_BIT(pll_config, RCC_PLLCFGR_PLLSRC)  != RCC_OscInitStruct->PLL.PLLSource) ||
00896          (READ_BIT(pll_config, RCC_PLLCFGR_PLLM)    != ((RCC_OscInitStruct->PLL.PLLM - 1U) << RCC_PLLCFGR_PLLM_Pos)) ||
00897          (READ_BIT(pll_config, RCC_PLLCFGR_PLLN)    != (RCC_OscInitStruct->PLL.PLLN << RCC_PLLCFGR_PLLN_Pos)) ||
00898 #if defined(RCC_PLLP_SUPPORT)
00899 #if defined(RCC_PLLP_DIV_2_31_SUPPORT)
00900          (READ_BIT(pll_config, RCC_PLLCFGR_PLLPDIV) != (RCC_OscInitStruct->PLL.PLLP << RCC_PLLCFGR_PLLPDIV_Pos)) ||
00901 #else
00902          (READ_BIT(pll_config, RCC_PLLCFGR_PLLP)    != ((RCC_OscInitStruct->PLL.PLLP == RCC_PLLP_DIV7) ? 0U : 1U)) ||
00903 #endif
00904 #endif
00905          (READ_BIT(pll_config, RCC_PLLCFGR_PLLQ)    != ((((RCC_OscInitStruct->PLL.PLLQ) >> 1U) - 1U) << RCC_PLLCFGR_PLLQ_Pos)) ||
00906          (READ_BIT(pll_config, RCC_PLLCFGR_PLLR)    != ((((RCC_OscInitStruct->PLL.PLLR) >> 1U) - 1U) << RCC_PLLCFGR_PLLR_Pos)))
00907       {
00908         /* Check if the PLL is used as system clock or not */
00909         if(sysclk_source != RCC_CFGR_SWS_PLL)
00910         {
00911 #if defined(RCC_PLLSAI1_SUPPORT) || defined(RCC_PLLSAI2_SUPPORT)
00912           /* Check if main PLL can be updated */
00913           /* Not possible if the source is shared by other enabled PLLSAIx */
00914           if((READ_BIT(RCC->CR, RCC_CR_PLLSAI1ON) != 0U)
00915 #if defined(RCC_PLLSAI2_SUPPORT)
00916              || (READ_BIT(RCC->CR, RCC_CR_PLLSAI2ON) != 0U)
00917 #endif
00918             )
00919           {
00920             return HAL_ERROR;
00921           }
00922           else
00923 #endif /* RCC_PLLSAI1_SUPPORT || RCC_PLLSAI2_SUPPORT */
00924           {
00925             /* Disable the main PLL. */
00926             __HAL_RCC_PLL_DISABLE();
00927 
00928             /* Get Start Tick*/
00929             tickstart = HAL_GetTick();
00930 
00931             /* Wait till PLL is ready */
00932             while(READ_BIT(RCC->CR, RCC_CR_PLLRDY) != 0U)
00933             {
00934               if((HAL_GetTick() - tickstart) > PLL_TIMEOUT_VALUE)
00935               {
00936                 return HAL_TIMEOUT;
00937               }
00938             }
00939 
00940             /* Configure the main PLL clock source, multiplication and division factors. */
00941 #if defined(RCC_PLLP_SUPPORT)
00942             __HAL_RCC_PLL_CONFIG(RCC_OscInitStruct->PLL.PLLSource,
00943                                  RCC_OscInitStruct->PLL.PLLM,
00944                                  RCC_OscInitStruct->PLL.PLLN,
00945                                  RCC_OscInitStruct->PLL.PLLP,
00946                                  RCC_OscInitStruct->PLL.PLLQ,
00947                                  RCC_OscInitStruct->PLL.PLLR);
00948 #else
00949             __HAL_RCC_PLL_CONFIG(RCC_OscInitStruct->PLL.PLLSource,
00950                                  RCC_OscInitStruct->PLL.PLLM,
00951                                  RCC_OscInitStruct->PLL.PLLN,
00952                                  RCC_OscInitStruct->PLL.PLLQ,
00953                                  RCC_OscInitStruct->PLL.PLLR);
00954 #endif
00955 
00956             /* Enable the main PLL. */
00957             __HAL_RCC_PLL_ENABLE();
00958 
00959             /* Enable PLL System Clock output. */
00960             __HAL_RCC_PLLCLKOUT_ENABLE(RCC_PLL_SYSCLK);
00961 
00962             /* Get Start Tick*/
00963             tickstart = HAL_GetTick();
00964 
00965             /* Wait till PLL is ready */
00966             while(READ_BIT(RCC->CR, RCC_CR_PLLRDY) == 0U)
00967             {
00968               if((HAL_GetTick() - tickstart) > PLL_TIMEOUT_VALUE)
00969               {
00970                 return HAL_TIMEOUT;
00971               }
00972             }
00973           }
00974         }
00975         else
00976         {
00977           /* PLL is already used as System core clock */
00978           return HAL_ERROR;
00979         }
00980       }
00981       else
00982       {
00983         /* PLL configuration is unchanged */
00984         /* Re-enable PLL if it was disabled (ie. low power mode) */
00985         if(READ_BIT(RCC->CR, RCC_CR_PLLRDY) == 0U)
00986         {
00987           /* Enable the main PLL. */
00988           __HAL_RCC_PLL_ENABLE();
00989 
00990           /* Enable PLL System Clock output. */
00991           __HAL_RCC_PLLCLKOUT_ENABLE(RCC_PLL_SYSCLK);
00992 
00993           /* Get Start Tick*/
00994           tickstart = HAL_GetTick();
00995 
00996           /* Wait till PLL is ready */
00997           while(READ_BIT(RCC->CR, RCC_CR_PLLRDY) == 0U)
00998           {
00999             if((HAL_GetTick() - tickstart) > PLL_TIMEOUT_VALUE)
01000             {
01001               return HAL_TIMEOUT;
01002             }
01003           }
01004         }
01005       }
01006     }
01007     else
01008     {
01009       /* Check that PLL is not used as system clock or not */
01010       if(sysclk_source != RCC_CFGR_SWS_PLL)
01011       {
01012         /* Disable the main PLL. */
01013         __HAL_RCC_PLL_DISABLE();
01014 
01015         /* Disable all PLL outputs to save power if no PLLs on */
01016 #if defined(RCC_PLLSAI1_SUPPORT) && defined(RCC_CR_PLLSAI2RDY)
01017         if(READ_BIT(RCC->CR, (RCC_CR_PLLSAI1RDY | RCC_CR_PLLSAI2RDY)) == 0U)
01018         {
01019           MODIFY_REG(RCC->PLLCFGR, RCC_PLLCFGR_PLLSRC, RCC_PLLSOURCE_NONE);
01020         }
01021 #elif defined(RCC_PLLSAI1_SUPPORT)
01022         if(READ_BIT(RCC->CR, RCC_CR_PLLSAI1RDY) == 0U)
01023         {
01024           MODIFY_REG(RCC->PLLCFGR, RCC_PLLCFGR_PLLSRC, RCC_PLLSOURCE_NONE);
01025         }
01026 #else
01027         MODIFY_REG(RCC->PLLCFGR, RCC_PLLCFGR_PLLSRC, RCC_PLLSOURCE_NONE);
01028 #endif /* RCC_PLLSAI1_SUPPORT && RCC_CR_PLLSAI2RDY */
01029 
01030 #if defined(RCC_PLLSAI2_SUPPORT)
01031         __HAL_RCC_PLLCLKOUT_DISABLE(RCC_PLL_SYSCLK | RCC_PLL_48M1CLK | RCC_PLL_SAI3CLK);
01032 #elif defined(RCC_PLLSAI1_SUPPORT)
01033         __HAL_RCC_PLLCLKOUT_DISABLE(RCC_PLL_SYSCLK | RCC_PLL_48M1CLK | RCC_PLL_SAI2CLK);
01034 #else
01035         __HAL_RCC_PLLCLKOUT_DISABLE(RCC_PLL_SYSCLK | RCC_PLL_48M1CLK);
01036 #endif /* RCC_PLLSAI2_SUPPORT */
01037 
01038         /* Get Start Tick*/
01039         tickstart = HAL_GetTick();
01040 
01041         /* Wait till PLL is disabled */
01042         while(READ_BIT(RCC->CR, RCC_CR_PLLRDY) != 0U)
01043         {
01044           if((HAL_GetTick() - tickstart) > PLL_TIMEOUT_VALUE)
01045           {
01046             return HAL_TIMEOUT;
01047           }
01048         }
01049       }
01050       else
01051       {
01052         /* PLL is already used as System core clock */
01053         return HAL_ERROR;
01054       }
01055     }
01056   }
01057   return HAL_OK;
01058 }
01059 
01060 /**
01061   * @brief  Initialize the CPU, AHB and APB busses clocks according to the specified
01062   *         parameters in the RCC_ClkInitStruct.
01063   * @param  RCC_ClkInitStruct  pointer to an RCC_OscInitTypeDef structure that
01064   *         contains the configuration information for the RCC peripheral.
01065   * @param  FLatency  FLASH Latency
01066   *          This parameter can be one of the following values:
01067   *            @arg FLASH_LATENCY_0   FLASH 0 Latency cycle
01068   *            @arg FLASH_LATENCY_1   FLASH 1 Latency cycle
01069   *            @arg FLASH_LATENCY_2   FLASH 2 Latency cycles
01070   *            @arg FLASH_LATENCY_3   FLASH 3 Latency cycles
01071   *            @arg FLASH_LATENCY_4   FLASH 4 Latency cycles
01072   @if STM32L4S9xx
01073   *            @arg FLASH_LATENCY_5   FLASH 5 Latency cycles
01074   *            @arg FLASH_LATENCY_6   FLASH 6 Latency cycles
01075   *            @arg FLASH_LATENCY_7   FLASH 7 Latency cycles
01076   *            @arg FLASH_LATENCY_8   FLASH 8 Latency cycles
01077   *            @arg FLASH_LATENCY_9   FLASH 9 Latency cycles
01078   *            @arg FLASH_LATENCY_10  FLASH 10 Latency cycles
01079   *            @arg FLASH_LATENCY_11  FLASH 11 Latency cycles
01080   *            @arg FLASH_LATENCY_12  FLASH 12 Latency cycles
01081   *            @arg FLASH_LATENCY_13  FLASH 13 Latency cycles
01082   *            @arg FLASH_LATENCY_14  FLASH 14 Latency cycles
01083   *            @arg FLASH_LATENCY_15  FLASH 15 Latency cycles
01084   @endif
01085   *
01086   * @note   The SystemCoreClock CMSIS variable is used to store System Clock Frequency
01087   *         and updated by HAL_RCC_GetHCLKFreq() function called within this function
01088   *
01089   * @note   The MSI is used by default as system clock source after
01090   *         startup from Reset, wake-up from STANDBY mode. After restart from Reset,
01091   *         the MSI frequency is set to its default value 4 MHz.
01092   *
01093   * @note   The HSI can be selected as system clock source after
01094   *         from STOP modes or in case of failure of the HSE used directly or indirectly
01095   *         as system clock (if the Clock Security System CSS is enabled).
01096   *
01097   * @note   A switch from one clock source to another occurs only if the target
01098   *         clock source is ready (clock stable after startup delay or PLL locked).
01099   *         If a clock source which is not yet ready is selected, the switch will
01100   *         occur when the clock source is ready.
01101   *
01102   * @note   You can use HAL_RCC_GetClockConfig() function to know which clock is
01103   *         currently used as system clock source.
01104   *
01105   * @note   Depending on the device voltage range, the software has to set correctly
01106   *         HPRE[3:0] bits to ensure that HCLK not exceed the maximum allowed frequency
01107   *         (for more details refer to section above "Initialization/de-initialization functions")
01108   * @retval None
01109   */
01110 HAL_StatusTypeDef HAL_RCC_ClockConfig(RCC_ClkInitTypeDef  *RCC_ClkInitStruct, uint32_t FLatency)
01111 {
01112   uint32_t tickstart;
01113 #if defined(STM32L4P5xx) || defined(STM32L4Q5xx) || \
01114     defined(STM32L4R5xx) || defined(STM32L4R7xx) || defined(STM32L4R9xx) || defined(STM32L4S5xx) || defined(STM32L4S7xx) || defined(STM32L4S9xx)
01115   uint32_t hpre = RCC_SYSCLK_DIV1;
01116 #endif
01117   HAL_StatusTypeDef status;
01118 
01119   /* Check Null pointer */
01120   if(RCC_ClkInitStruct == NULL)
01121   {
01122     return HAL_ERROR;
01123   }
01124 
01125   /* Check the parameters */
01126   assert_param(IS_RCC_CLOCKTYPE(RCC_ClkInitStruct->ClockType));
01127   assert_param(IS_FLASH_LATENCY(FLatency));
01128 
01129   /* To correctly read data from FLASH memory, the number of wait states (LATENCY)
01130     must be correctly programmed according to the frequency of the CPU clock
01131     (HCLK) and the supply voltage of the device. */
01132 
01133   /* Increasing the number of wait states because of higher CPU frequency */
01134   if(FLatency > __HAL_FLASH_GET_LATENCY())
01135   {
01136     /* Program the new number of wait states to the LATENCY bits in the FLASH_ACR register */
01137     __HAL_FLASH_SET_LATENCY(FLatency);
01138 
01139     /* Check that the new number of wait states is taken into account to access the Flash
01140     memory by reading the FLASH_ACR register */
01141     if(__HAL_FLASH_GET_LATENCY() != FLatency)
01142     {
01143       return HAL_ERROR;
01144     }
01145   }
01146 
01147   /*------------------------- SYSCLK Configuration ---------------------------*/
01148   if(((RCC_ClkInitStruct->ClockType) & RCC_CLOCKTYPE_SYSCLK) == RCC_CLOCKTYPE_SYSCLK)
01149   {
01150     assert_param(IS_RCC_SYSCLKSOURCE(RCC_ClkInitStruct->SYSCLKSource));
01151 
01152     /* PLL is selected as System Clock Source */
01153     if(RCC_ClkInitStruct->SYSCLKSource == RCC_SYSCLKSOURCE_PLLCLK)
01154     {
01155       /* Check the PLL ready flag */
01156       if(READ_BIT(RCC->CR, RCC_CR_PLLRDY) == 0U)
01157       {
01158         return HAL_ERROR;
01159       }
01160 #if defined(STM32L4P5xx) || defined(STM32L4Q5xx) || \
01161     defined(STM32L4R5xx) || defined(STM32L4R7xx) || defined(STM32L4R9xx) || defined(STM32L4S5xx) || defined(STM32L4S7xx) || defined(STM32L4S9xx)
01162       /* Undershoot management when selection PLL as SYSCLK source and frequency above 80Mhz */
01163       /* Compute target PLL output frequency */
01164       if(RCC_GetSysClockFreqFromPLLSource() > 80000000U)
01165       {
01166         if(READ_BIT(RCC->CFGR, RCC_CFGR_HPRE) == RCC_SYSCLK_DIV1)
01167         {
01168           /* Intermediate step with HCLK prescaler 2 necessary before to go over 80Mhz */
01169           MODIFY_REG(RCC->CFGR, RCC_CFGR_HPRE, RCC_SYSCLK_DIV2);
01170           hpre = RCC_SYSCLK_DIV2;
01171         }
01172         else if((((RCC_ClkInitStruct->ClockType) & RCC_CLOCKTYPE_HCLK) == RCC_CLOCKTYPE_HCLK) && (RCC_ClkInitStruct->AHBCLKDivider == RCC_SYSCLK_DIV1))
01173         {
01174           /* Intermediate step with HCLK prescaler 2 necessary before to go over 80Mhz */
01175           MODIFY_REG(RCC->CFGR, RCC_CFGR_HPRE, RCC_SYSCLK_DIV2);
01176           hpre = RCC_SYSCLK_DIV2;
01177         }
01178         else
01179         {
01180           /* nothing to do */
01181         }
01182       }
01183 #endif
01184     }
01185     else
01186     {
01187       /* HSE is selected as System Clock Source */
01188       if(RCC_ClkInitStruct->SYSCLKSource == RCC_SYSCLKSOURCE_HSE)
01189       {
01190         /* Check the HSE ready flag */
01191         if(READ_BIT(RCC->CR, RCC_CR_HSERDY) == 0U)
01192         {
01193           return HAL_ERROR;
01194         }
01195       }
01196       /* MSI is selected as System Clock Source */
01197       else if(RCC_ClkInitStruct->SYSCLKSource == RCC_SYSCLKSOURCE_MSI)
01198       {
01199         /* Check the MSI ready flag */
01200         if(READ_BIT(RCC->CR, RCC_CR_MSIRDY) == 0U)
01201         {
01202           return HAL_ERROR;
01203         }
01204       }
01205       /* HSI is selected as System Clock Source */
01206       else
01207       {
01208         /* Check the HSI ready flag */
01209         if(READ_BIT(RCC->CR, RCC_CR_HSIRDY) == 0U)
01210         {
01211           return HAL_ERROR;
01212         }
01213       }
01214 #if defined(STM32L4P5xx) || defined(STM32L4Q5xx) || \
01215     defined(STM32L4R5xx) || defined(STM32L4R7xx) || defined(STM32L4R9xx) || defined(STM32L4S5xx) || defined(STM32L4S7xx) || defined(STM32L4S9xx)
01216       /* Overshoot management when going down from PLL as SYSCLK source and frequency above 80Mhz */
01217       if(HAL_RCC_GetSysClockFreq() > 80000000U)
01218       {
01219         /* Intermediate step with HCLK prescaler 2 necessary before to go under 80Mhz */
01220         MODIFY_REG(RCC->CFGR, RCC_CFGR_HPRE, RCC_SYSCLK_DIV2);
01221         hpre = RCC_SYSCLK_DIV2;
01222       }
01223 #endif
01224 
01225     }
01226 
01227     MODIFY_REG(RCC->CFGR, RCC_CFGR_SW, RCC_ClkInitStruct->SYSCLKSource);
01228 
01229     /* Get Start Tick*/
01230     tickstart = HAL_GetTick();
01231 
01232     while(__HAL_RCC_GET_SYSCLK_SOURCE() != (RCC_ClkInitStruct->SYSCLKSource << RCC_CFGR_SWS_Pos))
01233     {
01234       if((HAL_GetTick() - tickstart) > CLOCKSWITCH_TIMEOUT_VALUE)
01235       {
01236         return HAL_TIMEOUT;
01237       }
01238     }
01239   }
01240 
01241   /*-------------------------- HCLK Configuration --------------------------*/
01242   if(((RCC_ClkInitStruct->ClockType) & RCC_CLOCKTYPE_HCLK) == RCC_CLOCKTYPE_HCLK)
01243   {
01244     assert_param(IS_RCC_HCLK(RCC_ClkInitStruct->AHBCLKDivider));
01245     MODIFY_REG(RCC->CFGR, RCC_CFGR_HPRE, RCC_ClkInitStruct->AHBCLKDivider);
01246   }
01247 #if defined(STM32L4P5xx) || defined(STM32L4Q5xx) || \
01248     defined(STM32L4R5xx) || defined(STM32L4R7xx) || defined(STM32L4R9xx) || defined(STM32L4S5xx) || defined(STM32L4S7xx) || defined(STM32L4S9xx)
01249   else
01250   {
01251     /* Is intermediate HCLK prescaler 2 applied internally, complete with HCLK prescaler 1 */
01252     if(hpre == RCC_SYSCLK_DIV2)
01253     {
01254       MODIFY_REG(RCC->CFGR, RCC_CFGR_HPRE, RCC_SYSCLK_DIV1);
01255     }
01256   }
01257 #endif
01258 
01259   /* Decreasing the number of wait states because of lower CPU frequency */
01260   if(FLatency < __HAL_FLASH_GET_LATENCY())
01261   {
01262     /* Program the new number of wait states to the LATENCY bits in the FLASH_ACR register */
01263     __HAL_FLASH_SET_LATENCY(FLatency);
01264 
01265     /* Check that the new number of wait states is taken into account to access the Flash
01266     memory by reading the FLASH_ACR register */
01267     if(__HAL_FLASH_GET_LATENCY() != FLatency)
01268     {
01269       return HAL_ERROR;
01270     }
01271   }
01272 
01273   /*-------------------------- PCLK1 Configuration ---------------------------*/
01274   if(((RCC_ClkInitStruct->ClockType) & RCC_CLOCKTYPE_PCLK1) == RCC_CLOCKTYPE_PCLK1)
01275   {
01276     assert_param(IS_RCC_PCLK(RCC_ClkInitStruct->APB1CLKDivider));
01277     MODIFY_REG(RCC->CFGR, RCC_CFGR_PPRE1, RCC_ClkInitStruct->APB1CLKDivider);
01278   }
01279 
01280   /*-------------------------- PCLK2 Configuration ---------------------------*/
01281   if(((RCC_ClkInitStruct->ClockType) & RCC_CLOCKTYPE_PCLK2) == RCC_CLOCKTYPE_PCLK2)
01282   {
01283     assert_param(IS_RCC_PCLK(RCC_ClkInitStruct->APB2CLKDivider));
01284     MODIFY_REG(RCC->CFGR, RCC_CFGR_PPRE2, ((RCC_ClkInitStruct->APB2CLKDivider) << 3U));
01285   }
01286 
01287   /* Update the SystemCoreClock global variable */
01288   SystemCoreClock = HAL_RCC_GetSysClockFreq() >> (AHBPrescTable[READ_BIT(RCC->CFGR, RCC_CFGR_HPRE) >> RCC_CFGR_HPRE_Pos] & 0x1FU);
01289 
01290   /* Configure the source of time base considering new system clocks settings*/
01291   status = HAL_InitTick(uwTickPrio);
01292 
01293   return status;
01294 }
01295 
01296 /**
01297   * @}
01298   */
01299 
01300 /** @defgroup RCC_Exported_Functions_Group2 Peripheral Control functions
01301  *  @brief   RCC clocks control functions
01302  *
01303 @verbatim
01304  ===============================================================================
01305                       ##### Peripheral Control functions #####
01306  ===============================================================================
01307     [..]
01308     This subsection provides a set of functions allowing to:
01309 
01310     (+) Ouput clock to MCO pin.
01311     (+) Retrieve current clock frequencies.
01312     (+) Enable the Clock Security System.
01313 
01314 @endverbatim
01315   * @{
01316   */
01317 
01318 /**
01319   * @brief  Select the clock source to output on MCO pin(PA8).
01320   * @note   PA8 should be configured in alternate function mode.
01321   * @param  RCC_MCOx  specifies the output direction for the clock source.
01322   *          For STM32L4xx family this parameter can have only one value:
01323   *            @arg @ref RCC_MCO1  Clock source to output on MCO1 pin(PA8).
01324   * @param  RCC_MCOSource  specifies the clock source to output.
01325   *          This parameter can be one of the following values:
01326   *            @arg @ref RCC_MCO1SOURCE_NOCLOCK  MCO output disabled, no clock on MCO
01327   *            @arg @ref RCC_MCO1SOURCE_SYSCLK  system  clock selected as MCO source
01328   *            @arg @ref RCC_MCO1SOURCE_MSI  MSI clock selected as MCO source
01329   *            @arg @ref RCC_MCO1SOURCE_HSI  HSI clock selected as MCO source
01330   *            @arg @ref RCC_MCO1SOURCE_HSE  HSE clock selected as MCO sourcee
01331   *            @arg @ref RCC_MCO1SOURCE_PLLCLK  main PLL clock selected as MCO source
01332   *            @arg @ref RCC_MCO1SOURCE_LSI  LSI clock selected as MCO source
01333   *            @arg @ref RCC_MCO1SOURCE_LSE  LSE clock selected as MCO source
01334   @if STM32L443xx
01335   *            @arg @ref RCC_MCO1SOURCE_HSI48  HSI48 clock selected as MCO source for devices with HSI48
01336   @endif
01337   * @param  RCC_MCODiv  specifies the MCO prescaler.
01338   *          This parameter can be one of the following values:
01339   *            @arg @ref RCC_MCODIV_1  no division applied to MCO clock
01340   *            @arg @ref RCC_MCODIV_2  division by 2 applied to MCO clock
01341   *            @arg @ref RCC_MCODIV_4  division by 4 applied to MCO clock
01342   *            @arg @ref RCC_MCODIV_8  division by 8 applied to MCO clock
01343   *            @arg @ref RCC_MCODIV_16  division by 16 applied to MCO clock
01344   * @retval None
01345   */
01346 void HAL_RCC_MCOConfig( uint32_t RCC_MCOx, uint32_t RCC_MCOSource, uint32_t RCC_MCODiv)
01347 {
01348   GPIO_InitTypeDef GPIO_InitStruct;
01349 
01350   /* Check the parameters */
01351   assert_param(IS_RCC_MCO(RCC_MCOx));
01352   assert_param(IS_RCC_MCODIV(RCC_MCODiv));
01353   assert_param(IS_RCC_MCO1SOURCE(RCC_MCOSource));
01354 
01355   /* Prevent unused argument(s) compilation warning if no assert_param check */
01356   UNUSED(RCC_MCOx);
01357 
01358   /* MCO Clock Enable */
01359   __MCO1_CLK_ENABLE();
01360 
01361   /* Configue the MCO1 pin in alternate function mode */
01362   GPIO_InitStruct.Pin = MCO1_PIN;
01363   GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
01364   GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;
01365   GPIO_InitStruct.Pull = GPIO_NOPULL;
01366   GPIO_InitStruct.Alternate = GPIO_AF0_MCO;
01367   HAL_GPIO_Init(MCO1_GPIO_PORT, &GPIO_InitStruct);
01368 
01369   /* Mask MCOSEL[] and MCOPRE[] bits then set MCO1 clock source and prescaler */
01370   MODIFY_REG(RCC->CFGR, (RCC_CFGR_MCOSEL | RCC_CFGR_MCOPRE), (RCC_MCOSource | RCC_MCODiv ));
01371 }
01372 
01373 /**
01374   * @brief  Return the SYSCLK frequency.
01375   *
01376   * @note   The system frequency computed by this function is not the real
01377   *         frequency in the chip. It is calculated based on the predefined
01378   *         constant and the selected clock source:
01379   * @note     If SYSCLK source is MSI, function returns values based on MSI
01380   *             Value as defined by the MSI range.
01381   * @note     If SYSCLK source is HSI, function returns values based on HSI_VALUE(*)
01382   * @note     If SYSCLK source is HSE, function returns values based on HSE_VALUE(**)
01383   * @note     If SYSCLK source is PLL, function returns values based on HSE_VALUE(**),
01384   *           HSI_VALUE(*) or MSI Value multiplied/divided by the PLL factors.
01385   * @note     (*) HSI_VALUE is a constant defined in stm32l4xx_hal_conf.h file (default value
01386   *               16 MHz) but the real value may vary depending on the variations
01387   *               in voltage and temperature.
01388   * @note     (**) HSE_VALUE is a constant defined in stm32l4xx_hal_conf.h file (default value
01389   *                8 MHz), user has to ensure that HSE_VALUE is same as the real
01390   *                frequency of the crystal used. Otherwise, this function may
01391   *                have wrong result.
01392   *
01393   * @note   The result of this function could be not correct when using fractional
01394   *         value for HSE crystal.
01395   *
01396   * @note   This function can be used by the user application to compute the
01397   *         baudrate for the communication peripherals or configure other parameters.
01398   *
01399   * @note   Each time SYSCLK changes, this function must be called to update the
01400   *         right SYSCLK value. Otherwise, any configuration based on this function will be incorrect.
01401   *
01402   *
01403   * @retval SYSCLK frequency
01404   */
01405 uint32_t HAL_RCC_GetSysClockFreq(void)
01406 {
01407   uint32_t msirange = 0U, sysclockfreq = 0U;
01408   uint32_t pllvco, pllsource, pllr, pllm;    /* no init needed */
01409   uint32_t sysclk_source, pll_oscsource;
01410 
01411   sysclk_source = __HAL_RCC_GET_SYSCLK_SOURCE();
01412   pll_oscsource = __HAL_RCC_GET_PLL_OSCSOURCE();
01413 
01414   if((sysclk_source == RCC_CFGR_SWS_MSI) ||
01415      ((sysclk_source == RCC_CFGR_SWS_PLL) && (pll_oscsource == RCC_PLLSOURCE_MSI)))
01416   {
01417     /* MSI or PLL with MSI source used as system clock source */
01418 
01419     /* Get SYSCLK source */
01420     if(READ_BIT(RCC->CR, RCC_CR_MSIRGSEL) == 0U)
01421     { /* MSISRANGE from RCC_CSR applies */
01422       msirange = READ_BIT(RCC->CSR, RCC_CSR_MSISRANGE) >> RCC_CSR_MSISRANGE_Pos;
01423     }
01424     else
01425     { /* MSIRANGE from RCC_CR applies */
01426       msirange = READ_BIT(RCC->CR, RCC_CR_MSIRANGE) >> RCC_CR_MSIRANGE_Pos;
01427     }
01428     /*MSI frequency range in HZ*/
01429     msirange = MSIRangeTable[msirange];
01430 
01431     if(sysclk_source == RCC_CFGR_SWS_MSI)
01432     {
01433       /* MSI used as system clock source */
01434       sysclockfreq = msirange;
01435     }
01436   }
01437   else if(sysclk_source == RCC_CFGR_SWS_HSI)
01438   {
01439     /* HSI used as system clock source */
01440     sysclockfreq = HSI_VALUE;
01441   }
01442   else if(sysclk_source == RCC_CFGR_SWS_HSE)
01443   {
01444     /* HSE used as system clock source */
01445     sysclockfreq = HSE_VALUE;
01446   }
01447   else
01448   {
01449     /* unexpected case: sysclockfreq at 0 */
01450   }
01451 
01452   if(sysclk_source == RCC_CFGR_SWS_PLL)
01453   {
01454     /* PLL used as system clock  source */
01455 
01456     /* PLL_VCO = (HSE_VALUE or HSI_VALUE or MSI_VALUE) * PLLN / PLLM
01457     SYSCLK = PLL_VCO / PLLR
01458     */
01459     pllsource = READ_BIT(RCC->PLLCFGR, RCC_PLLCFGR_PLLSRC);
01460 
01461     switch (pllsource)
01462     {
01463     case RCC_PLLSOURCE_HSI:  /* HSI used as PLL clock source */
01464       pllvco = HSI_VALUE;
01465       break;
01466 
01467     case RCC_PLLSOURCE_HSE:  /* HSE used as PLL clock source */
01468       pllvco = HSE_VALUE;
01469       break;
01470 
01471     case RCC_PLLSOURCE_MSI:  /* MSI used as PLL clock source */
01472     default:
01473       pllvco = msirange;
01474       break;
01475     }
01476     pllm = (READ_BIT(RCC->PLLCFGR, RCC_PLLCFGR_PLLM) >> RCC_PLLCFGR_PLLM_Pos) + 1U ;
01477     pllvco = (pllvco * (READ_BIT(RCC->PLLCFGR, RCC_PLLCFGR_PLLN) >> RCC_PLLCFGR_PLLN_Pos)) / pllm;
01478     pllr = ((READ_BIT(RCC->PLLCFGR, RCC_PLLCFGR_PLLR) >> RCC_PLLCFGR_PLLR_Pos) + 1U ) * 2U;
01479     sysclockfreq = pllvco / pllr;
01480   }
01481 
01482   return sysclockfreq;
01483 }
01484 
01485 /**
01486   * @brief  Return the HCLK frequency.
01487   * @note   Each time HCLK changes, this function must be called to update the
01488   *         right HCLK value. Otherwise, any configuration based on this function will be incorrect.
01489   *
01490   * @note   The SystemCoreClock CMSIS variable is used to store System Clock Frequency.
01491   * @retval HCLK frequency in Hz
01492   */
01493 uint32_t HAL_RCC_GetHCLKFreq(void)
01494 {
01495   return SystemCoreClock;
01496 }
01497 
01498 /**
01499   * @brief  Return the PCLK1 frequency.
01500   * @note   Each time PCLK1 changes, this function must be called to update the
01501   *         right PCLK1 value. Otherwise, any configuration based on this function will be incorrect.
01502   * @retval PCLK1 frequency in Hz
01503   */
01504 uint32_t HAL_RCC_GetPCLK1Freq(void)
01505 {
01506   /* Get HCLK source and Compute PCLK1 frequency ---------------------------*/
01507   return (HAL_RCC_GetHCLKFreq() >> (APBPrescTable[READ_BIT(RCC->CFGR, RCC_CFGR_PPRE1) >> RCC_CFGR_PPRE1_Pos] & 0x1FU));
01508 }
01509 
01510 /**
01511   * @brief  Return the PCLK2 frequency.
01512   * @note   Each time PCLK2 changes, this function must be called to update the
01513   *         right PCLK2 value. Otherwise, any configuration based on this function will be incorrect.
01514   * @retval PCLK2 frequency in Hz
01515   */
01516 uint32_t HAL_RCC_GetPCLK2Freq(void)
01517 {
01518   /* Get HCLK source and Compute PCLK2 frequency ---------------------------*/
01519   return (HAL_RCC_GetHCLKFreq()>> (APBPrescTable[READ_BIT(RCC->CFGR, RCC_CFGR_PPRE2) >> RCC_CFGR_PPRE2_Pos] & 0x1FU));
01520 }
01521 
01522 /**
01523   * @brief  Configure the RCC_OscInitStruct according to the internal
01524   *         RCC configuration registers.
01525   * @param  RCC_OscInitStruct  pointer to an RCC_OscInitTypeDef structure that
01526   *         will be configured.
01527   * @retval None
01528   */
01529 void HAL_RCC_GetOscConfig(RCC_OscInitTypeDef  *RCC_OscInitStruct)
01530 {
01531   /* Check the parameters */
01532   assert_param(RCC_OscInitStruct != (void *)NULL);
01533 
01534   /* Set all possible values for the Oscillator type parameter ---------------*/
01535 #if defined(RCC_HSI48_SUPPORT)
01536   RCC_OscInitStruct->OscillatorType = RCC_OSCILLATORTYPE_HSE | RCC_OSCILLATORTYPE_HSI | RCC_OSCILLATORTYPE_MSI | \
01537                                       RCC_OSCILLATORTYPE_LSE | RCC_OSCILLATORTYPE_LSI | RCC_OSCILLATORTYPE_HSI48;
01538 #else
01539   RCC_OscInitStruct->OscillatorType = RCC_OSCILLATORTYPE_HSE | RCC_OSCILLATORTYPE_HSI | RCC_OSCILLATORTYPE_MSI | \
01540                                       RCC_OSCILLATORTYPE_LSE | RCC_OSCILLATORTYPE_LSI;
01541 #endif /* RCC_HSI48_SUPPORT */
01542 
01543   /* Get the HSE configuration -----------------------------------------------*/
01544   if(READ_BIT(RCC->CR, RCC_CR_HSEBYP) == RCC_CR_HSEBYP)
01545   {
01546     RCC_OscInitStruct->HSEState = RCC_HSE_BYPASS;
01547   }
01548   else if(READ_BIT(RCC->CR, RCC_CR_HSEON) == RCC_CR_HSEON)
01549   {
01550     RCC_OscInitStruct->HSEState = RCC_HSE_ON;
01551   }
01552   else
01553   {
01554     RCC_OscInitStruct->HSEState = RCC_HSE_OFF;
01555   }
01556 
01557    /* Get the MSI configuration -----------------------------------------------*/
01558   if(READ_BIT(RCC->CR, RCC_CR_MSION) == RCC_CR_MSION)
01559   {
01560     RCC_OscInitStruct->MSIState = RCC_MSI_ON;
01561   }
01562   else
01563   {
01564     RCC_OscInitStruct->MSIState = RCC_MSI_OFF;
01565   }
01566 
01567   RCC_OscInitStruct->MSICalibrationValue = READ_BIT(RCC->ICSCR, RCC_ICSCR_MSITRIM) >> RCC_ICSCR_MSITRIM_Pos;
01568   RCC_OscInitStruct->MSIClockRange = READ_BIT(RCC->CR, RCC_CR_MSIRANGE);
01569 
01570   /* Get the HSI configuration -----------------------------------------------*/
01571   if(READ_BIT(RCC->CR, RCC_CR_HSION) == RCC_CR_HSION)
01572   {
01573     RCC_OscInitStruct->HSIState = RCC_HSI_ON;
01574   }
01575   else
01576   {
01577     RCC_OscInitStruct->HSIState = RCC_HSI_OFF;
01578   }
01579 
01580   RCC_OscInitStruct->HSICalibrationValue = READ_BIT(RCC->ICSCR, RCC_ICSCR_HSITRIM) >> RCC_ICSCR_HSITRIM_Pos;
01581 
01582   /* Get the LSE configuration -----------------------------------------------*/
01583   if(READ_BIT(RCC->BDCR, RCC_BDCR_LSEBYP) == RCC_BDCR_LSEBYP)
01584   {
01585 #if defined(RCC_BDCR_LSESYSDIS)
01586     if((RCC->BDCR & RCC_BDCR_LSESYSDIS) == RCC_BDCR_LSESYSDIS)
01587     {
01588       RCC_OscInitStruct->LSEState = RCC_LSE_BYPASS_RTC_ONLY;
01589     }
01590     else
01591 #endif /* RCC_BDCR_LSESYSDIS */
01592     {
01593       RCC_OscInitStruct->LSEState = RCC_LSE_BYPASS;
01594     }
01595   }
01596   else if(READ_BIT(RCC->BDCR, RCC_BDCR_LSEON) == RCC_BDCR_LSEON)
01597   {
01598 #if defined(RCC_BDCR_LSESYSDIS)
01599     if((RCC->BDCR & RCC_BDCR_LSESYSDIS) == RCC_BDCR_LSESYSDIS)
01600     {
01601       RCC_OscInitStruct->LSEState = RCC_LSE_ON_RTC_ONLY;
01602     }
01603     else
01604 #endif /* RCC_BDCR_LSESYSDIS */
01605     {
01606       RCC_OscInitStruct->LSEState = RCC_LSE_ON;
01607     }
01608   }
01609   else
01610   {
01611     RCC_OscInitStruct->LSEState = RCC_LSE_OFF;
01612   }
01613 
01614   /* Get the LSI configuration -----------------------------------------------*/
01615   if(READ_BIT(RCC->CSR, RCC_CSR_LSION) == RCC_CSR_LSION)
01616   {
01617     RCC_OscInitStruct->LSIState = RCC_LSI_ON;
01618   }
01619   else
01620   {
01621     RCC_OscInitStruct->LSIState = RCC_LSI_OFF;
01622   }
01623 #if defined(RCC_CSR_LSIPREDIV)
01624 
01625   /* Get the LSI configuration -----------------------------------------------*/
01626   if((RCC->CSR & RCC_CSR_LSIPREDIV) == RCC_CSR_LSIPREDIV)
01627   {
01628     RCC_OscInitStruct->LSIDiv = RCC_LSI_DIV128;
01629   }
01630   else
01631   {
01632     RCC_OscInitStruct->LSIDiv = RCC_LSI_DIV1;
01633   }
01634 #endif /* RCC_CSR_LSIPREDIV */
01635 
01636 #if defined(RCC_HSI48_SUPPORT)
01637   /* Get the HSI48 configuration ---------------------------------------------*/
01638   if(READ_BIT(RCC->CRRCR, RCC_CRRCR_HSI48ON) == RCC_CRRCR_HSI48ON)
01639   {
01640     RCC_OscInitStruct->HSI48State = RCC_HSI48_ON;
01641   }
01642   else
01643   {
01644     RCC_OscInitStruct->HSI48State = RCC_HSI48_OFF;
01645   }
01646 #else
01647   RCC_OscInitStruct->HSI48State = RCC_HSI48_OFF;
01648 #endif /* RCC_HSI48_SUPPORT */
01649 
01650   /* Get the PLL configuration -----------------------------------------------*/
01651   if(READ_BIT(RCC->CR, RCC_CR_PLLON) == RCC_CR_PLLON)
01652   {
01653     RCC_OscInitStruct->PLL.PLLState = RCC_PLL_ON;
01654   }
01655   else
01656   {
01657     RCC_OscInitStruct->PLL.PLLState = RCC_PLL_OFF;
01658   }
01659   RCC_OscInitStruct->PLL.PLLSource = READ_BIT(RCC->PLLCFGR, RCC_PLLCFGR_PLLSRC);
01660   RCC_OscInitStruct->PLL.PLLM = (READ_BIT(RCC->PLLCFGR, RCC_PLLCFGR_PLLM) >> RCC_PLLCFGR_PLLM_Pos) + 1U;
01661   RCC_OscInitStruct->PLL.PLLN = READ_BIT(RCC->PLLCFGR, RCC_PLLCFGR_PLLN) >> RCC_PLLCFGR_PLLN_Pos;
01662   RCC_OscInitStruct->PLL.PLLQ = (((READ_BIT(RCC->PLLCFGR, RCC_PLLCFGR_PLLQ) >> RCC_PLLCFGR_PLLQ_Pos) + 1U) << 1U);
01663   RCC_OscInitStruct->PLL.PLLR = (((READ_BIT(RCC->PLLCFGR, RCC_PLLCFGR_PLLR) >> RCC_PLLCFGR_PLLR_Pos) + 1U) << 1U);
01664 #if defined(RCC_PLLP_SUPPORT)
01665 #if defined(RCC_PLLP_DIV_2_31_SUPPORT)
01666   RCC_OscInitStruct->PLL.PLLP = READ_BIT(RCC->PLLCFGR, RCC_PLLCFGR_PLLPDIV) >> RCC_PLLCFGR_PLLPDIV_Pos;
01667 #else
01668   if(READ_BIT(RCC->PLLCFGR, RCC_PLLCFGR_PLLP) != 0U)
01669   {
01670     RCC_OscInitStruct->PLL.PLLP = RCC_PLLP_DIV17;
01671   }
01672   else
01673   {
01674     RCC_OscInitStruct->PLL.PLLP = RCC_PLLP_DIV7;
01675   }
01676 #endif /* RCC_PLLP_DIV_2_31_SUPPORT */
01677 #endif /* RCC_PLLP_SUPPORT */
01678 }
01679 
01680 /**
01681   * @brief  Configure the RCC_ClkInitStruct according to the internal
01682   *         RCC configuration registers.
01683   * @param  RCC_ClkInitStruct  pointer to an RCC_ClkInitTypeDef structure that
01684   *         will be configured.
01685   * @param  pFLatency  Pointer on the Flash Latency.
01686   * @retval None
01687   */
01688 void HAL_RCC_GetClockConfig(RCC_ClkInitTypeDef  *RCC_ClkInitStruct, uint32_t *pFLatency)
01689 {
01690   /* Check the parameters */
01691   assert_param(RCC_ClkInitStruct != (void  *)NULL);
01692   assert_param(pFLatency != (void *)NULL);
01693 
01694   /* Set all possible values for the Clock type parameter --------------------*/
01695   RCC_ClkInitStruct->ClockType = RCC_CLOCKTYPE_SYSCLK | RCC_CLOCKTYPE_HCLK | RCC_CLOCKTYPE_PCLK1 | RCC_CLOCKTYPE_PCLK2;
01696 
01697   /* Get the SYSCLK configuration --------------------------------------------*/
01698   RCC_ClkInitStruct->SYSCLKSource = READ_BIT(RCC->CFGR, RCC_CFGR_SW);
01699 
01700   /* Get the HCLK configuration ----------------------------------------------*/
01701   RCC_ClkInitStruct->AHBCLKDivider = READ_BIT(RCC->CFGR, RCC_CFGR_HPRE);
01702 
01703   /* Get the APB1 configuration ----------------------------------------------*/
01704   RCC_ClkInitStruct->APB1CLKDivider = READ_BIT(RCC->CFGR, RCC_CFGR_PPRE1);
01705 
01706   /* Get the APB2 configuration ----------------------------------------------*/
01707   RCC_ClkInitStruct->APB2CLKDivider = (READ_BIT(RCC->CFGR, RCC_CFGR_PPRE2) >> 3U);
01708 
01709   /* Get the Flash Wait State (Latency) configuration ------------------------*/
01710   *pFLatency = __HAL_FLASH_GET_LATENCY();
01711 }
01712 
01713 /**
01714   * @brief  Enable the Clock Security System.
01715   * @note   If a failure is detected on the HSE oscillator clock, this oscillator
01716   *         is automatically disabled and an interrupt is generated to inform the
01717   *         software about the failure (Clock Security System Interrupt, CSSI),
01718   *         allowing the MCU to perform rescue operations. The CSSI is linked to
01719   *         the Cortex-M4 NMI (Non-Maskable Interrupt) exception vector.
01720   * @note   The Clock Security System can only be cleared by reset.
01721   * @retval None
01722   */
01723 void HAL_RCC_EnableCSS(void)
01724 {
01725   SET_BIT(RCC->CR, RCC_CR_CSSON) ;
01726 }
01727 
01728 /**
01729   * @brief Handle the RCC Clock Security System interrupt request.
01730   * @note This API should be called under the NMI_Handler().
01731   * @retval None
01732   */
01733 void HAL_RCC_NMI_IRQHandler(void)
01734 {
01735   /* Check RCC CSSF interrupt flag  */
01736   if(__HAL_RCC_GET_IT(RCC_IT_CSS))
01737   {
01738     /* RCC Clock Security System interrupt user callback */
01739     HAL_RCC_CSSCallback();
01740 
01741     /* Clear RCC CSS pending bit */
01742     __HAL_RCC_CLEAR_IT(RCC_IT_CSS);
01743   }
01744 }
01745 
01746 /**
01747   * @brief  RCC Clock Security System interrupt callback.
01748   * @retval none
01749   */
01750 __weak void HAL_RCC_CSSCallback(void)
01751 {
01752   /* NOTE : This function should not be modified, when the callback is needed,
01753             the HAL_RCC_CSSCallback should be implemented in the user file
01754    */
01755 }
01756 
01757 /**
01758   * @brief  Get and clear reset flags
01759   * @param  None
01760   * @note   Once reset flags are retrieved, this API is clearing them in order
01761   *         to isolate next reset reason.
01762   * @retval can be a combination of @ref RCC_Reset_Flag
01763   */
01764 uint32_t HAL_RCC_GetResetSource(void)
01765 {
01766   uint32_t reset;
01767 
01768   /* Get all reset flags */
01769   reset = RCC->CSR & RCC_RESET_FLAG_ALL;
01770 
01771   /* Clear Reset flags */
01772   RCC->CSR |= RCC_CSR_RMVF;
01773 
01774   return reset;
01775 }
01776 
01777 /**  * @}
01778   */
01779 
01780 /**
01781   * @}
01782   */
01783 
01784 /* Private function prototypes -----------------------------------------------*/
01785 /** @addtogroup RCC_Private_Functions
01786   * @{
01787   */
01788 /**
01789   * @brief  Update number of Flash wait states in line with MSI range and current
01790             voltage range.
01791   * @param  msirange  MSI range value from RCC_MSIRANGE_0 to RCC_MSIRANGE_11
01792   * @retval HAL status
01793   */
01794 static HAL_StatusTypeDef RCC_SetFlashLatencyFromMSIRange(uint32_t msirange)
01795 {
01796   uint32_t vos;
01797   uint32_t latency = FLASH_LATENCY_0;  /* default value 0WS */
01798 
01799   if(__HAL_RCC_PWR_IS_CLK_ENABLED())
01800   {
01801     vos = HAL_PWREx_GetVoltageRange();
01802   }
01803   else
01804   {
01805     __HAL_RCC_PWR_CLK_ENABLE();
01806     vos = HAL_PWREx_GetVoltageRange();
01807     __HAL_RCC_PWR_CLK_DISABLE();
01808   }
01809 
01810   if(vos == PWR_REGULATOR_VOLTAGE_SCALE1)
01811   {
01812     if(msirange > RCC_MSIRANGE_8)
01813     {
01814       /* MSI > 16Mhz */
01815       if(msirange > RCC_MSIRANGE_10)
01816       {
01817         /* MSI 48Mhz */
01818         latency = FLASH_LATENCY_2; /* 2WS */
01819       }
01820       else
01821       {
01822         /* MSI 24Mhz or 32Mhz */
01823         latency = FLASH_LATENCY_1; /* 1WS */
01824       }
01825     }
01826     /* else MSI <= 16Mhz default FLASH_LATENCY_0 0WS */
01827   }
01828   else
01829   {
01830 #if defined(STM32L4P5xx) || defined(STM32L4Q5xx) || \
01831     defined(STM32L4R5xx) || defined(STM32L4R7xx) || defined(STM32L4R9xx) || defined(STM32L4S5xx) || defined(STM32L4S7xx) || defined(STM32L4S9xx)
01832     if(msirange >= RCC_MSIRANGE_8)
01833     {
01834       /* MSI >= 16Mhz */
01835       latency = FLASH_LATENCY_2; /* 2WS */
01836     }
01837     else
01838     {
01839       if(msirange == RCC_MSIRANGE_7)
01840       {
01841         /* MSI 8Mhz */
01842         latency = FLASH_LATENCY_1; /* 1WS */
01843       }
01844       /* else MSI < 8Mhz default FLASH_LATENCY_0 0WS */
01845     }
01846 #else
01847     if(msirange > RCC_MSIRANGE_8)
01848     {
01849       /* MSI > 16Mhz */
01850       latency = FLASH_LATENCY_3; /* 3WS */
01851     }
01852     else
01853     {
01854       if(msirange == RCC_MSIRANGE_8)
01855       {
01856         /* MSI 16Mhz */
01857         latency = FLASH_LATENCY_2; /* 2WS */
01858       }
01859       else if(msirange == RCC_MSIRANGE_7)
01860       {
01861         /* MSI 8Mhz */
01862         latency = FLASH_LATENCY_1; /* 1WS */
01863       }
01864       /* else MSI < 8Mhz default FLASH_LATENCY_0 0WS */
01865     }
01866 #endif
01867   }
01868 
01869   __HAL_FLASH_SET_LATENCY(latency);
01870 
01871   /* Check that the new number of wait states is taken into account to access the Flash
01872      memory by reading the FLASH_ACR register */
01873   if(__HAL_FLASH_GET_LATENCY() != latency)
01874   {
01875     return HAL_ERROR;
01876   }
01877 
01878   return HAL_OK;
01879 }
01880 
01881 #if defined(STM32L4P5xx) || defined(STM32L4Q5xx) || \
01882     defined(STM32L4R5xx) || defined(STM32L4R7xx) || defined(STM32L4R9xx) || defined(STM32L4S5xx) || defined(STM32L4S7xx) || defined(STM32L4S9xx)
01883 /**
01884   * @brief  Compute SYSCLK frequency based on PLL SYSCLK source.
01885   * @retval SYSCLK frequency
01886   */
01887 static uint32_t RCC_GetSysClockFreqFromPLLSource(void)
01888 {
01889   uint32_t msirange = 0U;
01890   uint32_t pllvco, pllsource, pllr, pllm, sysclockfreq;  /* no init needed */
01891 
01892   if(__HAL_RCC_GET_PLL_OSCSOURCE() == RCC_PLLSOURCE_MSI)
01893   {
01894     /* Get MSI range source */
01895     if(READ_BIT(RCC->CR, RCC_CR_MSIRGSEL) == 0U)
01896     { /* MSISRANGE from RCC_CSR applies */
01897       msirange = READ_BIT(RCC->CSR, RCC_CSR_MSISRANGE) >> RCC_CSR_MSISRANGE_Pos;
01898     }
01899     else
01900     { /* MSIRANGE from RCC_CR applies */
01901       msirange = READ_BIT(RCC->CR, RCC_CR_MSIRANGE) >> RCC_CR_MSIRANGE_Pos;
01902     }
01903     /*MSI frequency range in HZ*/
01904     msirange = MSIRangeTable[msirange];
01905   }
01906 
01907   /* PLL_VCO = (HSE_VALUE or HSI_VALUE or MSI_VALUE) * PLLN / PLLM
01908      SYSCLK = PLL_VCO / PLLR
01909    */
01910   pllsource = READ_BIT(RCC->PLLCFGR, RCC_PLLCFGR_PLLSRC);
01911 
01912   switch (pllsource)
01913   {
01914   case RCC_PLLSOURCE_HSI:  /* HSI used as PLL clock source */
01915     pllvco = HSI_VALUE;
01916     break;
01917 
01918   case RCC_PLLSOURCE_HSE:  /* HSE used as PLL clock source */
01919     pllvco = HSE_VALUE;
01920     break;
01921 
01922   case RCC_PLLSOURCE_MSI:  /* MSI used as PLL clock source */
01923   default:
01924     pllvco = msirange;
01925     break;
01926   }
01927   pllm = (READ_BIT(RCC->PLLCFGR, RCC_PLLCFGR_PLLM) >> RCC_PLLCFGR_PLLM_Pos) + 1U ;
01928   pllvco = (pllvco * (READ_BIT(RCC->PLLCFGR, RCC_PLLCFGR_PLLN) >> RCC_PLLCFGR_PLLN_Pos)) / pllm;
01929   pllr = ((READ_BIT(RCC->PLLCFGR, RCC_PLLCFGR_PLLR) >> RCC_PLLCFGR_PLLR_Pos) + 1U ) * 2U;
01930   sysclockfreq = pllvco / pllr;
01931 
01932   return sysclockfreq;
01933 }
01934 #endif
01935 
01936 /**
01937   * @}
01938   */
01939 
01940 #endif /* HAL_RCC_MODULE_ENABLED */
01941 /**
01942   * @}
01943   */
01944 
01945 /**
01946   * @}
01947   */
01948