📄 39vf160.c
字号:
#include "def.h"
#include "2410lib.h"
#ifdef _FLASH_TYPE_SST39VF_
//
// program norflash type SST39VF160x
//
#define ROM_BASE 0x08000000 //地址重定向到0x08000000
#define CMD_ADDR0 *((volatile U16 *)(0x5555*2+ROM_BASE))
#define CMD_ADDR1 *((volatile U16 *)(0x2aaa*2+ROM_BASE))
static U8 state = 0;
static void CFIQueryExit(void)
{
CMD_ADDR0 = 0xaaaa;
CMD_ADDR1 = 0x5555;
CMD_ADDR0 = 0xf0f0;
state &= 0xfc;
}
static void SWPIDExit(void)
{
CMD_ADDR0 = 0xf0f0;
state &= 0xfc;
}
static void CFIQueryEntry(void)
{
if(state&1)
{
if(state&2)
SWPIDExit();
else
return;
}
CMD_ADDR0 = 0xaaaa;
CMD_ADDR1 = 0x5555;
CMD_ADDR0 = 0x9898;
state |= 1;
}
static void SWPIDEntry(void)
{
if(state&1)
{
if(state&2)
return;
else
CFIQueryExit();
}
CMD_ADDR0 = 0xaaaa;
CMD_ADDR1 = 0x5555;
CMD_ADDR0 = 0x9090;
state |= 3;
}
U32 GetFlashID(void)
{
U32 i;
SWPIDEntry();
i = *(U16 *)(0+ROM_BASE);
i |= (*(U16 *)(2+ROM_BASE))<<16;
SWPIDExit();
return i;
}
void GetFlashCFI(U16 *DataPtr)
{
U16 i;
CFIQueryEntry();
for(i = 0x10; i<0x35; DataPtr++, i++)
*DataPtr = *(U16 *)(i*2+ROM_BASE);
CFIQueryExit();
}
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
}
}
void SectorErase(U32 sector)
{
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;
*(volatile U16 *)sector = 0x3030;
while(1)
{
U16 i;
i = *((volatile U16 *)sector)&0x40;
if(i!=*((volatile U16 *)sector)&0x40) //D6 == D6
continue;
if(*((volatile U16 *)sector)&0x80)
break; //D7 == 1
}
// printf("Erase sector 0x%x ok\n", sector-ROM_BASE);
}
void FlashProg(U32 ProgStart, U16 *DataPtr, U32 WordCnt)
{
U16 i, j;
ProgStart += ROM_BASE;
for( ; WordCnt; ProgStart+=2, DataPtr++, WordCnt--)
{
j = *DataPtr;
CMD_ADDR0 = 0xaaaa;
CMD_ADDR1 = 0x5555;
CMD_ADDR0 = 0xa0a0;
*(volatile U16 *)ProgStart = j;
while(1)
{
i = *(volatile U16 *)ProgStart&0x40;
if(i!=*(volatile U16 *)ProgStart&0x40) //D6 == D6
continue;
if((*(volatile U16 *)ProgStart&0x80)==(j&0x80))
break; //D7 == D7
}
}
}
void FlashRead(unsigned int ReadStart, unsigned short *DataPtr, unsigned int Size)
{
int i;
ReadStart += ROM_BASE;
for(i=0; i<Size/2; i++)
*(DataPtr+i) = *((unsigned short *)ReadStart+i);
}
int SectorProg(U32 begin, U16 *data, U32 size)
{
U32 tmp = 0x1000-(begin&0xfff);
if(tmp>size)
tmp = size;
for(; size;)
{
SectorErase(begin&0xfffff000); //4K Bytes boudary
FlashProg(begin, data, tmp/2);
printf("Program %x ok\n", begin);
size -= tmp;
begin += tmp;
data += tmp/2;
tmp = (size>0x1000)?0x1000:size;
}
return 0;
}
#else //_FLASH_TYPE_SST39VF_
//
// program norflash type AM29LV800BB
//
unsigned long rom_base = 0x08000000; //set to nGCS0 or nGCS1 when detected
#define CMD_ADDR(x) *((volatile U16 *)((x)*2+rom_base))
U32 GetFlashID(void)
{
U32 id;
// reset flash
CMD_ADDR(0) = 0x00F0;
// read id
CMD_ADDR(0x555) = 0x00AA;
CMD_ADDR(0x2aa) = 0x0055;
CMD_ADDR(0x555) = 0x0090;
id = (CMD_ADDR(0x001) & 0xffff);
// reset flash
CMD_ADDR(0) = 0x00F0;
return id;
}
void SectorErase(U32 SecAddr)
{
U32 Addr;
Addr = SecAddr & 0x7f000;
Addr /= 2;
// reset flash
CMD_ADDR(0) = 0x00F0;
CMD_ADDR(0x555) = 0x00AA;
CMD_ADDR(0x2aa) = 0x0055;
CMD_ADDR(0x555) = 0x0080;
CMD_ADDR(0x555) = 0x00AA;
CMD_ADDR(0x2aa) = 0x0055;
CMD_ADDR(Addr) = 0x0030;
// wait complete
while(!(CMD_ADDR(Addr) & (1<<7)))
;
// reset flash
CMD_ADDR(0) = 0x00F0;
}
void FlashProg(U32 ProgStart, U16 *DataPtr, U32 WordCnt)
{
U32 l;
U32 AddrNow;
if(ProgStart + WordCnt * 2 >= 0x100000) {
printf("FlashProg: exceed the limit of flash\n");
return;
}
// reset flash
CMD_ADDR(0) = 0x00F0;
AddrNow = ProgStart/2;
for(l = 0; l < WordCnt; ++l) {
// write program command
CMD_ADDR(0x555) = 0x00AA;
CMD_ADDR(0x2aa) = 0x0055;
CMD_ADDR(0x555) = 0x00A0;
CMD_ADDR(AddrNow) = *DataPtr;
// wait complete
while( (( CMD_ADDR(AddrNow)^(*DataPtr) ) & (1<<7)) )
;
++AddrNow;
++DataPtr;
}
// reset flash
CMD_ADDR(0) = 0x00F0;
}
int SectorProg(U32 begin, U16 *data, U32 size)
{
U32 blkAddr;
U32 blkSize, wsize;
U16 *start;
U16 *data1;
U32 len;
start = (U16*)(begin + rom_base);
data1 = data;
if(begin & 0xfff) {
printf("Flash program must be block alain\n");
return -1;
}
/* size must be odd */
if(size & 1)
++size;
len = size;
blkAddr = begin;
for( ; size > 0; ) {
switch(blkAddr) {
case 0:
blkSize = 0x4000;
break;
case 0x4000:
case 0x6000:
blkSize = 0x2000;
break;
case 0x8000:
blkSize = 0x8000;
break;
default:
blkSize = 0x10000;
break;
}
wsize = (size > blkSize) ? blkSize : size;
// printf("blkaddr=0x%x, data=0x%x, wsize=0x%x\n", blkAddr, (U32)data, wsize);
SectorErase(blkAddr);
FlashProg(blkAddr, data, wsize/2);
putch('.');
blkAddr += wsize;
data += (wsize/2);
size -= wsize;
}
printf("\nVerify...");
for( ; len > 1; len -= 2) {
if(*start != *data1) {
printf("error, addr=0x%x, flashdata=0x%x, memdata=0x%x\n",
(U32)start, *start, *data1);
break;
}
++start;
++data1;
}
if(len == 0)
printf("ok\n");
printf("\nFinish write nor flash\n");
return 0;
}
#endif
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -