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