comparison Common/Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_rcc_ex.c @ 128:c78bcbd5deda FlipDisplay

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