1 /**
2 ******************************************************************************
3 * @file stm32l0xx_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 multispeed internal oscillator clock
17 (MSI 2.097MHz) with Flash 0 wait state and Flash prefetch buffer is disabled,
18 and all peripherals are off except internal SRAM, Flash and JTAG.
19 (+) There is no prescaler on High speed (AHB) and Low speed (APB) buses;
20 all peripherals mapped on these buses are running at MSI speed.
21 (+) The clock for all peripherals is switched off, except the SRAM and FLASH.
22 (+) All GPIOs are in input floating state, except the JTAG pins which
23 are assigned to be used for debug purpose.
24 [..] Once the device started from reset, the user application has to:
25 (+) Configure the clock source to be used to drive the System clock
26 (if the application needs higher frequency/performance)
27 (+) Configure the System clock frequency and Flash settings
28 (+) Configure the AHB and APB buses prescalers
29 (+) Enable the clock for the peripheral(s) to be used
30 (+) Configure the clock source(s) for peripherals whose clocks are not
31 derived from the System clock (I2S, RTC, ADC, USB OTG FS/SDIO/RNG)
32 (*) SDIO only for STM32L0xxxD devices
33
34 ##### RCC Limitations #####
35 ==============================================================================
36 [..]
37 A delay between an RCC peripheral clock enable and the effective peripheral
38 enabling should be taken into account in order to manage the peripheral read/write
39 from/to registers.
40 (+) This delay depends on the peripheral mapping.
41 (++) AHB & APB peripherals, 1 dummy read is necessary
42
43 [..]
44 Workarounds:
45 (#) For AHB & APB peripherals, a dummy read to the peripheral register has been
46 inserted in each __HAL_RCC_PPP_CLK_ENABLE() macro.
47
48 @endverbatim
49 ******************************************************************************
50 * @attention
51 *
52 * <h2><center>© Copyright(c) 2016 STMicroelectronics.
53 * All rights reserved.</center></h2>
54 *
55 * This software component is licensed by ST under BSD 3-Clause license,
56 * the "License"; You may not use this file except in compliance with the
57 * License. You may obtain a copy of the License at:
58 * opensource.org/licenses/BSD-3-Clause
59 *
60 ******************************************************************************
61 */
62
63 /* Includes ------------------------------------------------------------------*/
64 #include "stm32l0xx_hal.h"
65
66 /** @addtogroup STM32L0xx_HAL_Driver
67 * @{
68 */
69
70 /** @defgroup RCC RCC
71 * @brief RCC HAL module driver
72 * @{
73 */
74
75 #ifdef HAL_RCC_MODULE_ENABLED
76
77 /* Private typedef -----------------------------------------------------------*/
78 /* Private define ------------------------------------------------------------*/
79 /* Private macro -------------------------------------------------------------*/
80 /** @defgroup RCC_Private_Macros RCC Private Macros
81 * @{
82 */
83
84 #define MCO1_CLK_ENABLE() __HAL_RCC_GPIOA_CLK_ENABLE()
85 #define MCO1_GPIO_PORT GPIOA
86 #define MCO1_PIN GPIO_PIN_8
87
88 #define MCO2_CLK_ENABLE() __HAL_RCC_GPIOA_CLK_ENABLE()
89 #define MCO2_GPIO_PORT GPIOA
90 #define MCO2_PIN GPIO_PIN_9
91
92 #if defined(STM32L031xx) || defined(STM32L041xx) || defined(STM32L073xx) || defined(STM32L083xx) \
93 || defined(STM32L072xx) || defined(STM32L082xx) || defined(STM32L071xx) || defined(STM32L081xx)
94 #define MCO3_CLK_ENABLE() __HAL_RCC_GPIOB_CLK_ENABLE()
95 #define MCO3_GPIO_PORT GPIOB
96 #define MCO3_PIN GPIO_PIN_13
97 #endif
98
99 /**
100 * @}
101 */
102
103 /* Private variables ---------------------------------------------------------*/
104 /* Private function prototypes -----------------------------------------------*/
105 /* Exported functions ---------------------------------------------------------*/
106
107 /** @defgroup RCC_Exported_Functions RCC Exported Functions
108 * @{
109 */
110
111 /** @defgroup RCC_Exported_Functions_Group1 Initialization and de-initialization functions
112 * @brief Initialization and Configuration functions
113 *
114 @verbatim
115 ===============================================================================
116 ##### Initialization and de-initialization functions #####
117 ===============================================================================
118 [..]
119 This section provides functions allowing to configure the internal/external oscillators
120 (MSI, HSE, HSI, LSE, LSI, PLL, CSS and MCO) and the System buses clocks (SYSCLK, AHB, APB1
121 and APB2).
122
123 [..] Internal/external clock and PLL configuration
124 (#) MSI (Multispeed internal), Seven frequency ranges are available: 65.536 kHz,
125 131.072 kHz, 262.144 kHz, 524.288 kHz, 1.048 MHz, 2.097 MHz (default value) and 4.194 MHz.
126
127 (#) HSI (high-speed internal), 16 MHz factory-trimmed RC used directly or through
128 the PLL as System clock source.
129 (#) LSI (low-speed internal), ~37 KHz low consumption RC used as IWDG and/or RTC
130 clock source.
131
132 (#) HSE (high-speed external), 1 to 24 MHz crystal oscillator used directly or
133 through the PLL as System clock source. Can be used also as RTC clock source.
134
135 (#) LSE (low-speed external), 32 KHz oscillator used as RTC clock source.
136
137 (#) PLL (clocked by HSI or HSE), featuring different output clocks:
138 (++) The first output is used to generate the high speed system clock (up to 32 MHz)
139 (++) The second output is used to generate the clock for the USB OTG FS (48 MHz)
140
141 (#) CSS (Clock security system), once enable using the macro __HAL_RCC_CSS_ENABLE()
142 and if a HSE clock failure occurs(HSE used directly or through PLL as System
143 clock source), the System clocks automatically switched to MSI and an interrupt
144 is generated if enabled. The interrupt is linked to the Cortex-M0+ NMI
145 (Non-Maskable Interrupt) exception vector.
146
147 (#) MCO1/MCO2/MCO3 (microcontroller clock output), used to output SYSCLK, HSI, LSI, MSI, LSE,
148 HSE, HSI48 or PLL clock (through a configurable prescaler) on PA8/PA9/PB13 pins.
149
150 [..] System, AHB and APB buses clocks configuration
151 (#) Several clock sources can be used to drive the System clock (SYSCLK): MSI, HSI,
152 HSE and PLL.
153 The AHB clock (HCLK) is derived from System clock through configurable
154 prescaler and used to clock the CPU, memory and peripherals mapped
155 on AHB bus (DMA, GPIO...). APB1 (PCLK1) and APB2 (PCLK2) clocks are derived
156 from AHB clock through configurable prescalers and used to clock
157 the peripherals mapped on these buses. You can use
158 "@ref HAL_RCC_GetSysClockFreq()" function to retrieve the frequencies of these clocks.
159
160 -@- All the peripheral clocks are derived from the System clock (SYSCLK) except:
161 (+@) RTC: RTC clock can be derived either from the LSI, LSE or HSE clock
162 divided by 2 to 16. You have to use @ref __HAL_RCC_RTC_CONFIG() and @ref __HAL_RCC_RTC_ENABLE()
163 macros to configure this clock.
164 (+@) LCD: LCD clock can be derived either from the LSI, LSE or HSE clock
165 divided by 2 to 16. You have to use @ref __HAL_RCC_LCD_CONFIG()
166 macros to configure this clock.
167 (+@) USB FS and RNG: USB FS require a frequency equal to 48 MHz to work correctly.
168 This clock is derived of the main PLL through PLL Multiplier or HSI48 RC oscillator.
169
170 (+@) IWDG clock which is always the LSI clock.
171
172 (#) The maximum frequency of the SYSCLK and HCLK is 32 MHz, PCLK2 32 MHz
173 and PCLK1 32 MHz. Depending on the device voltage range, the maximum
174 frequency should be adapted accordingly.
175 @endverbatim
176 * @{
177 */
178
179 /*
180 Additional consideration on the HCLK based on Latency settings:
181 +----------------------------------------------------------------------+
182 | Latency | HCLK clock frequency (MHz) |
183 | |------------------------------------------------------|
184 | | voltage range 1 | voltage range 2 | voltage range 3 |
185 | | 1.8 V | 1.5 V | 1.2 V |
186 |---------------|------------------|-----------------|-----------------|
187 |0WS(1CPU cycle)| 0 < HCLK <= 16 | 0 < HCLK <= 8 | 0 < HCLK <= 4.2 |
188 |---------------|------------------|-----------------|-----------------|
189 |1WS(2CPU cycle)| 16 < HCLK <= 32 | 8 < HCLK <= 16 | |
190 +----------------------------------------------------------------------+
191
192 The following table gives the different clock source frequencies depending on the product
193 voltage range:
194 +------------------------------------------------------------------------------------------+
195 | Product voltage | Clock frequency |
196 | |------------------|-----------------------------|-----------------------|
197 | range | MSI | HSI | HSE | PLL |
198 |-----------------|---------|--------|-----------------------------|-----------------------|
199 | Range 1 (1.8 V) | 4.2 MHz | 16 MHz | HSE 32 MHz (external clock) | 32 MHz |
200 | | | | or 24 MHz (crystal) | (PLLVCO max = 96 MHz) |
201 |-----------------|---------|--------|-----------------------------|-----------------------|
202 | Range 2 (1.5 V) | 4.2 MHz | 16 MHz | 16 MHz | 16 MHz |
203 | | | | | (PLLVCO max = 48 MHz) |
204 |-----------------|---------|--------|-----------------------------|-----------------------|
205 | Range 3 (1.2 V) | 4.2 MHz | NA | 8 MHz | 4 MHz |
206 | | | | | (PLLVCO max = 24 MHz) |
207 +------------------------------------------------------------------------------------------+
208 */
209
210 /**
211 * @brief Resets the RCC clock configuration to the default reset state.
212 * @note The default reset state of the clock configuration is given below:
213 * - MSI ON and used as system clock source
214 * - HSI, HSE and PLL OFF
215 * - AHB, APB1 and APB2 prescaler set to 1.
216 * - CSS and MCO1/MCO2/MCO3 OFF
217 * - All interrupts disabled
218 * @note This function does not modify the configuration of the
219 * - Peripheral clocks
220 * - LSI, LSE and RTC clocks
221 * - HSI48 clock
222 * @retval None
223 */
HAL_RCC_DeInit(void)224 HAL_StatusTypeDef HAL_RCC_DeInit(void)
225 {
226 __IO uint32_t tmpreg;
227 uint32_t tickstart;
228 uint32_t vl_mask;
229 HAL_StatusTypeDef status;
230
231 /* Set MSIClockRange, HSITRIM and MSITRIM bits to the reset values */
232 MODIFY_REG(RCC->ICSCR, (RCC_ICSCR_MSITRIM | RCC_ICSCR_HSITRIM | RCC_ICSCR_MSIRANGE), \
233 ((RCC_MSICALIBRATION_DEFAULT << RCC_ICSCR_MSITRIM_Pos) | (RCC_HSICALIBRATION_DEFAULT << RCC_ICSCR_HSITRIM_Pos) | RCC_ICSCR_MSIRANGE_5));
234
235 /* Set MSION bit */
236 SET_BIT(RCC->CR, RCC_CR_MSION);
237
238 /* Get Start Tick*/
239 tickstart = HAL_GetTick();
240
241 /* Wait till MSI is ready */
242 while (READ_BIT(RCC->CR, RCC_CR_MSIRDY) == 0U)
243 {
244 if ((HAL_GetTick() - tickstart) > MSI_TIMEOUT_VALUE)
245 {
246 return HAL_TIMEOUT;
247 }
248 }
249
250 /* Switch SYSCLK to MSI*/
251 CLEAR_BIT(RCC->CFGR, RCC_CFGR_SW);
252
253 /* Wait till MSI as SYSCLK status is ready */
254 while (READ_BIT(RCC->CFGR, RCC_CFGR_SWS) != 0U)
255 {
256 if ((HAL_GetTick() - tickstart) > CLOCKSWITCH_TIMEOUT_VALUE)
257 {
258 return HAL_TIMEOUT;
259 }
260 }
261
262 /* Update the SystemCoreClock global variable for MSI as system clock source */
263 SystemCoreClock = MSI_VALUE;
264
265 /* Configure the source of time base considering new system clock settings */
266 status = HAL_InitTick(TICK_INT_PRIORITY);
267 if(status != HAL_OK)
268 {
269 return status;
270 }
271
272 /* Reset HSE, HSI, CSS, PLL */
273 #if defined(RCC_CR_CSSHSEON) && defined(RCC_CR_HSIOUTEN)
274 CLEAR_BIT(RCC->CR, RCC_CR_HSION| RCC_CR_HSIKERON| RCC_CR_HSIDIVEN | RCC_CR_HSIOUTEN | \
275 RCC_CR_HSEON | RCC_CR_CSSHSEON | RCC_CR_PLLON);
276 #elif !defined(RCC_CR_CSSHSEON) && defined(RCC_CR_HSIOUTEN)
277 CLEAR_BIT(RCC->CR, RCC_CR_HSION| RCC_CR_HSIKERON| RCC_CR_HSIDIVEN | RCC_CR_HSIOUTEN | \
278 RCC_CR_HSEON | RCC_CR_PLLON);
279 #elif defined(RCC_CR_CSSHSEON) && !defined(RCC_CR_HSIOUTEN)
280 CLEAR_BIT(RCC->CR, RCC_CR_HSION| RCC_CR_HSIKERON| RCC_CR_HSIDIVEN | \
281 RCC_CR_HSEON | RCC_CR_CSSHSEON | RCC_CR_PLLON);
282 #endif
283
284 /* Delay after an RCC peripheral clock */ \
285 tmpreg = READ_BIT(RCC->CR, RCC_CR_HSEON); \
286 UNUSED(tmpreg);
287
288 /* Reset HSEBYP bit */
289 CLEAR_BIT(RCC->CR, RCC_CR_HSEBYP);
290
291 /* Get Start Tick*/
292 tickstart = HAL_GetTick();
293
294 /* Wait till PLL is not ready */
295 while (READ_BIT(RCC->CR, RCC_CR_PLLRDY) != 0U)
296 {
297 if ((HAL_GetTick() - tickstart) > PLL_TIMEOUT_VALUE)
298 {
299 return HAL_TIMEOUT;
300 }
301 }
302
303 /* Reset CFGR register */
304 CLEAR_REG(RCC->CFGR);
305
306 /* Disable all interrupts */
307 CLEAR_REG(RCC->CIER);
308
309 /* Clear all flags */
310 vl_mask = RCC_CICR_LSIRDYC | RCC_CICR_LSERDYC | RCC_CICR_HSIRDYC | RCC_CICR_HSERDYC | RCC_CICR_PLLRDYC | RCC_CICR_MSIRDYC | RCC_CICR_CSSLSEC;
311 #if defined(RCC_HSI48_SUPPORT)
312 vl_mask |= RCC_CICR_HSI48RDYC;
313 #endif
314 #if defined(RCC_HSECSS_SUPPORT)
315 vl_mask |= RCC_CICR_CSSHSEC;
316 #endif
317 WRITE_REG(RCC->CICR, vl_mask);
318
319 /* Clear all reset flags */
320 SET_BIT(RCC->CSR, RCC_CSR_RMVF);
321
322 return HAL_OK;
323 }
324
325 /**
326 * @brief Initializes the RCC Oscillators according to the specified parameters in the
327 * RCC_OscInitTypeDef.
328 * @param RCC_OscInitStruct pointer to an RCC_OscInitTypeDef structure that
329 * contains the configuration information for the RCC Oscillators.
330 * @note The PLL is not disabled when used as system clock.
331 * @note Transitions LSE Bypass to LSE On and LSE On to LSE Bypass are not
332 * supported by this macro. User should request a transition to LSE Off
333 * first and then LSE On or LSE Bypass.
334 * @note Transition HSE Bypass to HSE On and HSE On to HSE Bypass are not
335 * supported by this macro. User should request a transition to HSE Off
336 * first and then HSE On or HSE Bypass.
337 * @retval HAL status
338 */
HAL_RCC_OscConfig(RCC_OscInitTypeDef * RCC_OscInitStruct)339 HAL_StatusTypeDef HAL_RCC_OscConfig(RCC_OscInitTypeDef *RCC_OscInitStruct)
340 {
341 uint32_t tickstart;
342 uint32_t hsi_state;
343 HAL_StatusTypeDef status;
344 uint32_t sysclk_source, pll_config;
345
346 /* Check the parameters */
347 if(RCC_OscInitStruct == NULL)
348 {
349 return HAL_ERROR;
350 }
351
352 assert_param(IS_RCC_OSCILLATORTYPE(RCC_OscInitStruct->OscillatorType));
353
354 sysclk_source = __HAL_RCC_GET_SYSCLK_SOURCE();
355 pll_config = __HAL_RCC_GET_PLL_OSCSOURCE();
356
357 /*------------------------------- HSE Configuration ------------------------*/
358 if(((RCC_OscInitStruct->OscillatorType) & RCC_OSCILLATORTYPE_HSE) == RCC_OSCILLATORTYPE_HSE)
359 {
360 /* Check the parameters */
361 assert_param(IS_RCC_HSE(RCC_OscInitStruct->HSEState));
362
363 /* When the HSE is used as system clock or clock source for PLL in these cases it is not allowed to be disabled */
364 if((sysclk_source == RCC_SYSCLKSOURCE_STATUS_HSE)
365 || ((sysclk_source == RCC_SYSCLKSOURCE_STATUS_PLLCLK) && (pll_config == RCC_PLLSOURCE_HSE)))
366 {
367 if((__HAL_RCC_GET_FLAG(RCC_FLAG_HSERDY) != 0U) && (RCC_OscInitStruct->HSEState == RCC_HSE_OFF))
368 {
369 return HAL_ERROR;
370 }
371 }
372 else
373 {
374 /* Set the new HSE configuration ---------------------------------------*/
375 __HAL_RCC_HSE_CONFIG(RCC_OscInitStruct->HSEState);
376
377 /* Check the HSE State */
378 if(RCC_OscInitStruct->HSEState != RCC_HSE_OFF)
379 {
380 /* Get Start Tick */
381 tickstart = HAL_GetTick();
382
383 /* Wait till HSE is ready */
384 while(__HAL_RCC_GET_FLAG(RCC_FLAG_HSERDY) == 0U)
385 {
386 if((HAL_GetTick() - tickstart ) > HSE_TIMEOUT_VALUE)
387 {
388 return HAL_TIMEOUT;
389 }
390 }
391 }
392 else
393 {
394 /* Get Start Tick */
395 tickstart = HAL_GetTick();
396
397 /* Wait till HSE is disabled */
398 while(__HAL_RCC_GET_FLAG(RCC_FLAG_HSERDY) != 0U)
399 {
400 if((HAL_GetTick() - tickstart ) > HSE_TIMEOUT_VALUE)
401 {
402 return HAL_TIMEOUT;
403 }
404 }
405 }
406 }
407 }
408 /*----------------------------- HSI Configuration --------------------------*/
409 if(((RCC_OscInitStruct->OscillatorType) & RCC_OSCILLATORTYPE_HSI) == RCC_OSCILLATORTYPE_HSI)
410 {
411 /* Check the parameters */
412 assert_param(IS_RCC_HSI(RCC_OscInitStruct->HSIState));
413 assert_param(IS_RCC_CALIBRATION_VALUE(RCC_OscInitStruct->HSICalibrationValue));
414
415 hsi_state = RCC_OscInitStruct->HSIState;
416
417 #if defined(RCC_CR_HSIOUTEN)
418 if((hsi_state & RCC_HSI_OUTEN) != 0U)
419 {
420 /* HSI Output enable for timer requested */
421 SET_BIT(RCC->CR, RCC_CR_HSIOUTEN);
422
423 hsi_state &= ~RCC_CR_HSIOUTEN;
424 }
425 #endif
426
427 /* Check if HSI is used as system clock or as PLL source when PLL is selected as system clock */
428 if((sysclk_source == RCC_SYSCLKSOURCE_STATUS_HSI)
429 || ((sysclk_source == RCC_SYSCLKSOURCE_STATUS_PLLCLK) && (pll_config == RCC_PLLSOURCE_HSI)))
430 {
431 /* When HSI is used as system clock it will not disabled */
432 if((__HAL_RCC_GET_FLAG(RCC_FLAG_HSIRDY) != 0U) && (hsi_state == RCC_HSI_OFF))
433 {
434 return HAL_ERROR;
435 }
436 /* Otherwise, just the calibration and HSI or HSIdiv4 are allowed */
437 else
438 {
439 /* Adjusts the Internal High Speed oscillator (HSI) calibration value.*/
440 __HAL_RCC_HSI_CALIBRATIONVALUE_ADJUST(RCC_OscInitStruct->HSICalibrationValue);
441
442 /* Enable the Internal High Speed oscillator (HSI or HSIdiv4) */
443 __HAL_RCC_HSI_CONFIG(hsi_state);
444 }
445
446 /* Update the SystemCoreClock global variable */
447 SystemCoreClock = HAL_RCC_GetSysClockFreq() >> AHBPrescTable[(RCC->CFGR & RCC_CFGR_HPRE)>> RCC_CFGR_HPRE_Pos];
448
449 /* Configure the source of time base considering new system clocks settings*/
450 status = HAL_InitTick (TICK_INT_PRIORITY);
451 if(status != HAL_OK)
452 {
453 return status;
454 }
455 }
456 else
457 {
458 /* Check the HSI State */
459 if(hsi_state != RCC_HSI_OFF)
460 {
461 /* Enable the Internal High Speed oscillator (HSI or HSIdiv4) */
462 __HAL_RCC_HSI_CONFIG(hsi_state);
463
464 /* Get Start Tick */
465 tickstart = HAL_GetTick();
466
467 /* Wait till HSI is ready */
468 while(__HAL_RCC_GET_FLAG(RCC_FLAG_HSIRDY) == 0U)
469 {
470 if((HAL_GetTick() - tickstart ) > HSI_TIMEOUT_VALUE)
471 {
472 return HAL_TIMEOUT;
473 }
474 }
475
476 /* Adjusts the Internal High Speed oscillator (HSI) calibration value.*/
477 __HAL_RCC_HSI_CALIBRATIONVALUE_ADJUST(RCC_OscInitStruct->HSICalibrationValue);
478 }
479 else
480 {
481 /* Disable the Internal High Speed oscillator (HSI). */
482 __HAL_RCC_HSI_DISABLE();
483
484 /* Get Start Tick */
485 tickstart = HAL_GetTick();
486
487 /* Wait till HSI is disabled */
488 while(__HAL_RCC_GET_FLAG(RCC_FLAG_HSIRDY) != 0U)
489 {
490 if((HAL_GetTick() - tickstart ) > HSI_TIMEOUT_VALUE)
491 {
492 return HAL_TIMEOUT;
493 }
494 }
495 }
496 }
497 }
498 /*----------------------------- MSI Configuration --------------------------*/
499 if(((RCC_OscInitStruct->OscillatorType) & RCC_OSCILLATORTYPE_MSI) == RCC_OSCILLATORTYPE_MSI)
500 {
501 /* When the MSI is used as system clock it will not be disabled */
502 if((sysclk_source == RCC_CFGR_SWS_MSI) )
503 {
504 if((__HAL_RCC_GET_FLAG(RCC_FLAG_MSIRDY) != 0U) && (RCC_OscInitStruct->MSIState == RCC_MSI_OFF))
505 {
506 return HAL_ERROR;
507 }
508 /* Otherwise, just the calibration and MSI range change are allowed */
509 else
510 {
511 /* Check MSICalibrationValue and MSIClockRange input parameters */
512 assert_param(IS_RCC_MSICALIBRATION_VALUE(RCC_OscInitStruct->MSICalibrationValue));
513 assert_param(IS_RCC_MSI_CLOCK_RANGE(RCC_OscInitStruct->MSIClockRange));
514
515 /* Selects the Multiple Speed oscillator (MSI) clock range .*/
516 __HAL_RCC_MSI_RANGE_CONFIG(RCC_OscInitStruct->MSIClockRange);
517 /* Adjusts the Multiple Speed oscillator (MSI) calibration value.*/
518 __HAL_RCC_MSI_CALIBRATIONVALUE_ADJUST(RCC_OscInitStruct->MSICalibrationValue);
519
520
521 /* Update the SystemCoreClock global variable */
522 SystemCoreClock = (32768U * (1UL << ((RCC_OscInitStruct->MSIClockRange >> RCC_ICSCR_MSIRANGE_Pos) + 1U)))
523 >> AHBPrescTable[((RCC->CFGR & RCC_CFGR_HPRE) >> RCC_CFGR_HPRE_Pos)];
524
525 /* Configure the source of time base considering new system clocks settings*/
526 status = HAL_InitTick (TICK_INT_PRIORITY);
527 if(status != HAL_OK)
528 {
529 return status;
530 }
531 }
532 }
533 else
534 {
535 /* Check MSI State */
536 assert_param(IS_RCC_MSI(RCC_OscInitStruct->MSIState));
537
538 /* Check the MSI State */
539 if(RCC_OscInitStruct->MSIState != RCC_MSI_OFF)
540 {
541 /* Enable the Multi Speed oscillator (MSI). */
542 __HAL_RCC_MSI_ENABLE();
543
544 /* Get Start Tick */
545 tickstart = HAL_GetTick();
546
547 /* Wait till MSI is ready */
548 while(__HAL_RCC_GET_FLAG(RCC_FLAG_MSIRDY) == 0U)
549 {
550 if((HAL_GetTick() - tickstart) > MSI_TIMEOUT_VALUE)
551 {
552 return HAL_TIMEOUT;
553 }
554 }
555 /* Check MSICalibrationValue and MSIClockRange input parameters */
556 assert_param(IS_RCC_MSICALIBRATION_VALUE(RCC_OscInitStruct->MSICalibrationValue));
557 assert_param(IS_RCC_MSI_CLOCK_RANGE(RCC_OscInitStruct->MSIClockRange));
558
559 /* Selects the Multiple Speed oscillator (MSI) clock range .*/
560 __HAL_RCC_MSI_RANGE_CONFIG(RCC_OscInitStruct->MSIClockRange);
561 /* Adjusts the Multiple Speed oscillator (MSI) calibration value.*/
562 __HAL_RCC_MSI_CALIBRATIONVALUE_ADJUST(RCC_OscInitStruct->MSICalibrationValue);
563 }
564 else
565 {
566 /* Disable the Multi Speed oscillator (MSI). */
567 __HAL_RCC_MSI_DISABLE();
568
569 /* Get Start Tick */
570 tickstart = HAL_GetTick();
571
572 /* Wait till MSI is ready */
573 while(__HAL_RCC_GET_FLAG(RCC_FLAG_MSIRDY) != 0U)
574 {
575 if((HAL_GetTick() - tickstart) > MSI_TIMEOUT_VALUE)
576 {
577 return HAL_TIMEOUT;
578 }
579 }
580 }
581 }
582 }
583 /*------------------------------ LSI Configuration -------------------------*/
584 if(((RCC_OscInitStruct->OscillatorType) & RCC_OSCILLATORTYPE_LSI) == RCC_OSCILLATORTYPE_LSI)
585 {
586 /* Check the parameters */
587 assert_param(IS_RCC_LSI(RCC_OscInitStruct->LSIState));
588
589 /* Check the LSI State */
590 if(RCC_OscInitStruct->LSIState != RCC_LSI_OFF)
591 {
592 /* Enable the Internal Low Speed oscillator (LSI). */
593 __HAL_RCC_LSI_ENABLE();
594
595 /* Get Start Tick */
596 tickstart = HAL_GetTick();
597
598 /* Wait till LSI is ready */
599 while(__HAL_RCC_GET_FLAG(RCC_FLAG_LSIRDY) == 0U)
600 {
601 if((HAL_GetTick() - tickstart ) > LSI_TIMEOUT_VALUE)
602 {
603 return HAL_TIMEOUT;
604 }
605 }
606 }
607 else
608 {
609 /* Disable the Internal Low Speed oscillator (LSI). */
610 __HAL_RCC_LSI_DISABLE();
611
612 /* Get Start Tick */
613 tickstart = HAL_GetTick();
614
615 /* Wait till LSI is disabled */
616 while(__HAL_RCC_GET_FLAG(RCC_FLAG_LSIRDY) != 0U)
617 {
618 if((HAL_GetTick() - tickstart ) > LSI_TIMEOUT_VALUE)
619 {
620 return HAL_TIMEOUT;
621 }
622 }
623 }
624 }
625 /*------------------------------ LSE Configuration -------------------------*/
626 if(((RCC_OscInitStruct->OscillatorType) & RCC_OSCILLATORTYPE_LSE) == RCC_OSCILLATORTYPE_LSE)
627 {
628 FlagStatus pwrclkchanged = RESET;
629
630 /* Check the parameters */
631 assert_param(IS_RCC_LSE(RCC_OscInitStruct->LSEState));
632
633 /* Update LSE configuration in Backup Domain control register */
634 /* Requires to enable write access to Backup Domain of necessary */
635 if(__HAL_RCC_PWR_IS_CLK_DISABLED())
636 {
637 __HAL_RCC_PWR_CLK_ENABLE();
638 pwrclkchanged = SET;
639 }
640
641 if(HAL_IS_BIT_CLR(PWR->CR, PWR_CR_DBP))
642 {
643 /* Enable write access to Backup domain */
644 SET_BIT(PWR->CR, PWR_CR_DBP);
645
646 /* Wait for Backup domain Write protection disable */
647 tickstart = HAL_GetTick();
648
649 while(HAL_IS_BIT_CLR(PWR->CR, PWR_CR_DBP))
650 {
651 if((HAL_GetTick() - tickstart) > RCC_DBP_TIMEOUT_VALUE)
652 {
653 return HAL_TIMEOUT;
654 }
655 }
656 }
657
658 /* Set the new LSE configuration -----------------------------------------*/
659 __HAL_RCC_LSE_CONFIG(RCC_OscInitStruct->LSEState);
660 /* Check the LSE State */
661 if(RCC_OscInitStruct->LSEState != RCC_LSE_OFF)
662 {
663 /* Get Start Tick */
664 tickstart = HAL_GetTick();
665
666 /* Wait till LSE is ready */
667 while(__HAL_RCC_GET_FLAG(RCC_FLAG_LSERDY) == 0U)
668 {
669 if((HAL_GetTick() - tickstart ) > RCC_LSE_TIMEOUT_VALUE)
670 {
671 return HAL_TIMEOUT;
672 }
673 }
674 }
675 else
676 {
677 /* Get Start Tick */
678 tickstart = HAL_GetTick();
679
680 /* Wait till LSE is disabled */
681 while(__HAL_RCC_GET_FLAG(RCC_FLAG_LSERDY) != 0U)
682 {
683 if((HAL_GetTick() - tickstart ) > RCC_LSE_TIMEOUT_VALUE)
684 {
685 return HAL_TIMEOUT;
686 }
687 }
688 }
689
690 /* Require to disable power clock if necessary */
691 if(pwrclkchanged == SET)
692 {
693 __HAL_RCC_PWR_CLK_DISABLE();
694 }
695 }
696
697 #if defined(RCC_HSI48_SUPPORT)
698 /*----------------------------- HSI48 Configuration --------------------------*/
699 if(((RCC_OscInitStruct->OscillatorType) & RCC_OSCILLATORTYPE_HSI48) == RCC_OSCILLATORTYPE_HSI48)
700 {
701 /* Check the parameters */
702 assert_param(IS_RCC_HSI48(RCC_OscInitStruct->HSI48State));
703
704 /* Check the HSI48 State */
705 if(RCC_OscInitStruct->HSI48State != RCC_HSI48_OFF)
706 {
707 /* Enable the Internal High Speed oscillator (HSI48). */
708 __HAL_RCC_HSI48_ENABLE();
709
710 /* Get Start Tick */
711 tickstart = HAL_GetTick();
712
713 /* Wait till HSI48 is ready */
714 while(__HAL_RCC_GET_FLAG(RCC_FLAG_HSI48RDY) == 0U)
715 {
716 if((HAL_GetTick() - tickstart) > HSI48_TIMEOUT_VALUE)
717 {
718 return HAL_TIMEOUT;
719 }
720 }
721 }
722 else
723 {
724 /* Disable the Internal High Speed oscillator (HSI48). */
725 __HAL_RCC_HSI48_DISABLE();
726
727 /* Get Start Tick */
728 tickstart = HAL_GetTick();
729
730 /* Wait till HSI48 is ready */
731 while(__HAL_RCC_GET_FLAG(RCC_FLAG_HSI48RDY) != 0U)
732 {
733 if((HAL_GetTick() - tickstart) > HSI48_TIMEOUT_VALUE)
734 {
735 return HAL_TIMEOUT;
736 }
737 }
738 }
739 }
740 #endif /* RCC_HSI48_SUPPORT */
741
742 /*-------------------------------- PLL Configuration -----------------------*/
743 /* Check the parameters */
744 assert_param(IS_RCC_PLL(RCC_OscInitStruct->PLL.PLLState));
745 if ((RCC_OscInitStruct->PLL.PLLState) != RCC_PLL_NONE)
746 {
747 /* Check if the PLL is used as system clock or not */
748 if(sysclk_source != RCC_SYSCLKSOURCE_STATUS_PLLCLK)
749 {
750 if((RCC_OscInitStruct->PLL.PLLState) == RCC_PLL_ON)
751 {
752 /* Check the parameters */
753 assert_param(IS_RCC_PLLSOURCE(RCC_OscInitStruct->PLL.PLLSource));
754 assert_param(IS_RCC_PLL_MUL(RCC_OscInitStruct->PLL.PLLMUL));
755 assert_param(IS_RCC_PLL_DIV(RCC_OscInitStruct->PLL.PLLDIV));
756
757 /* Disable the main PLL. */
758 __HAL_RCC_PLL_DISABLE();
759
760 /* Get Start Tick */
761 tickstart = HAL_GetTick();
762
763 /* Wait till PLL is disabled */
764 while(__HAL_RCC_GET_FLAG(RCC_FLAG_PLLRDY) != 0U)
765 {
766 if((HAL_GetTick() - tickstart ) > PLL_TIMEOUT_VALUE)
767 {
768 return HAL_TIMEOUT;
769 }
770 }
771
772 /* Configure the main PLL clock source, multiplication and division factors. */
773 __HAL_RCC_PLL_CONFIG(RCC_OscInitStruct->PLL.PLLSource,
774 RCC_OscInitStruct->PLL.PLLMUL,
775 RCC_OscInitStruct->PLL.PLLDIV);
776 /* Enable the main PLL. */
777 __HAL_RCC_PLL_ENABLE();
778
779 /* Get Start Tick */
780 tickstart = HAL_GetTick();
781
782 /* Wait till PLL is ready */
783 while(__HAL_RCC_GET_FLAG(RCC_FLAG_PLLRDY) == 0U)
784 {
785 if((HAL_GetTick() - tickstart ) > PLL_TIMEOUT_VALUE)
786 {
787 return HAL_TIMEOUT;
788 }
789 }
790 }
791 else
792 {
793 /* Disable the main PLL. */
794 __HAL_RCC_PLL_DISABLE();
795
796 /* Get Start Tick */
797 tickstart = HAL_GetTick();
798
799 /* Wait till PLL is disabled */
800 while(__HAL_RCC_GET_FLAG(RCC_FLAG_PLLRDY) != 0U)
801 {
802 if((HAL_GetTick() - tickstart ) > PLL_TIMEOUT_VALUE)
803 {
804 return HAL_TIMEOUT;
805 }
806 }
807 }
808 }
809 else
810 {
811 /* Check if there is a request to disable the PLL used as System clock source */
812 if((RCC_OscInitStruct->PLL.PLLState) == RCC_PLL_OFF)
813 {
814 return HAL_ERROR;
815 }
816 else
817 {
818 /* Do not return HAL_ERROR if request repeats the current configuration */
819 pll_config = RCC->CFGR;
820 if((READ_BIT(pll_config, RCC_CFGR_PLLSRC) != RCC_OscInitStruct->PLL.PLLSource) ||
821 (READ_BIT(pll_config, RCC_CFGR_PLLMUL) != RCC_OscInitStruct->PLL.PLLMUL) ||
822 (READ_BIT(pll_config, RCC_CFGR_PLLDIV) != RCC_OscInitStruct->PLL.PLLDIV))
823 {
824 return HAL_ERROR;
825 }
826 }
827 }
828 }
829
830 return HAL_OK;
831 }
832
833 /**
834 * @brief Initializes the CPU, AHB and APB buses clocks according to the specified
835 * parameters in the RCC_ClkInitStruct.
836 * @param RCC_ClkInitStruct pointer to an RCC_OscInitTypeDef structure that
837 * contains the configuration information for the RCC peripheral.
838 * @param FLatency FLASH Latency
839 * The value of this parameter depend on device used within the same series
840 * @note The SystemCoreClock CMSIS variable is used to store System Clock Frequency
841 * and updated by @ref HAL_RCC_GetHCLKFreq() function called within this function
842 *
843 * @note The MSI is used (enabled by hardware) as system clock source after
844 * start-up from Reset, wake-up from STOP and STANDBY mode, or in case
845 * of failure of the HSE used directly or indirectly as system clock
846 * (if the Clock Security System CSS is enabled).
847 *
848 * @note A switch from one clock source to another occurs only if the target
849 * clock source is ready (clock stable after start-up delay or PLL locked).
850 * If a clock source which is not yet ready is selected, the switch will
851 * occur when the clock source will be ready.
852 * You can use @ref HAL_RCC_GetClockConfig() function to know which clock is
853 * currently used as system clock source.
854 * @note Depending on the device voltage range, the software has to set correctly
855 * HPRE[3:0] bits to ensure that HCLK not exceed the maximum allowed frequency
856 * (for more details refer to section above "Initialization/de-initialization functions")
857 * @retval HAL status
858 */
HAL_RCC_ClockConfig(RCC_ClkInitTypeDef * RCC_ClkInitStruct,uint32_t FLatency)859 HAL_StatusTypeDef HAL_RCC_ClockConfig(RCC_ClkInitTypeDef *RCC_ClkInitStruct, uint32_t FLatency)
860 {
861 uint32_t tickstart;
862 HAL_StatusTypeDef status;
863
864 /* Check the parameters */
865 if(RCC_ClkInitStruct == NULL)
866 {
867 return HAL_ERROR;
868 }
869
870 assert_param(IS_RCC_CLOCKTYPE(RCC_ClkInitStruct->ClockType));
871 assert_param(IS_FLASH_LATENCY(FLatency));
872
873 /* To correctly read data from FLASH memory, the number of wait states (LATENCY)
874 must be correctly programmed according to the frequency of the CPU clock
875 (HCLK) and the supply voltage of the device. */
876
877 /* Increasing the number of wait states because of higher CPU frequency */
878 if(FLatency > __HAL_FLASH_GET_LATENCY())
879 {
880 /* Program the new number of wait states to the LATENCY bits in the FLASH_ACR register */
881 __HAL_FLASH_SET_LATENCY(FLatency);
882
883 /* Check that the new number of wait states is taken into account to access the Flash
884 memory by reading the FLASH_ACR register */
885 if(__HAL_FLASH_GET_LATENCY() != FLatency)
886 {
887 return HAL_ERROR;
888 }
889 }
890
891 /*-------------------------- HCLK Configuration --------------------------*/
892 if(((RCC_ClkInitStruct->ClockType) & RCC_CLOCKTYPE_HCLK) == RCC_CLOCKTYPE_HCLK)
893 {
894 assert_param(IS_RCC_HCLK(RCC_ClkInitStruct->AHBCLKDivider));
895 MODIFY_REG(RCC->CFGR, RCC_CFGR_HPRE, RCC_ClkInitStruct->AHBCLKDivider);
896 }
897
898 /*------------------------- SYSCLK Configuration ---------------------------*/
899 if(((RCC_ClkInitStruct->ClockType) & RCC_CLOCKTYPE_SYSCLK) == RCC_CLOCKTYPE_SYSCLK)
900 {
901 assert_param(IS_RCC_SYSCLKSOURCE(RCC_ClkInitStruct->SYSCLKSource));
902
903 /* HSE is selected as System Clock Source */
904 if(RCC_ClkInitStruct->SYSCLKSource == RCC_SYSCLKSOURCE_HSE)
905 {
906 /* Check the HSE ready flag */
907 if(__HAL_RCC_GET_FLAG(RCC_FLAG_HSERDY) == 0U)
908 {
909 return HAL_ERROR;
910 }
911 }
912 /* PLL is selected as System Clock Source */
913 else if(RCC_ClkInitStruct->SYSCLKSource == RCC_SYSCLKSOURCE_PLLCLK)
914 {
915 /* Check the PLL ready flag */
916 if(__HAL_RCC_GET_FLAG(RCC_FLAG_PLLRDY) == 0U)
917 {
918 return HAL_ERROR;
919 }
920 }
921 /* HSI is selected as System Clock Source */
922 else if(RCC_ClkInitStruct->SYSCLKSource == RCC_SYSCLKSOURCE_HSI)
923 {
924 /* Check the HSI ready flag */
925 if(__HAL_RCC_GET_FLAG(RCC_FLAG_HSIRDY) == 0U)
926 {
927 return HAL_ERROR;
928 }
929 }
930 /* MSI is selected as System Clock Source */
931 else
932 {
933 /* Check the MSI ready flag */
934 if(__HAL_RCC_GET_FLAG(RCC_FLAG_MSIRDY) == 0U)
935 {
936 return HAL_ERROR;
937 }
938 }
939 __HAL_RCC_SYSCLK_CONFIG(RCC_ClkInitStruct->SYSCLKSource);
940
941 /* Get Start Tick */
942 tickstart = HAL_GetTick();
943
944 if(RCC_ClkInitStruct->SYSCLKSource == RCC_SYSCLKSOURCE_HSE)
945 {
946 while (__HAL_RCC_GET_SYSCLK_SOURCE() != RCC_SYSCLKSOURCE_STATUS_HSE)
947 {
948 if((HAL_GetTick() - tickstart ) > CLOCKSWITCH_TIMEOUT_VALUE)
949 {
950 return HAL_TIMEOUT;
951 }
952 }
953 }
954 else if(RCC_ClkInitStruct->SYSCLKSource == RCC_SYSCLKSOURCE_PLLCLK)
955 {
956 while (__HAL_RCC_GET_SYSCLK_SOURCE() != RCC_SYSCLKSOURCE_STATUS_PLLCLK)
957 {
958 if((HAL_GetTick() - tickstart ) > CLOCKSWITCH_TIMEOUT_VALUE)
959 {
960 return HAL_TIMEOUT;
961 }
962 }
963 }
964 else if(RCC_ClkInitStruct->SYSCLKSource == RCC_SYSCLKSOURCE_HSI)
965 {
966 while (__HAL_RCC_GET_SYSCLK_SOURCE() != RCC_SYSCLKSOURCE_STATUS_HSI)
967 {
968 if((HAL_GetTick() - tickstart ) > CLOCKSWITCH_TIMEOUT_VALUE)
969 {
970 return HAL_TIMEOUT;
971 }
972 }
973 }
974 else
975 {
976 while(__HAL_RCC_GET_SYSCLK_SOURCE() != RCC_SYSCLKSOURCE_STATUS_MSI)
977 {
978 if((HAL_GetTick() - tickstart ) > CLOCKSWITCH_TIMEOUT_VALUE)
979 {
980 return HAL_TIMEOUT;
981 }
982 }
983 }
984 }
985 /* Decreasing the number of wait states because of lower CPU frequency */
986 if(FLatency < __HAL_FLASH_GET_LATENCY())
987 {
988 /* Program the new number of wait states to the LATENCY bits in the FLASH_ACR register */
989 __HAL_FLASH_SET_LATENCY(FLatency);
990
991 /* Check that the new number of wait states is taken into account to access the Flash
992 memory by reading the FLASH_ACR register */
993 if(__HAL_FLASH_GET_LATENCY() != FLatency)
994 {
995 return HAL_ERROR;
996 }
997 }
998
999 /*-------------------------- PCLK1 Configuration ---------------------------*/
1000 if(((RCC_ClkInitStruct->ClockType) & RCC_CLOCKTYPE_PCLK1) == RCC_CLOCKTYPE_PCLK1)
1001 {
1002 assert_param(IS_RCC_PCLK(RCC_ClkInitStruct->APB1CLKDivider));
1003 MODIFY_REG(RCC->CFGR, RCC_CFGR_PPRE1, RCC_ClkInitStruct->APB1CLKDivider);
1004 }
1005
1006 /*-------------------------- PCLK2 Configuration ---------------------------*/
1007 if(((RCC_ClkInitStruct->ClockType) & RCC_CLOCKTYPE_PCLK2) == RCC_CLOCKTYPE_PCLK2)
1008 {
1009 assert_param(IS_RCC_PCLK(RCC_ClkInitStruct->APB2CLKDivider));
1010 MODIFY_REG(RCC->CFGR, RCC_CFGR_PPRE2, ((RCC_ClkInitStruct->APB2CLKDivider) << 3));
1011 }
1012
1013 /* Update the SystemCoreClock global variable */
1014 SystemCoreClock = HAL_RCC_GetSysClockFreq() >> AHBPrescTable[(RCC->CFGR & RCC_CFGR_HPRE)>> RCC_CFGR_HPRE_Pos];
1015
1016 /* Configure the source of time base considering new system clocks settings*/
1017 status = HAL_InitTick(TICK_INT_PRIORITY);
1018 if(status != HAL_OK)
1019 {
1020 return status;
1021 }
1022
1023 return HAL_OK;
1024 }
1025
1026 /**
1027 * @}
1028 */
1029
1030 /** @defgroup RCC_Exported_Functions_Group2 Peripheral Control functions
1031 * @brief RCC clocks control functions
1032 *
1033 @verbatim
1034 ===============================================================================
1035 ##### Peripheral Control functions #####
1036 ===============================================================================
1037 [..]
1038 This subsection provides a set of functions allowing to control the RCC Clocks
1039 frequencies.
1040
1041 @endverbatim
1042 * @{
1043 */
1044
1045 /**
1046 * @brief Selects the clock source to output on MCO pin.
1047 * @note MCO pin should be configured in alternate function mode.
1048 * @param RCC_MCOx specifies the output direction for the clock source.
1049 * This parameter can be one of the following values:
1050 * @arg @ref RCC_MCO1 Clock source to output on MCO1 pin(PA8).
1051 * @arg @ref RCC_MCO2 Clock source to output on MCO2 pin(PA9).
1052 @if STM32L031xx
1053 * @arg @ref RCC_MCO3 Clock source to output on MCO3 pin(PB13)
1054 @elseif STM32L041xx
1055 * @arg @ref RCC_MCO3 Clock source to output on MCO3 pin(PB13)
1056 @elseif STM32L073xx
1057 * @arg @ref RCC_MCO3 Clock source to output on MCO3 pin(PB13)
1058 @elseif STM32L083xx
1059 * @arg @ref RCC_MCO3 Clock source to output on MCO3 pin(PB13)
1060 @elseif STM32L072xx
1061 * @arg @ref RCC_MCO3 Clock source to output on MCO3 pin(PB13)
1062 @elseif STM32L082xx
1063 * @arg @ref RCC_MCO3 Clock source to output on MCO3 pin(PB13)
1064 @elseif STM32L071xx
1065 * @arg @ref RCC_MCO3 Clock source to output on MCO3 pin(PB13)
1066 @elseif STM32L081xx
1067 * @arg @ref RCC_MCO3 Clock source to output on MCO3 pin(PB13)
1068 @endif
1069 * @param RCC_MCOSource specifies the clock source to output.
1070 * This parameter can be one of the following values:
1071 * @arg @ref RCC_MCO1SOURCE_NOCLOCK No clock selected as MCO clock
1072 * @arg @ref RCC_MCO1SOURCE_SYSCLK System clock selected as MCO clock
1073 * @arg @ref RCC_MCO1SOURCE_HSI HSI selected as MCO clock
1074 * @arg @ref RCC_MCO1SOURCE_HSE HSE selected as MCO clock
1075 * @arg @ref RCC_MCO1SOURCE_MSI MSI oscillator clock selected as MCO clock
1076 * @arg @ref RCC_MCO1SOURCE_PLLCLK PLL clock selected as MCO clock
1077 * @arg @ref RCC_MCO1SOURCE_LSI LSI clock selected as MCO clock
1078 * @arg @ref RCC_MCO1SOURCE_LSE LSE clock selected as MCO clock
1079 @if STM32L052xx
1080 * @arg @ref RCC_MCO1SOURCE_HSI48 HSI48 clock selected as MCO clock
1081 @elseif STM32L053xx
1082 * @arg @ref RCC_MCO1SOURCE_HSI48 HSI48 clock selected as MCO clock
1083 @elseif STM32L062xx
1084 * @arg @ref RCC_MCO1SOURCE_HSI48 HSI48 clock selected as MCO clock
1085 @elseif STM32L063xx
1086 * @arg @ref RCC_MCO1SOURCE_HSI48 HSI48 clock selected as MCO clock
1087 @elseif STM32L072xx
1088 * @arg @ref RCC_MCO1SOURCE_HSI48 HSI48 clock selected as MCO clock
1089 @elseif STM32L073xx
1090 * @arg @ref RCC_MCO1SOURCE_HSI48 HSI48 clock selected as MCO clock
1091 @elseif STM32L082xx
1092 * @arg @ref RCC_MCO1SOURCE_HSI48 HSI48 clock selected as MCO clock
1093 @elseif STM32L083xx
1094 * @arg @ref RCC_MCO1SOURCE_HSI48 HSI48 clock selected as MCO clock
1095 @endif
1096 * @param RCC_MCODiv specifies the MCO DIV.
1097 * This parameter can be one of the following values:
1098 * @arg @ref RCC_MCODIV_1 no division applied to MCO clock
1099 * @arg @ref RCC_MCODIV_2 division by 2 applied to MCO clock
1100 * @arg @ref RCC_MCODIV_4 division by 4 applied to MCO clock
1101 * @arg @ref RCC_MCODIV_8 division by 8 applied to MCO clock
1102 * @arg @ref RCC_MCODIV_16 division by 16 applied to MCO clock
1103 * @retval None
1104 */
HAL_RCC_MCOConfig(uint32_t RCC_MCOx,uint32_t RCC_MCOSource,uint32_t RCC_MCODiv)1105 void HAL_RCC_MCOConfig(uint32_t RCC_MCOx, uint32_t RCC_MCOSource, uint32_t RCC_MCODiv)
1106 {
1107 GPIO_InitTypeDef gpio = {0};
1108
1109 /* Check the parameters */
1110 assert_param(IS_RCC_MCO(RCC_MCOx));
1111 assert_param(IS_RCC_MCODIV(RCC_MCODiv));
1112 assert_param(IS_RCC_MCO1SOURCE(RCC_MCOSource));
1113
1114 /* Configure the MCO1 pin in alternate function mode */
1115 gpio.Mode = GPIO_MODE_AF_PP;
1116 gpio.Speed = GPIO_SPEED_FREQ_HIGH;
1117 gpio.Pull = GPIO_NOPULL;
1118 if(RCC_MCOx == RCC_MCO1)
1119 {
1120 gpio.Pin = MCO1_PIN;
1121 gpio.Alternate = GPIO_AF0_MCO;
1122
1123 /* MCO1 Clock Enable */
1124 MCO1_CLK_ENABLE();
1125 HAL_GPIO_Init(MCO1_GPIO_PORT, &gpio);
1126 }
1127 #if defined(STM32L031xx) || defined(STM32L041xx) || defined(STM32L073xx) || defined(STM32L083xx) \
1128 || defined(STM32L072xx) || defined(STM32L082xx) || defined(STM32L071xx) || defined(STM32L081xx)
1129 else if (RCC_MCOx == RCC_MCO3)
1130 {
1131 gpio.Pin = MCO3_PIN;
1132 gpio.Alternate = GPIO_AF2_MCO;
1133
1134 /* MCO3 Clock Enable */
1135 MCO3_CLK_ENABLE();
1136 HAL_GPIO_Init(MCO3_GPIO_PORT, &gpio);
1137 }
1138 #endif
1139 else
1140 {
1141 gpio.Pin = MCO2_PIN;
1142 gpio.Alternate = GPIO_AF0_MCO;
1143
1144 /* MCO2 Clock Enable */
1145 MCO2_CLK_ENABLE();
1146 HAL_GPIO_Init(MCO2_GPIO_PORT, &gpio);
1147 }
1148
1149 /* Configure the MCO clock source */
1150 __HAL_RCC_MCO1_CONFIG(RCC_MCOSource, RCC_MCODiv);
1151 }
1152
1153 #if defined(RCC_HSECSS_SUPPORT)
1154 /**
1155 * @brief Enables the Clock Security System.
1156 * @note If a failure is detected on the HSE oscillator clock, this oscillator
1157 * is automatically disabled and an interrupt is generated to inform the
1158 * software about the failure (Clock Security System Interrupt, CSSI),
1159 * allowing the MCU to perform rescue operations. The CSSI is linked to
1160 * the Cortex-M0+ NMI (Non-Maskable Interrupt) exception vector.
1161 * @retval None
1162 */
HAL_RCC_EnableCSS(void)1163 void HAL_RCC_EnableCSS(void)
1164 {
1165 SET_BIT(RCC->CR, RCC_CR_CSSON) ;
1166 }
1167
1168 #endif /* RCC_HSECSS_SUPPORT */
1169 /**
1170 * @brief Returns the SYSCLK frequency
1171 * @note The system frequency computed by this function is not the real
1172 * frequency in the chip. It is calculated based on the predefined
1173 * constant and the selected clock source:
1174 * @note If SYSCLK source is MSI, function returns a value based on MSI
1175 * Value as defined by the MSI range.
1176 * @note If SYSCLK source is HSI, function returns values based on HSI_VALUE(*)
1177 * @note If SYSCLK source is HSE, function returns a value based on HSE_VALUE(**)
1178 * @note If SYSCLK source is PLL, function returns a value based on HSE_VALUE(**)
1179 * or HSI_VALUE(*) multiplied/divided by the PLL factors.
1180 * @note (*) HSI_VALUE is a constant defined in stm32l0xx_hal_conf.h file (default value
1181 * 16 MHz) but the real value may vary depending on the variations
1182 * in voltage and temperature.
1183 * @note (**) HSE_VALUE is a constant defined in stm32l0xx_hal_conf.h file (default value
1184 * 8 MHz), user has to ensure that HSE_VALUE is same as the real
1185 * frequency of the crystal used. Otherwise, this function may
1186 * have wrong result.
1187 *
1188 * @note The result of this function could be not correct when using fractional
1189 * value for HSE crystal.
1190 *
1191 * @note This function can be used by the user application to compute the
1192 * baud-rate for the communication peripherals or configure other parameters.
1193 *
1194 * @note Each time SYSCLK changes, this function must be called to update the
1195 * right SYSCLK value. Otherwise, any configuration based on this function will be incorrect.
1196 *
1197 * @retval SYSCLK frequency
1198 */
HAL_RCC_GetSysClockFreq(void)1199 uint32_t HAL_RCC_GetSysClockFreq(void)
1200 {
1201 uint32_t tmpreg, pllm, plld, pllvco, msiclkrange; /* no init needed */
1202 uint32_t sysclockfreq;
1203
1204 tmpreg = RCC->CFGR;
1205
1206 /* Get SYSCLK source -------------------------------------------------------*/
1207 switch (tmpreg & RCC_CFGR_SWS)
1208 {
1209 case RCC_SYSCLKSOURCE_STATUS_HSI: /* HSI used as system clock source */
1210 {
1211 if ((RCC->CR & RCC_CR_HSIDIVF) != 0U)
1212 {
1213 sysclockfreq = (HSI_VALUE >> 2);
1214 }
1215 else
1216 {
1217 sysclockfreq = HSI_VALUE;
1218 }
1219 break;
1220 }
1221 case RCC_SYSCLKSOURCE_STATUS_HSE: /* HSE used as system clock */
1222 {
1223 sysclockfreq = HSE_VALUE;
1224 break;
1225 }
1226 case RCC_SYSCLKSOURCE_STATUS_PLLCLK: /* PLL used as system clock */
1227 {
1228 pllm = PLLMulTable[(uint32_t)(tmpreg & RCC_CFGR_PLLMUL) >> RCC_CFGR_PLLMUL_Pos];
1229 plld = ((uint32_t)(tmpreg & RCC_CFGR_PLLDIV) >> RCC_CFGR_PLLDIV_Pos) + 1U;
1230 if (__HAL_RCC_GET_PLL_OSCSOURCE() != RCC_PLLSOURCE_HSI)
1231 {
1232 /* HSE used as PLL clock source */
1233 pllvco = (HSE_VALUE * pllm) / plld;
1234 }
1235 else
1236 {
1237 if ((RCC->CR & RCC_CR_HSIDIVF) != 0U)
1238 {
1239 pllvco = ((HSI_VALUE >> 2) * pllm) / plld;
1240 }
1241 else
1242 {
1243 pllvco = (HSI_VALUE * pllm) / plld;
1244 }
1245 }
1246 sysclockfreq = pllvco;
1247 break;
1248 }
1249 case RCC_SYSCLKSOURCE_STATUS_MSI: /* MSI used as system clock source */
1250 default: /* MSI used as system clock */
1251 {
1252 msiclkrange = (RCC->ICSCR & RCC_ICSCR_MSIRANGE ) >> RCC_ICSCR_MSIRANGE_Pos;
1253 sysclockfreq = (32768U * (1UL << (msiclkrange + 1U)));
1254 break;
1255 }
1256 }
1257 return sysclockfreq;
1258 }
1259
1260 /**
1261 * @brief Returns the HCLK frequency
1262 * @note Each time HCLK changes, this function must be called to update the
1263 * right HCLK value. Otherwise, any configuration based on this function will be incorrect.
1264 *
1265 * @note The SystemCoreClock CMSIS variable is used to store System Clock Frequency
1266 * and updated within this function
1267 * @retval HCLK frequency
1268 */
HAL_RCC_GetHCLKFreq(void)1269 uint32_t HAL_RCC_GetHCLKFreq(void)
1270 {
1271 return SystemCoreClock;
1272 }
1273
1274 /**
1275 * @brief Returns the PCLK1 frequency
1276 * @note Each time PCLK1 changes, this function must be called to update the
1277 * right PCLK1 value. Otherwise, any configuration based on this function will be incorrect.
1278 * @retval PCLK1 frequency
1279 */
HAL_RCC_GetPCLK1Freq(void)1280 uint32_t HAL_RCC_GetPCLK1Freq(void)
1281 {
1282 /* Get HCLK source and Compute PCLK1 frequency ---------------------------*/
1283 return (HAL_RCC_GetHCLKFreq() >> APBPrescTable[(RCC->CFGR & RCC_CFGR_PPRE1) >> RCC_CFGR_PPRE1_Pos]);
1284 }
1285
1286 /**
1287 * @brief Returns the PCLK2 frequency
1288 * @note Each time PCLK2 changes, this function must be called to update the
1289 * right PCLK2 value. Otherwise, any configuration based on this function will be incorrect.
1290 * @retval PCLK2 frequency
1291 */
HAL_RCC_GetPCLK2Freq(void)1292 uint32_t HAL_RCC_GetPCLK2Freq(void)
1293 {
1294 /* Get HCLK source and Compute PCLK2 frequency ---------------------------*/
1295 return (HAL_RCC_GetHCLKFreq()>> APBPrescTable[(RCC->CFGR & RCC_CFGR_PPRE2) >> RCC_CFGR_PPRE2_Pos]);
1296 }
1297
1298 /**
1299 * @brief Configures the RCC_OscInitStruct according to the internal
1300 * RCC configuration registers.
1301 * @param RCC_OscInitStruct pointer to an RCC_OscInitTypeDef structure that
1302 * will be configured.
1303 * @retval None
1304 */
HAL_RCC_GetOscConfig(RCC_OscInitTypeDef * RCC_OscInitStruct)1305 void HAL_RCC_GetOscConfig(RCC_OscInitTypeDef *RCC_OscInitStruct)
1306 {
1307 /* Check the parameters */
1308 assert_param(RCC_OscInitStruct != (void *)NULL);
1309
1310 /* Set all possible values for the Oscillator type parameter ---------------*/
1311 RCC_OscInitStruct->OscillatorType = RCC_OSCILLATORTYPE_HSE | RCC_OSCILLATORTYPE_HSI \
1312 | RCC_OSCILLATORTYPE_LSE | RCC_OSCILLATORTYPE_LSI | RCC_OSCILLATORTYPE_MSI;
1313 #if defined(RCC_HSI48_SUPPORT)
1314 RCC_OscInitStruct->OscillatorType |= RCC_OSCILLATORTYPE_HSI48;
1315 #endif /* RCC_HSI48_SUPPORT */
1316
1317
1318 /* Get the HSE configuration -----------------------------------------------*/
1319 if((RCC->CR &RCC_CR_HSEBYP) == RCC_CR_HSEBYP)
1320 {
1321 RCC_OscInitStruct->HSEState = RCC_HSE_BYPASS;
1322 }
1323 else if((RCC->CR &RCC_CR_HSEON) == RCC_CR_HSEON)
1324 {
1325 RCC_OscInitStruct->HSEState = RCC_HSE_ON;
1326 }
1327 else
1328 {
1329 RCC_OscInitStruct->HSEState = RCC_HSE_OFF;
1330 }
1331
1332 /* Get the HSI configuration -----------------------------------------------*/
1333 if((RCC->CR &RCC_CR_HSION) == RCC_CR_HSION)
1334 {
1335 RCC_OscInitStruct->HSIState = RCC_HSI_ON;
1336 }
1337 else
1338 {
1339 RCC_OscInitStruct->HSIState = RCC_HSI_OFF;
1340 }
1341
1342 RCC_OscInitStruct->HSICalibrationValue = (uint32_t)((RCC->ICSCR & RCC_ICSCR_HSITRIM) >> 8);
1343
1344 /* Get the MSI configuration -----------------------------------------------*/
1345 if((RCC->CR &RCC_CR_MSION) == RCC_CR_MSION)
1346 {
1347 RCC_OscInitStruct->MSIState = RCC_MSI_ON;
1348 }
1349 else
1350 {
1351 RCC_OscInitStruct->MSIState = RCC_MSI_OFF;
1352 }
1353
1354 RCC_OscInitStruct->MSICalibrationValue = (uint32_t)((RCC->ICSCR & RCC_ICSCR_MSITRIM) >> RCC_ICSCR_MSITRIM_Pos);
1355 RCC_OscInitStruct->MSIClockRange = (uint32_t)((RCC->ICSCR & RCC_ICSCR_MSIRANGE));
1356
1357 /* Get the LSE configuration -----------------------------------------------*/
1358 if((RCC->CSR &RCC_CSR_LSEBYP) == RCC_CSR_LSEBYP)
1359 {
1360 RCC_OscInitStruct->LSEState = RCC_LSE_BYPASS;
1361 }
1362 else if((RCC->CSR &RCC_CSR_LSEON) == RCC_CSR_LSEON)
1363 {
1364 RCC_OscInitStruct->LSEState = RCC_LSE_ON;
1365 }
1366 else
1367 {
1368 RCC_OscInitStruct->LSEState = RCC_LSE_OFF;
1369 }
1370
1371 /* Get the LSI configuration -----------------------------------------------*/
1372 if((RCC->CSR &RCC_CSR_LSION) == RCC_CSR_LSION)
1373 {
1374 RCC_OscInitStruct->LSIState = RCC_LSI_ON;
1375 }
1376 else
1377 {
1378 RCC_OscInitStruct->LSIState = RCC_LSI_OFF;
1379 }
1380
1381 #if defined(RCC_HSI48_SUPPORT)
1382 /* Get the HSI48 configuration if any-----------------------------------------*/
1383 RCC_OscInitStruct->HSI48State = __HAL_RCC_GET_HSI48_STATE();
1384 #endif /* RCC_HSI48_SUPPORT */
1385
1386 /* Get the PLL configuration -----------------------------------------------*/
1387 if((RCC->CR &RCC_CR_PLLON) == RCC_CR_PLLON)
1388 {
1389 RCC_OscInitStruct->PLL.PLLState = RCC_PLL_ON;
1390 }
1391 else
1392 {
1393 RCC_OscInitStruct->PLL.PLLState = RCC_PLL_OFF;
1394 }
1395 RCC_OscInitStruct->PLL.PLLSource = (uint32_t)(RCC->CFGR & RCC_CFGR_PLLSRC);
1396 RCC_OscInitStruct->PLL.PLLMUL = (uint32_t)(RCC->CFGR & RCC_CFGR_PLLMUL);
1397 RCC_OscInitStruct->PLL.PLLDIV = (uint32_t)(RCC->CFGR & RCC_CFGR_PLLDIV);
1398 }
1399
1400 /**
1401 * @brief Get the RCC_ClkInitStruct according to the internal
1402 * RCC configuration registers.
1403 * @param RCC_ClkInitStruct pointer to an RCC_ClkInitTypeDef structure that
1404 * contains the current clock configuration.
1405 * @param pFLatency Pointer on the Flash Latency.
1406 * @retval None
1407 */
HAL_RCC_GetClockConfig(RCC_ClkInitTypeDef * RCC_ClkInitStruct,uint32_t * pFLatency)1408 void HAL_RCC_GetClockConfig(RCC_ClkInitTypeDef *RCC_ClkInitStruct, uint32_t *pFLatency)
1409 {
1410 /* Check the parameters */
1411 assert_param(RCC_ClkInitStruct != (void *)NULL);
1412 assert_param(pFLatency != (void *)NULL);
1413
1414 /* Set all possible values for the Clock type parameter --------------------*/
1415 RCC_ClkInitStruct->ClockType = RCC_CLOCKTYPE_SYSCLK | RCC_CLOCKTYPE_HCLK | RCC_CLOCKTYPE_PCLK1 | RCC_CLOCKTYPE_PCLK2;
1416
1417 /* Get the SYSCLK configuration --------------------------------------------*/
1418 RCC_ClkInitStruct->SYSCLKSource = (uint32_t)(RCC->CFGR & RCC_CFGR_SW);
1419
1420 /* Get the HCLK configuration ----------------------------------------------*/
1421 RCC_ClkInitStruct->AHBCLKDivider = (uint32_t)(RCC->CFGR & RCC_CFGR_HPRE);
1422
1423 /* Get the APB1 configuration ----------------------------------------------*/
1424 RCC_ClkInitStruct->APB1CLKDivider = (uint32_t)(RCC->CFGR & RCC_CFGR_PPRE1);
1425
1426 /* Get the APB2 configuration ----------------------------------------------*/
1427 RCC_ClkInitStruct->APB2CLKDivider = (uint32_t)((RCC->CFGR & RCC_CFGR_PPRE2) >> 3);
1428
1429 /* Get the Flash Wait State (Latency) configuration ------------------------*/
1430 *pFLatency = __HAL_FLASH_GET_LATENCY();
1431 }
1432
1433 #if defined(RCC_HSECSS_SUPPORT)
1434 /**
1435 * @brief This function handles the RCC CSS interrupt request.
1436 * @note This API should be called under the NMI_Handler().
1437 * @retval None
1438 */
HAL_RCC_NMI_IRQHandler(void)1439 void HAL_RCC_NMI_IRQHandler(void)
1440 {
1441 /* Check RCC CSSF flag */
1442 if(__HAL_RCC_GET_IT(RCC_IT_CSS))
1443 {
1444 /* RCC Clock Security System interrupt user callback */
1445 HAL_RCC_CSSCallback();
1446
1447 /* Clear RCC CSS pending bit */
1448 __HAL_RCC_CLEAR_IT(RCC_IT_CSS);
1449 }
1450 }
1451
1452 /**
1453 * @brief RCC Clock Security System interrupt callback
1454 * @retval none
1455 */
HAL_RCC_CSSCallback(void)1456 __weak void HAL_RCC_CSSCallback(void)
1457 {
1458 /* NOTE : This function Should not be modified, when the callback is needed,
1459 the HAL_RCC_CSSCallback could be implemented in the user file
1460 */
1461 }
1462
1463 #endif /* RCC_HSECSS_SUPPORT */
1464 /**
1465 * @}
1466 */
1467
1468 /**
1469 * @}
1470 */
1471
1472 /* Private function prototypes -----------------------------------------------*/
1473 /** @addtogroup RCC_Private_Functions
1474 * @{
1475 */
1476
1477 /**
1478 * @}
1479 */
1480
1481 #endif /* HAL_RCC_MODULE_ENABLED */
1482 /**
1483 * @}
1484 */
1485
1486 /**
1487 * @}
1488 */
1489
1490 /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
1491