1 /**
2   ******************************************************************************
3   * @file    stm32g4xx_hal_rcc.c
4   * @author  MCD Application Team
5   * @brief   RCC HAL module driver.
6   *          This file provides firmware functions to manage the following
7   *          functionalities of the Reset and Clock Control (RCC) peripheral:
8   *           + Initialization and de-initialization functions
9   *           + Peripheral Control functions
10   *
11   @verbatim
12   ==============================================================================
13                       ##### RCC specific features #####
14   ==============================================================================
15     [..]
16       After reset the device is running from High Speed Internal oscillator
17       (16 MHz) with Flash 0 wait state. Flash prefetch buffer, D-Cache
18       and I-Cache are disabled, and all peripherals are off except internal
19       SRAM, Flash and JTAG.
20 
21       (+) There is no prescaler on High speed (AHBs) and Low speed (APBs) buses:
22           all peripherals mapped on these buses are running at HSI speed.
23       (+) The clock for all peripherals is switched off, except the SRAM and FLASH.
24       (+) All GPIOs are in analog mode, except the JTAG pins which
25           are assigned to be used for debug purpose.
26 
27     [..]
28       Once the device started from reset, the user application has to:
29       (+) Configure the clock source to be used to drive the System clock
30           (if the application needs higher frequency/performance)
31       (+) Configure the System clock frequency and Flash settings
32       (+) Configure the AHB and APB buses prescalers
33       (+) Enable the clock for the peripheral(s) to be used
34       (+) Configure the clock source(s) for peripherals which clocks are not
35           derived from the System clock (USB, RNG, USART, LPUART, FDCAN, some TIMERs,
36           UCPD, I2S, I2C, LPTIM, ADC, QSPI)
37 
38   @endverbatim
39   ******************************************************************************
40   * @attention
41   *
42   * Copyright (c) 2019 STMicroelectronics.
43   * All rights reserved.
44   *
45   * This software is licensed under terms that can be found in the LICENSE file in
46   * the root directory of this software component.
47   * If no LICENSE file comes with this software, it is provided AS-IS.
48   ******************************************************************************
49   */
50 
51 /* Includes ------------------------------------------------------------------*/
52 #include "stm32g4xx_hal.h"
53 
54 /** @addtogroup STM32G4xx_HAL_Driver
55   * @{
56   */
57 
58 /** @defgroup RCC RCC
59   * @brief RCC HAL module driver
60   * @{
61   */
62 
63 #ifdef HAL_RCC_MODULE_ENABLED
64 
65 /* Private typedef -----------------------------------------------------------*/
66 /* Private define ------------------------------------------------------------*/
67 /** @defgroup RCC_Private_Constants RCC Private Constants
68  * @{
69  */
70 #define HSE_TIMEOUT_VALUE          HSE_STARTUP_TIMEOUT
71 #define HSI_TIMEOUT_VALUE          2U                /* 2 ms (minimum Tick + 1) */
72 #define LSI_TIMEOUT_VALUE          2U                /* 2 ms (minimum Tick + 1) */
73 #define HSI48_TIMEOUT_VALUE        2U                /* 2 ms (minimum Tick + 1) */
74 #define PLL_TIMEOUT_VALUE          2U                /* 2 ms (minimum Tick + 1) */
75 #define CLOCKSWITCH_TIMEOUT_VALUE  5000U             /* 5 s    */
76 /**
77   * @}
78   */
79 
80 /* Private macro -------------------------------------------------------------*/
81 /** @defgroup RCC_Private_Macros RCC Private Macros
82   * @{
83   */
84 #define RCC_GET_MCO_GPIO_PIN(__RCC_MCOx__)   ((__RCC_MCOx__) & GPIO_PIN_MASK)
85 
86 #define RCC_GET_MCO_GPIO_AF(__RCC_MCOx__)    (((__RCC_MCOx__) & RCC_MCO_GPIOAF_MASK) >> RCC_MCO_GPIOAF_POS)
87 
88 #define RCC_GET_MCO_GPIO_INDEX(__RCC_MCOx__) (((__RCC_MCOx__) & RCC_MCO_GPIOPORT_MASK) >> RCC_MCO_GPIOPORT_POS)
89 
90 #define RCC_GET_MCO_GPIO_PORT(__RCC_MCOx__)  (AHB2PERIPH_BASE + ((0x00000400UL) * RCC_GET_MCO_GPIO_INDEX(__RCC_MCOx__)))
91 
92 #define RCC_PLL_OSCSOURCE_CONFIG(__HAL_RCC_PLLSOURCE__) \
93             (MODIFY_REG(RCC->PLLCFGR, RCC_PLLCFGR_PLLSRC, (__HAL_RCC_PLLSOURCE__)))
94 /**
95   * @}
96   */
97 
98 /* Private variables ---------------------------------------------------------*/
99 
100 /* Private function prototypes -----------------------------------------------*/
101 /** @defgroup RCC_Private_Functions RCC Private Functions
102   * @{
103   */
104 static uint32_t          RCC_GetSysClockFreqFromPLLSource(void);
105 /**
106   * @}
107   */
108 
109 /* Exported functions --------------------------------------------------------*/
110 
111 /** @defgroup RCC_Exported_Functions RCC Exported Functions
112   * @{
113   */
114 
115 /** @defgroup RCC_Exported_Functions_Group1 Initialization and de-initialization functions
116   *  @brief    Initialization and Configuration functions
117   *
118   @verbatim
119  ===============================================================================
120            ##### Initialization and de-initialization functions #####
121  ===============================================================================
122     [..]
123       This section provides functions allowing to configure the internal and external oscillators
124       (HSE, HSI, LSE, LSI, PLL, CSS and MCO) and the System buses clocks (SYSCLK, AHB, APB1
125        and APB2).
126 
127     [..] Internal/external clock and PLL configuration
128          (+) HSI (high-speed internal): 16 MHz factory-trimmed RC used directly or through
129              the PLL as System clock source.
130 
131          (+) LSI (low-speed internal): 32 KHz low consumption RC used as IWDG and/or RTC
132              clock source.
133 
134          (+) HSE (high-speed external): 4 to 48 MHz crystal oscillator used directly or
135              through the PLL as System clock source. Can be used also optionally as RTC clock source.
136 
137          (+) LSE (low-speed external): 32.768 KHz oscillator used optionally as RTC clock source.
138 
139          (+) PLL (clocked by HSI, HSE) providing up to three independent output clocks:
140            (++) The first output is used to generate the high speed system clock (up to 170 MHz).
141            (++) The second output is used to generate the clock for the USB (48 MHz),
142                 the QSPI (<= 48 MHz), the FDCAN, the SAI and the I2S.
143            (++) The third output is used to generate a clock for ADC
144 
145          (+) CSS (Clock security system): once enabled, if a HSE clock failure occurs
146             (HSE used directly or through PLL as System clock source), the System clock
147              is automatically switched to HSI and an interrupt is generated if enabled.
148              The interrupt is linked to the Cortex-M4 NMI (Non-Maskable Interrupt)
149              exception vector.
150 
151          (+) MCO (microcontroller clock output): used to output LSI, HSI, LSE, HSE,
152              main PLL clock, system clock or RC48 clock (through a configurable prescaler) on PA8 pin.
153 
154     [..] System, AHB and APB buses clocks configuration
155          (+) Several clock sources can be used to drive the System clock (SYSCLK): HSI,
156              HSE and main PLL.
157              The AHB clock (HCLK) is derived from System clock through configurable
158              prescaler and used to clock the CPU, memory and peripherals mapped
159              on AHB bus (DMA, GPIO...). APB1 (PCLK1) and APB2 (PCLK2) clocks are derived
160              from AHB clock through configurable prescalers and used to clock
161              the peripherals mapped on these buses. You can use
162              "HAL_RCC_GetSysClockFreq()" function to retrieve the frequencies of these clocks.
163 
164          -@- All the peripheral clocks are derived from the System clock (SYSCLK) except:
165 
166            (+@) RTC: the RTC clock can be derived either from the LSI, LSE or HSE clock
167                 divided by 2 to 31.
168                 You have to use __HAL_RCC_RTC_ENABLE() and HAL_RCCEx_PeriphCLKConfig() function
169                 to configure this clock.
170            (+@) USB FS and RNG: USB FS requires a frequency equal to 48 MHz
171                 to work correctly, while the RNG peripheral requires a frequency
172                 equal or lower than to 48 MHz. This clock is derived of the main PLL
173                 through PLLQ divider. You have to enable the peripheral clock and use
174                 HAL_RCCEx_PeriphCLKConfig() function to configure this clock.
175            (+@) IWDG clock which is always the LSI clock.
176 
177 
178          (+) The maximum frequency of the SYSCLK, HCLK, PCLK1 and PCLK2 is 170 MHz.
179              The clock source frequency should be adapted depending on the device voltage range
180              as listed in the Reference Manual "Clock source frequency versus voltage scaling" chapter.
181 
182   @endverbatim
183 
184            Table 1. HCLK clock frequency for STM32G4xx devices
185            +----------------------------------------------------------------------------+
186            | Latency         |            HCLK clock frequency (MHz)                    |
187            |                 |----------------------------------------------------------|
188            |                 |  voltage range 1  |  voltage range 1  | voltage range 2  |
189            |                 | boost mode 1.28 V | normal mode 1.2 V |     1.0 V        |
190            |-----------------|-------------------|-------------------|------------------|
191            |0WS(1 CPU cycles)|    HCLK <= 34     |    HCLK <= 30     |    HCLK <= 13    |
192            |-----------------|-------------------|-------------------|------------------|
193            |1WS(2 CPU cycles)|    HCLK <= 68     |    HCLK <= 60     |    HCLK <= 26    |
194            |-----------------|-------------------|-------------------|------------------|
195            |2WS(3 CPU cycles)|    HCLK <= 102    |    HCLK <= 90     |        -         |
196            |-----------------|-------------------|-------------------|------------------|
197            |3WS(4 CPU cycles)|    HCLK <= 136    |    HCLK <= 120    |        -         |
198            |-----------------|-------------------|-------------------|------------------|
199            |4WS(5 CPU cycles)|    HCLK <= 170    |    HCLK <= 150    |        -         |
200            +----------------------------------------------------------------------------+
201 
202   * @{
203   */
204 
205 /**
206   * @brief  Reset the RCC clock configuration to the default reset state.
207   * @note   The default reset state of the clock configuration is given below:
208   *            - HSI ON and used as system clock source
209   *            - HSE, PLL OFF
210   *            - AHB, APB1 and APB2 prescaler set to 1.
211   *            - CSS, MCO1 OFF
212   *            - All interrupts disabled
213   *            - All interrupt and reset flags cleared
214   * @note   This function doesn't modify the configuration of the
215   *            - Peripheral clocks
216   *            - LSI, LSE and RTC clocks
217   * @retval HAL status
218   */
HAL_RCC_DeInit(void)219 HAL_StatusTypeDef HAL_RCC_DeInit(void)
220 {
221   uint32_t tickstart;
222 
223   /* Get Start Tick*/
224   tickstart = HAL_GetTick();
225 
226   /* Set HSION bit to the reset value */
227   SET_BIT(RCC->CR, RCC_CR_HSION);
228 
229   /* Wait till HSI is ready */
230   while (READ_BIT(RCC->CR, RCC_CR_HSIRDY) == 0U)
231   {
232     if ((HAL_GetTick() - tickstart) > HSI_TIMEOUT_VALUE)
233     {
234       return HAL_TIMEOUT;
235     }
236   }
237 
238  /* Set HSITRIM[6:0] bits to the reset value */
239   SET_BIT(RCC->ICSCR, RCC_HSICALIBRATION_DEFAULT << RCC_ICSCR_HSITRIM_Pos);
240 
241   /* Get Start Tick*/
242   tickstart = HAL_GetTick();
243 
244   /* Reset CFGR register (HSI is selected as system clock source) */
245   RCC->CFGR = 0x00000001u;
246 
247   /* Wait till HSI is ready */
248   while (READ_BIT(RCC->CFGR, RCC_CFGR_SWS) != RCC_CFGR_SWS_HSI)
249   {
250     if ((HAL_GetTick() - tickstart) > CLOCKSWITCH_TIMEOUT_VALUE)
251     {
252       return HAL_TIMEOUT;
253     }
254   }
255 
256   /* Update the SystemCoreClock global variable */
257   SystemCoreClock = HSI_VALUE;
258 
259   /* Adapt Systick interrupt period */
260   if (HAL_InitTick(uwTickPrio) != HAL_OK)
261   {
262     return HAL_ERROR;
263   }
264 
265   /* Clear CR register in 2 steps: first to clear HSEON in case bypass was enabled */
266   RCC->CR = RCC_CR_HSION;
267 
268   /* Then again to HSEBYP in case bypass was enabled */
269   RCC->CR = RCC_CR_HSION;
270 
271   /* Get Start Tick*/
272   tickstart = HAL_GetTick();
273 
274   /* Wait till PLL is OFF */
275   while (READ_BIT(RCC->CR, RCC_CR_PLLRDY) != 0U)
276   {
277     if ((HAL_GetTick() - tickstart) > PLL_TIMEOUT_VALUE)
278     {
279       return HAL_TIMEOUT;
280     }
281   }
282 
283   /* once PLL is OFF, reset PLLCFGR register to default value */
284   RCC->PLLCFGR = RCC_PLLCFGR_PLLN_4;
285 
286   /* Disable all interrupts */
287   CLEAR_REG(RCC->CIER);
288 
289   /* Clear all interrupt flags */
290   WRITE_REG(RCC->CICR, 0xFFFFFFFFU);
291 
292   /* Clear all reset flags */
293   SET_BIT(RCC->CSR, RCC_CSR_RMVF);
294 
295   return HAL_OK;
296 }
297 
298 /**
299   * @brief  Initialize the RCC Oscillators according to the specified parameters in the
300   *         RCC_OscInitTypeDef.
301   * @param  RCC_OscInitStruct  pointer to an RCC_OscInitTypeDef structure that
302   *         contains the configuration information for the RCC Oscillators.
303   * @note   The PLL is not disabled when used as system clock.
304   * @note   Transitions LSE Bypass to LSE On and LSE On to LSE Bypass are not
305   *         supported by this macro. User should request a transition to LSE Off
306   *         first and then LSE On or LSE Bypass.
307   * @note   Transition HSE Bypass to HSE On and HSE On to HSE Bypass are not
308   *         supported by this macro. User should request a transition to HSE Off
309   *         first and then HSE On or HSE Bypass.
310   * @retval HAL status
311   */
HAL_RCC_OscConfig(RCC_OscInitTypeDef * RCC_OscInitStruct)312 HAL_StatusTypeDef HAL_RCC_OscConfig(RCC_OscInitTypeDef  *RCC_OscInitStruct)
313 {
314   uint32_t tickstart;
315   uint32_t temp_sysclksrc;
316   uint32_t temp_pllckcfg;
317 
318   /* Check Null pointer */
319   if (RCC_OscInitStruct == NULL)
320   {
321     return HAL_ERROR;
322   }
323 
324   /* Check the parameters */
325   assert_param(IS_RCC_OSCILLATORTYPE(RCC_OscInitStruct->OscillatorType));
326 
327   /*------------------------------- HSE Configuration ------------------------*/
328   if (((RCC_OscInitStruct->OscillatorType) & RCC_OSCILLATORTYPE_HSE) == RCC_OSCILLATORTYPE_HSE)
329   {
330     /* Check the parameters */
331     assert_param(IS_RCC_HSE(RCC_OscInitStruct->HSEState));
332 
333     temp_sysclksrc = __HAL_RCC_GET_SYSCLK_SOURCE();
334     temp_pllckcfg = __HAL_RCC_GET_PLL_OSCSOURCE();
335 
336     /* When the HSE is used as system clock or clock source for PLL in these cases it is not allowed to be disabled */
337     if (((temp_sysclksrc == RCC_CFGR_SWS_PLL) && (temp_pllckcfg == RCC_PLLSOURCE_HSE)) || (temp_sysclksrc == RCC_CFGR_SWS_HSE))
338     {
339       if ((READ_BIT(RCC->CR, RCC_CR_HSERDY) != 0U) && (RCC_OscInitStruct->HSEState == RCC_HSE_OFF))
340       {
341         return HAL_ERROR;
342       }
343     }
344     else
345     {
346       /* Set the new HSE configuration ---------------------------------------*/
347       __HAL_RCC_HSE_CONFIG(RCC_OscInitStruct->HSEState);
348 
349       /* Check the HSE State */
350       if (RCC_OscInitStruct->HSEState != RCC_HSE_OFF)
351       {
352         /* Get Start Tick*/
353         tickstart = HAL_GetTick();
354 
355         /* Wait till HSE is ready */
356         while (READ_BIT(RCC->CR, RCC_CR_HSERDY) == 0U)
357         {
358           if ((HAL_GetTick() - tickstart) > HSE_TIMEOUT_VALUE)
359           {
360             return HAL_TIMEOUT;
361           }
362         }
363       }
364       else
365       {
366         /* Get Start Tick*/
367         tickstart = HAL_GetTick();
368 
369         /* Wait till HSE is disabled */
370         while (READ_BIT(RCC->CR, RCC_CR_HSERDY) != 0U)
371         {
372           if ((HAL_GetTick() - tickstart) > HSE_TIMEOUT_VALUE)
373           {
374             return HAL_TIMEOUT;
375           }
376         }
377       }
378     }
379   }
380   /*----------------------------- HSI Configuration --------------------------*/
381   if (((RCC_OscInitStruct->OscillatorType) & RCC_OSCILLATORTYPE_HSI) == RCC_OSCILLATORTYPE_HSI)
382   {
383     /* Check the parameters */
384     assert_param(IS_RCC_HSI(RCC_OscInitStruct->HSIState));
385     assert_param(IS_RCC_HSI_CALIBRATION_VALUE(RCC_OscInitStruct->HSICalibrationValue));
386 
387     /* Check if HSI is used as system clock or as PLL source when PLL is selected as system clock */
388     temp_sysclksrc = __HAL_RCC_GET_SYSCLK_SOURCE();
389     temp_pllckcfg = __HAL_RCC_GET_PLL_OSCSOURCE();
390     if (((temp_sysclksrc == RCC_CFGR_SWS_PLL) && (temp_pllckcfg == RCC_PLLSOURCE_HSI)) || (temp_sysclksrc == RCC_CFGR_SWS_HSI))
391     {
392       /* When HSI is used as system clock it will not be disabled */
393       if ((READ_BIT(RCC->CR, RCC_CR_HSIRDY) != 0U) && (RCC_OscInitStruct->HSIState == RCC_HSI_OFF))
394       {
395         return HAL_ERROR;
396       }
397       /* Otherwise, just the calibration is allowed */
398       else
399       {
400         /* Adjusts the Internal High Speed oscillator (HSI) calibration value.*/
401         __HAL_RCC_HSI_CALIBRATIONVALUE_ADJUST(RCC_OscInitStruct->HSICalibrationValue);
402 
403         /* Adapt Systick interrupt period */
404         if (HAL_InitTick(uwTickPrio) != HAL_OK)
405         {
406           return HAL_ERROR;
407         }
408       }
409     }
410     else
411     {
412       /* Check the HSI State */
413       if (RCC_OscInitStruct->HSIState != RCC_HSI_OFF)
414       {
415         /* Enable the Internal High Speed oscillator (HSI). */
416         __HAL_RCC_HSI_ENABLE();
417 
418         /* Get Start Tick*/
419         tickstart = HAL_GetTick();
420 
421         /* Wait till HSI is ready */
422         while (READ_BIT(RCC->CR, RCC_CR_HSIRDY) == 0U)
423         {
424           if ((HAL_GetTick() - tickstart) > HSI_TIMEOUT_VALUE)
425           {
426             return HAL_TIMEOUT;
427           }
428         }
429 
430         /* Adjusts the Internal High Speed oscillator (HSI) calibration value.*/
431         __HAL_RCC_HSI_CALIBRATIONVALUE_ADJUST(RCC_OscInitStruct->HSICalibrationValue);
432       }
433       else
434       {
435         /* Disable the Internal High Speed oscillator (HSI). */
436         __HAL_RCC_HSI_DISABLE();
437 
438         /* Get Start Tick*/
439         tickstart = HAL_GetTick();
440 
441         /* Wait till HSI is disabled */
442         while (READ_BIT(RCC->CR, RCC_CR_HSIRDY) != 0U)
443         {
444           if ((HAL_GetTick() - tickstart) > HSI_TIMEOUT_VALUE)
445           {
446             return HAL_TIMEOUT;
447           }
448         }
449       }
450     }
451   }
452   /*------------------------------ LSI Configuration -------------------------*/
453   if (((RCC_OscInitStruct->OscillatorType) & RCC_OSCILLATORTYPE_LSI) == RCC_OSCILLATORTYPE_LSI)
454   {
455     /* Check the parameters */
456     assert_param(IS_RCC_LSI(RCC_OscInitStruct->LSIState));
457 
458     /* Check the LSI State */
459     if(RCC_OscInitStruct->LSIState != RCC_LSI_OFF)
460     {
461       /* Enable the Internal Low Speed oscillator (LSI). */
462       __HAL_RCC_LSI_ENABLE();
463 
464       /* Get Start Tick*/
465       tickstart = HAL_GetTick();
466 
467       /* Wait till LSI is ready */
468       while (READ_BIT(RCC->CSR, RCC_CSR_LSIRDY) == 0U)
469       {
470         if ((HAL_GetTick() - tickstart) > LSI_TIMEOUT_VALUE)
471         {
472           return HAL_TIMEOUT;
473         }
474       }
475     }
476     else
477     {
478       /* Disable the Internal Low Speed oscillator (LSI). */
479       __HAL_RCC_LSI_DISABLE();
480 
481       /* Get Start Tick*/
482       tickstart = HAL_GetTick();
483 
484       /* Wait till LSI is disabled */
485       while(READ_BIT(RCC->CSR, RCC_CSR_LSIRDY) != 0U)
486       {
487         if((HAL_GetTick() - tickstart) > LSI_TIMEOUT_VALUE)
488         {
489           return HAL_TIMEOUT;
490         }
491       }
492     }
493   }
494   /*------------------------------ LSE Configuration -------------------------*/
495   if (((RCC_OscInitStruct->OscillatorType) & RCC_OSCILLATORTYPE_LSE) == RCC_OSCILLATORTYPE_LSE)
496   {
497     FlagStatus       pwrclkchanged = RESET;
498 
499     /* Check the parameters */
500     assert_param(IS_RCC_LSE(RCC_OscInitStruct->LSEState));
501 
502     /* Update LSE configuration in Backup Domain control register    */
503     /* Requires to enable write access to Backup Domain if necessary */
504     if (__HAL_RCC_PWR_IS_CLK_DISABLED() != 0U)
505     {
506       __HAL_RCC_PWR_CLK_ENABLE();
507       pwrclkchanged = SET;
508     }
509 
510     if (HAL_IS_BIT_CLR(PWR->CR1, PWR_CR1_DBP))
511     {
512       /* Enable write access to Backup domain */
513       SET_BIT(PWR->CR1, PWR_CR1_DBP);
514 
515       /* Wait for Backup domain Write protection disable */
516       tickstart = HAL_GetTick();
517 
518       while (HAL_IS_BIT_CLR(PWR->CR1, PWR_CR1_DBP))
519       {
520         if ((HAL_GetTick() - tickstart) > RCC_DBP_TIMEOUT_VALUE)
521         {
522           return HAL_TIMEOUT;
523         }
524       }
525     }
526 
527     /* Set the new LSE configuration -----------------------------------------*/
528     __HAL_RCC_LSE_CONFIG(RCC_OscInitStruct->LSEState);
529 
530     /* Check the LSE State */
531     if (RCC_OscInitStruct->LSEState != RCC_LSE_OFF)
532     {
533       /* Get Start Tick*/
534       tickstart = HAL_GetTick();
535 
536       /* Wait till LSE is ready */
537       while (READ_BIT(RCC->BDCR, RCC_BDCR_LSERDY) == 0U)
538       {
539         if((HAL_GetTick() - tickstart) > RCC_LSE_TIMEOUT_VALUE)
540         {
541           return HAL_TIMEOUT;
542         }
543       }
544     }
545     else
546     {
547       /* Get Start Tick*/
548       tickstart = HAL_GetTick();
549 
550       /* Wait till LSE is disabled */
551       while (READ_BIT(RCC->BDCR, RCC_BDCR_LSERDY) != 0U)
552       {
553         if((HAL_GetTick() - tickstart) > RCC_LSE_TIMEOUT_VALUE)
554         {
555           return HAL_TIMEOUT;
556         }
557       }
558     }
559 
560     /* Restore clock configuration if changed */
561     if (pwrclkchanged == SET)
562     {
563       __HAL_RCC_PWR_CLK_DISABLE();
564     }
565   }
566 
567   /*------------------------------ HSI48 Configuration -----------------------*/
568   if(((RCC_OscInitStruct->OscillatorType) & RCC_OSCILLATORTYPE_HSI48) == RCC_OSCILLATORTYPE_HSI48)
569   {
570     /* Check the parameters */
571     assert_param(IS_RCC_HSI48(RCC_OscInitStruct->HSI48State));
572 
573     /* Check the HSI48 State */
574     if(RCC_OscInitStruct->HSI48State != RCC_HSI48_OFF)
575     {
576       /* Enable the Internal Low Speed oscillator (HSI48). */
577       __HAL_RCC_HSI48_ENABLE();
578 
579       /* Get Start Tick*/
580       tickstart = HAL_GetTick();
581 
582       /* Wait till HSI48 is ready */
583       while(READ_BIT(RCC->CRRCR, RCC_CRRCR_HSI48RDY) == 0U)
584       {
585         if((HAL_GetTick() - tickstart) > HSI48_TIMEOUT_VALUE)
586         {
587           return HAL_TIMEOUT;
588         }
589       }
590     }
591     else
592     {
593       /* Disable the Internal Low Speed oscillator (HSI48). */
594       __HAL_RCC_HSI48_DISABLE();
595 
596       /* Get Start Tick*/
597       tickstart = HAL_GetTick();
598 
599       /* Wait till HSI48 is disabled */
600       while(READ_BIT(RCC->CRRCR, RCC_CRRCR_HSI48RDY) != 0U)
601       {
602         if((HAL_GetTick() - tickstart) > HSI48_TIMEOUT_VALUE)
603         {
604           return HAL_TIMEOUT;
605         }
606       }
607     }
608   }
609 
610   /*-------------------------------- PLL Configuration -----------------------*/
611   /* Check the parameters */
612   assert_param(IS_RCC_PLL(RCC_OscInitStruct->PLL.PLLState));
613 
614   if (RCC_OscInitStruct->PLL.PLLState != RCC_PLL_NONE)
615   {
616     /* Check if the PLL is used as system clock or not */
617     if (__HAL_RCC_GET_SYSCLK_SOURCE() != RCC_CFGR_SWS_PLL)
618     {
619       if (RCC_OscInitStruct->PLL.PLLState == RCC_PLL_ON)
620       {
621         /* Check the parameters */
622         assert_param(IS_RCC_PLLSOURCE(RCC_OscInitStruct->PLL.PLLSource));
623         assert_param(IS_RCC_PLLM_VALUE(RCC_OscInitStruct->PLL.PLLM));
624         assert_param(IS_RCC_PLLN_VALUE(RCC_OscInitStruct->PLL.PLLN));
625         assert_param(IS_RCC_PLLP_VALUE(RCC_OscInitStruct->PLL.PLLP));
626         assert_param(IS_RCC_PLLQ_VALUE(RCC_OscInitStruct->PLL.PLLQ));
627         assert_param(IS_RCC_PLLR_VALUE(RCC_OscInitStruct->PLL.PLLR));
628 
629         /* Disable the main PLL. */
630         __HAL_RCC_PLL_DISABLE();
631 
632         /* Get Start Tick*/
633         tickstart = HAL_GetTick();
634 
635         /* Wait till PLL is ready */
636         while (READ_BIT(RCC->CR, RCC_CR_PLLRDY) != 0U)
637         {
638           if ((HAL_GetTick() - tickstart) > PLL_TIMEOUT_VALUE)
639           {
640             return HAL_TIMEOUT;
641           }
642         }
643 
644         /* Configure the main PLL clock source, multiplication and division factors. */
645         __HAL_RCC_PLL_CONFIG(RCC_OscInitStruct->PLL.PLLSource,
646                              RCC_OscInitStruct->PLL.PLLM,
647                              RCC_OscInitStruct->PLL.PLLN,
648                              RCC_OscInitStruct->PLL.PLLP,
649                              RCC_OscInitStruct->PLL.PLLQ,
650                              RCC_OscInitStruct->PLL.PLLR);
651 
652         /* Enable the main PLL. */
653         __HAL_RCC_PLL_ENABLE();
654 
655         /* Enable PLL System Clock output. */
656          __HAL_RCC_PLLCLKOUT_ENABLE(RCC_PLL_SYSCLK);
657 
658         /* Get Start Tick*/
659         tickstart = HAL_GetTick();
660 
661         /* Wait till PLL is ready */
662         while (READ_BIT(RCC->CR, RCC_CR_PLLRDY) == 0U)
663         {
664           if ((HAL_GetTick() - tickstart) > PLL_TIMEOUT_VALUE)
665           {
666             return HAL_TIMEOUT;
667           }
668         }
669       }
670       else
671       {
672         /* Disable the main PLL. */
673         __HAL_RCC_PLL_DISABLE();
674 
675         /* Disable all PLL outputs to save power if no PLLs on */
676           MODIFY_REG(RCC->PLLCFGR, RCC_PLLCFGR_PLLSRC, RCC_PLLSOURCE_NONE);
677         __HAL_RCC_PLLCLKOUT_DISABLE(RCC_PLL_SYSCLK | RCC_PLL_48M1CLK | RCC_PLL_ADCCLK);
678 
679         /* Get Start Tick*/
680         tickstart = HAL_GetTick();
681 
682         /* Wait till PLL is disabled */
683         while (READ_BIT(RCC->CR, RCC_CR_PLLRDY) != 0U)
684         {
685           if ((HAL_GetTick() - tickstart) > PLL_TIMEOUT_VALUE)
686           {
687             return HAL_TIMEOUT;
688           }
689         }
690       }
691     }
692     else
693     {
694       /* Check if there is a request to disable the PLL used as System clock source */
695       if((RCC_OscInitStruct->PLL.PLLState) == RCC_PLL_OFF)
696       {
697         return HAL_ERROR;
698       }
699       else
700       {
701       /* Do not return HAL_ERROR if request repeats the current configuration */
702       temp_pllckcfg = RCC->PLLCFGR;
703       if((READ_BIT(temp_pllckcfg, RCC_PLLCFGR_PLLSRC) != RCC_OscInitStruct->PLL.PLLSource) ||
704          (READ_BIT(temp_pllckcfg, RCC_PLLCFGR_PLLM) != (((RCC_OscInitStruct->PLL.PLLM) - 1U) << RCC_PLLCFGR_PLLM_Pos)) ||
705          (READ_BIT(temp_pllckcfg, RCC_PLLCFGR_PLLN) != ((RCC_OscInitStruct->PLL.PLLN) << RCC_PLLCFGR_PLLN_Pos)) ||
706          (READ_BIT(temp_pllckcfg, RCC_PLLCFGR_PLLPDIV) != ((RCC_OscInitStruct->PLL.PLLP) << RCC_PLLCFGR_PLLPDIV_Pos)) ||
707          (READ_BIT(temp_pllckcfg, RCC_PLLCFGR_PLLQ) != ((((RCC_OscInitStruct->PLL.PLLQ) >> 1U) - 1U) << RCC_PLLCFGR_PLLQ_Pos)) ||
708          (READ_BIT(temp_pllckcfg, RCC_PLLCFGR_PLLR) != ((((RCC_OscInitStruct->PLL.PLLR) >> 1U) - 1U) << RCC_PLLCFGR_PLLR_Pos)))
709       {
710         return HAL_ERROR;
711       }
712     }
713   }
714   }
715 
716   return HAL_OK;
717 }
718 
719 /**
720   * @brief  Initialize the CPU, AHB and APB buses clocks according to the specified
721   *         parameters in the RCC_ClkInitStruct.
722   * @param  RCC_ClkInitStruct  pointer to an RCC_OscInitTypeDef structure that
723   *         contains the configuration information for the RCC peripheral.
724   * @param  FLatency  FLASH Latency
725   *          This parameter can be one of the following values:
726   *            @arg FLASH_LATENCY_0   FLASH 0 Latency cycle
727   *            @arg FLASH_LATENCY_1   FLASH 1 Latency cycle
728   *            @arg FLASH_LATENCY_2   FLASH 2 Latency cycles
729   *            @arg FLASH_LATENCY_3   FLASH 3 Latency cycles
730   *            @arg FLASH_LATENCY_4   FLASH 4 Latency cycles
731   *            @arg FLASH_LATENCY_5   FLASH 5 Latency cycles
732   *            @arg FLASH_LATENCY_6   FLASH 6 Latency cycles
733   *            @arg FLASH_LATENCY_7   FLASH 7 Latency cycles
734   *            @arg FLASH_LATENCY_8   FLASH 8 Latency cycles
735   *            @arg FLASH_LATENCY_9   FLASH 9 Latency cycles
736   *            @arg FLASH_LATENCY_10  FLASH 10 Latency cycles
737   *            @arg FLASH_LATENCY_11  FLASH 11 Latency cycles
738   *            @arg FLASH_LATENCY_12  FLASH 12 Latency cycles
739   *            @arg FLASH_LATENCY_13  FLASH 13 Latency cycles
740   *            @arg FLASH_LATENCY_14  FLASH 14 Latency cycles
741   *            @arg FLASH_LATENCY_15  FLASH 15 Latency cycles
742   *
743   * @note   The SystemCoreClock CMSIS variable is used to store System Clock Frequency
744   *         and updated by HAL_RCC_GetHCLKFreq() function called within this function
745   *
746   * @note   The HSI is used by default as system clock source after
747   *         startup from Reset, wake-up from STANDBY mode. After restart from Reset,
748   *         the HSI frequency is set to its default value 16 MHz.
749   *
750   * @note   The HSI can be selected as system clock source after
751   *         from STOP modes or in case of failure of the HSE used directly or indirectly
752   *         as system clock (if the Clock Security System CSS is enabled).
753   *
754   * @note   A switch from one clock source to another occurs only if the target
755   *         clock source is ready (clock stable after startup delay or PLL locked).
756   *         If a clock source which is not yet ready is selected, the switch will
757   *         occur when the clock source is ready.
758   *
759   * @note   You can use HAL_RCC_GetClockConfig() function to know which clock is
760   *         currently used as system clock source.
761   *
762   * @note   Depending on the device voltage range, the software has to set correctly
763   *         HPRE[3:0] bits to ensure that HCLK not exceed the maximum allowed frequency
764   *         (for more details refer to section above "Initialization/de-initialization functions")
765   * @retval None
766   */
HAL_RCC_ClockConfig(RCC_ClkInitTypeDef * RCC_ClkInitStruct,uint32_t FLatency)767 HAL_StatusTypeDef HAL_RCC_ClockConfig(RCC_ClkInitTypeDef  *RCC_ClkInitStruct, uint32_t FLatency)
768 {
769   uint32_t tickstart;
770   uint32_t pllfreq;
771   uint32_t hpre = RCC_SYSCLK_DIV1;
772 
773   /* Check Null pointer */
774   if (RCC_ClkInitStruct == NULL)
775   {
776     return HAL_ERROR;
777   }
778 
779   /* Check the parameters */
780   assert_param(IS_RCC_CLOCKTYPE(RCC_ClkInitStruct->ClockType));
781   assert_param(IS_FLASH_LATENCY(FLatency));
782 
783   /* To correctly read data from FLASH memory, the number of wait states (LATENCY)
784     must be correctly programmed according to the frequency of the CPU clock
785     (HCLK) and the supply voltage of the device. */
786 
787   /* Increasing the number of wait states because of higher CPU frequency */
788   if (FLatency > __HAL_FLASH_GET_LATENCY())
789   {
790     /* Program the new number of wait states to the LATENCY bits in the FLASH_ACR register */
791     __HAL_FLASH_SET_LATENCY(FLatency);
792 
793     /* Check that the new number of wait states is taken into account to access the Flash
794     memory by reading the FLASH_ACR register */
795     if (__HAL_FLASH_GET_LATENCY() != FLatency)
796     {
797       return HAL_ERROR;
798     }
799   }
800 
801   /*------------------------- SYSCLK Configuration ---------------------------*/
802   if(((RCC_ClkInitStruct->ClockType) & RCC_CLOCKTYPE_SYSCLK) == RCC_CLOCKTYPE_SYSCLK)
803   {
804     assert_param(IS_RCC_SYSCLKSOURCE(RCC_ClkInitStruct->SYSCLKSource));
805 
806     /* PLL is selected as System Clock Source */
807     if (RCC_ClkInitStruct->SYSCLKSource == RCC_SYSCLKSOURCE_PLLCLK)
808     {
809       /* Check the PLL ready flag */
810       if (READ_BIT(RCC->CR, RCC_CR_PLLRDY) == 0U)
811       {
812         return HAL_ERROR;
813       }
814       /* Undershoot management when selection PLL as SYSCLK source and frequency above 80Mhz */
815       /* Compute target PLL output frequency */
816       pllfreq = RCC_GetSysClockFreqFromPLLSource();
817 
818       /* Intermediate step with HCLK prescaler 2 necessary before to go over 80Mhz */
819       if(pllfreq > 80000000U)
820       {
821         if (((READ_BIT(RCC->CFGR, RCC_CFGR_HPRE) == RCC_SYSCLK_DIV1)) ||
822             (((((RCC_ClkInitStruct->ClockType) & RCC_CLOCKTYPE_HCLK) == RCC_CLOCKTYPE_HCLK) &&
823               (RCC_ClkInitStruct->AHBCLKDivider == RCC_SYSCLK_DIV1))))
824         {
825           MODIFY_REG(RCC->CFGR, RCC_CFGR_HPRE, RCC_SYSCLK_DIV2);
826           hpre = RCC_SYSCLK_DIV2;
827         }
828       }
829     }
830     else
831     {
832       /* HSE is selected as System Clock Source */
833       if (RCC_ClkInitStruct->SYSCLKSource == RCC_SYSCLKSOURCE_HSE)
834       {
835         /* Check the HSE ready flag */
836         if(READ_BIT(RCC->CR, RCC_CR_HSERDY) == 0U)
837         {
838           return HAL_ERROR;
839         }
840       }
841       /* HSI is selected as System Clock Source */
842       else
843       {
844         /* Check the HSI ready flag */
845         if(READ_BIT(RCC->CR, RCC_CR_HSIRDY) == 0U)
846         {
847           return HAL_ERROR;
848         }
849       }
850       /* Overshoot management when going down from PLL as SYSCLK source and frequency above 80Mhz */
851       pllfreq = HAL_RCC_GetSysClockFreq();
852 
853       /* Intermediate step with HCLK prescaler 2 necessary before to go under 80Mhz */
854       if(pllfreq > 80000000U)
855       {
856         MODIFY_REG(RCC->CFGR, RCC_CFGR_HPRE, RCC_SYSCLK_DIV2);
857         hpre = RCC_SYSCLK_DIV2;
858       }
859 
860     }
861 
862     MODIFY_REG(RCC->CFGR, RCC_CFGR_SW, RCC_ClkInitStruct->SYSCLKSource);
863 
864     /* Get Start Tick*/
865     tickstart = HAL_GetTick();
866 
867     while (__HAL_RCC_GET_SYSCLK_SOURCE() != (RCC_ClkInitStruct->SYSCLKSource << RCC_CFGR_SWS_Pos))
868     {
869       if ((HAL_GetTick() - tickstart) > CLOCKSWITCH_TIMEOUT_VALUE)
870       {
871         return HAL_TIMEOUT;
872       }
873     }
874   }
875 
876   /*-------------------------- HCLK Configuration --------------------------*/
877   if (((RCC_ClkInitStruct->ClockType) & RCC_CLOCKTYPE_HCLK) == RCC_CLOCKTYPE_HCLK)
878   {
879     /* Set the highest APB divider in order to ensure that we do not go through
880        a non-spec phase whatever we decrease or increase HCLK. */
881     if (((RCC_ClkInitStruct->ClockType) & RCC_CLOCKTYPE_PCLK1) == RCC_CLOCKTYPE_PCLK1)
882     {
883       MODIFY_REG(RCC->CFGR, RCC_CFGR_PPRE1, RCC_HCLK_DIV16);
884     }
885     if (((RCC_ClkInitStruct->ClockType) & RCC_CLOCKTYPE_PCLK2) == RCC_CLOCKTYPE_PCLK2)
886     {
887       MODIFY_REG(RCC->CFGR, RCC_CFGR_PPRE2, RCC_HCLK_DIV16);
888     }
889 
890     /* Set the new HCLK clock divider */
891     assert_param(IS_RCC_HCLK(RCC_ClkInitStruct->AHBCLKDivider));
892     MODIFY_REG(RCC->CFGR, RCC_CFGR_HPRE, RCC_ClkInitStruct->AHBCLKDivider);
893   }
894   else
895   {
896     /* Is intermediate HCLK prescaler 2 applied internally, complete with HCLK prescaler 1 */
897     if(hpre == RCC_SYSCLK_DIV2)
898     {
899       MODIFY_REG(RCC->CFGR, RCC_CFGR_HPRE, RCC_SYSCLK_DIV1);
900     }
901   }
902 
903   /* Decreasing the number of wait states because of lower CPU frequency */
904   if (FLatency < __HAL_FLASH_GET_LATENCY())
905   {
906     /* Program the new number of wait states to the LATENCY bits in the FLASH_ACR register */
907     __HAL_FLASH_SET_LATENCY(FLatency);
908 
909     /* Check that the new number of wait states is taken into account to access the Flash
910     memory by polling the FLASH_ACR register */
911     tickstart = HAL_GetTick();
912 
913     while (__HAL_FLASH_GET_LATENCY() != FLatency)
914     {
915       if ((HAL_GetTick() - tickstart) > CLOCKSWITCH_TIMEOUT_VALUE)
916       {
917         return HAL_TIMEOUT;
918       }
919     }
920   }
921 
922   /*-------------------------- PCLK1 Configuration ---------------------------*/
923   if (((RCC_ClkInitStruct->ClockType) & RCC_CLOCKTYPE_PCLK1) == RCC_CLOCKTYPE_PCLK1)
924   {
925     assert_param(IS_RCC_PCLK(RCC_ClkInitStruct->APB1CLKDivider));
926     MODIFY_REG(RCC->CFGR, RCC_CFGR_PPRE1, RCC_ClkInitStruct->APB1CLKDivider);
927   }
928 
929   /*-------------------------- PCLK2 Configuration ---------------------------*/
930   if(((RCC_ClkInitStruct->ClockType) & RCC_CLOCKTYPE_PCLK2) == RCC_CLOCKTYPE_PCLK2)
931   {
932     assert_param(IS_RCC_PCLK(RCC_ClkInitStruct->APB2CLKDivider));
933     MODIFY_REG(RCC->CFGR, RCC_CFGR_PPRE2, ((RCC_ClkInitStruct->APB2CLKDivider) << 3U));
934   }
935 
936   /* Update the SystemCoreClock global variable */
937   SystemCoreClock = HAL_RCC_GetSysClockFreq() >> (AHBPrescTable[READ_BIT(RCC->CFGR, RCC_CFGR_HPRE) >> RCC_CFGR_HPRE_Pos] & 0x1FU);
938 
939   /* Configure the source of time base considering new system clocks settings*/
940   return HAL_InitTick(uwTickPrio);
941 }
942 
943 /**
944   * @}
945   */
946 
947 /** @defgroup RCC_Exported_Functions_Group2 Peripheral Control functions
948  *  @brief   RCC clocks control functions
949  *
950 @verbatim
951  ===============================================================================
952                       ##### Peripheral Control functions #####
953  ===============================================================================
954     [..]
955     This subsection provides a set of functions allowing to:
956 
957     (+) Output clock to MCO pin.
958     (+) Retrieve current clock frequencies.
959     (+) Enable the Clock Security System.
960 
961 @endverbatim
962   * @{
963   */
964 
965 /**
966   * @brief  Select the clock source to output on MCO pin(PA8/PG10).
967   * @note   PA8/PG10 should be configured in alternate function mode.
968   * @note   The default configuration of the GPIOG pin 10 (PG10) is set to reset mode (NRST pin)
969   *         and user shall set the NRST_MODE Bit in the FLASH OPTR register to be able to use it
970   *         as an MCO pin.
971   *         The @ref HAL_FLASHEx_OBProgram() API can be used to configure the NRST_MODE Bit value.
972   * @param  RCC_MCOx  specifies the output direction for the clock source.
973   *          For STM32G4xx family this parameter can have only one value:
974   *            @arg @ref RCC_MCO_PA8  Clock source to output on MCO1 pin(PA8).
975   *            @arg @ref RCC_MCO_PG10  Clock source to output on MCO1 pin(PG10).
976   * @param  RCC_MCOSource  specifies the clock source to output.
977   *          This parameter can be one of the following values:
978   *            @arg @ref RCC_MCO1SOURCE_NOCLOCK  MCO output disabled, no clock on MCO
979   *            @arg @ref RCC_MCO1SOURCE_SYSCLK  system  clock selected as MCO source
980   *            @arg @ref RCC_MCO1SOURCE_HSI  HSI clock selected as MCO source
981   *            @arg @ref RCC_MCO1SOURCE_HSE  HSE clock selected as MCO sourcee
982   *            @arg @ref RCC_MCO1SOURCE_PLLCLK  main PLL clock selected as MCO source
983   *            @arg @ref RCC_MCO1SOURCE_LSI  LSI clock selected as MCO source
984   *            @arg @ref RCC_MCO1SOURCE_LSE  LSE clock selected as MCO source
985   *            @arg @ref RCC_MCO1SOURCE_HSI48  HSI48 clock selected as MCO source for devices with HSI48
986   * @param  RCC_MCODiv  specifies the MCO prescaler.
987   *          This parameter can be one of the following values:
988   *            @arg @ref RCC_MCODIV_1  no division applied to MCO clock
989   *            @arg @ref RCC_MCODIV_2  division by 2 applied to MCO clock
990   *            @arg @ref RCC_MCODIV_4  division by 4 applied to MCO clock
991   *            @arg @ref RCC_MCODIV_8  division by 8 applied to MCO clock
992   *            @arg @ref RCC_MCODIV_16  division by 16 applied to MCO clock
993   * @retval None
994   */
HAL_RCC_MCOConfig(uint32_t RCC_MCOx,uint32_t RCC_MCOSource,uint32_t RCC_MCODiv)995 void HAL_RCC_MCOConfig(uint32_t RCC_MCOx, uint32_t RCC_MCOSource, uint32_t RCC_MCODiv)
996 {
997   GPIO_InitTypeDef gpio_initstruct;
998   uint32_t mcoindex;
999   uint32_t mco_gpio_index;
1000   GPIO_TypeDef * mco_gpio_port;
1001 
1002   /* Check the parameters */
1003   assert_param(IS_RCC_MCO(RCC_MCOx));
1004 
1005   /* Common GPIO init parameters */
1006   gpio_initstruct.Mode      = GPIO_MODE_AF_PP;
1007   gpio_initstruct.Speed     = GPIO_SPEED_FREQ_VERY_HIGH;
1008   gpio_initstruct.Pull      = GPIO_NOPULL;
1009 
1010   /* Get MCOx selection */
1011   mcoindex = RCC_MCOx & RCC_MCO_INDEX_MASK;
1012 
1013   /* Get MCOx GPIO Port */
1014   mco_gpio_port = (GPIO_TypeDef *) RCC_GET_MCO_GPIO_PORT(RCC_MCOx);
1015 
1016   /* MCOx Clock Enable */
1017   mco_gpio_index = RCC_GET_MCO_GPIO_INDEX(RCC_MCOx);
1018   SET_BIT(RCC->AHB2ENR, (1UL << mco_gpio_index ));
1019 
1020   /* Configure the MCOx pin in alternate function mode */
1021   gpio_initstruct.Pin = RCC_GET_MCO_GPIO_PIN(RCC_MCOx);
1022   gpio_initstruct.Alternate = RCC_GET_MCO_GPIO_AF(RCC_MCOx);
1023   HAL_GPIO_Init(mco_gpio_port, &gpio_initstruct);
1024 
1025    if (mcoindex == RCC_MCO1_INDEX)
1026   {
1027     assert_param(IS_RCC_MCODIV(RCC_MCODiv));
1028     assert_param(IS_RCC_MCO1SOURCE(RCC_MCOSource));
1029     /* Mask MCOSEL[] and MCOPRE[] bits then set MCO clock source and prescaler */
1030     MODIFY_REG(RCC->CFGR, (RCC_CFGR_MCOSEL | RCC_CFGR_MCOPRE), (RCC_MCOSource | RCC_MCODiv));
1031   }
1032 }
1033 
1034 /**
1035   * @brief  Return the SYSCLK frequency.
1036   *
1037   * @note   The system frequency computed by this function is not the real
1038   *         frequency in the chip. It is calculated based on the predefined
1039   *         constant and the selected clock source:
1040   * @note     If SYSCLK source is HSI, function returns values based on HSI_VALUE(*)
1041   * @note     If SYSCLK source is HSE, function returns values based on HSE_VALUE(**)
1042   * @note     If SYSCLK source is PLL, function returns values based on HSE_VALUE(**),
1043   *           HSI_VALUE(*) Value multiplied/divided by the PLL factors.
1044   * @note     (*) HSI_VALUE is a constant defined in stm32g4xx_hal_conf.h file (default value
1045   *               16 MHz) but the real value may vary depending on the variations
1046   *               in voltage and temperature.
1047   * @note     (**) HSE_VALUE is a constant defined in stm32g4xx_hal_conf.h file (default value
1048   *                8 MHz), user has to ensure that HSE_VALUE is same as the real
1049   *                frequency of the crystal used. Otherwise, this function may
1050   *                have wrong result.
1051   *
1052   * @note   The result of this function could be not correct when using fractional
1053   *         value for HSE crystal.
1054   *
1055   * @note   This function can be used by the user application to compute the
1056   *         baudrate for the communication peripherals or configure other parameters.
1057   *
1058   * @note   Each time SYSCLK changes, this function must be called to update the
1059   *         right SYSCLK value. Otherwise, any configuration based on this function will be incorrect.
1060   *
1061   *
1062   * @retval SYSCLK frequency
1063   */
HAL_RCC_GetSysClockFreq(void)1064 uint32_t HAL_RCC_GetSysClockFreq(void)
1065 {
1066   uint32_t pllvco, pllsource, pllr, pllm;
1067   uint32_t sysclockfreq;
1068 
1069   if (__HAL_RCC_GET_SYSCLK_SOURCE() == RCC_CFGR_SWS_HSI)
1070   {
1071     /* HSI used as system clock source */
1072     sysclockfreq = HSI_VALUE;
1073   }
1074   else if (__HAL_RCC_GET_SYSCLK_SOURCE() == RCC_CFGR_SWS_HSE)
1075   {
1076     /* HSE used as system clock source */
1077     sysclockfreq = HSE_VALUE;
1078   }
1079   else if (__HAL_RCC_GET_SYSCLK_SOURCE() == RCC_CFGR_SWS_PLL)
1080   {
1081     /* PLL used as system clock  source */
1082 
1083     /* PLL_VCO = ((HSE_VALUE or HSI_VALUE)/ PLLM) * PLLN
1084     SYSCLK = PLL_VCO / PLLR
1085     */
1086     pllsource = READ_BIT(RCC->PLLCFGR, RCC_PLLCFGR_PLLSRC);
1087     pllm = (READ_BIT(RCC->PLLCFGR, RCC_PLLCFGR_PLLM) >> RCC_PLLCFGR_PLLM_Pos) + 1U ;
1088 
1089     switch (pllsource)
1090     {
1091     case RCC_PLLSOURCE_HSE:  /* HSE used as PLL clock source */
1092       pllvco = (HSE_VALUE / pllm) * (READ_BIT(RCC->PLLCFGR, RCC_PLLCFGR_PLLN) >> RCC_PLLCFGR_PLLN_Pos);
1093       break;
1094 
1095     case RCC_PLLSOURCE_HSI:  /* HSI used as PLL clock source */
1096     default:
1097       pllvco = (HSI_VALUE / pllm) * (READ_BIT(RCC->PLLCFGR, RCC_PLLCFGR_PLLN) >> RCC_PLLCFGR_PLLN_Pos);
1098       break;
1099     }
1100     pllr = ((READ_BIT(RCC->PLLCFGR, RCC_PLLCFGR_PLLR) >> RCC_PLLCFGR_PLLR_Pos) + 1U ) * 2U;
1101     sysclockfreq = pllvco/pllr;
1102   }
1103   else
1104   {
1105     sysclockfreq = 0U;
1106   }
1107 
1108   return sysclockfreq;
1109 }
1110 
1111 /**
1112   * @brief  Return the HCLK frequency.
1113   * @note   Each time HCLK changes, this function must be called to update the
1114   *         right HCLK value. Otherwise, any configuration based on this function will be incorrect.
1115   *
1116   * @note   The SystemCoreClock CMSIS variable is used to store System Clock Frequency.
1117   * @retval HCLK frequency in Hz
1118   */
HAL_RCC_GetHCLKFreq(void)1119 uint32_t HAL_RCC_GetHCLKFreq(void)
1120 {
1121   return SystemCoreClock;
1122 }
1123 
1124 /**
1125   * @brief  Return the PCLK1 frequency.
1126   * @note   Each time PCLK1 changes, this function must be called to update the
1127   *         right PCLK1 value. Otherwise, any configuration based on this function will be incorrect.
1128   * @retval PCLK1 frequency in Hz
1129   */
HAL_RCC_GetPCLK1Freq(void)1130 uint32_t HAL_RCC_GetPCLK1Freq(void)
1131 {
1132   /* Get HCLK source and Compute PCLK1 frequency ---------------------------*/
1133   return (HAL_RCC_GetHCLKFreq() >> (APBPrescTable[READ_BIT(RCC->CFGR, RCC_CFGR_PPRE1) >> RCC_CFGR_PPRE1_Pos] & 0x1FU));
1134 }
1135 
1136 /**
1137   * @brief  Return the PCLK2 frequency.
1138   * @note   Each time PCLK2 changes, this function must be called to update the
1139   *         right PCLK2 value. Otherwise, any configuration based on this function will be incorrect.
1140   * @retval PCLK2 frequency in Hz
1141   */
HAL_RCC_GetPCLK2Freq(void)1142 uint32_t HAL_RCC_GetPCLK2Freq(void)
1143 {
1144   /* Get HCLK source and Compute PCLK2 frequency ---------------------------*/
1145   return (HAL_RCC_GetHCLKFreq()>> (APBPrescTable[READ_BIT(RCC->CFGR, RCC_CFGR_PPRE2) >> RCC_CFGR_PPRE2_Pos] & 0x1FU));
1146 }
1147 
1148 /**
1149   * @brief  Configure the RCC_OscInitStruct according to the internal
1150   *         RCC configuration registers.
1151   * @param  RCC_OscInitStruct  pointer to an RCC_OscInitTypeDef structure that
1152   *         will be configured.
1153   * @retval None
1154   */
HAL_RCC_GetOscConfig(RCC_OscInitTypeDef * RCC_OscInitStruct)1155 void HAL_RCC_GetOscConfig(RCC_OscInitTypeDef  *RCC_OscInitStruct)
1156 {
1157   /* Check the parameters */
1158   assert_param(RCC_OscInitStruct != (void *)NULL);
1159 
1160   /* Set all possible values for the Oscillator type parameter ---------------*/
1161   RCC_OscInitStruct->OscillatorType = RCC_OSCILLATORTYPE_HSE | RCC_OSCILLATORTYPE_HSI | \
1162                                       RCC_OSCILLATORTYPE_LSE | RCC_OSCILLATORTYPE_LSI | RCC_OSCILLATORTYPE_HSI48;
1163 
1164   /* Get the HSE configuration -----------------------------------------------*/
1165   if(READ_BIT(RCC->CR, RCC_CR_HSEBYP) == RCC_CR_HSEBYP)
1166   {
1167     RCC_OscInitStruct->HSEState = RCC_HSE_BYPASS;
1168   }
1169   else if(READ_BIT(RCC->CR, RCC_CR_HSEON) == RCC_CR_HSEON)
1170   {
1171     RCC_OscInitStruct->HSEState = RCC_HSE_ON;
1172   }
1173   else
1174   {
1175     RCC_OscInitStruct->HSEState = RCC_HSE_OFF;
1176   }
1177 
1178   /* Get the HSI configuration -----------------------------------------------*/
1179   if(READ_BIT(RCC->CR, RCC_CR_HSION) == RCC_CR_HSION)
1180   {
1181     RCC_OscInitStruct->HSIState = RCC_HSI_ON;
1182   }
1183   else
1184   {
1185     RCC_OscInitStruct->HSIState = RCC_HSI_OFF;
1186   }
1187 
1188   RCC_OscInitStruct->HSICalibrationValue = READ_BIT(RCC->ICSCR, RCC_ICSCR_HSITRIM) >> RCC_ICSCR_HSITRIM_Pos;
1189 
1190   /* Get the LSE configuration -----------------------------------------------*/
1191   if(READ_BIT(RCC->BDCR, RCC_BDCR_LSEBYP) == RCC_BDCR_LSEBYP)
1192   {
1193     RCC_OscInitStruct->LSEState = RCC_LSE_BYPASS;
1194   }
1195   else if(READ_BIT(RCC->BDCR, RCC_BDCR_LSEON) == RCC_BDCR_LSEON)
1196   {
1197     RCC_OscInitStruct->LSEState = RCC_LSE_ON;
1198   }
1199   else
1200   {
1201     RCC_OscInitStruct->LSEState = RCC_LSE_OFF;
1202   }
1203 
1204   /* Get the LSI configuration -----------------------------------------------*/
1205   if(READ_BIT(RCC->CSR, RCC_CSR_LSION) == RCC_CSR_LSION)
1206   {
1207     RCC_OscInitStruct->LSIState = RCC_LSI_ON;
1208   }
1209   else
1210   {
1211     RCC_OscInitStruct->LSIState = RCC_LSI_OFF;
1212   }
1213 
1214   /* Get the HSI48 configuration ---------------------------------------------*/
1215   if(READ_BIT(RCC->CRRCR, RCC_CRRCR_HSI48ON) == RCC_CRRCR_HSI48ON)
1216   {
1217     RCC_OscInitStruct->HSI48State = RCC_HSI48_ON;
1218   }
1219   else
1220   {
1221     RCC_OscInitStruct->HSI48State = RCC_HSI48_OFF;
1222   }
1223 
1224   /* Get the PLL configuration -----------------------------------------------*/
1225   if(READ_BIT(RCC->CR, RCC_CR_PLLON) == RCC_CR_PLLON)
1226   {
1227     RCC_OscInitStruct->PLL.PLLState = RCC_PLL_ON;
1228   }
1229   else
1230   {
1231     RCC_OscInitStruct->PLL.PLLState = RCC_PLL_OFF;
1232   }
1233   RCC_OscInitStruct->PLL.PLLSource = READ_BIT(RCC->PLLCFGR, RCC_PLLCFGR_PLLSRC);
1234   RCC_OscInitStruct->PLL.PLLM = (READ_BIT(RCC->PLLCFGR, RCC_PLLCFGR_PLLM) >> RCC_PLLCFGR_PLLM_Pos) + 1U;
1235   RCC_OscInitStruct->PLL.PLLN = READ_BIT(RCC->PLLCFGR, RCC_PLLCFGR_PLLN) >> RCC_PLLCFGR_PLLN_Pos;
1236   RCC_OscInitStruct->PLL.PLLQ = (((READ_BIT(RCC->PLLCFGR, RCC_PLLCFGR_PLLQ) >> RCC_PLLCFGR_PLLQ_Pos) + 1U) << 1U);
1237   RCC_OscInitStruct->PLL.PLLR = (((READ_BIT(RCC->PLLCFGR, RCC_PLLCFGR_PLLR) >> RCC_PLLCFGR_PLLR_Pos) + 1U) << 1U);
1238   RCC_OscInitStruct->PLL.PLLP = READ_BIT(RCC->PLLCFGR, RCC_PLLCFGR_PLLPDIV) >> RCC_PLLCFGR_PLLPDIV_Pos;
1239 }
1240 
1241 /**
1242   * @brief  Configure the RCC_ClkInitStruct according to the internal
1243   *         RCC configuration registers.
1244   * @param  RCC_ClkInitStruct  pointer to an RCC_ClkInitTypeDef structure that
1245   *         will be configured.
1246   * @param  pFLatency  Pointer on the Flash Latency.
1247   * @retval None
1248   */
HAL_RCC_GetClockConfig(RCC_ClkInitTypeDef * RCC_ClkInitStruct,uint32_t * pFLatency)1249 void HAL_RCC_GetClockConfig(RCC_ClkInitTypeDef  *RCC_ClkInitStruct, uint32_t *pFLatency)
1250 {
1251   /* Check the parameters */
1252   assert_param(RCC_ClkInitStruct != (void  *)NULL);
1253   assert_param(pFLatency != (void *)NULL);
1254 
1255   /* Set all possible values for the Clock type parameter --------------------*/
1256   RCC_ClkInitStruct->ClockType = RCC_CLOCKTYPE_SYSCLK | RCC_CLOCKTYPE_HCLK | RCC_CLOCKTYPE_PCLK1 | RCC_CLOCKTYPE_PCLK2;
1257 
1258   /* Get the SYSCLK configuration --------------------------------------------*/
1259   RCC_ClkInitStruct->SYSCLKSource = READ_BIT(RCC->CFGR, RCC_CFGR_SW);
1260 
1261   /* Get the HCLK configuration ----------------------------------------------*/
1262   RCC_ClkInitStruct->AHBCLKDivider = READ_BIT(RCC->CFGR, RCC_CFGR_HPRE);
1263 
1264   /* Get the APB1 configuration ----------------------------------------------*/
1265   RCC_ClkInitStruct->APB1CLKDivider = READ_BIT(RCC->CFGR, RCC_CFGR_PPRE1);
1266 
1267   /* Get the APB2 configuration ----------------------------------------------*/
1268   RCC_ClkInitStruct->APB2CLKDivider = (READ_BIT(RCC->CFGR, RCC_CFGR_PPRE2) >> 3U);
1269 
1270   /* Get the Flash Wait State (Latency) configuration ------------------------*/
1271   *pFLatency = __HAL_FLASH_GET_LATENCY();
1272 }
1273 
1274 /**
1275   * @brief  Enable the Clock Security System.
1276   * @note   If a failure is detected on the HSE oscillator clock, this oscillator
1277   *         is automatically disabled and an interrupt is generated to inform the
1278   *         software about the failure (Clock Security System Interrupt, CSSI),
1279   *         allowing the MCU to perform rescue operations. The CSSI is linked to
1280   *         the Cortex-M4 NMI (Non-Maskable Interrupt) exception vector.
1281   * @note   The Clock Security System can only be cleared by reset.
1282   * @retval None
1283   */
HAL_RCC_EnableCSS(void)1284 void HAL_RCC_EnableCSS(void)
1285 {
1286   SET_BIT(RCC->CR, RCC_CR_CSSON) ;
1287 }
1288 
1289 /**
1290   * @brief  Enable the LSE Clock Security System.
1291   * @note   If a failure is detected on the external 32 kHz oscillator,
1292   *         the LSE clock is no longer supplied to the RTC but no hardware action
1293   *         is made to the registers. If enabled, an interrupt will be generated
1294   *         and handle through @ref RCCEx_EXTI_LINE_LSECSS
1295   * @note   The Clock Security System can only be cleared by reset or after a LSE failure detection.
1296   * @retval None
1297   */
HAL_RCC_EnableLSECSS(void)1298 void HAL_RCC_EnableLSECSS(void)
1299 {
1300   SET_BIT(RCC->BDCR, RCC_BDCR_LSECSSON) ;
1301 }
1302 
1303 /**
1304   * @brief  Disable the LSE Clock Security System.
1305   * @note   After LSE failure detection, the software must disable LSECSSON
1306   * @note   The Clock Security System can only be cleared by reset otherwise.
1307   * @retval None
1308   */
HAL_RCC_DisableLSECSS(void)1309 void HAL_RCC_DisableLSECSS(void)
1310 {
1311   CLEAR_BIT(RCC->BDCR, RCC_BDCR_LSECSSON) ;
1312 }
1313 
1314 /**
1315   * @brief Handle the RCC Clock Security System interrupt request.
1316   * @note This API should be called under the NMI_Handler().
1317   * @retval None
1318   */
HAL_RCC_NMI_IRQHandler(void)1319 void HAL_RCC_NMI_IRQHandler(void)
1320 {
1321   /* Check RCC CSSF interrupt flag  */
1322   if(__HAL_RCC_GET_IT(RCC_IT_CSS))
1323   {
1324     /* RCC Clock Security System interrupt user callback */
1325     HAL_RCC_CSSCallback();
1326 
1327     /* Clear RCC CSS pending bit */
1328     __HAL_RCC_CLEAR_IT(RCC_IT_CSS);
1329   }
1330 }
1331 
1332 /**
1333   * @brief  RCC Clock Security System interrupt callback.
1334   * @retval none
1335   */
HAL_RCC_CSSCallback(void)1336 __weak void HAL_RCC_CSSCallback(void)
1337 {
1338   /* NOTE : This function should not be modified, when the callback is needed,
1339             the HAL_RCC_CSSCallback should be implemented in the user file
1340    */
1341 }
1342 
1343 /**
1344   * @}
1345   */
1346 
1347 /**
1348   * @}
1349   */
1350 
1351 /* Private function prototypes -----------------------------------------------*/
1352 /** @addtogroup RCC_Private_Functions
1353   * @{
1354   */
1355 
1356 /**
1357   * @brief  Compute SYSCLK frequency based on PLL SYSCLK source.
1358   * @retval SYSCLK frequency
1359   */
RCC_GetSysClockFreqFromPLLSource(void)1360 static uint32_t RCC_GetSysClockFreqFromPLLSource(void)
1361 {
1362   uint32_t pllvco, pllsource, pllr, pllm;
1363   uint32_t sysclockfreq;
1364 
1365   /* PLL_VCO = (HSE_VALUE or HSI_VALUE/ PLLM) * PLLN
1366      SYSCLK = PLL_VCO / PLLR
1367    */
1368   pllsource = READ_BIT(RCC->PLLCFGR, RCC_PLLCFGR_PLLSRC);
1369   pllm = (READ_BIT(RCC->PLLCFGR, RCC_PLLCFGR_PLLM) >> RCC_PLLCFGR_PLLM_Pos) + 1U ;
1370 
1371   switch (pllsource)
1372   {
1373   case RCC_PLLSOURCE_HSE:  /* HSE used as PLL clock source */
1374     pllvco = (HSE_VALUE / pllm) * (READ_BIT(RCC->PLLCFGR, RCC_PLLCFGR_PLLN) >> RCC_PLLCFGR_PLLN_Pos);
1375     break;
1376 
1377   case RCC_PLLSOURCE_HSI:  /* HSI used as PLL clock source */
1378   default:
1379     pllvco = (HSI_VALUE / pllm) * (READ_BIT(RCC->PLLCFGR, RCC_PLLCFGR_PLLN) >> RCC_PLLCFGR_PLLN_Pos);
1380     break;
1381   }
1382 
1383   pllr = ((READ_BIT(RCC->PLLCFGR, RCC_PLLCFGR_PLLR) >> RCC_PLLCFGR_PLLR_Pos) + 1U ) * 2U;
1384   sysclockfreq = pllvco/pllr;
1385 
1386   return sysclockfreq;
1387 }
1388 
1389 /**
1390   * @}
1391   */
1392 
1393 #endif /* HAL_RCC_MODULE_ENABLED */
1394 /**
1395   * @}
1396   */
1397 
1398 /**
1399   * @}
1400   */
1401 
1402