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