⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 init.c

📁 YL9200开发板的测试代码,详细请下载后细看
💻 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           : init.c
//* Object              : Low level initialisations written in C
//* Creation            : ODi   06/26/2002
//*
//*----------------------------------------------------------------------------

#include "AT91RM9200.h"
#include "lib_AT91RM9200.h"
#include "def.h"
#include "config.h"
#include "slib.h"
#include "console.h"

//伪中断处理函数
//伪中断是指电平出发时持续时间太短中断,不能被被正常识别出来的情况
static void SpuriousHandler(void) 
{
	puts("Spurious Interrupt detected\n");
	AT91F_AIC_AcknowledgeIt(AT91C_BASE_AIC);	//应答并返回
}

//未设置处理函数的中断
static void NonSvcHandler(void)
{
	puts("Non-serviced irq detectd\n");
	while(1);
}

static void SwiHandler(void)
{
	puts("Swi Interrupt detected\n");
}

static void DataAbortHandler(void) 
{
	puts("Data Abort detected\n");
	while (1);
}

static void FetchAbortHandler(void)
{
	puts("Prefetch Abort detected\n");
	while (1);
}

static void UndefHandler() 
{
	puts("Halt on Undefined instruction\n");
	while (1);
}

static void FiqHandler(void)
{
	puts("Halt on FIQ!\n");
	while(1);
}


#define	DELAY_PLL				1000
#define DELAY_MAIN_FREQ			1000

#define SLOWCLOCK				32768		//* In Hz

