1 /** 2 ****************************************************************************** 3 * @file stm32f2xx_hal_rcc_ex.c 4 * @author MCD Application Team 5 * @brief Extension 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) 2017 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 23 /* Includes ------------------------------------------------------------------*/ 24 #include "stm32f2xx_hal.h" 25 26 /** @addtogroup STM32F2xx_HAL_Driver 27 * @{ 28 */ 29 30 /** @defgroup RCCEx RCCEx 31 * @brief RCCEx HAL module driver 32 * @{ 33 */ 34 35 #ifdef HAL_RCC_MODULE_ENABLED 36 37 /* Private typedef -----------------------------------------------------------*/ 38 /* Private define ------------------------------------------------------------*/ 39 /** @addtogroup RCCEx_Private_Constants 40 * @{ 41 */ 42 /** 43 * @} 44 */ 45 /* Private macro -------------------------------------------------------------*/ 46 /* Private variables ---------------------------------------------------------*/ 47 /* Private function prototypes -----------------------------------------------*/ 48 /* Private functions ---------------------------------------------------------*/ 49 /** @defgroup RCCEx_Exported_Functions RCCEx Exported Functions 50 * @{ 51 */ 52 53 /** @defgroup RCCEx_Exported_Functions_Group1 Extended Peripheral Control functions 54 * @brief Extended Peripheral Control functions 55 * 56 @verbatim 57 =============================================================================== 58 ##### Extended Peripheral Control functions ##### 59 =============================================================================== 60 [..] 61 This subsection provides a set of functions allowing to control the RCC Clocks 62 frequencies. 63 [..] 64 (@) Important note: Care must be taken when HAL_RCCEx_PeriphCLKConfig() is used to 65 select the RTC clock source; in this case the Backup domain will be reset in 66 order to modify the RTC Clock source, as consequence RTC registers (including 67 the backup registers) and RCC_BDCR register are set to their reset values. 68 69 @endverbatim 70 * @{ 71 */ 72 73 /** 74 * @brief Initializes the RCC extended peripherals clocks according to the specified parameters in the 75 * RCC_PeriphCLKInitTypeDef. 76 * @param PeriphClkInit pointer to an RCC_PeriphCLKInitTypeDef structure that 77 * contains the configuration information for the Extended Peripherals clocks(I2S and RTC clocks). 78 * 79 * @note A caution to be taken when HAL_RCCEx_PeriphCLKConfig() is used to select RTC clock selection, in this case 80 * the Reset of Backup domain will be applied in order to modify the RTC Clock source as consequence all backup 81 * domain (RTC and RCC_BDCR register expect BKPSRAM) will be reset 82 * 83 * @retval HAL status 84 */ HAL_RCCEx_PeriphCLKConfig(RCC_PeriphCLKInitTypeDef * PeriphClkInit)85HAL_StatusTypeDef HAL_RCCEx_PeriphCLKConfig(RCC_PeriphCLKInitTypeDef *PeriphClkInit) 86 { 87 uint32_t tickstart = 0U; 88 uint32_t tmpreg1 = 0U; 89 90 /* Check the parameters */ 91 assert_param(IS_RCC_PERIPHCLOCK(PeriphClkInit->PeriphClockSelection)); 92 93 /*---------------------------- I2S configuration ---------------------------*/ 94 if(((PeriphClkInit->PeriphClockSelection & RCC_PERIPHCLK_I2S) == (RCC_PERIPHCLK_I2S))|| \ 95 (PeriphClkInit->PeriphClockSelection == RCC_PERIPHCLK_PLLI2S)) 96 { 97 /* check for Parameters */ 98 assert_param(IS_RCC_PLLI2SR_VALUE(PeriphClkInit->PLLI2S.PLLI2SR)); 99 assert_param(IS_RCC_PLLI2SN_VALUE(PeriphClkInit->PLLI2S.PLLI2SN)); 100 101 /* Disable the PLLI2S */ 102 __HAL_RCC_PLLI2S_DISABLE(); 103 /* Get tick */ 104 tickstart = HAL_GetTick(); 105 /* Wait till PLLI2S is disabled */ 106 while(__HAL_RCC_GET_FLAG(RCC_FLAG_PLLI2SRDY) != RESET) 107 { 108 if((HAL_GetTick() - tickstart ) > PLLI2S_TIMEOUT_VALUE) 109 { 110 /* return in case of Timeout detected */ 111 return HAL_TIMEOUT; 112 } 113 } 114 /* Configure the PLLI2S division factors */ 115 /* PLLI2S_VCO = f(VCO clock) = f(PLLI2S clock input) * (PLLI2SN/PLLM) */ 116 /* I2SCLK = f(PLLI2S clock output) = f(VCO clock) / PLLI2SR */ 117 __HAL_RCC_PLLI2S_CONFIG(PeriphClkInit->PLLI2S.PLLI2SN , PeriphClkInit->PLLI2S.PLLI2SR); 118 119 /* Enable the PLLI2S */ 120 __HAL_RCC_PLLI2S_ENABLE(); 121 /* Get tick */ 122 tickstart = HAL_GetTick(); 123 /* Wait till PLLI2S is ready */ 124 while(__HAL_RCC_GET_FLAG(RCC_FLAG_PLLI2SRDY) == RESET) 125 { 126 if((HAL_GetTick() - tickstart ) > PLLI2S_TIMEOUT_VALUE) 127 { 128 /* return in case of Timeout detected */ 129 return HAL_TIMEOUT; 130 } 131 } 132 } 133 /*--------------------------------------------------------------------------*/ 134 135 /*---------------------------- RTC configuration ---------------------------*/ 136 if(((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_RTC) == (RCC_PERIPHCLK_RTC)) 137 { 138 /* Check for RTC Parameters used to output RTCCLK */ 139 assert_param(IS_RCC_RTCCLKSOURCE(PeriphClkInit->RTCClockSelection)); 140 141 /* Enable Power Clock*/ 142 __HAL_RCC_PWR_CLK_ENABLE(); 143 144 /* Enable write access to Backup domain */ 145 PWR->CR |= PWR_CR_DBP; 146 147 /* Get tick */ 148 tickstart = HAL_GetTick(); 149 150 while((PWR->CR & PWR_CR_DBP) == RESET) 151 { 152 if((HAL_GetTick() - tickstart ) > RCC_DBP_TIMEOUT_VALUE) 153 { 154 return HAL_TIMEOUT; 155 } 156 } 157 /* Reset the Backup domain only if the RTC Clock source selection is modified from reset value */ 158 tmpreg1 = (RCC->BDCR & RCC_BDCR_RTCSEL); 159 if((tmpreg1 != 0x00000000U) && ((tmpreg1) != (PeriphClkInit->RTCClockSelection & RCC_BDCR_RTCSEL))) 160 { 161 /* Store the content of BDCR register before the reset of Backup Domain */ 162 tmpreg1 = (RCC->BDCR & ~(RCC_BDCR_RTCSEL)); 163 /* RTC Clock selection can be changed only if the Backup Domain is reset */ 164 __HAL_RCC_BACKUPRESET_FORCE(); 165 __HAL_RCC_BACKUPRESET_RELEASE(); 166 /* Restore the Content of BDCR register */ 167 RCC->BDCR = tmpreg1; 168 169 /* Wait for LSE reactivation if LSE was enable prior to Backup Domain reset */ 170 if(HAL_IS_BIT_SET(RCC->BDCR, RCC_BDCR_LSEON)) 171 { 172 /* Get tick */ 173 tickstart = HAL_GetTick(); 174 175 /* Wait till LSE is ready */ 176 while(__HAL_RCC_GET_FLAG(RCC_FLAG_LSERDY) == RESET) 177 { 178 if((HAL_GetTick() - tickstart ) > RCC_LSE_TIMEOUT_VALUE) 179 { 180 return HAL_TIMEOUT; 181 } 182 } 183 } 184 } 185 __HAL_RCC_RTC_CONFIG(PeriphClkInit->RTCClockSelection); 186 } 187 /*--------------------------------------------------------------------------*/ 188 189 return HAL_OK; 190 } 191 192 /** 193 * @brief Configures the RCC_OscInitStruct according to the internal 194 * RCC configuration registers. 195 * @param PeriphClkInit pointer to an RCC_PeriphCLKInitTypeDef structure that 196 * will be configured. 197 * @retval None 198 */ HAL_RCCEx_GetPeriphCLKConfig(RCC_PeriphCLKInitTypeDef * PeriphClkInit)199void HAL_RCCEx_GetPeriphCLKConfig(RCC_PeriphCLKInitTypeDef *PeriphClkInit) 200 { 201 uint32_t tempreg; 202 203 /* Set all possible values for the extended clock type parameter------------*/ 204 PeriphClkInit->PeriphClockSelection = RCC_PERIPHCLK_I2S | RCC_PERIPHCLK_RTC; 205 206 /* Get the PLLI2S Clock configuration --------------------------------------*/ 207 PeriphClkInit->PLLI2S.PLLI2SN = (uint32_t)((RCC->PLLI2SCFGR & RCC_PLLI2SCFGR_PLLI2SN) >> POSITION_VAL(RCC_PLLI2SCFGR_PLLI2SN)); 208 PeriphClkInit->PLLI2S.PLLI2SR = (uint32_t)((RCC->PLLI2SCFGR & RCC_PLLI2SCFGR_PLLI2SR) >> POSITION_VAL(RCC_PLLI2SCFGR_PLLI2SR)); 209 210 /* Get the RTC Clock configuration -----------------------------------------------*/ 211 tempreg = (RCC->CFGR & RCC_CFGR_RTCPRE); 212 PeriphClkInit->RTCClockSelection = (uint32_t)((tempreg) | (RCC->BDCR & RCC_BDCR_RTCSEL)); 213 214 } 215 /** 216 * @} 217 */ 218 219 /** @defgroup RCCEx_Exported_Functions_Group2 Extended Clock management functions 220 * @brief Extended Clock management functions 221 * 222 @verbatim 223 =============================================================================== 224 ##### Extended clock management functions ##### 225 =============================================================================== 226 [..] 227 This subsection provides a set of functions allowing to control the 228 activation or deactivation of PLLI2S. 229 @endverbatim 230 * @{ 231 */ 232 233 /** 234 * @brief Enable PLLI2S. 235 * @param PLLI2SInit pointer to an RCC_PLLI2SInitTypeDef structure that 236 * contains the configuration information for the PLLI2S 237 * @retval HAL status 238 */ HAL_RCCEx_EnablePLLI2S(RCC_PLLI2SInitTypeDef * PLLI2SInit)239HAL_StatusTypeDef HAL_RCCEx_EnablePLLI2S(RCC_PLLI2SInitTypeDef *PLLI2SInit) 240 { 241 uint32_t tickstart; 242 243 /* Check for parameters */ 244 assert_param(IS_RCC_PLLI2SN_VALUE(PLLI2SInit->PLLI2SN)); 245 assert_param(IS_RCC_PLLI2SR_VALUE(PLLI2SInit->PLLI2SR)); 246 247 /* Disable the PLLI2S */ 248 __HAL_RCC_PLLI2S_DISABLE(); 249 250 /* Wait till PLLI2S is disabled */ 251 tickstart = HAL_GetTick(); 252 while(__HAL_RCC_GET_FLAG(RCC_FLAG_PLLI2SRDY) != RESET) 253 { 254 if((HAL_GetTick() - tickstart ) > PLLI2S_TIMEOUT_VALUE) 255 { 256 /* return in case of Timeout detected */ 257 return HAL_TIMEOUT; 258 } 259 } 260 261 /* Configure the PLLI2S division factors */ 262 /* PLLI2S_VCO = f(VCO clock) = f(PLLI2S clock input) x PLLI2SN */ 263 /* I2SRCLK = PLLI2S_VCO / PLLI2SR */ 264 __HAL_RCC_PLLI2S_CONFIG(PLLI2SInit->PLLI2SN, PLLI2SInit->PLLI2SR); 265 266 /* Enable the PLLI2S */ 267 __HAL_RCC_PLLI2S_ENABLE(); 268 269 /* Wait till PLLI2S is ready */ 270 tickstart = HAL_GetTick(); 271 while(__HAL_RCC_GET_FLAG(RCC_FLAG_PLLI2SRDY) == RESET) 272 { 273 if((HAL_GetTick() - tickstart ) > PLLI2S_TIMEOUT_VALUE) 274 { 275 /* return in case of Timeout detected */ 276 return HAL_TIMEOUT; 277 } 278 } 279 280 return HAL_OK; 281 } 282 283 /** 284 * @brief Disable PLLI2S. 285 * @retval HAL status 286 */ HAL_RCCEx_DisablePLLI2S(void)287HAL_StatusTypeDef HAL_RCCEx_DisablePLLI2S(void) 288 { 289 uint32_t tickstart; 290 291 /* Disable the PLLI2S */ 292 __HAL_RCC_PLLI2S_DISABLE(); 293 294 /* Wait till PLLI2S is disabled */ 295 tickstart = HAL_GetTick(); 296 while(READ_BIT(RCC->CR, RCC_CR_PLLI2SRDY) != RESET) 297 { 298 if((HAL_GetTick() - tickstart) > PLLI2S_TIMEOUT_VALUE) 299 { 300 /* return in case of Timeout detected */ 301 return HAL_TIMEOUT; 302 } 303 } 304 305 return HAL_OK; 306 } 307 308 /** 309 * @} 310 */ 311 312 /** 313 * @} 314 */ 315 316 #endif /* HAL_RCC_MODULE_ENABLED */ 317 /** 318 * @} 319 */ 320 321 /** 322 * @} 323 */ 324 325