2 ******************************************************************************
3 * @file stm32f7xx_hal_rcc_ex.c
4 * @author MCD Application Team
7 * @brief Extension RCC HAL module driver.
8 * This file provides firmware functions to manage the following
9 * functionalities RCC extension peripheral:
10 * + Extended Peripheral Control functions
12 ******************************************************************************
15 * <h2><center>© COPYRIGHT(c) 2016 STMicroelectronics</center></h2>
17 * Redistribution and use in source and binary forms, with or without modification,
18 * are permitted provided that the following conditions are met:
19 * 1. Redistributions of source code must retain the above copyright notice,
20 * this list of conditions and the following disclaimer.
21 * 2. Redistributions in binary form must reproduce the above copyright notice,
22 * this list of conditions and the following disclaimer in the documentation
23 * and/or other materials provided with the distribution.
24 * 3. Neither the name of STMicroelectronics nor the names of its contributors
25 * may be used to endorse or promote products derived from this software
26 * without specific prior written permission.
28 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
29 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
30 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
31 * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
32 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
33 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
34 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
35 * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
36 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
37 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
39 ******************************************************************************
42 /* Includes ------------------------------------------------------------------*/
43 #include "stm32f7xx_hal.h"
45 /** @addtogroup STM32F7xx_HAL_Driver
49 /** @defgroup RCCEx RCCEx
50 * @brief RCCEx HAL module driver
54 #ifdef HAL_RCC_MODULE_ENABLED
56 /* Private typedef -----------------------------------------------------------*/
57 /* Private define ------------------------------------------------------------*/
58 /** @defgroup RCCEx_Private_Defines RCCEx Private Defines
62 #define PLLI2S_TIMEOUT_VALUE 100 /* Timeout value fixed to 100 ms */
63 #define PLLSAI_TIMEOUT_VALUE 100 /* Timeout value fixed to 100 ms */
68 /* Private macro -------------------------------------------------------------*/
69 /** @defgroup RCCEx_Private_Macros RCCEx Private Macros
76 /** @defgroup RCCEx_Private_Macros RCCEx Private Macros
85 /* Private variables ---------------------------------------------------------*/
86 /* Private function prototypes -----------------------------------------------*/
87 /* Private functions ---------------------------------------------------------*/
89 /** @defgroup RCCEx_Exported_Functions RCCEx Exported Functions
93 /** @defgroup RCCEx_Exported_Functions_Group1 Extended Peripheral Control functions
94 * @brief Extended Peripheral Control functions
97 ===============================================================================
98 ##### Extended Peripheral Control functions #####
99 ===============================================================================
101 This subsection provides a set of functions allowing to control the RCC Clocks
104 (@) Important note: Care must be taken when HAL_RCCEx_PeriphCLKConfig() is used to
105 select the RTC clock source; in this case the Backup domain will be reset in
106 order to modify the RTC Clock source, as consequence RTC registers (including
107 the backup registers) and RCC_BDCR register will be set to their reset values.
113 * @brief Initializes the RCC extended peripherals clocks according to the specified
114 * parameters in the RCC_PeriphCLKInitTypeDef.
115 * @param PeriphClkInit: pointer to an RCC_PeriphCLKInitTypeDef structure that
116 * contains the configuration information for the Extended Peripherals
117 * clocks(I2S, SAI, LTDC, RTC, TIM, UARTs, USARTs, LTPIM, SDMMC...).
119 * @note Care must be taken when HAL_RCCEx_PeriphCLKConfig() is used to select
120 * the RTC clock source; in this case the Backup domain will be reset in
121 * order to modify the RTC Clock source, as consequence RTC registers (including
122 * the backup registers) are set to their reset values.
126 HAL_StatusTypeDef
HAL_RCCEx_PeriphCLKConfig(RCC_PeriphCLKInitTypeDef
*PeriphClkInit
)
128 uint32_t tickstart
= 0;
129 uint32_t tmpreg0
= 0;
130 uint32_t tmpreg1
= 0;
131 uint32_t plli2sused
= 0;
132 uint32_t pllsaiused
= 0;
134 /* Check the parameters */
135 assert_param(IS_RCC_PERIPHCLOCK(PeriphClkInit
->PeriphClockSelection
));
137 /*----------------------------------- I2S configuration ----------------------------------*/
138 if(((PeriphClkInit
->PeriphClockSelection
) & RCC_PERIPHCLK_I2S
) == (RCC_PERIPHCLK_I2S
))
140 /* Check the parameters */
141 assert_param(IS_RCC_I2SCLKSOURCE(PeriphClkInit
->I2sClockSelection
));
143 /* Configure I2S Clock source */
144 __HAL_RCC_I2S_CONFIG(PeriphClkInit
->I2sClockSelection
);
146 /* Enable the PLLI2S when it's used as clock source for I2S */
147 if(PeriphClkInit
->I2sClockSelection
== RCC_I2SCLKSOURCE_PLLI2S
)
153 /*------------------------------------ SAI1 configuration --------------------------------------*/
154 if(((PeriphClkInit
->PeriphClockSelection
) & RCC_PERIPHCLK_SAI1
) == (RCC_PERIPHCLK_SAI1
))
156 /* Check the parameters */
157 assert_param(IS_RCC_SAI1CLKSOURCE(PeriphClkInit
->Sai1ClockSelection
));
159 /* Configure SAI1 Clock source */
160 __HAL_RCC_SAI1_CONFIG(PeriphClkInit
->Sai1ClockSelection
);
161 /* Enable the PLLI2S when it's used as clock source for SAI */
162 if(PeriphClkInit
->Sai1ClockSelection
== RCC_SAI1CLKSOURCE_PLLI2S
)
166 /* Enable the PLLSAI when it's used as clock source for SAI */
167 if(PeriphClkInit
->Sai1ClockSelection
== RCC_SAI1CLKSOURCE_PLLSAI
)
173 /*------------------------------------ SAI2 configuration --------------------------------------*/
174 if(((PeriphClkInit
->PeriphClockSelection
) & RCC_PERIPHCLK_SAI2
) == (RCC_PERIPHCLK_SAI2
))
176 /* Check the parameters */
177 assert_param(IS_RCC_SAI2CLKSOURCE(PeriphClkInit
->Sai2ClockSelection
));
179 /* Configure SAI2 Clock source */
180 __HAL_RCC_SAI2_CONFIG(PeriphClkInit
->Sai2ClockSelection
);
182 /* Enable the PLLI2S when it's used as clock source for SAI */
183 if(PeriphClkInit
->Sai2ClockSelection
== RCC_SAI2CLKSOURCE_PLLI2S
)
187 /* Enable the PLLSAI when it's used as clock source for SAI */
188 if(PeriphClkInit
->Sai2ClockSelection
== RCC_SAI2CLKSOURCE_PLLSAI
)
194 /*-------------------------------------- SPDIF-RX Configuration -----------------------------------*/
195 if(((PeriphClkInit
->PeriphClockSelection
) & RCC_PERIPHCLK_SPDIFRX
) == RCC_PERIPHCLK_SPDIFRX
)
200 /*------------------------------------ RTC configuration --------------------------------------*/
201 if(((PeriphClkInit
->PeriphClockSelection
) & RCC_PERIPHCLK_RTC
) == (RCC_PERIPHCLK_RTC
))
203 /* Check for RTC Parameters used to output RTCCLK */
204 assert_param(IS_RCC_RTCCLKSOURCE(PeriphClkInit
->RTCClockSelection
));
206 /* Enable Power Clock*/
207 __HAL_RCC_PWR_CLK_ENABLE();
209 /* Enable write access to Backup domain */
210 PWR
->CR1
|= PWR_CR1_DBP
;
213 tickstart
= HAL_GetTick();
215 /* Wait for Backup domain Write protection disable */
216 while((PWR
->CR1
& PWR_CR1_DBP
) == RESET
)
218 if((HAL_GetTick() - tickstart
) > RCC_DBP_TIMEOUT_VALUE
)
224 /* Reset the Backup domain only if the RTC Clock source selection is modified */
225 tmpreg0
= (RCC
->BDCR
& RCC_BDCR_RTCSEL
);
227 if((tmpreg0
!= 0x00000000U
) && (tmpreg0
!= (PeriphClkInit
->RTCClockSelection
& RCC_BDCR_RTCSEL
)))
229 /* Store the content of BDCR register before the reset of Backup Domain */
230 tmpreg0
= (RCC
->BDCR
& ~(RCC_BDCR_RTCSEL
));
232 /* RTC Clock selection can be changed only if the Backup Domain is reset */
233 __HAL_RCC_BACKUPRESET_FORCE();
234 __HAL_RCC_BACKUPRESET_RELEASE();
236 /* Restore the Content of BDCR register */
239 /* Wait for LSE reactivation if LSE was enable prior to Backup Domain reset */
240 if (HAL_IS_BIT_SET(RCC
->BDCR
, RCC_BDCR_LSEON
))
243 tickstart
= HAL_GetTick();
245 /* Wait till LSE is ready */
246 while(__HAL_RCC_GET_FLAG(RCC_FLAG_LSERDY
) == RESET
)
248 if((HAL_GetTick() - tickstart
) > RCC_LSE_TIMEOUT_VALUE
)
255 __HAL_RCC_RTC_CONFIG(PeriphClkInit
->RTCClockSelection
);
258 /*------------------------------------ TIM configuration --------------------------------------*/
259 if(((PeriphClkInit
->PeriphClockSelection
) & RCC_PERIPHCLK_TIM
) == (RCC_PERIPHCLK_TIM
))
261 /* Check the parameters */
262 assert_param(IS_RCC_TIMPRES(PeriphClkInit
->TIMPresSelection
));
264 /* Configure Timer Prescaler */
265 __HAL_RCC_TIMCLKPRESCALER(PeriphClkInit
->TIMPresSelection
);
268 /*-------------------------------------- I2C1 Configuration -----------------------------------*/
269 if(((PeriphClkInit
->PeriphClockSelection
) & RCC_PERIPHCLK_I2C1
) == RCC_PERIPHCLK_I2C1
)
271 /* Check the parameters */
272 assert_param(IS_RCC_I2C1CLKSOURCE(PeriphClkInit
->I2c1ClockSelection
));
274 /* Configure the I2C1 clock source */
275 __HAL_RCC_I2C1_CONFIG(PeriphClkInit
->I2c1ClockSelection
);
278 /*-------------------------------------- I2C2 Configuration -----------------------------------*/
279 if(((PeriphClkInit
->PeriphClockSelection
) & RCC_PERIPHCLK_I2C2
) == RCC_PERIPHCLK_I2C2
)
281 /* Check the parameters */
282 assert_param(IS_RCC_I2C2CLKSOURCE(PeriphClkInit
->I2c2ClockSelection
));
284 /* Configure the I2C2 clock source */
285 __HAL_RCC_I2C2_CONFIG(PeriphClkInit
->I2c2ClockSelection
);
288 /*-------------------------------------- I2C3 Configuration -----------------------------------*/
289 if(((PeriphClkInit
->PeriphClockSelection
) & RCC_PERIPHCLK_I2C3
) == RCC_PERIPHCLK_I2C3
)
291 /* Check the parameters */
292 assert_param(IS_RCC_I2C3CLKSOURCE(PeriphClkInit
->I2c3ClockSelection
));
294 /* Configure the I2C3 clock source */
295 __HAL_RCC_I2C3_CONFIG(PeriphClkInit
->I2c3ClockSelection
);
298 /*-------------------------------------- I2C4 Configuration -----------------------------------*/
299 if(((PeriphClkInit
->PeriphClockSelection
) & RCC_PERIPHCLK_I2C4
) == RCC_PERIPHCLK_I2C4
)
301 /* Check the parameters */
302 assert_param(IS_RCC_I2C4CLKSOURCE(PeriphClkInit
->I2c4ClockSelection
));
304 /* Configure the I2C4 clock source */
305 __HAL_RCC_I2C4_CONFIG(PeriphClkInit
->I2c4ClockSelection
);
308 /*-------------------------------------- USART1 Configuration -----------------------------------*/
309 if(((PeriphClkInit
->PeriphClockSelection
) & RCC_PERIPHCLK_USART1
) == RCC_PERIPHCLK_USART1
)
311 /* Check the parameters */
312 assert_param(IS_RCC_USART1CLKSOURCE(PeriphClkInit
->Usart1ClockSelection
));
314 /* Configure the USART1 clock source */
315 __HAL_RCC_USART1_CONFIG(PeriphClkInit
->Usart1ClockSelection
);
318 /*-------------------------------------- USART2 Configuration -----------------------------------*/
319 if(((PeriphClkInit
->PeriphClockSelection
) & RCC_PERIPHCLK_USART2
) == RCC_PERIPHCLK_USART2
)
321 /* Check the parameters */
322 assert_param(IS_RCC_USART2CLKSOURCE(PeriphClkInit
->Usart2ClockSelection
));
324 /* Configure the USART2 clock source */
325 __HAL_RCC_USART2_CONFIG(PeriphClkInit
->Usart2ClockSelection
);
328 /*-------------------------------------- USART3 Configuration -----------------------------------*/
329 if(((PeriphClkInit
->PeriphClockSelection
) & RCC_PERIPHCLK_USART3
) == RCC_PERIPHCLK_USART3
)
331 /* Check the parameters */
332 assert_param(IS_RCC_USART3CLKSOURCE(PeriphClkInit
->Usart3ClockSelection
));
334 /* Configure the USART3 clock source */
335 __HAL_RCC_USART3_CONFIG(PeriphClkInit
->Usart3ClockSelection
);
338 /*-------------------------------------- UART4 Configuration -----------------------------------*/
339 if(((PeriphClkInit
->PeriphClockSelection
) & RCC_PERIPHCLK_UART4
) == RCC_PERIPHCLK_UART4
)
341 /* Check the parameters */
342 assert_param(IS_RCC_UART4CLKSOURCE(PeriphClkInit
->Uart4ClockSelection
));
344 /* Configure the UART4 clock source */
345 __HAL_RCC_UART4_CONFIG(PeriphClkInit
->Uart4ClockSelection
);
348 /*-------------------------------------- UART5 Configuration -----------------------------------*/
349 if(((PeriphClkInit
->PeriphClockSelection
) & RCC_PERIPHCLK_UART5
) == RCC_PERIPHCLK_UART5
)
351 /* Check the parameters */
352 assert_param(IS_RCC_UART5CLKSOURCE(PeriphClkInit
->Uart5ClockSelection
));
354 /* Configure the UART5 clock source */
355 __HAL_RCC_UART5_CONFIG(PeriphClkInit
->Uart5ClockSelection
);
358 /*-------------------------------------- USART6 Configuration -----------------------------------*/
359 if(((PeriphClkInit
->PeriphClockSelection
) & RCC_PERIPHCLK_USART6
) == RCC_PERIPHCLK_USART6
)
361 /* Check the parameters */
362 assert_param(IS_RCC_USART6CLKSOURCE(PeriphClkInit
->Usart6ClockSelection
));
364 /* Configure the USART6 clock source */
365 __HAL_RCC_USART6_CONFIG(PeriphClkInit
->Usart6ClockSelection
);
368 /*-------------------------------------- UART7 Configuration -----------------------------------*/
369 if(((PeriphClkInit
->PeriphClockSelection
) & RCC_PERIPHCLK_UART7
) == RCC_PERIPHCLK_UART7
)
371 /* Check the parameters */
372 assert_param(IS_RCC_UART7CLKSOURCE(PeriphClkInit
->Uart7ClockSelection
));
374 /* Configure the UART7 clock source */
375 __HAL_RCC_UART7_CONFIG(PeriphClkInit
->Uart7ClockSelection
);
378 /*-------------------------------------- UART8 Configuration -----------------------------------*/
379 if(((PeriphClkInit
->PeriphClockSelection
) & RCC_PERIPHCLK_UART8
) == RCC_PERIPHCLK_UART8
)
381 /* Check the parameters */
382 assert_param(IS_RCC_UART8CLKSOURCE(PeriphClkInit
->Uart8ClockSelection
));
384 /* Configure the UART8 clock source */
385 __HAL_RCC_UART8_CONFIG(PeriphClkInit
->Uart8ClockSelection
);
388 /*--------------------------------------- CEC Configuration -----------------------------------*/
389 if(((PeriphClkInit
->PeriphClockSelection
) & RCC_PERIPHCLK_CEC
) == RCC_PERIPHCLK_CEC
)
391 /* Check the parameters */
392 assert_param(IS_RCC_CECCLKSOURCE(PeriphClkInit
->CecClockSelection
));
394 /* Configure the CEC clock source */
395 __HAL_RCC_CEC_CONFIG(PeriphClkInit
->CecClockSelection
);
398 /*-------------------------------------- CK48 Configuration -----------------------------------*/
399 if(((PeriphClkInit
->PeriphClockSelection
) & RCC_PERIPHCLK_CLK48
) == RCC_PERIPHCLK_CLK48
)
401 /* Check the parameters */
402 assert_param(IS_RCC_CLK48SOURCE(PeriphClkInit
->Clk48ClockSelection
));
404 /* Configure the CLK48 source */
405 __HAL_RCC_CLK48_CONFIG(PeriphClkInit
->Clk48ClockSelection
);
407 /* Enable the PLLSAI when it's used as clock source for CK48 */
408 if(PeriphClkInit
->Clk48ClockSelection
== RCC_CLK48SOURCE_PLLSAIP
)
414 /*-------------------------------------- LTDC Configuration -----------------------------------*/
415 #if defined(STM32F746xx) || defined(STM32F756xx) || defined (STM32F767xx) || defined (STM32F769xx) || defined (STM32F777xx) || defined (STM32F779xx)
416 if(((PeriphClkInit
->PeriphClockSelection
) & RCC_PERIPHCLK_LTDC
) == RCC_PERIPHCLK_LTDC
)
420 #endif /* STM32F746xx || STM32F756xx || STM32F767xx || STM32F769xx || STM32F777xx || STM32F779xx */
422 /*-------------------------------------- LPTIM1 Configuration -----------------------------------*/
423 if(((PeriphClkInit
->PeriphClockSelection
) & RCC_PERIPHCLK_LPTIM1
) == RCC_PERIPHCLK_LPTIM1
)
425 /* Check the parameters */
426 assert_param(IS_RCC_LPTIM1CLK(PeriphClkInit
->Lptim1ClockSelection
));
428 /* Configure the LTPIM1 clock source */
429 __HAL_RCC_LPTIM1_CONFIG(PeriphClkInit
->Lptim1ClockSelection
);
432 /*------------------------------------- SDMMC1 Configuration ------------------------------------*/
433 if(((PeriphClkInit
->PeriphClockSelection
) & RCC_PERIPHCLK_SDMMC1
) == RCC_PERIPHCLK_SDMMC1
)
435 /* Check the parameters */
436 assert_param(IS_RCC_SDMMC1CLKSOURCE(PeriphClkInit
->Sdmmc1ClockSelection
));
438 /* Configure the SDMMC1 clock source */
439 __HAL_RCC_SDMMC1_CONFIG(PeriphClkInit
->Sdmmc1ClockSelection
);
442 #if defined (STM32F765xx) || defined (STM32F767xx) || defined (STM32F769xx) || defined (STM32F777xx) || defined (STM32F779xx)
443 /*------------------------------------- SDMMC2 Configuration ------------------------------------*/
444 if(((PeriphClkInit
->PeriphClockSelection
) & RCC_PERIPHCLK_SDMMC2
) == RCC_PERIPHCLK_SDMMC2
)
446 /* Check the parameters */
447 assert_param(IS_RCC_SDMMC2CLKSOURCE(PeriphClkInit
->Sdmmc2ClockSelection
));
449 /* Configure the SDMMC2 clock source */
450 __HAL_RCC_SDMMC2_CONFIG(PeriphClkInit
->Sdmmc2ClockSelection
);
453 /*------------------------------------- DFSDM1 Configuration -------------------------------------*/
454 if(((PeriphClkInit
->PeriphClockSelection
) & RCC_PERIPHCLK_DFSDM1
) == RCC_PERIPHCLK_DFSDM1
)
456 /* Check the parameters */
457 assert_param(IS_RCC_DFSDM1CLKSOURCE(PeriphClkInit
->Dfsdm1ClockSelection
));
459 /* Configure the DFSDM1 interface clock source */
460 __HAL_RCC_DFSDM1_CONFIG(PeriphClkInit
->Dfsdm1ClockSelection
);
463 /*------------------------------------- DFSDM AUDIO Configuration -------------------------------------*/
464 if(((PeriphClkInit
->PeriphClockSelection
) & RCC_PERIPHCLK_DFSDM1_AUDIO
) == RCC_PERIPHCLK_DFSDM1_AUDIO
)
466 /* Check the parameters */
467 assert_param(IS_RCC_DFSDM1AUDIOCLKSOURCE(PeriphClkInit
->Dfsdm1AudioClockSelection
));
469 /* Configure the DFSDM interface clock source */
470 __HAL_RCC_DFSDM1AUDIO_CONFIG(PeriphClkInit
->Dfsdm1AudioClockSelection
);
472 #endif /* STM32F767xx || STM32F769xx || STM32F777xx || STM32F779xx */
474 /*-------------------------------------- PLLI2S Configuration ---------------------------------*/
475 /* PLLI2S is configured when a peripheral will use it as source clock : SAI1, SAI2, I2S or SPDIF-RX */
476 if((plli2sused
== 1) || (PeriphClkInit
->PeriphClockSelection
== RCC_PERIPHCLK_PLLI2S
))
478 /* Disable the PLLI2S */
479 __HAL_RCC_PLLI2S_DISABLE();
482 tickstart
= HAL_GetTick();
484 /* Wait till PLLI2S is disabled */
485 while(__HAL_RCC_GET_FLAG(RCC_FLAG_PLLI2SRDY
) != RESET
)
487 if((HAL_GetTick() - tickstart
) > PLLI2S_TIMEOUT_VALUE
)
489 /* return in case of Timeout detected */
494 /* check for common PLLI2S Parameters */
495 assert_param(IS_RCC_PLLI2SN_VALUE(PeriphClkInit
->PLLI2S
.PLLI2SN
));
497 /*----------------- In Case of PLLI2S is selected as source clock for I2S -------------------*/
498 if(((((PeriphClkInit
->PeriphClockSelection
) & RCC_PERIPHCLK_I2S
) == RCC_PERIPHCLK_I2S
) && (PeriphClkInit
->I2sClockSelection
== RCC_I2SCLKSOURCE_PLLI2S
)))
500 /* check for Parameters */
501 assert_param(IS_RCC_PLLI2SR_VALUE(PeriphClkInit
->PLLI2S
.PLLI2SR
));
503 /* Read PLLI2SP and PLLI2SQ value from PLLI2SCFGR register (this value is not needed for I2S configuration) */
504 tmpreg0
= ((RCC
->PLLI2SCFGR
& RCC_PLLI2SCFGR_PLLI2SP
) >> POSITION_VAL(RCC_PLLI2SCFGR_PLLI2SP
));
505 tmpreg1
= ((RCC
->PLLI2SCFGR
& RCC_PLLI2SCFGR_PLLI2SQ
) >> POSITION_VAL(RCC_PLLI2SCFGR_PLLI2SQ
));
506 /* Configure the PLLI2S division factors */
507 /* PLLI2S_VCO = f(VCO clock) = f(PLLI2S clock input) x (PLLI2SN/PLLM) */
508 /* I2SCLK = f(PLLI2S clock output) = f(VCO clock) / PLLI2SR */
509 __HAL_RCC_PLLI2S_CONFIG(PeriphClkInit
->PLLI2S
.PLLI2SN
, tmpreg0
, tmpreg1
, PeriphClkInit
->PLLI2S
.PLLI2SR
);
512 /*----------------- In Case of PLLI2S is selected as source clock for SAI -------------------*/
513 if(((((PeriphClkInit
->PeriphClockSelection
) & RCC_PERIPHCLK_SAI1
) == RCC_PERIPHCLK_SAI1
) && (PeriphClkInit
->Sai1ClockSelection
== RCC_SAI1CLKSOURCE_PLLI2S
)) ||
514 ((((PeriphClkInit
->PeriphClockSelection
) & RCC_PERIPHCLK_SAI2
) == RCC_PERIPHCLK_SAI2
) && (PeriphClkInit
->Sai2ClockSelection
== RCC_SAI2CLKSOURCE_PLLI2S
)))
516 /* Check for PLLI2S Parameters */
517 assert_param(IS_RCC_PLLI2SQ_VALUE(PeriphClkInit
->PLLI2S
.PLLI2SQ
));
518 /* Check for PLLI2S/DIVQ parameters */
519 assert_param(IS_RCC_PLLI2S_DIVQ_VALUE(PeriphClkInit
->PLLI2SDivQ
));
521 /* Read PLLI2SP and PLLI2SR values from PLLI2SCFGR register (this value is not needed for SAI configuration) */
522 tmpreg0
= ((RCC
->PLLI2SCFGR
& RCC_PLLI2SCFGR_PLLI2SP
) >> POSITION_VAL(RCC_PLLI2SCFGR_PLLI2SP
));
523 tmpreg1
= ((RCC
->PLLI2SCFGR
& RCC_PLLI2SCFGR_PLLI2SR
) >> POSITION_VAL(RCC_PLLI2SCFGR_PLLI2SR
));
524 /* Configure the PLLI2S division factors */
525 /* PLLI2S_VCO Input = PLL_SOURCE/PLLM */
526 /* PLLI2S_VCO Output = PLLI2S_VCO Input * PLLI2SN */
527 /* SAI_CLK(first level) = PLLI2S_VCO Output/PLLI2SQ */
528 __HAL_RCC_PLLI2S_CONFIG(PeriphClkInit
->PLLI2S
.PLLI2SN
, tmpreg0
, PeriphClkInit
->PLLI2S
.PLLI2SQ
, tmpreg1
);
530 /* SAI_CLK_x = SAI_CLK(first level)/PLLI2SDIVQ */
531 __HAL_RCC_PLLI2S_PLLSAICLKDIVQ_CONFIG(PeriphClkInit
->PLLI2SDivQ
);
534 /*----------------- In Case of PLLI2S is selected as source clock for SPDIF-RX -------------------*/
535 if(((PeriphClkInit
->PeriphClockSelection
) & RCC_PERIPHCLK_SPDIFRX
) == RCC_PERIPHCLK_SPDIFRX
)
537 /* check for Parameters */
538 assert_param(IS_RCC_PLLI2SP_VALUE(PeriphClkInit
->PLLI2S
.PLLI2SP
));
540 /* Read PLLI2SR value from PLLI2SCFGR register (this value is not needed for SPDIF-RX configuration) */
541 tmpreg0
= ((RCC
->PLLI2SCFGR
& RCC_PLLI2SCFGR_PLLI2SQ
) >> POSITION_VAL(RCC_PLLI2SCFGR_PLLI2SQ
));
542 tmpreg1
= ((RCC
->PLLI2SCFGR
& RCC_PLLI2SCFGR_PLLI2SR
) >> POSITION_VAL(RCC_PLLI2SCFGR_PLLI2SR
));
543 /* Configure the PLLI2S division factors */
544 /* PLLI2S_VCO = f(VCO clock) = f(PLLI2S clock input) x (PLLI2SN/PLLM) */
545 /* SPDIFCLK = f(PLLI2S clock output) = f(VCO clock) / PLLI2SP */
546 __HAL_RCC_PLLI2S_CONFIG(PeriphClkInit
->PLLI2S
.PLLI2SN
, PeriphClkInit
->PLLI2S
.PLLI2SP
, tmpreg0
, tmpreg1
);
549 /*----------------- In Case of PLLI2S is just selected -----------------*/
550 if((PeriphClkInit
->PeriphClockSelection
& RCC_PERIPHCLK_PLLI2S
) == RCC_PERIPHCLK_PLLI2S
)
552 /* Check for Parameters */
553 assert_param(IS_RCC_PLLI2SP_VALUE(PeriphClkInit
->PLLI2S
.PLLI2SP
));
554 assert_param(IS_RCC_PLLI2SR_VALUE(PeriphClkInit
->PLLI2S
.PLLI2SR
));
555 assert_param(IS_RCC_PLLI2SQ_VALUE(PeriphClkInit
->PLLI2S
.PLLI2SQ
));
557 /* Configure the PLLI2S division factors */
558 /* PLLI2S_VCO = f(VCO clock) = f(PLLI2S clock input) x (PLLI2SN/PLLI2SM) */
559 /* SPDIFRXCLK = f(PLLI2S clock output) = f(VCO clock) / PLLI2SP */
560 __HAL_RCC_PLLI2S_CONFIG(PeriphClkInit
->PLLI2S
.PLLI2SN
, PeriphClkInit
->PLLI2S
.PLLI2SP
, PeriphClkInit
->PLLI2S
.PLLI2SQ
, PeriphClkInit
->PLLI2S
.PLLI2SR
);
563 /* Enable the PLLI2S */
564 __HAL_RCC_PLLI2S_ENABLE();
567 tickstart
= HAL_GetTick();
569 /* Wait till PLLI2S is ready */
570 while(__HAL_RCC_GET_FLAG(RCC_FLAG_PLLI2SRDY
) == RESET
)
572 if((HAL_GetTick() - tickstart
) > PLLI2S_TIMEOUT_VALUE
)
574 /* return in case of Timeout detected */
580 /*-------------------------------------- PLLSAI Configuration ---------------------------------*/
581 /* PLLSAI is configured when a peripheral will use it as source clock : SAI1, SAI2, LTDC or CK48 */
584 /* Disable PLLSAI Clock */
585 __HAL_RCC_PLLSAI_DISABLE();
588 tickstart
= HAL_GetTick();
590 /* Wait till PLLSAI is disabled */
591 while(__HAL_RCC_PLLSAI_GET_FLAG() != RESET
)
593 if((HAL_GetTick() - tickstart
) > PLLSAI_TIMEOUT_VALUE
)
595 /* return in case of Timeout detected */
600 /* Check the PLLSAI division factors */
601 assert_param(IS_RCC_PLLSAIN_VALUE(PeriphClkInit
->PLLSAI
.PLLSAIN
));
603 /*----------------- In Case of PLLSAI is selected as source clock for SAI -------------------*/
604 if(((((PeriphClkInit
->PeriphClockSelection
) & RCC_PERIPHCLK_SAI1
) == RCC_PERIPHCLK_SAI1
) && (PeriphClkInit
->Sai1ClockSelection
== RCC_SAI1CLKSOURCE_PLLSAI
)) ||\
605 ((((PeriphClkInit
->PeriphClockSelection
) & RCC_PERIPHCLK_SAI2
) == RCC_PERIPHCLK_SAI2
) && (PeriphClkInit
->Sai2ClockSelection
== RCC_SAI2CLKSOURCE_PLLSAI
)))
607 /* check for PLLSAIQ Parameter */
608 assert_param(IS_RCC_PLLSAIQ_VALUE(PeriphClkInit
->PLLSAI
.PLLSAIQ
));
609 /* check for PLLSAI/DIVQ Parameter */
610 assert_param(IS_RCC_PLLSAI_DIVQ_VALUE(PeriphClkInit
->PLLSAIDivQ
));
612 /* Read PLLSAIP value from PLLSAICFGR register (this value is not needed for SAI configuration) */
613 tmpreg0
= ((RCC
->PLLSAICFGR
& RCC_PLLSAICFGR_PLLSAIP
) >> POSITION_VAL(RCC_PLLSAICFGR_PLLSAIP
));
614 tmpreg1
= ((RCC
->PLLSAICFGR
& RCC_PLLI2SCFGR_PLLI2SR
) >> POSITION_VAL(RCC_PLLSAICFGR_PLLSAIR
));
615 /* PLLSAI_VCO Input = PLL_SOURCE/PLLM */
616 /* PLLSAI_VCO Output = PLLSAI_VCO Input * PLLSAIN */
617 /* SAI_CLK(first level) = PLLSAI_VCO Output/PLLSAIQ */
618 __HAL_RCC_PLLSAI_CONFIG(PeriphClkInit
->PLLSAI
.PLLSAIN
, tmpreg0
, PeriphClkInit
->PLLSAI
.PLLSAIQ
, tmpreg1
);
620 /* SAI_CLK_x = SAI_CLK(first level)/PLLSAIDIVQ */
621 __HAL_RCC_PLLSAI_PLLSAICLKDIVQ_CONFIG(PeriphClkInit
->PLLSAIDivQ
);
624 /*----------------- In Case of PLLSAI is selected as source clock for CLK48 -------------------*/
625 /* In Case of PLLI2S is selected as source clock for CK48 */
626 if((((PeriphClkInit
->PeriphClockSelection
) & RCC_PERIPHCLK_CLK48
) == RCC_PERIPHCLK_CLK48
) && (PeriphClkInit
->Clk48ClockSelection
== RCC_CLK48SOURCE_PLLSAIP
))
628 /* check for Parameters */
629 assert_param(IS_RCC_PLLSAIP_VALUE(PeriphClkInit
->PLLSAI
.PLLSAIP
));
630 /* Read PLLSAIQ and PLLSAIR value from PLLSAICFGR register (this value is not needed for CK48 configuration) */
631 tmpreg0
= ((RCC
->PLLSAICFGR
& RCC_PLLSAICFGR_PLLSAIQ
) >> POSITION_VAL(RCC_PLLSAICFGR_PLLSAIQ
));
632 tmpreg1
= ((RCC
->PLLSAICFGR
& RCC_PLLSAICFGR_PLLSAIR
) >> POSITION_VAL(RCC_PLLSAICFGR_PLLSAIR
));
634 /* Configure the PLLSAI division factors */
635 /* PLLSAI_VCO = f(VCO clock) = f(PLLSAI clock input) x (PLLI2SN/PLLM) */
636 /* 48CLK = f(PLLSAI clock output) = f(VCO clock) / PLLSAIP */
637 __HAL_RCC_PLLSAI_CONFIG(PeriphClkInit
->PLLSAI
.PLLSAIN
, PeriphClkInit
->PLLSAI
.PLLSAIP
, tmpreg0
, tmpreg1
);
640 #if defined(STM32F746xx) || defined(STM32F756xx) || defined (STM32F767xx) || defined (STM32F769xx) || defined (STM32F777xx) || defined (STM32F779xx)
641 /*---------------------------- LTDC configuration -------------------------------*/
642 if(((PeriphClkInit
->PeriphClockSelection
) & RCC_PERIPHCLK_LTDC
) == (RCC_PERIPHCLK_LTDC
))
644 assert_param(IS_RCC_PLLSAIR_VALUE(PeriphClkInit
->PLLSAI
.PLLSAIR
));
645 assert_param(IS_RCC_PLLSAI_DIVR_VALUE(PeriphClkInit
->PLLSAIDivR
));
647 /* Read PLLSAIP and PLLSAIQ value from PLLSAICFGR register (these value are not needed for LTDC configuration) */
648 tmpreg0
= ((RCC
->PLLSAICFGR
& RCC_PLLSAICFGR_PLLSAIQ
) >> POSITION_VAL(RCC_PLLSAICFGR_PLLSAIQ
));
649 tmpreg1
= ((RCC
->PLLSAICFGR
& RCC_PLLSAICFGR_PLLSAIP
) >> POSITION_VAL(RCC_PLLSAICFGR_PLLSAIP
));
651 /* PLLSAI_VCO Input = PLL_SOURCE/PLLM */
652 /* PLLSAI_VCO Output = PLLSAI_VCO Input * PLLSAIN */
653 /* LTDC_CLK(first level) = PLLSAI_VCO Output/PLLSAIR */
654 __HAL_RCC_PLLSAI_CONFIG(PeriphClkInit
->PLLSAI
.PLLSAIN
, tmpreg1
, tmpreg0
, PeriphClkInit
->PLLSAI
.PLLSAIR
);
656 /* LTDC_CLK = LTDC_CLK(first level)/PLLSAIDIVR */
657 __HAL_RCC_PLLSAI_PLLSAICLKDIVR_CONFIG(PeriphClkInit
->PLLSAIDivR
);
659 #endif /* STM32F746xx || STM32F756xx || STM32F767xx || STM32F769xx || STM32F777xx || STM32F779xx */
661 /* Enable PLLSAI Clock */
662 __HAL_RCC_PLLSAI_ENABLE();
665 tickstart
= HAL_GetTick();
667 /* Wait till PLLSAI is ready */
668 while(__HAL_RCC_PLLSAI_GET_FLAG() == RESET
)
670 if((HAL_GetTick() - tickstart
) > PLLSAI_TIMEOUT_VALUE
)
672 /* return in case of Timeout detected */
681 * @brief Get the RCC_PeriphCLKInitTypeDef according to the internal
682 * RCC configuration registers.
683 * @param PeriphClkInit: pointer to the configured RCC_PeriphCLKInitTypeDef structure
686 void HAL_RCCEx_GetPeriphCLKConfig(RCC_PeriphCLKInitTypeDef
*PeriphClkInit
)
688 uint32_t tempreg
= 0;
690 /* Set all possible values for the extended clock type parameter------------*/
691 #if defined (STM32F765xx) || defined (STM32F767xx) || defined (STM32F769xx) || defined (STM32F777xx) || defined (STM32F779xx)
692 PeriphClkInit
->PeriphClockSelection
= RCC_PERIPHCLK_I2S
| RCC_PERIPHCLK_LPTIM1
|\
693 RCC_PERIPHCLK_SAI1
| RCC_PERIPHCLK_SAI2
|\
694 RCC_PERIPHCLK_TIM
| RCC_PERIPHCLK_RTC
|\
695 RCC_PERIPHCLK_CEC
| RCC_PERIPHCLK_I2C4
|\
696 RCC_PERIPHCLK_I2C1
| RCC_PERIPHCLK_I2C2
|\
697 RCC_PERIPHCLK_I2C3
| RCC_PERIPHCLK_USART1
|\
698 RCC_PERIPHCLK_USART2
| RCC_PERIPHCLK_USART3
|\
699 RCC_PERIPHCLK_UART4
| RCC_PERIPHCLK_UART5
|\
700 RCC_PERIPHCLK_USART6
| RCC_PERIPHCLK_UART7
|\
701 RCC_PERIPHCLK_UART8
| RCC_PERIPHCLK_SDMMC1
|\
702 RCC_PERIPHCLK_CLK48
| RCC_PERIPHCLK_SDMMC2
|\
703 RCC_PERIPHCLK_DFSDM1
| RCC_PERIPHCLK_DFSDM1_AUDIO
;
705 PeriphClkInit
->PeriphClockSelection
= RCC_PERIPHCLK_I2S
| RCC_PERIPHCLK_LPTIM1
|\
706 RCC_PERIPHCLK_SAI1
| RCC_PERIPHCLK_SAI2
|\
707 RCC_PERIPHCLK_TIM
| RCC_PERIPHCLK_RTC
|\
708 RCC_PERIPHCLK_CEC
| RCC_PERIPHCLK_I2C4
|\
709 RCC_PERIPHCLK_I2C1
| RCC_PERIPHCLK_I2C2
|\
710 RCC_PERIPHCLK_I2C3
| RCC_PERIPHCLK_USART1
|\
711 RCC_PERIPHCLK_USART2
| RCC_PERIPHCLK_USART3
|\
712 RCC_PERIPHCLK_UART4
| RCC_PERIPHCLK_UART5
|\
713 RCC_PERIPHCLK_USART6
| RCC_PERIPHCLK_UART7
|\
714 RCC_PERIPHCLK_UART8
| RCC_PERIPHCLK_SDMMC1
|\
716 #endif /* STM32F767xx || STM32F769xx || STM32F777xx || STM32F779xx */
718 /* Get the PLLI2S Clock configuration -----------------------------------------------*/
719 PeriphClkInit
->PLLI2S
.PLLI2SN
= (uint32_t)((RCC
->PLLI2SCFGR
& RCC_PLLI2SCFGR_PLLI2SN
) >> POSITION_VAL(RCC_PLLI2SCFGR_PLLI2SN
));
720 PeriphClkInit
->PLLI2S
.PLLI2SP
= (uint32_t)((RCC
->PLLI2SCFGR
& RCC_PLLI2SCFGR_PLLI2SP
) >> POSITION_VAL(RCC_PLLI2SCFGR_PLLI2SP
));
721 PeriphClkInit
->PLLI2S
.PLLI2SQ
= (uint32_t)((RCC
->PLLI2SCFGR
& RCC_PLLI2SCFGR_PLLI2SQ
) >> POSITION_VAL(RCC_PLLI2SCFGR_PLLI2SQ
));
722 PeriphClkInit
->PLLI2S
.PLLI2SR
= (uint32_t)((RCC
->PLLI2SCFGR
& RCC_PLLI2SCFGR_PLLI2SR
) >> POSITION_VAL(RCC_PLLI2SCFGR_PLLI2SR
));
724 /* Get the PLLSAI Clock configuration -----------------------------------------------*/
725 PeriphClkInit
->PLLSAI
.PLLSAIN
= (uint32_t)((RCC
->PLLSAICFGR
& RCC_PLLSAICFGR_PLLSAIN
) >> POSITION_VAL(RCC_PLLSAICFGR_PLLSAIN
));
726 PeriphClkInit
->PLLSAI
.PLLSAIP
= (uint32_t)((RCC
->PLLSAICFGR
& RCC_PLLSAICFGR_PLLSAIP
) >> POSITION_VAL(RCC_PLLSAICFGR_PLLSAIP
));
727 PeriphClkInit
->PLLSAI
.PLLSAIQ
= (uint32_t)((RCC
->PLLSAICFGR
& RCC_PLLSAICFGR_PLLSAIQ
) >> POSITION_VAL(RCC_PLLSAICFGR_PLLSAIQ
));
728 PeriphClkInit
->PLLSAI
.PLLSAIR
= (uint32_t)((RCC
->PLLSAICFGR
& RCC_PLLSAICFGR_PLLSAIR
) >> POSITION_VAL(RCC_PLLSAICFGR_PLLSAIR
));
730 /* Get the PLLSAI/PLLI2S division factors -------------------------------------------*/
731 PeriphClkInit
->PLLI2SDivQ
= (uint32_t)((RCC
->DCKCFGR1
& RCC_DCKCFGR1_PLLI2SDIVQ
) >> POSITION_VAL(RCC_DCKCFGR1_PLLI2SDIVQ
));
732 PeriphClkInit
->PLLSAIDivQ
= (uint32_t)((RCC
->DCKCFGR1
& RCC_DCKCFGR1_PLLSAIDIVQ
) >> POSITION_VAL(RCC_DCKCFGR1_PLLSAIDIVQ
));
733 PeriphClkInit
->PLLSAIDivR
= (uint32_t)((RCC
->DCKCFGR1
& RCC_DCKCFGR1_PLLSAIDIVR
) >> POSITION_VAL(RCC_DCKCFGR1_PLLSAIDIVR
));
735 /* Get the SAI1 clock configuration ----------------------------------------------*/
736 PeriphClkInit
->Sai1ClockSelection
= __HAL_RCC_GET_SAI1_SOURCE();
738 /* Get the SAI2 clock configuration ----------------------------------------------*/
739 PeriphClkInit
->Sai2ClockSelection
= __HAL_RCC_GET_SAI2_SOURCE();
741 /* Get the I2S clock configuration ------------------------------------------*/
742 PeriphClkInit
->I2sClockSelection
= __HAL_RCC_GET_I2SCLKSOURCE();
744 /* Get the I2C1 clock configuration ------------------------------------------*/
745 PeriphClkInit
->I2c1ClockSelection
= __HAL_RCC_GET_I2C1_SOURCE();
747 /* Get the I2C2 clock configuration ------------------------------------------*/
748 PeriphClkInit
->I2c2ClockSelection
= __HAL_RCC_GET_I2C2_SOURCE();
750 /* Get the I2C3 clock configuration ------------------------------------------*/
751 PeriphClkInit
->I2c3ClockSelection
= __HAL_RCC_GET_I2C3_SOURCE();
753 /* Get the I2C4 clock configuration ------------------------------------------*/
754 PeriphClkInit
->I2c4ClockSelection
= __HAL_RCC_GET_I2C4_SOURCE();
756 /* Get the USART1 clock configuration ------------------------------------------*/
757 PeriphClkInit
->Usart1ClockSelection
= __HAL_RCC_GET_USART1_SOURCE();
759 /* Get the USART2 clock configuration ------------------------------------------*/
760 PeriphClkInit
->Usart2ClockSelection
= __HAL_RCC_GET_USART2_SOURCE();
762 /* Get the USART3 clock configuration ------------------------------------------*/
763 PeriphClkInit
->Usart3ClockSelection
= __HAL_RCC_GET_USART3_SOURCE();
765 /* Get the UART4 clock configuration ------------------------------------------*/
766 PeriphClkInit
->Uart4ClockSelection
= __HAL_RCC_GET_UART4_SOURCE();
768 /* Get the UART5 clock configuration ------------------------------------------*/
769 PeriphClkInit
->Uart5ClockSelection
= __HAL_RCC_GET_UART5_SOURCE();
771 /* Get the USART6 clock configuration ------------------------------------------*/
772 PeriphClkInit
->Usart6ClockSelection
= __HAL_RCC_GET_USART6_SOURCE();
774 /* Get the UART7 clock configuration ------------------------------------------*/
775 PeriphClkInit
->Uart7ClockSelection
= __HAL_RCC_GET_UART7_SOURCE();
777 /* Get the UART8 clock configuration ------------------------------------------*/
778 PeriphClkInit
->Uart8ClockSelection
= __HAL_RCC_GET_UART8_SOURCE();
780 /* Get the LPTIM1 clock configuration ------------------------------------------*/
781 PeriphClkInit
->Lptim1ClockSelection
= __HAL_RCC_GET_LPTIM1_SOURCE();
783 /* Get the CEC clock configuration -----------------------------------------------*/
784 PeriphClkInit
->CecClockSelection
= __HAL_RCC_GET_CEC_SOURCE();
786 /* Get the CK48 clock configuration -----------------------------------------------*/
787 PeriphClkInit
->Clk48ClockSelection
= __HAL_RCC_GET_CLK48_SOURCE();
789 /* Get the SDMMC1 clock configuration -----------------------------------------------*/
790 PeriphClkInit
->Sdmmc1ClockSelection
= __HAL_RCC_GET_SDMMC1_SOURCE();
792 #if defined (STM32F765xx) || defined (STM32F767xx) || defined (STM32F769xx) || defined (STM32F777xx) || defined (STM32F779xx)
793 /* Get the SDMMC2 clock configuration -----------------------------------------------*/
794 PeriphClkInit
->Sdmmc2ClockSelection
= __HAL_RCC_GET_SDMMC2_SOURCE();
796 /* Get the DFSDM clock configuration -----------------------------------------------*/
797 PeriphClkInit
->Dfsdm1ClockSelection
= __HAL_RCC_GET_DFSDM1_SOURCE();
799 /* Get the DFSDM AUDIO clock configuration -----------------------------------------------*/
800 PeriphClkInit
->Dfsdm1AudioClockSelection
= __HAL_RCC_GET_DFSDM1AUDIO_SOURCE();
801 #endif /* STM32F767xx || STM32F769xx || STM32F777xx || STM32F779xx */
803 /* Get the RTC Clock configuration -----------------------------------------------*/
804 tempreg
= (RCC
->CFGR
& RCC_CFGR_RTCPRE
);
805 PeriphClkInit
->RTCClockSelection
= (uint32_t)((tempreg
) | (RCC
->BDCR
& RCC_BDCR_RTCSEL
));
807 /* Get the TIM Prescaler configuration --------------------------------------------*/
808 if ((RCC
->DCKCFGR1
& RCC_DCKCFGR1_TIMPRE
) == RESET
)
810 PeriphClkInit
->TIMPresSelection
= RCC_TIMPRES_DESACTIVATED
;
814 PeriphClkInit
->TIMPresSelection
= RCC_TIMPRES_ACTIVATED
;
819 * @brief Return the peripheral clock frequency for a given peripheral(SAI..)
820 * @note Return 0 if peripheral clock identifier not managed by this API
821 * @param PeriphClk: Peripheral clock identifier
822 * This parameter can be one of the following values:
823 * @arg RCC_PERIPHCLK_SAI1: SAI1 peripheral clock
824 * @arg RCC_PERIPHCLK_SAI2: SAI2 peripheral clock
825 * @retval Frequency in KHz
827 uint32_t HAL_RCCEx_GetPeriphCLKFreq(uint32_t PeriphClk
)
830 /* This variable is used to store the SAI clock frequency (value in Hz) */
831 uint32_t frequency
= 0;
832 /* This variable is used to store the VCO Input (value in Hz) */
833 uint32_t vcoinput
= 0;
834 /* This variable is used to store the SAI clock source */
835 uint32_t saiclocksource
= 0;
837 if (PeriphClk
== RCC_PERIPHCLK_SAI1
)
839 saiclocksource
= RCC
->DCKCFGR1
;
840 saiclocksource
&= RCC_DCKCFGR1_SAI1SEL
;
841 switch (saiclocksource
)
843 case 0: /* PLLSAI is the clock source for SAI1 */
845 /* Configure the PLLSAI division factor */
846 /* PLLSAI_VCO Input = PLL_SOURCE/PLLM */
847 if((RCC
->PLLCFGR
& RCC_PLLCFGR_PLLSRC
) == RCC_PLLSOURCE_HSI
)
849 /* In Case the PLL Source is HSI (Internal Clock) */
850 vcoinput
= (HSI_VALUE
/ (uint32_t)(RCC
->PLLCFGR
& RCC_PLLCFGR_PLLM
));
854 /* In Case the PLL Source is HSE (External Clock) */
855 vcoinput
= ((HSE_VALUE
/ (uint32_t)(RCC
->PLLCFGR
& RCC_PLLCFGR_PLLM
)));
857 /* PLLSAI_VCO Output = PLLSAI_VCO Input * PLLSAIN */
858 /* SAI_CLK(first level) = PLLSAI_VCO Output/PLLSAIQ */
859 tmpreg
= (RCC
->PLLSAICFGR
& RCC_PLLSAICFGR_PLLSAIQ
) >> 24;
860 frequency
= (vcoinput
* ((RCC
->PLLSAICFGR
& RCC_PLLSAICFGR_PLLSAIN
) >> 6))/(tmpreg
);
862 /* SAI_CLK_x = SAI_CLK(first level)/PLLSAIDIVQ */
863 tmpreg
= (((RCC
->DCKCFGR1
& RCC_DCKCFGR1_PLLSAIDIVQ
) >> 8) + 1);
864 frequency
= frequency
/(tmpreg
);
867 case RCC_DCKCFGR1_SAI1SEL_0
: /* PLLI2S is the clock source for SAI1 */
869 /* Configure the PLLI2S division factor */
870 /* PLLI2S_VCO Input = PLL_SOURCE/PLLM */
871 if((RCC
->PLLCFGR
& RCC_PLLCFGR_PLLSRC
) == RCC_PLLSOURCE_HSI
)
873 /* In Case the PLL Source is HSI (Internal Clock) */
874 vcoinput
= (HSI_VALUE
/ (uint32_t)(RCC
->PLLCFGR
& RCC_PLLCFGR_PLLM
));
878 /* In Case the PLL Source is HSE (External Clock) */
879 vcoinput
= ((HSE_VALUE
/ (uint32_t)(RCC
->PLLCFGR
& RCC_PLLCFGR_PLLM
)));
882 /* PLLI2S_VCO Output = PLLI2S_VCO Input * PLLI2SN */
883 /* SAI_CLK(first level) = PLLI2S_VCO Output/PLLI2SQ */
884 tmpreg
= (RCC
->PLLI2SCFGR
& RCC_PLLI2SCFGR_PLLI2SQ
) >> 24;
885 frequency
= (vcoinput
* ((RCC
->PLLI2SCFGR
& RCC_PLLI2SCFGR_PLLI2SN
) >> 6))/(tmpreg
);
887 /* SAI_CLK_x = SAI_CLK(first level)/PLLI2SDIVQ */
888 tmpreg
= ((RCC
->DCKCFGR1
& RCC_DCKCFGR1_PLLI2SDIVQ
) + 1);
889 frequency
= frequency
/(tmpreg
);
892 case RCC_DCKCFGR1_SAI1SEL_1
: /* External clock is the clock source for SAI1 */
894 frequency
= EXTERNAL_CLOCK_VALUE
;
897 #if defined (STM32F765xx) || defined (STM32F767xx) || defined (STM32F769xx) || defined (STM32F777xx) || defined (STM32F779xx)
898 case RCC_DCKCFGR1_SAI1SEL
: /* HSI or HSE is the clock source for SAI*/
900 if((RCC
->PLLCFGR
& RCC_PLLCFGR_PLLSRC
) == RCC_PLLSOURCE_HSI
)
902 /* In Case the main PLL Source is HSI */
903 frequency
= HSI_VALUE
;
907 /* In Case the main PLL Source is HSE */
908 frequency
= HSE_VALUE
;
912 #endif /* STM32F767xx || STM32F769xx || STM32F777xx || STM32F779xx */
920 if (PeriphClk
== RCC_PERIPHCLK_SAI2
)
922 saiclocksource
= RCC
->DCKCFGR1
;
923 saiclocksource
&= RCC_DCKCFGR1_SAI2SEL
;
924 switch (saiclocksource
)
926 case 0: /* PLLSAI is the clock source for SAI*/
928 /* Configure the PLLSAI division factor */
929 /* PLLSAI_VCO Input = PLL_SOURCE/PLLM */
930 if((RCC
->PLLCFGR
& RCC_PLLCFGR_PLLSRC
) == RCC_PLLSOURCE_HSI
)
932 /* In Case the PLL Source is HSI (Internal Clock) */
933 vcoinput
= (HSI_VALUE
/ (uint32_t)(RCC
->PLLCFGR
& RCC_PLLCFGR_PLLM
));
937 /* In Case the PLL Source is HSE (External Clock) */
938 vcoinput
= ((HSE_VALUE
/ (uint32_t)(RCC
->PLLCFGR
& RCC_PLLCFGR_PLLM
)));
940 /* PLLSAI_VCO Output = PLLSAI_VCO Input * PLLSAIN */
941 /* SAI_CLK(first level) = PLLSAI_VCO Output/PLLSAIQ */
942 tmpreg
= (RCC
->PLLSAICFGR
& RCC_PLLSAICFGR_PLLSAIQ
) >> 24;
943 frequency
= (vcoinput
* ((RCC
->PLLSAICFGR
& RCC_PLLSAICFGR_PLLSAIN
) >> 6))/(tmpreg
);
945 /* SAI_CLK_x = SAI_CLK(first level)/PLLSAIDIVQ */
946 tmpreg
= (((RCC
->DCKCFGR1
& RCC_DCKCFGR1_PLLSAIDIVQ
) >> 8) + 1);
947 frequency
= frequency
/(tmpreg
);
950 case RCC_DCKCFGR1_SAI2SEL_0
: /* PLLI2S is the clock source for SAI2 */
952 /* Configure the PLLI2S division factor */
953 /* PLLI2S_VCO Input = PLL_SOURCE/PLLM */
954 if((RCC
->PLLCFGR
& RCC_PLLCFGR_PLLSRC
) == RCC_PLLSOURCE_HSI
)
956 /* In Case the PLL Source is HSI (Internal Clock) */
957 vcoinput
= (HSI_VALUE
/ (uint32_t)(RCC
->PLLCFGR
& RCC_PLLCFGR_PLLM
));
961 /* In Case the PLL Source is HSE (External Clock) */
962 vcoinput
= ((HSE_VALUE
/ (uint32_t)(RCC
->PLLCFGR
& RCC_PLLCFGR_PLLM
)));
965 /* PLLI2S_VCO Output = PLLI2S_VCO Input * PLLI2SN */
966 /* SAI_CLK(first level) = PLLI2S_VCO Output/PLLI2SQ */
967 tmpreg
= (RCC
->PLLI2SCFGR
& RCC_PLLI2SCFGR_PLLI2SQ
) >> 24;
968 frequency
= (vcoinput
* ((RCC
->PLLI2SCFGR
& RCC_PLLI2SCFGR_PLLI2SN
) >> 6))/(tmpreg
);
970 /* SAI_CLK_x = SAI_CLK(first level)/PLLI2SDIVQ */
971 tmpreg
= ((RCC
->DCKCFGR1
& RCC_DCKCFGR1_PLLI2SDIVQ
) + 1);
972 frequency
= frequency
/(tmpreg
);
975 case RCC_DCKCFGR1_SAI2SEL_1
: /* External clock is the clock source for SAI2 */
977 frequency
= EXTERNAL_CLOCK_VALUE
;
980 #if defined (STM32F765xx) || defined (STM32F767xx) || defined (STM32F769xx) || defined (STM32F777xx) || defined (STM32F779xx)
981 case RCC_DCKCFGR1_SAI2SEL
: /* HSI or HSE is the clock source for SAI2 */
983 if((RCC
->PLLCFGR
& RCC_PLLCFGR_PLLSRC
) == RCC_PLLSOURCE_HSI
)
985 /* In Case the main PLL Source is HSI */
986 frequency
= HSI_VALUE
;
990 /* In Case the main PLL Source is HSE */
991 frequency
= HSE_VALUE
;
995 #endif /* STM32F767xx || STM32F769xx || STM32F777xx || STM32F779xx */
1006 #if defined (STM32F765xx) || defined(STM32F767xx) || defined(STM32F769xx) || defined(STM32F777xx) || defined(STM32F779xx)
1008 * @brief Initializes the RCC Oscillators according to the specified parameters in the
1009 * RCC_OscInitTypeDef.
1010 * @param RCC_OscInitStruct: pointer to an RCC_OscInitTypeDef structure that
1011 * contains the configuration information for the RCC Oscillators.
1012 * @note The PLL is not disabled when used as system clock.
1013 * @note Transitions LSE Bypass to LSE On and LSE On to LSE Bypass are not
1014 * supported by this function. User should request a transition to LSE Off
1015 * first and then LSE On or LSE Bypass.
1016 * @note Transition HSE Bypass to HSE On and HSE On to HSE Bypass are not
1017 * supported by this function. User should request a transition to HSE Off
1018 * first and then HSE On or HSE Bypass.
1019 * @retval HAL status
1021 HAL_StatusTypeDef
HAL_RCC_OscConfig(RCC_OscInitTypeDef
*RCC_OscInitStruct
)
1023 uint32_t tickstart
= 0;
1025 /* Check the parameters */
1026 assert_param(IS_RCC_OSCILLATORTYPE(RCC_OscInitStruct
->OscillatorType
));
1028 /*------------------------------- HSE Configuration ------------------------*/
1029 if(((RCC_OscInitStruct
->OscillatorType
) & RCC_OSCILLATORTYPE_HSE
) == RCC_OSCILLATORTYPE_HSE
)
1031 /* Check the parameters */
1032 assert_param(IS_RCC_HSE(RCC_OscInitStruct
->HSEState
));
1033 /* When the HSE is used as system clock or clock source for PLL, It can not be disabled */
1034 if((__HAL_RCC_GET_SYSCLK_SOURCE() == RCC_SYSCLKSOURCE_STATUS_HSE
)
1035 || ((__HAL_RCC_GET_SYSCLK_SOURCE() == RCC_SYSCLKSOURCE_STATUS_PLLCLK
) && ((RCC
->PLLCFGR
& RCC_PLLCFGR_PLLSRC
) == RCC_PLLCFGR_PLLSRC_HSE
)))
1037 if((__HAL_RCC_GET_FLAG(RCC_FLAG_HSERDY
) != RESET
) && (RCC_OscInitStruct
->HSEState
== RCC_HSE_OFF
))
1044 /* Set the new HSE configuration ---------------------------------------*/
1045 __HAL_RCC_HSE_CONFIG(RCC_OscInitStruct
->HSEState
);
1047 /* Check the HSE State */
1048 if(RCC_OscInitStruct
->HSEState
!= RCC_HSE_OFF
)
1051 tickstart
= HAL_GetTick();
1053 /* Wait till HSE is ready */
1054 while(__HAL_RCC_GET_FLAG(RCC_FLAG_HSERDY
) == RESET
)
1056 if((HAL_GetTick() - tickstart
) > HSE_TIMEOUT_VALUE
)
1065 tickstart
= HAL_GetTick();
1067 /* Wait till HSE is bypassed or disabled */
1068 while(__HAL_RCC_GET_FLAG(RCC_FLAG_HSERDY
) != RESET
)
1070 if((HAL_GetTick() - tickstart
) > HSE_TIMEOUT_VALUE
)
1078 /*----------------------------- HSI Configuration --------------------------*/
1079 if(((RCC_OscInitStruct
->OscillatorType
) & RCC_OSCILLATORTYPE_HSI
) == RCC_OSCILLATORTYPE_HSI
)
1081 /* Check the parameters */
1082 assert_param(IS_RCC_HSI(RCC_OscInitStruct
->HSIState
));
1083 assert_param(IS_RCC_CALIBRATION_VALUE(RCC_OscInitStruct
->HSICalibrationValue
));
1085 /* Check if HSI is used as system clock or as PLL source when PLL is selected as system clock */
1086 if((__HAL_RCC_GET_SYSCLK_SOURCE() == RCC_SYSCLKSOURCE_STATUS_HSI
)
1087 || ((__HAL_RCC_GET_SYSCLK_SOURCE() == RCC_SYSCLKSOURCE_STATUS_PLLCLK
) && ((RCC
->PLLCFGR
& RCC_PLLCFGR_PLLSRC
) == RCC_PLLCFGR_PLLSRC_HSI
)))
1089 /* When HSI is used as system clock it will not disabled */
1090 if((__HAL_RCC_GET_FLAG(RCC_FLAG_HSIRDY
) != RESET
) && (RCC_OscInitStruct
->HSIState
!= RCC_HSI_ON
))
1094 /* Otherwise, just the calibration is allowed */
1097 /* Adjusts the Internal High Speed oscillator (HSI) calibration value.*/
1098 __HAL_RCC_HSI_CALIBRATIONVALUE_ADJUST(RCC_OscInitStruct
->HSICalibrationValue
);
1103 /* Check the HSI State */
1104 if((RCC_OscInitStruct
->HSIState
)!= RCC_HSI_OFF
)
1106 /* Enable the Internal High Speed oscillator (HSI). */
1107 __HAL_RCC_HSI_ENABLE();
1110 tickstart
= HAL_GetTick();
1112 /* Wait till HSI is ready */
1113 while(__HAL_RCC_GET_FLAG(RCC_FLAG_HSIRDY
) == RESET
)
1115 if((HAL_GetTick() - tickstart
) > HSI_TIMEOUT_VALUE
)
1121 /* Adjusts the Internal High Speed oscillator (HSI) calibration value.*/
1122 __HAL_RCC_HSI_CALIBRATIONVALUE_ADJUST(RCC_OscInitStruct
->HSICalibrationValue
);
1126 /* Disable the Internal High Speed oscillator (HSI). */
1127 __HAL_RCC_HSI_DISABLE();
1130 tickstart
= HAL_GetTick();
1132 /* Wait till HSI is ready */
1133 while(__HAL_RCC_GET_FLAG(RCC_FLAG_HSIRDY
) != RESET
)
1135 if((HAL_GetTick() - tickstart
) > HSI_TIMEOUT_VALUE
)
1143 /*------------------------------ LSI Configuration -------------------------*/
1144 if(((RCC_OscInitStruct
->OscillatorType
) & RCC_OSCILLATORTYPE_LSI
) == RCC_OSCILLATORTYPE_LSI
)
1146 /* Check the parameters */
1147 assert_param(IS_RCC_LSI(RCC_OscInitStruct
->LSIState
));
1149 /* Check the LSI State */
1150 if((RCC_OscInitStruct
->LSIState
)!= RCC_LSI_OFF
)
1152 /* Enable the Internal Low Speed oscillator (LSI). */
1153 __HAL_RCC_LSI_ENABLE();
1156 tickstart
= HAL_GetTick();
1158 /* Wait till LSI is ready */
1159 while(__HAL_RCC_GET_FLAG(RCC_FLAG_LSIRDY
) == RESET
)
1161 if((HAL_GetTick() - tickstart
) > LSI_TIMEOUT_VALUE
)
1169 /* Disable the Internal Low Speed oscillator (LSI). */
1170 __HAL_RCC_LSI_DISABLE();
1173 tickstart
= HAL_GetTick();
1175 /* Wait till LSI is ready */
1176 while(__HAL_RCC_GET_FLAG(RCC_FLAG_LSIRDY
) != RESET
)
1178 if((HAL_GetTick() - tickstart
) > LSI_TIMEOUT_VALUE
)
1185 /*------------------------------ LSE Configuration -------------------------*/
1186 if(((RCC_OscInitStruct
->OscillatorType
) & RCC_OSCILLATORTYPE_LSE
) == RCC_OSCILLATORTYPE_LSE
)
1188 /* Check the parameters */
1189 assert_param(IS_RCC_LSE(RCC_OscInitStruct
->LSEState
));
1191 /* Enable Power Clock*/
1192 __HAL_RCC_PWR_CLK_ENABLE();
1194 /* Enable write access to Backup domain */
1195 PWR
->CR1
|= PWR_CR1_DBP
;
1197 /* Wait for Backup domain Write protection disable */
1198 tickstart
= HAL_GetTick();
1200 while((PWR
->CR1
& PWR_CR1_DBP
) == RESET
)
1202 if((HAL_GetTick() - tickstart
) > RCC_DBP_TIMEOUT_VALUE
)
1208 /* Set the new LSE configuration -----------------------------------------*/
1209 __HAL_RCC_LSE_CONFIG(RCC_OscInitStruct
->LSEState
);
1210 /* Check the LSE State */
1211 if((RCC_OscInitStruct
->LSEState
) != RCC_LSE_OFF
)
1214 tickstart
= HAL_GetTick();
1216 /* Wait till LSE is ready */
1217 while(__HAL_RCC_GET_FLAG(RCC_FLAG_LSERDY
) == RESET
)
1219 if((HAL_GetTick() - tickstart
) > RCC_LSE_TIMEOUT_VALUE
)
1228 tickstart
= HAL_GetTick();
1230 /* Wait till LSE is ready */
1231 while(__HAL_RCC_GET_FLAG(RCC_FLAG_LSERDY
) != RESET
)
1233 if((HAL_GetTick() - tickstart
) > RCC_LSE_TIMEOUT_VALUE
)
1240 /*-------------------------------- PLL Configuration -----------------------*/
1241 /* Check the parameters */
1242 assert_param(IS_RCC_PLL(RCC_OscInitStruct
->PLL
.PLLState
));
1243 if ((RCC_OscInitStruct
->PLL
.PLLState
) != RCC_PLL_NONE
)
1245 /* Check if the PLL is used as system clock or not */
1246 if(__HAL_RCC_GET_SYSCLK_SOURCE() != RCC_SYSCLKSOURCE_STATUS_PLLCLK
)
1248 if((RCC_OscInitStruct
->PLL
.PLLState
) == RCC_PLL_ON
)
1250 /* Check the parameters */
1251 assert_param(IS_RCC_PLLSOURCE(RCC_OscInitStruct
->PLL
.PLLSource
));
1252 assert_param(IS_RCC_PLLM_VALUE(RCC_OscInitStruct
->PLL
.PLLM
));
1253 assert_param(IS_RCC_PLLN_VALUE(RCC_OscInitStruct
->PLL
.PLLN
));
1254 assert_param(IS_RCC_PLLP_VALUE(RCC_OscInitStruct
->PLL
.PLLP
));
1255 assert_param(IS_RCC_PLLQ_VALUE(RCC_OscInitStruct
->PLL
.PLLQ
));
1256 assert_param(IS_RCC_PLLR_VALUE(RCC_OscInitStruct
->PLL
.PLLR
));
1258 /* Disable the main PLL. */
1259 __HAL_RCC_PLL_DISABLE();
1262 tickstart
= HAL_GetTick();
1264 /* Wait till PLL is ready */
1265 while(__HAL_RCC_GET_FLAG(RCC_FLAG_PLLRDY
) != RESET
)
1267 if((HAL_GetTick() - tickstart
) > PLL_TIMEOUT_VALUE
)
1273 /* Configure the main PLL clock source, multiplication and division factors. */
1274 __HAL_RCC_PLL_CONFIG(RCC_OscInitStruct
->PLL
.PLLSource
,
1275 RCC_OscInitStruct
->PLL
.PLLM
,
1276 RCC_OscInitStruct
->PLL
.PLLN
,
1277 RCC_OscInitStruct
->PLL
.PLLP
,
1278 RCC_OscInitStruct
->PLL
.PLLQ
,
1279 RCC_OscInitStruct
->PLL
.PLLR
);
1281 /* Enable the main PLL. */
1282 __HAL_RCC_PLL_ENABLE();
1285 tickstart
= HAL_GetTick();
1287 /* Wait till PLL is ready */
1288 while(__HAL_RCC_GET_FLAG(RCC_FLAG_PLLRDY
) == RESET
)
1290 if((HAL_GetTick() - tickstart
) > PLL_TIMEOUT_VALUE
)
1298 /* Disable the main PLL. */
1299 __HAL_RCC_PLL_DISABLE();
1302 tickstart
= HAL_GetTick();
1304 /* Wait till PLL is ready */
1305 while(__HAL_RCC_GET_FLAG(RCC_FLAG_PLLRDY
) != RESET
)
1307 if((HAL_GetTick() - tickstart
) > PLL_TIMEOUT_VALUE
)
1321 #endif /* STM32F767xx || STM32F769xx || STM32F777xx || STM32F779xx */
1331 #endif /* HAL_RCC_MODULE_ENABLED */
1340 /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/