You cannot select more than 25 topics
			Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
		
		
		
		
		
			
		
			
				
	
	
		
			1473 lines
		
	
	
		
			54 KiB
		
	
	
	
		
			C
		
	
			
		
		
	
	
			1473 lines
		
	
	
		
			54 KiB
		
	
	
	
		
			C
		
	
| /**
 | |
|   ******************************************************************************
 | |
|   * @file    stm32g0xx_hal_rcc.c
 | |
|   * @author  MCD Application Team
 | |
|   * @brief   RCC HAL module driver.
 | |
|   *          This file provides firmware functions to manage the following
 | |
|   *          functionalities of the Reset and Clock Control (RCC) peripheral:
 | |
|   *           + Initialization and de-initialization functions
 | |
|   *           + Peripheral Control functions
 | |
|   *
 | |
|   @verbatim
 | |
|   ==============================================================================
 | |
|                       ##### RCC specific features #####
 | |
|   ==============================================================================
 | |
|     [..]
 | |
|       After reset the device is running from High Speed Internal oscillator
 | |
|       (from 8 MHz to reach 16MHz) with Flash 0 wait state. Flash prefetch buffer,
 | |
|       D-Cache and I-Cache are disabled, and all peripherals are off except internal
 | |
|       SRAM, Flash and JTAG.
 | |
| 
 | |
|       (+) There is no prescaler on High speed (AHB) and Low speed (APB) buses:
 | |
|           all peripherals mapped on these buses are running at HSI speed.
 | |
|       (+) The clock for all peripherals is switched off, except the SRAM and FLASH.
 | |
|       (+) All GPIOs are in analog mode, except the JTAG pins which
 | |
|           are assigned to be used for debug purpose.
 | |
| 
 | |
|     [..]
 | |
|       Once the device started from reset, the user application has to:
 | |
|       (+) Configure the clock source to be used to drive the System clock
 | |
|           (if the application needs higher frequency/performance)
 | |
|       (+) Configure the System clock frequency and Flash settings
 | |
|       (+) Configure the AHB and APB buses prescalers
 | |
|       (+) Enable the clock for the peripheral(s) to be used
 | |
|       (+) Configure the clock source(s) for peripherals which clocks are not
 | |
|           derived from the System clock (RTC, ADC, RNG, HSTIM)
 | |
| 
 | |
|   @endverbatim
 | |
|   ******************************************************************************
 | |
|   * @attention
 | |
|   *
 | |
|   * Copyright (c) 2018 STMicroelectronics.
 | |
|   * All rights reserved.
 | |
|   *
 | |
|   * This software is licensed under terms that can be found in the LICENSE file in
 | |
|   * the root directory of this software component.
 | |
|   * If no LICENSE file comes with this software, it is provided AS-IS.
 | |
|   ******************************************************************************
 | |
|   */
 | |
| 
 | |
| /* Includes ------------------------------------------------------------------*/
 | |
| #include "stm32g0xx_hal.h"
 | |
| 
 | |
| /** @addtogroup STM32G0xx_HAL_Driver
 | |
|   * @{
 | |
|   */
 | |
| 
 | |
| /** @defgroup RCC RCC
 | |
|   * @brief RCC HAL module driver
 | |
|   * @{
 | |
|   */
 | |
| 
 | |
| #ifdef HAL_RCC_MODULE_ENABLED
 | |
| 
 | |
| /* Private typedef -----------------------------------------------------------*/
 | |
| /* Private define ------------------------------------------------------------*/
 | |
| /** @defgroup RCC_Private_Constants RCC Private Constants
 | |
|   * @{
 | |
|   */
 | |
| #define HSE_TIMEOUT_VALUE          HSE_STARTUP_TIMEOUT
 | |
| #define HSI_TIMEOUT_VALUE          (2U)    /* 2 ms (minimum Tick + 1) */
 | |
| #define LSI_TIMEOUT_VALUE          (2U)    /* 2 ms (minimum Tick + 1) */
 | |
| #define PLL_TIMEOUT_VALUE          (2U)    /* 2 ms (minimum Tick + 1) */
 | |
| 
 | |
| #if defined(RCC_HSI48_SUPPORT)
 | |
| #define HSI48_TIMEOUT_VALUE        (2U)    /* 2 ms (minimum Tick + 1) */
 | |
| #endif /* RCC_HSI48_SUPPORT */
 | |
| #define CLOCKSWITCH_TIMEOUT_VALUE  (5000U) /* 5 s    */
 | |
| 
 | |
| #define PLLSOURCE_NONE             (0U)
 | |
| /**
 | |
|   * @}
 | |
|   */
 | |
| 
 | |
| /* Private macro -------------------------------------------------------------*/
 | |
| /** @defgroup RCC_Private_Macros RCC Private Macros
 | |
|   * @{
 | |
|   */
 | |
| 
 | |
| #define RCC_GET_MCO_GPIO_PIN(__RCC_MCOx__)   ((__RCC_MCOx__) & GPIO_PIN_MASK)
 | |
| 
 | |
| #define RCC_GET_MCO_GPIO_AF(__RCC_MCOx__)    (((__RCC_MCOx__) & RCC_MCO_GPIOAF_MASK) >> RCC_MCO_GPIOAF_POS)
 | |
| 
 | |
| #define RCC_GET_MCO_GPIO_INDEX(__RCC_MCOx__) (((__RCC_MCOx__) & RCC_MCO_GPIOPORT_MASK) >> RCC_MCO_GPIOPORT_POS)
 | |
| 
 | |
| #define RCC_GET_MCO_GPIO_PORT(__RCC_MCOx__)  (IOPORT_BASE + ((0x00000400UL) * RCC_GET_MCO_GPIO_INDEX(__RCC_MCOx__)))
 | |
| 
 | |
| #define RCC_PLL_OSCSOURCE_CONFIG(__HAL_RCC_PLLSOURCE__) \
 | |
|   (MODIFY_REG(RCC->PLLCFGR, RCC_PLLCFGR_PLLSRC, (uint32_t)(__HAL_RCC_PLLSOURCE__)))
 | |
| /**
 | |
|   * @}
 | |
|   */
 | |
| 
 | |
| /* Private variables ---------------------------------------------------------*/
 | |
| /** @defgroup RCC_Private_Variables RCC Private Variables
 | |
|   * @{
 | |
|   */
 | |
| 
 | |
| /**
 | |
|   * @}
 | |
|   */
 | |
| 
 | |
| /* Private function prototypes -----------------------------------------------*/
 | |
| /* Exported functions --------------------------------------------------------*/
 | |
| 
 | |
| /** @defgroup RCC_Exported_Functions RCC Exported Functions
 | |
|   * @{
 | |
|   */
 | |
| 
 | |
| /** @defgroup RCC_Exported_Functions_Group1 Initialization and de-initialization functions
 | |
|   *  @brief    Initialization and Configuration functions
 | |
|   *
 | |
|   @verbatim
 | |
|  ===============================================================================
 | |
|            ##### Initialization and de-initialization functions #####
 | |
|  ===============================================================================
 | |
|     [..]
 | |
|       This section provides functions allowing to configure the internal and external oscillators
 | |
|       (HSE, HSI, LSE, LSI, PLL, CSS and MCO) and the System buses clocks (SYSCLK, AHB, APB)
 | |
| 
 | |
|     [..] Internal/external clock and PLL configuration
 | |
|          (+) HSI (high-speed internal): 16 MHz factory-trimmed RC used directly or through
 | |
|              the PLL as System clock source.
 | |
| 
 | |
|          (+) LSI (low-speed internal): 32 KHz low consumption RC used as IWDG and/or RTC
 | |
|              clock source.
 | |
| 
 | |
|          (+) HSE (high-speed external): 4 to 48 MHz crystal oscillator used directly or
 | |
|              through the PLL as System clock source. Can be used also optionally as RTC clock source.
 | |
| 
 | |
|          (+) LSE (low-speed external): 32.768 KHz oscillator used optionally as RTC clock source.
 | |
| 
 | |
|          (+) PLL (clocked by HSI, HSE) providing up to three independent output clocks:
 | |
|            (++) The first output (R) is used to generate the high speed system clock (up to 64MHz).
 | |
|            (++) The second output(Q) is used to generate the clock for the random analog generator and HStim.
 | |
|            (++) The Third output (P) is used to generate the clock for the Analog to Digital Converter and I2S.
 | |
| 
 | |
|          (+) CSS (Clock security system): once enabled, if a HSE or LSE clock failure occurs
 | |
|             (HSE used directly or through PLL as System clock source), the System clock
 | |
|              is automatically switched respectively to HSI or LSI and an interrupt is generated
 | |
|              if enabled. The interrupt is linked to the Cortex-M0+ NMI (Non-Maskable Interrupt)
 | |
|              exception vector.
 | |
| 
 | |
|          (+) MCOx (microcontroller clock output):
 | |
|              (++) MCO1 used to output LSI, HSI48(*), HSI, LSE, HSE or main PLL clock (through a configurable prescaler) on PA8 pin.
 | |
|              (++) MCO2(*) used to output LSI, HSI48(*), HSI, LSE, HSE, main PLLR clock, PLLQ clock, PLLP clock, RTC clock or RTC_Wakeup (through a configurable prescaler) on PA10 pin.
 | |
|                  (*) available on certain devices only
 | |
| 
 | |
|     [..] System, AHB and APB buses clocks configuration
 | |
|          (+) Several clock sources can be used to drive the System clock (SYSCLK): HSI,
 | |
|              HSE, LSI, LSE and main PLL.
 | |
|              The AHB clock (HCLK) is derived from System clock through configurable
 | |
|              prescaler and used to clock the CPU, memory and peripherals mapped
 | |
|              on AHB bus (DMA, GPIO...).and APB (PCLK1) clock is derived
 | |
|              from AHB clock through configurable prescalers and used to clock
 | |
|              the peripherals mapped on these buses. You can use
 | |
|              "HAL_RCC_GetSysClockFreq()" function to retrieve the frequencies of these clocks.
 | |
| 
 | |
|          -@- All the peripheral clocks are derived from the System clock (SYSCLK) except:
 | |
| 
 | |
|             (+@) RTC: the RTC clock can be derived either from the LSI, LSE or HSE clock
 | |
|                 divided by 2 to 31.
 | |
|                 You have to use __HAL_RCC_RTC_ENABLE() and HAL_RCCEx_PeriphCLKConfig() function
 | |
|                  to configure this clock.
 | |
| 
 | |
|             (+@) RNG(*) requires a frequency equal or lower than 48 MHz.
 | |
|                  This clock is derived from the main PLL or HSI or System clock.
 | |
|                  (*) available on certain devices only
 | |
| 
 | |
|             (+@) IWDG clock which is always the LSI clock.
 | |
| 
 | |
| 
 | |
|          (+) The maximum frequency of the SYSCLK, HCLK, PCLK is 64 MHz.
 | |
|              Depending on the device voltage range, the maximum frequency should be
 | |
|              adapted accordingly.
 | |
| 
 | |
|   @endverbatim
 | |
| 
 | |
|      (++)  Table 1. HCLK clock frequency.
 | |
|      (++)  +-------------------------------------------------------+
 | |
|      (++)  | Latency         |    HCLK clock frequency (MHz)       |
 | |
|      (++)  |                 |-------------------------------------|
 | |
|      (++)  |                 | voltage range 1  | voltage range 2  |
 | |
|      (++)  |                 |      1.2 V       |     1.0 V        |
 | |
|      (++)  |-----------------|------------------|------------------|
 | |
|      (++)  |0WS(1 CPU cycles)|  HCLK <= 24      |  HCLK <= 8       |
 | |
|      (++)  |-----------------|------------------|------------------|
 | |
|      (++)  |1WS(2 CPU cycles)|  HCLK <= 48      |  HCLK <= 16      |
 | |
|      (++)  |-----------------|------------------|------------------|
 | |
|      (++)  |2WS(3 CPU cycles)|  HCLK <= 64      |           -      |
 | |
|      (++)  |-----------------|------------------|------------------|
 | |
|    * @{
 | |
|   */
 | |
