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