diff options
| author | Anson Bridges <bridges.anson@gmail.com> | 2026-02-17 11:37:50 -0800 |
|---|---|---|
| committer | Anson Bridges <bridges.anson@gmail.com> | 2026-02-17 11:37:50 -0800 |
| commit | fb1611c0ca99d9e609057c46507be2af8389bb7b (patch) | |
| tree | 646ac568fdad1e6cf9e1f5767295b183bc5c5441 /firmware/rf test/Drivers/STM32WBxx_HAL_Driver/Src/stm32wbxx_hal_rcc.c | |
| parent | 6e952fe110c2a48204c8cb0a836309ab97e5979a (diff) | |
Diffstat (limited to 'firmware/rf test/Drivers/STM32WBxx_HAL_Driver/Src/stm32wbxx_hal_rcc.c')
| -rw-r--r-- | firmware/rf test/Drivers/STM32WBxx_HAL_Driver/Src/stm32wbxx_hal_rcc.c | 1824 |
1 files changed, 1824 insertions, 0 deletions
diff --git a/firmware/rf test/Drivers/STM32WBxx_HAL_Driver/Src/stm32wbxx_hal_rcc.c b/firmware/rf test/Drivers/STM32WBxx_HAL_Driver/Src/stm32wbxx_hal_rcc.c new file mode 100644 index 0000000..d2c2f5d --- /dev/null +++ b/firmware/rf test/Drivers/STM32WBxx_HAL_Driver/Src/stm32wbxx_hal_rcc.c @@ -0,0 +1,1824 @@ +/** + ****************************************************************************** + * @file stm32wbxx_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 + ****************************************************************************** + * @attention + * + * Copyright (c) 2019 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. + * + ****************************************************************************** + @verbatim + ============================================================================== + ##### RCC specific features ##### + ============================================================================== + [..] + After reset the device is running from Multiple Speed Internal oscillator + (4 MHz) 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 (AHBs) and Low speed (APBs) buses: + all peripherals mapped on these buses are running at MSI 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 (SAI1, RTC, ADC, USB/RNG, USART1, LPUART1, LPTIMx, I2Cx, SMPS) + + @endverbatim + ****************************************************************************** + */ + +/* Includes ------------------------------------------------------------------*/ +#include "stm32wbxx_hal.h" + +/** @addtogroup STM32WBxx_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 MSI_TIMEOUT_VALUE (2U) /* 2 ms (minimum Tick + 1) */ +#define LSI1_TIMEOUT_VALUE (2U) /* 2 ms (minimum Tick + 1) */ +#define LSI2_TIMEOUT_VALUE (3U) /* to be adjusted with DS */ +#define HSI48_TIMEOUT_VALUE (2U) /* 2 ms (minimum Tick + 1) */ +#define PLL_TIMEOUT_VALUE (2U) /* 2 ms (minimum Tick + 1) */ +#if defined(SAI1) +#define PLLSAI1_TIMEOUT_VALUE (2U) /* 2 ms (minimum Tick + 1) */ +#endif /* SAI1 */ +#define PRESCALER_TIMEOUT_VALUE (2U) /* 2 ms (minimum Tick + 1) */ +#define LATENCY_TIMEOUT_VALUE (2U) /* 2 ms (minimum Tick + 1) */ +#define CLOCKSWITCH_TIMEOUT_VALUE (5000U) /* 5 s */ + +#define PLLSOURCE_NONE (0U) +#define MEGA_HZ (1000000U) /* Division factor to convert Hz in Mhz */ +/** + * @} + */ + +/* 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__))) + +#define __COUNTOF(_A_) (sizeof(_A_) / sizeof(*(_A_))) +/** + * @} + */ + +/* Private variables ---------------------------------------------------------*/ +/** @defgroup RCC_Private_Variables RCC Private Variables + * @{ + */ + + +/** + * @} + */ + +/* Private function prototypes -----------------------------------------------*/ +/** @defgroup RCC_Private_Functions RCC Private Functions + * @{ + */ +static HAL_StatusTypeDef RCC_SetFlashLatencyFromMSIRange(uint32_t MSI_Range); +static HAL_StatusTypeDef RCC_SetFlashLatency(uint32_t Flash_ClkSrcFreq, uint32_t VCORE_Voltage); +/** + * @} + */ + +/* 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, MSI, LSI1, LSI2, PLL, CSS and MCO) and the System buses clocks (SYSCLK, HCLK1, HCLK2, HCLK4, PCLK1 + and PCLK2). + + [..] 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. + + (+) MSI (Multiple Speed Internal): Its frequency is software trimmable from 100KHZ to 48MHZ. + It can be used to generate the clock for the USB FS (48 MHz). + The number of flash wait states is automatically adjusted when MSI range is updated with + HAL_RCC_OscConfig() and the MSI is used as System clock source. + + (+) LSI1/LSI2 (low-speed internal): 32 KHz low consumption RC used as IWDG and/or RTC + clock source. + + (+) HSE (high-speed external): 32 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 + or the RF system Auto-wakeup from Stop and Standby modes. + + (+) PLL (clocked by HSI, HSE or MSI) providing up to three independent output clocks: + (++) The first output is used to generate the high speed system clock (up to 64MHz). + (++) The second output is used to generate the clock for the USB FS (48 MHz), + the random analog generator (<=48 MHz) + (++) The third output is used to generate an accurate clock to achieve + high-quality audio performance on SAI interface. + + (+) PLLSAI1 (clocked by HSI, HSE or MSI) providing up to three independent output clocks: + (++) The first output is used to generate SAR ADC clock. + (++) The second output is used to generate the clock for the USB FS (48 MHz), + the random analog generator (<=48 MHz). + (++) The Third output is used to generate an accurate clock to achieve + high-quality audio performance on SAI interface. + + + (+) CSS (Clock security system): once enabled, if a HSE clock failure occurs + (HSE used directly or through PLL as System clock source), the System clock + is automatically switched to MSI or the HSI oscillator (depending on the + STOPWUCK configuration) and an interrupt is generated if enabled. + The interrupt is linked to the CPU1 and CPU2 NMI (Non-Maskable Interrupt) exception vector. + + (+) LSECSS: once enabled, if a LSE clock failure occurs, the LSE + clock is no longer supplied to the RTC but no hardware action is made to the registers. If the + MSI was in PLL-mode, this mode is disabled. + In Standby mode a wakeup is generated. In other modes an interrupt can be sent to wakeup + the software + + (+) MCO (microcontroller clock output): used to output MSI, LSI1, LSI2, HSI, LSE, HSE (before and + after stabilization), SYSCLK, HSI48 or main PLL clock (through a configurable prescaler) + on PA8, PB6 & PA15 pins. + + [..] System, AHB and APB buses clocks configuration + (+) Several clock sources can be used to drive the System clock (SYSCLK): MSI, HSI, + HSE and main PLL. + The AHB clock (HCLK1) is derived from System clock through configurable + prescaler and used to clock the CPU, memory and peripherals mapped + on AHB bus (DMA, GPIO...). APB1 (PCLK1) and APB2 (PCLK2) clocks are 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. + The AHB4 clock (HCLK4) is derived from System clock through configurable + prescaler and used to clock the FLASH + + -@- All the peripheral clocks are derived from the System clock (SYSCLK) except: + + (+@) SAI: the SAI clock can be derived either from a specific PLL (PLLSAI1) or (PLLSYS) or + from an external clock mapped on the SAI_CKIN pin. + You have to use HAL_RCCEx_PeriphCLKConfig() function to configure this clock. + (+@) RTC: the RTC clock can be derived either from the LSI, LSE or HSE clock + divided by 32. + You have to use __HAL_RCC_RTC_ENABLE() and HAL_RCCEx_PeriphCLKConfig() function + to configure this clock. + (+@) USB FS and RNG: USB FS requires a frequency equal to 48 MHz + to work correctly, while RNG peripherals requires a frequency + equal or lower than to 48 MHz. This clock is derived of the main PLL or PLLSAI1 + through PLLQ divider. You have to enable the peripheral clock and use + HAL_RCCEx_PeriphCLKConfig() function to configure this clock. + (+@) IWDG clock which is always the LSI clock. + + + (+) The maximum frequency of the SYSCLK, HCLK1, HCLK4, PCLK1 and PCLK2 is 64 MHz. + The maximum frequency of the HCLK2 is 32 MHz. + The clock source frequency should be adapted depending on the device voltage range + as listed in the Reference Manual "Clock source frequency versus voltage scaling" chapter. + + @endverbatim + + Table 1. HCLK4 clock frequency. + +-------------------------------------------------------+ + | Latency | HCLK4 clock frequency (MHz) | + | |-------------------------------------| + | | voltage range 1 | voltage range 2 | + | | 1.2 V | 1.0 V | + |-----------------|------------------|------------------| + |0WS(1 CPU cycles)| HCLK4 <= 18 | HCLK4 <= 6 | + |-----------------|------------------|------------------| + |1WS(2 CPU cycles)| HCLK4 <= 36 | HCLK4 <= 12 | + |-----------------|------------------|------------------| + |2WS(3 CPU cycles)| HCLK4 <= 54 | HCLK4 <= 16 | + |-----------------|------------------|------------------| + |3WS(4 CPU cycles)| HCLK4 <= 64 | HCLK4 <= n.a. | + |-----------------|------------------|------------------| + + * @{ + */ + +/** + * @brief Reset the RCC clock configuration to the default reset state. + * @note The default reset state of the clock configuration is given below: + * - MSI ON and used as system clock source + * - HSE, HSI, PLL, PLLSAI1 + * - HCLK1, HCLK2, HCLK4, PCLK1 and PCLK2 prescalers set to 1. + * - CSS, MCO OFF + * - All interrupts disabled + * @note This function doesn't 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(); + + /* MSI PLL OFF */ + LL_RCC_MSI_DisablePLLMode(); + + /* Set MSION bit */ + LL_RCC_MSI_Enable(); + + /* Wait till MSI is ready */ + while (LL_RCC_MSI_IsReady() == 0U) + { + if ((HAL_GetTick() - tickstart) > MSI_TIMEOUT_VALUE) + { + return HAL_TIMEOUT; + } + } + + /* Set MSIRANGE default value */ + LL_RCC_MSI_SetRange(LL_RCC_MSIRANGE_6); + + /* Set MSITRIM bits to the reset value*/ + LL_RCC_MSI_SetCalibTrimming(0); + + /* Set HSITRIM bits to the reset value*/ + LL_RCC_HSI_SetCalibTrimming(0x40U); + + /* Get Start Tick*/ + tickstart = HAL_GetTick(); + + /* Reset CFGR register (MSI is selected as system clock source) */ + CLEAR_REG(RCC->CFGR); + + /* Wait till MSI is ready */ + while (READ_BIT(RCC->CFGR, RCC_CFGR_SWS) != 0U) + { + if ((HAL_GetTick() - tickstart) > CLOCKSWITCH_TIMEOUT_VALUE) + { + return HAL_TIMEOUT; + } + } + + /* Reset HSION, HSIKERON, HSIASFS, HSEON, PLLON, PLLSAI11ON, HSEPRE bits */ +#if defined(SAI1) + CLEAR_BIT(RCC->CR, RCC_CR_HSION | RCC_CR_HSIKERON | RCC_CR_HSIASFS | RCC_CR_HSEON | RCC_CR_HSEPRE | RCC_CR_PLLON | + RCC_CR_PLLSAI1ON); +#else + CLEAR_BIT(RCC->CR, RCC_CR_HSION | RCC_CR_HSIKERON | RCC_CR_HSIASFS | RCC_CR_HSEON | RCC_CR_HSEPRE | RCC_CR_PLLON); +#endif /* SAI1 */ + + /* Get Start Tick*/ + tickstart = HAL_GetTick(); + + /* Wait till PLL is ready */ + while (LL_RCC_PLL_IsReady() != 0U) + { + if ((HAL_GetTick() - tickstart) > PLL_TIMEOUT_VALUE) + { + return HAL_TIMEOUT; + } + } + + /* once PLL is OFF, reset PLLCFGR register to default value */ + WRITE_REG(RCC->PLLCFGR, RCC_PLLCFGR_PLLR_0 | RCC_PLLCFGR_PLLQ_0 | RCC_PLLCFGR_PLLP_1 | RCC_PLLCFGR_PLLN_0); + +#if defined(SAI1) + /* Get Start Tick*/ + tickstart = HAL_GetTick(); + + /* Wait till PLL is ready */ + while (LL_RCC_PLLSAI1_IsReady() != 0U) + { + if ((HAL_GetTick() - tickstart) > PLLSAI1_TIMEOUT_VALUE) + { + return HAL_TIMEOUT; + } + } + /* once PLLSAI1 is OFF, reset PLLSAI1CFGR register to default value */ + WRITE_REG(RCC->PLLSAI1CFGR, RCC_PLLSAI1CFGR_PLLR_0 | RCC_PLLSAI1CFGR_PLLQ_0 | + RCC_PLLSAI1CFGR_PLLP_1 | RCC_PLLSAI1CFGR_PLLN_0); +#endif /* SAI1 */ + + /* Disable all interrupts */ + CLEAR_REG(RCC->CIER); + + /* Clear all interrupt flags */ + WRITE_REG(RCC->CICR, 0xFFFFFFFFU); + + /* EXTCFGR reset*/ + LL_RCC_WriteReg(EXTCFGR, 0x00030000U); + + /* Update the SystemCoreClock global variable */ + SystemCoreClock = MSI_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 The PLL source is not updated when used as PLLSAI1 clock source. + * @retval HAL status + */ +HAL_StatusTypeDef HAL_RCC_OscConfig(RCC_OscInitTypeDef *RCC_OscInitStruct) +{ + uint32_t tickstart; + + /* Check Null pointer */ + if (RCC_OscInitStruct == NULL) + { + return HAL_ERROR; + } + + /* Check the parameters */ + assert_param(IS_RCC_OSCILLATORTYPE(RCC_OscInitStruct->OscillatorType)); + + /*----------------------------- MSI Configuration --------------------------*/ + if (((RCC_OscInitStruct->OscillatorType) & RCC_OSCILLATORTYPE_MSI) == RCC_OSCILLATORTYPE_MSI) + { + /* Check the parameters */ + assert_param(IS_RCC_MSI(RCC_OscInitStruct->MSIState)); + assert_param(IS_RCC_MSICALIBRATION_VALUE(RCC_OscInitStruct->MSICalibrationValue)); + assert_param(IS_RCC_MSI_CLOCK_RANGE(RCC_OscInitStruct->MSIClockRange)); + + /* When the MSI is used as system clock it will not be disabled */ + const uint32_t temp_sysclksrc = __HAL_RCC_GET_SYSCLK_SOURCE(); + const uint32_t temp_plloscsrc = __HAL_RCC_GET_PLL_OSCSOURCE(); + if ((temp_sysclksrc == RCC_SYSCLKSOURCE_STATUS_MSI) || + ((temp_sysclksrc == RCC_SYSCLKSOURCE_STATUS_PLLCLK) && (temp_plloscsrc == RCC_PLLSOURCE_MSI))) + { + if (RCC_OscInitStruct->MSIState == RCC_MSI_OFF) + { + return HAL_ERROR; + } + /* Otherwise, just the calibration and MSI range change are allowed */ + else + { + /* To correctly read data from FLASH memory, the number of wait states (LATENCY) + must be correctly programmed according to the frequency of the AHB4 clock + and the supply voltage of the device. */ + if (RCC_OscInitStruct->MSIClockRange > __HAL_RCC_GET_MSI_RANGE()) + { + /* First increase number of wait states update if necessary */ + if (RCC_SetFlashLatencyFromMSIRange(RCC_OscInitStruct->MSIClockRange) != HAL_OK) + { + return HAL_ERROR; + } + + /* Selects the Multiple Speed oscillator (MSI) clock range .*/ + __HAL_RCC_MSI_RANGE_CONFIG(RCC_OscInitStruct->MSIClockRange); + /* Adjusts the Multiple Speed oscillator (MSI) calibration value.*/ + __HAL_RCC_MSI_CALIBRATIONVALUE_ADJUST(RCC_OscInitStruct->MSICalibrationValue); + } + else + { + /* Else, keep current flash latency while decreasing applies */ + /* Selects the Multiple Speed oscillator (MSI) clock range .*/ + __HAL_RCC_MSI_RANGE_CONFIG(RCC_OscInitStruct->MSIClockRange); + /* Adjusts the Multiple Speed oscillator (MSI) calibration value.*/ + __HAL_RCC_MSI_CALIBRATIONVALUE_ADJUST(RCC_OscInitStruct->MSICalibrationValue); + + /* Decrease number of wait states update if necessary */ + if (RCC_SetFlashLatencyFromMSIRange(RCC_OscInitStruct->MSIClockRange) != HAL_OK) + { + return HAL_ERROR; + } + } + + /* Update the SystemCoreClock global variable */ + SystemCoreClock = HAL_RCC_GetHCLKFreq(); + + if (HAL_InitTick(uwTickPrio) != HAL_OK) + { + return HAL_ERROR; + } + } + } + else + { + /* Check the MSI State */ + if (RCC_OscInitStruct->MSIState != RCC_MSI_OFF) + { + /* Enable the Internal High Speed oscillator (MSI). */ + __HAL_RCC_MSI_ENABLE(); + + /* Get timeout */ + tickstart = HAL_GetTick(); + + /* Wait till MSI is ready */ + while (LL_RCC_MSI_IsReady() == 0U) + { + if ((HAL_GetTick() - tickstart) > MSI_TIMEOUT_VALUE) + { + return HAL_TIMEOUT; + } + } + + /* Selects the Multiple Speed oscillator (MSI) clock range .*/ + __HAL_RCC_MSI_RANGE_CONFIG(RCC_OscInitStruct->MSIClockRange); + /* Adjusts the Multiple Speed oscillator (MSI) calibration value.*/ + __HAL_RCC_MSI_CALIBRATIONVALUE_ADJUST(RCC_OscInitStruct->MSICalibrationValue); + + } + else + { + /* Disable the Internal High Speed oscillator (MSI). */ + __HAL_RCC_MSI_DISABLE(); + + /* Get timeout */ + tickstart = HAL_GetTick(); + + /* Wait till MSI is disabled */ + while (LL_RCC_MSI_IsReady() != 0U) + { + if ((HAL_GetTick() - tickstart) > MSI_TIMEOUT_VALUE) + { + return HAL_TIMEOUT; + } + } + } + } + } + + /*------------------------------- HSE Configuration ------------------------*/ + if (((RCC_OscInitStruct->OscillatorType) & RCC_OSCILLATORTYPE_HSE) == RCC_OSCILLATORTYPE_HSE) + { + /* Check the parameters */ + assert_param(IS_RCC_HSE(RCC_OscInitStruct->HSEState)); + + /* When the HSE is used as system clock or clock source for PLL in these cases it is not allowed to be disabled */ + const uint32_t temp_sysclksrc = __HAL_RCC_GET_SYSCLK_SOURCE(); + const uint32_t temp_plloscsrc = __HAL_RCC_GET_PLL_OSCSOURCE(); + if ((temp_sysclksrc == RCC_SYSCLKSOURCE_STATUS_HSE) || + ((temp_sysclksrc == RCC_SYSCLKSOURCE_STATUS_PLLCLK) && (temp_plloscsrc == RCC_PLLSOURCE_HSE))) + { + if (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 (LL_RCC_HSE_IsReady() == 0U) + { + if ((HAL_GetTick() - tickstart) > HSE_TIMEOUT_VALUE) + { + return HAL_TIMEOUT; + } + } + } + else + { + /* Get Start Tick*/ + tickstart = HAL_GetTick(); + + /* Wait till HSE is disabled */ + while (LL_RCC_HSE_IsReady() != 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)); + + /* Check if HSI is used as system clock or as PLL source when PLL is selected as system clock */ + const uint32_t temp_sysclksrc = __HAL_RCC_GET_SYSCLK_SOURCE(); + const uint32_t temp_plloscsrc = __HAL_RCC_GET_PLL_OSCSOURCE(); + if ((temp_sysclksrc == RCC_SYSCLKSOURCE_STATUS_HSI) || + ((temp_sysclksrc == RCC_SYSCLKSOURCE_STATUS_PLLCLK) && (temp_plloscsrc == RCC_PLLSOURCE_HSI))) + { + /* When HSI is used as system clock it will not be disabled */ + if (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); + } + } + else + { + /* Check the HSI State */ + if (RCC_OscInitStruct->HSIState != RCC_HSI_OFF) + { + /* Enable the Internal High Speed oscillator (HSI). */ + __HAL_RCC_HSI_ENABLE(); + + /* Get Start Tick*/ + tickstart = HAL_GetTick(); + + /* Wait till HSI is ready */ + while (LL_RCC_HSI_IsReady() == 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 (HSI). */ + __HAL_RCC_HSI_DISABLE(); + + /* Get Start Tick*/ + tickstart = HAL_GetTick(); + + /* Wait till HSI is disabled */ + while (LL_RCC_HSI_IsReady() != 0U) + { + if ((HAL_GetTick() - tickstart) > HSI_TIMEOUT_VALUE) + { + return HAL_TIMEOUT; + } + } + } + } + } + /*------------------------------ LSI Configuration (LSI1 or LSI2) -------------------------*/ + + if ((((RCC_OscInitStruct->OscillatorType) & RCC_OSCILLATORTYPE_LSI1) == RCC_OSCILLATORTYPE_LSI1) || \ + (((RCC_OscInitStruct->OscillatorType) & RCC_OSCILLATORTYPE_LSI2) == RCC_OSCILLATORTYPE_LSI2)) + { + /* Check the parameters */ + assert_param(IS_RCC_LSI(RCC_OscInitStruct->LSIState)); + + /* Check the LSI State */ + if (RCC_OscInitStruct->LSIState != RCC_LSI_OFF) + { + /*------------------------------ LSI2 selected by default (when Switch ON) -------------------------*/ + if (((RCC_OscInitStruct->OscillatorType) & RCC_OSCILLATORTYPE_LSI2) == RCC_OSCILLATORTYPE_LSI2) + { + assert_param(IS_RCC_LSI2_CALIBRATION_VALUE(RCC_OscInitStruct->LSI2CalibrationValue)); + + /* 1. Check LSI1 state and enable if required */ + if (LL_RCC_LSI1_IsReady() == 0U) + { + /* This is required to enable LSI1 before enabling LSI2 */ + __HAL_RCC_LSI1_ENABLE(); + + /* Get Start Tick*/ + tickstart = HAL_GetTick(); + + /* Wait till LSI1 is ready */ + while (LL_RCC_LSI1_IsReady() == 0U) + { + if ((HAL_GetTick() - tickstart) > LSI1_TIMEOUT_VALUE) + { + return HAL_TIMEOUT; + } + } + } + + /* 2. Enable the Internal Low Speed oscillator (LSI2) and set trimming value */ + __HAL_RCC_LSI2_ENABLE(); + + /* Get Start Tick*/ + tickstart = HAL_GetTick(); + + /* Wait till LSI2 is ready */ + while (LL_RCC_LSI2_IsReady() == 0U) + { + if ((HAL_GetTick() - tickstart) > LSI2_TIMEOUT_VALUE) + { + return HAL_TIMEOUT; + } + } + /* Adjusts the Internal Low Spee oscillator (LSI2) calibration value */ + __HAL_RCC_LSI2_CALIBRATIONVALUE_ADJUST(RCC_OscInitStruct->LSI2CalibrationValue); + + /* 3. Disable LSI1 */ + + /* LSI1 was initially not enable, require to disable it */ + __HAL_RCC_LSI1_DISABLE(); + + /* Get Start Tick*/ + tickstart = HAL_GetTick(); + + /* Wait till LSI1 is disabled */ + while (LL_RCC_LSI1_IsReady() != 0U) + { + if ((HAL_GetTick() - tickstart) > LSI1_TIMEOUT_VALUE) + { + return HAL_TIMEOUT; + } + } + } + else + { + /*------------------------------ LSI1 selected (only if LSI2 OFF)-------------------------*/ + + /* 1. Enable the Internal Low Speed oscillator (LSI1). */ + __HAL_RCC_LSI1_ENABLE(); + + /* Get Start Tick*/ + tickstart = HAL_GetTick(); + + /* Wait till LSI1 is ready */ + while (LL_RCC_LSI1_IsReady() == 0U) + { + if ((HAL_GetTick() - tickstart) > LSI1_TIMEOUT_VALUE) + { + return HAL_TIMEOUT; + } + } + /*2. Switch OFF LSI2*/ + + /* Disable the Internal Low Speed oscillator (LSI2). */ + __HAL_RCC_LSI2_DISABLE(); + + /* Wait till LSI2 is disabled */ + while (LL_RCC_LSI2_IsReady() != 0U) + { + if ((HAL_GetTick() - tickstart) > LSI2_TIMEOUT_VALUE) + { + return HAL_TIMEOUT; + } + } + } + } + else + { + + /* Disable the Internal Low Speed oscillator (LSI2). */ + __HAL_RCC_LSI2_DISABLE(); + + /* Get Start Tick*/ + tickstart = HAL_GetTick(); + + /* Wait till LSI2 is disabled */ + while (LL_RCC_LSI2_IsReady() != 0U) + { + if ((HAL_GetTick() - tickstart) > LSI2_TIMEOUT_VALUE) + { + return HAL_TIMEOUT; + } + } + + /* Disable the Internal Low Speed oscillator (LSI1). */ + __HAL_RCC_LSI1_DISABLE(); + + /* Get Start Tick*/ + tickstart = HAL_GetTick(); + + /* Wait till LSI1 is disabled */ + while (LL_RCC_LSI1_IsReady() != 0U) + { + if ((HAL_GetTick() - tickstart) > LSI1_TIMEOUT_VALUE) + { + return HAL_TIMEOUT; + } + } + } + } + + /*------------------------------ LSE Configuration -------------------------*/ + if (((RCC_OscInitStruct->OscillatorType) & RCC_OSCILLATORTYPE_LSE) == RCC_OSCILLATORTYPE_LSE) + { + /* Check the parameters */ + assert_param(IS_RCC_LSE(RCC_OscInitStruct->LSEState)); + + /* Update LSE configuration in Backup Domain control register */ + /* Requires to enable write access to Backup Domain of necessary */ + + if (HAL_IS_BIT_CLR(PWR->CR1, PWR_CR1_DBP)) + { + /* Enable write access to Backup domain */ + HAL_PWR_EnableBkUpAccess(); + + /* 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 (LL_RCC_LSE_IsReady() == 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 (LL_RCC_LSE_IsReady() != 0U) + { + if ((HAL_GetTick() - tickstart) > RCC_LSE_TIMEOUT_VALUE) + { + return HAL_TIMEOUT; + } + } + } + + } +#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 HSI 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 (LL_RCC_HSI48_IsReady() == 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 (LL_RCC_HSI48_IsReady() != 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) + { + const uint32_t temp_sysclksrc = __HAL_RCC_GET_SYSCLK_SOURCE(); + const uint32_t temp_pllconfig = RCC->PLLCFGR; + + /* PLL On ? */ + 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)); + assert_param(IS_RCC_PLLQ_VALUE(RCC_OscInitStruct->PLL.PLLQ)); + assert_param(IS_RCC_PLLR_VALUE(RCC_OscInitStruct->PLL.PLLR)); + + /* Do nothing if PLL configuration is unchanged */ + if ((READ_BIT(temp_pllconfig, RCC_PLLCFGR_PLLSRC) != RCC_OscInitStruct->PLL.PLLSource) || + (READ_BIT(temp_pllconfig, RCC_PLLCFGR_PLLM) != RCC_OscInitStruct->PLL.PLLM) || + ((READ_BIT(temp_pllconfig, RCC_PLLCFGR_PLLN) >> RCC_PLLCFGR_PLLN_Pos) != RCC_OscInitStruct->PLL.PLLN) || + (READ_BIT(temp_pllconfig, RCC_PLLCFGR_PLLP) != RCC_OscInitStruct->PLL.PLLP) || + (READ_BIT(temp_pllconfig, RCC_PLLCFGR_PLLQ) != RCC_OscInitStruct->PLL.PLLQ) || + (READ_BIT(temp_pllconfig, RCC_PLLCFGR_PLLR) != RCC_OscInitStruct->PLL.PLLR)) + { + /* Check if the PLL is used as system clock or not */ + if (temp_sysclksrc != RCC_SYSCLKSOURCE_STATUS_PLLCLK) + { +#if defined(SAI1) + /* Check if main PLL can be updated */ + /* Not possible if the source is shared by other enabled PLLSAIx */ + if (READ_BIT(RCC->CR, RCC_CR_PLLSAI1ON) != 0U) + + { + return HAL_ERROR; + } + else +#endif /* SAI1 */ + { + /* 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. */ + __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); + + /* Enable the main PLL. */ + __HAL_RCC_PLL_ENABLE(); + + /* Enable PLL System Clock output. */ + __HAL_RCC_PLLCLKOUT_ENABLE(RCC_PLL_SYSCLK); + + /* 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 + { + /* PLL is already used as System core clock */ + return HAL_ERROR; + } + } + else + { + /* PLL configuration is unchanged */ + /* Re-enable PLL if it was disabled (ie. low power mode) */ + if (READ_BIT(RCC->CR, RCC_CR_PLLRDY) == 0U) + { + /* Enable the main PLL. */ + __HAL_RCC_PLL_ENABLE(); + + /* Enable PLL System Clock output. */ + __HAL_RCC_PLLCLKOUT_ENABLE(RCC_PLL_SYSCLK); + + /* 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 + { + /* Check that PLL is not used as system clock or not */ + if (temp_sysclksrc != RCC_SYSCLKSOURCE_STATUS_PLLCLK) + { + /* 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; + } + } + + /* Disable the PLL source and outputs to save power when PLL is off */ +#if defined(SAI1) && defined(USB) + CLEAR_BIT(RCC->PLLCFGR, (RCC_PLLCFGR_PLLSRC | RCC_PLLCFGR_PLLPEN | RCC_PLLCFGR_PLLQEN | RCC_PLLCFGR_PLLREN)); +#else + CLEAR_BIT(RCC->PLLCFGR, (RCC_PLLCFGR_PLLSRC | RCC_PLLCFGR_PLLREN)); +#endif /* SAI1 && USB */ + } + else + { + /* PLL is already used as System core clock */ + 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 + * @arg FLASH_LATENCY_2 FLASH 2 Latency cycle + * @arg FLASH_LATENCY_3 FLASH 3 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 MSI is used by default as system clock source after + * startup from Reset, wake-up from STANDBY mode. After restart from Reset, + * the MSI frequency is set to its default value 4 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 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 HCLK1 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 + (HCLK4) 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); + + /* Get Start Tick*/ + tickstart = HAL_GetTick(); + + /* Check that the new number of wait states is taken into account to access the Flash + memory by reading the FLASH_ACR register */ + while (__HAL_FLASH_GET_LATENCY() != FLatency) + { + if ((HAL_GetTick() - tickstart) > LATENCY_TIMEOUT_VALUE) + { + return HAL_TIMEOUT; + } + } + } + + /*-------------------------- HCLK1 Configuration --------------------------*/ + if (((RCC_ClkInitStruct->ClockType) & RCC_CLOCKTYPE_HCLK) == RCC_CLOCKTYPE_HCLK) + { + assert_param(IS_RCC_HCLKx(RCC_ClkInitStruct->AHBCLKDivider)); + LL_RCC_SetAHBPrescaler(RCC_ClkInitStruct->AHBCLKDivider); + + /* HCLK1 prescaler flag when value applied */ + tickstart = HAL_GetTick(); + while (LL_RCC_IsActiveFlag_HPRE() == 0U) + { + if ((HAL_GetTick() - tickstart) > PRESCALER_TIMEOUT_VALUE) + { + return HAL_TIMEOUT; + } + } + } + + /*-------------------------- HCLK2 Configuration --------------------------*/ + if (((RCC_ClkInitStruct->ClockType) & RCC_CLOCKTYPE_HCLK2) == RCC_CLOCKTYPE_HCLK2) + { + assert_param(IS_RCC_HCLKx(RCC_ClkInitStruct->AHBCLK2Divider)); + LL_C2_RCC_SetAHBPrescaler(RCC_ClkInitStruct->AHBCLK2Divider); + + /* HCLK2 prescaler flag when value applied */ + tickstart = HAL_GetTick(); + while (LL_RCC_IsActiveFlag_C2HPRE() == 0U) + { + if ((HAL_GetTick() - tickstart) > PRESCALER_TIMEOUT_VALUE) + { + return HAL_TIMEOUT; + } + } + } + /*-------------------------- HCLK4 Configuration --------------------------*/ + if (((RCC_ClkInitStruct->ClockType) & RCC_CLOCKTYPE_HCLK4) == RCC_CLOCKTYPE_HCLK4) + { + assert_param(IS_RCC_HCLKx(RCC_ClkInitStruct->AHBCLK4Divider)); + LL_RCC_SetAHB4Prescaler(RCC_ClkInitStruct->AHBCLK4Divider); + + /* AHB shared prescaler flag when value applied */ + tickstart = HAL_GetTick(); + while (LL_RCC_IsActiveFlag_SHDHPRE() == 0U) + { + if ((HAL_GetTick() - tickstart) > PRESCALER_TIMEOUT_VALUE) + { + return HAL_TIMEOUT; + } + } + } + + /*-------------------------- PCLK1 Configuration ---------------------------*/ + if (((RCC_ClkInitStruct->ClockType) & RCC_CLOCKTYPE_PCLK1) == RCC_CLOCKTYPE_PCLK1) + { + assert_param(IS_RCC_PCLKx(RCC_ClkInitStruct->APB1CLKDivider)); + LL_RCC_SetAPB1Prescaler(RCC_ClkInitStruct->APB1CLKDivider); + + /* APB1 prescaler flag when value applied */ + tickstart = HAL_GetTick(); + while (LL_RCC_IsActiveFlag_PPRE1() == 0U) + { + if ((HAL_GetTick() - tickstart) > PRESCALER_TIMEOUT_VALUE) + { + return HAL_TIMEOUT; + } + } + } + + /*-------------------------- PCLK2 Configuration ---------------------------*/ + if (((RCC_ClkInitStruct->ClockType) & RCC_CLOCKTYPE_PCLK2) == RCC_CLOCKTYPE_PCLK2) + { + assert_param(IS_RCC_PCLKx(RCC_ClkInitStruct->APB2CLKDivider)); + LL_RCC_SetAPB2Prescaler((RCC_ClkInitStruct->APB2CLKDivider) << 3U); + + /* APB2 prescaler flag when value applied */ + tickstart = HAL_GetTick(); + while (LL_RCC_IsActiveFlag_PPRE2() == 0U) + { + if ((HAL_GetTick() - tickstart) > PRESCALER_TIMEOUT_VALUE) + { + return HAL_TIMEOUT; + } + } + } + + /*------------------------- 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 (LL_RCC_HSE_IsReady() == 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 (LL_RCC_PLL_IsReady() == 0U) + { + return HAL_ERROR; + } + } + /* MSI is selected as System Clock Source */ + else if (RCC_ClkInitStruct->SYSCLKSource == RCC_SYSCLKSOURCE_MSI) + { + /* Check the MSI ready flag */ + if (LL_RCC_MSI_IsReady() == 0U) + { + return HAL_ERROR; + } + } + /* HSI is selected as System Clock Source */ + else + { + /* Check the HSI ready flag */ + if (LL_RCC_HSI_IsReady() == 0U) + { + return HAL_ERROR; + } + + } + + /* apply system clock switch */ + LL_RCC_SetSysClkSource(RCC_ClkInitStruct->SYSCLKSource); + + /* Get Start Tick*/ + tickstart = HAL_GetTick(); + + /* check system clock source switch status */ + 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); + + /* Get Start Tick*/ + tickstart = HAL_GetTick(); + + /* Check that the new number of wait states is taken into account to access the Flash + memory by reading the FLASH_ACR register */ + while (__HAL_FLASH_GET_LATENCY() != FLatency) + { + if ((HAL_GetTick() - tickstart) > LATENCY_TIMEOUT_VALUE) + { + return HAL_TIMEOUT; + } + } + } + + /*---------------------------------------------------------------------------*/ + + /* Update the SystemCoreClock global variable */ + SystemCoreClock = HAL_RCC_GetHCLKFreq(); + + /* Configure the source of time base considering new system clocks settings*/ + return HAL_InitTick(HAL_GetTickPrio()); +} + +/** + * @} + */ + +/** @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 MCO2 pin (PB6) or MCO3 pin (PA15). + * @note PA8, PB6 or PA15 should be configured in alternate function mode. + * @param RCC_MCOx specifies the output direction for the clock source. + * @arg @ref RCC_MCO1_PA8 Clock source to output on MCO1 pin(PA8) + * @arg @ref RCC_MCO2_PB6 Clock source to output on MCO2 pin(PB6) + * @arg @ref RCC_MCO3_PA15 Clock source to output on MCO3 pin(PA15) + * @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_MSI MSI clock selected as MCO source + * @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 PLL clock selected as MCO source + * @arg @ref RCC_MCO1SOURCE_LSI1 LSI1 clock selected as MCO source + * @arg @ref RCC_MCO1SOURCE_LSI2 LSI2 clock selected as MCO source + * @arg @ref RCC_MCO1SOURCE_LSE LSE clock selected as MCO source + * @arg @ref RCC_MCO1SOURCE_HSI48 HSI48 clock selected as MCO source for devices with HSI48 + * @arg @ref RCC_MCO1SOURCE_HSE_BEFORE_STAB HSE clock before stabilization selected as MCO 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 + * @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->AHB2ENR, (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 */ + LL_RCC_ConfigMCO(RCC_MCOSource, RCC_MCODiv); + } + else if (mcoindex == RCC_MCO2_INDEX) + { + assert_param(IS_RCC_MCODIV(RCC_MCODiv)); + assert_param(IS_RCC_MCO2SOURCE(RCC_MCOSource)); + /* Mask MCOSEL[] and MCOPRE[] bits then set MCO clock source and prescaler */ + LL_RCC_ConfigMCO(RCC_MCOSource, RCC_MCODiv); + } +#if defined(RCC_MCO3_SUPPORT) + else if (mcoindex == RCC_MCO3_INDEX) + { + assert_param(IS_RCC_MCODIV(RCC_MCODiv)); + assert_param(IS_RCC_MCO3SOURCE(RCC_MCOSource)); + /* Mask MCOSEL[] and MCOPRE[] bits then set MCO clock source and prescaler */ + LL_RCC_ConfigMCO(RCC_MCOSource, RCC_MCODiv); + } +#endif /* RCC_MCO3_SUPPORT */ + else + {} +} + +/** + * @brief Return the SYSCLK frequency. + * + * @note The system 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 MSI, function returns values based on MSI range + * @note If SYSCLK source is HSI, function returns values based on HSI_VALUE(*) + * @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(**), + * HSI_VALUE(*) or MSI Value multiplied/divided by the PLL factors. + * @note (*) HSI_VALUE is a constant defined in stm32wbxx_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 stm32wbxx_hal_conf.h file (default value + * 32 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 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 pllsource; + uint32_t sysclockfreq; + uint32_t pllinputfreq; + const uint32_t temp_sysclksrc = __HAL_RCC_GET_SYSCLK_SOURCE(); + + if (temp_sysclksrc == RCC_SYSCLKSOURCE_STATUS_MSI) + { + /* Retrieve MSI frequency range in HZ*/ + /* MSI used as system clock source */ + sysclockfreq = __LL_RCC_CALC_MSI_FREQ(LL_RCC_MSI_GetRange()); + } + else if (temp_sysclksrc == RCC_SYSCLKSOURCE_STATUS_HSI) + { + /* HSI used as system clock source */ + sysclockfreq = HSI_VALUE; + } + else if (temp_sysclksrc == RCC_SYSCLKSOURCE_STATUS_HSE) + { + /* HSE used as system clock source */ + if (LL_RCC_HSE_IsEnabledDiv2() == 1U) + { + sysclockfreq = HSE_VALUE / 2U; + } + else + { + sysclockfreq = HSE_VALUE; + } + } + else + { + /* PLL used as system clock source */ + pllsource = LL_RCC_PLL_GetMainSource(); + switch (pllsource) + { + case RCC_PLLSOURCE_HSI: /* HSI used as PLL clock source */ + pllinputfreq = HSI_VALUE; + break; + case RCC_PLLSOURCE_HSE: /* HSE used as PLL clock source */ + if (LL_RCC_HSE_IsEnabledDiv2() == 1U) + { + pllinputfreq = HSE_VALUE / 2U; + } + else + { + pllinputfreq = HSE_VALUE; + } + break; + case RCC_PLLSOURCE_MSI: /* MSI used as PLL clock source */ + default: + pllinputfreq = __LL_RCC_CALC_MSI_FREQ(LL_RCC_MSI_GetRange()); + break; + } + sysclockfreq = __LL_RCC_CALC_PLLCLK_FREQ(pllinputfreq, LL_RCC_PLL_GetDivider(), LL_RCC_PLL_GetN(), + LL_RCC_PLL_GetR()); + } + + return sysclockfreq; +} + +/** + * @brief Return the HCLK frequency. + * @retval HCLK frequency in Hz + */ +uint32_t HAL_RCC_GetHCLKFreq(void) +{ + /* Get SysClock and Compute HCLK1 frequency ---------------------------*/ + return ((uint32_t)(__LL_RCC_CALC_HCLK1_FREQ(HAL_RCC_GetSysClockFreq(), LL_RCC_GetAHBPrescaler()))); +} + +/** + * @brief Return the HCLK2 frequency. + * @retval HCLK2 frequency in Hz + */ +uint32_t HAL_RCC_GetHCLK2Freq(void) +{ + /* Get SysClock and Compute HCLK2 frequency ---------------------------*/ + return ((uint32_t)(__LL_RCC_CALC_HCLK2_FREQ(HAL_RCC_GetSysClockFreq(), LL_C2_RCC_GetAHBPrescaler()))); +} + +/** + * @brief Return the HCLK4 frequency. + * @retval HCLK4 frequency in Hz + */ +uint32_t HAL_RCC_GetHCLK4Freq(void) +{ + /* Get SysClock and Compute AHB4 frequency ---------------------------*/ + return ((uint32_t)(__LL_RCC_CALC_HCLK4_FREQ(HAL_RCC_GetSysClockFreq(), LL_RCC_GetAHB4Prescaler()))); +} + +/** + * @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 Return the PCLK2 frequency. + * @note Each time PCLK2 changes, this function must be called to update the + * right PCLK2 value. Otherwise, any configuration based on this function will be incorrect. + * @retval PCLK2 frequency in Hz + */ +uint32_t HAL_RCC_GetPCLK2Freq(void) +{ + /* Get HCLK source and Compute PCLK2 frequency ---------------------------*/ + return ((uint32_t)(__LL_RCC_CALC_PCLK2_FREQ(HAL_RCC_GetHCLKFreq(), LL_RCC_GetAPB2Prescaler()))); +} + +/** + * @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) +{ + uint32_t regvalue; + uint32_t regICSRvalue; + uint32_t regPLLCFGRvalue; + + /* Check the parameters */ + assert_param(RCC_OscInitStruct != (void *)NULL); + + /* Set all possible values for the Oscillator type parameter ---------------*/ + RCC_OscInitStruct->OscillatorType = RCC_OSCILLATORTYPE_HSE | RCC_OSCILLATORTYPE_HSI | RCC_OSCILLATORTYPE_MSI | \ + RCC_OSCILLATORTYPE_LSE | RCC_OSCILLATORTYPE_LSI1 | RCC_OSCILLATORTYPE_LSI2; + +#if defined(RCC_HSI48_SUPPORT) + RCC_OscInitStruct->OscillatorType |= RCC_OSCILLATORTYPE_HSI48; +#endif /* RCC_HSI48_SUPPORT */ + + /* Get register values */ + regvalue = RCC->CR; /* Control register */ + regICSRvalue = RCC->ICSCR; /* Get Internal Clock Sources Calibration register */ + regPLLCFGRvalue = RCC->PLLCFGR; /* Get PLL Configuration register */ + + /* Get the HSE configuration -----------------------------------------------*/ + RCC_OscInitStruct->HSEState = (regvalue & RCC_CR_HSEON); + + /* Get the MSI configuration -----------------------------------------------*/ + RCC_OscInitStruct->MSIState = (regvalue & RCC_CR_MSION); + RCC_OscInitStruct->MSICalibrationValue = (regICSRvalue & RCC_ICSCR_MSITRIM) >> RCC_ICSCR_MSITRIM_Pos; + RCC_OscInitStruct->MSIClockRange = (regvalue & RCC_CR_MSIRANGE); + + /* Get the HSI configuration -----------------------------------------------*/ + RCC_OscInitStruct->HSIState = (regvalue & RCC_CR_HSION); + RCC_OscInitStruct->HSICalibrationValue = ((regICSRvalue & RCC_ICSCR_HSITRIM) >> RCC_ICSCR_HSITRIM_Pos); + + /* Get the PLL configuration -----------------------------------------------*/ + RCC_OscInitStruct->PLL.PLLState = ((regvalue & RCC_CR_PLLON) >> RCC_CR_PLLON_Pos) + 1U; + RCC_OscInitStruct->PLL.PLLSource = (regPLLCFGRvalue & RCC_PLLCFGR_PLLSRC); + RCC_OscInitStruct->PLL.PLLM = (regPLLCFGRvalue & RCC_PLLCFGR_PLLM); + RCC_OscInitStruct->PLL.PLLN = ((regPLLCFGRvalue & RCC_PLLCFGR_PLLN) >> RCC_PLLCFGR_PLLN_Pos); + RCC_OscInitStruct->PLL.PLLP = (regPLLCFGRvalue & RCC_PLLCFGR_PLLP); + RCC_OscInitStruct->PLL.PLLQ = (regPLLCFGRvalue & RCC_PLLCFGR_PLLQ); + RCC_OscInitStruct->PLL.PLLR = (regPLLCFGRvalue & RCC_PLLCFGR_PLLR); + + /* Get Backup Domain register */ + regvalue = RCC->BDCR; + + /* Get the LSE configuration -----------------------------------------------*/ + RCC_OscInitStruct->LSEState = (regvalue & RCC_LSE_BYPASS); + + /* Get Control/Status register */ + regvalue = RCC->CSR; + + /* Get the LSI configuration -----------------------------------------------*/ + RCC_OscInitStruct->LSIState = ((regvalue & RCC_LSI_ON) > 0U) ? RCC_LSI_ON : 0U; + +#if defined(RCC_HSI48_SUPPORT) + /* Get Control/Status register */ + regvalue = RCC->CRRCR; + + /* Get the HSI48 configuration ---------------------------------------------*/ + RCC_OscInitStruct->HSI48State = (regvalue & RCC_CRRCR_HSI48ON); +#endif /* RCC_HSI48_SUPPORT */ + +} + +/** + * @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 | + RCC_CLOCKTYPE_PCLK2 | RCC_CLOCKTYPE_HCLK2 | RCC_CLOCKTYPE_HCLK4); + + /* Get the SYSCLK configuration --------------------------------------------*/ + RCC_ClkInitStruct->SYSCLKSource = LL_RCC_GetSysClkSource(); + + /* Get the HCLK configuration ----------------------------------------------*/ + RCC_ClkInitStruct->AHBCLKDivider = LL_RCC_GetAHBPrescaler(); + + /* Get the APB1 configuration ----------------------------------------------*/ + RCC_ClkInitStruct->APB1CLKDivider = LL_RCC_GetAPB1Prescaler(); + + /* Get the APB2 configuration ----------------------------------------------*/ + RCC_ClkInitStruct->APB2CLKDivider = LL_RCC_GetAPB2Prescaler(); + + /* Get the AHBCLK2Divider configuration ------------------------------------*/ + RCC_ClkInitStruct->AHBCLK2Divider = LL_C2_RCC_GetAHBPrescaler(); + + /* Get the AHBCLK4Divider configuration ------------------------------------*/ + RCC_ClkInitStruct->AHBCLK4Divider = LL_RCC_GetAHB4Prescaler(); + + /* Get the Flash Wait State (Latency) configuration ------------------------*/ + *pFLatency = __HAL_FLASH_GET_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 + * CPU1 and CPU2 NMI (Non-Maskable Interrupt) exception vector. + * @note The Clock Security System can only be cleared by reset. + * @retval None + */ +void HAL_RCC_EnableCSS(void) +{ + LL_RCC_HSE_EnableCSS(); +} + +/** + * @brief Handle the RCC HSE Clock Security System interrupt request. + * @note This API should be called under the NMI_Handler(). + * @retval None + */ +void HAL_RCC_NMI_IRQHandler(void) +{ + /* Check RCC CSSF interrupt flag */ + if (__HAL_RCC_GET_IT(RCC_IT_HSECSS)) + { + /* RCC Clock Security System interrupt user callback */ + HAL_RCC_CSSCallback(); + + /* Clear RCC CSS pending bit */ + __HAL_RCC_CLEAR_IT(RCC_IT_HSECSS); + } +} + +/** + * @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 Get and clear reset flags + * @param None + * @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; +} + +/** + * @} + */ + +/** + * @} + */ + +/* Private function prototypes -----------------------------------------------*/ +/** @addtogroup RCC_Private_Functions + * @{ + */ + +/** + * @brief Update number of Flash wait states in line with MSI range and current + voltage range. + * @param MSI_Range MSI range value from @ref RCC_MSIRANGE_0 to @ref RCC_MSIRANGE_11 + * @retval HAL status + */ +static HAL_StatusTypeDef RCC_SetFlashLatencyFromMSIRange(uint32_t MSI_Range) +{ + uint32_t flash_clksrcfreq; + uint32_t msifreq; + + /* Check the parameters */ + assert_param(IS_RCC_MSI_CLOCK_RANGE(MSI_Range)); + + /* MSI frequency range in Hz */ + if (MSI_Range > RCC_MSIRANGE_11) + { + msifreq = __LL_RCC_CALC_MSI_FREQ(RCC_MSIRANGE_11); + } + else + { + msifreq = __LL_RCC_CALC_MSI_FREQ(MSI_Range); + } + + flash_clksrcfreq = __LL_RCC_CALC_HCLK4_FREQ(msifreq, LL_RCC_GetAHB4Prescaler()); + +#if defined(PWR_CR1_VOS) + return RCC_SetFlashLatency((flash_clksrcfreq / MEGA_HZ), HAL_PWREx_GetVoltageRange()); +#else + return RCC_SetFlashLatency((flash_clksrcfreq / MEGA_HZ), PWR_REGULATOR_VOLTAGE_SCALE1); +#endif /* PWR_CR1_VOS */ +} + + +/** + * @brief Update number of Flash wait states. + * @param Flash_ClkSrcFreq Flash Clock Source (in MHz) + * @param VCORE_Voltage Current Vcore voltage (PWR_REGULATOR_VOLTAGE_SCALE1 or PWR_REGULATOR_VOLTAGE_SCALE2) + * @retval HAL status + */ +static HAL_StatusTypeDef RCC_SetFlashLatency(uint32_t Flash_ClkSrcFreq, uint32_t VCORE_Voltage) +{ + /* Flash Clock source (HCLK4) range in MHz with a VCORE is range1 */ + const uint32_t FLASH_CLK_SRC_RANGE_VOS1[] = {18UL, 36UL, 54UL, 64UL}; +#if defined(PWR_CR1_VOS) + /* Flash Clock source (HCLK4) range in MHz with a VCORE is range2 */ + const uint32_t FLASH_CLK_SRC_RANGE_VOS2[] = {6UL, 12UL, 16UL}; +#endif /* PWR_CR1_VOS */ + /* Flash Latency range */ + const uint32_t FLASH_LATENCY_RANGE[] = {FLASH_LATENCY_0, FLASH_LATENCY_1, FLASH_LATENCY_2, FLASH_LATENCY_3}; + uint32_t latency = FLASH_LATENCY_0; /* default value 0WS */ + uint32_t tickstart; + +#if defined(PWR_CR1_VOS) + if (VCORE_Voltage == PWR_REGULATOR_VOLTAGE_SCALE1) + { + for (uint32_t index = 0; index < __COUNTOF(FLASH_CLK_SRC_RANGE_VOS1); index++) + { + if (Flash_ClkSrcFreq <= FLASH_CLK_SRC_RANGE_VOS1[index]) + { + latency = FLASH_LATENCY_RANGE[index]; + break; + } + } + } + else /* PWR_REGULATOR_VOLTAGE_SCALE2 */ + { + for (uint32_t index = 0; index < __COUNTOF(FLASH_CLK_SRC_RANGE_VOS2); index++) + { + if (Flash_ClkSrcFreq <= FLASH_CLK_SRC_RANGE_VOS2[index]) + { + latency = FLASH_LATENCY_RANGE[index]; + break; + } + } + } +#else + for (uint32_t index = 0; index < __COUNTOF(FLASH_CLK_SRC_RANGE_VOS1); index++) + { + if (Flash_ClkSrcFreq <= FLASH_CLK_SRC_RANGE_VOS1[index]) + { + latency = FLASH_LATENCY_RANGE[index]; + break; + } + } +#endif /* PWR_CR1_VOS */ + + __HAL_FLASH_SET_LATENCY(latency); + + /* Get Start Tick*/ + tickstart = HAL_GetTick(); + + /* Check that the new number of wait states is taken into account to access the Flash + memory by reading the FLASH_ACR register */ + while (__HAL_FLASH_GET_LATENCY() != latency) + { + if ((HAL_GetTick() - tickstart) > LATENCY_TIMEOUT_VALUE) + { + return HAL_TIMEOUT; + } + } + return HAL_OK; +} + +/** + * @} + */ + +#endif /* HAL_RCC_MODULE_ENABLED */ +/** + * @} + */ + +/** + * @} + */ |
