www.pudn.com > ucos_lwip_at91rm9200.rar > C_Start.c


//*---------------------------------------------------------------------------- 
//*         ATMEL Microcontroller Software Support  -  ROUSSET  - 
//*---------------------------------------------------------------------------- 
//* The software is delivered "AS IS" without warranty or condition of any 
//* kind, either express, implied or statutory. This includes without 
//* limitation any warranty or condition with respect to merchantability or 
//* fitness for any particular purpose, or against the infringements of 
//* intellectual property rights of others. 
//*---------------------------------------------------------------------------- 
//* File Name           : lib_AT91RM9200.h 
//* Object              : AT91RM9200 inlined functions 
//* Generated           : AT91 SW Application Group  04/16/2003 (12:30:07) 
//* 
//* CVS Reference       : /lib_pdc.h/1.2/Tue Jul 02 11:29:40 2002// 
//* CVS Reference       : /lib_dbgu.h/1.1/Fri Jan 31 11:18:40 2003// 
//* CVS Reference       : /lib_rtc_1245d.h/1.1/Fri Jan 31 11:19:12 2003// 
//* CVS Reference       : /lib_ssc.h/1.4/Fri Jan 31 11:19:20 2003// 
//* CVS Reference       : /lib_spi_AT91RMxxxx.h/1.2/Fri Jan 31 11:19:32 2003// 
//* CVS Reference       : /lib_tc_1753b.h/1.1/Fri Jan 31 11:20:02 2003// 
//* CVS Reference       : /lib_pmc.h/1.3/Thu Nov 14 06:40:46 2002// 
//* CVS Reference       : /lib_pio.h/1.3/Fri Jan 31 11:18:56 2003// 
//* CVS Reference       : /lib_twi.h/1.2/Fri Jan 31 11:19:38 2003// 
//* CVS Reference       : /lib_usart.h/1.5/Thu Nov 21 15:01:54 2002// 
//* CVS Reference       : /lib_mci.h/1.2/Wed Nov 20 13:18:56 2002// 
//* CVS Reference       : /lib_aic.h/1.3/Fri Jul 12 06:46:12 2002// 
//* CVS Reference       : /lib_udp.h/1.3/Fri Jan 31 11:19:48 2003// 
//* CVS Reference       : /lib_st.h/1.4/Fri Jan 31 11:20:14 2003// 
//*---------------------------------------------------------------------------- 
#include "AT91RM9200.h" 
#include "lib_AT91RM9200.h" 
 
//*---------------------------------------------------------------------------- 
//*         ATMEL Microcontroller Software Support  -  ROUSSET  - 
//*---------------------------------------------------------------------------- 
//* The software is delivered "AS IS" without warranty or condition of any 
//* kind, either express, implied or statutory. This includes without 
//* limitation any warranty or condition with respect to merchantability or 
//* fitness for any particular purpose, or against the infringements of 
//* intellectual property rights of others. 
//*---------------------------------------------------------------------------- 
//* File Name           : init_c.c 
//* Object              : Low level initialisations written in C 
//* Creation            : FB   23/10/2002 
//* 
//*---------------------------------------------------------------------------- 
 
///////////////////////////////////////////////////////////////////////////////////////////////////// 
///////////////////////////////////////////////////////////////////////////////////////////////////// 
///////////////////////////////////////////////////////////////////////////////////////////////////// 
 
#define	FALSE					0 
#define	TRUE					1 
#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	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 
 
 
//*---------------------------------------------------------------------------- 
//* \fn    AT91F_DBGU_Printk 
//* \brief This function is used to send a string through the DBGU channel (Very low level debugging) 
//*---------------------------------------------------------------------------- 
void AT91F_DBGU_Printk( 
	char *buffer) // \arg pointer to a string ending by \0 
{ 
	while(*buffer != '\0') { 
		while (!AT91F_US_TxReady((AT91PS_USART)AT91C_BASE_DBGU)); 
		AT91F_US_PutChar((AT91PS_USART)AT91C_BASE_DBGU, *buffer++); 
	} 
} 
 
