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

📄 loadkernel.c

📁 一位大侠写的ARM7DTMI模拟器,功能强大,可以模拟按键,彩色液晶,触摸屏,中断,异常等ARM7内核模块和外设,其中包含了bootloader代码,可以用ADS直接编译,是您没有ARM硬件条件下学习
💻 C
字号:
/*
**BootLoader for simuCPU,you can only free use it for personal study purpose!
**www.MShowTec.com for more information.
**lmjx,Email:limiao@yeah.com,All Right Reserved.
**/

#include <stdio.h>

#define ASIC_BASE  	 	 	0x02000000
//SYSTEM MANAGER REGISTERS 
#define ARM7_SYSCFG	     	(ASIC_BASE+0x00)
#define ARM7_MEMMAP  	 	(ASIC_BASE+0x04)


// controller registers
#define ARM7_INTMODE 	 	(ASIC_BASE+0x40)
#define ARM7_INTPEND 	 	(ASIC_BASE+0x44)
#define ARM7_INTMASK 	 	(ASIC_BASE+0x48)
#define ARM7_INTOFFSET   	(ASIC_BASE+0x4c)
#define ARM7_INTROUTER		(ASIC_BASE+0x50)

// Timer Registers
#define ARM7_TMOD			(ASIC_BASE+0x80)
#define ARM7_TDATA			(ASIC_BASE+0x84)
#define ARM7_TRELOAD		(ASIC_BASE+0x88)
#define ARM7_TCNT			(ASIC_BASE+0x8c)

// UART Registers
#define ARM7_UCON			(ASIC_BASE+0xc0)
#define ARM7_USTAT			(ASIC_BASE+0xc4)
#define ARM7_UTXBUF			(ASIC_BASE+0xc8)
#define ARM7_URXBUF			(ASIC_BASE+0xcc)

//DEV Registers
#define	ARM7_LCDADDR		(ASIC_BASE+0x100)
#define ARM7_LCDDATA		(ASIC_BASE+0x104)

#define ARM7_TOUCHCON		(ASIC_BASE+0x108)
#define ARM7_TOUCHSTATE		(ASIC_BASE+0x10c)
#define ARM7_TOUCHBUF		(ASIC_BASE+0x110)

#define ARM7_KBDCON			(ASIC_BASE+0x120)
#define ARM7_KBDSTATE		(ASIC_BASE+0x124)
#define ARM7_KBDBUF			(ASIC_BASE+0x128)

#define ARM7_NANDDAT		(ASIC_BASE+0x140)
#define ARM7_NANDCMD		(ASIC_BASE+0x144)
#define ARM7_NANDADR		(ASIC_BASE+0x148)


void out(char*buf)
{
	int i = 0;
	while(buf[i]!= 0){
		*(unsigned long*)(ARM7_UTXBUF) = buf[i++];
	}
}

void int_kbd()
{
	char buf[20];
	unsigned char state,code;
	state = *(unsigned long*)ARM7_KBDSTATE & 0x03;
	code = *(unsigned long*)ARM7_KBDBUF & 0xff;
	sprintf(buf,"code=%02x ",code);
	out(buf);
	if(state == 0)
		out("Key down\r\n");
	if(state == 1)
		out("Key up\r\n");
	
}

void int_touch()
{
	char buf[20];
	unsigned char state,x,y;
	
	state = *(unsigned long*)ARM7_TOUCHSTATE & 0x03;
	x = *(unsigned long*)ARM7_TOUCHBUF & 0xff;
	y = ((*(unsigned long*)ARM7_TOUCHBUF)>>8) & 0xff;
	sprintf(buf,"x=%02x y=%02x ",x,y);
	out(buf);
	if(state == 0)
		out("Touch down\r\n");
	if(state == 1)
		out("Touch up\r\n");
	if(state == 2)
		out("Touch Move\r\n");	
	
}

void(* const Ext0InterruptRoutTableIRQ[])(void) = {
	0,
};

void(* const Ext1InterruptRoutTableIRQ[])(void) = {
	int_kbd,
	int_touch,
	0,
};

void int_ext0()
{
	unsigned short subIntNo;
	
	*(unsigned long*)ARM7_INTPEND &= ~0x01;
	subIntNo = *(unsigned long*)ARM7_INTROUTER & 0x0000ffff;
	Ext0InterruptRoutTableIRQ[subIntNo]();
}

void int_ext1()
{
	unsigned short subIntNo;
	
	*(unsigned long*)ARM7_INTPEND &= ~0x02;
	subIntNo = (*(unsigned long*)ARM7_INTROUTER>>16) & 0x0000ffff;
	Ext1InterruptRoutTableIRQ[subIntNo]();
	
}

void int_uarutTX()
{
	*(unsigned long*)ARM7_INTPEND &= ~0x04;	
	out("uarutTX\r\n");
}

void int_uarutRX()
{
	unsigned char code;
	char buf[20];
	*(unsigned long*)ARM7_INTPEND &= ~0x08;
	code = *(unsigned long*)ARM7_URXBUF;
	sprintf(buf,"tty input %02x\r\n",code);
	out(buf);
}

