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