1 /**
2   ******************************************************************************
3   * @file    stm32f4xx_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 16MHz) with Flash 0 wait state, Flash prefetch buffer, D-Cache
18       and I-Cache are disabled, and all peripherals are off except internal
19       SRAM, Flash and JTAG.
20       (+) There is no prescaler on High speed (AHB) and Low speed (APB) busses;
21           all peripherals mapped on these busses are running at HSI speed.
22       (+) The clock for all peripherals is switched off, except the SRAM and FLASH.
23       (+) All GPIOs are in input floating state, except the JTAG pins which
24           are assigned to be used for debug purpose.
25 
26     [..]
27       Once the device started from reset, the user application has to:
28       (+) Configure the clock source to be used to drive the System clock
29           (if the application needs higher frequency/performance)
30       (+) Configure the System clock frequency and Flash settings
31       (+) Configure the AHB and APB busses prescalers
32       (+) Enable the clock for the peripheral(s) to be used
33       (+) Configure the clock source(s) for peripherals which clocks are not
34           derived from the System clock (I2S, RTC, ADC, USB OTG FS/SDIO/RNG)
35 
36                       ##### RCC Limitations #####
37   ==============================================================================
38     [..]
39       A delay between an RCC peripheral clock enable and the effective peripheral
40       enabling should be taken into account in order to manage the peripheral read/write
41       from/to registers.
42       (+) This delay depends on the peripheral mapping.
43       (+) If peripheral is mapped on AHB: the delay is 2 AHB clock cycle
44           after the clock enable bit is set on the hardware register
45       (+) If peripheral is mapped on APB: the delay is 2 APB clock cycle
46           after the clock enable bit is set on the hardware register
47 
48     [..]
49       Implemented Workaround:
50       (+) For AHB & APB peripherals, a dummy read to the peripheral register has been
51           inserted in each __HAL_RCC_PPP_CLK_ENABLE() macro.
52 
53   @endverbatim
54   ******************************************************************************
55   * @attention
56   *
57   * Copyright (c) 2017 STMicroelectronics.
58   * All rights reserved.
59   *
60   * This software is licensed under terms that can be found in the LICENSE file in
61   * the root directory of this software component.
62   * If no LICENSE file comes with this software, it is provided AS-IS.
63   ******************************************************************************
64   */
65 
66 /* Includes ------------------------------------------------------------------*/
67 #include "stm32f4xx_hal.h"
68 
69 /** @addtogroup STM32F4xx_HAL_Driver
70   * @{
71   */
72 
73 /** @defgroup RCC RCC
74   * @brief RCC HAL module driver
75   * @{
76   */
77 
78 #ifdef HAL_RCC_MODULE_ENABLED
79 
80 /* Private typedef -----------------------------------------------------------*/
81 /* Private define ------------------------------------------------------------*/
82 /** @addtogroup RCC_Private_Constants
83   * @{
84   */
85 
86 /* Private macro -------------------------------------------------------------*/
87 #define __MCO1_CLK_ENABLE()   __HAL_RCC_GPIOA_CLK_ENABLE()
88 #define MCO1_GPIO_PORT        GPIOA
89 #define MCO1_PIN              GPIO_PIN_8
90 
91 #define __MCO2_CLK_ENABLE()   __HAL_RCC_GPIOC_CLK_ENABLE()
92 #define MCO2_GPIO_PORT         GPIOC
93 #define MCO2_PIN               GPIO_PIN_9
94 /**
95   * @}
96   */
97 
98 /* Private variables ---------------------------------------------------------*/
99 /** @defgroup RCC_Private_Variables RCC Private Variables
100   * @{
101   */
102 /**
103   * @}
104   */
105 /* Private function prototypes -----------------------------------------------*/
106 /* Private functions ---------------------------------------------------------*/
107 
108 /** @defgroup RCC_Exported_Functions RCC Exported Functions
109   *  @{
110   */
111 
112 /** @defgroup RCC_Exported_Functions_Group1 Initialization and de-initialization functions
113   *  @brief    Initialization and Configuration functions
114   *
115 @verbatim
116  ===============================================================================
117            ##### Initialization and de-initialization functions #####
118  ===============================================================================
119     [..]
120       This section provides functions allowing to configure the internal/external oscillators
121       (HSE, HSI, LSE, LSI, PLL, CSS and MCO) and the System busses clocks (SYSCLK, AHB, APB1
122        and APB2).
123 
124     [..] Internal/external clock and PLL configuration
125          (#) HSI (high-speed internal), 16 MHz factory-trimmed RC used directly or through
126              the PLL as System clock source.
127 
128          (#) LSI (low-speed internal), 32 KHz low consumption RC used as IWDG and/or RTC
129              clock source.
130 
131          (#) HSE (high-speed external), 4 to 26 MHz crystal oscillator used directly or
132              through the PLL as System clock source. Can be used also as RTC clock source.
133 
134          (#) LSE (low-speed external), 32 KHz oscillator used as RTC clock source.
135 
136          (#) PLL (clocked by HSI or HSE), featuring two different output clocks:
137            (++) The first output is used to generate the high speed system clock (up to 168 MHz)
138            (++) The second output is used to generate the clock for the USB OTG FS (48 MHz),
139                 the random analog generator (<=48 MHz) and the SDIO (<= 48 MHz).
140 
141          (#) CSS (Clock security system), once enable using the macro __HAL_RCC_CSS_ENABLE()
142              and if a HSE clock failure occurs(HSE used directly or through PLL as System
143              clock source), the System clocks automatically switched to HSI and an interrupt
144              is generated if enabled. The interrupt is linked to the Cortex-M4 NMI
145              (Non-Maskable Interrupt) exception vector.
146 
147          (#) MCO1 (microcontroller clock output), used to output HSI, LSE, HSE or PLL
148              clock (through a configurable prescaler) on PA8 pin.
149 
150          (#) MCO2 (microcontroller clock output), used to output HSE, PLL, SYSCLK or PLLI2S
151              clock (through a configurable prescaler) on PC9 pin.
152 
153     [..] System, AHB and APB busses clocks configuration
154          (#) Several clock sources can be used to drive the System clock (SYSCLK): HSI,
155              HSE and PLL.
156              The AHB clock (HCLK) is derived from System clock through configurable
157              prescaler and used to clock the CPU, memory and peripherals mapped
158              on AHB bus (DMA, GPIO...). APB1 (PCLK1) and APB2 (PCLK2) clocks are derived
159              from AHB clock through configurable prescalers and used to clock
160              the peripherals mapped on these busses. You can use
161              "HAL_RCC_GetSysClockFreq()" function to retrieve the frequencies of these clocks.
162 
163          (#) For the STM32F405xx/07xx and STM32F415xx/17xx devices, the maximum
164              frequency of the SYSCLK and HCLK is 168 MHz, PCLK2 84 MHz and PCLK1 42 MHz.
165              Depending on the device voltage range, the maximum frequency should
166              be adapted accordingly (refer to the product datasheets for more details).
167 
168          (#) For the STM32F42xxx, STM32F43xxx, STM32F446xx, STM32F469xx and STM32F479xx devices,
169              the maximum frequency of the SYSCLK and HCLK is 180 MHz, PCLK2 90 MHz and PCLK1 45 MHz.
170              Depending on the device voltage range, the maximum frequency should
171              be adapted accordingly (refer to the product datasheets for more details).
172 
173          (#) For the STM32F401xx, the maximum frequency of the SYSCLK and HCLK is 84 MHz,
174              PCLK2 84 MHz and PCLK1 42 MHz.
175              Depending on the device voltage range, the maximum frequency should
176              be adapted accordingly (refer to the product datasheets for more details).
177 
178          (#) For the STM32F41xxx, the maximum frequency of the SYSCLK and HCLK is 100 MHz,
179              PCLK2 100 MHz and PCLK1 50 MHz.
180              Depending on the device voltage range, the maximum frequency should
181              be adapted accordingly (refer to the product datasheets for more details).
182 
183 @endverbatim
184   * @{
185   */
186 
187 /**
188   * @brief  Resets the RCC clock configuration to the default reset state.
189   * @note   The default reset state of the clock configuration is given below:
190   *            - HSI ON and used as system clock source
191   *            - HSE and PLL OFF
192   *            - AHB, APB1 and APB2 prescaler set to 1.
193   *            - CSS, MCO1 and MCO2 OFF
194   *            - All interrupts disabled
195   * @note   This function doesn't modify the configuration of the
196   *            - Peripheral clocks
197   *            - LSI, LSE and RTC clocks
198   * @retval HAL status
199   */
HAL_RCC_DeInit(void)200 __weak HAL_StatusTypeDef HAL_RCC_DeInit(void)
201 {
202   return HAL_OK;
203 }
204 
205 /**
206   * @brief  Initializes the RCC Oscillators according to the specified parameters in the
207   *         RCC_OscInitTypeDef.
208   * @param  RCC_OscInitStruct pointer to an RCC_OscInitTypeDef structure that
209   *         contains the configuration information for the RCC Oscillators.
210   * @note   The PLL is not disabled when used as system clock.
211   * @note   Transitions LSE Bypass to LSE On and LSE On to LSE Bypass are not
212   *         supported by this API. User should request a transition to LSE Off
213   *         first and then LSE On or LSE Bypass.
214   * @note   Transition HSE Bypass to HSE On and HSE On to HSE Bypass are not
215   *         supported by this API. User should request a transition to HSE Off
216   *         first and then HSE On or HSE Bypass.
217   * @retval HAL status
218   */
HAL_RCC_OscConfig(RCC_OscInitTypeDef * RCC_OscInitStruct)219 __weak HAL_StatusTypeDef HAL_RCC_OscConfig(RCC_OscInitTypeDef  *RCC_OscInitStruct)
220 {
221   uint32_t tickstart;
222   uint32_t pll_config;
223   /* Check Null pointer */
224   if (RCC_OscInitStruct == NULL)
225   {
226     return HAL_ERROR;
227   }
228 
229   /* Check the parameters */
230   assert_param(IS_RCC_OSCILLATORTYPE(RCC_OscInitStruct->OscillatorType));
231   /*------------------------------- HSE Configuration ------------------------*/
232   if (((RCC_OscInitStruct->OscillatorType) & RCC_OSCILLATORTYPE_HSE) == RCC_OSCILLATORTYPE_HSE)
233   {
234     /* Check the parameters */
235     assert_param(IS_RCC_HSE(RCC_OscInitStruct->HSEState));
236     /* When the HSE is used as system clock or clock source for PLL in these cases HSE will not disabled */
237     if ((__HAL_RCC_GET_SYSCLK_SOURCE() == RCC_CFGR_SWS_HSE) || \
238         ((__HAL_RCC_GET_SYSCLK_SOURCE() == RCC_CFGR_SWS_PLL) && ((RCC->PLLCFGR & RCC_PLLCFGR_PLLSRC) == RCC_PLLCFGR_PLLSRC_HSE)))
239     {
240       if ((__HAL_RCC_GET_FLAG(RCC_FLAG_HSERDY) != RESET) && (RCC_OscInitStruct->HSEState == RCC_HSE_OFF))
241       {
242         return HAL_ERROR;
243       }
244     }
245     else
246     {
247       /* Set the new HSE configuration ---------------------------------------*/
248       __HAL_RCC_HSE_CONFIG(RCC_OscInitStruct->HSEState);
249 
250       /* Check the HSE State */
251       if ((RCC_OscInitStruct->HSEState) != RCC_HSE_OFF)
252       {
253         /* Get Start Tick */
254         tickstart = HAL_GetTick();
255 
256         /* Wait till HSE is ready */
257         while (__HAL_RCC_GET_FLAG(RCC_FLAG_HSERDY) == RESET)
258         {
259           if ((HAL_GetTick() - tickstart) > HSE_TIMEOUT_VALUE)
260           {
261             return HAL_TIMEOUT;
262           }
263         }
264       }
265       else
266       {
267         /* Get Start Tick */
268         tickstart = HAL_GetTick();
269 
270         /* Wait till HSE is bypassed or disabled */
271         while (__HAL_RCC_GET_FLAG(RCC_FLAG_HSERDY) != RESET)
272         {
273           if ((HAL_GetTick() - tickstart) > HSE_TIMEOUT_VALUE)
274           {
275             return HAL_TIMEOUT;
276           }
277         }
278       }
279     }
280   }
281   /*----------------------------- HSI Configuration --------------------------*/
282   if (((RCC_OscInitStruct->OscillatorType) & RCC_OSCILLATORTYPE_HSI) == RCC_OSCILLATORTYPE_HSI)
283   {
284     /* Check the parameters */
285     assert_param(IS_RCC_HSI(RCC_OscInitStruct->HSIState));
286     assert_param(IS_RCC_CALIBRATION_VALUE(RCC_OscInitStruct->HSICalibrationValue));
287 
288     /* Check if HSI is used as system clock or as PLL source when PLL is selected as system clock */
289     if ((__HAL_RCC_GET_SYSCLK_SOURCE() == RCC_CFGR_SWS_HSI) || \
290         ((__HAL_RCC_GET_SYSCLK_SOURCE() == RCC_CFGR_SWS_PLL) && ((RCC->PLLCFGR & RCC_PLLCFGR_PLLSRC) == RCC_PLLCFGR_PLLSRC_HSI)))
291     {
292       /* When HSI is used as system clock it will not disabled */
293       if ((__HAL_RCC_GET_FLAG(RCC_FLAG_HSIRDY) != RESET) && (RCC_OscInitStruct->HSIState != RCC_HSI_ON))
294       {
295         return HAL_ERROR;
296       }
297       /* Otherwise, just the calibration is allowed */
298       else
299       {
300         /* Adjusts the Internal High Speed oscillator (HSI) calibration value.*/
301         __HAL_RCC_HSI_CALIBRATIONVALUE_ADJUST(RCC_OscInitStruct->HSICalibrationValue);
302       }
303     }
304     else
305     {
306       /* Check the HSI State */
307       if ((RCC_OscInitStruct->HSIState) != RCC_HSI_OFF)
308       {
309         /* Enable the Internal High Speed oscillator (HSI). */
310         __HAL_RCC_HSI_ENABLE();
311 
312         /* Get Start Tick*/
313         tickstart = HAL_GetTick();
314 
315         /* Wait till HSI is ready */
316         while (__HAL_RCC_GET_FLAG(RCC_FLAG_HSIRDY) == RESET)
317         {
318           if ((HAL_GetTick() - tickstart) > HSI_TIMEOUT_VALUE)
319           {
320             return HAL_TIMEOUT;
321           }
322         }
323 
324         /* Adjusts the Internal High Speed oscillator (HSI) calibration value. */
325         __HAL_RCC_HSI_CALIBRATIONVALUE_ADJUST(RCC_OscInitStruct->HSICalibrationValue);
326       }
327       else
328       {
329         /* Disable the Internal High Speed oscillator (HSI). */
330         __HAL_RCC_HSI_DISABLE();
331 
332         /* Get Start Tick*/
333         tickstart = HAL_GetTick();
334 
335         /* Wait till HSI is ready */
336         while (__HAL_RCC_GET_FLAG(RCC_FLAG_HSIRDY) != RESET)
337         {
338           if ((HAL_GetTick() - tickstart) > HSI_TIMEOUT_VALUE)
339           {
340             return HAL_TIMEOUT;
341           }
342         }
343       }
344     }
345   }
346   /*------------------------------ LSI Configuration -------------------------*/
347   if (((RCC_OscInitStruct->OscillatorType) & RCC_OSCILLATORTYPE_LSI) == RCC_OSCILLATORTYPE_LSI)
348   {
349     /* Check the parameters */
350     assert_param(IS_RCC_LSI(RCC_OscInitStruct->LSIState));
351 
352     /* Check the LSI State */
353     if ((RCC_OscInitStruct->LSIState) != RCC_LSI_OFF)
354     {
355       /* Enable the Internal Low Speed oscillator (LSI). */
356       __HAL_RCC_LSI_ENABLE();
357 
358       /* Get Start Tick*/
359       tickstart = HAL_GetTick();
360 
361       /* Wait till LSI is ready */
362       while (__HAL_RCC_GET_FLAG(RCC_FLAG_LSIRDY) == RESET)
363       {
364         if ((HAL_GetTick() - tickstart) > LSI_TIMEOUT_VALUE)
365         {
366           return HAL_TIMEOUT;
367         }
368       }
369     }
370     else
371     {
372       /* Disable the Internal Low Speed oscillator (LSI). */
373       __HAL_RCC_LSI_DISABLE();
374 
375       /* Get Start Tick */
376       tickstart = HAL_GetTick();
377 
378       /* Wait till LSI is ready */
379       while (__HAL_RCC_GET_FLAG(RCC_FLAG_LSIRDY) != RESET)
380       {
381         if ((HAL_GetTick() - tickstart) > LSI_TIMEOUT_VALUE)
382         {
383           return HAL_TIMEOUT;
384         }
385       }
386     }
387   }
388   /*------------------------------ LSE Configuration -------------------------*/
389   if (((RCC_OscInitStruct->OscillatorType) & RCC_OSCILLATORTYPE_LSE) == RCC_OSCILLATORTYPE_LSE)
390   {
391     FlagStatus       pwrclkchanged = RESET;
392 
393     /* Check the parameters */
394     assert_param(IS_RCC_LSE(RCC_OscInitStruct->LSEState));
395 
396     /* Update LSE configuration in Backup Domain control register    */
397     /* Requires to enable write access to Backup Domain of necessary */
398     if (__HAL_RCC_PWR_IS_CLK_DISABLED())
399     {
400       __HAL_RCC_PWR_CLK_ENABLE();
401       pwrclkchanged = SET;
402     }
403 
404     if (HAL_IS_BIT_CLR(PWR->CR, PWR_CR_DBP))
405     {
406       /* Enable write access to Backup domain */
407       SET_BIT(PWR->CR, PWR_CR_DBP);
408 
409       /* Wait for Backup domain Write protection disable */
410       tickstart = HAL_GetTick();
411 
412       while (HAL_IS_BIT_CLR(PWR->CR, PWR_CR_DBP))
413       {
414         if ((HAL_GetTick() - tickstart) > RCC_DBP_TIMEOUT_VALUE)
415         {
416           return HAL_TIMEOUT;
417         }
418       }
419     }
420 
421     /* Set the new LSE configuration -----------------------------------------*/
422     __HAL_RCC_LSE_CONFIG(RCC_OscInitStruct->LSEState);
423     /* Check the LSE State */
424     if ((RCC_OscInitStruct->LSEState) != RCC_LSE_OFF)
425     {
426       /* Get Start Tick*/
427       tickstart = HAL_GetTick();
428 
429       /* Wait till LSE is ready */
430       while (__HAL_RCC_GET_FLAG(RCC_FLAG_LSERDY) == RESET)
431       {
432         if ((HAL_GetTick() - tickstart) > RCC_LSE_TIMEOUT_VALUE)
433         {
434           return HAL_TIMEOUT;
435         }
436       }
437     }
438     else
439     {
440       /* Get Start Tick */
441       tickstart = HAL_GetTick();
442 
443       /* Wait till LSE is ready */
444       while (__HAL_RCC_GET_FLAG(RCC_FLAG_LSERDY) != RESET)
445       {
446         if ((HAL_GetTick() - tickstart) > RCC_LSE_TIMEOUT_VALUE)
447         {
448           return HAL_TIMEOUT;
449         }
450       }
451     }
452 
453     /* Restore clock configuration if changed */
454     if (pwrclkchanged == SET)
455     {
456       __HAL_RCC_PWR_CLK_DISABLE();
457     }
458   }
459   /*-------------------------------- PLL Configuration -----------------------*/
460   /* Check the parameters */
461   assert_param(IS_RCC_PLL(RCC_OscInitStruct->PLL.PLLState));
462   if ((RCC_OscInitStruct->PLL.PLLState) != RCC_PLL_NONE)
463   {
464     /* Check if the PLL is used as system clock or not */
465     if (__HAL_RCC_GET_SYSCLK_SOURCE() != RCC_CFGR_SWS_PLL)
466     {
467       if ((RCC_OscInitStruct->PLL.PLLState) == RCC_PLL_ON)
468       {
469         /* Check the parameters */
470         assert_param(IS_RCC_PLLSOURCE(RCC_OscInitStruct->PLL.PLLSource));
471         assert_param(IS_RCC_PLLM_VALUE(RCC_OscInitStruct->PLL.PLLM));
472         assert_param(IS_RCC_PLLN_VALUE(RCC_OscInitStruct->PLL.PLLN));
473         assert_param(IS_RCC_PLLP_VALUE(RCC_OscInitStruct->PLL.PLLP));
474         assert_param(IS_RCC_PLLQ_VALUE(RCC_OscInitStruct->PLL.PLLQ));
475 
476         /* Disable the main PLL. */
477         __HAL_RCC_PLL_DISABLE();
478 
479         /* Get Start Tick */
480         tickstart = HAL_GetTick();
481 
482         /* Wait till PLL is disabled */
483         while (__HAL_RCC_GET_FLAG(RCC_FLAG_PLLRDY) != RESET)
484         {
485           if ((HAL_GetTick() - tickstart) > PLL_TIMEOUT_VALUE)
486           {
487             return HAL_TIMEOUT;
488           }
489         }
490 
491         /* Configure the main PLL clock source, multiplication and division factors. */
492         WRITE_REG(RCC->PLLCFGR, (RCC_OscInitStruct->PLL.PLLSource                                            | \
493                                  RCC_OscInitStruct->PLL.PLLM                                                 | \
494                                  (RCC_OscInitStruct->PLL.PLLN << RCC_PLLCFGR_PLLN_Pos)             | \
495                                  (((RCC_OscInitStruct->PLL.PLLP >> 1U) - 1U) << RCC_PLLCFGR_PLLP_Pos) | \
496                                  (RCC_OscInitStruct->PLL.PLLQ << RCC_PLLCFGR_PLLQ_Pos)));
497         /* Enable the main PLL. */
498         __HAL_RCC_PLL_ENABLE();
499 
500         /* Get Start Tick */
501         tickstart = HAL_GetTick();
502 
503         /* Wait till PLL is ready */
504         while (__HAL_RCC_GET_FLAG(RCC_FLAG_PLLRDY) == RESET)
505         {
506           if ((HAL_GetTick() - tickstart) > PLL_TIMEOUT_VALUE)
507           {
508             return HAL_TIMEOUT;
509           }
510         }
511       }
512       else
513       {
514         /* Disable the main PLL. */
515         __HAL_RCC_PLL_DISABLE();
516 
517         /* Get Start Tick */
518         tickstart = HAL_GetTick();
519 
520         /* Wait till PLL is disabled */
521         while (__HAL_RCC_GET_FLAG(RCC_FLAG_PLLRDY) != RESET)
522         {
523           if ((HAL_GetTick() - tickstart) > PLL_TIMEOUT_VALUE)
524           {
525             return HAL_TIMEOUT;
526           }
527         }
528       }
529     }
530     else
531     {
532       /* Check if there is a request to disable the PLL used as System clock source */
533       if ((RCC_OscInitStruct->PLL.PLLState) == RCC_PLL_OFF)
534       {
535         return HAL_ERROR;
536       }
537       else
538       {
539         /* Do not return HAL_ERROR if request repeats the current configuration */
540         pll_config = RCC->PLLCFGR;
541 #if defined (RCC_PLLCFGR_PLLR)
542         if (((RCC_OscInitStruct->PLL.PLLState) == RCC_PLL_OFF) ||
543             (READ_BIT(pll_config, RCC_PLLCFGR_PLLSRC) != RCC_OscInitStruct->PLL.PLLSource) ||
544             (READ_BIT(pll_config, RCC_PLLCFGR_PLLM) != (RCC_OscInitStruct->PLL.PLLM) << RCC_PLLCFGR_PLLM_Pos) ||
545             (READ_BIT(pll_config, RCC_PLLCFGR_PLLN) != (RCC_OscInitStruct->PLL.PLLN) << RCC_PLLCFGR_PLLN_Pos) ||
546             (READ_BIT(pll_config, RCC_PLLCFGR_PLLP) != (((RCC_OscInitStruct->PLL.PLLP >> 1U) - 1U)) << RCC_PLLCFGR_PLLP_Pos) ||
547             (READ_BIT(pll_config, RCC_PLLCFGR_PLLQ) != (RCC_OscInitStruct->PLL.PLLQ << RCC_PLLCFGR_PLLQ_Pos)) ||
548             (READ_BIT(pll_config, RCC_PLLCFGR_PLLR) != (RCC_OscInitStruct->PLL.PLLR << RCC_PLLCFGR_PLLR_Pos)))
549 #else
550         if (((RCC_OscInitStruct->PLL.PLLState) == RCC_PLL_OFF) ||
551             (READ_BIT(pll_config, RCC_PLLCFGR_PLLSRC) != RCC_OscInitStruct->PLL.PLLSource) ||
552             (READ_BIT(pll_config, RCC_PLLCFGR_PLLM) != (RCC_OscInitStruct->PLL.PLLM) << RCC_PLLCFGR_PLLM_Pos) ||
553             (READ_BIT(pll_config, RCC_PLLCFGR_PLLN) != (RCC_OscInitStruct->PLL.PLLN) << RCC_PLLCFGR_PLLN_Pos) ||
554             (READ_BIT(pll_config, RCC_PLLCFGR_PLLP) != (((RCC_OscInitStruct->PLL.PLLP >> 1U) - 1U)) << RCC_PLLCFGR_PLLP_Pos) ||
555             (READ_BIT(pll_config, RCC_PLLCFGR_PLLQ) != (RCC_OscInitStruct->PLL.PLLQ << RCC_PLLCFGR_PLLQ_Pos)))
556 #endif /* RCC_PLLCFGR_PLLR */
557         {
558           return HAL_ERROR;
559         }
560       }
561     }
562   }
563   return HAL_OK;
564 }
565 
566 /**
567   * @brief  Initializes the CPU, AHB and APB busses clocks according to the specified
568   *         parameters in the RCC_ClkInitStruct.
569   * @param  RCC_ClkInitStruct pointer to an RCC_OscInitTypeDef structure that
570   *         contains the configuration information for the RCC peripheral.
571   * @param  FLatency FLASH Latency, this parameter depend on device selected
572   *
573   * @note   The SystemCoreClock CMSIS variable is used to store System Clock Frequency
574   *         and updated by HAL_RCC_GetHCLKFreq() function called within this function
575   *
576   * @note   The HSI is used (enabled by hardware) as system clock source after
577   *         startup from Reset, wake-up from STOP and STANDBY mode, or in case
578   *         of failure of the HSE used directly or indirectly as system clock
579   *         (if the Clock Security System CSS is enabled).
580   *
581   * @note   A switch from one clock source to another occurs only if the target
582   *         clock source is ready (clock stable after startup delay or PLL locked).
583   *         If a clock source which is not yet ready is selected, the switch will
584   *         occur when the clock source will be ready.
585   *
586   * @note   Depending on the device voltage range, the software has to set correctly
587   *         HPRE[3:0] bits to ensure that HCLK not exceed the maximum allowed frequency
588   *         (for more details refer to section above "Initialization/de-initialization functions")
589   * @retval None
590   */
HAL_RCC_ClockConfig(RCC_ClkInitTypeDef * RCC_ClkInitStruct,uint32_t FLatency)591 HAL_StatusTypeDef HAL_RCC_ClockConfig(RCC_ClkInitTypeDef  *RCC_ClkInitStruct, uint32_t FLatency)
592 {
593   uint32_t tickstart;
594 
595   /* Check Null pointer */
596   if (RCC_ClkInitStruct == NULL)
597   {
598     return HAL_ERROR;
599   }
600 
601   /* Check the parameters */
602   assert_param(IS_RCC_CLOCKTYPE(RCC_ClkInitStruct->ClockType));
603   assert_param(IS_FLASH_LATENCY(FLatency));
604 
605   /* To correctly read data from FLASH memory, the number of wait states (LATENCY)
606     must be correctly programmed according to the frequency of the CPU clock
607     (HCLK) and the supply voltage of the device. */
608 
609   /* Increasing the number of wait states because of higher CPU frequency */
610   if (FLatency > __HAL_FLASH_GET_LATENCY())
611   {
612     /* Program the new number of wait states to the LATENCY bits in the FLASH_ACR register */
613     __HAL_FLASH_SET_LATENCY(FLatency);
614 
615     /* Check that the new number of wait states is taken into account to access the Flash
616     memory by reading the FLASH_ACR register */
617     if (__HAL_FLASH_GET_LATENCY() != FLatency)
618     {
619       return HAL_ERROR;
620     }
621   }
622 
623   /*-------------------------- HCLK Configuration --------------------------*/
624   if (((RCC_ClkInitStruct->ClockType) & RCC_CLOCKTYPE_HCLK) == RCC_CLOCKTYPE_HCLK)
625   {
626     /* Set the highest APBx dividers in order to ensure that we do not go through
627        a non-spec phase whatever we decrease or increase HCLK. */
628     if (((RCC_ClkInitStruct->ClockType) & RCC_CLOCKTYPE_PCLK1) == RCC_CLOCKTYPE_PCLK1)
629     {
630       MODIFY_REG(RCC->CFGR, RCC_CFGR_PPRE1, RCC_HCLK_DIV16);
631     }
632 
633     if (((RCC_ClkInitStruct->ClockType) & RCC_CLOCKTYPE_PCLK2) == RCC_CLOCKTYPE_PCLK2)
634     {
635       MODIFY_REG(RCC->CFGR, RCC_CFGR_PPRE2, (RCC_HCLK_DIV16 << 3));
636     }
637 
638     assert_param(IS_RCC_HCLK(RCC_ClkInitStruct->AHBCLKDivider));
639     MODIFY_REG(RCC->CFGR, RCC_CFGR_HPRE, RCC_ClkInitStruct->AHBCLKDivider);
640   }
641 
642   /*------------------------- SYSCLK Configuration ---------------------------*/
643   if (((RCC_ClkInitStruct->ClockType) & RCC_CLOCKTYPE_SYSCLK) == RCC_CLOCKTYPE_SYSCLK)
644   {
645     assert_param(IS_RCC_SYSCLKSOURCE(RCC_ClkInitStruct->SYSCLKSource));
646 
647     /* HSE is selected as System Clock Source */
648     if (RCC_ClkInitStruct->SYSCLKSource == RCC_SYSCLKSOURCE_HSE)
649     {
650       /* Check the HSE ready flag */
651       if (__HAL_RCC_GET_FLAG(RCC_FLAG_HSERDY) == RESET)
652       {
653         return HAL_ERROR;
654       }
655     }
656     /* PLL is selected as System Clock Source */
657     else if ((RCC_ClkInitStruct->SYSCLKSource == RCC_SYSCLKSOURCE_PLLCLK)   ||
658              (RCC_ClkInitStruct->SYSCLKSource == RCC_SYSCLKSOURCE_PLLRCLK))
659     {
660       /* Check the PLL ready flag */
661       if (__HAL_RCC_GET_FLAG(RCC_FLAG_PLLRDY) == RESET)
662       {
663         return HAL_ERROR;
664       }
665     }
666     /* HSI is selected as System Clock Source */
667     else
668     {
669       /* Check the HSI ready flag */
670       if (__HAL_RCC_GET_FLAG(RCC_FLAG_HSIRDY) == RESET)
671       {
672         return HAL_ERROR;
673       }
674     }
675 
676     __HAL_RCC_SYSCLK_CONFIG(RCC_ClkInitStruct->SYSCLKSource);
677 
678     /* Get Start Tick */
679     tickstart = HAL_GetTick();
680 
681     while (__HAL_RCC_GET_SYSCLK_SOURCE() != (RCC_ClkInitStruct->SYSCLKSource << RCC_CFGR_SWS_Pos))
682     {
683       if ((HAL_GetTick() - tickstart) > CLOCKSWITCH_TIMEOUT_VALUE)
684       {
685         return HAL_TIMEOUT;
686       }
687     }
688   }
689 
690   /* Decreasing the number of wait states because of lower CPU frequency */
691   if (FLatency < __HAL_FLASH_GET_LATENCY())
692   {
693     /* Program the new number of wait states to the LATENCY bits in the FLASH_ACR register */
694     __HAL_FLASH_SET_LATENCY(FLatency);
695 
696     /* Check that the new number of wait states is taken into account to access the Flash
697     memory by reading the FLASH_ACR register */
698     if (__HAL_FLASH_GET_LATENCY() != FLatency)
699     {
700       return HAL_ERROR;
701     }
702   }
703 
704   /*-------------------------- PCLK1 Configuration ---------------------------*/
705   if (((RCC_ClkInitStruct->ClockType) & RCC_CLOCKTYPE_PCLK1) == RCC_CLOCKTYPE_PCLK1)
706   {
707     assert_param(IS_RCC_PCLK(RCC_ClkInitStruct->APB1CLKDivider));
708     MODIFY_REG(RCC->CFGR, RCC_CFGR_PPRE1, RCC_ClkInitStruct->APB1CLKDivider);
709   }
710 
711   /*-------------------------- PCLK2 Configuration ---------------------------*/
712   if (((RCC_ClkInitStruct->ClockType) & RCC_CLOCKTYPE_PCLK2) == RCC_CLOCKTYPE_PCLK2)
713   {
714     assert_param(IS_RCC_PCLK(RCC_ClkInitStruct->APB2CLKDivider));
715     MODIFY_REG(RCC->CFGR, RCC_CFGR_PPRE2, ((RCC_ClkInitStruct->APB2CLKDivider) << 3U));
716   }
717 
718   /* Update the SystemCoreClock global variable */
719   SystemCoreClock = HAL_RCC_GetSysClockFreq() >> AHBPrescTable[(RCC->CFGR & RCC_CFGR_HPRE) >> RCC_CFGR_HPRE_Pos];
720 
721   /* Configure the source of time base considering new system clocks settings */
722   HAL_InitTick(uwTickPrio);
723 
724   return HAL_OK;
725 }
726 
727 /**
728   * @}
729   */
730 
731 /** @defgroup RCC_Exported_Functions_Group2 Peripheral Control functions
732   *  @brief   RCC clocks control functions
733   *
734 @verbatim
735  ===============================================================================
736                       ##### Peripheral Control functions #####
737  ===============================================================================
738     [..]
739     This subsection provides a set of functions allowing to control the RCC Clocks
740     frequencies.
741 
742 @endverbatim
743   * @{
744   */
745 
746 /**
747   * @brief  Selects the clock source to output on MCO1 pin(PA8) or on MCO2 pin(PC9).
748   * @note   PA8/PC9 should be configured in alternate function mode.
749   * @param  RCC_MCOx specifies the output direction for the clock source.
750   *          This parameter can be one of the following values:
751   *            @arg RCC_MCO1: Clock source to output on MCO1 pin(PA8).
752   *            @arg RCC_MCO2: Clock source to output on MCO2 pin(PC9).
753   * @param  RCC_MCOSource specifies the clock source to output.
754   *          This parameter can be one of the following values:
755   *            @arg RCC_MCO1SOURCE_HSI: HSI clock selected as MCO1 source
756   *            @arg RCC_MCO1SOURCE_LSE: LSE clock selected as MCO1 source
757   *            @arg RCC_MCO1SOURCE_HSE: HSE clock selected as MCO1 source
758   *            @arg RCC_MCO1SOURCE_PLLCLK: main PLL clock selected as MCO1 source
759   *            @arg RCC_MCO2SOURCE_SYSCLK: System clock (SYSCLK) selected as MCO2 source
760   *            @arg RCC_MCO2SOURCE_PLLI2SCLK: PLLI2S clock selected as MCO2 source, available for all STM32F4 devices except STM32F410xx
761   *            @arg RCC_MCO2SOURCE_I2SCLK: I2SCLK clock selected as MCO2 source, available only for STM32F410Rx devices
762   *            @arg RCC_MCO2SOURCE_HSE: HSE clock selected as MCO2 source
763   *            @arg RCC_MCO2SOURCE_PLLCLK: main PLL clock selected as MCO2 source
764   * @param  RCC_MCODiv specifies the MCOx prescaler.
765   *          This parameter can be one of the following values:
766   *            @arg RCC_MCODIV_1: no division applied to MCOx clock
767   *            @arg RCC_MCODIV_2: division by 2 applied to MCOx clock
768   *            @arg RCC_MCODIV_3: division by 3 applied to MCOx clock
769   *            @arg RCC_MCODIV_4: division by 4 applied to MCOx clock
770   *            @arg RCC_MCODIV_5: division by 5 applied to MCOx clock
771   * @note  For STM32F410Rx devices to output I2SCLK clock on MCO2 you should have
772   *        at last one of the SPI clocks enabled (SPI1, SPI2 or SPI5).
773   * @retval None
774   */
HAL_RCC_MCOConfig(uint32_t RCC_MCOx,uint32_t RCC_MCOSource,uint32_t RCC_MCODiv)775 void HAL_RCC_MCOConfig(uint32_t RCC_MCOx, uint32_t RCC_MCOSource, uint32_t RCC_MCODiv)
776 {
777   GPIO_InitTypeDef GPIO_InitStruct;
778   /* Check the parameters */
779   assert_param(IS_RCC_MCO(RCC_MCOx));
780   assert_param(IS_RCC_MCODIV(RCC_MCODiv));
781   /* RCC_MCO1 */
782   if (RCC_MCOx == RCC_MCO1)
783   {
784     assert_param(IS_RCC_MCO1SOURCE(RCC_MCOSource));
785 
786     /* MCO1 Clock Enable */
787     __MCO1_CLK_ENABLE();
788 
789     /* Configure the MCO1 pin in alternate function mode */
790     GPIO_InitStruct.Pin = MCO1_PIN;
791     GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
792     GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
793     GPIO_InitStruct.Pull = GPIO_NOPULL;
794     GPIO_InitStruct.Alternate = GPIO_AF0_MCO;
795     HAL_GPIO_Init(MCO1_GPIO_PORT, &GPIO_InitStruct);
796 
797     /* Mask MCO1 and MCO1PRE[2:0] bits then Select MCO1 clock source and prescaler */
798     MODIFY_REG(RCC->CFGR, (RCC_CFGR_MCO1 | RCC_CFGR_MCO1PRE), (RCC_MCOSource | RCC_MCODiv));
799 
800     /* This RCC MCO1 enable feature is available only on STM32F410xx devices */
801 #if defined(RCC_CFGR_MCO1EN)
802     __HAL_RCC_MCO1_ENABLE();
803 #endif /* RCC_CFGR_MCO1EN */
804   }
805 #if defined(RCC_CFGR_MCO2)
806   else
807   {
808     assert_param(IS_RCC_MCO2SOURCE(RCC_MCOSource));
809 
810     /* MCO2 Clock Enable */
811     __MCO2_CLK_ENABLE();
812 
813     /* Configure the MCO2 pin in alternate function mode */
814     GPIO_InitStruct.Pin = MCO2_PIN;
815     GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
816     GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
817     GPIO_InitStruct.Pull = GPIO_NOPULL;
818     GPIO_InitStruct.Alternate = GPIO_AF0_MCO;
819     HAL_GPIO_Init(MCO2_GPIO_PORT, &GPIO_InitStruct);
820 
821     /* Mask MCO2 and MCO2PRE[2:0] bits then Select MCO2 clock source and prescaler */
822     MODIFY_REG(RCC->CFGR, (RCC_CFGR_MCO2 | RCC_CFGR_MCO2PRE), (RCC_MCOSource | (RCC_MCODiv << 3U)));
823 
824     /* This RCC MCO2 enable feature is available only on STM32F410Rx devices */
825 #if defined(RCC_CFGR_MCO2EN)
826     __HAL_RCC_MCO2_ENABLE();
827 #endif /* RCC_CFGR_MCO2EN */
828   }
829 #endif /* RCC_CFGR_MCO2 */
830 }
831 
832 /**
833   * @brief  Enables the Clock Security System.
834   * @note   If a failure is detected on the HSE oscillator clock, this oscillator
835   *         is automatically disabled and an interrupt is generated to inform the
836   *         software about the failure (Clock Security System Interrupt, CSSI),
837   *         allowing the MCU to perform rescue operations. The CSSI is linked to
838   *         the Cortex-M4 NMI (Non-Maskable Interrupt) exception vector.
839   * @retval None
840   */
HAL_RCC_EnableCSS(void)841 void HAL_RCC_EnableCSS(void)
842 {
843   *(__IO uint32_t *) RCC_CR_CSSON_BB = (uint32_t)ENABLE;
844 }
845 
846 /**
847   * @brief  Disables the Clock Security System.
848   * @retval None
849   */
HAL_RCC_DisableCSS(void)850 void HAL_RCC_DisableCSS(void)
851 {
852   *(__IO uint32_t *) RCC_CR_CSSON_BB = (uint32_t)DISABLE;
853 }
854 
855 /**
856   * @brief  Returns the SYSCLK frequency
857   *
858   * @note   The system frequency computed by this function is not the real
859   *         frequency in the chip. It is calculated based on the predefined
860   *         constant and the selected clock source:
861   * @note     If SYSCLK source is HSI, function returns values based on HSI_VALUE(*)
862   * @note     If SYSCLK source is HSE, function returns values based on HSE_VALUE(**)
863   * @note     If SYSCLK source is PLL, function returns values based on HSE_VALUE(**)
864   *           or HSI_VALUE(*) multiplied/divided by the PLL factors.
865   * @note     (*) HSI_VALUE is a constant defined in stm32f4xx_hal_conf.h file (default value
866   *               16 MHz) but the real value may vary depending on the variations
867   *               in voltage and temperature.
868   * @note     (**) HSE_VALUE is a constant defined in stm32f4xx_hal_conf.h file (default value
869   *                25 MHz), user has to ensure that HSE_VALUE is same as the real
870   *                frequency of the crystal used. Otherwise, this function may
871   *                have wrong result.
872   *
873   * @note   The result of this function could be not correct when using fractional
874   *         value for HSE crystal.
875   *
876   * @note   This function can be used by the user application to compute the
877   *         baudrate for the communication peripherals or configure other parameters.
878   *
879   * @note   Each time SYSCLK changes, this function must be called to update the
880   *         right SYSCLK value. Otherwise, any configuration based on this function will be incorrect.
881   *
882   *
883   * @retval SYSCLK frequency
884   */
HAL_RCC_GetSysClockFreq(void)885 __weak uint32_t HAL_RCC_GetSysClockFreq(void)
886 {
887   uint32_t pllm = 0U;
888   uint32_t pllvco = 0U;
889   uint32_t pllp = 0U;
890   uint32_t sysclockfreq = 0U;
891 
892   /* Get SYSCLK source -------------------------------------------------------*/
893   switch (RCC->CFGR & RCC_CFGR_SWS)
894   {
895     case RCC_CFGR_SWS_HSI:  /* HSI used as system clock source */
896     {
897       sysclockfreq = HSI_VALUE;
898       break;
899     }
900     case RCC_CFGR_SWS_HSE:  /* HSE used as system clock  source */
901     {
902       sysclockfreq = HSE_VALUE;
903       break;
904     }
905     case RCC_CFGR_SWS_PLL:  /* PLL used as system clock  source */
906     {
907       /* PLL_VCO = (HSE_VALUE or HSI_VALUE / PLLM) * PLLN
908       SYSCLK = PLL_VCO / PLLP */
909       pllm = RCC->PLLCFGR & RCC_PLLCFGR_PLLM;
910       if (__HAL_RCC_GET_PLL_OSCSOURCE() != RCC_PLLSOURCE_HSI)
911       {
912         /* HSE used as PLL clock source */
913         pllvco = (uint32_t)((((uint64_t) HSE_VALUE * ((uint64_t)((RCC->PLLCFGR & RCC_PLLCFGR_PLLN) >> RCC_PLLCFGR_PLLN_Pos)))) / (uint64_t)pllm);
914       }
915       else
916       {
917         /* HSI used as PLL clock source */
918         pllvco = (uint32_t)((((uint64_t) HSI_VALUE * ((uint64_t)((RCC->PLLCFGR & RCC_PLLCFGR_PLLN) >> RCC_PLLCFGR_PLLN_Pos)))) / (uint64_t)pllm);
919       }
920       pllp = ((((RCC->PLLCFGR & RCC_PLLCFGR_PLLP) >> RCC_PLLCFGR_PLLP_Pos) + 1U) * 2U);
921 
922       sysclockfreq = pllvco / pllp;
923       break;
924     }
925     default:
926     {
927       sysclockfreq = HSI_VALUE;
928       break;
929     }
930   }
931   return sysclockfreq;
932 }
933 
934 /**
935   * @brief  Returns the HCLK frequency
936   * @note   Each time HCLK changes, this function must be called to update the
937   *         right HCLK value. Otherwise, any configuration based on this function will be incorrect.
938   *
939   * @note   The SystemCoreClock CMSIS variable is used to store System Clock Frequency
940   *         and updated within this function
941   * @retval HCLK frequency
942   */
HAL_RCC_GetHCLKFreq(void)943 uint32_t HAL_RCC_GetHCLKFreq(void)
944 {
945   return SystemCoreClock;
946 }
947 
948 /**
949   * @brief  Returns the PCLK1 frequency
950   * @note   Each time PCLK1 changes, this function must be called to update the
951   *         right PCLK1 value. Otherwise, any configuration based on this function will be incorrect.
952   * @retval PCLK1 frequency
953   */
HAL_RCC_GetPCLK1Freq(void)954 uint32_t HAL_RCC_GetPCLK1Freq(void)
955 {
956   /* Get HCLK source and Compute PCLK1 frequency ---------------------------*/
957   return (HAL_RCC_GetHCLKFreq() >> APBPrescTable[(RCC->CFGR & RCC_CFGR_PPRE1) >> RCC_CFGR_PPRE1_Pos]);
958 }
959 
960 /**
961   * @brief  Returns the PCLK2 frequency
962   * @note   Each time PCLK2 changes, this function must be called to update the
963   *         right PCLK2 value. Otherwise, any configuration based on this function will be incorrect.
964   * @retval PCLK2 frequency
965   */
HAL_RCC_GetPCLK2Freq(void)966 uint32_t HAL_RCC_GetPCLK2Freq(void)
967 {
968   /* Get HCLK source and Compute PCLK2 frequency ---------------------------*/
969   return (HAL_RCC_GetHCLKFreq() >> APBPrescTable[(RCC->CFGR & RCC_CFGR_PPRE2) >> RCC_CFGR_PPRE2_Pos]);
970 }
971 
972 /**
973   * @brief  Configures the RCC_OscInitStruct according to the internal
974   * RCC configuration registers.
975   * @param  RCC_OscInitStruct pointer to an RCC_OscInitTypeDef structure that
976   * will be configured.
977   * @retval None
978   */
HAL_RCC_GetOscConfig(RCC_OscInitTypeDef * RCC_OscInitStruct)979 __weak void HAL_RCC_GetOscConfig(RCC_OscInitTypeDef  *RCC_OscInitStruct)
980 {
981   /* Set all possible values for the Oscillator type parameter ---------------*/
982   RCC_OscInitStruct->OscillatorType = RCC_OSCILLATORTYPE_HSE | RCC_OSCILLATORTYPE_HSI | RCC_OSCILLATORTYPE_LSE | RCC_OSCILLATORTYPE_LSI;
983 
984   /* Get the HSE configuration -----------------------------------------------*/
985   if ((RCC->CR & RCC_CR_HSEBYP) == RCC_CR_HSEBYP)
986   {
987     RCC_OscInitStruct->HSEState = RCC_HSE_BYPASS;
988   }
989   else if ((RCC->CR & RCC_CR_HSEON) == RCC_CR_HSEON)
990   {
991     RCC_OscInitStruct->HSEState = RCC_HSE_ON;
992   }
993   else
994   {
995     RCC_OscInitStruct->HSEState = RCC_HSE_OFF;
996   }
997 
998   /* Get the HSI configuration -----------------------------------------------*/
999   if ((RCC->CR & RCC_CR_HSION) == RCC_CR_HSION)
1000   {
1001     RCC_OscInitStruct->HSIState = RCC_HSI_ON;
1002   }
1003   else
1004   {
1005     RCC_OscInitStruct->HSIState = RCC_HSI_OFF;
1006   }
1007 
1008   RCC_OscInitStruct->HSICalibrationValue = (uint32_t)((RCC->CR & RCC_CR_HSITRIM) >> RCC_CR_HSITRIM_Pos);
1009 
1010   /* Get the LSE configuration -----------------------------------------------*/
1011   if ((RCC->BDCR & RCC_BDCR_LSEBYP) == RCC_BDCR_LSEBYP)
1012   {
1013     RCC_OscInitStruct->LSEState = RCC_LSE_BYPASS;
1014   }
1015   else if ((RCC->BDCR & RCC_BDCR_LSEON) == RCC_BDCR_LSEON)
1016   {
1017     RCC_OscInitStruct->LSEState = RCC_LSE_ON;
1018   }
1019   else
1020   {
1021     RCC_OscInitStruct->LSEState = RCC_LSE_OFF;
1022   }
1023 
1024   /* Get the LSI configuration -----------------------------------------------*/
1025   if ((RCC->CSR & RCC_CSR_LSION) == RCC_CSR_LSION)
1026   {
1027     RCC_OscInitStruct->LSIState = RCC_LSI_ON;
1028   }
1029   else
1030   {
1031     RCC_OscInitStruct->LSIState = RCC_LSI_OFF;
1032   }
1033 
1034   /* Get the PLL configuration -----------------------------------------------*/
1035   if ((RCC->CR & RCC_CR_PLLON) == RCC_CR_PLLON)
1036   {
1037     RCC_OscInitStruct->PLL.PLLState = RCC_PLL_ON;
1038   }
1039   else
1040   {
1041     RCC_OscInitStruct->PLL.PLLState = RCC_PLL_OFF;
1042   }
1043   RCC_OscInitStruct->PLL.PLLSource = (uint32_t)(RCC->PLLCFGR & RCC_PLLCFGR_PLLSRC);
1044   RCC_OscInitStruct->PLL.PLLM = (uint32_t)(RCC->PLLCFGR & RCC_PLLCFGR_PLLM);
1045   RCC_OscInitStruct->PLL.PLLN = (uint32_t)((RCC->PLLCFGR & RCC_PLLCFGR_PLLN) >> RCC_PLLCFGR_PLLN_Pos);
1046   RCC_OscInitStruct->PLL.PLLP = (uint32_t)((((RCC->PLLCFGR & RCC_PLLCFGR_PLLP) + RCC_PLLCFGR_PLLP_0) << 1U) >> RCC_PLLCFGR_PLLP_Pos);
1047   RCC_OscInitStruct->PLL.PLLQ = (uint32_t)((RCC->PLLCFGR & RCC_PLLCFGR_PLLQ) >> RCC_PLLCFGR_PLLQ_Pos);
1048 }
1049 
1050 /**
1051   * @brief  Configures the RCC_ClkInitStruct according to the internal
1052   * RCC configuration registers.
1053   * @param  RCC_ClkInitStruct pointer to an RCC_ClkInitTypeDef structure that
1054   * will be configured.
1055   * @param  pFLatency Pointer on the Flash Latency.
1056   * @retval None
1057   */
HAL_RCC_GetClockConfig(RCC_ClkInitTypeDef * RCC_ClkInitStruct,uint32_t * pFLatency)1058 void HAL_RCC_GetClockConfig(RCC_ClkInitTypeDef  *RCC_ClkInitStruct, uint32_t *pFLatency)
1059 {
1060   /* Set all possible values for the Clock type parameter --------------------*/
1061   RCC_ClkInitStruct->ClockType = RCC_CLOCKTYPE_SYSCLK | RCC_CLOCKTYPE_HCLK | RCC_CLOCKTYPE_PCLK1 | RCC_CLOCKTYPE_PCLK2;
1062 
1063   /* Get the SYSCLK configuration --------------------------------------------*/
1064   RCC_ClkInitStruct->SYSCLKSource = (uint32_t)(RCC->CFGR & RCC_CFGR_SW);
1065 
1066   /* Get the HCLK configuration ----------------------------------------------*/
1067   RCC_ClkInitStruct->AHBCLKDivider = (uint32_t)(RCC->CFGR & RCC_CFGR_HPRE);
1068 
1069   /* Get the APB1 configuration ----------------------------------------------*/
1070   RCC_ClkInitStruct->APB1CLKDivider = (uint32_t)(RCC->CFGR & RCC_CFGR_PPRE1);
1071 
1072   /* Get the APB2 configuration ----------------------------------------------*/
1073   RCC_ClkInitStruct->APB2CLKDivider = (uint32_t)((RCC->CFGR & RCC_CFGR_PPRE2) >> 3U);
1074 
1075   /* Get the Flash Wait State (Latency) configuration ------------------------*/
1076   *pFLatency = (uint32_t)(FLASH->ACR & FLASH_ACR_LATENCY);
1077 }
1078 
1079 /**
1080   * @brief This function handles the RCC CSS interrupt request.
1081   * @note This API should be called under the NMI_Handler().
1082   * @retval None
1083   */
HAL_RCC_NMI_IRQHandler(void)1084 void HAL_RCC_NMI_IRQHandler(void)
1085 {
1086   /* Check RCC CSSF flag  */
1087   if (__HAL_RCC_GET_IT(RCC_IT_CSS))
1088   {
1089     /* RCC Clock Security System interrupt user callback */
1090     HAL_RCC_CSSCallback();
1091 
1092     /* Clear RCC CSS pending bit */
1093     __HAL_RCC_CLEAR_IT(RCC_IT_CSS);
1094   }
1095 }
1096 
1097 /**
1098   * @brief  RCC Clock Security System interrupt callback
1099   * @retval None
1100   */
HAL_RCC_CSSCallback(void)1101 __weak void HAL_RCC_CSSCallback(void)
1102 {
1103   /* NOTE : This function Should not be modified, when the callback is needed,
1104             the HAL_RCC_CSSCallback could be implemented in the user file
1105    */
1106 }
1107 
1108 /**
1109   * @}
1110   */
1111 
1112 /**
1113   * @}
1114   */
1115 
1116 #endif /* HAL_RCC_MODULE_ENABLED */
1117 /**
1118   * @}
1119   */
1120 
1121 /**
1122   * @}
1123   */
1124 
1125