//*----------------------------------------------------------------------------
//* \fn    AT91F_WaitForMainClockFrequency
//* \brief This function performs very low level HW initialization
//*----------------------------------------------------------------------------
unsigned char AT91F_WaitForMainClockFrequency(void)
{
	volatile char	tmp	= 0;

/////////////////////////////////////////////////////////////////////////////////////////////////////
// Step 2.
// Checking the Main Oscillator Frequency (Optional)
/////////////////////////////////////////////////////////////////////////////////////////////////////

	//* 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_InitFlash
//* \brief This function performs very low level HW initialization
//*----------------------------------------------------------------------------
void AT91F_InitFlash(void)
{
	AT91C_BASE_MC->MC_PUIA[0] = AT91C_MC_PROT_PNAUNA;
	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;
}

/*--------------------------------------------------------------------------------------*/
/* Function Name       : AT91F_SetPLL()							*/
/* Object              : Set the PLLA to 180MHz and Master Clock to 60Mhz		*/
/* Object              : Set the PLLA to 200MHz and Master Clock to 66Mhz		*/
/*--------------------------------------------------------------------------------------*/
/////////////////////////////////////////////////////////////////////////////////////////////////////
// Configuration for a Quartz 18.432000 MHz
/////////////////////////////////////////////////////////////////////////////////////////////////////
#if (PROCESSOR_CLOCK == 243302400)
#define AT91C_PLLA_VALUE	0x20C5BE0F	//PLLA = 0xC6*18.432M/0xf = 243.3024M
#elif (PROCESSOR_CLOCK == 221184000)
#define AT91C_PLLA_VALUE	0x2077BE0A	//PLLA = 0x78*18.432M/0xa = 221.184M
#elif (PROCESSOR_CLOCK == 203000000)
#define AT91C_PLLA_VALUE	0x21B8BE28	//PLLA = 0x1B8*18.432M/0x28 = 203M
#elif (PROCESSOR_CLOCK == 199065600)
#define AT91C_PLLA_VALUE	0x206BBE0A	//PLLA = 0x6c*18.432M/0xa = 199.0656M
#elif (PROCESSOR_CLOCK == 176947200)
#define AT91C_PLLA_VALUE	0x205FBE0A	//PLLA = 0x60*18.432M/0xa = 176.9472M
#elif (PROCESSOR_CLOCK == 154828800)
#define AT91C_PLLA_VALUE	0x2053BE0A	//PLLA = 0x54*18.432M/0xa = 154.8288M
#endif

#define	AT91C_PLLB_VALUE	0x10483E0E	//* 48,054857 MHz (divider by 2 for USB)

#if (MASTER_CLOCK_DIVIDER == 1)
#define	MCKR_VAL	0x002				//1/1
#elif (MASTER_CLOCK_DIVIDER == 2)
#define	MCKR_VAL	0x102				//1/2
#elif (MASTER_CLOCK_DIVIDER == 3)
#define	MCKR_VAL	0x202				//1/3
#elif (MASTER_CLOCK_DIVIDER == 4)
#define	MCKR_VAL	0x302				//1/3
#endif

static void InitPLL_old(void)
{
	volatile int tmp = 0;
	
	/* APMC Initialization for Crystal */
	AT91PS_PMC pApmc = (AT91PS_PMC)AT91C_BASE_PMC;
	AT91PS_CKGR pCkgr =  (AT91PS_CKGR)AT91C_BASE_CKGR;
	
	//禁止PMC的所有中断源
	pApmc->PMC_IDR = 0xFFFFFFFF;
	
	// Setting PLLB and Divider B
	if((pCkgr->CKGR_PLLBR^AT91C_PLLB_VALUE)&0x07ff00ff) {
		pCkgr->CKGR_PLLBR = AT91C_PLLB_VALUE;
		//* Wait for PLLB stabilization LOCKB bit in PMC_SR
		tmp = 0;
		while(!(pApmc->PMC_SR & AT91C_PMC_LOCKB) && (tmp++ < DELAY_PLL));
	}
	
	//先选择PLLB做为主时钟
	/* Write in the MCKR dirty value concerning the clock selection CSS then overwrite it in a second sequence */
	pApmc->PMC_MCKR = 0x203;
	/* Wait until the master clock is established */
	tmp = 0;
	while(!(pApmc->PMC_SR & AT91C_PMC_MCKRDY) && (tmp++ < DELAY_MAIN_FREQ));

	//再设置PLLA,若原主时钟为PLLA而在未切换到其他时钟源时设置PLLA(值不变),启动会等很久,why?
	if((pCkgr->CKGR_PLLAR^AT91C_PLLA_VALUE)&0x07ff00ff) {
		pCkgr->CKGR_PLLAR = AT91C_PLLA_VALUE;
		//* Wait for PLLB stabilization LOCKB bit in PMC_SR
		tmp = 0;
		while(!(pApmc->PMC_SR & AT91C_PMC_LOCKA) && (tmp++ < DELAY_PLL));
	}
	
	//再把主时钟源换到PLLA,设置同步模式,等待时钟稳定
	/* - Commuting Master Clock from PLLB to PLLA/3 */
	pApmc->PMC_MCKR = MCKR_VAL;	//master clock 为 PLLA,预分频为1,Processor clock为master clock的2/3倍	
	/* Wait until the master clock is established */
	tmp = 0;
	while(!(pApmc->PMC_SR & AT91C_PMC_MCKRDY) && (tmp++ < DELAY_MAIN_FREQ));
	MMU_SetAsyncBusMode();		//设置CPU总线同步模式
}

#define	EXT_OSC_CLK			18432000
static struct{
	U32 plla;
	U32 mckr;
	U32 n1;
	U32 n2;
} ClkPara;

static void InitPLL(void)
{
	
	volatile int tmp = 0;
	U32 freq;
	
	/* APMC Initialization for Crystal */
	AT91PS_PMC pApmc = (AT91PS_PMC)AT91C_BASE_PMC;
	AT91PS_CKGR pCkgr =  (AT91PS_CKGR)AT91C_BASE_CKGR;
	ClkPara.plla=(440<<16)|40;
	ClkPara.mckr=2<<8;
//	if(((pCkgr->CKGR_PLLAR&0x7ff0000)==(ClkPara.plla&0x7ff0000)) &&
//		((pCkgr->CKGR_PLLAR&0xff)==(ClkPara.plla&0xff)) &&
//		(pApmc->PMC_MCKR==))
//		return
	
	ClkPara.plla &= 0x7ff00ff;
	ClkPara.plla |= (1<<29)|(0x3f<<8);
	freq = (((ClkPara.plla>>16)&0x7ff)+1)*EXT_OSC_CLK/(ClkPara.plla&0xff);
	if(freq>=150000000)
		ClkPara.plla |= 1<<15;
		
	ClkPara.mckr &= 0x300;
	ClkPara.mckr |= 2;

	//禁止PMC的所有中断源
	pApmc->PMC_IDR = 0xFFFFFFFF;
	
	// Setting PLLB and Divider B
	if((pCkgr->CKGR_PLLBR^AT91C_PLLB_VALUE)&0x07ff00ff) {
		pCkgr->CKGR_PLLBR = AT91C_PLLB_VALUE;
		//* Wait for PLLB stabilization LOCKB bit in PMC_SR
		tmp = 0;
		while(!(pApmc->PMC_SR & AT91C_PMC_LOCKB) && (tmp++ < DELAY_MAIN_FREQ));
	}
	
	//先选择PLLB做为主时钟
	/* Write in the MCKR dirty value concerning the clock selection CSS then overwrite it in a second sequence */
	pApmc->PMC_MCKR = 0x203;
	/* Wait until the master clock is established */
	tmp = 0;
	while(!(pApmc->PMC_SR & AT91C_PMC_MCKRDY) && (tmp++ < DELAY_PLL));

	//再设置PLLA,若原主时钟为PLLA而在未切换到其他时钟源时设置PLLA(值不变),启动会等很久,why?
	if((pCkgr->CKGR_PLLAR^ClkPara.plla)&0x07ff00ff) {
		pCkgr->CKGR_PLLAR = ClkPara.plla;
		//* Wait for PLLB stabilization LOCKB bit in PMC_SR
		tmp = 0;
		while(!(pApmc->PMC_SR & AT91C_PMC_LOCKA) && (tmp++ < DELAY_PLL));
	}
	
	//再把主时钟源换到PLLA,设置同步模式,等待时钟稳定
	/* - Commuting Master Clock from PLLB to PLLA/3 */
	pApmc->PMC_MCKR = ClkPara.mckr;	//master clock 为 PLLA,预分频为1,Processor clock为master clock的2/3倍
	/* Wait until the master clock is established */
	tmp = 0;
	while(!(pApmc->PMC_SR & AT91C_PMC_MCKRDY) && (tmp++ < DELAY_MAIN_FREQ));
	MMU_SetAsyncBusMode();		//设置CPU总线同步模式	
	
//	ClkPara.n1   = GetCpuClock();
//	ClkPara.n2   = GetMasterClock();
}
/*--------------------------------------------------------------------------------------*/
/* Function Name       : InitSDRAM						*/
/* Object              : Initialize the SDRAM						*/
/*--------------------------------------------------------------------------------------*/
/*
DRAM_PARAMS dram_params[DRAM_BANKS] = {	//在SDRAM初始化完成以前不要读取
	{DRAM_BASE, DRAM_SIZE},				//带初始化值的全局变量!!!
};*/									//要么使用PIC编译

static void InitSDRAM(void)		//此类函数均为相对调用,可与地址无关
{
	volatile int *pSDRAM = (int *)DRAM_BASE;
	
	/* Configure PIOC as peripheral (D16/D31) */	
	AT91F_PIO_CfgPeriph( AT91C_BASE_PIOC, 0xFFFF0000, 0);

	/*Setup MEMC to support all connected memories (CS0 = FLASH; CS1=SDRAM)*/
	AT91C_BASE_EBI->EBI_CSA = AT91C_EBI_CS1A;
	
	/*Init SDRAM*/
	AT91C_BASE_SDRC->SDRC_CR = 0x2188c155;
	AT91C_BASE_SDRC->SDRC_MR = 0x02;
	*pSDRAM = 0;
	AT91C_BASE_SDRC->SDRC_MR = 0x04;	
	*pSDRAM = 0;
	*pSDRAM = 0;
	*pSDRAM = 0;
	*pSDRAM = 0;
	*pSDRAM = 0;
	*pSDRAM = 0;
	*pSDRAM = 0;
	*pSDRAM = 0;

	AT91C_BASE_SDRC->SDRC_MR = 0x03;
	*(pSDRAM + 0x80) = 0;
	
	AT91C_BASE_SDRC->SDRC_TR= 0x2e0;
	*pSDRAM = 0;
	
	AT91C_BASE_SDRC->SDRC_MR = 0;
	*pSDRAM = 0;
}

#define	_ISR_STARTADDRESS	0x21ffff00
#define	pISR_RESET			*(U32 *)(_ISR_STARTADDRESS+0x0)
#define	pISR_UNDEF			*(U32 *)(_ISR_STARTADDRESS+0x4)
#define	pISR_SWI			*(U32 *)(_ISR_STARTADDRESS+0x8)
#define	pISR_PABORT			*(U32 *)(_ISR_STARTADDRESS+0xc)
#define	pISR_DABORT			*(U32 *)(_ISR_STARTADDRESS+0x10)
#define	pISR_RESERVED		*(U32 *)(_ISR_STARTADDRESS+0x14)
#define	pISR_IRQ			*(U32 *)(_ISR_STARTADDRESS+0x18)
#define	pISR_FIQ			*(U32 *)(_ISR_STARTADDRESS+0x1c)

static void InitISR(void)
{
	int i;
	
	pISR_UNDEF  = (U32)UndefHandler;
	pISR_SWI    = (U32)SwiHandler;
	pISR_PABORT = (U32)FetchAbortHandler;
	pISR_DABORT = (U32)DataAbortHandler;
	pISR_FIQ    = (U32)FiqHandler;
	
	// 禁止并清除所有中断,设置所有中断优先级,触发模式和缺省处理函数
	for (i = 0; i < 32; ++i) { 
		AT91F_AIC_DisableIt(AT91C_BASE_AIC, i);
		AT91F_AIC_ConfigureIt(AT91C_BASE_AIC, i, AT91C_AIC_PRIOR_LOWEST, AT91C_AIC_SRCTYPE_INT_LEVEL_SENSITIVE, NonSvcHandler);
	}	
	//设置伪中断处理函数入口
	AT91C_BASE_AIC->AIC_SPU = (U32)SpuriousHandler;
	AT91C_BASE_AIC->AIC_DCR = 0; //nornal mode
	
	/* Perform 8 End Of Interrupt Command to make s齬e AIC will not Lock out nIRQ */
	for(i=0; i<8; i++)
		AT91F_AIC_AcknowledgeIt(AT91C_BASE_AIC);
}

static void InitTimerCounter(void)
{
	AT91PS_TC pTC = AT91C_BASE_TC0;
	
	AT91F_TC0_CfgPMC();
	pTC->TC_IDR = 0xff;	//disable all interrupts
	//select TIMER_CLOCK2 = MCK/8, CPCTRG, up mode, Waveform mode
	pTC->TC_CMR = 1|(2<<13)|(1<<15);	//Capture模式下,RC COMPARE也可复位计数器
	pTC->TC_RC  = (AT91F_PMC_GetMasterClock(AT91C_BASE_PMC, AT91C_BASE_CKGR, 32768)>>3)/1000;
	pTC->TC_CCR = 5;	//enable timer-counter and trig it		
}

//*----------------------------------------------------------------------------
//* \fn    AT91F_LowLevelInit
//* \brief This function performs very low level HW initialization
//*----------------------------------------------------------------------------
void LowLevelInit()
{
/////////////////////////////////////////////////////////////////////////////////////////////////////
// Step 2.
// Checking the Main Oscillator Frequency (Optional)
/////////////////////////////////////////////////////////////////////////////////////////////////////
	AT91F_WaitForMainClockFrequency();
	
/////////////////////////////////////////////////////////////////////////////////////////////////////
// Flash AT49BV1614 Initialisation : must be done before change the clocks -> Set correct Wait States
/////////////////////////////////////////////////////////////////////////////////////////////////////

	//AT91F_InitFlash();

/////////////////////////////////////////////////////////////////////////////////////////////////////
// Step 3. to 5.
/////////////////////////////////////////////////////////////////////////////////////////////////////

	//AT91F_InitClocks(AT91C_PLLA_VALUE, AT91C_PLLB_VALUE, MCKR_VAL);

	InitPLL();
/*	// 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 s齬e 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);

	AT91F_AIC_SetExceptionVector((unsigned int *)0x0C, AT91F_FetchAbort);
	AT91F_AIC_SetExceptionVector((unsigned int *)0x10, AT91F_DataAbort);
	AT91F_AIC_SetExceptionVector((unsigned int *)0x4, AT91F_Undef);
*/
	InitSDRAM();
	InitISR();
	
	//initialize timer-counter for other functions to call delay()
	InitTimerCounter();
	
	// Open PIO for DBGU
	AT91F_DBGU_CfgPIO();

	// Configure DBGU
	AT91F_US_Configure (
		(AT91PS_USART) AT91C_BASE_DBGU,	// DBGU base address
		AT91C_MASTER_CLOCK,				// 
		AT91C_US_ASYNC_MODE,			// mode Register to be programmed
		UART_BAUD_RATE,					// baudrate to be programmed
		0);								// timeguard to be programmed

	// Enable Transmitter
	AT91F_US_EnableTx((AT91PS_USART) AT91C_BASE_DBGU);
	/* Enable Receiver */
	AT91F_US_EnableRx((AT91PS_USART)AT91C_BASE_DBGU);

//	puts("\n AT91F_LowLevelInit() done\n");
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -