1 /**
2   ******************************************************************************
3   * @file    stm32u5xx_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   ******************************************************************************
12   * @attention
13   *
14   * Copyright (c) 2021 STMicroelectronics.
15   * All rights reserved.
16   *
17   * This software is licensed under terms that can be found in the LICENSE file
18   * in the root directory of this software component.
19   * If no LICENSE file comes with this software, it is provided AS-IS.
20   *
21   ******************************************************************************
22   @verbatim
23   ==============================================================================
24                       ##### RCC specific features #####
25   ==============================================================================
26     [..]
27       After reset the device is running from Multiple Speed Internal oscillator
28       (4 MHz) with Flash 0 wait state. Flash prefetch buffer, D-Cache
29       and I-Cache are disabled, and all peripherals are off except internal
30       SRAM, Flash and JTAG.
31 
32       (+) There is no prescaler on High speed (AHBs) and Low speed (APBs) busses:
33           all peripherals mapped on these busses are running at MSI speed.
34       (+) The clock for all peripherals is switched off, except the SRAM and FLASH.
35       (+) All GPIOs are in analog mode, except the JTAG pins which
36           are assigned to be used for debug purpose.
37 
38     [..]
39       Once the device started from reset, the user application has to:
40       (+) Configure the clock source to be used to drive the System clock
41           (if the application needs higher frequency/performance)
42       (+) Configure the System clock frequency and Flash settings
43       (+) Configure the AHB and APB busses prescalers
44       (+) Enable the clock for the peripheral(s) to be used
45       (+) Configure the clock source(s) for peripherals which clocks are not
46           derived from the System clock (SAIx, SYSTICK, RTC, ADC, USB OTG FS/USB FS/SDMMC1/RNG)
47 
48   @endverbatim
49   ******************************************************************************
50   */
51 
52 /* Includes ------------------------------------------------------------------*/
53 #include "stm32u5xx_hal.h"
54 
55 /** @addtogroup STM32U5xx_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 constants ---------------------------------------------------------*/
68 /** @defgroup RCC_Private_Constants RCC Private Constants
69   * @{
70   */
71 #define PLLDIVR_RESET_VALUE      (0x01010280U)
72 #define PLL_FRAC_WAIT_VALUE       1U            /* PLL Fractional part waiting time before new latch enable : 1 ms */
73 /**
74   * @}
75   */
76 /* Private macros ------------------------------------------------------------*/
77 /** @addtogroup RCC_Private_Macros
78   * @{
79   */
80 #define IS_RCC_OSCILLATORTYPE(__OSCILLATOR__)  (((__OSCILLATOR__) == RCC_OSCILLATORTYPE_NONE) || \
81                                                 (((__OSCILLATOR__) & ~RCC_OSCILLATORTYPE_ALL) == 0x00U))
82 
83 #define IS_RCC_HSE(__HSE__)  (((__HSE__) == RCC_HSE_OFF) || ((__HSE__) == RCC_HSE_ON) || \
84                               ((__HSE__) == RCC_HSE_BYPASS) || ((__HSE__) == RCC_HSE_BYPASS_DIGITAL))
85 
86 #define IS_RCC_LSE(__LSE__)  (((__LSE__) == RCC_LSE_OFF) || ((__LSE__) == RCC_LSE_ON) || \
87                               ((__LSE__) == RCC_LSE_ON_RTC_ONLY) || ((__LSE__) == RCC_LSE_BYPASS_RTC_ONLY) || \
88                               ((__LSE__) == RCC_LSE_BYPASS))
89 
90 #define IS_RCC_HSI(__HSI__)  (((__HSI__) == RCC_HSI_OFF) || ((__HSI__) == RCC_HSI_ON))
91 
92 #define IS_RCC_HSI_CALIBRATION_VALUE(__VALUE__) ((__VALUE__) <= (uint32_t)( RCC_ICSCR3_HSITRIM  >>\
93                                                                             RCC_ICSCR3_HSITRIM_Pos))
94 
95 #define IS_RCC_LSI(__LSI__)  (((__LSI__) == RCC_LSI_OFF) || ((__LSI__) == RCC_LSI_ON))
96 
97 #define IS_RCC_LSIDIV(__LSIDIV__)  (((__LSIDIV__) == RCC_LSI_DIV1) || ((__LSIDIV__) == RCC_LSI_DIV128))
98 
99 #define IS_RCC_MSI(__MSI__)  (((__MSI__) == RCC_MSI_OFF) || ((__MSI__) == RCC_MSI_ON))
100 
101 #define IS_RCC_MSICALIBRATION_VALUE(__VALUE__) ((__VALUE__) <= 255U)
102 
103 #define IS_RCC_HSI48(__HSI48__)  (((__HSI48__) == RCC_HSI48_OFF) || ((__HSI48__) == RCC_HSI48_ON))
104 
105 #define IS_RCC_SHSI(__SHSI__)  (((__SHSI__) == RCC_SHSI_OFF) || ((__SHSI__) == RCC_SHSI_ON))
106 
107 #define IS_RCC_MSIK(__MSIK__)  (((__MSIK__) == RCC_MSIK_OFF) || ((__MSIK__) == RCC_MSIK_ON))
108 
109 #define IS_RCC_PLL(PLL) (((PLL) == RCC_PLL_NONE) ||((PLL) == RCC_PLL_OFF) || \
110                          ((PLL) == RCC_PLL_ON))
111 
112 #define IS_RCC_PLLMBOOST_VALUE(VALUE) (((VALUE) == RCC_PLLMBOOST_DIV1)   || \
113                                        ((VALUE) == RCC_PLLMBOOST_DIV2)   || \
114                                        ((VALUE) == RCC_PLLMBOOST_DIV4)   || \
115                                        ((VALUE) == RCC_PLLMBOOST_DIV6)   || \
116                                        ((VALUE) == RCC_PLLMBOOST_DIV8)   || \
117                                        ((VALUE) == RCC_PLLMBOOST_DIV10)  || \
118                                        ((VALUE) == RCC_PLLMBOOST_DIV12)  || \
119                                        ((VALUE) == RCC_PLLMBOOST_DIV14)  || \
120                                        ((VALUE) == RCC_PLLMBOOST_DIV16))
121 
122 #define IS_RCC_PLLCLOCKOUT_VALUE(VALUE) (((VALUE) == RCC_PLL1_DIVP) || \
123                                          ((VALUE) == RCC_PLL1_DIVQ) || \
124                                          ((VALUE) == RCC_PLL1_DIVR))
125 
126 #define IS_RCC_PLLRGE_VALUE(VALUE) (((VALUE) == RCC_PLLVCIRANGE_0) || \
127                                     ((VALUE) == RCC_PLLVCIRANGE_1))
128 
129 #define IS_RCC_PLL_FRACN_VALUE(VALUE) ((VALUE) <= 8191U)
130 
131 #define IS_RCC_CLOCKTYPE(CLK) ((1U <= (CLK)) && ((CLK) <= 0x1FU))
132 
133 #define IS_RCC_SYSCLKSOURCE(__SOURCE__) (((__SOURCE__) == RCC_SYSCLKSOURCE_MSI) || \
134                                          ((__SOURCE__) == RCC_SYSCLKSOURCE_HSI) || \
135                                          ((__SOURCE__) == RCC_SYSCLKSOURCE_HSE) || \
136                                          ((__SOURCE__) == RCC_SYSCLKSOURCE_PLLCLK))
137 
138 #define IS_RCC_HCLK(__HCLK__) (((__HCLK__) == RCC_SYSCLK_DIV1)   || ((__HCLK__) == RCC_SYSCLK_DIV2)   || \
139                                ((__HCLK__) == RCC_SYSCLK_DIV4)   || ((__HCLK__) == RCC_SYSCLK_DIV8)   || \
140                                ((__HCLK__) == RCC_SYSCLK_DIV16)  || ((__HCLK__) == RCC_SYSCLK_DIV64)  || \
141                                ((__HCLK__) == RCC_SYSCLK_DIV128) || ((__HCLK__) == RCC_SYSCLK_DIV256) || \
142                                ((__HCLK__) == RCC_SYSCLK_DIV512))
143 
144 #define IS_RCC_PCLK(__PCLK__) (((__PCLK__) == RCC_HCLK_DIV1) || ((__PCLK__) == RCC_HCLK_DIV2) || \
145                                ((__PCLK__) == RCC_HCLK_DIV4) || ((__PCLK__) == RCC_HCLK_DIV8) || \
146                                ((__PCLK__) == RCC_HCLK_DIV16))
147 
148 #define IS_RCC_MCO(__MCOX__) ((__MCOX__) == RCC_MCO1)
149 
150 #define IS_RCC_MCO1SOURCE(__SOURCE__) (((__SOURCE__) == RCC_MCO1SOURCE_NOCLOCK) || \
151                                        ((__SOURCE__) == RCC_MCO1SOURCE_SYSCLK) || \
152                                        ((__SOURCE__) == RCC_MCO1SOURCE_MSI) || \
153                                        ((__SOURCE__) == RCC_MCO1SOURCE_HSI) || \
154                                        ((__SOURCE__) == RCC_MCO1SOURCE_HSE) || \
155                                        ((__SOURCE__) == RCC_MCO1SOURCE_PLL1CLK) || \
156                                        ((__SOURCE__) == RCC_MCO1SOURCE_LSI) || \
157                                        ((__SOURCE__) == RCC_MCO1SOURCE_LSE) || \
158                                        ((__SOURCE__) == RCC_MCO1SOURCE_HSI48)|| \
159                                        ((__SOURCE__) == RCC_MCO1SOURCE_MSIK))
160 
161 #define IS_RCC_MCODIV(__DIV__) (((__DIV__) == RCC_MCODIV_1) || ((__DIV__) == RCC_MCODIV_2) || \
162                                 ((__DIV__) == RCC_MCODIV_4) || ((__DIV__) == RCC_MCODIV_8) || \
163                                 ((__DIV__) == RCC_MCODIV_16))
164 
165 #define IS_RCC_LSE_DRIVE(__DRIVE__) (((__DRIVE__) == RCC_LSEDRIVE_LOW)        || \
166                                      ((__DRIVE__) == RCC_LSEDRIVE_MEDIUMLOW)  || \
167                                      ((__DRIVE__) == RCC_LSEDRIVE_MEDIUMHIGH) || \
168                                      ((__DRIVE__) == RCC_LSEDRIVE_HIGH))
169 
170 #define IS_RCC_ITEM_ATTRIBUTES(ITEM) ((0U < (ITEM)) && ((ITEM) <= 0x1FFFU))
171 
172 #if defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U)
173 #define IS_RCC_ATTRIBUTES(ATTRIBUTES) (((ATTRIBUTES) == RCC_SEC_PRIV)  || \
174                                        ((ATTRIBUTES)  == RCC_SEC_NPRIV) || \
175                                        ((ATTRIBUTES)  == RCC_NSEC_PRIV) || \
176                                        ((ATTRIBUTES)  == RCC_NSEC_NPRIV))
177 #else
178 #define IS_RCC_ATTRIBUTES(ATTRIBUTES) (((ATTRIBUTES) == RCC_NSEC_NPRIV) || ((ATTRIBUTES) == RCC_NSEC_PRIV))
179 #endif /* __ARM_FEATURE_CMSE */
180 /**
181   * @}
182   */
183 
184 /* Private define ------------------------------------------------------------*/
185 /** @defgroup RCC_Private_Constants RCC Private Constants
186   * @{
187   */
188 #define LSI_TIMEOUT_VALUE          5UL    /* 5 ms (LSI maximum timeout is LSI startup time + LSI_VALUE/128 when
189                                              LSI prediv is used) */
190 #define HSI48_TIMEOUT_VALUE        2UL    /* 2 ms (minimum Tick + 1) */
191 #define SHSI_TIMEOUT_VALUE         2UL    /* 2 ms (minimum Tick + 1) */
192 #define MSIK_TIMEOUT_VALUE         2UL    /* 2 ms (minimum Tick + 1) */
193 #define PLL_TIMEOUT_VALUE          2UL    /* 2 ms (minimum Tick + 1) */
194 #define CLOCKSWITCH_TIMEOUT_VALUE  5000UL /* 5 s    */
195 #define EPOD_TIMEOUT_VALUE         2UL    /* 2 ms (minimum Tick + 1) */
196 /**
197   * @}
198   */
199 
200 /* Private macro -------------------------------------------------------------*/
201 /** @defgroup RCC_Private_Macros RCC Private Macros
202   * @{
203   */
204 
205 #define MCO1_CLK_ENABLE()   __HAL_RCC_GPIOA_CLK_ENABLE()
206 
207 #define MCO1_GPIO_PORT        GPIOA
208 
209 #define MCO1_PIN              GPIO_PIN_8
210 
211 #define RCC_PLL_OSCSOURCE_CONFIG(__HAL_RCC_PLLSOURCE__) \
212   (MODIFY_REG(RCC->PLLCFGR, RCC_PLLCFGR_PLLSRC, (uint32_t)(__HAL_RCC_PLLSOURCE__)))
213 /**
214   * @}
215   */
216 
217 /* Private variables ---------------------------------------------------------*/
218 
219 /* Private function prototypes -----------------------------------------------*/
220 /** @defgroup RCC_Private_Functions RCC Private Functions
221   * @{
222   */
223 static HAL_StatusTypeDef RCC_SetFlashLatencyFromMSIRange(uint32_t msirange);
224 /**
225   * @}
226   */
227 
228 /* Exported functions --------------------------------------------------------*/
229 
230 /** @defgroup RCC_Exported_Functions RCC Exported Functions
231   * @{
232   */
233 
234 /** @defgroup RCC_Exported_Functions_Group1 Initialization and de-initialization functions
235   *  @brief    Initialization and Configuration functions
236   *
237   @verbatim
238  ===============================================================================
239            ##### Initialization and de-initialization functions #####
240  ===============================================================================
241     [..]
242       This section provides functions allowing to configure the internal and external oscillators
243       (HSE, HSI, LSE, MSI, LSI, PLL, CSS and MCO) and the System busses clocks (SYSCLK, AHB, APB1
244        and APB2).
245 
246     [..] Internal/external clock and PLL configuration
247          (+) HSI (high-speed internal): 16 MHz factory-trimmed RC used directly or through
248              the PLL as System clock source.
249 
250          (+) MSI (Multiple Speed Internal): Its frequency is software trimmable from 100KHZ to 48MHZ.
251              It can be used to generate the clock for the USB FS or USB OTG FS (48 MHz).
252              The number of flash wait states is automatically adjusted when MSI range is updated with
253              HAL_RCC_OscConfig() and the MSI is used as System clock source.
254 
255          (+) LSI (low-speed internal): 32 KHz low consumption RC used as IWDG and/or RTC
256              clock source.
257 
258          (+) HSE (high-speed external): 4 to 48 MHz crystal oscillator used directly or
259              through the PLL as System clock source. Can be used also optionally as RTC clock source.
260 
261          (+) LSE (low-speed external): 32.768 KHz oscillator used optionally as RTC clock source.
262 
263          (+) PLL (clocked by HSI, HSE or MSI) providing up to three independent output clocks:
264            (++) The first output is used to generate the high speed system clock (up to 80MHz).
265            (++) The second output is used to generate the clock for the USB FS or USB OTG FS (48 MHz),
266                 the random analog generator (<=48 MHz) and the SDMMC1 (<= 48 MHz).
267            (++) The third output is used to generate an accurate clock to achieve
268                 high-quality audio performance on SAI interface.
269 
270          (+) PLL2 (clocked by HSI, HSE or MSI) providing up to three independent output clocks:
271            (++) The first output is used to generate SAR ADC1 clock.
272            (++) The second output is used to generate the clock for the USB Fs or USB OTG FS (48 MHz),
273                 the random analog generator (<=48 MHz) and the SDMMC1 (<= 48 MHz).
274            (++) The Third output is used to generate an accurate clock to achieve
275                 high-quality audio performance on SAI interface.
276 
277          (+) PLL3 (clocked by HSI , HSE or MSI) providing up to two independent output clocks:
278            (++) The first output is used to generate SAR ADC4 clock.
279            (++) The second  output is used to generate an accurate clock to achieve
280                 high-quality audio performance on SAI interface.
281 
282          (+) CSS (Clock security system): once enabled, if a HSE clock failure occurs
283             (HSE used directly or through PLL as System clock source), the System clock
284              is automatically switched to HSI and an interrupt is generated if enabled.
285              The interrupt is linked to the Cortex-M4 NMI (Non-Maskable Interrupt)
286              exception vector.
287 
288          (+) MCO (microcontroller clock output): used to output MSI, LSI, HSI, LSE, HSE or
289              main PLL clock (through a configurable prescaler) on PA8 pin.
290 
291     [..] System, AHB and APB busses clocks configuration
292          (+) Several clock sources can be used to drive the System clock (SYSCLK): MSI, HSI,
293              HSE and main PLL.
294              The AHB clock (HCLK) is derived from System clock through configurable
295              prescaler and used to clock the CPU, memory and peripherals mapped
296              on AHB bus (DMA, GPIO...). APB1 (PCLK1) and APB2 (PCLK2) clocks are derived
297              from AHB clock through configurable prescalers and used to clock
298              the peripherals mapped on these busses. You can use
299              "HAL_RCC_GetSysClockFreq()" function to retrieve the frequencies of these clocks.
300 
301          -@- All the peripheral clocks are derived from the System clock (SYSCLK) except:
302 
303            (+@) SAI: the SAI clock can be derived either from a specific PLL (PLL2) or (PLL3) or
304                 from an external clock mapped on the SAI_CKIN pin.
305                 You have to use HAL_RCCEx_PeriphCLKConfig() function to configure this clock.
306            (+@) RTC: the RTC clock can be derived either from the LSI, LSE or HSE clock
307                 divided by 2 to 31.
308                 You have to use __HAL_RCC_RTC_ENABLE() and HAL_RCCEx_PeriphCLKConfig() function
309                 to configure this clock.
310            (+@) USB FS, USB OTG FS, SDMMC1 and RNG: USB OTG FS or USB FS requires a frequency equal to 48 MHz
311                 to work correctly, while the SDMMC1 and RNG peripherals require a frequency
312                 equal or lower than to 48 MHz. This clock is derived of the main PLL or PLL2
313                 through PLLQ divider. You have to enable the peripheral clock and use
314                 HAL_RCCEx_PeriphCLKConfig() function to configure this clock.
315            (+@) IWDG clock which is always the LSI clock.
316 
317 
318          (+) The maximum frequency of the SYSCLK, HCLK, PCLK1 and PCLK2 is 80 MHz.
319              The clock source frequency should be adapted depending on the device voltage range
320              as listed in the Reference Manual "Clock source frequency versus voltage scaling" chapter.
321 
322   @endverbatim
323 
324 
325            Table 1. HCLK clock frequency for STM32U5xx devices
326            +-------------------------------------------------------+----------------------------------------+
327            | Latency         |                    HCLK clock frequency (MHz) 0.9V-1.2V                      |
328            |                 |-------------------------------------|---------------------+------------------|
329            |                 | voltage range 1  | voltage range 2  |   voltage range 3   |  voltage range 4 |
330            |                 |  1.1 V - 1.2V    |  1.0 V - 1.1V    |    0.9 V - 1.0V     |       0.9V       |
331            |-----------------|------------------|------------------|---------------------|------------------|
332            |0WS(1 CPU cycles)|  0 < HCLK <= 32  |  0 < HCLK <= 25  |    0 < HCLK <= 12.5 |  0 < HCLK <= 8   |
333            |-----------------|------------------|------------------|---------------------|------------------|
334            |1WS(2 CPU cycles)| 32 < HCLK <= 64  | 25 < HCLK <= 50  | 12.5 < HCLK <= 25   |  8 < HCLK <= 16  |
335            |-----------------|------------------|------------------|---------------------|------------------|
336            |2WS(3 CPU cycles)| 64 < HCLK <= 96  | 50 < HCLK <= 75  |  25 < HCLK <= 37.5  | 16 < HCLK <= 24  |
337            |-----------------|------------------|------------------|---------------------|------------------|
338            |3WS(4 CPU cycles)| 96 < HCLK <= 128 | 75 < HCLK <= 100 |  37.5 < HCLK <= 50  |        -         |
339            |-----------------|------------------|------------------|---------------------|------------------|
340            |4WS(5 CPU cycles)|128 < HCLK <= 160 |         -        |         -           |        -         |
341            +-----------------+------------------+------------------+---------------------+------------------+
342   * @{
343   */
344 
345 /**
346   * @brief  Reset the RCC clock configuration to the default reset state.
347   * @note   The default reset state of the clock configuration is given below:
348   *            - MSI ON and used as system clock source
349   *            - HSE, HSI, PLL, PLL2 and PLLISAI2 OFF
350   *            - AHB, APB1 and APB2 prescaler set to 1
351   *            - CSS, MCO1 OFF
352   *            - All interrupts disabled
353   *            - All interrupt and reset flags cleared
354   * @note   This function doesn't modify the configuration of the
355   *            - Peripheral clocks
356   *            - LSI, LSE and RTC clocks
357   * @retval HAL status
358   */
359 
HAL_RCC_DeInit(void)360 HAL_StatusTypeDef HAL_RCC_DeInit(void)
361 {
362   uint32_t tickstart;
363 
364   tickstart = HAL_GetTick();
365 
366   /* Set MSION bit */
367   SET_BIT(RCC->CR, RCC_CR_MSISON);
368 
369   /* Insure MSIRDY bit is set before writing default MSIRANGE value */
370   while (READ_BIT(RCC->CR, RCC_CR_MSISRDY) == 0U)
371   {
372     if ((HAL_GetTick() - tickstart) > MSI_TIMEOUT_VALUE)
373     {
374       return HAL_TIMEOUT;
375     }
376   }
377 
378   /* Set MSIRANGE default value */
379   MODIFY_REG(RCC->ICSCR1, RCC_ICSCR1_MSISRANGE, RCC_MSIRANGE_4);
380 
381   /* Set MSITRIM default value */
382   WRITE_REG(RCC->ICSCR2, 0x00084210U);
383 
384   /* Set MSIKRANGE default value */
385   MODIFY_REG(RCC->ICSCR1, RCC_ICSCR1_MSIKRANGE, RCC_MSIKRANGE_4);
386 
387   /* Set MSIRGSEL default value */
388   MODIFY_REG(RCC->ICSCR1, RCC_ICSCR1_MSIRGSEL, 0x0U);
389 
390   tickstart = HAL_GetTick();
391 
392   /* Reset CFGR register (MSI is selected as system clock source) */
393   CLEAR_REG(RCC->CFGR1);
394   CLEAR_REG(RCC->CFGR2);
395 
396   /* Wait till clock switch is ready */
397   while (READ_BIT(RCC->CFGR1, RCC_CFGR1_SWS) != 0U)
398   {
399     if ((HAL_GetTick() - tickstart) > CLOCKSWITCH_TIMEOUT_VALUE)
400     {
401       return HAL_TIMEOUT;
402     }
403   }
404 
405   /* Reset MSIKON, HSECSSON , HSEON, HSEBYP, HSION, HSIKERON, PLL1ON, PLL2ON, PLL3ON bits */
406   CLEAR_BIT(RCC->CR, RCC_CR_MSIKON | RCC_CR_MSIPLLSEL | RCC_CR_MSIPLLFAST | RCC_CR_MSIKERON | RCC_CR_CSSON | \
407             RCC_CR_HSION | RCC_CR_HSIKERON | RCC_CR_PLL1ON | RCC_CR_PLL2ON | RCC_CR_PLL3ON | RCC_CR_HSI48ON | \
408             RCC_CR_HSEON | RCC_CR_SHSION);
409 
410   /* Reset HSEBYP & HSEEXT bits */
411   CLEAR_BIT(RCC->CR, RCC_CR_HSEBYP | RCC_CR_HSEEXT);
412 
413   tickstart = HAL_GetTick();
414 
415   /* Clear PLL1ON bit */
416   CLEAR_BIT(RCC->CR, RCC_CR_PLL1ON);
417 
418   /* Wait till PLL1 is disabled */
419   while (READ_BIT(RCC->CR, RCC_CR_PLL1RDY) != 0U)
420   {
421     if ((HAL_GetTick() - tickstart) > PLL_TIMEOUT_VALUE)
422     {
423       return HAL_TIMEOUT;
424     }
425   }
426 
427   tickstart = HAL_GetTick();
428 
429   /* Reset PLL2N bit */
430   CLEAR_BIT(RCC->CR, RCC_CR_PLL2ON);
431 
432   /* Wait till PLL2 is disabled */
433   while (READ_BIT(RCC->CR, RCC_CR_PLL2RDY) != 0U)
434   {
435     if ((HAL_GetTick() - tickstart) > PLL_TIMEOUT_VALUE)
436     {
437       return HAL_TIMEOUT;
438     }
439   }
440 
441   tickstart = HAL_GetTick();
442 
443   /* Reset PLL3 bit */
444   CLEAR_BIT(RCC->CR, RCC_CR_PLL3ON);
445 
446   /* Wait till PLL3 is disabled */
447   while (READ_BIT(RCC->CR, RCC_CR_PLL3RDY) != 0U)
448   {
449     if ((HAL_GetTick() - tickstart) > PLL_TIMEOUT_VALUE)
450     {
451       return HAL_TIMEOUT;
452     }
453   }
454 
455   /* Reset PLL1CFGR register */
456   CLEAR_REG(RCC->PLL1CFGR);
457 
458   /* Reset PLL1DIVR register */
459   WRITE_REG(RCC->PLL1DIVR, PLLDIVR_RESET_VALUE);
460 
461   /* Reset PLL1FRACR register */
462   CLEAR_REG(RCC->PLL1FRACR);
463 
464   /* Reset PLL2CFGR register */
465   CLEAR_REG(RCC->PLL2CFGR);
466 
467   /* Reset PLL2DIVR register */
468   WRITE_REG(RCC->PLL2DIVR, PLLDIVR_RESET_VALUE);
469 
470   /* Reset PLL2FRACR register */
471   CLEAR_REG(RCC->PLL2FRACR);
472 
473   /* Reset PLL3CFGR register */
474   CLEAR_REG(RCC->PLL3CFGR);
475 
476   /* Reset PLL3DIVR register */
477   WRITE_REG(RCC->PLL3DIVR, PLLDIVR_RESET_VALUE);
478 
479   /* Reset PLL3FRACR register */
480   CLEAR_REG(RCC->PLL3FRACR);
481 
482   /* Disable all interrupts */
483   CLEAR_REG(RCC->CIER);
484 
485   /* Clear all interrupts flags */
486   WRITE_REG(RCC->CICR, 0xFFFFFFFFU);
487 
488   /* Reset all CSR flags */
489   SET_BIT(RCC->CSR, RCC_CSR_RMVF);
490 
491   /* Update the SystemCoreClock global variable */
492   SystemCoreClock = MSI_VALUE;
493 
494   /* Decreasing the number of wait states because of lower CPU frequency */
495 
496   /* Program the new number of wait states to the LATENCY bits in the FLASH_ACR register */
497   __HAL_FLASH_SET_LATENCY(FLASH_LATENCY_DEFAULT);
498 
499   /* Check that the new number of wait states is taken into account to access the Flash
500   memory by reading the FLASH_ACR register */
501   if (__HAL_FLASH_GET_LATENCY() != FLASH_LATENCY_DEFAULT)
502   {
503     return HAL_ERROR;
504   }
505 
506   /* Adapt Systick interrupt period */
507   return (HAL_InitTick(TICK_INT_PRIORITY));
508 
509 }
510 
511 /**
512   * @brief  Initialize the RCC Oscillators according to the specified parameters in the
513   *         RCC_OscInitTypeDef.
514   * @param  pRCC_OscInitStruct  pointer to an RCC_OscInitTypeDef structure that
515   *         contains the configuration information for the RCC Oscillators.
516   * @note   The PLL is not disabled when used as system clock.
517   * @note   Transitions LSE Bypass to LSE On and LSE On to LSE Bypass are not
518   *         supported by this function. User should request a transition to LSE Off
519   *         first and then LSE On or LSE Bypass.
520   * @note   Transition HSE Bypass to HSE On and HSE On to HSE Bypass are not
521   *         supported by this function. User should request a transition to HSE Off
522   *         first and then HSE On or HSE Bypass.
523   * @retval HAL status
524   */
HAL_RCC_OscConfig(const RCC_OscInitTypeDef * pRCC_OscInitStruct)525 HAL_StatusTypeDef HAL_RCC_OscConfig(const RCC_OscInitTypeDef  *pRCC_OscInitStruct)
526 {
527   uint32_t tickstart;
528   HAL_StatusTypeDef status;
529   uint32_t sysclk_source;
530   uint32_t pll_config;
531   FlagStatus pwrboosten = RESET;
532   uint32_t temp1_pllckcfg;
533   uint32_t temp2_pllckcfg;
534 
535   /* Check Null pointer */
536   if (pRCC_OscInitStruct == NULL)
537   {
538     return HAL_ERROR;
539   }
540 
541   /* Check the parameters */
542   assert_param(IS_RCC_OSCILLATORTYPE(pRCC_OscInitStruct->OscillatorType));
543 
544   sysclk_source = __HAL_RCC_GET_SYSCLK_SOURCE();
545   pll_config = __HAL_RCC_GET_PLL_OSCSOURCE();
546 
547   /*----------------------------- MSI Configuration --------------------------*/
548   if (((pRCC_OscInitStruct->OscillatorType) & RCC_OSCILLATORTYPE_MSI) == RCC_OSCILLATORTYPE_MSI)
549   {
550     /* Check the parameters */
551     assert_param(IS_RCC_MSI(pRCC_OscInitStruct->MSIState));
552     assert_param(IS_RCC_MSICALIBRATION_VALUE(pRCC_OscInitStruct->MSICalibrationValue));
553     assert_param(IS_RCC_MSI_CLOCK_RANGE(pRCC_OscInitStruct->MSIClockRange));
554 
555     /*Check if MSI is used as system clock or as PLL source when PLL is selected as system clock*/
556 
557     if ((sysclk_source == RCC_SYSCLKSOURCE_STATUS_MSI) ||
558         ((sysclk_source == RCC_SYSCLKSOURCE_STATUS_PLLCLK) && (pll_config == RCC_PLLSOURCE_MSI)))
559     {
560       if (pRCC_OscInitStruct->MSIState == RCC_MSI_OFF)
561       {
562         return HAL_ERROR;
563       }
564 
565       /* Otherwise, just the calibration and MSI range change are allowed */
566       else
567       {
568         /* To correctly read data from FLASH memory, the number of wait states (LATENCY)
569            must be correctly programmed according to the frequency of the CPU clock
570            (HCLK) and the supply voltage of the device */
571         if (pRCC_OscInitStruct->MSIClockRange > __HAL_RCC_GET_MSI_RANGE())
572         {
573           /* Decrease number of wait states update if necessary */
574           /* Only possible when MSI is the System clock source  */
575           if (sysclk_source == RCC_SYSCLKSOURCE_STATUS_MSI)
576           {
577             if (RCC_SetFlashLatencyFromMSIRange(pRCC_OscInitStruct->MSIClockRange) != HAL_OK)
578             {
579               return HAL_ERROR;
580             }
581           }
582 
583           /* Selects the Multiple Speed oscillator (MSI) clock range */
584           __HAL_RCC_MSI_RANGE_CONFIG(pRCC_OscInitStruct->MSIClockRange);
585           /* Adjusts the Multiple Speed oscillator (MSI) calibration value */
586           __HAL_RCC_MSI_CALIBRATIONVALUE_ADJUST((pRCC_OscInitStruct->MSICalibrationValue), \
587                                                 (pRCC_OscInitStruct->MSIClockRange));
588         }
589         else
590         {
591           /* Else, keep current flash latency while decreasing applies */
592           /* Selects the Multiple Speed oscillator (MSI) clock range */
593           __HAL_RCC_MSI_RANGE_CONFIG(pRCC_OscInitStruct->MSIClockRange);
594           /* Adjusts the Multiple Speed oscillator (MSI) calibration value */
595           __HAL_RCC_MSI_CALIBRATIONVALUE_ADJUST((pRCC_OscInitStruct->MSICalibrationValue), \
596                                                 (pRCC_OscInitStruct->MSIClockRange));
597 
598           if (sysclk_source == RCC_SYSCLKSOURCE_STATUS_MSI)
599           {
600             if (RCC_SetFlashLatencyFromMSIRange(pRCC_OscInitStruct->MSIClockRange) != HAL_OK)
601             {
602               return HAL_ERROR;
603             }
604           }
605         }
606 
607         /* Update the SystemCoreClock global variable */
608         (void) HAL_RCC_GetHCLKFreq();
609         /* Configure the source of time base considering new system clocks settings*/
610         status = HAL_InitTick(uwTickPrio);
611         if (status != HAL_OK)
612         {
613           return status;
614         }
615       }
616     }
617     else
618     {
619       /* Check the MSI State */
620       if (pRCC_OscInitStruct->MSIState != RCC_MSI_OFF)
621       {
622         /* Enable the Internal High Speed oscillator (MSI) */
623         __HAL_RCC_MSI_ENABLE();
624 
625         tickstart = HAL_GetTick();
626 
627         /* Wait till MSI is ready */
628         while (READ_BIT(RCC->CR, RCC_CR_MSISRDY) == 0U)
629         {
630           if ((HAL_GetTick() - tickstart) > MSI_TIMEOUT_VALUE)
631           {
632             return HAL_TIMEOUT;
633           }
634         }
635         /* Selects the Multiple Speed oscillator (MSI) clock range */
636         __HAL_RCC_MSI_RANGE_CONFIG(pRCC_OscInitStruct->MSIClockRange);
637         /* Adjusts the Multiple Speed oscillator (MSI) calibration value */
638         __HAL_RCC_MSI_CALIBRATIONVALUE_ADJUST((pRCC_OscInitStruct->MSICalibrationValue), \
639                                               (pRCC_OscInitStruct->MSIClockRange));
640 
641       }
642       else
643       {
644         /* Disable the Internal High Speed oscillator (MSI) */
645         __HAL_RCC_MSI_DISABLE();
646 
647         tickstart = HAL_GetTick();
648 
649         /* Wait till MSI is ready */
650         while (READ_BIT(RCC->CR, RCC_CR_MSISRDY) != 0U)
651         {
652           if ((HAL_GetTick() - tickstart) > MSI_TIMEOUT_VALUE)
653           {
654             return HAL_TIMEOUT;
655           }
656         }
657       }
658     }
659   }
660   /*------------------------------- HSE Configuration ------------------------*/
661   if (((pRCC_OscInitStruct->OscillatorType) & RCC_OSCILLATORTYPE_HSE) == RCC_OSCILLATORTYPE_HSE)
662   {
663     /* Check the parameters */
664     assert_param(IS_RCC_HSE(pRCC_OscInitStruct->HSEState));
665 
666     /* When the HSE is used as system clock or clock source for PLL in these cases it is not allowed to be disabled */
667     if ((sysclk_source == RCC_SYSCLKSOURCE_STATUS_HSE) ||
668         ((sysclk_source == RCC_SYSCLKSOURCE_STATUS_PLLCLK) && (pll_config == RCC_PLLSOURCE_HSE)))
669     {
670       if (pRCC_OscInitStruct->HSEState == RCC_HSE_OFF)
671       {
672         return HAL_ERROR;
673       }
674     }
675     else
676     {
677       /* Set the new HSE configuration ---------------------------------------*/
678       __HAL_RCC_HSE_CONFIG(pRCC_OscInitStruct->HSEState);
679 
680       /* Check the HSE State */
681       if (pRCC_OscInitStruct->HSEState != RCC_HSE_OFF)
682       {
683         tickstart = HAL_GetTick();
684 
685         /* Wait till HSE is ready */
686         while (READ_BIT(RCC->CR, RCC_CR_HSERDY) == 0U)
687         {
688           if ((HAL_GetTick() - tickstart) > HSE_TIMEOUT_VALUE)
689           {
690             return HAL_TIMEOUT;
691           }
692         }
693       }
694       else
695       {
696         tickstart = HAL_GetTick();
697 
698         /* Wait till HSE is disabled */
699         while (READ_BIT(RCC->CR, RCC_CR_HSERDY) != 0U)
700         {
701           if ((HAL_GetTick() - tickstart) > HSE_TIMEOUT_VALUE)
702           {
703             return HAL_TIMEOUT;
704           }
705         }
706       }
707     }
708   }
709   /*----------------------------- HSI Configuration --------------------------*/
710   if (((pRCC_OscInitStruct->OscillatorType) & RCC_OSCILLATORTYPE_HSI) == RCC_OSCILLATORTYPE_HSI)
711   {
712     /* Check the parameters */
713     assert_param(IS_RCC_HSI(pRCC_OscInitStruct->HSIState));
714     assert_param(IS_RCC_HSI_CALIBRATION_VALUE(pRCC_OscInitStruct->HSICalibrationValue));
715 
716     /* Check if HSI is used as system clock or as PLL source when PLL is selected as system clock */
717     if ((sysclk_source == RCC_SYSCLKSOURCE_STATUS_HSI) ||
718         ((sysclk_source == RCC_SYSCLKSOURCE_STATUS_PLLCLK) && (pll_config == RCC_PLLSOURCE_HSI)))
719     {
720       /* When HSI is used as system clock it will not be disabled */
721       if (pRCC_OscInitStruct->HSIState == RCC_HSI_OFF)
722       {
723         return HAL_ERROR;
724       }
725       /* Otherwise, just the calibration is allowed */
726       else
727       {
728         /* Adjusts the Internal High Speed oscillator (HSI) calibration value */
729         __HAL_RCC_HSI_CALIBRATIONVALUE_ADJUST(pRCC_OscInitStruct->HSICalibrationValue);
730       }
731     }
732     else
733     {
734       /* Check the HSI State */
735       if (pRCC_OscInitStruct->HSIState != RCC_HSI_OFF)
736       {
737         /* Enable the Internal High Speed oscillator (HSI) */
738         __HAL_RCC_HSI_ENABLE();
739 
740         tickstart = HAL_GetTick();
741 
742         /* Wait till HSI is ready */
743         while (READ_BIT(RCC->CR, RCC_CR_HSIRDY) == 0U)
744         {
745           if ((HAL_GetTick() - tickstart) > HSI_TIMEOUT_VALUE)
746           {
747             return HAL_TIMEOUT;
748           }
749         }
750 
751         /* Adjusts the Internal High Speed oscillator (HSI) calibration value */
752         __HAL_RCC_HSI_CALIBRATIONVALUE_ADJUST(pRCC_OscInitStruct->HSICalibrationValue);
753       }
754       else
755       {
756         /* Disable the Internal High Speed oscillator (HSI) */
757         __HAL_RCC_HSI_DISABLE();
758 
759         tickstart = HAL_GetTick();
760 
761         /* Wait till HSI is disabled */
762         while (READ_BIT(RCC->CR, RCC_CR_HSIRDY) != 0U)
763         {
764           if ((HAL_GetTick() - tickstart) > HSI_TIMEOUT_VALUE)
765           {
766             return HAL_TIMEOUT;
767           }
768         }
769       }
770     }
771   }
772   /*------------------------------ LSI Configuration -------------------------*/
773   if (((pRCC_OscInitStruct->OscillatorType) & RCC_OSCILLATORTYPE_LSI) == RCC_OSCILLATORTYPE_LSI)
774   {
775     /* Check the parameters */
776     assert_param(IS_RCC_LSI(pRCC_OscInitStruct->LSIState));
777 
778     FlagStatus  pwrclkchanged = RESET;
779 
780     /* Update LSI configuration in Backup Domain control register    */
781     /* Requires to enable write access to Backup Domain of necessary */
782     if (__HAL_RCC_PWR_IS_CLK_DISABLED())
783     {
784       __HAL_RCC_PWR_CLK_ENABLE();
785       pwrclkchanged = SET;
786     }
787 
788     if (HAL_IS_BIT_CLR(PWR->DBPR, PWR_DBPR_DBP))
789     {
790       /* Enable write access to Backup domain */
791       SET_BIT(PWR->DBPR, PWR_DBPR_DBP);
792 
793       /* Wait for Backup domain Write protection disable */
794       tickstart = HAL_GetTick();
795 
796       while (HAL_IS_BIT_CLR(PWR->DBPR, PWR_DBPR_DBP))
797       {
798         if ((HAL_GetTick() - tickstart) > RCC_DBP_TIMEOUT_VALUE)
799         {
800           return HAL_TIMEOUT;
801         }
802       }
803     }
804     /* Check the LSI State */
805     if (pRCC_OscInitStruct->LSIState != RCC_LSI_OFF)
806     {
807       uint32_t bdcr_temp = RCC->BDCR;
808 
809       /* Check LSI division factor */
810       assert_param(IS_RCC_LSIDIV(pRCC_OscInitStruct->LSIDiv));
811 
812       if (pRCC_OscInitStruct->LSIDiv != (bdcr_temp & RCC_BDCR_LSIPREDIV))
813       {
814         if (((bdcr_temp & RCC_BDCR_LSIRDY) == RCC_BDCR_LSIRDY) && \
815             ((bdcr_temp & RCC_BDCR_LSION) != RCC_BDCR_LSION))
816         {
817           /* If LSIRDY is set while LSION is not enabled, LSIPREDIV can't be updated */
818           /* The LSIPREDIV cannot be changed if the LSI is used by the IWDG or by the RTC */
819           return HAL_ERROR;
820         }
821 
822         /* Turn off LSI before changing RCC_BDCR_LSIPREDIV */
823         if ((bdcr_temp & RCC_BDCR_LSION) == RCC_BDCR_LSION)
824         {
825           __HAL_RCC_LSI_DISABLE();
826 
827           tickstart = HAL_GetTick();
828 
829           /* Wait till LSI is disabled */
830           while (READ_BIT(RCC->BDCR, RCC_BDCR_LSIRDY) != 0U)
831           {
832             if ((HAL_GetTick() - tickstart) > LSI_TIMEOUT_VALUE)
833             {
834               return HAL_TIMEOUT;
835             }
836           }
837         }
838 
839         /* Set LSI division factor */
840         MODIFY_REG(RCC->BDCR, RCC_BDCR_LSIPREDIV, pRCC_OscInitStruct->LSIDiv);
841       }
842 
843       /* Enable the Internal Low Speed oscillator (LSI) */
844       __HAL_RCC_LSI_ENABLE();
845 
846       tickstart = HAL_GetTick();
847 
848       /* Wait till LSI is ready */
849       while (READ_BIT(RCC->BDCR, RCC_BDCR_LSIRDY) == 0U)
850       {
851         if ((HAL_GetTick() - tickstart) > LSI_TIMEOUT_VALUE)
852         {
853           return HAL_TIMEOUT;
854         }
855       }
856     }
857     else
858     {
859       /* Disable the Internal Low Speed oscillator (LSI) */
860       __HAL_RCC_LSI_DISABLE();
861 
862       tickstart = HAL_GetTick();
863 
864       /* Wait till LSI is disabled */
865       while (READ_BIT(RCC->BDCR, RCC_BDCR_LSIRDY) != 0U)
866       {
867         if ((HAL_GetTick() - tickstart) > LSI_TIMEOUT_VALUE)
868         {
869           return HAL_TIMEOUT;
870         }
871       }
872     }
873     /* Restore clock configuration if changed */
874     if (pwrclkchanged == SET)
875     {
876       __HAL_RCC_PWR_CLK_DISABLE();
877     }
878   }
879   /*------------------------------ LSE Configuration -------------------------*/
880   if (((pRCC_OscInitStruct->OscillatorType) & RCC_OSCILLATORTYPE_LSE) == RCC_OSCILLATORTYPE_LSE)
881   {
882     FlagStatus pwrclkchanged = RESET;
883 
884     /* Check the parameters */
885     assert_param(IS_RCC_LSE(pRCC_OscInitStruct->LSEState));
886 
887     /* Update LSE configuration in Backup Domain control register    */
888     /* Requires to enable write access to Backup Domain of necessary */
889     if (__HAL_RCC_PWR_IS_CLK_DISABLED())
890     {
891       __HAL_RCC_PWR_CLK_ENABLE();
892       pwrclkchanged = SET;
893     }
894 
895     if (HAL_IS_BIT_CLR(PWR->DBPR, PWR_DBPR_DBP))
896     {
897       /* Enable write access to Backup domain */
898       SET_BIT(PWR->DBPR, PWR_DBPR_DBP);
899 
900       /* Wait for Backup domain Write protection disable */
901       tickstart = HAL_GetTick();
902 
903       while (HAL_IS_BIT_CLR(PWR->DBPR, PWR_DBPR_DBP))
904       {
905         if ((HAL_GetTick() - tickstart) > RCC_DBP_TIMEOUT_VALUE)
906         {
907           return HAL_TIMEOUT;
908         }
909       }
910     }
911 
912     /* Set the new LSE configuration -----------------------------------------*/
913     if ((pRCC_OscInitStruct->LSEState & RCC_BDCR_LSEON) != 0U)
914     {
915       if ((pRCC_OscInitStruct->LSEState & RCC_BDCR_LSEBYP) != 0U)
916       {
917         /* LSE oscillator bypass enable */
918         SET_BIT(RCC->BDCR, RCC_BDCR_LSEBYP);
919         SET_BIT(RCC->BDCR, RCC_BDCR_LSEON);
920       }
921       else
922       {
923         /* LSE oscillator enable */
924         SET_BIT(RCC->BDCR, RCC_BDCR_LSEON);
925       }
926     }
927     else
928     {
929       CLEAR_BIT(RCC->BDCR, RCC_BDCR_LSEON);
930       CLEAR_BIT(RCC->BDCR, RCC_BDCR_LSEBYP);
931     }
932 
933     /* Check the LSE State */
934     if (pRCC_OscInitStruct->LSEState != RCC_LSE_OFF)
935     {
936       tickstart = HAL_GetTick();
937 
938       /* Wait till LSE is ready */
939       while (READ_BIT(RCC->BDCR, RCC_BDCR_LSERDY) == 0U)
940       {
941         if ((HAL_GetTick() - tickstart) > RCC_LSE_TIMEOUT_VALUE)
942         {
943           return HAL_TIMEOUT;
944         }
945       }
946 
947       /* Enable LSESYS additionally if requested */
948       if ((pRCC_OscInitStruct->LSEState & RCC_BDCR_LSESYSEN) != 0U)
949       {
950         SET_BIT(RCC->BDCR, RCC_BDCR_LSESYSEN);
951 
952         /* Wait till LSESYS is ready */
953         while (READ_BIT(RCC->BDCR, RCC_BDCR_LSESYSRDY) == 0U)
954         {
955           if ((HAL_GetTick() - tickstart) > RCC_LSE_TIMEOUT_VALUE)
956           {
957             return HAL_TIMEOUT;
958           }
959         }
960       }
961       else
962       {
963         /* Make sure LSESYSEN/LSESYSRDY are reset */
964         CLEAR_BIT(RCC->BDCR, RCC_BDCR_LSESYSEN);
965 
966         /* Wait till LSESYSRDY is cleared */
967         while (READ_BIT(RCC->BDCR, RCC_BDCR_LSESYSRDY) != 0U)
968         {
969           if ((HAL_GetTick() - tickstart) > RCC_LSE_TIMEOUT_VALUE)
970           {
971             return HAL_TIMEOUT;
972           }
973         }
974       }
975     }
976     else
977     {
978       tickstart = HAL_GetTick();
979 
980       /* Wait till LSE is disabled */
981       while (READ_BIT(RCC->BDCR, RCC_BDCR_LSERDY) != 0U)
982       {
983         if ((HAL_GetTick() - tickstart) > RCC_LSE_TIMEOUT_VALUE)
984         {
985           return HAL_TIMEOUT;
986         }
987       }
988 
989       if (READ_BIT(RCC->BDCR, RCC_BDCR_LSESYSEN) != 0U)
990       {
991         /* Reset LSESYSEN once LSE is disabled */
992         CLEAR_BIT(RCC->BDCR, RCC_BDCR_LSESYSEN);
993 
994         /* Wait till LSESYSRDY is cleared */
995         while (READ_BIT(RCC->BDCR, RCC_BDCR_LSESYSRDY) != 0U)
996         {
997           if ((HAL_GetTick() - tickstart) > RCC_LSE_TIMEOUT_VALUE)
998           {
999             return HAL_TIMEOUT;
1000           }
1001         }
1002       }
1003     }
1004 
1005     /* Restore clock configuration if changed */
1006     if (pwrclkchanged == SET)
1007     {
1008       __HAL_RCC_PWR_CLK_DISABLE();
1009     }
1010   }
1011   /*------------------------------ HSI48 Configuration -----------------------*/
1012   if (((pRCC_OscInitStruct->OscillatorType) & RCC_OSCILLATORTYPE_HSI48) == RCC_OSCILLATORTYPE_HSI48)
1013   {
1014     /* Check the parameters */
1015     assert_param(IS_RCC_HSI48(pRCC_OscInitStruct->HSI48State));
1016 
1017     /* Check the HSI48 State */
1018     if (pRCC_OscInitStruct->HSI48State != RCC_HSI48_OFF)
1019     {
1020       /* Enable the Internal High Speed oscillator (HSI48) */
1021       __HAL_RCC_HSI48_ENABLE();
1022 
1023       tickstart = HAL_GetTick();
1024 
1025       /* Wait till HSI48 is ready */
1026       while (READ_BIT(RCC->CR, RCC_CR_HSI48RDY) == 0U)
1027       {
1028         if ((HAL_GetTick() - tickstart) > HSI48_TIMEOUT_VALUE)
1029         {
1030           return HAL_TIMEOUT;
1031         }
1032       }
1033     }
1034     else
1035     {
1036       /* Disable the Internal High Speed oscillator (HSI48) */
1037       __HAL_RCC_HSI48_DISABLE();
1038 
1039       tickstart = HAL_GetTick();
1040 
1041       /* Wait till HSI48 is disabled */
1042       while (READ_BIT(RCC->CR, RCC_CR_HSI48RDY) != 0U)
1043       {
1044         if ((HAL_GetTick() - tickstart) > HSI48_TIMEOUT_VALUE)
1045         {
1046           return HAL_TIMEOUT;
1047         }
1048       }
1049     }
1050   }
1051 
1052   /*------------------------------ SHSI Configuration -----------------------*/
1053   if (((pRCC_OscInitStruct->OscillatorType) & RCC_OSCILLATORTYPE_SHSI) == RCC_OSCILLATORTYPE_SHSI)
1054   {
1055     /* Check the parameters */
1056     assert_param(IS_RCC_SHSI(pRCC_OscInitStruct->SHSIState));
1057 
1058     /* Check the SHSI State */
1059     if (pRCC_OscInitStruct->SHSIState != RCC_SHSI_OFF)
1060     {
1061       /* Enable the Secure Internal High Speed oscillator (SHSI) */
1062       __HAL_RCC_SHSI_ENABLE();
1063 
1064       tickstart = HAL_GetTick();
1065 
1066       /* Wait till SHSI is ready */
1067       while (READ_BIT(RCC->CR, RCC_CR_SHSIRDY) == 0U)
1068       {
1069         if ((HAL_GetTick() - tickstart) > SHSI_TIMEOUT_VALUE)
1070         {
1071           return HAL_TIMEOUT;
1072         }
1073       }
1074     }
1075     else
1076     {
1077       /* Disable the Secure Internal High Speed oscillator (SHSI) */
1078       __HAL_RCC_SHSI_DISABLE();
1079 
1080       tickstart = HAL_GetTick();
1081 
1082       /* Wait till SHSI is disabled */
1083       while (READ_BIT(RCC->CR, RCC_CR_SHSIRDY) != 0U)
1084       {
1085         if ((HAL_GetTick() - tickstart) > SHSI_TIMEOUT_VALUE)
1086         {
1087           return HAL_TIMEOUT;
1088         }
1089       }
1090     }
1091   }
1092   /*------------------------------ MSIK Configuration -----------------------*/
1093   if (((pRCC_OscInitStruct->OscillatorType) & RCC_OSCILLATORTYPE_MSIK) == RCC_OSCILLATORTYPE_MSIK)
1094   {
1095     /* Check the parameters */
1096     assert_param(IS_RCC_MSIK(pRCC_OscInitStruct->MSIKState));
1097     assert_param(IS_RCC_MSIK_CLOCK_RANGE(pRCC_OscInitStruct->MSIKClockRange));
1098     assert_param(IS_RCC_MSICALIBRATION_VALUE(pRCC_OscInitStruct->MSICalibrationValue));
1099 
1100     /* Check the MSIK State */
1101     if (pRCC_OscInitStruct->MSIKState != RCC_MSIK_OFF)
1102     {
1103 
1104       /* Selects the Multiple Speed of kernel high speed oscillator (MSIK) clock range .*/
1105       __HAL_RCC_MSIK_RANGE_CONFIG(pRCC_OscInitStruct->MSIKClockRange);
1106       /* Adjusts the Multiple Speed of kernel high speed oscillator (MSIK) calibration value.*/
1107       __HAL_RCC_MSI_CALIBRATIONVALUE_ADJUST((pRCC_OscInitStruct->MSICalibrationValue), \
1108                                             (pRCC_OscInitStruct->MSIClockRange));
1109 
1110       /* Enable the Internal kernel High Speed oscillator (MSIK) */
1111       __HAL_RCC_MSIK_ENABLE();
1112 
1113       tickstart = HAL_GetTick();
1114 
1115       /* Wait till MSIK is ready */
1116       while (READ_BIT(RCC->CR, RCC_CR_MSIKRDY) == 0U)
1117       {
1118         if ((HAL_GetTick() - tickstart) > MSIK_TIMEOUT_VALUE)
1119         {
1120           return HAL_TIMEOUT;
1121         }
1122       }
1123     }
1124     else
1125     {
1126       /* Disable the Internal High Speed Kernel oscillator (MSIK) */
1127       __HAL_RCC_MSIK_DISABLE();
1128 
1129       tickstart = HAL_GetTick();
1130 
1131       /* Wait till MSIK is disabled */
1132       while (READ_BIT(RCC->CR, RCC_CR_MSIKRDY) != 0U)
1133       {
1134         if ((HAL_GetTick() - tickstart) > MSIK_TIMEOUT_VALUE)
1135         {
1136           return HAL_TIMEOUT;
1137         }
1138       }
1139     }
1140   }
1141   /*-------------------------------- PLL Configuration -----------------------*/
1142   /* Check the parameters */
1143   assert_param(IS_RCC_PLL(pRCC_OscInitStruct->PLL.PLLState));
1144 
1145   if ((pRCC_OscInitStruct->PLL.PLLState) != RCC_PLL_NONE)
1146   {
1147     FlagStatus  pwrclkchanged = RESET;
1148 
1149     /* Check if the PLL is used as system clock or not */
1150     if (__HAL_RCC_GET_SYSCLK_SOURCE() != RCC_SYSCLKSOURCE_STATUS_PLLCLK)
1151     {
1152       if ((pRCC_OscInitStruct->PLL.PLLState) == RCC_PLL_ON)
1153       {
1154         /* Check the parameters */
1155         assert_param(IS_RCC_PLLMBOOST_VALUE(pRCC_OscInitStruct->PLL.PLLMBOOST));
1156         assert_param(IS_RCC_PLLSOURCE(pRCC_OscInitStruct->PLL.PLLSource));
1157         assert_param(IS_RCC_PLLM_VALUE(pRCC_OscInitStruct->PLL.PLLM));
1158         assert_param(IS_RCC_PLLN_VALUE(pRCC_OscInitStruct->PLL.PLLN));
1159         assert_param(IS_RCC_PLLP_VALUE(pRCC_OscInitStruct->PLL.PLLP));
1160         assert_param(IS_RCC_PLLQ_VALUE(pRCC_OscInitStruct->PLL.PLLQ));
1161         assert_param(IS_RCC_PLLR_VALUE(pRCC_OscInitStruct->PLL.PLLR));
1162 
1163         /* Disable the main PLL */
1164         __HAL_RCC_PLL_DISABLE();
1165 
1166         tickstart = HAL_GetTick();
1167 
1168         /* Wait till PLL is disabled */
1169         while (READ_BIT(RCC->CR, RCC_CR_PLL1RDY) != 0U)
1170         {
1171           if ((HAL_GetTick() - tickstart) > PLL_TIMEOUT_VALUE)
1172           {
1173             return HAL_TIMEOUT;
1174           }
1175         }
1176 
1177         /* Requires to enable write access to Backup Domain of necessary */
1178         if (__HAL_RCC_PWR_IS_CLK_DISABLED())
1179         {
1180           __HAL_RCC_PWR_CLK_ENABLE();
1181           pwrclkchanged = SET;
1182         }
1183 
1184         /*Disable EPOD to configure PLL1MBOOST*/
1185         if (READ_BIT(PWR->VOSR, PWR_VOSR_BOOSTEN) == PWR_VOSR_BOOSTEN)
1186         {
1187           pwrboosten = SET;
1188         }
1189         CLEAR_BIT(PWR->VOSR, PWR_VOSR_BOOSTEN);
1190 
1191         /* Configure the main PLL clock source, multiplication and division factors */
1192         __HAL_RCC_PLL_CONFIG(pRCC_OscInitStruct->PLL.PLLSource,
1193                              pRCC_OscInitStruct->PLL.PLLMBOOST,
1194                              pRCC_OscInitStruct->PLL.PLLM,
1195                              pRCC_OscInitStruct->PLL.PLLN,
1196                              pRCC_OscInitStruct->PLL.PLLP,
1197                              pRCC_OscInitStruct->PLL.PLLQ,
1198                              pRCC_OscInitStruct->PLL.PLLR);
1199 
1200         assert_param(IS_RCC_PLL_FRACN_VALUE(pRCC_OscInitStruct->PLL.PLLFRACN));
1201 
1202         /* Disable PLL1FRACN  */
1203         __HAL_RCC_PLL_FRACN_DISABLE();
1204 
1205         /* Configure PLL  PLL1FRACN */
1206         __HAL_RCC_PLL_FRACN_CONFIG(pRCC_OscInitStruct->PLL.PLLFRACN);
1207 
1208         /* Enable PLL1FRACN  */
1209         __HAL_RCC_PLL_FRACN_ENABLE();
1210 
1211         assert_param(IS_RCC_PLLRGE_VALUE(pRCC_OscInitStruct->PLL.PLLRGE));
1212 
1213         /* Select PLL1 input reference frequency range: VCI */
1214         __HAL_RCC_PLL_VCIRANGE(pRCC_OscInitStruct->PLL.PLLRGE);
1215 
1216         if (pwrboosten == SET)
1217         {
1218           /* Enable the EPOD to reach max frequency */
1219           SET_BIT(PWR->VOSR, PWR_VOSR_BOOSTEN);
1220         }
1221 
1222         /* Restore clock configuration if changed */
1223         if (pwrclkchanged == SET)
1224         {
1225           __HAL_RCC_PWR_CLK_DISABLE();
1226         }
1227 
1228         /* Enable the main PLL */
1229         __HAL_RCC_PLL_ENABLE();
1230 
1231         tickstart = HAL_GetTick();
1232 
1233         /* Wait till PLL is ready */
1234         while (READ_BIT(RCC->CR, RCC_CR_PLL1RDY) == 0U)
1235         {
1236           if ((HAL_GetTick() - tickstart) > PLL_TIMEOUT_VALUE)
1237           {
1238             return HAL_TIMEOUT;
1239           }
1240         }
1241 
1242         /* Enable PLL System Clock output */
1243         __HAL_RCC_PLLCLKOUT_ENABLE(RCC_PLL1_DIVR);
1244 
1245       }
1246       else
1247       {
1248         /* Disable the main PLL */
1249         __HAL_RCC_PLL_DISABLE();
1250 
1251         tickstart = HAL_GetTick();
1252 
1253         /* Wait till PLL is disabled */
1254         while (READ_BIT(RCC->CR, RCC_CR_PLL1RDY) != 0U)
1255         {
1256           if ((HAL_GetTick() - tickstart) > PLL_TIMEOUT_VALUE)
1257           {
1258             return HAL_TIMEOUT;
1259           }
1260         }
1261 
1262         /* Unselect main PLL clock source and disable main PLL outputs to save power */
1263         RCC->PLL1CFGR &= ~(RCC_PLL1CFGR_PLL1SRC | RCC_PLL1CFGR_PLL1PEN | RCC_PLL1CFGR_PLL1QEN | RCC_PLL1CFGR_PLL1REN);
1264 
1265       }
1266     }
1267     else
1268     {
1269       /* Do not return HAL_ERROR if request repeats the current configuration */
1270       temp1_pllckcfg = RCC->PLL1CFGR;
1271       temp2_pllckcfg = RCC->PLL1DIVR;
1272       if (((pRCC_OscInitStruct->PLL.PLLState) == RCC_PLL_OFF) ||
1273           (READ_BIT(temp1_pllckcfg, RCC_PLL1CFGR_PLL1SRC) != pRCC_OscInitStruct->PLL.PLLSource) ||
1274           ((READ_BIT(temp1_pllckcfg, RCC_PLL1CFGR_PLL1M) >> \
1275             RCC_PLL1CFGR_PLL1M_Pos) != (pRCC_OscInitStruct->PLL.PLLM - 1U)) ||
1276           (READ_BIT(temp1_pllckcfg, RCC_PLL1CFGR_PLL1MBOOST) != pRCC_OscInitStruct->PLL.PLLMBOOST) ||
1277           (READ_BIT(temp2_pllckcfg, RCC_PLL1DIVR_PLL1N) != (pRCC_OscInitStruct->PLL.PLLN - 1U)) ||
1278           ((READ_BIT(temp2_pllckcfg, RCC_PLL1DIVR_PLL1P) >> \
1279             RCC_PLL1DIVR_PLL1P_Pos) != (pRCC_OscInitStruct->PLL.PLLP - 1U)) ||
1280           ((READ_BIT(temp2_pllckcfg, RCC_PLL1DIVR_PLL1Q) >> \
1281             RCC_PLL1DIVR_PLL1Q_Pos) != (pRCC_OscInitStruct->PLL.PLLQ - 1U)) ||
1282           ((READ_BIT(temp2_pllckcfg, RCC_PLL1DIVR_PLL1R) >> \
1283             RCC_PLL1DIVR_PLL1R_Pos) != (pRCC_OscInitStruct->PLL.PLLR - 1U)))
1284       {
1285         return HAL_ERROR;
1286       }
1287 
1288       /* FRACN1 on-the-fly value update */
1289       if ((READ_BIT(RCC->PLL1FRACR, RCC_PLL1FRACR_PLL1FRACN) >> \
1290            RCC_PLL1FRACR_PLL1FRACN_Pos) != (pRCC_OscInitStruct->PLL.PLLFRACN))
1291       {
1292         assert_param(IS_RCC_PLL_FRACN_VALUE(pRCC_OscInitStruct->PLL.PLLFRACN));
1293 
1294         /* Disable PLL1FRACN. */
1295         __HAL_RCC_PLL_FRACN_DISABLE();
1296 
1297         /* Get Start Tick*/
1298         tickstart = HAL_GetTick();
1299 
1300         /* Wait at least 2 CK_REF (PLL1 input source divided by M) period to make sure next latched value
1301            will be taken into account. */
1302         while ((HAL_GetTick() - tickstart) < PLL_FRAC_WAIT_VALUE)
1303         {
1304         }
1305 
1306         /* Configure PLL PLL1FRACN */
1307         __HAL_RCC_PLL_FRACN_CONFIG(pRCC_OscInitStruct->PLL.PLLFRACN);
1308 
1309         /* Enable PLL1FRACN to latch the new value. */
1310         __HAL_RCC_PLL_FRACN_ENABLE();
1311       }
1312     }
1313   }
1314   return HAL_OK;
1315 }
1316 
1317 /**
1318   * @brief  Initialize the CPU, AHB and APB busses clocks according to the specified
1319   *         parameters in the pRCC_ClkInitStruct.
1320   * @param  pRCC_ClkInitStruct  pointer to an RCC_OscInitTypeDef structure that
1321   *         contains the configuration information for the RCC peripheral.
1322   * @param  FLatency  FLASH Latency
1323   *          This parameter can be one of the following values:
1324   *            @arg FLASH_LATENCY_0   FLASH 0 Latency cycle
1325   *            @arg FLASH_LATENCY_1   FLASH 1 Latency cycle
1326   *            @arg FLASH_LATENCY_2   FLASH 2 Latency cycles
1327   *            @arg FLASH_LATENCY_3   FLASH 3 Latency cycles
1328   *            @arg FLASH_LATENCY_4   FLASH 4 Latency cycles
1329   *            @arg FLASH_LATENCY_5   FLASH 5 Latency cycles
1330   *
1331   * @note   The SystemCoreClock CMSIS variable is used to store System Clock Frequency
1332   *         and updated by HAL_RCC_GetHCLKFreq() function called within this function
1333   *
1334   * @note   The MSI is used by default as system clock source after
1335   *         startup from Reset, wake-up from STANDBY mode. After restart from Reset,
1336   *         the MSI frequency is set to its default value 4 MHz.
1337   * @note   The HSI can be selected as system clock source after wakeup
1338   *         from STOP modes or in case of failure of the HSE used directly or indirectly
1339   *         as system clock (if the Clock Security System CSS is enabled).
1340   * @note   A switch from one clock source to another occurs only if the target
1341   *         clock source is ready (clock stable after startup delay or PLL locked).
1342   *         If a clock source which is not yet ready is selected, the switch will
1343   *         occur when the clock source is ready.
1344   * @note   You can use HAL_RCC_GetClockConfig() function to know which clock is
1345   *         currently used as system clock source.
1346   *
1347   * @note   Depending on the device voltage range, the software has to set correctly
1348   *         HPRE[3:0] bits to ensure that HCLK not exceed the maximum allowed frequency
1349   *         (for more details refer to section above "Initialization/de-initialization functions")
1350   * @retval HAL status
1351   */
HAL_RCC_ClockConfig(const RCC_ClkInitTypeDef * const pRCC_ClkInitStruct,uint32_t FLatency)1352 HAL_StatusTypeDef HAL_RCC_ClockConfig(const RCC_ClkInitTypeDef   *const pRCC_ClkInitStruct, uint32_t FLatency)
1353 {
1354   HAL_StatusTypeDef status;
1355   uint32_t tickstart;
1356 
1357   /* Check Null pointer */
1358   if (pRCC_ClkInitStruct == NULL)
1359   {
1360     return HAL_ERROR;
1361   }
1362 
1363   /* Check the parameters */
1364   assert_param(IS_RCC_CLOCKTYPE(pRCC_ClkInitStruct->ClockType));
1365   assert_param(IS_FLASH_LATENCY(FLatency));
1366 
1367   /* To correctly read data from FLASH memory, the number of wait states (LATENCY)
1368    must be correctly programmed according to the frequency of the CPU clock
1369    (HCLK) and the supply voltage of the device */
1370 
1371   /* Increasing the number of wait states because of higher CPU frequency */
1372   if (FLatency > __HAL_FLASH_GET_LATENCY())
1373   {
1374     /* Program the new number of wait states to the LATENCY bits in the FLASH_ACR register */
1375     __HAL_FLASH_SET_LATENCY(FLatency);
1376 
1377     /* Check that the new number of wait states is taken into account to access the Flash
1378     memory by reading the FLASH_ACR register */
1379     if (__HAL_FLASH_GET_LATENCY() != FLatency)
1380     {
1381       return HAL_ERROR;
1382     }
1383   }
1384 
1385   /* Increasing the BUS frequency divider */
1386   /*-------------------------- PCLK3 Configuration ---------------------------*/
1387   if (((pRCC_ClkInitStruct->ClockType) & RCC_CLOCKTYPE_PCLK3) == RCC_CLOCKTYPE_PCLK3)
1388   {
1389     if ((pRCC_ClkInitStruct->APB3CLKDivider) > (RCC->CFGR3 & RCC_CFGR3_PPRE3))
1390     {
1391       assert_param(IS_RCC_PCLK(pRCC_ClkInitStruct->APB3CLKDivider));
1392       MODIFY_REG(RCC->CFGR3, RCC_CFGR3_PPRE3, pRCC_ClkInitStruct->APB3CLKDivider);
1393     }
1394   }
1395   /*-------------------------- PCLK2 Configuration ---------------------------*/
1396   if (((pRCC_ClkInitStruct->ClockType) & RCC_CLOCKTYPE_PCLK2) == RCC_CLOCKTYPE_PCLK2)
1397   {
1398     if ((pRCC_ClkInitStruct->APB2CLKDivider) > ((RCC->CFGR2 & RCC_CFGR2_PPRE2) >> 4))
1399     {
1400       assert_param(IS_RCC_PCLK(pRCC_ClkInitStruct->APB2CLKDivider));
1401       MODIFY_REG(RCC->CFGR2, RCC_CFGR2_PPRE2, ((pRCC_ClkInitStruct->APB2CLKDivider) << 4));
1402     }
1403   }
1404 
1405   /*-------------------------- PCLK1 Configuration ---------------------------*/
1406   if (((pRCC_ClkInitStruct->ClockType) & RCC_CLOCKTYPE_PCLK1) == RCC_CLOCKTYPE_PCLK1)
1407   {
1408     if ((pRCC_ClkInitStruct->APB1CLKDivider) > (RCC->CFGR2 & RCC_CFGR2_PPRE1))
1409     {
1410       assert_param(IS_RCC_PCLK(pRCC_ClkInitStruct->APB1CLKDivider));
1411       MODIFY_REG(RCC->CFGR2, RCC_CFGR2_PPRE1, pRCC_ClkInitStruct->APB1CLKDivider);
1412     }
1413   }
1414 
1415   /*-------------------------- HCLK Configuration --------------------------*/
1416   if (((pRCC_ClkInitStruct->ClockType) & RCC_CLOCKTYPE_HCLK) == RCC_CLOCKTYPE_HCLK)
1417   {
1418     if ((pRCC_ClkInitStruct->AHBCLKDivider) > (RCC->CFGR2 & RCC_CFGR2_HPRE))
1419     {
1420       assert_param(IS_RCC_HCLK(pRCC_ClkInitStruct->AHBCLKDivider));
1421       MODIFY_REG(RCC->CFGR2, RCC_CFGR2_HPRE, pRCC_ClkInitStruct->AHBCLKDivider);
1422     }
1423   }
1424 
1425   /*------------------------- SYSCLK Configuration ---------------------------*/
1426   if (((pRCC_ClkInitStruct->ClockType) & RCC_CLOCKTYPE_SYSCLK) == RCC_CLOCKTYPE_SYSCLK)
1427   {
1428     assert_param(IS_RCC_SYSCLKSOURCE(pRCC_ClkInitStruct->SYSCLKSource));
1429     FlagStatus  pwrclkchanged = RESET;
1430 
1431     /* PLL is selected as System Clock Source */
1432     if (pRCC_ClkInitStruct->SYSCLKSource == RCC_SYSCLKSOURCE_PLLCLK)
1433     {
1434       if (__HAL_RCC_PWR_IS_CLK_DISABLED())
1435       {
1436         __HAL_RCC_PWR_CLK_ENABLE();
1437         pwrclkchanged = SET;
1438       }
1439       tickstart = HAL_GetTick();
1440       /* Check if EPOD is enabled */
1441       if (READ_BIT(PWR->VOSR, PWR_VOSR_BOOSTEN) != 0U)
1442       {
1443         /* Wait till BOOST is ready */
1444         while (READ_BIT(PWR->VOSR, PWR_VOSR_BOOSTRDY) == 0U)
1445         {
1446           if ((HAL_GetTick() - tickstart) > EPOD_TIMEOUT_VALUE)
1447           {
1448             return HAL_TIMEOUT;
1449           }
1450         }
1451       }
1452 
1453       /* Restore clock configuration if changed */
1454       if (pwrclkchanged == SET)
1455       {
1456         __HAL_RCC_PWR_CLK_DISABLE();
1457       }
1458 
1459       /* Check the PLL ready flag */
1460       if (READ_BIT(RCC->CR, RCC_CR_PLL1RDY) == 0U)
1461       {
1462         return HAL_ERROR;
1463       }
1464     }
1465     else
1466     {
1467       /* HSE is selected as System Clock Source */
1468       if (pRCC_ClkInitStruct->SYSCLKSource == RCC_SYSCLKSOURCE_HSE)
1469       {
1470         /* Check the HSE ready flag */
1471         if (READ_BIT(RCC->CR, RCC_CR_HSERDY) == 0U)
1472         {
1473           return HAL_ERROR;
1474         }
1475       }
1476       /* MSI is selected as System Clock Source */
1477       else if (pRCC_ClkInitStruct->SYSCLKSource == RCC_SYSCLKSOURCE_MSI)
1478       {
1479         /* Check the MSI ready flag */
1480         if (READ_BIT(RCC->CR, RCC_CR_MSISRDY) == 0U)
1481         {
1482           return HAL_ERROR;
1483         }
1484       }
1485       /* HSI is selected as System Clock Source */
1486       else
1487       {
1488         /* Check the HSI ready flag */
1489         if (READ_BIT(RCC->CR, RCC_CR_HSIRDY) == 0U)
1490         {
1491           return HAL_ERROR;
1492         }
1493       }
1494     }
1495 
1496     MODIFY_REG(RCC->CFGR1, RCC_CFGR1_SW, pRCC_ClkInitStruct->SYSCLKSource);
1497 
1498     tickstart = HAL_GetTick();
1499 
1500     if (pRCC_ClkInitStruct->SYSCLKSource == RCC_SYSCLKSOURCE_PLLCLK)
1501     {
1502       while (__HAL_RCC_GET_SYSCLK_SOURCE() != RCC_SYSCLKSOURCE_STATUS_PLLCLK)
1503       {
1504         if ((HAL_GetTick() - tickstart) > CLOCKSWITCH_TIMEOUT_VALUE)
1505         {
1506           return HAL_TIMEOUT;
1507         }
1508       }
1509     }
1510     else
1511     {
1512       if (pRCC_ClkInitStruct->SYSCLKSource == RCC_SYSCLKSOURCE_HSE)
1513       {
1514         while (__HAL_RCC_GET_SYSCLK_SOURCE() != RCC_SYSCLKSOURCE_STATUS_HSE)
1515         {
1516           if ((HAL_GetTick() - tickstart) > CLOCKSWITCH_TIMEOUT_VALUE)
1517           {
1518             return HAL_TIMEOUT;
1519           }
1520         }
1521       }
1522       else if (pRCC_ClkInitStruct->SYSCLKSource == RCC_SYSCLKSOURCE_MSI)
1523       {
1524         while (__HAL_RCC_GET_SYSCLK_SOURCE() != RCC_SYSCLKSOURCE_STATUS_MSI)
1525         {
1526           if ((HAL_GetTick() - tickstart) > CLOCKSWITCH_TIMEOUT_VALUE)
1527           {
1528             return HAL_TIMEOUT;
1529           }
1530         }
1531       }
1532       else
1533       {
1534         while (__HAL_RCC_GET_SYSCLK_SOURCE() != RCC_SYSCLKSOURCE_STATUS_HSI)
1535         {
1536           if ((HAL_GetTick() - tickstart) > CLOCKSWITCH_TIMEOUT_VALUE)
1537           {
1538             return HAL_TIMEOUT;
1539           }
1540         }
1541       }
1542     }
1543   }
1544 
1545   /* Decreasing the BUS frequency divider */
1546   /*-------------------------- HCLK Configuration --------------------------*/
1547   if (((pRCC_ClkInitStruct->ClockType) & RCC_CLOCKTYPE_HCLK) == RCC_CLOCKTYPE_HCLK)
1548   {
1549     if ((pRCC_ClkInitStruct->AHBCLKDivider) < (RCC->CFGR2 & RCC_CFGR2_HPRE))
1550     {
1551       assert_param(IS_RCC_HCLK(pRCC_ClkInitStruct->AHBCLKDivider));
1552       MODIFY_REG(RCC->CFGR2, RCC_CFGR2_HPRE, pRCC_ClkInitStruct->AHBCLKDivider);
1553     }
1554   }
1555 
1556   /* Decreasing the number of wait states because of lower CPU frequency */
1557   if (FLatency < __HAL_FLASH_GET_LATENCY())
1558   {
1559     /* Program the new number of wait states to the LATENCY bits in the FLASH_ACR register */
1560     __HAL_FLASH_SET_LATENCY(FLatency);
1561 
1562     /* Check that the new number of wait states is taken into account to access the Flash
1563     memory by reading the FLASH_ACR register */
1564     if (__HAL_FLASH_GET_LATENCY() != FLatency)
1565     {
1566       return HAL_ERROR;
1567     }
1568   }
1569 
1570   /*-------------------------- PCLK1 Configuration ---------------------------*/
1571   if (((pRCC_ClkInitStruct->ClockType) & RCC_CLOCKTYPE_PCLK1) == RCC_CLOCKTYPE_PCLK1)
1572   {
1573     if ((pRCC_ClkInitStruct->APB1CLKDivider) < (RCC->CFGR2 & RCC_CFGR2_PPRE1))
1574     {
1575       assert_param(IS_RCC_PCLK(pRCC_ClkInitStruct->APB1CLKDivider));
1576       MODIFY_REG(RCC->CFGR2, RCC_CFGR2_PPRE1, pRCC_ClkInitStruct->APB1CLKDivider);
1577     }
1578   }
1579 
1580   /*-------------------------- PCLK2 Configuration ---------------------------*/
1581   if (((pRCC_ClkInitStruct->ClockType) & RCC_CLOCKTYPE_PCLK2) == RCC_CLOCKTYPE_PCLK2)
1582   {
1583     if ((pRCC_ClkInitStruct->APB2CLKDivider) < ((RCC->CFGR2 & RCC_CFGR2_PPRE2) >> 4))
1584     {
1585       assert_param(IS_RCC_PCLK(pRCC_ClkInitStruct->APB2CLKDivider));
1586       MODIFY_REG(RCC->CFGR2, RCC_CFGR2_PPRE2, ((pRCC_ClkInitStruct->APB2CLKDivider) << 4));
1587     }
1588   }
1589 
1590   /*-------------------------- PCLK3 Configuration ---------------------------*/
1591   if (((pRCC_ClkInitStruct->ClockType) & RCC_CLOCKTYPE_PCLK3) == RCC_CLOCKTYPE_PCLK3)
1592   {
1593     if ((pRCC_ClkInitStruct->APB3CLKDivider) < (RCC->CFGR3 & RCC_CFGR3_PPRE3))
1594     {
1595       assert_param(IS_RCC_PCLK(pRCC_ClkInitStruct->APB3CLKDivider));
1596       MODIFY_REG(RCC->CFGR3, RCC_CFGR3_PPRE3, (pRCC_ClkInitStruct->APB3CLKDivider));
1597     }
1598   }
1599 
1600   /* Update the SystemCoreClock global variable */
1601   SystemCoreClock = HAL_RCC_GetSysClockFreq() >> AHBPrescTable[(RCC->CFGR2 & RCC_CFGR2_HPRE) >> RCC_CFGR2_HPRE_Pos];
1602 
1603   /* Configure the source of time base considering new system clocks settings*/
1604   status = HAL_InitTick(uwTickPrio);
1605 
1606   return status;
1607 }
1608 
1609 /**
1610   * @}
1611   */
1612 
1613 /** @defgroup RCC_Exported_Functions_Group2 Peripheral Control functions
1614   * @brief   RCC clocks control functions
1615   *
1616 @verbatim
1617  ===============================================================================
1618                       ##### Peripheral Control functions #####
1619  ===============================================================================
1620     [..]
1621     This subsection provides a set of functions allowing to:
1622 
1623     (+) Output clock to MCO pin.
1624     (+) Retrieve current clock frequencies.
1625     (+) Enable the Clock Security System.
1626 
1627 @endverbatim
1628   * @{
1629   */
1630 
1631 /**
1632   * @brief  Select the clock source to output on MCO pin(PA8).
1633   * @note   PA8 should be configured in alternate function mode.
1634   * @param  RCC_MCOx  specifies the output direction for the clock source.
1635   *          For STM32U5xx family this parameter can have only one value:
1636   *            @arg @ref RCC_MCO1  Clock source to output on MCO1 pin(PA8).
1637   * @param  RCC_MCOSource  specifies the clock source to output.
1638   *          This parameter can be one of the following values:
1639   *            @arg @ref RCC_MCO1SOURCE_NOCLOCK  MCO output disabled, no clock on MCO
1640   *            @arg @ref RCC_MCO1SOURCE_SYSCLK  system  clock selected as MCO source
1641   *            @arg @ref RCC_MCO1SOURCE_MSI  MSI clock selected as MCO source
1642   *            @arg @ref RCC_MCO1SOURCE_HSI  HSI clock selected as MCO source
1643   *            @arg @ref RCC_MCO1SOURCE_HSE  HSE clock selected as MCO source
1644   *            @arg @ref RCC_MCO1SOURCE_PLL1CLK  main PLL clock selected as MCO source
1645   *            @arg @ref RCC_MCO1SOURCE_LSI  LSI clock selected as MCO source
1646   *            @arg @ref RCC_MCO1SOURCE_LSE  LSE clock selected as MCO source
1647   *            @arg @ref RCC_MCO1SOURCE_HSI48  HSI48 clock selected as MCO source for devices with HSI48
1648   * @param  RCC_MCODiv  specifies the MCO prescaler.
1649   *          This parameter can be one of the following values:
1650   *            @arg @ref RCC_MCODIV_1  no division applied to MCO clock
1651   *            @arg @ref RCC_MCODIV_2  division by 2 applied to MCO clock
1652   *            @arg @ref RCC_MCODIV_4  division by 4 applied to MCO clock
1653   *            @arg @ref RCC_MCODIV_8  division by 8 applied to MCO clock
1654   *            @arg @ref RCC_MCODIV_16  division by 16 applied to MCO clock
1655   * @retval None
1656   */
HAL_RCC_MCOConfig(uint32_t RCC_MCOx,uint32_t RCC_MCOSource,uint32_t RCC_MCODiv)1657 void HAL_RCC_MCOConfig(uint32_t RCC_MCOx, uint32_t RCC_MCOSource, uint32_t RCC_MCODiv)
1658 {
1659   GPIO_InitTypeDef gpio_initstruct;
1660 
1661   /* Prevent unused argument(s) compilation warning */
1662   UNUSED(RCC_MCOx);
1663 
1664   /* Check the parameters */
1665   assert_param(IS_RCC_MCO(RCC_MCOx));
1666   assert_param(IS_RCC_MCODIV(RCC_MCODiv));
1667   assert_param(IS_RCC_MCO1SOURCE(RCC_MCOSource));
1668 
1669   /* MCO Clock Enable */
1670   MCO1_CLK_ENABLE();
1671 
1672   /* Configure the MCO1 pin in alternate function mode */
1673   gpio_initstruct.Pin = MCO1_PIN;
1674   gpio_initstruct.Mode = GPIO_MODE_AF_PP;
1675   gpio_initstruct.Speed = GPIO_SPEED_FREQ_HIGH;
1676   gpio_initstruct.Pull = GPIO_NOPULL;
1677   gpio_initstruct.Alternate = GPIO_AF0_MCO;
1678   HAL_GPIO_Init(MCO1_GPIO_PORT, &gpio_initstruct);
1679 
1680   /* Mask MCOSEL[] and MCOPRE[] bits then set MCO1 clock source and prescaler */
1681   MODIFY_REG(RCC->CFGR1, (RCC_CFGR1_MCOSEL | RCC_CFGR1_MCOPRE), (RCC_MCOSource | RCC_MCODiv));
1682 }
1683 
1684 /**
1685   * @brief  Return the SYSCLK frequency.
1686   * @note   The system frequency computed by this function is not the real
1687   *         frequency in the chip. It is calculated based on the predefined
1688   *         constant and the selected clock source:
1689   * @note     If SYSCLK source is MSI, function returns values based on MSI
1690   *             Value as defined by the MSI range.
1691   * @note     If SYSCLK source is HSI, function returns values based on HSI_VALUE(*)
1692   * @note     If SYSCLK source is HSE, function returns values based on HSE_VALUE(**)
1693   * @note     If SYSCLK source is PLL, function returns values based on HSE_VALUE(**),
1694   *           HSI_VALUE(*) or MSI Value multiplied/divided by the PLL factors.
1695   * @note     (*) HSI_VALUE is a constant defined in stm32u5xx_hal_conf.h file (default value
1696   *               16 MHz) but the real value may vary depending on the variations
1697   *               in voltage and temperature.
1698   * @note     (**) HSE_VALUE is a constant defined in stm32u5xx_hal_conf.h file (default value
1699   *                8 MHz), user has to ensure that HSE_VALUE is same as the real
1700   *                frequency of the crystal used. Otherwise, this function may
1701   *                have wrong result.
1702   * @note   The result of this function could be not correct when using fractional
1703   *         value for HSE crystal.
1704   * @note   This function can be used by the user application to compute the
1705   *         baudrate for the communication peripherals or configure other parameters.
1706   * @note   Each time SYSCLK changes, this function must be called to update the
1707   *         right SYSCLK value. Otherwise, any configuration based on this function will be incorrect.
1708   * @retval SYSCLK frequency
1709   */
HAL_RCC_GetSysClockFreq(void)1710 uint32_t HAL_RCC_GetSysClockFreq(void)
1711 {
1712   uint32_t msirange = 0U;
1713   uint32_t pllsource;
1714   uint32_t pllr;
1715   uint32_t pllm;
1716   uint32_t pllfracen;
1717   uint32_t sysclockfreq = 0U;
1718   uint32_t sysclk_source;
1719   uint32_t pll_oscsource;
1720   float_t fracn1;
1721   float_t pllvco;
1722 
1723   sysclk_source = __HAL_RCC_GET_SYSCLK_SOURCE();
1724   pll_oscsource = __HAL_RCC_GET_PLL_OSCSOURCE();
1725 
1726   if ((sysclk_source == RCC_SYSCLKSOURCE_STATUS_MSI) ||
1727       ((sysclk_source == RCC_SYSCLKSOURCE_STATUS_PLLCLK) && (pll_oscsource == RCC_PLLSOURCE_MSI)))
1728   {
1729     /* MSI or PLL with MSI source used as system clock source */
1730 
1731     /* Get SYSCLK source */
1732     if (READ_BIT(RCC->ICSCR1, RCC_ICSCR1_MSIRGSEL) == 0U)
1733     {
1734       /* MSISRANGE from RCC_CSR applies */
1735       msirange = (RCC->CSR & RCC_CSR_MSISSRANGE) >> RCC_CSR_MSISSRANGE_Pos;
1736     }
1737     else
1738     {
1739       /* MSIRANGE from RCC_CR applies */
1740       msirange = (RCC->ICSCR1 & RCC_ICSCR1_MSISRANGE) >> RCC_ICSCR1_MSISRANGE_Pos;
1741     }
1742     /*MSI frequency range in HZ*/
1743     msirange = MSIRangeTable[msirange];
1744 
1745     if (sysclk_source == RCC_SYSCLKSOURCE_STATUS_MSI)
1746     {
1747       /* MSI used as system clock source */
1748       sysclockfreq = msirange;
1749     }
1750   }
1751   else if (__HAL_RCC_GET_SYSCLK_SOURCE() == RCC_SYSCLKSOURCE_STATUS_HSI)
1752   {
1753     /* HSI used as system clock source */
1754     sysclockfreq = HSI_VALUE;
1755   }
1756   else if (sysclk_source == RCC_SYSCLKSOURCE_STATUS_HSE)
1757   {
1758     /* HSE used as system clock source */
1759     sysclockfreq = HSE_VALUE;
1760   }
1761   else
1762   {
1763     /* Nothing to do */
1764   }
1765 
1766   if (sysclk_source == RCC_SYSCLKSOURCE_STATUS_PLLCLK)
1767   {
1768     /* PLL used as system clock  source
1769        PLL_VCO = (HSE_VALUE or HSI_VALUE or MSI_VALUE/ PLLM) * PLLN
1770        SYSCLK = PLL_VCO / PLLR
1771     */
1772     pllsource = (RCC->PLL1CFGR & RCC_PLL1CFGR_PLL1SRC);
1773     pllm = ((RCC->PLL1CFGR & RCC_PLL1CFGR_PLL1M) >> RCC_PLL1CFGR_PLL1M_Pos) + 1U;
1774     pllfracen = ((RCC->PLL1CFGR & RCC_PLL1CFGR_PLL1FRACEN) >> RCC_PLL1CFGR_PLL1FRACEN_Pos);
1775     fracn1 = (float_t)(uint32_t)(pllfracen * ((RCC->PLL1FRACR & RCC_PLL1FRACR_PLL1FRACN) >> \
1776                                               RCC_PLL1FRACR_PLL1FRACN_Pos));
1777 
1778     switch (pllsource)
1779     {
1780       case RCC_PLLSOURCE_HSI:  /* HSI used as PLL clock source */
1781         pllvco = ((float_t)HSI_VALUE / (float_t)pllm) * ((float_t)(uint32_t)(RCC->PLL1DIVR & RCC_PLL1DIVR_PLL1N) + \
1782                                                          (fracn1 / (float_t)0x2000) + (float_t)1U);
1783         break;
1784 
1785       case RCC_PLLSOURCE_HSE:  /* HSE used as PLL clock source */
1786         pllvco = ((float_t)HSE_VALUE / (float_t)pllm) * ((float_t)(uint32_t)(RCC->PLL1DIVR & RCC_PLL1DIVR_PLL1N) + \
1787                                                          (fracn1 / (float_t)0x2000) + (float_t)1U);
1788         break;
1789 
1790       case RCC_PLLSOURCE_MSI:  /* MSI used as PLL clock source */
1791       default:
1792         pllvco = ((float_t) msirange / (float_t)pllm) * ((float_t)(uint32_t)(RCC->PLL1DIVR & RCC_PLL1DIVR_PLL1N) + \
1793                                                          (fracn1 / (float_t)0x2000) + (float_t)1U);
1794         break;
1795     }
1796 
1797     pllr = (((RCC->PLL1DIVR & RCC_PLL1DIVR_PLL1R) >> RCC_PLL1DIVR_PLL1R_Pos) + 1U);
1798     sysclockfreq = (uint32_t)(float_t)((float_t)pllvco / (float_t)pllr);
1799   }
1800 
1801   return sysclockfreq;
1802 }
1803 
1804 /**
1805   * @brief  Return the HCLK frequency.
1806   * @note   Each time HCLK changes, this function must be called to update the
1807   *         right HCLK value. Otherwise, any configuration based on this function will be incorrect.
1808   *
1809   * @note   The SystemCoreClock CMSIS variable is used to store System Clock Frequency.
1810   * @retval HCLK frequency in Hz
1811   */
HAL_RCC_GetHCLKFreq(void)1812 uint32_t HAL_RCC_GetHCLKFreq(void)
1813 {
1814   SystemCoreClock = HAL_RCC_GetSysClockFreq() >> AHBPrescTable[(RCC->CFGR2 & RCC_CFGR2_HPRE) >> RCC_CFGR2_HPRE_Pos];
1815   return SystemCoreClock;
1816 }
1817 
1818 /**
1819   * @brief  Return the PCLK1 frequency.
1820   * @note   Each time PCLK1 changes, this function must be called to update the
1821   *         right PCLK1 value. Otherwise, any configuration based on this function will be incorrect.
1822   * @retval PCLK1 frequency in Hz
1823   */
HAL_RCC_GetPCLK1Freq(void)1824 uint32_t HAL_RCC_GetPCLK1Freq(void)
1825 {
1826   /* Get HCLK source and Compute PCLK1 frequency ---------------------------*/
1827   return (HAL_RCC_GetHCLKFreq() >> APBPrescTable[(RCC->CFGR2 & RCC_CFGR2_PPRE1) >> RCC_CFGR2_PPRE1_Pos]);
1828 }
1829 
1830 /**
1831   * @brief  Return the PCLK2 frequency.
1832   * @note   Each time PCLK2 changes, this function must be called to update the
1833   *         right PCLK2 value. Otherwise, any configuration based on this function will be incorrect.
1834   * @retval PCLK2 frequency in Hz
1835   */
HAL_RCC_GetPCLK2Freq(void)1836 uint32_t HAL_RCC_GetPCLK2Freq(void)
1837 {
1838   /* Get HCLK source and Compute PCLK2 frequency ---------------------------*/
1839   return (HAL_RCC_GetHCLKFreq() >> APBPrescTable[(RCC->CFGR2 & RCC_CFGR2_PPRE2) >> RCC_CFGR2_PPRE2_Pos]);
1840 }
1841 
1842 /**
1843   * @brief  Return the PCLK3 frequency.
1844   * @note   Each time PCLK3 changes, this function must be called to update the
1845   *         right PCLK3 value. Otherwise, any configuration based on this function will be incorrect.
1846   * @retval PCLK3 frequency in Hz
1847   */
HAL_RCC_GetPCLK3Freq(void)1848 uint32_t HAL_RCC_GetPCLK3Freq(void)
1849 {
1850   /* Get HCLK source and Compute PCLK2 frequency ---------------------------*/
1851   return (HAL_RCC_GetHCLKFreq() >> APBPrescTable[(RCC->CFGR3 & RCC_CFGR3_PPRE3) >> RCC_CFGR3_PPRE3_Pos]);
1852 }
1853 /**
1854   * @brief  Get the pRCC_OscInitStruct according to the internal
1855   *         RCC configuration registers.
1856   * @param  pRCC_OscInitStruct  pointer to an RCC_OscInitTypeDef structure that
1857   *         will be configured.
1858   * @retval None
1859   */
HAL_RCC_GetOscConfig(RCC_OscInitTypeDef * pRCC_OscInitStruct)1860 void HAL_RCC_GetOscConfig(RCC_OscInitTypeDef  *pRCC_OscInitStruct)
1861 {
1862   uint32_t regval;
1863   uint32_t reg1val;
1864   uint32_t reg2val;
1865 
1866   /* Check the parameters */
1867   assert_param(pRCC_OscInitStruct != (void *)NULL);
1868 
1869   /* Set all possible values for the Oscillator type parameter ---------------*/
1870   pRCC_OscInitStruct->OscillatorType = RCC_OSCILLATORTYPE_HSE | RCC_OSCILLATORTYPE_HSI | RCC_OSCILLATORTYPE_MSI | \
1871                                        RCC_OSCILLATORTYPE_LSE | RCC_OSCILLATORTYPE_LSI | RCC_OSCILLATORTYPE_HSI48;
1872 
1873   /* Get Control register */
1874   regval = RCC->CR;
1875 
1876   /* Get the HSE configuration -----------------------------------------------*/
1877   pRCC_OscInitStruct->HSEState = (regval & (RCC_CR_HSEON | RCC_CR_HSEBYP | RCC_CR_HSEEXT));
1878 
1879   /* Get the MSI configuration -----------------------------------------------*/
1880   pRCC_OscInitStruct->MSIState = regval & RCC_CR_MSISON;
1881 
1882   reg1val = RCC->ICSCR1;
1883   reg2val = RCC->ICSCR2;
1884 
1885   pRCC_OscInitStruct->MSIClockRange = (uint32_t)((reg1val & RCC_ICSCR1_MSISRANGE));
1886   if (pRCC_OscInitStruct->MSIClockRange >= RCC_MSIRANGE_12)
1887   {
1888     pRCC_OscInitStruct->MSICalibrationValue = (uint32_t)((reg2val & RCC_ICSCR2_MSITRIM3) >> \
1889                                                          RCC_ICSCR2_MSITRIM3_Pos);
1890   }
1891   else if (pRCC_OscInitStruct->MSIClockRange >= RCC_MSIRANGE_8)
1892   {
1893     pRCC_OscInitStruct->MSICalibrationValue = (uint32_t)((reg2val & RCC_ICSCR2_MSITRIM2) >> \
1894                                                          RCC_ICSCR2_MSITRIM2_Pos);
1895   }
1896   else if (pRCC_OscInitStruct->MSIClockRange >= RCC_MSIRANGE_4)
1897   {
1898     pRCC_OscInitStruct->MSICalibrationValue = (uint32_t)((reg2val & RCC_ICSCR2_MSITRIM1) >> \
1899                                                          RCC_ICSCR2_MSITRIM1_Pos);
1900   }
1901   else /*if (pRCC_OscInitStruct->MSIClockRange >= RCC_MSIRANGE_0)*/
1902   {
1903     pRCC_OscInitStruct->MSICalibrationValue = (uint32_t)((reg2val & RCC_ICSCR2_MSITRIM0) >> \
1904                                                          RCC_ICSCR2_MSITRIM0_Pos);
1905   }
1906 
1907 
1908   /* Get the HSI configuration -----------------------------------------------*/
1909   pRCC_OscInitStruct->HSIState = regval & RCC_CR_HSION;
1910   pRCC_OscInitStruct->HSICalibrationValue = (uint32_t)((RCC->ICSCR3 & RCC_ICSCR3_HSITRIM) >> RCC_ICSCR3_HSITRIM_Pos);
1911 
1912   /* Get BDCR register */
1913   regval = RCC->BDCR;
1914 
1915   /* Get the LSE configuration -----------------------------------------------*/
1916   pRCC_OscInitStruct->LSEState = (regval & (RCC_BDCR_LSEON | RCC_BDCR_LSEBYP | RCC_BDCR_LSESYSEN));
1917 
1918   /* Get the LSI configuration -----------------------------------------------*/
1919   pRCC_OscInitStruct->LSIState = regval & RCC_BDCR_LSION;
1920 
1921   /* Get Control register */
1922   regval = RCC->CR;
1923 
1924   /* Get the HSI48 configuration ---------------------------------------------*/
1925   pRCC_OscInitStruct->HSI48State = regval & RCC_CR_HSI48ON;
1926 
1927   /* Get the PLL configuration -----------------------------------------------*/
1928   if ((regval & RCC_CR_PLL1ON) == RCC_CR_PLL1ON)
1929   {
1930     pRCC_OscInitStruct->PLL.PLLState = RCC_PLL_ON;
1931   }
1932   else
1933   {
1934     pRCC_OscInitStruct->PLL.PLLState = RCC_PLL_OFF;
1935   }
1936 
1937   reg1val = RCC->PLL1CFGR;
1938   reg2val = RCC->PLL1DIVR;
1939 
1940   pRCC_OscInitStruct->PLL.PLLSource = (uint32_t)(reg1val & RCC_PLL1CFGR_PLL1SRC);
1941   pRCC_OscInitStruct->PLL.PLLM = (uint32_t)(((reg1val & RCC_PLL1CFGR_PLL1M) >> RCC_PLL1CFGR_PLL1M_Pos) + 1U);
1942   pRCC_OscInitStruct->PLL.PLLN = (uint32_t)(((reg2val & RCC_PLL1DIVR_PLL1N) >> RCC_PLL1DIVR_PLL1N_Pos) + 1U);
1943   pRCC_OscInitStruct->PLL.PLLQ = (uint32_t)(((reg2val & RCC_PLL1DIVR_PLL1Q) >> RCC_PLL1DIVR_PLL1Q_Pos) + 1U);
1944   pRCC_OscInitStruct->PLL.PLLR = (uint32_t)(((reg2val & RCC_PLL1DIVR_PLL1R) >> RCC_PLL1DIVR_PLL1R_Pos) + 1U);
1945   pRCC_OscInitStruct->PLL.PLLP = (uint32_t)(((reg2val & RCC_PLL1DIVR_PLL1P) >> RCC_PLL1DIVR_PLL1P_Pos) + 1U);
1946   pRCC_OscInitStruct->PLL.PLLRGE = (uint32_t)((reg1val & RCC_PLL1CFGR_PLL1RGE));
1947   pRCC_OscInitStruct->PLL.PLLFRACN = (uint32_t)(((RCC->PLL1FRACR & RCC_PLL1FRACR_PLL1FRACN) >> \
1948                                                  RCC_PLL1FRACR_PLL1FRACN_Pos));
1949   pRCC_OscInitStruct->PLL.PLLMBOOST = (uint32_t)(((reg1val & RCC_PLL1CFGR_PLL1MBOOST) >> \
1950                                                   RCC_PLL1CFGR_PLL1MBOOST_Pos));
1951 }
1952 
1953 /**
1954   * @brief  Configure the pRCC_ClkInitStruct according to the internal
1955   *         RCC configuration registers.
1956   * @param  pRCC_ClkInitStruct  pointer to an RCC_ClkInitTypeDef structure that
1957   *         will be configured.
1958   * @param  pFLatency  Pointer on the Flash Latency.
1959   * @retval None
1960   */
HAL_RCC_GetClockConfig(RCC_ClkInitTypeDef * pRCC_ClkInitStruct,uint32_t * pFLatency)1961 void HAL_RCC_GetClockConfig(RCC_ClkInitTypeDef  *pRCC_ClkInitStruct, uint32_t *pFLatency)
1962 {
1963   /* Check the parameters */
1964   assert_param(pRCC_ClkInitStruct != (void *)NULL);
1965   assert_param(pFLatency != (void *)NULL);
1966 
1967   /* Set all possible values for the Clock type parameter --------------------*/
1968   pRCC_ClkInitStruct->ClockType = RCC_CLOCKTYPE_SYSCLK | RCC_CLOCKTYPE_HCLK | RCC_CLOCKTYPE_PCLK1 | \
1969                                   RCC_CLOCKTYPE_PCLK2 | RCC_CLOCKTYPE_PCLK3;
1970 
1971   /* Get the SYSCLK configuration --------------------------------------------*/
1972   pRCC_ClkInitStruct->SYSCLKSource = (uint32_t)(RCC->CFGR1 & RCC_CFGR1_SW);
1973 
1974   /* Get the HCLK configuration ----------------------------------------------*/
1975   pRCC_ClkInitStruct->AHBCLKDivider = (uint32_t)(RCC->CFGR2 & RCC_CFGR2_HPRE);
1976 
1977   /* Get the APB1 configuration ----------------------------------------------*/
1978   pRCC_ClkInitStruct->APB1CLKDivider = (uint32_t)(RCC->CFGR2 & RCC_CFGR2_PPRE1);
1979 
1980   /* Get the APB2 configuration ----------------------------------------------*/
1981   pRCC_ClkInitStruct->APB2CLKDivider = (uint32_t)((RCC->CFGR2 & RCC_CFGR2_PPRE2) >> 4);
1982 
1983   /* Get the APB3 configuration ----------------------------------------------*/
1984   pRCC_ClkInitStruct->APB3CLKDivider = (uint32_t)(RCC->CFGR3 & RCC_CFGR3_PPRE3);
1985 
1986   /* Get the Flash Wait State (Latency) configuration ------------------------*/
1987   *pFLatency = (uint32_t)(FLASH->ACR & FLASH_ACR_LATENCY);
1988 }
1989 
1990 /**
1991   * @brief  Get and clear reset flags
1992   * @note   Once reset flags are retrieved, this API is clearing them in order
1993   *         to isolate next reset reason.
1994   * @retval can be a combination of @ref RCC_Reset_Flag
1995   */
HAL_RCC_GetResetSource(void)1996 uint32_t HAL_RCC_GetResetSource(void)
1997 {
1998   uint32_t reset;
1999 
2000   /* Get all reset flags */
2001   reset = RCC->CSR & RCC_RESET_FLAG_ALL;
2002 
2003   /* Clear Reset flags */
2004   RCC->CSR |= RCC_CSR_RMVF;
2005 
2006   return reset;
2007 }
2008 
2009 /**
2010   * @brief  Enable the Clock Security System.
2011   * @note   If a failure is detected on the HSE oscillator clock, this oscillator
2012   *         is automatically disabled and an interrupt is generated to inform the
2013   *         software about the failure (Clock Security System Interrupt, CSSI),
2014   *         allowing the MCU to perform rescue operations. The CSSI is linked to
2015   *         the Cortex-M4 NMI (Non-Maskable Interrupt) exception vector.
2016   * @note   The Clock Security System can only be cleared by reset.
2017   * @retval None
2018   */
HAL_RCC_EnableCSS(void)2019 void HAL_RCC_EnableCSS(void)
2020 {
2021   SET_BIT(RCC->CR, RCC_CR_CSSON);
2022 }
2023 
2024 /**
2025   * @brief Handle the RCC Clock Security System interrupt request.
2026   * @note This API should be called under the NMI_Handler().
2027   * @retval None
2028   */
HAL_RCC_NMI_IRQHandler(void)2029 void HAL_RCC_NMI_IRQHandler(void)
2030 {
2031   /* Check RCC CSSF interrupt flag  */
2032   if (__HAL_RCC_GET_IT(RCC_IT_CSS))
2033   {
2034     /* Clear RCC CSS pending bit */
2035     __HAL_RCC_CLEAR_IT(RCC_IT_CSS);
2036 
2037     /* RCC Clock Security System interrupt user callback */
2038     HAL_RCC_CSSCallback();
2039   }
2040 }
2041 
2042 /**
2043   * @brief  RCC Clock Security System interrupt callback.
2044   * @retval none
2045   */
HAL_RCC_CSSCallback(void)2046 __weak void HAL_RCC_CSSCallback(void)
2047 {
2048   /* NOTE : This function should not be modified, when the callback is needed,
2049             the HAL_RCC_CSSCallback should be implemented in the user file
2050    */
2051 }
2052 
2053 /**
2054   * @}
2055   */
2056 /** @defgroup RCC_Exported_Functions_Group3 Attributes management functions
2057   *  @brief Attributes management functions.
2058   *
2059 @verbatim
2060  ===============================================================================
2061                        ##### RCC attributes functions #####
2062  ===============================================================================
2063 @endverbatim
2064   * @{
2065   */
2066 /**
2067   * @brief  Configure the RCC item attribute(s).
2068   * @note   Available attributes are to secure items and set RCC as privileged.
2069   * @note   As the privileged attributes concern either all secure or all
2070   *         non-secure RCC resources accesses and not each RCC individual items
2071   *         access attribute, the application must ensure that the privilege
2072   *         access attribute configurations are coherent amongst the security
2073   *         level set on RCC individual items so not to overwrite a previous
2074   *         more restricted access rule (consider either all secure and/or all
2075   *         non-secure RCC resources accesses by privileged-only transactions or
2076   *         privileged and unprivileged transactions).
2077   * @param  Item Item(s) to set attributes on.
2078   *         This parameter can be a one or a combination of @ref RCC_items
2079   * @param  Attributes specifies the RCC secure/privilege attributes.
2080   *         This parameter can be a value of @ref RCC_attributes
2081   * @retval None
2082   */
HAL_RCC_ConfigAttributes(uint32_t Item,uint32_t Attributes)2083 void HAL_RCC_ConfigAttributes(uint32_t Item, uint32_t Attributes)
2084 {
2085   /* Check the parameters */
2086   assert_param(IS_RCC_ITEM_ATTRIBUTES(Item));
2087   assert_param(IS_RCC_ATTRIBUTES(Attributes));
2088 
2089   switch (Attributes)
2090   {
2091 #if defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U)
2092     /* Secure Privilege attribute */
2093     case RCC_SEC_PRIV:
2094       SET_BIT(RCC->SECCFGR, Item);
2095       SET_BIT(RCC->PRIVCFGR, RCC_PRIVCFGR_SPRIV);
2096       break;
2097     /* Secure Non-Privilege attribute */
2098     case RCC_SEC_NPRIV:
2099       SET_BIT(RCC->SECCFGR, Item);
2100       CLEAR_BIT(RCC->PRIVCFGR, RCC_PRIVCFGR_SPRIV);
2101       break;
2102     /* Non-secure Privilege attribute */
2103     case RCC_NSEC_PRIV:
2104       CLEAR_BIT(RCC->SECCFGR, Item);
2105       SET_BIT(RCC->PRIVCFGR, RCC_PRIVCFGR_NSPRIV);
2106       break;
2107     /* Non-secure Non-Privilege attribute */
2108     case RCC_NSEC_NPRIV:
2109       CLEAR_BIT(RCC->SECCFGR, Item);
2110       CLEAR_BIT(RCC->PRIVCFGR, RCC_PRIVCFGR_NSPRIV);
2111       break;
2112 #else
2113     /* Non-secure Privilege attribute */
2114     case RCC_NSEC_PRIV:
2115       SET_BIT(RCC->PRIVCFGR, RCC_PRIVCFGR_NSPRIV);
2116       /* Prevent unused argument(s) compilation warning */
2117       UNUSED(Item);
2118       break;
2119     /* Non-secure Non-Privilege attribute */
2120     case RCC_NSEC_NPRIV:
2121       CLEAR_BIT(RCC->PRIVCFGR, RCC_PRIVCFGR_NSPRIV);
2122       /* Prevent unused argument(s) compilation warning */
2123       UNUSED(Item);
2124       break;
2125 #endif /* __ARM_FEATURE_CMSE */
2126     default:
2127       /* Nothing to do */
2128       break;
2129   }
2130 }
2131 /**
2132   * @}
2133   */
2134 
2135 /**
2136   * @brief  Get the attribute of a RCC item.
2137   * @note   Secure and non-secure attributes are only available from secure state
2138   *         when the system implements the security (TZEN=1)
2139   * @param  Item Single item to get secure/non-secure and privilege/non-privilege attribute from.
2140   *         This parameter can be a one value of @ref RCC_items except RCC_ALL.
2141   * @param  pAttributes pointer to return the attributes.
2142   * @retval HAL Status.
2143   */
HAL_RCC_GetConfigAttributes(uint32_t Item,uint32_t * pAttributes)2144 HAL_StatusTypeDef HAL_RCC_GetConfigAttributes(uint32_t Item, uint32_t *pAttributes)
2145 {
2146   uint32_t attributes;
2147 
2148   /* Check null pointer */
2149   if (pAttributes == NULL)
2150   {
2151     return HAL_ERROR;
2152   }
2153 
2154   /* Check the parameters */
2155   assert_param(IS_RCC_ITEM_ATTRIBUTES(Item));
2156 
2157 #if defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U)
2158 
2159   /* Check item security */
2160   if ((RCC->SECCFGR & Item) == Item)
2161   {
2162     /* Get Secure privileges attribute */
2163     attributes = ((RCC->PRIVCFGR & RCC_PRIVCFGR_SPRIV) == 0U) ? RCC_SEC_NPRIV : RCC_SEC_PRIV;
2164   }
2165   else
2166   {
2167     /* Get Non-Secure privileges attribute */
2168     attributes = ((RCC->PRIVCFGR & RCC_PRIVCFGR_NSPRIV) == 0U) ? RCC_NSEC_NPRIV : RCC_NSEC_PRIV;
2169   }
2170 #else
2171   /* Get Non-Secure privileges attribute */
2172   attributes = ((RCC->PRIVCFGR & RCC_PRIVCFGR_NSPRIV) == 0U) ? RCC_NSEC_NPRIV : RCC_NSEC_PRIV;
2173   /* Prevent unused argument(s) compilation warning */
2174   UNUSED(Item);
2175 
2176 #endif /* __ARM_FEATURE_CMSE */
2177 
2178   /* return value */
2179   *pAttributes = attributes;
2180 
2181   return HAL_OK;
2182 }
2183 /**
2184   * @}
2185   */
2186 
2187 /* Private function prototypes -----------------------------------------------*/
2188 /** @addtogroup RCC_Private_Functions
2189   * @{
2190   */
2191 /**
2192   * @brief  Update number of Flash wait states in line with MSI range and current
2193             voltage range.
2194   * @param  msirange  MSI range value from RCC_MSIRANGE_0 to RCC_MSIRANGE_15
2195   * @retval HAL status
2196   */
RCC_SetFlashLatencyFromMSIRange(uint32_t msirange)2197 static HAL_StatusTypeDef RCC_SetFlashLatencyFromMSIRange(uint32_t msirange)
2198 {
2199   uint32_t vos;
2200   uint32_t latency;  /* default value 0WS */
2201 
2202   if (__HAL_RCC_PWR_IS_CLK_ENABLED())
2203   {
2204     vos = HAL_PWREx_GetVoltageRange();
2205   }
2206   else
2207   {
2208     __HAL_RCC_PWR_CLK_ENABLE();
2209     vos = HAL_PWREx_GetVoltageRange();
2210     __HAL_RCC_PWR_CLK_DISABLE();
2211   }
2212 
2213   if ((vos == PWR_REGULATOR_VOLTAGE_SCALE1) || (vos == PWR_REGULATOR_VOLTAGE_SCALE2))
2214   {
2215 
2216     if (msirange < RCC_MSIRANGE_1)
2217     {
2218       /* MSI = 48Mhz */
2219       latency = FLASH_LATENCY_1; /* 1WS */
2220     }
2221     else
2222     {
2223       /*  MSI < 48Mhz */
2224       latency = FLASH_LATENCY_0; /* 0WS */
2225     }
2226   }
2227   else
2228   {
2229     if (msirange < RCC_MSIRANGE_1)
2230     {
2231       /* MSI = 48Mhz */
2232       if (vos == PWR_REGULATOR_VOLTAGE_SCALE3)
2233       {
2234         latency = FLASH_LATENCY_3; /* 3WS */
2235       }
2236       else
2237       {
2238         return HAL_ERROR;
2239       }
2240     }
2241     else
2242     {
2243       if (msirange > RCC_MSIRANGE_2)
2244       {
2245         if (vos == PWR_REGULATOR_VOLTAGE_SCALE4)
2246         {
2247           if (msirange > RCC_MSIRANGE_3)
2248           {
2249             latency = FLASH_LATENCY_0; /* 1WS */
2250           }
2251           else
2252           {
2253             latency = FLASH_LATENCY_1; /* 0WS */
2254           }
2255         }
2256         else
2257         {
2258           latency = FLASH_LATENCY_0; /* 0WS */
2259         }
2260       }
2261       else
2262       {
2263         if (msirange == RCC_MSIRANGE_1)
2264         {
2265           if (vos == PWR_REGULATOR_VOLTAGE_SCALE3)
2266           {
2267             latency = FLASH_LATENCY_1; /* 1WS */
2268           }
2269           else
2270           {
2271             latency = FLASH_LATENCY_2; /* 2WS */
2272           }
2273         }
2274         else
2275         {
2276           latency = FLASH_LATENCY_1; /* 1WS */
2277         }
2278       }
2279     }
2280   }
2281 
2282   __HAL_FLASH_SET_LATENCY(latency);
2283 
2284   /* Check that the new number of wait states is taken into account to access the Flash
2285   memory by reading the FLASH_ACR register */
2286   if ((FLASH->ACR & FLASH_ACR_LATENCY) != latency)
2287   {
2288     return HAL_ERROR;
2289   }
2290 
2291   return HAL_OK;
2292 }
2293 
2294 /**
2295   * @}
2296   */
2297 #endif /* HAL_RCC_MODULE_ENABLED */
2298 /**
2299   * @}
2300   */
2301 
2302 /**
2303   * @}
2304   */
2305