| 
 | |
| /**
 | |
|   * @brief  Reset the RCC clock configuration to the default reset state.
 | |
|   * @note   The default reset state of the clock configuration is given below:
 | |
|   *            - HSI ON and used as system clock source
 | |
|   *            - HSE, PLL OFF
 | |
|   *            - AHB and APB prescaler set to 1.
 | |
|   *            - CSS, MCO1 OFF
 | |
|   *            - All interrupts disabled
 | |
|   * @note   This function does not modify the configuration of the
 | |
|   *            - Peripheral clocks
 | |
|   *            - LSI, LSE and RTC clocks
 | |
|   * @retval HAL status
 | |
|   */
 | |
| HAL_StatusTypeDef HAL_RCC_DeInit(void)
 | |
| {
 | |
|   uint32_t tickstart;
 | |
| 
 | |
|   /* Get Start Tick*/
 | |
|   tickstart = HAL_GetTick();
 | |
| 
 | |
|   /* Set HSION bit to the reset value */
 | |
|   SET_BIT(RCC->CR, RCC_CR_HSION);
 | |
| 
 | |
|   /* Wait till HSI is ready */
 | |
|   while (READ_BIT(RCC->CR, RCC_CR_HSIRDY) == 0U)
 | |
|   {
 | |
|     if ((HAL_GetTick() - tickstart) > HSI_TIMEOUT_VALUE)
 | |
|     {
 | |
|       return HAL_TIMEOUT;
 | |
|     }
 | |
|   }
 | |
| 
 | |
|   /* Set HSITRIM[6:0] bits to the reset value */
 | |
|   RCC->ICSCR = RCC_ICSCR_HSITRIM_6;
 | |
| 
 | |
|   /* Get Start Tick*/
 | |
|   tickstart = HAL_GetTick();
 | |
| 
 | |
|   /* Reset CFGR register (HSI is selected as system clock source) */
 | |
|   RCC->CFGR = 0x00000000u;
 | |
| 
 | |
|   /* Wait till HSI is ready */
 | |
|   while (READ_BIT(RCC->CFGR, RCC_CFGR_SWS) != 0U)
 | |
|   {
 | |
|     if ((HAL_GetTick() - tickstart) > CLOCKSWITCH_TIMEOUT_VALUE)
 | |
|     {
 | |
|       return HAL_TIMEOUT;
 | |
|     }
 | |
|   }
 | |
| 
 | |
|   /* Clear CR register in 2 steps: first to clear HSEON in case bypass was enabled */
 | |
|   RCC->CR = RCC_CR_HSION;
 | |
| 
 | |
|   /* Then again to HSEBYP in case bypass was enabled */
 | |
|   RCC->CR = RCC_CR_HSION;
 | |
| 
 | |
|   /* Get Start Tick*/
 | |
|   tickstart = HAL_GetTick();
 | |
| 
 | |
|   /* Wait till PLL is ready */
 | |
|   while (READ_BIT(RCC->CR, RCC_CR_PLLRDY) != 0U)
 | |
|   {
 | |
|     if ((HAL_GetTick() - tickstart) > PLL_TIMEOUT_VALUE)
 | |
|     {
 | |
|       return HAL_TIMEOUT;
 | |
|     }
 | |
|   }
 | |
| 
 | |
|   /* once PLL is OFF, reset PLLCFGR register to default value */
 | |
|   RCC->PLLCFGR = RCC_PLLCFGR_PLLN_4;
 | |
| 
 | |
|   /* Disable all interrupts */
 | |
|   RCC->CIER = 0x00000000u;
 | |
| 
 | |
|   /* Clear all flags */
 | |
|   RCC->CICR = 0xFFFFFFFFu;
 | |
| 
 | |
|   /* Update the SystemCoreClock global variable */
 | |
|   SystemCoreClock = HSI_VALUE;
 | |
| 
 | |
|   /* Adapt Systick interrupt period */
 | |
|   if (HAL_InitTick(uwTickPrio) != HAL_OK)
 | |
|   {
 | |
|     return HAL_ERROR;
 | |
|   }
 | |
|   else
 | |
|   {
 | |
|     return HAL_OK;
 | |
|   }
 | |
| }
 | |
| 
 | |
| /**
 | |
|   * @brief  Initialize the RCC Oscillators according to the specified parameters in the
 | |
|   *         @ref RCC_OscInitTypeDef.
 | |
|   * @param  RCC_OscInitStruct pointer to a @ref RCC_OscInitTypeDef structure that
 | |
|   *         contains the configuration information for the RCC Oscillators.
 | |
|   * @note   The PLL is not disabled when used as system clock.
 | |
|   * @note   Transition HSE Bypass to HSE On and HSE On to HSE Bypass are not
 | |
|   *         supported by this function. User should request a transition to HSE Off
 | |
|   *         first and then to HSE On or HSE Bypass.
 | |
|   * @note   Transition LSE Bypass to LSE On and LSE On to LSE Bypass are not
 | |
|   *         supported by this function. User should request a transition to LSE Off
 | |
|   *         first and then to LSE On or LSE Bypass.
 | |
|   * @retval HAL status
 | |
|   */
 | |
| HAL_StatusTypeDef HAL_RCC_OscConfig(RCC_OscInitTypeDef  *RCC_OscInitStruct)
 | |
