comparison l476rg/Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_rcc.c @ 0:32a3b1785697

a rough draft of Hardware Abstraction Layer for C++ STM32L476RG drivers
author cin
date Thu, 12 Jan 2017 02:45:43 +0300
parents
children
comparison
equal deleted inserted replaced
-1:000000000000 0:32a3b1785697
1 /**
2 ******************************************************************************
3 * @file stm32l4xx_hal_rcc.c
4 * @author MCD Application Team
5 * @version V1.6.0
6 * @date 28-October-2016
7 * @brief RCC HAL module driver.
8 * This file provides firmware functions to manage the following
9 * functionalities of the Reset and Clock Control (RCC) peripheral:
10 * + Initialization and de-initialization functions
11 * + Peripheral Control functions
12 *
13 @verbatim
14 ==============================================================================
15 ##### RCC specific features #####
16 ==============================================================================
17 [..]
18 After reset the device is running from Multiple Speed Internal oscillator
19 (4 MHz) with Flash 0 wait state. Flash prefetch buffer, D-Cache
20 and I-Cache are disabled, and all peripherals are off except internal
21 SRAM, Flash and JTAG.
22
23 (+) There is no prescaler on High speed (AHBs) and Low speed (APBs) busses:
24 all peripherals mapped on these busses are running at MSI speed.
25 (+) The clock for all peripherals is switched off, except the SRAM and FLASH.
26 (+) All GPIOs are in analog mode, except the JTAG pins which
27 are assigned to be used for debug purpose.
28
29 [..]
30 Once the device started from reset, the user application has to:
31 (+) Configure the clock source to be used to drive the System clock
32 (if the application needs higher frequency/performance)
33 (+) Configure the System clock frequency and Flash settings
34 (+) Configure the AHB and APB busses prescalers
35 (+) Enable the clock for the peripheral(s) to be used
36 (+) Configure the clock source(s) for peripherals which clocks are not
37 derived from the System clock (SAIx, RTC, ADC, USB OTG FS/SDMMC1/RNG)
38
39 @endverbatim
40 ******************************************************************************
41 * @attention
42 *
43 * <h2><center>&copy; COPYRIGHT(c) 2016 STMicroelectronics</center></h2>
44 *
45 * Redistribution and use in source and binary forms, with or without modification,
46 * are permitted provided that the following conditions are met:
47 * 1. Redistributions of source code must retain the above copyright notice,
48 * this list of conditions and the following disclaimer.
49 * 2. Redistributions in binary form must reproduce the above copyright notice,
50 * this list of conditions and the following disclaimer in the documentation
51 * and/or other materials provided with the distribution.
52 * 3. Neither the name of STMicroelectronics nor the names of its contributors
53 * may be used to endorse or promote products derived from this software
54 * without specific prior written permission.
55 *
56 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
57 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
58 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
59 * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
60 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
61 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
62 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
63 * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
64 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
65 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
66 *
67 ******************************************************************************
68 */
69
70 /* Includes ------------------------------------------------------------------*/
71 #include "stm32l4xx_hal.h"
72
73 /** @addtogroup STM32L4xx_HAL_Driver
74 * @{
75 */
76
77 /** @defgroup RCC RCC
78 * @brief RCC HAL module driver
79 * @{
80 */
81
82 #ifdef HAL_RCC_MODULE_ENABLED
83
84 /* Private typedef -----------------------------------------------------------*/
85 /* Private define ------------------------------------------------------------*/
86 /** @defgroup RCC_Private_Constants RCC Private Constants
87 * @{
88 */
89 #define HSE_TIMEOUT_VALUE HSE_STARTUP_TIMEOUT
90 #define HSI_TIMEOUT_VALUE ((uint32_t)2U) /* 2 ms (minimum Tick + 1) */
91 #define MSI_TIMEOUT_VALUE ((uint32_t)2U) /* 2 ms (minimum Tick + 1) */
92 #define LSI_TIMEOUT_VALUE ((uint32_t)2U) /* 2 ms (minimum Tick + 1) */
93 #define HSI48_TIMEOUT_VALUE ((uint32_t)2U) /* 2 ms (minimum Tick + 1) */
94 #define PLL_TIMEOUT_VALUE ((uint32_t)2U) /* 2 ms (minimum Tick + 1) */
95 #define CLOCKSWITCH_TIMEOUT_VALUE ((uint32_t)5000U) /* 5 s */
96 /**
97 * @}
98 */
99
100 /* Private macro -------------------------------------------------------------*/
101 /** @defgroup RCC_Private_Macros RCC Private Macros
102 * @{
103 */
104 #define __MCO1_CLK_ENABLE() __HAL_RCC_GPIOA_CLK_ENABLE()
105 #define MCO1_GPIO_PORT GPIOA
106 #define MCO1_PIN GPIO_PIN_8
107
108 #define RCC_PLL_OSCSOURCE_CONFIG(__HAL_RCC_PLLSOURCE__) \
109 (MODIFY_REG(RCC->PLLCFGR, RCC_PLLCFGR_PLLSRC, (uint32_t)(__HAL_RCC_PLLSOURCE__)))
110 /**
111 * @}
112 */
113
114 /* Private variables ---------------------------------------------------------*/
115 /** @defgroup RCC_Private_Variables RCC Private Variables
116 * @{
117 */
118
119 /**
120 * @}
121 */
122
123 /* Private function prototypes -----------------------------------------------*/
124 /** @defgroup RCC_Private_Functions RCC Private Functions
125 * @{
126 */
127 static HAL_StatusTypeDef RCC_SetFlashLatencyFromMSIRange(uint32_t msirange);
128 /**
129 * @}
130 */
131
132 /* Exported functions --------------------------------------------------------*/
133
134 /** @defgroup RCC_Exported_Functions RCC Exported Functions
135 * @{
136 */
137
138 /** @defgroup RCC_Exported_Functions_Group1 Initialization and de-initialization functions
139 * @brief Initialization and Configuration functions
140 *
141 @verbatim
142 ===============================================================================
143 ##### Initialization and de-initialization functions #####
144 ===============================================================================
145 [..]
146 This section provides functions allowing to configure the internal and external oscillators
147 (HSE, HSI, LSE, MSI, LSI, PLL, CSS and MCO) and the System busses clocks (SYSCLK, AHB, APB1
148 and APB2).
149
150 [..] Internal/external clock and PLL configuration
151 (+) HSI (high-speed internal): 16 MHz factory-trimmed RC used directly or through
152 the PLL as System clock source.
153
154 (+) MSI (Mutiple Speed Internal): Its frequency is software trimmable from 100KHZ to 48MHZ.
155 It can be used to generate the clock for the USB OTG FS (48 MHz).
156 The number of flash wait states is automatically adjusted when MSI range is updated with
157 HAL_RCC_OscConfig() and the MSI is used as System clock source.
158
159 (+) LSI (low-speed internal): 32 KHz low consumption RC used as IWDG and/or RTC
160 clock source.
161
162 (+) HSE (high-speed external): 4 to 48 MHz crystal oscillator used directly or
163 through the PLL as System clock source. Can be used also optionally as RTC clock source.
164
165 (+) LSE (low-speed external): 32.768 KHz oscillator used optionally as RTC clock source.
166
167 (+) PLL (clocked by HSI, HSE or MSI) providing up to three independent output clocks:
168 (++) The first output is used to generate the high speed system clock (up to 80MHz).
169 (++) The second output is used to generate the clock for the USB OTG FS (48 MHz),
170 the random analog generator (<=48 MHz) and the SDMMC1 (<= 48 MHz).
171 (++) The third output is used to generate an accurate clock to achieve
172 high-quality audio performance on SAI interface.
173
174 (+) PLLSAI1 (clocked by HSI, HSE or MSI) providing up to three independent output clocks:
175 (++) The first output is used to generate SAR ADC1 clock.
176 (++) The second output is used to generate the clock for the USB OTG FS (48 MHz),
177 the random analog generator (<=48 MHz) and the SDMMC1 (<= 48 MHz).
178 (++) The Third output is used to generate an accurate clock to achieve
179 high-quality audio performance on SAI interface.
180
181 (+) PLLSAI2 (clocked by HSI , HSE or MSI) providing up to two independent output clocks:
182 (++) The first output is used to generate SAR ADC2 clock.
183 (++) The second output is used to generate an accurate clock to achieve
184 high-quality audio performance on SAI interface.
185
186 (+) CSS (Clock security system): once enabled, if a HSE clock failure occurs
187 (HSE used directly or through PLL as System clock source), the System clock
188 is automatically switched to HSI and an interrupt is generated if enabled.
189 The interrupt is linked to the Cortex-M4 NMI (Non-Maskable Interrupt)
190 exception vector.
191
192 (+) MCO (microcontroller clock output): used to output MSI, LSI, HSI, LSE, HSE or
193 main PLL clock (through a configurable prescaler) on PA8 pin.
194
195 [..] System, AHB and APB busses clocks configuration
196 (+) Several clock sources can be used to drive the System clock (SYSCLK): MSI, HSI,
197 HSE and main PLL.
198 The AHB clock (HCLK) is derived from System clock through configurable
199 prescaler and used to clock the CPU, memory and peripherals mapped
200 on AHB bus (DMA, GPIO...). APB1 (PCLK1) and APB2 (PCLK2) clocks are derived
201 from AHB clock through configurable prescalers and used to clock
202 the peripherals mapped on these busses. You can use
203 "HAL_RCC_GetSysClockFreq()" function to retrieve the frequencies of these clocks.
204
205 -@- All the peripheral clocks are derived from the System clock (SYSCLK) except:
206
207 (+@) SAI: the SAI clock can be derived either from a specific PLL (PLLSAI1) or (PLLSAI2) or
208 from an external clock mapped on the SAI_CKIN pin.
209 You have to use HAL_RCCEx_PeriphCLKConfig() function to configure this clock.
210 (+@) RTC: the RTC clock can be derived either from the LSI, LSE or HSE clock
211 divided by 2 to 31.
212 You have to use __HAL_RCC_RTC_ENABLE() and HAL_RCCEx_PeriphCLKConfig() function
213 to configure this clock.
214 (+@) USB OTG FS, SDMMC1 and RNG: USB OTG FS requires a frequency equal to 48 MHz
215 to work correctly, while the SDMMC1 and RNG peripherals require a frequency
216 equal or lower than to 48 MHz. This clock is derived of the main PLL or PLLSAI1
217 through PLLQ divider. You have to enable the peripheral clock and use
218 HAL_RCCEx_PeriphCLKConfig() function to configure this clock.
219 (+@) IWDG clock which is always the LSI clock.
220
221
222 (+) The maximum frequency of the SYSCLK, HCLK, PCLK1 and PCLK2 is 80 MHz.
223 The clock source frequency should be adapted depending on the device voltage range
224 as listed in the Reference Manual "Clock source frequency versus voltage scaling" chapter.
225
226 @endverbatim
227
228 Table 1. HCLK clock frequency.
229 +-------------------------------------------------------+
230 | Latency | HCLK clock frequency (MHz) |
231 | |-------------------------------------|
232 | | voltage range 1 | voltage range 2 |
233 | | 1.2 V | 1.0 V |
234 |-----------------|------------------|------------------|
235 |0WS(1 CPU cycles)| 0 < HCLK <= 16 | 0 < HCLK <= 6 |
236 |-----------------|------------------|------------------|
237 |1WS(2 CPU cycles)| 16 < HCLK <= 32 | 6 < HCLK <= 12 |
238 |-----------------|------------------|------------------|
239 |2WS(3 CPU cycles)| 32 < HCLK <= 48 | 12 < HCLK <= 18 |
240 |-----------------|------------------|------------------|
241 |3WS(4 CPU cycles)| 48 < HCLK <= 64 | 18 < HCLK <= 26 |
242 |-----------------|------------------|------------------|
243 |4WS(5 CPU cycles)| 64 < HCLK <= 80 | 18 < HCLK <= 26 |
244 +-------------------------------------------------------+
245 * @{
246 */
247
248 /**
249 * @brief Reset the RCC clock configuration to the default reset state.
250 * @note The default reset state of the clock configuration is given below:
251 * - MSI ON and used as system clock source
252 * - HSE, HSI, PLL, PLLSAI1 and PLLISAI2 OFF
253 * - AHB, APB1 and APB2 prescaler set to 1.
254 * - CSS, MCO1 OFF
255 * - All interrupts disabled
256 * @note This function doesn't modify the configuration of the
257 * - Peripheral clocks
258 * - LSI, LSE and RTC clocks
259 * @retval None
260 */
261 void HAL_RCC_DeInit(void)
262 {
263 /* Set MSION bit */
264 SET_BIT(RCC->CR, RCC_CR_MSION);
265
266 /* Insure MSIRDY bit is set before writing default MSIRANGE value */
267 while(READ_BIT(RCC->CR, RCC_CR_MSIRDY) == RESET) { __NOP(); }
268
269 /* Set MSIRANGE default value */
270 MODIFY_REG(RCC->CR, RCC_CR_MSIRANGE, RCC_MSIRANGE_6);
271
272 /* Reset CFGR register (MSI is selected as system clock source) */
273 CLEAR_REG(RCC->CFGR);
274
275 /* Reset HSION, HSIKERON, HSIASFS, HSEON, HSECSSON, PLLON, PLLSAIxON bits */
276 #if defined(RCC_PLLSAI2_SUPPORT)
277
278 CLEAR_BIT(RCC->CR, RCC_CR_HSEON | RCC_CR_HSION | RCC_CR_HSIKERON| RCC_CR_HSIASFS | RCC_CR_PLLON | RCC_CR_PLLSAI1ON | RCC_CR_PLLSAI2ON);
279
280 #else
281
282 CLEAR_BIT(RCC->CR, RCC_CR_HSEON | RCC_CR_HSION | RCC_CR_HSIKERON| RCC_CR_HSIASFS | RCC_CR_PLLON | RCC_CR_PLLSAI1ON);
283
284 #endif /* RCC_PLLSAI2_SUPPORT */
285
286 /* Reset PLLCFGR register */
287 CLEAR_REG(RCC->PLLCFGR);
288 SET_BIT(RCC->PLLCFGR, RCC_PLLCFGR_PLLN_4 );
289
290 /* Reset PLLSAI1CFGR register */
291 CLEAR_REG(RCC->PLLSAI1CFGR);
292 SET_BIT(RCC->PLLSAI1CFGR, RCC_PLLSAI1CFGR_PLLSAI1N_4 );
293
294 #if defined(RCC_PLLSAI2_SUPPORT)
295
296 /* Reset PLLSAI2CFGR register */
297 CLEAR_REG(RCC->PLLSAI2CFGR);
298 SET_BIT(RCC->PLLSAI2CFGR, RCC_PLLSAI2CFGR_PLLSAI2N_4 );
299
300 #endif /* RCC_PLLSAI2_SUPPORT */
301
302 /* Reset HSEBYP bit */
303 CLEAR_BIT(RCC->CR, RCC_CR_HSEBYP);
304
305 /* Disable all interrupts */
306 CLEAR_REG(RCC->CIER);
307
308 /* Update the SystemCoreClock global variable */
309 SystemCoreClock = MSI_VALUE;
310 }
311
312 /**
313 * @brief Initialize the RCC Oscillators according to the specified parameters in the
314 * RCC_OscInitTypeDef.
315 * @param RCC_OscInitStruct pointer to an RCC_OscInitTypeDef structure that
316 * contains the configuration information for the RCC Oscillators.
317 * @note The PLL is not disabled when used as system clock.
318 * @note Transitions LSE Bypass to LSE On and LSE On to LSE Bypass are not
319 * supported by this macro. User should request a transition to LSE Off
320 * first and then LSE On or LSE Bypass.
321 * @note Transition HSE Bypass to HSE On and HSE On to HSE Bypass are not
322 * supported by this macro. User should request a transition to HSE Off
323 * first and then HSE On or HSE Bypass.
324 * @retval HAL status
325 */
326 HAL_StatusTypeDef HAL_RCC_OscConfig(RCC_OscInitTypeDef *RCC_OscInitStruct)
327 {
328 uint32_t tickstart = 0;
329
330 /* Check the parameters */
331 assert_param(RCC_OscInitStruct != NULL);
332 assert_param(IS_RCC_OSCILLATORTYPE(RCC_OscInitStruct->OscillatorType));
333
334 /*----------------------------- MSI Configuration --------------------------*/
335 if(((RCC_OscInitStruct->OscillatorType) & RCC_OSCILLATORTYPE_MSI) == RCC_OSCILLATORTYPE_MSI)
336 {
337 /* Check the parameters */
338 assert_param(IS_RCC_MSI(RCC_OscInitStruct->MSIState));
339 assert_param(IS_RCC_MSICALIBRATION_VALUE(RCC_OscInitStruct->MSICalibrationValue));
340 assert_param(IS_RCC_MSI_CLOCK_RANGE(RCC_OscInitStruct->MSIClockRange));
341
342 /* When the MSI is used as system clock it will not be disabled */
343 if((__HAL_RCC_GET_SYSCLK_SOURCE() == RCC_CFGR_SWS_MSI) )
344 {
345 if((READ_BIT(RCC->CR, RCC_CR_MSIRDY) != RESET) && (RCC_OscInitStruct->MSIState == RCC_MSI_OFF))
346 {
347 return HAL_ERROR;
348 }
349
350 /* Otherwise, just the calibration and MSI range change are allowed */
351 else
352 {
353 /* To correctly read data from FLASH memory, the number of wait states (LATENCY)
354 must be correctly programmed according to the frequency of the CPU clock
355 (HCLK) and the supply voltage of the device. */
356 if(RCC_OscInitStruct->MSIClockRange > __HAL_RCC_GET_MSI_RANGE())
357 {
358 /* First increase number of wait states update if necessary */
359 if(RCC_SetFlashLatencyFromMSIRange(RCC_OscInitStruct->MSIClockRange) != HAL_OK)
360 {
361 return HAL_ERROR;
362 }
363
364 /* Selects the Multiple Speed oscillator (MSI) clock range .*/
365 __HAL_RCC_MSI_RANGE_CONFIG(RCC_OscInitStruct->MSIClockRange);
366 /* Adjusts the Multiple Speed oscillator (MSI) calibration value.*/
367 __HAL_RCC_MSI_CALIBRATIONVALUE_ADJUST(RCC_OscInitStruct->MSICalibrationValue);
368 }
369 else
370 {
371 /* Else, keep current flash latency while decreasing applies */
372 /* Selects the Multiple Speed oscillator (MSI) clock range .*/
373 __HAL_RCC_MSI_RANGE_CONFIG(RCC_OscInitStruct->MSIClockRange);
374 /* Adjusts the Multiple Speed oscillator (MSI) calibration value.*/
375 __HAL_RCC_MSI_CALIBRATIONVALUE_ADJUST(RCC_OscInitStruct->MSICalibrationValue);
376
377 /* Decrease number of wait states update if necessary */
378 if(RCC_SetFlashLatencyFromMSIRange(RCC_OscInitStruct->MSIClockRange) != HAL_OK)
379 {
380 return HAL_ERROR;
381 }
382 }
383
384 /* Update the SystemCoreClock global variable */
385 SystemCoreClock = HAL_RCC_GetSysClockFreq() >> AHBPrescTable[(RCC->CFGR & RCC_CFGR_HPRE)>> POSITION_VAL(RCC_CFGR_HPRE)];
386
387 /* Configure the source of time base considering new system clocks settings*/
388 HAL_InitTick (TICK_INT_PRIORITY);
389 }
390 }
391 else
392 {
393 /* Check the MSI State */
394 if(RCC_OscInitStruct->MSIState != RCC_MSI_OFF)
395 {
396 /* Enable the Internal High Speed oscillator (MSI). */
397 __HAL_RCC_MSI_ENABLE();
398
399 /* Get timeout */
400 tickstart = HAL_GetTick();
401
402 /* Wait till MSI is ready */
403 while(READ_BIT(RCC->CR, RCC_CR_MSIRDY) == RESET)
404 {
405 if((HAL_GetTick() - tickstart) > MSI_TIMEOUT_VALUE)
406 {
407 return HAL_TIMEOUT;
408 }
409 }
410 /* Selects the Multiple Speed oscillator (MSI) clock range .*/
411 __HAL_RCC_MSI_RANGE_CONFIG(RCC_OscInitStruct->MSIClockRange);
412 /* Adjusts the Multiple Speed oscillator (MSI) calibration value.*/
413 __HAL_RCC_MSI_CALIBRATIONVALUE_ADJUST(RCC_OscInitStruct->MSICalibrationValue);
414
415 }
416 else
417 {
418 /* Disable the Internal High Speed oscillator (MSI). */
419 __HAL_RCC_MSI_DISABLE();
420
421 /* Get timeout */
422 tickstart = HAL_GetTick();
423
424 /* Wait till MSI is ready */
425 while(READ_BIT(RCC->CR, RCC_CR_MSIRDY) != RESET)
426 {
427 if((HAL_GetTick() - tickstart) > MSI_TIMEOUT_VALUE)
428 {
429 return HAL_TIMEOUT;
430 }
431 }
432 }
433 }
434 }
435 /*------------------------------- HSE Configuration ------------------------*/
436 if(((RCC_OscInitStruct->OscillatorType) & RCC_OSCILLATORTYPE_HSE) == RCC_OSCILLATORTYPE_HSE)
437 {
438 /* Check the parameters */
439 assert_param(IS_RCC_HSE(RCC_OscInitStruct->HSEState));
440
441 /* When the HSE is used as system clock or clock source for PLL in these cases it is not allowed to be disabled */
442 if((__HAL_RCC_GET_SYSCLK_SOURCE() == RCC_CFGR_SWS_HSE) ||
443 ((__HAL_RCC_GET_SYSCLK_SOURCE() == RCC_CFGR_SWS_PLL) && (__HAL_RCC_GET_PLL_OSCSOURCE() == RCC_PLLSOURCE_HSE)))
444 {
445 if((READ_BIT(RCC->CR, RCC_CR_HSERDY) != RESET) && (RCC_OscInitStruct->HSEState == RCC_HSE_OFF))
446 {
447 return HAL_ERROR;
448 }
449 }
450 else
451 {
452 /* Set the new HSE configuration ---------------------------------------*/
453 __HAL_RCC_HSE_CONFIG(RCC_OscInitStruct->HSEState);
454
455 /* Check the HSE State */
456 if(RCC_OscInitStruct->HSEState != RCC_HSE_OFF)
457 {
458 /* Get Start Tick*/
459 tickstart = HAL_GetTick();
460
461 /* Wait till HSE is ready */
462 while(READ_BIT(RCC->CR, RCC_CR_HSERDY) == RESET)
463 {
464 if((HAL_GetTick() - tickstart) > HSE_TIMEOUT_VALUE)
465 {
466 return HAL_TIMEOUT;
467 }
468 }
469 }
470 else
471 {
472 /* Get Start Tick*/
473 tickstart = HAL_GetTick();
474
475 /* Wait till HSE is disabled */
476 while(READ_BIT(RCC->CR, RCC_CR_HSERDY) != RESET)
477 {
478 if((HAL_GetTick() - tickstart) > HSE_TIMEOUT_VALUE)
479 {
480 return HAL_TIMEOUT;
481 }
482 }
483 }
484 }
485 }
486 /*----------------------------- HSI Configuration --------------------------*/
487 if(((RCC_OscInitStruct->OscillatorType) & RCC_OSCILLATORTYPE_HSI) == RCC_OSCILLATORTYPE_HSI)
488 {
489 /* Check the parameters */
490 assert_param(IS_RCC_HSI(RCC_OscInitStruct->HSIState));
491 assert_param(IS_RCC_HSI_CALIBRATION_VALUE(RCC_OscInitStruct->HSICalibrationValue));
492
493 /* Check if HSI is used as system clock or as PLL source when PLL is selected as system clock */
494 if((__HAL_RCC_GET_SYSCLK_SOURCE() == RCC_CFGR_SWS_HSI) ||
495 ((__HAL_RCC_GET_SYSCLK_SOURCE() == RCC_CFGR_SWS_PLL) && (__HAL_RCC_GET_PLL_OSCSOURCE() == RCC_PLLSOURCE_HSI)))
496 {
497 /* When HSI is used as system clock it will not be disabled */
498 if((READ_BIT(RCC->CR, RCC_CR_HSIRDY) != RESET) && (RCC_OscInitStruct->HSIState == RCC_HSI_OFF))
499 {
500 return HAL_ERROR;
501 }
502 /* Otherwise, just the calibration is allowed */
503 else
504 {
505 /* Adjusts the Internal High Speed oscillator (HSI) calibration value.*/
506 __HAL_RCC_HSI_CALIBRATIONVALUE_ADJUST(RCC_OscInitStruct->HSICalibrationValue);
507 }
508 }
509 else
510 {
511 /* Check the HSI State */
512 if(RCC_OscInitStruct->HSIState != RCC_HSI_OFF)
513 {
514 /* Enable the Internal High Speed oscillator (HSI). */
515 __HAL_RCC_HSI_ENABLE();
516
517 /* Get Start Tick*/
518 tickstart = HAL_GetTick();
519
520 /* Wait till HSI is ready */
521 while(READ_BIT(RCC->CR, RCC_CR_HSIRDY) == RESET)
522 {
523 if((HAL_GetTick() - tickstart) > HSI_TIMEOUT_VALUE)
524 {
525 return HAL_TIMEOUT;
526 }
527 }
528
529 /* Adjusts the Internal High Speed oscillator (HSI) calibration value.*/
530 __HAL_RCC_HSI_CALIBRATIONVALUE_ADJUST(RCC_OscInitStruct->HSICalibrationValue);
531 }
532 else
533 {
534 /* Disable the Internal High Speed oscillator (HSI). */
535 __HAL_RCC_HSI_DISABLE();
536
537 /* Get Start Tick*/
538 tickstart = HAL_GetTick();
539
540 /* Wait till HSI is disabled */
541 while(READ_BIT(RCC->CR, RCC_CR_HSIRDY) != RESET)
542 {
543 if((HAL_GetTick() - tickstart) > HSI_TIMEOUT_VALUE)
544 {
545 return HAL_TIMEOUT;
546 }
547 }
548 }
549 }
550 }
551 /*------------------------------ LSI Configuration -------------------------*/
552 if(((RCC_OscInitStruct->OscillatorType) & RCC_OSCILLATORTYPE_LSI) == RCC_OSCILLATORTYPE_LSI)
553 {
554 /* Check the parameters */
555 assert_param(IS_RCC_LSI(RCC_OscInitStruct->LSIState));
556
557 /* Check the LSI State */
558 if(RCC_OscInitStruct->LSIState != RCC_LSI_OFF)
559 {
560 /* Enable the Internal Low Speed oscillator (LSI). */
561 __HAL_RCC_LSI_ENABLE();
562
563 /* Get Start Tick*/
564 tickstart = HAL_GetTick();
565
566 /* Wait till LSI is ready */
567 while(READ_BIT(RCC->CSR, RCC_CSR_LSIRDY) == RESET)
568 {
569 if((HAL_GetTick() - tickstart) > LSI_TIMEOUT_VALUE)
570 {
571 return HAL_TIMEOUT;
572 }
573 }
574 }
575 else
576 {
577 /* Disable the Internal Low Speed oscillator (LSI). */
578 __HAL_RCC_LSI_DISABLE();
579
580 /* Get Start Tick*/
581 tickstart = HAL_GetTick();
582
583 /* Wait till LSI is disabled */
584 while(READ_BIT(RCC->CSR, RCC_CSR_LSIRDY) != RESET)
585 {
586 if((HAL_GetTick() - tickstart) > LSI_TIMEOUT_VALUE)
587 {
588 return HAL_TIMEOUT;
589 }
590 }
591 }
592 }
593 /*------------------------------ LSE Configuration -------------------------*/
594 if(((RCC_OscInitStruct->OscillatorType) & RCC_OSCILLATORTYPE_LSE) == RCC_OSCILLATORTYPE_LSE)
595 {
596 FlagStatus pwrclkchanged = RESET;
597
598 /* Check the parameters */
599 assert_param(IS_RCC_LSE(RCC_OscInitStruct->LSEState));
600
601 /* Update LSE configuration in Backup Domain control register */
602 /* Requires to enable write access to Backup Domain of necessary */
603 if(HAL_IS_BIT_CLR(RCC->APB1ENR1, RCC_APB1ENR1_PWREN))
604 {
605 __HAL_RCC_PWR_CLK_ENABLE();
606 pwrclkchanged = SET;
607 }
608
609 if(HAL_IS_BIT_CLR(PWR->CR1, PWR_CR1_DBP))
610 {
611 /* Enable write access to Backup domain */
612 SET_BIT(PWR->CR1, PWR_CR1_DBP);
613
614 /* Wait for Backup domain Write protection disable */
615 tickstart = HAL_GetTick();
616
617 while(HAL_IS_BIT_CLR(PWR->CR1, PWR_CR1_DBP))
618 {
619 if((HAL_GetTick() - tickstart) > RCC_DBP_TIMEOUT_VALUE)
620 {
621 return HAL_TIMEOUT;
622 }
623 }
624 }
625
626 /* Set the new LSE configuration -----------------------------------------*/
627 __HAL_RCC_LSE_CONFIG(RCC_OscInitStruct->LSEState);
628
629 /* Check the LSE State */
630 if(RCC_OscInitStruct->LSEState != RCC_LSE_OFF)
631 {
632 /* Get Start Tick*/
633 tickstart = HAL_GetTick();
634
635 /* Wait till LSE is ready */
636 while(READ_BIT(RCC->BDCR, RCC_BDCR_LSERDY) == RESET)
637 {
638 if((HAL_GetTick() - tickstart) > RCC_LSE_TIMEOUT_VALUE)
639 {
640 return HAL_TIMEOUT;
641 }
642 }
643 }
644 else
645 {
646 /* Get Start Tick*/
647 tickstart = HAL_GetTick();
648
649 /* Wait till LSE is disabled */
650 while(READ_BIT(RCC->BDCR, RCC_BDCR_LSERDY) != RESET)
651 {
652 if((HAL_GetTick() - tickstart) > RCC_LSE_TIMEOUT_VALUE)
653 {
654 return HAL_TIMEOUT;
655 }
656 }
657 }
658
659 /* Restore clock configuration if changed */
660 if(pwrclkchanged == SET)
661 {
662 __HAL_RCC_PWR_CLK_DISABLE();
663 }
664 }
665 #if defined(RCC_HSI48_SUPPORT)
666 /*------------------------------ HSI48 Configuration -----------------------*/
667 if(((RCC_OscInitStruct->OscillatorType) & RCC_OSCILLATORTYPE_HSI48) == RCC_OSCILLATORTYPE_HSI48)
668 {
669 /* Check the parameters */
670 assert_param(IS_RCC_HSI48(RCC_OscInitStruct->HSI48State));
671
672 /* Check the LSI State */
673 if(RCC_OscInitStruct->HSI48State != RCC_HSI48_OFF)
674 {
675 /* Enable the Internal Low Speed oscillator (HSI48). */
676 __HAL_RCC_HSI48_ENABLE();
677
678 /* Get Start Tick*/
679 tickstart = HAL_GetTick();
680
681 /* Wait till HSI48 is ready */
682 while(READ_BIT(RCC->CRRCR, RCC_CRRCR_HSI48RDY) == RESET)
683 {
684 if((HAL_GetTick() - tickstart) > HSI48_TIMEOUT_VALUE)
685 {
686 return HAL_TIMEOUT;
687 }
688 }
689 }
690 else
691 {
692 /* Disable the Internal Low Speed oscillator (HSI48). */
693 __HAL_RCC_HSI48_DISABLE();
694
695 /* Get Start Tick*/
696 tickstart = HAL_GetTick();
697
698 /* Wait till HSI48 is disabled */
699 while(READ_BIT(RCC->CRRCR, RCC_CRRCR_HSI48RDY) != RESET)
700 {
701 if((HAL_GetTick() - tickstart) > HSI48_TIMEOUT_VALUE)
702 {
703 return HAL_TIMEOUT;
704 }
705 }
706 }
707 }
708 #endif /* RCC_HSI48_SUPPORT */
709 /*-------------------------------- PLL Configuration -----------------------*/
710 /* Check the parameters */
711 assert_param(IS_RCC_PLL(RCC_OscInitStruct->PLL.PLLState));
712
713 if(RCC_OscInitStruct->PLL.PLLState != RCC_PLL_NONE)
714 {
715 /* Check if the PLL is used as system clock or not */
716 if(__HAL_RCC_GET_SYSCLK_SOURCE() != RCC_CFGR_SWS_PLL)
717 {
718 if(RCC_OscInitStruct->PLL.PLLState == RCC_PLL_ON)
719 {
720 /* Check the parameters */
721 assert_param(IS_RCC_PLLSOURCE(RCC_OscInitStruct->PLL.PLLSource));
722 assert_param(IS_RCC_PLLM_VALUE(RCC_OscInitStruct->PLL.PLLM));
723 assert_param(IS_RCC_PLLN_VALUE(RCC_OscInitStruct->PLL.PLLN));
724 assert_param(IS_RCC_PLLP_VALUE(RCC_OscInitStruct->PLL.PLLP));
725 assert_param(IS_RCC_PLLQ_VALUE(RCC_OscInitStruct->PLL.PLLQ));
726 assert_param(IS_RCC_PLLR_VALUE(RCC_OscInitStruct->PLL.PLLR));
727
728 /* Disable the main PLL. */
729 __HAL_RCC_PLL_DISABLE();
730
731 /* Get Start Tick*/
732 tickstart = HAL_GetTick();
733
734 /* Wait till PLL is ready */
735 while(READ_BIT(RCC->CR, RCC_CR_PLLRDY) != RESET)
736 {
737 if((HAL_GetTick() - tickstart) > PLL_TIMEOUT_VALUE)
738 {
739 return HAL_TIMEOUT;
740 }
741 }
742
743 /* Configure the main PLL clock source, multiplication and division factors. */
744 __HAL_RCC_PLL_CONFIG(RCC_OscInitStruct->PLL.PLLSource,
745 RCC_OscInitStruct->PLL.PLLM,
746 RCC_OscInitStruct->PLL.PLLN,
747 RCC_OscInitStruct->PLL.PLLP,
748 RCC_OscInitStruct->PLL.PLLQ,
749 RCC_OscInitStruct->PLL.PLLR);
750
751 /* Enable the main PLL. */
752 __HAL_RCC_PLL_ENABLE();
753
754 /* Enable PLL System Clock output. */
755 __HAL_RCC_PLLCLKOUT_ENABLE(RCC_PLL_SYSCLK);
756
757 /* Get Start Tick*/
758 tickstart = HAL_GetTick();
759
760 /* Wait till PLL is ready */
761 while(READ_BIT(RCC->CR, RCC_CR_PLLRDY) == RESET)
762 {
763 if((HAL_GetTick() - tickstart) > PLL_TIMEOUT_VALUE)
764 {
765 return HAL_TIMEOUT;
766 }
767 }
768 }
769 else
770 {
771 /* Disable the main PLL. */
772 __HAL_RCC_PLL_DISABLE();
773
774 /* Disable all PLL outputs to save power if no PLLs on */
775 if((READ_BIT(RCC->CR, RCC_CR_PLLSAI1RDY) == RESET)
776 #if defined(RCC_PLLSAI2_SUPPORT)
777 &&
778 (READ_BIT(RCC->CR, RCC_CR_PLLSAI2RDY) == RESET)
779 #endif /* RCC_PLLSAI2_SUPPORT */
780 )
781 {
782 MODIFY_REG(RCC->PLLCFGR, RCC_PLLCFGR_PLLSRC, RCC_PLLSOURCE_NONE);
783 }
784
785 #if defined(RCC_PLLSAI2_SUPPORT)
786 __HAL_RCC_PLLCLKOUT_DISABLE(RCC_PLL_SYSCLK | RCC_PLL_48M1CLK | RCC_PLL_SAI3CLK);
787 #else
788 __HAL_RCC_PLLCLKOUT_DISABLE(RCC_PLL_SYSCLK | RCC_PLL_48M1CLK | RCC_PLL_SAI2CLK);
789 #endif /* RCC_PLLSAI2_SUPPORT */
790
791 /* Get Start Tick*/
792 tickstart = HAL_GetTick();
793
794 /* Wait till PLL is disabled */
795 while(READ_BIT(RCC->CR, RCC_CR_PLLRDY) != RESET)
796 {
797 if((HAL_GetTick() - tickstart) > PLL_TIMEOUT_VALUE)
798 {
799 return HAL_TIMEOUT;
800 }
801 }
802 }
803 }
804 else
805 {
806 return HAL_ERROR;
807 }
808 }
809 return HAL_OK;
810 }
811
812 /**
813 * @brief Initialize the CPU, AHB and APB busses clocks according to the specified
814 * parameters in the RCC_ClkInitStruct.
815 * @param RCC_ClkInitStruct pointer to an RCC_OscInitTypeDef structure that
816 * contains the configuration information for the RCC peripheral.
817 * @param FLatency FLASH Latency
818 * This parameter can be one of the following values:
819 * @arg FLASH_LATENCY_0 FLASH 0 Latency cycle
820 * @arg FLASH_LATENCY_1 FLASH 1 Latency cycle
821 * @arg FLASH_LATENCY_2 FLASH 2 Latency cycle
822 * @arg FLASH_LATENCY_3 FLASH 3 Latency cycle
823 * @arg FLASH_LATENCY_4 FLASH 4 Latency cycle
824 *
825 * @note The SystemCoreClock CMSIS variable is used to store System Clock Frequency
826 * and updated by HAL_RCC_GetHCLKFreq() function called within this function
827 *
828 * @note The MSI is used by default as system clock source after
829 * startup from Reset, wake-up from STANDBY mode. After restart from Reset,
830 * the MSI frequency is set to its default value 4 MHz.
831 *
832 * @note The HSI can be selected as system clock source after
833 * from STOP modes or in case of failure of the HSE used directly or indirectly
834 * as system clock (if the Clock Security System CSS is enabled).
835 *
836 * @note A switch from one clock source to another occurs only if the target
837 * clock source is ready (clock stable after startup delay or PLL locked).
838 * If a clock source which is not yet ready is selected, the switch will
839 * occur when the clock source is ready.
840 *
841 * @note You can use HAL_RCC_GetClockConfig() function to know which clock is
842 * currently used as system clock source.
843 *
844 * @note Depending on the device voltage range, the software has to set correctly
845 * HPRE[3:0] bits to ensure that HCLK not exceed the maximum allowed frequency
846 * (for more details refer to section above "Initialization/de-initialization functions")
847 * @retval None
848 */
849 HAL_StatusTypeDef HAL_RCC_ClockConfig(RCC_ClkInitTypeDef *RCC_ClkInitStruct, uint32_t FLatency)
850 {
851 uint32_t tickstart = 0;
852
853 /* Check the parameters */
854 assert_param(RCC_ClkInitStruct != NULL);
855 assert_param(IS_RCC_CLOCKTYPE(RCC_ClkInitStruct->ClockType));
856 assert_param(IS_FLASH_LATENCY(FLatency));
857
858 /* To correctly read data from FLASH memory, the number of wait states (LATENCY)
859 must be correctly programmed according to the frequency of the CPU clock
860 (HCLK) and the supply voltage of the device. */
861
862 /* Increasing the number of wait states because of higher CPU frequency */
863 if(FLatency > (FLASH->ACR & FLASH_ACR_LATENCY))
864 {
865 /* Program the new number of wait states to the LATENCY bits in the FLASH_ACR register */
866 __HAL_FLASH_SET_LATENCY(FLatency);
867
868 /* Check that the new number of wait states is taken into account to access the Flash
869 memory by reading the FLASH_ACR register */
870 if((FLASH->ACR & FLASH_ACR_LATENCY) != FLatency)
871 {
872 return HAL_ERROR;
873 }
874 }
875
876 /*-------------------------- HCLK Configuration --------------------------*/
877 if(((RCC_ClkInitStruct->ClockType) & RCC_CLOCKTYPE_HCLK) == RCC_CLOCKTYPE_HCLK)
878 {
879 assert_param(IS_RCC_HCLK(RCC_ClkInitStruct->AHBCLKDivider));
880 MODIFY_REG(RCC->CFGR, RCC_CFGR_HPRE, RCC_ClkInitStruct->AHBCLKDivider);
881 }
882
883 /*------------------------- SYSCLK Configuration ---------------------------*/
884 if(((RCC_ClkInitStruct->ClockType) & RCC_CLOCKTYPE_SYSCLK) == RCC_CLOCKTYPE_SYSCLK)
885 {
886 assert_param(IS_RCC_SYSCLKSOURCE(RCC_ClkInitStruct->SYSCLKSource));
887
888 /* HSE is selected as System Clock Source */
889 if(RCC_ClkInitStruct->SYSCLKSource == RCC_SYSCLKSOURCE_HSE)
890 {
891 /* Check the HSE ready flag */
892 if(READ_BIT(RCC->CR, RCC_CR_HSERDY) == RESET)
893 {
894 return HAL_ERROR;
895 }
896 }
897 /* PLL is selected as System Clock Source */
898 else if(RCC_ClkInitStruct->SYSCLKSource == RCC_SYSCLKSOURCE_PLLCLK)
899 {
900 /* Check the PLL ready flag */
901 if(READ_BIT(RCC->CR, RCC_CR_PLLRDY) == RESET)
902 {
903 return HAL_ERROR;
904 }
905 }
906 /* MSI is selected as System Clock Source */
907 else if(RCC_ClkInitStruct->SYSCLKSource == RCC_SYSCLKSOURCE_MSI)
908 {
909 /* Check the MSI ready flag */
910 if(READ_BIT(RCC->CR, RCC_CR_MSIRDY) == RESET)
911 {
912 return HAL_ERROR;
913 }
914 }
915 /* HSI is selected as System Clock Source */
916 else
917 {
918 /* Check the HSI ready flag */
919 if(READ_BIT(RCC->CR, RCC_CR_HSIRDY) == RESET)
920 {
921 return HAL_ERROR;
922 }
923 }
924 MODIFY_REG(RCC->CFGR, RCC_CFGR_SW, RCC_ClkInitStruct->SYSCLKSource);
925
926 /* Get Start Tick*/
927 tickstart = HAL_GetTick();
928
929 if(RCC_ClkInitStruct->SYSCLKSource == RCC_SYSCLKSOURCE_HSE)
930 {
931 while (__HAL_RCC_GET_SYSCLK_SOURCE() != RCC_CFGR_SWS_HSE)
932 {
933 if((HAL_GetTick() - tickstart) > CLOCKSWITCH_TIMEOUT_VALUE)
934 {
935 return HAL_TIMEOUT;
936 }
937 }
938 }
939 else if(RCC_ClkInitStruct->SYSCLKSource == RCC_SYSCLKSOURCE_PLLCLK)
940 {
941 while (__HAL_RCC_GET_SYSCLK_SOURCE() != RCC_CFGR_SWS_PLL)
942 {
943 if((HAL_GetTick() - tickstart) > CLOCKSWITCH_TIMEOUT_VALUE)
944 {
945 return HAL_TIMEOUT;
946 }
947 }
948 }
949 else if(RCC_ClkInitStruct->SYSCLKSource == RCC_SYSCLKSOURCE_MSI)
950 {
951 while (__HAL_RCC_GET_SYSCLK_SOURCE() != RCC_CFGR_SWS_MSI)
952 {
953 if((HAL_GetTick() - tickstart) > CLOCKSWITCH_TIMEOUT_VALUE)
954 {
955 return HAL_TIMEOUT;
956 }
957 }
958 }
959 else
960 {
961 while(__HAL_RCC_GET_SYSCLK_SOURCE() != RCC_CFGR_SWS_HSI)
962 {
963 if((HAL_GetTick() - tickstart) > CLOCKSWITCH_TIMEOUT_VALUE)
964 {
965 return HAL_TIMEOUT;
966 }
967 }
968 }
969 }
970
971 /* Decreasing the number of wait states because of lower CPU frequency */
972 if(FLatency < (FLASH->ACR & FLASH_ACR_LATENCY))
973 {
974 /* Program the new number of wait states to the LATENCY bits in the FLASH_ACR register */
975 __HAL_FLASH_SET_LATENCY(FLatency);
976
977 /* Check that the new number of wait states is taken into account to access the Flash
978 memory by reading the FLASH_ACR register */
979 if((FLASH->ACR & FLASH_ACR_LATENCY) != FLatency)
980 {
981 return HAL_ERROR;
982 }
983 }
984
985 /*-------------------------- PCLK1 Configuration ---------------------------*/
986 if(((RCC_ClkInitStruct->ClockType) & RCC_CLOCKTYPE_PCLK1) == RCC_CLOCKTYPE_PCLK1)
987 {
988 assert_param(IS_RCC_PCLK(RCC_ClkInitStruct->APB1CLKDivider));
989 MODIFY_REG(RCC->CFGR, RCC_CFGR_PPRE1, RCC_ClkInitStruct->APB1CLKDivider);
990 }
991
992 /*-------------------------- PCLK2 Configuration ---------------------------*/
993 if(((RCC_ClkInitStruct->ClockType) & RCC_CLOCKTYPE_PCLK2) == RCC_CLOCKTYPE_PCLK2)
994 {
995 assert_param(IS_RCC_PCLK(RCC_ClkInitStruct->APB2CLKDivider));
996 MODIFY_REG(RCC->CFGR, RCC_CFGR_PPRE2, ((RCC_ClkInitStruct->APB2CLKDivider) << 3U));
997 }
998
999 /* Update the SystemCoreClock global variable */
1000 SystemCoreClock = HAL_RCC_GetSysClockFreq() >> AHBPrescTable[(RCC->CFGR & RCC_CFGR_HPRE)>> POSITION_VAL(RCC_CFGR_HPRE)];
1001
1002 /* Configure the source of time base considering new system clocks settings*/
1003 HAL_InitTick (TICK_INT_PRIORITY);
1004
1005 return HAL_OK;
1006 }
1007
1008 /**
1009 * @}
1010 */
1011
1012 /** @defgroup RCC_Exported_Functions_Group2 Peripheral Control functions
1013 * @brief RCC clocks control functions
1014 *
1015 @verbatim
1016 ===============================================================================
1017 ##### Peripheral Control functions #####
1018 ===============================================================================
1019 [..]
1020 This subsection provides a set of functions allowing to:
1021
1022 (+) Ouput clock to MCO pin.
1023 (+) Retrieve current clock frequencies.
1024 (+) Enable the Clock Security System.
1025
1026 @endverbatim
1027 * @{
1028 */
1029
1030 /**
1031 * @brief Select the clock source to output on MCO pin(PA8).
1032 * @note PA8 should be configured in alternate function mode.
1033 * @param RCC_MCOx specifies the output direction for the clock source.
1034 * For STM32L4xx family this parameter can have only one value:
1035 * @arg @ref RCC_MCO1 Clock source to output on MCO1 pin(PA8).
1036 * @param RCC_MCOSource specifies the clock source to output.
1037 * This parameter can be one of the following values:
1038 * @arg @ref RCC_MCO1SOURCE_NOCLOCK MCO output disabled, no clock on MCO
1039 * @arg @ref RCC_MCO1SOURCE_SYSCLK system clock selected as MCO source
1040 * @arg @ref RCC_MCO1SOURCE_MSI MSI clock selected as MCO source
1041 * @arg @ref RCC_MCO1SOURCE_HSI HSI clock selected as MCO source
1042 * @arg @ref RCC_MCO1SOURCE_HSE HSE clock selected as MCO sourcee
1043 * @arg @ref RCC_MCO1SOURCE_PLLCLK main PLL clock selected as MCO source
1044 * @arg @ref RCC_MCO1SOURCE_LSI LSI clock selected as MCO source
1045 * @arg @ref RCC_MCO1SOURCE_LSE LSE clock selected as MCO source
1046 @if STM32L443xx
1047 * @arg @ref RCC_MCO1SOURCE_HSI48 HSI48 clock selected as MCO source for devices with HSI48
1048 @endif
1049 * @param RCC_MCODiv specifies the MCO prescaler.
1050 * This parameter can be one of the following values:
1051 * @arg @ref RCC_MCODIV_1 no division applied to MCO clock
1052 * @arg @ref RCC_MCODIV_2 division by 2 applied to MCO clock
1053 * @arg @ref RCC_MCODIV_4 division by 4 applied to MCO clock
1054 * @arg @ref RCC_MCODIV_8 division by 8 applied to MCO clock
1055 * @arg @ref RCC_MCODIV_16 division by 16 applied to MCO clock
1056 * @retval None
1057 */
1058 void HAL_RCC_MCOConfig( uint32_t RCC_MCOx, uint32_t RCC_MCOSource, uint32_t RCC_MCODiv)
1059 {
1060 GPIO_InitTypeDef GPIO_InitStruct;
1061 /* Check the parameters */
1062 assert_param(IS_RCC_MCO(RCC_MCOx));
1063 assert_param(IS_RCC_MCODIV(RCC_MCODiv));
1064 assert_param(IS_RCC_MCO1SOURCE(RCC_MCOSource));
1065
1066 /* MCO Clock Enable */
1067 __MCO1_CLK_ENABLE();
1068
1069 /* Configue the MCO1 pin in alternate function mode */
1070 GPIO_InitStruct.Pin = MCO1_PIN;
1071 GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
1072 GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;
1073 GPIO_InitStruct.Pull = GPIO_NOPULL;
1074 GPIO_InitStruct.Alternate = GPIO_AF0_MCO;
1075 HAL_GPIO_Init(MCO1_GPIO_PORT, &GPIO_InitStruct);
1076
1077 /* Mask MCOSEL[] and MCOPRE[] bits then set MCO1 clock source and prescaler */
1078 MODIFY_REG(RCC->CFGR, (RCC_CFGR_MCOSEL | RCC_CFGR_MCOPRE), (RCC_MCOSource | RCC_MCODiv ));
1079 }
1080
1081 /**
1082 * @brief Return the SYSCLK frequency.
1083 *
1084 * @note The system frequency computed by this function is not the real
1085 * frequency in the chip. It is calculated based on the predefined
1086 * constant and the selected clock source:
1087 * @note If SYSCLK source is MSI, function returns values based on MSI
1088 * Value as defined by the MSI range.
1089 * @note If SYSCLK source is HSI, function returns values based on HSI_VALUE(*)
1090 * @note If SYSCLK source is HSE, function returns values based on HSE_VALUE(**)
1091 * @note If SYSCLK source is PLL, function returns values based on HSE_VALUE(**),
1092 * HSI_VALUE(*) or MSI Value multiplied/divided by the PLL factors.
1093 * @note (*) HSI_VALUE is a constant defined in stm32l4xx_hal_conf.h file (default value
1094 * 16 MHz) but the real value may vary depending on the variations
1095 * in voltage and temperature.
1096 * @note (**) HSE_VALUE is a constant defined in stm32l4xx_hal_conf.h file (default value
1097 * 8 MHz), user has to ensure that HSE_VALUE is same as the real
1098 * frequency of the crystal used. Otherwise, this function may
1099 * have wrong result.
1100 *
1101 * @note The result of this function could be not correct when using fractional
1102 * value for HSE crystal.
1103 *
1104 * @note This function can be used by the user application to compute the
1105 * baudrate for the communication peripherals or configure other parameters.
1106 *
1107 * @note Each time SYSCLK changes, this function must be called to update the
1108 * right SYSCLK value. Otherwise, any configuration based on this function will be incorrect.
1109 *
1110 *
1111 * @retval SYSCLK frequency
1112 */
1113 uint32_t HAL_RCC_GetSysClockFreq(void)
1114 {
1115 uint32_t msirange = 0U, pllvco = 0U, pllsource = 0U, pllr = 2U, pllm = 2U;
1116 uint32_t sysclockfreq = 0U;
1117
1118 if((__HAL_RCC_GET_SYSCLK_SOURCE() == RCC_CFGR_SWS_MSI) ||
1119 ((__HAL_RCC_GET_SYSCLK_SOURCE() == RCC_CFGR_SWS_PLL) && (__HAL_RCC_GET_PLL_OSCSOURCE() == RCC_PLLSOURCE_MSI)))
1120 {
1121 /* MSI or PLL with MSI source used as system clock source */
1122
1123 /* Get SYSCLK source */
1124 if(READ_BIT(RCC->CR, RCC_CR_MSIRGSEL) == RESET)
1125 { /* MSISRANGE from RCC_CSR applies */
1126 msirange = (RCC->CSR & RCC_CSR_MSISRANGE) >> POSITION_VAL(RCC_CSR_MSISRANGE);
1127 }
1128 else
1129 { /* MSIRANGE from RCC_CR applies */
1130 msirange = (RCC->CR & RCC_CR_MSIRANGE) >> POSITION_VAL(RCC_CR_MSIRANGE);
1131 }
1132 /*MSI frequency range in HZ*/
1133 msirange = MSIRangeTable[msirange];
1134
1135 if(__HAL_RCC_GET_SYSCLK_SOURCE() == RCC_CFGR_SWS_MSI)
1136 {
1137 /* MSI used as system clock source */
1138 sysclockfreq = msirange;
1139 }
1140 }
1141 else if(__HAL_RCC_GET_SYSCLK_SOURCE() == RCC_CFGR_SWS_HSI)
1142 {
1143 /* HSI used as system clock source */
1144 sysclockfreq = HSI_VALUE;
1145 }
1146 else if(__HAL_RCC_GET_SYSCLK_SOURCE() == RCC_CFGR_SWS_HSE)
1147 {
1148 /* HSE used as system clock source */
1149 sysclockfreq = HSE_VALUE;
1150 }
1151
1152 if(__HAL_RCC_GET_SYSCLK_SOURCE() == RCC_CFGR_SWS_PLL)
1153 {
1154 /* PLL used as system clock source */
1155
1156 /* PLL_VCO = (HSE_VALUE or HSI_VALUE or MSI_VALUE/ PLLM) * PLLN
1157 SYSCLK = PLL_VCO / PLLR
1158 */
1159 pllsource = (RCC->PLLCFGR & RCC_PLLCFGR_PLLSRC);
1160 pllm = ((RCC->PLLCFGR & RCC_PLLCFGR_PLLM) >> POSITION_VAL(RCC_PLLCFGR_PLLM)) + 1U ;
1161
1162 switch (pllsource)
1163 {
1164 case RCC_PLLSOURCE_HSI: /* HSI used as PLL clock source */
1165 pllvco = (HSI_VALUE / pllm) * ((RCC->PLLCFGR & RCC_PLLCFGR_PLLN) >> POSITION_VAL(RCC_PLLCFGR_PLLN));
1166 break;
1167
1168 case RCC_PLLSOURCE_HSE: /* HSE used as PLL clock source */
1169 pllvco = (HSE_VALUE / pllm) * ((RCC->PLLCFGR & RCC_PLLCFGR_PLLN) >> POSITION_VAL(RCC_PLLCFGR_PLLN));
1170 break;
1171
1172 case RCC_PLLSOURCE_MSI: /* MSI used as PLL clock source */
1173 default:
1174 pllvco = (msirange / pllm) * ((RCC->PLLCFGR & RCC_PLLCFGR_PLLN) >> POSITION_VAL(RCC_PLLCFGR_PLLN));
1175 break;
1176 }
1177 pllr = (((RCC->PLLCFGR & RCC_PLLCFGR_PLLR) >> POSITION_VAL(RCC_PLLCFGR_PLLR)) + 1U ) * 2U;
1178 sysclockfreq = pllvco/pllr;
1179 }
1180
1181 return sysclockfreq;
1182 }
1183
1184 /**
1185 * @brief Return the HCLK frequency.
1186 * @note Each time HCLK changes, this function must be called to update the
1187 * right HCLK value. Otherwise, any configuration based on this function will be incorrect.
1188 *
1189 * @note The SystemCoreClock CMSIS variable is used to store System Clock Frequency.
1190 * @retval HCLK frequency in Hz
1191 */
1192 uint32_t HAL_RCC_GetHCLKFreq(void)
1193 {
1194 return SystemCoreClock;
1195 }
1196
1197 /**
1198 * @brief Return the PCLK1 frequency.
1199 * @note Each time PCLK1 changes, this function must be called to update the
1200 * right PCLK1 value. Otherwise, any configuration based on this function will be incorrect.
1201 * @retval PCLK1 frequency in Hz
1202 */
1203 uint32_t HAL_RCC_GetPCLK1Freq(void)
1204 {
1205 /* Get HCLK source and Compute PCLK1 frequency ---------------------------*/
1206 return (HAL_RCC_GetHCLKFreq() >> APBPrescTable[(RCC->CFGR & RCC_CFGR_PPRE1)>> POSITION_VAL(RCC_CFGR_PPRE1)]);
1207 }
1208
1209 /**
1210 * @brief Return the PCLK2 frequency.
1211 * @note Each time PCLK2 changes, this function must be called to update the
1212 * right PCLK2 value. Otherwise, any configuration based on this function will be incorrect.
1213 * @retval PCLK2 frequency in Hz
1214 */
1215 uint32_t HAL_RCC_GetPCLK2Freq(void)
1216 {
1217 /* Get HCLK source and Compute PCLK2 frequency ---------------------------*/
1218 return (HAL_RCC_GetHCLKFreq()>> APBPrescTable[(RCC->CFGR & RCC_CFGR_PPRE2)>> POSITION_VAL(RCC_CFGR_PPRE2)]);
1219 }
1220
1221 /**
1222 * @brief Configure the RCC_OscInitStruct according to the internal
1223 * RCC configuration registers.
1224 * @param RCC_OscInitStruct pointer to an RCC_OscInitTypeDef structure that
1225 * will be configured.
1226 * @retval None
1227 */
1228 void HAL_RCC_GetOscConfig(RCC_OscInitTypeDef *RCC_OscInitStruct)
1229 {
1230 /* Check the parameters */
1231 assert_param(RCC_OscInitStruct != NULL);
1232
1233 /* Set all possible values for the Oscillator type parameter ---------------*/
1234 #if defined(RCC_HSI48_SUPPORT)
1235 RCC_OscInitStruct->OscillatorType = RCC_OSCILLATORTYPE_HSE | RCC_OSCILLATORTYPE_HSI | RCC_OSCILLATORTYPE_MSI | \
1236 RCC_OSCILLATORTYPE_LSE | RCC_OSCILLATORTYPE_LSI | RCC_OSCILLATORTYPE_HSI48;
1237 #else
1238 RCC_OscInitStruct->OscillatorType = RCC_OSCILLATORTYPE_HSE | RCC_OSCILLATORTYPE_HSI | RCC_OSCILLATORTYPE_MSI | \
1239 RCC_OSCILLATORTYPE_LSE | RCC_OSCILLATORTYPE_LSI;
1240 #endif /* RCC_HSI48_SUPPORT */
1241
1242 /* Get the HSE configuration -----------------------------------------------*/
1243 if((RCC->CR & RCC_CR_HSEBYP) == RCC_CR_HSEBYP)
1244 {
1245 RCC_OscInitStruct->HSEState = RCC_HSE_BYPASS;
1246 }
1247 else if((RCC->CR & RCC_CR_HSEON) == RCC_CR_HSEON)
1248 {
1249 RCC_OscInitStruct->HSEState = RCC_HSE_ON;
1250 }
1251 else
1252 {
1253 RCC_OscInitStruct->HSEState = RCC_HSE_OFF;
1254 }
1255
1256 /* Get the MSI configuration -----------------------------------------------*/
1257 if((RCC->CR & RCC_CR_MSION) == RCC_CR_MSION)
1258 {
1259 RCC_OscInitStruct->MSIState = RCC_MSI_ON;
1260 }
1261 else
1262 {
1263 RCC_OscInitStruct->MSIState = RCC_MSI_OFF;
1264 }
1265
1266 RCC_OscInitStruct->MSICalibrationValue = (uint32_t)((RCC->ICSCR & RCC_ICSCR_MSITRIM) >> POSITION_VAL(RCC_ICSCR_MSITRIM));
1267 RCC_OscInitStruct->MSIClockRange = (uint32_t)((RCC->CR & RCC_CR_MSIRANGE) );
1268
1269 /* Get the HSI configuration -----------------------------------------------*/
1270 if((RCC->CR & RCC_CR_HSION) == RCC_CR_HSION)
1271 {
1272 RCC_OscInitStruct->HSIState = RCC_HSI_ON;
1273 }
1274 else
1275 {
1276 RCC_OscInitStruct->HSIState = RCC_HSI_OFF;
1277 }
1278
1279 RCC_OscInitStruct->HSICalibrationValue = (uint32_t)((RCC->ICSCR & RCC_ICSCR_HSITRIM) >> POSITION_VAL(RCC_ICSCR_HSITRIM));
1280
1281 /* Get the LSE configuration -----------------------------------------------*/
1282 if((RCC->BDCR & RCC_BDCR_LSEBYP) == RCC_BDCR_LSEBYP)
1283 {
1284 RCC_OscInitStruct->LSEState = RCC_LSE_BYPASS;
1285 }
1286 else if((RCC->BDCR & RCC_BDCR_LSEON) == RCC_BDCR_LSEON)
1287 {
1288 RCC_OscInitStruct->LSEState = RCC_LSE_ON;
1289 }
1290 else
1291 {
1292 RCC_OscInitStruct->LSEState = RCC_LSE_OFF;
1293 }
1294
1295 /* Get the LSI configuration -----------------------------------------------*/
1296 if((RCC->CSR & RCC_CSR_LSION) == RCC_CSR_LSION)
1297 {
1298 RCC_OscInitStruct->LSIState = RCC_LSI_ON;
1299 }
1300 else
1301 {
1302 RCC_OscInitStruct->LSIState = RCC_LSI_OFF;
1303 }
1304
1305 #if defined(RCC_HSI48_SUPPORT)
1306 /* Get the HSI48 configuration ---------------------------------------------*/
1307 if((RCC->CRRCR & RCC_CRRCR_HSI48ON) == RCC_CRRCR_HSI48ON)
1308 {
1309 RCC_OscInitStruct->HSI48State = RCC_HSI48_ON;
1310 }
1311 else
1312 {
1313 RCC_OscInitStruct->HSI48State = RCC_HSI48_OFF;
1314 }
1315 #else
1316 RCC_OscInitStruct->HSI48State = RCC_HSI48_OFF;
1317 #endif /* RCC_HSI48_SUPPORT */
1318
1319 /* Get the PLL configuration -----------------------------------------------*/
1320 if((RCC->CR & RCC_CR_PLLON) == RCC_CR_PLLON)
1321 {
1322 RCC_OscInitStruct->PLL.PLLState = RCC_PLL_ON;
1323 }
1324 else
1325 {
1326 RCC_OscInitStruct->PLL.PLLState = RCC_PLL_OFF;
1327 }
1328 RCC_OscInitStruct->PLL.PLLSource = (uint32_t)(RCC->PLLCFGR & RCC_PLLCFGR_PLLSRC);
1329 RCC_OscInitStruct->PLL.PLLM = (uint32_t)(((RCC->PLLCFGR & RCC_PLLCFGR_PLLM) >> POSITION_VAL(RCC_PLLCFGR_PLLM)) + 1U);
1330 RCC_OscInitStruct->PLL.PLLN = (uint32_t)((RCC->PLLCFGR & RCC_PLLCFGR_PLLN) >> POSITION_VAL(RCC_PLLCFGR_PLLN));
1331 RCC_OscInitStruct->PLL.PLLQ = (uint32_t)((((RCC->PLLCFGR & RCC_PLLCFGR_PLLQ) >> POSITION_VAL(RCC_PLLCFGR_PLLQ)) + 1U) << 1U);
1332 RCC_OscInitStruct->PLL.PLLR = (uint32_t)((((RCC->PLLCFGR & RCC_PLLCFGR_PLLR) >> POSITION_VAL(RCC_PLLCFGR_PLLR)) + 1U) << 1U);
1333 #if defined(RCC_PLLP_DIV_2_31_SUPPORT)
1334 RCC_OscInitStruct->PLL.PLLP = (uint32_t)((RCC->PLLCFGR & RCC_PLLCFGR_PLLPDIV) >> POSITION_VAL(RCC_PLLCFGR_PLLPDIV));
1335 #else
1336 if((RCC->PLLCFGR & RCC_PLLCFGR_PLLP) != RESET)
1337 {
1338 RCC_OscInitStruct->PLL.PLLP = RCC_PLLP_DIV17;
1339 }
1340 else
1341 {
1342 RCC_OscInitStruct->PLL.PLLP = RCC_PLLP_DIV7;
1343 }
1344 #endif /* RCC_PLLP_DIV_2_31_SUPPORT */
1345 }
1346
1347 /**
1348 * @brief Configure the RCC_ClkInitStruct according to the internal
1349 * RCC configuration registers.
1350 * @param RCC_ClkInitStruct pointer to an RCC_ClkInitTypeDef structure that
1351 * will be configured.
1352 * @param pFLatency Pointer on the Flash Latency.
1353 * @retval None
1354 */
1355 void HAL_RCC_GetClockConfig(RCC_ClkInitTypeDef *RCC_ClkInitStruct, uint32_t *pFLatency)
1356 {
1357 /* Check the parameters */
1358 assert_param(RCC_ClkInitStruct != NULL);
1359 assert_param(pFLatency != NULL);
1360
1361 /* Set all possible values for the Clock type parameter --------------------*/
1362 RCC_ClkInitStruct->ClockType = RCC_CLOCKTYPE_SYSCLK | RCC_CLOCKTYPE_HCLK | RCC_CLOCKTYPE_PCLK1 | RCC_CLOCKTYPE_PCLK2;
1363
1364 /* Get the SYSCLK configuration --------------------------------------------*/
1365 RCC_ClkInitStruct->SYSCLKSource = (uint32_t)(RCC->CFGR & RCC_CFGR_SW);
1366
1367 /* Get the HCLK configuration ----------------------------------------------*/
1368 RCC_ClkInitStruct->AHBCLKDivider = (uint32_t)(RCC->CFGR & RCC_CFGR_HPRE);
1369
1370 /* Get the APB1 configuration ----------------------------------------------*/
1371 RCC_ClkInitStruct->APB1CLKDivider = (uint32_t)(RCC->CFGR & RCC_CFGR_PPRE1);
1372
1373 /* Get the APB2 configuration ----------------------------------------------*/
1374 RCC_ClkInitStruct->APB2CLKDivider = (uint32_t)((RCC->CFGR & RCC_CFGR_PPRE2) >> 3U);
1375
1376 /* Get the Flash Wait State (Latency) configuration ------------------------*/
1377 *pFLatency = (uint32_t)(FLASH->ACR & FLASH_ACR_LATENCY);
1378 }
1379
1380 /**
1381 * @brief Enable the Clock Security System.
1382 * @note If a failure is detected on the HSE oscillator clock, this oscillator
1383 * is automatically disabled and an interrupt is generated to inform the
1384 * software about the failure (Clock Security System Interrupt, CSSI),
1385 * allowing the MCU to perform rescue operations. The CSSI is linked to
1386 * the Cortex-M4 NMI (Non-Maskable Interrupt) exception vector.
1387 * @note The Clock Security System can only be cleared by reset.
1388 * @retval None
1389 */
1390 void HAL_RCC_EnableCSS(void)
1391 {
1392 SET_BIT(RCC->CR, RCC_CR_CSSON) ;
1393 }
1394
1395 /**
1396 * @brief Handle the RCC Clock Security System interrupt request.
1397 * @note This API should be called under the NMI_Handler().
1398 * @retval None
1399 */
1400 void HAL_RCC_NMI_IRQHandler(void)
1401 {
1402 /* Check RCC CSSF interrupt flag */
1403 if(__HAL_RCC_GET_IT(RCC_IT_CSS))
1404 {
1405 /* RCC Clock Security System interrupt user callback */
1406 HAL_RCC_CSSCallback();
1407
1408 /* Clear RCC CSS pending bit */
1409 __HAL_RCC_CLEAR_IT(RCC_IT_CSS);
1410 }
1411 }
1412
1413 /**
1414 * @brief RCC Clock Security System interrupt callback.
1415 * @retval none
1416 */
1417 __weak void HAL_RCC_CSSCallback(void)
1418 {
1419 /* NOTE : This function should not be modified, when the callback is needed,
1420 the HAL_RCC_CSSCallback should be implemented in the user file
1421 */
1422 }
1423
1424 /**
1425 * @}
1426 */
1427
1428 /**
1429 * @}
1430 */
1431
1432 /* Private function prototypes -----------------------------------------------*/
1433 /** @addtogroup RCC_Private_Functions
1434 * @{
1435 */
1436 /**
1437 * @brief Update number of Flash wait states in line with MSI range and current
1438 voltage range.
1439 * @param msirange MSI range value from RCC_MSIRANGE_0 to RCC_MSIRANGE_11
1440 * @retval HAL status
1441 */
1442 static HAL_StatusTypeDef RCC_SetFlashLatencyFromMSIRange(uint32_t msirange)
1443 {
1444 uint32_t vos = 0;
1445 uint32_t latency = FLASH_LATENCY_0; /* default value 0WS */
1446
1447 if(__HAL_RCC_PWR_IS_CLK_ENABLED())
1448 {
1449 vos = HAL_PWREx_GetVoltageRange();
1450 }
1451 else
1452 {
1453 __HAL_RCC_PWR_CLK_ENABLE();
1454 vos = HAL_PWREx_GetVoltageRange();
1455 __HAL_RCC_PWR_CLK_DISABLE();
1456 }
1457
1458 if(vos == PWR_REGULATOR_VOLTAGE_SCALE1)
1459 {
1460 if(msirange > RCC_MSIRANGE_8)
1461 {
1462 /* MSI > 16Mhz */
1463 if(msirange > RCC_MSIRANGE_10)
1464 {
1465 /* MSI 48Mhz */
1466 latency = FLASH_LATENCY_2; /* 2WS */
1467 }
1468 else
1469 {
1470 /* MSI 24Mhz or 32Mhz */
1471 latency = FLASH_LATENCY_1; /* 1WS */
1472 }
1473 }
1474 /* else MSI <= 16Mhz default FLASH_LATENCY_0 0WS */
1475 }
1476 else
1477 {
1478 if(msirange > RCC_MSIRANGE_8)
1479 {
1480 /* MSI > 16Mhz */
1481 latency = FLASH_LATENCY_3; /* 3WS */
1482 }
1483 else
1484 {
1485 if(msirange == RCC_MSIRANGE_8)
1486 {
1487 /* MSI 16Mhz */
1488 latency = FLASH_LATENCY_2; /* 2WS */
1489 }
1490 else if(msirange == RCC_MSIRANGE_7)
1491 {
1492 /* MSI 8Mhz */
1493 latency = FLASH_LATENCY_1; /* 1WS */
1494 }
1495 /* else MSI < 8Mhz default FLASH_LATENCY_0 0WS */
1496 }
1497 }
1498
1499 __HAL_FLASH_SET_LATENCY(latency);
1500
1501 /* Check that the new number of wait states is taken into account to access the Flash
1502 memory by reading the FLASH_ACR register */
1503 if((FLASH->ACR & FLASH_ACR_LATENCY) != latency)
1504 {
1505 return HAL_ERROR;
1506 }
1507
1508 return HAL_OK;
1509 }
1510
1511 /**
1512 * @}
1513 */
1514
1515 #endif /* HAL_RCC_MODULE_ENABLED */
1516 /**
1517 * @}
1518 */
1519
1520 /**
1521 * @}
1522 */
1523
1524 /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/