/** ****************************************************************************** * @file stm32mp1xx_ll_rcc.c * @author MCD Application Team * @version $VERSION$ * @date $DATE$ * @brief RCC LL module driver. ****************************************************************************** * @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. * ****************************************************************************** */ #if defined(USE_FULL_LL_DRIVER) /* Includes ------------------------------------------------------------------*/ #include "stm32mp1xx_ll_rcc.h" #ifdef USE_FULL_ASSERT #include "stm32_assert.h" #else #define assert_param(expr) ((void)0U) #endif /** @addtogroup STM32MP1xx_LL_Driver * @{ */ #if defined(RCC) /** @addtogroup RCC_LL * @{ */ /* Private types -------------------------------------------------------------*/ /* Private variables ---------------------------------------------------------*/ /* Private constants ---------------------------------------------------------*/ /* Private macros ------------------------------------------------------------*/ /** @addtogroup RCC_LL_Private_Macros * @{ */ #define IS_LL_RCC_I2C_CLKSOURCE(__VALUE__) (((__VALUE__) == LL_RCC_I2C12_CLKSOURCE) \ || ((__VALUE__) == LL_RCC_I2C35_CLKSOURCE) \ || ((__VALUE__) == LL_RCC_I2C46_CLKSOURCE)) #define IS_LL_RCC_SAI_CLKSOURCE(__VALUE__) (((__VALUE__) == LL_RCC_SAI1_CLKSOURCE) \ || ((__VALUE__) == LL_RCC_SAI2_CLKSOURCE) \ || ((__VALUE__) == LL_RCC_SAI3_CLKSOURCE) \ || ((__VALUE__) == LL_RCC_SAI4_CLKSOURCE)) #define IS_LL_RCC_SPI_CLKSOURCE(__VALUE__) (((__VALUE__) == LL_RCC_SPI1_CLKSOURCE) \ || ((__VALUE__) == LL_RCC_SPI23_CLKSOURCE) \ || ((__VALUE__) == LL_RCC_SPI45_CLKSOURCE) \ || ((__VALUE__) == LL_RCC_SPI6_CLKSOURCE)) #define IS_LL_RCC_UART_CLKSOURCE(__VALUE__) (((__VALUE__) == LL_RCC_USART1_CLKSOURCE) \ || ((__VALUE__) == LL_RCC_UART24_CLKSOURCE) \ || ((__VALUE__) == LL_RCC_UART35_CLKSOURCE) \ || ((__VALUE__) == LL_RCC_USART6_CLKSOURCE) \ || ((__VALUE__) == LL_RCC_UART78_CLKSOURCE)) #define IS_LL_RCC_SDMMC_CLKSOURCE(__VALUE__) (((__VALUE__) == LL_RCC_SDMMC12_CLKSOURCE) \ || ((__VALUE__) == LL_RCC_SDMMC3_CLKSOURCE)) #define IS_LL_RCC_ETH_CLKSOURCE(__VALUE__) (((__VALUE__) == LL_RCC_ETH_CLKSOURCE)) #define IS_LL_RCC_QSPI_CLKSOURCE(__VALUE__) (((__VALUE__) == LL_RCC_QSPI_CLKSOURCE)) #define IS_LL_RCC_FMC_CLKSOURCE(__VALUE__) (((__VALUE__) == LL_RCC_FMC_CLKSOURCE)) #if defined(FDCAN1) #define IS_LL_RCC_FDCAN_CLKSOURCE(__VALUE__) (((__VALUE__) == LL_RCC_FDCAN_CLKSOURCE)) #endif /*FDCAN1*/ #define IS_LL_RCC_SPDIFRX_CLKSOURCE(__VALUE__) (((__VALUE__) == LL_RCC_SPDIFRX_CLKSOURCE)) #define IS_LL_RCC_CEC_CLKSOURCE(__VALUE__) (((__VALUE__) == LL_RCC_CEC_CLKSOURCE)) #define IS_LL_RCC_USBPHY_CLKSOURCE(__VALUE__) (((__VALUE__) == LL_RCC_USBPHY_CLKSOURCE)) #define IS_LL_RCC_USBO_CLKSOURCE(__VALUE__) (((__VALUE__) == LL_RCC_USBO_CLKSOURCE)) #define IS_LL_RCC_RNG_CLKSOURCE(__VALUE__) (((__VALUE__) == LL_RCC_RNG1_CLKSOURCE) \ || ((__VALUE__) == LL_RCC_RNG2_CLKSOURCE)) #define IS_LL_RCC_CKPER_CLKSOURCE(__VALUE__) (((__VALUE__) == LL_RCC_CKPER_CLKSOURCE)) #define IS_LL_RCC_STGEN_CLKSOURCE(__VALUE__) (((__VALUE__) == LL_RCC_STGEN_CLKSOURCE)) #if defined(DSI) #define IS_LL_RCC_DSI_CLKSOURCE(__VALUE__) (((__VALUE__) == LL_RCC_DSI_CLKSOURCE)) #endif /*DSI*/ #define IS_LL_RCC_ADC_CLKSOURCE(__VALUE__) (((__VALUE__) == LL_RCC_ADC_CLKSOURCE)) #define IS_LL_RCC_LPTIM_CLKSOURCE(__VALUE__) (((__VALUE__) == LL_RCC_LPTIM1_CLKSOURCE) \ || ((__VALUE__) == LL_RCC_LPTIM23_CLKSOURCE) \ || ((__VALUE__) == LL_RCC_LPTIM45_CLKSOURCE)) #define IS_LL_RCC_DFSDM_CLKSOURCE(__VALUE__) (((__VALUE__) == LL_RCC_DFSDM_CLKSOURCE)) #define IS_LL_RCC_TIMGPRES(__VALUE__) (((__VALUE__) == LL_RCC_TIMG1PRES) \ || ((__VALUE__) == LL_RCC_TIMG2PRES)) /** * @} */ /* Private function prototypes -----------------------------------------------*/ /** @defgroup RCC_LL_Private_Functions RCC Private functions * @{ */ uint32_t RCC_GetMPUSSClockFreq(void); uint32_t RCC_GetAXISSClockFreq(void); uint32_t RCC_GetMCUSSClockFreq(void); uint32_t RCC_GetACLKClockFreq(uint32_t AXISS_Frequency); uint32_t RCC_GetMLHCLKClockFreq(uint32_t MCUSS_Frequency); uint32_t RCC_GetPCLK1ClockFreq(uint32_t MLHCLK_Frequency); uint32_t RCC_GetPCLK2ClockFreq(uint32_t MLHCLK_Frequency); uint32_t RCC_GetPCLK3ClockFreq(uint32_t MLHCLK_Frequency); uint32_t RCC_GetPCLK4ClockFreq(uint32_t ACLK_Frequency); uint32_t RCC_GetPCLK5ClockFreq(uint32_t ACLK_Frequency); /** * @} */ /* Exported functions --------------------------------------------------------*/ /** @addtogroup RCC_LL_Exported_Functions * @{ */ /** @addtogroup RCC_LL_EF_Init * @{ */ /** * @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, CSI, PLL1, PLL2, PLL3 and PLL4 OFF * - AHBs and APBs bus pre-scalers set to 1. * - MCO1 and MCO2 OFF * - All interrupts disabled (except Wake-up from CSTOP Interrupt Enable) * @note This function doesn't modify the configuration of the * - Peripheral clocks * - LSI, LSE and RTC clocks * - HSECSS and LSECSS * @retval An ErrorStatus enumeration value: * - SUCCESS: RCC registers are de-initialized * - ERROR: not applicable */ ErrorStatus LL_RCC_DeInit(void) { /* Set HSION bit */ LL_RCC_HSI_Enable(); /* Insure HSIRDY bit is set before writing default MSIRANGE value */ while (LL_RCC_HSI_IsReady() == 0U) {} /* Reset MPU Clock Selection */ LL_RCC_SetMPUClkSource(LL_RCC_MPU_CLKSOURCE_HSI); /* Reset AXI Sub-System Clock Selection */ LL_RCC_SetAXISSClkSource(LL_RCC_AXISS_CLKSOURCE_HSI); /* Reset MCU Sub-System Clock Selection */ LL_RCC_SetMCUSSClkSource(LL_RCC_MCUSS_CLKSOURCE_HSI); /* Reset RCC MPU Clock Divider */ LL_RCC_SetMPUPrescaler(LL_RCC_MPU_DIV_2); /* Reset RCC ACLK (ACLK, HCLK5 and HCLK6) Clock Divider */ LL_RCC_SetACLKPrescaler(LL_RCC_AXI_DIV_1); /* Reset RCC APB4 Clock Divider */ LL_RCC_SetAPB4Prescaler(LL_RCC_APB4_DIV_1); /* Reset RCC APB5 Clock Divider */ LL_RCC_SetAPB5Prescaler(LL_RCC_APB5_DIV_1); /* Reset RCC MLHCLK (MLHCLK, MCU, FCLK, HCLK4, HCLK3, HCLK2 and HCLK1) Clock Divider */ LL_RCC_SetMLHCLKPrescaler(LL_RCC_MCU_DIV_1); /* Reset RCC APB1 Clock Divider */ LL_RCC_SetAPB1Prescaler(LL_RCC_APB1_DIV_1); /* Reset RCC APB2 Clock Divider */ LL_RCC_SetAPB2Prescaler(LL_RCC_APB2_DIV_1); /* Reset RCC APB3 Clock Divider */ LL_RCC_SetAPB3Prescaler(LL_RCC_APB3_DIV_1); /* Reset MCO1 Configuration */ CLEAR_BIT(RCC->MCO1CFGR, RCC_MCO1CFGR_MCO1ON); LL_RCC_ConfigMCO(LL_RCC_MCO1SOURCE_HSI, LL_RCC_MCO1_DIV_1); /* Reset MCO2 Configuration */ CLEAR_BIT(RCC->MCO2CFGR, RCC_MCO2CFGR_MCO2ON); LL_RCC_ConfigMCO(LL_RCC_MCO2SOURCE_MPU, LL_RCC_MCO2_DIV_1); /* Disable PLL1 outputs */ CLEAR_BIT(RCC->PLL1CR, RCC_PLL1CR_DIVPEN | RCC_PLL1CR_DIVQEN | RCC_PLL1CR_DIVREN); /* Disable PLL1 */ CLEAR_BIT(RCC->PLL1CR, RCC_PLL1CR_PLLON); /* Wait for PLL1 READY bit to be reset */ while (LL_RCC_PLL1_IsReady() != 0U) {} /* Clear remaining SSCG_CTRL bit */ LL_RCC_PLL1CSG_Disable(); /* Disable PLL2 outputs */ CLEAR_BIT(RCC->PLL2CR, RCC_PLL2CR_DIVPEN | RCC_PLL2CR_DIVQEN | RCC_PLL2CR_DIVREN); /* Disable PLL2 */ CLEAR_BIT(RCC->PLL2CR, RCC_PLL2CR_PLLON); /* Wait for PLL2 READY bit to be reset */ while (LL_RCC_PLL2_IsReady() != 0U) {} /* Clear remaining SSCG_CTRL bit */ LL_RCC_PLL2CSG_Disable(); /* Disable PLL3 outputs */ CLEAR_BIT(RCC->PLL3CR, RCC_PLL3CR_DIVPEN | RCC_PLL3CR_DIVQEN | RCC_PLL3CR_DIVREN); /* Disable PLL3 */ CLEAR_BIT(RCC->PLL3CR, RCC_PLL3CR_PLLON); /* Wait for PLL3 READY bit to be reset */ while (LL_RCC_PLL3_IsReady() != 0U) {} /* Clear remaining SSCG_CTRL bit */ LL_RCC_PLL3CSG_Disable(); /* Disable PLL4 outputs */ CLEAR_BIT(RCC->PLL4CR, RCC_PLL4CR_DIVPEN | RCC_PLL4CR_DIVQEN | RCC_PLL4CR_DIVREN); /* Disable PLL4 */ CLEAR_BIT(RCC->PLL4CR, RCC_PLL4CR_PLLON); /* Wait for PLL4 READY bit to be reset */ while (LL_RCC_PLL4_IsReady() != 0U) {} /* Clear remaining SSCG_CTRL bit */ LL_RCC_PLL4CSG_Disable(); /* Clear remaining SSCG_CTRL bit */ CLEAR_BIT(RCC->PLL4CR, RCC_PLL4CR_SSCG_CTRL); /* Reset PLL 1 and 2 Ref. Clock Selection Register */ MODIFY_REG(RCC->RCK12SELR, (RCC_RCK12SELR_PLL12SRC), RCC_RCK12SELR_PLL12SRC_0); /* Reset RCC PLL 3 Ref. Clock Selection Register */ MODIFY_REG(RCC->RCK3SELR, (RCC_RCK3SELR_PLL3SRC), RCC_RCK3SELR_PLL3SRC_0); /* Reset PLL4 Ref. Clock Selection Register */ MODIFY_REG(RCC->RCK4SELR, (RCC_RCK4SELR_PLL4SRC), RCC_RCK4SELR_PLL4SRC_0); /* Reset RCC PLL1 Configuration Register 1 */ WRITE_REG(RCC->PLL1CFGR1, 0x00010031U); /* Reset RCC PLL1 Configuration Register 2 */ WRITE_REG(RCC->PLL1CFGR2, 0x00010100U); /* Reset RCC PLL1 Fractional Register */ CLEAR_REG(RCC->PLL1FRACR); /* Reset RCC PLL1 Clock Spreading Generator Register */ CLEAR_REG(RCC->PLL1CSGR); /* Reset RCC PLL2 Configuration Register 1 */ WRITE_REG(RCC->PLL2CFGR1, 0x00010063U); /* Reset RCC PLL2 Configuration Register 2 */ WRITE_REG(RCC->PLL2CFGR2, 0x00010101U); /* Reset RCC PLL2 Fractional Register */ CLEAR_REG(RCC->PLL2FRACR); /* Reset RCC PLL2 Clock Spreading Generator Register */ CLEAR_REG(RCC->PLL2CSGR); /* Reset RCC PLL3 Configuration Register 1 */ WRITE_REG(RCC->PLL3CFGR1, 0x00010031U); /* Reset RCC PLL3 Configuration Register 2 */ WRITE_REG(RCC->PLL3CFGR2, 0x00010101U); /* Reset RCC PLL3 Fractional Register */ CLEAR_REG(RCC->PLL3FRACR); /* Reset RCC PLL3 Clock Spreading Generator Register */ CLEAR_REG(RCC->PLL3CSGR); /* Reset RCC PLL4 Configuration Register 1 */ WRITE_REG(RCC->PLL4CFGR1, 0x00010031U); /* Reset RCC PLL4 Configuration Register 2 */ WRITE_REG(RCC->PLL4CFGR2, 0x00000000U); /* Reset RCC PLL4 Fractional Register */ CLEAR_REG(RCC->PLL4FRACR); /* Reset RCC PLL4 Clock Spreading Generator Register */ CLEAR_REG(RCC->PLL4CSGR); /* Reset HSIDIV once PLLs are off */ LL_RCC_HSI_SetDivider(LL_RCC_HSI_DIV_1); /* Wait for HSIDIV READY bit to set */ while (LL_RCC_HSI_IsDividerReady() != 1U) {} /* Set HSITRIM bits to the reset value*/ LL_RCC_HSI_SetCalibTrimming(0x0U); /* Reset the Oscillator Enable Control registers */ WRITE_REG(RCC->OCENCLRR, RCC_OCENCLRR_HSIKERON | RCC_OCENCLRR_CSION | RCC_OCENCLRR_CSIKERON | RCC_OCENCLRR_DIGBYP | RCC_OCENCLRR_HSEON | RCC_OCENCLRR_HSEKERON | RCC_OCENCLRR_HSEBYP); /* Reset CSITRIM value */ LL_RCC_CSI_SetCalibTrimming(0x10U); #ifdef CORE_CM4 /* Reset RCC Clock Source Interrupt Enable Register */ CLEAR_BIT(RCC->MC_CIER, (RCC_MC_CIER_LSIRDYIE | RCC_MC_CIER_LSERDYIE | RCC_MC_CIER_HSIRDYIE | RCC_MC_CIER_HSERDYIE | RCC_MC_CIER_CSIRDYIE | RCC_MC_CIER_PLL1DYIE | RCC_MC_CIER_PLL2DYIE | RCC_MC_CIER_PLL3DYIE | RCC_MC_CIER_PLL4DYIE | RCC_MC_CIER_LSECSSIE | RCC_MC_CIER_WKUPIE)); /* Clear all RCC MCU interrupt flags */ SET_BIT(RCC->MC_CIFR, (RCC_MC_CIFR_LSIRDYF | RCC_MC_CIFR_LSERDYF | RCC_MC_CIFR_HSIRDYF | RCC_MC_CIFR_HSERDYF | RCC_MC_CIFR_CSIRDYF | RCC_MC_CIFR_PLL1DYF | RCC_MC_CIFR_PLL2DYF | RCC_MC_CIFR_PLL3DYF | RCC_MC_CIFR_PLL4DYF | RCC_MC_CIFR_LSECSSF)); /* Clear all RCC MCU Reset Flags */ SET_BIT(RCC->MC_RSTSCLRR, RCC_MC_RSTSCLRR_WWDG1RSTF | RCC_MC_RSTSCLRR_IWDG2RSTF | RCC_MC_RSTSCLRR_IWDG1RSTF | RCC_MC_RSTSCLRR_MCSYSRSTF | RCC_MC_RSTSCLRR_MPSYSRSTF | RCC_MC_RSTSCLRR_MCURSTF | RCC_MC_RSTSCLRR_VCORERSTF | RCC_MC_RSTSCLRR_HCSSRSTF | RCC_MC_RSTSCLRR_PADRSTF | RCC_MC_RSTSCLRR_BORRSTF | RCC_MC_RSTSCLRR_PORRSTF); #endif return SUCCESS; } /** * @} */ /** @addtogroup RCC_LL_EF_Get_Freq * @brief Return the frequencies of different on chip clocks; MPUSS, AXISS, * MCUSS, ACLK, MLHCLK, APB[5:1] AHB[6:1] and MCU buses clocks and * different peripheral clocks available on the device. * @note If MCUSS source is CSI, function returns values based on CSI_VALUE(*) * @note If MPUSS/AXISS/MCUSS source is HSI, function returns values based on HSI_VALUE(**) * @note If MPUSS/AXISS/MCUSS source is HSE, function returns values based on HSE_VALUE(***) * @note If MPUSS/AXISS/MCUSS source is PLLx, function returns values based * on HSE_VALUE(***), or HSI_VALUE(**) or CSI_VALUE(*) or EXTERNAL_CLOCK_VALUE(****) * multiplied/divided by the PLLx factors where 'PLLx' can be PLL1, PLL2 * or PLL3. * @note (*) CSI_VALUE is a constant defined in this file (default value * 4 MHz) but the real value may vary depending on the variations * in voltage and temperature. * @note (**) HSI_VALUE is a constant defined in this file (default value * 64 MHz) but the real value may vary depending on the variations * in voltage and temperature. * @note (***) HSE_VALUE is a constant defined in this file (default value * 24 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 (****) EXTERNAL_CLOCK_VALUE is a constant defined in this file * (default value 12.288 MHz), user has to ensure that * EXTERNAL_CLOCK_VALUE is same as the real frequency of the * I2S_CKIN external oscillator used. Otherwise, this function may * have wrong result. * @note The result of this function could be incorrect when using fractional * value for HSE crystal. * @note This function can be used by the user application to compute the * baud-rate for the communication peripherals or configure other parameters. * @{ */ /** * @brief Return the frequencies of different on chip clocks; MPUSS, AXISS, * MCUSS, ACLK, MLHCLK, APB[5:1] AHB[6:1] and MCU buses clocks. * @note Each time MPUSS, AXISS, MCUSS, ACLK, MLHCLK, APB[5:1] AHB[6:1] and/or * MCU clock changes, this function must be called to update structure * fields. Otherwise, any configuration based on this function will * be incorrect. * @param RCC_Clocks pointer to a @ref LL_RCC_ClocksTypeDef structure which * will hold the clocks frequencies. * @retval None */ void LL_RCC_GetSystemClocksFreq(LL_RCC_ClocksTypeDef *RCC_Clocks) { /*!< MPUSS clock frequency */ RCC_Clocks->MPUSS_Frequency = RCC_GetMPUSSClockFreq(); /*!< AXISS clock frequency */ RCC_Clocks->AXISS_Frequency = RCC_GetAXISSClockFreq(); /*!< MCUSS clock frequency */ RCC_Clocks->MCUSS_Frequency = RCC_GetMCUSSClockFreq(); /*!< ACLK clock frequency */ RCC_Clocks->ACLK_Frequency = RCC_GetACLKClockFreq(RCC_Clocks->AXISS_Frequency); /*!< MLHCLK clock frequency */ RCC_Clocks->MLHCLK_Frequency = RCC_GetMLHCLKClockFreq(RCC_Clocks->MCUSS_Frequency); /*!< PCLK1 clock frequency */ RCC_Clocks->PCLK1_Frequency = RCC_GetPCLK1ClockFreq(RCC_Clocks->MLHCLK_Frequency); /*!< PCLK2 clock frequency */ RCC_Clocks->PCLK2_Frequency = RCC_GetPCLK2ClockFreq(RCC_Clocks->MLHCLK_Frequency); /*!< PCLK3 clock frequency */ RCC_Clocks->PCLK3_Frequency = RCC_GetPCLK3ClockFreq(RCC_Clocks->MLHCLK_Frequency); /*!< PCLK4 clock frequency */ RCC_Clocks->PCLK4_Frequency = RCC_GetPCLK4ClockFreq(RCC_Clocks->ACLK_Frequency); /*!< PCLK5 clock frequency */ RCC_Clocks->PCLK5_Frequency = RCC_GetPCLK5ClockFreq(RCC_Clocks->ACLK_Frequency); /*!< HCLK1 clock frequency */ RCC_Clocks->HCLK1_Frequency = RCC_Clocks->MLHCLK_Frequency; /*!< HCLK2 clock frequency */ RCC_Clocks->HCLK2_Frequency = RCC_Clocks->MLHCLK_Frequency; /*!< HCLK3 clock frequency */ RCC_Clocks->HCLK3_Frequency = RCC_Clocks->MLHCLK_Frequency; /*!< HCLK4 clock frequency */ RCC_Clocks->HCLK4_Frequency = RCC_Clocks->MLHCLK_Frequency; /*!< MCU clock frequency */ RCC_Clocks->MCU_Frequency = RCC_Clocks->MLHCLK_Frequency; /*!< HCLK5 clock frequency */ RCC_Clocks->HCLK5_Frequency = RCC_Clocks->ACLK_Frequency; /*!< HCLK6 clock frequency */ RCC_Clocks->HCLK6_Frequency = RCC_Clocks->ACLK_Frequency; } /** * @brief Return PLL1 clocks frequencies * @note LL_RCC_PERIPH_FREQUENCY_NO returned for non activated output or * oscillator not ready. * For PLL1Q and PLL1R LL_RCC_PERIPH_FREQUENCY_NO is returned as these * outputs are not available. * @retval None */ void LL_RCC_GetPLL1ClockFreq(LL_PLL_ClocksTypeDef *PLL_Clocks) { uint32_t pllinputfreq = LL_RCC_PERIPH_FREQUENCY_NO, pllsource; uint32_t m, n, fracv = 0U; /* Fout1_ck = ((HSE_VALUE or HSI_VALUE/HSIDIV) / PLLM) * (PLLN + (FRACV/(2^13))) * Where Fout1_ck is the PLL1 frequency before PQR post-dividers * PLL_P_Frequency = Fout1_ck/DIVP (if output enabled) */ pllsource = LL_RCC_PLL12_GetSource(); switch (pllsource) { case LL_RCC_PLL12SOURCE_HSI: if (LL_RCC_HSI_IsReady() != 0U) { pllinputfreq = HSI_VALUE >> LL_RCC_HSI_GetDivider(); } break; case LL_RCC_PLL12SOURCE_HSE: if (LL_RCC_HSE_IsReady() != 0U) { pllinputfreq = HSE_VALUE; } break; case LL_RCC_PLL12SOURCE_NONE: default: /* PLL12 clock disabled */ break; } PLL_Clocks->PLL_P_Frequency = 0U; PLL_Clocks->PLL_Q_Frequency = LL_RCC_PERIPH_FREQUENCY_NO; PLL_Clocks->PLL_R_Frequency = LL_RCC_PERIPH_FREQUENCY_NO; m = LL_RCC_PLL1_GetM(); n = LL_RCC_PLL1_GetN(); if (LL_RCC_PLL1FRACV_IsEnabled() != 0U) { fracv = LL_RCC_PLL1_GetFRACV(); } if (m != 0U) { if (LL_RCC_PLL1P_IsEnabled() != 0U) { PLL_Clocks->PLL_P_Frequency = LL_RCC_CalcPLLClockFreq(pllinputfreq, m, n, fracv, LL_RCC_PLL1_GetP()); } } } /** * @brief Return PLL2 clocks frequencies * @note LL_RCC_PERIPH_FREQUENCY_NO returned for non activated output or * oscillator not ready * @retval None */ void LL_RCC_GetPLL2ClockFreq(LL_PLL_ClocksTypeDef *PLL_Clocks) { uint32_t pllinputfreq = LL_RCC_PERIPH_FREQUENCY_NO, pllsource; uint32_t m, n, fracv = 0U; /* Fout2_ck = ((HSE_VALUE or HSI_VALUE/HSIDIV) / PLLM) * (PLLN + (FRACV/(2^13))) * Where Fout2_ck is the PLL2 frequency before PQR post-dividers * PLL_P_Frequency = Fout2_ck/DIVP (if output enabled) * PLL_Q_Frequency = Fout2_ck/DIVQ (if output enabled) * PLL_R_Frequency = Fout2_ck/DIVR (if output enabled) */ pllsource = LL_RCC_PLL12_GetSource(); switch (pllsource) { case LL_RCC_PLL12SOURCE_HSI: if (LL_RCC_HSI_IsReady() != 0U) { pllinputfreq = HSI_VALUE >> LL_RCC_HSI_GetDivider(); } break; case LL_RCC_PLL12SOURCE_HSE: if (LL_RCC_HSE_IsReady() != 0U) { pllinputfreq = HSE_VALUE; } break; case LL_RCC_PLL12SOURCE_NONE: default: /* PLL12 clock disabled */ break; } PLL_Clocks->PLL_P_Frequency = 0U; PLL_Clocks->PLL_Q_Frequency = 0U; PLL_Clocks->PLL_R_Frequency = 0U; m = LL_RCC_PLL2_GetM(); n = LL_RCC_PLL2_GetN(); if (LL_RCC_PLL2FRACV_IsEnabled() != 0U) { fracv = LL_RCC_PLL2_GetFRACV(); } if (m != 0U) { if (LL_RCC_PLL2P_IsEnabled() != 0U) { PLL_Clocks->PLL_P_Frequency = LL_RCC_CalcPLLClockFreq(pllinputfreq, m, n, fracv, LL_RCC_PLL2_GetP()); } if (LL_RCC_PLL2Q_IsEnabled() != 0U) { PLL_Clocks->PLL_Q_Frequency = LL_RCC_CalcPLLClockFreq(pllinputfreq, m, n, fracv, LL_RCC_PLL2_GetQ()); } if (LL_RCC_PLL2R_IsEnabled() != 0U) { PLL_Clocks->PLL_R_Frequency = LL_RCC_CalcPLLClockFreq(pllinputfreq, m, n, fracv, LL_RCC_PLL2_GetR()); } } } /** * @brief Return PLL3 clocks frequencies * @note LL_RCC_PERIPH_FREQUENCY_NO returned for non activated output or * oscillator not ready * @retval None */ void LL_RCC_GetPLL3ClockFreq(LL_PLL_ClocksTypeDef *PLL_Clocks) { uint32_t pllinputfreq = LL_RCC_PERIPH_FREQUENCY_NO, pllsource; uint32_t m, n, fracv = 0U; /* Fout3_ck = ((HSE_VALUE, CSI_VALUE or HSI_VALUE/HSIDIV) / PLLM) * (PLLN + (FRACV/(2^13))) * Where Fout3_ck is the PLL3 frequency before PQR post-dividers * PLL_P_Frequency = Fout3_ck/DIVP (if output enabled) * PLL_Q_Frequency = Fout3_ck/DIVQ (if output enabled) * PLL_R_Frequency = Fout3_ck/DIVR (if output enabled) */ pllsource = LL_RCC_PLL3_GetSource(); switch (pllsource) { case LL_RCC_PLL3SOURCE_HSI: if (LL_RCC_HSI_IsReady() != 0U) { pllinputfreq = HSI_VALUE >> LL_RCC_HSI_GetDivider(); } break; case LL_RCC_PLL3SOURCE_HSE: if (LL_RCC_HSE_IsReady() != 0U) { pllinputfreq = HSE_VALUE; } break; case LL_RCC_PLL3SOURCE_CSI: if (LL_RCC_CSI_IsReady() != 0U) { pllinputfreq = CSI_VALUE; } break; case LL_RCC_PLL3SOURCE_NONE: default: /* PLL3 clock disabled */ break; } PLL_Clocks->PLL_P_Frequency = 0U; PLL_Clocks->PLL_Q_Frequency = 0U; PLL_Clocks->PLL_R_Frequency = 0U; m = LL_RCC_PLL3_GetM(); n = LL_RCC_PLL3_GetN(); if (LL_RCC_PLL3FRACV_IsEnabled() != 0U) { fracv = LL_RCC_PLL3_GetFRACV(); } if (m != 0U) { if (LL_RCC_PLL3P_IsEnabled() != 0U) { PLL_Clocks->PLL_P_Frequency = LL_RCC_CalcPLLClockFreq(pllinputfreq, m, n, fracv, LL_RCC_PLL3_GetP()); } if (LL_RCC_PLL3Q_IsEnabled() != 0U) { PLL_Clocks->PLL_Q_Frequency = LL_RCC_CalcPLLClockFreq(pllinputfreq, m, n, fracv, LL_RCC_PLL3_GetQ()); } if (LL_RCC_PLL3R_IsEnabled() != 0U) { PLL_Clocks->PLL_R_Frequency = LL_RCC_CalcPLLClockFreq(pllinputfreq, m, n, fracv, LL_RCC_PLL3_GetR()); } } } /** * @brief Return PLL4 clocks frequencies * @note LL_RCC_PERIPH_FREQUENCY_NO returned for non activated output or * oscillator not ready * @retval None */ void LL_RCC_GetPLL4ClockFreq(LL_PLL_ClocksTypeDef *PLL_Clocks) { uint32_t pllinputfreq = LL_RCC_PERIPH_FREQUENCY_NO, pllsource; uint32_t m, n, fracv = 0U; /* Fout4_ck = ((HSE_VALUE, CSI_VALUE, EXTERNAL_CLOCK_VALUE or HSI_VALUE/HSIDIV) / PLLM) * (PLLN + (FRACV/(2^13))) * Where Fout4_ck is the PLL4 frequency before PQR post-dividers * PLL_P_Frequency = Fout4_ck/DIVP (if output enabled) * PLL_Q_Frequency = Fout4_ck/DIVQ (if output enabled) * PLL_R_Frequency = Fout4_ck/DIVR (if output enabled) */ pllsource = LL_RCC_PLL4_GetSource(); switch (pllsource) { case LL_RCC_PLL4SOURCE_HSI: if (LL_RCC_HSI_IsReady() != 0U) { pllinputfreq = HSI_VALUE >> LL_RCC_HSI_GetDivider(); } break; case LL_RCC_PLL4SOURCE_HSE: if (LL_RCC_HSE_IsReady() != 0U) { pllinputfreq = HSE_VALUE; } break; case LL_RCC_PLL4SOURCE_CSI: if (LL_RCC_HSE_IsReady() != 0U) { pllinputfreq = HSE_VALUE; } break; case LL_RCC_PLL4SOURCE_I2SCKIN: pllinputfreq = EXTERNAL_CLOCK_VALUE; break; } PLL_Clocks->PLL_P_Frequency = 0U; PLL_Clocks->PLL_Q_Frequency = 0U; PLL_Clocks->PLL_R_Frequency = 0U; m = LL_RCC_PLL4_GetM(); n = LL_RCC_PLL4_GetN(); if (LL_RCC_PLL4FRACV_IsEnabled() != 0U) { fracv = LL_RCC_PLL4_GetFRACV(); } if (m != 0U) { if (LL_RCC_PLL4P_IsEnabled() != 0U) { PLL_Clocks->PLL_P_Frequency = LL_RCC_CalcPLLClockFreq(pllinputfreq, m, n, fracv, LL_RCC_PLL4_GetP()); } if (LL_RCC_PLL4Q_IsEnabled() != 0U) { PLL_Clocks->PLL_Q_Frequency = LL_RCC_CalcPLLClockFreq(pllinputfreq, m, n, fracv, LL_RCC_PLL4_GetQ()); } if (LL_RCC_PLL4R_IsEnabled() != 0U) { PLL_Clocks->PLL_R_Frequency = LL_RCC_CalcPLLClockFreq(pllinputfreq, m, n, fracv, LL_RCC_PLL4_GetR()); } } } /** * @brief Helper function to calculate the PLL frequency output * @note ex: @ref LL_RCC_CalcPLLClockFreq (HSE_VALUE, @ref LL_RCC_PLL1_GetM (), * @ref LL_RCC_PLL1_GetN (), @ref LL_RCC_PLL1_GetFRACV (), @ref LL_RCC_PLL1_GetP ()); * @param PLLInputFreq PLL Input frequency (based on HSE/(HSI/HSIDIV)/CSI/I2SCKIN) * @param M Between 1 and 64 * @param N Between 4 and 512 on fractional mode (PLL1, PLL2, PLL3 and PLL4). * Between 25 and 100 on integer mode for PLL1 and PLL2. * Between 25 and 200 on integer mode for PLL3 and PLL4. * @param FRACV Between 0 and 0x1FFF * @param PQR VCO output divider (P, Q or R) * Between 1 and 128. For PLL1 and PLL2, only the bypass * (division by 1) and even divisions are allowed. For PLL3, * only the even divisions are allowed. If those conditions are * not respected the behavior of the circuit is not guaranteed. * @retval PLL clock frequency (in Hz) */ uint32_t LL_RCC_CalcPLLClockFreq(uint32_t PLLInputFreq, uint32_t M, uint32_t N, uint32_t FRACV, uint32_t PQR) { float freq; freq = ((float)PLLInputFreq / (float)M) * ((float)N + ((float)FRACV / (float)0x2000)); freq = freq / (float)PQR; return (uint32_t)freq; } /** * @brief Return I2Cx clock frequency * @param I2CxSource This parameter can be one of the following values: * @arg @ref LL_RCC_I2C12_CLKSOURCE * @arg @ref LL_RCC_I2C35_CLKSOURCE * @arg @ref LL_RCC_I2C46_CLKSOURCE * @retval I2C clock frequency (in Hz) * - @ref LL_RCC_PERIPH_FREQUENCY_NO indicates that oscillator is not ready */ uint32_t LL_RCC_GetI2CClockFreq(uint32_t I2CxSource) { uint32_t i2c_frequency = LL_RCC_PERIPH_FREQUENCY_NO; LL_PLL_ClocksTypeDef PLL_Clocks; /* Check parameter */ assert_param(IS_LL_RCC_I2C_CLKSOURCE(I2CxSource)); switch (LL_RCC_GetI2CClockSource(I2CxSource)) { case LL_RCC_I2C12_CLKSOURCE_PCLK1: case LL_RCC_I2C35_CLKSOURCE_PCLK1: i2c_frequency = RCC_GetPCLK1ClockFreq(RCC_GetMLHCLKClockFreq(RCC_GetMCUSSClockFreq())); break; case LL_RCC_I2C12_CLKSOURCE_PLL4R: case LL_RCC_I2C35_CLKSOURCE_PLL4R: if (LL_RCC_PLL4_IsReady() != 0U) { LL_RCC_GetPLL4ClockFreq(&PLL_Clocks); i2c_frequency = PLL_Clocks.PLL_R_Frequency; } break; case LL_RCC_I2C12_CLKSOURCE_HSI: case LL_RCC_I2C35_CLKSOURCE_HSI: case LL_RCC_I2C46_CLKSOURCE_HSI: if (LL_RCC_HSI_IsReady() != 0U) { i2c_frequency = HSI_VALUE >> LL_RCC_HSI_GetDivider(); } break; case LL_RCC_I2C12_CLKSOURCE_CSI: case LL_RCC_I2C35_CLKSOURCE_CSI: case LL_RCC_I2C46_CLKSOURCE_CSI: if (LL_RCC_CSI_IsReady() != 0U) { i2c_frequency = CSI_VALUE; } break; case LL_RCC_I2C46_CLKSOURCE_PCLK5: i2c_frequency = RCC_GetPCLK5ClockFreq(RCC_GetACLKClockFreq(RCC_GetAXISSClockFreq())); break; case LL_RCC_I2C46_CLKSOURCE_PLL3Q: if (LL_RCC_PLL3_IsReady() != 0U) { LL_RCC_GetPLL3ClockFreq(&PLL_Clocks); i2c_frequency = PLL_Clocks.PLL_Q_Frequency; } break; default: /* Nothing to do */ break; } return i2c_frequency; } /** * @brief Return SAIx clock frequency * @param SAIxSource This parameter can be one of the following values: * @arg @ref LL_RCC_SAI1_CLKSOURCE * @arg @ref LL_RCC_SAI2_CLKSOURCE * @arg @ref LL_RCC_SAI3_CLKSOURCE * @arg @ref LL_RCC_SAI4_CLKSOURCE * @retval SAI clock frequency (in Hz) * - @ref LL_RCC_PERIPH_FREQUENCY_NO indicates that oscillator is not ready */ uint32_t LL_RCC_GetSAIClockFreq(uint32_t SAIxSource) { uint32_t sai_frequency = LL_RCC_PERIPH_FREQUENCY_NO; LL_PLL_ClocksTypeDef PLL_Clocks; /* Check parameter */ assert_param(IS_LL_RCC_SAI_CLKSOURCE(SAIxSource)); switch (LL_RCC_GetSAIClockSource(SAIxSource)) { case LL_RCC_SAI1_CLKSOURCE_PLL4Q: case LL_RCC_SAI2_CLKSOURCE_PLL4Q: case LL_RCC_SAI3_CLKSOURCE_PLL4Q: case LL_RCC_SAI4_CLKSOURCE_PLL4Q: if (LL_RCC_PLL4_IsReady() != 0U) { LL_RCC_GetPLL4ClockFreq(&PLL_Clocks); sai_frequency = PLL_Clocks.PLL_Q_Frequency; } break; case LL_RCC_SAI1_CLKSOURCE_PLL3Q: case LL_RCC_SAI2_CLKSOURCE_PLL3Q: case LL_RCC_SAI3_CLKSOURCE_PLL3Q: case LL_RCC_SAI4_CLKSOURCE_PLL3Q: if (LL_RCC_PLL3_IsReady() != 0U) { LL_RCC_GetPLL3ClockFreq(&PLL_Clocks); sai_frequency = PLL_Clocks.PLL_Q_Frequency; } break; case LL_RCC_SAI1_CLKSOURCE_I2SCKIN: case LL_RCC_SAI2_CLKSOURCE_I2SCKIN: case LL_RCC_SAI3_CLKSOURCE_I2SCKIN: case LL_RCC_SAI4_CLKSOURCE_I2SCKIN: sai_frequency = EXTERNAL_CLOCK_VALUE; break; case LL_RCC_SAI1_CLKSOURCE_PER: case LL_RCC_SAI2_CLKSOURCE_PER: case LL_RCC_SAI3_CLKSOURCE_PER: case LL_RCC_SAI4_CLKSOURCE_PER: sai_frequency = LL_RCC_GetCKPERClockFreq(LL_RCC_CKPER_CLKSOURCE); break; case LL_RCC_SAI1_CLKSOURCE_PLL3R: case LL_RCC_SAI2_CLKSOURCE_PLL3R: case LL_RCC_SAI3_CLKSOURCE_PLL3R: case LL_RCC_SAI4_CLKSOURCE_PLL3R: if (LL_RCC_PLL3_IsReady() != 0U) { LL_RCC_GetPLL3ClockFreq(&PLL_Clocks); sai_frequency = PLL_Clocks.PLL_R_Frequency; } break; case LL_RCC_SAI2_CLKSOURCE_SPDIF: //SAI2 manages this SPDIF_CKSYMB_VALUE default: /* Nothing to do */ break; } return sai_frequency; } /** * @brief Return SPIx clock frequency * @param SPIxSource This parameter can be one of the following values: * @arg @ref LL_RCC_SPI1_CLKSOURCE * @arg @ref LL_RCC_SPI23_CLKSOURCE * @arg @ref LL_RCC_SPI45_CLKSOURCE * @arg @ref LL_RCC_SPI6_CLKSOURCE * @retval SPI clock frequency (in Hz) * - @ref LL_RCC_PERIPH_FREQUENCY_NO indicates that oscillator is not ready */ uint32_t LL_RCC_GetSPIClockFreq(uint32_t SPIxSource) { uint32_t spi_frequency = LL_RCC_PERIPH_FREQUENCY_NO; LL_PLL_ClocksTypeDef PLL_Clocks; /* Check parameter */ assert_param(IS_LL_RCC_SPI_CLKSOURCE(SPIxSource)); switch (LL_RCC_GetSPIClockSource(SPIxSource)) { case LL_RCC_SPI1_CLKSOURCE_PLL4P: case LL_RCC_SPI23_CLKSOURCE_PLL4P: if (LL_RCC_PLL4_IsReady() != 0U) { LL_RCC_GetPLL4ClockFreq(&PLL_Clocks); spi_frequency = PLL_Clocks.PLL_P_Frequency; } break; case LL_RCC_SPI1_CLKSOURCE_PLL3Q: case LL_RCC_SPI23_CLKSOURCE_PLL3Q: case LL_RCC_SPI6_CLKSOURCE_PLL3Q: if (LL_RCC_PLL3_IsReady() != 0U) { LL_RCC_GetPLL3ClockFreq(&PLL_Clocks); spi_frequency = PLL_Clocks.PLL_Q_Frequency; } break; case LL_RCC_SPI1_CLKSOURCE_I2SCKIN: case LL_RCC_SPI23_CLKSOURCE_I2SCKIN: spi_frequency = EXTERNAL_CLOCK_VALUE; break; case LL_RCC_SPI1_CLKSOURCE_PER: case LL_RCC_SPI23_CLKSOURCE_PER: spi_frequency = LL_RCC_GetCKPERClockFreq(LL_RCC_CKPER_CLKSOURCE); break; case LL_RCC_SPI1_CLKSOURCE_PLL3R: case LL_RCC_SPI23_CLKSOURCE_PLL3R: if (LL_RCC_PLL3_IsReady() != 0U) { LL_RCC_GetPLL3ClockFreq(&PLL_Clocks); spi_frequency = PLL_Clocks.PLL_R_Frequency; } break; case LL_RCC_SPI45_CLKSOURCE_PCLK2: spi_frequency = RCC_GetPCLK2ClockFreq(RCC_GetMLHCLKClockFreq(RCC_GetMCUSSClockFreq())); break; case LL_RCC_SPI45_CLKSOURCE_PLL4Q: case LL_RCC_SPI6_CLKSOURCE_PLL4Q: if (LL_RCC_PLL4_IsReady() != 0U) { LL_RCC_GetPLL4ClockFreq(&PLL_Clocks); spi_frequency = PLL_Clocks.PLL_Q_Frequency; } break; case LL_RCC_SPI45_CLKSOURCE_HSI: case LL_RCC_SPI6_CLKSOURCE_HSI: if (LL_RCC_HSI_IsReady() != 0U) { spi_frequency = HSI_VALUE >> LL_RCC_HSI_GetDivider(); } break; case LL_RCC_SPI45_CLKSOURCE_CSI: case LL_RCC_SPI6_CLKSOURCE_CSI: if (LL_RCC_CSI_IsReady() != 0U) { spi_frequency = CSI_VALUE; } break; case LL_RCC_SPI45_CLKSOURCE_HSE: case LL_RCC_SPI6_CLKSOURCE_HSE: if (LL_RCC_HSE_IsReady() != 0U) { spi_frequency = HSE_VALUE; } break; case LL_RCC_SPI6_CLKSOURCE_PCLK5: spi_frequency = RCC_GetPCLK5ClockFreq(RCC_GetACLKClockFreq(RCC_GetAXISSClockFreq())); break; default: /* Nothing to do */ break; } return spi_frequency; } /** * @brief Return UARTx clock frequency * @param UARTxSource This parameter can be one of the following values: * @arg @ref LL_RCC_USART1_CLKSOURCE * @arg @ref LL_RCC_UART24_CLKSOURCE * @arg @ref LL_RCC_UART35_CLKSOURCE * @arg @ref LL_RCC_USART6_CLKSOURCE * @arg @ref LL_RCC_UART78_CLKSOURCE * @retval UART clock frequency (in Hz) * - @ref LL_RCC_PERIPH_FREQUENCY_NO indicates that oscillator is not ready */ uint32_t LL_RCC_GetUARTClockFreq(uint32_t UARTxSource) { uint32_t uart_frequency = LL_RCC_PERIPH_FREQUENCY_NO; LL_PLL_ClocksTypeDef PLL_Clocks; /* Check parameter */ assert_param(IS_LL_RCC_UART_CLKSOURCE(UARTxSource)); switch (LL_RCC_GetUARTClockSource(UARTxSource)) { case LL_RCC_USART1_CLKSOURCE_PCLK5: uart_frequency = RCC_GetPCLK5ClockFreq(RCC_GetACLKClockFreq(RCC_GetAXISSClockFreq())); break; case LL_RCC_USART1_CLKSOURCE_PLL3Q: if (LL_RCC_PLL3_IsReady() != 0U) { LL_RCC_GetPLL3ClockFreq(&PLL_Clocks); uart_frequency = PLL_Clocks.PLL_Q_Frequency; } break; case LL_RCC_USART1_CLKSOURCE_HSI: case LL_RCC_UART24_CLKSOURCE_HSI: case LL_RCC_UART35_CLKSOURCE_HSI: case LL_RCC_USART6_CLKSOURCE_HSI: case LL_RCC_UART78_CLKSOURCE_HSI: if (LL_RCC_HSI_IsReady() != 0U) { uart_frequency = HSI_VALUE >> LL_RCC_HSI_GetDivider(); } break; case LL_RCC_USART1_CLKSOURCE_CSI: case LL_RCC_UART24_CLKSOURCE_CSI: case LL_RCC_UART35_CLKSOURCE_CSI: case LL_RCC_USART6_CLKSOURCE_CSI: case LL_RCC_UART78_CLKSOURCE_CSI: if (LL_RCC_CSI_IsReady() != 0U) { uart_frequency = CSI_VALUE; } break; case LL_RCC_USART1_CLKSOURCE_PLL4Q: case LL_RCC_UART24_CLKSOURCE_PLL4Q: case LL_RCC_UART35_CLKSOURCE_PLL4Q: case LL_RCC_USART6_CLKSOURCE_PLL4Q: case LL_RCC_UART78_CLKSOURCE_PLL4Q: if (LL_RCC_PLL4_IsReady() != 0U) { LL_RCC_GetPLL4ClockFreq(&PLL_Clocks); uart_frequency = PLL_Clocks.PLL_Q_Frequency; } break; case LL_RCC_USART1_CLKSOURCE_HSE: case LL_RCC_UART24_CLKSOURCE_HSE: case LL_RCC_UART35_CLKSOURCE_HSE: case LL_RCC_USART6_CLKSOURCE_HSE: case LL_RCC_UART78_CLKSOURCE_HSE: if (LL_RCC_HSE_IsReady() != 0U) { uart_frequency = HSE_VALUE; } break; case LL_RCC_UART24_CLKSOURCE_PCLK1: case LL_RCC_UART35_CLKSOURCE_PCLK1: case LL_RCC_UART78_CLKSOURCE_PCLK1: uart_frequency = RCC_GetPCLK1ClockFreq(RCC_GetMLHCLKClockFreq(RCC_GetMCUSSClockFreq())); break; case LL_RCC_USART6_CLKSOURCE_PCLK2: uart_frequency = RCC_GetPCLK2ClockFreq(RCC_GetMLHCLKClockFreq(RCC_GetMCUSSClockFreq())); break; default: /* Nothing to do */ break; } return uart_frequency; } /** * @brief Return SDMMCx clock frequency * @param SDMMCxSource This parameter can be one of the following values: * @arg @ref LL_RCC_SDMMC12_CLKSOURCE * @arg @ref LL_RCC_SDMMC3_CLKSOURCE * @retval SDMMC clock frequency (in Hz) * - @ref LL_RCC_PERIPH_FREQUENCY_NO indicates that oscillator is not ready */ uint32_t LL_RCC_GetSDMMCClockFreq(uint32_t SDMMCxSource) { uint32_t sdmmc_frequency = LL_RCC_PERIPH_FREQUENCY_NO; LL_PLL_ClocksTypeDef PLL_Clocks; /* Check parameter */ assert_param(IS_LL_RCC_SDMMC_CLKSOURCE(SDMMCxSource)); switch (LL_RCC_GetSDMMCClockSource(SDMMCxSource)) { case LL_RCC_SDMMC12_CLKSOURCE_HCLK6: sdmmc_frequency = RCC_GetACLKClockFreq(RCC_GetAXISSClockFreq()); break; case LL_RCC_SDMMC12_CLKSOURCE_PLL3R: case LL_RCC_SDMMC3_CLKSOURCE_PLL3R: if (LL_RCC_PLL3_IsReady() != 0U) { LL_RCC_GetPLL3ClockFreq(&PLL_Clocks); sdmmc_frequency = PLL_Clocks.PLL_R_Frequency; } break; case LL_RCC_SDMMC12_CLKSOURCE_PLL4P: case LL_RCC_SDMMC3_CLKSOURCE_PLL4P: if (LL_RCC_PLL4_IsReady() != 0U) { LL_RCC_GetPLL4ClockFreq(&PLL_Clocks); sdmmc_frequency = PLL_Clocks.PLL_P_Frequency; } break; case LL_RCC_SDMMC12_CLKSOURCE_HSI: case LL_RCC_SDMMC3_CLKSOURCE_HSI: if (LL_RCC_HSI_IsReady() != 0U) { sdmmc_frequency = HSI_VALUE >> LL_RCC_HSI_GetDivider(); } break; case LL_RCC_SDMMC3_CLKSOURCE_HCLK2: sdmmc_frequency = RCC_GetMLHCLKClockFreq(RCC_GetMCUSSClockFreq()); break; default: /* Nothing to do */ break; } return sdmmc_frequency; } /** * @brief Return ETHx clock frequency * @param ETHxSource This parameter can be one of the following values: * @arg @ref LL_RCC_ETH_CLKSOURCE * @retval ETH clock frequency (in Hz) * - @ref LL_RCC_PERIPH_FREQUENCY_NO indicates that oscillator is not ready */ uint32_t LL_RCC_GetETHClockFreq(uint32_t ETHxSource) { uint32_t eth_frequency = LL_RCC_PERIPH_FREQUENCY_NO; LL_PLL_ClocksTypeDef PLL_Clocks; /* Check parameter */ assert_param(IS_LL_RCC_ETH_CLKSOURCE(ETHxSource)); switch (LL_RCC_GetETHClockSource(ETHxSource)) { case LL_RCC_ETH_CLKSOURCE_PLL4P: if (LL_RCC_PLL4_IsReady() != 0U) { LL_RCC_GetPLL4ClockFreq(&PLL_Clocks); eth_frequency = PLL_Clocks.PLL_P_Frequency; } break; case LL_RCC_ETH_CLKSOURCE_PLL3Q: if (LL_RCC_PLL3_IsReady() != 0U) { LL_RCC_GetPLL3ClockFreq(&PLL_Clocks); eth_frequency = PLL_Clocks.PLL_Q_Frequency; } break; case LL_RCC_ETH_CLKSOURCE_OFF: default: /* Nothing to do */ break; } return eth_frequency; } /** * @brief Return QSPIx clock frequency * @param QSPIxSource This parameter can be one of the following values: * @arg @ref LL_RCC_QSPI_CLKSOURCE * @retval QSPI clock frequency (in Hz) * - @ref LL_RCC_PERIPH_FREQUENCY_NO indicates that oscillator is not ready */ uint32_t LL_RCC_GetQSPIClockFreq(uint32_t QSPIxSource) { uint32_t qspi_frequency = LL_RCC_PERIPH_FREQUENCY_NO; LL_PLL_ClocksTypeDef PLL_Clocks; /* Check parameter */ assert_param(IS_LL_RCC_QSPI_CLKSOURCE(QSPIxSource)); switch (LL_RCC_GetQSPIClockSource(QSPIxSource)) { case LL_RCC_QSPI_CLKSOURCE_ACLK: qspi_frequency = RCC_GetACLKClockFreq(RCC_GetACLKClockFreq(RCC_GetAXISSClockFreq())); break; case LL_RCC_QSPI_CLKSOURCE_PLL3R: if (LL_RCC_PLL3_IsReady() != 0U) { LL_RCC_GetPLL3ClockFreq(&PLL_Clocks); qspi_frequency = PLL_Clocks.PLL_R_Frequency; } break; case LL_RCC_QSPI_CLKSOURCE_PLL4P: if (LL_RCC_PLL4_IsReady() != 0U) { LL_RCC_GetPLL4ClockFreq(&PLL_Clocks); qspi_frequency = PLL_Clocks.PLL_P_Frequency; } break; case LL_RCC_QSPI_CLKSOURCE_PER: qspi_frequency = LL_RCC_GetCKPERClockFreq(LL_RCC_CKPER_CLKSOURCE); break; default: /* Nothing to do */ break; } return qspi_frequency; } /** * @brief Return FMCx clock frequency * @param FMCxSource This parameter can be one of the following values: * @arg @ref LL_RCC_FMC_CLKSOURCE * @retval FMC clock frequency (in Hz) * - @ref LL_RCC_PERIPH_FREQUENCY_NO indicates that oscillator is not ready */ uint32_t LL_RCC_GetFMCClockFreq(uint32_t FMCxSource) { uint32_t fmc_frequency = LL_RCC_PERIPH_FREQUENCY_NO; LL_PLL_ClocksTypeDef PLL_Clocks; /* Check parameter */ assert_param(IS_LL_RCC_FMC_CLKSOURCE(FMCxSource)); switch (LL_RCC_GetFMCClockSource(FMCxSource)) { case LL_RCC_FMC_CLKSOURCE_ACLK: fmc_frequency = RCC_GetACLKClockFreq(RCC_GetACLKClockFreq(RCC_GetAXISSClockFreq())); break; case LL_RCC_FMC_CLKSOURCE_PLL3R: if (LL_RCC_PLL3_IsReady() != 0U) { LL_RCC_GetPLL3ClockFreq(&PLL_Clocks); fmc_frequency = PLL_Clocks.PLL_R_Frequency; } break; case LL_RCC_FMC_CLKSOURCE_PLL4P: if (LL_RCC_PLL4_IsReady() != 0U) { LL_RCC_GetPLL4ClockFreq(&PLL_Clocks); fmc_frequency = PLL_Clocks.PLL_P_Frequency; } break; case LL_RCC_FMC_CLKSOURCE_PER: fmc_frequency = LL_RCC_GetCKPERClockFreq(LL_RCC_CKPER_CLKSOURCE); break; default: /* Nothing to do */ break; } return fmc_frequency; } #if defined(FDCAN1) /** * @brief Return FDCANx clock frequency * @param FDCANxSource This parameter can be one of the following values: * @arg @ref LL_RCC_FDCAN_CLKSOURCE * @retval FDCAN clock frequency (in Hz) * - @ref LL_RCC_PERIPH_FREQUENCY_NO indicates that oscillator is not ready */ uint32_t LL_RCC_GetFDCANClockFreq(uint32_t FDCANxSource) { uint32_t fdcan_frequency = LL_RCC_PERIPH_FREQUENCY_NO; LL_PLL_ClocksTypeDef PLL_Clocks; /* Check parameter */ assert_param(IS_LL_RCC_FDCAN_CLKSOURCE(FDCANxSource)); switch (LL_RCC_GetFDCANClockSource(FDCANxSource)) { case LL_RCC_FDCAN_CLKSOURCE_HSE: if (LL_RCC_HSE_IsReady() != 0U) { fdcan_frequency = HSE_VALUE; } break; case LL_RCC_FDCAN_CLKSOURCE_PLL3Q: if (LL_RCC_PLL3_IsReady() != 0U) { LL_RCC_GetPLL3ClockFreq(&PLL_Clocks); fdcan_frequency = PLL_Clocks.PLL_Q_Frequency; } break; case LL_RCC_FDCAN_CLKSOURCE_PLL4Q: if (LL_RCC_PLL4_IsReady() != 0U) { LL_RCC_GetPLL4ClockFreq(&PLL_Clocks); fdcan_frequency = PLL_Clocks.PLL_Q_Frequency; } break; case LL_RCC_FDCAN_CLKSOURCE_PLL4R: if (LL_RCC_PLL4_IsReady() != 0U) { LL_RCC_GetPLL4ClockFreq(&PLL_Clocks); fdcan_frequency = PLL_Clocks.PLL_R_Frequency; } break; default: /* Nothing to do */ break; } return fdcan_frequency; } #endif /*FDCAN1*/ /** * @brief Return SPDIFRXx clock frequency * @param SPDIFRXxSource This parameter can be one of the following values: * @arg @ref LL_RCC_SPDIFRX_CLKSOURCE * @retval SPDIFRX clock frequency (in Hz) * - @ref LL_RCC_PERIPH_FREQUENCY_NO indicates that oscillator is not ready */ uint32_t LL_RCC_GetSPDIFRXClockFreq(uint32_t SPDIFRXxSource) { uint32_t spdifrx_frequency = LL_RCC_PERIPH_FREQUENCY_NO; LL_PLL_ClocksTypeDef PLL_Clocks; /* Check parameter */ assert_param(IS_LL_RCC_SPDIFRX_CLKSOURCE(SPDIFRXxSource)); switch (LL_RCC_GetSPDIFRXClockSource(SPDIFRXxSource)) { case LL_RCC_SPDIFRX_CLKSOURCE_PLL4P: if (LL_RCC_PLL4_IsReady() != 0U) { LL_RCC_GetPLL4ClockFreq(&PLL_Clocks); spdifrx_frequency = PLL_Clocks.PLL_P_Frequency; } break; case LL_RCC_SPDIFRX_CLKSOURCE_PLL3Q: if (LL_RCC_PLL3_IsReady() != 0U) { LL_RCC_GetPLL3ClockFreq(&PLL_Clocks); spdifrx_frequency = PLL_Clocks.PLL_Q_Frequency; } break; case LL_RCC_SPDIFRX_CLKSOURCE_HSI: if (LL_RCC_HSI_IsReady() != 0U) { spdifrx_frequency = HSI_VALUE >> LL_RCC_HSI_GetDivider(); } break; default: /* Nothing to do */ break; } return spdifrx_frequency; } /** * @brief Return CECx clock frequency * @param CECxSource This parameter can be one of the following values: * @arg @ref LL_RCC_CEC_CLKSOURCE * @retval CEC clock frequency (in Hz) * - @ref LL_RCC_PERIPH_FREQUENCY_NO indicates that oscillator is not ready */ uint32_t LL_RCC_GetCECClockFreq(uint32_t CECxSource) { uint32_t cec_frequency = LL_RCC_PERIPH_FREQUENCY_NO; /* Check parameter */ assert_param(IS_LL_RCC_CEC_CLKSOURCE(CECxSource)); switch (LL_RCC_GetCECClockSource(CECxSource)) { case LL_RCC_CEC_CLKSOURCE_LSE: if (LL_RCC_LSE_IsReady() != 0U) { cec_frequency = LSE_VALUE; } break; case LL_RCC_CEC_CLKSOURCE_LSI: if (LL_RCC_LSI_IsReady() != 0U) { cec_frequency = LSI_VALUE; } break; case LL_RCC_CEC_CLKSOURCE_CSI122: if (LL_RCC_CSI_IsReady() != 0U) { cec_frequency = (CSI_VALUE / 122U); } break; default: /* Nothing to do */ break; } return cec_frequency; } /** * @brief Return USBPHYx clock frequency * @param USBPHYxSource This parameter can be one of the following values: * @arg @ref LL_RCC_USBPHY_CLKSOURCE * @retval USBPHY clock frequency (in Hz) * - @ref LL_RCC_PERIPH_FREQUENCY_NO indicates that oscillator is not ready */ uint32_t LL_RCC_GetUSBPHYClockFreq(uint32_t USBPHYxSource) { uint32_t usbphy_frequency = LL_RCC_PERIPH_FREQUENCY_NO; LL_PLL_ClocksTypeDef PLL_Clocks; /* Check parameter */ assert_param(IS_LL_RCC_USBPHY_CLKSOURCE(USBPHYxSource)); switch (LL_RCC_GetUSBPHYClockSource(USBPHYxSource)) { case LL_RCC_USBPHY_CLKSOURCE_HSE: if (LL_RCC_HSE_IsReady() != 0U) { usbphy_frequency = HSE_VALUE; } break; case LL_RCC_USBPHY_CLKSOURCE_PLL4R: if (LL_RCC_PLL4_IsReady() != 0U) { LL_RCC_GetPLL4ClockFreq(&PLL_Clocks); usbphy_frequency = PLL_Clocks.PLL_R_Frequency; } break; case LL_RCC_USBPHY_CLKSOURCE_HSE2: if (LL_RCC_HSE_IsReady() != 0U) { usbphy_frequency = (HSE_VALUE / 2U); } break; default: /* Nothing to do */ break; } return usbphy_frequency; } /** * @brief Return USBOx clock frequency * @param USBOxSource This parameter can be one of the following values: * @arg @ref LL_RCC_USBO_CLKSOURCE * @retval USBO clock frequency (in Hz) * - @ref LL_RCC_PERIPH_FREQUENCY_NO indicates that oscillator is not ready */ uint32_t LL_RCC_GetUSBOClockFreq(uint32_t USBOxSource) { uint32_t usbo_frequency = LL_RCC_PERIPH_FREQUENCY_NO; LL_PLL_ClocksTypeDef PLL_Clocks; /* Check parameter */ assert_param(IS_LL_RCC_USBO_CLKSOURCE(USBOxSource)); switch (LL_RCC_GetUSBOClockSource(USBOxSource)) { case LL_RCC_USBO_CLKSOURCE_PLL4R: if (LL_RCC_PLL4_IsReady() != 0U) { LL_RCC_GetPLL4ClockFreq(&PLL_Clocks); usbo_frequency = PLL_Clocks.PLL_R_Frequency; } break; case LL_RCC_USBO_CLKSOURCE_PHY: usbo_frequency = USBO_48M_VALUE; /* rcc_ck_usbo_48m */ break; default: /* Nothing to do */ break; } return usbo_frequency; } /** * @brief Return RNGx clock frequency * @param RNGxSource This parameter can be one of the following values: * @arg @ref LL_RCC_RNG1_CLKSOURCE * @arg @ref LL_RCC_RNG2_CLKSOURCE * @retval RNG clock frequency (in Hz) * - @ref LL_RCC_PERIPH_FREQUENCY_NO indicates that oscillator is not ready */ uint32_t LL_RCC_GetRNGClockFreq(uint32_t RNGxSource) { uint32_t rng_frequency = LL_RCC_PERIPH_FREQUENCY_NO; LL_PLL_ClocksTypeDef PLL_Clocks; /* Check parameter */ assert_param(IS_LL_RCC_RNG_CLKSOURCE(RNGxSource)); switch (LL_RCC_GetRNGClockSource(RNGxSource)) { case LL_RCC_RNG1_CLKSOURCE_CSI: case LL_RCC_RNG2_CLKSOURCE_CSI: if (LL_RCC_CSI_IsReady() != 0U) { rng_frequency = CSI_VALUE; } break; case LL_RCC_RNG1_CLKSOURCE_PLL4R: case LL_RCC_RNG2_CLKSOURCE_PLL4R: if (LL_RCC_PLL4_IsReady() != 0U) { LL_RCC_GetPLL4ClockFreq(&PLL_Clocks); rng_frequency = PLL_Clocks.PLL_R_Frequency; } break; case LL_RCC_RNG1_CLKSOURCE_LSE: case LL_RCC_RNG2_CLKSOURCE_LSE: if (LL_RCC_LSE_IsReady() != 0U) { rng_frequency = LSE_VALUE; } break; case LL_RCC_RNG1_CLKSOURCE_LSI: case LL_RCC_RNG2_CLKSOURCE_LSI: if (LL_RCC_LSI_IsReady() != 0U) { rng_frequency = LSI_VALUE; } break; default: /* Nothing to do */ break; } return rng_frequency; } /** * @brief Return CKPERx clock frequency * @param CKPERxSource This parameter can be one of the following values: * @arg @ref LL_RCC_CKPER_CLKSOURCE * @retval CKPER clock frequency (in Hz) * - @ref LL_RCC_PERIPH_FREQUENCY_NO indicates that oscillator is not ready */ uint32_t LL_RCC_GetCKPERClockFreq(uint32_t CKPERxSource) { uint32_t ckper_frequency = LL_RCC_PERIPH_FREQUENCY_NO; /* Check parameter */ assert_param(IS_LL_RCC_CKPER_CLKSOURCE(CKPERxSource)); switch (LL_RCC_GetCKPERClockSource(CKPERxSource)) { case LL_RCC_CKPER_CLKSOURCE_HSI: if (LL_RCC_HSI_IsReady() != 0U) { ckper_frequency = HSI_VALUE >> LL_RCC_HSI_GetDivider(); } break; case LL_RCC_CKPER_CLKSOURCE_CSI: if (LL_RCC_CSI_IsReady() != 0U) { ckper_frequency = CSI_VALUE; } break; case LL_RCC_CKPER_CLKSOURCE_HSE: if (LL_RCC_HSE_IsReady() != 0U) { ckper_frequency = HSE_VALUE; } break; case LL_RCC_CKPER_CLKSOURCE_OFF: default: /* Nothing to do */ break; } return ckper_frequency; } /** * @brief Return STGENx clock frequency * @param STGENxSource This parameter can be one of the following values: * @arg @ref LL_RCC_STGEN_CLKSOURCE * @retval STGEN clock frequency (in Hz) * - @ref LL_RCC_PERIPH_FREQUENCY_NO indicates that oscillator is not ready */ uint32_t LL_RCC_GetSTGENClockFreq(uint32_t STGENxSource) { uint32_t stgen_frequency = LL_RCC_PERIPH_FREQUENCY_NO; /* Check parameter */ assert_param(IS_LL_RCC_STGEN_CLKSOURCE(STGENxSource)); switch (LL_RCC_GetSTGENClockSource(STGENxSource)) { case LL_RCC_STGEN_CLKSOURCE_HSI: if (LL_RCC_HSI_IsReady() != 0U) { stgen_frequency = HSI_VALUE >> LL_RCC_HSI_GetDivider(); } break; case LL_RCC_STGEN_CLKSOURCE_HSE: if (LL_RCC_HSE_IsReady() != 0U) { stgen_frequency = HSE_VALUE; } break; case LL_RCC_STGEN_CLKSOURCE_OFF: default: /* Nothing to do */ break; } return stgen_frequency; } #if defined(DSI) /** * @brief Return DSIx clock frequency * @param DSIxSource This parameter can be one of the following values: * @arg @ref LL_RCC_DSI_CLKSOURCE * @retval DSI clock frequency (in Hz) * - @ref LL_RCC_PERIPH_FREQUENCY_NO indicates that oscillator is not ready */ uint32_t LL_RCC_GetDSIClockFreq(uint32_t DSIxSource) { uint32_t dsi_frequency = LL_RCC_PERIPH_FREQUENCY_NO; LL_PLL_ClocksTypeDef PLL_Clocks; /* Check parameter */ assert_param(IS_LL_RCC_DSI_CLKSOURCE(DSIxSource)); switch (LL_RCC_GetDSIClockSource(DSIxSource)) { case LL_RCC_DSI_CLKSOURCE_PLL4P: if (LL_RCC_PLL4_IsReady() != 0U) { LL_RCC_GetPLL4ClockFreq(&PLL_Clocks); dsi_frequency = PLL_Clocks.PLL_P_Frequency; } break; /* It has no sense to ask for DSIPHY frequency because it is generated * by DSI itself, so send back 0 as kernel frequency */ case LL_RCC_DSI_CLKSOURCE_PHY: dsi_frequency = LL_RCC_PERIPH_FREQUENCY_NA; break; default: /* Nothing to do */ break; } return dsi_frequency; } #endif /*DSI*/ /** * @brief Return ADCx clock frequency * @param ADCxSource This parameter can be one of the following values: * @arg @ref LL_RCC_ADC_CLKSOURCE * @retval ADC clock frequency (in Hz) * - @ref LL_RCC_PERIPH_FREQUENCY_NO indicates that oscillator is not ready */ uint32_t LL_RCC_GetADCClockFreq(uint32_t ADCxSource) { uint32_t adc_frequency = LL_RCC_PERIPH_FREQUENCY_NO; LL_PLL_ClocksTypeDef PLL_Clocks; /* Check parameter */ assert_param(IS_LL_RCC_ADC_CLKSOURCE(ADCxSource)); switch (LL_RCC_GetADCClockSource(ADCxSource)) { case LL_RCC_ADC_CLKSOURCE_PLL4R: if (LL_RCC_PLL4_IsReady() != 0U) { LL_RCC_GetPLL4ClockFreq(&PLL_Clocks); adc_frequency = PLL_Clocks.PLL_R_Frequency; } break; case LL_RCC_ADC_CLKSOURCE_PER: adc_frequency = LL_RCC_GetCKPERClockFreq(LL_RCC_CKPER_CLKSOURCE); break; case LL_RCC_ADC_CLKSOURCE_PLL3Q: if (LL_RCC_PLL3_IsReady() != 0U) { LL_RCC_GetPLL3ClockFreq(&PLL_Clocks); adc_frequency = PLL_Clocks.PLL_Q_Frequency; } break; default: /* Nothing to do */ break; } return adc_frequency; } /** * @brief Return LPTIMx clock frequency * @param LPTIMxSource This parameter can be one of the following values: * @arg @ref LL_RCC_LPTIM1_CLKSOURCE * @arg @ref LL_RCC_LPTIM23_CLKSOURCE * @arg @ref LL_RCC_LPTIM45_CLKSOURCE * @retval LPTIM clock frequency (in Hz) * - @ref LL_RCC_PERIPH_FREQUENCY_NO indicates that oscillator is not ready */ uint32_t LL_RCC_GetLPTIMClockFreq(uint32_t LPTIMxSource) { uint32_t lptim_frequency = LL_RCC_PERIPH_FREQUENCY_NO; LL_PLL_ClocksTypeDef PLL_Clocks; /* Check parameter */ assert_param(IS_LL_RCC_LPTIM_CLKSOURCE(LPTIMxSource)); switch (LL_RCC_GetLPTIMClockSource(LPTIMxSource)) { case LL_RCC_LPTIM1_CLKSOURCE_PCLK1: lptim_frequency = RCC_GetPCLK1ClockFreq(RCC_GetMLHCLKClockFreq(RCC_GetMCUSSClockFreq())); break; case LL_RCC_LPTIM1_CLKSOURCE_PLL4P: case LL_RCC_LPTIM45_CLKSOURCE_PLL4P: if (LL_RCC_PLL4_IsReady() != 0U) { LL_RCC_GetPLL4ClockFreq(&PLL_Clocks); lptim_frequency = PLL_Clocks.PLL_P_Frequency; } break; case LL_RCC_LPTIM1_CLKSOURCE_PLL3Q: case LL_RCC_LPTIM45_CLKSOURCE_PLL3Q: if (LL_RCC_PLL3_IsReady() != 0U) { LL_RCC_GetPLL3ClockFreq(&PLL_Clocks); lptim_frequency = PLL_Clocks.PLL_Q_Frequency; } break; case LL_RCC_LPTIM1_CLKSOURCE_LSE: case LL_RCC_LPTIM23_CLKSOURCE_LSE: case LL_RCC_LPTIM45_CLKSOURCE_LSE: if (LL_RCC_LSE_IsReady() != 0U) { lptim_frequency = LSE_VALUE; } break; case LL_RCC_LPTIM1_CLKSOURCE_LSI: case LL_RCC_LPTIM23_CLKSOURCE_LSI: case LL_RCC_LPTIM45_CLKSOURCE_LSI: if (LL_RCC_LSI_IsReady() != 0U) { lptim_frequency = LSI_VALUE; } break; case LL_RCC_LPTIM1_CLKSOURCE_PER: case LL_RCC_LPTIM23_CLKSOURCE_PER: case LL_RCC_LPTIM45_CLKSOURCE_PER: lptim_frequency = LL_RCC_GetCKPERClockFreq(LL_RCC_CKPER_CLKSOURCE); break; case LL_RCC_LPTIM23_CLKSOURCE_PCLK3: case LL_RCC_LPTIM45_CLKSOURCE_PCLK3: lptim_frequency = RCC_GetPCLK3ClockFreq(RCC_GetMLHCLKClockFreq(RCC_GetMCUSSClockFreq())); break; case LL_RCC_LPTIM23_CLKSOURCE_PLL4Q: if (LL_RCC_PLL4_IsReady() != 0U) { LL_RCC_GetPLL4ClockFreq(&PLL_Clocks); lptim_frequency = PLL_Clocks.PLL_Q_Frequency; } break; case LL_RCC_LPTIM1_CLKSOURCE_OFF: case LL_RCC_LPTIM23_CLKSOURCE_OFF: case LL_RCC_LPTIM45_CLKSOURCE_OFF: default: /* Nothing to do */ break; } return lptim_frequency; } /** * @brief Return DFSDM kernel clock frequency * @param DFSDMxSource This parameter can be one of the following values: * @arg @ref LL_RCC_DFSDM_CLKSOURCE * @note DFSM shares with SAI1 the same kernel clock source * @retval DFSDM clock frequency (in Hz) * - @ref LL_RCC_PERIPH_FREQUENCY_NO indicates that oscillator is not ready */ uint32_t LL_RCC_GetDFSDMClockFreq(uint32_t DFSDMxSource) { uint32_t dfsdm_frequency = LL_RCC_PERIPH_FREQUENCY_NO; LL_PLL_ClocksTypeDef PLL_Clocks; /* Check parameter */ assert_param(IS_LL_RCC_DFSDM_CLKSOURCE(DFSDMxSource)); switch (LL_RCC_GetSAIClockSource(LL_RCC_SAI1_CLKSOURCE)) { case LL_RCC_SAI1_CLKSOURCE_PLL4Q: if (LL_RCC_PLL4_IsReady() != 0U) { LL_RCC_GetPLL4ClockFreq(&PLL_Clocks); dfsdm_frequency = PLL_Clocks.PLL_Q_Frequency; } break; case LL_RCC_SAI1_CLKSOURCE_PLL3Q: if (LL_RCC_PLL3_IsReady() != 0U) { LL_RCC_GetPLL3ClockFreq(&PLL_Clocks); dfsdm_frequency = PLL_Clocks.PLL_Q_Frequency; } break; case LL_RCC_SAI1_CLKSOURCE_I2SCKIN: dfsdm_frequency = EXTERNAL_CLOCK_VALUE; break; case LL_RCC_SAI1_CLKSOURCE_PER: dfsdm_frequency = LL_RCC_GetCKPERClockFreq(LL_RCC_CKPER_CLKSOURCE); break; case LL_RCC_SAI1_CLKSOURCE_PLL3R: if (LL_RCC_PLL3_IsReady() != 0U) { LL_RCC_GetPLL3ClockFreq(&PLL_Clocks); dfsdm_frequency = PLL_Clocks.PLL_R_Frequency; } break; default: /* Nothing to do */ break; } return dfsdm_frequency; } /** * @brief Return LTDC kernel clock frequency * @retval LTDC clock frequency (in Hz) * - @ref LL_RCC_PERIPH_FREQUENCY_NO indicates that oscillator is not ready */ uint32_t LL_RCC_GetLTDCClockFreq(void) { uint32_t ltdc_frequency = LL_RCC_PERIPH_FREQUENCY_NO; LL_PLL_ClocksTypeDef PLL_Clocks; if (LL_RCC_PLL4_IsReady() != 0U) { LL_RCC_GetPLL4ClockFreq(&PLL_Clocks); ltdc_frequency = PLL_Clocks.PLL_Q_Frequency; } return ltdc_frequency; } /** * @brief Return RTC clock frequency * @retval RTC clock frequency (in Hz) * - @ref LL_RCC_PERIPH_FREQUENCY_NO indicates that oscillator is not ready */ uint32_t LL_RCC_GetRTCClockFreq(void) { uint32_t rtc_frequency = LL_RCC_PERIPH_FREQUENCY_NO; /* RTCCLK clock frequency */ switch (LL_RCC_GetRTCClockSource()) { case LL_RCC_RTC_CLKSOURCE_LSE: /* LSE clock used as RTC clock source */ if (LL_RCC_LSE_IsReady() != 0U) { rtc_frequency = LSE_VALUE; } break; case LL_RCC_RTC_CLKSOURCE_LSI: /* LSI clock used as RTC clock source */ if (LL_RCC_LSI_IsReady() != 0U) { rtc_frequency = LSI_VALUE; } break; case LL_RCC_RTC_CLKSOURCE_HSE_DIV: /* HSE clock used as RTC clock source */ rtc_frequency = (HSE_VALUE / (LL_RCC_GetRTC_HSEPrescaler() + 1U)); break; case LL_RCC_RTC_CLKSOURCE_NONE: /* No clock used as RTC clock source */ default: /* Nothing to do */ break; } return rtc_frequency; } /** * @brief Return TIMGx clock frequency * @param TIMGxPrescaler This parameter can be one of the following values: * @arg @ref LL_RCC_TIMG1PRES * @arg @ref LL_RCC_TIMG2PRES *@note LL_RCC_TIMG1PRES returns the frequency of the prescaler of timers * located into APB1 domain. It concerns TIM2, TIM3, TIM4, TIM5, TIM6, * TIM7, TIM12, TIM13 and TIM14 frequencies. * LL_RCC_TIMG2PRES returns the frequency of the prescaler of timers * located into APB2 domain. It concerns TIM1, TIM8, TIM15, TIM16, and * TIM17. * @retval TIMGx clock frequency (in Hz) * - @ref LL_RCC_PERIPH_FREQUENCY_NO indicates that oscillator is not ready */ uint32_t LL_RCC_GetTIMGClockFreq(uint32_t TIMGxPrescaler) { uint32_t timg_frequency, apb1_div; /* Check parameter */ assert_param(IS_LL_RCC_TIMGPRES(TIMGxPrescaler)); timg_frequency = RCC_GetMLHCLKClockFreq(RCC_GetMCUSSClockFreq()); apb1_div = LL_RCC_GetAPB1Prescaler(); switch (LL_RCC_GetTIMGPrescaler(TIMGxPrescaler)) { case LL_RCC_TIMG1PRES_ACTIVATED: case LL_RCC_TIMG2PRES_ACTIVATED: switch (apb1_div) { case LL_RCC_APB1_DIV_1: case LL_RCC_APB1_DIV_2: case LL_RCC_APB1_DIV_4: break; case LL_RCC_APB1_DIV_8: timg_frequency /= 2U; break; case LL_RCC_APB1_DIV_16: timg_frequency /= 4U; break; } break; case LL_RCC_TIMG1PRES_DEACTIVATED: case LL_RCC_TIMG2PRES_DEACTIVATED: switch (apb1_div) { case LL_RCC_APB1_DIV_1: case LL_RCC_APB1_DIV_2: break; case LL_RCC_APB1_DIV_4: timg_frequency /= 2U; break; case LL_RCC_APB1_DIV_8: timg_frequency /= 4U; break; case LL_RCC_APB1_DIV_16: timg_frequency /= 8U; break; } break; default: timg_frequency = LL_RCC_PERIPH_FREQUENCY_NO; break; } return timg_frequency; } /** * @} */ /** * @} */ /** @addtogroup RCC_LL_Private_Functions * @{ */ /** * @brief Return MPUSS clock frequency * @retval MPUSS clock frequency (in Hz) */ uint32_t RCC_GetMPUSSClockFreq(void) { uint32_t frequency = 0U, mpudiv; LL_PLL_ClocksTypeDef PLL_Clocks; /* Get MPUSS source -------------------------------------------------------*/ switch (LL_RCC_GetMPUClkSource()) { case LL_RCC_MPU_CLKSOURCE_HSI: frequency = (HSI_VALUE >> LL_RCC_HSI_GetDivider()); break; case LL_RCC_MPU_CLKSOURCE_HSE: frequency = HSE_VALUE; break; case LL_RCC_MPU_CLKSOURCE_PLL1: LL_RCC_GetPLL1ClockFreq(&PLL_Clocks); frequency = PLL_Clocks.PLL_P_Frequency; break; case LL_RCC_MPU_CLKSOURCE_MPUDIV: mpudiv = LL_RCC_GetMPUPrescaler(); if (mpudiv != LL_RCC_MPU_DIV_OFF) { LL_RCC_GetPLL1ClockFreq(&PLL_Clocks); frequency = (PLL_Clocks.PLL_P_Frequency >> mpudiv); } break; default: /* Nothing to do */ break; } return frequency; } /** * @brief Return AXISS clock frequency * @retval AXISS clock frequency (in Hz) */ uint32_t RCC_GetAXISSClockFreq(void) { uint32_t frequency = 0U; LL_PLL_ClocksTypeDef PLL_Clocks; /* Get AXISS source -------------------------------------------------------*/ switch (LL_RCC_GetAXISSClkSource()) { case LL_RCC_AXISS_CLKSOURCE_HSI: frequency = (HSI_VALUE >> LL_RCC_HSI_GetDivider()); break; case LL_RCC_AXISS_CLKSOURCE_HSE: frequency = HSE_VALUE; break; case LL_RCC_AXISS_CLKSOURCE_PLL2: LL_RCC_GetPLL2ClockFreq(&PLL_Clocks); frequency = PLL_Clocks.PLL_P_Frequency; break; case LL_RCC_AXISS_CLKSOURCE_OFF: default: /* Nothing to do */ break; } return frequency; } /** * @brief Return MCUSS clock frequency * @retval MCUSS clock frequency (in Hz) */ uint32_t RCC_GetMCUSSClockFreq() { uint32_t frequency = 0U; LL_PLL_ClocksTypeDef PLL_Clocks; /* Get MCUSS source -------------------------------------------------------*/ switch (LL_RCC_GetMCUSSClkSource()) { case LL_RCC_MCUSS_CLKSOURCE_HSI: frequency = (HSI_VALUE >> LL_RCC_HSI_GetDivider()); break; case LL_RCC_MCUSS_CLKSOURCE_HSE: frequency = HSE_VALUE; break; case LL_RCC_MCUSS_CLKSOURCE_CSI: frequency = CSI_VALUE; break; case LL_RCC_MCUSS_CLKSOURCE_PLL3: LL_RCC_GetPLL3ClockFreq(&PLL_Clocks); frequency = PLL_Clocks.PLL_P_Frequency; break; default: /* Nothing to do */ break; } return frequency; } /** * @brief Return ACLK (ACLK, HCLK5 and HCLK6) clock frequency * @retval ACLK clock frequency (in Hz) */ uint32_t RCC_GetACLKClockFreq(uint32_t AXISS_Frequency) { return LL_RCC_CALC_ACLK_FREQ(AXISS_Frequency, LL_RCC_GetACLKPrescaler()); } /** * @brief Return MLHCLK (MLHCLK, HCLK[4:1], MCU_CK and FCLK_CK) clock frequency * @retval MLHCLK clock frequency (in Hz) */ uint32_t RCC_GetMLHCLKClockFreq(uint32_t MCUSS_Frequency) { return LL_RCC_CALC_MLHCLK_FREQ(MCUSS_Frequency, LL_RCC_GetMLHCLKPrescaler()); } /** * @brief Return PCLK1 clock frequency * @param MLHCLK_Frequency MLHCLK clock frequency * @retval PCLK1 clock frequency (in Hz) */ uint32_t RCC_GetPCLK1ClockFreq(uint32_t MLHCLK_Frequency) { /* PCLK1 clock frequency */ return LL_RCC_CALC_PCLK1_FREQ(MLHCLK_Frequency, LL_RCC_GetAPB1Prescaler()); } /** * @brief Return PCLK2 clock frequency * @param MLHCLK_Frequency MLHCLK clock frequency * @retval PCLK2 clock frequency (in Hz) */ uint32_t RCC_GetPCLK2ClockFreq(uint32_t MLHCLK_Frequency) { /* PCLK2 clock frequency */ return LL_RCC_CALC_PCLK2_FREQ(MLHCLK_Frequency, LL_RCC_GetAPB2Prescaler()); } /** * @brief Return PCLK3 clock frequency * @param MLHCLK_Frequency MLHCLK clock frequency * @retval PCLK3 clock frequency (in Hz) */ uint32_t RCC_GetPCLK3ClockFreq(uint32_t MLHCLK_Frequency) { /* PCLK3 clock frequency */ return LL_RCC_CALC_PCLK3_FREQ(MLHCLK_Frequency, LL_RCC_GetAPB3Prescaler()); } /** * @brief Return PCLK4 clock frequency * @param ACLK_Frequency ACLK clock frequency * @retval PCLK4 clock frequency (in Hz) */ uint32_t RCC_GetPCLK4ClockFreq(uint32_t ACLK_Frequency) { /* PCLK4 clock frequency */ return LL_RCC_CALC_PCLK4_FREQ(ACLK_Frequency, LL_RCC_GetAPB4Prescaler()); } /** * @brief Return PCLK5 clock frequency * @param ACLK_Frequency ACLK clock frequency * @retval PCLK5 clock frequency (in Hz) */ uint32_t RCC_GetPCLK5ClockFreq(uint32_t ACLK_Frequency) { /* PCLK5 clock frequency */ return LL_RCC_CALC_PCLK5_FREQ(ACLK_Frequency, LL_RCC_GetAPB5Prescaler()); } /** * @} */ /** * @} */ #endif /* defined(RCC) */ /** * @} */ #endif /* USE_FULL_LL_DRIVER */