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