tdse-tp0_03-hw_sw_test

FIUBA - Electrónica - Taller de Sistemas Embebidos - Trabajo Práctico N°: 0 - Proyecto N°: 03
Index Commits Files Refs README
Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal_rcc.c (50375B)
   1 /**
   2  ******************************************************************************
   3  * @file    stm32f1xx_hal_rcc.c
   4  * @author  MCD Application Team
   5  * @brief   RCC HAL module driver.
   6  *          This file provides firmware functions to manage the following
   7  *          functionalities of the Reset and Clock Control (RCC) peripheral:
   8  *           + Initialization and de-initialization functions
   9  *           + Peripheral Control functions
  10  *
  11  @verbatim
  12  ==============================================================================
  13  ##### RCC specific features #####
  14  ==============================================================================
  15  [..]
  16  After reset the device is running from Internal High Speed oscillator
  17  (HSI 8MHz) with Flash 0 wait state, Flash prefetch buffer is enabled,
  18  and all peripherals are off except internal SRAM, Flash and JTAG.
  19  (+) There is no prescaler on High speed (AHB) and Low speed (APB) buses;
  20  all peripherals mapped on these buses are running at HSI speed.
  21  (+) The clock for all peripherals is switched off, except the SRAM and FLASH.
  22  (+) All GPIOs are in input floating state, except the JTAG pins which
  23  are assigned to be used for debug purpose.
  24  [..] Once the device started from reset, the user application has to:
  25  (+) Configure the clock source to be used to drive the System clock
  26  (if the application needs higher frequency/performance)
  27  (+) Configure the System clock frequency and Flash settings
  28  (+) Configure the AHB and APB buses prescalers
  29  (+) Enable the clock for the peripheral(s) to be used
  30  (+) Configure the clock source(s) for peripherals whose clocks are not
  31  derived from the System clock (I2S, RTC, ADC, USB OTG FS)
  32 
  33  ##### RCC Limitations #####
  34  ==============================================================================
  35  [..]
  36  A delay between an RCC peripheral clock enable and the effective peripheral
  37  enabling should be taken into account in order to manage the peripheral read/write
  38  from/to registers.
  39  (+) This delay depends on the peripheral mapping.
  40  (++) AHB & APB peripherals, 1 dummy read is necessary
  41 
  42  [..]
  43  Workarounds:
  44  (#) For AHB & APB peripherals, a dummy read to the peripheral register has been
  45  inserted in each __HAL_RCC_PPP_CLK_ENABLE() macro.
  46 
  47  @endverbatim
  48  ******************************************************************************
  49  * @attention
  50  *
  51  * Copyright (c) 2016 STMicroelectronics.
  52  * All rights reserved.
  53  *
  54  * This software is licensed under terms that can be found in the LICENSE file in
  55  * the root directory of this software component.
  56  * If no LICENSE file comes with this software, it is provided AS-IS.
  57  ******************************************************************************
  58  */
  59 
  60 /* Includes ------------------------------------------------------------------*/
  61 #include "stm32f1xx_hal.h"
  62 
  63 /** @addtogroup STM32F1xx_HAL_Driver
  64  * @{
  65  */
  66 
  67 /** @defgroup RCC RCC
  68  * @brief RCC HAL module driver
  69  * @{
  70  */
  71 
  72 #ifdef HAL_RCC_MODULE_ENABLED
  73 
  74 /* Private typedef -----------------------------------------------------------*/
  75 /* Private define ------------------------------------------------------------*/
  76 /** @defgroup RCC_Private_Constants RCC Private Constants
  77  * @{
  78  */
  79 /**
  80  * @}
  81  */
  82 /* Private macro -------------------------------------------------------------*/
  83 /** @defgroup RCC_Private_Macros RCC Private Macros
  84  * @{
  85  */
  86 
  87 #define MCO1_CLK_ENABLE()     __HAL_RCC_GPIOA_CLK_ENABLE()
  88 #define MCO1_GPIO_PORT        GPIOA
  89 #define MCO1_PIN              GPIO_PIN_8
  90 
  91 /**
  92  * @}
  93  */
  94 
  95 /* Private variables ---------------------------------------------------------*/
  96 /** @defgroup RCC_Private_Variables RCC Private Variables
  97  * @{
  98  */
  99 /**
 100  * @}
 101  */
 102 
 103 /* Private function prototypes -----------------------------------------------*/
 104 static void RCC_Delay(uint32_t mdelay);
 105 
 106 /* Exported functions --------------------------------------------------------*/
 107 
 108 /** @defgroup RCC_Exported_Functions RCC Exported Functions
 109  * @{
 110  */
 111 
 112 /** @defgroup RCC_Exported_Functions_Group1 Initialization and de-initialization functions
 113  *  @brief    Initialization and Configuration functions
 114  *
 115  @verbatim
 116  ===============================================================================
 117  ##### Initialization and de-initialization functions #####
 118  ===============================================================================
 119  [..]
 120  This section provides functions allowing to configure the internal/external oscillators
 121  (HSE, HSI, LSE, LSI, PLL, CSS and MCO) and the System buses clocks (SYSCLK, AHB, APB1
 122  and APB2).
 123 
 124  [..] Internal/external clock and PLL configuration
 125  (#) HSI (high-speed internal), 8 MHz factory-trimmed RC used directly or through
 126  the PLL as System clock source.
 127  (#) LSI (low-speed internal), ~40 KHz low consumption RC used as IWDG and/or RTC
 128  clock source.
 129 
 130  (#) HSE (high-speed external), 4 to 24 MHz (STM32F100xx) or 4 to 16 MHz (STM32F101x/STM32F102x/STM32F103x) or 3 to 25 MHz (STM32F105x/STM32F107x)  crystal oscillator used directly or
 131  through the PLL as System clock source. Can be used also as RTC clock source.
 132 
 133  (#) LSE (low-speed external), 32 KHz oscillator used as RTC clock source.
 134 
 135  (#) PLL (clocked by HSI or HSE), featuring different output clocks:
 136  (++) The first output is used to generate the high speed system clock (up to 72 MHz for STM32F10xxx or up to 24 MHz for STM32F100xx)
 137  (++) The second output is used to generate the clock for the USB OTG FS (48 MHz)
 138 
 139  (#) CSS (Clock security system), once enable using the macro __HAL_RCC_CSS_ENABLE()
 140  and if a HSE clock failure occurs(HSE used directly or through PLL as System
 141  clock source), the System clocks automatically switched to HSI and an interrupt
 142  is generated if enabled. The interrupt is linked to the Cortex-M3 NMI
 143  (Non-Maskable Interrupt) exception vector.
 144 
 145  (#) MCO1 (microcontroller clock output), used to output SYSCLK, HSI,
 146  HSE or PLL clock (divided by 2) on PA8 pin + PLL2CLK, PLL3CLK/2, PLL3CLK and XTI for STM32F105x/STM32F107x
 147 
 148  [..] System, AHB and APB buses clocks configuration
 149  (#) Several clock sources can be used to drive the System clock (SYSCLK): HSI,
 150  HSE and PLL.
 151  The AHB clock (HCLK) is derived from System clock through configurable
 152  prescaler and used to clock the CPU, memory and peripherals mapped
 153  on AHB bus (DMA, GPIO...). APB1 (PCLK1) and APB2 (PCLK2) clocks are derived
 154  from AHB clock through configurable prescalers and used to clock
 155  the peripherals mapped on these buses. You can use
 156  "HAL_RCC_GetSysClockFreq()" function to retrieve the frequencies of these clocks.
 157 
 158  -@- All the peripheral clocks are derived from the System clock (SYSCLK) except:
 159  (+@) RTC: RTC clock can be derived either from the LSI, LSE or HSE clock
 160  divided by 128.
 161  (+@) USB OTG FS and RTC: USB OTG FS require a frequency equal to 48 MHz
 162  to work correctly. This clock is derived of the main PLL through PLL Multiplier.
 163  (+@) I2S interface on STM32F105x/STM32F107x can be derived from PLL3CLK
 164  (+@) IWDG clock which is always the LSI clock.
 165 
 166  (#) For STM32F10xxx, the maximum frequency of the SYSCLK and HCLK/PCLK2 is 72 MHz, PCLK1 36 MHz.
 167  For STM32F100xx, the maximum frequency of the SYSCLK and HCLK/PCLK1/PCLK2 is 24 MHz.
 168  Depending on the SYSCLK frequency, the flash latency should be adapted accordingly.
 169  @endverbatim
 170  * @{
 171  */
 172 
 173 /*
 174  Additional consideration on the SYSCLK based on Latency settings:
 175  +-----------------------------------------------+
 176  | Latency       | SYSCLK clock frequency (MHz)  |
 177  |---------------|-------------------------------|
 178  |0WS(1CPU cycle)|       0 < SYSCLK <= 24        |
 179  |---------------|-------------------------------|
 180  |1WS(2CPU cycle)|      24 < SYSCLK <= 48        |
 181  |---------------|-------------------------------|
 182  |2WS(3CPU cycle)|      48 < SYSCLK <= 72        |
 183  +-----------------------------------------------+
 184  */
 185 
 186 /**
 187  * @brief  Resets the RCC clock configuration to the default reset state.
 188  * @note   The default reset state of the clock configuration is given below:
 189  *            - HSI ON and used as system clock source
 190  *            - HSE, PLL, PLL2 and PLL3 are OFF
 191  *            - AHB, APB1 and APB2 prescaler set to 1.
 192  *            - CSS and MCO1 OFF
 193  *            - All interrupts disabled
 194  *            - All flags are cleared
 195  * @note   This function does not modify the configuration of the
 196  *            - Peripheral clocks
 197  *            - LSI, LSE and RTC clocks
 198  * @retval HAL_StatusTypeDef
 199  */
 200 HAL_StatusTypeDef HAL_RCC_DeInit(void)
 201 {
 202     uint32_t tickstart;
 203 
 204     /* Get Start Tick */
 205     tickstart = HAL_GetTick();
 206 
 207     /* Set HSION bit */
 208     SET_BIT(RCC->CR, RCC_CR_HSION);
 209 
 210     /* Wait till HSI is ready */
 211     while (READ_BIT(RCC->CR, RCC_CR_HSIRDY) == RESET) {
 212         if ((HAL_GetTick() - tickstart) > HSI_TIMEOUT_VALUE) {
 213             return HAL_TIMEOUT;
 214         }
 215     }
 216 
 217     /* Set HSITRIM bits to the reset value */
 218     MODIFY_REG(RCC->CR, RCC_CR_HSITRIM, (0x10U << RCC_CR_HSITRIM_Pos));
 219 
 220     /* Get Start Tick */
 221     tickstart = HAL_GetTick();
 222 
 223     /* Reset CFGR register */
 224     CLEAR_REG(RCC->CFGR);
 225 
 226     /* Wait till clock switch is ready */
 227     while (READ_BIT(RCC->CFGR, RCC_CFGR_SWS) != RESET) {
 228         if ((HAL_GetTick() - tickstart) > CLOCKSWITCH_TIMEOUT_VALUE) {
 229             return HAL_TIMEOUT;
 230         }
 231     }
 232 
 233     /* Update the SystemCoreClock global variable */
 234     SystemCoreClock = HSI_VALUE;
 235 
 236     /* Adapt Systick interrupt period */
 237     if (HAL_InitTick(uwTickPrio) != HAL_OK) {
 238         return HAL_ERROR;
 239     }
 240 
 241     /* Get Start Tick */
 242     tickstart = HAL_GetTick();
 243 
 244     /* Second step is to clear PLLON bit */
 245     CLEAR_BIT(RCC->CR, RCC_CR_PLLON);
 246 
 247     /* Wait till PLL is disabled */
 248     while (READ_BIT(RCC->CR, RCC_CR_PLLRDY) != RESET) {
 249         if ((HAL_GetTick() - tickstart) > PLL_TIMEOUT_VALUE) {
 250             return HAL_TIMEOUT;
 251         }
 252     }
 253 
 254     /* Ensure to reset PLLSRC and PLLMUL bits */
 255     CLEAR_REG(RCC->CFGR);
 256 
 257     /* Get Start Tick */
 258     tickstart = HAL_GetTick();
 259 
 260     /* Reset HSEON & CSSON bits */
 261     CLEAR_BIT(RCC->CR, RCC_CR_HSEON | RCC_CR_CSSON);
 262 
 263     /* Wait till HSE is disabled */
 264     while (READ_BIT(RCC->CR, RCC_CR_HSERDY) != RESET) {
 265         if ((HAL_GetTick() - tickstart) > HSE_TIMEOUT_VALUE) {
 266             return HAL_TIMEOUT;
 267         }
 268     }
 269 
 270     /* Reset HSEBYP bit */
 271     CLEAR_BIT(RCC->CR, RCC_CR_HSEBYP);
 272 
 273 #if defined(RCC_PLL2_SUPPORT)
 274   /* Get Start Tick */
 275   tickstart = HAL_GetTick();
 276 
 277   /* Clear PLL2ON bit */
 278   CLEAR_BIT(RCC->CR, RCC_CR_PLL2ON);
 279 
 280   /* Wait till PLL2 is disabled */
 281   while (READ_BIT(RCC->CR, RCC_CR_PLL2RDY) != RESET)
 282   {
 283     if ((HAL_GetTick() - tickstart) > PLL2_TIMEOUT_VALUE)
 284     {
 285       return HAL_TIMEOUT;
 286     }
 287   }
 288 #endif /* RCC_PLL2_SUPPORT */
 289 
 290 #if defined(RCC_PLLI2S_SUPPORT)
 291   /* Get Start Tick */
 292   tickstart = HAL_GetTick();
 293 
 294   /* Clear PLL3ON bit */
 295   CLEAR_BIT(RCC->CR, RCC_CR_PLL3ON);
 296 
 297   /* Wait till PLL3 is disabled */
 298   while (READ_BIT(RCC->CR, RCC_CR_PLL3RDY) != RESET)
 299   {
 300     if ((HAL_GetTick() - tickstart) > PLLI2S_TIMEOUT_VALUE)
 301     {
 302       return HAL_TIMEOUT;
 303     }
 304   }
 305 #endif /* RCC_PLLI2S_SUPPORT */
 306 
 307 #if defined(RCC_CFGR2_PREDIV1)
 308   /* Reset CFGR2 register */
 309   CLEAR_REG(RCC->CFGR2);
 310 #endif /* RCC_CFGR2_PREDIV1 */
 311 
 312     /* Reset all CSR flags */
 313     SET_BIT(RCC->CSR, RCC_CSR_RMVF);
 314 
 315     /* Disable all interrupts */
 316     CLEAR_REG(RCC->CIR);
 317 
 318     return HAL_OK;
 319 }
 320 
 321 /**
 322  * @brief  Initializes the RCC Oscillators according to the specified parameters in the
 323  *         RCC_OscInitTypeDef.
 324  * @param  RCC_OscInitStruct pointer to an RCC_OscInitTypeDef structure that
 325  *         contains the configuration information for the RCC Oscillators.
 326  * @note   The PLL is not disabled when used as system clock.
 327  * @note   The PLL is not disabled when USB OTG FS clock is enabled (specific to devices with USB FS)
 328  * @note   Transitions LSE Bypass to LSE On and LSE On to LSE Bypass are not
 329  *         supported by this macro. User should request a transition to LSE Off
 330  *         first and then LSE On or LSE Bypass.
 331  * @note   Transition HSE Bypass to HSE On and HSE On to HSE Bypass are not
 332  *         supported by this macro. User should request a transition to HSE Off
 333  *         first and then HSE On or HSE Bypass.
 334  * @retval HAL status
 335  */
 336 HAL_StatusTypeDef HAL_RCC_OscConfig(RCC_OscInitTypeDef *RCC_OscInitStruct)
 337 {
 338     uint32_t tickstart;
 339     uint32_t pll_config;
 340 
 341     /* Check Null pointer */
 342     if (RCC_OscInitStruct == NULL) {
 343         return HAL_ERROR;
 344     }
 345 
 346     /* Check the parameters */
 347     assert_param(IS_RCC_OSCILLATORTYPE(RCC_OscInitStruct->OscillatorType));
 348 
 349     /*------------------------------- HSE Configuration ------------------------*/
 350     if (((RCC_OscInitStruct->OscillatorType) & RCC_OSCILLATORTYPE_HSE)
 351             == RCC_OSCILLATORTYPE_HSE) {
 352         /* Check the parameters */
 353         assert_param(IS_RCC_HSE(RCC_OscInitStruct->HSEState));
 354 
 355         /* When the HSE is used as system clock or clock source for PLL in these cases it is not allowed to be disabled */
 356         if ((__HAL_RCC_GET_SYSCLK_SOURCE() == RCC_SYSCLKSOURCE_STATUS_HSE)
 357                 || ((__HAL_RCC_GET_SYSCLK_SOURCE()
 358                         == RCC_SYSCLKSOURCE_STATUS_PLLCLK)
 359                         && (__HAL_RCC_GET_PLL_OSCSOURCE() == RCC_PLLSOURCE_HSE))) {
 360             if ((__HAL_RCC_GET_FLAG(RCC_FLAG_HSERDY) != RESET)
 361                     && (RCC_OscInitStruct->HSEState == RCC_HSE_OFF)) {
 362                 return HAL_ERROR;
 363             }
 364         } else {
 365             /* Set the new HSE configuration ---------------------------------------*/
 366             __HAL_RCC_HSE_CONFIG(RCC_OscInitStruct->HSEState);
 367 
 368             /* Check the HSE State */
 369             if (RCC_OscInitStruct->HSEState != RCC_HSE_OFF) {
 370                 /* Get Start Tick */
 371                 tickstart = HAL_GetTick();
 372 
 373                 /* Wait till HSE is ready */
 374                 while (__HAL_RCC_GET_FLAG(RCC_FLAG_HSERDY) == RESET) {
 375                     if ((HAL_GetTick() - tickstart) > HSE_TIMEOUT_VALUE) {
 376                         return HAL_TIMEOUT;
 377                     }
 378                 }
 379             } else {
 380                 /* Get Start Tick */
 381                 tickstart = HAL_GetTick();
 382 
 383                 /* Wait till HSE is disabled */
 384                 while (__HAL_RCC_GET_FLAG(RCC_FLAG_HSERDY) != RESET) {
 385                     if ((HAL_GetTick() - tickstart) > HSE_TIMEOUT_VALUE) {
 386                         return HAL_TIMEOUT;
 387                     }
 388                 }
 389             }
 390         }
 391     }
 392     /*----------------------------- HSI Configuration --------------------------*/
 393     if (((RCC_OscInitStruct->OscillatorType) & RCC_OSCILLATORTYPE_HSI)
 394             == RCC_OSCILLATORTYPE_HSI) {
 395         /* Check the parameters */
 396         assert_param(IS_RCC_HSI(RCC_OscInitStruct->HSIState));
 397         assert_param(
 398                 IS_RCC_CALIBRATION_VALUE(RCC_OscInitStruct->HSICalibrationValue));
 399 
 400         /* Check if HSI is used as system clock or as PLL source when PLL is selected as system clock */
 401         if ((__HAL_RCC_GET_SYSCLK_SOURCE() == RCC_SYSCLKSOURCE_STATUS_HSI)
 402                 || ((__HAL_RCC_GET_SYSCLK_SOURCE()
 403                         == RCC_SYSCLKSOURCE_STATUS_PLLCLK)
 404                         && (__HAL_RCC_GET_PLL_OSCSOURCE()
 405                                 == RCC_PLLSOURCE_HSI_DIV2))) {
 406             /* When HSI is used as system clock it will not disabled */
 407             if ((__HAL_RCC_GET_FLAG(RCC_FLAG_HSIRDY) != RESET)
 408                     && (RCC_OscInitStruct->HSIState != RCC_HSI_ON)) {
 409                 return HAL_ERROR;
 410             }
 411             /* Otherwise, just the calibration is allowed */
 412             else {
 413                 /* Adjusts the Internal High Speed oscillator (HSI) calibration value.*/
 414                 __HAL_RCC_HSI_CALIBRATIONVALUE_ADJUST(
 415                         RCC_OscInitStruct->HSICalibrationValue);
 416             }
 417         } else {
 418             /* Check the HSI State */
 419             if (RCC_OscInitStruct->HSIState != RCC_HSI_OFF) {
 420                 /* Enable the Internal High Speed oscillator (HSI). */
 421                 __HAL_RCC_HSI_ENABLE();
 422 
 423                 /* Get Start Tick */
 424                 tickstart = HAL_GetTick();
 425 
 426                 /* Wait till HSI is ready */
 427                 while (__HAL_RCC_GET_FLAG(RCC_FLAG_HSIRDY) == RESET) {
 428                     if ((HAL_GetTick() - tickstart) > HSI_TIMEOUT_VALUE) {
 429                         return HAL_TIMEOUT;
 430                     }
 431                 }
 432 
 433                 /* Adjusts the Internal High Speed oscillator (HSI) calibration value.*/
 434                 __HAL_RCC_HSI_CALIBRATIONVALUE_ADJUST(
 435                         RCC_OscInitStruct->HSICalibrationValue);
 436             } else {
 437                 /* Disable the Internal High Speed oscillator (HSI). */
 438                 __HAL_RCC_HSI_DISABLE();
 439 
 440                 /* Get Start Tick */
 441                 tickstart = HAL_GetTick();
 442 
 443                 /* Wait till HSI is disabled */
 444                 while (__HAL_RCC_GET_FLAG(RCC_FLAG_HSIRDY) != RESET) {
 445                     if ((HAL_GetTick() - tickstart) > HSI_TIMEOUT_VALUE) {
 446                         return HAL_TIMEOUT;
 447                     }
 448                 }
 449             }
 450         }
 451     }
 452     /*------------------------------ LSI Configuration -------------------------*/
 453     if (((RCC_OscInitStruct->OscillatorType) & RCC_OSCILLATORTYPE_LSI)
 454             == RCC_OSCILLATORTYPE_LSI) {
 455         /* Check the parameters */
 456         assert_param(IS_RCC_LSI(RCC_OscInitStruct->LSIState));
 457 
 458         /* Check the LSI State */
 459         if (RCC_OscInitStruct->LSIState != RCC_LSI_OFF) {
 460             /* Enable the Internal Low Speed oscillator (LSI). */
 461             __HAL_RCC_LSI_ENABLE();
 462 
 463             /* Get Start Tick */
 464             tickstart = HAL_GetTick();
 465 
 466             /* Wait till LSI is ready */
 467             while (__HAL_RCC_GET_FLAG(RCC_FLAG_LSIRDY) == RESET) {
 468                 if ((HAL_GetTick() - tickstart) > LSI_TIMEOUT_VALUE) {
 469                     return HAL_TIMEOUT;
 470                 }
 471             }
 472             /*  To have a fully stabilized clock in the specified range, a software delay of 1ms
 473              should be added.*/
 474             RCC_Delay(1);
 475         } else {
 476             /* Disable the Internal Low Speed oscillator (LSI). */
 477             __HAL_RCC_LSI_DISABLE();
 478 
 479             /* Get Start Tick */
 480             tickstart = HAL_GetTick();
 481 
 482             /* Wait till LSI is disabled */
 483             while (__HAL_RCC_GET_FLAG(RCC_FLAG_LSIRDY) != RESET) {
 484                 if ((HAL_GetTick() - tickstart) > LSI_TIMEOUT_VALUE) {
 485                     return HAL_TIMEOUT;
 486                 }
 487             }
 488         }
 489     }
 490     /*------------------------------ LSE Configuration -------------------------*/
 491     if (((RCC_OscInitStruct->OscillatorType) & RCC_OSCILLATORTYPE_LSE)
 492             == RCC_OSCILLATORTYPE_LSE) {
 493         FlagStatus pwrclkchanged = RESET;
 494 
 495         /* Check the parameters */
 496         assert_param(IS_RCC_LSE(RCC_OscInitStruct->LSEState));
 497 
 498         /* Update LSE configuration in Backup Domain control register    */
 499         /* Requires to enable write access to Backup Domain of necessary */
 500         if (__HAL_RCC_PWR_IS_CLK_DISABLED()) {
 501             __HAL_RCC_PWR_CLK_ENABLE();
 502             pwrclkchanged = SET;
 503         }
 504 
 505         if (HAL_IS_BIT_CLR(PWR->CR, PWR_CR_DBP)) {
 506             /* Enable write access to Backup domain */
 507             SET_BIT(PWR->CR, PWR_CR_DBP);
 508 
 509             /* Wait for Backup domain Write protection disable */
 510             tickstart = HAL_GetTick();
 511 
 512             while (HAL_IS_BIT_CLR(PWR->CR, PWR_CR_DBP)) {
 513                 if ((HAL_GetTick() - tickstart) > RCC_DBP_TIMEOUT_VALUE) {
 514                     return HAL_TIMEOUT;
 515                 }
 516             }
 517         }
 518 
 519         /* Set the new LSE configuration -----------------------------------------*/
 520         __HAL_RCC_LSE_CONFIG(RCC_OscInitStruct->LSEState);
 521         /* Check the LSE State */
 522         if (RCC_OscInitStruct->LSEState != RCC_LSE_OFF) {
 523             /* Get Start Tick */
 524             tickstart = HAL_GetTick();
 525 
 526             /* Wait till LSE is ready */
 527             while (__HAL_RCC_GET_FLAG(RCC_FLAG_LSERDY) == RESET) {
 528                 if ((HAL_GetTick() - tickstart) > RCC_LSE_TIMEOUT_VALUE) {
 529                     return HAL_TIMEOUT;
 530                 }
 531             }
 532         } else {
 533             /* Get Start Tick */
 534             tickstart = HAL_GetTick();
 535 
 536             /* Wait till LSE is disabled */
 537             while (__HAL_RCC_GET_FLAG(RCC_FLAG_LSERDY) != RESET) {
 538                 if ((HAL_GetTick() - tickstart) > RCC_LSE_TIMEOUT_VALUE) {
 539                     return HAL_TIMEOUT;
 540                 }
 541             }
 542         }
 543 
 544         /* Require to disable power clock if necessary */
 545         if (pwrclkchanged == SET) {
 546             __HAL_RCC_PWR_CLK_DISABLE();
 547         }
 548     }
 549 
 550 #if defined(RCC_CR_PLL2ON)
 551   /*-------------------------------- PLL2 Configuration -----------------------*/
 552   /* Check the parameters */
 553   assert_param(IS_RCC_PLL2(RCC_OscInitStruct->PLL2.PLL2State));
 554   if ((RCC_OscInitStruct->PLL2.PLL2State) != RCC_PLL2_NONE)
 555   {
 556     /* This bit can not be cleared if the PLL2 clock is used indirectly as system
 557       clock (i.e. it is used as PLL clock entry that is used as system clock). */
 558     if ((__HAL_RCC_GET_PLL_OSCSOURCE() == RCC_PLLSOURCE_HSE) && \
 559         (__HAL_RCC_GET_SYSCLK_SOURCE() == RCC_SYSCLKSOURCE_STATUS_PLLCLK) && \
 560         ((READ_BIT(RCC->CFGR2, RCC_CFGR2_PREDIV1SRC)) == RCC_CFGR2_PREDIV1SRC_PLL2))
 561     {
 562       return HAL_ERROR;
 563     }
 564     else
 565     {
 566       if ((RCC_OscInitStruct->PLL2.PLL2State) == RCC_PLL2_ON)
 567       {
 568         /* Check the parameters */
 569         assert_param(IS_RCC_PLL2_MUL(RCC_OscInitStruct->PLL2.PLL2MUL));
 570         assert_param(IS_RCC_HSE_PREDIV2(RCC_OscInitStruct->PLL2.HSEPrediv2Value));
 571 
 572         /* Prediv2 can be written only when the PLLI2S is disabled. */
 573         /* Return an error only if new value is different from the programmed value */
 574         if (HAL_IS_BIT_SET(RCC->CR, RCC_CR_PLL3ON) && \
 575             (__HAL_RCC_HSE_GET_PREDIV2() != RCC_OscInitStruct->PLL2.HSEPrediv2Value))
 576         {
 577           return HAL_ERROR;
 578         }
 579 
 580         /* Disable the main PLL2. */
 581         __HAL_RCC_PLL2_DISABLE();
 582 
 583         /* Get Start Tick */
 584         tickstart = HAL_GetTick();
 585 
 586         /* Wait till PLL2 is disabled */
 587         while (__HAL_RCC_GET_FLAG(RCC_FLAG_PLL2RDY) != RESET)
 588         {
 589           if ((HAL_GetTick() - tickstart) > PLL2_TIMEOUT_VALUE)
 590           {
 591             return HAL_TIMEOUT;
 592           }
 593         }
 594 
 595         /* Configure the HSE prediv2 factor --------------------------------*/
 596         __HAL_RCC_HSE_PREDIV2_CONFIG(RCC_OscInitStruct->PLL2.HSEPrediv2Value);
 597 
 598         /* Configure the main PLL2 multiplication factors. */
 599         __HAL_RCC_PLL2_CONFIG(RCC_OscInitStruct->PLL2.PLL2MUL);
 600 
 601         /* Enable the main PLL2. */
 602         __HAL_RCC_PLL2_ENABLE();
 603 
 604         /* Get Start Tick */
 605         tickstart = HAL_GetTick();
 606 
 607         /* Wait till PLL2 is ready */
 608         while (__HAL_RCC_GET_FLAG(RCC_FLAG_PLL2RDY)  == RESET)
 609         {
 610           if ((HAL_GetTick() - tickstart) > PLL2_TIMEOUT_VALUE)
 611           {
 612             return HAL_TIMEOUT;
 613           }
 614         }
 615       }
 616       else
 617       {
 618         /* Set PREDIV1 source to HSE */
 619         CLEAR_BIT(RCC->CFGR2, RCC_CFGR2_PREDIV1SRC);
 620 
 621         /* Disable the main PLL2. */
 622         __HAL_RCC_PLL2_DISABLE();
 623 
 624         /* Get Start Tick */
 625         tickstart = HAL_GetTick();
 626 
 627         /* Wait till PLL2 is disabled */
 628         while (__HAL_RCC_GET_FLAG(RCC_FLAG_PLL2RDY)  != RESET)
 629         {
 630           if ((HAL_GetTick() - tickstart) > PLL2_TIMEOUT_VALUE)
 631           {
 632             return HAL_TIMEOUT;
 633           }
 634         }
 635       }
 636     }
 637   }
 638 
 639 #endif /* RCC_CR_PLL2ON */
 640     /*-------------------------------- PLL Configuration -----------------------*/
 641     /* Check the parameters */
 642     assert_param(IS_RCC_PLL(RCC_OscInitStruct->PLL.PLLState));
 643     if ((RCC_OscInitStruct->PLL.PLLState) != RCC_PLL_NONE) {
 644         /* Check if the PLL is used as system clock or not */
 645         if (__HAL_RCC_GET_SYSCLK_SOURCE() != RCC_SYSCLKSOURCE_STATUS_PLLCLK) {
 646             if ((RCC_OscInitStruct->PLL.PLLState) == RCC_PLL_ON) {
 647                 /* Check the parameters */
 648                 assert_param(
 649                         IS_RCC_PLLSOURCE(RCC_OscInitStruct->PLL.PLLSource));
 650                 assert_param(IS_RCC_PLL_MUL(RCC_OscInitStruct->PLL.PLLMUL));
 651 
 652                 /* Disable the main PLL. */
 653                 __HAL_RCC_PLL_DISABLE();
 654 
 655                 /* Get Start Tick */
 656                 tickstart = HAL_GetTick();
 657 
 658                 /* Wait till PLL is disabled */
 659                 while (__HAL_RCC_GET_FLAG(RCC_FLAG_PLLRDY) != RESET) {
 660                     if ((HAL_GetTick() - tickstart) > PLL_TIMEOUT_VALUE) {
 661                         return HAL_TIMEOUT;
 662                     }
 663                 }
 664 
 665                 /* Configure the HSE prediv factor --------------------------------*/
 666                 /* It can be written only when the PLL is disabled. Not used in PLL source is different than HSE */
 667                 if (RCC_OscInitStruct->PLL.PLLSource == RCC_PLLSOURCE_HSE) {
 668                     /* Check the parameter */
 669                     assert_param(
 670                             IS_RCC_HSE_PREDIV(RCC_OscInitStruct->HSEPredivValue));
 671 #if defined(RCC_CFGR2_PREDIV1SRC)
 672           assert_param(IS_RCC_PREDIV1_SOURCE(RCC_OscInitStruct->Prediv1Source));
 673 
 674           /* Set PREDIV1 source */
 675           SET_BIT(RCC->CFGR2, RCC_OscInitStruct->Prediv1Source);
 676 #endif /* RCC_CFGR2_PREDIV1SRC */
 677 
 678                     /* Set PREDIV1 Value */
 679                     __HAL_RCC_HSE_PREDIV_CONFIG(
 680                             RCC_OscInitStruct->HSEPredivValue);
 681                 }
 682 
 683                 /* Configure the main PLL clock source and multiplication factors. */
 684                 __HAL_RCC_PLL_CONFIG(RCC_OscInitStruct->PLL.PLLSource,
 685                         RCC_OscInitStruct->PLL.PLLMUL);
 686                 /* Enable the main PLL. */
 687                 __HAL_RCC_PLL_ENABLE();
 688 
 689                 /* Get Start Tick */
 690                 tickstart = HAL_GetTick();
 691 
 692                 /* Wait till PLL is ready */
 693                 while (__HAL_RCC_GET_FLAG(RCC_FLAG_PLLRDY) == RESET) {
 694                     if ((HAL_GetTick() - tickstart) > PLL_TIMEOUT_VALUE) {
 695                         return HAL_TIMEOUT;
 696                     }
 697                 }
 698             } else {
 699                 /* Disable the main PLL. */
 700                 __HAL_RCC_PLL_DISABLE();
 701 
 702                 /* Get Start Tick */
 703                 tickstart = HAL_GetTick();
 704 
 705                 /* Wait till PLL is disabled */
 706                 while (__HAL_RCC_GET_FLAG(RCC_FLAG_PLLRDY) != RESET) {
 707                     if ((HAL_GetTick() - tickstart) > PLL_TIMEOUT_VALUE) {
 708                         return HAL_TIMEOUT;
 709                     }
 710                 }
 711             }
 712         } else {
 713             /* Check if there is a request to disable the PLL used as System clock source */
 714             if ((RCC_OscInitStruct->PLL.PLLState) == RCC_PLL_OFF) {
 715                 return HAL_ERROR;
 716             } else {
 717                 /* Do not return HAL_ERROR if request repeats the current configuration */
 718                 pll_config = RCC->CFGR;
 719                 if ((READ_BIT(pll_config, RCC_CFGR_PLLSRC)
 720                         != RCC_OscInitStruct->PLL.PLLSource)
 721                         || (READ_BIT(pll_config, RCC_CFGR_PLLMULL)
 722                                 != RCC_OscInitStruct->PLL.PLLMUL)) {
 723                     return HAL_ERROR;
 724                 }
 725             }
 726         }
 727     }
 728 
 729     return HAL_OK;
 730 }
 731 
 732 /**
 733  * @brief  Initializes the CPU, AHB and APB buses clocks according to the specified
 734  *         parameters in the RCC_ClkInitStruct.
 735  * @param  RCC_ClkInitStruct pointer to an RCC_OscInitTypeDef structure that
 736  *         contains the configuration information for the RCC peripheral.
 737  * @param  FLatency FLASH Latency
 738  *          The value of this parameter depend on device used within the same series
 739  * @note   The SystemCoreClock CMSIS variable is used to store System Clock Frequency
 740  *         and updated by @ref HAL_RCC_GetHCLKFreq() function called within this function
 741  *
 742  * @note   The HSI is used (enabled by hardware) as system clock source after
 743  *         start-up from Reset, wake-up from STOP and STANDBY mode, or in case
 744  *         of failure of the HSE used directly or indirectly as system clock
 745  *         (if the Clock Security System CSS is enabled).
 746  *
 747  * @note   A switch from one clock source to another occurs only if the target
 748  *         clock source is ready (clock stable after start-up delay or PLL locked).
 749  *         If a clock source which is not yet ready is selected, the switch will
 750  *         occur when the clock source will be ready.
 751  *         You can use @ref HAL_RCC_GetClockConfig() function to know which clock is
 752  *         currently used as system clock source.
 753  * @retval HAL status
 754  */
 755 HAL_StatusTypeDef HAL_RCC_ClockConfig(RCC_ClkInitTypeDef *RCC_ClkInitStruct,
 756         uint32_t FLatency)
 757 {
 758     uint32_t tickstart;
 759 
 760     /* Check Null pointer */
 761     if (RCC_ClkInitStruct == NULL) {
 762         return HAL_ERROR;
 763     }
 764 
 765     /* Check the parameters */
 766     assert_param(IS_RCC_CLOCKTYPE(RCC_ClkInitStruct->ClockType));
 767     assert_param(IS_FLASH_LATENCY(FLatency));
 768 
 769     /* To correctly read data from FLASH memory, the number of wait states (LATENCY)
 770      must be correctly programmed according to the frequency of the CPU clock
 771      (HCLK) of the device. */
 772 
 773 #if defined(FLASH_ACR_LATENCY)
 774     /* Increasing the number of wait states because of higher CPU frequency */
 775     if (FLatency > __HAL_FLASH_GET_LATENCY()) {
 776         /* Program the new number of wait states to the LATENCY bits in the FLASH_ACR register */
 777         __HAL_FLASH_SET_LATENCY(FLatency);
 778 
 779         /* Check that the new number of wait states is taken into account to access the Flash
 780          memory by reading the FLASH_ACR register */
 781         if (__HAL_FLASH_GET_LATENCY() != FLatency) {
 782             return HAL_ERROR;
 783         }
 784     }
 785 
 786 #endif /* FLASH_ACR_LATENCY */
 787     /*-------------------------- HCLK Configuration --------------------------*/
 788     if (((RCC_ClkInitStruct->ClockType) & RCC_CLOCKTYPE_HCLK)
 789             == RCC_CLOCKTYPE_HCLK) {
 790         /* Set the highest APBx dividers in order to ensure that we do not go through
 791          a non-spec phase whatever we decrease or increase HCLK. */
 792         if (((RCC_ClkInitStruct->ClockType) & RCC_CLOCKTYPE_PCLK1)
 793                 == RCC_CLOCKTYPE_PCLK1) {
 794             MODIFY_REG(RCC->CFGR, RCC_CFGR_PPRE1, RCC_HCLK_DIV16);
 795         }
 796 
 797         if (((RCC_ClkInitStruct->ClockType) & RCC_CLOCKTYPE_PCLK2)
 798                 == RCC_CLOCKTYPE_PCLK2) {
 799             MODIFY_REG(RCC->CFGR, RCC_CFGR_PPRE2, (RCC_HCLK_DIV16 << 3));
 800         }
 801 
 802         /* Set the new HCLK clock divider */
 803         assert_param(IS_RCC_HCLK(RCC_ClkInitStruct->AHBCLKDivider));
 804         MODIFY_REG(RCC->CFGR, RCC_CFGR_HPRE, RCC_ClkInitStruct->AHBCLKDivider);
 805     }
 806 
 807     /*------------------------- SYSCLK Configuration ---------------------------*/
 808     if (((RCC_ClkInitStruct->ClockType) & RCC_CLOCKTYPE_SYSCLK)
 809             == RCC_CLOCKTYPE_SYSCLK) {
 810         assert_param(IS_RCC_SYSCLKSOURCE(RCC_ClkInitStruct->SYSCLKSource));
 811 
 812         /* HSE is selected as System Clock Source */
 813         if (RCC_ClkInitStruct->SYSCLKSource == RCC_SYSCLKSOURCE_HSE) {
 814             /* Check the HSE ready flag */
 815             if (__HAL_RCC_GET_FLAG(RCC_FLAG_HSERDY) == RESET) {
 816                 return HAL_ERROR;
 817             }
 818         }
 819         /* PLL is selected as System Clock Source */
 820         else if (RCC_ClkInitStruct->SYSCLKSource == RCC_SYSCLKSOURCE_PLLCLK) {
 821             /* Check the PLL ready flag */
 822             if (__HAL_RCC_GET_FLAG(RCC_FLAG_PLLRDY) == RESET) {
 823                 return HAL_ERROR;
 824             }
 825         }
 826         /* HSI is selected as System Clock Source */
 827         else {
 828             /* Check the HSI ready flag */
 829             if (__HAL_RCC_GET_FLAG(RCC_FLAG_HSIRDY) == RESET) {
 830                 return HAL_ERROR;
 831             }
 832         }
 833         __HAL_RCC_SYSCLK_CONFIG(RCC_ClkInitStruct->SYSCLKSource);
 834 
 835         /* Get Start Tick */
 836         tickstart = HAL_GetTick();
 837 
 838         while (__HAL_RCC_GET_SYSCLK_SOURCE()
 839                 != (RCC_ClkInitStruct->SYSCLKSource << RCC_CFGR_SWS_Pos)) {
 840             if ((HAL_GetTick() - tickstart) > CLOCKSWITCH_TIMEOUT_VALUE) {
 841                 return HAL_TIMEOUT;
 842             }
 843         }
 844     }
 845 
 846 #if defined(FLASH_ACR_LATENCY)
 847     /* Decreasing the number of wait states because of lower CPU frequency */
 848     if (FLatency < __HAL_FLASH_GET_LATENCY()) {
 849         /* Program the new number of wait states to the LATENCY bits in the FLASH_ACR register */
 850         __HAL_FLASH_SET_LATENCY(FLatency);
 851 
 852         /* Check that the new number of wait states is taken into account to access the Flash
 853          memory by reading the FLASH_ACR register */
 854         if (__HAL_FLASH_GET_LATENCY() != FLatency) {
 855             return HAL_ERROR;
 856         }
 857     }
 858 #endif /* FLASH_ACR_LATENCY */
 859 
 860     /*-------------------------- PCLK1 Configuration ---------------------------*/
 861     if (((RCC_ClkInitStruct->ClockType) & RCC_CLOCKTYPE_PCLK1)
 862             == RCC_CLOCKTYPE_PCLK1) {
 863         assert_param(IS_RCC_PCLK(RCC_ClkInitStruct->APB1CLKDivider));
 864         MODIFY_REG(RCC->CFGR, RCC_CFGR_PPRE1,
 865                 RCC_ClkInitStruct->APB1CLKDivider);
 866     }
 867 
 868     /*-------------------------- PCLK2 Configuration ---------------------------*/
 869     if (((RCC_ClkInitStruct->ClockType) & RCC_CLOCKTYPE_PCLK2)
 870             == RCC_CLOCKTYPE_PCLK2) {
 871         assert_param(IS_RCC_PCLK(RCC_ClkInitStruct->APB2CLKDivider));
 872         MODIFY_REG(RCC->CFGR, RCC_CFGR_PPRE2,
 873                 ((RCC_ClkInitStruct->APB2CLKDivider) << 3));
 874     }
 875 
 876     /* Update the SystemCoreClock global variable */
 877     SystemCoreClock = HAL_RCC_GetSysClockFreq()
 878             >> AHBPrescTable[(RCC->CFGR & RCC_CFGR_HPRE) >> RCC_CFGR_HPRE_Pos];
 879 
 880     /* Configure the source of time base considering new system clocks settings*/
 881     HAL_InitTick(uwTickPrio);
 882 
 883     return HAL_OK;
 884 }
 885 
 886 /**
 887  * @}
 888  */
 889 
 890 /** @defgroup RCC_Exported_Functions_Group2 Peripheral Control functions
 891  *  @brief   RCC clocks control functions
 892  *
 893  @verbatim
 894  ===============================================================================
 895  ##### Peripheral Control functions #####
 896  ===============================================================================
 897  [..]
 898  This subsection provides a set of functions allowing to control the RCC Clocks
 899  frequencies.
 900 
 901  @endverbatim
 902  * @{
 903  */
 904 
 905 /**
 906  * @brief  Selects the clock source to output on MCO pin.
 907  * @note   MCO pin should be configured in alternate function mode.
 908  * @param  RCC_MCOx specifies the output direction for the clock source.
 909  *          This parameter can be one of the following values:
 910  *            @arg @ref RCC_MCO1 Clock source to output on MCO1 pin(PA8).
 911  * @param  RCC_MCOSource specifies the clock source to output.
 912  *          This parameter can be one of the following values:
 913  *            @arg @ref RCC_MCO1SOURCE_NOCLOCK     No clock selected as MCO clock
 914  *            @arg @ref RCC_MCO1SOURCE_SYSCLK      System clock selected as MCO clock
 915  *            @arg @ref RCC_MCO1SOURCE_HSI         HSI selected as MCO clock
 916  *            @arg @ref RCC_MCO1SOURCE_HSE         HSE selected as MCO clock
 917  @if STM32F105xC
 918  *            @arg @ref RCC_MCO1SOURCE_PLLCLK       PLL clock divided by 2 selected as MCO source
 919  *            @arg @ref RCC_MCO1SOURCE_PLL2CLK      PLL2 clock selected as MCO source
 920  *            @arg @ref RCC_MCO1SOURCE_PLL3CLK_DIV2 PLL3 clock divided by 2 selected as MCO source
 921  *            @arg @ref RCC_MCO1SOURCE_EXT_HSE      XT1 external 3-25 MHz oscillator clock selected as MCO source
 922  *            @arg @ref RCC_MCO1SOURCE_PLL3CLK      PLL3 clock selected as MCO source
 923  @endif
 924  @if STM32F107xC
 925  *            @arg @ref RCC_MCO1SOURCE_PLLCLK       PLL clock divided by 2 selected as MCO source
 926  *            @arg @ref RCC_MCO1SOURCE_PLL2CLK      PLL2 clock selected as MCO source
 927  *            @arg @ref RCC_MCO1SOURCE_PLL3CLK_DIV2 PLL3 clock divided by 2 selected as MCO source
 928  *            @arg @ref RCC_MCO1SOURCE_EXT_HSE XT1  external 3-25 MHz oscillator clock selected as MCO source
 929  *            @arg @ref RCC_MCO1SOURCE_PLL3CLK      PLL3 clock selected as MCO source
 930  @endif
 931  * @param  RCC_MCODiv specifies the MCO DIV.
 932  *          This parameter can be one of the following values:
 933  *            @arg @ref RCC_MCODIV_1 no division applied to MCO clock
 934  * @retval None
 935  */
 936 void HAL_RCC_MCOConfig(uint32_t RCC_MCOx, uint32_t RCC_MCOSource,
 937         uint32_t RCC_MCODiv)
 938 {
 939     GPIO_InitTypeDef gpio = { 0U };
 940 
 941     /* Check the parameters */
 942     assert_param(IS_RCC_MCO(RCC_MCOx));
 943     assert_param(IS_RCC_MCODIV(RCC_MCODiv));
 944     assert_param(IS_RCC_MCO1SOURCE(RCC_MCOSource));
 945 
 946     /* Prevent unused argument(s) compilation warning */
 947     UNUSED(RCC_MCOx);
 948     UNUSED(RCC_MCODiv);
 949 
 950     /* Configure the MCO1 pin in alternate function mode */
 951     gpio.Mode = GPIO_MODE_AF_PP;
 952     gpio.Speed = GPIO_SPEED_FREQ_HIGH;
 953     gpio.Pull = GPIO_NOPULL;
 954     gpio.Pin = MCO1_PIN;
 955 
 956     /* MCO1 Clock Enable */
 957     MCO1_CLK_ENABLE();
 958 
 959     HAL_GPIO_Init(MCO1_GPIO_PORT, &gpio);
 960 
 961     /* Configure the MCO clock source */
 962     __HAL_RCC_MCO1_CONFIG(RCC_MCOSource, RCC_MCODiv);
 963 }
 964 
 965 /**
 966  * @brief  Enables the Clock Security System.
 967  * @note   If a failure is detected on the HSE oscillator clock, this oscillator
 968  *         is automatically disabled and an interrupt is generated to inform the
 969  *         software about the failure (Clock Security System Interrupt, CSSI),
 970  *         allowing the MCU to perform rescue operations. The CSSI is linked to
 971  *         the Cortex-M3 NMI (Non-Maskable Interrupt) exception vector.
 972  * @retval None
 973  */
 974 void HAL_RCC_EnableCSS(void)
 975 {
 976     *(__IO uint32_t*) RCC_CR_CSSON_BB = (uint32_t) ENABLE;
 977 }
 978 
 979 /**
 980  * @brief  Disables the Clock Security System.
 981  * @retval None
 982  */
 983 void HAL_RCC_DisableCSS(void)
 984 {
 985     *(__IO uint32_t*) RCC_CR_CSSON_BB = (uint32_t) DISABLE;
 986 }
 987 
 988 /**
 989  * @brief  Returns the SYSCLK frequency
 990  * @note   The system frequency computed by this function is not the real
 991  *         frequency in the chip. It is calculated based on the predefined
 992  *         constant and the selected clock source:
 993  * @note     If SYSCLK source is HSI, function returns values based on HSI_VALUE(*)
 994  * @note     If SYSCLK source is HSE, function returns a value based on HSE_VALUE
 995  *           divided by PREDIV factor(**)
 996  * @note     If SYSCLK source is PLL, function returns a value based on HSE_VALUE
 997  *           divided by PREDIV factor(**) or HSI_VALUE(*) multiplied by the PLL factor.
 998  * @note     (*) HSI_VALUE is a constant defined in stm32f1xx_hal_conf.h file (default value
 999  *               8 MHz) but the real value may vary depending on the variations
1000  *               in voltage and temperature.
1001  * @note     (**) HSE_VALUE is a constant defined in stm32f1xx_hal_conf.h file (default value
1002  *                8 MHz), user has to ensure that HSE_VALUE is same as the real
1003  *                frequency of the crystal used. Otherwise, this function may
1004  *                have wrong result.
1005  *
1006  * @note   The result of this function could be not correct when using fractional
1007  *         value for HSE crystal.
1008  *
1009  * @note   This function can be used by the user application to compute the
1010  *         baud-rate for the communication peripherals or configure other parameters.
1011  *
1012  * @note   Each time SYSCLK changes, this function must be called to update the
1013  *         right SYSCLK value. Otherwise, any configuration based on this function will be incorrect.
1014  *
1015  * @retval SYSCLK frequency
1016  */
1017 uint32_t HAL_RCC_GetSysClockFreq(void)
1018 {
1019 #if defined(RCC_CFGR2_PREDIV1SRC)
1020   static const uint8_t aPLLMULFactorTable[14U] = {0, 0, 4, 5, 6, 7, 8, 9, 0, 0, 0, 0, 0, 13};
1021   static const uint8_t aPredivFactorTable[16U] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16};
1022 #else
1023     static const uint8_t aPLLMULFactorTable[16U] = { 2, 3, 4, 5, 6, 7, 8, 9, 10,
1024             11, 12, 13, 14, 15, 16, 16 };
1025 #if defined(RCC_CFGR2_PREDIV1)
1026   static const uint8_t aPredivFactorTable[16U] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16};
1027 #else
1028     static const uint8_t aPredivFactorTable[2U] = { 1, 2 };
1029 #endif /*RCC_CFGR2_PREDIV1*/
1030 
1031 #endif
1032     uint32_t tmpreg = 0U, prediv = 0U, pllclk = 0U, pllmul = 0U;
1033     uint32_t sysclockfreq = 0U;
1034 #if defined(RCC_CFGR2_PREDIV1SRC)
1035   uint32_t prediv2 = 0U, pll2mul = 0U;
1036 #endif /*RCC_CFGR2_PREDIV1SRC*/
1037 
1038     tmpreg = RCC->CFGR;
1039 
1040     /* Get SYSCLK source -------------------------------------------------------*/
1041     switch (tmpreg & RCC_CFGR_SWS) {
1042     case RCC_SYSCLKSOURCE_STATUS_HSE: /* HSE used as system clock */
1043     {
1044         sysclockfreq = HSE_VALUE;
1045         break;
1046     }
1047     case RCC_SYSCLKSOURCE_STATUS_PLLCLK: /* PLL used as system clock */
1048     {
1049         pllmul = aPLLMULFactorTable[(uint32_t) (tmpreg & RCC_CFGR_PLLMULL)
1050                 >> RCC_CFGR_PLLMULL_Pos];
1051         if ((tmpreg & RCC_CFGR_PLLSRC) != RCC_PLLSOURCE_HSI_DIV2) {
1052 #if defined(RCC_CFGR2_PREDIV1)
1053         prediv = aPredivFactorTable[(uint32_t)(RCC->CFGR2 & RCC_CFGR2_PREDIV1) >> RCC_CFGR2_PREDIV1_Pos];
1054 #else
1055             prediv = aPredivFactorTable[(uint32_t) (RCC->CFGR
1056                     & RCC_CFGR_PLLXTPRE) >> RCC_CFGR_PLLXTPRE_Pos];
1057 #endif /*RCC_CFGR2_PREDIV1*/
1058 #if defined(RCC_CFGR2_PREDIV1SRC)
1059 
1060         if (HAL_IS_BIT_SET(RCC->CFGR2, RCC_CFGR2_PREDIV1SRC))
1061         {
1062           /* PLL2 selected as Prediv1 source */
1063           /* PLLCLK = PLL2CLK / PREDIV1 * PLLMUL with PLL2CLK = HSE/PREDIV2 * PLL2MUL */
1064           prediv2 = ((RCC->CFGR2 & RCC_CFGR2_PREDIV2) >> RCC_CFGR2_PREDIV2_Pos) + 1;
1065           pll2mul = ((RCC->CFGR2 & RCC_CFGR2_PLL2MUL) >> RCC_CFGR2_PLL2MUL_Pos) + 2;
1066           pllclk = (uint32_t)(((uint64_t)HSE_VALUE * (uint64_t)pll2mul * (uint64_t)pllmul) / ((uint64_t)prediv2 * (uint64_t)prediv));
1067         }
1068         else
1069         {
1070           /* HSE used as PLL clock source : PLLCLK = HSE/PREDIV1 * PLLMUL */
1071           pllclk = (uint32_t)((HSE_VALUE * pllmul) / prediv);
1072         }
1073 
1074         /* If PLLMUL was set to 13 means that it was to cover the case PLLMUL 6.5 (avoid using float) */
1075         /* In this case need to divide pllclk by 2 */
1076         if (pllmul == aPLLMULFactorTable[(uint32_t)(RCC_CFGR_PLLMULL6_5) >> RCC_CFGR_PLLMULL_Pos])
1077         {
1078           pllclk = pllclk / 2;
1079         }
1080 #else
1081             /* HSE used as PLL clock source : PLLCLK = HSE/PREDIV1 * PLLMUL */
1082             pllclk = (uint32_t) ((HSE_VALUE * pllmul) / prediv);
1083 #endif /*RCC_CFGR2_PREDIV1SRC*/
1084         } else {
1085             /* HSI used as PLL clock source : PLLCLK = HSI/2 * PLLMUL */
1086             pllclk = (uint32_t) ((HSI_VALUE >> 1) * pllmul);
1087         }
1088         sysclockfreq = pllclk;
1089         break;
1090     }
1091     case RCC_SYSCLKSOURCE_STATUS_HSI: /* HSI used as system clock source */
1092     default: /* HSI used as system clock */
1093     {
1094         sysclockfreq = HSI_VALUE;
1095         break;
1096     }
1097     }
1098     return sysclockfreq;
1099 }
1100 
1101 /**
1102  * @brief  Returns the HCLK frequency
1103  * @note   Each time HCLK changes, this function must be called to update the
1104  *         right HCLK value. Otherwise, any configuration based on this function will be incorrect.
1105  *
1106  * @note   The SystemCoreClock CMSIS variable is used to store System Clock Frequency
1107  *         and updated within this function
1108  * @retval HCLK frequency
1109  */
1110 uint32_t HAL_RCC_GetHCLKFreq(void)
1111 {
1112     return SystemCoreClock;
1113 }
1114 
1115 /**
1116  * @brief  Returns the PCLK1 frequency
1117  * @note   Each time PCLK1 changes, this function must be called to update the
1118  *         right PCLK1 value. Otherwise, any configuration based on this function will be incorrect.
1119  * @retval PCLK1 frequency
1120  */
1121 uint32_t HAL_RCC_GetPCLK1Freq(void)
1122 {
1123     /* Get HCLK source and Compute PCLK1 frequency ---------------------------*/
1124     return (HAL_RCC_GetHCLKFreq()
1125             >> APBPrescTable[(RCC->CFGR & RCC_CFGR_PPRE1) >> RCC_CFGR_PPRE1_Pos]);
1126 }
1127 
1128 /**
1129  * @brief  Returns the PCLK2 frequency
1130  * @note   Each time PCLK2 changes, this function must be called to update the
1131  *         right PCLK2 value. Otherwise, any configuration based on this function will be incorrect.
1132  * @retval PCLK2 frequency
1133  */
1134 uint32_t HAL_RCC_GetPCLK2Freq(void)
1135 {
1136     /* Get HCLK source and Compute PCLK2 frequency ---------------------------*/
1137     return (HAL_RCC_GetHCLKFreq()
1138             >> APBPrescTable[(RCC->CFGR & RCC_CFGR_PPRE2) >> RCC_CFGR_PPRE2_Pos]);
1139 }
1140 
1141 /**
1142  * @brief  Configures the RCC_OscInitStruct according to the internal
1143  * RCC configuration registers.
1144  * @param  RCC_OscInitStruct pointer to an RCC_OscInitTypeDef structure that
1145  * will be configured.
1146  * @retval None
1147  */
1148 void HAL_RCC_GetOscConfig(RCC_OscInitTypeDef *RCC_OscInitStruct)
1149 {
1150     /* Check the parameters */
1151     assert_param(RCC_OscInitStruct != NULL);
1152 
1153     /* Set all possible values for the Oscillator type parameter ---------------*/
1154     RCC_OscInitStruct->OscillatorType = RCC_OSCILLATORTYPE_HSE
1155             | RCC_OSCILLATORTYPE_HSI | RCC_OSCILLATORTYPE_LSE
1156             | RCC_OSCILLATORTYPE_LSI;
1157 
1158 #if defined(RCC_CFGR2_PREDIV1SRC)
1159   /* Get the Prediv1 source --------------------------------------------------*/
1160   RCC_OscInitStruct->Prediv1Source = READ_BIT(RCC->CFGR2, RCC_CFGR2_PREDIV1SRC);
1161 #endif /* RCC_CFGR2_PREDIV1SRC */
1162 
1163     /* Get the HSE configuration -----------------------------------------------*/
1164     if ((RCC->CR & RCC_CR_HSEBYP) == RCC_CR_HSEBYP) {
1165         RCC_OscInitStruct->HSEState = RCC_HSE_BYPASS;
1166     } else if ((RCC->CR & RCC_CR_HSEON) == RCC_CR_HSEON) {
1167         RCC_OscInitStruct->HSEState = RCC_HSE_ON;
1168     } else {
1169         RCC_OscInitStruct->HSEState = RCC_HSE_OFF;
1170     }
1171     RCC_OscInitStruct->HSEPredivValue = __HAL_RCC_HSE_GET_PREDIV();
1172 
1173     /* Get the HSI configuration -----------------------------------------------*/
1174     if ((RCC->CR & RCC_CR_HSION) == RCC_CR_HSION) {
1175         RCC_OscInitStruct->HSIState = RCC_HSI_ON;
1176     } else {
1177         RCC_OscInitStruct->HSIState = RCC_HSI_OFF;
1178     }
1179 
1180     RCC_OscInitStruct->HSICalibrationValue = (uint32_t) ((RCC->CR
1181             & RCC_CR_HSITRIM) >> RCC_CR_HSITRIM_Pos);
1182 
1183     /* Get the LSE configuration -----------------------------------------------*/
1184     if ((RCC->BDCR & RCC_BDCR_LSEBYP) == RCC_BDCR_LSEBYP) {
1185         RCC_OscInitStruct->LSEState = RCC_LSE_BYPASS;
1186     } else if ((RCC->BDCR & RCC_BDCR_LSEON) == RCC_BDCR_LSEON) {
1187         RCC_OscInitStruct->LSEState = RCC_LSE_ON;
1188     } else {
1189         RCC_OscInitStruct->LSEState = RCC_LSE_OFF;
1190     }
1191 
1192     /* Get the LSI configuration -----------------------------------------------*/
1193     if ((RCC->CSR & RCC_CSR_LSION) == RCC_CSR_LSION) {
1194         RCC_OscInitStruct->LSIState = RCC_LSI_ON;
1195     } else {
1196         RCC_OscInitStruct->LSIState = RCC_LSI_OFF;
1197     }
1198 
1199     /* Get the PLL configuration -----------------------------------------------*/
1200     if ((RCC->CR & RCC_CR_PLLON) == RCC_CR_PLLON) {
1201         RCC_OscInitStruct->PLL.PLLState = RCC_PLL_ON;
1202     } else {
1203         RCC_OscInitStruct->PLL.PLLState = RCC_PLL_OFF;
1204     }
1205     RCC_OscInitStruct->PLL.PLLSource = (uint32_t) (RCC->CFGR & RCC_CFGR_PLLSRC);
1206     RCC_OscInitStruct->PLL.PLLMUL = (uint32_t) (RCC->CFGR & RCC_CFGR_PLLMULL);
1207 #if defined(RCC_CR_PLL2ON)
1208   /* Get the PLL2 configuration -----------------------------------------------*/
1209   if ((RCC->CR & RCC_CR_PLL2ON) == RCC_CR_PLL2ON)
1210   {
1211     RCC_OscInitStruct->PLL2.PLL2State = RCC_PLL2_ON;
1212   }
1213   else
1214   {
1215     RCC_OscInitStruct->PLL2.PLL2State = RCC_PLL2_OFF;
1216   }
1217   RCC_OscInitStruct->PLL2.HSEPrediv2Value = __HAL_RCC_HSE_GET_PREDIV2();
1218   RCC_OscInitStruct->PLL2.PLL2MUL = (uint32_t)(RCC->CFGR2 & RCC_CFGR2_PLL2MUL);
1219 #endif /* RCC_CR_PLL2ON */
1220 }
1221 
1222 /**
1223  * @brief  Get the RCC_ClkInitStruct according to the internal
1224  * RCC configuration registers.
1225  * @param  RCC_ClkInitStruct pointer to an RCC_ClkInitTypeDef structure that
1226  * contains the current clock configuration.
1227  * @param  pFLatency Pointer on the Flash Latency.
1228  * @retval None
1229  */
1230 void HAL_RCC_GetClockConfig(RCC_ClkInitTypeDef *RCC_ClkInitStruct,
1231         uint32_t *pFLatency)
1232 {
1233     /* Check the parameters */
1234     assert_param(RCC_ClkInitStruct != NULL);
1235     assert_param(pFLatency != NULL);
1236 
1237     /* Set all possible values for the Clock type parameter --------------------*/
1238     RCC_ClkInitStruct->ClockType = RCC_CLOCKTYPE_SYSCLK | RCC_CLOCKTYPE_HCLK
1239             | RCC_CLOCKTYPE_PCLK1 | RCC_CLOCKTYPE_PCLK2;
1240 
1241     /* Get the SYSCLK configuration --------------------------------------------*/
1242     RCC_ClkInitStruct->SYSCLKSource = (uint32_t) (RCC->CFGR & RCC_CFGR_SW);
1243 
1244     /* Get the HCLK configuration ----------------------------------------------*/
1245     RCC_ClkInitStruct->AHBCLKDivider = (uint32_t) (RCC->CFGR & RCC_CFGR_HPRE);
1246 
1247     /* Get the APB1 configuration ----------------------------------------------*/
1248     RCC_ClkInitStruct->APB1CLKDivider = (uint32_t) (RCC->CFGR & RCC_CFGR_PPRE1);
1249 
1250     /* Get the APB2 configuration ----------------------------------------------*/
1251     RCC_ClkInitStruct->APB2CLKDivider = (uint32_t) ((RCC->CFGR & RCC_CFGR_PPRE2)
1252             >> 3);
1253 
1254 #if   defined(FLASH_ACR_LATENCY)
1255     /* Get the Flash Wait State (Latency) configuration ------------------------*/
1256     *pFLatency = (uint32_t) (FLASH->ACR & FLASH_ACR_LATENCY);
1257 #else
1258   /* For VALUE lines devices, only LATENCY_0 can be set*/
1259   *pFLatency = (uint32_t)FLASH_LATENCY_0;
1260 #endif
1261 }
1262 
1263 /**
1264  * @brief This function handles the RCC CSS interrupt request.
1265  * @note This API should be called under the NMI_Handler().
1266  * @retval None
1267  */
1268 void HAL_RCC_NMI_IRQHandler(void)
1269 {
1270     /* Check RCC CSSF flag  */
1271     if (__HAL_RCC_GET_IT(RCC_IT_CSS)) {
1272         /* RCC Clock Security System interrupt user callback */
1273         HAL_RCC_CSSCallback();
1274 
1275         /* Clear RCC CSS pending bit */
1276         __HAL_RCC_CLEAR_IT(RCC_IT_CSS);
1277     }
1278 }
1279 
1280 /**
1281  * @brief  This function provides delay (in milliseconds) based on CPU cycles method.
1282  * @param  mdelay: specifies the delay time length, in milliseconds.
1283  * @retval None
1284  */
1285 static void RCC_Delay(uint32_t mdelay)
1286 {
1287     __IO uint32_t Delay = mdelay * (SystemCoreClock / 8U / 1000U);
1288     do {
1289         __NOP();
1290     } while (Delay--);
1291 }
1292 
1293 /**
1294  * @brief  RCC Clock Security System interrupt callback
1295  * @retval none
1296  */
1297 __weak void HAL_RCC_CSSCallback(void)
1298 {
1299     /* NOTE : This function Should not be modified, when the callback is needed,
1300      the HAL_RCC_CSSCallback could be implemented in the user file
1301      */
1302 }
1303 
1304 /**
1305  * @}
1306  */
1307 
1308 /**
1309  * @}
1310  */
1311 
1312 #endif /* HAL_RCC_MODULE_ENABLED */
1313 /**
1314  * @}
1315  */
1316 
1317 /**
1318  * @}
1319  */
1320