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