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