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>&copy; 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