微波EDA网,见证研发工程师的成长!
首页 > 硬件设计 > 嵌入式设计 > S3C2440对Nand Flash操作和电路原理(基于K9F2G08U0A)

S3C2440对Nand Flash操作和电路原理(基于K9F2G08U0A)

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

(3)使用CVAVR中的编程下载程序时应特别注意,由于CVAVR编程下载界面初始打开时,大部分熔丝位的初始状态定义为“1”,因此不要使用其编程菜单选项中的“all”选项。此时的“all”选项会以熔丝位的初始状态定义来配置芯片的熔丝位,而实际上其往往并不是用户所需要的配置结果。如果要使用“all”选项,应先使用“read->

for(i=5;i>

for(k=150;k>

for(j=4;j>

定的(比如说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); }//复位ECC

#define NF_MECC_UnLock(){rNFCONT &= ~(1<5); }//解锁main区ECC

#define NF_MECC_Lock(){rNFCONT |= (1<5); }//锁定main区ECC

#define NF_SECC_UnLock() {rNFCONT &= ~(1<6); }//解锁spare区ECC

#define NF_SECC_Lock(){rNFCONT |= (1<6); }//锁定spare区ECC

NFSTAT是另一个比较重要的寄存器,它的第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++ );等一段时间

//读五个周期的ID

pMID = NF_RDDATA8();//厂商ID:0xEC

pDID = NF_RDDATA8();//设备ID:0xDA

cyc3 = NF_RDDATA8();//0x10

cyc4 = NF_RDDATA8();//0x95

cyc5 = NF_RDDATA8();//0x44

NF_nFCE_H();//关闭nandflash片选

return (pDID);

}

下面介绍Nand Flash读操作,读操作是以页为单位进行的。如果在读取数据的过程中不进行ECC校验判断,则读操作比较简单,在写入读命令的两个周期之间写入要读取的页地址,然后读取数据即可。如果为了更准确地读取数据,则在读取完数据之后还要进行E

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

网站地图

Top