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