xref: /btstack/port/stm32-l451-miromico-sx1280/Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_rcc.c (revision 2fd737d36a1de5d778cacc671d4b4d8c4f3fed82)
1 /**
2   ******************************************************************************
3   * @file    stm32l4xx_hal_rcc.c
4   * @author  MCD Application Team
5   * @brief   RCC HAL module driver.
6   *          This file provides firmware functions to manage the following
7   *          functionalities of the Reset and Clock Control (RCC) peripheral:
8   *           + Initialization and de-initialization functions
9   *           + Peripheral Control functions
10   *
11   @verbatim
12   ==============================================================================
13                       ##### RCC specific features #####
14   ==============================================================================
15     [..]
16       After reset the device is running from Multiple Speed Internal oscillator
17       (4 MHz) with Flash 0 wait state. Flash prefetch buffer, D-Cache
18       and I-Cache are disabled, and all peripherals are off except internal
19       SRAM, Flash and JTAG.
20 
21       (+) There is no prescaler on High speed (AHBs) and Low speed (APBs) busses:
22           all peripherals mapped on these busses are running at MSI speed.
23       (+) The clock for all peripherals is switched off, except the SRAM and FLASH.
24       (+) All GPIOs are in analog mode, except the JTAG pins which
25           are assigned to be used for debug purpose.
26 
27     [..]
28       Once the device started from reset, the user application has to:
29       (+) Configure the clock source to be used to drive the System clock
30           (if the application needs higher frequency/performance)
31       (+) Configure the System clock frequency and Flash settings
32       (+) Configure the AHB and APB busses prescalers
33       (+) Enable the clock for the peripheral(s) to be used
34       (+) Configure the clock source(s) for peripherals which clocks are not
35           derived from the System clock (SAIx, RTC, ADC, USB OTG FS/SDMMC1/RNG)
36 
37   @endverbatim
38   ******************************************************************************
39   * @attention
40   *
41   * <h2><center>&copy; Copyright (c) 2017 STMicroelectronics.
42   * All rights reserved.</center></h2>
43   *
44   * This software component is licensed by ST under BSD 3-Clause license,
45   * the "License"; You may not use this file except in compliance with the
46   * License. You may obtain a copy of the License at:
47   *                        opensource.org/licenses/BSD-3-Clause
48   *
49   ******************************************************************************
50   */
51 
52 /* Includes ------------------------------------------------------------------*/
53 #include "stm32l4xx_hal.h"
54 
55 /** @addtogroup STM32L4xx_HAL_Driver
56   * @{
57   */
58 
59 /** @defgroup RCC RCC
60   * @brief RCC HAL module driver
61   * @{
62   */
63 
64 #ifdef HAL_RCC_MODULE_ENABLED
65 
66 /* Private typedef -----------------------------------------------------------*/
67 /* Private define ------------------------------------------------------------*/
68 /** @defgroup RCC_Private_Constants RCC Private Constants
69  * @{
70  */
71 #define HSE_TIMEOUT_VALUE          HSE_STARTUP_TIMEOUT
72 #define HSI_TIMEOUT_VALUE          2U    /* 2 ms (minimum Tick + 1) */
73 #define MSI_TIMEOUT_VALUE          2U    /* 2 ms (minimum Tick + 1) */
74 #if defined(RCC_CSR_LSIPREDIV)
75 #define LSI_TIMEOUT_VALUE          17U   /* 17 ms (16 ms starting time + 1) */
76 #else
77 #define LSI_TIMEOUT_VALUE          2U    /* 2 ms (minimum Tick + 1) */
78 #endif /* RCC_CSR_LSIPREDIV */
79 #define HSI48_TIMEOUT_VALUE        2U    /* 2 ms (minimum Tick + 1) */
80 #define PLL_TIMEOUT_VALUE          2U    /* 2 ms (minimum Tick + 1) */
81 #define CLOCKSWITCH_TIMEOUT_VALUE  5000U /* 5 s    */
82 /**
83   * @}
84   */
85 
86 /* Private macro -------------------------------------------------------------*/
87 /** @defgroup RCC_Private_Macros RCC Private Macros
88   * @{
89   */
90 #define __MCO1_CLK_ENABLE()   __HAL_RCC_GPIOA_CLK_ENABLE()
91 #define MCO1_GPIO_PORT        GPIOA
92 #define MCO1_PIN              GPIO_PIN_8
93 
94 #define RCC_PLL_OSCSOURCE_CONFIG(__HAL_RCC_PLLSOURCE__) \
95             (MODIFY_REG(RCC->PLLCFGR, RCC_PLLCFGR_PLLSRC, (__HAL_RCC_PLLSOURCE__)))
96 /**
97   * @}
98   */
99 
100 /* Private variables ---------------------------------------------------------*/
101 
102 /* Private function prototypes -----------------------------------------------*/
103 /** @defgroup RCC_Private_Functions RCC Private Functions
104   * @{
105   */
106 static HAL_StatusTypeDef RCC_SetFlashLatencyFromMSIRange(uint32_t msirange);
107 #if defined(STM32L4P5xx) || defined(STM32L4Q5xx) || \
108     defined(STM32L4R5xx) || defined(STM32L4R7xx) || defined(STM32L4R9xx) || defined(STM32L4S5xx) || defined(STM32L4S7xx) || defined(STM32L4S9xx)
109 static uint32_t          RCC_GetSysClockFreqFromPLLSource(void);
110 #endif
111 /**
112   * @}
113   */
114 
115 /* Exported functions --------------------------------------------------------*/
116 
117 /** @defgroup RCC_Exported_Functions RCC Exported Functions
118   * @{
119   */
120 
121 /** @defgroup RCC_Exported_Functions_Group1 Initialization and de-initialization functions
122   *  @brief    Initialization and Configuration functions
123   *
124   @verbatim
125  ===============================================================================
126            ##### Initialization and de-initialization functions #####
127  ===============================================================================
128     [..]
129       This section provides functions allowing to configure the internal and external oscillators
130       (HSE, HSI, LSE, MSI, LSI, PLL, CSS and MCO) and the System busses clocks (SYSCLK, AHB, APB1
131        and APB2).
132 
133     [..] Internal/external clock and PLL configuration
134          (+) HSI (high-speed internal): 16 MHz factory-trimmed RC used directly or through
135              the PLL as System clock source.
136 
137          (+) MSI (Mutiple Speed Internal): Its frequency is software trimmable from 100KHZ to 48MHZ.
138              It can be used to generate the clock for the USB OTG FS (48 MHz).
139              The number of flash wait states is automatically adjusted when MSI range is updated with
140              HAL_RCC_OscConfig() and the MSI is used as System clock source.
141 
142          (+) LSI (low-speed internal): 32 KHz low consumption RC used as IWDG and/or RTC
143              clock source.
144 
145          (+) HSE (high-speed external): 4 to 48 MHz crystal oscillator used directly or
146              through the PLL as System clock source. Can be used also optionally as RTC clock source.
147 
148          (+) LSE (low-speed external): 32.768 KHz oscillator used optionally as RTC clock source.
149 
150          (+) PLL (clocked by HSI, HSE or MSI) providing up to three independent output clocks:
151            (++) The first output is used to generate the high speed system clock (up to 80MHz).
152            (++) The second output is used to generate the clock for the USB OTG FS (48 MHz),
153                 the random analog generator (<=48 MHz) and the SDMMC1 (<= 48 MHz).
154            (++) The third output is used to generate an accurate clock to achieve
155                 high-quality audio performance on SAI interface.
156 
157          (+) PLLSAI1 (clocked by HSI, HSE or MSI) providing up to three independent output clocks:
158            (++) The first output is used to generate SAR ADC1 clock.
159            (++) The second output is used to generate the clock for the USB OTG FS (48 MHz),
160                 the random analog generator (<=48 MHz) and the SDMMC1 (<= 48 MHz).
161            (++) The third output is used to generate an accurate clock to achieve
162                 high-quality audio performance on SAI interface.
163 
164          (+) PLLSAI2 (clocked by HSI, HSE or MSI) providing up to three independent output clocks:
165            (++) The first output is used to generate an accurate clock to achieve
166                 high-quality audio performance on SAI interface.
167            (++) The second output is used to generate either SAR ADC2 clock if ADC2 is present
168                 or LCD clock if LTDC is present.
169            (++) The third output is used to generate DSI clock if DSI is present.
170 
171          (+) CSS (Clock security system): once enabled, if a HSE clock failure occurs
172             (HSE used directly or through PLL as System clock source), the System clock
173              is automatically switched to HSI and an interrupt is generated if enabled.
174              The interrupt is linked to the Cortex-M4 NMI (Non-Maskable Interrupt)
175              exception vector.
176 
177          (+) MCO (microcontroller clock output): used to output MSI, LSI, HSI, LSE, HSE or
178              main PLL clock (through a configurable prescaler) on PA8 pin.
179 
180     [..] System, AHB and APB busses clocks configuration
181          (+) Several clock sources can be used to drive the System clock (SYSCLK): MSI, HSI,
182              HSE and main PLL.
183              The AHB clock (HCLK) is derived from System clock through configurable
184              prescaler and used to clock the CPU, memory and peripherals mapped
185              on AHB bus (DMA, GPIO...). APB1 (PCLK1) and APB2 (PCLK2) clocks are derived
186              from AHB clock through configurable prescalers and used to clock
187              the peripherals mapped on these busses. You can use
188              "HAL_RCC_GetSysClockFreq()" function to retrieve the frequencies of these clocks.
189 
190          -@- All the peripheral clocks are derived from the System clock (SYSCLK) except:
191 
192            (+@) SAI: the SAI clock can be derived either from a specific PLL (PLLSAI1) or (PLLSAI2) or
193                 from an external clock mapped on the SAI_CKIN pin.
194                 You have to use HAL_RCCEx_PeriphCLKConfig() function to configure this clock.
195            (+@) RTC: the RTC clock can be derived either from the LSI, LSE or HSE clock
196                 divided by 2 to 31.
197                 You have to use __HAL_RCC_RTC_ENABLE() and HAL_RCCEx_PeriphCLKConfig() function
198                 to configure this clock.
199            (+@) USB OTG FS, SDMMC1 and RNG: USB OTG FS requires a frequency equal to 48 MHz
200                 to work correctly, while the SDMMC1 and RNG peripherals require a frequency
201                 equal or lower than to 48 MHz. This clock is derived of the main PLL or PLLSAI1
202                 through PLLQ divider. You have to enable the peripheral clock and use
203                 HAL_RCCEx_PeriphCLKConfig() function to configure this clock.
204            (+@) IWDG clock which is always the LSI clock.
205 
206 
207          (+) The maximum frequency of the SYSCLK, HCLK, PCLK1 and PCLK2 is 80 MHz.
208              The clock source frequency should be adapted depending on the device voltage range
209              as listed in the Reference Manual "Clock source frequency versus voltage scaling" chapter.
210 
211   @endverbatim
212 
213            Table 1. HCLK clock frequency for other STM32L4 devices
214            +-------------------------------------------------------+
215            | Latency         |    HCLK clock frequency (MHz)       |
216            |                 |-------------------------------------|
217            |                 | voltage range 1  | voltage range 2  |
218            |                 |      1.2 V       |     1.0 V        |
219            |-----------------|------------------|------------------|
220            |0WS(1 CPU cycles)|  0 < HCLK <= 16  |  0 < HCLK <= 6   |
221            |-----------------|------------------|------------------|
222            |1WS(2 CPU cycles)| 16 < HCLK <= 32  |  6 < HCLK <= 12  |
223            |-----------------|------------------|------------------|
224            |2WS(3 CPU cycles)| 32 < HCLK <= 48  | 12 < HCLK <= 18  |
225            |-----------------|------------------|------------------|
226            |3WS(4 CPU cycles)| 48 < HCLK <= 64  | 18 < HCLK <= 26  |
227            |-----------------|------------------|------------------|
228            |4WS(5 CPU cycles)| 64 < HCLK <= 80  | 18 < HCLK <= 26  |
229            +-------------------------------------------------------+
230 
231            Table 2. HCLK clock frequency for STM32L4+ devices
232            +--------------------------------------------------------+
233            | Latency         |     HCLK clock frequency (MHz)       |
234            |                 |--------------------------------------|
235            |                 |  voltage range 1  | voltage range 2  |
236            |                 |       1.2 V       |     1.0 V        |
237            |-----------------|-------------------|------------------|
238            |0WS(1 CPU cycles)|   0 < HCLK <= 20  |  0 < HCLK <= 8   |
239            |-----------------|-------------------|------------------|
240            |1WS(2 CPU cycles)|  20 < HCLK <= 40  |  8 < HCLK <= 16  |
241            |-----------------|-------------------|------------------|
242            |2WS(3 CPU cycles)|  40 < HCLK <= 60  | 16 < HCLK <= 26  |
243            |-----------------|-------------------|------------------|
244            |3WS(4 CPU cycles)|  60 < HCLK <= 80  | 16 < HCLK <= 26  |
245            |-----------------|-------------------|------------------|
246            |4WS(5 CPU cycles)|  80 < HCLK <= 100 | 16 < HCLK <= 26  |
247            |-----------------|-------------------|------------------|
248            |5WS(6 CPU cycles)| 100 < HCLK <= 120 | 16 < HCLK <= 26  |
249            +--------------------------------------------------------+
250   * @{
251   */
252 
253 /**
254   * @brief  Reset the RCC clock configuration to the default reset state.
255   * @note   The default reset state of the clock configuration is given below:
256   *            - MSI ON and used as system clock source
257   *            - HSE, HSI, PLL, PLLSAI1 and PLLSAI2 OFF
258   *            - AHB, APB1 and APB2 prescalers set to 1.
259   *            - CSS, MCO1 OFF
260   *            - All interrupts disabled
261   *            - All interrupt and reset flags cleared
262   * @note   This function does not modify the configuration of the
263   *            - Peripheral clock sources
264   *            - LSI, LSE and RTC clocks (Backup domain)
265   * @retval HAL status
266   */
HAL_RCC_DeInit(void)267 HAL_StatusTypeDef HAL_RCC_DeInit(void)
268 {
269   uint32_t tickstart;
270 
271   /* Reset to default System clock */
272   /* Set MSION bit */
273   SET_BIT(RCC->CR, RCC_CR_MSION);
274 
275   /* Insure MSIRDY bit is set before writing default MSIRANGE value */
276   /* Get start tick */
277   tickstart = HAL_GetTick();
278 
279   /* Wait till MSI is ready */
280   while(READ_BIT(RCC->CR, RCC_CR_MSIRDY) == 0U)
281   {
282     if((HAL_GetTick() - tickstart) > MSI_TIMEOUT_VALUE)
283     {
284       return HAL_TIMEOUT;
285     }
286   }
287 
288   /* Set MSIRANGE default value */
289   MODIFY_REG(RCC->CR, RCC_CR_MSIRANGE, RCC_MSIRANGE_6);
290 
291   /* Reset CFGR register (MSI is selected as system clock source) */
292   CLEAR_REG(RCC->CFGR);
293 
294   /* Update the SystemCoreClock global variable for MSI as system clock source */
295   SystemCoreClock = MSI_VALUE;
296 
297   /* Configure the source of time base considering new system clock settings  */
298   if(HAL_InitTick(uwTickPrio) != HAL_OK)
299   {
300     return HAL_ERROR;
301   }
302 
303   /* Insure MSI selected as system clock source */
304   /* Get start tick */
305   tickstart = HAL_GetTick();
306 
307   /* Wait till system clock source is ready */
308   while(READ_BIT(RCC->CFGR, RCC_CFGR_SWS) != RCC_CFGR_SWS_MSI)
309   {
310     if((HAL_GetTick() - tickstart) > CLOCKSWITCH_TIMEOUT_VALUE)
311     {
312       return HAL_TIMEOUT;
313     }
314   }
315 
316   /* Reset HSION, HSIKERON, HSIASFS, HSEON, HSECSSON, PLLON, PLLSAIxON bits */
317 #if defined(RCC_PLLSAI2_SUPPORT)
318 
319   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);
320 
321 #elif defined(RCC_PLLSAI1_SUPPORT)
322 
323   CLEAR_BIT(RCC->CR, RCC_CR_HSEON | RCC_CR_HSION | RCC_CR_HSIKERON| RCC_CR_HSIASFS | RCC_CR_PLLON | RCC_CR_PLLSAI1ON);
324 
325 #else
326 
327   CLEAR_BIT(RCC->CR, RCC_CR_HSEON | RCC_CR_HSION | RCC_CR_HSIKERON| RCC_CR_HSIASFS | RCC_CR_PLLON);
328 
329 #endif /* RCC_PLLSAI2_SUPPORT */
330 
331   /* Insure PLLRDY, PLLSAI1RDY and PLLSAI2RDY (if present) are reset */
332   /* Get start tick */
333   tickstart = HAL_GetTick();
334 
335 #if defined(RCC_PLLSAI2_SUPPORT)
336 
337   while(READ_BIT(RCC->CR, RCC_CR_PLLRDY | RCC_CR_PLLSAI1RDY | RCC_CR_PLLSAI2RDY) != 0U)
338 
339 #elif defined(RCC_PLLSAI1_SUPPORT)
340 
341   while(READ_BIT(RCC->CR, RCC_CR_PLLRDY | RCC_CR_PLLSAI1RDY) != 0U)
342 
343 #else
344 
345   while(READ_BIT(RCC->CR, RCC_CR_PLLRDY) != 0U)
346 
347 #endif
348   {
349     if((HAL_GetTick() - tickstart) > PLL_TIMEOUT_VALUE)
350     {
351       return HAL_TIMEOUT;
352     }
353   }
354 
355   /* Reset PLLCFGR register */
356   CLEAR_REG(RCC->PLLCFGR);
357   SET_BIT(RCC->PLLCFGR, RCC_PLLCFGR_PLLN_4 );
358 
359 #if defined(RCC_PLLSAI1_SUPPORT)
360 
361   /* Reset PLLSAI1CFGR register */
362   CLEAR_REG(RCC->PLLSAI1CFGR);
363   SET_BIT(RCC->PLLSAI1CFGR,  RCC_PLLSAI1CFGR_PLLSAI1N_4 );
364 
365 #endif /* RCC_PLLSAI1_SUPPORT */
366 
367 #if defined(RCC_PLLSAI2_SUPPORT)
368 
369   /* Reset PLLSAI2CFGR register */
370   CLEAR_REG(RCC->PLLSAI2CFGR);
371   SET_BIT(RCC->PLLSAI2CFGR,  RCC_PLLSAI2CFGR_PLLSAI2N_4 );
372 
373 #endif /* RCC_PLLSAI2_SUPPORT */
374 
375   /* Reset HSEBYP bit */
376   CLEAR_BIT(RCC->CR, RCC_CR_HSEBYP);
377 
378   /* Disable all interrupts */
379   CLEAR_REG(RCC->CIER);
380 
381   /* Clear all interrupt flags */
382   WRITE_REG(RCC->CICR, 0xFFFFFFFFU);
383 
384   /* Clear all reset flags */
385   SET_BIT(RCC->CSR, RCC_CSR_RMVF);
386 
387   return HAL_OK;
388 }
389 
390 /**
391   * @brief  Initialize the RCC Oscillators according to the specified parameters in the
392   *         RCC_OscInitTypeDef.
393   * @param  RCC_OscInitStruct  pointer to an RCC_OscInitTypeDef structure that
394   *         contains the configuration information for the RCC Oscillators.
395   * @note   The PLL is not disabled when used as system clock.
396   * @note   The PLL source is not updated when used as PLLSAI(s) clock source.
397   * @note   Transitions LSE Bypass to LSE On and LSE On to LSE Bypass are not
398   *         supported by this macro. User should request a transition to LSE Off
399   *         first and then LSE On or LSE Bypass.
400   * @note   Transition HSE Bypass to HSE On and HSE On to HSE Bypass are not
401   *         supported by this macro. User should request a transition to HSE Off
402   *         first and then HSE On or HSE Bypass.
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             __HAL_RCC_PLL_CONFIG(RCC_OscInitStruct->PLL.PLLSource,
944                                  RCC_OscInitStruct->PLL.PLLM,
945                                  RCC_OscInitStruct->PLL.PLLN,
946 #if defined(RCC_PLLP_SUPPORT)
947                                  RCC_OscInitStruct->PLL.PLLP,
948 #endif
949                                  RCC_OscInitStruct->PLL.PLLQ,
950                                  RCC_OscInitStruct->PLL.PLLR);
951 
952             /* Enable the main PLL. */
953             __HAL_RCC_PLL_ENABLE();
954 
955             /* Enable PLL System Clock output. */
956             __HAL_RCC_PLLCLKOUT_ENABLE(RCC_PLL_SYSCLK);
957 
958             /* Get Start Tick*/
959             tickstart = HAL_GetTick();
960 
961             /* Wait till PLL is ready */
962             while(READ_BIT(RCC->CR, RCC_CR_PLLRDY) == 0U)
963             {
964               if((HAL_GetTick() - tickstart) > PLL_TIMEOUT_VALUE)
965               {
966                 return HAL_TIMEOUT;
967               }
968             }
969           }
970         }
971         else
972         {
973           /* PLL is already used as System core clock */
974           return HAL_ERROR;
975         }
976       }
977       else
978       {
979         /* PLL configuration is unchanged */
980         /* Re-enable PLL if it was disabled (ie. low power mode) */
981         if(READ_BIT(RCC->CR, RCC_CR_PLLRDY) == 0U)
982         {
983           /* Enable the main PLL. */
984           __HAL_RCC_PLL_ENABLE();
985 
986           /* Enable PLL System Clock output. */
987           __HAL_RCC_PLLCLKOUT_ENABLE(RCC_PLL_SYSCLK);
988 
989           /* Get Start Tick*/
990           tickstart = HAL_GetTick();
991 
992           /* Wait till PLL is ready */
993           while(READ_BIT(RCC->CR, RCC_CR_PLLRDY) == 0U)
994           {
995             if((HAL_GetTick() - tickstart) > PLL_TIMEOUT_VALUE)
996             {
997               return HAL_TIMEOUT;
998             }
999           }
1000         }
1001       }
1002     }
1003     else
1004     {
1005       /* Check that PLL is not used as system clock or not */
1006       if(sysclk_source != RCC_CFGR_SWS_PLL)
1007       {
1008         /* Disable the main PLL. */
1009         __HAL_RCC_PLL_DISABLE();
1010 
1011         /* Disable all PLL outputs to save power if no PLLs on */
1012 #if defined(RCC_PLLSAI1_SUPPORT) && defined(RCC_CR_PLLSAI2RDY)
1013         if(READ_BIT(RCC->CR, (RCC_CR_PLLSAI1RDY | RCC_CR_PLLSAI2RDY)) == 0U)
1014         {
1015           MODIFY_REG(RCC->PLLCFGR, RCC_PLLCFGR_PLLSRC, RCC_PLLSOURCE_NONE);
1016         }
1017 #elif defined(RCC_PLLSAI1_SUPPORT)
1018         if(READ_BIT(RCC->CR, RCC_CR_PLLSAI1RDY) == 0U)
1019         {
1020           MODIFY_REG(RCC->PLLCFGR, RCC_PLLCFGR_PLLSRC, RCC_PLLSOURCE_NONE);
1021         }
1022 #else
1023         MODIFY_REG(RCC->PLLCFGR, RCC_PLLCFGR_PLLSRC, RCC_PLLSOURCE_NONE);
1024 #endif /* RCC_PLLSAI1_SUPPORT && RCC_CR_PLLSAI2RDY */
1025 
1026 #if defined(RCC_PLLSAI2_SUPPORT)
1027         __HAL_RCC_PLLCLKOUT_DISABLE(RCC_PLL_SYSCLK | RCC_PLL_48M1CLK | RCC_PLL_SAI3CLK);
1028 #elif defined(RCC_PLLSAI1_SUPPORT)
1029         __HAL_RCC_PLLCLKOUT_DISABLE(RCC_PLL_SYSCLK | RCC_PLL_48M1CLK | RCC_PLL_SAI2CLK);
1030 #else
1031         __HAL_RCC_PLLCLKOUT_DISABLE(RCC_PLL_SYSCLK | RCC_PLL_48M1CLK);
1032 #endif /* RCC_PLLSAI2_SUPPORT */
1033 
1034         /* Get Start Tick*/
1035         tickstart = HAL_GetTick();
1036 
1037         /* Wait till PLL is disabled */
1038         while(READ_BIT(RCC->CR, RCC_CR_PLLRDY) != 0U)
1039         {
1040           if((HAL_GetTick() - tickstart) > PLL_TIMEOUT_VALUE)
1041           {
1042             return HAL_TIMEOUT;
1043           }
1044         }
1045       }
1046       else
1047       {
1048         /* PLL is already used as System core clock */
1049         return HAL_ERROR;
1050       }
1051     }
1052   }
1053   return HAL_OK;
1054 }
1055 
1056 /**
1057   * @brief  Initialize the CPU, AHB and APB busses clocks according to the specified
1058   *         parameters in the RCC_ClkInitStruct.
1059   * @param  RCC_ClkInitStruct  pointer to an RCC_OscInitTypeDef structure that
1060   *         contains the configuration information for the RCC peripheral.
1061   * @param  FLatency  FLASH Latency
1062   *          This parameter can be one of the following values:
1063   *            @arg FLASH_LATENCY_0   FLASH 0 Latency cycle
1064   *            @arg FLASH_LATENCY_1   FLASH 1 Latency cycle
1065   *            @arg FLASH_LATENCY_2   FLASH 2 Latency cycles
1066   *            @arg FLASH_LATENCY_3   FLASH 3 Latency cycles
1067   *            @arg FLASH_LATENCY_4   FLASH 4 Latency cycles
1068   @if STM32L4S9xx
1069   *            @arg FLASH_LATENCY_5   FLASH 5 Latency cycles
1070   *            @arg FLASH_LATENCY_6   FLASH 6 Latency cycles
1071   *            @arg FLASH_LATENCY_7   FLASH 7 Latency cycles
1072   *            @arg FLASH_LATENCY_8   FLASH 8 Latency cycles
1073   *            @arg FLASH_LATENCY_9   FLASH 9 Latency cycles
1074   *            @arg FLASH_LATENCY_10  FLASH 10 Latency cycles
1075   *            @arg FLASH_LATENCY_11  FLASH 11 Latency cycles
1076   *            @arg FLASH_LATENCY_12  FLASH 12 Latency cycles
1077   *            @arg FLASH_LATENCY_13  FLASH 13 Latency cycles
1078   *            @arg FLASH_LATENCY_14  FLASH 14 Latency cycles
1079   *            @arg FLASH_LATENCY_15  FLASH 15 Latency cycles
1080   @endif
1081   *
1082   * @note   The SystemCoreClock CMSIS variable is used to store System Clock Frequency
1083   *         and updated by HAL_RCC_GetHCLKFreq() function called within this function
1084   *
1085   * @note   The MSI is used by default as system clock source after
1086   *         startup from Reset, wake-up from STANDBY mode. After restart from Reset,
1087   *         the MSI frequency is set to its default value 4 MHz.
1088   *
1089   * @note   The HSI can be selected as system clock source after
1090   *         from STOP modes or in case of failure of the HSE used directly or indirectly
1091   *         as system clock (if the Clock Security System CSS is enabled).
1092   *
1093   * @note   A switch from one clock source to another occurs only if the target
1094   *         clock source is ready (clock stable after startup delay or PLL locked).
1095   *         If a clock source which is not yet ready is selected, the switch will
1096   *         occur when the clock source is ready.
1097   *
1098   * @note   You can use HAL_RCC_GetClockConfig() function to know which clock is
1099   *         currently used as system clock source.
1100   *
1101   * @note   Depending on the device voltage range, the software has to set correctly
1102   *         HPRE[3:0] bits to ensure that HCLK not exceed the maximum allowed frequency
1103   *         (for more details refer to section above "Initialization/de-initialization functions")
1104   * @retval None
1105   */
HAL_RCC_ClockConfig(RCC_ClkInitTypeDef * RCC_ClkInitStruct,uint32_t FLatency)1106 HAL_StatusTypeDef HAL_RCC_ClockConfig(RCC_ClkInitTypeDef  *RCC_ClkInitStruct, uint32_t FLatency)
1107 {
1108   uint32_t tickstart;
1109 #if defined(STM32L4P5xx) || defined(STM32L4Q5xx) || \
1110     defined(STM32L4R5xx) || defined(STM32L4R7xx) || defined(STM32L4R9xx) || defined(STM32L4S5xx) || defined(STM32L4S7xx) || defined(STM32L4S9xx)
1111   uint32_t hpre = RCC_SYSCLK_DIV1;
1112 #endif
1113   HAL_StatusTypeDef status;
1114 
1115   /* Check Null pointer */
1116   if(RCC_ClkInitStruct == NULL)
1117   {
1118     return HAL_ERROR;
1119   }
1120 
1121   /* Check the parameters */
1122   assert_param(IS_RCC_CLOCKTYPE(RCC_ClkInitStruct->ClockType));
1123   assert_param(IS_FLASH_LATENCY(FLatency));
1124 
1125   /* To correctly read data from FLASH memory, the number of wait states (LATENCY)
1126     must be correctly programmed according to the frequency of the CPU clock
1127     (HCLK) and the supply voltage of the device. */
1128 
1129   /* Increasing the number of wait states because of higher CPU frequency */
1130   if(FLatency > __HAL_FLASH_GET_LATENCY())
1131   {
1132     /* Program the new number of wait states to the LATENCY bits in the FLASH_ACR register */
1133     __HAL_FLASH_SET_LATENCY(FLatency);
1134 
1135     /* Check that the new number of wait states is taken into account to access the Flash
1136     memory by reading the FLASH_ACR register */
1137     if(__HAL_FLASH_GET_LATENCY() != FLatency)
1138     {
1139       return HAL_ERROR;
1140     }
1141   }
1142 
1143   /*------------------------- SYSCLK Configuration ---------------------------*/
1144   if(((RCC_ClkInitStruct->ClockType) & RCC_CLOCKTYPE_SYSCLK) == RCC_CLOCKTYPE_SYSCLK)
1145   {
1146     assert_param(IS_RCC_SYSCLKSOURCE(RCC_ClkInitStruct->SYSCLKSource));
1147 
1148     /* PLL is selected as System Clock Source */
1149     if(RCC_ClkInitStruct->SYSCLKSource == RCC_SYSCLKSOURCE_PLLCLK)
1150     {
1151       /* Check the PLL ready flag */
1152       if(READ_BIT(RCC->CR, RCC_CR_PLLRDY) == 0U)
1153       {
1154         return HAL_ERROR;
1155       }
1156 #if defined(STM32L4P5xx) || defined(STM32L4Q5xx) || \
1157     defined(STM32L4R5xx) || defined(STM32L4R7xx) || defined(STM32L4R9xx) || defined(STM32L4S5xx) || defined(STM32L4S7xx) || defined(STM32L4S9xx)
1158       /* Undershoot management when selection PLL as SYSCLK source and frequency above 80Mhz */
1159       /* Compute target PLL output frequency */
1160       if(RCC_GetSysClockFreqFromPLLSource() > 80000000U)
1161       {
1162         if(READ_BIT(RCC->CFGR, RCC_CFGR_HPRE) == RCC_SYSCLK_DIV1)
1163         {
1164           /* Intermediate step with HCLK prescaler 2 necessary before to go over 80Mhz */
1165           MODIFY_REG(RCC->CFGR, RCC_CFGR_HPRE, RCC_SYSCLK_DIV2);
1166           hpre = RCC_SYSCLK_DIV2;
1167         }
1168         else if((((RCC_ClkInitStruct->ClockType) & RCC_CLOCKTYPE_HCLK) == RCC_CLOCKTYPE_HCLK) && (RCC_ClkInitStruct->AHBCLKDivider == RCC_SYSCLK_DIV1))
1169         {
1170           /* Intermediate step with HCLK prescaler 2 necessary before to go over 80Mhz */
1171           MODIFY_REG(RCC->CFGR, RCC_CFGR_HPRE, RCC_SYSCLK_DIV2);
1172           hpre = RCC_SYSCLK_DIV2;
1173         }
1174         else
1175         {
1176           /* nothing to do */
1177         }
1178       }
1179 #endif
1180     }
1181     else
1182     {
1183       /* HSE is selected as System Clock Source */
1184       if(RCC_ClkInitStruct->SYSCLKSource == RCC_SYSCLKSOURCE_HSE)
1185       {
1186         /* Check the HSE ready flag */
1187         if(READ_BIT(RCC->CR, RCC_CR_HSERDY) == 0U)
1188         {
1189           return HAL_ERROR;
1190         }
1191       }
1192       /* MSI is selected as System Clock Source */
1193       else if(RCC_ClkInitStruct->SYSCLKSource == RCC_SYSCLKSOURCE_MSI)
1194       {
1195         /* Check the MSI ready flag */
1196         if(READ_BIT(RCC->CR, RCC_CR_MSIRDY) == 0U)
1197         {
1198           return HAL_ERROR;
1199         }
1200       }
1201       /* HSI is selected as System Clock Source */
1202       else
1203       {
1204         /* Check the HSI ready flag */
1205         if(READ_BIT(RCC->CR, RCC_CR_HSIRDY) == 0U)
1206         {
1207           return HAL_ERROR;
1208         }
1209       }
1210 #if defined(STM32L4P5xx) || defined(STM32L4Q5xx) || \
1211     defined(STM32L4R5xx) || defined(STM32L4R7xx) || defined(STM32L4R9xx) || defined(STM32L4S5xx) || defined(STM32L4S7xx) || defined(STM32L4S9xx)
1212       /* Overshoot management when going down from PLL as SYSCLK source and frequency above 80Mhz */
1213       if(HAL_RCC_GetSysClockFreq() > 80000000U)
1214       {
1215         /* Intermediate step with HCLK prescaler 2 necessary before to go under 80Mhz */
1216         MODIFY_REG(RCC->CFGR, RCC_CFGR_HPRE, RCC_SYSCLK_DIV2);
1217         hpre = RCC_SYSCLK_DIV2;
1218       }
1219 #endif
1220 
1221     }
1222 
1223     MODIFY_REG(RCC->CFGR, RCC_CFGR_SW, RCC_ClkInitStruct->SYSCLKSource);
1224 
1225     /* Get Start Tick*/
1226     tickstart = HAL_GetTick();
1227 
1228     while(__HAL_RCC_GET_SYSCLK_SOURCE() != (RCC_ClkInitStruct->SYSCLKSource << RCC_CFGR_SWS_Pos))
1229     {
1230       if((HAL_GetTick() - tickstart) > CLOCKSWITCH_TIMEOUT_VALUE)
1231       {
1232         return HAL_TIMEOUT;
1233       }
1234     }
1235   }
1236 
1237   /*-------------------------- HCLK Configuration --------------------------*/
1238   if(((RCC_ClkInitStruct->ClockType) & RCC_CLOCKTYPE_HCLK) == RCC_CLOCKTYPE_HCLK)
1239   {
1240     assert_param(IS_RCC_HCLK(RCC_ClkInitStruct->AHBCLKDivider));
1241     MODIFY_REG(RCC->CFGR, RCC_CFGR_HPRE, RCC_ClkInitStruct->AHBCLKDivider);
1242   }
1243 #if defined(STM32L4P5xx) || defined(STM32L4Q5xx) || \
1244     defined(STM32L4R5xx) || defined(STM32L4R7xx) || defined(STM32L4R9xx) || defined(STM32L4S5xx) || defined(STM32L4S7xx) || defined(STM32L4S9xx)
1245   else
1246   {
1247     /* Is intermediate HCLK prescaler 2 applied internally, complete with HCLK prescaler 1 */
1248     if(hpre == RCC_SYSCLK_DIV2)
1249     {
1250       MODIFY_REG(RCC->CFGR, RCC_CFGR_HPRE, RCC_SYSCLK_DIV1);
1251     }
1252   }
1253 #endif
1254 
1255   /* Decreasing the number of wait states because of lower CPU frequency */
1256   if(FLatency < __HAL_FLASH_GET_LATENCY())
1257   {
1258     /* Program the new number of wait states to the LATENCY bits in the FLASH_ACR register */
1259     __HAL_FLASH_SET_LATENCY(FLatency);
1260 
1261     /* Check that the new number of wait states is taken into account to access the Flash
1262     memory by reading the FLASH_ACR register */
1263     if(__HAL_FLASH_GET_LATENCY() != FLatency)
1264     {
1265       return HAL_ERROR;
1266     }
1267   }
1268 
1269   /*-------------------------- PCLK1 Configuration ---------------------------*/
1270   if(((RCC_ClkInitStruct->ClockType) & RCC_CLOCKTYPE_PCLK1) == RCC_CLOCKTYPE_PCLK1)
1271   {
1272     assert_param(IS_RCC_PCLK(RCC_ClkInitStruct->APB1CLKDivider));
1273     MODIFY_REG(RCC->CFGR, RCC_CFGR_PPRE1, RCC_ClkInitStruct->APB1CLKDivider);
1274   }
1275 
1276   /*-------------------------- PCLK2 Configuration ---------------------------*/
1277   if(((RCC_ClkInitStruct->ClockType) & RCC_CLOCKTYPE_PCLK2) == RCC_CLOCKTYPE_PCLK2)
1278   {
1279     assert_param(IS_RCC_PCLK(RCC_ClkInitStruct->APB2CLKDivider));
1280     MODIFY_REG(RCC->CFGR, RCC_CFGR_PPRE2, ((RCC_ClkInitStruct->APB2CLKDivider) << 3U));
1281   }
1282 
1283   /* Update the SystemCoreClock global variable */
1284   SystemCoreClock = HAL_RCC_GetSysClockFreq() >> (AHBPrescTable[READ_BIT(RCC->CFGR, RCC_CFGR_HPRE) >> RCC_CFGR_HPRE_Pos] & 0x1FU);
1285 
1286   /* Configure the source of time base considering new system clocks settings*/
1287   status = HAL_InitTick(uwTickPrio);
1288 
1289   return status;
1290 }
1291 
1292 /**
1293   * @}
1294   */
1295 
1296 /** @defgroup RCC_Exported_Functions_Group2 Peripheral Control functions
1297  *  @brief   RCC clocks control functions
1298  *
1299 @verbatim
1300  ===============================================================================
1301                       ##### Peripheral Control functions #####
1302  ===============================================================================
1303     [..]
1304     This subsection provides a set of functions allowing to:
1305 
1306     (+) Ouput clock to MCO pin.
1307     (+) Retrieve current clock frequencies.
1308     (+) Enable the Clock Security System.
1309 
1310 @endverbatim
1311   * @{
1312   */
1313 
1314 /**
1315   * @brief  Select the clock source to output on MCO pin(PA8).
1316   * @note   PA8 should be configured in alternate function mode.
1317   * @param  RCC_MCOx  specifies the output direction for the clock source.
1318   *          For STM32L4xx family this parameter can have only one value:
1319   *            @arg @ref RCC_MCO1  Clock source to output on MCO1 pin(PA8).
1320   * @param  RCC_MCOSource  specifies the clock source to output.
1321   *          This parameter can be one of the following values:
1322   *            @arg @ref RCC_MCO1SOURCE_NOCLOCK  MCO output disabled, no clock on MCO
1323   *            @arg @ref RCC_MCO1SOURCE_SYSCLK  system  clock selected as MCO source
1324   *            @arg @ref RCC_MCO1SOURCE_MSI  MSI clock selected as MCO source
1325   *            @arg @ref RCC_MCO1SOURCE_HSI  HSI clock selected as MCO source
1326   *            @arg @ref RCC_MCO1SOURCE_HSE  HSE clock selected as MCO sourcee
1327   *            @arg @ref RCC_MCO1SOURCE_PLLCLK  main PLL clock selected as MCO source
1328   *            @arg @ref RCC_MCO1SOURCE_LSI  LSI clock selected as MCO source
1329   *            @arg @ref RCC_MCO1SOURCE_LSE  LSE clock selected as MCO source
1330   @if STM32L443xx
1331   *            @arg @ref RCC_MCO1SOURCE_HSI48  HSI48 clock selected as MCO source for devices with HSI48
1332   @endif
1333   * @param  RCC_MCODiv  specifies the MCO prescaler.
1334   *          This parameter can be one of the following values:
1335   *            @arg @ref RCC_MCODIV_1  no division applied to MCO clock
1336   *            @arg @ref RCC_MCODIV_2  division by 2 applied to MCO clock
1337   *            @arg @ref RCC_MCODIV_4  division by 4 applied to MCO clock
1338   *            @arg @ref RCC_MCODIV_8  division by 8 applied to MCO clock
1339   *            @arg @ref RCC_MCODIV_16  division by 16 applied to MCO clock
1340   * @retval None
1341   */
HAL_RCC_MCOConfig(uint32_t RCC_MCOx,uint32_t RCC_MCOSource,uint32_t RCC_MCODiv)1342 void HAL_RCC_MCOConfig( uint32_t RCC_MCOx, uint32_t RCC_MCOSource, uint32_t RCC_MCODiv)
1343 {
1344   GPIO_InitTypeDef GPIO_InitStruct;
1345 
1346   /* Check the parameters */
1347   assert_param(IS_RCC_MCO(RCC_MCOx));
1348   assert_param(IS_RCC_MCODIV(RCC_MCODiv));
1349   assert_param(IS_RCC_MCO1SOURCE(RCC_MCOSource));
1350 
1351   /* Prevent unused argument(s) compilation warning if no assert_param check */
1352   UNUSED(RCC_MCOx);
1353 
1354   /* MCO Clock Enable */
1355   __MCO1_CLK_ENABLE();
1356 
1357   /* Configue the MCO1 pin in alternate function mode */
1358   GPIO_InitStruct.Pin = MCO1_PIN;
1359   GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
1360   GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;
1361   GPIO_InitStruct.Pull = GPIO_NOPULL;
1362   GPIO_InitStruct.Alternate = GPIO_AF0_MCO;
1363   HAL_GPIO_Init(MCO1_GPIO_PORT, &GPIO_InitStruct);
1364 
1365   /* Mask MCOSEL[] and MCOPRE[] bits then set MCO1 clock source and prescaler */
1366   MODIFY_REG(RCC->CFGR, (RCC_CFGR_MCOSEL | RCC_CFGR_MCOPRE), (RCC_MCOSource | RCC_MCODiv ));
1367 }
1368 
1369 /**
1370   * @brief  Return the SYSCLK frequency.
1371   *
1372   * @note   The system frequency computed by this function is not the real
1373   *         frequency in the chip. It is calculated based on the predefined
1374   *         constant and the selected clock source:
1375   * @note     If SYSCLK source is MSI, function returns values based on MSI
1376   *             Value as defined by the MSI range.
1377   * @note     If SYSCLK source is HSI, function returns values based on HSI_VALUE(*)
1378   * @note     If SYSCLK source is HSE, function returns values based on HSE_VALUE(**)
1379   * @note     If SYSCLK source is PLL, function returns values based on HSE_VALUE(**),
1380   *           HSI_VALUE(*) or MSI Value multiplied/divided by the PLL factors.
1381   * @note     (*) HSI_VALUE is a constant defined in stm32l4xx_hal_conf.h file (default value
1382   *               16 MHz) but the real value may vary depending on the variations
1383   *               in voltage and temperature.
1384   * @note     (**) HSE_VALUE is a constant defined in stm32l4xx_hal_conf.h file (default value
1385   *                8 MHz), user has to ensure that HSE_VALUE is same as the real
1386   *                frequency of the crystal used. Otherwise, this function may
1387   *                have wrong result.
1388   *
1389   * @note   The result of this function could be not correct when using fractional
1390   *         value for HSE crystal.
1391   *
1392   * @note   This function can be used by the user application to compute the
1393   *         baudrate for the communication peripherals or configure other parameters.
1394   *
1395   * @note   Each time SYSCLK changes, this function must be called to update the
1396   *         right SYSCLK value. Otherwise, any configuration based on this function will be incorrect.
1397   *
1398   *
1399   * @retval SYSCLK frequency
1400   */
HAL_RCC_GetSysClockFreq(void)1401 uint32_t HAL_RCC_GetSysClockFreq(void)
1402 {
1403   uint32_t msirange = 0U, sysclockfreq = 0U;
1404   uint32_t pllvco, pllsource, pllr, pllm;    /* no init needed */
1405   uint32_t sysclk_source, pll_oscsource;
1406 
1407   sysclk_source = __HAL_RCC_GET_SYSCLK_SOURCE();
1408   pll_oscsource = __HAL_RCC_GET_PLL_OSCSOURCE();
1409 
1410   if((sysclk_source == RCC_CFGR_SWS_MSI) ||
1411      ((sysclk_source == RCC_CFGR_SWS_PLL) && (pll_oscsource == RCC_PLLSOURCE_MSI)))
1412   {
1413     /* MSI or PLL with MSI source used as system clock source */
1414 
1415     /* Get SYSCLK source */
1416     if(READ_BIT(RCC->CR, RCC_CR_MSIRGSEL) == 0U)
1417     { /* MSISRANGE from RCC_CSR applies */
1418       msirange = READ_BIT(RCC->CSR, RCC_CSR_MSISRANGE) >> RCC_CSR_MSISRANGE_Pos;
1419     }
1420     else
1421     { /* MSIRANGE from RCC_CR applies */
1422       msirange = READ_BIT(RCC->CR, RCC_CR_MSIRANGE) >> RCC_CR_MSIRANGE_Pos;
1423     }
1424     /*MSI frequency range in HZ*/
1425     msirange = MSIRangeTable[msirange];
1426 
1427     if(sysclk_source == RCC_CFGR_SWS_MSI)
1428     {
1429       /* MSI used as system clock source */
1430       sysclockfreq = msirange;
1431     }
1432   }
1433   else if(sysclk_source == RCC_CFGR_SWS_HSI)
1434   {
1435     /* HSI used as system clock source */
1436     sysclockfreq = HSI_VALUE;
1437   }
1438   else if(sysclk_source == RCC_CFGR_SWS_HSE)
1439   {
1440     /* HSE used as system clock source */
1441     sysclockfreq = HSE_VALUE;
1442   }
1443   else
1444   {
1445     /* unexpected case: sysclockfreq at 0 */
1446   }
1447 
1448   if(sysclk_source == RCC_CFGR_SWS_PLL)
1449   {
1450     /* PLL used as system clock  source */
1451 
1452     /* PLL_VCO = (HSE_VALUE or HSI_VALUE or MSI_VALUE) * PLLN / PLLM
1453     SYSCLK = PLL_VCO / PLLR
1454     */
1455     pllsource = READ_BIT(RCC->PLLCFGR, RCC_PLLCFGR_PLLSRC);
1456 
1457     switch (pllsource)
1458     {
1459     case RCC_PLLSOURCE_HSI:  /* HSI used as PLL clock source */
1460       pllvco = HSI_VALUE;
1461       break;
1462 
1463     case RCC_PLLSOURCE_HSE:  /* HSE used as PLL clock source */
1464       pllvco = HSE_VALUE;
1465       break;
1466 
1467     case RCC_PLLSOURCE_MSI:  /* MSI used as PLL clock source */
1468     default:
1469       pllvco = msirange;
1470       break;
1471     }
1472     pllm = (READ_BIT(RCC->PLLCFGR, RCC_PLLCFGR_PLLM) >> RCC_PLLCFGR_PLLM_Pos) + 1U ;
1473     pllvco = (pllvco * (READ_BIT(RCC->PLLCFGR, RCC_PLLCFGR_PLLN) >> RCC_PLLCFGR_PLLN_Pos)) / pllm;
1474     pllr = ((READ_BIT(RCC->PLLCFGR, RCC_PLLCFGR_PLLR) >> RCC_PLLCFGR_PLLR_Pos) + 1U ) * 2U;
1475     sysclockfreq = pllvco / pllr;
1476   }
1477 
1478   return sysclockfreq;
1479 }
1480 
1481 /**
1482   * @brief  Return the HCLK frequency.
1483   * @note   Each time HCLK changes, this function must be called to update the
1484   *         right HCLK value. Otherwise, any configuration based on this function will be incorrect.
1485   *
1486   * @note   The SystemCoreClock CMSIS variable is used to store System Clock Frequency.
1487   * @retval HCLK frequency in Hz
1488   */
HAL_RCC_GetHCLKFreq(void)1489 uint32_t HAL_RCC_GetHCLKFreq(void)
1490 {
1491   return SystemCoreClock;
1492 }
1493 
1494 /**
1495   * @brief  Return the PCLK1 frequency.
1496   * @note   Each time PCLK1 changes, this function must be called to update the
1497   *         right PCLK1 value. Otherwise, any configuration based on this function will be incorrect.
1498   * @retval PCLK1 frequency in Hz
1499   */
HAL_RCC_GetPCLK1Freq(void)1500 uint32_t HAL_RCC_GetPCLK1Freq(void)
1501 {
1502   /* Get HCLK source and Compute PCLK1 frequency ---------------------------*/
1503   return (HAL_RCC_GetHCLKFreq() >> (APBPrescTable[READ_BIT(RCC->CFGR, RCC_CFGR_PPRE1) >> RCC_CFGR_PPRE1_Pos] & 0x1FU));
1504 }
1505 
1506 /**
1507   * @brief  Return the PCLK2 frequency.
1508   * @note   Each time PCLK2 changes, this function must be called to update the
1509   *         right PCLK2 value. Otherwise, any configuration based on this function will be incorrect.
1510   * @retval PCLK2 frequency in Hz
1511   */
HAL_RCC_GetPCLK2Freq(void)1512 uint32_t HAL_RCC_GetPCLK2Freq(void)
1513 {
1514   /* Get HCLK source and Compute PCLK2 frequency ---------------------------*/
1515   return (HAL_RCC_GetHCLKFreq()>> (APBPrescTable[READ_BIT(RCC->CFGR, RCC_CFGR_PPRE2) >> RCC_CFGR_PPRE2_Pos] & 0x1FU));
1516 }
1517 
1518 /**
1519   * @brief  Configure the RCC_OscInitStruct according to the internal
1520   *         RCC configuration registers.
1521   * @param  RCC_OscInitStruct  pointer to an RCC_OscInitTypeDef structure that
1522   *         will be configured.
1523   * @retval None
1524   */
HAL_RCC_GetOscConfig(RCC_OscInitTypeDef * RCC_OscInitStruct)1525 void HAL_RCC_GetOscConfig(RCC_OscInitTypeDef  *RCC_OscInitStruct)
1526 {
1527   /* Check the parameters */
1528   assert_param(RCC_OscInitStruct != (void *)NULL);
1529 
1530   /* Set all possible values for the Oscillator type parameter ---------------*/
1531 #if defined(RCC_HSI48_SUPPORT)
1532   RCC_OscInitStruct->OscillatorType = RCC_OSCILLATORTYPE_HSE | RCC_OSCILLATORTYPE_HSI | RCC_OSCILLATORTYPE_MSI | \
1533                                       RCC_OSCILLATORTYPE_LSE | RCC_OSCILLATORTYPE_LSI | RCC_OSCILLATORTYPE_HSI48;
1534 #else
1535   RCC_OscInitStruct->OscillatorType = RCC_OSCILLATORTYPE_HSE | RCC_OSCILLATORTYPE_HSI | RCC_OSCILLATORTYPE_MSI | \
1536                                       RCC_OSCILLATORTYPE_LSE | RCC_OSCILLATORTYPE_LSI;
1537 #endif /* RCC_HSI48_SUPPORT */
1538 
1539   /* Get the HSE configuration -----------------------------------------------*/
1540   if(READ_BIT(RCC->CR, RCC_CR_HSEBYP) == RCC_CR_HSEBYP)
1541   {
1542     RCC_OscInitStruct->HSEState = RCC_HSE_BYPASS;
1543   }
1544   else if(READ_BIT(RCC->CR, RCC_CR_HSEON) == RCC_CR_HSEON)
1545   {
1546     RCC_OscInitStruct->HSEState = RCC_HSE_ON;
1547   }
1548   else
1549   {
1550     RCC_OscInitStruct->HSEState = RCC_HSE_OFF;
1551   }
1552 
1553    /* Get the MSI configuration -----------------------------------------------*/
1554   if(READ_BIT(RCC->CR, RCC_CR_MSION) == RCC_CR_MSION)
1555   {
1556     RCC_OscInitStruct->MSIState = RCC_MSI_ON;
1557   }
1558   else
1559   {
1560     RCC_OscInitStruct->MSIState = RCC_MSI_OFF;
1561   }
1562 
1563   RCC_OscInitStruct->MSICalibrationValue = READ_BIT(RCC->ICSCR, RCC_ICSCR_MSITRIM) >> RCC_ICSCR_MSITRIM_Pos;
1564   RCC_OscInitStruct->MSIClockRange = READ_BIT(RCC->CR, RCC_CR_MSIRANGE);
1565 
1566   /* Get the HSI configuration -----------------------------------------------*/
1567   if(READ_BIT(RCC->CR, RCC_CR_HSION) == RCC_CR_HSION)
1568   {
1569     RCC_OscInitStruct->HSIState = RCC_HSI_ON;
1570   }
1571   else
1572   {
1573     RCC_OscInitStruct->HSIState = RCC_HSI_OFF;
1574   }
1575 
1576   RCC_OscInitStruct->HSICalibrationValue = READ_BIT(RCC->ICSCR, RCC_ICSCR_HSITRIM) >> RCC_ICSCR_HSITRIM_Pos;
1577 
1578   /* Get the LSE configuration -----------------------------------------------*/
1579   if(READ_BIT(RCC->BDCR, RCC_BDCR_LSEBYP) == RCC_BDCR_LSEBYP)
1580   {
1581 #if defined(RCC_BDCR_LSESYSDIS)
1582     if((RCC->BDCR & RCC_BDCR_LSESYSDIS) == RCC_BDCR_LSESYSDIS)
1583     {
1584       RCC_OscInitStruct->LSEState = RCC_LSE_BYPASS_RTC_ONLY;
1585     }
1586     else
1587 #endif /* RCC_BDCR_LSESYSDIS */
1588     {
1589       RCC_OscInitStruct->LSEState = RCC_LSE_BYPASS;
1590     }
1591   }
1592   else if(READ_BIT(RCC->BDCR, RCC_BDCR_LSEON) == RCC_BDCR_LSEON)
1593   {
1594 #if defined(RCC_BDCR_LSESYSDIS)
1595     if((RCC->BDCR & RCC_BDCR_LSESYSDIS) == RCC_BDCR_LSESYSDIS)
1596     {
1597       RCC_OscInitStruct->LSEState = RCC_LSE_ON_RTC_ONLY;
1598     }
1599     else
1600 #endif /* RCC_BDCR_LSESYSDIS */
1601     {
1602       RCC_OscInitStruct->LSEState = RCC_LSE_ON;
1603     }
1604   }
1605   else
1606   {
1607     RCC_OscInitStruct->LSEState = RCC_LSE_OFF;
1608   }
1609 
1610   /* Get the LSI configuration -----------------------------------------------*/
1611   if(READ_BIT(RCC->CSR, RCC_CSR_LSION) == RCC_CSR_LSION)
1612   {
1613     RCC_OscInitStruct->LSIState = RCC_LSI_ON;
1614   }
1615   else
1616   {
1617     RCC_OscInitStruct->LSIState = RCC_LSI_OFF;
1618   }
1619 #if defined(RCC_CSR_LSIPREDIV)
1620 
1621   /* Get the LSI configuration -----------------------------------------------*/
1622   if((RCC->CSR & RCC_CSR_LSIPREDIV) == RCC_CSR_LSIPREDIV)
1623   {
1624     RCC_OscInitStruct->LSIDiv = RCC_LSI_DIV128;
1625   }
1626   else
1627   {
1628     RCC_OscInitStruct->LSIDiv = RCC_LSI_DIV1;
1629   }
1630 #endif /* RCC_CSR_LSIPREDIV */
1631 
1632 #if defined(RCC_HSI48_SUPPORT)
1633   /* Get the HSI48 configuration ---------------------------------------------*/
1634   if(READ_BIT(RCC->CRRCR, RCC_CRRCR_HSI48ON) == RCC_CRRCR_HSI48ON)
1635   {
1636     RCC_OscInitStruct->HSI48State = RCC_HSI48_ON;
1637   }
1638   else
1639   {
1640     RCC_OscInitStruct->HSI48State = RCC_HSI48_OFF;
1641   }
1642 #else
1643   RCC_OscInitStruct->HSI48State = RCC_HSI48_OFF;
1644 #endif /* RCC_HSI48_SUPPORT */
1645 
1646   /* Get the PLL configuration -----------------------------------------------*/
1647   if(READ_BIT(RCC->CR, RCC_CR_PLLON) == RCC_CR_PLLON)
1648   {
1649     RCC_OscInitStruct->PLL.PLLState = RCC_PLL_ON;
1650   }
1651   else
1652   {
1653     RCC_OscInitStruct->PLL.PLLState = RCC_PLL_OFF;
1654   }
1655   RCC_OscInitStruct->PLL.PLLSource = READ_BIT(RCC->PLLCFGR, RCC_PLLCFGR_PLLSRC);
1656   RCC_OscInitStruct->PLL.PLLM = (READ_BIT(RCC->PLLCFGR, RCC_PLLCFGR_PLLM) >> RCC_PLLCFGR_PLLM_Pos) + 1U;
1657   RCC_OscInitStruct->PLL.PLLN = READ_BIT(RCC->PLLCFGR, RCC_PLLCFGR_PLLN) >> RCC_PLLCFGR_PLLN_Pos;
1658   RCC_OscInitStruct->PLL.PLLQ = (((READ_BIT(RCC->PLLCFGR, RCC_PLLCFGR_PLLQ) >> RCC_PLLCFGR_PLLQ_Pos) + 1U) << 1U);
1659   RCC_OscInitStruct->PLL.PLLR = (((READ_BIT(RCC->PLLCFGR, RCC_PLLCFGR_PLLR) >> RCC_PLLCFGR_PLLR_Pos) + 1U) << 1U);
1660 #if defined(RCC_PLLP_SUPPORT)
1661 #if defined(RCC_PLLP_DIV_2_31_SUPPORT)
1662   RCC_OscInitStruct->PLL.PLLP = READ_BIT(RCC->PLLCFGR, RCC_PLLCFGR_PLLPDIV) >> RCC_PLLCFGR_PLLPDIV_Pos;
1663 #else
1664   if(READ_BIT(RCC->PLLCFGR, RCC_PLLCFGR_PLLP) != 0U)
1665   {
1666     RCC_OscInitStruct->PLL.PLLP = RCC_PLLP_DIV17;
1667   }
1668   else
1669   {
1670     RCC_OscInitStruct->PLL.PLLP = RCC_PLLP_DIV7;
1671   }
1672 #endif /* RCC_PLLP_DIV_2_31_SUPPORT */
1673 #endif /* RCC_PLLP_SUPPORT */
1674 }
1675 
1676 /**
1677   * @brief  Configure the RCC_ClkInitStruct according to the internal
1678   *         RCC configuration registers.
1679   * @param  RCC_ClkInitStruct  pointer to an RCC_ClkInitTypeDef structure that
1680   *         will be configured.
1681   * @param  pFLatency  Pointer on the Flash Latency.
1682   * @retval None
1683   */
HAL_RCC_GetClockConfig(RCC_ClkInitTypeDef * RCC_ClkInitStruct,uint32_t * pFLatency)1684 void HAL_RCC_GetClockConfig(RCC_ClkInitTypeDef  *RCC_ClkInitStruct, uint32_t *pFLatency)
1685 {
1686   /* Check the parameters */
1687   assert_param(RCC_ClkInitStruct != (void  *)NULL);
1688   assert_param(pFLatency != (void *)NULL);
1689 
1690   /* Set all possible values for the Clock type parameter --------------------*/
1691   RCC_ClkInitStruct->ClockType = RCC_CLOCKTYPE_SYSCLK | RCC_CLOCKTYPE_HCLK | RCC_CLOCKTYPE_PCLK1 | RCC_CLOCKTYPE_PCLK2;
1692 
1693   /* Get the SYSCLK configuration --------------------------------------------*/
1694   RCC_ClkInitStruct->SYSCLKSource = READ_BIT(RCC->CFGR, RCC_CFGR_SW);
1695 
1696   /* Get the HCLK configuration ----------------------------------------------*/
1697   RCC_ClkInitStruct->AHBCLKDivider = READ_BIT(RCC->CFGR, RCC_CFGR_HPRE);
1698 
1699   /* Get the APB1 configuration ----------------------------------------------*/
1700   RCC_ClkInitStruct->APB1CLKDivider = READ_BIT(RCC->CFGR, RCC_CFGR_PPRE1);
1701 
1702   /* Get the APB2 configuration ----------------------------------------------*/
1703   RCC_ClkInitStruct->APB2CLKDivider = (READ_BIT(RCC->CFGR, RCC_CFGR_PPRE2) >> 3U);
1704 
1705   /* Get the Flash Wait State (Latency) configuration ------------------------*/
1706   *pFLatency = __HAL_FLASH_GET_LATENCY();
1707 }
1708 
1709 /**
1710   * @brief  Enable the Clock Security System.
1711   * @note   If a failure is detected on the HSE oscillator clock, this oscillator
1712   *         is automatically disabled and an interrupt is generated to inform the
1713   *         software about the failure (Clock Security System Interrupt, CSSI),
1714   *         allowing the MCU to perform rescue operations. The CSSI is linked to
1715   *         the Cortex-M4 NMI (Non-Maskable Interrupt) exception vector.
1716   * @note   The Clock Security System can only be cleared by reset.
1717   * @retval None
1718   */
HAL_RCC_EnableCSS(void)1719 void HAL_RCC_EnableCSS(void)
1720 {
1721   SET_BIT(RCC->CR, RCC_CR_CSSON) ;
1722 }
1723 
1724 /**
1725   * @brief Handle the RCC Clock Security System interrupt request.
1726   * @note This API should be called under the NMI_Handler().
1727   * @retval None
1728   */
HAL_RCC_NMI_IRQHandler(void)1729 void HAL_RCC_NMI_IRQHandler(void)
1730 {
1731   /* Check RCC CSSF interrupt flag  */
1732   if(__HAL_RCC_GET_IT(RCC_IT_CSS))
1733   {
1734     /* RCC Clock Security System interrupt user callback */
1735     HAL_RCC_CSSCallback();
1736 
1737     /* Clear RCC CSS pending bit */
1738     __HAL_RCC_CLEAR_IT(RCC_IT_CSS);
1739   }
1740 }
1741 
1742 /**
1743   * @brief  RCC Clock Security System interrupt callback.
1744   * @retval none
1745   */
HAL_RCC_CSSCallback(void)1746 __weak void HAL_RCC_CSSCallback(void)
1747 {
1748   /* NOTE : This function should not be modified, when the callback is needed,
1749             the HAL_RCC_CSSCallback should be implemented in the user file
1750    */
1751 }
1752 
1753 /**
1754   * @}
1755   */
1756 
1757 /**
1758   * @}
1759   */
1760 
1761 /* Private function prototypes -----------------------------------------------*/
1762 /** @addtogroup RCC_Private_Functions
1763   * @{
1764   */
1765 /**
1766   * @brief  Update number of Flash wait states in line with MSI range and current
1767             voltage range.
1768   * @param  msirange  MSI range value from RCC_MSIRANGE_0 to RCC_MSIRANGE_11
1769   * @retval HAL status
1770   */
RCC_SetFlashLatencyFromMSIRange(uint32_t msirange)1771 static HAL_StatusTypeDef RCC_SetFlashLatencyFromMSIRange(uint32_t msirange)
1772 {
1773   uint32_t vos;
1774   uint32_t latency = FLASH_LATENCY_0;  /* default value 0WS */
1775 
1776   if(__HAL_RCC_PWR_IS_CLK_ENABLED())
1777   {
1778     vos = HAL_PWREx_GetVoltageRange();
1779   }
1780   else
1781   {
1782     __HAL_RCC_PWR_CLK_ENABLE();
1783     vos = HAL_PWREx_GetVoltageRange();
1784     __HAL_RCC_PWR_CLK_DISABLE();
1785   }
1786 
1787   if(vos == PWR_REGULATOR_VOLTAGE_SCALE1)
1788   {
1789     if(msirange > RCC_MSIRANGE_8)
1790     {
1791       /* MSI > 16Mhz */
1792       if(msirange > RCC_MSIRANGE_10)
1793       {
1794         /* MSI 48Mhz */
1795         latency = FLASH_LATENCY_2; /* 2WS */
1796       }
1797       else
1798       {
1799         /* MSI 24Mhz or 32Mhz */
1800         latency = FLASH_LATENCY_1; /* 1WS */
1801       }
1802     }
1803     /* else MSI <= 16Mhz default FLASH_LATENCY_0 0WS */
1804   }
1805   else
1806   {
1807 #if defined(STM32L4P5xx) || defined(STM32L4Q5xx) || \
1808     defined(STM32L4R5xx) || defined(STM32L4R7xx) || defined(STM32L4R9xx) || defined(STM32L4S5xx) || defined(STM32L4S7xx) || defined(STM32L4S9xx)
1809     if(msirange >= RCC_MSIRANGE_8)
1810     {
1811       /* MSI >= 16Mhz */
1812       latency = FLASH_LATENCY_2; /* 2WS */
1813     }
1814     else
1815     {
1816       if(msirange == RCC_MSIRANGE_7)
1817       {
1818         /* MSI 8Mhz */
1819         latency = FLASH_LATENCY_1; /* 1WS */
1820       }
1821       /* else MSI < 8Mhz default FLASH_LATENCY_0 0WS */
1822     }
1823 #else
1824     if(msirange > RCC_MSIRANGE_8)
1825     {
1826       /* MSI > 16Mhz */
1827       latency = FLASH_LATENCY_3; /* 3WS */
1828     }
1829     else
1830     {
1831       if(msirange == RCC_MSIRANGE_8)
1832       {
1833         /* MSI 16Mhz */
1834         latency = FLASH_LATENCY_2; /* 2WS */
1835       }
1836       else if(msirange == RCC_MSIRANGE_7)
1837       {
1838         /* MSI 8Mhz */
1839         latency = FLASH_LATENCY_1; /* 1WS */
1840       }
1841       /* else MSI < 8Mhz default FLASH_LATENCY_0 0WS */
1842     }
1843 #endif
1844   }
1845 
1846   __HAL_FLASH_SET_LATENCY(latency);
1847 
1848   /* Check that the new number of wait states is taken into account to access the Flash
1849      memory by reading the FLASH_ACR register */
1850   if(__HAL_FLASH_GET_LATENCY() != latency)
1851   {
1852     return HAL_ERROR;
1853   }
1854 
1855   return HAL_OK;
1856 }
1857 
1858 #if defined(STM32L4P5xx) || defined(STM32L4Q5xx) || \
1859     defined(STM32L4R5xx) || defined(STM32L4R7xx) || defined(STM32L4R9xx) || defined(STM32L4S5xx) || defined(STM32L4S7xx) || defined(STM32L4S9xx)
1860 /**
1861   * @brief  Compute SYSCLK frequency based on PLL SYSCLK source.
1862   * @retval SYSCLK frequency
1863   */
RCC_GetSysClockFreqFromPLLSource(void)1864 static uint32_t RCC_GetSysClockFreqFromPLLSource(void)
1865 {
1866   uint32_t msirange = 0U;
1867   uint32_t pllvco, pllsource, pllr, pllm, sysclockfreq;  /* no init needed */
1868 
1869   if(__HAL_RCC_GET_PLL_OSCSOURCE() == RCC_PLLSOURCE_MSI)
1870   {
1871     /* Get MSI range source */
1872     if(READ_BIT(RCC->CR, RCC_CR_MSIRGSEL) == 0U)
1873     { /* MSISRANGE from RCC_CSR applies */
1874       msirange = READ_BIT(RCC->CSR, RCC_CSR_MSISRANGE) >> RCC_CSR_MSISRANGE_Pos;
1875     }
1876     else
1877     { /* MSIRANGE from RCC_CR applies */
1878       msirange = READ_BIT(RCC->CR, RCC_CR_MSIRANGE) >> RCC_CR_MSIRANGE_Pos;
1879     }
1880     /*MSI frequency range in HZ*/
1881     msirange = MSIRangeTable[msirange];
1882   }
1883 
1884   /* PLL_VCO = (HSE_VALUE or HSI_VALUE or MSI_VALUE) * PLLN / PLLM
1885      SYSCLK = PLL_VCO / PLLR
1886    */
1887   pllsource = READ_BIT(RCC->PLLCFGR, RCC_PLLCFGR_PLLSRC);
1888 
1889   switch (pllsource)
1890   {
1891   case RCC_PLLSOURCE_HSI:  /* HSI used as PLL clock source */
1892     pllvco = HSI_VALUE;
1893     break;
1894 
1895   case RCC_PLLSOURCE_HSE:  /* HSE used as PLL clock source */
1896     pllvco = HSE_VALUE;
1897     break;
1898 
1899   case RCC_PLLSOURCE_MSI:  /* MSI used as PLL clock source */
1900   default:
1901     pllvco = msirange;
1902     break;
1903   }
1904   pllm = (READ_BIT(RCC->PLLCFGR, RCC_PLLCFGR_PLLM) >> RCC_PLLCFGR_PLLM_Pos) + 1U ;
1905   pllvco = (pllvco * (READ_BIT(RCC->PLLCFGR, RCC_PLLCFGR_PLLN) >> RCC_PLLCFGR_PLLN_Pos)) / pllm;
1906   pllr = ((READ_BIT(RCC->PLLCFGR, RCC_PLLCFGR_PLLR) >> RCC_PLLCFGR_PLLR_Pos) + 1U ) * 2U;
1907   sysclockfreq = pllvco / pllr;
1908 
1909   return sysclockfreq;
1910 }
1911 #endif
1912 
1913 /**
1914   * @}
1915   */
1916 
1917 #endif /* HAL_RCC_MODULE_ENABLED */
1918 /**
1919   * @}
1920   */
1921 
1922 /**
1923   * @}
1924   */
1925 
1926 /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
1927