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

📄 sst39vf1601.c

📁 杭州立宇泰ARMsys-P型ARM开发板BIOS代码
💻 C
字号:
/****************************************************************
 *		ARMSYS7 S3C44B0X developer's notes						*  
 ****************************************************************

 1. 2005.5.20:ZXJ:
 
 ***************************************************************/

#include "..\inc\def.h"
#include "..\inc\config.h"
#include "..\inc\utils.h"
#include "..\inc\flashrom.h"
#include "..\inc\board.h"

#ifdef	SST39VF1601_SUPPORT

#define	CHECK_DELAY	150000

static U32 flashrom_id; 
static U16 state;
static U16 NorF_support;

//
int FlashProg(U32 ProgStart, U32 DataPtr, U32 WordSize)
{
	int i;
	U16 temp, *ramaddress;
	ramaddress =(U16 *)DataPtr;
	
	if(ProgStart<SIZE_64K) 
	{
		printf("Invalid flash address, the address is from 0x10000~0x%x, 16Bits aligned\n", ROM_SIZE);
		return 1;
	}
	
	for(i=ProgStart;i<(ProgStart+WordSize);i++)
	{
		if((Flash_WordProg(i,(*ramaddress)))==0)
		{
			ramaddress +=1;			      	
		}
		else
		{
			printf("ProgAddr=0x%x,Write Error",i);
			return i;
		}
		i++;
	}
	printf("\nWrite end! Begin to Verify... ");
	ramaddress = (U16 *)DataPtr; 
    for(i=ProgStart;i<(ProgStart+WordSize);i++)
    {
           		
	    temp = Readflash(i);
	    if(temp!= *ramaddress)
	    {
	    	printf("\nProgAddr=0x%x,Value = 0x%4x Verify Error!",i,temp);	      
			return i;//break;
		}
		ramaddress +=1;
		i++;
	}
	printf("\nVerify OK!");
	return 0;	
}

static void CFIQueryExit(void)
{
	outportw(0xaaaa, ROM_BASE+0xaaaa);	//CMD_ADDR: 0x5555;
	outportw(0x5555, ROM_BASE+0x5554);	//CMD_ADDR: 0x2aaa;
	outportw(0xf0f0, ROM_BASE+0xaaaa);	//CMD_ADDR: 0x5555;
	state &= 0xfc;	
}

void SWPIDExit(void)
{
	outportw(0xf0f0, ROM_BASE+0xaaaa);	//CMD_ADDR0: 0x5555;
	state &= 0xfc;
}

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

	outportw(0xaaaa, ROM_BASE+0xaaaa);	//CMD_ADDR: 0x5555;
	outportw(0x5555, ROM_BASE+0x5554);	//CMD_ADDR: 0x2aaa;
	outportw(0x9090, ROM_BASE+0xaaaa);	//CMD_ADDR: 0x5555;
	state |= 3;
}

U32 GetFlashID(void)
{
	U32 i;
	NorF_support = 0;
			
	SWPIDEntry();
	i  = inportw(ROM_BASE);
	i |= inportw(ROM_BASE+2)<<16;
	SWPIDExit();
	
	if( (i==0x234b00bf)||(i==0x235b00bf)||(i==0x236b00bf) )
		NorF_support = 1;
		
	return i;	
}

void NorFlashStatusRep(void)
{
	flashrom_id = GetFlashID();
	printf("Nor Flash  : ");
	if(NorF_support) 
	{		
		if(flashrom_id==0x234b00bf)
			printf("SST39VF1601,  Size: 2MByte\n");
		if(flashrom_id==0x235b00bf)
			printf("SST39VF3201,  Size: 4MByte\n");
		if(flashrom_id==0x236b00bf)
			printf("SST39VF3201,  Size: 8MByte\n");
	} 
	else
		printf("Unknown Flash Type! Nor Flash ID is: 0x%x\n", flashrom_id);
}

int Flash_CheckBlank(U32 addr, U32 WordSize) 
{
	U32 i;
	unsigned short temp;
	
	for (i=addr;i<(addr+WordSize);i++)
	{
		temp=Readflash(i);		//*((volatile U16 *)(i<<1));
		if(temp!=0xffff)
		{
			printf("\nCheck is not empty ,this V=0x%x",temp);
			printf("\nCheck is not empty at 0x%x! Abort the program!",i);
			return i;
		}
		i++;
	}
	return 0;	
}

int Wait_endofprg(void) 	//Check if the bit6 toggle ends.
{
	volatile U16 flashStatus,old;
	old=(*((volatile U16 *)0x0));

	while(1)
	{	
		
		flashStatus=(*((volatile U16 *)0x0));
		if( (old & 0x40) == (flashStatus & 0x40) )  //Does DQ6 mach? 
			break;
		else
			old =(*((volatile U16 *)0x0));
	}
	return 0;
}


int Flash_WordProg (U32 addr,U16 dat)
{
	U32 tm;
	
	addr += ROM_BASE;
	outportw(0xaaaa, ROM_BASE+0xaaaa);	//CMD_ADDR: 0x5555;
	outportw(0x5555, ROM_BASE+0x5554);	//CMD_ADDR: 0x2aaa;
	outportw(0xa0a0, ROM_BASE+0xaaaa);	//CMD_ADDR: 0x5555;
	outportw(dat,    addr);
		
	tm = CHECK_DELAY;
	while(1) 
	{			
		if((inportw(addr)^inportw(addr))&(0x40)) 
		{	//D6 == D6
			tm--;
			if(!tm)
				return -1;
			continue;
		}
		if(inportw(addr)==dat)
			break;					//D7 == D7
		tm--;
		if(!tm)
			return -1;					
		
	}
	
		
}

