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