微波EDA网,见证研发工程师的成长!
首页 > 硬件设计 > 嵌入式设计 > FLASH存储-----NAND FLASH

FLASH存储-----NAND FLASH

时间:11-21 来源:互联网 点击:

NAND设备的软件调试一般分为以下几个步骤:设置相关寄存器、NAND设备的初始化、NAND设备的识别、NAND设备的读擦写(带ECC校验)

NAND设备的操作都是需要通过命令来完成,不同厂家的命令稍有不同,以下一Samsung公司的K9F1208U0M命令表为例介绍NAND设备的软件编写。

表2K9F1208U0MCommand Sets

1)根据2410寄存器定义如下的命令宏

#define NF_CMD(cmd){rNFCMD=cmd;}

#define NF_ADDR(addr){rNFADDR=addr;}

#define NF_nFCE_L(){rNFCONF&=~(1<11);}

#define NF_nFCE_H(){rNFCONF|=(1<11);}

#define NF_RSTECC(){rNFCONF|=(1<12);}

#define NF_RDDATA()(rNFDATA)

#define NF_WRDATA(data) {rNFDATA=data;}

#define NF_WAITRB(){while(!(rNFSTAT&(1<0)));}

//wait tWB and check F_RNB pin.

2)NAND设备的初始化

static void NF_Init(void)//Flash初始化

{

rNFCONF=(1<15)|(1<14)|(1<13)|(1<12)|(1<11)|(TACLS<8)|(TWRPH0<4)|(TWRPH1<0);//设置NAND设备的相关寄存器

NF_Reset();

}

static void NF_Reset(void)//Flash重置

{

int i;

NF_nFCE_L();

NF_CMD(0xFF);//reset command

for(i=0;i<10;i++);//tWB = 100ns

NF_WAITRB();//wait 200~500us;

NF_nFCE_H();

}

3)NAND设备的识别//#define ID_K9F1208U0M0xec76

static U16 NF_CheckId(void)//Id辨别

{

int i;

U16 id;

NF_nFCE_L();

NF_CMD(0x90);

NF_ADDR(0x0);

for(i=0;i<10;i++);//wait tWB(100ns)

id=NF_RDDATA()<8;// Maker code(K9F1208U:0xec)

id|=NF_RDDATA();// Devide code(K9F1208U:0x76)

NF_nFCE_H();

return id;

}

4)NAND的擦操作

static int NF_EraseBlock(U32 block)

{

U32 blockPage=(block<5);

int i;

NF_nFCE_L();

NF_CMD(0x60[q1]);// Erase one block 1st command

NF_ADDR(blockPage&0xff);// Page number="0"

NF_ADDR((blockPage>>8)&0xff);

NF_ADDR((blockPage>>16)&0xff);

NF_CMD(0xd0[q2]);// Erase one blcok 2nd command

for(i=0;i<10;i++);//wait tWB(100ns)//??????

NF_WAITRB();// Wait tBERS max 3ms.

NF_CMD(0x70);//Read status command

if (NF_RDDATA()&0x1)// Erase error

{

NF_nFCE_H();

Uart_Printf("[ERASE_ERROR:block#=%d]\n",block);

return 0;

}

else

{

NF_nFCE_H();

return 1;

}

}

5)NAND的读操作

static int NF_ReadPage(U32 block,U32 page,U8 *buffer)//读Flash

{

int i;

unsigned int blockPage;

U8 ecc0,ecc1,ecc2;

U8 *bufPt=buffer;

U8 se[16];

page=page&0x1f;//32页

blockPage=(block<5)+page;//1Bolck包含32页

NF_RSTECC();// Initialize ECC

NF_nFCE_L();

NF_CMD(0x00);// Read command

NF_ADDR(0);// Column = 0

NF_ADDR(blockPage&0xff);//

NF_ADDR((blockPage>>8)&0xff);// Block & Page num.

NF_ADDR((blockPage>>16)&0xff);//

for(i=0;i<10;i++);//wait tWB(100ns)

NF_WAITRB();// Wait tR(max 12us)

for(i=0;i<512;i++)

{

*bufPt++=NF_RDDATA();// Read one page

}

ecc0=rNFECC0;//利用2410自带的硬件ECC校验

ecc1=rNFECC1;

ecc2=rNFECC2;

for(i=0;i<16;i++)

{

se[i]=NF_RDDATA();// Read spare array

//读页内冗余的16B

}

NF_nFCE_H();

if(ecc0==se[0] && ecc1==se[1] && ecc2==se[2])//未知使用哪一种软件规范?

{//比较数据结果是否正确

Uart_Printf("[ECC OK:%x,%x,%x]\n",se[0],se[1],se[2]);

return 1;

}

else

{

Uart_Printf("[ECC ERROR(RD):read:%x,%x,%x, reg:%x,%x,%x]\n",

se[0],se[1],se[2],ecc0,ecc1,ecc2);

return 0;

}

}

6)NAND的写操作

static int NF_WritePage(U32 block,U32 page,U8 *buffer)//写Flash

{

int i;

U32 blockPage=(block<5)+page;

U8 *bufPt=buffer;

NF_RSTECC();// Initialize ECC

NF_nFCE_L();

NF_CMD(0x0[q4]);//Read Mode 1

NF_CMD(0x80);// Write 1st command,数据输入

NF_ADDR(0);// Column 0

NF_ADDR(blockPage&0xff);

NF_ADDR((blockPage>>8)&0xff);// Block & page num.

NF_ADDR((blockPage>>16)&0xff);

for(i=0;i<512;i++)

{

NF_WRDATA(*bufPt++);// Write one page to NFM from buffer

}

seBuf[0]=rNFECC0;

seBuf[1]=rNFECC1;

seBuf[2]=rNFECC2;

seBuf[5]=0xff;// Marking good block

for(i=0;i<16;i++)

{

NF_WRDATA(seBuf[i]);// Write spare array(ECC and Mark)

}

NF_CMD(0x10);// Write 2nd command

for(i=0;i<10;i++);//tWB = 100ns.

NF_WAITRB();//wait tPROG 200~500us;

NF_CMD(0x70);// Read status command

for(i=0;i<3;i++);//twhr=60ns

if (NF_RDDATA()&0x1)// Page write error

{

NF_nFCE_H();

Uart_Printf("[PROGRAM_ERROR:block#=%d]\n",block);

return 0;

}

else

{

NF_nFCE_H();

#if (WRITEVERIFY==1)

//return NF_VerifyPage(block,page,pPage);

#else

return 1;

#endif

}

}

以下讨论一下NAND设备上所支持的文件系统,大概现在有以下几种:

A.JFFS2(没有坏块处理,支持大容量存储的时候需要消耗大量的内存,大量的随机访问降低了NAND设备的读取效率)和YAFFS(速度快,但不支持文件的压缩和解压)

Copyright © 2017-2020 微波EDA网 版权所有

网站地图

Top