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