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

📄 main.c

📁 该程序为AT91RM9200引导程序
💻 C
📖 第 1 页 / 共 2 页
字号:
//*----------------------------------------------------------------------------
extern void FindNandBoot(void);

void InitSDRAM(void)
{
	volatile int *pSDRAM = (int *)DRAM_BASE;
	
	//puts("1\n");
	/* 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 = 0x2188c154;
	AT91C_BASE_SDRC->SDRC_MR = 0x02;
	//puts("2\n");
	*pSDRAM = 0;
	AT91C_BASE_SDRC->SDRC_MR = 0x04;	
	//puts("3\n");
	*pSDRAM = 0;
	*pSDRAM = 0;
	*pSDRAM = 0;
	*pSDRAM = 0;
	*pSDRAM = 0;
	*pSDRAM = 0;
	*pSDRAM = 0;
	*pSDRAM = 0;
	//puts("4\n");

	AT91C_BASE_SDRC->SDRC_MR = 0x03;
	*(pSDRAM + 0x80) = 0;
	
	//puts("5\n");
	AT91C_BASE_SDRC->SDRC_TR= 0x2e0;
	*pSDRAM = 0;
	
	AT91C_BASE_SDRC->SDRC_MR = 0;
	*pSDRAM = 0;
	//puts("6\n");
}

#define		_DATA_OFF_SET	0x00000020
void TestSDRAM()
{
	volatile U32 *pSDRAM = (U32*)DRAM_BASE;
	U32 i;
	U32 j;
	for (i=0;i<DRAM_SIZE/sizeof(U32);i++){
		*(pSDRAM+i) = i+1/*0+_DATA_OFF_SET*/;
	}
	
	for (i=0;i<DRAM_SIZE/sizeof(U32);i++){
		j = *(pSDRAM+i);
		if(j!=(i+1/*0+_DATA_OFF_SET*/)){
			printf("Bad address:0x%x   wr = 0x%08X  rd = 0x%08X\n",DRAM_BASE+i*sizeof(U32) ,i+1/*0+_DATA_OFF_SET*/,j);
			//delay(500);
			//puts("aaaaaaaaaaaaaaaa\n");
		}
	}
	return;
}

int main(void)
{
	U8 c;
	int timeout=3000;
	int bootflag=1;
	AT91PS_EMAC pEmac = AT91C_BASE_EMAC;
	
	AT91F_RTC_InterruptDisable(AT91C_BASE_RTC, 0x1f);
	AT91F_ST_DisableIt(AT91C_BASE_ST, 0xf);

	AT91C_BASE_ST->ST_PIMR = 328;	// 328/32768 S
//	*AT91C_PMC_IDR = 0xf0f;	//disabled in InitSDRAM(init.c)
//	printf("\nST_PIMR = 0x%08x\n", AT91C_BASE_ST->ST_PIMR);
//	AT91F_ST_EnableIt(AT91C_BASE_ST, AT91C_ST_PITS);
	
	//设置网口MAC地址,先使能EMAC时钟,启动linux前要设置好MAC地址.
	AT91F_EMAC_CfgPMC();
	pEmac->EMAC_SA1L = ((int)OurEmacAddr[2] << 24) | ((int)OurEmacAddr[3] << 16) | ((int)OurEmacAddr[4] << 8) | OurEmacAddr[5];
	pEmac->EMAC_SA1H = ((int)OurEmacAddr[0] << 8) | OurEmacAddr[1];
	
	//when set an irq handler, the irq will be disabled in AT91F_AIC_ConfigureIt,
	//so enable it after AT91F_AIC_ConfigureIt!!!
	AT91F_AIC_ConfigureIt (
		AT91C_BASE_AIC,							// AIC base address
		AT91C_ID_SYS,							// System peripheral ID
		AT91C_AIC_PRIOR_HIGHEST,				// Max priority
		AT91C_AIC_SRCTYPE_INT_LEVEL_SENSITIVE,	// Level sensitive
		SysIrqHandler );						// 将设置处理函数地址填入AIC_SVC[AT91C_ID_SYS]
	//使能系统中断(包括ST,DBGU等)
	AT91F_AIC_EnableIt(AT91C_BASE_AIC, AT91C_ID_SYS);
	
	MMU_EnableICache();
	
	downloadAddress = LINUX_KERNEL_ADDR;

/*	while(1) {	//读NAND FLASH 的BUSY脚状态
		if(AT91F_PIO_GetInput(AT91C_BASE_PIOC)&AT91C_PIO_PC14)
			putch('1');
		else
			putch('0');
		delay(100);	
	}*/
	
/*	while(1) {
		delay(300);
		putch('a');
	}*/	
	
	puts("\n*********************************************\n");
	//puts("*                                           *\n");
	puts("*           BIOS For AT91RM9200             *\n");
	//puts("*                                           *\n");
	puts("*********************************************\n");

	//get counter from CKGR_MCFR
	//printf("Set Processor Clock = %dHz \nMaster Clock = %dHz\n", 
	//		AT91F_PMC_GetProcessorClock(AT91C_BASE_PMC, AT91C_BASE_CKGR, 32768), 
	//		AT91F_PMC_GetMasterClock(AT91C_BASE_PMC, AT91C_BASE_CKGR, 32768));
			
	InitPio();
	InitTwi();
	InitNorFlash();
//	InitNandFlash();

	InitSDRAM();
	puts("1\n");
	TestSDRAM();
	puts("2\n");
	
	
	while(timeout--)
	{
		int key_status;
		key_status=GetKeyStatus();
		if((key_status==1)||(key_status==2)||(key_status==3)||(key_status==4))
		{
			bootflag=2;
			break;
		}

	}
//	if(bootflag==1)
	{
//		FindNandBoot();
	}
	
	while(1) {
		U16 i;
		U8 c;
		
		puts("Select\n");
		for(i=0; Functions[i].FuncAddr; i++)
			printf("%d : %s\n", i, Functions[i].str);
		putch('\n');	
		c = getch();
		if((c>='0')&&(c<('0'+i)))
			(*Functions[c-'0'].FuncAddr)(downloadAddress, downloadFileSize);
	}
}

