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 * <h2><center>© Copyright (c) 2017 STMicroelectronics.
42 * All rights reserved.</center></h2>
43 *
44 * This software component is licensed by ST under BSD 3-Clause license,
45 * the "License"; You may not use this file except in compliance with the
46 * License. You may obtain a copy of the License at:
47 * opensource.org/licenses/BSD-3-Clause
48 *
49 ******************************************************************************
50 */
51
52 /* Includes ------------------------------------------------------------------*/
53 #include "stm32l4xx_hal.h"
54
55 /** @addtogroup STM32L4xx_HAL_Driver
56 * @{
57 */
58
59 /** @defgroup RCC RCC
60 * @brief RCC HAL module driver
61 * @{
62 */
63
64 #ifdef HAL_RCC_MODULE_ENABLED
65
66 /* Private typedef -----------------------------------------------------------*/
67 /* Private define ------------------------------------------------------------*/
68 /** @defgroup RCC_Private_Constants RCC Private Constants
69 * @{
70 */
71 #define HSE_TIMEOUT_VALUE HSE_STARTUP_TIMEOUT
72 #define HSI_TIMEOUT_VALUE 2U /* 2 ms (minimum Tick + 1) */
73 #define MSI_TIMEOUT_VALUE 2U /* 2 ms (minimum Tick + 1) */
74 #if defined(RCC_CSR_LSIPREDIV)
75 #define LSI_TIMEOUT_VALUE 17U /* 17 ms (16 ms starting time + 1) */
76 #else
77 #define LSI_TIMEOUT_VALUE 2U /* 2 ms (minimum Tick + 1) */
78 #endif /* RCC_CSR_LSIPREDIV */
79 #define HSI48_TIMEOUT_VALUE 2U /* 2 ms (minimum Tick + 1) */
80 #define PLL_TIMEOUT_VALUE 2U /* 2 ms (minimum Tick + 1) */
81 #define CLOCKSWITCH_TIMEOUT_VALUE 5000U /* 5 s */
82 /**
83 * @}
84 */
85
86 /* Private macro -------------------------------------------------------------*/
87 /** @defgroup RCC_Private_Macros RCC Private Macros
88 * @{
89 */
90 #define __MCO1_CLK_ENABLE() __HAL_RCC_GPIOA_CLK_ENABLE()
91 #define MCO1_GPIO_PORT GPIOA
92 #define MCO1_PIN GPIO_PIN_8
93
94 #define RCC_PLL_OSCSOURCE_CONFIG(__HAL_RCC_PLLSOURCE__) \
95 (MODIFY_REG(RCC->PLLCFGR, RCC_PLLCFGR_PLLSRC, (__HAL_RCC_PLLSOURCE__)))
96 /**
97 * @}
98 */
99
100 /* Private variables ---------------------------------------------------------*/
101
102 /* Private function prototypes -----------------------------------------------*/
103 /** @defgroup RCC_Private_Functions RCC Private Functions
104 * @{
105 */
106 static HAL_StatusTypeDef RCC_SetFlashLatencyFromMSIRange(uint32_t msirange);
107 #if defined(STM32L4P5xx) || defined(STM32L4Q5xx) || \
108 defined(STM32L4R5xx) || defined(STM32L4R7xx) || defined(STM32L4R9xx) || defined(STM32L4S5xx) || defined(STM32L4S7xx) || defined(STM32L4S9xx)
109 static uint32_t RCC_GetSysClockFreqFromPLLSource(void);
110 #endif
111 /**
112 * @}
113 */
114
115 /* Exported functions --------------------------------------------------------*/
116
117 /** @defgroup RCC_Exported_Functions RCC Exported Functions
118 * @{
119 */
120
121 /** @defgroup RCC_Exported_Functions_Group1 Initialization and de-initialization functions
122 * @brief Initialization and Configuration functions
123 *
124 @verbatim
125 ===============================================================================
126 ##### Initialization and de-initialization functions #####
127 ===============================================================================
128 [..]
129 This section provides functions allowing to configure the internal and external oscillators
130 (HSE, HSI, LSE, MSI, LSI, PLL, CSS and MCO) and the System busses clocks (SYSCLK, AHB, APB1
131 and APB2).
132
133 [..] Internal/external clock and PLL configuration
134 (+) HSI (high-speed internal): 16 MHz factory-trimmed RC used directly or through
135 the PLL as System clock source.
136
137 (+) MSI (Mutiple Speed Internal): Its frequency is software trimmable from 100KHZ to 48MHZ.
138 It can be used to generate the clock for the USB OTG FS (48 MHz).
139 The number of flash wait states is automatically adjusted when MSI range is updated with
140 HAL_RCC_OscConfig() and the MSI is used as System clock source.
141
142 (+) LSI (low-speed internal): 32 KHz low consumption RC used as IWDG and/or RTC
143 clock source.
144
145 (+) HSE (high-speed external): 4 to 48 MHz crystal oscillator used directly or
146 through the PLL as System clock source. Can be used also optionally as RTC clock source.
147
148 (+) LSE (low-speed external): 32.768 KHz oscillator used optionally as RTC clock source.
149
150 (+) PLL (clocked by HSI, HSE or MSI) providing up to three independent output clocks:
151 (++) The first output is used to generate the high speed system clock (up to 80MHz).
152 (++) The second output is used to generate the clock for the USB OTG FS (48 MHz),
153 the random analog generator (<=48 MHz) and the SDMMC1 (<= 48 MHz).
154 (++) The third output is used to generate an accurate clock to achieve
155 high-quality audio performance on SAI interface.
156
157 (+) PLLSAI1 (clocked by HSI, HSE or MSI) providing up to three independent output clocks:
158 (++) The first output is used to generate SAR ADC1 clock.
159 (++) The second output is used to generate the clock for the USB OTG FS (48 MHz),
160 the random analog generator (<=48 MHz) and the SDMMC1 (<= 48 MHz).
161 (++) The third output is used to generate an accurate clock to achieve
162 high-quality audio performance on SAI interface.
163
164 (+) PLLSAI2 (clocked by HSI, HSE or MSI) providing up to three independent output clocks:
165 (++) The first output is used to generate an accurate clock to achieve
166 high-quality audio performance on SAI interface.
167 (++) The second output is used to generate either SAR ADC2 clock if ADC2 is present
168 or LCD clock if LTDC is present.
169 (++) The third output is used to generate DSI clock if DSI is present.
170
171 (+) CSS (Clock security system): once enabled, if a HSE clock failure occurs
172 (HSE used directly or through PLL as System clock source), the System clock
173 is automatically switched to HSI and an interrupt is generated if enabled.
174 The interrupt is linked to the Cortex-M4 NMI (Non-Maskable Interrupt)
175 exception vector.
176
177 (+) MCO (microcontroller clock output): used to output MSI, LSI, HSI, LSE, HSE or
178 main PLL clock (through a configurable prescaler) on PA8 pin.
179
180 [..] System, AHB and APB busses clocks configuration
181 (+) Several clock sources can be used to drive the System clock (SYSCLK): MSI, HSI,
182 HSE and main PLL.
183 The AHB clock (HCLK) is derived from System clock through configurable
184 prescaler and used to clock the CPU, memory and peripherals mapped
185 on AHB bus (DMA, GPIO...). APB1 (PCLK1) and APB2 (PCLK2) clocks are derived
186 from AHB clock through configurable prescalers and used to clock
187 the peripherals mapped on these busses. You can use
188 "HAL_RCC_GetSysClockFreq()" function to retrieve the frequencies of these clocks.
189
190 -@- All the peripheral clocks are derived from the System clock (SYSCLK) except:
191
192 (+@) SAI: the SAI clock can be derived either from a specific PLL (PLLSAI1) or (PLLSAI2) or
193 from an external clock mapped on the SAI_CKIN pin.
194 You have to use HAL_RCCEx_PeriphCLKConfig() function to configure this clock.
195 (+@) RTC: the RTC clock can be derived either from the LSI, LSE or HSE clock
196 divided by 2 to 31.
197 You have to use __HAL_RCC_RTC_ENABLE() and HAL_RCCEx_PeriphCLKConfig() function
198 to configure this clock.
199 (+@) USB OTG FS, SDMMC1 and RNG: USB OTG FS requires a frequency equal to 48 MHz
200 to work correctly, while the SDMMC1 and RNG peripherals require a frequency
201 equal or lower than to 48 MHz. This clock is derived of the main PLL or PLLSAI1
202 through PLLQ divider. You have to enable the peripheral clock and use
203 HAL_RCCEx_PeriphCLKConfig() function to configure this clock.
204 (+@) IWDG clock which is always the LSI clock.
205
206
207 (+) The maximum frequency of the SYSCLK, HCLK, PCLK1 and PCLK2 is 80 MHz.
208 The clock source frequency should be adapted depending on the device voltage range
209 as listed in the Reference Manual "Clock source frequency versus voltage scaling" chapter.
210
211 @endverbatim
212
213 Table 1. HCLK clock frequency for other STM32L4 devices
214 +-------------------------------------------------------+
215 | Latency | HCLK clock frequency (MHz) |
216 | |-------------------------------------|
217 | | voltage range 1 | voltage range 2 |
218 | | 1.2 V | 1.0 V |
219 |-----------------|------------------|------------------|
220 |0WS(1 CPU cycles)| 0 < HCLK <= 16 | 0 < HCLK <= 6 |
221 |-----------------|------------------|------------------|
222 |1WS(2 CPU cycles)| 16 < HCLK <= 32 | 6 < HCLK <= 12 |
223 |-----------------|------------------|------------------|
224 |2WS(3 CPU cycles)| 32 < HCLK <= 48 | 12 < HCLK <= 18 |
225 |-----------------|------------------|------------------|
226 |3WS(4 CPU cycles)| 48 < HCLK <= 64 | 18 < HCLK <= 26 |
227 |-----------------|------------------|------------------|
228 |4WS(5 CPU cycles)| 64 < HCLK <= 80 | 18 < HCLK <= 26 |
229 +-------------------------------------------------------+
230
231 Table 2. HCLK clock frequency for STM32L4+ devices
232 +--------------------------------------------------------+
233 | Latency | HCLK clock frequency (MHz) |
234 | |--------------------------------------|
235 | | voltage range 1 | voltage range 2 |
236 | | 1.2 V | 1.0 V |
237 |-----------------|-------------------|------------------|
238 |0WS(1 CPU cycles)| 0 < HCLK <= 20 | 0 < HCLK <= 8 |
239 |-----------------|-------------------|------------------|
240 |1WS(2 CPU cycles)| 20 < HCLK <= 40 | 8 < HCLK <= 16 |
241 |-----------------|-------------------|------------------|
242 |2WS(3 CPU cycles)| 40 < HCLK <= 60 | 16 < HCLK <= 26 |
243 |-----------------|-------------------|------------------|
244 |3WS(4 CPU cycles)| 60 < HCLK <= 80 | 16 < HCLK <= 26 |
245 |-----------------|-------------------|------------------|
246 |4WS(5 CPU cycles)| 80 < HCLK <= 100 | 16 < HCLK <= 26 |
247 |-----------------|-------------------|------------------|
248 |5WS(6 CPU cycles)| 100 < HCLK <= 120 | 16 < HCLK <= 26 |
249 +--------------------------------------------------------+
250 * @{
251 */
252
253 /**
254 * @brief Reset the RCC clock configuration to the default reset state.
255 * @note The default reset state of the clock configuration is given below:
256 * - MSI ON and used as system clock source
257 * - HSE, HSI, PLL, PLLSAI1 and PLLSAI2 OFF
258 * - AHB, APB1 and APB2 prescalers set to 1.
259 * - CSS, MCO1 OFF
260 * - All interrupts disabled
261 * - All interrupt and reset flags cleared
262 * @note This function does not modify the configuration of the
263 * - Peripheral clock sources
264 * - LSI, LSE and RTC clocks (Backup domain)
265 * @retval HAL status
266 */
HAL_RCC_DeInit(void)267 HAL_StatusTypeDef HAL_RCC_DeInit(void)
268 {
269 uint32_t tickstart;
270
271 /* Reset to default System clock */
272 /* Set MSION bit */
273 SET_BIT(RCC->CR, RCC_CR_MSION);
274
275 /* Insure MSIRDY bit is set before writing default MSIRANGE value */
276 /* Get start tick */
277 tickstart = HAL_GetTick();
278
279 /* Wait till MSI is ready */
280 while(READ_BIT(RCC->CR, RCC_CR_MSIRDY) == 0U)
281 {
282 if((HAL_GetTick() - tickstart) > MSI_TIMEOUT_VALUE)
283 {
284 return HAL_TIMEOUT;
285 }
286 }
287
288 /* Set MSIRANGE default value */
289 MODIFY_REG(RCC->CR, RCC_CR_MSIRANGE, RCC_MSIRANGE_6);
290
291 /* Reset CFGR register (MSI is selected as system clock source) */
292 CLEAR_REG(RCC->CFGR);
293
294 /* Update the SystemCoreClock global variable for MSI as system clock source */
295 SystemCoreClock = MSI_VALUE;
296
297 /* Configure the source of time base considering new system clock settings */
298 if(HAL_InitTick(uwTickPrio) != HAL_OK)
299 {
300 return HAL_ERROR;
301 }
302
303 /* Insure MSI selected as system clock source */
304 /* Get start tick */
305 tickstart = HAL_GetTick();
306
307 /* Wait till system clock source is ready */
308 while(READ_BIT(RCC->CFGR, RCC_CFGR_SWS) != RCC_CFGR_SWS_MSI)
309 {
310 if((HAL_GetTick() - tickstart) > CLOCKSWITCH_TIMEOUT_VALUE)
311 {
312 return HAL_TIMEOUT;
313 }
314 }
315
316 /* Reset HSION, HSIKERON, HSIASFS, HSEON, HSECSSON, PLLON, PLLSAIxON bits */
317 #if defined(RCC_PLLSAI2_SUPPORT)
318
319 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);
320
321 #elif defined(RCC_PLLSAI1_SUPPORT)
322
323 CLEAR_BIT(RCC->CR, RCC_CR_HSEON | RCC_CR_HSION | RCC_CR_HSIKERON| RCC_CR_HSIASFS | RCC_CR_PLLON | RCC_CR_PLLSAI1ON);
324
325 #else
326
327 CLEAR_BIT(RCC->CR, RCC_CR_HSEON | RCC_CR_HSION | RCC_CR_HSIKERON| RCC_CR_HSIASFS | RCC_CR_PLLON);
328
329 #endif /* RCC_PLLSAI2_SUPPORT */
330
331 /* Insure PLLRDY, PLLSAI1RDY and PLLSAI2RDY (if present) are reset */
332 /* Get start tick */
333 tickstart = HAL_GetTick();
334
335 #if defined(RCC_PLLSAI2_SUPPORT)
336
337 while(READ_BIT(RCC->CR, RCC_CR_PLLRDY | RCC_CR_PLLSAI1RDY | RCC_CR_PLLSAI2RDY) != 0U)
338
339 #elif defined(RCC_PLLSAI1_SUPPORT)
340
341 while(READ_BIT(RCC->CR, RCC_CR_PLLRDY | RCC_CR_PLLSAI1RDY) != 0U)
342
343 #else
344
345 while(READ_BIT(RCC->CR, RCC_CR_PLLRDY) != 0U)
346
347 #endif
348 {
349 if((HAL_GetTick() - tickstart) > PLL_TIMEOUT_VALUE)
350 {
351 return HAL_TIMEOUT;
352 }
353 }
354
355 /* Reset PLLCFGR register */
356 CLEAR_REG(RCC->PLLCFGR);
357 SET_BIT(RCC->PLLCFGR, RCC_PLLCFGR_PLLN_4 );
358
359 #if defined(RCC_PLLSAI1_SUPPORT)
360
361 /* Reset PLLSAI1CFGR register */
362 CLEAR_REG(RCC->PLLSAI1CFGR);
363 SET_BIT(RCC->PLLSAI1CFGR, RCC_PLLSAI1CFGR_PLLSAI1N_4 );
364
365 #endif /* RCC_PLLSAI1_SUPPORT */
366
367 #if defined(RCC_PLLSAI2_SUPPORT)
368
369 /* Reset PLLSAI2CFGR register */
370 CLEAR_REG(RCC->PLLSAI2CFGR);
371 SET_BIT(RCC->PLLSAI2CFGR, RCC_PLLSAI2CFGR_PLLSAI2N_4 );
372
373 #endif /* RCC_PLLSAI2_SUPPORT */
374
375 /* Reset HSEBYP bit */
376 CLEAR_BIT(RCC->CR, RCC_CR_HSEBYP);
377
378 /* Disable all interrupts */
379 CLEAR_REG(RCC->CIER);
380
381 /* Clear all interrupt flags */
382 WRITE_REG(RCC->CICR, 0xFFFFFFFFU);
383
384 /* Clear all reset flags */
385 SET_BIT(RCC->CSR, RCC_CSR_RMVF);
386
387 return HAL_OK;
388 }
389
390 /**
391 * @brief Initialize the RCC Oscillators according to the specified parameters in the
392 * RCC_OscInitTypeDef.
393 * @param RCC_OscInitStruct pointer to an RCC_OscInitTypeDef structure that
394 * contains the configuration information for the RCC Oscillators.
395 * @note The PLL is not disabled when used as system clock.
396 * @note The PLL source is not updated when used as PLLSAI(s) clock source.
397 * @note Transitions LSE Bypass to LSE On and LSE On to LSE Bypass are not
398 * supported by this macro. User should request a transition to LSE Off
399 * first and then LSE On or LSE Bypass.
400 * @note Transition HSE Bypass to HSE On and HSE On to HSE Bypass are not
401 * supported by this macro. User should request a transition to HSE Off
402 * first and then HSE On or HSE Bypass.
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 __HAL_RCC_PLL_CONFIG(RCC_OscInitStruct->PLL.PLLSource,
944 RCC_OscInitStruct->PLL.PLLM,
945 RCC_OscInitStruct->PLL.PLLN,
946 #if defined(RCC_PLLP_SUPPORT)
947 RCC_OscInitStruct->PLL.PLLP,
948 #endif
949 RCC_OscInitStruct->PLL.PLLQ,
950 RCC_OscInitStruct->PLL.PLLR);
951
952 /* Enable the main PLL. */
953 __HAL_RCC_PLL_ENABLE();
954
955 /* Enable PLL System Clock output. */
956 __HAL_RCC_PLLCLKOUT_ENABLE(RCC_PLL_SYSCLK);
957
958 /* Get Start Tick*/
959 tickstart = HAL_GetTick();
960
961 /* Wait till PLL is ready */
962 while(READ_BIT(RCC->CR, RCC_CR_PLLRDY) == 0U)
963 {
964 if((HAL_GetTick() - tickstart) > PLL_TIMEOUT_VALUE)
965 {
966 return HAL_TIMEOUT;
967 }
968 }
969 }
970 }
971 else
972 {
973 /* PLL is already used as System core clock */
974 return HAL_ERROR;
975 }
976 }
977 else
978 {
979 /* PLL configuration is unchanged */
980 /* Re-enable PLL if it was disabled (ie. low power mode) */
981 if(READ_BIT(RCC->CR, RCC_CR_PLLRDY) == 0U)
982 {
983 /* Enable the main PLL. */
984 __HAL_RCC_PLL_ENABLE();
985
986 /* Enable PLL System Clock output. */
987 __HAL_RCC_PLLCLKOUT_ENABLE(RCC_PLL_SYSCLK);
988
989 /* Get Start Tick*/
990 tickstart = HAL_GetTick();
991
992 /* Wait till PLL is ready */
993 while(READ_BIT(RCC->CR, RCC_CR_PLLRDY) == 0U)
994 {
995 if((HAL_GetTick() - tickstart) > PLL_TIMEOUT_VALUE)
996 {
997 return HAL_TIMEOUT;
998 }
999 }
1000 }
1001 }
1002 }
1003 else
1004 {
1005 /* Check that PLL is not used as system clock or not */
1006 if(sysclk_source != RCC_CFGR_SWS_PLL)
1007 {
1008 /* Disable the main PLL. */
1009 __HAL_RCC_PLL_DISABLE();
1010
1011 /* Disable all PLL outputs to save power if no PLLs on */
1012 #if defined(RCC_PLLSAI1_SUPPORT) && defined(RCC_CR_PLLSAI2RDY)
1013 if(READ_BIT(RCC->CR, (RCC_CR_PLLSAI1RDY | RCC_CR_PLLSAI2RDY)) == 0U)
1014 {
1015 MODIFY_REG(RCC->PLLCFGR, RCC_PLLCFGR_PLLSRC, RCC_PLLSOURCE_NONE);
1016 }
1017 #elif defined(RCC_PLLSAI1_SUPPORT)
1018 if(READ_BIT(RCC->CR, RCC_CR_PLLSAI1RDY) == 0U)
1019 {
1020 MODIFY_REG(RCC->PLLCFGR, RCC_PLLCFGR_PLLSRC, RCC_PLLSOURCE_NONE);
1021 }
1022 #else
1023 MODIFY_REG(RCC->PLLCFGR, RCC_PLLCFGR_PLLSRC, RCC_PLLSOURCE_NONE);
1024 #endif /* RCC_PLLSAI1_SUPPORT && RCC_CR_PLLSAI2RDY */
1025
1026 #if defined(RCC_PLLSAI2_SUPPORT)
1027 __HAL_RCC_PLLCLKOUT_DISABLE(RCC_PLL_SYSCLK | RCC_PLL_48M1CLK | RCC_PLL_SAI3CLK);
1028 #elif defined(RCC_PLLSAI1_SUPPORT)
1029 __HAL_RCC_PLLCLKOUT_DISABLE(RCC_PLL_SYSCLK | RCC_PLL_48M1CLK | RCC_PLL_SAI2CLK);
1030 #else
1031 __HAL_RCC_PLLCLKOUT_DISABLE(RCC_PLL_SYSCLK | RCC_PLL_48M1CLK);
1032 #endif /* RCC_PLLSAI2_SUPPORT */
1033
1034 /* Get Start Tick*/
1035 tickstart = HAL_GetTick();
1036
1037 /* Wait till PLL is disabled */
1038 while(READ_BIT(RCC->CR, RCC_CR_PLLRDY) != 0U)
1039 {
1040 if((HAL_GetTick() - tickstart) > PLL_TIMEOUT_VALUE)
1041 {
1042 return HAL_TIMEOUT;
1043 }
1044 }
1045 }
1046 else
1047 {
1048 /* PLL is already used as System core clock */
1049 return HAL_ERROR;
1050 }
1051 }
1052 }
1053 return HAL_OK;
1054 }
1055
1056 /**
1057 * @brief Initialize the CPU, AHB and APB busses clocks according to the specified
1058 * parameters in the RCC_ClkInitStruct.
1059 * @param RCC_ClkInitStruct pointer to an RCC_OscInitTypeDef structure that
1060 * contains the configuration information for the RCC peripheral.
1061 * @param FLatency FLASH Latency
1062 * This parameter can be one of the following values:
1063 * @arg FLASH_LATENCY_0 FLASH 0 Latency cycle
1064 * @arg FLASH_LATENCY_1 FLASH 1 Latency cycle
1065 * @arg FLASH_LATENCY_2 FLASH 2 Latency cycles
1066 * @arg FLASH_LATENCY_3 FLASH 3 Latency cycles
1067 * @arg FLASH_LATENCY_4 FLASH 4 Latency cycles
1068 @if STM32L4S9xx
1069 * @arg FLASH_LATENCY_5 FLASH 5 Latency cycles
1070 * @arg FLASH_LATENCY_6 FLASH 6 Latency cycles
1071 * @arg FLASH_LATENCY_7 FLASH 7 Latency cycles
1072 * @arg FLASH_LATENCY_8 FLASH 8 Latency cycles
1073 * @arg FLASH_LATENCY_9 FLASH 9 Latency cycles
1074 * @arg FLASH_LATENCY_10 FLASH 10 Latency cycles
1075 * @arg FLASH_LATENCY_11 FLASH 11 Latency cycles
1076 * @arg FLASH_LATENCY_12 FLASH 12 Latency cycles
1077 * @arg FLASH_LATENCY_13 FLASH 13 Latency cycles
1078 * @arg FLASH_LATENCY_14 FLASH 14 Latency cycles
1079 * @arg FLASH_LATENCY_15 FLASH 15 Latency cycles
1080 @endif
1081 *
1082 * @note The SystemCoreClock CMSIS variable is used to store System Clock Frequency
1083 * and updated by HAL_RCC_GetHCLKFreq() function called within this function
1084 *
1085 * @note The MSI is used by default as system clock source after
1086 * startup from Reset, wake-up from STANDBY mode. After restart from Reset,
1087 * the MSI frequency is set to its default value 4 MHz.
1088 *
1089 * @note The HSI can be selected as system clock source after
1090 * from STOP modes or in case of failure of the HSE used directly or indirectly
1091 * as system clock (if the Clock Security System CSS is enabled).
1092 *
1093 * @note A switch from one clock source to another occurs only if the target
1094 * clock source is ready (clock stable after startup delay or PLL locked).
1095 * If a clock source which is not yet ready is selected, the switch will
1096 * occur when the clock source is ready.
1097 *
1098 * @note You can use HAL_RCC_GetClockConfig() function to know which clock is
1099 * currently used as system clock source.
1100 *
1101 * @note Depending on the device voltage range, the software has to set correctly
1102 * HPRE[3:0] bits to ensure that HCLK not exceed the maximum allowed frequency
1103 * (for more details refer to section above "Initialization/de-initialization functions")
1104 * @retval None
1105 */
HAL_RCC_ClockConfig(RCC_ClkInitTypeDef * RCC_ClkInitStruct,uint32_t FLatency)1106 HAL_StatusTypeDef HAL_RCC_ClockConfig(RCC_ClkInitTypeDef *RCC_ClkInitStruct, uint32_t FLatency)
1107 {
1108 uint32_t tickstart;
1109 #if defined(STM32L4P5xx) || defined(STM32L4Q5xx) || \
1110 defined(STM32L4R5xx) || defined(STM32L4R7xx) || defined(STM32L4R9xx) || defined(STM32L4S5xx) || defined(STM32L4S7xx) || defined(STM32L4S9xx)
1111 uint32_t hpre = RCC_SYSCLK_DIV1;
1112 #endif
1113 HAL_StatusTypeDef status;
1114
1115 /* Check Null pointer */
1116 if(RCC_ClkInitStruct == NULL)
1117 {
1118 return HAL_ERROR;
1119 }
1120
1121 /* Check the parameters */
1122 assert_param(IS_RCC_CLOCKTYPE(RCC_ClkInitStruct->ClockType));
1123 assert_param(IS_FLASH_LATENCY(FLatency));
1124
1125 /* To correctly read data from FLASH memory, the number of wait states (LATENCY)
1126 must be correctly programmed according to the frequency of the CPU clock
1127 (HCLK) and the supply voltage of the device. */
1128
1129 /* Increasing the number of wait states because of higher CPU frequency */
1130 if(FLatency > __HAL_FLASH_GET_LATENCY())
1131 {
1132 /* Program the new number of wait states to the LATENCY bits in the FLASH_ACR register */
1133 __HAL_FLASH_SET_LATENCY(FLatency);
1134
1135 /* Check that the new number of wait states is taken into account to access the Flash
1136 memory by reading the FLASH_ACR register */
1137 if(__HAL_FLASH_GET_LATENCY() != FLatency)
1138 {
1139 return HAL_ERROR;
1140 }
1141 }
1142
1143 /*------------------------- SYSCLK Configuration ---------------------------*/
1144 if(((RCC_ClkInitStruct->ClockType) & RCC_CLOCKTYPE_SYSCLK) == RCC_CLOCKTYPE_SYSCLK)
1145 {
1146 assert_param(IS_RCC_SYSCLKSOURCE(RCC_ClkInitStruct->SYSCLKSource));
1147
1148 /* PLL is selected as System Clock Source */
1149 if(RCC_ClkInitStruct->SYSCLKSource == RCC_SYSCLKSOURCE_PLLCLK)
1150 {
1151 /* Check the PLL ready flag */
1152 if(READ_BIT(RCC->CR, RCC_CR_PLLRDY) == 0U)
1153 {
1154 return HAL_ERROR;
1155 }
1156 #if defined(STM32L4P5xx) || defined(STM32L4Q5xx) || \
1157 defined(STM32L4R5xx) || defined(STM32L4R7xx) || defined(STM32L4R9xx) || defined(STM32L4S5xx) || defined(STM32L4S7xx) || defined(STM32L4S9xx)
1158 /* Undershoot management when selection PLL as SYSCLK source and frequency above 80Mhz */
1159 /* Compute target PLL output frequency */
1160 if(RCC_GetSysClockFreqFromPLLSource() > 80000000U)
1161 {
1162 if(READ_BIT(RCC->CFGR, RCC_CFGR_HPRE) == RCC_SYSCLK_DIV1)
1163 {
1164 /* Intermediate step with HCLK prescaler 2 necessary before to go over 80Mhz */
1165 MODIFY_REG(RCC->CFGR, RCC_CFGR_HPRE, RCC_SYSCLK_DIV2);
1166 hpre = RCC_SYSCLK_DIV2;
1167 }
1168 else if((((RCC_ClkInitStruct->ClockType) & RCC_CLOCKTYPE_HCLK) == RCC_CLOCKTYPE_HCLK) && (RCC_ClkInitStruct->AHBCLKDivider == RCC_SYSCLK_DIV1))
1169 {
1170 /* Intermediate step with HCLK prescaler 2 necessary before to go over 80Mhz */
1171 MODIFY_REG(RCC->CFGR, RCC_CFGR_HPRE, RCC_SYSCLK_DIV2);
1172 hpre = RCC_SYSCLK_DIV2;
1173 }
1174 else
1175 {
1176 /* nothing to do */
1177 }
1178 }
1179 #endif
1180 }
1181 else
1182 {
1183 /* HSE is selected as System Clock Source */
1184 if(RCC_ClkInitStruct->SYSCLKSource == RCC_SYSCLKSOURCE_HSE)
1185 {
1186 /* Check the HSE ready flag */
1187 if(READ_BIT(RCC->CR, RCC_CR_HSERDY) == 0U)
1188 {
1189 return HAL_ERROR;
1190 }
1191 }
1192 /* MSI is selected as System Clock Source */
1193 else if(RCC_ClkInitStruct->SYSCLKSource == RCC_SYSCLKSOURCE_MSI)
1194 {
1195 /* Check the MSI ready flag */
1196 if(READ_BIT(RCC->CR, RCC_CR_MSIRDY) == 0U)
1197 {
1198 return HAL_ERROR;
1199 }
1200 }
1201 /* HSI is selected as System Clock Source */
1202 else
1203 {
1204 /* Check the HSI ready flag */
1205 if(READ_BIT(RCC->CR, RCC_CR_HSIRDY) == 0U)
1206 {
1207 return HAL_ERROR;
1208 }
1209 }
1210 #if defined(STM32L4P5xx) || defined(STM32L4Q5xx) || \
1211 defined(STM32L4R5xx) || defined(STM32L4R7xx) || defined(STM32L4R9xx) || defined(STM32L4S5xx) || defined(STM32L4S7xx) || defined(STM32L4S9xx)
1212 /* Overshoot management when going down from PLL as SYSCLK source and frequency above 80Mhz */
1213 if(HAL_RCC_GetSysClockFreq() > 80000000U)
1214 {
1215 /* Intermediate step with HCLK prescaler 2 necessary before to go under 80Mhz */
1216 MODIFY_REG(RCC->CFGR, RCC_CFGR_HPRE, RCC_SYSCLK_DIV2);
1217 hpre = RCC_SYSCLK_DIV2;
1218 }
1219 #endif
1220
1221 }
1222
1223 MODIFY_REG(RCC->CFGR, RCC_CFGR_SW, RCC_ClkInitStruct->SYSCLKSource);
1224
1225 /* Get Start Tick*/
1226 tickstart = HAL_GetTick();
1227
1228 while(__HAL_RCC_GET_SYSCLK_SOURCE() != (RCC_ClkInitStruct->SYSCLKSource << RCC_CFGR_SWS_Pos))
1229 {
1230 if((HAL_GetTick() - tickstart) > CLOCKSWITCH_TIMEOUT_VALUE)
1231 {
1232 return HAL_TIMEOUT;
1233 }
1234 }
1235 }
1236
1237 /*-------------------------- HCLK Configuration --------------------------*/
1238 if(((RCC_ClkInitStruct->ClockType) & RCC_CLOCKTYPE_HCLK) == RCC_CLOCKTYPE_HCLK)
1239 {
1240 assert_param(IS_RCC_HCLK(RCC_ClkInitStruct->AHBCLKDivider));
1241 MODIFY_REG(RCC->CFGR, RCC_CFGR_HPRE, RCC_ClkInitStruct->AHBCLKDivider);
1242 }
1243 #if defined(STM32L4P5xx) || defined(STM32L4Q5xx) || \
1244 defined(STM32L4R5xx) || defined(STM32L4R7xx) || defined(STM32L4R9xx) || defined(STM32L4S5xx) || defined(STM32L4S7xx) || defined(STM32L4S9xx)
1245 else
1246 {
1247 /* Is intermediate HCLK prescaler 2 applied internally, complete with HCLK prescaler 1 */
1248 if(hpre == RCC_SYSCLK_DIV2)
1249 {
1250 MODIFY_REG(RCC->CFGR, RCC_CFGR_HPRE, RCC_SYSCLK_DIV1);
1251 }
1252 }
1253 #endif
1254
1255 /* Decreasing the number of wait states because of lower CPU frequency */
1256 if(FLatency < __HAL_FLASH_GET_LATENCY())
1257 {
1258 /* Program the new number of wait states to the LATENCY bits in the FLASH_ACR register */
1259 __HAL_FLASH_SET_LATENCY(FLatency);
1260
1261 /* Check that the new number of wait states is taken into account to access the Flash
1262 memory by reading the FLASH_ACR register */
1263 if(__HAL_FLASH_GET_LATENCY() != FLatency)
1264 {
1265 return HAL_ERROR;
1266 }
1267 }
1268
1269 /*-------------------------- PCLK1 Configuration ---------------------------*/
1270 if(((RCC_ClkInitStruct->ClockType) & RCC_CLOCKTYPE_PCLK1) == RCC_CLOCKTYPE_PCLK1)
1271 {
1272 assert_param(IS_RCC_PCLK(RCC_ClkInitStruct->APB1CLKDivider));
1273 MODIFY_REG(RCC->CFGR, RCC_CFGR_PPRE1, RCC_ClkInitStruct->APB1CLKDivider);
1274 }
1275
1276 /*-------------------------- PCLK2 Configuration ---------------------------*/
1277 if(((RCC_ClkInitStruct->ClockType) & RCC_CLOCKTYPE_PCLK2) == RCC_CLOCKTYPE_PCLK2)
1278 {
1279 assert_param(IS_RCC_PCLK(RCC_ClkInitStruct->APB2CLKDivider));
1280 MODIFY_REG(RCC->CFGR, RCC_CFGR_PPRE2, ((RCC_ClkInitStruct->APB2CLKDivider) << 3U));
1281 }
1282
1283 /* Update the SystemCoreClock global variable */
1284 SystemCoreClock = HAL_RCC_GetSysClockFreq() >> (AHBPrescTable[READ_BIT(RCC->CFGR, RCC_CFGR_HPRE) >> RCC_CFGR_HPRE_Pos] & 0x1FU);
1285
1286 /* Configure the source of time base considering new system clocks settings*/
1287 status = HAL_InitTick(uwTickPrio);
1288
1289 return status;
1290 }
1291
1292 /**
1293 * @}
1294 */
1295
1296 /** @defgroup RCC_Exported_Functions_Group2 Peripheral Control functions
1297 * @brief RCC clocks control functions
1298 *
1299 @verbatim
1300 ===============================================================================
1301 ##### Peripheral Control functions #####
1302 ===============================================================================
1303 [..]
1304 This subsection provides a set of functions allowing to:
1305
1306 (+) Ouput clock to MCO pin.
1307 (+) Retrieve current clock frequencies.
1308 (+) Enable the Clock Security System.
1309
1310 @endverbatim
1311 * @{
1312 */
1313
1314 /**
1315 * @brief Select the clock source to output on MCO pin(PA8).
1316 * @note PA8 should be configured in alternate function mode.
1317 * @param RCC_MCOx specifies the output direction for the clock source.
1318 * For STM32L4xx family this parameter can have only one value:
1319 * @arg @ref RCC_MCO1 Clock source to output on MCO1 pin(PA8).
1320 * @param RCC_MCOSource specifies the clock source to output.
1321 * This parameter can be one of the following values:
1322 * @arg @ref RCC_MCO1SOURCE_NOCLOCK MCO output disabled, no clock on MCO
1323 * @arg @ref RCC_MCO1SOURCE_SYSCLK system clock selected as MCO source
1324 * @arg @ref RCC_MCO1SOURCE_MSI MSI clock selected as MCO source
1325 * @arg @ref RCC_MCO1SOURCE_HSI HSI clock selected as MCO source
1326 * @arg @ref RCC_MCO1SOURCE_HSE HSE clock selected as MCO sourcee
1327 * @arg @ref RCC_MCO1SOURCE_PLLCLK main PLL clock selected as MCO source
1328 * @arg @ref RCC_MCO1SOURCE_LSI LSI clock selected as MCO source
1329 * @arg @ref RCC_MCO1SOURCE_LSE LSE clock selected as MCO source
1330 @if STM32L443xx
1331 * @arg @ref RCC_MCO1SOURCE_HSI48 HSI48 clock selected as MCO source for devices with HSI48
1332 @endif
1333 * @param RCC_MCODiv specifies the MCO prescaler.
1334 * This parameter can be one of the following values:
1335 * @arg @ref RCC_MCODIV_1 no division applied to MCO clock
1336 * @arg @ref RCC_MCODIV_2 division by 2 applied to MCO clock
1337 * @arg @ref RCC_MCODIV_4 division by 4 applied to MCO clock
1338 * @arg @ref RCC_MCODIV_8 division by 8 applied to MCO clock
1339 * @arg @ref RCC_MCODIV_16 division by 16 applied to MCO clock
1340 * @retval None
1341 */
HAL_RCC_MCOConfig(uint32_t RCC_MCOx,uint32_t RCC_MCOSource,uint32_t RCC_MCODiv)1342 void HAL_RCC_MCOConfig( uint32_t RCC_MCOx, uint32_t RCC_MCOSource, uint32_t RCC_MCODiv)
1343 {
1344 GPIO_InitTypeDef GPIO_InitStruct;
1345
1346 /* Check the parameters */
1347 assert_param(IS_RCC_MCO(RCC_MCOx));
1348 assert_param(IS_RCC_MCODIV(RCC_MCODiv));
1349 assert_param(IS_RCC_MCO1SOURCE(RCC_MCOSource));
1350
1351 /* Prevent unused argument(s) compilation warning if no assert_param check */
1352 UNUSED(RCC_MCOx);
1353
1354 /* MCO Clock Enable */
1355 __MCO1_CLK_ENABLE();
1356
1357 /* Configue the MCO1 pin in alternate function mode */
1358 GPIO_InitStruct.Pin = MCO1_PIN;
1359 GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
1360 GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;
1361 GPIO_InitStruct.Pull = GPIO_NOPULL;
1362 GPIO_InitStruct.Alternate = GPIO_AF0_MCO;
1363 HAL_GPIO_Init(MCO1_GPIO_PORT, &GPIO_InitStruct);
1364
1365 /* Mask MCOSEL[] and MCOPRE[] bits then set MCO1 clock source and prescaler */
1366 MODIFY_REG(RCC->CFGR, (RCC_CFGR_MCOSEL | RCC_CFGR_MCOPRE), (RCC_MCOSource | RCC_MCODiv ));
1367 }
1368
1369 /**
1370 * @brief Return the SYSCLK frequency.
1371 *
1372 * @note The system frequency computed by this function is not the real
1373 * frequency in the chip. It is calculated based on the predefined
1374 * constant and the selected clock source:
1375 * @note If SYSCLK source is MSI, function returns values based on MSI
1376 * Value as defined by the MSI range.
1377 * @note If SYSCLK source is HSI, function returns values based on HSI_VALUE(*)
1378 * @note If SYSCLK source is HSE, function returns values based on HSE_VALUE(**)
1379 * @note If SYSCLK source is PLL, function returns values based on HSE_VALUE(**),
1380 * HSI_VALUE(*) or MSI Value multiplied/divided by the PLL factors.
1381 * @note (*) HSI_VALUE is a constant defined in stm32l4xx_hal_conf.h file (default value
1382 * 16 MHz) but the real value may vary depending on the variations
1383 * in voltage and temperature.
1384 * @note (**) HSE_VALUE is a constant defined in stm32l4xx_hal_conf.h file (default value
1385 * 8 MHz), user has to ensure that HSE_VALUE is same as the real
1386 * frequency of the crystal used. Otherwise, this function may
1387 * have wrong result.
1388 *
1389 * @note The result of this function could be not correct when using fractional
1390 * value for HSE crystal.
1391 *
1392 * @note This function can be used by the user application to compute the
1393 * baudrate for the communication peripherals or configure other parameters.
1394 *
1395 * @note Each time SYSCLK changes, this function must be called to update the
1396 * right SYSCLK value. Otherwise, any configuration based on this function will be incorrect.
1397 *
1398 *
1399 * @retval SYSCLK frequency
1400 */
HAL_RCC_GetSysClockFreq(void)1401 uint32_t HAL_RCC_GetSysClockFreq(void)
1402 {
1403 uint32_t msirange = 0U, sysclockfreq = 0U;
1404 uint32_t pllvco, pllsource, pllr, pllm; /* no init needed */
1405 uint32_t sysclk_source, pll_oscsource;
1406
1407 sysclk_source = __HAL_RCC_GET_SYSCLK_SOURCE();
1408 pll_oscsource = __HAL_RCC_GET_PLL_OSCSOURCE();
1409
1410 if((sysclk_source == RCC_CFGR_SWS_MSI) ||
1411 ((sysclk_source == RCC_CFGR_SWS_PLL) && (pll_oscsource == RCC_PLLSOURCE_MSI)))
1412 {
1413 /* MSI or PLL with MSI source used as system clock source */
1414
1415 /* Get SYSCLK source */
1416 if(READ_BIT(RCC->CR, RCC_CR_MSIRGSEL) == 0U)
1417 { /* MSISRANGE from RCC_CSR applies */
1418 msirange = READ_BIT(RCC->CSR, RCC_CSR_MSISRANGE) >> RCC_CSR_MSISRANGE_Pos;
1419 }
1420 else
1421 { /* MSIRANGE from RCC_CR applies */
1422 msirange = READ_BIT(RCC->CR, RCC_CR_MSIRANGE) >> RCC_CR_MSIRANGE_Pos;
1423 }
1424 /*MSI frequency range in HZ*/
1425 msirange = MSIRangeTable[msirange];
1426
1427 if(sysclk_source == RCC_CFGR_SWS_MSI)
1428 {
1429 /* MSI used as system clock source */
1430 sysclockfreq = msirange;
1431 }
1432 }
1433 else if(sysclk_source == RCC_CFGR_SWS_HSI)
1434 {
1435 /* HSI used as system clock source */
1436 sysclockfreq = HSI_VALUE;
1437 }
1438 else if(sysclk_source == RCC_CFGR_SWS_HSE)
1439 {
1440 /* HSE used as system clock source */
1441 sysclockfreq = HSE_VALUE;
1442 }
1443 else
1444 {
1445 /* unexpected case: sysclockfreq at 0 */
1446 }
1447
1448 if(sysclk_source == RCC_CFGR_SWS_PLL)
1449 {
1450 /* PLL used as system clock source */
1451
1452 /* PLL_VCO = (HSE_VALUE or HSI_VALUE or MSI_VALUE) * PLLN / PLLM
1453 SYSCLK = PLL_VCO / PLLR
1454 */
1455 pllsource = READ_BIT(RCC->PLLCFGR, RCC_PLLCFGR_PLLSRC);
1456
1457 switch (pllsource)
1458 {
1459 case RCC_PLLSOURCE_HSI: /* HSI used as PLL clock source */
1460 pllvco = HSI_VALUE;
1461 break;
1462
1463 case RCC_PLLSOURCE_HSE: /* HSE used as PLL clock source */
1464 pllvco = HSE_VALUE;
1465 break;
1466
1467 case RCC_PLLSOURCE_MSI: /* MSI used as PLL clock source */
1468 default:
1469 pllvco = msirange;
1470 break;
1471 }
1472 pllm = (READ_BIT(RCC->PLLCFGR, RCC_PLLCFGR_PLLM) >> RCC_PLLCFGR_PLLM_Pos) + 1U ;
1473 pllvco = (pllvco * (READ_BIT(RCC->PLLCFGR, RCC_PLLCFGR_PLLN) >> RCC_PLLCFGR_PLLN_Pos)) / pllm;
1474 pllr = ((READ_BIT(RCC->PLLCFGR, RCC_PLLCFGR_PLLR) >> RCC_PLLCFGR_PLLR_Pos) + 1U ) * 2U;
1475 sysclockfreq = pllvco / pllr;
1476 }
1477
1478 return sysclockfreq;
1479 }
1480
1481 /**
1482 * @brief Return the HCLK frequency.
1483 * @note Each time HCLK changes, this function must be called to update the
1484 * right HCLK value. Otherwise, any configuration based on this function will be incorrect.
1485 *
1486 * @note The SystemCoreClock CMSIS variable is used to store System Clock Frequency.
1487 * @retval HCLK frequency in Hz
1488 */
HAL_RCC_GetHCLKFreq(void)1489 uint32_t HAL_RCC_GetHCLKFreq(void)
1490 {
1491 return SystemCoreClock;
1492 }
1493
1494 /**
1495 * @brief Return the PCLK1 frequency.
1496 * @note Each time PCLK1 changes, this function must be called to update the
1497 * right PCLK1 value. Otherwise, any configuration based on this function will be incorrect.
1498 * @retval PCLK1 frequency in Hz
1499 */
HAL_RCC_GetPCLK1Freq(void)1500 uint32_t HAL_RCC_GetPCLK1Freq(void)
1501 {
1502 /* Get HCLK source and Compute PCLK1 frequency ---------------------------*/
1503 return (HAL_RCC_GetHCLKFreq() >> (APBPrescTable[READ_BIT(RCC->CFGR, RCC_CFGR_PPRE1) >> RCC_CFGR_PPRE1_Pos] & 0x1FU));
1504 }
1505
1506 /**
1507 * @brief Return the PCLK2 frequency.
1508 * @note Each time PCLK2 changes, this function must be called to update the
1509 * right PCLK2 value. Otherwise, any configuration based on this function will be incorrect.
1510 * @retval PCLK2 frequency in Hz
1511 */
HAL_RCC_GetPCLK2Freq(void)1512 uint32_t HAL_RCC_GetPCLK2Freq(void)
1513 {
1514 /* Get HCLK source and Compute PCLK2 frequency ---------------------------*/
1515 return (HAL_RCC_GetHCLKFreq()>> (APBPrescTable[READ_BIT(RCC->CFGR, RCC_CFGR_PPRE2) >> RCC_CFGR_PPRE2_Pos] & 0x1FU));
1516 }
1517
1518 /**
1519 * @brief Configure the RCC_OscInitStruct according to the internal
1520 * RCC configuration registers.
1521 * @param RCC_OscInitStruct pointer to an RCC_OscInitTypeDef structure that
1522 * will be configured.
1523 * @retval None
1524 */
HAL_RCC_GetOscConfig(RCC_OscInitTypeDef * RCC_OscInitStruct)1525 void HAL_RCC_GetOscConfig(RCC_OscInitTypeDef *RCC_OscInitStruct)
1526 {
1527 /* Check the parameters */
1528 assert_param(RCC_OscInitStruct != (void *)NULL);
1529
1530 /* Set all possible values for the Oscillator type parameter ---------------*/
1531 #if defined(RCC_HSI48_SUPPORT)
1532 RCC_OscInitStruct->OscillatorType = RCC_OSCILLATORTYPE_HSE | RCC_OSCILLATORTYPE_HSI | RCC_OSCILLATORTYPE_MSI | \
1533 RCC_OSCILLATORTYPE_LSE | RCC_OSCILLATORTYPE_LSI | RCC_OSCILLATORTYPE_HSI48;
1534 #else
1535 RCC_OscInitStruct->OscillatorType = RCC_OSCILLATORTYPE_HSE | RCC_OSCILLATORTYPE_HSI | RCC_OSCILLATORTYPE_MSI | \
1536 RCC_OSCILLATORTYPE_LSE | RCC_OSCILLATORTYPE_LSI;
1537 #endif /* RCC_HSI48_SUPPORT */
1538
1539 /* Get the HSE configuration -----------------------------------------------*/
1540 if(READ_BIT(RCC->CR, RCC_CR_HSEBYP) == RCC_CR_HSEBYP)
1541 {
1542 RCC_OscInitStruct->HSEState = RCC_HSE_BYPASS;
1543 }
1544 else if(READ_BIT(RCC->CR, RCC_CR_HSEON) == RCC_CR_HSEON)
1545 {
1546 RCC_OscInitStruct->HSEState = RCC_HSE_ON;
1547 }
1548 else
1549 {
1550 RCC_OscInitStruct->HSEState = RCC_HSE_OFF;
1551 }
1552
1553 /* Get the MSI configuration -----------------------------------------------*/
1554 if(READ_BIT(RCC->CR, RCC_CR_MSION) == RCC_CR_MSION)
1555 {
1556 RCC_OscInitStruct->MSIState = RCC_MSI_ON;
1557 }
1558 else
1559 {
1560 RCC_OscInitStruct->MSIState = RCC_MSI_OFF;
1561 }
1562
1563 RCC_OscInitStruct->MSICalibrationValue = READ_BIT(RCC->ICSCR, RCC_ICSCR_MSITRIM) >> RCC_ICSCR_MSITRIM_Pos;
1564 RCC_OscInitStruct->MSIClockRange = READ_BIT(RCC->CR, RCC_CR_MSIRANGE);
1565
1566 /* Get the HSI configuration -----------------------------------------------*/
1567 if(READ_BIT(RCC->CR, RCC_CR_HSION) == RCC_CR_HSION)
1568 {
1569 RCC_OscInitStruct->HSIState = RCC_HSI_ON;
1570 }
1571 else
1572 {
1573 RCC_OscInitStruct->HSIState = RCC_HSI_OFF;
1574 }
1575
1576 RCC_OscInitStruct->HSICalibrationValue = READ_BIT(RCC->ICSCR, RCC_ICSCR_HSITRIM) >> RCC_ICSCR_HSITRIM_Pos;
1577
1578 /* Get the LSE configuration -----------------------------------------------*/
1579 if(READ_BIT(RCC->BDCR, RCC_BDCR_LSEBYP) == RCC_BDCR_LSEBYP)
1580 {
1581 #if defined(RCC_BDCR_LSESYSDIS)
1582 if((RCC->BDCR & RCC_BDCR_LSESYSDIS) == RCC_BDCR_LSESYSDIS)
1583 {
1584 RCC_OscInitStruct->LSEState = RCC_LSE_BYPASS_RTC_ONLY;
1585 }
1586 else
1587 #endif /* RCC_BDCR_LSESYSDIS */
1588 {
1589 RCC_OscInitStruct->LSEState = RCC_LSE_BYPASS;
1590 }
1591 }
1592 else if(READ_BIT(RCC->BDCR, RCC_BDCR_LSEON) == RCC_BDCR_LSEON)
1593 {
1594 #if defined(RCC_BDCR_LSESYSDIS)
1595 if((RCC->BDCR & RCC_BDCR_LSESYSDIS) == RCC_BDCR_LSESYSDIS)
1596 {
1597 RCC_OscInitStruct->LSEState = RCC_LSE_ON_RTC_ONLY;
1598 }
1599 else
1600 #endif /* RCC_BDCR_LSESYSDIS */
1601 {
1602 RCC_OscInitStruct->LSEState = RCC_LSE_ON;
1603 }
1604 }
1605 else
1606 {
1607 RCC_OscInitStruct->LSEState = RCC_LSE_OFF;
1608 }
1609
1610 /* Get the LSI configuration -----------------------------------------------*/
1611 if(READ_BIT(RCC->CSR, RCC_CSR_LSION) == RCC_CSR_LSION)
1612 {
1613 RCC_OscInitStruct->LSIState = RCC_LSI_ON;
1614 }
1615 else
1616 {
1617 RCC_OscInitStruct->LSIState = RCC_LSI_OFF;
1618 }
1619 #if defined(RCC_CSR_LSIPREDIV)
1620
1621 /* Get the LSI configuration -----------------------------------------------*/
1622 if((RCC->CSR & RCC_CSR_LSIPREDIV) == RCC_CSR_LSIPREDIV)
1623 {
1624 RCC_OscInitStruct->LSIDiv = RCC_LSI_DIV128;
1625 }
1626 else
1627 {
1628 RCC_OscInitStruct->LSIDiv = RCC_LSI_DIV1;
1629 }
1630 #endif /* RCC_CSR_LSIPREDIV */
1631
1632 #if defined(RCC_HSI48_SUPPORT)
1633 /* Get the HSI48 configuration ---------------------------------------------*/
1634 if(READ_BIT(RCC->CRRCR, RCC_CRRCR_HSI48ON) == RCC_CRRCR_HSI48ON)
1635 {
1636 RCC_OscInitStruct->HSI48State = RCC_HSI48_ON;
1637 }
1638 else
1639 {
1640 RCC_OscInitStruct->HSI48State = RCC_HSI48_OFF;
1641 }
1642 #else
1643 RCC_OscInitStruct->HSI48State = RCC_HSI48_OFF;
1644 #endif /* RCC_HSI48_SUPPORT */
1645
1646 /* Get the PLL configuration -----------------------------------------------*/
1647 if(READ_BIT(RCC->CR, RCC_CR_PLLON) == RCC_CR_PLLON)
1648 {
1649 RCC_OscInitStruct->PLL.PLLState = RCC_PLL_ON;
1650 }
1651 else
1652 {
1653 RCC_OscInitStruct->PLL.PLLState = RCC_PLL_OFF;
1654 }
1655 RCC_OscInitStruct->PLL.PLLSource = READ_BIT(RCC->PLLCFGR, RCC_PLLCFGR_PLLSRC);
1656 RCC_OscInitStruct->PLL.PLLM = (READ_BIT(RCC->PLLCFGR, RCC_PLLCFGR_PLLM) >> RCC_PLLCFGR_PLLM_Pos) + 1U;
1657 RCC_OscInitStruct->PLL.PLLN = READ_BIT(RCC->PLLCFGR, RCC_PLLCFGR_PLLN) >> RCC_PLLCFGR_PLLN_Pos;
1658 RCC_OscInitStruct->PLL.PLLQ = (((READ_BIT(RCC->PLLCFGR, RCC_PLLCFGR_PLLQ) >> RCC_PLLCFGR_PLLQ_Pos) + 1U) << 1U);
1659 RCC_OscInitStruct->PLL.PLLR = (((READ_BIT(RCC->PLLCFGR, RCC_PLLCFGR_PLLR) >> RCC_PLLCFGR_PLLR_Pos) + 1U) << 1U);
1660 #if defined(RCC_PLLP_SUPPORT)
1661 #if defined(RCC_PLLP_DIV_2_31_SUPPORT)
1662 RCC_OscInitStruct->PLL.PLLP = READ_BIT(RCC->PLLCFGR, RCC_PLLCFGR_PLLPDIV) >> RCC_PLLCFGR_PLLPDIV_Pos;
1663 #else
1664 if(READ_BIT(RCC->PLLCFGR, RCC_PLLCFGR_PLLP) != 0U)
1665 {
1666 RCC_OscInitStruct->PLL.PLLP = RCC_PLLP_DIV17;
1667 }
1668 else
1669 {
1670 RCC_OscInitStruct->PLL.PLLP = RCC_PLLP_DIV7;
1671 }
1672 #endif /* RCC_PLLP_DIV_2_31_SUPPORT */
1673 #endif /* RCC_PLLP_SUPPORT */
1674 }
1675
1676 /**
1677 * @brief Configure the RCC_ClkInitStruct according to the internal
1678 * RCC configuration registers.
1679 * @param RCC_ClkInitStruct pointer to an RCC_ClkInitTypeDef structure that
1680 * will be configured.
1681 * @param pFLatency Pointer on the Flash Latency.
1682 * @retval None
1683 */
HAL_RCC_GetClockConfig(RCC_ClkInitTypeDef * RCC_ClkInitStruct,uint32_t * pFLatency)1684 void HAL_RCC_GetClockConfig(RCC_ClkInitTypeDef *RCC_ClkInitStruct, uint32_t *pFLatency)
1685 {
1686 /* Check the parameters */
1687 assert_param(RCC_ClkInitStruct != (void *)NULL);
1688 assert_param(pFLatency != (void *)NULL);
1689
1690 /* Set all possible values for the Clock type parameter --------------------*/
1691 RCC_ClkInitStruct->ClockType = RCC_CLOCKTYPE_SYSCLK | RCC_CLOCKTYPE_HCLK | RCC_CLOCKTYPE_PCLK1 | RCC_CLOCKTYPE_PCLK2;
1692
1693 /* Get the SYSCLK configuration --------------------------------------------*/
1694 RCC_ClkInitStruct->SYSCLKSource = READ_BIT(RCC->CFGR, RCC_CFGR_SW);
1695
1696 /* Get the HCLK configuration ----------------------------------------------*/
1697 RCC_ClkInitStruct->AHBCLKDivider = READ_BIT(RCC->CFGR, RCC_CFGR_HPRE);
1698
1699 /* Get the APB1 configuration ----------------------------------------------*/
1700 RCC_ClkInitStruct->APB1CLKDivider = READ_BIT(RCC->CFGR, RCC_CFGR_PPRE1);
1701
1702 /* Get the APB2 configuration ----------------------------------------------*/
1703 RCC_ClkInitStruct->APB2CLKDivider = (READ_BIT(RCC->CFGR, RCC_CFGR_PPRE2) >> 3U);
1704
1705 /* Get the Flash Wait State (Latency) configuration ------------------------*/
1706 *pFLatency = __HAL_FLASH_GET_LATENCY();
1707 }
1708
1709 /**
1710 * @brief Enable the Clock Security System.
1711 * @note If a failure is detected on the HSE oscillator clock, this oscillator
1712 * is automatically disabled and an interrupt is generated to inform the
1713 * software about the failure (Clock Security System Interrupt, CSSI),
1714 * allowing the MCU to perform rescue operations. The CSSI is linked to
1715 * the Cortex-M4 NMI (Non-Maskable Interrupt) exception vector.
1716 * @note The Clock Security System can only be cleared by reset.
1717 * @retval None
1718 */
HAL_RCC_EnableCSS(void)1719 void HAL_RCC_EnableCSS(void)
1720 {
1721 SET_BIT(RCC->CR, RCC_CR_CSSON) ;
1722 }
1723
1724 /**
1725 * @brief Handle the RCC Clock Security System interrupt request.
1726 * @note This API should be called under the NMI_Handler().
1727 * @retval None
1728 */
HAL_RCC_NMI_IRQHandler(void)1729 void HAL_RCC_NMI_IRQHandler(void)
1730 {
1731 /* Check RCC CSSF interrupt flag */
1732 if(__HAL_RCC_GET_IT(RCC_IT_CSS))
1733 {
1734 /* RCC Clock Security System interrupt user callback */
1735 HAL_RCC_CSSCallback();
1736
1737 /* Clear RCC CSS pending bit */
1738 __HAL_RCC_CLEAR_IT(RCC_IT_CSS);
1739 }
1740 }
1741
1742 /**
1743 * @brief RCC Clock Security System interrupt callback.
1744 * @retval none
1745 */
HAL_RCC_CSSCallback(void)1746 __weak void HAL_RCC_CSSCallback(void)
1747 {
1748 /* NOTE : This function should not be modified, when the callback is needed,
1749 the HAL_RCC_CSSCallback should be implemented in the user file
1750 */
1751 }
1752
1753 /**
1754 * @}
1755 */
1756
1757 /**
1758 * @}
1759 */
1760
1761 /* Private function prototypes -----------------------------------------------*/
1762 /** @addtogroup RCC_Private_Functions
1763 * @{
1764 */
1765 /**
1766 * @brief Update number of Flash wait states in line with MSI range and current
1767 voltage range.
1768 * @param msirange MSI range value from RCC_MSIRANGE_0 to RCC_MSIRANGE_11
1769 * @retval HAL status
1770 */
RCC_SetFlashLatencyFromMSIRange(uint32_t msirange)1771 static HAL_StatusTypeDef RCC_SetFlashLatencyFromMSIRange(uint32_t msirange)
1772 {
1773 uint32_t vos;
1774 uint32_t latency = FLASH_LATENCY_0; /* default value 0WS */
1775
1776 if(__HAL_RCC_PWR_IS_CLK_ENABLED())
1777 {
1778 vos = HAL_PWREx_GetVoltageRange();
1779 }
1780 else
1781 {
1782 __HAL_RCC_PWR_CLK_ENABLE();
1783 vos = HAL_PWREx_GetVoltageRange();
1784 __HAL_RCC_PWR_CLK_DISABLE();
1785 }
1786
1787 if(vos == PWR_REGULATOR_VOLTAGE_SCALE1)
1788 {
1789 if(msirange > RCC_MSIRANGE_8)
1790 {
1791 /* MSI > 16Mhz */
1792 if(msirange > RCC_MSIRANGE_10)
1793 {
1794 /* MSI 48Mhz */
1795 latency = FLASH_LATENCY_2; /* 2WS */
1796 }
1797 else
1798 {
1799 /* MSI 24Mhz or 32Mhz */
1800 latency = FLASH_LATENCY_1; /* 1WS */
1801 }
1802 }
1803 /* else MSI <= 16Mhz default FLASH_LATENCY_0 0WS */
1804 }
1805 else
1806 {
1807 #if defined(STM32L4P5xx) || defined(STM32L4Q5xx) || \
1808 defined(STM32L4R5xx) || defined(STM32L4R7xx) || defined(STM32L4R9xx) || defined(STM32L4S5xx) || defined(STM32L4S7xx) || defined(STM32L4S9xx)
1809 if(msirange >= RCC_MSIRANGE_8)
1810 {
1811 /* MSI >= 16Mhz */
1812 latency = FLASH_LATENCY_2; /* 2WS */
1813 }
1814 else
1815 {
1816 if(msirange == RCC_MSIRANGE_7)
1817 {
1818 /* MSI 8Mhz */
1819 latency = FLASH_LATENCY_1; /* 1WS */
1820 }
1821 /* else MSI < 8Mhz default FLASH_LATENCY_0 0WS */
1822 }
1823 #else
1824 if(msirange > RCC_MSIRANGE_8)
1825 {
1826 /* MSI > 16Mhz */
1827 latency = FLASH_LATENCY_3; /* 3WS */
1828 }
1829 else
1830 {
1831 if(msirange == RCC_MSIRANGE_8)
1832 {
1833 /* MSI 16Mhz */
1834 latency = FLASH_LATENCY_2; /* 2WS */
1835 }
1836 else if(msirange == RCC_MSIRANGE_7)
1837 {
1838 /* MSI 8Mhz */
1839 latency = FLASH_LATENCY_1; /* 1WS */
1840 }
1841 /* else MSI < 8Mhz default FLASH_LATENCY_0 0WS */
1842 }
1843 #endif
1844 }
1845
1846 __HAL_FLASH_SET_LATENCY(latency);
1847
1848 /* Check that the new number of wait states is taken into account to access the Flash
1849 memory by reading the FLASH_ACR register */
1850 if(__HAL_FLASH_GET_LATENCY() != latency)
1851 {
1852 return HAL_ERROR;
1853 }
1854
1855 return HAL_OK;
1856 }
1857
1858 #if defined(STM32L4P5xx) || defined(STM32L4Q5xx) || \
1859 defined(STM32L4R5xx) || defined(STM32L4R7xx) || defined(STM32L4R9xx) || defined(STM32L4S5xx) || defined(STM32L4S7xx) || defined(STM32L4S9xx)
1860 /**
1861 * @brief Compute SYSCLK frequency based on PLL SYSCLK source.
1862 * @retval SYSCLK frequency
1863 */
RCC_GetSysClockFreqFromPLLSource(void)1864 static uint32_t RCC_GetSysClockFreqFromPLLSource(void)
1865 {
1866 uint32_t msirange = 0U;
1867 uint32_t pllvco, pllsource, pllr, pllm, sysclockfreq; /* no init needed */
1868
1869 if(__HAL_RCC_GET_PLL_OSCSOURCE() == RCC_PLLSOURCE_MSI)
1870 {
1871 /* Get MSI range source */
1872 if(READ_BIT(RCC->CR, RCC_CR_MSIRGSEL) == 0U)
1873 { /* MSISRANGE from RCC_CSR applies */
1874 msirange = READ_BIT(RCC->CSR, RCC_CSR_MSISRANGE) >> RCC_CSR_MSISRANGE_Pos;
1875 }
1876 else
1877 { /* MSIRANGE from RCC_CR applies */
1878 msirange = READ_BIT(RCC->CR, RCC_CR_MSIRANGE) >> RCC_CR_MSIRANGE_Pos;
1879 }
1880 /*MSI frequency range in HZ*/
1881 msirange = MSIRangeTable[msirange];
1882 }
1883
1884 /* PLL_VCO = (HSE_VALUE or HSI_VALUE or MSI_VALUE) * PLLN / PLLM
1885 SYSCLK = PLL_VCO / PLLR
1886 */
1887 pllsource = READ_BIT(RCC->PLLCFGR, RCC_PLLCFGR_PLLSRC);
1888
1889 switch (pllsource)
1890 {
1891 case RCC_PLLSOURCE_HSI: /* HSI used as PLL clock source */
1892 pllvco = HSI_VALUE;
1893 break;
1894
1895 case RCC_PLLSOURCE_HSE: /* HSE used as PLL clock source */
1896 pllvco = HSE_VALUE;
1897 break;
1898
1899 case RCC_PLLSOURCE_MSI: /* MSI used as PLL clock source */
1900 default:
1901 pllvco = msirange;
1902 break;
1903 }
1904 pllm = (READ_BIT(RCC->PLLCFGR, RCC_PLLCFGR_PLLM) >> RCC_PLLCFGR_PLLM_Pos) + 1U ;
1905 pllvco = (pllvco * (READ_BIT(RCC->PLLCFGR, RCC_PLLCFGR_PLLN) >> RCC_PLLCFGR_PLLN_Pos)) / pllm;
1906 pllr = ((READ_BIT(RCC->PLLCFGR, RCC_PLLCFGR_PLLR) >> RCC_PLLCFGR_PLLR_Pos) + 1U ) * 2U;
1907 sysclockfreq = pllvco / pllr;
1908
1909 return sysclockfreq;
1910 }
1911 #endif
1912
1913 /**
1914 * @}
1915 */
1916
1917 #endif /* HAL_RCC_MODULE_ENABLED */
1918 /**
1919 * @}
1920 */
1921
1922 /**
1923 * @}
1924 */
1925
1926 /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
1927