1 /**
2   ******************************************************************************
3   * @file    stm32f0xx_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 Internal High Speed oscillator
17       (HSI 8MHz) with Flash 0 wait state, Flash prefetch buffer is disabled,
18       and all peripherals are off except internal SRAM, Flash and JTAG.
19       (+) There is no prescaler on High speed (AHB) and Low speed (APB) buses;
20           all peripherals mapped on these buses are running at HSI speed.
21       (+) The clock for all peripherals is switched off, except the SRAM and FLASH.
22       (+) All GPIOs are in input floating state, except the JTAG pins which
23           are assigned to be used for debug purpose.
24     [..] Once the device started from reset, the user application has to:
25       (+) Configure the clock source to be used to drive the System clock
26           (if the application needs higher frequency/performance)
27       (+) Configure the System clock frequency and Flash settings
28       (+) Configure the AHB and APB buses prescalers
29       (+) Enable the clock for the peripheral(s) to be used
30       (+) Configure the clock source(s) for peripherals whose clocks are not
31           derived from the System clock (RTC, ADC, I2C, USART, TIM, USB FS, etc..)
32 
33                       ##### RCC Limitations #####
34   ==============================================================================
35     [..]
36       A delay between an RCC peripheral clock enable and the effective peripheral
37       enabling should be taken into account in order to manage the peripheral read/write
38       from/to registers.
39       (+) This delay depends on the peripheral mapping.
40         (++) AHB & APB peripherals, 1 dummy read is necessary
41 
42     [..]
43       Workarounds:
44       (#) For AHB & APB peripherals, a dummy read to the peripheral register has been
45           inserted in each __HAL_RCC_PPP_CLK_ENABLE() macro.
46 
47   @endverbatim
48   ******************************************************************************
49   * @attention
50   *
51   * Copyright (c) 2016 STMicroelectronics.
52   * All rights reserved.
53   *
54   * This software is licensed under terms that can be found in the LICENSE file in
55   * the root directory of this software component.
56   * If no LICENSE file comes with this software, it is provided AS-IS.
57   ******************************************************************************
58   */
59 
60 /* Includes ------------------------------------------------------------------*/
61 #include "stm32f0xx_hal.h"
62 
63 /** @addtogroup STM32F0xx_HAL_Driver
64   * @{
65   */
66 
67 /** @defgroup RCC RCC
68 * @brief RCC HAL module driver
69   * @{
70   */
71 
72 #ifdef HAL_RCC_MODULE_ENABLED
73 
74 /* Private typedef -----------------------------------------------------------*/
75 /* Private define ------------------------------------------------------------*/
76 /** @defgroup RCC_Private_Constants RCC Private Constants
77  * @{
78  */
79 /**
80   * @}
81   */
82 /* Private macro -------------------------------------------------------------*/
83 /** @defgroup RCC_Private_Macros RCC Private Macros
84   * @{
85   */
86 
87 #define MCO1_CLK_ENABLE()     __HAL_RCC_GPIOA_CLK_ENABLE()
88 #define MCO1_GPIO_PORT        GPIOA
89 #define MCO1_PIN              GPIO_PIN_8
90 
91 /**
92   * @}
93   */
94 
95 /* Private variables ---------------------------------------------------------*/
96 /** @defgroup RCC_Private_Variables RCC Private Variables
97   * @{
98   */
99 /**
100   * @}
101   */
102 
103 /* Private function prototypes -----------------------------------------------*/
104 /* Exported functions ---------------------------------------------------------*/
105 
106 /** @defgroup RCC_Exported_Functions RCC Exported Functions
107   * @{
108   */
109 
110 /** @defgroup RCC_Exported_Functions_Group1 Initialization and de-initialization functions
111   *  @brief    Initialization and Configuration functions
112   *
113   @verbatim
114   ===============================================================================
115            ##### Initialization and de-initialization functions #####
116   ===============================================================================
117     [..]
118       This section provides functions allowing to configure the internal/external oscillators
119       (HSE, HSI, HSI14, HSI48, LSE, LSI, PLL, CSS and MCO) and the System buses clocks (SYSCLK,
120       AHB and APB1).
121 
122     [..] Internal/external clock and PLL configuration
123       (#) HSI (high-speed internal), 8 MHz factory-trimmed RC used directly or through
124           the PLL as System clock source.
125           The HSI clock can be used also to clock the USART and I2C peripherals.
126 
127       (#) HSI14 (high-speed internal), 14 MHz factory-trimmed RC used directly to clock
128           the ADC peripheral.
129 
130       (#) LSI (low-speed internal), ~40 KHz low consumption RC used as IWDG and/or RTC
131           clock source.
132 
133       (#) HSE (high-speed external), 4 to 32 MHz crystal oscillator used directly or
134           through the PLL as System clock source. Can be used also as RTC clock source.
135 
136       (#) LSE (low-speed external), 32 KHz oscillator used as RTC clock source.
137 
138       (#) PLL (clocked by HSI, HSI48 or HSE), featuring different output clocks:
139        (++) The first output is used to generate the high speed system clock (up to 48 MHz)
140        (++) The second output is used to generate the clock for the USB FS (48 MHz)
141        (++) The third output may be used to generate the clock for the TIM, I2C and USART
142             peripherals (up to 48 MHz)
143 
144       (#) CSS (Clock security system), once enable using the macro __HAL_RCC_CSS_ENABLE()
145           and if a HSE clock failure occurs(HSE used directly or through PLL as System
146           clock source), the System clocks automatically switched to HSI and an interrupt
147           is generated if enabled. The interrupt is linked to the Cortex-M0 NMI
148           (Non-Maskable Interrupt) exception vector.
149 
150       (#) MCO (microcontroller clock output), used to output SYSCLK, HSI, HSE, LSI, LSE or PLL
151           clock (divided by 2) output on pin (such as PA8 pin).
152 
153     [..] System, AHB and APB buses clocks configuration
154       (#) Several clock sources can be used to drive the System clock (SYSCLK): HSI,
155           HSE and PLL.
156           The AHB clock (HCLK) is derived from System clock through configurable
157           prescaler and used to clock the CPU, memory and peripherals mapped
158           on AHB bus (DMA, GPIO...). APB1 (PCLK1) clock is derived
159           from AHB clock through configurable prescalers and used to clock
160           the peripherals mapped on these buses. You can use
161           "HAL_RCC_GetSysClockFreq()" function to retrieve the frequencies of these clocks.
162 
163       (#) All the peripheral clocks are derived from the System clock (SYSCLK) except:
164         (++) The FLASH program/erase clock  which is always HSI 8MHz clock.
165         (++) The USB 48 MHz clock which is derived from the PLL VCO clock.
166         (++) The USART clock which can be derived as well from HSI 8MHz, LSI or LSE.
167         (++) The I2C clock which can be derived as well from HSI 8MHz clock.
168         (++) The ADC clock which is derived from PLL output.
169         (++) The RTC clock which is derived from the LSE, LSI or 1 MHz HSE_RTC
170              (HSE divided by a programmable prescaler). The System clock (SYSCLK)
171              frequency must be higher or equal to the RTC clock frequency.
172         (++) IWDG clock which is always the LSI clock.
173 
174       (#) For the STM32F0xx devices, the maximum frequency of the SYSCLK, HCLK and PCLK1 is 48 MHz,
175           Depending on the SYSCLK frequency, the flash latency should be adapted accordingly.
176 
177       (#) After reset, the System clock source is the HSI (8 MHz) with 0 WS and
178           prefetch is disabled.
179   @endverbatim
180   * @{
181   */
182 
183 /*
184   Additional consideration on the SYSCLK based on Latency settings:
185           +-----------------------------------------------+
186           | Latency       | SYSCLK clock frequency (MHz)  |
187           |---------------|-------------------------------|
188           |0WS(1CPU cycle)|       0 < SYSCLK <= 24        |
189           |---------------|-------------------------------|
190           |1WS(2CPU cycle)|      24 < SYSCLK <= 48        |
191           +-----------------------------------------------+
192   */
193 
194 /**
195   * @brief  Resets the RCC clock configuration to the default reset state.
196   * @note   The default reset state of the clock configuration is given below:
197   *            - HSI ON and used as system clock source
198   *            - HSE and PLL OFF
199   *            - AHB, APB1 prescaler set to 1.
200   *            - CSS and MCO1 OFF
201   *            - All interrupts disabled
202   *            - All interrupt and reset flags cleared
203   * @note   This function does not modify the configuration of the
204   *            - Peripheral clocks
205   *            - LSI, LSE and RTC clocks
206   * @retval HAL status
207   */
HAL_RCC_DeInit(void)208 HAL_StatusTypeDef HAL_RCC_DeInit(void)
209 {
210   uint32_t tickstart;
211 
212   /* Get Start Tick*/
213   tickstart = HAL_GetTick();
214 
215   /* Set HSION bit, HSITRIM[4:0] bits to the reset value*/
216   SET_BIT(RCC->CR, RCC_CR_HSION | RCC_CR_HSITRIM_4);
217 
218   /* Wait till HSI is ready */
219   while (READ_BIT(RCC->CR, RCC_CR_HSIRDY) == RESET)
220   {
221     if ((HAL_GetTick() - tickstart) > HSI_TIMEOUT_VALUE)
222     {
223       return HAL_TIMEOUT;
224     }
225   }
226 
227   /* Reset SW[1:0], HPRE[3:0], PPRE[2:0] and MCOSEL[2:0] bits */
228   CLEAR_BIT(RCC->CFGR, RCC_CFGR_SW | RCC_CFGR_HPRE | RCC_CFGR_PPRE | RCC_CFGR_MCO);
229 
230   /* Wait till HSI as SYSCLK status is enabled */
231   while (READ_BIT(RCC->CFGR, RCC_CFGR_SWS) != RESET)
232   {
233     if ((HAL_GetTick() - tickstart) > CLOCKSWITCH_TIMEOUT_VALUE)
234     {
235       return HAL_TIMEOUT;
236     }
237   }
238 
239   /* Update the SystemCoreClock global variable for HSI as system clock source */
240   SystemCoreClock = HSI_VALUE;
241 
242   /* Adapt Systick interrupt period */
243   if (HAL_InitTick(uwTickPrio) != HAL_OK)
244   {
245     return HAL_ERROR;
246   }
247 
248   /* Reset HSEON, CSSON, PLLON bits */
249   CLEAR_BIT(RCC->CR, RCC_CR_PLLON | RCC_CR_CSSON | RCC_CR_HSEON);
250 
251   /* Reset HSEBYP bit */
252   CLEAR_BIT(RCC->CR, RCC_CR_HSEBYP);
253 
254   /* Get start tick */
255   tickstart = HAL_GetTick();
256 
257   /* Wait till PLLRDY is cleared */
258   while(READ_BIT(RCC->CR, RCC_CR_PLLRDY) != RESET)
259   {
260     if((HAL_GetTick() - tickstart) > PLL_TIMEOUT_VALUE)
261     {
262       return HAL_TIMEOUT;
263     }
264   }
265 
266   /* Reset CFGR register */
267   CLEAR_REG(RCC->CFGR);
268 
269   /* Reset CFGR2 register */
270   CLEAR_REG(RCC->CFGR2);
271 
272   /* Reset CFGR3 register */
273   CLEAR_REG(RCC->CFGR3);
274 
275   /* Disable all interrupts */
276   CLEAR_REG(RCC->CIR);
277 
278   /* Clear all reset flags */
279   __HAL_RCC_CLEAR_RESET_FLAGS();
280 
281   return HAL_OK;
282 }
283 
284 /**
285   * @brief  Initializes the RCC Oscillators according to the specified parameters in the
286   *         RCC_OscInitTypeDef.
287   * @param  RCC_OscInitStruct pointer to an RCC_OscInitTypeDef structure that
288   *         contains the configuration information for the RCC Oscillators.
289   * @note   The PLL is not disabled when used as system clock.
290   * @note   Transitions LSE Bypass to LSE On and LSE On to LSE Bypass are not
291   *         supported by this macro. User should request a transition to LSE Off
292   *         first and then LSE On or LSE Bypass.
293   * @note   Transition HSE Bypass to HSE On and HSE On to HSE Bypass are not
294   *         supported by this macro. User should request a transition to HSE Off
295   *         first and then HSE On or HSE Bypass.
296   * @retval HAL status
297   */
HAL_RCC_OscConfig(RCC_OscInitTypeDef * RCC_OscInitStruct)298 HAL_StatusTypeDef HAL_RCC_OscConfig(RCC_OscInitTypeDef  *RCC_OscInitStruct)
299 {
300   uint32_t tickstart;
301   uint32_t pll_config;
302   uint32_t pll_config2;
303 
304   /* Check Null pointer */
305   if(RCC_OscInitStruct == NULL)
306   {
307     return HAL_ERROR;
308   }
309 
310   /* Check the parameters */
311   assert_param(IS_RCC_OSCILLATORTYPE(RCC_OscInitStruct->OscillatorType));
312 
313   /*------------------------------- HSE Configuration ------------------------*/
314   if(((RCC_OscInitStruct->OscillatorType) & RCC_OSCILLATORTYPE_HSE) == RCC_OSCILLATORTYPE_HSE)
315   {
316     /* Check the parameters */
317     assert_param(IS_RCC_HSE(RCC_OscInitStruct->HSEState));
318 
319     /* When the HSE is used as system clock or clock source for PLL in these cases it is not allowed to be disabled */
320     if((__HAL_RCC_GET_SYSCLK_SOURCE() == RCC_SYSCLKSOURCE_STATUS_HSE)
321        || ((__HAL_RCC_GET_SYSCLK_SOURCE() == RCC_SYSCLKSOURCE_STATUS_PLLCLK) && (__HAL_RCC_GET_PLL_OSCSOURCE() == RCC_PLLSOURCE_HSE)))
322     {
323       if((__HAL_RCC_GET_FLAG(RCC_FLAG_HSERDY) != RESET) && (RCC_OscInitStruct->HSEState == RCC_HSE_OFF))
324       {
325         return HAL_ERROR;
326       }
327     }
328     else
329     {
330       /* Set the new HSE configuration ---------------------------------------*/
331       __HAL_RCC_HSE_CONFIG(RCC_OscInitStruct->HSEState);
332 
333 
334        /* Check the HSE State */
335       if(RCC_OscInitStruct->HSEState != RCC_HSE_OFF)
336       {
337         /* Get Start Tick */
338         tickstart = HAL_GetTick();
339 
340         /* Wait till HSE is ready */
341         while(__HAL_RCC_GET_FLAG(RCC_FLAG_HSERDY) == RESET)
342         {
343           if((HAL_GetTick() - tickstart ) > HSE_TIMEOUT_VALUE)
344           {
345             return HAL_TIMEOUT;
346           }
347         }
348       }
349       else
350       {
351         /* Get Start Tick */
352         tickstart = HAL_GetTick();
353 
354         /* Wait till HSE is disabled */
355         while(__HAL_RCC_GET_FLAG(RCC_FLAG_HSERDY) != RESET)
356         {
357            if((HAL_GetTick() - tickstart ) > HSE_TIMEOUT_VALUE)
358           {
359             return HAL_TIMEOUT;
360           }
361         }
362       }
363     }
364   }
365   /*----------------------------- HSI Configuration --------------------------*/
366   if(((RCC_OscInitStruct->OscillatorType) & RCC_OSCILLATORTYPE_HSI) == RCC_OSCILLATORTYPE_HSI)
367   {
368     /* Check the parameters */
369     assert_param(IS_RCC_HSI(RCC_OscInitStruct->HSIState));
370     assert_param(IS_RCC_CALIBRATION_VALUE(RCC_OscInitStruct->HSICalibrationValue));
371 
372     /* Check if HSI is used as system clock or as PLL source when PLL is selected as system clock */
373     if((__HAL_RCC_GET_SYSCLK_SOURCE() == RCC_SYSCLKSOURCE_STATUS_HSI)
374        || ((__HAL_RCC_GET_SYSCLK_SOURCE() == RCC_SYSCLKSOURCE_STATUS_PLLCLK) && (__HAL_RCC_GET_PLL_OSCSOURCE() == RCC_PLLSOURCE_HSI)))
375     {
376       /* When HSI is used as system clock it will not disabled */
377       if((__HAL_RCC_GET_FLAG(RCC_FLAG_HSIRDY) != RESET) && (RCC_OscInitStruct->HSIState != RCC_HSI_ON))
378       {
379         return HAL_ERROR;
380       }
381       /* Otherwise, just the calibration is allowed */
382       else
383       {
384         /* Adjusts the Internal High Speed oscillator (HSI) calibration value.*/
385         __HAL_RCC_HSI_CALIBRATIONVALUE_ADJUST(RCC_OscInitStruct->HSICalibrationValue);
386       }
387     }
388     else
389     {
390       /* Check the HSI State */
391       if(RCC_OscInitStruct->HSIState != RCC_HSI_OFF)
392       {
393        /* Enable the Internal High Speed oscillator (HSI). */
394         __HAL_RCC_HSI_ENABLE();
395 
396         /* Get Start Tick */
397         tickstart = HAL_GetTick();
398 
399         /* Wait till HSI is ready */
400         while(__HAL_RCC_GET_FLAG(RCC_FLAG_HSIRDY) == RESET)
401         {
402           if((HAL_GetTick() - tickstart ) > HSI_TIMEOUT_VALUE)
403           {
404             return HAL_TIMEOUT;
405           }
406         }
407 
408         /* Adjusts the Internal High Speed oscillator (HSI) calibration value.*/
409         __HAL_RCC_HSI_CALIBRATIONVALUE_ADJUST(RCC_OscInitStruct->HSICalibrationValue);
410       }
411       else
412       {
413         /* Disable the Internal High Speed oscillator (HSI). */
414         __HAL_RCC_HSI_DISABLE();
415 
416         /* Get Start Tick */
417         tickstart = HAL_GetTick();
418 
419         /* Wait till HSI is disabled */
420         while(__HAL_RCC_GET_FLAG(RCC_FLAG_HSIRDY) != RESET)
421         {
422           if((HAL_GetTick() - tickstart ) > HSI_TIMEOUT_VALUE)
423           {
424             return HAL_TIMEOUT;
425           }
426         }
427       }
428     }
429   }
430   /*------------------------------ LSI Configuration -------------------------*/
431   if(((RCC_OscInitStruct->OscillatorType) & RCC_OSCILLATORTYPE_LSI) == RCC_OSCILLATORTYPE_LSI)
432   {
433     /* Check the parameters */
434     assert_param(IS_RCC_LSI(RCC_OscInitStruct->LSIState));
435 
436     /* Check the LSI State */
437     if(RCC_OscInitStruct->LSIState != RCC_LSI_OFF)
438     {
439       /* Enable the Internal Low Speed oscillator (LSI). */
440       __HAL_RCC_LSI_ENABLE();
441 
442       /* Get Start Tick */
443       tickstart = HAL_GetTick();
444 
445       /* Wait till LSI is ready */
446       while(__HAL_RCC_GET_FLAG(RCC_FLAG_LSIRDY) == RESET)
447       {
448         if((HAL_GetTick() - tickstart ) > LSI_TIMEOUT_VALUE)
449         {
450           return HAL_TIMEOUT;
451         }
452       }
453     }
454     else
455     {
456       /* Disable the Internal Low Speed oscillator (LSI). */
457       __HAL_RCC_LSI_DISABLE();
458 
459       /* Get Start Tick */
460       tickstart = HAL_GetTick();
461 
462       /* Wait till LSI is disabled */
463       while(__HAL_RCC_GET_FLAG(RCC_FLAG_LSIRDY) != RESET)
464       {
465         if((HAL_GetTick() - tickstart ) > LSI_TIMEOUT_VALUE)
466         {
467           return HAL_TIMEOUT;
468         }
469       }
470     }
471   }
472   /*------------------------------ LSE Configuration -------------------------*/
473   if(((RCC_OscInitStruct->OscillatorType) & RCC_OSCILLATORTYPE_LSE) == RCC_OSCILLATORTYPE_LSE)
474   {
475     FlagStatus       pwrclkchanged = RESET;
476 
477     /* Check the parameters */
478     assert_param(IS_RCC_LSE(RCC_OscInitStruct->LSEState));
479 
480     /* Update LSE configuration in Backup Domain control register    */
481     /* Requires to enable write access to Backup Domain of necessary */
482     if(__HAL_RCC_PWR_IS_CLK_DISABLED())
483     {
484       __HAL_RCC_PWR_CLK_ENABLE();
485       pwrclkchanged = SET;
486     }
487 
488     if(HAL_IS_BIT_CLR(PWR->CR, PWR_CR_DBP))
489     {
490       /* Enable write access to Backup domain */
491       SET_BIT(PWR->CR, PWR_CR_DBP);
492 
493       /* Wait for Backup domain Write protection disable */
494       tickstart = HAL_GetTick();
495 
496       while(HAL_IS_BIT_CLR(PWR->CR, PWR_CR_DBP))
497       {
498         if((HAL_GetTick() - tickstart) > RCC_DBP_TIMEOUT_VALUE)
499         {
500           return HAL_TIMEOUT;
501         }
502       }
503     }
504 
505     /* Set the new LSE configuration -----------------------------------------*/
506     __HAL_RCC_LSE_CONFIG(RCC_OscInitStruct->LSEState);
507     /* Check the LSE State */
508     if(RCC_OscInitStruct->LSEState != RCC_LSE_OFF)
509     {
510       /* Get Start Tick */
511       tickstart = HAL_GetTick();
512 
513       /* Wait till LSE is ready */
514       while(__HAL_RCC_GET_FLAG(RCC_FLAG_LSERDY) == RESET)
515       {
516         if((HAL_GetTick() - tickstart ) > RCC_LSE_TIMEOUT_VALUE)
517         {
518           return HAL_TIMEOUT;
519         }
520       }
521     }
522     else
523     {
524       /* Get Start Tick */
525       tickstart = HAL_GetTick();
526 
527       /* Wait till LSE is disabled */
528       while(__HAL_RCC_GET_FLAG(RCC_FLAG_LSERDY) != RESET)
529       {
530         if((HAL_GetTick() - tickstart ) > RCC_LSE_TIMEOUT_VALUE)
531         {
532           return HAL_TIMEOUT;
533         }
534       }
535     }
536 
537     /* Require to disable power clock if necessary */
538     if(pwrclkchanged == SET)
539     {
540       __HAL_RCC_PWR_CLK_DISABLE();
541     }
542   }
543 
544   /*----------------------------- HSI14 Configuration --------------------------*/
545   if(((RCC_OscInitStruct->OscillatorType) & RCC_OSCILLATORTYPE_HSI14) == RCC_OSCILLATORTYPE_HSI14)
546   {
547     /* Check the parameters */
548     assert_param(IS_RCC_HSI14(RCC_OscInitStruct->HSI14State));
549     assert_param(IS_RCC_CALIBRATION_VALUE(RCC_OscInitStruct->HSI14CalibrationValue));
550 
551     /* Check the HSI14 State */
552     if(RCC_OscInitStruct->HSI14State == RCC_HSI14_ON)
553     {
554       /* Disable ADC control of the Internal High Speed oscillator HSI14 */
555       __HAL_RCC_HSI14ADC_DISABLE();
556 
557       /* Enable the Internal High Speed oscillator (HSI). */
558       __HAL_RCC_HSI14_ENABLE();
559 
560       /* Get Start Tick */
561       tickstart = HAL_GetTick();
562 
563       /* Wait till HSI is ready */
564       while(__HAL_RCC_GET_FLAG(RCC_FLAG_HSI14RDY) == RESET)
565       {
566         if((HAL_GetTick() - tickstart) > HSI14_TIMEOUT_VALUE)
567         {
568           return HAL_TIMEOUT;
569         }
570       }
571 
572       /* Adjusts the Internal High Speed oscillator 14Mhz (HSI14) calibration value. */
573       __HAL_RCC_HSI14_CALIBRATIONVALUE_ADJUST(RCC_OscInitStruct->HSI14CalibrationValue);
574     }
575     else if(RCC_OscInitStruct->HSI14State == RCC_HSI14_ADC_CONTROL)
576     {
577       /* Enable ADC control of the Internal High Speed oscillator HSI14 */
578       __HAL_RCC_HSI14ADC_ENABLE();
579 
580       /* Adjusts the Internal High Speed oscillator 14Mhz (HSI14) calibration value. */
581       __HAL_RCC_HSI14_CALIBRATIONVALUE_ADJUST(RCC_OscInitStruct->HSI14CalibrationValue);
582     }
583     else
584     {
585       /* Disable ADC control of the Internal High Speed oscillator HSI14 */
586       __HAL_RCC_HSI14ADC_DISABLE();
587 
588       /* Disable the Internal High Speed oscillator (HSI). */
589       __HAL_RCC_HSI14_DISABLE();
590 
591       /* Get Start Tick */
592       tickstart = HAL_GetTick();
593 
594       /* Wait till HSI is ready */
595       while(__HAL_RCC_GET_FLAG(RCC_FLAG_HSI14RDY) != RESET)
596       {
597         if((HAL_GetTick() - tickstart) > HSI14_TIMEOUT_VALUE)
598         {
599           return HAL_TIMEOUT;
600         }
601       }
602     }
603   }
604 
605 #if defined(RCC_HSI48_SUPPORT)
606   /*----------------------------- HSI48 Configuration --------------------------*/
607   if(((RCC_OscInitStruct->OscillatorType) & RCC_OSCILLATORTYPE_HSI48) == RCC_OSCILLATORTYPE_HSI48)
608   {
609     /* Check the parameters */
610     assert_param(IS_RCC_HSI48(RCC_OscInitStruct->HSI48State));
611 
612     /* When the HSI48 is used as system clock it is not allowed to be disabled */
613     if((__HAL_RCC_GET_SYSCLK_SOURCE() == RCC_SYSCLKSOURCE_STATUS_HSI48) ||
614        ((__HAL_RCC_GET_SYSCLK_SOURCE() == RCC_SYSCLKSOURCE_STATUS_PLLCLK) && (__HAL_RCC_GET_PLL_OSCSOURCE() == RCC_PLLSOURCE_HSI48)))
615     {
616       if((__HAL_RCC_GET_FLAG(RCC_FLAG_HSI48RDY) != RESET) && (RCC_OscInitStruct->HSI48State != RCC_HSI48_ON))
617       {
618         return HAL_ERROR;
619       }
620     }
621     else
622     {
623       /* Check the HSI48 State */
624       if(RCC_OscInitStruct->HSI48State != RCC_HSI48_OFF)
625       {
626         /* Enable the Internal High Speed oscillator (HSI48). */
627         __HAL_RCC_HSI48_ENABLE();
628 
629         /* Get Start Tick */
630         tickstart = HAL_GetTick();
631 
632         /* Wait till HSI48 is ready */
633         while(__HAL_RCC_GET_FLAG(RCC_FLAG_HSI48RDY) == RESET)
634         {
635           if((HAL_GetTick() - tickstart) > HSI48_TIMEOUT_VALUE)
636           {
637             return HAL_TIMEOUT;
638           }
639         }
640       }
641       else
642       {
643         /* Disable the Internal High Speed oscillator (HSI48). */
644         __HAL_RCC_HSI48_DISABLE();
645 
646         /* Get Start Tick */
647         tickstart = HAL_GetTick();
648 
649         /* Wait till HSI48 is ready */
650         while(__HAL_RCC_GET_FLAG(RCC_FLAG_HSI48RDY) != RESET)
651         {
652           if((HAL_GetTick() - tickstart) > HSI48_TIMEOUT_VALUE)
653           {
654             return HAL_TIMEOUT;
655           }
656         }
657       }
658     }
659   }
660 #endif /* RCC_HSI48_SUPPORT */
661 
662   /*-------------------------------- PLL Configuration -----------------------*/
663   /* Check the parameters */
664   assert_param(IS_RCC_PLL(RCC_OscInitStruct->PLL.PLLState));
665   if ((RCC_OscInitStruct->PLL.PLLState) != RCC_PLL_NONE)
666   {
667     /* Check if the PLL is used as system clock or not */
668     if(__HAL_RCC_GET_SYSCLK_SOURCE() != RCC_SYSCLKSOURCE_STATUS_PLLCLK)
669     {
670       if((RCC_OscInitStruct->PLL.PLLState) == RCC_PLL_ON)
671       {
672         /* Check the parameters */
673         assert_param(IS_RCC_PLLSOURCE(RCC_OscInitStruct->PLL.PLLSource));
674         assert_param(IS_RCC_PLL_MUL(RCC_OscInitStruct->PLL.PLLMUL));
675         assert_param(IS_RCC_PREDIV(RCC_OscInitStruct->PLL.PREDIV));
676 
677         /* Disable the main PLL. */
678         __HAL_RCC_PLL_DISABLE();
679 
680         /* Get Start Tick */
681         tickstart = HAL_GetTick();
682 
683         /* Wait till PLL is disabled */
684         while(__HAL_RCC_GET_FLAG(RCC_FLAG_PLLRDY)  != RESET)
685         {
686           if((HAL_GetTick() - tickstart ) > PLL_TIMEOUT_VALUE)
687           {
688             return HAL_TIMEOUT;
689           }
690         }
691 
692         /* Configure the main PLL clock source, predivider and multiplication factor. */
693         __HAL_RCC_PLL_CONFIG(RCC_OscInitStruct->PLL.PLLSource,
694                              RCC_OscInitStruct->PLL.PREDIV,
695                              RCC_OscInitStruct->PLL.PLLMUL);
696         /* Enable the main PLL. */
697         __HAL_RCC_PLL_ENABLE();
698 
699         /* Get Start Tick */
700         tickstart = HAL_GetTick();
701 
702         /* Wait till PLL is ready */
703         while(__HAL_RCC_GET_FLAG(RCC_FLAG_PLLRDY)  == RESET)
704         {
705           if((HAL_GetTick() - tickstart ) > PLL_TIMEOUT_VALUE)
706           {
707             return HAL_TIMEOUT;
708           }
709         }
710       }
711       else
712       {
713         /* Disable the main PLL. */
714         __HAL_RCC_PLL_DISABLE();
715 
716         /* Get Start Tick */
717         tickstart = HAL_GetTick();
718 
719         /* Wait till PLL is disabled */
720         while(__HAL_RCC_GET_FLAG(RCC_FLAG_PLLRDY)  != RESET)
721         {
722           if((HAL_GetTick() - tickstart ) > PLL_TIMEOUT_VALUE)
723           {
724             return HAL_TIMEOUT;
725           }
726         }
727       }
728     }
729     else
730     {
731       /* Check if there is a request to disable the PLL used as System clock source */
732       if((RCC_OscInitStruct->PLL.PLLState) == RCC_PLL_OFF)
733       {
734         return HAL_ERROR;
735       }
736       else
737       {
738         /* Do not return HAL_ERROR if request repeats the current configuration */
739         pll_config  = RCC->CFGR;
740         pll_config2 = RCC->CFGR2;
741         if((READ_BIT(pll_config,  RCC_CFGR_PLLSRC)  != RCC_OscInitStruct->PLL.PLLSource) ||
742            (READ_BIT(pll_config2, RCC_CFGR2_PREDIV) != RCC_OscInitStruct->PLL.PREDIV)    ||
743            (READ_BIT(pll_config,  RCC_CFGR_PLLMUL)  != RCC_OscInitStruct->PLL.PLLMUL))
744         {
745           return HAL_ERROR;
746         }
747       }
748     }
749   }
750 
751   return HAL_OK;
752 }
753 
754 /**
755   * @brief  Initializes the CPU, AHB and APB buses clocks according to the specified
756   *         parameters in the RCC_ClkInitStruct.
757   * @param  RCC_ClkInitStruct pointer to an RCC_OscInitTypeDef structure that
758   *         contains the configuration information for the RCC peripheral.
759   * @param  FLatency FLASH Latency
760   *          The value of this parameter depend on device used within the same series
761   * @note   The SystemCoreClock CMSIS variable is used to store System Clock Frequency
762   *         and updated by @ref HAL_RCC_GetHCLKFreq() function called within this function
763   *
764   * @note   The HSI is used (enabled by hardware) as system clock source after
765   *         start-up from Reset, wake-up from STOP and STANDBY mode, or in case
766   *         of failure of the HSE used directly or indirectly as system clock
767   *         (if the Clock Security System CSS is enabled).
768   *
769   * @note   A switch from one clock source to another occurs only if the target
770   *         clock source is ready (clock stable after start-up delay or PLL locked).
771   *         If a clock source which is not yet ready is selected, the switch will
772   *         occur when the clock source will be ready.
773   *         You can use @ref HAL_RCC_GetClockConfig() function to know which clock is
774   *         currently used as system clock source.
775   * @retval HAL status
776   */
HAL_RCC_ClockConfig(RCC_ClkInitTypeDef * RCC_ClkInitStruct,uint32_t FLatency)777 HAL_StatusTypeDef HAL_RCC_ClockConfig(RCC_ClkInitTypeDef  *RCC_ClkInitStruct, uint32_t FLatency)
778 {
779   uint32_t tickstart;
780 
781   /* Check Null pointer */
782   if(RCC_ClkInitStruct == NULL)
783   {
784     return HAL_ERROR;
785   }
786 
787   /* Check the parameters */
788   assert_param(IS_RCC_CLOCKTYPE(RCC_ClkInitStruct->ClockType));
789   assert_param(IS_FLASH_LATENCY(FLatency));
790 
791   /* To correctly read data from FLASH memory, the number of wait states (LATENCY)
792   must be correctly programmed according to the frequency of the CPU clock
793     (HCLK) of the device. */
794 
795   /* Increasing the number of wait states because of higher CPU frequency */
796   if(FLatency > __HAL_FLASH_GET_LATENCY())
797   {
798     /* Program the new number of wait states to the LATENCY bits in the FLASH_ACR register */
799     __HAL_FLASH_SET_LATENCY(FLatency);
800 
801     /* Check that the new number of wait states is taken into account to access the Flash
802     memory by reading the FLASH_ACR register */
803     if(__HAL_FLASH_GET_LATENCY() != FLatency)
804     {
805       return HAL_ERROR;
806     }
807   }
808 
809   /*-------------------------- HCLK Configuration --------------------------*/
810   if(((RCC_ClkInitStruct->ClockType) & RCC_CLOCKTYPE_HCLK) == RCC_CLOCKTYPE_HCLK)
811   {
812     /* Set the highest APB divider in order to ensure that we do not go through
813        a non-spec phase whatever we decrease or increase HCLK. */
814     if(((RCC_ClkInitStruct->ClockType) & RCC_CLOCKTYPE_PCLK1) == RCC_CLOCKTYPE_PCLK1)
815     {
816       MODIFY_REG(RCC->CFGR, RCC_CFGR_PPRE, RCC_HCLK_DIV16);
817     }
818 
819     /* Set the new HCLK clock divider */
820     assert_param(IS_RCC_HCLK(RCC_ClkInitStruct->AHBCLKDivider));
821     MODIFY_REG(RCC->CFGR, RCC_CFGR_HPRE, RCC_ClkInitStruct->AHBCLKDivider);
822   }
823 
824   /*------------------------- SYSCLK Configuration ---------------------------*/
825   if(((RCC_ClkInitStruct->ClockType) & RCC_CLOCKTYPE_SYSCLK) == RCC_CLOCKTYPE_SYSCLK)
826   {
827     assert_param(IS_RCC_SYSCLKSOURCE(RCC_ClkInitStruct->SYSCLKSource));
828 
829     /* HSE is selected as System Clock Source */
830     if(RCC_ClkInitStruct->SYSCLKSource == RCC_SYSCLKSOURCE_HSE)
831     {
832       /* Check the HSE ready flag */
833       if(__HAL_RCC_GET_FLAG(RCC_FLAG_HSERDY) == RESET)
834       {
835         return HAL_ERROR;
836       }
837     }
838     /* PLL is selected as System Clock Source */
839     else if(RCC_ClkInitStruct->SYSCLKSource == RCC_SYSCLKSOURCE_PLLCLK)
840     {
841       /* Check the PLL ready flag */
842       if(__HAL_RCC_GET_FLAG(RCC_FLAG_PLLRDY) == RESET)
843       {
844         return HAL_ERROR;
845       }
846     }
847 #if defined(RCC_CFGR_SWS_HSI48)
848     /* HSI48 is selected as System Clock Source */
849     else if(RCC_ClkInitStruct->SYSCLKSource == RCC_SYSCLKSOURCE_HSI48)
850     {
851       /* Check the HSI48 ready flag */
852       if(__HAL_RCC_GET_FLAG(RCC_FLAG_HSI48RDY) == RESET)
853       {
854         return HAL_ERROR;
855       }
856     }
857 #endif /* RCC_CFGR_SWS_HSI48 */
858     /* HSI is selected as System Clock Source */
859     else
860     {
861       /* Check the HSI ready flag */
862       if(__HAL_RCC_GET_FLAG(RCC_FLAG_HSIRDY) == RESET)
863       {
864         return HAL_ERROR;
865       }
866     }
867     __HAL_RCC_SYSCLK_CONFIG(RCC_ClkInitStruct->SYSCLKSource);
868 
869     /* Get Start Tick */
870     tickstart = HAL_GetTick();
871 
872     while (__HAL_RCC_GET_SYSCLK_SOURCE() != (RCC_ClkInitStruct->SYSCLKSource << RCC_CFGR_SWS_Pos))
873     {
874       if((HAL_GetTick() - tickstart ) > CLOCKSWITCH_TIMEOUT_VALUE)
875       {
876         return HAL_TIMEOUT;
877       }
878     }
879   }
880 
881   /* Decreasing the number of wait states because of lower CPU frequency */
882   if(FLatency < __HAL_FLASH_GET_LATENCY())
883   {
884     /* Program the new number of wait states to the LATENCY bits in the FLASH_ACR register */
885     __HAL_FLASH_SET_LATENCY(FLatency);
886 
887     /* Check that the new number of wait states is taken into account to access the Flash
888     memory by reading the FLASH_ACR register */
889     if(__HAL_FLASH_GET_LATENCY() != FLatency)
890     {
891       return HAL_ERROR;
892     }
893   }
894 
895   /*-------------------------- PCLK1 Configuration ---------------------------*/
896   if(((RCC_ClkInitStruct->ClockType) & RCC_CLOCKTYPE_PCLK1) == RCC_CLOCKTYPE_PCLK1)
897   {
898     assert_param(IS_RCC_PCLK(RCC_ClkInitStruct->APB1CLKDivider));
899     MODIFY_REG(RCC->CFGR, RCC_CFGR_PPRE, RCC_ClkInitStruct->APB1CLKDivider);
900   }
901 
902   /* Update the SystemCoreClock global variable */
903   SystemCoreClock = HAL_RCC_GetSysClockFreq() >> AHBPrescTable[(RCC->CFGR & RCC_CFGR_HPRE)>> RCC_CFGR_HPRE_BITNUMBER];
904 
905   /* Configure the source of time base considering new system clocks settings*/
906   HAL_InitTick (TICK_INT_PRIORITY);
907 
908   return HAL_OK;
909 }
910 
911 /**
912   * @}
913   */
914 
915 /** @defgroup RCC_Exported_Functions_Group2 Peripheral Control functions
916   *  @brief   RCC clocks control functions
917   *
918   @verbatim
919   ===============================================================================
920                   ##### Peripheral Control functions #####
921   ===============================================================================
922     [..]
923     This subsection provides a set of functions allowing to control the RCC Clocks
924     frequencies.
925 
926   @endverbatim
927   * @{
928   */
929 
930 #if defined(RCC_CFGR_MCOPRE)
931 /**
932   * @brief  Selects the clock source to output on MCO pin.
933   * @note   MCO pin should be configured in alternate function mode.
934   * @param  RCC_MCOx specifies the output direction for the clock source.
935   *          This parameter can be one of the following values:
936   *            @arg @ref RCC_MCO1 Clock source to output on MCO1 pin(PA8).
937   * @param  RCC_MCOSource specifies the clock source to output.
938   *          This parameter can be one of the following values:
939   *            @arg @ref RCC_MCO1SOURCE_NOCLOCK     No clock selected
940   *            @arg @ref RCC_MCO1SOURCE_SYSCLK      System Clock selected as MCO clock
941   *            @arg @ref RCC_MCO1SOURCE_HSI         HSI selected as MCO clock
942   *            @arg @ref RCC_MCO1SOURCE_HSE         HSE selected as MCO clock
943   *            @arg @ref RCC_MCO1SOURCE_LSI         LSI selected as MCO clock
944   *            @arg @ref RCC_MCO1SOURCE_LSE         LSE selected as MCO clock
945   *            @arg @ref RCC_MCO1SOURCE_HSI14       HSI14 selected as MCO clock
946   @if STM32F042x6
947   *            @arg @ref RCC_MCO1SOURCE_HSI48       HSI48 selected as MCO clock
948   *            @arg @ref RCC_MCO1SOURCE_PLLCLK      PLLCLK selected as MCO clock
949   @elseif STM32F048xx
950   *            @arg @ref RCC_MCO1SOURCE_HSI48       HSI48 selected as MCO clock
951   *            @arg @ref RCC_MCO1SOURCE_PLLCLK      PLLCLK selected as MCO clock
952   @elseif STM32F071xB
953   *            @arg @ref RCC_MCO1SOURCE_HSI48       HSI48 selected as MCO clock
954   *            @arg @ref RCC_MCO1SOURCE_PLLCLK      PLLCLK selected as MCO clock
955   @elseif STM32F072xB
956   *            @arg @ref RCC_MCO1SOURCE_HSI48       HSI48 selected as MCO clock
957   *            @arg @ref RCC_MCO1SOURCE_PLLCLK      PLLCLK selected as MCO clock
958   @elseif STM32F078xx
959   *            @arg @ref RCC_MCO1SOURCE_HSI48       HSI48 selected as MCO clock
960   *            @arg @ref RCC_MCO1SOURCE_PLLCLK      PLLCLK selected as MCO clock
961   @elseif STM32F091xC
962   *            @arg @ref RCC_MCO1SOURCE_HSI48       HSI48 selected as MCO clock
963   *            @arg @ref RCC_MCO1SOURCE_PLLCLK      PLLCLK selected as MCO clock
964   @elseif STM32F098xx
965   *            @arg @ref RCC_MCO1SOURCE_HSI48       HSI48 selected as MCO clock
966   *            @arg @ref RCC_MCO1SOURCE_PLLCLK      PLLCLK selected as MCO clock
967   @elif STM32F030x6
968   *            @arg @ref RCC_MCO1SOURCE_PLLCLK      PLLCLK selected as MCO clock
969   @elif STM32F030xC
970   *            @arg @ref RCC_MCO1SOURCE_PLLCLK      PLLCLK selected as MCO clock
971   @elif STM32F031x6
972   *            @arg @ref RCC_MCO1SOURCE_PLLCLK      PLLCLK selected as MCO clock
973   @elif STM32F038xx
974   *            @arg @ref RCC_MCO1SOURCE_PLLCLK      PLLCLK selected as MCO clock
975   @elif STM32F070x6
976   *            @arg @ref RCC_MCO1SOURCE_PLLCLK      PLLCLK selected as MCO clock
977   @elif STM32F070xB
978   *            @arg @ref RCC_MCO1SOURCE_PLLCLK      PLLCLK selected as MCO clock
979   @endif
980   *            @arg @ref RCC_MCO1SOURCE_PLLCLK_DIV2 PLLCLK Divided by 2 selected as MCO clock
981   * @param  RCC_MCODiv specifies the MCO DIV.
982   *          This parameter can be one of the following values:
983   *            @arg @ref RCC_MCODIV_1   no division applied to MCO clock
984   *            @arg @ref RCC_MCODIV_2   division by 2 applied to MCO clock
985   *            @arg @ref RCC_MCODIV_4   division by 4 applied to MCO clock
986   *            @arg @ref RCC_MCODIV_8   division by 8 applied to MCO clock
987   *            @arg @ref RCC_MCODIV_16  division by 16 applied to MCO clock
988   *            @arg @ref RCC_MCODIV_32  division by 32 applied to MCO clock
989   *            @arg @ref RCC_MCODIV_64  division by 64 applied to MCO clock
990   *            @arg @ref RCC_MCODIV_128 division by 128 applied to MCO clock
991   * @retval None
992   */
993 #else
994 /**
995   * @brief  Selects the clock source to output on MCO pin.
996   * @note   MCO pin should be configured in alternate function mode.
997   * @param  RCC_MCOx specifies the output direction for the clock source.
998   *          This parameter can be one of the following values:
999   *            @arg @ref RCC_MCO1 Clock source to output on MCO1 pin(PA8).
1000   * @param  RCC_MCOSource specifies the clock source to output.
1001   *          This parameter can be one of the following values:
1002   *            @arg @ref RCC_MCO1SOURCE_NOCLOCK     No clock selected as MCO clock
1003   *            @arg @ref RCC_MCO1SOURCE_SYSCLK      System clock selected as MCO clock
1004   *            @arg @ref RCC_MCO1SOURCE_HSI         HSI selected as MCO clock
1005   *            @arg @ref RCC_MCO1SOURCE_HSE         HSE selected as MCO clock
1006   *            @arg @ref RCC_MCO1SOURCE_LSI         LSI selected as MCO clock
1007   *            @arg @ref RCC_MCO1SOURCE_LSE         LSE selected as MCO clock
1008   *            @arg @ref RCC_MCO1SOURCE_HSI14       HSI14 selected as MCO clock
1009   *            @arg @ref RCC_MCO1SOURCE_PLLCLK_DIV2 PLLCLK Divided by 2 selected as MCO clock
1010   * @param  RCC_MCODiv specifies the MCO DIV.
1011   *          This parameter can be one of the following values:
1012   *            @arg @ref RCC_MCODIV_1 no division applied to MCO clock
1013   * @retval None
1014   */
1015 #endif
HAL_RCC_MCOConfig(uint32_t RCC_MCOx,uint32_t RCC_MCOSource,uint32_t RCC_MCODiv)1016 void HAL_RCC_MCOConfig(uint32_t RCC_MCOx, uint32_t RCC_MCOSource, uint32_t RCC_MCODiv)
1017 {
1018   GPIO_InitTypeDef gpio;
1019 
1020   /* Check the parameters */
1021   assert_param(IS_RCC_MCO(RCC_MCOx));
1022   assert_param(IS_RCC_MCODIV(RCC_MCODiv));
1023   assert_param(IS_RCC_MCO1SOURCE(RCC_MCOSource));
1024 
1025   /* Configure the MCO1 pin in alternate function mode */
1026   gpio.Mode      = GPIO_MODE_AF_PP;
1027   gpio.Speed     = GPIO_SPEED_FREQ_HIGH;
1028   gpio.Pull      = GPIO_NOPULL;
1029   gpio.Pin       = MCO1_PIN;
1030   gpio.Alternate = GPIO_AF0_MCO;
1031 
1032   /* MCO1 Clock Enable */
1033   MCO1_CLK_ENABLE();
1034 
1035   HAL_GPIO_Init(MCO1_GPIO_PORT, &gpio);
1036 
1037   /* Configure the MCO clock source */
1038   __HAL_RCC_MCO1_CONFIG(RCC_MCOSource, RCC_MCODiv);
1039 }
1040 
1041 /**
1042   * @brief  Enables the Clock Security System.
1043   * @note   If a failure is detected on the HSE oscillator clock, this oscillator
1044   *         is automatically disabled and an interrupt is generated to inform the
1045   *         software about the failure (Clock Security System Interrupt, CSSI),
1046   *         allowing the MCU to perform rescue operations. The CSSI is linked to
1047   *         the Cortex-M0 NMI (Non-Maskable Interrupt) exception vector.
1048   * @retval None
1049   */
HAL_RCC_EnableCSS(void)1050 void HAL_RCC_EnableCSS(void)
1051 {
1052   SET_BIT(RCC->CR, RCC_CR_CSSON) ;
1053 }
1054 
1055 /**
1056   * @brief  Disables the Clock Security System.
1057   * @retval None
1058   */
HAL_RCC_DisableCSS(void)1059 void HAL_RCC_DisableCSS(void)
1060 {
1061   CLEAR_BIT(RCC->CR, RCC_CR_CSSON) ;
1062 }
1063 
1064 /**
1065   * @brief  Returns the SYSCLK frequency
1066   * @note   The system frequency computed by this function is not the real
1067   *         frequency in the chip. It is calculated based on the predefined
1068   *         constant and the selected clock source:
1069   * @note     If SYSCLK source is HSI, function returns values based on HSI_VALUE(*)
1070   * @note     If SYSCLK source is HSE, function returns a value based on HSE_VALUE
1071   *           divided by PREDIV factor(**)
1072   * @note     If SYSCLK source is PLL, function returns a value based on HSE_VALUE
1073   *           divided by PREDIV factor(**) or depending on STM32F0xxxx devices either a value based
1074   *           on HSI_VALUE divided by 2 or HSI_VALUE divided by PREDIV factor(*) multiplied by the
1075   *           PLL factor.
1076   * @note     (*) HSI_VALUE is a constant defined in stm32f0xx_hal_conf.h file (default value
1077   *               8 MHz) but the real value may vary depending on the variations
1078   *               in voltage and temperature.
1079   * @note     (**) HSE_VALUE is a constant defined in stm32f0xx_hal_conf.h file (default value
1080   *                8 MHz), user has to ensure that HSE_VALUE is same as the real
1081   *                frequency of the crystal used. Otherwise, this function may
1082   *                have wrong result.
1083   *
1084   * @note   The result of this function could be not correct when using fractional
1085   *         value for HSE crystal.
1086   *
1087   * @note   This function can be used by the user application to compute the
1088   *         baud-rate for the communication peripherals or configure other parameters.
1089   *
1090   * @note   Each time SYSCLK changes, this function must be called to update the
1091   *         right SYSCLK value. Otherwise, any configuration based on this function will be incorrect.
1092   *
1093   * @retval SYSCLK frequency
1094   */
HAL_RCC_GetSysClockFreq(void)1095 uint32_t HAL_RCC_GetSysClockFreq(void)
1096 {
1097   static const uint8_t aPLLMULFactorTable[16U] = { 2U,  3U,  4U,  5U,  6U,  7U,  8U,  9U,
1098                                                    10U, 11U, 12U, 13U, 14U, 15U, 16U, 16U};
1099   static const uint8_t aPredivFactorTable[16U] = { 1U, 2U,  3U,  4U,  5U,  6U,  7U,  8U,
1100                                                    9U,10U, 11U, 12U, 13U, 14U, 15U, 16U};
1101 
1102   uint32_t tmpreg = 0U, prediv = 0U, pllclk = 0U, pllmul = 0U;
1103   uint32_t sysclockfreq = 0U;
1104 
1105   tmpreg = RCC->CFGR;
1106 
1107   /* Get SYSCLK source -------------------------------------------------------*/
1108   switch (tmpreg & RCC_CFGR_SWS)
1109   {
1110     case RCC_SYSCLKSOURCE_STATUS_HSE:  /* HSE used as system clock */
1111     {
1112       sysclockfreq = HSE_VALUE;
1113       break;
1114     }
1115     case RCC_SYSCLKSOURCE_STATUS_PLLCLK:  /* PLL used as system clock */
1116     {
1117       pllmul = aPLLMULFactorTable[(uint32_t)(tmpreg & RCC_CFGR_PLLMUL) >> RCC_CFGR_PLLMUL_BITNUMBER];
1118       prediv = aPredivFactorTable[(uint32_t)(RCC->CFGR2 & RCC_CFGR2_PREDIV) >> RCC_CFGR2_PREDIV_BITNUMBER];
1119       if ((tmpreg & RCC_CFGR_PLLSRC) == RCC_PLLSOURCE_HSE)
1120       {
1121         /* HSE used as PLL clock source : PLLCLK = HSE/PREDIV * PLLMUL */
1122         pllclk = (uint32_t)((uint64_t) HSE_VALUE / (uint64_t) (prediv)) * ((uint64_t) pllmul);
1123       }
1124 #if defined(RCC_CFGR_PLLSRC_HSI48_PREDIV)
1125       else if ((tmpreg & RCC_CFGR_PLLSRC) == RCC_PLLSOURCE_HSI48)
1126       {
1127         /* HSI48 used as PLL clock source : PLLCLK = HSI48/PREDIV * PLLMUL */
1128         pllclk = (uint32_t)((uint64_t) HSI48_VALUE / (uint64_t) (prediv)) * ((uint64_t) pllmul);
1129       }
1130 #endif /* RCC_CFGR_PLLSRC_HSI48_PREDIV */
1131       else
1132       {
1133 #if  (defined(STM32F042x6) || defined(STM32F048xx) || defined(STM32F070x6) || defined(STM32F071xB) || defined(STM32F072xB) || defined(STM32F078xx) || defined(STM32F070xB) || defined(STM32F091xC) || defined(STM32F098xx) || defined(STM32F030xC))
1134         /* HSI used as PLL clock source : PLLCLK = HSI/PREDIV * PLLMUL */
1135         pllclk = (uint32_t)((uint64_t) HSI_VALUE / (uint64_t) (prediv)) * ((uint64_t) pllmul);
1136 #else
1137         /* HSI used as PLL clock source : PLLCLK = HSI/2 * PLLMUL */
1138         pllclk = (uint32_t)((uint64_t) (HSI_VALUE >> 1U) * ((uint64_t) pllmul));
1139 #endif
1140       }
1141       sysclockfreq = pllclk;
1142       break;
1143     }
1144 #if defined(RCC_CFGR_SWS_HSI48)
1145     case RCC_SYSCLKSOURCE_STATUS_HSI48:    /* HSI48 used as system clock source */
1146     {
1147       sysclockfreq = HSI48_VALUE;
1148       break;
1149     }
1150 #endif /* RCC_CFGR_SWS_HSI48 */
1151     case RCC_SYSCLKSOURCE_STATUS_HSI:  /* HSI used as system clock source */
1152     default: /* HSI used as system clock */
1153     {
1154       sysclockfreq = HSI_VALUE;
1155       break;
1156     }
1157   }
1158   return sysclockfreq;
1159 }
1160 
1161 /**
1162   * @brief  Returns the HCLK frequency
1163   * @note   Each time HCLK changes, this function must be called to update the
1164   *         right HCLK value. Otherwise, any configuration based on this function will be incorrect.
1165   *
1166   * @note   The SystemCoreClock CMSIS variable is used to store System Clock Frequency
1167   *         and updated within this function
1168   * @retval HCLK frequency
1169   */
HAL_RCC_GetHCLKFreq(void)1170 uint32_t HAL_RCC_GetHCLKFreq(void)
1171 {
1172   return SystemCoreClock;
1173 }
1174 
1175 /**
1176   * @brief  Returns the PCLK1 frequency
1177   * @note   Each time PCLK1 changes, this function must be called to update the
1178   *         right PCLK1 value. Otherwise, any configuration based on this function will be incorrect.
1179   * @retval PCLK1 frequency
1180   */
HAL_RCC_GetPCLK1Freq(void)1181 uint32_t HAL_RCC_GetPCLK1Freq(void)
1182 {
1183   /* Get HCLK source and Compute PCLK1 frequency ---------------------------*/
1184   return (HAL_RCC_GetHCLKFreq() >> APBPrescTable[(RCC->CFGR & RCC_CFGR_PPRE) >> RCC_CFGR_PPRE_BITNUMBER]);
1185 }
1186 
1187 /**
1188   * @brief  Configures the RCC_OscInitStruct according to the internal
1189   * RCC configuration registers.
1190   * @param  RCC_OscInitStruct pointer to an RCC_OscInitTypeDef structure that
1191   * will be configured.
1192   * @retval None
1193   */
HAL_RCC_GetOscConfig(RCC_OscInitTypeDef * RCC_OscInitStruct)1194 void HAL_RCC_GetOscConfig(RCC_OscInitTypeDef  *RCC_OscInitStruct)
1195 {
1196   /* Check the parameters */
1197   assert_param(RCC_OscInitStruct != NULL);
1198 
1199   /* Set all possible values for the Oscillator type parameter ---------------*/
1200   RCC_OscInitStruct->OscillatorType = RCC_OSCILLATORTYPE_HSE | RCC_OSCILLATORTYPE_HSI  \
1201                   | RCC_OSCILLATORTYPE_LSE | RCC_OSCILLATORTYPE_LSI | RCC_OSCILLATORTYPE_HSI14;
1202 #if defined(RCC_HSI48_SUPPORT)
1203   RCC_OscInitStruct->OscillatorType |= RCC_OSCILLATORTYPE_HSI48;
1204 #endif /* RCC_HSI48_SUPPORT */
1205 
1206 
1207   /* Get the HSE configuration -----------------------------------------------*/
1208   if((RCC->CR &RCC_CR_HSEBYP) == RCC_CR_HSEBYP)
1209   {
1210     RCC_OscInitStruct->HSEState = RCC_HSE_BYPASS;
1211   }
1212   else if((RCC->CR &RCC_CR_HSEON) == RCC_CR_HSEON)
1213   {
1214     RCC_OscInitStruct->HSEState = RCC_HSE_ON;
1215   }
1216   else
1217   {
1218     RCC_OscInitStruct->HSEState = RCC_HSE_OFF;
1219   }
1220 
1221   /* Get the HSI configuration -----------------------------------------------*/
1222   if((RCC->CR &RCC_CR_HSION) == RCC_CR_HSION)
1223   {
1224     RCC_OscInitStruct->HSIState = RCC_HSI_ON;
1225   }
1226   else
1227   {
1228     RCC_OscInitStruct->HSIState = RCC_HSI_OFF;
1229   }
1230 
1231   RCC_OscInitStruct->HSICalibrationValue = (uint32_t)((RCC->CR &RCC_CR_HSITRIM) >> RCC_CR_HSITRIM_BitNumber);
1232 
1233   /* Get the LSE configuration -----------------------------------------------*/
1234   if((RCC->BDCR &RCC_BDCR_LSEBYP) == RCC_BDCR_LSEBYP)
1235   {
1236     RCC_OscInitStruct->LSEState = RCC_LSE_BYPASS;
1237   }
1238   else if((RCC->BDCR &RCC_BDCR_LSEON) == RCC_BDCR_LSEON)
1239   {
1240     RCC_OscInitStruct->LSEState = RCC_LSE_ON;
1241   }
1242   else
1243   {
1244     RCC_OscInitStruct->LSEState = RCC_LSE_OFF;
1245   }
1246 
1247   /* Get the LSI configuration -----------------------------------------------*/
1248   if((RCC->CSR &RCC_CSR_LSION) == RCC_CSR_LSION)
1249   {
1250     RCC_OscInitStruct->LSIState = RCC_LSI_ON;
1251   }
1252   else
1253   {
1254     RCC_OscInitStruct->LSIState = RCC_LSI_OFF;
1255   }
1256 
1257   /* Get the HSI14 configuration -----------------------------------------------*/
1258   if((RCC->CR2 & RCC_CR2_HSI14ON) == RCC_CR2_HSI14ON)
1259   {
1260     RCC_OscInitStruct->HSI14State = RCC_HSI_ON;
1261   }
1262   else
1263   {
1264     RCC_OscInitStruct->HSI14State = RCC_HSI_OFF;
1265   }
1266 
1267   RCC_OscInitStruct->HSI14CalibrationValue = (uint32_t)((RCC->CR2 & RCC_CR2_HSI14TRIM) >> RCC_HSI14TRIM_BIT_NUMBER);
1268 
1269 #if defined(RCC_HSI48_SUPPORT)
1270   /* Get the HSI48 configuration if any-----------------------------------------*/
1271   RCC_OscInitStruct->HSI48State = __HAL_RCC_GET_HSI48_STATE();
1272 #endif /* RCC_HSI48_SUPPORT */
1273 
1274   /* Get the PLL configuration -----------------------------------------------*/
1275   if((RCC->CR &RCC_CR_PLLON) == RCC_CR_PLLON)
1276   {
1277     RCC_OscInitStruct->PLL.PLLState = RCC_PLL_ON;
1278   }
1279   else
1280   {
1281     RCC_OscInitStruct->PLL.PLLState = RCC_PLL_OFF;
1282   }
1283   RCC_OscInitStruct->PLL.PLLSource = (uint32_t)(RCC->CFGR & RCC_CFGR_PLLSRC);
1284   RCC_OscInitStruct->PLL.PLLMUL = (uint32_t)(RCC->CFGR & RCC_CFGR_PLLMUL);
1285   RCC_OscInitStruct->PLL.PREDIV = (uint32_t)(RCC->CFGR2 & RCC_CFGR2_PREDIV);
1286 }
1287 
1288 /**
1289   * @brief  Get the RCC_ClkInitStruct according to the internal
1290   * RCC configuration registers.
1291   * @param  RCC_ClkInitStruct pointer to an RCC_ClkInitTypeDef structure that
1292   * contains the current clock configuration.
1293   * @param  pFLatency Pointer on the Flash Latency.
1294   * @retval None
1295   */
HAL_RCC_GetClockConfig(RCC_ClkInitTypeDef * RCC_ClkInitStruct,uint32_t * pFLatency)1296 void HAL_RCC_GetClockConfig(RCC_ClkInitTypeDef  *RCC_ClkInitStruct, uint32_t *pFLatency)
1297 {
1298   /* Check the parameters */
1299   assert_param(RCC_ClkInitStruct != NULL);
1300   assert_param(pFLatency != NULL);
1301 
1302   /* Set all possible values for the Clock type parameter --------------------*/
1303   RCC_ClkInitStruct->ClockType = RCC_CLOCKTYPE_SYSCLK | RCC_CLOCKTYPE_HCLK | RCC_CLOCKTYPE_PCLK1;
1304 
1305   /* Get the SYSCLK configuration --------------------------------------------*/
1306   RCC_ClkInitStruct->SYSCLKSource = (uint32_t)(RCC->CFGR & RCC_CFGR_SW);
1307 
1308   /* Get the HCLK configuration ----------------------------------------------*/
1309   RCC_ClkInitStruct->AHBCLKDivider = (uint32_t)(RCC->CFGR & RCC_CFGR_HPRE);
1310 
1311   /* Get the APB1 configuration ----------------------------------------------*/
1312   RCC_ClkInitStruct->APB1CLKDivider = (uint32_t)(RCC->CFGR & RCC_CFGR_PPRE);
1313   /* Get the Flash Wait State (Latency) configuration ------------------------*/
1314   *pFLatency = __HAL_FLASH_GET_LATENCY();
1315 }
1316 
1317 /**
1318   * @brief This function handles the RCC CSS interrupt request.
1319   * @note This API should be called under the NMI_Handler().
1320   * @retval None
1321   */
HAL_RCC_NMI_IRQHandler(void)1322 void HAL_RCC_NMI_IRQHandler(void)
1323 {
1324   /* Check RCC CSSF flag  */
1325   if(__HAL_RCC_GET_IT(RCC_IT_CSS))
1326   {
1327     /* RCC Clock Security System interrupt user callback */
1328     HAL_RCC_CSSCallback();
1329 
1330     /* Clear RCC CSS pending bit */
1331     __HAL_RCC_CLEAR_IT(RCC_IT_CSS);
1332   }
1333 }
1334 
1335 /**
1336   * @brief  RCC Clock Security System interrupt callback
1337   * @retval none
1338   */
HAL_RCC_CSSCallback(void)1339 __weak void HAL_RCC_CSSCallback(void)
1340 {
1341   /* NOTE : This function Should not be modified, when the callback is needed,
1342     the HAL_RCC_CSSCallback could be implemented in the user file
1343     */
1344 }
1345 
1346 /**
1347   * @}
1348   */
1349 
1350 /**
1351   * @}
1352   */
1353 
1354 #endif /* HAL_RCC_MODULE_ENABLED */
1355 /**
1356   * @}
1357   */
1358 
1359 /**
1360   * @}
1361   */
1362 
1363