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_hal_rcc_ex.c
00001 /** 00002 ****************************************************************************** 00003 * @file stm32l4xx_hal_rcc_ex.c 00004 * @author MCD Application Team 00005 * @version V1.5.1 00006 * @date 31-May-2016 00007 * @brief Extended RCC HAL module driver. 00008 * This file provides firmware functions to manage the following 00009 * functionalities RCC extended peripheral: 00010 * + Extended Peripheral Control functions 00011 * + Extended Clock management functions 00012 * + Extended Clock Recovery System Control functions 00013 * 00014 ****************************************************************************** 00015 * @attention 00016 * 00017 * <h2><center>© COPYRIGHT(c) 2016 STMicroelectronics</center></h2> 00018 * 00019 * Redistribution and use in source and binary forms, with or without modification, 00020 * are permitted provided that the following conditions are met: 00021 * 1. Redistributions of source code must retain the above copyright notice, 00022 * this list of conditions and the following disclaimer. 00023 * 2. Redistributions in binary form must reproduce the above copyright notice, 00024 * this list of conditions and the following disclaimer in the documentation 00025 * and/or other materials provided with the distribution. 00026 * 3. Neither the name of STMicroelectronics nor the names of its contributors 00027 * may be used to endorse or promote products derived from this software 00028 * without specific prior written permission. 00029 * 00030 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 00031 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 00032 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 00033 * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE 00034 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 00035 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 00036 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 00037 * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 00038 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 00039 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 00040 * 00041 ****************************************************************************** 00042 */ 00043 00044 /* Includes ------------------------------------------------------------------*/ 00045 #include "stm32l4xx_hal.h" 00046 00047 /** @addtogroup STM32L4xx_HAL_Driver 00048 * @{ 00049 */ 00050 00051 /** @defgroup RCCEx RCCEx 00052 * @brief RCC Extended HAL module driver 00053 * @{ 00054 */ 00055 00056 #ifdef HAL_RCC_MODULE_ENABLED 00057 00058 /* Private typedef -----------------------------------------------------------*/ 00059 /* Private defines -----------------------------------------------------------*/ 00060 /** @defgroup RCCEx_Private_Constants RCCEx Private Constants 00061 * @{ 00062 */ 00063 #define PLLSAI1_TIMEOUT_VALUE ((uint32_t)2U) /* 2 ms (minimum Tick + 1) */ 00064 #define PLLSAI2_TIMEOUT_VALUE ((uint32_t)2U) /* 2 ms (minimum Tick + 1) */ 00065 #define PLL_TIMEOUT_VALUE ((uint32_t)2U) /* 2 ms (minimum Tick + 1) */ 00066 00067 #define DIVIDER_P_UPDATE 0U 00068 #define DIVIDER_Q_UPDATE 1U 00069 #define DIVIDER_R_UPDATE 2U 00070 00071 #define __LSCO_CLK_ENABLE() __HAL_RCC_GPIOA_CLK_ENABLE() 00072 #define LSCO_GPIO_PORT GPIOA 00073 #define LSCO_PIN GPIO_PIN_2 00074 /** 00075 * @} 00076 */ 00077 00078 /* Private macros ------------------------------------------------------------*/ 00079 /* Private variables ---------------------------------------------------------*/ 00080 /* Private function prototypes -----------------------------------------------*/ 00081 /** @defgroup RCCEx_Private_Functions RCCEx Private Functions 00082 * @{ 00083 */ 00084 static HAL_StatusTypeDef RCCEx_PLLSAI1_Config(RCC_PLLSAI1InitTypeDef *PllSai1, uint32_t Divider); 00085 00086 #if defined(RCC_PLLSAI2_SUPPORT) 00087 00088 static HAL_StatusTypeDef RCCEx_PLLSAI2_Config(RCC_PLLSAI2InitTypeDef *PllSai2, uint32_t Divider); 00089 00090 #endif /* RCC_PLLSAI2_SUPPORT */ 00091 00092 /** 00093 * @} 00094 */ 00095 00096 /* Exported functions --------------------------------------------------------*/ 00097 00098 /** @defgroup RCCEx_Exported_Functions RCCEx Exported Functions 00099 * @{ 00100 */ 00101 00102 /** @defgroup RCCEx_Exported_Functions_Group1 Extended Peripheral Control functions 00103 * @brief Extended Peripheral Control functions 00104 * 00105 @verbatim 00106 =============================================================================== 00107 ##### Extended Peripheral Control functions ##### 00108 =============================================================================== 00109 [..] 00110 This subsection provides a set of functions allowing to control the RCC Clocks 00111 frequencies. 00112 [..] 00113 (@) Important note: Care must be taken when HAL_RCCEx_PeriphCLKConfig() is used to 00114 select the RTC clock source; in this case the Backup domain will be reset in 00115 order to modify the RTC Clock source, as consequence RTC registers (including 00116 the backup registers) are set to their reset values. 00117 00118 @endverbatim 00119 * @{ 00120 */ 00121 /** 00122 * @brief Initialize the RCC extended peripherals clocks according to the specified 00123 * parameters in the RCC_PeriphCLKInitTypeDef. 00124 * @param PeriphClkInit pointer to an RCC_PeriphCLKInitTypeDef structure that 00125 * contains a field PeriphClockSelection which can be a combination of the following values: 00126 * @arg @ref RCC_PERIPHCLK_RTC RTC peripheral clock 00127 * @arg @ref RCC_PERIPHCLK_ADC ADC peripheral clock 00128 @if STM32L486xx 00129 * @arg @ref RCC_PERIPHCLK_DFSDM1 DFSDM1 peripheral clock (only for devices with DFSDM1) 00130 @endif 00131 * @arg @ref RCC_PERIPHCLK_I2C1 I2C1 peripheral clock 00132 * @arg @ref RCC_PERIPHCLK_I2C2 I2C2 peripheral clock 00133 * @arg @ref RCC_PERIPHCLK_I2C3 I2C3 peripheral clock 00134 * @arg @ref RCC_PERIPHCLK_LPTIM1 LPTIM1 peripheral clock 00135 * @arg @ref RCC_PERIPHCLK_LPTIM2 LPTIM2 peripheral clock 00136 * @arg @ref RCC_PERIPHCLK_LPUART1 LPUART1 peripheral clock 00137 * @arg @ref RCC_PERIPHCLK_RNG RNG peripheral clock 00138 * @arg @ref RCC_PERIPHCLK_SAI1 SAI1 peripheral clock 00139 @if STM32L486xx 00140 * @arg @ref RCC_PERIPHCLK_SAI2 SAI2 peripheral clock (only for devices with SAI2) 00141 @endif 00142 * @arg @ref RCC_PERIPHCLK_SDMMC1 SDMMC1 peripheral clock 00143 @if STM32L443xx 00144 * @arg @ref RCC_PERIPHCLK_SWPMI1 SWPMI1 peripheral clock (only for devices with SWPMI1) 00145 @endif 00146 @if STM32L486xx 00147 * @arg @ref RCC_PERIPHCLK_SWPMI1 SWPMI1 peripheral clock (only for devices with SWPMI1) 00148 @endif 00149 * @arg @ref RCC_PERIPHCLK_USART1 USART1 peripheral clock 00150 * @arg @ref RCC_PERIPHCLK_USART2 USART1 peripheral clock 00151 * @arg @ref RCC_PERIPHCLK_USART3 USART1 peripheral clock 00152 @if STM32L486xx 00153 * @arg @ref RCC_PERIPHCLK_UART4 USART1 peripheral clock (only for devices with UART4) 00154 * @arg @ref RCC_PERIPHCLK_UART5 USART1 peripheral clock (only for devices with UART5) 00155 * @arg @ref RCC_PERIPHCLK_USB USB peripheral clock (only for devices with USB) 00156 @endif 00157 * 00158 * @note Care must be taken when HAL_RCCEx_PeriphCLKConfig() is used to select 00159 * the RTC clock source: in this case the access to Backup domain is enabled. 00160 * 00161 * @retval HAL status 00162 */ 00163 HAL_StatusTypeDef HAL_RCCEx_PeriphCLKConfig(RCC_PeriphCLKInitTypeDef *PeriphClkInit) 00164 { 00165 uint32_t tmpregister = 0; 00166 uint32_t tickstart = 0U; 00167 HAL_StatusTypeDef ret = HAL_OK; /* Intermediate status */ 00168 HAL_StatusTypeDef status = HAL_OK; /* Final status */ 00169 00170 /* Check the parameters */ 00171 assert_param(IS_RCC_PERIPHCLOCK(PeriphClkInit->PeriphClockSelection)); 00172 00173 /*-------------------------- SAI1 clock source configuration ---------------------*/ 00174 if((((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_SAI1) == RCC_PERIPHCLK_SAI1)) 00175 { 00176 /* Check the parameters */ 00177 assert_param(IS_RCC_SAI1CLK(PeriphClkInit->Sai1ClockSelection)); 00178 00179 switch(PeriphClkInit->Sai1ClockSelection) 00180 { 00181 case RCC_SAI1CLKSOURCE_PLL: /* PLL is used as clock source for SAI1*/ 00182 /* Enable SAI Clock output generated form System PLL . */ 00183 #if defined(RCC_PLLSAI2_SUPPORT) 00184 __HAL_RCC_PLLCLKOUT_ENABLE(RCC_PLL_SAI3CLK); 00185 #else 00186 __HAL_RCC_PLLCLKOUT_ENABLE(RCC_PLL_SAI2CLK); 00187 #endif /* RCC_PLLSAI2_SUPPORT */ 00188 /* SAI1 clock source config set later after clock selection check */ 00189 break; 00190 00191 case RCC_SAI1CLKSOURCE_PLLSAI1: /* PLLSAI1 is used as clock source for SAI1*/ 00192 /* PLLSAI1 input clock, parameters M, N & P configuration and clock output (PLLSAI1ClockOut) */ 00193 ret = RCCEx_PLLSAI1_Config(&(PeriphClkInit->PLLSAI1), DIVIDER_P_UPDATE); 00194 /* SAI1 clock source config set later after clock selection check */ 00195 break; 00196 00197 #if defined(RCC_PLLSAI2_SUPPORT) 00198 00199 case RCC_SAI1CLKSOURCE_PLLSAI2: /* PLLSAI2 is used as clock source for SAI1*/ 00200 /* PLLSAI2 input clock, parameters M, N & P configuration clock output (PLLSAI2ClockOut) */ 00201 ret = RCCEx_PLLSAI2_Config(&(PeriphClkInit->PLLSAI2), DIVIDER_P_UPDATE); 00202 /* SAI1 clock source config set later after clock selection check */ 00203 break; 00204 00205 #endif /* RCC_PLLSAI2_SUPPORT */ 00206 00207 case RCC_SAI1CLKSOURCE_PIN: /* External clock is used as source of SAI1 clock*/ 00208 /* SAI1 clock source config set later after clock selection check */ 00209 break; 00210 00211 default: 00212 ret = HAL_ERROR; 00213 break; 00214 } 00215 00216 if(ret == HAL_OK) 00217 { 00218 /* Set the source of SAI1 clock*/ 00219 __HAL_RCC_SAI1_CONFIG(PeriphClkInit->Sai1ClockSelection); 00220 } 00221 else 00222 { 00223 /* set overall return value */ 00224 status = ret; 00225 } 00226 } 00227 00228 #if defined(SAI2) 00229 00230 /*-------------------------- SAI2 clock source configuration ---------------------*/ 00231 if((((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_SAI2) == RCC_PERIPHCLK_SAI2)) 00232 { 00233 /* Check the parameters */ 00234 assert_param(IS_RCC_SAI2CLK(PeriphClkInit->Sai2ClockSelection)); 00235 00236 switch(PeriphClkInit->Sai2ClockSelection) 00237 { 00238 case RCC_SAI2CLKSOURCE_PLL: /* PLL is used as clock source for SAI2*/ 00239 /* Enable SAI Clock output generated form System PLL . */ 00240 __HAL_RCC_PLLCLKOUT_ENABLE(RCC_PLL_SAI3CLK); 00241 /* SAI2 clock source config set later after clock selection check */ 00242 break; 00243 00244 case RCC_SAI2CLKSOURCE_PLLSAI1: /* PLLSAI1 is used as clock source for SAI2*/ 00245 /* PLLSAI1 input clock, parameters M, N & P configuration and clock output (PLLSAI1ClockOut) */ 00246 ret = RCCEx_PLLSAI1_Config(&(PeriphClkInit->PLLSAI1), DIVIDER_P_UPDATE); 00247 /* SAI2 clock source config set later after clock selection check */ 00248 break; 00249 00250 case RCC_SAI2CLKSOURCE_PLLSAI2: /* PLLSAI2 is used as clock source for SAI2*/ 00251 /* PLLSAI2 input clock, parameters M, N & P configuration and clock output (PLLSAI2ClockOut) */ 00252 ret = RCCEx_PLLSAI2_Config(&(PeriphClkInit->PLLSAI2), DIVIDER_P_UPDATE); 00253 /* SAI2 clock source config set later after clock selection check */ 00254 break; 00255 00256 case RCC_SAI2CLKSOURCE_PIN: /* External clock is used as source of SAI2 clock*/ 00257 /* SAI2 clock source config set later after clock selection check */ 00258 break; 00259 00260 default: 00261 ret = HAL_ERROR; 00262 break; 00263 } 00264 00265 if(ret == HAL_OK) 00266 { 00267 /* Set the source of SAI2 clock*/ 00268 __HAL_RCC_SAI2_CONFIG(PeriphClkInit->Sai2ClockSelection); 00269 } 00270 else 00271 { 00272 /* set overall return value */ 00273 status = ret; 00274 } 00275 } 00276 #endif /* SAI2 */ 00277 00278 /*-------------------------- RTC clock source configuration ----------------------*/ 00279 if((PeriphClkInit->PeriphClockSelection & RCC_PERIPHCLK_RTC) == RCC_PERIPHCLK_RTC) 00280 { 00281 FlagStatus pwrclkchanged = RESET; 00282 00283 /* Check for RTC Parameters used to output RTCCLK */ 00284 assert_param(IS_RCC_RTCCLKSOURCE(PeriphClkInit->RTCClockSelection)); 00285 00286 /* Enable Power Clock */ 00287 if(__HAL_RCC_PWR_IS_CLK_DISABLED()) 00288 { 00289 __HAL_RCC_PWR_CLK_ENABLE(); 00290 pwrclkchanged = SET; 00291 } 00292 00293 /* Enable write access to Backup domain */ 00294 SET_BIT(PWR->CR1, PWR_CR1_DBP); 00295 00296 /* Wait for Backup domain Write protection disable */ 00297 tickstart = HAL_GetTick(); 00298 00299 while((PWR->CR1 & PWR_CR1_DBP) == RESET) 00300 { 00301 if((HAL_GetTick() - tickstart) > RCC_DBP_TIMEOUT_VALUE) 00302 { 00303 ret = HAL_TIMEOUT; 00304 break; 00305 } 00306 } 00307 00308 if(ret == HAL_OK) 00309 { 00310 /* Reset the Backup domain only if the RTC Clock source selection is modified from default */ 00311 tmpregister = READ_BIT(RCC->BDCR, RCC_BDCR_RTCSEL); 00312 00313 if((tmpregister != RCC_RTCCLKSOURCE_NO_CLK) && (tmpregister != PeriphClkInit->RTCClockSelection)) 00314 { 00315 /* Store the content of BDCR register before the reset of Backup Domain */ 00316 tmpregister = READ_BIT(RCC->BDCR, ~(RCC_BDCR_RTCSEL)); 00317 /* RTC Clock selection can be changed only if the Backup Domain is reset */ 00318 __HAL_RCC_BACKUPRESET_FORCE(); 00319 __HAL_RCC_BACKUPRESET_RELEASE(); 00320 /* Restore the Content of BDCR register */ 00321 RCC->BDCR = tmpregister; 00322 } 00323 00324 /* Wait for LSE reactivation if LSE was enable prior to Backup Domain reset */ 00325 if (HAL_IS_BIT_SET(tmpregister, RCC_BDCR_LSEON)) 00326 { 00327 /* Get Start Tick*/ 00328 tickstart = HAL_GetTick(); 00329 00330 /* Wait till LSE is ready */ 00331 while(READ_BIT(RCC->BDCR, RCC_BDCR_LSERDY) == RESET) 00332 { 00333 if((HAL_GetTick() - tickstart) > RCC_LSE_TIMEOUT_VALUE) 00334 { 00335 ret = HAL_TIMEOUT; 00336 break; 00337 } 00338 } 00339 } 00340 00341 if(ret == HAL_OK) 00342 { 00343 /* Apply new RTC clock source selection */ 00344 __HAL_RCC_RTC_CONFIG(PeriphClkInit->RTCClockSelection); 00345 } 00346 else 00347 { 00348 /* set overall return value */ 00349 status = ret; 00350 } 00351 } 00352 else 00353 { 00354 /* set overall return value */ 00355 status = ret; 00356 } 00357 00358 /* Restore clock configuration if changed */ 00359 if(pwrclkchanged == SET) 00360 { 00361 __HAL_RCC_PWR_CLK_DISABLE(); 00362 } 00363 } 00364 00365 /*-------------------------- USART1 clock source configuration -------------------*/ 00366 if(((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_USART1) == RCC_PERIPHCLK_USART1) 00367 { 00368 /* Check the parameters */ 00369 assert_param(IS_RCC_USART1CLKSOURCE(PeriphClkInit->Usart1ClockSelection)); 00370 00371 /* Configure the USART1 clock source */ 00372 __HAL_RCC_USART1_CONFIG(PeriphClkInit->Usart1ClockSelection); 00373 } 00374 00375 /*-------------------------- USART2 clock source configuration -------------------*/ 00376 if(((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_USART2) == RCC_PERIPHCLK_USART2) 00377 { 00378 /* Check the parameters */ 00379 assert_param(IS_RCC_USART2CLKSOURCE(PeriphClkInit->Usart2ClockSelection)); 00380 00381 /* Configure the USART2 clock source */ 00382 __HAL_RCC_USART2_CONFIG(PeriphClkInit->Usart2ClockSelection); 00383 } 00384 00385 #if defined(USART3) 00386 00387 /*-------------------------- USART3 clock source configuration -------------------*/ 00388 if(((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_USART3) == RCC_PERIPHCLK_USART3) 00389 { 00390 /* Check the parameters */ 00391 assert_param(IS_RCC_USART3CLKSOURCE(PeriphClkInit->Usart3ClockSelection)); 00392 00393 /* Configure the USART3 clock source */ 00394 __HAL_RCC_USART3_CONFIG(PeriphClkInit->Usart3ClockSelection); 00395 } 00396 00397 #endif /* USART3 */ 00398 00399 #if defined(UART4) 00400 00401 /*-------------------------- UART4 clock source configuration --------------------*/ 00402 if(((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_UART4) == RCC_PERIPHCLK_UART4) 00403 { 00404 /* Check the parameters */ 00405 assert_param(IS_RCC_UART4CLKSOURCE(PeriphClkInit->Uart4ClockSelection)); 00406 00407 /* Configure the UART4 clock source */ 00408 __HAL_RCC_UART4_CONFIG(PeriphClkInit->Uart4ClockSelection); 00409 } 00410 00411 #endif /* UART4 */ 00412 00413 #if defined(UART5) 00414 00415 /*-------------------------- UART5 clock source configuration --------------------*/ 00416 if(((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_UART5) == RCC_PERIPHCLK_UART5) 00417 { 00418 /* Check the parameters */ 00419 assert_param(IS_RCC_UART5CLKSOURCE(PeriphClkInit->Uart5ClockSelection)); 00420 00421 /* Configure the UART5 clock source */ 00422 __HAL_RCC_UART5_CONFIG(PeriphClkInit->Uart5ClockSelection); 00423 } 00424 00425 #endif /* UART5 */ 00426 00427 /*-------------------------- LPUART1 clock source configuration ------------------*/ 00428 if(((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_LPUART1) == RCC_PERIPHCLK_LPUART1) 00429 { 00430 /* Check the parameters */ 00431 assert_param(IS_RCC_LPUART1CLKSOURCE(PeriphClkInit->Lpuart1ClockSelection)); 00432 00433 /* Configure the LPUAR1 clock source */ 00434 __HAL_RCC_LPUART1_CONFIG(PeriphClkInit->Lpuart1ClockSelection); 00435 } 00436 00437 /*-------------------------- LPTIM1 clock source configuration -------------------*/ 00438 if(((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_LPTIM1) == (RCC_PERIPHCLK_LPTIM1)) 00439 { 00440 assert_param(IS_RCC_LPTIM1CLK(PeriphClkInit->Lptim1ClockSelection)); 00441 __HAL_RCC_LPTIM1_CONFIG(PeriphClkInit->Lptim1ClockSelection); 00442 } 00443 00444 /*-------------------------- LPTIM2 clock source configuration -------------------*/ 00445 if(((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_LPTIM2) == (RCC_PERIPHCLK_LPTIM2)) 00446 { 00447 assert_param(IS_RCC_LPTIM2CLK(PeriphClkInit->Lptim2ClockSelection)); 00448 __HAL_RCC_LPTIM2_CONFIG(PeriphClkInit->Lptim2ClockSelection); 00449 } 00450 00451 /*-------------------------- I2C1 clock source configuration ---------------------*/ 00452 if(((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_I2C1) == RCC_PERIPHCLK_I2C1) 00453 { 00454 /* Check the parameters */ 00455 assert_param(IS_RCC_I2C1CLKSOURCE(PeriphClkInit->I2c1ClockSelection)); 00456 00457 /* Configure the I2C1 clock source */ 00458 __HAL_RCC_I2C1_CONFIG(PeriphClkInit->I2c1ClockSelection); 00459 } 00460 00461 #if defined(I2C2) 00462 00463 /*-------------------------- I2C2 clock source configuration ---------------------*/ 00464 if(((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_I2C2) == RCC_PERIPHCLK_I2C2) 00465 { 00466 /* Check the parameters */ 00467 assert_param(IS_RCC_I2C2CLKSOURCE(PeriphClkInit->I2c2ClockSelection)); 00468 00469 /* Configure the I2C2 clock source */ 00470 __HAL_RCC_I2C2_CONFIG(PeriphClkInit->I2c2ClockSelection); 00471 } 00472 00473 #endif /* I2C2 */ 00474 00475 /*-------------------------- I2C3 clock source configuration ---------------------*/ 00476 if(((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_I2C3) == RCC_PERIPHCLK_I2C3) 00477 { 00478 /* Check the parameters */ 00479 assert_param(IS_RCC_I2C3CLKSOURCE(PeriphClkInit->I2c3ClockSelection)); 00480 00481 /* Configure the I2C3 clock source */ 00482 __HAL_RCC_I2C3_CONFIG(PeriphClkInit->I2c3ClockSelection); 00483 } 00484 00485 #if defined(USB_OTG_FS) || defined(USB) 00486 00487 /*-------------------------- USB clock source configuration ----------------------*/ 00488 if(((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_USB) == (RCC_PERIPHCLK_USB)) 00489 { 00490 assert_param(IS_RCC_USBCLKSOURCE(PeriphClkInit->UsbClockSelection)); 00491 __HAL_RCC_USB_CONFIG(PeriphClkInit->UsbClockSelection); 00492 00493 if(PeriphClkInit->UsbClockSelection == RCC_USBCLKSOURCE_PLL) 00494 { 00495 /* Enable PLL48M1CLK output */ 00496 __HAL_RCC_PLLCLKOUT_ENABLE(RCC_PLL_48M1CLK); 00497 } 00498 else if(PeriphClkInit->UsbClockSelection == RCC_USBCLKSOURCE_PLLSAI1) 00499 { 00500 /* PLLSAI1 input clock, parameters M, N & Q configuration and clock output (PLLSAI1ClockOut) */ 00501 ret = RCCEx_PLLSAI1_Config(&(PeriphClkInit->PLLSAI1), DIVIDER_Q_UPDATE); 00502 00503 if(ret != HAL_OK) 00504 { 00505 /* set overall return value */ 00506 status = ret; 00507 } 00508 } 00509 } 00510 00511 #endif /* USB_OTG_FS || USB */ 00512 00513 #if defined(SDMMC1) 00514 00515 /*-------------------------- SDMMC1 clock source configuration -------------------*/ 00516 if(((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_SDMMC1) == (RCC_PERIPHCLK_SDMMC1)) 00517 { 00518 assert_param(IS_RCC_SDMMC1CLKSOURCE(PeriphClkInit->Sdmmc1ClockSelection)); 00519 __HAL_RCC_SDMMC1_CONFIG(PeriphClkInit->Sdmmc1ClockSelection); 00520 00521 if(PeriphClkInit->Sdmmc1ClockSelection == RCC_SDMMC1CLKSOURCE_PLL) 00522 { 00523 /* Enable PLL48M1CLK output */ 00524 __HAL_RCC_PLLCLKOUT_ENABLE(RCC_PLL_48M1CLK); 00525 } 00526 else if(PeriphClkInit->Sdmmc1ClockSelection == RCC_SDMMC1CLKSOURCE_PLLSAI1) 00527 { 00528 /* PLLSAI1 input clock, parameters M, N & Q configuration and clock output (PLLSAI1ClockOut) */ 00529 ret = RCCEx_PLLSAI1_Config(&(PeriphClkInit->PLLSAI1), DIVIDER_Q_UPDATE); 00530 00531 if(ret != HAL_OK) 00532 { 00533 /* set overall return value */ 00534 status = ret; 00535 } 00536 } 00537 } 00538 00539 #endif /* SDMMC1 */ 00540 00541 /*-------------------------- RNG clock source configuration ----------------------*/ 00542 if(((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_RNG) == (RCC_PERIPHCLK_RNG)) 00543 { 00544 assert_param(IS_RCC_RNGCLKSOURCE(PeriphClkInit->RngClockSelection)); 00545 __HAL_RCC_RNG_CONFIG(PeriphClkInit->RngClockSelection); 00546 00547 if(PeriphClkInit->RngClockSelection == RCC_RNGCLKSOURCE_PLL) 00548 { 00549 /* Enable PLL48M1CLK output */ 00550 __HAL_RCC_PLLCLKOUT_ENABLE(RCC_PLL_48M1CLK); 00551 } 00552 else if(PeriphClkInit->RngClockSelection == RCC_RNGCLKSOURCE_PLLSAI1) 00553 { 00554 /* PLLSAI1 input clock, parameters M, N & Q configuration and clock output (PLLSAI1ClockOut) */ 00555 ret = RCCEx_PLLSAI1_Config(&(PeriphClkInit->PLLSAI1), DIVIDER_Q_UPDATE); 00556 00557 if(ret != HAL_OK) 00558 { 00559 /* set overall return value */ 00560 status = ret; 00561 } 00562 } 00563 } 00564 00565 /*-------------------------- ADC clock source configuration ----------------------*/ 00566 if(((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_ADC) == RCC_PERIPHCLK_ADC) 00567 { 00568 /* Check the parameters */ 00569 assert_param(IS_RCC_ADCCLKSOURCE(PeriphClkInit->AdcClockSelection)); 00570 00571 /* Configure the ADC interface clock source */ 00572 __HAL_RCC_ADC_CONFIG(PeriphClkInit->AdcClockSelection); 00573 00574 if(PeriphClkInit->AdcClockSelection == RCC_ADCCLKSOURCE_PLLSAI1) 00575 { 00576 /* PLLSAI1 input clock, parameters M, N & R configuration and clock output (PLLSAI1ClockOut) */ 00577 ret = RCCEx_PLLSAI1_Config(&(PeriphClkInit->PLLSAI1), DIVIDER_R_UPDATE); 00578 00579 if(ret != HAL_OK) 00580 { 00581 /* set overall return value */ 00582 status = ret; 00583 } 00584 } 00585 00586 #if defined(STM32L471xx) || defined(STM32L475xx) || defined(STM32L476xx) || defined(STM32L485xx) || defined(STM32L486xx) 00587 00588 else if(PeriphClkInit->AdcClockSelection == RCC_ADCCLKSOURCE_PLLSAI2) 00589 { 00590 /* PLLSAI2 input clock, parameters M, N & R configuration and clock output (PLLSAI2ClockOut) */ 00591 ret = RCCEx_PLLSAI2_Config(&(PeriphClkInit->PLLSAI2), DIVIDER_R_UPDATE); 00592 00593 if(ret != HAL_OK) 00594 { 00595 /* set overall return value */ 00596 status = ret; 00597 } 00598 } 00599 00600 #endif /* STM32L471xx || STM32L475xx || STM32L476xx || STM32L485xx || STM32L486xx */ 00601 00602 } 00603 00604 #if defined(SWPMI1) 00605 00606 /*-------------------------- SWPMI1 clock source configuration -------------------*/ 00607 if(((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_SWPMI1) == RCC_PERIPHCLK_SWPMI1) 00608 { 00609 /* Check the parameters */ 00610 assert_param(IS_RCC_SWPMI1CLKSOURCE(PeriphClkInit->Swpmi1ClockSelection)); 00611 00612 /* Configure the SWPMI1 clock source */ 00613 __HAL_RCC_SWPMI1_CONFIG(PeriphClkInit->Swpmi1ClockSelection); 00614 } 00615 00616 #endif /* SWPMI1 */ 00617 00618 #if defined(DFSDM1_Filter0) 00619 00620 /*-------------------------- DFSDM1 clock source configuration -------------------*/ 00621 if(((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_DFSDM1) == RCC_PERIPHCLK_DFSDM1) 00622 { 00623 /* Check the parameters */ 00624 assert_param(IS_RCC_DFSDM1CLKSOURCE(PeriphClkInit->Dfsdm1ClockSelection)); 00625 00626 /* Configure the DFSDM1 interface clock source */ 00627 __HAL_RCC_DFSDM1_CONFIG(PeriphClkInit->Dfsdm1ClockSelection); 00628 } 00629 00630 #endif /* DFSDM1_Filter0 */ 00631 00632 return status; 00633 } 00634 00635 /** 00636 * @brief Get the RCC_ClkInitStruct according to the internal RCC configuration registers. 00637 * @param PeriphClkInit pointer to an RCC_PeriphCLKInitTypeDef structure that 00638 * returns the configuration information for the Extended Peripherals 00639 * clocks(SAI1, SAI2, LPTIM1, LPTIM2, I2C1, I2C2, I2C3, LPUART, 00640 * USART1, USART2, USART3, UART4, UART5, RTC, ADCx, DFSDMx, SWPMI1, USB, SDMMC1 and RNG). 00641 * @retval None 00642 */ 00643 void HAL_RCCEx_GetPeriphCLKConfig(RCC_PeriphCLKInitTypeDef *PeriphClkInit) 00644 { 00645 /* Set all possible values for the extended clock type parameter------------*/ 00646 00647 #if defined(STM32L431xx) 00648 00649 PeriphClkInit->PeriphClockSelection = RCC_PERIPHCLK_USART1 | RCC_PERIPHCLK_USART2 | RCC_PERIPHCLK_USART3 | \ 00650 RCC_PERIPHCLK_LPUART1 | RCC_PERIPHCLK_I2C1 | RCC_PERIPHCLK_I2C2 | RCC_PERIPHCLK_I2C3 | \ 00651 RCC_PERIPHCLK_LPTIM1 | RCC_PERIPHCLK_LPTIM2 | RCC_PERIPHCLK_SAI1 | \ 00652 RCC_PERIPHCLK_SDMMC1 | RCC_PERIPHCLK_RNG | RCC_PERIPHCLK_ADC | RCC_PERIPHCLK_SWPMI1 | \ 00653 RCC_PERIPHCLK_RTC ; 00654 00655 #elif defined(STM32L432xx) || defined(STM32L442xx) 00656 00657 PeriphClkInit->PeriphClockSelection = RCC_PERIPHCLK_USART1 | RCC_PERIPHCLK_USART2 | \ 00658 RCC_PERIPHCLK_LPUART1 | RCC_PERIPHCLK_I2C1 | RCC_PERIPHCLK_I2C3 | \ 00659 RCC_PERIPHCLK_LPTIM1 | RCC_PERIPHCLK_LPTIM2 | RCC_PERIPHCLK_SAI1 | RCC_PERIPHCLK_USB | \ 00660 RCC_PERIPHCLK_RNG | RCC_PERIPHCLK_ADC | RCC_PERIPHCLK_SWPMI1 | \ 00661 RCC_PERIPHCLK_RTC ; 00662 00663 #elif defined(STM32L433xx) || defined(STM32L443xx) 00664 00665 PeriphClkInit->PeriphClockSelection = RCC_PERIPHCLK_USART1 | RCC_PERIPHCLK_USART2 | RCC_PERIPHCLK_USART3 | \ 00666 RCC_PERIPHCLK_LPUART1 | RCC_PERIPHCLK_I2C1 | RCC_PERIPHCLK_I2C2 | RCC_PERIPHCLK_I2C3 | \ 00667 RCC_PERIPHCLK_LPTIM1 | RCC_PERIPHCLK_LPTIM2 | RCC_PERIPHCLK_SAI1 | RCC_PERIPHCLK_USB | \ 00668 RCC_PERIPHCLK_SDMMC1 | RCC_PERIPHCLK_RNG | RCC_PERIPHCLK_ADC | RCC_PERIPHCLK_SWPMI1 | \ 00669 RCC_PERIPHCLK_RTC ; 00670 #elif defined(STM32L471xx) 00671 00672 PeriphClkInit->PeriphClockSelection = RCC_PERIPHCLK_USART1 | RCC_PERIPHCLK_USART2 | RCC_PERIPHCLK_USART3 | RCC_PERIPHCLK_UART4 | RCC_PERIPHCLK_UART5 | \ 00673 RCC_PERIPHCLK_LPUART1 | RCC_PERIPHCLK_I2C1 | RCC_PERIPHCLK_I2C2 | RCC_PERIPHCLK_I2C3 | \ 00674 RCC_PERIPHCLK_LPTIM1 | RCC_PERIPHCLK_LPTIM2 | RCC_PERIPHCLK_SAI1 | RCC_PERIPHCLK_SAI2 | \ 00675 RCC_PERIPHCLK_SDMMC1 | RCC_PERIPHCLK_RNG | RCC_PERIPHCLK_ADC | RCC_PERIPHCLK_SWPMI1 | RCC_PERIPHCLK_DFSDM1 | \ 00676 RCC_PERIPHCLK_RTC ; 00677 00678 #elif defined(STM32L475xx) || defined(STM32L476xx) || defined(STM32L485xx) || defined(STM32L486xx) 00679 00680 PeriphClkInit->PeriphClockSelection = RCC_PERIPHCLK_USART1 | RCC_PERIPHCLK_USART2 | RCC_PERIPHCLK_USART3 | RCC_PERIPHCLK_UART4 | RCC_PERIPHCLK_UART5 | \ 00681 RCC_PERIPHCLK_LPUART1 | RCC_PERIPHCLK_I2C1 | RCC_PERIPHCLK_I2C2 | RCC_PERIPHCLK_I2C3 | \ 00682 RCC_PERIPHCLK_LPTIM1 | RCC_PERIPHCLK_LPTIM2 | RCC_PERIPHCLK_SAI1 | RCC_PERIPHCLK_SAI2 | RCC_PERIPHCLK_USB | \ 00683 RCC_PERIPHCLK_SDMMC1 | RCC_PERIPHCLK_RNG | RCC_PERIPHCLK_ADC | RCC_PERIPHCLK_SWPMI1 | RCC_PERIPHCLK_DFSDM1 | \ 00684 RCC_PERIPHCLK_RTC ; 00685 00686 #endif /* STM32L431xx */ 00687 00688 /* Get the PLLSAI1 Clock configuration -----------------------------------------------*/ 00689 00690 PeriphClkInit->PLLSAI1.PLLSAI1Source = (uint32_t)((RCC->PLLCFGR & RCC_PLLCFGR_PLLSRC) >> POSITION_VAL(RCC_PLLCFGR_PLLSRC)); 00691 PeriphClkInit->PLLSAI1.PLLSAI1M = (uint32_t)((RCC->PLLCFGR & RCC_PLLCFGR_PLLM) >> POSITION_VAL(RCC_PLLCFGR_PLLM)) + 1U; 00692 PeriphClkInit->PLLSAI1.PLLSAI1N = (uint32_t)((RCC->PLLSAI1CFGR & RCC_PLLSAI1CFGR_PLLSAI1N) >> POSITION_VAL(RCC_PLLSAI1CFGR_PLLSAI1N)); 00693 PeriphClkInit->PLLSAI1.PLLSAI1P = (uint32_t)(((RCC->PLLSAI1CFGR & RCC_PLLSAI1CFGR_PLLSAI1P) >> POSITION_VAL(RCC_PLLSAI1CFGR_PLLSAI1P)) << 4U) + 7U; 00694 PeriphClkInit->PLLSAI1.PLLSAI1Q = (uint32_t)(((RCC->PLLSAI1CFGR & RCC_PLLSAI1CFGR_PLLSAI1Q) >> POSITION_VAL(RCC_PLLSAI1CFGR_PLLSAI1Q))+1U) * 2U; 00695 PeriphClkInit->PLLSAI1.PLLSAI1R = (uint32_t)(((RCC->PLLSAI1CFGR & RCC_PLLSAI1CFGR_PLLSAI1R) >> POSITION_VAL(RCC_PLLSAI1CFGR_PLLSAI1R))+1U) * 2U; 00696 00697 #if defined(RCC_PLLSAI2_SUPPORT) 00698 00699 /* Get the PLLSAI2 Clock configuration -----------------------------------------------*/ 00700 00701 PeriphClkInit->PLLSAI2.PLLSAI2Source = PeriphClkInit->PLLSAI1.PLLSAI1Source; 00702 PeriphClkInit->PLLSAI2.PLLSAI2M = PeriphClkInit->PLLSAI1.PLLSAI1M; 00703 PeriphClkInit->PLLSAI2.PLLSAI2N = (uint32_t)((RCC->PLLSAI2CFGR & RCC_PLLSAI2CFGR_PLLSAI2N) >> POSITION_VAL(RCC_PLLSAI2CFGR_PLLSAI2N)); 00704 PeriphClkInit->PLLSAI2.PLLSAI2P = (uint32_t)(((RCC->PLLSAI2CFGR & RCC_PLLSAI2CFGR_PLLSAI2P) >> POSITION_VAL(RCC_PLLSAI2CFGR_PLLSAI2P)) << 4U) + 7U; 00705 PeriphClkInit->PLLSAI2.PLLSAI2R = (uint32_t)(((RCC->PLLSAI2CFGR & RCC_PLLSAI2CFGR_PLLSAI2R)>> POSITION_VAL(RCC_PLLSAI2CFGR_PLLSAI2R))+1U) * 2U; 00706 00707 #endif /* RCC_PLLSAI2_SUPPORT */ 00708 00709 /* Get the USART1 clock source ---------------------------------------------*/ 00710 PeriphClkInit->Usart1ClockSelection = __HAL_RCC_GET_USART1_SOURCE(); 00711 /* Get the USART2 clock source ---------------------------------------------*/ 00712 PeriphClkInit->Usart2ClockSelection = __HAL_RCC_GET_USART2_SOURCE(); 00713 00714 #if defined(USART3) 00715 /* Get the USART3 clock source ---------------------------------------------*/ 00716 PeriphClkInit->Usart3ClockSelection = __HAL_RCC_GET_USART3_SOURCE(); 00717 #endif /* USART3 */ 00718 00719 #if defined(UART4) 00720 /* Get the UART4 clock source ----------------------------------------------*/ 00721 PeriphClkInit->Uart4ClockSelection = __HAL_RCC_GET_UART4_SOURCE(); 00722 #endif /* UART4 */ 00723 00724 #if defined(UART5) 00725 /* Get the UART5 clock source ----------------------------------------------*/ 00726 PeriphClkInit->Uart5ClockSelection = __HAL_RCC_GET_UART5_SOURCE(); 00727 #endif /* UART5 */ 00728 00729 /* Get the LPUART1 clock source --------------------------------------------*/ 00730 PeriphClkInit->Lpuart1ClockSelection = __HAL_RCC_GET_LPUART1_SOURCE(); 00731 00732 /* Get the I2C1 clock source -----------------------------------------------*/ 00733 PeriphClkInit->I2c1ClockSelection = __HAL_RCC_GET_I2C1_SOURCE(); 00734 00735 #if defined(I2C2) 00736 /* Get the I2C2 clock source ----------------------------------------------*/ 00737 PeriphClkInit->I2c2ClockSelection = __HAL_RCC_GET_I2C2_SOURCE(); 00738 #endif /* I2C2 */ 00739 00740 /* Get the I2C3 clock source -----------------------------------------------*/ 00741 PeriphClkInit->I2c3ClockSelection = __HAL_RCC_GET_I2C3_SOURCE(); 00742 00743 /* Get the LPTIM1 clock source ---------------------------------------------*/ 00744 PeriphClkInit->Lptim1ClockSelection = __HAL_RCC_GET_LPTIM1_SOURCE(); 00745 00746 /* Get the LPTIM2 clock source ---------------------------------------------*/ 00747 PeriphClkInit->Lptim2ClockSelection = __HAL_RCC_GET_LPTIM2_SOURCE(); 00748 00749 /* Get the SAI1 clock source -----------------------------------------------*/ 00750 PeriphClkInit->Sai1ClockSelection = __HAL_RCC_GET_SAI1_SOURCE(); 00751 00752 #if defined(SAI2) 00753 /* Get the SAI2 clock source -----------------------------------------------*/ 00754 PeriphClkInit->Sai2ClockSelection = __HAL_RCC_GET_SAI2_SOURCE(); 00755 #endif /* SAI2 */ 00756 00757 /* Get the RTC clock source ------------------------------------------------*/ 00758 PeriphClkInit->RTCClockSelection = __HAL_RCC_GET_RTC_SOURCE(); 00759 00760 #if defined(USB_OTG_FS) || defined(USB) 00761 /* Get the USB clock source ------------------------------------------------*/ 00762 PeriphClkInit->UsbClockSelection = __HAL_RCC_GET_USB_SOURCE(); 00763 #endif /* USB_OTG_FS || USB */ 00764 00765 #if defined(SDMMC1) 00766 /* Get the SDMMC1 clock source ---------------------------------------------*/ 00767 PeriphClkInit->Sdmmc1ClockSelection = __HAL_RCC_GET_SDMMC1_SOURCE(); 00768 #endif /* SDMMC1 */ 00769 00770 /* Get the RNG clock source ------------------------------------------------*/ 00771 PeriphClkInit->RngClockSelection = __HAL_RCC_GET_RNG_SOURCE(); 00772 00773 /* Get the ADC clock source ------------------------------------------------*/ 00774 PeriphClkInit->AdcClockSelection = __HAL_RCC_GET_ADC_SOURCE(); 00775 00776 #if defined(SWPMI1) 00777 /* Get the SWPMI1 clock source ---------------------------------------------*/ 00778 PeriphClkInit->Swpmi1ClockSelection = __HAL_RCC_GET_SWPMI1_SOURCE(); 00779 #endif /* SWPMI1 */ 00780 00781 #if defined(DFSDM1_Filter0) 00782 /* Get the DFSDM1 clock source ---------------------------------------------*/ 00783 PeriphClkInit->Dfsdm1ClockSelection = __HAL_RCC_GET_DFSDM1_SOURCE(); 00784 #endif /* DFSDM1_Filter0 */ 00785 } 00786 00787 /** 00788 * @brief Return the peripheral clock frequency for peripherals with clock source from PLLSAIs 00789 * @note Return 0 if peripheral clock identifier not managed by this API 00790 * @param PeriphClk Peripheral clock identifier 00791 * This parameter can be one of the following values: 00792 * @arg @ref RCC_PERIPHCLK_RTC RTC peripheral clock 00793 * @arg @ref RCC_PERIPHCLK_ADC ADC peripheral clock 00794 @if STM32L486xx 00795 * @arg @ref RCC_PERIPHCLK_DFSDM1 DFSDM1 peripheral clock (only for devices with DFSDM) 00796 @endif 00797 * @arg @ref RCC_PERIPHCLK_I2C1 I2C1 peripheral clock 00798 * @arg @ref RCC_PERIPHCLK_I2C2 I2C2 peripheral clock 00799 * @arg @ref RCC_PERIPHCLK_I2C3 I2C3 peripheral clock 00800 * @arg @ref RCC_PERIPHCLK_LPTIM1 LPTIM1 peripheral clock 00801 * @arg @ref RCC_PERIPHCLK_LPTIM2 LPTIM2 peripheral clock 00802 * @arg @ref RCC_PERIPHCLK_LPUART1 LPUART1 peripheral clock 00803 * @arg @ref RCC_PERIPHCLK_RNG RNG peripheral clock 00804 * @arg @ref RCC_PERIPHCLK_SAI1 SAI1 peripheral clock 00805 @if STM32L486xx 00806 * @arg @ref RCC_PERIPHCLK_SAI2 SAI2 peripheral clock (only for devices with SAI2) 00807 @endif 00808 * @arg @ref RCC_PERIPHCLK_SDMMC1 SDMMC1 peripheral clock 00809 * @arg @ref RCC_PERIPHCLK_SWPMI1 SWPMI1 peripheral clock 00810 * @arg @ref RCC_PERIPHCLK_USART1 USART1 peripheral clock 00811 * @arg @ref RCC_PERIPHCLK_USART2 USART1 peripheral clock 00812 * @arg @ref RCC_PERIPHCLK_USART3 USART1 peripheral clock 00813 @if STM32L486xx 00814 * @arg @ref RCC_PERIPHCLK_UART4 UART4 peripheral clock (only for devices with UART4) 00815 * @arg @ref RCC_PERIPHCLK_UART5 UART5 peripheral clock (only for devices with UART5) 00816 * @arg @ref RCC_PERIPHCLK_USB USB peripheral clock (only for devices with USB) 00817 @endif 00818 * @retval Frequency in Hz 00819 */ 00820 uint32_t HAL_RCCEx_GetPeriphCLKFreq(uint32_t PeriphClk) 00821 { 00822 uint32_t frequency = 0U; 00823 uint32_t srcclk = 0U; 00824 uint32_t pllvco = 0U, plln = 0U, pllp = 0U; 00825 00826 /* Check the parameters */ 00827 assert_param(IS_RCC_PERIPHCLOCK(PeriphClk)); 00828 00829 if(PeriphClk == RCC_PERIPHCLK_RTC) 00830 { 00831 /* Get the current RTC source */ 00832 srcclk = __HAL_RCC_GET_RTC_SOURCE(); 00833 00834 /* Check if LSE is ready and if RTC clock selection is LSE */ 00835 if ((srcclk == RCC_RTCCLKSOURCE_LSE) && (HAL_IS_BIT_SET(RCC->BDCR, RCC_BDCR_LSERDY))) 00836 { 00837 frequency = LSE_VALUE; 00838 } 00839 /* Check if LSI is ready and if RTC clock selection is LSI */ 00840 else if ((srcclk == RCC_RTCCLKSOURCE_LSI) && (HAL_IS_BIT_SET(RCC->CSR, RCC_CSR_LSIRDY))) 00841 { 00842 frequency = LSI_VALUE; 00843 } 00844 /* Check if HSE is ready and if RTC clock selection is HSI_DIV32*/ 00845 else if ((srcclk == RCC_RTCCLKSOURCE_HSE_DIV32) && (HAL_IS_BIT_SET(RCC->CR, RCC_CR_HSERDY))) 00846 { 00847 frequency = HSE_VALUE / 32; 00848 } 00849 /* Clock not enabled for RTC*/ 00850 else 00851 { 00852 frequency = 0U; 00853 } 00854 } 00855 else 00856 { 00857 /* Other external peripheral clock source than RTC */ 00858 00859 /* Compute PLL clock input */ 00860 if(__HAL_RCC_GET_PLL_OSCSOURCE() == RCC_PLLSOURCE_MSI) /* MSI ? */ 00861 { 00862 if(HAL_IS_BIT_SET(RCC->CR, RCC_CR_MSIRDY)) 00863 { 00864 pllvco = (1U << ((__HAL_RCC_GET_MSI_RANGE() >> 4U) - 4U)) * 1000000U; 00865 } 00866 else 00867 { 00868 pllvco = 0U; 00869 } 00870 } 00871 else if(__HAL_RCC_GET_PLL_OSCSOURCE() == RCC_PLLSOURCE_HSI) /* HSI ? */ 00872 { 00873 if(HAL_IS_BIT_SET(RCC->CR, RCC_CR_HSIRDY)) 00874 { 00875 pllvco = HSI_VALUE; 00876 } 00877 else 00878 { 00879 pllvco = 0U; 00880 } 00881 } 00882 else if(__HAL_RCC_GET_PLL_OSCSOURCE() == RCC_PLLSOURCE_HSE) /* HSE ? */ 00883 { 00884 if(HAL_IS_BIT_SET(RCC->CR, RCC_CR_HSERDY)) 00885 { 00886 pllvco = HSE_VALUE; 00887 } 00888 else 00889 { 00890 pllvco = 0U; 00891 } 00892 } 00893 else /* No source */ 00894 { 00895 pllvco = 0U; 00896 } 00897 00898 /* f(PLL Source) / PLLM */ 00899 pllvco = (pllvco / ((READ_BIT(RCC->PLLCFGR, RCC_PLLCFGR_PLLM) >> POSITION_VAL(RCC_PLLCFGR_PLLM)) + 1U)); 00900 00901 switch(PeriphClk) 00902 { 00903 #if defined(SAI2) 00904 00905 case RCC_PERIPHCLK_SAI1: 00906 case RCC_PERIPHCLK_SAI2: 00907 00908 if(PeriphClk == RCC_PERIPHCLK_SAI1) 00909 { 00910 srcclk = __HAL_RCC_GET_SAI1_SOURCE(); 00911 00912 if(srcclk == RCC_SAI1CLKSOURCE_PIN) 00913 { 00914 frequency = EXTERNAL_SAI1_CLOCK_VALUE; 00915 } 00916 /* Else, PLL clock output to check below */ 00917 } 00918 else /* RCC_PERIPHCLK_SAI2 */ 00919 { 00920 srcclk = __HAL_RCC_GET_SAI2_SOURCE(); 00921 00922 if(srcclk == RCC_SAI2CLKSOURCE_PIN) 00923 { 00924 frequency = EXTERNAL_SAI2_CLOCK_VALUE; 00925 } 00926 /* Else, PLL clock output to check below */ 00927 } 00928 00929 #else 00930 00931 case RCC_PERIPHCLK_SAI1: 00932 00933 if(PeriphClk == RCC_PERIPHCLK_SAI1) 00934 { 00935 srcclk = READ_BIT(RCC->CCIPR, RCC_CCIPR_SAI1SEL); 00936 00937 if(srcclk == RCC_SAI1CLKSOURCE_PIN) 00938 { 00939 frequency = EXTERNAL_SAI1_CLOCK_VALUE; 00940 } 00941 /* Else, PLL clock output to check below */ 00942 } 00943 00944 #endif /* SAI2 */ 00945 00946 if(frequency == 0U) 00947 { 00948 #if defined(SAI2) 00949 if((srcclk == RCC_SAI1CLKSOURCE_PLL) || (srcclk == RCC_SAI2CLKSOURCE_PLL)) 00950 { 00951 if(__HAL_RCC_GET_PLLCLKOUT_CONFIG(RCC_PLL_SAI3CLK) != RESET) 00952 { 00953 /* f(PLLSAI3CLK) = f(VCO input) * PLLN / PLLP */ 00954 plln = READ_BIT(RCC->PLLCFGR, RCC_PLLCFGR_PLLN) >> POSITION_VAL(RCC_PLLCFGR_PLLN); 00955 #if defined(RCC_PLLP_DIV_2_31_SUPPORT) 00956 pllp = READ_BIT(RCC->PLLCFGR, RCC_PLLCFGR_PLLPDIV) >> POSITION_VAL(RCC_PLLCFGR_PLLPDIV); 00957 #endif 00958 if(pllp == 0U) 00959 { 00960 if(READ_BIT(RCC->PLLCFGR, RCC_PLLCFGR_PLLP) != RESET) 00961 { 00962 pllp = 17U; 00963 } 00964 else 00965 { 00966 pllp = 7U; 00967 } 00968 } 00969 frequency = (pllvco * plln) / pllp; 00970 } 00971 } 00972 else if(srcclk == 0U) /* RCC_SAI1CLKSOURCE_PLLSAI1 || RCC_SAI2CLKSOURCE_PLLSAI1 */ 00973 { 00974 if(__HAL_RCC_GET_PLLSAI1CLKOUT_CONFIG(RCC_PLLSAI1_SAI1CLK) != RESET) 00975 { 00976 /* f(PLLSAI1CLK) = f(VCOSAI1 input) * PLLSAI1N / PLLSAI1P */ 00977 plln = READ_BIT(RCC->PLLSAI1CFGR, RCC_PLLSAI1CFGR_PLLSAI1N) >> POSITION_VAL(RCC_PLLSAI1CFGR_PLLSAI1N); 00978 #if defined(RCC_PLLSAI1P_DIV_2_31_SUPPORT) 00979 pllp = READ_BIT(RCC->PLLSAI1CFGR, RCC_PLLSAI1CFGR_PLLSAI1PDIV) >> POSITION_VAL(RCC_PLLSAI1CFGR_PLLSAI1PDIV); 00980 #endif 00981 if(pllp == 0U) 00982 { 00983 if(READ_BIT(RCC->PLLSAI1CFGR, RCC_PLLSAI1CFGR_PLLSAI1P) != RESET) 00984 { 00985 pllp = 17U; 00986 } 00987 else 00988 { 00989 pllp = 7U; 00990 } 00991 } 00992 frequency = (pllvco * plln) / pllp; 00993 } 00994 } 00995 #else 00996 if(srcclk == RCC_SAI1CLKSOURCE_PLL) 00997 { 00998 if(__HAL_RCC_GET_PLLCLKOUT_CONFIG(RCC_PLL_SAI2CLK) != RESET) 00999 { 01000 /* f(PLLSAI2CLK) = f(VCO input) * PLLN / PLLP */ 01001 plln = READ_BIT(RCC->PLLCFGR, RCC_PLLCFGR_PLLN) >> POSITION_VAL(RCC_PLLCFGR_PLLN); 01002 #if defined(RCC_PLLP_DIV_2_31_SUPPORT) 01003 pllp = READ_BIT(RCC->PLLCFGR, RCC_PLLCFGR_PLLPDIV) >> POSITION_VAL(RCC_PLLCFGR_PLLPDIV); 01004 #endif 01005 if(pllp == 0U) 01006 { 01007 if(READ_BIT(RCC->PLLCFGR, RCC_PLLCFGR_PLLP) != RESET) 01008 { 01009 pllp = 17U; 01010 } 01011 else 01012 { 01013 pllp = 7U; 01014 } 01015 } 01016 01017 frequency = (pllvco * plln) / pllp; 01018 } 01019 else if(HAL_IS_BIT_SET(RCC->CR, RCC_CR_HSIRDY)) 01020 { 01021 /* HSI automatically selected as clock source if PLLs not enabled */ 01022 frequency = HSI_VALUE; 01023 } 01024 else 01025 { 01026 /* No clock source */ 01027 frequency = 0U; 01028 } 01029 } 01030 else if(srcclk == RCC_SAI1CLKSOURCE_PLLSAI1) 01031 { 01032 if(__HAL_RCC_GET_PLLSAI1CLKOUT_CONFIG(RCC_PLLSAI1_SAI1CLK) != RESET) 01033 { 01034 /* f(PLLSAI1CLK) = f(VCOSAI1 input) * PLLSAI1N / PLLSAI1P */ 01035 plln = READ_BIT(RCC->PLLSAI1CFGR, RCC_PLLSAI1CFGR_PLLSAI1N) >> POSITION_VAL(RCC_PLLSAI1CFGR_PLLSAI1N); 01036 #if defined(RCC_PLLSAI1P_DIV_2_31_SUPPORT) 01037 pllp = READ_BIT(RCC->PLLSAI1CFGR, RCC_PLLSAI1CFGR_PLLSAI1PDIV) >> POSITION_VAL(RCC_PLLSAI1CFGR_PLLSAI1PDIV); 01038 #endif 01039 if(pllp == 0U) 01040 { 01041 if(READ_BIT(RCC->PLLSAI1CFGR, RCC_PLLSAI1CFGR_PLLSAI1P) != RESET) 01042 { 01043 pllp = 17U; 01044 } 01045 else 01046 { 01047 pllp = 7U; 01048 } 01049 } 01050 01051 frequency = (pllvco * plln) / pllp; 01052 } 01053 else if(HAL_IS_BIT_SET(RCC->CR, RCC_CR_HSIRDY)) 01054 { 01055 /* HSI automatically selected as clock source if PLLs not enabled */ 01056 frequency = HSI_VALUE; 01057 } 01058 else 01059 { 01060 /* No clock source */ 01061 frequency = 0U; 01062 } 01063 } 01064 #endif /* SAI2 */ 01065 01066 #if defined(RCC_PLLSAI2_SUPPORT) 01067 01068 else if((srcclk == RCC_SAI1CLKSOURCE_PLLSAI2) || (srcclk == RCC_SAI2CLKSOURCE_PLLSAI2)) 01069 { 01070 if(__HAL_RCC_GET_PLLSAI2CLKOUT_CONFIG(RCC_PLLSAI2_SAI2CLK) != RESET) 01071 { 01072 /* f(PLLSAI2CLK) = f(VCOSAI2 input) * PLLSAI2N / PLLSAI2P */ 01073 plln = READ_BIT(RCC->PLLSAI2CFGR, RCC_PLLSAI2CFGR_PLLSAI2N) >> POSITION_VAL(RCC_PLLSAI2CFGR_PLLSAI2N); 01074 #if defined(RCC_PLLSAI2P_DIV_2_31_SUPPORT) 01075 pllp = READ_BIT(RCC->PLLSAI2CFGR, RCC_PLLSAI2CFGR_PLLSAI2PDIV) >> POSITION_VAL(RCC_PLLSAI2CFGR_PLLSAI2PDIV); 01076 #endif 01077 if(pllp == 0U) 01078 { 01079 if(READ_BIT(RCC->PLLSAI2CFGR, RCC_PLLSAI2CFGR_PLLSAI2P) != RESET) 01080 { 01081 pllp = 17U; 01082 } 01083 else 01084 { 01085 pllp = 7U; 01086 } 01087 } 01088 frequency = (pllvco * plln) / pllp; 01089 } 01090 } 01091 01092 #endif /* RCC_PLLSAI2_SUPPORT */ 01093 01094 else 01095 { 01096 /* No clock source */ 01097 frequency = 0U; 01098 } 01099 } 01100 break; 01101 01102 #if defined(USB_OTG_FS) || defined(USB) 01103 01104 case RCC_PERIPHCLK_USB: 01105 01106 #endif /* USB_OTG_FS || USB */ 01107 01108 case RCC_PERIPHCLK_RNG: 01109 01110 #if defined(SDMMC1) 01111 01112 case RCC_PERIPHCLK_SDMMC1: 01113 01114 #endif /* SDMMC1 */ 01115 01116 srcclk = READ_BIT(RCC->CCIPR, RCC_CCIPR_CLK48SEL); 01117 01118 if(srcclk == RCC_CCIPR_CLK48SEL) /* MSI ? */ 01119 { 01120 if(HAL_IS_BIT_SET(RCC->CR, RCC_CR_MSIRDY)) 01121 { 01122 frequency = (1U << ((__HAL_RCC_GET_MSI_RANGE() >> 4U) - 4U)) * 1000000U; 01123 } 01124 else 01125 { 01126 frequency = 0U; 01127 } 01128 } 01129 else if(srcclk == RCC_CCIPR_CLK48SEL_1) /* PLL ? */ 01130 { 01131 if(HAL_IS_BIT_SET(RCC->CR, RCC_CR_PLLRDY) && HAL_IS_BIT_SET(RCC->PLLCFGR, RCC_PLLCFGR_PLLQEN)) 01132 { 01133 /* f(PLL48M1CLK) = f(VCO input) * PLLN / PLLQ */ 01134 plln = READ_BIT(RCC->PLLCFGR, RCC_PLLCFGR_PLLN) >> POSITION_VAL(RCC_PLLCFGR_PLLN); 01135 frequency = (pllvco * plln) / (((READ_BIT(RCC->PLLCFGR, RCC_PLLCFGR_PLLQ) >> POSITION_VAL(RCC_PLLCFGR_PLLQ)) + 1U) << 1U); 01136 } 01137 else 01138 { 01139 frequency = 0U; 01140 } 01141 } 01142 else if(srcclk == RCC_CCIPR_CLK48SEL_0) /* PLLSAI1 ? */ 01143 { 01144 if(HAL_IS_BIT_SET(RCC->CR, RCC_CR_PLLSAI1RDY) && HAL_IS_BIT_SET(RCC->PLLSAI1CFGR, RCC_PLLSAI1CFGR_PLLSAI1QEN)) 01145 { 01146 /* f(PLL48M2CLK) = f(VCOSAI1 input) * PLLSAI1N / PLLSAI1Q */ 01147 plln = READ_BIT(RCC->PLLSAI1CFGR, RCC_PLLSAI1CFGR_PLLSAI1N) >> POSITION_VAL(RCC_PLLSAI1CFGR_PLLSAI1N); 01148 frequency = (pllvco * plln) / (((READ_BIT(RCC->PLLSAI1CFGR, RCC_PLLSAI1CFGR_PLLSAI1Q) >> POSITION_VAL(RCC_PLLSAI1CFGR_PLLSAI1Q)) + 1U) << 1U); 01149 } 01150 else 01151 { 01152 frequency = 0U; 01153 } 01154 } 01155 #if defined(RCC_HSI48_SUPPORT) 01156 else if((srcclk == 0U) && (HAL_IS_BIT_SET(RCC->CRRCR, RCC_CRRCR_HSI48RDY))) /* HSI48 ? */ 01157 { 01158 frequency = HSI48_VALUE; 01159 } 01160 else /* No clock source */ 01161 { 01162 frequency = 0U; 01163 } 01164 #else 01165 else /* No clock source */ 01166 { 01167 frequency = 0U; 01168 } 01169 #endif /* RCC_HSI48_SUPPORT */ 01170 break; 01171 01172 case RCC_PERIPHCLK_USART1: 01173 /* Get the current USART1 source */ 01174 srcclk = __HAL_RCC_GET_USART1_SOURCE(); 01175 01176 if(srcclk == RCC_USART1CLKSOURCE_PCLK2) 01177 { 01178 frequency = HAL_RCC_GetPCLK2Freq(); 01179 } 01180 else if(srcclk == RCC_USART1CLKSOURCE_SYSCLK) 01181 { 01182 frequency = HAL_RCC_GetSysClockFreq(); 01183 } 01184 else if((srcclk == RCC_USART1CLKSOURCE_HSI) && (HAL_IS_BIT_SET(RCC->CR, RCC_CR_HSIRDY))) 01185 { 01186 frequency = HSI_VALUE; 01187 } 01188 else if((srcclk == RCC_USART1CLKSOURCE_LSE) && (HAL_IS_BIT_SET(RCC->BDCR, RCC_BDCR_LSERDY))) 01189 { 01190 frequency = LSE_VALUE; 01191 } 01192 /* Clock not enabled for USART1 */ 01193 else 01194 { 01195 frequency = 0U; 01196 } 01197 break; 01198 01199 case RCC_PERIPHCLK_USART2: 01200 /* Get the current USART2 source */ 01201 srcclk = __HAL_RCC_GET_USART2_SOURCE(); 01202 01203 if(srcclk == RCC_USART2CLKSOURCE_PCLK1) 01204 { 01205 frequency = HAL_RCC_GetPCLK1Freq(); 01206 } 01207 else if(srcclk == RCC_USART2CLKSOURCE_SYSCLK) 01208 { 01209 frequency = HAL_RCC_GetSysClockFreq(); 01210 } 01211 else if((srcclk == RCC_USART2CLKSOURCE_HSI) && (HAL_IS_BIT_SET(RCC->CR, RCC_CR_HSIRDY))) 01212 { 01213 frequency = HSI_VALUE; 01214 } 01215 else if((srcclk == RCC_USART2CLKSOURCE_LSE) && (HAL_IS_BIT_SET(RCC->BDCR, RCC_BDCR_LSERDY))) 01216 { 01217 frequency = LSE_VALUE; 01218 } 01219 /* Clock not enabled for USART2 */ 01220 else 01221 { 01222 frequency = 0U; 01223 } 01224 break; 01225 01226 #if defined(USART3) 01227 01228 case RCC_PERIPHCLK_USART3: 01229 /* Get the current USART3 source */ 01230 srcclk = __HAL_RCC_GET_USART3_SOURCE(); 01231 01232 if(srcclk == RCC_USART3CLKSOURCE_PCLK1) 01233 { 01234 frequency = HAL_RCC_GetPCLK1Freq(); 01235 } 01236 else if(srcclk == RCC_USART3CLKSOURCE_SYSCLK) 01237 { 01238 frequency = HAL_RCC_GetSysClockFreq(); 01239 } 01240 else if((srcclk == RCC_USART3CLKSOURCE_HSI) && (HAL_IS_BIT_SET(RCC->CR, RCC_CR_HSIRDY))) 01241 { 01242 frequency = HSI_VALUE; 01243 } 01244 else if((srcclk == RCC_USART3CLKSOURCE_LSE) && (HAL_IS_BIT_SET(RCC->BDCR, RCC_BDCR_LSERDY))) 01245 { 01246 frequency = LSE_VALUE; 01247 } 01248 /* Clock not enabled for USART3 */ 01249 else 01250 { 01251 frequency = 0U; 01252 } 01253 break; 01254 01255 #endif /* USART3 */ 01256 01257 #if defined(UART4) 01258 01259 case RCC_PERIPHCLK_UART4: 01260 /* Get the current UART4 source */ 01261 srcclk = __HAL_RCC_GET_UART4_SOURCE(); 01262 01263 if(srcclk == RCC_UART4CLKSOURCE_PCLK1) 01264 { 01265 frequency = HAL_RCC_GetPCLK1Freq(); 01266 } 01267 else if(srcclk == RCC_UART4CLKSOURCE_SYSCLK) 01268 { 01269 frequency = HAL_RCC_GetSysClockFreq(); 01270 } 01271 else if((srcclk == RCC_UART4CLKSOURCE_HSI) && (HAL_IS_BIT_SET(RCC->CR, RCC_CR_HSIRDY))) 01272 { 01273 frequency = HSI_VALUE; 01274 } 01275 else if((srcclk == RCC_UART4CLKSOURCE_LSE) && (HAL_IS_BIT_SET(RCC->BDCR, RCC_BDCR_LSERDY))) 01276 { 01277 frequency = LSE_VALUE; 01278 } 01279 /* Clock not enabled for UART4 */ 01280 else 01281 { 01282 frequency = 0U; 01283 } 01284 break; 01285 01286 #endif /* UART4 */ 01287 01288 #if defined(UART5) 01289 01290 case RCC_PERIPHCLK_UART5: 01291 /* Get the current UART5 source */ 01292 srcclk = __HAL_RCC_GET_UART5_SOURCE(); 01293 01294 if(srcclk == RCC_UART5CLKSOURCE_PCLK1) 01295 { 01296 frequency = HAL_RCC_GetPCLK1Freq(); 01297 } 01298 else if(srcclk == RCC_UART5CLKSOURCE_SYSCLK) 01299 { 01300 frequency = HAL_RCC_GetSysClockFreq(); 01301 } 01302 else if((srcclk == RCC_UART5CLKSOURCE_HSI) && (HAL_IS_BIT_SET(RCC->CR, RCC_CR_HSIRDY))) 01303 { 01304 frequency = HSI_VALUE; 01305 } 01306 else if((srcclk == RCC_UART5CLKSOURCE_LSE) && (HAL_IS_BIT_SET(RCC->BDCR, RCC_BDCR_LSERDY))) 01307 { 01308 frequency = LSE_VALUE; 01309 } 01310 /* Clock not enabled for UART5 */ 01311 else 01312 { 01313 frequency = 0U; 01314 } 01315 break; 01316 01317 #endif /* UART5 */ 01318 01319 case RCC_PERIPHCLK_LPUART1: 01320 /* Get the current LPUART1 source */ 01321 srcclk = __HAL_RCC_GET_LPUART1_SOURCE(); 01322 01323 if(srcclk == RCC_LPUART1CLKSOURCE_PCLK1) 01324 { 01325 frequency = HAL_RCC_GetPCLK1Freq(); 01326 } 01327 else if(srcclk == RCC_LPUART1CLKSOURCE_SYSCLK) 01328 { 01329 frequency = HAL_RCC_GetSysClockFreq(); 01330 } 01331 else if((srcclk == RCC_LPUART1CLKSOURCE_HSI) && (HAL_IS_BIT_SET(RCC->CR, RCC_CR_HSIRDY))) 01332 { 01333 frequency = HSI_VALUE; 01334 } 01335 else if((srcclk == RCC_LPUART1CLKSOURCE_LSE) && (HAL_IS_BIT_SET(RCC->BDCR, RCC_BDCR_LSERDY))) 01336 { 01337 frequency = LSE_VALUE; 01338 } 01339 /* Clock not enabled for LPUART1 */ 01340 else 01341 { 01342 frequency = 0U; 01343 } 01344 break; 01345 01346 case RCC_PERIPHCLK_ADC: 01347 01348 srcclk = __HAL_RCC_GET_ADC_SOURCE(); 01349 01350 if(srcclk == RCC_ADCCLKSOURCE_SYSCLK) 01351 { 01352 frequency = HAL_RCC_GetSysClockFreq(); 01353 } 01354 else if(srcclk == RCC_ADCCLKSOURCE_PLLSAI1) 01355 { 01356 if(__HAL_RCC_GET_PLLSAI1CLKOUT_CONFIG(RCC_PLLSAI1_ADC1CLK) != RESET) 01357 { 01358 /* f(PLLADC1CLK) = f(VCOSAI1 input) * PLLSAI1N / PLLSAI1R */ 01359 plln = READ_BIT(RCC->PLLSAI1CFGR, RCC_PLLSAI1CFGR_PLLSAI1N) >> POSITION_VAL(RCC_PLLSAI1CFGR_PLLSAI1N); 01360 frequency = (pllvco * plln) / (((READ_BIT(RCC->PLLSAI1CFGR, RCC_PLLSAI1CFGR_PLLSAI1R) >> POSITION_VAL(RCC_PLLSAI1CFGR_PLLSAI1R)) + 1U) << 1U); 01361 } 01362 } 01363 #if defined(STM32L471xx) || defined(STM32L475xx) || defined(STM32L476xx) || defined(STM32L485xx) || defined(STM32L486xx) 01364 else if(srcclk == RCC_ADCCLKSOURCE_PLLSAI2) 01365 { 01366 if(__HAL_RCC_GET_PLLSAI2CLKOUT_CONFIG(RCC_PLLSAI2_ADC2CLK) != RESET) 01367 { 01368 /* f(PLLADC2CLK) = f(VCOSAI2 input) * PLLSAI2N / PLLSAI2R */ 01369 plln = READ_BIT(RCC->PLLSAI2CFGR, RCC_PLLSAI2CFGR_PLLSAI2N) >> POSITION_VAL(RCC_PLLSAI2CFGR_PLLSAI2N); 01370 frequency = (pllvco * plln) / (((READ_BIT(RCC->PLLSAI2CFGR, RCC_PLLSAI2CFGR_PLLSAI2R) >> POSITION_VAL(RCC_PLLSAI2CFGR_PLLSAI2R)) + 1U) << 1U); 01371 } 01372 } 01373 #endif /* STM32L471xx || STM32L475xx || STM32L476xx || STM32L485xx || STM32L486xx */ 01374 /* Clock not enabled for ADC */ 01375 else 01376 { 01377 frequency = 0U; 01378 } 01379 break; 01380 01381 #if defined(DFSDM1_Filter0) 01382 01383 case RCC_PERIPHCLK_DFSDM1: 01384 /* Get the current DFSDM1 source */ 01385 srcclk = __HAL_RCC_GET_DFSDM1_SOURCE(); 01386 01387 if(srcclk == RCC_DFSDM1CLKSOURCE_PCLK) 01388 { 01389 frequency = HAL_RCC_GetPCLK1Freq(); 01390 } 01391 else 01392 { 01393 frequency = HAL_RCC_GetSysClockFreq(); 01394 } 01395 break; 01396 01397 #endif /* DFSDM1_Filter0 */ 01398 01399 case RCC_PERIPHCLK_I2C1: 01400 /* Get the current I2C1 source */ 01401 srcclk = __HAL_RCC_GET_I2C1_SOURCE(); 01402 01403 if(srcclk == RCC_I2C1CLKSOURCE_PCLK1) 01404 { 01405 frequency = HAL_RCC_GetPCLK1Freq(); 01406 } 01407 else if(srcclk == RCC_I2C1CLKSOURCE_SYSCLK) 01408 { 01409 frequency = HAL_RCC_GetSysClockFreq(); 01410 } 01411 else if((srcclk == RCC_I2C1CLKSOURCE_HSI) && (HAL_IS_BIT_SET(RCC->CR, RCC_CR_HSIRDY))) 01412 { 01413 frequency = HSI_VALUE; 01414 } 01415 /* Clock not enabled for I2C1 */ 01416 else 01417 { 01418 frequency = 0U; 01419 } 01420 break; 01421 01422 #if defined(I2C2) 01423 01424 case RCC_PERIPHCLK_I2C2: 01425 /* Get the current I2C2 source */ 01426 srcclk = __HAL_RCC_GET_I2C2_SOURCE(); 01427 01428 if(srcclk == RCC_I2C2CLKSOURCE_PCLK1) 01429 { 01430 frequency = HAL_RCC_GetPCLK1Freq(); 01431 } 01432 else if(srcclk == RCC_I2C2CLKSOURCE_SYSCLK) 01433 { 01434 frequency = HAL_RCC_GetSysClockFreq(); 01435 } 01436 else if((srcclk == RCC_I2C2CLKSOURCE_HSI) && (HAL_IS_BIT_SET(RCC->CR, RCC_CR_HSIRDY))) 01437 { 01438 frequency = HSI_VALUE; 01439 } 01440 /* Clock not enabled for I2C2 */ 01441 else 01442 { 01443 frequency = 0U; 01444 } 01445 break; 01446 01447 #endif /* I2C2 */ 01448 01449 case RCC_PERIPHCLK_I2C3: 01450 /* Get the current I2C3 source */ 01451 srcclk = __HAL_RCC_GET_I2C3_SOURCE(); 01452 01453 if(srcclk == RCC_I2C3CLKSOURCE_PCLK1) 01454 { 01455 frequency = HAL_RCC_GetPCLK1Freq(); 01456 } 01457 else if(srcclk == RCC_I2C3CLKSOURCE_SYSCLK) 01458 { 01459 frequency = HAL_RCC_GetSysClockFreq(); 01460 } 01461 else if((srcclk == RCC_I2C3CLKSOURCE_HSI) && (HAL_IS_BIT_SET(RCC->CR, RCC_CR_HSIRDY))) 01462 { 01463 frequency = HSI_VALUE; 01464 } 01465 /* Clock not enabled for I2C3 */ 01466 else 01467 { 01468 frequency = 0U; 01469 } 01470 break; 01471 01472 case RCC_PERIPHCLK_LPTIM1: 01473 /* Get the current LPTIM1 source */ 01474 srcclk = __HAL_RCC_GET_LPTIM1_SOURCE(); 01475 01476 if(srcclk == RCC_LPTIM1CLKSOURCE_PCLK) 01477 { 01478 frequency = HAL_RCC_GetPCLK1Freq(); 01479 } 01480 else if((srcclk == RCC_LPTIM1CLKSOURCE_LSI) && (HAL_IS_BIT_SET(RCC->CSR, RCC_CSR_LSIRDY))) 01481 { 01482 frequency = LSI_VALUE; 01483 } 01484 else if((srcclk == RCC_LPTIM1CLKSOURCE_HSI) && (HAL_IS_BIT_SET(RCC->CR, RCC_CR_HSIRDY))) 01485 { 01486 frequency = HSI_VALUE; 01487 } 01488 else if ((srcclk == RCC_LPTIM1CLKSOURCE_LSE) && (HAL_IS_BIT_SET(RCC->BDCR, RCC_BDCR_LSERDY))) 01489 { 01490 frequency = LSE_VALUE; 01491 } 01492 /* Clock not enabled for LPTIM1 */ 01493 else 01494 { 01495 frequency = 0U; 01496 } 01497 break; 01498 01499 case RCC_PERIPHCLK_LPTIM2: 01500 /* Get the current LPTIM2 source */ 01501 srcclk = __HAL_RCC_GET_LPTIM2_SOURCE(); 01502 01503 if(srcclk == RCC_LPTIM2CLKSOURCE_PCLK) 01504 { 01505 frequency = HAL_RCC_GetPCLK1Freq(); 01506 } 01507 else if((srcclk == RCC_LPTIM2CLKSOURCE_LSI) && (HAL_IS_BIT_SET(RCC->CSR, RCC_CSR_LSIRDY))) 01508 { 01509 frequency = LSI_VALUE; 01510 } 01511 else if((srcclk == RCC_LPTIM2CLKSOURCE_HSI) && (HAL_IS_BIT_SET(RCC->CR, RCC_CR_HSIRDY))) 01512 { 01513 frequency = HSI_VALUE; 01514 } 01515 else if ((srcclk == RCC_LPTIM2CLKSOURCE_LSE) && (HAL_IS_BIT_SET(RCC->BDCR, RCC_BDCR_LSERDY))) 01516 { 01517 frequency = LSE_VALUE; 01518 } 01519 /* Clock not enabled for LPTIM2 */ 01520 else 01521 { 01522 frequency = 0U; 01523 } 01524 break; 01525 01526 #if defined(SWPMI1) 01527 01528 case RCC_PERIPHCLK_SWPMI1: 01529 /* Get the current SWPMI1 source */ 01530 srcclk = __HAL_RCC_GET_SWPMI1_SOURCE(); 01531 01532 if(srcclk == RCC_SWPMI1CLKSOURCE_PCLK) 01533 { 01534 frequency = HAL_RCC_GetPCLK1Freq(); 01535 } 01536 else if((srcclk == RCC_SWPMI1CLKSOURCE_HSI) && (HAL_IS_BIT_SET(RCC->CR, RCC_CR_HSIRDY))) 01537 { 01538 frequency = HSI_VALUE; 01539 } 01540 /* Clock not enabled for SWPMI1 */ 01541 else 01542 { 01543 frequency = 0U; 01544 } 01545 break; 01546 01547 #endif /* SWPMI1 */ 01548 01549 default: 01550 break; 01551 } 01552 } 01553 01554 return(frequency); 01555 } 01556 01557 /** 01558 * @} 01559 */ 01560 01561 /** @defgroup RCCEx_Exported_Functions_Group2 Extended Clock management functions 01562 * @brief Extended Clock management functions 01563 * 01564 @verbatim 01565 =============================================================================== 01566 ##### Extended clock management functions ##### 01567 =============================================================================== 01568 [..] 01569 This subsection provides a set of functions allowing to control the 01570 activation or deactivation of MSI PLL-mode, PLLSAI1, PLLSAI2, LSE CSS, 01571 Low speed clock output and clock after wake-up from STOP mode. 01572 @endverbatim 01573 * @{ 01574 */ 01575 01576 /** 01577 * @brief Enable PLLSAI1. 01578 * @param PLLSAI1Init pointer to an RCC_PLLSAI1InitTypeDef structure that 01579 * contains the configuration information for the PLLSAI1 01580 * @retval HAL status 01581 */ 01582 HAL_StatusTypeDef HAL_RCCEx_EnablePLLSAI1(RCC_PLLSAI1InitTypeDef *PLLSAI1Init) 01583 { 01584 uint32_t tickstart = 0U; 01585 HAL_StatusTypeDef status = HAL_OK; 01586 01587 /* check for PLLSAI1 Parameters used to output PLLSAI1CLK */ 01588 assert_param(IS_RCC_PLLSAI1SOURCE(PLLSAI1Init->PLLSAI1Source)); 01589 assert_param(IS_RCC_PLLSAI1M_VALUE(PLLSAI1Init->PLLSAI1M)); 01590 assert_param(IS_RCC_PLLSAI1N_VALUE(PLLSAI1Init->PLLSAI1N)); 01591 assert_param(IS_RCC_PLLSAI1P_VALUE(PLLSAI1Init->PLLSAI1P)); 01592 assert_param(IS_RCC_PLLSAI1Q_VALUE(PLLSAI1Init->PLLSAI1Q)); 01593 assert_param(IS_RCC_PLLSAI1R_VALUE(PLLSAI1Init->PLLSAI1R)); 01594 assert_param(IS_RCC_PLLSAI1CLOCKOUT_VALUE(PLLSAI1Init->PLLSAI1ClockOut)); 01595 01596 /* Disable the PLLSAI1 */ 01597 __HAL_RCC_PLLSAI1_DISABLE(); 01598 01599 /* Get Start Tick*/ 01600 tickstart = HAL_GetTick(); 01601 01602 /* Wait till PLLSAI1 is ready to be updated */ 01603 while(READ_BIT(RCC->CR, RCC_CR_PLLSAI1RDY) != RESET) 01604 { 01605 if((HAL_GetTick() - tickstart) > PLLSAI1_TIMEOUT_VALUE) 01606 { 01607 status = HAL_TIMEOUT; 01608 break; 01609 } 01610 } 01611 01612 if(status == HAL_OK) 01613 { 01614 /* Configure the PLLSAI1 Multiplication factor N */ 01615 /* Configure the PLLSAI1 Division factors P, Q and R */ 01616 __HAL_RCC_PLLSAI1_CONFIG(PLLSAI1Init->PLLSAI1N, PLLSAI1Init->PLLSAI1P, PLLSAI1Init->PLLSAI1Q, PLLSAI1Init->PLLSAI1R); 01617 /* Configure the PLLSAI1 Clock output(s) */ 01618 __HAL_RCC_PLLSAI1CLKOUT_ENABLE(PLLSAI1Init->PLLSAI1ClockOut); 01619 01620 /* Enable the PLLSAI1 again by setting PLLSAI1ON to 1*/ 01621 __HAL_RCC_PLLSAI1_ENABLE(); 01622 01623 /* Get Start Tick*/ 01624 tickstart = HAL_GetTick(); 01625 01626 /* Wait till PLLSAI1 is ready */ 01627 while(READ_BIT(RCC->CR, RCC_CR_PLLSAI1RDY) == RESET) 01628 { 01629 if((HAL_GetTick() - tickstart) > PLLSAI1_TIMEOUT_VALUE) 01630 { 01631 status = HAL_TIMEOUT; 01632 break; 01633 } 01634 } 01635 } 01636 01637 return status; 01638 } 01639 01640 /** 01641 * @brief Disable PLLSAI1. 01642 * @retval HAL status 01643 */ 01644 HAL_StatusTypeDef HAL_RCCEx_DisablePLLSAI1(void) 01645 { 01646 uint32_t tickstart = 0U; 01647 HAL_StatusTypeDef status = HAL_OK; 01648 01649 /* Disable the PLLSAI1 */ 01650 __HAL_RCC_PLLSAI1_DISABLE(); 01651 01652 /* Get Start Tick*/ 01653 tickstart = HAL_GetTick(); 01654 01655 /* Wait till PLLSAI1 is ready */ 01656 while(READ_BIT(RCC->CR, RCC_CR_PLLSAI1RDY) != RESET) 01657 { 01658 if((HAL_GetTick() - tickstart) > PLLSAI1_TIMEOUT_VALUE) 01659 { 01660 status = HAL_TIMEOUT; 01661 break; 01662 } 01663 } 01664 01665 /* Disable the PLLSAI1 Clock outputs */ 01666 __HAL_RCC_PLLSAI1CLKOUT_DISABLE(RCC_PLLSAI1CFGR_PLLSAI1PEN|RCC_PLLSAI1CFGR_PLLSAI1QEN|RCC_PLLSAI1CFGR_PLLSAI1REN); 01667 01668 /* Reset PLL source to save power if no PLLs on */ 01669 if((READ_BIT(RCC->CR, RCC_CR_PLLRDY) == RESET) 01670 #if defined(RCC_PLLSAI2_SUPPORT) 01671 && 01672 (READ_BIT(RCC->CR, RCC_CR_PLLSAI2RDY) == RESET) 01673 #endif /* RCC_PLLSAI2_SUPPORT */ 01674 ) 01675 { 01676 MODIFY_REG(RCC->PLLCFGR, RCC_PLLCFGR_PLLSRC, RCC_PLLSOURCE_NONE); 01677 } 01678 01679 return status; 01680 } 01681 01682 #if defined(RCC_PLLSAI2_SUPPORT) 01683 01684 /** 01685 * @brief Enable PLLSAI2. 01686 * @param PLLSAI2Init pointer to an RCC_PLLSAI2InitTypeDef structure that 01687 * contains the configuration information for the PLLSAI2 01688 * @retval HAL status 01689 */ 01690 HAL_StatusTypeDef HAL_RCCEx_EnablePLLSAI2(RCC_PLLSAI2InitTypeDef *PLLSAI2Init) 01691 { 01692 uint32_t tickstart = 0U; 01693 HAL_StatusTypeDef status = HAL_OK; 01694 01695 /* check for PLLSAI2 Parameters used to output PLLSAI2CLK */ 01696 assert_param(IS_RCC_PLLSAI2SOURCE(PLLSAI2Init->PLLSAI2Source)); 01697 assert_param(IS_RCC_PLLSAI2M_VALUE(PLLSAI2Init->PLLSAI2M)); 01698 assert_param(IS_RCC_PLLSAI2N_VALUE(PLLSAI2Init->PLLSAI2N)); 01699 assert_param(IS_RCC_PLLSAI2P_VALUE(PLLSAI2Init->PLLSAI2P)); 01700 assert_param(IS_RCC_PLLSAI2R_VALUE(PLLSAI2Init->PLLSAI2R)); 01701 assert_param(IS_RCC_PLLSAI2CLOCKOUT_VALUE(PLLSAI2Init->PLLSAI2ClockOut)); 01702 01703 /* Disable the PLLSAI2 */ 01704 __HAL_RCC_PLLSAI2_DISABLE(); 01705 01706 /* Get Start Tick*/ 01707 tickstart = HAL_GetTick(); 01708 01709 /* Wait till PLLSAI2 is ready to be updated */ 01710 while(READ_BIT(RCC->CR, RCC_CR_PLLSAI2RDY) != RESET) 01711 { 01712 if((HAL_GetTick() - tickstart) > PLLSAI2_TIMEOUT_VALUE) 01713 { 01714 status = HAL_TIMEOUT; 01715 break; 01716 } 01717 } 01718 01719 if(status == HAL_OK) 01720 { 01721 /* Configure the PLLSAI2 Multiplication factor N */ 01722 /* Configure the PLLSAI2 Division factors P and R */ 01723 __HAL_RCC_PLLSAI2_CONFIG(PLLSAI2Init->PLLSAI2N, PLLSAI2Init->PLLSAI2P, PLLSAI2Init->PLLSAI2R); 01724 /* Configure the PLLSAI2 Clock output(s) */ 01725 __HAL_RCC_PLLSAI2CLKOUT_ENABLE(PLLSAI2Init->PLLSAI2ClockOut); 01726 01727 /* Enable the PLLSAI2 again by setting PLLSAI2ON to 1*/ 01728 __HAL_RCC_PLLSAI2_ENABLE(); 01729 01730 /* Get Start Tick*/ 01731 tickstart = HAL_GetTick(); 01732 01733 /* Wait till PLLSAI2 is ready */ 01734 while(READ_BIT(RCC->CR, RCC_CR_PLLSAI2RDY) == RESET) 01735 { 01736 if((HAL_GetTick() - tickstart) > PLLSAI2_TIMEOUT_VALUE) 01737 { 01738 status = HAL_TIMEOUT; 01739 break; 01740 } 01741 } 01742 } 01743 01744 return status; 01745 } 01746 01747 /** 01748 * @brief Disable PLLISAI2. 01749 * @retval HAL status 01750 */ 01751 HAL_StatusTypeDef HAL_RCCEx_DisablePLLSAI2(void) 01752 { 01753 uint32_t tickstart = 0U; 01754 HAL_StatusTypeDef status = HAL_OK; 01755 01756 /* Disable the PLLSAI2 */ 01757 __HAL_RCC_PLLSAI2_DISABLE(); 01758 01759 /* Get Start Tick*/ 01760 tickstart = HAL_GetTick(); 01761 01762 /* Wait till PLLSAI2 is ready */ 01763 while(READ_BIT(RCC->CR, RCC_CR_PLLSAI2RDY) != RESET) 01764 { 01765 if((HAL_GetTick() - tickstart) > PLLSAI2_TIMEOUT_VALUE) 01766 { 01767 status = HAL_TIMEOUT; 01768 break; 01769 } 01770 } 01771 01772 /* Disable the PLLSAI2 Clock outputs */ 01773 __HAL_RCC_PLLSAI2CLKOUT_DISABLE(RCC_PLLSAI2CFGR_PLLSAI2PEN|RCC_PLLSAI2CFGR_PLLSAI2REN); 01774 01775 /* Reset PLL source to save power if no PLLs on */ 01776 if((READ_BIT(RCC->CR, RCC_CR_PLLRDY) == RESET) 01777 && 01778 (READ_BIT(RCC->CR, RCC_CR_PLLSAI1RDY) == RESET) 01779 ) 01780 { 01781 MODIFY_REG(RCC->PLLCFGR, RCC_PLLCFGR_PLLSRC, RCC_PLLSOURCE_NONE); 01782 } 01783 01784 return status; 01785 } 01786 01787 #endif /* RCC_PLLSAI2_SUPPORT */ 01788 01789 /** 01790 * @brief Configure the oscillator clock source for wakeup from Stop and CSS backup clock. 01791 * @param WakeUpClk Wakeup clock 01792 * This parameter can be one of the following values: 01793 * @arg @ref RCC_STOP_WAKEUPCLOCK_MSI MSI oscillator selection 01794 * @arg @ref RCC_STOP_WAKEUPCLOCK_HSI HSI oscillator selection 01795 * @note This function shall not be called after the Clock Security System on HSE has been 01796 * enabled. 01797 * @retval None 01798 */ 01799 void HAL_RCCEx_WakeUpStopCLKConfig(uint32_t WakeUpClk) 01800 { 01801 assert_param(IS_RCC_STOP_WAKEUPCLOCK(WakeUpClk)); 01802 01803 __HAL_RCC_WAKEUPSTOP_CLK_CONFIG(WakeUpClk); 01804 } 01805 01806 /** 01807 * @brief Configure the MSI range after standby mode. 01808 * @note After Standby its frequency can be selected between 4 possible values (1, 2, 4 or 8 MHz). 01809 * @param MSIRange MSI range 01810 * This parameter can be one of the following values: 01811 * @arg @ref RCC_MSIRANGE_4 Range 4 around 1 MHz 01812 * @arg @ref RCC_MSIRANGE_5 Range 5 around 2 MHz 01813 * @arg @ref RCC_MSIRANGE_6 Range 6 around 4 MHz (reset value) 01814 * @arg @ref RCC_MSIRANGE_7 Range 7 around 8 MHz 01815 * @retval None 01816 */ 01817 void HAL_RCCEx_StandbyMSIRangeConfig(uint32_t MSIRange) 01818 { 01819 assert_param(IS_RCC_MSI_STANDBY_CLOCK_RANGE(MSIRange)); 01820 01821 __HAL_RCC_MSI_STANDBY_RANGE_CONFIG(MSIRange); 01822 } 01823 01824 /** 01825 * @brief Enable the LSE Clock Security System. 01826 * @note Prior to enable the LSE Clock Security System, LSE oscillator is to be enabled 01827 * with HAL_RCC_OscConfig() and the LSE oscillator clock is to be selected as RTC 01828 * clock with HAL_RCCEx_PeriphCLKConfig(). 01829 * @retval None 01830 */ 01831 void HAL_RCCEx_EnableLSECSS(void) 01832 { 01833 SET_BIT(RCC->BDCR, RCC_BDCR_LSECSSON) ; 01834 } 01835 01836 /** 01837 * @brief Disable the LSE Clock Security System. 01838 * @note LSE Clock Security System can only be disabled after a LSE failure detection. 01839 * @retval None 01840 */ 01841 void HAL_RCCEx_DisableLSECSS(void) 01842 { 01843 CLEAR_BIT(RCC->BDCR, RCC_BDCR_LSECSSON) ; 01844 01845 /* Disable LSE CSS IT if any */ 01846 __HAL_RCC_DISABLE_IT(RCC_IT_LSECSS); 01847 } 01848 01849 /** 01850 * @brief Enable the LSE Clock Security System Interrupt & corresponding EXTI line. 01851 * @note LSE Clock Security System Interrupt is mapped on RTC EXTI line 19 01852 * @retval None 01853 */ 01854 void HAL_RCCEx_EnableLSECSS_IT(void) 01855 { 01856 /* Enable LSE CSS */ 01857 SET_BIT(RCC->BDCR, RCC_BDCR_LSECSSON) ; 01858 01859 /* Enable LSE CSS IT */ 01860 __HAL_RCC_ENABLE_IT(RCC_IT_LSECSS); 01861 01862 /* Enable IT on EXTI Line 19 */ 01863 __HAL_RCC_LSECSS_EXTI_ENABLE_IT(); 01864 __HAL_RCC_LSECSS_EXTI_ENABLE_RISING_EDGE(); 01865 } 01866 01867 /** 01868 * @brief Handle the RCC LSE Clock Security System interrupt request. 01869 * @retval None 01870 */ 01871 void HAL_RCCEx_LSECSS_IRQHandler(void) 01872 { 01873 /* Check RCC LSE CSSF flag */ 01874 if(__HAL_RCC_GET_IT(RCC_IT_LSECSS)) 01875 { 01876 /* RCC LSE Clock Security System interrupt user callback */ 01877 HAL_RCCEx_LSECSS_Callback(); 01878 01879 /* Clear RCC LSE CSS pending bit */ 01880 __HAL_RCC_CLEAR_IT(RCC_IT_LSECSS); 01881 } 01882 } 01883 01884 /** 01885 * @brief RCCEx LSE Clock Security System interrupt callback. 01886 * @retval none 01887 */ 01888 __weak void HAL_RCCEx_LSECSS_Callback(void) 01889 { 01890 /* NOTE : This function should not be modified, when the callback is needed, 01891 the @ref HAL_RCCEx_LSECSS_Callback should be implemented in the user file 01892 */ 01893 } 01894 01895 /** 01896 * @brief Select the Low Speed clock source to output on LSCO pin (PA2). 01897 * @param LSCOSource specifies the Low Speed clock source to output. 01898 * This parameter can be one of the following values: 01899 * @arg @ref RCC_LSCOSOURCE_LSI LSI clock selected as LSCO source 01900 * @arg @ref RCC_LSCOSOURCE_LSE LSE clock selected as LSCO source 01901 * @retval None 01902 */ 01903 void HAL_RCCEx_EnableLSCO(uint32_t LSCOSource) 01904 { 01905 GPIO_InitTypeDef GPIO_InitStruct; 01906 FlagStatus pwrclkchanged = RESET; 01907 FlagStatus backupchanged = RESET; 01908 01909 /* Check the parameters */ 01910 assert_param(IS_RCC_LSCOSOURCE(LSCOSource)); 01911 01912 /* LSCO Pin Clock Enable */ 01913 __LSCO_CLK_ENABLE(); 01914 01915 /* Configue the LSCO pin in analog mode */ 01916 GPIO_InitStruct.Pin = LSCO_PIN; 01917 GPIO_InitStruct.Mode = GPIO_MODE_ANALOG; 01918 GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH; 01919 GPIO_InitStruct.Pull = GPIO_NOPULL; 01920 HAL_GPIO_Init(LSCO_GPIO_PORT, &GPIO_InitStruct); 01921 01922 /* Update LSCOSEL clock source in Backup Domain control register */ 01923 if(__HAL_RCC_PWR_IS_CLK_DISABLED()) 01924 { 01925 __HAL_RCC_PWR_CLK_ENABLE(); 01926 pwrclkchanged = SET; 01927 } 01928 if(HAL_IS_BIT_CLR(PWR->CR1, PWR_CR1_DBP)) 01929 { 01930 HAL_PWR_EnableBkUpAccess(); 01931 backupchanged = SET; 01932 } 01933 01934 MODIFY_REG(RCC->BDCR, RCC_BDCR_LSCOSEL | RCC_BDCR_LSCOEN, LSCOSource | RCC_BDCR_LSCOEN); 01935 01936 if(backupchanged == SET) 01937 { 01938 HAL_PWR_DisableBkUpAccess(); 01939 } 01940 if(pwrclkchanged == SET) 01941 { 01942 __HAL_RCC_PWR_CLK_DISABLE(); 01943 } 01944 } 01945 01946 /** 01947 * @brief Disable the Low Speed clock output. 01948 * @retval None 01949 */ 01950 void HAL_RCCEx_DisableLSCO(void) 01951 { 01952 FlagStatus pwrclkchanged = RESET; 01953 FlagStatus backupchanged = RESET; 01954 01955 /* Update LSCOEN bit in Backup Domain control register */ 01956 if(__HAL_RCC_PWR_IS_CLK_DISABLED()) 01957 { 01958 __HAL_RCC_PWR_CLK_ENABLE(); 01959 pwrclkchanged = SET; 01960 } 01961 if(HAL_IS_BIT_CLR(PWR->CR1, PWR_CR1_DBP)) 01962 { 01963 /* Enable access to the backup domain */ 01964 HAL_PWR_EnableBkUpAccess(); 01965 backupchanged = SET; 01966 } 01967 01968 CLEAR_BIT(RCC->BDCR, RCC_BDCR_LSCOEN); 01969 01970 /* Restore previous configuration */ 01971 if(backupchanged == SET) 01972 { 01973 /* Disable access to the backup domain */ 01974 HAL_PWR_DisableBkUpAccess(); 01975 } 01976 if(pwrclkchanged == SET) 01977 { 01978 __HAL_RCC_PWR_CLK_DISABLE(); 01979 } 01980 } 01981 01982 /** 01983 * @brief Enable the PLL-mode of the MSI. 01984 * @note Prior to enable the PLL-mode of the MSI for automatic hardware 01985 * calibration LSE oscillator is to be enabled with HAL_RCC_OscConfig(). 01986 * @retval None 01987 */ 01988 void HAL_RCCEx_EnableMSIPLLMode(void) 01989 { 01990 SET_BIT(RCC->CR, RCC_CR_MSIPLLEN) ; 01991 } 01992 01993 /** 01994 * @brief Disable the PLL-mode of the MSI. 01995 * @note PLL-mode of the MSI is automatically reset when LSE oscillator is disabled. 01996 * @retval None 01997 */ 01998 void HAL_RCCEx_DisableMSIPLLMode(void) 01999 { 02000 CLEAR_BIT(RCC->CR, RCC_CR_MSIPLLEN) ; 02001 } 02002 02003 /** 02004 * @} 02005 */ 02006 02007 #if defined(CRS) 02008 02009 /** @defgroup RCCEx_Exported_Functions_Group3 Extended Clock Recovery System Control functions 02010 * @brief Extended Clock Recovery System Control functions 02011 * 02012 @verbatim 02013 =============================================================================== 02014 ##### Extended Clock Recovery System Control functions ##### 02015 =============================================================================== 02016 [..] 02017 For devices with Clock Recovery System feature (CRS), RCC Extention HAL driver can be used as follows: 02018 02019 (#) In System clock config, HSI48 needs to be enabled 02020 02021 (#) Enable CRS clock in IP MSP init which will use CRS functions 02022 02023 (#) Call CRS functions as follows: 02024 (##) Prepare synchronization configuration necessary for HSI48 calibration 02025 (+++) Default values can be set for frequency Error Measurement (reload and error limit) 02026 and also HSI48 oscillator smooth trimming. 02027 (+++) Macro __HAL_RCC_CRS_RELOADVALUE_CALCULATE can be also used to calculate 02028 directly reload value with target and sychronization frequencies values 02029 (##) Call function HAL_RCCEx_CRSConfig which 02030 (+++) Resets CRS registers to their default values. 02031 (+++) Configures CRS registers with synchronization configuration 02032 (+++) Enables automatic calibration and frequency error counter feature 02033 Note: When using USB LPM (Link Power Management) and the device is in Sleep mode, the 02034 periodic USB SOF will not be generated by the host. No SYNC signal will therefore be 02035 provided to the CRS to calibrate the HSI48 on the run. To guarantee the required clock 02036 precision after waking up from Sleep mode, the LSE or reference clock on the GPIOs 02037 should be used as SYNC signal. 02038 02039 (##) A polling function is provided to wait for complete synchronization 02040 (+++) Call function HAL_RCCEx_CRSWaitSynchronization() 02041 (+++) According to CRS status, user can decide to adjust again the calibration or continue 02042 application if synchronization is OK 02043 02044 (#) User can retrieve information related to synchronization in calling function 02045 HAL_RCCEx_CRSGetSynchronizationInfo() 02046 02047 (#) Regarding synchronization status and synchronization information, user can try a new calibration 02048 in changing synchronization configuration and call again HAL_RCCEx_CRSConfig. 02049 Note: When the SYNC event is detected during the downcounting phase (before reaching the zero value), 02050 it means that the actual frequency is lower than the target (and so, that the TRIM value should be 02051 incremented), while when it is detected during the upcounting phase it means that the actual frequency 02052 is higher (and that the TRIM value should be decremented). 02053 02054 (#) In interrupt mode, user can resort to the available macros (__HAL_RCC_CRS_XXX_IT). Interrupts will go 02055 through CRS Handler (CRS_IRQn/CRS_IRQHandler) 02056 (++) Call function HAL_RCCEx_CRSConfig() 02057 (++) Enable CRS_IRQn (thanks to NVIC functions) 02058 (++) Enable CRS interrupt (__HAL_RCC_CRS_ENABLE_IT) 02059 (++) Implement CRS status management in the following user callbacks called from 02060 HAL_RCCEx_CRS_IRQHandler(): 02061 (+++) HAL_RCCEx_CRS_SyncOkCallback() 02062 (+++) HAL_RCCEx_CRS_SyncWarnCallback() 02063 (+++) HAL_RCCEx_CRS_ExpectedSyncCallback() 02064 (+++) HAL_RCCEx_CRS_ErrorCallback() 02065 02066 (#) To force a SYNC EVENT, user can use the function HAL_RCCEx_CRSSoftwareSynchronizationGenerate(). 02067 This function can be called before calling HAL_RCCEx_CRSConfig (for instance in Systick handler) 02068 02069 @endverbatim 02070 * @{ 02071 */ 02072 02073 /** 02074 * @brief Start automatic synchronization for polling mode 02075 * @param pInit Pointer on RCC_CRSInitTypeDef structure 02076 * @retval None 02077 */ 02078 void HAL_RCCEx_CRSConfig(RCC_CRSInitTypeDef *pInit) 02079 { 02080 uint32_t value = 0; 02081 02082 /* Check the parameters */ 02083 assert_param(IS_RCC_CRS_SYNC_DIV(pInit->Prescaler)); 02084 assert_param(IS_RCC_CRS_SYNC_SOURCE(pInit->Source)); 02085 assert_param(IS_RCC_CRS_SYNC_POLARITY(pInit->Polarity)); 02086 assert_param(IS_RCC_CRS_RELOADVALUE(pInit->ReloadValue)); 02087 assert_param(IS_RCC_CRS_ERRORLIMIT(pInit->ErrorLimitValue)); 02088 assert_param(IS_RCC_CRS_HSI48CALIBRATION(pInit->HSI48CalibrationValue)); 02089 02090 /* CONFIGURATION */ 02091 02092 /* Before configuration, reset CRS registers to their default values*/ 02093 __HAL_RCC_CRS_FORCE_RESET(); 02094 __HAL_RCC_CRS_RELEASE_RESET(); 02095 02096 /* Set the SYNCDIV[2:0] bits according to Prescaler value */ 02097 /* Set the SYNCSRC[1:0] bits according to Source value */ 02098 /* Set the SYNCSPOL bit according to Polarity value */ 02099 value = (pInit->Prescaler | pInit->Source | pInit->Polarity); 02100 /* Set the RELOAD[15:0] bits according to ReloadValue value */ 02101 value |= pInit->ReloadValue; 02102 /* Set the FELIM[7:0] bits according to ErrorLimitValue value */ 02103 value |= (pInit->ErrorLimitValue << POSITION_VAL(CRS_CFGR_FELIM)); 02104 WRITE_REG(CRS->CFGR, value); 02105 02106 /* Adjust HSI48 oscillator smooth trimming */ 02107 /* Set the TRIM[5:0] bits according to RCC_CRS_HSI48CalibrationValue value */ 02108 MODIFY_REG(CRS->CR, CRS_CR_TRIM, (pInit->HSI48CalibrationValue << POSITION_VAL(CRS_CR_TRIM))); 02109 02110 /* START AUTOMATIC SYNCHRONIZATION*/ 02111 02112 /* Enable Automatic trimming & Frequency error counter */ 02113 SET_BIT(CRS->CR, CRS_CR_AUTOTRIMEN | CRS_CR_CEN); 02114 } 02115 02116 /** 02117 * @brief Generate the software synchronization event 02118 * @retval None 02119 */ 02120 void HAL_RCCEx_CRSSoftwareSynchronizationGenerate(void) 02121 { 02122 SET_BIT(CRS->CR, CRS_CR_SWSYNC); 02123 } 02124 02125 /** 02126 * @brief Return synchronization info 02127 * @param pSynchroInfo Pointer on RCC_CRSSynchroInfoTypeDef structure 02128 * @retval None 02129 */ 02130 void HAL_RCCEx_CRSGetSynchronizationInfo(RCC_CRSSynchroInfoTypeDef *pSynchroInfo) 02131 { 02132 /* Check the parameter */ 02133 assert_param(pSynchroInfo != NULL); 02134 02135 /* Get the reload value */ 02136 pSynchroInfo->ReloadValue = (uint32_t)(READ_BIT(CRS->CFGR, CRS_CFGR_RELOAD)); 02137 02138 /* Get HSI48 oscillator smooth trimming */ 02139 pSynchroInfo->HSI48CalibrationValue = (uint32_t)(READ_BIT(CRS->CR, CRS_CR_TRIM) >> POSITION_VAL(CRS_CR_TRIM)); 02140 02141 /* Get Frequency error capture */ 02142 pSynchroInfo->FreqErrorCapture = (uint32_t)(READ_BIT(CRS->ISR, CRS_ISR_FECAP) >> POSITION_VAL(CRS_ISR_FECAP)); 02143 02144 /* Get Frequency error direction */ 02145 pSynchroInfo->FreqErrorDirection = (uint32_t)(READ_BIT(CRS->ISR, CRS_ISR_FEDIR)); 02146 } 02147 02148 /** 02149 * @brief Wait for CRS Synchronization status. 02150 * @param Timeout Duration of the timeout 02151 * @note Timeout is based on the maximum time to receive a SYNC event based on synchronization 02152 * frequency. 02153 * @note If Timeout set to HAL_MAX_DELAY, HAL_TIMEOUT will be never returned. 02154 * @retval Combination of Synchronization status 02155 * This parameter can be a combination of the following values: 02156 * @arg @ref RCC_CRS_TIMEOUT 02157 * @arg @ref RCC_CRS_SYNCOK 02158 * @arg @ref RCC_CRS_SYNCWARN 02159 * @arg @ref RCC_CRS_SYNCERR 02160 * @arg @ref RCC_CRS_SYNCMISS 02161 * @arg @ref RCC_CRS_TRIMOVF 02162 */ 02163 uint32_t HAL_RCCEx_CRSWaitSynchronization(uint32_t Timeout) 02164 { 02165 uint32_t crsstatus = RCC_CRS_NONE; 02166 uint32_t tickstart = 0U; 02167 02168 /* Get timeout */ 02169 tickstart = HAL_GetTick(); 02170 02171 /* Wait for CRS flag or timeout detection */ 02172 do 02173 { 02174 if(Timeout != HAL_MAX_DELAY) 02175 { 02176 if((Timeout == 0U) || ((HAL_GetTick() - tickstart) > Timeout)) 02177 { 02178 crsstatus = RCC_CRS_TIMEOUT; 02179 } 02180 } 02181 /* Check CRS SYNCOK flag */ 02182 if(__HAL_RCC_CRS_GET_FLAG(RCC_CRS_FLAG_SYNCOK)) 02183 { 02184 /* CRS SYNC event OK */ 02185 crsstatus |= RCC_CRS_SYNCOK; 02186 02187 /* Clear CRS SYNC event OK bit */ 02188 __HAL_RCC_CRS_CLEAR_FLAG(RCC_CRS_FLAG_SYNCOK); 02189 } 02190 02191 /* Check CRS SYNCWARN flag */ 02192 if(__HAL_RCC_CRS_GET_FLAG(RCC_CRS_FLAG_SYNCWARN)) 02193 { 02194 /* CRS SYNC warning */ 02195 crsstatus |= RCC_CRS_SYNCWARN; 02196 02197 /* Clear CRS SYNCWARN bit */ 02198 __HAL_RCC_CRS_CLEAR_FLAG(RCC_CRS_FLAG_SYNCWARN); 02199 } 02200 02201 /* Check CRS TRIM overflow flag */ 02202 if(__HAL_RCC_CRS_GET_FLAG(RCC_CRS_FLAG_TRIMOVF)) 02203 { 02204 /* CRS SYNC Error */ 02205 crsstatus |= RCC_CRS_TRIMOVF; 02206 02207 /* Clear CRS Error bit */ 02208 __HAL_RCC_CRS_CLEAR_FLAG(RCC_CRS_FLAG_TRIMOVF); 02209 } 02210 02211 /* Check CRS Error flag */ 02212 if(__HAL_RCC_CRS_GET_FLAG(RCC_CRS_FLAG_SYNCERR)) 02213 { 02214 /* CRS SYNC Error */ 02215 crsstatus |= RCC_CRS_SYNCERR; 02216 02217 /* Clear CRS Error bit */ 02218 __HAL_RCC_CRS_CLEAR_FLAG(RCC_CRS_FLAG_SYNCERR); 02219 } 02220 02221 /* Check CRS SYNC Missed flag */ 02222 if(__HAL_RCC_CRS_GET_FLAG(RCC_CRS_FLAG_SYNCMISS)) 02223 { 02224 /* CRS SYNC Missed */ 02225 crsstatus |= RCC_CRS_SYNCMISS; 02226 02227 /* Clear CRS SYNC Missed bit */ 02228 __HAL_RCC_CRS_CLEAR_FLAG(RCC_CRS_FLAG_SYNCMISS); 02229 } 02230 02231 /* Check CRS Expected SYNC flag */ 02232 if(__HAL_RCC_CRS_GET_FLAG(RCC_CRS_FLAG_ESYNC)) 02233 { 02234 /* frequency error counter reached a zero value */ 02235 __HAL_RCC_CRS_CLEAR_FLAG(RCC_CRS_FLAG_ESYNC); 02236 } 02237 } while(RCC_CRS_NONE == crsstatus); 02238 02239 return crsstatus; 02240 } 02241 02242 /** 02243 * @brief Handle the Clock Recovery System interrupt request. 02244 * @retval None 02245 */ 02246 void HAL_RCCEx_CRS_IRQHandler(void) 02247 { 02248 uint32_t crserror = RCC_CRS_NONE; 02249 /* Get current IT flags and IT sources values */ 02250 uint32_t itflags = READ_REG(CRS->ISR); 02251 uint32_t itsources = READ_REG(CRS->CR); 02252 02253 /* Check CRS SYNCOK flag */ 02254 if(((itflags & RCC_CRS_FLAG_SYNCOK) != RESET) && ((itsources & RCC_CRS_IT_SYNCOK) != RESET)) 02255 { 02256 /* Clear CRS SYNC event OK flag */ 02257 WRITE_REG(CRS->ICR, CRS_ICR_SYNCOKC); 02258 02259 /* user callback */ 02260 HAL_RCCEx_CRS_SyncOkCallback(); 02261 } 02262 /* Check CRS SYNCWARN flag */ 02263 else if(((itflags & RCC_CRS_FLAG_SYNCWARN) != RESET) && ((itsources & RCC_CRS_IT_SYNCWARN) != RESET)) 02264 { 02265 /* Clear CRS SYNCWARN flag */ 02266 WRITE_REG(CRS->ICR, CRS_ICR_SYNCWARNC); 02267 02268 /* user callback */ 02269 HAL_RCCEx_CRS_SyncWarnCallback(); 02270 } 02271 /* Check CRS Expected SYNC flag */ 02272 else if(((itflags & RCC_CRS_FLAG_ESYNC) != RESET) && ((itsources & RCC_CRS_IT_ESYNC) != RESET)) 02273 { 02274 /* frequency error counter reached a zero value */ 02275 WRITE_REG(CRS->ICR, CRS_ICR_ESYNCC); 02276 02277 /* user callback */ 02278 HAL_RCCEx_CRS_ExpectedSyncCallback(); 02279 } 02280 /* Check CRS Error flags */ 02281 else 02282 { 02283 if(((itflags & RCC_CRS_FLAG_ERR) != RESET) && ((itsources & RCC_CRS_IT_ERR) != RESET)) 02284 { 02285 if((itflags & RCC_CRS_FLAG_SYNCERR) != RESET) 02286 { 02287 crserror |= RCC_CRS_SYNCERR; 02288 } 02289 if((itflags & RCC_CRS_FLAG_SYNCMISS) != RESET) 02290 { 02291 crserror |= RCC_CRS_SYNCMISS; 02292 } 02293 if((itflags & RCC_CRS_FLAG_TRIMOVF) != RESET) 02294 { 02295 crserror |= RCC_CRS_TRIMOVF; 02296 } 02297 02298 /* Clear CRS Error flags */ 02299 WRITE_REG(CRS->ICR, CRS_ICR_ERRC); 02300 02301 /* user error callback */ 02302 HAL_RCCEx_CRS_ErrorCallback(crserror); 02303 } 02304 } 02305 } 02306 02307 /** 02308 * @brief RCCEx Clock Recovery System SYNCOK interrupt callback. 02309 * @retval none 02310 */ 02311 __weak void HAL_RCCEx_CRS_SyncOkCallback(void) 02312 { 02313 /* NOTE : This function should not be modified, when the callback is needed, 02314 the @ref HAL_RCCEx_CRS_SyncOkCallback should be implemented in the user file 02315 */ 02316 } 02317 02318 /** 02319 * @brief RCCEx Clock Recovery System SYNCWARN interrupt callback. 02320 * @retval none 02321 */ 02322 __weak void HAL_RCCEx_CRS_SyncWarnCallback(void) 02323 { 02324 /* NOTE : This function should not be modified, when the callback is needed, 02325 the @ref HAL_RCCEx_CRS_SyncWarnCallback should be implemented in the user file 02326 */ 02327 } 02328 02329 /** 02330 * @brief RCCEx Clock Recovery System Expected SYNC interrupt callback. 02331 * @retval none 02332 */ 02333 __weak void HAL_RCCEx_CRS_ExpectedSyncCallback(void) 02334 { 02335 /* NOTE : This function should not be modified, when the callback is needed, 02336 the @ref HAL_RCCEx_CRS_ExpectedSyncCallback should be implemented in the user file 02337 */ 02338 } 02339 02340 /** 02341 * @brief RCCEx Clock Recovery System Error interrupt callback. 02342 * @param Error Combination of Error status. 02343 * This parameter can be a combination of the following values: 02344 * @arg @ref RCC_CRS_SYNCERR 02345 * @arg @ref RCC_CRS_SYNCMISS 02346 * @arg @ref RCC_CRS_TRIMOVF 02347 * @retval none 02348 */ 02349 __weak void HAL_RCCEx_CRS_ErrorCallback(uint32_t Error) 02350 { 02351 /* Prevent unused argument(s) compilation warning */ 02352 UNUSED(Error); 02353 02354 /* NOTE : This function should not be modified, when the callback is needed, 02355 the @ref HAL_RCCEx_CRS_ErrorCallback should be implemented in the user file 02356 */ 02357 } 02358 02359 /** 02360 * @} 02361 */ 02362 02363 #endif /* CRS */ 02364 02365 /** 02366 * @} 02367 */ 02368 02369 /** @addtogroup RCCEx_Private_Functions 02370 * @{ 02371 */ 02372 02373 /** 02374 * @brief Configure the parameters N & P & optionally M of PLLSAI1 and enable PLLSAI1 output clock(s). 02375 * @param PllSai1 pointer to an RCC_PLLSAI1InitTypeDef structure that 02376 * contains the configuration parameters N & P & optionally M as well as PLLSAI1 output clock(s) 02377 * @param Divider divider parameter to be updated 02378 * 02379 * @note PLLSAI1 is temporary disable to apply new parameters 02380 * 02381 * @retval HAL status 02382 */ 02383 static HAL_StatusTypeDef RCCEx_PLLSAI1_Config(RCC_PLLSAI1InitTypeDef *PllSai1, uint32_t Divider) 02384 { 02385 uint32_t tickstart = 0U; 02386 HAL_StatusTypeDef status = HAL_OK; 02387 02388 /* check for PLLSAI1 Parameters used to output PLLSAI1CLK */ 02389 /* P, Q and R dividers are verified in each specific divider case below */ 02390 assert_param(IS_RCC_PLLSAI1SOURCE(PllSai1->PLLSAI1Source)); 02391 assert_param(IS_RCC_PLLSAI1M_VALUE(PllSai1->PLLSAI1M)); 02392 assert_param(IS_RCC_PLLSAI1N_VALUE(PllSai1->PLLSAI1N)); 02393 assert_param(IS_RCC_PLLSAI1CLOCKOUT_VALUE(PllSai1->PLLSAI1ClockOut)); 02394 02395 /* Check that PLLSAI1 clock source and divider M can be applied */ 02396 if(__HAL_RCC_GET_PLL_OSCSOURCE() != RCC_PLLSOURCE_NONE) 02397 { 02398 /* PLL clock source and divider M already set, check that no request for change */ 02399 if((__HAL_RCC_GET_PLL_OSCSOURCE() != PllSai1->PLLSAI1Source) 02400 || 02401 (PllSai1->PLLSAI1Source == RCC_PLLSOURCE_NONE) 02402 || 02403 (((READ_BIT(RCC->PLLCFGR, RCC_PLLCFGR_PLLM) >> POSITION_VAL(RCC_PLLCFGR_PLLM)) + 1U) != PllSai1->PLLSAI1M) 02404 ) 02405 { 02406 status = HAL_ERROR; 02407 } 02408 } 02409 else 02410 { 02411 /* Check PLLSAI1 clock source availability */ 02412 switch(PllSai1->PLLSAI1Source) 02413 { 02414 case RCC_PLLSOURCE_MSI: 02415 if(HAL_IS_BIT_CLR(RCC->CR, RCC_CR_MSIRDY)) 02416 { 02417 status = HAL_ERROR; 02418 } 02419 break; 02420 case RCC_PLLSOURCE_HSI: 02421 if(HAL_IS_BIT_CLR(RCC->CR, RCC_CR_HSIRDY)) 02422 { 02423 status = HAL_ERROR; 02424 } 02425 break; 02426 case RCC_PLLSOURCE_HSE: 02427 if(HAL_IS_BIT_CLR(RCC->CR, RCC_CR_HSERDY) && HAL_IS_BIT_CLR(RCC->CR, RCC_CR_HSEBYP)) 02428 { 02429 status = HAL_ERROR; 02430 } 02431 break; 02432 default: 02433 status = HAL_ERROR; 02434 break; 02435 } 02436 02437 if(status == HAL_OK) 02438 { 02439 /* Set PLLSAI1 clock source and divider M */ 02440 MODIFY_REG(RCC->PLLCFGR, RCC_PLLCFGR_PLLSRC | RCC_PLLCFGR_PLLM, PllSai1->PLLSAI1Source | (PllSai1->PLLSAI1M - 1U) << POSITION_VAL(RCC_PLLCFGR_PLLM)); 02441 } 02442 } 02443 02444 if(status == HAL_OK) 02445 { 02446 /* Disable the PLLSAI1 */ 02447 __HAL_RCC_PLLSAI1_DISABLE(); 02448 02449 /* Get Start Tick*/ 02450 tickstart = HAL_GetTick(); 02451 02452 /* Wait till PLLSAI1 is ready to be updated */ 02453 while(READ_BIT(RCC->CR, RCC_CR_PLLSAI1RDY) != RESET) 02454 { 02455 if((HAL_GetTick() - tickstart) > PLLSAI1_TIMEOUT_VALUE) 02456 { 02457 status = HAL_TIMEOUT; 02458 break; 02459 } 02460 } 02461 02462 if(status == HAL_OK) 02463 { 02464 if(Divider == DIVIDER_P_UPDATE) 02465 { 02466 assert_param(IS_RCC_PLLSAI1P_VALUE(PllSai1->PLLSAI1P)); 02467 /* Configure the PLLSAI1 Division factor P and Multiplication factor N*/ 02468 #if defined(RCC_PLLSAI1P_DIV_2_31_SUPPORT) 02469 MODIFY_REG(RCC->PLLSAI1CFGR, 02470 RCC_PLLSAI1CFGR_PLLSAI1N | RCC_PLLSAI1CFGR_PLLSAI1PDIV, 02471 (PllSai1->PLLSAI1N << POSITION_VAL(RCC_PLLSAI1CFGR_PLLSAI1N)) | 02472 (PllSai1->PLLSAI1P << POSITION_VAL(RCC_PLLSAI1CFGR_PLLSAI1PDIV))); 02473 #else 02474 MODIFY_REG(RCC->PLLSAI1CFGR, 02475 RCC_PLLSAI1CFGR_PLLSAI1N | RCC_PLLSAI1CFGR_PLLSAI1P, 02476 (PllSai1->PLLSAI1N << POSITION_VAL(RCC_PLLSAI1CFGR_PLLSAI1N)) | 02477 ((PllSai1->PLLSAI1P >> 4U) << POSITION_VAL(RCC_PLLSAI1CFGR_PLLSAI1P))); 02478 #endif /* RCC_PLLSAI1P_DIV_2_31_SUPPORT */ 02479 } 02480 else if(Divider == DIVIDER_Q_UPDATE) 02481 { 02482 assert_param(IS_RCC_PLLSAI1Q_VALUE(PllSai1->PLLSAI1Q)); 02483 /* Configure the PLLSAI1 Division factor Q and Multiplication factor N*/ 02484 MODIFY_REG(RCC->PLLSAI1CFGR, 02485 RCC_PLLSAI1CFGR_PLLSAI1N | RCC_PLLSAI1CFGR_PLLSAI1Q, 02486 (PllSai1->PLLSAI1N << POSITION_VAL(RCC_PLLSAI1CFGR_PLLSAI1N)) | 02487 (((PllSai1->PLLSAI1Q >> 1U) - 1U) << POSITION_VAL(RCC_PLLSAI1CFGR_PLLSAI1Q))); 02488 } 02489 else 02490 { 02491 assert_param(IS_RCC_PLLSAI1R_VALUE(PllSai1->PLLSAI1R)); 02492 /* Configure the PLLSAI1 Division factor R and Multiplication factor N*/ 02493 MODIFY_REG(RCC->PLLSAI1CFGR, 02494 RCC_PLLSAI1CFGR_PLLSAI1N | RCC_PLLSAI1CFGR_PLLSAI1R, 02495 (PllSai1->PLLSAI1N << POSITION_VAL(RCC_PLLSAI1CFGR_PLLSAI1N)) | 02496 (((PllSai1->PLLSAI1R >> 1U) - 1U) << POSITION_VAL(RCC_PLLSAI1CFGR_PLLSAI1R))); 02497 } 02498 02499 /* Enable the PLLSAI1 again by setting PLLSAI1ON to 1*/ 02500 __HAL_RCC_PLLSAI1_ENABLE(); 02501 02502 /* Get Start Tick*/ 02503 tickstart = HAL_GetTick(); 02504 02505 /* Wait till PLLSAI1 is ready */ 02506 while(READ_BIT(RCC->CR, RCC_CR_PLLSAI1RDY) == RESET) 02507 { 02508 if((HAL_GetTick() - tickstart) > PLLSAI1_TIMEOUT_VALUE) 02509 { 02510 status = HAL_TIMEOUT; 02511 break; 02512 } 02513 } 02514 02515 if(status == HAL_OK) 02516 { 02517 /* Configure the PLLSAI1 Clock output(s) */ 02518 __HAL_RCC_PLLSAI1CLKOUT_ENABLE(PllSai1->PLLSAI1ClockOut); 02519 } 02520 } 02521 } 02522 02523 return status; 02524 } 02525 02526 #if defined(RCC_PLLSAI2_SUPPORT) 02527 02528 /** 02529 * @brief Configure the parameters N & P & optionally M of PLLSAI2 and enable PLLSAI2 output clock(s). 02530 * @param PllSai2 pointer to an RCC_PLLSAI2InitTypeDef structure that 02531 * contains the configuration parameters N & P & optionally M as well as PLLSAI2 output clock(s) 02532 * @param Divider divider parameter to be updated 02533 * 02534 * @note PLLSAI2 is temporary disable to apply new parameters 02535 * 02536 * @retval HAL status 02537 */ 02538 static HAL_StatusTypeDef RCCEx_PLLSAI2_Config(RCC_PLLSAI2InitTypeDef *PllSai2, uint32_t Divider) 02539 { 02540 uint32_t tickstart = 0U; 02541 HAL_StatusTypeDef status = HAL_OK; 02542 02543 /* check for PLLSAI2 Parameters used to output PLLSAI2CLK */ 02544 /* P, Q and R dividers are verified in each specific divider case below */ 02545 assert_param(IS_RCC_PLLSAI2SOURCE(PllSai2->PLLSAI2Source)); 02546 assert_param(IS_RCC_PLLSAI2M_VALUE(PllSai2->PLLSAI2M)); 02547 assert_param(IS_RCC_PLLSAI2N_VALUE(PllSai2->PLLSAI2N)); 02548 assert_param(IS_RCC_PLLSAI2CLOCKOUT_VALUE(PllSai2->PLLSAI2ClockOut)); 02549 02550 /* Check that PLLSAI2 clock source and divider M can be applied */ 02551 if(__HAL_RCC_GET_PLL_OSCSOURCE() != RCC_PLLSOURCE_NONE) 02552 { 02553 /* PLL clock source and divider M already set, check that no request for change */ 02554 if((__HAL_RCC_GET_PLL_OSCSOURCE() != PllSai2->PLLSAI2Source) 02555 || 02556 (PllSai2->PLLSAI2Source == RCC_PLLSOURCE_NONE) 02557 || 02558 (((READ_BIT(RCC->PLLCFGR, RCC_PLLCFGR_PLLM) >> POSITION_VAL(RCC_PLLCFGR_PLLM)) + 1U) != PllSai2->PLLSAI2M) 02559 ) 02560 { 02561 status = HAL_ERROR; 02562 } 02563 } 02564 else 02565 { 02566 /* Check PLLSAI2 clock source availability */ 02567 switch(PllSai2->PLLSAI2Source) 02568 { 02569 case RCC_PLLSOURCE_MSI: 02570 if(HAL_IS_BIT_CLR(RCC->CR, RCC_CR_MSIRDY)) 02571 { 02572 status = HAL_ERROR; 02573 } 02574 break; 02575 case RCC_PLLSOURCE_HSI: 02576 if(HAL_IS_BIT_CLR(RCC->CR, RCC_CR_HSIRDY)) 02577 { 02578 status = HAL_ERROR; 02579 } 02580 break; 02581 case RCC_PLLSOURCE_HSE: 02582 if(HAL_IS_BIT_CLR(RCC->CR, RCC_CR_HSERDY) && HAL_IS_BIT_CLR(RCC->CR, RCC_CR_HSEBYP)) 02583 { 02584 status = HAL_ERROR; 02585 } 02586 break; 02587 default: 02588 status = HAL_ERROR; 02589 break; 02590 } 02591 02592 if(status == HAL_OK) 02593 { 02594 /* Set PLLSAI2 clock source and divider M */ 02595 MODIFY_REG(RCC->PLLCFGR, RCC_PLLCFGR_PLLSRC | RCC_PLLCFGR_PLLM, PllSai2->PLLSAI2Source | (PllSai2->PLLSAI2M - 1U) << POSITION_VAL(RCC_PLLCFGR_PLLM)); 02596 } 02597 } 02598 02599 if(status == HAL_OK) 02600 { 02601 /* Disable the PLLSAI2 */ 02602 __HAL_RCC_PLLSAI2_DISABLE(); 02603 02604 /* Get Start Tick*/ 02605 tickstart = HAL_GetTick(); 02606 02607 /* Wait till PLLSAI2 is ready to be updated */ 02608 while(READ_BIT(RCC->CR, RCC_CR_PLLSAI2RDY) != RESET) 02609 { 02610 if((HAL_GetTick() - tickstart) > PLLSAI2_TIMEOUT_VALUE) 02611 { 02612 status = HAL_TIMEOUT; 02613 break; 02614 } 02615 } 02616 02617 if(status == HAL_OK) 02618 { 02619 if(Divider == DIVIDER_P_UPDATE) 02620 { 02621 assert_param(IS_RCC_PLLSAI2P_VALUE(PllSai2->PLLSAI2P)); 02622 /* Configure the PLLSAI2 Division factor P and Multiplication factor N*/ 02623 #if defined(RCC_PLLSAI2P_DIV_2_31_SUPPORT) 02624 MODIFY_REG(RCC->PLLSAI2CFGR, 02625 RCC_PLLSAI2CFGR_PLLSAI2N | RCC_PLLSAI2CFGR_PLLSAI2PDIV, 02626 (PllSai2->PLLSAI2N << POSITION_VAL(RCC_PLLSAI2CFGR_PLLSAI2N)) | 02627 (PllSai2->PLLSAI2P << POSITION_VAL(RCC_PLLSAI2CFGR_PLLSAI2PDIV))); 02628 #else 02629 MODIFY_REG(RCC->PLLSAI2CFGR, 02630 RCC_PLLSAI2CFGR_PLLSAI2N | RCC_PLLSAI2CFGR_PLLSAI2P, 02631 (PllSai2->PLLSAI2N << POSITION_VAL(RCC_PLLSAI2CFGR_PLLSAI2N)) | 02632 ((PllSai2->PLLSAI2P >> 4U) << POSITION_VAL(RCC_PLLSAI2CFGR_PLLSAI2P))); 02633 #endif /* RCC_PLLSAI2P_DIV_2_31_SUPPORT */ 02634 } 02635 else 02636 { 02637 assert_param(IS_RCC_PLLSAI2R_VALUE(PllSai2->PLLSAI2R)); 02638 /* Configure the PLLSAI2 Division factor R and Multiplication factor N*/ 02639 MODIFY_REG(RCC->PLLSAI2CFGR, 02640 RCC_PLLSAI2CFGR_PLLSAI2N | RCC_PLLSAI2CFGR_PLLSAI2R, 02641 (PllSai2->PLLSAI2N << POSITION_VAL(RCC_PLLSAI2CFGR_PLLSAI2N)) | 02642 (((PllSai2->PLLSAI2R >> 1U) - 1U) << POSITION_VAL(RCC_PLLSAI2CFGR_PLLSAI2R))); 02643 } 02644 02645 /* Enable the PLLSAI2 again by setting PLLSAI2ON to 1*/ 02646 __HAL_RCC_PLLSAI2_ENABLE(); 02647 02648 /* Get Start Tick*/ 02649 tickstart = HAL_GetTick(); 02650 02651 /* Wait till PLLSAI2 is ready */ 02652 while(READ_BIT(RCC->CR, RCC_CR_PLLSAI2RDY) == RESET) 02653 { 02654 if((HAL_GetTick() - tickstart) > PLLSAI2_TIMEOUT_VALUE) 02655 { 02656 status = HAL_TIMEOUT; 02657 break; 02658 } 02659 } 02660 02661 if(status == HAL_OK) 02662 { 02663 /* Configure the PLLSAI2 Clock output(s) */ 02664 __HAL_RCC_PLLSAI2CLKOUT_ENABLE(PllSai2->PLLSAI2ClockOut); 02665 } 02666 } 02667 } 02668 02669 return status; 02670 } 02671 02672 #endif /* RCC_PLLSAI2_SUPPORT */ 02673 02674 /** 02675 * @} 02676 */ 02677 02678 /** 02679 * @} 02680 */ 02681 02682 #endif /* HAL_RCC_MODULE_ENABLED */ 02683 /** 02684 * @} 02685 */ 02686 02687 /** 02688 * @} 02689 */ 02690 02691 /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ 02692
Generated on Tue Jul 12 2022 10:59:58 by
