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