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