Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
stm32l4xx_ll_rcc.c
00001 /** 00002 ****************************************************************************** 00003 * @file stm32l4xx_ll_rcc.c 00004 * @author MCD Application Team 00005 * @version V1.5.1 00006 * @date 31-May-2016 00007 * @brief RCC LL module driver. 00008 ****************************************************************************** 00009 * @attention 00010 * 00011 * <h2><center>© COPYRIGHT(c) 2016 STMicroelectronics</center></h2> 00012 * 00013 * Redistribution and use in source and binary forms, with or without modification, 00014 * are permitted provided that the following conditions are met: 00015 * 1. Redistributions of source code must retain the above copyright notice, 00016 * this list of conditions and the following disclaimer. 00017 * 2. Redistributions in binary form must reproduce the above copyright notice, 00018 * this list of conditions and the following disclaimer in the documentation 00019 * and/or other materials provided with the distribution. 00020 * 3. Neither the name of STMicroelectronics nor the names of its contributors 00021 * may be used to endorse or promote products derived from this software 00022 * without specific prior written permission. 00023 * 00024 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 00025 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 00026 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 00027 * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE 00028 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 00029 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 00030 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 00031 * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 00032 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 00033 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 00034 * 00035 ****************************************************************************** 00036 */ 00037 #if defined(USE_FULL_LL_DRIVER) 00038 00039 /* Includes ------------------------------------------------------------------*/ 00040 #include "stm32l4xx_ll_rcc.h" 00041 #ifdef USE_FULL_ASSERT 00042 #include "stm32_assert.h" 00043 #else 00044 #define assert_param(expr) ((void)0U) 00045 #endif 00046 /** @addtogroup STM32L4xx_LL_Driver 00047 * @{ 00048 */ 00049 00050 #if defined(RCC) 00051 00052 /** @addtogroup RCC_LL 00053 * @{ 00054 */ 00055 00056 /* Private types -------------------------------------------------------------*/ 00057 /* Private variables ---------------------------------------------------------*/ 00058 /* Private constants ---------------------------------------------------------*/ 00059 /* Private macros ------------------------------------------------------------*/ 00060 /** @addtogroup RCC_LL_Private_Macros 00061 * @{ 00062 */ 00063 #if defined(RCC_CCIPR_USART3SEL) 00064 #define IS_LL_RCC_USART_CLKSOURCE(__VALUE__) (((__VALUE__) == LL_RCC_USART1_CLKSOURCE) \ 00065 || ((__VALUE__) == LL_RCC_USART2_CLKSOURCE) \ 00066 || ((__VALUE__) == LL_RCC_USART3_CLKSOURCE)) 00067 #else 00068 #define IS_LL_RCC_USART_CLKSOURCE(__VALUE__) (((__VALUE__) == LL_RCC_USART1_CLKSOURCE) \ 00069 || ((__VALUE__) == LL_RCC_USART2_CLKSOURCE)) 00070 00071 #endif /* RCC_CCIPR_USART3SEL */ 00072 #if defined(RCC_CCIPR_UART4SEL) && defined(RCC_CCIPR_UART5SEL) 00073 #define IS_LL_RCC_UART_CLKSOURCE(__VALUE__) (((__VALUE__) == LL_RCC_UART4_CLKSOURCE) \ 00074 || ((__VALUE__) == LL_RCC_UART5_CLKSOURCE)) 00075 #elif defined(RCC_CCIPR_UART4SEL) 00076 #define IS_LL_RCC_UART_INSTANCE(__VALUE__) ((__VALUE__) == LL_RCC_UART4_CLKSOURCE) 00077 #elif defined(RCC_CCIPR_UART5SEL) 00078 #define IS_LL_RCC_UART_INSTANCE(__VALUE__) ((__VALUE__) == LL_RCC_UART5_CLKSOURCE) 00079 #endif /* RCC_CCIPR_UART4SEL && RCC_CCIPR_UART5SEL*/ 00080 00081 #define IS_LL_RCC_LPUART_CLKSOURCE(__VALUE__) (((__VALUE__) == LL_RCC_LPUART1_CLKSOURCE)) 00082 00083 #if defined(RCC_CCIPR_I2C2SEL)&&defined(RCC_CCIPR_I2C3SEL) 00084 #define IS_LL_RCC_I2C_CLKSOURCE(__VALUE__) (((__VALUE__) == LL_RCC_I2C1_CLKSOURCE) \ 00085 || ((__VALUE__) == LL_RCC_I2C2_CLKSOURCE) \ 00086 || ((__VALUE__) == LL_RCC_I2C3_CLKSOURCE)) 00087 00088 #elif !defined(RCC_CCIPR_I2C2SEL)&&defined(RCC_CCIPR_I2C3SEL) 00089 #define IS_LL_RCC_I2C_CLKSOURCE(__VALUE__) (((__VALUE__) == LL_RCC_I2C1_CLKSOURCE) \ 00090 || ((__VALUE__) == LL_RCC_I2C3_CLKSOURCE)) 00091 00092 #else 00093 #define IS_LL_RCC_I2C_CLKSOURCE(__VALUE__) ((__VALUE__) == LL_RCC_I2C1_CLKSOURCE) 00094 00095 #endif /* RCC_CCIPR_I2C2SEL && RCC_CCIPR_I2C3SEL */ 00096 #define IS_LL_RCC_LPTIM_CLKSOURCE(__VALUE__) (((__VALUE__) == LL_RCC_LPTIM1_CLKSOURCE) \ 00097 || ((__VALUE__) == LL_RCC_LPTIM2_CLKSOURCE)) 00098 00099 #if defined(RCC_CCIPR_SAI2SEL) 00100 #define IS_LL_RCC_SAI_CLKSOURCE(__VALUE__) (((__VALUE__) == LL_RCC_SAI1_CLKSOURCE) \ 00101 || ((__VALUE__) == LL_RCC_SAI2_CLKSOURCE)) 00102 #else 00103 #define IS_LL_RCC_SAI_CLKSOURCE(__VALUE__) ((__VALUE__) == LL_RCC_SAI1_CLKSOURCE) 00104 #endif /* RCC_CCIPR_SAI2SEL */ 00105 00106 #define IS_LL_RCC_SDMMC_CLKSOURCE(__VALUE__) (((__VALUE__) == LL_RCC_SDMMC1_CLKSOURCE)) 00107 00108 #define IS_LL_RCC_RNG_CLKSOURCE(__VALUE__) (((__VALUE__) == LL_RCC_RNG_CLKSOURCE)) 00109 00110 #if defined(USB_OTG_FS) || defined(USB) 00111 #define IS_LL_RCC_USB_CLKSOURCE(__VALUE__) (((__VALUE__) == LL_RCC_USB_CLKSOURCE)) 00112 #endif /* USB_OTG_FS || USB */ 00113 00114 #define IS_LL_RCC_ADC_CLKSOURCE(__VALUE__) (((__VALUE__) == LL_RCC_ADC_CLKSOURCE)) 00115 00116 #define IS_LL_RCC_SWPMI_CLKSOURCE(__VALUE__) (((__VALUE__) == LL_RCC_SWPMI1_CLKSOURCE)) 00117 00118 #define IS_LL_RCC_DFSDM_CLKSOURCE(__VALUE__) (((__VALUE__) == LL_RCC_DFSDM1_CLKSOURCE)) 00119 00120 /** 00121 * @} 00122 */ 00123 00124 /* Private function prototypes -----------------------------------------------*/ 00125 /** @defgroup RCC_LL_Private_Functions RCC Private functions 00126 * @{ 00127 */ 00128 uint32_t RCC_GetSystemClockFreq(void); 00129 uint32_t RCC_GetHCLKClockFreq(uint32_t SYSCLK_Frequency); 00130 uint32_t RCC_GetPCLK1ClockFreq(uint32_t HCLK_Frequency); 00131 uint32_t RCC_GetPCLK2ClockFreq(uint32_t HCLK_Frequency); 00132 uint32_t RCC_PLL_GetFreqDomain_SYS(void); 00133 uint32_t RCC_PLL_GetFreqDomain_SAI(void); 00134 uint32_t RCC_PLL_GetFreqDomain_48M(void); 00135 uint32_t RCC_PLLSAI1_GetFreqDomain_SAI(void); 00136 uint32_t RCC_PLLSAI1_GetFreqDomain_48M(void); 00137 uint32_t RCC_PLLSAI1_GetFreqDomain_ADC(void); 00138 #if defined(RCC_PLLSAI2_SUPPORT) 00139 uint32_t RCC_PLLSAI2_GetFreqDomain_SAI(void); 00140 uint32_t RCC_PLLSAI2_GetFreqDomain_ADC(void); 00141 #endif /*RCC_PLLSAI2_SUPPORT*/ 00142 /** 00143 * @} 00144 */ 00145 00146 00147 /* Exported functions --------------------------------------------------------*/ 00148 /** @addtogroup RCC_LL_Exported_Functions 00149 * @{ 00150 */ 00151 00152 /** @addtogroup RCC_LL_EF_Init 00153 * @{ 00154 */ 00155 00156 /** 00157 * @brief Reset the RCC clock configuration to the default reset state. 00158 * @note The default reset state of the clock configuration is given below: 00159 * - MSI ON and used as system clock source 00160 * - HSE, HSI, PLL and PLLSAIxSource OFF 00161 * - AHB, APB1 and APB2 prescaler set to 1. 00162 * - CSS, MCO OFF 00163 * - All interrupts disabled 00164 * @note This function doesn't modify the configuration of the 00165 * - Peripheral clocks 00166 * - LSI, LSE and RTC clocks 00167 * @retval An ErrorStatus enumeration value: 00168 * - SUCCESS: RCC registers are de-initialized 00169 * - ERROR: not applicable 00170 */ 00171 ErrorStatus LL_RCC_DeInit(void) 00172 { 00173 uint32_t vl_mask = 0; 00174 00175 /* Set MSION bit */ 00176 LL_RCC_MSI_Enable(); 00177 00178 /* Insure MSIRDY bit is set before writing default MSIRANGE value */ 00179 while (LL_RCC_MSI_IsReady() == 0) 00180 { 00181 __NOP(); 00182 } 00183 00184 /* Set MSIRANGE default value */ 00185 LL_RCC_MSI_SetRange(LL_RCC_MSIRANGE_6); 00186 /* Set MSITRIM bits to the reset value*/ 00187 LL_RCC_MSI_SetCalibTrimming(0); 00188 00189 /* Set HSITRIM bits to the reset value*/ 00190 LL_RCC_HSI_SetCalibTrimming(0x10); 00191 00192 /* Reset CFGR register */ 00193 LL_RCC_WriteReg(CFGR, 0x00000000); 00194 00195 vl_mask = 0xFFFFFFFFU; 00196 00197 /* Reset HSION, HSIKERON, HSIASFS, HSEON, PLLSYSON bits */ 00198 CLEAR_BIT(vl_mask, (RCC_CR_HSION | RCC_CR_HSIASFS | RCC_CR_HSIKERON | RCC_CR_HSEON | 00199 RCC_CR_PLLON)); 00200 00201 /* Reset PLLSAI1ON bit */ 00202 CLEAR_BIT(vl_mask, RCC_CR_PLLSAI1ON); 00203 00204 #if defined(RCC_PLLSAI2_SUPPORT) 00205 /* Reset PLLSAI2ON bit */ 00206 CLEAR_BIT(vl_mask, RCC_CR_PLLSAI2ON); 00207 #endif /*RCC_PLLSAI2_SUPPORT*/ 00208 00209 /* Write new mask in CR register */ 00210 LL_RCC_WriteReg(CR, vl_mask); 00211 00212 /* Reset PLLCFGR register */ 00213 LL_RCC_WriteReg(PLLCFGR, 16 << RCC_POSITION_PLLN); 00214 00215 /* Reset PLLSAI1CFGR register */ 00216 LL_RCC_WriteReg(PLLSAI1CFGR, 16 << RCC_POSITION_PLLSAI1N); 00217 00218 #if defined(RCC_PLLSAI2_SUPPORT) 00219 /* Reset PLLSAI2CFGR register */ 00220 LL_RCC_WriteReg(PLLSAI2CFGR, 16 << RCC_POSITION_PLLSAI2N); 00221 #endif /*RCC_PLLSAI2_SUPPORT*/ 00222 00223 /* Reset HSEBYP bit */ 00224 LL_RCC_HSE_DisableBypass(); 00225 00226 /* Disable all interrupts */ 00227 LL_RCC_WriteReg(CIER, 0x00000000); 00228 00229 return SUCCESS; 00230 } 00231 00232 /** 00233 * @} 00234 */ 00235 00236 /** @addtogroup RCC_LL_EF_Get_Freq 00237 * @brief Return the frequencies of different on chip clocks; System, AHB, APB1 and APB2 buses clocks 00238 * and different peripheral clocks available on the device. 00239 * @note If SYSCLK source is MSI, function returns values based on MSI_VALUE(*) 00240 * @note If SYSCLK source is HSI, function returns values based on HSI_VALUE(**) 00241 * @note If SYSCLK source is HSE, function returns values based on HSE_VALUE(***) 00242 * @note If SYSCLK source is PLL, function returns values based on HSE_VALUE(***) 00243 * or HSI_VALUE(**) or MSI_VALUE(*) multiplied/divided by the PLL factors. 00244 * @note (*) MSI_VALUE is a constant defined in this file (default value 00245 * 4 MHz) but the real value may vary depending on the variations 00246 * in voltage and temperature. 00247 * @note (**) HSI_VALUE is a constant defined in this file (default value 00248 * 16 MHz) but the real value may vary depending on the variations 00249 * in voltage and temperature. 00250 * @note (***) HSE_VALUE is a constant defined in this file (default value 00251 * 8 MHz), user has to ensure that HSE_VALUE is same as the real 00252 * frequency of the crystal used. Otherwise, this function may 00253 * have wrong result. 00254 * @note The result of this function could be incorrect when using fractional 00255 * value for HSE crystal. 00256 * @note This function can be used by the user application to compute the 00257 * baud-rate for the communication peripherals or configure other parameters. 00258 * @{ 00259 */ 00260 00261 /** 00262 * @brief Return the frequencies of different on chip clocks; System, AHB, APB1 and APB2 buses clocks 00263 * @note Each time SYSCLK, HCLK, PCLK1 and/or PCLK2 clock changes, this function 00264 * must be called to update structure fields. Otherwise, any 00265 * configuration based on this function will be incorrect. 00266 * @param RCC_Clocks pointer to a @ref LL_RCC_ClocksTypeDef structure which will hold the clocks frequencies 00267 * @retval None 00268 */ 00269 void LL_RCC_GetSystemClocksFreq(LL_RCC_ClocksTypeDef *RCC_Clocks) 00270 { 00271 /* Get SYSCLK frequency */ 00272 RCC_Clocks->SYSCLK_Frequency = RCC_GetSystemClockFreq(); 00273 00274 /* HCLK clock frequency */ 00275 RCC_Clocks->HCLK_Frequency = RCC_GetHCLKClockFreq(RCC_Clocks->SYSCLK_Frequency ); 00276 00277 /* PCLK1 clock frequency */ 00278 RCC_Clocks->PCLK1_Frequency = RCC_GetPCLK1ClockFreq(RCC_Clocks->HCLK_Frequency ); 00279 00280 /* PCLK2 clock frequency */ 00281 RCC_Clocks->PCLK2_Frequency = RCC_GetPCLK2ClockFreq(RCC_Clocks->HCLK_Frequency ); 00282 } 00283 00284 /** 00285 * @brief Return USARTx clock frequency 00286 * @param USARTxSource This parameter can be one of the following values: 00287 * @arg @ref LL_RCC_USART1_CLKSOURCE 00288 * @arg @ref LL_RCC_USART2_CLKSOURCE 00289 * @arg @ref LL_RCC_USART3_CLKSOURCE (*) 00290 * 00291 * (*) value not defined in all devices. 00292 * @retval USART clock frequency (in Hz) 00293 * - @ref LL_RCC_PERIPH_FREQUENCY_NO indicates that oscillator (HSI or LSE) is not ready 00294 */ 00295 uint32_t LL_RCC_GetUSARTClockFreq(uint32_t USARTxSource) 00296 { 00297 uint32_t usart_frequency = LL_RCC_PERIPH_FREQUENCY_NO; 00298 00299 /* Check parameter */ 00300 assert_param(IS_LL_RCC_USART_CLKSOURCE(USARTxSource)); 00301 00302 if (USARTxSource == LL_RCC_USART1_CLKSOURCE) 00303 { 00304 /* USART1CLK clock frequency */ 00305 switch (LL_RCC_GetUSARTClockSource(USARTxSource)) 00306 { 00307 case LL_RCC_USART1_CLKSOURCE_SYSCLK: /* USART1 Clock is System Clock */ 00308 usart_frequency = RCC_GetSystemClockFreq(); 00309 break; 00310 00311 case LL_RCC_USART1_CLKSOURCE_HSI: /* USART1 Clock is HSI Osc. */ 00312 if (LL_RCC_HSI_IsReady()) 00313 { 00314 usart_frequency = HSI_VALUE; 00315 } 00316 break; 00317 00318 case LL_RCC_USART1_CLKSOURCE_LSE: /* USART1 Clock is LSE Osc. */ 00319 if (LL_RCC_LSE_IsReady()) 00320 { 00321 usart_frequency = LSE_VALUE; 00322 } 00323 break; 00324 00325 case LL_RCC_USART1_CLKSOURCE_PCLK2: /* USART1 Clock is PCLK2 */ 00326 default: 00327 usart_frequency = RCC_GetPCLK2ClockFreq(RCC_GetHCLKClockFreq(RCC_GetSystemClockFreq())); 00328 break; 00329 } 00330 } 00331 else if (USARTxSource == LL_RCC_USART2_CLKSOURCE) 00332 { 00333 /* USART2CLK clock frequency */ 00334 switch (LL_RCC_GetUSARTClockSource(USARTxSource)) 00335 { 00336 case LL_RCC_USART2_CLKSOURCE_SYSCLK: /* USART2 Clock is System Clock */ 00337 usart_frequency = RCC_GetSystemClockFreq(); 00338 break; 00339 00340 case LL_RCC_USART2_CLKSOURCE_HSI: /* USART2 Clock is HSI Osc. */ 00341 if (LL_RCC_HSI_IsReady()) 00342 { 00343 usart_frequency = HSI_VALUE; 00344 } 00345 break; 00346 00347 case LL_RCC_USART2_CLKSOURCE_LSE: /* USART2 Clock is LSE Osc. */ 00348 if (LL_RCC_LSE_IsReady()) 00349 { 00350 usart_frequency = LSE_VALUE; 00351 } 00352 break; 00353 00354 case LL_RCC_USART2_CLKSOURCE_PCLK1: /* USART2 Clock is PCLK1 */ 00355 default: 00356 usart_frequency = RCC_GetPCLK1ClockFreq(RCC_GetHCLKClockFreq(RCC_GetSystemClockFreq())); 00357 break; 00358 } 00359 } 00360 else 00361 { 00362 #if defined(RCC_CCIPR_USART3SEL) 00363 if (USARTxSource == LL_RCC_USART3_CLKSOURCE) 00364 { 00365 /* USART3CLK clock frequency */ 00366 switch (LL_RCC_GetUSARTClockSource(USARTxSource)) 00367 { 00368 case LL_RCC_USART3_CLKSOURCE_SYSCLK: /* USART3 Clock is System Clock */ 00369 usart_frequency = RCC_GetSystemClockFreq(); 00370 break; 00371 00372 case LL_RCC_USART3_CLKSOURCE_HSI: /* USART3 Clock is HSI Osc. */ 00373 if (LL_RCC_HSI_IsReady()) 00374 { 00375 usart_frequency = HSI_VALUE; 00376 } 00377 break; 00378 00379 case LL_RCC_USART3_CLKSOURCE_LSE: /* USART3 Clock is LSE Osc. */ 00380 if (LL_RCC_LSE_IsReady()) 00381 { 00382 usart_frequency = LSE_VALUE; 00383 } 00384 break; 00385 00386 case LL_RCC_USART3_CLKSOURCE_PCLK1: /* USART3 Clock is PCLK1 */ 00387 default: 00388 usart_frequency = RCC_GetPCLK1ClockFreq(RCC_GetHCLKClockFreq(RCC_GetSystemClockFreq())); 00389 break; 00390 } 00391 } 00392 #endif /* RCC_CCIPR_USART3SEL */ 00393 } 00394 return usart_frequency; 00395 } 00396 00397 #if defined(RCC_CCIPR_UART4SEL) || defined(RCC_CCIPR_UART5SEL) 00398 /** 00399 * @brief Return UARTx clock frequency 00400 * @param UARTxSource This parameter can be one of the following values: 00401 * @arg @ref LL_RCC_UART4_CLKSOURCE 00402 * @arg @ref LL_RCC_UART5_CLKSOURCE 00403 * @retval UART clock frequency (in Hz) 00404 * - @ref LL_RCC_PERIPH_FREQUENCY_NO indicates that oscillator (HSI or LSE) is not ready 00405 */ 00406 uint32_t LL_RCC_GetUARTClockFreq(uint32_t UARTxSource) 00407 { 00408 uint32_t uart_frequency = LL_RCC_PERIPH_FREQUENCY_NO; 00409 00410 /* Check parameter */ 00411 assert_param(IS_LL_RCC_UART_CLKSOURCE(UARTxSource)); 00412 00413 #if defined(RCC_CCIPR_UART4SEL) 00414 if (UARTxSource == LL_RCC_UART4_CLKSOURCE) 00415 { 00416 /* UART4CLK clock frequency */ 00417 switch (LL_RCC_GetUARTClockSource(UARTxSource)) 00418 { 00419 case LL_RCC_UART4_CLKSOURCE_SYSCLK: /* UART4 Clock is System Clock */ 00420 uart_frequency = RCC_GetSystemClockFreq(); 00421 break; 00422 00423 case LL_RCC_UART4_CLKSOURCE_HSI: /* UART4 Clock is HSI Osc. */ 00424 if (LL_RCC_HSI_IsReady()) 00425 { 00426 uart_frequency = HSI_VALUE; 00427 } 00428 break; 00429 00430 case LL_RCC_UART4_CLKSOURCE_LSE: /* UART4 Clock is LSE Osc. */ 00431 if (LL_RCC_LSE_IsReady()) 00432 { 00433 uart_frequency = LSE_VALUE; 00434 } 00435 break; 00436 00437 case LL_RCC_UART4_CLKSOURCE_PCLK1: /* UART4 Clock is PCLK1 */ 00438 default: 00439 uart_frequency = RCC_GetPCLK1ClockFreq(RCC_GetHCLKClockFreq(RCC_GetSystemClockFreq())); 00440 break; 00441 } 00442 } 00443 #endif /* RCC_CCIPR_UART4SEL */ 00444 00445 #if defined(RCC_CCIPR_UART5SEL) 00446 if (UARTxSource == LL_RCC_UART5_CLKSOURCE) 00447 { 00448 /* UART5CLK clock frequency */ 00449 switch (LL_RCC_GetUARTClockSource(UARTxSource)) 00450 { 00451 case LL_RCC_UART5_CLKSOURCE_SYSCLK: /* UART5 Clock is System Clock */ 00452 uart_frequency = RCC_GetSystemClockFreq(); 00453 break; 00454 00455 case LL_RCC_UART5_CLKSOURCE_HSI: /* UART5 Clock is HSI Osc. */ 00456 if (LL_RCC_HSI_IsReady()) 00457 { 00458 uart_frequency = HSI_VALUE; 00459 } 00460 break; 00461 00462 case LL_RCC_UART5_CLKSOURCE_LSE: /* UART5 Clock is LSE Osc. */ 00463 if (LL_RCC_LSE_IsReady()) 00464 { 00465 uart_frequency = LSE_VALUE; 00466 } 00467 break; 00468 00469 case LL_RCC_UART5_CLKSOURCE_PCLK1: /* UART5 Clock is PCLK1 */ 00470 default: 00471 uart_frequency = RCC_GetPCLK1ClockFreq(RCC_GetHCLKClockFreq(RCC_GetSystemClockFreq())); 00472 break; 00473 } 00474 } 00475 #endif /* RCC_CCIPR_UART5SEL */ 00476 00477 return uart_frequency; 00478 } 00479 #endif /* RCC_CCIPR_UART4SEL || RCC_CCIPR_UART5SEL */ 00480 00481 /** 00482 * @brief Return I2Cx clock frequency 00483 * @param I2CxSource This parameter can be one of the following values: 00484 * @arg @ref LL_RCC_I2C1_CLKSOURCE 00485 * @arg @ref LL_RCC_I2C2_CLKSOURCE (*) 00486 * 00487 * (*) value not defined in all devices. 00488 * @arg @ref LL_RCC_I2C3_CLKSOURCE 00489 * @retval I2C clock frequency (in Hz) 00490 * - @ref LL_RCC_PERIPH_FREQUENCY_NO indicates that HSI oscillator is not ready 00491 */ 00492 uint32_t LL_RCC_GetI2CClockFreq(uint32_t I2CxSource) 00493 { 00494 uint32_t i2c_frequency = LL_RCC_PERIPH_FREQUENCY_NO; 00495 00496 /* Check parameter */ 00497 assert_param(IS_LL_RCC_I2C_CLKSOURCE(I2CxSource)); 00498 00499 if (I2CxSource == LL_RCC_I2C1_CLKSOURCE) 00500 { 00501 /* I2C1 CLK clock frequency */ 00502 switch (LL_RCC_GetI2CClockSource(I2CxSource)) 00503 { 00504 case LL_RCC_I2C1_CLKSOURCE_SYSCLK: /* I2C1 Clock is System Clock */ 00505 i2c_frequency = RCC_GetSystemClockFreq(); 00506 break; 00507 00508 case LL_RCC_I2C1_CLKSOURCE_HSI: /* I2C1 Clock is HSI Osc. */ 00509 if (LL_RCC_HSI_IsReady()) 00510 { 00511 i2c_frequency = HSI_VALUE; 00512 } 00513 break; 00514 00515 case LL_RCC_I2C1_CLKSOURCE_PCLK1: /* I2C1 Clock is PCLK1 */ 00516 default: 00517 i2c_frequency = RCC_GetPCLK1ClockFreq(RCC_GetHCLKClockFreq(RCC_GetSystemClockFreq())); 00518 break; 00519 } 00520 } 00521 #if defined(RCC_CCIPR_I2C2SEL) 00522 else if (I2CxSource == LL_RCC_I2C2_CLKSOURCE) 00523 { 00524 /* I2C2 CLK clock frequency */ 00525 switch (LL_RCC_GetI2CClockSource(I2CxSource)) 00526 { 00527 case LL_RCC_I2C2_CLKSOURCE_SYSCLK: /* I2C2 Clock is System Clock */ 00528 i2c_frequency = RCC_GetSystemClockFreq(); 00529 break; 00530 00531 case LL_RCC_I2C2_CLKSOURCE_HSI: /* I2C2 Clock is HSI Osc. */ 00532 if (LL_RCC_HSI_IsReady()) 00533 { 00534 i2c_frequency = HSI_VALUE; 00535 } 00536 break; 00537 00538 case LL_RCC_I2C2_CLKSOURCE_PCLK1: /* I2C2 Clock is PCLK1 */ 00539 default: 00540 i2c_frequency = RCC_GetPCLK1ClockFreq(RCC_GetHCLKClockFreq(RCC_GetSystemClockFreq())); 00541 break; 00542 } 00543 } 00544 #endif /*RCC_CCIPR_I2C2SEL*/ 00545 else 00546 { 00547 if (I2CxSource == LL_RCC_I2C3_CLKSOURCE) 00548 { 00549 /* I2C3 CLK clock frequency */ 00550 switch (LL_RCC_GetI2CClockSource(I2CxSource)) 00551 { 00552 case LL_RCC_I2C3_CLKSOURCE_SYSCLK: /* I2C3 Clock is System Clock */ 00553 i2c_frequency = RCC_GetSystemClockFreq(); 00554 break; 00555 00556 case LL_RCC_I2C3_CLKSOURCE_HSI: /* I2C3 Clock is HSI Osc. */ 00557 if (LL_RCC_HSI_IsReady()) 00558 { 00559 i2c_frequency = HSI_VALUE; 00560 } 00561 break; 00562 00563 case LL_RCC_I2C3_CLKSOURCE_PCLK1: /* I2C3 Clock is PCLK1 */ 00564 default: 00565 i2c_frequency = RCC_GetPCLK1ClockFreq(RCC_GetHCLKClockFreq(RCC_GetSystemClockFreq())); 00566 break; 00567 } 00568 } 00569 } 00570 00571 return i2c_frequency; 00572 } 00573 00574 /** 00575 * @brief Return LPUARTx clock frequency 00576 * @param LPUARTxSource This parameter can be one of the following values: 00577 * @arg @ref LL_RCC_LPUART1_CLKSOURCE 00578 * @retval LPUART clock frequency (in Hz) 00579 * - @ref LL_RCC_PERIPH_FREQUENCY_NO indicates that oscillator (HSI or LSE) is not ready 00580 */ 00581 uint32_t LL_RCC_GetLPUARTClockFreq(uint32_t LPUARTxSource) 00582 { 00583 uint32_t lpuart_frequency = LL_RCC_PERIPH_FREQUENCY_NO; 00584 00585 /* Check parameter */ 00586 assert_param(IS_LL_RCC_LPUART_CLKSOURCE(LPUARTxSource)); 00587 00588 /* LPUART1CLK clock frequency */ 00589 switch (LL_RCC_GetLPUARTClockSource(LPUARTxSource)) 00590 { 00591 case LL_RCC_LPUART1_CLKSOURCE_SYSCLK: /* LPUART1 Clock is System Clock */ 00592 lpuart_frequency = RCC_GetSystemClockFreq(); 00593 break; 00594 00595 case LL_RCC_LPUART1_CLKSOURCE_HSI: /* LPUART1 Clock is HSI Osc. */ 00596 if (LL_RCC_HSI_IsReady()) 00597 { 00598 lpuart_frequency = HSI_VALUE; 00599 } 00600 break; 00601 00602 case LL_RCC_LPUART1_CLKSOURCE_LSE: /* LPUART1 Clock is LSE Osc. */ 00603 if (LL_RCC_LSE_IsReady()) 00604 { 00605 lpuart_frequency = LSE_VALUE; 00606 } 00607 break; 00608 00609 case LL_RCC_LPUART1_CLKSOURCE_PCLK1: /* LPUART1 Clock is PCLK1 */ 00610 default: 00611 lpuart_frequency = RCC_GetPCLK1ClockFreq(RCC_GetHCLKClockFreq(RCC_GetSystemClockFreq())); 00612 break; 00613 } 00614 00615 return lpuart_frequency; 00616 } 00617 00618 /** 00619 * @brief Return LPTIMx clock frequency 00620 * @param LPTIMxSource This parameter can be one of the following values: 00621 * @arg @ref LL_RCC_LPTIM1_CLKSOURCE 00622 * @arg @ref LL_RCC_LPTIM2_CLKSOURCE 00623 * @retval LPTIM clock frequency (in Hz) 00624 * - @ref LL_RCC_PERIPH_FREQUENCY_NO indicates that oscillator (HSI or LSE) is not ready 00625 */ 00626 uint32_t LL_RCC_GetLPTIMClockFreq(uint32_t LPTIMxSource) 00627 { 00628 uint32_t lptim_frequency = LL_RCC_PERIPH_FREQUENCY_NO; 00629 00630 /* Check parameter */ 00631 assert_param(IS_LL_RCC_LPTIM_CLKSOURCE(LPTIMxSource)); 00632 00633 if (LPTIMxSource == LL_RCC_LPTIM1_CLKSOURCE) 00634 { 00635 /* LPTIM1CLK clock frequency */ 00636 switch (LL_RCC_GetLPTIMClockSource(LPTIMxSource)) 00637 { 00638 case LL_RCC_LPTIM1_CLKSOURCE_LSI: /* LPTIM1 Clock is LSI Osc. */ 00639 if (LL_RCC_LSI_IsReady()) 00640 { 00641 lptim_frequency = LSI_VALUE; 00642 } 00643 break; 00644 00645 case LL_RCC_LPTIM1_CLKSOURCE_HSI: /* LPTIM1 Clock is HSI Osc. */ 00646 if (LL_RCC_HSI_IsReady()) 00647 { 00648 lptim_frequency = HSI_VALUE; 00649 } 00650 break; 00651 00652 case LL_RCC_LPTIM1_CLKSOURCE_LSE: /* LPTIM1 Clock is LSE Osc. */ 00653 if (LL_RCC_LSE_IsReady()) 00654 { 00655 lptim_frequency = LSE_VALUE; 00656 } 00657 break; 00658 00659 case LL_RCC_LPTIM1_CLKSOURCE_PCLK1: /* LPTIM1 Clock is PCLK1 */ 00660 default: 00661 lptim_frequency = RCC_GetPCLK1ClockFreq(RCC_GetHCLKClockFreq(RCC_GetSystemClockFreq())); 00662 break; 00663 } 00664 } 00665 else 00666 { 00667 if (LPTIMxSource == LL_RCC_LPTIM2_CLKSOURCE) 00668 { 00669 /* LPTIM2CLK clock frequency */ 00670 switch (LL_RCC_GetLPTIMClockSource(LPTIMxSource)) 00671 { 00672 case LL_RCC_LPTIM2_CLKSOURCE_LSI: /* LPTIM2 Clock is LSI Osc. */ 00673 if (LL_RCC_LSI_IsReady()) 00674 { 00675 lptim_frequency = LSI_VALUE; 00676 } 00677 break; 00678 00679 case LL_RCC_LPTIM2_CLKSOURCE_HSI: /* LPTIM2 Clock is HSI Osc. */ 00680 if (LL_RCC_HSI_IsReady()) 00681 { 00682 lptim_frequency = HSI_VALUE; 00683 } 00684 break; 00685 00686 case LL_RCC_LPTIM2_CLKSOURCE_LSE: /* LPTIM2 Clock is LSE Osc. */ 00687 if (LL_RCC_LSE_IsReady()) 00688 { 00689 lptim_frequency = LSE_VALUE; 00690 } 00691 break; 00692 00693 case LL_RCC_LPTIM2_CLKSOURCE_PCLK1: /* LPTIM2 Clock is PCLK1 */ 00694 default: 00695 lptim_frequency = RCC_GetPCLK1ClockFreq(RCC_GetHCLKClockFreq(RCC_GetSystemClockFreq())); 00696 break; 00697 } 00698 } 00699 } 00700 00701 return lptim_frequency; 00702 } 00703 00704 /** 00705 * @brief Return SAIx clock frequency 00706 * @param SAIxSource This parameter can be one of the following values: 00707 * @arg @ref LL_RCC_SAI1_CLKSOURCE 00708 * @arg @ref LL_RCC_SAI2_CLKSOURCE (*) 00709 * 00710 * (*) value not defined in all devices. 00711 * @retval SAI clock frequency (in Hz) 00712 * - @ref LL_RCC_PERIPH_FREQUENCY_NO indicates that PLL is not ready 00713 * - @ref LL_RCC_PERIPH_FREQUENCY_NA indicates that external clock is used 00714 */ 00715 uint32_t LL_RCC_GetSAIClockFreq(uint32_t SAIxSource) 00716 { 00717 uint32_t sai_frequency = LL_RCC_PERIPH_FREQUENCY_NO; 00718 00719 /* Check parameter */ 00720 assert_param(IS_LL_RCC_SAI_CLKSOURCE(SAIxSource)); 00721 00722 if (SAIxSource == LL_RCC_SAI1_CLKSOURCE) 00723 { 00724 /* SAI1CLK clock frequency */ 00725 switch (LL_RCC_GetSAIClockSource(SAIxSource)) 00726 { 00727 case LL_RCC_SAI1_CLKSOURCE_PLLSAI1: /* PLLSAI1 clock used as SAI1 clock source */ 00728 if (LL_RCC_PLLSAI1_IsReady()) 00729 { 00730 sai_frequency = RCC_PLLSAI1_GetFreqDomain_SAI(); 00731 } 00732 break; 00733 00734 #if defined(RCC_PLLSAI2_SUPPORT) 00735 case LL_RCC_SAI1_CLKSOURCE_PLLSAI2: /* PLLSAI2 clock used as SAI1 clock source */ 00736 if (LL_RCC_PLLSAI2_IsReady()) 00737 { 00738 sai_frequency = RCC_PLLSAI2_GetFreqDomain_SAI(); 00739 } 00740 break; 00741 00742 #endif /* RCC_PLLSAI2_SUPPORT */ 00743 case LL_RCC_SAI1_CLKSOURCE_PLL: /* PLL clock used as SAI1 clock source */ 00744 if (LL_RCC_PLL_IsReady()) 00745 { 00746 sai_frequency = RCC_PLL_GetFreqDomain_SAI(); 00747 } 00748 break; 00749 00750 case LL_RCC_SAI1_CLKSOURCE_PIN: /* External input clock used as SAI1 clock source */ 00751 default: 00752 sai_frequency = LL_RCC_PERIPH_FREQUENCY_NA; 00753 break; 00754 } 00755 } 00756 else 00757 { 00758 #if defined(RCC_CCIPR_SAI2SEL) 00759 if (SAIxSource == LL_RCC_SAI2_CLKSOURCE) 00760 { 00761 /* SAI2CLK clock frequency */ 00762 switch (LL_RCC_GetSAIClockSource(SAIxSource)) 00763 { 00764 case LL_RCC_SAI2_CLKSOURCE_PLLSAI1: /* PLLSAI1 clock used as SAI2 clock source */ 00765 if (LL_RCC_PLLSAI1_IsReady()) 00766 { 00767 sai_frequency = RCC_PLLSAI1_GetFreqDomain_SAI(); 00768 } 00769 break; 00770 00771 #if defined(RCC_PLLSAI2_SUPPORT) 00772 case LL_RCC_SAI2_CLKSOURCE_PLLSAI2: /* PLLSAI2 clock used as SAI2 clock source */ 00773 if (LL_RCC_PLLSAI2_IsReady()) 00774 { 00775 sai_frequency = RCC_PLLSAI2_GetFreqDomain_SAI(); 00776 } 00777 break; 00778 00779 #endif /* RCC_PLLSAI2_SUPPORT */ 00780 case LL_RCC_SAI2_CLKSOURCE_PLL: /* PLL clock used as SAI2 clock source */ 00781 if (LL_RCC_PLL_IsReady()) 00782 { 00783 sai_frequency = RCC_PLL_GetFreqDomain_SAI(); 00784 } 00785 break; 00786 00787 case LL_RCC_SAI2_CLKSOURCE_PIN: /* External input clock used as SAI2 clock source */ 00788 default: 00789 sai_frequency = LL_RCC_PERIPH_FREQUENCY_NA; 00790 break; 00791 } 00792 } 00793 #endif /*RCC_CCIPR_SAI2SEL*/ 00794 } 00795 00796 return sai_frequency; 00797 } 00798 00799 /** 00800 * @brief Return SDMMCx clock frequency 00801 * @param SDMMCxSource This parameter can be one of the following values: 00802 * @arg @ref LL_RCC_SDMMC1_CLKSOURCE 00803 * @retval SDMMC clock frequency (in Hz) 00804 * - @ref LL_RCC_PERIPH_FREQUENCY_NO indicates that oscillator (MSI) or PLL is not ready 00805 * - @ref LL_RCC_PERIPH_FREQUENCY_NA indicates that no clock source selected 00806 */ 00807 uint32_t LL_RCC_GetSDMMCClockFreq(uint32_t SDMMCxSource) 00808 { 00809 uint32_t sdmmc_frequency = LL_RCC_PERIPH_FREQUENCY_NO; 00810 00811 /* Check parameter */ 00812 assert_param(IS_LL_RCC_SDMMC_CLKSOURCE(SDMMCxSource)); 00813 00814 /* SDMMC1CLK clock frequency */ 00815 switch (LL_RCC_GetSDMMCClockSource(SDMMCxSource)) 00816 { 00817 case LL_RCC_SDMMC1_CLKSOURCE_PLLSAI1: /* PLLSAI1 clock used as SDMMC1 clock source */ 00818 if (LL_RCC_PLLSAI1_IsReady()) 00819 { 00820 sdmmc_frequency = RCC_PLLSAI1_GetFreqDomain_48M(); 00821 } 00822 break; 00823 00824 case LL_RCC_SDMMC1_CLKSOURCE_PLL: /* PLL clock used as SDMMC1 clock source */ 00825 if (LL_RCC_PLL_IsReady()) 00826 { 00827 sdmmc_frequency = RCC_PLL_GetFreqDomain_48M(); 00828 } 00829 break; 00830 00831 case LL_RCC_SDMMC1_CLKSOURCE_MSI: /* MSI clock used as SDMMC1 clock source */ 00832 if (LL_RCC_MSI_IsReady()) 00833 { 00834 sdmmc_frequency = __LL_RCC_CALC_MSI_FREQ(LL_RCC_MSI_IsEnabledRangeSelect(), 00835 (LL_RCC_MSI_IsEnabledRangeSelect() ? 00836 LL_RCC_MSI_GetRange() : 00837 LL_RCC_MSI_GetRangeAfterStandby())); 00838 } 00839 break; 00840 00841 case LL_RCC_SDMMC1_CLKSOURCE_NONE: /* No clock used as SDMMC1 clock source */ 00842 default: 00843 sdmmc_frequency = LL_RCC_PERIPH_FREQUENCY_NA; 00844 break; 00845 } 00846 00847 return sdmmc_frequency; 00848 } 00849 00850 /** 00851 * @brief Return RNGx clock frequency 00852 * @param RNGxSource This parameter can be one of the following values: 00853 * @arg @ref LL_RCC_RNG_CLKSOURCE 00854 * @retval RNG clock frequency (in Hz) 00855 * - @ref LL_RCC_PERIPH_FREQUENCY_NO indicates that oscillator (MSI) or PLL is not ready 00856 * - @ref LL_RCC_PERIPH_FREQUENCY_NA indicates that no clock source selected 00857 */ 00858 uint32_t LL_RCC_GetRNGClockFreq(uint32_t RNGxSource) 00859 { 00860 uint32_t rng_frequency = LL_RCC_PERIPH_FREQUENCY_NO; 00861 00862 /* Check parameter */ 00863 assert_param(IS_LL_RCC_RNG_CLKSOURCE(RNGxSource)); 00864 00865 /* RNGCLK clock frequency */ 00866 switch (LL_RCC_GetRNGClockSource(RNGxSource)) 00867 { 00868 case LL_RCC_RNG_CLKSOURCE_PLLSAI1: /* PLLSAI1 clock used as RNG clock source */ 00869 if (LL_RCC_PLLSAI1_IsReady()) 00870 { 00871 rng_frequency = RCC_PLLSAI1_GetFreqDomain_48M(); 00872 } 00873 break; 00874 00875 case LL_RCC_RNG_CLKSOURCE_PLL: /* PLL clock used as RNG clock source */ 00876 if (LL_RCC_PLL_IsReady()) 00877 { 00878 rng_frequency = RCC_PLL_GetFreqDomain_48M(); 00879 } 00880 break; 00881 00882 case LL_RCC_RNG_CLKSOURCE_MSI: /* MSI clock used as RNG clock source */ 00883 if (LL_RCC_MSI_IsReady()) 00884 { 00885 rng_frequency = __LL_RCC_CALC_MSI_FREQ(LL_RCC_MSI_IsEnabledRangeSelect(), 00886 (LL_RCC_MSI_IsEnabledRangeSelect() ? 00887 LL_RCC_MSI_GetRange() : 00888 LL_RCC_MSI_GetRangeAfterStandby())); 00889 } 00890 break; 00891 00892 case LL_RCC_RNG_CLKSOURCE_NONE: /* No clock used as RNG clock source */ 00893 default: 00894 rng_frequency = LL_RCC_PERIPH_FREQUENCY_NA; 00895 break; 00896 } 00897 00898 return rng_frequency; 00899 } 00900 00901 #if defined(USB_OTG_FS) || defined(USB) 00902 /** 00903 * @brief Return USBx clock frequency 00904 * @param USBxSource This parameter can be one of the following values: 00905 * @arg @ref LL_RCC_USB_CLKSOURCE 00906 * @retval USB clock frequency (in Hz) 00907 * - @ref LL_RCC_PERIPH_FREQUENCY_NO indicates that oscillator (MSI) or PLL is not ready 00908 * - @ref LL_RCC_PERIPH_FREQUENCY_NA indicates that no clock source selected 00909 */ 00910 uint32_t LL_RCC_GetUSBClockFreq(uint32_t USBxSource) 00911 { 00912 uint32_t usb_frequency = LL_RCC_PERIPH_FREQUENCY_NO; 00913 00914 /* Check parameter */ 00915 assert_param(IS_LL_RCC_USB_CLKSOURCE(USBxSource)); 00916 00917 /* USBCLK clock frequency */ 00918 switch (LL_RCC_GetUSBClockSource(USBxSource)) 00919 { 00920 case LL_RCC_USB_CLKSOURCE_PLLSAI1: /* PLLSAI1 clock used as USB clock source */ 00921 if (LL_RCC_PLLSAI1_IsReady()) 00922 { 00923 usb_frequency = RCC_PLLSAI1_GetFreqDomain_48M(); 00924 } 00925 break; 00926 00927 case LL_RCC_USB_CLKSOURCE_PLL: /* PLL clock used as USB clock source */ 00928 if (LL_RCC_PLL_IsReady()) 00929 { 00930 usb_frequency = RCC_PLL_GetFreqDomain_48M(); 00931 } 00932 break; 00933 00934 case LL_RCC_USB_CLKSOURCE_MSI: /* MSI clock used as USB clock source */ 00935 if (LL_RCC_MSI_IsReady()) 00936 { 00937 usb_frequency = __LL_RCC_CALC_MSI_FREQ(LL_RCC_MSI_IsEnabledRangeSelect(), 00938 (LL_RCC_MSI_IsEnabledRangeSelect() ? 00939 LL_RCC_MSI_GetRange() : 00940 LL_RCC_MSI_GetRangeAfterStandby())); 00941 } 00942 break; 00943 00944 case LL_RCC_USB_CLKSOURCE_NONE: /* No clock used as USB clock source */ 00945 default: 00946 usb_frequency = LL_RCC_PERIPH_FREQUENCY_NA; 00947 break; 00948 } 00949 00950 return usb_frequency; 00951 } 00952 #endif /* USB_OTG_FS || USB */ 00953 00954 /** 00955 * @brief Return ADCx clock frequency 00956 * @param ADCxSource This parameter can be one of the following values: 00957 * @arg @ref LL_RCC_ADC_CLKSOURCE 00958 * @retval ADC clock frequency (in Hz) 00959 * - @ref LL_RCC_PERIPH_FREQUENCY_NO indicates that oscillator (MSI) or PLL is not ready 00960 * - @ref LL_RCC_PERIPH_FREQUENCY_NA indicates that no clock source selected 00961 */ 00962 uint32_t LL_RCC_GetADCClockFreq(uint32_t ADCxSource) 00963 { 00964 uint32_t adc_frequency = LL_RCC_PERIPH_FREQUENCY_NO; 00965 00966 /* Check parameter */ 00967 assert_param(IS_LL_RCC_ADC_CLKSOURCE(ADCxSource)); 00968 00969 /* ADCCLK clock frequency */ 00970 switch (LL_RCC_GetADCClockSource(ADCxSource)) 00971 { 00972 case LL_RCC_ADC_CLKSOURCE_PLLSAI1: /* PLLSAI1 clock used as ADC clock source */ 00973 if (LL_RCC_PLLSAI1_IsReady()) 00974 { 00975 adc_frequency = RCC_PLLSAI1_GetFreqDomain_ADC(); 00976 } 00977 break; 00978 00979 #if defined(RCC_PLLSAI2_SUPPORT) 00980 case LL_RCC_ADC_CLKSOURCE_PLLSAI2: /* PLLSAI2 clock used as ADC clock source */ 00981 if (LL_RCC_PLLSAI2_IsReady()) 00982 { 00983 adc_frequency = RCC_PLLSAI2_GetFreqDomain_ADC(); 00984 } 00985 break; 00986 #endif /* RCC_PLLSAI2_SUPPORT */ 00987 00988 case LL_RCC_ADC_CLKSOURCE_SYSCLK: /* SYSCLK clock used as ADC clock source */ 00989 adc_frequency = RCC_GetSystemClockFreq(); 00990 break; 00991 case LL_RCC_ADC_CLKSOURCE_NONE: /* No clock used as ADC clock source */ 00992 default: 00993 adc_frequency = LL_RCC_PERIPH_FREQUENCY_NA; 00994 break; 00995 } 00996 00997 return adc_frequency; 00998 } 00999 01000 /** 01001 * @brief Return SWPMIx clock frequency 01002 * @param SWPMIxSource This parameter can be one of the following values: 01003 * @arg @ref LL_RCC_SWPMI1_CLKSOURCE 01004 * @retval SWPMI clock frequency (in Hz) 01005 * - @ref LL_RCC_PERIPH_FREQUENCY_NO indicates that oscillator (HSI) is not ready 01006 */ 01007 uint32_t LL_RCC_GetSWPMIClockFreq(uint32_t SWPMIxSource) 01008 { 01009 uint32_t swpmi_frequency = LL_RCC_PERIPH_FREQUENCY_NO; 01010 01011 /* Check parameter */ 01012 assert_param(IS_LL_RCC_SWPMI_CLKSOURCE(SWPMIxSource)); 01013 01014 /* SWPMI1CLK clock frequency */ 01015 switch (LL_RCC_GetSWPMIClockSource(SWPMIxSource)) 01016 { 01017 case LL_RCC_SWPMI1_CLKSOURCE_HSI: /* SWPMI1 Clock is HSI Osc. */ 01018 if (LL_RCC_HSI_IsReady()) 01019 { 01020 swpmi_frequency = HSI_VALUE; 01021 } 01022 break; 01023 01024 case LL_RCC_SWPMI1_CLKSOURCE_PCLK: /* SWPMI1 Clock is PCLK1 */ 01025 default: 01026 swpmi_frequency = RCC_GetPCLK1ClockFreq(RCC_GetHCLKClockFreq(RCC_GetSystemClockFreq())); 01027 break; 01028 } 01029 01030 return swpmi_frequency; 01031 } 01032 01033 #if defined(DFSDM1_Channel0) 01034 /** 01035 * @brief Return DFSDMx clock frequency 01036 * @param DFSDMxSource This parameter can be one of the following values: 01037 * @arg @ref LL_RCC_DFSDM1_CLKSOURCE 01038 * @retval DFSDM clock frequency (in Hz) 01039 */ 01040 uint32_t LL_RCC_GetDFSDMClockFreq(uint32_t DFSDMxSource) 01041 { 01042 uint32_t dfsdm_frequency = LL_RCC_PERIPH_FREQUENCY_NO; 01043 01044 /* Check parameter */ 01045 assert_param(IS_LL_RCC_DFSDM_CLKSOURCE(DFSDMxSource)); 01046 01047 /* DFSDM1CLK clock frequency */ 01048 switch (LL_RCC_GetDFSDMClockSource(DFSDMxSource)) 01049 { 01050 case LL_RCC_DFSDM1_CLKSOURCE_SYSCLK: /* DFSDM1 Clock is SYSCLK */ 01051 dfsdm_frequency = RCC_GetSystemClockFreq(); 01052 break; 01053 01054 case LL_RCC_DFSDM1_CLKSOURCE_PCLK: /* DFSDM1 Clock is PCLK1 */ 01055 default: 01056 dfsdm_frequency = RCC_GetPCLK1ClockFreq(RCC_GetHCLKClockFreq(RCC_GetSystemClockFreq())); 01057 break; 01058 } 01059 01060 return dfsdm_frequency; 01061 } 01062 #endif /* DFSDM1_Channel0 */ 01063 01064 /** 01065 * @} 01066 */ 01067 01068 /** 01069 * @} 01070 */ 01071 01072 /** @addtogroup RCC_LL_Private_Functions 01073 * @{ 01074 */ 01075 01076 /** 01077 * @brief Return SYSTEM clock frequency 01078 * @retval SYSTEM clock frequency (in Hz) 01079 */ 01080 uint32_t RCC_GetSystemClockFreq(void) 01081 { 01082 uint32_t frequency = 0; 01083 01084 /* Get SYSCLK source -------------------------------------------------------*/ 01085 switch (LL_RCC_GetSysClkSource()) 01086 { 01087 case LL_RCC_SYS_CLKSOURCE_STATUS_MSI: /* MSI used as system clock source */ 01088 frequency = __LL_RCC_CALC_MSI_FREQ(LL_RCC_MSI_IsEnabledRangeSelect(), 01089 (LL_RCC_MSI_IsEnabledRangeSelect() ? 01090 LL_RCC_MSI_GetRange() : 01091 LL_RCC_MSI_GetRangeAfterStandby())); 01092 break; 01093 01094 case LL_RCC_SYS_CLKSOURCE_STATUS_HSI: /* HSI used as system clock source */ 01095 frequency = HSI_VALUE; 01096 break; 01097 01098 case LL_RCC_SYS_CLKSOURCE_STATUS_HSE: /* HSE used as system clock source */ 01099 frequency = HSE_VALUE; 01100 break; 01101 01102 case LL_RCC_SYS_CLKSOURCE_STATUS_PLL: /* PLL used as system clock source */ 01103 frequency = RCC_PLL_GetFreqDomain_SYS(); 01104 break; 01105 01106 default: 01107 frequency = __LL_RCC_CALC_MSI_FREQ(LL_RCC_MSI_IsEnabledRangeSelect(), 01108 (LL_RCC_MSI_IsEnabledRangeSelect() ? 01109 LL_RCC_MSI_GetRange() : 01110 LL_RCC_MSI_GetRangeAfterStandby())); 01111 break; 01112 } 01113 01114 return frequency; 01115 } 01116 01117 /** 01118 * @brief Return HCLK clock frequency 01119 * @param SYSCLK_Frequency SYSCLK clock frequency 01120 * @retval HCLK clock frequency (in Hz) 01121 */ 01122 uint32_t RCC_GetHCLKClockFreq(uint32_t SYSCLK_Frequency) 01123 { 01124 /* HCLK clock frequency */ 01125 return __LL_RCC_CALC_HCLK_FREQ(SYSCLK_Frequency, LL_RCC_GetAHBPrescaler()); 01126 } 01127 01128 /** 01129 * @brief Return PCLK1 clock frequency 01130 * @param HCLK_Frequency HCLK clock frequency 01131 * @retval PCLK1 clock frequency (in Hz) 01132 */ 01133 uint32_t RCC_GetPCLK1ClockFreq(uint32_t HCLK_Frequency) 01134 { 01135 /* PCLK1 clock frequency */ 01136 return __LL_RCC_CALC_PCLK1_FREQ(HCLK_Frequency, LL_RCC_GetAPB1Prescaler()); 01137 } 01138 01139 /** 01140 * @brief Return PCLK2 clock frequency 01141 * @param HCLK_Frequency HCLK clock frequency 01142 * @retval PCLK2 clock frequency (in Hz) 01143 */ 01144 uint32_t RCC_GetPCLK2ClockFreq(uint32_t HCLK_Frequency) 01145 { 01146 /* PCLK2 clock frequency */ 01147 return __LL_RCC_CALC_PCLK2_FREQ(HCLK_Frequency, LL_RCC_GetAPB2Prescaler()); 01148 } 01149 01150 /** 01151 * @brief Return PLL clock frequency used for system domain 01152 * @retval PLL clock frequency (in Hz) 01153 */ 01154 uint32_t RCC_PLL_GetFreqDomain_SYS(void) 01155 { 01156 uint32_t pllinputfreq = 0, pllsource = 0; 01157 01158 /* PLL_VCO = (HSE_VALUE or HSI_VALUE or MSI_VALUE/ PLLM) * PLLN 01159 SYSCLK = PLL_VCO / PLLR 01160 */ 01161 pllsource = LL_RCC_PLL_GetMainSource(); 01162 01163 switch (pllsource) 01164 { 01165 case LL_RCC_PLLSOURCE_MSI: /* MSI used as PLL clock source */ 01166 pllinputfreq = __LL_RCC_CALC_MSI_FREQ(LL_RCC_MSI_IsEnabledRangeSelect(), 01167 (LL_RCC_MSI_IsEnabledRangeSelect() ? 01168 LL_RCC_MSI_GetRange() : 01169 LL_RCC_MSI_GetRangeAfterStandby())); 01170 break; 01171 01172 case LL_RCC_PLLSOURCE_HSI: /* HSI used as PLL clock source */ 01173 pllinputfreq = HSI_VALUE; 01174 break; 01175 01176 case LL_RCC_PLLSOURCE_HSE: /* HSE used as PLL clock source */ 01177 pllinputfreq = HSE_VALUE; 01178 break; 01179 01180 default: 01181 pllinputfreq = __LL_RCC_CALC_MSI_FREQ(LL_RCC_MSI_IsEnabledRangeSelect(), 01182 (LL_RCC_MSI_IsEnabledRangeSelect() ? 01183 LL_RCC_MSI_GetRange() : 01184 LL_RCC_MSI_GetRangeAfterStandby())); 01185 break; 01186 } 01187 return __LL_RCC_CALC_PLLCLK_FREQ(pllinputfreq, LL_RCC_PLL_GetDivider(), 01188 LL_RCC_PLL_GetN(), LL_RCC_PLL_GetR()); 01189 } 01190 /** 01191 * @brief Return PLL clock frequency used for SAI domain 01192 * @retval PLL clock frequency (in Hz) 01193 */ 01194 uint32_t RCC_PLL_GetFreqDomain_SAI(void) 01195 { 01196 uint32_t pllinputfreq = 0, pllsource = 0; 01197 01198 /* PLL_VCO = (HSE_VALUE or HSI_VALUE or MSI_VALUE / PLLM) * PLLN 01199 SAI Domain clock = PLL_VCO / PLLP 01200 */ 01201 pllsource = LL_RCC_PLL_GetMainSource(); 01202 01203 switch (pllsource) 01204 { 01205 case LL_RCC_PLLSOURCE_MSI: /* MSI used as PLL clock source */ 01206 pllinputfreq = __LL_RCC_CALC_MSI_FREQ(LL_RCC_MSI_IsEnabledRangeSelect(), 01207 (LL_RCC_MSI_IsEnabledRangeSelect() ? 01208 LL_RCC_MSI_GetRange() : 01209 LL_RCC_MSI_GetRangeAfterStandby())); 01210 break; 01211 01212 case LL_RCC_PLLSOURCE_HSI: /* HSI used as PLL clock source */ 01213 pllinputfreq = HSI_VALUE; 01214 break; 01215 01216 case LL_RCC_PLLSOURCE_HSE: /* HSE used as PLL clock source */ 01217 pllinputfreq = HSE_VALUE; 01218 break; 01219 01220 default: 01221 pllinputfreq = __LL_RCC_CALC_MSI_FREQ(LL_RCC_MSI_IsEnabledRangeSelect(), 01222 (LL_RCC_MSI_IsEnabledRangeSelect() ? 01223 LL_RCC_MSI_GetRange() : 01224 LL_RCC_MSI_GetRangeAfterStandby())); 01225 break; 01226 } 01227 return __LL_RCC_CALC_PLLCLK_SAI_FREQ(pllinputfreq, LL_RCC_PLL_GetDivider(), 01228 LL_RCC_PLL_GetN(), LL_RCC_PLL_GetP()); 01229 } 01230 01231 /** 01232 * @brief Return PLL clock frequency used for 48 MHz domain 01233 * @retval PLL clock frequency (in Hz) 01234 */ 01235 uint32_t RCC_PLL_GetFreqDomain_48M(void) 01236 { 01237 uint32_t pllinputfreq = 0, pllsource = 0; 01238 01239 /* PLL_VCO = (HSE_VALUE or HSI_VALUE or MSI_VALUE/ PLLM) * PLLN 01240 48M Domain clock = PLL_VCO / PLLQ 01241 */ 01242 pllsource = LL_RCC_PLL_GetMainSource(); 01243 01244 switch (pllsource) 01245 { 01246 case LL_RCC_PLLSOURCE_MSI: /* MSI used as PLL clock source */ 01247 pllinputfreq = __LL_RCC_CALC_MSI_FREQ(LL_RCC_MSI_IsEnabledRangeSelect(), 01248 (LL_RCC_MSI_IsEnabledRangeSelect() ? 01249 LL_RCC_MSI_GetRange() : 01250 LL_RCC_MSI_GetRangeAfterStandby())); 01251 break; 01252 01253 case LL_RCC_PLLSOURCE_HSI: /* HSI used as PLL clock source */ 01254 pllinputfreq = HSI_VALUE; 01255 break; 01256 01257 case LL_RCC_PLLSOURCE_HSE: /* HSE used as PLL clock source */ 01258 pllinputfreq = HSE_VALUE; 01259 break; 01260 01261 default: 01262 pllinputfreq = __LL_RCC_CALC_MSI_FREQ(LL_RCC_MSI_IsEnabledRangeSelect(), 01263 (LL_RCC_MSI_IsEnabledRangeSelect() ? 01264 LL_RCC_MSI_GetRange() : 01265 LL_RCC_MSI_GetRangeAfterStandby())); 01266 break; 01267 } 01268 return __LL_RCC_CALC_PLLCLK_48M_FREQ(pllinputfreq, LL_RCC_PLL_GetDivider(), 01269 LL_RCC_PLL_GetN(), LL_RCC_PLL_GetQ()); 01270 } 01271 01272 /** 01273 * @brief Return PLLSAI1 clock frequency used for SAI domain 01274 * @retval PLLSAI1 clock frequency (in Hz) 01275 */ 01276 uint32_t RCC_PLLSAI1_GetFreqDomain_SAI(void) 01277 { 01278 uint32_t pllinputfreq = 0, pllsource = 0; 01279 01280 /* PLLSAI1_VCO = (HSE_VALUE or HSI_VALUE or MSI_VALUE/ PLLM) * PLLSAI1N 01281 SAI Domain clock = PLLSAI1_VCO / PLLSAI1P 01282 */ 01283 pllsource = LL_RCC_PLL_GetMainSource(); 01284 01285 switch (pllsource) 01286 { 01287 case LL_RCC_PLLSOURCE_MSI: /* MSI used as PLLSAI1 clock source */ 01288 pllinputfreq = __LL_RCC_CALC_MSI_FREQ(LL_RCC_MSI_IsEnabledRangeSelect(), 01289 (LL_RCC_MSI_IsEnabledRangeSelect() ? 01290 LL_RCC_MSI_GetRange() : 01291 LL_RCC_MSI_GetRangeAfterStandby())); 01292 break; 01293 01294 case LL_RCC_PLLSOURCE_HSI: /* HSI used as PLLSAI1 clock source */ 01295 pllinputfreq = HSI_VALUE; 01296 break; 01297 01298 case LL_RCC_PLLSOURCE_HSE: /* HSE used as PLLSAI1 clock source */ 01299 pllinputfreq = HSE_VALUE; 01300 break; 01301 01302 default: 01303 pllinputfreq = __LL_RCC_CALC_MSI_FREQ(LL_RCC_MSI_IsEnabledRangeSelect(), 01304 (LL_RCC_MSI_IsEnabledRangeSelect() ? 01305 LL_RCC_MSI_GetRange() : 01306 LL_RCC_MSI_GetRangeAfterStandby())); 01307 break; 01308 } 01309 return __LL_RCC_CALC_PLLSAI1_SAI_FREQ(pllinputfreq, LL_RCC_PLL_GetDivider(), 01310 LL_RCC_PLLSAI1_GetN(), LL_RCC_PLLSAI1_GetP()); 01311 } 01312 01313 /** 01314 * @brief Return PLLSAI1 clock frequency used for 48Mhz domain 01315 * @retval PLLSAI1 clock frequency (in Hz) 01316 */ 01317 uint32_t RCC_PLLSAI1_GetFreqDomain_48M(void) 01318 { 01319 uint32_t pllinputfreq = 0, pllsource = 0; 01320 01321 /* PLLSAI1_VCO = (HSE_VALUE or HSI_VALUE or MSI_VALUE/ PLLM) * PLLSAI1N 01322 48M Domain clock = PLLSAI1_VCO / PLLSAI1Q 01323 */ 01324 pllsource = LL_RCC_PLL_GetMainSource(); 01325 01326 switch (pllsource) 01327 { 01328 case LL_RCC_PLLSOURCE_MSI: /* MSI used as PLLSAI1 clock source */ 01329 pllinputfreq = __LL_RCC_CALC_MSI_FREQ(LL_RCC_MSI_IsEnabledRangeSelect(), 01330 (LL_RCC_MSI_IsEnabledRangeSelect() ? 01331 LL_RCC_MSI_GetRange() : 01332 LL_RCC_MSI_GetRangeAfterStandby())); 01333 break; 01334 01335 case LL_RCC_PLLSOURCE_HSI: /* HSI used as PLLSAI1 clock source */ 01336 pllinputfreq = HSI_VALUE; 01337 break; 01338 01339 case LL_RCC_PLLSOURCE_HSE: /* HSE used as PLLSAI1 clock source */ 01340 pllinputfreq = HSE_VALUE; 01341 break; 01342 01343 default: 01344 pllinputfreq = __LL_RCC_CALC_MSI_FREQ(LL_RCC_MSI_IsEnabledRangeSelect(), 01345 (LL_RCC_MSI_IsEnabledRangeSelect() ? 01346 LL_RCC_MSI_GetRange() : 01347 LL_RCC_MSI_GetRangeAfterStandby())); 01348 break; 01349 } 01350 return __LL_RCC_CALC_PLLSAI1_48M_FREQ(pllinputfreq, LL_RCC_PLL_GetDivider(), 01351 LL_RCC_PLLSAI1_GetN(), LL_RCC_PLLSAI1_GetQ()); 01352 } 01353 01354 /** 01355 * @brief Return PLLSAI1 clock frequency used for ADC domain 01356 * @retval PLLSAI1 clock frequency (in Hz) 01357 */ 01358 uint32_t RCC_PLLSAI1_GetFreqDomain_ADC(void) 01359 { 01360 uint32_t pllinputfreq = 0, pllsource = 0; 01361 01362 /* PLLSAI1_VCO = (HSE_VALUE or HSI_VALUE or MSI_VALUE/ PLLM) * PLLSAI1N 01363 48M Domain clock = PLLSAI1_VCO / PLLSAI1R 01364 */ 01365 pllsource = LL_RCC_PLL_GetMainSource(); 01366 01367 switch (pllsource) 01368 { 01369 case LL_RCC_PLLSOURCE_MSI: /* MSI used as PLLSAI1 clock source */ 01370 pllinputfreq = __LL_RCC_CALC_MSI_FREQ(LL_RCC_MSI_IsEnabledRangeSelect(), 01371 (LL_RCC_MSI_IsEnabledRangeSelect() ? 01372 LL_RCC_MSI_GetRange() : 01373 LL_RCC_MSI_GetRangeAfterStandby())); 01374 break; 01375 01376 case LL_RCC_PLLSOURCE_HSI: /* HSI used as PLLSAI1 clock source */ 01377 pllinputfreq = HSI_VALUE; 01378 break; 01379 01380 case LL_RCC_PLLSOURCE_HSE: /* HSE used as PLLSAI1 clock source */ 01381 pllinputfreq = HSE_VALUE; 01382 break; 01383 01384 default: 01385 pllinputfreq = __LL_RCC_CALC_MSI_FREQ(LL_RCC_MSI_IsEnabledRangeSelect(), 01386 (LL_RCC_MSI_IsEnabledRangeSelect() ? 01387 LL_RCC_MSI_GetRange() : 01388 LL_RCC_MSI_GetRangeAfterStandby())); 01389 break; 01390 } 01391 return __LL_RCC_CALC_PLLSAI1_ADC_FREQ(pllinputfreq, LL_RCC_PLL_GetDivider(), 01392 LL_RCC_PLLSAI1_GetN(), LL_RCC_PLLSAI1_GetR()); 01393 } 01394 01395 #if defined(RCC_PLLSAI2_SUPPORT) 01396 /** 01397 * @brief Return PLLSAI2 clock frequency used for SAI domain 01398 * @retval PLLSAI2 clock frequency (in Hz) 01399 */ 01400 uint32_t RCC_PLLSAI2_GetFreqDomain_SAI(void) 01401 { 01402 uint32_t pllinputfreq = 0, pllsource = 0; 01403 01404 /* PLLSAI2_VCO = (HSE_VALUE or HSI_VALUE or MSI_VALUE/ PLLM) * PLLSAI2N 01405 SAI Domain clock = PLLSAI2_VCO / PLLSAI2P 01406 */ 01407 pllsource = LL_RCC_PLL_GetMainSource(); 01408 01409 switch (pllsource) 01410 { 01411 case LL_RCC_PLLSOURCE_MSI: /* MSI used as PLLSAI2 clock source */ 01412 pllinputfreq = __LL_RCC_CALC_MSI_FREQ(LL_RCC_MSI_IsEnabledRangeSelect(), 01413 (LL_RCC_MSI_IsEnabledRangeSelect() ? 01414 LL_RCC_MSI_GetRange() : 01415 LL_RCC_MSI_GetRangeAfterStandby())); 01416 break; 01417 01418 case LL_RCC_PLLSOURCE_HSI: /* HSI used as PLLSAI2 clock source */ 01419 pllinputfreq = HSI_VALUE; 01420 break; 01421 01422 case LL_RCC_PLLSOURCE_HSE: /* HSE used as PLLSAI2 clock source */ 01423 pllinputfreq = HSE_VALUE; 01424 break; 01425 01426 default: 01427 pllinputfreq = __LL_RCC_CALC_MSI_FREQ(LL_RCC_MSI_IsEnabledRangeSelect(), 01428 (LL_RCC_MSI_IsEnabledRangeSelect() ? 01429 LL_RCC_MSI_GetRange() : 01430 LL_RCC_MSI_GetRangeAfterStandby())); 01431 break; 01432 } 01433 return __LL_RCC_CALC_PLLSAI2_SAI_FREQ(pllinputfreq, LL_RCC_PLL_GetDivider(), 01434 LL_RCC_PLLSAI2_GetN(), LL_RCC_PLLSAI2_GetP()); 01435 } 01436 01437 /** 01438 * @brief Return PLLSAI2 clock frequency used for ADC domain 01439 * @retval PLLSAI2 clock frequency (in Hz) 01440 */ 01441 uint32_t RCC_PLLSAI2_GetFreqDomain_ADC(void) 01442 { 01443 uint32_t pllinputfreq = 0, pllsource = 0; 01444 01445 /* PLLSAI2_VCO = (HSE_VALUE or HSI_VALUE or MSI_VALUE/ PLLM) * PLLSAI2N 01446 48M Domain clock = PLLSAI2_VCO / PLLSAI2R 01447 */ 01448 pllsource = LL_RCC_PLL_GetMainSource(); 01449 01450 switch (pllsource) 01451 { 01452 case LL_RCC_PLLSOURCE_MSI: /* MSI used as PLLSAI2 clock source */ 01453 pllinputfreq = __LL_RCC_CALC_MSI_FREQ(LL_RCC_MSI_IsEnabledRangeSelect(), 01454 (LL_RCC_MSI_IsEnabledRangeSelect() ? 01455 LL_RCC_MSI_GetRange() : 01456 LL_RCC_MSI_GetRangeAfterStandby())); 01457 break; 01458 01459 case LL_RCC_PLLSOURCE_HSI: /* HSI used as PLLSAI2 clock source */ 01460 pllinputfreq = HSI_VALUE; 01461 break; 01462 01463 case LL_RCC_PLLSOURCE_HSE: /* HSE used as PLLSAI2 clock source */ 01464 pllinputfreq = HSE_VALUE; 01465 break; 01466 01467 default: 01468 pllinputfreq = __LL_RCC_CALC_MSI_FREQ(LL_RCC_MSI_IsEnabledRangeSelect(), 01469 (LL_RCC_MSI_IsEnabledRangeSelect() ? 01470 LL_RCC_MSI_GetRange() : 01471 LL_RCC_MSI_GetRangeAfterStandby())); 01472 break; 01473 } 01474 return __LL_RCC_CALC_PLLSAI2_ADC_FREQ(pllinputfreq, LL_RCC_PLL_GetDivider(), 01475 LL_RCC_PLLSAI2_GetN(), LL_RCC_PLLSAI2_GetR()); 01476 } 01477 01478 #endif /*RCC_PLLSAI2_SUPPORT*/ 01479 /** 01480 * @} 01481 */ 01482 01483 /** 01484 * @} 01485 */ 01486 01487 #endif /* defined(RCC) */ 01488 01489 /** 01490 * @} 01491 */ 01492 01493 #endif /* USE_FULL_LL_DRIVER */ 01494 01495 /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
Generated on Tue Jul 12 2022 10:59:59 by
