]> git.sur5r.net Git - freertos/blob - FreeRTOS/Demo/CORTEX_M7_STM32F7_STM32756G-EVAL_IAR_Keil/ST_Library/stm32f7xx_hal_rcc_ex.c
Final V8.2.1 release ready for tagging:
[freertos] / FreeRTOS / Demo / CORTEX_M7_STM32F7_STM32756G-EVAL_IAR_Keil / ST_Library / stm32f7xx_hal_rcc_ex.c
1 /**\r
2   ******************************************************************************\r
3   * @file    stm32f7xx_hal_rcc_ex.c\r
4   * @author  MCD Application Team\r
5   * @version V1.0.0RC1\r
6   * @date    24-March-2015\r
7   * @brief   Extension RCC HAL module driver.\r
8   *          This file provides firmware functions to manage the following \r
9   *          functionalities RCC extension peripheral:\r
10   *           + Extended Peripheral Control functions\r
11   *  \r
12   ******************************************************************************\r
13   * @attention\r
14   *\r
15   * <h2><center>&copy; COPYRIGHT(c) 2015 STMicroelectronics</center></h2>\r
16   *\r
17   * Redistribution and use in source and binary forms, with or without modification,\r
18   * are permitted provided that the following conditions are met:\r
19   *   1. Redistributions of source code must retain the above copyright notice,\r
20   *      this list of conditions and the following disclaimer.\r
21   *   2. Redistributions in binary form must reproduce the above copyright notice,\r
22   *      this list of conditions and the following disclaimer in the documentation\r
23   *      and/or other materials provided with the distribution.\r
24   *   3. Neither the name of STMicroelectronics nor the names of its contributors\r
25   *      may be used to endorse or promote products derived from this software\r
26   *      without specific prior written permission.\r
27   *\r
28   * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"\r
29   * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\r
30   * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE\r
31   * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE\r
32   * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL\r
33   * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR\r
34   * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER\r
35   * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,\r
36   * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE\r
37   * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\r
38   *\r
39   ******************************************************************************\r
40   */ \r
41 \r
42 /* Includes ------------------------------------------------------------------*/\r
43 #include "stm32f7xx_hal.h"\r
44 \r
45 /** @addtogroup STM32F7xx_HAL_Driver\r
46   * @{\r
47   */\r
48 \r
49 /** @defgroup RCCEx RCCEx\r
50   * @brief RCCEx HAL module driver\r
51   * @{\r
52   */\r
53 \r
54 #ifdef HAL_RCC_MODULE_ENABLED\r
55 \r
56 /* Private typedef -----------------------------------------------------------*/\r
57 /* Private define ------------------------------------------------------------*/\r
58 /** @defgroup RCCEx_Private_Defines RCCEx Private Defines\r
59   * @{\r
60   */\r
61   \r
62 #define PLLI2S_TIMEOUT_VALUE    100 /* Timeout value fixed to 100 ms  */\r
63 #define PLLSAI_TIMEOUT_VALUE    100 /* Timeout value fixed to 100 ms  */\r
64 \r
65 /**\r
66   * @}\r
67   */\r
68 /* Private macro -------------------------------------------------------------*/\r
69 /** @defgroup RCCEx_Private_Macros RCCEx Private Macros\r
70  * @{\r
71  */\r
72 /**\r
73   * @}\r
74   */\r
75 \r
76 /** @defgroup RCCEx_Private_Macros RCCEx Private Macros\r
77  * @{\r
78  */\r
79 \r
80 /**\r
81   * @}\r
82   */\r
83 \r
84 \r
85 /* Private variables ---------------------------------------------------------*/\r
86 /* Private function prototypes -----------------------------------------------*/\r
87 /* Private functions ---------------------------------------------------------*/\r
88 \r
89 /** @defgroup RCCEx_Exported_Functions RCCEx Exported Functions\r
90   * @{\r
91   */\r
92 \r
93 /** @defgroup RCCEx_Exported_Functions_Group1 Extended Peripheral Control functions \r
94  *  @brief  Extended Peripheral Control functions  \r
95  *\r
96 @verbatim   \r
97  ===============================================================================\r
98                 ##### Extended Peripheral Control functions  #####\r
99  ===============================================================================  \r
100     [..]\r
101     This subsection provides a set of functions allowing to control the RCC Clocks \r
102     frequencies.\r
103     [..] \r
104     (@) Important note: Care must be taken when HAL_RCCEx_PeriphCLKConfig() is used to\r
105         select the RTC clock source; in this case the Backup domain will be reset in  \r
106         order to modify the RTC Clock source, as consequence RTC registers (including \r
107         the backup registers) and RCC_BDCR register will be set to their reset values.\r
108       \r
109 @endverbatim\r
110   * @{\r
111   */\r
112 /**\r
113   * @brief  Initializes the RCC extended peripherals clocks according to the specified\r
114   *         parameters in the RCC_PeriphCLKInitTypeDef.\r
115   * @param  PeriphClkInit: pointer to an RCC_PeriphCLKInitTypeDef structure that\r
116   *         contains the configuration information for the Extended Peripherals\r
117   *         clocks(I2S, SAI, LTDC RTC, TIM, UARTs, USARTs, LTPIM, SDMMC...).\r
118   *         \r
119   * @note   Care must be taken when HAL_RCCEx_PeriphCLKConfig() is used to select \r
120   *         the RTC clock source; in this case the Backup domain will be reset in  \r
121   *         order to modify the RTC Clock source, as consequence RTC registers (including \r
122   *         the backup registers) and RCC_BDCR register are set to their reset values.\r
123   *\r
124   * @retval HAL status\r
125   */\r
126 HAL_StatusTypeDef HAL_RCCEx_PeriphCLKConfig(RCC_PeriphCLKInitTypeDef  *PeriphClkInit)\r
127 {\r
128   uint32_t tickstart = 0;\r
129   uint32_t tmpreg0 = 0;\r
130   uint32_t tmpreg1 = 0;\r
131   uint32_t plli2sused = 0;\r
132   uint32_t pllsaiused = 0;\r
133     \r
134   /* Check the parameters */\r
135   assert_param(IS_RCC_PERIPHCLOCK(PeriphClkInit->PeriphClockSelection));\r
136   \r
137   /*----------------------------------- I2S configuration ----------------------------------*/\r
138   if(((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_I2S) == (RCC_PERIPHCLK_I2S))\r
139   {\r
140     /* Check the parameters */\r
141     assert_param(IS_RCC_I2SCLKSOURCE(PeriphClkInit->I2sClockSelection));\r
142     \r
143     /* Configure I2S Clock source */\r
144     __HAL_RCC_I2S_CONFIG(PeriphClkInit->I2sClockSelection);\r
145     \r
146     /* Enable the PLLI2S when it's used as clock source for I2S */\r
147     if(PeriphClkInit->I2sClockSelection == RCC_I2SCLKSOURCE_PLLI2S)\r
148     {\r
149       plli2sused = 1; \r
150     }\r
151   }\r
152   \r
153   /*------------------------------------ SAI1 configuration --------------------------------------*/\r
154   if(((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_SAI1) == (RCC_PERIPHCLK_SAI1))\r
155   {\r
156     /* Check the parameters */\r
157     assert_param(IS_RCC_SAI1CLKSOURCE(PeriphClkInit->Sai1ClockSelection));\r
158     \r
159     /* Configure SAI1 Clock source */\r
160     __HAL_RCC_SAI1_CONFIG(PeriphClkInit->Sai1ClockSelection);\r
161     /* Enable the PLLI2S when it's used as clock source for SAI */\r
162     if(PeriphClkInit->Sai1ClockSelection == RCC_SAI1CLKSOURCE_PLLI2S)\r
163     {\r
164       plli2sused = 1; \r
165     }\r
166     /* Enable the PLLSAI when it's used as clock source for SAI */\r
167     if(PeriphClkInit->Sai1ClockSelection == RCC_SAI1CLKSOURCE_PLLSAI)\r
168     {\r
169       pllsaiused = 1; \r
170     }\r
171   }\r
172   \r
173   /*------------------------------------ SAI2 configuration --------------------------------------*/\r
174   if(((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_SAI2) == (RCC_PERIPHCLK_SAI2))\r
175   {\r
176     /* Check the parameters */\r
177     assert_param(IS_RCC_SAI2CLKSOURCE(PeriphClkInit->Sai2ClockSelection));\r
178     \r
179     /* Configure SAI2 Clock source */\r
180     __HAL_RCC_SAI2_CONFIG(PeriphClkInit->Sai2ClockSelection);\r
181     \r
182     /* Enable the PLLI2S when it's used as clock source for SAI */\r
183     if(PeriphClkInit->Sai2ClockSelection == RCC_SAI2CLKSOURCE_PLLI2S)\r
184     {\r
185       plli2sused = 1; \r
186     }\r
187     /* Enable the PLLSAI when it's used as clock source for SAI */\r
188     if(PeriphClkInit->Sai2ClockSelection == RCC_SAI2CLKSOURCE_PLLSAI)\r
189     {\r
190       pllsaiused = 1; \r
191     }\r
192   }\r
193   \r
194   /*-------------------------------------- SPDIF-RX Configuration -----------------------------------*/\r
195   if(((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_SPDIFRX) == RCC_PERIPHCLK_SPDIFRX)\r
196   {    \r
197       plli2sused = 1; \r
198   }  \r
199   \r
200   /*------------------------------------ RTC configuration --------------------------------------*/\r
201   if(((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_RTC) == (RCC_PERIPHCLK_RTC))\r
202   {\r
203     /* Enable Power Clock*/\r
204     __HAL_RCC_PWR_CLK_ENABLE();\r
205     \r
206     /* Enable write access to Backup domain */\r
207     PWR->CR1 |= PWR_CR1_DBP;\r
208     \r
209     /* Get Start Tick*/\r
210     tickstart = HAL_GetTick();\r
211     \r
212     /* Wait for Backup domain Write protection disable */\r
213     while((PWR->CR1 & PWR_CR1_DBP) == RESET)\r
214     {\r
215       if((HAL_GetTick() - tickstart) > RCC_DBP_TIMEOUT_VALUE)\r
216       {\r
217         return HAL_TIMEOUT;\r
218       }      \r
219     }\r
220     \r
221     /* Reset the Backup domain only if the RTC Clock source selection is modified */ \r
222     if((RCC->BDCR & RCC_BDCR_RTCSEL) != (PeriphClkInit->RTCClockSelection & RCC_BDCR_RTCSEL))\r
223     {\r
224       /* Store the content of BDCR register before the reset of Backup Domain */\r
225       tmpreg0 = (RCC->BDCR & ~(RCC_BDCR_RTCSEL));\r
226       \r
227       /* RTC Clock selection can be changed only if the Backup Domain is reset */\r
228       __HAL_RCC_BACKUPRESET_FORCE();\r
229       __HAL_RCC_BACKUPRESET_RELEASE();\r
230       \r
231       /* Restore the Content of BDCR register */\r
232       RCC->BDCR = tmpreg0;\r
233     }\r
234     \r
235     /* If LSE is selected as RTC clock source, wait for LSE reactivation */\r
236     if(PeriphClkInit->RTCClockSelection == RCC_RTCCLKSOURCE_LSE)\r
237     {\r
238       /* Get Start Tick*/\r
239       tickstart = HAL_GetTick();\r
240      \r
241       /* Wait till LSE is ready */  \r
242       while(__HAL_RCC_GET_FLAG(RCC_FLAG_LSERDY) == RESET)\r
243       {\r
244         if((HAL_GetTick() - tickstart ) > RCC_LSE_TIMEOUT_VALUE)\r
245         {\r
246           return HAL_TIMEOUT;\r
247         }      \r
248       }  \r
249     }\r
250     __HAL_RCC_RTC_CONFIG(PeriphClkInit->RTCClockSelection); \r
251   }\r
252   /*------------------------------------ TIM configuration --------------------------------------*/\r
253   if(((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_TIM) == (RCC_PERIPHCLK_TIM))\r
254   {\r
255     /* Check the parameters */\r
256     assert_param(IS_RCC_TIMPRES(PeriphClkInit->TIMPresSelection));\r
257     \r
258     /* Configure Timer Prescaler */\r
259     __HAL_RCC_TIMCLKPRESCALER(PeriphClkInit->TIMPresSelection);\r
260   }\r
261   \r
262   /*-------------------------------------- I2C1 Configuration -----------------------------------*/\r
263   if(((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_I2C1) == RCC_PERIPHCLK_I2C1)\r
264   {\r
265     /* Check the parameters */\r
266     assert_param(IS_RCC_I2C1CLKSOURCE(PeriphClkInit->I2c1ClockSelection));\r
267     \r
268     /* Configure the I2C1 clock source */\r
269     __HAL_RCC_I2C1_CONFIG(PeriphClkInit->I2c1ClockSelection);\r
270   }\r
271   \r
272   /*-------------------------------------- I2C2 Configuration -----------------------------------*/\r
273   if(((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_I2C2) == RCC_PERIPHCLK_I2C2)\r
274   {\r
275     /* Check the parameters */\r
276     assert_param(IS_RCC_I2C2CLKSOURCE(PeriphClkInit->I2c2ClockSelection));\r
277     \r
278     /* Configure the I2C2 clock source */\r
279     __HAL_RCC_I2C2_CONFIG(PeriphClkInit->I2c2ClockSelection);\r
280   }\r
281   \r
282   /*-------------------------------------- I2C3 Configuration -----------------------------------*/\r
283   if(((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_I2C3) == RCC_PERIPHCLK_I2C3)\r
284   {\r
285     /* Check the parameters */\r
286     assert_param(IS_RCC_I2C3CLKSOURCE(PeriphClkInit->I2c3ClockSelection));\r
287     \r
288     /* Configure the I2C3 clock source */\r
289     __HAL_RCC_I2C3_CONFIG(PeriphClkInit->I2c3ClockSelection);\r
290   }\r
291     \r
292   /*-------------------------------------- I2C4 Configuration -----------------------------------*/\r
293   if(((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_I2C4) == RCC_PERIPHCLK_I2C4)\r
294   {\r
295     /* Check the parameters */\r
296     assert_param(IS_RCC_I2C4CLKSOURCE(PeriphClkInit->I2c4ClockSelection));\r
297     \r
298     /* Configure the I2C4 clock source */\r
299     __HAL_RCC_I2C4_CONFIG(PeriphClkInit->I2c4ClockSelection);\r
300   }\r
301 \r
302   /*-------------------------------------- USART1 Configuration -----------------------------------*/\r
303   if(((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_USART1) == RCC_PERIPHCLK_USART1)\r
304   {\r
305     /* Check the parameters */\r
306     assert_param(IS_RCC_USART1CLKSOURCE(PeriphClkInit->Usart1ClockSelection));\r
307     \r
308     /* Configure the USART1 clock source */\r
309     __HAL_RCC_USART1_CONFIG(PeriphClkInit->Usart1ClockSelection);\r
310   }\r
311 \r
312   /*-------------------------------------- USART2 Configuration -----------------------------------*/\r
313   if(((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_USART2) == RCC_PERIPHCLK_USART2)\r
314   {\r
315     /* Check the parameters */\r
316     assert_param(IS_RCC_USART2CLKSOURCE(PeriphClkInit->Usart2ClockSelection));\r
317     \r
318     /* Configure the USART2 clock source */\r
319     __HAL_RCC_USART2_CONFIG(PeriphClkInit->Usart2ClockSelection);\r
320   }\r
321 \r
322   /*-------------------------------------- USART3 Configuration -----------------------------------*/\r
323   if(((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_USART3) == RCC_PERIPHCLK_USART3)\r
324   {\r
325     /* Check the parameters */\r
326     assert_param(IS_RCC_USART3CLKSOURCE(PeriphClkInit->Usart3ClockSelection));\r
327     \r
328     /* Configure the USART3 clock source */\r
329     __HAL_RCC_USART3_CONFIG(PeriphClkInit->Usart3ClockSelection);\r
330   }\r
331 \r
332   /*-------------------------------------- UART4 Configuration -----------------------------------*/\r
333   if(((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_UART4) == RCC_PERIPHCLK_UART4)\r
334   {\r
335     /* Check the parameters */\r
336     assert_param(IS_RCC_UART4CLKSOURCE(PeriphClkInit->Uart4ClockSelection));\r
337     \r
338     /* Configure the UART4 clock source */\r
339     __HAL_RCC_UART4_CONFIG(PeriphClkInit->Uart4ClockSelection);\r
340   }\r
341 \r
342   /*-------------------------------------- UART5 Configuration -----------------------------------*/\r
343   if(((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_UART5) == RCC_PERIPHCLK_UART5)\r
344   {\r
345     /* Check the parameters */\r
346     assert_param(IS_RCC_UART5CLKSOURCE(PeriphClkInit->Uart5ClockSelection));\r
347     \r
348     /* Configure the UART5 clock source */\r
349     __HAL_RCC_UART5_CONFIG(PeriphClkInit->Uart5ClockSelection);\r
350   }\r
351 \r
352   /*-------------------------------------- USART6 Configuration -----------------------------------*/\r
353   if(((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_USART6) == RCC_PERIPHCLK_USART6)\r
354   {\r
355     /* Check the parameters */\r
356     assert_param(IS_RCC_USART6CLKSOURCE(PeriphClkInit->Usart6ClockSelection));\r
357     \r
358     /* Configure the USART6 clock source */\r
359     __HAL_RCC_USART6_CONFIG(PeriphClkInit->Usart6ClockSelection);\r
360   }\r
361 \r
362   /*-------------------------------------- UART7 Configuration -----------------------------------*/\r
363   if(((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_UART7) == RCC_PERIPHCLK_UART7)\r
364   {\r
365     /* Check the parameters */\r
366     assert_param(IS_RCC_UART7CLKSOURCE(PeriphClkInit->Uart7ClockSelection));\r
367     \r
368     /* Configure the UART7 clock source */\r
369     __HAL_RCC_UART7_CONFIG(PeriphClkInit->Uart7ClockSelection);\r
370   }\r
371 \r
372   /*-------------------------------------- UART8 Configuration -----------------------------------*/\r
373   if(((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_UART8) == RCC_PERIPHCLK_UART8)\r
374   {\r
375     /* Check the parameters */\r
376     assert_param(IS_RCC_UART8CLKSOURCE(PeriphClkInit->Uart8ClockSelection));\r
377     \r
378     /* Configure the UART8 clock source */\r
379     __HAL_RCC_UART8_CONFIG(PeriphClkInit->Uart8ClockSelection);\r
380   }\r
381   \r
382   /*--------------------------------------- CEC Configuration -----------------------------------*/\r
383   if(((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_CEC) == RCC_PERIPHCLK_CEC)\r
384   {\r
385     /* Check the parameters */\r
386     assert_param(IS_RCC_CECCLKSOURCE(PeriphClkInit->CecClockSelection));\r
387     \r
388     /* Configure the CEC clock source */\r
389     __HAL_RCC_CEC_CONFIG(PeriphClkInit->CecClockSelection);\r
390   }\r
391   \r
392   /*-------------------------------------- CK48 Configuration -----------------------------------*/\r
393   if(((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_CLK48) == RCC_PERIPHCLK_CLK48)\r
394   {\r
395     /* Check the parameters */\r
396     assert_param(IS_RCC_CLK48SOURCE(PeriphClkInit->Clk48ClockSelection));\r
397     \r
398     /* Configure the CLK48 source */\r
399     __HAL_RCC_CLK48_CONFIG(PeriphClkInit->Clk48ClockSelection);\r
400 \r
401     /* Enable the PLLSAI when it's used as clock source for CK48 */\r
402     if(PeriphClkInit->Clk48ClockSelection == RCC_CLK48SOURCE_PLLSAIP)\r
403     {\r
404       pllsaiused = 1; \r
405     }\r
406   }\r
407 \r
408   /*-------------------------------------- LTDC Configuration -----------------------------------*/\r
409   if(((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_LTDC) == RCC_PERIPHCLK_LTDC)\r
410   {\r
411     pllsaiused = 1; \r
412   }\r
413   \r
414   /*-------------------------------------- LPTIM1 Configuration -----------------------------------*/\r
415   if(((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_LPTIM1) == RCC_PERIPHCLK_LPTIM1)\r
416   {\r
417     /* Check the parameters */\r
418     assert_param(IS_RCC_LPTIM1CLK(PeriphClkInit->Lptim1ClockSelection));\r
419     \r
420     /* Configure the LTPIM1 clock source */\r
421     __HAL_RCC_LPTIM1_CONFIG(PeriphClkInit->Lptim1ClockSelection);\r
422    }\r
423   \r
424   /*------------------------------------- SDMMC Configuration ------------------------------------*/\r
425   if(((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_SDMMC1) == RCC_PERIPHCLK_SDMMC1)\r
426   {\r
427     /* Check the parameters */\r
428     assert_param(IS_RCC_SDMMC1CLKSOURCE(PeriphClkInit->Sdmmc1ClockSelection));\r
429     \r
430     /* Configure the SDMMC1 clock source */\r
431     __HAL_RCC_SDMMC1_CONFIG(PeriphClkInit->Sdmmc1ClockSelection);\r
432   }\r
433 \r
434   /*-------------------------------------- PLLI2S Configuration ---------------------------------*/\r
435   /* PLLI2S is configured when a peripheral will use it as source clock : SAI1, SAI2, I2S or SPDIF-RX */\r
436   if(plli2sused == 1)\r
437   {\r
438     /* Disable the PLLI2S */\r
439     __HAL_RCC_PLLI2S_DISABLE();  \r
440     \r
441     /* Get Start Tick*/\r
442     tickstart = HAL_GetTick();\r
443     \r
444     /* Wait till PLLI2S is disabled */\r
445     while(__HAL_RCC_GET_FLAG(RCC_FLAG_PLLI2SRDY)  != RESET)\r
446     {\r
447       if((HAL_GetTick() - tickstart) > PLLI2S_TIMEOUT_VALUE)\r
448       {\r
449         /* return in case of Timeout detected */         \r
450         return HAL_TIMEOUT;\r
451       }\r
452     }\r
453     \r
454     /* check for common PLLI2S Parameters */\r
455     assert_param(IS_RCC_PLLI2SN_VALUE(PeriphClkInit->PLLI2S.PLLI2SN));\r
456       \r
457     /*----------------- In Case of PLLI2S is selected as source clock for I2S -------------------*/ \r
458     if(((((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_I2S) == RCC_PERIPHCLK_I2S) && (PeriphClkInit->I2sClockSelection == RCC_I2SCLKSOURCE_PLLI2S)))\r
459     {\r
460       /* check for Parameters */\r
461       assert_param(IS_RCC_PLLI2SR_VALUE(PeriphClkInit->PLLI2S.PLLI2SR));\r
462     \r
463       /* Read PLLI2SP and PLLI2SQ value from PLLI2SCFGR register (this value is not needed for I2S configuration) */\r
464       tmpreg0 = ((RCC->PLLI2SCFGR & RCC_PLLI2SCFGR_PLLI2SP) >> POSITION_VAL(RCC_PLLI2SCFGR_PLLI2SP));\r
465       tmpreg1 = ((RCC->PLLI2SCFGR & RCC_PLLI2SCFGR_PLLI2SQ) >> POSITION_VAL(RCC_PLLI2SCFGR_PLLI2SQ));\r
466       /* Configure the PLLI2S division factors */\r
467       /* PLLI2S_VCO = f(VCO clock) = f(PLLI2S clock input) Ã— (PLLI2SN/PLLM) */\r
468       /* I2SCLK = f(PLLI2S clock output) = f(VCO clock) / PLLI2SR */\r
469       __HAL_RCC_PLLI2S_CONFIG(PeriphClkInit->PLLI2S.PLLI2SN , tmpreg0, tmpreg1, PeriphClkInit->PLLI2S.PLLI2SR);\r
470     }\r
471         \r
472     /*----------------- In Case of PLLI2S is selected as source clock for SAI -------------------*/  \r
473     if(((((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_SAI1) == RCC_PERIPHCLK_SAI1) && (PeriphClkInit->Sai1ClockSelection == RCC_SAI1CLKSOURCE_PLLI2S)) ||\r
474        ((((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_SAI2) == RCC_PERIPHCLK_SAI2) && (PeriphClkInit->Sai2ClockSelection == RCC_SAI2CLKSOURCE_PLLI2S))) \r
475     {\r
476       /* Check for PLLI2S Parameters */\r
477       assert_param(IS_RCC_PLLI2SQ_VALUE(PeriphClkInit->PLLI2S.PLLI2SQ));\r
478       /* Check for PLLI2S/DIVQ parameters */\r
479       assert_param(IS_RCC_PLLI2S_DIVQ_VALUE(PeriphClkInit->PLLI2SDivQ));\r
480             \r
481       /* Read PLLI2SP and PLLI2SR values from PLLI2SCFGR register (this value is not needed for SAI configuration) */\r
482       tmpreg0 = ((RCC->PLLI2SCFGR & RCC_PLLI2SCFGR_PLLI2SP) >> POSITION_VAL(RCC_PLLI2SCFGR_PLLI2SP));\r
483       tmpreg1 = ((RCC->PLLI2SCFGR & RCC_PLLI2SCFGR_PLLI2SR) >> POSITION_VAL(RCC_PLLI2SCFGR_PLLI2SR));\r
484       /* Configure the PLLI2S division factors */      \r
485       /* PLLI2S_VCO Input  = PLL_SOURCE/PLLM */\r
486       /* PLLI2S_VCO Output = PLLI2S_VCO Input * PLLI2SN */\r
487       /* SAI_CLK(first level) = PLLI2S_VCO Output/PLLI2SQ */\r
488       __HAL_RCC_PLLI2S_CONFIG(PeriphClkInit->PLLI2S.PLLI2SN, tmpreg0, PeriphClkInit->PLLI2S.PLLI2SQ, tmpreg1);\r
489    \r
490       /* SAI_CLK_x = SAI_CLK(first level)/PLLI2SDIVQ */ \r
491       __HAL_RCC_PLLI2S_PLLSAICLKDIVQ_CONFIG(PeriphClkInit->PLLI2SDivQ);   \r
492     }          \r
493 \r
494     /*----------------- In Case of PLLI2S is selected as source clock for SPDIF-RX -------------------*/  \r
495     if(((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_SPDIFRX) == RCC_PERIPHCLK_SPDIFRX)\r
496     {\r
497       /* check for Parameters */\r
498       assert_param(IS_RCC_PLLI2SP_VALUE(PeriphClkInit->PLLI2S.PLLI2SP));\r
499      \r
500      /* Read PLLI2SR value from PLLI2SCFGR register (this value is not needed for SPDIF-RX configuration) */\r
501       tmpreg0 = ((RCC->PLLI2SCFGR & RCC_PLLI2SCFGR_PLLI2SQ) >> POSITION_VAL(RCC_PLLI2SCFGR_PLLI2SQ));\r
502       tmpreg1 = ((RCC->PLLI2SCFGR & RCC_PLLI2SCFGR_PLLI2SR) >> POSITION_VAL(RCC_PLLI2SCFGR_PLLI2SR));\r
503       /* Configure the PLLI2S division factors */\r
504       /* PLLI2S_VCO = f(VCO clock) = f(PLLI2S clock input) Ã— (PLLI2SN/PLLM) */\r
505       /* SPDIFCLK = f(PLLI2S clock output) = f(VCO clock) / PLLI2SP */\r
506       __HAL_RCC_PLLI2S_CONFIG(PeriphClkInit->PLLI2S.PLLI2SN , PeriphClkInit->PLLI2S.PLLI2SP, tmpreg0, tmpreg1);\r
507     }       \r
508    \r
509     /* Enable the PLLI2S */\r
510     __HAL_RCC_PLLI2S_ENABLE();\r
511     \r
512     /* Get Start Tick*/\r
513     tickstart = HAL_GetTick();\r
514 \r
515     /* Wait till PLLI2S is ready */\r
516     while(__HAL_RCC_GET_FLAG(RCC_FLAG_PLLI2SRDY)  == RESET)\r
517     {\r
518       if((HAL_GetTick() - tickstart) > PLLI2S_TIMEOUT_VALUE)\r
519       {\r
520         /* return in case of Timeout detected */                \r
521         return HAL_TIMEOUT;\r
522       }\r
523     }\r
524   } \r
525   \r
526   /*-------------------------------------- PLLSAI Configuration ---------------------------------*/\r
527   /* PLLSAI is configured when a peripheral will use it as source clock : SAI1, SAI2, LTDC or CK48 */\r
528   if(pllsaiused == 1)\r
529   {\r
530     /* Disable PLLSAI Clock */\r
531     __HAL_RCC_PLLSAI_DISABLE(); \r
532     \r
533     /* Get Start Tick*/\r
534     tickstart = HAL_GetTick();\r
535 \r
536     /* Wait till PLLSAI is disabled */\r
537     while(__HAL_RCC_PLLSAI_GET_FLAG() != RESET)\r
538     {\r
539       if((HAL_GetTick() - tickstart) > PLLSAI_TIMEOUT_VALUE)\r
540       { \r
541         /* return in case of Timeout detected */        \r
542         return HAL_TIMEOUT;\r
543       }\r
544     } \r
545     \r
546     /* Check the PLLSAI division factors */\r
547     assert_param(IS_RCC_PLLSAIN_VALUE(PeriphClkInit->PLLSAI.PLLSAIN));\r
548     \r
549     /*----------------- In Case of PLLSAI is selected as source clock for SAI -------------------*/  \r
550     if(((((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_SAI1) == RCC_PERIPHCLK_SAI1) && (PeriphClkInit->Sai1ClockSelection == RCC_SAI1CLKSOURCE_PLLSAI)) ||\r
551        ((((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_SAI2) == RCC_PERIPHCLK_SAI2) && (PeriphClkInit->Sai2ClockSelection == RCC_SAI2CLKSOURCE_PLLSAI)))\r
552     {\r
553       /* check for PLLSAIQ Parameter */\r
554       assert_param(IS_RCC_PLLSAIQ_VALUE(PeriphClkInit->PLLSAI.PLLSAIQ));\r
555       /* check for PLLSAI/DIVQ Parameter */\r
556       assert_param(IS_RCC_PLLSAI_DIVQ_VALUE(PeriphClkInit->PLLSAIDivQ));\r
557     \r
558       /* Read PLLSAIP value from PLLSAICFGR register (this value is not needed for SAI configuration) */\r
559       tmpreg0 = ((RCC->PLLSAICFGR & RCC_PLLSAICFGR_PLLSAIP) >> POSITION_VAL(RCC_PLLSAICFGR_PLLSAIP));\r
560       tmpreg1 = ((RCC->PLLSAICFGR & RCC_PLLI2SCFGR_PLLI2SR) >> POSITION_VAL(RCC_PLLSAICFGR_PLLSAIR));\r
561       /* PLLSAI_VCO Input  = PLL_SOURCE/PLLM */\r
562       /* PLLSAI_VCO Output = PLLSAI_VCO Input * PLLSAIN */\r
563       /* SAI_CLK(first level) = PLLSAI_VCO Output/PLLSAIQ */\r
564       __HAL_RCC_PLLSAI_CONFIG(PeriphClkInit->PLLSAI.PLLSAIN , tmpreg0, PeriphClkInit->PLLSAI.PLLSAIQ, tmpreg1);\r
565       \r
566       /* SAI_CLK_x = SAI_CLK(first level)/PLLSAIDIVQ */ \r
567       __HAL_RCC_PLLSAI_PLLSAICLKDIVQ_CONFIG(PeriphClkInit->PLLSAIDivQ);\r
568     }           \r
569 \r
570     /*----------------- In Case of PLLSAI is selected as source clock for CLK48 -------------------*/   \r
571     /* In Case of PLLI2S is selected as source clock for CK48 */ \r
572     if((((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_CLK48) == RCC_PERIPHCLK_CLK48) && (PeriphClkInit->Clk48ClockSelection == RCC_CLK48SOURCE_PLLSAIP))\r
573     {\r
574       /* check for Parameters */\r
575       assert_param(IS_RCC_PLLSAIP_VALUE(PeriphClkInit->PLLSAI.PLLSAIP));\r
576       /* Read PLLSAIQ and PLLSAIR value from PLLSAICFGR register (this value is not needed for CK48 configuration) */\r
577       tmpreg0 = ((RCC->PLLSAICFGR & RCC_PLLSAICFGR_PLLSAIQ) >> POSITION_VAL(RCC_PLLSAICFGR_PLLSAIQ));\r
578       tmpreg1 = ((RCC->PLLSAICFGR & RCC_PLLSAICFGR_PLLSAIR) >> POSITION_VAL(RCC_PLLSAICFGR_PLLSAIR));\r
579       \r
580       /* Configure the PLLSAI division factors */\r
581       /* PLLSAI_VCO = f(VCO clock) = f(PLLSAI clock input) Ã— (PLLI2SN/PLLM) */\r
582       /* 48CLK = f(PLLSAI clock output) = f(VCO clock) / PLLSAIP */\r
583       __HAL_RCC_PLLSAI_CONFIG(PeriphClkInit->PLLSAI.PLLSAIN , PeriphClkInit->PLLSAI.PLLSAIP, tmpreg0, tmpreg1);\r
584     }        \r
585 \r
586     /*---------------------------- LTDC configuration -------------------------------*/\r
587     if(((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_LTDC) == (RCC_PERIPHCLK_LTDC))\r
588     {\r
589       assert_param(IS_RCC_PLLSAIR_VALUE(PeriphClkInit->PLLSAI.PLLSAIR));\r
590       assert_param(IS_RCC_PLLSAI_DIVR_VALUE(PeriphClkInit->PLLSAIDivR));\r
591       \r
592       /* Read PLLSAIP and PLLSAIQ value from PLLSAICFGR register (these value are not needed for LTDC configuration) */\r
593       tmpreg0 = ((RCC->PLLSAICFGR & RCC_PLLSAICFGR_PLLSAIQ) >> POSITION_VAL(RCC_PLLSAICFGR_PLLSAIQ));\r
594       tmpreg1 = ((RCC->PLLSAICFGR & RCC_PLLSAICFGR_PLLSAIP) >> POSITION_VAL(RCC_PLLSAICFGR_PLLSAIP));\r
595       \r
596       /* PLLSAI_VCO Input  = PLL_SOURCE/PLLM */\r
597       /* PLLSAI_VCO Output = PLLSAI_VCO Input * PLLSAIN */\r
598       /* LTDC_CLK(first level) = PLLSAI_VCO Output/PLLSAIR */\r
599       __HAL_RCC_PLLSAI_CONFIG(PeriphClkInit->PLLSAI.PLLSAIN , tmpreg1, tmpreg0, PeriphClkInit->PLLSAI.PLLSAIR);\r
600       \r
601       /* LTDC_CLK = LTDC_CLK(first level)/PLLSAIDIVR */ \r
602       __HAL_RCC_PLLSAI_PLLSAICLKDIVR_CONFIG(PeriphClkInit->PLLSAIDivR);\r
603     }    \r
604     \r
605     /* Enable PLLSAI Clock */\r
606     __HAL_RCC_PLLSAI_ENABLE();\r
607     \r
608     /* Get Start Tick*/\r
609     tickstart = HAL_GetTick();\r
610 \r
611     /* Wait till PLLSAI is ready */\r
612     while(__HAL_RCC_PLLSAI_GET_FLAG() == RESET)\r
613     {\r
614       if((HAL_GetTick() - tickstart) > PLLSAI_TIMEOUT_VALUE)\r
615       { \r
616         /* return in case of Timeout detected */        \r
617         return HAL_TIMEOUT;\r
618       }\r
619     }\r
620   }\r
621   return HAL_OK;\r
622 }\r
623 \r
624 /**\r
625   * @brief  Get the RCC_PeriphCLKInitTypeDef according to the internal\r
626   *         RCC configuration registers.\r
627   * @param  PeriphClkInit: pointer to the configured RCC_PeriphCLKInitTypeDef structure\r
628   * @retval None\r
629   */\r
630 void HAL_RCCEx_GetPeriphCLKConfig(RCC_PeriphCLKInitTypeDef  *PeriphClkInit)\r
631 {\r
632   uint32_t tempreg = 0;\r
633   \r
634   /* Set all possible values for the extended clock type parameter------------*/\r
635   PeriphClkInit->PeriphClockSelection = RCC_PERIPHCLK_I2S      | RCC_PERIPHCLK_LPTIM1 |\\r
636                                         RCC_PERIPHCLK_SAI1     | RCC_PERIPHCLK_SAI2     |\\r
637                                         RCC_PERIPHCLK_TIM      | RCC_PERIPHCLK_RTC      |\\r
638                                         RCC_PERIPHCLK_CEC      | RCC_PERIPHCLK_I2C4     |\\r
639                                         RCC_PERIPHCLK_I2C1     | RCC_PERIPHCLK_I2C2     |\\r
640                                         RCC_PERIPHCLK_I2C3     | RCC_PERIPHCLK_USART1   |\\r
641                                         RCC_PERIPHCLK_USART2   | RCC_PERIPHCLK_USART3   |\\r
642                                         RCC_PERIPHCLK_UART4    | RCC_PERIPHCLK_UART5    |\\r
643                                         RCC_PERIPHCLK_USART6   | RCC_PERIPHCLK_UART7    |\\r
644                                         RCC_PERIPHCLK_UART8    | RCC_PERIPHCLK_SDMMC1    |\\r
645                                         RCC_PERIPHCLK_CLK48;          \r
646   \r
647   /* Get the PLLI2S Clock configuration -----------------------------------------------*/\r
648   PeriphClkInit->PLLI2S.PLLI2SN = (uint32_t)((RCC->PLLI2SCFGR & RCC_PLLI2SCFGR_PLLI2SN) >> POSITION_VAL(RCC_PLLI2SCFGR_PLLI2SN));\r
649   PeriphClkInit->PLLI2S.PLLI2SP = (uint32_t)((RCC->PLLI2SCFGR & RCC_PLLI2SCFGR_PLLI2SP) >> POSITION_VAL(RCC_PLLI2SCFGR_PLLI2SP));\r
650   PeriphClkInit->PLLI2S.PLLI2SQ = (uint32_t)((RCC->PLLI2SCFGR & RCC_PLLI2SCFGR_PLLI2SQ) >> POSITION_VAL(RCC_PLLI2SCFGR_PLLI2SQ));\r
651   PeriphClkInit->PLLI2S.PLLI2SR = (uint32_t)((RCC->PLLI2SCFGR & RCC_PLLI2SCFGR_PLLI2SR) >> POSITION_VAL(RCC_PLLI2SCFGR_PLLI2SR));\r
652   \r
653   /* Get the PLLSAI Clock configuration -----------------------------------------------*/\r
654   PeriphClkInit->PLLSAI.PLLSAIN = (uint32_t)((RCC->PLLSAICFGR & RCC_PLLSAICFGR_PLLSAIN) >> POSITION_VAL(RCC_PLLSAICFGR_PLLSAIN));\r
655   PeriphClkInit->PLLSAI.PLLSAIP = (uint32_t)((RCC->PLLSAICFGR & RCC_PLLSAICFGR_PLLSAIP) >> POSITION_VAL(RCC_PLLSAICFGR_PLLSAIP));\r
656   PeriphClkInit->PLLSAI.PLLSAIQ = (uint32_t)((RCC->PLLSAICFGR & RCC_PLLSAICFGR_PLLSAIQ) >> POSITION_VAL(RCC_PLLSAICFGR_PLLSAIQ)); \r
657   PeriphClkInit->PLLSAI.PLLSAIR = (uint32_t)((RCC->PLLSAICFGR & RCC_PLLSAICFGR_PLLSAIR) >> POSITION_VAL(RCC_PLLSAICFGR_PLLSAIR)); \r
658   \r
659   /* Get the PLLSAI/PLLI2S division factors -------------------------------------------*/\r
660   PeriphClkInit->PLLI2SDivQ = (uint32_t)((RCC->DCKCFGR1 & RCC_DCKCFGR1_PLLI2SDIVQ) >> POSITION_VAL(RCC_DCKCFGR1_PLLI2SDIVQ));\r
661   PeriphClkInit->PLLSAIDivQ = (uint32_t)((RCC->DCKCFGR1 & RCC_DCKCFGR1_PLLSAIDIVQ) >> POSITION_VAL(RCC_DCKCFGR1_PLLSAIDIVQ));\r
662   PeriphClkInit->PLLSAIDivR = (uint32_t)((RCC->DCKCFGR1 & RCC_DCKCFGR1_PLLSAIDIVR) >> POSITION_VAL(RCC_DCKCFGR1_PLLSAIDIVR));\r
663 \r
664   /* Get the SAI1 clock configuration ----------------------------------------------*/\r
665   PeriphClkInit->Sai1ClockSelection = __HAL_RCC_GET_SAI1_SOURCE();\r
666   \r
667   /* Get the SAI2 clock configuration ----------------------------------------------*/\r
668   PeriphClkInit->Sai2ClockSelection = __HAL_RCC_GET_SAI2_SOURCE();\r
669   \r
670   /* Get the I2S clock configuration ------------------------------------------*/\r
671   PeriphClkInit->I2sClockSelection = __HAL_RCC_GET_I2SCLKSOURCE();\r
672   \r
673   /* Get the I2C1 clock configuration ------------------------------------------*/\r
674   PeriphClkInit->I2c1ClockSelection = __HAL_RCC_GET_I2C1_SOURCE();\r
675   \r
676   /* Get the I2C2 clock configuration ------------------------------------------*/\r
677   PeriphClkInit->I2c2ClockSelection = __HAL_RCC_GET_I2C2_SOURCE();\r
678   \r
679   /* Get the I2C3 clock configuration ------------------------------------------*/\r
680   PeriphClkInit->I2c3ClockSelection = __HAL_RCC_GET_I2C3_SOURCE();\r
681   \r
682   /* Get the I2C4 clock configuration ------------------------------------------*/\r
683   PeriphClkInit->I2c4ClockSelection = __HAL_RCC_GET_I2C4_SOURCE();\r
684   \r
685   /* Get the USART1 clock configuration ------------------------------------------*/\r
686   PeriphClkInit->Usart1ClockSelection = __HAL_RCC_GET_USART1_SOURCE();\r
687   \r
688   /* Get the USART2 clock configuration ------------------------------------------*/\r
689   PeriphClkInit->Usart2ClockSelection = __HAL_RCC_GET_USART2_SOURCE();\r
690   \r
691   /* Get the USART3 clock configuration ------------------------------------------*/\r
692   PeriphClkInit->Usart3ClockSelection = __HAL_RCC_GET_USART3_SOURCE();\r
693   \r
694   /* Get the UART4 clock configuration ------------------------------------------*/\r
695   PeriphClkInit->Uart4ClockSelection = __HAL_RCC_GET_UART4_SOURCE();\r
696   \r
697   /* Get the UART5 clock configuration ------------------------------------------*/\r
698   PeriphClkInit->Uart5ClockSelection = __HAL_RCC_GET_UART5_SOURCE();\r
699   \r
700   /* Get the USART6 clock configuration ------------------------------------------*/\r
701   PeriphClkInit->Usart6ClockSelection = __HAL_RCC_GET_USART6_SOURCE();\r
702   \r
703   /* Get the UART7 clock configuration ------------------------------------------*/\r
704   PeriphClkInit->Uart7ClockSelection = __HAL_RCC_GET_UART7_SOURCE();\r
705   \r
706   /* Get the UART8 clock configuration ------------------------------------------*/\r
707   PeriphClkInit->Uart8ClockSelection = __HAL_RCC_GET_UART8_SOURCE();\r
708   \r
709   /* Get the LPTIM1 clock configuration ------------------------------------------*/\r
710   PeriphClkInit->Lptim1ClockSelection = __HAL_RCC_GET_LPTIM1_SOURCE();\r
711   \r
712   /* Get the CEC clock configuration -----------------------------------------------*/\r
713   PeriphClkInit->CecClockSelection = __HAL_RCC_GET_CEC_SOURCE();\r
714   \r
715   /* Get the CK48 clock configuration -----------------------------------------------*/\r
716   PeriphClkInit->Clk48ClockSelection = __HAL_RCC_GET_CLK48_SOURCE();\r
717 \r
718   /* Get the SDMMC clock configuration -----------------------------------------------*/\r
719   PeriphClkInit->Sdmmc1ClockSelection = __HAL_RCC_GET_SDMMC1_SOURCE();\r
720   \r
721   /* Get the RTC Clock configuration -----------------------------------------------*/\r
722   tempreg = (RCC->CFGR & RCC_CFGR_RTCPRE);\r
723   PeriphClkInit->RTCClockSelection = (uint32_t)((tempreg) | (RCC->BDCR & RCC_BDCR_RTCSEL));\r
724   \r
725   /* Get the TIM Prescaler configuration --------------------------------------------*/\r
726   if ((RCC->DCKCFGR1 & RCC_DCKCFGR1_TIMPRE) == RESET)\r
727   {\r
728     PeriphClkInit->TIMPresSelection = RCC_TIMPRES_DESACTIVATED;\r
729   }\r
730   else\r
731   {\r
732     PeriphClkInit->TIMPresSelection = RCC_TIMPRES_ACTIVATED;\r
733   }\r
734 }\r
735 \r
736 /**\r
737   * @brief  Return the peripheral clock frequency for a given peripheral(SAI..) \r
738   * @note   Return 0 if peripheral clock identifier not managed by this API\r
739   * @param  PeriphClk: Peripheral clock identifier\r
740   *         This parameter can be one of the following values:\r
741   *            @arg RCC_PERIPHCLK_SAI1: SAI1 peripheral clock\r
742   *            @arg RCC_PERIPHCLK_SAI2: SAI2 peripheral clock\r
743   * @retval Frequency in KHz\r
744   */\r
745 uint32_t HAL_RCCEx_GetPeriphCLKFreq(uint32_t PeriphClk)\r
746 {\r
747   uint32_t tmpreg = 0;\r
748   /* This variable used to store the SAI clock frequency (value in Hz) */\r
749   uint32_t frequency = 0;\r
750   /* This variable used to store the VCO Input (value in Hz) */\r
751   uint32_t vcoinput = 0;\r
752   /* This variable used to store the SAI clock source */\r
753   uint32_t saiclocksource = 0;\r
754   if ((PeriphClk == RCC_PERIPHCLK_SAI1) || (PeriphClk == RCC_PERIPHCLK_SAI2))\r
755   {\r
756     saiclocksource = RCC->DCKCFGR1;   \r
757     saiclocksource &= (RCC_DCKCFGR1_SAI1SEL | RCC_DCKCFGR1_SAI2SEL);\r
758     switch (saiclocksource)\r
759     {\r
760     case 0: /* PLLSAI is the clock source for SAI*/ \r
761       {\r
762         /* Configure the PLLSAI division factor */\r
763         /* PLLSAI_VCO Input  = PLL_SOURCE/PLLM */ \r
764         if((RCC->PLLCFGR & RCC_PLLCFGR_PLLSRC) == RCC_PLLSOURCE_HSI)\r
765         {\r
766           /* In Case the PLL Source is HSI (Internal Clock) */\r
767           vcoinput = (HSI_VALUE / (uint32_t)(RCC->PLLCFGR & RCC_PLLCFGR_PLLM));\r
768         }\r
769         else\r
770         {\r
771           /* In Case the PLL Source is HSE (External Clock) */\r
772           vcoinput = ((HSE_VALUE / (uint32_t)(RCC->PLLCFGR & RCC_PLLCFGR_PLLM)));\r
773         }   \r
774         /* PLLSAI_VCO Output = PLLSAI_VCO Input * PLLSAIN */\r
775         /* SAI_CLK(first level) = PLLSAI_VCO Output/PLLSAIQ */\r
776         tmpreg = (RCC->PLLSAICFGR & RCC_PLLSAICFGR_PLLSAIQ) >> 24;\r
777         frequency = (vcoinput * ((RCC->PLLSAICFGR & RCC_PLLSAICFGR_PLLSAIN) >> 6))/(tmpreg);\r
778         \r
779         /* SAI_CLK_x = SAI_CLK(first level)/PLLSAIDIVQ */\r
780         tmpreg = (((RCC->DCKCFGR1 & RCC_DCKCFGR1_PLLSAIDIVQ) >> 8) + 1);\r
781         frequency = frequency/(tmpreg); \r
782         break;       \r
783       }\r
784     case RCC_DCKCFGR1_SAI1SEL_0: /* PLLI2S is the clock source for SAI*/\r
785     case RCC_DCKCFGR1_SAI2SEL_0: /* PLLI2S is the clock source for SAI*/\r
786       {  \r
787         /* Configure the PLLI2S division factor */\r
788         /* PLLI2S_VCO Input  = PLL_SOURCE/PLLM */ \r
789         if((RCC->PLLCFGR & RCC_PLLCFGR_PLLSRC) == RCC_PLLSOURCE_HSI)\r
790         {\r
791           /* In Case the PLL Source is HSI (Internal Clock) */\r
792           vcoinput = (HSI_VALUE / (uint32_t)(RCC->PLLCFGR & RCC_PLLCFGR_PLLM));\r
793         }\r
794         else\r
795         {\r
796           /* In Case the PLL Source is HSE (External Clock) */\r
797           vcoinput = ((HSE_VALUE / (uint32_t)(RCC->PLLCFGR & RCC_PLLCFGR_PLLM)));\r
798         }\r
799         \r
800         /* PLLI2S_VCO Output = PLLI2S_VCO Input * PLLI2SN */\r
801         /* SAI_CLK(first level) = PLLI2S_VCO Output/PLLI2SQ */\r
802         tmpreg = (RCC->PLLI2SCFGR & RCC_PLLI2SCFGR_PLLI2SQ) >> 24;\r
803         frequency = (vcoinput * ((RCC->PLLI2SCFGR & RCC_PLLI2SCFGR_PLLI2SN) >> 6))/(tmpreg);\r
804         \r
805         /* SAI_CLK_x = SAI_CLK(first level)/PLLI2SDIVQ */\r
806         tmpreg = ((RCC->DCKCFGR1 & RCC_DCKCFGR1_PLLI2SDIVQ) + 1); \r
807         frequency = frequency/(tmpreg);\r
808         break;\r
809       }\r
810     case RCC_DCKCFGR1_SAI1SEL_1: /* External clock is the clock source for SAI*/\r
811     case RCC_DCKCFGR1_SAI2SEL_1: /* External clock is the clock source for SAI*/\r
812       {\r
813         frequency = EXTERNAL_CLOCK_VALUE;\r
814         break;       \r
815       }\r
816     default :\r
817       {\r
818         break;\r
819       }\r
820     }\r
821   }\r
822   return frequency;\r
823 }\r
824 \r
825 /**\r
826   * @}\r
827   */\r
828 \r
829 /**\r
830   * @}\r
831   */\r
832 \r
833 #endif /* HAL_RCC_MODULE_ENABLED */\r
834 /**\r
835   * @}\r
836   */\r
837 \r
838 /**\r
839   * @}\r
840   */\r
841 \r
842 /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/\r