mirror of https://github.com/rusefi/cantact-fw.git
1407 lines
52 KiB
C
1407 lines
52 KiB
C
/**
|
|
******************************************************************************
|
|
* @file stm32f0xx_hal_rcc_ex.c
|
|
* @author MCD Application Team
|
|
* @version V1.1.0
|
|
* @date 03-Oct-2014
|
|
* @brief Extended RCC HAL module driver
|
|
* This file provides firmware functions to manage the following
|
|
* functionalities RCC extension peripheral:
|
|
* + Extended Clock Source configuration functions
|
|
*
|
|
@verbatim
|
|
==============================================================================
|
|
##### How to use this driver #####
|
|
==============================================================================
|
|
|
|
For CRS, RCC Extention HAL driver can be used as follows:
|
|
|
|
(#) In System clock config, HSI48 need to be enabled
|
|
|
|
(#] Enable CRS clock in IP MSP init which will use CRS functions
|
|
|
|
(#) Call CRS functions like this
|
|
(##) Prepare synchronization configuration necessary for HSI48 calibration
|
|
(+++) Default values can be set for frequency Error Measurement (reload and error limit)
|
|
and also HSI48 oscillator smooth trimming.
|
|
(+++) Macro __HAL_RCC_CRS_CALCULATE_RELOADVALUE can be also used to calculate
|
|
directly reload value with target and sychronization frequencies values
|
|
(##) Call function HAL_RCCEx_CRSConfig which
|
|
(+++) Reset CRS registers to their default values.
|
|
(+++) Configure CRS registers with synchronization configuration
|
|
(+++) Enable automatic calibration and frequency error counter feature
|
|
|
|
(##) A polling function is provided to wait for complete Synchronization
|
|
(+++) Call function HAL_RCCEx_CRSWaitSynchronization()
|
|
(+++) According to CRS status, user can decide to adjust again the calibration or continue
|
|
application if synchronization is OK
|
|
|
|
(#) User can retrieve information related to synchronization in calling function
|
|
HAL_RCCEx_CRSGetSynchronizationInfo()
|
|
|
|
(#) Regarding synchronization status and synchronization information, user can try a new calibration
|
|
in changing synchronization configuration and call again HAL_RCCEx_CRSConfig.
|
|
Note: When the SYNC event is detected during the downcounting phase (before reaching the zero value),
|
|
it means that the actual frequency is lower than the target (and so, that the TRIM value should be
|
|
incremented), while when it is detected during the upcounting phase it means that the actual frequency
|
|
is higher (and that the TRIM value should be decremented).
|
|
|
|
(#) To use IT mode, user needs to handle it in calling different macros available to do it
|
|
(__HAL_RCC_CRS_XXX_IT). Interuptions will go through RCC Handler (RCC_IRQn/RCC_CRS_IRQHandler)
|
|
(++) Call function HAL_RCCEx_CRSConfig()
|
|
(++) Enable RCC_IRQn (thnaks to NVIC functions)
|
|
(++) Enable CRS IT (__HAL_RCC_CRS_ENABLE_IT)
|
|
(++) Implement CRS status management in RCC_CRS_IRQHandler
|
|
|
|
(#) To force a SYNC EVENT, user can use function HAL_RCCEx_CRSSoftwareSynchronizationGenerate(). Function can be
|
|
called before calling HAL_RCCEx_CRSConfig (for instance in Systick handler)
|
|
|
|
@endverbatim
|
|
******************************************************************************
|
|
* @attention
|
|
*
|
|
* <h2><center>© COPYRIGHT(c) 2014 STMicroelectronics</center></h2>
|
|
*
|
|
* Redistribution and use in source and binary forms, with or without modification,
|
|
* are permitted provided that the following conditions are met:
|
|
* 1. Redistributions of source code must retain the above copyright notice,
|
|
* this list of conditions and the following disclaimer.
|
|
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
|
* this list of conditions and the following disclaimer in the documentation
|
|
* and/or other materials provided with the distribution.
|
|
* 3. Neither the name of STMicroelectronics nor the names of its contributors
|
|
* may be used to endorse or promote products derived from this software
|
|
* without specific prior written permission.
|
|
*
|
|
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
|
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
|
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
|
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
|
|
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
|
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
|
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
|
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
|
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
|
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
*
|
|
******************************************************************************
|
|
*/
|
|
|
|
/* Includes ------------------------------------------------------------------*/
|
|
#include "stm32f0xx_hal.h"
|
|
|
|
/** @addtogroup STM32F0xx_HAL_Driver
|
|
* @{
|
|
*/
|
|
|
|
/** @defgroup RCCEx RCCEx Extended HAL module driver
|
|
* @brief RCC Extension HAL module driver.
|
|
* @{
|
|
*/
|
|
|
|
#ifdef HAL_RCC_MODULE_ENABLED
|
|
|
|
/* Private typedef -----------------------------------------------------------*/
|
|
/* Private define ------------------------------------------------------------*/
|
|
/** @defgroup RCCEx_Private_Define RCCEx Private Define
|
|
* @{
|
|
*/
|
|
#define HSI48_TIMEOUT_VALUE ((uint32_t)100) /* 100 ms */
|
|
|
|
/* Bit position in register */
|
|
#define CRS_CFGR_FELIM_BITNUMBER 16
|
|
#define CRS_CR_TRIM_BITNUMBER 8
|
|
#define CRS_ISR_FECAP_BITNUMBER 16
|
|
/**
|
|
* @}
|
|
*/
|
|
|
|
/* Private macro -------------------------------------------------------------*/
|
|
/* Private variables ---------------------------------------------------------*/
|
|
/** @defgroup RCCEx_Private_Variables RCCEx Private Variables
|
|
* @{
|
|
*/
|
|
const uint8_t PLLMULFactorTable[16] = { 2, 3, 4, 5, 6, 7, 8, 9,
|
|
10, 11, 12, 13, 14, 15, 16, 16};
|
|
const uint8_t PredivFactorTable[16] = { 1, 2, 3, 4, 5, 6, 7, 8,
|
|
9,10, 11, 12, 13, 14, 15, 16};
|
|
/**
|
|
* @}
|
|
*/
|
|
/* Private function prototypes -----------------------------------------------*/
|
|
/* Exported functions ---------------------------------------------------------*/
|
|
|
|
/** @defgroup RCCEx_Exported_Functions RCCEx Exported Functions
|
|
* @{
|
|
*/
|
|
|
|
/** @defgroup RCCEx_Exported_Functions_Group1 Extended Peripheral Control functions
|
|
* @brief Extended RCC clocks control functions
|
|
*
|
|
@verbatim
|
|
===============================================================================
|
|
##### Extended Peripheral Control functions #####
|
|
===============================================================================
|
|
[..]
|
|
This subsection provides a set of functions allowing to control the RCC Clocks
|
|
frequencies.
|
|
[..]
|
|
(@) Important note: Care must be taken when HAL_RCCEx_PeriphCLKConfig() is used to
|
|
select the RTC clock source; in this case the Backup domain will be reset in
|
|
order to modify the RTC Clock source, as consequence RTC registers (including
|
|
the backup registers) and RCC_BDCR register are set to their reset values.
|
|
|
|
@endverbatim
|
|
* @{
|
|
*/
|
|
|
|
/**
|
|
* @brief Initializes the RCC Oscillators according to the specified parameters in the
|
|
* RCC_OscInitTypeDef.
|
|
* @param RCC_OscInitStruct: pointer to an RCC_OscInitTypeDef structure that
|
|
* contains the configuration information for the RCC Oscillators.
|
|
* @note The PLL is not disabled when used as system clock.
|
|
* @retval HAL status
|
|
*/
|
|
HAL_StatusTypeDef HAL_RCC_OscConfig(RCC_OscInitTypeDef *RCC_OscInitStruct)
|
|
{
|
|
uint32_t tickstart = 0;
|
|
|
|
/* Check the parameters */
|
|
assert_param(IS_RCC_OSCILLATORTYPE(RCC_OscInitStruct->OscillatorType));
|
|
/*------------------------------- HSE Configuration ------------------------*/
|
|
if(((RCC_OscInitStruct->OscillatorType) & RCC_OSCILLATORTYPE_HSE) == RCC_OSCILLATORTYPE_HSE)
|
|
{
|
|
/* Check the parameters */
|
|
assert_param(IS_RCC_HSE(RCC_OscInitStruct->HSEState));
|
|
/* When the HSE is used as system clock or clock source for PLL in these cases it is not allowed to be disabled */
|
|
if((__HAL_RCC_GET_SYSCLK_SOURCE() == RCC_SYSCLKSOURCE_STATUS_HSE) ||
|
|
((__HAL_RCC_GET_SYSCLK_SOURCE() == RCC_SYSCLKSOURCE_STATUS_PLLCLK) && (__HAL_RCC_GET_PLL_OSCSOURCE() == RCC_PLLSOURCE_HSE)))
|
|
{
|
|
if((__HAL_RCC_GET_FLAG(RCC_FLAG_HSERDY) != RESET) && (RCC_OscInitStruct->HSEState != RCC_HSE_ON))
|
|
{
|
|
return HAL_ERROR;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
/* Reset HSEON and HSEBYP bits before configuring the HSE --------------*/
|
|
__HAL_RCC_HSE_CONFIG(RCC_HSE_OFF);
|
|
|
|
/* Get timeout */
|
|
tickstart = HAL_GetTick();
|
|
|
|
/* Wait till HSE is ready */
|
|
while(__HAL_RCC_GET_FLAG(RCC_FLAG_HSERDY) != RESET)
|
|
{
|
|
if((HAL_GetTick() - tickstart) > HSE_TIMEOUT_VALUE)
|
|
{
|
|
return HAL_TIMEOUT;
|
|
}
|
|
}
|
|
|
|
/* Set the new HSE configuration ---------------------------------------*/
|
|
__HAL_RCC_HSE_CONFIG((uint8_t)RCC_OscInitStruct->HSEState);
|
|
|
|
/* Check the HSE State */
|
|
if(RCC_OscInitStruct->HSEState != RCC_HSE_OFF)
|
|
{
|
|
/* Get timeout */
|
|
tickstart = HAL_GetTick();
|
|
|
|
/* Wait till HSE is ready */
|
|
while(__HAL_RCC_GET_FLAG(RCC_FLAG_HSERDY) == RESET)
|
|
{
|
|
if((HAL_GetTick() - tickstart) > HSE_TIMEOUT_VALUE)
|
|
{
|
|
return HAL_TIMEOUT;
|
|
}
|
|
}
|
|
}
|
|
else
|
|
{
|
|
/* Get timeout */
|
|
tickstart = HAL_GetTick();
|
|
|
|
/* Wait till HSE is ready */
|
|
while(__HAL_RCC_GET_FLAG(RCC_FLAG_HSERDY) != RESET)
|
|
{
|
|
if((HAL_GetTick() - tickstart) > HSE_TIMEOUT_VALUE)
|
|
{
|
|
return HAL_TIMEOUT;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
/*----------------------------- HSI Configuration --------------------------*/
|
|
if(((RCC_OscInitStruct->OscillatorType) & RCC_OSCILLATORTYPE_HSI) == RCC_OSCILLATORTYPE_HSI)
|
|
{
|
|
/* Check the parameters */
|
|
assert_param(IS_RCC_HSI(RCC_OscInitStruct->HSIState));
|
|
assert_param(IS_RCC_CALIBRATION_VALUE(RCC_OscInitStruct->HSICalibrationValue));
|
|
|
|
/* Check if HSI is used as system clock or as PLL source when PLL is selected as system clock */
|
|
if((__HAL_RCC_GET_SYSCLK_SOURCE() == RCC_SYSCLKSOURCE_STATUS_HSI) ||
|
|
((__HAL_RCC_GET_SYSCLK_SOURCE() == RCC_SYSCLKSOURCE_STATUS_PLLCLK) && (__HAL_RCC_GET_PLL_OSCSOURCE() == RCC_PLLSOURCE_HSI)))
|
|
{
|
|
/* When the HSI is used as system clock it is not allowed to be disabled */
|
|
if((__HAL_RCC_GET_FLAG(RCC_FLAG_HSIRDY) != RESET) && (RCC_OscInitStruct->HSIState != RCC_HSI_ON))
|
|
{
|
|
return HAL_ERROR;
|
|
}
|
|
/* Otherwise, just the calibration is allowed */
|
|
else
|
|
{
|
|
/* Adjusts the Internal High Speed oscillator (HSI) calibration value.*/
|
|
__HAL_RCC_HSI_CALIBRATIONVALUE_ADJUST(RCC_OscInitStruct->HSICalibrationValue);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
/* Check the HSI State */
|
|
if(RCC_OscInitStruct->HSIState != RCC_HSI_OFF)
|
|
{
|
|
/* Enable the Internal High Speed oscillator (HSI). */
|
|
__HAL_RCC_HSI_ENABLE();
|
|
|
|
tickstart = HAL_GetTick();
|
|
|
|
/* Wait till HSI is ready */
|
|
while(__HAL_RCC_GET_FLAG(RCC_FLAG_HSIRDY) == RESET)
|
|
{
|
|
if((HAL_GetTick() - tickstart) > HSI_TIMEOUT_VALUE)
|
|
{
|
|
return HAL_TIMEOUT;
|
|
}
|
|
}
|
|
|
|
/* Adjusts the Internal High Speed oscillator (HSI) calibration value. */
|
|
__HAL_RCC_HSI_CALIBRATIONVALUE_ADJUST(RCC_OscInitStruct->HSICalibrationValue);
|
|
}
|
|
else
|
|
{
|
|
/* Disable the Internal High Speed oscillator (HSI). */
|
|
__HAL_RCC_HSI_DISABLE();
|
|
|
|
/* Get timeout */
|
|
tickstart = HAL_GetTick();
|
|
|
|
/* Wait till HSI is ready */
|
|
while(__HAL_RCC_GET_FLAG(RCC_FLAG_HSIRDY) != RESET)
|
|
{
|
|
if((HAL_GetTick() - tickstart) > HSI_TIMEOUT_VALUE)
|
|
{
|
|
return HAL_TIMEOUT;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
/*------------------------------ LSI Configuration -------------------------*/
|
|
if(((RCC_OscInitStruct->OscillatorType) & RCC_OSCILLATORTYPE_LSI) == RCC_OSCILLATORTYPE_LSI)
|
|
{
|
|
/* Check the parameters */
|
|
assert_param(IS_RCC_LSI(RCC_OscInitStruct->LSIState));
|
|
|
|
/* Check the LSI State */
|
|
if(RCC_OscInitStruct->LSIState != RCC_LSI_OFF)
|
|
{
|
|
/* Enable the Internal Low Speed oscillator (LSI). */
|
|
__HAL_RCC_LSI_ENABLE();
|
|
|
|
/* Get timeout */
|
|
tickstart = HAL_GetTick();
|
|
|
|
/* Wait till LSI is ready */
|
|
while(__HAL_RCC_GET_FLAG(RCC_FLAG_LSIRDY) == RESET)
|
|
{
|
|
if((HAL_GetTick() - tickstart) > LSI_TIMEOUT_VALUE)
|
|
{
|
|
return HAL_TIMEOUT;
|
|
}
|
|
}
|
|
}
|
|
else
|
|
{
|
|
/* Disable the Internal Low Speed oscillator (LSI). */
|
|
__HAL_RCC_LSI_DISABLE();
|
|
|
|
/* Get timeout */
|
|
tickstart = HAL_GetTick();
|
|
|
|
/* Wait till LSI is ready */
|
|
while(__HAL_RCC_GET_FLAG(RCC_FLAG_LSIRDY) != RESET)
|
|
{
|
|
if((HAL_GetTick() - tickstart) > LSI_TIMEOUT_VALUE)
|
|
{
|
|
return HAL_TIMEOUT;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
/*------------------------------ LSE Configuration -------------------------*/
|
|
if(((RCC_OscInitStruct->OscillatorType) & RCC_OSCILLATORTYPE_LSE) == RCC_OSCILLATORTYPE_LSE)
|
|
{
|
|
/* Check the parameters */
|
|
assert_param(IS_RCC_LSE(RCC_OscInitStruct->LSEState));
|
|
|
|
/* Enable Power Clock */
|
|
__PWR_CLK_ENABLE();
|
|
|
|
/* Enable write access to Backup domain */
|
|
SET_BIT(PWR->CR, PWR_CR_DBP);
|
|
|
|
/* Wait for Backup domain Write protection disable */
|
|
tickstart = HAL_GetTick();
|
|
|
|
while((PWR->CR & PWR_CR_DBP) == RESET)
|
|
{
|
|
if((HAL_GetTick() - tickstart) > DBP_TIMEOUT_VALUE)
|
|
{
|
|
return HAL_TIMEOUT;
|
|
}
|
|
}
|
|
|
|
/* Reset LSEON and LSEBYP bits before configuring the LSE ----------------*/
|
|
__HAL_RCC_LSE_CONFIG(RCC_LSE_OFF);
|
|
|
|
/* Get timeout */
|
|
tickstart = HAL_GetTick();
|
|
|
|
/* Wait till LSE is ready */
|
|
while(__HAL_RCC_GET_FLAG(RCC_FLAG_LSERDY) != RESET)
|
|
{
|
|
if((HAL_GetTick() - tickstart) > LSE_TIMEOUT_VALUE)
|
|
{
|
|
return HAL_TIMEOUT;
|
|
}
|
|
}
|
|
|
|
/* Set the new LSE configuration -----------------------------------------*/
|
|
__HAL_RCC_LSE_CONFIG(RCC_OscInitStruct->LSEState);
|
|
/* Check the LSE State */
|
|
if(RCC_OscInitStruct->LSEState == RCC_LSE_ON)
|
|
{
|
|
/* Get timeout */
|
|
tickstart = HAL_GetTick();
|
|
|
|
/* Wait till LSE is ready */
|
|
while(__HAL_RCC_GET_FLAG(RCC_FLAG_LSERDY) == RESET)
|
|
{
|
|
if((HAL_GetTick() - tickstart) > LSE_TIMEOUT_VALUE)
|
|
{
|
|
return HAL_TIMEOUT;
|
|
}
|
|
}
|
|
}
|
|
else
|
|
{
|
|
/* Get timeout */
|
|
tickstart = HAL_GetTick();
|
|
|
|
/* Wait till LSE is ready */
|
|
while(__HAL_RCC_GET_FLAG(RCC_FLAG_LSERDY) != RESET)
|
|
{
|
|
if((HAL_GetTick() - tickstart) > LSE_TIMEOUT_VALUE)
|
|
{
|
|
return HAL_TIMEOUT;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
/*----------------------------- HSI14 Configuration --------------------------*/
|
|
if(((RCC_OscInitStruct->OscillatorType) & RCC_OSCILLATORTYPE_HSI14) == RCC_OSCILLATORTYPE_HSI14)
|
|
{
|
|
/* Check the parameters */
|
|
assert_param(IS_RCC_HSI14(RCC_OscInitStruct->HSI14State));
|
|
assert_param(IS_RCC_CALIBRATION_VALUE(RCC_OscInitStruct->HSI14CalibrationValue));
|
|
|
|
/* Check the HSI14 State */
|
|
if(RCC_OscInitStruct->HSI14State == RCC_HSI14_ON)
|
|
{
|
|
/* Disable ADC control of the Internal High Speed oscillator HSI14 */
|
|
__HAL_RCC_HSI14ADC_DISABLE();
|
|
|
|
/* Enable the Internal High Speed oscillator (HSI). */
|
|
__HAL_RCC_HSI14_ENABLE();
|
|
|
|
/* Get timeout */
|
|
tickstart = HAL_GetTick();
|
|
|
|
/* Wait till HSI is ready */
|
|
while(__HAL_RCC_GET_FLAG(RCC_FLAG_HSI14RDY) == RESET)
|
|
{
|
|
if((HAL_GetTick() - tickstart) > HSI14_TIMEOUT_VALUE)
|
|
{
|
|
return HAL_TIMEOUT;
|
|
}
|
|
}
|
|
|
|
/* Adjusts the Internal High Speed oscillator 14Mhz (HSI14) calibration value. */
|
|
__HAL_RCC_HSI14_CALIBRATIONVALUE_ADJUST(RCC_OscInitStruct->HSI14CalibrationValue);
|
|
}
|
|
else if(RCC_OscInitStruct->HSI14State == RCC_HSI14_ADC_CONTROL)
|
|
{
|
|
/* Enable ADC control of the Internal High Speed oscillator HSI14 */
|
|
__HAL_RCC_HSI14ADC_ENABLE();
|
|
|
|
/* Adjusts the Internal High Speed oscillator 14Mhz (HSI14) calibration value. */
|
|
__HAL_RCC_HSI14_CALIBRATIONVALUE_ADJUST(RCC_OscInitStruct->HSI14CalibrationValue);
|
|
}
|
|
else
|
|
{
|
|
/* Disable ADC control of the Internal High Speed oscillator HSI14 */
|
|
__HAL_RCC_HSI14ADC_DISABLE();
|
|
|
|
/* Disable the Internal High Speed oscillator (HSI). */
|
|
__HAL_RCC_HSI14_DISABLE();
|
|
|
|
/* Get timeout */
|
|
tickstart = HAL_GetTick();
|
|
|
|
/* Wait till HSI is ready */
|
|
while(__HAL_RCC_GET_FLAG(RCC_FLAG_HSI14RDY) != RESET)
|
|
{
|
|
if((HAL_GetTick() - tickstart) > HSI14_TIMEOUT_VALUE)
|
|
{
|
|
return HAL_TIMEOUT;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
#if defined(STM32F042x6) || defined(STM32F048xx) || defined(STM32F072xB) || defined(STM32F078xx) || \
|
|
defined(STM32F091xC) || defined(STM32F098xx)
|
|
/*----------------------------- HSI48 Configuration --------------------------*/
|
|
if(((RCC_OscInitStruct->OscillatorType) & RCC_OSCILLATORTYPE_HSI48) == RCC_OSCILLATORTYPE_HSI48)
|
|
{
|
|
/* Check the parameters */
|
|
assert_param(IS_RCC_HSI48(RCC_OscInitStruct->HSI48State));
|
|
|
|
/* When the HSI48 is used as system clock it is not allowed to be disabled */
|
|
if((__HAL_RCC_GET_SYSCLK_SOURCE() == RCC_SYSCLKSOURCE_STATUS_HSI48) ||
|
|
((__HAL_RCC_GET_SYSCLK_SOURCE() == RCC_SYSCLKSOURCE_STATUS_PLLCLK) && (__HAL_RCC_GET_PLL_OSCSOURCE() == RCC_PLLSOURCE_HSI48)))
|
|
{
|
|
if((__HAL_RCC_GET_FLAG(RCC_FLAG_HSI48RDY) != RESET) && (RCC_OscInitStruct->HSI48State != RCC_HSI48_ON))
|
|
{
|
|
return HAL_ERROR;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
/* Check the HSI State */
|
|
if(RCC_OscInitStruct->HSI48State != RCC_HSI48_OFF)
|
|
{
|
|
/* Enable the Internal High Speed oscillator (HSI48). */
|
|
__HAL_RCC_HSI48_ENABLE();
|
|
|
|
/* Get timeout */
|
|
tickstart = HAL_GetTick();
|
|
|
|
/* Wait till HSI is ready */
|
|
while(__HAL_RCC_GET_FLAG(RCC_FLAG_HSI48RDY) == RESET)
|
|
{
|
|
if((HAL_GetTick() - tickstart) > HSI48_TIMEOUT_VALUE)
|
|
{
|
|
return HAL_TIMEOUT;
|
|
}
|
|
}
|
|
}
|
|
else
|
|
{
|
|
/* Disable the Internal High Speed oscillator (HSI48). */
|
|
__HAL_RCC_HSI48_DISABLE();
|
|
|
|
/* Get timeout */
|
|
tickstart = HAL_GetTick();
|
|
|
|
/* Wait till HSI is ready */
|
|
while(__HAL_RCC_GET_FLAG(RCC_FLAG_HSI48RDY) != RESET)
|
|
{
|
|
if((HAL_GetTick() - tickstart) > HSI48_TIMEOUT_VALUE)
|
|
{
|
|
return HAL_TIMEOUT;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
#endif /* STM32F042x6 || STM32F048xx || STM32F072xB || STM32F078xx || */
|
|
/* STM32F091xC || STM32F098xx */
|
|
|
|
/*-------------------------------- PLL Configuration -----------------------*/
|
|
/* Check the parameters */
|
|
assert_param(IS_RCC_PLL(RCC_OscInitStruct->PLL.PLLState));
|
|
if ((RCC_OscInitStruct->PLL.PLLState) != RCC_PLL_NONE)
|
|
{
|
|
/* Check if the PLL is used as system clock or not */
|
|
if(__HAL_RCC_GET_SYSCLK_SOURCE() != RCC_SYSCLKSOURCE_STATUS_PLLCLK)
|
|
{
|
|
if((RCC_OscInitStruct->PLL.PLLState) == RCC_PLL_ON)
|
|
{
|
|
/* Check the parameters */
|
|
assert_param(IS_RCC_PLLSOURCE(RCC_OscInitStruct->PLL.PLLSource));
|
|
assert_param(IS_RCC_PREDIV(RCC_OscInitStruct->PLL.PREDIV));
|
|
assert_param(IS_RCC_PLL_MUL(RCC_OscInitStruct->PLL.PLLMUL));
|
|
|
|
/* Disable the main PLL. */
|
|
__HAL_RCC_PLL_DISABLE();
|
|
|
|
/* Get timeout */
|
|
tickstart = HAL_GetTick();
|
|
|
|
/* Wait till PLL is ready */
|
|
while(__HAL_RCC_GET_FLAG(RCC_FLAG_PLLRDY) != RESET)
|
|
{
|
|
if((HAL_GetTick() - tickstart) > PLL_TIMEOUT_VALUE)
|
|
{
|
|
return HAL_TIMEOUT;
|
|
}
|
|
}
|
|
|
|
/* Configure the main PLL clock source, predivider and multiplication factor. */
|
|
__HAL_RCC_PLL_CONFIG(RCC_OscInitStruct->PLL.PLLSource,
|
|
RCC_OscInitStruct->PLL.PREDIV,
|
|
RCC_OscInitStruct->PLL.PLLMUL);
|
|
|
|
/* Enable the main PLL. */
|
|
__HAL_RCC_PLL_ENABLE();
|
|
|
|
/* Get timeout */
|
|
tickstart = HAL_GetTick();
|
|
|
|
/* Wait till PLL is ready */
|
|
while(__HAL_RCC_GET_FLAG(RCC_FLAG_PLLRDY) == RESET)
|
|
{
|
|
if((HAL_GetTick() - tickstart) > PLL_TIMEOUT_VALUE)
|
|
{
|
|
return HAL_TIMEOUT;
|
|
}
|
|
}
|
|
}
|
|
else
|
|
{
|
|
/* Disable the main PLL. */
|
|
__HAL_RCC_PLL_DISABLE();
|
|
/* Get timeout */
|
|
tickstart = HAL_GetTick();
|
|
|
|
/* Wait till PLL is ready */
|
|
while(__HAL_RCC_GET_FLAG(RCC_FLAG_PLLRDY) != RESET)
|
|
{
|
|
if((HAL_GetTick() - tickstart) > PLL_TIMEOUT_VALUE)
|
|
{
|
|
return HAL_TIMEOUT;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
else
|
|
{
|
|
return HAL_ERROR;
|
|
}
|
|
}
|
|
return HAL_OK;
|
|
}
|
|
|
|
/**
|
|
* @brief Initializes the CPU, AHB and APB busses clocks according to the specified
|
|
* parameters in the RCC_ClkInitStruct.
|
|
* @param RCC_ClkInitStruct: pointer to an RCC_OscInitTypeDef structure that
|
|
* contains the configuration information for the RCC peripheral.
|
|
* @param FLatency: FLASH Latency
|
|
* This parameter can be one of the following values:
|
|
* @arg FLASH_LATENCY_0: FLASH 0 Latency cycle
|
|
* @arg FLASH_LATENCY_1: FLASH 1 Latency cycle
|
|
*
|
|
* @note The SystemCoreClock CMSIS variable is used to store System Clock Frequency
|
|
* and updated by HAL_RCC_GetHCLKFreq() function called within this function
|
|
*
|
|
* @note The HSI is used (enabled by hardware) as system clock source after
|
|
* startup from Reset, wake-up from STOP and STANDBY mode, or in case
|
|
* of failure of the HSE used directly or indirectly as system clock
|
|
* (if the Clock Security System CSS is enabled).
|
|
*
|
|
* @note A switch from one clock source to another occurs only if the target
|
|
* clock source is ready (clock stable after startup delay or PLL locked).
|
|
* If a clock source which is not yet ready is selected, the switch will
|
|
* occur when the clock source will be ready.
|
|
* @retval None
|
|
*/
|
|
HAL_StatusTypeDef HAL_RCC_ClockConfig(RCC_ClkInitTypeDef *RCC_ClkInitStruct, uint32_t FLatency)
|
|
{
|
|
uint32_t tickstart = 0;
|
|
|
|
/* Check the parameters */
|
|
assert_param(IS_RCC_CLOCKTYPE(RCC_ClkInitStruct->ClockType));
|
|
assert_param(IS_FLASH_LATENCY(FLatency));
|
|
|
|
/* To correctly read data from FLASH memory, the number of wait states (LATENCY)
|
|
must be correctly programmed according to the frequency of the CPU clock
|
|
(HCLK) of the device. */
|
|
|
|
/* Increasing the CPU frequency */
|
|
if(FLatency > (FLASH->ACR & FLASH_ACR_LATENCY))
|
|
{
|
|
/* Program the new number of wait states to the LATENCY bits in the FLASH_ACR register */
|
|
__HAL_FLASH_SET_LATENCY(FLatency);
|
|
|
|
/* Check that the new number of wait states is taken into account to access the Flash
|
|
memory by reading the FLASH_ACR register */
|
|
if((FLASH->ACR & FLASH_ACR_LATENCY) != FLatency)
|
|
{
|
|
return HAL_ERROR;
|
|
}
|
|
|
|
/*-------------------------- HCLK Configuration --------------------------*/
|
|
if(((RCC_ClkInitStruct->ClockType) & RCC_CLOCKTYPE_HCLK) == RCC_CLOCKTYPE_HCLK)
|
|
{
|
|
assert_param(IS_RCC_SYSCLK_DIV(RCC_ClkInitStruct->AHBCLKDivider));
|
|
MODIFY_REG(RCC->CFGR, RCC_CFGR_HPRE, RCC_ClkInitStruct->AHBCLKDivider);
|
|
}
|
|
|
|
/*------------------------- SYSCLK Configuration ---------------------------*/
|
|
if(((RCC_ClkInitStruct->ClockType) & RCC_CLOCKTYPE_SYSCLK) == RCC_CLOCKTYPE_SYSCLK)
|
|
{
|
|
assert_param(IS_RCC_SYSCLKSOURCE(RCC_ClkInitStruct->SYSCLKSource));
|
|
|
|
/* HSE is selected as System Clock Source */
|
|
if(RCC_ClkInitStruct->SYSCLKSource == RCC_SYSCLKSOURCE_HSE)
|
|
{
|
|
/* Check the HSE ready flag */
|
|
if(__HAL_RCC_GET_FLAG(RCC_FLAG_HSERDY) == RESET)
|
|
{
|
|
return HAL_ERROR;
|
|
}
|
|
}
|
|
/* PLL is selected as System Clock Source */
|
|
else if(RCC_ClkInitStruct->SYSCLKSource == RCC_SYSCLKSOURCE_PLLCLK)
|
|
{
|
|
/* Check the PLL ready flag */
|
|
if(__HAL_RCC_GET_FLAG(RCC_FLAG_PLLRDY) == RESET)
|
|
{
|
|
return HAL_ERROR;
|
|
}
|
|
}
|
|
#if defined(STM32F042x6) || defined(STM32F048xx) || defined(STM32F072xB) || defined(STM32F078xx) || \
|
|
defined(STM32F091xC) || defined(STM32F098xx)
|
|
/* HSI48 is selected as System Clock Source */
|
|
else if(RCC_ClkInitStruct->SYSCLKSource == RCC_SYSCLKSOURCE_HSI48)
|
|
{
|
|
/* Check the HSI48 ready flag */
|
|
if(__HAL_RCC_GET_FLAG(RCC_FLAG_HSI48RDY) == RESET)
|
|
{
|
|
return HAL_ERROR;
|
|
}
|
|
}
|
|
#endif /* STM32F042x6 || STM32F048xx || STM32F072xB || STM32F078xx || */
|
|
/* STM32F091xC || STM32F098xx */
|
|
/* HSI is selected as System Clock Source */
|
|
else
|
|
{
|
|
/* Check the HSI ready flag */
|
|
if(__HAL_RCC_GET_FLAG(RCC_FLAG_HSIRDY) == RESET)
|
|
{
|
|
return HAL_ERROR;
|
|
}
|
|
}
|
|
MODIFY_REG(RCC->CFGR, RCC_CFGR_SW, RCC_ClkInitStruct->SYSCLKSource);
|
|
|
|
/* Get timeout */
|
|
tickstart = HAL_GetTick();
|
|
|
|
if(RCC_ClkInitStruct->SYSCLKSource == RCC_SYSCLKSOURCE_HSE)
|
|
{
|
|
while (__HAL_RCC_GET_SYSCLK_SOURCE() != RCC_SYSCLKSOURCE_STATUS_HSE)
|
|
{
|
|
if((HAL_GetTick() - tickstart) > CLOCKSWITCH_TIMEOUT_VALUE)
|
|
{
|
|
return HAL_TIMEOUT;
|
|
}
|
|
}
|
|
}
|
|
else if(RCC_ClkInitStruct->SYSCLKSource == RCC_SYSCLKSOURCE_PLLCLK)
|
|
{
|
|
while (__HAL_RCC_GET_SYSCLK_SOURCE() != RCC_SYSCLKSOURCE_STATUS_PLLCLK)
|
|
{
|
|
if((HAL_GetTick() - tickstart) > CLOCKSWITCH_TIMEOUT_VALUE)
|
|
{
|
|
return HAL_TIMEOUT;
|
|
}
|
|
}
|
|
}
|
|
#if defined(STM32F042x6) || defined(STM32F048xx) || defined(STM32F072xB) || defined(STM32F078xx) || \
|
|
defined(STM32F091xC) || defined(STM32F098xx)
|
|
else if(RCC_ClkInitStruct->SYSCLKSource == RCC_SYSCLKSOURCE_HSI48)
|
|
{
|
|
while (__HAL_RCC_GET_SYSCLK_SOURCE() != RCC_SYSCLKSOURCE_STATUS_HSI48)
|
|
{
|
|
if((HAL_GetTick() - tickstart) > CLOCKSWITCH_TIMEOUT_VALUE)
|
|
{
|
|
return HAL_TIMEOUT;
|
|
}
|
|
}
|
|
}
|
|
#endif /* STM32F042x6 || STM32F048xx || STM32F072xB || STM32F078xx || */
|
|
/* STM32F091xC || STM32F098xx */
|
|
else
|
|
{
|
|
while(__HAL_RCC_GET_SYSCLK_SOURCE() != RCC_SYSCLKSOURCE_STATUS_HSI)
|
|
{
|
|
if((HAL_GetTick() - tickstart) > CLOCKSWITCH_TIMEOUT_VALUE)
|
|
{
|
|
return HAL_TIMEOUT;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
/* Decreasing the CPU frequency */
|
|
else
|
|
{
|
|
/*-------------------------- HCLK Configuration --------------------------*/
|
|
if(((RCC_ClkInitStruct->ClockType) & RCC_CLOCKTYPE_HCLK) == RCC_CLOCKTYPE_HCLK)
|
|
{
|
|
assert_param(IS_RCC_SYSCLK_DIV(RCC_ClkInitStruct->AHBCLKDivider));
|
|
MODIFY_REG(RCC->CFGR, RCC_CFGR_HPRE, RCC_ClkInitStruct->AHBCLKDivider);
|
|
}
|
|
|
|
/*------------------------- SYSCLK Configuration ---------------------------*/
|
|
if(((RCC_ClkInitStruct->ClockType) & RCC_CLOCKTYPE_SYSCLK) == RCC_CLOCKTYPE_SYSCLK)
|
|
{
|
|
assert_param(IS_RCC_SYSCLKSOURCE(RCC_ClkInitStruct->SYSCLKSource));
|
|
|
|
/* HSE is selected as System Clock Source */
|
|
if(RCC_ClkInitStruct->SYSCLKSource == RCC_SYSCLKSOURCE_HSE)
|
|
{
|
|
/* Check the HSE ready flag */
|
|
if(__HAL_RCC_GET_FLAG(RCC_FLAG_HSERDY) == RESET)
|
|
{
|
|
return HAL_ERROR;
|
|
}
|
|
}
|
|
/* PLL is selected as System Clock Source */
|
|
else if(RCC_ClkInitStruct->SYSCLKSource == RCC_SYSCLKSOURCE_PLLCLK)
|
|
{
|
|
/* Check the PLL ready flag */
|
|
if(__HAL_RCC_GET_FLAG(RCC_FLAG_PLLRDY) == RESET)
|
|
{
|
|
return HAL_ERROR;
|
|
}
|
|
}
|
|
#if defined(STM32F042x6) || defined(STM32F048xx) || defined(STM32F072xB) || defined(STM32F078xx) || \
|
|
defined(STM32F091xC) || defined(STM32F098xx)
|
|
/* HSI48 is selected as System Clock Source */
|
|
else if(RCC_ClkInitStruct->SYSCLKSource == RCC_SYSCLKSOURCE_HSI48)
|
|
{
|
|
/* Check the HSI48 ready flag */
|
|
if(__HAL_RCC_GET_FLAG(RCC_FLAG_HSI48RDY) == RESET)
|
|
{
|
|
return HAL_ERROR;
|
|
}
|
|
}
|
|
#endif /* STM32F042x6 || STM32F048xx || STM32F072xB || STM32F078xx || */
|
|
/* STM32F091xC || STM32F098xx */
|
|
/* HSI is selected as System Clock Source */
|
|
else
|
|
{
|
|
/* Check the HSI ready flag */
|
|
if(__HAL_RCC_GET_FLAG(RCC_FLAG_HSIRDY) == RESET)
|
|
{
|
|
return HAL_ERROR;
|
|
}
|
|
}
|
|
MODIFY_REG(RCC->CFGR, RCC_CFGR_SW, RCC_ClkInitStruct->SYSCLKSource);
|
|
|
|
/* Get timeout */
|
|
tickstart = HAL_GetTick();
|
|
|
|
if(RCC_ClkInitStruct->SYSCLKSource == RCC_SYSCLKSOURCE_HSE)
|
|
{
|
|
while (__HAL_RCC_GET_SYSCLK_SOURCE() != RCC_SYSCLKSOURCE_STATUS_HSE)
|
|
{
|
|
if((HAL_GetTick() - tickstart) > CLOCKSWITCH_TIMEOUT_VALUE)
|
|
{
|
|
return HAL_TIMEOUT;
|
|
}
|
|
}
|
|
}
|
|
else if(RCC_ClkInitStruct->SYSCLKSource == RCC_SYSCLKSOURCE_PLLCLK)
|
|
{
|
|
while (__HAL_RCC_GET_SYSCLK_SOURCE() != RCC_SYSCLKSOURCE_STATUS_PLLCLK)
|
|
{
|
|
if((HAL_GetTick() - tickstart) > CLOCKSWITCH_TIMEOUT_VALUE)
|
|
{
|
|
return HAL_TIMEOUT;
|
|
}
|
|
}
|
|
}
|
|
#if defined(STM32F042x6) || defined(STM32F048xx) || defined(STM32F072xB) || defined(STM32F078xx) || \
|
|
defined(STM32F091xC) || defined(STM32F098xx)
|
|
else if(RCC_ClkInitStruct->SYSCLKSource == RCC_SYSCLKSOURCE_HSI48)
|
|
{
|
|
while (__HAL_RCC_GET_SYSCLK_SOURCE() != RCC_SYSCLKSOURCE_STATUS_HSI48)
|
|
{
|
|
if((HAL_GetTick() - tickstart) > CLOCKSWITCH_TIMEOUT_VALUE)
|
|
{
|
|
return HAL_TIMEOUT;
|
|
}
|
|
}
|
|
}
|
|
#endif /* STM32F042x6 || STM32F048xx || STM32F072xB || STM32F078xx || */
|
|
/* STM32F091xC || STM32F098xx */
|
|
else
|
|
{
|
|
while(__HAL_RCC_GET_SYSCLK_SOURCE() != RCC_SYSCLKSOURCE_STATUS_HSI)
|
|
{
|
|
if((HAL_GetTick() - tickstart) > CLOCKSWITCH_TIMEOUT_VALUE)
|
|
{
|
|
return HAL_TIMEOUT;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
/* Program the new number of wait states to the LATENCY bits in the FLASH_ACR register */
|
|
__HAL_FLASH_SET_LATENCY(FLatency);
|
|
|
|
/* Check that the new number of wait states is taken into account to access the Flash
|
|
memory by reading the FLASH_ACR register */
|
|
if((FLASH->ACR & FLASH_ACR_LATENCY) != FLatency)
|
|
{
|
|
return HAL_ERROR;
|
|
}
|
|
}
|
|
|
|
/*-------------------------- PCLK1 Configuration ---------------------------*/
|
|
if(((RCC_ClkInitStruct->ClockType) & RCC_CLOCKTYPE_PCLK1) == RCC_CLOCKTYPE_PCLK1)
|
|
{
|
|
assert_param(IS_RCC_HCLK_DIV(RCC_ClkInitStruct->APB1CLKDivider));
|
|
MODIFY_REG(RCC->CFGR, RCC_CFGR_PPRE, RCC_ClkInitStruct->APB1CLKDivider);
|
|
}
|
|
|
|
/* Configure the source of time base considering new system clocks settings*/
|
|
HAL_InitTick (TICK_INT_PRIORITY);
|
|
|
|
return HAL_OK;
|
|
}
|
|
|
|
/**
|
|
* @brief Returns the SYSCLK frequency
|
|
* @note The system frequency computed by this function is not the real
|
|
* frequency in the chip. It is calculated based on the predefined
|
|
* constant and the selected clock source:
|
|
* @note If SYSCLK source is HSI, function returns a value based on HSI_VALUE(*)
|
|
* @note If SYSCLK source is HSI48, function returns a value based on HSI48_VALUE(*)
|
|
* @note If SYSCLK source is HSE, function returns a value based on HSE_VALUE
|
|
* divided by PREDIV factor(**)
|
|
* @note If SYSCLK source is PLL, function returns a value based on HSE_VALUE
|
|
* divided by PREDIV factor(**) or depending on STM32F0xx devices either a value based
|
|
* on HSI_VALUE divided by 2 or HSI_VALUE divided by PREDIV factor(*) multiplied by the
|
|
* PLL factor .
|
|
* @note (*) HSI_VALUE & HSI48_VALUE are constants defined in stm32f0xx_hal_conf.h file
|
|
* (default values 8 MHz and 48MHz).
|
|
* @note (**) HSE_VALUE is a constant defined in stm32f0xx_hal_conf.h file (default value
|
|
* 8 MHz), user has to ensure that HSE_VALUE is same as the real
|
|
* frequency of the crystal used. Otherwise, this function may
|
|
* have wrong result.
|
|
*
|
|
* @note The result of this function could be not correct when using fractional
|
|
* value for HSE crystal.
|
|
*
|
|
* @note This function can be used by the user application to compute the
|
|
* baudrate for the communication peripherals or configure other parameters.
|
|
*
|
|
* @note Each time SYSCLK changes, this function must be called to update the
|
|
* right SYSCLK value. Otherwise, any configuration based on this function will be incorrect.
|
|
*
|
|
* @retval SYSCLK frequency
|
|
*/
|
|
uint32_t HAL_RCC_GetSysClockFreq(void)
|
|
{
|
|
uint32_t tmpreg = 0, prediv = 0, pllmul = 0, pllclk = 0;
|
|
uint32_t sysclockfreq = 0;
|
|
|
|
tmpreg = RCC->CFGR;
|
|
|
|
/* Get SYSCLK source -------------------------------------------------------*/
|
|
switch (tmpreg & RCC_CFGR_SWS)
|
|
{
|
|
case RCC_SYSCLKSOURCE_STATUS_HSE: /* HSE used as system clock source */
|
|
sysclockfreq = HSE_VALUE;
|
|
break;
|
|
|
|
case RCC_SYSCLKSOURCE_STATUS_PLLCLK: /* PLL used as system clock source */
|
|
pllmul = PLLMULFactorTable[(uint32_t)(tmpreg & RCC_CFGR_PLLMUL) >> RCC_CFGR_PLLMUL_BITNUMBER];
|
|
prediv = PredivFactorTable[(uint32_t)(RCC->CFGR2 & RCC_CFGR2_PREDIV) >> RCC_CFGR2_PREDIV_BITNUMBER];
|
|
if ((tmpreg & RCC_CFGR_PLLSRC) == RCC_PLLSOURCE_HSE)
|
|
{
|
|
/* HSE used as PLL clock source : PLLCLK = HSE/PREDIV * PLLMUL */
|
|
pllclk = (HSE_VALUE/prediv) * pllmul;
|
|
}
|
|
#if defined(STM32F042x6) || defined(STM32F048xx) || defined(STM32F072xB) || defined(STM32F078xx) || \
|
|
defined(STM32F091xC) || defined(STM32F098xx)
|
|
else if ((tmpreg & RCC_CFGR_PLLSRC) == RCC_PLLSOURCE_HSI48)
|
|
{
|
|
/* HSI48 used as PLL clock source : PLLCLK = HSI48/PREDIV * PLLMUL */
|
|
pllclk = (HSI48_VALUE/prediv) * pllmul;
|
|
}
|
|
#endif /* STM32F042x6 || STM32F048xx || STM32F072xB || STM32F078xx || */
|
|
/* STM32F091xC || STM32F098xx */
|
|
else
|
|
{
|
|
#if defined(STM32F042x6) || defined(STM32F048xx) || \
|
|
defined(STM32F071xB) || defined(STM32F072xB) || defined(STM32F078xx) || \
|
|
defined(STM32F091xC) || defined(STM32F098xx)
|
|
/* HSI used as PLL clock source : PLLCLK = HSI/PREDIV * PLLMUL */
|
|
pllclk = (HSI_VALUE/prediv) * pllmul;
|
|
#else
|
|
/* HSI used as PLL clock source : PLLCLK = HSI/2 * PLLMUL */
|
|
pllclk = (HSI_VALUE >> 1) * pllmul;
|
|
#endif /* STM32F042x6 || STM32F048xx || STM32F071xB || STM32F072xB || STM32F078xx || */
|
|
/* STM32F091xC || STM32F098xx */
|
|
}
|
|
sysclockfreq = pllclk;
|
|
break;
|
|
|
|
#if defined(STM32F042x6) || defined(STM32F048xx) || defined(STM32F072xB) || defined(STM32F078xx) || \
|
|
defined(STM32F091xC) || defined(STM32F098xx)
|
|
case RCC_SYSCLKSOURCE_STATUS_HSI48: /* HSI48 used as system clock source */
|
|
sysclockfreq = HSI48_VALUE;
|
|
break;
|
|
#endif /* STM32F042x6 || STM32F048xx || STM32F072xB || STM32F078xx || */
|
|
/* STM32F091xC || STM32F098xx */
|
|
|
|
case RCC_SYSCLKSOURCE_STATUS_HSI: /* HSI used as system clock source */
|
|
default:
|
|
sysclockfreq = HSI_VALUE;
|
|
break;
|
|
}
|
|
return sysclockfreq;
|
|
}
|
|
|
|
/**
|
|
* @brief Initializes the RCC extended peripherals clocks according to the specified
|
|
* parameters in the RCC_PeriphCLKInitTypeDef.
|
|
* @param PeriphClkInit: pointer to an RCC_PeriphCLKInitTypeDef structure that
|
|
* contains the configuration information for the Extended Peripherals clocks
|
|
* (USART, RTC, I2C, CEC and USB).
|
|
*
|
|
* @note Care must be taken when HAL_RCCEx_PeriphCLKConfig() is used to select
|
|
* the RTC clock source; in this case the Backup domain will be reset in
|
|
* order to modify the RTC Clock source, as consequence RTC registers (including
|
|
* the backup registers) and RCC_BDCR register are set to their reset values.
|
|
*
|
|
* @retval None
|
|
*/
|
|
HAL_StatusTypeDef HAL_RCCEx_PeriphCLKConfig(RCC_PeriphCLKInitTypeDef *PeriphClkInit)
|
|
{
|
|
uint32_t tickstart = 0;
|
|
uint32_t tmpreg = 0;
|
|
|
|
/* Check the parameters */
|
|
assert_param(IS_RCC_PERIPHCLK(PeriphClkInit->PeriphClockSelection));
|
|
|
|
/*---------------------------- RTC configuration -------------------------------*/
|
|
if(((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_RTC) == (RCC_PERIPHCLK_RTC))
|
|
{
|
|
/* Enable Power Clock*/
|
|
__PWR_CLK_ENABLE();
|
|
|
|
/* Enable write access to Backup domain */
|
|
SET_BIT(PWR->CR, PWR_CR_DBP);
|
|
|
|
/* Wait for Backup domain Write protection disable */
|
|
tickstart = HAL_GetTick();
|
|
|
|
while((PWR->CR & PWR_CR_DBP) == RESET)
|
|
{
|
|
if((HAL_GetTick() - tickstart) > DBP_TIMEOUT_VALUE)
|
|
{
|
|
return HAL_TIMEOUT;
|
|
}
|
|
}
|
|
|
|
/* Reset the Backup domain only if the RTC Clock source selction is modified */
|
|
if((RCC->BDCR & RCC_BDCR_RTCSEL) != (PeriphClkInit->RTCClockSelection & RCC_BDCR_RTCSEL))
|
|
{
|
|
/* Store the content of BDCR register before the reset of Backup Domain */
|
|
tmpreg = (RCC->BDCR & ~(RCC_BDCR_RTCSEL));
|
|
/* RTC Clock selection can be changed only if the Backup Domain is reset */
|
|
__HAL_RCC_BACKUPRESET_FORCE();
|
|
__HAL_RCC_BACKUPRESET_RELEASE();
|
|
/* Restore the Content of BDCR register */
|
|
RCC->BDCR = tmpreg;
|
|
}
|
|
|
|
/* If LSE is selected as RTC clock source, wait for LSE reactivation */
|
|
if(PeriphClkInit->RTCClockSelection == RCC_RTCCLKSOURCE_LSE)
|
|
{
|
|
/* Get timeout */
|
|
tickstart = HAL_GetTick();
|
|
|
|
/* Wait till LSE is ready */
|
|
while(__HAL_RCC_GET_FLAG(RCC_FLAG_LSERDY) == RESET)
|
|
{
|
|
if((HAL_GetTick() - tickstart) > LSE_TIMEOUT_VALUE)
|
|
{
|
|
return HAL_TIMEOUT;
|
|
}
|
|
}
|
|
}
|
|
__HAL_RCC_RTC_CONFIG(PeriphClkInit->RTCClockSelection);
|
|
}
|
|
|
|
/*------------------------------- USART1 Configuration ------------------------*/
|
|
if(((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_USART1) == RCC_PERIPHCLK_USART1)
|
|
{
|
|
/* Check the parameters */
|
|
assert_param(IS_RCC_USART1CLKSOURCE(PeriphClkInit->Usart1ClockSelection));
|
|
|
|
/* Configure the USART1 clock source */
|
|
__HAL_RCC_USART1_CONFIG(PeriphClkInit->Usart1ClockSelection);
|
|
}
|
|
|
|
#if defined(STM32F071xB) || defined(STM32F072xB) || defined(STM32F078xx) || \
|
|
defined(STM32F091xC) || defined(STM32F098xx)
|
|
/*----------------------------- USART2 Configuration --------------------------*/
|
|
if(((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_USART2) == RCC_PERIPHCLK_USART2)
|
|
{
|
|
/* Check the parameters */
|
|
assert_param(IS_RCC_USART2CLKSOURCE(PeriphClkInit->Usart2ClockSelection));
|
|
|
|
/* Configure the USART2 clock source */
|
|
__HAL_RCC_USART2_CONFIG(PeriphClkInit->Usart2ClockSelection);
|
|
}
|
|
#endif /* STM32F071xB || STM32F072xB || STM32F078xx || */
|
|
/* STM32F091xC || STM32F098xx */
|
|
|
|
#if defined(STM32F091xC) || defined(STM32F098xx)
|
|
/*----------------------------- USART3 Configuration --------------------------*/
|
|
if(((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_USART3) == RCC_PERIPHCLK_USART3)
|
|
{
|
|
/* Check the parameters */
|
|
assert_param(IS_RCC_USART3CLKSOURCE(PeriphClkInit->Usart3ClockSelection));
|
|
|
|
/* Configure the USART3 clock source */
|
|
__HAL_RCC_USART3_CONFIG(PeriphClkInit->Usart3ClockSelection);
|
|
}
|
|
#endif /* STM32F091xC || STM32F098xx */
|
|
|
|
/*------------------------------ I2C1 Configuration ------------------------*/
|
|
if(((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_I2C1) == RCC_PERIPHCLK_I2C1)
|
|
{
|
|
/* Check the parameters */
|
|
assert_param(IS_RCC_I2C1CLKSOURCE(PeriphClkInit->I2c1ClockSelection));
|
|
|
|
/* Configure the I2C1 clock source */
|
|
__HAL_RCC_I2C1_CONFIG(PeriphClkInit->I2c1ClockSelection);
|
|
}
|
|
|
|
#if defined(STM32F042x6) || defined(STM32F048xx) || defined(STM32F072xB) || defined(STM32F078xx)
|
|
/*------------------------------ USB Configuration ------------------------*/
|
|
if(((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_USB) == RCC_PERIPHCLK_USB)
|
|
{
|
|
/* Check the parameters */
|
|
assert_param(IS_RCC_USBCLKSOURCE(PeriphClkInit->UsbClockSelection));
|
|
|
|
/* Configure the USB clock source */
|
|
__HAL_RCC_USB_CONFIG(PeriphClkInit->UsbClockSelection);
|
|
}
|
|
#endif /* STM32F042x6 || STM32F048xx || STM32F072xB || STM32F078xx */
|
|
|
|
#if defined(STM32F042x6) || defined(STM32F048xx) || \
|
|
defined(STM32F051x8) || defined(STM32F058xx) || \
|
|
defined(STM32F071xB) || defined(STM32F072xB) || defined(STM32F078xx) || \
|
|
defined(STM32F091xC) || defined(STM32F098xx)
|
|
/*------------------------------ CEC clock Configuration -------------------*/
|
|
if(((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_CEC) == RCC_PERIPHCLK_CEC)
|
|
{
|
|
/* Check the parameters */
|
|
assert_param(IS_RCC_CECCLKSOURCE(PeriphClkInit->CecClockSelection));
|
|
|
|
/* Configure the CEC clock source */
|
|
__HAL_RCC_CEC_CONFIG(PeriphClkInit->CecClockSelection);
|
|
}
|
|
#endif /* STM32F042x6 || STM32F048xx || */
|
|
/* STM32F051x8 || STM32F058xx || */
|
|
/* STM32F071xB || STM32F072xB || STM32F078xx || */
|
|
/* STM32F091xC || STM32F098xx */
|
|
|
|
return HAL_OK;
|
|
}
|
|
|
|
/**
|
|
* @brief Get the RCC_ClkInitStruct according to the internal
|
|
* RCC configuration registers.
|
|
* @param PeriphClkInit: pointer to an RCC_PeriphCLKInitTypeDef structure that
|
|
* returns the configuration information for the Extended Peripherals clocks
|
|
* (USART, RTC, I2C, CEC and USB).
|
|
* @retval None
|
|
*/
|
|
void HAL_RCCEx_GetPeriphCLKConfig(RCC_PeriphCLKInitTypeDef *PeriphClkInit)
|
|
{
|
|
/* Set all possible values for the extended clock type parameter------------*/
|
|
/* Common part first */
|
|
PeriphClkInit->PeriphClockSelection = RCC_PERIPHCLK_USART1 | RCC_PERIPHCLK_I2C1 | RCC_PERIPHCLK_RTC;
|
|
/* Get the RTC configuration --------------------------------------------*/
|
|
PeriphClkInit->RTCClockSelection = __HAL_RCC_GET_RTC_SOURCE();
|
|
/* Get the USART1 configuration --------------------------------------------*/
|
|
PeriphClkInit->Usart1ClockSelection = __HAL_RCC_GET_USART1_SOURCE();
|
|
/* Get the I2C1 clock source -----------------------------------------------*/
|
|
PeriphClkInit->I2c1ClockSelection = __HAL_RCC_GET_I2C1_SOURCE();
|
|
|
|
#if defined(STM32F071xB) || defined(STM32F072xB) || defined(STM32F078xx) || \
|
|
defined(STM32F091xC) || defined(STM32F098xx)
|
|
PeriphClkInit->PeriphClockSelection |= RCC_PERIPHCLK_USART2;
|
|
/* Get the USART2 clock source ---------------------------------------------*/
|
|
PeriphClkInit->Usart2ClockSelection = __HAL_RCC_GET_USART2_SOURCE();
|
|
#endif /* STM32F071xB || STM32F072xB || STM32F078xx || */
|
|
/* STM32F091xC || STM32F098xx */
|
|
|
|
#if defined(STM32F091xC) || defined(STM32F098xx)
|
|
PeriphClkInit->PeriphClockSelection |= RCC_PERIPHCLK_USART3;
|
|
/* Get the USART3 clock source ---------------------------------------------*/
|
|
PeriphClkInit->Usart3ClockSelection = __HAL_RCC_GET_USART3_SOURCE();
|
|
#endif /* STM32F091xC || STM32F098xx */
|
|
|
|
#if defined(STM32F042x6) || defined(STM32F048xx) || defined(STM32F072xB) || defined(STM32F078xx)
|
|
PeriphClkInit->PeriphClockSelection |= RCC_PERIPHCLK_USB;
|
|
/* Get the USB clock source ---------------------------------------------*/
|
|
PeriphClkInit->UsbClockSelection = __HAL_RCC_GET_USB_SOURCE();
|
|
#endif /* STM32F042x6 || STM32F048xx || STM32F072xB || STM32F078xx */
|
|
|
|
#if defined(STM32F042x6) || defined(STM32F048xx) || \
|
|
defined(STM32F051x8) || defined(STM32F058xx) || \
|
|
defined(STM32F071xB) || defined(STM32F072xB) || defined(STM32F078xx) || \
|
|
defined(STM32F091xC) || defined(STM32F098xx)
|
|
PeriphClkInit->PeriphClockSelection |= RCC_PERIPHCLK_CEC;
|
|
/* Get the CEC clock source ------------------------------------------------*/
|
|
PeriphClkInit->CecClockSelection = __HAL_RCC_GET_CEC_SOURCE();
|
|
#endif /* STM32F042x6 || STM32F048xx || */
|
|
/* STM32F051x8 || STM32F058xx || */
|
|
/* STM32F071xB || STM32F072xB || STM32F078xx || */
|
|
/* STM32F091xC || STM32F098xx */
|
|
|
|
}
|
|
|
|
#if defined(STM32F042x6) || defined(STM32F048xx) || \
|
|
defined(STM32F071xB) || defined(STM32F072xB) || defined(STM32F078xx) || \
|
|
defined(STM32F091xC) || defined(STM32F098xx)
|
|
/**
|
|
* @brief Start automatic synchronization using polling mode
|
|
* @param pInit Pointer on RCC_CRSInitTypeDef structure
|
|
* @retval None
|
|
*/
|
|
void HAL_RCCEx_CRSConfig(RCC_CRSInitTypeDef *pInit)
|
|
{
|
|
/* Check the parameters */
|
|
assert_param(IS_RCC_CRS_SYNC_DIV(pInit->Prescaler));
|
|
assert_param(IS_RCC_CRS_SYNC_SOURCE(pInit->Source));
|
|
assert_param(IS_RCC_CRS_SYNC_POLARITY(pInit->Polarity));
|
|
assert_param(IS_RCC_CRS_RELOADVALUE(pInit->ReloadValue));
|
|
assert_param(IS_RCC_CRS_ERRORLIMIT(pInit->ErrorLimitValue));
|
|
assert_param(IS_RCC_CRS_HSI48CALIBRATION(pInit->HSI48CalibrationValue));
|
|
|
|
|
|
/* CONFIGURATION */
|
|
|
|
/* Before configuration, reset CRS registers to their default values*/
|
|
__CRS_FORCE_RESET();
|
|
__CRS_RELEASE_RESET();
|
|
|
|
/* Configure Synchronization input */
|
|
/* Clear SYNCDIV[2:0], SYNCSRC[1:0] & SYNCSPOL bits */
|
|
CRS->CFGR &= ~(CRS_CFGR_SYNCDIV | CRS_CFGR_SYNCSRC | CRS_CFGR_SYNCPOL);
|
|
|
|
/* Set the CRS_CFGR_SYNCDIV[2:0] bits according to Prescaler value */
|
|
CRS->CFGR |= pInit->Prescaler;
|
|
|
|
/* Set the SYNCSRC[1:0] bits according to Source value */
|
|
CRS->CFGR |= pInit->Source;
|
|
|
|
/* Set the SYNCSPOL bits according to Polarity value */
|
|
CRS->CFGR |= pInit->Polarity;
|
|
|
|
/* Configure Frequency Error Measurement */
|
|
/* Clear RELOAD[15:0] & FELIM[7:0] bits*/
|
|
CRS->CFGR &= ~(CRS_CFGR_RELOAD | CRS_CFGR_FELIM);
|
|
|
|
/* Set the RELOAD[15:0] bits according to ReloadValue value */
|
|
CRS->CFGR |= pInit->ReloadValue;
|
|
|
|
/* Set the FELIM[7:0] bits according to ErrorLimitValue value */
|
|
CRS->CFGR |= (pInit->ErrorLimitValue << CRS_CFGR_FELIM_BITNUMBER);
|
|
|
|
/* Adjust HSI48 oscillator smooth trimming */
|
|
/* Clear TRIM[5:0] bits */
|
|
CRS->CR &= ~CRS_CR_TRIM;
|
|
|
|
/* Set the TRIM[5:0] bits according to RCC_CRS_HSI48CalibrationValue value */
|
|
CRS->CR |= (pInit->HSI48CalibrationValue << CRS_CR_TRIM_BITNUMBER);
|
|
|
|
|
|
/* START AUTOMATIC SYNCHRONIZATION*/
|
|
|
|
/* Enable Automatic trimming */
|
|
__HAL_RCC_CRS_ENABLE_AUTOMATIC_CALIB();
|
|
|
|
/* Enable Frequency error counter */
|
|
__HAL_RCC_CRS_ENABLE_FREQ_ERROR_COUNTER();
|
|
|
|
}
|
|
|
|
/**
|
|
* @brief Generate the software synchronization event
|
|
* @retval None
|
|
*/
|
|
void HAL_RCCEx_CRSSoftwareSynchronizationGenerate(void)
|
|
{
|
|
CRS->CR |= CRS_CR_SWSYNC;
|
|
}
|
|
|
|
|
|
/**
|
|
* @brief Function to return synchronization info
|
|
* @param pSynchroInfo Pointer on RCC_CRSSynchroInfoTypeDef structure
|
|
* @retval None
|
|
*/
|
|
void HAL_RCCEx_CRSGetSynchronizationInfo(RCC_CRSSynchroInfoTypeDef *pSynchroInfo)
|
|
{
|
|
/* Check the parameter */
|
|
assert_param(pSynchroInfo != NULL);
|
|
|
|
/* Get the reload value */
|
|
pSynchroInfo->ReloadValue = (uint32_t)(CRS->CFGR & CRS_CFGR_RELOAD);
|
|
|
|
/* Get HSI48 oscillator smooth trimming */
|
|
pSynchroInfo->HSI48CalibrationValue = (uint32_t)((CRS->CR & CRS_CR_TRIM) >> CRS_CR_TRIM_BITNUMBER);
|
|
|
|
/* Get Frequency error capture */
|
|
pSynchroInfo->FreqErrorCapture = (uint32_t)((CRS->ISR & CRS_ISR_FECAP) >> CRS_ISR_FECAP_BITNUMBER);
|
|
|
|
/* Get FFrequency error direction */
|
|
pSynchroInfo->FreqErrorDirection = (uint32_t)(CRS->ISR & CRS_ISR_FEDIR);
|
|
|
|
|
|
}
|
|
|
|
/**
|
|
* @brief This function handles CRS Synchronization Timeout.
|
|
* @param Timeout: Duration of the timeout
|
|
* @note Timeout is based on the maximum time to receive a SYNC event based on synchronization
|
|
* frequency.
|
|
* @note If Timeout set to HAL_MAX_DELAY, HAL_TIMEOUT will be never returned.
|
|
* @retval Combination of Synchronization status
|
|
* This parameter can be a combination of the following values:
|
|
* @arg RCC_CRS_TIMEOUT
|
|
* @arg RCC_CRS_SYNCOK
|
|
* @arg RCC_CRS_SYNCWARM
|
|
* @arg RCC_CRS_SYNCERR
|
|
* @arg RCC_CRS_SYNCMISS
|
|
* @arg RCC_CRS_TRIMOV
|
|
*/
|
|
RCC_CRSStatusTypeDef HAL_RCCEx_CRSWaitSynchronization(uint32_t Timeout)
|
|
{
|
|
RCC_CRSStatusTypeDef crsstatus = RCC_CRS_NONE;
|
|
uint32_t tickstart = 0;
|
|
|
|
/* Get timeout */
|
|
tickstart = HAL_GetTick();
|
|
|
|
/* Check that if one of CRS flags have been set */
|
|
while(RCC_CRS_NONE == crsstatus)
|
|
{
|
|
if(Timeout != HAL_MAX_DELAY)
|
|
{
|
|
if((Timeout == 0) || ((HAL_GetTick() - tickstart) > Timeout))
|
|
{
|
|
crsstatus = RCC_CRS_TIMEOUT;
|
|
}
|
|
}
|
|
/* Check CRS SYNCOK flag */
|
|
if(__HAL_RCC_CRS_GET_FLAG(RCC_CRS_FLAG_SYNCOK))
|
|
{
|
|
/* CRS SYNC event OK */
|
|
crsstatus |= RCC_CRS_SYNCOK;
|
|
|
|
/* Clear CRS SYNC event OK bit */
|
|
__HAL_RCC_CRS_CLEAR_FLAG(RCC_CRS_FLAG_SYNCOK);
|
|
}
|
|
|
|
/* Check CRS SYNCWARN flag */
|
|
if(__HAL_RCC_CRS_GET_FLAG(RCC_CRS_FLAG_SYNCWARN))
|
|
{
|
|
/* CRS SYNC warning */
|
|
crsstatus |= RCC_CRS_SYNCWARM;
|
|
|
|
/* Clear CRS SYNCWARN bit */
|
|
__HAL_RCC_CRS_CLEAR_FLAG(RCC_CRS_FLAG_SYNCWARN);
|
|
}
|
|
|
|
/* Check CRS TRIM overflow flag */
|
|
if(__HAL_RCC_CRS_GET_FLAG(RCC_CRS_FLAG_TRIMOVF))
|
|
{
|
|
/* CRS SYNC Error */
|
|
crsstatus |= RCC_CRS_TRIMOV;
|
|
|
|
/* Clear CRS Error bit */
|
|
__HAL_RCC_CRS_CLEAR_FLAG(RCC_CRS_FLAG_TRIMOVF);
|
|
}
|
|
|
|
/* Check CRS Error flag */
|
|
if(__HAL_RCC_CRS_GET_FLAG(RCC_CRS_FLAG_SYNCERR))
|
|
{
|
|
/* CRS SYNC Error */
|
|
crsstatus |= RCC_CRS_SYNCERR;
|
|
|
|
/* Clear CRS Error bit */
|
|
__HAL_RCC_CRS_CLEAR_FLAG(RCC_CRS_FLAG_SYNCERR);
|
|
}
|
|
|
|
/* Check CRS SYNC Missed flag */
|
|
if(__HAL_RCC_CRS_GET_FLAG(RCC_CRS_FLAG_SYNCMISS))
|
|
{
|
|
/* CRS SYNC Missed */
|
|
crsstatus |= RCC_CRS_SYNCMISS;
|
|
|
|
/* Clear CRS SYNC Missed bit */
|
|
__HAL_RCC_CRS_CLEAR_FLAG(RCC_CRS_FLAG_SYNCMISS);
|
|
}
|
|
|
|
/* Check CRS Expected SYNC flag */
|
|
if(__HAL_RCC_CRS_GET_FLAG(RCC_CRS_FLAG_ESYNC))
|
|
{
|
|
/* frequency error counter reached a zero value */
|
|
__HAL_RCC_CRS_CLEAR_FLAG(RCC_CRS_FLAG_ESYNC);
|
|
}
|
|
}
|
|
|
|
return crsstatus;
|
|
}
|
|
|
|
#endif /* STM32F042x6 || STM32F048xx || */
|
|
/* STM32F071xB || STM32F072xB || STM32F078xx || */
|
|
/* STM32F091xC || STM32F098xx */
|
|
|
|
/**
|
|
* @}
|
|
*/
|
|
|
|
/**
|
|
* @}
|
|
*/
|
|
|
|
#endif /* HAL_RCC_MODULE_ENABLED */
|
|
/**
|
|
* @}
|
|
*/
|
|
|
|
/**
|
|
* @}
|
|
*/
|
|
|
|
/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
|