1 /**
2 ******************************************************************************
3 * @file stm32f7xx_hal_rcc_ex.c
4 * @author MCD Application Team
5 * @brief Extension RCC HAL module driver.
6 * This file provides firmware functions to manage the following
7 * functionalities RCC extension peripheral:
8 * + Extended Peripheral Control functions
9 *
10 ******************************************************************************
11 * @attention
12 *
13 * Copyright (c) 2017 STMicroelectronics.
14 * All rights reserved.
15 *
16 * This software is licensed under terms that can be found in the LICENSE file in
17 * the root directory of this software component.
18 * If no LICENSE file comes with this software, it is provided AS-IS.
19 ******************************************************************************
20 */
21
22 /* Includes ------------------------------------------------------------------*/
23 #include "stm32f7xx_hal.h"
24
25 /** @addtogroup STM32F7xx_HAL_Driver
26 * @{
27 */
28
29 /** @defgroup RCCEx RCCEx
30 * @brief RCCEx HAL module driver
31 * @{
32 */
33
34 #ifdef HAL_RCC_MODULE_ENABLED
35
36 /* Private typedef -----------------------------------------------------------*/
37 /* Private define ------------------------------------------------------------*/
38 /** @defgroup RCCEx_Private_Defines RCCEx Private Defines
39 * @{
40 */
41 /**
42 * @}
43 */
44 /* Private macro -------------------------------------------------------------*/
45 /** @defgroup RCCEx_Private_Macros RCCEx Private Macros
46 * @{
47 */
48 /**
49 * @}
50 */
51
52 /** @defgroup RCCEx_Private_Macros RCCEx Private Macros
53 * @{
54 */
55
56 /**
57 * @}
58 */
59
60
61 /* Private variables ---------------------------------------------------------*/
62 /* Private function prototypes -----------------------------------------------*/
63 /* Private functions ---------------------------------------------------------*/
64
65 /** @defgroup RCCEx_Exported_Functions RCCEx Exported Functions
66 * @{
67 */
68
69 /** @defgroup RCCEx_Exported_Functions_Group1 Extended Peripheral Control functions
70 * @brief Extended Peripheral Control functions
71 *
72 @verbatim
73 ===============================================================================
74 ##### Extended Peripheral Control functions #####
75 ===============================================================================
76 [..]
77 This subsection provides a set of functions allowing to control the RCC Clocks
78 frequencies.
79 [..]
80 (@) Important note: Care must be taken when HAL_RCCEx_PeriphCLKConfig() is used to
81 select the RTC clock source; in this case the Backup domain will be reset in
82 order to modify the RTC Clock source, as consequence RTC registers (including
83 the backup registers) and RCC_BDCR register will be set to their reset values.
84
85 @endverbatim
86 * @{
87 */
88 #if defined (STM32F745xx) || defined (STM32F746xx) || defined (STM32F756xx) || defined (STM32F765xx) || \
89 defined (STM32F767xx) || defined (STM32F769xx) || defined (STM32F777xx) || defined (STM32F779xx) || \
90 defined (STM32F750xx)
91 /**
92 * @brief Initializes the RCC extended peripherals clocks according to the specified
93 * parameters in the RCC_PeriphCLKInitTypeDef.
94 * @param PeriphClkInit pointer to an RCC_PeriphCLKInitTypeDef structure that
95 * contains the configuration information for the Extended Peripherals
96 * clocks(I2S, SAI, LTDC, RTC, TIM, UARTs, USARTs, LTPIM, SDMMC...).
97 *
98 * @note Care must be taken when HAL_RCCEx_PeriphCLKConfig() is used to select
99 * the RTC clock source; in this case the Backup domain will be reset in
100 * order to modify the RTC Clock source, as consequence RTC registers (including
101 * the backup registers) are set to their reset values.
102 *
103 * @retval HAL status
104 */
HAL_RCCEx_PeriphCLKConfig(RCC_PeriphCLKInitTypeDef * PeriphClkInit)105 HAL_StatusTypeDef HAL_RCCEx_PeriphCLKConfig(RCC_PeriphCLKInitTypeDef *PeriphClkInit)
106 {
107 uint32_t tickstart = 0;
108 uint32_t tmpreg0 = 0;
109 uint32_t tmpreg1 = 0;
110 uint32_t plli2sused = 0;
111 uint32_t pllsaiused = 0;
112
113 /* Check the parameters */
114 assert_param(IS_RCC_PERIPHCLOCK(PeriphClkInit->PeriphClockSelection));
115
116 /*----------------------------------- I2S configuration ----------------------------------*/
117 if(((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_I2S) == (RCC_PERIPHCLK_I2S))
118 {
119 /* Check the parameters */
120 assert_param(IS_RCC_I2SCLKSOURCE(PeriphClkInit->I2sClockSelection));
121
122 /* Configure I2S Clock source */
123 __HAL_RCC_I2S_CONFIG(PeriphClkInit->I2sClockSelection);
124
125 /* Enable the PLLI2S when it's used as clock source for I2S */
126 if(PeriphClkInit->I2sClockSelection == RCC_I2SCLKSOURCE_PLLI2S)
127 {
128 plli2sused = 1;
129 }
130 }
131
132 /*------------------------------------ SAI1 configuration --------------------------------------*/
133 if(((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_SAI1) == (RCC_PERIPHCLK_SAI1))
134 {
135 /* Check the parameters */
136 assert_param(IS_RCC_SAI1CLKSOURCE(PeriphClkInit->Sai1ClockSelection));
137
138 /* Configure SAI1 Clock source */
139 __HAL_RCC_SAI1_CONFIG(PeriphClkInit->Sai1ClockSelection);
140 /* Enable the PLLI2S when it's used as clock source for SAI */
141 if(PeriphClkInit->Sai1ClockSelection == RCC_SAI1CLKSOURCE_PLLI2S)
142 {
143 plli2sused = 1;
144 }
145 /* Enable the PLLSAI when it's used as clock source for SAI */
146 if(PeriphClkInit->Sai1ClockSelection == RCC_SAI1CLKSOURCE_PLLSAI)
147 {
148 pllsaiused = 1;
149 }
150 }
151
152 /*------------------------------------ SAI2 configuration --------------------------------------*/
153 if(((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_SAI2) == (RCC_PERIPHCLK_SAI2))
154 {
155 /* Check the parameters */
156 assert_param(IS_RCC_SAI2CLKSOURCE(PeriphClkInit->Sai2ClockSelection));
157
158 /* Configure SAI2 Clock source */
159 __HAL_RCC_SAI2_CONFIG(PeriphClkInit->Sai2ClockSelection);
160
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
173 /*-------------------------------------- SPDIF-RX Configuration -----------------------------------*/
174 if(((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_SPDIFRX) == RCC_PERIPHCLK_SPDIFRX)
175 {
176 plli2sused = 1;
177 }
178
179 /*------------------------------------ RTC configuration --------------------------------------*/
180 if(((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_RTC) == (RCC_PERIPHCLK_RTC))
181 {
182 /* Check for RTC Parameters used to output RTCCLK */
183 assert_param(IS_RCC_RTCCLKSOURCE(PeriphClkInit->RTCClockSelection));
184
185 /* Enable Power Clock*/
186 __HAL_RCC_PWR_CLK_ENABLE();
187
188 /* Enable write access to Backup domain */
189 PWR->CR1 |= PWR_CR1_DBP;
190
191 /* Get Start Tick*/
192 tickstart = HAL_GetTick();
193
194 /* Wait for Backup domain Write protection disable */
195 while((PWR->CR1 & PWR_CR1_DBP) == RESET)
196 {
197 if((HAL_GetTick() - tickstart) > RCC_DBP_TIMEOUT_VALUE)
198 {
199 return HAL_TIMEOUT;
200 }
201 }
202
203 /* Reset the Backup domain only if the RTC Clock source selection is modified */
204 tmpreg0 = (RCC->BDCR & RCC_BDCR_RTCSEL);
205
206 if((tmpreg0 != 0x00000000U) && (tmpreg0 != (PeriphClkInit->RTCClockSelection & RCC_BDCR_RTCSEL)))
207 {
208 /* Store the content of BDCR register before the reset of Backup Domain */
209 tmpreg0 = (RCC->BDCR & ~(RCC_BDCR_RTCSEL));
210
211 /* RTC Clock selection can be changed only if the Backup Domain is reset */
212 __HAL_RCC_BACKUPRESET_FORCE();
213 __HAL_RCC_BACKUPRESET_RELEASE();
214
215 /* Restore the Content of BDCR register */
216 RCC->BDCR = tmpreg0;
217
218 /* Wait for LSE reactivation if LSE was enable prior to Backup Domain reset */
219 if (HAL_IS_BIT_SET(RCC->BDCR, RCC_BDCR_LSEON))
220 {
221 /* Get Start Tick*/
222 tickstart = HAL_GetTick();
223
224 /* Wait till LSE is ready */
225 while(__HAL_RCC_GET_FLAG(RCC_FLAG_LSERDY) == RESET)
226 {
227 if((HAL_GetTick() - tickstart ) > RCC_LSE_TIMEOUT_VALUE)
228 {
229 return HAL_TIMEOUT;
230 }
231 }
232 }
233 }
234 __HAL_RCC_RTC_CONFIG(PeriphClkInit->RTCClockSelection);
235 }
236
237 /*------------------------------------ TIM configuration --------------------------------------*/
238 if(((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_TIM) == (RCC_PERIPHCLK_TIM))
239 {
240 /* Check the parameters */
241 assert_param(IS_RCC_TIMPRES(PeriphClkInit->TIMPresSelection));
242
243 /* Configure Timer Prescaler */
244 __HAL_RCC_TIMCLKPRESCALER(PeriphClkInit->TIMPresSelection);
245 }
246
247 /*-------------------------------------- I2C1 Configuration -----------------------------------*/
248 if(((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_I2C1) == RCC_PERIPHCLK_I2C1)
249 {
250 /* Check the parameters */
251 assert_param(IS_RCC_I2C1CLKSOURCE(PeriphClkInit->I2c1ClockSelection));
252
253 /* Configure the I2C1 clock source */
254 __HAL_RCC_I2C1_CONFIG(PeriphClkInit->I2c1ClockSelection);
255 }
256
257 /*-------------------------------------- I2C2 Configuration -----------------------------------*/
258 if(((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_I2C2) == RCC_PERIPHCLK_I2C2)
259 {
260 /* Check the parameters */
261 assert_param(IS_RCC_I2C2CLKSOURCE(PeriphClkInit->I2c2ClockSelection));
262
263 /* Configure the I2C2 clock source */
264 __HAL_RCC_I2C2_CONFIG(PeriphClkInit->I2c2ClockSelection);
265 }
266
267 /*-------------------------------------- I2C3 Configuration -----------------------------------*/
268 if(((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_I2C3) == RCC_PERIPHCLK_I2C3)
269 {
270 /* Check the parameters */
271 assert_param(IS_RCC_I2C3CLKSOURCE(PeriphClkInit->I2c3ClockSelection));
272
273 /* Configure the I2C3 clock source */
274 __HAL_RCC_I2C3_CONFIG(PeriphClkInit->I2c3ClockSelection);
275 }
276
277 /*-------------------------------------- I2C4 Configuration -----------------------------------*/
278 if(((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_I2C4) == RCC_PERIPHCLK_I2C4)
279 {
280 /* Check the parameters */
281 assert_param(IS_RCC_I2C4CLKSOURCE(PeriphClkInit->I2c4ClockSelection));
282
283 /* Configure the I2C4 clock source */
284 __HAL_RCC_I2C4_CONFIG(PeriphClkInit->I2c4ClockSelection);
285 }
286
287 /*-------------------------------------- USART1 Configuration -----------------------------------*/
288 if(((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_USART1) == RCC_PERIPHCLK_USART1)
289 {
290 /* Check the parameters */
291 assert_param(IS_RCC_USART1CLKSOURCE(PeriphClkInit->Usart1ClockSelection));
292
293 /* Configure the USART1 clock source */
294 __HAL_RCC_USART1_CONFIG(PeriphClkInit->Usart1ClockSelection);
295 }
296
297 /*-------------------------------------- USART2 Configuration -----------------------------------*/
298 if(((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_USART2) == RCC_PERIPHCLK_USART2)
299 {
300 /* Check the parameters */
301 assert_param(IS_RCC_USART2CLKSOURCE(PeriphClkInit->Usart2ClockSelection));
302
303 /* Configure the USART2 clock source */
304 __HAL_RCC_USART2_CONFIG(PeriphClkInit->Usart2ClockSelection);
305 }
306
307 /*-------------------------------------- USART3 Configuration -----------------------------------*/
308 if(((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_USART3) == RCC_PERIPHCLK_USART3)
309 {
310 /* Check the parameters */
311 assert_param(IS_RCC_USART3CLKSOURCE(PeriphClkInit->Usart3ClockSelection));
312
313 /* Configure the USART3 clock source */
314 __HAL_RCC_USART3_CONFIG(PeriphClkInit->Usart3ClockSelection);
315 }
316
317 /*-------------------------------------- UART4 Configuration -----------------------------------*/
318 if(((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_UART4) == RCC_PERIPHCLK_UART4)
319 {
320 /* Check the parameters */
321 assert_param(IS_RCC_UART4CLKSOURCE(PeriphClkInit->Uart4ClockSelection));
322
323 /* Configure the UART4 clock source */
324 __HAL_RCC_UART4_CONFIG(PeriphClkInit->Uart4ClockSelection);
325 }
326
327 /*-------------------------------------- UART5 Configuration -----------------------------------*/
328 if(((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_UART5) == RCC_PERIPHCLK_UART5)
329 {
330 /* Check the parameters */
331 assert_param(IS_RCC_UART5CLKSOURCE(PeriphClkInit->Uart5ClockSelection));
332
333 /* Configure the UART5 clock source */
334 __HAL_RCC_UART5_CONFIG(PeriphClkInit->Uart5ClockSelection);
335 }
336
337 /*-------------------------------------- USART6 Configuration -----------------------------------*/
338 if(((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_USART6) == RCC_PERIPHCLK_USART6)
339 {
340 /* Check the parameters */
341 assert_param(IS_RCC_USART6CLKSOURCE(PeriphClkInit->Usart6ClockSelection));
342
343 /* Configure the USART6 clock source */
344 __HAL_RCC_USART6_CONFIG(PeriphClkInit->Usart6ClockSelection);
345 }
346
347 /*-------------------------------------- UART7 Configuration -----------------------------------*/
348 if(((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_UART7) == RCC_PERIPHCLK_UART7)
349 {
350 /* Check the parameters */
351 assert_param(IS_RCC_UART7CLKSOURCE(PeriphClkInit->Uart7ClockSelection));
352
353 /* Configure the UART7 clock source */
354 __HAL_RCC_UART7_CONFIG(PeriphClkInit->Uart7ClockSelection);
355 }
356
357 /*-------------------------------------- UART8 Configuration -----------------------------------*/
358 if(((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_UART8) == RCC_PERIPHCLK_UART8)
359 {
360 /* Check the parameters */
361 assert_param(IS_RCC_UART8CLKSOURCE(PeriphClkInit->Uart8ClockSelection));
362
363 /* Configure the UART8 clock source */
364 __HAL_RCC_UART8_CONFIG(PeriphClkInit->Uart8ClockSelection);
365 }
366
367 /*--------------------------------------- CEC Configuration -----------------------------------*/
368 if(((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_CEC) == RCC_PERIPHCLK_CEC)
369 {
370 /* Check the parameters */
371 assert_param(IS_RCC_CECCLKSOURCE(PeriphClkInit->CecClockSelection));
372
373 /* Configure the CEC clock source */
374 __HAL_RCC_CEC_CONFIG(PeriphClkInit->CecClockSelection);
375 }
376
377 /*-------------------------------------- CK48 Configuration -----------------------------------*/
378 if(((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_CLK48) == RCC_PERIPHCLK_CLK48)
379 {
380 /* Check the parameters */
381 assert_param(IS_RCC_CLK48SOURCE(PeriphClkInit->Clk48ClockSelection));
382
383 /* Configure the CLK48 source */
384 __HAL_RCC_CLK48_CONFIG(PeriphClkInit->Clk48ClockSelection);
385
386 /* Enable the PLLSAI when it's used as clock source for CK48 */
387 if(PeriphClkInit->Clk48ClockSelection == RCC_CLK48SOURCE_PLLSAIP)
388 {
389 pllsaiused = 1;
390 }
391 }
392
393 /*-------------------------------------- LTDC Configuration -----------------------------------*/
394 #if defined(STM32F746xx) || defined(STM32F756xx) || defined (STM32F767xx) || defined (STM32F769xx) || defined (STM32F777xx) || defined (STM32F779xx) || defined (STM32F750xx)
395 if(((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_LTDC) == RCC_PERIPHCLK_LTDC)
396 {
397 pllsaiused = 1;
398 }
399 #endif /* STM32F746xx || STM32F756xx || STM32F767xx || STM32F769xx || STM32F777xx || STM32F779xx || STM32F750xx */
400
401 /*-------------------------------------- LPTIM1 Configuration -----------------------------------*/
402 if(((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_LPTIM1) == RCC_PERIPHCLK_LPTIM1)
403 {
404 /* Check the parameters */
405 assert_param(IS_RCC_LPTIM1CLK(PeriphClkInit->Lptim1ClockSelection));
406
407 /* Configure the LTPIM1 clock source */
408 __HAL_RCC_LPTIM1_CONFIG(PeriphClkInit->Lptim1ClockSelection);
409 }
410
411 /*------------------------------------- SDMMC1 Configuration ------------------------------------*/
412 if(((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_SDMMC1) == RCC_PERIPHCLK_SDMMC1)
413 {
414 /* Check the parameters */
415 assert_param(IS_RCC_SDMMC1CLKSOURCE(PeriphClkInit->Sdmmc1ClockSelection));
416
417 /* Configure the SDMMC1 clock source */
418 __HAL_RCC_SDMMC1_CONFIG(PeriphClkInit->Sdmmc1ClockSelection);
419 }
420
421 #if defined (STM32F765xx) || defined (STM32F767xx) || defined (STM32F769xx) || defined (STM32F777xx) || defined (STM32F779xx)
422 /*------------------------------------- SDMMC2 Configuration ------------------------------------*/
423 if(((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_SDMMC2) == RCC_PERIPHCLK_SDMMC2)
424 {
425 /* Check the parameters */
426 assert_param(IS_RCC_SDMMC2CLKSOURCE(PeriphClkInit->Sdmmc2ClockSelection));
427
428 /* Configure the SDMMC2 clock source */
429 __HAL_RCC_SDMMC2_CONFIG(PeriphClkInit->Sdmmc2ClockSelection);
430 }
431
432 /*------------------------------------- DFSDM1 Configuration -------------------------------------*/
433 if(((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_DFSDM1) == RCC_PERIPHCLK_DFSDM1)
434 {
435 /* Check the parameters */
436 assert_param(IS_RCC_DFSDM1CLKSOURCE(PeriphClkInit->Dfsdm1ClockSelection));
437
438 /* Configure the DFSDM1 interface clock source */
439 __HAL_RCC_DFSDM1_CONFIG(PeriphClkInit->Dfsdm1ClockSelection);
440 }
441
442 /*------------------------------------- DFSDM AUDIO Configuration -------------------------------------*/
443 if(((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_DFSDM1_AUDIO) == RCC_PERIPHCLK_DFSDM1_AUDIO)
444 {
445 /* Check the parameters */
446 assert_param(IS_RCC_DFSDM1AUDIOCLKSOURCE(PeriphClkInit->Dfsdm1AudioClockSelection));
447
448 /* Configure the DFSDM interface clock source */
449 __HAL_RCC_DFSDM1AUDIO_CONFIG(PeriphClkInit->Dfsdm1AudioClockSelection);
450 }
451 #endif /* STM32F767xx || STM32F769xx || STM32F777xx || STM32F779xx */
452
453 /*-------------------------------------- PLLI2S Configuration ---------------------------------*/
454 /* PLLI2S is configured when a peripheral will use it as source clock : SAI1, SAI2, I2S or SPDIF-RX */
455 if((plli2sused == 1) || ((PeriphClkInit->PeriphClockSelection & RCC_PERIPHCLK_PLLI2S) == RCC_PERIPHCLK_PLLI2S))
456 {
457 /* Disable the PLLI2S */
458 __HAL_RCC_PLLI2S_DISABLE();
459
460 /* Get Start Tick*/
461 tickstart = HAL_GetTick();
462
463 /* Wait till PLLI2S is disabled */
464 while(__HAL_RCC_GET_FLAG(RCC_FLAG_PLLI2SRDY) != RESET)
465 {
466 if((HAL_GetTick() - tickstart) > PLLI2S_TIMEOUT_VALUE)
467 {
468 /* return in case of Timeout detected */
469 return HAL_TIMEOUT;
470 }
471 }
472
473 /* check for common PLLI2S Parameters */
474 assert_param(IS_RCC_PLLI2SN_VALUE(PeriphClkInit->PLLI2S.PLLI2SN));
475
476 /*----------------- In Case of PLLI2S is selected as source clock for I2S -------------------*/
477 if(((((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_I2S) == RCC_PERIPHCLK_I2S) && (PeriphClkInit->I2sClockSelection == RCC_I2SCLKSOURCE_PLLI2S)))
478 {
479 /* check for Parameters */
480 assert_param(IS_RCC_PLLI2SR_VALUE(PeriphClkInit->PLLI2S.PLLI2SR));
481
482 /* Read PLLI2SP and PLLI2SQ value from PLLI2SCFGR register (this value is not needed for I2S configuration) */
483 tmpreg0 = ((RCC->PLLI2SCFGR & RCC_PLLI2SCFGR_PLLI2SP) >> RCC_PLLI2SCFGR_PLLI2SP_Pos);
484 tmpreg1 = ((RCC->PLLI2SCFGR & RCC_PLLI2SCFGR_PLLI2SQ) >> RCC_PLLI2SCFGR_PLLI2SQ_Pos);
485 /* Configure the PLLI2S division factors */
486 /* PLLI2S_VCO = f(VCO clock) = f(PLLI2S clock input) x (PLLI2SN/PLLM) */
487 /* I2SCLK = f(PLLI2S clock output) = f(VCO clock) / PLLI2SR */
488 __HAL_RCC_PLLI2S_CONFIG(PeriphClkInit->PLLI2S.PLLI2SN , tmpreg0, tmpreg1, PeriphClkInit->PLLI2S.PLLI2SR);
489 }
490
491 /*----------------- In Case of PLLI2S is selected as source clock for SAI -------------------*/
492 if(((((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_SAI1) == RCC_PERIPHCLK_SAI1) && (PeriphClkInit->Sai1ClockSelection == RCC_SAI1CLKSOURCE_PLLI2S)) ||
493 ((((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_SAI2) == RCC_PERIPHCLK_SAI2) && (PeriphClkInit->Sai2ClockSelection == RCC_SAI2CLKSOURCE_PLLI2S)))
494 {
495 /* Check for PLLI2S Parameters */
496 assert_param(IS_RCC_PLLI2SQ_VALUE(PeriphClkInit->PLLI2S.PLLI2SQ));
497 /* Check for PLLI2S/DIVQ parameters */
498 assert_param(IS_RCC_PLLI2S_DIVQ_VALUE(PeriphClkInit->PLLI2SDivQ));
499
500 /* Read PLLI2SP and PLLI2SR values from PLLI2SCFGR register (this value is not needed for SAI configuration) */
501 tmpreg0 = ((RCC->PLLI2SCFGR & RCC_PLLI2SCFGR_PLLI2SP) >> RCC_PLLI2SCFGR_PLLI2SP_Pos);
502 tmpreg1 = ((RCC->PLLI2SCFGR & RCC_PLLI2SCFGR_PLLI2SR) >> RCC_PLLI2SCFGR_PLLI2SR_Pos);
503 /* Configure the PLLI2S division factors */
504 /* PLLI2S_VCO Input = PLL_SOURCE/PLLM */
505 /* PLLI2S_VCO Output = PLLI2S_VCO Input * PLLI2SN */
506 /* SAI_CLK(first level) = PLLI2S_VCO Output/PLLI2SQ */
507 __HAL_RCC_PLLI2S_CONFIG(PeriphClkInit->PLLI2S.PLLI2SN, tmpreg0, PeriphClkInit->PLLI2S.PLLI2SQ, tmpreg1);
508
509 /* SAI_CLK_x = SAI_CLK(first level)/PLLI2SDIVQ */
510 __HAL_RCC_PLLI2S_PLLSAICLKDIVQ_CONFIG(PeriphClkInit->PLLI2SDivQ);
511 }
512
513 /*----------------- In Case of PLLI2S is selected as source clock for SPDIF-RX -------------------*/
514 if(((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_SPDIFRX) == RCC_PERIPHCLK_SPDIFRX)
515 {
516 /* check for Parameters */
517 assert_param(IS_RCC_PLLI2SP_VALUE(PeriphClkInit->PLLI2S.PLLI2SP));
518
519 /* Read PLLI2SR value from PLLI2SCFGR register (this value is not needed for SPDIF-RX configuration) */
520 tmpreg0 = ((RCC->PLLI2SCFGR & RCC_PLLI2SCFGR_PLLI2SQ) >> RCC_PLLI2SCFGR_PLLI2SQ_Pos);
521 tmpreg1 = ((RCC->PLLI2SCFGR & RCC_PLLI2SCFGR_PLLI2SR) >> RCC_PLLI2SCFGR_PLLI2SR_Pos);
522 /* Configure the PLLI2S division factors */
523 /* PLLI2S_VCO = f(VCO clock) = f(PLLI2S clock input) x (PLLI2SN/PLLM) */
524 /* SPDIFCLK = f(PLLI2S clock output) = f(VCO clock) / PLLI2SP */
525 __HAL_RCC_PLLI2S_CONFIG(PeriphClkInit->PLLI2S.PLLI2SN , PeriphClkInit->PLLI2S.PLLI2SP, tmpreg0, tmpreg1);
526 }
527
528 /*----------------- In Case of PLLI2S is just selected -----------------*/
529 if((PeriphClkInit->PeriphClockSelection & RCC_PERIPHCLK_PLLI2S) == RCC_PERIPHCLK_PLLI2S)
530 {
531 /* Check for Parameters */
532 assert_param(IS_RCC_PLLI2SP_VALUE(PeriphClkInit->PLLI2S.PLLI2SP));
533 assert_param(IS_RCC_PLLI2SR_VALUE(PeriphClkInit->PLLI2S.PLLI2SR));
534 assert_param(IS_RCC_PLLI2SQ_VALUE(PeriphClkInit->PLLI2S.PLLI2SQ));
535
536 /* Configure the PLLI2S division factors */
537 /* PLLI2S_VCO = f(VCO clock) = f(PLLI2S clock input) x (PLLI2SN/PLLI2SM) */
538 /* SPDIFRXCLK = f(PLLI2S clock output) = f(VCO clock) / PLLI2SP */
539 __HAL_RCC_PLLI2S_CONFIG(PeriphClkInit->PLLI2S.PLLI2SN , PeriphClkInit->PLLI2S.PLLI2SP, PeriphClkInit->PLLI2S.PLLI2SQ, PeriphClkInit->PLLI2S.PLLI2SR);
540 }
541
542 /* Enable the PLLI2S */
543 __HAL_RCC_PLLI2S_ENABLE();
544
545 /* Get Start Tick*/
546 tickstart = HAL_GetTick();
547
548 /* Wait till PLLI2S is ready */
549 while(__HAL_RCC_GET_FLAG(RCC_FLAG_PLLI2SRDY) == RESET)
550 {
551 if((HAL_GetTick() - tickstart) > PLLI2S_TIMEOUT_VALUE)
552 {
553 /* return in case of Timeout detected */
554 return HAL_TIMEOUT;
555 }
556 }
557 }
558
559 /*-------------------------------------- PLLSAI Configuration ---------------------------------*/
560 /* PLLSAI is configured when a peripheral will use it as source clock : SAI1, SAI2, LTDC or CK48 */
561 if(pllsaiused == 1)
562 {
563 /* Disable PLLSAI Clock */
564 __HAL_RCC_PLLSAI_DISABLE();
565
566 /* Get Start Tick*/
567 tickstart = HAL_GetTick();
568
569 /* Wait till PLLSAI is disabled */
570 while(__HAL_RCC_PLLSAI_GET_FLAG() != RESET)
571 {
572 if((HAL_GetTick() - tickstart) > PLLSAI_TIMEOUT_VALUE)
573 {
574 /* return in case of Timeout detected */
575 return HAL_TIMEOUT;
576 }
577 }
578
579 /* Check the PLLSAI division factors */
580 assert_param(IS_RCC_PLLSAIN_VALUE(PeriphClkInit->PLLSAI.PLLSAIN));
581
582 /*----------------- In Case of PLLSAI is selected as source clock for SAI -------------------*/
583 if(((((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_SAI1) == RCC_PERIPHCLK_SAI1) && (PeriphClkInit->Sai1ClockSelection == RCC_SAI1CLKSOURCE_PLLSAI)) ||\
584 ((((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_SAI2) == RCC_PERIPHCLK_SAI2) && (PeriphClkInit->Sai2ClockSelection == RCC_SAI2CLKSOURCE_PLLSAI)))
585 {
586 /* check for PLLSAIQ Parameter */
587 assert_param(IS_RCC_PLLSAIQ_VALUE(PeriphClkInit->PLLSAI.PLLSAIQ));
588 /* check for PLLSAI/DIVQ Parameter */
589 assert_param(IS_RCC_PLLSAI_DIVQ_VALUE(PeriphClkInit->PLLSAIDivQ));
590
591 /* Read PLLSAIP value from PLLSAICFGR register (this value is not needed for SAI configuration) */
592 tmpreg0 = ((RCC->PLLSAICFGR & RCC_PLLSAICFGR_PLLSAIP) >> RCC_PLLSAICFGR_PLLSAIP_Pos);
593 tmpreg1 = ((RCC->PLLSAICFGR & RCC_PLLI2SCFGR_PLLI2SR) >> RCC_PLLSAICFGR_PLLSAIR_Pos);
594 /* PLLSAI_VCO Input = PLL_SOURCE/PLLM */
595 /* PLLSAI_VCO Output = PLLSAI_VCO Input * PLLSAIN */
596 /* SAI_CLK(first level) = PLLSAI_VCO Output/PLLSAIQ */
597 __HAL_RCC_PLLSAI_CONFIG(PeriphClkInit->PLLSAI.PLLSAIN , tmpreg0, PeriphClkInit->PLLSAI.PLLSAIQ, tmpreg1);
598
599 /* SAI_CLK_x = SAI_CLK(first level)/PLLSAIDIVQ */
600 __HAL_RCC_PLLSAI_PLLSAICLKDIVQ_CONFIG(PeriphClkInit->PLLSAIDivQ);
601 }
602
603 /*----------------- In Case of PLLSAI is selected as source clock for CLK48 -------------------*/
604 /* In Case of PLLI2S is selected as source clock for CK48 */
605 if((((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_CLK48) == RCC_PERIPHCLK_CLK48) && (PeriphClkInit->Clk48ClockSelection == RCC_CLK48SOURCE_PLLSAIP))
606 {
607 /* check for Parameters */
608 assert_param(IS_RCC_PLLSAIP_VALUE(PeriphClkInit->PLLSAI.PLLSAIP));
609 /* Read PLLSAIQ and PLLSAIR value from PLLSAICFGR register (this value is not needed for CK48 configuration) */
610 tmpreg0 = ((RCC->PLLSAICFGR & RCC_PLLSAICFGR_PLLSAIQ) >> RCC_PLLSAICFGR_PLLSAIQ_Pos);
611 tmpreg1 = ((RCC->PLLSAICFGR & RCC_PLLSAICFGR_PLLSAIR) >> RCC_PLLSAICFGR_PLLSAIR_Pos);
612
613 /* Configure the PLLSAI division factors */
614 /* PLLSAI_VCO = f(VCO clock) = f(PLLSAI clock input) x (PLLI2SN/PLLM) */
615 /* 48CLK = f(PLLSAI clock output) = f(VCO clock) / PLLSAIP */
616 __HAL_RCC_PLLSAI_CONFIG(PeriphClkInit->PLLSAI.PLLSAIN , PeriphClkInit->PLLSAI.PLLSAIP, tmpreg0, tmpreg1);
617 }
618
619 #if defined(STM32F746xx) || defined(STM32F756xx) || defined (STM32F767xx) || defined (STM32F769xx) || defined (STM32F777xx) || defined (STM32F779xx) || defined (STM32F750xx)
620 /*---------------------------- LTDC configuration -------------------------------*/
621 if(((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_LTDC) == (RCC_PERIPHCLK_LTDC))
622 {
623 assert_param(IS_RCC_PLLSAIR_VALUE(PeriphClkInit->PLLSAI.PLLSAIR));
624 assert_param(IS_RCC_PLLSAI_DIVR_VALUE(PeriphClkInit->PLLSAIDivR));
625
626 /* Read PLLSAIP and PLLSAIQ value from PLLSAICFGR register (these value are not needed for LTDC configuration) */
627 tmpreg0 = ((RCC->PLLSAICFGR & RCC_PLLSAICFGR_PLLSAIQ) >> RCC_PLLSAICFGR_PLLSAIQ_Pos);
628 tmpreg1 = ((RCC->PLLSAICFGR & RCC_PLLSAICFGR_PLLSAIP) >> RCC_PLLSAICFGR_PLLSAIP_Pos);
629
630 /* PLLSAI_VCO Input = PLL_SOURCE/PLLM */
631 /* PLLSAI_VCO Output = PLLSAI_VCO Input * PLLSAIN */
632 /* LTDC_CLK(first level) = PLLSAI_VCO Output/PLLSAIR */
633 __HAL_RCC_PLLSAI_CONFIG(PeriphClkInit->PLLSAI.PLLSAIN , tmpreg1, tmpreg0, PeriphClkInit->PLLSAI.PLLSAIR);
634
635 /* LTDC_CLK = LTDC_CLK(first level)/PLLSAIDIVR */
636 __HAL_RCC_PLLSAI_PLLSAICLKDIVR_CONFIG(PeriphClkInit->PLLSAIDivR);
637 }
638 #endif /* STM32F746xx || STM32F756xx || STM32F767xx || STM32F769xx || STM32F777xx || STM32F779xx || STM32F750xx */
639
640 /* Enable PLLSAI Clock */
641 __HAL_RCC_PLLSAI_ENABLE();
642
643 /* Get Start Tick*/
644 tickstart = HAL_GetTick();
645
646 /* Wait till PLLSAI is ready */
647 while(__HAL_RCC_PLLSAI_GET_FLAG() == RESET)
648 {
649 if((HAL_GetTick() - tickstart) > PLLSAI_TIMEOUT_VALUE)
650 {
651 /* return in case of Timeout detected */
652 return HAL_TIMEOUT;
653 }
654 }
655 }
656 return HAL_OK;
657 }
658
659 /**
660 * @brief Get the RCC_PeriphCLKInitTypeDef according to the internal
661 * RCC configuration registers.
662 * @param PeriphClkInit pointer to the configured RCC_PeriphCLKInitTypeDef structure
663 * @retval None
664 */
HAL_RCCEx_GetPeriphCLKConfig(RCC_PeriphCLKInitTypeDef * PeriphClkInit)665 void HAL_RCCEx_GetPeriphCLKConfig(RCC_PeriphCLKInitTypeDef *PeriphClkInit)
666 {
667 uint32_t tempreg = 0;
668
669 /* Set all possible values for the extended clock type parameter------------*/
670 #if defined (STM32F765xx) || defined (STM32F767xx) || defined (STM32F769xx) || defined (STM32F777xx) || defined (STM32F779xx)
671 PeriphClkInit->PeriphClockSelection = RCC_PERIPHCLK_I2S | RCC_PERIPHCLK_LPTIM1 |\
672 RCC_PERIPHCLK_SAI1 | RCC_PERIPHCLK_SAI2 |\
673 RCC_PERIPHCLK_TIM | RCC_PERIPHCLK_RTC |\
674 RCC_PERIPHCLK_CEC | RCC_PERIPHCLK_I2C4 |\
675 RCC_PERIPHCLK_I2C1 | RCC_PERIPHCLK_I2C2 |\
676 RCC_PERIPHCLK_I2C3 | RCC_PERIPHCLK_USART1 |\
677 RCC_PERIPHCLK_USART2 | RCC_PERIPHCLK_USART3 |\
678 RCC_PERIPHCLK_UART4 | RCC_PERIPHCLK_UART5 |\
679 RCC_PERIPHCLK_USART6 | RCC_PERIPHCLK_UART7 |\
680 RCC_PERIPHCLK_UART8 | RCC_PERIPHCLK_SDMMC1 |\
681 RCC_PERIPHCLK_CLK48 | RCC_PERIPHCLK_SDMMC2 |\
682 RCC_PERIPHCLK_DFSDM1 | RCC_PERIPHCLK_DFSDM1_AUDIO;
683 #else
684 PeriphClkInit->PeriphClockSelection = RCC_PERIPHCLK_I2S | RCC_PERIPHCLK_LPTIM1 |\
685 RCC_PERIPHCLK_SAI1 | RCC_PERIPHCLK_SAI2 |\
686 RCC_PERIPHCLK_TIM | RCC_PERIPHCLK_RTC |\
687 RCC_PERIPHCLK_CEC | RCC_PERIPHCLK_I2C4 |\
688 RCC_PERIPHCLK_I2C1 | RCC_PERIPHCLK_I2C2 |\
689 RCC_PERIPHCLK_I2C3 | RCC_PERIPHCLK_USART1 |\
690 RCC_PERIPHCLK_USART2 | RCC_PERIPHCLK_USART3 |\
691 RCC_PERIPHCLK_UART4 | RCC_PERIPHCLK_UART5 |\
692 RCC_PERIPHCLK_USART6 | RCC_PERIPHCLK_UART7 |\
693 RCC_PERIPHCLK_UART8 | RCC_PERIPHCLK_SDMMC1 |\
694 RCC_PERIPHCLK_CLK48;
695 #endif /* STM32F767xx || STM32F769xx || STM32F777xx || STM32F779xx */
696
697 /* Get the PLLI2S Clock configuration -----------------------------------------------*/
698 PeriphClkInit->PLLI2S.PLLI2SN = (uint32_t)((RCC->PLLI2SCFGR & RCC_PLLI2SCFGR_PLLI2SN) >> RCC_PLLI2SCFGR_PLLI2SN_Pos);
699 PeriphClkInit->PLLI2S.PLLI2SP = (uint32_t)((RCC->PLLI2SCFGR & RCC_PLLI2SCFGR_PLLI2SP) >> RCC_PLLI2SCFGR_PLLI2SP_Pos);
700 PeriphClkInit->PLLI2S.PLLI2SQ = (uint32_t)((RCC->PLLI2SCFGR & RCC_PLLI2SCFGR_PLLI2SQ) >> RCC_PLLI2SCFGR_PLLI2SQ_Pos);
701 PeriphClkInit->PLLI2S.PLLI2SR = (uint32_t)((RCC->PLLI2SCFGR & RCC_PLLI2SCFGR_PLLI2SR) >> RCC_PLLI2SCFGR_PLLI2SR_Pos);
702
703 /* Get the PLLSAI Clock configuration -----------------------------------------------*/
704 PeriphClkInit->PLLSAI.PLLSAIN = (uint32_t)((RCC->PLLSAICFGR & RCC_PLLSAICFGR_PLLSAIN) >> RCC_PLLSAICFGR_PLLSAIN_Pos);
705 PeriphClkInit->PLLSAI.PLLSAIP = (uint32_t)((RCC->PLLSAICFGR & RCC_PLLSAICFGR_PLLSAIP) >> RCC_PLLSAICFGR_PLLSAIP_Pos);
706 PeriphClkInit->PLLSAI.PLLSAIQ = (uint32_t)((RCC->PLLSAICFGR & RCC_PLLSAICFGR_PLLSAIQ) >> RCC_PLLSAICFGR_PLLSAIQ_Pos);
707 PeriphClkInit->PLLSAI.PLLSAIR = (uint32_t)((RCC->PLLSAICFGR & RCC_PLLSAICFGR_PLLSAIR) >> RCC_PLLSAICFGR_PLLSAIR_Pos);
708
709 /* Get the PLLSAI/PLLI2S division factors -------------------------------------------*/
710 PeriphClkInit->PLLI2SDivQ = (uint32_t)((RCC->DCKCFGR1 & RCC_DCKCFGR1_PLLI2SDIVQ) >> RCC_DCKCFGR1_PLLI2SDIVQ_Pos);
711 PeriphClkInit->PLLSAIDivQ = (uint32_t)((RCC->DCKCFGR1 & RCC_DCKCFGR1_PLLSAIDIVQ) >> RCC_DCKCFGR1_PLLSAIDIVQ_Pos);
712 PeriphClkInit->PLLSAIDivR = (uint32_t)((RCC->DCKCFGR1 & RCC_DCKCFGR1_PLLSAIDIVR) >> RCC_DCKCFGR1_PLLSAIDIVR_Pos);
713
714 /* Get the SAI1 clock configuration ----------------------------------------------*/
715 PeriphClkInit->Sai1ClockSelection = __HAL_RCC_GET_SAI1_SOURCE();
716
717 /* Get the SAI2 clock configuration ----------------------------------------------*/
718 PeriphClkInit->Sai2ClockSelection = __HAL_RCC_GET_SAI2_SOURCE();
719
720 /* Get the I2S clock configuration ------------------------------------------*/
721 PeriphClkInit->I2sClockSelection = __HAL_RCC_GET_I2SCLKSOURCE();
722
723 /* Get the I2C1 clock configuration ------------------------------------------*/
724 PeriphClkInit->I2c1ClockSelection = __HAL_RCC_GET_I2C1_SOURCE();
725
726 /* Get the I2C2 clock configuration ------------------------------------------*/
727 PeriphClkInit->I2c2ClockSelection = __HAL_RCC_GET_I2C2_SOURCE();
728
729 /* Get the I2C3 clock configuration ------------------------------------------*/
730 PeriphClkInit->I2c3ClockSelection = __HAL_RCC_GET_I2C3_SOURCE();
731
732 /* Get the I2C4 clock configuration ------------------------------------------*/
733 PeriphClkInit->I2c4ClockSelection = __HAL_RCC_GET_I2C4_SOURCE();
734
735 /* Get the USART1 clock configuration ------------------------------------------*/
736 PeriphClkInit->Usart1ClockSelection = __HAL_RCC_GET_USART1_SOURCE();
737
738 /* Get the USART2 clock configuration ------------------------------------------*/
739 PeriphClkInit->Usart2ClockSelection = __HAL_RCC_GET_USART2_SOURCE();
740
741 /* Get the USART3 clock configuration ------------------------------------------*/
742 PeriphClkInit->Usart3ClockSelection = __HAL_RCC_GET_USART3_SOURCE();
743
744 /* Get the UART4 clock configuration ------------------------------------------*/
745 PeriphClkInit->Uart4ClockSelection = __HAL_RCC_GET_UART4_SOURCE();
746
747 /* Get the UART5 clock configuration ------------------------------------------*/
748 PeriphClkInit->Uart5ClockSelection = __HAL_RCC_GET_UART5_SOURCE();
749
750 /* Get the USART6 clock configuration ------------------------------------------*/
751 PeriphClkInit->Usart6ClockSelection = __HAL_RCC_GET_USART6_SOURCE();
752
753 /* Get the UART7 clock configuration ------------------------------------------*/
754 PeriphClkInit->Uart7ClockSelection = __HAL_RCC_GET_UART7_SOURCE();
755
756 /* Get the UART8 clock configuration ------------------------------------------*/
757 PeriphClkInit->Uart8ClockSelection = __HAL_RCC_GET_UART8_SOURCE();
758
759 /* Get the LPTIM1 clock configuration ------------------------------------------*/
760 PeriphClkInit->Lptim1ClockSelection = __HAL_RCC_GET_LPTIM1_SOURCE();
761
762 /* Get the CEC clock configuration -----------------------------------------------*/
763 PeriphClkInit->CecClockSelection = __HAL_RCC_GET_CEC_SOURCE();
764
765 /* Get the CK48 clock configuration -----------------------------------------------*/
766 PeriphClkInit->Clk48ClockSelection = __HAL_RCC_GET_CLK48_SOURCE();
767
768 /* Get the SDMMC1 clock configuration -----------------------------------------------*/
769 PeriphClkInit->Sdmmc1ClockSelection = __HAL_RCC_GET_SDMMC1_SOURCE();
770
771 #if defined (STM32F765xx) || defined (STM32F767xx) || defined (STM32F769xx) || defined (STM32F777xx) || defined (STM32F779xx)
772 /* Get the SDMMC2 clock configuration -----------------------------------------------*/
773 PeriphClkInit->Sdmmc2ClockSelection = __HAL_RCC_GET_SDMMC2_SOURCE();
774
775 /* Get the DFSDM clock configuration -----------------------------------------------*/
776 PeriphClkInit->Dfsdm1ClockSelection = __HAL_RCC_GET_DFSDM1_SOURCE();
777
778 /* Get the DFSDM AUDIO clock configuration -----------------------------------------------*/
779 PeriphClkInit->Dfsdm1AudioClockSelection = __HAL_RCC_GET_DFSDM1AUDIO_SOURCE();
780 #endif /* STM32F767xx || STM32F769xx || STM32F777xx || STM32F779xx */
781
782 /* Get the RTC Clock configuration -----------------------------------------------*/
783 tempreg = (RCC->CFGR & RCC_CFGR_RTCPRE);
784 PeriphClkInit->RTCClockSelection = (uint32_t)((tempreg) | (RCC->BDCR & RCC_BDCR_RTCSEL));
785
786 /* Get the TIM Prescaler configuration --------------------------------------------*/
787 if ((RCC->DCKCFGR1 & RCC_DCKCFGR1_TIMPRE) == RESET)
788 {
789 PeriphClkInit->TIMPresSelection = RCC_TIMPRES_DESACTIVATED;
790 }
791 else
792 {
793 PeriphClkInit->TIMPresSelection = RCC_TIMPRES_ACTIVATED;
794 }
795 }
796 #endif /* STM32F745xx || STM32F746xx || STM32F756xx || STM32F765xx || STM32F767xx || STM32F769xx || STM32F777xx || STM32F779xx || STM32F750xx */
797
798 #if defined (STM32F722xx) || defined (STM32F723xx) || defined (STM32F732xx) || defined (STM32F733xx) || defined (STM32F730xx)
799 /**
800 * @brief Initializes the RCC extended peripherals clocks according to the specified
801 * parameters in the RCC_PeriphCLKInitTypeDef.
802 * @param PeriphClkInit pointer to an RCC_PeriphCLKInitTypeDef structure that
803 * contains the configuration information for the Extended Peripherals
804 * clocks(I2S, SAI, RTC, TIM, UARTs, USARTs, LTPIM, SDMMC...).
805 *
806 * @note Care must be taken when HAL_RCCEx_PeriphCLKConfig() is used to select
807 * the RTC clock source; in this case the Backup domain will be reset in
808 * order to modify the RTC Clock source, as consequence RTC registers (including
809 * the backup registers) are set to their reset values.
810 *
811 * @retval HAL status
812 */
HAL_RCCEx_PeriphCLKConfig(RCC_PeriphCLKInitTypeDef * PeriphClkInit)813 HAL_StatusTypeDef HAL_RCCEx_PeriphCLKConfig(RCC_PeriphCLKInitTypeDef *PeriphClkInit)
814 {
815 uint32_t tickstart = 0;
816 uint32_t tmpreg0 = 0;
817 uint32_t plli2sused = 0;
818 uint32_t pllsaiused = 0;
819
820 /* Check the parameters */
821 assert_param(IS_RCC_PERIPHCLOCK(PeriphClkInit->PeriphClockSelection));
822
823 /*----------------------------------- I2S configuration ----------------------------------*/
824 if(((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_I2S) == (RCC_PERIPHCLK_I2S))
825 {
826 /* Check the parameters */
827 assert_param(IS_RCC_I2SCLKSOURCE(PeriphClkInit->I2sClockSelection));
828
829 /* Configure I2S Clock source */
830 __HAL_RCC_I2S_CONFIG(PeriphClkInit->I2sClockSelection);
831
832 /* Enable the PLLI2S when it's used as clock source for I2S */
833 if(PeriphClkInit->I2sClockSelection == RCC_I2SCLKSOURCE_PLLI2S)
834 {
835 plli2sused = 1;
836 }
837 }
838
839 /*------------------------------------ SAI1 configuration --------------------------------------*/
840 if(((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_SAI1) == (RCC_PERIPHCLK_SAI1))
841 {
842 /* Check the parameters */
843 assert_param(IS_RCC_SAI1CLKSOURCE(PeriphClkInit->Sai1ClockSelection));
844
845 /* Configure SAI1 Clock source */
846 __HAL_RCC_SAI1_CONFIG(PeriphClkInit->Sai1ClockSelection);
847 /* Enable the PLLI2S when it's used as clock source for SAI */
848 if(PeriphClkInit->Sai1ClockSelection == RCC_SAI1CLKSOURCE_PLLI2S)
849 {
850 plli2sused = 1;
851 }
852 /* Enable the PLLSAI when it's used as clock source for SAI */
853 if(PeriphClkInit->Sai1ClockSelection == RCC_SAI1CLKSOURCE_PLLSAI)
854 {
855 pllsaiused = 1;
856 }
857 }
858
859 /*------------------------------------ SAI2 configuration --------------------------------------*/
860 if(((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_SAI2) == (RCC_PERIPHCLK_SAI2))
861 {
862 /* Check the parameters */
863 assert_param(IS_RCC_SAI2CLKSOURCE(PeriphClkInit->Sai2ClockSelection));
864
865 /* Configure SAI2 Clock source */
866 __HAL_RCC_SAI2_CONFIG(PeriphClkInit->Sai2ClockSelection);
867
868 /* Enable the PLLI2S when it's used as clock source for SAI */
869 if(PeriphClkInit->Sai2ClockSelection == RCC_SAI2CLKSOURCE_PLLI2S)
870 {
871 plli2sused = 1;
872 }
873 /* Enable the PLLSAI when it's used as clock source for SAI */
874 if(PeriphClkInit->Sai2ClockSelection == RCC_SAI2CLKSOURCE_PLLSAI)
875 {
876 pllsaiused = 1;
877 }
878 }
879
880 /*------------------------------------ RTC configuration --------------------------------------*/
881 if(((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_RTC) == (RCC_PERIPHCLK_RTC))
882 {
883 /* Check for RTC Parameters used to output RTCCLK */
884 assert_param(IS_RCC_RTCCLKSOURCE(PeriphClkInit->RTCClockSelection));
885
886 /* Enable Power Clock*/
887 __HAL_RCC_PWR_CLK_ENABLE();
888
889 /* Enable write access to Backup domain */
890 PWR->CR1 |= PWR_CR1_DBP;
891
892 /* Get Start Tick*/
893 tickstart = HAL_GetTick();
894
895 /* Wait for Backup domain Write protection disable */
896 while((PWR->CR1 & PWR_CR1_DBP) == RESET)
897 {
898 if((HAL_GetTick() - tickstart) > RCC_DBP_TIMEOUT_VALUE)
899 {
900 return HAL_TIMEOUT;
901 }
902 }
903
904 /* Reset the Backup domain only if the RTC Clock source selection is modified */
905 tmpreg0 = (RCC->BDCR & RCC_BDCR_RTCSEL);
906
907 if((tmpreg0 != 0x00000000U) && (tmpreg0 != (PeriphClkInit->RTCClockSelection & RCC_BDCR_RTCSEL)))
908 {
909 /* Store the content of BDCR register before the reset of Backup Domain */
910 tmpreg0 = (RCC->BDCR & ~(RCC_BDCR_RTCSEL));
911
912 /* RTC Clock selection can be changed only if the Backup Domain is reset */
913 __HAL_RCC_BACKUPRESET_FORCE();
914 __HAL_RCC_BACKUPRESET_RELEASE();
915
916 /* Restore the Content of BDCR register */
917 RCC->BDCR = tmpreg0;
918
919 /* Wait for LSE reactivation if LSE was enable prior to Backup Domain reset */
920 if (HAL_IS_BIT_SET(RCC->BDCR, RCC_BDCR_LSEON))
921 {
922 /* Get Start Tick*/
923 tickstart = HAL_GetTick();
924
925 /* Wait till LSE is ready */
926 while(__HAL_RCC_GET_FLAG(RCC_FLAG_LSERDY) == RESET)
927 {
928 if((HAL_GetTick() - tickstart ) > RCC_LSE_TIMEOUT_VALUE)
929 {
930 return HAL_TIMEOUT;
931 }
932 }
933 }
934 }
935 __HAL_RCC_RTC_CONFIG(PeriphClkInit->RTCClockSelection);
936 }
937
938 /*------------------------------------ TIM configuration --------------------------------------*/
939 if(((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_TIM) == (RCC_PERIPHCLK_TIM))
940 {
941 /* Check the parameters */
942 assert_param(IS_RCC_TIMPRES(PeriphClkInit->TIMPresSelection));
943
944 /* Configure Timer Prescaler */
945 __HAL_RCC_TIMCLKPRESCALER(PeriphClkInit->TIMPresSelection);
946 }
947
948 /*-------------------------------------- I2C1 Configuration -----------------------------------*/
949 if(((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_I2C1) == RCC_PERIPHCLK_I2C1)
950 {
951 /* Check the parameters */
952 assert_param(IS_RCC_I2C1CLKSOURCE(PeriphClkInit->I2c1ClockSelection));
953
954 /* Configure the I2C1 clock source */
955 __HAL_RCC_I2C1_CONFIG(PeriphClkInit->I2c1ClockSelection);
956 }
957
958 /*-------------------------------------- I2C2 Configuration -----------------------------------*/
959 if(((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_I2C2) == RCC_PERIPHCLK_I2C2)
960 {
961 /* Check the parameters */
962 assert_param(IS_RCC_I2C2CLKSOURCE(PeriphClkInit->I2c2ClockSelection));
963
964 /* Configure the I2C2 clock source */
965 __HAL_RCC_I2C2_CONFIG(PeriphClkInit->I2c2ClockSelection);
966 }
967
968 /*-------------------------------------- I2C3 Configuration -----------------------------------*/
969 if(((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_I2C3) == RCC_PERIPHCLK_I2C3)
970 {
971 /* Check the parameters */
972 assert_param(IS_RCC_I2C3CLKSOURCE(PeriphClkInit->I2c3ClockSelection));
973
974 /* Configure the I2C3 clock source */
975 __HAL_RCC_I2C3_CONFIG(PeriphClkInit->I2c3ClockSelection);
976 }
977
978 /*-------------------------------------- USART1 Configuration -----------------------------------*/
979 if(((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_USART1) == RCC_PERIPHCLK_USART1)
980 {
981 /* Check the parameters */
982 assert_param(IS_RCC_USART1CLKSOURCE(PeriphClkInit->Usart1ClockSelection));
983
984 /* Configure the USART1 clock source */
985 __HAL_RCC_USART1_CONFIG(PeriphClkInit->Usart1ClockSelection);
986 }
987
988 /*-------------------------------------- USART2 Configuration -----------------------------------*/
989 if(((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_USART2) == RCC_PERIPHCLK_USART2)
990 {
991 /* Check the parameters */
992 assert_param(IS_RCC_USART2CLKSOURCE(PeriphClkInit->Usart2ClockSelection));
993
994 /* Configure the USART2 clock source */
995 __HAL_RCC_USART2_CONFIG(PeriphClkInit->Usart2ClockSelection);
996 }
997
998 /*-------------------------------------- USART3 Configuration -----------------------------------*/
999 if(((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_USART3) == RCC_PERIPHCLK_USART3)
1000 {
1001 /* Check the parameters */
1002 assert_param(IS_RCC_USART3CLKSOURCE(PeriphClkInit->Usart3ClockSelection));
1003
1004 /* Configure the USART3 clock source */
1005 __HAL_RCC_USART3_CONFIG(PeriphClkInit->Usart3ClockSelection);
1006 }
1007
1008 /*-------------------------------------- UART4 Configuration -----------------------------------*/
1009 if(((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_UART4) == RCC_PERIPHCLK_UART4)
1010 {
1011 /* Check the parameters */
1012 assert_param(IS_RCC_UART4CLKSOURCE(PeriphClkInit->Uart4ClockSelection));
1013
1014 /* Configure the UART4 clock source */
1015 __HAL_RCC_UART4_CONFIG(PeriphClkInit->Uart4ClockSelection);
1016 }
1017
1018 /*-------------------------------------- UART5 Configuration -----------------------------------*/
1019 if(((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_UART5) == RCC_PERIPHCLK_UART5)
1020 {
1021 /* Check the parameters */
1022 assert_param(IS_RCC_UART5CLKSOURCE(PeriphClkInit->Uart5ClockSelection));
1023
1024 /* Configure the UART5 clock source */
1025 __HAL_RCC_UART5_CONFIG(PeriphClkInit->Uart5ClockSelection);
1026 }
1027
1028 /*-------------------------------------- USART6 Configuration -----------------------------------*/
1029 if(((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_USART6) == RCC_PERIPHCLK_USART6)
1030 {
1031 /* Check the parameters */
1032 assert_param(IS_RCC_USART6CLKSOURCE(PeriphClkInit->Usart6ClockSelection));
1033
1034 /* Configure the USART6 clock source */
1035 __HAL_RCC_USART6_CONFIG(PeriphClkInit->Usart6ClockSelection);
1036 }
1037
1038 /*-------------------------------------- UART7 Configuration -----------------------------------*/
1039 if(((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_UART7) == RCC_PERIPHCLK_UART7)
1040 {
1041 /* Check the parameters */
1042 assert_param(IS_RCC_UART7CLKSOURCE(PeriphClkInit->Uart7ClockSelection));
1043
1044 /* Configure the UART7 clock source */
1045 __HAL_RCC_UART7_CONFIG(PeriphClkInit->Uart7ClockSelection);
1046 }
1047
1048 /*-------------------------------------- UART8 Configuration -----------------------------------*/
1049 if(((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_UART8) == RCC_PERIPHCLK_UART8)
1050 {
1051 /* Check the parameters */
1052 assert_param(IS_RCC_UART8CLKSOURCE(PeriphClkInit->Uart8ClockSelection));
1053
1054 /* Configure the UART8 clock source */
1055 __HAL_RCC_UART8_CONFIG(PeriphClkInit->Uart8ClockSelection);
1056 }
1057
1058 /*-------------------------------------- CK48 Configuration -----------------------------------*/
1059 if(((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_CLK48) == RCC_PERIPHCLK_CLK48)
1060 {
1061 /* Check the parameters */
1062 assert_param(IS_RCC_CLK48SOURCE(PeriphClkInit->Clk48ClockSelection));
1063
1064 /* Configure the CLK48 source */
1065 __HAL_RCC_CLK48_CONFIG(PeriphClkInit->Clk48ClockSelection);
1066
1067 /* Enable the PLLSAI when it's used as clock source for CK48 */
1068 if(PeriphClkInit->Clk48ClockSelection == RCC_CLK48SOURCE_PLLSAIP)
1069 {
1070 pllsaiused = 1;
1071 }
1072 }
1073
1074 /*-------------------------------------- LPTIM1 Configuration -----------------------------------*/
1075 if(((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_LPTIM1) == RCC_PERIPHCLK_LPTIM1)
1076 {
1077 /* Check the parameters */
1078 assert_param(IS_RCC_LPTIM1CLK(PeriphClkInit->Lptim1ClockSelection));
1079
1080 /* Configure the LTPIM1 clock source */
1081 __HAL_RCC_LPTIM1_CONFIG(PeriphClkInit->Lptim1ClockSelection);
1082 }
1083
1084 /*------------------------------------- SDMMC1 Configuration ------------------------------------*/
1085 if(((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_SDMMC1) == RCC_PERIPHCLK_SDMMC1)
1086 {
1087 /* Check the parameters */
1088 assert_param(IS_RCC_SDMMC1CLKSOURCE(PeriphClkInit->Sdmmc1ClockSelection));
1089
1090 /* Configure the SDMMC1 clock source */
1091 __HAL_RCC_SDMMC1_CONFIG(PeriphClkInit->Sdmmc1ClockSelection);
1092 }
1093
1094 /*------------------------------------- SDMMC2 Configuration ------------------------------------*/
1095 if(((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_SDMMC2) == RCC_PERIPHCLK_SDMMC2)
1096 {
1097 /* Check the parameters */
1098 assert_param(IS_RCC_SDMMC2CLKSOURCE(PeriphClkInit->Sdmmc2ClockSelection));
1099
1100 /* Configure the SDMMC2 clock source */
1101 __HAL_RCC_SDMMC2_CONFIG(PeriphClkInit->Sdmmc2ClockSelection);
1102 }
1103
1104 /*-------------------------------------- PLLI2S Configuration ---------------------------------*/
1105 /* PLLI2S is configured when a peripheral will use it as source clock : SAI1, SAI2 or I2S */
1106 if((plli2sused == 1) || ((PeriphClkInit->PeriphClockSelection & RCC_PERIPHCLK_PLLI2S) == RCC_PERIPHCLK_PLLI2S))
1107 {
1108 /* Disable the PLLI2S */
1109 __HAL_RCC_PLLI2S_DISABLE();
1110
1111 /* Get Start Tick*/
1112 tickstart = HAL_GetTick();
1113
1114 /* Wait till PLLI2S is disabled */
1115 while(__HAL_RCC_GET_FLAG(RCC_FLAG_PLLI2SRDY) != RESET)
1116 {
1117 if((HAL_GetTick() - tickstart) > PLLI2S_TIMEOUT_VALUE)
1118 {
1119 /* return in case of Timeout detected */
1120 return HAL_TIMEOUT;
1121 }
1122 }
1123
1124 /* check for common PLLI2S Parameters */
1125 assert_param(IS_RCC_PLLI2SN_VALUE(PeriphClkInit->PLLI2S.PLLI2SN));
1126
1127 /*----------------- In Case of PLLI2S is selected as source clock for I2S -------------------*/
1128 if(((((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_I2S) == RCC_PERIPHCLK_I2S) && (PeriphClkInit->I2sClockSelection == RCC_I2SCLKSOURCE_PLLI2S)))
1129 {
1130 /* check for Parameters */
1131 assert_param(IS_RCC_PLLI2SR_VALUE(PeriphClkInit->PLLI2S.PLLI2SR));
1132
1133 /* Read PLLI2SQ value from PLLI2SCFGR register (this value is not needed for I2S configuration) */
1134 tmpreg0 = ((RCC->PLLI2SCFGR & RCC_PLLI2SCFGR_PLLI2SQ) >> RCC_PLLI2SCFGR_PLLI2SQ_Pos);
1135 /* Configure the PLLI2S division factors */
1136 /* PLLI2S_VCO = f(VCO clock) = f(PLLI2S clock input) x (PLLI2SN/PLLM) */
1137 /* I2SCLK = f(PLLI2S clock output) = f(VCO clock) / PLLI2SR */
1138 __HAL_RCC_PLLI2S_CONFIG(PeriphClkInit->PLLI2S.PLLI2SN , tmpreg0, PeriphClkInit->PLLI2S.PLLI2SR);
1139 }
1140
1141 /*----------------- In Case of PLLI2S is selected as source clock for SAI -------------------*/
1142 if(((((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_SAI1) == RCC_PERIPHCLK_SAI1) && (PeriphClkInit->Sai1ClockSelection == RCC_SAI1CLKSOURCE_PLLI2S)) ||
1143 ((((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_SAI2) == RCC_PERIPHCLK_SAI2) && (PeriphClkInit->Sai2ClockSelection == RCC_SAI2CLKSOURCE_PLLI2S)))
1144 {
1145 /* Check for PLLI2S Parameters */
1146 assert_param(IS_RCC_PLLI2SQ_VALUE(PeriphClkInit->PLLI2S.PLLI2SQ));
1147 /* Check for PLLI2S/DIVQ parameters */
1148 assert_param(IS_RCC_PLLI2S_DIVQ_VALUE(PeriphClkInit->PLLI2SDivQ));
1149
1150 /* Read PLLI2SP and PLLI2SR values from PLLI2SCFGR register (this value is not needed for SAI configuration) */
1151 tmpreg0 = ((RCC->PLLI2SCFGR & RCC_PLLI2SCFGR_PLLI2SR) >> RCC_PLLI2SCFGR_PLLI2SR_Pos);
1152 /* Configure the PLLI2S division factors */
1153 /* PLLI2S_VCO Input = PLL_SOURCE/PLLM */
1154 /* PLLI2S_VCO Output = PLLI2S_VCO Input * PLLI2SN */
1155 /* SAI_CLK(first level) = PLLI2S_VCO Output/PLLI2SQ */
1156 __HAL_RCC_PLLI2S_CONFIG(PeriphClkInit->PLLI2S.PLLI2SN, PeriphClkInit->PLLI2S.PLLI2SQ, tmpreg0);
1157
1158 /* SAI_CLK_x = SAI_CLK(first level)/PLLI2SDIVQ */
1159 __HAL_RCC_PLLI2S_PLLSAICLKDIVQ_CONFIG(PeriphClkInit->PLLI2SDivQ);
1160 }
1161
1162 /*----------------- In Case of PLLI2S is just selected -----------------*/
1163 if((PeriphClkInit->PeriphClockSelection & RCC_PERIPHCLK_PLLI2S) == RCC_PERIPHCLK_PLLI2S)
1164 {
1165 /* Check for Parameters */
1166 assert_param(IS_RCC_PLLI2SR_VALUE(PeriphClkInit->PLLI2S.PLLI2SR));
1167 assert_param(IS_RCC_PLLI2SQ_VALUE(PeriphClkInit->PLLI2S.PLLI2SQ));
1168
1169 /* Configure the PLLI2S division factors */
1170 /* PLLI2S_VCO = f(VCO clock) = f(PLLI2S clock input) x (PLLI2SN/PLLI2SM) */
1171 __HAL_RCC_PLLI2S_CONFIG(PeriphClkInit->PLLI2S.PLLI2SN , PeriphClkInit->PLLI2S.PLLI2SQ, PeriphClkInit->PLLI2S.PLLI2SR);
1172 }
1173
1174 /* Enable the PLLI2S */
1175 __HAL_RCC_PLLI2S_ENABLE();
1176
1177 /* Get Start Tick*/
1178 tickstart = HAL_GetTick();
1179
1180 /* Wait till PLLI2S is ready */
1181 while(__HAL_RCC_GET_FLAG(RCC_FLAG_PLLI2SRDY) == RESET)
1182 {
1183 if((HAL_GetTick() - tickstart) > PLLI2S_TIMEOUT_VALUE)
1184 {
1185 /* return in case of Timeout detected */
1186 return HAL_TIMEOUT;
1187 }
1188 }
1189 }
1190
1191 /*-------------------------------------- PLLSAI Configuration ---------------------------------*/
1192 /* PLLSAI is configured when a peripheral will use it as source clock : SAI1, SAI2, LTDC or CK48 */
1193 if(pllsaiused == 1)
1194 {
1195 /* Disable PLLSAI Clock */
1196 __HAL_RCC_PLLSAI_DISABLE();
1197
1198 /* Get Start Tick*/
1199 tickstart = HAL_GetTick();
1200
1201 /* Wait till PLLSAI is disabled */
1202 while(__HAL_RCC_PLLSAI_GET_FLAG() != RESET)
1203 {
1204 if((HAL_GetTick() - tickstart) > PLLSAI_TIMEOUT_VALUE)
1205 {
1206 /* return in case of Timeout detected */
1207 return HAL_TIMEOUT;
1208 }
1209 }
1210
1211 /* Check the PLLSAI division factors */
1212 assert_param(IS_RCC_PLLSAIN_VALUE(PeriphClkInit->PLLSAI.PLLSAIN));
1213
1214 /*----------------- In Case of PLLSAI is selected as source clock for SAI -------------------*/
1215 if(((((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_SAI1) == RCC_PERIPHCLK_SAI1) && (PeriphClkInit->Sai1ClockSelection == RCC_SAI1CLKSOURCE_PLLSAI)) ||\
1216 ((((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_SAI2) == RCC_PERIPHCLK_SAI2) && (PeriphClkInit->Sai2ClockSelection == RCC_SAI2CLKSOURCE_PLLSAI)))
1217 {
1218 /* check for PLLSAIQ Parameter */
1219 assert_param(IS_RCC_PLLSAIQ_VALUE(PeriphClkInit->PLLSAI.PLLSAIQ));
1220 /* check for PLLSAI/DIVQ Parameter */
1221 assert_param(IS_RCC_PLLSAI_DIVQ_VALUE(PeriphClkInit->PLLSAIDivQ));
1222
1223 /* Read PLLSAIP value from PLLSAICFGR register (this value is not needed for SAI configuration) */
1224 tmpreg0 = ((RCC->PLLSAICFGR & RCC_PLLSAICFGR_PLLSAIP) >> RCC_PLLSAICFGR_PLLSAIP_Pos);
1225 /* PLLSAI_VCO Input = PLL_SOURCE/PLLM */
1226 /* PLLSAI_VCO Output = PLLSAI_VCO Input * PLLSAIN */
1227 /* SAI_CLK(first level) = PLLSAI_VCO Output/PLLSAIQ */
1228 __HAL_RCC_PLLSAI_CONFIG(PeriphClkInit->PLLSAI.PLLSAIN , tmpreg0, PeriphClkInit->PLLSAI.PLLSAIQ);
1229
1230 /* SAI_CLK_x = SAI_CLK(first level)/PLLSAIDIVQ */
1231 __HAL_RCC_PLLSAI_PLLSAICLKDIVQ_CONFIG(PeriphClkInit->PLLSAIDivQ);
1232 }
1233
1234 /*----------------- In Case of PLLSAI is selected as source clock for CLK48 -------------------*/
1235 /* In Case of PLLI2S is selected as source clock for CK48 */
1236 if((((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_CLK48) == RCC_PERIPHCLK_CLK48) && (PeriphClkInit->Clk48ClockSelection == RCC_CLK48SOURCE_PLLSAIP))
1237 {
1238 /* check for Parameters */
1239 assert_param(IS_RCC_PLLSAIP_VALUE(PeriphClkInit->PLLSAI.PLLSAIP));
1240 /* Read PLLSAIQ and PLLSAIR value from PLLSAICFGR register (this value is not needed for CK48 configuration) */
1241 tmpreg0 = ((RCC->PLLSAICFGR & RCC_PLLSAICFGR_PLLSAIQ) >> RCC_PLLSAICFGR_PLLSAIQ_Pos);
1242
1243 /* Configure the PLLSAI division factors */
1244 /* PLLSAI_VCO = f(VCO clock) = f(PLLSAI clock input) x (PLLI2SN/PLLM) */
1245 /* 48CLK = f(PLLSAI clock output) = f(VCO clock) / PLLSAIP */
1246 __HAL_RCC_PLLSAI_CONFIG(PeriphClkInit->PLLSAI.PLLSAIN , PeriphClkInit->PLLSAI.PLLSAIP, tmpreg0);
1247 }
1248
1249 /* Enable PLLSAI Clock */
1250 __HAL_RCC_PLLSAI_ENABLE();
1251
1252 /* Get Start Tick*/
1253 tickstart = HAL_GetTick();
1254
1255 /* Wait till PLLSAI is ready */
1256 while(__HAL_RCC_PLLSAI_GET_FLAG() == RESET)
1257 {
1258 if((HAL_GetTick() - tickstart) > PLLSAI_TIMEOUT_VALUE)
1259 {
1260 /* return in case of Timeout detected */
1261 return HAL_TIMEOUT;
1262 }
1263 }
1264 }
1265 return HAL_OK;
1266 }
1267
1268 /**
1269 * @brief Get the RCC_PeriphCLKInitTypeDef according to the internal
1270 * RCC configuration registers.
1271 * @param PeriphClkInit pointer to the configured RCC_PeriphCLKInitTypeDef structure
1272 * @retval None
1273 */
HAL_RCCEx_GetPeriphCLKConfig(RCC_PeriphCLKInitTypeDef * PeriphClkInit)1274 void HAL_RCCEx_GetPeriphCLKConfig(RCC_PeriphCLKInitTypeDef *PeriphClkInit)
1275 {
1276 uint32_t tempreg = 0;
1277
1278 /* Set all possible values for the extended clock type parameter------------*/
1279 PeriphClkInit->PeriphClockSelection = RCC_PERIPHCLK_I2S | RCC_PERIPHCLK_LPTIM1 |\
1280 RCC_PERIPHCLK_SAI1 | RCC_PERIPHCLK_SAI2 |\
1281 RCC_PERIPHCLK_TIM | RCC_PERIPHCLK_RTC |\
1282 RCC_PERIPHCLK_I2C1 | RCC_PERIPHCLK_I2C2 |\
1283 RCC_PERIPHCLK_I2C3 | RCC_PERIPHCLK_USART1 |\
1284 RCC_PERIPHCLK_USART2 | RCC_PERIPHCLK_USART3 |\
1285 RCC_PERIPHCLK_UART4 | RCC_PERIPHCLK_UART5 |\
1286 RCC_PERIPHCLK_USART6 | RCC_PERIPHCLK_UART7 |\
1287 RCC_PERIPHCLK_UART8 | RCC_PERIPHCLK_SDMMC1 |\
1288 RCC_PERIPHCLK_CLK48 | RCC_PERIPHCLK_SDMMC2;
1289
1290 /* Get the PLLI2S Clock configuration -----------------------------------------------*/
1291 PeriphClkInit->PLLI2S.PLLI2SN = (uint32_t)((RCC->PLLI2SCFGR & RCC_PLLI2SCFGR_PLLI2SN) >> RCC_PLLI2SCFGR_PLLI2SN_Pos);
1292 PeriphClkInit->PLLI2S.PLLI2SQ = (uint32_t)((RCC->PLLI2SCFGR & RCC_PLLI2SCFGR_PLLI2SQ) >> RCC_PLLI2SCFGR_PLLI2SQ_Pos);
1293 PeriphClkInit->PLLI2S.PLLI2SR = (uint32_t)((RCC->PLLI2SCFGR & RCC_PLLI2SCFGR_PLLI2SR) >> RCC_PLLI2SCFGR_PLLI2SR_Pos);
1294
1295 /* Get the PLLSAI Clock configuration -----------------------------------------------*/
1296 PeriphClkInit->PLLSAI.PLLSAIN = (uint32_t)((RCC->PLLSAICFGR & RCC_PLLSAICFGR_PLLSAIN) >> RCC_PLLSAICFGR_PLLSAIN_Pos);
1297 PeriphClkInit->PLLSAI.PLLSAIP = (uint32_t)((RCC->PLLSAICFGR & RCC_PLLSAICFGR_PLLSAIP) >> RCC_PLLSAICFGR_PLLSAIP_Pos);
1298 PeriphClkInit->PLLSAI.PLLSAIQ = (uint32_t)((RCC->PLLSAICFGR & RCC_PLLSAICFGR_PLLSAIQ) >> RCC_PLLSAICFGR_PLLSAIQ_Pos);
1299
1300 /* Get the PLLSAI/PLLI2S division factors -------------------------------------------*/
1301 PeriphClkInit->PLLI2SDivQ = (uint32_t)((RCC->DCKCFGR1 & RCC_DCKCFGR1_PLLI2SDIVQ) >> RCC_DCKCFGR1_PLLI2SDIVQ_Pos);
1302 PeriphClkInit->PLLSAIDivQ = (uint32_t)((RCC->DCKCFGR1 & RCC_DCKCFGR1_PLLSAIDIVQ) >> RCC_DCKCFGR1_PLLSAIDIVQ_Pos);
1303
1304 /* Get the SAI1 clock configuration ----------------------------------------------*/
1305 PeriphClkInit->Sai1ClockSelection = __HAL_RCC_GET_SAI1_SOURCE();
1306
1307 /* Get the SAI2 clock configuration ----------------------------------------------*/
1308 PeriphClkInit->Sai2ClockSelection = __HAL_RCC_GET_SAI2_SOURCE();
1309
1310 /* Get the I2S clock configuration ------------------------------------------*/
1311 PeriphClkInit->I2sClockSelection = __HAL_RCC_GET_I2SCLKSOURCE();
1312
1313 /* Get the I2C1 clock configuration ------------------------------------------*/
1314 PeriphClkInit->I2c1ClockSelection = __HAL_RCC_GET_I2C1_SOURCE();
1315
1316 /* Get the I2C2 clock configuration ------------------------------------------*/
1317 PeriphClkInit->I2c2ClockSelection = __HAL_RCC_GET_I2C2_SOURCE();
1318
1319 /* Get the I2C3 clock configuration ------------------------------------------*/
1320 PeriphClkInit->I2c3ClockSelection = __HAL_RCC_GET_I2C3_SOURCE();
1321
1322 /* Get the USART1 clock configuration ------------------------------------------*/
1323 PeriphClkInit->Usart1ClockSelection = __HAL_RCC_GET_USART1_SOURCE();
1324
1325 /* Get the USART2 clock configuration ------------------------------------------*/
1326 PeriphClkInit->Usart2ClockSelection = __HAL_RCC_GET_USART2_SOURCE();
1327
1328 /* Get the USART3 clock configuration ------------------------------------------*/
1329 PeriphClkInit->Usart3ClockSelection = __HAL_RCC_GET_USART3_SOURCE();
1330
1331 /* Get the UART4 clock configuration ------------------------------------------*/
1332 PeriphClkInit->Uart4ClockSelection = __HAL_RCC_GET_UART4_SOURCE();
1333
1334 /* Get the UART5 clock configuration ------------------------------------------*/
1335 PeriphClkInit->Uart5ClockSelection = __HAL_RCC_GET_UART5_SOURCE();
1336
1337 /* Get the USART6 clock configuration ------------------------------------------*/
1338 PeriphClkInit->Usart6ClockSelection = __HAL_RCC_GET_USART6_SOURCE();
1339
1340 /* Get the UART7 clock configuration ------------------------------------------*/
1341 PeriphClkInit->Uart7ClockSelection = __HAL_RCC_GET_UART7_SOURCE();
1342
1343 /* Get the UART8 clock configuration ------------------------------------------*/
1344 PeriphClkInit->Uart8ClockSelection = __HAL_RCC_GET_UART8_SOURCE();
1345
1346 /* Get the LPTIM1 clock configuration ------------------------------------------*/
1347 PeriphClkInit->Lptim1ClockSelection = __HAL_RCC_GET_LPTIM1_SOURCE();
1348
1349 /* Get the CK48 clock configuration -----------------------------------------------*/
1350 PeriphClkInit->Clk48ClockSelection = __HAL_RCC_GET_CLK48_SOURCE();
1351
1352 /* Get the SDMMC1 clock configuration -----------------------------------------------*/
1353 PeriphClkInit->Sdmmc1ClockSelection = __HAL_RCC_GET_SDMMC1_SOURCE();
1354
1355 /* Get the SDMMC2 clock configuration -----------------------------------------------*/
1356 PeriphClkInit->Sdmmc2ClockSelection = __HAL_RCC_GET_SDMMC2_SOURCE();
1357
1358 /* Get the RTC Clock configuration -----------------------------------------------*/
1359 tempreg = (RCC->CFGR & RCC_CFGR_RTCPRE);
1360 PeriphClkInit->RTCClockSelection = (uint32_t)((tempreg) | (RCC->BDCR & RCC_BDCR_RTCSEL));
1361
1362 /* Get the TIM Prescaler configuration --------------------------------------------*/
1363 if ((RCC->DCKCFGR1 & RCC_DCKCFGR1_TIMPRE) == RESET)
1364 {
1365 PeriphClkInit->TIMPresSelection = RCC_TIMPRES_DESACTIVATED;
1366 }
1367 else
1368 {
1369 PeriphClkInit->TIMPresSelection = RCC_TIMPRES_ACTIVATED;
1370 }
1371 }
1372 #endif /* STM32F722xx || STM32F723xx || STM32F732xx || STM32F733xx || STM32F730xx */
1373
1374 /**
1375 * @brief Return the peripheral clock frequency for a given peripheral(SAI..)
1376 * @note Return 0 if peripheral clock identifier not managed by this API
1377 * @param PeriphClk Peripheral clock identifier
1378 * This parameter can be one of the following values:
1379 * @arg RCC_PERIPHCLK_SAI1: SAI1 peripheral clock
1380 * @arg RCC_PERIPHCLK_SAI2: SAI2 peripheral clock
1381 * @retval Frequency in KHz
1382 */
HAL_RCCEx_GetPeriphCLKFreq(uint32_t PeriphClk)1383 uint32_t HAL_RCCEx_GetPeriphCLKFreq(uint32_t PeriphClk)
1384 {
1385 uint32_t tmpreg = 0;
1386 /* This variable is used to store the SAI clock frequency (value in Hz) */
1387 uint32_t frequency = 0;
1388 /* This variable is used to store the VCO Input (value in Hz) */
1389 uint32_t vcoinput = 0;
1390 /* This variable is used to store the SAI clock source */
1391 uint32_t saiclocksource = 0;
1392
1393 if (PeriphClk == RCC_PERIPHCLK_SAI1)
1394 {
1395 saiclocksource = RCC->DCKCFGR1;
1396 saiclocksource &= RCC_DCKCFGR1_SAI1SEL;
1397 switch (saiclocksource)
1398 {
1399 case 0: /* PLLSAI is the clock source for SAI1 */
1400 {
1401 /* Configure the PLLSAI division factor */
1402 /* PLLSAI_VCO Input = PLL_SOURCE/PLLM */
1403 if((RCC->PLLCFGR & RCC_PLLCFGR_PLLSRC) == RCC_PLLSOURCE_HSI)
1404 {
1405 /* In Case the PLL Source is HSI (Internal Clock) */
1406 vcoinput = (HSI_VALUE / (uint32_t)(RCC->PLLCFGR & RCC_PLLCFGR_PLLM));
1407 }
1408 else
1409 {
1410 /* In Case the PLL Source is HSE (External Clock) */
1411 vcoinput = ((HSE_VALUE / (uint32_t)(RCC->PLLCFGR & RCC_PLLCFGR_PLLM)));
1412 }
1413 /* PLLSAI_VCO Output = PLLSAI_VCO Input * PLLSAIN */
1414 /* SAI_CLK(first level) = PLLSAI_VCO Output/PLLSAIQ */
1415 tmpreg = (RCC->PLLSAICFGR & RCC_PLLSAICFGR_PLLSAIQ) >> 24;
1416 frequency = (vcoinput * ((RCC->PLLSAICFGR & RCC_PLLSAICFGR_PLLSAIN) >> 6))/(tmpreg);
1417
1418 /* SAI_CLK_x = SAI_CLK(first level)/PLLSAIDIVQ */
1419 tmpreg = (((RCC->DCKCFGR1 & RCC_DCKCFGR1_PLLSAIDIVQ) >> 8) + 1);
1420 frequency = frequency/(tmpreg);
1421 break;
1422 }
1423 case RCC_DCKCFGR1_SAI1SEL_0: /* PLLI2S is the clock source for SAI1 */
1424 {
1425 /* Configure the PLLI2S division factor */
1426 /* PLLI2S_VCO Input = PLL_SOURCE/PLLM */
1427 if((RCC->PLLCFGR & RCC_PLLCFGR_PLLSRC) == RCC_PLLSOURCE_HSI)
1428 {
1429 /* In Case the PLL Source is HSI (Internal Clock) */
1430 vcoinput = (HSI_VALUE / (uint32_t)(RCC->PLLCFGR & RCC_PLLCFGR_PLLM));
1431 }
1432 else
1433 {
1434 /* In Case the PLL Source is HSE (External Clock) */
1435 vcoinput = ((HSE_VALUE / (uint32_t)(RCC->PLLCFGR & RCC_PLLCFGR_PLLM)));
1436 }
1437
1438 /* PLLI2S_VCO Output = PLLI2S_VCO Input * PLLI2SN */
1439 /* SAI_CLK(first level) = PLLI2S_VCO Output/PLLI2SQ */
1440 tmpreg = (RCC->PLLI2SCFGR & RCC_PLLI2SCFGR_PLLI2SQ) >> 24;
1441 frequency = (vcoinput * ((RCC->PLLI2SCFGR & RCC_PLLI2SCFGR_PLLI2SN) >> 6))/(tmpreg);
1442
1443 /* SAI_CLK_x = SAI_CLK(first level)/PLLI2SDIVQ */
1444 tmpreg = ((RCC->DCKCFGR1 & RCC_DCKCFGR1_PLLI2SDIVQ) + 1);
1445 frequency = frequency/(tmpreg);
1446 break;
1447 }
1448 case RCC_DCKCFGR1_SAI1SEL_1: /* External clock is the clock source for SAI1 */
1449 {
1450 frequency = EXTERNAL_CLOCK_VALUE;
1451 break;
1452 }
1453 #if defined (STM32F765xx) || defined (STM32F767xx) || defined (STM32F769xx) || defined (STM32F777xx) || defined (STM32F779xx)
1454 case RCC_DCKCFGR1_SAI1SEL: /* HSI or HSE is the clock source for SAI*/
1455 {
1456 if((RCC->PLLCFGR & RCC_PLLCFGR_PLLSRC) == RCC_PLLSOURCE_HSI)
1457 {
1458 /* In Case the main PLL Source is HSI */
1459 frequency = HSI_VALUE;
1460 }
1461 else
1462 {
1463 /* In Case the main PLL Source is HSE */
1464 frequency = HSE_VALUE;
1465 }
1466 break;
1467 }
1468 #endif /* STM32F767xx || STM32F769xx || STM32F777xx || STM32F779xx */
1469 default :
1470 {
1471 break;
1472 }
1473 }
1474 }
1475
1476 if (PeriphClk == RCC_PERIPHCLK_SAI2)
1477 {
1478 saiclocksource = RCC->DCKCFGR1;
1479 saiclocksource &= RCC_DCKCFGR1_SAI2SEL;
1480 switch (saiclocksource)
1481 {
1482 case 0: /* PLLSAI is the clock source for SAI*/
1483 {
1484 /* Configure the PLLSAI division factor */
1485 /* PLLSAI_VCO Input = PLL_SOURCE/PLLM */
1486 if((RCC->PLLCFGR & RCC_PLLCFGR_PLLSRC) == RCC_PLLSOURCE_HSI)
1487 {
1488 /* In Case the PLL Source is HSI (Internal Clock) */
1489 vcoinput = (HSI_VALUE / (uint32_t)(RCC->PLLCFGR & RCC_PLLCFGR_PLLM));
1490 }
1491 else
1492 {
1493 /* In Case the PLL Source is HSE (External Clock) */
1494 vcoinput = ((HSE_VALUE / (uint32_t)(RCC->PLLCFGR & RCC_PLLCFGR_PLLM)));
1495 }
1496 /* PLLSAI_VCO Output = PLLSAI_VCO Input * PLLSAIN */
1497 /* SAI_CLK(first level) = PLLSAI_VCO Output/PLLSAIQ */
1498 tmpreg = (RCC->PLLSAICFGR & RCC_PLLSAICFGR_PLLSAIQ) >> 24;
1499 frequency = (vcoinput * ((RCC->PLLSAICFGR & RCC_PLLSAICFGR_PLLSAIN) >> 6))/(tmpreg);
1500
1501 /* SAI_CLK_x = SAI_CLK(first level)/PLLSAIDIVQ */
1502 tmpreg = (((RCC->DCKCFGR1 & RCC_DCKCFGR1_PLLSAIDIVQ) >> 8) + 1);
1503 frequency = frequency/(tmpreg);
1504 break;
1505 }
1506 case RCC_DCKCFGR1_SAI2SEL_0: /* PLLI2S is the clock source for SAI2 */
1507 {
1508 /* Configure the PLLI2S division factor */
1509 /* PLLI2S_VCO Input = PLL_SOURCE/PLLM */
1510 if((RCC->PLLCFGR & RCC_PLLCFGR_PLLSRC) == RCC_PLLSOURCE_HSI)
1511 {
1512 /* In Case the PLL Source is HSI (Internal Clock) */
1513 vcoinput = (HSI_VALUE / (uint32_t)(RCC->PLLCFGR & RCC_PLLCFGR_PLLM));
1514 }
1515 else
1516 {
1517 /* In Case the PLL Source is HSE (External Clock) */
1518 vcoinput = ((HSE_VALUE / (uint32_t)(RCC->PLLCFGR & RCC_PLLCFGR_PLLM)));
1519 }
1520
1521 /* PLLI2S_VCO Output = PLLI2S_VCO Input * PLLI2SN */
1522 /* SAI_CLK(first level) = PLLI2S_VCO Output/PLLI2SQ */
1523 tmpreg = (RCC->PLLI2SCFGR & RCC_PLLI2SCFGR_PLLI2SQ) >> 24;
1524 frequency = (vcoinput * ((RCC->PLLI2SCFGR & RCC_PLLI2SCFGR_PLLI2SN) >> 6))/(tmpreg);
1525
1526 /* SAI_CLK_x = SAI_CLK(first level)/PLLI2SDIVQ */
1527 tmpreg = ((RCC->DCKCFGR1 & RCC_DCKCFGR1_PLLI2SDIVQ) + 1);
1528 frequency = frequency/(tmpreg);
1529 break;
1530 }
1531 case RCC_DCKCFGR1_SAI2SEL_1: /* External clock is the clock source for SAI2 */
1532 {
1533 frequency = EXTERNAL_CLOCK_VALUE;
1534 break;
1535 }
1536 #if defined (STM32F765xx) || defined (STM32F767xx) || defined (STM32F769xx) || defined (STM32F777xx) || defined (STM32F779xx)
1537 case RCC_DCKCFGR1_SAI2SEL: /* HSI or HSE is the clock source for SAI2 */
1538 {
1539 if((RCC->PLLCFGR & RCC_PLLCFGR_PLLSRC) == RCC_PLLSOURCE_HSI)
1540 {
1541 /* In Case the main PLL Source is HSI */
1542 frequency = HSI_VALUE;
1543 }
1544 else
1545 {
1546 /* In Case the main PLL Source is HSE */
1547 frequency = HSE_VALUE;
1548 }
1549 break;
1550 }
1551 #endif /* STM32F767xx || STM32F769xx || STM32F777xx || STM32F779xx */
1552 default :
1553 {
1554 break;
1555 }
1556 }
1557 }
1558
1559 return frequency;
1560 }
1561
1562 /**
1563 * @}
1564 */
1565
1566 /** @defgroup RCCEx_Exported_Functions_Group2 Extended Clock management functions
1567 * @brief Extended Clock management functions
1568 *
1569 @verbatim
1570 ===============================================================================
1571 ##### Extended clock management functions #####
1572 ===============================================================================
1573 [..]
1574 This subsection provides a set of functions allowing to control the
1575 activation or deactivation of PLLI2S, PLLSAI.
1576 @endverbatim
1577 * @{
1578 */
1579
1580 /**
1581 * @brief Enable PLLI2S.
1582 * @param PLLI2SInit pointer to an RCC_PLLI2SInitTypeDef structure that
1583 * contains the configuration information for the PLLI2S
1584 * @retval HAL status
1585 */
HAL_RCCEx_EnablePLLI2S(RCC_PLLI2SInitTypeDef * PLLI2SInit)1586 HAL_StatusTypeDef HAL_RCCEx_EnablePLLI2S(RCC_PLLI2SInitTypeDef *PLLI2SInit)
1587 {
1588 uint32_t tickstart;
1589
1590 /* Check for parameters */
1591 assert_param(IS_RCC_PLLI2SN_VALUE(PLLI2SInit->PLLI2SN));
1592 assert_param(IS_RCC_PLLI2SR_VALUE(PLLI2SInit->PLLI2SR));
1593 assert_param(IS_RCC_PLLI2SQ_VALUE(PLLI2SInit->PLLI2SQ));
1594 #if defined(RCC_PLLI2SCFGR_PLLI2SP)
1595 assert_param(IS_RCC_PLLI2SP_VALUE(PLLI2SInit->PLLI2SP));
1596 #endif /* RCC_PLLI2SCFGR_PLLI2SP */
1597
1598 /* Disable the PLLI2S */
1599 __HAL_RCC_PLLI2S_DISABLE();
1600
1601 /* Wait till PLLI2S is disabled */
1602 tickstart = HAL_GetTick();
1603 while(__HAL_RCC_GET_FLAG(RCC_FLAG_PLLI2SRDY) != RESET)
1604 {
1605 if((HAL_GetTick() - tickstart ) > PLLI2S_TIMEOUT_VALUE)
1606 {
1607 /* return in case of Timeout detected */
1608 return HAL_TIMEOUT;
1609 }
1610 }
1611
1612 /* Configure the PLLI2S division factors */
1613 #if defined (STM32F722xx) || defined (STM32F723xx) || defined (STM32F732xx) || defined (STM32F733xx) || defined (STM32F730xx)
1614 /* PLLI2S_VCO = f(VCO clock) = f(PLLI2S clock input) * PLLI2SN */
1615 /* I2SQCLK = PLLI2S_VCO / PLLI2SQ */
1616 /* I2SRCLK = PLLI2S_VCO / PLLI2SR */
1617 __HAL_RCC_PLLI2S_CONFIG(PLLI2SInit->PLLI2SN, PLLI2SInit->PLLI2SQ, PLLI2SInit->PLLI2SR);
1618 #else
1619 /* PLLI2S_VCO = f(VCO clock) = f(PLLI2S clock input) * PLLI2SN */
1620 /* I2SPCLK = PLLI2S_VCO / PLLI2SP */
1621 /* I2SQCLK = PLLI2S_VCO / PLLI2SQ */
1622 /* I2SRCLK = PLLI2S_VCO / PLLI2SR */
1623 __HAL_RCC_PLLI2S_CONFIG(PLLI2SInit->PLLI2SN, PLLI2SInit->PLLI2SP, PLLI2SInit->PLLI2SQ, PLLI2SInit->PLLI2SR);
1624 #endif /* STM32F722xx || STM32F723xx || STM32F732xx || STM32F733xx || STM32F730xx */
1625
1626 /* Enable the PLLI2S */
1627 __HAL_RCC_PLLI2S_ENABLE();
1628
1629 /* Wait till PLLI2S is ready */
1630 tickstart = HAL_GetTick();
1631 while(__HAL_RCC_GET_FLAG(RCC_FLAG_PLLI2SRDY) == RESET)
1632 {
1633 if((HAL_GetTick() - tickstart ) > PLLI2S_TIMEOUT_VALUE)
1634 {
1635 /* return in case of Timeout detected */
1636 return HAL_TIMEOUT;
1637 }
1638 }
1639
1640 return HAL_OK;
1641 }
1642
1643 /**
1644 * @brief Disable PLLI2S.
1645 * @retval HAL status
1646 */
HAL_RCCEx_DisablePLLI2S(void)1647 HAL_StatusTypeDef HAL_RCCEx_DisablePLLI2S(void)
1648 {
1649 uint32_t tickstart;
1650
1651 /* Disable the PLLI2S */
1652 __HAL_RCC_PLLI2S_DISABLE();
1653
1654 /* Wait till PLLI2S is disabled */
1655 tickstart = HAL_GetTick();
1656 while(READ_BIT(RCC->CR, RCC_CR_PLLI2SRDY) != RESET)
1657 {
1658 if((HAL_GetTick() - tickstart) > PLLI2S_TIMEOUT_VALUE)
1659 {
1660 /* return in case of Timeout detected */
1661 return HAL_TIMEOUT;
1662 }
1663 }
1664
1665 return HAL_OK;
1666 }
1667
1668 /**
1669 * @brief Enable PLLSAI.
1670 * @param PLLSAIInit pointer to an RCC_PLLSAIInitTypeDef structure that
1671 * contains the configuration information for the PLLSAI
1672 * @retval HAL status
1673 */
HAL_RCCEx_EnablePLLSAI(RCC_PLLSAIInitTypeDef * PLLSAIInit)1674 HAL_StatusTypeDef HAL_RCCEx_EnablePLLSAI(RCC_PLLSAIInitTypeDef *PLLSAIInit)
1675 {
1676 uint32_t tickstart;
1677
1678 /* Check for parameters */
1679 assert_param(IS_RCC_PLLSAIN_VALUE(PLLSAIInit->PLLSAIN));
1680 assert_param(IS_RCC_PLLSAIQ_VALUE(PLLSAIInit->PLLSAIQ));
1681 assert_param(IS_RCC_PLLSAIP_VALUE(PLLSAIInit->PLLSAIP));
1682 #if defined(RCC_PLLSAICFGR_PLLSAIR)
1683 assert_param(IS_RCC_PLLSAIR_VALUE(PLLSAIInit->PLLSAIR));
1684 #endif /* RCC_PLLSAICFGR_PLLSAIR */
1685
1686 /* Disable the PLLSAI */
1687 __HAL_RCC_PLLSAI_DISABLE();
1688
1689 /* Wait till PLLSAI is disabled */
1690 tickstart = HAL_GetTick();
1691 while(__HAL_RCC_PLLSAI_GET_FLAG() != RESET)
1692 {
1693 if((HAL_GetTick() - tickstart ) > PLLSAI_TIMEOUT_VALUE)
1694 {
1695 /* return in case of Timeout detected */
1696 return HAL_TIMEOUT;
1697 }
1698 }
1699
1700 /* Configure the PLLSAI division factors */
1701 #if defined (STM32F722xx) || defined (STM32F723xx) || defined (STM32F732xx) || defined (STM32F733xx) || defined (STM32F730xx)
1702 /* PLLSAI_VCO = f(VCO clock) = f(PLLSAI clock input) * PLLSAIN */
1703 /* SAIPCLK = PLLSAI_VCO / PLLSAIP */
1704 /* SAIQCLK = PLLSAI_VCO / PLLSAIQ */
1705 __HAL_RCC_PLLSAI_CONFIG(PLLSAIInit->PLLSAIN, PLLSAIInit->PLLSAIP, PLLSAIInit->PLLSAIQ);
1706 #else
1707 /* PLLSAI_VCO = f(VCO clock) = f(PLLSAI clock input) * PLLSAIN */
1708 /* SAIPCLK = PLLSAI_VCO / PLLSAIP */
1709 /* SAIQCLK = PLLSAI_VCO / PLLSAIQ */
1710 /* SAIRCLK = PLLSAI_VCO / PLLSAIR */
1711 __HAL_RCC_PLLSAI_CONFIG(PLLSAIInit->PLLSAIN, PLLSAIInit->PLLSAIP, \
1712 PLLSAIInit->PLLSAIQ, PLLSAIInit->PLLSAIR);
1713 #endif /* STM32F722xx || STM32F723xx || STM32F732xx || STM32F733xx || STM32F730xx */
1714
1715 /* Enable the PLLSAI */
1716 __HAL_RCC_PLLSAI_ENABLE();
1717
1718 /* Wait till PLLSAI is ready */
1719 tickstart = HAL_GetTick();
1720 while(__HAL_RCC_PLLSAI_GET_FLAG() == RESET)
1721 {
1722 if((HAL_GetTick() - tickstart ) > PLLSAI_TIMEOUT_VALUE)
1723 {
1724 /* return in case of Timeout detected */
1725 return HAL_TIMEOUT;
1726 }
1727 }
1728
1729 return HAL_OK;
1730 }
1731
1732 /**
1733 * @brief Disable PLLSAI.
1734 * @retval HAL status
1735 */
HAL_RCCEx_DisablePLLSAI(void)1736 HAL_StatusTypeDef HAL_RCCEx_DisablePLLSAI(void)
1737 {
1738 uint32_t tickstart;
1739
1740 /* Disable the PLLSAI */
1741 __HAL_RCC_PLLSAI_DISABLE();
1742
1743 /* Wait till PLLSAI is disabled */
1744 tickstart = HAL_GetTick();
1745 while(__HAL_RCC_PLLSAI_GET_FLAG() != RESET)
1746 {
1747 if((HAL_GetTick() - tickstart) > PLLSAI_TIMEOUT_VALUE)
1748 {
1749 /* return in case of Timeout detected */
1750 return HAL_TIMEOUT;
1751 }
1752 }
1753
1754 return HAL_OK;
1755 }
1756
1757 /**
1758 * @}
1759 */
1760
1761 /**
1762 * @}
1763 */
1764
1765 #endif /* HAL_RCC_MODULE_ENABLED */
1766 /**
1767 * @}
1768 */
1769
1770 /**
1771 * @}
1772 */
1773
1774