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.
 
 
 
 
 

3834 rivejä
153 KiB

  1. /**
  2. ******************************************************************************
  3. * @file stm32f4xx_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. /* Includes ------------------------------------------------------------------*/
  22. #include "stm32f4xx_hal.h"
  23. /** @addtogroup STM32F4xx_HAL_Driver
  24. * @{
  25. */
  26. /** @defgroup RCCEx RCCEx
  27. * @brief RCCEx HAL module driver
  28. * @{
  29. */
  30. #ifdef HAL_RCC_MODULE_ENABLED
  31. /* Private typedef -----------------------------------------------------------*/
  32. /* Private define ------------------------------------------------------------*/
  33. /** @addtogroup RCCEx_Private_Constants
  34. * @{
  35. */
  36. /**
  37. * @}
  38. */
  39. /* Private macro -------------------------------------------------------------*/
  40. /* Private variables ---------------------------------------------------------*/
  41. /* Private function prototypes -----------------------------------------------*/
  42. /* Private functions ---------------------------------------------------------*/
  43. /** @defgroup RCCEx_Exported_Functions RCCEx Exported Functions
  44. * @{
  45. */
  46. /** @defgroup RCCEx_Exported_Functions_Group1 Extended Peripheral Control functions
  47. * @brief Extended Peripheral Control functions
  48. *
  49. @verbatim
  50. ===============================================================================
  51. ##### Extended Peripheral Control functions #####
  52. ===============================================================================
  53. [..]
  54. This subsection provides a set of functions allowing to control the RCC Clocks
  55. frequencies.
  56. [..]
  57. (@) Important note: Care must be taken when HAL_RCCEx_PeriphCLKConfig() is used to
  58. select the RTC clock source; in this case the Backup domain will be reset in
  59. order to modify the RTC Clock source, as consequence RTC registers (including
  60. the backup registers) and RCC_BDCR register are set to their reset values.
  61. @endverbatim
  62. * @{
  63. */
  64. #if defined(STM32F446xx)
  65. /**
  66. * @brief Initializes the RCC extended peripherals clocks according to the specified
  67. * parameters in the RCC_PeriphCLKInitTypeDef.
  68. * @param PeriphClkInit pointer to an RCC_PeriphCLKInitTypeDef structure that
  69. * contains the configuration information for the Extended Peripherals
  70. * clocks(I2S, SAI, LTDC RTC and TIM).
  71. *
  72. * @note Care must be taken when HAL_RCCEx_PeriphCLKConfig() is used to select
  73. * 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) and RCC_BDCR register are set to their reset values.
  76. *
  77. * @retval HAL status
  78. */
  79. HAL_StatusTypeDef HAL_RCCEx_PeriphCLKConfig(RCC_PeriphCLKInitTypeDef *PeriphClkInit)
  80. {
  81. uint32_t tickstart = 0U;
  82. uint32_t tmpreg1 = 0U;
  83. uint32_t plli2sp = 0U;
  84. uint32_t plli2sq = 0U;
  85. uint32_t plli2sr = 0U;
  86. uint32_t pllsaip = 0U;
  87. uint32_t pllsaiq = 0U;
  88. uint32_t plli2sused = 0U;
  89. uint32_t pllsaiused = 0U;
  90. /* Check the peripheral clock selection parameters */
  91. assert_param(IS_RCC_PERIPHCLOCK(PeriphClkInit->PeriphClockSelection));
  92. /*------------------------ I2S APB1 configuration --------------------------*/
  93. if (((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_I2S_APB1) == (RCC_PERIPHCLK_I2S_APB1))
  94. {
  95. /* Check the parameters */
  96. assert_param(IS_RCC_I2SAPB1CLKSOURCE(PeriphClkInit->I2sApb1ClockSelection));
  97. /* Configure I2S Clock source */
  98. __HAL_RCC_I2S_APB1_CONFIG(PeriphClkInit->I2sApb1ClockSelection);
  99. /* Enable the PLLI2S when it's used as clock source for I2S */
  100. if (PeriphClkInit->I2sApb1ClockSelection == RCC_I2SAPB1CLKSOURCE_PLLI2S)
  101. {
  102. plli2sused = 1U;
  103. }
  104. }
  105. /*--------------------------------------------------------------------------*/
  106. /*---------------------------- I2S APB2 configuration ----------------------*/
  107. if (((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_I2S_APB2) == (RCC_PERIPHCLK_I2S_APB2))
  108. {
  109. /* Check the parameters */
  110. assert_param(IS_RCC_I2SAPB2CLKSOURCE(PeriphClkInit->I2sApb2ClockSelection));
  111. /* Configure I2S Clock source */
  112. __HAL_RCC_I2S_APB2_CONFIG(PeriphClkInit->I2sApb2ClockSelection);
  113. /* Enable the PLLI2S when it's used as clock source for I2S */
  114. if (PeriphClkInit->I2sApb2ClockSelection == RCC_I2SAPB2CLKSOURCE_PLLI2S)
  115. {
  116. plli2sused = 1U;
  117. }
  118. }
  119. /*--------------------------------------------------------------------------*/
  120. /*--------------------------- SAI1 configuration ---------------------------*/
  121. if (((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_SAI1) == (RCC_PERIPHCLK_SAI1))
  122. {
  123. /* Check the parameters */
  124. assert_param(IS_RCC_SAI1CLKSOURCE(PeriphClkInit->Sai1ClockSelection));
  125. /* Configure SAI1 Clock source */
  126. __HAL_RCC_SAI1_CONFIG(PeriphClkInit->Sai1ClockSelection);
  127. /* Enable the PLLI2S when it's used as clock source for SAI */
  128. if (PeriphClkInit->Sai1ClockSelection == RCC_SAI1CLKSOURCE_PLLI2S)
  129. {
  130. plli2sused = 1U;
  131. }
  132. /* Enable the PLLSAI when it's used as clock source for SAI */
  133. if (PeriphClkInit->Sai1ClockSelection == RCC_SAI1CLKSOURCE_PLLSAI)
  134. {
  135. pllsaiused = 1U;
  136. }
  137. }
  138. /*--------------------------------------------------------------------------*/
  139. /*-------------------------- SAI2 configuration ----------------------------*/
  140. if (((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_SAI2) == (RCC_PERIPHCLK_SAI2))
  141. {
  142. /* Check the parameters */
  143. assert_param(IS_RCC_SAI2CLKSOURCE(PeriphClkInit->Sai2ClockSelection));
  144. /* Configure SAI2 Clock source */
  145. __HAL_RCC_SAI2_CONFIG(PeriphClkInit->Sai2ClockSelection);
  146. /* Enable the PLLI2S when it's used as clock source for SAI */
  147. if (PeriphClkInit->Sai2ClockSelection == RCC_SAI2CLKSOURCE_PLLI2S)
  148. {
  149. plli2sused = 1U;
  150. }
  151. /* Enable the PLLSAI when it's used as clock source for SAI */
  152. if (PeriphClkInit->Sai2ClockSelection == RCC_SAI2CLKSOURCE_PLLSAI)
  153. {
  154. pllsaiused = 1U;
  155. }
  156. }
  157. /*--------------------------------------------------------------------------*/
  158. /*----------------------------- RTC configuration --------------------------*/
  159. if (((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_RTC) == (RCC_PERIPHCLK_RTC))
  160. {
  161. /* Check for RTC Parameters used to output RTCCLK */
  162. assert_param(IS_RCC_RTCCLKSOURCE(PeriphClkInit->RTCClockSelection));
  163. /* Enable Power Clock*/
  164. __HAL_RCC_PWR_CLK_ENABLE();
  165. /* Enable write access to Backup domain */
  166. PWR->CR |= PWR_CR_DBP;
  167. /* Get tick */
  168. tickstart = HAL_GetTick();
  169. while ((PWR->CR & PWR_CR_DBP) == RESET)
  170. {
  171. if ((HAL_GetTick() - tickstart) > RCC_DBP_TIMEOUT_VALUE)
  172. {
  173. return HAL_TIMEOUT;
  174. }
  175. }
  176. /* Reset the Backup domain only if the RTC Clock source selection is modified from reset value */
  177. tmpreg1 = (RCC->BDCR & RCC_BDCR_RTCSEL);
  178. if ((tmpreg1 != 0x00000000U) && ((tmpreg1) != (PeriphClkInit->RTCClockSelection & RCC_BDCR_RTCSEL)))
  179. {
  180. /* Store the content of BDCR register before the reset of Backup Domain */
  181. tmpreg1 = (RCC->BDCR & ~(RCC_BDCR_RTCSEL));
  182. /* RTC Clock selection can be changed only if the Backup Domain is reset */
  183. __HAL_RCC_BACKUPRESET_FORCE();
  184. __HAL_RCC_BACKUPRESET_RELEASE();
  185. /* Restore the Content of BDCR register */
  186. RCC->BDCR = tmpreg1;
  187. /* Wait for LSE reactivation if LSE was enable prior to Backup Domain reset */
  188. if (HAL_IS_BIT_SET(RCC->BDCR, RCC_BDCR_LSEON))
  189. {
  190. /* Get tick */
  191. tickstart = HAL_GetTick();
  192. /* Wait till LSE is ready */
  193. while (__HAL_RCC_GET_FLAG(RCC_FLAG_LSERDY) == RESET)
  194. {
  195. if ((HAL_GetTick() - tickstart) > RCC_LSE_TIMEOUT_VALUE)
  196. {
  197. return HAL_TIMEOUT;
  198. }
  199. }
  200. }
  201. }
  202. __HAL_RCC_RTC_CONFIG(PeriphClkInit->RTCClockSelection);
  203. }
  204. /*--------------------------------------------------------------------------*/
  205. /*---------------------------- TIM configuration ---------------------------*/
  206. if (((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_TIM) == (RCC_PERIPHCLK_TIM))
  207. {
  208. /* Configure Timer Prescaler */
  209. __HAL_RCC_TIMCLKPRESCALER(PeriphClkInit->TIMPresSelection);
  210. }
  211. /*--------------------------------------------------------------------------*/
  212. /*---------------------------- FMPI2C1 Configuration -----------------------*/
  213. if (((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_FMPI2C1) == RCC_PERIPHCLK_FMPI2C1)
  214. {
  215. /* Check the parameters */
  216. assert_param(IS_RCC_FMPI2C1CLKSOURCE(PeriphClkInit->Fmpi2c1ClockSelection));
  217. /* Configure the FMPI2C1 clock source */
  218. __HAL_RCC_FMPI2C1_CONFIG(PeriphClkInit->Fmpi2c1ClockSelection);
  219. }
  220. /*--------------------------------------------------------------------------*/
  221. /*------------------------------ CEC Configuration -------------------------*/
  222. if (((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_CEC) == RCC_PERIPHCLK_CEC)
  223. {
  224. /* Check the parameters */
  225. assert_param(IS_RCC_CECCLKSOURCE(PeriphClkInit->CecClockSelection));
  226. /* Configure the CEC clock source */
  227. __HAL_RCC_CEC_CONFIG(PeriphClkInit->CecClockSelection);
  228. }
  229. /*--------------------------------------------------------------------------*/
  230. /*----------------------------- CLK48 Configuration ------------------------*/
  231. if (((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_CLK48) == RCC_PERIPHCLK_CLK48)
  232. {
  233. /* Check the parameters */
  234. assert_param(IS_RCC_CLK48CLKSOURCE(PeriphClkInit->Clk48ClockSelection));
  235. /* Configure the CLK48 clock source */
  236. __HAL_RCC_CLK48_CONFIG(PeriphClkInit->Clk48ClockSelection);
  237. /* Enable the PLLSAI when it's used as clock source for CLK48 */
  238. if (PeriphClkInit->Clk48ClockSelection == RCC_CLK48CLKSOURCE_PLLSAIP)
  239. {
  240. pllsaiused = 1U;
  241. }
  242. }
  243. /*--------------------------------------------------------------------------*/
  244. /*----------------------------- SDIO Configuration -------------------------*/
  245. if (((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_SDIO) == RCC_PERIPHCLK_SDIO)
  246. {
  247. /* Check the parameters */
  248. assert_param(IS_RCC_SDIOCLKSOURCE(PeriphClkInit->SdioClockSelection));
  249. /* Configure the SDIO clock source */
  250. __HAL_RCC_SDIO_CONFIG(PeriphClkInit->SdioClockSelection);
  251. }
  252. /*--------------------------------------------------------------------------*/
  253. /*------------------------------ SPDIFRX Configuration ---------------------*/
  254. if (((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_SPDIFRX) == RCC_PERIPHCLK_SPDIFRX)
  255. {
  256. /* Check the parameters */
  257. assert_param(IS_RCC_SPDIFRXCLKSOURCE(PeriphClkInit->SpdifClockSelection));
  258. /* Configure the SPDIFRX clock source */
  259. __HAL_RCC_SPDIFRX_CONFIG(PeriphClkInit->SpdifClockSelection);
  260. /* Enable the PLLI2S when it's used as clock source for SPDIFRX */
  261. if (PeriphClkInit->SpdifClockSelection == RCC_SPDIFRXCLKSOURCE_PLLI2SP)
  262. {
  263. plli2sused = 1U;
  264. }
  265. }
  266. /*--------------------------------------------------------------------------*/
  267. /*---------------------------- PLLI2S Configuration ------------------------*/
  268. /* PLLI2S is configured when a peripheral will use it as source clock : SAI1, SAI2, I2S on APB1,
  269. I2S on APB2 or SPDIFRX */
  270. if ((plli2sused == 1U) || (PeriphClkInit->PeriphClockSelection == RCC_PERIPHCLK_PLLI2S))
  271. {
  272. /* Disable the PLLI2S */
  273. __HAL_RCC_PLLI2S_DISABLE();
  274. /* Get tick */
  275. tickstart = HAL_GetTick();
  276. /* Wait till PLLI2S is disabled */
  277. while (__HAL_RCC_GET_FLAG(RCC_FLAG_PLLI2SRDY) != RESET)
  278. {
  279. if ((HAL_GetTick() - tickstart) > PLLI2S_TIMEOUT_VALUE)
  280. {
  281. /* return in case of Timeout detected */
  282. return HAL_TIMEOUT;
  283. }
  284. }
  285. /* check for common PLLI2S Parameters */
  286. assert_param(IS_RCC_PLLI2SM_VALUE(PeriphClkInit->PLLI2S.PLLI2SM));
  287. assert_param(IS_RCC_PLLI2SN_VALUE(PeriphClkInit->PLLI2S.PLLI2SN));
  288. /*------ In Case of PLLI2S is selected as source clock for I2S -----------*/
  289. if (((((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_I2S_APB1) == RCC_PERIPHCLK_I2S_APB1)
  290. && (PeriphClkInit->I2sApb1ClockSelection == RCC_I2SAPB1CLKSOURCE_PLLI2S)) ||
  291. ((((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_I2S_APB2) == RCC_PERIPHCLK_I2S_APB2) && (PeriphClkInit->I2sApb2ClockSelection == RCC_I2SAPB2CLKSOURCE_PLLI2S)))
  292. {
  293. /* check for Parameters */
  294. assert_param(IS_RCC_PLLI2SR_VALUE(PeriphClkInit->PLLI2S.PLLI2SR));
  295. /* Read PLLI2SP/PLLI2SQ value from PLLI2SCFGR register (this value is not needed for I2S configuration) */
  296. plli2sp = ((((RCC->PLLI2SCFGR & RCC_PLLI2SCFGR_PLLI2SP) >> RCC_PLLI2SCFGR_PLLI2SP_Pos) + 1U) << 1U);
  297. plli2sq = ((RCC->PLLI2SCFGR & RCC_PLLI2SCFGR_PLLI2SQ) >> RCC_PLLI2SCFGR_PLLI2SQ_Pos);
  298. /* Configure the PLLI2S division factors */
  299. /* PLLI2S_VCO = f(VCO clock) = f(PLLI2S clock input) * (PLLI2SN/PLLI2SM) */
  300. /* I2SCLK = f(PLLI2S clock output) = f(VCO clock) / PLLI2SR */
  301. __HAL_RCC_PLLI2S_CONFIG(PeriphClkInit->PLLI2S.PLLI2SM, PeriphClkInit->PLLI2S.PLLI2SN, plli2sp, plli2sq,
  302. PeriphClkInit->PLLI2S.PLLI2SR);
  303. }
  304. /*------- In Case of PLLI2S is selected as source clock for SAI ----------*/
  305. if (((((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_SAI1) == RCC_PERIPHCLK_SAI1)
  306. && (PeriphClkInit->Sai1ClockSelection == RCC_SAI1CLKSOURCE_PLLI2S)) ||
  307. ((((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_SAI2) == RCC_PERIPHCLK_SAI2) && (PeriphClkInit->Sai2ClockSelection == RCC_SAI2CLKSOURCE_PLLI2S)))
  308. {
  309. /* Check for PLLI2S Parameters */
  310. assert_param(IS_RCC_PLLI2SQ_VALUE(PeriphClkInit->PLLI2S.PLLI2SQ));
  311. /* Check for PLLI2S/DIVQ parameters */
  312. assert_param(IS_RCC_PLLI2S_DIVQ_VALUE(PeriphClkInit->PLLI2SDivQ));
  313. /* Read PLLI2SP/PLLI2SR value from PLLI2SCFGR register (this value is not needed for SAI configuration) */
  314. plli2sp = ((((RCC->PLLI2SCFGR & RCC_PLLI2SCFGR_PLLI2SP) >> RCC_PLLI2SCFGR_PLLI2SP_Pos) + 1U) << 1U);
  315. plli2sr = ((RCC->PLLI2SCFGR & RCC_PLLI2SCFGR_PLLI2SR) >> RCC_PLLI2SCFGR_PLLI2SR_Pos);
  316. /* Configure the PLLI2S division factors */
  317. /* PLLI2S_VCO Input = PLL_SOURCE/PLLI2SM */
  318. /* PLLI2S_VCO Output = PLLI2S_VCO Input * PLLI2SN */
  319. /* SAI_CLK(first level) = PLLI2S_VCO Output/PLLI2SQ */
  320. __HAL_RCC_PLLI2S_CONFIG(PeriphClkInit->PLLI2S.PLLI2SM, PeriphClkInit->PLLI2S.PLLI2SN, plli2sp,
  321. PeriphClkInit->PLLI2S.PLLI2SQ, plli2sr);
  322. /* SAI_CLK_x = SAI_CLK(first level)/PLLI2SDIVQ */
  323. __HAL_RCC_PLLI2S_PLLSAICLKDIVQ_CONFIG(PeriphClkInit->PLLI2SDivQ);
  324. }
  325. /*------ In Case of PLLI2S is selected as source clock for SPDIFRX -------*/
  326. if ((((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_SPDIFRX) == RCC_PERIPHCLK_SPDIFRX)
  327. && (PeriphClkInit->SpdifClockSelection == RCC_SPDIFRXCLKSOURCE_PLLI2SP))
  328. {
  329. /* check for Parameters */
  330. assert_param(IS_RCC_PLLI2SP_VALUE(PeriphClkInit->PLLI2S.PLLI2SP));
  331. /* Read PLLI2SR value from PLLI2SCFGR register (this value is not need for SAI configuration) */
  332. plli2sq = ((((RCC->PLLI2SCFGR & RCC_PLLI2SCFGR_PLLI2SP) >> RCC_PLLI2SCFGR_PLLI2SP_Pos) + 1U) << 1U);
  333. plli2sr = ((RCC->PLLI2SCFGR & RCC_PLLI2SCFGR_PLLI2SR) >> RCC_PLLI2SCFGR_PLLI2SR_Pos);
  334. /* Configure the PLLI2S division factors */
  335. /* PLLI2S_VCO = f(VCO clock) = f(PLLI2S clock input) * (PLLI2SN/PLLI2SM) */
  336. /* SPDIFRXCLK = f(PLLI2S clock output) = f(VCO clock) / PLLI2SP */
  337. __HAL_RCC_PLLI2S_CONFIG(PeriphClkInit->PLLI2S.PLLI2SM, PeriphClkInit->PLLI2S.PLLI2SN, PeriphClkInit->PLLI2S.PLLI2SP,
  338. plli2sq, plli2sr);
  339. }
  340. /*----------------- In Case of PLLI2S is just selected -----------------*/
  341. if ((PeriphClkInit->PeriphClockSelection & RCC_PERIPHCLK_PLLI2S) == RCC_PERIPHCLK_PLLI2S)
  342. {
  343. /* Check for Parameters */
  344. assert_param(IS_RCC_PLLI2SP_VALUE(PeriphClkInit->PLLI2S.PLLI2SP));
  345. assert_param(IS_RCC_PLLI2SR_VALUE(PeriphClkInit->PLLI2S.PLLI2SR));
  346. assert_param(IS_RCC_PLLI2SQ_VALUE(PeriphClkInit->PLLI2S.PLLI2SQ));
  347. /* Configure the PLLI2S division factors */
  348. /* PLLI2S_VCO = f(VCO clock) = f(PLLI2S clock input) * (PLLI2SN/PLLI2SM) */
  349. __HAL_RCC_PLLI2S_CONFIG(PeriphClkInit->PLLI2S.PLLI2SM, PeriphClkInit->PLLI2S.PLLI2SN, PeriphClkInit->PLLI2S.PLLI2SP,
  350. PeriphClkInit->PLLI2S.PLLI2SQ, PeriphClkInit->PLLI2S.PLLI2SR);
  351. }
  352. /* Enable the PLLI2S */
  353. __HAL_RCC_PLLI2S_ENABLE();
  354. /* Get tick */
  355. tickstart = HAL_GetTick();
  356. /* Wait till PLLI2S is ready */
  357. while (__HAL_RCC_GET_FLAG(RCC_FLAG_PLLI2SRDY) == RESET)
  358. {
  359. if ((HAL_GetTick() - tickstart) > PLLI2S_TIMEOUT_VALUE)
  360. {
  361. /* return in case of Timeout detected */
  362. return HAL_TIMEOUT;
  363. }
  364. }
  365. }
  366. /*--------------------------------------------------------------------------*/
  367. /*----------------------------- PLLSAI Configuration -----------------------*/
  368. /* PLLSAI is configured when a peripheral will use it as source clock : SAI1, SAI2, CLK48 or SDIO */
  369. if (pllsaiused == 1U)
  370. {
  371. /* Disable PLLSAI Clock */
  372. __HAL_RCC_PLLSAI_DISABLE();
  373. /* Get tick */
  374. tickstart = HAL_GetTick();
  375. /* Wait till PLLSAI is disabled */
  376. while (__HAL_RCC_PLLSAI_GET_FLAG() != RESET)
  377. {
  378. if ((HAL_GetTick() - tickstart) > PLLSAI_TIMEOUT_VALUE)
  379. {
  380. /* return in case of Timeout detected */
  381. return HAL_TIMEOUT;
  382. }
  383. }
  384. /* Check the PLLSAI division factors */
  385. assert_param(IS_RCC_PLLSAIM_VALUE(PeriphClkInit->PLLSAI.PLLSAIM));
  386. assert_param(IS_RCC_PLLSAIN_VALUE(PeriphClkInit->PLLSAI.PLLSAIN));
  387. /*------ In Case of PLLSAI is selected as source clock for SAI -----------*/
  388. if (((((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_SAI1) == RCC_PERIPHCLK_SAI1)
  389. && (PeriphClkInit->Sai1ClockSelection == RCC_SAI1CLKSOURCE_PLLSAI)) ||
  390. ((((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_SAI2) == RCC_PERIPHCLK_SAI2) && (PeriphClkInit->Sai2ClockSelection == RCC_SAI2CLKSOURCE_PLLSAI)))
  391. {
  392. /* check for PLLSAIQ Parameter */
  393. assert_param(IS_RCC_PLLSAIQ_VALUE(PeriphClkInit->PLLSAI.PLLSAIQ));
  394. /* check for PLLSAI/DIVQ Parameter */
  395. assert_param(IS_RCC_PLLSAI_DIVQ_VALUE(PeriphClkInit->PLLSAIDivQ));
  396. /* Read PLLSAIP value from PLLSAICFGR register (this value is not needed for SAI configuration) */
  397. pllsaip = ((((RCC->PLLSAICFGR & RCC_PLLSAICFGR_PLLSAIP) >> RCC_PLLSAICFGR_PLLSAIP_Pos) + 1U) << 1U);
  398. /* PLLSAI_VCO Input = PLL_SOURCE/PLLM */
  399. /* PLLSAI_VCO Output = PLLSAI_VCO Input * PLLSAIN */
  400. /* SAI_CLK(first level) = PLLSAI_VCO Output/PLLSAIQ */
  401. __HAL_RCC_PLLSAI_CONFIG(PeriphClkInit->PLLSAI.PLLSAIM, PeriphClkInit->PLLSAI.PLLSAIN, pllsaip,
  402. PeriphClkInit->PLLSAI.PLLSAIQ, 0U);
  403. /* SAI_CLK_x = SAI_CLK(first level)/PLLSAIDIVQ */
  404. __HAL_RCC_PLLSAI_PLLSAICLKDIVQ_CONFIG(PeriphClkInit->PLLSAIDivQ);
  405. }
  406. /*------ In Case of PLLSAI is selected as source clock for CLK48 ---------*/
  407. /* In Case of PLLI2S is selected as source clock for CLK48 */
  408. if ((((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_CLK48) == RCC_PERIPHCLK_CLK48)
  409. && (PeriphClkInit->Clk48ClockSelection == RCC_CLK48CLKSOURCE_PLLSAIP))
  410. {
  411. /* check for Parameters */
  412. assert_param(IS_RCC_PLLSAIP_VALUE(PeriphClkInit->PLLSAI.PLLSAIP));
  413. /* Read PLLSAIQ value from PLLI2SCFGR register (this value is not need for SAI configuration) */
  414. pllsaiq = ((RCC->PLLSAICFGR & RCC_PLLSAICFGR_PLLSAIQ) >> RCC_PLLSAICFGR_PLLSAIQ_Pos);
  415. /* Configure the PLLSAI division factors */
  416. /* PLLSAI_VCO = f(VCO clock) = f(PLLSAI clock input) * (PLLI2SN/PLLSAIM) */
  417. /* 48CLK = f(PLLSAI clock output) = f(VCO clock) / PLLSAIP */
  418. __HAL_RCC_PLLSAI_CONFIG(PeriphClkInit->PLLSAI.PLLSAIM, PeriphClkInit->PLLSAI.PLLSAIN, PeriphClkInit->PLLSAI.PLLSAIP,
  419. pllsaiq, 0U);
  420. }
  421. /* Enable PLLSAI Clock */
  422. __HAL_RCC_PLLSAI_ENABLE();
  423. /* Get tick */
  424. tickstart = HAL_GetTick();
  425. /* Wait till PLLSAI is ready */
  426. while (__HAL_RCC_PLLSAI_GET_FLAG() == RESET)
  427. {
  428. if ((HAL_GetTick() - tickstart) > PLLSAI_TIMEOUT_VALUE)
  429. {
  430. /* return in case of Timeout detected */
  431. return HAL_TIMEOUT;
  432. }
  433. }
  434. }
  435. return HAL_OK;
  436. }
  437. /**
  438. * @brief Get the RCC_PeriphCLKInitTypeDef according to the internal
  439. * RCC configuration registers.
  440. * @param PeriphClkInit pointer to an RCC_PeriphCLKInitTypeDef structure that
  441. * will be configured.
  442. * @retval None
  443. */
  444. void HAL_RCCEx_GetPeriphCLKConfig(RCC_PeriphCLKInitTypeDef *PeriphClkInit)
  445. {
  446. uint32_t tempreg;
  447. /* Set all possible values for the extended clock type parameter------------*/
  448. PeriphClkInit->PeriphClockSelection = RCC_PERIPHCLK_I2S_APB1 | RCC_PERIPHCLK_I2S_APB2 | \
  449. RCC_PERIPHCLK_SAI1 | RCC_PERIPHCLK_SAI2 | \
  450. RCC_PERIPHCLK_TIM | RCC_PERIPHCLK_RTC | \
  451. RCC_PERIPHCLK_CEC | RCC_PERIPHCLK_FMPI2C1 | \
  452. RCC_PERIPHCLK_CLK48 | RCC_PERIPHCLK_SDIO | \
  453. RCC_PERIPHCLK_SPDIFRX;
  454. /* Get the PLLI2S Clock configuration --------------------------------------*/
  455. PeriphClkInit->PLLI2S.PLLI2SM = (uint32_t)((RCC->PLLI2SCFGR & RCC_PLLI2SCFGR_PLLI2SM) >> RCC_PLLI2SCFGR_PLLI2SM_Pos);
  456. PeriphClkInit->PLLI2S.PLLI2SN = (uint32_t)((RCC->PLLI2SCFGR & RCC_PLLI2SCFGR_PLLI2SN) >> RCC_PLLI2SCFGR_PLLI2SN_Pos);
  457. PeriphClkInit->PLLI2S.PLLI2SP = (uint32_t)((((RCC->PLLI2SCFGR & RCC_PLLI2SCFGR_PLLI2SP) >> RCC_PLLI2SCFGR_PLLI2SP_Pos) + 1U) << 1U);
  458. PeriphClkInit->PLLI2S.PLLI2SQ = (uint32_t)((RCC->PLLI2SCFGR & RCC_PLLI2SCFGR_PLLI2SQ) >> RCC_PLLI2SCFGR_PLLI2SQ_Pos);
  459. PeriphClkInit->PLLI2S.PLLI2SR = (uint32_t)((RCC->PLLI2SCFGR & RCC_PLLI2SCFGR_PLLI2SR) >> RCC_PLLI2SCFGR_PLLI2SR_Pos);
  460. /* Get the PLLSAI Clock configuration --------------------------------------*/
  461. PeriphClkInit->PLLSAI.PLLSAIM = (uint32_t)((RCC->PLLSAICFGR & RCC_PLLSAICFGR_PLLSAIM) >> RCC_PLLSAICFGR_PLLSAIM_Pos);
  462. PeriphClkInit->PLLSAI.PLLSAIN = (uint32_t)((RCC->PLLSAICFGR & RCC_PLLSAICFGR_PLLSAIN) >> RCC_PLLSAICFGR_PLLSAIN_Pos);
  463. PeriphClkInit->PLLSAI.PLLSAIP = (uint32_t)((((RCC->PLLSAICFGR & RCC_PLLSAICFGR_PLLSAIP) >> RCC_PLLSAICFGR_PLLSAIP_Pos) + 1U) << 1U);
  464. PeriphClkInit->PLLSAI.PLLSAIQ = (uint32_t)((RCC->PLLSAICFGR & RCC_PLLSAICFGR_PLLSAIQ) >> RCC_PLLSAICFGR_PLLSAIQ_Pos);
  465. /* Get the PLLSAI/PLLI2S division factors ----------------------------------*/
  466. PeriphClkInit->PLLI2SDivQ = (uint32_t)((RCC->DCKCFGR & RCC_DCKCFGR_PLLI2SDIVQ) >> RCC_DCKCFGR_PLLI2SDIVQ_Pos);
  467. PeriphClkInit->PLLSAIDivQ = (uint32_t)((RCC->DCKCFGR & RCC_DCKCFGR_PLLSAIDIVQ) >> RCC_DCKCFGR_PLLSAIDIVQ_Pos);
  468. /* Get the SAI1 clock configuration ----------------------------------------*/
  469. PeriphClkInit->Sai1ClockSelection = __HAL_RCC_GET_SAI1_SOURCE();
  470. /* Get the SAI2 clock configuration ----------------------------------------*/
  471. PeriphClkInit->Sai2ClockSelection = __HAL_RCC_GET_SAI2_SOURCE();
  472. /* Get the I2S APB1 clock configuration ------------------------------------*/
  473. PeriphClkInit->I2sApb1ClockSelection = __HAL_RCC_GET_I2S_APB1_SOURCE();
  474. /* Get the I2S APB2 clock configuration ------------------------------------*/
  475. PeriphClkInit->I2sApb2ClockSelection = __HAL_RCC_GET_I2S_APB2_SOURCE();
  476. /* Get the RTC Clock configuration -----------------------------------------*/
  477. tempreg = (RCC->CFGR & RCC_CFGR_RTCPRE);
  478. PeriphClkInit->RTCClockSelection = (uint32_t)((tempreg) | (RCC->BDCR & RCC_BDCR_RTCSEL));
  479. /* Get the CEC clock configuration -----------------------------------------*/
  480. PeriphClkInit->CecClockSelection = __HAL_RCC_GET_CEC_SOURCE();
  481. /* Get the FMPI2C1 clock configuration -------------------------------------*/
  482. PeriphClkInit->Fmpi2c1ClockSelection = __HAL_RCC_GET_FMPI2C1_SOURCE();
  483. /* Get the CLK48 clock configuration ----------------------------------------*/
  484. PeriphClkInit->Clk48ClockSelection = __HAL_RCC_GET_CLK48_SOURCE();
  485. /* Get the SDIO clock configuration ----------------------------------------*/
  486. PeriphClkInit->SdioClockSelection = __HAL_RCC_GET_SDIO_SOURCE();
  487. /* Get the SPDIFRX clock configuration -------------------------------------*/
  488. PeriphClkInit->SpdifClockSelection = __HAL_RCC_GET_SPDIFRX_SOURCE();
  489. /* Get the TIM Prescaler configuration -------------------------------------*/
  490. if ((RCC->DCKCFGR & RCC_DCKCFGR_TIMPRE) == RESET)
  491. {
  492. PeriphClkInit->TIMPresSelection = RCC_TIMPRES_DESACTIVATED;
  493. }
  494. else
  495. {
  496. PeriphClkInit->TIMPresSelection = RCC_TIMPRES_ACTIVATED;
  497. }
  498. }
  499. /**
  500. * @brief Return the peripheral clock frequency for a given peripheral(SAI..)
  501. * @note Return 0 if peripheral clock identifier not managed by this API
  502. * @param PeriphClk Peripheral clock identifier
  503. * This parameter can be one of the following values:
  504. * @arg RCC_PERIPHCLK_SAI1: SAI1 peripheral clock
  505. * @arg RCC_PERIPHCLK_SAI2: SAI2 peripheral clock
  506. * @arg RCC_PERIPHCLK_I2S_APB1: I2S APB1 peripheral clock
  507. * @arg RCC_PERIPHCLK_I2S_APB2: I2S APB2 peripheral clock
  508. * @retval Frequency in KHz
  509. */
  510. uint32_t HAL_RCCEx_GetPeriphCLKFreq(uint32_t PeriphClk)
  511. {
  512. uint32_t tmpreg1 = 0U;
  513. /* This variable used to store the SAI clock frequency (value in Hz) */
  514. uint32_t frequency = 0U;
  515. /* This variable used to store the VCO Input (value in Hz) */
  516. uint32_t vcoinput = 0U;
  517. /* This variable used to store the SAI clock source */
  518. uint32_t saiclocksource = 0U;
  519. uint32_t srcclk = 0U;
  520. /* This variable used to store the VCO Output (value in Hz) */
  521. uint32_t vcooutput = 0U;
  522. switch (PeriphClk)
  523. {
  524. case RCC_PERIPHCLK_SAI1:
  525. case RCC_PERIPHCLK_SAI2:
  526. {
  527. saiclocksource = RCC->DCKCFGR;
  528. saiclocksource &= (RCC_DCKCFGR_SAI1SRC | RCC_DCKCFGR_SAI2SRC);
  529. switch (saiclocksource)
  530. {
  531. case 0U: /* PLLSAI is the clock source for SAI*/
  532. {
  533. /* Configure the PLLSAI division factor */
  534. /* PLLSAI_VCO Input = PLL_SOURCE/PLLSAIM */
  535. if ((RCC->PLLCFGR & RCC_PLLCFGR_PLLSRC) == RCC_PLLSOURCE_HSI)
  536. {
  537. /* In Case the PLL Source is HSI (Internal Clock) */
  538. vcoinput = (HSI_VALUE / (uint32_t)(RCC->PLLSAICFGR & RCC_PLLSAICFGR_PLLSAIM));
  539. }
  540. else
  541. {
  542. /* In Case the PLL Source is HSE (External Clock) */
  543. vcoinput = ((HSE_VALUE / (uint32_t)(RCC->PLLSAICFGR & RCC_PLLSAICFGR_PLLSAIM)));
  544. }
  545. /* PLLSAI_VCO Output = PLLSAI_VCO Input * PLLSAIN */
  546. /* SAI_CLK(first level) = PLLSAI_VCO Output/PLLSAIQ */
  547. tmpreg1 = (RCC->PLLSAICFGR & RCC_PLLSAICFGR_PLLSAIQ) >> 24U;
  548. frequency = (vcoinput * ((RCC->PLLSAICFGR & RCC_PLLSAICFGR_PLLSAIN) >> 6U)) / (tmpreg1);
  549. /* SAI_CLK_x = SAI_CLK(first level)/PLLSAIDIVQ */
  550. tmpreg1 = (((RCC->DCKCFGR & RCC_DCKCFGR_PLLSAIDIVQ) >> 8U) + 1U);
  551. frequency = frequency / (tmpreg1);
  552. break;
  553. }
  554. case RCC_DCKCFGR_SAI1SRC_0: /* PLLI2S is the clock source for SAI*/
  555. case RCC_DCKCFGR_SAI2SRC_0: /* PLLI2S is the clock source for SAI*/
  556. {
  557. /* Configure the PLLI2S division factor */
  558. /* PLLI2S_VCO Input = PLL_SOURCE/PLLI2SM */
  559. if ((RCC->PLLCFGR & RCC_PLLCFGR_PLLSRC) == RCC_PLLSOURCE_HSI)
  560. {
  561. /* In Case the PLL Source is HSI (Internal Clock) */
  562. vcoinput = (HSI_VALUE / (uint32_t)(RCC->PLLI2SCFGR & RCC_PLLI2SCFGR_PLLI2SM));
  563. }
  564. else
  565. {
  566. /* In Case the PLL Source is HSE (External Clock) */
  567. vcoinput = ((HSE_VALUE / (uint32_t)(RCC->PLLI2SCFGR & RCC_PLLI2SCFGR_PLLI2SM)));
  568. }
  569. /* PLLI2S_VCO Output = PLLI2S_VCO Input * PLLI2SN */
  570. /* SAI_CLK(first level) = PLLI2S_VCO Output/PLLI2SQ */
  571. tmpreg1 = (RCC->PLLI2SCFGR & RCC_PLLI2SCFGR_PLLI2SQ) >> 24U;
  572. frequency = (vcoinput * ((RCC->PLLI2SCFGR & RCC_PLLI2SCFGR_PLLI2SN) >> 6U)) / (tmpreg1);
  573. /* SAI_CLK_x = SAI_CLK(first level)/PLLI2SDIVQ */
  574. tmpreg1 = ((RCC->DCKCFGR & RCC_DCKCFGR_PLLI2SDIVQ) + 1U);
  575. frequency = frequency / (tmpreg1);
  576. break;
  577. }
  578. case RCC_DCKCFGR_SAI1SRC_1: /* PLLR is the clock source for SAI*/
  579. case RCC_DCKCFGR_SAI2SRC_1: /* PLLR is the clock source for SAI*/
  580. {
  581. /* Configure the PLLI2S division factor */
  582. /* PLL_VCO Input = PLL_SOURCE/PLLM */
  583. if ((RCC->PLLCFGR & RCC_PLLCFGR_PLLSRC) == RCC_PLLSOURCE_HSI)
  584. {
  585. /* In Case the PLL Source is HSI (Internal Clock) */
  586. vcoinput = (HSI_VALUE / (uint32_t)(RCC->PLLCFGR & RCC_PLLCFGR_PLLM));
  587. }
  588. else
  589. {
  590. /* In Case the PLL Source is HSE (External Clock) */
  591. vcoinput = ((HSE_VALUE / (uint32_t)(RCC->PLLCFGR & RCC_PLLCFGR_PLLM)));
  592. }
  593. /* PLL_VCO Output = PLL_VCO Input * PLLN */
  594. /* SAI_CLK_x = PLL_VCO Output/PLLR */
  595. tmpreg1 = (RCC->PLLCFGR & RCC_PLLCFGR_PLLR) >> 28U;
  596. frequency = (vcoinput * ((RCC->PLLCFGR & RCC_PLLCFGR_PLLN) >> 6U)) / (tmpreg1);
  597. break;
  598. }
  599. case RCC_DCKCFGR_SAI1SRC: /* External clock is the clock source for SAI*/
  600. {
  601. frequency = EXTERNAL_CLOCK_VALUE;
  602. break;
  603. }
  604. case RCC_DCKCFGR_SAI2SRC: /* PLLSRC(HSE or HSI) is the clock source for SAI*/
  605. {
  606. if ((RCC->PLLCFGR & RCC_PLLCFGR_PLLSRC) == RCC_PLLSOURCE_HSI)
  607. {
  608. /* In Case the PLL Source is HSI (Internal Clock) */
  609. frequency = (uint32_t)(HSI_VALUE);
  610. }
  611. else
  612. {
  613. /* In Case the PLL Source is HSE (External Clock) */
  614. frequency = (uint32_t)(HSE_VALUE);
  615. }
  616. break;
  617. }
  618. default :
  619. {
  620. break;
  621. }
  622. }
  623. break;
  624. }
  625. case RCC_PERIPHCLK_I2S_APB1:
  626. {
  627. /* Get the current I2S source */
  628. srcclk = __HAL_RCC_GET_I2S_APB1_SOURCE();
  629. switch (srcclk)
  630. {
  631. /* Check if I2S clock selection is External clock mapped on the I2S_CKIN pin used as I2S clock */
  632. case RCC_I2SAPB1CLKSOURCE_EXT:
  633. {
  634. /* Set the I2S clock to the external clock value */
  635. frequency = EXTERNAL_CLOCK_VALUE;
  636. break;
  637. }
  638. /* Check if I2S clock selection is PLLI2S VCO output clock divided by PLLI2SR used as I2S clock */
  639. case RCC_I2SAPB1CLKSOURCE_PLLI2S:
  640. {
  641. /* Configure the PLLI2S division factor */
  642. /* PLLI2S_VCO Input = PLL_SOURCE/PLLI2SM */
  643. if ((RCC->PLLCFGR & RCC_PLLCFGR_PLLSRC) == RCC_PLLSOURCE_HSE)
  644. {
  645. /* Get the I2S source clock value */
  646. vcoinput = (uint32_t)(HSE_VALUE / (uint32_t)(RCC->PLLI2SCFGR & RCC_PLLI2SCFGR_PLLI2SM));
  647. }
  648. else
  649. {
  650. /* Get the I2S source clock value */
  651. vcoinput = (uint32_t)(HSI_VALUE / (uint32_t)(RCC->PLLI2SCFGR & RCC_PLLI2SCFGR_PLLI2SM));
  652. }
  653. /* PLLI2S_VCO Output = PLLI2S_VCO Input * PLLI2SN */
  654. vcooutput = (uint32_t)(vcoinput * (((RCC->PLLI2SCFGR & RCC_PLLI2SCFGR_PLLI2SN) >> 6U) & (RCC_PLLI2SCFGR_PLLI2SN >> 6U)));
  655. /* I2S_CLK = PLLI2S_VCO Output/PLLI2SR */
  656. frequency = (uint32_t)(vcooutput / (((RCC->PLLI2SCFGR & RCC_PLLI2SCFGR_PLLI2SR) >> 28U) & (RCC_PLLI2SCFGR_PLLI2SR >> 28U)));
  657. break;
  658. }
  659. /* Check if I2S clock selection is PLL VCO Output divided by PLLR used as I2S clock */
  660. case RCC_I2SAPB1CLKSOURCE_PLLR:
  661. {
  662. /* Configure the PLL division factor R */
  663. /* PLL_VCO Input = PLL_SOURCE/PLLM */
  664. if ((RCC->PLLCFGR & RCC_PLLCFGR_PLLSRC) == RCC_PLLSOURCE_HSE)
  665. {
  666. /* Get the I2S source clock value */
  667. vcoinput = (uint32_t)(HSE_VALUE / (uint32_t)(RCC->PLLCFGR & RCC_PLLCFGR_PLLM));
  668. }
  669. else
  670. {
  671. /* Get the I2S source clock value */
  672. vcoinput = (uint32_t)(HSI_VALUE / (uint32_t)(RCC->PLLCFGR & RCC_PLLCFGR_PLLM));
  673. }
  674. /* PLL_VCO Output = PLL_VCO Input * PLLN */
  675. vcooutput = (uint32_t)(vcoinput * (((RCC->PLLCFGR & RCC_PLLCFGR_PLLN) >> 6U) & (RCC_PLLCFGR_PLLN >> 6U)));
  676. /* I2S_CLK = PLL_VCO Output/PLLR */
  677. frequency = (uint32_t)(vcooutput / (((RCC->PLLCFGR & RCC_PLLCFGR_PLLR) >> 28U) & (RCC_PLLCFGR_PLLR >> 28U)));
  678. break;
  679. }
  680. /* Check if I2S clock selection is HSI or HSE depending from PLL source Clock */
  681. case RCC_I2SAPB1CLKSOURCE_PLLSRC:
  682. {
  683. if ((RCC->PLLCFGR & RCC_PLLCFGR_PLLSRC) == RCC_PLLSOURCE_HSE)
  684. {
  685. frequency = HSE_VALUE;
  686. }
  687. else
  688. {
  689. frequency = HSI_VALUE;
  690. }
  691. break;
  692. }
  693. /* Clock not enabled for I2S*/
  694. default:
  695. {
  696. frequency = 0U;
  697. break;
  698. }
  699. }
  700. break;
  701. }
  702. case RCC_PERIPHCLK_I2S_APB2:
  703. {
  704. /* Get the current I2S source */
  705. srcclk = __HAL_RCC_GET_I2S_APB2_SOURCE();
  706. switch (srcclk)
  707. {
  708. /* Check if I2S clock selection is External clock mapped on the I2S_CKIN pin used as I2S clock */
  709. case RCC_I2SAPB2CLKSOURCE_EXT:
  710. {
  711. /* Set the I2S clock to the external clock value */
  712. frequency = EXTERNAL_CLOCK_VALUE;
  713. break;
  714. }
  715. /* Check if I2S clock selection is PLLI2S VCO output clock divided by PLLI2SR used as I2S clock */
  716. case RCC_I2SAPB2CLKSOURCE_PLLI2S:
  717. {
  718. /* Configure the PLLI2S division factor */
  719. /* PLLI2S_VCO Input = PLL_SOURCE/PLLI2SM */
  720. if ((RCC->PLLCFGR & RCC_PLLCFGR_PLLSRC) == RCC_PLLSOURCE_HSE)
  721. {
  722. /* Get the I2S source clock value */
  723. vcoinput = (uint32_t)(HSE_VALUE / (uint32_t)(RCC->PLLI2SCFGR & RCC_PLLI2SCFGR_PLLI2SM));
  724. }
  725. else
  726. {
  727. /* Get the I2S source clock value */
  728. vcoinput = (uint32_t)(HSI_VALUE / (uint32_t)(RCC->PLLI2SCFGR & RCC_PLLI2SCFGR_PLLI2SM));
  729. }
  730. /* PLLI2S_VCO Output = PLLI2S_VCO Input * PLLI2SN */
  731. vcooutput = (uint32_t)(vcoinput * (((RCC->PLLI2SCFGR & RCC_PLLI2SCFGR_PLLI2SN) >> 6U) & (RCC_PLLI2SCFGR_PLLI2SN >> 6U)));
  732. /* I2S_CLK = PLLI2S_VCO Output/PLLI2SR */
  733. frequency = (uint32_t)(vcooutput / (((RCC->PLLI2SCFGR & RCC_PLLI2SCFGR_PLLI2SR) >> 28U) & (RCC_PLLI2SCFGR_PLLI2SR >> 28U)));
  734. break;
  735. }
  736. /* Check if I2S clock selection is PLL VCO Output divided by PLLR used as I2S clock */
  737. case RCC_I2SAPB2CLKSOURCE_PLLR:
  738. {
  739. /* Configure the PLL division factor R */
  740. /* PLL_VCO Input = PLL_SOURCE/PLLM */
  741. if ((RCC->PLLCFGR & RCC_PLLCFGR_PLLSRC) == RCC_PLLSOURCE_HSE)
  742. {
  743. /* Get the I2S source clock value */
  744. vcoinput = (uint32_t)(HSE_VALUE / (uint32_t)(RCC->PLLCFGR & RCC_PLLCFGR_PLLM));
  745. }
  746. else
  747. {
  748. /* Get the I2S source clock value */
  749. vcoinput = (uint32_t)(HSI_VALUE / (uint32_t)(RCC->PLLCFGR & RCC_PLLCFGR_PLLM));
  750. }
  751. /* PLL_VCO Output = PLL_VCO Input * PLLN */
  752. vcooutput = (uint32_t)(vcoinput * (((RCC->PLLCFGR & RCC_PLLCFGR_PLLN) >> 6U) & (RCC_PLLCFGR_PLLN >> 6U)));
  753. /* I2S_CLK = PLL_VCO Output/PLLR */
  754. frequency = (uint32_t)(vcooutput / (((RCC->PLLCFGR & RCC_PLLCFGR_PLLR) >> 28U) & (RCC_PLLCFGR_PLLR >> 28U)));
  755. break;
  756. }
  757. /* Check if I2S clock selection is HSI or HSE depending from PLL source Clock */
  758. case RCC_I2SAPB2CLKSOURCE_PLLSRC:
  759. {
  760. if ((RCC->PLLCFGR & RCC_PLLCFGR_PLLSRC) == RCC_PLLSOURCE_HSE)
  761. {
  762. frequency = HSE_VALUE;
  763. }
  764. else
  765. {
  766. frequency = HSI_VALUE;
  767. }
  768. break;
  769. }
  770. /* Clock not enabled for I2S*/
  771. default:
  772. {
  773. frequency = 0U;
  774. break;
  775. }
  776. }
  777. break;
  778. }
  779. default:
  780. {
  781. break;
  782. }
  783. }
  784. return frequency;
  785. }
  786. #endif /* STM32F446xx */
  787. #if defined(STM32F469xx) || defined(STM32F479xx)
  788. /**
  789. * @brief Initializes the RCC extended peripherals clocks according to the specified
  790. * parameters in the RCC_PeriphCLKInitTypeDef.
  791. * @param PeriphClkInit pointer to an RCC_PeriphCLKInitTypeDef structure that
  792. * contains the configuration information for the Extended Peripherals
  793. * clocks(I2S, SAI, LTDC, RTC and TIM).
  794. *
  795. * @note Care must be taken when HAL_RCCEx_PeriphCLKConfig() is used to select
  796. * the RTC clock source; in this case the Backup domain will be reset in
  797. * order to modify the RTC Clock source, as consequence RTC registers (including
  798. * the backup registers) and RCC_BDCR register are set to their reset values.
  799. *
  800. * @retval HAL status
  801. */
  802. HAL_StatusTypeDef HAL_RCCEx_PeriphCLKConfig(RCC_PeriphCLKInitTypeDef *PeriphClkInit)
  803. {
  804. uint32_t tickstart = 0U;
  805. uint32_t tmpreg1 = 0U;
  806. uint32_t pllsaip = 0U;
  807. uint32_t pllsaiq = 0U;
  808. uint32_t pllsair = 0U;
  809. /* Check the parameters */
  810. assert_param(IS_RCC_PERIPHCLOCK(PeriphClkInit->PeriphClockSelection));
  811. /*--------------------------- CLK48 Configuration --------------------------*/
  812. if (((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_CLK48) == RCC_PERIPHCLK_CLK48)
  813. {
  814. /* Check the parameters */
  815. assert_param(IS_RCC_CLK48CLKSOURCE(PeriphClkInit->Clk48ClockSelection));
  816. /* Configure the CLK48 clock source */
  817. __HAL_RCC_CLK48_CONFIG(PeriphClkInit->Clk48ClockSelection);
  818. }
  819. /*--------------------------------------------------------------------------*/
  820. /*------------------------------ SDIO Configuration ------------------------*/
  821. if (((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_SDIO) == RCC_PERIPHCLK_SDIO)
  822. {
  823. /* Check the parameters */
  824. assert_param(IS_RCC_SDIOCLKSOURCE(PeriphClkInit->SdioClockSelection));
  825. /* Configure the SDIO clock source */
  826. __HAL_RCC_SDIO_CONFIG(PeriphClkInit->SdioClockSelection);
  827. }
  828. /*--------------------------------------------------------------------------*/
  829. /*----------------------- SAI/I2S Configuration (PLLI2S) -------------------*/
  830. /*------------------- Common configuration SAI/I2S -------------------------*/
  831. /* In Case of SAI or I2S Clock Configuration through PLLI2S, PLLI2SN division
  832. factor is common parameters for both peripherals */
  833. if ((((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_I2S) == RCC_PERIPHCLK_I2S) ||
  834. (((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_SAI_PLLI2S) == RCC_PERIPHCLK_SAI_PLLI2S) ||
  835. (((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_PLLI2S) == RCC_PERIPHCLK_PLLI2S))
  836. {
  837. /* check for Parameters */
  838. assert_param(IS_RCC_PLLI2SN_VALUE(PeriphClkInit->PLLI2S.PLLI2SN));
  839. /* Disable the PLLI2S */
  840. __HAL_RCC_PLLI2S_DISABLE();
  841. /* Get tick */
  842. tickstart = HAL_GetTick();
  843. /* Wait till PLLI2S is disabled */
  844. while (__HAL_RCC_GET_FLAG(RCC_FLAG_PLLI2SRDY) != RESET)
  845. {
  846. if ((HAL_GetTick() - tickstart) > PLLI2S_TIMEOUT_VALUE)
  847. {
  848. /* return in case of Timeout detected */
  849. return HAL_TIMEOUT;
  850. }
  851. }
  852. /*---------------------- I2S configuration -------------------------------*/
  853. /* In Case of I2S Clock Configuration through PLLI2S, PLLI2SR must be added
  854. only for I2S configuration */
  855. if (((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_I2S) == (RCC_PERIPHCLK_I2S))
  856. {
  857. /* check for Parameters */
  858. assert_param(IS_RCC_PLLI2SR_VALUE(PeriphClkInit->PLLI2S.PLLI2SR));
  859. /* Configure the PLLI2S division factors */
  860. /* PLLI2S_VCO = f(VCO clock) = f(PLLI2S clock input) x (PLLI2SN/PLLM) */
  861. /* I2SCLK = f(PLLI2S clock output) = f(VCO clock) / PLLI2SR */
  862. __HAL_RCC_PLLI2S_CONFIG(PeriphClkInit->PLLI2S.PLLI2SN, PeriphClkInit->PLLI2S.PLLI2SR);
  863. }
  864. /*---------------------------- SAI configuration -------------------------*/
  865. /* In Case of SAI Clock Configuration through PLLI2S, PLLI2SQ and PLLI2S_DIVQ must
  866. be added only for SAI configuration */
  867. if (((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_SAI_PLLI2S) == (RCC_PERIPHCLK_SAI_PLLI2S))
  868. {
  869. /* Check the PLLI2S division factors */
  870. assert_param(IS_RCC_PLLI2SQ_VALUE(PeriphClkInit->PLLI2S.PLLI2SQ));
  871. assert_param(IS_RCC_PLLI2S_DIVQ_VALUE(PeriphClkInit->PLLI2SDivQ));
  872. /* Read PLLI2SR value from PLLI2SCFGR register (this value is not need for SAI configuration) */
  873. tmpreg1 = ((RCC->PLLI2SCFGR & RCC_PLLI2SCFGR_PLLI2SR) >> RCC_PLLI2SCFGR_PLLI2SR_Pos);
  874. /* Configure the PLLI2S division factors */
  875. /* PLLI2S_VCO Input = PLL_SOURCE/PLLM */
  876. /* PLLI2S_VCO Output = PLLI2S_VCO Input * PLLI2SN */
  877. /* SAI_CLK(first level) = PLLI2S_VCO Output/PLLI2SQ */
  878. __HAL_RCC_PLLI2S_SAICLK_CONFIG(PeriphClkInit->PLLI2S.PLLI2SN, PeriphClkInit->PLLI2S.PLLI2SQ, tmpreg1);
  879. /* SAI_CLK_x = SAI_CLK(first level)/PLLI2SDIVQ */
  880. __HAL_RCC_PLLI2S_PLLSAICLKDIVQ_CONFIG(PeriphClkInit->PLLI2SDivQ);
  881. }
  882. /*----------------- In Case of PLLI2S is just selected -----------------*/
  883. if ((PeriphClkInit->PeriphClockSelection & RCC_PERIPHCLK_PLLI2S) == RCC_PERIPHCLK_PLLI2S)
  884. {
  885. /* Check for Parameters */
  886. assert_param(IS_RCC_PLLI2SQ_VALUE(PeriphClkInit->PLLI2S.PLLI2SQ));
  887. assert_param(IS_RCC_PLLI2SR_VALUE(PeriphClkInit->PLLI2S.PLLI2SR));
  888. /* Configure the PLLI2S multiplication and division factors */
  889. __HAL_RCC_PLLI2S_SAICLK_CONFIG(PeriphClkInit->PLLI2S.PLLI2SN, PeriphClkInit->PLLI2S.PLLI2SQ,
  890. PeriphClkInit->PLLI2S.PLLI2SR);
  891. }
  892. /* Enable the PLLI2S */
  893. __HAL_RCC_PLLI2S_ENABLE();
  894. /* Get tick */
  895. tickstart = HAL_GetTick();
  896. /* Wait till PLLI2S is ready */
  897. while (__HAL_RCC_GET_FLAG(RCC_FLAG_PLLI2SRDY) == RESET)
  898. {
  899. if ((HAL_GetTick() - tickstart) > PLLI2S_TIMEOUT_VALUE)
  900. {
  901. /* return in case of Timeout detected */
  902. return HAL_TIMEOUT;
  903. }
  904. }
  905. }
  906. /*--------------------------------------------------------------------------*/
  907. /*----------------------- SAI/LTDC Configuration (PLLSAI) ------------------*/
  908. /*----------------------- Common configuration SAI/LTDC --------------------*/
  909. /* In Case of SAI, LTDC or CLK48 Clock Configuration through PLLSAI, PLLSAIN division
  910. factor is common parameters for these peripherals */
  911. if ((((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_SAI_PLLSAI) == RCC_PERIPHCLK_SAI_PLLSAI) ||
  912. (((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_LTDC) == RCC_PERIPHCLK_LTDC) ||
  913. ((((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_CLK48) == RCC_PERIPHCLK_CLK48) &&
  914. (PeriphClkInit->Clk48ClockSelection == RCC_CLK48CLKSOURCE_PLLSAIP)))
  915. {
  916. /* Check the PLLSAI division factors */
  917. assert_param(IS_RCC_PLLSAIN_VALUE(PeriphClkInit->PLLSAI.PLLSAIN));
  918. /* Disable PLLSAI Clock */
  919. __HAL_RCC_PLLSAI_DISABLE();
  920. /* Get tick */
  921. tickstart = HAL_GetTick();
  922. /* Wait till PLLSAI is disabled */
  923. while (__HAL_RCC_PLLSAI_GET_FLAG() != RESET)
  924. {
  925. if ((HAL_GetTick() - tickstart) > PLLSAI_TIMEOUT_VALUE)
  926. {
  927. /* return in case of Timeout detected */
  928. return HAL_TIMEOUT;
  929. }
  930. }
  931. /*---------------------------- SAI configuration -------------------------*/
  932. /* In Case of SAI Clock Configuration through PLLSAI, PLLSAIQ and PLLSAI_DIVQ must
  933. be added only for SAI configuration */
  934. if (((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_SAI_PLLSAI) == (RCC_PERIPHCLK_SAI_PLLSAI))
  935. {
  936. assert_param(IS_RCC_PLLSAIQ_VALUE(PeriphClkInit->PLLSAI.PLLSAIQ));
  937. assert_param(IS_RCC_PLLSAI_DIVQ_VALUE(PeriphClkInit->PLLSAIDivQ));
  938. /* Read PLLSAIP value from PLLSAICFGR register (this value is not needed for SAI configuration) */
  939. pllsaip = ((((RCC->PLLSAICFGR & RCC_PLLSAICFGR_PLLSAIP) >> RCC_PLLSAICFGR_PLLSAIP_Pos) + 1U) << 1U);
  940. /* Read PLLSAIR value from PLLSAICFGR register (this value is not need for SAI configuration) */
  941. pllsair = ((RCC->PLLSAICFGR & RCC_PLLSAICFGR_PLLSAIR) >> RCC_PLLSAICFGR_PLLSAIR_Pos);
  942. /* PLLSAI_VCO Input = PLL_SOURCE/PLLM */
  943. /* PLLSAI_VCO Output = PLLSAI_VCO Input * PLLSAIN */
  944. /* SAI_CLK(first level) = PLLSAI_VCO Output/PLLSAIQ */
  945. __HAL_RCC_PLLSAI_CONFIG(PeriphClkInit->PLLSAI.PLLSAIN, pllsaip, PeriphClkInit->PLLSAI.PLLSAIQ, pllsair);
  946. /* SAI_CLK_x = SAI_CLK(first level)/PLLSAIDIVQ */
  947. __HAL_RCC_PLLSAI_PLLSAICLKDIVQ_CONFIG(PeriphClkInit->PLLSAIDivQ);
  948. }
  949. /*---------------------------- LTDC configuration ------------------------*/
  950. if (((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_LTDC) == (RCC_PERIPHCLK_LTDC))
  951. {
  952. assert_param(IS_RCC_PLLSAIR_VALUE(PeriphClkInit->PLLSAI.PLLSAIR));
  953. assert_param(IS_RCC_PLLSAI_DIVR_VALUE(PeriphClkInit->PLLSAIDivR));
  954. /* Read PLLSAIP value from PLLSAICFGR register (this value is not needed for SAI configuration) */
  955. pllsaip = ((((RCC->PLLSAICFGR & RCC_PLLSAICFGR_PLLSAIP) >> RCC_PLLSAICFGR_PLLSAIP_Pos) + 1U) << 1U);
  956. /* Read PLLSAIQ value from PLLSAICFGR register (this value is not need for SAI configuration) */
  957. pllsaiq = ((RCC->PLLSAICFGR & RCC_PLLSAICFGR_PLLSAIQ) >> RCC_PLLSAICFGR_PLLSAIQ_Pos);
  958. /* PLLSAI_VCO Input = PLL_SOURCE/PLLM */
  959. /* PLLSAI_VCO Output = PLLSAI_VCO Input * PLLSAIN */
  960. /* LTDC_CLK(first level) = PLLSAI_VCO Output/PLLSAIR */
  961. __HAL_RCC_PLLSAI_CONFIG(PeriphClkInit->PLLSAI.PLLSAIN, pllsaip, pllsaiq, PeriphClkInit->PLLSAI.PLLSAIR);
  962. /* LTDC_CLK = LTDC_CLK(first level)/PLLSAIDIVR */
  963. __HAL_RCC_PLLSAI_PLLSAICLKDIVR_CONFIG(PeriphClkInit->PLLSAIDivR);
  964. }
  965. /*---------------------------- CLK48 configuration ------------------------*/
  966. /* Configure the PLLSAI when it is used as clock source for CLK48 */
  967. if ((((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_CLK48) == (RCC_PERIPHCLK_CLK48)) &&
  968. (PeriphClkInit->Clk48ClockSelection == RCC_CLK48CLKSOURCE_PLLSAIP))
  969. {
  970. assert_param(IS_RCC_PLLSAIP_VALUE(PeriphClkInit->PLLSAI.PLLSAIP));
  971. /* Read PLLSAIQ value from PLLSAICFGR register (this value is not need for SAI configuration) */
  972. pllsaiq = ((RCC->PLLSAICFGR & RCC_PLLSAICFGR_PLLSAIQ) >> RCC_PLLSAICFGR_PLLSAIQ_Pos);
  973. /* Read PLLSAIR value from PLLSAICFGR register (this value is not need for SAI configuration) */
  974. pllsair = ((RCC->PLLSAICFGR & RCC_PLLSAICFGR_PLLSAIR) >> RCC_PLLSAICFGR_PLLSAIR_Pos);
  975. /* PLLSAI_VCO Input = PLL_SOURCE/PLLM */
  976. /* PLLSAI_VCO Output = PLLSAI_VCO Input * PLLSAIN */
  977. /* CLK48_CLK(first level) = PLLSAI_VCO Output/PLLSAIP */
  978. __HAL_RCC_PLLSAI_CONFIG(PeriphClkInit->PLLSAI.PLLSAIN, PeriphClkInit->PLLSAI.PLLSAIP, pllsaiq, pllsair);
  979. }
  980. /* Enable PLLSAI Clock */
  981. __HAL_RCC_PLLSAI_ENABLE();
  982. /* Get tick */
  983. tickstart = HAL_GetTick();
  984. /* Wait till PLLSAI is ready */
  985. while (__HAL_RCC_PLLSAI_GET_FLAG() == RESET)
  986. {
  987. if ((HAL_GetTick() - tickstart) > PLLSAI_TIMEOUT_VALUE)
  988. {
  989. /* return in case of Timeout detected */
  990. return HAL_TIMEOUT;
  991. }
  992. }
  993. }
  994. /*--------------------------------------------------------------------------*/
  995. /*---------------------------- RTC configuration ---------------------------*/
  996. if (((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_RTC) == (RCC_PERIPHCLK_RTC))
  997. {
  998. /* Check for RTC Parameters used to output RTCCLK */
  999. assert_param(IS_RCC_RTCCLKSOURCE(PeriphClkInit->RTCClockSelection));
  1000. /* Enable Power Clock*/
  1001. __HAL_RCC_PWR_CLK_ENABLE();
  1002. /* Enable write access to Backup domain */
  1003. PWR->CR |= PWR_CR_DBP;
  1004. /* Get tick */
  1005. tickstart = HAL_GetTick();
  1006. while ((PWR->CR & PWR_CR_DBP) == RESET)
  1007. {
  1008. if ((HAL_GetTick() - tickstart) > RCC_DBP_TIMEOUT_VALUE)
  1009. {
  1010. return HAL_TIMEOUT;
  1011. }
  1012. }
  1013. /* Reset the Backup domain only if the RTC Clock source selection is modified from reset value */
  1014. tmpreg1 = (RCC->BDCR & RCC_BDCR_RTCSEL);
  1015. if ((tmpreg1 != 0x00000000U) && ((tmpreg1) != (PeriphClkInit->RTCClockSelection & RCC_BDCR_RTCSEL)))
  1016. {
  1017. /* Store the content of BDCR register before the reset of Backup Domain */
  1018. tmpreg1 = (RCC->BDCR & ~(RCC_BDCR_RTCSEL));
  1019. /* RTC Clock selection can be changed only if the Backup Domain is reset */
  1020. __HAL_RCC_BACKUPRESET_FORCE();
  1021. __HAL_RCC_BACKUPRESET_RELEASE();
  1022. /* Restore the Content of BDCR register */
  1023. RCC->BDCR = tmpreg1;
  1024. /* Wait for LSE reactivation if LSE was enable prior to Backup Domain reset */
  1025. if (HAL_IS_BIT_SET(RCC->BDCR, RCC_BDCR_LSEON))
  1026. {
  1027. /* Get tick */
  1028. tickstart = HAL_GetTick();
  1029. /* Wait till LSE is ready */
  1030. while (__HAL_RCC_GET_FLAG(RCC_FLAG_LSERDY) == RESET)
  1031. {
  1032. if ((HAL_GetTick() - tickstart) > RCC_LSE_TIMEOUT_VALUE)
  1033. {
  1034. return HAL_TIMEOUT;
  1035. }
  1036. }
  1037. }
  1038. }
  1039. __HAL_RCC_RTC_CONFIG(PeriphClkInit->RTCClockSelection);
  1040. }
  1041. /*--------------------------------------------------------------------------*/
  1042. /*---------------------------- TIM configuration ---------------------------*/
  1043. if (((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_TIM) == (RCC_PERIPHCLK_TIM))
  1044. {
  1045. __HAL_RCC_TIMCLKPRESCALER(PeriphClkInit->TIMPresSelection);
  1046. }
  1047. return HAL_OK;
  1048. }
  1049. /**
  1050. * @brief Configures the RCC_PeriphCLKInitTypeDef according to the internal
  1051. * RCC configuration registers.
  1052. * @param PeriphClkInit pointer to an RCC_PeriphCLKInitTypeDef structure that
  1053. * will be configured.
  1054. * @retval None
  1055. */
  1056. void HAL_RCCEx_GetPeriphCLKConfig(RCC_PeriphCLKInitTypeDef *PeriphClkInit)
  1057. {
  1058. uint32_t tempreg;
  1059. /* Set all possible values for the extended clock type parameter------------*/
  1060. PeriphClkInit->PeriphClockSelection = RCC_PERIPHCLK_I2S | RCC_PERIPHCLK_SAI_PLLSAI | \
  1061. RCC_PERIPHCLK_SAI_PLLI2S | RCC_PERIPHCLK_LTDC | \
  1062. RCC_PERIPHCLK_TIM | RCC_PERIPHCLK_RTC | \
  1063. RCC_PERIPHCLK_CLK48 | RCC_PERIPHCLK_SDIO;
  1064. /* Get the PLLI2S Clock configuration --------------------------------------*/
  1065. PeriphClkInit->PLLI2S.PLLI2SN = (uint32_t)((RCC->PLLI2SCFGR & RCC_PLLI2SCFGR_PLLI2SN) >> RCC_PLLI2SCFGR_PLLI2SN_Pos);
  1066. PeriphClkInit->PLLI2S.PLLI2SR = (uint32_t)((RCC->PLLI2SCFGR & RCC_PLLI2SCFGR_PLLI2SR) >> RCC_PLLI2SCFGR_PLLI2SR_Pos);
  1067. PeriphClkInit->PLLI2S.PLLI2SQ = (uint32_t)((RCC->PLLI2SCFGR & RCC_PLLI2SCFGR_PLLI2SQ) >> RCC_PLLI2SCFGR_PLLI2SQ_Pos);
  1068. /* Get the PLLSAI Clock configuration --------------------------------------*/
  1069. PeriphClkInit->PLLSAI.PLLSAIN = (uint32_t)((RCC->PLLSAICFGR & RCC_PLLSAICFGR_PLLSAIN) >> RCC_PLLSAICFGR_PLLSAIN_Pos);
  1070. PeriphClkInit->PLLSAI.PLLSAIR = (uint32_t)((RCC->PLLSAICFGR & RCC_PLLSAICFGR_PLLSAIR) >> RCC_PLLSAICFGR_PLLSAIR_Pos);
  1071. PeriphClkInit->PLLSAI.PLLSAIQ = (uint32_t)((RCC->PLLSAICFGR & RCC_PLLSAICFGR_PLLSAIQ) >> RCC_PLLSAICFGR_PLLSAIQ_Pos);
  1072. /* Get the PLLSAI/PLLI2S division factors ----------------------------------*/
  1073. PeriphClkInit->PLLI2SDivQ = (uint32_t)((RCC->DCKCFGR & RCC_DCKCFGR_PLLI2SDIVQ) >> RCC_DCKCFGR_PLLI2SDIVQ_Pos);
  1074. PeriphClkInit->PLLSAIDivQ = (uint32_t)((RCC->DCKCFGR & RCC_DCKCFGR_PLLSAIDIVQ) >> RCC_DCKCFGR_PLLSAIDIVQ_Pos);
  1075. PeriphClkInit->PLLSAIDivR = (uint32_t)(RCC->DCKCFGR & RCC_DCKCFGR_PLLSAIDIVR);
  1076. /* Get the RTC Clock configuration -----------------------------------------*/
  1077. tempreg = (RCC->CFGR & RCC_CFGR_RTCPRE);
  1078. PeriphClkInit->RTCClockSelection = (uint32_t)((tempreg) | (RCC->BDCR & RCC_BDCR_RTCSEL));
  1079. /* Get the CLK48 clock configuration -------------------------------------*/
  1080. PeriphClkInit->Clk48ClockSelection = __HAL_RCC_GET_CLK48_SOURCE();
  1081. /* Get the SDIO clock configuration ----------------------------------------*/
  1082. PeriphClkInit->SdioClockSelection = __HAL_RCC_GET_SDIO_SOURCE();
  1083. if ((RCC->DCKCFGR & RCC_DCKCFGR_TIMPRE) == RESET)
  1084. {
  1085. PeriphClkInit->TIMPresSelection = RCC_TIMPRES_DESACTIVATED;
  1086. }
  1087. else
  1088. {
  1089. PeriphClkInit->TIMPresSelection = RCC_TIMPRES_ACTIVATED;
  1090. }
  1091. }
  1092. /**
  1093. * @brief Return the peripheral clock frequency for a given peripheral(SAI..)
  1094. * @note Return 0 if peripheral clock identifier not managed by this API
  1095. * @param PeriphClk Peripheral clock identifier
  1096. * This parameter can be one of the following values:
  1097. * @arg RCC_PERIPHCLK_I2S: I2S peripheral clock
  1098. * @retval Frequency in KHz
  1099. */
  1100. uint32_t HAL_RCCEx_GetPeriphCLKFreq(uint32_t PeriphClk)
  1101. {
  1102. /* This variable used to store the I2S clock frequency (value in Hz) */
  1103. uint32_t frequency = 0U;
  1104. /* This variable used to store the VCO Input (value in Hz) */
  1105. uint32_t vcoinput = 0U;
  1106. uint32_t srcclk = 0U;
  1107. /* This variable used to store the VCO Output (value in Hz) */
  1108. uint32_t vcooutput = 0U;
  1109. switch (PeriphClk)
  1110. {
  1111. case RCC_PERIPHCLK_I2S:
  1112. {
  1113. /* Get the current I2S source */
  1114. srcclk = __HAL_RCC_GET_I2S_SOURCE();
  1115. switch (srcclk)
  1116. {
  1117. /* Check if I2S clock selection is External clock mapped on the I2S_CKIN pin used as I2S clock */
  1118. case RCC_I2SCLKSOURCE_EXT:
  1119. {
  1120. /* Set the I2S clock to the external clock value */
  1121. frequency = EXTERNAL_CLOCK_VALUE;
  1122. break;
  1123. }
  1124. /* Check if I2S clock selection is PLLI2S VCO output clock divided by PLLI2SR used as I2S clock */
  1125. case RCC_I2SCLKSOURCE_PLLI2S:
  1126. {
  1127. /* Configure the PLLI2S division factor */
  1128. /* PLLI2S_VCO Input = PLL_SOURCE/PLLI2SM */
  1129. if ((RCC->PLLCFGR & RCC_PLLCFGR_PLLSRC) == RCC_PLLSOURCE_HSE)
  1130. {
  1131. /* Get the I2S source clock value */
  1132. vcoinput = (uint32_t)(HSE_VALUE / (uint32_t)(RCC->PLLCFGR & RCC_PLLCFGR_PLLM));
  1133. }
  1134. else
  1135. {
  1136. /* Get the I2S source clock value */
  1137. vcoinput = (uint32_t)(HSI_VALUE / (uint32_t)(RCC->PLLCFGR & RCC_PLLCFGR_PLLM));
  1138. }
  1139. /* PLLI2S_VCO Output = PLLI2S_VCO Input * PLLI2SN */
  1140. vcooutput = (uint32_t)(vcoinput * (((RCC->PLLI2SCFGR & RCC_PLLI2SCFGR_PLLI2SN) >> 6U) & (RCC_PLLI2SCFGR_PLLI2SN >> 6U)));
  1141. /* I2S_CLK = PLLI2S_VCO Output/PLLI2SR */
  1142. frequency = (uint32_t)(vcooutput / (((RCC->PLLI2SCFGR & RCC_PLLI2SCFGR_PLLI2SR) >> 28U) & (RCC_PLLI2SCFGR_PLLI2SR >> 28U)));
  1143. break;
  1144. }
  1145. /* Clock not enabled for I2S*/
  1146. default:
  1147. {
  1148. frequency = 0U;
  1149. break;
  1150. }
  1151. }
  1152. break;
  1153. }
  1154. default:
  1155. {
  1156. break;
  1157. }
  1158. }
  1159. return frequency;
  1160. }
  1161. #endif /* STM32F469xx || STM32F479xx */
  1162. #if defined(STM32F412Zx) || defined(STM32F412Vx) || defined(STM32F412Rx) || defined(STM32F412Cx) || defined(STM32F413xx) || defined(STM32F423xx)
  1163. /**
  1164. * @brief Initializes the RCC extended peripherals clocks according to the specified
  1165. * parameters in the RCC_PeriphCLKInitTypeDef.
  1166. * @param PeriphClkInit pointer to an RCC_PeriphCLKInitTypeDef structure that
  1167. * contains the configuration information for the Extended Peripherals
  1168. * clocks(I2S, LTDC RTC and TIM).
  1169. *
  1170. * @note Care must be taken when HAL_RCCEx_PeriphCLKConfig() is used to select
  1171. * the RTC clock source; in this case the Backup domain will be reset in
  1172. * order to modify the RTC Clock source, as consequence RTC registers (including
  1173. * the backup registers) and RCC_BDCR register are set to their reset values.
  1174. *
  1175. * @retval HAL status
  1176. */
  1177. HAL_StatusTypeDef HAL_RCCEx_PeriphCLKConfig(RCC_PeriphCLKInitTypeDef *PeriphClkInit)
  1178. {
  1179. uint32_t tickstart = 0U;
  1180. uint32_t tmpreg1 = 0U;
  1181. #if defined(STM32F413xx) || defined(STM32F423xx)
  1182. uint32_t plli2sq = 0U;
  1183. #endif /* STM32F413xx || STM32F423xx */
  1184. uint32_t plli2sused = 0U;
  1185. /* Check the peripheral clock selection parameters */
  1186. assert_param(IS_RCC_PERIPHCLOCK(PeriphClkInit->PeriphClockSelection));
  1187. /*----------------------------------- I2S APB1 configuration ---------------*/
  1188. if (((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_I2S_APB1) == (RCC_PERIPHCLK_I2S_APB1))
  1189. {
  1190. /* Check the parameters */
  1191. assert_param(IS_RCC_I2SAPB1CLKSOURCE(PeriphClkInit->I2sApb1ClockSelection));
  1192. /* Configure I2S Clock source */
  1193. __HAL_RCC_I2S_APB1_CONFIG(PeriphClkInit->I2sApb1ClockSelection);
  1194. /* Enable the PLLI2S when it's used as clock source for I2S */
  1195. if (PeriphClkInit->I2sApb1ClockSelection == RCC_I2SAPB1CLKSOURCE_PLLI2S)
  1196. {
  1197. plli2sused = 1U;
  1198. }
  1199. }
  1200. /*--------------------------------------------------------------------------*/
  1201. /*----------------------------------- I2S APB2 configuration ---------------*/
  1202. if (((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_I2S_APB2) == (RCC_PERIPHCLK_I2S_APB2))
  1203. {
  1204. /* Check the parameters */
  1205. assert_param(IS_RCC_I2SAPB2CLKSOURCE(PeriphClkInit->I2sApb2ClockSelection));
  1206. /* Configure I2S Clock source */
  1207. __HAL_RCC_I2S_APB2_CONFIG(PeriphClkInit->I2sApb2ClockSelection);
  1208. /* Enable the PLLI2S when it's used as clock source for I2S */
  1209. if (PeriphClkInit->I2sApb2ClockSelection == RCC_I2SAPB2CLKSOURCE_PLLI2S)
  1210. {
  1211. plli2sused = 1U;
  1212. }
  1213. }
  1214. /*--------------------------------------------------------------------------*/
  1215. #if defined(STM32F413xx) || defined(STM32F423xx)
  1216. /*----------------------- SAI1 Block A configuration -----------------------*/
  1217. if (((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_SAIA) == (RCC_PERIPHCLK_SAIA))
  1218. {
  1219. /* Check the parameters */
  1220. assert_param(IS_RCC_SAIACLKSOURCE(PeriphClkInit->SaiAClockSelection));
  1221. /* Configure SAI1 Clock source */
  1222. __HAL_RCC_SAI_BLOCKACLKSOURCE_CONFIG(PeriphClkInit->SaiAClockSelection);
  1223. /* Enable the PLLI2S when it's used as clock source for SAI */
  1224. if (PeriphClkInit->SaiAClockSelection == RCC_SAIACLKSOURCE_PLLI2SR)
  1225. {
  1226. plli2sused = 1U;
  1227. }
  1228. /* Enable the PLLSAI when it's used as clock source for SAI */
  1229. if (PeriphClkInit->SaiAClockSelection == RCC_SAIACLKSOURCE_PLLR)
  1230. {
  1231. /* Check for PLL/DIVR parameters */
  1232. assert_param(IS_RCC_PLL_DIVR_VALUE(PeriphClkInit->PLLDivR));
  1233. /* SAI_CLK_x = SAI_CLK(first level)/PLLDIVR */
  1234. __HAL_RCC_PLL_PLLSAICLKDIVR_CONFIG(PeriphClkInit->PLLDivR);
  1235. }
  1236. }
  1237. /*--------------------------------------------------------------------------*/
  1238. /*---------------------- SAI1 Block B configuration ------------------------*/
  1239. if (((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_SAIB) == (RCC_PERIPHCLK_SAIB))
  1240. {
  1241. /* Check the parameters */
  1242. assert_param(IS_RCC_SAIBCLKSOURCE(PeriphClkInit->SaiBClockSelection));
  1243. /* Configure SAI1 Clock source */
  1244. __HAL_RCC_SAI_BLOCKBCLKSOURCE_CONFIG(PeriphClkInit->SaiBClockSelection);
  1245. /* Enable the PLLI2S when it's used as clock source for SAI */
  1246. if (PeriphClkInit->SaiBClockSelection == RCC_SAIBCLKSOURCE_PLLI2SR)
  1247. {
  1248. plli2sused = 1U;
  1249. }
  1250. /* Enable the PLLSAI when it's used as clock source for SAI */
  1251. if (PeriphClkInit->SaiBClockSelection == RCC_SAIBCLKSOURCE_PLLR)
  1252. {
  1253. /* Check for PLL/DIVR parameters */
  1254. assert_param(IS_RCC_PLL_DIVR_VALUE(PeriphClkInit->PLLDivR));
  1255. /* SAI_CLK_x = SAI_CLK(first level)/PLLDIVR */
  1256. __HAL_RCC_PLL_PLLSAICLKDIVR_CONFIG(PeriphClkInit->PLLDivR);
  1257. }
  1258. }
  1259. /*--------------------------------------------------------------------------*/
  1260. #endif /* STM32F413xx || STM32F423xx */
  1261. /*------------------------------------ RTC configuration -------------------*/
  1262. if (((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_RTC) == (RCC_PERIPHCLK_RTC))
  1263. {
  1264. /* Check for RTC Parameters used to output RTCCLK */
  1265. assert_param(IS_RCC_RTCCLKSOURCE(PeriphClkInit->RTCClockSelection));
  1266. /* Enable Power Clock*/
  1267. __HAL_RCC_PWR_CLK_ENABLE();
  1268. /* Enable write access to Backup domain */
  1269. PWR->CR |= PWR_CR_DBP;
  1270. /* Get tick */
  1271. tickstart = HAL_GetTick();
  1272. while ((PWR->CR & PWR_CR_DBP) == RESET)
  1273. {
  1274. if ((HAL_GetTick() - tickstart) > RCC_DBP_TIMEOUT_VALUE)
  1275. {
  1276. return HAL_TIMEOUT;
  1277. }
  1278. }
  1279. /* Reset the Backup domain only if the RTC Clock source selection is modified from reset value */
  1280. tmpreg1 = (RCC->BDCR & RCC_BDCR_RTCSEL);
  1281. if ((tmpreg1 != 0x00000000U) && ((tmpreg1) != (PeriphClkInit->RTCClockSelection & RCC_BDCR_RTCSEL)))
  1282. {
  1283. /* Store the content of BDCR register before the reset of Backup Domain */
  1284. tmpreg1 = (RCC->BDCR & ~(RCC_BDCR_RTCSEL));
  1285. /* RTC Clock selection can be changed only if the Backup Domain is reset */
  1286. __HAL_RCC_BACKUPRESET_FORCE();
  1287. __HAL_RCC_BACKUPRESET_RELEASE();
  1288. /* Restore the Content of BDCR register */
  1289. RCC->BDCR = tmpreg1;
  1290. /* Wait for LSE reactivation if LSE was enable prior to Backup Domain reset */
  1291. if (HAL_IS_BIT_SET(RCC->BDCR, RCC_BDCR_LSEON))
  1292. {
  1293. /* Get tick */
  1294. tickstart = HAL_GetTick();
  1295. /* Wait till LSE is ready */
  1296. while (__HAL_RCC_GET_FLAG(RCC_FLAG_LSERDY) == RESET)
  1297. {
  1298. if ((HAL_GetTick() - tickstart) > RCC_LSE_TIMEOUT_VALUE)
  1299. {
  1300. return HAL_TIMEOUT;
  1301. }
  1302. }
  1303. }
  1304. }
  1305. __HAL_RCC_RTC_CONFIG(PeriphClkInit->RTCClockSelection);
  1306. }
  1307. /*--------------------------------------------------------------------------*/
  1308. /*------------------------------------ TIM configuration -------------------*/
  1309. if (((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_TIM) == (RCC_PERIPHCLK_TIM))
  1310. {
  1311. /* Configure Timer Prescaler */
  1312. __HAL_RCC_TIMCLKPRESCALER(PeriphClkInit->TIMPresSelection);
  1313. }
  1314. /*--------------------------------------------------------------------------*/
  1315. /*------------------------------------- FMPI2C1 Configuration --------------*/
  1316. if (((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_FMPI2C1) == RCC_PERIPHCLK_FMPI2C1)
  1317. {
  1318. /* Check the parameters */
  1319. assert_param(IS_RCC_FMPI2C1CLKSOURCE(PeriphClkInit->Fmpi2c1ClockSelection));
  1320. /* Configure the FMPI2C1 clock source */
  1321. __HAL_RCC_FMPI2C1_CONFIG(PeriphClkInit->Fmpi2c1ClockSelection);
  1322. }
  1323. /*--------------------------------------------------------------------------*/
  1324. /*------------------------------------- CLK48 Configuration ----------------*/
  1325. if (((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_CLK48) == RCC_PERIPHCLK_CLK48)
  1326. {
  1327. /* Check the parameters */
  1328. assert_param(IS_RCC_CLK48CLKSOURCE(PeriphClkInit->Clk48ClockSelection));
  1329. /* Configure the SDIO clock source */
  1330. __HAL_RCC_CLK48_CONFIG(PeriphClkInit->Clk48ClockSelection);
  1331. /* Enable the PLLI2S when it's used as clock source for CLK48 */
  1332. if (PeriphClkInit->Clk48ClockSelection == RCC_CLK48CLKSOURCE_PLLI2SQ)
  1333. {
  1334. plli2sused = 1U;
  1335. }
  1336. }
  1337. /*--------------------------------------------------------------------------*/
  1338. /*------------------------------------- SDIO Configuration -----------------*/
  1339. if (((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_SDIO) == RCC_PERIPHCLK_SDIO)
  1340. {
  1341. /* Check the parameters */
  1342. assert_param(IS_RCC_SDIOCLKSOURCE(PeriphClkInit->SdioClockSelection));
  1343. /* Configure the SDIO clock source */
  1344. __HAL_RCC_SDIO_CONFIG(PeriphClkInit->SdioClockSelection);
  1345. }
  1346. /*--------------------------------------------------------------------------*/
  1347. /*-------------------------------------- PLLI2S Configuration --------------*/
  1348. /* PLLI2S is configured when a peripheral will use it as source clock : I2S on APB1 or
  1349. I2S on APB2*/
  1350. if ((plli2sused == 1U) || (PeriphClkInit->PeriphClockSelection == RCC_PERIPHCLK_PLLI2S))
  1351. {
  1352. /* Disable the PLLI2S */
  1353. __HAL_RCC_PLLI2S_DISABLE();
  1354. /* Get tick */
  1355. tickstart = HAL_GetTick();
  1356. /* Wait till PLLI2S is disabled */
  1357. while (__HAL_RCC_GET_FLAG(RCC_FLAG_PLLI2SRDY) != RESET)
  1358. {
  1359. if ((HAL_GetTick() - tickstart) > PLLI2S_TIMEOUT_VALUE)
  1360. {
  1361. /* return in case of Timeout detected */
  1362. return HAL_TIMEOUT;
  1363. }
  1364. }
  1365. /* check for common PLLI2S Parameters */
  1366. assert_param(IS_RCC_PLLI2SCLKSOURCE(PeriphClkInit->PLLI2SSelection));
  1367. assert_param(IS_RCC_PLLI2SM_VALUE(PeriphClkInit->PLLI2S.PLLI2SM));
  1368. assert_param(IS_RCC_PLLI2SN_VALUE(PeriphClkInit->PLLI2S.PLLI2SN));
  1369. /*-------------------- Set the PLL I2S clock -----------------------------*/
  1370. __HAL_RCC_PLL_I2S_CONFIG(PeriphClkInit->PLLI2SSelection);
  1371. /*------- In Case of PLLI2S is selected as source clock for I2S ----------*/
  1372. if (((((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_I2S_APB1) == RCC_PERIPHCLK_I2S_APB1)
  1373. && (PeriphClkInit->I2sApb1ClockSelection == RCC_I2SAPB1CLKSOURCE_PLLI2S)) ||
  1374. ((((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_I2S_APB2) == RCC_PERIPHCLK_I2S_APB2) && (PeriphClkInit->I2sApb2ClockSelection == RCC_I2SAPB2CLKSOURCE_PLLI2S)) ||
  1375. ((((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_CLK48) == RCC_PERIPHCLK_CLK48) && (PeriphClkInit->Clk48ClockSelection == RCC_CLK48CLKSOURCE_PLLI2SQ)) ||
  1376. ((((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_SDIO) == RCC_PERIPHCLK_SDIO) && (PeriphClkInit->SdioClockSelection == RCC_SDIOCLKSOURCE_CLK48) && (PeriphClkInit->Clk48ClockSelection == RCC_CLK48CLKSOURCE_PLLI2SQ)))
  1377. {
  1378. /* check for Parameters */
  1379. assert_param(IS_RCC_PLLI2SR_VALUE(PeriphClkInit->PLLI2S.PLLI2SR));
  1380. assert_param(IS_RCC_PLLI2SQ_VALUE(PeriphClkInit->PLLI2S.PLLI2SQ));
  1381. /* Configure the PLLI2S division factors */
  1382. /* PLLI2S_VCO = f(VCO clock) = f(PLLI2S clock input) * (PLLI2SN/PLLI2SM)*/
  1383. /* I2SCLK = f(PLLI2S clock output) = f(VCO clock) / PLLI2SR */
  1384. __HAL_RCC_PLLI2S_CONFIG(PeriphClkInit->PLLI2S.PLLI2SM, PeriphClkInit->PLLI2S.PLLI2SN, PeriphClkInit->PLLI2S.PLLI2SQ,
  1385. PeriphClkInit->PLLI2S.PLLI2SR);
  1386. }
  1387. #if defined(STM32F413xx) || defined(STM32F423xx)
  1388. /*------- In Case of PLLI2S is selected as source clock for SAI ----------*/
  1389. if (((((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_SAIA) == RCC_PERIPHCLK_SAIA)
  1390. && (PeriphClkInit->SaiAClockSelection == RCC_SAIACLKSOURCE_PLLI2SR)) ||
  1391. ((((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_SAIB) == RCC_PERIPHCLK_SAIB) && (PeriphClkInit->SaiBClockSelection == RCC_SAIBCLKSOURCE_PLLI2SR)))
  1392. {
  1393. /* Check for PLLI2S Parameters */
  1394. assert_param(IS_RCC_PLLI2SR_VALUE(PeriphClkInit->PLLI2S.PLLI2SR));
  1395. /* Check for PLLI2S/DIVR parameters */
  1396. assert_param(IS_RCC_PLLI2S_DIVR_VALUE(PeriphClkInit->PLLI2SDivR));
  1397. /* Read PLLI2SQ value from PLLI2SCFGR register (this value is not needed for SAI configuration) */
  1398. plli2sq = ((RCC->PLLI2SCFGR & RCC_PLLI2SCFGR_PLLI2SQ) >> RCC_PLLI2SCFGR_PLLI2SQ_Pos);
  1399. /* Configure the PLLI2S division factors */
  1400. /* PLLI2S_VCO Input = PLL_SOURCE/PLLI2SM */
  1401. /* PLLI2S_VCO Output = PLLI2S_VCO Input * PLLI2SN */
  1402. /* SAI_CLK(first level) = PLLI2S_VCO Output/PLLI2SQ */
  1403. __HAL_RCC_PLLI2S_CONFIG(PeriphClkInit->PLLI2S.PLLI2SM, PeriphClkInit->PLLI2S.PLLI2SN, plli2sq,
  1404. PeriphClkInit->PLLI2S.PLLI2SR);
  1405. /* SAI_CLK_x = SAI_CLK(first level)/PLLI2SDIVR */
  1406. __HAL_RCC_PLLI2S_PLLSAICLKDIVR_CONFIG(PeriphClkInit->PLLI2SDivR);
  1407. }
  1408. #endif /* STM32F413xx || STM32F423xx */
  1409. /*----------------- In Case of PLLI2S is just selected ------------------*/
  1410. if ((PeriphClkInit->PeriphClockSelection & RCC_PERIPHCLK_PLLI2S) == RCC_PERIPHCLK_PLLI2S)
  1411. {
  1412. /* Check for Parameters */
  1413. assert_param(IS_RCC_PLLI2SR_VALUE(PeriphClkInit->PLLI2S.PLLI2SR));
  1414. assert_param(IS_RCC_PLLI2SQ_VALUE(PeriphClkInit->PLLI2S.PLLI2SQ));
  1415. /* Configure the PLLI2S division factors */
  1416. /* PLLI2S_VCO = f(VCO clock) = f(PLLI2S clock input) * (PLLI2SN/PLLI2SM)*/
  1417. /* SPDIFRXCLK = f(PLLI2S clock output) = f(VCO clock) / PLLI2SP */
  1418. __HAL_RCC_PLLI2S_CONFIG(PeriphClkInit->PLLI2S.PLLI2SM, PeriphClkInit->PLLI2S.PLLI2SN, PeriphClkInit->PLLI2S.PLLI2SQ,
  1419. PeriphClkInit->PLLI2S.PLLI2SR);
  1420. }
  1421. /* Enable the PLLI2S */
  1422. __HAL_RCC_PLLI2S_ENABLE();
  1423. /* Get tick */
  1424. tickstart = HAL_GetTick();
  1425. /* Wait till PLLI2S is ready */
  1426. while (__HAL_RCC_GET_FLAG(RCC_FLAG_PLLI2SRDY) == RESET)
  1427. {
  1428. if ((HAL_GetTick() - tickstart) > PLLI2S_TIMEOUT_VALUE)
  1429. {
  1430. /* return in case of Timeout detected */
  1431. return HAL_TIMEOUT;
  1432. }
  1433. }
  1434. }
  1435. /*--------------------------------------------------------------------------*/
  1436. /*-------------------- DFSDM1 clock source configuration -------------------*/
  1437. if (((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_DFSDM1) == RCC_PERIPHCLK_DFSDM1)
  1438. {
  1439. /* Check the parameters */
  1440. assert_param(IS_RCC_DFSDM1CLKSOURCE(PeriphClkInit->Dfsdm1ClockSelection));
  1441. /* Configure the DFSDM1 interface clock source */
  1442. __HAL_RCC_DFSDM1_CONFIG(PeriphClkInit->Dfsdm1ClockSelection);
  1443. }
  1444. /*--------------------------------------------------------------------------*/
  1445. /*-------------------- DFSDM1 Audio clock source configuration -------------*/
  1446. if (((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_DFSDM1_AUDIO) == RCC_PERIPHCLK_DFSDM1_AUDIO)
  1447. {
  1448. /* Check the parameters */
  1449. assert_param(IS_RCC_DFSDM1AUDIOCLKSOURCE(PeriphClkInit->Dfsdm1AudioClockSelection));
  1450. /* Configure the DFSDM1 Audio interface clock source */
  1451. __HAL_RCC_DFSDM1AUDIO_CONFIG(PeriphClkInit->Dfsdm1AudioClockSelection);
  1452. }
  1453. /*--------------------------------------------------------------------------*/
  1454. #if defined(STM32F413xx) || defined(STM32F423xx)
  1455. /*-------------------- DFSDM2 clock source configuration -------------------*/
  1456. if (((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_DFSDM2) == RCC_PERIPHCLK_DFSDM2)
  1457. {
  1458. /* Check the parameters */
  1459. assert_param(IS_RCC_DFSDM2CLKSOURCE(PeriphClkInit->Dfsdm2ClockSelection));
  1460. /* Configure the DFSDM1 interface clock source */
  1461. __HAL_RCC_DFSDM2_CONFIG(PeriphClkInit->Dfsdm2ClockSelection);
  1462. }
  1463. /*--------------------------------------------------------------------------*/
  1464. /*-------------------- DFSDM2 Audio clock source configuration -------------*/
  1465. if (((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_DFSDM2_AUDIO) == RCC_PERIPHCLK_DFSDM2_AUDIO)
  1466. {
  1467. /* Check the parameters */
  1468. assert_param(IS_RCC_DFSDM2AUDIOCLKSOURCE(PeriphClkInit->Dfsdm2AudioClockSelection));
  1469. /* Configure the DFSDM1 Audio interface clock source */
  1470. __HAL_RCC_DFSDM2AUDIO_CONFIG(PeriphClkInit->Dfsdm2AudioClockSelection);
  1471. }
  1472. /*--------------------------------------------------------------------------*/
  1473. /*---------------------------- LPTIM1 Configuration ------------------------*/
  1474. if (((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_LPTIM1) == RCC_PERIPHCLK_LPTIM1)
  1475. {
  1476. /* Check the parameters */
  1477. assert_param(IS_RCC_LPTIM1CLKSOURCE(PeriphClkInit->Lptim1ClockSelection));
  1478. /* Configure the LPTIM1 clock source */
  1479. __HAL_RCC_LPTIM1_CONFIG(PeriphClkInit->Lptim1ClockSelection);
  1480. }
  1481. /*--------------------------------------------------------------------------*/
  1482. #endif /* STM32F413xx || STM32F423xx */
  1483. return HAL_OK;
  1484. }
  1485. /**
  1486. * @brief Get the RCC_PeriphCLKInitTypeDef according to the internal
  1487. * RCC configuration registers.
  1488. * @param PeriphClkInit pointer to an RCC_PeriphCLKInitTypeDef structure that
  1489. * will be configured.
  1490. * @retval None
  1491. */
  1492. void HAL_RCCEx_GetPeriphCLKConfig(RCC_PeriphCLKInitTypeDef *PeriphClkInit)
  1493. {
  1494. uint32_t tempreg;
  1495. /* Set all possible values for the extended clock type parameter------------*/
  1496. #if defined(STM32F413xx) || defined(STM32F423xx)
  1497. PeriphClkInit->PeriphClockSelection = RCC_PERIPHCLK_I2S_APB1 | RCC_PERIPHCLK_I2S_APB2 | \
  1498. RCC_PERIPHCLK_TIM | RCC_PERIPHCLK_RTC | \
  1499. RCC_PERIPHCLK_FMPI2C1 | RCC_PERIPHCLK_CLK48 | \
  1500. RCC_PERIPHCLK_SDIO | RCC_PERIPHCLK_DFSDM1 | \
  1501. RCC_PERIPHCLK_DFSDM1_AUDIO | RCC_PERIPHCLK_DFSDM2 | \
  1502. RCC_PERIPHCLK_DFSDM2_AUDIO | RCC_PERIPHCLK_LPTIM1 | \
  1503. RCC_PERIPHCLK_SAIA | RCC_PERIPHCLK_SAIB;
  1504. #else /* STM32F412Zx || STM32F412Vx || STM32F412Rx || STM32F412Cx */
  1505. PeriphClkInit->PeriphClockSelection = RCC_PERIPHCLK_I2S_APB1 | RCC_PERIPHCLK_I2S_APB2 | \
  1506. RCC_PERIPHCLK_TIM | RCC_PERIPHCLK_RTC | \
  1507. RCC_PERIPHCLK_FMPI2C1 | RCC_PERIPHCLK_CLK48 | \
  1508. RCC_PERIPHCLK_SDIO | RCC_PERIPHCLK_DFSDM1 | \
  1509. RCC_PERIPHCLK_DFSDM1_AUDIO;
  1510. #endif /* STM32F413xx || STM32F423xx */
  1511. /* Get the PLLI2S Clock configuration --------------------------------------*/
  1512. PeriphClkInit->PLLI2S.PLLI2SM = (uint32_t)((RCC->PLLI2SCFGR & RCC_PLLI2SCFGR_PLLI2SM) >> RCC_PLLI2SCFGR_PLLI2SM_Pos);
  1513. PeriphClkInit->PLLI2S.PLLI2SN = (uint32_t)((RCC->PLLI2SCFGR & RCC_PLLI2SCFGR_PLLI2SN) >> RCC_PLLI2SCFGR_PLLI2SN_Pos);
  1514. PeriphClkInit->PLLI2S.PLLI2SQ = (uint32_t)((RCC->PLLI2SCFGR & RCC_PLLI2SCFGR_PLLI2SQ) >> RCC_PLLI2SCFGR_PLLI2SQ_Pos);
  1515. PeriphClkInit->PLLI2S.PLLI2SR = (uint32_t)((RCC->PLLI2SCFGR & RCC_PLLI2SCFGR_PLLI2SR) >> RCC_PLLI2SCFGR_PLLI2SR_Pos);
  1516. #if defined(STM32F413xx) || defined(STM32F423xx)
  1517. /* Get the PLL/PLLI2S division factors -------------------------------------*/
  1518. PeriphClkInit->PLLI2SDivR = (uint32_t)((RCC->DCKCFGR & RCC_DCKCFGR_PLLI2SDIVR) >> RCC_DCKCFGR_PLLI2SDIVR_Pos);
  1519. PeriphClkInit->PLLDivR = (uint32_t)((RCC->DCKCFGR & RCC_DCKCFGR_PLLDIVR) >> RCC_DCKCFGR_PLLDIVR_Pos);
  1520. #endif /* STM32F413xx || STM32F423xx */
  1521. /* Get the I2S APB1 clock configuration ------------------------------------*/
  1522. PeriphClkInit->I2sApb1ClockSelection = __HAL_RCC_GET_I2S_APB1_SOURCE();
  1523. /* Get the I2S APB2 clock configuration ------------------------------------*/
  1524. PeriphClkInit->I2sApb2ClockSelection = __HAL_RCC_GET_I2S_APB2_SOURCE();
  1525. /* Get the RTC Clock configuration -----------------------------------------*/
  1526. tempreg = (RCC->CFGR & RCC_CFGR_RTCPRE);
  1527. PeriphClkInit->RTCClockSelection = (uint32_t)((tempreg) | (RCC->BDCR & RCC_BDCR_RTCSEL));
  1528. /* Get the FMPI2C1 clock configuration -------------------------------------*/
  1529. PeriphClkInit->Fmpi2c1ClockSelection = __HAL_RCC_GET_FMPI2C1_SOURCE();
  1530. /* Get the CLK48 clock configuration ---------------------------------------*/
  1531. PeriphClkInit->Clk48ClockSelection = __HAL_RCC_GET_CLK48_SOURCE();
  1532. /* Get the SDIO clock configuration ----------------------------------------*/
  1533. PeriphClkInit->SdioClockSelection = __HAL_RCC_GET_SDIO_SOURCE();
  1534. /* Get the DFSDM1 clock configuration --------------------------------------*/
  1535. PeriphClkInit->Dfsdm1ClockSelection = __HAL_RCC_GET_DFSDM1_SOURCE();
  1536. /* Get the DFSDM1 Audio clock configuration --------------------------------*/
  1537. PeriphClkInit->Dfsdm1AudioClockSelection = __HAL_RCC_GET_DFSDM1AUDIO_SOURCE();
  1538. #if defined(STM32F413xx) || defined(STM32F423xx)
  1539. /* Get the DFSDM2 clock configuration --------------------------------------*/
  1540. PeriphClkInit->Dfsdm2ClockSelection = __HAL_RCC_GET_DFSDM2_SOURCE();
  1541. /* Get the DFSDM2 Audio clock configuration --------------------------------*/
  1542. PeriphClkInit->Dfsdm2AudioClockSelection = __HAL_RCC_GET_DFSDM2AUDIO_SOURCE();
  1543. /* Get the LPTIM1 clock configuration --------------------------------------*/
  1544. PeriphClkInit->Lptim1ClockSelection = __HAL_RCC_GET_LPTIM1_SOURCE();
  1545. /* Get the SAI1 Block Aclock configuration ---------------------------------*/
  1546. PeriphClkInit->SaiAClockSelection = __HAL_RCC_GET_SAI_BLOCKA_SOURCE();
  1547. /* Get the SAI1 Block B clock configuration --------------------------------*/
  1548. PeriphClkInit->SaiBClockSelection = __HAL_RCC_GET_SAI_BLOCKB_SOURCE();
  1549. #endif /* STM32F413xx || STM32F423xx */
  1550. /* Get the TIM Prescaler configuration -------------------------------------*/
  1551. if ((RCC->DCKCFGR & RCC_DCKCFGR_TIMPRE) == RESET)
  1552. {
  1553. PeriphClkInit->TIMPresSelection = RCC_TIMPRES_DESACTIVATED;
  1554. }
  1555. else
  1556. {
  1557. PeriphClkInit->TIMPresSelection = RCC_TIMPRES_ACTIVATED;
  1558. }
  1559. }
  1560. /**
  1561. * @brief Return the peripheral clock frequency for a given peripheral(I2S..)
  1562. * @note Return 0 if peripheral clock identifier not managed by this API
  1563. * @param PeriphClk Peripheral clock identifier
  1564. * This parameter can be one of the following values:
  1565. * @arg RCC_PERIPHCLK_I2S_APB1: I2S APB1 peripheral clock
  1566. * @arg RCC_PERIPHCLK_I2S_APB2: I2S APB2 peripheral clock
  1567. * @retval Frequency in KHz
  1568. */
  1569. uint32_t HAL_RCCEx_GetPeriphCLKFreq(uint32_t PeriphClk)
  1570. {
  1571. /* This variable used to store the I2S clock frequency (value in Hz) */
  1572. uint32_t frequency = 0U;
  1573. /* This variable used to store the VCO Input (value in Hz) */
  1574. uint32_t vcoinput = 0U;
  1575. uint32_t srcclk = 0U;
  1576. /* This variable used to store the VCO Output (value in Hz) */
  1577. uint32_t vcooutput = 0U;
  1578. switch (PeriphClk)
  1579. {
  1580. case RCC_PERIPHCLK_I2S_APB1:
  1581. {
  1582. /* Get the current I2S source */
  1583. srcclk = __HAL_RCC_GET_I2S_APB1_SOURCE();
  1584. switch (srcclk)
  1585. {
  1586. /* Check if I2S clock selection is External clock mapped on the I2S_CKIN pin used as I2S clock */
  1587. case RCC_I2SAPB1CLKSOURCE_EXT:
  1588. {
  1589. /* Set the I2S clock to the external clock value */
  1590. frequency = EXTERNAL_CLOCK_VALUE;
  1591. break;
  1592. }
  1593. /* Check if I2S clock selection is PLLI2S VCO output clock divided by PLLI2SR used as I2S clock */
  1594. case RCC_I2SAPB1CLKSOURCE_PLLI2S:
  1595. {
  1596. if ((RCC->PLLI2SCFGR & RCC_PLLI2SCFGR_PLLI2SSRC) == RCC_PLLI2SCFGR_PLLI2SSRC)
  1597. {
  1598. /* Get the I2S source clock value */
  1599. vcoinput = (uint32_t)(EXTERNAL_CLOCK_VALUE / (uint32_t)(RCC->PLLI2SCFGR & RCC_PLLI2SCFGR_PLLI2SM));
  1600. }
  1601. else
  1602. {
  1603. /* Configure the PLLI2S division factor */
  1604. /* PLLI2S_VCO Input = PLL_SOURCE/PLLI2SM */
  1605. if ((RCC->PLLCFGR & RCC_PLLCFGR_PLLSRC) == RCC_PLLSOURCE_HSE)
  1606. {
  1607. /* Get the I2S source clock value */
  1608. vcoinput = (uint32_t)(HSE_VALUE / (uint32_t)(RCC->PLLI2SCFGR & RCC_PLLI2SCFGR_PLLI2SM));
  1609. }
  1610. else
  1611. {
  1612. /* Get the I2S source clock value */
  1613. vcoinput = (uint32_t)(HSI_VALUE / (uint32_t)(RCC->PLLI2SCFGR & RCC_PLLI2SCFGR_PLLI2SM));
  1614. }
  1615. }
  1616. /* PLLI2S_VCO Output = PLLI2S_VCO Input * PLLI2SN */
  1617. vcooutput = (uint32_t)(vcoinput * (((RCC->PLLI2SCFGR & RCC_PLLI2SCFGR_PLLI2SN) >> 6U) & (RCC_PLLI2SCFGR_PLLI2SN >> 6U)));
  1618. /* I2S_CLK = PLLI2S_VCO Output/PLLI2SR */
  1619. frequency = (uint32_t)(vcooutput / (((RCC->PLLI2SCFGR & RCC_PLLI2SCFGR_PLLI2SR) >> 28U) & (RCC_PLLI2SCFGR_PLLI2SR >> 28U)));
  1620. break;
  1621. }
  1622. /* Check if I2S clock selection is PLL VCO Output divided by PLLR used as I2S clock */
  1623. case RCC_I2SAPB1CLKSOURCE_PLLR:
  1624. {
  1625. /* Configure the PLL division factor R */
  1626. /* PLL_VCO Input = PLL_SOURCE/PLLM */
  1627. if ((RCC->PLLCFGR & RCC_PLLCFGR_PLLSRC) == RCC_PLLSOURCE_HSE)
  1628. {
  1629. /* Get the I2S source clock value */
  1630. vcoinput = (uint32_t)(HSE_VALUE / (uint32_t)(RCC->PLLCFGR & RCC_PLLCFGR_PLLM));
  1631. }
  1632. else
  1633. {
  1634. /* Get the I2S source clock value */
  1635. vcoinput = (uint32_t)(HSI_VALUE / (uint32_t)(RCC->PLLCFGR & RCC_PLLCFGR_PLLM));
  1636. }
  1637. /* PLL_VCO Output = PLL_VCO Input * PLLN */
  1638. vcooutput = (uint32_t)(vcoinput * (((RCC->PLLCFGR & RCC_PLLCFGR_PLLN) >> 6U) & (RCC_PLLCFGR_PLLN >> 6U)));
  1639. /* I2S_CLK = PLL_VCO Output/PLLR */
  1640. frequency = (uint32_t)(vcooutput / (((RCC->PLLCFGR & RCC_PLLCFGR_PLLR) >> 28U) & (RCC_PLLCFGR_PLLR >> 28U)));
  1641. break;
  1642. }
  1643. /* Check if I2S clock selection is HSI or HSE depending from PLL source Clock */
  1644. case RCC_I2SAPB1CLKSOURCE_PLLSRC:
  1645. {
  1646. if ((RCC->PLLCFGR & RCC_PLLCFGR_PLLSRC) == RCC_PLLSOURCE_HSE)
  1647. {
  1648. frequency = HSE_VALUE;
  1649. }
  1650. else
  1651. {
  1652. frequency = HSI_VALUE;
  1653. }
  1654. break;
  1655. }
  1656. /* Clock not enabled for I2S*/
  1657. default:
  1658. {
  1659. frequency = 0U;
  1660. break;
  1661. }
  1662. }
  1663. break;
  1664. }
  1665. case RCC_PERIPHCLK_I2S_APB2:
  1666. {
  1667. /* Get the current I2S source */
  1668. srcclk = __HAL_RCC_GET_I2S_APB2_SOURCE();
  1669. switch (srcclk)
  1670. {
  1671. /* Check if I2S clock selection is External clock mapped on the I2S_CKIN pin used as I2S clock */
  1672. case RCC_I2SAPB2CLKSOURCE_EXT:
  1673. {
  1674. /* Set the I2S clock to the external clock value */
  1675. frequency = EXTERNAL_CLOCK_VALUE;
  1676. break;
  1677. }
  1678. /* Check if I2S clock selection is PLLI2S VCO output clock divided by PLLI2SR used as I2S clock */
  1679. case RCC_I2SAPB2CLKSOURCE_PLLI2S:
  1680. {
  1681. if ((RCC->PLLI2SCFGR & RCC_PLLI2SCFGR_PLLI2SSRC) == RCC_PLLI2SCFGR_PLLI2SSRC)
  1682. {
  1683. /* Get the I2S source clock value */
  1684. vcoinput = (uint32_t)(EXTERNAL_CLOCK_VALUE / (uint32_t)(RCC->PLLI2SCFGR & RCC_PLLI2SCFGR_PLLI2SM));
  1685. }
  1686. else
  1687. {
  1688. /* Configure the PLLI2S division factor */
  1689. /* PLLI2S_VCO Input = PLL_SOURCE/PLLI2SM */
  1690. if ((RCC->PLLCFGR & RCC_PLLCFGR_PLLSRC) == RCC_PLLSOURCE_HSE)
  1691. {
  1692. /* Get the I2S source clock value */
  1693. vcoinput = (uint32_t)(HSE_VALUE / (uint32_t)(RCC->PLLI2SCFGR & RCC_PLLI2SCFGR_PLLI2SM));
  1694. }
  1695. else
  1696. {
  1697. /* Get the I2S source clock value */
  1698. vcoinput = (uint32_t)(HSI_VALUE / (uint32_t)(RCC->PLLI2SCFGR & RCC_PLLI2SCFGR_PLLI2SM));
  1699. }
  1700. }
  1701. /* PLLI2S_VCO Output = PLLI2S_VCO Input * PLLI2SN */
  1702. vcooutput = (uint32_t)(vcoinput * (((RCC->PLLI2SCFGR & RCC_PLLI2SCFGR_PLLI2SN) >> 6U) & (RCC_PLLI2SCFGR_PLLI2SN >> 6U)));
  1703. /* I2S_CLK = PLLI2S_VCO Output/PLLI2SR */
  1704. frequency = (uint32_t)(vcooutput / (((RCC->PLLI2SCFGR & RCC_PLLI2SCFGR_PLLI2SR) >> 28U) & (RCC_PLLI2SCFGR_PLLI2SR >> 28U)));
  1705. break;
  1706. }
  1707. /* Check if I2S clock selection is PLL VCO Output divided by PLLR used as I2S clock */
  1708. case RCC_I2SAPB2CLKSOURCE_PLLR:
  1709. {
  1710. /* Configure the PLL division factor R */
  1711. /* PLL_VCO Input = PLL_SOURCE/PLLM */
  1712. if ((RCC->PLLCFGR & RCC_PLLCFGR_PLLSRC) == RCC_PLLSOURCE_HSE)
  1713. {
  1714. /* Get the I2S source clock value */
  1715. vcoinput = (uint32_t)(HSE_VALUE / (uint32_t)(RCC->PLLCFGR & RCC_PLLCFGR_PLLM));
  1716. }
  1717. else
  1718. {
  1719. /* Get the I2S source clock value */
  1720. vcoinput = (uint32_t)(HSI_VALUE / (uint32_t)(RCC->PLLCFGR & RCC_PLLCFGR_PLLM));
  1721. }
  1722. /* PLL_VCO Output = PLL_VCO Input * PLLN */
  1723. vcooutput = (uint32_t)(vcoinput * (((RCC->PLLCFGR & RCC_PLLCFGR_PLLN) >> 6U) & (RCC_PLLCFGR_PLLN >> 6U)));
  1724. /* I2S_CLK = PLL_VCO Output/PLLR */
  1725. frequency = (uint32_t)(vcooutput / (((RCC->PLLCFGR & RCC_PLLCFGR_PLLR) >> 28U) & (RCC_PLLCFGR_PLLR >> 28U)));
  1726. break;
  1727. }
  1728. /* Check if I2S clock selection is HSI or HSE depending from PLL source Clock */
  1729. case RCC_I2SAPB2CLKSOURCE_PLLSRC:
  1730. {
  1731. if ((RCC->PLLCFGR & RCC_PLLCFGR_PLLSRC) == RCC_PLLSOURCE_HSE)
  1732. {
  1733. frequency = HSE_VALUE;
  1734. }
  1735. else
  1736. {
  1737. frequency = HSI_VALUE;
  1738. }
  1739. break;
  1740. }
  1741. /* Clock not enabled for I2S*/
  1742. default:
  1743. {
  1744. frequency = 0U;
  1745. break;
  1746. }
  1747. }
  1748. break;
  1749. }
  1750. default:
  1751. {
  1752. break;
  1753. }
  1754. }
  1755. return frequency;
  1756. }
  1757. #endif /* STM32F412Zx || STM32F412Vx || STM32F412Rx || STM32F412Cx || STM32F413xx || STM32F423xx */
  1758. #if defined(STM32F410Tx) || defined(STM32F410Cx) || defined(STM32F410Rx)
  1759. /**
  1760. * @brief Initializes the RCC extended peripherals clocks according to the specified parameters in the
  1761. * RCC_PeriphCLKInitTypeDef.
  1762. * @param PeriphClkInit pointer to an RCC_PeriphCLKInitTypeDef structure that
  1763. * contains the configuration information for the Extended Peripherals clocks(I2S and RTC clocks).
  1764. *
  1765. * @note A caution to be taken when HAL_RCCEx_PeriphCLKConfig() is used to select RTC clock selection, in this case
  1766. * the Reset of Backup domain will be applied in order to modify the RTC Clock source as consequence all backup
  1767. * domain (RTC and RCC_BDCR register expect BKPSRAM) will be reset
  1768. *
  1769. * @retval HAL status
  1770. */
  1771. HAL_StatusTypeDef HAL_RCCEx_PeriphCLKConfig(RCC_PeriphCLKInitTypeDef *PeriphClkInit)
  1772. {
  1773. uint32_t tickstart = 0U;
  1774. uint32_t tmpreg1 = 0U;
  1775. /* Check the parameters */
  1776. assert_param(IS_RCC_PERIPHCLOCK(PeriphClkInit->PeriphClockSelection));
  1777. /*---------------------------- RTC configuration ---------------------------*/
  1778. if (((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_RTC) == (RCC_PERIPHCLK_RTC))
  1779. {
  1780. /* Check for RTC Parameters used to output RTCCLK */
  1781. assert_param(IS_RCC_RTCCLKSOURCE(PeriphClkInit->RTCClockSelection));
  1782. /* Enable Power Clock*/
  1783. __HAL_RCC_PWR_CLK_ENABLE();
  1784. /* Enable write access to Backup domain */
  1785. PWR->CR |= PWR_CR_DBP;
  1786. /* Get tick */
  1787. tickstart = HAL_GetTick();
  1788. while ((PWR->CR & PWR_CR_DBP) == RESET)
  1789. {
  1790. if ((HAL_GetTick() - tickstart) > RCC_DBP_TIMEOUT_VALUE)
  1791. {
  1792. return HAL_TIMEOUT;
  1793. }
  1794. }
  1795. /* Reset the Backup domain only if the RTC Clock source selection is modified from reset value */
  1796. tmpreg1 = (RCC->BDCR & RCC_BDCR_RTCSEL);
  1797. if ((tmpreg1 != 0x00000000U) && ((tmpreg1) != (PeriphClkInit->RTCClockSelection & RCC_BDCR_RTCSEL)))
  1798. {
  1799. /* Store the content of BDCR register before the reset of Backup Domain */
  1800. tmpreg1 = (RCC->BDCR & ~(RCC_BDCR_RTCSEL));
  1801. /* RTC Clock selection can be changed only if the Backup Domain is reset */
  1802. __HAL_RCC_BACKUPRESET_FORCE();
  1803. __HAL_RCC_BACKUPRESET_RELEASE();
  1804. /* Restore the Content of BDCR register */
  1805. RCC->BDCR = tmpreg1;
  1806. /* Wait for LSE reactivation if LSE was enable prior to Backup Domain reset */
  1807. if (HAL_IS_BIT_SET(RCC->BDCR, RCC_BDCR_LSEON))
  1808. {
  1809. /* Get tick */
  1810. tickstart = HAL_GetTick();
  1811. /* Wait till LSE is ready */
  1812. while (__HAL_RCC_GET_FLAG(RCC_FLAG_LSERDY) == RESET)
  1813. {
  1814. if ((HAL_GetTick() - tickstart) > RCC_LSE_TIMEOUT_VALUE)
  1815. {
  1816. return HAL_TIMEOUT;
  1817. }
  1818. }
  1819. }
  1820. }
  1821. __HAL_RCC_RTC_CONFIG(PeriphClkInit->RTCClockSelection);
  1822. }
  1823. /*--------------------------------------------------------------------------*/
  1824. /*---------------------------- TIM configuration ---------------------------*/
  1825. if (((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_TIM) == (RCC_PERIPHCLK_TIM))
  1826. {
  1827. __HAL_RCC_TIMCLKPRESCALER(PeriphClkInit->TIMPresSelection);
  1828. }
  1829. /*--------------------------------------------------------------------------*/
  1830. /*---------------------------- FMPI2C1 Configuration -----------------------*/
  1831. if (((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_FMPI2C1) == RCC_PERIPHCLK_FMPI2C1)
  1832. {
  1833. /* Check the parameters */
  1834. assert_param(IS_RCC_FMPI2C1CLKSOURCE(PeriphClkInit->Fmpi2c1ClockSelection));
  1835. /* Configure the FMPI2C1 clock source */
  1836. __HAL_RCC_FMPI2C1_CONFIG(PeriphClkInit->Fmpi2c1ClockSelection);
  1837. }
  1838. /*--------------------------------------------------------------------------*/
  1839. /*---------------------------- LPTIM1 Configuration ------------------------*/
  1840. if (((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_LPTIM1) == RCC_PERIPHCLK_LPTIM1)
  1841. {
  1842. /* Check the parameters */
  1843. assert_param(IS_RCC_LPTIM1CLKSOURCE(PeriphClkInit->Lptim1ClockSelection));
  1844. /* Configure the LPTIM1 clock source */
  1845. __HAL_RCC_LPTIM1_CONFIG(PeriphClkInit->Lptim1ClockSelection);
  1846. }
  1847. /*---------------------------- I2S Configuration ---------------------------*/
  1848. if (((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_I2S) == RCC_PERIPHCLK_I2S)
  1849. {
  1850. /* Check the parameters */
  1851. assert_param(IS_RCC_I2SAPBCLKSOURCE(PeriphClkInit->I2SClockSelection));
  1852. /* Configure the I2S clock source */
  1853. __HAL_RCC_I2S_CONFIG(PeriphClkInit->I2SClockSelection);
  1854. }
  1855. return HAL_OK;
  1856. }
  1857. /**
  1858. * @brief Configures the RCC_OscInitStruct according to the internal
  1859. * RCC configuration registers.
  1860. * @param PeriphClkInit pointer to an RCC_PeriphCLKInitTypeDef structure that
  1861. * will be configured.
  1862. * @retval None
  1863. */
  1864. void HAL_RCCEx_GetPeriphCLKConfig(RCC_PeriphCLKInitTypeDef *PeriphClkInit)
  1865. {
  1866. uint32_t tempreg;
  1867. /* Set all possible values for the extended clock type parameter------------*/
  1868. PeriphClkInit->PeriphClockSelection = RCC_PERIPHCLK_FMPI2C1 | RCC_PERIPHCLK_LPTIM1 | RCC_PERIPHCLK_TIM | RCC_PERIPHCLK_RTC;
  1869. tempreg = (RCC->CFGR & RCC_CFGR_RTCPRE);
  1870. PeriphClkInit->RTCClockSelection = (uint32_t)((tempreg) | (RCC->BDCR & RCC_BDCR_RTCSEL));
  1871. if ((RCC->DCKCFGR & RCC_DCKCFGR_TIMPRE) == RESET)
  1872. {
  1873. PeriphClkInit->TIMPresSelection = RCC_TIMPRES_DESACTIVATED;
  1874. }
  1875. else
  1876. {
  1877. PeriphClkInit->TIMPresSelection = RCC_TIMPRES_ACTIVATED;
  1878. }
  1879. /* Get the FMPI2C1 clock configuration -------------------------------------*/
  1880. PeriphClkInit->Fmpi2c1ClockSelection = __HAL_RCC_GET_FMPI2C1_SOURCE();
  1881. /* Get the I2S clock configuration -----------------------------------------*/
  1882. PeriphClkInit->I2SClockSelection = __HAL_RCC_GET_I2S_SOURCE();
  1883. }
  1884. /**
  1885. * @brief Return the peripheral clock frequency for a given peripheral(SAI..)
  1886. * @note Return 0 if peripheral clock identifier not managed by this API
  1887. * @param PeriphClk Peripheral clock identifier
  1888. * This parameter can be one of the following values:
  1889. * @arg RCC_PERIPHCLK_I2S: I2S peripheral clock
  1890. * @retval Frequency in KHz
  1891. */
  1892. uint32_t HAL_RCCEx_GetPeriphCLKFreq(uint32_t PeriphClk)
  1893. {
  1894. /* This variable used to store the I2S clock frequency (value in Hz) */
  1895. uint32_t frequency = 0U;
  1896. /* This variable used to store the VCO Input (value in Hz) */
  1897. uint32_t vcoinput = 0U;
  1898. uint32_t srcclk = 0U;
  1899. /* This variable used to store the VCO Output (value in Hz) */
  1900. uint32_t vcooutput = 0U;
  1901. switch (PeriphClk)
  1902. {
  1903. case RCC_PERIPHCLK_I2S:
  1904. {
  1905. /* Get the current I2S source */
  1906. srcclk = __HAL_RCC_GET_I2S_SOURCE();
  1907. switch (srcclk)
  1908. {
  1909. /* Check if I2S clock selection is External clock mapped on the I2S_CKIN pin used as I2S clock */
  1910. case RCC_I2SAPBCLKSOURCE_EXT:
  1911. {
  1912. /* Set the I2S clock to the external clock value */
  1913. frequency = EXTERNAL_CLOCK_VALUE;
  1914. break;
  1915. }
  1916. /* Check if I2S clock selection is PLL VCO Output divided by PLLR used as I2S clock */
  1917. case RCC_I2SAPBCLKSOURCE_PLLR:
  1918. {
  1919. /* Configure the PLL division factor R */
  1920. /* PLL_VCO Input = PLL_SOURCE/PLLM */
  1921. if ((RCC->PLLCFGR & RCC_PLLCFGR_PLLSRC) == RCC_PLLSOURCE_HSE)
  1922. {
  1923. /* Get the I2S source clock value */
  1924. vcoinput = (uint32_t)(HSE_VALUE / (uint32_t)(RCC->PLLCFGR & RCC_PLLCFGR_PLLM));
  1925. }
  1926. else
  1927. {
  1928. /* Get the I2S source clock value */
  1929. vcoinput = (uint32_t)(HSI_VALUE / (uint32_t)(RCC->PLLCFGR & RCC_PLLCFGR_PLLM));
  1930. }
  1931. /* PLL_VCO Output = PLL_VCO Input * PLLN */
  1932. vcooutput = (uint32_t)(vcoinput * (((RCC->PLLCFGR & RCC_PLLCFGR_PLLN) >> 6U) & (RCC_PLLCFGR_PLLN >> 6U)));
  1933. /* I2S_CLK = PLL_VCO Output/PLLR */
  1934. frequency = (uint32_t)(vcooutput / (((RCC->PLLCFGR & RCC_PLLCFGR_PLLR) >> 28U) & (RCC_PLLCFGR_PLLR >> 28U)));
  1935. break;
  1936. }
  1937. /* Check if I2S clock selection is HSI or HSE depending from PLL source Clock */
  1938. case RCC_I2SAPBCLKSOURCE_PLLSRC:
  1939. {
  1940. if ((RCC->PLLCFGR & RCC_PLLCFGR_PLLSRC) == RCC_PLLSOURCE_HSE)
  1941. {
  1942. frequency = HSE_VALUE;
  1943. }
  1944. else
  1945. {
  1946. frequency = HSI_VALUE;
  1947. }
  1948. break;
  1949. }
  1950. /* Clock not enabled for I2S*/
  1951. default:
  1952. {
  1953. frequency = 0U;
  1954. break;
  1955. }
  1956. }
  1957. break;
  1958. }
  1959. default:
  1960. {
  1961. break;
  1962. }
  1963. }
  1964. return frequency;
  1965. }
  1966. #endif /* STM32F410Tx || STM32F410Cx || STM32F410Rx */
  1967. #if defined(STM32F427xx) || defined(STM32F437xx) || defined(STM32F429xx) || defined(STM32F439xx)
  1968. /**
  1969. * @brief Initializes the RCC extended peripherals clocks according to the specified
  1970. * parameters in the RCC_PeriphCLKInitTypeDef.
  1971. * @param PeriphClkInit pointer to an RCC_PeriphCLKInitTypeDef structure that
  1972. * contains the configuration information for the Extended Peripherals
  1973. * clocks(I2S, SAI, LTDC RTC and TIM).
  1974. *
  1975. * @note Care must be taken when HAL_RCCEx_PeriphCLKConfig() is used to select
  1976. * the RTC clock source; in this case the Backup domain will be reset in
  1977. * order to modify the RTC Clock source, as consequence RTC registers (including
  1978. * the backup registers) and RCC_BDCR register are set to their reset values.
  1979. *
  1980. * @retval HAL status
  1981. */
  1982. HAL_StatusTypeDef HAL_RCCEx_PeriphCLKConfig(RCC_PeriphCLKInitTypeDef *PeriphClkInit)
  1983. {
  1984. uint32_t tickstart = 0U;
  1985. uint32_t tmpreg1 = 0U;
  1986. /* Check the parameters */
  1987. assert_param(IS_RCC_PERIPHCLOCK(PeriphClkInit->PeriphClockSelection));
  1988. /*----------------------- SAI/I2S Configuration (PLLI2S) -------------------*/
  1989. /*----------------------- Common configuration SAI/I2S ---------------------*/
  1990. /* In Case of SAI or I2S Clock Configuration through PLLI2S, PLLI2SN division
  1991. factor is common parameters for both peripherals */
  1992. if ((((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_I2S) == RCC_PERIPHCLK_I2S) ||
  1993. (((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_SAI_PLLI2S) == RCC_PERIPHCLK_SAI_PLLI2S) ||
  1994. (((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_PLLI2S) == RCC_PERIPHCLK_PLLI2S))
  1995. {
  1996. /* check for Parameters */
  1997. assert_param(IS_RCC_PLLI2SN_VALUE(PeriphClkInit->PLLI2S.PLLI2SN));
  1998. /* Disable the PLLI2S */
  1999. __HAL_RCC_PLLI2S_DISABLE();
  2000. /* Get tick */
  2001. tickstart = HAL_GetTick();
  2002. /* Wait till PLLI2S is disabled */
  2003. while (__HAL_RCC_GET_FLAG(RCC_FLAG_PLLI2SRDY) != RESET)
  2004. {
  2005. if ((HAL_GetTick() - tickstart) > PLLI2S_TIMEOUT_VALUE)
  2006. {
  2007. /* return in case of Timeout detected */
  2008. return HAL_TIMEOUT;
  2009. }
  2010. }
  2011. /*---------------------------- I2S configuration -------------------------*/
  2012. /* In Case of I2S Clock Configuration through PLLI2S, PLLI2SR must be added
  2013. only for I2S configuration */
  2014. if (((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_I2S) == (RCC_PERIPHCLK_I2S))
  2015. {
  2016. /* check for Parameters */
  2017. assert_param(IS_RCC_PLLI2SR_VALUE(PeriphClkInit->PLLI2S.PLLI2SR));
  2018. /* Configure the PLLI2S division factors */
  2019. /* PLLI2S_VCO = f(VCO clock) = f(PLLI2S clock input) * (PLLI2SN/PLLM) */
  2020. /* I2SCLK = f(PLLI2S clock output) = f(VCO clock) / PLLI2SR */
  2021. __HAL_RCC_PLLI2S_CONFIG(PeriphClkInit->PLLI2S.PLLI2SN, PeriphClkInit->PLLI2S.PLLI2SR);
  2022. }
  2023. /*---------------------------- SAI configuration -------------------------*/
  2024. /* In Case of SAI Clock Configuration through PLLI2S, PLLI2SQ and PLLI2S_DIVQ must
  2025. be added only for SAI configuration */
  2026. if (((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_SAI_PLLI2S) == (RCC_PERIPHCLK_SAI_PLLI2S))
  2027. {
  2028. /* Check the PLLI2S division factors */
  2029. assert_param(IS_RCC_PLLI2SQ_VALUE(PeriphClkInit->PLLI2S.PLLI2SQ));
  2030. assert_param(IS_RCC_PLLI2S_DIVQ_VALUE(PeriphClkInit->PLLI2SDivQ));
  2031. /* Read PLLI2SR value from PLLI2SCFGR register (this value is not need for SAI configuration) */
  2032. tmpreg1 = ((RCC->PLLI2SCFGR & RCC_PLLI2SCFGR_PLLI2SR) >> RCC_PLLI2SCFGR_PLLI2SR_Pos);
  2033. /* Configure the PLLI2S division factors */
  2034. /* PLLI2S_VCO Input = PLL_SOURCE/PLLM */
  2035. /* PLLI2S_VCO Output = PLLI2S_VCO Input * PLLI2SN */
  2036. /* SAI_CLK(first level) = PLLI2S_VCO Output/PLLI2SQ */
  2037. __HAL_RCC_PLLI2S_SAICLK_CONFIG(PeriphClkInit->PLLI2S.PLLI2SN, PeriphClkInit->PLLI2S.PLLI2SQ, tmpreg1);
  2038. /* SAI_CLK_x = SAI_CLK(first level)/PLLI2SDIVQ */
  2039. __HAL_RCC_PLLI2S_PLLSAICLKDIVQ_CONFIG(PeriphClkInit->PLLI2SDivQ);
  2040. }
  2041. /*----------------- In Case of PLLI2S is just selected -----------------*/
  2042. if ((PeriphClkInit->PeriphClockSelection & RCC_PERIPHCLK_PLLI2S) == RCC_PERIPHCLK_PLLI2S)
  2043. {
  2044. /* Check for Parameters */
  2045. assert_param(IS_RCC_PLLI2SQ_VALUE(PeriphClkInit->PLLI2S.PLLI2SQ));
  2046. assert_param(IS_RCC_PLLI2SR_VALUE(PeriphClkInit->PLLI2S.PLLI2SR));
  2047. /* Configure the PLLI2S multiplication and division factors */
  2048. __HAL_RCC_PLLI2S_SAICLK_CONFIG(PeriphClkInit->PLLI2S.PLLI2SN, PeriphClkInit->PLLI2S.PLLI2SQ,
  2049. PeriphClkInit->PLLI2S.PLLI2SR);
  2050. }
  2051. /* Enable the PLLI2S */
  2052. __HAL_RCC_PLLI2S_ENABLE();
  2053. /* Get tick */
  2054. tickstart = HAL_GetTick();
  2055. /* Wait till PLLI2S is ready */
  2056. while (__HAL_RCC_GET_FLAG(RCC_FLAG_PLLI2SRDY) == RESET)
  2057. {
  2058. if ((HAL_GetTick() - tickstart) > PLLI2S_TIMEOUT_VALUE)
  2059. {
  2060. /* return in case of Timeout detected */
  2061. return HAL_TIMEOUT;
  2062. }
  2063. }
  2064. }
  2065. /*--------------------------------------------------------------------------*/
  2066. /*----------------------- SAI/LTDC Configuration (PLLSAI) ------------------*/
  2067. /*----------------------- Common configuration SAI/LTDC --------------------*/
  2068. /* In Case of SAI or LTDC Clock Configuration through PLLSAI, PLLSAIN division
  2069. factor is common parameters for both peripherals */
  2070. if ((((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_SAI_PLLSAI) == RCC_PERIPHCLK_SAI_PLLSAI) ||
  2071. (((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_LTDC) == RCC_PERIPHCLK_LTDC))
  2072. {
  2073. /* Check the PLLSAI division factors */
  2074. assert_param(IS_RCC_PLLSAIN_VALUE(PeriphClkInit->PLLSAI.PLLSAIN));
  2075. /* Disable PLLSAI Clock */
  2076. __HAL_RCC_PLLSAI_DISABLE();
  2077. /* Get tick */
  2078. tickstart = HAL_GetTick();
  2079. /* Wait till PLLSAI is disabled */
  2080. while (__HAL_RCC_PLLSAI_GET_FLAG() != RESET)
  2081. {
  2082. if ((HAL_GetTick() - tickstart) > PLLSAI_TIMEOUT_VALUE)
  2083. {
  2084. /* return in case of Timeout detected */
  2085. return HAL_TIMEOUT;
  2086. }
  2087. }
  2088. /*---------------------------- SAI configuration -------------------------*/
  2089. /* In Case of SAI Clock Configuration through PLLSAI, PLLSAIQ and PLLSAI_DIVQ must
  2090. be added only for SAI configuration */
  2091. if (((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_SAI_PLLSAI) == (RCC_PERIPHCLK_SAI_PLLSAI))
  2092. {
  2093. assert_param(IS_RCC_PLLSAIQ_VALUE(PeriphClkInit->PLLSAI.PLLSAIQ));
  2094. assert_param(IS_RCC_PLLSAI_DIVQ_VALUE(PeriphClkInit->PLLSAIDivQ));
  2095. /* Read PLLSAIR value from PLLSAICFGR register (this value is not need for SAI configuration) */
  2096. tmpreg1 = ((RCC->PLLSAICFGR & RCC_PLLSAICFGR_PLLSAIR) >> RCC_PLLSAICFGR_PLLSAIR_Pos);
  2097. /* PLLSAI_VCO Input = PLL_SOURCE/PLLM */
  2098. /* PLLSAI_VCO Output = PLLSAI_VCO Input * PLLSAIN */
  2099. /* SAI_CLK(first level) = PLLSAI_VCO Output/PLLSAIQ */
  2100. __HAL_RCC_PLLSAI_CONFIG(PeriphClkInit->PLLSAI.PLLSAIN, PeriphClkInit->PLLSAI.PLLSAIQ, tmpreg1);
  2101. /* SAI_CLK_x = SAI_CLK(first level)/PLLSAIDIVQ */
  2102. __HAL_RCC_PLLSAI_PLLSAICLKDIVQ_CONFIG(PeriphClkInit->PLLSAIDivQ);
  2103. }
  2104. /*---------------------------- LTDC configuration ------------------------*/
  2105. if (((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_LTDC) == (RCC_PERIPHCLK_LTDC))
  2106. {
  2107. assert_param(IS_RCC_PLLSAIR_VALUE(PeriphClkInit->PLLSAI.PLLSAIR));
  2108. assert_param(IS_RCC_PLLSAI_DIVR_VALUE(PeriphClkInit->PLLSAIDivR));
  2109. /* Read PLLSAIR value from PLLSAICFGR register (this value is not need for SAI configuration) */
  2110. tmpreg1 = ((RCC->PLLSAICFGR & RCC_PLLSAICFGR_PLLSAIQ) >> RCC_PLLSAICFGR_PLLSAIQ_Pos);
  2111. /* PLLSAI_VCO Input = PLL_SOURCE/PLLM */
  2112. /* PLLSAI_VCO Output = PLLSAI_VCO Input * PLLSAIN */
  2113. /* LTDC_CLK(first level) = PLLSAI_VCO Output/PLLSAIR */
  2114. __HAL_RCC_PLLSAI_CONFIG(PeriphClkInit->PLLSAI.PLLSAIN, tmpreg1, PeriphClkInit->PLLSAI.PLLSAIR);
  2115. /* LTDC_CLK = LTDC_CLK(first level)/PLLSAIDIVR */
  2116. __HAL_RCC_PLLSAI_PLLSAICLKDIVR_CONFIG(PeriphClkInit->PLLSAIDivR);
  2117. }
  2118. /* Enable PLLSAI Clock */
  2119. __HAL_RCC_PLLSAI_ENABLE();
  2120. /* Get tick */
  2121. tickstart = HAL_GetTick();
  2122. /* Wait till PLLSAI is ready */
  2123. while (__HAL_RCC_PLLSAI_GET_FLAG() == RESET)
  2124. {
  2125. if ((HAL_GetTick() - tickstart) > PLLSAI_TIMEOUT_VALUE)
  2126. {
  2127. /* return in case of Timeout detected */
  2128. return HAL_TIMEOUT;
  2129. }
  2130. }
  2131. }
  2132. /*--------------------------------------------------------------------------*/
  2133. /*---------------------------- RTC configuration ---------------------------*/
  2134. if (((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_RTC) == (RCC_PERIPHCLK_RTC))
  2135. {
  2136. /* Check for RTC Parameters used to output RTCCLK */
  2137. assert_param(IS_RCC_RTCCLKSOURCE(PeriphClkInit->RTCClockSelection));
  2138. /* Enable Power Clock*/
  2139. __HAL_RCC_PWR_CLK_ENABLE();
  2140. /* Enable write access to Backup domain */
  2141. PWR->CR |= PWR_CR_DBP;
  2142. /* Get tick */
  2143. tickstart = HAL_GetTick();
  2144. while ((PWR->CR & PWR_CR_DBP) == RESET)
  2145. {
  2146. if ((HAL_GetTick() - tickstart) > RCC_DBP_TIMEOUT_VALUE)
  2147. {
  2148. return HAL_TIMEOUT;
  2149. }
  2150. }
  2151. /* Reset the Backup domain only if the RTC Clock source selection is modified from reset value */
  2152. tmpreg1 = (RCC->BDCR & RCC_BDCR_RTCSEL);
  2153. if ((tmpreg1 != 0x00000000U) && ((tmpreg1) != (PeriphClkInit->RTCClockSelection & RCC_BDCR_RTCSEL)))
  2154. {
  2155. /* Store the content of BDCR register before the reset of Backup Domain */
  2156. tmpreg1 = (RCC->BDCR & ~(RCC_BDCR_RTCSEL));
  2157. /* RTC Clock selection can be changed only if the Backup Domain is reset */
  2158. __HAL_RCC_BACKUPRESET_FORCE();
  2159. __HAL_RCC_BACKUPRESET_RELEASE();
  2160. /* Restore the Content of BDCR register */
  2161. RCC->BDCR = tmpreg1;
  2162. /* Wait for LSE reactivation if LSE was enable prior to Backup Domain reset */
  2163. if (HAL_IS_BIT_SET(RCC->BDCR, RCC_BDCR_LSEON))
  2164. {
  2165. /* Get tick */
  2166. tickstart = HAL_GetTick();
  2167. /* Wait till LSE is ready */
  2168. while (__HAL_RCC_GET_FLAG(RCC_FLAG_LSERDY) == RESET)
  2169. {
  2170. if ((HAL_GetTick() - tickstart) > RCC_LSE_TIMEOUT_VALUE)
  2171. {
  2172. return HAL_TIMEOUT;
  2173. }
  2174. }
  2175. }
  2176. }
  2177. __HAL_RCC_RTC_CONFIG(PeriphClkInit->RTCClockSelection);
  2178. }
  2179. /*--------------------------------------------------------------------------*/
  2180. /*---------------------------- TIM configuration ---------------------------*/
  2181. if (((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_TIM) == (RCC_PERIPHCLK_TIM))
  2182. {
  2183. __HAL_RCC_TIMCLKPRESCALER(PeriphClkInit->TIMPresSelection);
  2184. }
  2185. return HAL_OK;
  2186. }
  2187. /**
  2188. * @brief Configures the PeriphClkInit according to the internal
  2189. * RCC configuration registers.
  2190. * @param PeriphClkInit pointer to an RCC_PeriphCLKInitTypeDef structure that
  2191. * will be configured.
  2192. * @retval None
  2193. */
  2194. void HAL_RCCEx_GetPeriphCLKConfig(RCC_PeriphCLKInitTypeDef *PeriphClkInit)
  2195. {
  2196. uint32_t tempreg;
  2197. /* Set all possible values for the extended clock type parameter------------*/
  2198. PeriphClkInit->PeriphClockSelection = RCC_PERIPHCLK_I2S | RCC_PERIPHCLK_SAI_PLLSAI | RCC_PERIPHCLK_SAI_PLLI2S | RCC_PERIPHCLK_LTDC | RCC_PERIPHCLK_TIM | RCC_PERIPHCLK_RTC;
  2199. /* Get the PLLI2S Clock configuration -----------------------------------------------*/
  2200. PeriphClkInit->PLLI2S.PLLI2SN = (uint32_t)((RCC->PLLI2SCFGR & RCC_PLLI2SCFGR_PLLI2SN) >> RCC_PLLI2SCFGR_PLLI2SN_Pos);
  2201. PeriphClkInit->PLLI2S.PLLI2SR = (uint32_t)((RCC->PLLI2SCFGR & RCC_PLLI2SCFGR_PLLI2SR) >> RCC_PLLI2SCFGR_PLLI2SR_Pos);
  2202. PeriphClkInit->PLLI2S.PLLI2SQ = (uint32_t)((RCC->PLLI2SCFGR & RCC_PLLI2SCFGR_PLLI2SQ) >> RCC_PLLI2SCFGR_PLLI2SQ_Pos);
  2203. /* Get the PLLSAI Clock configuration -----------------------------------------------*/
  2204. PeriphClkInit->PLLSAI.PLLSAIN = (uint32_t)((RCC->PLLSAICFGR & RCC_PLLSAICFGR_PLLSAIN) >> RCC_PLLSAICFGR_PLLSAIN_Pos);
  2205. PeriphClkInit->PLLSAI.PLLSAIR = (uint32_t)((RCC->PLLSAICFGR & RCC_PLLSAICFGR_PLLSAIR) >> RCC_PLLSAICFGR_PLLSAIR_Pos);
  2206. PeriphClkInit->PLLSAI.PLLSAIQ = (uint32_t)((RCC->PLLSAICFGR & RCC_PLLSAICFGR_PLLSAIQ) >> RCC_PLLSAICFGR_PLLSAIQ_Pos);
  2207. /* Get the PLLSAI/PLLI2S division factors -----------------------------------------------*/
  2208. PeriphClkInit->PLLI2SDivQ = (uint32_t)((RCC->DCKCFGR & RCC_DCKCFGR_PLLI2SDIVQ) >> RCC_DCKCFGR_PLLI2SDIVQ_Pos);
  2209. PeriphClkInit->PLLSAIDivQ = (uint32_t)((RCC->DCKCFGR & RCC_DCKCFGR_PLLSAIDIVQ) >> RCC_DCKCFGR_PLLSAIDIVQ_Pos);
  2210. PeriphClkInit->PLLSAIDivR = (uint32_t)(RCC->DCKCFGR & RCC_DCKCFGR_PLLSAIDIVR);
  2211. /* Get the RTC Clock configuration -----------------------------------------------*/
  2212. tempreg = (RCC->CFGR & RCC_CFGR_RTCPRE);
  2213. PeriphClkInit->RTCClockSelection = (uint32_t)((tempreg) | (RCC->BDCR & RCC_BDCR_RTCSEL));
  2214. if ((RCC->DCKCFGR & RCC_DCKCFGR_TIMPRE) == RESET)
  2215. {
  2216. PeriphClkInit->TIMPresSelection = RCC_TIMPRES_DESACTIVATED;
  2217. }
  2218. else
  2219. {
  2220. PeriphClkInit->TIMPresSelection = RCC_TIMPRES_ACTIVATED;
  2221. }
  2222. }
  2223. /**
  2224. * @brief Return the peripheral clock frequency for a given peripheral(SAI..)
  2225. * @note Return 0 if peripheral clock identifier not managed by this API
  2226. * @param PeriphClk Peripheral clock identifier
  2227. * This parameter can be one of the following values:
  2228. * @arg RCC_PERIPHCLK_I2S: I2S peripheral clock
  2229. * @retval Frequency in KHz
  2230. */
  2231. uint32_t HAL_RCCEx_GetPeriphCLKFreq(uint32_t PeriphClk)
  2232. {
  2233. /* This variable used to store the I2S clock frequency (value in Hz) */
  2234. uint32_t frequency = 0U;
  2235. /* This variable used to store the VCO Input (value in Hz) */
  2236. uint32_t vcoinput = 0U;
  2237. uint32_t srcclk = 0U;
  2238. /* This variable used to store the VCO Output (value in Hz) */
  2239. uint32_t vcooutput = 0U;
  2240. switch (PeriphClk)
  2241. {
  2242. case RCC_PERIPHCLK_I2S:
  2243. {
  2244. /* Get the current I2S source */
  2245. srcclk = __HAL_RCC_GET_I2S_SOURCE();
  2246. switch (srcclk)
  2247. {
  2248. /* Check if I2S clock selection is External clock mapped on the I2S_CKIN pin used as I2S clock */
  2249. case RCC_I2SCLKSOURCE_EXT:
  2250. {
  2251. /* Set the I2S clock to the external clock value */
  2252. frequency = EXTERNAL_CLOCK_VALUE;
  2253. break;
  2254. }
  2255. /* Check if I2S clock selection is PLLI2S VCO output clock divided by PLLI2SR used as I2S clock */
  2256. case RCC_I2SCLKSOURCE_PLLI2S:
  2257. {
  2258. /* Configure the PLLI2S division factor */
  2259. /* PLLI2S_VCO Input = PLL_SOURCE/PLLM */
  2260. if ((RCC->PLLCFGR & RCC_PLLCFGR_PLLSRC) == RCC_PLLSOURCE_HSE)
  2261. {
  2262. /* Get the I2S source clock value */
  2263. vcoinput = (uint32_t)(HSE_VALUE / (uint32_t)(RCC->PLLCFGR & RCC_PLLCFGR_PLLM));
  2264. }
  2265. else
  2266. {
  2267. /* Get the I2S source clock value */
  2268. vcoinput = (uint32_t)(HSI_VALUE / (uint32_t)(RCC->PLLCFGR & RCC_PLLCFGR_PLLM));
  2269. }
  2270. /* PLLI2S_VCO Output = PLLI2S_VCO Input * PLLI2SN */
  2271. vcooutput = (uint32_t)(vcoinput * (((RCC->PLLI2SCFGR & RCC_PLLI2SCFGR_PLLI2SN) >> 6U) & (RCC_PLLI2SCFGR_PLLI2SN >> 6U)));
  2272. /* I2S_CLK = PLLI2S_VCO Output/PLLI2SR */
  2273. frequency = (uint32_t)(vcooutput / (((RCC->PLLI2SCFGR & RCC_PLLI2SCFGR_PLLI2SR) >> 28U) & (RCC_PLLI2SCFGR_PLLI2SR >> 28U)));
  2274. break;
  2275. }
  2276. /* Clock not enabled for I2S*/
  2277. default:
  2278. {
  2279. frequency = 0U;
  2280. break;
  2281. }
  2282. }
  2283. break;
  2284. }
  2285. default:
  2286. {
  2287. break;
  2288. }
  2289. }
  2290. return frequency;
  2291. }
  2292. #endif /* STM32F427xx || STM32F437xx || STM32F429xx || STM32F439xx */
  2293. #if defined(STM32F405xx) || defined(STM32F415xx) || defined(STM32F407xx)|| defined(STM32F417xx) ||\
  2294. defined(STM32F401xC) || defined(STM32F401xE) || defined(STM32F411xE)
  2295. /**
  2296. * @brief Initializes the RCC extended peripherals clocks according to the specified parameters in the
  2297. * RCC_PeriphCLKInitTypeDef.
  2298. * @param PeriphClkInit pointer to an RCC_PeriphCLKInitTypeDef structure that
  2299. * contains the configuration information for the Extended Peripherals clocks(I2S and RTC clocks).
  2300. *
  2301. * @note A caution to be taken when HAL_RCCEx_PeriphCLKConfig() is used to select RTC clock selection, in this case
  2302. * the Reset of Backup domain will be applied in order to modify the RTC Clock source as consequence all backup
  2303. * domain (RTC and RCC_BDCR register expect BKPSRAM) will be reset
  2304. *
  2305. * @retval HAL status
  2306. */
  2307. HAL_StatusTypeDef HAL_RCCEx_PeriphCLKConfig(RCC_PeriphCLKInitTypeDef *PeriphClkInit)
  2308. {
  2309. uint32_t tickstart = 0U;
  2310. uint32_t tmpreg1 = 0U;
  2311. /* Check the parameters */
  2312. assert_param(IS_RCC_PERIPHCLOCK(PeriphClkInit->PeriphClockSelection));
  2313. /*---------------------------- I2S configuration ---------------------------*/
  2314. if ((((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_I2S) == RCC_PERIPHCLK_I2S) ||
  2315. (((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_PLLI2S) == RCC_PERIPHCLK_PLLI2S))
  2316. {
  2317. /* check for Parameters */
  2318. assert_param(IS_RCC_PLLI2SR_VALUE(PeriphClkInit->PLLI2S.PLLI2SR));
  2319. assert_param(IS_RCC_PLLI2SN_VALUE(PeriphClkInit->PLLI2S.PLLI2SN));
  2320. #if defined(STM32F411xE)
  2321. assert_param(IS_RCC_PLLI2SM_VALUE(PeriphClkInit->PLLI2S.PLLI2SM));
  2322. #endif /* STM32F411xE */
  2323. /* Disable the PLLI2S */
  2324. __HAL_RCC_PLLI2S_DISABLE();
  2325. /* Get tick */
  2326. tickstart = HAL_GetTick();
  2327. /* Wait till PLLI2S is disabled */
  2328. while (__HAL_RCC_GET_FLAG(RCC_FLAG_PLLI2SRDY) != RESET)
  2329. {
  2330. if ((HAL_GetTick() - tickstart) > PLLI2S_TIMEOUT_VALUE)
  2331. {
  2332. /* return in case of Timeout detected */
  2333. return HAL_TIMEOUT;
  2334. }
  2335. }
  2336. #if defined(STM32F411xE)
  2337. /* Configure the PLLI2S division factors */
  2338. /* PLLI2S_VCO = f(VCO clock) = f(PLLI2S clock input) * (PLLI2SN/PLLI2SM) */
  2339. /* I2SCLK = f(PLLI2S clock output) = f(VCO clock) / PLLI2SR */
  2340. __HAL_RCC_PLLI2S_I2SCLK_CONFIG(PeriphClkInit->PLLI2S.PLLI2SM, PeriphClkInit->PLLI2S.PLLI2SN,
  2341. PeriphClkInit->PLLI2S.PLLI2SR);
  2342. #else
  2343. /* Configure the PLLI2S division factors */
  2344. /* PLLI2S_VCO = f(VCO clock) = f(PLLI2S clock input) * (PLLI2SN/PLLM) */
  2345. /* I2SCLK = f(PLLI2S clock output) = f(VCO clock) / PLLI2SR */
  2346. __HAL_RCC_PLLI2S_CONFIG(PeriphClkInit->PLLI2S.PLLI2SN, PeriphClkInit->PLLI2S.PLLI2SR);
  2347. #endif /* STM32F411xE */
  2348. /* Enable the PLLI2S */
  2349. __HAL_RCC_PLLI2S_ENABLE();
  2350. /* Get tick */
  2351. tickstart = HAL_GetTick();
  2352. /* Wait till PLLI2S is ready */
  2353. while (__HAL_RCC_GET_FLAG(RCC_FLAG_PLLI2SRDY) == RESET)
  2354. {
  2355. if ((HAL_GetTick() - tickstart) > PLLI2S_TIMEOUT_VALUE)
  2356. {
  2357. /* return in case of Timeout detected */
  2358. return HAL_TIMEOUT;
  2359. }
  2360. }
  2361. }
  2362. /*---------------------------- RTC configuration ---------------------------*/
  2363. if (((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_RTC) == (RCC_PERIPHCLK_RTC))
  2364. {
  2365. /* Check for RTC Parameters used to output RTCCLK */
  2366. assert_param(IS_RCC_RTCCLKSOURCE(PeriphClkInit->RTCClockSelection));
  2367. /* Enable Power Clock*/
  2368. __HAL_RCC_PWR_CLK_ENABLE();
  2369. /* Enable write access to Backup domain */
  2370. PWR->CR |= PWR_CR_DBP;
  2371. /* Get tick */
  2372. tickstart = HAL_GetTick();
  2373. while ((PWR->CR & PWR_CR_DBP) == RESET)
  2374. {
  2375. if ((HAL_GetTick() - tickstart) > RCC_DBP_TIMEOUT_VALUE)
  2376. {
  2377. return HAL_TIMEOUT;
  2378. }
  2379. }
  2380. /* Reset the Backup domain only if the RTC Clock source selection is modified from reset value */
  2381. tmpreg1 = (RCC->BDCR & RCC_BDCR_RTCSEL);
  2382. if ((tmpreg1 != 0x00000000U) && ((tmpreg1) != (PeriphClkInit->RTCClockSelection & RCC_BDCR_RTCSEL)))
  2383. {
  2384. /* Store the content of BDCR register before the reset of Backup Domain */
  2385. tmpreg1 = (RCC->BDCR & ~(RCC_BDCR_RTCSEL));
  2386. /* RTC Clock selection can be changed only if the Backup Domain is reset */
  2387. __HAL_RCC_BACKUPRESET_FORCE();
  2388. __HAL_RCC_BACKUPRESET_RELEASE();
  2389. /* Restore the Content of BDCR register */
  2390. RCC->BDCR = tmpreg1;
  2391. /* Wait for LSE reactivation if LSE was enable prior to Backup Domain reset */
  2392. if (HAL_IS_BIT_SET(RCC->BDCR, RCC_BDCR_LSEON))
  2393. {
  2394. /* Get tick */
  2395. tickstart = HAL_GetTick();
  2396. /* Wait till LSE is ready */
  2397. while (__HAL_RCC_GET_FLAG(RCC_FLAG_LSERDY) == RESET)
  2398. {
  2399. if ((HAL_GetTick() - tickstart) > RCC_LSE_TIMEOUT_VALUE)
  2400. {
  2401. return HAL_TIMEOUT;
  2402. }
  2403. }
  2404. }
  2405. }
  2406. __HAL_RCC_RTC_CONFIG(PeriphClkInit->RTCClockSelection);
  2407. }
  2408. #if defined(STM32F401xC) || defined(STM32F401xE) || defined(STM32F411xE)
  2409. /*---------------------------- TIM configuration ---------------------------*/
  2410. if (((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_TIM) == (RCC_PERIPHCLK_TIM))
  2411. {
  2412. __HAL_RCC_TIMCLKPRESCALER(PeriphClkInit->TIMPresSelection);
  2413. }
  2414. #endif /* STM32F401xC || STM32F401xE || STM32F411xE */
  2415. return HAL_OK;
  2416. }
  2417. /**
  2418. * @brief Configures the RCC_OscInitStruct according to the internal
  2419. * RCC configuration registers.
  2420. * @param PeriphClkInit pointer to an RCC_PeriphCLKInitTypeDef structure that
  2421. * will be configured.
  2422. * @retval None
  2423. */
  2424. void HAL_RCCEx_GetPeriphCLKConfig(RCC_PeriphCLKInitTypeDef *PeriphClkInit)
  2425. {
  2426. uint32_t tempreg;
  2427. /* Set all possible values for the extended clock type parameter------------*/
  2428. PeriphClkInit->PeriphClockSelection = RCC_PERIPHCLK_I2S | RCC_PERIPHCLK_RTC;
  2429. /* Get the PLLI2S Clock configuration --------------------------------------*/
  2430. PeriphClkInit->PLLI2S.PLLI2SN = (uint32_t)((RCC->PLLI2SCFGR & RCC_PLLI2SCFGR_PLLI2SN) >> RCC_PLLI2SCFGR_PLLI2SN_Pos);
  2431. PeriphClkInit->PLLI2S.PLLI2SR = (uint32_t)((RCC->PLLI2SCFGR & RCC_PLLI2SCFGR_PLLI2SR) >> RCC_PLLI2SCFGR_PLLI2SR_Pos);
  2432. #if defined(STM32F411xE)
  2433. PeriphClkInit->PLLI2S.PLLI2SM = (uint32_t)(RCC->PLLI2SCFGR & RCC_PLLI2SCFGR_PLLI2SM);
  2434. #endif /* STM32F411xE */
  2435. /* Get the RTC Clock configuration -----------------------------------------*/
  2436. tempreg = (RCC->CFGR & RCC_CFGR_RTCPRE);
  2437. PeriphClkInit->RTCClockSelection = (uint32_t)((tempreg) | (RCC->BDCR & RCC_BDCR_RTCSEL));
  2438. #if defined(STM32F401xC) || defined(STM32F401xE) || defined(STM32F411xE)
  2439. /* Get the TIM Prescaler configuration -------------------------------------*/
  2440. if ((RCC->DCKCFGR & RCC_DCKCFGR_TIMPRE) == RESET)
  2441. {
  2442. PeriphClkInit->TIMPresSelection = RCC_TIMPRES_DESACTIVATED;
  2443. }
  2444. else
  2445. {
  2446. PeriphClkInit->TIMPresSelection = RCC_TIMPRES_ACTIVATED;
  2447. }
  2448. #endif /* STM32F401xC || STM32F401xE || STM32F411xE */
  2449. }
  2450. /**
  2451. * @brief Return the peripheral clock frequency for a given peripheral(SAI..)
  2452. * @note Return 0 if peripheral clock identifier not managed by this API
  2453. * @param PeriphClk Peripheral clock identifier
  2454. * This parameter can be one of the following values:
  2455. * @arg RCC_PERIPHCLK_I2S: I2S peripheral clock
  2456. * @retval Frequency in KHz
  2457. */
  2458. uint32_t HAL_RCCEx_GetPeriphCLKFreq(uint32_t PeriphClk)
  2459. {
  2460. /* This variable used to store the I2S clock frequency (value in Hz) */
  2461. uint32_t frequency = 0U;
  2462. /* This variable used to store the VCO Input (value in Hz) */
  2463. uint32_t vcoinput = 0U;
  2464. uint32_t srcclk = 0U;
  2465. /* This variable used to store the VCO Output (value in Hz) */
  2466. uint32_t vcooutput = 0U;
  2467. switch (PeriphClk)
  2468. {
  2469. case RCC_PERIPHCLK_I2S:
  2470. {
  2471. /* Get the current I2S source */
  2472. srcclk = __HAL_RCC_GET_I2S_SOURCE();
  2473. switch (srcclk)
  2474. {
  2475. /* Check if I2S clock selection is External clock mapped on the I2S_CKIN pin used as I2S clock */
  2476. case RCC_I2SCLKSOURCE_EXT:
  2477. {
  2478. /* Set the I2S clock to the external clock value */
  2479. frequency = EXTERNAL_CLOCK_VALUE;
  2480. break;
  2481. }
  2482. /* Check if I2S clock selection is PLLI2S VCO output clock divided by PLLI2SR used as I2S clock */
  2483. case RCC_I2SCLKSOURCE_PLLI2S:
  2484. {
  2485. #if defined(STM32F411xE)
  2486. /* Configure the PLLI2S division factor */
  2487. /* PLLI2S_VCO Input = PLL_SOURCE/PLLI2SM */
  2488. if ((RCC->PLLCFGR & RCC_PLLCFGR_PLLSRC) == RCC_PLLSOURCE_HSE)
  2489. {
  2490. /* Get the I2S source clock value */
  2491. vcoinput = (uint32_t)(HSE_VALUE / (uint32_t)(RCC->PLLI2SCFGR & RCC_PLLI2SCFGR_PLLI2SM));
  2492. }
  2493. else
  2494. {
  2495. /* Get the I2S source clock value */
  2496. vcoinput = (uint32_t)(HSI_VALUE / (uint32_t)(RCC->PLLI2SCFGR & RCC_PLLI2SCFGR_PLLI2SM));
  2497. }
  2498. #else
  2499. /* Configure the PLLI2S division factor */
  2500. /* PLLI2S_VCO Input = PLL_SOURCE/PLLM */
  2501. if ((RCC->PLLCFGR & RCC_PLLCFGR_PLLSRC) == RCC_PLLSOURCE_HSE)
  2502. {
  2503. /* Get the I2S source clock value */
  2504. vcoinput = (uint32_t)(HSE_VALUE / (uint32_t)(RCC->PLLCFGR & RCC_PLLCFGR_PLLM));
  2505. }
  2506. else
  2507. {
  2508. /* Get the I2S source clock value */
  2509. vcoinput = (uint32_t)(HSI_VALUE / (uint32_t)(RCC->PLLCFGR & RCC_PLLCFGR_PLLM));
  2510. }
  2511. #endif /* STM32F411xE */
  2512. /* PLLI2S_VCO Output = PLLI2S_VCO Input * PLLI2SN */
  2513. vcooutput = (uint32_t)(vcoinput * (((RCC->PLLI2SCFGR & RCC_PLLI2SCFGR_PLLI2SN) >> 6U) & (RCC_PLLI2SCFGR_PLLI2SN >> 6U)));
  2514. /* I2S_CLK = PLLI2S_VCO Output/PLLI2SR */
  2515. frequency = (uint32_t)(vcooutput / (((RCC->PLLI2SCFGR & RCC_PLLI2SCFGR_PLLI2SR) >> 28U) & (RCC_PLLI2SCFGR_PLLI2SR >> 28U)));
  2516. break;
  2517. }
  2518. /* Clock not enabled for I2S*/
  2519. default:
  2520. {
  2521. frequency = 0U;
  2522. break;
  2523. }
  2524. }
  2525. break;
  2526. }
  2527. default:
  2528. {
  2529. break;
  2530. }
  2531. }
  2532. return frequency;
  2533. }
  2534. #endif /* STM32F405xx || STM32F415xx || STM32F407xx || STM32F417xx || STM32F401xC || STM32F401xE || STM32F411xE */
  2535. #if defined(STM32F410Tx) || defined(STM32F410Cx) || defined(STM32F410Rx) || defined(STM32F411xE) || defined(STM32F446xx) || defined(STM32F469xx) || defined(STM32F479xx) || defined(STM32F412Zx) ||\
  2536. defined(STM32F412Vx) || defined(STM32F412Rx) || defined(STM32F412Cx) || defined(STM32F413xx) || defined(STM32F423xx)
  2537. /**
  2538. * @brief Select LSE mode
  2539. *
  2540. * @note This mode is only available for STM32F410xx/STM32F411xx/STM32F446xx/STM32F469xx/STM32F479xx/STM32F412Zx/STM32F412Vx/STM32F412Rx/STM32F412Cx devices.
  2541. *
  2542. * @param Mode specifies the LSE mode.
  2543. * This parameter can be one of the following values:
  2544. * @arg RCC_LSE_LOWPOWER_MODE: LSE oscillator in low power mode selection
  2545. * @arg RCC_LSE_HIGHDRIVE_MODE: LSE oscillator in High Drive mode selection
  2546. * @retval None
  2547. */
  2548. void HAL_RCCEx_SelectLSEMode(uint8_t Mode)
  2549. {
  2550. /* Check the parameters */
  2551. assert_param(IS_RCC_LSE_MODE(Mode));
  2552. if (Mode == RCC_LSE_HIGHDRIVE_MODE)
  2553. {
  2554. SET_BIT(RCC->BDCR, RCC_BDCR_LSEMOD);
  2555. }
  2556. else
  2557. {
  2558. CLEAR_BIT(RCC->BDCR, RCC_BDCR_LSEMOD);
  2559. }
  2560. }
  2561. #endif /* STM32F410xx || STM32F411xE || STM32F446xx || STM32F469xx || STM32F479xx || STM32F412Zx || STM32F412Vx || STM32F412Rx || STM32F412Cx || STM32F413xx || STM32F423xx */
  2562. /** @defgroup RCCEx_Exported_Functions_Group2 Extended Clock management functions
  2563. * @brief Extended Clock management functions
  2564. *
  2565. @verbatim
  2566. ===============================================================================
  2567. ##### Extended clock management functions #####
  2568. ===============================================================================
  2569. [..]
  2570. This subsection provides a set of functions allowing to control the
  2571. activation or deactivation of PLLI2S, PLLSAI.
  2572. @endverbatim
  2573. * @{
  2574. */
  2575. #if defined(RCC_PLLI2S_SUPPORT)
  2576. /**
  2577. * @brief Enable PLLI2S.
  2578. * @param PLLI2SInit pointer to an RCC_PLLI2SInitTypeDef structure that
  2579. * contains the configuration information for the PLLI2S
  2580. * @retval HAL status
  2581. */
  2582. HAL_StatusTypeDef HAL_RCCEx_EnablePLLI2S(RCC_PLLI2SInitTypeDef *PLLI2SInit)
  2583. {
  2584. uint32_t tickstart;
  2585. /* Check for parameters */
  2586. assert_param(IS_RCC_PLLI2SN_VALUE(PLLI2SInit->PLLI2SN));
  2587. assert_param(IS_RCC_PLLI2SR_VALUE(PLLI2SInit->PLLI2SR));
  2588. #if defined(RCC_PLLI2SCFGR_PLLI2SM)
  2589. assert_param(IS_RCC_PLLI2SM_VALUE(PLLI2SInit->PLLI2SM));
  2590. #endif /* RCC_PLLI2SCFGR_PLLI2SM */
  2591. #if defined(RCC_PLLI2SCFGR_PLLI2SP)
  2592. assert_param(IS_RCC_PLLI2SP_VALUE(PLLI2SInit->PLLI2SP));
  2593. #endif /* RCC_PLLI2SCFGR_PLLI2SP */
  2594. #if defined(RCC_PLLI2SCFGR_PLLI2SQ)
  2595. assert_param(IS_RCC_PLLI2SQ_VALUE(PLLI2SInit->PLLI2SQ));
  2596. #endif /* RCC_PLLI2SCFGR_PLLI2SQ */
  2597. /* Disable the PLLI2S */
  2598. __HAL_RCC_PLLI2S_DISABLE();
  2599. /* Wait till PLLI2S is disabled */
  2600. tickstart = HAL_GetTick();
  2601. while (__HAL_RCC_GET_FLAG(RCC_FLAG_PLLI2SRDY) != RESET)
  2602. {
  2603. if ((HAL_GetTick() - tickstart) > PLLI2S_TIMEOUT_VALUE)
  2604. {
  2605. /* return in case of Timeout detected */
  2606. return HAL_TIMEOUT;
  2607. }
  2608. }
  2609. /* Configure the PLLI2S division factors */
  2610. #if defined(STM32F446xx)
  2611. /* PLLI2S_VCO = f(VCO clock) = f(PLLI2S clock input) * (PLLI2SN/PLLI2SM) */
  2612. /* I2SPCLK = PLLI2S_VCO / PLLI2SP */
  2613. /* I2SQCLK = PLLI2S_VCO / PLLI2SQ */
  2614. /* I2SRCLK = PLLI2S_VCO / PLLI2SR */
  2615. __HAL_RCC_PLLI2S_CONFIG(PLLI2SInit->PLLI2SM, PLLI2SInit->PLLI2SN, \
  2616. PLLI2SInit->PLLI2SP, PLLI2SInit->PLLI2SQ, PLLI2SInit->PLLI2SR);
  2617. #elif defined(STM32F412Zx) || defined(STM32F412Vx) || defined(STM32F412Rx) || defined(STM32F412Cx) ||\
  2618. defined(STM32F413xx) || defined(STM32F423xx)
  2619. /* PLLI2S_VCO = f(VCO clock) = f(PLLI2S clock input) * (PLLI2SN/PLLI2SM)*/
  2620. /* I2SQCLK = PLLI2S_VCO / PLLI2SQ */
  2621. /* I2SRCLK = PLLI2S_VCO / PLLI2SR */
  2622. __HAL_RCC_PLLI2S_CONFIG(PLLI2SInit->PLLI2SM, PLLI2SInit->PLLI2SN, \
  2623. PLLI2SInit->PLLI2SQ, PLLI2SInit->PLLI2SR);
  2624. #elif defined(STM32F427xx) || defined(STM32F437xx) || defined(STM32F429xx) || defined(STM32F439xx) ||\
  2625. defined(STM32F469xx) || defined(STM32F479xx)
  2626. /* PLLI2S_VCO = f(VCO clock) = f(PLLI2S clock input) * PLLI2SN */
  2627. /* I2SQCLK = PLLI2S_VCO / PLLI2SQ */
  2628. /* I2SRCLK = PLLI2S_VCO / PLLI2SR */
  2629. __HAL_RCC_PLLI2S_SAICLK_CONFIG(PLLI2SInit->PLLI2SN, PLLI2SInit->PLLI2SQ, PLLI2SInit->PLLI2SR);
  2630. #elif defined(STM32F411xE)
  2631. /* PLLI2S_VCO = f(VCO clock) = f(PLLI2S clock input) * (PLLI2SN/PLLI2SM) */
  2632. /* I2SRCLK = PLLI2S_VCO / PLLI2SR */
  2633. __HAL_RCC_PLLI2S_I2SCLK_CONFIG(PLLI2SInit->PLLI2SM, PLLI2SInit->PLLI2SN, PLLI2SInit->PLLI2SR);
  2634. #else
  2635. /* PLLI2S_VCO = f(VCO clock) = f(PLLI2S clock input) x PLLI2SN */
  2636. /* I2SRCLK = PLLI2S_VCO / PLLI2SR */
  2637. __HAL_RCC_PLLI2S_CONFIG(PLLI2SInit->PLLI2SN, PLLI2SInit->PLLI2SR);
  2638. #endif /* STM32F446xx */
  2639. /* Enable the PLLI2S */
  2640. __HAL_RCC_PLLI2S_ENABLE();
  2641. /* Wait till PLLI2S is ready */
  2642. tickstart = HAL_GetTick();
  2643. while (__HAL_RCC_GET_FLAG(RCC_FLAG_PLLI2SRDY) == RESET)
  2644. {
  2645. if ((HAL_GetTick() - tickstart) > PLLI2S_TIMEOUT_VALUE)
  2646. {
  2647. /* return in case of Timeout detected */
  2648. return HAL_TIMEOUT;
  2649. }
  2650. }
  2651. return HAL_OK;
  2652. }
  2653. /**
  2654. * @brief Disable PLLI2S.
  2655. * @retval HAL status
  2656. */
  2657. HAL_StatusTypeDef HAL_RCCEx_DisablePLLI2S(void)
  2658. {
  2659. uint32_t tickstart;
  2660. /* Disable the PLLI2S */
  2661. __HAL_RCC_PLLI2S_DISABLE();
  2662. /* Wait till PLLI2S is disabled */
  2663. tickstart = HAL_GetTick();
  2664. while (READ_BIT(RCC->CR, RCC_CR_PLLI2SRDY) != RESET)
  2665. {
  2666. if ((HAL_GetTick() - tickstart) > PLLI2S_TIMEOUT_VALUE)
  2667. {
  2668. /* return in case of Timeout detected */
  2669. return HAL_TIMEOUT;
  2670. }
  2671. }
  2672. return HAL_OK;
  2673. }
  2674. #endif /* RCC_PLLI2S_SUPPORT */
  2675. #if defined(RCC_PLLSAI_SUPPORT)
  2676. /**
  2677. * @brief Enable PLLSAI.
  2678. * @param PLLSAIInit pointer to an RCC_PLLSAIInitTypeDef structure that
  2679. * contains the configuration information for the PLLSAI
  2680. * @retval HAL status
  2681. */
  2682. HAL_StatusTypeDef HAL_RCCEx_EnablePLLSAI(RCC_PLLSAIInitTypeDef *PLLSAIInit)
  2683. {
  2684. uint32_t tickstart;
  2685. /* Check for parameters */
  2686. assert_param(IS_RCC_PLLSAIN_VALUE(PLLSAIInit->PLLSAIN));
  2687. assert_param(IS_RCC_PLLSAIQ_VALUE(PLLSAIInit->PLLSAIQ));
  2688. #if defined(RCC_PLLSAICFGR_PLLSAIM)
  2689. assert_param(IS_RCC_PLLSAIM_VALUE(PLLSAIInit->PLLSAIM));
  2690. #endif /* RCC_PLLSAICFGR_PLLSAIM */
  2691. #if defined(RCC_PLLSAICFGR_PLLSAIP)
  2692. assert_param(IS_RCC_PLLSAIP_VALUE(PLLSAIInit->PLLSAIP));
  2693. #endif /* RCC_PLLSAICFGR_PLLSAIP */
  2694. #if defined(RCC_PLLSAICFGR_PLLSAIR)
  2695. assert_param(IS_RCC_PLLSAIR_VALUE(PLLSAIInit->PLLSAIR));
  2696. #endif /* RCC_PLLSAICFGR_PLLSAIR */
  2697. /* Disable the PLLSAI */
  2698. __HAL_RCC_PLLSAI_DISABLE();
  2699. /* Wait till PLLSAI is disabled */
  2700. tickstart = HAL_GetTick();
  2701. while (__HAL_RCC_PLLSAI_GET_FLAG() != RESET)
  2702. {
  2703. if ((HAL_GetTick() - tickstart) > PLLSAI_TIMEOUT_VALUE)
  2704. {
  2705. /* return in case of Timeout detected */
  2706. return HAL_TIMEOUT;
  2707. }
  2708. }
  2709. /* Configure the PLLSAI division factors */
  2710. #if defined(STM32F446xx)
  2711. /* PLLSAI_VCO = f(VCO clock) = f(PLLSAI clock input) * (PLLSAIN/PLLSAIM) */
  2712. /* SAIPCLK = PLLSAI_VCO / PLLSAIP */
  2713. /* SAIQCLK = PLLSAI_VCO / PLLSAIQ */
  2714. /* SAIRCLK = PLLSAI_VCO / PLLSAIR */
  2715. __HAL_RCC_PLLSAI_CONFIG(PLLSAIInit->PLLSAIM, PLLSAIInit->PLLSAIN, \
  2716. PLLSAIInit->PLLSAIP, PLLSAIInit->PLLSAIQ, 0U);
  2717. #elif defined(STM32F469xx) || defined(STM32F479xx)
  2718. /* PLLSAI_VCO = f(VCO clock) = f(PLLSAI clock input) * PLLSAIN */
  2719. /* SAIPCLK = PLLSAI_VCO / PLLSAIP */
  2720. /* SAIQCLK = PLLSAI_VCO / PLLSAIQ */
  2721. /* SAIRCLK = PLLSAI_VCO / PLLSAIR */
  2722. __HAL_RCC_PLLSAI_CONFIG(PLLSAIInit->PLLSAIN, PLLSAIInit->PLLSAIP, \
  2723. PLLSAIInit->PLLSAIQ, PLLSAIInit->PLLSAIR);
  2724. #else
  2725. /* PLLSAI_VCO = f(VCO clock) = f(PLLSAI clock input) x PLLSAIN */
  2726. /* SAIQCLK = PLLSAI_VCO / PLLSAIQ */
  2727. /* SAIRCLK = PLLSAI_VCO / PLLSAIR */
  2728. __HAL_RCC_PLLSAI_CONFIG(PLLSAIInit->PLLSAIN, PLLSAIInit->PLLSAIQ, PLLSAIInit->PLLSAIR);
  2729. #endif /* STM32F446xx */
  2730. /* Enable the PLLSAI */
  2731. __HAL_RCC_PLLSAI_ENABLE();
  2732. /* Wait till PLLSAI is ready */
  2733. tickstart = HAL_GetTick();
  2734. while (__HAL_RCC_PLLSAI_GET_FLAG() == RESET)
  2735. {
  2736. if ((HAL_GetTick() - tickstart) > PLLSAI_TIMEOUT_VALUE)
  2737. {
  2738. /* return in case of Timeout detected */
  2739. return HAL_TIMEOUT;
  2740. }
  2741. }
  2742. return HAL_OK;
  2743. }
  2744. /**
  2745. * @brief Disable PLLSAI.
  2746. * @retval HAL status
  2747. */
  2748. HAL_StatusTypeDef HAL_RCCEx_DisablePLLSAI(void)
  2749. {
  2750. uint32_t tickstart;
  2751. /* Disable the PLLSAI */
  2752. __HAL_RCC_PLLSAI_DISABLE();
  2753. /* Wait till PLLSAI is disabled */
  2754. tickstart = HAL_GetTick();
  2755. while (__HAL_RCC_PLLSAI_GET_FLAG() != RESET)
  2756. {
  2757. if ((HAL_GetTick() - tickstart) > PLLSAI_TIMEOUT_VALUE)
  2758. {
  2759. /* return in case of Timeout detected */
  2760. return HAL_TIMEOUT;
  2761. }
  2762. }
  2763. return HAL_OK;
  2764. }
  2765. #endif /* RCC_PLLSAI_SUPPORT */
  2766. /**
  2767. * @}
  2768. */
  2769. #if defined(STM32F446xx)
  2770. /**
  2771. * @brief Returns the SYSCLK frequency
  2772. *
  2773. * @note This function implementation is valid only for STM32F446xx devices.
  2774. * @note This function add the PLL/PLLR System clock source
  2775. *
  2776. * @note The system frequency computed by this function is not the real
  2777. * frequency in the chip. It is calculated based on the predefined
  2778. * constant and the selected clock source:
  2779. * @note If SYSCLK source is HSI, function returns values based on HSI_VALUE(*)
  2780. * @note If SYSCLK source is HSE, function returns values based on HSE_VALUE(**)
  2781. * @note If SYSCLK source is PLL or PLLR, function returns values based on HSE_VALUE(**)
  2782. * or HSI_VALUE(*) multiplied/divided by the PLL factors.
  2783. * @note (*) HSI_VALUE is a constant defined in stm32f4xx_hal_conf.h file (default value
  2784. * 16 MHz) but the real value may vary depending on the variations
  2785. * in voltage and temperature.
  2786. * @note (**) HSE_VALUE is a constant defined in stm32f4xx_hal_conf.h file (default value
  2787. * 25 MHz), user has to ensure that HSE_VALUE is same as the real
  2788. * frequency of the crystal used. Otherwise, this function may
  2789. * have wrong result.
  2790. *
  2791. * @note The result of this function could be not correct when using fractional
  2792. * value for HSE crystal.
  2793. *
  2794. * @note This function can be used by the user application to compute the
  2795. * baudrate for the communication peripherals or configure other parameters.
  2796. *
  2797. * @note Each time SYSCLK changes, this function must be called to update the
  2798. * right SYSCLK value. Otherwise, any configuration based on this function will be incorrect.
  2799. *
  2800. *
  2801. * @retval SYSCLK frequency
  2802. */
  2803. uint32_t HAL_RCC_GetSysClockFreq(void)
  2804. {
  2805. uint32_t pllm = 0U;
  2806. uint32_t pllvco = 0U;
  2807. uint32_t pllp = 0U;
  2808. uint32_t pllr = 0U;
  2809. uint32_t sysclockfreq = 0U;
  2810. /* Get SYSCLK source -------------------------------------------------------*/
  2811. switch (RCC->CFGR & RCC_CFGR_SWS)
  2812. {
  2813. case RCC_CFGR_SWS_HSI: /* HSI used as system clock source */
  2814. {
  2815. sysclockfreq = HSI_VALUE;
  2816. break;
  2817. }
  2818. case RCC_CFGR_SWS_HSE: /* HSE used as system clock source */
  2819. {
  2820. sysclockfreq = HSE_VALUE;
  2821. break;
  2822. }
  2823. case RCC_CFGR_SWS_PLL: /* PLL/PLLP used as system clock source */
  2824. {
  2825. /* PLL_VCO = (HSE_VALUE or HSI_VALUE / PLLM) * PLLN
  2826. SYSCLK = PLL_VCO / PLLP */
  2827. pllm = RCC->PLLCFGR & RCC_PLLCFGR_PLLM;
  2828. if (__HAL_RCC_GET_PLL_OSCSOURCE() != RCC_PLLSOURCE_HSI)
  2829. {
  2830. /* HSE used as PLL clock source */
  2831. pllvco = (uint32_t)((((uint64_t) HSE_VALUE * ((uint64_t)((RCC->PLLCFGR & RCC_PLLCFGR_PLLN) >> RCC_PLLCFGR_PLLN_Pos)))) / (uint64_t)pllm);
  2832. }
  2833. else
  2834. {
  2835. /* HSI used as PLL clock source */
  2836. pllvco = (uint32_t)((((uint64_t) HSI_VALUE * ((uint64_t)((RCC->PLLCFGR & RCC_PLLCFGR_PLLN) >> RCC_PLLCFGR_PLLN_Pos)))) / (uint64_t)pllm);
  2837. }
  2838. pllp = ((((RCC->PLLCFGR & RCC_PLLCFGR_PLLP) >> RCC_PLLCFGR_PLLP_Pos) + 1U) * 2U);
  2839. sysclockfreq = pllvco / pllp;
  2840. break;
  2841. }
  2842. case RCC_CFGR_SWS_PLLR: /* PLL/PLLR used as system clock source */
  2843. {
  2844. /* PLL_VCO = (HSE_VALUE or HSI_VALUE / PLLM) * PLLN
  2845. SYSCLK = PLL_VCO / PLLR */
  2846. pllm = RCC->PLLCFGR & RCC_PLLCFGR_PLLM;
  2847. if (__HAL_RCC_GET_PLL_OSCSOURCE() != RCC_PLLSOURCE_HSI)
  2848. {
  2849. /* HSE used as PLL clock source */
  2850. pllvco = (uint32_t)((((uint64_t) HSE_VALUE * ((uint64_t)((RCC->PLLCFGR & RCC_PLLCFGR_PLLN) >> RCC_PLLCFGR_PLLN_Pos)))) / (uint64_t)pllm);
  2851. }
  2852. else
  2853. {
  2854. /* HSI used as PLL clock source */
  2855. pllvco = (uint32_t)((((uint64_t) HSI_VALUE * ((uint64_t)((RCC->PLLCFGR & RCC_PLLCFGR_PLLN) >> RCC_PLLCFGR_PLLN_Pos)))) / (uint64_t)pllm);
  2856. }
  2857. pllr = ((RCC->PLLCFGR & RCC_PLLCFGR_PLLR) >> RCC_PLLCFGR_PLLR_Pos);
  2858. sysclockfreq = pllvco / pllr;
  2859. break;
  2860. }
  2861. default:
  2862. {
  2863. sysclockfreq = HSI_VALUE;
  2864. break;
  2865. }
  2866. }
  2867. return sysclockfreq;
  2868. }
  2869. #endif /* STM32F446xx */
  2870. /**
  2871. * @}
  2872. */
  2873. /**
  2874. * @}
  2875. */
  2876. /**
  2877. * @brief Resets the RCC clock configuration to the default reset state.
  2878. * @note The default reset state of the clock configuration is given below:
  2879. * - HSI ON and used as system clock source
  2880. * - HSE, PLL, PLLI2S and PLLSAI OFF
  2881. * - AHB, APB1 and APB2 prescaler set to 1.
  2882. * - CSS, MCO1 and MCO2 OFF
  2883. * - All interrupts disabled
  2884. * @note This function doesn't modify the configuration of the
  2885. * - Peripheral clocks
  2886. * - LSI, LSE and RTC clocks
  2887. * @retval HAL status
  2888. */
  2889. HAL_StatusTypeDef HAL_RCC_DeInit(void)
  2890. {
  2891. uint32_t tickstart;
  2892. /* Get Start Tick */
  2893. tickstart = HAL_GetTick();
  2894. /* Set HSION bit to the reset value */
  2895. SET_BIT(RCC->CR, RCC_CR_HSION);
  2896. /* Wait till HSI is ready */
  2897. while (READ_BIT(RCC->CR, RCC_CR_HSIRDY) == RESET)
  2898. {
  2899. if ((HAL_GetTick() - tickstart) > HSI_TIMEOUT_VALUE)
  2900. {
  2901. return HAL_TIMEOUT;
  2902. }
  2903. }
  2904. /* Set HSITRIM[4:0] bits to the reset value */
  2905. SET_BIT(RCC->CR, RCC_CR_HSITRIM_4);
  2906. /* Get Start Tick */
  2907. tickstart = HAL_GetTick();
  2908. /* Reset CFGR register */
  2909. CLEAR_REG(RCC->CFGR);
  2910. /* Wait till clock switch is ready */
  2911. while (READ_BIT(RCC->CFGR, RCC_CFGR_SWS) != RESET)
  2912. {
  2913. if ((HAL_GetTick() - tickstart) > CLOCKSWITCH_TIMEOUT_VALUE)
  2914. {
  2915. return HAL_TIMEOUT;
  2916. }
  2917. }
  2918. /* Get Start Tick */
  2919. tickstart = HAL_GetTick();
  2920. /* Clear HSEON, HSEBYP and CSSON bits */
  2921. CLEAR_BIT(RCC->CR, RCC_CR_HSEON | RCC_CR_HSEBYP | RCC_CR_CSSON);
  2922. /* Wait till HSE is disabled */
  2923. while (READ_BIT(RCC->CR, RCC_CR_HSERDY) != RESET)
  2924. {
  2925. if ((HAL_GetTick() - tickstart) > HSE_TIMEOUT_VALUE)
  2926. {
  2927. return HAL_TIMEOUT;
  2928. }
  2929. }
  2930. /* Get Start Tick */
  2931. tickstart = HAL_GetTick();
  2932. /* Clear PLLON bit */
  2933. CLEAR_BIT(RCC->CR, RCC_CR_PLLON);
  2934. /* Wait till PLL is disabled */
  2935. while (READ_BIT(RCC->CR, RCC_CR_PLLRDY) != RESET)
  2936. {
  2937. if ((HAL_GetTick() - tickstart) > PLL_TIMEOUT_VALUE)
  2938. {
  2939. return HAL_TIMEOUT;
  2940. }
  2941. }
  2942. #if defined(RCC_PLLI2S_SUPPORT)
  2943. /* Get Start Tick */
  2944. tickstart = HAL_GetTick();
  2945. /* Reset PLLI2SON bit */
  2946. CLEAR_BIT(RCC->CR, RCC_CR_PLLI2SON);
  2947. /* Wait till PLLI2S is disabled */
  2948. while (READ_BIT(RCC->CR, RCC_CR_PLLI2SRDY) != RESET)
  2949. {
  2950. if ((HAL_GetTick() - tickstart) > PLLI2S_TIMEOUT_VALUE)
  2951. {
  2952. return HAL_TIMEOUT;
  2953. }
  2954. }
  2955. #endif /* RCC_PLLI2S_SUPPORT */
  2956. #if defined(RCC_PLLSAI_SUPPORT)
  2957. /* Get Start Tick */
  2958. tickstart = HAL_GetTick();
  2959. /* Reset PLLSAI bit */
  2960. CLEAR_BIT(RCC->CR, RCC_CR_PLLSAION);
  2961. /* Wait till PLLSAI is disabled */
  2962. while (READ_BIT(RCC->CR, RCC_CR_PLLSAIRDY) != RESET)
  2963. {
  2964. if ((HAL_GetTick() - tickstart) > PLLSAI_TIMEOUT_VALUE)
  2965. {
  2966. return HAL_TIMEOUT;
  2967. }
  2968. }
  2969. #endif /* RCC_PLLSAI_SUPPORT */
  2970. /* Once PLL, PLLI2S and PLLSAI are OFF, reset PLLCFGR register to default value */
  2971. #if defined(STM32F412Cx) || defined(STM32F412Rx) || defined(STM32F412Vx) || defined(STM32F412Zx) || defined(STM32F413xx) || \
  2972. defined(STM32F423xx) || defined(STM32F446xx) || defined(STM32F469xx) || defined(STM32F479xx)
  2973. RCC->PLLCFGR = RCC_PLLCFGR_PLLM_4 | RCC_PLLCFGR_PLLN_6 | RCC_PLLCFGR_PLLN_7 | RCC_PLLCFGR_PLLQ_2 | RCC_PLLCFGR_PLLR_1;
  2974. #elif defined(STM32F410Tx) || defined(STM32F410Cx) || defined(STM32F410Rx)
  2975. 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;
  2976. #else
  2977. RCC->PLLCFGR = RCC_PLLCFGR_PLLM_4 | RCC_PLLCFGR_PLLN_6 | RCC_PLLCFGR_PLLN_7 | RCC_PLLCFGR_PLLQ_2;
  2978. #endif /* STM32F412Cx || STM32F412Rx || STM32F412Vx || STM32F412Zx || STM32F413xx || STM32F423xx || STM32F446xx || STM32F469xx || STM32F479xx */
  2979. /* Reset PLLI2SCFGR register to default value */
  2980. #if defined(STM32F412Cx) || defined(STM32F412Rx) || defined(STM32F412Vx) || defined(STM32F412Zx) || defined(STM32F413xx) || \
  2981. defined(STM32F423xx) || defined(STM32F446xx)
  2982. RCC->PLLI2SCFGR = RCC_PLLI2SCFGR_PLLI2SM_4 | RCC_PLLI2SCFGR_PLLI2SN_6 | RCC_PLLI2SCFGR_PLLI2SN_7 | RCC_PLLI2SCFGR_PLLI2SQ_2 | RCC_PLLI2SCFGR_PLLI2SR_1;
  2983. #elif defined(STM32F401xC) || defined(STM32F401xE) || defined(STM32F405xx) || defined(STM32F415xx) || defined(STM32F407xx) || defined(STM32F417xx)
  2984. RCC->PLLI2SCFGR = RCC_PLLI2SCFGR_PLLI2SN_6 | RCC_PLLI2SCFGR_PLLI2SN_7 | RCC_PLLI2SCFGR_PLLI2SR_1;
  2985. #elif defined(STM32F427xx) || defined(STM32F437xx) || defined(STM32F429xx) || defined(STM32F439xx) || defined(STM32F469xx) || defined(STM32F479xx)
  2986. RCC->PLLI2SCFGR = RCC_PLLI2SCFGR_PLLI2SN_6 | RCC_PLLI2SCFGR_PLLI2SN_7 | RCC_PLLI2SCFGR_PLLI2SQ_2 | RCC_PLLI2SCFGR_PLLI2SR_1;
  2987. #elif defined(STM32F411xE)
  2988. RCC->PLLI2SCFGR = RCC_PLLI2SCFGR_PLLI2SM_4 | RCC_PLLI2SCFGR_PLLI2SN_6 | RCC_PLLI2SCFGR_PLLI2SN_7 | RCC_PLLI2SCFGR_PLLI2SR_1;
  2989. #endif /* STM32F412Cx || STM32F412Rx || STM32F412Vx || STM32F412Zx || STM32F413xx || STM32F423xx || STM32F446xx */
  2990. /* Reset PLLSAICFGR register */
  2991. #if defined(STM32F427xx) || defined(STM32F429xx) || defined(STM32F437xx) || defined(STM32F439xx) || defined(STM32F469xx) || defined(STM32F479xx)
  2992. RCC->PLLSAICFGR = RCC_PLLSAICFGR_PLLSAIN_6 | RCC_PLLSAICFGR_PLLSAIN_7 | RCC_PLLSAICFGR_PLLSAIQ_2 | RCC_PLLSAICFGR_PLLSAIR_1;
  2993. #elif defined(STM32F446xx)
  2994. RCC->PLLSAICFGR = RCC_PLLSAICFGR_PLLSAIM_4 | RCC_PLLSAICFGR_PLLSAIN_6 | RCC_PLLSAICFGR_PLLSAIN_7 | RCC_PLLSAICFGR_PLLSAIQ_2;
  2995. #endif /* STM32F427xx || STM32F429xx || STM32F437xx || STM32F439xx || STM32F469xx || STM32F479xx */
  2996. /* Disable all interrupts */
  2997. CLEAR_BIT(RCC->CIR, RCC_CIR_LSIRDYIE | RCC_CIR_LSERDYIE | RCC_CIR_HSIRDYIE | RCC_CIR_HSERDYIE | RCC_CIR_PLLRDYIE);
  2998. #if defined(RCC_CIR_PLLI2SRDYIE)
  2999. CLEAR_BIT(RCC->CIR, RCC_CIR_PLLI2SRDYIE);
  3000. #endif /* RCC_CIR_PLLI2SRDYIE */
  3001. #if defined(RCC_CIR_PLLSAIRDYIE)
  3002. CLEAR_BIT(RCC->CIR, RCC_CIR_PLLSAIRDYIE);
  3003. #endif /* RCC_CIR_PLLSAIRDYIE */
  3004. /* Clear all interrupt flags */
  3005. SET_BIT(RCC->CIR, RCC_CIR_LSIRDYC | RCC_CIR_LSERDYC | RCC_CIR_HSIRDYC | RCC_CIR_HSERDYC | RCC_CIR_PLLRDYC |
  3006. RCC_CIR_CSSC);
  3007. #if defined(RCC_CIR_PLLI2SRDYC)
  3008. SET_BIT(RCC->CIR, RCC_CIR_PLLI2SRDYC);
  3009. #endif /* RCC_CIR_PLLI2SRDYC */
  3010. #if defined(RCC_CIR_PLLSAIRDYC)
  3011. SET_BIT(RCC->CIR, RCC_CIR_PLLSAIRDYC);
  3012. #endif /* RCC_CIR_PLLSAIRDYC */
  3013. /* Clear LSION bit */
  3014. CLEAR_BIT(RCC->CSR, RCC_CSR_LSION);
  3015. /* Reset all CSR flags */
  3016. SET_BIT(RCC->CSR, RCC_CSR_RMVF);
  3017. /* Update the SystemCoreClock global variable */
  3018. SystemCoreClock = HSI_VALUE;
  3019. /* Adapt Systick interrupt period */
  3020. if (HAL_InitTick(uwTickPrio) != HAL_OK)
  3021. {
  3022. return HAL_ERROR;
  3023. }
  3024. else
  3025. {
  3026. return HAL_OK;
  3027. }
  3028. }
  3029. #if defined(STM32F410Tx) || defined(STM32F410Cx) || defined(STM32F410Rx) || defined(STM32F446xx) || defined(STM32F469xx) || defined(STM32F479xx) || defined(STM32F412Zx) ||\
  3030. defined(STM32F412Vx) || defined(STM32F412Rx) || defined(STM32F412Cx) || defined(STM32F413xx) || defined(STM32F423xx)
  3031. /**
  3032. * @brief Initializes the RCC Oscillators according to the specified parameters in the
  3033. * RCC_OscInitTypeDef.
  3034. * @param RCC_OscInitStruct pointer to an RCC_OscInitTypeDef structure that
  3035. * contains the configuration information for the RCC Oscillators.
  3036. * @note The PLL is not disabled when used as system clock.
  3037. * @note Transitions LSE Bypass to LSE On and LSE On to LSE Bypass are not
  3038. * supported by this API. User should request a transition to LSE Off
  3039. * first and then LSE On or LSE Bypass.
  3040. * @note Transition HSE Bypass to HSE On and HSE On to HSE Bypass are not
  3041. * supported by this API. User should request a transition to HSE Off
  3042. * first and then HSE On or HSE Bypass.
  3043. * @note This function add the PLL/PLLR factor management during PLL configuration this feature
  3044. * is only available in STM32F410xx/STM32F446xx/STM32F469xx/STM32F479xx/STM32F412Zx/STM32F412Vx/STM32F412Rx/STM32F412Cx devices
  3045. * @retval HAL status
  3046. */
  3047. HAL_StatusTypeDef HAL_RCC_OscConfig(const RCC_OscInitTypeDef *RCC_OscInitStruct)
  3048. {
  3049. uint32_t tickstart;
  3050. uint32_t pll_config;
  3051. /* Check Null pointer */
  3052. if (RCC_OscInitStruct == NULL)
  3053. {
  3054. return HAL_ERROR;
  3055. }
  3056. /* Check the parameters */
  3057. assert_param(IS_RCC_OSCILLATORTYPE(RCC_OscInitStruct->OscillatorType));
  3058. /*------------------------------- HSE Configuration ------------------------*/
  3059. if (((RCC_OscInitStruct->OscillatorType) & RCC_OSCILLATORTYPE_HSE) == RCC_OSCILLATORTYPE_HSE)
  3060. {
  3061. /* Check the parameters */
  3062. assert_param(IS_RCC_HSE(RCC_OscInitStruct->HSEState));
  3063. /* When the HSE is used as system clock or clock source for PLL in these cases HSE will not disabled */
  3064. #if defined(STM32F446xx)
  3065. if ((__HAL_RCC_GET_SYSCLK_SOURCE() == RCC_CFGR_SWS_HSE)
  3066. || \
  3067. ((__HAL_RCC_GET_SYSCLK_SOURCE() == RCC_CFGR_SWS_PLL) && ((RCC->PLLCFGR & RCC_PLLCFGR_PLLSRC) == RCC_PLLCFGR_PLLSRC_HSE)) || \
  3068. ((__HAL_RCC_GET_SYSCLK_SOURCE() == RCC_CFGR_SWS_PLLR) && ((RCC->PLLCFGR & RCC_PLLCFGR_PLLSRC) == RCC_PLLCFGR_PLLSRC_HSE)))
  3069. #else
  3070. if ((__HAL_RCC_GET_SYSCLK_SOURCE() == RCC_CFGR_SWS_HSE)
  3071. || \
  3072. ((__HAL_RCC_GET_SYSCLK_SOURCE() == RCC_CFGR_SWS_PLL) && ((RCC->PLLCFGR & RCC_PLLCFGR_PLLSRC) == RCC_PLLCFGR_PLLSRC_HSE)))
  3073. #endif /* STM32F446xx */
  3074. {
  3075. if ((__HAL_RCC_GET_FLAG(RCC_FLAG_HSERDY) != RESET) && (RCC_OscInitStruct->HSEState == RCC_HSE_OFF))
  3076. {
  3077. return HAL_ERROR;
  3078. }
  3079. }
  3080. else
  3081. {
  3082. /* Set the new HSE configuration ---------------------------------------*/
  3083. __HAL_RCC_HSE_CONFIG(RCC_OscInitStruct->HSEState);
  3084. /* Check the HSE State */
  3085. if ((RCC_OscInitStruct->HSEState) != RCC_HSE_OFF)
  3086. {
  3087. /* Get Start Tick*/
  3088. tickstart = HAL_GetTick();
  3089. /* Wait till HSE is ready */
  3090. while (__HAL_RCC_GET_FLAG(RCC_FLAG_HSERDY) == RESET)
  3091. {
  3092. if ((HAL_GetTick() - tickstart) > HSE_TIMEOUT_VALUE)
  3093. {
  3094. return HAL_TIMEOUT;
  3095. }
  3096. }
  3097. }
  3098. else
  3099. {
  3100. /* Get Start Tick*/
  3101. tickstart = HAL_GetTick();
  3102. /* Wait till HSE is bypassed or disabled */
  3103. while (__HAL_RCC_GET_FLAG(RCC_FLAG_HSERDY) != RESET)
  3104. {
  3105. if ((HAL_GetTick() - tickstart) > HSE_TIMEOUT_VALUE)
  3106. {
  3107. return HAL_TIMEOUT;
  3108. }
  3109. }
  3110. }
  3111. }
  3112. }
  3113. /*----------------------------- HSI Configuration --------------------------*/
  3114. if (((RCC_OscInitStruct->OscillatorType) & RCC_OSCILLATORTYPE_HSI) == RCC_OSCILLATORTYPE_HSI)
  3115. {
  3116. /* Check the parameters */
  3117. assert_param(IS_RCC_HSI(RCC_OscInitStruct->HSIState));
  3118. assert_param(IS_RCC_CALIBRATION_VALUE(RCC_OscInitStruct->HSICalibrationValue));
  3119. /* Check if HSI is used as system clock or as PLL source when PLL is selected as system clock */
  3120. #if defined(STM32F446xx)
  3121. if ((__HAL_RCC_GET_SYSCLK_SOURCE() == RCC_CFGR_SWS_HSI)
  3122. || \
  3123. ((__HAL_RCC_GET_SYSCLK_SOURCE() == RCC_CFGR_SWS_PLL) && ((RCC->PLLCFGR & RCC_PLLCFGR_PLLSRC) == RCC_PLLCFGR_PLLSRC_HSI)) || \
  3124. ((__HAL_RCC_GET_SYSCLK_SOURCE() == RCC_CFGR_SWS_PLLR) && ((RCC->PLLCFGR & RCC_PLLCFGR_PLLSRC) == RCC_PLLCFGR_PLLSRC_HSI)))
  3125. #else
  3126. if ((__HAL_RCC_GET_SYSCLK_SOURCE() == RCC_CFGR_SWS_HSI)
  3127. || \
  3128. ((__HAL_RCC_GET_SYSCLK_SOURCE() == RCC_CFGR_SWS_PLL) && ((RCC->PLLCFGR & RCC_PLLCFGR_PLLSRC) == RCC_PLLCFGR_PLLSRC_HSI)))
  3129. #endif /* STM32F446xx */
  3130. {
  3131. /* When HSI is used as system clock it will not disabled */
  3132. if ((__HAL_RCC_GET_FLAG(RCC_FLAG_HSIRDY) != RESET) && (RCC_OscInitStruct->HSIState != RCC_HSI_ON))
  3133. {
  3134. return HAL_ERROR;
  3135. }
  3136. /* Otherwise, just the calibration is allowed */
  3137. else
  3138. {
  3139. /* Adjusts the Internal High Speed oscillator (HSI) calibration value.*/
  3140. __HAL_RCC_HSI_CALIBRATIONVALUE_ADJUST(RCC_OscInitStruct->HSICalibrationValue);
  3141. }
  3142. }
  3143. else
  3144. {
  3145. /* Check the HSI State */
  3146. if ((RCC_OscInitStruct->HSIState) != RCC_HSI_OFF)
  3147. {
  3148. /* Enable the Internal High Speed oscillator (HSI). */
  3149. __HAL_RCC_HSI_ENABLE();
  3150. /* Get Start Tick*/
  3151. tickstart = HAL_GetTick();
  3152. /* Wait till HSI is ready */
  3153. while (__HAL_RCC_GET_FLAG(RCC_FLAG_HSIRDY) == RESET)
  3154. {
  3155. if ((HAL_GetTick() - tickstart) > HSI_TIMEOUT_VALUE)
  3156. {
  3157. return HAL_TIMEOUT;
  3158. }
  3159. }
  3160. /* Adjusts the Internal High Speed oscillator (HSI) calibration value.*/
  3161. __HAL_RCC_HSI_CALIBRATIONVALUE_ADJUST(RCC_OscInitStruct->HSICalibrationValue);
  3162. }
  3163. else
  3164. {
  3165. /* Disable the Internal High Speed oscillator (HSI). */
  3166. __HAL_RCC_HSI_DISABLE();
  3167. /* Get Start Tick*/
  3168. tickstart = HAL_GetTick();
  3169. /* Wait till HSI is ready */
  3170. while (__HAL_RCC_GET_FLAG(RCC_FLAG_HSIRDY) != RESET)
  3171. {
  3172. if ((HAL_GetTick() - tickstart) > HSI_TIMEOUT_VALUE)
  3173. {
  3174. return HAL_TIMEOUT;
  3175. }
  3176. }
  3177. }
  3178. }
  3179. }
  3180. /*------------------------------ LSI Configuration -------------------------*/
  3181. if (((RCC_OscInitStruct->OscillatorType) & RCC_OSCILLATORTYPE_LSI) == RCC_OSCILLATORTYPE_LSI)
  3182. {
  3183. /* Check the parameters */
  3184. assert_param(IS_RCC_LSI(RCC_OscInitStruct->LSIState));
  3185. /* Check the LSI State */
  3186. if ((RCC_OscInitStruct->LSIState) != RCC_LSI_OFF)
  3187. {
  3188. /* Enable the Internal Low Speed oscillator (LSI). */
  3189. __HAL_RCC_LSI_ENABLE();
  3190. /* Get Start Tick*/
  3191. tickstart = HAL_GetTick();
  3192. /* Wait till LSI is ready */
  3193. while (__HAL_RCC_GET_FLAG(RCC_FLAG_LSIRDY) == RESET)
  3194. {
  3195. if ((HAL_GetTick() - tickstart) > LSI_TIMEOUT_VALUE)
  3196. {
  3197. return HAL_TIMEOUT;
  3198. }
  3199. }
  3200. }
  3201. else
  3202. {
  3203. /* Disable the Internal Low Speed oscillator (LSI). */
  3204. __HAL_RCC_LSI_DISABLE();
  3205. /* Get Start Tick*/
  3206. tickstart = HAL_GetTick();
  3207. /* Wait till LSI is ready */
  3208. while (__HAL_RCC_GET_FLAG(RCC_FLAG_LSIRDY) != RESET)
  3209. {
  3210. if ((HAL_GetTick() - tickstart) > LSI_TIMEOUT_VALUE)
  3211. {
  3212. return HAL_TIMEOUT;
  3213. }
  3214. }
  3215. }
  3216. }
  3217. /*------------------------------ LSE Configuration -------------------------*/
  3218. if (((RCC_OscInitStruct->OscillatorType) & RCC_OSCILLATORTYPE_LSE) == RCC_OSCILLATORTYPE_LSE)
  3219. {
  3220. FlagStatus pwrclkchanged = RESET;
  3221. /* Check the parameters */
  3222. assert_param(IS_RCC_LSE(RCC_OscInitStruct->LSEState));
  3223. /* Update LSE configuration in Backup Domain control register */
  3224. /* Requires to enable write access to Backup Domain of necessary */
  3225. if (__HAL_RCC_PWR_IS_CLK_DISABLED())
  3226. {
  3227. __HAL_RCC_PWR_CLK_ENABLE();
  3228. pwrclkchanged = SET;
  3229. }
  3230. if (HAL_IS_BIT_CLR(PWR->CR, PWR_CR_DBP))
  3231. {
  3232. /* Enable write access to Backup domain */
  3233. SET_BIT(PWR->CR, PWR_CR_DBP);
  3234. /* Wait for Backup domain Write protection disable */
  3235. tickstart = HAL_GetTick();
  3236. while (HAL_IS_BIT_CLR(PWR->CR, PWR_CR_DBP))
  3237. {
  3238. if ((HAL_GetTick() - tickstart) > RCC_DBP_TIMEOUT_VALUE)
  3239. {
  3240. return HAL_TIMEOUT;
  3241. }
  3242. }
  3243. }
  3244. /* Set the new LSE configuration -----------------------------------------*/
  3245. __HAL_RCC_LSE_CONFIG(RCC_OscInitStruct->LSEState);
  3246. /* Check the LSE State */
  3247. if ((RCC_OscInitStruct->LSEState) != RCC_LSE_OFF)
  3248. {
  3249. /* Get Start Tick*/
  3250. tickstart = HAL_GetTick();
  3251. /* Wait till LSE is ready */
  3252. while (__HAL_RCC_GET_FLAG(RCC_FLAG_LSERDY) == RESET)
  3253. {
  3254. if ((HAL_GetTick() - tickstart) > RCC_LSE_TIMEOUT_VALUE)
  3255. {
  3256. return HAL_TIMEOUT;
  3257. }
  3258. }
  3259. }
  3260. else
  3261. {
  3262. /* Get Start Tick*/
  3263. tickstart = HAL_GetTick();
  3264. /* Wait till LSE is ready */
  3265. while (__HAL_RCC_GET_FLAG(RCC_FLAG_LSERDY) != RESET)
  3266. {
  3267. if ((HAL_GetTick() - tickstart) > RCC_LSE_TIMEOUT_VALUE)
  3268. {
  3269. return HAL_TIMEOUT;
  3270. }
  3271. }
  3272. }
  3273. /* Restore clock configuration if changed */
  3274. if (pwrclkchanged == SET)
  3275. {
  3276. __HAL_RCC_PWR_CLK_DISABLE();
  3277. }
  3278. }
  3279. /*-------------------------------- PLL Configuration -----------------------*/
  3280. /* Check the parameters */
  3281. assert_param(IS_RCC_PLL(RCC_OscInitStruct->PLL.PLLState));
  3282. if ((RCC_OscInitStruct->PLL.PLLState) != RCC_PLL_NONE)
  3283. {
  3284. /* Check if the PLL is used as system clock or not */
  3285. if (__HAL_RCC_GET_SYSCLK_SOURCE() != RCC_CFGR_SWS_PLL)
  3286. {
  3287. if ((RCC_OscInitStruct->PLL.PLLState) == RCC_PLL_ON)
  3288. {
  3289. /* Check the parameters */
  3290. assert_param(IS_RCC_PLLSOURCE(RCC_OscInitStruct->PLL.PLLSource));
  3291. assert_param(IS_RCC_PLLM_VALUE(RCC_OscInitStruct->PLL.PLLM));
  3292. assert_param(IS_RCC_PLLN_VALUE(RCC_OscInitStruct->PLL.PLLN));
  3293. assert_param(IS_RCC_PLLP_VALUE(RCC_OscInitStruct->PLL.PLLP));
  3294. assert_param(IS_RCC_PLLQ_VALUE(RCC_OscInitStruct->PLL.PLLQ));
  3295. assert_param(IS_RCC_PLLR_VALUE(RCC_OscInitStruct->PLL.PLLR));
  3296. /* Disable the main PLL. */
  3297. __HAL_RCC_PLL_DISABLE();
  3298. /* Get Start Tick*/
  3299. tickstart = HAL_GetTick();
  3300. /* Wait till PLL is ready */
  3301. while (__HAL_RCC_GET_FLAG(RCC_FLAG_PLLRDY) != RESET)
  3302. {
  3303. if ((HAL_GetTick() - tickstart) > PLL_TIMEOUT_VALUE)
  3304. {
  3305. return HAL_TIMEOUT;
  3306. }
  3307. }
  3308. /* Configure the main PLL clock source, multiplication and division factors. */
  3309. WRITE_REG(RCC->PLLCFGR, (RCC_OscInitStruct->PLL.PLLSource | \
  3310. RCC_OscInitStruct->PLL.PLLM | \
  3311. (RCC_OscInitStruct->PLL.PLLN << RCC_PLLCFGR_PLLN_Pos) | \
  3312. (((RCC_OscInitStruct->PLL.PLLP >> 1U) - 1U) << RCC_PLLCFGR_PLLP_Pos) | \
  3313. (RCC_OscInitStruct->PLL.PLLQ << RCC_PLLCFGR_PLLQ_Pos) | \
  3314. (RCC_OscInitStruct->PLL.PLLR << RCC_PLLCFGR_PLLR_Pos)));
  3315. /* Enable the main PLL. */
  3316. __HAL_RCC_PLL_ENABLE();
  3317. /* Get Start Tick*/
  3318. tickstart = HAL_GetTick();
  3319. /* Wait till PLL is ready */
  3320. while (__HAL_RCC_GET_FLAG(RCC_FLAG_PLLRDY) == RESET)
  3321. {
  3322. if ((HAL_GetTick() - tickstart) > PLL_TIMEOUT_VALUE)
  3323. {
  3324. return HAL_TIMEOUT;
  3325. }
  3326. }
  3327. }
  3328. else
  3329. {
  3330. /* Disable the main PLL. */
  3331. __HAL_RCC_PLL_DISABLE();
  3332. /* Get Start Tick*/
  3333. tickstart = HAL_GetTick();
  3334. /* Wait till PLL is ready */
  3335. while (__HAL_RCC_GET_FLAG(RCC_FLAG_PLLRDY) != RESET)
  3336. {
  3337. if ((HAL_GetTick() - tickstart) > PLL_TIMEOUT_VALUE)
  3338. {
  3339. return HAL_TIMEOUT;
  3340. }
  3341. }
  3342. }
  3343. }
  3344. else
  3345. {
  3346. /* Check if there is a request to disable the PLL used as System clock source */
  3347. if ((RCC_OscInitStruct->PLL.PLLState) == RCC_PLL_OFF)
  3348. {
  3349. return HAL_ERROR;
  3350. }
  3351. else
  3352. {
  3353. /* Do not return HAL_ERROR if request repeats the current configuration */
  3354. pll_config = RCC->PLLCFGR;
  3355. #if defined (RCC_PLLCFGR_PLLR)
  3356. if (((RCC_OscInitStruct->PLL.PLLState) == RCC_PLL_OFF) ||
  3357. (READ_BIT(pll_config, RCC_PLLCFGR_PLLSRC) != RCC_OscInitStruct->PLL.PLLSource) ||
  3358. (READ_BIT(pll_config, RCC_PLLCFGR_PLLM) != (RCC_OscInitStruct->PLL.PLLM) << RCC_PLLCFGR_PLLM_Pos) ||
  3359. (READ_BIT(pll_config, RCC_PLLCFGR_PLLN) != (RCC_OscInitStruct->PLL.PLLN) << RCC_PLLCFGR_PLLN_Pos) ||
  3360. (READ_BIT(pll_config, RCC_PLLCFGR_PLLP) != (((RCC_OscInitStruct->PLL.PLLP >> 1U) - 1U)) << RCC_PLLCFGR_PLLP_Pos) ||
  3361. (READ_BIT(pll_config, RCC_PLLCFGR_PLLQ) != (RCC_OscInitStruct->PLL.PLLQ << RCC_PLLCFGR_PLLQ_Pos)) ||
  3362. (READ_BIT(pll_config, RCC_PLLCFGR_PLLR) != (RCC_OscInitStruct->PLL.PLLR << RCC_PLLCFGR_PLLR_Pos)))
  3363. #else
  3364. if (((RCC_OscInitStruct->PLL.PLLState) == RCC_PLL_OFF) ||
  3365. (READ_BIT(pll_config, RCC_PLLCFGR_PLLSRC) != RCC_OscInitStruct->PLL.PLLSource) ||
  3366. (READ_BIT(pll_config, RCC_PLLCFGR_PLLM) != (RCC_OscInitStruct->PLL.PLLM) << RCC_PLLCFGR_PLLM_Pos) ||
  3367. (READ_BIT(pll_config, RCC_PLLCFGR_PLLN) != (RCC_OscInitStruct->PLL.PLLN) << RCC_PLLCFGR_PLLN_Pos) ||
  3368. (READ_BIT(pll_config, RCC_PLLCFGR_PLLP) != (((RCC_OscInitStruct->PLL.PLLP >> 1U) - 1U)) << RCC_PLLCFGR_PLLP_Pos) ||
  3369. (READ_BIT(pll_config, RCC_PLLCFGR_PLLQ) != (RCC_OscInitStruct->PLL.PLLQ << RCC_PLLCFGR_PLLQ_Pos)))
  3370. #endif /* RCC_PLLCFGR_PLLR */
  3371. {
  3372. return HAL_ERROR;
  3373. }
  3374. }
  3375. }
  3376. }
  3377. return HAL_OK;
  3378. }
  3379. /**
  3380. * @brief Configures the RCC_OscInitStruct according to the internal
  3381. * RCC configuration registers.
  3382. * @param RCC_OscInitStruct pointer to an RCC_OscInitTypeDef structure that will be configured.
  3383. *
  3384. * @note This function is only available in case of STM32F410xx/STM32F446xx/STM32F469xx/STM32F479xx/STM32F412Zx/STM32F412Vx/STM32F412Rx/STM32F412Cx devices.
  3385. * @note This function add the PLL/PLLR factor management
  3386. * @retval None
  3387. */
  3388. void HAL_RCC_GetOscConfig(RCC_OscInitTypeDef *RCC_OscInitStruct)
  3389. {
  3390. /* Set all possible values for the Oscillator type parameter ---------------*/
  3391. RCC_OscInitStruct->OscillatorType = RCC_OSCILLATORTYPE_HSE | RCC_OSCILLATORTYPE_HSI | RCC_OSCILLATORTYPE_LSE | RCC_OSCILLATORTYPE_LSI;
  3392. /* Get the HSE configuration -----------------------------------------------*/
  3393. if ((RCC->CR & RCC_CR_HSEBYP) == RCC_CR_HSEBYP)
  3394. {
  3395. RCC_OscInitStruct->HSEState = RCC_HSE_BYPASS;
  3396. }
  3397. else if ((RCC->CR & RCC_CR_HSEON) == RCC_CR_HSEON)
  3398. {
  3399. RCC_OscInitStruct->HSEState = RCC_HSE_ON;
  3400. }
  3401. else
  3402. {
  3403. RCC_OscInitStruct->HSEState = RCC_HSE_OFF;
  3404. }
  3405. /* Get the HSI configuration -----------------------------------------------*/
  3406. if ((RCC->CR & RCC_CR_HSION) == RCC_CR_HSION)
  3407. {
  3408. RCC_OscInitStruct->HSIState = RCC_HSI_ON;
  3409. }
  3410. else
  3411. {
  3412. RCC_OscInitStruct->HSIState = RCC_HSI_OFF;
  3413. }
  3414. RCC_OscInitStruct->HSICalibrationValue = (uint32_t)((RCC->CR & RCC_CR_HSITRIM) >> RCC_CR_HSITRIM_Pos);
  3415. /* Get the LSE configuration -----------------------------------------------*/
  3416. if ((RCC->BDCR & RCC_BDCR_LSEBYP) == RCC_BDCR_LSEBYP)
  3417. {
  3418. RCC_OscInitStruct->LSEState = RCC_LSE_BYPASS;
  3419. }
  3420. else if ((RCC->BDCR & RCC_BDCR_LSEON) == RCC_BDCR_LSEON)
  3421. {
  3422. RCC_OscInitStruct->LSEState = RCC_LSE_ON;
  3423. }
  3424. else
  3425. {
  3426. RCC_OscInitStruct->LSEState = RCC_LSE_OFF;
  3427. }
  3428. /* Get the LSI configuration -----------------------------------------------*/
  3429. if ((RCC->CSR & RCC_CSR_LSION) == RCC_CSR_LSION)
  3430. {
  3431. RCC_OscInitStruct->LSIState = RCC_LSI_ON;
  3432. }
  3433. else
  3434. {
  3435. RCC_OscInitStruct->LSIState = RCC_LSI_OFF;
  3436. }
  3437. /* Get the PLL configuration -----------------------------------------------*/
  3438. if ((RCC->CR & RCC_CR_PLLON) == RCC_CR_PLLON)
  3439. {
  3440. RCC_OscInitStruct->PLL.PLLState = RCC_PLL_ON;
  3441. }
  3442. else
  3443. {
  3444. RCC_OscInitStruct->PLL.PLLState = RCC_PLL_OFF;
  3445. }
  3446. RCC_OscInitStruct->PLL.PLLSource = (uint32_t)(RCC->PLLCFGR & RCC_PLLCFGR_PLLSRC);
  3447. RCC_OscInitStruct->PLL.PLLM = (uint32_t)(RCC->PLLCFGR & RCC_PLLCFGR_PLLM);
  3448. RCC_OscInitStruct->PLL.PLLN = (uint32_t)((RCC->PLLCFGR & RCC_PLLCFGR_PLLN) >> RCC_PLLCFGR_PLLN_Pos);
  3449. RCC_OscInitStruct->PLL.PLLP = (uint32_t)((((RCC->PLLCFGR & RCC_PLLCFGR_PLLP) + RCC_PLLCFGR_PLLP_0) << 1U) >> RCC_PLLCFGR_PLLP_Pos);
  3450. RCC_OscInitStruct->PLL.PLLQ = (uint32_t)((RCC->PLLCFGR & RCC_PLLCFGR_PLLQ) >> RCC_PLLCFGR_PLLQ_Pos);
  3451. RCC_OscInitStruct->PLL.PLLR = (uint32_t)((RCC->PLLCFGR & RCC_PLLCFGR_PLLR) >> RCC_PLLCFGR_PLLR_Pos);
  3452. }
  3453. #endif /* STM32F410xx || STM32F446xx || STM32F469xx || STM32F479xx || STM32F412Zx || STM32F412Vx || STM32F412Rx || STM32F412Cx || STM32F413xx || STM32F423xx */
  3454. #endif /* HAL_RCC_MODULE_ENABLED */
  3455. /**
  3456. * @}
  3457. */
  3458. /**
  3459. * @}
  3460. */