1 /**
2 ******************************************************************************
3 * @file stm32g0xx_hal_rcc_ex.c
4 * @author MCD Application Team
5 * @brief Extended RCC HAL module driver.
6 * This file provides firmware functions to manage the following
7 * functionalities RCC extended peripheral:
8 * + Extended Peripheral Control functions
9 * + Extended Clock management functions
10 * + Extended Clock Recovery System Control functions
11 *
12 ******************************************************************************
13 * @attention
14 *
15 * Copyright (c) 2018 STMicroelectronics.
16 * All rights reserved.
17 *
18 * This software is licensed under terms that can be found in the LICENSE file in
19 * the root directory of this software component.
20 * If no LICENSE file comes with this software, it is provided AS-IS.
21 ******************************************************************************
22 */
23
24 /* Includes ------------------------------------------------------------------*/
25 #include "stm32g0xx_hal.h"
26
27 /** @addtogroup STM32G0xx_HAL_Driver
28 * @{
29 */
30
31 /** @defgroup RCCEx RCCEx
32 * @brief RCC Extended HAL module driver
33 * @{
34 */
35
36 #ifdef HAL_RCC_MODULE_ENABLED
37
38 /* Private typedef -----------------------------------------------------------*/
39 /* Private defines -----------------------------------------------------------*/
40 /** @defgroup RCCEx_Private_Constants RCCEx Private Constants
41 * @{
42 */
43 #define PLL_TIMEOUT_VALUE 100U /* 100 ms (minimum Tick + 1) */
44
45 #define LSCO_CLK_ENABLE() __HAL_RCC_GPIOA_CLK_ENABLE()
46 #define LSCO_GPIO_PORT GPIOA
47 #define LSCO_PIN GPIO_PIN_2
48 /**
49 * @}
50 */
51
52 /* Private macros ------------------------------------------------------------*/
53 /* Private variables ---------------------------------------------------------*/
54 /* Private function prototypes -----------------------------------------------*/
55 /* Exported functions --------------------------------------------------------*/
56
57 /** @defgroup RCCEx_Exported_Functions RCCEx Exported Functions
58 * @{
59 */
60
61 /** @defgroup RCCEx_Exported_Functions_Group1 Extended Peripheral Control functions
62 * @brief Extended Peripheral Control functions
63 *
64 @verbatim
65 ===============================================================================
66 ##### Extended Peripheral Control functions #####
67 ===============================================================================
68 [..]
69 This subsection provides a set of functions allowing to control the RCC Clocks
70 frequencies.
71 [..]
72 (@) Important note: Care must be taken when HAL_RCCEx_PeriphCLKConfig() is used to
73 select the RTC clock source; in this case the Backup domain will be reset in
74 order to modify the RTC Clock source, as consequence RTC registers (including
75 the backup registers) and RCC_BDCR register are set to their reset values.
76
77 @endverbatim
78 * @{
79 */
80 /**
81 * @brief Initialize the RCC extended peripherals clocks according to the specified
82 * parameters in the @ref RCC_PeriphCLKInitTypeDef.
83 * @param PeriphClkInit pointer to a @ref RCC_PeriphCLKInitTypeDef structure that
84 * contains a field PeriphClockSelection which can be a combination of the following values:
85 * @arg @ref RCC_PERIPHCLK_RTC RTC peripheral clock
86 * @arg @ref RCC_PERIPHCLK_ADC ADC peripheral clock
87 * @arg @ref RCC_PERIPHCLK_I2C1 I2C1 peripheral clock
88 * @arg @ref RCC_PERIPHCLK_I2C2 I2C2 peripheral clock (2)
89 * @arg @ref RCC_PERIPHCLK_I2S1 I2S1 peripheral clock
90 * @arg @ref RCC_PERIPHCLK_I2S2 I2S2 peripheral clock (1)
91 * @arg @ref RCC_PERIPHCLK_USART1 USART1 peripheral clock
92 * @arg @ref RCC_PERIPHCLK_CEC CEC peripheral clock (1)
93 * @arg @ref RCC_PERIPHCLK_LPTIM1 LPTIM1 peripheral clock (1)
94 * @arg @ref RCC_PERIPHCLK_LPTIM2 LPTIM2 peripheral clock (1)
95 * @arg @ref RCC_PERIPHCLK_LPUART1 LPUART1 peripheral clock (1)
96 * @arg @ref RCC_PERIPHCLK_LPUART2 LPUART2 peripheral clock (1)
97 * @arg @ref RCC_PERIPHCLK_RNG RNG peripheral clock (1)
98 * @arg @ref RCC_PERIPHCLK_TIM1 TIM1 peripheral clock (1)(2)
99 * @arg @ref RCC_PERIPHCLK_TIM15 TIM15 peripheral clock (1)(2)
100 * @arg @ref RCC_PERIPHCLK_USART2 USART2 peripheral clock (2)
101 * @arg @ref RCC_PERIPHCLK_USART3 USART3 peripheral clock (2)
102 * @arg @ref RCC_PERIPHCLK_FDCAN FDCAN peripheral clock (1)
103 * @arg @ref RCC_PERIPHCLK_USB USB peripheral clock (1)
104 *
105 * @note (1) Peripherals are not available on all devices
106 * @note (2) Peripherals clock selection is not available on all devices
107 * @note Care must be taken when @ref HAL_RCCEx_PeriphCLKConfig() is used to select
108 * the RTC clock source: in this case the access to Backup domain is enabled.
109 *
110 * @retval HAL status
111 */
HAL_RCCEx_PeriphCLKConfig(RCC_PeriphCLKInitTypeDef * PeriphClkInit)112 HAL_StatusTypeDef HAL_RCCEx_PeriphCLKConfig(RCC_PeriphCLKInitTypeDef *PeriphClkInit)
113 {
114 uint32_t tmpregister;
115 uint32_t tickstart;
116 HAL_StatusTypeDef ret = HAL_OK; /* Intermediate status */
117 HAL_StatusTypeDef status = HAL_OK; /* Final status */
118
119 /* Check the parameters */
120 assert_param(IS_RCC_PERIPHCLOCK(PeriphClkInit->PeriphClockSelection));
121
122 /*-------------------------- RTC clock source configuration ----------------------*/
123 if ((PeriphClkInit->PeriphClockSelection & RCC_PERIPHCLK_RTC) == RCC_PERIPHCLK_RTC)
124 {
125 FlagStatus pwrclkchanged = RESET;
126
127 /* Check for RTC Parameters used to output RTCCLK */
128 assert_param(IS_RCC_RTCCLKSOURCE(PeriphClkInit->RTCClockSelection));
129
130 /* Enable Power Clock */
131 if (__HAL_RCC_PWR_IS_CLK_DISABLED())
132 {
133 __HAL_RCC_PWR_CLK_ENABLE();
134 pwrclkchanged = SET;
135 }
136
137 /* Enable write access to Backup domain */
138 SET_BIT(PWR->CR1, PWR_CR1_DBP);
139
140 /* Wait for Backup domain Write protection disable */
141 tickstart = HAL_GetTick();
142
143 while ((PWR->CR1 & PWR_CR1_DBP) == 0U)
144 {
145 if ((HAL_GetTick() - tickstart) > RCC_DBP_TIMEOUT_VALUE)
146 {
147 ret = HAL_TIMEOUT;
148 break;
149 }
150 }
151
152 if (ret == HAL_OK)
153 {
154 /* Reset the Backup domain only if the RTC Clock source selection is modified from default */
155 tmpregister = READ_BIT(RCC->BDCR, RCC_BDCR_RTCSEL);
156
157 /* Reset the Backup domain only if the RTC Clock source selection is modified */
158 if ((tmpregister != RCC_RTCCLKSOURCE_NONE) && (tmpregister != PeriphClkInit->RTCClockSelection))
159 {
160 /* Store the content of BDCR register before the reset of Backup Domain */
161 tmpregister = READ_BIT(RCC->BDCR, ~(RCC_BDCR_RTCSEL));
162 /* RTC Clock selection can be changed only if the Backup Domain is reset */
163 __HAL_RCC_BACKUPRESET_FORCE();
164 __HAL_RCC_BACKUPRESET_RELEASE();
165 /* Restore the Content of BDCR register */
166 RCC->BDCR = tmpregister;
167 }
168
169 /* Wait for LSE reactivation if LSE was enable prior to Backup Domain reset */
170 if (HAL_IS_BIT_SET(tmpregister, RCC_BDCR_LSEON))
171 {
172 /* Get Start Tick*/
173 tickstart = HAL_GetTick();
174
175 /* Wait till LSE is ready */
176 while (READ_BIT(RCC->BDCR, RCC_BDCR_LSERDY) == 0U)
177 {
178 if ((HAL_GetTick() - tickstart) > RCC_LSE_TIMEOUT_VALUE)
179 {
180 ret = HAL_TIMEOUT;
181 break;
182 }
183 }
184 }
185
186 if (ret == HAL_OK)
187 {
188 /* Apply new RTC clock source selection */
189 __HAL_RCC_RTC_CONFIG(PeriphClkInit->RTCClockSelection);
190 }
191 else
192 {
193 /* set overall return value */
194 status = ret;
195 }
196 }
197 else
198 {
199 /* set overall return value */
200 status = ret;
201 }
202
203 /* Restore clock configuration if changed */
204 if (pwrclkchanged == SET)
205 {
206 __HAL_RCC_PWR_CLK_DISABLE();
207 }
208 }
209
210 /*-------------------------- USART1 clock source configuration -------------------*/
211 if (((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_USART1) == RCC_PERIPHCLK_USART1)
212 {
213 /* Check the parameters */
214 assert_param(IS_RCC_USART1CLKSOURCE(PeriphClkInit->Usart1ClockSelection));
215
216 /* Configure the USART1 clock source */
217 __HAL_RCC_USART1_CONFIG(PeriphClkInit->Usart1ClockSelection);
218 }
219
220 #if defined(RCC_CCIPR_USART2SEL)
221 /*-------------------------- USART2 clock source configuration -------------------*/
222 if (((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_USART2) == RCC_PERIPHCLK_USART2)
223 {
224 /* Check the parameters */
225 assert_param(IS_RCC_USART2CLKSOURCE(PeriphClkInit->Usart2ClockSelection));
226
227 /* Configure the USART2 clock source */
228 __HAL_RCC_USART2_CONFIG(PeriphClkInit->Usart2ClockSelection);
229 }
230 #endif /* RCC_CCIPR_USART2SEL */
231
232 #if defined(RCC_CCIPR_USART3SEL)
233 /*-------------------------- USART3 clock source configuration -------------------*/
234 if (((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_USART3) == RCC_PERIPHCLK_USART3)
235 {
236 /* Check the parameters */
237 assert_param(IS_RCC_USART3CLKSOURCE(PeriphClkInit->Usart3ClockSelection));
238
239 /* Configure the USART3 clock source */
240 __HAL_RCC_USART3_CONFIG(PeriphClkInit->Usart3ClockSelection);
241 }
242 #endif /* RCC_CCIPR_USART3SEL */
243
244 #if defined(LPUART1)
245 /*-------------------------- LPUART1 clock source configuration ------------------*/
246 if (((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_LPUART1) == RCC_PERIPHCLK_LPUART1)
247 {
248 /* Check the parameters */
249 assert_param(IS_RCC_LPUART1CLKSOURCE(PeriphClkInit->Lpuart1ClockSelection));
250
251 /* Configure the LPUART1 clock source */
252 __HAL_RCC_LPUART1_CONFIG(PeriphClkInit->Lpuart1ClockSelection);
253 }
254 #endif /* LPUART1 */
255
256 #if defined(LPUART2)
257 /*-------------------------- LPUART2 clock source configuration ------------------*/
258 if (((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_LPUART2) == RCC_PERIPHCLK_LPUART2)
259 {
260 /* Check the parameters */
261 assert_param(IS_RCC_LPUART2CLKSOURCE(PeriphClkInit->Lpuart2ClockSelection));
262
263 /* Configure the LPUART clock source */
264 __HAL_RCC_LPUART2_CONFIG(PeriphClkInit->Lpuart2ClockSelection);
265 }
266 #endif /* LPUART2 */
267
268 #if defined(RCC_CCIPR_LPTIM1SEL)
269 /*-------------------------- LPTIM1 clock source configuration -------------------*/
270 if (((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_LPTIM1) == (RCC_PERIPHCLK_LPTIM1))
271 {
272 assert_param(IS_RCC_LPTIM1CLKSOURCE(PeriphClkInit->Lptim1ClockSelection));
273 __HAL_RCC_LPTIM1_CONFIG(PeriphClkInit->Lptim1ClockSelection);
274 }
275 #endif /* RCC_CCIPR_LPTIM1SEL */
276
277 #if defined(RCC_CCIPR_LPTIM2SEL)
278 /*-------------------------- LPTIM2 clock source configuration -------------------*/
279 if (((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_LPTIM2) == (RCC_PERIPHCLK_LPTIM2))
280 {
281 assert_param(IS_RCC_LPTIM2CLKSOURCE(PeriphClkInit->Lptim2ClockSelection));
282 __HAL_RCC_LPTIM2_CONFIG(PeriphClkInit->Lptim2ClockSelection);
283 }
284 #endif /* RCC_CCIPR_LPTIM2SEL */
285
286 /*-------------------------- I2C1 clock source configuration ---------------------*/
287 if (((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_I2C1) == RCC_PERIPHCLK_I2C1)
288 {
289 /* Check the parameters */
290 assert_param(IS_RCC_I2C1CLKSOURCE(PeriphClkInit->I2c1ClockSelection));
291
292 /* Configure the I2C1 clock source */
293 __HAL_RCC_I2C1_CONFIG(PeriphClkInit->I2c1ClockSelection);
294 }
295
296 #if defined(RCC_CCIPR_I2C2SEL)
297 /*-------------------------- I2C2 clock source configuration ---------------------*/
298 if (((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_I2C2) == RCC_PERIPHCLK_I2C2)
299 {
300 /* Check the parameters */
301 assert_param(IS_RCC_I2C2CLKSOURCE(PeriphClkInit->I2c2ClockSelection));
302
303 /* Configure the I2C2 clock source */
304 __HAL_RCC_I2C2_CONFIG(PeriphClkInit->I2c2ClockSelection);
305 }
306 #endif /* (RCC_CCIPR_I2C2SEL */
307
308 #if defined(RNG)
309 /*-------------------------- RNG clock source configuration ----------------------*/
310 if (((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_RNG) == (RCC_PERIPHCLK_RNG))
311 {
312 assert_param(IS_RCC_RNGCLKSOURCE(PeriphClkInit->RngClockSelection));
313 __HAL_RCC_RNG_CONFIG(PeriphClkInit->RngClockSelection);
314
315 if (PeriphClkInit->RngClockSelection == RCC_RNGCLKSOURCE_PLL)
316 {
317 /* Enable PLLQCLK output */
318 __HAL_RCC_PLLCLKOUT_ENABLE(RCC_PLLQCLK);
319 }
320 }
321 #endif /* RNG */
322 /*-------------------------- ADC clock source configuration ----------------------*/
323 if (((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_ADC) == RCC_PERIPHCLK_ADC)
324 {
325 /* Check the parameters */
326 assert_param(IS_RCC_ADCCLKSOURCE(PeriphClkInit->AdcClockSelection));
327
328 /* Configure the ADC interface clock source */
329 __HAL_RCC_ADC_CONFIG(PeriphClkInit->AdcClockSelection);
330
331 if (PeriphClkInit->AdcClockSelection == RCC_ADCCLKSOURCE_PLLADC)
332 {
333 /* Enable PLLPCLK output */
334 __HAL_RCC_PLLCLKOUT_ENABLE(RCC_PLLPCLK);
335 }
336 }
337
338 #if defined(CEC)
339 /*-------------------------- CEC clock source configuration ---------------------*/
340 if (((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_CEC) == RCC_PERIPHCLK_CEC)
341 {
342 /* Check the parameters */
343 assert_param(IS_RCC_CECCLKSOURCE(PeriphClkInit->CecClockSelection));
344
345 /* Configure the CEC clock source */
346 __HAL_RCC_CEC_CONFIG(PeriphClkInit->CecClockSelection);
347 }
348 #endif /* CEC */
349
350 #if defined(RCC_CCIPR_TIM1SEL)
351 /*-------------------------- TIM1 clock source configuration ---------------------*/
352 if (((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_TIM1) == RCC_PERIPHCLK_TIM1)
353 {
354 /* Check the parameters */
355 assert_param(IS_RCC_TIM1CLKSOURCE(PeriphClkInit->Tim1ClockSelection));
356
357 /* Configure the TIM1 clock source */
358 __HAL_RCC_TIM1_CONFIG(PeriphClkInit->Tim1ClockSelection);
359
360 if (PeriphClkInit->Tim1ClockSelection == RCC_TIM1CLKSOURCE_PLL)
361 {
362 /* Enable PLLQCLK output */
363 __HAL_RCC_PLLCLKOUT_ENABLE(RCC_PLLQCLK);
364 }
365 }
366 #endif /* RCC_CCIPR_TIM1SEL */
367
368 #if defined(RCC_CCIPR_TIM15SEL)
369 /*-------------------------- TIM15 clock source configuration ---------------------*/
370 if (((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_TIM15) == RCC_PERIPHCLK_TIM15)
371 {
372 /* Check the parameters */
373 assert_param(IS_RCC_TIM15CLKSOURCE(PeriphClkInit->Tim15ClockSelection));
374
375 /* Configure the TIM15 clock source */
376 __HAL_RCC_TIM15_CONFIG(PeriphClkInit->Tim15ClockSelection);
377
378 if (PeriphClkInit->Tim15ClockSelection == RCC_TIM15CLKSOURCE_PLL)
379 {
380 /* Enable PLLQCLK output */
381 __HAL_RCC_PLLCLKOUT_ENABLE(RCC_PLLQCLK);
382 }
383 }
384 #endif /* RCC_CCIPR_TIM15SEL */
385
386 /*-------------------------- I2S1 clock source configuration ---------------------*/
387 if (((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_I2S1) == RCC_PERIPHCLK_I2S1)
388 {
389 /* Check the parameters */
390 assert_param(IS_RCC_I2S1CLKSOURCE(PeriphClkInit->I2s1ClockSelection));
391
392 /* Configure the I2S1 clock source */
393 __HAL_RCC_I2S1_CONFIG(PeriphClkInit->I2s1ClockSelection);
394
395 if (PeriphClkInit->I2s1ClockSelection == RCC_I2S1CLKSOURCE_PLL)
396 {
397 /* Enable PLLPCLK output */
398 __HAL_RCC_PLLCLKOUT_ENABLE(RCC_PLLPCLK);
399 }
400 }
401
402 #if defined(RCC_CCIPR2_I2S2SEL)
403 /*-------------------------- I2S2 clock source configuration ---------------------*/
404 if (((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_I2S2) == RCC_PERIPHCLK_I2S2)
405 {
406 /* Check the parameters */
407 assert_param(IS_RCC_I2S2CLKSOURCE(PeriphClkInit->I2s2ClockSelection));
408
409 /* Configure the I2S2 clock source */
410 __HAL_RCC_I2S2_CONFIG(PeriphClkInit->I2s2ClockSelection);
411
412 if (PeriphClkInit->I2s2ClockSelection == RCC_I2S2CLKSOURCE_PLL)
413 {
414 /* Enable PLLPCLK output */
415 __HAL_RCC_PLLCLKOUT_ENABLE(RCC_PLLPCLK);
416 }
417 }
418 #endif /* RCC_CCIPR2_I2S2SEL */
419
420 #if defined(STM32G0C1xx) || defined(STM32G0B1xx) || defined(STM32G0B0xx)
421 /*-------------------------- USB clock source configuration ---------------------*/
422 if (((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_USB) == RCC_PERIPHCLK_USB)
423 {
424 /* Check the parameters */
425 assert_param(IS_RCC_USBCLKSOURCE(PeriphClkInit->UsbClockSelection));
426
427 /* Configure the USB clock source */
428 __HAL_RCC_USB_CONFIG(PeriphClkInit->UsbClockSelection);
429
430 if (PeriphClkInit->UsbClockSelection == RCC_USBCLKSOURCE_PLL)
431 {
432 /* Enable PLLQCLK output */
433 __HAL_RCC_PLLCLKOUT_ENABLE(RCC_PLLQCLK);
434 }
435 }
436 #endif /* STM32G0C1xx || STM32G0B1xx || STM32G0B0xx */
437
438 #if defined(FDCAN1) || defined(FDCAN2)
439 /*-------------------------- FDCAN clock source configuration ---------------------*/
440 if (((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_FDCAN) == RCC_PERIPHCLK_FDCAN)
441 {
442 /* Check the parameters */
443 assert_param(IS_RCC_FDCANCLKSOURCE(PeriphClkInit->FdcanClockSelection));
444
445 /* Configure the FDCAN clock source */
446 __HAL_RCC_FDCAN_CONFIG(PeriphClkInit->FdcanClockSelection);
447
448 if (PeriphClkInit->FdcanClockSelection == RCC_FDCANCLKSOURCE_PLL)
449 {
450 /* Enable PLLQCLK output */
451 __HAL_RCC_PLLCLKOUT_ENABLE(RCC_PLLQCLK);
452 }
453 }
454 #endif /* FDCAN1 || FDCAN2 */
455
456 return status;
457 }
458
459 /**
460 * @brief Get the RCC_ClkInitStruct according to the internal RCC configuration registers.
461 * @param PeriphClkInit pointer to an RCC_PeriphCLKInitTypeDef structure that
462 * returns the configuration information for the Extended Peripherals
463 * clocks: I2C1, I2S1, USART1, RTC, ADC,
464 * LPTIM1 (1), LPTIM2 (1), TIM1 (2), TIM15 (1)(2), USART2 (2), LPUART1 (1), CEC (1) and RNG (1)
465 * @note (1) Peripheral is not available on all devices
466 * @note (2) Peripheral clock selection is not available on all devices
467 * @retval None
468 */
HAL_RCCEx_GetPeriphCLKConfig(RCC_PeriphCLKInitTypeDef * PeriphClkInit)469 void HAL_RCCEx_GetPeriphCLKConfig(RCC_PeriphCLKInitTypeDef *PeriphClkInit)
470 {
471 /* Set all possible values for the extended clock type parameter------------*/
472 PeriphClkInit->PeriphClockSelection = RCC_PERIPHCLK_USART1 | RCC_PERIPHCLK_I2C1 | RCC_PERIPHCLK_I2S1 | \
473 RCC_PERIPHCLK_ADC | RCC_PERIPHCLK_RTC ;
474
475 #if defined(RCC_CCIPR_LPTIM1SEL) && defined(RCC_CCIPR_LPTIM2SEL)
476 PeriphClkInit->PeriphClockSelection |= RCC_PERIPHCLK_LPTIM2 | RCC_PERIPHCLK_LPTIM1;
477 #endif /* RCC_CCIPR_LPTIM1SEL && RCC_CCIPR_LPTIM2SEL */
478 #if defined(RCC_CCIPR_RNGSEL)
479 PeriphClkInit->PeriphClockSelection |= RCC_PERIPHCLK_RNG;
480 #endif /* RCC_CCIPR_RNGSEL */
481 #if defined(RCC_CCIPR_LPUART1SEL)
482 PeriphClkInit->PeriphClockSelection |= RCC_PERIPHCLK_LPUART1;
483 #endif /* RCC_CCIPR_LPUART1SEL */
484 #if defined(RCC_CCIPR_LPUART2SEL)
485 PeriphClkInit->PeriphClockSelection |= RCC_PERIPHCLK_LPUART2;
486 #endif /* RCC_CCIPR_LPUART2SEL */
487 #if defined(RCC_CCIPR_CECSEL)
488 PeriphClkInit->PeriphClockSelection |= RCC_PERIPHCLK_CEC;
489 #endif /* RCC_CCIPR_CECSEL */
490 #if defined(RCC_CCIPR_TIM1SEL)
491 PeriphClkInit->PeriphClockSelection |= RCC_PERIPHCLK_TIM1;
492 #endif /* RCC_CCIPR_TIM1SEL */
493 #if defined(RCC_CCIPR_TIM15SEL)
494 PeriphClkInit->PeriphClockSelection |= RCC_PERIPHCLK_TIM15;
495 #endif /* RCC_CCIPR_TIM15SEL */
496 #if defined(RCC_CCIPR_USART2SEL)
497 PeriphClkInit->PeriphClockSelection |= RCC_PERIPHCLK_USART2;
498 #endif /* RCC_CCIPR_USART2SEL */
499 #if defined(RCC_CCIPR_USART3SEL)
500 PeriphClkInit->PeriphClockSelection |= RCC_PERIPHCLK_USART3;
501 #endif /* RCC_CCIPR_USART3SEL */
502 #if defined(RCC_CCIPR_I2C2SEL)
503 PeriphClkInit->PeriphClockSelection |= RCC_PERIPHCLK_I2C2;
504 #endif /* RCC_CCIPR_I2C2SEL */
505 #if defined(RCC_CCIPR2_I2S2SEL)
506 PeriphClkInit->PeriphClockSelection |= RCC_PERIPHCLK_I2S2;
507 #endif /* RCC_CCIPR2_I2S2SEL */
508 #if defined(RCC_CCIPR2_USBSEL)
509 PeriphClkInit->PeriphClockSelection |= RCC_PERIPHCLK_USB;
510 #endif /* RCC_CCIPR2_USBSEL */
511 #if defined(RCC_CCIPR2_FDCANSEL)
512 PeriphClkInit->PeriphClockSelection |= RCC_PERIPHCLK_FDCAN;
513 #endif /* RCC_CCIPR_FDCANSEL */
514 /* Get the USART1 clock source ---------------------------------------------*/
515 PeriphClkInit->Usart1ClockSelection = __HAL_RCC_GET_USART1_SOURCE();
516 #if defined(RCC_CCIPR_USART2SEL)
517 /* Get the USART2 clock source ---------------------------------------------*/
518 PeriphClkInit->Usart2ClockSelection = __HAL_RCC_GET_USART2_SOURCE();
519 #endif /* RCC_CCIPR_USART2SEL */
520 #if defined(RCC_CCIPR_USART3SEL)
521 /* Get the USART3 clock source ---------------------------------------------*/
522 PeriphClkInit->Usart3ClockSelection = __HAL_RCC_GET_USART3_SOURCE();
523 #endif /* RCC_CCIPR_USART3SEL */
524 #if defined(RCC_CCIPR_LPUART1SEL)
525 /* Get the LPUART1 clock source --------------------------------------------*/
526 PeriphClkInit->Lpuart1ClockSelection = __HAL_RCC_GET_LPUART1_SOURCE();
527 #endif /* RCC_CCIPR_LPUART1SEL */
528 #if defined(RCC_CCIPR_LPUART2SEL)
529 /* Get the LPUART2 clock source --------------------------------------------*/
530 PeriphClkInit->Lpuart2ClockSelection = __HAL_RCC_GET_LPUART2_SOURCE();
531 #endif /* RCC_CCIPR_LPUART2SEL */
532 /* Get the I2C1 clock source -----------------------------------------------*/
533 PeriphClkInit->I2c1ClockSelection = __HAL_RCC_GET_I2C1_SOURCE();
534 #if defined(RCC_CCIPR_I2C2SEL)
535 /* Get the I2C2 clock source -----------------------------------------------*/
536 PeriphClkInit->I2c2ClockSelection = __HAL_RCC_GET_I2C2_SOURCE();
537 #endif /* RCC_CCIPR_I2C2SEL */
538 #if defined(RCC_CCIPR_LPTIM1SEL)
539 /* Get the LPTIM1 clock source ---------------------------------------------*/
540 PeriphClkInit->Lptim1ClockSelection = __HAL_RCC_GET_LPTIM1_SOURCE();
541 #endif /* RCC_CCIPR_LPTIM1SEL */
542 #if defined(RCC_CCIPR_LPTIM2SEL)
543 /* Get the LPTIM2 clock source ---------------------------------------------*/
544 PeriphClkInit->Lptim2ClockSelection = __HAL_RCC_GET_LPTIM2_SOURCE();
545 #endif /* RCC_CCIPR_LPTIM2SEL */
546 #if defined(RCC_CCIPR_TIM1SEL)
547 /* Get the TIM1 clock source ---------------------------------------------*/
548 PeriphClkInit->Tim1ClockSelection = __HAL_RCC_GET_TIM1_SOURCE();
549 #endif /* RCC_CCIPR_TIM1SEL */
550 #if defined(RCC_CCIPR_TIM15SEL)
551 /* Get the TIM15 clock source ---------------------------------------------*/
552 PeriphClkInit->Tim15ClockSelection = __HAL_RCC_GET_TIM15_SOURCE();
553 #endif /* RCC_CCIPR_TIM15SEL */
554 /* Get the RTC clock source ------------------------------------------------*/
555 PeriphClkInit->RTCClockSelection = __HAL_RCC_GET_RTC_SOURCE();
556 #if defined(RCC_CCIPR_RNGSEL)
557 /* Get the RNG clock source ------------------------------------------------*/
558 PeriphClkInit->RngClockSelection = __HAL_RCC_GET_RNG_SOURCE();
559 #endif /* RCC_CCIPR_RNGSEL */
560 /* Get the ADC clock source -----------------------------------------------*/
561 PeriphClkInit->AdcClockSelection = __HAL_RCC_GET_ADC_SOURCE();
562 #if defined(RCC_CCIPR_CECSEL)
563 /* Get the CEC clock source -----------------------------------------------*/
564 PeriphClkInit->CecClockSelection = __HAL_RCC_GET_CEC_SOURCE();
565 #endif /* RCC_CCIPR_CECSEL */
566 #if defined(RCC_CCIPR2_USBSEL)
567 /* Get the USB clock source -----------------------------------------------*/
568 PeriphClkInit->UsbClockSelection = __HAL_RCC_GET_USB_SOURCE();
569 #endif /* RCC_CCIPR2_USBSEL */
570 #if defined(RCC_CCIPR2_FDCANSEL)
571 /* Get the FDCAN clock source -----------------------------------------------*/
572 PeriphClkInit->FdcanClockSelection = __HAL_RCC_GET_FDCAN_SOURCE();
573 #endif /* RCC_CCIPR2_FDCANSEL */
574 /* Get the I2S1 clock source -----------------------------------------------*/
575 PeriphClkInit->I2s1ClockSelection = __HAL_RCC_GET_I2S1_SOURCE();
576 #if defined(RCC_CCIPR2_I2S2SEL)
577 /* Get the I2S2 clock source -----------------------------------------------*/
578 PeriphClkInit->I2s2ClockSelection = __HAL_RCC_GET_I2S2_SOURCE();
579 #endif /* RCC_CCIPR2_I2S2SEL */
580 }
581
582 /**
583 * @brief Return the peripheral clock frequency for peripherals with clock source from PLL
584 * @note Return 0 if peripheral clock identifier not managed by this API
585 * @param PeriphClk Peripheral clock identifier
586 * This parameter can be one of the following values:
587 * @arg @ref RCC_PERIPHCLK_RTC RTC peripheral clock
588 * @arg @ref RCC_PERIPHCLK_ADC ADC peripheral clock
589 * @arg @ref RCC_PERIPHCLK_I2C1 I2C1 peripheral clock
590 * @arg @ref RCC_PERIPHCLK_I2C2 I2C2 peripheral clock (1)
591 * @arg @ref RCC_PERIPHCLK_I2S1 I2S1 peripheral clock
592 * @arg @ref RCC_PERIPHCLK_I2S2 I2S2 peripheral clock (1)
593 * @arg @ref RCC_PERIPHCLK_USART1 USART1 peripheral clock
594 * @arg @ref RCC_PERIPHCLK_USART2 USART2 peripheral clock (1)(2)
595 * @arg @ref RCC_PERIPHCLK_USART3 USART3 peripheral clock (1)
596 * @arg @ref RCC_PERIPHCLK_RNG RNG peripheral clock (1)
597 * @arg @ref RCC_PERIPHCLK_TIM15 TIM15 peripheral clock (1)(2)
598 * @arg @ref RCC_PERIPHCLK_TIM1 TIM1 peripheral clock (1)(2)
599 * @arg @ref RCC_PERIPHCLK_LPTIM1 LPTIM1 peripheral clock (1)
600 * @arg @ref RCC_PERIPHCLK_LPTIM2 LPTIM2 peripheral clock (1)
601 * @arg @ref RCC_PERIPHCLK_LPUART1 LPUART1 peripheral clock(1)
602 * @arg @ref RCC_PERIPHCLK_LPUART2 LPUART2 peripheral clock(1)
603 * @arg @ref RCC_PERIPHCLK_CEC CEC peripheral clock (1)
604 * @arg @ref RCC_PERIPHCLK_FDCAN FDCAN peripheral clock (1)
605 * @arg @ref RCC_PERIPHCLK_USB USB peripheral clock (1)
606 * @note (1) Peripheral not available on all devices
607 * @note (2) Peripheral Clock configuration not available on all devices
608 * @retval Frequency in Hz
609 */
HAL_RCCEx_GetPeriphCLKFreq(uint32_t PeriphClk)610 uint32_t HAL_RCCEx_GetPeriphCLKFreq(uint32_t PeriphClk)
611 {
612 uint32_t frequency = 0U;
613 uint32_t srcclk;
614 uint32_t pllvco;
615 uint32_t plln;
616 #if defined(RCC_CCIPR_RNGSEL)
617 uint32_t rngclk;
618 uint32_t rngdiv;
619 #endif /* RCC_CCIPR_RNGSEL */
620 /* Check the parameters */
621 assert_param(IS_RCC_PERIPHCLOCK(PeriphClk));
622
623 if (PeriphClk == RCC_PERIPHCLK_RTC)
624 {
625 /* Get the current RTC source */
626 srcclk = __HAL_RCC_GET_RTC_SOURCE();
627
628 /* Check if LSE is ready and if RTC clock selection is LSE */
629 if ((HAL_IS_BIT_SET(RCC->BDCR, RCC_BDCR_LSERDY)) && (srcclk == RCC_RTCCLKSOURCE_LSE))
630 {
631 frequency = LSE_VALUE;
632 }
633 /* Check if LSI is ready and if RTC clock selection is LSI */
634 else if ((HAL_IS_BIT_SET(RCC->CSR, RCC_CSR_LSIRDY)) && (srcclk == RCC_RTCCLKSOURCE_LSI))
635 {
636 frequency = LSI_VALUE;
637 }
638 /* Check if HSE is ready and if RTC clock selection is HSI_DIV32*/
639 else if ((HAL_IS_BIT_SET(RCC->CR, RCC_CR_HSERDY)) && (srcclk == RCC_RTCCLKSOURCE_HSE_DIV32))
640 {
641 frequency = HSE_VALUE / 32U;
642 }
643 /* Clock not enabled for RTC*/
644 else
645 {
646 /* Nothing to do as frequency already initialized to 0U */
647 }
648 }
649 else
650 {
651 /* Other external peripheral clock source than RTC */
652
653 /* Compute PLL clock input */
654 if (__HAL_RCC_GET_PLL_OSCSOURCE() == RCC_PLLSOURCE_HSI) /* HSI ? */
655 {
656 pllvco = HSI_VALUE;
657 }
658 else if (__HAL_RCC_GET_PLL_OSCSOURCE() == RCC_PLLSOURCE_HSE) /* HSE ? */
659 {
660 pllvco = HSE_VALUE;
661 }
662 else /* No source */
663 {
664 pllvco = 0U;
665 }
666
667 /* f(PLL Source) / PLLM */
668 pllvco = (pllvco / ((READ_BIT(RCC->PLLCFGR, RCC_PLLCFGR_PLLM) >> RCC_PLLCFGR_PLLM_Pos) + 1U));
669
670 switch (PeriphClk)
671 {
672 #if defined(RCC_CCIPR_RNGSEL)
673 case RCC_PERIPHCLK_RNG:
674
675 srcclk = READ_BIT(RCC->CCIPR, RCC_CCIPR_RNGSEL);
676 if (srcclk == RCC_RNGCLKSOURCE_HSI_DIV8) /* HSI_DIV8 ? */
677 {
678 rngclk = HSI_VALUE / 8U;
679 }
680 else if (srcclk == RCC_RNGCLKSOURCE_PLL) /* PLL ? */
681 {
682 /* f(PLLQ) = f(VCO input) * PLLN / PLLQ */
683 plln = READ_BIT(RCC->PLLCFGR, RCC_PLLCFGR_PLLN) >> RCC_PLLCFGR_PLLN_Pos;
684 rngclk = (pllvco * plln) / ((READ_BIT(RCC->PLLCFGR, RCC_PLLCFGR_PLLQ) >> RCC_PLLCFGR_PLLQ_Pos) + 1U);
685 }
686 else if (srcclk == RCC_RNGCLKSOURCE_SYSCLK) /* SYSCLK ? */
687 {
688 rngclk = HAL_RCC_GetSysClockFreq();
689 }
690 else /* No clock source */
691 {
692 rngclk = 0U;
693 }
694
695 rngdiv = (1UL << ((READ_BIT(RCC->CCIPR, RCC_CCIPR_RNGDIV)) >> RCC_CCIPR_RNGDIV_Pos));
696 frequency = (rngclk / rngdiv);
697
698 break;
699 #endif /* RCC_CCIPR_RNGSEL */
700 case RCC_PERIPHCLK_USART1:
701 /* Get the current USART1 source */
702 srcclk = __HAL_RCC_GET_USART1_SOURCE();
703
704 if (srcclk == RCC_USART1CLKSOURCE_PCLK1) /* PCLK1 ? */
705 {
706 frequency = HAL_RCC_GetPCLK1Freq();
707 }
708 else if (srcclk == RCC_USART1CLKSOURCE_SYSCLK) /* SYSCLK ? */
709 {
710 frequency = HAL_RCC_GetSysClockFreq();
711 }
712 else if ((HAL_IS_BIT_SET(RCC->CR, RCC_CR_HSIRDY)) && (srcclk == RCC_USART1CLKSOURCE_HSI))
713 {
714 frequency = HSI_VALUE;
715 }
716 else if ((HAL_IS_BIT_SET(RCC->BDCR, RCC_BDCR_LSERDY)) && (srcclk == RCC_USART1CLKSOURCE_LSE))
717 {
718 frequency = LSE_VALUE;
719 }
720 /* Clock not enabled for USART1 */
721 else
722 {
723 /* Nothing to do as frequency already initialized to 0U */
724 }
725 break;
726 #if defined(RCC_CCIPR_USART2SEL)
727 case RCC_PERIPHCLK_USART2:
728 /* Get the current USART2 source */
729 srcclk = __HAL_RCC_GET_USART2_SOURCE();
730
731 if (srcclk == RCC_USART2CLKSOURCE_PCLK1)
732 {
733 frequency = HAL_RCC_GetPCLK1Freq();
734 }
735 else if (srcclk == RCC_USART2CLKSOURCE_SYSCLK)
736 {
737 frequency = HAL_RCC_GetSysClockFreq();
738 }
739 else if ((HAL_IS_BIT_SET(RCC->CR, RCC_CR_HSIRDY)) && (srcclk == RCC_USART2CLKSOURCE_HSI))
740 {
741 frequency = HSI_VALUE;
742 }
743 else if ((HAL_IS_BIT_SET(RCC->BDCR, RCC_BDCR_LSERDY)) && (srcclk == RCC_USART2CLKSOURCE_LSE))
744 {
745 frequency = LSE_VALUE;
746 }
747 /* Clock not enabled for USART2 */
748 else
749 {
750 /* Nothing to do as frequency already initialized to 0U */
751 }
752 break;
753 #endif /* RCC_CCIPR_USART2SEL */
754
755 #if defined(RCC_CCIPR_USART3SEL)
756 case RCC_PERIPHCLK_USART3:
757 /* Get the current USART3 source */
758 srcclk = __HAL_RCC_GET_USART3_SOURCE();
759
760 if (srcclk == RCC_USART3CLKSOURCE_PCLK1)
761 {
762 frequency = HAL_RCC_GetPCLK1Freq();
763 }
764 else if (srcclk == RCC_USART3CLKSOURCE_SYSCLK)
765 {
766 frequency = HAL_RCC_GetSysClockFreq();
767 }
768 else if ((HAL_IS_BIT_SET(RCC->CR, RCC_CR_HSIRDY)) && (srcclk == RCC_USART3CLKSOURCE_HSI))
769 {
770 frequency = HSI_VALUE;
771 }
772 else if ((HAL_IS_BIT_SET(RCC->BDCR, RCC_BDCR_LSERDY)) && (srcclk == RCC_USART3CLKSOURCE_LSE))
773 {
774 frequency = LSE_VALUE;
775 }
776 /* Clock not enabled for USART3 */
777 else
778 {
779 /* Nothing to do as frequency already initialized to 0U */
780 }
781 break;
782 #endif /* RCC_CCIPR_USART3SEL */
783
784 #if defined(RCC_CCIPR_CECSEL)
785 case RCC_PERIPHCLK_CEC:
786 /* Get the current CEC source */
787 srcclk = __HAL_RCC_GET_CEC_SOURCE();
788
789 if ((HAL_IS_BIT_SET(RCC->CR, RCC_CR_HSIRDY)) && (srcclk == RCC_CECCLKSOURCE_HSI_DIV488))
790 {
791 frequency = (HSI_VALUE / 488U);
792 }
793 else if ((HAL_IS_BIT_SET(RCC->BDCR, RCC_BDCR_LSERDY)) && (srcclk == RCC_CECCLKSOURCE_LSE))
794 {
795 frequency = LSE_VALUE;
796 }
797 /* Clock not enabled for CEC */
798 else
799 {
800 /* Nothing to do as frequency already initialized to 0U */
801 }
802 break;
803 #endif /* RCC_CCIPR_CECSEL */
804
805 #if defined(RCC_CCIPR_LPUART1SEL)
806 case RCC_PERIPHCLK_LPUART1:
807 /* Get the current LPUART1 source */
808 srcclk = __HAL_RCC_GET_LPUART1_SOURCE();
809
810 if (srcclk == RCC_LPUART1CLKSOURCE_PCLK1)
811 {
812 frequency = HAL_RCC_GetPCLK1Freq();
813 }
814 else if (srcclk == RCC_LPUART1CLKSOURCE_SYSCLK)
815 {
816 frequency = HAL_RCC_GetSysClockFreq();
817 }
818 else if ((HAL_IS_BIT_SET(RCC->CR, RCC_CR_HSIRDY)) && (srcclk == RCC_LPUART1CLKSOURCE_HSI))
819 {
820 frequency = HSI_VALUE;
821 }
822 else if ((HAL_IS_BIT_SET(RCC->BDCR, RCC_BDCR_LSERDY)) && (srcclk == RCC_LPUART1CLKSOURCE_LSE))
823 {
824 frequency = LSE_VALUE;
825 }
826 /* Clock not enabled for LPUART1 */
827 else
828 {
829 /* Nothing to do as frequency already initialized to 0U */
830 }
831 break;
832 #endif /* RCC_CCIPR_LPUART1SEL */
833
834 #if defined(RCC_CCIPR_LPUART2SEL)
835 case RCC_PERIPHCLK_LPUART2:
836 /* Get the current LPUART2 source */
837 srcclk = __HAL_RCC_GET_LPUART2_SOURCE();
838
839 if (srcclk == RCC_LPUART2CLKSOURCE_PCLK1)
840 {
841 frequency = HAL_RCC_GetPCLK1Freq();
842 }
843 else if (srcclk == RCC_LPUART2CLKSOURCE_SYSCLK)
844 {
845 frequency = HAL_RCC_GetSysClockFreq();
846 }
847 else if ((HAL_IS_BIT_SET(RCC->CR, RCC_CR_HSIRDY)) && (srcclk == RCC_LPUART2CLKSOURCE_HSI))
848 {
849 frequency = HSI_VALUE;
850 }
851 else if ((HAL_IS_BIT_SET(RCC->BDCR, RCC_BDCR_LSERDY)) && (srcclk == RCC_LPUART2CLKSOURCE_LSE))
852 {
853 frequency = LSE_VALUE;
854 }
855 /* Clock not enabled for LPUART2 */
856 else
857 {
858 /* Nothing to do as frequency already initialized to 0U */
859 }
860 break;
861 #endif /* RCC_CCIPR_LPUART2SEL */
862
863 case RCC_PERIPHCLK_ADC:
864
865 srcclk = __HAL_RCC_GET_ADC_SOURCE();
866
867 if (srcclk == RCC_ADCCLKSOURCE_SYSCLK)
868 {
869 frequency = HAL_RCC_GetSysClockFreq();
870 }
871 else if (srcclk == RCC_ADCCLKSOURCE_HSI)
872 {
873 frequency = HSI_VALUE;
874 }
875 else if (srcclk == RCC_ADCCLKSOURCE_PLLADC)
876 {
877 if (__HAL_RCC_GET_PLLCLKOUT_CONFIG(RCC_PLLPCLK) != 0U)
878 {
879 /* f(PLLP) = f(VCO input) * PLLN / PLLP */
880 plln = READ_BIT(RCC->PLLCFGR, RCC_PLLCFGR_PLLN) >> RCC_PLLCFGR_PLLN_Pos;
881 frequency = (pllvco * plln) / ((READ_BIT(RCC->PLLCFGR, RCC_PLLCFGR_PLLP) >> RCC_PLLCFGR_PLLP_Pos) + 1U);
882 }
883 }
884 /* Clock not enabled for ADC */
885 else
886 {
887 /* Nothing to do as frequency already initialized to 0U */
888 }
889 break;
890
891 case RCC_PERIPHCLK_I2C1:
892 /* Get the current I2C1 source */
893 srcclk = __HAL_RCC_GET_I2C1_SOURCE();
894
895 if (srcclk == RCC_I2C1CLKSOURCE_PCLK1)
896 {
897 frequency = HAL_RCC_GetPCLK1Freq();
898 }
899 else if (srcclk == RCC_I2C1CLKSOURCE_SYSCLK)
900 {
901 frequency = HAL_RCC_GetSysClockFreq();
902 }
903 else if ((HAL_IS_BIT_SET(RCC->CR, RCC_CR_HSIRDY)) && (srcclk == RCC_I2C1CLKSOURCE_HSI))
904 {
905 frequency = HSI_VALUE;
906 }
907 /* Clock not enabled for I2C1 */
908 else
909 {
910 /* Nothing to do as frequency already initialized to 0U */
911 }
912 break;
913
914 #if defined(RCC_CCIPR_I2C2SEL)
915 case RCC_PERIPHCLK_I2C2:
916 /* Get the current I2C2 source */
917 srcclk = __HAL_RCC_GET_I2C2_SOURCE();
918
919 if (srcclk == RCC_I2C2CLKSOURCE_PCLK1)
920 {
921 frequency = HAL_RCC_GetPCLK1Freq();
922 }
923 else if (srcclk == RCC_I2C2CLKSOURCE_SYSCLK)
924 {
925 frequency = HAL_RCC_GetSysClockFreq();
926 }
927 else if ((HAL_IS_BIT_SET(RCC->CR, RCC_CR_HSIRDY)) && (srcclk == RCC_I2C2CLKSOURCE_HSI))
928 {
929 frequency = HSI_VALUE;
930 }
931 /* Clock not enabled for I2C2 */
932 else
933 {
934 /* Nothing to do as frequency already initialized to 0U */
935 }
936 break;
937 #endif /* RCC_CCIPR_I2C2SEL */
938
939 case RCC_PERIPHCLK_I2S1:
940 /* Get the current I2S1 source */
941 srcclk = __HAL_RCC_GET_I2S1_SOURCE();
942
943 if (srcclk == RCC_I2S1CLKSOURCE_PLL)
944 {
945 if (__HAL_RCC_GET_PLLCLKOUT_CONFIG(RCC_PLLPCLK) != 0U)
946 {
947 /* f(PLLP) = f(VCO input) * PLLN / PLLP */
948 plln = READ_BIT(RCC->PLLCFGR, RCC_PLLCFGR_PLLN) >> RCC_PLLCFGR_PLLN_Pos;
949 frequency = (pllvco * plln) / ((READ_BIT(RCC->PLLCFGR, RCC_PLLCFGR_PLLP) >> RCC_PLLCFGR_PLLP_Pos) + 1U);
950 }
951 }
952 else if (srcclk == RCC_I2S1CLKSOURCE_SYSCLK)
953 {
954 frequency = HAL_RCC_GetSysClockFreq();
955 }
956 else if ((HAL_IS_BIT_SET(RCC->CR, RCC_CR_HSIRDY)) && (srcclk == RCC_I2S1CLKSOURCE_HSI))
957 {
958 frequency = HSI_VALUE;
959 }
960 else if (srcclk == RCC_I2S1CLKSOURCE_EXT)
961 {
962 /* External clock used.*/
963 frequency = EXTERNAL_I2S1_CLOCK_VALUE;
964 }
965 /* Clock not enabled for I2S1 */
966 else
967 {
968 /* Nothing to do as frequency already initialized to 0U */
969 }
970 break;
971
972 #if defined(RCC_CCIPR2_I2S2SEL)
973 case RCC_PERIPHCLK_I2S2:
974 /* Get the current I2S2 source */
975 srcclk = __HAL_RCC_GET_I2S2_SOURCE();
976
977 if (srcclk == RCC_I2S2CLKSOURCE_PLL)
978 {
979 if (__HAL_RCC_GET_PLLCLKOUT_CONFIG(RCC_PLLPCLK) != 0U)
980 {
981 /* f(PLLP) = f(VCO input) * PLLN / PLLP */
982 plln = READ_BIT(RCC->PLLCFGR, RCC_PLLCFGR_PLLN) >> RCC_PLLCFGR_PLLN_Pos;
983 frequency = (pllvco * plln) / ((READ_BIT(RCC->PLLCFGR, RCC_PLLCFGR_PLLP) >> RCC_PLLCFGR_PLLP_Pos) + 1U);
984 }
985 }
986 else if (srcclk == RCC_I2S2CLKSOURCE_SYSCLK)
987 {
988 frequency = HAL_RCC_GetSysClockFreq();
989 }
990 else if ((HAL_IS_BIT_SET(RCC->CR, RCC_CR_HSIRDY)) && (srcclk == RCC_I2S2CLKSOURCE_HSI))
991 {
992 frequency = HSI_VALUE;
993 }
994 else if (srcclk == RCC_I2S2CLKSOURCE_EXT)
995 {
996 /* External clock used.*/
997 frequency = EXTERNAL_I2S2_CLOCK_VALUE;
998 }
999 /* Clock not enabled for I2S2 */
1000 else
1001 {
1002 /* Nothing to do as frequency already initialized to 0U */
1003 }
1004 break;
1005 #endif /* RCC_CCIPR2_I2S2SEL */
1006
1007 #if defined(RCC_CCIPR_LPTIM1SEL)
1008 case RCC_PERIPHCLK_LPTIM1:
1009 /* Get the current LPTIM1 source */
1010 srcclk = __HAL_RCC_GET_LPTIM1_SOURCE();
1011
1012 if (srcclk == RCC_LPTIM1CLKSOURCE_PCLK1)
1013 {
1014 frequency = HAL_RCC_GetPCLK1Freq();
1015 }
1016 else if ((HAL_IS_BIT_SET(RCC->CSR, RCC_CSR_LSIRDY)) && (srcclk == RCC_LPTIM1CLKSOURCE_LSI))
1017 {
1018 frequency = LSI_VALUE;
1019 }
1020 else if ((HAL_IS_BIT_SET(RCC->CR, RCC_CR_HSIRDY)) && (srcclk == RCC_LPTIM1CLKSOURCE_HSI))
1021 {
1022 frequency = HSI_VALUE;
1023 }
1024 else if ((HAL_IS_BIT_SET(RCC->BDCR, RCC_BDCR_LSERDY)) && (srcclk == RCC_LPTIM1CLKSOURCE_LSE))
1025 {
1026 frequency = LSE_VALUE;
1027 }
1028 /* Clock not enabled for LPTIM1 */
1029 else
1030 {
1031 /* Nothing to do as frequency already initialized to 0U */
1032 }
1033 break;
1034 #endif /* RCC_CCIPR_LPTIM1SEL */
1035
1036 #if defined(RCC_CCIPR_LPTIM2SEL)
1037 case RCC_PERIPHCLK_LPTIM2:
1038 /* Get the current LPTIM2 source */
1039 srcclk = __HAL_RCC_GET_LPTIM2_SOURCE();
1040
1041 if (srcclk == RCC_LPTIM2CLKSOURCE_PCLK1)
1042 {
1043 frequency = HAL_RCC_GetPCLK1Freq();
1044 }
1045 else if ((HAL_IS_BIT_SET(RCC->CSR, RCC_CSR_LSIRDY)) && (srcclk == RCC_LPTIM2CLKSOURCE_LSI))
1046 {
1047 frequency = LSI_VALUE;
1048 }
1049 else if ((HAL_IS_BIT_SET(RCC->CR, RCC_CR_HSIRDY)) && (srcclk == RCC_LPTIM2CLKSOURCE_HSI))
1050 {
1051 frequency = HSI_VALUE;
1052 }
1053 else if ((HAL_IS_BIT_SET(RCC->BDCR, RCC_BDCR_LSERDY)) && (srcclk == RCC_LPTIM2CLKSOURCE_LSE))
1054 {
1055 frequency = LSE_VALUE;
1056 }
1057 /* Clock not enabled for LPTIM2 */
1058 else
1059 {
1060 /* Nothing to do as frequency already initialized to 0U */
1061 }
1062 break;
1063 #endif /* RCC_CCIPR_LPTIM2SEL */
1064
1065 #if defined(RCC_CCIPR_TIM1SEL)
1066 case RCC_PERIPHCLK_TIM1:
1067
1068 srcclk = READ_BIT(RCC->CCIPR, RCC_CCIPR_TIM1SEL);
1069
1070 if (srcclk == RCC_TIM1CLKSOURCE_PLL) /* PLL ? */
1071 {
1072 if (__HAL_RCC_GET_PLLCLKOUT_CONFIG(RCC_PLLQCLK) != 0U)
1073 {
1074 /* f(PLLQ) = f(VCO input) * PLLN / PLLQ */
1075 plln = READ_BIT(RCC->PLLCFGR, RCC_PLLCFGR_PLLN) >> RCC_PLLCFGR_PLLN_Pos;
1076 frequency = (pllvco * plln) / ((READ_BIT(RCC->PLLCFGR, RCC_PLLCFGR_PLLQ) >> RCC_PLLCFGR_PLLQ_Pos) + 1U);
1077 }
1078 }
1079 else if (srcclk == RCC_TIM1CLKSOURCE_PCLK1) /* PCLK1 ? */
1080 {
1081 frequency = HAL_RCC_GetPCLK1Freq();
1082 }
1083 else /* No clock source */
1084 {
1085 /* Nothing to do as frequency already initialized to 0U */
1086 }
1087 break;
1088 #endif /* RCC_CCIPR_TIM1SEL */
1089
1090 #if defined(RCC_CCIPR_TIM15SEL)
1091 case RCC_PERIPHCLK_TIM15:
1092
1093 srcclk = READ_BIT(RCC->CCIPR, RCC_CCIPR_TIM15SEL);
1094
1095 if (srcclk == RCC_TIM15CLKSOURCE_PLL) /* PLL ? */
1096 {
1097 if (__HAL_RCC_GET_PLLCLKOUT_CONFIG(RCC_PLLQCLK) != 0U)
1098 {
1099 /* f(PLLQ) = f(VCO input) * PLLN / PLLQ */
1100 plln = READ_BIT(RCC->PLLCFGR, RCC_PLLCFGR_PLLN) >> RCC_PLLCFGR_PLLN_Pos;
1101 frequency = (pllvco * plln) / ((READ_BIT(RCC->PLLCFGR, RCC_PLLCFGR_PLLQ) >> RCC_PLLCFGR_PLLQ_Pos) + 1U);
1102 }
1103 }
1104 else if (srcclk == RCC_TIM15CLKSOURCE_PCLK1) /* PCLK1 ? */
1105 {
1106 frequency = HAL_RCC_GetPCLK1Freq();
1107 }
1108 else /* No clock source */
1109 {
1110 /* Nothing to do as frequency already initialized to 0U */
1111 }
1112 break;
1113 #endif /* RCC_CCIPR_TIM15SEL */
1114
1115 #if defined(RCC_CCIPR2_USBSEL)
1116 case RCC_PERIPHCLK_USB:
1117
1118 srcclk = READ_BIT(RCC->CCIPR2, RCC_CCIPR2_USBSEL);
1119
1120 if (srcclk == RCC_USBCLKSOURCE_PLL) /* PLL ? */
1121 {
1122 if (__HAL_RCC_GET_PLLCLKOUT_CONFIG(RCC_PLLQCLK) != 0U)
1123 {
1124 /* f(PLLQ) = f(VCO input) * PLLN / PLLQ */
1125 plln = READ_BIT(RCC->PLLCFGR, RCC_PLLCFGR_PLLN) >> RCC_PLLCFGR_PLLN_Pos;
1126 frequency = (pllvco * plln) / ((READ_BIT(RCC->PLLCFGR, RCC_PLLCFGR_PLLQ) >> RCC_PLLCFGR_PLLQ_Pos) + 1U);
1127 }
1128 }
1129 #if defined(RCC_HSI48_SUPPORT)
1130 else if (srcclk == RCC_USBCLKSOURCE_HSI48) /* HSI48 ? */
1131 {
1132 if ((HAL_IS_BIT_SET(RCC->CR, RCC_CR_HSI48RDY)) && (srcclk == RCC_USBCLKSOURCE_HSI48))
1133 {
1134 frequency = HSI48_VALUE;
1135 }
1136 }
1137 #endif /* RCC_HSI48_SUPPORT */
1138 else if (srcclk == RCC_USBCLKSOURCE_HSE)
1139 {
1140 if ((HAL_IS_BIT_SET(RCC->CR, RCC_CR_HSERDY)) && (srcclk == RCC_USBCLKSOURCE_HSE))
1141 {
1142 frequency = HSE_VALUE;
1143 }
1144 }
1145 else /* No clock source */
1146 {
1147 /* Nothing to do as frequency already initialized to 0U */
1148 }
1149 break;
1150 #endif /* RCC_CCIPR2_USBSEL */
1151
1152 #if defined(RCC_CCIPR2_FDCANSEL)
1153 case RCC_PERIPHCLK_FDCAN:
1154
1155 srcclk = READ_BIT(RCC->CCIPR2, RCC_CCIPR2_FDCANSEL);
1156
1157 if (srcclk == RCC_FDCANCLKSOURCE_PLL) /* PLL ? */
1158 {
1159 if (__HAL_RCC_GET_PLLCLKOUT_CONFIG(RCC_PLLQCLK) != 0U)
1160 {
1161 /* f(PLLQ) = f(VCO input) * PLLN / PLLQ */
1162 plln = READ_BIT(RCC->PLLCFGR, RCC_PLLCFGR_PLLN) >> RCC_PLLCFGR_PLLN_Pos;
1163 frequency = (pllvco * plln) / ((READ_BIT(RCC->PLLCFGR, RCC_PLLCFGR_PLLQ) >> RCC_PLLCFGR_PLLQ_Pos) + 1U);
1164 }
1165 }
1166 else if (srcclk == RCC_FDCANCLKSOURCE_PCLK1) /* PCLK1 ? */
1167 {
1168 frequency = HAL_RCC_GetPCLK1Freq();
1169 }
1170 else if ((HAL_IS_BIT_SET(RCC->CR, RCC_CR_HSERDY)) && (srcclk == RCC_FDCANCLKSOURCE_HSE))
1171 {
1172 frequency = HSE_VALUE;
1173 }
1174 else /* No clock source */
1175 {
1176 /* Nothing to do as frequency already initialized to 0U */
1177 }
1178 break;
1179 #endif /* RCC_CCIPR2_FDCANSEL */
1180
1181 default:
1182 break;
1183 }
1184 }
1185
1186 return (frequency);
1187 }
1188
1189 /**
1190 * @}
1191 */
1192
1193 /** @defgroup RCCEx_Exported_Functions_Group2 Extended Clock management functions
1194 * @brief Extended Clock management functions
1195 *
1196 @verbatim
1197 ===============================================================================
1198 ##### Extended clock management functions #####
1199 ===============================================================================
1200 [..]
1201 This subsection provides a set of functions allowing to control the
1202 activation or deactivation of LSE CSS, Low speed clock output and
1203 clock after wake-up from STOP mode.
1204 @endverbatim
1205 * @{
1206 */
1207
1208 /**
1209 * @brief Select the Low Speed clock source to output on LSCO pin (PA2).
1210 * @param LSCOSource specifies the Low Speed clock source to output.
1211 * This parameter can be one of the following values:
1212 * @arg @ref RCC_LSCOSOURCE_LSI LSI clock selected as LSCO source
1213 * @arg @ref RCC_LSCOSOURCE_LSE LSE clock selected as LSCO source
1214 * @retval None
1215 */
HAL_RCCEx_EnableLSCO(uint32_t LSCOSource)1216 void HAL_RCCEx_EnableLSCO(uint32_t LSCOSource)
1217 {
1218 GPIO_InitTypeDef GPIO_InitStruct;
1219 FlagStatus pwrclkchanged = RESET;
1220 FlagStatus backupchanged = RESET;
1221
1222 /* Check the parameters */
1223 assert_param(IS_RCC_LSCOSOURCE(LSCOSource));
1224
1225 /* LSCO Pin Clock Enable */
1226 LSCO_CLK_ENABLE();
1227
1228 /* Configure the LSCO pin in analog mode */
1229 GPIO_InitStruct.Pin = LSCO_PIN;
1230 GPIO_InitStruct.Mode = GPIO_MODE_ANALOG;
1231 GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
1232 GPIO_InitStruct.Pull = GPIO_NOPULL;
1233 HAL_GPIO_Init(LSCO_GPIO_PORT, &GPIO_InitStruct);
1234
1235 /* Update LSCOSEL clock source in Backup Domain control register */
1236 if (__HAL_RCC_PWR_IS_CLK_DISABLED())
1237 {
1238 __HAL_RCC_PWR_CLK_ENABLE();
1239 pwrclkchanged = SET;
1240 }
1241 if (HAL_IS_BIT_CLR(PWR->CR1, PWR_CR1_DBP))
1242 {
1243 HAL_PWR_EnableBkUpAccess();
1244 backupchanged = SET;
1245 }
1246
1247 MODIFY_REG(RCC->BDCR, RCC_BDCR_LSCOSEL | RCC_BDCR_LSCOEN, LSCOSource | RCC_BDCR_LSCOEN);
1248
1249 if (backupchanged == SET)
1250 {
1251 HAL_PWR_DisableBkUpAccess();
1252 }
1253 if (pwrclkchanged == SET)
1254 {
1255 __HAL_RCC_PWR_CLK_DISABLE();
1256 }
1257 }
1258
1259 /**
1260 * @brief Disable the Low Speed clock output.
1261 * @retval None
1262 */
HAL_RCCEx_DisableLSCO(void)1263 void HAL_RCCEx_DisableLSCO(void)
1264 {
1265 FlagStatus pwrclkchanged = RESET;
1266 FlagStatus backupchanged = RESET;
1267
1268 /* Update LSCOEN bit in Backup Domain control register */
1269 if (__HAL_RCC_PWR_IS_CLK_DISABLED())
1270 {
1271 __HAL_RCC_PWR_CLK_ENABLE();
1272 pwrclkchanged = SET;
1273 }
1274 if (HAL_IS_BIT_CLR(PWR->CR1, PWR_CR1_DBP))
1275 {
1276 /* Enable access to the backup domain */
1277 HAL_PWR_EnableBkUpAccess();
1278 backupchanged = SET;
1279 }
1280
1281 CLEAR_BIT(RCC->BDCR, RCC_BDCR_LSCOEN);
1282
1283 /* Restore previous configuration */
1284 if (backupchanged == SET)
1285 {
1286 /* Disable access to the backup domain */
1287 HAL_PWR_DisableBkUpAccess();
1288 }
1289 if (pwrclkchanged == SET)
1290 {
1291 __HAL_RCC_PWR_CLK_DISABLE();
1292 }
1293 }
1294
1295 /**
1296 * @}
1297 */
1298
1299 #if defined(CRS)
1300
1301 /** @defgroup RCCEx_Exported_Functions_Group3 Extended Clock Recovery System Control functions
1302 * @brief Extended Clock Recovery System Control functions
1303 *
1304 @verbatim
1305 ===============================================================================
1306 ##### Extended Clock Recovery System Control functions #####
1307 ===============================================================================
1308 [..]
1309 For devices with Clock Recovery System feature (CRS), RCC Extension HAL driver can be used as follows:
1310
1311 (#) In System clock config, HSI48 needs to be enabled
1312
1313 (#) Enable CRS clock in IP MSP init which will use CRS functions
1314
1315 (#) Call CRS functions as follows:
1316 (##) Prepare synchronization configuration necessary for HSI48 calibration
1317 (+++) Default values can be set for frequency Error Measurement (reload and error limit)
1318 and also HSI48 oscillator smooth trimming.
1319 (+++) Macro __HAL_RCC_CRS_RELOADVALUE_CALCULATE can be also used to calculate
1320 directly reload value with target and synchronization frequencies values
1321 (##) Call function HAL_RCCEx_CRSConfig which
1322 (+++) Resets CRS registers to their default values.
1323 (+++) Configures CRS registers with synchronization configuration
1324 (+++) Enables automatic calibration and frequency error counter feature
1325 Note: When using USB LPM (Link Power Management) and the device is in Sleep mode, the
1326 periodic USB SOF will not be generated by the host. No SYNC signal will therefore be
1327 provided to the CRS to calibrate the HSI48 on the run. To guarantee the required clock
1328 precision after waking up from Sleep mode, the LSE or reference clock on the GPIOs
1329 should be used as SYNC signal.
1330
1331 (##) A polling function is provided to wait for complete synchronization
1332 (+++) Call function HAL_RCCEx_CRSWaitSynchronization()
1333 (+++) According to CRS status, user can decide to adjust again the calibration or continue
1334 application if synchronization is OK
1335
1336 (#) User can retrieve information related to synchronization in calling function
1337 HAL_RCCEx_CRSGetSynchronizationInfo()
1338
1339 (#) Regarding synchronization status and synchronization information, user can try a new calibration
1340 in changing synchronization configuration and call again HAL_RCCEx_CRSConfig.
1341 Note: When the SYNC event is detected during the downcounting phase (before reaching the zero value),
1342 it means that the actual frequency is lower than the target (and so, that the TRIM value should be
1343 incremented), while when it is detected during the upcounting phase it means that the actual frequency
1344 is higher (and that the TRIM value should be decremented).
1345
1346 (#) In interrupt mode, user can resort to the available macros (__HAL_RCC_CRS_XXX_IT). Interrupts will go
1347 through CRS Handler (CRS_IRQn/CRS_IRQHandler)
1348 (++) Call function HAL_RCCEx_CRSConfig()
1349 (++) Enable CRS_IRQn (thanks to NVIC functions)
1350 (++) Enable CRS interrupt (__HAL_RCC_CRS_ENABLE_IT)
1351 (++) Implement CRS status management in the following user callbacks called from
1352 HAL_RCCEx_CRS_IRQHandler():
1353 (+++) HAL_RCCEx_CRS_SyncOkCallback()
1354 (+++) HAL_RCCEx_CRS_SyncWarnCallback()
1355 (+++) HAL_RCCEx_CRS_ExpectedSyncCallback()
1356 (+++) HAL_RCCEx_CRS_ErrorCallback()
1357
1358 (#) To force a SYNC EVENT, user can use the function HAL_RCCEx_CRSSoftwareSynchronizationGenerate().
1359 This function can be called before calling HAL_RCCEx_CRSConfig (for instance in Systick handler)
1360
1361 @endverbatim
1362 * @{
1363 */
1364
1365 /**
1366 * @brief Start automatic synchronization for polling mode
1367 * @param pInit Pointer on RCC_CRSInitTypeDef structure
1368 * @retval None
1369 */
HAL_RCCEx_CRSConfig(RCC_CRSInitTypeDef * pInit)1370 void HAL_RCCEx_CRSConfig(RCC_CRSInitTypeDef *pInit)
1371 {
1372 uint32_t value; /* no init needed */
1373
1374 /* Check the parameters */
1375 assert_param(IS_RCC_CRS_SYNC_DIV(pInit->Prescaler));
1376 assert_param(IS_RCC_CRS_SYNC_SOURCE(pInit->Source));
1377 assert_param(IS_RCC_CRS_SYNC_POLARITY(pInit->Polarity));
1378 assert_param(IS_RCC_CRS_RELOADVALUE(pInit->ReloadValue));
1379 assert_param(IS_RCC_CRS_ERRORLIMIT(pInit->ErrorLimitValue));
1380 assert_param(IS_RCC_CRS_HSI48CALIBRATION(pInit->HSI48CalibrationValue));
1381
1382 /* CONFIGURATION */
1383
1384 /* Before configuration, reset CRS registers to their default values*/
1385 __HAL_RCC_CRS_FORCE_RESET();
1386 __HAL_RCC_CRS_RELEASE_RESET();
1387
1388 /* Set the SYNCDIV[2:0] bits according to Prescaler value */
1389 /* Set the SYNCSRC[1:0] bits according to Source value */
1390 /* Set the SYNCSPOL bit according to Polarity value */
1391 value = (pInit->Prescaler | pInit->Source | pInit->Polarity);
1392 /* Set the RELOAD[15:0] bits according to ReloadValue value */
1393 value |= pInit->ReloadValue;
1394 /* Set the FELIM[7:0] bits according to ErrorLimitValue value */
1395 value |= (pInit->ErrorLimitValue << CRS_CFGR_FELIM_Pos);
1396 WRITE_REG(CRS->CFGR, value);
1397
1398 /* Adjust HSI48 oscillator smooth trimming */
1399 /* Set the TRIM[6:0] bits according to RCC_CRS_HSI48CalibrationValue value */
1400 MODIFY_REG(CRS->CR, CRS_CR_TRIM, (pInit->HSI48CalibrationValue << CRS_CR_TRIM_Pos));
1401
1402 /* START AUTOMATIC SYNCHRONIZATION*/
1403
1404 /* Enable Automatic trimming & Frequency error counter */
1405 SET_BIT(CRS->CR, CRS_CR_AUTOTRIMEN | CRS_CR_CEN);
1406 }
1407
1408 /**
1409 * @brief Generate the software synchronization event
1410 * @retval None
1411 */
HAL_RCCEx_CRSSoftwareSynchronizationGenerate(void)1412 void HAL_RCCEx_CRSSoftwareSynchronizationGenerate(void)
1413 {
1414 SET_BIT(CRS->CR, CRS_CR_SWSYNC);
1415 }
1416
1417 /**
1418 * @brief Return synchronization info
1419 * @param pSynchroInfo Pointer on RCC_CRSSynchroInfoTypeDef structure
1420 * @retval None
1421 */
HAL_RCCEx_CRSGetSynchronizationInfo(RCC_CRSSynchroInfoTypeDef * pSynchroInfo)1422 void HAL_RCCEx_CRSGetSynchronizationInfo(RCC_CRSSynchroInfoTypeDef *pSynchroInfo)
1423 {
1424 /* Check the parameter */
1425 assert_param(pSynchroInfo != (void *)NULL);
1426
1427 /* Get the reload value */
1428 pSynchroInfo->ReloadValue = (READ_BIT(CRS->CFGR, CRS_CFGR_RELOAD));
1429
1430 /* Get HSI48 oscillator smooth trimming */
1431 pSynchroInfo->HSI48CalibrationValue = (READ_BIT(CRS->CR, CRS_CR_TRIM) >> CRS_CR_TRIM_Pos);
1432
1433 /* Get Frequency error capture */
1434 pSynchroInfo->FreqErrorCapture = (READ_BIT(CRS->ISR, CRS_ISR_FECAP) >> CRS_ISR_FECAP_Pos);
1435
1436 /* Get Frequency error direction */
1437 pSynchroInfo->FreqErrorDirection = (READ_BIT(CRS->ISR, CRS_ISR_FEDIR));
1438 }
1439
1440 /**
1441 * @brief Wait for CRS Synchronization status.
1442 * @param Timeout Duration of the timeout
1443 * @note Timeout is based on the maximum time to receive a SYNC event based on synchronization
1444 * frequency.
1445 * @note If Timeout set to HAL_MAX_DELAY, HAL_TIMEOUT will be never returned.
1446 * @retval Combination of Synchronization status
1447 * This parameter can be a combination of the following values:
1448 * @arg @ref RCC_CRS_TIMEOUT
1449 * @arg @ref RCC_CRS_SYNCOK
1450 * @arg @ref RCC_CRS_SYNCWARN
1451 * @arg @ref RCC_CRS_SYNCERR
1452 * @arg @ref RCC_CRS_SYNCMISS
1453 * @arg @ref RCC_CRS_TRIMOVF
1454 */
HAL_RCCEx_CRSWaitSynchronization(uint32_t Timeout)1455 uint32_t HAL_RCCEx_CRSWaitSynchronization(uint32_t Timeout)
1456 {
1457 uint32_t crsstatus = RCC_CRS_NONE;
1458 uint32_t tickstart;
1459
1460 /* Get timeout */
1461 tickstart = HAL_GetTick();
1462
1463 /* Wait for CRS flag or timeout detection */
1464 do
1465 {
1466 if (Timeout != HAL_MAX_DELAY)
1467 {
1468 if (((HAL_GetTick() - tickstart) > Timeout) || (Timeout == 0U))
1469 {
1470 crsstatus = RCC_CRS_TIMEOUT;
1471 }
1472 }
1473 /* Check CRS SYNCOK flag */
1474 if (__HAL_RCC_CRS_GET_FLAG(RCC_CRS_FLAG_SYNCOK))
1475 {
1476 /* CRS SYNC event OK */
1477 crsstatus |= RCC_CRS_SYNCOK;
1478
1479 /* Clear CRS SYNC event OK bit */
1480 __HAL_RCC_CRS_CLEAR_FLAG(RCC_CRS_FLAG_SYNCOK);
1481 }
1482
1483 /* Check CRS SYNCWARN flag */
1484 if (__HAL_RCC_CRS_GET_FLAG(RCC_CRS_FLAG_SYNCWARN))
1485 {
1486 /* CRS SYNC warning */
1487 crsstatus |= RCC_CRS_SYNCWARN;
1488
1489 /* Clear CRS SYNCWARN bit */
1490 __HAL_RCC_CRS_CLEAR_FLAG(RCC_CRS_FLAG_SYNCWARN);
1491 }
1492
1493 /* Check CRS TRIM overflow flag */
1494 if (__HAL_RCC_CRS_GET_FLAG(RCC_CRS_FLAG_TRIMOVF))
1495 {
1496 /* CRS SYNC Error */
1497 crsstatus |= RCC_CRS_TRIMOVF;
1498
1499 /* Clear CRS Error bit */
1500 __HAL_RCC_CRS_CLEAR_FLAG(RCC_CRS_FLAG_TRIMOVF);
1501 }
1502
1503 /* Check CRS Error flag */
1504 if (__HAL_RCC_CRS_GET_FLAG(RCC_CRS_FLAG_SYNCERR))
1505 {
1506 /* CRS SYNC Error */
1507 crsstatus |= RCC_CRS_SYNCERR;
1508
1509 /* Clear CRS Error bit */
1510 __HAL_RCC_CRS_CLEAR_FLAG(RCC_CRS_FLAG_SYNCERR);
1511 }
1512
1513 /* Check CRS SYNC Missed flag */
1514 if (__HAL_RCC_CRS_GET_FLAG(RCC_CRS_FLAG_SYNCMISS))
1515 {
1516 /* CRS SYNC Missed */
1517 crsstatus |= RCC_CRS_SYNCMISS;
1518
1519 /* Clear CRS SYNC Missed bit */
1520 __HAL_RCC_CRS_CLEAR_FLAG(RCC_CRS_FLAG_SYNCMISS);
1521 }
1522
1523 /* Check CRS Expected SYNC flag */
1524 if (__HAL_RCC_CRS_GET_FLAG(RCC_CRS_FLAG_ESYNC))
1525 {
1526 /* frequency error counter reached a zero value */
1527 __HAL_RCC_CRS_CLEAR_FLAG(RCC_CRS_FLAG_ESYNC);
1528 }
1529 } while (RCC_CRS_NONE == crsstatus);
1530
1531 return crsstatus;
1532 }
1533
1534 /**
1535 * @brief Handle the Clock Recovery System interrupt request.
1536 * @retval None
1537 */
HAL_RCCEx_CRS_IRQHandler(void)1538 void HAL_RCCEx_CRS_IRQHandler(void)
1539 {
1540 uint32_t crserror = RCC_CRS_NONE;
1541 /* Get current IT flags and IT sources values */
1542 uint32_t itflags = READ_REG(CRS->ISR);
1543 uint32_t itsources = READ_REG(CRS->CR);
1544
1545 /* Check CRS SYNCOK flag */
1546 if (((itflags & RCC_CRS_FLAG_SYNCOK) != 0U) && ((itsources & RCC_CRS_IT_SYNCOK) != 0U))
1547 {
1548 /* Clear CRS SYNC event OK flag */
1549 WRITE_REG(CRS->ICR, CRS_ICR_SYNCOKC);
1550
1551 /* user callback */
1552 HAL_RCCEx_CRS_SyncOkCallback();
1553 }
1554 /* Check CRS SYNCWARN flag */
1555 else if (((itflags & RCC_CRS_FLAG_SYNCWARN) != 0U) && ((itsources & RCC_CRS_IT_SYNCWARN) != 0U))
1556 {
1557 /* Clear CRS SYNCWARN flag */
1558 WRITE_REG(CRS->ICR, CRS_ICR_SYNCWARNC);
1559
1560 /* user callback */
1561 HAL_RCCEx_CRS_SyncWarnCallback();
1562 }
1563 /* Check CRS Expected SYNC flag */
1564 else if (((itflags & RCC_CRS_FLAG_ESYNC) != 0U) && ((itsources & RCC_CRS_IT_ESYNC) != 0U))
1565 {
1566 /* frequency error counter reached a zero value */
1567 WRITE_REG(CRS->ICR, CRS_ICR_ESYNCC);
1568
1569 /* user callback */
1570 HAL_RCCEx_CRS_ExpectedSyncCallback();
1571 }
1572 /* Check CRS Error flags */
1573 else
1574 {
1575 if (((itflags & RCC_CRS_FLAG_ERR) != 0U) && ((itsources & RCC_CRS_IT_ERR) != 0U))
1576 {
1577 if ((itflags & RCC_CRS_FLAG_SYNCERR) != 0U)
1578 {
1579 crserror |= RCC_CRS_SYNCERR;
1580 }
1581 if ((itflags & RCC_CRS_FLAG_SYNCMISS) != 0U)
1582 {
1583 crserror |= RCC_CRS_SYNCMISS;
1584 }
1585 if ((itflags & RCC_CRS_FLAG_TRIMOVF) != 0U)
1586 {
1587 crserror |= RCC_CRS_TRIMOVF;
1588 }
1589
1590 /* Clear CRS Error flags */
1591 WRITE_REG(CRS->ICR, CRS_ICR_ERRC);
1592
1593 /* user error callback */
1594 HAL_RCCEx_CRS_ErrorCallback(crserror);
1595 }
1596 }
1597 }
1598
1599 /**
1600 * @brief RCCEx Clock Recovery System SYNCOK interrupt callback.
1601 * @retval none
1602 */
HAL_RCCEx_CRS_SyncOkCallback(void)1603 __weak void HAL_RCCEx_CRS_SyncOkCallback(void)
1604 {
1605 /* NOTE : This function should not be modified, when the callback is needed,
1606 the @ref HAL_RCCEx_CRS_SyncOkCallback should be implemented in the user file
1607 */
1608 }
1609
1610 /**
1611 * @brief RCCEx Clock Recovery System SYNCWARN interrupt callback.
1612 * @retval none
1613 */
HAL_RCCEx_CRS_SyncWarnCallback(void)1614 __weak void HAL_RCCEx_CRS_SyncWarnCallback(void)
1615 {
1616 /* NOTE : This function should not be modified, when the callback is needed,
1617 the @ref HAL_RCCEx_CRS_SyncWarnCallback should be implemented in the user file
1618 */
1619 }
1620
1621 /**
1622 * @brief RCCEx Clock Recovery System Expected SYNC interrupt callback.
1623 * @retval none
1624 */
HAL_RCCEx_CRS_ExpectedSyncCallback(void)1625 __weak void HAL_RCCEx_CRS_ExpectedSyncCallback(void)
1626 {
1627 /* NOTE : This function should not be modified, when the callback is needed,
1628 the @ref HAL_RCCEx_CRS_ExpectedSyncCallback should be implemented in the user file
1629 */
1630 }
1631
1632 /**
1633 * @brief RCCEx Clock Recovery System Error interrupt callback.
1634 * @param Error Combination of Error status.
1635 * This parameter can be a combination of the following values:
1636 * @arg @ref RCC_CRS_SYNCERR
1637 * @arg @ref RCC_CRS_SYNCMISS
1638 * @arg @ref RCC_CRS_TRIMOVF
1639 * @retval none
1640 */
HAL_RCCEx_CRS_ErrorCallback(uint32_t Error)1641 __weak void HAL_RCCEx_CRS_ErrorCallback(uint32_t Error)
1642 {
1643 /* Prevent unused argument(s) compilation warning */
1644 UNUSED(Error);
1645
1646 /* NOTE : This function should not be modified, when the callback is needed,
1647 the @ref HAL_RCCEx_CRS_ErrorCallback should be implemented in the user file
1648 */
1649 }
1650
1651 /**
1652 * @}
1653 */
1654
1655 #endif /* CRS */
1656
1657 /**
1658 * @}
1659 */
1660
1661
1662 /**
1663 * @}
1664 */
1665
1666 /**
1667 * @}
1668 */
1669
1670 #endif /* HAL_RCC_MODULE_ENABLED */
1671 /**
1672 * @}
1673 */
1674
1675 /**
1676 * @}
1677 */
1678
1679