#include "config.h"
#define ROM_BASE 0x80083000 //0x8009C000
#define INROM_BASE 0x80008000
//#define ROM_BASE 0x8007D000+0x8000 //test //0x800B5000+0x8000 //地址重定向到 //数据区+显示字库区
#define CMD_BASE 0x80000000
#define CMD_ADDR0 *((volatile uint16 *)(0x5555*2+CMD_BASE)) //+ROM_BASE
#define CMD_ADDR1 *((volatile uint16 *)(0x2aaa*2+CMD_BASE)) //+ROM_BASE
#define FLASH_MAXCYCLES 100000 //100ms
uint8 write_flag;
uint8 state;
void CFIQueryExit(void)
{
CMD_ADDR0 = 0xaaaa;
CMD_ADDR1 = 0x5555;
CMD_ADDR0 = 0xf0f0;
state &= 0xfc;
}
void SWPIDExit(void)
{
CMD_ADDR0 = 0xf0f0;
state &= 0xfc;
}
void CFIQueryEntry(void)
{
if(state&1)
{
if(state&2)
SWPIDExit();
else
return;
}
CMD_ADDR0 = 0xaaaa;
CMD_ADDR1 = 0x5555;
CMD_ADDR0 = 0x9898;
state |= 1;
}
void SWPIDEntry(void)
{
if(state&1)
{
if(state&2)
return;
else
CFIQueryExit();
}
CMD_ADDR0 = 0xaaaa;
CMD_ADDR1 = 0x5555;
CMD_ADDR0 = 0x9090;
state |= 3;
}
uint32 GetFlashID(void)
{
uint32 i;
SWPIDEntry();
i = *(uint16 *)(0+ROM_BASE);
i |= (*(uint16 *)(2+ROM_BASE))<<16;
SWPIDExit();
return i;
}
void GetFlashCFI(uint16 *DataPtr)
{
uint16 i;
CFIQueryEntry();
for(i = 0x10; i<0x35; DataPtr++, i++)
*DataPtr = *(uint16 *)(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)
{
uint16 i;
i = *((volatile uint16 *)0x6666)&0x40;
if(i!=*((volatile uint16 *)0x6666)&0x40) //D6 == D6
continue;
if(*((volatile uint16 *)0x8888)&0x80)
break; //D7 == 1
}
}
*/
uint8 SectorErase(uint32 sector)
{
uint16 i;
uint32 FlashTimeOut;
uint32 flashSIntEnble;
/*if(state&1)
{
if(state&2)
SWPIDExit();
else
CFIQueryExit();
}*/
if(sector > (0x001ff000-(ROM_BASE-CMD_BASE)))
{
return 0;
}
flashSIntEnble = VICIntEnable;
VICIntEnClr = 0xffffffff;
if(write_flag == 1)
{
sector += ROM_BASE;
CMD_ADDR0 = 0xaaaa;
CMD_ADDR1 = 0x5555;
CMD_ADDR0 = 0x8080;
CMD_ADDR0 = 0xaaaa;
CMD_ADDR1 = 0x5555;
*(volatile uint16 *)sector = 0x3030;
FlashTimeOut = 0;
while (1)
{
FlashTimeOut++;
if(FlashTimeOut > FLASH_MAXCYCLES)
{
VICIntEnable = flashSIntEnble;
return 0;
}
i = *((volatile uint16 *)sector)&0x40;
if(i!=*((volatile uint16 *)sector)&0x40) //D6 == D6
continue;
if(*((volatile uint16 *)sector)&0x80)
break; //D7 == 1
}
}
else
{
VICIntEnable = flashSIntEnble;
return 0;
}
VICIntEnable = flashSIntEnble;
return 1;
}
/*******************************************************************
函数名称: uint8 FlashProg(uint32 ProgStart, uint16 *DataPtr, uint32 WordCnt)
函数功能: 编程地址
相关调用:
入口参数: ProgStart:编程的起始位置
DataPtr:要编程的数据指针
WordCnt:要写的长度
返 回 值: 1 成功
0 失败
备 注:
创建信息:
修改信息:
********************************************************************/
uint8 FlashProg(uint32 ProgStart, uint16 *DataPtr, uint32 WordCnt) //wordcnt 表示字长
{
uint16 i, j;
uint32 FlashTimeOut;
uint32 flashSIntEnble;
if(write_flag == 1)
{
flashSIntEnble = VICIntEnable;
VICIntEnClr = 0xffffffff;
ProgStart += ROM_BASE; //只能偶地址
for( ; WordCnt; ProgStart+=2, DataPtr++, WordCnt--)
{
j = *DataPtr;
CMD_ADDR0 = 0xaaaa;
CMD_ADDR1 = 0x5555;
CMD_ADDR0 = 0xa0a0;
*(volatile uint16 *)ProgStart = j;
FlashTimeOut = 0;
while (1)
{
FlashTimeOut++;
if(FlashTimeOut > FLASH_MAXCYCLES)
{
VICIntEnable = flashSIntEnble;
return 0;
}
i = *(volatile uint16 *)ProgStart&0x40;
if(i!=*(volatile uint16 *)ProgStart&0x40) //D6 == D6
continue;
if((*(volatile uint16 *)ProgStart&0x80)==(j&0x80)) //D7 == D7
break;
}
}
VICIntEnable = flashSIntEnble;
return 1;
}
else
{
return 0;
}
}
void FlashRead(unsigned int ReadStart, unsigned short *DataPtr, unsigned int Size) //size 表示要读出的字节长
{
int i;
// uint32 flashSIntEnble;
// flashSIntEnble = VICIntEnable;
// VICIntEnClr = 0xffffffff;
ReadStart += ROM_BASE;
for(i=0; i<Size/2; i++)
{
*(DataPtr+i) = *((unsigned short *)ReadStart+i); //只能偶地址
}
// VICIntEnable = flashSIntEnble;
}
void InFlashRead(unsigned int ReadStart, unsigned short *DataPtr, unsigned int Size) //size 表示要读出的字节长
{
int i;
// uint32 flashSIntEnble;
// flashSIntEnble = VICIntEnable;
// VICIntEnClr = 0xffffffff;
ReadStart += INROM_BASE;
for(i=0; i<Size/2; i++)
{
*(DataPtr+i) = *((unsigned short *)ReadStart+i); //只能偶地址
}
// VICIntEnable = flashSIntEnble;
}
/*******************************************************************
函数名称: uint8 SectorProg(uint32 begin, uint16 *data, uint32 size)
函数功能: 先擦后编程
相关调用:
入口参数: begin:编程的起始位置
DataPtr:要编程的数据指针
WordCnt:要写的长度
返 回 值: 1 成功
0 失败
备 注:
创建信息:
修改信息:
********************************************************************/
uint8 SectorProg(uint32 begin, uint16 *data, uint32 size) //size 表示要写入的字节长
{
uint32 flashSIntEnble;
uint32 tmp = 0x1000-(begin&0xfff);
flashSIntEnble = VICIntEnable;
VICIntEnClr = 0xffffffff;
if(write_flag == 1)
{
if(tmp>size)
tmp = size;
for(; size;)
{
if(0 == SectorErase(begin&0xfffff000)) //4K Bytes boudary
{
VICIntEnable = flashSIntEnble;
return 0;
}
if(0 == FlashProg(begin, data, tmp/2))
{
VICIntEnable = flashSIntEnble;
return 0;
}
size -= tmp;
begin += tmp;
data += tmp/2;
tmp = (size>0x1000)?0x1000:size;
}
}
else
{
VICIntEnable = flashSIntEnble;
return 0;
}
VICIntEnable = flashSIntEnble;
return 1;
}