You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 

555 lines
22 KiB

  1. /**
  2. ******************************************************************************
  3. * @file stm32f4xx_hal_rcc_ex.c
  4. * @author MCD Application Team
  5. * @version V1.1.0
  6. * @date 19-June-2014
  7. * @brief Extension RCC HAL module driver.
  8. * This file provides firmware functions to manage the following
  9. * functionalities RCC extension peripheral:
  10. * + Extended Peripheral Control functions
  11. *
  12. ******************************************************************************
  13. * @attention
  14. *
  15. * <h2><center>&copy; COPYRIGHT(c) 2014 STMicroelectronics</center></h2>
  16. *
  17. * Redistribution and use in source and binary forms, with or without modification,
  18. * are permitted provided that the following conditions are met:
  19. * 1. Redistributions of source code must retain the above copyright notice,
  20. * this list of conditions and the following disclaimer.
  21. * 2. Redistributions in binary form must reproduce the above copyright notice,
  22. * this list of conditions and the following disclaimer in the documentation
  23. * and/or other materials provided with the distribution.
  24. * 3. Neither the name of STMicroelectronics nor the names of its contributors
  25. * may be used to endorse or promote products derived from this software
  26. * without specific prior written permission.
  27. *
  28. * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
  29. * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  30. * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  31. * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
  32. * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
  33. * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
  34. * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
  35. * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
  36. * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
  37. * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  38. *
  39. ******************************************************************************
  40. */
  41. /* Includes ------------------------------------------------------------------*/
  42. #include "stm32f4xx_hal.h"
  43. /** @addtogroup STM32F4xx_HAL_Driver
  44. * @{
  45. */
  46. /** @defgroup RCC
  47. * @brief RCC HAL module driver
  48. * @{
  49. */
  50. #ifdef HAL_RCC_MODULE_ENABLED
  51. /* Private typedef -----------------------------------------------------------*/
  52. /* Private define ------------------------------------------------------------*/
  53. #define PLLI2S_TIMEOUT_VALUE 100 /* Timeout value fixed to 100 ms */
  54. #define PLLSAI_TIMEOUT_VALUE 100 /* Timeout value fixed to 100 ms */
  55. /* Private macro -------------------------------------------------------------*/
  56. /* Private variables ---------------------------------------------------------*/
  57. /* Private function prototypes -----------------------------------------------*/
  58. /* Private functions ---------------------------------------------------------*/
  59. /** @defgroup RCCEx_Private_Functions
  60. * @{
  61. */
  62. /** @defgroup RCCEx_Group1 Extended Peripheral Control functions
  63. * @brief Extended Peripheral Control functions
  64. *
  65. @verbatim
  66. ===============================================================================
  67. ##### Extended Peripheral Control functions #####
  68. ===============================================================================
  69. [..]
  70. This subsection provides a set of functions allowing to control the RCC Clocks
  71. frequencies.
  72. [..]
  73. (@) Important note: Care must be taken when HAL_RCCEx_PeriphCLKConfig() is used to
  74. select the RTC clock source; in this case the Backup domain will be reset in
  75. order to modify the RTC Clock source, as consequence RTC registers (including
  76. the backup registers) and RCC_BDCR register are set to their reset values.
  77. @endverbatim
  78. * @{
  79. */
  80. #if defined(STM32F427xx) || defined(STM32F437xx) || defined(STM32F429xx)|| defined(STM32F439xx)
  81. /**
  82. * @brief Initializes the RCC extended peripherals clocks according to the specified
  83. * parameters in the RCC_PeriphCLKInitTypeDef.
  84. * @param PeriphClkInit: pointer to an RCC_PeriphCLKInitTypeDef structure that
  85. * contains the configuration information for the Extended Peripherals
  86. * clocks(I2S, SAI, LTDC RTC and TIM).
  87. *
  88. * @note Care must be taken when HAL_RCCEx_PeriphCLKConfig() is used to select
  89. * the RTC clock source; in this case the Backup domain will be reset in
  90. * order to modify the RTC Clock source, as consequence RTC registers (including
  91. * the backup registers) and RCC_BDCR register are set to their reset values.
  92. *
  93. * @retval HAL status
  94. */
  95. HAL_StatusTypeDef HAL_RCCEx_PeriphCLKConfig(RCC_PeriphCLKInitTypeDef *PeriphClkInit)
  96. {
  97. uint32_t tickstart = 0;
  98. uint32_t tmpreg = 0;
  99. /* Check the parameters */
  100. assert_param(IS_RCC_PERIPHCLOCK(PeriphClkInit->PeriphClockSelection));
  101. /*----------------------- SAI/I2S Configuration (PLLI2S) -------------------------*/
  102. /*----------------------- Common configuration SAI/I2S ---------------------------*/
  103. /* In Case of SAI or I2S Clock Configuration through PLLI2S, PLLI2SN division
  104. factor is common parameters for both peripherals */
  105. if((((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_I2S) == RCC_PERIPHCLK_I2S) ||
  106. (((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_SAI_PLLI2S) == RCC_PERIPHCLK_SAI_PLLI2S))
  107. {
  108. /* check for Parameters */
  109. assert_param(IS_RCC_PLLI2SN_VALUE(PeriphClkInit->PLLI2S.PLLI2SN));
  110. /* Disable the PLLI2S */
  111. __HAL_RCC_PLLI2S_DISABLE();
  112. /* Get tick */
  113. tickstart = HAL_GetTick();
  114. /* Wait till PLLI2S is disabled */
  115. while(__HAL_RCC_GET_FLAG(RCC_FLAG_PLLI2SRDY) != RESET)
  116. {
  117. if((HAL_GetTick() - tickstart ) > PLLI2S_TIMEOUT_VALUE)
  118. {
  119. /* return in case of Timeout detected */
  120. return HAL_TIMEOUT;
  121. }
  122. }
  123. /*---------------------------- I2S configuration -------------------------------*/
  124. /* In Case of I2S Clock Configuration through PLLI2S, PLLI2SR must be added
  125. only for I2S configuration */
  126. if(((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_I2S) == (RCC_PERIPHCLK_I2S))
  127. {
  128. /* check for Parameters */
  129. assert_param(IS_RCC_PLLI2SR_VALUE(PeriphClkInit->PLLI2S.PLLI2SR));
  130. /* Configure the PLLI2S division factors */
  131. /* PLLI2S_VCO = f(VCO clock) = f(PLLI2S clock input) & (PLLI2SN/PLLM) */
  132. /* I2SCLK = f(PLLI2S clock output) = f(VCO clock) / PLLI2SR */
  133. __HAL_RCC_PLLI2S_CONFIG(PeriphClkInit->PLLI2S.PLLI2SN , PeriphClkInit->PLLI2S.PLLI2SR);
  134. }
  135. /*---------------------------- SAI configuration -------------------------------*/
  136. /* In Case of SAI Clock Configuration through PLLI2S, PLLI2SQ and PLLI2S_DIVQ must
  137. be added only for SAI configuration */
  138. if(((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_SAI_PLLI2S) == (RCC_PERIPHCLK_SAI_PLLI2S))
  139. {
  140. /* Check the PLLI2S division factors */
  141. assert_param(IS_RCC_PLLI2SQ_VALUE(PeriphClkInit->PLLI2S.PLLI2SQ));
  142. assert_param(IS_RCC_PLLI2S_DIVQ_VALUE(PeriphClkInit->PLLI2SDivQ));
  143. /* Read PLLI2SR value from PLLI2SCFGR register (this value is not need for SAI configuration) */
  144. tmpreg = ((RCC->PLLI2SCFGR & RCC_PLLI2SCFGR_PLLI2SR) >> POSITION_VAL(RCC_PLLI2SCFGR_PLLI2SR));
  145. /* Configure the PLLI2S division factors */
  146. /* PLLI2S_VCO Input = PLL_SOURCE/PLLM */
  147. /* PLLI2S_VCO Output = PLLI2S_VCO Input * PLLI2SN */
  148. /* SAI_CLK(first level) = PLLI2S_VCO Output/PLLI2SQ */
  149. __HAL_RCC_PLLI2S_SAICLK_CONFIG(PeriphClkInit->PLLI2S.PLLI2SN , PeriphClkInit->PLLI2S.PLLI2SQ , tmpreg);
  150. /* SAI_CLK_x = SAI_CLK(first level)/PLLI2SDIVQ */
  151. __HAL_RCC_PLLI2S_PLLSAICLKDIVQ_CONFIG(PeriphClkInit->PLLI2SDivQ);
  152. }
  153. /* Enable the PLLI2S */
  154. __HAL_RCC_PLLI2S_ENABLE();
  155. /* Get tick */
  156. tickstart = HAL_GetTick();
  157. /* Wait till PLLI2S is ready */
  158. while(__HAL_RCC_GET_FLAG(RCC_FLAG_PLLI2SRDY) == RESET)
  159. {
  160. if((HAL_GetTick() - tickstart ) > PLLI2S_TIMEOUT_VALUE)
  161. {
  162. /* return in case of Timeout detected */
  163. return HAL_TIMEOUT;
  164. }
  165. }
  166. }
  167. /*----------------------- SAI/LTDC Configuration (PLLSAI) ------------------*/
  168. /*----------------------- Common configuration SAI/LTDC --------------------*/
  169. /* In Case of SAI or LTDC Clock Configuration through PLLSAI, PLLSAIN division
  170. factor is common parameters for both peripherals */
  171. if((((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_SAI_PLLSAI) == RCC_PERIPHCLK_SAI_PLLSAI) ||
  172. (((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_LTDC) == RCC_PERIPHCLK_LTDC))
  173. {
  174. /* Check the PLLSAI division factors */
  175. assert_param(IS_RCC_PLLSAIN_VALUE(PeriphClkInit->PLLSAI.PLLSAIN));
  176. /* Disable PLLSAI Clock */
  177. __HAL_RCC_PLLSAI_DISABLE();
  178. /* Get tick */
  179. tickstart = HAL_GetTick();
  180. /* Wait till PLLSAI is disabled */
  181. while(__HAL_RCC_PLLSAI_GET_FLAG() != RESET)
  182. {
  183. if((HAL_GetTick() - tickstart ) > PLLSAI_TIMEOUT_VALUE)
  184. {
  185. /* return in case of Timeout detected */
  186. return HAL_TIMEOUT;
  187. }
  188. }
  189. /*---------------------------- SAI configuration -------------------------*/
  190. /* In Case of SAI Clock Configuration through PLLSAI, PLLSAIQ and PLLSAI_DIVQ must
  191. be added only for SAI configuration */
  192. if(((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_SAI_PLLSAI) == (RCC_PERIPHCLK_SAI_PLLSAI))
  193. {
  194. assert_param(IS_RCC_PLLSAIQ_VALUE(PeriphClkInit->PLLSAI.PLLSAIQ));
  195. assert_param(IS_RCC_PLLSAI_DIVQ_VALUE(PeriphClkInit->PLLSAIDivQ));
  196. /* Read PLLSAIR value from PLLSAICFGR register (this value is not need for SAI configuration) */
  197. tmpreg = ((RCC->PLLSAICFGR & RCC_PLLSAICFGR_PLLSAIR) >> POSITION_VAL(RCC_PLLSAICFGR_PLLSAIR));
  198. /* PLLSAI_VCO Input = PLL_SOURCE/PLLM */
  199. /* PLLSAI_VCO Output = PLLSAI_VCO Input * PLLSAIN */
  200. /* SAI_CLK(first level) = PLLSAI_VCO Output/PLLSAIQ */
  201. __HAL_RCC_PLLSAI_CONFIG(PeriphClkInit->PLLSAI.PLLSAIN , PeriphClkInit->PLLSAI.PLLSAIQ, tmpreg);
  202. /* SAI_CLK_x = SAI_CLK(first level)/PLLSAIDIVQ */
  203. __HAL_RCC_PLLSAI_PLLSAICLKDIVQ_CONFIG(PeriphClkInit->PLLSAIDivQ);
  204. }
  205. /*---------------------------- LTDC configuration ------------------------*/
  206. if(((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_LTDC) == (RCC_PERIPHCLK_LTDC))
  207. {
  208. assert_param(IS_RCC_PLLSAIR_VALUE(PeriphClkInit->PLLSAI.PLLSAIR));
  209. assert_param(IS_RCC_PLLSAI_DIVR_VALUE(PeriphClkInit->PLLSAIDivR));
  210. /* Read PLLSAIR value from PLLSAICFGR register (this value is not need for SAI configuration) */
  211. tmpreg = ((RCC->PLLSAICFGR & RCC_PLLSAICFGR_PLLSAIQ) >> POSITION_VAL(RCC_PLLSAICFGR_PLLSAIQ));
  212. /* PLLSAI_VCO Input = PLL_SOURCE/PLLM */
  213. /* PLLSAI_VCO Output = PLLSAI_VCO Input * PLLSAIN */
  214. /* LTDC_CLK(first level) = PLLSAI_VCO Output/PLLSAIR */
  215. __HAL_RCC_PLLSAI_CONFIG(PeriphClkInit->PLLSAI.PLLSAIN , tmpreg, PeriphClkInit->PLLSAI.PLLSAIR);
  216. /* LTDC_CLK = LTDC_CLK(first level)/PLLSAIDIVR */
  217. __HAL_RCC_PLLSAI_PLLSAICLKDIVR_CONFIG(PeriphClkInit->PLLSAIDivR);
  218. }
  219. /* Enable PLLSAI Clock */
  220. __HAL_RCC_PLLSAI_ENABLE();
  221. /* Get tick */
  222. tickstart = HAL_GetTick();
  223. /* Wait till PLLSAI is ready */
  224. while(__HAL_RCC_PLLSAI_GET_FLAG() == RESET)
  225. {
  226. if((HAL_GetTick() - tickstart ) > PLLSAI_TIMEOUT_VALUE)
  227. {
  228. /* return in case of Timeout detected */
  229. return HAL_TIMEOUT;
  230. }
  231. }
  232. }
  233. /*---------------------------- RTC configuration ---------------------------*/
  234. if(((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_RTC) == (RCC_PERIPHCLK_RTC))
  235. {
  236. /* Enable Power Clock*/
  237. __PWR_CLK_ENABLE();
  238. /* Enable write access to Backup domain */
  239. PWR->CR |= PWR_CR_DBP;
  240. /* Get tick */
  241. tickstart = HAL_GetTick();
  242. while((PWR->CR & PWR_CR_DBP) == RESET)
  243. {
  244. if((HAL_GetTick() - tickstart ) > DBP_TIMEOUT_VALUE)
  245. {
  246. return HAL_TIMEOUT;
  247. }
  248. }
  249. /* Reset the Backup domain only if the RTC Clock source selction is modified */
  250. if((RCC->BDCR & RCC_BDCR_RTCSEL) != (PeriphClkInit->RTCClockSelection & RCC_BDCR_RTCSEL))
  251. {
  252. /* Store the content of BDCR register before the reset of Backup Domain */
  253. tmpreg = (RCC->BDCR & ~(RCC_BDCR_RTCSEL));
  254. /* RTC Clock selection can be changed only if the Backup Domain is reset */
  255. __HAL_RCC_BACKUPRESET_FORCE();
  256. __HAL_RCC_BACKUPRESET_RELEASE();
  257. /* Restore the Content of BDCR register */
  258. RCC->BDCR = tmpreg;
  259. }
  260. /* If LSE is selected as RTC clock source, wait for LSE reactivation */
  261. if(PeriphClkInit->RTCClockSelection == RCC_RTCCLKSOURCE_LSE)
  262. {
  263. /* Get tick */
  264. tickstart = HAL_GetTick();
  265. /* Wait till LSE is ready */
  266. while(__HAL_RCC_GET_FLAG(RCC_FLAG_LSERDY) == RESET)
  267. {
  268. if((HAL_GetTick() - tickstart ) > LSE_TIMEOUT_VALUE)
  269. {
  270. return HAL_TIMEOUT;
  271. }
  272. }
  273. }
  274. __HAL_RCC_RTC_CONFIG(PeriphClkInit->RTCClockSelection);
  275. }
  276. /*---------------------------- TIM configuration ---------------------------*/
  277. if(((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_TIM) == (RCC_PERIPHCLK_TIM))
  278. {
  279. __HAL_RCC_TIMCLKPRESCALER(PeriphClkInit->TIMPresSelection);
  280. }
  281. return HAL_OK;
  282. }
  283. /**
  284. * @brief Configures the RCC_OscInitStruct according to the internal
  285. * RCC configuration registers.
  286. * @param PeriphClkInit: pointer to an RCC_PeriphCLKInitTypeDef structure that
  287. * will be configured.
  288. * @retval None
  289. */
  290. void HAL_RCCEx_GetPeriphCLKConfig(RCC_PeriphCLKInitTypeDef *PeriphClkInit)
  291. {
  292. uint32_t tempreg;
  293. /* Set all possible values for the extended clock type parameter------------*/
  294. PeriphClkInit->PeriphClockSelection = RCC_PERIPHCLK_I2S | RCC_PERIPHCLK_SAI_PLLSAI | RCC_PERIPHCLK_SAI_PLLI2S | RCC_PERIPHCLK_LTDC | RCC_PERIPHCLK_TIM | RCC_PERIPHCLK_RTC;
  295. /* Get the PLLI2S Clock configuration -----------------------------------------------*/
  296. PeriphClkInit->PLLI2S.PLLI2SN = (uint32_t)((RCC->PLLI2SCFGR & RCC_PLLI2SCFGR_PLLI2SN) >> POSITION_VAL(RCC_PLLI2SCFGR_PLLI2SN));
  297. PeriphClkInit->PLLI2S.PLLI2SR = (uint32_t)((RCC->PLLI2SCFGR & RCC_PLLI2SCFGR_PLLI2SR) >> POSITION_VAL(RCC_PLLI2SCFGR_PLLI2SR));
  298. PeriphClkInit->PLLI2S.PLLI2SQ = (uint32_t)((RCC->PLLI2SCFGR & RCC_PLLI2SCFGR_PLLI2SQ) >> POSITION_VAL(RCC_PLLI2SCFGR_PLLI2SQ));
  299. /* Get the PLLSAI Clock configuration -----------------------------------------------*/
  300. PeriphClkInit->PLLSAI.PLLSAIN = (uint32_t)((RCC->PLLSAICFGR & RCC_PLLSAICFGR_PLLSAIN) >> POSITION_VAL(RCC_PLLSAICFGR_PLLSAIN));
  301. PeriphClkInit->PLLSAI.PLLSAIR = (uint32_t)((RCC->PLLSAICFGR & RCC_PLLSAICFGR_PLLSAIR) >> POSITION_VAL(RCC_PLLSAICFGR_PLLSAIR));
  302. PeriphClkInit->PLLSAI.PLLSAIQ = (uint32_t)((RCC->PLLSAICFGR & RCC_PLLSAICFGR_PLLSAIQ) >> POSITION_VAL(RCC_PLLSAICFGR_PLLSAIQ));
  303. /* Get the PLLSAI/PLLI2S division factors -----------------------------------------------*/
  304. PeriphClkInit->PLLI2SDivQ = (uint32_t)((RCC->DCKCFGR & RCC_DCKCFGR_PLLI2SDIVQ) >> POSITION_VAL(RCC_DCKCFGR_PLLI2SDIVQ));
  305. PeriphClkInit->PLLSAIDivQ = (uint32_t)((RCC->DCKCFGR & RCC_DCKCFGR_PLLSAIDIVQ) >> POSITION_VAL(RCC_DCKCFGR_PLLSAIDIVQ));
  306. PeriphClkInit->PLLSAIDivR = (uint32_t)(RCC->DCKCFGR & RCC_DCKCFGR_PLLSAIDIVR);
  307. /* Get the RTC Clock configuration -----------------------------------------------*/
  308. tempreg = (RCC->CFGR & RCC_CFGR_RTCPRE);
  309. PeriphClkInit->RTCClockSelection = (uint32_t)((tempreg) | (RCC->BDCR & RCC_BDCR_RTCSEL));
  310. if ((RCC->DCKCFGR & RCC_DCKCFGR_TIMPRE) == RESET)
  311. {
  312. PeriphClkInit->TIMPresSelection = RCC_TIMPRES_DESACTIVATED;
  313. }
  314. else
  315. {
  316. PeriphClkInit->TIMPresSelection = RCC_TIMPRES_ACTIVATED;
  317. }
  318. }
  319. #endif /* STM32F427xx || STM32F437xx || STM32F429xx || STM32F439xx */
  320. #if defined(STM32F405xx) || defined(STM32F415xx) || defined(STM32F407xx)|| defined(STM32F417xx) ||\
  321. defined(STM32F401xC) || defined(STM32F401xE) || defined(STM32F411xE)
  322. /**
  323. * @brief Initializes the RCC extended peripherals clocks according to the specified parameters in the
  324. * RCC_PeriphCLKInitTypeDef.
  325. * @param PeriphClkInit: pointer to an RCC_PeriphCLKInitTypeDef structure that
  326. * contains the configuration information for the Extended Peripherals clocks(I2S and RTC clocks).
  327. *
  328. * @note A caution to be taken when HAL_RCCEx_PeriphCLKConfig() is used to select RTC clock selection, in this case
  329. * the Reset of Backup domain will be applied in order to modify the RTC Clock source as consequence all backup
  330. * domain (RTC and RCC_BDCR register expect BKPSRAM) will be reset
  331. *
  332. * @retval HAL status
  333. */
  334. HAL_StatusTypeDef HAL_RCCEx_PeriphCLKConfig(RCC_PeriphCLKInitTypeDef *PeriphClkInit)
  335. {
  336. uint32_t tickstart = 0;
  337. uint32_t tmpreg = 0;
  338. /* Check the parameters */
  339. assert_param(IS_RCC_PERIPHCLOCK(PeriphClkInit->PeriphClockSelection));
  340. /*---------------------------- I2S configuration ---------------------------*/
  341. if(((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_I2S) == (RCC_PERIPHCLK_I2S))
  342. {
  343. /* check for Parameters */
  344. assert_param(IS_RCC_PLLI2SR_VALUE(PeriphClkInit->PLLI2S.PLLI2SR));
  345. assert_param(IS_RCC_PLLI2SN_VALUE(PeriphClkInit->PLLI2S.PLLI2SN));
  346. #if defined(STM32F411xE)
  347. assert_param(IS_RCC_PLLI2SM_VALUE(PeriphClkInit->PLLI2S.PLLI2SM));
  348. #endif /* STM32F411xE */
  349. /* Disable the PLLI2S */
  350. __HAL_RCC_PLLI2S_DISABLE();
  351. /* Get tick */
  352. tickstart = HAL_GetTick();
  353. /* Wait till PLLI2S is disabled */
  354. while(__HAL_RCC_GET_FLAG(RCC_FLAG_PLLI2SRDY) != RESET)
  355. {
  356. if((HAL_GetTick() - tickstart ) > PLLI2S_TIMEOUT_VALUE)
  357. {
  358. /* return in case of Timeout detected */
  359. return HAL_TIMEOUT;
  360. }
  361. }
  362. #if defined(STM32F411xE)
  363. /* Configure the PLLI2S division factors */
  364. /* PLLI2S_VCO = f(VCO clock) = f(PLLI2S clock input) & (PLLI2SN/PLLI2SM) */
  365. /* I2SCLK = f(PLLI2S clock output) = f(VCO clock) / PLLI2SR */
  366. __HAL_RCC_PLLI2S_I2SCLK_CONFIG(PeriphClkInit->PLLI2S.PLLI2SM, PeriphClkInit->PLLI2S.PLLI2SN, PeriphClkInit->PLLI2S.PLLI2SR);
  367. #else
  368. /* Configure the PLLI2S division factors */
  369. /* PLLI2S_VCO = f(VCO clock) = f(PLLI2S clock input) & (PLLI2SN/PLLM) */
  370. /* I2SCLK = f(PLLI2S clock output) = f(VCO clock) / PLLI2SR */
  371. __HAL_RCC_PLLI2S_CONFIG(PeriphClkInit->PLLI2S.PLLI2SN , PeriphClkInit->PLLI2S.PLLI2SR);
  372. #endif /* STM32F411xE */
  373. /* Enable the PLLI2S */
  374. __HAL_RCC_PLLI2S_ENABLE();
  375. /* Get tick */
  376. tickstart = HAL_GetTick();
  377. /* Wait till PLLI2S is ready */
  378. while(__HAL_RCC_GET_FLAG(RCC_FLAG_PLLI2SRDY) == RESET)
  379. {
  380. if((HAL_GetTick() - tickstart ) > PLLI2S_TIMEOUT_VALUE)
  381. {
  382. /* return in case of Timeout detected */
  383. return HAL_TIMEOUT;
  384. }
  385. }
  386. }
  387. /*---------------------------- RTC configuration ---------------------------*/
  388. if(((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_RTC) == (RCC_PERIPHCLK_RTC))
  389. {
  390. /* Enable Power Clock*/
  391. __PWR_CLK_ENABLE();
  392. /* Enable write access to Backup domain */
  393. PWR->CR |= PWR_CR_DBP;
  394. /* Get tick */
  395. tickstart = HAL_GetTick();
  396. while((PWR->CR & PWR_CR_DBP) == RESET)
  397. {
  398. if((HAL_GetTick() - tickstart ) > DBP_TIMEOUT_VALUE)
  399. {
  400. return HAL_TIMEOUT;
  401. }
  402. }
  403. /* Reset the Backup domain only if the RTC Clock source selction is modified */
  404. if((RCC->BDCR & RCC_BDCR_RTCSEL) != (PeriphClkInit->RTCClockSelection & RCC_BDCR_RTCSEL))
  405. {
  406. /* Store the content of BDCR register before the reset of Backup Domain */
  407. tmpreg = (RCC->BDCR & ~(RCC_BDCR_RTCSEL));
  408. /* RTC Clock selection can be changed only if the Backup Domain is reset */
  409. __HAL_RCC_BACKUPRESET_FORCE();
  410. __HAL_RCC_BACKUPRESET_RELEASE();
  411. /* Restore the Content of BDCR register */
  412. RCC->BDCR = tmpreg;
  413. }
  414. /* If LSE is selected as RTC clock source, wait for LSE reactivation */
  415. if(PeriphClkInit->RTCClockSelection == RCC_RTCCLKSOURCE_LSE)
  416. {
  417. /* Get tick */
  418. tickstart = HAL_GetTick();
  419. /* Wait till LSE is ready */
  420. while(__HAL_RCC_GET_FLAG(RCC_FLAG_LSERDY) == RESET)
  421. {
  422. if((HAL_GetTick() - tickstart ) > LSE_TIMEOUT_VALUE)
  423. {
  424. return HAL_TIMEOUT;
  425. }
  426. }
  427. }
  428. __HAL_RCC_RTC_CONFIG(PeriphClkInit->RTCClockSelection);
  429. }
  430. return HAL_OK;
  431. }
  432. /**
  433. * @brief Configures the RCC_OscInitStruct according to the internal
  434. * RCC configuration registers.
  435. * @param PeriphClkInit: pointer to an RCC_PeriphCLKInitTypeDef structure that
  436. * will be configured.
  437. * @retval None
  438. */
  439. void HAL_RCCEx_GetPeriphCLKConfig(RCC_PeriphCLKInitTypeDef *PeriphClkInit)
  440. {
  441. uint32_t tempreg;
  442. /* Set all possible values for the extended clock type parameter------------*/
  443. PeriphClkInit->PeriphClockSelection = RCC_PERIPHCLK_I2S | RCC_PERIPHCLK_RTC;
  444. /* Get the PLLI2S Clock configuration -----------------------------------------------*/
  445. PeriphClkInit->PLLI2S.PLLI2SN = (uint32_t)((RCC->PLLI2SCFGR & RCC_PLLI2SCFGR_PLLI2SN) >> POSITION_VAL(RCC_PLLI2SCFGR_PLLI2SN));
  446. PeriphClkInit->PLLI2S.PLLI2SR = (uint32_t)((RCC->PLLI2SCFGR & RCC_PLLI2SCFGR_PLLI2SR) >> POSITION_VAL(RCC_PLLI2SCFGR_PLLI2SR));
  447. #if defined(STM32F411xE)
  448. PeriphClkInit->PLLI2S.PLLI2SM = (uint32_t)(RCC->PLLI2SCFGR & RCC_PLLI2SCFGR_PLLI2SM);
  449. #endif /* STM32F411xE */
  450. /* Get the RTC Clock configuration -----------------------------------------------*/
  451. tempreg = (RCC->CFGR & RCC_CFGR_RTCPRE);
  452. PeriphClkInit->RTCClockSelection = (uint32_t)((tempreg) | (RCC->BDCR & RCC_BDCR_RTCSEL));
  453. }
  454. #endif /* STM32F405xx || STM32F415xx || STM32F407xx || STM32F417xx || STM32F401xC || STM32F401xE || STM32F411xE */
  455. #if defined(STM32F411xE)
  456. /**
  457. * @brief Select LSE mode
  458. *
  459. * @note This mode is only available for STM32F411xx devices.
  460. *
  461. * @param Mode: specifies the LSE mode.
  462. * This parameter can be one of the following values:
  463. * @arg RCC_LSE_LOWPOWER_MODE: LSE oscillator in low power mode selection
  464. * @arg RCC_LSE_HIGHDRIVE_MODE: LSE oscillator in High Drive mode selection
  465. * @retval None
  466. */
  467. void HAL_RCCEx_SelectLSEMode(uint8_t Mode)
  468. {
  469. /* Check the parameters */
  470. assert_param(IS_RCC_LSE_MODE(Mode));
  471. if(Mode == RCC_LSE_HIGHDRIVE_MODE)
  472. {
  473. SET_BIT(RCC->BDCR, RCC_BDCR_LSEMOD);
  474. }
  475. else
  476. {
  477. CLEAR_BIT(RCC->BDCR, RCC_BDCR_LSEMOD);
  478. }
  479. }
  480. #endif /* STM32F411xE */
  481. /**
  482. * @}
  483. */
  484. /**
  485. * @}
  486. */
  487. #endif /* HAL_RCC_MODULE_ENABLED */
  488. /**
  489. * @}
  490. */
  491. /**
  492. * @}
  493. */
  494. /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/