STM32F479xx HAL User Manual
|
00001 /** 00002 ****************************************************************************** 00003 * @file stm32f4xx_hal_rcc_ex.c 00004 * @author MCD Application Team 00005 * @brief Extension RCC HAL module driver. 00006 * This file provides firmware functions to manage the following 00007 * functionalities RCC extension peripheral: 00008 * + Extended Peripheral Control functions 00009 * 00010 ****************************************************************************** 00011 * @attention 00012 * 00013 * <h2><center>© Copyright (c) 2017 STMicroelectronics. 00014 * All rights reserved.</center></h2> 00015 * 00016 * This software component is licensed by ST under BSD 3-Clause license, 00017 * the "License"; You may not use this file except in compliance with the 00018 * License. You may obtain a copy of the License at: 00019 * opensource.org/licenses/BSD-3-Clause 00020 * 00021 ****************************************************************************** 00022 */ 00023 00024 /* Includes ------------------------------------------------------------------*/ 00025 #include "stm32f4xx_hal.h" 00026 00027 /** @addtogroup STM32F4xx_HAL_Driver 00028 * @{ 00029 */ 00030 00031 /** @defgroup RCCEx RCCEx 00032 * @brief RCCEx HAL module driver 00033 * @{ 00034 */ 00035 00036 #ifdef HAL_RCC_MODULE_ENABLED 00037 00038 /* Private typedef -----------------------------------------------------------*/ 00039 /* Private define ------------------------------------------------------------*/ 00040 /** @addtogroup RCCEx_Private_Constants 00041 * @{ 00042 */ 00043 /** 00044 * @} 00045 */ 00046 /* Private macro -------------------------------------------------------------*/ 00047 /* Private variables ---------------------------------------------------------*/ 00048 /* Private function prototypes -----------------------------------------------*/ 00049 /* Private functions ---------------------------------------------------------*/ 00050 /** @defgroup RCCEx_Exported_Functions RCCEx Exported Functions 00051 * @{ 00052 */ 00053 00054 /** @defgroup RCCEx_Exported_Functions_Group1 Extended Peripheral Control functions 00055 * @brief Extended Peripheral Control functions 00056 * 00057 @verbatim 00058 =============================================================================== 00059 ##### Extended Peripheral Control functions ##### 00060 =============================================================================== 00061 [..] 00062 This subsection provides a set of functions allowing to control the RCC Clocks 00063 frequencies. 00064 [..] 00065 (@) Important note: Care must be taken when HAL_RCCEx_PeriphCLKConfig() is used to 00066 select the RTC clock source; in this case the Backup domain will be reset in 00067 order to modify the RTC Clock source, as consequence RTC registers (including 00068 the backup registers) and RCC_BDCR register are set to their reset values. 00069 00070 @endverbatim 00071 * @{ 00072 */ 00073 00074 #if defined(STM32F446xx) 00075 /** 00076 * @brief Initializes the RCC extended peripherals clocks according to the specified 00077 * parameters in the RCC_PeriphCLKInitTypeDef. 00078 * @param PeriphClkInit pointer to an RCC_PeriphCLKInitTypeDef structure that 00079 * contains the configuration information for the Extended Peripherals 00080 * clocks(I2S, SAI, LTDC RTC and TIM). 00081 * 00082 * @note Care must be taken when HAL_RCCEx_PeriphCLKConfig() is used to select 00083 * the RTC clock source; in this case the Backup domain will be reset in 00084 * order to modify the RTC Clock source, as consequence RTC registers (including 00085 * the backup registers) and RCC_BDCR register are set to their reset values. 00086 * 00087 * @retval HAL status 00088 */ 00089 HAL_StatusTypeDef HAL_RCCEx_PeriphCLKConfig(RCC_PeriphCLKInitTypeDef *PeriphClkInit) 00090 { 00091 uint32_t tickstart = 0U; 00092 uint32_t tmpreg1 = 0U; 00093 uint32_t plli2sp = 0U; 00094 uint32_t plli2sq = 0U; 00095 uint32_t plli2sr = 0U; 00096 uint32_t pllsaip = 0U; 00097 uint32_t pllsaiq = 0U; 00098 uint32_t plli2sused = 0U; 00099 uint32_t pllsaiused = 0U; 00100 00101 /* Check the peripheral clock selection parameters */ 00102 assert_param(IS_RCC_PERIPHCLOCK(PeriphClkInit->PeriphClockSelection)); 00103 00104 /*------------------------ I2S APB1 configuration --------------------------*/ 00105 if(((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_I2S_APB1) == (RCC_PERIPHCLK_I2S_APB1)) 00106 { 00107 /* Check the parameters */ 00108 assert_param(IS_RCC_I2SAPB1CLKSOURCE(PeriphClkInit->I2sApb1ClockSelection)); 00109 00110 /* Configure I2S Clock source */ 00111 __HAL_RCC_I2S_APB1_CONFIG(PeriphClkInit->I2sApb1ClockSelection); 00112 /* Enable the PLLI2S when it's used as clock source for I2S */ 00113 if(PeriphClkInit->I2sApb1ClockSelection == RCC_I2SAPB1CLKSOURCE_PLLI2S) 00114 { 00115 plli2sused = 1U; 00116 } 00117 } 00118 /*--------------------------------------------------------------------------*/ 00119 00120 /*---------------------------- I2S APB2 configuration ----------------------*/ 00121 if(((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_I2S_APB2) == (RCC_PERIPHCLK_I2S_APB2)) 00122 { 00123 /* Check the parameters */ 00124 assert_param(IS_RCC_I2SAPB2CLKSOURCE(PeriphClkInit->I2sApb2ClockSelection)); 00125 00126 /* Configure I2S Clock source */ 00127 __HAL_RCC_I2S_APB2_CONFIG(PeriphClkInit->I2sApb2ClockSelection); 00128 /* Enable the PLLI2S when it's used as clock source for I2S */ 00129 if(PeriphClkInit->I2sApb2ClockSelection == RCC_I2SAPB2CLKSOURCE_PLLI2S) 00130 { 00131 plli2sused = 1U; 00132 } 00133 } 00134 /*--------------------------------------------------------------------------*/ 00135 00136 /*--------------------------- SAI1 configuration ---------------------------*/ 00137 if(((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_SAI1) == (RCC_PERIPHCLK_SAI1)) 00138 { 00139 /* Check the parameters */ 00140 assert_param(IS_RCC_SAI1CLKSOURCE(PeriphClkInit->Sai1ClockSelection)); 00141 00142 /* Configure SAI1 Clock source */ 00143 __HAL_RCC_SAI1_CONFIG(PeriphClkInit->Sai1ClockSelection); 00144 /* Enable the PLLI2S when it's used as clock source for SAI */ 00145 if(PeriphClkInit->Sai1ClockSelection == RCC_SAI1CLKSOURCE_PLLI2S) 00146 { 00147 plli2sused = 1U; 00148 } 00149 /* Enable the PLLSAI when it's used as clock source for SAI */ 00150 if(PeriphClkInit->Sai1ClockSelection == RCC_SAI1CLKSOURCE_PLLSAI) 00151 { 00152 pllsaiused = 1U; 00153 } 00154 } 00155 /*--------------------------------------------------------------------------*/ 00156 00157 /*-------------------------- SAI2 configuration ----------------------------*/ 00158 if(((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_SAI2) == (RCC_PERIPHCLK_SAI2)) 00159 { 00160 /* Check the parameters */ 00161 assert_param(IS_RCC_SAI2CLKSOURCE(PeriphClkInit->Sai2ClockSelection)); 00162 00163 /* Configure SAI2 Clock source */ 00164 __HAL_RCC_SAI2_CONFIG(PeriphClkInit->Sai2ClockSelection); 00165 00166 /* Enable the PLLI2S when it's used as clock source for SAI */ 00167 if(PeriphClkInit->Sai2ClockSelection == RCC_SAI2CLKSOURCE_PLLI2S) 00168 { 00169 plli2sused = 1U; 00170 } 00171 /* Enable the PLLSAI when it's used as clock source for SAI */ 00172 if(PeriphClkInit->Sai2ClockSelection == RCC_SAI2CLKSOURCE_PLLSAI) 00173 { 00174 pllsaiused = 1U; 00175 } 00176 } 00177 /*--------------------------------------------------------------------------*/ 00178 00179 /*----------------------------- RTC configuration --------------------------*/ 00180 if(((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_RTC) == (RCC_PERIPHCLK_RTC)) 00181 { 00182 /* Check for RTC Parameters used to output RTCCLK */ 00183 assert_param(IS_RCC_RTCCLKSOURCE(PeriphClkInit->RTCClockSelection)); 00184 00185 /* Enable Power Clock*/ 00186 __HAL_RCC_PWR_CLK_ENABLE(); 00187 00188 /* Enable write access to Backup domain */ 00189 PWR->CR |= PWR_CR_DBP; 00190 00191 /* Get tick */ 00192 tickstart = HAL_GetTick(); 00193 00194 while((PWR->CR & PWR_CR_DBP) == RESET) 00195 { 00196 if((HAL_GetTick() - tickstart ) > RCC_DBP_TIMEOUT_VALUE) 00197 { 00198 return HAL_TIMEOUT; 00199 } 00200 } 00201 /* Reset the Backup domain only if the RTC Clock source selection is modified from reset value */ 00202 tmpreg1 = (RCC->BDCR & RCC_BDCR_RTCSEL); 00203 if((tmpreg1 != 0x00000000U) && ((tmpreg1) != (PeriphClkInit->RTCClockSelection & RCC_BDCR_RTCSEL))) 00204 { 00205 /* Store the content of BDCR register before the reset of Backup Domain */ 00206 tmpreg1 = (RCC->BDCR & ~(RCC_BDCR_RTCSEL)); 00207 /* RTC Clock selection can be changed only if the Backup Domain is reset */ 00208 __HAL_RCC_BACKUPRESET_FORCE(); 00209 __HAL_RCC_BACKUPRESET_RELEASE(); 00210 /* Restore the Content of BDCR register */ 00211 RCC->BDCR = tmpreg1; 00212 00213 /* Wait for LSE reactivation if LSE was enable prior to Backup Domain reset */ 00214 if(HAL_IS_BIT_SET(RCC->BDCR, RCC_BDCR_LSEON)) 00215 { 00216 /* Get tick */ 00217 tickstart = HAL_GetTick(); 00218 00219 /* Wait till LSE is ready */ 00220 while(__HAL_RCC_GET_FLAG(RCC_FLAG_LSERDY) == RESET) 00221 { 00222 if((HAL_GetTick() - tickstart ) > RCC_LSE_TIMEOUT_VALUE) 00223 { 00224 return HAL_TIMEOUT; 00225 } 00226 } 00227 } 00228 } 00229 __HAL_RCC_RTC_CONFIG(PeriphClkInit->RTCClockSelection); 00230 } 00231 /*--------------------------------------------------------------------------*/ 00232 00233 /*---------------------------- TIM configuration ---------------------------*/ 00234 if(((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_TIM) == (RCC_PERIPHCLK_TIM)) 00235 { 00236 /* Configure Timer Prescaler */ 00237 __HAL_RCC_TIMCLKPRESCALER(PeriphClkInit->TIMPresSelection); 00238 } 00239 /*--------------------------------------------------------------------------*/ 00240 00241 /*---------------------------- FMPI2C1 Configuration -----------------------*/ 00242 if(((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_FMPI2C1) == RCC_PERIPHCLK_FMPI2C1) 00243 { 00244 /* Check the parameters */ 00245 assert_param(IS_RCC_FMPI2C1CLKSOURCE(PeriphClkInit->Fmpi2c1ClockSelection)); 00246 00247 /* Configure the FMPI2C1 clock source */ 00248 __HAL_RCC_FMPI2C1_CONFIG(PeriphClkInit->Fmpi2c1ClockSelection); 00249 } 00250 /*--------------------------------------------------------------------------*/ 00251 00252 /*------------------------------ CEC Configuration -------------------------*/ 00253 if(((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_CEC) == RCC_PERIPHCLK_CEC) 00254 { 00255 /* Check the parameters */ 00256 assert_param(IS_RCC_CECCLKSOURCE(PeriphClkInit->CecClockSelection)); 00257 00258 /* Configure the CEC clock source */ 00259 __HAL_RCC_CEC_CONFIG(PeriphClkInit->CecClockSelection); 00260 } 00261 /*--------------------------------------------------------------------------*/ 00262 00263 /*----------------------------- CLK48 Configuration ------------------------*/ 00264 if(((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_CLK48) == RCC_PERIPHCLK_CLK48) 00265 { 00266 /* Check the parameters */ 00267 assert_param(IS_RCC_CLK48CLKSOURCE(PeriphClkInit->Clk48ClockSelection)); 00268 00269 /* Configure the CLK48 clock source */ 00270 __HAL_RCC_CLK48_CONFIG(PeriphClkInit->Clk48ClockSelection); 00271 00272 /* Enable the PLLSAI when it's used as clock source for CLK48 */ 00273 if(PeriphClkInit->Clk48ClockSelection == RCC_CLK48CLKSOURCE_PLLSAIP) 00274 { 00275 pllsaiused = 1U; 00276 } 00277 } 00278 /*--------------------------------------------------------------------------*/ 00279 00280 /*----------------------------- SDIO Configuration -------------------------*/ 00281 if(((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_SDIO) == RCC_PERIPHCLK_SDIO) 00282 { 00283 /* Check the parameters */ 00284 assert_param(IS_RCC_SDIOCLKSOURCE(PeriphClkInit->SdioClockSelection)); 00285 00286 /* Configure the SDIO clock source */ 00287 __HAL_RCC_SDIO_CONFIG(PeriphClkInit->SdioClockSelection); 00288 } 00289 /*--------------------------------------------------------------------------*/ 00290 00291 /*------------------------------ SPDIFRX Configuration ---------------------*/ 00292 if(((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_SPDIFRX) == RCC_PERIPHCLK_SPDIFRX) 00293 { 00294 /* Check the parameters */ 00295 assert_param(IS_RCC_SPDIFRXCLKSOURCE(PeriphClkInit->SpdifClockSelection)); 00296 00297 /* Configure the SPDIFRX clock source */ 00298 __HAL_RCC_SPDIFRX_CONFIG(PeriphClkInit->SpdifClockSelection); 00299 /* Enable the PLLI2S when it's used as clock source for SPDIFRX */ 00300 if(PeriphClkInit->SpdifClockSelection == RCC_SPDIFRXCLKSOURCE_PLLI2SP) 00301 { 00302 plli2sused = 1U; 00303 } 00304 } 00305 /*--------------------------------------------------------------------------*/ 00306 00307 /*---------------------------- PLLI2S Configuration ------------------------*/ 00308 /* PLLI2S is configured when a peripheral will use it as source clock : SAI1, SAI2, I2S on APB1, 00309 I2S on APB2 or SPDIFRX */ 00310 if((plli2sused == 1U) || (PeriphClkInit->PeriphClockSelection == RCC_PERIPHCLK_PLLI2S)) 00311 { 00312 /* Disable the PLLI2S */ 00313 __HAL_RCC_PLLI2S_DISABLE(); 00314 /* Get tick */ 00315 tickstart = HAL_GetTick(); 00316 /* Wait till PLLI2S is disabled */ 00317 while(__HAL_RCC_GET_FLAG(RCC_FLAG_PLLI2SRDY) != RESET) 00318 { 00319 if((HAL_GetTick() - tickstart ) > PLLI2S_TIMEOUT_VALUE) 00320 { 00321 /* return in case of Timeout detected */ 00322 return HAL_TIMEOUT; 00323 } 00324 } 00325 00326 /* check for common PLLI2S Parameters */ 00327 assert_param(IS_RCC_PLLI2SM_VALUE(PeriphClkInit->PLLI2S.PLLI2SM)); 00328 assert_param(IS_RCC_PLLI2SN_VALUE(PeriphClkInit->PLLI2S.PLLI2SN)); 00329 00330 /*------ In Case of PLLI2S is selected as source clock for I2S -----------*/ 00331 if(((((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_I2S_APB1) == RCC_PERIPHCLK_I2S_APB1) && (PeriphClkInit->I2sApb1ClockSelection == RCC_I2SAPB1CLKSOURCE_PLLI2S)) || 00332 ((((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_I2S_APB2) == RCC_PERIPHCLK_I2S_APB2) && (PeriphClkInit->I2sApb2ClockSelection == RCC_I2SAPB2CLKSOURCE_PLLI2S))) 00333 { 00334 /* check for Parameters */ 00335 assert_param(IS_RCC_PLLI2SR_VALUE(PeriphClkInit->PLLI2S.PLLI2SR)); 00336 00337 /* Read PLLI2SP/PLLI2SQ value from PLLI2SCFGR register (this value is not needed for I2S configuration) */ 00338 plli2sp = ((((RCC->PLLI2SCFGR & RCC_PLLI2SCFGR_PLLI2SP) >> RCC_PLLI2SCFGR_PLLI2SP_Pos) + 1U) << 1U); 00339 plli2sq = ((RCC->PLLI2SCFGR & RCC_PLLI2SCFGR_PLLI2SQ) >> RCC_PLLI2SCFGR_PLLI2SQ_Pos); 00340 /* Configure the PLLI2S division factors */ 00341 /* PLLI2S_VCO = f(VCO clock) = f(PLLI2S clock input) * (PLLI2SN/PLLI2SM) */ 00342 /* I2SCLK = f(PLLI2S clock output) = f(VCO clock) / PLLI2SR */ 00343 __HAL_RCC_PLLI2S_CONFIG(PeriphClkInit->PLLI2S.PLLI2SM, PeriphClkInit->PLLI2S.PLLI2SN , plli2sp, plli2sq, PeriphClkInit->PLLI2S.PLLI2SR); 00344 } 00345 00346 /*------- In Case of PLLI2S is selected as source clock for SAI ----------*/ 00347 if(((((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_SAI1) == RCC_PERIPHCLK_SAI1) && (PeriphClkInit->Sai1ClockSelection == RCC_SAI1CLKSOURCE_PLLI2S)) || 00348 ((((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_SAI2) == RCC_PERIPHCLK_SAI2) && (PeriphClkInit->Sai2ClockSelection == RCC_SAI2CLKSOURCE_PLLI2S))) 00349 { 00350 /* Check for PLLI2S Parameters */ 00351 assert_param(IS_RCC_PLLI2SQ_VALUE(PeriphClkInit->PLLI2S.PLLI2SQ)); 00352 /* Check for PLLI2S/DIVQ parameters */ 00353 assert_param(IS_RCC_PLLI2S_DIVQ_VALUE(PeriphClkInit->PLLI2SDivQ)); 00354 00355 /* Read PLLI2SP/PLLI2SR value from PLLI2SCFGR register (this value is not needed for SAI configuration) */ 00356 plli2sp = ((((RCC->PLLI2SCFGR & RCC_PLLI2SCFGR_PLLI2SP) >> RCC_PLLI2SCFGR_PLLI2SP_Pos) + 1U) << 1U); 00357 plli2sr = ((RCC->PLLI2SCFGR & RCC_PLLI2SCFGR_PLLI2SR) >> RCC_PLLI2SCFGR_PLLI2SR_Pos); 00358 /* Configure the PLLI2S division factors */ 00359 /* PLLI2S_VCO Input = PLL_SOURCE/PLLI2SM */ 00360 /* PLLI2S_VCO Output = PLLI2S_VCO Input * PLLI2SN */ 00361 /* SAI_CLK(first level) = PLLI2S_VCO Output/PLLI2SQ */ 00362 __HAL_RCC_PLLI2S_CONFIG(PeriphClkInit->PLLI2S.PLLI2SM, PeriphClkInit->PLLI2S.PLLI2SN , plli2sp, PeriphClkInit->PLLI2S.PLLI2SQ, plli2sr); 00363 00364 /* SAI_CLK_x = SAI_CLK(first level)/PLLI2SDIVQ */ 00365 __HAL_RCC_PLLI2S_PLLSAICLKDIVQ_CONFIG(PeriphClkInit->PLLI2SDivQ); 00366 } 00367 00368 /*------ In Case of PLLI2S is selected as source clock for SPDIFRX -------*/ 00369 if((((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_SPDIFRX) == RCC_PERIPHCLK_SPDIFRX) && (PeriphClkInit->SpdifClockSelection == RCC_SPDIFRXCLKSOURCE_PLLI2SP)) 00370 { 00371 /* check for Parameters */ 00372 assert_param(IS_RCC_PLLI2SP_VALUE(PeriphClkInit->PLLI2S.PLLI2SP)); 00373 /* Read PLLI2SR value from PLLI2SCFGR register (this value is not need for SAI configuration) */ 00374 plli2sq = ((((RCC->PLLI2SCFGR & RCC_PLLI2SCFGR_PLLI2SP) >> RCC_PLLI2SCFGR_PLLI2SP_Pos) + 1U) << 1U); 00375 plli2sr = ((RCC->PLLI2SCFGR & RCC_PLLI2SCFGR_PLLI2SR) >> RCC_PLLI2SCFGR_PLLI2SR_Pos); 00376 /* Configure the PLLI2S division factors */ 00377 /* PLLI2S_VCO = f(VCO clock) = f(PLLI2S clock input) * (PLLI2SN/PLLI2SM) */ 00378 /* SPDIFRXCLK = f(PLLI2S clock output) = f(VCO clock) / PLLI2SP */ 00379 __HAL_RCC_PLLI2S_CONFIG(PeriphClkInit->PLLI2S.PLLI2SM, PeriphClkInit->PLLI2S.PLLI2SN , PeriphClkInit->PLLI2S.PLLI2SP, plli2sq, plli2sr); 00380 } 00381 00382 /*----------------- In Case of PLLI2S is just selected -----------------*/ 00383 if((PeriphClkInit->PeriphClockSelection & RCC_PERIPHCLK_PLLI2S) == RCC_PERIPHCLK_PLLI2S) 00384 { 00385 /* Check for Parameters */ 00386 assert_param(IS_RCC_PLLI2SP_VALUE(PeriphClkInit->PLLI2S.PLLI2SP)); 00387 assert_param(IS_RCC_PLLI2SR_VALUE(PeriphClkInit->PLLI2S.PLLI2SR)); 00388 assert_param(IS_RCC_PLLI2SQ_VALUE(PeriphClkInit->PLLI2S.PLLI2SQ)); 00389 00390 /* Configure the PLLI2S division factors */ 00391 /* PLLI2S_VCO = f(VCO clock) = f(PLLI2S clock input) * (PLLI2SN/PLLI2SM) */ 00392 __HAL_RCC_PLLI2S_CONFIG(PeriphClkInit->PLLI2S.PLLI2SM, PeriphClkInit->PLLI2S.PLLI2SN , PeriphClkInit->PLLI2S.PLLI2SP, PeriphClkInit->PLLI2S.PLLI2SQ, PeriphClkInit->PLLI2S.PLLI2SR); 00393 } 00394 00395 /* Enable the PLLI2S */ 00396 __HAL_RCC_PLLI2S_ENABLE(); 00397 /* Get tick */ 00398 tickstart = HAL_GetTick(); 00399 /* Wait till PLLI2S is ready */ 00400 while(__HAL_RCC_GET_FLAG(RCC_FLAG_PLLI2SRDY) == RESET) 00401 { 00402 if((HAL_GetTick() - tickstart ) > PLLI2S_TIMEOUT_VALUE) 00403 { 00404 /* return in case of Timeout detected */ 00405 return HAL_TIMEOUT; 00406 } 00407 } 00408 } 00409 /*--------------------------------------------------------------------------*/ 00410 00411 /*----------------------------- PLLSAI Configuration -----------------------*/ 00412 /* PLLSAI is configured when a peripheral will use it as source clock : SAI1, SAI2, CLK48 or SDIO */ 00413 if(pllsaiused == 1U) 00414 { 00415 /* Disable PLLSAI Clock */ 00416 __HAL_RCC_PLLSAI_DISABLE(); 00417 /* Get tick */ 00418 tickstart = HAL_GetTick(); 00419 /* Wait till PLLSAI is disabled */ 00420 while(__HAL_RCC_PLLSAI_GET_FLAG() != RESET) 00421 { 00422 if((HAL_GetTick() - tickstart ) > PLLSAI_TIMEOUT_VALUE) 00423 { 00424 /* return in case of Timeout detected */ 00425 return HAL_TIMEOUT; 00426 } 00427 } 00428 00429 /* Check the PLLSAI division factors */ 00430 assert_param(IS_RCC_PLLSAIM_VALUE(PeriphClkInit->PLLSAI.PLLSAIM)); 00431 assert_param(IS_RCC_PLLSAIN_VALUE(PeriphClkInit->PLLSAI.PLLSAIN)); 00432 00433 /*------ In Case of PLLSAI is selected as source clock for SAI -----------*/ 00434 if(((((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_SAI1) == RCC_PERIPHCLK_SAI1) && (PeriphClkInit->Sai1ClockSelection == RCC_SAI1CLKSOURCE_PLLSAI)) || 00435 ((((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_SAI2) == RCC_PERIPHCLK_SAI2) && (PeriphClkInit->Sai2ClockSelection == RCC_SAI2CLKSOURCE_PLLSAI))) 00436 { 00437 /* check for PLLSAIQ Parameter */ 00438 assert_param(IS_RCC_PLLSAIQ_VALUE(PeriphClkInit->PLLSAI.PLLSAIQ)); 00439 /* check for PLLSAI/DIVQ Parameter */ 00440 assert_param(IS_RCC_PLLSAI_DIVQ_VALUE(PeriphClkInit->PLLSAIDivQ)); 00441 00442 /* Read PLLSAIP value from PLLSAICFGR register (this value is not needed for SAI configuration) */ 00443 pllsaip = ((((RCC->PLLSAICFGR & RCC_PLLSAICFGR_PLLSAIP) >> RCC_PLLSAICFGR_PLLSAIP_Pos) + 1U) << 1U); 00444 /* PLLSAI_VCO Input = PLL_SOURCE/PLLM */ 00445 /* PLLSAI_VCO Output = PLLSAI_VCO Input * PLLSAIN */ 00446 /* SAI_CLK(first level) = PLLSAI_VCO Output/PLLSAIQ */ 00447 __HAL_RCC_PLLSAI_CONFIG(PeriphClkInit->PLLSAI.PLLSAIM, PeriphClkInit->PLLSAI.PLLSAIN , pllsaip, PeriphClkInit->PLLSAI.PLLSAIQ, 0U); 00448 00449 /* SAI_CLK_x = SAI_CLK(first level)/PLLSAIDIVQ */ 00450 __HAL_RCC_PLLSAI_PLLSAICLKDIVQ_CONFIG(PeriphClkInit->PLLSAIDivQ); 00451 } 00452 00453 /*------ In Case of PLLSAI is selected as source clock for CLK48 ---------*/ 00454 /* In Case of PLLI2S is selected as source clock for CLK48 */ 00455 if((((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_CLK48) == RCC_PERIPHCLK_CLK48) && (PeriphClkInit->Clk48ClockSelection == RCC_CLK48CLKSOURCE_PLLSAIP)) 00456 { 00457 /* check for Parameters */ 00458 assert_param(IS_RCC_PLLSAIP_VALUE(PeriphClkInit->PLLSAI.PLLSAIP)); 00459 /* Read PLLSAIQ value from PLLI2SCFGR register (this value is not need for SAI configuration) */ 00460 pllsaiq = ((RCC->PLLSAICFGR & RCC_PLLSAICFGR_PLLSAIQ) >> RCC_PLLSAICFGR_PLLSAIQ_Pos); 00461 /* Configure the PLLSAI division factors */ 00462 /* PLLSAI_VCO = f(VCO clock) = f(PLLSAI clock input) * (PLLI2SN/PLLSAIM) */ 00463 /* 48CLK = f(PLLSAI clock output) = f(VCO clock) / PLLSAIP */ 00464 __HAL_RCC_PLLSAI_CONFIG(PeriphClkInit->PLLSAI.PLLSAIM, PeriphClkInit->PLLSAI.PLLSAIN , PeriphClkInit->PLLSAI.PLLSAIP, pllsaiq, 0U); 00465 } 00466 00467 /* Enable PLLSAI Clock */ 00468 __HAL_RCC_PLLSAI_ENABLE(); 00469 /* Get tick */ 00470 tickstart = HAL_GetTick(); 00471 /* Wait till PLLSAI is ready */ 00472 while(__HAL_RCC_PLLSAI_GET_FLAG() == RESET) 00473 { 00474 if((HAL_GetTick() - tickstart ) > PLLSAI_TIMEOUT_VALUE) 00475 { 00476 /* return in case of Timeout detected */ 00477 return HAL_TIMEOUT; 00478 } 00479 } 00480 } 00481 return HAL_OK; 00482 } 00483 00484 /** 00485 * @brief Get the RCC_PeriphCLKInitTypeDef according to the internal 00486 * RCC configuration registers. 00487 * @param PeriphClkInit pointer to an RCC_PeriphCLKInitTypeDef structure that 00488 * will be configured. 00489 * @retval None 00490 */ 00491 void HAL_RCCEx_GetPeriphCLKConfig(RCC_PeriphCLKInitTypeDef *PeriphClkInit) 00492 { 00493 uint32_t tempreg; 00494 00495 /* Set all possible values for the extended clock type parameter------------*/ 00496 PeriphClkInit->PeriphClockSelection = RCC_PERIPHCLK_I2S_APB1 | RCC_PERIPHCLK_I2S_APB2 |\ 00497 RCC_PERIPHCLK_SAI1 | RCC_PERIPHCLK_SAI2 |\ 00498 RCC_PERIPHCLK_TIM | RCC_PERIPHCLK_RTC |\ 00499 RCC_PERIPHCLK_CEC | RCC_PERIPHCLK_FMPI2C1 |\ 00500 RCC_PERIPHCLK_CLK48 | RCC_PERIPHCLK_SDIO |\ 00501 RCC_PERIPHCLK_SPDIFRX; 00502 00503 /* Get the PLLI2S Clock configuration --------------------------------------*/ 00504 PeriphClkInit->PLLI2S.PLLI2SM = (uint32_t)((RCC->PLLI2SCFGR & RCC_PLLI2SCFGR_PLLI2SM) >> RCC_PLLI2SCFGR_PLLI2SM_Pos); 00505 PeriphClkInit->PLLI2S.PLLI2SN = (uint32_t)((RCC->PLLI2SCFGR & RCC_PLLI2SCFGR_PLLI2SN) >> RCC_PLLI2SCFGR_PLLI2SN_Pos); 00506 PeriphClkInit->PLLI2S.PLLI2SP = (uint32_t)((((RCC->PLLI2SCFGR & RCC_PLLI2SCFGR_PLLI2SP) >> RCC_PLLI2SCFGR_PLLI2SP_Pos) + 1U) << 1U); 00507 PeriphClkInit->PLLI2S.PLLI2SQ = (uint32_t)((RCC->PLLI2SCFGR & RCC_PLLI2SCFGR_PLLI2SQ) >> RCC_PLLI2SCFGR_PLLI2SQ_Pos); 00508 PeriphClkInit->PLLI2S.PLLI2SR = (uint32_t)((RCC->PLLI2SCFGR & RCC_PLLI2SCFGR_PLLI2SR) >> RCC_PLLI2SCFGR_PLLI2SR_Pos); 00509 /* Get the PLLSAI Clock configuration --------------------------------------*/ 00510 PeriphClkInit->PLLSAI.PLLSAIM = (uint32_t)((RCC->PLLSAICFGR & RCC_PLLSAICFGR_PLLSAIM) >> RCC_PLLSAICFGR_PLLSAIM_Pos); 00511 PeriphClkInit->PLLSAI.PLLSAIN = (uint32_t)((RCC->PLLSAICFGR & RCC_PLLSAICFGR_PLLSAIN) >> RCC_PLLSAICFGR_PLLSAIN_Pos); 00512 PeriphClkInit->PLLSAI.PLLSAIP = (uint32_t)((((RCC->PLLSAICFGR & RCC_PLLSAICFGR_PLLSAIP) >> RCC_PLLSAICFGR_PLLSAIP_Pos) + 1U) << 1U); 00513 PeriphClkInit->PLLSAI.PLLSAIQ = (uint32_t)((RCC->PLLSAICFGR & RCC_PLLSAICFGR_PLLSAIQ) >> RCC_PLLSAICFGR_PLLSAIQ_Pos); 00514 /* Get the PLLSAI/PLLI2S division factors ----------------------------------*/ 00515 PeriphClkInit->PLLI2SDivQ = (uint32_t)((RCC->DCKCFGR & RCC_DCKCFGR_PLLI2SDIVQ) >> RCC_DCKCFGR_PLLI2SDIVQ_Pos); 00516 PeriphClkInit->PLLSAIDivQ = (uint32_t)((RCC->DCKCFGR & RCC_DCKCFGR_PLLSAIDIVQ) >> RCC_DCKCFGR_PLLSAIDIVQ_Pos); 00517 00518 /* Get the SAI1 clock configuration ----------------------------------------*/ 00519 PeriphClkInit->Sai1ClockSelection = __HAL_RCC_GET_SAI1_SOURCE(); 00520 00521 /* Get the SAI2 clock configuration ----------------------------------------*/ 00522 PeriphClkInit->Sai2ClockSelection = __HAL_RCC_GET_SAI2_SOURCE(); 00523 00524 /* Get the I2S APB1 clock configuration ------------------------------------*/ 00525 PeriphClkInit->I2sApb1ClockSelection = __HAL_RCC_GET_I2S_APB1_SOURCE(); 00526 00527 /* Get the I2S APB2 clock configuration ------------------------------------*/ 00528 PeriphClkInit->I2sApb2ClockSelection = __HAL_RCC_GET_I2S_APB2_SOURCE(); 00529 00530 /* Get the RTC Clock configuration -----------------------------------------*/ 00531 tempreg = (RCC->CFGR & RCC_CFGR_RTCPRE); 00532 PeriphClkInit->RTCClockSelection = (uint32_t)((tempreg) | (RCC->BDCR & RCC_BDCR_RTCSEL)); 00533 00534 /* Get the CEC clock configuration -----------------------------------------*/ 00535 PeriphClkInit->CecClockSelection = __HAL_RCC_GET_CEC_SOURCE(); 00536 00537 /* Get the FMPI2C1 clock configuration -------------------------------------*/ 00538 PeriphClkInit->Fmpi2c1ClockSelection = __HAL_RCC_GET_FMPI2C1_SOURCE(); 00539 00540 /* Get the CLK48 clock configuration ----------------------------------------*/ 00541 PeriphClkInit->Clk48ClockSelection = __HAL_RCC_GET_CLK48_SOURCE(); 00542 00543 /* Get the SDIO clock configuration ----------------------------------------*/ 00544 PeriphClkInit->SdioClockSelection = __HAL_RCC_GET_SDIO_SOURCE(); 00545 00546 /* Get the SPDIFRX clock configuration -------------------------------------*/ 00547 PeriphClkInit->SpdifClockSelection = __HAL_RCC_GET_SPDIFRX_SOURCE(); 00548 00549 /* Get the TIM Prescaler configuration -------------------------------------*/ 00550 if ((RCC->DCKCFGR & RCC_DCKCFGR_TIMPRE) == RESET) 00551 { 00552 PeriphClkInit->TIMPresSelection = RCC_TIMPRES_DESACTIVATED; 00553 } 00554 else 00555 { 00556 PeriphClkInit->TIMPresSelection = RCC_TIMPRES_ACTIVATED; 00557 } 00558 } 00559 00560 /** 00561 * @brief Return the peripheral clock frequency for a given peripheral(SAI..) 00562 * @note Return 0 if peripheral clock identifier not managed by this API 00563 * @param PeriphClk Peripheral clock identifier 00564 * This parameter can be one of the following values: 00565 * @arg RCC_PERIPHCLK_SAI1: SAI1 peripheral clock 00566 * @arg RCC_PERIPHCLK_SAI2: SAI2 peripheral clock 00567 * @arg RCC_PERIPHCLK_I2S_APB1: I2S APB1 peripheral clock 00568 * @arg RCC_PERIPHCLK_I2S_APB2: I2S APB2 peripheral clock 00569 * @retval Frequency in KHz 00570 */ 00571 uint32_t HAL_RCCEx_GetPeriphCLKFreq(uint32_t PeriphClk) 00572 { 00573 uint32_t tmpreg1 = 0U; 00574 /* This variable used to store the SAI clock frequency (value in Hz) */ 00575 uint32_t frequency = 0U; 00576 /* This variable used to store the VCO Input (value in Hz) */ 00577 uint32_t vcoinput = 0U; 00578 /* This variable used to store the SAI clock source */ 00579 uint32_t saiclocksource = 0U; 00580 uint32_t srcclk = 0U; 00581 /* This variable used to store the VCO Output (value in Hz) */ 00582 uint32_t vcooutput = 0U; 00583 switch (PeriphClk) 00584 { 00585 case RCC_PERIPHCLK_SAI1: 00586 case RCC_PERIPHCLK_SAI2: 00587 { 00588 saiclocksource = RCC->DCKCFGR; 00589 saiclocksource &= (RCC_DCKCFGR_SAI1SRC | RCC_DCKCFGR_SAI2SRC); 00590 switch (saiclocksource) 00591 { 00592 case 0U: /* PLLSAI is the clock source for SAI*/ 00593 { 00594 /* Configure the PLLSAI division factor */ 00595 /* PLLSAI_VCO Input = PLL_SOURCE/PLLSAIM */ 00596 if((RCC->PLLCFGR & RCC_PLLCFGR_PLLSRC) == RCC_PLLSOURCE_HSI) 00597 { 00598 /* In Case the PLL Source is HSI (Internal Clock) */ 00599 vcoinput = (HSI_VALUE / (uint32_t)(RCC->PLLSAICFGR & RCC_PLLSAICFGR_PLLSAIM)); 00600 } 00601 else 00602 { 00603 /* In Case the PLL Source is HSE (External Clock) */ 00604 vcoinput = ((HSE_VALUE / (uint32_t)(RCC->PLLSAICFGR & RCC_PLLSAICFGR_PLLSAIM))); 00605 } 00606 /* PLLSAI_VCO Output = PLLSAI_VCO Input * PLLSAIN */ 00607 /* SAI_CLK(first level) = PLLSAI_VCO Output/PLLSAIQ */ 00608 tmpreg1 = (RCC->PLLSAICFGR & RCC_PLLSAICFGR_PLLSAIQ) >> 24U; 00609 frequency = (vcoinput * ((RCC->PLLSAICFGR & RCC_PLLSAICFGR_PLLSAIN) >> 6U))/(tmpreg1); 00610 00611 /* SAI_CLK_x = SAI_CLK(first level)/PLLSAIDIVQ */ 00612 tmpreg1 = (((RCC->DCKCFGR & RCC_DCKCFGR_PLLSAIDIVQ) >> 8U) + 1U); 00613 frequency = frequency/(tmpreg1); 00614 break; 00615 } 00616 case RCC_DCKCFGR_SAI1SRC_0: /* PLLI2S is the clock source for SAI*/ 00617 case RCC_DCKCFGR_SAI2SRC_0: /* PLLI2S is the clock source for SAI*/ 00618 { 00619 /* Configure the PLLI2S division factor */ 00620 /* PLLI2S_VCO Input = PLL_SOURCE/PLLI2SM */ 00621 if((RCC->PLLCFGR & RCC_PLLCFGR_PLLSRC) == RCC_PLLSOURCE_HSI) 00622 { 00623 /* In Case the PLL Source is HSI (Internal Clock) */ 00624 vcoinput = (HSI_VALUE / (uint32_t)(RCC->PLLI2SCFGR & RCC_PLLI2SCFGR_PLLI2SM)); 00625 } 00626 else 00627 { 00628 /* In Case the PLL Source is HSE (External Clock) */ 00629 vcoinput = ((HSE_VALUE / (uint32_t)(RCC->PLLI2SCFGR & RCC_PLLI2SCFGR_PLLI2SM))); 00630 } 00631 00632 /* PLLI2S_VCO Output = PLLI2S_VCO Input * PLLI2SN */ 00633 /* SAI_CLK(first level) = PLLI2S_VCO Output/PLLI2SQ */ 00634 tmpreg1 = (RCC->PLLI2SCFGR & RCC_PLLI2SCFGR_PLLI2SQ) >> 24U; 00635 frequency = (vcoinput * ((RCC->PLLI2SCFGR & RCC_PLLI2SCFGR_PLLI2SN) >> 6U))/(tmpreg1); 00636 00637 /* SAI_CLK_x = SAI_CLK(first level)/PLLI2SDIVQ */ 00638 tmpreg1 = ((RCC->DCKCFGR & RCC_DCKCFGR_PLLI2SDIVQ) + 1U); 00639 frequency = frequency/(tmpreg1); 00640 break; 00641 } 00642 case RCC_DCKCFGR_SAI1SRC_1: /* PLLR is the clock source for SAI*/ 00643 case RCC_DCKCFGR_SAI2SRC_1: /* PLLR is the clock source for SAI*/ 00644 { 00645 /* Configure the PLLI2S division factor */ 00646 /* PLL_VCO Input = PLL_SOURCE/PLLM */ 00647 if((RCC->PLLCFGR & RCC_PLLCFGR_PLLSRC) == RCC_PLLSOURCE_HSI) 00648 { 00649 /* In Case the PLL Source is HSI (Internal Clock) */ 00650 vcoinput = (HSI_VALUE / (uint32_t)(RCC->PLLCFGR & RCC_PLLCFGR_PLLM)); 00651 } 00652 else 00653 { 00654 /* In Case the PLL Source is HSE (External Clock) */ 00655 vcoinput = ((HSE_VALUE / (uint32_t)(RCC->PLLCFGR & RCC_PLLCFGR_PLLM))); 00656 } 00657 00658 /* PLL_VCO Output = PLL_VCO Input * PLLN */ 00659 /* SAI_CLK_x = PLL_VCO Output/PLLR */ 00660 tmpreg1 = (RCC->PLLCFGR & RCC_PLLCFGR_PLLR) >> 28U; 00661 frequency = (vcoinput * ((RCC->PLLCFGR & RCC_PLLCFGR_PLLN) >> 6U))/(tmpreg1); 00662 break; 00663 } 00664 case RCC_DCKCFGR_SAI1SRC: /* External clock is the clock source for SAI*/ 00665 { 00666 frequency = EXTERNAL_CLOCK_VALUE; 00667 break; 00668 } 00669 case RCC_DCKCFGR_SAI2SRC: /* PLLSRC(HSE or HSI) is the clock source for SAI*/ 00670 { 00671 if((RCC->PLLCFGR & RCC_PLLCFGR_PLLSRC) == RCC_PLLSOURCE_HSI) 00672 { 00673 /* In Case the PLL Source is HSI (Internal Clock) */ 00674 frequency = (uint32_t)(HSI_VALUE); 00675 } 00676 else 00677 { 00678 /* In Case the PLL Source is HSE (External Clock) */ 00679 frequency = (uint32_t)(HSE_VALUE); 00680 } 00681 break; 00682 } 00683 default : 00684 { 00685 break; 00686 } 00687 } 00688 break; 00689 } 00690 case RCC_PERIPHCLK_I2S_APB1: 00691 { 00692 /* Get the current I2S source */ 00693 srcclk = __HAL_RCC_GET_I2S_APB1_SOURCE(); 00694 switch (srcclk) 00695 { 00696 /* Check if I2S clock selection is External clock mapped on the I2S_CKIN pin used as I2S clock */ 00697 case RCC_I2SAPB1CLKSOURCE_EXT: 00698 { 00699 /* Set the I2S clock to the external clock value */ 00700 frequency = EXTERNAL_CLOCK_VALUE; 00701 break; 00702 } 00703 /* Check if I2S clock selection is PLLI2S VCO output clock divided by PLLI2SR used as I2S clock */ 00704 case RCC_I2SAPB1CLKSOURCE_PLLI2S: 00705 { 00706 /* Configure the PLLI2S division factor */ 00707 /* PLLI2S_VCO Input = PLL_SOURCE/PLLI2SM */ 00708 if((RCC->PLLCFGR & RCC_PLLCFGR_PLLSRC) == RCC_PLLSOURCE_HSE) 00709 { 00710 /* Get the I2S source clock value */ 00711 vcoinput = (uint32_t)(HSE_VALUE / (uint32_t)(RCC->PLLI2SCFGR & RCC_PLLI2SCFGR_PLLI2SM)); 00712 } 00713 else 00714 { 00715 /* Get the I2S source clock value */ 00716 vcoinput = (uint32_t)(HSI_VALUE / (uint32_t)(RCC->PLLI2SCFGR & RCC_PLLI2SCFGR_PLLI2SM)); 00717 } 00718 00719 /* PLLI2S_VCO Output = PLLI2S_VCO Input * PLLI2SN */ 00720 vcooutput = (uint32_t)(vcoinput * (((RCC->PLLI2SCFGR & RCC_PLLI2SCFGR_PLLI2SN) >> 6U) & (RCC_PLLI2SCFGR_PLLI2SN >> 6U))); 00721 /* I2S_CLK = PLLI2S_VCO Output/PLLI2SR */ 00722 frequency = (uint32_t)(vcooutput /(((RCC->PLLI2SCFGR & RCC_PLLI2SCFGR_PLLI2SR) >> 28U) & (RCC_PLLI2SCFGR_PLLI2SR >> 28U))); 00723 break; 00724 } 00725 /* Check if I2S clock selection is PLL VCO Output divided by PLLR used as I2S clock */ 00726 case RCC_I2SAPB1CLKSOURCE_PLLR: 00727 { 00728 /* Configure the PLL division factor R */ 00729 /* PLL_VCO Input = PLL_SOURCE/PLLM */ 00730 if((RCC->PLLCFGR & RCC_PLLCFGR_PLLSRC) == RCC_PLLSOURCE_HSE) 00731 { 00732 /* Get the I2S source clock value */ 00733 vcoinput = (uint32_t)(HSE_VALUE / (uint32_t)(RCC->PLLCFGR & RCC_PLLCFGR_PLLM)); 00734 } 00735 else 00736 { 00737 /* Get the I2S source clock value */ 00738 vcoinput = (uint32_t)(HSI_VALUE / (uint32_t)(RCC->PLLCFGR & RCC_PLLCFGR_PLLM)); 00739 } 00740 00741 /* PLL_VCO Output = PLL_VCO Input * PLLN */ 00742 vcooutput = (uint32_t)(vcoinput * (((RCC->PLLCFGR & RCC_PLLCFGR_PLLN) >> 6U) & (RCC_PLLCFGR_PLLN >> 6U))); 00743 /* I2S_CLK = PLL_VCO Output/PLLR */ 00744 frequency = (uint32_t)(vcooutput /(((RCC->PLLCFGR & RCC_PLLCFGR_PLLR) >> 28U) & (RCC_PLLCFGR_PLLR >> 28U))); 00745 break; 00746 } 00747 /* Check if I2S clock selection is HSI or HSE depending from PLL source Clock */ 00748 case RCC_I2SAPB1CLKSOURCE_PLLSRC: 00749 { 00750 if((RCC->PLLCFGR & RCC_PLLCFGR_PLLSRC) == RCC_PLLSOURCE_HSE) 00751 { 00752 frequency = HSE_VALUE; 00753 } 00754 else 00755 { 00756 frequency = HSI_VALUE; 00757 } 00758 break; 00759 } 00760 /* Clock not enabled for I2S*/ 00761 default: 00762 { 00763 frequency = 0U; 00764 break; 00765 } 00766 } 00767 break; 00768 } 00769 case RCC_PERIPHCLK_I2S_APB2: 00770 { 00771 /* Get the current I2S source */ 00772 srcclk = __HAL_RCC_GET_I2S_APB2_SOURCE(); 00773 switch (srcclk) 00774 { 00775 /* Check if I2S clock selection is External clock mapped on the I2S_CKIN pin used as I2S clock */ 00776 case RCC_I2SAPB2CLKSOURCE_EXT: 00777 { 00778 /* Set the I2S clock to the external clock value */ 00779 frequency = EXTERNAL_CLOCK_VALUE; 00780 break; 00781 } 00782 /* Check if I2S clock selection is PLLI2S VCO output clock divided by PLLI2SR used as I2S clock */ 00783 case RCC_I2SAPB2CLKSOURCE_PLLI2S: 00784 { 00785 /* Configure the PLLI2S division factor */ 00786 /* PLLI2S_VCO Input = PLL_SOURCE/PLLI2SM */ 00787 if((RCC->PLLCFGR & RCC_PLLCFGR_PLLSRC) == RCC_PLLSOURCE_HSE) 00788 { 00789 /* Get the I2S source clock value */ 00790 vcoinput = (uint32_t)(HSE_VALUE / (uint32_t)(RCC->PLLI2SCFGR & RCC_PLLI2SCFGR_PLLI2SM)); 00791 } 00792 else 00793 { 00794 /* Get the I2S source clock value */ 00795 vcoinput = (uint32_t)(HSI_VALUE / (uint32_t)(RCC->PLLI2SCFGR & RCC_PLLI2SCFGR_PLLI2SM)); 00796 } 00797 00798 /* PLLI2S_VCO Output = PLLI2S_VCO Input * PLLI2SN */ 00799 vcooutput = (uint32_t)(vcoinput * (((RCC->PLLI2SCFGR & RCC_PLLI2SCFGR_PLLI2SN) >> 6U) & (RCC_PLLI2SCFGR_PLLI2SN >> 6U))); 00800 /* I2S_CLK = PLLI2S_VCO Output/PLLI2SR */ 00801 frequency = (uint32_t)(vcooutput /(((RCC->PLLI2SCFGR & RCC_PLLI2SCFGR_PLLI2SR) >> 28U) & (RCC_PLLI2SCFGR_PLLI2SR >> 28U))); 00802 break; 00803 } 00804 /* Check if I2S clock selection is PLL VCO Output divided by PLLR used as I2S clock */ 00805 case RCC_I2SAPB2CLKSOURCE_PLLR: 00806 { 00807 /* Configure the PLL division factor R */ 00808 /* PLL_VCO Input = PLL_SOURCE/PLLM */ 00809 if((RCC->PLLCFGR & RCC_PLLCFGR_PLLSRC) == RCC_PLLSOURCE_HSE) 00810 { 00811 /* Get the I2S source clock value */ 00812 vcoinput = (uint32_t)(HSE_VALUE / (uint32_t)(RCC->PLLCFGR & RCC_PLLCFGR_PLLM)); 00813 } 00814 else 00815 { 00816 /* Get the I2S source clock value */ 00817 vcoinput = (uint32_t)(HSI_VALUE / (uint32_t)(RCC->PLLCFGR & RCC_PLLCFGR_PLLM)); 00818 } 00819 00820 /* PLL_VCO Output = PLL_VCO Input * PLLN */ 00821 vcooutput = (uint32_t)(vcoinput * (((RCC->PLLCFGR & RCC_PLLCFGR_PLLN) >> 6U) & (RCC_PLLCFGR_PLLN >> 6U))); 00822 /* I2S_CLK = PLL_VCO Output/PLLR */ 00823 frequency = (uint32_t)(vcooutput /(((RCC->PLLCFGR & RCC_PLLCFGR_PLLR) >> 28U) & (RCC_PLLCFGR_PLLR >> 28U))); 00824 break; 00825 } 00826 /* Check if I2S clock selection is HSI or HSE depending from PLL source Clock */ 00827 case RCC_I2SAPB2CLKSOURCE_PLLSRC: 00828 { 00829 if((RCC->PLLCFGR & RCC_PLLCFGR_PLLSRC) == RCC_PLLSOURCE_HSE) 00830 { 00831 frequency = HSE_VALUE; 00832 } 00833 else 00834 { 00835 frequency = HSI_VALUE; 00836 } 00837 break; 00838 } 00839 /* Clock not enabled for I2S*/ 00840 default: 00841 { 00842 frequency = 0U; 00843 break; 00844 } 00845 } 00846 break; 00847 } 00848 } 00849 return frequency; 00850 } 00851 #endif /* STM32F446xx */ 00852 00853 #if defined(STM32F469xx) || defined(STM32F479xx) 00854 /** 00855 * @brief Initializes the RCC extended peripherals clocks according to the specified 00856 * parameters in the RCC_PeriphCLKInitTypeDef. 00857 * @param PeriphClkInit pointer to an RCC_PeriphCLKInitTypeDef structure that 00858 * contains the configuration information for the Extended Peripherals 00859 * clocks(I2S, SAI, LTDC, RTC and TIM). 00860 * 00861 * @note Care must be taken when HAL_RCCEx_PeriphCLKConfig() is used to select 00862 * the RTC clock source; in this case the Backup domain will be reset in 00863 * order to modify the RTC Clock source, as consequence RTC registers (including 00864 * the backup registers) and RCC_BDCR register are set to their reset values. 00865 * 00866 * @retval HAL status 00867 */ 00868 HAL_StatusTypeDef HAL_RCCEx_PeriphCLKConfig(RCC_PeriphCLKInitTypeDef *PeriphClkInit) 00869 { 00870 uint32_t tickstart = 0U; 00871 uint32_t tmpreg1 = 0U; 00872 uint32_t pllsaip = 0U; 00873 uint32_t pllsaiq = 0U; 00874 uint32_t pllsair = 0U; 00875 00876 /* Check the parameters */ 00877 assert_param(IS_RCC_PERIPHCLOCK(PeriphClkInit->PeriphClockSelection)); 00878 00879 /*--------------------------- CLK48 Configuration --------------------------*/ 00880 if(((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_CLK48) == RCC_PERIPHCLK_CLK48) 00881 { 00882 /* Check the parameters */ 00883 assert_param(IS_RCC_CLK48CLKSOURCE(PeriphClkInit->Clk48ClockSelection)); 00884 00885 /* Configure the CLK48 clock source */ 00886 __HAL_RCC_CLK48_CONFIG(PeriphClkInit->Clk48ClockSelection); 00887 } 00888 /*--------------------------------------------------------------------------*/ 00889 00890 /*------------------------------ SDIO Configuration ------------------------*/ 00891 if(((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_SDIO) == RCC_PERIPHCLK_SDIO) 00892 { 00893 /* Check the parameters */ 00894 assert_param(IS_RCC_SDIOCLKSOURCE(PeriphClkInit->SdioClockSelection)); 00895 00896 /* Configure the SDIO clock source */ 00897 __HAL_RCC_SDIO_CONFIG(PeriphClkInit->SdioClockSelection); 00898 } 00899 /*--------------------------------------------------------------------------*/ 00900 00901 /*----------------------- SAI/I2S Configuration (PLLI2S) -------------------*/ 00902 /*------------------- Common configuration SAI/I2S -------------------------*/ 00903 /* In Case of SAI or I2S Clock Configuration through PLLI2S, PLLI2SN division 00904 factor is common parameters for both peripherals */ 00905 if((((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_I2S) == RCC_PERIPHCLK_I2S) || 00906 (((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_SAI_PLLI2S) == RCC_PERIPHCLK_SAI_PLLI2S) || 00907 (((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_PLLI2S) == RCC_PERIPHCLK_PLLI2S)) 00908 { 00909 /* check for Parameters */ 00910 assert_param(IS_RCC_PLLI2SN_VALUE(PeriphClkInit->PLLI2S.PLLI2SN)); 00911 00912 /* Disable the PLLI2S */ 00913 __HAL_RCC_PLLI2S_DISABLE(); 00914 /* Get tick */ 00915 tickstart = HAL_GetTick(); 00916 /* Wait till PLLI2S is disabled */ 00917 while(__HAL_RCC_GET_FLAG(RCC_FLAG_PLLI2SRDY) != RESET) 00918 { 00919 if((HAL_GetTick() - tickstart ) > PLLI2S_TIMEOUT_VALUE) 00920 { 00921 /* return in case of Timeout detected */ 00922 return HAL_TIMEOUT; 00923 } 00924 } 00925 00926 /*---------------------- I2S configuration -------------------------------*/ 00927 /* In Case of I2S Clock Configuration through PLLI2S, PLLI2SR must be added 00928 only for I2S configuration */ 00929 if(((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_I2S) == (RCC_PERIPHCLK_I2S)) 00930 { 00931 /* check for Parameters */ 00932 assert_param(IS_RCC_PLLI2SR_VALUE(PeriphClkInit->PLLI2S.PLLI2SR)); 00933 /* Configure the PLLI2S division factors */ 00934 /* PLLI2S_VCO = f(VCO clock) = f(PLLI2S clock input) x (PLLI2SN/PLLM) */ 00935 /* I2SCLK = f(PLLI2S clock output) = f(VCO clock) / PLLI2SR */ 00936 __HAL_RCC_PLLI2S_CONFIG(PeriphClkInit->PLLI2S.PLLI2SN , PeriphClkInit->PLLI2S.PLLI2SR); 00937 } 00938 00939 /*---------------------------- SAI configuration -------------------------*/ 00940 /* In Case of SAI Clock Configuration through PLLI2S, PLLI2SQ and PLLI2S_DIVQ must 00941 be added only for SAI configuration */ 00942 if(((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_SAI_PLLI2S) == (RCC_PERIPHCLK_SAI_PLLI2S)) 00943 { 00944 /* Check the PLLI2S division factors */ 00945 assert_param(IS_RCC_PLLI2SQ_VALUE(PeriphClkInit->PLLI2S.PLLI2SQ)); 00946 assert_param(IS_RCC_PLLI2S_DIVQ_VALUE(PeriphClkInit->PLLI2SDivQ)); 00947 00948 /* Read PLLI2SR value from PLLI2SCFGR register (this value is not need for SAI configuration) */ 00949 tmpreg1 = ((RCC->PLLI2SCFGR & RCC_PLLI2SCFGR_PLLI2SR) >> RCC_PLLI2SCFGR_PLLI2SR_Pos); 00950 /* Configure the PLLI2S division factors */ 00951 /* PLLI2S_VCO Input = PLL_SOURCE/PLLM */ 00952 /* PLLI2S_VCO Output = PLLI2S_VCO Input * PLLI2SN */ 00953 /* SAI_CLK(first level) = PLLI2S_VCO Output/PLLI2SQ */ 00954 __HAL_RCC_PLLI2S_SAICLK_CONFIG(PeriphClkInit->PLLI2S.PLLI2SN , PeriphClkInit->PLLI2S.PLLI2SQ , tmpreg1); 00955 /* SAI_CLK_x = SAI_CLK(first level)/PLLI2SDIVQ */ 00956 __HAL_RCC_PLLI2S_PLLSAICLKDIVQ_CONFIG(PeriphClkInit->PLLI2SDivQ); 00957 } 00958 00959 /*----------------- In Case of PLLI2S is just selected -----------------*/ 00960 if((PeriphClkInit->PeriphClockSelection & RCC_PERIPHCLK_PLLI2S) == RCC_PERIPHCLK_PLLI2S) 00961 { 00962 /* Check for Parameters */ 00963 assert_param(IS_RCC_PLLI2SQ_VALUE(PeriphClkInit->PLLI2S.PLLI2SQ)); 00964 assert_param(IS_RCC_PLLI2SR_VALUE(PeriphClkInit->PLLI2S.PLLI2SR)); 00965 00966 /* Configure the PLLI2S multiplication and division factors */ 00967 __HAL_RCC_PLLI2S_SAICLK_CONFIG(PeriphClkInit->PLLI2S.PLLI2SN, PeriphClkInit->PLLI2S.PLLI2SQ, PeriphClkInit->PLLI2S.PLLI2SR); 00968 } 00969 00970 /* Enable the PLLI2S */ 00971 __HAL_RCC_PLLI2S_ENABLE(); 00972 /* Get tick */ 00973 tickstart = HAL_GetTick(); 00974 /* Wait till PLLI2S is ready */ 00975 while(__HAL_RCC_GET_FLAG(RCC_FLAG_PLLI2SRDY) == RESET) 00976 { 00977 if((HAL_GetTick() - tickstart ) > PLLI2S_TIMEOUT_VALUE) 00978 { 00979 /* return in case of Timeout detected */ 00980 return HAL_TIMEOUT; 00981 } 00982 } 00983 } 00984 /*--------------------------------------------------------------------------*/ 00985 00986 /*----------------------- SAI/LTDC Configuration (PLLSAI) ------------------*/ 00987 /*----------------------- Common configuration SAI/LTDC --------------------*/ 00988 /* In Case of SAI, LTDC or CLK48 Clock Configuration through PLLSAI, PLLSAIN division 00989 factor is common parameters for these peripherals */ 00990 if((((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_SAI_PLLSAI) == RCC_PERIPHCLK_SAI_PLLSAI) || 00991 (((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_LTDC) == RCC_PERIPHCLK_LTDC) || 00992 ((((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_CLK48) == RCC_PERIPHCLK_CLK48) && 00993 (PeriphClkInit->Clk48ClockSelection == RCC_CLK48CLKSOURCE_PLLSAIP))) 00994 { 00995 /* Check the PLLSAI division factors */ 00996 assert_param(IS_RCC_PLLSAIN_VALUE(PeriphClkInit->PLLSAI.PLLSAIN)); 00997 00998 /* Disable PLLSAI Clock */ 00999 __HAL_RCC_PLLSAI_DISABLE(); 01000 /* Get tick */ 01001 tickstart = HAL_GetTick(); 01002 /* Wait till PLLSAI is disabled */ 01003 while(__HAL_RCC_PLLSAI_GET_FLAG() != RESET) 01004 { 01005 if((HAL_GetTick() - tickstart ) > PLLSAI_TIMEOUT_VALUE) 01006 { 01007 /* return in case of Timeout detected */ 01008 return HAL_TIMEOUT; 01009 } 01010 } 01011 01012 /*---------------------------- SAI configuration -------------------------*/ 01013 /* In Case of SAI Clock Configuration through PLLSAI, PLLSAIQ and PLLSAI_DIVQ must 01014 be added only for SAI configuration */ 01015 if(((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_SAI_PLLSAI) == (RCC_PERIPHCLK_SAI_PLLSAI)) 01016 { 01017 assert_param(IS_RCC_PLLSAIQ_VALUE(PeriphClkInit->PLLSAI.PLLSAIQ)); 01018 assert_param(IS_RCC_PLLSAI_DIVQ_VALUE(PeriphClkInit->PLLSAIDivQ)); 01019 01020 /* Read PLLSAIP value from PLLSAICFGR register (this value is not needed for SAI configuration) */ 01021 pllsaip = ((((RCC->PLLSAICFGR & RCC_PLLSAICFGR_PLLSAIP) >> RCC_PLLSAICFGR_PLLSAIP_Pos) + 1U) << 1U); 01022 /* Read PLLSAIR value from PLLSAICFGR register (this value is not need for SAI configuration) */ 01023 pllsair = ((RCC->PLLSAICFGR & RCC_PLLSAICFGR_PLLSAIR) >> RCC_PLLSAICFGR_PLLSAIR_Pos); 01024 /* PLLSAI_VCO Input = PLL_SOURCE/PLLM */ 01025 /* PLLSAI_VCO Output = PLLSAI_VCO Input * PLLSAIN */ 01026 /* SAI_CLK(first level) = PLLSAI_VCO Output/PLLSAIQ */ 01027 __HAL_RCC_PLLSAI_CONFIG(PeriphClkInit->PLLSAI.PLLSAIN, pllsaip, PeriphClkInit->PLLSAI.PLLSAIQ, pllsair); 01028 /* SAI_CLK_x = SAI_CLK(first level)/PLLSAIDIVQ */ 01029 __HAL_RCC_PLLSAI_PLLSAICLKDIVQ_CONFIG(PeriphClkInit->PLLSAIDivQ); 01030 } 01031 01032 /*---------------------------- LTDC configuration ------------------------*/ 01033 if(((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_LTDC) == (RCC_PERIPHCLK_LTDC)) 01034 { 01035 assert_param(IS_RCC_PLLSAIR_VALUE(PeriphClkInit->PLLSAI.PLLSAIR)); 01036 assert_param(IS_RCC_PLLSAI_DIVR_VALUE(PeriphClkInit->PLLSAIDivR)); 01037 01038 /* Read PLLSAIP value from PLLSAICFGR register (this value is not needed for SAI configuration) */ 01039 pllsaip = ((((RCC->PLLSAICFGR & RCC_PLLSAICFGR_PLLSAIP) >> RCC_PLLSAICFGR_PLLSAIP_Pos) + 1U) << 1U); 01040 /* Read PLLSAIQ value from PLLSAICFGR register (this value is not need for SAI configuration) */ 01041 pllsaiq = ((RCC->PLLSAICFGR & RCC_PLLSAICFGR_PLLSAIQ) >> RCC_PLLSAICFGR_PLLSAIQ_Pos); 01042 /* PLLSAI_VCO Input = PLL_SOURCE/PLLM */ 01043 /* PLLSAI_VCO Output = PLLSAI_VCO Input * PLLSAIN */ 01044 /* LTDC_CLK(first level) = PLLSAI_VCO Output/PLLSAIR */ 01045 __HAL_RCC_PLLSAI_CONFIG(PeriphClkInit->PLLSAI.PLLSAIN, pllsaip, pllsaiq, PeriphClkInit->PLLSAI.PLLSAIR); 01046 /* LTDC_CLK = LTDC_CLK(first level)/PLLSAIDIVR */ 01047 __HAL_RCC_PLLSAI_PLLSAICLKDIVR_CONFIG(PeriphClkInit->PLLSAIDivR); 01048 } 01049 01050 /*---------------------------- CLK48 configuration ------------------------*/ 01051 /* Configure the PLLSAI when it is used as clock source for CLK48 */ 01052 if((((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_CLK48) == (RCC_PERIPHCLK_CLK48)) && 01053 (PeriphClkInit->Clk48ClockSelection == RCC_CLK48CLKSOURCE_PLLSAIP)) 01054 { 01055 assert_param(IS_RCC_PLLSAIP_VALUE(PeriphClkInit->PLLSAI.PLLSAIP)); 01056 01057 /* Read PLLSAIQ value from PLLSAICFGR register (this value is not need for SAI configuration) */ 01058 pllsaiq = ((RCC->PLLSAICFGR & RCC_PLLSAICFGR_PLLSAIQ) >> RCC_PLLSAICFGR_PLLSAIQ_Pos); 01059 /* Read PLLSAIR value from PLLSAICFGR register (this value is not need for SAI configuration) */ 01060 pllsair = ((RCC->PLLSAICFGR & RCC_PLLSAICFGR_PLLSAIR) >> RCC_PLLSAICFGR_PLLSAIR_Pos); 01061 /* PLLSAI_VCO Input = PLL_SOURCE/PLLM */ 01062 /* PLLSAI_VCO Output = PLLSAI_VCO Input * PLLSAIN */ 01063 /* CLK48_CLK(first level) = PLLSAI_VCO Output/PLLSAIP */ 01064 __HAL_RCC_PLLSAI_CONFIG(PeriphClkInit->PLLSAI.PLLSAIN, PeriphClkInit->PLLSAI.PLLSAIP, pllsaiq, pllsair); 01065 } 01066 01067 /* Enable PLLSAI Clock */ 01068 __HAL_RCC_PLLSAI_ENABLE(); 01069 /* Get tick */ 01070 tickstart = HAL_GetTick(); 01071 /* Wait till PLLSAI is ready */ 01072 while(__HAL_RCC_PLLSAI_GET_FLAG() == RESET) 01073 { 01074 if((HAL_GetTick() - tickstart ) > PLLSAI_TIMEOUT_VALUE) 01075 { 01076 /* return in case of Timeout detected */ 01077 return HAL_TIMEOUT; 01078 } 01079 } 01080 } 01081 01082 /*--------------------------------------------------------------------------*/ 01083 01084 /*---------------------------- RTC configuration ---------------------------*/ 01085 if(((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_RTC) == (RCC_PERIPHCLK_RTC)) 01086 { 01087 /* Check for RTC Parameters used to output RTCCLK */ 01088 assert_param(IS_RCC_RTCCLKSOURCE(PeriphClkInit->RTCClockSelection)); 01089 01090 /* Enable Power Clock*/ 01091 __HAL_RCC_PWR_CLK_ENABLE(); 01092 01093 /* Enable write access to Backup domain */ 01094 PWR->CR |= PWR_CR_DBP; 01095 01096 /* Get tick */ 01097 tickstart = HAL_GetTick(); 01098 01099 while((PWR->CR & PWR_CR_DBP) == RESET) 01100 { 01101 if((HAL_GetTick() - tickstart ) > RCC_DBP_TIMEOUT_VALUE) 01102 { 01103 return HAL_TIMEOUT; 01104 } 01105 } 01106 /* Reset the Backup domain only if the RTC Clock source selection is modified from reset value */ 01107 tmpreg1 = (RCC->BDCR & RCC_BDCR_RTCSEL); 01108 if((tmpreg1 != 0x00000000U) && ((tmpreg1) != (PeriphClkInit->RTCClockSelection & RCC_BDCR_RTCSEL))) 01109 { 01110 /* Store the content of BDCR register before the reset of Backup Domain */ 01111 tmpreg1 = (RCC->BDCR & ~(RCC_BDCR_RTCSEL)); 01112 /* RTC Clock selection can be changed only if the Backup Domain is reset */ 01113 __HAL_RCC_BACKUPRESET_FORCE(); 01114 __HAL_RCC_BACKUPRESET_RELEASE(); 01115 /* Restore the Content of BDCR register */ 01116 RCC->BDCR = tmpreg1; 01117 01118 /* Wait for LSE reactivation if LSE was enable prior to Backup Domain reset */ 01119 if(HAL_IS_BIT_SET(RCC->BDCR, RCC_BDCR_LSEON)) 01120 { 01121 /* Get tick */ 01122 tickstart = HAL_GetTick(); 01123 01124 /* Wait till LSE is ready */ 01125 while(__HAL_RCC_GET_FLAG(RCC_FLAG_LSERDY) == RESET) 01126 { 01127 if((HAL_GetTick() - tickstart ) > RCC_LSE_TIMEOUT_VALUE) 01128 { 01129 return HAL_TIMEOUT; 01130 } 01131 } 01132 } 01133 } 01134 __HAL_RCC_RTC_CONFIG(PeriphClkInit->RTCClockSelection); 01135 } 01136 /*--------------------------------------------------------------------------*/ 01137 01138 /*---------------------------- TIM configuration ---------------------------*/ 01139 if(((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_TIM) == (RCC_PERIPHCLK_TIM)) 01140 { 01141 __HAL_RCC_TIMCLKPRESCALER(PeriphClkInit->TIMPresSelection); 01142 } 01143 return HAL_OK; 01144 } 01145 01146 /** 01147 * @brief Configures the RCC_PeriphCLKInitTypeDef according to the internal 01148 * RCC configuration registers. 01149 * @param PeriphClkInit pointer to an RCC_PeriphCLKInitTypeDef structure that 01150 * will be configured. 01151 * @retval None 01152 */ 01153 void HAL_RCCEx_GetPeriphCLKConfig(RCC_PeriphCLKInitTypeDef *PeriphClkInit) 01154 { 01155 uint32_t tempreg; 01156 01157 /* Set all possible values for the extended clock type parameter------------*/ 01158 PeriphClkInit->PeriphClockSelection = RCC_PERIPHCLK_I2S | RCC_PERIPHCLK_SAI_PLLSAI |\ 01159 RCC_PERIPHCLK_SAI_PLLI2S | RCC_PERIPHCLK_LTDC |\ 01160 RCC_PERIPHCLK_TIM | RCC_PERIPHCLK_RTC |\ 01161 RCC_PERIPHCLK_CLK48 | RCC_PERIPHCLK_SDIO; 01162 01163 /* Get the PLLI2S Clock configuration --------------------------------------*/ 01164 PeriphClkInit->PLLI2S.PLLI2SN = (uint32_t)((RCC->PLLI2SCFGR & RCC_PLLI2SCFGR_PLLI2SN) >> RCC_PLLI2SCFGR_PLLI2SN_Pos); 01165 PeriphClkInit->PLLI2S.PLLI2SR = (uint32_t)((RCC->PLLI2SCFGR & RCC_PLLI2SCFGR_PLLI2SR) >> RCC_PLLI2SCFGR_PLLI2SR_Pos); 01166 PeriphClkInit->PLLI2S.PLLI2SQ = (uint32_t)((RCC->PLLI2SCFGR & RCC_PLLI2SCFGR_PLLI2SQ) >> RCC_PLLI2SCFGR_PLLI2SQ_Pos); 01167 /* Get the PLLSAI Clock configuration --------------------------------------*/ 01168 PeriphClkInit->PLLSAI.PLLSAIN = (uint32_t)((RCC->PLLSAICFGR & RCC_PLLSAICFGR_PLLSAIN) >> RCC_PLLSAICFGR_PLLSAIN_Pos); 01169 PeriphClkInit->PLLSAI.PLLSAIR = (uint32_t)((RCC->PLLSAICFGR & RCC_PLLSAICFGR_PLLSAIR) >> RCC_PLLSAICFGR_PLLSAIR_Pos); 01170 PeriphClkInit->PLLSAI.PLLSAIQ = (uint32_t)((RCC->PLLSAICFGR & RCC_PLLSAICFGR_PLLSAIQ) >> RCC_PLLSAICFGR_PLLSAIQ_Pos); 01171 /* Get the PLLSAI/PLLI2S division factors ----------------------------------*/ 01172 PeriphClkInit->PLLI2SDivQ = (uint32_t)((RCC->DCKCFGR & RCC_DCKCFGR_PLLI2SDIVQ) >> RCC_DCKCFGR_PLLI2SDIVQ_Pos); 01173 PeriphClkInit->PLLSAIDivQ = (uint32_t)((RCC->DCKCFGR & RCC_DCKCFGR_PLLSAIDIVQ) >> RCC_DCKCFGR_PLLSAIDIVQ_Pos); 01174 PeriphClkInit->PLLSAIDivR = (uint32_t)(RCC->DCKCFGR & RCC_DCKCFGR_PLLSAIDIVR); 01175 /* Get the RTC Clock configuration -----------------------------------------*/ 01176 tempreg = (RCC->CFGR & RCC_CFGR_RTCPRE); 01177 PeriphClkInit->RTCClockSelection = (uint32_t)((tempreg) | (RCC->BDCR & RCC_BDCR_RTCSEL)); 01178 01179 /* Get the CLK48 clock configuration -------------------------------------*/ 01180 PeriphClkInit->Clk48ClockSelection = __HAL_RCC_GET_CLK48_SOURCE(); 01181 01182 /* Get the SDIO clock configuration ----------------------------------------*/ 01183 PeriphClkInit->SdioClockSelection = __HAL_RCC_GET_SDIO_SOURCE(); 01184 01185 if ((RCC->DCKCFGR & RCC_DCKCFGR_TIMPRE) == RESET) 01186 { 01187 PeriphClkInit->TIMPresSelection = RCC_TIMPRES_DESACTIVATED; 01188 } 01189 else 01190 { 01191 PeriphClkInit->TIMPresSelection = RCC_TIMPRES_ACTIVATED; 01192 } 01193 } 01194 01195 /** 01196 * @brief Return the peripheral clock frequency for a given peripheral(SAI..) 01197 * @note Return 0 if peripheral clock identifier not managed by this API 01198 * @param PeriphClk Peripheral clock identifier 01199 * This parameter can be one of the following values: 01200 * @arg RCC_PERIPHCLK_I2S: I2S peripheral clock 01201 * @retval Frequency in KHz 01202 */ 01203 uint32_t HAL_RCCEx_GetPeriphCLKFreq(uint32_t PeriphClk) 01204 { 01205 /* This variable used to store the I2S clock frequency (value in Hz) */ 01206 uint32_t frequency = 0U; 01207 /* This variable used to store the VCO Input (value in Hz) */ 01208 uint32_t vcoinput = 0U; 01209 uint32_t srcclk = 0U; 01210 /* This variable used to store the VCO Output (value in Hz) */ 01211 uint32_t vcooutput = 0U; 01212 switch (PeriphClk) 01213 { 01214 case RCC_PERIPHCLK_I2S: 01215 { 01216 /* Get the current I2S source */ 01217 srcclk = __HAL_RCC_GET_I2S_SOURCE(); 01218 switch (srcclk) 01219 { 01220 /* Check if I2S clock selection is External clock mapped on the I2S_CKIN pin used as I2S clock */ 01221 case RCC_I2SCLKSOURCE_EXT: 01222 { 01223 /* Set the I2S clock to the external clock value */ 01224 frequency = EXTERNAL_CLOCK_VALUE; 01225 break; 01226 } 01227 /* Check if I2S clock selection is PLLI2S VCO output clock divided by PLLI2SR used as I2S clock */ 01228 case RCC_I2SCLKSOURCE_PLLI2S: 01229 { 01230 /* Configure the PLLI2S division factor */ 01231 /* PLLI2S_VCO Input = PLL_SOURCE/PLLI2SM */ 01232 if((RCC->PLLCFGR & RCC_PLLCFGR_PLLSRC) == RCC_PLLSOURCE_HSE) 01233 { 01234 /* Get the I2S source clock value */ 01235 vcoinput = (uint32_t)(HSE_VALUE / (uint32_t)(RCC->PLLCFGR & RCC_PLLCFGR_PLLM)); 01236 } 01237 else 01238 { 01239 /* Get the I2S source clock value */ 01240 vcoinput = (uint32_t)(HSI_VALUE / (uint32_t)(RCC->PLLCFGR & RCC_PLLCFGR_PLLM)); 01241 } 01242 01243 /* PLLI2S_VCO Output = PLLI2S_VCO Input * PLLI2SN */ 01244 vcooutput = (uint32_t)(vcoinput * (((RCC->PLLI2SCFGR & RCC_PLLI2SCFGR_PLLI2SN) >> 6U) & (RCC_PLLI2SCFGR_PLLI2SN >> 6U))); 01245 /* I2S_CLK = PLLI2S_VCO Output/PLLI2SR */ 01246 frequency = (uint32_t)(vcooutput /(((RCC->PLLI2SCFGR & RCC_PLLI2SCFGR_PLLI2SR) >> 28U) & (RCC_PLLI2SCFGR_PLLI2SR >> 28U))); 01247 break; 01248 } 01249 /* Clock not enabled for I2S*/ 01250 default: 01251 { 01252 frequency = 0U; 01253 break; 01254 } 01255 } 01256 break; 01257 } 01258 } 01259 return frequency; 01260 } 01261 #endif /* STM32F469xx || STM32F479xx */ 01262 01263 #if defined(STM32F412Zx) || defined(STM32F412Vx) || defined(STM32F412Rx) || defined(STM32F412Cx) || defined(STM32F413xx) || defined(STM32F423xx) 01264 /** 01265 * @brief Initializes the RCC extended peripherals clocks according to the specified 01266 * parameters in the RCC_PeriphCLKInitTypeDef. 01267 * @param PeriphClkInit pointer to an RCC_PeriphCLKInitTypeDef structure that 01268 * contains the configuration information for the Extended Peripherals 01269 * clocks(I2S, LTDC RTC and TIM). 01270 * 01271 * @note Care must be taken when HAL_RCCEx_PeriphCLKConfig() is used to select 01272 * the RTC clock source; in this case the Backup domain will be reset in 01273 * order to modify the RTC Clock source, as consequence RTC registers (including 01274 * the backup registers) and RCC_BDCR register are set to their reset values. 01275 * 01276 * @retval HAL status 01277 */ 01278 HAL_StatusTypeDef HAL_RCCEx_PeriphCLKConfig(RCC_PeriphCLKInitTypeDef *PeriphClkInit) 01279 { 01280 uint32_t tickstart = 0U; 01281 uint32_t tmpreg1 = 0U; 01282 #if defined(STM32F413xx) || defined(STM32F423xx) 01283 uint32_t plli2sq = 0U; 01284 #endif /* STM32F413xx || STM32F423xx */ 01285 uint32_t plli2sused = 0U; 01286 01287 /* Check the peripheral clock selection parameters */ 01288 assert_param(IS_RCC_PERIPHCLOCK(PeriphClkInit->PeriphClockSelection)); 01289 01290 /*----------------------------------- I2S APB1 configuration ---------------*/ 01291 if(((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_I2S_APB1) == (RCC_PERIPHCLK_I2S_APB1)) 01292 { 01293 /* Check the parameters */ 01294 assert_param(IS_RCC_I2SAPB1CLKSOURCE(PeriphClkInit->I2sApb1ClockSelection)); 01295 01296 /* Configure I2S Clock source */ 01297 __HAL_RCC_I2S_APB1_CONFIG(PeriphClkInit->I2sApb1ClockSelection); 01298 /* Enable the PLLI2S when it's used as clock source for I2S */ 01299 if(PeriphClkInit->I2sApb1ClockSelection == RCC_I2SAPB1CLKSOURCE_PLLI2S) 01300 { 01301 plli2sused = 1U; 01302 } 01303 } 01304 /*--------------------------------------------------------------------------*/ 01305 01306 /*----------------------------------- I2S APB2 configuration ---------------*/ 01307 if(((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_I2S_APB2) == (RCC_PERIPHCLK_I2S_APB2)) 01308 { 01309 /* Check the parameters */ 01310 assert_param(IS_RCC_I2SAPB2CLKSOURCE(PeriphClkInit->I2sApb2ClockSelection)); 01311 01312 /* Configure I2S Clock source */ 01313 __HAL_RCC_I2S_APB2_CONFIG(PeriphClkInit->I2sApb2ClockSelection); 01314 /* Enable the PLLI2S when it's used as clock source for I2S */ 01315 if(PeriphClkInit->I2sApb2ClockSelection == RCC_I2SAPB2CLKSOURCE_PLLI2S) 01316 { 01317 plli2sused = 1U; 01318 } 01319 } 01320 /*--------------------------------------------------------------------------*/ 01321 01322 #if defined(STM32F413xx) || defined(STM32F423xx) 01323 /*----------------------- SAI1 Block A configuration -----------------------*/ 01324 if(((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_SAIA) == (RCC_PERIPHCLK_SAIA)) 01325 { 01326 /* Check the parameters */ 01327 assert_param(IS_RCC_SAIACLKSOURCE(PeriphClkInit->SaiAClockSelection)); 01328 01329 /* Configure SAI1 Clock source */ 01330 __HAL_RCC_SAI_BLOCKACLKSOURCE_CONFIG(PeriphClkInit->SaiAClockSelection); 01331 /* Enable the PLLI2S when it's used as clock source for SAI */ 01332 if(PeriphClkInit->SaiAClockSelection == RCC_SAIACLKSOURCE_PLLI2SR) 01333 { 01334 plli2sused = 1U; 01335 } 01336 /* Enable the PLLSAI when it's used as clock source for SAI */ 01337 if(PeriphClkInit->SaiAClockSelection == RCC_SAIACLKSOURCE_PLLR) 01338 { 01339 /* Check for PLL/DIVR parameters */ 01340 assert_param(IS_RCC_PLL_DIVR_VALUE(PeriphClkInit->PLLDivR)); 01341 01342 /* SAI_CLK_x = SAI_CLK(first level)/PLLDIVR */ 01343 __HAL_RCC_PLL_PLLSAICLKDIVR_CONFIG(PeriphClkInit->PLLDivR); 01344 } 01345 } 01346 /*--------------------------------------------------------------------------*/ 01347 01348 /*---------------------- SAI1 Block B configuration ------------------------*/ 01349 if(((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_SAIB) == (RCC_PERIPHCLK_SAIB)) 01350 { 01351 /* Check the parameters */ 01352 assert_param(IS_RCC_SAIBCLKSOURCE(PeriphClkInit->SaiBClockSelection)); 01353 01354 /* Configure SAI1 Clock source */ 01355 __HAL_RCC_SAI_BLOCKBCLKSOURCE_CONFIG(PeriphClkInit->SaiBClockSelection); 01356 /* Enable the PLLI2S when it's used as clock source for SAI */ 01357 if(PeriphClkInit->SaiBClockSelection == RCC_SAIBCLKSOURCE_PLLI2SR) 01358 { 01359 plli2sused = 1U; 01360 } 01361 /* Enable the PLLSAI when it's used as clock source for SAI */ 01362 if(PeriphClkInit->SaiBClockSelection == RCC_SAIBCLKSOURCE_PLLR) 01363 { 01364 /* Check for PLL/DIVR parameters */ 01365 assert_param(IS_RCC_PLL_DIVR_VALUE(PeriphClkInit->PLLDivR)); 01366 01367 /* SAI_CLK_x = SAI_CLK(first level)/PLLDIVR */ 01368 __HAL_RCC_PLL_PLLSAICLKDIVR_CONFIG(PeriphClkInit->PLLDivR); 01369 } 01370 } 01371 /*--------------------------------------------------------------------------*/ 01372 #endif /* STM32F413xx || STM32F423xx */ 01373 01374 /*------------------------------------ RTC configuration -------------------*/ 01375 if(((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_RTC) == (RCC_PERIPHCLK_RTC)) 01376 { 01377 /* Check for RTC Parameters used to output RTCCLK */ 01378 assert_param(IS_RCC_RTCCLKSOURCE(PeriphClkInit->RTCClockSelection)); 01379 01380 /* Enable Power Clock*/ 01381 __HAL_RCC_PWR_CLK_ENABLE(); 01382 01383 /* Enable write access to Backup domain */ 01384 PWR->CR |= PWR_CR_DBP; 01385 01386 /* Get tick */ 01387 tickstart = HAL_GetTick(); 01388 01389 while((PWR->CR & PWR_CR_DBP) == RESET) 01390 { 01391 if((HAL_GetTick() - tickstart ) > RCC_DBP_TIMEOUT_VALUE) 01392 { 01393 return HAL_TIMEOUT; 01394 } 01395 } 01396 /* Reset the Backup domain only if the RTC Clock source selection is modified from reset value */ 01397 tmpreg1 = (RCC->BDCR & RCC_BDCR_RTCSEL); 01398 if((tmpreg1 != 0x00000000U) && ((tmpreg1) != (PeriphClkInit->RTCClockSelection & RCC_BDCR_RTCSEL))) 01399 { 01400 /* Store the content of BDCR register before the reset of Backup Domain */ 01401 tmpreg1 = (RCC->BDCR & ~(RCC_BDCR_RTCSEL)); 01402 /* RTC Clock selection can be changed only if the Backup Domain is reset */ 01403 __HAL_RCC_BACKUPRESET_FORCE(); 01404 __HAL_RCC_BACKUPRESET_RELEASE(); 01405 /* Restore the Content of BDCR register */ 01406 RCC->BDCR = tmpreg1; 01407 01408 /* Wait for LSE reactivation if LSE was enable prior to Backup Domain reset */ 01409 if(HAL_IS_BIT_SET(RCC->BDCR, RCC_BDCR_LSEON)) 01410 { 01411 /* Get tick */ 01412 tickstart = HAL_GetTick(); 01413 01414 /* Wait till LSE is ready */ 01415 while(__HAL_RCC_GET_FLAG(RCC_FLAG_LSERDY) == RESET) 01416 { 01417 if((HAL_GetTick() - tickstart ) > RCC_LSE_TIMEOUT_VALUE) 01418 { 01419 return HAL_TIMEOUT; 01420 } 01421 } 01422 } 01423 } 01424 __HAL_RCC_RTC_CONFIG(PeriphClkInit->RTCClockSelection); 01425 } 01426 /*--------------------------------------------------------------------------*/ 01427 01428 /*------------------------------------ TIM configuration -------------------*/ 01429 if(((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_TIM) == (RCC_PERIPHCLK_TIM)) 01430 { 01431 /* Configure Timer Prescaler */ 01432 __HAL_RCC_TIMCLKPRESCALER(PeriphClkInit->TIMPresSelection); 01433 } 01434 /*--------------------------------------------------------------------------*/ 01435 01436 /*------------------------------------- FMPI2C1 Configuration --------------*/ 01437 if(((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_FMPI2C1) == RCC_PERIPHCLK_FMPI2C1) 01438 { 01439 /* Check the parameters */ 01440 assert_param(IS_RCC_FMPI2C1CLKSOURCE(PeriphClkInit->Fmpi2c1ClockSelection)); 01441 01442 /* Configure the FMPI2C1 clock source */ 01443 __HAL_RCC_FMPI2C1_CONFIG(PeriphClkInit->Fmpi2c1ClockSelection); 01444 } 01445 /*--------------------------------------------------------------------------*/ 01446 01447 /*------------------------------------- CLK48 Configuration ----------------*/ 01448 if(((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_CLK48) == RCC_PERIPHCLK_CLK48) 01449 { 01450 /* Check the parameters */ 01451 assert_param(IS_RCC_CLK48CLKSOURCE(PeriphClkInit->Clk48ClockSelection)); 01452 01453 /* Configure the SDIO clock source */ 01454 __HAL_RCC_CLK48_CONFIG(PeriphClkInit->Clk48ClockSelection); 01455 01456 /* Enable the PLLI2S when it's used as clock source for CLK48 */ 01457 if(PeriphClkInit->Clk48ClockSelection == RCC_CLK48CLKSOURCE_PLLI2SQ) 01458 { 01459 plli2sused = 1U; 01460 } 01461 } 01462 /*--------------------------------------------------------------------------*/ 01463 01464 /*------------------------------------- SDIO Configuration -----------------*/ 01465 if(((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_SDIO) == RCC_PERIPHCLK_SDIO) 01466 { 01467 /* Check the parameters */ 01468 assert_param(IS_RCC_SDIOCLKSOURCE(PeriphClkInit->SdioClockSelection)); 01469 01470 /* Configure the SDIO clock source */ 01471 __HAL_RCC_SDIO_CONFIG(PeriphClkInit->SdioClockSelection); 01472 } 01473 /*--------------------------------------------------------------------------*/ 01474 01475 /*-------------------------------------- PLLI2S Configuration --------------*/ 01476 /* PLLI2S is configured when a peripheral will use it as source clock : I2S on APB1 or 01477 I2S on APB2*/ 01478 if((plli2sused == 1U) || (PeriphClkInit->PeriphClockSelection == RCC_PERIPHCLK_PLLI2S)) 01479 { 01480 /* Disable the PLLI2S */ 01481 __HAL_RCC_PLLI2S_DISABLE(); 01482 /* Get tick */ 01483 tickstart = HAL_GetTick(); 01484 /* Wait till PLLI2S is disabled */ 01485 while(__HAL_RCC_GET_FLAG(RCC_FLAG_PLLI2SRDY) != RESET) 01486 { 01487 if((HAL_GetTick() - tickstart ) > PLLI2S_TIMEOUT_VALUE) 01488 { 01489 /* return in case of Timeout detected */ 01490 return HAL_TIMEOUT; 01491 } 01492 } 01493 01494 /* check for common PLLI2S Parameters */ 01495 assert_param(IS_RCC_PLLI2SCLKSOURCE(PeriphClkInit->PLLI2SSelection)); 01496 assert_param(IS_RCC_PLLI2SM_VALUE(PeriphClkInit->PLLI2S.PLLI2SM)); 01497 assert_param(IS_RCC_PLLI2SN_VALUE(PeriphClkInit->PLLI2S.PLLI2SN)); 01498 /*-------------------- Set the PLL I2S clock -----------------------------*/ 01499 __HAL_RCC_PLL_I2S_CONFIG(PeriphClkInit->PLLI2SSelection); 01500 01501 /*------- In Case of PLLI2S is selected as source clock for I2S ----------*/ 01502 if(((((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_I2S_APB1) == RCC_PERIPHCLK_I2S_APB1) && (PeriphClkInit->I2sApb1ClockSelection == RCC_I2SAPB1CLKSOURCE_PLLI2S)) || 01503 ((((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_I2S_APB2) == RCC_PERIPHCLK_I2S_APB2) && (PeriphClkInit->I2sApb2ClockSelection == RCC_I2SAPB2CLKSOURCE_PLLI2S)) || 01504 ((((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_CLK48) == RCC_PERIPHCLK_CLK48) && (PeriphClkInit->Clk48ClockSelection == RCC_CLK48CLKSOURCE_PLLI2SQ)) || 01505 ((((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_SDIO) == RCC_PERIPHCLK_SDIO) && (PeriphClkInit->SdioClockSelection == RCC_SDIOCLKSOURCE_CLK48) && (PeriphClkInit->Clk48ClockSelection == RCC_CLK48CLKSOURCE_PLLI2SQ))) 01506 { 01507 /* check for Parameters */ 01508 assert_param(IS_RCC_PLLI2SR_VALUE(PeriphClkInit->PLLI2S.PLLI2SR)); 01509 assert_param(IS_RCC_PLLI2SQ_VALUE(PeriphClkInit->PLLI2S.PLLI2SQ)); 01510 01511 /* Configure the PLLI2S division factors */ 01512 /* PLLI2S_VCO = f(VCO clock) = f(PLLI2S clock input) * (PLLI2SN/PLLI2SM)*/ 01513 /* I2SCLK = f(PLLI2S clock output) = f(VCO clock) / PLLI2SR */ 01514 __HAL_RCC_PLLI2S_CONFIG(PeriphClkInit->PLLI2S.PLLI2SM, PeriphClkInit->PLLI2S.PLLI2SN , PeriphClkInit->PLLI2S.PLLI2SQ, PeriphClkInit->PLLI2S.PLLI2SR); 01515 } 01516 01517 #if defined(STM32F413xx) || defined(STM32F423xx) 01518 /*------- In Case of PLLI2S is selected as source clock for SAI ----------*/ 01519 if(((((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_SAIA) == RCC_PERIPHCLK_SAIA) && (PeriphClkInit->SaiAClockSelection == RCC_SAIACLKSOURCE_PLLI2SR)) || 01520 ((((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_SAIB) == RCC_PERIPHCLK_SAIB) && (PeriphClkInit->SaiBClockSelection == RCC_SAIBCLKSOURCE_PLLI2SR))) 01521 { 01522 /* Check for PLLI2S Parameters */ 01523 assert_param(IS_RCC_PLLI2SR_VALUE(PeriphClkInit->PLLI2S.PLLI2SR)); 01524 /* Check for PLLI2S/DIVR parameters */ 01525 assert_param(IS_RCC_PLLI2S_DIVR_VALUE(PeriphClkInit->PLLI2SDivR)); 01526 01527 /* Read PLLI2SQ value from PLLI2SCFGR register (this value is not needed for SAI configuration) */ 01528 plli2sq = ((RCC->PLLI2SCFGR & RCC_PLLI2SCFGR_PLLI2SQ) >> RCC_PLLI2SCFGR_PLLI2SQ_Pos); 01529 /* Configure the PLLI2S division factors */ 01530 /* PLLI2S_VCO Input = PLL_SOURCE/PLLI2SM */ 01531 /* PLLI2S_VCO Output = PLLI2S_VCO Input * PLLI2SN */ 01532 /* SAI_CLK(first level) = PLLI2S_VCO Output/PLLI2SQ */ 01533 __HAL_RCC_PLLI2S_CONFIG(PeriphClkInit->PLLI2S.PLLI2SM, PeriphClkInit->PLLI2S.PLLI2SN, plli2sq, PeriphClkInit->PLLI2S.PLLI2SR); 01534 01535 /* SAI_CLK_x = SAI_CLK(first level)/PLLI2SDIVR */ 01536 __HAL_RCC_PLLI2S_PLLSAICLKDIVR_CONFIG(PeriphClkInit->PLLI2SDivR); 01537 } 01538 #endif /* STM32F413xx || STM32F423xx */ 01539 01540 /*----------------- In Case of PLLI2S is just selected ------------------*/ 01541 if((PeriphClkInit->PeriphClockSelection & RCC_PERIPHCLK_PLLI2S) == RCC_PERIPHCLK_PLLI2S) 01542 { 01543 /* Check for Parameters */ 01544 assert_param(IS_RCC_PLLI2SR_VALUE(PeriphClkInit->PLLI2S.PLLI2SR)); 01545 assert_param(IS_RCC_PLLI2SQ_VALUE(PeriphClkInit->PLLI2S.PLLI2SQ)); 01546 01547 /* Configure the PLLI2S division factors */ 01548 /* PLLI2S_VCO = f(VCO clock) = f(PLLI2S clock input) * (PLLI2SN/PLLI2SM)*/ 01549 /* SPDIFRXCLK = f(PLLI2S clock output) = f(VCO clock) / PLLI2SP */ 01550 __HAL_RCC_PLLI2S_CONFIG(PeriphClkInit->PLLI2S.PLLI2SM, PeriphClkInit->PLLI2S.PLLI2SN , PeriphClkInit->PLLI2S.PLLI2SQ, PeriphClkInit->PLLI2S.PLLI2SR); 01551 } 01552 01553 /* Enable the PLLI2S */ 01554 __HAL_RCC_PLLI2S_ENABLE(); 01555 /* Get tick */ 01556 tickstart = HAL_GetTick(); 01557 /* Wait till PLLI2S is ready */ 01558 while(__HAL_RCC_GET_FLAG(RCC_FLAG_PLLI2SRDY) == RESET) 01559 { 01560 if((HAL_GetTick() - tickstart ) > PLLI2S_TIMEOUT_VALUE) 01561 { 01562 /* return in case of Timeout detected */ 01563 return HAL_TIMEOUT; 01564 } 01565 } 01566 } 01567 /*--------------------------------------------------------------------------*/ 01568 01569 /*-------------------- DFSDM1 clock source configuration -------------------*/ 01570 if(((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_DFSDM1) == RCC_PERIPHCLK_DFSDM1) 01571 { 01572 /* Check the parameters */ 01573 assert_param(IS_RCC_DFSDM1CLKSOURCE(PeriphClkInit->Dfsdm1ClockSelection)); 01574 01575 /* Configure the DFSDM1 interface clock source */ 01576 __HAL_RCC_DFSDM1_CONFIG(PeriphClkInit->Dfsdm1ClockSelection); 01577 } 01578 /*--------------------------------------------------------------------------*/ 01579 01580 /*-------------------- DFSDM1 Audio clock source configuration -------------*/ 01581 if(((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_DFSDM1_AUDIO) == RCC_PERIPHCLK_DFSDM1_AUDIO) 01582 { 01583 /* Check the parameters */ 01584 assert_param(IS_RCC_DFSDM1AUDIOCLKSOURCE(PeriphClkInit->Dfsdm1AudioClockSelection)); 01585 01586 /* Configure the DFSDM1 Audio interface clock source */ 01587 __HAL_RCC_DFSDM1AUDIO_CONFIG(PeriphClkInit->Dfsdm1AudioClockSelection); 01588 } 01589 /*--------------------------------------------------------------------------*/ 01590 01591 #if defined(STM32F413xx) || defined(STM32F423xx) 01592 /*-------------------- DFSDM2 clock source configuration -------------------*/ 01593 if(((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_DFSDM2) == RCC_PERIPHCLK_DFSDM2) 01594 { 01595 /* Check the parameters */ 01596 assert_param(IS_RCC_DFSDM2CLKSOURCE(PeriphClkInit->Dfsdm2ClockSelection)); 01597 01598 /* Configure the DFSDM1 interface clock source */ 01599 __HAL_RCC_DFSDM2_CONFIG(PeriphClkInit->Dfsdm2ClockSelection); 01600 } 01601 /*--------------------------------------------------------------------------*/ 01602 01603 /*-------------------- DFSDM2 Audio clock source configuration -------------*/ 01604 if(((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_DFSDM2_AUDIO) == RCC_PERIPHCLK_DFSDM2_AUDIO) 01605 { 01606 /* Check the parameters */ 01607 assert_param(IS_RCC_DFSDM2AUDIOCLKSOURCE(PeriphClkInit->Dfsdm2AudioClockSelection)); 01608 01609 /* Configure the DFSDM1 Audio interface clock source */ 01610 __HAL_RCC_DFSDM2AUDIO_CONFIG(PeriphClkInit->Dfsdm2AudioClockSelection); 01611 } 01612 /*--------------------------------------------------------------------------*/ 01613 01614 /*---------------------------- LPTIM1 Configuration ------------------------*/ 01615 if(((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_LPTIM1) == RCC_PERIPHCLK_LPTIM1) 01616 { 01617 /* Check the parameters */ 01618 assert_param(IS_RCC_LPTIM1CLKSOURCE(PeriphClkInit->Lptim1ClockSelection)); 01619 01620 /* Configure the LPTIM1 clock source */ 01621 __HAL_RCC_LPTIM1_CONFIG(PeriphClkInit->Lptim1ClockSelection); 01622 } 01623 /*--------------------------------------------------------------------------*/ 01624 #endif /* STM32F413xx || STM32F423xx */ 01625 01626 return HAL_OK; 01627 } 01628 01629 /** 01630 * @brief Get the RCC_PeriphCLKInitTypeDef according to the internal 01631 * RCC configuration registers. 01632 * @param PeriphClkInit pointer to an RCC_PeriphCLKInitTypeDef structure that 01633 * will be configured. 01634 * @retval None 01635 */ 01636 void HAL_RCCEx_GetPeriphCLKConfig(RCC_PeriphCLKInitTypeDef *PeriphClkInit) 01637 { 01638 uint32_t tempreg; 01639 01640 /* Set all possible values for the extended clock type parameter------------*/ 01641 #if defined(STM32F413xx) || defined(STM32F423xx) 01642 PeriphClkInit->PeriphClockSelection = RCC_PERIPHCLK_I2S_APB1 | RCC_PERIPHCLK_I2S_APB2 |\ 01643 RCC_PERIPHCLK_TIM | RCC_PERIPHCLK_RTC |\ 01644 RCC_PERIPHCLK_FMPI2C1 | RCC_PERIPHCLK_CLK48 |\ 01645 RCC_PERIPHCLK_SDIO | RCC_PERIPHCLK_DFSDM1 |\ 01646 RCC_PERIPHCLK_DFSDM1_AUDIO | RCC_PERIPHCLK_DFSDM2 |\ 01647 RCC_PERIPHCLK_DFSDM2_AUDIO | RCC_PERIPHCLK_LPTIM1 |\ 01648 RCC_PERIPHCLK_SAIA | RCC_PERIPHCLK_SAIB; 01649 #else /* STM32F412Zx || STM32F412Vx || STM32F412Rx || STM32F412Cx */ 01650 PeriphClkInit->PeriphClockSelection = RCC_PERIPHCLK_I2S_APB1 | RCC_PERIPHCLK_I2S_APB2 |\ 01651 RCC_PERIPHCLK_TIM | RCC_PERIPHCLK_RTC |\ 01652 RCC_PERIPHCLK_FMPI2C1 | RCC_PERIPHCLK_CLK48 |\ 01653 RCC_PERIPHCLK_SDIO | RCC_PERIPHCLK_DFSDM1 |\ 01654 RCC_PERIPHCLK_DFSDM1_AUDIO; 01655 #endif /* STM32F413xx || STM32F423xx */ 01656 01657 01658 01659 /* Get the PLLI2S Clock configuration --------------------------------------*/ 01660 PeriphClkInit->PLLI2S.PLLI2SM = (uint32_t)((RCC->PLLI2SCFGR & RCC_PLLI2SCFGR_PLLI2SM) >> RCC_PLLI2SCFGR_PLLI2SM_Pos); 01661 PeriphClkInit->PLLI2S.PLLI2SN = (uint32_t)((RCC->PLLI2SCFGR & RCC_PLLI2SCFGR_PLLI2SN) >> RCC_PLLI2SCFGR_PLLI2SN_Pos); 01662 PeriphClkInit->PLLI2S.PLLI2SQ = (uint32_t)((RCC->PLLI2SCFGR & RCC_PLLI2SCFGR_PLLI2SQ) >> RCC_PLLI2SCFGR_PLLI2SQ_Pos); 01663 PeriphClkInit->PLLI2S.PLLI2SR = (uint32_t)((RCC->PLLI2SCFGR & RCC_PLLI2SCFGR_PLLI2SR) >> RCC_PLLI2SCFGR_PLLI2SR_Pos); 01664 #if defined(STM32F413xx) || defined(STM32F423xx) 01665 /* Get the PLL/PLLI2S division factors -------------------------------------*/ 01666 PeriphClkInit->PLLI2SDivR = (uint32_t)((RCC->DCKCFGR & RCC_DCKCFGR_PLLI2SDIVR) >> RCC_DCKCFGR_PLLI2SDIVR_Pos); 01667 PeriphClkInit->PLLDivR = (uint32_t)((RCC->DCKCFGR & RCC_DCKCFGR_PLLDIVR) >> RCC_DCKCFGR_PLLDIVR_Pos); 01668 #endif /* STM32F413xx || STM32F423xx */ 01669 01670 /* Get the I2S APB1 clock configuration ------------------------------------*/ 01671 PeriphClkInit->I2sApb1ClockSelection = __HAL_RCC_GET_I2S_APB1_SOURCE(); 01672 01673 /* Get the I2S APB2 clock configuration ------------------------------------*/ 01674 PeriphClkInit->I2sApb2ClockSelection = __HAL_RCC_GET_I2S_APB2_SOURCE(); 01675 01676 /* Get the RTC Clock configuration -----------------------------------------*/ 01677 tempreg = (RCC->CFGR & RCC_CFGR_RTCPRE); 01678 PeriphClkInit->RTCClockSelection = (uint32_t)((tempreg) | (RCC->BDCR & RCC_BDCR_RTCSEL)); 01679 01680 /* Get the FMPI2C1 clock configuration -------------------------------------*/ 01681 PeriphClkInit->Fmpi2c1ClockSelection = __HAL_RCC_GET_FMPI2C1_SOURCE(); 01682 01683 /* Get the CLK48 clock configuration ---------------------------------------*/ 01684 PeriphClkInit->Clk48ClockSelection = __HAL_RCC_GET_CLK48_SOURCE(); 01685 01686 /* Get the SDIO clock configuration ----------------------------------------*/ 01687 PeriphClkInit->SdioClockSelection = __HAL_RCC_GET_SDIO_SOURCE(); 01688 01689 /* Get the DFSDM1 clock configuration --------------------------------------*/ 01690 PeriphClkInit->Dfsdm1ClockSelection = __HAL_RCC_GET_DFSDM1_SOURCE(); 01691 01692 /* Get the DFSDM1 Audio clock configuration --------------------------------*/ 01693 PeriphClkInit->Dfsdm1AudioClockSelection = __HAL_RCC_GET_DFSDM1AUDIO_SOURCE(); 01694 01695 #if defined(STM32F413xx) || defined(STM32F423xx) 01696 /* Get the DFSDM2 clock configuration --------------------------------------*/ 01697 PeriphClkInit->Dfsdm2ClockSelection = __HAL_RCC_GET_DFSDM2_SOURCE(); 01698 01699 /* Get the DFSDM2 Audio clock configuration --------------------------------*/ 01700 PeriphClkInit->Dfsdm2AudioClockSelection = __HAL_RCC_GET_DFSDM2AUDIO_SOURCE(); 01701 01702 /* Get the LPTIM1 clock configuration --------------------------------------*/ 01703 PeriphClkInit->Lptim1ClockSelection = __HAL_RCC_GET_LPTIM1_SOURCE(); 01704 01705 /* Get the SAI1 Block Aclock configuration ---------------------------------*/ 01706 PeriphClkInit->SaiAClockSelection = __HAL_RCC_GET_SAI_BLOCKA_SOURCE(); 01707 01708 /* Get the SAI1 Block B clock configuration --------------------------------*/ 01709 PeriphClkInit->SaiBClockSelection = __HAL_RCC_GET_SAI_BLOCKB_SOURCE(); 01710 #endif /* STM32F413xx || STM32F423xx */ 01711 01712 /* Get the TIM Prescaler configuration -------------------------------------*/ 01713 if ((RCC->DCKCFGR & RCC_DCKCFGR_TIMPRE) == RESET) 01714 { 01715 PeriphClkInit->TIMPresSelection = RCC_TIMPRES_DESACTIVATED; 01716 } 01717 else 01718 { 01719 PeriphClkInit->TIMPresSelection = RCC_TIMPRES_ACTIVATED; 01720 } 01721 } 01722 01723 /** 01724 * @brief Return the peripheral clock frequency for a given peripheral(I2S..) 01725 * @note Return 0 if peripheral clock identifier not managed by this API 01726 * @param PeriphClk Peripheral clock identifier 01727 * This parameter can be one of the following values: 01728 * @arg RCC_PERIPHCLK_I2S_APB1: I2S APB1 peripheral clock 01729 * @arg RCC_PERIPHCLK_I2S_APB2: I2S APB2 peripheral clock 01730 * @retval Frequency in KHz 01731 */ 01732 uint32_t HAL_RCCEx_GetPeriphCLKFreq(uint32_t PeriphClk) 01733 { 01734 /* This variable used to store the I2S clock frequency (value in Hz) */ 01735 uint32_t frequency = 0U; 01736 /* This variable used to store the VCO Input (value in Hz) */ 01737 uint32_t vcoinput = 0U; 01738 uint32_t srcclk = 0U; 01739 /* This variable used to store the VCO Output (value in Hz) */ 01740 uint32_t vcooutput = 0U; 01741 switch (PeriphClk) 01742 { 01743 case RCC_PERIPHCLK_I2S_APB1: 01744 { 01745 /* Get the current I2S source */ 01746 srcclk = __HAL_RCC_GET_I2S_APB1_SOURCE(); 01747 switch (srcclk) 01748 { 01749 /* Check if I2S clock selection is External clock mapped on the I2S_CKIN pin used as I2S clock */ 01750 case RCC_I2SAPB1CLKSOURCE_EXT: 01751 { 01752 /* Set the I2S clock to the external clock value */ 01753 frequency = EXTERNAL_CLOCK_VALUE; 01754 break; 01755 } 01756 /* Check if I2S clock selection is PLLI2S VCO output clock divided by PLLI2SR used as I2S clock */ 01757 case RCC_I2SAPB1CLKSOURCE_PLLI2S: 01758 { 01759 if((RCC->PLLI2SCFGR & RCC_PLLI2SCFGR_PLLI2SSRC) == RCC_PLLI2SCFGR_PLLI2SSRC) 01760 { 01761 /* Get the I2S source clock value */ 01762 vcoinput = (uint32_t)(EXTERNAL_CLOCK_VALUE / (uint32_t)(RCC->PLLI2SCFGR & RCC_PLLI2SCFGR_PLLI2SM)); 01763 } 01764 else 01765 { 01766 /* Configure the PLLI2S division factor */ 01767 /* PLLI2S_VCO Input = PLL_SOURCE/PLLI2SM */ 01768 if((RCC->PLLCFGR & RCC_PLLCFGR_PLLSRC) == RCC_PLLSOURCE_HSE) 01769 { 01770 /* Get the I2S source clock value */ 01771 vcoinput = (uint32_t)(HSE_VALUE / (uint32_t)(RCC->PLLI2SCFGR & RCC_PLLI2SCFGR_PLLI2SM)); 01772 } 01773 else 01774 { 01775 /* Get the I2S source clock value */ 01776 vcoinput = (uint32_t)(HSI_VALUE / (uint32_t)(RCC->PLLI2SCFGR & RCC_PLLI2SCFGR_PLLI2SM)); 01777 } 01778 } 01779 /* PLLI2S_VCO Output = PLLI2S_VCO Input * PLLI2SN */ 01780 vcooutput = (uint32_t)(vcoinput * (((RCC->PLLI2SCFGR & RCC_PLLI2SCFGR_PLLI2SN) >> 6U) & (RCC_PLLI2SCFGR_PLLI2SN >> 6U))); 01781 /* I2S_CLK = PLLI2S_VCO Output/PLLI2SR */ 01782 frequency = (uint32_t)(vcooutput /(((RCC->PLLI2SCFGR & RCC_PLLI2SCFGR_PLLI2SR) >> 28U) & (RCC_PLLI2SCFGR_PLLI2SR >> 28U))); 01783 break; 01784 } 01785 /* Check if I2S clock selection is PLL VCO Output divided by PLLR used as I2S clock */ 01786 case RCC_I2SAPB1CLKSOURCE_PLLR: 01787 { 01788 /* Configure the PLL division factor R */ 01789 /* PLL_VCO Input = PLL_SOURCE/PLLM */ 01790 if((RCC->PLLCFGR & RCC_PLLCFGR_PLLSRC) == RCC_PLLSOURCE_HSE) 01791 { 01792 /* Get the I2S source clock value */ 01793 vcoinput = (uint32_t)(HSE_VALUE / (uint32_t)(RCC->PLLCFGR & RCC_PLLCFGR_PLLM)); 01794 } 01795 else 01796 { 01797 /* Get the I2S source clock value */ 01798 vcoinput = (uint32_t)(HSI_VALUE / (uint32_t)(RCC->PLLCFGR & RCC_PLLCFGR_PLLM)); 01799 } 01800 01801 /* PLL_VCO Output = PLL_VCO Input * PLLN */ 01802 vcooutput = (uint32_t)(vcoinput * (((RCC->PLLCFGR & RCC_PLLCFGR_PLLN) >> 6U) & (RCC_PLLCFGR_PLLN >> 6U))); 01803 /* I2S_CLK = PLL_VCO Output/PLLR */ 01804 frequency = (uint32_t)(vcooutput /(((RCC->PLLCFGR & RCC_PLLCFGR_PLLR) >> 28U) & (RCC_PLLCFGR_PLLR >> 28U))); 01805 break; 01806 } 01807 /* Check if I2S clock selection is HSI or HSE depending from PLL source Clock */ 01808 case RCC_I2SAPB1CLKSOURCE_PLLSRC: 01809 { 01810 if((RCC->PLLCFGR & RCC_PLLCFGR_PLLSRC) == RCC_PLLSOURCE_HSE) 01811 { 01812 frequency = HSE_VALUE; 01813 } 01814 else 01815 { 01816 frequency = HSI_VALUE; 01817 } 01818 break; 01819 } 01820 /* Clock not enabled for I2S*/ 01821 default: 01822 { 01823 frequency = 0U; 01824 break; 01825 } 01826 } 01827 break; 01828 } 01829 case RCC_PERIPHCLK_I2S_APB2: 01830 { 01831 /* Get the current I2S source */ 01832 srcclk = __HAL_RCC_GET_I2S_APB2_SOURCE(); 01833 switch (srcclk) 01834 { 01835 /* Check if I2S clock selection is External clock mapped on the I2S_CKIN pin used as I2S clock */ 01836 case RCC_I2SAPB2CLKSOURCE_EXT: 01837 { 01838 /* Set the I2S clock to the external clock value */ 01839 frequency = EXTERNAL_CLOCK_VALUE; 01840 break; 01841 } 01842 /* Check if I2S clock selection is PLLI2S VCO output clock divided by PLLI2SR used as I2S clock */ 01843 case RCC_I2SAPB2CLKSOURCE_PLLI2S: 01844 { 01845 if((RCC->PLLI2SCFGR & RCC_PLLI2SCFGR_PLLI2SSRC) == RCC_PLLI2SCFGR_PLLI2SSRC) 01846 { 01847 /* Get the I2S source clock value */ 01848 vcoinput = (uint32_t)(EXTERNAL_CLOCK_VALUE / (uint32_t)(RCC->PLLI2SCFGR & RCC_PLLI2SCFGR_PLLI2SM)); 01849 } 01850 else 01851 { 01852 /* Configure the PLLI2S division factor */ 01853 /* PLLI2S_VCO Input = PLL_SOURCE/PLLI2SM */ 01854 if((RCC->PLLCFGR & RCC_PLLCFGR_PLLSRC) == RCC_PLLSOURCE_HSE) 01855 { 01856 /* Get the I2S source clock value */ 01857 vcoinput = (uint32_t)(HSE_VALUE / (uint32_t)(RCC->PLLI2SCFGR & RCC_PLLI2SCFGR_PLLI2SM)); 01858 } 01859 else 01860 { 01861 /* Get the I2S source clock value */ 01862 vcoinput = (uint32_t)(HSI_VALUE / (uint32_t)(RCC->PLLI2SCFGR & RCC_PLLI2SCFGR_PLLI2SM)); 01863 } 01864 } 01865 /* PLLI2S_VCO Output = PLLI2S_VCO Input * PLLI2SN */ 01866 vcooutput = (uint32_t)(vcoinput * (((RCC->PLLI2SCFGR & RCC_PLLI2SCFGR_PLLI2SN) >> 6U) & (RCC_PLLI2SCFGR_PLLI2SN >> 6U))); 01867 /* I2S_CLK = PLLI2S_VCO Output/PLLI2SR */ 01868 frequency = (uint32_t)(vcooutput /(((RCC->PLLI2SCFGR & RCC_PLLI2SCFGR_PLLI2SR) >> 28U) & (RCC_PLLI2SCFGR_PLLI2SR >> 28U))); 01869 break; 01870 } 01871 /* Check if I2S clock selection is PLL VCO Output divided by PLLR used as I2S clock */ 01872 case RCC_I2SAPB2CLKSOURCE_PLLR: 01873 { 01874 /* Configure the PLL division factor R */ 01875 /* PLL_VCO Input = PLL_SOURCE/PLLM */ 01876 if((RCC->PLLCFGR & RCC_PLLCFGR_PLLSRC) == RCC_PLLSOURCE_HSE) 01877 { 01878 /* Get the I2S source clock value */ 01879 vcoinput = (uint32_t)(HSE_VALUE / (uint32_t)(RCC->PLLCFGR & RCC_PLLCFGR_PLLM)); 01880 } 01881 else 01882 { 01883 /* Get the I2S source clock value */ 01884 vcoinput = (uint32_t)(HSI_VALUE / (uint32_t)(RCC->PLLCFGR & RCC_PLLCFGR_PLLM)); 01885 } 01886 01887 /* PLL_VCO Output = PLL_VCO Input * PLLN */ 01888 vcooutput = (uint32_t)(vcoinput * (((RCC->PLLCFGR & RCC_PLLCFGR_PLLN) >> 6U) & (RCC_PLLCFGR_PLLN >> 6U))); 01889 /* I2S_CLK = PLL_VCO Output/PLLR */ 01890 frequency = (uint32_t)(vcooutput /(((RCC->PLLCFGR & RCC_PLLCFGR_PLLR) >> 28U) & (RCC_PLLCFGR_PLLR >> 28U))); 01891 break; 01892 } 01893 /* Check if I2S clock selection is HSI or HSE depending from PLL source Clock */ 01894 case RCC_I2SAPB2CLKSOURCE_PLLSRC: 01895 { 01896 if((RCC->PLLCFGR & RCC_PLLCFGR_PLLSRC) == RCC_PLLSOURCE_HSE) 01897 { 01898 frequency = HSE_VALUE; 01899 } 01900 else 01901 { 01902 frequency = HSI_VALUE; 01903 } 01904 break; 01905 } 01906 /* Clock not enabled for I2S*/ 01907 default: 01908 { 01909 frequency = 0U; 01910 break; 01911 } 01912 } 01913 break; 01914 } 01915 } 01916 return frequency; 01917 } 01918 #endif /* STM32F412Zx || STM32F412Vx || STM32F412Rx || STM32F412Cx || STM32F413xx || STM32F423xx */ 01919 01920 #if defined(STM32F410Tx) || defined(STM32F410Cx) || defined(STM32F410Rx) 01921 /** 01922 * @brief Initializes the RCC extended peripherals clocks according to the specified parameters in the 01923 * RCC_PeriphCLKInitTypeDef. 01924 * @param PeriphClkInit pointer to an RCC_PeriphCLKInitTypeDef structure that 01925 * contains the configuration information for the Extended Peripherals clocks(I2S and RTC clocks). 01926 * 01927 * @note A caution to be taken when HAL_RCCEx_PeriphCLKConfig() is used to select RTC clock selection, in this case 01928 * the Reset of Backup domain will be applied in order to modify the RTC Clock source as consequence all backup 01929 * domain (RTC and RCC_BDCR register expect BKPSRAM) will be reset 01930 * 01931 * @retval HAL status 01932 */ 01933 HAL_StatusTypeDef HAL_RCCEx_PeriphCLKConfig(RCC_PeriphCLKInitTypeDef *PeriphClkInit) 01934 { 01935 uint32_t tickstart = 0U; 01936 uint32_t tmpreg1 = 0U; 01937 01938 /* Check the parameters */ 01939 assert_param(IS_RCC_PERIPHCLOCK(PeriphClkInit->PeriphClockSelection)); 01940 01941 /*---------------------------- RTC configuration ---------------------------*/ 01942 if(((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_RTC) == (RCC_PERIPHCLK_RTC)) 01943 { 01944 /* Check for RTC Parameters used to output RTCCLK */ 01945 assert_param(IS_RCC_RTCCLKSOURCE(PeriphClkInit->RTCClockSelection)); 01946 01947 /* Enable Power Clock*/ 01948 __HAL_RCC_PWR_CLK_ENABLE(); 01949 01950 /* Enable write access to Backup domain */ 01951 PWR->CR |= PWR_CR_DBP; 01952 01953 /* Get tick */ 01954 tickstart = HAL_GetTick(); 01955 01956 while((PWR->CR & PWR_CR_DBP) == RESET) 01957 { 01958 if((HAL_GetTick() - tickstart ) > RCC_DBP_TIMEOUT_VALUE) 01959 { 01960 return HAL_TIMEOUT; 01961 } 01962 } 01963 /* Reset the Backup domain only if the RTC Clock source selection is modified from reset value */ 01964 tmpreg1 = (RCC->BDCR & RCC_BDCR_RTCSEL); 01965 if((tmpreg1 != 0x00000000U) && ((tmpreg1) != (PeriphClkInit->RTCClockSelection & RCC_BDCR_RTCSEL))) 01966 { 01967 /* Store the content of BDCR register before the reset of Backup Domain */ 01968 tmpreg1 = (RCC->BDCR & ~(RCC_BDCR_RTCSEL)); 01969 /* RTC Clock selection can be changed only if the Backup Domain is reset */ 01970 __HAL_RCC_BACKUPRESET_FORCE(); 01971 __HAL_RCC_BACKUPRESET_RELEASE(); 01972 /* Restore the Content of BDCR register */ 01973 RCC->BDCR = tmpreg1; 01974 01975 /* Wait for LSE reactivation if LSE was enable prior to Backup Domain reset */ 01976 if(HAL_IS_BIT_SET(RCC->BDCR, RCC_BDCR_LSEON)) 01977 { 01978 /* Get tick */ 01979 tickstart = HAL_GetTick(); 01980 01981 /* Wait till LSE is ready */ 01982 while(__HAL_RCC_GET_FLAG(RCC_FLAG_LSERDY) == RESET) 01983 { 01984 if((HAL_GetTick() - tickstart ) > RCC_LSE_TIMEOUT_VALUE) 01985 { 01986 return HAL_TIMEOUT; 01987 } 01988 } 01989 } 01990 } 01991 __HAL_RCC_RTC_CONFIG(PeriphClkInit->RTCClockSelection); 01992 } 01993 /*--------------------------------------------------------------------------*/ 01994 01995 /*---------------------------- TIM configuration ---------------------------*/ 01996 if(((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_TIM) == (RCC_PERIPHCLK_TIM)) 01997 { 01998 __HAL_RCC_TIMCLKPRESCALER(PeriphClkInit->TIMPresSelection); 01999 } 02000 /*--------------------------------------------------------------------------*/ 02001 02002 /*---------------------------- FMPI2C1 Configuration -----------------------*/ 02003 if(((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_FMPI2C1) == RCC_PERIPHCLK_FMPI2C1) 02004 { 02005 /* Check the parameters */ 02006 assert_param(IS_RCC_FMPI2C1CLKSOURCE(PeriphClkInit->Fmpi2c1ClockSelection)); 02007 02008 /* Configure the FMPI2C1 clock source */ 02009 __HAL_RCC_FMPI2C1_CONFIG(PeriphClkInit->Fmpi2c1ClockSelection); 02010 } 02011 /*--------------------------------------------------------------------------*/ 02012 02013 /*---------------------------- LPTIM1 Configuration ------------------------*/ 02014 if(((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_LPTIM1) == RCC_PERIPHCLK_LPTIM1) 02015 { 02016 /* Check the parameters */ 02017 assert_param(IS_RCC_LPTIM1CLKSOURCE(PeriphClkInit->Lptim1ClockSelection)); 02018 02019 /* Configure the LPTIM1 clock source */ 02020 __HAL_RCC_LPTIM1_CONFIG(PeriphClkInit->Lptim1ClockSelection); 02021 } 02022 02023 /*---------------------------- I2S Configuration ---------------------------*/ 02024 if(((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_I2S) == RCC_PERIPHCLK_I2S) 02025 { 02026 /* Check the parameters */ 02027 assert_param(IS_RCC_I2SAPBCLKSOURCE(PeriphClkInit->I2SClockSelection)); 02028 02029 /* Configure the I2S clock source */ 02030 __HAL_RCC_I2S_CONFIG(PeriphClkInit->I2SClockSelection); 02031 } 02032 02033 return HAL_OK; 02034 } 02035 02036 /** 02037 * @brief Configures the RCC_OscInitStruct according to the internal 02038 * RCC configuration registers. 02039 * @param PeriphClkInit pointer to an RCC_PeriphCLKInitTypeDef structure that 02040 * will be configured. 02041 * @retval None 02042 */ 02043 void HAL_RCCEx_GetPeriphCLKConfig(RCC_PeriphCLKInitTypeDef *PeriphClkInit) 02044 { 02045 uint32_t tempreg; 02046 02047 /* Set all possible values for the extended clock type parameter------------*/ 02048 PeriphClkInit->PeriphClockSelection = RCC_PERIPHCLK_FMPI2C1 | RCC_PERIPHCLK_LPTIM1 | RCC_PERIPHCLK_TIM | RCC_PERIPHCLK_RTC; 02049 02050 tempreg = (RCC->CFGR & RCC_CFGR_RTCPRE); 02051 PeriphClkInit->RTCClockSelection = (uint32_t)((tempreg) | (RCC->BDCR & RCC_BDCR_RTCSEL)); 02052 02053 if ((RCC->DCKCFGR & RCC_DCKCFGR_TIMPRE) == RESET) 02054 { 02055 PeriphClkInit->TIMPresSelection = RCC_TIMPRES_DESACTIVATED; 02056 } 02057 else 02058 { 02059 PeriphClkInit->TIMPresSelection = RCC_TIMPRES_ACTIVATED; 02060 } 02061 /* Get the FMPI2C1 clock configuration -------------------------------------*/ 02062 PeriphClkInit->Fmpi2c1ClockSelection = __HAL_RCC_GET_FMPI2C1_SOURCE(); 02063 02064 /* Get the I2S clock configuration -----------------------------------------*/ 02065 PeriphClkInit->I2SClockSelection = __HAL_RCC_GET_I2S_SOURCE(); 02066 02067 02068 } 02069 /** 02070 * @brief Return the peripheral clock frequency for a given peripheral(SAI..) 02071 * @note Return 0 if peripheral clock identifier not managed by this API 02072 * @param PeriphClk Peripheral clock identifier 02073 * This parameter can be one of the following values: 02074 * @arg RCC_PERIPHCLK_I2S: I2S peripheral clock 02075 * @retval Frequency in KHz 02076 */ 02077 uint32_t HAL_RCCEx_GetPeriphCLKFreq(uint32_t PeriphClk) 02078 { 02079 /* This variable used to store the I2S clock frequency (value in Hz) */ 02080 uint32_t frequency = 0U; 02081 /* This variable used to store the VCO Input (value in Hz) */ 02082 uint32_t vcoinput = 0U; 02083 uint32_t srcclk = 0U; 02084 /* This variable used to store the VCO Output (value in Hz) */ 02085 uint32_t vcooutput = 0U; 02086 switch (PeriphClk) 02087 { 02088 case RCC_PERIPHCLK_I2S: 02089 { 02090 /* Get the current I2S source */ 02091 srcclk = __HAL_RCC_GET_I2S_SOURCE(); 02092 switch (srcclk) 02093 { 02094 /* Check if I2S clock selection is External clock mapped on the I2S_CKIN pin used as I2S clock */ 02095 case RCC_I2SAPBCLKSOURCE_EXT: 02096 { 02097 /* Set the I2S clock to the external clock value */ 02098 frequency = EXTERNAL_CLOCK_VALUE; 02099 break; 02100 } 02101 /* Check if I2S clock selection is PLL VCO Output divided by PLLR used as I2S clock */ 02102 case RCC_I2SAPBCLKSOURCE_PLLR: 02103 { 02104 /* Configure the PLL division factor R */ 02105 /* PLL_VCO Input = PLL_SOURCE/PLLM */ 02106 if((RCC->PLLCFGR & RCC_PLLCFGR_PLLSRC) == RCC_PLLSOURCE_HSE) 02107 { 02108 /* Get the I2S source clock value */ 02109 vcoinput = (uint32_t)(HSE_VALUE / (uint32_t)(RCC->PLLCFGR & RCC_PLLCFGR_PLLM)); 02110 } 02111 else 02112 { 02113 /* Get the I2S source clock value */ 02114 vcoinput = (uint32_t)(HSI_VALUE / (uint32_t)(RCC->PLLCFGR & RCC_PLLCFGR_PLLM)); 02115 } 02116 02117 /* PLL_VCO Output = PLL_VCO Input * PLLN */ 02118 vcooutput = (uint32_t)(vcoinput * (((RCC->PLLCFGR & RCC_PLLCFGR_PLLN) >> 6U) & (RCC_PLLCFGR_PLLN >> 6U))); 02119 /* I2S_CLK = PLL_VCO Output/PLLR */ 02120 frequency = (uint32_t)(vcooutput /(((RCC->PLLCFGR & RCC_PLLCFGR_PLLR) >> 28U) & (RCC_PLLCFGR_PLLR >> 28U))); 02121 break; 02122 } 02123 /* Check if I2S clock selection is HSI or HSE depending from PLL source Clock */ 02124 case RCC_I2SAPBCLKSOURCE_PLLSRC: 02125 { 02126 if((RCC->PLLCFGR & RCC_PLLCFGR_PLLSRC) == RCC_PLLSOURCE_HSE) 02127 { 02128 frequency = HSE_VALUE; 02129 } 02130 else 02131 { 02132 frequency = HSI_VALUE; 02133 } 02134 break; 02135 } 02136 /* Clock not enabled for I2S*/ 02137 default: 02138 { 02139 frequency = 0U; 02140 break; 02141 } 02142 } 02143 break; 02144 } 02145 } 02146 return frequency; 02147 } 02148 #endif /* STM32F410Tx || STM32F410Cx || STM32F410Rx */ 02149 02150 #if defined(STM32F427xx) || defined(STM32F437xx) || defined(STM32F429xx) || defined(STM32F439xx) 02151 /** 02152 * @brief Initializes the RCC extended peripherals clocks according to the specified 02153 * parameters in the RCC_PeriphCLKInitTypeDef. 02154 * @param PeriphClkInit pointer to an RCC_PeriphCLKInitTypeDef structure that 02155 * contains the configuration information for the Extended Peripherals 02156 * clocks(I2S, SAI, LTDC RTC and TIM). 02157 * 02158 * @note Care must be taken when HAL_RCCEx_PeriphCLKConfig() is used to select 02159 * the RTC clock source; in this case the Backup domain will be reset in 02160 * order to modify the RTC Clock source, as consequence RTC registers (including 02161 * the backup registers) and RCC_BDCR register are set to their reset values. 02162 * 02163 * @retval HAL status 02164 */ 02165 HAL_StatusTypeDef HAL_RCCEx_PeriphCLKConfig(RCC_PeriphCLKInitTypeDef *PeriphClkInit) 02166 { 02167 uint32_t tickstart = 0U; 02168 uint32_t tmpreg1 = 0U; 02169 02170 /* Check the parameters */ 02171 assert_param(IS_RCC_PERIPHCLOCK(PeriphClkInit->PeriphClockSelection)); 02172 02173 /*----------------------- SAI/I2S Configuration (PLLI2S) -------------------*/ 02174 /*----------------------- Common configuration SAI/I2S ---------------------*/ 02175 /* In Case of SAI or I2S Clock Configuration through PLLI2S, PLLI2SN division 02176 factor is common parameters for both peripherals */ 02177 if((((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_I2S) == RCC_PERIPHCLK_I2S) || 02178 (((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_SAI_PLLI2S) == RCC_PERIPHCLK_SAI_PLLI2S) || 02179 (((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_PLLI2S) == RCC_PERIPHCLK_PLLI2S)) 02180 { 02181 /* check for Parameters */ 02182 assert_param(IS_RCC_PLLI2SN_VALUE(PeriphClkInit->PLLI2S.PLLI2SN)); 02183 02184 /* Disable the PLLI2S */ 02185 __HAL_RCC_PLLI2S_DISABLE(); 02186 /* Get tick */ 02187 tickstart = HAL_GetTick(); 02188 /* Wait till PLLI2S is disabled */ 02189 while(__HAL_RCC_GET_FLAG(RCC_FLAG_PLLI2SRDY) != RESET) 02190 { 02191 if((HAL_GetTick() - tickstart ) > PLLI2S_TIMEOUT_VALUE) 02192 { 02193 /* return in case of Timeout detected */ 02194 return HAL_TIMEOUT; 02195 } 02196 } 02197 02198 /*---------------------------- I2S configuration -------------------------*/ 02199 /* In Case of I2S Clock Configuration through PLLI2S, PLLI2SR must be added 02200 only for I2S configuration */ 02201 if(((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_I2S) == (RCC_PERIPHCLK_I2S)) 02202 { 02203 /* check for Parameters */ 02204 assert_param(IS_RCC_PLLI2SR_VALUE(PeriphClkInit->PLLI2S.PLLI2SR)); 02205 /* Configure the PLLI2S division factors */ 02206 /* PLLI2S_VCO = f(VCO clock) = f(PLLI2S clock input) * (PLLI2SN/PLLM) */ 02207 /* I2SCLK = f(PLLI2S clock output) = f(VCO clock) / PLLI2SR */ 02208 __HAL_RCC_PLLI2S_CONFIG(PeriphClkInit->PLLI2S.PLLI2SN , PeriphClkInit->PLLI2S.PLLI2SR); 02209 } 02210 02211 /*---------------------------- SAI configuration -------------------------*/ 02212 /* In Case of SAI Clock Configuration through PLLI2S, PLLI2SQ and PLLI2S_DIVQ must 02213 be added only for SAI configuration */ 02214 if(((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_SAI_PLLI2S) == (RCC_PERIPHCLK_SAI_PLLI2S)) 02215 { 02216 /* Check the PLLI2S division factors */ 02217 assert_param(IS_RCC_PLLI2SQ_VALUE(PeriphClkInit->PLLI2S.PLLI2SQ)); 02218 assert_param(IS_RCC_PLLI2S_DIVQ_VALUE(PeriphClkInit->PLLI2SDivQ)); 02219 02220 /* Read PLLI2SR value from PLLI2SCFGR register (this value is not need for SAI configuration) */ 02221 tmpreg1 = ((RCC->PLLI2SCFGR & RCC_PLLI2SCFGR_PLLI2SR) >> RCC_PLLI2SCFGR_PLLI2SR_Pos); 02222 /* Configure the PLLI2S division factors */ 02223 /* PLLI2S_VCO Input = PLL_SOURCE/PLLM */ 02224 /* PLLI2S_VCO Output = PLLI2S_VCO Input * PLLI2SN */ 02225 /* SAI_CLK(first level) = PLLI2S_VCO Output/PLLI2SQ */ 02226 __HAL_RCC_PLLI2S_SAICLK_CONFIG(PeriphClkInit->PLLI2S.PLLI2SN , PeriphClkInit->PLLI2S.PLLI2SQ , tmpreg1); 02227 /* SAI_CLK_x = SAI_CLK(first level)/PLLI2SDIVQ */ 02228 __HAL_RCC_PLLI2S_PLLSAICLKDIVQ_CONFIG(PeriphClkInit->PLLI2SDivQ); 02229 } 02230 02231 /*----------------- In Case of PLLI2S is just selected -----------------*/ 02232 if((PeriphClkInit->PeriphClockSelection & RCC_PERIPHCLK_PLLI2S) == RCC_PERIPHCLK_PLLI2S) 02233 { 02234 /* Check for Parameters */ 02235 assert_param(IS_RCC_PLLI2SQ_VALUE(PeriphClkInit->PLLI2S.PLLI2SQ)); 02236 assert_param(IS_RCC_PLLI2SR_VALUE(PeriphClkInit->PLLI2S.PLLI2SR)); 02237 02238 /* Configure the PLLI2S multiplication and division factors */ 02239 __HAL_RCC_PLLI2S_SAICLK_CONFIG(PeriphClkInit->PLLI2S.PLLI2SN, PeriphClkInit->PLLI2S.PLLI2SQ, PeriphClkInit->PLLI2S.PLLI2SR); 02240 } 02241 02242 /* Enable the PLLI2S */ 02243 __HAL_RCC_PLLI2S_ENABLE(); 02244 /* Get tick */ 02245 tickstart = HAL_GetTick(); 02246 /* Wait till PLLI2S is ready */ 02247 while(__HAL_RCC_GET_FLAG(RCC_FLAG_PLLI2SRDY) == RESET) 02248 { 02249 if((HAL_GetTick() - tickstart ) > PLLI2S_TIMEOUT_VALUE) 02250 { 02251 /* return in case of Timeout detected */ 02252 return HAL_TIMEOUT; 02253 } 02254 } 02255 } 02256 /*--------------------------------------------------------------------------*/ 02257 02258 /*----------------------- SAI/LTDC Configuration (PLLSAI) ------------------*/ 02259 /*----------------------- Common configuration SAI/LTDC --------------------*/ 02260 /* In Case of SAI or LTDC Clock Configuration through PLLSAI, PLLSAIN division 02261 factor is common parameters for both peripherals */ 02262 if((((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_SAI_PLLSAI) == RCC_PERIPHCLK_SAI_PLLSAI) || 02263 (((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_LTDC) == RCC_PERIPHCLK_LTDC)) 02264 { 02265 /* Check the PLLSAI division factors */ 02266 assert_param(IS_RCC_PLLSAIN_VALUE(PeriphClkInit->PLLSAI.PLLSAIN)); 02267 02268 /* Disable PLLSAI Clock */ 02269 __HAL_RCC_PLLSAI_DISABLE(); 02270 /* Get tick */ 02271 tickstart = HAL_GetTick(); 02272 /* Wait till PLLSAI is disabled */ 02273 while(__HAL_RCC_PLLSAI_GET_FLAG() != RESET) 02274 { 02275 if((HAL_GetTick() - tickstart ) > PLLSAI_TIMEOUT_VALUE) 02276 { 02277 /* return in case of Timeout detected */ 02278 return HAL_TIMEOUT; 02279 } 02280 } 02281 02282 /*---------------------------- SAI configuration -------------------------*/ 02283 /* In Case of SAI Clock Configuration through PLLSAI, PLLSAIQ and PLLSAI_DIVQ must 02284 be added only for SAI configuration */ 02285 if(((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_SAI_PLLSAI) == (RCC_PERIPHCLK_SAI_PLLSAI)) 02286 { 02287 assert_param(IS_RCC_PLLSAIQ_VALUE(PeriphClkInit->PLLSAI.PLLSAIQ)); 02288 assert_param(IS_RCC_PLLSAI_DIVQ_VALUE(PeriphClkInit->PLLSAIDivQ)); 02289 02290 /* Read PLLSAIR value from PLLSAICFGR register (this value is not need for SAI configuration) */ 02291 tmpreg1 = ((RCC->PLLSAICFGR & RCC_PLLSAICFGR_PLLSAIR) >> RCC_PLLSAICFGR_PLLSAIR_Pos); 02292 /* PLLSAI_VCO Input = PLL_SOURCE/PLLM */ 02293 /* PLLSAI_VCO Output = PLLSAI_VCO Input * PLLSAIN */ 02294 /* SAI_CLK(first level) = PLLSAI_VCO Output/PLLSAIQ */ 02295 __HAL_RCC_PLLSAI_CONFIG(PeriphClkInit->PLLSAI.PLLSAIN , PeriphClkInit->PLLSAI.PLLSAIQ, tmpreg1); 02296 /* SAI_CLK_x = SAI_CLK(first level)/PLLSAIDIVQ */ 02297 __HAL_RCC_PLLSAI_PLLSAICLKDIVQ_CONFIG(PeriphClkInit->PLLSAIDivQ); 02298 } 02299 02300 /*---------------------------- LTDC configuration ------------------------*/ 02301 if(((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_LTDC) == (RCC_PERIPHCLK_LTDC)) 02302 { 02303 assert_param(IS_RCC_PLLSAIR_VALUE(PeriphClkInit->PLLSAI.PLLSAIR)); 02304 assert_param(IS_RCC_PLLSAI_DIVR_VALUE(PeriphClkInit->PLLSAIDivR)); 02305 02306 /* Read PLLSAIR value from PLLSAICFGR register (this value is not need for SAI configuration) */ 02307 tmpreg1 = ((RCC->PLLSAICFGR & RCC_PLLSAICFGR_PLLSAIQ) >> RCC_PLLSAICFGR_PLLSAIQ_Pos); 02308 /* PLLSAI_VCO Input = PLL_SOURCE/PLLM */ 02309 /* PLLSAI_VCO Output = PLLSAI_VCO Input * PLLSAIN */ 02310 /* LTDC_CLK(first level) = PLLSAI_VCO Output/PLLSAIR */ 02311 __HAL_RCC_PLLSAI_CONFIG(PeriphClkInit->PLLSAI.PLLSAIN , tmpreg1, PeriphClkInit->PLLSAI.PLLSAIR); 02312 /* LTDC_CLK = LTDC_CLK(first level)/PLLSAIDIVR */ 02313 __HAL_RCC_PLLSAI_PLLSAICLKDIVR_CONFIG(PeriphClkInit->PLLSAIDivR); 02314 } 02315 /* Enable PLLSAI Clock */ 02316 __HAL_RCC_PLLSAI_ENABLE(); 02317 /* Get tick */ 02318 tickstart = HAL_GetTick(); 02319 /* Wait till PLLSAI is ready */ 02320 while(__HAL_RCC_PLLSAI_GET_FLAG() == RESET) 02321 { 02322 if((HAL_GetTick() - tickstart ) > PLLSAI_TIMEOUT_VALUE) 02323 { 02324 /* return in case of Timeout detected */ 02325 return HAL_TIMEOUT; 02326 } 02327 } 02328 } 02329 /*--------------------------------------------------------------------------*/ 02330 02331 /*---------------------------- RTC configuration ---------------------------*/ 02332 if(((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_RTC) == (RCC_PERIPHCLK_RTC)) 02333 { 02334 /* Check for RTC Parameters used to output RTCCLK */ 02335 assert_param(IS_RCC_RTCCLKSOURCE(PeriphClkInit->RTCClockSelection)); 02336 02337 /* Enable Power Clock*/ 02338 __HAL_RCC_PWR_CLK_ENABLE(); 02339 02340 /* Enable write access to Backup domain */ 02341 PWR->CR |= PWR_CR_DBP; 02342 02343 /* Get tick */ 02344 tickstart = HAL_GetTick(); 02345 02346 while((PWR->CR & PWR_CR_DBP) == RESET) 02347 { 02348 if((HAL_GetTick() - tickstart ) > RCC_DBP_TIMEOUT_VALUE) 02349 { 02350 return HAL_TIMEOUT; 02351 } 02352 } 02353 /* Reset the Backup domain only if the RTC Clock source selection is modified from reset value */ 02354 tmpreg1 = (RCC->BDCR & RCC_BDCR_RTCSEL); 02355 if((tmpreg1 != 0x00000000U) && ((tmpreg1) != (PeriphClkInit->RTCClockSelection & RCC_BDCR_RTCSEL))) 02356 { 02357 /* Store the content of BDCR register before the reset of Backup Domain */ 02358 tmpreg1 = (RCC->BDCR & ~(RCC_BDCR_RTCSEL)); 02359 /* RTC Clock selection can be changed only if the Backup Domain is reset */ 02360 __HAL_RCC_BACKUPRESET_FORCE(); 02361 __HAL_RCC_BACKUPRESET_RELEASE(); 02362 /* Restore the Content of BDCR register */ 02363 RCC->BDCR = tmpreg1; 02364 02365 /* Wait for LSE reactivation if LSE was enable prior to Backup Domain reset */ 02366 if(HAL_IS_BIT_SET(RCC->BDCR, RCC_BDCR_LSEON)) 02367 { 02368 /* Get tick */ 02369 tickstart = HAL_GetTick(); 02370 02371 /* Wait till LSE is ready */ 02372 while(__HAL_RCC_GET_FLAG(RCC_FLAG_LSERDY) == RESET) 02373 { 02374 if((HAL_GetTick() - tickstart ) > RCC_LSE_TIMEOUT_VALUE) 02375 { 02376 return HAL_TIMEOUT; 02377 } 02378 } 02379 } 02380 } 02381 __HAL_RCC_RTC_CONFIG(PeriphClkInit->RTCClockSelection); 02382 } 02383 /*--------------------------------------------------------------------------*/ 02384 02385 /*---------------------------- TIM configuration ---------------------------*/ 02386 if(((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_TIM) == (RCC_PERIPHCLK_TIM)) 02387 { 02388 __HAL_RCC_TIMCLKPRESCALER(PeriphClkInit->TIMPresSelection); 02389 } 02390 return HAL_OK; 02391 } 02392 02393 /** 02394 * @brief Configures the PeriphClkInit according to the internal 02395 * RCC configuration registers. 02396 * @param PeriphClkInit pointer to an RCC_PeriphCLKInitTypeDef structure that 02397 * will be configured. 02398 * @retval None 02399 */ 02400 void HAL_RCCEx_GetPeriphCLKConfig(RCC_PeriphCLKInitTypeDef *PeriphClkInit) 02401 { 02402 uint32_t tempreg; 02403 02404 /* Set all possible values for the extended clock type parameter------------*/ 02405 PeriphClkInit->PeriphClockSelection = RCC_PERIPHCLK_I2S | RCC_PERIPHCLK_SAI_PLLSAI | RCC_PERIPHCLK_SAI_PLLI2S | RCC_PERIPHCLK_LTDC | RCC_PERIPHCLK_TIM | RCC_PERIPHCLK_RTC; 02406 02407 /* Get the PLLI2S Clock configuration -----------------------------------------------*/ 02408 PeriphClkInit->PLLI2S.PLLI2SN = (uint32_t)((RCC->PLLI2SCFGR & RCC_PLLI2SCFGR_PLLI2SN) >> RCC_PLLI2SCFGR_PLLI2SN_Pos); 02409 PeriphClkInit->PLLI2S.PLLI2SR = (uint32_t)((RCC->PLLI2SCFGR & RCC_PLLI2SCFGR_PLLI2SR) >> RCC_PLLI2SCFGR_PLLI2SR_Pos); 02410 PeriphClkInit->PLLI2S.PLLI2SQ = (uint32_t)((RCC->PLLI2SCFGR & RCC_PLLI2SCFGR_PLLI2SQ) >> RCC_PLLI2SCFGR_PLLI2SQ_Pos); 02411 /* Get the PLLSAI Clock configuration -----------------------------------------------*/ 02412 PeriphClkInit->PLLSAI.PLLSAIN = (uint32_t)((RCC->PLLSAICFGR & RCC_PLLSAICFGR_PLLSAIN) >> RCC_PLLSAICFGR_PLLSAIN_Pos); 02413 PeriphClkInit->PLLSAI.PLLSAIR = (uint32_t)((RCC->PLLSAICFGR & RCC_PLLSAICFGR_PLLSAIR) >> RCC_PLLSAICFGR_PLLSAIR_Pos); 02414 PeriphClkInit->PLLSAI.PLLSAIQ = (uint32_t)((RCC->PLLSAICFGR & RCC_PLLSAICFGR_PLLSAIQ) >> RCC_PLLSAICFGR_PLLSAIQ_Pos); 02415 /* Get the PLLSAI/PLLI2S division factors -----------------------------------------------*/ 02416 PeriphClkInit->PLLI2SDivQ = (uint32_t)((RCC->DCKCFGR & RCC_DCKCFGR_PLLI2SDIVQ) >> RCC_DCKCFGR_PLLI2SDIVQ_Pos); 02417 PeriphClkInit->PLLSAIDivQ = (uint32_t)((RCC->DCKCFGR & RCC_DCKCFGR_PLLSAIDIVQ) >> RCC_DCKCFGR_PLLSAIDIVQ_Pos); 02418 PeriphClkInit->PLLSAIDivR = (uint32_t)(RCC->DCKCFGR & RCC_DCKCFGR_PLLSAIDIVR); 02419 /* Get the RTC Clock configuration -----------------------------------------------*/ 02420 tempreg = (RCC->CFGR & RCC_CFGR_RTCPRE); 02421 PeriphClkInit->RTCClockSelection = (uint32_t)((tempreg) | (RCC->BDCR & RCC_BDCR_RTCSEL)); 02422 02423 if ((RCC->DCKCFGR & RCC_DCKCFGR_TIMPRE) == RESET) 02424 { 02425 PeriphClkInit->TIMPresSelection = RCC_TIMPRES_DESACTIVATED; 02426 } 02427 else 02428 { 02429 PeriphClkInit->TIMPresSelection = RCC_TIMPRES_ACTIVATED; 02430 } 02431 } 02432 02433 /** 02434 * @brief Return the peripheral clock frequency for a given peripheral(SAI..) 02435 * @note Return 0 if peripheral clock identifier not managed by this API 02436 * @param PeriphClk Peripheral clock identifier 02437 * This parameter can be one of the following values: 02438 * @arg RCC_PERIPHCLK_I2S: I2S peripheral clock 02439 * @retval Frequency in KHz 02440 */ 02441 uint32_t HAL_RCCEx_GetPeriphCLKFreq(uint32_t PeriphClk) 02442 { 02443 /* This variable used to store the I2S clock frequency (value in Hz) */ 02444 uint32_t frequency = 0U; 02445 /* This variable used to store the VCO Input (value in Hz) */ 02446 uint32_t vcoinput = 0U; 02447 uint32_t srcclk = 0U; 02448 /* This variable used to store the VCO Output (value in Hz) */ 02449 uint32_t vcooutput = 0U; 02450 switch (PeriphClk) 02451 { 02452 case RCC_PERIPHCLK_I2S: 02453 { 02454 /* Get the current I2S source */ 02455 srcclk = __HAL_RCC_GET_I2S_SOURCE(); 02456 switch (srcclk) 02457 { 02458 /* Check if I2S clock selection is External clock mapped on the I2S_CKIN pin used as I2S clock */ 02459 case RCC_I2SCLKSOURCE_EXT: 02460 { 02461 /* Set the I2S clock to the external clock value */ 02462 frequency = EXTERNAL_CLOCK_VALUE; 02463 break; 02464 } 02465 /* Check if I2S clock selection is PLLI2S VCO output clock divided by PLLI2SR used as I2S clock */ 02466 case RCC_I2SCLKSOURCE_PLLI2S: 02467 { 02468 /* Configure the PLLI2S division factor */ 02469 /* PLLI2S_VCO Input = PLL_SOURCE/PLLM */ 02470 if((RCC->PLLCFGR & RCC_PLLCFGR_PLLSRC) == RCC_PLLSOURCE_HSE) 02471 { 02472 /* Get the I2S source clock value */ 02473 vcoinput = (uint32_t)(HSE_VALUE / (uint32_t)(RCC->PLLCFGR & RCC_PLLCFGR_PLLM)); 02474 } 02475 else 02476 { 02477 /* Get the I2S source clock value */ 02478 vcoinput = (uint32_t)(HSI_VALUE / (uint32_t)(RCC->PLLCFGR & RCC_PLLCFGR_PLLM)); 02479 } 02480 02481 /* PLLI2S_VCO Output = PLLI2S_VCO Input * PLLI2SN */ 02482 vcooutput = (uint32_t)(vcoinput * (((RCC->PLLI2SCFGR & RCC_PLLI2SCFGR_PLLI2SN) >> 6U) & (RCC_PLLI2SCFGR_PLLI2SN >> 6U))); 02483 /* I2S_CLK = PLLI2S_VCO Output/PLLI2SR */ 02484 frequency = (uint32_t)(vcooutput /(((RCC->PLLI2SCFGR & RCC_PLLI2SCFGR_PLLI2SR) >> 28U) & (RCC_PLLI2SCFGR_PLLI2SR >> 28U))); 02485 break; 02486 } 02487 /* Clock not enabled for I2S*/ 02488 default: 02489 { 02490 frequency = 0U; 02491 break; 02492 } 02493 } 02494 break; 02495 } 02496 } 02497 return frequency; 02498 } 02499 #endif /* STM32F427xx || STM32F437xx || STM32F429xx || STM32F439xx */ 02500 02501 #if defined(STM32F405xx) || defined(STM32F415xx) || defined(STM32F407xx)|| defined(STM32F417xx) ||\ 02502 defined(STM32F401xC) || defined(STM32F401xE) || defined(STM32F411xE) 02503 /** 02504 * @brief Initializes the RCC extended peripherals clocks according to the specified parameters in the 02505 * RCC_PeriphCLKInitTypeDef. 02506 * @param PeriphClkInit pointer to an RCC_PeriphCLKInitTypeDef structure that 02507 * contains the configuration information for the Extended Peripherals clocks(I2S and RTC clocks). 02508 * 02509 * @note A caution to be taken when HAL_RCCEx_PeriphCLKConfig() is used to select RTC clock selection, in this case 02510 * the Reset of Backup domain will be applied in order to modify the RTC Clock source as consequence all backup 02511 * domain (RTC and RCC_BDCR register expect BKPSRAM) will be reset 02512 * 02513 * @retval HAL status 02514 */ 02515 HAL_StatusTypeDef HAL_RCCEx_PeriphCLKConfig(RCC_PeriphCLKInitTypeDef *PeriphClkInit) 02516 { 02517 uint32_t tickstart = 0U; 02518 uint32_t tmpreg1 = 0U; 02519 02520 /* Check the parameters */ 02521 assert_param(IS_RCC_PERIPHCLOCK(PeriphClkInit->PeriphClockSelection)); 02522 02523 /*---------------------------- I2S configuration ---------------------------*/ 02524 if((((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_I2S) == RCC_PERIPHCLK_I2S) || 02525 (((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_PLLI2S) == RCC_PERIPHCLK_PLLI2S)) 02526 { 02527 /* check for Parameters */ 02528 assert_param(IS_RCC_PLLI2SR_VALUE(PeriphClkInit->PLLI2S.PLLI2SR)); 02529 assert_param(IS_RCC_PLLI2SN_VALUE(PeriphClkInit->PLLI2S.PLLI2SN)); 02530 #if defined(STM32F411xE) 02531 assert_param(IS_RCC_PLLI2SM_VALUE(PeriphClkInit->PLLI2S.PLLI2SM)); 02532 #endif /* STM32F411xE */ 02533 /* Disable the PLLI2S */ 02534 __HAL_RCC_PLLI2S_DISABLE(); 02535 /* Get tick */ 02536 tickstart = HAL_GetTick(); 02537 /* Wait till PLLI2S is disabled */ 02538 while(__HAL_RCC_GET_FLAG(RCC_FLAG_PLLI2SRDY) != RESET) 02539 { 02540 if((HAL_GetTick() - tickstart ) > PLLI2S_TIMEOUT_VALUE) 02541 { 02542 /* return in case of Timeout detected */ 02543 return HAL_TIMEOUT; 02544 } 02545 } 02546 02547 #if defined(STM32F411xE) 02548 /* Configure the PLLI2S division factors */ 02549 /* PLLI2S_VCO = f(VCO clock) = f(PLLI2S clock input) * (PLLI2SN/PLLI2SM) */ 02550 /* I2SCLK = f(PLLI2S clock output) = f(VCO clock) / PLLI2SR */ 02551 __HAL_RCC_PLLI2S_I2SCLK_CONFIG(PeriphClkInit->PLLI2S.PLLI2SM, PeriphClkInit->PLLI2S.PLLI2SN, PeriphClkInit->PLLI2S.PLLI2SR); 02552 #else 02553 /* Configure the PLLI2S division factors */ 02554 /* PLLI2S_VCO = f(VCO clock) = f(PLLI2S clock input) * (PLLI2SN/PLLM) */ 02555 /* I2SCLK = f(PLLI2S clock output) = f(VCO clock) / PLLI2SR */ 02556 __HAL_RCC_PLLI2S_CONFIG(PeriphClkInit->PLLI2S.PLLI2SN , PeriphClkInit->PLLI2S.PLLI2SR); 02557 #endif /* STM32F411xE */ 02558 02559 /* Enable the PLLI2S */ 02560 __HAL_RCC_PLLI2S_ENABLE(); 02561 /* Get tick */ 02562 tickstart = HAL_GetTick(); 02563 /* Wait till PLLI2S is ready */ 02564 while(__HAL_RCC_GET_FLAG(RCC_FLAG_PLLI2SRDY) == RESET) 02565 { 02566 if((HAL_GetTick() - tickstart ) > PLLI2S_TIMEOUT_VALUE) 02567 { 02568 /* return in case of Timeout detected */ 02569 return HAL_TIMEOUT; 02570 } 02571 } 02572 } 02573 02574 /*---------------------------- RTC configuration ---------------------------*/ 02575 if(((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_RTC) == (RCC_PERIPHCLK_RTC)) 02576 { 02577 /* Check for RTC Parameters used to output RTCCLK */ 02578 assert_param(IS_RCC_RTCCLKSOURCE(PeriphClkInit->RTCClockSelection)); 02579 02580 /* Enable Power Clock*/ 02581 __HAL_RCC_PWR_CLK_ENABLE(); 02582 02583 /* Enable write access to Backup domain */ 02584 PWR->CR |= PWR_CR_DBP; 02585 02586 /* Get tick */ 02587 tickstart = HAL_GetTick(); 02588 02589 while((PWR->CR & PWR_CR_DBP) == RESET) 02590 { 02591 if((HAL_GetTick() - tickstart ) > RCC_DBP_TIMEOUT_VALUE) 02592 { 02593 return HAL_TIMEOUT; 02594 } 02595 } 02596 /* Reset the Backup domain only if the RTC Clock source selection is modified from reset value */ 02597 tmpreg1 = (RCC->BDCR & RCC_BDCR_RTCSEL); 02598 if((tmpreg1 != 0x00000000U) && ((tmpreg1) != (PeriphClkInit->RTCClockSelection & RCC_BDCR_RTCSEL))) 02599 { 02600 /* Store the content of BDCR register before the reset of Backup Domain */ 02601 tmpreg1 = (RCC->BDCR & ~(RCC_BDCR_RTCSEL)); 02602 /* RTC Clock selection can be changed only if the Backup Domain is reset */ 02603 __HAL_RCC_BACKUPRESET_FORCE(); 02604 __HAL_RCC_BACKUPRESET_RELEASE(); 02605 /* Restore the Content of BDCR register */ 02606 RCC->BDCR = tmpreg1; 02607 02608 /* Wait for LSE reactivation if LSE was enable prior to Backup Domain reset */ 02609 if(HAL_IS_BIT_SET(RCC->BDCR, RCC_BDCR_LSEON)) 02610 { 02611 /* Get tick */ 02612 tickstart = HAL_GetTick(); 02613 02614 /* Wait till LSE is ready */ 02615 while(__HAL_RCC_GET_FLAG(RCC_FLAG_LSERDY) == RESET) 02616 { 02617 if((HAL_GetTick() - tickstart ) > RCC_LSE_TIMEOUT_VALUE) 02618 { 02619 return HAL_TIMEOUT; 02620 } 02621 } 02622 } 02623 } 02624 __HAL_RCC_RTC_CONFIG(PeriphClkInit->RTCClockSelection); 02625 } 02626 #if defined(STM32F401xC) || defined(STM32F401xE) || defined(STM32F411xE) 02627 /*---------------------------- TIM configuration ---------------------------*/ 02628 if(((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_TIM) == (RCC_PERIPHCLK_TIM)) 02629 { 02630 __HAL_RCC_TIMCLKPRESCALER(PeriphClkInit->TIMPresSelection); 02631 } 02632 #endif /* STM32F401xC || STM32F401xE || STM32F411xE */ 02633 return HAL_OK; 02634 } 02635 02636 /** 02637 * @brief Configures the RCC_OscInitStruct according to the internal 02638 * RCC configuration registers. 02639 * @param PeriphClkInit pointer to an RCC_PeriphCLKInitTypeDef structure that 02640 * will be configured. 02641 * @retval None 02642 */ 02643 void HAL_RCCEx_GetPeriphCLKConfig(RCC_PeriphCLKInitTypeDef *PeriphClkInit) 02644 { 02645 uint32_t tempreg; 02646 02647 /* Set all possible values for the extended clock type parameter------------*/ 02648 PeriphClkInit->PeriphClockSelection = RCC_PERIPHCLK_I2S | RCC_PERIPHCLK_RTC; 02649 02650 /* Get the PLLI2S Clock configuration --------------------------------------*/ 02651 PeriphClkInit->PLLI2S.PLLI2SN = (uint32_t)((RCC->PLLI2SCFGR & RCC_PLLI2SCFGR_PLLI2SN) >> RCC_PLLI2SCFGR_PLLI2SN_Pos); 02652 PeriphClkInit->PLLI2S.PLLI2SR = (uint32_t)((RCC->PLLI2SCFGR & RCC_PLLI2SCFGR_PLLI2SR) >> RCC_PLLI2SCFGR_PLLI2SR_Pos); 02653 #if defined(STM32F411xE) 02654 PeriphClkInit->PLLI2S.PLLI2SM = (uint32_t)(RCC->PLLI2SCFGR & RCC_PLLI2SCFGR_PLLI2SM); 02655 #endif /* STM32F411xE */ 02656 /* Get the RTC Clock configuration -----------------------------------------*/ 02657 tempreg = (RCC->CFGR & RCC_CFGR_RTCPRE); 02658 PeriphClkInit->RTCClockSelection = (uint32_t)((tempreg) | (RCC->BDCR & RCC_BDCR_RTCSEL)); 02659 02660 #if defined(STM32F401xC) || defined(STM32F401xE) || defined(STM32F411xE) 02661 /* Get the TIM Prescaler configuration -------------------------------------*/ 02662 if ((RCC->DCKCFGR & RCC_DCKCFGR_TIMPRE) == RESET) 02663 { 02664 PeriphClkInit->TIMPresSelection = RCC_TIMPRES_DESACTIVATED; 02665 } 02666 else 02667 { 02668 PeriphClkInit->TIMPresSelection = RCC_TIMPRES_ACTIVATED; 02669 } 02670 #endif /* STM32F401xC || STM32F401xE || STM32F411xE */ 02671 } 02672 02673 /** 02674 * @brief Return the peripheral clock frequency for a given peripheral(SAI..) 02675 * @note Return 0 if peripheral clock identifier not managed by this API 02676 * @param PeriphClk Peripheral clock identifier 02677 * This parameter can be one of the following values: 02678 * @arg RCC_PERIPHCLK_I2S: I2S peripheral clock 02679 * @retval Frequency in KHz 02680 */ 02681 uint32_t HAL_RCCEx_GetPeriphCLKFreq(uint32_t PeriphClk) 02682 { 02683 /* This variable used to store the I2S clock frequency (value in Hz) */ 02684 uint32_t frequency = 0U; 02685 /* This variable used to store the VCO Input (value in Hz) */ 02686 uint32_t vcoinput = 0U; 02687 uint32_t srcclk = 0U; 02688 /* This variable used to store the VCO Output (value in Hz) */ 02689 uint32_t vcooutput = 0U; 02690 switch (PeriphClk) 02691 { 02692 case RCC_PERIPHCLK_I2S: 02693 { 02694 /* Get the current I2S source */ 02695 srcclk = __HAL_RCC_GET_I2S_SOURCE(); 02696 switch (srcclk) 02697 { 02698 /* Check if I2S clock selection is External clock mapped on the I2S_CKIN pin used as I2S clock */ 02699 case RCC_I2SCLKSOURCE_EXT: 02700 { 02701 /* Set the I2S clock to the external clock value */ 02702 frequency = EXTERNAL_CLOCK_VALUE; 02703 break; 02704 } 02705 /* Check if I2S clock selection is PLLI2S VCO output clock divided by PLLI2SR used as I2S clock */ 02706 case RCC_I2SCLKSOURCE_PLLI2S: 02707 { 02708 #if defined(STM32F411xE) 02709 /* Configure the PLLI2S division factor */ 02710 /* PLLI2S_VCO Input = PLL_SOURCE/PLLI2SM */ 02711 if((RCC->PLLCFGR & RCC_PLLCFGR_PLLSRC) == RCC_PLLSOURCE_HSE) 02712 { 02713 /* Get the I2S source clock value */ 02714 vcoinput = (uint32_t)(HSE_VALUE / (uint32_t)(RCC->PLLI2SCFGR & RCC_PLLI2SCFGR_PLLI2SM)); 02715 } 02716 else 02717 { 02718 /* Get the I2S source clock value */ 02719 vcoinput = (uint32_t)(HSI_VALUE / (uint32_t)(RCC->PLLI2SCFGR & RCC_PLLI2SCFGR_PLLI2SM)); 02720 } 02721 #else 02722 /* Configure the PLLI2S division factor */ 02723 /* PLLI2S_VCO Input = PLL_SOURCE/PLLM */ 02724 if((RCC->PLLCFGR & RCC_PLLCFGR_PLLSRC) == RCC_PLLSOURCE_HSE) 02725 { 02726 /* Get the I2S source clock value */ 02727 vcoinput = (uint32_t)(HSE_VALUE / (uint32_t)(RCC->PLLCFGR & RCC_PLLCFGR_PLLM)); 02728 } 02729 else 02730 { 02731 /* Get the I2S source clock value */ 02732 vcoinput = (uint32_t)(HSI_VALUE / (uint32_t)(RCC->PLLCFGR & RCC_PLLCFGR_PLLM)); 02733 } 02734 #endif /* STM32F411xE */ 02735 /* PLLI2S_VCO Output = PLLI2S_VCO Input * PLLI2SN */ 02736 vcooutput = (uint32_t)(vcoinput * (((RCC->PLLI2SCFGR & RCC_PLLI2SCFGR_PLLI2SN) >> 6U) & (RCC_PLLI2SCFGR_PLLI2SN >> 6U))); 02737 /* I2S_CLK = PLLI2S_VCO Output/PLLI2SR */ 02738 frequency = (uint32_t)(vcooutput /(((RCC->PLLI2SCFGR & RCC_PLLI2SCFGR_PLLI2SR) >> 28U) & (RCC_PLLI2SCFGR_PLLI2SR >> 28U))); 02739 break; 02740 } 02741 /* Clock not enabled for I2S*/ 02742 default: 02743 { 02744 frequency = 0U; 02745 break; 02746 } 02747 } 02748 break; 02749 } 02750 } 02751 return frequency; 02752 } 02753 #endif /* STM32F405xx || STM32F415xx || STM32F407xx || STM32F417xx || STM32F401xC || STM32F401xE || STM32F411xE */ 02754 02755 #if defined(STM32F410Tx) || defined(STM32F410Cx) || defined(STM32F410Rx) || defined(STM32F411xE) || defined(STM32F446xx) || defined(STM32F469xx) || defined(STM32F479xx) || defined(STM32F412Zx) ||\ 02756 defined(STM32F412Vx) || defined(STM32F412Rx) || defined(STM32F412Cx) || defined(STM32F413xx) || defined(STM32F423xx) 02757 /** 02758 * @brief Select LSE mode 02759 * 02760 * @note This mode is only available for STM32F410xx/STM32F411xx/STM32F446xx/STM32F469xx/STM32F479xx/STM32F412Zx/STM32F412Vx/STM32F412Rx/STM32F412Cx devices. 02761 * 02762 * @param Mode specifies the LSE mode. 02763 * This parameter can be one of the following values: 02764 * @arg RCC_LSE_LOWPOWER_MODE: LSE oscillator in low power mode selection 02765 * @arg RCC_LSE_HIGHDRIVE_MODE: LSE oscillator in High Drive mode selection 02766 * @retval None 02767 */ 02768 void HAL_RCCEx_SelectLSEMode(uint8_t Mode) 02769 { 02770 /* Check the parameters */ 02771 assert_param(IS_RCC_LSE_MODE(Mode)); 02772 if(Mode == RCC_LSE_HIGHDRIVE_MODE) 02773 { 02774 SET_BIT(RCC->BDCR, RCC_BDCR_LSEMOD); 02775 } 02776 else 02777 { 02778 CLEAR_BIT(RCC->BDCR, RCC_BDCR_LSEMOD); 02779 } 02780 } 02781 02782 #endif /* STM32F410xx || STM32F411xE || STM32F446xx || STM32F469xx || STM32F479xx || STM32F412Zx || STM32F412Vx || STM32F412Rx || STM32F412Cx || STM32F413xx || STM32F423xx */ 02783 02784 /** @defgroup RCCEx_Exported_Functions_Group2 Extended Clock management functions 02785 * @brief Extended Clock management functions 02786 * 02787 @verbatim 02788 =============================================================================== 02789 ##### Extended clock management functions ##### 02790 =============================================================================== 02791 [..] 02792 This subsection provides a set of functions allowing to control the 02793 activation or deactivation of PLLI2S, PLLSAI. 02794 @endverbatim 02795 * @{ 02796 */ 02797 02798 #if defined(RCC_PLLI2S_SUPPORT) 02799 /** 02800 * @brief Enable PLLI2S. 02801 * @param PLLI2SInit pointer to an RCC_PLLI2SInitTypeDef structure that 02802 * contains the configuration information for the PLLI2S 02803 * @retval HAL status 02804 */ 02805 HAL_StatusTypeDef HAL_RCCEx_EnablePLLI2S(RCC_PLLI2SInitTypeDef *PLLI2SInit) 02806 { 02807 uint32_t tickstart; 02808 02809 /* Check for parameters */ 02810 assert_param(IS_RCC_PLLI2SN_VALUE(PLLI2SInit->PLLI2SN)); 02811 assert_param(IS_RCC_PLLI2SR_VALUE(PLLI2SInit->PLLI2SR)); 02812 #if defined(RCC_PLLI2SCFGR_PLLI2SM) 02813 assert_param(IS_RCC_PLLI2SM_VALUE(PLLI2SInit->PLLI2SM)); 02814 #endif /* RCC_PLLI2SCFGR_PLLI2SM */ 02815 #if defined(RCC_PLLI2SCFGR_PLLI2SP) 02816 assert_param(IS_RCC_PLLI2SP_VALUE(PLLI2SInit->PLLI2SP)); 02817 #endif /* RCC_PLLI2SCFGR_PLLI2SP */ 02818 #if defined(RCC_PLLI2SCFGR_PLLI2SQ) 02819 assert_param(IS_RCC_PLLI2SQ_VALUE(PLLI2SInit->PLLI2SQ)); 02820 #endif /* RCC_PLLI2SCFGR_PLLI2SQ */ 02821 02822 /* Disable the PLLI2S */ 02823 __HAL_RCC_PLLI2S_DISABLE(); 02824 02825 /* Wait till PLLI2S is disabled */ 02826 tickstart = HAL_GetTick(); 02827 while(__HAL_RCC_GET_FLAG(RCC_FLAG_PLLI2SRDY) != RESET) 02828 { 02829 if((HAL_GetTick() - tickstart ) > PLLI2S_TIMEOUT_VALUE) 02830 { 02831 /* return in case of Timeout detected */ 02832 return HAL_TIMEOUT; 02833 } 02834 } 02835 02836 /* Configure the PLLI2S division factors */ 02837 #if defined(STM32F446xx) 02838 /* PLLI2S_VCO = f(VCO clock) = f(PLLI2S clock input) * (PLLI2SN/PLLI2SM) */ 02839 /* I2SPCLK = PLLI2S_VCO / PLLI2SP */ 02840 /* I2SQCLK = PLLI2S_VCO / PLLI2SQ */ 02841 /* I2SRCLK = PLLI2S_VCO / PLLI2SR */ 02842 __HAL_RCC_PLLI2S_CONFIG(PLLI2SInit->PLLI2SM, PLLI2SInit->PLLI2SN, \ 02843 PLLI2SInit->PLLI2SP, PLLI2SInit->PLLI2SQ, PLLI2SInit->PLLI2SR); 02844 #elif defined(STM32F412Zx) || defined(STM32F412Vx) || defined(STM32F412Rx) || defined(STM32F412Cx) ||\ 02845 defined(STM32F413xx) || defined(STM32F423xx) 02846 /* PLLI2S_VCO = f(VCO clock) = f(PLLI2S clock input) * (PLLI2SN/PLLI2SM)*/ 02847 /* I2SQCLK = PLLI2S_VCO / PLLI2SQ */ 02848 /* I2SRCLK = PLLI2S_VCO / PLLI2SR */ 02849 __HAL_RCC_PLLI2S_CONFIG(PLLI2SInit->PLLI2SM, PLLI2SInit->PLLI2SN, \ 02850 PLLI2SInit->PLLI2SQ, PLLI2SInit->PLLI2SR); 02851 #elif defined(STM32F427xx) || defined(STM32F437xx) || defined(STM32F429xx) || defined(STM32F439xx) ||\ 02852 defined(STM32F469xx) || defined(STM32F479xx) 02853 /* PLLI2S_VCO = f(VCO clock) = f(PLLI2S clock input) * PLLI2SN */ 02854 /* I2SQCLK = PLLI2S_VCO / PLLI2SQ */ 02855 /* I2SRCLK = PLLI2S_VCO / PLLI2SR */ 02856 __HAL_RCC_PLLI2S_SAICLK_CONFIG(PLLI2SInit->PLLI2SN, PLLI2SInit->PLLI2SQ, PLLI2SInit->PLLI2SR); 02857 #elif defined(STM32F411xE) 02858 /* PLLI2S_VCO = f(VCO clock) = f(PLLI2S clock input) * (PLLI2SN/PLLI2SM) */ 02859 /* I2SRCLK = PLLI2S_VCO / PLLI2SR */ 02860 __HAL_RCC_PLLI2S_I2SCLK_CONFIG(PLLI2SInit->PLLI2SM, PLLI2SInit->PLLI2SN, PLLI2SInit->PLLI2SR); 02861 #else 02862 /* PLLI2S_VCO = f(VCO clock) = f(PLLI2S clock input) x PLLI2SN */ 02863 /* I2SRCLK = PLLI2S_VCO / PLLI2SR */ 02864 __HAL_RCC_PLLI2S_CONFIG(PLLI2SInit->PLLI2SN, PLLI2SInit->PLLI2SR); 02865 #endif /* STM32F446xx */ 02866 02867 /* Enable the PLLI2S */ 02868 __HAL_RCC_PLLI2S_ENABLE(); 02869 02870 /* Wait till PLLI2S is ready */ 02871 tickstart = HAL_GetTick(); 02872 while(__HAL_RCC_GET_FLAG(RCC_FLAG_PLLI2SRDY) == RESET) 02873 { 02874 if((HAL_GetTick() - tickstart ) > PLLI2S_TIMEOUT_VALUE) 02875 { 02876 /* return in case of Timeout detected */ 02877 return HAL_TIMEOUT; 02878 } 02879 } 02880 02881 return HAL_OK; 02882 } 02883 02884 /** 02885 * @brief Disable PLLI2S. 02886 * @retval HAL status 02887 */ 02888 HAL_StatusTypeDef HAL_RCCEx_DisablePLLI2S(void) 02889 { 02890 uint32_t tickstart; 02891 02892 /* Disable the PLLI2S */ 02893 __HAL_RCC_PLLI2S_DISABLE(); 02894 02895 /* Wait till PLLI2S is disabled */ 02896 tickstart = HAL_GetTick(); 02897 while(READ_BIT(RCC->CR, RCC_CR_PLLI2SRDY) != RESET) 02898 { 02899 if((HAL_GetTick() - tickstart) > PLLI2S_TIMEOUT_VALUE) 02900 { 02901 /* return in case of Timeout detected */ 02902 return HAL_TIMEOUT; 02903 } 02904 } 02905 02906 return HAL_OK; 02907 } 02908 02909 #endif /* RCC_PLLI2S_SUPPORT */ 02910 02911 #if defined(RCC_PLLSAI_SUPPORT) 02912 /** 02913 * @brief Enable PLLSAI. 02914 * @param PLLSAIInit pointer to an RCC_PLLSAIInitTypeDef structure that 02915 * contains the configuration information for the PLLSAI 02916 * @retval HAL status 02917 */ 02918 HAL_StatusTypeDef HAL_RCCEx_EnablePLLSAI(RCC_PLLSAIInitTypeDef *PLLSAIInit) 02919 { 02920 uint32_t tickstart; 02921 02922 /* Check for parameters */ 02923 assert_param(IS_RCC_PLLSAIN_VALUE(PLLSAIInit->PLLSAIN)); 02924 assert_param(IS_RCC_PLLSAIQ_VALUE(PLLSAIInit->PLLSAIQ)); 02925 #if defined(RCC_PLLSAICFGR_PLLSAIM) 02926 assert_param(IS_RCC_PLLSAIM_VALUE(PLLSAIInit->PLLSAIM)); 02927 #endif /* RCC_PLLSAICFGR_PLLSAIM */ 02928 #if defined(RCC_PLLSAICFGR_PLLSAIP) 02929 assert_param(IS_RCC_PLLSAIP_VALUE(PLLSAIInit->PLLSAIP)); 02930 #endif /* RCC_PLLSAICFGR_PLLSAIP */ 02931 #if defined(RCC_PLLSAICFGR_PLLSAIR) 02932 assert_param(IS_RCC_PLLSAIR_VALUE(PLLSAIInit->PLLSAIR)); 02933 #endif /* RCC_PLLSAICFGR_PLLSAIR */ 02934 02935 /* Disable the PLLSAI */ 02936 __HAL_RCC_PLLSAI_DISABLE(); 02937 02938 /* Wait till PLLSAI is disabled */ 02939 tickstart = HAL_GetTick(); 02940 while(__HAL_RCC_PLLSAI_GET_FLAG() != RESET) 02941 { 02942 if((HAL_GetTick() - tickstart ) > PLLSAI_TIMEOUT_VALUE) 02943 { 02944 /* return in case of Timeout detected */ 02945 return HAL_TIMEOUT; 02946 } 02947 } 02948 02949 /* Configure the PLLSAI division factors */ 02950 #if defined(STM32F446xx) 02951 /* PLLSAI_VCO = f(VCO clock) = f(PLLSAI clock input) * (PLLSAIN/PLLSAIM) */ 02952 /* SAIPCLK = PLLSAI_VCO / PLLSAIP */ 02953 /* SAIQCLK = PLLSAI_VCO / PLLSAIQ */ 02954 /* SAIRCLK = PLLSAI_VCO / PLLSAIR */ 02955 __HAL_RCC_PLLSAI_CONFIG(PLLSAIInit->PLLSAIM, PLLSAIInit->PLLSAIN, \ 02956 PLLSAIInit->PLLSAIP, PLLSAIInit->PLLSAIQ, 0U); 02957 #elif defined(STM32F469xx) || defined(STM32F479xx) 02958 /* PLLSAI_VCO = f(VCO clock) = f(PLLSAI clock input) * PLLSAIN */ 02959 /* SAIPCLK = PLLSAI_VCO / PLLSAIP */ 02960 /* SAIQCLK = PLLSAI_VCO / PLLSAIQ */ 02961 /* SAIRCLK = PLLSAI_VCO / PLLSAIR */ 02962 __HAL_RCC_PLLSAI_CONFIG(PLLSAIInit->PLLSAIN, PLLSAIInit->PLLSAIP, \ 02963 PLLSAIInit->PLLSAIQ, PLLSAIInit->PLLSAIR); 02964 #else 02965 /* PLLSAI_VCO = f(VCO clock) = f(PLLSAI clock input) x PLLSAIN */ 02966 /* SAIQCLK = PLLSAI_VCO / PLLSAIQ */ 02967 /* SAIRCLK = PLLSAI_VCO / PLLSAIR */ 02968 __HAL_RCC_PLLSAI_CONFIG(PLLSAIInit->PLLSAIN, PLLSAIInit->PLLSAIQ, PLLSAIInit->PLLSAIR); 02969 #endif /* STM32F446xx */ 02970 02971 /* Enable the PLLSAI */ 02972 __HAL_RCC_PLLSAI_ENABLE(); 02973 02974 /* Wait till PLLSAI is ready */ 02975 tickstart = HAL_GetTick(); 02976 while(__HAL_RCC_PLLSAI_GET_FLAG() == RESET) 02977 { 02978 if((HAL_GetTick() - tickstart ) > PLLSAI_TIMEOUT_VALUE) 02979 { 02980 /* return in case of Timeout detected */ 02981 return HAL_TIMEOUT; 02982 } 02983 } 02984 02985 return HAL_OK; 02986 } 02987 02988 /** 02989 * @brief Disable PLLSAI. 02990 * @retval HAL status 02991 */ 02992 HAL_StatusTypeDef HAL_RCCEx_DisablePLLSAI(void) 02993 { 02994 uint32_t tickstart; 02995 02996 /* Disable the PLLSAI */ 02997 __HAL_RCC_PLLSAI_DISABLE(); 02998 02999 /* Wait till PLLSAI is disabled */ 03000 tickstart = HAL_GetTick(); 03001 while(__HAL_RCC_PLLSAI_GET_FLAG() != RESET) 03002 { 03003 if((HAL_GetTick() - tickstart) > PLLSAI_TIMEOUT_VALUE) 03004 { 03005 /* return in case of Timeout detected */ 03006 return HAL_TIMEOUT; 03007 } 03008 } 03009 03010 return HAL_OK; 03011 } 03012 03013 #endif /* RCC_PLLSAI_SUPPORT */ 03014 03015 /** 03016 * @} 03017 */ 03018 03019 #if defined(STM32F446xx) 03020 /** 03021 * @brief Returns the SYSCLK frequency 03022 * 03023 * @note This function implementation is valid only for STM32F446xx devices. 03024 * @note This function add the PLL/PLLR System clock source 03025 * 03026 * @note The system frequency computed by this function is not the real 03027 * frequency in the chip. It is calculated based on the predefined 03028 * constant and the selected clock source: 03029 * @note If SYSCLK source is HSI, function returns values based on HSI_VALUE(*) 03030 * @note If SYSCLK source is HSE, function returns values based on HSE_VALUE(**) 03031 * @note If SYSCLK source is PLL or PLLR, function returns values based on HSE_VALUE(**) 03032 * or HSI_VALUE(*) multiplied/divided by the PLL factors. 03033 * @note (*) HSI_VALUE is a constant defined in stm32f4xx_hal_conf.h file (default value 03034 * 16 MHz) but the real value may vary depending on the variations 03035 * in voltage and temperature. 03036 * @note (**) HSE_VALUE is a constant defined in stm32f4xx_hal_conf.h file (default value 03037 * 25 MHz), user has to ensure that HSE_VALUE is same as the real 03038 * frequency of the crystal used. Otherwise, this function may 03039 * have wrong result. 03040 * 03041 * @note The result of this function could be not correct when using fractional 03042 * value for HSE crystal. 03043 * 03044 * @note This function can be used by the user application to compute the 03045 * baudrate for the communication peripherals or configure other parameters. 03046 * 03047 * @note Each time SYSCLK changes, this function must be called to update the 03048 * right SYSCLK value. Otherwise, any configuration based on this function will be incorrect. 03049 * 03050 * 03051 * @retval SYSCLK frequency 03052 */ 03053 uint32_t HAL_RCC_GetSysClockFreq(void) 03054 { 03055 uint32_t pllm = 0U; 03056 uint32_t pllvco = 0U; 03057 uint32_t pllp = 0U; 03058 uint32_t pllr = 0U; 03059 uint32_t sysclockfreq = 0U; 03060 03061 /* Get SYSCLK source -------------------------------------------------------*/ 03062 switch (RCC->CFGR & RCC_CFGR_SWS) 03063 { 03064 case RCC_CFGR_SWS_HSI: /* HSI used as system clock source */ 03065 { 03066 sysclockfreq = HSI_VALUE; 03067 break; 03068 } 03069 case RCC_CFGR_SWS_HSE: /* HSE used as system clock source */ 03070 { 03071 sysclockfreq = HSE_VALUE; 03072 break; 03073 } 03074 case RCC_CFGR_SWS_PLL: /* PLL/PLLP used as system clock source */ 03075 { 03076 /* PLL_VCO = (HSE_VALUE or HSI_VALUE / PLLM) * PLLN 03077 SYSCLK = PLL_VCO / PLLP */ 03078 pllm = RCC->PLLCFGR & RCC_PLLCFGR_PLLM; 03079 if(__HAL_RCC_GET_PLL_OSCSOURCE() != RCC_PLLSOURCE_HSI) 03080 { 03081 /* HSE used as PLL clock source */ 03082 pllvco = (uint32_t) ((((uint64_t) HSE_VALUE * ((uint64_t) ((RCC->PLLCFGR & RCC_PLLCFGR_PLLN) >> RCC_PLLCFGR_PLLN_Pos)))) / (uint64_t)pllm); 03083 } 03084 else 03085 { 03086 /* HSI used as PLL clock source */ 03087 pllvco = (uint32_t) ((((uint64_t) HSI_VALUE * ((uint64_t) ((RCC->PLLCFGR & RCC_PLLCFGR_PLLN) >> RCC_PLLCFGR_PLLN_Pos)))) / (uint64_t)pllm); 03088 } 03089 pllp = ((((RCC->PLLCFGR & RCC_PLLCFGR_PLLP) >> RCC_PLLCFGR_PLLP_Pos) + 1U) *2U); 03090 03091 sysclockfreq = pllvco/pllp; 03092 break; 03093 } 03094 case RCC_CFGR_SWS_PLLR: /* PLL/PLLR used as system clock source */ 03095 { 03096 /* PLL_VCO = (HSE_VALUE or HSI_VALUE / PLLM) * PLLN 03097 SYSCLK = PLL_VCO / PLLR */ 03098 pllm = RCC->PLLCFGR & RCC_PLLCFGR_PLLM; 03099 if(__HAL_RCC_GET_PLL_OSCSOURCE() != RCC_PLLSOURCE_HSI) 03100 { 03101 /* HSE used as PLL clock source */ 03102 pllvco = (uint32_t) ((((uint64_t) HSE_VALUE * ((uint64_t) ((RCC->PLLCFGR & RCC_PLLCFGR_PLLN) >> RCC_PLLCFGR_PLLN_Pos)))) / (uint64_t)pllm); 03103 } 03104 else 03105 { 03106 /* HSI used as PLL clock source */ 03107 pllvco = (uint32_t) ((((uint64_t) HSI_VALUE * ((uint64_t) ((RCC->PLLCFGR & RCC_PLLCFGR_PLLN) >> RCC_PLLCFGR_PLLN_Pos)))) / (uint64_t)pllm); 03108 } 03109 pllr = ((RCC->PLLCFGR & RCC_PLLCFGR_PLLR) >> RCC_PLLCFGR_PLLR_Pos); 03110 03111 sysclockfreq = pllvco/pllr; 03112 break; 03113 } 03114 default: 03115 { 03116 sysclockfreq = HSI_VALUE; 03117 break; 03118 } 03119 } 03120 return sysclockfreq; 03121 } 03122 #endif /* STM32F446xx */ 03123 03124 /** 03125 * @} 03126 */ 03127 03128 /** 03129 * @} 03130 */ 03131 03132 /** 03133 * @brief Resets the RCC clock configuration to the default reset state. 03134 * @note The default reset state of the clock configuration is given below: 03135 * - HSI ON and used as system clock source 03136 * - HSE, PLL, PLLI2S and PLLSAI OFF 03137 * - AHB, APB1 and APB2 prescaler set to 1. 03138 * - CSS, MCO1 and MCO2 OFF 03139 * - All interrupts disabled 03140 * @note This function doesn't modify the configuration of the 03141 * - Peripheral clocks 03142 * - LSI, LSE and RTC clocks 03143 * @retval HAL status 03144 */ 03145 HAL_StatusTypeDef HAL_RCC_DeInit(void) 03146 { 03147 uint32_t tickstart; 03148 03149 /* Get Start Tick */ 03150 tickstart = HAL_GetTick(); 03151 03152 /* Set HSION bit to the reset value */ 03153 SET_BIT(RCC->CR, RCC_CR_HSION); 03154 03155 /* Wait till HSI is ready */ 03156 while (READ_BIT(RCC->CR, RCC_CR_HSIRDY) == RESET) 03157 { 03158 if ((HAL_GetTick() - tickstart) > HSI_TIMEOUT_VALUE) 03159 { 03160 return HAL_TIMEOUT; 03161 } 03162 } 03163 03164 /* Set HSITRIM[4:0] bits to the reset value */ 03165 SET_BIT(RCC->CR, RCC_CR_HSITRIM_4); 03166 03167 /* Get Start Tick */ 03168 tickstart = HAL_GetTick(); 03169 03170 /* Reset CFGR register */ 03171 CLEAR_REG(RCC->CFGR); 03172 03173 /* Wait till clock switch is ready */ 03174 while (READ_BIT(RCC->CFGR, RCC_CFGR_SWS) != RESET) 03175 { 03176 if ((HAL_GetTick() - tickstart) > CLOCKSWITCH_TIMEOUT_VALUE) 03177 { 03178 return HAL_TIMEOUT; 03179 } 03180 } 03181 03182 /* Get Start Tick */ 03183 tickstart = HAL_GetTick(); 03184 03185 /* Clear HSEON, HSEBYP and CSSON bits */ 03186 CLEAR_BIT(RCC->CR, RCC_CR_HSEON | RCC_CR_HSEBYP | RCC_CR_CSSON); 03187 03188 /* Wait till HSE is disabled */ 03189 while (READ_BIT(RCC->CR, RCC_CR_HSERDY) != RESET) 03190 { 03191 if ((HAL_GetTick() - tickstart) > HSE_TIMEOUT_VALUE) 03192 { 03193 return HAL_TIMEOUT; 03194 } 03195 } 03196 03197 /* Get Start Tick */ 03198 tickstart = HAL_GetTick(); 03199 03200 /* Clear PLLON bit */ 03201 CLEAR_BIT(RCC->CR, RCC_CR_PLLON); 03202 03203 /* Wait till PLL is disabled */ 03204 while (READ_BIT(RCC->CR, RCC_CR_PLLRDY) != RESET) 03205 { 03206 if ((HAL_GetTick() - tickstart) > PLL_TIMEOUT_VALUE) 03207 { 03208 return HAL_TIMEOUT; 03209 } 03210 } 03211 03212 #if defined(RCC_PLLI2S_SUPPORT) 03213 /* Get Start Tick */ 03214 tickstart = HAL_GetTick(); 03215 03216 /* Reset PLLI2SON bit */ 03217 CLEAR_BIT(RCC->CR, RCC_CR_PLLI2SON); 03218 03219 /* Wait till PLLI2S is disabled */ 03220 while (READ_BIT(RCC->CR, RCC_CR_PLLI2SRDY) != RESET) 03221 { 03222 if ((HAL_GetTick() - tickstart) > PLLI2S_TIMEOUT_VALUE) 03223 { 03224 return HAL_TIMEOUT; 03225 } 03226 } 03227 #endif /* RCC_PLLI2S_SUPPORT */ 03228 03229 #if defined(RCC_PLLSAI_SUPPORT) 03230 /* Get Start Tick */ 03231 tickstart = HAL_GetTick(); 03232 03233 /* Reset PLLSAI bit */ 03234 CLEAR_BIT(RCC->CR, RCC_CR_PLLSAION); 03235 03236 /* Wait till PLLSAI is disabled */ 03237 while (READ_BIT(RCC->CR, RCC_CR_PLLSAIRDY) != RESET) 03238 { 03239 if ((HAL_GetTick() - tickstart) > PLLSAI_TIMEOUT_VALUE) 03240 { 03241 return HAL_TIMEOUT; 03242 } 03243 } 03244 #endif /* RCC_PLLSAI_SUPPORT */ 03245 03246 /* Once PLL, PLLI2S and PLLSAI are OFF, reset PLLCFGR register to default value */ 03247 #if defined(STM32F412Cx) || defined(STM32F412Rx) || defined(STM32F412Vx) || defined(STM32F412Zx) || defined(STM32F413xx) || \ 03248 defined(STM32F423xx) || defined(STM32F446xx) || defined(STM32F469xx) || defined(STM32F479xx) 03249 RCC->PLLCFGR = RCC_PLLCFGR_PLLM_4 | RCC_PLLCFGR_PLLN_6 | RCC_PLLCFGR_PLLN_7 | RCC_PLLCFGR_PLLQ_2 | RCC_PLLCFGR_PLLR_1; 03250 #elif defined(STM32F410Tx) || defined(STM32F410Cx) || defined(STM32F410Rx) 03251 RCC->PLLCFGR = RCC_PLLCFGR_PLLR_0 | RCC_PLLCFGR_PLLR_1 | RCC_PLLCFGR_PLLR_2 | RCC_PLLCFGR_PLLM_4 | RCC_PLLCFGR_PLLN_6 | RCC_PLLCFGR_PLLN_7 | RCC_PLLCFGR_PLLQ_0 | RCC_PLLCFGR_PLLQ_1 | RCC_PLLCFGR_PLLQ_2 | RCC_PLLCFGR_PLLQ_3; 03252 #else 03253 RCC->PLLCFGR = RCC_PLLCFGR_PLLM_4 | RCC_PLLCFGR_PLLN_6 | RCC_PLLCFGR_PLLN_7 | RCC_PLLCFGR_PLLQ_2; 03254 #endif /* STM32F412Cx || STM32F412Rx || STM32F412Vx || STM32F412Zx || STM32F413xx || STM32F423xx || STM32F446xx || STM32F469xx || STM32F479xx */ 03255 03256 /* Reset PLLI2SCFGR register to default value */ 03257 #if defined(STM32F412Cx) || defined(STM32F412Rx) || defined(STM32F412Vx) || defined(STM32F412Zx) || defined(STM32F413xx) || \ 03258 defined(STM32F423xx) || defined(STM32F446xx) 03259 RCC->PLLI2SCFGR = RCC_PLLI2SCFGR_PLLI2SM_4 | RCC_PLLI2SCFGR_PLLI2SN_6 | RCC_PLLI2SCFGR_PLLI2SN_7 | RCC_PLLI2SCFGR_PLLI2SQ_2 | RCC_PLLI2SCFGR_PLLI2SR_1; 03260 #elif defined(STM32F401xC) || defined(STM32F401xE) || defined(STM32F405xx) || defined(STM32F415xx) || defined(STM32F407xx) || defined(STM32F417xx) 03261 RCC->PLLI2SCFGR = RCC_PLLI2SCFGR_PLLI2SN_6 | RCC_PLLI2SCFGR_PLLI2SN_7 | RCC_PLLI2SCFGR_PLLI2SR_1; 03262 #elif defined(STM32F427xx) || defined(STM32F437xx) || defined(STM32F429xx) || defined(STM32F439xx) || defined(STM32F469xx) || defined(STM32F479xx) 03263 RCC->PLLI2SCFGR = RCC_PLLI2SCFGR_PLLI2SN_6 | RCC_PLLI2SCFGR_PLLI2SN_7 | RCC_PLLI2SCFGR_PLLI2SQ_2 | RCC_PLLI2SCFGR_PLLI2SR_1; 03264 #elif defined(STM32F411xE) 03265 RCC->PLLI2SCFGR = RCC_PLLI2SCFGR_PLLI2SM_4 | RCC_PLLI2SCFGR_PLLI2SN_6 | RCC_PLLI2SCFGR_PLLI2SN_7 | RCC_PLLI2SCFGR_PLLI2SR_1; 03266 #endif /* STM32F412Cx || STM32F412Rx || STM32F412Vx || STM32F412Zx || STM32F413xx || STM32F423xx || STM32F446xx */ 03267 03268 /* Reset PLLSAICFGR register */ 03269 #if defined(STM32F427xx) || defined(STM32F429xx) || defined(STM32F437xx) || defined(STM32F439xx) || defined(STM32F469xx) || defined(STM32F479xx) 03270 RCC->PLLSAICFGR = RCC_PLLSAICFGR_PLLSAIN_6 | RCC_PLLSAICFGR_PLLSAIN_7 | RCC_PLLSAICFGR_PLLSAIQ_2 | RCC_PLLSAICFGR_PLLSAIR_1; 03271 #elif defined(STM32F446xx) 03272 RCC->PLLSAICFGR = RCC_PLLSAICFGR_PLLSAIM_4 | RCC_PLLSAICFGR_PLLSAIN_6 | RCC_PLLSAICFGR_PLLSAIN_7 | RCC_PLLSAICFGR_PLLSAIQ_2; 03273 #endif /* STM32F427xx || STM32F429xx || STM32F437xx || STM32F439xx || STM32F469xx || STM32F479xx */ 03274 03275 /* Disable all interrupts */ 03276 CLEAR_BIT(RCC->CIR, RCC_CIR_LSIRDYIE | RCC_CIR_LSERDYIE | RCC_CIR_HSIRDYIE | RCC_CIR_HSERDYIE | RCC_CIR_PLLRDYIE); 03277 03278 #if defined(RCC_CIR_PLLI2SRDYIE) 03279 CLEAR_BIT(RCC->CIR, RCC_CIR_PLLI2SRDYIE); 03280 #endif /* RCC_CIR_PLLI2SRDYIE */ 03281 03282 #if defined(RCC_CIR_PLLSAIRDYIE) 03283 CLEAR_BIT(RCC->CIR, RCC_CIR_PLLSAIRDYIE); 03284 #endif /* RCC_CIR_PLLSAIRDYIE */ 03285 03286 /* Clear all interrupt flags */ 03287 SET_BIT(RCC->CIR, RCC_CIR_LSIRDYC | RCC_CIR_LSERDYC | RCC_CIR_HSIRDYC | RCC_CIR_HSERDYC | RCC_CIR_PLLRDYC | RCC_CIR_CSSC); 03288 03289 #if defined(RCC_CIR_PLLI2SRDYC) 03290 SET_BIT(RCC->CIR, RCC_CIR_PLLI2SRDYC); 03291 #endif /* RCC_CIR_PLLI2SRDYC */ 03292 03293 #if defined(RCC_CIR_PLLSAIRDYC) 03294 SET_BIT(RCC->CIR, RCC_CIR_PLLSAIRDYC); 03295 #endif /* RCC_CIR_PLLSAIRDYC */ 03296 03297 /* Clear LSION bit */ 03298 CLEAR_BIT(RCC->CSR, RCC_CSR_LSION); 03299 03300 /* Reset all CSR flags */ 03301 SET_BIT(RCC->CSR, RCC_CSR_RMVF); 03302 03303 /* Update the SystemCoreClock global variable */ 03304 SystemCoreClock = HSI_VALUE; 03305 03306 /* Adapt Systick interrupt period */ 03307 if(HAL_InitTick(uwTickPrio) != HAL_OK) 03308 { 03309 return HAL_ERROR; 03310 } 03311 else 03312 { 03313 return HAL_OK; 03314 } 03315 } 03316 03317 #if defined(STM32F410Tx) || defined(STM32F410Cx) || defined(STM32F410Rx) || defined(STM32F446xx) || defined(STM32F469xx) || defined(STM32F479xx) || defined(STM32F412Zx) ||\ 03318 defined(STM32F412Vx) || defined(STM32F412Rx) || defined(STM32F412Cx) || defined(STM32F413xx) || defined(STM32F423xx) 03319 /** 03320 * @brief Initializes the RCC Oscillators according to the specified parameters in the 03321 * RCC_OscInitTypeDef. 03322 * @param RCC_OscInitStruct pointer to an RCC_OscInitTypeDef structure that 03323 * contains the configuration information for the RCC Oscillators. 03324 * @note The PLL is not disabled when used as system clock. 03325 * @note Transitions LSE Bypass to LSE On and LSE On to LSE Bypass are not 03326 * supported by this API. User should request a transition to LSE Off 03327 * first and then LSE On or LSE Bypass. 03328 * @note Transition HSE Bypass to HSE On and HSE On to HSE Bypass are not 03329 * supported by this API. User should request a transition to HSE Off 03330 * first and then HSE On or HSE Bypass. 03331 * @note This function add the PLL/PLLR factor management during PLL configuration this feature 03332 * is only available in STM32F410xx/STM32F446xx/STM32F469xx/STM32F479xx/STM32F412Zx/STM32F412Vx/STM32F412Rx/STM32F412Cx devices 03333 * @retval HAL status 03334 */ 03335 HAL_StatusTypeDef HAL_RCC_OscConfig(RCC_OscInitTypeDef *RCC_OscInitStruct) 03336 { 03337 uint32_t tickstart, pll_config; 03338 03339 /* Check Null pointer */ 03340 if(RCC_OscInitStruct == NULL) 03341 { 03342 return HAL_ERROR; 03343 } 03344 03345 /* Check the parameters */ 03346 assert_param(IS_RCC_OSCILLATORTYPE(RCC_OscInitStruct->OscillatorType)); 03347 /*------------------------------- HSE Configuration ------------------------*/ 03348 if(((RCC_OscInitStruct->OscillatorType) & RCC_OSCILLATORTYPE_HSE) == RCC_OSCILLATORTYPE_HSE) 03349 { 03350 /* Check the parameters */ 03351 assert_param(IS_RCC_HSE(RCC_OscInitStruct->HSEState)); 03352 /* When the HSE is used as system clock or clock source for PLL in these cases HSE will not disabled */ 03353 #if defined(STM32F446xx) 03354 if((__HAL_RCC_GET_SYSCLK_SOURCE() == RCC_CFGR_SWS_HSE) ||\ 03355 ((__HAL_RCC_GET_SYSCLK_SOURCE() == RCC_CFGR_SWS_PLL) && ((RCC->PLLCFGR & RCC_PLLCFGR_PLLSRC) == RCC_PLLCFGR_PLLSRC_HSE)) ||\ 03356 ((__HAL_RCC_GET_SYSCLK_SOURCE() == RCC_CFGR_SWS_PLLR) && ((RCC->PLLCFGR & RCC_PLLCFGR_PLLSRC) == RCC_PLLCFGR_PLLSRC_HSE))) 03357 #else 03358 if((__HAL_RCC_GET_SYSCLK_SOURCE() == RCC_CFGR_SWS_HSE) ||\ 03359 ((__HAL_RCC_GET_SYSCLK_SOURCE() == RCC_CFGR_SWS_PLL) && ((RCC->PLLCFGR & RCC_PLLCFGR_PLLSRC) == RCC_PLLCFGR_PLLSRC_HSE))) 03360 #endif /* STM32F446xx */ 03361 { 03362 if((__HAL_RCC_GET_FLAG(RCC_FLAG_HSERDY) != RESET) && (RCC_OscInitStruct->HSEState == RCC_HSE_OFF)) 03363 { 03364 return HAL_ERROR; 03365 } 03366 } 03367 else 03368 { 03369 /* Set the new HSE configuration ---------------------------------------*/ 03370 __HAL_RCC_HSE_CONFIG(RCC_OscInitStruct->HSEState); 03371 03372 /* Check the HSE State */ 03373 if((RCC_OscInitStruct->HSEState) != RCC_HSE_OFF) 03374 { 03375 /* Get Start Tick*/ 03376 tickstart = HAL_GetTick(); 03377 03378 /* Wait till HSE is ready */ 03379 while(__HAL_RCC_GET_FLAG(RCC_FLAG_HSERDY) == RESET) 03380 { 03381 if((HAL_GetTick() - tickstart ) > HSE_TIMEOUT_VALUE) 03382 { 03383 return HAL_TIMEOUT; 03384 } 03385 } 03386 } 03387 else 03388 { 03389 /* Get Start Tick*/ 03390 tickstart = HAL_GetTick(); 03391 03392 /* Wait till HSE is bypassed or disabled */ 03393 while(__HAL_RCC_GET_FLAG(RCC_FLAG_HSERDY) != RESET) 03394 { 03395 if((HAL_GetTick() - tickstart ) > HSE_TIMEOUT_VALUE) 03396 { 03397 return HAL_TIMEOUT; 03398 } 03399 } 03400 } 03401 } 03402 } 03403 /*----------------------------- HSI Configuration --------------------------*/ 03404 if(((RCC_OscInitStruct->OscillatorType) & RCC_OSCILLATORTYPE_HSI) == RCC_OSCILLATORTYPE_HSI) 03405 { 03406 /* Check the parameters */ 03407 assert_param(IS_RCC_HSI(RCC_OscInitStruct->HSIState)); 03408 assert_param(IS_RCC_CALIBRATION_VALUE(RCC_OscInitStruct->HSICalibrationValue)); 03409 03410 /* Check if HSI is used as system clock or as PLL source when PLL is selected as system clock */ 03411 #if defined(STM32F446xx) 03412 if((__HAL_RCC_GET_SYSCLK_SOURCE() == RCC_CFGR_SWS_HSI) ||\ 03413 ((__HAL_RCC_GET_SYSCLK_SOURCE() == RCC_CFGR_SWS_PLL) && ((RCC->PLLCFGR & RCC_PLLCFGR_PLLSRC) == RCC_PLLCFGR_PLLSRC_HSI)) ||\ 03414 ((__HAL_RCC_GET_SYSCLK_SOURCE() == RCC_CFGR_SWS_PLLR) && ((RCC->PLLCFGR & RCC_PLLCFGR_PLLSRC) == RCC_PLLCFGR_PLLSRC_HSI))) 03415 #else 03416 if((__HAL_RCC_GET_SYSCLK_SOURCE() == RCC_CFGR_SWS_HSI) ||\ 03417 ((__HAL_RCC_GET_SYSCLK_SOURCE() == RCC_CFGR_SWS_PLL) && ((RCC->PLLCFGR & RCC_PLLCFGR_PLLSRC) == RCC_PLLCFGR_PLLSRC_HSI))) 03418 #endif /* STM32F446xx */ 03419 { 03420 /* When HSI is used as system clock it will not disabled */ 03421 if((__HAL_RCC_GET_FLAG(RCC_FLAG_HSIRDY) != RESET) && (RCC_OscInitStruct->HSIState != RCC_HSI_ON)) 03422 { 03423 return HAL_ERROR; 03424 } 03425 /* Otherwise, just the calibration is allowed */ 03426 else 03427 { 03428 /* Adjusts the Internal High Speed oscillator (HSI) calibration value.*/ 03429 __HAL_RCC_HSI_CALIBRATIONVALUE_ADJUST(RCC_OscInitStruct->HSICalibrationValue); 03430 } 03431 } 03432 else 03433 { 03434 /* Check the HSI State */ 03435 if((RCC_OscInitStruct->HSIState)!= RCC_HSI_OFF) 03436 { 03437 /* Enable the Internal High Speed oscillator (HSI). */ 03438 __HAL_RCC_HSI_ENABLE(); 03439 03440 /* Get Start Tick*/ 03441 tickstart = HAL_GetTick(); 03442 03443 /* Wait till HSI is ready */ 03444 while(__HAL_RCC_GET_FLAG(RCC_FLAG_HSIRDY) == RESET) 03445 { 03446 if((HAL_GetTick() - tickstart ) > HSI_TIMEOUT_VALUE) 03447 { 03448 return HAL_TIMEOUT; 03449 } 03450 } 03451 03452 /* Adjusts the Internal High Speed oscillator (HSI) calibration value.*/ 03453 __HAL_RCC_HSI_CALIBRATIONVALUE_ADJUST(RCC_OscInitStruct->HSICalibrationValue); 03454 } 03455 else 03456 { 03457 /* Disable the Internal High Speed oscillator (HSI). */ 03458 __HAL_RCC_HSI_DISABLE(); 03459 03460 /* Get Start Tick*/ 03461 tickstart = HAL_GetTick(); 03462 03463 /* Wait till HSI is ready */ 03464 while(__HAL_RCC_GET_FLAG(RCC_FLAG_HSIRDY) != RESET) 03465 { 03466 if((HAL_GetTick() - tickstart ) > HSI_TIMEOUT_VALUE) 03467 { 03468 return HAL_TIMEOUT; 03469 } 03470 } 03471 } 03472 } 03473 } 03474 /*------------------------------ LSI Configuration -------------------------*/ 03475 if(((RCC_OscInitStruct->OscillatorType) & RCC_OSCILLATORTYPE_LSI) == RCC_OSCILLATORTYPE_LSI) 03476 { 03477 /* Check the parameters */ 03478 assert_param(IS_RCC_LSI(RCC_OscInitStruct->LSIState)); 03479 03480 /* Check the LSI State */ 03481 if((RCC_OscInitStruct->LSIState)!= RCC_LSI_OFF) 03482 { 03483 /* Enable the Internal Low Speed oscillator (LSI). */ 03484 __HAL_RCC_LSI_ENABLE(); 03485 03486 /* Get Start Tick*/ 03487 tickstart = HAL_GetTick(); 03488 03489 /* Wait till LSI is ready */ 03490 while(__HAL_RCC_GET_FLAG(RCC_FLAG_LSIRDY) == RESET) 03491 { 03492 if((HAL_GetTick() - tickstart ) > LSI_TIMEOUT_VALUE) 03493 { 03494 return HAL_TIMEOUT; 03495 } 03496 } 03497 } 03498 else 03499 { 03500 /* Disable the Internal Low Speed oscillator (LSI). */ 03501 __HAL_RCC_LSI_DISABLE(); 03502 03503 /* Get Start Tick*/ 03504 tickstart = HAL_GetTick(); 03505 03506 /* Wait till LSI is ready */ 03507 while(__HAL_RCC_GET_FLAG(RCC_FLAG_LSIRDY) != RESET) 03508 { 03509 if((HAL_GetTick() - tickstart ) > LSI_TIMEOUT_VALUE) 03510 { 03511 return HAL_TIMEOUT; 03512 } 03513 } 03514 } 03515 } 03516 /*------------------------------ LSE Configuration -------------------------*/ 03517 if(((RCC_OscInitStruct->OscillatorType) & RCC_OSCILLATORTYPE_LSE) == RCC_OSCILLATORTYPE_LSE) 03518 { 03519 FlagStatus pwrclkchanged = RESET; 03520 03521 /* Check the parameters */ 03522 assert_param(IS_RCC_LSE(RCC_OscInitStruct->LSEState)); 03523 03524 /* Update LSE configuration in Backup Domain control register */ 03525 /* Requires to enable write access to Backup Domain of necessary */ 03526 if(__HAL_RCC_PWR_IS_CLK_DISABLED()) 03527 { 03528 __HAL_RCC_PWR_CLK_ENABLE(); 03529 pwrclkchanged = SET; 03530 } 03531 03532 if(HAL_IS_BIT_CLR(PWR->CR, PWR_CR_DBP)) 03533 { 03534 /* Enable write access to Backup domain */ 03535 SET_BIT(PWR->CR, PWR_CR_DBP); 03536 03537 /* Wait for Backup domain Write protection disable */ 03538 tickstart = HAL_GetTick(); 03539 03540 while(HAL_IS_BIT_CLR(PWR->CR, PWR_CR_DBP)) 03541 { 03542 if((HAL_GetTick() - tickstart) > RCC_DBP_TIMEOUT_VALUE) 03543 { 03544 return HAL_TIMEOUT; 03545 } 03546 } 03547 } 03548 03549 /* Set the new LSE configuration -----------------------------------------*/ 03550 __HAL_RCC_LSE_CONFIG(RCC_OscInitStruct->LSEState); 03551 /* Check the LSE State */ 03552 if((RCC_OscInitStruct->LSEState) != RCC_LSE_OFF) 03553 { 03554 /* Get Start Tick*/ 03555 tickstart = HAL_GetTick(); 03556 03557 /* Wait till LSE is ready */ 03558 while(__HAL_RCC_GET_FLAG(RCC_FLAG_LSERDY) == RESET) 03559 { 03560 if((HAL_GetTick() - tickstart ) > RCC_LSE_TIMEOUT_VALUE) 03561 { 03562 return HAL_TIMEOUT; 03563 } 03564 } 03565 } 03566 else 03567 { 03568 /* Get Start Tick*/ 03569 tickstart = HAL_GetTick(); 03570 03571 /* Wait till LSE is ready */ 03572 while(__HAL_RCC_GET_FLAG(RCC_FLAG_LSERDY) != RESET) 03573 { 03574 if((HAL_GetTick() - tickstart ) > RCC_LSE_TIMEOUT_VALUE) 03575 { 03576 return HAL_TIMEOUT; 03577 } 03578 } 03579 } 03580 03581 /* Restore clock configuration if changed */ 03582 if(pwrclkchanged == SET) 03583 { 03584 __HAL_RCC_PWR_CLK_DISABLE(); 03585 } 03586 } 03587 /*-------------------------------- PLL Configuration -----------------------*/ 03588 /* Check the parameters */ 03589 assert_param(IS_RCC_PLL(RCC_OscInitStruct->PLL.PLLState)); 03590 if ((RCC_OscInitStruct->PLL.PLLState) != RCC_PLL_NONE) 03591 { 03592 /* Check if the PLL is used as system clock or not */ 03593 if(__HAL_RCC_GET_SYSCLK_SOURCE() != RCC_CFGR_SWS_PLL) 03594 { 03595 if((RCC_OscInitStruct->PLL.PLLState) == RCC_PLL_ON) 03596 { 03597 /* Check the parameters */ 03598 assert_param(IS_RCC_PLLSOURCE(RCC_OscInitStruct->PLL.PLLSource)); 03599 assert_param(IS_RCC_PLLM_VALUE(RCC_OscInitStruct->PLL.PLLM)); 03600 assert_param(IS_RCC_PLLN_VALUE(RCC_OscInitStruct->PLL.PLLN)); 03601 assert_param(IS_RCC_PLLP_VALUE(RCC_OscInitStruct->PLL.PLLP)); 03602 assert_param(IS_RCC_PLLQ_VALUE(RCC_OscInitStruct->PLL.PLLQ)); 03603 assert_param(IS_RCC_PLLR_VALUE(RCC_OscInitStruct->PLL.PLLR)); 03604 03605 /* Disable the main PLL. */ 03606 __HAL_RCC_PLL_DISABLE(); 03607 03608 /* Get Start Tick*/ 03609 tickstart = HAL_GetTick(); 03610 03611 /* Wait till PLL is ready */ 03612 while(__HAL_RCC_GET_FLAG(RCC_FLAG_PLLRDY) != RESET) 03613 { 03614 if((HAL_GetTick() - tickstart ) > PLL_TIMEOUT_VALUE) 03615 { 03616 return HAL_TIMEOUT; 03617 } 03618 } 03619 03620 /* Configure the main PLL clock source, multiplication and division factors. */ 03621 WRITE_REG(RCC->PLLCFGR, (RCC_OscInitStruct->PLL.PLLSource | \ 03622 RCC_OscInitStruct->PLL.PLLM | \ 03623 (RCC_OscInitStruct->PLL.PLLN << RCC_PLLCFGR_PLLN_Pos) | \ 03624 (((RCC_OscInitStruct->PLL.PLLP >> 1U) - 1U) << RCC_PLLCFGR_PLLP_Pos) | \ 03625 (RCC_OscInitStruct->PLL.PLLQ << RCC_PLLCFGR_PLLQ_Pos) | \ 03626 (RCC_OscInitStruct->PLL.PLLR << RCC_PLLCFGR_PLLR_Pos))); 03627 /* Enable the main PLL. */ 03628 __HAL_RCC_PLL_ENABLE(); 03629 03630 /* Get Start Tick*/ 03631 tickstart = HAL_GetTick(); 03632 03633 /* Wait till PLL is ready */ 03634 while(__HAL_RCC_GET_FLAG(RCC_FLAG_PLLRDY) == RESET) 03635 { 03636 if((HAL_GetTick() - tickstart ) > PLL_TIMEOUT_VALUE) 03637 { 03638 return HAL_TIMEOUT; 03639 } 03640 } 03641 } 03642 else 03643 { 03644 /* Disable the main PLL. */ 03645 __HAL_RCC_PLL_DISABLE(); 03646 03647 /* Get Start Tick*/ 03648 tickstart = HAL_GetTick(); 03649 03650 /* Wait till PLL is ready */ 03651 while(__HAL_RCC_GET_FLAG(RCC_FLAG_PLLRDY) != RESET) 03652 { 03653 if((HAL_GetTick() - tickstart ) > PLL_TIMEOUT_VALUE) 03654 { 03655 return HAL_TIMEOUT; 03656 } 03657 } 03658 } 03659 } 03660 else 03661 { 03662 /* Check if there is a request to disable the PLL used as System clock source */ 03663 if((RCC_OscInitStruct->PLL.PLLState) == RCC_PLL_OFF) 03664 { 03665 return HAL_ERROR; 03666 } 03667 else 03668 { 03669 /* Do not return HAL_ERROR if request repeats the current configuration */ 03670 pll_config = RCC->PLLCFGR; 03671 #if defined (RCC_PLLCFGR_PLLR) 03672 if (((RCC_OscInitStruct->PLL.PLLState) == RCC_PLL_OFF) || 03673 (READ_BIT(pll_config, RCC_PLLCFGR_PLLSRC) != RCC_OscInitStruct->PLL.PLLSource) || 03674 (READ_BIT(pll_config, RCC_PLLCFGR_PLLM) != (RCC_OscInitStruct->PLL.PLLM) << RCC_PLLCFGR_PLLM_Pos) || 03675 (READ_BIT(pll_config, RCC_PLLCFGR_PLLN) != (RCC_OscInitStruct->PLL.PLLN) << RCC_PLLCFGR_PLLN_Pos) || 03676 (READ_BIT(pll_config, RCC_PLLCFGR_PLLP) != (((RCC_OscInitStruct->PLL.PLLP >> 1U) - 1U)) << RCC_PLLCFGR_PLLP_Pos) || 03677 (READ_BIT(pll_config, RCC_PLLCFGR_PLLQ) != (RCC_OscInitStruct->PLL.PLLQ << RCC_PLLCFGR_PLLQ_Pos)) || 03678 (READ_BIT(pll_config, RCC_PLLCFGR_PLLR) != (RCC_OscInitStruct->PLL.PLLR << RCC_PLLCFGR_PLLR_Pos))) 03679 #else 03680 if (((RCC_OscInitStruct->PLL.PLLState) == RCC_PLL_OFF) || 03681 (READ_BIT(pll_config, RCC_PLLCFGR_PLLSRC) != RCC_OscInitStruct->PLL.PLLSource) || 03682 (READ_BIT(pll_config, RCC_PLLCFGR_PLLM) != (RCC_OscInitStruct->PLL.PLLM) << RCC_PLLCFGR_PLLM_Pos) || 03683 (READ_BIT(pll_config, RCC_PLLCFGR_PLLN) != (RCC_OscInitStruct->PLL.PLLN) << RCC_PLLCFGR_PLLN_Pos) || 03684 (READ_BIT(pll_config, RCC_PLLCFGR_PLLP) != (((RCC_OscInitStruct->PLL.PLLP >> 1U) - 1U)) << RCC_PLLCFGR_PLLP_Pos) || 03685 (READ_BIT(pll_config, RCC_PLLCFGR_PLLQ) != (RCC_OscInitStruct->PLL.PLLQ << RCC_PLLCFGR_PLLQ_Pos))) 03686 #endif 03687 { 03688 return HAL_ERROR; 03689 } 03690 } 03691 } 03692 } 03693 return HAL_OK; 03694 } 03695 03696 /** 03697 * @brief Configures the RCC_OscInitStruct according to the internal 03698 * RCC configuration registers. 03699 * @param RCC_OscInitStruct pointer to an RCC_OscInitTypeDef structure that will be configured. 03700 * 03701 * @note This function is only available in case of STM32F410xx/STM32F446xx/STM32F469xx/STM32F479xx/STM32F412Zx/STM32F412Vx/STM32F412Rx/STM32F412Cx devices. 03702 * @note This function add the PLL/PLLR factor management 03703 * @retval None 03704 */ 03705 void HAL_RCC_GetOscConfig(RCC_OscInitTypeDef *RCC_OscInitStruct) 03706 { 03707 /* Set all possible values for the Oscillator type parameter ---------------*/ 03708 RCC_OscInitStruct->OscillatorType = RCC_OSCILLATORTYPE_HSE | RCC_OSCILLATORTYPE_HSI | RCC_OSCILLATORTYPE_LSE | RCC_OSCILLATORTYPE_LSI; 03709 03710 /* Get the HSE configuration -----------------------------------------------*/ 03711 if((RCC->CR &RCC_CR_HSEBYP) == RCC_CR_HSEBYP) 03712 { 03713 RCC_OscInitStruct->HSEState = RCC_HSE_BYPASS; 03714 } 03715 else if((RCC->CR &RCC_CR_HSEON) == RCC_CR_HSEON) 03716 { 03717 RCC_OscInitStruct->HSEState = RCC_HSE_ON; 03718 } 03719 else 03720 { 03721 RCC_OscInitStruct->HSEState = RCC_HSE_OFF; 03722 } 03723 03724 /* Get the HSI configuration -----------------------------------------------*/ 03725 if((RCC->CR &RCC_CR_HSION) == RCC_CR_HSION) 03726 { 03727 RCC_OscInitStruct->HSIState = RCC_HSI_ON; 03728 } 03729 else 03730 { 03731 RCC_OscInitStruct->HSIState = RCC_HSI_OFF; 03732 } 03733 03734 RCC_OscInitStruct->HSICalibrationValue = (uint32_t)((RCC->CR &RCC_CR_HSITRIM) >> RCC_CR_HSITRIM_Pos); 03735 03736 /* Get the LSE configuration -----------------------------------------------*/ 03737 if((RCC->BDCR &RCC_BDCR_LSEBYP) == RCC_BDCR_LSEBYP) 03738 { 03739 RCC_OscInitStruct->LSEState = RCC_LSE_BYPASS; 03740 } 03741 else if((RCC->BDCR &RCC_BDCR_LSEON) == RCC_BDCR_LSEON) 03742 { 03743 RCC_OscInitStruct->LSEState = RCC_LSE_ON; 03744 } 03745 else 03746 { 03747 RCC_OscInitStruct->LSEState = RCC_LSE_OFF; 03748 } 03749 03750 /* Get the LSI configuration -----------------------------------------------*/ 03751 if((RCC->CSR &RCC_CSR_LSION) == RCC_CSR_LSION) 03752 { 03753 RCC_OscInitStruct->LSIState = RCC_LSI_ON; 03754 } 03755 else 03756 { 03757 RCC_OscInitStruct->LSIState = RCC_LSI_OFF; 03758 } 03759 03760 /* Get the PLL configuration -----------------------------------------------*/ 03761 if((RCC->CR &RCC_CR_PLLON) == RCC_CR_PLLON) 03762 { 03763 RCC_OscInitStruct->PLL.PLLState = RCC_PLL_ON; 03764 } 03765 else 03766 { 03767 RCC_OscInitStruct->PLL.PLLState = RCC_PLL_OFF; 03768 } 03769 RCC_OscInitStruct->PLL.PLLSource = (uint32_t)(RCC->PLLCFGR & RCC_PLLCFGR_PLLSRC); 03770 RCC_OscInitStruct->PLL.PLLM = (uint32_t)(RCC->PLLCFGR & RCC_PLLCFGR_PLLM); 03771 RCC_OscInitStruct->PLL.PLLN = (uint32_t)((RCC->PLLCFGR & RCC_PLLCFGR_PLLN) >> RCC_PLLCFGR_PLLN_Pos); 03772 RCC_OscInitStruct->PLL.PLLP = (uint32_t)((((RCC->PLLCFGR & RCC_PLLCFGR_PLLP) + RCC_PLLCFGR_PLLP_0) << 1U) >> RCC_PLLCFGR_PLLP_Pos); 03773 RCC_OscInitStruct->PLL.PLLQ = (uint32_t)((RCC->PLLCFGR & RCC_PLLCFGR_PLLQ) >> RCC_PLLCFGR_PLLQ_Pos); 03774 RCC_OscInitStruct->PLL.PLLR = (uint32_t)((RCC->PLLCFGR & RCC_PLLCFGR_PLLR) >> RCC_PLLCFGR_PLLR_Pos); 03775 } 03776 #endif /* STM32F410xx || STM32F446xx || STM32F469xx || STM32F479xx || STM32F412Zx || STM32F412Vx || STM32F412Rx || STM32F412Cx || STM32F413xx || STM32F423xx */ 03777 03778 #endif /* HAL_RCC_MODULE_ENABLED */ 03779 /** 03780 * @} 03781 */ 03782 03783 /** 03784 * @} 03785 */ 03786 03787 /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/