1 /**
2   ******************************************************************************
3   * @file    stm32l1xx_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 multispeed internal oscillator clock
17       (MSI 2.097MHz) with Flash 0 wait state and Flash prefetch buffer is disabled,
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 MSI 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/SDIO/RNG)
32           (*) SDIO only for STM32L1xxxD devices
33 
34                       ##### RCC Limitations #####
35   ==============================================================================
36     [..]
37       A delay between an RCC peripheral clock enable and the effective peripheral
38       enabling should be taken into account in order to manage the peripheral read/write
39       from/to registers.
40       (+) This delay depends on the peripheral mapping.
41         (++) AHB & APB peripherals, 1 dummy read is necessary
42 
43     [..]
44       Workarounds:
45       (#) For AHB & APB peripherals, a dummy read to the peripheral register has been
46           inserted in each __HAL_RCC_PPP_CLK_ENABLE() macro.
47 
48   @endverbatim
49   ******************************************************************************
50   * @attention
51   *
52   * <h2><center>&copy; COPYRIGHT(c) 2017 STMicroelectronics</center></h2>
53   *
54   * Redistribution and use in source and binary forms, with or without modification,
55   * are permitted provided that the following conditions are met:
56   *   1. Redistributions of source code must retain the above copyright notice,
57   *      this list of conditions and the following disclaimer.
58   *   2. Redistributions in binary form must reproduce the above copyright notice,
59   *      this list of conditions and the following disclaimer in the documentation
60   *      and/or other materials provided with the distribution.
61   *   3. Neither the name of STMicroelectronics nor the names of its contributors
62   *      may be used to endorse or promote products derived from this software
63   *      without specific prior written permission.
64   *
65   * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
66   * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
67   * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
68   * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
69   * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
70   * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
71   * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
72   * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
73   * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
74   * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
75   *
76   ******************************************************************************
77 */
78 
79 /* Includes ------------------------------------------------------------------*/
80 #include "stm32l1xx_hal.h"
81 
82 /** @addtogroup STM32L1xx_HAL_Driver
83   * @{
84   */
85 
86 /** @defgroup RCC RCC
87 * @brief RCC HAL module driver
88   * @{
89   */
90 
91 #ifdef HAL_RCC_MODULE_ENABLED
92 
93 /* Private typedef -----------------------------------------------------------*/
94 /* Private define ------------------------------------------------------------*/
95 /** @defgroup RCC_Private_Constants RCC Private Constants
96  * @{
97  */
98 /* Bits position in  in the CFGR register */
99 #define RCC_CFGR_PLLMUL_BITNUMBER         POSITION_VAL(RCC_CFGR_PLLMUL)
100 #define RCC_CFGR_PLLDIV_BITNUMBER         POSITION_VAL(RCC_CFGR_PLLDIV)
101 #define RCC_CFGR_HPRE_BITNUMBER           POSITION_VAL(RCC_CFGR_HPRE)
102 #define RCC_CFGR_PPRE1_BITNUMBER          POSITION_VAL(RCC_CFGR_PPRE1)
103 #define RCC_CFGR_PPRE2_BITNUMBER          POSITION_VAL(RCC_CFGR_PPRE2)
104 /* Bits position in  in the ICSCR register */
105 #define RCC_ICSCR_MSIRANGE_BITNUMBER      POSITION_VAL(RCC_ICSCR_MSIRANGE)
106 #define RCC_ICSCR_MSITRIM_BITNUMBER       POSITION_VAL(RCC_ICSCR_MSITRIM)
107 /**
108   * @}
109   */
110 /* Private macro -------------------------------------------------------------*/
111 /** @defgroup RCC_Private_Macros RCC Private Macros
112   * @{
113   */
114 
115 #define MCO1_CLK_ENABLE()     __HAL_RCC_GPIOA_CLK_ENABLE()
116 #define MCO1_GPIO_PORT        GPIOA
117 #define MCO1_PIN              GPIO_PIN_8
118 
119 /**
120   * @}
121   */
122 
123 /* Private variables ---------------------------------------------------------*/
124 /** @defgroup RCC_Private_Variables RCC Private Variables
125   * @{
126   */
127 extern const uint8_t PLLMulTable[];          /* Defined in CMSIS (system_stm32l0xx.c)*/
128 /**
129   * @}
130   */
131 
132 /* Private function prototypes -----------------------------------------------*/
133 /** @defgroup RCC_Private_Functions RCC Private Functions
134   * @{
135   */
136 static HAL_StatusTypeDef RCC_SetFlashLatencyFromMSIRange(uint32_t MSIrange);
137 /**
138   * @}
139   */
140 
141 /* Exported functions ---------------------------------------------------------*/
142 
143 /** @defgroup RCC_Exported_Functions RCC Exported Functions
144   * @{
145   */
146 
147 /** @defgroup RCC_Exported_Functions_Group1 Initialization and de-initialization functions
148   *  @brief    Initialization and Configuration functions
149   *
150   @verbatim
151   ===============================================================================
152            ##### Initialization and de-initialization functions #####
153   ===============================================================================
154     [..]
155       This section provides functions allowing to configure the internal/external oscillators
156       (MSI, HSE, HSI, LSE, LSI, PLL, CSS and MCO) and the System buses clocks (SYSCLK, AHB, APB1
157       and APB2).
158 
159     [..] Internal/external clock and PLL configuration
160       (#) MSI (Multispeed internal), Seven frequency ranges are available: 65.536 kHz,
161           131.072 kHz, 262.144 kHz, 524.288 kHz, 1.048 MHz, 2.097 MHz (default value) and 4.194 MHz.
162 
163       (#) HSI (high-speed internal), 16 MHz factory-trimmed RC used directly or through
164           the PLL as System clock source.
165       (#) LSI (low-speed internal), ~37 KHz low consumption RC used as IWDG and/or RTC
166           clock source.
167 
168       (#) HSE (high-speed external), 1 to 24 MHz crystal oscillator used directly or
169           through the PLL as System clock source. Can be used also as RTC clock source.
170 
171       (#) LSE (low-speed external), 32 KHz oscillator used as RTC clock source.
172 
173       (#) PLL (clocked by HSI or HSE), featuring different output clocks:
174         (++) The first output is used to generate the high speed system clock (up to 32 MHz)
175         (++) The second output is used to generate the clock for the USB OTG FS (48 MHz)
176 
177       (#) CSS (Clock security system), once enable using the macro __HAL_RCC_CSS_ENABLE()
178           and if a HSE clock failure occurs(HSE used directly or through PLL as System
179           clock source), the System clocks automatically switched to MSI and an interrupt
180           is generated if enabled. The interrupt is linked to the Cortex-M3 NMI
181           (Non-Maskable Interrupt) exception vector.
182 
183       (#) MCO1 (microcontroller clock output), used to output SYSCLK, HSI, LSI, MSI, LSE,
184           HSE or PLL clock (through a configurable prescaler) on PA8 pin.
185 
186     [..] System, AHB and APB buses clocks configuration
187       (#) Several clock sources can be used to drive the System clock (SYSCLK): MSI, HSI,
188           HSE and PLL.
189           The AHB clock (HCLK) is derived from System clock through configurable
190           prescaler and used to clock the CPU, memory and peripherals mapped
191           on AHB bus (DMA, GPIO...). APB1 (PCLK1) and APB2 (PCLK2) clocks are derived
192           from AHB clock through configurable prescalers and used to clock
193           the peripherals mapped on these buses. You can use
194           "@ref HAL_RCC_GetSysClockFreq()" function to retrieve the frequencies of these clocks.
195 
196       -@- All the peripheral clocks are derived from the System clock (SYSCLK) except:
197           (+@) RTC: RTC clock can be derived either from the LSI, LSE or HSE clock
198               divided by 2 to 16. You have to use @ref __HAL_RCC_RTC_CONFIG() and @ref __HAL_RCC_RTC_ENABLE()
199               macros to configure this clock.
200           (+@) LCD: LCD clock can be derived either from the LSI, LSE or HSE clock
201               divided by 2 to 16. You have to use @ref __HAL_RCC_LCD_CONFIG()
202               macros to configure this clock.
203           (+@) USB OTG FS: USB OTG FS require a frequency equal to 48 MHz
204               to work correctly. This clock is derived of the main PLL through PLL Multiplier.
205 
206           (+@) IWDG clock which is always the LSI clock.
207 
208       (#) The maximum frequency of the SYSCLK and HCLK is 32 MHz, PCLK2 32 MHz
209           and PCLK1 32 MHz. Depending on the device voltage range, the maximum
210           frequency should be adapted accordingly.
211   @endverbatim
212   * @{
213   */
214 
215 /*
216   Additional consideration on the HCLK based on Latency settings:
217   +----------------------------------------------------------------------+
218   | Latency       |                HCLK clock frequency (MHz)            |
219   |               |------------------------------------------------------|
220   |               | voltage range 1  | voltage range 2 | voltage range 3 |
221   |               |      1.8 V       |     1.5 V       |      1.2 V      |
222   |---------------|------------------|-----------------|-----------------|
223   |0WS(1CPU cycle)| 0 < HCLK <= 16   | 0 < HCLK <= 8   | 0 < HCLK <= 2   |
224   |---------------|------------------|-----------------|-----------------|
225   |1WS(2CPU cycle)| 16 < HCLK <= 32  | 8 < HCLK <= 16  | 2 < HCLK <= 4   |
226   +----------------------------------------------------------------------+
227 
228   The following table gives the different clock source frequencies depending on the product
229   voltage range:
230   +------------------------------------------------------------------------------------------+
231   | Product voltage |                    Clock frequency                                     |
232   |                 |------------------|-----------------------------|-----------------------|
233   |      range      |   MSI   |   HSI  |              HSE            |          PLL          |
234   |-----------------|---------|--------|-----------------------------|-----------------------|
235   | Range 1 (1.8 V) | 4.2 MHz | 16 MHz | HSE 32 MHz (external clock) |         32 MHz        |
236   |                 |         |        |      or 24 MHz (crystal)    | (PLLVCO max = 96 MHz) |
237   |-----------------|---------|--------|-----------------------------|-----------------------|
238   | Range 2 (1.5 V) | 4.2 MHz | 16 MHz |         16 MHz              |         16 MHz        |
239   |                 |         |        |                             | (PLLVCO max = 48 MHz) |
240   |-----------------|---------|--------|-----------------------------|-----------------------|
241   | Range 3 (1.2 V) | 4.2 MHz |   NA   |         8 MHz               |           4 MHz       |
242   |                 |         |        |                             | (PLLVCO max = 24 MHz) |
243   +------------------------------------------------------------------------------------------+
244   */
245 
246 /**
247   * @brief  Resets the RCC clock configuration to the default reset state.
248   * @note   The default reset state of the clock configuration is given below:
249   *            - MSI ON and used as system clock source
250   *            - HSI, HSE and PLL  OFF
251   *            - AHB, APB1 and APB2 prescaler set to 1.
252   *            - CSS and MCO1 OFF
253   *            - All interrupts disabled
254   * @note   This function does not modify the configuration of the
255   *            - Peripheral clocks
256   *            - LSI, LSE and RTC clocks
257   * @retval None
258   */
HAL_RCC_DeInit(void)259 void HAL_RCC_DeInit(void)
260 {
261   /* Set MSION bit */
262   SET_BIT(RCC->CR, RCC_CR_MSION);
263 
264   /* Switch SYSCLK to MSI*/
265   CLEAR_BIT(RCC->CFGR, RCC_CFGR_SW);
266 
267   /* Reset HSION, HSEON, CSSON, HSEBYP & PLLON bits */
268   CLEAR_BIT(RCC->CR, RCC_CR_HSION | RCC_CR_HSEON | RCC_CR_CSSON | RCC_CR_PLLON | RCC_CR_HSEBYP);
269   /* Reset CFGR register */
270   CLEAR_REG(RCC->CFGR);
271 
272   /* Set MSIClockRange & MSITRIM[4:0] bits to the reset value */
273   MODIFY_REG(RCC->ICSCR, (RCC_ICSCR_MSIRANGE | RCC_ICSCR_MSITRIM), ((0U << RCC_ICSCR_MSITRIM_BITNUMBER) | RCC_ICSCR_MSIRANGE_5));
274 
275   /* Set HSITRIM bits to the reset value */
276   MODIFY_REG(RCC->ICSCR, RCC_ICSCR_HSITRIM, (0x10U << POSITION_VAL(RCC_ICSCR_HSITRIM)));
277 
278   /* Disable all interrupts */
279   CLEAR_REG(RCC->CIR);
280 
281   /* Update the SystemCoreClock global variable */
282   SystemCoreClock = MSI_VALUE;
283 }
284 
285 /**
286   * @brief  Initializes the RCC Oscillators according to the specified parameters in the
287   *         RCC_OscInitTypeDef.
288   * @param  RCC_OscInitStruct pointer to an RCC_OscInitTypeDef structure that
289   *         contains the configuration information for the RCC Oscillators.
290   * @note   The PLL is not disabled when used as system clock.
291   * @note   Transitions LSE Bypass to LSE On and LSE On to LSE Bypass are not
292   *         supported by this macro. User should request a transition to LSE Off
293   *         first and then LSE On or LSE Bypass.
294   * @note   Transition HSE Bypass to HSE On and HSE On to HSE Bypass are not
295   *         supported by this macro. User should request a transition to HSE Off
296   *         first and then HSE On or HSE Bypass.
297   * @retval HAL status
298   */
HAL_RCC_OscConfig(RCC_OscInitTypeDef * RCC_OscInitStruct)299 HAL_StatusTypeDef HAL_RCC_OscConfig(RCC_OscInitTypeDef  *RCC_OscInitStruct)
300 {
301    uint32_t tickstart = 0U;
302 
303   /* Check the parameters */
304   assert_param(RCC_OscInitStruct != NULL);
305   assert_param(IS_RCC_OSCILLATORTYPE(RCC_OscInitStruct->OscillatorType));
306 
307   /*------------------------------- HSE Configuration ------------------------*/
308   if(((RCC_OscInitStruct->OscillatorType) & RCC_OSCILLATORTYPE_HSE) == RCC_OSCILLATORTYPE_HSE)
309   {
310     /* Check the parameters */
311     assert_param(IS_RCC_HSE(RCC_OscInitStruct->HSEState));
312 
313     /* When the HSE is used as system clock or clock source for PLL in these cases it is not allowed to be disabled */
314     if((__HAL_RCC_GET_SYSCLK_SOURCE() == RCC_SYSCLKSOURCE_STATUS_HSE)
315        || ((__HAL_RCC_GET_SYSCLK_SOURCE() == RCC_SYSCLKSOURCE_STATUS_PLLCLK) && (__HAL_RCC_GET_PLL_OSCSOURCE() == RCC_PLLSOURCE_HSE)))
316     {
317       if((__HAL_RCC_GET_FLAG(RCC_FLAG_HSERDY) != RESET) && (RCC_OscInitStruct->HSEState == RCC_HSE_OFF))
318       {
319         return HAL_ERROR;
320       }
321     }
322     else
323     {
324       /* Set the new HSE configuration ---------------------------------------*/
325       __HAL_RCC_HSE_CONFIG(RCC_OscInitStruct->HSEState);
326 
327 
328        /* Check the HSE State */
329       if(RCC_OscInitStruct->HSEState != RCC_HSE_OFF)
330       {
331         /* Get Start Tick */
332         tickstart = HAL_GetTick();
333 
334         /* Wait till HSE is ready */
335         while(__HAL_RCC_GET_FLAG(RCC_FLAG_HSERDY) == RESET)
336         {
337           if((HAL_GetTick() - tickstart ) > HSE_TIMEOUT_VALUE)
338           {
339             return HAL_TIMEOUT;
340           }
341         }
342       }
343       else
344       {
345         /* Get Start Tick */
346         tickstart = HAL_GetTick();
347 
348         /* Wait till HSE is disabled */
349         while(__HAL_RCC_GET_FLAG(RCC_FLAG_HSERDY) != RESET)
350         {
351            if((HAL_GetTick() - tickstart ) > HSE_TIMEOUT_VALUE)
352           {
353             return HAL_TIMEOUT;
354           }
355         }
356       }
357     }
358   }
359   /*----------------------------- HSI Configuration --------------------------*/
360   if(((RCC_OscInitStruct->OscillatorType) & RCC_OSCILLATORTYPE_HSI) == RCC_OSCILLATORTYPE_HSI)
361   {
362     /* Check the parameters */
363     assert_param(IS_RCC_HSI(RCC_OscInitStruct->HSIState));
364     assert_param(IS_RCC_CALIBRATION_VALUE(RCC_OscInitStruct->HSICalibrationValue));
365 
366     /* Check if HSI is used as system clock or as PLL source when PLL is selected as system clock */
367     if((__HAL_RCC_GET_SYSCLK_SOURCE() == RCC_SYSCLKSOURCE_STATUS_HSI)
368        || ((__HAL_RCC_GET_SYSCLK_SOURCE() == RCC_SYSCLKSOURCE_STATUS_PLLCLK) && (__HAL_RCC_GET_PLL_OSCSOURCE() == RCC_PLLSOURCE_HSI)))
369     {
370       /* When HSI is used as system clock it will not disabled */
371       if((__HAL_RCC_GET_FLAG(RCC_FLAG_HSIRDY) != RESET) && (RCC_OscInitStruct->HSIState != RCC_HSI_ON))
372       {
373         return HAL_ERROR;
374       }
375       /* Otherwise, just the calibration is allowed */
376       else
377       {
378         /* Adjusts the Internal High Speed oscillator (HSI) calibration value.*/
379         __HAL_RCC_HSI_CALIBRATIONVALUE_ADJUST(RCC_OscInitStruct->HSICalibrationValue);
380       }
381     }
382     else
383     {
384       /* Check the HSI State */
385       if(RCC_OscInitStruct->HSIState != RCC_HSI_OFF)
386       {
387        /* Enable the Internal High Speed oscillator (HSI). */
388         __HAL_RCC_HSI_ENABLE();
389 
390         /* Get Start Tick */
391         tickstart = HAL_GetTick();
392 
393         /* Wait till HSI is ready */
394         while(__HAL_RCC_GET_FLAG(RCC_FLAG_HSIRDY) == RESET)
395         {
396           if((HAL_GetTick() - tickstart ) > HSI_TIMEOUT_VALUE)
397           {
398             return HAL_TIMEOUT;
399           }
400         }
401 
402         /* Adjusts the Internal High Speed oscillator (HSI) calibration value.*/
403         __HAL_RCC_HSI_CALIBRATIONVALUE_ADJUST(RCC_OscInitStruct->HSICalibrationValue);
404       }
405       else
406       {
407         /* Disable the Internal High Speed oscillator (HSI). */
408         __HAL_RCC_HSI_DISABLE();
409 
410         /* Get Start Tick */
411         tickstart = HAL_GetTick();
412 
413         /* Wait till HSI is disabled */
414         while(__HAL_RCC_GET_FLAG(RCC_FLAG_HSIRDY) != RESET)
415         {
416           if((HAL_GetTick() - tickstart ) > HSI_TIMEOUT_VALUE)
417           {
418             return HAL_TIMEOUT;
419           }
420         }
421       }
422     }
423   }
424   /*----------------------------- MSI Configuration --------------------------*/
425   if(((RCC_OscInitStruct->OscillatorType) & RCC_OSCILLATORTYPE_MSI) == RCC_OSCILLATORTYPE_MSI)
426   {
427     /* When the MSI is used as system clock it will not be disabled */
428     if((__HAL_RCC_GET_SYSCLK_SOURCE() == RCC_CFGR_SWS_MSI) )
429     {
430       if((__HAL_RCC_GET_FLAG(RCC_FLAG_MSIRDY) != RESET) && (RCC_OscInitStruct->MSIState == RCC_MSI_OFF))
431       {
432         return HAL_ERROR;
433       }
434       /* Otherwise, just the calibration and MSI range change are allowed */
435       else
436       {
437        /* Check MSICalibrationValue and MSIClockRange input parameters */
438         assert_param(IS_RCC_MSICALIBRATION_VALUE(RCC_OscInitStruct->MSICalibrationValue));
439         assert_param(IS_RCC_MSI_CLOCK_RANGE(RCC_OscInitStruct->MSIClockRange));
440 
441         /* To correctly read data from FLASH memory, the number of wait states (LATENCY)
442            must be correctly programmed according to the frequency of the CPU clock
443            (HCLK) and the supply voltage of the device. */
444         if(RCC_OscInitStruct->MSIClockRange > __HAL_RCC_GET_MSI_RANGE())
445         {
446           /* First increase number of wait states update if necessary */
447           if(RCC_SetFlashLatencyFromMSIRange(RCC_OscInitStruct->MSIClockRange) != HAL_OK)
448           {
449             return HAL_ERROR;
450           }
451 
452           /* Selects the Multiple Speed oscillator (MSI) clock range .*/
453           __HAL_RCC_MSI_RANGE_CONFIG(RCC_OscInitStruct->MSIClockRange);
454           /* Adjusts the Multiple Speed oscillator (MSI) calibration value.*/
455           __HAL_RCC_MSI_CALIBRATIONVALUE_ADJUST(RCC_OscInitStruct->MSICalibrationValue);
456         }
457         else
458         {
459           /* Else, keep current flash latency while decreasing applies */
460           /* Selects the Multiple Speed oscillator (MSI) clock range .*/
461           __HAL_RCC_MSI_RANGE_CONFIG(RCC_OscInitStruct->MSIClockRange);
462           /* Adjusts the Multiple Speed oscillator (MSI) calibration value.*/
463           __HAL_RCC_MSI_CALIBRATIONVALUE_ADJUST(RCC_OscInitStruct->MSICalibrationValue);
464 
465           /* Decrease number of wait states update if necessary */
466           if(RCC_SetFlashLatencyFromMSIRange(RCC_OscInitStruct->MSIClockRange) != HAL_OK)
467           {
468             return HAL_ERROR;
469           }
470         }
471 
472         /* Update the SystemCoreClock global variable */
473         SystemCoreClock =  (32768U * (1U << ((RCC_OscInitStruct->MSIClockRange >> RCC_ICSCR_MSIRANGE_BITNUMBER) + 1U)))
474                            >> AHBPrescTable[((RCC->CFGR & RCC_CFGR_HPRE) >> RCC_CFGR_HPRE_BITNUMBER)];
475 
476         /* Configure the source of time base considering new system clocks settings*/
477         HAL_InitTick (TICK_INT_PRIORITY);
478       }
479     }
480     else
481     {
482       /* Check MSI State */
483       assert_param(IS_RCC_MSI(RCC_OscInitStruct->MSIState));
484 
485       /* Check the MSI State */
486       if(RCC_OscInitStruct->MSIState != RCC_MSI_OFF)
487       {
488         /* Enable the Multi Speed oscillator (MSI). */
489         __HAL_RCC_MSI_ENABLE();
490 
491         /* Get Start Tick */
492         tickstart = HAL_GetTick();
493 
494         /* Wait till MSI is ready */
495         while(__HAL_RCC_GET_FLAG(RCC_FLAG_MSIRDY) == RESET)
496         {
497           if((HAL_GetTick() - tickstart) > MSI_TIMEOUT_VALUE)
498           {
499             return HAL_TIMEOUT;
500           }
501         }
502         /* Check MSICalibrationValue and MSIClockRange input parameters */
503         assert_param(IS_RCC_MSICALIBRATION_VALUE(RCC_OscInitStruct->MSICalibrationValue));
504         assert_param(IS_RCC_MSI_CLOCK_RANGE(RCC_OscInitStruct->MSIClockRange));
505 
506         /* Selects the Multiple Speed oscillator (MSI) clock range .*/
507         __HAL_RCC_MSI_RANGE_CONFIG(RCC_OscInitStruct->MSIClockRange);
508          /* Adjusts the Multiple Speed oscillator (MSI) calibration value.*/
509         __HAL_RCC_MSI_CALIBRATIONVALUE_ADJUST(RCC_OscInitStruct->MSICalibrationValue);
510 
511       }
512       else
513       {
514         /* Disable the Multi Speed oscillator (MSI). */
515         __HAL_RCC_MSI_DISABLE();
516 
517         /* Get Start Tick */
518         tickstart = HAL_GetTick();
519 
520         /* Wait till MSI is ready */
521         while(__HAL_RCC_GET_FLAG(RCC_FLAG_MSIRDY) != RESET)
522         {
523           if((HAL_GetTick() - tickstart) > MSI_TIMEOUT_VALUE)
524           {
525             return HAL_TIMEOUT;
526           }
527         }
528       }
529     }
530   }
531   /*------------------------------ LSI Configuration -------------------------*/
532   if(((RCC_OscInitStruct->OscillatorType) & RCC_OSCILLATORTYPE_LSI) == RCC_OSCILLATORTYPE_LSI)
533   {
534     /* Check the parameters */
535     assert_param(IS_RCC_LSI(RCC_OscInitStruct->LSIState));
536 
537     /* Check the LSI State */
538     if(RCC_OscInitStruct->LSIState != RCC_LSI_OFF)
539     {
540       /* Enable the Internal Low Speed oscillator (LSI). */
541       __HAL_RCC_LSI_ENABLE();
542 
543       /* Get Start Tick */
544       tickstart = HAL_GetTick();
545 
546       /* Wait till LSI is ready */
547       while(__HAL_RCC_GET_FLAG(RCC_FLAG_LSIRDY) == RESET)
548       {
549         if((HAL_GetTick() - tickstart ) > LSI_TIMEOUT_VALUE)
550         {
551           return HAL_TIMEOUT;
552         }
553       }
554     }
555     else
556     {
557       /* Disable the Internal Low Speed oscillator (LSI). */
558       __HAL_RCC_LSI_DISABLE();
559 
560       /* Get Start Tick */
561       tickstart = HAL_GetTick();
562 
563       /* Wait till LSI is disabled */
564       while(__HAL_RCC_GET_FLAG(RCC_FLAG_LSIRDY) != RESET)
565       {
566         if((HAL_GetTick() - tickstart ) > LSI_TIMEOUT_VALUE)
567         {
568           return HAL_TIMEOUT;
569         }
570       }
571     }
572   }
573   /*------------------------------ LSE Configuration -------------------------*/
574   if(((RCC_OscInitStruct->OscillatorType) & RCC_OSCILLATORTYPE_LSE) == RCC_OSCILLATORTYPE_LSE)
575   {
576     FlagStatus       pwrclkchanged = RESET;
577 
578     /* Check the parameters */
579     assert_param(IS_RCC_LSE(RCC_OscInitStruct->LSEState));
580 
581     /* Update LSE configuration in Backup Domain control register    */
582     /* Requires to enable write access to Backup Domain of necessary */
583     if(__HAL_RCC_PWR_IS_CLK_DISABLED())
584     {
585       __HAL_RCC_PWR_CLK_ENABLE();
586       pwrclkchanged = SET;
587     }
588 
589     if(HAL_IS_BIT_CLR(PWR->CR, PWR_CR_DBP))
590     {
591       /* Enable write access to Backup domain */
592       SET_BIT(PWR->CR, PWR_CR_DBP);
593 
594       /* Wait for Backup domain Write protection disable */
595       tickstart = HAL_GetTick();
596 
597       while(HAL_IS_BIT_CLR(PWR->CR, PWR_CR_DBP))
598       {
599         if((HAL_GetTick() - tickstart) > RCC_DBP_TIMEOUT_VALUE)
600         {
601           return HAL_TIMEOUT;
602         }
603       }
604     }
605 
606     /* Set the new LSE configuration -----------------------------------------*/
607     __HAL_RCC_LSE_CONFIG(RCC_OscInitStruct->LSEState);
608     /* Check the LSE State */
609     if(RCC_OscInitStruct->LSEState != RCC_LSE_OFF)
610     {
611       /* Get Start Tick */
612       tickstart = HAL_GetTick();
613 
614       /* Wait till LSE is ready */
615       while(__HAL_RCC_GET_FLAG(RCC_FLAG_LSERDY) == RESET)
616       {
617         if((HAL_GetTick() - tickstart ) > RCC_LSE_TIMEOUT_VALUE)
618         {
619           return HAL_TIMEOUT;
620         }
621       }
622     }
623     else
624     {
625       /* Get Start Tick */
626       tickstart = HAL_GetTick();
627 
628       /* Wait till LSE is disabled */
629       while(__HAL_RCC_GET_FLAG(RCC_FLAG_LSERDY) != RESET)
630       {
631         if((HAL_GetTick() - tickstart ) > RCC_LSE_TIMEOUT_VALUE)
632         {
633           return HAL_TIMEOUT;
634         }
635       }
636     }
637 
638     /* Require to disable power clock if necessary */
639     if(pwrclkchanged == SET)
640     {
641       __HAL_RCC_PWR_CLK_DISABLE();
642     }
643   }
644 
645   /*-------------------------------- PLL Configuration -----------------------*/
646   /* Check the parameters */
647   assert_param(IS_RCC_PLL(RCC_OscInitStruct->PLL.PLLState));
648   if ((RCC_OscInitStruct->PLL.PLLState) != RCC_PLL_NONE)
649   {
650     /* Check if the PLL is used as system clock or not */
651     if(__HAL_RCC_GET_SYSCLK_SOURCE() != RCC_SYSCLKSOURCE_STATUS_PLLCLK)
652     {
653       if((RCC_OscInitStruct->PLL.PLLState) == RCC_PLL_ON)
654       {
655         /* Check the parameters */
656         assert_param(IS_RCC_PLLSOURCE(RCC_OscInitStruct->PLL.PLLSource));
657         assert_param(IS_RCC_PLL_MUL(RCC_OscInitStruct->PLL.PLLMUL));
658         assert_param(IS_RCC_PLL_DIV(RCC_OscInitStruct->PLL.PLLDIV));
659 
660         /* Disable the main PLL. */
661         __HAL_RCC_PLL_DISABLE();
662 
663         /* Get Start Tick */
664         tickstart = HAL_GetTick();
665 
666         /* Wait till PLL is disabled */
667         while(__HAL_RCC_GET_FLAG(RCC_FLAG_PLLRDY)  != RESET)
668         {
669           if((HAL_GetTick() - tickstart ) > PLL_TIMEOUT_VALUE)
670           {
671             return HAL_TIMEOUT;
672           }
673         }
674 
675         /* Configure the main PLL clock source, multiplication and division factors. */
676         __HAL_RCC_PLL_CONFIG(RCC_OscInitStruct->PLL.PLLSource,
677                              RCC_OscInitStruct->PLL.PLLMUL,
678                              RCC_OscInitStruct->PLL.PLLDIV);
679         /* Enable the main PLL. */
680         __HAL_RCC_PLL_ENABLE();
681 
682         /* Get Start Tick */
683         tickstart = HAL_GetTick();
684 
685         /* Wait till PLL is ready */
686         while(__HAL_RCC_GET_FLAG(RCC_FLAG_PLLRDY)  == RESET)
687         {
688           if((HAL_GetTick() - tickstart ) > PLL_TIMEOUT_VALUE)
689           {
690             return HAL_TIMEOUT;
691           }
692         }
693       }
694       else
695       {
696         /* Disable the main PLL. */
697         __HAL_RCC_PLL_DISABLE();
698 
699         /* Get Start Tick */
700         tickstart = HAL_GetTick();
701 
702         /* Wait till PLL is disabled */
703         while(__HAL_RCC_GET_FLAG(RCC_FLAG_PLLRDY)  != RESET)
704         {
705           if((HAL_GetTick() - tickstart ) > PLL_TIMEOUT_VALUE)
706           {
707             return HAL_TIMEOUT;
708           }
709         }
710       }
711     }
712     else
713     {
714       return HAL_ERROR;
715     }
716   }
717 
718   return HAL_OK;
719 }
720 
721 /**
722   * @brief  Initializes the CPU, AHB and APB buses clocks according to the specified
723   *         parameters in the RCC_ClkInitStruct.
724   * @param  RCC_ClkInitStruct pointer to an RCC_OscInitTypeDef structure that
725   *         contains the configuration information for the RCC peripheral.
726   * @param  FLatency FLASH Latency
727   *          The value of this parameter depend on device used within the same series
728   * @note   The SystemCoreClock CMSIS variable is used to store System Clock Frequency
729   *         and updated by @ref HAL_RCC_GetHCLKFreq() function called within this function
730   *
731   * @note   The MSI is used (enabled by hardware) as system clock source after
732   *         start-up from Reset, wake-up from STOP and STANDBY mode, or in case
733   *         of failure of the HSE used directly or indirectly as system clock
734   *         (if the Clock Security System CSS is enabled).
735   *
736   * @note   A switch from one clock source to another occurs only if the target
737   *         clock source is ready (clock stable after start-up delay or PLL locked).
738   *         If a clock source which is not yet ready is selected, the switch will
739   *         occur when the clock source will be ready.
740   *         You can use @ref HAL_RCC_GetClockConfig() function to know which clock is
741   *         currently used as system clock source.
742   * @note   Depending on the device voltage range, the software has to set correctly
743   *         HPRE[3:0] bits to ensure that HCLK not exceed the maximum allowed frequency
744   *         (for more details refer to section above "Initialization/de-initialization functions")
745   * @retval HAL status
746   */
HAL_RCC_ClockConfig(RCC_ClkInitTypeDef * RCC_ClkInitStruct,uint32_t FLatency)747 HAL_StatusTypeDef HAL_RCC_ClockConfig(RCC_ClkInitTypeDef  *RCC_ClkInitStruct, uint32_t FLatency)
748 {
749   uint32_t tickstart = 0U;
750 
751   /* Check the parameters */
752   assert_param(RCC_ClkInitStruct != NULL);
753   assert_param(IS_RCC_CLOCKTYPE(RCC_ClkInitStruct->ClockType));
754   assert_param(IS_FLASH_LATENCY(FLatency));
755 
756   /* To correctly read data from FLASH memory, the number of wait states (LATENCY)
757   must be correctly programmed according to the frequency of the CPU clock
758   (HCLK) and the supply voltage of the device. */
759 
760   /* Increasing the number of wait states because of higher CPU frequency */
761   if(FLatency > (FLASH->ACR & FLASH_ACR_LATENCY))
762   {
763     /* Program the new number of wait states to the LATENCY bits in the FLASH_ACR register */
764     __HAL_FLASH_SET_LATENCY(FLatency);
765 
766     /* Check that the new number of wait states is taken into account to access the Flash
767     memory by reading the FLASH_ACR register */
768     if((FLASH->ACR & FLASH_ACR_LATENCY) != FLatency)
769     {
770       return HAL_ERROR;
771     }
772   }
773 
774   /*-------------------------- HCLK Configuration --------------------------*/
775   if(((RCC_ClkInitStruct->ClockType) & RCC_CLOCKTYPE_HCLK) == RCC_CLOCKTYPE_HCLK)
776   {
777     assert_param(IS_RCC_HCLK(RCC_ClkInitStruct->AHBCLKDivider));
778     MODIFY_REG(RCC->CFGR, RCC_CFGR_HPRE, RCC_ClkInitStruct->AHBCLKDivider);
779   }
780 
781   /*------------------------- SYSCLK Configuration ---------------------------*/
782   if(((RCC_ClkInitStruct->ClockType) & RCC_CLOCKTYPE_SYSCLK) == RCC_CLOCKTYPE_SYSCLK)
783   {
784     assert_param(IS_RCC_SYSCLKSOURCE(RCC_ClkInitStruct->SYSCLKSource));
785 
786     /* HSE is selected as System Clock Source */
787     if(RCC_ClkInitStruct->SYSCLKSource == RCC_SYSCLKSOURCE_HSE)
788     {
789       /* Check the HSE ready flag */
790       if(__HAL_RCC_GET_FLAG(RCC_FLAG_HSERDY) == RESET)
791       {
792         return HAL_ERROR;
793       }
794     }
795     /* PLL is selected as System Clock Source */
796     else if(RCC_ClkInitStruct->SYSCLKSource == RCC_SYSCLKSOURCE_PLLCLK)
797     {
798       /* Check the PLL ready flag */
799       if(__HAL_RCC_GET_FLAG(RCC_FLAG_PLLRDY) == RESET)
800       {
801         return HAL_ERROR;
802       }
803     }
804     /* HSI is selected as System Clock Source */
805     else if(RCC_ClkInitStruct->SYSCLKSource == RCC_SYSCLKSOURCE_HSI)
806     {
807       /* Check the HSI ready flag */
808       if(__HAL_RCC_GET_FLAG(RCC_FLAG_HSIRDY) == RESET)
809       {
810         return HAL_ERROR;
811       }
812     }
813     /* MSI is selected as System Clock Source */
814     else
815     {
816       /* Check the MSI ready flag */
817       if(__HAL_RCC_GET_FLAG(RCC_FLAG_MSIRDY) == RESET)
818       {
819         return HAL_ERROR;
820       }
821     }
822     __HAL_RCC_SYSCLK_CONFIG(RCC_ClkInitStruct->SYSCLKSource);
823 
824     /* Get Start Tick */
825     tickstart = HAL_GetTick();
826 
827     if(RCC_ClkInitStruct->SYSCLKSource == RCC_SYSCLKSOURCE_HSE)
828     {
829       while (__HAL_RCC_GET_SYSCLK_SOURCE() != RCC_SYSCLKSOURCE_STATUS_HSE)
830       {
831         if((HAL_GetTick() - tickstart ) > CLOCKSWITCH_TIMEOUT_VALUE)
832         {
833           return HAL_TIMEOUT;
834         }
835       }
836     }
837     else if(RCC_ClkInitStruct->SYSCLKSource == RCC_SYSCLKSOURCE_PLLCLK)
838     {
839       while (__HAL_RCC_GET_SYSCLK_SOURCE() != RCC_SYSCLKSOURCE_STATUS_PLLCLK)
840       {
841         if((HAL_GetTick() - tickstart ) > CLOCKSWITCH_TIMEOUT_VALUE)
842         {
843           return HAL_TIMEOUT;
844         }
845       }
846     }
847     else if(RCC_ClkInitStruct->SYSCLKSource == RCC_SYSCLKSOURCE_HSI)
848     {
849       while (__HAL_RCC_GET_SYSCLK_SOURCE() != RCC_SYSCLKSOURCE_STATUS_HSI)
850       {
851         if((HAL_GetTick() - tickstart ) > CLOCKSWITCH_TIMEOUT_VALUE)
852         {
853           return HAL_TIMEOUT;
854         }
855       }
856     }
857     else
858     {
859       while(__HAL_RCC_GET_SYSCLK_SOURCE() != RCC_SYSCLKSOURCE_STATUS_MSI)
860       {
861         if((HAL_GetTick() - tickstart ) > CLOCKSWITCH_TIMEOUT_VALUE)
862         {
863           return HAL_TIMEOUT;
864         }
865       }
866     }
867   }
868   /* Decreasing the number of wait states because of lower CPU frequency */
869   if(FLatency < (FLASH->ACR & FLASH_ACR_LATENCY))
870   {
871     /* Program the new number of wait states to the LATENCY bits in the FLASH_ACR register */
872     __HAL_FLASH_SET_LATENCY(FLatency);
873 
874     /* Check that the new number of wait states is taken into account to access the Flash
875     memory by reading the FLASH_ACR register */
876     if((FLASH->ACR & FLASH_ACR_LATENCY) != FLatency)
877     {
878       return HAL_ERROR;
879     }
880   }
881 
882   /*-------------------------- PCLK1 Configuration ---------------------------*/
883   if(((RCC_ClkInitStruct->ClockType) & RCC_CLOCKTYPE_PCLK1) == RCC_CLOCKTYPE_PCLK1)
884   {
885     assert_param(IS_RCC_PCLK(RCC_ClkInitStruct->APB1CLKDivider));
886     MODIFY_REG(RCC->CFGR, RCC_CFGR_PPRE1, RCC_ClkInitStruct->APB1CLKDivider);
887   }
888 
889   /*-------------------------- PCLK2 Configuration ---------------------------*/
890   if(((RCC_ClkInitStruct->ClockType) & RCC_CLOCKTYPE_PCLK2) == RCC_CLOCKTYPE_PCLK2)
891   {
892     assert_param(IS_RCC_PCLK(RCC_ClkInitStruct->APB2CLKDivider));
893     MODIFY_REG(RCC->CFGR, RCC_CFGR_PPRE2, ((RCC_ClkInitStruct->APB2CLKDivider) << 3U));
894   }
895 
896   /* Update the SystemCoreClock global variable */
897   SystemCoreClock = HAL_RCC_GetSysClockFreq() >> AHBPrescTable[(RCC->CFGR & RCC_CFGR_HPRE)>> RCC_CFGR_HPRE_BITNUMBER];
898 
899   /* Configure the source of time base considering new system clocks settings*/
900   HAL_InitTick (TICK_INT_PRIORITY);
901 
902   return HAL_OK;
903 }
904 
905 /**
906   * @}
907   */
908 
909 /** @defgroup RCC_Exported_Functions_Group2 Peripheral Control functions
910   *  @brief   RCC clocks control functions
911   *
912   @verbatim
913   ===============================================================================
914                   ##### Peripheral Control functions #####
915   ===============================================================================
916     [..]
917     This subsection provides a set of functions allowing to control the RCC Clocks
918     frequencies.
919 
920   @endverbatim
921   * @{
922   */
923 
924 /**
925   * @brief  Selects the clock source to output on MCO pin.
926   * @note   MCO pin should be configured in alternate function mode.
927   * @param  RCC_MCOx specifies the output direction for the clock source.
928   *          This parameter can be one of the following values:
929   *            @arg @ref RCC_MCO1 Clock source to output on MCO1 pin(PA8).
930   * @param  RCC_MCOSource specifies the clock source to output.
931   *          This parameter can be one of the following values:
932   *            @arg @ref RCC_MCO1SOURCE_NOCLOCK     No clock selected as MCO clock
933   *            @arg @ref RCC_MCO1SOURCE_SYSCLK      System clock selected as MCO clock
934   *            @arg @ref RCC_MCO1SOURCE_HSI         HSI selected as MCO clock
935   *            @arg @ref RCC_MCO1SOURCE_HSE         HSE selected as MCO clock
936   *            @arg @ref RCC_MCO1SOURCE_MSI         MSI oscillator clock selected as MCO clock
937   *            @arg @ref RCC_MCO1SOURCE_PLLCLK      PLL clock selected as MCO clock
938   *            @arg @ref RCC_MCO1SOURCE_LSI         LSI clock selected as MCO clock
939   *            @arg @ref RCC_MCO1SOURCE_LSE         LSE clock selected as MCO clock
940   * @param  RCC_MCODiv specifies the MCO DIV.
941   *          This parameter can be one of the following values:
942   *            @arg @ref RCC_MCODIV_1 no division applied to MCO clock
943   *            @arg @ref RCC_MCODIV_2  division by 2 applied to MCO clock
944   *            @arg @ref RCC_MCODIV_4  division by 4 applied to MCO clock
945   *            @arg @ref RCC_MCODIV_8  division by 8 applied to MCO clock
946   *            @arg @ref RCC_MCODIV_16 division by 16 applied to MCO clock
947   * @retval None
948   */
HAL_RCC_MCOConfig(uint32_t RCC_MCOx,uint32_t RCC_MCOSource,uint32_t RCC_MCODiv)949 void HAL_RCC_MCOConfig(uint32_t RCC_MCOx, uint32_t RCC_MCOSource, uint32_t RCC_MCODiv)
950 {
951   GPIO_InitTypeDef gpio;
952 
953   /* Check the parameters */
954   assert_param(IS_RCC_MCO(RCC_MCOx));
955   assert_param(IS_RCC_MCODIV(RCC_MCODiv));
956   assert_param(IS_RCC_MCO1SOURCE(RCC_MCOSource));
957 
958   /* Configure the MCO1 pin in alternate function mode */
959   gpio.Mode      = GPIO_MODE_AF_PP;
960   gpio.Speed     = GPIO_SPEED_FREQ_HIGH;
961   gpio.Pull      = GPIO_NOPULL;
962   gpio.Pin       = MCO1_PIN;
963   gpio.Alternate = GPIO_AF0_MCO;
964 
965   /* MCO1 Clock Enable */
966   MCO1_CLK_ENABLE();
967 
968   HAL_GPIO_Init(MCO1_GPIO_PORT, &gpio);
969 
970   /* Configure the MCO clock source */
971   __HAL_RCC_MCO1_CONFIG(RCC_MCOSource, RCC_MCODiv);
972 }
973 
974 /**
975   * @brief  Enables the Clock Security System.
976   * @note   If a failure is detected on the HSE oscillator clock, this oscillator
977   *         is automatically disabled and an interrupt is generated to inform the
978   *         software about the failure (Clock Security System Interrupt, CSSI),
979   *         allowing the MCU to perform rescue operations. The CSSI is linked to
980   *         the Cortex-M3 NMI (Non-Maskable Interrupt) exception vector.
981   * @retval None
982   */
HAL_RCC_EnableCSS(void)983 void HAL_RCC_EnableCSS(void)
984 {
985   *(__IO uint32_t *) RCC_CR_CSSON_BB = (uint32_t)ENABLE;
986 }
987 
988 /**
989   * @brief  Disables the Clock Security System.
990   * @retval None
991   */
HAL_RCC_DisableCSS(void)992 void HAL_RCC_DisableCSS(void)
993 {
994   *(__IO uint32_t *) RCC_CR_CSSON_BB = (uint32_t)DISABLE;
995 }
996 
997 /**
998   * @brief  Returns the SYSCLK frequency
999   * @note   The system frequency computed by this function is not the real
1000   *         frequency in the chip. It is calculated based on the predefined
1001   *         constant and the selected clock source:
1002   * @note     If SYSCLK source is MSI, function returns a value based on MSI
1003   *             Value as defined by the MSI range.
1004   * @note     If SYSCLK source is HSI, function returns values based on HSI_VALUE(*)
1005   * @note     If SYSCLK source is HSE, function returns a value based on HSE_VALUE(**)
1006   * @note     If SYSCLK source is PLL, function returns a value based on HSE_VALUE(**)
1007   *           or HSI_VALUE(*) multiplied/divided by the PLL factors.
1008   * @note     (*) HSI_VALUE is a constant defined in stm32l1xx_hal_conf.h file (default value
1009   *               16 MHz) but the real value may vary depending on the variations
1010   *               in voltage and temperature.
1011   * @note     (**) HSE_VALUE is a constant defined in stm32l1xx_hal_conf.h file (default value
1012   *                8 MHz), user has to ensure that HSE_VALUE is same as the real
1013   *                frequency of the crystal used. Otherwise, this function may
1014   *                have wrong result.
1015   *
1016   * @note   The result of this function could be not correct when using fractional
1017   *         value for HSE crystal.
1018   *
1019   * @note   This function can be used by the user application to compute the
1020   *         baud-rate for the communication peripherals or configure other parameters.
1021   *
1022   * @note   Each time SYSCLK changes, this function must be called to update the
1023   *         right SYSCLK value. Otherwise, any configuration based on this function will be incorrect.
1024   *
1025   * @retval SYSCLK frequency
1026   */
HAL_RCC_GetSysClockFreq(void)1027 uint32_t HAL_RCC_GetSysClockFreq(void)
1028 {
1029   uint32_t tmpreg = 0U, pllm = 0U, plld = 0U, pllvco = 0U, msiclkrange = 0U;
1030   uint32_t sysclockfreq = 0U;
1031 
1032   tmpreg = RCC->CFGR;
1033 
1034   /* Get SYSCLK source -------------------------------------------------------*/
1035   switch (tmpreg & RCC_CFGR_SWS)
1036   {
1037     case RCC_SYSCLKSOURCE_STATUS_HSI:  /* HSI used as system clock source */
1038     {
1039       sysclockfreq = HSI_VALUE;
1040       break;
1041     }
1042     case RCC_SYSCLKSOURCE_STATUS_HSE:  /* HSE used as system clock */
1043     {
1044       sysclockfreq = HSE_VALUE;
1045       break;
1046     }
1047     case RCC_SYSCLKSOURCE_STATUS_PLLCLK:  /* PLL used as system clock */
1048     {
1049       pllm = PLLMulTable[(uint32_t)(tmpreg & RCC_CFGR_PLLMUL) >> RCC_CFGR_PLLMUL_BITNUMBER];
1050       plld = ((uint32_t)(tmpreg & RCC_CFGR_PLLDIV) >> RCC_CFGR_PLLDIV_BITNUMBER) + 1U;
1051       if (__HAL_RCC_GET_PLL_OSCSOURCE() != RCC_PLLSOURCE_HSI)
1052       {
1053         /* HSE used as PLL clock source */
1054         pllvco = (HSE_VALUE * pllm) / plld;
1055       }
1056       else
1057       {
1058         /* HSI used as PLL clock source */
1059         pllvco = (HSI_VALUE * pllm) / plld;
1060       }
1061       sysclockfreq = pllvco;
1062       break;
1063     }
1064     case RCC_SYSCLKSOURCE_STATUS_MSI:  /* MSI used as system clock source */
1065     default: /* MSI used as system clock */
1066     {
1067       msiclkrange = (RCC->ICSCR & RCC_ICSCR_MSIRANGE ) >> RCC_ICSCR_MSIRANGE_BITNUMBER;
1068       sysclockfreq = (32768U * (1U << (msiclkrange + 1U)));
1069       break;
1070     }
1071   }
1072   return sysclockfreq;
1073 }
1074 
1075 /**
1076   * @brief  Returns the HCLK frequency
1077   * @note   Each time HCLK changes, this function must be called to update the
1078   *         right HCLK value. Otherwise, any configuration based on this function will be incorrect.
1079   *
1080   * @note   The SystemCoreClock CMSIS variable is used to store System Clock Frequency
1081   *         and updated within this function
1082   * @retval HCLK frequency
1083   */
HAL_RCC_GetHCLKFreq(void)1084 uint32_t HAL_RCC_GetHCLKFreq(void)
1085 {
1086   return SystemCoreClock;
1087 }
1088 
1089 /**
1090   * @brief  Returns the PCLK1 frequency
1091   * @note   Each time PCLK1 changes, this function must be called to update the
1092   *         right PCLK1 value. Otherwise, any configuration based on this function will be incorrect.
1093   * @retval PCLK1 frequency
1094   */
HAL_RCC_GetPCLK1Freq(void)1095 uint32_t HAL_RCC_GetPCLK1Freq(void)
1096 {
1097   /* Get HCLK source and Compute PCLK1 frequency ---------------------------*/
1098   return (HAL_RCC_GetHCLKFreq() >> APBPrescTable[(RCC->CFGR & RCC_CFGR_PPRE1) >> RCC_CFGR_PPRE1_BITNUMBER]);
1099 }
1100 
1101 /**
1102   * @brief  Returns the PCLK2 frequency
1103   * @note   Each time PCLK2 changes, this function must be called to update the
1104   *         right PCLK2 value. Otherwise, any configuration based on this function will be incorrect.
1105   * @retval PCLK2 frequency
1106   */
HAL_RCC_GetPCLK2Freq(void)1107 uint32_t HAL_RCC_GetPCLK2Freq(void)
1108 {
1109   /* Get HCLK source and Compute PCLK2 frequency ---------------------------*/
1110   return (HAL_RCC_GetHCLKFreq()>> APBPrescTable[(RCC->CFGR & RCC_CFGR_PPRE2) >> RCC_CFGR_PPRE2_BITNUMBER]);
1111 }
1112 
1113 /**
1114   * @brief  Configures the RCC_OscInitStruct according to the internal
1115   * RCC configuration registers.
1116   * @param  RCC_OscInitStruct pointer to an RCC_OscInitTypeDef structure that
1117   * will be configured.
1118   * @retval None
1119   */
HAL_RCC_GetOscConfig(RCC_OscInitTypeDef * RCC_OscInitStruct)1120 void HAL_RCC_GetOscConfig(RCC_OscInitTypeDef  *RCC_OscInitStruct)
1121 {
1122   /* Check the parameters */
1123   assert_param(RCC_OscInitStruct != NULL);
1124 
1125   /* Set all possible values for the Oscillator type parameter ---------------*/
1126   RCC_OscInitStruct->OscillatorType = RCC_OSCILLATORTYPE_HSE | RCC_OSCILLATORTYPE_HSI  \
1127                   | RCC_OSCILLATORTYPE_LSE | RCC_OSCILLATORTYPE_LSI | RCC_OSCILLATORTYPE_MSI;
1128 
1129 
1130   /* Get the HSE configuration -----------------------------------------------*/
1131   if((RCC->CR &RCC_CR_HSEBYP) == RCC_CR_HSEBYP)
1132   {
1133     RCC_OscInitStruct->HSEState = RCC_HSE_BYPASS;
1134   }
1135   else if((RCC->CR &RCC_CR_HSEON) == RCC_CR_HSEON)
1136   {
1137     RCC_OscInitStruct->HSEState = RCC_HSE_ON;
1138   }
1139   else
1140   {
1141     RCC_OscInitStruct->HSEState = RCC_HSE_OFF;
1142   }
1143 
1144   /* Get the HSI configuration -----------------------------------------------*/
1145   if((RCC->CR &RCC_CR_HSION) == RCC_CR_HSION)
1146   {
1147     RCC_OscInitStruct->HSIState = RCC_HSI_ON;
1148   }
1149   else
1150   {
1151     RCC_OscInitStruct->HSIState = RCC_HSI_OFF;
1152   }
1153 
1154   RCC_OscInitStruct->HSICalibrationValue = (uint32_t)((RCC->ICSCR & RCC_ICSCR_HSITRIM) >> POSITION_VAL(RCC_ICSCR_HSITRIM));
1155 
1156   /* Get the MSI configuration -----------------------------------------------*/
1157   if((RCC->CR &RCC_CR_MSION) == RCC_CR_MSION)
1158   {
1159     RCC_OscInitStruct->MSIState = RCC_MSI_ON;
1160   }
1161   else
1162   {
1163     RCC_OscInitStruct->MSIState = RCC_MSI_OFF;
1164   }
1165 
1166   RCC_OscInitStruct->MSICalibrationValue = (uint32_t)((RCC->ICSCR & RCC_ICSCR_MSITRIM) >> RCC_ICSCR_MSITRIM_BITNUMBER);
1167   RCC_OscInitStruct->MSIClockRange = (uint32_t)((RCC->ICSCR & RCC_ICSCR_MSIRANGE));
1168 
1169   /* Get the LSE configuration -----------------------------------------------*/
1170   if((RCC->CSR &RCC_CSR_LSEBYP) == RCC_CSR_LSEBYP)
1171   {
1172     RCC_OscInitStruct->LSEState = RCC_LSE_BYPASS;
1173   }
1174   else if((RCC->CSR &RCC_CSR_LSEON) == RCC_CSR_LSEON)
1175   {
1176     RCC_OscInitStruct->LSEState = RCC_LSE_ON;
1177   }
1178   else
1179   {
1180     RCC_OscInitStruct->LSEState = RCC_LSE_OFF;
1181   }
1182 
1183   /* Get the LSI configuration -----------------------------------------------*/
1184   if((RCC->CSR &RCC_CSR_LSION) == RCC_CSR_LSION)
1185   {
1186     RCC_OscInitStruct->LSIState = RCC_LSI_ON;
1187   }
1188   else
1189   {
1190     RCC_OscInitStruct->LSIState = RCC_LSI_OFF;
1191   }
1192 
1193 
1194   /* Get the PLL configuration -----------------------------------------------*/
1195   if((RCC->CR &RCC_CR_PLLON) == RCC_CR_PLLON)
1196   {
1197     RCC_OscInitStruct->PLL.PLLState = RCC_PLL_ON;
1198   }
1199   else
1200   {
1201     RCC_OscInitStruct->PLL.PLLState = RCC_PLL_OFF;
1202   }
1203   RCC_OscInitStruct->PLL.PLLSource = (uint32_t)(RCC->CFGR & RCC_CFGR_PLLSRC);
1204   RCC_OscInitStruct->PLL.PLLMUL = (uint32_t)(RCC->CFGR & RCC_CFGR_PLLMUL);
1205   RCC_OscInitStruct->PLL.PLLDIV = (uint32_t)(RCC->CFGR & RCC_CFGR_PLLDIV);
1206 }
1207 
1208 /**
1209   * @brief  Get the RCC_ClkInitStruct according to the internal
1210   * RCC configuration registers.
1211   * @param  RCC_ClkInitStruct pointer to an RCC_ClkInitTypeDef structure that
1212   * contains the current clock configuration.
1213   * @param  pFLatency Pointer on the Flash Latency.
1214   * @retval None
1215   */
HAL_RCC_GetClockConfig(RCC_ClkInitTypeDef * RCC_ClkInitStruct,uint32_t * pFLatency)1216 void HAL_RCC_GetClockConfig(RCC_ClkInitTypeDef  *RCC_ClkInitStruct, uint32_t *pFLatency)
1217 {
1218   /* Check the parameters */
1219   assert_param(RCC_ClkInitStruct != NULL);
1220   assert_param(pFLatency != NULL);
1221 
1222   /* Set all possible values for the Clock type parameter --------------------*/
1223   RCC_ClkInitStruct->ClockType = RCC_CLOCKTYPE_SYSCLK | RCC_CLOCKTYPE_HCLK | RCC_CLOCKTYPE_PCLK1 | RCC_CLOCKTYPE_PCLK2;
1224 
1225   /* Get the SYSCLK configuration --------------------------------------------*/
1226   RCC_ClkInitStruct->SYSCLKSource = (uint32_t)(RCC->CFGR & RCC_CFGR_SW);
1227 
1228   /* Get the HCLK configuration ----------------------------------------------*/
1229   RCC_ClkInitStruct->AHBCLKDivider = (uint32_t)(RCC->CFGR & RCC_CFGR_HPRE);
1230 
1231   /* Get the APB1 configuration ----------------------------------------------*/
1232   RCC_ClkInitStruct->APB1CLKDivider = (uint32_t)(RCC->CFGR & RCC_CFGR_PPRE1);
1233 
1234   /* Get the APB2 configuration ----------------------------------------------*/
1235   RCC_ClkInitStruct->APB2CLKDivider = (uint32_t)((RCC->CFGR & RCC_CFGR_PPRE2) >> 3U);
1236 
1237   /* Get the Flash Wait State (Latency) configuration ------------------------*/
1238   *pFLatency = (uint32_t)(FLASH->ACR & FLASH_ACR_LATENCY);
1239 }
1240 
1241 /**
1242   * @brief This function handles the RCC CSS interrupt request.
1243   * @note This API should be called under the NMI_Handler().
1244   * @retval None
1245   */
HAL_RCC_NMI_IRQHandler(void)1246 void HAL_RCC_NMI_IRQHandler(void)
1247 {
1248   /* Check RCC CSSF flag  */
1249   if(__HAL_RCC_GET_IT(RCC_IT_CSS))
1250   {
1251     /* RCC Clock Security System interrupt user callback */
1252     HAL_RCC_CSSCallback();
1253 
1254     /* Clear RCC CSS pending bit */
1255     __HAL_RCC_CLEAR_IT(RCC_IT_CSS);
1256   }
1257 }
1258 
1259 /**
1260   * @brief  RCC Clock Security System interrupt callback
1261   * @retval none
1262   */
HAL_RCC_CSSCallback(void)1263 __weak void HAL_RCC_CSSCallback(void)
1264 {
1265   /* NOTE : This function Should not be modified, when the callback is needed,
1266     the HAL_RCC_CSSCallback could be implemented in the user file
1267     */
1268 }
1269 
1270 /**
1271   * @}
1272   */
1273 
1274 /**
1275   * @}
1276   */
1277 
1278 /* Private function prototypes -----------------------------------------------*/
1279 /** @addtogroup RCC_Private_Functions
1280   * @{
1281   */
1282 /**
1283   * @brief  Update number of Flash wait states in line with MSI range and current
1284             voltage range
1285   * @param  MSIrange  MSI range value from RCC_MSIRANGE_0 to RCC_MSIRANGE_6
1286   * @retval HAL status
1287   */
RCC_SetFlashLatencyFromMSIRange(uint32_t MSIrange)1288 static HAL_StatusTypeDef RCC_SetFlashLatencyFromMSIRange(uint32_t MSIrange)
1289 {
1290   uint32_t vos = 0U;
1291   uint32_t latency = FLASH_LATENCY_0;  /* default value 0WS */
1292 
1293   /* HCLK can reach 4 MHz only if AHB prescaler = 1 */
1294   if (READ_BIT(RCC->CFGR, RCC_CFGR_HPRE) == RCC_SYSCLK_DIV1)
1295   {
1296     if(__HAL_RCC_PWR_IS_CLK_ENABLED())
1297     {
1298       vos = READ_BIT(PWR->CR, PWR_CR_VOS);
1299     }
1300     else
1301     {
1302       __HAL_RCC_PWR_CLK_ENABLE();
1303       vos = READ_BIT(PWR->CR, PWR_CR_VOS);
1304       __HAL_RCC_PWR_CLK_DISABLE();
1305     }
1306 
1307     /* Check if need to set latency 1 only for Range 3 & HCLK = 4MHz */
1308     if((vos == PWR_REGULATOR_VOLTAGE_SCALE3) && (MSIrange == RCC_MSIRANGE_6))
1309     {
1310       latency = FLASH_LATENCY_1; /* 1WS */
1311     }
1312   }
1313 
1314   __HAL_FLASH_SET_LATENCY(latency);
1315 
1316   /* Check that the new number of wait states is taken into account to access the Flash
1317      memory by reading the FLASH_ACR register */
1318   if((FLASH->ACR & FLASH_ACR_LATENCY) != latency)
1319   {
1320     return HAL_ERROR;
1321   }
1322 
1323   return HAL_OK;
1324 }
1325 
1326 /**
1327   * @}
1328   */
1329 
1330 #endif /* HAL_RCC_MODULE_ENABLED */
1331 /**
1332   * @}
1333   */
1334 
1335 /**
1336   * @}
1337   */
1338 
1339 /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
1340