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
1381 /* Prevent unused argument(s) compilation warning */
1382 UNUSED(RCC_MCOx);
1383
1384 /* Check the parameters */
1385 assert_param(IS_RCC_MCODIV(RCC_MCODiv));
1386 assert_param(IS_RCC_MCO1SOURCE(RCC_MCOSource));
1387
1388 /* MCO Clock Enable */
1389 __MCO1_CLK_ENABLE();
1390
1391 /* Configure the MCO1 pin in alternate function mode */
1392 GPIO_InitStruct.Pin = MCO1_PIN;
1393 GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
1394 GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;
1395 GPIO_InitStruct.Pull = GPIO_NOPULL;
1396 GPIO_InitStruct.Alternate = GPIO_AF0_MCO;
1397 HAL_GPIO_Init(MCO1_GPIO_PORT, &GPIO_InitStruct);
1398
1399 /* Mask MCOSEL[] and MCOPRE[] bits then set MCO1 clock source and prescaler */
1400 MODIFY_REG(RCC->CFGR, (RCC_CFGR_MCOSEL | RCC_CFGR_MCOPRE), (RCC_MCOSource | RCC_MCODiv));
1401 }
1402
1403 /**
1404 * @brief Return the SYSCLK frequency.
1405 *
1406 * @note The system frequency computed by this function is not the real
1407 * frequency in the chip. It is calculated based on the predefined
1408 * constant and the selected clock source:
1409 * @note If SYSCLK source is MSI, function returns values based on MSI
1410 * Value as defined by the MSI range.
1411 * @note If SYSCLK source is HSI, function returns values based on HSI_VALUE(*)
1412 * @note If SYSCLK source is HSE, function returns values based on HSE_VALUE(**)
1413 * @note If SYSCLK source is PLL, function returns values based on HSE_VALUE(**),
1414 * HSI_VALUE(*) or MSI Value multiplied/divided by the PLL factors.
1415 * @note (*) HSI_VALUE is a constant defined in stm32l5xx_hal_conf.h file (default value
1416 * 16 MHz) but the real value may vary depending on the variations
1417 * in voltage and temperature.
1418 * @note (**) HSE_VALUE is a constant defined in stm32l5xx_hal_conf.h file (default value
1419 * 8 MHz), user has to ensure that HSE_VALUE is same as the real
1420 * frequency of the crystal used. Otherwise, this function may
1421 * have wrong result.
1422 *
1423 * @note The result of this function could be not correct when using fractional
1424 * value for HSE crystal.
1425 *
1426 * @note This function can be used by the user application to compute the
1427 * baudrate for the communication peripherals or configure other parameters.
1428 *
1429 * @note Each time SYSCLK changes, this function must be called to update the
1430 * right SYSCLK value. Otherwise, any configuration based on this function will be incorrect.
1431 *
1432 *
1433 * @retval SYSCLK frequency
1434 */
HAL_RCC_GetSysClockFreq(void)1435 uint32_t HAL_RCC_GetSysClockFreq(void)
1436 {
1437 uint32_t msirange = 0U, sysclockfreq = 0U;
1438 uint32_t pllvco, pllsource, pllr, pllm; /* no init needed */
1439 uint32_t sysclk_source, pll_oscsource;
1440
1441 sysclk_source = __HAL_RCC_GET_SYSCLK_SOURCE();
1442 pll_oscsource = __HAL_RCC_GET_PLL_OSCSOURCE();
1443
1444 if ((sysclk_source == RCC_SYSCLKSOURCE_STATUS_MSI) ||
1445 ((sysclk_source == RCC_SYSCLKSOURCE_STATUS_PLLCLK) && (pll_oscsource == RCC_PLLSOURCE_MSI)))
1446 {
1447 /* MSI or PLL with MSI source used as system clock source */
1448
1449 /* Get SYSCLK source */
1450 if (READ_BIT(RCC->CR, RCC_CR_MSIRGSEL) == 0U)
1451 {
1452 /* MSISRANGE from RCC_CSR applies */
1453 msirange = READ_BIT(RCC->CSR, RCC_CSR_MSISRANGE) >> RCC_CSR_MSISRANGE_Pos;
1454 }
1455 else
1456 {
1457 /* MSIRANGE from RCC_CR applies */
1458 msirange = READ_BIT(RCC->CR, RCC_CR_MSIRANGE) >> RCC_CR_MSIRANGE_Pos;
1459 }
1460 /*MSI frequency range in Hz*/
1461 msirange = MSIRangeTable[msirange];
1462
1463 if (sysclk_source == RCC_SYSCLKSOURCE_STATUS_MSI)
1464 {
1465 /* MSI used as system clock source */
1466 sysclockfreq = msirange;
1467 }
1468 }
1469 else if (sysclk_source == RCC_SYSCLKSOURCE_STATUS_HSI)
1470 {
1471 /* HSI used as system clock source */
1472 sysclockfreq = HSI_VALUE;
1473 }
1474 else if (sysclk_source == RCC_SYSCLKSOURCE_STATUS_HSE)
1475 {
1476 /* HSE used as system clock source */
1477 sysclockfreq = HSE_VALUE;
1478 }
1479 else
1480 {
1481 /* unexpected case: sysclockfreq at 0 */
1482 }
1483
1484 if (sysclk_source == RCC_SYSCLKSOURCE_STATUS_PLLCLK)
1485 {
1486 /* PLL used as system clock source */
1487
1488 /* PLL_VCO = (HSE_VALUE or HSI_VALUE or MSI_VALUE/ PLLM) * PLLN
1489 SYSCLK = PLL_VCO / PLLR
1490 */
1491 pllsource = (RCC->PLLCFGR & RCC_PLLCFGR_PLLSRC);
1492 pllm = ((RCC->PLLCFGR & RCC_PLLCFGR_PLLM) >> RCC_PLLCFGR_PLLM_Pos) + 1U ;
1493
1494 switch (pllsource)
1495 {
1496 case RCC_PLLSOURCE_HSI: /* HSI used as PLL clock source */
1497 pllvco = (HSI_VALUE / pllm) * ((RCC->PLLCFGR & RCC_PLLCFGR_PLLN) >> RCC_PLLCFGR_PLLN_Pos);
1498 break;
1499
1500 case RCC_PLLSOURCE_HSE: /* HSE used as PLL clock source */
1501 pllvco = (HSE_VALUE / pllm) * ((RCC->PLLCFGR & RCC_PLLCFGR_PLLN) >> RCC_PLLCFGR_PLLN_Pos);
1502 break;
1503
1504 case RCC_PLLSOURCE_MSI: /* MSI used as PLL clock source */
1505 default:
1506 pllvco = (msirange / pllm) * ((RCC->PLLCFGR & RCC_PLLCFGR_PLLN) >> RCC_PLLCFGR_PLLN_Pos);
1507 break;
1508 }
1509 pllr = (((RCC->PLLCFGR & RCC_PLLCFGR_PLLR) >> RCC_PLLCFGR_PLLR_Pos) + 1U) * 2U;
1510 sysclockfreq = pllvco / pllr;
1511 }
1512
1513 return sysclockfreq;
1514 }
1515
1516 /**
1517 * @brief Return the HCLK frequency.
1518 * @note Each time HCLK changes, this function must be called to update the
1519 * right HCLK value. Otherwise, any configuration based on this function will be incorrect.
1520 * @retval HCLK frequency in Hz
1521 */
HAL_RCC_GetHCLKFreq(void)1522 uint32_t HAL_RCC_GetHCLKFreq(void)
1523 {
1524 return (HAL_RCC_GetSysClockFreq() >> AHBPrescTable[(RCC->CFGR & RCC_CFGR_HPRE) >> RCC_CFGR_HPRE_Pos]);
1525 }
1526
1527 /**
1528 * @brief Return the PCLK1 frequency.
1529 * @note Each time PCLK1 changes, this function must be called to update the
1530 * right PCLK1 value. Otherwise, any configuration based on this function will be incorrect.
1531 * @retval PCLK1 frequency in Hz
1532 */
HAL_RCC_GetPCLK1Freq(void)1533 uint32_t HAL_RCC_GetPCLK1Freq(void)
1534 {
1535 /* Get HCLK source and Compute PCLK1 frequency ---------------------------*/
1536 return (HAL_RCC_GetHCLKFreq() >> APBPrescTable[(RCC->CFGR & RCC_CFGR_PPRE1) >> RCC_CFGR_PPRE1_Pos]);
1537 }
1538
1539 /**
1540 * @brief Return the PCLK2 frequency.
1541 * @note Each time PCLK2 changes, this function must be called to update the
1542 * right PCLK2 value. Otherwise, any configuration based on this function will be incorrect.
1543 * @retval PCLK2 frequency in Hz
1544 */
HAL_RCC_GetPCLK2Freq(void)1545 uint32_t HAL_RCC_GetPCLK2Freq(void)
1546 {
1547 /* Get HCLK source and Compute PCLK2 frequency ---------------------------*/
1548 return (HAL_RCC_GetHCLKFreq() >> APBPrescTable[(RCC->CFGR & RCC_CFGR_PPRE2) >> RCC_CFGR_PPRE2_Pos]);
1549 }
1550
1551 /**
1552 * @brief Return the oscillators and main PLL configuration in RCC_OscInitStruct
1553 * according to the internal RCC configuration registers.
1554 * @param RCC_OscInitStruct pointer to an RCC_OscInitTypeDef structure that
1555 * will be configured.
1556 * @retval None
1557 */
HAL_RCC_GetOscConfig(RCC_OscInitTypeDef * RCC_OscInitStruct)1558 void HAL_RCC_GetOscConfig(RCC_OscInitTypeDef *RCC_OscInitStruct)
1559 {
1560 /* Check the parameters */
1561 assert_param(RCC_OscInitStruct != (void *)NULL);
1562
1563 /* Set all possible values for the Oscillator type parameter ---------------*/
1564 RCC_OscInitStruct->OscillatorType = RCC_OSCILLATORTYPE_HSE | RCC_OSCILLATORTYPE_HSI | RCC_OSCILLATORTYPE_MSI | \
1565 RCC_OSCILLATORTYPE_LSE | RCC_OSCILLATORTYPE_LSI | RCC_OSCILLATORTYPE_HSI48;
1566
1567 /* Get the HSE configuration -----------------------------------------------*/
1568 if ((RCC->CR & RCC_CR_HSERDY) == RCC_CR_HSERDY)
1569 {
1570 if ((RCC->CR & RCC_CR_HSEBYP) == RCC_CR_HSEBYP)
1571 {
1572 RCC_OscInitStruct->HSEState = RCC_HSE_BYPASS;
1573 }
1574 else
1575 {
1576 RCC_OscInitStruct->HSEState = RCC_HSE_ON;
1577 }
1578 }
1579 else
1580 {
1581 RCC_OscInitStruct->HSEState = RCC_HSE_OFF;
1582 }
1583
1584 /* Get the MSI configuration -----------------------------------------------*/
1585 if ((RCC->CR & RCC_CR_MSIRDY) == RCC_CR_MSIRDY)
1586 {
1587 RCC_OscInitStruct->MSIState = RCC_MSI_ON;
1588 }
1589 else
1590 {
1591 RCC_OscInitStruct->MSIState = RCC_MSI_OFF;
1592 }
1593
1594 RCC_OscInitStruct->MSICalibrationValue = (uint32_t)((RCC->ICSCR & RCC_ICSCR_MSITRIM) >> RCC_ICSCR_MSITRIM_Pos);
1595 RCC_OscInitStruct->MSIClockRange = (uint32_t)((RCC->CR & RCC_CR_MSIRANGE));
1596
1597 /* Get the HSI configuration -----------------------------------------------*/
1598 if ((RCC->CR & RCC_CR_HSIRDY) == RCC_CR_HSIRDY)
1599 {
1600 RCC_OscInitStruct->HSIState = RCC_HSI_ON;
1601 }
1602 else
1603 {
1604 RCC_OscInitStruct->HSIState = RCC_HSI_OFF;
1605 }
1606
1607 RCC_OscInitStruct->HSICalibrationValue = (uint32_t)((RCC->ICSCR & RCC_ICSCR_HSITRIM) >> RCC_ICSCR_HSITRIM_Pos);
1608
1609 /* Get the LSE configuration -----------------------------------------------*/
1610 if ((RCC->BDCR & RCC_BDCR_LSERDY) == RCC_BDCR_LSERDY)
1611 {
1612 if ((RCC->BDCR & RCC_BDCR_LSEBYP) == RCC_BDCR_LSEBYP)
1613 {
1614 if ((RCC->BDCR & RCC_BDCR_LSESYSEN) == RCC_BDCR_LSESYSEN)
1615 {
1616 RCC_OscInitStruct->LSEState = RCC_LSE_BYPASS;
1617 }
1618 else
1619 {
1620 RCC_OscInitStruct->LSEState = RCC_LSE_BYPASS_RTC_ONLY;
1621 }
1622 }
1623 else
1624 {
1625 if ((RCC->BDCR & RCC_BDCR_LSESYSEN) == RCC_BDCR_LSESYSEN)
1626 {
1627 RCC_OscInitStruct->LSEState = RCC_LSE_ON;
1628 }
1629 else
1630 {
1631 RCC_OscInitStruct->LSEState = RCC_LSE_ON_RTC_ONLY;
1632 }
1633 }
1634 }
1635 else
1636 {
1637 RCC_OscInitStruct->LSEState = RCC_LSE_OFF;
1638 }
1639
1640 /* Get the LSI configuration -----------------------------------------------*/
1641 if ((RCC->CSR & RCC_CSR_LSIRDY) == RCC_CSR_LSIRDY)
1642 {
1643 RCC_OscInitStruct->LSIState = RCC_LSI_ON;
1644 }
1645 else
1646 {
1647 RCC_OscInitStruct->LSIState = RCC_LSI_OFF;
1648 }
1649
1650 if ((RCC->CSR & RCC_CSR_LSIPRE) == RCC_CSR_LSIPRE)
1651 {
1652 RCC_OscInitStruct->LSIDiv = RCC_LSI_DIV128;
1653 }
1654 else
1655 {
1656 RCC_OscInitStruct->LSIDiv = RCC_LSI_DIV1;
1657 }
1658
1659 /* Get the HSI48 configuration ---------------------------------------------*/
1660 if ((RCC->CRRCR & RCC_CRRCR_HSI48RDY) == RCC_CRRCR_HSI48RDY)
1661 {
1662 RCC_OscInitStruct->HSI48State = RCC_HSI48_ON;
1663 }
1664 else
1665 {
1666 RCC_OscInitStruct->HSI48State = RCC_HSI48_OFF;
1667 }
1668
1669 /* Get the PLL configuration -----------------------------------------------*/
1670 if ((RCC->CR & RCC_CR_PLLRDY) == RCC_CR_PLLRDY)
1671 {
1672 RCC_OscInitStruct->PLL.PLLState = RCC_PLL_ON;
1673 }
1674 else
1675 {
1676 RCC_OscInitStruct->PLL.PLLState = RCC_PLL_OFF;
1677 }
1678 RCC_OscInitStruct->PLL.PLLSource = (uint32_t)(RCC->PLLCFGR & RCC_PLLCFGR_PLLSRC);
1679 RCC_OscInitStruct->PLL.PLLM = (uint32_t)(((RCC->PLLCFGR & RCC_PLLCFGR_PLLM) >> RCC_PLLCFGR_PLLM_Pos) + 1U);
1680 RCC_OscInitStruct->PLL.PLLN = (uint32_t)((RCC->PLLCFGR & RCC_PLLCFGR_PLLN) >> RCC_PLLCFGR_PLLN_Pos);
1681 RCC_OscInitStruct->PLL.PLLQ = (uint32_t)((((RCC->PLLCFGR & RCC_PLLCFGR_PLLQ) >> RCC_PLLCFGR_PLLQ_Pos) + 1U) << 1U);
1682 RCC_OscInitStruct->PLL.PLLR = (uint32_t)((((RCC->PLLCFGR & RCC_PLLCFGR_PLLR) >> RCC_PLLCFGR_PLLR_Pos) + 1U) << 1U);
1683 RCC_OscInitStruct->PLL.PLLP = (uint32_t)((RCC->PLLCFGR & RCC_PLLCFGR_PLLPDIV) >> RCC_PLLCFGR_PLLPDIV_Pos);
1684 }
1685
1686 /**
1687 * @brief Return the clocks configuration in RCC_ClkInitStruct according to the
1688 * internal RCC configuration registers as well as the current FLASH latency.
1689 * @param RCC_ClkInitStruct pointer to an RCC_ClkInitTypeDef structure that
1690 * will be configured.
1691 * @param pFLatency Pointer on the Flash Latency.
1692 * @retval None
1693 */
HAL_RCC_GetClockConfig(RCC_ClkInitTypeDef * RCC_ClkInitStruct,uint32_t * pFLatency)1694 void HAL_RCC_GetClockConfig(RCC_ClkInitTypeDef *RCC_ClkInitStruct, uint32_t *pFLatency)
1695 {
1696 /* Check the parameters */
1697 assert_param(RCC_ClkInitStruct != (void *)NULL);
1698 assert_param(pFLatency != (void *)NULL);
1699
1700 /* Set all possible values for the Clock type parameter --------------------*/
1701 RCC_ClkInitStruct->ClockType = RCC_CLOCKTYPE_SYSCLK | RCC_CLOCKTYPE_HCLK | RCC_CLOCKTYPE_PCLK1 | RCC_CLOCKTYPE_PCLK2;
1702
1703 /* Get the SYSCLK configuration --------------------------------------------*/
1704 RCC_ClkInitStruct->SYSCLKSource = (uint32_t)(RCC->CFGR & RCC_CFGR_SW);
1705
1706 /* Get the HCLK configuration ----------------------------------------------*/
1707 RCC_ClkInitStruct->AHBCLKDivider = (uint32_t)(RCC->CFGR & RCC_CFGR_HPRE);
1708
1709 /* Get the APB1 configuration ----------------------------------------------*/
1710 RCC_ClkInitStruct->APB1CLKDivider = (uint32_t)(RCC->CFGR & RCC_CFGR_PPRE1);
1711
1712 /* Get the APB2 configuration ----------------------------------------------*/
1713 RCC_ClkInitStruct->APB2CLKDivider = (uint32_t)((RCC->CFGR & RCC_CFGR_PPRE2) >> 3U);
1714
1715 /* Get the Flash Wait State (Latency) configuration ------------------------*/
1716 *pFLatency = (uint32_t)(FLASH->ACR & FLASH_ACR_LATENCY);
1717 }
1718
1719 /**
1720 * @brief Enable the Clock Security System.
1721 * @note If a failure is detected on the HSE oscillator clock, this oscillator
1722 * is automatically disabled and an interrupt is generated to inform the
1723 * software about the failure (Clock Security System Interrupt, CSSI),
1724 * allowing the MCU to perform rescue operations. The CSSI is linked to
1725 * the Cortex-M33 NMI (Non-Maskable Interrupt) exception vector.
1726 * @note The Clock Security System can only be cleared by reset.
1727 * @retval None
1728 */
HAL_RCC_EnableCSS(void)1729 void HAL_RCC_EnableCSS(void)
1730 {
1731 SET_BIT(RCC->CR, RCC_CR_CSSON) ;
1732 }
1733
1734 /**
1735 * @brief Handle the RCC Clock Security System interrupt request.
1736 * @note This API should be called under the NMI_Handler().
1737 * @retval None
1738 */
HAL_RCC_NMI_IRQHandler(void)1739 void HAL_RCC_NMI_IRQHandler(void)
1740 {
1741 /* Check RCC CSSF interrupt flag */
1742 if (__HAL_RCC_GET_IT(RCC_IT_CSS))
1743 {
1744 /* RCC Clock Security System interrupt user callback */
1745 HAL_RCC_CSSCallback();
1746
1747 /* Clear RCC CSS pending bit */
1748 __HAL_RCC_CLEAR_IT(RCC_IT_CSS);
1749 }
1750 }
1751
1752 /**
1753 * @brief RCC Clock Security System interrupt callback.
1754 * @retval none
1755 */
HAL_RCC_CSSCallback(void)1756 __weak void HAL_RCC_CSSCallback(void)
1757 {
1758 /* NOTE : This function should not be modified, when the callback is needed,
1759 the HAL_RCC_CSSCallback should be implemented in the user file
1760 */
1761 }
1762
1763 /**
1764 * @brief Get and clear reset flags
1765 * @note Once reset flags are retrieved, this API is clearing them in order
1766 * to isolate next reset reason.
1767 * @retval can be a combination of @ref RCC_Reset_Flag
1768 */
HAL_RCC_GetResetSource(void)1769 uint32_t HAL_RCC_GetResetSource(void)
1770 {
1771 uint32_t reset;
1772
1773 /* Get all reset flags */
1774 reset = RCC->CSR & RCC_RESET_FLAG_ALL;
1775
1776 /* Clear Reset flags */
1777 RCC->CSR |= RCC_CSR_RMVF;
1778
1779 return reset;
1780 }
1781
1782 /**
1783 * @}
1784 */
1785
1786 /** @defgroup RCC_Exported_Functions_Group3 Attributes management functions
1787 * @brief Attributes management functions.
1788 *
1789 @verbatim
1790 ===============================================================================
1791 ##### RCC attributes functions #####
1792 ===============================================================================
1793
1794 @endverbatim
1795 * @{
1796 */
1797
1798 /**
1799 * @brief Configure the RCC item attribute(s).
1800 * @note Available attributes are to secure items and set RCC as privileged.
1801 * Default state is not secure and unprivileged access allowed.
1802 * @note Secure and non-secure attributes can only be set from the secure
1803 * state when the system implements the security (TZEN=1).
1804 * @note Security and privilege attributes can be set independently.
1805 * @param Item Item(s) to set attributes on.
1806 * This parameter can be a one or a combination of @ref RCC_items
1807 * @param Attributes can be one or a combination of the following values:
1808 * @arg @ref RCC_PRIV Privileged-only access
1809 * @arg @ref RCC_NPRIV Privileged/Non-privileged access
1810 * @arg @ref RCC_SEC Secure-only access
1811 * @arg @ref RCC_NSEC Secure/Non-secure access
1812 * @retval None
1813 */
HAL_RCC_ConfigAttributes(uint32_t Item,uint32_t Attributes)1814 void HAL_RCC_ConfigAttributes(uint32_t Item, uint32_t Attributes)
1815 {
1816 /* Check the parameters */
1817 assert_param(IS_RCC_ATTRIBUTES(Attributes));
1818
1819 /* Privilege/non-privilege attribute */
1820 if ((Attributes & RCC_PRIV) == RCC_PRIV)
1821 {
1822 SET_BIT(RCC->CR, RCC_CR_PRIV);
1823 }
1824 else if ((Attributes & RCC_NPRIV) == RCC_NPRIV)
1825 {
1826 CLEAR_BIT(RCC->CR, RCC_CR_PRIV);
1827 }
1828 else
1829 {
1830 /* do nothing */
1831 }
1832
1833 #if defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U)
1834
1835 /* Check the parameters */
1836 assert_param(IS_RCC_ITEMS_ATTRIBUTES(Item));
1837
1838 /* Secure/non-secure attribute */
1839 if ((Attributes & RCC_SEC) == RCC_SEC)
1840 {
1841 SET_BIT(RCC_S->SECCFGR, Item);
1842 }
1843 else if ((Attributes & RCC_NSEC) == RCC_NSEC)
1844 {
1845 CLEAR_BIT(RCC_S->SECCFGR, Item);
1846 }
1847 else
1848 {
1849 /* do nothing */
1850 }
1851
1852 #else
1853
1854 /* Prevent unused argument(s) compilation warning */
1855 UNUSED(Item);
1856
1857 #endif /* __ARM_FEATURE_CMSE */
1858 }
1859
1860 /**
1861 * @brief Get the attribute of a RCC item.
1862 * @note Secure and non-secure attributes are only available from secure state
1863 * when the system implements the security (TZEN=1)
1864 * @param Item Single item to get secure/non-secure and privilege/non-privilege attribute from.
1865 * @param pAttributes pointer to return the attributes value.
1866 * @retval HAL Status.
1867 */
HAL_RCC_GetConfigAttributes(uint32_t Item,uint32_t * pAttributes)1868 HAL_StatusTypeDef HAL_RCC_GetConfigAttributes(uint32_t Item, uint32_t *pAttributes)
1869 {
1870 uint32_t attributes;
1871
1872 /* Check null pointer */
1873 if (pAttributes == NULL)
1874 {
1875 return HAL_ERROR;
1876 }
1877
1878
1879 /* Get privilege or non-privilege attribute */
1880 if (READ_BIT(RCC->CR, RCC_CR_PRIV) != 0U)
1881 {
1882 attributes = RCC_PRIV;
1883 }
1884 else
1885 {
1886 attributes = RCC_NPRIV;
1887 }
1888
1889 #if defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U)
1890
1891 /* Check the parameters */
1892 assert_param(IS_RCC_ITEMS_ATTRIBUTES(Item));
1893
1894 /* Get the secure or non-secure attribute state */
1895 if ((RCC_S->SECCFGR & Item) == Item)
1896 {
1897 attributes |= RCC_SEC;
1898 }
1899 else
1900 {
1901 attributes |= RCC_NSEC;
1902 }
1903
1904 #else
1905
1906 /* Prevent unused argument(s) compilation warning */
1907 UNUSED(Item);
1908
1909 #endif /* __ARM_FEATURE_CMSE */
1910
1911 /* return value */
1912 *pAttributes = attributes;
1913
1914 return HAL_OK;
1915 }
1916
1917
1918 /**
1919 * @}
1920 */
1921
1922 /**
1923 * @}
1924 */
1925
1926 /* Private function prototypes -----------------------------------------------*/
1927 /** @addtogroup RCC_Private_Functions
1928 * @{
1929 */
1930 /**
1931 * @brief Update number of Flash wait states in line with MSI range and current
1932 voltage range.
1933 * @param msirange MSI range value from RCC_MSIRANGE_0 to RCC_MSIRANGE_11
1934 * @retval HAL status
1935 */
RCC_SetFlashLatencyFromMSIRange(uint32_t msirange)1936 static HAL_StatusTypeDef RCC_SetFlashLatencyFromMSIRange(uint32_t msirange)
1937 {
1938 uint32_t latency = FLASH_LATENCY_0; /* default value 0WS */
1939 uint32_t vos;
1940
1941 if (__HAL_RCC_PWR_IS_CLK_ENABLED())
1942 {
1943 vos = HAL_PWREx_GetVoltageRange();
1944 }
1945 else
1946 {
1947 __HAL_RCC_PWR_CLK_ENABLE();
1948 vos = HAL_PWREx_GetVoltageRange();
1949 __HAL_RCC_PWR_CLK_DISABLE();
1950 }
1951
1952 if ((vos == PWR_REGULATOR_VOLTAGE_SCALE0) || (vos == PWR_REGULATOR_VOLTAGE_SCALE1))
1953 {
1954 if (msirange > RCC_MSIRANGE_8)
1955 {
1956 /* MSI > 16Mhz */
1957 if (msirange > RCC_MSIRANGE_10)
1958 {
1959 /* MSI 48Mhz */
1960 latency = FLASH_LATENCY_2; /* 2WS */
1961 }
1962 else
1963 {
1964 /* MSI 24Mhz or 32Mhz */
1965 latency = FLASH_LATENCY_1; /* 1WS */
1966 }
1967 }
1968 /* else MSI <= 16Mhz default FLASH_LATENCY_0 0WS */
1969 }
1970 else
1971 {
1972 if (msirange > RCC_MSIRANGE_8)
1973 {
1974 /* MSI > 16Mhz */
1975 latency = FLASH_LATENCY_3; /* 3WS */
1976 }
1977 else
1978 {
1979 if (msirange == RCC_MSIRANGE_8)
1980 {
1981 /* MSI 16Mhz */
1982 latency = FLASH_LATENCY_2; /* 2WS */
1983 }
1984 else if (msirange == RCC_MSIRANGE_7)
1985 {
1986 /* MSI 8Mhz */
1987 latency = FLASH_LATENCY_1; /* 1WS */
1988 }
1989 else
1990 {
1991 /* MSI < 8Mhz default FLASH_LATENCY_0 0WS */
1992 }
1993 }
1994 }
1995
1996 __HAL_FLASH_SET_LATENCY(latency);
1997
1998 /* Check that the new number of wait states is taken into account to access the Flash
1999 memory by reading the FLASH_ACR register */
2000 if ((FLASH->ACR & FLASH_ACR_LATENCY) != latency)
2001 {
2002 return HAL_ERROR;
2003 }
2004
2005 return HAL_OK;
2006 }
2007
2008 /**
2009 * @brief Compute SYSCLK frequency based on PLL SYSCLK source.
2010 * @retval SYSCLK frequency
2011 */
RCC_GetSysClockFreqFromPLLSource(void)2012 static uint32_t RCC_GetSysClockFreqFromPLLSource(void)
2013 {
2014 uint32_t msirange, pllvco, pllsource, pllr, pllm, sysclockfreq; /* no init needed */
2015
2016 /* PLL_VCO = (HSE_VALUE or HSI_VALUE or MSI_VALUE/ PLLM) * PLLN
2017 SYSCLK = PLL_VCO / PLLR
2018 */
2019 pllsource = READ_BIT(RCC->PLLCFGR, RCC_PLLCFGR_PLLSRC);
2020 pllm = (READ_BIT(RCC->PLLCFGR, RCC_PLLCFGR_PLLM) >> RCC_PLLCFGR_PLLM_Pos) + 1U ;
2021
2022 switch (pllsource)
2023 {
2024 case RCC_PLLSOURCE_HSI: /* HSI used as PLL clock source */
2025 pllvco = (HSI_VALUE / pllm) * (READ_BIT(RCC->PLLCFGR, RCC_PLLCFGR_PLLN) >> RCC_PLLCFGR_PLLN_Pos);
2026 break;
2027
2028 case RCC_PLLSOURCE_HSE: /* HSE used as PLL clock source */
2029 pllvco = (HSE_VALUE / pllm) * (READ_BIT(RCC->PLLCFGR, RCC_PLLCFGR_PLLN) >> RCC_PLLCFGR_PLLN_Pos);
2030 break;
2031
2032 case RCC_PLLSOURCE_MSI: /* MSI used as PLL clock source */
2033 /* Get MSI range source */
2034 if(READ_BIT(RCC->CR, RCC_CR_MSIRGSEL) == 0U)
2035 { /* MSISRANGE from RCC_CSR applies */
2036 msirange = READ_BIT(RCC->CSR, RCC_CSR_MSISRANGE) >> RCC_CSR_MSISRANGE_Pos;
2037 }
2038 else
2039 { /* MSIRANGE from RCC_CR applies */
2040 msirange = READ_BIT(RCC->CR, RCC_CR_MSIRANGE) >> RCC_CR_MSIRANGE_Pos;
2041 }
2042 /*MSI frequency range in HZ*/
2043 pllvco = MSIRangeTable[msirange];
2044 break;
2045 default:
2046 /* unexpected */
2047 pllvco = 0;
2048 break;
2049 }
2050
2051 pllr = ((READ_BIT(RCC->PLLCFGR, RCC_PLLCFGR_PLLR) >> RCC_PLLCFGR_PLLR_Pos) + 1U) * 2U;
2052 sysclockfreq = pllvco / pllr;
2053
2054 return sysclockfreq;
2055 }
2056
2057 /**
2058 * @}
2059 */
2060
2061 #endif /* HAL_RCC_MODULE_ENABLED */
2062 /**
2063 * @}
2064 */
2065
2066 /**
2067 * @}
2068 */
2069
2070