int  Flash_SectorErase(U32 SAaddr)		//size:   0K ->4KByte->8K	 ->12K    ->16K
{										//address:0x0->0x1000->0x2000->0x3000->0x4000
	U32 tm, d1 ,d2;
	
	SAaddr += ROM_BASE;
	
	outportw(0xaaaa, ROM_BASE+0xaaaa);	//CMD_ADDR: 0x5555;
	outportw(0x5555, ROM_BASE+0x5554);	//CMD_ADDR: 0x2aaa;
	outportw(0x8080, ROM_BASE+0xaaaa);	//CMD_ADDR: 0x5555;
	outportw(0xaaaa, ROM_BASE+0xaaaa);	//CMD_ADDR: 0x5555;
	outportw(0x5555, ROM_BASE+0x5554);	//CMD_ADDR: 0x2aaa;
	outportw(0x3030, SAaddr);	
	d2 = inportw(SAaddr);
	
	tm = CHECK_DELAY;
	while(1) 
	{
	
		tm--;
		if(!tm)
			return -1;
		
		d1 = d2;
		d2 = inportw(SAaddr);		
		
		if((d1^d2)&(1<<6)) 
		{	//D6 == D6
			
			continue;
		}

		if(inportw(SAaddr)==0xffff) 
		{
			return 0;
		}
		
	}
	
}

int  Flash_BlockErase(U32 BAaddr)		//size:   0K ->64KByte->128K   ->192K	->256K 
{	
	U32 tm, d1 ,d2;
	
	BAaddr += ROM_BASE;
	
	outportw(0xaaaa, ROM_BASE+0xaaaa);	//CMD_ADDR: 0x5555;
	outportw(0x5555, ROM_BASE+0x5554);	//CMD_ADDR: 0x2aaa;
	outportw(0x8080, ROM_BASE+0xaaaa);	//CMD_ADDR: 0x5555;
	outportw(0xaaaa, ROM_BASE+0xaaaa);	//CMD_ADDR: 0x5555;
	outportw(0x5555, ROM_BASE+0x5554);	//CMD_ADDR: 0x2aaa;
	outportw(0x5050, BAaddr);	
	d2 = inportw(BAaddr);
	
	tm = CHECK_DELAY;
	while(1) 
	{
	
		tm--;
		if(!tm)
			return -1;
		
		d1 = d2;
		d2 = inportw(BAaddr);		
		
		if((d1^d2)&(1<<6)) 
		{	//D6 == D6
			
			continue;
		}

		if(inportw(BAaddr)==0xffff) 
		{
			return 0;
		}
		
	}									//address:0x0->0x10000->0x20000->0x30000->0x40000
	
}

int Flash_NumSectorErase(U32 Staddr,U32 cont)		//实际擦除的是从Staddr开始cont*4Kbyte的空间
{
	U32 i,address,aa;
	if(Staddr < 0x10000)
		Staddr = 0x10000;
	if(cont < 1)
		return -1;
	address=Staddr & 0x1f0000;
	for(i=0;i<cont;i++)
	{
		//address=address + (1<<12);
		if(address > (ROM_SIZE - 0x1000))	//39vf1601的SIZE为2Mbyte
		{
			printf("\nThe Err Erase address is 0x%x\n",address);
			return address;
		}
		
		Flash_SectorErase(address);		//先把ProgStart后的32KWORD空间擦除			
		address=address + (1<<12);
	}
	printf("\nBegin 0x%x to 0x%x is erased!\n",Staddr & 0x1f0000,address);
	address=Staddr & 0x1f0000;
	aa=Flash_CheckBlank(address,cont<<12);
	if(aa !=0)
		{
			printf("\nThe Sector is not empty at 0x%x! Abort the program!\n",aa);
			return aa;
		}
		
	return 0;
}

int Flash_NumBlockErase(U32 Staddr,U32 cont)		//实际擦除的是从UAaddr开始cont*64Kbyte的空间
{
	U32 i,address,aa;
	if(Staddr < 0x10000)
		Staddr = 0x10000;
	if(cont < 1)
		return -1;
	address=Staddr & 0x1f0000;
	for(i=0;i<cont;i++)
	{
		//address=address + (1<<16);
		if(address > (ROM_SIZE - 0x10000))	//39vf1601的SIZE为2Mbyte
		{
			printf("\nThe Erase address is 0x%x\n",address);
			return address;
		}
		
		aa=Flash_BlockErase(address);		//先把ProgStart后的32KWORD空间擦除
		address=address + (1<<16);
	}
	
	printf("\nBegin 0x%x to 0x%x is erased!\n",Staddr & 0x1f0000,address);
	address=Staddr & 0x1f0000;	
	aa=Flash_CheckBlank(address,cont<<16);
	if(aa !=0)
	{
		printf("\nThe Block is not empty at 0x%x! Abort the program!\n",aa);
		return aa;
	}
	return 0;
}

void  Flash_ChipErase(void)
{
	outportw(0xaaaa, ROM_BASE+0xaaaa);	//CMD_ADDR: 0x5555;
	outportw(0x5555, ROM_BASE+0x5554);	//CMD_ADDR: 0x2aaa;
	outportw(0x8080, ROM_BASE+0xaaaa);	//CMD_ADDR: 0x5555;
	outportw(0xaaaa, ROM_BASE+0xaaaa);	//CMD_ADDR: 0x5555;
	outportw(0x5555, ROM_BASE+0x5554);	//CMD_ADDR: 0x2aaa;
	outportw(0x1010, ROM_BASE+0xaaaa);
	
    Wait_endofprg();
}

#endif

⌨️ 快捷键说明

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