分类: 嵌入式
2010-06-24 11:31:56
环境: C8051F360 + K9F120160A
注意16位NAND Flash的命令字只能从数据线的低8位送入,此时高8位为0.
void FlashWriteCmd_8(uint Cmd);
void FlashWriteAddr_8(uchar addr);
void FlashWriteData_8(uchar sdata);
void FlashWriteData_16(uint sdata);
void FlashReadPage_8(uint PageAddr,uchar *buf);
uchar FlashWritePage_8(uint PageAddr,uchar *buf);
void FlashReadPage_16(uchar ColAddr,uint PageAddr,uchar *buf,uint num);
uchar FlashWritePage_16(uchar ColAddr,uint PageAddr,uchar *buf,uint num);
uint FlashReadData_16();
uint FlashReadId(void);
uchar FlashEraseBlock(uint blockAddr);
uchar FlashReadStatus(void);
#define SetFlashRD() P3_4=1;
#define ClrFlashRD() P3_4=0;
#define ClrFlashWE() P3_3=0;
#define SetFlashWE() P3_3=1;
#define SetFlashWP() SetBit(P5,3) //写保护
#define SetFlashReady() SetBit(P5,4)
#define TestReady() TestBit(P5,4)
#define SetFlashCS() SetBit(P5,5)
#define SetFlashCLE() SetBit(P5,6)
#define SetFlashALE() SetBit(P5,7)
#define ClrFlashWP() ClrBit(P5,3) //写保护
#define ClrFlashReady() ClrBit(P5,4)
#define ClrFlashCS() ClrBit(P5,5)
#define ClrFlashCLE() ClrBit(P5,6)
#define ClrFlashALE() ClrBit(P5,7)
#define WaitReady() {while(!TestReady());}
/* nandflash command define */
#define NAND_READ0 0x00 //for 1st half array from 0-255 byte of the same page
#define NAND_READ2 0x50 //for spare array from 512-527 byte
#define NAND_READ_ID 0x90
#define NAND_RST 0xFF
#define NAND_PAGE_PROG_C1 0x80
#define NAND_PAGE_PROG_C2 0x10
#define NAND_BLOCKERASE_C1 0x60
#define NAND_BLOCKERASE_C2 0xD0
#define NAND_READSTATUS 0x70
void FlashWriteCmd_8(uint Cmd)
{
SetFlashRD();
ClrFlashCS();
SetFlashWP();//取消写保护
SetFlashCLE(); //command latch enable
ClrFlashALE(); //address latch disable
nop();
nop();
ClrFlashWE();
DataPortL=Cmd;
DataPortH=0x00;
SetFlashWE();
SetFlashCS();
}
void FlashWriteAddr_8(uchar addr)
{
SetFlashRD();
ClrFlashCS(); //选中FLASH 芯片
SetFlashWP();//取消写保护
SetFlashALE(); //address latch enable
ClrFlashCLE() ; //command latch disable
ClrFlashWE();
DataPortL=addr;
DataPortH=0x00;
SetFlashWE();
SetFlashCS();
}
void FlashWriteData_8(uchar sdata)
{
SetFlashRD();
ClrFlashCS();
SetFlashWP();//取消写保护
ClrFlashALE(); //address latch disable
ClrFlashCLE() ; //command latch disable
nop();
nop();
ClrFlashWE();
nop();
nop();
DataPortL=sdata;
DataPortH=0x24;
nop();
nop();
SetFlashWE();
SetFlashCS();
}
void FlashWriteData_16(uint sdata)
{
UWORD temp;
temp.UInt=sdata;
SetFlashRD();
ClrFlashCS();
SetFlashWP();//取消写保护
ClrFlashALE(); //address latch disable
ClrFlashCLE() ; //command latch disable
ClrFlashWE();
nop();
nop();
DataPortL=temp.UByte[1];
DataPortH=temp.UByte[0];
nop();
nop();
SetFlashWE();
SetFlashCS();
}
uchar FlashReadData_8()
{
uchar dat;
SetFlashWE();
ClrFlashCS();
SetFlashWP();//取消写保护
ClrFlashALE(); //address latch disable
ClrFlashCLE() ; //command latch disable
ClrFlashRD();
dat=DataPortL;
SetFlashRD();
SetFlashCS();
return dat;
}
uint FlashReadData_16()
{
uint dat;
SetFlashWE();
ClrFlashCS();
SetFlashWP();//取消写保护
ClrFlashALE(); //address latch disable
ClrFlashCLE() ; //command latch disable
SetFlashRD();
nop();
ClrFlashRD();
dat=DataPortH;
dat=((dat<<8)&0xff00);
dat|=DataPortL;
SetFlashRD();
SetFlashCS();
return dat;
}
uint FlashReadId(void) //K9F1216D0A K9F1216U0A **56H
//ec 56 a5 c0
{
uint deveceId=0x0000;
FlashWriteCmd_8(NAND_READ_ID);
FlashWriteAddr_8(0x00); //需要1个地址周期
// flashbuf[0]=FlashReadData_8();
// flashbuf[1]=FlashReadData_8();
// flashbuf[2]=FlashReadData_8();
// flashbuf[3]=FlashReadData_8();
return deveceId;
}
uchar FlashReadStatus(void)
{
uchar status=0x00;
FlashWriteCmd_8(NAND_READSTATUS);
status=FlashReadData_8();
return status;
}
/*******************************************
FlashEraseBlock是块擦除指令,一次擦除32个page.
*******************************************/
uchar FlashEraseBlock(uint blockAddr)
{
uchar status=0x00; //used for the result of erase
FlashWriteCmd_8(NAND_BLOCKERASE_C1);
//需要3个地址周期
FlashWriteAddr_8(blockAddr &0xff);
FlashWriteAddr_8((blockAddr>>8) &0xff);
FlashWriteAddr_8(0x00);
FlashWriteCmd_8(NAND_BLOCKERASE_C2);
WaitReady(); //wait util ready
status=0x01 & (FlashReadStatus()); //read status register IO0
return status; //when 0:OK ,1:error
}
void FlashReadPage_8(uint PageAddr,uchar *buf)
{
uint i; //used for the result of read
FlashWriteCmd_8(NAND_READ0);
FlashWriteAddr_8(0x00);
FlashWriteAddr_8(PageAddr &0xff);
FlashWriteAddr_8((PageAddr>>8) &0xff);
FlashWriteAddr_8(0x00);
WaitReady();
for(i=0;i<4;i++)
{
buf[i]= FlashReadData_8();
}
}
uchar FlashWritePage_8(uint PageAddr,uchar *buf)
{
uchar status=0x00;
uint i;
FlashWriteCmd_8(NAND_PAGE_PROG_C1);
FlashWriteAddr_8(0x00); //default col=0;
FlashWriteAddr_8(PageAddr &0xff); //write pageaddrL
FlashWriteAddr_8((PageAddr>>8) &0xff); //write pageaddrH
FlashWriteAddr_8(0x00);
for(i=0;i<4;i++)
{
FlashWriteData_8(buf[i]);
}
FlashWriteCmd_8(NAND_PAGE_PROG_C2);
WaitReady(); //wait util ready
status=0x01 & (FlashReadStatus()); //read status register IO0
return status; //when 0:OK ,1:error
}
uchar FlashWritePage_16(uchar ColAddr,uint PageAddr,uchar *buf,uint num)
{
uchar status=0x00;
uint i;
FlashWriteCmd_8(NAND_PAGE_PROG_C1);
FlashWriteAddr_8(ColAddr); //default col=0;
FlashWriteAddr_8(PageAddr &0xff); //write pageaddrL
FlashWriteAddr_8((PageAddr>>8) &0xff); //write pageaddrH
FlashWriteAddr_8(0x00);
for(i=0;i
ReceiveTempbuf.UByte[0]=buf[i];
ReceiveTempbuf.UByte[1]=buf[i+1];
FlashWriteData_16(ReceiveTempbuf.UInt);
}
FlashWriteCmd_8(NAND_PAGE_PROG_C2);
WaitReady(); //wait util ready
status=0x01 & (FlashReadStatus()); //read status register IO0
return status; //when 0:OK ,1:error
}
void FlashReadPage_16(uchar ColAddr,uint PageAddr,uchar *buf,uint num)
{
uint i; //used for the result of read
FlashWriteCmd_8(NAND_READ0);
FlashWriteAddr_8(ColAddr);
FlashWriteAddr_8(PageAddr &0xff);
FlashWriteAddr_8((PageAddr>>8) &0xff);
FlashWriteAddr_8(0x00);
WaitReady();
Delay_Us(120);//delay 12 us
for(i=0;i
ReceiveTempbuf.UInt=FlashReadData_16();
buf[i]=ReceiveTempbuf.UByte[0];
buf[i+1]=ReceiveTempbuf.UByte[1];
}