| {
 | |
|   uint32_t tickstart;
 | |
|   uint32_t temp_sysclksrc;
 | |
|   uint32_t temp_pllckcfg;
 | |
| 
 | |
|   /* Check Null pointer */
 | |
|   if (RCC_OscInitStruct == NULL)
 | |
|   {
 | |
|     return HAL_ERROR;
 | |
|   }
 | |
| 
 | |
|   /* Check the parameters */
 | |
|   assert_param(IS_RCC_OSCILLATORTYPE(RCC_OscInitStruct->OscillatorType));
 | |
| 
 | |
|   /*------------------------------- HSE Configuration ------------------------*/
 | |
|   if (((RCC_OscInitStruct->OscillatorType) & RCC_OSCILLATORTYPE_HSE) == RCC_OSCILLATORTYPE_HSE)
 | |
|   {
 | |
|     /* Check the parameters */
 | |
|     assert_param(IS_RCC_HSE(RCC_OscInitStruct->HSEState));
 | |
| 
 | |
|     temp_sysclksrc = __HAL_RCC_GET_SYSCLK_SOURCE();
 | |
|     temp_pllckcfg = __HAL_RCC_GET_PLL_OSCSOURCE();
 | |
| 
 | |
|     /* When the HSE is used as system clock or clock source for PLL in these cases it is not allowed to be disabled */
 | |
|     if (((temp_sysclksrc == RCC_SYSCLKSOURCE_STATUS_PLLCLK) && (temp_pllckcfg == RCC_PLLSOURCE_HSE))
 | |
|         || (temp_sysclksrc == RCC_SYSCLKSOURCE_STATUS_HSE))
 | |
|     {
 | |
|       if ((READ_BIT(RCC->CR, RCC_CR_HSERDY) != 0U) && (RCC_OscInitStruct->HSEState == RCC_HSE_OFF))
 | |
|       {
 | |
|         return HAL_ERROR;
 | |
|       }
 | |
|     }
 | |
|     else
 | |
|     {
 | |
|       /* Set the new HSE configuration ---------------------------------------*/
 | |
|       __HAL_RCC_HSE_CONFIG(RCC_OscInitStruct->HSEState);
 | |
| 
 | |
|       /* Check the HSE State */
 | |
|       if (RCC_OscInitStruct->HSEState != RCC_HSE_OFF)
 | |
|       {
 | |
|         /* Get Start Tick*/
 | |
|         tickstart = HAL_GetTick();
 | |
| 
 | |
|         /* Wait till HSE is ready */
 | |
|         while (READ_BIT(RCC->CR, RCC_CR_HSERDY) == 0U)
 | |
|         {
 | |
|           if ((HAL_GetTick() - tickstart) > HSE_TIMEOUT_VALUE)
 | |
|           {
 | |
|             return HAL_TIMEOUT;
 | |
|           }
 | |
|         }
 | |
|       }
 | |
|       else
 | |
|       {
 | |
|         /* Get Start Tick*/
 | |
|         tickstart = HAL_GetTick();
 | |
| 
 | |
|         /* Wait till HSE is disabled */
 | |
|         while (READ_BIT(RCC->CR, RCC_CR_HSERDY) != 0U)
 | |
|         {
 | |
|           if ((HAL_GetTick() - tickstart) > HSE_TIMEOUT_VALUE)
 | |
|           {
 | |
|             return HAL_TIMEOUT;
 | |
|           }
 | |
|         }
 | |
|       }
 | |
|     }
 | |
|   }
 | |
|   /*----------------------------- HSI Configuration --------------------------*/
 | |
|   if (((RCC_OscInitStruct->OscillatorType) & RCC_OSCILLATORTYPE_HSI) == RCC_OSCILLATORTYPE_HSI)
 | |
|   {
 | |
|     /* Check the parameters */
 | |
|     assert_param(IS_RCC_HSI(RCC_OscInitStruct->HSIState));
 | |
|     assert_param(IS_RCC_HSI_CALIBRATION_VALUE(RCC_OscInitStruct->HSICalibrationValue));
 | |
|     assert_param(IS_RCC_HSIDIV(RCC_OscInitStruct->HSIDiv));
 | |
| 
 | |
|     /* Check if HSI16 is used as system clock or as PLL source when PLL is selected as system clock */
 | |
|     temp_sysclksrc = __HAL_RCC_GET_SYSCLK_SOURCE();
 | |
|     temp_pllckcfg = __HAL_RCC_GET_PLL_OSCSOURCE();
 | |
|     if (((temp_sysclksrc == RCC_SYSCLKSOURCE_STATUS_PLLCLK) && (temp_pllckcfg == RCC_PLLSOURCE_HSI))
 | |
|         || (temp_sysclksrc == RCC_SYSCLKSOURCE_STATUS_HSI))
 | |
|     {
 | |
|       /* When HSI is used as system clock or as PLL input clock it can not be disabled */
 | |
|       if ((READ_BIT(RCC->CR, RCC_CR_HSIRDY) != 0U) && (RCC_OscInitStruct->HSIState == RCC_HSI_OFF))
 | |
|       {
 | |
|         return HAL_ERROR;
 | |
|       }
 | |
|       /* Otherwise, just the calibration is allowed */
 | |
|       else
 | |
|       {
 | |
|         /* Adjusts the Internal High Speed oscillator (HSI) calibration value.*/
 | |
|         __HAL_RCC_HSI_CALIBRATIONVALUE_ADJUST(RCC_OscInitStruct->HSICalibrationValue);
 | |
| 
 | |
|         if (temp_sysclksrc == RCC_SYSCLKSOURCE_STATUS_HSI)
 | |
|         {
 | |
|           /* Adjust the HSI16 division factor */
 | |
|           __HAL_RCC_HSI_CONFIG(RCC_OscInitStruct->HSIDiv);
 | |
| 
 | |
|           /* Update the SystemCoreClock global variable with HSISYS value  */
 | |
|           SystemCoreClock = (HSI_VALUE / (1UL << ((READ_BIT(RCC->CR, RCC_CR_HSIDIV)) >> RCC_CR_HSIDIV_Pos)));
 | |
|         }
 | |
| 
 | |
|         /* Adapt Systick interrupt period */
 | |
|         if (HAL_InitTick(uwTickPrio) != HAL_OK)
 | |
|         {
 | |
|           return HAL_ERROR;
 | |
|         }
 | |
|       }
 | |
|     }
 | |
|     else
 | |
|     {
 | |
|       /* Check the HSI State */
 | |
|       if (RCC_OscInitStruct->HSIState != RCC_HSI_OFF)
 | |
|       {
 | |
|         /* Configure the HSI16 division factor */
 | |
|         __HAL_RCC_HSI_CONFIG(RCC_OscInitStruct->HSIDiv);
 | |
| 
 | |
|         /* Enable the Internal High Speed oscillator (HSI16). */
 | |
|         __HAL_RCC_HSI_ENABLE();
 | |
| 
 | |
|         /* Get Start Tick*/
 | |
|         tickstart = HAL_GetTick();
 | |
| 
 | |
|         /* Wait till HSI is ready */
 | |
|         while (READ_BIT(RCC->CR, RCC_CR_HSIRDY) == 0U)
 | |
|         {
 | |
|           if ((HAL_GetTick() - tickstart) > HSI_TIMEOUT_VALUE)
 | |
|           {
 | |
|             return HAL_TIMEOUT;
 | |
|           }
 | |
|         }
 | |
| 
 | |
|         /* Adjusts the Internal High Speed oscillator (HSI) calibration value.*/
 | |
|         __HAL_RCC_HSI_CALIBRATIONVALUE_ADJUST(RCC_OscInitStruct->HSICalibrationValue);
 | |
|       }
 | |
|       else
 | |
|       {
 | |
|         /* Disable the Internal High Speed oscillator (HSI16). */
 | |
|         __HAL_RCC_HSI_DISABLE();
 | |
| 
 | |
|         /* Get Start Tick*/
 | |
|         tickstart = HAL_GetTick();
 | |
| 
 | |
|         /* Wait till HSI is disabled */
 | |
|         while (READ_BIT(RCC->CR, RCC_CR_HSIRDY) != 0U)
 | |
|         {
 | |
|           if ((HAL_GetTick() - tickstart) > HSI_TIMEOUT_VALUE)
 | |
|           {
 | |
|             return HAL_TIMEOUT;
 | |
|           }
 | |
|         }
 | |
|       }
 | |
|     }
 | |
|   }
 | |
|   /*------------------------------ LSI Configuration -------------------------*/
 | |
|   if (((RCC_OscInitStruct->OscillatorType) & RCC_OSCILLATORTYPE_LSI) == RCC_OSCILLATORTYPE_LSI)
 | |
|   {
 | |
|     /* Check the parameters */
 | |
|     assert_param(IS_RCC_LSI(RCC_OscInitStruct->LSIState));
 | |
| 
 | |
|     /* Check if LSI is used as system clock */
 | |
|     if (__HAL_RCC_GET_SYSCLK_SOURCE() == RCC_SYSCLKSOURCE_STATUS_LSI)
 | |
|     {
 | |
|       /* When LSI is used as system clock it will not be disabled */
 | |
|       if ((((RCC->CSR) & RCC_CSR_LSIRDY) != 0U) && (RCC_OscInitStruct->LSIState == RCC_LSI_OFF))
 | |
|       {
 | |
|         return HAL_ERROR;
 | |
|       }
 | |
|     }
 | |
|     else
 | |
|     {
 | |
|       /* Check the LSI State */
 | |
|       if (RCC_OscInitStruct->LSIState != RCC_LSI_OFF)
 | |
|       {
 | |
|         /* Enable the Internal Low Speed oscillator (LSI). */
 | |
|         __HAL_RCC_LSI_ENABLE();
 | |
| 
 | |
|         /* Get Start Tick*/
 | |
|         tickstart = HAL_GetTick();
 | |
| 
 | |
|         /* Wait till LSI is ready */
 | |
|         while (READ_BIT(RCC->CSR, RCC_CSR_LSIRDY) == 0U)
 | |
|         {
 | |
|           if ((HAL_GetTick() - tickstart) > LSI_TIMEOUT_VALUE)
 | |
|           {
 | |
|             return HAL_TIMEOUT;
 | |
|           }
 | |
|         }
 | |
|       }
 | |
|       else
 | |
|       {
 | |
|         /* Disable the Internal Low Speed oscillator (LSI). */
 | |
|         __HAL_RCC_LSI_DISABLE();
 | |
| 
 | |
|         /* Get Start Tick*/
 | |
|         tickstart = HAL_GetTick();
 | |
| 
 | |
|         /* Wait till LSI is disabled */
 | |
|         while (READ_BIT(RCC->CSR, RCC_CSR_LSIRDY) != 0U)
 | |
|         {
 | |
|           if ((HAL_GetTick() - tickstart) > LSI_TIMEOUT_VALUE)
 | |
|           {
 | |
|             return HAL_TIMEOUT;
 | |
|           }
 | |
|         }
 | |
|       }
 | |
|     }
 | |
|   }
 | |
|   /*------------------------------ LSE Configuration -------------------------*/
 | |
|   if (((RCC_OscInitStruct->OscillatorType) & RCC_OSCILLATORTYPE_LSE) == RCC_OSCILLATORTYPE_LSE)
 | |
|   {
 | |
|     FlagStatus       pwrclkchanged = RESET;
 | |
| 
 | |
|     /* Check the parameters */
 | |
|     assert_param(IS_RCC_LSE(RCC_OscInitStruct->LSEState));
 | |
| 
 | |
|     /* When the LSE is used as system clock, it is not allowed disable it */
 | |
|     if (__HAL_RCC_GET_SYSCLK_SOURCE() == RCC_SYSCLKSOURCE_STATUS_LSE)
 | |
|     {
 | |
|       if ((((RCC->BDCR) & RCC_BDCR_LSERDY) != 0U) && (RCC_OscInitStruct->LSEState == RCC_LSE_OFF))
 | |
|       {
 | |
|         return HAL_ERROR;
 | |
|       }
 | |
|     }
 | |
|     else
 | |
|     {
 | |
|       /* Update LSE configuration in Backup Domain control register    */
 | |
|       /* Requires to enable write access to Backup Domain of necessary */
 | |
|       if (__HAL_RCC_PWR_IS_CLK_DISABLED() != 0U)
 | |
|       {
 | |
|         __HAL_RCC_PWR_CLK_ENABLE();
 | |
|         pwrclkchanged = SET;
 | |
|       }
 | |
| 
 | |
|       if (HAL_IS_BIT_CLR(PWR->CR1, PWR_CR1_DBP))
 | |
|       {
 | |
|         /* Enable write access to Backup domain */
 | |
|         SET_BIT(PWR->CR1, PWR_CR1_DBP);
 | |
| 
 | |
|         /* Wait for Backup domain Write protection disable */
 | |
|         tickstart = HAL_GetTick();
 | |
| 
 | |
|         while (HAL_IS_BIT_CLR(PWR->CR1, PWR_CR1_DBP))
 | |
|         {
 | |
|           if ((HAL_GetTick() - tickstart) > RCC_DBP_TIMEOUT_VALUE)
 | |
|           {
 | |
|             return HAL_TIMEOUT;
 | |
|           }
 | |
|         }
 | |
|       }
 | |
| 
 | |
|       /* Set the new LSE configuration -----------------------------------------*/
 | |
|       __HAL_RCC_LSE_CONFIG(RCC_OscInitStruct->LSEState);
 | |
| 
 | |
|       /* Check the LSE State */
 | |
|       if (RCC_OscInitStruct->LSEState != RCC_LSE_OFF)
 | |
|       {
 | |
|         /* Get Start Tick*/
 | |
|         tickstart = HAL_GetTick();
 | |
| 
 | |
|         /* Wait till LSE is ready */
 | |
|         while (READ_BIT(RCC->BDCR, RCC_BDCR_LSERDY) == 0U)
 | |
|         {
 | |
|           if ((HAL_GetTick() - tickstart) > RCC_LSE_TIMEOUT_VALUE)
 | |
|           {
 | |
|             return HAL_TIMEOUT;
 | |
|           }
 | |
|         }
 | |
|       }
 | |
|       else
 | |
|       {
 | |
|         /* Get Start Tick*/
 | |
|         tickstart = HAL_GetTick();
 | |
| 
 | |
|         /* Wait till LSE is disabled */
 | |
|         while (READ_BIT(RCC->BDCR, RCC_BDCR_LSERDY) != 0U)
 | |
|         {
 | |
|           if ((HAL_GetTick() - tickstart) > RCC_LSE_TIMEOUT_VALUE)
 | |
|           {
 | |
|             return HAL_TIMEOUT;
 | |
|           }
 | |
|         }
 | |
|       }
 | |
| 
 | |
|       /* Restore clock configuration if changed */
 | |
|       if (pwrclkchanged == SET)
 | |
|       {
 | |
|         __HAL_RCC_PWR_CLK_DISABLE();
 | |
|       }
 | |
|     }
 | |
|   }
 | |
| #if defined(RCC_HSI48_SUPPORT)
 | |
|   /*------------------------------ HSI48 Configuration -----------------------*/
 | |
|   if (((RCC_OscInitStruct->OscillatorType) & RCC_OSCILLATORTYPE_HSI48) == RCC_OSCILLATORTYPE_HSI48)
 | |
|   {
 | |
|     /* Check the parameters */
 | |
|     assert_param(IS_RCC_HSI48(RCC_OscInitStruct->HSI48State));
 | |
| 
 | |
|     /* Check the LSI State */
 | |
|     if (RCC_OscInitStruct->HSI48State != RCC_HSI48_OFF)
 | |
|     {
 | |
|       /* Enable the Internal Low Speed oscillator (HSI48). */
 | |
|       __HAL_RCC_HSI48_ENABLE();
 | |
| 
 | |
|       /* Get Start Tick*/
 | |
|       tickstart = HAL_GetTick();
 | |
| 
 | |
|       /* Wait till HSI48 is ready */
 | |
|       while (READ_BIT(RCC->CR, RCC_CR_HSI48RDY) == 0U)
 | |
|       {
 | |
|         if ((HAL_GetTick() - tickstart) > HSI48_TIMEOUT_VALUE)
 | |
|         {
 | |
|           return HAL_TIMEOUT;
 | |
|         }
 | |
|       }
 | |
|     }
 | |
|     else
 | |
|     {
 | |
|       /* Disable the Internal Low Speed oscillator (HSI48). */
 | |
|       __HAL_RCC_HSI48_DISABLE();
 | |
| 
 | |
|       /* Get Start Tick*/
 | |
|       tickstart = HAL_GetTick();
 | |
| 
 | |
|       /* Wait till HSI48 is disabled */
 | |
|       while (READ_BIT(RCC->CR, RCC_CR_HSI48RDY) != 0U)
 | |
|       {
 | |
|         if ((HAL_GetTick() - tickstart) > HSI48_TIMEOUT_VALUE)
 | |
|         {
 | |
|           return HAL_TIMEOUT;
 | |
|         }
 | |
|       }
 | |
|     }
 | |
|   }
 | |
| #endif /* RCC_HSI48_SUPPORT */
 | |
|   /*-------------------------------- PLL Configuration -----------------------*/
 | |
|   /* Check the parameters */
 | |
|   assert_param(IS_RCC_PLL(RCC_OscInitStruct->PLL.PLLState));
 | |
| 
 | |
|   if (RCC_OscInitStruct->PLL.PLLState != RCC_PLL_NONE)
 | |
|   {
 | |
|     /* Check if the PLL is used as system clock or not */
 | |
|     if (__HAL_RCC_GET_SYSCLK_SOURCE() != RCC_SYSCLKSOURCE_STATUS_PLLCLK)
 | |
|     {
 | |
|       if (RCC_OscInitStruct->PLL.PLLState == RCC_PLL_ON)
 | |
|       {
 | |
|         /* Check the parameters */
 | |
|         assert_param(IS_RCC_PLLSOURCE(RCC_OscInitStruct->PLL.PLLSource));
 | |
|         assert_param(IS_RCC_PLLM_VALUE(RCC_OscInitStruct->PLL.PLLM));
 | |
|         assert_param(IS_RCC_PLLN_VALUE(RCC_OscInitStruct->PLL.PLLN));
 | |
|         assert_param(IS_RCC_PLLP_VALUE(RCC_OscInitStruct->PLL.PLLP));
 | |
| #if defined(RCC_PLLQ_SUPPORT)
 | |
|         assert_param(IS_RCC_PLLQ_VALUE(RCC_OscInitStruct->PLL.PLLQ));
 | |
| #endif /* RCC_PLLQ_SUPPORT */
 | |
|         assert_param(IS_RCC_PLLR_VALUE(RCC_OscInitStruct->PLL.PLLR));
 | |
| 
 | |
|         /* Disable the main PLL. */
 | |
|         __HAL_RCC_PLL_DISABLE();
 | |
| 
 | |
|         /* Get Start Tick*/
 | |
|         tickstart = HAL_GetTick();
 | |
| 
 | |
|         /* Wait till PLL is ready */
 | |
|         while (READ_BIT(RCC->CR, RCC_CR_PLLRDY) != 0U)
 | |
|         {
 | |
|           if ((HAL_GetTick() - tickstart) > PLL_TIMEOUT_VALUE)
 | |
|           {
 | |
|             return HAL_TIMEOUT;
 | |
|           }
 | |
|         }
 | |
| 
 | |
|         /* Configure the main PLL clock source, multiplication and division factors. */
 | |
| #if defined(RCC_PLLQ_SUPPORT)
 | |
|         __HAL_RCC_PLL_CONFIG(RCC_OscInitStruct->PLL.PLLSource,
 | |
|                              RCC_OscInitStruct->PLL.PLLM,
 | |
|                              RCC_OscInitStruct->PLL.PLLN,
 | |
|                              RCC_OscInitStruct->PLL.PLLP,
 | |
|                              RCC_OscInitStruct->PLL.PLLQ,
 | |
|                              RCC_OscInitStruct->PLL.PLLR);
 | |
| #else /* !RCC_PLLQ_SUPPORT */
 | |
|         __HAL_RCC_PLL_CONFIG(RCC_OscInitStruct->PLL.PLLSource,
 | |
|                              RCC_OscInitStruct->PLL.PLLM,
 | |
|                              RCC_OscInitStruct->PLL.PLLN,
 | |
|                              RCC_OscInitStruct->PLL.PLLP,
 | |
|                              RCC_OscInitStruct->PLL.PLLR);
 | |
| #endif /* RCC_PLLQ_SUPPORT */
 | |
| 
 | |
|         /* Enable the main PLL. */
 | |
|         __HAL_RCC_PLL_ENABLE();
 | |
| 
 | |
|         /* Enable PLLR Clock output. */
 | |
|         __HAL_RCC_PLLCLKOUT_ENABLE(RCC_PLLRCLK);
 | |
| 
 | |
|         /* Get Start Tick*/
 | |
|         tickstart = HAL_GetTick();
 | |
| 
 | |
|         /* Wait till PLL is ready */
 | |
|         while (READ_BIT(RCC->CR, RCC_CR_PLLRDY) == 0U)
 | |
|         {
 | |
|           if ((HAL_GetTick() - tickstart) > PLL_TIMEOUT_VALUE)
 | |
|           {
 | |
|             return HAL_TIMEOUT;
 | |
|           }
 | |
|         }
 | |
|       }
 | |
|       else
 | |
|       {
 | |
|         /* Disable the main PLL. */
 | |
|         __HAL_RCC_PLL_DISABLE();
 | |
| 
 | |
|         /* Get Start Tick*/
 | |
|         tickstart = HAL_GetTick();
 | |
| 
 | |
|         /* Wait till PLL is disabled */
 | |
|         while (READ_BIT(RCC->CR, RCC_CR_PLLRDY) != 0U)
 | |
|         {
 | |
|           if ((HAL_GetTick() - tickstart) > PLL_TIMEOUT_VALUE)
 | |
|           {
 | |
|             return HAL_TIMEOUT;
 | |
|           }
 | |
|         }
 | |
|         /* Unselect main PLL clock source and disable main PLL outputs to save power */
 | |
| #if defined(RCC_PLLQ_SUPPORT)
 | |
|         RCC->PLLCFGR &= ~(RCC_PLLCFGR_PLLSRC | RCC_PLLCFGR_PLLPEN | RCC_PLLCFGR_PLLQEN | RCC_PLLCFGR_PLLREN);
 | |
| #else
 | |
|         RCC->PLLCFGR &= ~(RCC_PLLCFGR_PLLSRC | RCC_PLLCFGR_PLLPEN | RCC_PLLCFGR_PLLREN);
 | |
| #endif /* RCC_PLLQ_SUPPORT */
 | |
|       }
 | |
|     }
 | |
|     else
 | |
|     {
 | |
|       /* Check if there is a request to disable the PLL used as System clock source */
 | |
|       if ((RCC_OscInitStruct->PLL.PLLState) == RCC_PLL_OFF)
 | |
|       {
 | |
|         return HAL_ERROR;
 | |
|       }
 | |
|       else
 | |
|       {
 | |
|         /* Do not return HAL_ERROR if request repeats the current configuration */
 | |
|         temp_pllckcfg = RCC->PLLCFGR;
 | |
|         if ((READ_BIT(temp_pllckcfg, RCC_PLLCFGR_PLLSRC) != RCC_OscInitStruct->PLL.PLLSource) ||
 | |
|             (READ_BIT(temp_pllckcfg, RCC_PLLCFGR_PLLM) != RCC_OscInitStruct->PLL.PLLM) ||
 | |
|             (READ_BIT(temp_pllckcfg, RCC_PLLCFGR_PLLN) != (RCC_OscInitStruct->PLL.PLLN << RCC_PLLCFGR_PLLN_Pos)) ||
 | |
|             (READ_BIT(temp_pllckcfg, RCC_PLLCFGR_PLLP) != RCC_OscInitStruct->PLL.PLLP) ||
 | |
| #if defined (RCC_PLLQ_SUPPORT)
 | |
|             (READ_BIT(temp_pllckcfg, RCC_PLLCFGR_PLLQ) != RCC_OscInitStruct->PLL.PLLQ) ||
 | |
| #endif /* RCC_PLLQ_SUPPORT */
 | |
|             (READ_BIT(temp_pllckcfg, RCC_PLLCFGR_PLLR) != RCC_OscInitStruct->PLL.PLLR))
 | |
|         {
 | |
|           return HAL_ERROR;
 | |
|         }
 | |
|       }
 | |
|     }
 | |
|   }
 | |
|   return HAL_OK;
 | |
| }
 | |
| 
 | |
| /**
 | |
|   * @brief  Initialize the CPU, AHB and APB buses clocks according to the specified
 | |
|   *         parameters in the RCC_ClkInitStruct.
 | |
|   * @param  RCC_ClkInitStruct  pointer to a @ref RCC_ClkInitTypeDef structure that
 | |
|   *         contains the configuration information for the RCC peripheral.
 | |
|   * @param  FLatency  FLASH Latency
 | |
|   *          This parameter can be one of the following values:
 | |
|   *            @arg FLASH_LATENCY_0   FLASH 0 Latency cycle
 | |
|   *            @arg FLASH_LATENCY_1   FLASH 1 Latency cycle
 | |
|   *
 | |
|   * @note   The SystemCoreClock CMSIS variable is used to store System Clock Frequency
 | |
|   *         and updated by @ref HAL_RCC_GetHCLKFreq() function called within this function
 | |
|   *
 | |
|   * @note   The HSI is used by default as system clock source after
 | |
|   *         startup from Reset, wake-up from STANDBY mode. After restart from Reset,
 | |
|   *         the HSI frequency is set to 8 Mhz, then it reaches its default value 16 MHz.
 | |
|   *
 | |
|   * @note   The HSI can be selected as system clock source after
 | |
|   *         from STOP modes or in case of failure of the HSE used directly or indirectly
 | |
|   *         as system clock (if the Clock Security System CSS is enabled).
 | |
|   *
 | |
|   * @note   The LSI can be selected as system clock source after
 | |
|   *         in case of failure of the LSE used directly or indirectly
 | |
|   *         as system clock (if the Clock Security System LSECSS is enabled).
 | |
|   *
 | |
|   * @note   A switch from one clock source to another occurs only if the target
 | |
|   *         clock source is ready (clock stable after startup delay or PLL locked).
 | |
|   *         If a clock source which is not yet ready is selected, the switch will
 | |
|   *         occur when the clock source is ready.
 | |
|   *
 | |
|   * @note   You can use @ref HAL_RCC_GetClockConfig() function to know which clock is
 | |
|   *         currently used as system clock source.
 | |
|   *
 | |
|   * @note   Depending on the device voltage range, the software has to set correctly
 | |
|   *         HPRE[3:0] bits to ensure that HCLK not exceed the maximum allowed frequency
 | |
|   *         (for more details refer to section above "Initialization/de-initialization functions")
 | |
|   * @retval None
 | |
|   */
 | |
| HAL_StatusTypeDef HAL_RCC_ClockConfig(RCC_ClkInitTypeDef  *RCC_ClkInitStruct, uint32_t FLatency)
 | |
| {
 | |
|   uint32_t tickstart;
 | |
| 
 | |
|   /* Check Null pointer */
 | |
|   if (RCC_ClkInitStruct == NULL)
 | |
|   {
 | |
|     return HAL_ERROR;
 | |
|   }
 | |
| 
 | |
|   /* Check the parameters */
 | |
|   assert_param(IS_RCC_CLOCKTYPE(RCC_ClkInitStruct->ClockType));
 | |
|   assert_param(IS_FLASH_LATENCY(FLatency));
 | |
| 
 | |
|   /* To correctly read data from FLASH memory, the number of wait states (LATENCY)
 | |
|     must be correctly programmed according to the frequency of the FLASH clock
 | |
|     (HCLK) and the supply voltage of the device. */
 | |
| 
 | |
|   /* Increasing the number of wait states because of higher CPU frequency */
 | |
|   if (FLatency > __HAL_FLASH_GET_LATENCY())
 | |
|   {
 | |
|     /* Program the new number of wait states to the LATENCY bits in the FLASH_ACR register */
 | |
|     __HAL_FLASH_SET_LATENCY(FLatency);
 | |
| 
 | |
|     /* Check that the new number of wait states is taken into account to access the Flash
 | |
|     memory by polling the FLASH_ACR register */
 | |
|     tickstart = HAL_GetTick();
 | |
| 
 | |
|     while ((FLASH->ACR & FLASH_ACR_LATENCY) != FLatency)
 | |
|     {
 | |
|       if ((HAL_GetTick() - tickstart) > CLOCKSWITCH_TIMEOUT_VALUE)
 | |
|       {
 | |
|         return HAL_TIMEOUT;
 | |
|       }
 | |
|     }
 | |
|   }
 | |
| 
 | |
|   /*-------------------------- HCLK Configuration --------------------------*/
 | |
|   if (((RCC_ClkInitStruct->ClockType) & RCC_CLOCKTYPE_HCLK) == RCC_CLOCKTYPE_HCLK)
 | |
|   {
 | |
|     /* Set the highest APB divider in order to ensure that we do not go through
 | |
|        a non-spec phase whatever we decrease or increase HCLK. */
 | |
|     if (((RCC_ClkInitStruct->ClockType) & RCC_CLOCKTYPE_PCLK1) == RCC_CLOCKTYPE_PCLK1)
 | |
|     {
 | |
|       MODIFY_REG(RCC->CFGR, RCC_CFGR_PPRE, RCC_HCLK_DIV16);
 | |
|     }
 | |
| 
 | |
|     /* Set the new HCLK clock divider */
 | |
|     assert_param(IS_RCC_HCLK(RCC_ClkInitStruct->AHBCLKDivider));
 | |
|     MODIFY_REG(RCC->CFGR, RCC_CFGR_HPRE, RCC_ClkInitStruct->AHBCLKDivider);
 | |
|   }
 | |
| 
 | |
|   /*------------------------- SYSCLK Configuration ---------------------------*/
 | |
|   if (((RCC_ClkInitStruct->ClockType) & RCC_CLOCKTYPE_SYSCLK) == RCC_CLOCKTYPE_SYSCLK)
 | |
|   {
 | |
|     assert_param(IS_RCC_SYSCLKSOURCE(RCC_ClkInitStruct->SYSCLKSource));
 | |
| 
 | |
|     /* HSE is selected as System Clock Source */
 | |
|     if (RCC_ClkInitStruct->SYSCLKSource == RCC_SYSCLKSOURCE_HSE)
 | |
|     {
 | |
|       /* Check the HSE ready flag */
 | |
|       if (READ_BIT(RCC->CR, RCC_CR_HSERDY) == 0U)
 | |
|       {
 | |
|         return HAL_ERROR;
 | |
|       }
 | |
|     }
 | |
|     /* PLL is selected as System Clock Source */
 | |
|     else if (RCC_ClkInitStruct->SYSCLKSource == RCC_SYSCLKSOURCE_PLLCLK)
 | |
|     {
 | |
|       /* Check the PLL ready flag */
 | |
|       if (READ_BIT(RCC->CR, RCC_CR_PLLRDY) == 0U)
 | |
|       {
 | |
|         return HAL_ERROR;
 | |
|       }
 | |
|     }
 | |
|     /* HSI is selected as System Clock Source */
 | |
|     else if (RCC_ClkInitStruct->SYSCLKSource == RCC_SYSCLKSOURCE_HSI)
 | |
|     {
 | |
|       /* Check the HSI ready flag */
 | |
|       if (READ_BIT(RCC->CR, RCC_CR_HSIRDY) == 0U)
 | |
|       {
 | |
|         return HAL_ERROR;
 | |
|       }
 | |
|     }
 | |
|     /* LSI is selected as System Clock Source */
 | |
|     else if (RCC_ClkInitStruct->SYSCLKSource == RCC_SYSCLKSOURCE_LSI)
 | |
|     {
 | |
|       /* Check the LSI ready flag */
 | |
|       if (READ_BIT(RCC->CSR, RCC_CSR_LSIRDY) == 0U)
 | |
|       {
 | |
|         return HAL_ERROR;
 | |
|       }
 | |
|     }
 | |
|     /* LSE is selected as System Clock Source */
 | |
|     else
 | |
|     {
 | |
|       /* Check the LSE ready flag */
 | |
|       if (READ_BIT(RCC->BDCR, RCC_BDCR_LSERDY) == 0U)
 | |
|       {
 | |
|         return HAL_ERROR;
 | |
|       }
 | |
|     }
 | |
|     MODIFY_REG(RCC->CFGR, RCC_CFGR_SW, RCC_ClkInitStruct->SYSCLKSource);
 | |
| 
 | |
|     /* Get Start Tick*/
 | |
|     tickstart = HAL_GetTick();
 | |
| 
 | |
|     while (__HAL_RCC_GET_SYSCLK_SOURCE() != (RCC_ClkInitStruct->SYSCLKSource << RCC_CFGR_SWS_Pos))
 | |
|     {
 | |
|       if ((HAL_GetTick() - tickstart) > CLOCKSWITCH_TIMEOUT_VALUE)
 | |
|       {
 | |
|         return HAL_TIMEOUT;
 | |
|       }
 | |
|     }
 | |
|   }
 | |
| 
 | |
|   /* Decreasing the number of wait states because of lower CPU frequency */
 | |
|   if (FLatency < __HAL_FLASH_GET_LATENCY())
 | |
|   {
 | |
|     /* Program the new number of wait states to the LATENCY bits in the FLASH_ACR register */
 | |
|     __HAL_FLASH_SET_LATENCY(FLatency);
 | |
| 
 | |
|     /* Check that the new number of wait states is taken into account to access the Flash
 | |
|     memory by polling the FLASH_ACR register */
 | |
|     tickstart = HAL_GetTick();
 | |
| 
 | |
|     while ((FLASH->ACR & FLASH_ACR_LATENCY) != FLatency)
 | |
|     {
 | |
|       if ((HAL_GetTick() - tickstart) > CLOCKSWITCH_TIMEOUT_VALUE)
 | |
|       {
 | |
|         return HAL_TIMEOUT;
 | |
|       }
 | |
|     }
 | |
|   }
 | |
| 
 | |
|   /*-------------------------- PCLK1 Configuration ---------------------------*/
 | |
|   if (((RCC_ClkInitStruct->ClockType) & RCC_CLOCKTYPE_PCLK1) == RCC_CLOCKTYPE_PCLK1)
 | |
|   {
 | |
|     assert_param(IS_RCC_PCLK(RCC_ClkInitStruct->APB1CLKDivider));
 | |
|     MODIFY_REG(RCC->CFGR, RCC_CFGR_PPRE, RCC_ClkInitStruct->APB1CLKDivider);
 | |
|   }
 | |
| 
 | |
|   /* Update the SystemCoreClock global variable */
 | |
|   SystemCoreClock = (HAL_RCC_GetSysClockFreq() >> ((AHBPrescTable[(RCC->CFGR & RCC_CFGR_HPRE) >> RCC_CFGR_HPRE_Pos]) & 0x1FU));
 | |
| 
 | |
|   /* Configure the source of time base considering new system clocks settings*/
 | |
|   return HAL_InitTick(uwTickPrio);
 | |
| }
 | |
| 
 | |
| /**
 | |
|   * @}
 | |
|   */
 | |
| 
 | |
| /** @defgroup RCC_Exported_Functions_Group2 Peripheral Control functions
 | |
|   *  @brief   RCC clocks control functions
 | |
|   *
 | |
| @verbatim
 | |
|  ===============================================================================
 | |
|                       ##### Peripheral Control functions #####
 | |
|  ===============================================================================
 | |
|     [..]
 | |
|     This subsection provides a set of functions allowing to:
 | |
| 
 | |
|     (+) Output clock to MCO pin.
 | |
|     (+) Retrieve current clock frequencies.
 | |
|     (+) Enable the Clock Security System.
 | |
| 
 | |
| @endverbatim
 | |
|   * @{
 | |
|   */
 | |