static volatile U8 *RxTmp;

void DBGU_Rx_Isr(void)
{
	//读完状态寄存器后才清掉中断源
	unsigned int csr = (((AT91PS_USART)AT91C_BASE_DBGU)->US_CSR & ((AT91PS_USART)AT91C_BASE_DBGU)->US_IMR);
	if (csr & AT91C_US_RXRDY) {
		*RxTmp = AT91F_US_GetChar((AT91PS_USART) AT91C_BASE_DBGU);
//		putch(*RxTmp);
		RxTmp++;
	}
}

U32 WaitComDownload(void);

void ComDownload(U32 a1, U32 a2)
{
	if(WaitComDownload())
		return;
	start_kernel(downloadAddress, 0);
/*	U8 sel;

	puts("Select\n1: Kernel\n2: initrd\n3: boot\nEsc: exit\n");
	while(1) {
		sel = getch();
		if(sel=='1') {
			downloadAddress = LINUX_KERNEL_ADDR;
			break;
		}
		if(sel=='2') {
			downloadAddress = INITRD_START;
			break;
		}
		if(sel=='3') {
			downloadAddress = BOOT_PORG_ADDR;
			break;
		}
		if(sel==0x1b)
			return;
	}
	
	if(WaitComDownload())
		return;
	
	if(sel=='2')
		return;
	
	if(sel=='3')
		start_kernel(downloadAddress, 0);
		
	puts("Do you want to run it ?\n1: boot without initrd\n2: boot wiht initrd\nEsc: exit\n");
	while(1) {
		char c = getch();
		if(c==0x1b)
			break;
		if((c=='1')||(c=='2'))
			start_kernel(downloadAddress, (c=='1')?0:INITRD_START);
	}
*/
}
/*
void RunProg(U32 addr, U32 size)
{
	start_kernel(downloadAddress, 0);
}*/

void Program_eep(U32 addr, U32 size)
{
#ifdef	IIC_SUPPORT
	char *pdata;
	U32 eep_addr;
	int bytes, len;
	U32 loop;
	char data[EEP_RW_CHK_CNT];
	
	eep_addr = 0;
	pdata = (char *)addr;
	len = size;

	while(len>0) {
		putchar('.');
		bytes = (len>EEP_RW_CHK_CNT)?EEP_RW_CHK_CNT:len;
		AT91F_TWI_Write(AT91C_BASE_TWI, eep_addr, pdata, bytes);
		eep_addr += bytes;
		pdata += bytes;
		len -= bytes;				
		//for (loop=0; loop<30000; loop++);
		delay(5);
	}
	puts("end\n");
	
	eep_addr = 0;
	pdata = (char *)addr;
	len = size;
	
	while(len) {
		bytes = (len>EEP_RW_CHK_CNT)?EEP_RW_CHK_CNT:len;
		AT91F_TWI_Read(AT91C_BASE_TWI, eep_addr, data, bytes);
		for(loop=0; loop<bytes; loop++)
			if(data[loop]!=pdata[loop]) {
				puts("Program EEPROM fail!\n");
				printf("%x,%x\n", loop, data[loop]);
				return;
			}
		eep_addr += bytes;
		pdata += bytes;
		len -= bytes;
	}
	puts("Program EEPROM Success!\n");
#endif	
}

U32 WaitComDownload(void)
{
	U32 size;
	U16 dnCS, CheckSum;
	U8 *buf;

	puts("Now download file from uart0...\n");
	buf    = (U8 *)downloadAddress;
	RxTmp  = buf-4;
	
	//设置调试串口中断处理程序入口,使能属于调试串口的子中断
	DbguIrqHandler = DBGU_Rx_Isr;
	AT91F_US_EnableIt((AT91PS_USART) AT91C_BASE_DBGU, (AT91C_US_RXRDY | AT91C_US_OVRE | AT91C_US_FRAME | AT91C_US_PARE));
	
	while((U32)RxTmp<(U32)buf) {
		ShowLed(0);
		delay(80);
		ShowLed(15);
		delay(80);
    }							//接收文件长度,4 bytes
   	size = *(U32 *)(buf-4);
	downloadFileSize = size-6;
	printf("Download File Size = %d\n", size);

	while(((U32)RxTmp-(U32)buf)<(size-4)) {
		ShowLed(0);
		delay(80);
		ShowLed(15);
		delay(80);
	}
	
	AT91F_US_DisableIt((AT91PS_USART) AT91C_BASE_DBGU, (AT91C_US_RXRDY | AT91C_US_OVRE | AT91C_US_FRAME | AT91C_US_PARE));
	DbguIrqHandler = NULL;
	
	dnCS = (buf[downloadFileSize+1]<<8)|buf[downloadFileSize];
	CheckSum = 0;
	for(size=0; size<downloadFileSize; size++)
		CheckSum += buf[size];
	if(dnCS!=CheckSum) {
		puts("\nCheckSum error!\n");
		return 1;
	}
	
	puts("\nDwonload success\n");
	return 0;	
}

⌨️ 快捷键说明

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