我的mini2440开发板上的nandflash的型号是k9f2g08uoc是一块256M 每页2K大小的nandflash
由图可看出nandflash的大小为2k 每页有64bytes的spare区,我们的1个devices由2048个blocks组成,1 block 由 64 page 组成,1 page由(2K + 64) bytes组成。
由于我们2440上的NFADDR寄存器是8位(nandflash只有8根I/O)的而我们的地址是28位的所以要分几次来发,发送地址周期如下:
地址周期表中 有2个列周期(A0 - A11) 3个列地址周期(A12 - A28)组成;其实列周期就是页内地址(0~2047)这个A11貌似不用也可以,用途有点不清楚猜大概是和那个64bytes 的spare区有关吧。行地址就是块地址和页地址(a12 - A28).在操作我们的nandflash时读的最小单位是page 擦出的最小单位是block,所以我们接下来的nandflash的页内地址都给0,只用发送页号。
命令:
1.主要寄存器:
#define NFCONF (*(volatile unsigned *)0x4E000000)
#define NFCONT (*(volatile unsigned *)0x4E000004)
#define NFCMD (*(volatile unsigned *)0x4E000008)
#define NFADDR (*(volatile unsigned *)0x4E00000C)
#define NFDATA (*(volatile unsigned char*)0x4E000010)
#define NFSTAT (*(volatile unsigned *)0x4E000020)
NFCONF:用来设置时序参数TACLS,TWRPH0,TWRPH1,设置数据位宽。
NFCONT:被用来是能/禁止nandflash控制寄存器,使能禁止片选信号nFCE,初始化ecc
NFCMD:发送时序操作命令
NFADDR:发送地址信号(8位)
NFDATA:nandflash数据寄存器,只用到低8位(nandflash 8 I/O线),用于读写数据(8位)
NFSTAT:nandflash 状态寄存器,只用到位0,0:busy,1:ready
详细的信息请查看芯片手册
2 芯片手册上的读nandflash上的操作流程:
2,操作函数
//PLL 405M
#define TACLS 1
#define TWRPH0 2
#define TWRPH1 1
/*初始化函数*/
void nandinit()
{
NFCONF = (TACLS<<12)|(TWRPH0<<8)|(TWRPH1<<4)|(0<<0);
NFCONT = (1<<4)|(1<<1)|(1<<0);
}
void s3c2440_nand_chip_select(void)
{
NFCONT &= ~(1<<1);
}
/*取消片选*/
void s3c2440_nand_chip_desselect(void)
{
NFCONT |= (1<<1);
}
/*写命令*/
void s3c2440_write_cmd(unsigned char cmd)
{
NFCMD = cmd;
}
/*发送地址*/
void write_addr(unsigned int addr)
{
unsigned int page = addr / 2048;
NFADDR = 0;
NFADDR = 0;
NFADDR = (page & 0xff);
NFADDR = ((page >> 8)&0xff);
NFADDR = ((page >> 16)&0xff);
}
/*复位*/
void nand_reset()
{
s3c2440_nand_chip_select();
NFSTAT |= (1);
s3c2440_write_cmd(0xff);
while(!(NFSTAT&(1)));
s3c2440_nand_chip_desselect();
}
/*单页读取函数*/
void nand_read_page(unsigned int address,unsigned char *buffer) //参考芯片读取流程图
{
int i;
//nand_reset();
s3c2440_nand_chip_select();
NFSTAT |= (1);//消除忙状态
s3c2440_write_cmd(0x00);//read1
write_addr(address);
s3c2440_write_cmd(0x30);//read2
while(!(NFSTAT&(1)));//等待不忙
for(i = 0;i < 2048;i++)
buffer[i] =NFDATA;
s3c2440_nand_chip_desselect();
}
/*读取函数*/
void nand_read(unsigned int address,unsigned int size,unsigned char *buffer)
{
unsigned int i;
for(i = address;i <= size+address;i+=2048)
{
nand_read_page(i,buffer);
buffer += 2048;
}
}