void int_timer()
{
	static unsigned char lvl = 0;
	int i,x,y;
	
	*(unsigned long*)ARM7_INTPEND &= ~0x10;
	out("timer\r\n");
	*(unsigned long*)ARM7_LCDADDR = 3;
	*(unsigned long*)ARM7_LCDDATA = lvl;
	lvl ++;
	if(lvl == 11)lvl = 0;
	
	//set CURX=0 
	*(unsigned long*)ARM7_LCDADDR = 1;
	*(unsigned long*)ARM7_LCDDATA = 0;
	//delay
	for(i=0;i<10;i++);
	//set  CURY=0
	*(unsigned long*)ARM7_LCDADDR = 1;
	*(unsigned long*)ARM7_LCDDATA = 0;
	//clear screen by red
	for(y=0;y<0xa0;y++){
		for(x=0;x<0x80;x++){
			*(unsigned long*)ARM7_LCDDATA = 0xf800;
		}
	}
	//update screen
	*(unsigned long*)ARM7_LCDADDR = 4;
	*(unsigned long*)ARM7_LCDDATA = 0;
}



void(* const InterruptRoutTableIRQ[])(void) = {
	int_ext0,
	int_ext1,
	int_uarutTX,
	int_uarutRX,
	int_timer,
	0,
};


unsigned char NandData[512],NandRedt[16],ReadChkData[512],ReadChkRedt[16];

void loadkernel()
{  
	int i,x,y;
	unsigned short NandId;
	char outbuf[40];
	
	Nand_ResetDevice();
	out("Nand_ResetDevice OK\r\n");
	
	NandId = Nand_ReadDevID();
	sprintf(outbuf,"NandFlash id = %04x\r\n",NandId);
	out(outbuf);
	
	for(i = 0;i<512;i++){
		NandData[i] = 0xaa;
	}
	
	for(i = 0;i<16;i++){
		NandRedt[i] = 0xbb;
	}

	Nand_WriteSector(31,NandData,NandRedt);
	Nand_WriteSector(32,NandData,NandRedt);
	
	Nand_ReadSector(31,ReadChkData,ReadChkRedt);
	for(i = 0;i<512;i++){
		if(NandData[i] != ReadChkData[i]){
			out("NandFlash Read/Write Data Error\r\n");
		}
	}
	
	for(i = 0;i<16;i++){
		if(NandRedt[i] != ReadChkRedt[i]){
			out("NandFlash Read/Write Redt Error\r\n");
		}
	} 
	
	memset(ReadChkRedt,0,16);
	
	Nand_ReadSectorRedt(31,ReadChkRedt);
	for(i = 0;i<16;i++){
		if(NandRedt[i] != ReadChkRedt[i]){
			out("NandFlash Read/Write Redt Error\r\n");
		}
	}
			
	for(i = 0;i<16;i++){
		NandRedt[i] = 0xcc;
	}
	Nand_WriteSectorRedt(32,NandRedt);
	
	Nand_ReadSectorRedt(32,ReadChkRedt);
	for(i = 0;i<16;i++){
		if(NandRedt[i] != ReadChkRedt[i]){
			out("NandFlash Read/Write Redt Error\r\n");
		}
	}

	Nand_BlockErase(0);
	out("Nand_BlockErase OK\r\n");

	//interrupt ctl
	*(unsigned long*)ARM7_INTMASK = 0;
	
	//timer
	*(unsigned long*)ARM7_TDATA = 100;
	*(unsigned long*)ARM7_TRELOAD = 100;
	*(unsigned long*)ARM7_TCNT = 0;
	*(unsigned long*)ARM7_TMOD = 3;
	
	//tty
	*(unsigned long*)ARM7_UCON = 1;
	 
	//LCD
	//128*160 RGB565 Normal display
	*(unsigned long*)ARM7_LCDADDR = 0;
	*(unsigned long*)ARM7_LCDDATA = 0x80|(0xa0<<8);
	//delay
	for(i=0;i<10;i++);
	//set CURX=0 
	*(unsigned long*)ARM7_LCDADDR = 1;
	*(unsigned long*)ARM7_LCDDATA = 0;
	//delay
	for(i=0;i<10;i++);
	//set  CURY=0
	*(unsigned long*)ARM7_LCDADDR = 1;
	*(unsigned long*)ARM7_LCDDATA = 0;
	//clear screen by red
	for(y=0;y<0xa0;y++){
		for(x=0;x<0x80;x++){
			*(unsigned long*)ARM7_LCDDATA = 0xf800;
		}
	}
	//update screen
	*(unsigned long*)ARM7_LCDADDR = 4;
	*(unsigned long*)ARM7_LCDDATA = 0;
	
	//KBD
	//kbd enable,use extInt1,subIntNO.=0
	*(unsigned long*)ARM7_KBDCON = 3;
	
	//Touch
	//touch enable,use extInt1,subIntNO.=1
	*(unsigned long*)ARM7_TOUCHCON = 0x103;
	
	
	for(;;);
	return;	
}

void InterruptHandler_IRQ()
{	
	InterruptRoutTableIRQ [*(unsigned long*)ARM7_INTOFFSET]();
}

⌨️ 快捷键说明

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