//*********************************************************************************************************************
//【 版 权 】Copyright (c) 2007-2008 http://gliethttp.cublog.cn
//
//【 文 件 版 本 】v1.x
//
//【 文 件 名 称 】startup.c
//
//【 创 建 日 期 】2007-12-27
//
//【 功 能 描 述 】
//*********************************************************************************************************************
#include <misc.h>
#include <xDBGU.h>
//---------------------------------------------------------------------------------------------------------------------
//【 版 本 】v1.0
//【 函 数 名 称 】
//【 创建人及创建时间 】gliethttp 2007-12-27
//【 修改人及修改时间 】
//【 修 改 原 因 】
//【 功 能 描 述 】
//---------------------------------------------------------------------------------------------------------------------
#define DELAY_PLL 200
#define DELAY_MAIN_FREQ 200
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// Configuration for a Quartz 18.432000 MHz
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
#define PLLAR 0x2026BE04 //* 179,712000 MHz for PCK 0x20263E04
//#define PLLAR 0x2027BE04 //* 188,928000 MHz for PCK 0x20263E04
#define PLLBR 0x10483E0E //* 48,054857 MHz (divider by 2 for USB)
#define MCKR 0x00000202 //* PCK/3 = MCK Master Clock = 59,904000MHz with PLLA selected 0x00000202
#define SLOWCLOCK 32768 //* In Hz
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// Frequencies Range
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
#define INPUT_FREQ_MIN 900000
#define INPUT_FREQ_MAX 32000000
#define BASE_EBI_CS0_ADDRESS 0x10000000 //* base address to access memory on CS0
#define BASE_EBI_CS1_ADDRESS 0x20000000 //* base address to access memory on CS1
#define OUTPUT_FREQ_MIN 80000000
#define OUTPUT_FREQ_MAX 240000000
#define TRUE 1
#define FALSE 0
//---------------------------------------------------------------------------------------------------------------------
//【 版 本 】v1.0
//【 函 数 名 称 】
//【 创建人及创建时间 】gliethttp 2007-12-27
//【 修改人及修改时间 】
//【 修 改 原 因 】
//【 功 能 描 述 】
//---------------------------------------------------------------------------------------------------------------------
unsigned char AT91F_WaitForMainClockFrequency()
{
volatile char tmp = 0;
/////////////////////////////////////////////////////////////////////////////////////////////////////
// Step 2.
// Checking the Main Oscillator Frequency (Optional)
/////////////////////////////////////////////////////////////////////////////////////////////////////
AT91C_BASE_CKGR->CKGR_MOR=0x1;
//* Determine the main clock frequency
//2005-08-01:葛立新
//等待时钟稳定
while(!(AT91C_BASE_CKGR->CKGR_MCFR & AT91C_CKGR_MAINRDY) && (tmp++ < DELAY_MAIN_FREQ));
if (tmp >= DELAY_MAIN_FREQ)
return FALSE;
return TRUE;
}
//---------------------------------------------------------------------------------------------------------------------
//【 版 本 】v1.0
//【 函 数 名 称 】
//【 创建人及创建时间 】gliethttp 2007-12-27
//【 修改人及修改时间 】
//【 修 改 原 因 】
//【 功 能 描 述 】
//---------------------------------------------------------------------------------------------------------------------
void AT91F_InitFlash()
{
AT91C_BASE_MC->MC_PUIA[0] = AT91C_MC_PROT_PRWURW;
AT91C_BASE_MC->MC_PUP = 0;
AT91C_BASE_MC->MC_PUER =0; //* Memory controller protection unit disable
AT91C_BASE_MC->MC_ASR = 0; //* read only!
AT91C_BASE_MC->MC_AASR = 0; //* read only!
//* Setup MEMC to support CS0=Flash
AT91C_BASE_EBI->EBI_CSA |= AT91C_EBI_CS0A_SMC;
AT91C_BASE_EBI->EBI_CFGR = (AT91C_EBI_DBPUC & 0x00) | (AT91C_EBI_EBSEN & 0x00);
//* Setup Flash
AT91C_BASE_SMC2->SMC2_CSR[0] = (AT91C_SMC2_NWS & 0x4) | AT91C_SMC2_WSEN
| (AT91C_SMC2_TDF & 0x200) | AT91C_SMC2_BAT | AT91C_SMC2_DBW_16;
}
//---------------------------------------------------------------------------------------------------------------------
//【 版 本 】v1.0
//【 函 数 名 称 】
//【 创建人及创建时间 】gliethttp 2007-12-27
//【 修改人及修改时间 】
//【 修 改 原 因 】
//【 功 能 描 述 】
//---------------------------------------------------------------------------------------------------------------------
unsigned char AT91F_CheckPLL_FrequencyRange(int MainClock,int pllDivider ,int pllMultiplier)
{
if(pllDivider == 0)
return FALSE;
//* Check Input Frequency
if( ((MainClock/pllDivider) < INPUT_FREQ_MIN)
|| ((MainClock/pllDivider) > INPUT_FREQ_MAX) )
return FALSE;
//* Check Output Frequency
if( ((MainClock/pllDivider*pllMultiplier) < OUTPUT_FREQ_MIN)
|| ((MainClock/pllDivider*pllMultiplier) > OUTPUT_FREQ_MAX) )
return FALSE;
return TRUE;
}
//---------------------------------------------------------------------------------------------------------------------
//【 版 本 】v1.0
//【 函 数 名 称 】
//【 创建人及创建时间 】gliethttp 2007-12-27
//【 修改人及修改时间 】
//【 修 改 原 因 】
//【 功 能 描 述 】
//---------------------------------------------------------------------------------------------------------------------
unsigned char AT91F_InitClocks(int PLLAR_Register,int PLLBR_Register ,int MCKR_Register)
{
//#define PLLAR 0x2026BE04 //* 179,712000 MHz for PCK 0x20263E04
//#define PLLBR 0x10483E0E //* 48,054857 MHz (divider by 2 for USB)
//#define MCKR 0x00000202 //* PCK/3 = MCK Master Clock = 59,904000MHz with PLLA selected 0x00000202
//#define SLOWCLOCK 32768 //* In Hz
volatile char tmp = 0;
unsigned int MainClock;
unsigned int pllDivider,pllMultiplier;
/////////////////////////////////////////////////////////////////////////////////////////////////////
// Optionnal
/////////////////////////////////////////////////////////////////////////////////////////////////////
//* Check if Input & Output Frequencies are in the correct range
MainClock = AT91F_CKGR_GetMainClock(AT91C_BASE_CKGR,SLOWCLOCK);
pllDivider = (PLLAR_Register & AT91C_CKGR_DIVA);
pllMultiplier = ((PLLAR_Register & AT91C_CKGR_MULA) >> 16) + 1;
if(AT91F_CheckPLL_FrequencyRange(MainClock, pllDivider , pllMultiplier) == FALSE)
return FALSE;
pllDivider = (PLLBR_Register & AT91C_CKGR_DIVB);
pllMultiplier = ((PLLBR_Register & AT91C_CKGR_MULB) >> 16) + 1;
if(AT91F_CheckPLL_FrequencyRange(MainClock, pllDivider , pllMultiplier) == FALSE)
return FALSE;
/////////////////////////////////////////////////////////////////////////////////////////////////////
// Step 3.
// Setting PLLA and Divider A
/////////////////////////////////////////////////////////////////////////////////////////////////////
AT91C_BASE_CKGR->CKGR_PLLAR = PLLAR_Register;
//* Wait for PLLA stabilization LOCKA bit in PMC_SR
tmp = 0;
while( !(AT91C_BASE_PMC->PMC_SR & AT91C_PMC_LOCKA) && (tmp++ < DELAY_PLL) ) ;
/////////////////////////////////////////////////////////////////////////////////////////////////////
// Step 4.
// Setting PLLB and Divider B
/////////////////////////////////////////////////////////////////////////////////////////////////////
AT91C_BASE_CKGR->CKGR_PLLBR = PLLBR_Register;
//* Wait for PLLB stabilization LOCKB bit in PMC_SR
tmp = 0;
while( !(AT91C_BASE_PMC->PMC_SR & AT91C_PMC_LOCKB) && (tmp++ < DELAY_PLL) ) ;
/////////////////////////////////////////////////////////////////////////////////////////////////////
// Step 5.
// Selection of Master Clock MCK (and Processor Clock