📄 sst39vf1601.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 + -