/*----------------------------------------------------------------------------	*/ 
/* \fn    AT91F_DataAbort							*/ 
/* \brief This function reports an Abort					*/ 
/*----------------------------------------------------------------------------	*/ 
void AT91F_SpuriousHandler()  
{ 
	AT91F_DBGU_Printk("-F- Spurious Interrupt detected\n\r"); 
	while (1); 
} 
 
 
/*----------------------------------------------------------------------------	*/ 
/* \fn    AT91F_DataAbort							*/ 
/* \brief This function reports an Abort					*/ 
/*----------------------------------------------------------------------------	*/ 
void AT91F_DataAbort()  
{ 
	AT91F_DBGU_Printk("-F- Data Abort detected\n\r"); 
	while (1); 
} 
 
/*----------------------------------------------------------------------------	*/ 
/* \fn    AT91F_FetchAbort							*/ 
/* \brief This function reports an Abort					*/ 
/*----------------------------------------------------------------------------	*/ 
void AT91F_FetchAbort() 
{ 
	AT91F_DBGU_Printk("-F- Prefetch Abort detected\n\r"); 
	while (1); 
} 
 
/*----------------------------------------------------------------------------	*/ 
/* \fn    AT91F_Undef								*/ 
/* \brief This function reports an Abort					*/ 
/*----------------------------------------------------------------------------	*/ 
void AT91F_Undef()  
{ 
	AT91F_DBGU_Printk("-F- Undef detected\n\r"); 
	while (1); 
} 
 
/*----------------------------------------------------------------------------	*/ 
/* \fn    AT91F_UndefHandler							*/ 
/* \brief This function reports that no handler have been set for current IT	*/ 
/*----------------------------------------------------------------------------	*/ 
void AT91F_UndefHandler()  
{ 
	AT91F_DBGU_Printk("-F- Undef detected\n\r"); 
	while (1); 
} 
 
 
//*---------------------------------------------------------------------------- 
//* \fn    AT91F_WaitForMainClockFrequency 
//* \brief This function performs very low level HW initialization 
//*---------------------------------------------------------------------------- 
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 
	 
	while(!(AT91C_BASE_CKGR->CKGR_MCFR & AT91C_CKGR_MAINRDY) && (tmp++ < DELAY_MAIN_FREQ)); 
 
	if (tmp >= DELAY_MAIN_FREQ) 
		return FALSE; 
 
	return TRUE; 
} 
 
//*---------------------------------------------------------------------------- 
//* \fn    AT91F_CheckPLL_FrequencyRange 
//* \brief This function performs very low level HW initialiszation 
//*---------------------------------------------------------------------------- 
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; 
} 
 
//*---------------------------------------------------------------------------- 
//* \fn    AT91F_InitClocks 
//* \brief This function performs very low level HW initialization 
//*---------------------------------------------------------------------------- 
unsigned char AT91F_InitClocks(int PLLAR_Register,int PLLBR_Register ,int MCKR_Register) 
{ 
	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 PCK) 
