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