K9F2G08U0-存储NFlash
对NnF的基本操作
S3C2440对Nand Flash操作和电路原理——K9F2G08U0A S3C2440内部集成了一个Nand flash控制器.S3C2440的Nand flash控制器包含了如下的特性:l 一个引导启动单元l Nand Flash存储器接口,支持8位或16位的每页大小为256字,512字节,1K字和2K字节的Nand flashl 软件模式:用户可以直接访问Nand Flash存储器,此特性可以用于Nand Flash 存储器的读、擦除和编程.l S3C2440支持8/16位的Nand Flash存储器接口总线l 硬件ECC生成,检测和指示(软件纠错).l Steppingstone接口,支持大/小端模式的按字节/半字/字访问.我用的开发板是天嵌的TQ2440,板子用到的Nand Flash是Samsung公司的K9F2G08U0A,它是8位的Nand flash.本文只介绍Nand Flash的电路原理和Nand Flash的读、写、擦除等基本操作,暂不涉及Nand Flash启动程序的问题.Nand Flash的电路连接如图 1所示:图 1 Nand Flash电路原理上图的左边为K9F2G08U0A与2440的连接图,原理方面就不多介绍,去看看datasheet估计就懂得了,右边的部分是S3C2440的Nand控制器的配置.配置引脚NCON,GPG13,GPG14和GPG15用来设置Nand Flash的基本信息,Nand控制器通过读取配置引脚的状态获取外接的Nand Flash的配置信息,图 2是这四个配置引脚的定义:图 2 Nand控制配置引脚信息由于K9F2G08U0A的总线宽度为8位,页大小为2048字节,需要5个寻址命令,所以NCON、GPG13和GPG14应该接高电平,GPG15应该接低电平.K9F2G08U0A没有地址或数据总线,只有8个IO口,这8个IO口用于传输命令、地址和数据.K9F2G08U0A主要以page(页)为单位进行读写,以block(块)为单位进行擦除.每一页中又分为main区和spare区,main区用于正常数据的存储,spare区用于存储一些附加信息,如块好坏的标记、块的逻辑地址、页内数据的ECC校验和等.K9F2G08U0A的存储阵列如图 3所示:图 3K9F2G08U0A内部存储阵列由上图,我们可以知道:K9F2G08U0A的一页为(2K+64)字节(2K表示的是main区容量, 64表示的是spare区容量),它的一块为64页,而整个设备包括了2048个块.这样算下来一共有2112M位容量,如果只算main区容量则有256M字节(即256M×8位).图 4 K9F2G08U0A地址序列要实现用8个IO口来要访问这么大的容量,如图 4所示:K9F2G08U0A规定了用5个周期来实现.第一个周期访问的地址为A0~A7;第二个周期访问的地址为A8~A11,它作用在IO0~IO3上,而此时IO4~IO7必须为低电平;第三个周期访问的地址为A12~A19;第四个周期访问的地址为A20~A27;第五个周期访问的地址为A28,它作用在IO0上,而此时IO1~IO7必须为低电平.前两个周期传输的是列地址,后三个周期传输的是行地址.通过分析可知,列地址是用于寻址页内空间,行地址用于寻址页,如果要直接访问块,则需要从地址A18开始.由于所有的命令、地址和数据全部从8位IO口传输,所以Nand flash定义了一个命令集来完成各种操作.有的操作只需要一个命令(即一个周期)即可,而有的操作则需要两个命令(即两个周期)来实现.K9F2G08U0A的命令说明如图 5所示:图 5 K9F2G08U0A命令表为了方便使用,我们宏定义了K9F2G08U0A的常用命令define CMD_READ10x00 //页读命令周期1define CMD_READ20x30 //页读命令周期2define CMD_READID 0x90 //读ID命令define CMD_WRITE1 0x80 //页写命令周期1define CMD_WRITE2 0x10 //页写命令周期2define CMD_ERASE1 0x60 //块擦除命令周期1define CMD_ERASE2 0xd0 //块擦除命令周期2define CMD_STATUS0x70 //读状态命令define CMD_RESET0xff //复位define CMD_RANDOMREAD1 0x05 //随意读命令周期1define CMD_RANDOMREAD2 0xE0 //随意读命令周期2define CMD_RANDOMWRITE 0x85 //随意写命令接下来介绍几个Nand Flash控制器的寄存器.Nand Flash控制器的寄存器主要有NFCONF(Nand Flash配置寄存器),NFCONT (Nand Flash控制寄存器),NFCMMD(Nand Flash命令集寄存器),NFADDR(Nand Flash地址集寄存器),NFDATA(Nand Flash数据寄存器),NFMECCD0/1(Nand Flash的main区ECC寄存器),NFSECCD(Nand Flash的spare区ECC寄存器),NFSTAT(Nand Flash操作状态寄存器),NFESTAT0/1(Nand Flash的ECC状态寄存器),NFMECC0/1(Nand Flash用于数据的ECC寄存器),以及NFSECC(Nand Flash用于IO的ECC寄存器).(1)NFCONF:2440的NFCONF寄存器是用来设置NAND Flash的时序参数TACLS、TWRPH0、TWRPH1.配置寄存器的[3:0]是只读位,用来指示外部所接的Nand Flash的配置信息,它们是由配置引脚NCON,GPG13,GPG14和GPG15所决定的(比如说K9F2G08U0A的配置为NCON、GPG13和GPG14接高电平,GPG15接低电平,所以[3:0]位状态应该是1110).(2)NFCONT:用来使能/禁止NAND Flash控制器、使能/禁止控制引脚信号nFCE、初始化ECC.它还有其他功能,在一般的应用中用不到,比如锁定NAND Flash.(3)NFCMMD:对于不同型号的Flash,操作命令一般不一样.参考前面介绍的K9F2G08U0A命令序列.(4)NFADDR:当写这个寄存器时,它将对Flash发出地址信号.只用到低8位来传输,所以需要分次来写入一个完整的32位地址,K9F2G08U0A的地址序列在图4已经做了详细说明.(5)NFDATA:只用到低8位,读、写此寄存器将启动对NAND Flash的读数据、写数据操作.(6)NFSTAT:只用到位0,用来检测NAND是否准备好.0:busy,1:ready.NFCONF寄存器使用TACLS、TWRPH0、TWRPH1这3个参数来控制NAND Flash信号线CLE/ALE与写控制信号nWE的时序关系,它们之间的关系如图6和图7所示:图6 CLE/ALE时序图图7 nWE和nRE时序图TACLS为CLE/ALE有效到nWE有效之间的持续时间,TWRPH0为nWE的有效持续时间,TWRPH1为nWE无效到CLE/ALE无效之间的持续时间,这些时间都是以HCLK为单位的.通过查阅K9F2G08U0A的数据手册,我们可以找到并计算与S3C2440相对应的时序:K9F2G08U0A中的Twp与TWRPH0相对应,Tclh与TWRPH1相对应, TACLS应该是与Tcls相对应.K9F2G08U0A给出的都是最小时间, 2440只要满足它的最小时间即可.TACLS、TWRPH0、TWRPH1这三个变量取值大一些会更保险,在这里,这三个值分别取1,2和0.下面就开始详细介绍K9F2G08U0A的基本操作,包括复位,读ID,页读、写数据,随意读、写数据,块擦除等.为了更好地应用ECC和使能Nand Flash片选,我们还需要一些宏定义:define NF_nFCE_L(){rNFCONT &= ~(1<<1); }define NF_CE_L()NF_nFCE_L()//打开nandflash片选define NF_nFCE_H(){rNFCONT |= (1<<1); }define NF_CE_H() NF_nFCE_H() //关闭nandflash片选define NF_RSTECC(){rNFCONT |= (1<<4); }//复位ECCdefine NF_MECC_UnLock(){rNFCONT &= ~(1<<5); }//解锁main区ECCdefine NF_MECC_Lock(){rNFCONT |= (1<<5); }//锁定main区ECCdefine NF_SECC_UnLock() {rNFCONT &= ~(1<<6); }//解锁spare区ECCdefine NF_SECC_Lock(){rNFCONT |= (1<<6); }//锁定spare区ECCNFSTAT是另一个比较重要的寄存器,它的第0位可以用于判断nandflash是否在忙,第2位用于检测RnB引脚信号:define NF_WAITRB() {while((rNFSTAT & (1<<0) ) ); }//等待Nand Flash不忙define NF_CLEAR_RB(){rNFSTAT |= (1<<2); }//清除RnB信号define NF_DETECT_RB(){while((rNFSTAT&(1<<2)));} //等待RnB信号变高,即不忙NFCMMD,NFADDR和NFDATA分别用于传输命令,地址和数据,为了方便起见,我们可以定义一些宏定义用于完成上述操作:define NF_CMD(data) {rNFCMD = (data); }//传输命令define NF_ADDR(addr){rNFADDR = (addr); }//传输地址define NF_RDDATA() (rNFDATA) //读32位数据define NF_RDDATA8()(rNFDATA8)//读8位数据define NF_WRDATA(data){rNFDATA = (data); }//写32位数据define NF_WRDATA8(data) {rNFDATA8 = (data); }//写8位数据首先,是初始化操作void rNF_Init(void){rNFCONF = (TACLS<<12)|(TWRPH0<<8)|( TWRPH1<<4)|(0<<0); //初始化时序参数rNFCONT =(0<<13)|(0<<12)|(0<<10)|(0<<9)|(0<<8)|(1<<6)|(1<<5)|(1<<4)|(1<<1)|(1<<0); //非锁定,屏蔽nandflash中断,初始化ECC及锁定main区和spare区ECC,使能nandflash控制器,禁止片选rNF_Reset(); //复位芯片}复位操作,写入复位命令static void rNF_Reset(){NF_CE_L();//打开nandflash片选NF_CLEAR_RB();//清除RnB信号NF_CMD(CMD_RESET); //写入复位命令NF_DETECT_RB();//等待RnB信号变高,即不忙NF_CE_H();//关闭nandflash片选}读取K9F2G08U0A芯片ID的操作如下:时序图在datasheet的figure18.首先需要写入读ID命令(0x90),然后再写入0x00地址,并等待芯片就绪,就可以读取到一共五个周期的芯片ID,第一个周期为厂商ID,第二个周期为设备ID,第三个周期至第五个周期包括了一些具体的该芯片信息,函数如下static char rNF_ReadID(){char pMID;char pDID;char cyc3, cyc4, cyc5;NF_nFCE_L();//打开nandflash片选NF_CLEAR_RB();//清RnB信号NF_CMD(CMD_READID);//读ID命令NF_ADDR(0x0); //写0x00地址for ( i = 0; i < 100; i++ );等一段时间//读五个周期的IDpMID = NF_RDDATA8();//厂商ID:0xECpDID = NF_RDDATA8();//设备ID:0xDAcyc3 = NF_RDDATA8();//0x10cyc4 = NF_RDDATA8();//0x95cyc5 = NF_RDDATA8();//0x44NF_nFCE_H();//关闭nandflash片选return (pDID);}下面介绍Nand Flash读操作,读操作是以页为单位进行的.如果在读取数据的过程中不进行ECC校验判断,则读操作比较简单,在写入读命令的两个周期之间写入要读取的页地址,然后读取数据即可.如果为了更准确地读取数据,则在读取完数据之后还要进行ECC校验判断,以确定所读取的数据是否正确.在上文中已经介绍过,Nand Flash的每一页有两区:main区和spare区,main区用于存储正常的数据,spare区用于存储其他附加信息,其中就包括ECC校验码.当我们在写入数据的时候,我们就计算这一页数据的ECC校验码,然后把校验码存储到spare区的特定位置中,在下次读取这一页数据的时候,同样我们也计算ECC校验码,然后与spare区中的ECC校验码比较,如果一致则说明读取的数据正确,如果不一致则不正确.ECC的算法较为复杂,好在S3C2440能够硬件产生ECC校验码,这样就省去了不少的麻烦事.S3C2440既可以产生main区的ECC 校验码,也可以产生spare区的ECC校验码.因为K9F2G08U0A是8位IO口,因此S3C2440共产生4个字节的main区ECC码和2个字节的spare区ECC码.在这里我们规定,在每一页的spare区的第0个地址到第3个地址存储main区ECC,第4个地址和第5个地址存储spare区ECC.产生ECC校验码的过程为:在读取或写入哪个区的数据之前,先解锁该区的ECC,以便产生该区的ECC.在读取或写入完数据之后,再锁定该区的ECC,这样系统就会把产生的ECC码保存到相应的寄存器中.main区的ECC保存到NFMECC0/1中(因为K9F2G08U0A是8位IO口,因此这里只用到了NFMECC0),spare区的ECC保存到NFSECC中.对于读操作来说,我们还要继续读取spare 区的相应地址内容,以得到上次写操作时所存储的main区和spare区的ECC,并把这些数据分别放入NFMECCD0/1和NFSECCD的相应位置中.最后我们就可以通过读取NFESTAT0/1(因为K9F2G08U0A是8位IO口,因此这里只用到了NFESTAT0)中的低4位来判断读取的数据是否正确,其中第0位和第1位为main区指示错误,第2位和第3位为spare区指示错误.下面是一段具体的页读操作程序:U8 rNF_ReadPage( U32 page_number ){U32 i, mecc0, secc;NF_RSTECC(); //复位ECCNF_MECC_UnLock(); //解锁main区ECCNF_nFCE_L(); //使能芯片NF_CLEAR_RB(); //清除RnBNF_CMD(CMD_READ1); //页读命令周期1,0x00//写入5个地址周期NF_ADDR(0x00); //列地址A0-A7NF_ADDR(0x00); //列地址A8-A11NF_ADDR((page_number) & 0xff); //行地址A12-A19NF_ADDR((page_number >> 8) & 0xff); //行地址A20-A27NF_ADDR((page_number >> 16) & 0xff); //行地址A28NF_CMD(CMD_READ2); //页读命令周期2,0x30NF_DETECT_RB(); //等待RnB信号变高,即不忙for (i = 0; i < 2048; i++){buf[i] = NF_RDDATA8(); //读取一页数据内容}NF_MECC_Lock();//锁定main区ECC值NF_SECC_UnLock();//解锁spare区ECC//读spare区的前4个地址内容,即第2048~2051地址,这4个字节为main区的ECCmecc0=NF_RDDATA();//把读取到的main区的ECC校验码放入NFMECCD0/1的相应位置内rNFMECCD0=((mecc0&0xff00)<<8)|(mecc0&0xff);rNFMECCD1=((mecc0 & 0xff00 0000)>>8)|((mecc0 & 0xff0 000)>>16);NF_SECC_Lock();//锁定spare区的ECC值//继续读spare区的4个地址内容,即第2052~2055地址,其中前2个字节为spare区的ECC值secc=NF_RDDATA();//把读取到的spare区的ECC校验码放入NFSECCD的相应位置内rNFSECCD=((secc&0xff00)<<8)|(secc&0xff);NF_nFCE_H(); //关闭nandflash片选//判断所读取到的数据是否正确if ((rNFESTAT0&0xf) == 0x0)return 0x66; //正确elsereturn 0x44; //错误}这段程序是把某一页的内容读取到全局变量数组buffer中.该程序的输入参数直接就为K9F2G08U0A的第几页,例如我们要读取第128064页中的内容,可以调用该程序为:rNF_ReadPage(128064).由于第128064页是第2001块中的第0页(128064=2001×64+0),所以为了更清楚地表示页与块之间的关系,也可以写为:rNF_ReadPage(200164).页写操作的大致流程为:在两个写命令周期之间分别写入页地址和数据,当然如果为了保证下次读取该数据时的正确性,还需要把main区的ECC值和spare区的ECC值写入到该页的spare区内.然后我们还需要读取状态寄存器,以判断这次写操作是否正确.下面就给出一段具体的页写操作程序,其中输入参数也是要写入数据到第几页:U8 rNF_WritePage(U32 page_number){U32 i, mecc0, secc;U8 stat, temp;temp = rNF_IsBadBlock(page_number>>6); //判断该块是否为坏块if(temp == 0x33)return 0x42; //是坏块,返回NF_RSTECC(); //复位ECC——>使能ECCNF_MECC_UnLock();//解锁main区的ECCNF_nFCE_L();//打开nandflash片选NF_CLEAR_RB(); //清RnB信号NF_CMD(CMD_WRITE1); //页写命令周期1//写入5个地址周期NF_ADDR(0x00);//列地址A0~A7NF_ADDR(0x00); //列地址A8~A11NF_ADDR((page_number) & 0xff);//行地址A12~A19NF_ADDR((page_number >> 8) & 0xff); //行地址A20~A27NF_ADDR((page_number >> 16) & 0xff); //行地址A28for (i = 0; i < 2048; i++)//写入一页数据{NF_WRDATA8((char)(i+6));}NF_MECC_Lock();//锁定main区的ECC值mecc0=rNFMECC0; //读取main区的ECC校验码//把ECC校验码由字型转换为字节型,并保存到全局变量数组ECCBuf中ECCBuf[0]=(U8)(mecc0&0xff);ECCBuf[1]=(U8)((mecc0>>8) & 0xff);ECCBuf[2]=(U8)((mecc0>>16) & 0xff);ECCBuf[3]=(U8)((mecc0>>24) & 0xff);NF_SECC_UnLock(); //解锁spare区的ECC//把main区的ECC值写入到spare区的前4个字节地址内,即第2048~2051地址for(i=0;i<4;i++){NF_WRDATA8(ECCBuf[i]);}NF_SECC_Lock(); //锁定spare区的ECC值secc=rNFSECC; //读取spare区的ECC校验码//把ECC校验码保存到全局变量数组ECCBuf中ECCBuf[4]=(U8)(secc&0xff);ECCBuf[5]=(U8)((secc>>8) & 0xff);//把spare区的ECC值继续写入到spare区的第2052~2053地址内for(i=4;i<6;i++){NF_WRDATA8(ECCBuf[i]);}NF_CMD(CMD_WRITE2);//页写命令周期2delay(1000);//延时一段时间,以等待写操作完成NF_CMD(CMD_STATUS); //读状态命令//判断状态值的第6位是否为1,即是否在忙,该语句的作用与NF_DETECT_RB();相同do {stat = NF_RDDATA8();}while((stat&0x40));NF_nFCE_H(); //关闭Nand Flash片选//判断状态值的第0位是否为0,为0则写操作正确,否则错误if (stat & 0x1){temp = rNF_MarkBadBlock(page_number>>6);//标注该页所在的块为坏块if (temp == 0x21)return 0x43 //表示写操作失败,并且在标注该页所在的块为坏块时也失败elsereturn 0x44; //写操作失败}elsereturn 0x66; //写操作成功}该段程序先判断该页所在的坏是否为坏块,如果是则退出.在最后写操作失败后,还要标注该页所在的块为坏块,其中所用到的函数rNF_IsBadBlock和rNF_MarkBadBlock,我们在后面介绍.我们再总结一下该程序所返回数值的含义,0x42:表示该页所在的块为坏块;0x43:表示写操作失败,并且在标注该页所在的块为坏块时也失败;0x44:表示写操作失败,但是标注坏块成功;0x66:写操作成功.擦除是以块为单位进行的,因此在写地址周期是,只需写三个行周期,并且要从A18开始写起.与写操作一样,在擦除结束前还要判断是否擦除操作成功,另外同样也存在需要判断是否为坏块以及要标注坏块的问题.下面就给出一段具体的块擦除操作程序:U8 rNF_EraseBlock(U32 block_number){char stat, temp;temp = rNF_IsBadBlock(block_number); //判断该块是否为坏块if(temp == 0x33)return 0x42; //是坏块,返回NF_nFCE_L(); //打开片选NF_CLEAR_RB(); //清RnB信号NF_CMD(CMD_ERASE1); //擦除命令周期1//写入3个地址周期,从A18开始写起NF_ADDR((block_number << 6) & 0xff); //行地址A18~A19NF_ADDR((block_number >> 2) & 0xff); //行地址A20~A27NF_ADDR((block_number >> 10) & 0xff); //行地址A28NF_CMD(CMD_ERASE2); //擦除命令周期2delay(1000); //延时一段时间NF_CMD(CMD_STATUS); //读状态命令//判断状态值的第6位是否为1,即是否在忙,该语句的作用与NF_DETECT_RB();相同do{stat = NF_RDDATA8();}while((stat&0x40));NF_nFCE_H(); //关闭Nand Flash片选//判断状态值的第0位是否为0,为0则擦除操作正确,否则错误if (stat & 0x1){temp = rNF_MarkBadBlock(page_number>>6);//标注该块为坏块if (temp == 0x21)return 0x43 //标注坏块失败elsereturn 0x44; //擦除操作失败}elsereturn 0x66; //擦除操作成功}该程序的输入参数为K9F2G08U0A的第几块,例如我们要擦除第2001块,则调用该函数为:rNF_EraseBlock(2001) K9F2G08U0A除了提供了页读和页写功能外,还提供了页内地址随意读、写功能.页读和页写是从页的首地址开始读、写,而随意读、写实现了在一页范围内任意地址的读、写.随意读操作是在页读操作后输入随意读命令和页内列地址,这样就可以读取到列地址所指定地址的数据.随意写操作是在页写操作的第二个页写命令周期前,输入随意写命令和页内列地址,以及要写入的数据,这样就可以把数据写入到列地址所指定的地址内.下面两段程序实现了随意读和随意写功能,其中随意读程序的输入参数分别为页地址和页内地址,输出参数为所读取到的数据,随意写程序的输入参数分别为页地址,页内地址,以及要写入的数据.U8 rNF_RamdomRead(U32 page_number, U32 add){NF_nFCE_L(); //打开Nand Flash片选NF_CLEAR_RB(); //清RnB信号NF_CMD(CMD_READ1); //页读命令周期1//写入5个地址周期NF_ADDR(0x00); //列地址A0~A7NF_ADDR(0x00); //列地址A8~A11NF_ADDR((page_number) & 0xff); //行地址A12~A19NF_ADDR((page_number >> 8) & 0xff); //行地址A20~A27NF_ADDR((page_number >> 16) & 0xff); //行地址A28NF_CMD(CMD_READ2); //页读命令周期2NF_DETECT_RB(); //等待RnB信号变高,即不忙NF_CMD(CMD_RANDOMREAD1); //随意读命令周期1//页内地址NF_ADDR((char)(add&0xff)); //列地址A0~A7NF_ADDR((char)((add>>8)&0x0f)); //列地址A8~A11NF_CMD(CMD_RANDOMREAD2); //随意读命令周期2return NF_RDDATA8(); //读取数据}U8 rNF_RamdomWrite(U32 page_number, U32 add, U8 dat){U8 temp,stat;NF_nFCE_L(); //打开Nand Flash片选NF_CLEAR_RB(); //清RnB信号NF_CMD(CMD_WRITE1); //页写命令周期1//写入5个地址周期NF_ADDR(0x00); //列地址A0~A7NF_ADDR(0x00); //列地址A8~A11NF_ADDR((page_number) & 0xff); //行地址A12~A19NF_ADDR((page_number >> 8) & 0xff); //行地址A20~A27NF_ADDR((page_number >> 16) & 0xff); //行地址A28NF_CMD(CMD_RANDOMWRITE); //随意写命令//页内地址NF_ADDR((char)(add&0xff)); //列地址A0~A7NF_ADDR((char)((add>>8)&0x0f)); //列地址A8~A11NF_WRDATA8(dat); //写入数据NF_CMD(CMD_WRITE2); //页写命令周期2delay(1000); //延时一段时间NF_CMD(CMD_STATUS); //读状态命令//判断状态值的第6位是否为1,即是否在忙,该语句的作用与NF_DETECT_RB();相同do{stat = NF_RDDATA8();}while((stat&0x40));NF_nFCE_H(); //关闭Nand Flash片选//判断状态值的第0位是否为0,为0则写操作正确,否则错误if (stat & 0x1)return 0x44; //失败elsereturn 0x66; //成功}下面介绍上文中提到的判断坏块以及标注坏块的那两个程序:rNF_IsBadBlock和rNF_MarkBadBlock.在这里,我们定义在spare区的第6个地址(即每页的第2054地址)用来标注坏块,0x44表示该块为坏块.要判断坏块时,利用随意读命令来读取2054地址的内容是否为0x44,要标注坏块时,利用随意写命令来向2054地址写0x33.下面就给出这两个程序,它们的输入参数都为块地址,也就是即使仅仅一页出现问题,我们也标注整个块为坏块.U8 rNF_IsBadBlock(U32 block){return rNF_RamdomRead(block64, 2054);}U8 rNF_MarkBadBlock(U32 block){U8 result;result = rNF_RamdomWrite(block64, 2054, 0x33);if(result == 0x44)return 0x21; //写坏块标注失败elsereturn 0x60; //写坏块标注成功}关于Nand Flash的基本操作就介绍到这吧。
使用的NandFlash为三星的K9F2G08U0M
使用的Nand Flash为三星的K9F2G08U0M,存储为256M,数据宽度为8bit.具体的资料可以参考datasheet.由于S3C2440里面包括了Nand FLash 控制器,所以,我们的工作就是根据芯片手册配置一下寄存器。
包括的寄存器如下:NFCONF; NFCONT;NFCMD;NFADDR;NFDATA; NFMECCD0; NFMECCD1;NFSECCD; N FSTAT; NFESTAT0; NFESTAT1;NFMECC0;NFMECC1;NFSECC;NFSBLK;NFEBLK;(1) 对于每个寄存器的地址,每一位的功能可以参考S3C2440芯片手册!对于目前的编程主要涉及到如下五个寄存器:NFCONT;NFCMD;NFADDR;NFDATA;NFSTAT;使用宏定义:#define rNFCONF (*(volatile unsigned *)0x4E000000)#define rNFCONT (*(volatile unsigned *)0x4E000004)#define rNFCMD (*(volatile unsigned *)0x4E000008) #define rNFADDR (*(volatile unsigned char*)0x4E00000C)#define rNFDATA8 (*(volatile unsigned char*)0x4E000010)#define rNFSTAT (*(volatile unsigned *)0x4E000020)特别注明:对于NFCONF寄存器,特别要说明的是TACLS,TWRPH0,TWRPH1,这三个参数。
如何设置这三个参数,主要得看K9F2G08U0M 手册上的时序表,参数表,上面已经写好了CLE ,ALEsetup时间,WE_N的Pulse WiDth,WE_N HIGH HOLD TIME .根据这些参数,设置个合适的TACLS,TWRPH0,TWRPH1值!(2) 命令! Nand Flash编程时涉及到很多命令,其实这些命令帮助我们完成了很多的工作,我们现在只需做发送命令的工作。
FLASH型号容量对照表
FLASH型号容量对照表FLASH型号容量对照表各品牌 FLASH型号容量对照表三星(SAMSUNG)FLASH: 8M K9F6408UOC-TCBO16M K9F2808UOB/C-YC/IBO32M K9F5608UOA/B/C-YC/IBO64M K9F1208UOM/A-YCIBO128M K9K1G08UOM/A-YC/IBOK9F1G08UOM-YC/IBO256M K9F2G08UOM-YC/IBOK9K2G08UOM-YC/IBO512M K9W4G08U1M-YC/IBOK9K4G08UOM-YC/IBO东芝(TOSHIBA)FLASH:16M TC58128AFT/TC58DVM72A1FTOO32MTC58256FT/TC58DVM82A1FT00 64MTC58512FT/TC58DVM92A1FT00 128MTH58100FT/TC58DVG02A1FT00 TC58NVGOS3AFT05 256M TC58NVG1S3AFT05sandiak sdtnfbh-1024 128m -512 64 K9F2808U0C-YCB0 16MBK9F2808U0C-VCB0 16MBKM29U128(I)T 16MBK9F5608U0B-YCB0 32MBK9F5608U0C-YCB0 32MBK9F5608U0C-YIB0 32MBSmall K9F5608U0C-VCB0 32MBBlock K9F1208U0M-YCB0 64MBK9F1208U0A-YCB0 64MBK9F1208U0A-YIB0 64MBK9F1208U0A-VCB0 64MBK9K1G08U0A-YCB0 128MBK9K1G08U0M-YCB0 128MBK9K1G08U0M-VIB0 128MBK9T1G08U0A-YCB0 128MBK9T1G08U0M-YCB0 128MBSamsung SLC K9T1G08U0M-VIB0 128MBK9F1G08U0M-YCB0 128MBK9F1G08U0A-YCB0 128MBK9F1G08U0M-VCB0 128MBK9F1G08U0M-VIB0 128MBK9F1G08U0M-FIB0 128MBK9K2G08U0M-YCB0 256MBK9K2G08U0A-FIB0(90nm) 256MBK9K2G08U0M-VCB0 256MBK9K2G08U0M-VIB0 256MB Large K9K2G08U0A-VIB0(90nm) 256MBBlock K9F2G08U0M-YCB0(90nm) 256MBK9K4G08U0M-YCBO(90nm) 512MBK9K4G08U0M-PIB0(90nm) 512MBK9W4G08U1M-YCB0(90nm) 512MBK9W4G08U1M-YIB0(90nm) 512MBK9W8G08U1M-YCB0(90nm) 1GBK9W8G08U1M-YIB0(90nm) 1GBTC58128FT 16MBTC58DVM72A1FT00/05 16MBTC58DVM72A1FTI0 16MBTC58256FT 32MBSmall TC58DVM82A1FT00/05 32MBBlock TC58DVM82A1FTI0 32MBSLC TC58512FT 64MBTC58DVM92A1FT00/05 64MBToshiba TH58100FT 128MBTC58DVG02A1FT00/05 128MBTC58DVG04B1FT00/05 128MBTC58DVG04B1FTI0 128MBSmall TC58DVG14B1FT00/05 256MBMLC Block TC58DVG14B1FTI0 256MBTH58DVG24B1FT00/05 512MBTH58DVG24B1FTI0 512MBHY27US08561M 32MBSmall HY27US08121M 64MBBlock HY27UA081G1M 128MBHynix SLC HY27UB082G4M 256MBLarge HY27UF081G2M 128MBBlock HY27UG082G2M 256MBHY27UH084G2M 512MBInfineon HYF33DS512800ATC 64MBNAND128W3A 16MB Small NAND256W3A 32MBBlock NAND512W3A 64MBNAND01GW3A 128MBNAND128W3B 16MBST SLC NAND256W3B 32MBLarge NAND512W3B 64MBBlock NAND01GW3B 128MBNAND02GW3B 256MBNAND04GW3B 512MBNAND08GW3B 1GBMicron SLC Large MT29F2G08A 256MBBlock MT29F4G08B 256MBSanDisk MLC Small SDTNFCH-512 64MBBlock SDTNGCHE0-1024 128MBHN29V1G91T-30 128MBAG-AND HN29V2G74WT-30 256MBHN29V25691BT 32MB Renesas R1FVH04G13R 512MBSUPER HN29V51211T-50H 64MBAND HN29V51211T-50 64MB补充一下,大家只要记住,最常见的,在MP3中应用的,就是SAMSUNG | HYNIXK9K/K9F 128M 1G08;| HY 1G1M/1G2M,有一个共同的特征,1G代表128M, 如果是2GXX就代表256M,以此类推。
Flash 坏块分析
FLASH 坏块分析我们所用的Flash芯片是三星K9F2G08U0B,256M,NAND Flash。
对于NAND Flash的坏块有两种:一、先天性坏块。
先天性坏块是在生产过程中产生,这种坏块在出厂时已做标记。
二、后天性坏块。
这种坏块是在后天使用过程中产生的,由于使用时间长,擦除的时候数据出错,无法回到0xFF,系统认为此块为坏块。
关于坏块的数量,芯片在出厂时会做出保证,保证坏块的数量在一定范围之内。
例如:三星的K9G8G08U0M,整个flash一共有4096个块,出厂的时候,保证好的块至少大于3996个就算是合格品。
意思是,新买的这个型号的nand flash,最坏的可能是有100个坏块。
每个芯片都有其允许的坏块数量,具体要参考芯片手册。
对于这些坏块,出厂时都会做上标记,芯片有了这些坏块无非是这些坏块所对应的容量不可存储。
对于坏块,Linux系统中有坏块管理,对应会有坏块表来记录好块和坏块信息。
后面往Flash里写入信息时,将跳过这些坏块,把信息存在其他好的块中。
下面分析研发部门提出的怀疑是由于Flash坏块造成的7U设备业务吊死。
一、由于先天性坏块造成业务吊死根据上面分析,先天性坏块出厂时已做标记,后面的程序烧写会绕过这些标记坏块。
所以个人认为这类坏块对系统不会造成影响。
二、由于后天性坏块造成业务吊死芯片在使用的过程中,确实会出现一些坏块。
对于我们板卡中使用的Flash芯片,存储的是Linux系统,在设备运行的过程中,Flash芯片有可能会写入一些数据。
个人认为即使运行过程中会向Flash中写入数据也仅仅是一些配置信息,如:设备的IP和ID等。
芯片在使用中的坏块我将它分为三个方面:第一、存储了Linux系统的块坏了。
第二、没有存储Linux的块坏了。
第三、第一和第二种情况都有。
对于第一种情况,存储Linux 系统的块坏了,那么在出现业务吊死的情况后,重启设备,个人认为Linux系统有可能起不来,业务也可能恢复不了。
大容量NAND Flash K9T1G08UOM在网络存储中的应用
N N ls A D Fah器件 K T G 8 0 及 其编程 特 点 ,并 讨论 了网络 存储应 用 的存储 策略 和数 据 可靠性 9 10U M 方 面的考虑 , 设计 并 实现 了网络数据 流 的 N N l h存储 A D Fa s
关 键 词 : A D Fah 9 1 0 U M: 网络 存 储 : 无 效 块 处 理 N N l ;K T G 8 0 s
维普资讯
一ቤተ መጻሕፍቲ ባይዱ
6一 4
《 国外 电子元器件}0 7 20 年第 1 期 20 0 07年 1 0月
●主 题 论 文
大 容 量 N D ls T G0 U M AN F ah K9 1 8 0
在 网络存储 中的应 用
郭 宝 清 ,黄光 明
1 引 言
随着嵌 入式 系 统 广泛应 用 , 入 式 系统 中的数 嵌 据存储 和数据 管理 则成 为设计人 员考 虑 的重点 。在
许 多现 场 不 可 达 数据 采 集 应 用 中采 用 分 布式 数 据
基于 大 容量 N N ah的 网络存 储 系统 ,该 系统 A DF s l 具有 速 度快 、 全 可靠 、 扩展 、 震 和抗 干扰 能力 安 易 抗 强 、 用 温 度 范 围宽 等 特点 , 方 便 的用 于 安 全 监 使 可 控、 生产 数 据记 录 、 航行 数 据记 录等 方 面 , 具有 广 阔
都存 在 抗 震 和 抗 电磁 干扰 能 力 差 、使 用 温 度 范 围
构 如 图 1 示 , 中 5 2列 至 5 7列 间是 备 用 区 。 所 其 1 2
Abs r c : mi g a h tr g e u r me tf re e d d s se t a tAi n tt e so a e r q ie n o mb d e y t m,a so a e s h me b s d o r a a t r g c e a e n g e tc - p ct a i NAND F a h s p o o e n t i a e . e NAND a h K9 8 M n i p o r mmi g y l s i r p s d i h s p p rTh Fls - T1 G0 UO a d t r g a s n c a a t rsi r nto u e Th tae y fr a lc to fn t r tr g a d t e d t e ib lt r h r ce itc a e i r d c d. e sr t g pp ia i n o ewo k so a e, n h aa r l iiy a e o a d s u s d he so a e o ic s e .T tr g n NAND a h fr n t r t te m sd sg e Fl s ewo k daa sr a i e in d. o Ke r : NAND l s ; K9 y wo ds Fa h T1 G08 UOM; n t r tr g ; ma a e n fi a i l c e wo k so a e n g me to nv ld b o k
K9F2G08U0M中文资料
2
元器件交易网
K9F2G08Q0M K9F2G16Q0M K9F2G08U0M K9F2G16U0M
Preliminary FLASH MEMORY
256M x 8 Bit / 128M x 16 Bit NAND Flash Memory
PRODUCT LIST
Part Number K9F2G08Q0M-Y,P K9F2G16Q0M-Y,P K9F2G08U0M-Y,P K9F2G16U0M-Y,P 2.7 ~ 3.6V Vcc Range 1.70 ~ 1.95V Organization X8 X16 X8 X16 TSOP1 PKG Type
FEATURES
• Voltage Supply -1.8V device(K9F2GXXQ0M): 1.70V~1.95V -3.3V device(K9F2GXXU0M): 2.7 V ~3.6 V • Organization - Memory Cell Array -X8 device(K9F2G08X0M) : (256M + 8,192K)bit x 8bit -X16 device(K9F2G16X0M) : (128M + 4,096K)bit x 16bit - Data Register -X8 device(K9F2G08X0M): (2K + 64)bit x8bit -X16 device(K9F2G16X0M): (1K + 32)bit x16bit - Cache Register -X8 device(K9F2G08X0M) : (2K + 64)bit x8bit -X16 device(K9F2G16X0M) : (1K + 32)bit x16bit • Automatic Program and Erase - Page Program -X8 device(K9F2G08X0M) : (2K + 64)Byte -X16 device(K9F2G16X0M) : (1K + 32)Word - Block Erase -X8 device(K9F2G08X0M) : (128K + 4K)Byte -X16 device(K9F2G16X0M) : (64K + 2K)Word • Page Read Operation - Page Size - X8 device(K9F2G08X0M) : 2K-Byte - X16 device(K9F2G16X0M) : 1K-Word - Random Read : 25µs(Max.) - Serial Access : 50ns(Min.) 30ns(Min., K9F2G08U0M only) • Fast Write Cycle Time - Page Program time : 300µs(Typ.) - Block Erase Time : 2ms(Typ.) • Command/Address/Data Multiplexed I/O Port • Hardware Data Protection - Program/Erase Lockout During Power Transitions • Reliable CMOS Floating-Gate Technology - Endurance : 100K Program/Erase Cycles - Data Retention : 10 Years • Command Register Operation • Cache Program Operation for High Performance Program • Power-On Auto-Read Operation • Intelligent Copy-Back Operation • Unique ID for Copyright Protection • Package : - K9F2GXXX0M-YCB0/YIB0 48 - Pin TSOP I (12 x 20 / 0.5 mm pitch) - K9F2GXXX0M-PCB0/PIB0 : Pb-FREE PACKAGE 48 - Pin TSOP I (12 x 20 / 0.5 mm pitch)
NandFlash驱动(实现初始化以及读操作)
NandFlash驱动(实现初始化以及读操作)本节来学习裸机下的Nand Flash驱动,本节学完后,再来学习Linux下如何使⽤Nand Flash驱动Linux中的Nand Flash驱动,链接如下:(只需要初始化Flash以及读Flash)打开2440芯⽚⼿册,K9F2G08U0M芯⽚⼿册(因为2440中Nand Flash是⽤的256MB(2Gb)内存,8个数据引脚)在芯⽚⼿册中得到K9F2G08U0M=2048块Block=128K页Pages=256MB=2Gb1个设备=2048块Block1块Block=64页Pages1页=(2K+64)B (因为每个地址⾥都存放了⼀个字节,所以⽤B表⽰)其中64B是存放ECC的OOB地址,(ECC:存放判断位反转的校验码)Nand Flash 缺点:读数据容易位反转可以通过ECC编码器值来判断读数据是否位反转,若位反转则重新读数据写过程:1)写页数据2)然后⽣成ECC3)将ECC写⼊到OBB页地址⾥(写数据是不会出现位反转)读过程:1)读出页数据,然后⽣成临时ECC(此时ECC可能有错)2)然后读出OOB页地址⾥的ECC3)⽐较两个ECC,判断是否出现位反转读OOB⽅法:读整个Nand Flash时,是读不出页⾥⾯的OBB地址,⽐如读2049这个地址数据时,是读的第⼆页上的第2个地址:只有读某⼀页时,才能读出这个页⾥⾯的OOB地址, ⽐如读第0页的2049这个地址数据时,才是读的第0页OOB的第2个地址:Nand Flash芯⽚硬件引脚图:RnB:就绪(ready)/忙(busy)输出信号,需要采⽤上拉电阻(1:表⽰写⼊数据成功,0:表⽰正在写⼊)CLE:命令(command)锁存(latch)使能,(1:表⽰当前传的是命令值)ALE:地址锁存使能,(1:表⽰当前传的是地址值,当CLE=0和ALE=0,表⽰传的是数据)nCE:芯⽚使能(低电平使能) (n:表⽰低电平有效)nWE:写使能 ,⽐如写命令时,当CLE=1,ALE=0时,当nWE来个上升沿,则会将IO数据写⼊flash中nRE:读使能,和we类似nWP:写保护(protect) (1:不保护,0:只能读不能写),默认接⾼电平.1.编写nand_init()函数1.1设置通信时序图1(nandflash时序表):图2(nandflash时序图):通过图2和图1可以看出:tCS是等待芯⽚使能CE的时间, tCS=20nStCLS和tALS是等待WE(写信号)结束的时间, tCLS=tALS=15nStWP是WE(写信号)维持时间, tWP=15nStALH是等待命令写⼊成功的时间, tALH=5nStCLH是等待地址写⼊成功的时间, tCLH=5nS图3(2440-nandflash时序图):⾸先查看2440芯⽚⼿册⾥nandflash时序图,如上图,可以看出需要设置TACLS,TWRPH0和TWRPH1,这三个参数TACLS:属于等待WE(写信号)就绪的时间,对⽐图2得出TACLS= tCLS- tWP=0nSTWRPH0:属于WE(写信号)的时间, 对⽐图2得出TWRPH0= tWP=15nSTWRPH1:属于等待命令写⼊成功的时间,对⽐图2得出TWRPH1=tALH=tCLH=5nS最后,在NFCONF寄存器中设置这三个参数TACLS[13:12]表⽰Duration(持续时间)=HCLK*TACLS,由于Duration=0nS,所以TACLS=0TWRPH0 [10:8]表⽰Duration(持续时间)=HCLK*( TWRPH0+1),由于Duration=15nS,HCLK=10nS(100Mhz),所以TWRPH0 =1. TWRPH1 [6:4]表⽰Duration(持续时间)= HCLK*( TWRPH1 +1),由于Duration=5nS,HCLK=10nS(100Mhz),所以TWRPH1 =0 1.2然后定义全局变量,并实现nand_init()初始化:/* nand flash 时序 */#define TACLS 0#define TWRPH0 1#define TWRPH1 0/* nand flash 寄存器 */#define NFCONF *((unsigend int *)0X4E000000); //配置寄存器(⽤来设置时序)#define NFCONT *((unsigend int *)0X4E000000); //控制寄存器(⽤来使能nandflash控制器以及ECC编码器,还有控制芯⽚使能CE脚)#define NFCMMD *((unsigend char *)0X4E000000);//发送命令寄存器(命令只有8位)#define NFADDR *((unsigend char *)0X4E000000);//发送地址寄存器(地址只有8位)#define NFDATA *((unsigend int *)0X4E000000);//读/写数据寄存器(数据只有8位)#define NFSTAT *((unsigend int *)0X4E000000);//运⾏状态寄存器(⽤于判断RnB脚)/*因为Nand Flash只有8位I/O脚,所以NFCMMD/ NFADDR/ NFDATA三个寄存器值都是unsigend char型 */1.3 nand_init()函数初始化void nand_init(void){/* 设置时序 */NFCONF = (TACLS<<12)|(TWRPH0<<8)|(TWRPH1<<4);/* bit4=1:初始化ECC, bit1=1:禁⽌⽚选 bit0=1:启动nandflash控制器*/NFCONT = (1<<4)|(1<<1)|(1<<0);}2编写nand_read()函数2.1编写nand_read()函数需要以下⼏个⼦函数:2.1.1⽚选使能函数(在读写FLASH之前都要选中⽚选)nand_select() //使能⽚选{int i;NFCONT&=~(1<<1); // NFCONT控制器位1置0for(i=0;i<10;i++); //等待芯⽚使能成功}2.1.2取消⽚选函数(退出读写FLASH时需要取消⽚选)nand_deselect() //取消⽚选{int i;NFCONT&=~(1<<1); // NFCONT控制器位1置0for(i=0;i<10;i++); //等待芯⽚使能成功}2.1.3读命令函数nand_cmd(unsigned char cmd){int i;NFCMMD= cmd; // 向NFCMMD寄存器写⼊命令for(i=0;i<10;i++); //等待写⼊命令成功}2.1.4判断RnB状态函数(在写⼊所有命令后都要判断RnB脚是否为⾼电平就绪)nand_waite_idle(){int i;while(!(NFSTAT&0X01)) // 等待NFSTAT寄存器位0置1for(i=0;i<10;i++);}2.1.5读数据函数nand_read_data(){unsigend char p=NFDATA; //读取NFDATA寄存器return p; //返回}2.1.6 编写写⼊地址函数(分5个周期)⾸先Nand Flash引脚只有8位,然⽽地址共有2048(块)*64(页)*2KB,为了读出多个地址,如下图,所以需要分5个周期来实现发送地址如上图,其中 A10~A0对应页⼤⼩(列),由于nandflash每页2048B,所以只⽤到A10~A0 A28~A11对应页⽬录(⾏),表⽰共有2048块*64(每块有64页)个⽬录例如,4097 地址就是:A10~A0=4097%2048= 1(A0=1,其余为0)A28~A11=4097/2048=2(A13=1,其余为0)所以nand_write_nand()函数如下:void nand_read_addr(unsigned int addr){unsigned int col = addr % 2048;unsigned int page = addr / 2048;volatile int i;NFADDR=(col>>0)&0xff; //A7~A0,第1周期for(i=0;i<10;i++);NFADDR=(col>>8)&0x0f; //A10~A8,第2周期for(i=0;i<10;i++);NFADDR=(page>>0)&0xff; //A18~A11,第3周期for(i=0;i<10;i++);NFADDR=(page>>8)&0xff; //A26~A19,第4周期for(i=0;i<10;i++);NFADDR=(page>>16)&0xff; //A27~A28,第5周期for(i=0;i<10;i++);}2.2Nand Flash命令图:如上图,例如:当要reset复位nand flash时1) 使能⽚选nand_select();2) 发送0XFF复位命令nand_cmd(0xFF);3) 等待RnB状态是否就绪 nand_wait_idle();4) 取消⽚选 nand_deselect();2.3Nand Flash读数据时序图:从上图可以看出nand flash 读数据分为了以下⼏个步骤:(1) 使能⽚选CE,将CLE置1,等待发送命令(2) 将WE置低,将IO置为0X00,然后拉⾼WE,触发⼀次上升沿,则将把0x00写⼊flash中(3) 将CLE置0,表⽰发送地址(分为5个周期)(4) 发送读命令0X30(5) 等待RnB信号为⾼电平(6) 读数据(在同⼀页⾥,数据可以连续读,读下⼀页时,需要重新发送新的地址才⾏例如:读1000地址到2050地址时,1.发出1000地址,到达页0的1000地址上,然后再连续读(2048-1000)次,直到读到页0的2047处.2.再发出2048地址,到达页1的0地址上,然后连续读(2051-2048)次,直到读到2050为⽌)(7) 取消⽚选nCE2.4 所以nand_read()函数如下:void nand_read(unsigned int src,unsigned char *dest,unsigned int len)/* src:源地址,为32位地址,所以⽤unsigend int表⽰*dest:⽬的地址内容,由于这⾥是将数据读出到⽬的地址内容中,所以需要⽤到*指针,因为每个地址⾥存的是⼀个字节,所以⽤unsigend char 型 */ {int col=src%2048; //第⼀次读,可能不是读的页⾸地址,所以需要记录当前页的位置int i=0; //当前读了0次nand_select(); //1使能⽚选nCEwhile(i<len){ nand_cmd(0X00); //2发送读命令0X00nand_write_addr(src); // 3发送yuan地址(分为5个周期)nand_cmd(0X30); //4发送读命令0X30nand_wait_idle(); //5等待RnB信号为⾼电平for(;(col<2048)&&(i<len);col++) //连续读页内数据{dest[i]=nand_read_data(); //6.读数据i++;src++;}col=0;}nand_deselect(); // 取消⽚选nCE }。
常用NAND Flash支持列表
Y
Y
第25脚 不能接
Y
32 Samsung 1GB MLC-2K K9G8G08U0A EC D3 14 A5 1CE 4b/512B 51nm 8Bit Y
Y
33 Samsung 1GB MLC-2K K9G8G08U0M EC D3 14 25 1CE 4b/512B 60nm 8Bit Y
Y
34 Samsung 1GB MLC-2K K9L8G08U0A EC D3 55 25 1CE 4b/512B 60nm 8bit Y
Y
2 Samsung 16GB MLC-4K K9MDG08U5M EC D7 55 B6 4CE 4b/512B 51nm 8bit Y
Y
3 Samsung 8GB MLC-8K K9LCG08U1M EC D7 94 72 2CE 24b/1KB 35nm 8bit Y
Y
4 Samsung 8GB MLC-4K K9HCG08U5M EC D3 14 A5 4CE 4b/512B 51nm 8Bit Y
Y
23 Samsung 2GB MLC-4K KLEAG8ZUMM EC D7 99 35 1CE
51nm 8Bit Y
Y
24 Samsung 2GB MLC-2K K9LAG08U0M EC D5 55 25 1CE 4b/512B 60nm 8Bit Y
Y
25 Samsung 2GB MLC-2K K9HAG08U1M EC D3 55 25 2CE 4b/512B 90nm 8Bit Y
Flash Support List
序号
Vendor 品牌
Capaci ty 容
量
Type 类 型
三星K9F1G08U0E(128MB,NANDFLASH)STM32平台驱动程序(模拟时序)
三星K9F1G08U0E(128MB,NANDFLASH)STM32平台驱动程序(模拟时序)STM32平台下模拟时序驱动K9F1G08U0E,主要⽬的为了解、学习NAND FLASH的功能特性,没有使⽤STM32的FSMC(⽕龙开发板硬件为模拟时序驱动),纯粹⾃娱⾃乐,如对你有帮助,不胜荣幸,呵呵。
C⽂件内容:1 #include "NAND512W3A2C.h"2/*3作者:毕⼩乐4⽇期:2019.01.245版本:V1.0067驱动代码针对K9F1G08U0E时序⽽写,K9F1G08U0E与NAND512W3A2C,Pin to Pin兼容。
8驱动运⾏平台STM32F103。
9驱动实现功能:101)Page Read112) Page Program123) Block Erase134) Read Status145) Read ID15PE0~PE7 -> DB00~DB0716PD6 -> CL17PD5 -> AL18PD14 -> W19PD15 -> R20PD7 -> CS21PB5 -> R/B22*/23static void NAND512_Delay_uS(int tick)24 {25int i;26while(tick>0)27 {28 tick--;29for(i=0;i<10;i++)30 __nop();31 }32 }33void NAND512_DB_OutPut(void)34 {35 GPIO_InitTypeDef GPIO_InitStructure;3637 GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0 | GPIO_Pin_1 | GPIO_Pin_2 | GPIO_Pin_338 | GPIO_Pin_4 | GPIO_Pin_5 | GPIO_Pin_6 | GPIO_Pin_7;39 GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;40 GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;41 GPIO_Init(GPIOE, &GPIO_InitStructure);42 }43void NAND512_DB_InPut(void)44 {45 GPIO_InitTypeDef GPIO_InitStructure;4647 GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0 | GPIO_Pin_1 | GPIO_Pin_2 | GPIO_Pin_348 | GPIO_Pin_4 | GPIO_Pin_5 | GPIO_Pin_6 | GPIO_Pin_7;49 GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;50 GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;51 GPIO_Init(GPIOE, &GPIO_InitStructure);52 }53char NAND512_DB_Read(void)54 {55char dat;56 NAND512_DB_InPut();57 __nop();58 dat = GPIO_ReadInputData(GPIOE) & 0x00FF;59return dat;60 }61void NAND512_DB_Write(char Data)62 {63 u16 temp;64 NAND512_DB_OutPut();65// __nop();71void NAND512_IO_Init(void)72 {73 GPIO_InitTypeDef GPIO_InitStructure;7475 RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB | RCC_APB2Periph_GPIOD76 | RCC_APB2Periph_GPIOE, ENABLE);7778/*CL*/79 GPIO_InitStructure.GPIO_Pin = NAND512_CL_PIN;80 GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;81 GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;82 GPIO_Init(NAND512_CL_PORT, &GPIO_InitStructure);8384/*AL*/85 GPIO_InitStructure.GPIO_Pin = NAND512_AL_PIN;86 GPIO_Init(NAND512_AL_PORT, &GPIO_InitStructure);8788/*W*/89 GPIO_InitStructure.GPIO_Pin = NAND512_W_PIN;90 GPIO_Init(NAND512_W_PORT, &GPIO_InitStructure);9192/*R*/93 GPIO_InitStructure.GPIO_Pin = NAND512_R_PIN;94 GPIO_Init(NAND512_R_PORT, &GPIO_InitStructure);9596/*CE*/97 GPIO_InitStructure.GPIO_Pin = NAND512_CE_PIN;98 GPIO_Init(NAND512_CE_PORT, &GPIO_InitStructure);99100/*R/B*/101 GPIO_InitStructure.GPIO_Pin = NAND512_RB_PIN;102 GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;103 GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;104 GPIO_Init(NAND512_RB_PORT, &GPIO_InitStructure);105106 NAND512_CL_LOW;107 NAND512_AL_LOW;108 NAND512_R_HIGH;109 NAND512_W_HIGH;110 NAND512_CE_HIGH;111 }112113//读状态寄存器信息114char NAND512_Read_Status(void)115 {116char dat;117118 NAND512_CL_LOW;119 NAND512_W_HIGH;120 NAND512_R_HIGH;121 NAND512_CE_HIGH;122 NOP;123124 NAND512_Delay_uS(5);125 NAND512_CL_HIGH;126 NOP;127 NOP;128 NAND512_CE_LOW;129 NOP;130 NOP;131 NOP;132 NAND512_W_LOW;133 NAND512_DB_Write(0x70);134 NOP;135 NAND512_W_HIGH;136137 NAND512_Delay_uS(5);138 NAND512_CL_LOW;139 NOP;140 NOP;141//CE状态保持不变142143 NAND512_Delay_uS(10);144 NAND512_R_LOW;145 NOP;146 dat = NAND512_DB_Read();147 NAND512_Delay_uS(5);148 NAND512_R_LOW;149 NAND512_Delay_uS(5);155156void NAND512_Read_ID(char* Buf)157 {158char i = 0;159160 NAND512_CL_LOW;161 NAND512_AL_LOW;162 NAND512_R_HIGH;163 NAND512_W_HIGH;164 NAND512_CE_HIGH;165 NAND512_Delay_uS(5);166167 NAND512_CL_HIGH;168 NAND512_W_LOW;169 NAND512_Delay_uS(5);170 NAND512_CE_LOW;171 NAND512_DB_Write(0x90);172 NAND512_Delay_uS(5);173 NAND512_W_HIGH;174 NAND512_Delay_uS(5);175176 NAND512_CL_LOW;177 NAND512_Delay_uS(20);178 NAND512_AL_HIGH;179 NAND512_Delay_uS(20);180 NAND512_W_LOW;181 NAND512_DB_Write(0x00); //写地址0182 NAND512_Delay_uS(5);183 NAND512_W_HIGH;184 NAND512_Delay_uS(10);185 NAND512_AL_LOW;186 NAND512_Delay_uS(20);187188for(i=0;i<5;i++)189 {190 NAND512_R_LOW;191 NAND512_Delay_uS(10);192 Buf[i] = NAND512_DB_Read();193 NAND512_R_HIGH;194 NAND512_Delay_uS(10);195 }196197return ;198 }199200void NAND512_Page_Read(char* Buf,int Len,int Add)201 {202int Bank_Index,Page_Index,Page_Start_Add;203int Add_New,j;204char i;205206 Bank_Index = Add / BANK_SIZE;207 Page_Index = (Add % BANK_SIZE) / PAGE_SIZE;208 Page_Start_Add = Add % PAGE_SIZE;209 Add_New = (((Bank_Index<<6) | Page_Index)<<16) | Page_Start_Add; 210211 NAND512_CL_LOW;212 NAND512_AL_LOW;213 NAND512_W_HIGH;214 NAND512_R_HIGH;215 NAND512_CE_HIGH;216 NAND512_Delay_uS(10);217218 NAND512_CE_LOW;219 NAND512_Delay_uS(5);220 NAND512_CL_HIGH;221 NAND512_W_LOW;222 NAND512_DB_Write(0x00);223 NAND512_Delay_uS(5);224 NAND512_W_HIGH;225 NAND512_Delay_uS(5);226 NAND512_CL_LOW;227 NAND512_Delay_uS(5);228 NAND512_AL_HIGH;229 NAND512_Delay_uS(5);230231//发送地址232for(i=0;i<4;i++)233 {239 NAND512_Delay_uS(10);240 }241 NAND512_AL_LOW;242 NAND512_Delay_uS(5);243 NAND512_CL_HIGH;244 NAND512_Delay_uS(5);245 NAND512_W_LOW;246 NAND512_Delay_uS(5);247 NAND512_DB_Write(0x30);248 NAND512_Delay_uS(5);249 NAND512_W_HIGH;250 NAND512_Delay_uS(5);251 NAND512_CL_LOW;252 NAND512_Delay_uS(5);253254while(NAND512_RB_STATUS == 0);255 NAND512_Delay_uS(5);256257for(j=0;j<Len;j++)258 {259 NAND512_R_LOW;260 NAND512_Delay_uS(5);261 Buf[j] = NAND512_DB_Read();262 NAND512_Delay_uS(5);263 NAND512_R_HIGH;264 NAND512_Delay_uS(10);265 }266267return;268 }269270char NAND512_Page_Write(char* Buf,int Len,int Add)271 {272int Bank_Index,Page_Index,Page_Start_Add;273int Add_New,j;274char i,Status;275276 Bank_Index = Add / BANK_SIZE;277 Page_Index = (Add % BANK_SIZE) / PAGE_SIZE;278 Page_Start_Add = Add % PAGE_SIZE;279 Add_New = (((Bank_Index<<6) | Page_Index)<<16) | Page_Start_Add; 280281 NAND512_CL_LOW;282 NAND512_AL_LOW;283 NAND512_W_HIGH;284 NAND512_R_HIGH;285 NAND512_CE_HIGH;286 NAND512_Delay_uS(10);287288 NAND512_CE_LOW;289 NAND512_Delay_uS(5);290 NAND512_CL_HIGH;291 NAND512_W_LOW;292 NAND512_DB_Write(0x80);293 NAND512_Delay_uS(5);294 NAND512_W_HIGH;295 NAND512_Delay_uS(5);296 NAND512_CL_LOW;297 NAND512_Delay_uS(5);298 NAND512_AL_HIGH;299 NAND512_Delay_uS(5);300301//发送地址302for(i=0;i<4;i++)303 {304 NAND512_W_LOW;305 NAND512_Delay_uS(5);306 NAND512_DB_Write(Add_New>>8*i);307 NAND512_Delay_uS(10);308 NAND512_W_HIGH;309 NAND512_Delay_uS(10);310 }311 NAND512_AL_LOW;312 NAND512_Delay_uS(5);313314for(j=0;j<Len;j++)315 {316 NAND512_W_LOW;317 NAND512_Delay_uS(5);324 NAND512_CL_HIGH;325 NAND512_Delay_uS(5);326 NAND512_W_LOW;327 NAND512_Delay_uS(5);328 NAND512_DB_Write(0x10);329 NAND512_Delay_uS(5);330 NAND512_W_HIGH;331 NAND512_Delay_uS(5);332333while(NAND512_RB_STATUS == 0);334 NAND512_Delay_uS(5);335336 Status = NAND512_Read_Status();337338if((Status & 0x01) == 0)339return1;340else341return0;342 }343344char NAND512_Block_Erase(int Add)345 {346int Bank_Index,Page_Index;347int Add_New;348char i,Status;349350 Bank_Index = Add / BANK_SIZE;351 Page_Index = (Add % BANK_SIZE) / PAGE_SIZE; 352 Add_New = (Bank_Index<<6) | Page_Index;353354 NAND512_CL_LOW;355 NAND512_AL_LOW;356 NAND512_W_HIGH;357 NAND512_R_HIGH;358 NAND512_CE_HIGH;359 NAND512_Delay_uS(10);360361 NAND512_CE_LOW;362 NAND512_Delay_uS(5);363 NAND512_CL_HIGH;364 NAND512_W_LOW;365 NAND512_DB_Write(0x60);366 NAND512_Delay_uS(5);367 NAND512_W_HIGH;368 NAND512_Delay_uS(5);369 NAND512_CL_LOW;370 NAND512_Delay_uS(5);371 NAND512_AL_HIGH;372 NAND512_Delay_uS(5);373374//发送地址375for(i=0;i<2;i++)376 {377 NAND512_W_LOW;378 NAND512_Delay_uS(5);379 NAND512_DB_Write(Add_New>>8*i);380 NAND512_Delay_uS(10);381 NAND512_W_HIGH;382 NAND512_Delay_uS(10);383 }384 NAND512_AL_LOW;385 NAND512_Delay_uS(5);386387 NAND512_CL_HIGH;388 NAND512_Delay_uS(5);389 NAND512_W_LOW;390 NAND512_Delay_uS(5);391 NAND512_DB_Write(0xD0);392 NAND512_Delay_uS(5);393 NAND512_W_HIGH;394 NAND512_Delay_uS(5);395 NAND512_CL_LOW;396 NAND512_Delay_uS(5);397398while(NAND512_RB_STATUS == 0);399 NAND512_Delay_uS(5);400401 Status = NAND512_Read_Status();H⽂件内容:1 #ifndef NAND512W3A2C__H2#define NAND512W3A2C__H34 #include "stm32f10x.h"56#define NAND512_CL_PORT GPIOD7#define NAND512_AL_PORT GPIOD8#define NAND512_W_PORT GPIOD9#define NAND512_R_PORT GPIOD10#define NAND512_CE_PORT GPIOD11#define NAND512_RB_PORT GPIOB12#define NAND512_WP_PORT /*GPIOD*/1314#define NAND512_CL_PIN GPIO_Pin_615#define NAND512_AL_PIN GPIO_Pin_516#define NAND512_W_PIN GPIO_Pin_1417#define NAND512_R_PIN GPIO_Pin_1518#define NAND512_CE_PIN GPIO_Pin_719#define NAND512_RB_PIN GPIO_Pin_520#define NAND512_WP_PIN /*GPIO_Pin_5*/2122#define NAND512_CL_CLK RCC_APB2Periph_GPIOD23#define NAND512_AL_CLK RCC_APB2Periph_GPIOD24#define NAND512_W_CLK RCC_APB2Periph_GPIOD25#define NAND512_R_CLK RCC_APB2Periph_GPIOD26#define NAND512_CE_CLK RCC_APB2Periph_GPIOD27#define NAND512_RB_CLK RCC_APB2Periph_GPIOB28#define NAND512_WP_CLK /*RCC_APB2Periph_GPIOD*/2930#define NAND512_CE_LOW GPIO_ResetBits(NAND512_CE_PORT,NAND512_CE_PIN)31#define NAND512_CE_HIGH GPIO_SetBits(NAND512_CE_PORT,NAND512_CE_PIN)32#define NAND512_CL_LOW GPIO_ResetBits(NAND512_CL_PORT,NAND512_CL_PIN)33#define NAND512_CL_HIGH GPIO_SetBits(NAND512_CL_PORT,NAND512_CL_PIN)34#define NAND512_AL_LOW GPIO_ResetBits(NAND512_AL_PORT,NAND512_AL_PIN)35#define NAND512_AL_HIGH GPIO_SetBits(NAND512_AL_PORT,NAND512_AL_PIN)36#define NAND512_W_LOW GPIO_ResetBits(NAND512_W_PORT,NAND512_W_PIN)37#define NAND512_W_HIGH GPIO_SetBits(NAND512_W_PORT,NAND512_W_PIN)38#define NAND512_R_LOW GPIO_ResetBits(NAND512_R_PORT,NAND512_R_PIN)39#define NAND512_R_HIGH GPIO_SetBits(NAND512_R_PORT,NAND512_R_PIN)4041#define NAND512_RB_STATUS GPIO_ReadInputDataBit(NAND512_RB_PORT,NAND512_RB_PIN) 4243#define NOP __nop()44#define BANK_SIZE 13107245#define PAGE_SIZE 20484647extern void NAND512_IO_Init(void);48extern char NAND512_Read_Status(void);49extern void NAND512_Read_ID(char* Buf);50extern void NAND512_Page_Read(char* Buf,int Len,int Add);51extern char NAND512_Page_Write(char* Buf,int Len,int Add);52extern char NAND512_Block_Erase(int Add);53#endif。
三星公司型号K9F1208U08的NandFlash内部物理结构
k9f1208U0B NandFlash: 4096 block 数据区:
64MB
NandFlash的总容量=4096 Blocks=66MB=64MB(Data Field+2MB(Spare Field) Data Field=512Byte*32*4096=16KB*4096=64MB (实际可以操作的容量) Spare Field=16Byte *32 *4096=0.5KB*4096=2MB (存储检验码用的)
1Byte = 8 bits
cell
bit line
bit
以页为 单位读 写数据
512 Bytes
数Байду номын сангаас区存
6
2.2 page(页)
数据 512B
Data field
528 Bytes
16 Bytes
Spare field
1page=528Byte=512Byte(Data Field)+16Bytes(Spare Field)
三星公司型号K9F1208U08的 NandFlash内部物理结构
2
1. Flash闪存
1.1 Flash的属性
Flash闪存的英文名称:Flash Memory,简称Flash. 属于非易失型存储器:即:在没有电源供应的条件下能够持久的保持数据。
3
1. Flash闪存
1.2 Flash的作用
备用区: 存检验码
16B
7
2.2 page(页)数据区分二区
512 Bytes
1st half 256B 2st half 256B
528 Bytes
16 Bytes
Spare field
基于FPGA的K9F2G08U0M Nand FLASH控制器设计
收稿 日期 :0 7 0 — 4 20 - 9 1
(k 6 ) 2 ~ 2 2 + 4。A 8 A1 被称 为行地 址 ,即页地址 。
. d. e an c c
4
电 子元 器 件 主 用 20 . 0 83
Ⅳ03 IO IO5 IO6 IO7 /4 / / /
Ⅲ
1 期 周 2 期 周
M o
o
\_ _,
表1 所列 。 表2 列 是K FG 8 O 所 9 2 0 U M的 地 址 发 送 格 式 。 表 中 。A 表示相 应 的地 址线 ,A1- 0 x l A 为列 地址 。 用于表 示 同一页 内的地 址 ,因此 。必 须小 于2 1 12
据 ,也 可 以存 放 校验 值 。 整个 芯 片包 含 1 8 页 , 2k 每 6 页构成 一 个块 (l k 。芯 片共 包 含2 个块 。 4 bo ) c k 整个 存储 区的结构 示意 图如 图 l 所示 。
加
舭
脚
。
除命 令要 将 所有2 4 个 块擦 除一遍 。擦除 一个 块 08 的时序 如 图3 示 。 所
CE L 八 几 门
枷
衰 2 F A H地 址发 送 格 式 LS
IO0 / Ⅳ01 Ⅳ02
。
。
。
西 _\ _
W E ALE RE
维普资讯
第 1卷 O
第3 期
电 子元 嚣 件 主 用
E e t n cCo o e t De ieAp l ain lcr i mp n n & o vc p i t s c o
nor_flash_读写过程
nor_flash_读写过程一、结构分析S3C2410处理器集成了8位NandFlash控制器。
目前市场上常见的8位NandFlash有三星公司的k9f1208、k9f1g08、k9f2g08等。
k9f1208、k9f1g08、k9f2g08的数据页大小分别为512Byte、2kByte、2kByte。
它们在寻址方式上有一定差异,所以程序代码并不通用。
本文以S3C2410处理器和k9f1208系统为例,讲述Nan dFlash的读写方法。
NandFlash的数据是以bit 的方式保存在memory cell里的,一般来说,一个cell 中只能存储一个bit,这些cell 以8 个或者16 个为单位,连成bit line,形成所谓的byte(x8)/word(x16),这就是NAND Device的位宽。
这些Line 组成Page,page 再组织形成一个Block。
k9f1208的相关数据如下:1block=32page;1page=528byte=512byte(Main Area)+16byte(Spare Area)。
总容量为=4096(block数量)*32(page/block)*512(byte/page)=64MbyteNandFlash以页为单位读写数据,而以块为单位擦除数据。
按照k9f1208的组织方式可以分四类地址:Col umn Address、halfpage pointer、Page Address 、Block Address。
A[0:25]表示数据在64M 空间中的地址。
Column Address表示数据在半页中的地址,大小范围0~255,用A[0:7]表示;halfpage pointer表示半页在整页中的位置,即在0~255空间还是在256~511空间,用A[8]表示;Page Address表示页在块中的地址,大小范围0~31,用A[13:9]表示;Block Address表示块在flash中的位置,大小范围0~4095,A[25:14] 表示;二、读操作过程K9f1208的寻址分为4个cycle。
闪存型号容量对照.docx
型号品牌类型容量K9F2808U0C Samsung SLC 16MB K9F2808U0B Samsung SLC 16MB K9F5608U0B Samsung SLC 32MB K9F5616U0C Samsung SLC 32MB K9F1208U0M(A) Samsung SLC 64MB K9F1G08UOC Samsung SLC 128MB K9K(T)1G08U0M(A) Samsung SLC 128MB K9F1G08U0B Samsung SLC 128MB K9F1G08U0M(A) Samsung SLC 128MB K9F(K)2G08U0M(A) Samsung SLC 256MB K9F2G08U0A Samsung SLC 256MB K9F2G08U0B Samsung SLC 256MB K9K4G08U0M Samsung SLC 512MB K9F4G08U0M Samsung SLC 512MB K9G4G08UOA Samsung MLC 512MB K9G4G08U0M Samsung MLC 512MB K9G4G08UOB Samsung SLC 512MB K9F8G08UOB Samsung SLC 1GBK9F8G08U0M Samsung SLC 1GBK9G8G08U0A Samsung MLC 1GBK9G8G08U0B Samsung MLC 1GBK9G8G08U0M Samsung MLC 1GBK9L8G08U0A/M Samsung MLC 1GBK9HAG08U1M Samsung MLC 2GBK9WAG08U1A Samsung SLC 2GBK9K8G08U0M Samsung SLC 1GBK9K8G08U0A Samsung SLC 1GBK9WBG08U1M Samsung SLC 4GBK9LBG08UOD Samsung MLC 4GBK9GAG08U0M Samsung MLC 2GBK9LAG08U0M Samsung MLC 2GBK9GAG08U0M Samsung MLC 2GBK9GAG08U0D Samsung MLC 2GBK9HBG08U1M Samsung MLC 4GBK9HBG08U1A Samsung MLC 4GBK9MBG08U5M Samsung MLC 4GBK9LBG08U0M Samsung MLC 4GBK9HCG08U1M Samsung MLC 8GBK9MDG08U5M Samsung MLC 16GB HY27US08281A/B HYNIX SLC 16MB HY27US08561M HYNIX SLC 32MBHY27US08561A HYNIX SLC 32MB HY27US16562A HYNIX SLC 32MB HY27US08121B HYNIX SLC 64MB HY27US08121M HYNIX SLC 64MB HY27UF081G2A HYNIX SLC 128MB HY27UF081G2M HYNIX SLC 128MB HY27UA081G1M HYNIX SLC 128MB HY27UB082G4M HYNIX SLC 256MB HY27UF082G2A HYNIX SLC 256MB HY27UF082G2B HYNIX SLC 256MB HY27UF(G)082G2M HYNIX SLC 256MB HY27UU(T)084G2M HYNIX MLC 512MB HY27UT084G2A HYNIX MLC 512MB HY27UF084G2MW HYNIX SLC 512MB HY27UG(H)084G2A HYNIX SLC 512MB HY27UF(G)084G2M HYNIX SLC 512MB HY27UF084G2B HYNIX SLC 512MB HY27UG088G5M HYNIX SLC 1GB HY27UH088G2M HYNIX SLC 1GB HY27UG088G2M HYNIX SLC 1GB HY27UG084G2B HYNIX SLC 512MB HY27UG088G5B HYNIX SLC 1GB HY27UU088G5M HYNIX MLC 1GB HY27UT088G2M HYNIX MLC 1GB HY27UU08AG5M HYNIX MLC 2GB HY27UV08BGFM HYNIX MLC 4GB HY27UH08AG5M HYNIX SLC 2GB HY27UV08AG5M HYNIX MLC 2GBH27UBG8U5MTR HYNIX MLC 4GBH27UAG8T2MTR HYNIX MLC 2GB HY27UW08BGFM HYNIX MLC 4GB HY27UU08AG2M HYNIX MLC 2GB HY27UV08BG5M HYNIX MLC 4GB HY27UW08CGFM HYNIX MLC 8GB HY27UW08CGFA HYNIX MLC 8GB MT29F2G08AAC Micron SLC 256MB MT29F2G08AAA Micron SLC 256MB MT29F2G16AAB Micron SLC 256MB MT29F2G08X Micron SLC 256MB MT29F2G08AAB Micron SLC 256MB MT29F4G08MAA Micron MLC 512MB MT29F4G08AAA Micron SLC 512MBMT29F4G08AAA(1) Micron SLC 512MB MT29F8G08FAB Micron SLC 1GB MT29F8G08DAA Micron SLC 1GB MT29F8G08QAA Micron MLC 1GB MT29F8G16MAA Micron MLC 1GB MT29F128G08CJWAAAWC Micron MLC 16GB MT29F8G08MAD Micron MLC 1GB MT29F8G08BAA Micron SLC 1GB MT29F8G08MAA Micron MLC 1GB MT29F16G08FAA Micron SLC 2GB MT29F16G08QAA Micron MLC 2GB MT29F16G08MAA Micron MLC 2GB MT29F16G08TAA Micron MLC 2GB MT29F32G08QAA Micron MLC 4GB MT29F32G08CBAAAWP Micron MLC 4GB MT29F32G09CFAAA Micron MLC 8GB MT29F32G08TAA Micron MLC 4GB MT29F32G08FAA Micron SLC 4GB MT29F32G08TAA1 Micron MLC 4GB MT29F64G08TAA Micron MLC 8GB MT29F64G08MAA Micron MLC 8GB JS29F02G08AAA intel SLC 256MB JS29F04G08FANB3 intel MLC 512MB JS29F8G08CANCI intel MLC 1GB JS29F16G08CANCI intel MLC 2GB JS29F16G08CANC2 intel MLC 2GB JS29F08G08CANC1 intel MLC 1GB JS29F08G08AAMB2 intel MLC 1GB JS29F16G08CAMB2 intel SLC 2GB JS29F16G08AAMC1 intel MLC 2GB JS29F32G08CAMC1 intel MLC 4GB JS29F32G08FAMB2 intel MLC 4GB JS29F32G08AAMDB intel MLC 4GB JS29F32G08AAMD2 intel MLC 4GB JS29F64G08CAMDB intel MLC 8GB JS29F64G08CAMD1 intel MLC 8GB JS29F128G08FAMC1 intel MLC 16GB TC58128(A)FT Toshiba SLC 16MB TC58256(A)FT Toshiba SLC 32MB TC58DVM82A1FT Toshiba SLC 32MB TC58512(A)FT Toshiba SLC 64MB TC58DVM92A1FT Toshiba SLC 64MBTC58DVG02A1FT Toshiba MLC 128MB TC58NVG0S3BFT Toshiba SLC 128MB TC58NVG0D3BTG Toshiba MLC 128MB TC58NVG1S3BFT Toshiba SLC 256MB TC58DVG14B1FT00 Toshiba SLC 256MB TC58NVG1D4BTG00 Toshiba MLC 256MB TC58NVG2D4BFT00 Toshiba MLC 512MB TC58NG3D4BTG00 Toshiba MLC 1GBB TH58NVG2S3BFT Toshiba SLC 512MB TH58NVG2D3BTG00 Toshiba SLC 512MB TC58NVG3D1DTG00 Toshiba MLC 1GB TC58NVG3D4CTGI0 Toshiba MLC 1GB TH58NVG3D4BTG00 Toshiba MLC 1GB TC58NVG4D4CTG00 Toshiba MLC 2GB TC58NVG4D1DTG00 Toshiba MLC 2GB TH58NVG4D4CTG00 Toshiba MLC 2GB TH58NVG5D4CTG20 Toshiba MLC 4GB TH58NVG4D4DTG00 Toshiba MLC 4GB TC58NVG5D1DTG00 Toshiba MLC 4GB TH58NVG6D1DTG20 Toshiba MLC 8GB TH58NVG6D1DTG80 Toshiba MLC 8GB。
闪存型号容量对照
K9MDG08U5M Samsung MLC16GB HY27US08281A/B HYNIX SLC16MB HY27US08561M HYNIX SLC32MB
HY27US08561A HYNIX SLC32MB HY27US16562A HYNIX SLC32MB HY27US08121B HYNIX SLC64MB HY27US08121M HYNIX SLC64MB HY27UF081G2A HYNIX SLC128MB HY27UF081G2M HYNIX SLC128MB HY27UA081G1M HYNIX SLC128MB HY27UB082G4M HYNIX SLC256MB HY27UF082G2A HYNIX SLC256MB HY27UF082G2B HYNIX SLC256MB HY27UF(G)082G2M HYNIX SLC256MB HY27UU(T)084G2M HYNIX MLC512MB HY27UT084G2A HYNIX MLC512MB HY27UF084G2MW HYNIX SLC512MB HY27UG(H)084G2A HYNIX SLC512MB HY27UF(G)084G2M HYNIX SLC512MB HY27UF084G2B HYNIX SLC512MB HY27UG088G5M HYNIX SLC1GB HY27UH088G2M HYNIX SLC1GB HY27UG088G2M HYNIX SLC1GB HY27UG084G2B HYNIX SLC512MB HY27UG088G5B HYNIX SLC1GB HY27UU088G5M HYNIX MLC1GB HY27UT088G2M HYNIX MLC1GB HY27UU08AG5M HYNIX MLC2GB HY27UV08BGFM HYNIX MLC4GB HY27UH08AG5M HYNIX SLC2GB HY27UV08AG5M HYNIX MLC2GB
三星的NAND FLASH K9F4G08U0D
K9F4G08U0D K9K8G08U1D K9K8G08U0D K9WAG08U1D
Revision History
RevInitial issue
0.1
1. Corrected errata.
2. Chapter 1.2 Features revised.
0.2
2.0 PRODUCT INTRODUCTION...................................................................................................................................... 9 2.1 Absolute Maximum Ratings ..................................................................................................................................... 10 2.2 Recommended Operating Conditions ..................................................................................................................... 10 2.3 DC AND OPERATING CHARACTERISTICS(Recommended operating conditions otherwise noted.) ..................10 2.4 Valid Block............................................................................................................................................................... 11 2.5 Ac Test Condition .................................................................................................................................................... 11 2.6 Capacitance(TA=25°C, VCC=3.3V, f=1.0MHz) ....................................................................................................... 11 2.7 Mode Selection........................................................................................................................................................ 11 2.8 Program / Erase Characteristics ........................................................................................................................12 2.9 AC Timing Characteristics for Command / Address / Data Input ............................................................................ 12 2.10 AC Characteristics for Operation........................................................................................................................... 13
K9F2G08U0A 中文数据手册
8
K9F2G08R0A K9F2G08U0A
图1. K9F2G08X0A 功能框图
VCC VSS
A12 - A28(地址) A0 - A11(地址)
X-Buffers Latches & Decoders
(行地址锁存缓存区&译码)
Y-Buffers Latches & Decoders
(列地址锁存缓存区&译码)
63-∅0.45±0.05
∅ 0.20 M A B
底视图
#A1 索引标记(可选)
10.00±0.10 0.80 x 9= 7.20 0.80 x 5= 4.00
0.80 654321
A B
0.80
0.25(最小) 1.00(最大)
侧视图
13.00±0.10
2.00 0.45±0.05
0.80 x 7= 5.60 0.80 x 11= 8.80
13.00±0.10
6
K9F2G08R0A K9F2G08U0A
引脚配置 (ULGA封装)
7 6 5 4 3 2 1
K9F2G08U0A-ICB0/IIB0
A B C DE FG HJ K L M N
NC
NC
NC
NC
NC
NC
NC
/RE
NC
NC
NC
NC
NC
Vcc
NC
Vss
IO7
IO5
Vcc
/CE
NC
3
K9F2G08R0A K9F2G08U0A
引脚配置 (TSOP1封装)
K9F2G08U0A-PCB0/PIB0
N.C N.C
1 2
51单片机控制K9K8G08U0CNANDFlash读写程序
51单片机控制K9K8G08U0C NAND Flash读写程序#include#include#include/*********************************************************************/sbit NF_CLE=P0^3; //命令锁存使能(输出) CLE D3sbit NF_ALE=P3^4; //地址锁存使能(输出) ALE RSsbit NF_WE=P1^3; //NAND Flash写使能(输出) /WE DB4sbit NF_RE=P1^2; //NAND Flash读使能(输出) /RE DB3sbit NF_CE=P3^7; //NAND Flash片选使能(输出)/CE RDsbit NF_R_B=P3^5; //NAND Flash就绪/忙(输入)r/b R/D_LCDENsbit NF_WP=P3^6; //不用(已接到VCC) /WP#define NF_DATA P2/************************************************ **********************/sbit DIOLA=P2^5;/************************************************ *********************///unsigned int DataArray[10];/************************************************ *******************/// 12c5A60S2单片机初始化/************************************************ *******************/void MCU_Init(){P0M0=0x00;P0M1=0x00;P1M0=0x00;P1M1=0x00;P2M0=0x00;P2M1=0x00;P3M0=0x00;P3M1=0x00;AUXR=0x00;//TMOD=0x21;}/************************************************ *******************/void TimerInit(){TMOD=0x20; //设置定时器1为工作方式2 (0x22;)TH1=0xfd; //装入初值 (0xef;)TL1=0xfd; //装入初值 (0xef;)TR1=1; //启动定时器REN=1; //允许串口接收位SM0=1;SM1=0; //方式1SCON=0x50;///////EA=1;ES=1;// PCON=0x80;//PS=1;//PT0=0;} //晶振:22.1184M 波特率:19200/************************************************ *******************///延时/************************************************ *******************/void delay(unsigned int z)//延时参数(z)无反回值的子程序(void表示无反值){unsigned int x,y;for(x=z;x>0;x--)for(y=100;y>0;y--);}/************************************************ ********************//模块名:51单片机控制K9K8G08U0C的读写程序//功能描述:NANDFLASH读写程序//兼容性 :适合大部分的NANDFLASH,如需要根据手册做简单修改即可//芯片型号: STC89C516RD STC12C5A60S2等。
NANDFlash大容量存储器K9F1G08U的坏块管理方法
NANDFlash大容量存储器K9F1G08U的坏块管理方法NAND Flash大容量存储器K9F1G08U的坏块管理方法在进行数据存储的时候,我们需要保证数据的完整性,而NAND Flash大容量存储器K9F1G08U芯片由于工艺上问题,不可避免就会出现有的Block中就是某个位或某些位是块的,就是用块擦除命令也是无法擦除的,K9F1G08U数据手册也讲了坏块是存在的,对于K9F1G08U最多有20个坏块。
如果数据存储到这个坏块中,就无法保证该数据存储的完整性。
对于坏块的管理K9F1G08U数据手册也有它的方法去处理该坏块的方法,我根据实际经验总结出自己的一种方法。
首先我们要定义一个坏块管理表:unsigned char BadBlockTable[128],此数组可以存储1024个Block状态,即每一个字节存储8个Block状态。
我们要存储一批数据到NAND Flash中去某个Block时,先执行Block擦除操作,然后分析该Block的1st Page和2st Page中的每个位是否全是FFH,如果全是FFH,则在BadBlockTable数组当前Block对应的字节位给置0,否则置1。
如果是1表示当前的块是不能存储数据的,这时需要更换下一个Block来存储这些数据,这样我们重复上面的动作分析再进行分析是否可以存储数据,该块能存储就存储到该块中去。
具体实现的算法程序如下:Flag=TRUE;while(TRUE==Flag){Erase_K9F1G08U_Block(K9F1G08U.HighAddress,K9F1G08U.L owAddress);Flag=Check_K9F1G08U_Block(K9F1G08U.HighAddress/64);if(TRUE==Flag)//is invalid block{BadBlockTable[K9F1G08U.HighAddress/512]|=(1<<(K9F1G08U.HighAddress%8));K9F1G08U.HighAddress+=64;//Point to Next Block}else// is valid block ,record to BadBlockTable{BadBlockTable[K9F1G08U.HighAddress/512]&=~(1<<(K9F1G08U.HighAddress%8));}}for(i=0;i<sizeof(BadBlockTable);i++)Write_RAM(RAM_BANK_0,K9F1G08U_BAD_BLOCK+i,BadBlo ckTable[i]);。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
1.0
1.1
1. 1.8V AC timing is changed
2. tRPB/tRCB/tREAB is added for 1.8V device
1.2
1. tCSD is changed.(10ns -> 0ns)
1.3
1. tCS 31ns -> 25ns, tREH 15ns -> 10ns (@ 1.8V)
33
N.C
32
I/O3
31
I/O2
30
I/O1
29
I/O0
28
N.C
27
N.C
26
N.C
25
N.C
PACKAGE DIMENSIONS
48-PIN LEAD/LEAD FREE PLASTIC THIN SMALL OUT-LINE PACKAGE TYPE(I) 48 - TSOP1 - 1220F
17
WE
18
WP
19
N.C
20
N.C
21
N.C
22
N.C
23
N.C
24
48-pin TSOP1 Standard Type 12mm x 20mm
48
N.C
47
N.C
46
N.C
45
N.C
44
I/O7
43
I/O6
42
I/O5
41
I/O4
40
N.C
39
N.C
38
N.C
37
Vcc
36
Vss
35
N.C
34
N.C
Revision History
Revision No History
0.0
1. Initial issue
0.1
1. 1.8V part is added.
2. tRHW, tCSD parameter is defined.
3. 4G DDP LGA part is deleted.
4. Technical note is added.(p.18)
- K9F2G08R0A-JCB0/JIB0 : Pb-FREE PACKAGE 63 - Ball FBGA I (10 x 13 / 0.8 mm pitch)
- K9F2G08U0A-PCB0/PIB0 : Pb-FREE PACKAGE 48 - Pin TSOP I (12 x 20 / 0.5 mm pitch) - K9F2G08U0A-ICB0/IIB0 52 - Pin ULGA (12 x 17 / 1.00 mm pitch)
GENERAL DESCRIPTION
Offered in 256Mx8bit, the K9F2G08X0A is a 2G-bit NAND Flash Memory with spare 64M-bit. Its NAND cell provides the most costeffective solution for the solid state application market. A program operation can be performed in typical 200µs on the (2K+64)Byte page and an erase operation can be performed in typical 1.5ms on a (128K+4K)Byte block. Data in the data register can be read out at 25ns(42ns with 1.8V device) cycle time per Byte. The I/O pins serve as the ports for address and data input/output as well as command input. The on-chip write controller automates all program and erase functions including pulse repetition, where required, and internal verification and margining of data. Even the write-intensive systems can take advantage of the K9F2G08X0A′s extended reliability of 100K program/erase cycles by providing ECC(Error Correcting Code) with real time mapping-out algorithm. The K9F2G08X0A is an optimum solution for large nonvolatile storage applications such as solid state file storage and other portable applications requiring non-volatility.
3
K9F2G08R0A K9F2G08U0A
FLASH MEMORY
PIN CONFIGURATION (TSOP1)
K9F2G08U0A-PCB0/PIB0
N.C
1
N.C
2
N.C
3
N.C
4
N.C
5
N.C
6
R/B
7
RE
8
CE
9
N.C
10
N.C
11
Vcc
12
Vss
13
N.C
14
N.C
15
CLE
16
ALE
2
K9F2G08R0A K9F2G08U0A
256M x 8 Bit NAND Flash Memory
PRODUCT LIST
Part Number K9F2G08R0A-J K9F2G08U0A-1.65 ~ 1.95V
2.70 ~ 3.60V
FLASH MEMORY
- Program/Erase Lockout During Power Transitions • Reliable CMOS Floating-Gate Technology
-Endurance : 100K Program/Erase Cycles(with 1bit/512Byte ECC)
- Data Retention : 10 Years • Command Driven Operation • Intelligent Copy-Back with internal 1bit/528Byte EDC • Unique ID for Copyright Protection • Package :
Unit :mm/Inch
0.10 MAX
0.004
20.00±0.20 0.787±0.008
#1
#48
0.008-+00..000013
+0.07 -0.03
)
0.25 0.010
Organization X8
PKG Type FBGA TSOP1
52ULGA
FEATURES
• Voltage Supply - 1.65V ~ 1.95V - 2.70V ~ 3.60V
• Organization - Memory Cell Array : (256M + 8M) x 8bit - Data Register : (2K + 64) x 8bit
The attached data sheets are prepared and approved by SAMSUNG Electronics. SAMSUNG Electronics CO., LTD. reserve the right to change the specifications. SAMSUNG Electronics will evaluate and reply to your requests and questions about device. If you have any questions, please contact the SAMSUNG branch office near your office.
K9F2G08R0A K9F2G08U0A
FLASH MEMORY
K9F2G08UXA
INFORMATION IN THIS DOCUMENT IS PROVIDED IN RELATION TO SAMSUNG PRODUCTS, AND IS SUBJECT TO CHANGE WITHOUT NOTICE. NOTHING IN THIS DOCUMENT SHALL BE CONSTRUED AS GRANTING ANY LICENSE, EXPRESS OR IMPLIED, BY ESTOPPEL OR OTHERWISE, TO ANY INTELLECTUAL PROPERTY RIGHTS IN SAMSUNG PRODUCTS OR TECHNOLOGY. ALL INFORMATION IN THIS DOCUMENT IS PROVIDED ON AS "AS IS" BASIS WITHOUT GUARANTEE OR WARRANTY OF ANY KIND. 1. For updates or additional information about Samsung products, contact your nearest Samsung office. 2. Samsung products are not intended for use in life support, critical care, medical, safety equipment, or similar