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