Mercurial > pub > halpp
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>© 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****/ |