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