| 
 | |
| /**
 | |
|   * @brief  Select the clock source to output on MCO1 pin(PA8) or MC02 pin (PA10)(*).
 | |
|   * @note   PA8, PA10(*) should be configured in alternate function mode.
 | |
|   * @param  RCC_MCOx  specifies the output direction for the clock source.
 | |
|   *          For STM32G0xx family this parameter can have only one value:
 | |
|   *            @arg @ref RCC_MCO_PA8  Clock source to output on MCO1 pin(PA8).
 | |
|   *            @arg @ref RCC_MCO_PA9  Clock source to output on MCO1 pin(PA9).
 | |
|   *            @arg @ref RCC_MCO_PD10 Clock source to output on MCO1 pin(PD10)(*).
 | |
|   *            @arg @ref RCC_MCO_PF2  Clock source to output on MCO1 pin(PF2)(*).
 | |
|   *            @arg @ref RCC_MCO_PA10 Clock source to output on MCO2 pin(PA10)(*).
 | |
|   *            @arg @ref RCC_MCO_PA15 Clock source to output on MCO2 pin(PA15)(*).
 | |
|   *            @arg @ref RCC_MCO_PB2  Clock source to output on MCO2 pin(PB2)(*).
 | |
|   *            @arg @ref RCC_MCO_PD7  Clock source to output on MCO2 pin(PD7)(*).
 | |
|   * @param  RCC_MCOSource  specifies the clock source to output.
 | |
|   *          This parameter can be one of the following values:
 | |
|   *            @arg @ref RCC_MCO1SOURCE_NOCLOCK  MCO output disabled, no clock on MCO
 | |
|   *            @arg @ref RCC_MCO1SOURCE_SYSCLK   system  clock selected as MCO source
 | |
|   *            @arg @ref RCC_MCO1SOURCE_HSI48    HSI48 clock selected as MCO source for devices with HSI48(*)
 | |
|   *            @arg @ref RCC_MCO1SOURCE_HSI      HSI clock selected as MCO source
 | |
|   *            @arg @ref RCC_MCO1SOURCE_HSE      HSE clock selected as MCO source
 | |
|   *            @arg @ref RCC_MCO1SOURCE_PLLCLK   main PLLR clock selected as MCO source
 | |
|   *            @arg @ref RCC_MCO1SOURCE_LSI      LSI clock selected as MCO source
 | |
|   *            @arg @ref RCC_MCO1SOURCE_LSE      LSE clock selected as MCO source
 | |
|   *            @arg @ref RCC_MCO1SOURCE_PLLPCLK  PLLP clock selected as MCO1 source(*)
 | |
|   *            @arg @ref RCC_MCO1SOURCE_PLLQCLK  PLLQ clock selected as MCO1 source(*)
 | |
|   *            @arg @ref RCC_MCO1SOURCE_RTCCLK   RTC clock selected as MCO1 source(*)
 | |
|   *            @arg @ref RCC_MCO1SOURCE_RTC_WKUP RTC_Wakeup selected as MCO1 source(*)
 | |
|   *            @arg @ref RCC_MCO2SOURCE_NOCLOCK  MCO2 output disabled, no clock on MCO2(*)
 | |
|   *            @arg @ref RCC_MCO2SOURCE_SYSCLK   system  clock selected as MCO2 source(*)
 | |
|   *            @arg @ref RCC_MCO2SOURCE_HSI48    HSI48 clock selected as MCO2 source for devices with HSI48(*)
 | |
|   *            @arg @ref RCC_MCO2SOURCE_HSI      HSI clock selected as MCO2 source(*)
 | |
|   *            @arg @ref RCC_MCO2SOURCE_HSE      HSE clock selected as MCO2 source(*)
 | |
|   *            @arg @ref RCC_MCO2SOURCE_PLLCLK   main PLLR clock selected as MCO2 source(*)
 | |
|   *            @arg @ref RCC_MCO2SOURCE_LSI      LSI clock selected as MCO2 source(*)
 | |
|   *            @arg @ref RCC_MCO2SOURCE_LSE      LSE clock selected as MCO2 source(*)
 | |
|   *            @arg @ref RCC_MCO2SOURCE_PLLPCLK  PLLP clock selected as MCO2 source(*)
 | |
|   *            @arg @ref RCC_MCO2SOURCE_PLLQCLK  PLLQ clock selected as MCO2 source(*)
 | |
|   *            @arg @ref RCC_MCO2SOURCE_RTCCLK   RTC clock selected as MCO2 source(*)
 | |
|   *            @arg @ref RCC_MCO2SOURCE_RTC_WKUP RTC_Wakeup selected as MCO2 source(*)
 | |
|   * @param  RCC_MCODiv  specifies the MCO prescaler.
 | |
|   *          This parameter can be one of the following values:
 | |
|   *            @arg @ref RCC_MCODIV_1     no division applied to MCO clock
 | |
|   *            @arg @ref RCC_MCODIV_2     division by 2 applied to MCO clock
 | |
|   *            @arg @ref RCC_MCODIV_4     division by 4 applied to MCO clock
 | |
|   *            @arg @ref RCC_MCODIV_8     division by 8 applied to MCO clock
 | |
|   *            @arg @ref RCC_MCODIV_16    division by 16 applied to MCO clock
 | |
|   *            @arg @ref RCC_MCODIV_32    division by 32 applied to MCO clock
 | |
|   *            @arg @ref RCC_MCODIV_64    division by 64 applied to MCO clock
 | |
|   *            @arg @ref RCC_MCODIV_128   division by 128 applied to MCO clock
 | |
|   *            @arg @ref RCC_MCO2DIV_1    no division applied to MCO2 clock(*)
 | |
|   *            @arg @ref RCC_MCO2DIV_2    division by 2 applied to MCO2 clock(*)
 | |
|   *            @arg @ref RCC_MCO2DIV_4    division by 4 applied to MCO2 clock(*)
 | |
|   *            @arg @ref RCC_MCO2DIV_8    division by 8 applied to MCO2 clock(*)
 | |
|   *            @arg @ref RCC_MCO2DIV_16   division by 16 applied to MCO2 clock(*)
 | |
|   *            @arg @ref RCC_MCO2DIV_32   division by 32 applied to MCO2 clock(*)
 | |
|   *            @arg @ref RCC_MCO2DIV_64   division by 64 applied to MCO2 clock(*)
 | |
|   *            @arg @ref RCC_MCO2DIV_128  division by 128 applied to MCO2 clock(*)
 | |
|   *            @arg @ref RCC_MCO2DIV_256  division by 256 applied to MCO2 clock(*)
 | |
|   *            @arg @ref RCC_MCO2DIV_512  division by 512 applied to MCO2 clock(*)
 | |
|   *            @arg @ref RCC_MCO2DIV_1024 division by 1024 applied to MCO2 clock(*)
 | |
|   *
 | |
|   * (*) Feature not available on all devices of the family
 | |
|   * @retval None
 | |
|   */
 | |
| void HAL_RCC_MCOConfig(uint32_t RCC_MCOx, uint32_t RCC_MCOSource, uint32_t RCC_MCODiv)
 | |
| {
 | |
|   GPIO_InitTypeDef gpio_initstruct;
 | |
|   uint32_t mcoindex;
 | |
|   uint32_t mco_gpio_index;
 | |
|   GPIO_TypeDef * mco_gpio_port;
 | |
| 
 | |
|   /* Check the parameters */
 | |
|   assert_param(IS_RCC_MCO(RCC_MCOx));
 | |
| 
 | |
|   /* Common GPIO init parameters */
 | |
|   gpio_initstruct.Mode      = GPIO_MODE_AF_PP;
 | |
|   gpio_initstruct.Speed     = GPIO_SPEED_FREQ_VERY_HIGH;
 | |
|   gpio_initstruct.Pull      = GPIO_NOPULL;
 | |
| 
 | |
|   /* Get MCOx selection */
 | |
|   mcoindex = RCC_MCOx & RCC_MCO_INDEX_MASK;
 | |
| 
 | |
|   /* Get MCOx GPIO Port */
 | |
|   mco_gpio_port = (GPIO_TypeDef *) RCC_GET_MCO_GPIO_PORT(RCC_MCOx);
 | |
| 
 | |
|   /* MCOx Clock Enable */
 | |
|   mco_gpio_index = RCC_GET_MCO_GPIO_INDEX(RCC_MCOx);
 | |
|   SET_BIT(RCC->IOPENR, (1UL << mco_gpio_index ));
 | |
| 
 | |
|   /* Configure the MCOx pin in alternate function mode */
 | |
|   gpio_initstruct.Pin = RCC_GET_MCO_GPIO_PIN(RCC_MCOx);
 | |
|   gpio_initstruct.Alternate = RCC_GET_MCO_GPIO_AF(RCC_MCOx);
 | |
|   HAL_GPIO_Init(mco_gpio_port, &gpio_initstruct);
 | |
| 
 | |
|   if (mcoindex == RCC_MCO1_INDEX)
 | |
|   {
 | |
|     assert_param(IS_RCC_MCODIV(RCC_MCODiv));
 | |
|     assert_param(IS_RCC_MCO1SOURCE(RCC_MCOSource));
 | |
|     /* Mask MCOSEL[] and MCOPRE[] bits then set MCO clock source and prescaler */
 | |
|     MODIFY_REG(RCC->CFGR, (RCC_CFGR_MCOSEL | RCC_CFGR_MCOPRE), (RCC_MCOSource | RCC_MCODiv));
 | |
|   }
 | |
| #if defined(RCC_MCO2_SUPPORT)
 | |
|   else if (mcoindex == RCC_MCO2_INDEX)
 | |
|   {
 | |
|     assert_param(IS_RCC_MCO2DIV(RCC_MCODiv));
 | |
|     assert_param(IS_RCC_MCO2SOURCE(RCC_MCOSource));
 | |
|     /* Mask MCOSEL[] and MCOPRE[] bits then set MCO clock source and prescaler */
 | |
|     MODIFY_REG(RCC->CFGR, (RCC_CFGR_MCO2SEL | RCC_CFGR_MCO2PRE), (RCC_MCOSource | RCC_MCODiv));
 | |
|   }
 | |
| #endif /* RCC_MCO2_SUPPORT */
 | |
|   else
 | |
|   {
 | |
|     /* Nothing to do */
 | |
|   }
 | |
| }
 | |
| 
 | |
