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