2 ******************************************************************************
3 * @file stm32f0xx_hal_rcc_ex.c
4 * @author MCD Application Team
6 * @date 11-December-2014
7 * @brief Extended RCC HAL module driver
8 * This file provides firmware functions to manage the following
9 * functionalities RCC extension peripheral:
10 * + Extended Clock Source configuration functions
13 ==============================================================================
14 ##### How to use this driver #####
15 ==============================================================================
17 For CRS, RCC Extention HAL driver can be used as follows:
19 (#) In System clock config, HSI48 need to be enabled
21 (#] Enable CRS clock in IP MSP init which will use CRS functions
23 (#) Call CRS functions like this
24 (##) Prepare synchronization configuration necessary for HSI48 calibration
25 (+++) Default values can be set for frequency Error Measurement (reload and error limit)
26 and also HSI48 oscillator smooth trimming.
27 (+++) Macro __HAL_RCC_CRS_CALCULATE_RELOADVALUE can be also used to calculate
28 directly reload value with target and sychronization frequencies values
29 (##) Call function HAL_RCCEx_CRSConfig which
30 (+++) Reset CRS registers to their default values.
31 (+++) Configure CRS registers with synchronization configuration
32 (+++) Enable automatic calibration and frequency error counter feature
34 (##) A polling function is provided to wait for complete Synchronization
35 (+++) Call function HAL_RCCEx_CRSWaitSynchronization()
36 (+++) According to CRS status, user can decide to adjust again the calibration or continue
37 application if synchronization is OK
39 (#) User can retrieve information related to synchronization in calling function
40 HAL_RCCEx_CRSGetSynchronizationInfo()
42 (#) Regarding synchronization status and synchronization information, user can try a new calibration
43 in changing synchronization configuration and call again HAL_RCCEx_CRSConfig.
44 Note: When the SYNC event is detected during the downcounting phase (before reaching the zero value),
45 it means that the actual frequency is lower than the target (and so, that the TRIM value should be
46 incremented), while when it is detected during the upcounting phase it means that the actual frequency
47 is higher (and that the TRIM value should be decremented).
49 (#) To use IT mode, user needs to handle it in calling different macros available to do it
50 (__HAL_RCC_CRS_XXX_IT). Interuptions will go through RCC Handler (RCC_IRQn/RCC_CRS_IRQHandler)
51 (++) Call function HAL_RCCEx_CRSConfig()
52 (++) Enable RCC_IRQn (thnaks to NVIC functions)
53 (++) Enable CRS IT (__HAL_RCC_CRS_ENABLE_IT)
54 (++) Implement CRS status management in RCC_CRS_IRQHandler
56 (#) To force a SYNC EVENT, user can use function HAL_RCCEx_CRSSoftwareSynchronizationGenerate(). Function can be
57 called before calling HAL_RCCEx_CRSConfig (for instance in Systick handler)
60 ******************************************************************************
63 * <h2><center>© COPYRIGHT(c) 2014 STMicroelectronics</center></h2>
65 * Redistribution and use in source and binary forms, with or without modification,
66 * are permitted provided that the following conditions are met:
67 * 1. Redistributions of source code must retain the above copyright notice,
68 * this list of conditions and the following disclaimer.
69 * 2. Redistributions in binary form must reproduce the above copyright notice,
70 * this list of conditions and the following disclaimer in the documentation
71 * and/or other materials provided with the distribution.
72 * 3. Neither the name of STMicroelectronics nor the names of its contributors
73 * may be used to endorse or promote products derived from this software
74 * without specific prior written permission.
76 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
77 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
78 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
79 * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
80 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
81 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
82 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
83 * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
84 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
85 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
87 ******************************************************************************
90 /* Includes ------------------------------------------------------------------*/
91 #include "stm32f0xx_hal.h"
93 /** @addtogroup STM32F0xx_HAL_Driver
97 /** @defgroup RCCEx RCCEx Extended HAL module driver
98 * @brief RCC Extension HAL module driver.
102 #ifdef HAL_RCC_MODULE_ENABLED
104 /* Private typedef -----------------------------------------------------------*/
105 /* Private define ------------------------------------------------------------*/
106 /** @defgroup RCCEx_Private_Define RCCEx Private Define
109 #define HSI48_TIMEOUT_VALUE ((uint32_t)100) /* 100 ms */
111 /* Bit position in register */
112 #define CRS_CFGR_FELIM_BITNUMBER 16
113 #define CRS_CR_TRIM_BITNUMBER 8
114 #define CRS_ISR_FECAP_BITNUMBER 16
119 /* Private macro -------------------------------------------------------------*/
120 /* Private variables ---------------------------------------------------------*/
121 /** @defgroup RCCEx_Private_Variables RCCEx Private Variables
124 const uint8_t PLLMULFactorTable[16] = { 2, 3, 4, 5, 6, 7, 8, 9,
125 10, 11, 12, 13, 14, 15, 16, 16};
126 const uint8_t PredivFactorTable[16] = { 1, 2, 3, 4, 5, 6, 7, 8,
127 9,10, 11, 12, 13, 14, 15, 16};
131 /* Private function prototypes -----------------------------------------------*/
132 /* Exported functions ---------------------------------------------------------*/
134 /** @defgroup RCCEx_Exported_Functions RCCEx Exported Functions
138 /** @defgroup RCCEx_Exported_Functions_Group1 Extended Peripheral Control functions
139 * @brief Extended RCC clocks control functions
142 ===============================================================================
143 ##### Extended Peripheral Control functions #####
144 ===============================================================================
146 This subsection provides a set of functions allowing to control the RCC Clocks
149 (@) Important note: Care must be taken when HAL_RCCEx_PeriphCLKConfig() is used to
150 select the RTC clock source; in this case the Backup domain will be reset in
151 order to modify the RTC Clock source, as consequence RTC registers (including
152 the backup registers) and RCC_BDCR register are set to their reset values.
159 * @brief Initializes the RCC Oscillators according to the specified parameters in the
160 * RCC_OscInitTypeDef.
161 * @param RCC_OscInitStruct: pointer to an RCC_OscInitTypeDef structure that
162 * contains the configuration information for the RCC Oscillators.
163 * @note The PLL is not disabled when used as system clock.
166 HAL_StatusTypeDef HAL_RCC_OscConfig(RCC_OscInitTypeDef *RCC_OscInitStruct)
168 uint32_t tickstart = 0;
170 /* Check the parameters */
171 assert_param(IS_RCC_OSCILLATORTYPE(RCC_OscInitStruct->OscillatorType));
172 /*------------------------------- HSE Configuration ------------------------*/
173 if(((RCC_OscInitStruct->OscillatorType) & RCC_OSCILLATORTYPE_HSE) == RCC_OSCILLATORTYPE_HSE)
175 /* Check the parameters */
176 assert_param(IS_RCC_HSE(RCC_OscInitStruct->HSEState));
177 /* When the HSE is used as system clock or clock source for PLL in these cases it is not allowed to be disabled */
178 if((__HAL_RCC_GET_SYSCLK_SOURCE() == RCC_SYSCLKSOURCE_STATUS_HSE) ||
179 ((__HAL_RCC_GET_SYSCLK_SOURCE() == RCC_SYSCLKSOURCE_STATUS_PLLCLK) && (__HAL_RCC_GET_PLL_OSCSOURCE() == RCC_PLLSOURCE_HSE)))
181 if((__HAL_RCC_GET_FLAG(RCC_FLAG_HSERDY) != RESET) && (RCC_OscInitStruct->HSEState != RCC_HSE_ON))
188 /* Reset HSEON and HSEBYP bits before configuring the HSE --------------*/
189 __HAL_RCC_HSE_CONFIG(RCC_HSE_OFF);
192 tickstart = HAL_GetTick();
194 /* Wait till HSE is ready */
195 while(__HAL_RCC_GET_FLAG(RCC_FLAG_HSERDY) != RESET)
197 if((HAL_GetTick() - tickstart) > HSE_TIMEOUT_VALUE)
203 /* Set the new HSE configuration ---------------------------------------*/
204 __HAL_RCC_HSE_CONFIG((uint8_t)RCC_OscInitStruct->HSEState);
206 /* Check the HSE State */
207 if(RCC_OscInitStruct->HSEState != RCC_HSE_OFF)
210 tickstart = HAL_GetTick();
212 /* Wait till HSE is ready */
213 while(__HAL_RCC_GET_FLAG(RCC_FLAG_HSERDY) == RESET)
215 if((HAL_GetTick() - tickstart) > HSE_TIMEOUT_VALUE)
224 tickstart = HAL_GetTick();
226 /* Wait till HSE is ready */
227 while(__HAL_RCC_GET_FLAG(RCC_FLAG_HSERDY) != RESET)
229 if((HAL_GetTick() - tickstart) > HSE_TIMEOUT_VALUE)
237 /*----------------------------- HSI Configuration --------------------------*/
238 if(((RCC_OscInitStruct->OscillatorType) & RCC_OSCILLATORTYPE_HSI) == RCC_OSCILLATORTYPE_HSI)
240 /* Check the parameters */
241 assert_param(IS_RCC_HSI(RCC_OscInitStruct->HSIState));
242 assert_param(IS_RCC_CALIBRATION_VALUE(RCC_OscInitStruct->HSICalibrationValue));
244 /* Check if HSI is used as system clock or as PLL source when PLL is selected as system clock */
245 if((__HAL_RCC_GET_SYSCLK_SOURCE() == RCC_SYSCLKSOURCE_STATUS_HSI) ||
246 ((__HAL_RCC_GET_SYSCLK_SOURCE() == RCC_SYSCLKSOURCE_STATUS_PLLCLK) && (__HAL_RCC_GET_PLL_OSCSOURCE() == RCC_PLLSOURCE_HSI)))
248 /* When the HSI is used as system clock it is not allowed to be disabled */
249 if((__HAL_RCC_GET_FLAG(RCC_FLAG_HSIRDY) != RESET) && (RCC_OscInitStruct->HSIState != RCC_HSI_ON))
253 /* Otherwise, just the calibration is allowed */
256 /* Adjusts the Internal High Speed oscillator (HSI) calibration value.*/
257 __HAL_RCC_HSI_CALIBRATIONVALUE_ADJUST(RCC_OscInitStruct->HSICalibrationValue);
262 /* Check the HSI State */
263 if(RCC_OscInitStruct->HSIState != RCC_HSI_OFF)
265 /* Enable the Internal High Speed oscillator (HSI). */
266 __HAL_RCC_HSI_ENABLE();
268 tickstart = HAL_GetTick();
270 /* Wait till HSI is ready */
271 while(__HAL_RCC_GET_FLAG(RCC_FLAG_HSIRDY) == RESET)
273 if((HAL_GetTick() - tickstart) > HSI_TIMEOUT_VALUE)
279 /* Adjusts the Internal High Speed oscillator (HSI) calibration value. */
280 __HAL_RCC_HSI_CALIBRATIONVALUE_ADJUST(RCC_OscInitStruct->HSICalibrationValue);
284 /* Disable the Internal High Speed oscillator (HSI). */
285 __HAL_RCC_HSI_DISABLE();
288 tickstart = HAL_GetTick();
290 /* Wait till HSI is ready */
291 while(__HAL_RCC_GET_FLAG(RCC_FLAG_HSIRDY) != RESET)
293 if((HAL_GetTick() - tickstart) > HSI_TIMEOUT_VALUE)
301 /*------------------------------ LSI Configuration -------------------------*/
302 if(((RCC_OscInitStruct->OscillatorType) & RCC_OSCILLATORTYPE_LSI) == RCC_OSCILLATORTYPE_LSI)
304 /* Check the parameters */
305 assert_param(IS_RCC_LSI(RCC_OscInitStruct->LSIState));
307 /* Check the LSI State */
308 if(RCC_OscInitStruct->LSIState != RCC_LSI_OFF)
310 /* Enable the Internal Low Speed oscillator (LSI). */
311 __HAL_RCC_LSI_ENABLE();
314 tickstart = HAL_GetTick();
316 /* Wait till LSI is ready */
317 while(__HAL_RCC_GET_FLAG(RCC_FLAG_LSIRDY) == RESET)
319 if((HAL_GetTick() - tickstart) > LSI_TIMEOUT_VALUE)
327 /* Disable the Internal Low Speed oscillator (LSI). */
328 __HAL_RCC_LSI_DISABLE();
331 tickstart = HAL_GetTick();
333 /* Wait till LSI is ready */
334 while(__HAL_RCC_GET_FLAG(RCC_FLAG_LSIRDY) != RESET)
336 if((HAL_GetTick() - tickstart) > LSI_TIMEOUT_VALUE)
343 /*------------------------------ LSE Configuration -------------------------*/
344 if(((RCC_OscInitStruct->OscillatorType) & RCC_OSCILLATORTYPE_LSE) == RCC_OSCILLATORTYPE_LSE)
346 /* Check the parameters */
347 assert_param(IS_RCC_LSE(RCC_OscInitStruct->LSEState));
349 /* Enable Power Clock */
352 /* Enable write access to Backup domain */
353 SET_BIT(PWR->CR, PWR_CR_DBP);
355 /* Wait for Backup domain Write protection disable */
356 tickstart = HAL_GetTick();
358 while((PWR->CR & PWR_CR_DBP) == RESET)
360 if((HAL_GetTick() - tickstart) > DBP_TIMEOUT_VALUE)
366 /* Reset LSEON and LSEBYP bits before configuring the LSE ----------------*/
367 __HAL_RCC_LSE_CONFIG(RCC_LSE_OFF);
370 tickstart = HAL_GetTick();
372 /* Wait till LSE is ready */
373 while(__HAL_RCC_GET_FLAG(RCC_FLAG_LSERDY) != RESET)
375 if((HAL_GetTick() - tickstart) > LSE_TIMEOUT_VALUE)
381 /* Set the new LSE configuration -----------------------------------------*/
382 __HAL_RCC_LSE_CONFIG(RCC_OscInitStruct->LSEState);
383 /* Check the LSE State */
384 if(RCC_OscInitStruct->LSEState == RCC_LSE_ON)
387 tickstart = HAL_GetTick();
389 /* Wait till LSE is ready */
390 while(__HAL_RCC_GET_FLAG(RCC_FLAG_LSERDY) == RESET)
392 if((HAL_GetTick() - tickstart) > LSE_TIMEOUT_VALUE)
401 tickstart = HAL_GetTick();
403 /* Wait till LSE is ready */
404 while(__HAL_RCC_GET_FLAG(RCC_FLAG_LSERDY) != RESET)
406 if((HAL_GetTick() - tickstart) > LSE_TIMEOUT_VALUE)
414 /*----------------------------- HSI14 Configuration --------------------------*/
415 if(((RCC_OscInitStruct->OscillatorType) & RCC_OSCILLATORTYPE_HSI14) == RCC_OSCILLATORTYPE_HSI14)
417 /* Check the parameters */
418 assert_param(IS_RCC_HSI14(RCC_OscInitStruct->HSI14State));
419 assert_param(IS_RCC_CALIBRATION_VALUE(RCC_OscInitStruct->HSI14CalibrationValue));
421 /* Check the HSI14 State */
422 if(RCC_OscInitStruct->HSI14State == RCC_HSI14_ON)
424 /* Disable ADC control of the Internal High Speed oscillator HSI14 */
425 __HAL_RCC_HSI14ADC_DISABLE();
427 /* Enable the Internal High Speed oscillator (HSI). */
428 __HAL_RCC_HSI14_ENABLE();
431 tickstart = HAL_GetTick();
433 /* Wait till HSI is ready */
434 while(__HAL_RCC_GET_FLAG(RCC_FLAG_HSI14RDY) == RESET)
436 if((HAL_GetTick() - tickstart) > HSI14_TIMEOUT_VALUE)
442 /* Adjusts the Internal High Speed oscillator 14Mhz (HSI14) calibration value. */
443 __HAL_RCC_HSI14_CALIBRATIONVALUE_ADJUST(RCC_OscInitStruct->HSI14CalibrationValue);
445 else if(RCC_OscInitStruct->HSI14State == RCC_HSI14_ADC_CONTROL)
447 /* Enable ADC control of the Internal High Speed oscillator HSI14 */
448 __HAL_RCC_HSI14ADC_ENABLE();
450 /* Adjusts the Internal High Speed oscillator 14Mhz (HSI14) calibration value. */
451 __HAL_RCC_HSI14_CALIBRATIONVALUE_ADJUST(RCC_OscInitStruct->HSI14CalibrationValue);
455 /* Disable ADC control of the Internal High Speed oscillator HSI14 */
456 __HAL_RCC_HSI14ADC_DISABLE();
458 /* Disable the Internal High Speed oscillator (HSI). */
459 __HAL_RCC_HSI14_DISABLE();
462 tickstart = HAL_GetTick();
464 /* Wait till HSI is ready */
465 while(__HAL_RCC_GET_FLAG(RCC_FLAG_HSI14RDY) != RESET)
467 if((HAL_GetTick() - tickstart) > HSI14_TIMEOUT_VALUE)
475 #if defined(STM32F042x6) || defined(STM32F048xx) || defined(STM32F072xB) || defined(STM32F078xx) || \
476 defined(STM32F091xC) || defined(STM32F098xx)
477 /*----------------------------- HSI48 Configuration --------------------------*/
478 if(((RCC_OscInitStruct->OscillatorType) & RCC_OSCILLATORTYPE_HSI48) == RCC_OSCILLATORTYPE_HSI48)
480 /* Check the parameters */
481 assert_param(IS_RCC_HSI48(RCC_OscInitStruct->HSI48State));
483 /* When the HSI48 is used as system clock it is not allowed to be disabled */
484 if((__HAL_RCC_GET_SYSCLK_SOURCE() == RCC_SYSCLKSOURCE_STATUS_HSI48) ||
485 ((__HAL_RCC_GET_SYSCLK_SOURCE() == RCC_SYSCLKSOURCE_STATUS_PLLCLK) && (__HAL_RCC_GET_PLL_OSCSOURCE() == RCC_PLLSOURCE_HSI48)))
487 if((__HAL_RCC_GET_FLAG(RCC_FLAG_HSI48RDY) != RESET) && (RCC_OscInitStruct->HSI48State != RCC_HSI48_ON))
494 /* Check the HSI State */
495 if(RCC_OscInitStruct->HSI48State != RCC_HSI48_OFF)
497 /* Enable the Internal High Speed oscillator (HSI48). */
498 __HAL_RCC_HSI48_ENABLE();
501 tickstart = HAL_GetTick();
503 /* Wait till HSI is ready */
504 while(__HAL_RCC_GET_FLAG(RCC_FLAG_HSI48RDY) == RESET)
506 if((HAL_GetTick() - tickstart) > HSI48_TIMEOUT_VALUE)
514 /* Disable the Internal High Speed oscillator (HSI48). */
515 __HAL_RCC_HSI48_DISABLE();
518 tickstart = HAL_GetTick();
520 /* Wait till HSI is ready */
521 while(__HAL_RCC_GET_FLAG(RCC_FLAG_HSI48RDY) != RESET)
523 if((HAL_GetTick() - tickstart) > HSI48_TIMEOUT_VALUE)
531 #endif /* STM32F042x6 || STM32F048xx || STM32F072xB || STM32F078xx || */
532 /* STM32F091xC || STM32F098xx */
534 /*-------------------------------- PLL Configuration -----------------------*/
535 /* Check the parameters */
536 assert_param(IS_RCC_PLL(RCC_OscInitStruct->PLL.PLLState));
537 if ((RCC_OscInitStruct->PLL.PLLState) != RCC_PLL_NONE)
539 /* Check if the PLL is used as system clock or not */
540 if(__HAL_RCC_GET_SYSCLK_SOURCE() != RCC_SYSCLKSOURCE_STATUS_PLLCLK)
542 if((RCC_OscInitStruct->PLL.PLLState) == RCC_PLL_ON)
544 /* Check the parameters */
545 assert_param(IS_RCC_PLLSOURCE(RCC_OscInitStruct->PLL.PLLSource));
546 assert_param(IS_RCC_PREDIV(RCC_OscInitStruct->PLL.PREDIV));
547 assert_param(IS_RCC_PLL_MUL(RCC_OscInitStruct->PLL.PLLMUL));
549 /* Disable the main PLL. */
550 __HAL_RCC_PLL_DISABLE();
553 tickstart = HAL_GetTick();
555 /* Wait till PLL is ready */
556 while(__HAL_RCC_GET_FLAG(RCC_FLAG_PLLRDY) != RESET)
558 if((HAL_GetTick() - tickstart) > PLL_TIMEOUT_VALUE)
564 /* Configure the main PLL clock source, predivider and multiplication factor. */
565 __HAL_RCC_PLL_CONFIG(RCC_OscInitStruct->PLL.PLLSource,
566 RCC_OscInitStruct->PLL.PREDIV,
567 RCC_OscInitStruct->PLL.PLLMUL);
569 /* Enable the main PLL. */
570 __HAL_RCC_PLL_ENABLE();
573 tickstart = HAL_GetTick();
575 /* Wait till PLL is ready */
576 while(__HAL_RCC_GET_FLAG(RCC_FLAG_PLLRDY) == RESET)
578 if((HAL_GetTick() - tickstart) > PLL_TIMEOUT_VALUE)
586 /* Disable the main PLL. */
587 __HAL_RCC_PLL_DISABLE();
589 tickstart = HAL_GetTick();
591 /* Wait till PLL is ready */
592 while(__HAL_RCC_GET_FLAG(RCC_FLAG_PLLRDY) != RESET)
594 if((HAL_GetTick() - tickstart) > PLL_TIMEOUT_VALUE)
610 * @brief Initializes the CPU, AHB and APB busses clocks according to the specified
611 * parameters in the RCC_ClkInitStruct.
612 * @param RCC_ClkInitStruct: pointer to an RCC_OscInitTypeDef structure that
613 * contains the configuration information for the RCC peripheral.
614 * @param FLatency: FLASH Latency
615 * This parameter can be one of the following values:
616 * @arg FLASH_LATENCY_0: FLASH 0 Latency cycle
617 * @arg FLASH_LATENCY_1: FLASH 1 Latency cycle
619 * @note The SystemCoreClock CMSIS variable is used to store System Clock Frequency
620 * and updated by HAL_RCC_GetHCLKFreq() function called within this function
622 * @note The HSI is used (enabled by hardware) as system clock source after
623 * startup from Reset, wake-up from STOP and STANDBY mode, or in case
624 * of failure of the HSE used directly or indirectly as system clock
625 * (if the Clock Security System CSS is enabled).
627 * @note A switch from one clock source to another occurs only if the target
628 * clock source is ready (clock stable after startup delay or PLL locked).
629 * If a clock source which is not yet ready is selected, the switch will
630 * occur when the clock source will be ready.
633 HAL_StatusTypeDef HAL_RCC_ClockConfig(RCC_ClkInitTypeDef *RCC_ClkInitStruct, uint32_t FLatency)
635 uint32_t tickstart = 0;
637 /* Check the parameters */
638 assert_param(IS_RCC_CLOCKTYPE(RCC_ClkInitStruct->ClockType));
639 assert_param(IS_FLASH_LATENCY(FLatency));
641 /* To correctly read data from FLASH memory, the number of wait states (LATENCY)
642 must be correctly programmed according to the frequency of the CPU clock
643 (HCLK) of the device. */
645 /* Increasing the CPU frequency */
646 if(FLatency > (FLASH->ACR & FLASH_ACR_LATENCY))
648 /* Program the new number of wait states to the LATENCY bits in the FLASH_ACR register */
649 __HAL_FLASH_SET_LATENCY(FLatency);
651 /* Check that the new number of wait states is taken into account to access the Flash
652 memory by reading the FLASH_ACR register */
653 if((FLASH->ACR & FLASH_ACR_LATENCY) != FLatency)
658 /*-------------------------- HCLK Configuration --------------------------*/
659 if(((RCC_ClkInitStruct->ClockType) & RCC_CLOCKTYPE_HCLK) == RCC_CLOCKTYPE_HCLK)
661 assert_param(IS_RCC_SYSCLK_DIV(RCC_ClkInitStruct->AHBCLKDivider));
662 MODIFY_REG(RCC->CFGR, RCC_CFGR_HPRE, RCC_ClkInitStruct->AHBCLKDivider);
665 /*------------------------- SYSCLK Configuration ---------------------------*/
666 if(((RCC_ClkInitStruct->ClockType) & RCC_CLOCKTYPE_SYSCLK) == RCC_CLOCKTYPE_SYSCLK)
668 assert_param(IS_RCC_SYSCLKSOURCE(RCC_ClkInitStruct->SYSCLKSource));
670 /* HSE is selected as System Clock Source */
671 if(RCC_ClkInitStruct->SYSCLKSource == RCC_SYSCLKSOURCE_HSE)
673 /* Check the HSE ready flag */
674 if(__HAL_RCC_GET_FLAG(RCC_FLAG_HSERDY) == RESET)
679 /* PLL is selected as System Clock Source */
680 else if(RCC_ClkInitStruct->SYSCLKSource == RCC_SYSCLKSOURCE_PLLCLK)
682 /* Check the PLL ready flag */
683 if(__HAL_RCC_GET_FLAG(RCC_FLAG_PLLRDY) == RESET)
688 #if defined(STM32F042x6) || defined(STM32F048xx) || defined(STM32F072xB) || defined(STM32F078xx) || \
689 defined(STM32F091xC) || defined(STM32F098xx)
690 /* HSI48 is selected as System Clock Source */
691 else if(RCC_ClkInitStruct->SYSCLKSource == RCC_SYSCLKSOURCE_HSI48)
693 /* Check the HSI48 ready flag */
694 if(__HAL_RCC_GET_FLAG(RCC_FLAG_HSI48RDY) == RESET)
699 #endif /* STM32F042x6 || STM32F048xx || STM32F072xB || STM32F078xx || */
700 /* STM32F091xC || STM32F098xx */
701 /* HSI is selected as System Clock Source */
704 /* Check the HSI ready flag */
705 if(__HAL_RCC_GET_FLAG(RCC_FLAG_HSIRDY) == RESET)
710 MODIFY_REG(RCC->CFGR, RCC_CFGR_SW, RCC_ClkInitStruct->SYSCLKSource);
713 tickstart = HAL_GetTick();
715 if(RCC_ClkInitStruct->SYSCLKSource == RCC_SYSCLKSOURCE_HSE)
717 while (__HAL_RCC_GET_SYSCLK_SOURCE() != RCC_SYSCLKSOURCE_STATUS_HSE)
719 if((HAL_GetTick() - tickstart) > CLOCKSWITCH_TIMEOUT_VALUE)
725 else if(RCC_ClkInitStruct->SYSCLKSource == RCC_SYSCLKSOURCE_PLLCLK)
727 while (__HAL_RCC_GET_SYSCLK_SOURCE() != RCC_SYSCLKSOURCE_STATUS_PLLCLK)
729 if((HAL_GetTick() - tickstart) > CLOCKSWITCH_TIMEOUT_VALUE)
735 #if defined(STM32F042x6) || defined(STM32F048xx) || defined(STM32F072xB) || defined(STM32F078xx) || \
736 defined(STM32F091xC) || defined(STM32F098xx)
737 else if(RCC_ClkInitStruct->SYSCLKSource == RCC_SYSCLKSOURCE_HSI48)
739 while (__HAL_RCC_GET_SYSCLK_SOURCE() != RCC_SYSCLKSOURCE_STATUS_HSI48)
741 if((HAL_GetTick() - tickstart) > CLOCKSWITCH_TIMEOUT_VALUE)
747 #endif /* STM32F042x6 || STM32F048xx || STM32F072xB || STM32F078xx || */
748 /* STM32F091xC || STM32F098xx */
751 while(__HAL_RCC_GET_SYSCLK_SOURCE() != RCC_SYSCLKSOURCE_STATUS_HSI)
753 if((HAL_GetTick() - tickstart) > CLOCKSWITCH_TIMEOUT_VALUE)
761 /* Decreasing the CPU frequency */
764 /*-------------------------- HCLK Configuration --------------------------*/
765 if(((RCC_ClkInitStruct->ClockType) & RCC_CLOCKTYPE_HCLK) == RCC_CLOCKTYPE_HCLK)
767 assert_param(IS_RCC_SYSCLK_DIV(RCC_ClkInitStruct->AHBCLKDivider));
768 MODIFY_REG(RCC->CFGR, RCC_CFGR_HPRE, RCC_ClkInitStruct->AHBCLKDivider);
771 /*------------------------- SYSCLK Configuration ---------------------------*/
772 if(((RCC_ClkInitStruct->ClockType) & RCC_CLOCKTYPE_SYSCLK) == RCC_CLOCKTYPE_SYSCLK)
774 assert_param(IS_RCC_SYSCLKSOURCE(RCC_ClkInitStruct->SYSCLKSource));
776 /* HSE is selected as System Clock Source */
777 if(RCC_ClkInitStruct->SYSCLKSource == RCC_SYSCLKSOURCE_HSE)
779 /* Check the HSE ready flag */
780 if(__HAL_RCC_GET_FLAG(RCC_FLAG_HSERDY) == RESET)
785 /* PLL is selected as System Clock Source */
786 else if(RCC_ClkInitStruct->SYSCLKSource == RCC_SYSCLKSOURCE_PLLCLK)
788 /* Check the PLL ready flag */
789 if(__HAL_RCC_GET_FLAG(RCC_FLAG_PLLRDY) == RESET)
794 #if defined(STM32F042x6) || defined(STM32F048xx) || defined(STM32F072xB) || defined(STM32F078xx) || \
795 defined(STM32F091xC) || defined(STM32F098xx)
796 /* HSI48 is selected as System Clock Source */
797 else if(RCC_ClkInitStruct->SYSCLKSource == RCC_SYSCLKSOURCE_HSI48)
799 /* Check the HSI48 ready flag */
800 if(__HAL_RCC_GET_FLAG(RCC_FLAG_HSI48RDY) == RESET)
805 #endif /* STM32F042x6 || STM32F048xx || STM32F072xB || STM32F078xx || */
806 /* STM32F091xC || STM32F098xx */
807 /* HSI is selected as System Clock Source */
810 /* Check the HSI ready flag */
811 if(__HAL_RCC_GET_FLAG(RCC_FLAG_HSIRDY) == RESET)
816 MODIFY_REG(RCC->CFGR, RCC_CFGR_SW, RCC_ClkInitStruct->SYSCLKSource);
819 tickstart = HAL_GetTick();
821 if(RCC_ClkInitStruct->SYSCLKSource == RCC_SYSCLKSOURCE_HSE)
823 while (__HAL_RCC_GET_SYSCLK_SOURCE() != RCC_SYSCLKSOURCE_STATUS_HSE)
825 if((HAL_GetTick() - tickstart) > CLOCKSWITCH_TIMEOUT_VALUE)
831 else if(RCC_ClkInitStruct->SYSCLKSource == RCC_SYSCLKSOURCE_PLLCLK)
833 while (__HAL_RCC_GET_SYSCLK_SOURCE() != RCC_SYSCLKSOURCE_STATUS_PLLCLK)
835 if((HAL_GetTick() - tickstart) > CLOCKSWITCH_TIMEOUT_VALUE)
841 #if defined(STM32F042x6) || defined(STM32F048xx) || defined(STM32F072xB) || defined(STM32F078xx) || \
842 defined(STM32F091xC) || defined(STM32F098xx)
843 else if(RCC_ClkInitStruct->SYSCLKSource == RCC_SYSCLKSOURCE_HSI48)
845 while (__HAL_RCC_GET_SYSCLK_SOURCE() != RCC_SYSCLKSOURCE_STATUS_HSI48)
847 if((HAL_GetTick() - tickstart) > CLOCKSWITCH_TIMEOUT_VALUE)
853 #endif /* STM32F042x6 || STM32F048xx || STM32F072xB || STM32F078xx || */
854 /* STM32F091xC || STM32F098xx */
857 while(__HAL_RCC_GET_SYSCLK_SOURCE() != RCC_SYSCLKSOURCE_STATUS_HSI)
859 if((HAL_GetTick() - tickstart) > CLOCKSWITCH_TIMEOUT_VALUE)
867 /* Program the new number of wait states to the LATENCY bits in the FLASH_ACR register */
868 __HAL_FLASH_SET_LATENCY(FLatency);
870 /* Check that the new number of wait states is taken into account to access the Flash
871 memory by reading the FLASH_ACR register */
872 if((FLASH->ACR & FLASH_ACR_LATENCY) != FLatency)
878 /*-------------------------- PCLK1 Configuration ---------------------------*/
879 if(((RCC_ClkInitStruct->ClockType) & RCC_CLOCKTYPE_PCLK1) == RCC_CLOCKTYPE_PCLK1)
881 assert_param(IS_RCC_HCLK_DIV(RCC_ClkInitStruct->APB1CLKDivider));
882 MODIFY_REG(RCC->CFGR, RCC_CFGR_PPRE, RCC_ClkInitStruct->APB1CLKDivider);
885 /* Configure the source of time base considering new system clocks settings*/
886 HAL_InitTick (TICK_INT_PRIORITY);
892 * @brief Returns the SYSCLK frequency
893 * @note The system frequency computed by this function is not the real
894 * frequency in the chip. It is calculated based on the predefined
895 * constant and the selected clock source:
896 * @note If SYSCLK source is HSI, function returns a value based on HSI_VALUE(*)
897 * @note If SYSCLK source is HSI48, function returns a value based on HSI48_VALUE(*)
898 * @note If SYSCLK source is HSE, function returns a value based on HSE_VALUE
899 * divided by PREDIV factor(**)
900 * @note If SYSCLK source is PLL, function returns a value based on HSE_VALUE
901 * divided by PREDIV factor(**) or depending on STM32F0xx devices either a value based
902 * on HSI_VALUE divided by 2 or HSI_VALUE divided by PREDIV factor(*) multiplied by the
904 * @note (*) HSI_VALUE & HSI48_VALUE are constants defined in stm32f0xx_hal_conf.h file
905 * (default values 8 MHz and 48MHz).
906 * @note (**) HSE_VALUE is a constant defined in stm32f0xx_hal_conf.h file (default value
907 * 8 MHz), user has to ensure that HSE_VALUE is same as the real
908 * frequency of the crystal used. Otherwise, this function may
911 * @note The result of this function could be not correct when using fractional
912 * value for HSE crystal.
914 * @note This function can be used by the user application to compute the
915 * baudrate for the communication peripherals or configure other parameters.
917 * @note Each time SYSCLK changes, this function must be called to update the
918 * right SYSCLK value. Otherwise, any configuration based on this function will be incorrect.
920 * @retval SYSCLK frequency
922 uint32_t HAL_RCC_GetSysClockFreq(void)
924 uint32_t tmpreg = 0, prediv = 0, pllmul = 0, pllclk = 0;
925 uint32_t sysclockfreq = 0;
929 /* Get SYSCLK source -------------------------------------------------------*/
930 switch (tmpreg & RCC_CFGR_SWS)
932 case RCC_SYSCLKSOURCE_STATUS_HSE: /* HSE used as system clock source */
933 sysclockfreq = HSE_VALUE;
936 case RCC_SYSCLKSOURCE_STATUS_PLLCLK: /* PLL used as system clock source */
937 pllmul = PLLMULFactorTable[(uint32_t)(tmpreg & RCC_CFGR_PLLMUL) >> RCC_CFGR_PLLMUL_BITNUMBER];
938 prediv = PredivFactorTable[(uint32_t)(RCC->CFGR2 & RCC_CFGR2_PREDIV) >> RCC_CFGR2_PREDIV_BITNUMBER];
939 if ((tmpreg & RCC_CFGR_PLLSRC) == RCC_PLLSOURCE_HSE)
941 /* HSE used as PLL clock source : PLLCLK = HSE/PREDIV * PLLMUL */
942 pllclk = (HSE_VALUE/prediv) * pllmul;
944 #if defined(STM32F042x6) || defined(STM32F048xx) || defined(STM32F072xB) || defined(STM32F078xx) || \
945 defined(STM32F091xC) || defined(STM32F098xx)
946 else if ((tmpreg & RCC_CFGR_PLLSRC) == RCC_PLLSOURCE_HSI48)
948 /* HSI48 used as PLL clock source : PLLCLK = HSI48/PREDIV * PLLMUL */
949 pllclk = (HSI48_VALUE/prediv) * pllmul;
951 #endif /* STM32F042x6 || STM32F048xx || STM32F072xB || STM32F078xx || */
952 /* STM32F091xC || STM32F098xx */
955 #if defined(STM32F042x6) || defined(STM32F048xx) || defined(STM32F070x6) || \
956 defined(STM32F071xB) || defined(STM32F072xB) || defined(STM32F078xx) || defined(STM32F070xB) || \
957 defined(STM32F091xC) || defined(STM32F098xx) || defined(STM32F030xC)
958 /* HSI used as PLL clock source : PLLCLK = HSI/PREDIV * PLLMUL */
959 pllclk = (HSI_VALUE/prediv) * pllmul;
961 /* HSI used as PLL clock source : PLLCLK = HSI/2 * PLLMUL */
962 pllclk = (HSI_VALUE >> 1) * pllmul;
963 #endif /* STM32F042x6 || STM32F048xx || STM32F070x6 ||
964 STM32F071xB || STM32F072xB || STM32F078xx || STM32F070xB
965 STM32F091xC || STM32F098xx || STM32F030xC */
967 sysclockfreq = pllclk;
970 #if defined(STM32F042x6) || defined(STM32F048xx) || defined(STM32F072xB) || defined(STM32F078xx) || \
971 defined(STM32F091xC) || defined(STM32F098xx)
972 case RCC_SYSCLKSOURCE_STATUS_HSI48: /* HSI48 used as system clock source */
973 sysclockfreq = HSI48_VALUE;
975 #endif /* STM32F042x6 || STM32F048xx || STM32F072xB || STM32F078xx || */
976 /* STM32F091xC || STM32F098xx */
978 case RCC_SYSCLKSOURCE_STATUS_HSI: /* HSI used as system clock source */
980 sysclockfreq = HSI_VALUE;
987 * @brief Initializes the RCC extended peripherals clocks according to the specified
988 * parameters in the RCC_PeriphCLKInitTypeDef.
989 * @param PeriphClkInit: pointer to an RCC_PeriphCLKInitTypeDef structure that
990 * contains the configuration information for the Extended Peripherals clocks
991 * (USART, RTC, I2C, CEC and USB).
993 * @note Care must be taken when HAL_RCCEx_PeriphCLKConfig() is used to select
994 * the RTC clock source; in this case the Backup domain will be reset in
995 * order to modify the RTC Clock source, as consequence RTC registers (including
996 * the backup registers) and RCC_BDCR register are set to their reset values.
1000 HAL_StatusTypeDef HAL_RCCEx_PeriphCLKConfig(RCC_PeriphCLKInitTypeDef *PeriphClkInit)
1002 uint32_t tickstart = 0;
1003 uint32_t tmpreg = 0;
1005 /* Check the parameters */
1006 assert_param(IS_RCC_PERIPHCLK(PeriphClkInit->PeriphClockSelection));
1008 /*---------------------------- RTC configuration -------------------------------*/
1009 if(((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_RTC) == (RCC_PERIPHCLK_RTC))
1011 /* Enable Power Clock*/
1014 /* Enable write access to Backup domain */
1015 SET_BIT(PWR->CR, PWR_CR_DBP);
1017 /* Wait for Backup domain Write protection disable */
1018 tickstart = HAL_GetTick();
1020 while((PWR->CR & PWR_CR_DBP) == RESET)
1022 if((HAL_GetTick() - tickstart) > DBP_TIMEOUT_VALUE)
1028 /* Reset the Backup domain only if the RTC Clock source selction is modified */
1029 if((RCC->BDCR & RCC_BDCR_RTCSEL) != (PeriphClkInit->RTCClockSelection & RCC_BDCR_RTCSEL))
1031 /* Store the content of BDCR register before the reset of Backup Domain */
1032 tmpreg = (RCC->BDCR & ~(RCC_BDCR_RTCSEL));
1033 /* RTC Clock selection can be changed only if the Backup Domain is reset */
1034 __HAL_RCC_BACKUPRESET_FORCE();
1035 __HAL_RCC_BACKUPRESET_RELEASE();
1036 /* Restore the Content of BDCR register */
1040 /* If LSE is selected as RTC clock source, wait for LSE reactivation */
1041 if(PeriphClkInit->RTCClockSelection == RCC_RTCCLKSOURCE_LSE)
1044 tickstart = HAL_GetTick();
1046 /* Wait till LSE is ready */
1047 while(__HAL_RCC_GET_FLAG(RCC_FLAG_LSERDY) == RESET)
1049 if((HAL_GetTick() - tickstart) > LSE_TIMEOUT_VALUE)
1055 __HAL_RCC_RTC_CONFIG(PeriphClkInit->RTCClockSelection);
1058 /*------------------------------- USART1 Configuration ------------------------*/
1059 if(((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_USART1) == RCC_PERIPHCLK_USART1)
1061 /* Check the parameters */
1062 assert_param(IS_RCC_USART1CLKSOURCE(PeriphClkInit->Usart1ClockSelection));
1064 /* Configure the USART1 clock source */
1065 __HAL_RCC_USART1_CONFIG(PeriphClkInit->Usart1ClockSelection);
1068 #if defined(STM32F071xB) || defined(STM32F072xB) || defined(STM32F078xx) || \
1069 defined(STM32F091xC) || defined(STM32F098xx)
1070 /*----------------------------- USART2 Configuration --------------------------*/
1071 if(((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_USART2) == RCC_PERIPHCLK_USART2)
1073 /* Check the parameters */
1074 assert_param(IS_RCC_USART2CLKSOURCE(PeriphClkInit->Usart2ClockSelection));
1076 /* Configure the USART2 clock source */
1077 __HAL_RCC_USART2_CONFIG(PeriphClkInit->Usart2ClockSelection);
1079 #endif /* STM32F071xB || STM32F072xB || STM32F078xx || */
1080 /* STM32F091xC || STM32F098xx */
1082 #if defined(STM32F091xC) || defined(STM32F098xx)
1083 /*----------------------------- USART3 Configuration --------------------------*/
1084 if(((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_USART3) == RCC_PERIPHCLK_USART3)
1086 /* Check the parameters */
1087 assert_param(IS_RCC_USART3CLKSOURCE(PeriphClkInit->Usart3ClockSelection));
1089 /* Configure the USART3 clock source */
1090 __HAL_RCC_USART3_CONFIG(PeriphClkInit->Usart3ClockSelection);
1092 #endif /* STM32F091xC || STM32F098xx */
1094 /*------------------------------ I2C1 Configuration ------------------------*/
1095 if(((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_I2C1) == RCC_PERIPHCLK_I2C1)
1097 /* Check the parameters */
1098 assert_param(IS_RCC_I2C1CLKSOURCE(PeriphClkInit->I2c1ClockSelection));
1100 /* Configure the I2C1 clock source */
1101 __HAL_RCC_I2C1_CONFIG(PeriphClkInit->I2c1ClockSelection);
1104 #if defined(STM32F042x6) || defined(STM32F048xx) || defined(STM32F072xB) || defined(STM32F078xx) || defined(STM32F070xB) || defined(STM32F070x6)
1105 /*------------------------------ USB Configuration ------------------------*/
1106 if(((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_USB) == RCC_PERIPHCLK_USB)
1108 /* Check the parameters */
1109 assert_param(IS_RCC_USBCLKSOURCE(PeriphClkInit->UsbClockSelection));
1111 /* Configure the USB clock source */
1112 __HAL_RCC_USB_CONFIG(PeriphClkInit->UsbClockSelection);
1114 #endif /* STM32F042x6 || STM32F048xx || STM32F072xB || STM32F078xx || STM32F070xB || STM32F070x6 */
1116 #if defined(STM32F042x6) || defined(STM32F048xx) || \
1117 defined(STM32F051x8) || defined(STM32F058xx) || \
1118 defined(STM32F071xB) || defined(STM32F072xB) || defined(STM32F078xx) || \
1119 defined(STM32F091xC) || defined(STM32F098xx)
1120 /*------------------------------ CEC clock Configuration -------------------*/
1121 if(((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_CEC) == RCC_PERIPHCLK_CEC)
1123 /* Check the parameters */
1124 assert_param(IS_RCC_CECCLKSOURCE(PeriphClkInit->CecClockSelection));
1126 /* Configure the CEC clock source */
1127 __HAL_RCC_CEC_CONFIG(PeriphClkInit->CecClockSelection);
1129 #endif /* STM32F042x6 || STM32F048xx || */
1130 /* STM32F051x8 || STM32F058xx || */
1131 /* STM32F071xB || STM32F072xB || STM32F078xx || */
1132 /* STM32F091xC || STM32F098xx */
1138 * @brief Get the RCC_ClkInitStruct according to the internal
1139 * RCC configuration registers.
1140 * @param PeriphClkInit: pointer to an RCC_PeriphCLKInitTypeDef structure that
1141 * returns the configuration information for the Extended Peripherals clocks
1142 * (USART, RTC, I2C, CEC and USB).
1145 void HAL_RCCEx_GetPeriphCLKConfig(RCC_PeriphCLKInitTypeDef *PeriphClkInit)
1147 /* Set all possible values for the extended clock type parameter------------*/
1148 /* Common part first */
1149 PeriphClkInit->PeriphClockSelection = RCC_PERIPHCLK_USART1 | RCC_PERIPHCLK_I2C1 | RCC_PERIPHCLK_RTC;
1150 /* Get the RTC configuration --------------------------------------------*/
1151 PeriphClkInit->RTCClockSelection = __HAL_RCC_GET_RTC_SOURCE();
1152 /* Get the USART1 configuration --------------------------------------------*/
1153 PeriphClkInit->Usart1ClockSelection = __HAL_RCC_GET_USART1_SOURCE();
1154 /* Get the I2C1 clock source -----------------------------------------------*/
1155 PeriphClkInit->I2c1ClockSelection = __HAL_RCC_GET_I2C1_SOURCE();
1157 #if defined(STM32F071xB) || defined(STM32F072xB) || defined(STM32F078xx) || \
1158 defined(STM32F091xC) || defined(STM32F098xx)
1159 PeriphClkInit->PeriphClockSelection |= RCC_PERIPHCLK_USART2;
1160 /* Get the USART2 clock source ---------------------------------------------*/
1161 PeriphClkInit->Usart2ClockSelection = __HAL_RCC_GET_USART2_SOURCE();
1162 #endif /* STM32F071xB || STM32F072xB || STM32F078xx || */
1163 /* STM32F091xC || STM32F098xx */
1165 #if defined(STM32F091xC) || defined(STM32F098xx)
1166 PeriphClkInit->PeriphClockSelection |= RCC_PERIPHCLK_USART3;
1167 /* Get the USART3 clock source ---------------------------------------------*/
1168 PeriphClkInit->Usart3ClockSelection = __HAL_RCC_GET_USART3_SOURCE();
1169 #endif /* STM32F091xC || STM32F098xx */
1171 #if defined(STM32F042x6) || defined(STM32F048xx) || defined(STM32F072xB) || defined(STM32F078xx) || defined(STM32F070xB) || defined(STM32F070x6)
1172 PeriphClkInit->PeriphClockSelection |= RCC_PERIPHCLK_USB;
1173 /* Get the USB clock source ---------------------------------------------*/
1174 PeriphClkInit->UsbClockSelection = __HAL_RCC_GET_USB_SOURCE();
1175 #endif /* STM32F042x6 || STM32F048xx || STM32F072xB || STM32F078xx || STM32F070xB || STM32F070x6 */
1177 #if defined(STM32F042x6) || defined(STM32F048xx) || \
1178 defined(STM32F051x8) || defined(STM32F058xx) || \
1179 defined(STM32F071xB) || defined(STM32F072xB) || defined(STM32F078xx) || \
1180 defined(STM32F091xC) || defined(STM32F098xx)
1181 PeriphClkInit->PeriphClockSelection |= RCC_PERIPHCLK_CEC;
1182 /* Get the CEC clock source ------------------------------------------------*/
1183 PeriphClkInit->CecClockSelection = __HAL_RCC_GET_CEC_SOURCE();
1184 #endif /* STM32F042x6 || STM32F048xx || */
1185 /* STM32F051x8 || STM32F058xx || */
1186 /* STM32F071xB || STM32F072xB || STM32F078xx || */
1187 /* STM32F091xC || STM32F098xx */
1191 #if defined(STM32F042x6) || defined(STM32F048xx) || \
1192 defined(STM32F071xB) || defined(STM32F072xB) || defined(STM32F078xx) || \
1193 defined(STM32F091xC) || defined(STM32F098xx)
1195 * @brief Start automatic synchronization using polling mode
1196 * @param pInit Pointer on RCC_CRSInitTypeDef structure
1199 void HAL_RCCEx_CRSConfig(RCC_CRSInitTypeDef *pInit)
1201 /* Check the parameters */
1202 assert_param(IS_RCC_CRS_SYNC_DIV(pInit->Prescaler));
1203 assert_param(IS_RCC_CRS_SYNC_SOURCE(pInit->Source));
1204 assert_param(IS_RCC_CRS_SYNC_POLARITY(pInit->Polarity));
1205 assert_param(IS_RCC_CRS_RELOADVALUE(pInit->ReloadValue));
1206 assert_param(IS_RCC_CRS_ERRORLIMIT(pInit->ErrorLimitValue));
1207 assert_param(IS_RCC_CRS_HSI48CALIBRATION(pInit->HSI48CalibrationValue));
1212 /* Before configuration, reset CRS registers to their default values*/
1213 __CRS_FORCE_RESET();
1214 __CRS_RELEASE_RESET();
1216 /* Configure Synchronization input */
1217 /* Clear SYNCDIV[2:0], SYNCSRC[1:0] & SYNCSPOL bits */
1218 CRS->CFGR &= ~(CRS_CFGR_SYNCDIV | CRS_CFGR_SYNCSRC | CRS_CFGR_SYNCPOL);
1220 /* Set the CRS_CFGR_SYNCDIV[2:0] bits according to Prescaler value */
1221 CRS->CFGR |= pInit->Prescaler;
1223 /* Set the SYNCSRC[1:0] bits according to Source value */
1224 CRS->CFGR |= pInit->Source;
1226 /* Set the SYNCSPOL bits according to Polarity value */
1227 CRS->CFGR |= pInit->Polarity;
1229 /* Configure Frequency Error Measurement */
1230 /* Clear RELOAD[15:0] & FELIM[7:0] bits*/
1231 CRS->CFGR &= ~(CRS_CFGR_RELOAD | CRS_CFGR_FELIM);
1233 /* Set the RELOAD[15:0] bits according to ReloadValue value */
1234 CRS->CFGR |= pInit->ReloadValue;
1236 /* Set the FELIM[7:0] bits according to ErrorLimitValue value */
1237 CRS->CFGR |= (pInit->ErrorLimitValue << CRS_CFGR_FELIM_BITNUMBER);
1239 /* Adjust HSI48 oscillator smooth trimming */
1240 /* Clear TRIM[5:0] bits */
1241 CRS->CR &= ~CRS_CR_TRIM;
1243 /* Set the TRIM[5:0] bits according to RCC_CRS_HSI48CalibrationValue value */
1244 CRS->CR |= (pInit->HSI48CalibrationValue << CRS_CR_TRIM_BITNUMBER);
1247 /* START AUTOMATIC SYNCHRONIZATION*/
1249 /* Enable Automatic trimming */
1250 __HAL_RCC_CRS_ENABLE_AUTOMATIC_CALIB();
1252 /* Enable Frequency error counter */
1253 __HAL_RCC_CRS_ENABLE_FREQ_ERROR_COUNTER();
1258 * @brief Generate the software synchronization event
1261 void HAL_RCCEx_CRSSoftwareSynchronizationGenerate(void)
1263 CRS->CR |= CRS_CR_SWSYNC;
1268 * @brief Function to return synchronization info
1269 * @param pSynchroInfo Pointer on RCC_CRSSynchroInfoTypeDef structure
1272 void HAL_RCCEx_CRSGetSynchronizationInfo(RCC_CRSSynchroInfoTypeDef *pSynchroInfo)
1274 /* Check the parameter */
1275 assert_param(pSynchroInfo != NULL);
1277 /* Get the reload value */
1278 pSynchroInfo->ReloadValue = (uint32_t)(CRS->CFGR & CRS_CFGR_RELOAD);
1280 /* Get HSI48 oscillator smooth trimming */
1281 pSynchroInfo->HSI48CalibrationValue = (uint32_t)((CRS->CR & CRS_CR_TRIM) >> CRS_CR_TRIM_BITNUMBER);
1283 /* Get Frequency error capture */
1284 pSynchroInfo->FreqErrorCapture = (uint32_t)((CRS->ISR & CRS_ISR_FECAP) >> CRS_ISR_FECAP_BITNUMBER);
1286 /* Get FFrequency error direction */
1287 pSynchroInfo->FreqErrorDirection = (uint32_t)(CRS->ISR & CRS_ISR_FEDIR);
1293 * @brief This function handles CRS Synchronization Timeout.
1294 * @param Timeout: Duration of the timeout
1295 * @note Timeout is based on the maximum time to receive a SYNC event based on synchronization
1297 * @note If Timeout set to HAL_MAX_DELAY, HAL_TIMEOUT will be never returned.
1298 * @retval Combination of Synchronization status
1299 * This parameter can be a combination of the following values:
1300 * @arg RCC_CRS_TIMEOUT
1301 * @arg RCC_CRS_SYNCOK
1302 * @arg RCC_CRS_SYNCWARM
1303 * @arg RCC_CRS_SYNCERR
1304 * @arg RCC_CRS_SYNCMISS
1305 * @arg RCC_CRS_TRIMOV
1307 uint32_t HAL_RCCEx_CRSWaitSynchronization(uint32_t Timeout)
1309 uint32_t crsstatus = RCC_CRS_NONE;
1310 uint32_t tickstart = 0;
1313 tickstart = HAL_GetTick();
1315 /* Check that if one of CRS flags have been set */
1316 while(RCC_CRS_NONE == crsstatus)
1318 if(Timeout != HAL_MAX_DELAY)
1320 if((Timeout == 0) || ((HAL_GetTick() - tickstart) > Timeout))
1322 crsstatus = RCC_CRS_TIMEOUT;
1325 /* Check CRS SYNCOK flag */
1326 if(__HAL_RCC_CRS_GET_FLAG(RCC_CRS_FLAG_SYNCOK))
1328 /* CRS SYNC event OK */
1329 crsstatus |= RCC_CRS_SYNCOK;
1331 /* Clear CRS SYNC event OK bit */
1332 __HAL_RCC_CRS_CLEAR_FLAG(RCC_CRS_FLAG_SYNCOK);
1335 /* Check CRS SYNCWARN flag */
1336 if(__HAL_RCC_CRS_GET_FLAG(RCC_CRS_FLAG_SYNCWARN))
1338 /* CRS SYNC warning */
1339 crsstatus |= RCC_CRS_SYNCWARM;
1341 /* Clear CRS SYNCWARN bit */
1342 __HAL_RCC_CRS_CLEAR_FLAG(RCC_CRS_FLAG_SYNCWARN);
1345 /* Check CRS TRIM overflow flag */
1346 if(__HAL_RCC_CRS_GET_FLAG(RCC_CRS_FLAG_TRIMOVF))
1348 /* CRS SYNC Error */
1349 crsstatus |= RCC_CRS_TRIMOV;
1351 /* Clear CRS Error bit */
1352 __HAL_RCC_CRS_CLEAR_FLAG(RCC_CRS_FLAG_TRIMOVF);
1355 /* Check CRS Error flag */
1356 if(__HAL_RCC_CRS_GET_FLAG(RCC_CRS_FLAG_SYNCERR))
1358 /* CRS SYNC Error */
1359 crsstatus |= RCC_CRS_SYNCERR;
1361 /* Clear CRS Error bit */
1362 __HAL_RCC_CRS_CLEAR_FLAG(RCC_CRS_FLAG_SYNCERR);
1365 /* Check CRS SYNC Missed flag */
1366 if(__HAL_RCC_CRS_GET_FLAG(RCC_CRS_FLAG_SYNCMISS))
1368 /* CRS SYNC Missed */
1369 crsstatus |= RCC_CRS_SYNCMISS;
1371 /* Clear CRS SYNC Missed bit */
1372 __HAL_RCC_CRS_CLEAR_FLAG(RCC_CRS_FLAG_SYNCMISS);
1375 /* Check CRS Expected SYNC flag */
1376 if(__HAL_RCC_CRS_GET_FLAG(RCC_CRS_FLAG_ESYNC))
1378 /* frequency error counter reached a zero value */
1379 __HAL_RCC_CRS_CLEAR_FLAG(RCC_CRS_FLAG_ESYNC);
1386 #endif /* STM32F042x6 || STM32F048xx || */
1387 /* STM32F071xB || STM32F072xB || STM32F078xx || */
1388 /* STM32F091xC || STM32F098xx */
1398 #endif /* HAL_RCC_MODULE_ENABLED */
1407 /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/