///////////////////////////////////////////////////////////////////////////////////////////////////// 
 
	//* Constraints of the Master Clock selection sequence 
	//* Write in the MCKR dirty value concerning the clock selection CSS then overwrite it in a second sequence 
	 
	AT91C_BASE_PMC->PMC_MCKR =0x1;//AT91C_PMC_CSS_SLOW_CLK; 
	//* Wait until the master clock is established 
	tmp = 0; 
	while( !(AT91C_BASE_PMC->PMC_SR & AT91C_PMC_MCKRDY) && (tmp++ < DELAY_MAIN_FREQ) ); 
 
	//* Second sequence 
	AT91C_BASE_PMC->PMC_MCKR =MCKR; 
	//* Wait until the master clock is established 
	tmp = 0; 
	while( !(AT91C_BASE_PMC->PMC_SR & AT91C_PMC_MCKRDY) && (tmp++ < DELAY_MAIN_FREQ) ); 
 
	return TRUE; 
} 
//*---------------------------------------------------------------------------- 
//* \fn    AT91F_InitSDRAM 
//* \brief This function performs very low level HW initialisation 
//*---------------------------------------------------------------------------- 
void AT91F_InitSDRAM() 
{ 
	volatile int *pRegister; 
	AT91PS_PIO pPio = AT91C_BASE_PIOC; 
	 
	/* Configure PIOC as peripheral (D16/D31) */ 
	pPio->PIO_ASR = 0xFFFF0000; 
	pPio->PIO_BSR = 0x0; 
	pPio->PIO_PDR = 0xFFFF0000; 
	 
	/* Setup MEMC to support all connected memories (CS0 = FLASH; CS1=SDRAM) */ 
	pRegister = (int *)0xFFFFFF60; 
	*pRegister = 0x02;  
	 
	/* Init SDRAM */ 
	pRegister = (int *)0xFFFFFF98; 
	*pRegister = 0x2188c155;  
	pRegister = (int *)0xFFFFFF90; 
	*pRegister = 0x2;  
	pRegister = (int *)0x20000000; 
	*pRegister = 0;  
	pRegister = (int *)0xFFFFFF90; 
	*pRegister = 0x4;  
	pRegister = (int *)0x20000000; 
	*pRegister = 0;  
	*pRegister = 0;  
	*pRegister = 0;  
	*pRegister = 0;  
	*pRegister = 0;  
	*pRegister = 0;  
	*pRegister = 0;  
	*pRegister = 0;  
	pRegister = (int *)0xFFFFFF90; 
	*pRegister = 0x3;  
	pRegister = (int *)0x20000080; 
	*pRegister = 0;  
	pRegister = (int *)0xFFFFFF94; 
	*pRegister = 0x2e0;  
	pRegister = (int *)0x20000000; 
	*pRegister = 0;  
	pRegister = (int *)0xFFFFFF90; 
	*pRegister = 0x00;  
	pRegister = (int *)0x20000000; 
	*pRegister = 0;  
} 
 
 
//*---------------------------------------------------------------------------- 
//* \fn    AT91F_InitFlash 
//* \brief This function performs very low level HW initialization 
//*---------------------------------------------------------------------------- 
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; 
} 
 
 
//*---------------------------------------------------------------------------- 
//* \fn    AT91F_LowLevelInit 
//* \brief This function performs very low level HW initialization 
//*---------------------------------------------------------------------------- 
extern void AT91F_LowLevelInit() 
{ 
	unsigned char 	status; 
 
    //step1 
    status = AT91F_WaitForMainClockFrequency(); 
     
    //step2 
    AT91F_InitFlash(); 
     
    //step3 init clock 
    status = AT91F_InitClocks(PLLAR,PLLBR,MCKR); 
     
    //step4 configuare sdram 
    AT91F_InitSDRAM(); 
     
    // Init Interrupt Controller 
	AT91F_AIC_Open( 
		AT91C_BASE_AIC,          // pointer to the AIC registers 
		AT91C_AIC_BRANCH_OPCODE, // IRQ exception vector 
		AT91F_UndefHandler,      // FIQ exception vector 
		AT91F_UndefHandler,      // AIC default handler 
		AT91F_SpuriousHandler,   // AIC spurious handler 
		0);                      // Protect mode 
		 
	// Perform 8 End Of Interrupt Command to make sure AIC will not Lock out nIRQ  
	AT91F_AIC_AcknowledgeIt(AT91C_BASE_AIC); 
	AT91F_AIC_AcknowledgeIt(AT91C_BASE_AIC); 
	AT91F_AIC_AcknowledgeIt(AT91C_BASE_AIC); 
	AT91F_AIC_AcknowledgeIt(AT91C_BASE_AIC); 
	AT91F_AIC_AcknowledgeIt(AT91C_BASE_AIC); 
	AT91F_AIC_AcknowledgeIt(AT91C_BASE_AIC); 
	AT91F_AIC_AcknowledgeIt(AT91C_BASE_AIC); 
	AT91F_AIC_AcknowledgeIt(AT91C_BASE_AIC); 
 
    //step5 usart0 init 
    //AT91F_US0_Init(); 
    	 
    AT91F_DBGU_CfgPIO(); 
 
	// Configure DBGU 
	AT91F_US_Configure ( 
		(AT91PS_USART) AT91C_BASE_DBGU,          			// DBGU base address 
		60000000,                  							// 60 MHz 
		AT91C_US_CHMODE_NORMAL | AT91C_US_PAR_NONE ,        // mode Register to be programmed 
		115200 ,                   							// baudrate to be programmed 
		0);                        							// timeguard to be programmed 
 
	// Enable Transmitter 
	AT91F_US_EnableTx((AT91PS_USART) AT91C_BASE_DBGU); 
 
	AT91F_DBGU_Printk("\n\rAT91F_LowLevelInit() Complete in Flash!\n\r"); 
 
}