1 /**
2 ******************************************************************************
3 * @file stm32f4xx_hal_rcc_ex.c
4 * @author MCD Application Team
5 * @brief Extension RCC HAL module driver.
6 * This file provides firmware functions to manage the following
7 * functionalities RCC extension peripheral:
8 * + Extended Peripheral Control functions
9 *
10 ******************************************************************************
11 * @attention
12 *
13 * Copyright (c) 2017 STMicroelectronics.
14 * All rights reserved.
15 *
16 * This software is licensed under terms that can be found in the LICENSE file in
17 * the root directory of this software component.
18 * If no LICENSE file comes with this software, it is provided AS-IS.
19 ******************************************************************************
20 */
21
22 /* Includes ------------------------------------------------------------------*/
23 #include "stm32f4xx_hal.h"
24
25 /** @addtogroup STM32F4xx_HAL_Driver
26 * @{
27 */
28
29 /** @defgroup RCCEx RCCEx
30 * @brief RCCEx HAL module driver
31 * @{
32 */
33
34 #ifdef HAL_RCC_MODULE_ENABLED
35
36 /* Private typedef -----------------------------------------------------------*/
37 /* Private define ------------------------------------------------------------*/
38 /** @addtogroup RCCEx_Private_Constants
39 * @{
40 */
41 /**
42 * @}
43 */
44 /* Private macro -------------------------------------------------------------*/
45 /* Private variables ---------------------------------------------------------*/
46 /* Private function prototypes -----------------------------------------------*/
47 /* Private functions ---------------------------------------------------------*/
48 /** @defgroup RCCEx_Exported_Functions RCCEx Exported Functions
49 * @{
50 */
51
52 /** @defgroup RCCEx_Exported_Functions_Group1 Extended Peripheral Control functions
53 * @brief Extended Peripheral Control functions
54 *
55 @verbatim
56 ===============================================================================
57 ##### Extended Peripheral Control functions #####
58 ===============================================================================
59 [..]
60 This subsection provides a set of functions allowing to control the RCC Clocks
61 frequencies.
62 [..]
63 (@) Important note: Care must be taken when HAL_RCCEx_PeriphCLKConfig() is used to
64 select the RTC clock source; in this case the Backup domain will be reset in
65 order to modify the RTC Clock source, as consequence RTC registers (including
66 the backup registers) and RCC_BDCR register are set to their reset values.
67
68 @endverbatim
69 * @{
70 */
71
72 #if defined(STM32F446xx)
73 /**
74 * @brief Initializes the RCC extended peripherals clocks according to the specified
75 * parameters in the RCC_PeriphCLKInitTypeDef.
76 * @param PeriphClkInit pointer to an RCC_PeriphCLKInitTypeDef structure that
77 * contains the configuration information for the Extended Peripherals
78 * clocks(I2S, SAI, LTDC RTC and TIM).
79 *
80 * @note Care must be taken when HAL_RCCEx_PeriphCLKConfig() is used to select
81 * the RTC clock source; in this case the Backup domain will be reset in
82 * order to modify the RTC Clock source, as consequence RTC registers (including
83 * the backup registers) and RCC_BDCR register are set to their reset values.
84 *
85 * @retval HAL status
86 */
HAL_RCCEx_PeriphCLKConfig(RCC_PeriphCLKInitTypeDef * PeriphClkInit)87 HAL_StatusTypeDef HAL_RCCEx_PeriphCLKConfig(RCC_PeriphCLKInitTypeDef *PeriphClkInit)
88 {
89 uint32_t tickstart = 0U;
90 uint32_t tmpreg1 = 0U;
91 uint32_t plli2sp = 0U;
92 uint32_t plli2sq = 0U;
93 uint32_t plli2sr = 0U;
94 uint32_t pllsaip = 0U;
95 uint32_t pllsaiq = 0U;
96 uint32_t plli2sused = 0U;
97 uint32_t pllsaiused = 0U;
98
99 /* Check the peripheral clock selection parameters */
100 assert_param(IS_RCC_PERIPHCLOCK(PeriphClkInit->PeriphClockSelection));
101
102 /*------------------------ I2S APB1 configuration --------------------------*/
103 if(((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_I2S_APB1) == (RCC_PERIPHCLK_I2S_APB1))
104 {
105 /* Check the parameters */
106 assert_param(IS_RCC_I2SAPB1CLKSOURCE(PeriphClkInit->I2sApb1ClockSelection));
107
108 /* Configure I2S Clock source */
109 __HAL_RCC_I2S_APB1_CONFIG(PeriphClkInit->I2sApb1ClockSelection);
110 /* Enable the PLLI2S when it's used as clock source for I2S */
111 if(PeriphClkInit->I2sApb1ClockSelection == RCC_I2SAPB1CLKSOURCE_PLLI2S)
112 {
113 plli2sused = 1U;
114 }
115 }
116 /*--------------------------------------------------------------------------*/
117
118 /*---------------------------- I2S APB2 configuration ----------------------*/
119 if(((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_I2S_APB2) == (RCC_PERIPHCLK_I2S_APB2))
120 {
121 /* Check the parameters */
122 assert_param(IS_RCC_I2SAPB2CLKSOURCE(PeriphClkInit->I2sApb2ClockSelection));
123
124 /* Configure I2S Clock source */
125 __HAL_RCC_I2S_APB2_CONFIG(PeriphClkInit->I2sApb2ClockSelection);
126 /* Enable the PLLI2S when it's used as clock source for I2S */
127 if(PeriphClkInit->I2sApb2ClockSelection == RCC_I2SAPB2CLKSOURCE_PLLI2S)
128 {
129 plli2sused = 1U;
130 }
131 }
132 /*--------------------------------------------------------------------------*/
133
134 /*--------------------------- SAI1 configuration ---------------------------*/
135 if(((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_SAI1) == (RCC_PERIPHCLK_SAI1))
136 {
137 /* Check the parameters */
138 assert_param(IS_RCC_SAI1CLKSOURCE(PeriphClkInit->Sai1ClockSelection));
139
140 /* Configure SAI1 Clock source */
141 __HAL_RCC_SAI1_CONFIG(PeriphClkInit->Sai1ClockSelection);
142 /* Enable the PLLI2S when it's used as clock source for SAI */
143 if(PeriphClkInit->Sai1ClockSelection == RCC_SAI1CLKSOURCE_PLLI2S)
144 {
145 plli2sused = 1U;
146 }
147 /* Enable the PLLSAI when it's used as clock source for SAI */
148 if(PeriphClkInit->Sai1ClockSelection == RCC_SAI1CLKSOURCE_PLLSAI)
149 {
150 pllsaiused = 1U;
151 }
152 }
153 /*--------------------------------------------------------------------------*/
154
155 /*-------------------------- SAI2 configuration ----------------------------*/
156 if(((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_SAI2) == (RCC_PERIPHCLK_SAI2))
157 {
158 /* Check the parameters */
159 assert_param(IS_RCC_SAI2CLKSOURCE(PeriphClkInit->Sai2ClockSelection));
160
161 /* Configure SAI2 Clock source */
162 __HAL_RCC_SAI2_CONFIG(PeriphClkInit->Sai2ClockSelection);
163
164 /* Enable the PLLI2S when it's used as clock source for SAI */
165 if(PeriphClkInit->Sai2ClockSelection == RCC_SAI2CLKSOURCE_PLLI2S)
166 {
167 plli2sused = 1U;
168 }
169 /* Enable the PLLSAI when it's used as clock source for SAI */
170 if(PeriphClkInit->Sai2ClockSelection == RCC_SAI2CLKSOURCE_PLLSAI)
171 {
172 pllsaiused = 1U;
173 }
174 }
175 /*--------------------------------------------------------------------------*/
176
177 /*----------------------------- RTC configuration --------------------------*/
178 if(((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_RTC) == (RCC_PERIPHCLK_RTC))
179 {
180 /* Check for RTC Parameters used to output RTCCLK */
181 assert_param(IS_RCC_RTCCLKSOURCE(PeriphClkInit->RTCClockSelection));
182
183 /* Enable Power Clock*/
184 __HAL_RCC_PWR_CLK_ENABLE();
185
186 /* Enable write access to Backup domain */
187 PWR->CR |= PWR_CR_DBP;
188
189 /* Get tick */
190 tickstart = HAL_GetTick();
191
192 while((PWR->CR & PWR_CR_DBP) == RESET)
193 {
194 if((HAL_GetTick() - tickstart ) > RCC_DBP_TIMEOUT_VALUE)
195 {
196 return HAL_TIMEOUT;
197 }
198 }
199 /* Reset the Backup domain only if the RTC Clock source selection is modified from reset value */
200 tmpreg1 = (RCC->BDCR & RCC_BDCR_RTCSEL);
201 if((tmpreg1 != 0x00000000U) && ((tmpreg1) != (PeriphClkInit->RTCClockSelection & RCC_BDCR_RTCSEL)))
202 {
203 /* Store the content of BDCR register before the reset of Backup Domain */
204 tmpreg1 = (RCC->BDCR & ~(RCC_BDCR_RTCSEL));
205 /* RTC Clock selection can be changed only if the Backup Domain is reset */
206 __HAL_RCC_BACKUPRESET_FORCE();
207 __HAL_RCC_BACKUPRESET_RELEASE();
208 /* Restore the Content of BDCR register */
209 RCC->BDCR = tmpreg1;
210
211 /* Wait for LSE reactivation if LSE was enable prior to Backup Domain reset */
212 if(HAL_IS_BIT_SET(RCC->BDCR, RCC_BDCR_LSEON))
213 {
214 /* Get tick */
215 tickstart = HAL_GetTick();
216
217 /* Wait till LSE is ready */
218 while(__HAL_RCC_GET_FLAG(RCC_FLAG_LSERDY) == RESET)
219 {
220 if((HAL_GetTick() - tickstart ) > RCC_LSE_TIMEOUT_VALUE)
221 {
222 return HAL_TIMEOUT;
223 }
224 }
225 }
226 }
227 __HAL_RCC_RTC_CONFIG(PeriphClkInit->RTCClockSelection);
228 }
229 /*--------------------------------------------------------------------------*/
230
231 /*---------------------------- TIM configuration ---------------------------*/
232 if(((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_TIM) == (RCC_PERIPHCLK_TIM))
233 {
234 /* Configure Timer Prescaler */
235 __HAL_RCC_TIMCLKPRESCALER(PeriphClkInit->TIMPresSelection);
236 }
237 /*--------------------------------------------------------------------------*/
238
239 /*---------------------------- FMPI2C1 Configuration -----------------------*/
240 if(((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_FMPI2C1) == RCC_PERIPHCLK_FMPI2C1)
241 {
242 /* Check the parameters */
243 assert_param(IS_RCC_FMPI2C1CLKSOURCE(PeriphClkInit->Fmpi2c1ClockSelection));
244
245 /* Configure the FMPI2C1 clock source */
246 __HAL_RCC_FMPI2C1_CONFIG(PeriphClkInit->Fmpi2c1ClockSelection);
247 }
248 /*--------------------------------------------------------------------------*/
249
250 /*------------------------------ CEC Configuration -------------------------*/
251 if(((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_CEC) == RCC_PERIPHCLK_CEC)
252 {
253 /* Check the parameters */
254 assert_param(IS_RCC_CECCLKSOURCE(PeriphClkInit->CecClockSelection));
255
256 /* Configure the CEC clock source */
257 __HAL_RCC_CEC_CONFIG(PeriphClkInit->CecClockSelection);
258 }
259 /*--------------------------------------------------------------------------*/
260
261 /*----------------------------- CLK48 Configuration ------------------------*/
262 if(((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_CLK48) == RCC_PERIPHCLK_CLK48)
263 {
264 /* Check the parameters */
265 assert_param(IS_RCC_CLK48CLKSOURCE(PeriphClkInit->Clk48ClockSelection));
266
267 /* Configure the CLK48 clock source */
268 __HAL_RCC_CLK48_CONFIG(PeriphClkInit->Clk48ClockSelection);
269
270 /* Enable the PLLSAI when it's used as clock source for CLK48 */
271 if(PeriphClkInit->Clk48ClockSelection == RCC_CLK48CLKSOURCE_PLLSAIP)
272 {
273 pllsaiused = 1U;
274 }
275 }
276 /*--------------------------------------------------------------------------*/
277
278 /*----------------------------- SDIO Configuration -------------------------*/
279 if(((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_SDIO) == RCC_PERIPHCLK_SDIO)
280 {
281 /* Check the parameters */
282 assert_param(IS_RCC_SDIOCLKSOURCE(PeriphClkInit->SdioClockSelection));
283
284 /* Configure the SDIO clock source */
285 __HAL_RCC_SDIO_CONFIG(PeriphClkInit->SdioClockSelection);
286 }
287 /*--------------------------------------------------------------------------*/
288
289 /*------------------------------ SPDIFRX Configuration ---------------------*/
290 if(((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_SPDIFRX) == RCC_PERIPHCLK_SPDIFRX)
291 {
292 /* Check the parameters */
293 assert_param(IS_RCC_SPDIFRXCLKSOURCE(PeriphClkInit->SpdifClockSelection));
294
295 /* Configure the SPDIFRX clock source */
296 __HAL_RCC_SPDIFRX_CONFIG(PeriphClkInit->SpdifClockSelection);
297 /* Enable the PLLI2S when it's used as clock source for SPDIFRX */
298 if(PeriphClkInit->SpdifClockSelection == RCC_SPDIFRXCLKSOURCE_PLLI2SP)
299 {
300 plli2sused = 1U;
301 }
302 }
303 /*--------------------------------------------------------------------------*/
304
305 /*---------------------------- PLLI2S Configuration ------------------------*/
306 /* PLLI2S is configured when a peripheral will use it as source clock : SAI1, SAI2, I2S on APB1,
307 I2S on APB2 or SPDIFRX */
308 if((plli2sused == 1U) || (PeriphClkInit->PeriphClockSelection == RCC_PERIPHCLK_PLLI2S))
309 {
310 /* Disable the PLLI2S */
311 __HAL_RCC_PLLI2S_DISABLE();
312 /* Get tick */
313 tickstart = HAL_GetTick();
314 /* Wait till PLLI2S is disabled */
315 while(__HAL_RCC_GET_FLAG(RCC_FLAG_PLLI2SRDY) != RESET)
316 {
317 if((HAL_GetTick() - tickstart ) > PLLI2S_TIMEOUT_VALUE)
318 {
319 /* return in case of Timeout detected */
320 return HAL_TIMEOUT;
321 }
322 }
323
324 /* check for common PLLI2S Parameters */
325 assert_param(IS_RCC_PLLI2SM_VALUE(PeriphClkInit->PLLI2S.PLLI2SM));
326 assert_param(IS_RCC_PLLI2SN_VALUE(PeriphClkInit->PLLI2S.PLLI2SN));
327
328 /*------ In Case of PLLI2S is selected as source clock for I2S -----------*/
329 if(((((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_I2S_APB1) == RCC_PERIPHCLK_I2S_APB1) && (PeriphClkInit->I2sApb1ClockSelection == RCC_I2SAPB1CLKSOURCE_PLLI2S)) ||
330 ((((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_I2S_APB2) == RCC_PERIPHCLK_I2S_APB2) && (PeriphClkInit->I2sApb2ClockSelection == RCC_I2SAPB2CLKSOURCE_PLLI2S)))
331 {
332 /* check for Parameters */
333 assert_param(IS_RCC_PLLI2SR_VALUE(PeriphClkInit->PLLI2S.PLLI2SR));
334
335 /* Read PLLI2SP/PLLI2SQ value from PLLI2SCFGR register (this value is not needed for I2S configuration) */
336 plli2sp = ((((RCC->PLLI2SCFGR & RCC_PLLI2SCFGR_PLLI2SP) >> RCC_PLLI2SCFGR_PLLI2SP_Pos) + 1U) << 1U);
337 plli2sq = ((RCC->PLLI2SCFGR & RCC_PLLI2SCFGR_PLLI2SQ) >> RCC_PLLI2SCFGR_PLLI2SQ_Pos);
338 /* Configure the PLLI2S division factors */
339 /* PLLI2S_VCO = f(VCO clock) = f(PLLI2S clock input) * (PLLI2SN/PLLI2SM) */
340 /* I2SCLK = f(PLLI2S clock output) = f(VCO clock) / PLLI2SR */
341 __HAL_RCC_PLLI2S_CONFIG(PeriphClkInit->PLLI2S.PLLI2SM, PeriphClkInit->PLLI2S.PLLI2SN , plli2sp, plli2sq, PeriphClkInit->PLLI2S.PLLI2SR);
342 }
343
344 /*------- In Case of PLLI2S is selected as source clock for SAI ----------*/
345 if(((((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_SAI1) == RCC_PERIPHCLK_SAI1) && (PeriphClkInit->Sai1ClockSelection == RCC_SAI1CLKSOURCE_PLLI2S)) ||
346 ((((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_SAI2) == RCC_PERIPHCLK_SAI2) && (PeriphClkInit->Sai2ClockSelection == RCC_SAI2CLKSOURCE_PLLI2S)))
347 {
348 /* Check for PLLI2S Parameters */
349 assert_param(IS_RCC_PLLI2SQ_VALUE(PeriphClkInit->PLLI2S.PLLI2SQ));
350 /* Check for PLLI2S/DIVQ parameters */
351 assert_param(IS_RCC_PLLI2S_DIVQ_VALUE(PeriphClkInit->PLLI2SDivQ));
352
353 /* Read PLLI2SP/PLLI2SR value from PLLI2SCFGR register (this value is not needed for SAI configuration) */
354 plli2sp = ((((RCC->PLLI2SCFGR & RCC_PLLI2SCFGR_PLLI2SP) >> RCC_PLLI2SCFGR_PLLI2SP_Pos) + 1U) << 1U);
355 plli2sr = ((RCC->PLLI2SCFGR & RCC_PLLI2SCFGR_PLLI2SR) >> RCC_PLLI2SCFGR_PLLI2SR_Pos);
356 /* Configure the PLLI2S division factors */
357 /* PLLI2S_VCO Input = PLL_SOURCE/PLLI2SM */
358 /* PLLI2S_VCO Output = PLLI2S_VCO Input * PLLI2SN */
359 /* SAI_CLK(first level) = PLLI2S_VCO Output/PLLI2SQ */
360 __HAL_RCC_PLLI2S_CONFIG(PeriphClkInit->PLLI2S.PLLI2SM, PeriphClkInit->PLLI2S.PLLI2SN , plli2sp, PeriphClkInit->PLLI2S.PLLI2SQ, plli2sr);
361
362 /* SAI_CLK_x = SAI_CLK(first level)/PLLI2SDIVQ */
363 __HAL_RCC_PLLI2S_PLLSAICLKDIVQ_CONFIG(PeriphClkInit->PLLI2SDivQ);
364 }
365
366 /*------ In Case of PLLI2S is selected as source clock for SPDIFRX -------*/
367 if((((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_SPDIFRX) == RCC_PERIPHCLK_SPDIFRX) && (PeriphClkInit->SpdifClockSelection == RCC_SPDIFRXCLKSOURCE_PLLI2SP))
368 {
369 /* check for Parameters */
370 assert_param(IS_RCC_PLLI2SP_VALUE(PeriphClkInit->PLLI2S.PLLI2SP));
371 /* Read PLLI2SR value from PLLI2SCFGR register (this value is not need for SAI configuration) */
372 plli2sq = ((((RCC->PLLI2SCFGR & RCC_PLLI2SCFGR_PLLI2SP) >> RCC_PLLI2SCFGR_PLLI2SP_Pos) + 1U) << 1U);
373 plli2sr = ((RCC->PLLI2SCFGR & RCC_PLLI2SCFGR_PLLI2SR) >> RCC_PLLI2SCFGR_PLLI2SR_Pos);
374 /* Configure the PLLI2S division factors */
375 /* PLLI2S_VCO = f(VCO clock) = f(PLLI2S clock input) * (PLLI2SN/PLLI2SM) */
376 /* SPDIFRXCLK = f(PLLI2S clock output) = f(VCO clock) / PLLI2SP */
377 __HAL_RCC_PLLI2S_CONFIG(PeriphClkInit->PLLI2S.PLLI2SM, PeriphClkInit->PLLI2S.PLLI2SN , PeriphClkInit->PLLI2S.PLLI2SP, plli2sq, plli2sr);
378 }
379
380 /*----------------- In Case of PLLI2S is just selected -----------------*/
381 if((PeriphClkInit->PeriphClockSelection & RCC_PERIPHCLK_PLLI2S) == RCC_PERIPHCLK_PLLI2S)
382 {
383 /* Check for Parameters */
384 assert_param(IS_RCC_PLLI2SP_VALUE(PeriphClkInit->PLLI2S.PLLI2SP));
385 assert_param(IS_RCC_PLLI2SR_VALUE(PeriphClkInit->PLLI2S.PLLI2SR));
386 assert_param(IS_RCC_PLLI2SQ_VALUE(PeriphClkInit->PLLI2S.PLLI2SQ));
387
388 /* Configure the PLLI2S division factors */
389 /* PLLI2S_VCO = f(VCO clock) = f(PLLI2S clock input) * (PLLI2SN/PLLI2SM) */
390 __HAL_RCC_PLLI2S_CONFIG(PeriphClkInit->PLLI2S.PLLI2SM, PeriphClkInit->PLLI2S.PLLI2SN , PeriphClkInit->PLLI2S.PLLI2SP, PeriphClkInit->PLLI2S.PLLI2SQ, PeriphClkInit->PLLI2S.PLLI2SR);
391 }
392
393 /* Enable the PLLI2S */
394 __HAL_RCC_PLLI2S_ENABLE();
395 /* Get tick */
396 tickstart = HAL_GetTick();
397 /* Wait till PLLI2S is ready */
398 while(__HAL_RCC_GET_FLAG(RCC_FLAG_PLLI2SRDY) == RESET)
399 {
400 if((HAL_GetTick() - tickstart ) > PLLI2S_TIMEOUT_VALUE)
401 {
402 /* return in case of Timeout detected */
403 return HAL_TIMEOUT;
404 }
405 }
406 }
407 /*--------------------------------------------------------------------------*/
408
409 /*----------------------------- PLLSAI Configuration -----------------------*/
410 /* PLLSAI is configured when a peripheral will use it as source clock : SAI1, SAI2, CLK48 or SDIO */
411 if(pllsaiused == 1U)
412 {
413 /* Disable PLLSAI Clock */
414 __HAL_RCC_PLLSAI_DISABLE();
415 /* Get tick */
416 tickstart = HAL_GetTick();
417 /* Wait till PLLSAI is disabled */
418 while(__HAL_RCC_PLLSAI_GET_FLAG() != RESET)
419 {
420 if((HAL_GetTick() - tickstart ) > PLLSAI_TIMEOUT_VALUE)
421 {
422 /* return in case of Timeout detected */
423 return HAL_TIMEOUT;
424 }
425 }
426
427 /* Check the PLLSAI division factors */
428 assert_param(IS_RCC_PLLSAIM_VALUE(PeriphClkInit->PLLSAI.PLLSAIM));
429 assert_param(IS_RCC_PLLSAIN_VALUE(PeriphClkInit->PLLSAI.PLLSAIN));
430
431 /*------ In Case of PLLSAI is selected as source clock for SAI -----------*/
432 if(((((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_SAI1) == RCC_PERIPHCLK_SAI1) && (PeriphClkInit->Sai1ClockSelection == RCC_SAI1CLKSOURCE_PLLSAI)) ||
433 ((((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_SAI2) == RCC_PERIPHCLK_SAI2) && (PeriphClkInit->Sai2ClockSelection == RCC_SAI2CLKSOURCE_PLLSAI)))
434 {
435 /* check for PLLSAIQ Parameter */
436 assert_param(IS_RCC_PLLSAIQ_VALUE(PeriphClkInit->PLLSAI.PLLSAIQ));
437 /* check for PLLSAI/DIVQ Parameter */
438 assert_param(IS_RCC_PLLSAI_DIVQ_VALUE(PeriphClkInit->PLLSAIDivQ));
439
440 /* Read PLLSAIP value from PLLSAICFGR register (this value is not needed for SAI configuration) */
441 pllsaip = ((((RCC->PLLSAICFGR & RCC_PLLSAICFGR_PLLSAIP) >> RCC_PLLSAICFGR_PLLSAIP_Pos) + 1U) << 1U);
442 /* PLLSAI_VCO Input = PLL_SOURCE/PLLM */
443 /* PLLSAI_VCO Output = PLLSAI_VCO Input * PLLSAIN */
444 /* SAI_CLK(first level) = PLLSAI_VCO Output/PLLSAIQ */
445 __HAL_RCC_PLLSAI_CONFIG(PeriphClkInit->PLLSAI.PLLSAIM, PeriphClkInit->PLLSAI.PLLSAIN , pllsaip, PeriphClkInit->PLLSAI.PLLSAIQ, 0U);
446
447 /* SAI_CLK_x = SAI_CLK(first level)/PLLSAIDIVQ */
448 __HAL_RCC_PLLSAI_PLLSAICLKDIVQ_CONFIG(PeriphClkInit->PLLSAIDivQ);
449 }
450
451 /*------ In Case of PLLSAI is selected as source clock for CLK48 ---------*/
452 /* In Case of PLLI2S is selected as source clock for CLK48 */
453 if((((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_CLK48) == RCC_PERIPHCLK_CLK48) && (PeriphClkInit->Clk48ClockSelection == RCC_CLK48CLKSOURCE_PLLSAIP))
454 {
455 /* check for Parameters */
456 assert_param(IS_RCC_PLLSAIP_VALUE(PeriphClkInit->PLLSAI.PLLSAIP));
457 /* Read PLLSAIQ value from PLLI2SCFGR register (this value is not need for SAI configuration) */
458 pllsaiq = ((RCC->PLLSAICFGR & RCC_PLLSAICFGR_PLLSAIQ) >> RCC_PLLSAICFGR_PLLSAIQ_Pos);
459 /* Configure the PLLSAI division factors */
460 /* PLLSAI_VCO = f(VCO clock) = f(PLLSAI clock input) * (PLLI2SN/PLLSAIM) */
461 /* 48CLK = f(PLLSAI clock output) = f(VCO clock) / PLLSAIP */
462 __HAL_RCC_PLLSAI_CONFIG(PeriphClkInit->PLLSAI.PLLSAIM, PeriphClkInit->PLLSAI.PLLSAIN , PeriphClkInit->PLLSAI.PLLSAIP, pllsaiq, 0U);
463 }
464
465 /* Enable PLLSAI Clock */
466 __HAL_RCC_PLLSAI_ENABLE();
467 /* Get tick */
468 tickstart = HAL_GetTick();
469 /* Wait till PLLSAI is ready */
470 while(__HAL_RCC_PLLSAI_GET_FLAG() == RESET)
471 {
472 if((HAL_GetTick() - tickstart ) > PLLSAI_TIMEOUT_VALUE)
473 {
474 /* return in case of Timeout detected */
475 return HAL_TIMEOUT;
476 }
477 }
478 }
479 return HAL_OK;
480 }
481
482 /**
483 * @brief Get the RCC_PeriphCLKInitTypeDef according to the internal
484 * RCC configuration registers.
485 * @param PeriphClkInit pointer to an RCC_PeriphCLKInitTypeDef structure that
486 * will be configured.
487 * @retval None
488 */
HAL_RCCEx_GetPeriphCLKConfig(RCC_PeriphCLKInitTypeDef * PeriphClkInit)489 void HAL_RCCEx_GetPeriphCLKConfig(RCC_PeriphCLKInitTypeDef *PeriphClkInit)
490 {
491 uint32_t tempreg;
492
493 /* Set all possible values for the extended clock type parameter------------*/
494 PeriphClkInit->PeriphClockSelection = RCC_PERIPHCLK_I2S_APB1 | RCC_PERIPHCLK_I2S_APB2 |\
495 RCC_PERIPHCLK_SAI1 | RCC_PERIPHCLK_SAI2 |\
496 RCC_PERIPHCLK_TIM | RCC_PERIPHCLK_RTC |\
497 RCC_PERIPHCLK_CEC | RCC_PERIPHCLK_FMPI2C1 |\
498 RCC_PERIPHCLK_CLK48 | RCC_PERIPHCLK_SDIO |\
499 RCC_PERIPHCLK_SPDIFRX;
500
501 /* Get the PLLI2S Clock configuration --------------------------------------*/
502 PeriphClkInit->PLLI2S.PLLI2SM = (uint32_t)((RCC->PLLI2SCFGR & RCC_PLLI2SCFGR_PLLI2SM) >> RCC_PLLI2SCFGR_PLLI2SM_Pos);
503 PeriphClkInit->PLLI2S.PLLI2SN = (uint32_t)((RCC->PLLI2SCFGR & RCC_PLLI2SCFGR_PLLI2SN) >> RCC_PLLI2SCFGR_PLLI2SN_Pos);
504 PeriphClkInit->PLLI2S.PLLI2SP = (uint32_t)((((RCC->PLLI2SCFGR & RCC_PLLI2SCFGR_PLLI2SP) >> RCC_PLLI2SCFGR_PLLI2SP_Pos) + 1U) << 1U);
505 PeriphClkInit->PLLI2S.PLLI2SQ = (uint32_t)((RCC->PLLI2SCFGR & RCC_PLLI2SCFGR_PLLI2SQ) >> RCC_PLLI2SCFGR_PLLI2SQ_Pos);
506 PeriphClkInit->PLLI2S.PLLI2SR = (uint32_t)((RCC->PLLI2SCFGR & RCC_PLLI2SCFGR_PLLI2SR) >> RCC_PLLI2SCFGR_PLLI2SR_Pos);
507 /* Get the PLLSAI Clock configuration --------------------------------------*/
508 PeriphClkInit->PLLSAI.PLLSAIM = (uint32_t)((RCC->PLLSAICFGR & RCC_PLLSAICFGR_PLLSAIM) >> RCC_PLLSAICFGR_PLLSAIM_Pos);
509 PeriphClkInit->PLLSAI.PLLSAIN = (uint32_t)((RCC->PLLSAICFGR & RCC_PLLSAICFGR_PLLSAIN) >> RCC_PLLSAICFGR_PLLSAIN_Pos);
510 PeriphClkInit->PLLSAI.PLLSAIP = (uint32_t)((((RCC->PLLSAICFGR & RCC_PLLSAICFGR_PLLSAIP) >> RCC_PLLSAICFGR_PLLSAIP_Pos) + 1U) << 1U);
511 PeriphClkInit->PLLSAI.PLLSAIQ = (uint32_t)((RCC->PLLSAICFGR & RCC_PLLSAICFGR_PLLSAIQ) >> RCC_PLLSAICFGR_PLLSAIQ_Pos);
512 /* Get the PLLSAI/PLLI2S division factors ----------------------------------*/
513 PeriphClkInit->PLLI2SDivQ = (uint32_t)((RCC->DCKCFGR & RCC_DCKCFGR_PLLI2SDIVQ) >> RCC_DCKCFGR_PLLI2SDIVQ_Pos);
514 PeriphClkInit->PLLSAIDivQ = (uint32_t)((RCC->DCKCFGR & RCC_DCKCFGR_PLLSAIDIVQ) >> RCC_DCKCFGR_PLLSAIDIVQ_Pos);
515
516 /* Get the SAI1 clock configuration ----------------------------------------*/
517 PeriphClkInit->Sai1ClockSelection = __HAL_RCC_GET_SAI1_SOURCE();
518
519 /* Get the SAI2 clock configuration ----------------------------------------*/
520 PeriphClkInit->Sai2ClockSelection = __HAL_RCC_GET_SAI2_SOURCE();
521
522 /* Get the I2S APB1 clock configuration ------------------------------------*/
523 PeriphClkInit->I2sApb1ClockSelection = __HAL_RCC_GET_I2S_APB1_SOURCE();
524
525 /* Get the I2S APB2 clock configuration ------------------------------------*/
526 PeriphClkInit->I2sApb2ClockSelection = __HAL_RCC_GET_I2S_APB2_SOURCE();
527
528 /* Get the RTC Clock configuration -----------------------------------------*/
529 tempreg = (RCC->CFGR & RCC_CFGR_RTCPRE);
530 PeriphClkInit->RTCClockSelection = (uint32_t)((tempreg) | (RCC->BDCR & RCC_BDCR_RTCSEL));
531
532 /* Get the CEC clock configuration -----------------------------------------*/
533 PeriphClkInit->CecClockSelection = __HAL_RCC_GET_CEC_SOURCE();
534
535 /* Get the FMPI2C1 clock configuration -------------------------------------*/
536 PeriphClkInit->Fmpi2c1ClockSelection = __HAL_RCC_GET_FMPI2C1_SOURCE();
537
538 /* Get the CLK48 clock configuration ----------------------------------------*/
539 PeriphClkInit->Clk48ClockSelection = __HAL_RCC_GET_CLK48_SOURCE();
540
541 /* Get the SDIO clock configuration ----------------------------------------*/
542 PeriphClkInit->SdioClockSelection = __HAL_RCC_GET_SDIO_SOURCE();
543
544 /* Get the SPDIFRX clock configuration -------------------------------------*/
545 PeriphClkInit->SpdifClockSelection = __HAL_RCC_GET_SPDIFRX_SOURCE();
546
547 /* Get the TIM Prescaler configuration -------------------------------------*/
548 if ((RCC->DCKCFGR & RCC_DCKCFGR_TIMPRE) == RESET)
549 {
550 PeriphClkInit->TIMPresSelection = RCC_TIMPRES_DESACTIVATED;
551 }
552 else
553 {
554 PeriphClkInit->TIMPresSelection = RCC_TIMPRES_ACTIVATED;
555 }
556 }
557
558 /**
559 * @brief Return the peripheral clock frequency for a given peripheral(SAI..)
560 * @note Return 0 if peripheral clock identifier not managed by this API
561 * @param PeriphClk Peripheral clock identifier
562 * This parameter can be one of the following values:
563 * @arg RCC_PERIPHCLK_SAI1: SAI1 peripheral clock
564 * @arg RCC_PERIPHCLK_SAI2: SAI2 peripheral clock
565 * @arg RCC_PERIPHCLK_I2S_APB1: I2S APB1 peripheral clock
566 * @arg RCC_PERIPHCLK_I2S_APB2: I2S APB2 peripheral clock
567 * @retval Frequency in KHz
568 */
HAL_RCCEx_GetPeriphCLKFreq(uint32_t PeriphClk)569 uint32_t HAL_RCCEx_GetPeriphCLKFreq(uint32_t PeriphClk)
570 {
571 uint32_t tmpreg1 = 0U;
572 /* This variable used to store the SAI clock frequency (value in Hz) */
573 uint32_t frequency = 0U;
574 /* This variable used to store the VCO Input (value in Hz) */
575 uint32_t vcoinput = 0U;
576 /* This variable used to store the SAI clock source */
577 uint32_t saiclocksource = 0U;
578 uint32_t srcclk = 0U;
579 /* This variable used to store the VCO Output (value in Hz) */
580 uint32_t vcooutput = 0U;
581 switch (PeriphClk)
582 {
583 case RCC_PERIPHCLK_SAI1:
584 case RCC_PERIPHCLK_SAI2:
585 {
586 saiclocksource = RCC->DCKCFGR;
587 saiclocksource &= (RCC_DCKCFGR_SAI1SRC | RCC_DCKCFGR_SAI2SRC);
588 switch (saiclocksource)
589 {
590 case 0U: /* PLLSAI is the clock source for SAI*/
591 {
592 /* Configure the PLLSAI division factor */
593 /* PLLSAI_VCO Input = PLL_SOURCE/PLLSAIM */
594 if((RCC->PLLCFGR & RCC_PLLCFGR_PLLSRC) == RCC_PLLSOURCE_HSI)
595 {
596 /* In Case the PLL Source is HSI (Internal Clock) */
597 vcoinput = (HSI_VALUE / (uint32_t)(RCC->PLLSAICFGR & RCC_PLLSAICFGR_PLLSAIM));
598 }
599 else
600 {
601 /* In Case the PLL Source is HSE (External Clock) */
602 vcoinput = ((HSE_VALUE / (uint32_t)(RCC->PLLSAICFGR & RCC_PLLSAICFGR_PLLSAIM)));
603 }
604 /* PLLSAI_VCO Output = PLLSAI_VCO Input * PLLSAIN */
605 /* SAI_CLK(first level) = PLLSAI_VCO Output/PLLSAIQ */
606 tmpreg1 = (RCC->PLLSAICFGR & RCC_PLLSAICFGR_PLLSAIQ) >> 24U;
607 frequency = (vcoinput * ((RCC->PLLSAICFGR & RCC_PLLSAICFGR_PLLSAIN) >> 6U))/(tmpreg1);
608
609 /* SAI_CLK_x = SAI_CLK(first level)/PLLSAIDIVQ */
610 tmpreg1 = (((RCC->DCKCFGR & RCC_DCKCFGR_PLLSAIDIVQ) >> 8U) + 1U);
611 frequency = frequency/(tmpreg1);
612 break;
613 }
614 case RCC_DCKCFGR_SAI1SRC_0: /* PLLI2S is the clock source for SAI*/
615 case RCC_DCKCFGR_SAI2SRC_0: /* PLLI2S is the clock source for SAI*/
616 {
617 /* Configure the PLLI2S division factor */
618 /* PLLI2S_VCO Input = PLL_SOURCE/PLLI2SM */
619 if((RCC->PLLCFGR & RCC_PLLCFGR_PLLSRC) == RCC_PLLSOURCE_HSI)
620 {
621 /* In Case the PLL Source is HSI (Internal Clock) */
622 vcoinput = (HSI_VALUE / (uint32_t)(RCC->PLLI2SCFGR & RCC_PLLI2SCFGR_PLLI2SM));
623 }
624 else
625 {
626 /* In Case the PLL Source is HSE (External Clock) */
627 vcoinput = ((HSE_VALUE / (uint32_t)(RCC->PLLI2SCFGR & RCC_PLLI2SCFGR_PLLI2SM)));
628 }
629
630 /* PLLI2S_VCO Output = PLLI2S_VCO Input * PLLI2SN */
631 /* SAI_CLK(first level) = PLLI2S_VCO Output/PLLI2SQ */
632 tmpreg1 = (RCC->PLLI2SCFGR & RCC_PLLI2SCFGR_PLLI2SQ) >> 24U;
633 frequency = (vcoinput * ((RCC->PLLI2SCFGR & RCC_PLLI2SCFGR_PLLI2SN) >> 6U))/(tmpreg1);
634
635 /* SAI_CLK_x = SAI_CLK(first level)/PLLI2SDIVQ */
636 tmpreg1 = ((RCC->DCKCFGR & RCC_DCKCFGR_PLLI2SDIVQ) + 1U);
637 frequency = frequency/(tmpreg1);
638 break;
639 }
640 case RCC_DCKCFGR_SAI1SRC_1: /* PLLR is the clock source for SAI*/
641 case RCC_DCKCFGR_SAI2SRC_1: /* PLLR is the clock source for SAI*/
642 {
643 /* Configure the PLLI2S division factor */
644 /* PLL_VCO Input = PLL_SOURCE/PLLM */
645 if((RCC->PLLCFGR & RCC_PLLCFGR_PLLSRC) == RCC_PLLSOURCE_HSI)
646 {
647 /* In Case the PLL Source is HSI (Internal Clock) */
648 vcoinput = (HSI_VALUE / (uint32_t)(RCC->PLLCFGR & RCC_PLLCFGR_PLLM));
649 }
650 else
651 {
652 /* In Case the PLL Source is HSE (External Clock) */
653 vcoinput = ((HSE_VALUE / (uint32_t)(RCC->PLLCFGR & RCC_PLLCFGR_PLLM)));
654 }
655
656 /* PLL_VCO Output = PLL_VCO Input * PLLN */
657 /* SAI_CLK_x = PLL_VCO Output/PLLR */
658 tmpreg1 = (RCC->PLLCFGR & RCC_PLLCFGR_PLLR) >> 28U;
659 frequency = (vcoinput * ((RCC->PLLCFGR & RCC_PLLCFGR_PLLN) >> 6U))/(tmpreg1);
660 break;
661 }
662 case RCC_DCKCFGR_SAI1SRC: /* External clock is the clock source for SAI*/
663 {
664 frequency = EXTERNAL_CLOCK_VALUE;
665 break;
666 }
667 case RCC_DCKCFGR_SAI2SRC: /* PLLSRC(HSE or HSI) is the clock source for SAI*/
668 {
669 if((RCC->PLLCFGR & RCC_PLLCFGR_PLLSRC) == RCC_PLLSOURCE_HSI)
670 {
671 /* In Case the PLL Source is HSI (Internal Clock) */
672 frequency = (uint32_t)(HSI_VALUE);
673 }
674 else
675 {
676 /* In Case the PLL Source is HSE (External Clock) */
677 frequency = (uint32_t)(HSE_VALUE);
678 }
679 break;
680 }
681 default :
682 {
683 break;
684 }
685 }
686 break;
687 }
688 case RCC_PERIPHCLK_I2S_APB1:
689 {
690 /* Get the current I2S source */
691 srcclk = __HAL_RCC_GET_I2S_APB1_SOURCE();
692 switch (srcclk)
693 {
694 /* Check if I2S clock selection is External clock mapped on the I2S_CKIN pin used as I2S clock */
695 case RCC_I2SAPB1CLKSOURCE_EXT:
696 {
697 /* Set the I2S clock to the external clock value */
698 frequency = EXTERNAL_CLOCK_VALUE;
699 break;
700 }
701 /* Check if I2S clock selection is PLLI2S VCO output clock divided by PLLI2SR used as I2S clock */
702 case RCC_I2SAPB1CLKSOURCE_PLLI2S:
703 {
704 /* Configure the PLLI2S division factor */
705 /* PLLI2S_VCO Input = PLL_SOURCE/PLLI2SM */
706 if((RCC->PLLCFGR & RCC_PLLCFGR_PLLSRC) == RCC_PLLSOURCE_HSE)
707 {
708 /* Get the I2S source clock value */
709 vcoinput = (uint32_t)(HSE_VALUE / (uint32_t)(RCC->PLLI2SCFGR & RCC_PLLI2SCFGR_PLLI2SM));
710 }
711 else
712 {
713 /* Get the I2S source clock value */
714 vcoinput = (uint32_t)(HSI_VALUE / (uint32_t)(RCC->PLLI2SCFGR & RCC_PLLI2SCFGR_PLLI2SM));
715 }
716
717 /* PLLI2S_VCO Output = PLLI2S_VCO Input * PLLI2SN */
718 vcooutput = (uint32_t)(vcoinput * (((RCC->PLLI2SCFGR & RCC_PLLI2SCFGR_PLLI2SN) >> 6U) & (RCC_PLLI2SCFGR_PLLI2SN >> 6U)));
719 /* I2S_CLK = PLLI2S_VCO Output/PLLI2SR */
720 frequency = (uint32_t)(vcooutput /(((RCC->PLLI2SCFGR & RCC_PLLI2SCFGR_PLLI2SR) >> 28U) & (RCC_PLLI2SCFGR_PLLI2SR >> 28U)));
721 break;
722 }
723 /* Check if I2S clock selection is PLL VCO Output divided by PLLR used as I2S clock */
724 case RCC_I2SAPB1CLKSOURCE_PLLR:
725 {
726 /* Configure the PLL division factor R */
727 /* PLL_VCO Input = PLL_SOURCE/PLLM */
728 if((RCC->PLLCFGR & RCC_PLLCFGR_PLLSRC) == RCC_PLLSOURCE_HSE)
729 {
730 /* Get the I2S source clock value */
731 vcoinput = (uint32_t)(HSE_VALUE / (uint32_t)(RCC->PLLCFGR & RCC_PLLCFGR_PLLM));
732 }
733 else
734 {
735 /* Get the I2S source clock value */
736 vcoinput = (uint32_t)(HSI_VALUE / (uint32_t)(RCC->PLLCFGR & RCC_PLLCFGR_PLLM));
737 }
738
739 /* PLL_VCO Output = PLL_VCO Input * PLLN */
740 vcooutput = (uint32_t)(vcoinput * (((RCC->PLLCFGR & RCC_PLLCFGR_PLLN) >> 6U) & (RCC_PLLCFGR_PLLN >> 6U)));
741 /* I2S_CLK = PLL_VCO Output/PLLR */
742 frequency = (uint32_t)(vcooutput /(((RCC->PLLCFGR & RCC_PLLCFGR_PLLR) >> 28U) & (RCC_PLLCFGR_PLLR >> 28U)));
743 break;
744 }
745 /* Check if I2S clock selection is HSI or HSE depending from PLL source Clock */
746 case RCC_I2SAPB1CLKSOURCE_PLLSRC:
747 {
748 if((RCC->PLLCFGR & RCC_PLLCFGR_PLLSRC) == RCC_PLLSOURCE_HSE)
749 {
750 frequency = HSE_VALUE;
751 }
752 else
753 {
754 frequency = HSI_VALUE;
755 }
756 break;
757 }
758 /* Clock not enabled for I2S*/
759 default:
760 {
761 frequency = 0U;
762 break;
763 }
764 }
765 break;
766 }
767 case RCC_PERIPHCLK_I2S_APB2:
768 {
769 /* Get the current I2S source */
770 srcclk = __HAL_RCC_GET_I2S_APB2_SOURCE();
771 switch (srcclk)
772 {
773 /* Check if I2S clock selection is External clock mapped on the I2S_CKIN pin used as I2S clock */
774 case RCC_I2SAPB2CLKSOURCE_EXT:
775 {
776 /* Set the I2S clock to the external clock value */
777 frequency = EXTERNAL_CLOCK_VALUE;
778 break;
779 }
780 /* Check if I2S clock selection is PLLI2S VCO output clock divided by PLLI2SR used as I2S clock */
781 case RCC_I2SAPB2CLKSOURCE_PLLI2S:
782 {
783 /* Configure the PLLI2S division factor */
784 /* PLLI2S_VCO Input = PLL_SOURCE/PLLI2SM */
785 if((RCC->PLLCFGR & RCC_PLLCFGR_PLLSRC) == RCC_PLLSOURCE_HSE)
786 {
787 /* Get the I2S source clock value */
788 vcoinput = (uint32_t)(HSE_VALUE / (uint32_t)(RCC->PLLI2SCFGR & RCC_PLLI2SCFGR_PLLI2SM));
789 }
790 else
791 {
792 /* Get the I2S source clock value */
793 vcoinput = (uint32_t)(HSI_VALUE / (uint32_t)(RCC->PLLI2SCFGR & RCC_PLLI2SCFGR_PLLI2SM));
794 }
795
796 /* PLLI2S_VCO Output = PLLI2S_VCO Input * PLLI2SN */
797 vcooutput = (uint32_t)(vcoinput * (((RCC->PLLI2SCFGR & RCC_PLLI2SCFGR_PLLI2SN) >> 6U) & (RCC_PLLI2SCFGR_PLLI2SN >> 6U)));
798 /* I2S_CLK = PLLI2S_VCO Output/PLLI2SR */
799 frequency = (uint32_t)(vcooutput /(((RCC->PLLI2SCFGR & RCC_PLLI2SCFGR_PLLI2SR) >> 28U) & (RCC_PLLI2SCFGR_PLLI2SR >> 28U)));
800 break;
801 }
802 /* Check if I2S clock selection is PLL VCO Output divided by PLLR used as I2S clock */
803 case RCC_I2SAPB2CLKSOURCE_PLLR:
804 {
805 /* Configure the PLL division factor R */
806 /* PLL_VCO Input = PLL_SOURCE/PLLM */
807 if((RCC->PLLCFGR & RCC_PLLCFGR_PLLSRC) == RCC_PLLSOURCE_HSE)
808 {
809 /* Get the I2S source clock value */
810 vcoinput = (uint32_t)(HSE_VALUE / (uint32_t)(RCC->PLLCFGR & RCC_PLLCFGR_PLLM));
811 }
812 else
813 {
814 /* Get the I2S source clock value */
815 vcoinput = (uint32_t)(HSI_VALUE / (uint32_t)(RCC->PLLCFGR & RCC_PLLCFGR_PLLM));
816 }
817
818 /* PLL_VCO Output = PLL_VCO Input * PLLN */
819 vcooutput = (uint32_t)(vcoinput * (((RCC->PLLCFGR & RCC_PLLCFGR_PLLN) >> 6U) & (RCC_PLLCFGR_PLLN >> 6U)));
820 /* I2S_CLK = PLL_VCO Output/PLLR */
821 frequency = (uint32_t)(vcooutput /(((RCC->PLLCFGR & RCC_PLLCFGR_PLLR) >> 28U) & (RCC_PLLCFGR_PLLR >> 28U)));
822 break;
823 }
824 /* Check if I2S clock selection is HSI or HSE depending from PLL source Clock */
825 case RCC_I2SAPB2CLKSOURCE_PLLSRC:
826 {
827 if((RCC->PLLCFGR & RCC_PLLCFGR_PLLSRC) == RCC_PLLSOURCE_HSE)
828 {
829 frequency = HSE_VALUE;
830 }
831 else
832 {
833 frequency = HSI_VALUE;
834 }
835 break;
836 }
837 /* Clock not enabled for I2S*/
838 default:
839 {
840 frequency = 0U;
841 break;
842 }
843 }
844 break;
845 }
846 }
847 return frequency;
848 }
849 #endif /* STM32F446xx */
850
851 #if defined(STM32F469xx) || defined(STM32F479xx)
852 /**
853 * @brief Initializes the RCC extended peripherals clocks according to the specified
854 * parameters in the RCC_PeriphCLKInitTypeDef.
855 * @param PeriphClkInit pointer to an RCC_PeriphCLKInitTypeDef structure that
856 * contains the configuration information for the Extended Peripherals
857 * clocks(I2S, SAI, LTDC, RTC and TIM).
858 *
859 * @note Care must be taken when HAL_RCCEx_PeriphCLKConfig() is used to select
860 * the RTC clock source; in this case the Backup domain will be reset in
861 * order to modify the RTC Clock source, as consequence RTC registers (including
862 * the backup registers) and RCC_BDCR register are set to their reset values.
863 *
864 * @retval HAL status
865 */
HAL_RCCEx_PeriphCLKConfig(RCC_PeriphCLKInitTypeDef * PeriphClkInit)866 HAL_StatusTypeDef HAL_RCCEx_PeriphCLKConfig(RCC_PeriphCLKInitTypeDef *PeriphClkInit)
867 {
868 uint32_t tickstart = 0U;
869 uint32_t tmpreg1 = 0U;
870 uint32_t pllsaip = 0U;
871 uint32_t pllsaiq = 0U;
872 uint32_t pllsair = 0U;
873
874 /* Check the parameters */
875 assert_param(IS_RCC_PERIPHCLOCK(PeriphClkInit->PeriphClockSelection));
876
877 /*--------------------------- CLK48 Configuration --------------------------*/
878 if(((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_CLK48) == RCC_PERIPHCLK_CLK48)
879 {
880 /* Check the parameters */
881 assert_param(IS_RCC_CLK48CLKSOURCE(PeriphClkInit->Clk48ClockSelection));
882
883 /* Configure the CLK48 clock source */
884 __HAL_RCC_CLK48_CONFIG(PeriphClkInit->Clk48ClockSelection);
885 }
886 /*--------------------------------------------------------------------------*/
887
888 /*------------------------------ SDIO Configuration ------------------------*/
889 if(((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_SDIO) == RCC_PERIPHCLK_SDIO)
890 {
891 /* Check the parameters */
892 assert_param(IS_RCC_SDIOCLKSOURCE(PeriphClkInit->SdioClockSelection));
893
894 /* Configure the SDIO clock source */
895 __HAL_RCC_SDIO_CONFIG(PeriphClkInit->SdioClockSelection);
896 }
897 /*--------------------------------------------------------------------------*/
898
899 /*----------------------- SAI/I2S Configuration (PLLI2S) -------------------*/
900 /*------------------- Common configuration SAI/I2S -------------------------*/
901 /* In Case of SAI or I2S Clock Configuration through PLLI2S, PLLI2SN division
902 factor is common parameters for both peripherals */
903 if((((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_I2S) == RCC_PERIPHCLK_I2S) ||
904 (((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_SAI_PLLI2S) == RCC_PERIPHCLK_SAI_PLLI2S) ||
905 (((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_PLLI2S) == RCC_PERIPHCLK_PLLI2S))
906 {
907 /* check for Parameters */
908 assert_param(IS_RCC_PLLI2SN_VALUE(PeriphClkInit->PLLI2S.PLLI2SN));
909
910 /* Disable the PLLI2S */
911 __HAL_RCC_PLLI2S_DISABLE();
912 /* Get tick */
913 tickstart = HAL_GetTick();
914 /* Wait till PLLI2S is disabled */
915 while(__HAL_RCC_GET_FLAG(RCC_FLAG_PLLI2SRDY) != RESET)
916 {
917 if((HAL_GetTick() - tickstart ) > PLLI2S_TIMEOUT_VALUE)
918 {
919 /* return in case of Timeout detected */
920 return HAL_TIMEOUT;
921 }
922 }
923
924 /*---------------------- I2S configuration -------------------------------*/
925 /* In Case of I2S Clock Configuration through PLLI2S, PLLI2SR must be added
926 only for I2S configuration */
927 if(((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_I2S) == (RCC_PERIPHCLK_I2S))
928 {
929 /* check for Parameters */
930 assert_param(IS_RCC_PLLI2SR_VALUE(PeriphClkInit->PLLI2S.PLLI2SR));
931 /* Configure the PLLI2S division factors */
932 /* PLLI2S_VCO = f(VCO clock) = f(PLLI2S clock input) x (PLLI2SN/PLLM) */
933 /* I2SCLK = f(PLLI2S clock output) = f(VCO clock) / PLLI2SR */
934 __HAL_RCC_PLLI2S_CONFIG(PeriphClkInit->PLLI2S.PLLI2SN , PeriphClkInit->PLLI2S.PLLI2SR);
935 }
936
937 /*---------------------------- SAI configuration -------------------------*/
938 /* In Case of SAI Clock Configuration through PLLI2S, PLLI2SQ and PLLI2S_DIVQ must
939 be added only for SAI configuration */
940 if(((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_SAI_PLLI2S) == (RCC_PERIPHCLK_SAI_PLLI2S))
941 {
942 /* Check the PLLI2S division factors */
943 assert_param(IS_RCC_PLLI2SQ_VALUE(PeriphClkInit->PLLI2S.PLLI2SQ));
944 assert_param(IS_RCC_PLLI2S_DIVQ_VALUE(PeriphClkInit->PLLI2SDivQ));
945
946 /* Read PLLI2SR value from PLLI2SCFGR register (this value is not need for SAI configuration) */
947 tmpreg1 = ((RCC->PLLI2SCFGR & RCC_PLLI2SCFGR_PLLI2SR) >> RCC_PLLI2SCFGR_PLLI2SR_Pos);
948 /* Configure the PLLI2S division factors */
949 /* PLLI2S_VCO Input = PLL_SOURCE/PLLM */
950 /* PLLI2S_VCO Output = PLLI2S_VCO Input * PLLI2SN */
951 /* SAI_CLK(first level) = PLLI2S_VCO Output/PLLI2SQ */
952 __HAL_RCC_PLLI2S_SAICLK_CONFIG(PeriphClkInit->PLLI2S.PLLI2SN , PeriphClkInit->PLLI2S.PLLI2SQ , tmpreg1);
953 /* SAI_CLK_x = SAI_CLK(first level)/PLLI2SDIVQ */
954 __HAL_RCC_PLLI2S_PLLSAICLKDIVQ_CONFIG(PeriphClkInit->PLLI2SDivQ);
955 }
956
957 /*----------------- In Case of PLLI2S is just selected -----------------*/
958 if((PeriphClkInit->PeriphClockSelection & RCC_PERIPHCLK_PLLI2S) == RCC_PERIPHCLK_PLLI2S)
959 {
960 /* Check for Parameters */
961 assert_param(IS_RCC_PLLI2SQ_VALUE(PeriphClkInit->PLLI2S.PLLI2SQ));
962 assert_param(IS_RCC_PLLI2SR_VALUE(PeriphClkInit->PLLI2S.PLLI2SR));
963
964 /* Configure the PLLI2S multiplication and division factors */
965 __HAL_RCC_PLLI2S_SAICLK_CONFIG(PeriphClkInit->PLLI2S.PLLI2SN, PeriphClkInit->PLLI2S.PLLI2SQ, PeriphClkInit->PLLI2S.PLLI2SR);
966 }
967
968 /* Enable the PLLI2S */
969 __HAL_RCC_PLLI2S_ENABLE();
970 /* Get tick */
971 tickstart = HAL_GetTick();
972 /* Wait till PLLI2S is ready */
973 while(__HAL_RCC_GET_FLAG(RCC_FLAG_PLLI2SRDY) == RESET)
974 {
975 if((HAL_GetTick() - tickstart ) > PLLI2S_TIMEOUT_VALUE)
976 {
977 /* return in case of Timeout detected */
978 return HAL_TIMEOUT;
979 }
980 }
981 }
982 /*--------------------------------------------------------------------------*/
983
984 /*----------------------- SAI/LTDC Configuration (PLLSAI) ------------------*/
985 /*----------------------- Common configuration SAI/LTDC --------------------*/
986 /* In Case of SAI, LTDC or CLK48 Clock Configuration through PLLSAI, PLLSAIN division
987 factor is common parameters for these peripherals */
988 if((((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_SAI_PLLSAI) == RCC_PERIPHCLK_SAI_PLLSAI) ||
989 (((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_LTDC) == RCC_PERIPHCLK_LTDC) ||
990 ((((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_CLK48) == RCC_PERIPHCLK_CLK48) &&
991 (PeriphClkInit->Clk48ClockSelection == RCC_CLK48CLKSOURCE_PLLSAIP)))
992 {
993 /* Check the PLLSAI division factors */
994 assert_param(IS_RCC_PLLSAIN_VALUE(PeriphClkInit->PLLSAI.PLLSAIN));
995
996 /* Disable PLLSAI Clock */
997 __HAL_RCC_PLLSAI_DISABLE();
998 /* Get tick */
999 tickstart = HAL_GetTick();
1000 /* Wait till PLLSAI is disabled */
1001 while(__HAL_RCC_PLLSAI_GET_FLAG() != RESET)
1002 {
1003 if((HAL_GetTick() - tickstart ) > PLLSAI_TIMEOUT_VALUE)
1004 {
1005 /* return in case of Timeout detected */
1006 return HAL_TIMEOUT;
1007 }
1008 }
1009
1010 /*---------------------------- SAI configuration -------------------------*/
1011 /* In Case of SAI Clock Configuration through PLLSAI, PLLSAIQ and PLLSAI_DIVQ must
1012 be added only for SAI configuration */
1013 if(((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_SAI_PLLSAI) == (RCC_PERIPHCLK_SAI_PLLSAI))
1014 {
1015 assert_param(IS_RCC_PLLSAIQ_VALUE(PeriphClkInit->PLLSAI.PLLSAIQ));
1016 assert_param(IS_RCC_PLLSAI_DIVQ_VALUE(PeriphClkInit->PLLSAIDivQ));
1017
1018 /* Read PLLSAIP value from PLLSAICFGR register (this value is not needed for SAI configuration) */
1019 pllsaip = ((((RCC->PLLSAICFGR & RCC_PLLSAICFGR_PLLSAIP) >> RCC_PLLSAICFGR_PLLSAIP_Pos) + 1U) << 1U);
1020 /* Read PLLSAIR value from PLLSAICFGR register (this value is not need for SAI configuration) */
1021 pllsair = ((RCC->PLLSAICFGR & RCC_PLLSAICFGR_PLLSAIR) >> RCC_PLLSAICFGR_PLLSAIR_Pos);
1022 /* PLLSAI_VCO Input = PLL_SOURCE/PLLM */
1023 /* PLLSAI_VCO Output = PLLSAI_VCO Input * PLLSAIN */
1024 /* SAI_CLK(first level) = PLLSAI_VCO Output/PLLSAIQ */
1025 __HAL_RCC_PLLSAI_CONFIG(PeriphClkInit->PLLSAI.PLLSAIN, pllsaip, PeriphClkInit->PLLSAI.PLLSAIQ, pllsair);
1026 /* SAI_CLK_x = SAI_CLK(first level)/PLLSAIDIVQ */
1027 __HAL_RCC_PLLSAI_PLLSAICLKDIVQ_CONFIG(PeriphClkInit->PLLSAIDivQ);
1028 }
1029
1030 /*---------------------------- LTDC configuration ------------------------*/
1031 if(((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_LTDC) == (RCC_PERIPHCLK_LTDC))
1032 {
1033 assert_param(IS_RCC_PLLSAIR_VALUE(PeriphClkInit->PLLSAI.PLLSAIR));
1034 assert_param(IS_RCC_PLLSAI_DIVR_VALUE(PeriphClkInit->PLLSAIDivR));
1035
1036 /* Read PLLSAIP value from PLLSAICFGR register (this value is not needed for SAI configuration) */
1037 pllsaip = ((((RCC->PLLSAICFGR & RCC_PLLSAICFGR_PLLSAIP) >> RCC_PLLSAICFGR_PLLSAIP_Pos) + 1U) << 1U);
1038 /* Read PLLSAIQ value from PLLSAICFGR register (this value is not need for SAI configuration) */
1039 pllsaiq = ((RCC->PLLSAICFGR & RCC_PLLSAICFGR_PLLSAIQ) >> RCC_PLLSAICFGR_PLLSAIQ_Pos);
1040 /* PLLSAI_VCO Input = PLL_SOURCE/PLLM */
1041 /* PLLSAI_VCO Output = PLLSAI_VCO Input * PLLSAIN */
1042 /* LTDC_CLK(first level) = PLLSAI_VCO Output/PLLSAIR */
1043 __HAL_RCC_PLLSAI_CONFIG(PeriphClkInit->PLLSAI.PLLSAIN, pllsaip, pllsaiq, PeriphClkInit->PLLSAI.PLLSAIR);
1044 /* LTDC_CLK = LTDC_CLK(first level)/PLLSAIDIVR */
1045 __HAL_RCC_PLLSAI_PLLSAICLKDIVR_CONFIG(PeriphClkInit->PLLSAIDivR);
1046 }
1047
1048 /*---------------------------- CLK48 configuration ------------------------*/
1049 /* Configure the PLLSAI when it is used as clock source for CLK48 */
1050 if((((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_CLK48) == (RCC_PERIPHCLK_CLK48)) &&
1051 (PeriphClkInit->Clk48ClockSelection == RCC_CLK48CLKSOURCE_PLLSAIP))
1052 {
1053 assert_param(IS_RCC_PLLSAIP_VALUE(PeriphClkInit->PLLSAI.PLLSAIP));
1054
1055 /* Read PLLSAIQ value from PLLSAICFGR register (this value is not need for SAI configuration) */
1056 pllsaiq = ((RCC->PLLSAICFGR & RCC_PLLSAICFGR_PLLSAIQ) >> RCC_PLLSAICFGR_PLLSAIQ_Pos);
1057 /* Read PLLSAIR value from PLLSAICFGR register (this value is not need for SAI configuration) */
1058 pllsair = ((RCC->PLLSAICFGR & RCC_PLLSAICFGR_PLLSAIR) >> RCC_PLLSAICFGR_PLLSAIR_Pos);
1059 /* PLLSAI_VCO Input = PLL_SOURCE/PLLM */
1060 /* PLLSAI_VCO Output = PLLSAI_VCO Input * PLLSAIN */
1061 /* CLK48_CLK(first level) = PLLSAI_VCO Output/PLLSAIP */
1062 __HAL_RCC_PLLSAI_CONFIG(PeriphClkInit->PLLSAI.PLLSAIN, PeriphClkInit->PLLSAI.PLLSAIP, pllsaiq, pllsair);
1063 }
1064
1065 /* Enable PLLSAI Clock */
1066 __HAL_RCC_PLLSAI_ENABLE();
1067 /* Get tick */
1068 tickstart = HAL_GetTick();
1069 /* Wait till PLLSAI is ready */
1070 while(__HAL_RCC_PLLSAI_GET_FLAG() == RESET)
1071 {
1072 if((HAL_GetTick() - tickstart ) > PLLSAI_TIMEOUT_VALUE)
1073 {
1074 /* return in case of Timeout detected */
1075 return HAL_TIMEOUT;
1076 }
1077 }
1078 }
1079
1080 /*--------------------------------------------------------------------------*/
1081
1082 /*---------------------------- RTC configuration ---------------------------*/
1083 if(((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_RTC) == (RCC_PERIPHCLK_RTC))
1084 {
1085 /* Check for RTC Parameters used to output RTCCLK */
1086 assert_param(IS_RCC_RTCCLKSOURCE(PeriphClkInit->RTCClockSelection));
1087
1088 /* Enable Power Clock*/
1089 __HAL_RCC_PWR_CLK_ENABLE();
1090
1091 /* Enable write access to Backup domain */
1092 PWR->CR |= PWR_CR_DBP;
1093
1094 /* Get tick */
1095 tickstart = HAL_GetTick();
1096
1097 while((PWR->CR & PWR_CR_DBP) == RESET)
1098 {
1099 if((HAL_GetTick() - tickstart ) > RCC_DBP_TIMEOUT_VALUE)
1100 {
1101 return HAL_TIMEOUT;
1102 }
1103 }
1104 /* Reset the Backup domain only if the RTC Clock source selection is modified from reset value */
1105 tmpreg1 = (RCC->BDCR & RCC_BDCR_RTCSEL);
1106 if((tmpreg1 != 0x00000000U) && ((tmpreg1) != (PeriphClkInit->RTCClockSelection & RCC_BDCR_RTCSEL)))
1107 {
1108 /* Store the content of BDCR register before the reset of Backup Domain */
1109 tmpreg1 = (RCC->BDCR & ~(RCC_BDCR_RTCSEL));
1110 /* RTC Clock selection can be changed only if the Backup Domain is reset */
1111 __HAL_RCC_BACKUPRESET_FORCE();
1112 __HAL_RCC_BACKUPRESET_RELEASE();
1113 /* Restore the Content of BDCR register */
1114 RCC->BDCR = tmpreg1;
1115
1116 /* Wait for LSE reactivation if LSE was enable prior to Backup Domain reset */
1117 if(HAL_IS_BIT_SET(RCC->BDCR, RCC_BDCR_LSEON))
1118 {
1119 /* Get tick */
1120 tickstart = HAL_GetTick();
1121
1122 /* Wait till LSE is ready */
1123 while(__HAL_RCC_GET_FLAG(RCC_FLAG_LSERDY) == RESET)
1124 {
1125 if((HAL_GetTick() - tickstart ) > RCC_LSE_TIMEOUT_VALUE)
1126 {
1127 return HAL_TIMEOUT;
1128 }
1129 }
1130 }
1131 }
1132 __HAL_RCC_RTC_CONFIG(PeriphClkInit->RTCClockSelection);
1133 }
1134 /*--------------------------------------------------------------------------*/
1135
1136 /*---------------------------- TIM configuration ---------------------------*/
1137 if(((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_TIM) == (RCC_PERIPHCLK_TIM))
1138 {
1139 __HAL_RCC_TIMCLKPRESCALER(PeriphClkInit->TIMPresSelection);
1140 }
1141 return HAL_OK;
1142 }
1143
1144 /**
1145 * @brief Configures the RCC_PeriphCLKInitTypeDef according to the internal
1146 * RCC configuration registers.
1147 * @param PeriphClkInit pointer to an RCC_PeriphCLKInitTypeDef structure that
1148 * will be configured.
1149 * @retval None
1150 */
HAL_RCCEx_GetPeriphCLKConfig(RCC_PeriphCLKInitTypeDef * PeriphClkInit)1151 void HAL_RCCEx_GetPeriphCLKConfig(RCC_PeriphCLKInitTypeDef *PeriphClkInit)
1152 {
1153 uint32_t tempreg;
1154
1155 /* Set all possible values for the extended clock type parameter------------*/
1156 PeriphClkInit->PeriphClockSelection = RCC_PERIPHCLK_I2S | RCC_PERIPHCLK_SAI_PLLSAI |\
1157 RCC_PERIPHCLK_SAI_PLLI2S | RCC_PERIPHCLK_LTDC |\
1158 RCC_PERIPHCLK_TIM | RCC_PERIPHCLK_RTC |\
1159 RCC_PERIPHCLK_CLK48 | RCC_PERIPHCLK_SDIO;
1160
1161 /* Get the PLLI2S Clock configuration --------------------------------------*/
1162 PeriphClkInit->PLLI2S.PLLI2SN = (uint32_t)((RCC->PLLI2SCFGR & RCC_PLLI2SCFGR_PLLI2SN) >> RCC_PLLI2SCFGR_PLLI2SN_Pos);
1163 PeriphClkInit->PLLI2S.PLLI2SR = (uint32_t)((RCC->PLLI2SCFGR & RCC_PLLI2SCFGR_PLLI2SR) >> RCC_PLLI2SCFGR_PLLI2SR_Pos);
1164 PeriphClkInit->PLLI2S.PLLI2SQ = (uint32_t)((RCC->PLLI2SCFGR & RCC_PLLI2SCFGR_PLLI2SQ) >> RCC_PLLI2SCFGR_PLLI2SQ_Pos);
1165 /* Get the PLLSAI Clock configuration --------------------------------------*/
1166 PeriphClkInit->PLLSAI.PLLSAIN = (uint32_t)((RCC->PLLSAICFGR & RCC_PLLSAICFGR_PLLSAIN) >> RCC_PLLSAICFGR_PLLSAIN_Pos);
1167 PeriphClkInit->PLLSAI.PLLSAIR = (uint32_t)((RCC->PLLSAICFGR & RCC_PLLSAICFGR_PLLSAIR) >> RCC_PLLSAICFGR_PLLSAIR_Pos);
1168 PeriphClkInit->PLLSAI.PLLSAIQ = (uint32_t)((RCC->PLLSAICFGR & RCC_PLLSAICFGR_PLLSAIQ) >> RCC_PLLSAICFGR_PLLSAIQ_Pos);
1169 /* Get the PLLSAI/PLLI2S division factors ----------------------------------*/
1170 PeriphClkInit->PLLI2SDivQ = (uint32_t)((RCC->DCKCFGR & RCC_DCKCFGR_PLLI2SDIVQ) >> RCC_DCKCFGR_PLLI2SDIVQ_Pos);
1171 PeriphClkInit->PLLSAIDivQ = (uint32_t)((RCC->DCKCFGR & RCC_DCKCFGR_PLLSAIDIVQ) >> RCC_DCKCFGR_PLLSAIDIVQ_Pos);
1172 PeriphClkInit->PLLSAIDivR = (uint32_t)(RCC->DCKCFGR & RCC_DCKCFGR_PLLSAIDIVR);
1173 /* Get the RTC Clock configuration -----------------------------------------*/
1174 tempreg = (RCC->CFGR & RCC_CFGR_RTCPRE);
1175 PeriphClkInit->RTCClockSelection = (uint32_t)((tempreg) | (RCC->BDCR & RCC_BDCR_RTCSEL));
1176
1177 /* Get the CLK48 clock configuration -------------------------------------*/
1178 PeriphClkInit->Clk48ClockSelection = __HAL_RCC_GET_CLK48_SOURCE();
1179
1180 /* Get the SDIO clock configuration ----------------------------------------*/
1181 PeriphClkInit->SdioClockSelection = __HAL_RCC_GET_SDIO_SOURCE();
1182
1183 if ((RCC->DCKCFGR & RCC_DCKCFGR_TIMPRE) == RESET)
1184 {
1185 PeriphClkInit->TIMPresSelection = RCC_TIMPRES_DESACTIVATED;
1186 }
1187 else
1188 {
1189 PeriphClkInit->TIMPresSelection = RCC_TIMPRES_ACTIVATED;
1190 }
1191 }
1192
1193 /**
1194 * @brief Return the peripheral clock frequency for a given peripheral(SAI..)
1195 * @note Return 0 if peripheral clock identifier not managed by this API
1196 * @param PeriphClk Peripheral clock identifier
1197 * This parameter can be one of the following values:
1198 * @arg RCC_PERIPHCLK_I2S: I2S peripheral clock
1199 * @retval Frequency in KHz
1200 */
HAL_RCCEx_GetPeriphCLKFreq(uint32_t PeriphClk)1201 uint32_t HAL_RCCEx_GetPeriphCLKFreq(uint32_t PeriphClk)
1202 {
1203 /* This variable used to store the I2S clock frequency (value in Hz) */
1204 uint32_t frequency = 0U;
1205 /* This variable used to store the VCO Input (value in Hz) */
1206 uint32_t vcoinput = 0U;
1207 uint32_t srcclk = 0U;
1208 /* This variable used to store the VCO Output (value in Hz) */
1209 uint32_t vcooutput = 0U;
1210 switch (PeriphClk)
1211 {
1212 case RCC_PERIPHCLK_I2S:
1213 {
1214 /* Get the current I2S source */
1215 srcclk = __HAL_RCC_GET_I2S_SOURCE();
1216 switch (srcclk)
1217 {
1218 /* Check if I2S clock selection is External clock mapped on the I2S_CKIN pin used as I2S clock */
1219 case RCC_I2SCLKSOURCE_EXT:
1220 {
1221 /* Set the I2S clock to the external clock value */
1222 frequency = EXTERNAL_CLOCK_VALUE;
1223 break;
1224 }
1225 /* Check if I2S clock selection is PLLI2S VCO output clock divided by PLLI2SR used as I2S clock */
1226 case RCC_I2SCLKSOURCE_PLLI2S:
1227 {
1228 /* Configure the PLLI2S division factor */
1229 /* PLLI2S_VCO Input = PLL_SOURCE/PLLI2SM */
1230 if((RCC->PLLCFGR & RCC_PLLCFGR_PLLSRC) == RCC_PLLSOURCE_HSE)
1231 {
1232 /* Get the I2S source clock value */
1233 vcoinput = (uint32_t)(HSE_VALUE / (uint32_t)(RCC->PLLCFGR & RCC_PLLCFGR_PLLM));
1234 }
1235 else
1236 {
1237 /* Get the I2S source clock value */
1238 vcoinput = (uint32_t)(HSI_VALUE / (uint32_t)(RCC->PLLCFGR & RCC_PLLCFGR_PLLM));
1239 }
1240
1241 /* PLLI2S_VCO Output = PLLI2S_VCO Input * PLLI2SN */
1242 vcooutput = (uint32_t)(vcoinput * (((RCC->PLLI2SCFGR & RCC_PLLI2SCFGR_PLLI2SN) >> 6U) & (RCC_PLLI2SCFGR_PLLI2SN >> 6U)));
1243 /* I2S_CLK = PLLI2S_VCO Output/PLLI2SR */
1244 frequency = (uint32_t)(vcooutput /(((RCC->PLLI2SCFGR & RCC_PLLI2SCFGR_PLLI2SR) >> 28U) & (RCC_PLLI2SCFGR_PLLI2SR >> 28U)));
1245 break;
1246 }
1247 /* Clock not enabled for I2S*/
1248 default:
1249 {
1250 frequency = 0U;
1251 break;
1252 }
1253 }
1254 break;
1255 }
1256 }
1257 return frequency;
1258 }
1259 #endif /* STM32F469xx || STM32F479xx */
1260
1261 #if defined(STM32F412Zx) || defined(STM32F412Vx) || defined(STM32F412Rx) || defined(STM32F412Cx) || defined(STM32F413xx) || defined(STM32F423xx)
1262 /**
1263 * @brief Initializes the RCC extended peripherals clocks according to the specified
1264 * parameters in the RCC_PeriphCLKInitTypeDef.
1265 * @param PeriphClkInit pointer to an RCC_PeriphCLKInitTypeDef structure that
1266 * contains the configuration information for the Extended Peripherals
1267 * clocks(I2S, LTDC RTC and TIM).
1268 *
1269 * @note Care must be taken when HAL_RCCEx_PeriphCLKConfig() is used to select
1270 * the RTC clock source; in this case the Backup domain will be reset in
1271 * order to modify the RTC Clock source, as consequence RTC registers (including
1272 * the backup registers) and RCC_BDCR register are set to their reset values.
1273 *
1274 * @retval HAL status
1275 */
HAL_RCCEx_PeriphCLKConfig(RCC_PeriphCLKInitTypeDef * PeriphClkInit)1276 HAL_StatusTypeDef HAL_RCCEx_PeriphCLKConfig(RCC_PeriphCLKInitTypeDef *PeriphClkInit)
1277 {
1278 uint32_t tickstart = 0U;
1279 uint32_t tmpreg1 = 0U;
1280 #if defined(STM32F413xx) || defined(STM32F423xx)
1281 uint32_t plli2sq = 0U;
1282 #endif /* STM32F413xx || STM32F423xx */
1283 uint32_t plli2sused = 0U;
1284
1285 /* Check the peripheral clock selection parameters */
1286 assert_param(IS_RCC_PERIPHCLOCK(PeriphClkInit->PeriphClockSelection));
1287
1288 /*----------------------------------- I2S APB1 configuration ---------------*/
1289 if(((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_I2S_APB1) == (RCC_PERIPHCLK_I2S_APB1))
1290 {
1291 /* Check the parameters */
1292 assert_param(IS_RCC_I2SAPB1CLKSOURCE(PeriphClkInit->I2sApb1ClockSelection));
1293
1294 /* Configure I2S Clock source */
1295 __HAL_RCC_I2S_APB1_CONFIG(PeriphClkInit->I2sApb1ClockSelection);
1296 /* Enable the PLLI2S when it's used as clock source for I2S */
1297 if(PeriphClkInit->I2sApb1ClockSelection == RCC_I2SAPB1CLKSOURCE_PLLI2S)
1298 {
1299 plli2sused = 1U;
1300 }
1301 }
1302 /*--------------------------------------------------------------------------*/
1303
1304 /*----------------------------------- I2S APB2 configuration ---------------*/
1305 if(((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_I2S_APB2) == (RCC_PERIPHCLK_I2S_APB2))
1306 {
1307 /* Check the parameters */
1308 assert_param(IS_RCC_I2SAPB2CLKSOURCE(PeriphClkInit->I2sApb2ClockSelection));
1309
1310 /* Configure I2S Clock source */
1311 __HAL_RCC_I2S_APB2_CONFIG(PeriphClkInit->I2sApb2ClockSelection);
1312 /* Enable the PLLI2S when it's used as clock source for I2S */
1313 if(PeriphClkInit->I2sApb2ClockSelection == RCC_I2SAPB2CLKSOURCE_PLLI2S)
1314 {
1315 plli2sused = 1U;
1316 }
1317 }
1318 /*--------------------------------------------------------------------------*/
1319
1320 #if defined(STM32F413xx) || defined(STM32F423xx)
1321 /*----------------------- SAI1 Block A configuration -----------------------*/
1322 if(((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_SAIA) == (RCC_PERIPHCLK_SAIA))
1323 {
1324 /* Check the parameters */
1325 assert_param(IS_RCC_SAIACLKSOURCE(PeriphClkInit->SaiAClockSelection));
1326
1327 /* Configure SAI1 Clock source */
1328 __HAL_RCC_SAI_BLOCKACLKSOURCE_CONFIG(PeriphClkInit->SaiAClockSelection);
1329 /* Enable the PLLI2S when it's used as clock source for SAI */
1330 if(PeriphClkInit->SaiAClockSelection == RCC_SAIACLKSOURCE_PLLI2SR)
1331 {
1332 plli2sused = 1U;
1333 }
1334 /* Enable the PLLSAI when it's used as clock source for SAI */
1335 if(PeriphClkInit->SaiAClockSelection == RCC_SAIACLKSOURCE_PLLR)
1336 {
1337 /* Check for PLL/DIVR parameters */
1338 assert_param(IS_RCC_PLL_DIVR_VALUE(PeriphClkInit->PLLDivR));
1339
1340 /* SAI_CLK_x = SAI_CLK(first level)/PLLDIVR */
1341 __HAL_RCC_PLL_PLLSAICLKDIVR_CONFIG(PeriphClkInit->PLLDivR);
1342 }
1343 }
1344 /*--------------------------------------------------------------------------*/
1345
1346 /*---------------------- SAI1 Block B configuration ------------------------*/
1347 if(((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_SAIB) == (RCC_PERIPHCLK_SAIB))
1348 {
1349 /* Check the parameters */
1350 assert_param(IS_RCC_SAIBCLKSOURCE(PeriphClkInit->SaiBClockSelection));
1351
1352 /* Configure SAI1 Clock source */
1353 __HAL_RCC_SAI_BLOCKBCLKSOURCE_CONFIG(PeriphClkInit->SaiBClockSelection);
1354 /* Enable the PLLI2S when it's used as clock source for SAI */
1355 if(PeriphClkInit->SaiBClockSelection == RCC_SAIBCLKSOURCE_PLLI2SR)
1356 {
1357 plli2sused = 1U;
1358 }
1359 /* Enable the PLLSAI when it's used as clock source for SAI */
1360 if(PeriphClkInit->SaiBClockSelection == RCC_SAIBCLKSOURCE_PLLR)
1361 {
1362 /* Check for PLL/DIVR parameters */
1363 assert_param(IS_RCC_PLL_DIVR_VALUE(PeriphClkInit->PLLDivR));
1364
1365 /* SAI_CLK_x = SAI_CLK(first level)/PLLDIVR */
1366 __HAL_RCC_PLL_PLLSAICLKDIVR_CONFIG(PeriphClkInit->PLLDivR);
1367 }
1368 }
1369 /*--------------------------------------------------------------------------*/
1370 #endif /* STM32F413xx || STM32F423xx */
1371
1372 /*------------------------------------ RTC configuration -------------------*/
1373 if(((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_RTC) == (RCC_PERIPHCLK_RTC))
1374 {
1375 /* Check for RTC Parameters used to output RTCCLK */
1376 assert_param(IS_RCC_RTCCLKSOURCE(PeriphClkInit->RTCClockSelection));
1377
1378 /* Enable Power Clock*/
1379 __HAL_RCC_PWR_CLK_ENABLE();
1380
1381 /* Enable write access to Backup domain */
1382 PWR->CR |= PWR_CR_DBP;
1383
1384 /* Get tick */
1385 tickstart = HAL_GetTick();
1386
1387 while((PWR->CR & PWR_CR_DBP) == RESET)
1388 {
1389 if((HAL_GetTick() - tickstart ) > RCC_DBP_TIMEOUT_VALUE)
1390 {
1391 return HAL_TIMEOUT;
1392 }
1393 }
1394 /* Reset the Backup domain only if the RTC Clock source selection is modified from reset value */
1395 tmpreg1 = (RCC->BDCR & RCC_BDCR_RTCSEL);
1396 if((tmpreg1 != 0x00000000U) && ((tmpreg1) != (PeriphClkInit->RTCClockSelection & RCC_BDCR_RTCSEL)))
1397 {
1398 /* Store the content of BDCR register before the reset of Backup Domain */
1399 tmpreg1 = (RCC->BDCR & ~(RCC_BDCR_RTCSEL));
1400 /* RTC Clock selection can be changed only if the Backup Domain is reset */
1401 __HAL_RCC_BACKUPRESET_FORCE();
1402 __HAL_RCC_BACKUPRESET_RELEASE();
1403 /* Restore the Content of BDCR register */
1404 RCC->BDCR = tmpreg1;
1405
1406 /* Wait for LSE reactivation if LSE was enable prior to Backup Domain reset */
1407 if(HAL_IS_BIT_SET(RCC->BDCR, RCC_BDCR_LSEON))
1408 {
1409 /* Get tick */
1410 tickstart = HAL_GetTick();
1411
1412 /* Wait till LSE is ready */
1413 while(__HAL_RCC_GET_FLAG(RCC_FLAG_LSERDY) == RESET)
1414 {
1415 if((HAL_GetTick() - tickstart ) > RCC_LSE_TIMEOUT_VALUE)
1416 {
1417 return HAL_TIMEOUT;
1418 }
1419 }
1420 }
1421 }
1422 __HAL_RCC_RTC_CONFIG(PeriphClkInit->RTCClockSelection);
1423 }
1424 /*--------------------------------------------------------------------------*/
1425
1426 /*------------------------------------ TIM configuration -------------------*/
1427 if(((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_TIM) == (RCC_PERIPHCLK_TIM))
1428 {
1429 /* Configure Timer Prescaler */
1430 __HAL_RCC_TIMCLKPRESCALER(PeriphClkInit->TIMPresSelection);
1431 }
1432 /*--------------------------------------------------------------------------*/
1433
1434 /*------------------------------------- FMPI2C1 Configuration --------------*/
1435 if(((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_FMPI2C1) == RCC_PERIPHCLK_FMPI2C1)
1436 {
1437 /* Check the parameters */
1438 assert_param(IS_RCC_FMPI2C1CLKSOURCE(PeriphClkInit->Fmpi2c1ClockSelection));
1439
1440 /* Configure the FMPI2C1 clock source */
1441 __HAL_RCC_FMPI2C1_CONFIG(PeriphClkInit->Fmpi2c1ClockSelection);
1442 }
1443 /*--------------------------------------------------------------------------*/
1444
1445 /*------------------------------------- CLK48 Configuration ----------------*/
1446 if(((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_CLK48) == RCC_PERIPHCLK_CLK48)
1447 {
1448 /* Check the parameters */
1449 assert_param(IS_RCC_CLK48CLKSOURCE(PeriphClkInit->Clk48ClockSelection));
1450
1451 /* Configure the SDIO clock source */
1452 __HAL_RCC_CLK48_CONFIG(PeriphClkInit->Clk48ClockSelection);
1453
1454 /* Enable the PLLI2S when it's used as clock source for CLK48 */
1455 if(PeriphClkInit->Clk48ClockSelection == RCC_CLK48CLKSOURCE_PLLI2SQ)
1456 {
1457 plli2sused = 1U;
1458 }
1459 }
1460 /*--------------------------------------------------------------------------*/
1461
1462 /*------------------------------------- SDIO Configuration -----------------*/
1463 if(((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_SDIO) == RCC_PERIPHCLK_SDIO)
1464 {
1465 /* Check the parameters */
1466 assert_param(IS_RCC_SDIOCLKSOURCE(PeriphClkInit->SdioClockSelection));
1467
1468 /* Configure the SDIO clock source */
1469 __HAL_RCC_SDIO_CONFIG(PeriphClkInit->SdioClockSelection);
1470 }
1471 /*--------------------------------------------------------------------------*/
1472
1473 /*-------------------------------------- PLLI2S Configuration --------------*/
1474 /* PLLI2S is configured when a peripheral will use it as source clock : I2S on APB1 or
1475 I2S on APB2*/
1476 if((plli2sused == 1U) || (PeriphClkInit->PeriphClockSelection == RCC_PERIPHCLK_PLLI2S))
1477 {
1478 /* Disable the PLLI2S */
1479 __HAL_RCC_PLLI2S_DISABLE();
1480 /* Get tick */
1481 tickstart = HAL_GetTick();
1482 /* Wait till PLLI2S is disabled */
1483 while(__HAL_RCC_GET_FLAG(RCC_FLAG_PLLI2SRDY) != RESET)
1484 {
1485 if((HAL_GetTick() - tickstart ) > PLLI2S_TIMEOUT_VALUE)
1486 {
1487 /* return in case of Timeout detected */
1488 return HAL_TIMEOUT;
1489 }
1490 }
1491
1492 /* check for common PLLI2S Parameters */
1493 assert_param(IS_RCC_PLLI2SCLKSOURCE(PeriphClkInit->PLLI2SSelection));
1494 assert_param(IS_RCC_PLLI2SM_VALUE(PeriphClkInit->PLLI2S.PLLI2SM));
1495 assert_param(IS_RCC_PLLI2SN_VALUE(PeriphClkInit->PLLI2S.PLLI2SN));
1496 /*-------------------- Set the PLL I2S clock -----------------------------*/
1497 __HAL_RCC_PLL_I2S_CONFIG(PeriphClkInit->PLLI2SSelection);
1498
1499 /*------- In Case of PLLI2S is selected as source clock for I2S ----------*/
1500 if(((((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_I2S_APB1) == RCC_PERIPHCLK_I2S_APB1) && (PeriphClkInit->I2sApb1ClockSelection == RCC_I2SAPB1CLKSOURCE_PLLI2S)) ||
1501 ((((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_I2S_APB2) == RCC_PERIPHCLK_I2S_APB2) && (PeriphClkInit->I2sApb2ClockSelection == RCC_I2SAPB2CLKSOURCE_PLLI2S)) ||
1502 ((((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_CLK48) == RCC_PERIPHCLK_CLK48) && (PeriphClkInit->Clk48ClockSelection == RCC_CLK48CLKSOURCE_PLLI2SQ)) ||
1503 ((((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_SDIO) == RCC_PERIPHCLK_SDIO) && (PeriphClkInit->SdioClockSelection == RCC_SDIOCLKSOURCE_CLK48) && (PeriphClkInit->Clk48ClockSelection == RCC_CLK48CLKSOURCE_PLLI2SQ)))
1504 {
1505 /* check for Parameters */
1506 assert_param(IS_RCC_PLLI2SR_VALUE(PeriphClkInit->PLLI2S.PLLI2SR));
1507 assert_param(IS_RCC_PLLI2SQ_VALUE(PeriphClkInit->PLLI2S.PLLI2SQ));
1508
1509 /* Configure the PLLI2S division factors */
1510 /* PLLI2S_VCO = f(VCO clock) = f(PLLI2S clock input) * (PLLI2SN/PLLI2SM)*/
1511 /* I2SCLK = f(PLLI2S clock output) = f(VCO clock) / PLLI2SR */
1512 __HAL_RCC_PLLI2S_CONFIG(PeriphClkInit->PLLI2S.PLLI2SM, PeriphClkInit->PLLI2S.PLLI2SN , PeriphClkInit->PLLI2S.PLLI2SQ, PeriphClkInit->PLLI2S.PLLI2SR);
1513 }
1514
1515 #if defined(STM32F413xx) || defined(STM32F423xx)
1516 /*------- In Case of PLLI2S is selected as source clock for SAI ----------*/
1517 if(((((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_SAIA) == RCC_PERIPHCLK_SAIA) && (PeriphClkInit->SaiAClockSelection == RCC_SAIACLKSOURCE_PLLI2SR)) ||
1518 ((((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_SAIB) == RCC_PERIPHCLK_SAIB) && (PeriphClkInit->SaiBClockSelection == RCC_SAIBCLKSOURCE_PLLI2SR)))
1519 {
1520 /* Check for PLLI2S Parameters */
1521 assert_param(IS_RCC_PLLI2SR_VALUE(PeriphClkInit->PLLI2S.PLLI2SR));
1522 /* Check for PLLI2S/DIVR parameters */
1523 assert_param(IS_RCC_PLLI2S_DIVR_VALUE(PeriphClkInit->PLLI2SDivR));
1524
1525 /* Read PLLI2SQ value from PLLI2SCFGR register (this value is not needed for SAI configuration) */
1526 plli2sq = ((RCC->PLLI2SCFGR & RCC_PLLI2SCFGR_PLLI2SQ) >> RCC_PLLI2SCFGR_PLLI2SQ_Pos);
1527 /* Configure the PLLI2S division factors */
1528 /* PLLI2S_VCO Input = PLL_SOURCE/PLLI2SM */
1529 /* PLLI2S_VCO Output = PLLI2S_VCO Input * PLLI2SN */
1530 /* SAI_CLK(first level) = PLLI2S_VCO Output/PLLI2SQ */
1531 __HAL_RCC_PLLI2S_CONFIG(PeriphClkInit->PLLI2S.PLLI2SM, PeriphClkInit->PLLI2S.PLLI2SN, plli2sq, PeriphClkInit->PLLI2S.PLLI2SR);
1532
1533 /* SAI_CLK_x = SAI_CLK(first level)/PLLI2SDIVR */
1534 __HAL_RCC_PLLI2S_PLLSAICLKDIVR_CONFIG(PeriphClkInit->PLLI2SDivR);
1535 }
1536 #endif /* STM32F413xx || STM32F423xx */
1537
1538 /*----------------- In Case of PLLI2S is just selected ------------------*/
1539 if((PeriphClkInit->PeriphClockSelection & RCC_PERIPHCLK_PLLI2S) == RCC_PERIPHCLK_PLLI2S)
1540 {
1541 /* Check for Parameters */
1542 assert_param(IS_RCC_PLLI2SR_VALUE(PeriphClkInit->PLLI2S.PLLI2SR));
1543 assert_param(IS_RCC_PLLI2SQ_VALUE(PeriphClkInit->PLLI2S.PLLI2SQ));
1544
1545 /* Configure the PLLI2S division factors */
1546 /* PLLI2S_VCO = f(VCO clock) = f(PLLI2S clock input) * (PLLI2SN/PLLI2SM)*/
1547 /* SPDIFRXCLK = f(PLLI2S clock output) = f(VCO clock) / PLLI2SP */
1548 __HAL_RCC_PLLI2S_CONFIG(PeriphClkInit->PLLI2S.PLLI2SM, PeriphClkInit->PLLI2S.PLLI2SN , PeriphClkInit->PLLI2S.PLLI2SQ, PeriphClkInit->PLLI2S.PLLI2SR);
1549 }
1550
1551 /* Enable the PLLI2S */
1552 __HAL_RCC_PLLI2S_ENABLE();
1553 /* Get tick */
1554 tickstart = HAL_GetTick();
1555 /* Wait till PLLI2S is ready */
1556 while(__HAL_RCC_GET_FLAG(RCC_FLAG_PLLI2SRDY) == RESET)
1557 {
1558 if((HAL_GetTick() - tickstart ) > PLLI2S_TIMEOUT_VALUE)
1559 {
1560 /* return in case of Timeout detected */
1561 return HAL_TIMEOUT;
1562 }
1563 }
1564 }
1565 /*--------------------------------------------------------------------------*/
1566
1567 /*-------------------- DFSDM1 clock source configuration -------------------*/
1568 if(((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_DFSDM1) == RCC_PERIPHCLK_DFSDM1)
1569 {
1570 /* Check the parameters */
1571 assert_param(IS_RCC_DFSDM1CLKSOURCE(PeriphClkInit->Dfsdm1ClockSelection));
1572
1573 /* Configure the DFSDM1 interface clock source */
1574 __HAL_RCC_DFSDM1_CONFIG(PeriphClkInit->Dfsdm1ClockSelection);
1575 }
1576 /*--------------------------------------------------------------------------*/
1577
1578 /*-------------------- DFSDM1 Audio clock source configuration -------------*/
1579 if(((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_DFSDM1_AUDIO) == RCC_PERIPHCLK_DFSDM1_AUDIO)
1580 {
1581 /* Check the parameters */
1582 assert_param(IS_RCC_DFSDM1AUDIOCLKSOURCE(PeriphClkInit->Dfsdm1AudioClockSelection));
1583
1584 /* Configure the DFSDM1 Audio interface clock source */
1585 __HAL_RCC_DFSDM1AUDIO_CONFIG(PeriphClkInit->Dfsdm1AudioClockSelection);
1586 }
1587 /*--------------------------------------------------------------------------*/
1588
1589 #if defined(STM32F413xx) || defined(STM32F423xx)
1590 /*-------------------- DFSDM2 clock source configuration -------------------*/
1591 if(((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_DFSDM2) == RCC_PERIPHCLK_DFSDM2)
1592 {
1593 /* Check the parameters */
1594 assert_param(IS_RCC_DFSDM2CLKSOURCE(PeriphClkInit->Dfsdm2ClockSelection));
1595
1596 /* Configure the DFSDM1 interface clock source */
1597 __HAL_RCC_DFSDM2_CONFIG(PeriphClkInit->Dfsdm2ClockSelection);
1598 }
1599 /*--------------------------------------------------------------------------*/
1600
1601 /*-------------------- DFSDM2 Audio clock source configuration -------------*/
1602 if(((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_DFSDM2_AUDIO) == RCC_PERIPHCLK_DFSDM2_AUDIO)
1603 {
1604 /* Check the parameters */
1605 assert_param(IS_RCC_DFSDM2AUDIOCLKSOURCE(PeriphClkInit->Dfsdm2AudioClockSelection));
1606
1607 /* Configure the DFSDM1 Audio interface clock source */
1608 __HAL_RCC_DFSDM2AUDIO_CONFIG(PeriphClkInit->Dfsdm2AudioClockSelection);
1609 }
1610 /*--------------------------------------------------------------------------*/
1611
1612 /*---------------------------- LPTIM1 Configuration ------------------------*/
1613 if(((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_LPTIM1) == RCC_PERIPHCLK_LPTIM1)
1614 {
1615 /* Check the parameters */
1616 assert_param(IS_RCC_LPTIM1CLKSOURCE(PeriphClkInit->Lptim1ClockSelection));
1617
1618 /* Configure the LPTIM1 clock source */
1619 __HAL_RCC_LPTIM1_CONFIG(PeriphClkInit->Lptim1ClockSelection);
1620 }
1621 /*--------------------------------------------------------------------------*/
1622 #endif /* STM32F413xx || STM32F423xx */
1623
1624 return HAL_OK;
1625 }
1626
1627 /**
1628 * @brief Get the RCC_PeriphCLKInitTypeDef according to the internal
1629 * RCC configuration registers.
1630 * @param PeriphClkInit pointer to an RCC_PeriphCLKInitTypeDef structure that
1631 * will be configured.
1632 * @retval None
1633 */
HAL_RCCEx_GetPeriphCLKConfig(RCC_PeriphCLKInitTypeDef * PeriphClkInit)1634 void HAL_RCCEx_GetPeriphCLKConfig(RCC_PeriphCLKInitTypeDef *PeriphClkInit)
1635 {
1636 uint32_t tempreg;
1637
1638 /* Set all possible values for the extended clock type parameter------------*/
1639 #if defined(STM32F413xx) || defined(STM32F423xx)
1640 PeriphClkInit->PeriphClockSelection = RCC_PERIPHCLK_I2S_APB1 | RCC_PERIPHCLK_I2S_APB2 |\
1641 RCC_PERIPHCLK_TIM | RCC_PERIPHCLK_RTC |\
1642 RCC_PERIPHCLK_FMPI2C1 | RCC_PERIPHCLK_CLK48 |\
1643 RCC_PERIPHCLK_SDIO | RCC_PERIPHCLK_DFSDM1 |\
1644 RCC_PERIPHCLK_DFSDM1_AUDIO | RCC_PERIPHCLK_DFSDM2 |\
1645 RCC_PERIPHCLK_DFSDM2_AUDIO | RCC_PERIPHCLK_LPTIM1 |\
1646 RCC_PERIPHCLK_SAIA | RCC_PERIPHCLK_SAIB;
1647 #else /* STM32F412Zx || STM32F412Vx || STM32F412Rx || STM32F412Cx */
1648 PeriphClkInit->PeriphClockSelection = RCC_PERIPHCLK_I2S_APB1 | RCC_PERIPHCLK_I2S_APB2 |\
1649 RCC_PERIPHCLK_TIM | RCC_PERIPHCLK_RTC |\
1650 RCC_PERIPHCLK_FMPI2C1 | RCC_PERIPHCLK_CLK48 |\
1651 RCC_PERIPHCLK_SDIO | RCC_PERIPHCLK_DFSDM1 |\
1652 RCC_PERIPHCLK_DFSDM1_AUDIO;
1653 #endif /* STM32F413xx || STM32F423xx */
1654
1655
1656
1657 /* Get the PLLI2S Clock configuration --------------------------------------*/
1658 PeriphClkInit->PLLI2S.PLLI2SM = (uint32_t)((RCC->PLLI2SCFGR & RCC_PLLI2SCFGR_PLLI2SM) >> RCC_PLLI2SCFGR_PLLI2SM_Pos);
1659 PeriphClkInit->PLLI2S.PLLI2SN = (uint32_t)((RCC->PLLI2SCFGR & RCC_PLLI2SCFGR_PLLI2SN) >> RCC_PLLI2SCFGR_PLLI2SN_Pos);
1660 PeriphClkInit->PLLI2S.PLLI2SQ = (uint32_t)((RCC->PLLI2SCFGR & RCC_PLLI2SCFGR_PLLI2SQ) >> RCC_PLLI2SCFGR_PLLI2SQ_Pos);
1661 PeriphClkInit->PLLI2S.PLLI2SR = (uint32_t)((RCC->PLLI2SCFGR & RCC_PLLI2SCFGR_PLLI2SR) >> RCC_PLLI2SCFGR_PLLI2SR_Pos);
1662 #if defined(STM32F413xx) || defined(STM32F423xx)
1663 /* Get the PLL/PLLI2S division factors -------------------------------------*/
1664 PeriphClkInit->PLLI2SDivR = (uint32_t)((RCC->DCKCFGR & RCC_DCKCFGR_PLLI2SDIVR) >> RCC_DCKCFGR_PLLI2SDIVR_Pos);
1665 PeriphClkInit->PLLDivR = (uint32_t)((RCC->DCKCFGR & RCC_DCKCFGR_PLLDIVR) >> RCC_DCKCFGR_PLLDIVR_Pos);
1666 #endif /* STM32F413xx || STM32F423xx */
1667
1668 /* Get the I2S APB1 clock configuration ------------------------------------*/
1669 PeriphClkInit->I2sApb1ClockSelection = __HAL_RCC_GET_I2S_APB1_SOURCE();
1670
1671 /* Get the I2S APB2 clock configuration ------------------------------------*/
1672 PeriphClkInit->I2sApb2ClockSelection = __HAL_RCC_GET_I2S_APB2_SOURCE();
1673
1674 /* Get the RTC Clock configuration -----------------------------------------*/
1675 tempreg = (RCC->CFGR & RCC_CFGR_RTCPRE);
1676 PeriphClkInit->RTCClockSelection = (uint32_t)((tempreg) | (RCC->BDCR & RCC_BDCR_RTCSEL));
1677
1678 /* Get the FMPI2C1 clock configuration -------------------------------------*/
1679 PeriphClkInit->Fmpi2c1ClockSelection = __HAL_RCC_GET_FMPI2C1_SOURCE();
1680
1681 /* Get the CLK48 clock configuration ---------------------------------------*/
1682 PeriphClkInit->Clk48ClockSelection = __HAL_RCC_GET_CLK48_SOURCE();
1683
1684 /* Get the SDIO clock configuration ----------------------------------------*/
1685 PeriphClkInit->SdioClockSelection = __HAL_RCC_GET_SDIO_SOURCE();
1686
1687 /* Get the DFSDM1 clock configuration --------------------------------------*/
1688 PeriphClkInit->Dfsdm1ClockSelection = __HAL_RCC_GET_DFSDM1_SOURCE();
1689
1690 /* Get the DFSDM1 Audio clock configuration --------------------------------*/
1691 PeriphClkInit->Dfsdm1AudioClockSelection = __HAL_RCC_GET_DFSDM1AUDIO_SOURCE();
1692
1693 #if defined(STM32F413xx) || defined(STM32F423xx)
1694 /* Get the DFSDM2 clock configuration --------------------------------------*/
1695 PeriphClkInit->Dfsdm2ClockSelection = __HAL_RCC_GET_DFSDM2_SOURCE();
1696
1697 /* Get the DFSDM2 Audio clock configuration --------------------------------*/
1698 PeriphClkInit->Dfsdm2AudioClockSelection = __HAL_RCC_GET_DFSDM2AUDIO_SOURCE();
1699
1700 /* Get the LPTIM1 clock configuration --------------------------------------*/
1701 PeriphClkInit->Lptim1ClockSelection = __HAL_RCC_GET_LPTIM1_SOURCE();
1702
1703 /* Get the SAI1 Block Aclock configuration ---------------------------------*/
1704 PeriphClkInit->SaiAClockSelection = __HAL_RCC_GET_SAI_BLOCKA_SOURCE();
1705
1706 /* Get the SAI1 Block B clock configuration --------------------------------*/
1707 PeriphClkInit->SaiBClockSelection = __HAL_RCC_GET_SAI_BLOCKB_SOURCE();
1708 #endif /* STM32F413xx || STM32F423xx */
1709
1710 /* Get the TIM Prescaler configuration -------------------------------------*/
1711 if ((RCC->DCKCFGR & RCC_DCKCFGR_TIMPRE) == RESET)
1712 {
1713 PeriphClkInit->TIMPresSelection = RCC_TIMPRES_DESACTIVATED;
1714 }
1715 else
1716 {
1717 PeriphClkInit->TIMPresSelection = RCC_TIMPRES_ACTIVATED;
1718 }
1719 }
1720
1721 /**
1722 * @brief Return the peripheral clock frequency for a given peripheral(I2S..)
1723 * @note Return 0 if peripheral clock identifier not managed by this API
1724 * @param PeriphClk Peripheral clock identifier
1725 * This parameter can be one of the following values:
1726 * @arg RCC_PERIPHCLK_I2S_APB1: I2S APB1 peripheral clock
1727 * @arg RCC_PERIPHCLK_I2S_APB2: I2S APB2 peripheral clock
1728 * @retval Frequency in KHz
1729 */
HAL_RCCEx_GetPeriphCLKFreq(uint32_t PeriphClk)1730 uint32_t HAL_RCCEx_GetPeriphCLKFreq(uint32_t PeriphClk)
1731 {
1732 /* This variable used to store the I2S clock frequency (value in Hz) */
1733 uint32_t frequency = 0U;
1734 /* This variable used to store the VCO Input (value in Hz) */
1735 uint32_t vcoinput = 0U;
1736 uint32_t srcclk = 0U;
1737 /* This variable used to store the VCO Output (value in Hz) */
1738 uint32_t vcooutput = 0U;
1739 switch (PeriphClk)
1740 {
1741 case RCC_PERIPHCLK_I2S_APB1:
1742 {
1743 /* Get the current I2S source */
1744 srcclk = __HAL_RCC_GET_I2S_APB1_SOURCE();
1745 switch (srcclk)
1746 {
1747 /* Check if I2S clock selection is External clock mapped on the I2S_CKIN pin used as I2S clock */
1748 case RCC_I2SAPB1CLKSOURCE_EXT:
1749 {
1750 /* Set the I2S clock to the external clock value */
1751 frequency = EXTERNAL_CLOCK_VALUE;
1752 break;
1753 }
1754 /* Check if I2S clock selection is PLLI2S VCO output clock divided by PLLI2SR used as I2S clock */
1755 case RCC_I2SAPB1CLKSOURCE_PLLI2S:
1756 {
1757 if((RCC->PLLI2SCFGR & RCC_PLLI2SCFGR_PLLI2SSRC) == RCC_PLLI2SCFGR_PLLI2SSRC)
1758 {
1759 /* Get the I2S source clock value */
1760 vcoinput = (uint32_t)(EXTERNAL_CLOCK_VALUE / (uint32_t)(RCC->PLLI2SCFGR & RCC_PLLI2SCFGR_PLLI2SM));
1761 }
1762 else
1763 {
1764 /* Configure the PLLI2S division factor */
1765 /* PLLI2S_VCO Input = PLL_SOURCE/PLLI2SM */
1766 if((RCC->PLLCFGR & RCC_PLLCFGR_PLLSRC) == RCC_PLLSOURCE_HSE)
1767 {
1768 /* Get the I2S source clock value */
1769 vcoinput = (uint32_t)(HSE_VALUE / (uint32_t)(RCC->PLLI2SCFGR & RCC_PLLI2SCFGR_PLLI2SM));
1770 }
1771 else
1772 {
1773 /* Get the I2S source clock value */
1774 vcoinput = (uint32_t)(HSI_VALUE / (uint32_t)(RCC->PLLI2SCFGR & RCC_PLLI2SCFGR_PLLI2SM));
1775 }
1776 }
1777 /* PLLI2S_VCO Output = PLLI2S_VCO Input * PLLI2SN */
1778 vcooutput = (uint32_t)(vcoinput * (((RCC->PLLI2SCFGR & RCC_PLLI2SCFGR_PLLI2SN) >> 6U) & (RCC_PLLI2SCFGR_PLLI2SN >> 6U)));
1779 /* I2S_CLK = PLLI2S_VCO Output/PLLI2SR */
1780 frequency = (uint32_t)(vcooutput /(((RCC->PLLI2SCFGR & RCC_PLLI2SCFGR_PLLI2SR) >> 28U) & (RCC_PLLI2SCFGR_PLLI2SR >> 28U)));
1781 break;
1782 }
1783 /* Check if I2S clock selection is PLL VCO Output divided by PLLR used as I2S clock */
1784 case RCC_I2SAPB1CLKSOURCE_PLLR:
1785 {
1786 /* Configure the PLL division factor R */
1787 /* PLL_VCO Input = PLL_SOURCE/PLLM */
1788 if((RCC->PLLCFGR & RCC_PLLCFGR_PLLSRC) == RCC_PLLSOURCE_HSE)
1789 {
1790 /* Get the I2S source clock value */
1791 vcoinput = (uint32_t)(HSE_VALUE / (uint32_t)(RCC->PLLCFGR & RCC_PLLCFGR_PLLM));
1792 }
1793 else
1794 {
1795 /* Get the I2S source clock value */
1796 vcoinput = (uint32_t)(HSI_VALUE / (uint32_t)(RCC->PLLCFGR & RCC_PLLCFGR_PLLM));
1797 }
1798
1799 /* PLL_VCO Output = PLL_VCO Input * PLLN */
1800 vcooutput = (uint32_t)(vcoinput * (((RCC->PLLCFGR & RCC_PLLCFGR_PLLN) >> 6U) & (RCC_PLLCFGR_PLLN >> 6U)));
1801 /* I2S_CLK = PLL_VCO Output/PLLR */
1802 frequency = (uint32_t)(vcooutput /(((RCC->PLLCFGR & RCC_PLLCFGR_PLLR) >> 28U) & (RCC_PLLCFGR_PLLR >> 28U)));
1803 break;
1804 }
1805 /* Check if I2S clock selection is HSI or HSE depending from PLL source Clock */
1806 case RCC_I2SAPB1CLKSOURCE_PLLSRC:
1807 {
1808 if((RCC->PLLCFGR & RCC_PLLCFGR_PLLSRC) == RCC_PLLSOURCE_HSE)
1809 {
1810 frequency = HSE_VALUE;
1811 }
1812 else
1813 {
1814 frequency = HSI_VALUE;
1815 }
1816 break;
1817 }
1818 /* Clock not enabled for I2S*/
1819 default:
1820 {
1821 frequency = 0U;
1822 break;
1823 }
1824 }
1825 break;
1826 }
1827 case RCC_PERIPHCLK_I2S_APB2:
1828 {
1829 /* Get the current I2S source */
1830 srcclk = __HAL_RCC_GET_I2S_APB2_SOURCE();
1831 switch (srcclk)
1832 {
1833 /* Check if I2S clock selection is External clock mapped on the I2S_CKIN pin used as I2S clock */
1834 case RCC_I2SAPB2CLKSOURCE_EXT:
1835 {
1836 /* Set the I2S clock to the external clock value */
1837 frequency = EXTERNAL_CLOCK_VALUE;
1838 break;
1839 }
1840 /* Check if I2S clock selection is PLLI2S VCO output clock divided by PLLI2SR used as I2S clock */
1841 case RCC_I2SAPB2CLKSOURCE_PLLI2S:
1842 {
1843 if((RCC->PLLI2SCFGR & RCC_PLLI2SCFGR_PLLI2SSRC) == RCC_PLLI2SCFGR_PLLI2SSRC)
1844 {
1845 /* Get the I2S source clock value */
1846 vcoinput = (uint32_t)(EXTERNAL_CLOCK_VALUE / (uint32_t)(RCC->PLLI2SCFGR & RCC_PLLI2SCFGR_PLLI2SM));
1847 }
1848 else
1849 {
1850 /* Configure the PLLI2S division factor */
1851 /* PLLI2S_VCO Input = PLL_SOURCE/PLLI2SM */
1852 if((RCC->PLLCFGR & RCC_PLLCFGR_PLLSRC) == RCC_PLLSOURCE_HSE)
1853 {
1854 /* Get the I2S source clock value */
1855 vcoinput = (uint32_t)(HSE_VALUE / (uint32_t)(RCC->PLLI2SCFGR & RCC_PLLI2SCFGR_PLLI2SM));
1856 }
1857 else
1858 {
1859 /* Get the I2S source clock value */
1860 vcoinput = (uint32_t)(HSI_VALUE / (uint32_t)(RCC->PLLI2SCFGR & RCC_PLLI2SCFGR_PLLI2SM));
1861 }
1862 }
1863 /* PLLI2S_VCO Output = PLLI2S_VCO Input * PLLI2SN */
1864 vcooutput = (uint32_t)(vcoinput * (((RCC->PLLI2SCFGR & RCC_PLLI2SCFGR_PLLI2SN) >> 6U) & (RCC_PLLI2SCFGR_PLLI2SN >> 6U)));
1865 /* I2S_CLK = PLLI2S_VCO Output/PLLI2SR */
1866 frequency = (uint32_t)(vcooutput /(((RCC->PLLI2SCFGR & RCC_PLLI2SCFGR_PLLI2SR) >> 28U) & (RCC_PLLI2SCFGR_PLLI2SR >> 28U)));
1867 break;
1868 }
1869 /* Check if I2S clock selection is PLL VCO Output divided by PLLR used as I2S clock */
1870 case RCC_I2SAPB2CLKSOURCE_PLLR:
1871 {
1872 /* Configure the PLL division factor R */
1873 /* PLL_VCO Input = PLL_SOURCE/PLLM */
1874 if((RCC->PLLCFGR & RCC_PLLCFGR_PLLSRC) == RCC_PLLSOURCE_HSE)
1875 {
1876 /* Get the I2S source clock value */
1877 vcoinput = (uint32_t)(HSE_VALUE / (uint32_t)(RCC->PLLCFGR & RCC_PLLCFGR_PLLM));
1878 }
1879 else
1880 {
1881 /* Get the I2S source clock value */
1882 vcoinput = (uint32_t)(HSI_VALUE / (uint32_t)(RCC->PLLCFGR & RCC_PLLCFGR_PLLM));
1883 }
1884
1885 /* PLL_VCO Output = PLL_VCO Input * PLLN */
1886 vcooutput = (uint32_t)(vcoinput * (((RCC->PLLCFGR & RCC_PLLCFGR_PLLN) >> 6U) & (RCC_PLLCFGR_PLLN >> 6U)));
1887 /* I2S_CLK = PLL_VCO Output/PLLR */
1888 frequency = (uint32_t)(vcooutput /(((RCC->PLLCFGR & RCC_PLLCFGR_PLLR) >> 28U) & (RCC_PLLCFGR_PLLR >> 28U)));
1889 break;
1890 }
1891 /* Check if I2S clock selection is HSI or HSE depending from PLL source Clock */
1892 case RCC_I2SAPB2CLKSOURCE_PLLSRC:
1893 {
1894 if((RCC->PLLCFGR & RCC_PLLCFGR_PLLSRC) == RCC_PLLSOURCE_HSE)
1895 {
1896 frequency = HSE_VALUE;
1897 }
1898 else
1899 {
1900 frequency = HSI_VALUE;
1901 }
1902 break;
1903 }
1904 /* Clock not enabled for I2S*/
1905 default:
1906 {
1907 frequency = 0U;
1908 break;
1909 }
1910 }
1911 break;
1912 }
1913 }
1914 return frequency;
1915 }
1916 #endif /* STM32F412Zx || STM32F412Vx || STM32F412Rx || STM32F412Cx || STM32F413xx || STM32F423xx */
1917
1918 #if defined(STM32F410Tx) || defined(STM32F410Cx) || defined(STM32F410Rx)
1919 /**
1920 * @brief Initializes the RCC extended peripherals clocks according to the specified parameters in the
1921 * RCC_PeriphCLKInitTypeDef.
1922 * @param PeriphClkInit pointer to an RCC_PeriphCLKInitTypeDef structure that
1923 * contains the configuration information for the Extended Peripherals clocks(I2S and RTC clocks).
1924 *
1925 * @note A caution to be taken when HAL_RCCEx_PeriphCLKConfig() is used to select RTC clock selection, in this case
1926 * the Reset of Backup domain will be applied in order to modify the RTC Clock source as consequence all backup
1927 * domain (RTC and RCC_BDCR register expect BKPSRAM) will be reset
1928 *
1929 * @retval HAL status
1930 */
HAL_RCCEx_PeriphCLKConfig(RCC_PeriphCLKInitTypeDef * PeriphClkInit)1931 HAL_StatusTypeDef HAL_RCCEx_PeriphCLKConfig(RCC_PeriphCLKInitTypeDef *PeriphClkInit)
1932 {
1933 uint32_t tickstart = 0U;
1934 uint32_t tmpreg1 = 0U;
1935
1936 /* Check the parameters */
1937 assert_param(IS_RCC_PERIPHCLOCK(PeriphClkInit->PeriphClockSelection));
1938
1939 /*---------------------------- RTC configuration ---------------------------*/
1940 if(((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_RTC) == (RCC_PERIPHCLK_RTC))
1941 {
1942 /* Check for RTC Parameters used to output RTCCLK */
1943 assert_param(IS_RCC_RTCCLKSOURCE(PeriphClkInit->RTCClockSelection));
1944
1945 /* Enable Power Clock*/
1946 __HAL_RCC_PWR_CLK_ENABLE();
1947
1948 /* Enable write access to Backup domain */
1949 PWR->CR |= PWR_CR_DBP;
1950
1951 /* Get tick */
1952 tickstart = HAL_GetTick();
1953
1954 while((PWR->CR & PWR_CR_DBP) == RESET)
1955 {
1956 if((HAL_GetTick() - tickstart ) > RCC_DBP_TIMEOUT_VALUE)
1957 {
1958 return HAL_TIMEOUT;
1959 }
1960 }
1961 /* Reset the Backup domain only if the RTC Clock source selection is modified from reset value */
1962 tmpreg1 = (RCC->BDCR & RCC_BDCR_RTCSEL);
1963 if((tmpreg1 != 0x00000000U) && ((tmpreg1) != (PeriphClkInit->RTCClockSelection & RCC_BDCR_RTCSEL)))
1964 {
1965 /* Store the content of BDCR register before the reset of Backup Domain */
1966 tmpreg1 = (RCC->BDCR & ~(RCC_BDCR_RTCSEL));
1967 /* RTC Clock selection can be changed only if the Backup Domain is reset */
1968 __HAL_RCC_BACKUPRESET_FORCE();
1969 __HAL_RCC_BACKUPRESET_RELEASE();
1970 /* Restore the Content of BDCR register */
1971 RCC->BDCR = tmpreg1;
1972
1973 /* Wait for LSE reactivation if LSE was enable prior to Backup Domain reset */
1974 if(HAL_IS_BIT_SET(RCC->BDCR, RCC_BDCR_LSEON))
1975 {
1976 /* Get tick */
1977 tickstart = HAL_GetTick();
1978
1979 /* Wait till LSE is ready */
1980 while(__HAL_RCC_GET_FLAG(RCC_FLAG_LSERDY) == RESET)
1981 {
1982 if((HAL_GetTick() - tickstart ) > RCC_LSE_TIMEOUT_VALUE)
1983 {
1984 return HAL_TIMEOUT;
1985 }
1986 }
1987 }
1988 }
1989 __HAL_RCC_RTC_CONFIG(PeriphClkInit->RTCClockSelection);
1990 }
1991 /*--------------------------------------------------------------------------*/
1992
1993 /*---------------------------- TIM configuration ---------------------------*/
1994 if(((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_TIM) == (RCC_PERIPHCLK_TIM))
1995 {
1996 __HAL_RCC_TIMCLKPRESCALER(PeriphClkInit->TIMPresSelection);
1997 }
1998 /*--------------------------------------------------------------------------*/
1999
2000 /*---------------------------- FMPI2C1 Configuration -----------------------*/
2001 if(((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_FMPI2C1) == RCC_PERIPHCLK_FMPI2C1)
2002 {
2003 /* Check the parameters */
2004 assert_param(IS_RCC_FMPI2C1CLKSOURCE(PeriphClkInit->Fmpi2c1ClockSelection));
2005
2006 /* Configure the FMPI2C1 clock source */
2007 __HAL_RCC_FMPI2C1_CONFIG(PeriphClkInit->Fmpi2c1ClockSelection);
2008 }
2009 /*--------------------------------------------------------------------------*/
2010
2011 /*---------------------------- LPTIM1 Configuration ------------------------*/
2012 if(((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_LPTIM1) == RCC_PERIPHCLK_LPTIM1)
2013 {
2014 /* Check the parameters */
2015 assert_param(IS_RCC_LPTIM1CLKSOURCE(PeriphClkInit->Lptim1ClockSelection));
2016
2017 /* Configure the LPTIM1 clock source */
2018 __HAL_RCC_LPTIM1_CONFIG(PeriphClkInit->Lptim1ClockSelection);
2019 }
2020
2021 /*---------------------------- I2S Configuration ---------------------------*/
2022 if(((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_I2S) == RCC_PERIPHCLK_I2S)
2023 {
2024 /* Check the parameters */
2025 assert_param(IS_RCC_I2SAPBCLKSOURCE(PeriphClkInit->I2SClockSelection));
2026
2027 /* Configure the I2S clock source */
2028 __HAL_RCC_I2S_CONFIG(PeriphClkInit->I2SClockSelection);
2029 }
2030
2031 return HAL_OK;
2032 }
2033
2034 /**
2035 * @brief Configures the RCC_OscInitStruct according to the internal
2036 * RCC configuration registers.
2037 * @param PeriphClkInit pointer to an RCC_PeriphCLKInitTypeDef structure that
2038 * will be configured.
2039 * @retval None
2040 */
HAL_RCCEx_GetPeriphCLKConfig(RCC_PeriphCLKInitTypeDef * PeriphClkInit)2041 void HAL_RCCEx_GetPeriphCLKConfig(RCC_PeriphCLKInitTypeDef *PeriphClkInit)
2042 {
2043 uint32_t tempreg;
2044
2045 /* Set all possible values for the extended clock type parameter------------*/
2046 PeriphClkInit->PeriphClockSelection = RCC_PERIPHCLK_FMPI2C1 | RCC_PERIPHCLK_LPTIM1 | RCC_PERIPHCLK_TIM | RCC_PERIPHCLK_RTC;
2047
2048 tempreg = (RCC->CFGR & RCC_CFGR_RTCPRE);
2049 PeriphClkInit->RTCClockSelection = (uint32_t)((tempreg) | (RCC->BDCR & RCC_BDCR_RTCSEL));
2050
2051 if ((RCC->DCKCFGR & RCC_DCKCFGR_TIMPRE) == RESET)
2052 {
2053 PeriphClkInit->TIMPresSelection = RCC_TIMPRES_DESACTIVATED;
2054 }
2055 else
2056 {
2057 PeriphClkInit->TIMPresSelection = RCC_TIMPRES_ACTIVATED;
2058 }
2059 /* Get the FMPI2C1 clock configuration -------------------------------------*/
2060 PeriphClkInit->Fmpi2c1ClockSelection = __HAL_RCC_GET_FMPI2C1_SOURCE();
2061
2062 /* Get the I2S clock configuration -----------------------------------------*/
2063 PeriphClkInit->I2SClockSelection = __HAL_RCC_GET_I2S_SOURCE();
2064
2065
2066 }
2067 /**
2068 * @brief Return the peripheral clock frequency for a given peripheral(SAI..)
2069 * @note Return 0 if peripheral clock identifier not managed by this API
2070 * @param PeriphClk Peripheral clock identifier
2071 * This parameter can be one of the following values:
2072 * @arg RCC_PERIPHCLK_I2S: I2S peripheral clock
2073 * @retval Frequency in KHz
2074 */
HAL_RCCEx_GetPeriphCLKFreq(uint32_t PeriphClk)2075 uint32_t HAL_RCCEx_GetPeriphCLKFreq(uint32_t PeriphClk)
2076 {
2077 /* This variable used to store the I2S clock frequency (value in Hz) */
2078 uint32_t frequency = 0U;
2079 /* This variable used to store the VCO Input (value in Hz) */
2080 uint32_t vcoinput = 0U;
2081 uint32_t srcclk = 0U;
2082 /* This variable used to store the VCO Output (value in Hz) */
2083 uint32_t vcooutput = 0U;
2084 switch (PeriphClk)
2085 {
2086 case RCC_PERIPHCLK_I2S:
2087 {
2088 /* Get the current I2S source */
2089 srcclk = __HAL_RCC_GET_I2S_SOURCE();
2090 switch (srcclk)
2091 {
2092 /* Check if I2S clock selection is External clock mapped on the I2S_CKIN pin used as I2S clock */
2093 case RCC_I2SAPBCLKSOURCE_EXT:
2094 {
2095 /* Set the I2S clock to the external clock value */
2096 frequency = EXTERNAL_CLOCK_VALUE;
2097 break;
2098 }
2099 /* Check if I2S clock selection is PLL VCO Output divided by PLLR used as I2S clock */
2100 case RCC_I2SAPBCLKSOURCE_PLLR:
2101 {
2102 /* Configure the PLL division factor R */
2103 /* PLL_VCO Input = PLL_SOURCE/PLLM */
2104 if((RCC->PLLCFGR & RCC_PLLCFGR_PLLSRC) == RCC_PLLSOURCE_HSE)
2105 {
2106 /* Get the I2S source clock value */
2107 vcoinput = (uint32_t)(HSE_VALUE / (uint32_t)(RCC->PLLCFGR & RCC_PLLCFGR_PLLM));
2108 }
2109 else
2110 {
2111 /* Get the I2S source clock value */
2112 vcoinput = (uint32_t)(HSI_VALUE / (uint32_t)(RCC->PLLCFGR & RCC_PLLCFGR_PLLM));
2113 }
2114
2115 /* PLL_VCO Output = PLL_VCO Input * PLLN */
2116 vcooutput = (uint32_t)(vcoinput * (((RCC->PLLCFGR & RCC_PLLCFGR_PLLN) >> 6U) & (RCC_PLLCFGR_PLLN >> 6U)));
2117 /* I2S_CLK = PLL_VCO Output/PLLR */
2118 frequency = (uint32_t)(vcooutput /(((RCC->PLLCFGR & RCC_PLLCFGR_PLLR) >> 28U) & (RCC_PLLCFGR_PLLR >> 28U)));
2119 break;
2120 }
2121 /* Check if I2S clock selection is HSI or HSE depending from PLL source Clock */
2122 case RCC_I2SAPBCLKSOURCE_PLLSRC:
2123 {
2124 if((RCC->PLLCFGR & RCC_PLLCFGR_PLLSRC) == RCC_PLLSOURCE_HSE)
2125 {
2126 frequency = HSE_VALUE;
2127 }
2128 else
2129 {
2130 frequency = HSI_VALUE;
2131 }
2132 break;
2133 }
2134 /* Clock not enabled for I2S*/
2135 default:
2136 {
2137 frequency = 0U;
2138 break;
2139 }
2140 }
2141 break;
2142 }
2143 }
2144 return frequency;
2145 }
2146 #endif /* STM32F410Tx || STM32F410Cx || STM32F410Rx */
2147
2148 #if defined(STM32F427xx) || defined(STM32F437xx) || defined(STM32F429xx) || defined(STM32F439xx)
2149 /**
2150 * @brief Initializes the RCC extended peripherals clocks according to the specified
2151 * parameters in the RCC_PeriphCLKInitTypeDef.
2152 * @param PeriphClkInit pointer to an RCC_PeriphCLKInitTypeDef structure that
2153 * contains the configuration information for the Extended Peripherals
2154 * clocks(I2S, SAI, LTDC RTC and TIM).
2155 *
2156 * @note Care must be taken when HAL_RCCEx_PeriphCLKConfig() is used to select
2157 * the RTC clock source; in this case the Backup domain will be reset in
2158 * order to modify the RTC Clock source, as consequence RTC registers (including
2159 * the backup registers) and RCC_BDCR register are set to their reset values.
2160 *
2161 * @retval HAL status
2162 */
HAL_RCCEx_PeriphCLKConfig(RCC_PeriphCLKInitTypeDef * PeriphClkInit)2163 HAL_StatusTypeDef HAL_RCCEx_PeriphCLKConfig(RCC_PeriphCLKInitTypeDef *PeriphClkInit)
2164 {
2165 uint32_t tickstart = 0U;
2166 uint32_t tmpreg1 = 0U;
2167
2168 /* Check the parameters */
2169 assert_param(IS_RCC_PERIPHCLOCK(PeriphClkInit->PeriphClockSelection));
2170
2171 /*----------------------- SAI/I2S Configuration (PLLI2S) -------------------*/
2172 /*----------------------- Common configuration SAI/I2S ---------------------*/
2173 /* In Case of SAI or I2S Clock Configuration through PLLI2S, PLLI2SN division
2174 factor is common parameters for both peripherals */
2175 if((((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_I2S) == RCC_PERIPHCLK_I2S) ||
2176 (((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_SAI_PLLI2S) == RCC_PERIPHCLK_SAI_PLLI2S) ||
2177 (((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_PLLI2S) == RCC_PERIPHCLK_PLLI2S))
2178 {
2179 /* check for Parameters */
2180 assert_param(IS_RCC_PLLI2SN_VALUE(PeriphClkInit->PLLI2S.PLLI2SN));
2181
2182 /* Disable the PLLI2S */
2183 __HAL_RCC_PLLI2S_DISABLE();
2184 /* Get tick */
2185 tickstart = HAL_GetTick();
2186 /* Wait till PLLI2S is disabled */
2187 while(__HAL_RCC_GET_FLAG(RCC_FLAG_PLLI2SRDY) != RESET)
2188 {
2189 if((HAL_GetTick() - tickstart ) > PLLI2S_TIMEOUT_VALUE)
2190 {
2191 /* return in case of Timeout detected */
2192 return HAL_TIMEOUT;
2193 }
2194 }
2195
2196 /*---------------------------- I2S configuration -------------------------*/
2197 /* In Case of I2S Clock Configuration through PLLI2S, PLLI2SR must be added
2198 only for I2S configuration */
2199 if(((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_I2S) == (RCC_PERIPHCLK_I2S))
2200 {
2201 /* check for Parameters */
2202 assert_param(IS_RCC_PLLI2SR_VALUE(PeriphClkInit->PLLI2S.PLLI2SR));
2203 /* Configure the PLLI2S division factors */
2204 /* PLLI2S_VCO = f(VCO clock) = f(PLLI2S clock input) * (PLLI2SN/PLLM) */
2205 /* I2SCLK = f(PLLI2S clock output) = f(VCO clock) / PLLI2SR */
2206 __HAL_RCC_PLLI2S_CONFIG(PeriphClkInit->PLLI2S.PLLI2SN , PeriphClkInit->PLLI2S.PLLI2SR);
2207 }
2208
2209 /*---------------------------- SAI configuration -------------------------*/
2210 /* In Case of SAI Clock Configuration through PLLI2S, PLLI2SQ and PLLI2S_DIVQ must
2211 be added only for SAI configuration */
2212 if(((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_SAI_PLLI2S) == (RCC_PERIPHCLK_SAI_PLLI2S))
2213 {
2214 /* Check the PLLI2S division factors */
2215 assert_param(IS_RCC_PLLI2SQ_VALUE(PeriphClkInit->PLLI2S.PLLI2SQ));
2216 assert_param(IS_RCC_PLLI2S_DIVQ_VALUE(PeriphClkInit->PLLI2SDivQ));
2217
2218 /* Read PLLI2SR value from PLLI2SCFGR register (this value is not need for SAI configuration) */
2219 tmpreg1 = ((RCC->PLLI2SCFGR & RCC_PLLI2SCFGR_PLLI2SR) >> RCC_PLLI2SCFGR_PLLI2SR_Pos);
2220 /* Configure the PLLI2S division factors */
2221 /* PLLI2S_VCO Input = PLL_SOURCE/PLLM */
2222 /* PLLI2S_VCO Output = PLLI2S_VCO Input * PLLI2SN */
2223 /* SAI_CLK(first level) = PLLI2S_VCO Output/PLLI2SQ */
2224 __HAL_RCC_PLLI2S_SAICLK_CONFIG(PeriphClkInit->PLLI2S.PLLI2SN , PeriphClkInit->PLLI2S.PLLI2SQ , tmpreg1);
2225 /* SAI_CLK_x = SAI_CLK(first level)/PLLI2SDIVQ */
2226 __HAL_RCC_PLLI2S_PLLSAICLKDIVQ_CONFIG(PeriphClkInit->PLLI2SDivQ);
2227 }
2228
2229 /*----------------- In Case of PLLI2S is just selected -----------------*/
2230 if((PeriphClkInit->PeriphClockSelection & RCC_PERIPHCLK_PLLI2S) == RCC_PERIPHCLK_PLLI2S)
2231 {
2232 /* Check for Parameters */
2233 assert_param(IS_RCC_PLLI2SQ_VALUE(PeriphClkInit->PLLI2S.PLLI2SQ));
2234 assert_param(IS_RCC_PLLI2SR_VALUE(PeriphClkInit->PLLI2S.PLLI2SR));
2235
2236 /* Configure the PLLI2S multiplication and division factors */
2237 __HAL_RCC_PLLI2S_SAICLK_CONFIG(PeriphClkInit->PLLI2S.PLLI2SN, PeriphClkInit->PLLI2S.PLLI2SQ, PeriphClkInit->PLLI2S.PLLI2SR);
2238 }
2239
2240 /* Enable the PLLI2S */
2241 __HAL_RCC_PLLI2S_ENABLE();
2242 /* Get tick */
2243 tickstart = HAL_GetTick();
2244 /* Wait till PLLI2S is ready */
2245 while(__HAL_RCC_GET_FLAG(RCC_FLAG_PLLI2SRDY) == RESET)
2246 {
2247 if((HAL_GetTick() - tickstart ) > PLLI2S_TIMEOUT_VALUE)
2248 {
2249 /* return in case of Timeout detected */
2250 return HAL_TIMEOUT;
2251 }
2252 }
2253 }
2254 /*--------------------------------------------------------------------------*/
2255
2256 /*----------------------- SAI/LTDC Configuration (PLLSAI) ------------------*/
2257 /*----------------------- Common configuration SAI/LTDC --------------------*/
2258 /* In Case of SAI or LTDC Clock Configuration through PLLSAI, PLLSAIN division
2259 factor is common parameters for both peripherals */
2260 if((((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_SAI_PLLSAI) == RCC_PERIPHCLK_SAI_PLLSAI) ||
2261 (((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_LTDC) == RCC_PERIPHCLK_LTDC))
2262 {
2263 /* Check the PLLSAI division factors */
2264 assert_param(IS_RCC_PLLSAIN_VALUE(PeriphClkInit->PLLSAI.PLLSAIN));
2265
2266 /* Disable PLLSAI Clock */
2267 __HAL_RCC_PLLSAI_DISABLE();
2268 /* Get tick */
2269 tickstart = HAL_GetTick();
2270 /* Wait till PLLSAI is disabled */
2271 while(__HAL_RCC_PLLSAI_GET_FLAG() != RESET)
2272 {
2273 if((HAL_GetTick() - tickstart ) > PLLSAI_TIMEOUT_VALUE)
2274 {
2275 /* return in case of Timeout detected */
2276 return HAL_TIMEOUT;
2277 }
2278 }
2279
2280 /*---------------------------- SAI configuration -------------------------*/
2281 /* In Case of SAI Clock Configuration through PLLSAI, PLLSAIQ and PLLSAI_DIVQ must
2282 be added only for SAI configuration */
2283 if(((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_SAI_PLLSAI) == (RCC_PERIPHCLK_SAI_PLLSAI))
2284 {
2285 assert_param(IS_RCC_PLLSAIQ_VALUE(PeriphClkInit->PLLSAI.PLLSAIQ));
2286 assert_param(IS_RCC_PLLSAI_DIVQ_VALUE(PeriphClkInit->PLLSAIDivQ));
2287
2288 /* Read PLLSAIR value from PLLSAICFGR register (this value is not need for SAI configuration) */
2289 tmpreg1 = ((RCC->PLLSAICFGR & RCC_PLLSAICFGR_PLLSAIR) >> RCC_PLLSAICFGR_PLLSAIR_Pos);
2290 /* PLLSAI_VCO Input = PLL_SOURCE/PLLM */
2291 /* PLLSAI_VCO Output = PLLSAI_VCO Input * PLLSAIN */
2292 /* SAI_CLK(first level) = PLLSAI_VCO Output/PLLSAIQ */
2293 __HAL_RCC_PLLSAI_CONFIG(PeriphClkInit->PLLSAI.PLLSAIN , PeriphClkInit->PLLSAI.PLLSAIQ, tmpreg1);
2294 /* SAI_CLK_x = SAI_CLK(first level)/PLLSAIDIVQ */
2295 __HAL_RCC_PLLSAI_PLLSAICLKDIVQ_CONFIG(PeriphClkInit->PLLSAIDivQ);
2296 }
2297
2298 /*---------------------------- LTDC configuration ------------------------*/
2299 if(((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_LTDC) == (RCC_PERIPHCLK_LTDC))
2300 {
2301 assert_param(IS_RCC_PLLSAIR_VALUE(PeriphClkInit->PLLSAI.PLLSAIR));
2302 assert_param(IS_RCC_PLLSAI_DIVR_VALUE(PeriphClkInit->PLLSAIDivR));
2303
2304 /* Read PLLSAIR value from PLLSAICFGR register (this value is not need for SAI configuration) */
2305 tmpreg1 = ((RCC->PLLSAICFGR & RCC_PLLSAICFGR_PLLSAIQ) >> RCC_PLLSAICFGR_PLLSAIQ_Pos);
2306 /* PLLSAI_VCO Input = PLL_SOURCE/PLLM */
2307 /* PLLSAI_VCO Output = PLLSAI_VCO Input * PLLSAIN */
2308 /* LTDC_CLK(first level) = PLLSAI_VCO Output/PLLSAIR */
2309 __HAL_RCC_PLLSAI_CONFIG(PeriphClkInit->PLLSAI.PLLSAIN , tmpreg1, PeriphClkInit->PLLSAI.PLLSAIR);
2310 /* LTDC_CLK = LTDC_CLK(first level)/PLLSAIDIVR */
2311 __HAL_RCC_PLLSAI_PLLSAICLKDIVR_CONFIG(PeriphClkInit->PLLSAIDivR);
2312 }
2313 /* Enable PLLSAI Clock */
2314 __HAL_RCC_PLLSAI_ENABLE();
2315 /* Get tick */
2316 tickstart = HAL_GetTick();
2317 /* Wait till PLLSAI is ready */
2318 while(__HAL_RCC_PLLSAI_GET_FLAG() == RESET)
2319 {
2320 if((HAL_GetTick() - tickstart ) > PLLSAI_TIMEOUT_VALUE)
2321 {
2322 /* return in case of Timeout detected */
2323 return HAL_TIMEOUT;
2324 }
2325 }
2326 }
2327 /*--------------------------------------------------------------------------*/
2328
2329 /*---------------------------- RTC configuration ---------------------------*/
2330 if(((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_RTC) == (RCC_PERIPHCLK_RTC))
2331 {
2332 /* Check for RTC Parameters used to output RTCCLK */
2333 assert_param(IS_RCC_RTCCLKSOURCE(PeriphClkInit->RTCClockSelection));
2334
2335 /* Enable Power Clock*/
2336 __HAL_RCC_PWR_CLK_ENABLE();
2337
2338 /* Enable write access to Backup domain */
2339 PWR->CR |= PWR_CR_DBP;
2340
2341 /* Get tick */
2342 tickstart = HAL_GetTick();
2343
2344 while((PWR->CR & PWR_CR_DBP) == RESET)
2345 {
2346 if((HAL_GetTick() - tickstart ) > RCC_DBP_TIMEOUT_VALUE)
2347 {
2348 return HAL_TIMEOUT;
2349 }
2350 }
2351 /* Reset the Backup domain only if the RTC Clock source selection is modified from reset value */
2352 tmpreg1 = (RCC->BDCR & RCC_BDCR_RTCSEL);
2353 if((tmpreg1 != 0x00000000U) && ((tmpreg1) != (PeriphClkInit->RTCClockSelection & RCC_BDCR_RTCSEL)))
2354 {
2355 /* Store the content of BDCR register before the reset of Backup Domain */
2356 tmpreg1 = (RCC->BDCR & ~(RCC_BDCR_RTCSEL));
2357 /* RTC Clock selection can be changed only if the Backup Domain is reset */
2358 __HAL_RCC_BACKUPRESET_FORCE();
2359 __HAL_RCC_BACKUPRESET_RELEASE();
2360 /* Restore the Content of BDCR register */
2361 RCC->BDCR = tmpreg1;
2362
2363 /* Wait for LSE reactivation if LSE was enable prior to Backup Domain reset */
2364 if(HAL_IS_BIT_SET(RCC->BDCR, RCC_BDCR_LSEON))
2365 {
2366 /* Get tick */
2367 tickstart = HAL_GetTick();
2368
2369 /* Wait till LSE is ready */
2370 while(__HAL_RCC_GET_FLAG(RCC_FLAG_LSERDY) == RESET)
2371 {
2372 if((HAL_GetTick() - tickstart ) > RCC_LSE_TIMEOUT_VALUE)
2373 {
2374 return HAL_TIMEOUT;
2375 }
2376 }
2377 }
2378 }
2379 __HAL_RCC_RTC_CONFIG(PeriphClkInit->RTCClockSelection);
2380 }
2381 /*--------------------------------------------------------------------------*/
2382
2383 /*---------------------------- TIM configuration ---------------------------*/
2384 if(((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_TIM) == (RCC_PERIPHCLK_TIM))
2385 {
2386 __HAL_RCC_TIMCLKPRESCALER(PeriphClkInit->TIMPresSelection);
2387 }
2388 return HAL_OK;
2389 }
2390
2391 /**
2392 * @brief Configures the PeriphClkInit according to the internal
2393 * RCC configuration registers.
2394 * @param PeriphClkInit pointer to an RCC_PeriphCLKInitTypeDef structure that
2395 * will be configured.
2396 * @retval None
2397 */
HAL_RCCEx_GetPeriphCLKConfig(RCC_PeriphCLKInitTypeDef * PeriphClkInit)2398 void HAL_RCCEx_GetPeriphCLKConfig(RCC_PeriphCLKInitTypeDef *PeriphClkInit)
2399 {
2400 uint32_t tempreg;
2401
2402 /* Set all possible values for the extended clock type parameter------------*/
2403 PeriphClkInit->PeriphClockSelection = RCC_PERIPHCLK_I2S | RCC_PERIPHCLK_SAI_PLLSAI | RCC_PERIPHCLK_SAI_PLLI2S | RCC_PERIPHCLK_LTDC | RCC_PERIPHCLK_TIM | RCC_PERIPHCLK_RTC;
2404
2405 /* Get the PLLI2S Clock configuration -----------------------------------------------*/
2406 PeriphClkInit->PLLI2S.PLLI2SN = (uint32_t)((RCC->PLLI2SCFGR & RCC_PLLI2SCFGR_PLLI2SN) >> RCC_PLLI2SCFGR_PLLI2SN_Pos);
2407 PeriphClkInit->PLLI2S.PLLI2SR = (uint32_t)((RCC->PLLI2SCFGR & RCC_PLLI2SCFGR_PLLI2SR) >> RCC_PLLI2SCFGR_PLLI2SR_Pos);
2408 PeriphClkInit->PLLI2S.PLLI2SQ = (uint32_t)((RCC->PLLI2SCFGR & RCC_PLLI2SCFGR_PLLI2SQ) >> RCC_PLLI2SCFGR_PLLI2SQ_Pos);
2409 /* Get the PLLSAI Clock configuration -----------------------------------------------*/
2410 PeriphClkInit->PLLSAI.PLLSAIN = (uint32_t)((RCC->PLLSAICFGR & RCC_PLLSAICFGR_PLLSAIN) >> RCC_PLLSAICFGR_PLLSAIN_Pos);
2411 PeriphClkInit->PLLSAI.PLLSAIR = (uint32_t)((RCC->PLLSAICFGR & RCC_PLLSAICFGR_PLLSAIR) >> RCC_PLLSAICFGR_PLLSAIR_Pos);
2412 PeriphClkInit->PLLSAI.PLLSAIQ = (uint32_t)((RCC->PLLSAICFGR & RCC_PLLSAICFGR_PLLSAIQ) >> RCC_PLLSAICFGR_PLLSAIQ_Pos);
2413 /* Get the PLLSAI/PLLI2S division factors -----------------------------------------------*/
2414 PeriphClkInit->PLLI2SDivQ = (uint32_t)((RCC->DCKCFGR & RCC_DCKCFGR_PLLI2SDIVQ) >> RCC_DCKCFGR_PLLI2SDIVQ_Pos);
2415 PeriphClkInit->PLLSAIDivQ = (uint32_t)((RCC->DCKCFGR & RCC_DCKCFGR_PLLSAIDIVQ) >> RCC_DCKCFGR_PLLSAIDIVQ_Pos);
2416 PeriphClkInit->PLLSAIDivR = (uint32_t)(RCC->DCKCFGR & RCC_DCKCFGR_PLLSAIDIVR);
2417 /* Get the RTC Clock configuration -----------------------------------------------*/
2418 tempreg = (RCC->CFGR & RCC_CFGR_RTCPRE);
2419 PeriphClkInit->RTCClockSelection = (uint32_t)((tempreg) | (RCC->BDCR & RCC_BDCR_RTCSEL));
2420
2421 if ((RCC->DCKCFGR & RCC_DCKCFGR_TIMPRE) == RESET)
2422 {
2423 PeriphClkInit->TIMPresSelection = RCC_TIMPRES_DESACTIVATED;
2424 }
2425 else
2426 {
2427 PeriphClkInit->TIMPresSelection = RCC_TIMPRES_ACTIVATED;
2428 }
2429 }
2430
2431 /**
2432 * @brief Return the peripheral clock frequency for a given peripheral(SAI..)
2433 * @note Return 0 if peripheral clock identifier not managed by this API
2434 * @param PeriphClk Peripheral clock identifier
2435 * This parameter can be one of the following values:
2436 * @arg RCC_PERIPHCLK_I2S: I2S peripheral clock
2437 * @retval Frequency in KHz
2438 */
HAL_RCCEx_GetPeriphCLKFreq(uint32_t PeriphClk)2439 uint32_t HAL_RCCEx_GetPeriphCLKFreq(uint32_t PeriphClk)
2440 {
2441 /* This variable used to store the I2S clock frequency (value in Hz) */
2442 uint32_t frequency = 0U;
2443 /* This variable used to store the VCO Input (value in Hz) */
2444 uint32_t vcoinput = 0U;
2445 uint32_t srcclk = 0U;
2446 /* This variable used to store the VCO Output (value in Hz) */
2447 uint32_t vcooutput = 0U;
2448 switch (PeriphClk)
2449 {
2450 case RCC_PERIPHCLK_I2S:
2451 {
2452 /* Get the current I2S source */
2453 srcclk = __HAL_RCC_GET_I2S_SOURCE();
2454 switch (srcclk)
2455 {
2456 /* Check if I2S clock selection is External clock mapped on the I2S_CKIN pin used as I2S clock */
2457 case RCC_I2SCLKSOURCE_EXT:
2458 {
2459 /* Set the I2S clock to the external clock value */
2460 frequency = EXTERNAL_CLOCK_VALUE;
2461 break;
2462 }
2463 /* Check if I2S clock selection is PLLI2S VCO output clock divided by PLLI2SR used as I2S clock */
2464 case RCC_I2SCLKSOURCE_PLLI2S:
2465 {
2466 /* Configure the PLLI2S division factor */
2467 /* PLLI2S_VCO Input = PLL_SOURCE/PLLM */
2468 if((RCC->PLLCFGR & RCC_PLLCFGR_PLLSRC) == RCC_PLLSOURCE_HSE)
2469 {
2470 /* Get the I2S source clock value */
2471 vcoinput = (uint32_t)(HSE_VALUE / (uint32_t)(RCC->PLLCFGR & RCC_PLLCFGR_PLLM));
2472 }
2473 else
2474 {
2475 /* Get the I2S source clock value */
2476 vcoinput = (uint32_t)(HSI_VALUE / (uint32_t)(RCC->PLLCFGR & RCC_PLLCFGR_PLLM));
2477 }
2478
2479 /* PLLI2S_VCO Output = PLLI2S_VCO Input * PLLI2SN */
2480 vcooutput = (uint32_t)(vcoinput * (((RCC->PLLI2SCFGR & RCC_PLLI2SCFGR_PLLI2SN) >> 6U) & (RCC_PLLI2SCFGR_PLLI2SN >> 6U)));
2481 /* I2S_CLK = PLLI2S_VCO Output/PLLI2SR */
2482 frequency = (uint32_t)(vcooutput /(((RCC->PLLI2SCFGR & RCC_PLLI2SCFGR_PLLI2SR) >> 28U) & (RCC_PLLI2SCFGR_PLLI2SR >> 28U)));
2483 break;
2484 }
2485 /* Clock not enabled for I2S*/
2486 default:
2487 {
2488 frequency = 0U;
2489 break;
2490 }
2491 }
2492 break;
2493 }
2494 }
2495 return frequency;
2496 }
2497 #endif /* STM32F427xx || STM32F437xx || STM32F429xx || STM32F439xx */
2498
2499 #if defined(STM32F405xx) || defined(STM32F415xx) || defined(STM32F407xx)|| defined(STM32F417xx) ||\
2500 defined(STM32F401xC) || defined(STM32F401xE) || defined(STM32F411xE)
2501 /**
2502 * @brief Initializes the RCC extended peripherals clocks according to the specified parameters in the
2503 * RCC_PeriphCLKInitTypeDef.
2504 * @param PeriphClkInit pointer to an RCC_PeriphCLKInitTypeDef structure that
2505 * contains the configuration information for the Extended Peripherals clocks(I2S and RTC clocks).
2506 *
2507 * @note A caution to be taken when HAL_RCCEx_PeriphCLKConfig() is used to select RTC clock selection, in this case
2508 * the Reset of Backup domain will be applied in order to modify the RTC Clock source as consequence all backup
2509 * domain (RTC and RCC_BDCR register expect BKPSRAM) will be reset
2510 *
2511 * @retval HAL status
2512 */
HAL_RCCEx_PeriphCLKConfig(RCC_PeriphCLKInitTypeDef * PeriphClkInit)2513 HAL_StatusTypeDef HAL_RCCEx_PeriphCLKConfig(RCC_PeriphCLKInitTypeDef *PeriphClkInit)
2514 {
2515 uint32_t tickstart = 0U;
2516 uint32_t tmpreg1 = 0U;
2517
2518 /* Check the parameters */
2519 assert_param(IS_RCC_PERIPHCLOCK(PeriphClkInit->PeriphClockSelection));
2520
2521 /*---------------------------- I2S configuration ---------------------------*/
2522 if((((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_I2S) == RCC_PERIPHCLK_I2S) ||
2523 (((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_PLLI2S) == RCC_PERIPHCLK_PLLI2S))
2524 {
2525 /* check for Parameters */
2526 assert_param(IS_RCC_PLLI2SR_VALUE(PeriphClkInit->PLLI2S.PLLI2SR));
2527 assert_param(IS_RCC_PLLI2SN_VALUE(PeriphClkInit->PLLI2S.PLLI2SN));
2528 #if defined(STM32F411xE)
2529 assert_param(IS_RCC_PLLI2SM_VALUE(PeriphClkInit->PLLI2S.PLLI2SM));
2530 #endif /* STM32F411xE */
2531 /* Disable the PLLI2S */
2532 __HAL_RCC_PLLI2S_DISABLE();
2533 /* Get tick */
2534 tickstart = HAL_GetTick();
2535 /* Wait till PLLI2S is disabled */
2536 while(__HAL_RCC_GET_FLAG(RCC_FLAG_PLLI2SRDY) != RESET)
2537 {
2538 if((HAL_GetTick() - tickstart ) > PLLI2S_TIMEOUT_VALUE)
2539 {
2540 /* return in case of Timeout detected */
2541 return HAL_TIMEOUT;
2542 }
2543 }
2544
2545 #if defined(STM32F411xE)
2546 /* Configure the PLLI2S division factors */
2547 /* PLLI2S_VCO = f(VCO clock) = f(PLLI2S clock input) * (PLLI2SN/PLLI2SM) */
2548 /* I2SCLK = f(PLLI2S clock output) = f(VCO clock) / PLLI2SR */
2549 __HAL_RCC_PLLI2S_I2SCLK_CONFIG(PeriphClkInit->PLLI2S.PLLI2SM, PeriphClkInit->PLLI2S.PLLI2SN, PeriphClkInit->PLLI2S.PLLI2SR);
2550 #else
2551 /* Configure the PLLI2S division factors */
2552 /* PLLI2S_VCO = f(VCO clock) = f(PLLI2S clock input) * (PLLI2SN/PLLM) */
2553 /* I2SCLK = f(PLLI2S clock output) = f(VCO clock) / PLLI2SR */
2554 __HAL_RCC_PLLI2S_CONFIG(PeriphClkInit->PLLI2S.PLLI2SN , PeriphClkInit->PLLI2S.PLLI2SR);
2555 #endif /* STM32F411xE */
2556
2557 /* Enable the PLLI2S */
2558 __HAL_RCC_PLLI2S_ENABLE();
2559 /* Get tick */
2560 tickstart = HAL_GetTick();
2561 /* Wait till PLLI2S is ready */
2562 while(__HAL_RCC_GET_FLAG(RCC_FLAG_PLLI2SRDY) == RESET)
2563 {
2564 if((HAL_GetTick() - tickstart ) > PLLI2S_TIMEOUT_VALUE)
2565 {
2566 /* return in case of Timeout detected */
2567 return HAL_TIMEOUT;
2568 }
2569 }
2570 }
2571
2572 /*---------------------------- RTC configuration ---------------------------*/
2573 if(((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_RTC) == (RCC_PERIPHCLK_RTC))
2574 {
2575 /* Check for RTC Parameters used to output RTCCLK */
2576 assert_param(IS_RCC_RTCCLKSOURCE(PeriphClkInit->RTCClockSelection));
2577
2578 /* Enable Power Clock*/
2579 __HAL_RCC_PWR_CLK_ENABLE();
2580
2581 /* Enable write access to Backup domain */
2582 PWR->CR |= PWR_CR_DBP;
2583
2584 /* Get tick */
2585 tickstart = HAL_GetTick();
2586
2587 while((PWR->CR & PWR_CR_DBP) == RESET)
2588 {
2589 if((HAL_GetTick() - tickstart ) > RCC_DBP_TIMEOUT_VALUE)
2590 {
2591 return HAL_TIMEOUT;
2592 }
2593 }
2594 /* Reset the Backup domain only if the RTC Clock source selection is modified from reset value */
2595 tmpreg1 = (RCC->BDCR & RCC_BDCR_RTCSEL);
2596 if((tmpreg1 != 0x00000000U) && ((tmpreg1) != (PeriphClkInit->RTCClockSelection & RCC_BDCR_RTCSEL)))
2597 {
2598 /* Store the content of BDCR register before the reset of Backup Domain */
2599 tmpreg1 = (RCC->BDCR & ~(RCC_BDCR_RTCSEL));
2600 /* RTC Clock selection can be changed only if the Backup Domain is reset */
2601 __HAL_RCC_BACKUPRESET_FORCE();
2602 __HAL_RCC_BACKUPRESET_RELEASE();
2603 /* Restore the Content of BDCR register */
2604 RCC->BDCR = tmpreg1;
2605
2606 /* Wait for LSE reactivation if LSE was enable prior to Backup Domain reset */
2607 if(HAL_IS_BIT_SET(RCC->BDCR, RCC_BDCR_LSEON))
2608 {
2609 /* Get tick */
2610 tickstart = HAL_GetTick();
2611
2612 /* Wait till LSE is ready */
2613 while(__HAL_RCC_GET_FLAG(RCC_FLAG_LSERDY) == RESET)
2614 {
2615 if((HAL_GetTick() - tickstart ) > RCC_LSE_TIMEOUT_VALUE)
2616 {
2617 return HAL_TIMEOUT;
2618 }
2619 }
2620 }
2621 }
2622 __HAL_RCC_RTC_CONFIG(PeriphClkInit->RTCClockSelection);
2623 }
2624 #if defined(STM32F401xC) || defined(STM32F401xE) || defined(STM32F411xE)
2625 /*---------------------------- TIM configuration ---------------------------*/
2626 if(((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_TIM) == (RCC_PERIPHCLK_TIM))
2627 {
2628 __HAL_RCC_TIMCLKPRESCALER(PeriphClkInit->TIMPresSelection);
2629 }
2630 #endif /* STM32F401xC || STM32F401xE || STM32F411xE */
2631 return HAL_OK;
2632 }
2633
2634 /**
2635 * @brief Configures the RCC_OscInitStruct according to the internal
2636 * RCC configuration registers.
2637 * @param PeriphClkInit pointer to an RCC_PeriphCLKInitTypeDef structure that
2638 * will be configured.
2639 * @retval None
2640 */
HAL_RCCEx_GetPeriphCLKConfig(RCC_PeriphCLKInitTypeDef * PeriphClkInit)2641 void HAL_RCCEx_GetPeriphCLKConfig(RCC_PeriphCLKInitTypeDef *PeriphClkInit)
2642 {
2643 uint32_t tempreg;
2644
2645 /* Set all possible values for the extended clock type parameter------------*/
2646 PeriphClkInit->PeriphClockSelection = RCC_PERIPHCLK_I2S | RCC_PERIPHCLK_RTC;
2647
2648 /* Get the PLLI2S Clock configuration --------------------------------------*/
2649 PeriphClkInit->PLLI2S.PLLI2SN = (uint32_t)((RCC->PLLI2SCFGR & RCC_PLLI2SCFGR_PLLI2SN) >> RCC_PLLI2SCFGR_PLLI2SN_Pos);
2650 PeriphClkInit->PLLI2S.PLLI2SR = (uint32_t)((RCC->PLLI2SCFGR & RCC_PLLI2SCFGR_PLLI2SR) >> RCC_PLLI2SCFGR_PLLI2SR_Pos);
2651 #if defined(STM32F411xE)
2652 PeriphClkInit->PLLI2S.PLLI2SM = (uint32_t)(RCC->PLLI2SCFGR & RCC_PLLI2SCFGR_PLLI2SM);
2653 #endif /* STM32F411xE */
2654 /* Get the RTC Clock configuration -----------------------------------------*/
2655 tempreg = (RCC->CFGR & RCC_CFGR_RTCPRE);
2656 PeriphClkInit->RTCClockSelection = (uint32_t)((tempreg) | (RCC->BDCR & RCC_BDCR_RTCSEL));
2657
2658 #if defined(STM32F401xC) || defined(STM32F401xE) || defined(STM32F411xE)
2659 /* Get the TIM Prescaler configuration -------------------------------------*/
2660 if ((RCC->DCKCFGR & RCC_DCKCFGR_TIMPRE) == RESET)
2661 {
2662 PeriphClkInit->TIMPresSelection = RCC_TIMPRES_DESACTIVATED;
2663 }
2664 else
2665 {
2666 PeriphClkInit->TIMPresSelection = RCC_TIMPRES_ACTIVATED;
2667 }
2668 #endif /* STM32F401xC || STM32F401xE || STM32F411xE */
2669 }
2670
2671 /**
2672 * @brief Return the peripheral clock frequency for a given peripheral(SAI..)
2673 * @note Return 0 if peripheral clock identifier not managed by this API
2674 * @param PeriphClk Peripheral clock identifier
2675 * This parameter can be one of the following values:
2676 * @arg RCC_PERIPHCLK_I2S: I2S peripheral clock
2677 * @retval Frequency in KHz
2678 */
HAL_RCCEx_GetPeriphCLKFreq(uint32_t PeriphClk)2679 uint32_t HAL_RCCEx_GetPeriphCLKFreq(uint32_t PeriphClk)
2680 {
2681 /* This variable used to store the I2S clock frequency (value in Hz) */
2682 uint32_t frequency = 0U;
2683 /* This variable used to store the VCO Input (value in Hz) */
2684 uint32_t vcoinput = 0U;
2685 uint32_t srcclk = 0U;
2686 /* This variable used to store the VCO Output (value in Hz) */
2687 uint32_t vcooutput = 0U;
2688 switch (PeriphClk)
2689 {
2690 case RCC_PERIPHCLK_I2S:
2691 {
2692 /* Get the current I2S source */
2693 srcclk = __HAL_RCC_GET_I2S_SOURCE();
2694 switch (srcclk)
2695 {
2696 /* Check if I2S clock selection is External clock mapped on the I2S_CKIN pin used as I2S clock */
2697 case RCC_I2SCLKSOURCE_EXT:
2698 {
2699 /* Set the I2S clock to the external clock value */
2700 frequency = EXTERNAL_CLOCK_VALUE;
2701 break;
2702 }
2703 /* Check if I2S clock selection is PLLI2S VCO output clock divided by PLLI2SR used as I2S clock */
2704 case RCC_I2SCLKSOURCE_PLLI2S:
2705 {
2706 #if defined(STM32F411xE)
2707 /* Configure the PLLI2S division factor */
2708 /* PLLI2S_VCO Input = PLL_SOURCE/PLLI2SM */
2709 if((RCC->PLLCFGR & RCC_PLLCFGR_PLLSRC) == RCC_PLLSOURCE_HSE)
2710 {
2711 /* Get the I2S source clock value */
2712 vcoinput = (uint32_t)(HSE_VALUE / (uint32_t)(RCC->PLLI2SCFGR & RCC_PLLI2SCFGR_PLLI2SM));
2713 }
2714 else
2715 {
2716 /* Get the I2S source clock value */
2717 vcoinput = (uint32_t)(HSI_VALUE / (uint32_t)(RCC->PLLI2SCFGR & RCC_PLLI2SCFGR_PLLI2SM));
2718 }
2719 #else
2720 /* Configure the PLLI2S division factor */
2721 /* PLLI2S_VCO Input = PLL_SOURCE/PLLM */
2722 if((RCC->PLLCFGR & RCC_PLLCFGR_PLLSRC) == RCC_PLLSOURCE_HSE)
2723 {
2724 /* Get the I2S source clock value */
2725 vcoinput = (uint32_t)(HSE_VALUE / (uint32_t)(RCC->PLLCFGR & RCC_PLLCFGR_PLLM));
2726 }
2727 else
2728 {
2729 /* Get the I2S source clock value */
2730 vcoinput = (uint32_t)(HSI_VALUE / (uint32_t)(RCC->PLLCFGR & RCC_PLLCFGR_PLLM));
2731 }
2732 #endif /* STM32F411xE */
2733 /* PLLI2S_VCO Output = PLLI2S_VCO Input * PLLI2SN */
2734 vcooutput = (uint32_t)(vcoinput * (((RCC->PLLI2SCFGR & RCC_PLLI2SCFGR_PLLI2SN) >> 6U) & (RCC_PLLI2SCFGR_PLLI2SN >> 6U)));
2735 /* I2S_CLK = PLLI2S_VCO Output/PLLI2SR */
2736 frequency = (uint32_t)(vcooutput /(((RCC->PLLI2SCFGR & RCC_PLLI2SCFGR_PLLI2SR) >> 28U) & (RCC_PLLI2SCFGR_PLLI2SR >> 28U)));
2737 break;
2738 }
2739 /* Clock not enabled for I2S*/
2740 default:
2741 {
2742 frequency = 0U;
2743 break;
2744 }
2745 }
2746 break;
2747 }
2748 }
2749 return frequency;
2750 }
2751 #endif /* STM32F405xx || STM32F415xx || STM32F407xx || STM32F417xx || STM32F401xC || STM32F401xE || STM32F411xE */
2752
2753 #if defined(STM32F410Tx) || defined(STM32F410Cx) || defined(STM32F410Rx) || defined(STM32F411xE) || defined(STM32F446xx) || defined(STM32F469xx) || defined(STM32F479xx) || defined(STM32F412Zx) ||\
2754 defined(STM32F412Vx) || defined(STM32F412Rx) || defined(STM32F412Cx) || defined(STM32F413xx) || defined(STM32F423xx)
2755 /**
2756 * @brief Select LSE mode
2757 *
2758 * @note This mode is only available for STM32F410xx/STM32F411xx/STM32F446xx/STM32F469xx/STM32F479xx/STM32F412Zx/STM32F412Vx/STM32F412Rx/STM32F412Cx devices.
2759 *
2760 * @param Mode specifies the LSE mode.
2761 * This parameter can be one of the following values:
2762 * @arg RCC_LSE_LOWPOWER_MODE: LSE oscillator in low power mode selection
2763 * @arg RCC_LSE_HIGHDRIVE_MODE: LSE oscillator in High Drive mode selection
2764 * @retval None
2765 */
HAL_RCCEx_SelectLSEMode(uint8_t Mode)2766 void HAL_RCCEx_SelectLSEMode(uint8_t Mode)
2767 {
2768 /* Check the parameters */
2769 assert_param(IS_RCC_LSE_MODE(Mode));
2770 if(Mode == RCC_LSE_HIGHDRIVE_MODE)
2771 {
2772 SET_BIT(RCC->BDCR, RCC_BDCR_LSEMOD);
2773 }
2774 else
2775 {
2776 CLEAR_BIT(RCC->BDCR, RCC_BDCR_LSEMOD);
2777 }
2778 }
2779
2780 #endif /* STM32F410xx || STM32F411xE || STM32F446xx || STM32F469xx || STM32F479xx || STM32F412Zx || STM32F412Vx || STM32F412Rx || STM32F412Cx || STM32F413xx || STM32F423xx */
2781
2782 /** @defgroup RCCEx_Exported_Functions_Group2 Extended Clock management functions
2783 * @brief Extended Clock management functions
2784 *
2785 @verbatim
2786 ===============================================================================
2787 ##### Extended clock management functions #####
2788 ===============================================================================
2789 [..]
2790 This subsection provides a set of functions allowing to control the
2791 activation or deactivation of PLLI2S, PLLSAI.
2792 @endverbatim
2793 * @{
2794 */
2795
2796 #if defined(RCC_PLLI2S_SUPPORT)
2797 /**
2798 * @brief Enable PLLI2S.
2799 * @param PLLI2SInit pointer to an RCC_PLLI2SInitTypeDef structure that
2800 * contains the configuration information for the PLLI2S
2801 * @retval HAL status
2802 */
HAL_RCCEx_EnablePLLI2S(RCC_PLLI2SInitTypeDef * PLLI2SInit)2803 HAL_StatusTypeDef HAL_RCCEx_EnablePLLI2S(RCC_PLLI2SInitTypeDef *PLLI2SInit)
2804 {
2805 uint32_t tickstart;
2806
2807 /* Check for parameters */
2808 assert_param(IS_RCC_PLLI2SN_VALUE(PLLI2SInit->PLLI2SN));
2809 assert_param(IS_RCC_PLLI2SR_VALUE(PLLI2SInit->PLLI2SR));
2810 #if defined(RCC_PLLI2SCFGR_PLLI2SM)
2811 assert_param(IS_RCC_PLLI2SM_VALUE(PLLI2SInit->PLLI2SM));
2812 #endif /* RCC_PLLI2SCFGR_PLLI2SM */
2813 #if defined(RCC_PLLI2SCFGR_PLLI2SP)
2814 assert_param(IS_RCC_PLLI2SP_VALUE(PLLI2SInit->PLLI2SP));
2815 #endif /* RCC_PLLI2SCFGR_PLLI2SP */
2816 #if defined(RCC_PLLI2SCFGR_PLLI2SQ)
2817 assert_param(IS_RCC_PLLI2SQ_VALUE(PLLI2SInit->PLLI2SQ));
2818 #endif /* RCC_PLLI2SCFGR_PLLI2SQ */
2819
2820 /* Disable the PLLI2S */
2821 __HAL_RCC_PLLI2S_DISABLE();
2822
2823 /* Wait till PLLI2S is disabled */
2824 tickstart = HAL_GetTick();
2825 while(__HAL_RCC_GET_FLAG(RCC_FLAG_PLLI2SRDY) != RESET)
2826 {
2827 if((HAL_GetTick() - tickstart ) > PLLI2S_TIMEOUT_VALUE)
2828 {
2829 /* return in case of Timeout detected */
2830 return HAL_TIMEOUT;
2831 }
2832 }
2833
2834 /* Configure the PLLI2S division factors */
2835 #if defined(STM32F446xx)
2836 /* PLLI2S_VCO = f(VCO clock) = f(PLLI2S clock input) * (PLLI2SN/PLLI2SM) */
2837 /* I2SPCLK = PLLI2S_VCO / PLLI2SP */
2838 /* I2SQCLK = PLLI2S_VCO / PLLI2SQ */
2839 /* I2SRCLK = PLLI2S_VCO / PLLI2SR */
2840 __HAL_RCC_PLLI2S_CONFIG(PLLI2SInit->PLLI2SM, PLLI2SInit->PLLI2SN, \
2841 PLLI2SInit->PLLI2SP, PLLI2SInit->PLLI2SQ, PLLI2SInit->PLLI2SR);
2842 #elif defined(STM32F412Zx) || defined(STM32F412Vx) || defined(STM32F412Rx) || defined(STM32F412Cx) ||\
2843 defined(STM32F413xx) || defined(STM32F423xx)
2844 /* PLLI2S_VCO = f(VCO clock) = f(PLLI2S clock input) * (PLLI2SN/PLLI2SM)*/
2845 /* I2SQCLK = PLLI2S_VCO / PLLI2SQ */
2846 /* I2SRCLK = PLLI2S_VCO / PLLI2SR */
2847 __HAL_RCC_PLLI2S_CONFIG(PLLI2SInit->PLLI2SM, PLLI2SInit->PLLI2SN, \
2848 PLLI2SInit->PLLI2SQ, PLLI2SInit->PLLI2SR);
2849 #elif defined(STM32F427xx) || defined(STM32F437xx) || defined(STM32F429xx) || defined(STM32F439xx) ||\
2850 defined(STM32F469xx) || defined(STM32F479xx)
2851 /* PLLI2S_VCO = f(VCO clock) = f(PLLI2S clock input) * PLLI2SN */
2852 /* I2SQCLK = PLLI2S_VCO / PLLI2SQ */
2853 /* I2SRCLK = PLLI2S_VCO / PLLI2SR */
2854 __HAL_RCC_PLLI2S_SAICLK_CONFIG(PLLI2SInit->PLLI2SN, PLLI2SInit->PLLI2SQ, PLLI2SInit->PLLI2SR);
2855 #elif defined(STM32F411xE)
2856 /* PLLI2S_VCO = f(VCO clock) = f(PLLI2S clock input) * (PLLI2SN/PLLI2SM) */
2857 /* I2SRCLK = PLLI2S_VCO / PLLI2SR */
2858 __HAL_RCC_PLLI2S_I2SCLK_CONFIG(PLLI2SInit->PLLI2SM, PLLI2SInit->PLLI2SN, PLLI2SInit->PLLI2SR);
2859 #else
2860 /* PLLI2S_VCO = f(VCO clock) = f(PLLI2S clock input) x PLLI2SN */
2861 /* I2SRCLK = PLLI2S_VCO / PLLI2SR */
2862 __HAL_RCC_PLLI2S_CONFIG(PLLI2SInit->PLLI2SN, PLLI2SInit->PLLI2SR);
2863 #endif /* STM32F446xx */
2864
2865 /* Enable the PLLI2S */
2866 __HAL_RCC_PLLI2S_ENABLE();
2867
2868 /* Wait till PLLI2S is ready */
2869 tickstart = HAL_GetTick();
2870 while(__HAL_RCC_GET_FLAG(RCC_FLAG_PLLI2SRDY) == RESET)
2871 {
2872 if((HAL_GetTick() - tickstart ) > PLLI2S_TIMEOUT_VALUE)
2873 {
2874 /* return in case of Timeout detected */
2875 return HAL_TIMEOUT;
2876 }
2877 }
2878
2879 return HAL_OK;
2880 }
2881
2882 /**
2883 * @brief Disable PLLI2S.
2884 * @retval HAL status
2885 */
HAL_RCCEx_DisablePLLI2S(void)2886 HAL_StatusTypeDef HAL_RCCEx_DisablePLLI2S(void)
2887 {
2888 uint32_t tickstart;
2889
2890 /* Disable the PLLI2S */
2891 __HAL_RCC_PLLI2S_DISABLE();
2892
2893 /* Wait till PLLI2S is disabled */
2894 tickstart = HAL_GetTick();
2895 while(READ_BIT(RCC->CR, RCC_CR_PLLI2SRDY) != RESET)
2896 {
2897 if((HAL_GetTick() - tickstart) > PLLI2S_TIMEOUT_VALUE)
2898 {
2899 /* return in case of Timeout detected */
2900 return HAL_TIMEOUT;
2901 }
2902 }
2903
2904 return HAL_OK;
2905 }
2906
2907 #endif /* RCC_PLLI2S_SUPPORT */
2908
2909 #if defined(RCC_PLLSAI_SUPPORT)
2910 /**
2911 * @brief Enable PLLSAI.
2912 * @param PLLSAIInit pointer to an RCC_PLLSAIInitTypeDef structure that
2913 * contains the configuration information for the PLLSAI
2914 * @retval HAL status
2915 */
HAL_RCCEx_EnablePLLSAI(RCC_PLLSAIInitTypeDef * PLLSAIInit)2916 HAL_StatusTypeDef HAL_RCCEx_EnablePLLSAI(RCC_PLLSAIInitTypeDef *PLLSAIInit)
2917 {
2918 uint32_t tickstart;
2919
2920 /* Check for parameters */
2921 assert_param(IS_RCC_PLLSAIN_VALUE(PLLSAIInit->PLLSAIN));
2922 assert_param(IS_RCC_PLLSAIQ_VALUE(PLLSAIInit->PLLSAIQ));
2923 #if defined(RCC_PLLSAICFGR_PLLSAIM)
2924 assert_param(IS_RCC_PLLSAIM_VALUE(PLLSAIInit->PLLSAIM));
2925 #endif /* RCC_PLLSAICFGR_PLLSAIM */
2926 #if defined(RCC_PLLSAICFGR_PLLSAIP)
2927 assert_param(IS_RCC_PLLSAIP_VALUE(PLLSAIInit->PLLSAIP));
2928 #endif /* RCC_PLLSAICFGR_PLLSAIP */
2929 #if defined(RCC_PLLSAICFGR_PLLSAIR)
2930 assert_param(IS_RCC_PLLSAIR_VALUE(PLLSAIInit->PLLSAIR));
2931 #endif /* RCC_PLLSAICFGR_PLLSAIR */
2932
2933 /* Disable the PLLSAI */
2934 __HAL_RCC_PLLSAI_DISABLE();
2935
2936 /* Wait till PLLSAI is disabled */
2937 tickstart = HAL_GetTick();
2938 while(__HAL_RCC_PLLSAI_GET_FLAG() != RESET)
2939 {
2940 if((HAL_GetTick() - tickstart ) > PLLSAI_TIMEOUT_VALUE)
2941 {
2942 /* return in case of Timeout detected */
2943 return HAL_TIMEOUT;
2944 }
2945 }
2946
2947 /* Configure the PLLSAI division factors */
2948 #if defined(STM32F446xx)
2949 /* PLLSAI_VCO = f(VCO clock) = f(PLLSAI clock input) * (PLLSAIN/PLLSAIM) */
2950 /* SAIPCLK = PLLSAI_VCO / PLLSAIP */
2951 /* SAIQCLK = PLLSAI_VCO / PLLSAIQ */
2952 /* SAIRCLK = PLLSAI_VCO / PLLSAIR */
2953 __HAL_RCC_PLLSAI_CONFIG(PLLSAIInit->PLLSAIM, PLLSAIInit->PLLSAIN, \
2954 PLLSAIInit->PLLSAIP, PLLSAIInit->PLLSAIQ, 0U);
2955 #elif defined(STM32F469xx) || defined(STM32F479xx)
2956 /* PLLSAI_VCO = f(VCO clock) = f(PLLSAI clock input) * PLLSAIN */
2957 /* SAIPCLK = PLLSAI_VCO / PLLSAIP */
2958 /* SAIQCLK = PLLSAI_VCO / PLLSAIQ */
2959 /* SAIRCLK = PLLSAI_VCO / PLLSAIR */
2960 __HAL_RCC_PLLSAI_CONFIG(PLLSAIInit->PLLSAIN, PLLSAIInit->PLLSAIP, \
2961 PLLSAIInit->PLLSAIQ, PLLSAIInit->PLLSAIR);
2962 #else
2963 /* PLLSAI_VCO = f(VCO clock) = f(PLLSAI clock input) x PLLSAIN */
2964 /* SAIQCLK = PLLSAI_VCO / PLLSAIQ */
2965 /* SAIRCLK = PLLSAI_VCO / PLLSAIR */
2966 __HAL_RCC_PLLSAI_CONFIG(PLLSAIInit->PLLSAIN, PLLSAIInit->PLLSAIQ, PLLSAIInit->PLLSAIR);
2967 #endif /* STM32F446xx */
2968
2969 /* Enable the PLLSAI */
2970 __HAL_RCC_PLLSAI_ENABLE();
2971
2972 /* Wait till PLLSAI is ready */
2973 tickstart = HAL_GetTick();
2974 while(__HAL_RCC_PLLSAI_GET_FLAG() == RESET)
2975 {
2976 if((HAL_GetTick() - tickstart ) > PLLSAI_TIMEOUT_VALUE)
2977 {
2978 /* return in case of Timeout detected */
2979 return HAL_TIMEOUT;
2980 }
2981 }
2982
2983 return HAL_OK;
2984 }
2985
2986 /**
2987 * @brief Disable PLLSAI.
2988 * @retval HAL status
2989 */
HAL_RCCEx_DisablePLLSAI(void)2990 HAL_StatusTypeDef HAL_RCCEx_DisablePLLSAI(void)
2991 {
2992 uint32_t tickstart;
2993
2994 /* Disable the PLLSAI */
2995 __HAL_RCC_PLLSAI_DISABLE();
2996
2997 /* Wait till PLLSAI is disabled */
2998 tickstart = HAL_GetTick();
2999 while(__HAL_RCC_PLLSAI_GET_FLAG() != RESET)
3000 {
3001 if((HAL_GetTick() - tickstart) > PLLSAI_TIMEOUT_VALUE)
3002 {
3003 /* return in case of Timeout detected */
3004 return HAL_TIMEOUT;
3005 }
3006 }
3007
3008 return HAL_OK;
3009 }
3010
3011 #endif /* RCC_PLLSAI_SUPPORT */
3012
3013 /**
3014 * @}
3015 */
3016
3017 #if defined(STM32F446xx)
3018 /**
3019 * @brief Returns the SYSCLK frequency
3020 *
3021 * @note This function implementation is valid only for STM32F446xx devices.
3022 * @note This function add the PLL/PLLR System clock source
3023 *
3024 * @note The system frequency computed by this function is not the real
3025 * frequency in the chip. It is calculated based on the predefined
3026 * constant and the selected clock source:
3027 * @note If SYSCLK source is HSI, function returns values based on HSI_VALUE(*)
3028 * @note If SYSCLK source is HSE, function returns values based on HSE_VALUE(**)
3029 * @note If SYSCLK source is PLL or PLLR, function returns values based on HSE_VALUE(**)
3030 * or HSI_VALUE(*) multiplied/divided by the PLL factors.
3031 * @note (*) HSI_VALUE is a constant defined in stm32f4xx_hal_conf.h file (default value
3032 * 16 MHz) but the real value may vary depending on the variations
3033 * in voltage and temperature.
3034 * @note (**) HSE_VALUE is a constant defined in stm32f4xx_hal_conf.h file (default value
3035 * 25 MHz), user has to ensure that HSE_VALUE is same as the real
3036 * frequency of the crystal used. Otherwise, this function may
3037 * have wrong result.
3038 *
3039 * @note The result of this function could be not correct when using fractional
3040 * value for HSE crystal.
3041 *
3042 * @note This function can be used by the user application to compute the
3043 * baudrate for the communication peripherals or configure other parameters.
3044 *
3045 * @note Each time SYSCLK changes, this function must be called to update the
3046 * right SYSCLK value. Otherwise, any configuration based on this function will be incorrect.
3047 *
3048 *
3049 * @retval SYSCLK frequency
3050 */
HAL_RCC_GetSysClockFreq(void)3051 uint32_t HAL_RCC_GetSysClockFreq(void)
3052 {
3053 uint32_t pllm = 0U;
3054 uint32_t pllvco = 0U;
3055 uint32_t pllp = 0U;
3056 uint32_t pllr = 0U;
3057 uint32_t sysclockfreq = 0U;
3058
3059 /* Get SYSCLK source -------------------------------------------------------*/
3060 switch (RCC->CFGR & RCC_CFGR_SWS)
3061 {
3062 case RCC_CFGR_SWS_HSI: /* HSI used as system clock source */
3063 {
3064 sysclockfreq = HSI_VALUE;
3065 break;
3066 }
3067 case RCC_CFGR_SWS_HSE: /* HSE used as system clock source */
3068 {
3069 sysclockfreq = HSE_VALUE;
3070 break;
3071 }
3072 case RCC_CFGR_SWS_PLL: /* PLL/PLLP used as system clock source */
3073 {
3074 /* PLL_VCO = (HSE_VALUE or HSI_VALUE / PLLM) * PLLN
3075 SYSCLK = PLL_VCO / PLLP */
3076 pllm = RCC->PLLCFGR & RCC_PLLCFGR_PLLM;
3077 if(__HAL_RCC_GET_PLL_OSCSOURCE() != RCC_PLLSOURCE_HSI)
3078 {
3079 /* HSE used as PLL clock source */
3080 pllvco = (uint32_t) ((((uint64_t) HSE_VALUE * ((uint64_t) ((RCC->PLLCFGR & RCC_PLLCFGR_PLLN) >> RCC_PLLCFGR_PLLN_Pos)))) / (uint64_t)pllm);
3081 }
3082 else
3083 {
3084 /* HSI used as PLL clock source */
3085 pllvco = (uint32_t) ((((uint64_t) HSI_VALUE * ((uint64_t) ((RCC->PLLCFGR & RCC_PLLCFGR_PLLN) >> RCC_PLLCFGR_PLLN_Pos)))) / (uint64_t)pllm);
3086 }
3087 pllp = ((((RCC->PLLCFGR & RCC_PLLCFGR_PLLP) >> RCC_PLLCFGR_PLLP_Pos) + 1U) *2U);
3088
3089 sysclockfreq = pllvco/pllp;
3090 break;
3091 }
3092 case RCC_CFGR_SWS_PLLR: /* PLL/PLLR used as system clock source */
3093 {
3094 /* PLL_VCO = (HSE_VALUE or HSI_VALUE / PLLM) * PLLN
3095 SYSCLK = PLL_VCO / PLLR */
3096 pllm = RCC->PLLCFGR & RCC_PLLCFGR_PLLM;
3097 if(__HAL_RCC_GET_PLL_OSCSOURCE() != RCC_PLLSOURCE_HSI)
3098 {
3099 /* HSE used as PLL clock source */
3100 pllvco = (uint32_t) ((((uint64_t) HSE_VALUE * ((uint64_t) ((RCC->PLLCFGR & RCC_PLLCFGR_PLLN) >> RCC_PLLCFGR_PLLN_Pos)))) / (uint64_t)pllm);
3101 }
3102 else
3103 {
3104 /* HSI used as PLL clock source */
3105 pllvco = (uint32_t) ((((uint64_t) HSI_VALUE * ((uint64_t) ((RCC->PLLCFGR & RCC_PLLCFGR_PLLN) >> RCC_PLLCFGR_PLLN_Pos)))) / (uint64_t)pllm);
3106 }
3107 pllr = ((RCC->PLLCFGR & RCC_PLLCFGR_PLLR) >> RCC_PLLCFGR_PLLR_Pos);
3108
3109 sysclockfreq = pllvco/pllr;
3110 break;
3111 }
3112 default:
3113 {
3114 sysclockfreq = HSI_VALUE;
3115 break;
3116 }
3117 }
3118 return sysclockfreq;
3119 }
3120 #endif /* STM32F446xx */
3121
3122 /**
3123 * @}
3124 */
3125
3126 /**
3127 * @}
3128 */
3129
3130 /**
3131 * @brief Resets the RCC clock configuration to the default reset state.
3132 * @note The default reset state of the clock configuration is given below:
3133 * - HSI ON and used as system clock source
3134 * - HSE, PLL, PLLI2S and PLLSAI OFF
3135 * - AHB, APB1 and APB2 prescaler set to 1.
3136 * - CSS, MCO1 and MCO2 OFF
3137 * - All interrupts disabled
3138 * @note This function doesn't modify the configuration of the
3139 * - Peripheral clocks
3140 * - LSI, LSE and RTC clocks
3141 * @retval HAL status
3142 */
HAL_RCC_DeInit(void)3143 HAL_StatusTypeDef HAL_RCC_DeInit(void)
3144 {
3145 uint32_t tickstart;
3146
3147 /* Get Start Tick */
3148 tickstart = HAL_GetTick();
3149
3150 /* Set HSION bit to the reset value */
3151 SET_BIT(RCC->CR, RCC_CR_HSION);
3152
3153 /* Wait till HSI is ready */
3154 while (READ_BIT(RCC->CR, RCC_CR_HSIRDY) == RESET)
3155 {
3156 if ((HAL_GetTick() - tickstart) > HSI_TIMEOUT_VALUE)
3157 {
3158 return HAL_TIMEOUT;
3159 }
3160 }
3161
3162 /* Set HSITRIM[4:0] bits to the reset value */
3163 SET_BIT(RCC->CR, RCC_CR_HSITRIM_4);
3164
3165 /* Get Start Tick */
3166 tickstart = HAL_GetTick();
3167
3168 /* Reset CFGR register */
3169 CLEAR_REG(RCC->CFGR);
3170
3171 /* Wait till clock switch is ready */
3172 while (READ_BIT(RCC->CFGR, RCC_CFGR_SWS) != RESET)
3173 {
3174 if ((HAL_GetTick() - tickstart) > CLOCKSWITCH_TIMEOUT_VALUE)
3175 {
3176 return HAL_TIMEOUT;
3177 }
3178 }
3179
3180 /* Get Start Tick */
3181 tickstart = HAL_GetTick();
3182
3183 /* Clear HSEON, HSEBYP and CSSON bits */
3184 CLEAR_BIT(RCC->CR, RCC_CR_HSEON | RCC_CR_HSEBYP | RCC_CR_CSSON);
3185
3186 /* Wait till HSE is disabled */
3187 while (READ_BIT(RCC->CR, RCC_CR_HSERDY) != RESET)
3188 {
3189 if ((HAL_GetTick() - tickstart) > HSE_TIMEOUT_VALUE)
3190 {
3191 return HAL_TIMEOUT;
3192 }
3193 }
3194
3195 /* Get Start Tick */
3196 tickstart = HAL_GetTick();
3197
3198 /* Clear PLLON bit */
3199 CLEAR_BIT(RCC->CR, RCC_CR_PLLON);
3200
3201 /* Wait till PLL is disabled */
3202 while (READ_BIT(RCC->CR, RCC_CR_PLLRDY) != RESET)
3203 {
3204 if ((HAL_GetTick() - tickstart) > PLL_TIMEOUT_VALUE)
3205 {
3206 return HAL_TIMEOUT;
3207 }
3208 }
3209
3210 #if defined(RCC_PLLI2S_SUPPORT)
3211 /* Get Start Tick */
3212 tickstart = HAL_GetTick();
3213
3214 /* Reset PLLI2SON bit */
3215 CLEAR_BIT(RCC->CR, RCC_CR_PLLI2SON);
3216
3217 /* Wait till PLLI2S is disabled */
3218 while (READ_BIT(RCC->CR, RCC_CR_PLLI2SRDY) != RESET)
3219 {
3220 if ((HAL_GetTick() - tickstart) > PLLI2S_TIMEOUT_VALUE)
3221 {
3222 return HAL_TIMEOUT;
3223 }
3224 }
3225 #endif /* RCC_PLLI2S_SUPPORT */
3226
3227 #if defined(RCC_PLLSAI_SUPPORT)
3228 /* Get Start Tick */
3229 tickstart = HAL_GetTick();
3230
3231 /* Reset PLLSAI bit */
3232 CLEAR_BIT(RCC->CR, RCC_CR_PLLSAION);
3233
3234 /* Wait till PLLSAI is disabled */
3235 while (READ_BIT(RCC->CR, RCC_CR_PLLSAIRDY) != RESET)
3236 {
3237 if ((HAL_GetTick() - tickstart) > PLLSAI_TIMEOUT_VALUE)
3238 {
3239 return HAL_TIMEOUT;
3240 }
3241 }
3242 #endif /* RCC_PLLSAI_SUPPORT */
3243
3244 /* Once PLL, PLLI2S and PLLSAI are OFF, reset PLLCFGR register to default value */
3245 #if defined(STM32F412Cx) || defined(STM32F412Rx) || defined(STM32F412Vx) || defined(STM32F412Zx) || defined(STM32F413xx) || \
3246 defined(STM32F423xx) || defined(STM32F446xx) || defined(STM32F469xx) || defined(STM32F479xx)
3247 RCC->PLLCFGR = RCC_PLLCFGR_PLLM_4 | RCC_PLLCFGR_PLLN_6 | RCC_PLLCFGR_PLLN_7 | RCC_PLLCFGR_PLLQ_2 | RCC_PLLCFGR_PLLR_1;
3248 #elif defined(STM32F410Tx) || defined(STM32F410Cx) || defined(STM32F410Rx)
3249 RCC->PLLCFGR = RCC_PLLCFGR_PLLR_0 | RCC_PLLCFGR_PLLR_1 | RCC_PLLCFGR_PLLR_2 | RCC_PLLCFGR_PLLM_4 | RCC_PLLCFGR_PLLN_6 | RCC_PLLCFGR_PLLN_7 | RCC_PLLCFGR_PLLQ_0 | RCC_PLLCFGR_PLLQ_1 | RCC_PLLCFGR_PLLQ_2 | RCC_PLLCFGR_PLLQ_3;
3250 #else
3251 RCC->PLLCFGR = RCC_PLLCFGR_PLLM_4 | RCC_PLLCFGR_PLLN_6 | RCC_PLLCFGR_PLLN_7 | RCC_PLLCFGR_PLLQ_2;
3252 #endif /* STM32F412Cx || STM32F412Rx || STM32F412Vx || STM32F412Zx || STM32F413xx || STM32F423xx || STM32F446xx || STM32F469xx || STM32F479xx */
3253
3254 /* Reset PLLI2SCFGR register to default value */
3255 #if defined(STM32F412Cx) || defined(STM32F412Rx) || defined(STM32F412Vx) || defined(STM32F412Zx) || defined(STM32F413xx) || \
3256 defined(STM32F423xx) || defined(STM32F446xx)
3257 RCC->PLLI2SCFGR = RCC_PLLI2SCFGR_PLLI2SM_4 | RCC_PLLI2SCFGR_PLLI2SN_6 | RCC_PLLI2SCFGR_PLLI2SN_7 | RCC_PLLI2SCFGR_PLLI2SQ_2 | RCC_PLLI2SCFGR_PLLI2SR_1;
3258 #elif defined(STM32F401xC) || defined(STM32F401xE) || defined(STM32F405xx) || defined(STM32F415xx) || defined(STM32F407xx) || defined(STM32F417xx)
3259 RCC->PLLI2SCFGR = RCC_PLLI2SCFGR_PLLI2SN_6 | RCC_PLLI2SCFGR_PLLI2SN_7 | RCC_PLLI2SCFGR_PLLI2SR_1;
3260 #elif defined(STM32F427xx) || defined(STM32F437xx) || defined(STM32F429xx) || defined(STM32F439xx) || defined(STM32F469xx) || defined(STM32F479xx)
3261 RCC->PLLI2SCFGR = RCC_PLLI2SCFGR_PLLI2SN_6 | RCC_PLLI2SCFGR_PLLI2SN_7 | RCC_PLLI2SCFGR_PLLI2SQ_2 | RCC_PLLI2SCFGR_PLLI2SR_1;
3262 #elif defined(STM32F411xE)
3263 RCC->PLLI2SCFGR = RCC_PLLI2SCFGR_PLLI2SM_4 | RCC_PLLI2SCFGR_PLLI2SN_6 | RCC_PLLI2SCFGR_PLLI2SN_7 | RCC_PLLI2SCFGR_PLLI2SR_1;
3264 #endif /* STM32F412Cx || STM32F412Rx || STM32F412Vx || STM32F412Zx || STM32F413xx || STM32F423xx || STM32F446xx */
3265
3266 /* Reset PLLSAICFGR register */
3267 #if defined(STM32F427xx) || defined(STM32F429xx) || defined(STM32F437xx) || defined(STM32F439xx) || defined(STM32F469xx) || defined(STM32F479xx)
3268 RCC->PLLSAICFGR = RCC_PLLSAICFGR_PLLSAIN_6 | RCC_PLLSAICFGR_PLLSAIN_7 | RCC_PLLSAICFGR_PLLSAIQ_2 | RCC_PLLSAICFGR_PLLSAIR_1;
3269 #elif defined(STM32F446xx)
3270 RCC->PLLSAICFGR = RCC_PLLSAICFGR_PLLSAIM_4 | RCC_PLLSAICFGR_PLLSAIN_6 | RCC_PLLSAICFGR_PLLSAIN_7 | RCC_PLLSAICFGR_PLLSAIQ_2;
3271 #endif /* STM32F427xx || STM32F429xx || STM32F437xx || STM32F439xx || STM32F469xx || STM32F479xx */
3272
3273 /* Disable all interrupts */
3274 CLEAR_BIT(RCC->CIR, RCC_CIR_LSIRDYIE | RCC_CIR_LSERDYIE | RCC_CIR_HSIRDYIE | RCC_CIR_HSERDYIE | RCC_CIR_PLLRDYIE);
3275
3276 #if defined(RCC_CIR_PLLI2SRDYIE)
3277 CLEAR_BIT(RCC->CIR, RCC_CIR_PLLI2SRDYIE);
3278 #endif /* RCC_CIR_PLLI2SRDYIE */
3279
3280 #if defined(RCC_CIR_PLLSAIRDYIE)
3281 CLEAR_BIT(RCC->CIR, RCC_CIR_PLLSAIRDYIE);
3282 #endif /* RCC_CIR_PLLSAIRDYIE */
3283
3284 /* Clear all interrupt flags */
3285 SET_BIT(RCC->CIR, RCC_CIR_LSIRDYC | RCC_CIR_LSERDYC | RCC_CIR_HSIRDYC | RCC_CIR_HSERDYC | RCC_CIR_PLLRDYC | RCC_CIR_CSSC);
3286
3287 #if defined(RCC_CIR_PLLI2SRDYC)
3288 SET_BIT(RCC->CIR, RCC_CIR_PLLI2SRDYC);
3289 #endif /* RCC_CIR_PLLI2SRDYC */
3290
3291 #if defined(RCC_CIR_PLLSAIRDYC)
3292 SET_BIT(RCC->CIR, RCC_CIR_PLLSAIRDYC);
3293 #endif /* RCC_CIR_PLLSAIRDYC */
3294
3295 /* Clear LSION bit */
3296 CLEAR_BIT(RCC->CSR, RCC_CSR_LSION);
3297
3298 /* Reset all CSR flags */
3299 SET_BIT(RCC->CSR, RCC_CSR_RMVF);
3300
3301 /* Update the SystemCoreClock global variable */
3302 SystemCoreClock = HSI_VALUE;
3303
3304 /* Adapt Systick interrupt period */
3305 if(HAL_InitTick(uwTickPrio) != HAL_OK)
3306 {
3307 return HAL_ERROR;
3308 }
3309 else
3310 {
3311 return HAL_OK;
3312 }
3313 }
3314
3315 #if defined(STM32F410Tx) || defined(STM32F410Cx) || defined(STM32F410Rx) || defined(STM32F446xx) || defined(STM32F469xx) || defined(STM32F479xx) || defined(STM32F412Zx) ||\
3316 defined(STM32F412Vx) || defined(STM32F412Rx) || defined(STM32F412Cx) || defined(STM32F413xx) || defined(STM32F423xx)
3317 /**
3318 * @brief Initializes the RCC Oscillators according to the specified parameters in the
3319 * RCC_OscInitTypeDef.
3320 * @param RCC_OscInitStruct pointer to an RCC_OscInitTypeDef structure that
3321 * contains the configuration information for the RCC Oscillators.
3322 * @note The PLL is not disabled when used as system clock.
3323 * @note Transitions LSE Bypass to LSE On and LSE On to LSE Bypass are not
3324 * supported by this API. User should request a transition to LSE Off
3325 * first and then LSE On or LSE Bypass.
3326 * @note Transition HSE Bypass to HSE On and HSE On to HSE Bypass are not
3327 * supported by this API. User should request a transition to HSE Off
3328 * first and then HSE On or HSE Bypass.
3329 * @note This function add the PLL/PLLR factor management during PLL configuration this feature
3330 * is only available in STM32F410xx/STM32F446xx/STM32F469xx/STM32F479xx/STM32F412Zx/STM32F412Vx/STM32F412Rx/STM32F412Cx devices
3331 * @retval HAL status
3332 */
HAL_RCC_OscConfig(RCC_OscInitTypeDef * RCC_OscInitStruct)3333 HAL_StatusTypeDef HAL_RCC_OscConfig(RCC_OscInitTypeDef *RCC_OscInitStruct)
3334 {
3335 uint32_t tickstart, pll_config;
3336
3337 /* Check Null pointer */
3338 if(RCC_OscInitStruct == NULL)
3339 {
3340 return HAL_ERROR;
3341 }
3342
3343 /* Check the parameters */
3344 assert_param(IS_RCC_OSCILLATORTYPE(RCC_OscInitStruct->OscillatorType));
3345 /*------------------------------- HSE Configuration ------------------------*/
3346 if(((RCC_OscInitStruct->OscillatorType) & RCC_OSCILLATORTYPE_HSE) == RCC_OSCILLATORTYPE_HSE)
3347 {
3348 /* Check the parameters */
3349 assert_param(IS_RCC_HSE(RCC_OscInitStruct->HSEState));
3350 /* When the HSE is used as system clock or clock source for PLL in these cases HSE will not disabled */
3351 #if defined(STM32F446xx)
3352 if((__HAL_RCC_GET_SYSCLK_SOURCE() == RCC_CFGR_SWS_HSE) ||\
3353 ((__HAL_RCC_GET_SYSCLK_SOURCE() == RCC_CFGR_SWS_PLL) && ((RCC->PLLCFGR & RCC_PLLCFGR_PLLSRC) == RCC_PLLCFGR_PLLSRC_HSE)) ||\
3354 ((__HAL_RCC_GET_SYSCLK_SOURCE() == RCC_CFGR_SWS_PLLR) && ((RCC->PLLCFGR & RCC_PLLCFGR_PLLSRC) == RCC_PLLCFGR_PLLSRC_HSE)))
3355 #else
3356 if((__HAL_RCC_GET_SYSCLK_SOURCE() == RCC_CFGR_SWS_HSE) ||\
3357 ((__HAL_RCC_GET_SYSCLK_SOURCE() == RCC_CFGR_SWS_PLL) && ((RCC->PLLCFGR & RCC_PLLCFGR_PLLSRC) == RCC_PLLCFGR_PLLSRC_HSE)))
3358 #endif /* STM32F446xx */
3359 {
3360 if((__HAL_RCC_GET_FLAG(RCC_FLAG_HSERDY) != RESET) && (RCC_OscInitStruct->HSEState == RCC_HSE_OFF))
3361 {
3362 return HAL_ERROR;
3363 }
3364 }
3365 else
3366 {
3367 /* Set the new HSE configuration ---------------------------------------*/
3368 __HAL_RCC_HSE_CONFIG(RCC_OscInitStruct->HSEState);
3369
3370 /* Check the HSE State */
3371 if((RCC_OscInitStruct->HSEState) != RCC_HSE_OFF)
3372 {
3373 /* Get Start Tick*/
3374 tickstart = HAL_GetTick();
3375
3376 /* Wait till HSE is ready */
3377 while(__HAL_RCC_GET_FLAG(RCC_FLAG_HSERDY) == RESET)
3378 {
3379 if((HAL_GetTick() - tickstart ) > HSE_TIMEOUT_VALUE)
3380 {
3381 return HAL_TIMEOUT;
3382 }
3383 }
3384 }
3385 else
3386 {
3387 /* Get Start Tick*/
3388 tickstart = HAL_GetTick();
3389
3390 /* Wait till HSE is bypassed or disabled */
3391 while(__HAL_RCC_GET_FLAG(RCC_FLAG_HSERDY) != RESET)
3392 {
3393 if((HAL_GetTick() - tickstart ) > HSE_TIMEOUT_VALUE)
3394 {
3395 return HAL_TIMEOUT;
3396 }
3397 }
3398 }
3399 }
3400 }
3401 /*----------------------------- HSI Configuration --------------------------*/
3402 if(((RCC_OscInitStruct->OscillatorType) & RCC_OSCILLATORTYPE_HSI) == RCC_OSCILLATORTYPE_HSI)
3403 {
3404 /* Check the parameters */
3405 assert_param(IS_RCC_HSI(RCC_OscInitStruct->HSIState));
3406 assert_param(IS_RCC_CALIBRATION_VALUE(RCC_OscInitStruct->HSICalibrationValue));
3407
3408 /* Check if HSI is used as system clock or as PLL source when PLL is selected as system clock */
3409 #if defined(STM32F446xx)
3410 if((__HAL_RCC_GET_SYSCLK_SOURCE() == RCC_CFGR_SWS_HSI) ||\
3411 ((__HAL_RCC_GET_SYSCLK_SOURCE() == RCC_CFGR_SWS_PLL) && ((RCC->PLLCFGR & RCC_PLLCFGR_PLLSRC) == RCC_PLLCFGR_PLLSRC_HSI)) ||\
3412 ((__HAL_RCC_GET_SYSCLK_SOURCE() == RCC_CFGR_SWS_PLLR) && ((RCC->PLLCFGR & RCC_PLLCFGR_PLLSRC) == RCC_PLLCFGR_PLLSRC_HSI)))
3413 #else
3414 if((__HAL_RCC_GET_SYSCLK_SOURCE() == RCC_CFGR_SWS_HSI) ||\
3415 ((__HAL_RCC_GET_SYSCLK_SOURCE() == RCC_CFGR_SWS_PLL) && ((RCC->PLLCFGR & RCC_PLLCFGR_PLLSRC) == RCC_PLLCFGR_PLLSRC_HSI)))
3416 #endif /* STM32F446xx */
3417 {
3418 /* When HSI is used as system clock it will not disabled */
3419 if((__HAL_RCC_GET_FLAG(RCC_FLAG_HSIRDY) != RESET) && (RCC_OscInitStruct->HSIState != RCC_HSI_ON))
3420 {
3421 return HAL_ERROR;
3422 }
3423 /* Otherwise, just the calibration is allowed */
3424 else
3425 {
3426 /* Adjusts the Internal High Speed oscillator (HSI) calibration value.*/
3427 __HAL_RCC_HSI_CALIBRATIONVALUE_ADJUST(RCC_OscInitStruct->HSICalibrationValue);
3428 }
3429 }
3430 else
3431 {
3432 /* Check the HSI State */
3433 if((RCC_OscInitStruct->HSIState)!= RCC_HSI_OFF)
3434 {
3435 /* Enable the Internal High Speed oscillator (HSI). */
3436 __HAL_RCC_HSI_ENABLE();
3437
3438 /* Get Start Tick*/
3439 tickstart = HAL_GetTick();
3440
3441 /* Wait till HSI is ready */
3442 while(__HAL_RCC_GET_FLAG(RCC_FLAG_HSIRDY) == RESET)
3443 {
3444 if((HAL_GetTick() - tickstart ) > HSI_TIMEOUT_VALUE)
3445 {
3446 return HAL_TIMEOUT;
3447 }
3448 }
3449
3450 /* Adjusts the Internal High Speed oscillator (HSI) calibration value.*/
3451 __HAL_RCC_HSI_CALIBRATIONVALUE_ADJUST(RCC_OscInitStruct->HSICalibrationValue);
3452 }
3453 else
3454 {
3455 /* Disable the Internal High Speed oscillator (HSI). */
3456 __HAL_RCC_HSI_DISABLE();
3457
3458 /* Get Start Tick*/
3459 tickstart = HAL_GetTick();
3460
3461 /* Wait till HSI is ready */
3462 while(__HAL_RCC_GET_FLAG(RCC_FLAG_HSIRDY) != RESET)
3463 {
3464 if((HAL_GetTick() - tickstart ) > HSI_TIMEOUT_VALUE)
3465 {
3466 return HAL_TIMEOUT;
3467 }
3468 }
3469 }
3470 }
3471 }
3472 /*------------------------------ LSI Configuration -------------------------*/
3473 if(((RCC_OscInitStruct->OscillatorType) & RCC_OSCILLATORTYPE_LSI) == RCC_OSCILLATORTYPE_LSI)
3474 {
3475 /* Check the parameters */
3476 assert_param(IS_RCC_LSI(RCC_OscInitStruct->LSIState));
3477
3478 /* Check the LSI State */
3479 if((RCC_OscInitStruct->LSIState)!= RCC_LSI_OFF)
3480 {
3481 /* Enable the Internal Low Speed oscillator (LSI). */
3482 __HAL_RCC_LSI_ENABLE();
3483
3484 /* Get Start Tick*/
3485 tickstart = HAL_GetTick();
3486
3487 /* Wait till LSI is ready */
3488 while(__HAL_RCC_GET_FLAG(RCC_FLAG_LSIRDY) == RESET)
3489 {
3490 if((HAL_GetTick() - tickstart ) > LSI_TIMEOUT_VALUE)
3491 {
3492 return HAL_TIMEOUT;
3493 }
3494 }
3495 }
3496 else
3497 {
3498 /* Disable the Internal Low Speed oscillator (LSI). */
3499 __HAL_RCC_LSI_DISABLE();
3500
3501 /* Get Start Tick*/
3502 tickstart = HAL_GetTick();
3503
3504 /* Wait till LSI is ready */
3505 while(__HAL_RCC_GET_FLAG(RCC_FLAG_LSIRDY) != RESET)
3506 {
3507 if((HAL_GetTick() - tickstart ) > LSI_TIMEOUT_VALUE)
3508 {
3509 return HAL_TIMEOUT;
3510 }
3511 }
3512 }
3513 }
3514 /*------------------------------ LSE Configuration -------------------------*/
3515 if(((RCC_OscInitStruct->OscillatorType) & RCC_OSCILLATORTYPE_LSE) == RCC_OSCILLATORTYPE_LSE)
3516 {
3517 FlagStatus pwrclkchanged = RESET;
3518
3519 /* Check the parameters */
3520 assert_param(IS_RCC_LSE(RCC_OscInitStruct->LSEState));
3521
3522 /* Update LSE configuration in Backup Domain control register */
3523 /* Requires to enable write access to Backup Domain of necessary */
3524 if(__HAL_RCC_PWR_IS_CLK_DISABLED())
3525 {
3526 __HAL_RCC_PWR_CLK_ENABLE();
3527 pwrclkchanged = SET;
3528 }
3529
3530 if(HAL_IS_BIT_CLR(PWR->CR, PWR_CR_DBP))
3531 {
3532 /* Enable write access to Backup domain */
3533 SET_BIT(PWR->CR, PWR_CR_DBP);
3534
3535 /* Wait for Backup domain Write protection disable */
3536 tickstart = HAL_GetTick();
3537
3538 while(HAL_IS_BIT_CLR(PWR->CR, PWR_CR_DBP))
3539 {
3540 if((HAL_GetTick() - tickstart) > RCC_DBP_TIMEOUT_VALUE)
3541 {
3542 return HAL_TIMEOUT;
3543 }
3544 }
3545 }
3546
3547 /* Set the new LSE configuration -----------------------------------------*/
3548 __HAL_RCC_LSE_CONFIG(RCC_OscInitStruct->LSEState);
3549 /* Check the LSE State */
3550 if((RCC_OscInitStruct->LSEState) != RCC_LSE_OFF)
3551 {
3552 /* Get Start Tick*/
3553 tickstart = HAL_GetTick();
3554
3555 /* Wait till LSE is ready */
3556 while(__HAL_RCC_GET_FLAG(RCC_FLAG_LSERDY) == RESET)
3557 {
3558 if((HAL_GetTick() - tickstart ) > RCC_LSE_TIMEOUT_VALUE)
3559 {
3560 return HAL_TIMEOUT;
3561 }
3562 }
3563 }
3564 else
3565 {
3566 /* Get Start Tick*/
3567 tickstart = HAL_GetTick();
3568
3569 /* Wait till LSE is ready */
3570 while(__HAL_RCC_GET_FLAG(RCC_FLAG_LSERDY) != RESET)
3571 {
3572 if((HAL_GetTick() - tickstart ) > RCC_LSE_TIMEOUT_VALUE)
3573 {
3574 return HAL_TIMEOUT;
3575 }
3576 }
3577 }
3578
3579 /* Restore clock configuration if changed */
3580 if(pwrclkchanged == SET)
3581 {
3582 __HAL_RCC_PWR_CLK_DISABLE();
3583 }
3584 }
3585 /*-------------------------------- PLL Configuration -----------------------*/
3586 /* Check the parameters */
3587 assert_param(IS_RCC_PLL(RCC_OscInitStruct->PLL.PLLState));
3588 if ((RCC_OscInitStruct->PLL.PLLState) != RCC_PLL_NONE)
3589 {
3590 /* Check if the PLL is used as system clock or not */
3591 if(__HAL_RCC_GET_SYSCLK_SOURCE() != RCC_CFGR_SWS_PLL)
3592 {
3593 if((RCC_OscInitStruct->PLL.PLLState) == RCC_PLL_ON)
3594 {
3595 /* Check the parameters */
3596 assert_param(IS_RCC_PLLSOURCE(RCC_OscInitStruct->PLL.PLLSource));
3597 assert_param(IS_RCC_PLLM_VALUE(RCC_OscInitStruct->PLL.PLLM));
3598 assert_param(IS_RCC_PLLN_VALUE(RCC_OscInitStruct->PLL.PLLN));
3599 assert_param(IS_RCC_PLLP_VALUE(RCC_OscInitStruct->PLL.PLLP));
3600 assert_param(IS_RCC_PLLQ_VALUE(RCC_OscInitStruct->PLL.PLLQ));
3601 assert_param(IS_RCC_PLLR_VALUE(RCC_OscInitStruct->PLL.PLLR));
3602
3603 /* Disable the main PLL. */
3604 __HAL_RCC_PLL_DISABLE();
3605
3606 /* Get Start Tick*/
3607 tickstart = HAL_GetTick();
3608
3609 /* Wait till PLL is ready */
3610 while(__HAL_RCC_GET_FLAG(RCC_FLAG_PLLRDY) != RESET)
3611 {
3612 if((HAL_GetTick() - tickstart ) > PLL_TIMEOUT_VALUE)
3613 {
3614 return HAL_TIMEOUT;
3615 }
3616 }
3617
3618 /* Configure the main PLL clock source, multiplication and division factors. */
3619 WRITE_REG(RCC->PLLCFGR, (RCC_OscInitStruct->PLL.PLLSource | \
3620 RCC_OscInitStruct->PLL.PLLM | \
3621 (RCC_OscInitStruct->PLL.PLLN << RCC_PLLCFGR_PLLN_Pos) | \
3622 (((RCC_OscInitStruct->PLL.PLLP >> 1U) - 1U) << RCC_PLLCFGR_PLLP_Pos) | \
3623 (RCC_OscInitStruct->PLL.PLLQ << RCC_PLLCFGR_PLLQ_Pos) | \
3624 (RCC_OscInitStruct->PLL.PLLR << RCC_PLLCFGR_PLLR_Pos)));
3625 /* Enable the main PLL. */
3626 __HAL_RCC_PLL_ENABLE();
3627
3628 /* Get Start Tick*/
3629 tickstart = HAL_GetTick();
3630
3631 /* Wait till PLL is ready */
3632 while(__HAL_RCC_GET_FLAG(RCC_FLAG_PLLRDY) == RESET)
3633 {
3634 if((HAL_GetTick() - tickstart ) > PLL_TIMEOUT_VALUE)
3635 {
3636 return HAL_TIMEOUT;
3637 }
3638 }
3639 }
3640 else
3641 {
3642 /* Disable the main PLL. */
3643 __HAL_RCC_PLL_DISABLE();
3644
3645 /* Get Start Tick*/
3646 tickstart = HAL_GetTick();
3647
3648 /* Wait till PLL is ready */
3649 while(__HAL_RCC_GET_FLAG(RCC_FLAG_PLLRDY) != RESET)
3650 {
3651 if((HAL_GetTick() - tickstart ) > PLL_TIMEOUT_VALUE)
3652 {
3653 return HAL_TIMEOUT;
3654 }
3655 }
3656 }
3657 }
3658 else
3659 {
3660 /* Check if there is a request to disable the PLL used as System clock source */
3661 if((RCC_OscInitStruct->PLL.PLLState) == RCC_PLL_OFF)
3662 {
3663 return HAL_ERROR;
3664 }
3665 else
3666 {
3667 /* Do not return HAL_ERROR if request repeats the current configuration */
3668 pll_config = RCC->PLLCFGR;
3669 #if defined (RCC_PLLCFGR_PLLR)
3670 if (((RCC_OscInitStruct->PLL.PLLState) == RCC_PLL_OFF) ||
3671 (READ_BIT(pll_config, RCC_PLLCFGR_PLLSRC) != RCC_OscInitStruct->PLL.PLLSource) ||
3672 (READ_BIT(pll_config, RCC_PLLCFGR_PLLM) != (RCC_OscInitStruct->PLL.PLLM) << RCC_PLLCFGR_PLLM_Pos) ||
3673 (READ_BIT(pll_config, RCC_PLLCFGR_PLLN) != (RCC_OscInitStruct->PLL.PLLN) << RCC_PLLCFGR_PLLN_Pos) ||
3674 (READ_BIT(pll_config, RCC_PLLCFGR_PLLP) != (((RCC_OscInitStruct->PLL.PLLP >> 1U) - 1U)) << RCC_PLLCFGR_PLLP_Pos) ||
3675 (READ_BIT(pll_config, RCC_PLLCFGR_PLLQ) != (RCC_OscInitStruct->PLL.PLLQ << RCC_PLLCFGR_PLLQ_Pos)) ||
3676 (READ_BIT(pll_config, RCC_PLLCFGR_PLLR) != (RCC_OscInitStruct->PLL.PLLR << RCC_PLLCFGR_PLLR_Pos)))
3677 #else
3678 if (((RCC_OscInitStruct->PLL.PLLState) == RCC_PLL_OFF) ||
3679 (READ_BIT(pll_config, RCC_PLLCFGR_PLLSRC) != RCC_OscInitStruct->PLL.PLLSource) ||
3680 (READ_BIT(pll_config, RCC_PLLCFGR_PLLM) != (RCC_OscInitStruct->PLL.PLLM) << RCC_PLLCFGR_PLLM_Pos) ||
3681 (READ_BIT(pll_config, RCC_PLLCFGR_PLLN) != (RCC_OscInitStruct->PLL.PLLN) << RCC_PLLCFGR_PLLN_Pos) ||
3682 (READ_BIT(pll_config, RCC_PLLCFGR_PLLP) != (((RCC_OscInitStruct->PLL.PLLP >> 1U) - 1U)) << RCC_PLLCFGR_PLLP_Pos) ||
3683 (READ_BIT(pll_config, RCC_PLLCFGR_PLLQ) != (RCC_OscInitStruct->PLL.PLLQ << RCC_PLLCFGR_PLLQ_Pos)))
3684 #endif
3685 {
3686 return HAL_ERROR;
3687 }
3688 }
3689 }
3690 }
3691 return HAL_OK;
3692 }
3693
3694 /**
3695 * @brief Configures the RCC_OscInitStruct according to the internal
3696 * RCC configuration registers.
3697 * @param RCC_OscInitStruct pointer to an RCC_OscInitTypeDef structure that will be configured.
3698 *
3699 * @note This function is only available in case of STM32F410xx/STM32F446xx/STM32F469xx/STM32F479xx/STM32F412Zx/STM32F412Vx/STM32F412Rx/STM32F412Cx devices.
3700 * @note This function add the PLL/PLLR factor management
3701 * @retval None
3702 */
HAL_RCC_GetOscConfig(RCC_OscInitTypeDef * RCC_OscInitStruct)3703 void HAL_RCC_GetOscConfig(RCC_OscInitTypeDef *RCC_OscInitStruct)
3704 {
3705 /* Set all possible values for the Oscillator type parameter ---------------*/
3706 RCC_OscInitStruct->OscillatorType = RCC_OSCILLATORTYPE_HSE | RCC_OSCILLATORTYPE_HSI | RCC_OSCILLATORTYPE_LSE | RCC_OSCILLATORTYPE_LSI;
3707
3708 /* Get the HSE configuration -----------------------------------------------*/
3709 if((RCC->CR &RCC_CR_HSEBYP) == RCC_CR_HSEBYP)
3710 {
3711 RCC_OscInitStruct->HSEState = RCC_HSE_BYPASS;
3712 }
3713 else if((RCC->CR &RCC_CR_HSEON) == RCC_CR_HSEON)
3714 {
3715 RCC_OscInitStruct->HSEState = RCC_HSE_ON;
3716 }
3717 else
3718 {
3719 RCC_OscInitStruct->HSEState = RCC_HSE_OFF;
3720 }
3721
3722 /* Get the HSI configuration -----------------------------------------------*/
3723 if((RCC->CR &RCC_CR_HSION) == RCC_CR_HSION)
3724 {
3725 RCC_OscInitStruct->HSIState = RCC_HSI_ON;
3726 }
3727 else
3728 {
3729 RCC_OscInitStruct->HSIState = RCC_HSI_OFF;
3730 }
3731
3732 RCC_OscInitStruct->HSICalibrationValue = (uint32_t)((RCC->CR &RCC_CR_HSITRIM) >> RCC_CR_HSITRIM_Pos);
3733
3734 /* Get the LSE configuration -----------------------------------------------*/
3735 if((RCC->BDCR &RCC_BDCR_LSEBYP) == RCC_BDCR_LSEBYP)
3736 {
3737 RCC_OscInitStruct->LSEState = RCC_LSE_BYPASS;
3738 }
3739 else if((RCC->BDCR &RCC_BDCR_LSEON) == RCC_BDCR_LSEON)
3740 {
3741 RCC_OscInitStruct->LSEState = RCC_LSE_ON;
3742 }
3743 else
3744 {
3745 RCC_OscInitStruct->LSEState = RCC_LSE_OFF;
3746 }
3747
3748 /* Get the LSI configuration -----------------------------------------------*/
3749 if((RCC->CSR &RCC_CSR_LSION) == RCC_CSR_LSION)
3750 {
3751 RCC_OscInitStruct->LSIState = RCC_LSI_ON;
3752 }
3753 else
3754 {
3755 RCC_OscInitStruct->LSIState = RCC_LSI_OFF;
3756 }
3757
3758 /* Get the PLL configuration -----------------------------------------------*/
3759 if((RCC->CR &RCC_CR_PLLON) == RCC_CR_PLLON)
3760 {
3761 RCC_OscInitStruct->PLL.PLLState = RCC_PLL_ON;
3762 }
3763 else
3764 {
3765 RCC_OscInitStruct->PLL.PLLState = RCC_PLL_OFF;
3766 }
3767 RCC_OscInitStruct->PLL.PLLSource = (uint32_t)(RCC->PLLCFGR & RCC_PLLCFGR_PLLSRC);
3768 RCC_OscInitStruct->PLL.PLLM = (uint32_t)(RCC->PLLCFGR & RCC_PLLCFGR_PLLM);
3769 RCC_OscInitStruct->PLL.PLLN = (uint32_t)((RCC->PLLCFGR & RCC_PLLCFGR_PLLN) >> RCC_PLLCFGR_PLLN_Pos);
3770 RCC_OscInitStruct->PLL.PLLP = (uint32_t)((((RCC->PLLCFGR & RCC_PLLCFGR_PLLP) + RCC_PLLCFGR_PLLP_0) << 1U) >> RCC_PLLCFGR_PLLP_Pos);
3771 RCC_OscInitStruct->PLL.PLLQ = (uint32_t)((RCC->PLLCFGR & RCC_PLLCFGR_PLLQ) >> RCC_PLLCFGR_PLLQ_Pos);
3772 RCC_OscInitStruct->PLL.PLLR = (uint32_t)((RCC->PLLCFGR & RCC_PLLCFGR_PLLR) >> RCC_PLLCFGR_PLLR_Pos);
3773 }
3774 #endif /* STM32F410xx || STM32F446xx || STM32F469xx || STM32F479xx || STM32F412Zx || STM32F412Vx || STM32F412Rx || STM32F412Cx || STM32F413xx || STM32F423xx */
3775
3776 #endif /* HAL_RCC_MODULE_ENABLED */
3777 /**
3778 * @}
3779 */
3780
3781 /**
3782 * @}
3783 */
3784
3785