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 disabled */
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         /* Get Start Tick*/
676         tickstart = HAL_GetTick();
677 
678         /* Wait till PLL is disabled */
679         while (READ_BIT(RCC->CR, RCC_CR_PLLRDY) != 0U)
680         {
681           if ((HAL_GetTick() - tickstart) > PLL_TIMEOUT_VALUE)
682           {
683             return HAL_TIMEOUT;
684           }
685         }
686 
687         /* Unselect PLL clock source and disable outputs to save power */
688         RCC->PLLCFGR &= ~(RCC_PLLCFGR_PLLSRC | RCC_PLL_SYSCLK | RCC_PLL_48M1CLK | RCC_PLL_ADCCLK);
689       }
690     }
691     else
692     {
693       /* Check if there is a request to disable the PLL used as System clock source */
694       if((RCC_OscInitStruct->PLL.PLLState) == RCC_PLL_OFF)
695       {
696         return HAL_ERROR;
697       }
698       else
699       {
700       /* Do not return HAL_ERROR if request repeats the current configuration */
701       temp_pllckcfg = RCC->PLLCFGR;
702       if((READ_BIT(temp_pllckcfg, RCC_PLLCFGR_PLLSRC) != RCC_OscInitStruct->PLL.PLLSource) ||
703          (READ_BIT(temp_pllckcfg, RCC_PLLCFGR_PLLM) != (((RCC_OscInitStruct->PLL.PLLM) - 1U) << RCC_PLLCFGR_PLLM_Pos)) ||
704          (READ_BIT(temp_pllckcfg, RCC_PLLCFGR_PLLN) != ((RCC_OscInitStruct->PLL.PLLN) << RCC_PLLCFGR_PLLN_Pos)) ||
705          (READ_BIT(temp_pllckcfg, RCC_PLLCFGR_PLLPDIV) != ((RCC_OscInitStruct->PLL.PLLP) << RCC_PLLCFGR_PLLPDIV_Pos)) ||
706          (READ_BIT(temp_pllckcfg, RCC_PLLCFGR_PLLQ) != ((((RCC_OscInitStruct->PLL.PLLQ) >> 1U) - 1U) << RCC_PLLCFGR_PLLQ_Pos)) ||
707          (READ_BIT(temp_pllckcfg, RCC_PLLCFGR_PLLR) != ((((RCC_OscInitStruct->PLL.PLLR) >> 1U) - 1U) << RCC_PLLCFGR_PLLR_Pos)))
708       {
709         return HAL_ERROR;
710       }
711     }
712   }
713   }
714 
715   return HAL_OK;
716 }
717 
718 /**
719   * @brief  Initialize the CPU, AHB and APB buses clocks according to the specified
720   *         parameters in the RCC_ClkInitStruct.
721   * @param  RCC_ClkInitStruct  pointer to an RCC_OscInitTypeDef structure that
722   *         contains the configuration information for the RCC peripheral.
723   * @param  FLatency  FLASH Latency
724   *          This parameter can be one of the following values:
725   *            @arg FLASH_LATENCY_0   FLASH 0 Latency cycle
726   *            @arg FLASH_LATENCY_1   FLASH 1 Latency cycle
727   *            @arg FLASH_LATENCY_2   FLASH 2 Latency cycles
728   *            @arg FLASH_LATENCY_3   FLASH 3 Latency cycles
729   *            @arg FLASH_LATENCY_4   FLASH 4 Latency cycles
730   *            @arg FLASH_LATENCY_5   FLASH 5 Latency cycles
731   *            @arg FLASH_LATENCY_6   FLASH 6 Latency cycles
732   *            @arg FLASH_LATENCY_7   FLASH 7 Latency cycles
733   *            @arg FLASH_LATENCY_8   FLASH 8 Latency cycles
734   *            @arg FLASH_LATENCY_9   FLASH 9 Latency cycles
735   *            @arg FLASH_LATENCY_10  FLASH 10 Latency cycles
736   *            @arg FLASH_LATENCY_11  FLASH 11 Latency cycles
737   *            @arg FLASH_LATENCY_12  FLASH 12 Latency cycles
738   *            @arg FLASH_LATENCY_13  FLASH 13 Latency cycles
739   *            @arg FLASH_LATENCY_14  FLASH 14 Latency cycles
740   *            @arg FLASH_LATENCY_15  FLASH 15 Latency cycles
741   *
742   * @note   The SystemCoreClock CMSIS variable is used to store System Clock Frequency
743   *         and updated by HAL_RCC_GetHCLKFreq() function called within this function
744   *
745   * @note   The HSI is used by default as system clock source after
746   *         startup from Reset, wake-up from STANDBY mode. After restart from Reset,
747   *         the HSI frequency is set to its default value 16 MHz.
748   *
749   * @note   The HSI can be selected as system clock source after
750   *         from STOP modes or in case of failure of the HSE used directly or indirectly
751   *         as system clock (if the Clock Security System CSS is enabled).
752   *
753   * @note   A switch from one clock source to another occurs only if the target
754   *         clock source is ready (clock stable after startup delay or PLL locked).
755   *         If a clock source which is not yet ready is selected, the switch will
756   *         occur when the clock source is ready.
757   *
758   * @note   You can use HAL_RCC_GetClockConfig() function to know which clock is
759   *         currently used as system clock source.
760   *
761   * @note   Depending on the device voltage range, the software has to set correctly
762   *         HPRE[3:0] bits to ensure that HCLK not exceed the maximum allowed frequency
763   *         (for more details refer to section above "Initialization/de-initialization functions")
764   * @retval None
765   */
HAL_RCC_ClockConfig(RCC_ClkInitTypeDef * RCC_ClkInitStruct,uint32_t FLatency)766 HAL_StatusTypeDef HAL_RCC_ClockConfig(RCC_ClkInitTypeDef  *RCC_ClkInitStruct, uint32_t FLatency)
767 {
768   uint32_t tickstart;
769   uint32_t pllfreq;
770   uint32_t hpre = RCC_SYSCLK_DIV1;
771 
772   /* Check Null pointer */
773   if (RCC_ClkInitStruct == NULL)
774   {
775     return HAL_ERROR;
776   }
777 
778   /* Check the parameters */
779   assert_param(IS_RCC_CLOCKTYPE(RCC_ClkInitStruct->ClockType));
780   assert_param(IS_FLASH_LATENCY(FLatency));
781 
782   /* To correctly read data from FLASH memory, the number of wait states (LATENCY)
783     must be correctly programmed according to the frequency of the CPU clock
784     (HCLK) and the supply voltage of the device. */
785 
786   /* Increasing the number of wait states because of higher CPU frequency */
787   if (FLatency > __HAL_FLASH_GET_LATENCY())
788   {
789     /* Program the new number of wait states to the LATENCY bits in the FLASH_ACR register */
790     __HAL_FLASH_SET_LATENCY(FLatency);
791 
792     /* Check that the new number of wait states is taken into account to access the Flash
793     memory by reading the FLASH_ACR register */
794     if (__HAL_FLASH_GET_LATENCY() != FLatency)
795     {
796       return HAL_ERROR;
797     }
798   }
799 
800   /*------------------------- SYSCLK Configuration ---------------------------*/
801   if(((RCC_ClkInitStruct->ClockType) & RCC_CLOCKTYPE_SYSCLK) == RCC_CLOCKTYPE_SYSCLK)
802   {
803     assert_param(IS_RCC_SYSCLKSOURCE(RCC_ClkInitStruct->SYSCLKSource));
804 
805     /* PLL is selected as System Clock Source */
806     if (RCC_ClkInitStruct->SYSCLKSource == RCC_SYSCLKSOURCE_PLLCLK)
807     {
808       /* Check the PLL ready flag */
809       if (READ_BIT(RCC->CR, RCC_CR_PLLRDY) == 0U)
810       {
811         return HAL_ERROR;
812       }
813       /* Undershoot management when selection PLL as SYSCLK source and frequency above 80Mhz */
814       /* Compute target PLL output frequency */
815       pllfreq = RCC_GetSysClockFreqFromPLLSource();
816 
817       /* Intermediate step with HCLK prescaler 2 necessary before to go over 80Mhz */
818       if(pllfreq > 80000000U)
819       {
820         if (((READ_BIT(RCC->CFGR, RCC_CFGR_HPRE) == RCC_SYSCLK_DIV1)) ||
821             (((((RCC_ClkInitStruct->ClockType) & RCC_CLOCKTYPE_HCLK) == RCC_CLOCKTYPE_HCLK) &&
822               (RCC_ClkInitStruct->AHBCLKDivider == RCC_SYSCLK_DIV1))))
823         {
824           MODIFY_REG(RCC->CFGR, RCC_CFGR_HPRE, RCC_SYSCLK_DIV2);
825           hpre = RCC_SYSCLK_DIV2;
826         }
827       }
828     }
829     else
830     {
831       /* HSE is selected as System Clock Source */
832       if (RCC_ClkInitStruct->SYSCLKSource == RCC_SYSCLKSOURCE_HSE)
833       {
834         /* Check the HSE ready flag */
835         if(READ_BIT(RCC->CR, RCC_CR_HSERDY) == 0U)
836         {
837           return HAL_ERROR;
838         }
839       }
840       /* HSI is selected as System Clock Source */
841       else
842       {
843         /* Check the HSI ready flag */
844         if(READ_BIT(RCC->CR, RCC_CR_HSIRDY) == 0U)
845         {
846           return HAL_ERROR;
847         }
848       }
849       /* Overshoot management when going down from PLL as SYSCLK source and frequency above 80Mhz */
850       pllfreq = HAL_RCC_GetSysClockFreq();
851 
852       /* Intermediate step with HCLK prescaler 2 necessary before to go under 80Mhz */
853       if(pllfreq > 80000000U)
854       {
855         MODIFY_REG(RCC->CFGR, RCC_CFGR_HPRE, RCC_SYSCLK_DIV2);
856         hpre = RCC_SYSCLK_DIV2;
857       }
858 
859     }
860 
861     MODIFY_REG(RCC->CFGR, RCC_CFGR_SW, RCC_ClkInitStruct->SYSCLKSource);
862 
863     /* Get Start Tick*/
864     tickstart = HAL_GetTick();
865 
866     while (__HAL_RCC_GET_SYSCLK_SOURCE() != (RCC_ClkInitStruct->SYSCLKSource << RCC_CFGR_SWS_Pos))
867     {
868       if ((HAL_GetTick() - tickstart) > CLOCKSWITCH_TIMEOUT_VALUE)
869       {
870         return HAL_TIMEOUT;
871       }
872     }
873   }
874 
875   /*-------------------------- HCLK Configuration --------------------------*/
876   if (((RCC_ClkInitStruct->ClockType) & RCC_CLOCKTYPE_HCLK) == RCC_CLOCKTYPE_HCLK)
877   {
878     /* Set the highest APB divider in order to ensure that we do not go through
879        a non-spec phase whatever we decrease or increase HCLK. */
880     if (((RCC_ClkInitStruct->ClockType) & RCC_CLOCKTYPE_PCLK1) == RCC_CLOCKTYPE_PCLK1)
881     {
882       MODIFY_REG(RCC->CFGR, RCC_CFGR_PPRE1, RCC_HCLK_DIV16);
883     }
884     if (((RCC_ClkInitStruct->ClockType) & RCC_CLOCKTYPE_PCLK2) == RCC_CLOCKTYPE_PCLK2)
885     {
886       MODIFY_REG(RCC->CFGR, RCC_CFGR_PPRE2, RCC_HCLK_DIV16);
887     }
888 
889     /* Set the new HCLK clock divider */
890     assert_param(IS_RCC_HCLK(RCC_ClkInitStruct->AHBCLKDivider));
891     MODIFY_REG(RCC->CFGR, RCC_CFGR_HPRE, RCC_ClkInitStruct->AHBCLKDivider);
892   }
893   else
894   {
895     /* Is intermediate HCLK prescaler 2 applied internally, complete with HCLK prescaler 1 */
896     if(hpre == RCC_SYSCLK_DIV2)
897     {
898       MODIFY_REG(RCC->CFGR, RCC_CFGR_HPRE, RCC_SYSCLK_DIV1);
899     }
900   }
901 
902   /* Decreasing the number of wait states because of lower CPU frequency */
903   if (FLatency < __HAL_FLASH_GET_LATENCY())
904   {
905     /* Program the new number of wait states to the LATENCY bits in the FLASH_ACR register */
906     __HAL_FLASH_SET_LATENCY(FLatency);
907 
908     /* Check that the new number of wait states is taken into account to access the Flash
909     memory by polling the FLASH_ACR register */
910     tickstart = HAL_GetTick();
911 
912     while (__HAL_FLASH_GET_LATENCY() != FLatency)
913     {
914       if ((HAL_GetTick() - tickstart) > CLOCKSWITCH_TIMEOUT_VALUE)
915       {
916         return HAL_TIMEOUT;
917       }
918     }
919   }
920 
921   /*-------------------------- PCLK1 Configuration ---------------------------*/
922   if (((RCC_ClkInitStruct->ClockType) & RCC_CLOCKTYPE_PCLK1) == RCC_CLOCKTYPE_PCLK1)
923   {
924     assert_param(IS_RCC_PCLK(RCC_ClkInitStruct->APB1CLKDivider));
925     MODIFY_REG(RCC->CFGR, RCC_CFGR_PPRE1, RCC_ClkInitStruct->APB1CLKDivider);
926   }
927 
928   /*-------------------------- PCLK2 Configuration ---------------------------*/
929   if(((RCC_ClkInitStruct->ClockType) & RCC_CLOCKTYPE_PCLK2) == RCC_CLOCKTYPE_PCLK2)
930   {
931     assert_param(IS_RCC_PCLK(RCC_ClkInitStruct->APB2CLKDivider));
932     MODIFY_REG(RCC->CFGR, RCC_CFGR_PPRE2, ((RCC_ClkInitStruct->APB2CLKDivider) << 3U));
933   }
934 
935   /* Update the SystemCoreClock global variable */
936   SystemCoreClock = HAL_RCC_GetSysClockFreq() >> (AHBPrescTable[READ_BIT(RCC->CFGR, RCC_CFGR_HPRE) >> RCC_CFGR_HPRE_Pos] & 0x1FU);
937 
938   /* Configure the source of time base considering new system clocks settings*/
939   return HAL_InitTick(uwTickPrio);
940 }
941 
942 /**
943   * @}
944   */
945 
946 /** @defgroup RCC_Exported_Functions_Group2 Peripheral Control functions
947  *  @brief   RCC clocks control functions
948  *
949 @verbatim
950  ===============================================================================
951                       ##### Peripheral Control functions #####
952  ===============================================================================
953     [..]
954     This subsection provides a set of functions allowing to:
955 
956     (+) Output clock to MCO pin.
957     (+) Retrieve current clock frequencies.
958     (+) Enable the Clock Security System.
959 
960 @endverbatim
961   * @{
962   */
963 
964 /**
965   * @brief  Select the clock source to output on MCO pin(PA8/PG10).
966   * @note   PA8/PG10 should be configured in alternate function mode.
967   * @note   The default configuration of the GPIOG pin 10 (PG10) is set to reset mode (NRST pin)
968   *         and user shall set the NRST_MODE Bit in the FLASH OPTR register to be able to use it
969   *         as an MCO pin.
970   *         The @ref HAL_FLASHEx_OBProgram() API can be used to configure the NRST_MODE Bit value.
971   * @param  RCC_MCOx  specifies the output direction for the clock source.
972   *          For STM32G4xx family this parameter can have only one value:
973   *            @arg @ref RCC_MCO_PA8  Clock source to output on MCO1 pin(PA8).
974   *            @arg @ref RCC_MCO_PG10  Clock source to output on MCO1 pin(PG10).
975   * @param  RCC_MCOSource  specifies the clock source to output.
976   *          This parameter can be one of the following values:
977   *            @arg @ref RCC_MCO1SOURCE_NOCLOCK  MCO output disabled, no clock on MCO
978   *            @arg @ref RCC_MCO1SOURCE_SYSCLK  system  clock selected as MCO source
979   *            @arg @ref RCC_MCO1SOURCE_HSI  HSI clock selected as MCO source
980   *            @arg @ref RCC_MCO1SOURCE_HSE  HSE clock selected as MCO source
981   *            @arg @ref RCC_MCO1SOURCE_PLLCLK  main PLL clock selected as MCO source
982   *            @arg @ref RCC_MCO1SOURCE_LSI  LSI clock selected as MCO source
983   *            @arg @ref RCC_MCO1SOURCE_LSE  LSE clock selected as MCO source
984   *            @arg @ref RCC_MCO1SOURCE_HSI48  HSI48 clock selected as MCO source for devices with HSI48
985   * @param  RCC_MCODiv  specifies the MCO prescaler.
986   *          This parameter can be one of the following values:
987   *            @arg @ref RCC_MCODIV_1  no division applied to MCO clock
988   *            @arg @ref RCC_MCODIV_2  division by 2 applied to MCO clock
989   *            @arg @ref RCC_MCODIV_4  division by 4 applied to MCO clock
990   *            @arg @ref RCC_MCODIV_8  division by 8 applied to MCO clock
991   *            @arg @ref RCC_MCODIV_16  division by 16 applied to MCO clock
992   * @retval None
993   */
HAL_RCC_MCOConfig(uint32_t RCC_MCOx,uint32_t RCC_MCOSource,uint32_t RCC_MCODiv)994 void HAL_RCC_MCOConfig(uint32_t RCC_MCOx, uint32_t RCC_MCOSource, uint32_t RCC_MCODiv)
995 {
996   GPIO_InitTypeDef gpio_initstruct;
997   uint32_t mcoindex;
998   uint32_t mco_gpio_index;
999   GPIO_TypeDef * mco_gpio_port;
1000 
1001   /* Check the parameters */
1002   assert_param(IS_RCC_MCO(RCC_MCOx));
1003 
1004   /* Common GPIO init parameters */
1005   gpio_initstruct.Mode      = GPIO_MODE_AF_PP;
1006   gpio_initstruct.Speed     = GPIO_SPEED_FREQ_VERY_HIGH;
1007   gpio_initstruct.Pull      = GPIO_NOPULL;
1008 
1009   /* Get MCOx selection */
1010   mcoindex = RCC_MCOx & RCC_MCO_INDEX_MASK;
1011 
1012   /* Get MCOx GPIO Port */
1013   mco_gpio_port = (GPIO_TypeDef *) RCC_GET_MCO_GPIO_PORT(RCC_MCOx);
1014 
1015   /* MCOx Clock Enable */
1016   mco_gpio_index = RCC_GET_MCO_GPIO_INDEX(RCC_MCOx);
1017   SET_BIT(RCC->AHB2ENR, (1UL << mco_gpio_index ));
1018 
1019   /* Configure the MCOx pin in alternate function mode */
1020   gpio_initstruct.Pin = RCC_GET_MCO_GPIO_PIN(RCC_MCOx);
1021   gpio_initstruct.Alternate = RCC_GET_MCO_GPIO_AF(RCC_MCOx);
1022   HAL_GPIO_Init(mco_gpio_port, &gpio_initstruct);
1023 
1024    if (mcoindex == RCC_MCO1_INDEX)
1025   {
1026     assert_param(IS_RCC_MCODIV(RCC_MCODiv));
1027     assert_param(IS_RCC_MCO1SOURCE(RCC_MCOSource));
1028     /* Mask MCOSEL[] and MCOPRE[] bits then set MCO clock source and prescaler */
1029     MODIFY_REG(RCC->CFGR, (RCC_CFGR_MCOSEL | RCC_CFGR_MCOPRE), (RCC_MCOSource | RCC_MCODiv));
1030   }
1031 }
1032 
1033 /**
1034   * @brief  Return the SYSCLK frequency.
1035   *
1036   * @note   The system frequency computed by this function is not the real
1037   *         frequency in the chip. It is calculated based on the predefined
1038   *         constant and the selected clock source:
1039   * @note     If SYSCLK source is HSI, function returns values based on HSI_VALUE(*)
1040   * @note     If SYSCLK source is HSE, function returns values based on HSE_VALUE(**)
1041   * @note     If SYSCLK source is PLL, function returns values based on HSE_VALUE(**),
1042   *           HSI_VALUE(*) Value multiplied/divided by the PLL factors.
1043   * @note     (*) HSI_VALUE is a constant defined in stm32g4xx_hal_conf.h file (default value
1044   *               16 MHz) but the real value may vary depending on the variations
1045   *               in voltage and temperature.
1046   * @note     (**) HSE_VALUE is a constant defined in stm32g4xx_hal_conf.h file (default value
1047   *                8 MHz), user has to ensure that HSE_VALUE is same as the real
1048   *                frequency of the crystal used. Otherwise, this function may
1049   *                have wrong result.
1050   *
1051   * @note   The result of this function could be not correct when using fractional
1052   *         value for HSE crystal.
1053   *
1054   * @note   This function can be used by the user application to compute the
1055   *         baudrate for the communication peripherals or configure other parameters.
1056   *
1057   * @note   Each time SYSCLK changes, this function must be called to update the
1058   *         right SYSCLK value. Otherwise, any configuration based on this function will be incorrect.
1059   *
1060   *
1061   * @retval SYSCLK frequency
1062   */
HAL_RCC_GetSysClockFreq(void)1063 uint32_t HAL_RCC_GetSysClockFreq(void)
1064 {
1065   uint32_t pllvco, pllsource, pllr, pllm;
1066   uint32_t sysclockfreq;
1067 
1068   if (__HAL_RCC_GET_SYSCLK_SOURCE() == RCC_CFGR_SWS_HSI)
1069   {
1070     /* HSI used as system clock source */
1071     sysclockfreq = HSI_VALUE;
1072   }
1073   else if (__HAL_RCC_GET_SYSCLK_SOURCE() == RCC_CFGR_SWS_HSE)
1074   {
1075     /* HSE used as system clock source */
1076     sysclockfreq = HSE_VALUE;
1077   }
1078   else if (__HAL_RCC_GET_SYSCLK_SOURCE() == RCC_CFGR_SWS_PLL)
1079   {
1080     /* PLL used as system clock  source */
1081 
1082     /* PLL_VCO = ((HSE_VALUE or HSI_VALUE)/ PLLM) * PLLN
1083     SYSCLK = PLL_VCO / PLLR
1084     */
1085     pllsource = READ_BIT(RCC->PLLCFGR, RCC_PLLCFGR_PLLSRC);
1086     pllm = (READ_BIT(RCC->PLLCFGR, RCC_PLLCFGR_PLLM) >> RCC_PLLCFGR_PLLM_Pos) + 1U ;
1087 
1088     switch (pllsource)
1089     {
1090     case RCC_PLLSOURCE_HSE:  /* HSE used as PLL clock source */
1091       pllvco = (HSE_VALUE / pllm) * (READ_BIT(RCC->PLLCFGR, RCC_PLLCFGR_PLLN) >> RCC_PLLCFGR_PLLN_Pos);
1092       break;
1093 
1094     case RCC_PLLSOURCE_HSI:  /* HSI used as PLL clock source */
1095     default:
1096       pllvco = (HSI_VALUE / pllm) * (READ_BIT(RCC->PLLCFGR, RCC_PLLCFGR_PLLN) >> RCC_PLLCFGR_PLLN_Pos);
1097       break;
1098     }
1099     pllr = ((READ_BIT(RCC->PLLCFGR, RCC_PLLCFGR_PLLR) >> RCC_PLLCFGR_PLLR_Pos) + 1U ) * 2U;
1100     sysclockfreq = pllvco/pllr;
1101   }
1102   else
1103   {
1104     sysclockfreq = 0U;
1105   }
1106 
1107   return sysclockfreq;
1108 }
1109 
1110 /**
1111   * @brief  Return the HCLK frequency.
1112   * @note   Each time HCLK changes, this function must be called to update the
1113   *         right HCLK value. Otherwise, any configuration based on this function will be incorrect.
1114   *
1115   * @note   The SystemCoreClock CMSIS variable is used to store System Clock Frequency.
1116   * @retval HCLK frequency in Hz
1117   */
HAL_RCC_GetHCLKFreq(void)1118 uint32_t HAL_RCC_GetHCLKFreq(void)
1119 {
1120   return SystemCoreClock;
1121 }
1122 
1123 /**
1124   * @brief  Return the PCLK1 frequency.
1125   * @note   Each time PCLK1 changes, this function must be called to update the
1126   *         right PCLK1 value. Otherwise, any configuration based on this function will be incorrect.
1127   * @retval PCLK1 frequency in Hz
1128   */
HAL_RCC_GetPCLK1Freq(void)1129 uint32_t HAL_RCC_GetPCLK1Freq(void)
1130 {
1131   /* Get HCLK source and Compute PCLK1 frequency ---------------------------*/
1132   return (HAL_RCC_GetHCLKFreq() >> (APBPrescTable[READ_BIT(RCC->CFGR, RCC_CFGR_PPRE1) >> RCC_CFGR_PPRE1_Pos] & 0x1FU));
1133 }
1134 
1135 /**
1136   * @brief  Return the PCLK2 frequency.
1137   * @note   Each time PCLK2 changes, this function must be called to update the
1138   *         right PCLK2 value. Otherwise, any configuration based on this function will be incorrect.
1139   * @retval PCLK2 frequency in Hz
1140   */
HAL_RCC_GetPCLK2Freq(void)1141 uint32_t HAL_RCC_GetPCLK2Freq(void)
1142 {
1143   /* Get HCLK source and Compute PCLK2 frequency ---------------------------*/
1144   return (HAL_RCC_GetHCLKFreq()>> (APBPrescTable[READ_BIT(RCC->CFGR, RCC_CFGR_PPRE2) >> RCC_CFGR_PPRE2_Pos] & 0x1FU));
1145 }
1146 
1147 /**
1148   * @brief  Configure the RCC_OscInitStruct according to the internal
1149   *         RCC configuration registers.
1150   * @param  RCC_OscInitStruct  pointer to an RCC_OscInitTypeDef structure that
1151   *         will be configured.
1152   * @retval None
1153   */
HAL_RCC_GetOscConfig(RCC_OscInitTypeDef * RCC_OscInitStruct)1154 void HAL_RCC_GetOscConfig(RCC_OscInitTypeDef  *RCC_OscInitStruct)
1155 {
1156   /* Check the parameters */
1157   assert_param(RCC_OscInitStruct != (void *)NULL);
1158 
1159   /* Set all possible values for the Oscillator type parameter ---------------*/
1160   RCC_OscInitStruct->OscillatorType = RCC_OSCILLATORTYPE_HSE | RCC_OSCILLATORTYPE_HSI | \
1161                                       RCC_OSCILLATORTYPE_LSE | RCC_OSCILLATORTYPE_LSI | RCC_OSCILLATORTYPE_HSI48;
1162 
1163   /* Get the HSE configuration -----------------------------------------------*/
1164   if(READ_BIT(RCC->CR, RCC_CR_HSEBYP) == RCC_CR_HSEBYP)
1165   {
1166     RCC_OscInitStruct->HSEState = RCC_HSE_BYPASS;
1167   }
1168   else if(READ_BIT(RCC->CR, RCC_CR_HSEON) == RCC_CR_HSEON)
1169   {
1170     RCC_OscInitStruct->HSEState = RCC_HSE_ON;
1171   }
1172   else
1173   {
1174     RCC_OscInitStruct->HSEState = RCC_HSE_OFF;
1175   }
1176 
1177   /* Get the HSI configuration -----------------------------------------------*/
1178   if(READ_BIT(RCC->CR, RCC_CR_HSION) == RCC_CR_HSION)
1179   {
1180     RCC_OscInitStruct->HSIState = RCC_HSI_ON;
1181   }
1182   else
1183   {
1184     RCC_OscInitStruct->HSIState = RCC_HSI_OFF;
1185   }
1186 
1187   RCC_OscInitStruct->HSICalibrationValue = READ_BIT(RCC->ICSCR, RCC_ICSCR_HSITRIM) >> RCC_ICSCR_HSITRIM_Pos;
1188 
1189   /* Get the LSE configuration -----------------------------------------------*/
1190   if(READ_BIT(RCC->BDCR, RCC_BDCR_LSEBYP) == RCC_BDCR_LSEBYP)
1191   {
1192     RCC_OscInitStruct->LSEState = RCC_LSE_BYPASS;
1193   }
1194   else if(READ_BIT(RCC->BDCR, RCC_BDCR_LSEON) == RCC_BDCR_LSEON)
1195   {
1196     RCC_OscInitStruct->LSEState = RCC_LSE_ON;
1197   }
1198   else
1199   {
1200     RCC_OscInitStruct->LSEState = RCC_LSE_OFF;
1201   }
1202 
1203   /* Get the LSI configuration -----------------------------------------------*/
1204   if(READ_BIT(RCC->CSR, RCC_CSR_LSION) == RCC_CSR_LSION)
1205   {
1206     RCC_OscInitStruct->LSIState = RCC_LSI_ON;
1207   }
1208   else
1209   {
1210     RCC_OscInitStruct->LSIState = RCC_LSI_OFF;
1211   }
1212 
1213   /* Get the HSI48 configuration ---------------------------------------------*/
1214   if(READ_BIT(RCC->CRRCR, RCC_CRRCR_HSI48ON) == RCC_CRRCR_HSI48ON)
1215   {
1216     RCC_OscInitStruct->HSI48State = RCC_HSI48_ON;
1217   }
1218   else
1219   {
1220     RCC_OscInitStruct->HSI48State = RCC_HSI48_OFF;
1221   }
1222 
1223   /* Get the PLL configuration -----------------------------------------------*/
1224   if(READ_BIT(RCC->CR, RCC_CR_PLLON) == RCC_CR_PLLON)
1225   {
1226     RCC_OscInitStruct->PLL.PLLState = RCC_PLL_ON;
1227   }
1228   else
1229   {
1230     RCC_OscInitStruct->PLL.PLLState = RCC_PLL_OFF;
1231   }
1232   RCC_OscInitStruct->PLL.PLLSource = READ_BIT(RCC->PLLCFGR, RCC_PLLCFGR_PLLSRC);
1233   RCC_OscInitStruct->PLL.PLLM = (READ_BIT(RCC->PLLCFGR, RCC_PLLCFGR_PLLM) >> RCC_PLLCFGR_PLLM_Pos) + 1U;
1234   RCC_OscInitStruct->PLL.PLLN = READ_BIT(RCC->PLLCFGR, RCC_PLLCFGR_PLLN) >> RCC_PLLCFGR_PLLN_Pos;
1235   RCC_OscInitStruct->PLL.PLLQ = (((READ_BIT(RCC->PLLCFGR, RCC_PLLCFGR_PLLQ) >> RCC_PLLCFGR_PLLQ_Pos) + 1U) << 1U);
1236   RCC_OscInitStruct->PLL.PLLR = (((READ_BIT(RCC->PLLCFGR, RCC_PLLCFGR_PLLR) >> RCC_PLLCFGR_PLLR_Pos) + 1U) << 1U);
1237   RCC_OscInitStruct->PLL.PLLP = READ_BIT(RCC->PLLCFGR, RCC_PLLCFGR_PLLPDIV) >> RCC_PLLCFGR_PLLPDIV_Pos;
1238 }
1239 
1240 /**
1241   * @brief  Configure the RCC_ClkInitStruct according to the internal
1242   *         RCC configuration registers.
1243   * @param  RCC_ClkInitStruct  pointer to an RCC_ClkInitTypeDef structure that
1244   *         will be configured.
1245   * @param  pFLatency  Pointer on the Flash Latency.
1246   * @retval None
1247   */
HAL_RCC_GetClockConfig(RCC_ClkInitTypeDef * RCC_ClkInitStruct,uint32_t * pFLatency)1248 void HAL_RCC_GetClockConfig(RCC_ClkInitTypeDef  *RCC_ClkInitStruct, uint32_t *pFLatency)
1249 {
1250   /* Check the parameters */
1251   assert_param(RCC_ClkInitStruct != (void  *)NULL);
1252   assert_param(pFLatency != (void *)NULL);
1253 
1254   /* Set all possible values for the Clock type parameter --------------------*/
1255   RCC_ClkInitStruct->ClockType = RCC_CLOCKTYPE_SYSCLK | RCC_CLOCKTYPE_HCLK | RCC_CLOCKTYPE_PCLK1 | RCC_CLOCKTYPE_PCLK2;
1256 
1257   /* Get the SYSCLK configuration --------------------------------------------*/
1258   RCC_ClkInitStruct->SYSCLKSource = READ_BIT(RCC->CFGR, RCC_CFGR_SW);
1259 
1260   /* Get the HCLK configuration ----------------------------------------------*/
1261   RCC_ClkInitStruct->AHBCLKDivider = READ_BIT(RCC->CFGR, RCC_CFGR_HPRE);
1262 
1263   /* Get the APB1 configuration ----------------------------------------------*/
1264   RCC_ClkInitStruct->APB1CLKDivider = READ_BIT(RCC->CFGR, RCC_CFGR_PPRE1);
1265 
1266   /* Get the APB2 configuration ----------------------------------------------*/
1267   RCC_ClkInitStruct->APB2CLKDivider = (READ_BIT(RCC->CFGR, RCC_CFGR_PPRE2) >> 3U);
1268 
1269   /* Get the Flash Wait State (Latency) configuration ------------------------*/
1270   *pFLatency = __HAL_FLASH_GET_LATENCY();
1271 }
1272 
1273 /**
1274   * @brief  Enable the Clock Security System.
1275   * @note   If a failure is detected on the HSE oscillator clock, this oscillator
1276   *         is automatically disabled and an interrupt is generated to inform the
1277   *         software about the failure (Clock Security System Interrupt, CSSI),
1278   *         allowing the MCU to perform rescue operations. The CSSI is linked to
1279   *         the Cortex-M4 NMI (Non-Maskable Interrupt) exception vector.
1280   * @note   The Clock Security System can only be cleared by reset.
1281   * @retval None
1282   */
HAL_RCC_EnableCSS(void)1283 void HAL_RCC_EnableCSS(void)
1284 {
1285   SET_BIT(RCC->CR, RCC_CR_CSSON) ;
1286 }
1287 
1288 /**
1289   * @brief  Enable the LSE Clock Security System.
1290   * @note   If a failure is detected on the external 32 kHz oscillator,
1291   *         the LSE clock is no longer supplied to the RTC but no hardware action
1292   *         is made to the registers. If enabled, an interrupt will be generated
1293   *         and handle through @ref RCCEx_EXTI_LINE_LSECSS
1294   * @note   The Clock Security System can only be cleared by reset or after a LSE failure detection.
1295   * @retval None
1296   */
HAL_RCC_EnableLSECSS(void)1297 void HAL_RCC_EnableLSECSS(void)
1298 {
1299   SET_BIT(RCC->BDCR, RCC_BDCR_LSECSSON) ;
1300 }
1301 
1302 /**
1303   * @brief  Disable the LSE Clock Security System.
1304   * @note   After LSE failure detection, the software must disable LSECSSON
1305   * @note   The Clock Security System can only be cleared by reset otherwise.
1306   * @retval None
1307   */
HAL_RCC_DisableLSECSS(void)1308 void HAL_RCC_DisableLSECSS(void)
1309 {
1310   CLEAR_BIT(RCC->BDCR, RCC_BDCR_LSECSSON) ;
1311 }
1312 
1313 /**
1314   * @brief Handle the RCC Clock Security System interrupt request.
1315   * @note This API should be called under the NMI_Handler().
1316   * @retval None
1317   */
HAL_RCC_NMI_IRQHandler(void)1318 void HAL_RCC_NMI_IRQHandler(void)
1319 {
1320   /* Check RCC CSSF interrupt flag  */
1321   if(__HAL_RCC_GET_IT(RCC_IT_CSS))
1322   {
1323     /* RCC Clock Security System interrupt user callback */
1324     HAL_RCC_CSSCallback();
1325 
1326     /* Clear RCC CSS pending bit */
1327     __HAL_RCC_CLEAR_IT(RCC_IT_CSS);
1328   }
1329 }
1330 
1331 /**
1332   * @brief  RCC Clock Security System interrupt callback.
1333   * @retval none
1334   */
HAL_RCC_CSSCallback(void)1335 __weak void HAL_RCC_CSSCallback(void)
1336 {
1337   /* NOTE : This function should not be modified, when the callback is needed,
1338             the HAL_RCC_CSSCallback should be implemented in the user file
1339    */
1340 }
1341 
1342 /**
1343   * @}
1344   */
1345 
1346 /**
1347   * @}
1348   */
1349 
1350 /* Private function prototypes -----------------------------------------------*/
1351 /** @addtogroup RCC_Private_Functions
1352   * @{
1353   */
1354 
1355 /**
1356   * @brief  Compute SYSCLK frequency based on PLL SYSCLK source.
1357   * @retval SYSCLK frequency
1358   */
RCC_GetSysClockFreqFromPLLSource(void)1359 static uint32_t RCC_GetSysClockFreqFromPLLSource(void)
1360 {
1361   uint32_t pllvco, pllsource, pllr, pllm;
1362   uint32_t sysclockfreq;
1363 
1364   /* PLL_VCO = (HSE_VALUE or HSI_VALUE/ PLLM) * PLLN
1365      SYSCLK = PLL_VCO / PLLR
1366    */
1367   pllsource = READ_BIT(RCC->PLLCFGR, RCC_PLLCFGR_PLLSRC);
1368   pllm = (READ_BIT(RCC->PLLCFGR, RCC_PLLCFGR_PLLM) >> RCC_PLLCFGR_PLLM_Pos) + 1U ;
1369 
1370   switch (pllsource)
1371   {
1372   case RCC_PLLSOURCE_HSE:  /* HSE used as PLL clock source */
1373     pllvco = (HSE_VALUE / pllm) * (READ_BIT(RCC->PLLCFGR, RCC_PLLCFGR_PLLN) >> RCC_PLLCFGR_PLLN_Pos);
1374     break;
1375 
1376   case RCC_PLLSOURCE_HSI:  /* HSI used as PLL clock source */
1377   default:
1378     pllvco = (HSI_VALUE / pllm) * (READ_BIT(RCC->PLLCFGR, RCC_PLLCFGR_PLLN) >> RCC_PLLCFGR_PLLN_Pos);
1379     break;
1380   }
1381 
1382   pllr = ((READ_BIT(RCC->PLLCFGR, RCC_PLLCFGR_PLLR) >> RCC_PLLCFGR_PLLR_Pos) + 1U ) * 2U;
1383   sysclockfreq = pllvco/pllr;
1384 
1385   return sysclockfreq;
1386 }
1387 
1388 /**
1389   * @}
1390   */
1391 
1392 #endif /* HAL_RCC_MODULE_ENABLED */
1393 /**
1394   * @}
1395   */
1396 
1397 /**
1398   * @}
1399   */
1400 
1401