1 /**
2   ******************************************************************************
3   * @file    stm32c0xx_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   ******************************************************************************
12   * @attention
13   *
14   * Copyright (c) 2022 STMicroelectronics.
15   * All rights reserved.
16   *
17   * This software is licensed under terms that can be found in the LICENSE file
18   * in the root directory of this software component.
19   * If no LICENSE file comes with this software, it is provided AS-IS.
20   *
21   ******************************************************************************
22   @verbatim
23   ==============================================================================
24                       ##### RCC specific features #####
25   ==============================================================================
26     [..]
27       After reset the device is running from High Speed Internal oscillator
28       divided by 4 that is the default system clock with Flash 0 wait state.
29 
30       (+) There is no prescaler on High speed (AHB) and Low speed (APB) busses:
31           all peripherals mapped on these busses are running at HSI speed.
32       (+) The clock for all peripherals is switched off, except the SRAM and FLASH.
33       (+) All GPIOs are in analog mode
34 
35     [..]
36       Once the device started from reset, the user application has to:
37       (+) Configure the clock source to be used to drive the System clock
38           (if the application needs higher frequency/performance)
39       (+) Configure the System clock frequency and Flash settings
40       (+) Configure the AHB and APB busses prescalers
41       (+) Enable the clock for the peripheral(s) to be used
42       (+) Configure the clock source(s) for peripherals which clocks are not
43           derived from the System clock (RTC, ADC, USART, I2C, I2S)
44 
45   @endverbatim
46   ******************************************************************************
47   */
48 
49 /* Includes ------------------------------------------------------------------*/
50 #include "stm32c0xx_hal.h"
51 
52 /** @addtogroup STM32C0xx_HAL_Driver
53   * @{
54   */
55 
56 /** @defgroup RCC RCC
57   * @brief RCC HAL module driver
58   * @{
59   */
60 
61 #ifdef HAL_RCC_MODULE_ENABLED
62 
63 /* Private typedef -----------------------------------------------------------*/
64 /* Private define ------------------------------------------------------------*/
65 /** @defgroup RCC_Private_Constants RCC Private Constants
66   * @{
67   */
68 #define RCC_HSE_TIMEOUT_VALUE          HSE_STARTUP_TIMEOUT
69 #define RCC_HSI_TIMEOUT_VALUE          (2U)    /* 2 ms (minimum Tick + 1) */
70 #define RCC_LSI_TIMEOUT_VALUE          (2U)    /* 2 ms (minimum Tick + 1) */
71 #if defined(RCC_CR_HSIUSB48ON)
72 #define HSI48_TIMEOUT_VALUE            (2U)    /* 2 ms (minimum Tick + 1) */
73 #endif /* RCC_CR_HSIUSB48ON */
74 #define RCC_CLOCKSWITCH_TIMEOUT_VALUE  (5000U) /* 5 s    */
75 
76 /**
77   * @}
78   */
79 
80 /* Private macro -------------------------------------------------------------*/
81 /** @defgroup RCC_Private_Macros RCC Private Macros
82   * @{
83   */
84 #define RCC_GET_MCO_GPIO_PIN(__RCC_MCOx__)   ((__RCC_MCOx__) & GPIO_PIN_MASK)
85 
86 #define RCC_GET_MCO_GPIO_AF(__RCC_MCOx__)    (((__RCC_MCOx__) & RCC_MCO_GPIOAF_MASK) >> RCC_MCO_GPIOAF_POS)
87 
88 #define RCC_GET_MCO_GPIO_INDEX(__RCC_MCOx__) (((__RCC_MCOx__) & RCC_MCO_GPIOPORT_MASK) >> RCC_MCO_GPIOPORT_POS)
89 
90 #define RCC_GET_MCO_GPIO_PORT(__RCC_MCOx__)  (IOPORT_BASE + ((0x00000400UL) * RCC_GET_MCO_GPIO_INDEX((__RCC_MCOx__))))
91 
92 /**
93   * @}
94   */
95 
96 /* Private variables ---------------------------------------------------------*/
97 /** @defgroup RCC_Private_Variables RCC Private Variables
98   * @{
99   */
100 
101 /**
102   * @}
103   */
104 
105 /* Private function prototypes -----------------------------------------------*/
106 /* Exported functions --------------------------------------------------------*/
107 
108 /** @defgroup RCC_Exported_Functions RCC Exported Functions
109   * @{
110   */
111 
112 /** @defgroup RCC_Exported_Functions_Group1 Initialization and de-initialization functions
113   *  @brief    Initialization and Configuration functions
114   *
115   @verbatim
116  ===============================================================================
117            ##### Initialization and de-initialization functions #####
118  ===============================================================================
119     [..]
120       This section provides functions allowing to configure the internal and external oscillators
121       (HSE, HSI, LSE, LSI, CSS and MCO) and the System busses clocks (SYSCLK, AHB, APB)
122 
123     [..] Internal/external clock
124          (+) HSI (high-speed internal): 48 MHz factory-trimmed RC used directly as System clock source.
125 
126          (+) LSI (low-speed internal): 32 KHz low consumption RC used as IWDG and/or RTC
127              clock source.
128 
129          (+) HSE (high-speed external): 4 to 48 MHz crystal oscillator used directly or
130              through the PLL as System clock source. Can be used also optionally as RTC clock source.
131 
132          (+) LSE (low-speed external): 32.768 KHz oscillator used optionally as RTC clock source.
133 
134          (+) CSS (Clock security system): once enabled, if a HSE or LSE clock failure occurs,
135              the System clock is automatically switched respectively to HSI or LSI and an interrupt
136              is generated if enabled. The interrupt is linked to the Cortex-M0+ NMI (Non-Maskable Interrupt)
137              exception vector.
138 
139          (+) MCOx (microcontroller clock output): used to output LSI, HSI, LSE, HSE and SYSCLK on different pins.
140 
141     [..] System, AHB and APB busses clocks configuration
142          (+) Several clock sources can be used to drive the System clock (SYSCLK): HSI,
143              HSE, LSI and LSE.
144              The AHB clock (HCLK) is derived from System clock through configurable
145              prescaler and used to clock the CPU, memory and peripherals mapped
146              on AHB bus (DMA, GPIO...).and APB (PCLK1) clock is derived
147              from AHB clock through configurable prescalers and used to clock
148              the peripherals mapped on these busses. You can use
149              "@ref HAL_RCC_GetSysClockFreq()" function to retrieve the frequencies of these clocks.
150 
151          -@- All the peripheral clocks are derived from the System clock (SYSCLK) except:
152 
153             (+@) RTC: the RTC clock can be derived either from the LSI, LSE or HSE clock
154                 divided by 2 to 31.
155                 You have to use @ref __HAL_RCC_RTC_ENABLE() and @ref HAL_RCCEx_PeriphCLKConfig() function
156                  to configure this clock.
157 
158             (+@) ADC: the ADC clock can be derived either from system clock or HSI
159 
160             (+@) USART: the USART clock can be derived either from APB clock or HSI or LSE
161             (+@) I2C: the I2C clock can be derived either from system clock or HSI
162 
163             (+@) I2S: the I2S clock can be derived either from system clock or HSI or external clock source
164 
165          (+) The maximum frequency of the SYSCLK, HCLK, PCLK is 48 MHz.
166 
167   @endverbatim
168 
169      (++)  Table 1. HCLK clock frequency.
170      (++)  +------------------------------------+
171      (++)  | Latency         |    HCLK clock    |
172      (++)  |                 |  frequency (MHz) |
173      (++)  |                 |------------------|
174      (++)  |                 | voltage range    |
175      (++)  |                 |  VDD33 2V - 3.6V |
176      (++)  |                 |  VDD12 1V - 1.32V|
177      (++)  |-----------------|------------------|
178      (++)  |0WS(1 CPU cycles)|  HCLK <= 24      |
179      (++)  |-----------------|------------------|
180      (++)  |1WS(2 CPU cycles)|  HCLK <= 48      |
181      (++)  +------------------------------------+
182      (++)
183    * @{
184   */
185 
186 /**
187   * @brief  Reset the RCC clock configuration to the default reset state.
188   * @note   The default reset state of the clock configuration is given below:
189   *            - HSI ON and used as system clock source
190   *            - HSE OFF
191   *            - SYSDIV, AHB and APB prescaler set to 1.
192   *            - CSS, MCO1, MCO2 OFF
193   *            - All interrupts disabled
194   * @note   This function does not modify the configuration of the
195   *            - Peripheral clocks
196   *            - LSI, LSE and RTC clocks
197   * @retval HAL status
198   */
HAL_RCC_DeInit(void)199 HAL_StatusTypeDef HAL_RCC_DeInit(void)
200 {
201   uint32_t tickstart;
202 
203   /* Get Start Tick*/
204   tickstart = HAL_GetTick();
205 
206   /* Set HSION bit to the reset value */
207   SET_BIT(RCC->CR, RCC_CR_HSION);
208 
209   /* Wait till HSI is ready */
210   while (READ_BIT(RCC->CR, RCC_CR_HSIRDY) == 0U)
211   {
212     if ((HAL_GetTick() - tickstart) > RCC_HSI_TIMEOUT_VALUE)
213     {
214       return HAL_TIMEOUT;
215     }
216   }
217 
218   /* Set HSITRIM[6:0] bits to the reset value */
219   RCC->ICSCR = RCC_ICSCR_HSITRIM_6;
220 
221   /* Get Start Tick*/
222   tickstart = HAL_GetTick();
223 
224   /* Reset CFGR register (HSI is selected as system clock source) */
225   RCC->CFGR = 0x00000000u;
226 
227   /* Wait till HSI is ready */
228   while (READ_BIT(RCC->CFGR, RCC_CFGR_SWS) != 0U)
229   {
230     if ((HAL_GetTick() - tickstart) > RCC_CLOCKSWITCH_TIMEOUT_VALUE)
231     {
232       return HAL_TIMEOUT;
233     }
234   }
235 
236   /* Get Start Tick*/
237   tickstart = HAL_GetTick();
238 
239   /* Clear CR register in 2 steps: first to clear HSEON in case bypass was enabled */
240   RCC->CR &= ~RCC_CR_HSEON;
241 
242   /* Wait till HSEON is disabled */
243   while (READ_BIT(RCC->CR, RCC_CR_HSERDY) != 0U)
244   {
245     if ((HAL_GetTick() - tickstart) > RCC_HSE_TIMEOUT_VALUE)
246     {
247       return HAL_TIMEOUT;
248     }
249   }
250 
251   /* Then again to HSEBYP in case bypass was enabled */
252   RCC->CR &= ~RCC_CR_HSEBYP;
253 
254   /* Disable all interrupts */
255   RCC->CIER = 0x00000000u;
256 
257   /* Clear all flags */
258   RCC->CICR = 0xFFFFFFFFu;
259 
260   /* Update the SystemCoreClock global variable */
261   SystemCoreClock = HSI_VALUE;
262 
263   /* Adapt Systick interrupt period */
264   if (HAL_InitTick(uwTickPrio) != HAL_OK)
265   {
266     return HAL_ERROR;
267   }
268   else
269   {
270     return HAL_OK;
271   }
272 }
273 
274 /**
275   * @brief  Initialize the RCC Oscillators according to the specified parameters in the
276   *         @ref RCC_OscInitTypeDef.
277   * @param  RCC_OscInitStruct pointer to a @ref RCC_OscInitTypeDef structure that
278   *         contains the configuration information for the RCC Oscillators.
279   * @note   Transition HSE Bypass to HSE On and HSE On to HSE Bypass are not
280   *         supported by this function. User should request a transition to HSE Off
281   *         first and then to HSE On or HSE Bypass.
282   * @note   Transition LSE Bypass to LSE On and LSE On to LSE Bypass are not
283   *         supported by this function. User should request a transition to LSE Off
284   *         first and then to LSE On or LSE Bypass.
285   * @retval HAL status
286   */
HAL_RCC_OscConfig(const RCC_OscInitTypeDef * RCC_OscInitStruct)287 HAL_StatusTypeDef HAL_RCC_OscConfig(const RCC_OscInitTypeDef  *RCC_OscInitStruct)
288 {
289   uint32_t tickstart;
290   uint32_t temp_sysclksrc;
291 
292   /* Check Null pointer */
293   if (RCC_OscInitStruct == NULL)
294   {
295     return HAL_ERROR;
296   }
297 
298   /* Check the parameters */
299   assert_param(IS_RCC_OSCILLATORTYPE(RCC_OscInitStruct->OscillatorType));
300 
301   /*------------------------------- HSE Configuration ------------------------*/
302   if (((RCC_OscInitStruct->OscillatorType) & RCC_OSCILLATORTYPE_HSE) == RCC_OSCILLATORTYPE_HSE)
303   {
304     /* Check the parameters */
305     assert_param(IS_RCC_HSE(RCC_OscInitStruct->HSEState));
306 
307     temp_sysclksrc = __HAL_RCC_GET_SYSCLK_SOURCE();
308 
309     /* When the HSE is used as system clock in these cases it is not allowed to be disabled */
310     if (temp_sysclksrc == RCC_CFGR_SWS_HSE)
311     {
312       if (RCC_OscInitStruct->HSEState == RCC_HSE_OFF)
313       {
314         return HAL_ERROR;
315       }
316     }
317     else
318     {
319       /* Set the new HSE configuration ---------------------------------------*/
320       __HAL_RCC_HSE_CONFIG(RCC_OscInitStruct->HSEState);
321 
322       /* Check the HSE State */
323       if (RCC_OscInitStruct->HSEState != RCC_HSE_OFF)
324       {
325         /* Get Start Tick*/
326         tickstart = HAL_GetTick();
327 
328         /* Wait till HSE is ready */
329         while (READ_BIT(RCC->CR, RCC_CR_HSERDY) == 0U)
330         {
331           if ((HAL_GetTick() - tickstart) > RCC_HSE_TIMEOUT_VALUE)
332           {
333             return HAL_TIMEOUT;
334           }
335         }
336       }
337       else
338       {
339         /* Get Start Tick*/
340         tickstart = HAL_GetTick();
341 
342         /* Wait till HSE is disabled */
343         while (READ_BIT(RCC->CR, RCC_CR_HSERDY) != 0U)
344         {
345           if ((HAL_GetTick() - tickstart) > RCC_HSE_TIMEOUT_VALUE)
346           {
347             return HAL_TIMEOUT;
348           }
349         }
350       }
351     }
352   }
353   /*----------------------------- HSI Configuration --------------------------*/
354   if (((RCC_OscInitStruct->OscillatorType) & RCC_OSCILLATORTYPE_HSI) == RCC_OSCILLATORTYPE_HSI)
355   {
356     /* Check the parameters */
357     assert_param(IS_RCC_HSI(RCC_OscInitStruct->HSIState));
358     assert_param(IS_RCC_HSI_CALIBRATION_VALUE(RCC_OscInitStruct->HSICalibrationValue));
359     assert_param(IS_RCC_HSIDIV(RCC_OscInitStruct->HSIDiv));
360 
361     /* Check if HSI48 is used as system clock  */
362     temp_sysclksrc = __HAL_RCC_GET_SYSCLK_SOURCE();
363 
364     if (temp_sysclksrc == RCC_CFGR_SWS_HSI)
365     {
366       /* When HSI is used as system clock it can not be disabled */
367       if (RCC_OscInitStruct->HSIState == RCC_HSI_OFF)
368       {
369         return HAL_ERROR;
370       }
371       /* Otherwise, just the calibration is allowed */
372       else
373       {
374         /* Adjusts the Internal High Speed oscillator (HSI) calibration value.*/
375         __HAL_RCC_HSI_CALIBRATIONVALUE_ADJUST(RCC_OscInitStruct->HSICalibrationValue);
376 
377         if (temp_sysclksrc == RCC_CFGR_SWS_HSI)
378         {
379           /* Adjust the HSI48 division factor */
380           __HAL_RCC_HSI_CONFIG(RCC_OscInitStruct->HSIDiv);
381 
382           /* Update the SystemCoreClock global variable with HSISYS value  */
383           SystemCoreClock = (HSI_VALUE / (1UL << ((READ_BIT(RCC->CR, RCC_CR_HSIDIV)) >> RCC_CR_HSIDIV_Pos)));
384         }
385 
386         /* Adapt Systick interrupt period */
387         if (HAL_InitTick(uwTickPrio) != HAL_OK)
388         {
389           return HAL_ERROR;
390         }
391       }
392     }
393     else
394     {
395       /* Check the HSI State */
396       if (RCC_OscInitStruct->HSIState != RCC_HSI_OFF)
397       {
398         /* Configure the HSI48 division factor */
399         __HAL_RCC_HSI_CONFIG(RCC_OscInitStruct->HSIDiv);
400 
401         /* Enable the Internal High Speed oscillator (HSI48). */
402         __HAL_RCC_HSI_ENABLE();
403 
404         /* Get Start Tick*/
405         tickstart = HAL_GetTick();
406 
407         /* Wait till HSI is ready */
408         while (READ_BIT(RCC->CR, RCC_CR_HSIRDY) == 0U)
409         {
410           if ((HAL_GetTick() - tickstart) > RCC_HSI_TIMEOUT_VALUE)
411           {
412             return HAL_TIMEOUT;
413           }
414         }
415 
416         /* Adjusts the Internal High Speed oscillator (HSI) calibration value.*/
417         __HAL_RCC_HSI_CALIBRATIONVALUE_ADJUST(RCC_OscInitStruct->HSICalibrationValue);
418       }
419       else
420       {
421         /* Disable the Internal High Speed oscillator (HSI48). */
422         __HAL_RCC_HSI_DISABLE();
423 
424         /* Get Start Tick*/
425         tickstart = HAL_GetTick();
426 
427         /* Wait till HSI is disabled */
428         while (READ_BIT(RCC->CR, RCC_CR_HSIRDY) != 0U)
429         {
430           if ((HAL_GetTick() - tickstart) > RCC_HSI_TIMEOUT_VALUE)
431           {
432             return HAL_TIMEOUT;
433           }
434         }
435       }
436     }
437   }
438   /*------------------------------ LSI Configuration -------------------------*/
439   if (((RCC_OscInitStruct->OscillatorType) & RCC_OSCILLATORTYPE_LSI) == RCC_OSCILLATORTYPE_LSI)
440   {
441     /* Check the parameters */
442     assert_param(IS_RCC_LSI(RCC_OscInitStruct->LSIState));
443 
444     /* Check if LSI is used as system clock */
445     if (__HAL_RCC_GET_SYSCLK_SOURCE() == RCC_CFGR_SWS_LSI)
446     {
447       /* When LSI is used as system clock it will not be disabled */
448       if (RCC_OscInitStruct->LSIState == RCC_LSI_OFF)
449       {
450         return HAL_ERROR;
451       }
452     }
453     else
454     {
455       /* Check the LSI State */
456       if (RCC_OscInitStruct->LSIState != RCC_LSI_OFF)
457       {
458         /* Enable the Internal Low Speed oscillator (LSI). */
459         __HAL_RCC_LSI_ENABLE();
460 
461         /* Get Start Tick*/
462         tickstart = HAL_GetTick();
463 
464         /* Wait till LSI is ready */
465         while (READ_BIT(RCC->CSR2, RCC_CSR2_LSIRDY) == 0U)
466         {
467           if ((HAL_GetTick() - tickstart) > RCC_LSI_TIMEOUT_VALUE)
468           {
469             return HAL_TIMEOUT;
470           }
471         }
472       }
473       else
474       {
475         /* Disable the Internal Low Speed oscillator (LSI). */
476         __HAL_RCC_LSI_DISABLE();
477 
478         /* Get Start Tick*/
479         tickstart = HAL_GetTick();
480 
481         /* Wait till LSI is disabled */
482         while (READ_BIT(RCC->CSR2, RCC_CSR2_LSIRDY) != 0U)
483         {
484           if ((HAL_GetTick() - tickstart) > RCC_LSI_TIMEOUT_VALUE)
485           {
486             return HAL_TIMEOUT;
487           }
488         }
489       }
490     }
491   }
492   /*------------------------------ LSE Configuration -------------------------*/
493   if (((RCC_OscInitStruct->OscillatorType) & RCC_OSCILLATORTYPE_LSE) == RCC_OSCILLATORTYPE_LSE)
494   {
495     FlagStatus       pwrclkchanged = RESET;
496 
497     /* Check the parameters */
498     assert_param(IS_RCC_LSE(RCC_OscInitStruct->LSEState));
499 
500     /* When the LSE is used as system clock, it is not allowed disable it */
501     if (__HAL_RCC_GET_SYSCLK_SOURCE() == RCC_CFGR_SWS_LSE)
502     {
503       if (RCC_OscInitStruct->LSEState == RCC_LSE_OFF)
504       {
505         return HAL_ERROR;
506       }
507     }
508     else
509     {
510       /* Update LSE configuration in RTC Domain control register    */
511       /* Set the new LSE configuration -----------------------------------------*/
512       __HAL_RCC_LSE_CONFIG(RCC_OscInitStruct->LSEState);
513 
514       /* Check the LSE State */
515       if (RCC_OscInitStruct->LSEState != RCC_LSE_OFF)
516       {
517         /* Get Start Tick*/
518         tickstart = HAL_GetTick();
519 
520         /* Wait till LSE is ready */
521         while (READ_BIT(RCC->CSR1, RCC_CSR1_LSERDY) == 0U)
522         {
523           if ((HAL_GetTick() - tickstart) > RCC_LSE_TIMEOUT_VALUE)
524           {
525             return HAL_TIMEOUT;
526           }
527         }
528       }
529       else
530       {
531         /* Get Start Tick*/
532         tickstart = HAL_GetTick();
533 
534         /* Wait till LSE is disabled */
535         while (READ_BIT(RCC->CSR1, RCC_CSR1_LSERDY) != 0U)
536         {
537           if ((HAL_GetTick() - tickstart) > RCC_LSE_TIMEOUT_VALUE)
538           {
539             return HAL_TIMEOUT;
540           }
541         }
542       }
543 
544       /* Restore clock configuration if changed */
545       if (pwrclkchanged == SET)
546       {
547         __HAL_RCC_PWR_CLK_DISABLE();
548       }
549     }
550   }
551 #if defined(RCC_CR_HSIUSB48ON)
552   /*------------------------------ HSI48 Configuration -----------------------*/
553   if (((RCC_OscInitStruct->OscillatorType) & RCC_OSCILLATORTYPE_HSI48) == RCC_OSCILLATORTYPE_HSI48)
554   {
555     /* Check the parameters */
556     assert_param(IS_RCC_HSI48(RCC_OscInitStruct->HSI48State));
557 
558     /* Check the LSI State */
559     if (RCC_OscInitStruct->HSI48State != RCC_HSI48_OFF)
560     {
561       /* Enable the Internal Low Speed oscillator (HSI48). */
562       __HAL_RCC_HSI48_ENABLE();
563 
564       /* Get Start Tick*/
565       tickstart = HAL_GetTick();
566 
567       /* Wait till HSI48 is ready */
568       while (READ_BIT(RCC->CR, RCC_CR_HSIUSB48RDY) == 0U)
569       {
570         if ((HAL_GetTick() - tickstart) > HSI48_TIMEOUT_VALUE)
571         {
572           return HAL_TIMEOUT;
573         }
574       }
575     }
576     else
577     {
578       /* Disable the Internal Low Speed oscillator (HSI48). */
579       __HAL_RCC_HSI48_DISABLE();
580 
581       /* Get Start Tick*/
582       tickstart = HAL_GetTick();
583 
584       /* Wait till HSI48 is disabled */
585       while (READ_BIT(RCC->CR, RCC_CR_HSIUSB48RDY) != 0U)
586       {
587         if ((HAL_GetTick() - tickstart) > HSI48_TIMEOUT_VALUE)
588         {
589           return HAL_TIMEOUT;
590         }
591       }
592     }
593   }
594 #endif /* RCC_CR_HSIUSB48ON */
595   return HAL_OK;
596 }
597 
598 /**
599   * @brief  Initialize the CPU, AHB and APB busses clocks according to the specified
600   *         parameters in the RCC_ClkInitStruct.
601   * @param  RCC_ClkInitStruct  pointer to a @ref RCC_ClkInitTypeDef structure that
602   *         contains the configuration information for the RCC peripheral.
603   * @param  FLatency  FLASH Latency
604   *          This parameter can be one of the following values:
605   *            @arg FLASH_LATENCY_0   FLASH 0 Latency cycle
606   *            @arg FLASH_LATENCY_1   FLASH 1 Latency cycle
607   *
608   * @note   The SystemCoreClock CMSIS variable is used to store System Clock Frequency
609   *         and updated by @ref HAL_RCC_GetHCLKFreq() function called within this function
610   *
611   * @note   The HSI is used by default as system clock source after
612   *         startup from Reset, wake-up from STANDBY mode. After restart from Reset,
613   *         the HSI frequency is set to 12 Mhz, as HSI divider is set to 4.
614   *
615   * @note   The HSI can be selected as system clock source after
616   *         from STOP modes or in case of failure of the HSE used directly or indirectly
617   *         as system clock (if the Clock Security System CSS is enabled).
618   *
619   * @note   The LSI can be selected as system clock source after
620   *         in case of failure of the LSE used directly or indirectly
621   *         as system clock (if the Clock Security System LSECSS is enabled).
622   *
623   * @note   A switch from one clock source to another occurs only if the target
624   *         clock source is ready (clock stable after startup delay).
625   *         If a clock source which is not yet ready is selected, the switch will
626   *         occur when the clock source is ready.
627   *
628   * @note   You can use @ref HAL_RCC_GetClockConfig() function to know which clock is
629   *         currently used as system clock source.
630   *
631   * @note   Depending on the device voltage range, the software has to set correctly
632   *         HPRE[3:0] bits to ensure that HCLK not exceed the maximum allowed frequency
633   *         (for more details refer to section above "Initialization/de-initialization functions")
634   * @retval None
635   */
HAL_RCC_ClockConfig(const RCC_ClkInitTypeDef * RCC_ClkInitStruct,uint32_t FLatency)636 HAL_StatusTypeDef HAL_RCC_ClockConfig(const RCC_ClkInitTypeDef  *RCC_ClkInitStruct, uint32_t FLatency)
637 {
638   uint32_t tickstart;
639 
640   /* Check Null pointer */
641   if (RCC_ClkInitStruct == NULL)
642   {
643     return HAL_ERROR;
644   }
645 
646   /* Check the parameters */
647   assert_param(IS_RCC_CLOCKTYPE(RCC_ClkInitStruct->ClockType));
648   assert_param(IS_FLASH_LATENCY(FLatency));
649 
650   /* To correctly read data from FLASH memory, the number of wait states (LATENCY)
651     must be correctly programmed according to the frequency of the FLASH clock
652     (HCLK) and the supply voltage of the device. */
653 
654   /* Increasing the number of wait states because of higher CPU frequency */
655   if (FLatency > __HAL_FLASH_GET_LATENCY())
656   {
657     /* Program the new number of wait states to the LATENCY bits in the FLASH_ACR register */
658     __HAL_FLASH_SET_LATENCY(FLatency);
659 
660     /* Check that the new number of wait states is taken into account to access the Flash
661     memory by polling the FLASH_ACR register */
662     tickstart = HAL_GetTick();
663 
664     while ((FLASH->ACR & FLASH_ACR_LATENCY) != FLatency)
665     {
666       if ((HAL_GetTick() - tickstart) > RCC_CLOCKSWITCH_TIMEOUT_VALUE)
667       {
668         return HAL_TIMEOUT;
669       }
670     }
671   }
672 
673   /*-------------------------- HCLK Configuration --------------------------*/
674   if (((RCC_ClkInitStruct->ClockType) & RCC_CLOCKTYPE_HCLK) == RCC_CLOCKTYPE_HCLK)
675   {
676     /* Set the highest APB divider in order to ensure that we do not go through
677        a non-spec phase whatever we decrease or increase HCLK. */
678     if (((RCC_ClkInitStruct->ClockType) & RCC_CLOCKTYPE_PCLK1) == RCC_CLOCKTYPE_PCLK1)
679     {
680       MODIFY_REG(RCC->CFGR, RCC_CFGR_PPRE, RCC_HCLK_DIV16);
681     }
682 
683     /* Set the new HCLK clock divider */
684     assert_param(IS_RCC_HCLK(RCC_ClkInitStruct->AHBCLKDivider));
685     MODIFY_REG(RCC->CFGR, RCC_CFGR_HPRE, RCC_ClkInitStruct->AHBCLKDivider);
686   }
687 
688   /*------------------------- SYSCLK Configuration ---------------------------*/
689   if (((RCC_ClkInitStruct->ClockType) & RCC_CLOCKTYPE_SYSCLK) == RCC_CLOCKTYPE_SYSCLK)
690   {
691     assert_param(IS_RCC_SYSCLK(RCC_ClkInitStruct->SYSCLKDivider));
692     assert_param(IS_RCC_SYSCLKSOURCE(RCC_ClkInitStruct->SYSCLKSource));
693 
694 #if defined(RCC_CR_SYSDIV)
695     MODIFY_REG(RCC->CR, RCC_CR_SYSDIV, RCC_ClkInitStruct->SYSCLKDivider);
696 #endif /* RCC_CR_SYSDIV */
697 
698     /* HSE is selected as System Clock Source */
699     if (RCC_ClkInitStruct->SYSCLKSource == RCC_SYSCLKSOURCE_HSE)
700     {
701       /* Check the HSE ready flag */
702       if (READ_BIT(RCC->CR, RCC_CR_HSERDY) == 0U)
703       {
704         return HAL_ERROR;
705       }
706     }
707     /* HSI is selected as System Clock Source */
708     else if (RCC_ClkInitStruct->SYSCLKSource == RCC_SYSCLKSOURCE_HSI)
709     {
710       /* Check the HSI ready flag */
711       if (READ_BIT(RCC->CR, RCC_CR_HSIRDY) == 0U)
712       {
713         return HAL_ERROR;
714       }
715     }
716 #if defined(RCC_HSI48_SUPPORT)
717     /* HSIUSB48 is selected as System Clock Source */
718     else if (RCC_ClkInitStruct->SYSCLKSource == RCC_SYSCLKSOURCE_HSIUSB48)
719     {
720       /* Check the HSIUSB48 ready flag */
721       if (READ_BIT(RCC->CR, RCC_CR_HSIUSB48RDY) == 0U)
722       {
723         return HAL_ERROR;
724       }
725     }
726 #endif /* RCC_HSI48_SUPPORT */
727     /* LSI is selected as System Clock Source */
728     else if (RCC_ClkInitStruct->SYSCLKSource == RCC_SYSCLKSOURCE_LSI)
729     {
730       /* Check the LSI ready flag */
731       if (READ_BIT(RCC->CSR2, RCC_CSR2_LSIRDY) == 0U)
732       {
733         return HAL_ERROR;
734       }
735     }
736     /* LSE is selected as System Clock Source */
737     else
738     {
739       /* Check the LSE ready flag */
740       if (READ_BIT(RCC->CSR1, RCC_CSR1_LSERDY) == 0U)
741       {
742         return HAL_ERROR;
743       }
744     }
745     MODIFY_REG(RCC->CFGR, RCC_CFGR_SW, RCC_ClkInitStruct->SYSCLKSource);
746 
747     /* Get Start Tick*/
748     tickstart = HAL_GetTick();
749 
750     while (__HAL_RCC_GET_SYSCLK_SOURCE() != (RCC_ClkInitStruct->SYSCLKSource << RCC_CFGR_SWS_Pos))
751     {
752       if ((HAL_GetTick() - tickstart) > RCC_CLOCKSWITCH_TIMEOUT_VALUE)
753       {
754         return HAL_TIMEOUT;
755       }
756     }
757   }
758 
759   /* Decreasing the number of wait states because of lower CPU frequency */
760   if (FLatency < __HAL_FLASH_GET_LATENCY())
761   {
762     /* Program the new number of wait states to the LATENCY bits in the FLASH_ACR register */
763     __HAL_FLASH_SET_LATENCY(FLatency);
764 
765     /* Check that the new number of wait states is taken into account to access the Flash
766     memory by polling the FLASH_ACR register */
767     tickstart = HAL_GetTick();
768 
769     while ((FLASH->ACR & FLASH_ACR_LATENCY) != FLatency)
770     {
771       if ((HAL_GetTick() - tickstart) > RCC_CLOCKSWITCH_TIMEOUT_VALUE)
772       {
773         return HAL_TIMEOUT;
774       }
775     }
776   }
777 
778   /*-------------------------- PCLK1 Configuration ---------------------------*/
779   if (((RCC_ClkInitStruct->ClockType) & RCC_CLOCKTYPE_PCLK1) == RCC_CLOCKTYPE_PCLK1)
780   {
781     assert_param(IS_RCC_PCLK(RCC_ClkInitStruct->APB1CLKDivider));
782     MODIFY_REG(RCC->CFGR, RCC_CFGR_PPRE, RCC_ClkInitStruct->APB1CLKDivider);
783   }
784 
785   /* Update the SystemCoreClock global variable */
786   SystemCoreClock = (HAL_RCC_GetSysClockFreq() >> ((AHBPrescTable[(RCC->CFGR & RCC_CFGR_HPRE) \
787                                                                   >> RCC_CFGR_HPRE_Pos]) & 0x1FU));
788 
789   /* Configure the source of time base considering new system clocks settings*/
790   return HAL_InitTick(uwTickPrio);
791 }
792 
793 /**
794   * @}
795   */
796 
797 /** @defgroup RCC_Exported_Functions_Group2 Peripheral Control functions
798   *  @brief   RCC clocks control functions
799   *
800 @verbatim
801  ===============================================================================
802                       ##### Peripheral Control functions #####
803  ===============================================================================
804     [..]
805     This subsection provides a set of functions allowing to:
806 
807     (+) output clock to MCO pin.
808     (+) Retrieve current clock frequencies.
809     (+) Enable the Clock Security System.
810 
811 @endverbatim
812   * @{
813   */
814 
815 /**
816   * @brief  Select the clock source to output on MCOx pin.
817   * @note   PA8 for MCO1 and PB2 for MCO2 should be configured in alternate function mode.
818   * @param  RCC_MCOx  specifies the output direction for the clock source.
819   *            @arg @ref RCC_MCO1  Clock source to output on MCO1 pins.
820   *            @arg @ref RCC_MCO2  Clock source to output on MCO2 pins.
821   * @param  RCC_MCOSource  specifies the clock source to output.
822   *          This parameter can be one of the following values:
823   *            @arg @ref RCC_MCO1SOURCE_NOCLOCK  MCO1 output disabled, no clock on MCO1
824   *            @arg @ref RCC_MCO1SOURCE_SYSCLK  system  clock selected as MCO1 source
825   *            @arg @ref RCC_MCO1SOURCE_HSI  HSI clock selected as MCO1 source
826   *            @arg @ref RCC_MCO1SOURCE_HSI48  HSI48 clock selected as MCO1 source (*)
827   *            @arg @ref RCC_MCO1SOURCE_HSE  HSE clock selected as MCO1 source
828   *            @arg @ref RCC_MCO1SOURCE_LSI  LSI clock selected as MCO1 source
829   *            @arg @ref RCC_MCO1SOURCE_LSE  LSE clock selected as MCO1 source
830   *            @arg @ref RCC_MCO2SOURCE_NOCLOCK  MCO2 output disabled, no clock on MCO2
831   *            @arg @ref RCC_MCO2SOURCE_SYSCLK  system  clock selected as MCO2 source
832   *            @arg @ref RCC_MCO2SOURCE_HSI  HSI clock selected as MCO2 source
833   *            @arg @ref RCC_MCO2SOURCE_HSI48  HSI48 clock selected as MCO2 source (*)
834   *            @arg @ref RCC_MCO2SOURCE_HSE  HSE clock selected as MCO2 source
835   *            @arg @ref RCC_MCO2SOURCE_LSI  LSI clock selected as MCO2 source
836   *            @arg @ref RCC_MCO2SOURCE_LSE  LSE clock selected as MCO2 source
837   * @param  RCC_MCODiv  specifies the MCO prescaler.
838   *          This parameter can be one of the following values:
839   *            @arg @ref RCC_MCODIV_1  no division applied to MCO clock
840   *            @arg @ref RCC_MCODIV_2  division by 2 applied to MCO clock
841   *            @arg @ref RCC_MCODIV_4  division by 4 applied to MCO clock
842   *            @arg @ref RCC_MCODIV_8  division by 8 applied to MCO clock
843   *            @arg @ref RCC_MCODIV_16  division by 16 applied to MCO clock
844   *            @arg @ref RCC_MCODIV_32  division by 32 applied to MCO clock
845   *            @arg @ref RCC_MCODIV_64  division by 64 applied to MCO clock
846   *            @arg @ref RCC_MCODIV_128  division by 128 applied to MCO clock
847   * @note (*) peripheral not available on all devices
848   * @retval None
849   */
HAL_RCC_MCOConfig(uint32_t RCC_MCOx,uint32_t RCC_MCOSource,uint32_t RCC_MCODiv)850 void HAL_RCC_MCOConfig(uint32_t RCC_MCOx, uint32_t RCC_MCOSource, uint32_t RCC_MCODiv)
851 {
852   GPIO_InitTypeDef gpio_initstruct;
853   uint32_t mcoindex;
854   uint32_t mco_gpio_index;
855   GPIO_TypeDef *mco_gpio_port;
856 
857   /* Check the parameters */
858   assert_param(IS_RCC_MCO(RCC_MCOx));
859 
860   /* Common GPIO init parameters */
861   gpio_initstruct.Mode      = GPIO_MODE_AF_PP;
862   gpio_initstruct.Speed     = GPIO_SPEED_FREQ_VERY_HIGH;
863   gpio_initstruct.Pull      = GPIO_NOPULL;
864 
865   /* Get MCOx selection */
866   mcoindex = RCC_MCOx & RCC_MCO_INDEX_MASK;
867 
868   /* Get MCOx GPIO Port */
869   mco_gpio_port = (GPIO_TypeDef *) RCC_GET_MCO_GPIO_PORT(RCC_MCOx);
870 
871   /* MCOx Clock Enable */
872   mco_gpio_index = RCC_GET_MCO_GPIO_INDEX(RCC_MCOx);
873   SET_BIT(RCC->IOPENR, (1UL << mco_gpio_index));
874 
875   /* Configure the MCOx pin in alternate function mode */
876   gpio_initstruct.Pin = RCC_GET_MCO_GPIO_PIN(RCC_MCOx);
877   gpio_initstruct.Alternate = RCC_GET_MCO_GPIO_AF(RCC_MCOx);
878   HAL_GPIO_Init(mco_gpio_port, &gpio_initstruct);
879 
880   if (mcoindex == RCC_MCO1_INDEX)
881   {
882     assert_param(IS_RCC_MCODIV(RCC_MCODiv));
883     assert_param(IS_RCC_MCO1SOURCE(RCC_MCOSource));
884     /* Mask MCOSEL[] and MCOPRE[] bits then set MCO clock source and prescaler */
885     LL_RCC_ConfigMCO(RCC_MCOSource, RCC_MCODiv);
886   }
887   else if (mcoindex == RCC_MCO2_INDEX)
888   {
889     assert_param(IS_RCC_MCO2DIV(RCC_MCODiv));
890     assert_param(IS_RCC_MCO2SOURCE(RCC_MCOSource));
891     /* Mask MCOSEL[] and MCOPRE[] bits then set MCO clock source and prescaler */
892     LL_RCC_ConfigMCO2(RCC_MCOSource, RCC_MCODiv);
893   }
894   else
895   {
896     /* unexpected case: added to resolve MISRA 15.7 rule */
897   }
898 }
899 
900 /**
901   * @brief  Return the SYSCLK frequency.
902   *
903   * @note   The system frequency computed by this function is not the real
904   *         frequency in the chip. It is calculated based on the predefined
905   *         constant and the selected clock source:
906   * @note     If SYSCLK source is HSI, function returns values based on HSI_VALUE/HSIDIV(*)
907   * @note     If SYSCLK source is HSE, function returns values based on HSE_VALUE(**)
908   * @note     If SYSCLK source is LSI, function returns values based on LSI_VALUE(***)
909   * @note     If SYSCLK source is LSE, function returns values based on LSE_VALUE(****)
910   * @note     (*) HSI_VALUE is a constant defined in stm32c0xx_hal_conf.h file (default value
911   *               48 MHz) but the real value may vary depending on the variations
912   *               in voltage and temperature.
913   * @note     (**) HSE_VALUE is a constant defined in stm32c0xx_hal_conf.h file (default value
914   *                48 MHz), user has to ensure that HSE_VALUE is same as the real
915   *                frequency of the crystal used. Otherwise, this function may
916   *                have wrong result.
917   * @note     (***) LSE_VALUE is a constant defined in stm32c0xx_hal_conf.h file (default value
918   *               32768 Hz).
919   * @note     (****) LSI_VALUE is a constant defined in stm32c0xx_hal_conf.h file (default value
920   *               32000 Hz).
921   *
922   * @note   The result of this function could be not correct when using fractional
923   *         value for HSE crystal.
924   *
925   * @note   This function can be used by the user application to compute the
926   *         baudrate for the communication peripherals or configure other parameters.
927   *
928   * @note   Each time SYSCLK changes, this function must be called to update the
929   *         right SYSCLK value. Otherwise, any configuration based on this function will be incorrect.
930   *
931   *
932   * @retval SYSCLK frequency
933   */
HAL_RCC_GetSysClockFreq(void)934 uint32_t HAL_RCC_GetSysClockFreq(void)
935 {
936   uint32_t hsidiv;
937   uint32_t sysclockfreq;
938 #if defined(RCC_CR_SYSDIV)
939   uint32_t sysclockdiv = (uint32_t)(((RCC->CR & RCC_CR_SYSDIV) >> RCC_CR_SYSDIV_Pos) + 1U);
940 #endif /* RCC_CR_SYSDIV */
941 
942   if (__HAL_RCC_GET_SYSCLK_SOURCE() == RCC_CFGR_SWS_HSI)
943   {
944     /* HSISYS can be derived for HSI48 */
945     hsidiv = (1UL << ((READ_BIT(RCC->CR, RCC_CR_HSIDIV)) >> RCC_CR_HSIDIV_Pos));
946 
947     /* HSI used as system clock source */
948     sysclockfreq = (HSI_VALUE / hsidiv);
949   }
950   else if (__HAL_RCC_GET_SYSCLK_SOURCE() == RCC_CFGR_SWS_HSE)
951   {
952     /* HSE used as system clock source */
953     sysclockfreq = HSE_VALUE;
954   }
955   else if (__HAL_RCC_GET_SYSCLK_SOURCE() == RCC_CFGR_SWS_LSE)
956   {
957     /* LSE used as system clock source */
958     sysclockfreq = LSE_VALUE;
959   }
960   else if (__HAL_RCC_GET_SYSCLK_SOURCE() == RCC_CFGR_SWS_LSI)
961   {
962     /* LSI used as system clock source */
963     sysclockfreq = LSI_VALUE;
964   }
965 #if defined(RCC_HSI48_SUPPORT)
966   else if (__HAL_RCC_GET_SYSCLK_SOURCE() == RCC_CFGR_SWS_HSI48)
967   {
968     /* HSI48 used as system clock source */
969     sysclockfreq = HSI48_VALUE;
970   }
971 #endif /* RCC_HSI48_SUPPORT */
972   else
973   {
974     sysclockfreq = 0U;
975   }
976 #if defined(RCC_CR_SYSDIV)
977   sysclockfreq = sysclockfreq / sysclockdiv;
978 #endif /* RCC_CR_SYSDIV */
979   return sysclockfreq;
980 }
981 
982 /**
983   * @brief  Return the HCLK frequency.
984   * @note   Each time HCLK changes, this function must be called to update the
985   *         right HCLK value. Otherwise, any configuration based on this function will be incorrect.
986   *
987   * @note   The SystemCoreClock CMSIS variable is used to store System Clock Frequency.
988   * @retval HCLK frequency in Hz
989   */
HAL_RCC_GetHCLKFreq(void)990 uint32_t HAL_RCC_GetHCLKFreq(void)
991 {
992   SystemCoreClock = (HAL_RCC_GetSysClockFreq() >> ((AHBPrescTable[(RCC->CFGR & RCC_CFGR_HPRE) \
993                                                                   >> RCC_CFGR_HPRE_Pos]) & 0x1FU));
994   return SystemCoreClock;
995 }
996 
997 /**
998   * @brief  Return the PCLK1 frequency.
999   * @note   Each time PCLK1 changes, this function must be called to update the
1000   *         right PCLK1 value. Otherwise, any configuration based on this function will be incorrect.
1001   * @retval PCLK1 frequency in Hz
1002   */
HAL_RCC_GetPCLK1Freq(void)1003 uint32_t HAL_RCC_GetPCLK1Freq(void)
1004 {
1005   /* Get HCLK source and Compute PCLK1 frequency ---------------------------*/
1006   return (HAL_RCC_GetHCLKFreq() >> ((APBPrescTable[(RCC->CFGR & RCC_CFGR_PPRE) >> RCC_CFGR_PPRE_Pos]) & 0x1FU));
1007 }
1008 
1009 /**
1010   * @brief  Configure the RCC_OscInitStruct according to the internal
1011   *         RCC configuration registers.
1012   * @param  RCC_OscInitStruct  pointer to an RCC_OscInitTypeDef structure that
1013   *         will be configured.
1014   * @retval None
1015   */
HAL_RCC_GetOscConfig(RCC_OscInitTypeDef * RCC_OscInitStruct)1016 void HAL_RCC_GetOscConfig(RCC_OscInitTypeDef  *RCC_OscInitStruct)
1017 {
1018   uint32_t regval;
1019 
1020   /* Check the parameters */
1021   assert_param(RCC_OscInitStruct != (void *)NULL);
1022 
1023   /* Set all possible values for the Oscillator type parameter ---------------*/
1024 #if defined(RCC_HSI48_SUPPORT)
1025   RCC_OscInitStruct->OscillatorType = RCC_OSCILLATORTYPE_HSE | RCC_OSCILLATORTYPE_HSI | \
1026                                       RCC_OSCILLATORTYPE_LSE | RCC_OSCILLATORTYPE_LSI | RCC_OSCILLATORTYPE_HSI48;
1027 #else
1028   RCC_OscInitStruct->OscillatorType = RCC_OSCILLATORTYPE_HSE | RCC_OSCILLATORTYPE_HSI | \
1029                                       RCC_OSCILLATORTYPE_LSE | RCC_OSCILLATORTYPE_LSI;
1030 #endif /* RCC_HSI48_SUPPORT */
1031   /* Get Control register */
1032   regval = RCC->CR;
1033 
1034   /* Get the HSE configuration -----------------------------------------------*/
1035   RCC_OscInitStruct->HSEState = (regval & (RCC_CR_HSEON | RCC_CR_HSEBYP));
1036 
1037   /* Get the HSI configuration -----------------------------------------------*/
1038   RCC_OscInitStruct->HSIState = regval & RCC_CR_HSION;
1039   RCC_OscInitStruct->HSICalibrationValue = ((RCC->ICSCR & RCC_ICSCR_HSITRIM) >> RCC_ICSCR_HSITRIM_Pos);
1040   RCC_OscInitStruct->HSIDiv = ((regval & RCC_CR_HSIDIV) >> RCC_CR_HSIDIV_Pos);
1041 
1042   /* Get CSR1 register */
1043   regval = RCC->CSR1;
1044 
1045   /* Get the LSE configuration -----------------------------------------------*/
1046   RCC_OscInitStruct->LSEState = (regval & (RCC_CSR1_LSEON | RCC_CSR1_LSEBYP));
1047 
1048   /* Get CSR2 register */
1049   regval = RCC->CSR2;
1050 
1051   /* Get the LSI configuration -----------------------------------------------*/
1052   RCC_OscInitStruct->LSIState = regval & RCC_CSR2_LSION;
1053 
1054 #if defined(RCC_HSI48_SUPPORT)
1055   /* Get the HSI48 configuration ---------------------------------------------*/
1056   if (READ_BIT(RCC->CR, RCC_CR_HSIUSB48ON) == RCC_CR_HSIUSB48ON)
1057   {
1058     RCC_OscInitStruct->HSI48State = RCC_HSI48_ON;
1059   }
1060   else
1061   {
1062     RCC_OscInitStruct->HSI48State = RCC_HSI48_OFF;
1063   }
1064 #endif /* RCC_HSI48_SUPPORT */
1065 
1066 }
1067 
1068 /**
1069   * @brief  Configure the RCC_ClkInitStruct according to the internal
1070   *         RCC configuration registers.
1071   * @param  RCC_ClkInitStruct Pointer to a @ref RCC_ClkInitTypeDef structure that
1072   *                           will be configured.
1073   * @param  pFLatency         Pointer on the Flash Latency.
1074   * @retval None
1075   */
HAL_RCC_GetClockConfig(RCC_ClkInitTypeDef * RCC_ClkInitStruct,uint32_t * pFLatency)1076 void HAL_RCC_GetClockConfig(RCC_ClkInitTypeDef  *RCC_ClkInitStruct, uint32_t *pFLatency)
1077 {
1078   /* Check the parameters */
1079   assert_param(RCC_ClkInitStruct != (void *)NULL);
1080   assert_param(pFLatency != (void *)NULL);
1081 
1082   /* Set all possible values for the Clock type parameter --------------------*/
1083   RCC_ClkInitStruct->ClockType = RCC_CLOCKTYPE_SYSCLK | RCC_CLOCKTYPE_HCLK | RCC_CLOCKTYPE_PCLK1;
1084 
1085   /* Get the SYSCLK configuration --------------------------------------------*/
1086   RCC_ClkInitStruct->SYSCLKSource = (uint32_t)(RCC->CFGR & RCC_CFGR_SW);
1087 
1088 #if defined(RCC_CR_SYSDIV)
1089   /* Get the SYSCLK configuration ----------------------------------------------*/
1090   RCC_ClkInitStruct->SYSCLKDivider = (uint32_t)(RCC->CR & RCC_CR_SYSDIV);
1091 #endif /* RCC_CR_SYSDIV */
1092 
1093   /* Get the HCLK configuration ----------------------------------------------*/
1094   RCC_ClkInitStruct->AHBCLKDivider = (uint32_t)(RCC->CFGR & RCC_CFGR_HPRE);
1095 
1096   /* Get the APB1 configuration ----------------------------------------------*/
1097   RCC_ClkInitStruct->APB1CLKDivider = (uint32_t)(RCC->CFGR & RCC_CFGR_PPRE);
1098 
1099 
1100   /* Get the Flash Wait State (Latency) configuration ------------------------*/
1101   *pFLatency = (uint32_t)(FLASH->ACR & FLASH_ACR_LATENCY);
1102 }
1103 
1104 /**
1105   * @brief  Enable the Clock Security System.
1106   * @note   If a failure is detected on the HSE oscillator clock, this oscillator
1107   *         is automatically disabled and an interrupt is generated to inform the
1108   *         software about the failure (Clock Security System Interrupt, CSSI),
1109   *         allowing the MCU to perform rescue operations. The CSSI is linked to
1110   *         the Cortex-M0+ NMI (Non-Maskable Interrupt) exception vector.
1111   * @note   The Clock Security System can only be cleared by reset.
1112   * @retval None
1113   */
HAL_RCC_EnableCSS(void)1114 void HAL_RCC_EnableCSS(void)
1115 {
1116   SET_BIT(RCC->CR, RCC_CR_CSSON) ;
1117 }
1118 
1119 /**
1120   * @brief  Enable the LSE Clock Security System.
1121   * @note   If a failure is detected on the LSE oscillator clock, this oscillator
1122   *         is automatically disabled and an interrupt is generated to inform the
1123   *         software about the failure (Clock Security System Interrupt, CSSI),
1124   *         allowing the MCU to perform rescue operations. The CSSI is linked to
1125   *         the Cortex-M0+ NMI (Non-Maskable Interrupt) exception vector.
1126   * @note   The LSE Clock Security System Detection bit (LSECSSD in CSR1) can only be
1127   *         cleared by a backup domain reset.
1128   * @retval None
1129   */
HAL_RCC_EnableLSECSS(void)1130 void HAL_RCC_EnableLSECSS(void)
1131 {
1132   SET_BIT(RCC->CSR1, RCC_CSR1_LSECSSON) ;
1133 }
1134 
1135 /**
1136   * @brief  Disable the LSE Clock Security System.
1137   * @note   After LSE failure detection, the software must disable LSECSSON
1138   * @note   The Clock Security System can only be cleared by reset otherwise.
1139   * @retval None
1140   */
HAL_RCC_DisableLSECSS(void)1141 void HAL_RCC_DisableLSECSS(void)
1142 {
1143   CLEAR_BIT(RCC->CSR1, RCC_CSR1_LSECSSON) ;
1144 }
1145 
1146 /**
1147   * @brief Handle the RCC Clock Security System interrupt request.
1148   * @note  This API should be called under the NMI_Handler().
1149   * @retval None
1150   */
HAL_RCC_NMI_IRQHandler(void)1151 void HAL_RCC_NMI_IRQHandler(void)
1152 {
1153   uint32_t itflag = RCC->CIFR;
1154 
1155   /* Clear interrupt flags related to CSS */
1156   RCC->CICR = (itflag & (RCC_CIFR_CSSF | RCC_CIFR_LSECSSF));
1157 
1158   /* Check RCC CSSF interrupt flag  */
1159   if ((itflag & RCC_CIFR_CSSF) != 0x00u)
1160   {
1161     /* RCC Clock Security System interrupt user callback */
1162     HAL_RCC_CSSCallback();
1163   }
1164 
1165   /* Check RCC LSECSSF interrupt flag  */
1166   if ((itflag & RCC_CIFR_LSECSSF) != 0x00u)
1167   {
1168     /* RCC Clock Security System interrupt user callback */
1169     HAL_RCC_LSECSSCallback();
1170   }
1171 }
1172 
1173 /**
1174   * @brief Handle the RCC HSE Clock Security System interrupt callback.
1175   * @retval none
1176   */
HAL_RCC_CSSCallback(void)1177 __weak void HAL_RCC_CSSCallback(void)
1178 {
1179   /* NOTE : This function should not be modified, when the callback is needed,
1180             the @ref HAL_RCC_CSSCallback should be implemented in the user file
1181    */
1182 }
1183 
1184 /**
1185   * @brief  RCC LSE Clock Security System interrupt callback.
1186   * @retval none
1187   */
HAL_RCC_LSECSSCallback(void)1188 __weak void HAL_RCC_LSECSSCallback(void)
1189 {
1190   /* NOTE : This function should not be modified, when the callback is needed,
1191             the HAL_RCC_LSECSSCallback should be implemented in the user file
1192    */
1193 }
1194 
1195 /**
1196   * @}
1197   */
1198 
1199 /**
1200   * @}
1201   */
1202 
1203 #endif /* HAL_RCC_MODULE_ENABLED */
1204 /**
1205   * @}
1206   */
1207 
1208 /**
1209   * @}
1210   */
1211