📄 sst39vf160.c
字号:
#include "../inc/def.h"
#include "../inc/config.h"
#include "../inc/utils.h"
#include "../inc/board.h"
#ifdef SST39VF160_SUPPORT
//#define ROM_BASE 0x10000000 //地址重定向到0x10000000
#define CMD_ADDR0 *((volatile U16 *)(0x5555*2+ROM_BASE))
#define CMD_ADDR1 *((volatile U16 *)(0x2aaa*2+ROM_BASE))
#define CHECK_DELAY 150000
static U16 state;
static U16 support;
static U32 chip_id;
static void CFIQueryExit(void)
{
outportw(0xaaaa, ROM_BASE+0xaaaa);//CMD_ADDR0 = 0xaaaa;
outportw(0x5555, ROM_BASE+0x5554);//CMD_ADDR1 = 0x5555;
outportw(0xf0f0, ROM_BASE+0xaaaa);//CMD_ADDR0 = 0xf0f0;
state &= 0xfc;
}
static void SWPIDExit(void)
{
outportw(0xf0f0, ROM_BASE+0xaaaa);//CMD_ADDR0 = 0xf0f0;
state &= 0xfc;
}
/*
static void CFIQueryEntry(void)
{
if(state&1)
{
if(state&2)
SWPIDExit();
else
return;
}
outportw(0xaaaa, ROM_BASE+0xaaaa);//CMD_ADDR0 = 0xaaaa;
outportw(0x5555, ROM_BASE+0x5554);//CMD_ADDR1 = 0x5555;
outportw(0x9898, ROM_BASE+0xaaaa);//CMD_ADDR0 = 0x9898;
state |= 1;
}*/
static void SWPIDEntry(void)
{
if(state&1)
{
if(state&2)
return;
else
CFIQueryExit();
}
outportw(0xaaaa, ROM_BASE+0xaaaa);//CMD_ADDR0 = 0xaaaa;
outportw(0x5555, ROM_BASE+0x5554);//CMD_ADDR1 = 0x5555;
outportw(0x9090, ROM_BASE+0xaaaa);//CMD_ADDR0 = 0x9090;
state |= 3;
}
static U32 GetFlashID(void)
{
U32 i;
SWPIDEntry();
//i = *(U16 *)(0x0+ROM_BASE);
//i |= (*(U16 *)(2+ROM_BASE))<<16;
i = inportw(ROM_BASE);
i |= inportw(ROM_BASE+2)<<16;
SWPIDExit();
i = 0x234b00bf;
return i; //修改 return i; 0x234b00bf
}
/*
static void GetFlashCFI(U16 *DataPtr)
{
U16 i;
CFIQueryEntry();
for(i = 0x10; i<0x35; DataPtr++, i++)
*DataPtr = *(U16 *)(i*2+ROM_BASE);
CFIQueryExit();
}
static void ChipErase(void)
{
if(state&1)
{
if(state&2)
SWPIDExit();
else
CFIQueryExit();
}
CMD_ADDR0 = 0xaaaa;
CMD_ADDR1 = 0x5555;
CMD_ADDR0 = 0x8080;
CMD_ADDR0 = 0xaaaa;
CMD_ADDR1 = 0x5555;
CMD_ADDR0 = 0x1010;
while(1)
{
U16 i;
i = *((volatile U16 *)0x6666)&0x40;
if(i!=*((volatile U16 *)0x6666)&0x40) //D6 == D6
continue;
if(*((volatile U16 *)0x8888)&0x80)
break; //D7 == 1
}
}*/
/*
static U32 ChkAddr;
static int ChkD6Stat(void)
{
return ((inportw(ChkAddr)^inportw(ChkAddr))&0x40);
}*/
static int SectorErase(U32 sector)
{
U32 tm, d1 ,d2;
if(state&1) {
if(state&2)
SWPIDExit();
else
CFIQueryExit();
}
sector += ROM_BASE;
//CMD_ADDR0 = 0xaaaa;
//CMD_ADDR1 = 0x5555;
//CMD_ADDR0 = 0x8080;
//CMD_ADDR0 = 0xaaaa;
//CMD_ADDR1 = 0x5555;
outportw(0xaaaa, ROM_BASE+0xaaaa);
outportw(0x5555, ROM_BASE+0x5554);
outportw(0x8080, ROM_BASE+0xaaaa);
outportw(0xaaaa, ROM_BASE+0xaaaa);
outportw(0x5555, ROM_BASE+0x5554);
outportw(0x3030, sector);
d2 = inportw(sector);
tm = CHECK_DELAY;
while(1) {
tm--;
if(!tm)
return -1;
d1 = d2;
d2 = inportw(sector);
if((d1^d2)&(1<<6)) { //D6 == D6
//tm--;
//if(!tm)
// return -1;
continue;
}
// if(*((volatile U16 *)sector)&0x80) { //D7 == 1
if(inportw(sector)==0xffff) {
// printf("tm=%d\n", tm);
return 0;
}
/* ChkAddr = sector;
if(!WaitEventWithTimeout(ChkD6Stat, 0, 10)) {
if(inportw(sector)==0xffff)
return 0;
}
return -1;*/
}
/* __asm {
CheckAgn:
subs tm, tm, #1
beq CheckEnd
ldr d1, [sector]
ldr d2, [sector]
eor d1, d1, d2
tst d1, #0x40
bne CheckAgn
ldr d1, [sector]
tst d1, #80
beq CheckAgn
CheckEnd:
}
// printf("tm=%d\n", tm);
return tm?0:-1;*/
}
static int FlashProg(U32 ProgStart, U16 *DataPtr, U32 WordCnt)
{
ProgStart += ROM_BASE;
for( ; WordCnt; ProgStart+=2, DataPtr++, WordCnt--) {
U32 tm;
// CMD_ADDR0 = 0xaaaa;
// CMD_ADDR1 = 0x5555;
// CMD_ADDR0 = 0xa0a0;
// *(volatile U16 *)ProgStart = *DataPtr;
outportw(0xaaaa, ROM_BASE+0xaaaa);
outportw(0x5555, ROM_BASE+0x5554);
outportw(0xa0a0, ROM_BASE+0xaaaa);
outportw(*DataPtr, ProgStart);
tm = CHECK_DELAY;
while(1) {
if((inportw(ProgStart)^inportw(ProgStart))&(0x40)) { //D6 == D6
tm--;
if(!tm)
return -1;
continue;
}
// if((*(volatile U16 *)ProgStart&0x80)==(*DataPtr&0x80))
if(inportw(ProgStart)==*DataPtr)
break; //D7 == D7
tm--;
if(!tm)
return -1;
/* ChkAddr = ProgStart;
if(WaitEventWithTimeout(ChkD6Stat, 0, 10))
return -1;
if(inportw(ProgStart)==*DataPtr)
break;*/
}
}
return 0;
}
/******************************************************************************
【功能说明】从指定扇区begin开始,将size个来自指针data的数据编程到Flash
******************************************************************************/
void NorFlashProg(U32 dst, U32 src, U32 size)
{
char buf[0x1000];
U32 tmp = 0x1000-(dst&0xfff);
int err;
if(support) {
if((dst>ROM_SIZE)||(dst&1)) {
printf("Invalid flash address, the address is from 0~0x%x, 16Bits aligned\n", ROM_SIZE);
return;
}
if(tmp>size)
tmp = size;
if(tmp&1)
tmp++;
for(; size;) {
if(tmp<0x1000) {
NorFlashRead(buf, (dst&~0xfff), 0x1000);
memcpy(buf+(dst&0xfff), (char *)src, tmp);
} else {
memcpy(buf, (char *)src, 0x1000);
}
err = SectorErase(dst&~0xfff);
if(err) { //4K Bytes boudary
printf("\t\tErase 0x%x Fail!!!\n", dst&~0xfff);
return;
}
printf("Program 0x%x %s\n", dst&~0xfff, FlashProg(dst&~0xfff, (U16 *)buf, 0x1000>>1)?"\tFail!!! Error!!!":"Ok");
size -= tmp;
dst += tmp;
src += tmp;
tmp = (size>0x1000)?0x1000:size;
}
}
return;
}
//*****************************************************************************
void NorFlashInit(void)
{
chip_id = GetFlashID();
// support = 0;
// if( (chip_id==0x278200bf)||(chip_id==0x22c400c2)||(chip_id==0x234b00bf) )
support = 1;
}
void NorFlashStatusRep(void)
{
// outportw(0xaaaa, ROM_BASE+0xaaaa);//CMD_ADDR0 = 0xaaaa;
//printf("%x,%x\n", ROM_BASE+0xaaaa, inportw(ROM_BASE+0xaaaa));
// outportw(0x5555, ROM_BASE+0x5554);//CMD_ADDR1 = 0x5555;
//printf("%x,%x\n", ROM_BASE+0x5554, inportw(ROM_BASE+0x5554));
// outportw(0x9090, ROM_BASE+0xaaaa);//CMD_ADDR0 = 0x9090;
//printf("%x,%x\n", ROM_BASE+0xaaaa, inportw(ROM_BASE+0xaaaa));
// chip_id = inportw(ROM_BASE);
// chip_id |= inportw(ROM_BASE+2)<<16;
// outportw(0xf0f0, ROM_BASE+0xaaaa);//CMD_ADDR0 = 0xf0f0;
printf("Nor Flash ID is : %x\n", chip_id);
if(support) {
if(chip_id==0x278200bf)
printf("SST39VF160 Found\n");
if(chip_id==0x234b00bf)
printf("SST39VF1601 Found\n");
if(chip_id==0x22c400c2)
printf("MX29LV160 Found\n");
if(chip_id==0x22490001)
printf("AMD29LV160DB Found\n");
} else
printf("Unknown Flash Type\n");
}
//全局变量初始化
//void (*pNorFlashInit)(void) = NorFlashInit;
//void (*pNorFlashProg)(U32, U32, U32) = NorFlashProg;
#endif
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -