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