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