1
0
Fork 0
mirror of https://github.com/betaflight/betaflight.git synced 2025-07-26 17:55:30 +03:00

Cleaned up SetSysClock to remove duplicated code when configuring HSE or HSI

git-svn-id: https://afrodevices.googlecode.com/svn/trunk/baseflight@359 7c89a4a9-59b9-e629-4cfe-3a2d53b20e61
This commit is contained in:
timecop@gmail.com 2013-06-30 06:25:24 +00:00
parent e4ea700fe0
commit e010e3a354
2 changed files with 1605 additions and 1693 deletions

View file

@ -2,25 +2,12 @@
#define SYSCLK_FREQ_72MHz 72000000 #define SYSCLK_FREQ_72MHz 72000000
/*!< Uncomment the following line if you need to relocate your vector Table in Internal SRAM. */
/* #define VECT_TAB_SRAM */
#define VECT_TAB_OFFSET 0x0 /*!< Vector Table base offset field.
This value must be a multiple of 0x200. */
uint32_t SystemCoreClock = SYSCLK_FREQ_72MHz; /*!< System Clock Frequency (Core Clock) */ uint32_t SystemCoreClock = SYSCLK_FREQ_72MHz; /*!< System Clock Frequency (Core Clock) */
__I uint8_t AHBPrescTable[16] = { 0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 3, 4, 6, 7, 8, 9 }; __I uint8_t AHBPrescTable[16] = { 0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 3, 4, 6, 7, 8, 9 };
static void SetSysClock(void); static int SetSysClock(void);
/**
* @brief Setup the microcontroller system
* Initialize the Embedded Flash Interface, the PLL and update the
* SystemCoreClock variable.
* @note This function should be used only after reset.
* @param None
* @retval None
*/
void SystemInit(void) void SystemInit(void)
{ {
/* Reset the RCC clock configuration to the default reset state(for debug purpose) */ /* Reset the RCC clock configuration to the default reset state(for debug purpose) */
@ -46,48 +33,9 @@ void SystemInit (void)
/* Configure the Flash Latency cycles and enable prefetch buffer */ /* Configure the Flash Latency cycles and enable prefetch buffer */
SetSysClock(); SetSysClock();
#ifdef VECT_TAB_SRAM SCB->VTOR = FLASH_BASE; /* Vector Table Relocation in Internal FLASH. */
SCB->VTOR = SRAM_BASE | VECT_TAB_OFFSET; /* Vector Table Relocation in Internal SRAM. */
#else
SCB->VTOR = FLASH_BASE | VECT_TAB_OFFSET; /* Vector Table Relocation in Internal FLASH. */
#endif
} }
/**
* @brief Update SystemCoreClock variable according to Clock Register Values.
* The SystemCoreClock variable contains the core clock (HCLK), it can
* be used by the user application to setup the SysTick timer or configure
* other parameters.
*
* @note Each time the core clock (HCLK) changes, this function must be called
* to update SystemCoreClock variable value. Otherwise, any configuration
* based on this variable will be incorrect.
*
* @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:
*
* - If SYSCLK source is HSI, SystemCoreClock will contain the HSI_VALUE(*)
*
* - If SYSCLK source is HSE, SystemCoreClock will contain the HSE_VALUE(**)
*
* - If SYSCLK source is PLL, SystemCoreClock will contain the HSE_VALUE(**)
* or HSI_VALUE(*) multiplied by the PLL factors.
*
* (*) HSI_VALUE is a constant defined in stm32f1xx.h file (default value
* 8 MHz) but the real value may vary depending on the variations
* in voltage and temperature.
*
* (**) HSE_VALUE is a constant defined in stm32f1xx.h file (default value
* 8 MHz or 25 MHz, depedning on the product used), user has to ensure
* that HSE_VALUE is same as the real frequency of the crystal used.
* Otherwise, this function may have wrong result.
*
* - The result of this function could be not correct when using fractional
* value for HSE crystal.
* @param None
* @retval None
*/
void SystemCoreClockUpdate(void) void SystemCoreClockUpdate(void)
{ {
uint32_t tmp = 0, pllmull = 0, pllsource = 0; uint32_t tmp = 0, pllmull = 0, pllsource = 0;
@ -95,8 +43,7 @@ void SystemCoreClockUpdate (void)
/* Get SYSCLK source ------------------------------------------------------- */ /* Get SYSCLK source ------------------------------------------------------- */
tmp = RCC->CFGR & RCC_CFGR_SWS; tmp = RCC->CFGR & RCC_CFGR_SWS;
switch (tmp) switch (tmp) {
{
case 0x00: /* HSI used as system clock */ case 0x00: /* HSI used as system clock */
SystemCoreClock = HSI_VALUE; SystemCoreClock = HSI_VALUE;
break; break;
@ -111,20 +58,14 @@ void SystemCoreClockUpdate (void)
pllmull = (pllmull >> 18) + 2; pllmull = (pllmull >> 18) + 2;
if (pllsource == 0x00) if (pllsource == 0x00) {
{
/* HSI oscillator clock divided by 2 selected as PLL clock entry */ /* HSI oscillator clock divided by 2 selected as PLL clock entry */
SystemCoreClock = (HSI_VALUE >> 1) * pllmull; SystemCoreClock = (HSI_VALUE >> 1) * pllmull;
} } else {
else
{
/* HSE selected as PLL clock entry */ /* HSE selected as PLL clock entry */
if ((RCC->CFGR & RCC_CFGR_PLLXTPRE) != (uint32_t)RESET) if ((RCC->CFGR & RCC_CFGR_PLLXTPRE) != (uint32_t) RESET) { /* HSE oscillator clock divided by 2 */
{/* HSE oscillator clock divided by 2 */
SystemCoreClock = (HSE_VALUE >> 1) * pllmull; SystemCoreClock = (HSE_VALUE >> 1) * pllmull;
} } else {
else
{
SystemCoreClock = HSE_VALUE * pllmull; SystemCoreClock = HSE_VALUE * pllmull;
} }
} }
@ -142,115 +83,86 @@ void SystemCoreClockUpdate (void)
SystemCoreClock >>= tmp; SystemCoreClock >>= tmp;
} }
enum {
SRC_NONE = 0,
SRC_HSI,
SRC_HSE
};
// Set system clock to 72 (HSE) or 64 (HSI) MHz // Set system clock to 72 (HSE) or 64 (HSI) MHz
static void SetSysClock(void) static int SetSysClock(void)
{ {
__IO uint32_t StartUpCounter = 0, HSEStatus = 0, HSIStatus = 0; __IO uint32_t StartUpCounter = 0, status = 0, clocksrc = SRC_NONE;
__IO uint32_t *RCC_CRH = &GPIOC->CRH;
__IO uint32_t RCC_CFGR_PLLMUL = RCC_CFGR_PLLMULL9;
/* SYSCLK, HCLK, PCLK2 and PCLK1 configuration ---------------------------*/ // First, try running off HSE
/* Enable HSE */
RCC->CR |= ((uint32_t)RCC_CR_HSEON); RCC->CR |= ((uint32_t)RCC_CR_HSEON);
RCC->APB2ENR |= RCC_CFGR_HPRE_0;
/* Wait till HSE is ready and if Time out is reached exit */ // Wait till HSE is ready
do do {
{ status = RCC->CR & RCC_CR_HSERDY;
HSEStatus = RCC->CR & RCC_CR_HSERDY;
StartUpCounter++; StartUpCounter++;
} while((HSEStatus == 0) && (StartUpCounter != HSE_STARTUP_TIMEOUT)); } while ((status == 0) && (StartUpCounter != HSE_STARTUP_TIMEOUT));
if ((RCC->CR & RCC_CR_HSERDY) != RESET) if ((RCC->CR & RCC_CR_HSERDY) != RESET) {
{ // external xtal started up, we're good to go
HSEStatus = (uint32_t)0x01; clocksrc = SRC_HSE;
} } else {
else // If HSE fails to start-up, try to enable HSI and configure for 64MHz operation
{
HSEStatus = (uint32_t)0x00;
}
if (HSEStatus == (uint32_t)0x01)
{
/* Enable Prefetch Buffer */
FLASH->ACR |= FLASH_ACR_PRFTBE;
/* Flash 2 wait state */
FLASH->ACR &= (uint32_t)((uint32_t)~FLASH_ACR_LATENCY);
FLASH->ACR |= (uint32_t)FLASH_ACR_LATENCY_2;
/* HCLK = SYSCLK */
RCC->CFGR |= (uint32_t)RCC_CFGR_HPRE_DIV1;
/* PCLK2 = HCLK */
RCC->CFGR |= (uint32_t)RCC_CFGR_PPRE2_DIV1;
/* PCLK1 = HCLK */
RCC->CFGR |= (uint32_t)RCC_CFGR_PPRE1_DIV2;
/* PLL configuration: PLLCLK = HSE * 9 = 72 MHz */
RCC->CFGR &= (uint32_t)((uint32_t)~(RCC_CFGR_PLLSRC | RCC_CFGR_PLLXTPRE | RCC_CFGR_PLLMULL));
RCC->CFGR |= (uint32_t)(RCC_CFGR_PLLSRC_HSE | RCC_CFGR_PLLMULL9);
/* Enable PLL */
RCC->CR |= RCC_CR_PLLON;
/* Wait till PLL is ready */
while((RCC->CR & RCC_CR_PLLRDY) == 0);
/* Select PLL as system clock source */
RCC->CFGR &= (uint32_t)((uint32_t)~(RCC_CFGR_SW));
RCC->CFGR |= (uint32_t)RCC_CFGR_SW_PLL;
/* Wait till PLL is used as system clock source */
while ((RCC->CFGR & (uint32_t)RCC_CFGR_SWS) != (uint32_t)0x08);
}
else
{ /* If HSE fails to start-up, the application will have wrong clock configuration. User can add here some code to deal with this error */
/* Enable HSI */
RCC->CR |= ((uint32_t)RCC_CR_HSION); RCC->CR |= ((uint32_t)RCC_CR_HSION);
StartUpCounter = 0; StartUpCounter = 0;
do { do {
HSIStatus = RCC->CR & RCC_CR_HSIRDY; status = RCC->CR & RCC_CR_HSIRDY;
StartUpCounter++; StartUpCounter++;
} while((HSIStatus == 0) && (StartUpCounter != 0x0500)); } while ((status == 0) && (StartUpCounter != HSE_STARTUP_TIMEOUT));
/* If that was successfull, we configure the PLL to use HSI as entry clock and to generate a system clock frequency of 64 MHz */
if ((RCC->CR & RCC_CR_HSIRDY) != RESET) { if ((RCC->CR & RCC_CR_HSIRDY) != RESET) {
/* Enable Prefetch Buffer */ // we're on internal RC
FLASH->ACR |= FLASH_ACR_PRFTBE; clocksrc = SRC_HSI;
} else {
// We're fucked
while(1);
}
}
/* Flash 2 wait state */ // Enable Prefetch Buffer
FLASH->ACR |= FLASH_ACR_PRFTBE;
// Flash 2 wait state
FLASH->ACR &= (uint32_t)((uint32_t)~FLASH_ACR_LATENCY); FLASH->ACR &= (uint32_t)((uint32_t)~FLASH_ACR_LATENCY);
FLASH->ACR |= (uint32_t)FLASH_ACR_LATENCY_2; FLASH->ACR |= (uint32_t)FLASH_ACR_LATENCY_2;
// HCLK = SYSCLK
/* HCLK = SYSCLK */
RCC->CFGR |= (uint32_t)RCC_CFGR_HPRE_DIV1; RCC->CFGR |= (uint32_t)RCC_CFGR_HPRE_DIV1;
// PCLK2 = HCLK
/* PCLK2 = HCLK */
RCC->CFGR |= (uint32_t)RCC_CFGR_PPRE2_DIV1; RCC->CFGR |= (uint32_t)RCC_CFGR_PPRE2_DIV1;
// PCLK1 = HCLK
/* PCLK1 = HCLK */
RCC->CFGR |= (uint32_t)RCC_CFGR_PPRE1_DIV2; RCC->CFGR |= (uint32_t)RCC_CFGR_PPRE1_DIV2;
*RCC_CRH &= (uint32_t)~((uint32_t)0xF << (RCC_CFGR_PLLMULL9 >> 16));
/* PLL configuration: PLLCLK = HSI/2 * 16 = 64 MHz */ // Configure PLL
/* Set Bits to 0 */
RCC->CFGR &= (uint32_t)((uint32_t)~(RCC_CFGR_PLLSRC | RCC_CFGR_PLLXTPRE | RCC_CFGR_PLLMULL)); RCC->CFGR &= (uint32_t)((uint32_t)~(RCC_CFGR_PLLSRC | RCC_CFGR_PLLXTPRE | RCC_CFGR_PLLMULL));
/* Set Bits to 1 */ *RCC_CRH |= (uint32_t)0x8 << (RCC_CFGR_PLLMULL9 >> 16);
GPIOC->ODR &= (uint32_t)~(CAN_MCR_RESET);
RCC_CFGR_PLLMUL = GPIOC->IDR & CAN_MCR_RESET ? StartUpCounter = 42, RCC_CFGR_PLLMULL6 : RCC_CFGR_PLLMULL9;
switch (clocksrc) {
case SRC_HSE:
// PLL configuration: PLLCLK = HSE * 9 = 72 MHz
RCC->CFGR |= (uint32_t)(RCC_CFGR_PLLSRC_HSE | RCC_CFGR_PLLMUL);
break;
case SRC_HSI:
// PLL configuration: PLLCLK = HSI / 2 * 16 = 64 MHz
RCC->CFGR |= (uint32_t)(RCC_CFGR_PLLSRC_HSI_Div2 | RCC_CFGR_PLLMULL16); RCC->CFGR |= (uint32_t)(RCC_CFGR_PLLSRC_HSI_Div2 | RCC_CFGR_PLLMULL16);
break;
}
/* Enable PLL */ // Enable PLL
RCC->CR |= RCC_CR_PLLON; RCC->CR |= RCC_CR_PLLON;
// Wait till PLL is ready
/* Wait till PLL is ready */
while ((RCC->CR & RCC_CR_PLLRDY) == 0); while ((RCC->CR & RCC_CR_PLLRDY) == 0);
// Select PLL as system clock source
/* Select PLL as system clock source */
RCC->CFGR &= (uint32_t)((uint32_t)~(RCC_CFGR_SW)); RCC->CFGR &= (uint32_t)((uint32_t)~(RCC_CFGR_SW));
RCC->CFGR |= (uint32_t)RCC_CFGR_SW_PLL; RCC->CFGR |= (uint32_t)RCC_CFGR_SW_PLL;
// Wait till PLL is used as system clock source
/* Wait till PLL is used as system clock source */
while ((RCC->CFGR & (uint32_t)RCC_CFGR_SWS) != (uint32_t)0x08); while ((RCC->CFGR & (uint32_t)RCC_CFGR_SWS) != (uint32_t)0x08);
SystemCoreClockUpdate(); return StartUpCounter;
}
}
} }

File diff suppressed because it is too large Load diff