| /**
 | |
|   * @brief  Return the SYSCLK frequency.
 | |
|   *
 | |
|   * @note   The system frequency computed by this function is not the real
 | |
|   *         frequency in the chip. It is calculated based on the predefined
 | |
|   *         constant and the selected clock source:
 | |
|   * @note     If SYSCLK source is HSI, function returns values based on HSI_VALUE/HSIDIV(*)
 | |
|   * @note     If SYSCLK source is HSE, function returns values based on HSE_VALUE(**)
 | |
|   * @note     If SYSCLK source is PLL, function returns values based on HSE_VALUE(**),
 | |
|   *           or HSI_VALUE(*) multiplied/divided by the PLL factors.
 | |
|   * @note     If SYSCLK source is LSI, function returns values based on LSI_VALUE(***)
 | |
|   * @note     If SYSCLK source is LSE, function returns values based on LSE_VALUE(****)
 | |
|   * @note     (*) HSI_VALUE is a constant defined in stm32g0xx_hal_conf.h file (default value
 | |
|   *               16 MHz) but the real value may vary depending on the variations
 | |
|   *               in voltage and temperature.
 | |
|   * @note     (**) HSE_VALUE is a constant defined in stm32g0xx_hal_conf.h file (default value
 | |
|   *                8 MHz), user has to ensure that HSE_VALUE is same as the real
 | |
|   *                frequency of the crystal used. Otherwise, this function may
 | |
|   *                have wrong result.
 | |
|   * @note     (***) LSE_VALUE is a constant defined in stm32g0xx_hal_conf.h file (default value
 | |
|   *               32768 Hz).
 | |
|   * @note     (****) LSI_VALUE is a constant defined in stm32g0xx_hal_conf.h file (default value
 | |
|   *               32000 Hz).
 | |
|   *
 | |
|   * @note   The result of this function could be not correct when using fractional
 | |
|   *         value for HSE crystal.
 | |
|   *
 | |
|   * @note   This function can be used by the user application to compute the
 | |
|   *         baudrate for the communication peripherals or configure other parameters.
 | |
|   *
 | |
|   * @note   Each time SYSCLK changes, this function must be called to update the
 | |
|   *         right SYSCLK value. Otherwise, any configuration based on this function will be incorrect.
 | |
|   *
 | |
|   *
 | |
|   * @retval SYSCLK frequency
 | |
|   */
 | |
| uint32_t HAL_RCC_GetSysClockFreq(void)
 | |
| {
 | |
|   uint32_t pllvco, pllsource, pllr, pllm, hsidiv;
 | |
|   uint32_t sysclockfreq;
 | |
| 
 | |
|   if (__HAL_RCC_GET_SYSCLK_SOURCE() == RCC_SYSCLKSOURCE_STATUS_HSI)
 | |
|   {
 | |
|     /* HSISYS can be derived for HSI16 */
 | |
|     hsidiv = (1UL << ((READ_BIT(RCC->CR, RCC_CR_HSIDIV)) >> RCC_CR_HSIDIV_Pos));
 | |
| 
 | |
|     /* HSI used as system clock source */
 | |
|     sysclockfreq = (HSI_VALUE / hsidiv);
 | |
|   }
 | |
|   else if (__HAL_RCC_GET_SYSCLK_SOURCE() == RCC_SYSCLKSOURCE_STATUS_HSE)
 | |
|   {
 | |
|     /* HSE used as system clock source */
 | |
|     sysclockfreq = HSE_VALUE;
 | |
|   }
 | |
|   else if (__HAL_RCC_GET_SYSCLK_SOURCE() == RCC_SYSCLKSOURCE_STATUS_PLLCLK)
 | |
|   {
 | |
|     /* PLL used as system clock  source */
 | |
| 
 | |
|     /* PLL_VCO = ((HSE_VALUE or HSI_VALUE)/ PLLM) * PLLN
 | |
|     SYSCLK = PLL_VCO / PLLR
 | |
|     */
 | |
|     pllsource = (RCC->PLLCFGR & RCC_PLLCFGR_PLLSRC);
 | |
|     pllm = ((RCC->PLLCFGR & RCC_PLLCFGR_PLLM) >> RCC_PLLCFGR_PLLM_Pos) + 1U ;
 | |
| 
 | |
|     switch (pllsource)
 | |
|     {
 | |
|       case RCC_PLLSOURCE_HSE:  /* HSE used as PLL clock source */
 | |
|         pllvco = (HSE_VALUE / pllm) * ((RCC->PLLCFGR & RCC_PLLCFGR_PLLN) >> RCC_PLLCFGR_PLLN_Pos);
 | |
|         break;
 | |
| 
 | |
|       case RCC_PLLSOURCE_HSI:  /* HSI16 used as PLL clock source */
 | |
|       default:                 /* HSI16 used as PLL clock source */
 | |
|         pllvco = (HSI_VALUE / pllm) * ((RCC->PLLCFGR & RCC_PLLCFGR_PLLN) >> RCC_PLLCFGR_PLLN_Pos) ;
 | |
|         break;
 | |
|     }
 | |
|     pllr = (((RCC->PLLCFGR & RCC_PLLCFGR_PLLR) >> RCC_PLLCFGR_PLLR_Pos) + 1U);
 | |
|     sysclockfreq = pllvco / pllr;
 | |
|   }
 | |
|   else if (__HAL_RCC_GET_SYSCLK_SOURCE() == RCC_SYSCLKSOURCE_STATUS_LSE)
 | |
|   {
 | |
|     /* LSE used as system clock source */
 | |
|     sysclockfreq = LSE_VALUE;
 | |
|   }
 | |
|   else if (__HAL_RCC_GET_SYSCLK_SOURCE() == RCC_SYSCLKSOURCE_STATUS_LSI)
 | |
|   {
 | |
|     /* LSI used as system clock source */
 | |
|     sysclockfreq = LSI_VALUE;
 | |
|   }
 | |
|   else
 | |
|   {
 | |
|     sysclockfreq = 0U;
 | |
|   }
 | |
| 
 | |
|   return sysclockfreq;
 | |
| }
 | |
| 
 | |
| /**
 | |
|   * @brief  Return the HCLK frequency.
 | |
|   * @note   Each time HCLK changes, this function must be called to update the
 | |
|   *         right HCLK value. Otherwise, any configuration based on this function will be incorrect.
 | |
|   *
 | |
|   * @note   The SystemCoreClock CMSIS variable is used to store System Clock Frequency.
 | |
|   * @retval HCLK frequency in Hz
 | |
|   */
 | |
| uint32_t HAL_RCC_GetHCLKFreq(void)
 | |
| {
 | |
|   return SystemCoreClock;
 | |
| }
 | |
| 
 | |
| /**
 | |
|   * @brief  Return the PCLK1 frequency.
 | |
|   * @note   Each time PCLK1 changes, this function must be called to update the
 | |
|   *         right PCLK1 value. Otherwise, any configuration based on this function will be incorrect.
 | |
|   * @retval PCLK1 frequency in Hz
 | |
|   */
 | |
| uint32_t HAL_RCC_GetPCLK1Freq(void)
 | |
| {
 | |
|   /* Get HCLK source and Compute PCLK1 frequency ---------------------------*/
 | |
|   return ((uint32_t)(__LL_RCC_CALC_PCLK1_FREQ(HAL_RCC_GetHCLKFreq(), LL_RCC_GetAPB1Prescaler())));
 | |
| }
 | |
| 
 | |
| /**
 | |
|   * @brief  Configure the RCC_OscInitStruct according to the internal
 | |
|   *         RCC configuration registers.
 | |
|   * @param  RCC_OscInitStruct  pointer to an RCC_OscInitTypeDef structure that
 | |
|   *         will be configured.
 | |
|   * @retval None
 | |
|   */
 | |
| void HAL_RCC_GetOscConfig(RCC_OscInitTypeDef  *RCC_OscInitStruct)
 | |
