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