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

📄 norflash.c

📁 LPC2220的Bootloader自己写的,和 周立功的模版实现完全不一样
💻 C
字号:
//***************************************************************
//  ARM BOOT ROUTE VER1.0@0x0C000000 for 44B0X release
//  bjwork2007@gmail.com
//  chenjun @ 2005-6-10
//***************************************************************


#include "..\inc\usart.h"
#include "..\inc\common.h"
#include "..\inc\NorFlash.h"

unsigned char state;

#if(NorFlash_Type==AT49BV162_3)
	void SetConfigReg(unsigned char mode)
	{
		    *((unsigned short *)CMD_ADDR0) = 0xaa;
			*((unsigned short *)CMD_ADDR1) = 0x55;
			*((unsigned short *)CMD_ADDR0) = 0xd0;
			*((unsigned short *)CMD_ADDR1) = mode & 0x1;
	}
#endif

void FlashRead(unsigned int ReadFlashStart, unsigned int SdramPrt, unsigned int Size)
{
	unsigned int i;
	unsigned int k;
	
	if(state&1)
	{
		if(state&2)
			ProductIDExit();
		else
			CFIQueryExit();						
	}
	k = 0;
	
	for(i=0;i<Size;i++)
	{			
		*((unsigned char *)SdramPrt+i) = *((unsigned char *)(ReadFlashStart+i));
		
        if ((((((i+1) * 100) / Size) % 10) == 0) && ((((i+1) * 100) / Size) != k))
		{	
			printf("...%d%%",(((i+1) * 100 ) / Size));
			k = (((i+1) * 100 ) / Size);	}		
	}
	putch('\n');
}

unsigned char FlashProg(unsigned int ReadFlashStart, unsigned int SdramPrt, unsigned int Size)
{
	unsigned char j,retry;
	unsigned int i;
	unsigned int k;
	unsigned short data,readdata;
	unsigned int addr;
	
	if(Size & 1)
		{Size++;}
			
	if(state&1)
	{
		if(state&2)
			ProductIDExit();
		else
			CFIQueryExit();						
	}
	
	k = 0;
	#if (NorFlash_Type==AT49BV162_3)
		SetConfigReg(0);
	#endif
	for(i=0;i<Size;i+=2)
	{
		data = *((unsigned short *)(SdramPrt+i));
		addr = ReadFlashStart+i;
		j = WordProg(addr,data);
		retry = 3;
	reread:
		readdata = *((unsigned short *)(addr));
		if(readdata != data)
		{
			if((readdata & data)==data)
			{
				j = WordProg(addr,data);	
			}
			if((retry--)==0)
			{
				printf("\nFlash program failed!stop at flash addr: %.6x sdram_data:%.4x,flash_data:%.4x\n",addr,data,readdata);
				return 1;
			}
			goto reread;	
		}
        if ((((((i+2) * 100) / Size) % 10) == 0) && ((((i+2) * 100) / Size) != k))
		{	
			printf("...%d%%",(((i+2) * 100 ) / Size));
			k = (((i+2) * 100 ) / Size);	
		}	
	}
	putch('\n');
	return j;
}

unsigned char WordProg(unsigned int tempadd,unsigned short tempdata)
{	
	unsigned char i;
	unsigned char j;
	unsigned int time_out;
	
	*((unsigned short *)CMD_ADDR0) = 0xaa;
	*((unsigned short *)CMD_ADDR1) = 0x55;
	*((unsigned short *)CMD_ADDR0) = 0xa0;
	*((unsigned short *)tempadd) = tempdata;	

	time_out = 8;
	for(;;)
	{
	start:
		i = (unsigned char)(*((unsigned char *)(tempadd)) & 0x40);
		j = (unsigned char)(*((unsigned char *)(tempadd)) & 0x40);
		if(i != j)		//D6 == D6
			{	goto start;}
		if((*((unsigned char *)(tempadd)) & 0x80) == (unsigned char)(tempdata & 0x80))	
			{	return 0;break;}					//D7 == D7
		if ((time_out--)==0)
			{	return 1;break;}	
	}
	return 0;
}

