注意:
1)有的 NAND flash 芯片在读的时候,R/B 引脚为忙状态时,需要 CS 片选信号为低,
而有的需要为高,或者无关。如果这个没有设置正确,可能不能够正确读写数据。
2)flash 的 page 的大小有的为 512 字节,有的为 2048 字节。
3)NAND flash 发送地址的周期,也不相同,有的为 3 个周期,有的为 4 个周期。
4)在写页时,需要首先发送 0x00 ,0x01 或者 0x50 命令,设置芯片内的寄存器,
否则可能不能够写进数据,而返回的状态却为正确状态。
#define CLX_NAND_DATA_PORT ((unsigned char *)0xb4000000)
#define CLX_NAND_CMD_PORT ((unsigned char *)0xb4040000)
#define CLX_NAND_ADDR_PORT ((unsigned char *)0xb4080000)
//#define NAND_128M
static int clx_nand_write_page(int col, int page, char *buf, int num)
{
int i , state;
4)在写页时,需要首先发送 0x00 ,0x01 或者 0x50 命令,设置芯片内的寄存器,
否则可能不能够写进数据,而返回的状态却为正确状态。
#ifndef NAND_128M
writeb(0x00, CLX_NAND_CMD_PORT);
#endif
// ctrl CE pin
//clx_hwcontrol(NULL, -1, 0);
// send command write page
writeb(0x80, CLX_NAND_CMD_PORT);
// ndelay(10);
// set column 0x00
writeb(col&0xFF, CLX_NAND_ADDR_PORT);
#ifdef NAND_128M
writeb((col>>8)&0xFF, CLX_NAND_ADDR_PORT);
#endif
// set page addr, 2 cycle
writeb((page&0xFF), CLX_NAND_ADDR_PORT);
writeb((page>>8)&0xFF, CLX_NAND_ADDR_PORT);
// ndelay(100);
for(i = 0; i < num; i++)
{
writeb(buf[i], CLX_NAND_DATA_PORT);
}
// ndelay(100);
// send command end write page
writeb(0x10, CLX_NAND_CMD_PORT);
// wait R/B ready.
while(!(REG_EMC_NFCSR & 0x80))
{
printk("REG_EMC_NFCSR = %02x.\n", REG_EMC_NFCSR);
}
// send command read write state
writeb(0x70, CLX_NAND_CMD_PORT);
state = readb(CLX_NAND_DATA_PORT);
printk("write state = %02x.\n",state);
return 0;
}
static int clx_nand_read_page(int col,int page, char *buf, int num)
{
int i;
// test first send 0x00 cmd
//writeb(0x00, CLX_NAND_CMD_PORT);
// ctrl CE pin
//clx_hwcontrol(NULL, -1, 0);
// send command
if(col < 255){
writeb(0x00, CLX_NAND_CMD_PORT);
}else{
writeb(0x01, CLX_NAND_CMD_PORT);
}
ndelay(100);
// set column 0x00
writeb(col&0xFF, CLX_NAND_ADDR_PORT);
ndelay(100);
#ifdef NAND_128M
writeb((col>>8)&0xFF, CLX_NAND_ADDR_PORT);
#endif
// set page addr, 2 cycle
writeb((page&0xFF), CLX_NAND_ADDR_PORT);
ndelay(100);
writeb((page>>8)&0xFF, CLX_NAND_ADDR_PORT);
ndelay(100);
#ifdef NAND_128M
// send command
writeb(0x30, CLX_NAND_CMD_PORT);
#endif
udelay(100);
// wait R/B ready.
while(!(REG_EMC_NFCSR & 0x80))
{
printk("REG_EMC_NFCSR = %02x.\n", REG_EMC_NFCSR);
}
// read data
for(i = 0; i < num; i++)
{
buf[i] = readb(CLX_NAND_DATA_PORT);
}
printk("read %d bytes.\n",i);
ndelay(100);
return 0;
}
static int clx_erease_block(int block)
{
int state;
// test first send 0x00 cmd
writeb(0x00, CLX_NAND_CMD_PORT);
// ctrl CE pin
//clx_hwcontrol(NULL, -1, 0);
// send command
writeb(0x60, CLX_NAND_CMD_PORT);
// ndelay(100);
// send block addr, 2 cycle
writeb((block&0xFF), CLX_NAND_ADDR_PORT);
writeb((block>>8)&0xFF, CLX_NAND_ADDR_PORT);
// send erase command 2 0xD0
writeb(0xD0, CLX_NAND_CMD_PORT);
ndelay(100);
// wait R/B ready.
while(!(REG_EMC_NFCSR & 0x80))
{
printk("REG_EMC_NFCSR = %02x.\n", REG_EMC_NFCSR);
}
// send command read erase state
writeb(0x70, CLX_NAND_CMD_PORT);
state = readb(CLX_NAND_DATA_PORT);
printk("erase state = %02x.\n",state);
return 0;
}
static int clx_nand_read_id(void)
{
int maf_id, dev_id ;
// ctrl CE pin
//clx_hwcontrol(NULL, -1, 0);
// send command
writeb(0x90, CLX_NAND_CMD_PORT);
// set column 0x00
writeb(0x00, CLX_NAND_ADDR_PORT);
ndelay(100);
// wait R/B ready.
while(!(REG_EMC_NFCSR & 0x80))
{
printk("REG_EMC_NFCSR = %02x.\n", REG_EMC_NFCSR);
}
maf_id = readb(CLX_NAND_DATA_PORT);
dev_id = readb(CLX_NAND_DATA_PORT);
printk("maf_id = 0x%02x, dev_id = 0x%02x.\n", maf_id, dev_id);
return 0;
}
转载请注明出处,谢谢!http://qgjie456.blog.163.com/
1)有的 NAND flash 芯片在读的时候,R/B 引脚为忙状态时,需要 CS 片选信号为低,
而有的需要为高,或者无关。如果这个没有设置正确,可能不能够正确读写数据。
2)flash 的 page 的大小有的为 512 字节,有的为 2048 字节。
3)NAND flash 发送地址的周期,也不相同,有的为 3 个周期,有的为 4 个周期。
4)在写页时,需要首先发送 0x00 ,0x01 或者 0x50 命令,设置芯片内的寄存器,
否则可能不能够写进数据,而返回的状态却为正确状态。
#define CLX_NAND_DATA_PORT ((unsigned char *)0xb4000000)
#define CLX_NAND_CMD_PORT ((unsigned char *)0xb4040000)
#define CLX_NAND_ADDR_PORT ((unsigned char *)0xb4080000)
//#define NAND_128M
static int clx_nand_write_page(int col, int page, char *buf, int num)
{
int i , state;
4)在写页时,需要首先发送 0x00 ,0x01 或者 0x50 命令,设置芯片内的寄存器,
否则可能不能够写进数据,而返回的状态却为正确状态。
#ifndef NAND_128M
writeb(0x00, CLX_NAND_CMD_PORT);
#endif
// ctrl CE pin
//clx_hwcontrol(NULL, -1, 0);
// send command write page
writeb(0x80, CLX_NAND_CMD_PORT);
// ndelay(10);
// set column 0x00
writeb(col&0xFF, CLX_NAND_ADDR_PORT);
#ifdef NAND_128M
writeb((col>>8)&0xFF, CLX_NAND_ADDR_PORT);
#endif
// set page addr, 2 cycle
writeb((page&0xFF), CLX_NAND_ADDR_PORT);
writeb((page>>8)&0xFF, CLX_NAND_ADDR_PORT);
// ndelay(100);
for(i = 0; i < num; i++)
{
writeb(buf[i], CLX_NAND_DATA_PORT);
}
// ndelay(100);
// send command end write page
writeb(0x10, CLX_NAND_CMD_PORT);
// wait R/B ready.
while(!(REG_EMC_NFCSR & 0x80))
{
printk("REG_EMC_NFCSR = %02x.\n", REG_EMC_NFCSR);
}
// send command read write state
writeb(0x70, CLX_NAND_CMD_PORT);
state = readb(CLX_NAND_DATA_PORT);
printk("write state = %02x.\n",state);
return 0;
}
static int clx_nand_read_page(int col,int page, char *buf, int num)
{
int i;
// test first send 0x00 cmd
//writeb(0x00, CLX_NAND_CMD_PORT);
// ctrl CE pin
//clx_hwcontrol(NULL, -1, 0);
// send command
if(col < 255){
writeb(0x00, CLX_NAND_CMD_PORT);
}else{
writeb(0x01, CLX_NAND_CMD_PORT);
}
ndelay(100);
// set column 0x00
writeb(col&0xFF, CLX_NAND_ADDR_PORT);
ndelay(100);
#ifdef NAND_128M
writeb((col>>8)&0xFF, CLX_NAND_ADDR_PORT);
#endif
// set page addr, 2 cycle
writeb((page&0xFF), CLX_NAND_ADDR_PORT);
ndelay(100);
writeb((page>>8)&0xFF, CLX_NAND_ADDR_PORT);
ndelay(100);
#ifdef NAND_128M
// send command
writeb(0x30, CLX_NAND_CMD_PORT);
#endif
udelay(100);
// wait R/B ready.
while(!(REG_EMC_NFCSR & 0x80))
{
printk("REG_EMC_NFCSR = %02x.\n", REG_EMC_NFCSR);
}
// read data
for(i = 0; i < num; i++)
{
buf[i] = readb(CLX_NAND_DATA_PORT);
}
printk("read %d bytes.\n",i);
ndelay(100);
return 0;
}
static int clx_erease_block(int block)
{
int state;
// test first send 0x00 cmd
writeb(0x00, CLX_NAND_CMD_PORT);
// ctrl CE pin
//clx_hwcontrol(NULL, -1, 0);
// send command
writeb(0x60, CLX_NAND_CMD_PORT);
// ndelay(100);
// send block addr, 2 cycle
writeb((block&0xFF), CLX_NAND_ADDR_PORT);
writeb((block>>8)&0xFF, CLX_NAND_ADDR_PORT);
// send erase command 2 0xD0
writeb(0xD0, CLX_NAND_CMD_PORT);
ndelay(100);
// wait R/B ready.
while(!(REG_EMC_NFCSR & 0x80))
{
printk("REG_EMC_NFCSR = %02x.\n", REG_EMC_NFCSR);
}
// send command read erase state
writeb(0x70, CLX_NAND_CMD_PORT);
state = readb(CLX_NAND_DATA_PORT);
printk("erase state = %02x.\n",state);
return 0;
}
static int clx_nand_read_id(void)
{
int maf_id, dev_id ;
// ctrl CE pin
//clx_hwcontrol(NULL, -1, 0);
// send command
writeb(0x90, CLX_NAND_CMD_PORT);
// set column 0x00
writeb(0x00, CLX_NAND_ADDR_PORT);
ndelay(100);
// wait R/B ready.
while(!(REG_EMC_NFCSR & 0x80))
{
printk("REG_EMC_NFCSR = %02x.\n", REG_EMC_NFCSR);
}
maf_id = readb(CLX_NAND_DATA_PORT);
dev_id = readb(CLX_NAND_DATA_PORT);
printk("maf_id = 0x%02x, dev_id = 0x%02x.\n", maf_id, dev_id);
return 0;
}
转载请注明出处,谢谢!http://qgjie456.blog.163.com/