nand flash读写 (二) (转)
2015-10-22 11:28
441 查看
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设备的相关寄存器
//
1 1 1 1, 1 xxx, r
xxx, r
xxx
//
En 512B 4step ECCR nFCE="H" tACLS tWRPH0 tWRPH1
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_K9F1208U0M 0xec76
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;
[q3] 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;
}
}
转自:http://blog.chinaunix.net/uid-17066213-id-2834649.html
作者:jinweidavid
#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设备的相关寄存器
//
1 1 1 1, 1 xxx, r
xxx, r
xxx
//
En 512B 4step ECCR nFCE="H" tACLS tWRPH0 tWRPH1
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_K9F1208U0M 0xec76
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;
[q3] 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;
}
}
转自:http://blog.chinaunix.net/uid-17066213-id-2834649.html
作者:jinweidavid
相关文章推荐
- nand flash读写 (一) (转)
- spi协议及工作原理分析(转)
- uip之UDP应用笔记
- uIP协议栈——转载:uIP之ARP:地址…
- 网口扫盲二:Mac与Phy组成原理的简…
- UDP协议
- uCOS上下文切换,PendSV中断函数
- C#中调用百度地图API应用(.net&nb…
- 线程同步技术剖析:临界区、时间、…
- C和指针(一)
- Labview 同步——信号量
- c 数据结构
- C和指针(二)
- 如何在App中实现IM功能之一离线消息常见浅析——箭扣科技Arrownock
- 查看mysql版本信息
- Ajax获取SSH框架下JSON对象
- C# Interactive Shell
- TableViewCell去除选中效果
- iOS设置圆角矩形和阴影效果
- 编程规范