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