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