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