1 /**
2   ******************************************************************************
3   * @file    stm32l4xx_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 Multiple Speed Internal oscillator
17       (4 MHz) with Flash 0 wait state. Flash prefetch buffer, D-Cache
18       and I-Cache are disabled, and all peripherals are off except internal
19       SRAM, Flash and JTAG.
20 
21       (+) There is no prescaler on High speed (AHBs) and Low speed (APBs) busses:
22           all peripherals mapped on these busses are running at MSI speed.
23       (+) The clock for all peripherals is switched off, except the SRAM and FLASH.
24       (+) All GPIOs are in analog mode, except the JTAG pins which
25           are assigned to be used for debug purpose.
26 
27     [..]
28       Once the device started from reset, the user application has to:
29       (+) Configure the clock source to be used to drive the System clock
30           (if the application needs higher frequency/performance)
31       (+) Configure the System clock frequency and Flash settings
32       (+) Configure the AHB and APB busses prescalers
33       (+) Enable the clock for the peripheral(s) to be used
34       (+) Configure the clock source(s) for peripherals which clocks are not
35           derived from the System clock (SAIx, RTC, ADC, USB OTG FS/SDMMC1/RNG)
36 
37   @endverbatim
38   ******************************************************************************
39   * @attention
40   *
41   * <h2><center>&copy; COPYRIGHT(c) 2017 STMicroelectronics</center></h2>
42   *
43   * Redistribution and use in source and binary forms, with or without modification,
44   * are permitted provided that the following conditions are met:
45   *   1. Redistributions of source code must retain the above copyright notice,
46   *      this list of conditions and the following disclaimer.
47   *   2. Redistributions in binary form must reproduce the above copyright notice,
48   *      this list of conditions and the following disclaimer in the documentation
49   *      and/or other materials provided with the distribution.
50   *   3. Neither the name of STMicroelectronics nor the names of its contributors
51   *      may be used to endorse or promote products derived from this software
52   *      without specific prior written permission.
53   *
54   * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
55   * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
56   * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
57   * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
58   * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
59   * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
60   * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
61   * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
62   * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
63   * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
64   *
65   ******************************************************************************
66   */
67 
68 /* Includes ------------------------------------------------------------------*/
69 #include "stm32l4xx_hal.h"
70 
71 /** @addtogroup STM32L4xx_HAL_Driver
72   * @{
73   */
74 
75 /** @defgroup RCC RCC
76   * @brief RCC HAL module driver
77   * @{
78   */
79 
80 #ifdef HAL_RCC_MODULE_ENABLED
81 
82 /* Private typedef -----------------------------------------------------------*/
83 /* Private define ------------------------------------------------------------*/
84 /** @defgroup RCC_Private_Constants RCC Private Constants
85  * @{
86  */
87 #define HSE_TIMEOUT_VALUE          HSE_STARTUP_TIMEOUT
88 #define HSI_TIMEOUT_VALUE          2U    /* 2 ms (minimum Tick + 1) */
89 #define MSI_TIMEOUT_VALUE          2U    /* 2 ms (minimum Tick + 1) */
90 #if defined(RCC_CSR_LSIPREDIV)
91 #define LSI_TIMEOUT_VALUE          17U   /* 17 ms (16 ms starting time + 1) */
92 #else
93 #define LSI_TIMEOUT_VALUE          2U    /* 2 ms (minimum Tick + 1) */
94 #endif /* RCC_CSR_LSIPREDIV */
95 #define HSI48_TIMEOUT_VALUE        2U    /* 2 ms (minimum Tick + 1) */
96 #define PLL_TIMEOUT_VALUE          2U    /* 2 ms (minimum Tick + 1) */
97 #define CLOCKSWITCH_TIMEOUT_VALUE  5000U /* 5 s    */
98 /**
99   * @}
100   */
101 
102 /* Private macro -------------------------------------------------------------*/
103 /** @defgroup RCC_Private_Macros RCC Private Macros
104   * @{
105   */
106 #define __MCO1_CLK_ENABLE()   __HAL_RCC_GPIOA_CLK_ENABLE()
107 #define MCO1_GPIO_PORT        GPIOA
108 #define MCO1_PIN              GPIO_PIN_8
109 
110 #define RCC_PLL_OSCSOURCE_CONFIG(__HAL_RCC_PLLSOURCE__) \
111             (MODIFY_REG(RCC->PLLCFGR, RCC_PLLCFGR_PLLSRC, (__HAL_RCC_PLLSOURCE__)))
112 /**
113   * @}
114   */
115 
116 /* Private variables ---------------------------------------------------------*/
117 
118 /* Private function prototypes -----------------------------------------------*/
119 /** @defgroup RCC_Private_Functions RCC Private Functions
120   * @{
121   */
122 static HAL_StatusTypeDef RCC_SetFlashLatencyFromMSIRange(uint32_t msirange);
123 #if defined(STM32L4R5xx) || defined(STM32L4R7xx) || defined(STM32L4R9xx) || defined(STM32L4S5xx) || defined(STM32L4S7xx) || defined(STM32L4S9xx)
124 static uint32_t          RCC_GetSysClockFreqFromPLLSource(void);
125 #endif
126 /**
127   * @}
128   */
129 
130 /* Exported functions --------------------------------------------------------*/
131 
132 /** @defgroup RCC_Exported_Functions RCC Exported Functions
133   * @{
134   */
135 
136 /** @defgroup RCC_Exported_Functions_Group1 Initialization and de-initialization functions
137   *  @brief    Initialization and Configuration functions
138   *
139   @verbatim
140  ===============================================================================
141            ##### Initialization and de-initialization functions #####
142  ===============================================================================
143     [..]
144       This section provides functions allowing to configure the internal and external oscillators
145       (HSE, HSI, LSE, MSI, LSI, PLL, CSS and MCO) and the System busses clocks (SYSCLK, AHB, APB1
146        and APB2).
147 
148     [..] Internal/external clock and PLL configuration
149          (+) HSI (high-speed internal): 16 MHz factory-trimmed RC used directly or through
150              the PLL as System clock source.
151 
152          (+) MSI (Mutiple Speed Internal): Its frequency is software trimmable from 100KHZ to 48MHZ.
153              It can be used to generate the clock for the USB OTG FS (48 MHz).
154              The number of flash wait states is automatically adjusted when MSI range is updated with
155              HAL_RCC_OscConfig() and the MSI is used as System clock source.
156 
157          (+) LSI (low-speed internal): 32 KHz low consumption RC used as IWDG and/or RTC
158              clock source.
159 
160          (+) HSE (high-speed external): 4 to 48 MHz crystal oscillator used directly or
161              through the PLL as System clock source. Can be used also optionally as RTC clock source.
162 
163          (+) LSE (low-speed external): 32.768 KHz oscillator used optionally as RTC clock source.
164 
165          (+) PLL (clocked by HSI, HSE or MSI) providing up to three independent output clocks:
166            (++) The first output is used to generate the high speed system clock (up to 80MHz).
167            (++) The second output is used to generate the clock for the USB OTG FS (48 MHz),
168                 the random analog generator (<=48 MHz) and the SDMMC1 (<= 48 MHz).
169            (++) The third output is used to generate an accurate clock to achieve
170                 high-quality audio performance on SAI interface.
171 
172          (+) PLLSAI1 (clocked by HSI, HSE or MSI) providing up to three independent output clocks:
173            (++) The first output is used to generate SAR ADC1 clock.
174            (++) The second output is used to generate the clock for the USB OTG FS (48 MHz),
175                 the random analog generator (<=48 MHz) and the SDMMC1 (<= 48 MHz).
176            (++) The Third output is used to generate an accurate clock to achieve
177                 high-quality audio performance on SAI interface.
178 
179          (+) PLLSAI2 (clocked by HSI, HSE or MSI) providing up to two independent output clocks:
180            (++) The first output is used to generate SAR ADC2 clock.
181            (++) The second  output is used to generate an accurate clock to achieve
182                 high-quality audio performance on SAI interface.
183 
184          (+) CSS (Clock security system): once enabled, if a HSE clock failure occurs
185             (HSE used directly or through PLL as System clock source), the System clock
186              is automatically switched to HSI and an interrupt is generated if enabled.
187              The interrupt is linked to the Cortex-M4 NMI (Non-Maskable Interrupt)
188              exception vector.
189 
190          (+) MCO (microcontroller clock output): used to output MSI, LSI, HSI, LSE, HSE or
191              main PLL clock (through a configurable prescaler) on PA8 pin.
192 
193     [..] System, AHB and APB busses clocks configuration
194          (+) Several clock sources can be used to drive the System clock (SYSCLK): MSI, HSI,
195              HSE and main PLL.
196              The AHB clock (HCLK) is derived from System clock through configurable
197              prescaler and used to clock the CPU, memory and peripherals mapped
198              on AHB bus (DMA, GPIO...). APB1 (PCLK1) and APB2 (PCLK2) clocks are derived
199              from AHB clock through configurable prescalers and used to clock
200              the peripherals mapped on these busses. You can use
201              "HAL_RCC_GetSysClockFreq()" function to retrieve the frequencies of these clocks.
202 
203          -@- All the peripheral clocks are derived from the System clock (SYSCLK) except:
204 
205            (+@) SAI: the SAI clock can be derived either from a specific PLL (PLLSAI1) or (PLLSAI2) or
206                 from an external clock mapped on the SAI_CKIN pin.
207                 You have to use HAL_RCCEx_PeriphCLKConfig() function to configure this clock.
208            (+@) RTC: the RTC clock can be derived either from the LSI, LSE or HSE clock
209                 divided by 2 to 31.
210                 You have to use __HAL_RCC_RTC_ENABLE() and HAL_RCCEx_PeriphCLKConfig() function
211                 to configure this clock.
212            (+@) USB OTG FS, SDMMC1 and RNG: USB OTG FS requires a frequency equal to 48 MHz
213                 to work correctly, while the SDMMC1 and RNG peripherals require a frequency
214                 equal or lower than to 48 MHz. This clock is derived of the main PLL or PLLSAI1
215                 through PLLQ divider. You have to enable the peripheral clock and use
216                 HAL_RCCEx_PeriphCLKConfig() function to configure this clock.
217            (+@) IWDG clock which is always the LSI clock.
218 
219 
220          (+) The maximum frequency of the SYSCLK, HCLK, PCLK1 and PCLK2 is 80 MHz.
221              The clock source frequency should be adapted depending on the device voltage range
222              as listed in the Reference Manual "Clock source frequency versus voltage scaling" chapter.
223 
224   @endverbatim
225 
226            Table 1. HCLK clock frequency for STM32L4Rx/STM32L4Sx devices
227            +--------------------------------------------------------+
228            | Latency         |     HCLK clock frequency (MHz)       |
229            |                 |--------------------------------------|
230            |                 |  voltage range 1  | voltage range 2  |
231            |                 |       1.2 V       |     1.0 V        |
232            |-----------------|-------------------|------------------|
233            |0WS(1 CPU cycles)|   0 < HCLK <= 20  |  0 < HCLK <= 8   |
234            |-----------------|-------------------|------------------|
235            |1WS(2 CPU cycles)|  20 < HCLK <= 40  |  8 < HCLK <= 16  |
236            |-----------------|-------------------|------------------|
237            |2WS(3 CPU cycles)|  40 < HCLK <= 60  | 16 < HCLK <= 26  |
238            |-----------------|-------------------|------------------|
239            |3WS(4 CPU cycles)|  60 < HCLK <= 80  | 16 < HCLK <= 26  |
240            |-----------------|-------------------|------------------|
241            |4WS(5 CPU cycles)|  80 < HCLK <= 100 | 16 < HCLK <= 26  |
242            |-----------------|-------------------|------------------|
243            |5WS(6 CPU cycles)| 100 < HCLK <= 120 | 16 < HCLK <= 26  |
244            +--------------------------------------------------------+
245 
246            Table 2. HCLK clock frequency for other STM32L4 devices
247            +-------------------------------------------------------+
248            | Latency         |    HCLK clock frequency (MHz)       |
249            |                 |-------------------------------------|
250            |                 | voltage range 1  | voltage range 2  |
251            |                 |      1.2 V       |     1.0 V        |
252            |-----------------|------------------|------------------|
253            |0WS(1 CPU cycles)|  0 < HCLK <= 16  |  0 < HCLK <= 6   |
254            |-----------------|------------------|------------------|
255            |1WS(2 CPU cycles)| 16 < HCLK <= 32  |  6 < HCLK <= 12  |
256            |-----------------|------------------|------------------|
257            |2WS(3 CPU cycles)| 32 < HCLK <= 48  | 12 < HCLK <= 18  |
258            |-----------------|------------------|------------------|
259            |3WS(4 CPU cycles)| 48 < HCLK <= 64  | 18 < HCLK <= 26  |
260            |-----------------|------------------|------------------|
261            |4WS(5 CPU cycles)| 64 < HCLK <= 80  | 18 < HCLK <= 26  |
262            +-------------------------------------------------------+
263   * @{
264   */
265 
266 /**
267   * @brief  Reset the RCC clock configuration to the default reset state.
268   * @note   The default reset state of the clock configuration is given below:
269   *            - MSI ON and used as system clock source
270   *            - HSE, HSI, PLL, PLLSAI1 and PLLISAI2 OFF
271   *            - AHB, APB1 and APB2 prescaler set to 1.
272   *            - CSS, MCO1 OFF
273   *            - All interrupts disabled
274   *            - All interrupt and reset flags cleared
275   * @note   This function doesn't modify the configuration of the
276   *            - Peripheral clocks
277   *            - LSI, LSE and RTC clocks
278   * @retval HAL status
279   */
HAL_RCC_DeInit(void)280 HAL_StatusTypeDef HAL_RCC_DeInit(void)
281 {
282   uint32_t tickstart;
283 
284   /* Set MSION bit */
285   SET_BIT(RCC->CR, RCC_CR_MSION);
286 
287   /* Insure MSIRDY bit is set before writing default MSIRANGE value */
288   /* Get start tick */
289   tickstart = HAL_GetTick();
290 
291   /* Wait till MSI is ready */
292   while(READ_BIT(RCC->CR, RCC_CR_MSIRDY) == 0U)
293   {
294     if((HAL_GetTick() - tickstart) > MSI_TIMEOUT_VALUE)
295     {
296       return HAL_TIMEOUT;
297     }
298   }
299 
300   /* Set MSIRANGE default value */
301   MODIFY_REG(RCC->CR, RCC_CR_MSIRANGE, RCC_MSIRANGE_6);
302 
303   /* Reset CFGR register (MSI is selected as system clock source) */
304   CLEAR_REG(RCC->CFGR);
305 
306   /* Update the SystemCoreClock global variable for MSI as system clock source */
307   SystemCoreClock = MSI_VALUE;
308 
309   /* Configure the source of time base considering new system clock settings  */
310   if(HAL_InitTick(TICK_INT_PRIORITY) != HAL_OK)
311   {
312     return HAL_ERROR;
313   }
314 
315   /* Insure MSI selected as system clock source */
316   /* Get start tick */
317   tickstart = HAL_GetTick();
318 
319   /* Wait till system clock source is ready */
320   while(READ_BIT(RCC->CFGR, RCC_CFGR_SWS) != RCC_CFGR_SWS_MSI)
321   {
322     if((HAL_GetTick() - tickstart) > CLOCKSWITCH_TIMEOUT_VALUE)
323     {
324       return HAL_TIMEOUT;
325     }
326   }
327 
328   /* Reset HSION, HSIKERON, HSIASFS, HSEON, HSECSSON, PLLON, PLLSAIxON bits */
329 #if defined(RCC_PLLSAI2_SUPPORT)
330 
331   CLEAR_BIT(RCC->CR, RCC_CR_HSEON | RCC_CR_HSION | RCC_CR_HSIKERON| RCC_CR_HSIASFS | RCC_CR_PLLON | RCC_CR_PLLSAI1ON | RCC_CR_PLLSAI2ON);
332 
333 #elif defined(RCC_PLLSAI1_SUPPORT)
334 
335   CLEAR_BIT(RCC->CR, RCC_CR_HSEON | RCC_CR_HSION | RCC_CR_HSIKERON| RCC_CR_HSIASFS | RCC_CR_PLLON | RCC_CR_PLLSAI1ON);
336 
337 #else
338 
339   CLEAR_BIT(RCC->CR, RCC_CR_HSEON | RCC_CR_HSION | RCC_CR_HSIKERON| RCC_CR_HSIASFS | RCC_CR_PLLON);
340 
341 #endif /* RCC_PLLSAI2_SUPPORT */
342 
343   /* Insure PLLRDY, PLLSAI1RDY and PLLSAI2RDY (if present) are reset */
344   /* Get start tick */
345   tickstart = HAL_GetTick();
346 
347 #if defined(RCC_PLLSAI2_SUPPORT)
348 
349   while(READ_BIT(RCC->CR, RCC_CR_PLLRDY | RCC_CR_PLLSAI1RDY | RCC_CR_PLLSAI2RDY) != 0U)
350 
351 #elif defined(RCC_PLLSAI1_SUPPORT)
352 
353   while(READ_BIT(RCC->CR, RCC_CR_PLLRDY | RCC_CR_PLLSAI1RDY) != 0U)
354 
355 #else
356 
357   while(READ_BIT(RCC->CR, RCC_CR_PLLRDY) != 0U)
358 
359 #endif
360   {
361     if((HAL_GetTick() - tickstart) > PLL_TIMEOUT_VALUE)
362     {
363       return HAL_TIMEOUT;
364     }
365   }
366 
367   /* Reset PLLCFGR register */
368   CLEAR_REG(RCC->PLLCFGR);
369   SET_BIT(RCC->PLLCFGR, RCC_PLLCFGR_PLLN_4 );
370 
371 #if defined(RCC_PLLSAI1_SUPPORT)
372 
373   /* Reset PLLSAI1CFGR register */
374   CLEAR_REG(RCC->PLLSAI1CFGR);
375   SET_BIT(RCC->PLLSAI1CFGR,  RCC_PLLSAI1CFGR_PLLSAI1N_4 );
376 
377 #endif /* RCC_PLLSAI1_SUPPORT */
378 
379 #if defined(RCC_PLLSAI2_SUPPORT)
380 
381   /* Reset PLLSAI2CFGR register */
382   CLEAR_REG(RCC->PLLSAI2CFGR);
383   SET_BIT(RCC->PLLSAI2CFGR,  RCC_PLLSAI2CFGR_PLLSAI2N_4 );
384 
385 #endif /* RCC_PLLSAI2_SUPPORT */
386 
387   /* Reset HSEBYP bit */
388   CLEAR_BIT(RCC->CR, RCC_CR_HSEBYP);
389 
390   /* Disable all interrupts */
391   CLEAR_REG(RCC->CIER);
392 
393   /* Clear all interrupt flags */
394   WRITE_REG(RCC->CICR, 0xFFFFFFFFU);
395 
396   /* Clear all reset flags */
397   SET_BIT(RCC->CSR, RCC_CSR_RMVF);
398 
399   return HAL_OK;
400 }
401 
402 /**
403   * @brief  Initialize the RCC Oscillators according to the specified parameters in the
404   *         RCC_OscInitTypeDef.
405   * @param  RCC_OscInitStruct  pointer to an RCC_OscInitTypeDef structure that
406   *         contains the configuration information for the RCC Oscillators.
407   * @note   The PLL is not disabled when used as system clock.
408   * @note   Transitions LSE Bypass to LSE On and LSE On to LSE Bypass are not
409   *         supported by this macro. User should request a transition to LSE Off
410   *         first and then LSE On or LSE Bypass.
411   * @note   Transition HSE Bypass to HSE On and HSE On to HSE Bypass are not
412   *         supported by this macro. User should request a transition to HSE Off
413   *         first and then HSE On or HSE Bypass.
414   * @retval HAL status
415   */
HAL_RCC_OscConfig(RCC_OscInitTypeDef * RCC_OscInitStruct)416 HAL_StatusTypeDef HAL_RCC_OscConfig(RCC_OscInitTypeDef  *RCC_OscInitStruct)
417 {
418   uint32_t tickstart;
419   HAL_StatusTypeDef status;
420   uint32_t sysclk_source, pll_oscsource;
421 
422   /* Check Null pointer */
423   if(RCC_OscInitStruct == NULL)
424   {
425     return HAL_ERROR;
426   }
427 
428   /* Check the parameters */
429   assert_param(IS_RCC_OSCILLATORTYPE(RCC_OscInitStruct->OscillatorType));
430 
431   sysclk_source = __HAL_RCC_GET_SYSCLK_SOURCE();
432   pll_oscsource = __HAL_RCC_GET_PLL_OSCSOURCE();
433 
434   /*----------------------------- MSI Configuration --------------------------*/
435   if(((RCC_OscInitStruct->OscillatorType) & RCC_OSCILLATORTYPE_MSI) == RCC_OSCILLATORTYPE_MSI)
436   {
437     /* Check the parameters */
438     assert_param(IS_RCC_MSI(RCC_OscInitStruct->MSIState));
439     assert_param(IS_RCC_MSICALIBRATION_VALUE(RCC_OscInitStruct->MSICalibrationValue));
440     assert_param(IS_RCC_MSI_CLOCK_RANGE(RCC_OscInitStruct->MSIClockRange));
441 
442     /* Check if MSI is used as system clock or as PLL source when PLL is selected as system clock */
443     if((sysclk_source == RCC_CFGR_SWS_MSI) ||
444        ((sysclk_source == RCC_CFGR_SWS_PLL) && (pll_oscsource == RCC_PLLSOURCE_MSI)))
445     {
446       if((READ_BIT(RCC->CR, RCC_CR_MSIRDY) != 0U) && (RCC_OscInitStruct->MSIState == RCC_MSI_OFF))
447       {
448         return HAL_ERROR;
449       }
450 
451        /* Otherwise, just the calibration and MSI range change are allowed */
452       else
453       {
454         /* To correctly read data from FLASH memory, the number of wait states (LATENCY)
455            must be correctly programmed according to the frequency of the CPU clock
456            (HCLK) and the supply voltage of the device. */
457         if(RCC_OscInitStruct->MSIClockRange > __HAL_RCC_GET_MSI_RANGE())
458         {
459           /* First increase number of wait states update if necessary */
460           if(RCC_SetFlashLatencyFromMSIRange(RCC_OscInitStruct->MSIClockRange) != HAL_OK)
461           {
462             return HAL_ERROR;
463           }
464 
465           /* Selects the Multiple Speed oscillator (MSI) clock range .*/
466           __HAL_RCC_MSI_RANGE_CONFIG(RCC_OscInitStruct->MSIClockRange);
467           /* Adjusts the Multiple Speed oscillator (MSI) calibration value.*/
468           __HAL_RCC_MSI_CALIBRATIONVALUE_ADJUST(RCC_OscInitStruct->MSICalibrationValue);
469         }
470         else
471         {
472           /* Else, keep current flash latency while decreasing applies */
473           /* Selects the Multiple Speed oscillator (MSI) clock range .*/
474           __HAL_RCC_MSI_RANGE_CONFIG(RCC_OscInitStruct->MSIClockRange);
475           /* Adjusts the Multiple Speed oscillator (MSI) calibration value.*/
476           __HAL_RCC_MSI_CALIBRATIONVALUE_ADJUST(RCC_OscInitStruct->MSICalibrationValue);
477 
478           /* Decrease number of wait states update if necessary */
479           if(RCC_SetFlashLatencyFromMSIRange(RCC_OscInitStruct->MSIClockRange) != HAL_OK)
480           {
481             return HAL_ERROR;
482           }
483         }
484 
485         /* Update the SystemCoreClock global variable */
486         SystemCoreClock = HAL_RCC_GetSysClockFreq() >> (AHBPrescTable[READ_BIT(RCC->CFGR, RCC_CFGR_HPRE) >> RCC_CFGR_HPRE_Pos] & 0x1FU);
487 
488         /* Configure the source of time base considering new system clocks settings*/
489         status = HAL_InitTick (TICK_INT_PRIORITY);
490         if(status != HAL_OK)
491         {
492           return status;
493         }
494       }
495     }
496     else
497     {
498       /* Check the MSI State */
499       if(RCC_OscInitStruct->MSIState != RCC_MSI_OFF)
500       {
501         /* Enable the Internal High Speed oscillator (MSI). */
502         __HAL_RCC_MSI_ENABLE();
503 
504         /* Get timeout */
505         tickstart = HAL_GetTick();
506 
507         /* Wait till MSI is ready */
508         while(READ_BIT(RCC->CR, RCC_CR_MSIRDY) == 0U)
509         {
510           if((HAL_GetTick() - tickstart) > MSI_TIMEOUT_VALUE)
511           {
512             return HAL_TIMEOUT;
513           }
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       else
522       {
523         /* Disable the Internal High Speed oscillator (MSI). */
524         __HAL_RCC_MSI_DISABLE();
525 
526         /* Get timeout */
527         tickstart = HAL_GetTick();
528 
529         /* Wait till MSI is ready */
530         while(READ_BIT(RCC->CR, RCC_CR_MSIRDY) != 0U)
531         {
532           if((HAL_GetTick() - tickstart) > MSI_TIMEOUT_VALUE)
533           {
534             return HAL_TIMEOUT;
535           }
536         }
537       }
538     }
539   }
540   /*------------------------------- HSE Configuration ------------------------*/
541   if(((RCC_OscInitStruct->OscillatorType) & RCC_OSCILLATORTYPE_HSE) == RCC_OSCILLATORTYPE_HSE)
542   {
543     /* Check the parameters */
544     assert_param(IS_RCC_HSE(RCC_OscInitStruct->HSEState));
545 
546     /* When the HSE is used as system clock or clock source for PLL in these cases it is not allowed to be disabled */
547     if((sysclk_source == RCC_CFGR_SWS_HSE) ||
548        ((sysclk_source == RCC_CFGR_SWS_PLL) && (pll_oscsource == RCC_PLLSOURCE_HSE)))
549     {
550       if((READ_BIT(RCC->CR, RCC_CR_HSERDY) != 0U) && (RCC_OscInitStruct->HSEState == RCC_HSE_OFF))
551       {
552         return HAL_ERROR;
553       }
554     }
555     else
556     {
557       /* Set the new HSE configuration ---------------------------------------*/
558       __HAL_RCC_HSE_CONFIG(RCC_OscInitStruct->HSEState);
559 
560       /* Check the HSE State */
561       if(RCC_OscInitStruct->HSEState != RCC_HSE_OFF)
562       {
563         /* Get Start Tick*/
564         tickstart = HAL_GetTick();
565 
566         /* Wait till HSE is ready */
567         while(READ_BIT(RCC->CR, RCC_CR_HSERDY) == 0U)
568         {
569           if((HAL_GetTick() - tickstart) > HSE_TIMEOUT_VALUE)
570           {
571             return HAL_TIMEOUT;
572           }
573         }
574       }
575       else
576       {
577         /* Get Start Tick*/
578         tickstart = HAL_GetTick();
579 
580         /* Wait till HSE is disabled */
581         while(READ_BIT(RCC->CR, RCC_CR_HSERDY) != 0U)
582         {
583           if((HAL_GetTick() - tickstart) > HSE_TIMEOUT_VALUE)
584           {
585             return HAL_TIMEOUT;
586           }
587         }
588       }
589     }
590   }
591   /*----------------------------- HSI Configuration --------------------------*/
592   if(((RCC_OscInitStruct->OscillatorType) & RCC_OSCILLATORTYPE_HSI) == RCC_OSCILLATORTYPE_HSI)
593   {
594     /* Check the parameters */
595     assert_param(IS_RCC_HSI(RCC_OscInitStruct->HSIState));
596     assert_param(IS_RCC_HSI_CALIBRATION_VALUE(RCC_OscInitStruct->HSICalibrationValue));
597 
598     /* Check if HSI is used as system clock or as PLL source when PLL is selected as system clock */
599     if((sysclk_source == RCC_CFGR_SWS_HSI) ||
600        ((sysclk_source == RCC_CFGR_SWS_PLL) && (pll_oscsource == RCC_PLLSOURCE_HSI)))
601     {
602       /* When HSI is used as system clock it will not be disabled */
603       if((READ_BIT(RCC->CR, RCC_CR_HSIRDY) != 0U) && (RCC_OscInitStruct->HSIState == RCC_HSI_OFF))
604       {
605         return HAL_ERROR;
606       }
607       /* Otherwise, just the calibration is allowed */
608       else
609       {
610         /* Adjusts the Internal High Speed oscillator (HSI) calibration value.*/
611         __HAL_RCC_HSI_CALIBRATIONVALUE_ADJUST(RCC_OscInitStruct->HSICalibrationValue);
612       }
613     }
614     else
615     {
616       /* Check the HSI State */
617       if(RCC_OscInitStruct->HSIState != RCC_HSI_OFF)
618       {
619         /* Enable the Internal High Speed oscillator (HSI). */
620         __HAL_RCC_HSI_ENABLE();
621 
622         /* Get Start Tick*/
623         tickstart = HAL_GetTick();
624 
625         /* Wait till HSI is ready */
626         while(READ_BIT(RCC->CR, RCC_CR_HSIRDY) == 0U)
627         {
628           if((HAL_GetTick() - tickstart) > HSI_TIMEOUT_VALUE)
629           {
630             return HAL_TIMEOUT;
631           }
632         }
633 
634         /* Adjusts the Internal High Speed oscillator (HSI) calibration value.*/
635         __HAL_RCC_HSI_CALIBRATIONVALUE_ADJUST(RCC_OscInitStruct->HSICalibrationValue);
636       }
637       else
638       {
639         /* Disable the Internal High Speed oscillator (HSI). */
640         __HAL_RCC_HSI_DISABLE();
641 
642         /* Get Start Tick*/
643         tickstart = HAL_GetTick();
644 
645         /* Wait till HSI is disabled */
646         while(READ_BIT(RCC->CR, RCC_CR_HSIRDY) != 0U)
647         {
648           if((HAL_GetTick() - tickstart) > HSI_TIMEOUT_VALUE)
649           {
650             return HAL_TIMEOUT;
651           }
652         }
653       }
654     }
655   }
656   /*------------------------------ LSI Configuration -------------------------*/
657   if(((RCC_OscInitStruct->OscillatorType) & RCC_OSCILLATORTYPE_LSI) == RCC_OSCILLATORTYPE_LSI)
658   {
659     /* Check the parameters */
660     assert_param(IS_RCC_LSI(RCC_OscInitStruct->LSIState));
661 
662     /* Check the LSI State */
663     if(RCC_OscInitStruct->LSIState != RCC_LSI_OFF)
664     {
665 #if defined(RCC_CSR_LSIPREDIV)
666       uint32_t csr_temp = RCC->CSR;
667 
668       /* Check LSI division factor */
669       assert_param(IS_RCC_LSIDIV(RCC_OscInitStruct->LSIDiv));
670 
671       if (RCC_OscInitStruct->LSIDiv != (csr_temp & RCC_CSR_LSIPREDIV))
672       {
673         if (((csr_temp & RCC_CSR_LSIRDY) == RCC_CSR_LSIRDY) && \
674             ((csr_temp & RCC_CSR_LSION) != RCC_CSR_LSION))
675         {
676            /* If LSIRDY is set while LSION is not enabled,
677               LSIPREDIV can't be updated  */
678           return HAL_ERROR;
679         }
680 
681         /* Turn off LSI before changing RCC_CSR_LSIPREDIV */
682         if ((csr_temp & RCC_CSR_LSION) == RCC_CSR_LSION)
683         {
684           __HAL_RCC_LSI_DISABLE();
685 
686           /* Get Start Tick*/
687           tickstart = HAL_GetTick();
688 
689           /* Wait till LSI is disabled */
690           while(READ_BIT(RCC->CSR, RCC_CSR_LSIRDY) != 0U)
691           {
692             if((HAL_GetTick() - tickstart) > LSI_TIMEOUT_VALUE)
693             {
694               return HAL_TIMEOUT;
695             }
696           }
697         }
698 
699         /* Set LSI division factor */
700         MODIFY_REG(RCC->CSR, RCC_CSR_LSIPREDIV, RCC_OscInitStruct->LSIDiv);
701       }
702 #endif /* RCC_CSR_LSIPREDIV */
703 
704       /* Enable the Internal Low Speed oscillator (LSI). */
705       __HAL_RCC_LSI_ENABLE();
706 
707       /* Get Start Tick*/
708       tickstart = HAL_GetTick();
709 
710       /* Wait till LSI is ready */
711       while(READ_BIT(RCC->CSR, RCC_CSR_LSIRDY) == 0U)
712       {
713         if((HAL_GetTick() - tickstart) > LSI_TIMEOUT_VALUE)
714         {
715           return HAL_TIMEOUT;
716         }
717       }
718     }
719     else
720     {
721       /* Disable the Internal Low Speed oscillator (LSI). */
722       __HAL_RCC_LSI_DISABLE();
723 
724       /* Get Start Tick*/
725       tickstart = HAL_GetTick();
726 
727       /* Wait till LSI is disabled */
728       while(READ_BIT(RCC->CSR, RCC_CSR_LSIRDY) != 0U)
729       {
730         if((HAL_GetTick() - tickstart) > LSI_TIMEOUT_VALUE)
731         {
732           return HAL_TIMEOUT;
733         }
734       }
735     }
736   }
737   /*------------------------------ LSE Configuration -------------------------*/
738   if(((RCC_OscInitStruct->OscillatorType) & RCC_OSCILLATORTYPE_LSE) == RCC_OSCILLATORTYPE_LSE)
739   {
740     FlagStatus       pwrclkchanged = RESET;
741 
742     /* Check the parameters */
743     assert_param(IS_RCC_LSE(RCC_OscInitStruct->LSEState));
744 
745     /* Update LSE configuration in Backup Domain control register    */
746     /* Requires to enable write access to Backup Domain of necessary */
747     if(HAL_IS_BIT_CLR(RCC->APB1ENR1, RCC_APB1ENR1_PWREN))
748     {
749       __HAL_RCC_PWR_CLK_ENABLE();
750       pwrclkchanged = SET;
751     }
752 
753     if(HAL_IS_BIT_CLR(PWR->CR1, PWR_CR1_DBP))
754     {
755       /* Enable write access to Backup domain */
756       SET_BIT(PWR->CR1, PWR_CR1_DBP);
757 
758       /* Wait for Backup domain Write protection disable */
759       tickstart = HAL_GetTick();
760 
761       while(HAL_IS_BIT_CLR(PWR->CR1, PWR_CR1_DBP))
762       {
763         if((HAL_GetTick() - tickstart) > RCC_DBP_TIMEOUT_VALUE)
764         {
765           return HAL_TIMEOUT;
766         }
767       }
768     }
769 
770     /* Set the new LSE configuration -----------------------------------------*/
771 #if defined(RCC_BDCR_LSESYSDIS)
772     if((RCC_OscInitStruct->LSEState & RCC_BDCR_LSEON) != 0U)
773     {
774       /* Set LSESYSDIS bit according to LSE propagation option (enabled or disabled) */
775       MODIFY_REG(RCC->BDCR, RCC_BDCR_LSESYSDIS, (RCC_OscInitStruct->LSEState & RCC_BDCR_LSESYSDIS));
776 
777       if((RCC_OscInitStruct->LSEState & RCC_BDCR_LSEBYP) != 0U)
778       {
779         /* LSE oscillator bypass enable */
780         SET_BIT(RCC->BDCR, RCC_BDCR_LSEBYP);
781         SET_BIT(RCC->BDCR, RCC_BDCR_LSEON);
782       }
783       else
784       {
785         /* LSE oscillator enable */
786         SET_BIT(RCC->BDCR, RCC_BDCR_LSEON);
787       }
788     }
789     else
790     {
791       CLEAR_BIT(RCC->BDCR, RCC_BDCR_LSEON);
792       CLEAR_BIT(RCC->BDCR, RCC_BDCR_LSEBYP);
793     }
794 #else
795     __HAL_RCC_LSE_CONFIG(RCC_OscInitStruct->LSEState);
796 #endif /* RCC_BDCR_LSESYSDIS */
797 
798     /* Check the LSE State */
799     if(RCC_OscInitStruct->LSEState != RCC_LSE_OFF)
800     {
801       /* Get Start Tick*/
802       tickstart = HAL_GetTick();
803 
804       /* Wait till LSE is ready */
805       while(READ_BIT(RCC->BDCR, RCC_BDCR_LSERDY) == 0U)
806       {
807         if((HAL_GetTick() - tickstart) > RCC_LSE_TIMEOUT_VALUE)
808         {
809           return HAL_TIMEOUT;
810         }
811       }
812     }
813     else
814     {
815       /* Get Start Tick*/
816       tickstart = HAL_GetTick();
817 
818       /* Wait till LSE is disabled */
819       while(READ_BIT(RCC->BDCR, RCC_BDCR_LSERDY) != 0U)
820       {
821         if((HAL_GetTick() - tickstart) > RCC_LSE_TIMEOUT_VALUE)
822         {
823           return HAL_TIMEOUT;
824         }
825       }
826 
827 #if defined(RCC_BDCR_LSESYSDIS)
828       /* By default, stop disabling LSE propagation */
829       CLEAR_BIT(RCC->BDCR, RCC_BDCR_LSESYSDIS);
830 #endif /* RCC_BDCR_LSESYSDIS */
831     }
832 
833     /* Restore clock configuration if changed */
834     if(pwrclkchanged == SET)
835     {
836       __HAL_RCC_PWR_CLK_DISABLE();
837     }
838   }
839 #if defined(RCC_HSI48_SUPPORT)
840   /*------------------------------ HSI48 Configuration -----------------------*/
841   if(((RCC_OscInitStruct->OscillatorType) & RCC_OSCILLATORTYPE_HSI48) == RCC_OSCILLATORTYPE_HSI48)
842   {
843     /* Check the parameters */
844     assert_param(IS_RCC_HSI48(RCC_OscInitStruct->HSI48State));
845 
846     /* Check the LSI State */
847     if(RCC_OscInitStruct->HSI48State != RCC_HSI48_OFF)
848     {
849       /* Enable the Internal Low Speed oscillator (HSI48). */
850       __HAL_RCC_HSI48_ENABLE();
851 
852       /* Get Start Tick*/
853       tickstart = HAL_GetTick();
854 
855       /* Wait till HSI48 is ready */
856       while(READ_BIT(RCC->CRRCR, RCC_CRRCR_HSI48RDY) == 0U)
857       {
858         if((HAL_GetTick() - tickstart) > HSI48_TIMEOUT_VALUE)
859         {
860           return HAL_TIMEOUT;
861         }
862       }
863     }
864     else
865     {
866       /* Disable the Internal Low Speed oscillator (HSI48). */
867       __HAL_RCC_HSI48_DISABLE();
868 
869       /* Get Start Tick*/
870       tickstart = HAL_GetTick();
871 
872       /* Wait till HSI48 is disabled */
873       while(READ_BIT(RCC->CRRCR, RCC_CRRCR_HSI48RDY) != 0U)
874       {
875         if((HAL_GetTick() - tickstart) > HSI48_TIMEOUT_VALUE)
876         {
877           return HAL_TIMEOUT;
878         }
879       }
880     }
881   }
882 #endif /* RCC_HSI48_SUPPORT */
883   /*-------------------------------- PLL Configuration -----------------------*/
884   /* Check the parameters */
885   assert_param(IS_RCC_PLL(RCC_OscInitStruct->PLL.PLLState));
886 
887   if(RCC_OscInitStruct->PLL.PLLState != RCC_PLL_NONE)
888   {
889     /* Check if the PLL is used as system clock or not */
890     if(sysclk_source != RCC_CFGR_SWS_PLL)
891     {
892       if(RCC_OscInitStruct->PLL.PLLState == RCC_PLL_ON)
893       {
894         /* Check the parameters */
895         assert_param(IS_RCC_PLLSOURCE(RCC_OscInitStruct->PLL.PLLSource));
896         assert_param(IS_RCC_PLLM_VALUE(RCC_OscInitStruct->PLL.PLLM));
897         assert_param(IS_RCC_PLLN_VALUE(RCC_OscInitStruct->PLL.PLLN));
898 #if defined(RCC_PLLP_SUPPORT)
899         assert_param(IS_RCC_PLLP_VALUE(RCC_OscInitStruct->PLL.PLLP));
900 #endif /* RCC_PLLP_SUPPORT */
901         assert_param(IS_RCC_PLLQ_VALUE(RCC_OscInitStruct->PLL.PLLQ));
902         assert_param(IS_RCC_PLLR_VALUE(RCC_OscInitStruct->PLL.PLLR));
903 
904         /* Disable the main PLL. */
905         __HAL_RCC_PLL_DISABLE();
906 
907         /* Get Start Tick*/
908         tickstart = HAL_GetTick();
909 
910         /* Wait till PLL is ready */
911         while(READ_BIT(RCC->CR, RCC_CR_PLLRDY) != 0U)
912         {
913           if((HAL_GetTick() - tickstart) > PLL_TIMEOUT_VALUE)
914           {
915             return HAL_TIMEOUT;
916           }
917         }
918 
919         /* Configure the main PLL clock source, multiplication and division factors. */
920         __HAL_RCC_PLL_CONFIG(RCC_OscInitStruct->PLL.PLLSource,
921                              RCC_OscInitStruct->PLL.PLLM,
922                              RCC_OscInitStruct->PLL.PLLN,
923                              RCC_OscInitStruct->PLL.PLLP,
924                              RCC_OscInitStruct->PLL.PLLQ,
925                              RCC_OscInitStruct->PLL.PLLR);
926 
927         /* Enable the main PLL. */
928         __HAL_RCC_PLL_ENABLE();
929 
930         /* Enable PLL System Clock output. */
931          __HAL_RCC_PLLCLKOUT_ENABLE(RCC_PLL_SYSCLK);
932 
933         /* Get Start Tick*/
934         tickstart = HAL_GetTick();
935 
936         /* Wait till PLL is ready */
937         while(READ_BIT(RCC->CR, RCC_CR_PLLRDY) == 0U)
938         {
939           if((HAL_GetTick() - tickstart) > PLL_TIMEOUT_VALUE)
940           {
941             return HAL_TIMEOUT;
942           }
943         }
944       }
945       else
946       {
947         /* Disable the main PLL. */
948         __HAL_RCC_PLL_DISABLE();
949 
950         /* Disable all PLL outputs to save power if no PLLs on */
951 #if defined(RCC_PLLSAI1_SUPPORT) && defined(RCC_CR_PLLSAI2RDY)
952         if(READ_BIT(RCC->CR, (RCC_CR_PLLSAI1RDY | RCC_CR_PLLSAI2RDY)) == 0U)
953         {
954           MODIFY_REG(RCC->PLLCFGR, RCC_PLLCFGR_PLLSRC, RCC_PLLSOURCE_NONE);
955         }
956 #elif defined(RCC_PLLSAI1_SUPPORT)
957         if(READ_BIT(RCC->CR, RCC_CR_PLLSAI1RDY) == 0U)
958         {
959           MODIFY_REG(RCC->PLLCFGR, RCC_PLLCFGR_PLLSRC, RCC_PLLSOURCE_NONE);
960         }
961 #else
962         MODIFY_REG(RCC->PLLCFGR, RCC_PLLCFGR_PLLSRC, RCC_PLLSOURCE_NONE);
963 #endif /* RCC_PLLSAI1_SUPPORT && RCC_CR_PLLSAI2RDY */
964 
965 #if defined(RCC_PLLSAI2_SUPPORT)
966         __HAL_RCC_PLLCLKOUT_DISABLE(RCC_PLL_SYSCLK | RCC_PLL_48M1CLK | RCC_PLL_SAI3CLK);
967 #elif defined(RCC_PLLSAI1_SUPPORT)
968         __HAL_RCC_PLLCLKOUT_DISABLE(RCC_PLL_SYSCLK | RCC_PLL_48M1CLK | RCC_PLL_SAI2CLK);
969 #else
970         __HAL_RCC_PLLCLKOUT_DISABLE(RCC_PLL_SYSCLK | RCC_PLL_48M1CLK);
971 #endif /* RCC_PLLSAI2_SUPPORT */
972 
973         /* Get Start Tick*/
974         tickstart = HAL_GetTick();
975 
976         /* Wait till PLL is disabled */
977         while(READ_BIT(RCC->CR, RCC_CR_PLLRDY) != 0U)
978         {
979           if((HAL_GetTick() - tickstart) > PLL_TIMEOUT_VALUE)
980           {
981             return HAL_TIMEOUT;
982           }
983         }
984       }
985     }
986     else
987     {
988       return HAL_ERROR;
989     }
990   }
991   return HAL_OK;
992 }
993 
994 /**
995   * @brief  Initialize the CPU, AHB and APB busses clocks according to the specified
996   *         parameters in the RCC_ClkInitStruct.
997   * @param  RCC_ClkInitStruct  pointer to an RCC_OscInitTypeDef structure that
998   *         contains the configuration information for the RCC peripheral.
999   * @param  FLatency  FLASH Latency
1000   *          This parameter can be one of the following values:
1001   *            @arg FLASH_LATENCY_0   FLASH 0 Latency cycle
1002   *            @arg FLASH_LATENCY_1   FLASH 1 Latency cycle
1003   *            @arg FLASH_LATENCY_2   FLASH 2 Latency cycles
1004   *            @arg FLASH_LATENCY_3   FLASH 3 Latency cycles
1005   *            @arg FLASH_LATENCY_4   FLASH 4 Latency cycles
1006   @if STM32L4S9xx
1007   *            @arg FLASH_LATENCY_5   FLASH 5 Latency cycles
1008   *            @arg FLASH_LATENCY_6   FLASH 6 Latency cycles
1009   *            @arg FLASH_LATENCY_7   FLASH 7 Latency cycles
1010   *            @arg FLASH_LATENCY_8   FLASH 8 Latency cycles
1011   *            @arg FLASH_LATENCY_9   FLASH 9 Latency cycles
1012   *            @arg FLASH_LATENCY_10  FLASH 10 Latency cycles
1013   *            @arg FLASH_LATENCY_11  FLASH 11 Latency cycles
1014   *            @arg FLASH_LATENCY_12  FLASH 12 Latency cycles
1015   *            @arg FLASH_LATENCY_13  FLASH 13 Latency cycles
1016   *            @arg FLASH_LATENCY_14  FLASH 14 Latency cycles
1017   *            @arg FLASH_LATENCY_15  FLASH 15 Latency cycles
1018   @endif
1019   *
1020   * @note   The SystemCoreClock CMSIS variable is used to store System Clock Frequency
1021   *         and updated by HAL_RCC_GetHCLKFreq() function called within this function
1022   *
1023   * @note   The MSI is used by default as system clock source after
1024   *         startup from Reset, wake-up from STANDBY mode. After restart from Reset,
1025   *         the MSI frequency is set to its default value 4 MHz.
1026   *
1027   * @note   The HSI can be selected as system clock source after
1028   *         from STOP modes or in case of failure of the HSE used directly or indirectly
1029   *         as system clock (if the Clock Security System CSS is enabled).
1030   *
1031   * @note   A switch from one clock source to another occurs only if the target
1032   *         clock source is ready (clock stable after startup delay or PLL locked).
1033   *         If a clock source which is not yet ready is selected, the switch will
1034   *         occur when the clock source is ready.
1035   *
1036   * @note   You can use HAL_RCC_GetClockConfig() function to know which clock is
1037   *         currently used as system clock source.
1038   *
1039   * @note   Depending on the device voltage range, the software has to set correctly
1040   *         HPRE[3:0] bits to ensure that HCLK not exceed the maximum allowed frequency
1041   *         (for more details refer to section above "Initialization/de-initialization functions")
1042   * @retval None
1043   */
HAL_RCC_ClockConfig(RCC_ClkInitTypeDef * RCC_ClkInitStruct,uint32_t FLatency)1044 HAL_StatusTypeDef HAL_RCC_ClockConfig(RCC_ClkInitTypeDef  *RCC_ClkInitStruct, uint32_t FLatency)
1045 {
1046   uint32_t tickstart;
1047 #if defined(STM32L4R5xx) || defined(STM32L4R7xx) || defined(STM32L4R9xx) || defined(STM32L4S5xx) || defined(STM32L4S7xx) || defined(STM32L4S9xx)
1048   uint32_t hpre = RCC_SYSCLK_DIV1;
1049 #endif
1050   HAL_StatusTypeDef status;
1051 
1052   /* Check Null pointer */
1053   if(RCC_ClkInitStruct == NULL)
1054   {
1055     return HAL_ERROR;
1056   }
1057 
1058   /* Check the parameters */
1059   assert_param(IS_RCC_CLOCKTYPE(RCC_ClkInitStruct->ClockType));
1060   assert_param(IS_FLASH_LATENCY(FLatency));
1061 
1062   /* To correctly read data from FLASH memory, the number of wait states (LATENCY)
1063     must be correctly programmed according to the frequency of the CPU clock
1064     (HCLK) and the supply voltage of the device. */
1065 
1066   /* Increasing the number of wait states because of higher CPU frequency */
1067   if(FLatency > __HAL_FLASH_GET_LATENCY())
1068   {
1069     /* Program the new number of wait states to the LATENCY bits in the FLASH_ACR register */
1070     __HAL_FLASH_SET_LATENCY(FLatency);
1071 
1072     /* Check that the new number of wait states is taken into account to access the Flash
1073     memory by reading the FLASH_ACR register */
1074     if(__HAL_FLASH_GET_LATENCY() != FLatency)
1075     {
1076       return HAL_ERROR;
1077     }
1078   }
1079 
1080   /*------------------------- SYSCLK Configuration ---------------------------*/
1081   if(((RCC_ClkInitStruct->ClockType) & RCC_CLOCKTYPE_SYSCLK) == RCC_CLOCKTYPE_SYSCLK)
1082   {
1083     assert_param(IS_RCC_SYSCLKSOURCE(RCC_ClkInitStruct->SYSCLKSource));
1084 
1085     /* PLL is selected as System Clock Source */
1086     if(RCC_ClkInitStruct->SYSCLKSource == RCC_SYSCLKSOURCE_PLLCLK)
1087     {
1088       /* Check the PLL ready flag */
1089       if(READ_BIT(RCC->CR, RCC_CR_PLLRDY) == 0U)
1090       {
1091         return HAL_ERROR;
1092       }
1093 #if defined(STM32L4R5xx) || defined(STM32L4R7xx) || defined(STM32L4R9xx) || defined(STM32L4S5xx) || defined(STM32L4S7xx) || defined(STM32L4S9xx)
1094       /* Undershoot management when selection PLL as SYSCLK source and frequency above 80Mhz */
1095       /* Compute target PLL output frequency */
1096       if(RCC_GetSysClockFreqFromPLLSource() > 80000000U)
1097       {
1098         if(READ_BIT(RCC->CFGR, RCC_CFGR_HPRE) == RCC_SYSCLK_DIV1)
1099         {
1100           /* Intermediate step with HCLK prescaler 2 necessary before to go over 80Mhz */
1101           MODIFY_REG(RCC->CFGR, RCC_CFGR_HPRE, RCC_SYSCLK_DIV2);
1102           hpre = RCC_SYSCLK_DIV2;
1103         }
1104         else if((((RCC_ClkInitStruct->ClockType) & RCC_CLOCKTYPE_HCLK) == RCC_CLOCKTYPE_HCLK) && (RCC_ClkInitStruct->AHBCLKDivider == RCC_SYSCLK_DIV1))
1105         {
1106           /* Intermediate step with HCLK prescaler 2 necessary before to go over 80Mhz */
1107           MODIFY_REG(RCC->CFGR, RCC_CFGR_HPRE, RCC_SYSCLK_DIV2);
1108           hpre = RCC_SYSCLK_DIV2;
1109         }
1110         else
1111         {
1112           /* nothing to do */
1113         }
1114       }
1115 #endif
1116     }
1117     else
1118     {
1119       /* HSE is selected as System Clock Source */
1120       if(RCC_ClkInitStruct->SYSCLKSource == RCC_SYSCLKSOURCE_HSE)
1121       {
1122         /* Check the HSE ready flag */
1123         if(READ_BIT(RCC->CR, RCC_CR_HSERDY) == 0U)
1124         {
1125           return HAL_ERROR;
1126         }
1127       }
1128       /* MSI is selected as System Clock Source */
1129       else if(RCC_ClkInitStruct->SYSCLKSource == RCC_SYSCLKSOURCE_MSI)
1130       {
1131         /* Check the MSI ready flag */
1132         if(READ_BIT(RCC->CR, RCC_CR_MSIRDY) == 0U)
1133         {
1134           return HAL_ERROR;
1135         }
1136       }
1137       /* HSI is selected as System Clock Source */
1138       else
1139       {
1140         /* Check the HSI ready flag */
1141         if(READ_BIT(RCC->CR, RCC_CR_HSIRDY) == 0U)
1142         {
1143           return HAL_ERROR;
1144         }
1145       }
1146 #if defined(STM32L4R5xx) || defined(STM32L4R7xx) || defined(STM32L4R9xx) || defined(STM32L4S5xx) || defined(STM32L4S7xx) || defined(STM32L4S9xx)
1147       /* Overshoot management when going down from PLL as SYSCLK source and frequency above 80Mhz */
1148       if(HAL_RCC_GetSysClockFreq() > 80000000U)
1149       {
1150         /* Intermediate step with HCLK prescaler 2 necessary before to go under 80Mhz */
1151         MODIFY_REG(RCC->CFGR, RCC_CFGR_HPRE, RCC_SYSCLK_DIV2);
1152         hpre = RCC_SYSCLK_DIV2;
1153       }
1154 #endif
1155 
1156     }
1157 
1158     MODIFY_REG(RCC->CFGR, RCC_CFGR_SW, RCC_ClkInitStruct->SYSCLKSource);
1159 
1160     /* Get Start Tick*/
1161     tickstart = HAL_GetTick();
1162 
1163     while(__HAL_RCC_GET_SYSCLK_SOURCE() != (RCC_ClkInitStruct->SYSCLKSource << RCC_CFGR_SWS_Pos))
1164     {
1165       if((HAL_GetTick() - tickstart) > CLOCKSWITCH_TIMEOUT_VALUE)
1166       {
1167         return HAL_TIMEOUT;
1168       }
1169     }
1170   }
1171 
1172   /*-------------------------- HCLK Configuration --------------------------*/
1173   if(((RCC_ClkInitStruct->ClockType) & RCC_CLOCKTYPE_HCLK) == RCC_CLOCKTYPE_HCLK)
1174   {
1175     assert_param(IS_RCC_HCLK(RCC_ClkInitStruct->AHBCLKDivider));
1176     MODIFY_REG(RCC->CFGR, RCC_CFGR_HPRE, RCC_ClkInitStruct->AHBCLKDivider);
1177   }
1178 #if defined(STM32L4R5xx) || defined(STM32L4R7xx) || defined(STM32L4R9xx) || defined(STM32L4S5xx) || defined(STM32L4S7xx) || defined(STM32L4S9xx)
1179   else
1180   {
1181     /* Is intermediate HCLK prescaler 2 applied internally, complete with HCLK prescaler 1 */
1182     if(hpre == RCC_SYSCLK_DIV2)
1183     {
1184       MODIFY_REG(RCC->CFGR, RCC_CFGR_HPRE, RCC_SYSCLK_DIV1);
1185     }
1186   }
1187 #endif
1188 
1189   /* Decreasing the number of wait states because of lower CPU frequency */
1190   if(FLatency < __HAL_FLASH_GET_LATENCY())
1191   {
1192     /* Program the new number of wait states to the LATENCY bits in the FLASH_ACR register */
1193     __HAL_FLASH_SET_LATENCY(FLatency);
1194 
1195     /* Check that the new number of wait states is taken into account to access the Flash
1196     memory by reading the FLASH_ACR register */
1197     if(__HAL_FLASH_GET_LATENCY() != FLatency)
1198     {
1199       return HAL_ERROR;
1200     }
1201   }
1202 
1203   /*-------------------------- PCLK1 Configuration ---------------------------*/
1204   if(((RCC_ClkInitStruct->ClockType) & RCC_CLOCKTYPE_PCLK1) == RCC_CLOCKTYPE_PCLK1)
1205   {
1206     assert_param(IS_RCC_PCLK(RCC_ClkInitStruct->APB1CLKDivider));
1207     MODIFY_REG(RCC->CFGR, RCC_CFGR_PPRE1, RCC_ClkInitStruct->APB1CLKDivider);
1208   }
1209 
1210   /*-------------------------- PCLK2 Configuration ---------------------------*/
1211   if(((RCC_ClkInitStruct->ClockType) & RCC_CLOCKTYPE_PCLK2) == RCC_CLOCKTYPE_PCLK2)
1212   {
1213     assert_param(IS_RCC_PCLK(RCC_ClkInitStruct->APB2CLKDivider));
1214     MODIFY_REG(RCC->CFGR, RCC_CFGR_PPRE2, ((RCC_ClkInitStruct->APB2CLKDivider) << 3U));
1215   }
1216 
1217   /* Update the SystemCoreClock global variable */
1218   SystemCoreClock = HAL_RCC_GetSysClockFreq() >> (AHBPrescTable[READ_BIT(RCC->CFGR, RCC_CFGR_HPRE) >> RCC_CFGR_HPRE_Pos] & 0x1FU);
1219 
1220   /* Configure the source of time base considering new system clocks settings*/
1221   status = HAL_InitTick (TICK_INT_PRIORITY);
1222 
1223   return status;
1224 }
1225 
1226 /**
1227   * @}
1228   */
1229 
1230 /** @defgroup RCC_Exported_Functions_Group2 Peripheral Control functions
1231  *  @brief   RCC clocks control functions
1232  *
1233 @verbatim
1234  ===============================================================================
1235                       ##### Peripheral Control functions #####
1236  ===============================================================================
1237     [..]
1238     This subsection provides a set of functions allowing to:
1239 
1240     (+) Ouput clock to MCO pin.
1241     (+) Retrieve current clock frequencies.
1242     (+) Enable the Clock Security System.
1243 
1244 @endverbatim
1245   * @{
1246   */
1247 
1248 /**
1249   * @brief  Select the clock source to output on MCO pin(PA8).
1250   * @note   PA8 should be configured in alternate function mode.
1251   * @param  RCC_MCOx  specifies the output direction for the clock source.
1252   *          For STM32L4xx family this parameter can have only one value:
1253   *            @arg @ref RCC_MCO1  Clock source to output on MCO1 pin(PA8).
1254   * @param  RCC_MCOSource  specifies the clock source to output.
1255   *          This parameter can be one of the following values:
1256   *            @arg @ref RCC_MCO1SOURCE_NOCLOCK  MCO output disabled, no clock on MCO
1257   *            @arg @ref RCC_MCO1SOURCE_SYSCLK  system  clock selected as MCO source
1258   *            @arg @ref RCC_MCO1SOURCE_MSI  MSI clock selected as MCO source
1259   *            @arg @ref RCC_MCO1SOURCE_HSI  HSI clock selected as MCO source
1260   *            @arg @ref RCC_MCO1SOURCE_HSE  HSE clock selected as MCO sourcee
1261   *            @arg @ref RCC_MCO1SOURCE_PLLCLK  main PLL clock selected as MCO source
1262   *            @arg @ref RCC_MCO1SOURCE_LSI  LSI clock selected as MCO source
1263   *            @arg @ref RCC_MCO1SOURCE_LSE  LSE clock selected as MCO source
1264   @if STM32L443xx
1265   *            @arg @ref RCC_MCO1SOURCE_HSI48  HSI48 clock selected as MCO source for devices with HSI48
1266   @endif
1267   * @param  RCC_MCODiv  specifies the MCO prescaler.
1268   *          This parameter can be one of the following values:
1269   *            @arg @ref RCC_MCODIV_1  no division applied to MCO clock
1270   *            @arg @ref RCC_MCODIV_2  division by 2 applied to MCO clock
1271   *            @arg @ref RCC_MCODIV_4  division by 4 applied to MCO clock
1272   *            @arg @ref RCC_MCODIV_8  division by 8 applied to MCO clock
1273   *            @arg @ref RCC_MCODIV_16  division by 16 applied to MCO clock
1274   * @retval None
1275   */
HAL_RCC_MCOConfig(uint32_t RCC_MCOx,uint32_t RCC_MCOSource,uint32_t RCC_MCODiv)1276 void HAL_RCC_MCOConfig( uint32_t RCC_MCOx, uint32_t RCC_MCOSource, uint32_t RCC_MCODiv)
1277 {
1278   GPIO_InitTypeDef GPIO_InitStruct;
1279 
1280   /* Check the parameters */
1281   assert_param(IS_RCC_MCO(RCC_MCOx));
1282   assert_param(IS_RCC_MCODIV(RCC_MCODiv));
1283   assert_param(IS_RCC_MCO1SOURCE(RCC_MCOSource));
1284 
1285   /* Prevent unused argument(s) compilation warning if no assert_param check */
1286   UNUSED(RCC_MCOx);
1287 
1288   /* MCO Clock Enable */
1289   __MCO1_CLK_ENABLE();
1290 
1291   /* Configue the MCO1 pin in alternate function mode */
1292   GPIO_InitStruct.Pin = MCO1_PIN;
1293   GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
1294   GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;
1295   GPIO_InitStruct.Pull = GPIO_NOPULL;
1296   GPIO_InitStruct.Alternate = GPIO_AF0_MCO;
1297   HAL_GPIO_Init(MCO1_GPIO_PORT, &GPIO_InitStruct);
1298 
1299   /* Mask MCOSEL[] and MCOPRE[] bits then set MCO1 clock source and prescaler */
1300   MODIFY_REG(RCC->CFGR, (RCC_CFGR_MCOSEL | RCC_CFGR_MCOPRE), (RCC_MCOSource | RCC_MCODiv ));
1301 }
1302 
1303 /**
1304   * @brief  Return the SYSCLK frequency.
1305   *
1306   * @note   The system frequency computed by this function is not the real
1307   *         frequency in the chip. It is calculated based on the predefined
1308   *         constant and the selected clock source:
1309   * @note     If SYSCLK source is MSI, function returns values based on MSI
1310   *             Value as defined by the MSI range.
1311   * @note     If SYSCLK source is HSI, function returns values based on HSI_VALUE(*)
1312   * @note     If SYSCLK source is HSE, function returns values based on HSE_VALUE(**)
1313   * @note     If SYSCLK source is PLL, function returns values based on HSE_VALUE(**),
1314   *           HSI_VALUE(*) or MSI Value multiplied/divided by the PLL factors.
1315   * @note     (*) HSI_VALUE is a constant defined in stm32l4xx_hal_conf.h file (default value
1316   *               16 MHz) but the real value may vary depending on the variations
1317   *               in voltage and temperature.
1318   * @note     (**) HSE_VALUE is a constant defined in stm32l4xx_hal_conf.h file (default value
1319   *                8 MHz), user has to ensure that HSE_VALUE is same as the real
1320   *                frequency of the crystal used. Otherwise, this function may
1321   *                have wrong result.
1322   *
1323   * @note   The result of this function could be not correct when using fractional
1324   *         value for HSE crystal.
1325   *
1326   * @note   This function can be used by the user application to compute the
1327   *         baudrate for the communication peripherals or configure other parameters.
1328   *
1329   * @note   Each time SYSCLK changes, this function must be called to update the
1330   *         right SYSCLK value. Otherwise, any configuration based on this function will be incorrect.
1331   *
1332   *
1333   * @retval SYSCLK frequency
1334   */
HAL_RCC_GetSysClockFreq(void)1335 uint32_t HAL_RCC_GetSysClockFreq(void)
1336 {
1337   uint32_t msirange = 0U, sysclockfreq = 0U;
1338   uint32_t pllvco, pllsource, pllr, pllm;    /* no init needed */
1339   uint32_t sysclk_source, pll_oscsource;
1340 
1341   sysclk_source = __HAL_RCC_GET_SYSCLK_SOURCE();
1342   pll_oscsource = __HAL_RCC_GET_PLL_OSCSOURCE();
1343 
1344   if((sysclk_source == RCC_CFGR_SWS_MSI) ||
1345      ((sysclk_source == RCC_CFGR_SWS_PLL) && (pll_oscsource == RCC_PLLSOURCE_MSI)))
1346   {
1347     /* MSI or PLL with MSI source used as system clock source */
1348 
1349     /* Get SYSCLK source */
1350     if(READ_BIT(RCC->CR, RCC_CR_MSIRGSEL) == 0U)
1351     { /* MSISRANGE from RCC_CSR applies */
1352       msirange = READ_BIT(RCC->CSR, RCC_CSR_MSISRANGE) >> RCC_CSR_MSISRANGE_Pos;
1353     }
1354     else
1355     { /* MSIRANGE from RCC_CR applies */
1356       msirange = READ_BIT(RCC->CR, RCC_CR_MSIRANGE) >> RCC_CR_MSIRANGE_Pos;
1357     }
1358     /*MSI frequency range in HZ*/
1359     msirange = MSIRangeTable[msirange];
1360 
1361     if(sysclk_source == RCC_CFGR_SWS_MSI)
1362     {
1363       /* MSI used as system clock source */
1364       sysclockfreq = msirange;
1365     }
1366   }
1367   else if(sysclk_source == RCC_CFGR_SWS_HSI)
1368   {
1369     /* HSI used as system clock source */
1370     sysclockfreq = HSI_VALUE;
1371   }
1372   else if(sysclk_source == RCC_CFGR_SWS_HSE)
1373   {
1374     /* HSE used as system clock source */
1375     sysclockfreq = HSE_VALUE;
1376   }
1377   else
1378   {
1379     /* unexpected case: sysclockfreq at 0 */
1380   }
1381 
1382   if(sysclk_source == RCC_CFGR_SWS_PLL)
1383   {
1384     /* PLL used as system clock  source */
1385 
1386     /* PLL_VCO = (HSE_VALUE or HSI_VALUE or MSI_VALUE/ PLLM) * PLLN
1387     SYSCLK = PLL_VCO / PLLR
1388     */
1389     pllsource = READ_BIT(RCC->PLLCFGR, RCC_PLLCFGR_PLLSRC);
1390     pllm = (READ_BIT(RCC->PLLCFGR, RCC_PLLCFGR_PLLM) >> RCC_PLLCFGR_PLLM_Pos) + 1U ;
1391 
1392     switch (pllsource)
1393     {
1394     case RCC_PLLSOURCE_HSI:  /* HSI used as PLL clock source */
1395       pllvco = (HSI_VALUE / pllm) * (READ_BIT(RCC->PLLCFGR, RCC_PLLCFGR_PLLN) >> RCC_PLLCFGR_PLLN_Pos);
1396       break;
1397 
1398     case RCC_PLLSOURCE_HSE:  /* HSE used as PLL clock source */
1399       pllvco = (HSE_VALUE / pllm) * (READ_BIT(RCC->PLLCFGR, RCC_PLLCFGR_PLLN) >> RCC_PLLCFGR_PLLN_Pos);
1400       break;
1401 
1402     case RCC_PLLSOURCE_MSI:  /* MSI used as PLL clock source */
1403     default:
1404       pllvco = (msirange / pllm) * (READ_BIT(RCC->PLLCFGR, RCC_PLLCFGR_PLLN) >> RCC_PLLCFGR_PLLN_Pos);
1405       break;
1406     }
1407     pllr = ((READ_BIT(RCC->PLLCFGR, RCC_PLLCFGR_PLLR) >> RCC_PLLCFGR_PLLR_Pos) + 1U ) * 2U;
1408     sysclockfreq = pllvco/pllr;
1409   }
1410 
1411   return sysclockfreq;
1412 }
1413 
1414 /**
1415   * @brief  Return the HCLK frequency.
1416   * @note   Each time HCLK changes, this function must be called to update the
1417   *         right HCLK value. Otherwise, any configuration based on this function will be incorrect.
1418   *
1419   * @note   The SystemCoreClock CMSIS variable is used to store System Clock Frequency.
1420   * @retval HCLK frequency in Hz
1421   */
HAL_RCC_GetHCLKFreq(void)1422 uint32_t HAL_RCC_GetHCLKFreq(void)
1423 {
1424   return SystemCoreClock;
1425 }
1426 
1427 /**
1428   * @brief  Return the PCLK1 frequency.
1429   * @note   Each time PCLK1 changes, this function must be called to update the
1430   *         right PCLK1 value. Otherwise, any configuration based on this function will be incorrect.
1431   * @retval PCLK1 frequency in Hz
1432   */
HAL_RCC_GetPCLK1Freq(void)1433 uint32_t HAL_RCC_GetPCLK1Freq(void)
1434 {
1435   /* Get HCLK source and Compute PCLK1 frequency ---------------------------*/
1436   return (HAL_RCC_GetHCLKFreq() >> (APBPrescTable[READ_BIT(RCC->CFGR, RCC_CFGR_PPRE1) >> RCC_CFGR_PPRE1_Pos] & 0x1FU));
1437 }
1438 
1439 /**
1440   * @brief  Return the PCLK2 frequency.
1441   * @note   Each time PCLK2 changes, this function must be called to update the
1442   *         right PCLK2 value. Otherwise, any configuration based on this function will be incorrect.
1443   * @retval PCLK2 frequency in Hz
1444   */
HAL_RCC_GetPCLK2Freq(void)1445 uint32_t HAL_RCC_GetPCLK2Freq(void)
1446 {
1447   /* Get HCLK source and Compute PCLK2 frequency ---------------------------*/
1448   return (HAL_RCC_GetHCLKFreq()>> (APBPrescTable[READ_BIT(RCC->CFGR, RCC_CFGR_PPRE2) >> RCC_CFGR_PPRE2_Pos] & 0x1FU));
1449 }
1450 
1451 /**
1452   * @brief  Configure the RCC_OscInitStruct according to the internal
1453   *         RCC configuration registers.
1454   * @param  RCC_OscInitStruct  pointer to an RCC_OscInitTypeDef structure that
1455   *         will be configured.
1456   * @retval None
1457   */
HAL_RCC_GetOscConfig(RCC_OscInitTypeDef * RCC_OscInitStruct)1458 void HAL_RCC_GetOscConfig(RCC_OscInitTypeDef  *RCC_OscInitStruct)
1459 {
1460   /* Check the parameters */
1461   assert_param(RCC_OscInitStruct != (void *)NULL);
1462 
1463   /* Set all possible values for the Oscillator type parameter ---------------*/
1464 #if defined(RCC_HSI48_SUPPORT)
1465   RCC_OscInitStruct->OscillatorType = RCC_OSCILLATORTYPE_HSE | RCC_OSCILLATORTYPE_HSI | RCC_OSCILLATORTYPE_MSI | \
1466                                       RCC_OSCILLATORTYPE_LSE | RCC_OSCILLATORTYPE_LSI | RCC_OSCILLATORTYPE_HSI48;
1467 #else
1468   RCC_OscInitStruct->OscillatorType = RCC_OSCILLATORTYPE_HSE | RCC_OSCILLATORTYPE_HSI | RCC_OSCILLATORTYPE_MSI | \
1469                                       RCC_OSCILLATORTYPE_LSE | RCC_OSCILLATORTYPE_LSI;
1470 #endif /* RCC_HSI48_SUPPORT */
1471 
1472   /* Get the HSE configuration -----------------------------------------------*/
1473   if(READ_BIT(RCC->CR, RCC_CR_HSEBYP) == RCC_CR_HSEBYP)
1474   {
1475     RCC_OscInitStruct->HSEState = RCC_HSE_BYPASS;
1476   }
1477   else if(READ_BIT(RCC->CR, RCC_CR_HSEON) == RCC_CR_HSEON)
1478   {
1479     RCC_OscInitStruct->HSEState = RCC_HSE_ON;
1480   }
1481   else
1482   {
1483     RCC_OscInitStruct->HSEState = RCC_HSE_OFF;
1484   }
1485 
1486    /* Get the MSI configuration -----------------------------------------------*/
1487   if(READ_BIT(RCC->CR, RCC_CR_MSION) == RCC_CR_MSION)
1488   {
1489     RCC_OscInitStruct->MSIState = RCC_MSI_ON;
1490   }
1491   else
1492   {
1493     RCC_OscInitStruct->MSIState = RCC_MSI_OFF;
1494   }
1495 
1496   RCC_OscInitStruct->MSICalibrationValue = READ_BIT(RCC->ICSCR, RCC_ICSCR_MSITRIM) >> RCC_ICSCR_MSITRIM_Pos;
1497   RCC_OscInitStruct->MSIClockRange = READ_BIT(RCC->CR, RCC_CR_MSIRANGE);
1498 
1499   /* Get the HSI configuration -----------------------------------------------*/
1500   if(READ_BIT(RCC->CR, RCC_CR_HSION) == RCC_CR_HSION)
1501   {
1502     RCC_OscInitStruct->HSIState = RCC_HSI_ON;
1503   }
1504   else
1505   {
1506     RCC_OscInitStruct->HSIState = RCC_HSI_OFF;
1507   }
1508 
1509   RCC_OscInitStruct->HSICalibrationValue = READ_BIT(RCC->ICSCR, RCC_ICSCR_HSITRIM) >> RCC_ICSCR_HSITRIM_Pos;
1510 
1511   /* Get the LSE configuration -----------------------------------------------*/
1512   if(READ_BIT(RCC->BDCR, RCC_BDCR_LSEBYP) == RCC_BDCR_LSEBYP)
1513   {
1514 #if defined(RCC_BDCR_LSESYSDIS)
1515     if((RCC->BDCR & RCC_BDCR_LSESYSDIS) == RCC_BDCR_LSESYSDIS)
1516     {
1517       RCC_OscInitStruct->LSEState = RCC_LSE_BYPASS_RTC_ONLY;
1518     }
1519     else
1520 #endif /* RCC_BDCR_LSESYSDIS */
1521     {
1522       RCC_OscInitStruct->LSEState = RCC_LSE_BYPASS;
1523     }
1524   }
1525   else if(READ_BIT(RCC->BDCR, RCC_BDCR_LSEON) == RCC_BDCR_LSEON)
1526   {
1527 #if defined(RCC_BDCR_LSESYSDIS)
1528     if((RCC->BDCR & RCC_BDCR_LSESYSDIS) == RCC_BDCR_LSESYSDIS)
1529     {
1530       RCC_OscInitStruct->LSEState = RCC_LSE_ON_RTC_ONLY;
1531     }
1532     else
1533 #endif /* RCC_BDCR_LSESYSDIS */
1534     {
1535       RCC_OscInitStruct->LSEState = RCC_LSE_ON;
1536     }
1537   }
1538   else
1539   {
1540     RCC_OscInitStruct->LSEState = RCC_LSE_OFF;
1541   }
1542 
1543   /* Get the LSI configuration -----------------------------------------------*/
1544   if(READ_BIT(RCC->CSR, RCC_CSR_LSION) == RCC_CSR_LSION)
1545   {
1546     RCC_OscInitStruct->LSIState = RCC_LSI_ON;
1547   }
1548   else
1549   {
1550     RCC_OscInitStruct->LSIState = RCC_LSI_OFF;
1551   }
1552 #if defined(RCC_CSR_LSIPREDIV)
1553 
1554   /* Get the LSI configuration -----------------------------------------------*/
1555   if((RCC->CSR & RCC_CSR_LSIPREDIV) == RCC_CSR_LSIPREDIV)
1556   {
1557     RCC_OscInitStruct->LSIDiv = RCC_LSI_DIV128;
1558   }
1559   else
1560   {
1561     RCC_OscInitStruct->LSIDiv = RCC_LSI_DIV1;
1562   }
1563 #endif /* RCC_CSR_LSIPREDIV */
1564 
1565 #if defined(RCC_HSI48_SUPPORT)
1566   /* Get the HSI48 configuration ---------------------------------------------*/
1567   if(READ_BIT(RCC->CRRCR, RCC_CRRCR_HSI48ON) == RCC_CRRCR_HSI48ON)
1568   {
1569     RCC_OscInitStruct->HSI48State = RCC_HSI48_ON;
1570   }
1571   else
1572   {
1573     RCC_OscInitStruct->HSI48State = RCC_HSI48_OFF;
1574   }
1575 #else
1576   RCC_OscInitStruct->HSI48State = RCC_HSI48_OFF;
1577 #endif /* RCC_HSI48_SUPPORT */
1578 
1579   /* Get the PLL configuration -----------------------------------------------*/
1580   if(READ_BIT(RCC->CR, RCC_CR_PLLON) == RCC_CR_PLLON)
1581   {
1582     RCC_OscInitStruct->PLL.PLLState = RCC_PLL_ON;
1583   }
1584   else
1585   {
1586     RCC_OscInitStruct->PLL.PLLState = RCC_PLL_OFF;
1587   }
1588   RCC_OscInitStruct->PLL.PLLSource = READ_BIT(RCC->PLLCFGR, RCC_PLLCFGR_PLLSRC);
1589   RCC_OscInitStruct->PLL.PLLM = (READ_BIT(RCC->PLLCFGR, RCC_PLLCFGR_PLLM) >> RCC_PLLCFGR_PLLM_Pos) + 1U;
1590   RCC_OscInitStruct->PLL.PLLN = READ_BIT(RCC->PLLCFGR, RCC_PLLCFGR_PLLN) >> RCC_PLLCFGR_PLLN_Pos;
1591   RCC_OscInitStruct->PLL.PLLQ = (((READ_BIT(RCC->PLLCFGR, RCC_PLLCFGR_PLLQ) >> RCC_PLLCFGR_PLLQ_Pos) + 1U) << 1U);
1592   RCC_OscInitStruct->PLL.PLLR = (((READ_BIT(RCC->PLLCFGR, RCC_PLLCFGR_PLLR) >> RCC_PLLCFGR_PLLR_Pos) + 1U) << 1U);
1593 #if defined(RCC_PLLP_SUPPORT)
1594 #if defined(RCC_PLLP_DIV_2_31_SUPPORT)
1595   RCC_OscInitStruct->PLL.PLLP = READ_BIT(RCC->PLLCFGR, RCC_PLLCFGR_PLLPDIV) >> RCC_PLLCFGR_PLLPDIV_Pos;
1596 #else
1597   if(READ_BIT(RCC->PLLCFGR, RCC_PLLCFGR_PLLP) != 0U)
1598   {
1599     RCC_OscInitStruct->PLL.PLLP = RCC_PLLP_DIV17;
1600   }
1601   else
1602   {
1603     RCC_OscInitStruct->PLL.PLLP = RCC_PLLP_DIV7;
1604   }
1605 #endif /* RCC_PLLP_DIV_2_31_SUPPORT */
1606 #endif /* RCC_PLLP_SUPPORT */
1607 }
1608 
1609 /**
1610   * @brief  Configure the RCC_ClkInitStruct according to the internal
1611   *         RCC configuration registers.
1612   * @param  RCC_ClkInitStruct  pointer to an RCC_ClkInitTypeDef structure that
1613   *         will be configured.
1614   * @param  pFLatency  Pointer on the Flash Latency.
1615   * @retval None
1616   */
HAL_RCC_GetClockConfig(RCC_ClkInitTypeDef * RCC_ClkInitStruct,uint32_t * pFLatency)1617 void HAL_RCC_GetClockConfig(RCC_ClkInitTypeDef  *RCC_ClkInitStruct, uint32_t *pFLatency)
1618 {
1619   /* Check the parameters */
1620   assert_param(RCC_ClkInitStruct != (void  *)NULL);
1621   assert_param(pFLatency != (void *)NULL);
1622 
1623   /* Set all possible values for the Clock type parameter --------------------*/
1624   RCC_ClkInitStruct->ClockType = RCC_CLOCKTYPE_SYSCLK | RCC_CLOCKTYPE_HCLK | RCC_CLOCKTYPE_PCLK1 | RCC_CLOCKTYPE_PCLK2;
1625 
1626   /* Get the SYSCLK configuration --------------------------------------------*/
1627   RCC_ClkInitStruct->SYSCLKSource = READ_BIT(RCC->CFGR, RCC_CFGR_SW);
1628 
1629   /* Get the HCLK configuration ----------------------------------------------*/
1630   RCC_ClkInitStruct->AHBCLKDivider = READ_BIT(RCC->CFGR, RCC_CFGR_HPRE);
1631 
1632   /* Get the APB1 configuration ----------------------------------------------*/
1633   RCC_ClkInitStruct->APB1CLKDivider = READ_BIT(RCC->CFGR, RCC_CFGR_PPRE1);
1634 
1635   /* Get the APB2 configuration ----------------------------------------------*/
1636   RCC_ClkInitStruct->APB2CLKDivider = (READ_BIT(RCC->CFGR, RCC_CFGR_PPRE2) >> 3U);
1637 
1638   /* Get the Flash Wait State (Latency) configuration ------------------------*/
1639   *pFLatency = __HAL_FLASH_GET_LATENCY();
1640 }
1641 
1642 /**
1643   * @brief  Enable the Clock Security System.
1644   * @note   If a failure is detected on the HSE oscillator clock, this oscillator
1645   *         is automatically disabled and an interrupt is generated to inform the
1646   *         software about the failure (Clock Security System Interrupt, CSSI),
1647   *         allowing the MCU to perform rescue operations. The CSSI is linked to
1648   *         the Cortex-M4 NMI (Non-Maskable Interrupt) exception vector.
1649   * @note   The Clock Security System can only be cleared by reset.
1650   * @retval None
1651   */
HAL_RCC_EnableCSS(void)1652 void HAL_RCC_EnableCSS(void)
1653 {
1654   SET_BIT(RCC->CR, RCC_CR_CSSON) ;
1655 }
1656 
1657 /**
1658   * @brief Handle the RCC Clock Security System interrupt request.
1659   * @note This API should be called under the NMI_Handler().
1660   * @retval None
1661   */
HAL_RCC_NMI_IRQHandler(void)1662 void HAL_RCC_NMI_IRQHandler(void)
1663 {
1664   /* Check RCC CSSF interrupt flag  */
1665   if(__HAL_RCC_GET_IT(RCC_IT_CSS))
1666   {
1667     /* RCC Clock Security System interrupt user callback */
1668     HAL_RCC_CSSCallback();
1669 
1670     /* Clear RCC CSS pending bit */
1671     __HAL_RCC_CLEAR_IT(RCC_IT_CSS);
1672   }
1673 }
1674 
1675 /**
1676   * @brief  RCC Clock Security System interrupt callback.
1677   * @retval none
1678   */
HAL_RCC_CSSCallback(void)1679 __weak void HAL_RCC_CSSCallback(void)
1680 {
1681   /* NOTE : This function should not be modified, when the callback is needed,
1682             the HAL_RCC_CSSCallback should be implemented in the user file
1683    */
1684 }
1685 
1686 /**
1687   * @}
1688   */
1689 
1690 /**
1691   * @}
1692   */
1693 
1694 /* Private function prototypes -----------------------------------------------*/
1695 /** @addtogroup RCC_Private_Functions
1696   * @{
1697   */
1698 /**
1699   * @brief  Update number of Flash wait states in line with MSI range and current
1700             voltage range.
1701   * @param  msirange  MSI range value from RCC_MSIRANGE_0 to RCC_MSIRANGE_11
1702   * @retval HAL status
1703   */
RCC_SetFlashLatencyFromMSIRange(uint32_t msirange)1704 static HAL_StatusTypeDef RCC_SetFlashLatencyFromMSIRange(uint32_t msirange)
1705 {
1706   uint32_t vos;
1707   uint32_t latency = FLASH_LATENCY_0;  /* default value 0WS */
1708 
1709   if(__HAL_RCC_PWR_IS_CLK_ENABLED())
1710   {
1711     vos = HAL_PWREx_GetVoltageRange();
1712   }
1713   else
1714   {
1715     __HAL_RCC_PWR_CLK_ENABLE();
1716     vos = HAL_PWREx_GetVoltageRange();
1717     __HAL_RCC_PWR_CLK_DISABLE();
1718   }
1719 
1720   if(vos == PWR_REGULATOR_VOLTAGE_SCALE1)
1721   {
1722     if(msirange > RCC_MSIRANGE_8)
1723     {
1724       /* MSI > 16Mhz */
1725       if(msirange > RCC_MSIRANGE_10)
1726       {
1727         /* MSI 48Mhz */
1728         latency = FLASH_LATENCY_2; /* 2WS */
1729       }
1730       else
1731       {
1732         /* MSI 24Mhz or 32Mhz */
1733         latency = FLASH_LATENCY_1; /* 1WS */
1734       }
1735     }
1736     /* else MSI <= 16Mhz default FLASH_LATENCY_0 0WS */
1737   }
1738   else
1739   {
1740 #if defined(STM32L4R5xx) || defined(STM32L4R7xx) || defined(STM32L4R9xx) || defined(STM32L4S5xx) || defined(STM32L4S7xx) || defined(STM32L4S9xx)
1741     if(msirange >= RCC_MSIRANGE_8)
1742     {
1743       /* MSI >= 16Mhz */
1744       latency = FLASH_LATENCY_2; /* 2WS */
1745     }
1746     else
1747     {
1748       if(msirange == RCC_MSIRANGE_7)
1749       {
1750         /* MSI 8Mhz */
1751         latency = FLASH_LATENCY_1; /* 1WS */
1752       }
1753       /* else MSI < 8Mhz default FLASH_LATENCY_0 0WS */
1754     }
1755 #else
1756     if(msirange > RCC_MSIRANGE_8)
1757     {
1758       /* MSI > 16Mhz */
1759       latency = FLASH_LATENCY_3; /* 3WS */
1760     }
1761     else
1762     {
1763       if(msirange == RCC_MSIRANGE_8)
1764       {
1765         /* MSI 16Mhz */
1766         latency = FLASH_LATENCY_2; /* 2WS */
1767       }
1768       else if(msirange == RCC_MSIRANGE_7)
1769       {
1770         /* MSI 8Mhz */
1771         latency = FLASH_LATENCY_1; /* 1WS */
1772       }
1773       /* else MSI < 8Mhz default FLASH_LATENCY_0 0WS */
1774     }
1775 #endif
1776   }
1777 
1778   __HAL_FLASH_SET_LATENCY(latency);
1779 
1780   /* Check that the new number of wait states is taken into account to access the Flash
1781      memory by reading the FLASH_ACR register */
1782   if(__HAL_FLASH_GET_LATENCY() != latency)
1783   {
1784     return HAL_ERROR;
1785   }
1786 
1787   return HAL_OK;
1788 }
1789 
1790 #if defined(STM32L4R5xx) || defined(STM32L4R7xx) || defined(STM32L4R9xx) || defined(STM32L4S5xx) || defined(STM32L4S7xx) || defined(STM32L4S9xx)
1791 /**
1792   * @brief  Compute SYSCLK frequency based on PLL SYSCLK source.
1793   * @retval SYSCLK frequency
1794   */
RCC_GetSysClockFreqFromPLLSource(void)1795 static uint32_t RCC_GetSysClockFreqFromPLLSource(void)
1796 {
1797   uint32_t msirange = 0U;
1798   uint32_t pllvco, pllsource, pllr, pllm, sysclockfreq;  /* no init needed */
1799 
1800   if(__HAL_RCC_GET_PLL_OSCSOURCE() == RCC_PLLSOURCE_MSI)
1801   {
1802     /* Get MSI range source */
1803     if(READ_BIT(RCC->CR, RCC_CR_MSIRGSEL) == 0U)
1804     { /* MSISRANGE from RCC_CSR applies */
1805       msirange = READ_BIT(RCC->CSR, RCC_CSR_MSISRANGE) >> RCC_CSR_MSISRANGE_Pos;
1806     }
1807     else
1808     { /* MSIRANGE from RCC_CR applies */
1809       msirange = READ_BIT(RCC->CR, RCC_CR_MSIRANGE) >> RCC_CR_MSIRANGE_Pos;
1810     }
1811     /*MSI frequency range in HZ*/
1812     msirange = MSIRangeTable[msirange];
1813   }
1814 
1815   /* PLL_VCO = (HSE_VALUE or HSI_VALUE or MSI_VALUE/ PLLM) * PLLN
1816      SYSCLK = PLL_VCO / PLLR
1817    */
1818   pllsource = READ_BIT(RCC->PLLCFGR, RCC_PLLCFGR_PLLSRC);
1819   pllm = (READ_BIT(RCC->PLLCFGR, RCC_PLLCFGR_PLLM) >> RCC_PLLCFGR_PLLM_Pos) + 1U ;
1820 
1821   switch (pllsource)
1822   {
1823   case RCC_PLLSOURCE_HSI:  /* HSI used as PLL clock source */
1824     pllvco = (HSI_VALUE / pllm) * (READ_BIT(RCC->PLLCFGR, RCC_PLLCFGR_PLLN) >> RCC_PLLCFGR_PLLN_Pos);
1825     break;
1826 
1827   case RCC_PLLSOURCE_HSE:  /* HSE used as PLL clock source */
1828     pllvco = (HSE_VALUE / pllm) * (READ_BIT(RCC->PLLCFGR, RCC_PLLCFGR_PLLN) >> RCC_PLLCFGR_PLLN_Pos);
1829     break;
1830 
1831   case RCC_PLLSOURCE_MSI:  /* MSI used as PLL clock source */
1832   default:
1833     pllvco = (msirange / pllm) * (READ_BIT(RCC->PLLCFGR, RCC_PLLCFGR_PLLN) >> RCC_PLLCFGR_PLLN_Pos);
1834     break;
1835   }
1836 
1837   pllr = ((READ_BIT(RCC->PLLCFGR, RCC_PLLCFGR_PLLR) >> RCC_PLLCFGR_PLLR_Pos) + 1U ) * 2U;
1838   sysclockfreq = pllvco/pllr;
1839 
1840   return sysclockfreq;
1841 }
1842 #endif /* STM32L4R5xx || STM32L4R7xx || STM32L4R9xx || STM32L4S5xx || STM32L4S7xx || STM32L4S9xx */
1843 
1844 /**
1845   * @}
1846   */
1847 
1848 #endif /* HAL_RCC_MODULE_ENABLED */
1849 /**
1850   * @}
1851   */
1852 
1853 /**
1854   * @}
1855   */
1856 
1857 /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
1858