📄 norflash.c
字号:
#include "basic.h"
#include "Drivers\flash\NorFlash.h"
#define FLASH_START 0xf80000
#define TOP_BOOT 1
#define BOTTOM_BOOT 0
#if TOP_BOOT
const unsigned long SECTOR[] =
{
0x0,0x8000,0x10000,0x18000,0x20000,0x28000,0x30000,0x38000,0x3C000,0x3D000,0x3E000,0x40000
};
#elif BOTTOM_BOOT
const unsigned long SECTOR[] =
{
0x0,0x2000,0x3000,0x4000,0x8000,0x10000,0x18000,0x20000,0x28000,0x30000,0x38000,0x40000
}
#endif
//#define USE_ASM
//#ifndef USE_ASM
//#pragma section code bios_code
//#pragma section const bios_const
/*
function: short ByteWriteFlash(DWORD addr,DWORD len,BYTE *buf)
parameter: addr: write address len: read len buf: write buffer
return: 1:succeed 0:failure
remark: write the data into the address
addr:this is a byte address
*/
unsigned short ByteWriteFlash(DWORD addr,DWORD len,BYTE *buf)
{
unsigned long chip_addr=0;
unsigned short * address;
volatile unsigned short *p;
DWORD i,j;
WORD flag=OK;
WORD tmp;
BYTE dummy1, dummy2;
BYTE flag1=0, flag2=0;
DWORD index=0;
chip_addr=(unsigned long)FLASH_START;
p = (volatile unsigned short *)FLASH_START;
if( addr%2 )
{
address = (WORD*)(chip_addr+addr-1);
ByteReadFlash( addr-1, 1L, &dummy1 );
len++;
flag1 = 1;
}
else
{
address = (WORD*)(chip_addr+addr);
}
if(len%2 )
{
ByteReadFlash( addr+len, 1L, &dummy2 );
flag2 = 1;
len-=1;
}
if( flag1 )
{
tmp = (WORD)buf[index++]<<8;
tmp = (tmp&0xFF00)|(WORD)dummy1;
p[0x555] = 0xaa;
__asm("nop");
p[0x2AA] = 0x55;
__asm("nop");
p[0x555] = 0xa0;
__asm("nop");
*address = tmp;
__asm("nop");
__asm("nop");
for(j=0; j<0x10; j++);
flag = FlashDataToggle(address);
if(flag!=OK) return flag;
address++;
len-=2;
}
for(i=0;i<len;i=i+2)
{
tmp = (WORD)buf[index++]&0x00FF;
tmp |=(WORD)buf[index++]<<8;
p[0x555] = 0xaa;
__asm("nop");
p[0x2AA] = 0x55;
__asm("nop");
p[0x555] = 0xa0;
__asm("nop");
*address = tmp;
__asm("nop");
__asm("nop");
for(j=0; j<0x10; j++);
flag = FlashDataToggle(address);
if(flag!=OK) return flag;
address++;
}
if( flag2 )
{
tmp = (WORD)dummy2<<8;
tmp = (tmp&0xFF00)|(WORD)buf[index++];
p[0x555] = 0xaa;
__asm("nop");
p[0x2AA] = 0x55;
__asm("nop");
p[0x555] = 0xa0;
__asm("nop");
*address = tmp;
__asm("nop");
__asm("nop");
for(j=0; j<0x10; j++) ;
flag = FlashDataToggle(address);
if(flag!=OK) return flag;
}
FlashReset();//reset the chip
return OK;
}
/*
function: short ByteReadFlash(DWORD addr,DWORD len,BYTE *buf)
parameter: addr: read address len: read len buf: read buffer
return: 1:succeed 0:failure
remark: read the data from the address
addr:this is a byte address
*/
unsigned short ByteReadFlash(DWORD addr,DWORD len,BYTE *buf)
{
unsigned long i;
unsigned long chip_addr=0;
volatile unsigned short * address;
register tmp;
BYTE flag1=0;
BYTE flag2=0;
chip_addr=(unsigned long)FLASH_START;
if(addr%2)
{
address = (volatile unsigned short *)(chip_addr+addr-1);
flag1 = 1;
tmp = *address++;
*buf++ = (BYTE)((tmp>>8)&0x00FF);
len-=1;
}
else
{
address = (volatile unsigned short *)(chip_addr+addr);
}
if( len%2 )
{
flag2 = 1;
len-=1;
}
for(i=0;i<len;i=i+2)
{
*((unsigned short *)buf)=*address++;
buf+=2;
}
if(flag2)
{
*buf++ = (BYTE)(*address&0x00FF);
}
return OK;
}
//#endif //#ifndef USE_ASM
/*
function: WordReadFlash(DWORD addr,DWORD len,WORD *buf)
parameter: addr: read address len: read len buf: read buffer
return: 1:succeed 0:failure
remark: read the data from the address
addr:this is a word address
*/
unsigned short WordReadFlash(DWORD addr,DWORD len,WORD *buf)
{
volatile unsigned short * address;
DWORD i;
address = (volatile unsigned short *)FLASH_START;
address += addr;
for(i=0;i<len;i++)
{
*buf = *address;
address++;
buf++;
}
return OK;
}
/*
function: short WordWriteFlash(DWORD addr,DWORD len,WORD *buf)
parameter: addr: write address len: read len buf: write buffer
return: 1:succeed 0:failure
remark: write the data into the address
addr:this is a word address
*/
unsigned short WordWriteFlash(DWORD addr,DWORD len,WORD *buf)
{
volatile unsigned short * p;
volatile unsigned short * address;
short flag;
DWORD i,j;
unsigned char value=0;
p = (volatile unsigned short *)FLASH_START;
address = p + addr;
for(i=0;i<len;i++)
{
p[0x555] = 0xaa;
__asm("nop");
p[0x2AA] = 0x55;
__asm("nop");
p[0x555] = 0xa0;
__asm("nop");
*address = *buf;
__asm("nop");
__asm("nop");
buf++;
address++;
for(j=0; j<0x10; j++);
flag = FlashDataToggle(address);
if(flag!=OK) return flag;
}
FlashReset();//reset the chip
return OK;
}
unsigned short ReadDeviceCode(void)
{
volatile unsigned short * p;
unsigned short manu_id,device_id;
p = (volatile unsigned short *)FLASH_START;
p[0x555] = 0xaa;
__asm("nop");
p[0x2AA] = 0x55;
__asm("nop");
p[0x555] = 0x90;
__asm("nop");
//manu_id = p[0x00];
//__asm("nop");
device_id = p[0x01];
__asm("nop");
p[0x00] = 0xf0;
return device_id;
}
/*
function: void FlashReset()
parameter: None
return: None
remark: reset the chip
*/
void FlashReset(void)
{
volatile unsigned short * p;
p=(volatile unsigned short *)FLASH_START;
*p=0xf0;
}
/*
function: short EraseBlock3(unsigned long addr )
parameter: addr: address
return: None
remark: Erase the block
this is a word address
*/
unsigned short EraseBlock(DWORD addr)
{
volatile unsigned short *p;
unsigned short i;
p = (volatile unsigned short *)FLASH_START;
p[0x555] = 0xaa;// First cycle
__asm("nop");
p[0x2AA] = 0x55;// Second cycle
__asm("nop");
p[0x555] = 0x80;// Third cycle
__asm("nop");
p[0x555] = 0xaa;// Fourth cycle
__asm("nop");
p[0x2AA] = 0x55;// Fifth cycle
__asm("nop");
p[addr] = 0x30; // Sixth cycle
__asm("nop");
__asm("nop");
for(i=0; i<0x20; i++) ;//delay
return FlashDataToggle(p+addr);
}
/*
function: short EraseChip()
parameter: None
return: 0:succeed 1:failure
remark: Erase the chip
*/
unsigned short EraseChip(void)
{
volatile unsigned short *p;
unsigned short i;
p = (unsigned short volatile *)FLASH_START;
p[0x555] = 0xaa;// First cycle
__asm("nop");
p[0x2AA] = 0x55;// Second cycle
__asm("nop");
p[0x555] = 0x80;// Third cycle
__asm("nop");
p[0x555] = 0xaa;// Fourth cycle
__asm("nop");
p[0x2AA] = 0x55;// Fifth cycle
__asm("nop");
p[0x555] = 0x10;// Sixth cycle
__asm("nop");
__asm("nop");
for(i=0; i<0x20; i++) ;//delay
return FlashDataToggle(p);
}
/*
function: short FlashErase(DWORD addr,DWORD len)
parameter: None
return: 0:failure 1:succeed
remark:
this is a word address
*/
unsigned short FlashErase(DWORD addr,DWORD len)
{
short i;
short rtn;
short SectorNum;
short StartSec,EndSec;
SectorNum = 12;//sizeof(SECTOR)/sizeof(unsigned long);
for(i=0; i< SectorNum ; i++)
{
if( addr<SECTOR[i] )
{
StartSec = i-1;
break;
}
}
if(i==SectorNum) return FAIL;
addr = addr + len -1;
for(i=0; i< SectorNum ; i++)
{
if( addr<SECTOR[i] )
{
EndSec = i-1;
break;
}
}
if(i==SectorNum) return FAIL;
for(i=StartSec;i<=EndSec;i++)
{
rtn = EraseBlock(SECTOR[i]);
if(rtn!=OK) return rtn;
}
return OK;
}
/*
function: short FlashDataToggle(volatile unsigned short * address)
parameter: None
return: 0:failure 1:succeed
remark: judge whether the program/erase operation complete
*/
unsigned short FlashDataToggle(volatile unsigned short * address)
{
unsigned short uc1,uc2;
while(1)
{
uc1 = *address;//read twice
__asm("nop");
uc2 = *address;
__asm("nop");
if((uc1&0x40)==(uc2&0x40))//if ToggleBit not togging,succeed
{
FlashReset();//reset the chip
return OK;
}
if((uc2&0x20)==0x20) break;//if d5 is 1?
}
uc1 = *address;//read twice
__asm("nop");
uc2 = *address;
__asm("nop");
if((uc1&0x40)==(uc2&0x40))//if ToggleBit not togging,succeed
{
FlashReset();//reset the chip
return OK;
}
FlashReset();
return FAIL;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -