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