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