source: trunk/firmware/Drivers/STM32G0xx_HAL_Driver/Src/stm32g0xx_hal_rcc.c

Last change on this file was 6, checked in by f.jahn, 3 months ago
File size: 54.4 KB
Line 
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  */
217HAL_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  */
309HAL_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  */
805HAL_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  */
1040void 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  */
1128uint32_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  */
1196uint32_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  */
1207uint32_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  */
1220void 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  */
1323void 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  */
1356void 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  */
1372void 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  */
1383void 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  */
1393void 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  */
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  */
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  */
1443uint32_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
Note: See TracBrowser for help on using the repository browser.