unsigned char DataPolling(unsigned int Address)
{
	unsigned char i,j;
	//test data polling
	//puts("Start Data Polling,Wait for...!\n");
	for(;;)
	{
		start:
			j = *((unsigned char *)Address);
			j &= 0x40;
			i = *((unsigned char *)Address);
			#if(NorFlash_Type==AT49BV162_3)
				if(j!=(i&0x40)){	//toggle
					if((i&0x28)!=0x28){
						goto start;}
					else{
						j = (*((unsigned char *)Address) & 0x40);
						i = (*((unsigned char *)Address) & 0x40);
						if(j!=i){	// toggle
							ProductIDExit();	
							return 1;}
						else{ // no toggle
							return 0;}	
					}
				}	//no toggle
				else{
					return 0;
				}
			#elif(NorFlash_Type==SST39VF160)
				if(j!=(i&0x40))	//toggle
					goto start;
				else
					return 0;
			#endif
	}	
}

unsigned char ChipErase(void)
{	
	unsigned char i;
	
	if(state&1)
	{
		if(state&2)
			ProductIDExit();
		else
			CFIQueryExit();						
	}
	
	//set configuration register @ 0x00	
	puts("Send ChipErase Cmd!\n");
	
	#if (NorFlash_Type==AT49BV162_3)
		SetConfigReg(0);
	#endif
	
    *((unsigned short *)CMD_ADDR0) = 0xaa;
	*((unsigned short *)CMD_ADDR1) = 0x55;
	*((unsigned short *)CMD_ADDR0) = 0x80;
    *((unsigned short *)CMD_ADDR0) = 0xaa;
	*((unsigned short *)CMD_ADDR1) = 0x55;
	*((unsigned short *)CMD_ADDR0) = 0x10;	

	puts("Start Data Polling,Wait for...");
	i = DataPolling(ROM_BASE);
	if(i)
	{	puts("\nErase failed!Pls check hardware!\n");	}
	else
	{	puts("Erase completely!\n");	}
	return i;
}

unsigned char SectorErase(unsigned int sector)
{
	if(state&1)
	{
		if(state&2)
			ProductIDExit();
		else
			CFIQueryExit();						
	}
	
	sector += ROM_BASE;	
	#if (NorFlash_Type==AT49BV162_3)
		SetConfigReg(0);
	#endif
	
    *((unsigned short *)CMD_ADDR0) = 0xaa;
	*((unsigned short *)CMD_ADDR1) = 0x55;
	*((unsigned short *)CMD_ADDR0) = 0x80;
    *((unsigned short *)CMD_ADDR0) = 0xaa;
	*((unsigned short *)CMD_ADDR1) = 0x55;
	*((unsigned short *)sector) = 0x30;
	
	return DataPolling(sector);
}

#if(NorFlash_Type==SST39VF160)
	unsigned char BlockErase(unsigned int Block)
	{
		if(state&1)
		{
			if(state&2)
				ProductIDExit();
			else
				CFIQueryExit();						
		}
		
		Block += ROM_BASE;	
		#if (NorFlash_Type==AT49BV162_3)
			SetConfigReg(0);
		#endif
		
	    *((unsigned short *)CMD_ADDR0) = 0xaa;
		*((unsigned short *)CMD_ADDR1) = 0x55;
		*((unsigned short *)CMD_ADDR0) = 0x80;
	    *((unsigned short *)CMD_ADDR0) = 0xaa;
		*((unsigned short *)CMD_ADDR1) = 0x55;
		*((unsigned short *)Block) = 0x50;
		
		return DataPolling(Block);
	}
#endif

#if(NorFlash_Type==AT49BV162_3)
	void EnterSingerPulseProgMode(void)
	{
		if(state&1)
		{
			if(state&2)
				ProductIDExit();
			else
				CFIQueryExit();						
		}

	    *((unsigned short *)CMD_ADDR0) = 0xaa;
		*((unsigned short *)CMD_ADDR1) = 0x55;
		*((unsigned short *)CMD_ADDR0) = 0x80;
	    *((unsigned short *)CMD_ADDR0) = 0xaa;
		*((unsigned short *)CMD_ADDR1) = 0x55;
	    *((unsigned short *)CMD_ADDR0) = 0xa0;
		
		puts("Enter SingerPulse Prog Mode!\n");
	}