| {
 | |
|   /* Check the parameters */
 | |
|   assert_param(RCC_OscInitStruct != (void *)NULL);
 | |
| 
 | |
|   /* Set all possible values for the Oscillator type parameter ---------------*/
 | |
| #if defined(RCC_HSI48_SUPPORT)
 | |
|   RCC_OscInitStruct->OscillatorType = RCC_OSCILLATORTYPE_HSE | RCC_OSCILLATORTYPE_HSI | \
 | |
|                                       RCC_OSCILLATORTYPE_LSE | RCC_OSCILLATORTYPE_LSI | RCC_OSCILLATORTYPE_HSI48;
 | |
| #else
 | |
|   RCC_OscInitStruct->OscillatorType = RCC_OSCILLATORTYPE_HSE | RCC_OSCILLATORTYPE_HSI | \
 | |
|                                       RCC_OSCILLATORTYPE_LSE | RCC_OSCILLATORTYPE_LSI;
 | |
| #endif /* RCC_HSI48_SUPPORT */
 | |
| 
 | |
|   /* Get the HSE configuration -----------------------------------------------*/
 | |
|   if ((RCC->CR & RCC_CR_HSEBYP) == RCC_CR_HSEBYP)
 | |
|   {
 | |
|     RCC_OscInitStruct->HSEState = RCC_HSE_BYPASS;
 | |
|   }
 | |
|   else if ((RCC->CR & RCC_CR_HSEON) == RCC_CR_HSEON)
 | |
|   {
 | |
|     RCC_OscInitStruct->HSEState = RCC_HSE_ON;
 | |
|   }
 | |
|   else
 | |
|   {
 | |
|     RCC_OscInitStruct->HSEState = RCC_HSE_OFF;
 | |
|   }
 | |
| 
 | |
|   /* Get the HSI configuration -----------------------------------------------*/
 | |
|   if ((RCC->CR & RCC_CR_HSION) == RCC_CR_HSION)
 | |
|   {
 | |
|     RCC_OscInitStruct->HSIState = RCC_HSI_ON;
 | |
|   }
 | |
|   else
 | |
|   {
 | |
|     RCC_OscInitStruct->HSIState = RCC_HSI_OFF;
 | |
|   }
 | |
|   RCC_OscInitStruct->HSICalibrationValue = ((RCC->ICSCR & RCC_ICSCR_HSITRIM) >> RCC_ICSCR_HSITRIM_Pos);
 | |
|   RCC_OscInitStruct->HSIDiv = (RCC->CR & RCC_CR_HSIDIV);
 | |
| 
 | |
|   /* Get the LSE configuration -----------------------------------------------*/
 | |
|   if ((RCC->BDCR & RCC_BDCR_LSEBYP) == RCC_BDCR_LSEBYP)
 | |
|   {
 | |
|     RCC_OscInitStruct->LSEState = RCC_LSE_BYPASS;
 | |
|   }
 | |
|   else if ((RCC->BDCR & RCC_BDCR_LSEON) == RCC_BDCR_LSEON)
 | |
|   {
 | |
|     RCC_OscInitStruct->LSEState = RCC_LSE_ON;
 | |
|   }
 | |
|   else
 | |
|   {
 | |
|     RCC_OscInitStruct->LSEState = RCC_LSE_OFF;
 | |
|   }
 | |
| 
 | |
|   /* Get the LSI configuration -----------------------------------------------*/
 | |
|   if ((RCC->CSR & RCC_CSR_LSION) == RCC_CSR_LSION)
 | |
|   {
 | |
|     RCC_OscInitStruct->LSIState = RCC_LSI_ON;
 | |
|   }
 | |
|   else
 | |
|   {
 | |
|     RCC_OscInitStruct->LSIState = RCC_LSI_OFF;
 | |
|   }
 | |
| 
 | |
| #if defined(RCC_HSI48_SUPPORT)
 | |
|   /* Get the HSI48 configuration ---------------------------------------------*/
 | |
|   if (READ_BIT(RCC->CR, RCC_CR_HSI48ON) == RCC_CR_HSI48ON)
 | |
|   {
 | |
|     RCC_OscInitStruct->HSI48State = RCC_HSI48_ON;
 | |
|   }
 | |
|   else
 | |
|   {
 | |
|     RCC_OscInitStruct->HSI48State = RCC_HSI48_OFF;
 | |
|   }
 | |
| #endif /* RCC_HSI48_SUPPORT */
 | |
| 
 | |
|   /* Get the PLL configuration -----------------------------------------------*/
 | |
|   if ((RCC->CR & RCC_CR_PLLON) == RCC_CR_PLLON)
 | |
|   {
 | |
|     RCC_OscInitStruct->PLL.PLLState = RCC_PLL_ON;
 | |
|   }
 | |
|   else
 | |
|   {
 | |
|     RCC_OscInitStruct->PLL.PLLState = RCC_PLL_OFF;
 | |
|   }
 | |
|   RCC_OscInitStruct->PLL.PLLSource = (RCC->PLLCFGR & RCC_PLLCFGR_PLLSRC);
 | |
|   RCC_OscInitStruct->PLL.PLLM = (RCC->PLLCFGR & RCC_PLLCFGR_PLLM);
 | |
|   RCC_OscInitStruct->PLL.PLLN = ((RCC->PLLCFGR & RCC_PLLCFGR_PLLN) >> RCC_PLLCFGR_PLLN_Pos);
 | |
|   RCC_OscInitStruct->PLL.PLLP = (RCC->PLLCFGR & RCC_PLLCFGR_PLLP);
 | |
| #if defined(RCC_PLLQ_SUPPORT)
 | |
|   RCC_OscInitStruct->PLL.PLLQ = (RCC->PLLCFGR & RCC_PLLCFGR_PLLQ);
 | |
| #endif /* RCC_PLLQ_SUPPORT */
 | |
|   RCC_OscInitStruct->PLL.PLLR = (RCC->PLLCFGR & RCC_PLLCFGR_PLLR);
 | |
| }
 | |
| 
 | |
| /**
 | |
|   * @brief  Configure the RCC_ClkInitStruct according to the internal
 | |
|   *         RCC configuration registers.
 | |
|   * @param  RCC_ClkInitStruct Pointer to a @ref RCC_ClkInitTypeDef structure that
 | |
|   *                           will be configured.
 | |
|   * @param  pFLatency         Pointer on the Flash Latency.
 | |
|   * @retval None
 | |
|   */
 | |
| void HAL_RCC_GetClockConfig(RCC_ClkInitTypeDef  *RCC_ClkInitStruct, uint32_t *pFLatency)
 | |
| {
 | |
|   /* Check the parameters */
 | |
|   assert_param(RCC_ClkInitStruct != (void *)NULL);
 | |
|   assert_param(pFLatency != (void *)NULL);
 | |
| 
 | |
|   /* Set all possible values for the Clock type parameter --------------------*/
 | |
|   RCC_ClkInitStruct->ClockType = RCC_CLOCKTYPE_SYSCLK | RCC_CLOCKTYPE_HCLK | RCC_CLOCKTYPE_PCLK1;
 | |
| 
 | |
|   /* Get the SYSCLK configuration --------------------------------------------*/
 | |
|   RCC_ClkInitStruct->SYSCLKSource = (uint32_t)(RCC->CFGR & RCC_CFGR_SW);
 | |
| 
 | |
|   /* Get the HCLK configuration ----------------------------------------------*/
 | |
|   RCC_ClkInitStruct->AHBCLKDivider = (uint32_t)(RCC->CFGR & RCC_CFGR_HPRE);
 | |
| 
 | |
|   /* Get the APB1 configuration ----------------------------------------------*/
 | |
|   RCC_ClkInitStruct->APB1CLKDivider = (uint32_t)(RCC->CFGR & RCC_CFGR_PPRE);
 | |
| 
 | |
| 
 | |
|   /* Get the Flash Wait State (Latency) configuration ------------------------*/
 | |
|   *pFLatency = (uint32_t)(FLASH->ACR & FLASH_ACR_LATENCY);
 | |
| }
 | |
| 
 | |
| /**
 | |
|   * @brief  Enable the Clock Security System.
 | |
|   * @note   If a failure is detected on the HSE oscillator clock, this oscillator
 | |
|   *         is automatically disabled and an interrupt is generated to inform the
 | |
|   *         software about the failure (Clock Security System Interrupt, CSSI),
 | |
|   *         allowing the MCU to perform rescue operations. The CSSI is linked to
 | |
|   *         the Cortex-M0+ NMI (Non-Maskable Interrupt) exception vector.
 | |
|   * @note   The Clock Security System can only be cleared by reset.
 | |
|   * @retval None
 | |
|   */
 | |
| void HAL_RCC_EnableCSS(void)
 | |
| {
 | |
|   SET_BIT(RCC->CR, RCC_CR_CSSON) ;
 | |
| }
 | |
| 
 | |
| /**
 | |
|   * @brief  Enable the LSE Clock Security System.
 | |
|   * @note   If a failure is detected on the LSE oscillator clock, this oscillator
 | |
|   *         is automatically disabled and an interrupt is generated to inform the
 | |
|   *         software about the failure (Clock Security System Interrupt, CSSI),
 | |
|   *         allowing the MCU to perform rescue operations. The CSSI is linked to
 | |
|   *         the Cortex-M0+ NMI (Non-Maskable Interrupt) exception vector.
 | |
|   * @note   The LSE Clock Security System Detection bit (LSECSSD in BDCR) can only be
 | |
|   *         cleared by a backup domain reset.
 | |
|   * @retval None
 | |
|   */
 | |
| void HAL_RCC_EnableLSECSS(void)
 | |
| {
 | |
|   SET_BIT(RCC->BDCR, RCC_BDCR_LSECSSON) ;
 | |
| }
 | |
| 
 | |
| /**
 | |
|   * @brief  Disable the LSE Clock Security System.
 | |
|   * @note   After LSE failure detection, the software must disable LSECSSON
 | |
|   * @note   The Clock Security System can only be cleared by reset otherwise.
 | |
|   * @retval None
 | |
|   */
 | |
| void HAL_RCC_DisableLSECSS(void)
 | |
| {
 | |
|   CLEAR_BIT(RCC->BDCR, RCC_BDCR_LSECSSON) ;
 | |
| }
 | |
| 
 | |
| /**
 | |
|   * @brief Handle the RCC Clock Security System interrupt request.
 | |
|   * @note  This API should be called under the NMI_Handler().
 | |
|   * @retval None
 | |
|   */
 | |
| void HAL_RCC_NMI_IRQHandler(void)
 | |
| {
 | |
|   uint32_t itflag = RCC->CIFR;
 | |
| 
 | |
|   /* Clear interrupt flags related to CSS */
 | |
|   RCC->CICR = (itflag & (RCC_CIFR_CSSF | RCC_CIFR_LSECSSF));
 | |
| 
 | |
|   /* Check RCC CSSF interrupt flag  */
 | |
|   if ((itflag & RCC_CIFR_CSSF) != 0x00u)
 | |
|   {
 | |
|     /* RCC Clock Security System interrupt user callback */
 | |
|     HAL_RCC_CSSCallback();
 | |
|   }
 | |
| 
 | |
|   /* Check RCC LSECSSF interrupt flag  */
 | |
|   if ((itflag & RCC_CIFR_LSECSSF) != 0x00u)
 | |
|   {
 | |
|     /* RCC Clock Security System interrupt user callback */
 | |
|     HAL_RCC_LSECSSCallback();
 | |
|   }
 | |
| }
 | |
| 
 | |
| /**
 | |
|   * @brief Handle the RCC HSE Clock Security System interrupt callback.
 | |
|   * @retval none
 | |
|   */
 | |
| __weak void HAL_RCC_CSSCallback(void)
 | |
| {
 | |
|   /* NOTE : This function should not be modified, when the callback is needed,
 | |
|             the @ref HAL_RCC_CSSCallback should be implemented in the user file
 | |
|    */
 | |
| }
 | |
| 
 | |
| /**
 | |
|   * @brief  RCC LSE Clock Security System interrupt callback.
 | |
|   * @retval none
 | |
|   */
 | |
| __weak void HAL_RCC_LSECSSCallback(void)
 | |
| {
 | |
|   /* NOTE : This function should not be modified, when the callback is needed,
 | |
|             the HAL_RCC_LSECSSCallback should be implemented in the user file
 | |
|    */
 | |
| }
 | |
| 
 | |
| /**
 | |
|   * @brief  Get and clear reset flags
 | |
|   * @note   Once reset flags are retrieved, this API is clearing them in order
 | |
|   *         to isolate next reset reason.
 | |
|   * @retval can be a combination of @ref RCC_Reset_Flag
 | |
|   */
 | |
| uint32_t HAL_RCC_GetResetSource(void)
 | |
| {
 | |
|   uint32_t reset;
 | |
| 
 | |
|   /* Get all reset flags */
 | |
|   reset = RCC->CSR & RCC_RESET_FLAG_ALL;
 | |
| 
 | |
|   /* Clear Reset flags */
 | |
|   RCC->CSR |= RCC_CSR_RMVF;
 | |
| 
 | |
|   return reset;
 | |
| }
 | |
| 
 | |
| /**
 | |
|   * @}
 | |
|   */
 | |
| 
 | |
| /**
 | |
|   * @}
 | |
|   */
 | |
| 
 | |
| #endif /* HAL_RCC_MODULE_ENABLED */
 | |
| /**
 | |
|   * @}
 | |
|   */
 | |
| 
 | |
| /**
 | |
|   * @}
 | |
|   */
 | |
| 
 |