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