Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal_rcc_ex.c (30352B)
1 /** 2 ****************************************************************************** 3 * @file stm32f1xx_hal_rcc_ex.c 4 * @author MCD Application Team 5 * @brief Extended RCC HAL module driver. 6 * This file provides firmware functions to manage the following 7 * functionalities RCC extension peripheral: 8 * + Extended Peripheral Control functions 9 * 10 ****************************************************************************** 11 * @attention 12 * 13 * Copyright (c) 2016 STMicroelectronics. 14 * All rights reserved. 15 * 16 * This software is licensed under terms that can be found in the LICENSE file in 17 * the root directory of this software component. 18 * If no LICENSE file comes with this software, it is provided AS-IS. 19 ****************************************************************************** 20 */ 21 22 /* Includes ------------------------------------------------------------------*/ 23 #include "stm32f1xx_hal.h" 24 25 /** @addtogroup STM32F1xx_HAL_Driver 26 * @{ 27 */ 28 29 #ifdef HAL_RCC_MODULE_ENABLED 30 31 /** @defgroup RCCEx RCCEx 32 * @brief RCC Extension HAL module driver. 33 * @{ 34 */ 35 36 /* Private typedef -----------------------------------------------------------*/ 37 /* Private define ------------------------------------------------------------*/ 38 /** @defgroup RCCEx_Private_Constants RCCEx Private Constants 39 * @{ 40 */ 41 /** 42 * @} 43 */ 44 45 /* Private macro -------------------------------------------------------------*/ 46 /** @defgroup RCCEx_Private_Macros RCCEx Private Macros 47 * @{ 48 */ 49 /** 50 * @} 51 */ 52 53 /* Private variables ---------------------------------------------------------*/ 54 /* Private function prototypes -----------------------------------------------*/ 55 /* Private functions ---------------------------------------------------------*/ 56 57 /** @defgroup RCCEx_Exported_Functions RCCEx Exported Functions 58 * @{ 59 */ 60 61 /** @defgroup RCCEx_Exported_Functions_Group1 Peripheral Control functions 62 * @brief Extended Peripheral Control functions 63 * 64 @verbatim 65 =============================================================================== 66 ##### Extended Peripheral Control functions ##### 67 =============================================================================== 68 [..] 69 This subsection provides a set of functions allowing to control the RCC Clocks 70 frequencies. 71 [..] 72 (@) Important note: Care must be taken when HAL_RCCEx_PeriphCLKConfig() is used to 73 select the RTC clock source; in this case the Backup domain will be reset in 74 order to modify the RTC Clock source, as consequence RTC registers (including 75 the backup registers) are set to their reset values. 76 77 @endverbatim 78 * @{ 79 */ 80 81 /** 82 * @brief Initializes the RCC extended peripherals clocks according to the specified parameters in the 83 * RCC_PeriphCLKInitTypeDef. 84 * @param PeriphClkInit pointer to an RCC_PeriphCLKInitTypeDef structure that 85 * contains the configuration information for the Extended Peripherals clocks(RTC clock). 86 * 87 * @note Care must be taken when HAL_RCCEx_PeriphCLKConfig() is used to select 88 * the RTC clock source; in this case the Backup domain will be reset in 89 * order to modify the RTC Clock source, as consequence RTC registers (including 90 * the backup registers) are set to their reset values. 91 * 92 * @note In case of STM32F105xC or STM32F107xC devices, PLLI2S will be enabled if requested on 93 * one of 2 I2S interfaces. When PLLI2S is enabled, you need to call HAL_RCCEx_DisablePLLI2S to 94 * manually disable it. 95 * 96 * @retval HAL status 97 */ 98 HAL_StatusTypeDef HAL_RCCEx_PeriphCLKConfig( 99 RCC_PeriphCLKInitTypeDef *PeriphClkInit) 100 { 101 uint32_t tickstart = 0U, temp_reg = 0U; 102 #if defined(STM32F105xC) || defined(STM32F107xC) 103 uint32_t pllactive = 0U; 104 #endif /* STM32F105xC || STM32F107xC */ 105 106 /* Check the parameters */ 107 assert_param(IS_RCC_PERIPHCLOCK(PeriphClkInit->PeriphClockSelection)); 108 109 /*------------------------------- RTC/LCD Configuration ------------------------*/ 110 if ((((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_RTC) 111 == RCC_PERIPHCLK_RTC)) { 112 FlagStatus pwrclkchanged = RESET; 113 114 /* check for RTC Parameters used to output RTCCLK */ 115 assert_param(IS_RCC_RTCCLKSOURCE(PeriphClkInit->RTCClockSelection)); 116 117 /* As soon as function is called to change RTC clock source, activation of the 118 power domain is done. */ 119 /* Requires to enable write access to Backup Domain of necessary */ 120 if (__HAL_RCC_PWR_IS_CLK_DISABLED()) { 121 __HAL_RCC_PWR_CLK_ENABLE(); 122 pwrclkchanged = SET; 123 } 124 125 if (HAL_IS_BIT_CLR(PWR->CR, PWR_CR_DBP)) { 126 /* Enable write access to Backup domain */ 127 SET_BIT(PWR->CR, PWR_CR_DBP); 128 129 /* Wait for Backup domain Write protection disable */ 130 tickstart = HAL_GetTick(); 131 132 while (HAL_IS_BIT_CLR(PWR->CR, PWR_CR_DBP)) { 133 if ((HAL_GetTick() - tickstart) > RCC_DBP_TIMEOUT_VALUE) { 134 return HAL_TIMEOUT; 135 } 136 } 137 } 138 139 /* Reset the Backup domain only if the RTC Clock source selection is modified from reset value */ 140 temp_reg = (RCC->BDCR & RCC_BDCR_RTCSEL); 141 if ((temp_reg != 0x00000000U) 142 && (temp_reg 143 != (PeriphClkInit->RTCClockSelection & RCC_BDCR_RTCSEL))) { 144 /* Store the content of BDCR register before the reset of Backup Domain */ 145 temp_reg = (RCC->BDCR & ~(RCC_BDCR_RTCSEL)); 146 /* RTC Clock selection can be changed only if the Backup Domain is reset */ 147 __HAL_RCC_BACKUPRESET_FORCE(); 148 __HAL_RCC_BACKUPRESET_RELEASE(); 149 /* Restore the Content of BDCR register */ 150 RCC->BDCR = temp_reg; 151 152 /* Wait for LSERDY if LSE was enabled */ 153 if (HAL_IS_BIT_SET(temp_reg, RCC_BDCR_LSEON)) { 154 /* Get Start Tick */ 155 tickstart = HAL_GetTick(); 156 157 /* Wait till LSE is ready */ 158 while (__HAL_RCC_GET_FLAG(RCC_FLAG_LSERDY) == RESET) { 159 if ((HAL_GetTick() - tickstart) > RCC_LSE_TIMEOUT_VALUE) { 160 return HAL_TIMEOUT; 161 } 162 } 163 } 164 } 165 __HAL_RCC_RTC_CONFIG(PeriphClkInit->RTCClockSelection); 166 167 /* Require to disable power clock if necessary */ 168 if (pwrclkchanged == SET) { 169 __HAL_RCC_PWR_CLK_DISABLE(); 170 } 171 } 172 173 /*------------------------------ ADC clock Configuration ------------------*/ 174 if (((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_ADC) 175 == RCC_PERIPHCLK_ADC) { 176 /* Check the parameters */ 177 assert_param(IS_RCC_ADCPLLCLK_DIV(PeriphClkInit->AdcClockSelection)); 178 179 /* Configure the ADC clock source */ 180 __HAL_RCC_ADC_CONFIG(PeriphClkInit->AdcClockSelection); 181 } 182 183 #if defined(STM32F105xC) || defined(STM32F107xC) 184 /*------------------------------ I2S2 Configuration ------------------------*/ 185 if (((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_I2S2) == RCC_PERIPHCLK_I2S2) 186 { 187 /* Check the parameters */ 188 assert_param(IS_RCC_I2S2CLKSOURCE(PeriphClkInit->I2s2ClockSelection)); 189 190 /* Configure the I2S2 clock source */ 191 __HAL_RCC_I2S2_CONFIG(PeriphClkInit->I2s2ClockSelection); 192 } 193 194 /*------------------------------ I2S3 Configuration ------------------------*/ 195 if (((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_I2S3) == RCC_PERIPHCLK_I2S3) 196 { 197 /* Check the parameters */ 198 assert_param(IS_RCC_I2S3CLKSOURCE(PeriphClkInit->I2s3ClockSelection)); 199 200 /* Configure the I2S3 clock source */ 201 __HAL_RCC_I2S3_CONFIG(PeriphClkInit->I2s3ClockSelection); 202 } 203 204 /*------------------------------ PLL I2S Configuration ----------------------*/ 205 /* Check that PLLI2S need to be enabled */ 206 if (HAL_IS_BIT_SET(RCC->CFGR2, RCC_CFGR2_I2S2SRC) || HAL_IS_BIT_SET(RCC->CFGR2, RCC_CFGR2_I2S3SRC)) 207 { 208 /* Update flag to indicate that PLL I2S should be active */ 209 pllactive = 1; 210 } 211 212 /* Check if PLL I2S need to be enabled */ 213 if (pllactive == 1) 214 { 215 /* Enable PLL I2S only if not active */ 216 if (HAL_IS_BIT_CLR(RCC->CR, RCC_CR_PLL3ON)) 217 { 218 /* Check the parameters */ 219 assert_param(IS_RCC_PLLI2S_MUL(PeriphClkInit->PLLI2S.PLLI2SMUL)); 220 assert_param(IS_RCC_HSE_PREDIV2(PeriphClkInit->PLLI2S.HSEPrediv2Value)); 221 222 /* Prediv2 can be written only when the PLL2 is disabled. */ 223 /* Return an error only if new value is different from the programmed value */ 224 if (HAL_IS_BIT_SET(RCC->CR, RCC_CR_PLL2ON) && \ 225 (__HAL_RCC_HSE_GET_PREDIV2() != PeriphClkInit->PLLI2S.HSEPrediv2Value)) 226 { 227 return HAL_ERROR; 228 } 229 230 /* Configure the HSE prediv2 factor --------------------------------*/ 231 __HAL_RCC_HSE_PREDIV2_CONFIG(PeriphClkInit->PLLI2S.HSEPrediv2Value); 232 233 /* Configure the main PLLI2S multiplication factors. */ 234 __HAL_RCC_PLLI2S_CONFIG(PeriphClkInit->PLLI2S.PLLI2SMUL); 235 236 /* Enable the main PLLI2S. */ 237 __HAL_RCC_PLLI2S_ENABLE(); 238 239 /* Get Start Tick*/ 240 tickstart = HAL_GetTick(); 241 242 /* Wait till PLLI2S is ready */ 243 while (__HAL_RCC_GET_FLAG(RCC_FLAG_PLLI2SRDY) == RESET) 244 { 245 if ((HAL_GetTick() - tickstart) > PLLI2S_TIMEOUT_VALUE) 246 { 247 return HAL_TIMEOUT; 248 } 249 } 250 } 251 else 252 { 253 /* Return an error only if user wants to change the PLLI2SMUL whereas PLLI2S is active */ 254 if (READ_BIT(RCC->CFGR2, RCC_CFGR2_PLL3MUL) != PeriphClkInit->PLLI2S.PLLI2SMUL) 255 { 256 return HAL_ERROR; 257 } 258 } 259 } 260 #endif /* STM32F105xC || STM32F107xC */ 261 262 #if defined(STM32F102x6) || defined(STM32F102xB) || defined(STM32F103x6)\ 263 || defined(STM32F103xB) || defined(STM32F103xE) || defined(STM32F103xG)\ 264 || defined(STM32F105xC) || defined(STM32F107xC) 265 /*------------------------------ USB clock Configuration ------------------*/ 266 if (((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_USB) 267 == RCC_PERIPHCLK_USB) { 268 /* Check the parameters */ 269 assert_param(IS_RCC_USBPLLCLK_DIV(PeriphClkInit->UsbClockSelection)); 270 271 /* Configure the USB clock source */ 272 __HAL_RCC_USB_CONFIG(PeriphClkInit->UsbClockSelection); 273 } 274 #endif /* STM32F102x6 || STM32F102xB || STM32F103x6 || STM32F103xB || STM32F103xE || STM32F103xG || STM32F105xC || STM32F107xC */ 275 276 return HAL_OK; 277 } 278 279 /** 280 * @brief Get the PeriphClkInit according to the internal 281 * RCC configuration registers. 282 * @param PeriphClkInit pointer to an RCC_PeriphCLKInitTypeDef structure that 283 * returns the configuration information for the Extended Peripherals clocks(RTC, I2S, ADC clocks). 284 * @retval None 285 */ 286 void HAL_RCCEx_GetPeriphCLKConfig(RCC_PeriphCLKInitTypeDef *PeriphClkInit) 287 { 288 uint32_t srcclk = 0U; 289 290 /* Set all possible values for the extended clock type parameter------------*/ 291 PeriphClkInit->PeriphClockSelection = RCC_PERIPHCLK_RTC; 292 293 /* Get the RTC configuration -----------------------------------------------*/ 294 srcclk = __HAL_RCC_GET_RTC_SOURCE(); 295 /* Source clock is LSE or LSI*/ 296 PeriphClkInit->RTCClockSelection = srcclk; 297 298 /* Get the ADC clock configuration -----------------------------------------*/ 299 PeriphClkInit->PeriphClockSelection |= RCC_PERIPHCLK_ADC; 300 PeriphClkInit->AdcClockSelection = __HAL_RCC_GET_ADC_SOURCE(); 301 302 #if defined(STM32F105xC) || defined(STM32F107xC) 303 /* Get the I2S2 clock configuration -----------------------------------------*/ 304 PeriphClkInit->PeriphClockSelection |= RCC_PERIPHCLK_I2S2; 305 PeriphClkInit->I2s2ClockSelection = __HAL_RCC_GET_I2S2_SOURCE(); 306 307 /* Get the I2S3 clock configuration -----------------------------------------*/ 308 PeriphClkInit->PeriphClockSelection |= RCC_PERIPHCLK_I2S3; 309 PeriphClkInit->I2s3ClockSelection = __HAL_RCC_GET_I2S3_SOURCE(); 310 311 #endif /* STM32F105xC || STM32F107xC */ 312 313 #if defined(STM32F103xE) || defined(STM32F103xG) 314 /* Get the I2S2 clock configuration -----------------------------------------*/ 315 PeriphClkInit->PeriphClockSelection |= RCC_PERIPHCLK_I2S2; 316 PeriphClkInit->I2s2ClockSelection = RCC_I2S2CLKSOURCE_SYSCLK; 317 318 /* Get the I2S3 clock configuration -----------------------------------------*/ 319 PeriphClkInit->PeriphClockSelection |= RCC_PERIPHCLK_I2S3; 320 PeriphClkInit->I2s3ClockSelection = RCC_I2S3CLKSOURCE_SYSCLK; 321 322 #endif /* STM32F103xE || STM32F103xG */ 323 324 #if defined(STM32F102x6) || defined(STM32F102xB) || defined(STM32F103x6)\ 325 || defined(STM32F103xB) || defined(STM32F103xE) || defined(STM32F103xG)\ 326 || defined(STM32F105xC) || defined(STM32F107xC) 327 /* Get the USB clock configuration -----------------------------------------*/ 328 PeriphClkInit->PeriphClockSelection |= RCC_PERIPHCLK_USB; 329 PeriphClkInit->UsbClockSelection = __HAL_RCC_GET_USB_SOURCE(); 330 #endif /* STM32F102x6 || STM32F102xB || STM32F103x6 || STM32F103xB || STM32F103xE || STM32F103xG || STM32F105xC || STM32F107xC */ 331 } 332 333 /** 334 * @brief Returns the peripheral clock frequency 335 * @note Returns 0 if peripheral clock is unknown 336 * @param PeriphClk Peripheral clock identifier 337 * This parameter can be one of the following values: 338 * @arg @ref RCC_PERIPHCLK_RTC RTC peripheral clock 339 * @arg @ref RCC_PERIPHCLK_ADC ADC peripheral clock 340 @if STM32F103xE 341 * @arg @ref RCC_PERIPHCLK_I2S2 I2S2 peripheral clock 342 * @arg @ref RCC_PERIPHCLK_I2S3 I2S3 peripheral clock 343 * @arg @ref RCC_PERIPHCLK_I2S3 I2S3 peripheral clock 344 @endif 345 @if STM32F103xG 346 * @arg @ref RCC_PERIPHCLK_I2S2 I2S2 peripheral clock 347 * @arg @ref RCC_PERIPHCLK_I2S3 I2S3 peripheral clock 348 * @arg @ref RCC_PERIPHCLK_I2S3 I2S3 peripheral clock 349 * @arg @ref RCC_PERIPHCLK_I2S2 I2S2 peripheral clock 350 @endif 351 @if STM32F105xC 352 * @arg @ref RCC_PERIPHCLK_I2S2 I2S2 peripheral clock 353 * @arg @ref RCC_PERIPHCLK_I2S3 I2S3 peripheral clock 354 * @arg @ref RCC_PERIPHCLK_I2S3 I2S3 peripheral clock 355 * @arg @ref RCC_PERIPHCLK_I2S2 I2S2 peripheral clock 356 * @arg @ref RCC_PERIPHCLK_I2S3 I2S3 peripheral clock 357 * @arg @ref RCC_PERIPHCLK_I2S3 I2S3 peripheral clock 358 * @arg @ref RCC_PERIPHCLK_I2S2 I2S2 peripheral clock 359 * @arg @ref RCC_PERIPHCLK_USB USB peripheral clock 360 @endif 361 @if STM32F107xC 362 * @arg @ref RCC_PERIPHCLK_I2S2 I2S2 peripheral clock 363 * @arg @ref RCC_PERIPHCLK_I2S3 I2S3 peripheral clock 364 * @arg @ref RCC_PERIPHCLK_I2S3 I2S3 peripheral clock 365 * @arg @ref RCC_PERIPHCLK_I2S2 I2S2 peripheral clock 366 * @arg @ref RCC_PERIPHCLK_I2S3 I2S3 peripheral clock 367 * @arg @ref RCC_PERIPHCLK_I2S3 I2S3 peripheral clock 368 * @arg @ref RCC_PERIPHCLK_I2S2 I2S2 peripheral clock 369 * @arg @ref RCC_PERIPHCLK_USB USB peripheral clock 370 @endif 371 @if STM32F102xx 372 * @arg @ref RCC_PERIPHCLK_USB USB peripheral clock 373 @endif 374 @if STM32F103xx 375 * @arg @ref RCC_PERIPHCLK_USB USB peripheral clock 376 @endif 377 * @retval Frequency in Hz (0: means that no available frequency for the peripheral) 378 */ 379 uint32_t HAL_RCCEx_GetPeriphCLKFreq(uint32_t PeriphClk) 380 { 381 #if defined(STM32F105xC) || defined(STM32F107xC) 382 static const uint8_t aPLLMULFactorTable[14U] = {0, 0, 4, 5, 6, 7, 8, 9, 0, 0, 0, 0, 0, 13}; 383 static const uint8_t aPredivFactorTable[16U] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16}; 384 385 uint32_t prediv1 = 0U, pllclk = 0U, pllmul = 0U; 386 uint32_t pll2mul = 0U, pll3mul = 0U, prediv2 = 0U; 387 #endif /* STM32F105xC || STM32F107xC */ 388 #if defined(STM32F102x6) || defined(STM32F102xB) || defined(STM32F103x6) || \ 389 defined(STM32F103xB) || defined(STM32F103xE) || defined(STM32F103xG) 390 static const uint8_t aPLLMULFactorTable[16U] = { 2, 3, 4, 5, 6, 7, 8, 9, 10, 391 11, 12, 13, 14, 15, 16, 16 }; 392 static const uint8_t aPredivFactorTable[2U] = { 1, 2 }; 393 394 uint32_t prediv1 = 0U, pllclk = 0U, pllmul = 0U; 395 #endif /* STM32F102x6 || STM32F102xB || STM32F103x6 || STM32F103xB || STM32F103xE || STM32F103xG */ 396 uint32_t temp_reg = 0U, frequency = 0U; 397 398 /* Check the parameters */ 399 assert_param(IS_RCC_PERIPHCLOCK(PeriphClk)); 400 401 switch (PeriphClk) { 402 #if defined(STM32F102x6) || defined(STM32F102xB) || defined(STM32F103x6)\ 403 || defined(STM32F103xB) || defined(STM32F103xE) || defined(STM32F103xG)\ 404 || defined(STM32F105xC) || defined(STM32F107xC) 405 case RCC_PERIPHCLK_USB: { 406 /* Get RCC configuration ------------------------------------------------------*/ 407 temp_reg = RCC->CFGR; 408 409 /* Check if PLL is enabled */ 410 if (HAL_IS_BIT_SET(RCC->CR, RCC_CR_PLLON)) { 411 pllmul = aPLLMULFactorTable[(uint32_t) (temp_reg & RCC_CFGR_PLLMULL) 412 >> RCC_CFGR_PLLMULL_Pos]; 413 if ((temp_reg & RCC_CFGR_PLLSRC) != RCC_PLLSOURCE_HSI_DIV2) { 414 #if defined(STM32F105xC) || defined(STM32F107xC) || defined(STM32F100xB)\ 415 || defined(STM32F100xE) 416 prediv1 = aPredivFactorTable[(uint32_t)(RCC->CFGR2 & RCC_CFGR2_PREDIV1) >> RCC_CFGR2_PREDIV1_Pos]; 417 #else 418 prediv1 = aPredivFactorTable[(uint32_t) (RCC->CFGR 419 & RCC_CFGR_PLLXTPRE) >> RCC_CFGR_PLLXTPRE_Pos]; 420 #endif /* STM32F105xC || STM32F107xC || STM32F100xB || STM32F100xE */ 421 422 #if defined(STM32F105xC) || defined(STM32F107xC) 423 if (HAL_IS_BIT_SET(RCC->CFGR2, RCC_CFGR2_PREDIV1SRC)) 424 { 425 /* PLL2 selected as Prediv1 source */ 426 /* PLLCLK = PLL2CLK / PREDIV1 * PLLMUL with PLL2CLK = HSE/PREDIV2 * PLL2MUL */ 427 prediv2 = ((RCC->CFGR2 & RCC_CFGR2_PREDIV2) >> RCC_CFGR2_PREDIV2_Pos) + 1; 428 pll2mul = ((RCC->CFGR2 & RCC_CFGR2_PLL2MUL) >> RCC_CFGR2_PLL2MUL_Pos) + 2; 429 pllclk = (uint32_t)((((HSE_VALUE / prediv2) * pll2mul) / prediv1) * pllmul); 430 } 431 else 432 { 433 /* HSE used as PLL clock source : PLLCLK = HSE/PREDIV1 * PLLMUL */ 434 pllclk = (uint32_t)((HSE_VALUE / prediv1) * pllmul); 435 } 436 437 /* If PLLMUL was set to 13 means that it was to cover the case PLLMUL 6.5 (avoid using float) */ 438 /* In this case need to divide pllclk by 2 */ 439 if (pllmul == aPLLMULFactorTable[(uint32_t)(RCC_CFGR_PLLMULL6_5) >> RCC_CFGR_PLLMULL_Pos]) 440 { 441 pllclk = pllclk / 2; 442 } 443 #else 444 if ((temp_reg & RCC_CFGR_PLLSRC) != RCC_PLLSOURCE_HSI_DIV2) { 445 /* HSE used as PLL clock source : PLLCLK = HSE/PREDIV1 * PLLMUL */ 446 pllclk = (uint32_t) ((HSE_VALUE / prediv1) * pllmul); 447 } 448 #endif /* STM32F105xC || STM32F107xC */ 449 } else { 450 /* HSI used as PLL clock source : PLLCLK = HSI/2 * PLLMUL */ 451 pllclk = (uint32_t) ((HSI_VALUE >> 1) * pllmul); 452 } 453 454 /* Calcul of the USB frequency*/ 455 #if defined(STM32F105xC) || defined(STM32F107xC) 456 /* USBCLK = PLLVCO = (2 x PLLCLK) / USB prescaler */ 457 if (__HAL_RCC_GET_USB_SOURCE() == RCC_USBCLKSOURCE_PLL_DIV2) 458 { 459 /* Prescaler of 2 selected for USB */ 460 frequency = pllclk; 461 } 462 else 463 { 464 /* Prescaler of 3 selected for USB */ 465 frequency = (2 * pllclk) / 3; 466 } 467 #else 468 /* USBCLK = PLLCLK / USB prescaler */ 469 if (__HAL_RCC_GET_USB_SOURCE() == RCC_USBCLKSOURCE_PLL) { 470 /* No prescaler selected for USB */ 471 frequency = pllclk; 472 } else { 473 /* Prescaler of 1.5 selected for USB */ 474 frequency = (pllclk * 2) / 3; 475 } 476 #endif 477 } 478 break; 479 } 480 #endif /* STM32F102x6 || STM32F102xB || STM32F103x6 || STM32F103xB || STM32F103xE || STM32F103xG || STM32F105xC || STM32F107xC */ 481 #if defined(STM32F103xE) || defined(STM32F103xG) || defined(STM32F105xC) || defined(STM32F107xC) 482 case RCC_PERIPHCLK_I2S2: 483 { 484 #if defined(STM32F103xE) || defined(STM32F103xG) 485 /* SYSCLK used as source clock for I2S2 */ 486 frequency = HAL_RCC_GetSysClockFreq(); 487 #else 488 if (__HAL_RCC_GET_I2S2_SOURCE() == RCC_I2S2CLKSOURCE_SYSCLK) 489 { 490 /* SYSCLK used as source clock for I2S2 */ 491 frequency = HAL_RCC_GetSysClockFreq(); 492 } 493 else 494 { 495 /* Check if PLLI2S is enabled */ 496 if (HAL_IS_BIT_SET(RCC->CR, RCC_CR_PLL3ON)) 497 { 498 /* PLLI2SVCO = 2 * PLLI2SCLK = 2 * (HSE/PREDIV2 * PLL3MUL) */ 499 prediv2 = ((RCC->CFGR2 & RCC_CFGR2_PREDIV2) >> RCC_CFGR2_PREDIV2_Pos) + 1; 500 pll3mul = ((RCC->CFGR2 & RCC_CFGR2_PLL3MUL) >> RCC_CFGR2_PLL3MUL_Pos) + 2; 501 frequency = (uint32_t)(2 * ((HSE_VALUE / prediv2) * pll3mul)); 502 } 503 } 504 #endif /* STM32F103xE || STM32F103xG */ 505 break; 506 } 507 case RCC_PERIPHCLK_I2S3: 508 { 509 #if defined(STM32F103xE) || defined(STM32F103xG) 510 /* SYSCLK used as source clock for I2S3 */ 511 frequency = HAL_RCC_GetSysClockFreq(); 512 #else 513 if (__HAL_RCC_GET_I2S3_SOURCE() == RCC_I2S3CLKSOURCE_SYSCLK) 514 { 515 /* SYSCLK used as source clock for I2S3 */ 516 frequency = HAL_RCC_GetSysClockFreq(); 517 } 518 else 519 { 520 /* Check if PLLI2S is enabled */ 521 if (HAL_IS_BIT_SET(RCC->CR, RCC_CR_PLL3ON)) 522 { 523 /* PLLI2SVCO = 2 * PLLI2SCLK = 2 * (HSE/PREDIV2 * PLL3MUL) */ 524 prediv2 = ((RCC->CFGR2 & RCC_CFGR2_PREDIV2) >> RCC_CFGR2_PREDIV2_Pos) + 1; 525 pll3mul = ((RCC->CFGR2 & RCC_CFGR2_PLL3MUL) >> RCC_CFGR2_PLL3MUL_Pos) + 2; 526 frequency = (uint32_t)(2 * ((HSE_VALUE / prediv2) * pll3mul)); 527 } 528 } 529 #endif /* STM32F103xE || STM32F103xG */ 530 break; 531 } 532 #endif /* STM32F103xE || STM32F103xG || STM32F105xC || STM32F107xC */ 533 case RCC_PERIPHCLK_RTC: { 534 /* Get RCC BDCR configuration ------------------------------------------------------*/ 535 temp_reg = RCC->BDCR; 536 537 /* Check if LSE is ready if RTC clock selection is LSE */ 538 if (((temp_reg & RCC_BDCR_RTCSEL) == RCC_RTCCLKSOURCE_LSE) 539 && (HAL_IS_BIT_SET(temp_reg, RCC_BDCR_LSERDY))) { 540 frequency = LSE_VALUE; 541 } 542 /* Check if LSI is ready if RTC clock selection is LSI */ 543 else if (((temp_reg & RCC_BDCR_RTCSEL) == RCC_RTCCLKSOURCE_LSI) 544 && (HAL_IS_BIT_SET(RCC->CSR, RCC_CSR_LSIRDY))) { 545 frequency = LSI_VALUE; 546 } else if (((temp_reg & RCC_BDCR_RTCSEL) == RCC_RTCCLKSOURCE_HSE_DIV128) 547 && (HAL_IS_BIT_SET(RCC->CR, RCC_CR_HSERDY))) { 548 frequency = HSE_VALUE / 128U; 549 } 550 /* Clock not enabled for RTC*/ 551 else { 552 /* nothing to do: frequency already initialized to 0U */ 553 } 554 break; 555 } 556 case RCC_PERIPHCLK_ADC: { 557 frequency = 558 HAL_RCC_GetPCLK2Freq() 559 / (((__HAL_RCC_GET_ADC_SOURCE() >> RCC_CFGR_ADCPRE_Pos) 560 + 1) * 2); 561 break; 562 } 563 default: { 564 break; 565 } 566 } 567 return (frequency); 568 } 569 570 /** 571 * @} 572 */ 573 574 #if defined(STM32F105xC) || defined(STM32F107xC) 575 /** @defgroup RCCEx_Exported_Functions_Group2 PLLI2S Management function 576 * @brief PLLI2S Management functions 577 * 578 @verbatim 579 =============================================================================== 580 ##### Extended PLLI2S Management functions ##### 581 =============================================================================== 582 [..] 583 This subsection provides a set of functions allowing to control the PLLI2S 584 activation or deactivation 585 @endverbatim 586 * @{ 587 */ 588 589 /** 590 * @brief Enable PLLI2S 591 * @param PLLI2SInit pointer to an RCC_PLLI2SInitTypeDef structure that 592 * contains the configuration information for the PLLI2S 593 * @note The PLLI2S configuration not modified if used by I2S2 or I2S3 Interface. 594 * @retval HAL status 595 */ 596 HAL_StatusTypeDef HAL_RCCEx_EnablePLLI2S(RCC_PLLI2SInitTypeDef *PLLI2SInit) 597 { 598 uint32_t tickstart = 0U; 599 600 /* Check that PLL I2S has not been already enabled by I2S2 or I2S3*/ 601 if (HAL_IS_BIT_CLR(RCC->CFGR2, RCC_CFGR2_I2S2SRC) && HAL_IS_BIT_CLR(RCC->CFGR2, RCC_CFGR2_I2S3SRC)) 602 { 603 /* Check the parameters */ 604 assert_param(IS_RCC_PLLI2S_MUL(PLLI2SInit->PLLI2SMUL)); 605 assert_param(IS_RCC_HSE_PREDIV2(PLLI2SInit->HSEPrediv2Value)); 606 607 /* Prediv2 can be written only when the PLL2 is disabled. */ 608 /* Return an error only if new value is different from the programmed value */ 609 if (HAL_IS_BIT_SET(RCC->CR, RCC_CR_PLL2ON) && \ 610 (__HAL_RCC_HSE_GET_PREDIV2() != PLLI2SInit->HSEPrediv2Value)) 611 { 612 return HAL_ERROR; 613 } 614 615 /* Disable the main PLLI2S. */ 616 __HAL_RCC_PLLI2S_DISABLE(); 617 618 /* Get Start Tick*/ 619 tickstart = HAL_GetTick(); 620 621 /* Wait till PLLI2S is ready */ 622 while (__HAL_RCC_GET_FLAG(RCC_FLAG_PLLI2SRDY) != RESET) 623 { 624 if ((HAL_GetTick() - tickstart) > PLLI2S_TIMEOUT_VALUE) 625 { 626 return HAL_TIMEOUT; 627 } 628 } 629 630 /* Configure the HSE prediv2 factor --------------------------------*/ 631 __HAL_RCC_HSE_PREDIV2_CONFIG(PLLI2SInit->HSEPrediv2Value); 632 633 634 /* Configure the main PLLI2S multiplication factors. */ 635 __HAL_RCC_PLLI2S_CONFIG(PLLI2SInit->PLLI2SMUL); 636 637 /* Enable the main PLLI2S. */ 638 __HAL_RCC_PLLI2S_ENABLE(); 639 640 /* Get Start Tick*/ 641 tickstart = HAL_GetTick(); 642 643 /* Wait till PLLI2S is ready */ 644 while (__HAL_RCC_GET_FLAG(RCC_FLAG_PLLI2SRDY) == RESET) 645 { 646 if ((HAL_GetTick() - tickstart) > PLLI2S_TIMEOUT_VALUE) 647 { 648 return HAL_TIMEOUT; 649 } 650 } 651 } 652 else 653 { 654 /* PLLI2S cannot be modified as already used by I2S2 or I2S3 */ 655 return HAL_ERROR; 656 } 657 658 return HAL_OK; 659 } 660 661 /** 662 * @brief Disable PLLI2S 663 * @note PLLI2S is not disabled if used by I2S2 or I2S3 Interface. 664 * @retval HAL status 665 */ 666 HAL_StatusTypeDef HAL_RCCEx_DisablePLLI2S(void) 667 { 668 uint32_t tickstart = 0U; 669 670 /* Disable PLL I2S as not requested by I2S2 or I2S3*/ 671 if (HAL_IS_BIT_CLR(RCC->CFGR2, RCC_CFGR2_I2S2SRC) && HAL_IS_BIT_CLR(RCC->CFGR2, RCC_CFGR2_I2S3SRC)) 672 { 673 /* Disable the main PLLI2S. */ 674 __HAL_RCC_PLLI2S_DISABLE(); 675 676 /* Get Start Tick*/ 677 tickstart = HAL_GetTick(); 678 679 /* Wait till PLLI2S is ready */ 680 while (__HAL_RCC_GET_FLAG(RCC_FLAG_PLLI2SRDY) != RESET) 681 { 682 if ((HAL_GetTick() - tickstart) > PLLI2S_TIMEOUT_VALUE) 683 { 684 return HAL_TIMEOUT; 685 } 686 } 687 } 688 else 689 { 690 /* PLLI2S is currently used by I2S2 or I2S3. Cannot be disabled.*/ 691 return HAL_ERROR; 692 } 693 694 return HAL_OK; 695 } 696 697 /** 698 * @} 699 */ 700 701 /** @defgroup RCCEx_Exported_Functions_Group3 PLL2 Management function 702 * @brief PLL2 Management functions 703 * 704 @verbatim 705 =============================================================================== 706 ##### Extended PLL2 Management functions ##### 707 =============================================================================== 708 [..] 709 This subsection provides a set of functions allowing to control the PLL2 710 activation or deactivation 711 @endverbatim 712 * @{ 713 */ 714 715 /** 716 * @brief Enable PLL2 717 * @param PLL2Init pointer to an RCC_PLL2InitTypeDef structure that 718 * contains the configuration information for the PLL2 719 * @note The PLL2 configuration not modified if used indirectly as system clock. 720 * @retval HAL status 721 */ 722 HAL_StatusTypeDef HAL_RCCEx_EnablePLL2(RCC_PLL2InitTypeDef *PLL2Init) 723 { 724 uint32_t tickstart = 0U; 725 726 /* This bit can not be cleared if the PLL2 clock is used indirectly as system 727 clock (i.e. it is used as PLL clock entry that is used as system clock). */ 728 if ((__HAL_RCC_GET_PLL_OSCSOURCE() == RCC_PLLSOURCE_HSE) && \ 729 (__HAL_RCC_GET_SYSCLK_SOURCE() == RCC_SYSCLKSOURCE_STATUS_PLLCLK) && \ 730 ((READ_BIT(RCC->CFGR2, RCC_CFGR2_PREDIV1SRC)) == RCC_CFGR2_PREDIV1SRC_PLL2)) 731 { 732 return HAL_ERROR; 733 } 734 else 735 { 736 /* Check the parameters */ 737 assert_param(IS_RCC_PLL2_MUL(PLL2Init->PLL2MUL)); 738 assert_param(IS_RCC_HSE_PREDIV2(PLL2Init->HSEPrediv2Value)); 739 740 /* Prediv2 can be written only when the PLLI2S is disabled. */ 741 /* Return an error only if new value is different from the programmed value */ 742 if (HAL_IS_BIT_SET(RCC->CR, RCC_CR_PLL3ON) && \ 743 (__HAL_RCC_HSE_GET_PREDIV2() != PLL2Init->HSEPrediv2Value)) 744 { 745 return HAL_ERROR; 746 } 747 748 /* Disable the main PLL2. */ 749 __HAL_RCC_PLL2_DISABLE(); 750 751 /* Get Start Tick*/ 752 tickstart = HAL_GetTick(); 753 754 /* Wait till PLL2 is disabled */ 755 while (__HAL_RCC_GET_FLAG(RCC_FLAG_PLL2RDY) != RESET) 756 { 757 if ((HAL_GetTick() - tickstart) > PLL2_TIMEOUT_VALUE) 758 { 759 return HAL_TIMEOUT; 760 } 761 } 762 763 /* Configure the HSE prediv2 factor --------------------------------*/ 764 __HAL_RCC_HSE_PREDIV2_CONFIG(PLL2Init->HSEPrediv2Value); 765 766 /* Configure the main PLL2 multiplication factors. */ 767 __HAL_RCC_PLL2_CONFIG(PLL2Init->PLL2MUL); 768 769 /* Enable the main PLL2. */ 770 __HAL_RCC_PLL2_ENABLE(); 771 772 /* Get Start Tick*/ 773 tickstart = HAL_GetTick(); 774 775 /* Wait till PLL2 is ready */ 776 while (__HAL_RCC_GET_FLAG(RCC_FLAG_PLL2RDY) == RESET) 777 { 778 if ((HAL_GetTick() - tickstart) > PLL2_TIMEOUT_VALUE) 779 { 780 return HAL_TIMEOUT; 781 } 782 } 783 } 784 785 return HAL_OK; 786 } 787 788 /** 789 * @brief Disable PLL2 790 * @note PLL2 is not disabled if used indirectly as system clock. 791 * @retval HAL status 792 */ 793 HAL_StatusTypeDef HAL_RCCEx_DisablePLL2(void) 794 { 795 uint32_t tickstart = 0U; 796 797 /* This bit can not be cleared if the PLL2 clock is used indirectly as system 798 clock (i.e. it is used as PLL clock entry that is used as system clock). */ 799 if ((__HAL_RCC_GET_PLL_OSCSOURCE() == RCC_PLLSOURCE_HSE) && \ 800 (__HAL_RCC_GET_SYSCLK_SOURCE() == RCC_SYSCLKSOURCE_STATUS_PLLCLK) && \ 801 ((READ_BIT(RCC->CFGR2, RCC_CFGR2_PREDIV1SRC)) == RCC_CFGR2_PREDIV1SRC_PLL2)) 802 { 803 return HAL_ERROR; 804 } 805 else 806 { 807 /* Disable the main PLL2. */ 808 __HAL_RCC_PLL2_DISABLE(); 809 810 /* Get Start Tick*/ 811 tickstart = HAL_GetTick(); 812 813 /* Wait till PLL2 is disabled */ 814 while (__HAL_RCC_GET_FLAG(RCC_FLAG_PLL2RDY) != RESET) 815 { 816 if ((HAL_GetTick() - tickstart) > PLL2_TIMEOUT_VALUE) 817 { 818 return HAL_TIMEOUT; 819 } 820 } 821 } 822 823 return HAL_OK; 824 } 825 826 /** 827 * @} 828 */ 829 #endif /* STM32F105xC || STM32F107xC */ 830 831 /** 832 * @} 833 */ 834 835 /** 836 * @} 837 */ 838 839 #endif /* HAL_RCC_MODULE_ENABLED */ 840 841 /** 842 * @} 843 */ 844