#endif

#if(NorFlash_Type==AT49BV162_3)
	unsigned char SinglePulseByteProg(unsigned int tempadd,unsigned char tempdata)
	{
		*((unsigned short *)tempadd) = tempdata;
		return DataPolling(tempadd);
	}
#endif

#if(NorFlash_Type==AT49BV162_3)
	void SectorLock(unsigned int sector)
	{
		if(state&1)
		{
			if(state&2)
				ProductIDExit();
			else
				CFIQueryExit();						
		}

	    *((unsigned short *)CMD_ADDR0) = 0xaa;
		*((unsigned short *)CMD_ADDR1) = 0x55;
		*((unsigned short *)CMD_ADDR0) = 0x80;
	    *((unsigned short *)CMD_ADDR0) = 0xaa;
		*((unsigned short *)CMD_ADDR1) = 0x55;
	    *((unsigned short *)sector) = 0x60;
	}
#endif

void ProductIDEntry(void)
{
	if(state&1)
	{
		if(state&2)
			return;
		else
			CFIQueryExit();
	}

	*((unsigned short *)CMD_ADDR0) = 0xaa;
	*((unsigned short *)CMD_ADDR1) = 0x55;
	*((unsigned short *)CMD_ADDR0) = 0x90;
	
	state |= 3; //表示进入ProductID模式
}

void ProductIDExit(void)	
{
	*((unsigned short *)CMD_ADDR0) = 0xaa;
	*((unsigned short *)CMD_ADDR1) = 0x55;
	*((unsigned short *)CMD_ADDR0) = 0xf0;
	state &= 0xfc;	
}

void CFIQueryExit(void)	
{
	*((unsigned short *)CMD_ADDR0) = 0xf0;
	state &= 0xfc;
}

#if(NorFlash_Type==AT49BV162_3)
	void ProgPR(unsigned char PRA,unsigned char tempdata)
	{
		*((unsigned short *)CMD_ADDR0) = 0xaa;
		*((unsigned short *)CMD_ADDR1) = 0x55;
		*((unsigned short *)CMD_ADDR0) = 0xc0;
	    *((unsigned short *)PRA) = tempdata;
	}
#endif

#if(NorFlash_Type==AT49BV162_3)
	void LockPR(void)
	{
		*((unsigned short *)CMD_ADDR0) = 0xaa;
		*((unsigned short *)CMD_ADDR1) = 0x55;
		*((unsigned short *)CMD_ADDR0) = 0xc0;
	    *((unsigned short *)(0x80 * 2)) = 0x00;
	}
#endif

#if(NorFlash_Type==AT49BV162_3)
	unsigned char StatusBP(void)
	{
		*((unsigned short *)CMD_ADDR0) = 0xaa;
		*((unsigned short *)CMD_ADDR1) = 0x55;
		*((unsigned short *)CMD_ADDR0) = 0x90;
		return *((unsigned char *)(0x80*2));
	}
#endif

void CFIQueryEntry(void)	
{
	if(state&1)
	{
		if(state&2)
			ProductIDExit();
		else
			CFIQueryExit();
	}
#if(NorFlash_Type==SST39VF160)
	*((unsigned short *)CMD_ADDR0) = 0xaa;
	*((unsigned short *)CMD_ADDR1) = 0x55;
#endif
	*((unsigned short *)CMD_ADDR0) = 0x98;
	state |= 1;	//表示进入CFI模式
}

unsigned int GetFlashID(void)
{
	unsigned int i;
	
	if(state&1)
	{
		if(state&2)
			ProductIDExit();
		else
			CFIQueryExit();
	}
	i = 0;
	ProductIDEntry();
	i = *((unsigned short *)(0x0+ROM_BASE));
	i |= *((unsigned short *)(0x2+ROM_BASE)) << 16;
	ProductIDExit();
	return i;	
}

⌨️ 快捷键说明

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