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.
 
 
 

1603 lines
69 KiB

  1. /**
  2. ******************************************************************************
  3. * @file stm32f7xx_hal_rcc_ex.c
  4. * @author MCD Application Team
  5. * @version V1.2.2
  6. * @date 14-April-2017
  7. * @brief Extension RCC HAL module driver.
  8. * This file provides firmware functions to manage the following
  9. * functionalities RCC extension peripheral:
  10. * + Extended Peripheral Control functions
  11. *
  12. ******************************************************************************
  13. * @attention
  14. *
  15. * <h2><center>&copy; COPYRIGHT(c) 2017 STMicroelectronics</center></h2>
  16. *
  17. * Redistribution and use in source and binary forms, with or without modification,
  18. * are permitted provided that the following conditions are met:
  19. * 1. Redistributions of source code must retain the above copyright notice,
  20. * this list of conditions and the following disclaimer.
  21. * 2. Redistributions in binary form must reproduce the above copyright notice,
  22. * this list of conditions and the following disclaimer in the documentation
  23. * and/or other materials provided with the distribution.
  24. * 3. Neither the name of STMicroelectronics nor the names of its contributors
  25. * may be used to endorse or promote products derived from this software
  26. * without specific prior written permission.
  27. *
  28. * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
  29. * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  30. * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  31. * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
  32. * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
  33. * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
  34. * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
  35. * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
  36. * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
  37. * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  38. *
  39. ******************************************************************************
  40. */
  41. /* Includes ------------------------------------------------------------------*/
  42. #include "stm32f7xx_hal.h"
  43. /** @addtogroup STM32F7xx_HAL_Driver
  44. * @{
  45. */
  46. /** @defgroup RCCEx RCCEx
  47. * @brief RCCEx HAL module driver
  48. * @{
  49. */
  50. #ifdef HAL_RCC_MODULE_ENABLED
  51. /* Private typedef -----------------------------------------------------------*/
  52. /* Private define ------------------------------------------------------------*/
  53. /** @defgroup RCCEx_Private_Defines RCCEx Private Defines
  54. * @{
  55. */
  56. #define PLLI2S_TIMEOUT_VALUE 100 /* Timeout value fixed to 100 ms */
  57. #define PLLSAI_TIMEOUT_VALUE 100 /* Timeout value fixed to 100 ms */
  58. /**
  59. * @}
  60. */
  61. /* Private macro -------------------------------------------------------------*/
  62. /** @defgroup RCCEx_Private_Macros RCCEx Private Macros
  63. * @{
  64. */
  65. /**
  66. * @}
  67. */
  68. /** @defgroup RCCEx_Private_Macros RCCEx Private Macros
  69. * @{
  70. */
  71. /**
  72. * @}
  73. */
  74. /* Private variables ---------------------------------------------------------*/
  75. /* Private function prototypes -----------------------------------------------*/
  76. /* Private functions ---------------------------------------------------------*/
  77. /** @defgroup RCCEx_Exported_Functions RCCEx Exported Functions
  78. * @{
  79. */
  80. /** @defgroup RCCEx_Exported_Functions_Group1 Extended Peripheral Control functions
  81. * @brief Extended Peripheral Control functions
  82. *
  83. @verbatim
  84. ===============================================================================
  85. ##### Extended Peripheral Control functions #####
  86. ===============================================================================
  87. [..]
  88. This subsection provides a set of functions allowing to control the RCC Clocks
  89. frequencies.
  90. [..]
  91. (@) Important note: Care must be taken when HAL_RCCEx_PeriphCLKConfig() is used to
  92. select the RTC clock source; in this case the Backup domain will be reset in
  93. order to modify the RTC Clock source, as consequence RTC registers (including
  94. the backup registers) and RCC_BDCR register will be set to their reset values.
  95. @endverbatim
  96. * @{
  97. */
  98. #if defined (STM32F745xx) || defined (STM32F746xx) || defined (STM32F756xx) || defined (STM32F765xx) || \
  99. defined (STM32F767xx) || defined (STM32F769xx) || defined (STM32F777xx) || defined (STM32F779xx)
  100. /**
  101. * @brief Initializes the RCC extended peripherals clocks according to the specified
  102. * parameters in the RCC_PeriphCLKInitTypeDef.
  103. * @param PeriphClkInit: pointer to an RCC_PeriphCLKInitTypeDef structure that
  104. * contains the configuration information for the Extended Peripherals
  105. * clocks(I2S, SAI, LTDC, RTC, TIM, UARTs, USARTs, LTPIM, SDMMC...).
  106. *
  107. * @note Care must be taken when HAL_RCCEx_PeriphCLKConfig() is used to select
  108. * the RTC clock source; in this case the Backup domain will be reset in
  109. * order to modify the RTC Clock source, as consequence RTC registers (including
  110. * the backup registers) are set to their reset values.
  111. *
  112. * @retval HAL status
  113. */
  114. HAL_StatusTypeDef HAL_RCCEx_PeriphCLKConfig(RCC_PeriphCLKInitTypeDef *PeriphClkInit)
  115. {
  116. uint32_t tickstart = 0;
  117. uint32_t tmpreg0 = 0;
  118. uint32_t tmpreg1 = 0;
  119. uint32_t plli2sused = 0;
  120. uint32_t pllsaiused = 0;
  121. /* Check the parameters */
  122. assert_param(IS_RCC_PERIPHCLOCK(PeriphClkInit->PeriphClockSelection));
  123. /*----------------------------------- I2S configuration ----------------------------------*/
  124. if(((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_I2S) == (RCC_PERIPHCLK_I2S))
  125. {
  126. /* Check the parameters */
  127. assert_param(IS_RCC_I2SCLKSOURCE(PeriphClkInit->I2sClockSelection));
  128. /* Configure I2S Clock source */
  129. __HAL_RCC_I2S_CONFIG(PeriphClkInit->I2sClockSelection);
  130. /* Enable the PLLI2S when it's used as clock source for I2S */
  131. if(PeriphClkInit->I2sClockSelection == RCC_I2SCLKSOURCE_PLLI2S)
  132. {
  133. plli2sused = 1;
  134. }
  135. }
  136. /*------------------------------------ SAI1 configuration --------------------------------------*/
  137. if(((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_SAI1) == (RCC_PERIPHCLK_SAI1))
  138. {
  139. /* Check the parameters */
  140. assert_param(IS_RCC_SAI1CLKSOURCE(PeriphClkInit->Sai1ClockSelection));
  141. /* Configure SAI1 Clock source */
  142. __HAL_RCC_SAI1_CONFIG(PeriphClkInit->Sai1ClockSelection);
  143. /* Enable the PLLI2S when it's used as clock source for SAI */
  144. if(PeriphClkInit->Sai1ClockSelection == RCC_SAI1CLKSOURCE_PLLI2S)
  145. {
  146. plli2sused = 1;
  147. }
  148. /* Enable the PLLSAI when it's used as clock source for SAI */
  149. if(PeriphClkInit->Sai1ClockSelection == RCC_SAI1CLKSOURCE_PLLSAI)
  150. {
  151. pllsaiused = 1;
  152. }
  153. }
  154. /*------------------------------------ SAI2 configuration --------------------------------------*/
  155. if(((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_SAI2) == (RCC_PERIPHCLK_SAI2))
  156. {
  157. /* Check the parameters */
  158. assert_param(IS_RCC_SAI2CLKSOURCE(PeriphClkInit->Sai2ClockSelection));
  159. /* Configure SAI2 Clock source */
  160. __HAL_RCC_SAI2_CONFIG(PeriphClkInit->Sai2ClockSelection);
  161. /* Enable the PLLI2S when it's used as clock source for SAI */
  162. if(PeriphClkInit->Sai2ClockSelection == RCC_SAI2CLKSOURCE_PLLI2S)
  163. {
  164. plli2sused = 1;
  165. }
  166. /* Enable the PLLSAI when it's used as clock source for SAI */
  167. if(PeriphClkInit->Sai2ClockSelection == RCC_SAI2CLKSOURCE_PLLSAI)
  168. {
  169. pllsaiused = 1;
  170. }
  171. }
  172. /*-------------------------------------- SPDIF-RX Configuration -----------------------------------*/
  173. if(((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_SPDIFRX) == RCC_PERIPHCLK_SPDIFRX)
  174. {
  175. plli2sused = 1;
  176. }
  177. /*------------------------------------ RTC configuration --------------------------------------*/
  178. if(((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_RTC) == (RCC_PERIPHCLK_RTC))
  179. {
  180. /* Check for RTC Parameters used to output RTCCLK */
  181. assert_param(IS_RCC_RTCCLKSOURCE(PeriphClkInit->RTCClockSelection));
  182. /* Enable Power Clock*/
  183. __HAL_RCC_PWR_CLK_ENABLE();
  184. /* Enable write access to Backup domain */
  185. PWR->CR1 |= PWR_CR1_DBP;
  186. /* Get Start Tick*/
  187. tickstart = HAL_GetTick();
  188. /* Wait for Backup domain Write protection disable */
  189. while((PWR->CR1 & PWR_CR1_DBP) == RESET)
  190. {
  191. if((HAL_GetTick() - tickstart) > RCC_DBP_TIMEOUT_VALUE)
  192. {
  193. return HAL_TIMEOUT;
  194. }
  195. }
  196. /* Reset the Backup domain only if the RTC Clock source selection is modified */
  197. tmpreg0 = (RCC->BDCR & RCC_BDCR_RTCSEL);
  198. if((tmpreg0 != 0x00000000U) && (tmpreg0 != (PeriphClkInit->RTCClockSelection & RCC_BDCR_RTCSEL)))
  199. {
  200. /* Store the content of BDCR register before the reset of Backup Domain */
  201. tmpreg0 = (RCC->BDCR & ~(RCC_BDCR_RTCSEL));
  202. /* RTC Clock selection can be changed only if the Backup Domain is reset */
  203. __HAL_RCC_BACKUPRESET_FORCE();
  204. __HAL_RCC_BACKUPRESET_RELEASE();
  205. /* Restore the Content of BDCR register */
  206. RCC->BDCR = tmpreg0;
  207. /* Wait for LSE reactivation if LSE was enable prior to Backup Domain reset */
  208. if (HAL_IS_BIT_SET(RCC->BDCR, RCC_BDCR_LSEON))
  209. {
  210. /* Get Start Tick*/
  211. tickstart = HAL_GetTick();
  212. /* Wait till LSE is ready */
  213. while(__HAL_RCC_GET_FLAG(RCC_FLAG_LSERDY) == RESET)
  214. {
  215. if((HAL_GetTick() - tickstart ) > RCC_LSE_TIMEOUT_VALUE)
  216. {
  217. return HAL_TIMEOUT;
  218. }
  219. }
  220. }
  221. }
  222. __HAL_RCC_RTC_CONFIG(PeriphClkInit->RTCClockSelection);
  223. }
  224. /*------------------------------------ TIM configuration --------------------------------------*/
  225. if(((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_TIM) == (RCC_PERIPHCLK_TIM))
  226. {
  227. /* Check the parameters */
  228. assert_param(IS_RCC_TIMPRES(PeriphClkInit->TIMPresSelection));
  229. /* Configure Timer Prescaler */
  230. __HAL_RCC_TIMCLKPRESCALER(PeriphClkInit->TIMPresSelection);
  231. }
  232. /*-------------------------------------- I2C1 Configuration -----------------------------------*/
  233. if(((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_I2C1) == RCC_PERIPHCLK_I2C1)
  234. {
  235. /* Check the parameters */
  236. assert_param(IS_RCC_I2C1CLKSOURCE(PeriphClkInit->I2c1ClockSelection));
  237. /* Configure the I2C1 clock source */
  238. __HAL_RCC_I2C1_CONFIG(PeriphClkInit->I2c1ClockSelection);
  239. }
  240. /*-------------------------------------- I2C2 Configuration -----------------------------------*/
  241. if(((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_I2C2) == RCC_PERIPHCLK_I2C2)
  242. {
  243. /* Check the parameters */
  244. assert_param(IS_RCC_I2C2CLKSOURCE(PeriphClkInit->I2c2ClockSelection));
  245. /* Configure the I2C2 clock source */
  246. __HAL_RCC_I2C2_CONFIG(PeriphClkInit->I2c2ClockSelection);
  247. }
  248. /*-------------------------------------- I2C3 Configuration -----------------------------------*/
  249. if(((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_I2C3) == RCC_PERIPHCLK_I2C3)
  250. {
  251. /* Check the parameters */
  252. assert_param(IS_RCC_I2C3CLKSOURCE(PeriphClkInit->I2c3ClockSelection));
  253. /* Configure the I2C3 clock source */
  254. __HAL_RCC_I2C3_CONFIG(PeriphClkInit->I2c3ClockSelection);
  255. }
  256. /*-------------------------------------- I2C4 Configuration -----------------------------------*/
  257. if(((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_I2C4) == RCC_PERIPHCLK_I2C4)
  258. {
  259. /* Check the parameters */
  260. assert_param(IS_RCC_I2C4CLKSOURCE(PeriphClkInit->I2c4ClockSelection));
  261. /* Configure the I2C4 clock source */
  262. __HAL_RCC_I2C4_CONFIG(PeriphClkInit->I2c4ClockSelection);
  263. }
  264. /*-------------------------------------- USART1 Configuration -----------------------------------*/
  265. if(((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_USART1) == RCC_PERIPHCLK_USART1)
  266. {
  267. /* Check the parameters */
  268. assert_param(IS_RCC_USART1CLKSOURCE(PeriphClkInit->Usart1ClockSelection));
  269. /* Configure the USART1 clock source */
  270. __HAL_RCC_USART1_CONFIG(PeriphClkInit->Usart1ClockSelection);
  271. }
  272. /*-------------------------------------- USART2 Configuration -----------------------------------*/
  273. if(((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_USART2) == RCC_PERIPHCLK_USART2)
  274. {
  275. /* Check the parameters */
  276. assert_param(IS_RCC_USART2CLKSOURCE(PeriphClkInit->Usart2ClockSelection));
  277. /* Configure the USART2 clock source */
  278. __HAL_RCC_USART2_CONFIG(PeriphClkInit->Usart2ClockSelection);
  279. }
  280. /*-------------------------------------- USART3 Configuration -----------------------------------*/
  281. if(((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_USART3) == RCC_PERIPHCLK_USART3)
  282. {
  283. /* Check the parameters */
  284. assert_param(IS_RCC_USART3CLKSOURCE(PeriphClkInit->Usart3ClockSelection));
  285. /* Configure the USART3 clock source */
  286. __HAL_RCC_USART3_CONFIG(PeriphClkInit->Usart3ClockSelection);
  287. }
  288. /*-------------------------------------- UART4 Configuration -----------------------------------*/
  289. if(((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_UART4) == RCC_PERIPHCLK_UART4)
  290. {
  291. /* Check the parameters */
  292. assert_param(IS_RCC_UART4CLKSOURCE(PeriphClkInit->Uart4ClockSelection));
  293. /* Configure the UART4 clock source */
  294. __HAL_RCC_UART4_CONFIG(PeriphClkInit->Uart4ClockSelection);
  295. }
  296. /*-------------------------------------- UART5 Configuration -----------------------------------*/
  297. if(((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_UART5) == RCC_PERIPHCLK_UART5)
  298. {
  299. /* Check the parameters */
  300. assert_param(IS_RCC_UART5CLKSOURCE(PeriphClkInit->Uart5ClockSelection));
  301. /* Configure the UART5 clock source */
  302. __HAL_RCC_UART5_CONFIG(PeriphClkInit->Uart5ClockSelection);
  303. }
  304. /*-------------------------------------- USART6 Configuration -----------------------------------*/
  305. if(((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_USART6) == RCC_PERIPHCLK_USART6)
  306. {
  307. /* Check the parameters */
  308. assert_param(IS_RCC_USART6CLKSOURCE(PeriphClkInit->Usart6ClockSelection));
  309. /* Configure the USART6 clock source */
  310. __HAL_RCC_USART6_CONFIG(PeriphClkInit->Usart6ClockSelection);
  311. }
  312. /*-------------------------------------- UART7 Configuration -----------------------------------*/
  313. if(((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_UART7) == RCC_PERIPHCLK_UART7)
  314. {
  315. /* Check the parameters */
  316. assert_param(IS_RCC_UART7CLKSOURCE(PeriphClkInit->Uart7ClockSelection));
  317. /* Configure the UART7 clock source */
  318. __HAL_RCC_UART7_CONFIG(PeriphClkInit->Uart7ClockSelection);
  319. }
  320. /*-------------------------------------- UART8 Configuration -----------------------------------*/
  321. if(((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_UART8) == RCC_PERIPHCLK_UART8)
  322. {
  323. /* Check the parameters */
  324. assert_param(IS_RCC_UART8CLKSOURCE(PeriphClkInit->Uart8ClockSelection));
  325. /* Configure the UART8 clock source */
  326. __HAL_RCC_UART8_CONFIG(PeriphClkInit->Uart8ClockSelection);
  327. }
  328. /*--------------------------------------- CEC Configuration -----------------------------------*/
  329. if(((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_CEC) == RCC_PERIPHCLK_CEC)
  330. {
  331. /* Check the parameters */
  332. assert_param(IS_RCC_CECCLKSOURCE(PeriphClkInit->CecClockSelection));
  333. /* Configure the CEC clock source */
  334. __HAL_RCC_CEC_CONFIG(PeriphClkInit->CecClockSelection);
  335. }
  336. /*-------------------------------------- CK48 Configuration -----------------------------------*/
  337. if(((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_CLK48) == RCC_PERIPHCLK_CLK48)
  338. {
  339. /* Check the parameters */
  340. assert_param(IS_RCC_CLK48SOURCE(PeriphClkInit->Clk48ClockSelection));
  341. /* Configure the CLK48 source */
  342. __HAL_RCC_CLK48_CONFIG(PeriphClkInit->Clk48ClockSelection);
  343. /* Enable the PLLSAI when it's used as clock source for CK48 */
  344. if(PeriphClkInit->Clk48ClockSelection == RCC_CLK48SOURCE_PLLSAIP)
  345. {
  346. pllsaiused = 1;
  347. }
  348. }
  349. /*-------------------------------------- LTDC Configuration -----------------------------------*/
  350. #if defined(STM32F746xx) || defined(STM32F756xx) || defined (STM32F767xx) || defined (STM32F769xx) || defined (STM32F777xx) || defined (STM32F779xx)
  351. if(((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_LTDC) == RCC_PERIPHCLK_LTDC)
  352. {
  353. pllsaiused = 1;
  354. }
  355. #endif /* STM32F746xx || STM32F756xx || STM32F767xx || STM32F769xx || STM32F777xx || STM32F779xx */
  356. /*-------------------------------------- LPTIM1 Configuration -----------------------------------*/
  357. if(((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_LPTIM1) == RCC_PERIPHCLK_LPTIM1)
  358. {
  359. /* Check the parameters */
  360. assert_param(IS_RCC_LPTIM1CLK(PeriphClkInit->Lptim1ClockSelection));
  361. /* Configure the LTPIM1 clock source */
  362. __HAL_RCC_LPTIM1_CONFIG(PeriphClkInit->Lptim1ClockSelection);
  363. }
  364. /*------------------------------------- SDMMC1 Configuration ------------------------------------*/
  365. if(((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_SDMMC1) == RCC_PERIPHCLK_SDMMC1)
  366. {
  367. /* Check the parameters */
  368. assert_param(IS_RCC_SDMMC1CLKSOURCE(PeriphClkInit->Sdmmc1ClockSelection));
  369. /* Configure the SDMMC1 clock source */
  370. __HAL_RCC_SDMMC1_CONFIG(PeriphClkInit->Sdmmc1ClockSelection);
  371. }
  372. #if defined (STM32F765xx) || defined (STM32F767xx) || defined (STM32F769xx) || defined (STM32F777xx) || defined (STM32F779xx)
  373. /*------------------------------------- SDMMC2 Configuration ------------------------------------*/
  374. if(((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_SDMMC2) == RCC_PERIPHCLK_SDMMC2)
  375. {
  376. /* Check the parameters */
  377. assert_param(IS_RCC_SDMMC2CLKSOURCE(PeriphClkInit->Sdmmc2ClockSelection));
  378. /* Configure the SDMMC2 clock source */
  379. __HAL_RCC_SDMMC2_CONFIG(PeriphClkInit->Sdmmc2ClockSelection);
  380. }
  381. /*------------------------------------- DFSDM1 Configuration -------------------------------------*/
  382. if(((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_DFSDM1) == RCC_PERIPHCLK_DFSDM1)
  383. {
  384. /* Check the parameters */
  385. assert_param(IS_RCC_DFSDM1CLKSOURCE(PeriphClkInit->Dfsdm1ClockSelection));
  386. /* Configure the DFSDM1 interface clock source */
  387. __HAL_RCC_DFSDM1_CONFIG(PeriphClkInit->Dfsdm1ClockSelection);
  388. }
  389. /*------------------------------------- DFSDM AUDIO Configuration -------------------------------------*/
  390. if(((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_DFSDM1_AUDIO) == RCC_PERIPHCLK_DFSDM1_AUDIO)
  391. {
  392. /* Check the parameters */
  393. assert_param(IS_RCC_DFSDM1AUDIOCLKSOURCE(PeriphClkInit->Dfsdm1AudioClockSelection));
  394. /* Configure the DFSDM interface clock source */
  395. __HAL_RCC_DFSDM1AUDIO_CONFIG(PeriphClkInit->Dfsdm1AudioClockSelection);
  396. }
  397. #endif /* STM32F767xx || STM32F769xx || STM32F777xx || STM32F779xx */
  398. /*-------------------------------------- PLLI2S Configuration ---------------------------------*/
  399. /* PLLI2S is configured when a peripheral will use it as source clock : SAI1, SAI2, I2S or SPDIF-RX */
  400. if((plli2sused == 1) || (PeriphClkInit->PeriphClockSelection == RCC_PERIPHCLK_PLLI2S))
  401. {
  402. /* Disable the PLLI2S */
  403. __HAL_RCC_PLLI2S_DISABLE();
  404. /* Get Start Tick*/
  405. tickstart = HAL_GetTick();
  406. /* Wait till PLLI2S is disabled */
  407. while(__HAL_RCC_GET_FLAG(RCC_FLAG_PLLI2SRDY) != RESET)
  408. {
  409. if((HAL_GetTick() - tickstart) > PLLI2S_TIMEOUT_VALUE)
  410. {
  411. /* return in case of Timeout detected */
  412. return HAL_TIMEOUT;
  413. }
  414. }
  415. /* check for common PLLI2S Parameters */
  416. assert_param(IS_RCC_PLLI2SN_VALUE(PeriphClkInit->PLLI2S.PLLI2SN));
  417. /*----------------- In Case of PLLI2S is selected as source clock for I2S -------------------*/
  418. if(((((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_I2S) == RCC_PERIPHCLK_I2S) && (PeriphClkInit->I2sClockSelection == RCC_I2SCLKSOURCE_PLLI2S)))
  419. {
  420. /* check for Parameters */
  421. assert_param(IS_RCC_PLLI2SR_VALUE(PeriphClkInit->PLLI2S.PLLI2SR));
  422. /* Read PLLI2SP and PLLI2SQ value from PLLI2SCFGR register (this value is not needed for I2S configuration) */
  423. tmpreg0 = ((RCC->PLLI2SCFGR & RCC_PLLI2SCFGR_PLLI2SP) >> POSITION_VAL(RCC_PLLI2SCFGR_PLLI2SP));
  424. tmpreg1 = ((RCC->PLLI2SCFGR & RCC_PLLI2SCFGR_PLLI2SQ) >> POSITION_VAL(RCC_PLLI2SCFGR_PLLI2SQ));
  425. /* Configure the PLLI2S division factors */
  426. /* PLLI2S_VCO = f(VCO clock) = f(PLLI2S clock input) x (PLLI2SN/PLLM) */
  427. /* I2SCLK = f(PLLI2S clock output) = f(VCO clock) / PLLI2SR */
  428. __HAL_RCC_PLLI2S_CONFIG(PeriphClkInit->PLLI2S.PLLI2SN , tmpreg0, tmpreg1, PeriphClkInit->PLLI2S.PLLI2SR);
  429. }
  430. /*----------------- In Case of PLLI2S is selected as source clock for SAI -------------------*/
  431. if(((((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_SAI1) == RCC_PERIPHCLK_SAI1) && (PeriphClkInit->Sai1ClockSelection == RCC_SAI1CLKSOURCE_PLLI2S)) ||
  432. ((((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_SAI2) == RCC_PERIPHCLK_SAI2) && (PeriphClkInit->Sai2ClockSelection == RCC_SAI2CLKSOURCE_PLLI2S)))
  433. {
  434. /* Check for PLLI2S Parameters */
  435. assert_param(IS_RCC_PLLI2SQ_VALUE(PeriphClkInit->PLLI2S.PLLI2SQ));
  436. /* Check for PLLI2S/DIVQ parameters */
  437. assert_param(IS_RCC_PLLI2S_DIVQ_VALUE(PeriphClkInit->PLLI2SDivQ));
  438. /* Read PLLI2SP and PLLI2SR values from PLLI2SCFGR register (this value is not needed for SAI configuration) */
  439. tmpreg0 = ((RCC->PLLI2SCFGR & RCC_PLLI2SCFGR_PLLI2SP) >> POSITION_VAL(RCC_PLLI2SCFGR_PLLI2SP));
  440. tmpreg1 = ((RCC->PLLI2SCFGR & RCC_PLLI2SCFGR_PLLI2SR) >> POSITION_VAL(RCC_PLLI2SCFGR_PLLI2SR));
  441. /* Configure the PLLI2S division factors */
  442. /* PLLI2S_VCO Input = PLL_SOURCE/PLLM */
  443. /* PLLI2S_VCO Output = PLLI2S_VCO Input * PLLI2SN */
  444. /* SAI_CLK(first level) = PLLI2S_VCO Output/PLLI2SQ */
  445. __HAL_RCC_PLLI2S_CONFIG(PeriphClkInit->PLLI2S.PLLI2SN, tmpreg0, PeriphClkInit->PLLI2S.PLLI2SQ, tmpreg1);
  446. /* SAI_CLK_x = SAI_CLK(first level)/PLLI2SDIVQ */
  447. __HAL_RCC_PLLI2S_PLLSAICLKDIVQ_CONFIG(PeriphClkInit->PLLI2SDivQ);
  448. }
  449. /*----------------- In Case of PLLI2S is selected as source clock for SPDIF-RX -------------------*/
  450. if(((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_SPDIFRX) == RCC_PERIPHCLK_SPDIFRX)
  451. {
  452. /* check for Parameters */
  453. assert_param(IS_RCC_PLLI2SP_VALUE(PeriphClkInit->PLLI2S.PLLI2SP));
  454. /* Read PLLI2SR value from PLLI2SCFGR register (this value is not needed for SPDIF-RX configuration) */
  455. tmpreg0 = ((RCC->PLLI2SCFGR & RCC_PLLI2SCFGR_PLLI2SQ) >> POSITION_VAL(RCC_PLLI2SCFGR_PLLI2SQ));
  456. tmpreg1 = ((RCC->PLLI2SCFGR & RCC_PLLI2SCFGR_PLLI2SR) >> POSITION_VAL(RCC_PLLI2SCFGR_PLLI2SR));
  457. /* Configure the PLLI2S division factors */
  458. /* PLLI2S_VCO = f(VCO clock) = f(PLLI2S clock input) x (PLLI2SN/PLLM) */
  459. /* SPDIFCLK = f(PLLI2S clock output) = f(VCO clock) / PLLI2SP */
  460. __HAL_RCC_PLLI2S_CONFIG(PeriphClkInit->PLLI2S.PLLI2SN , PeriphClkInit->PLLI2S.PLLI2SP, tmpreg0, tmpreg1);
  461. }
  462. /*----------------- In Case of PLLI2S is just selected -----------------*/
  463. if((PeriphClkInit->PeriphClockSelection & RCC_PERIPHCLK_PLLI2S) == RCC_PERIPHCLK_PLLI2S)
  464. {
  465. /* Check for Parameters */
  466. assert_param(IS_RCC_PLLI2SP_VALUE(PeriphClkInit->PLLI2S.PLLI2SP));
  467. assert_param(IS_RCC_PLLI2SR_VALUE(PeriphClkInit->PLLI2S.PLLI2SR));
  468. assert_param(IS_RCC_PLLI2SQ_VALUE(PeriphClkInit->PLLI2S.PLLI2SQ));
  469. /* Configure the PLLI2S division factors */
  470. /* PLLI2S_VCO = f(VCO clock) = f(PLLI2S clock input) x (PLLI2SN/PLLI2SM) */
  471. /* SPDIFRXCLK = f(PLLI2S clock output) = f(VCO clock) / PLLI2SP */
  472. __HAL_RCC_PLLI2S_CONFIG(PeriphClkInit->PLLI2S.PLLI2SN , PeriphClkInit->PLLI2S.PLLI2SP, PeriphClkInit->PLLI2S.PLLI2SQ, PeriphClkInit->PLLI2S.PLLI2SR);
  473. }
  474. /* Enable the PLLI2S */
  475. __HAL_RCC_PLLI2S_ENABLE();
  476. /* Get Start Tick*/
  477. tickstart = HAL_GetTick();
  478. /* Wait till PLLI2S is ready */
  479. while(__HAL_RCC_GET_FLAG(RCC_FLAG_PLLI2SRDY) == RESET)
  480. {
  481. if((HAL_GetTick() - tickstart) > PLLI2S_TIMEOUT_VALUE)
  482. {
  483. /* return in case of Timeout detected */
  484. return HAL_TIMEOUT;
  485. }
  486. }
  487. }
  488. /*-------------------------------------- PLLSAI Configuration ---------------------------------*/
  489. /* PLLSAI is configured when a peripheral will use it as source clock : SAI1, SAI2, LTDC or CK48 */
  490. if(pllsaiused == 1)
  491. {
  492. /* Disable PLLSAI Clock */
  493. __HAL_RCC_PLLSAI_DISABLE();
  494. /* Get Start Tick*/
  495. tickstart = HAL_GetTick();
  496. /* Wait till PLLSAI is disabled */
  497. while(__HAL_RCC_PLLSAI_GET_FLAG() != RESET)
  498. {
  499. if((HAL_GetTick() - tickstart) > PLLSAI_TIMEOUT_VALUE)
  500. {
  501. /* return in case of Timeout detected */
  502. return HAL_TIMEOUT;
  503. }
  504. }
  505. /* Check the PLLSAI division factors */
  506. assert_param(IS_RCC_PLLSAIN_VALUE(PeriphClkInit->PLLSAI.PLLSAIN));
  507. /*----------------- In Case of PLLSAI is selected as source clock for SAI -------------------*/
  508. if(((((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_SAI1) == RCC_PERIPHCLK_SAI1) && (PeriphClkInit->Sai1ClockSelection == RCC_SAI1CLKSOURCE_PLLSAI)) ||\
  509. ((((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_SAI2) == RCC_PERIPHCLK_SAI2) && (PeriphClkInit->Sai2ClockSelection == RCC_SAI2CLKSOURCE_PLLSAI)))
  510. {
  511. /* check for PLLSAIQ Parameter */
  512. assert_param(IS_RCC_PLLSAIQ_VALUE(PeriphClkInit->PLLSAI.PLLSAIQ));
  513. /* check for PLLSAI/DIVQ Parameter */
  514. assert_param(IS_RCC_PLLSAI_DIVQ_VALUE(PeriphClkInit->PLLSAIDivQ));
  515. /* Read PLLSAIP value from PLLSAICFGR register (this value is not needed for SAI configuration) */
  516. tmpreg0 = ((RCC->PLLSAICFGR & RCC_PLLSAICFGR_PLLSAIP) >> POSITION_VAL(RCC_PLLSAICFGR_PLLSAIP));
  517. tmpreg1 = ((RCC->PLLSAICFGR & RCC_PLLI2SCFGR_PLLI2SR) >> POSITION_VAL(RCC_PLLSAICFGR_PLLSAIR));
  518. /* PLLSAI_VCO Input = PLL_SOURCE/PLLM */
  519. /* PLLSAI_VCO Output = PLLSAI_VCO Input * PLLSAIN */
  520. /* SAI_CLK(first level) = PLLSAI_VCO Output/PLLSAIQ */
  521. __HAL_RCC_PLLSAI_CONFIG(PeriphClkInit->PLLSAI.PLLSAIN , tmpreg0, PeriphClkInit->PLLSAI.PLLSAIQ, tmpreg1);
  522. /* SAI_CLK_x = SAI_CLK(first level)/PLLSAIDIVQ */
  523. __HAL_RCC_PLLSAI_PLLSAICLKDIVQ_CONFIG(PeriphClkInit->PLLSAIDivQ);
  524. }
  525. /*----------------- In Case of PLLSAI is selected as source clock for CLK48 -------------------*/
  526. /* In Case of PLLI2S is selected as source clock for CK48 */
  527. if((((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_CLK48) == RCC_PERIPHCLK_CLK48) && (PeriphClkInit->Clk48ClockSelection == RCC_CLK48SOURCE_PLLSAIP))
  528. {
  529. /* check for Parameters */
  530. assert_param(IS_RCC_PLLSAIP_VALUE(PeriphClkInit->PLLSAI.PLLSAIP));
  531. /* Read PLLSAIQ and PLLSAIR value from PLLSAICFGR register (this value is not needed for CK48 configuration) */
  532. tmpreg0 = ((RCC->PLLSAICFGR & RCC_PLLSAICFGR_PLLSAIQ) >> POSITION_VAL(RCC_PLLSAICFGR_PLLSAIQ));
  533. tmpreg1 = ((RCC->PLLSAICFGR & RCC_PLLSAICFGR_PLLSAIR) >> POSITION_VAL(RCC_PLLSAICFGR_PLLSAIR));
  534. /* Configure the PLLSAI division factors */
  535. /* PLLSAI_VCO = f(VCO clock) = f(PLLSAI clock input) x (PLLI2SN/PLLM) */
  536. /* 48CLK = f(PLLSAI clock output) = f(VCO clock) / PLLSAIP */
  537. __HAL_RCC_PLLSAI_CONFIG(PeriphClkInit->PLLSAI.PLLSAIN , PeriphClkInit->PLLSAI.PLLSAIP, tmpreg0, tmpreg1);
  538. }
  539. #if defined(STM32F746xx) || defined(STM32F756xx) || defined (STM32F767xx) || defined (STM32F769xx) || defined (STM32F777xx) || defined (STM32F779xx)
  540. /*---------------------------- LTDC configuration -------------------------------*/
  541. if(((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_LTDC) == (RCC_PERIPHCLK_LTDC))
  542. {
  543. assert_param(IS_RCC_PLLSAIR_VALUE(PeriphClkInit->PLLSAI.PLLSAIR));
  544. assert_param(IS_RCC_PLLSAI_DIVR_VALUE(PeriphClkInit->PLLSAIDivR));
  545. /* Read PLLSAIP and PLLSAIQ value from PLLSAICFGR register (these value are not needed for LTDC configuration) */
  546. tmpreg0 = ((RCC->PLLSAICFGR & RCC_PLLSAICFGR_PLLSAIQ) >> POSITION_VAL(RCC_PLLSAICFGR_PLLSAIQ));
  547. tmpreg1 = ((RCC->PLLSAICFGR & RCC_PLLSAICFGR_PLLSAIP) >> POSITION_VAL(RCC_PLLSAICFGR_PLLSAIP));
  548. /* PLLSAI_VCO Input = PLL_SOURCE/PLLM */
  549. /* PLLSAI_VCO Output = PLLSAI_VCO Input * PLLSAIN */
  550. /* LTDC_CLK(first level) = PLLSAI_VCO Output/PLLSAIR */
  551. __HAL_RCC_PLLSAI_CONFIG(PeriphClkInit->PLLSAI.PLLSAIN , tmpreg1, tmpreg0, PeriphClkInit->PLLSAI.PLLSAIR);
  552. /* LTDC_CLK = LTDC_CLK(first level)/PLLSAIDIVR */
  553. __HAL_RCC_PLLSAI_PLLSAICLKDIVR_CONFIG(PeriphClkInit->PLLSAIDivR);
  554. }
  555. #endif /* STM32F746xx || STM32F756xx || STM32F767xx || STM32F769xx || STM32F777xx || STM32F779xx */
  556. /* Enable PLLSAI Clock */
  557. __HAL_RCC_PLLSAI_ENABLE();
  558. /* Get Start Tick*/
  559. tickstart = HAL_GetTick();
  560. /* Wait till PLLSAI is ready */
  561. while(__HAL_RCC_PLLSAI_GET_FLAG() == RESET)
  562. {
  563. if((HAL_GetTick() - tickstart) > PLLSAI_TIMEOUT_VALUE)
  564. {
  565. /* return in case of Timeout detected */
  566. return HAL_TIMEOUT;
  567. }
  568. }
  569. }
  570. return HAL_OK;
  571. }
  572. /**
  573. * @brief Get the RCC_PeriphCLKInitTypeDef according to the internal
  574. * RCC configuration registers.
  575. * @param PeriphClkInit: pointer to the configured RCC_PeriphCLKInitTypeDef structure
  576. * @retval None
  577. */
  578. void HAL_RCCEx_GetPeriphCLKConfig(RCC_PeriphCLKInitTypeDef *PeriphClkInit)
  579. {
  580. uint32_t tempreg = 0;
  581. /* Set all possible values for the extended clock type parameter------------*/
  582. #if defined (STM32F765xx) || defined (STM32F767xx) || defined (STM32F769xx) || defined (STM32F777xx) || defined (STM32F779xx)
  583. PeriphClkInit->PeriphClockSelection = RCC_PERIPHCLK_I2S | RCC_PERIPHCLK_LPTIM1 |\
  584. RCC_PERIPHCLK_SAI1 | RCC_PERIPHCLK_SAI2 |\
  585. RCC_PERIPHCLK_TIM | RCC_PERIPHCLK_RTC |\
  586. RCC_PERIPHCLK_CEC | RCC_PERIPHCLK_I2C4 |\
  587. RCC_PERIPHCLK_I2C1 | RCC_PERIPHCLK_I2C2 |\
  588. RCC_PERIPHCLK_I2C3 | RCC_PERIPHCLK_USART1 |\
  589. RCC_PERIPHCLK_USART2 | RCC_PERIPHCLK_USART3 |\
  590. RCC_PERIPHCLK_UART4 | RCC_PERIPHCLK_UART5 |\
  591. RCC_PERIPHCLK_USART6 | RCC_PERIPHCLK_UART7 |\
  592. RCC_PERIPHCLK_UART8 | RCC_PERIPHCLK_SDMMC1 |\
  593. RCC_PERIPHCLK_CLK48 | RCC_PERIPHCLK_SDMMC2 |\
  594. RCC_PERIPHCLK_DFSDM1 | RCC_PERIPHCLK_DFSDM1_AUDIO;
  595. #else
  596. PeriphClkInit->PeriphClockSelection = RCC_PERIPHCLK_I2S | RCC_PERIPHCLK_LPTIM1 |\
  597. RCC_PERIPHCLK_SAI1 | RCC_PERIPHCLK_SAI2 |\
  598. RCC_PERIPHCLK_TIM | RCC_PERIPHCLK_RTC |\
  599. RCC_PERIPHCLK_CEC | RCC_PERIPHCLK_I2C4 |\
  600. RCC_PERIPHCLK_I2C1 | RCC_PERIPHCLK_I2C2 |\
  601. RCC_PERIPHCLK_I2C3 | RCC_PERIPHCLK_USART1 |\
  602. RCC_PERIPHCLK_USART2 | RCC_PERIPHCLK_USART3 |\
  603. RCC_PERIPHCLK_UART4 | RCC_PERIPHCLK_UART5 |\
  604. RCC_PERIPHCLK_USART6 | RCC_PERIPHCLK_UART7 |\
  605. RCC_PERIPHCLK_UART8 | RCC_PERIPHCLK_SDMMC1 |\
  606. RCC_PERIPHCLK_CLK48;
  607. #endif /* STM32F767xx || STM32F769xx || STM32F777xx || STM32F779xx */
  608. /* Get the PLLI2S Clock configuration -----------------------------------------------*/
  609. PeriphClkInit->PLLI2S.PLLI2SN = (uint32_t)((RCC->PLLI2SCFGR & RCC_PLLI2SCFGR_PLLI2SN) >> POSITION_VAL(RCC_PLLI2SCFGR_PLLI2SN));
  610. PeriphClkInit->PLLI2S.PLLI2SP = (uint32_t)((RCC->PLLI2SCFGR & RCC_PLLI2SCFGR_PLLI2SP) >> POSITION_VAL(RCC_PLLI2SCFGR_PLLI2SP));
  611. PeriphClkInit->PLLI2S.PLLI2SQ = (uint32_t)((RCC->PLLI2SCFGR & RCC_PLLI2SCFGR_PLLI2SQ) >> POSITION_VAL(RCC_PLLI2SCFGR_PLLI2SQ));
  612. PeriphClkInit->PLLI2S.PLLI2SR = (uint32_t)((RCC->PLLI2SCFGR & RCC_PLLI2SCFGR_PLLI2SR) >> POSITION_VAL(RCC_PLLI2SCFGR_PLLI2SR));
  613. /* Get the PLLSAI Clock configuration -----------------------------------------------*/
  614. PeriphClkInit->PLLSAI.PLLSAIN = (uint32_t)((RCC->PLLSAICFGR & RCC_PLLSAICFGR_PLLSAIN) >> POSITION_VAL(RCC_PLLSAICFGR_PLLSAIN));
  615. PeriphClkInit->PLLSAI.PLLSAIP = (uint32_t)((RCC->PLLSAICFGR & RCC_PLLSAICFGR_PLLSAIP) >> POSITION_VAL(RCC_PLLSAICFGR_PLLSAIP));
  616. PeriphClkInit->PLLSAI.PLLSAIQ = (uint32_t)((RCC->PLLSAICFGR & RCC_PLLSAICFGR_PLLSAIQ) >> POSITION_VAL(RCC_PLLSAICFGR_PLLSAIQ));
  617. PeriphClkInit->PLLSAI.PLLSAIR = (uint32_t)((RCC->PLLSAICFGR & RCC_PLLSAICFGR_PLLSAIR) >> POSITION_VAL(RCC_PLLSAICFGR_PLLSAIR));
  618. /* Get the PLLSAI/PLLI2S division factors -------------------------------------------*/
  619. PeriphClkInit->PLLI2SDivQ = (uint32_t)((RCC->DCKCFGR1 & RCC_DCKCFGR1_PLLI2SDIVQ) >> POSITION_VAL(RCC_DCKCFGR1_PLLI2SDIVQ));
  620. PeriphClkInit->PLLSAIDivQ = (uint32_t)((RCC->DCKCFGR1 & RCC_DCKCFGR1_PLLSAIDIVQ) >> POSITION_VAL(RCC_DCKCFGR1_PLLSAIDIVQ));
  621. PeriphClkInit->PLLSAIDivR = (uint32_t)((RCC->DCKCFGR1 & RCC_DCKCFGR1_PLLSAIDIVR) >> POSITION_VAL(RCC_DCKCFGR1_PLLSAIDIVR));
  622. /* Get the SAI1 clock configuration ----------------------------------------------*/
  623. PeriphClkInit->Sai1ClockSelection = __HAL_RCC_GET_SAI1_SOURCE();
  624. /* Get the SAI2 clock configuration ----------------------------------------------*/
  625. PeriphClkInit->Sai2ClockSelection = __HAL_RCC_GET_SAI2_SOURCE();
  626. /* Get the I2S clock configuration ------------------------------------------*/
  627. PeriphClkInit->I2sClockSelection = __HAL_RCC_GET_I2SCLKSOURCE();
  628. /* Get the I2C1 clock configuration ------------------------------------------*/
  629. PeriphClkInit->I2c1ClockSelection = __HAL_RCC_GET_I2C1_SOURCE();
  630. /* Get the I2C2 clock configuration ------------------------------------------*/
  631. PeriphClkInit->I2c2ClockSelection = __HAL_RCC_GET_I2C2_SOURCE();
  632. /* Get the I2C3 clock configuration ------------------------------------------*/
  633. PeriphClkInit->I2c3ClockSelection = __HAL_RCC_GET_I2C3_SOURCE();
  634. /* Get the I2C4 clock configuration ------------------------------------------*/
  635. PeriphClkInit->I2c4ClockSelection = __HAL_RCC_GET_I2C4_SOURCE();
  636. /* Get the USART1 clock configuration ------------------------------------------*/
  637. PeriphClkInit->Usart1ClockSelection = __HAL_RCC_GET_USART1_SOURCE();
  638. /* Get the USART2 clock configuration ------------------------------------------*/
  639. PeriphClkInit->Usart2ClockSelection = __HAL_RCC_GET_USART2_SOURCE();
  640. /* Get the USART3 clock configuration ------------------------------------------*/
  641. PeriphClkInit->Usart3ClockSelection = __HAL_RCC_GET_USART3_SOURCE();
  642. /* Get the UART4 clock configuration ------------------------------------------*/
  643. PeriphClkInit->Uart4ClockSelection = __HAL_RCC_GET_UART4_SOURCE();
  644. /* Get the UART5 clock configuration ------------------------------------------*/
  645. PeriphClkInit->Uart5ClockSelection = __HAL_RCC_GET_UART5_SOURCE();
  646. /* Get the USART6 clock configuration ------------------------------------------*/
  647. PeriphClkInit->Usart6ClockSelection = __HAL_RCC_GET_USART6_SOURCE();
  648. /* Get the UART7 clock configuration ------------------------------------------*/
  649. PeriphClkInit->Uart7ClockSelection = __HAL_RCC_GET_UART7_SOURCE();
  650. /* Get the UART8 clock configuration ------------------------------------------*/
  651. PeriphClkInit->Uart8ClockSelection = __HAL_RCC_GET_UART8_SOURCE();
  652. /* Get the LPTIM1 clock configuration ------------------------------------------*/
  653. PeriphClkInit->Lptim1ClockSelection = __HAL_RCC_GET_LPTIM1_SOURCE();
  654. /* Get the CEC clock configuration -----------------------------------------------*/
  655. PeriphClkInit->CecClockSelection = __HAL_RCC_GET_CEC_SOURCE();
  656. /* Get the CK48 clock configuration -----------------------------------------------*/
  657. PeriphClkInit->Clk48ClockSelection = __HAL_RCC_GET_CLK48_SOURCE();
  658. /* Get the SDMMC1 clock configuration -----------------------------------------------*/
  659. PeriphClkInit->Sdmmc1ClockSelection = __HAL_RCC_GET_SDMMC1_SOURCE();
  660. #if defined (STM32F765xx) || defined (STM32F767xx) || defined (STM32F769xx) || defined (STM32F777xx) || defined (STM32F779xx)
  661. /* Get the SDMMC2 clock configuration -----------------------------------------------*/
  662. PeriphClkInit->Sdmmc2ClockSelection = __HAL_RCC_GET_SDMMC2_SOURCE();
  663. /* Get the DFSDM clock configuration -----------------------------------------------*/
  664. PeriphClkInit->Dfsdm1ClockSelection = __HAL_RCC_GET_DFSDM1_SOURCE();
  665. /* Get the DFSDM AUDIO clock configuration -----------------------------------------------*/
  666. PeriphClkInit->Dfsdm1AudioClockSelection = __HAL_RCC_GET_DFSDM1AUDIO_SOURCE();
  667. #endif /* STM32F767xx || STM32F769xx || STM32F777xx || STM32F779xx */
  668. /* Get the RTC Clock configuration -----------------------------------------------*/
  669. tempreg = (RCC->CFGR & RCC_CFGR_RTCPRE);
  670. PeriphClkInit->RTCClockSelection = (uint32_t)((tempreg) | (RCC->BDCR & RCC_BDCR_RTCSEL));
  671. /* Get the TIM Prescaler configuration --------------------------------------------*/
  672. if ((RCC->DCKCFGR1 & RCC_DCKCFGR1_TIMPRE) == RESET)
  673. {
  674. PeriphClkInit->TIMPresSelection = RCC_TIMPRES_DESACTIVATED;
  675. }
  676. else
  677. {
  678. PeriphClkInit->TIMPresSelection = RCC_TIMPRES_ACTIVATED;
  679. }
  680. }
  681. #endif /* STM32F745xx || STM32F746xx || STM32F756xx || STM32F765xx || STM32F767xx || STM32F769xx || STM32F777xx || STM32F779xx */
  682. #if defined (STM32F722xx) || defined (STM32F723xx) || defined (STM32F732xx) || defined (STM32F733xx)
  683. /**
  684. * @brief Initializes the RCC extended peripherals clocks according to the specified
  685. * parameters in the RCC_PeriphCLKInitTypeDef.
  686. * @param PeriphClkInit: pointer to an RCC_PeriphCLKInitTypeDef structure that
  687. * contains the configuration information for the Extended Peripherals
  688. * clocks(I2S, SAI, RTC, TIM, UARTs, USARTs, LTPIM, SDMMC...).
  689. *
  690. * @note Care must be taken when HAL_RCCEx_PeriphCLKConfig() is used to select
  691. * the RTC clock source; in this case the Backup domain will be reset in
  692. * order to modify the RTC Clock source, as consequence RTC registers (including
  693. * the backup registers) are set to their reset values.
  694. *
  695. * @retval HAL status
  696. */
  697. HAL_StatusTypeDef HAL_RCCEx_PeriphCLKConfig(RCC_PeriphCLKInitTypeDef *PeriphClkInit)
  698. {
  699. uint32_t tickstart = 0;
  700. uint32_t tmpreg0 = 0;
  701. uint32_t plli2sused = 0;
  702. uint32_t pllsaiused = 0;
  703. /* Check the parameters */
  704. assert_param(IS_RCC_PERIPHCLOCK(PeriphClkInit->PeriphClockSelection));
  705. /*----------------------------------- I2S configuration ----------------------------------*/
  706. if(((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_I2S) == (RCC_PERIPHCLK_I2S))
  707. {
  708. /* Check the parameters */
  709. assert_param(IS_RCC_I2SCLKSOURCE(PeriphClkInit->I2sClockSelection));
  710. /* Configure I2S Clock source */
  711. __HAL_RCC_I2S_CONFIG(PeriphClkInit->I2sClockSelection);
  712. /* Enable the PLLI2S when it's used as clock source for I2S */
  713. if(PeriphClkInit->I2sClockSelection == RCC_I2SCLKSOURCE_PLLI2S)
  714. {
  715. plli2sused = 1;
  716. }
  717. }
  718. /*------------------------------------ SAI1 configuration --------------------------------------*/
  719. if(((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_SAI1) == (RCC_PERIPHCLK_SAI1))
  720. {
  721. /* Check the parameters */
  722. assert_param(IS_RCC_SAI1CLKSOURCE(PeriphClkInit->Sai1ClockSelection));
  723. /* Configure SAI1 Clock source */
  724. __HAL_RCC_SAI1_CONFIG(PeriphClkInit->Sai1ClockSelection);
  725. /* Enable the PLLI2S when it's used as clock source for SAI */
  726. if(PeriphClkInit->Sai1ClockSelection == RCC_SAI1CLKSOURCE_PLLI2S)
  727. {
  728. plli2sused = 1;
  729. }
  730. /* Enable the PLLSAI when it's used as clock source for SAI */
  731. if(PeriphClkInit->Sai1ClockSelection == RCC_SAI1CLKSOURCE_PLLSAI)
  732. {
  733. pllsaiused = 1;
  734. }
  735. }
  736. /*------------------------------------ SAI2 configuration --------------------------------------*/
  737. if(((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_SAI2) == (RCC_PERIPHCLK_SAI2))
  738. {
  739. /* Check the parameters */
  740. assert_param(IS_RCC_SAI2CLKSOURCE(PeriphClkInit->Sai2ClockSelection));
  741. /* Configure SAI2 Clock source */
  742. __HAL_RCC_SAI2_CONFIG(PeriphClkInit->Sai2ClockSelection);
  743. /* Enable the PLLI2S when it's used as clock source for SAI */
  744. if(PeriphClkInit->Sai2ClockSelection == RCC_SAI2CLKSOURCE_PLLI2S)
  745. {
  746. plli2sused = 1;
  747. }
  748. /* Enable the PLLSAI when it's used as clock source for SAI */
  749. if(PeriphClkInit->Sai2ClockSelection == RCC_SAI2CLKSOURCE_PLLSAI)
  750. {
  751. pllsaiused = 1;
  752. }
  753. }
  754. /*------------------------------------ RTC configuration --------------------------------------*/
  755. if(((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_RTC) == (RCC_PERIPHCLK_RTC))
  756. {
  757. /* Check for RTC Parameters used to output RTCCLK */
  758. assert_param(IS_RCC_RTCCLKSOURCE(PeriphClkInit->RTCClockSelection));
  759. /* Enable Power Clock*/
  760. __HAL_RCC_PWR_CLK_ENABLE();
  761. /* Enable write access to Backup domain */
  762. PWR->CR1 |= PWR_CR1_DBP;
  763. /* Get Start Tick*/
  764. tickstart = HAL_GetTick();
  765. /* Wait for Backup domain Write protection disable */
  766. while((PWR->CR1 & PWR_CR1_DBP) == RESET)
  767. {
  768. if((HAL_GetTick() - tickstart) > RCC_DBP_TIMEOUT_VALUE)
  769. {
  770. return HAL_TIMEOUT;
  771. }
  772. }
  773. /* Reset the Backup domain only if the RTC Clock source selection is modified */
  774. tmpreg0 = (RCC->BDCR & RCC_BDCR_RTCSEL);
  775. if((tmpreg0 != 0x00000000U) && (tmpreg0 != (PeriphClkInit->RTCClockSelection & RCC_BDCR_RTCSEL)))
  776. {
  777. /* Store the content of BDCR register before the reset of Backup Domain */
  778. tmpreg0 = (RCC->BDCR & ~(RCC_BDCR_RTCSEL));
  779. /* RTC Clock selection can be changed only if the Backup Domain is reset */
  780. __HAL_RCC_BACKUPRESET_FORCE();
  781. __HAL_RCC_BACKUPRESET_RELEASE();
  782. /* Restore the Content of BDCR register */
  783. RCC->BDCR = tmpreg0;
  784. /* Wait for LSE reactivation if LSE was enable prior to Backup Domain reset */
  785. if (HAL_IS_BIT_SET(RCC->BDCR, RCC_BDCR_LSEON))
  786. {
  787. /* Get Start Tick*/
  788. tickstart = HAL_GetTick();
  789. /* Wait till LSE is ready */
  790. while(__HAL_RCC_GET_FLAG(RCC_FLAG_LSERDY) == RESET)
  791. {
  792. if((HAL_GetTick() - tickstart ) > RCC_LSE_TIMEOUT_VALUE)
  793. {
  794. return HAL_TIMEOUT;
  795. }
  796. }
  797. }
  798. }
  799. __HAL_RCC_RTC_CONFIG(PeriphClkInit->RTCClockSelection);
  800. }
  801. /*------------------------------------ TIM configuration --------------------------------------*/
  802. if(((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_TIM) == (RCC_PERIPHCLK_TIM))
  803. {
  804. /* Check the parameters */
  805. assert_param(IS_RCC_TIMPRES(PeriphClkInit->TIMPresSelection));
  806. /* Configure Timer Prescaler */
  807. __HAL_RCC_TIMCLKPRESCALER(PeriphClkInit->TIMPresSelection);
  808. }
  809. /*-------------------------------------- I2C1 Configuration -----------------------------------*/
  810. if(((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_I2C1) == RCC_PERIPHCLK_I2C1)
  811. {
  812. /* Check the parameters */
  813. assert_param(IS_RCC_I2C1CLKSOURCE(PeriphClkInit->I2c1ClockSelection));
  814. /* Configure the I2C1 clock source */
  815. __HAL_RCC_I2C1_CONFIG(PeriphClkInit->I2c1ClockSelection);
  816. }
  817. /*-------------------------------------- I2C2 Configuration -----------------------------------*/
  818. if(((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_I2C2) == RCC_PERIPHCLK_I2C2)
  819. {
  820. /* Check the parameters */
  821. assert_param(IS_RCC_I2C2CLKSOURCE(PeriphClkInit->I2c2ClockSelection));
  822. /* Configure the I2C2 clock source */
  823. __HAL_RCC_I2C2_CONFIG(PeriphClkInit->I2c2ClockSelection);
  824. }
  825. /*-------------------------------------- I2C3 Configuration -----------------------------------*/
  826. if(((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_I2C3) == RCC_PERIPHCLK_I2C3)
  827. {
  828. /* Check the parameters */
  829. assert_param(IS_RCC_I2C3CLKSOURCE(PeriphClkInit->I2c3ClockSelection));
  830. /* Configure the I2C3 clock source */
  831. __HAL_RCC_I2C3_CONFIG(PeriphClkInit->I2c3ClockSelection);
  832. }
  833. /*-------------------------------------- USART1 Configuration -----------------------------------*/
  834. if(((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_USART1) == RCC_PERIPHCLK_USART1)
  835. {
  836. /* Check the parameters */
  837. assert_param(IS_RCC_USART1CLKSOURCE(PeriphClkInit->Usart1ClockSelection));
  838. /* Configure the USART1 clock source */
  839. __HAL_RCC_USART1_CONFIG(PeriphClkInit->Usart1ClockSelection);
  840. }
  841. /*-------------------------------------- USART2 Configuration -----------------------------------*/
  842. if(((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_USART2) == RCC_PERIPHCLK_USART2)
  843. {
  844. /* Check the parameters */
  845. assert_param(IS_RCC_USART2CLKSOURCE(PeriphClkInit->Usart2ClockSelection));
  846. /* Configure the USART2 clock source */
  847. __HAL_RCC_USART2_CONFIG(PeriphClkInit->Usart2ClockSelection);
  848. }
  849. /*-------------------------------------- USART3 Configuration -----------------------------------*/
  850. if(((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_USART3) == RCC_PERIPHCLK_USART3)
  851. {
  852. /* Check the parameters */
  853. assert_param(IS_RCC_USART3CLKSOURCE(PeriphClkInit->Usart3ClockSelection));
  854. /* Configure the USART3 clock source */
  855. __HAL_RCC_USART3_CONFIG(PeriphClkInit->Usart3ClockSelection);
  856. }
  857. /*-------------------------------------- UART4 Configuration -----------------------------------*/
  858. if(((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_UART4) == RCC_PERIPHCLK_UART4)
  859. {
  860. /* Check the parameters */
  861. assert_param(IS_RCC_UART4CLKSOURCE(PeriphClkInit->Uart4ClockSelection));
  862. /* Configure the UART4 clock source */
  863. __HAL_RCC_UART4_CONFIG(PeriphClkInit->Uart4ClockSelection);
  864. }
  865. /*-------------------------------------- UART5 Configuration -----------------------------------*/
  866. if(((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_UART5) == RCC_PERIPHCLK_UART5)
  867. {
  868. /* Check the parameters */
  869. assert_param(IS_RCC_UART5CLKSOURCE(PeriphClkInit->Uart5ClockSelection));
  870. /* Configure the UART5 clock source */
  871. __HAL_RCC_UART5_CONFIG(PeriphClkInit->Uart5ClockSelection);
  872. }
  873. /*-------------------------------------- USART6 Configuration -----------------------------------*/
  874. if(((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_USART6) == RCC_PERIPHCLK_USART6)
  875. {
  876. /* Check the parameters */
  877. assert_param(IS_RCC_USART6CLKSOURCE(PeriphClkInit->Usart6ClockSelection));
  878. /* Configure the USART6 clock source */
  879. __HAL_RCC_USART6_CONFIG(PeriphClkInit->Usart6ClockSelection);
  880. }
  881. /*-------------------------------------- UART7 Configuration -----------------------------------*/
  882. if(((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_UART7) == RCC_PERIPHCLK_UART7)
  883. {
  884. /* Check the parameters */
  885. assert_param(IS_RCC_UART7CLKSOURCE(PeriphClkInit->Uart7ClockSelection));
  886. /* Configure the UART7 clock source */
  887. __HAL_RCC_UART7_CONFIG(PeriphClkInit->Uart7ClockSelection);
  888. }
  889. /*-------------------------------------- UART8 Configuration -----------------------------------*/
  890. if(((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_UART8) == RCC_PERIPHCLK_UART8)
  891. {
  892. /* Check the parameters */
  893. assert_param(IS_RCC_UART8CLKSOURCE(PeriphClkInit->Uart8ClockSelection));
  894. /* Configure the UART8 clock source */
  895. __HAL_RCC_UART8_CONFIG(PeriphClkInit->Uart8ClockSelection);
  896. }
  897. /*-------------------------------------- CK48 Configuration -----------------------------------*/
  898. if(((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_CLK48) == RCC_PERIPHCLK_CLK48)
  899. {
  900. /* Check the parameters */
  901. assert_param(IS_RCC_CLK48SOURCE(PeriphClkInit->Clk48ClockSelection));
  902. /* Configure the CLK48 source */
  903. __HAL_RCC_CLK48_CONFIG(PeriphClkInit->Clk48ClockSelection);
  904. /* Enable the PLLSAI when it's used as clock source for CK48 */
  905. if(PeriphClkInit->Clk48ClockSelection == RCC_CLK48SOURCE_PLLSAIP)
  906. {
  907. pllsaiused = 1;
  908. }
  909. }
  910. /*-------------------------------------- LPTIM1 Configuration -----------------------------------*/
  911. if(((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_LPTIM1) == RCC_PERIPHCLK_LPTIM1)
  912. {
  913. /* Check the parameters */
  914. assert_param(IS_RCC_LPTIM1CLK(PeriphClkInit->Lptim1ClockSelection));
  915. /* Configure the LTPIM1 clock source */
  916. __HAL_RCC_LPTIM1_CONFIG(PeriphClkInit->Lptim1ClockSelection);
  917. }
  918. /*------------------------------------- SDMMC1 Configuration ------------------------------------*/
  919. if(((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_SDMMC1) == RCC_PERIPHCLK_SDMMC1)
  920. {
  921. /* Check the parameters */
  922. assert_param(IS_RCC_SDMMC1CLKSOURCE(PeriphClkInit->Sdmmc1ClockSelection));
  923. /* Configure the SDMMC1 clock source */
  924. __HAL_RCC_SDMMC1_CONFIG(PeriphClkInit->Sdmmc1ClockSelection);
  925. }
  926. /*------------------------------------- SDMMC2 Configuration ------------------------------------*/
  927. if(((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_SDMMC2) == RCC_PERIPHCLK_SDMMC2)
  928. {
  929. /* Check the parameters */
  930. assert_param(IS_RCC_SDMMC2CLKSOURCE(PeriphClkInit->Sdmmc2ClockSelection));
  931. /* Configure the SDMMC2 clock source */
  932. __HAL_RCC_SDMMC2_CONFIG(PeriphClkInit->Sdmmc2ClockSelection);
  933. }
  934. /*-------------------------------------- PLLI2S Configuration ---------------------------------*/
  935. /* PLLI2S is configured when a peripheral will use it as source clock : SAI1, SAI2 or I2S */
  936. if((plli2sused == 1) || (PeriphClkInit->PeriphClockSelection == RCC_PERIPHCLK_PLLI2S))
  937. {
  938. /* Disable the PLLI2S */
  939. __HAL_RCC_PLLI2S_DISABLE();
  940. /* Get Start Tick*/
  941. tickstart = HAL_GetTick();
  942. /* Wait till PLLI2S is disabled */
  943. while(__HAL_RCC_GET_FLAG(RCC_FLAG_PLLI2SRDY) != RESET)
  944. {
  945. if((HAL_GetTick() - tickstart) > PLLI2S_TIMEOUT_VALUE)
  946. {
  947. /* return in case of Timeout detected */
  948. return HAL_TIMEOUT;
  949. }
  950. }
  951. /* check for common PLLI2S Parameters */
  952. assert_param(IS_RCC_PLLI2SN_VALUE(PeriphClkInit->PLLI2S.PLLI2SN));
  953. /*----------------- In Case of PLLI2S is selected as source clock for I2S -------------------*/
  954. if(((((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_I2S) == RCC_PERIPHCLK_I2S) && (PeriphClkInit->I2sClockSelection == RCC_I2SCLKSOURCE_PLLI2S)))
  955. {
  956. /* check for Parameters */
  957. assert_param(IS_RCC_PLLI2SR_VALUE(PeriphClkInit->PLLI2S.PLLI2SR));
  958. /* Read PLLI2SQ value from PLLI2SCFGR register (this value is not needed for I2S configuration) */
  959. tmpreg0 = ((RCC->PLLI2SCFGR & RCC_PLLI2SCFGR_PLLI2SQ) >> POSITION_VAL(RCC_PLLI2SCFGR_PLLI2SQ));
  960. /* Configure the PLLI2S division factors */
  961. /* PLLI2S_VCO = f(VCO clock) = f(PLLI2S clock input) x (PLLI2SN/PLLM) */
  962. /* I2SCLK = f(PLLI2S clock output) = f(VCO clock) / PLLI2SR */
  963. __HAL_RCC_PLLI2S_CONFIG(PeriphClkInit->PLLI2S.PLLI2SN , tmpreg0, PeriphClkInit->PLLI2S.PLLI2SR);
  964. }
  965. /*----------------- In Case of PLLI2S is selected as source clock for SAI -------------------*/
  966. if(((((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_SAI1) == RCC_PERIPHCLK_SAI1) && (PeriphClkInit->Sai1ClockSelection == RCC_SAI1CLKSOURCE_PLLI2S)) ||
  967. ((((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_SAI2) == RCC_PERIPHCLK_SAI2) && (PeriphClkInit->Sai2ClockSelection == RCC_SAI2CLKSOURCE_PLLI2S)))
  968. {
  969. /* Check for PLLI2S Parameters */
  970. assert_param(IS_RCC_PLLI2SQ_VALUE(PeriphClkInit->PLLI2S.PLLI2SQ));
  971. /* Check for PLLI2S/DIVQ parameters */
  972. assert_param(IS_RCC_PLLI2S_DIVQ_VALUE(PeriphClkInit->PLLI2SDivQ));
  973. /* Read PLLI2SP and PLLI2SR values from PLLI2SCFGR register (this value is not needed for SAI configuration) */
  974. tmpreg0 = ((RCC->PLLI2SCFGR & RCC_PLLI2SCFGR_PLLI2SR) >> POSITION_VAL(RCC_PLLI2SCFGR_PLLI2SR));
  975. /* Configure the PLLI2S division factors */
  976. /* PLLI2S_VCO Input = PLL_SOURCE/PLLM */
  977. /* PLLI2S_VCO Output = PLLI2S_VCO Input * PLLI2SN */
  978. /* SAI_CLK(first level) = PLLI2S_VCO Output/PLLI2SQ */
  979. __HAL_RCC_PLLI2S_CONFIG(PeriphClkInit->PLLI2S.PLLI2SN, PeriphClkInit->PLLI2S.PLLI2SQ, tmpreg0);
  980. /* SAI_CLK_x = SAI_CLK(first level)/PLLI2SDIVQ */
  981. __HAL_RCC_PLLI2S_PLLSAICLKDIVQ_CONFIG(PeriphClkInit->PLLI2SDivQ);
  982. }
  983. /*----------------- In Case of PLLI2S is just selected -----------------*/
  984. if((PeriphClkInit->PeriphClockSelection & RCC_PERIPHCLK_PLLI2S) == RCC_PERIPHCLK_PLLI2S)
  985. {
  986. /* Check for Parameters */
  987. assert_param(IS_RCC_PLLI2SR_VALUE(PeriphClkInit->PLLI2S.PLLI2SR));
  988. assert_param(IS_RCC_PLLI2SQ_VALUE(PeriphClkInit->PLLI2S.PLLI2SQ));
  989. /* Configure the PLLI2S division factors */
  990. /* PLLI2S_VCO = f(VCO clock) = f(PLLI2S clock input) x (PLLI2SN/PLLI2SM) */
  991. __HAL_RCC_PLLI2S_CONFIG(PeriphClkInit->PLLI2S.PLLI2SN , PeriphClkInit->PLLI2S.PLLI2SQ, PeriphClkInit->PLLI2S.PLLI2SR);
  992. }
  993. /* Enable the PLLI2S */
  994. __HAL_RCC_PLLI2S_ENABLE();
  995. /* Get Start Tick*/
  996. tickstart = HAL_GetTick();
  997. /* Wait till PLLI2S is ready */
  998. while(__HAL_RCC_GET_FLAG(RCC_FLAG_PLLI2SRDY) == RESET)
  999. {
  1000. if((HAL_GetTick() - tickstart) > PLLI2S_TIMEOUT_VALUE)
  1001. {
  1002. /* return in case of Timeout detected */
  1003. return HAL_TIMEOUT;
  1004. }
  1005. }
  1006. }
  1007. /*-------------------------------------- PLLSAI Configuration ---------------------------------*/
  1008. /* PLLSAI is configured when a peripheral will use it as source clock : SAI1, SAI2, LTDC or CK48 */
  1009. if(pllsaiused == 1)
  1010. {
  1011. /* Disable PLLSAI Clock */
  1012. __HAL_RCC_PLLSAI_DISABLE();
  1013. /* Get Start Tick*/
  1014. tickstart = HAL_GetTick();
  1015. /* Wait till PLLSAI is disabled */
  1016. while(__HAL_RCC_PLLSAI_GET_FLAG() != RESET)
  1017. {
  1018. if((HAL_GetTick() - tickstart) > PLLSAI_TIMEOUT_VALUE)
  1019. {
  1020. /* return in case of Timeout detected */
  1021. return HAL_TIMEOUT;
  1022. }
  1023. }
  1024. /* Check the PLLSAI division factors */
  1025. assert_param(IS_RCC_PLLSAIN_VALUE(PeriphClkInit->PLLSAI.PLLSAIN));
  1026. /*----------------- In Case of PLLSAI is selected as source clock for SAI -------------------*/
  1027. if(((((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_SAI1) == RCC_PERIPHCLK_SAI1) && (PeriphClkInit->Sai1ClockSelection == RCC_SAI1CLKSOURCE_PLLSAI)) ||\
  1028. ((((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_SAI2) == RCC_PERIPHCLK_SAI2) && (PeriphClkInit->Sai2ClockSelection == RCC_SAI2CLKSOURCE_PLLSAI)))
  1029. {
  1030. /* check for PLLSAIQ Parameter */
  1031. assert_param(IS_RCC_PLLSAIQ_VALUE(PeriphClkInit->PLLSAI.PLLSAIQ));
  1032. /* check for PLLSAI/DIVQ Parameter */
  1033. assert_param(IS_RCC_PLLSAI_DIVQ_VALUE(PeriphClkInit->PLLSAIDivQ));
  1034. /* Read PLLSAIP value from PLLSAICFGR register (this value is not needed for SAI configuration) */
  1035. tmpreg0 = ((RCC->PLLSAICFGR & RCC_PLLSAICFGR_PLLSAIP) >> POSITION_VAL(RCC_PLLSAICFGR_PLLSAIP));
  1036. /* PLLSAI_VCO Input = PLL_SOURCE/PLLM */
  1037. /* PLLSAI_VCO Output = PLLSAI_VCO Input * PLLSAIN */
  1038. /* SAI_CLK(first level) = PLLSAI_VCO Output/PLLSAIQ */
  1039. __HAL_RCC_PLLSAI_CONFIG(PeriphClkInit->PLLSAI.PLLSAIN , tmpreg0, PeriphClkInit->PLLSAI.PLLSAIQ);
  1040. /* SAI_CLK_x = SAI_CLK(first level)/PLLSAIDIVQ */
  1041. __HAL_RCC_PLLSAI_PLLSAICLKDIVQ_CONFIG(PeriphClkInit->PLLSAIDivQ);
  1042. }
  1043. /*----------------- In Case of PLLSAI is selected as source clock for CLK48 -------------------*/
  1044. /* In Case of PLLI2S is selected as source clock for CK48 */
  1045. if((((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_CLK48) == RCC_PERIPHCLK_CLK48) && (PeriphClkInit->Clk48ClockSelection == RCC_CLK48SOURCE_PLLSAIP))
  1046. {
  1047. /* check for Parameters */
  1048. assert_param(IS_RCC_PLLSAIP_VALUE(PeriphClkInit->PLLSAI.PLLSAIP));
  1049. /* Read PLLSAIQ and PLLSAIR value from PLLSAICFGR register (this value is not needed for CK48 configuration) */
  1050. tmpreg0 = ((RCC->PLLSAICFGR & RCC_PLLSAICFGR_PLLSAIQ) >> POSITION_VAL(RCC_PLLSAICFGR_PLLSAIQ));
  1051. /* Configure the PLLSAI division factors */
  1052. /* PLLSAI_VCO = f(VCO clock) = f(PLLSAI clock input) x (PLLI2SN/PLLM) */
  1053. /* 48CLK = f(PLLSAI clock output) = f(VCO clock) / PLLSAIP */
  1054. __HAL_RCC_PLLSAI_CONFIG(PeriphClkInit->PLLSAI.PLLSAIN , PeriphClkInit->PLLSAI.PLLSAIP, tmpreg0);
  1055. }
  1056. /* Enable PLLSAI Clock */
  1057. __HAL_RCC_PLLSAI_ENABLE();
  1058. /* Get Start Tick*/
  1059. tickstart = HAL_GetTick();
  1060. /* Wait till PLLSAI is ready */
  1061. while(__HAL_RCC_PLLSAI_GET_FLAG() == RESET)
  1062. {
  1063. if((HAL_GetTick() - tickstart) > PLLSAI_TIMEOUT_VALUE)
  1064. {
  1065. /* return in case of Timeout detected */
  1066. return HAL_TIMEOUT;
  1067. }
  1068. }
  1069. }
  1070. return HAL_OK;
  1071. }
  1072. /**
  1073. * @brief Get the RCC_PeriphCLKInitTypeDef according to the internal
  1074. * RCC configuration registers.
  1075. * @param PeriphClkInit: pointer to the configured RCC_PeriphCLKInitTypeDef structure
  1076. * @retval None
  1077. */
  1078. void HAL_RCCEx_GetPeriphCLKConfig(RCC_PeriphCLKInitTypeDef *PeriphClkInit)
  1079. {
  1080. uint32_t tempreg = 0;
  1081. /* Set all possible values for the extended clock type parameter------------*/
  1082. PeriphClkInit->PeriphClockSelection = RCC_PERIPHCLK_I2S | RCC_PERIPHCLK_LPTIM1 |\
  1083. RCC_PERIPHCLK_SAI1 | RCC_PERIPHCLK_SAI2 |\
  1084. RCC_PERIPHCLK_TIM | RCC_PERIPHCLK_RTC |\
  1085. RCC_PERIPHCLK_I2C1 | RCC_PERIPHCLK_I2C2 |\
  1086. RCC_PERIPHCLK_I2C3 | RCC_PERIPHCLK_USART1 |\
  1087. RCC_PERIPHCLK_USART2 | RCC_PERIPHCLK_USART3 |\
  1088. RCC_PERIPHCLK_UART4 | RCC_PERIPHCLK_UART5 |\
  1089. RCC_PERIPHCLK_USART6 | RCC_PERIPHCLK_UART7 |\
  1090. RCC_PERIPHCLK_UART8 | RCC_PERIPHCLK_SDMMC1 |\
  1091. RCC_PERIPHCLK_CLK48 | RCC_PERIPHCLK_SDMMC2;
  1092. /* Get the PLLI2S Clock configuration -----------------------------------------------*/
  1093. PeriphClkInit->PLLI2S.PLLI2SN = (uint32_t)((RCC->PLLI2SCFGR & RCC_PLLI2SCFGR_PLLI2SN) >> POSITION_VAL(RCC_PLLI2SCFGR_PLLI2SN));
  1094. PeriphClkInit->PLLI2S.PLLI2SQ = (uint32_t)((RCC->PLLI2SCFGR & RCC_PLLI2SCFGR_PLLI2SQ) >> POSITION_VAL(RCC_PLLI2SCFGR_PLLI2SQ));
  1095. PeriphClkInit->PLLI2S.PLLI2SR = (uint32_t)((RCC->PLLI2SCFGR & RCC_PLLI2SCFGR_PLLI2SR) >> POSITION_VAL(RCC_PLLI2SCFGR_PLLI2SR));
  1096. /* Get the PLLSAI Clock configuration -----------------------------------------------*/
  1097. PeriphClkInit->PLLSAI.PLLSAIN = (uint32_t)((RCC->PLLSAICFGR & RCC_PLLSAICFGR_PLLSAIN) >> POSITION_VAL(RCC_PLLSAICFGR_PLLSAIN));
  1098. PeriphClkInit->PLLSAI.PLLSAIP = (uint32_t)((RCC->PLLSAICFGR & RCC_PLLSAICFGR_PLLSAIP) >> POSITION_VAL(RCC_PLLSAICFGR_PLLSAIP));
  1099. PeriphClkInit->PLLSAI.PLLSAIQ = (uint32_t)((RCC->PLLSAICFGR & RCC_PLLSAICFGR_PLLSAIQ) >> POSITION_VAL(RCC_PLLSAICFGR_PLLSAIQ));
  1100. /* Get the PLLSAI/PLLI2S division factors -------------------------------------------*/
  1101. PeriphClkInit->PLLI2SDivQ = (uint32_t)((RCC->DCKCFGR1 & RCC_DCKCFGR1_PLLI2SDIVQ) >> POSITION_VAL(RCC_DCKCFGR1_PLLI2SDIVQ));
  1102. PeriphClkInit->PLLSAIDivQ = (uint32_t)((RCC->DCKCFGR1 & RCC_DCKCFGR1_PLLSAIDIVQ) >> POSITION_VAL(RCC_DCKCFGR1_PLLSAIDIVQ));
  1103. /* Get the SAI1 clock configuration ----------------------------------------------*/
  1104. PeriphClkInit->Sai1ClockSelection = __HAL_RCC_GET_SAI1_SOURCE();
  1105. /* Get the SAI2 clock configuration ----------------------------------------------*/
  1106. PeriphClkInit->Sai2ClockSelection = __HAL_RCC_GET_SAI2_SOURCE();
  1107. /* Get the I2S clock configuration ------------------------------------------*/
  1108. PeriphClkInit->I2sClockSelection = __HAL_RCC_GET_I2SCLKSOURCE();
  1109. /* Get the I2C1 clock configuration ------------------------------------------*/
  1110. PeriphClkInit->I2c1ClockSelection = __HAL_RCC_GET_I2C1_SOURCE();
  1111. /* Get the I2C2 clock configuration ------------------------------------------*/
  1112. PeriphClkInit->I2c2ClockSelection = __HAL_RCC_GET_I2C2_SOURCE();
  1113. /* Get the I2C3 clock configuration ------------------------------------------*/
  1114. PeriphClkInit->I2c3ClockSelection = __HAL_RCC_GET_I2C3_SOURCE();
  1115. /* Get the USART1 clock configuration ------------------------------------------*/
  1116. PeriphClkInit->Usart1ClockSelection = __HAL_RCC_GET_USART1_SOURCE();
  1117. /* Get the USART2 clock configuration ------------------------------------------*/
  1118. PeriphClkInit->Usart2ClockSelection = __HAL_RCC_GET_USART2_SOURCE();
  1119. /* Get the USART3 clock configuration ------------------------------------------*/
  1120. PeriphClkInit->Usart3ClockSelection = __HAL_RCC_GET_USART3_SOURCE();
  1121. /* Get the UART4 clock configuration ------------------------------------------*/
  1122. PeriphClkInit->Uart4ClockSelection = __HAL_RCC_GET_UART4_SOURCE();
  1123. /* Get the UART5 clock configuration ------------------------------------------*/
  1124. PeriphClkInit->Uart5ClockSelection = __HAL_RCC_GET_UART5_SOURCE();
  1125. /* Get the USART6 clock configuration ------------------------------------------*/
  1126. PeriphClkInit->Usart6ClockSelection = __HAL_RCC_GET_USART6_SOURCE();
  1127. /* Get the UART7 clock configuration ------------------------------------------*/
  1128. PeriphClkInit->Uart7ClockSelection = __HAL_RCC_GET_UART7_SOURCE();
  1129. /* Get the UART8 clock configuration ------------------------------------------*/
  1130. PeriphClkInit->Uart8ClockSelection = __HAL_RCC_GET_UART8_SOURCE();
  1131. /* Get the LPTIM1 clock configuration ------------------------------------------*/
  1132. PeriphClkInit->Lptim1ClockSelection = __HAL_RCC_GET_LPTIM1_SOURCE();
  1133. /* Get the CK48 clock configuration -----------------------------------------------*/
  1134. PeriphClkInit->Clk48ClockSelection = __HAL_RCC_GET_CLK48_SOURCE();
  1135. /* Get the SDMMC1 clock configuration -----------------------------------------------*/
  1136. PeriphClkInit->Sdmmc1ClockSelection = __HAL_RCC_GET_SDMMC1_SOURCE();
  1137. /* Get the SDMMC2 clock configuration -----------------------------------------------*/
  1138. PeriphClkInit->Sdmmc2ClockSelection = __HAL_RCC_GET_SDMMC2_SOURCE();
  1139. /* Get the RTC Clock configuration -----------------------------------------------*/
  1140. tempreg = (RCC->CFGR & RCC_CFGR_RTCPRE);
  1141. PeriphClkInit->RTCClockSelection = (uint32_t)((tempreg) | (RCC->BDCR & RCC_BDCR_RTCSEL));
  1142. /* Get the TIM Prescaler configuration --------------------------------------------*/
  1143. if ((RCC->DCKCFGR1 & RCC_DCKCFGR1_TIMPRE) == RESET)
  1144. {
  1145. PeriphClkInit->TIMPresSelection = RCC_TIMPRES_DESACTIVATED;
  1146. }
  1147. else
  1148. {
  1149. PeriphClkInit->TIMPresSelection = RCC_TIMPRES_ACTIVATED;
  1150. }
  1151. }
  1152. #endif /* STM32F722xx || STM32F723xx || STM32F732xx || STM32F733xx */
  1153. /**
  1154. * @brief Return the peripheral clock frequency for a given peripheral(SAI..)
  1155. * @note Return 0 if peripheral clock identifier not managed by this API
  1156. * @param PeriphClk: Peripheral clock identifier
  1157. * This parameter can be one of the following values:
  1158. * @arg RCC_PERIPHCLK_SAI1: SAI1 peripheral clock
  1159. * @arg RCC_PERIPHCLK_SAI2: SAI2 peripheral clock
  1160. * @retval Frequency in KHz
  1161. */
  1162. uint32_t HAL_RCCEx_GetPeriphCLKFreq(uint32_t PeriphClk)
  1163. {
  1164. uint32_t tmpreg = 0;
  1165. /* This variable is used to store the SAI clock frequency (value in Hz) */
  1166. uint32_t frequency = 0;
  1167. /* This variable is used to store the VCO Input (value in Hz) */
  1168. uint32_t vcoinput = 0;
  1169. /* This variable is used to store the SAI clock source */
  1170. uint32_t saiclocksource = 0;
  1171. if (PeriphClk == RCC_PERIPHCLK_SAI1)
  1172. {
  1173. saiclocksource = RCC->DCKCFGR1;
  1174. saiclocksource &= RCC_DCKCFGR1_SAI1SEL;
  1175. switch (saiclocksource)
  1176. {
  1177. case 0: /* PLLSAI is the clock source for SAI1 */
  1178. {
  1179. /* Configure the PLLSAI division factor */
  1180. /* PLLSAI_VCO Input = PLL_SOURCE/PLLM */
  1181. if((RCC->PLLCFGR & RCC_PLLCFGR_PLLSRC) == RCC_PLLSOURCE_HSI)
  1182. {
  1183. /* In Case the PLL Source is HSI (Internal Clock) */
  1184. vcoinput = (HSI_VALUE / (uint32_t)(RCC->PLLCFGR & RCC_PLLCFGR_PLLM));
  1185. }
  1186. else
  1187. {
  1188. /* In Case the PLL Source is HSE (External Clock) */
  1189. vcoinput = ((HSE_VALUE / (uint32_t)(RCC->PLLCFGR & RCC_PLLCFGR_PLLM)));
  1190. }
  1191. /* PLLSAI_VCO Output = PLLSAI_VCO Input * PLLSAIN */
  1192. /* SAI_CLK(first level) = PLLSAI_VCO Output/PLLSAIQ */
  1193. tmpreg = (RCC->PLLSAICFGR & RCC_PLLSAICFGR_PLLSAIQ) >> 24;
  1194. frequency = (vcoinput * ((RCC->PLLSAICFGR & RCC_PLLSAICFGR_PLLSAIN) >> 6))/(tmpreg);
  1195. /* SAI_CLK_x = SAI_CLK(first level)/PLLSAIDIVQ */
  1196. tmpreg = (((RCC->DCKCFGR1 & RCC_DCKCFGR1_PLLSAIDIVQ) >> 8) + 1);
  1197. frequency = frequency/(tmpreg);
  1198. break;
  1199. }
  1200. case RCC_DCKCFGR1_SAI1SEL_0: /* PLLI2S is the clock source for SAI1 */
  1201. {
  1202. /* Configure the PLLI2S division factor */
  1203. /* PLLI2S_VCO Input = PLL_SOURCE/PLLM */
  1204. if((RCC->PLLCFGR & RCC_PLLCFGR_PLLSRC) == RCC_PLLSOURCE_HSI)
  1205. {
  1206. /* In Case the PLL Source is HSI (Internal Clock) */
  1207. vcoinput = (HSI_VALUE / (uint32_t)(RCC->PLLCFGR & RCC_PLLCFGR_PLLM));
  1208. }
  1209. else
  1210. {
  1211. /* In Case the PLL Source is HSE (External Clock) */
  1212. vcoinput = ((HSE_VALUE / (uint32_t)(RCC->PLLCFGR & RCC_PLLCFGR_PLLM)));
  1213. }
  1214. /* PLLI2S_VCO Output = PLLI2S_VCO Input * PLLI2SN */
  1215. /* SAI_CLK(first level) = PLLI2S_VCO Output/PLLI2SQ */
  1216. tmpreg = (RCC->PLLI2SCFGR & RCC_PLLI2SCFGR_PLLI2SQ) >> 24;
  1217. frequency = (vcoinput * ((RCC->PLLI2SCFGR & RCC_PLLI2SCFGR_PLLI2SN) >> 6))/(tmpreg);
  1218. /* SAI_CLK_x = SAI_CLK(first level)/PLLI2SDIVQ */
  1219. tmpreg = ((RCC->DCKCFGR1 & RCC_DCKCFGR1_PLLI2SDIVQ) + 1);
  1220. frequency = frequency/(tmpreg);
  1221. break;
  1222. }
  1223. case RCC_DCKCFGR1_SAI1SEL_1: /* External clock is the clock source for SAI1 */
  1224. {
  1225. frequency = EXTERNAL_CLOCK_VALUE;
  1226. break;
  1227. }
  1228. #if defined (STM32F765xx) || defined (STM32F767xx) || defined (STM32F769xx) || defined (STM32F777xx) || defined (STM32F779xx)
  1229. case RCC_DCKCFGR1_SAI1SEL: /* HSI or HSE is the clock source for SAI*/
  1230. {
  1231. if((RCC->PLLCFGR & RCC_PLLCFGR_PLLSRC) == RCC_PLLSOURCE_HSI)
  1232. {
  1233. /* In Case the main PLL Source is HSI */
  1234. frequency = HSI_VALUE;
  1235. }
  1236. else
  1237. {
  1238. /* In Case the main PLL Source is HSE */
  1239. frequency = HSE_VALUE;
  1240. }
  1241. break;
  1242. }
  1243. #endif /* STM32F767xx || STM32F769xx || STM32F777xx || STM32F779xx */
  1244. default :
  1245. {
  1246. break;
  1247. }
  1248. }
  1249. }
  1250. if (PeriphClk == RCC_PERIPHCLK_SAI2)
  1251. {
  1252. saiclocksource = RCC->DCKCFGR1;
  1253. saiclocksource &= RCC_DCKCFGR1_SAI2SEL;
  1254. switch (saiclocksource)
  1255. {
  1256. case 0: /* PLLSAI is the clock source for SAI*/
  1257. {
  1258. /* Configure the PLLSAI division factor */
  1259. /* PLLSAI_VCO Input = PLL_SOURCE/PLLM */
  1260. if((RCC->PLLCFGR & RCC_PLLCFGR_PLLSRC) == RCC_PLLSOURCE_HSI)
  1261. {
  1262. /* In Case the PLL Source is HSI (Internal Clock) */
  1263. vcoinput = (HSI_VALUE / (uint32_t)(RCC->PLLCFGR & RCC_PLLCFGR_PLLM));
  1264. }
  1265. else
  1266. {
  1267. /* In Case the PLL Source is HSE (External Clock) */
  1268. vcoinput = ((HSE_VALUE / (uint32_t)(RCC->PLLCFGR & RCC_PLLCFGR_PLLM)));
  1269. }
  1270. /* PLLSAI_VCO Output = PLLSAI_VCO Input * PLLSAIN */
  1271. /* SAI_CLK(first level) = PLLSAI_VCO Output/PLLSAIQ */
  1272. tmpreg = (RCC->PLLSAICFGR & RCC_PLLSAICFGR_PLLSAIQ) >> 24;
  1273. frequency = (vcoinput * ((RCC->PLLSAICFGR & RCC_PLLSAICFGR_PLLSAIN) >> 6))/(tmpreg);
  1274. /* SAI_CLK_x = SAI_CLK(first level)/PLLSAIDIVQ */
  1275. tmpreg = (((RCC->DCKCFGR1 & RCC_DCKCFGR1_PLLSAIDIVQ) >> 8) + 1);
  1276. frequency = frequency/(tmpreg);
  1277. break;
  1278. }
  1279. case RCC_DCKCFGR1_SAI2SEL_0: /* PLLI2S is the clock source for SAI2 */
  1280. {
  1281. /* Configure the PLLI2S division factor */
  1282. /* PLLI2S_VCO Input = PLL_SOURCE/PLLM */
  1283. if((RCC->PLLCFGR & RCC_PLLCFGR_PLLSRC) == RCC_PLLSOURCE_HSI)
  1284. {
  1285. /* In Case the PLL Source is HSI (Internal Clock) */
  1286. vcoinput = (HSI_VALUE / (uint32_t)(RCC->PLLCFGR & RCC_PLLCFGR_PLLM));
  1287. }
  1288. else
  1289. {
  1290. /* In Case the PLL Source is HSE (External Clock) */
  1291. vcoinput = ((HSE_VALUE / (uint32_t)(RCC->PLLCFGR & RCC_PLLCFGR_PLLM)));
  1292. }
  1293. /* PLLI2S_VCO Output = PLLI2S_VCO Input * PLLI2SN */
  1294. /* SAI_CLK(first level) = PLLI2S_VCO Output/PLLI2SQ */
  1295. tmpreg = (RCC->PLLI2SCFGR & RCC_PLLI2SCFGR_PLLI2SQ) >> 24;
  1296. frequency = (vcoinput * ((RCC->PLLI2SCFGR & RCC_PLLI2SCFGR_PLLI2SN) >> 6))/(tmpreg);
  1297. /* SAI_CLK_x = SAI_CLK(first level)/PLLI2SDIVQ */
  1298. tmpreg = ((RCC->DCKCFGR1 & RCC_DCKCFGR1_PLLI2SDIVQ) + 1);
  1299. frequency = frequency/(tmpreg);
  1300. break;
  1301. }
  1302. case RCC_DCKCFGR1_SAI2SEL_1: /* External clock is the clock source for SAI2 */
  1303. {
  1304. frequency = EXTERNAL_CLOCK_VALUE;
  1305. break;
  1306. }
  1307. #if defined (STM32F765xx) || defined (STM32F767xx) || defined (STM32F769xx) || defined (STM32F777xx) || defined (STM32F779xx)
  1308. case RCC_DCKCFGR1_SAI2SEL: /* HSI or HSE is the clock source for SAI2 */
  1309. {
  1310. if((RCC->PLLCFGR & RCC_PLLCFGR_PLLSRC) == RCC_PLLSOURCE_HSI)
  1311. {
  1312. /* In Case the main PLL Source is HSI */
  1313. frequency = HSI_VALUE;
  1314. }
  1315. else
  1316. {
  1317. /* In Case the main PLL Source is HSE */
  1318. frequency = HSE_VALUE;
  1319. }
  1320. break;
  1321. }
  1322. #endif /* STM32F767xx || STM32F769xx || STM32F777xx || STM32F779xx */
  1323. default :
  1324. {
  1325. break;
  1326. }
  1327. }
  1328. }
  1329. return frequency;
  1330. }
  1331. /**
  1332. * @}
  1333. */
  1334. /**
  1335. * @}
  1336. */
  1337. #endif /* HAL_RCC_MODULE_ENABLED */
  1338. /**
  1339. * @}
  1340. */
  1341. /**
  1342. * @}
  1343. */
  1344. /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/