您的位置 首页 系统

arm2440的nandflash相关函数

K9F2G08U0Anandflash的容量为256Mbyte,其内部有2048块,每块有64页,每页有2K+64字节,其中每页会分为main区(主域)和spare区(备用

K9F2G08U0A nand flash 的容量为256M byte,其内部有2048块,每块有64页,每页有2K+64字节,其间每页会分为main区(主域)和spare区(备用域),main区一般用来存入首要数据,spare一般用来寄存ECC校验码。

下面几点是编程时需求留意的:

1.NAND FLASH芯片手册里说的column是指页内地址,row是指页地址,page也是指页;

2.删去时是以块为单位的,可是删去块时写的是row地址,主动会删去row地点的块;

3.读写方法有页读写,或随机读写,所谓的随机读写便是能够在页内的任一当地读写一个字节;

4.ECC校验码分为main区的ECC和spare区的ECC,它们一般都会寄存在64字节的spare区内,下面是翻译2440手册的关于ECC编程的内容:

ECC 编程导游

1) 在软件形式, ECC 模块会为悉数读 / 写数据发生 ECC 查验码。所以你需求在读或许写数据前给 InitECC(NFCONT[4]) 位写 1 和给 MainECCLock(NFCONT[5]) 位写 0(Unlock) 来复位 ECC 值。

MainECCLock(NFCONT[5]) 和 SpareECCLock(NFCONT[6] 操控 ECC 校验码是否发生。

2) 任何时候读或许写数据时, ECC 模块在 NFMECC0/1 上发生 ECC 校验码。

3) 在你完结读或许写一个页后(不包括备用数据域),给 MainECCLock 方位 1(lock) 。 ECC 校验码被锁上, ECC 状况寄存器的值将不会被改动。

4) 清 0(Unlock) SpareECCLock(NFCONT[6]) 位来发生备用域的 ECC 校验码。

5) 任何时候读或许写数据时,备用域 ECC 模块在寄存器 NFSECC 上发生 ECC 校验码。

6) 在完结读或许写备用域后,给 SpareECCLock 方位 1(lock) 。 ECC 校验码被锁上, ECC 状况寄存器的值将不会被改动。

7) 一旦完结你就能够运用这些值来记载到备用域或许检测位过错。

接下来是代码:

NAND-FLASH.H内容:

#ifndef __NAND_FLASH_H__ //为了避免重复包括
#define __NAND_FLASH_H__

#include “lhg_def.h” //U8,U32相关的宏,也即变量类型

#define MAX_NAND_BLOCK 2048
#define NAND_PAGE_SIZE 2048 //2048 blocks,1block has 64pages, each page has 2k+64 bytes
typedef struct nand_id_info //这样的结构体变量保存芯片的ID信息
{
U8 IDm; //marker code
U8 IDd; //device code
U8 ID3rd;
U8 ID4th;
U8 ID5th;
} nand_id_info;

typedef struct bad_block_info //挂号坏块用的,只记载数量,没有记载坏块地址
{
U8 area[MAX_NAND_BLOCK];//0表明非坏块,1表明坏块
U32 sum;//坏块的总数
} bad_block_info;

//

//NAND 操作指令,??从哪里来的,我看你怎样用
#define NAND_CMD_READ_1st 0x00
#define NAND_CMD_READ_2st 0x30
#define NAND_CMD_RANDOM_WRITE 0x85
#define NAND_CMD_RANDOM_READ_1st 0x05
#define NAND_CMD_RANDOM_READ_2st 0xe0
#define NAND_CMD_READ_CB_1st 0x00
#define NAND_CMD_READ_CB_2st 0x35
#define NAND_CMD_READ_ID 0x90
#define NAND_CMD_RES 0xff
#define NAND_CMD_WRITE_PAGE_1st 0x80
#define NAND_CMD_WRITE_PAGE_2st 0x10
#define NAND_CMD_BLOCK_ERASE_1st 0x60
#define NAND_CMD_BLOCK_ERASE_2st 0xd0
#define NAND_CMD_READ_STATUS 0x70

//NAND 中止向量,?这是什么意思
#define INT_NFCON (24)

//NFCONF HCLK=100MHZ,nandflash configuration register
#define S3C2440_NFCONF_TACLS_init (1<<12) //设置cle ale的持续时间,NFCONF[14:12]
#define S3C2440_NFCONF_TWRPH0_init (4<<8) //TWRPH0持续时间设置,NFCONF[10:8]
#define S3C2440_NFCONF_TWRPH1_init (0<<4) //TWRPH1持续时间设置,NFCONF[6:4]
#define S3C2440_NFCONF_BusWidth_init (0) //bus_width for autobooting or general access,0 for1B
#define S3C2440_NFCONF_init() ( rNFCONF = S3C2440_NFCONF_TACLS_init | /
S3C2440_NFCONF_TWRPH0_init | /
S3C2440_NFCONF_TWRPH1_init | /
S3C2440_NFCONF_BusWidth_init ) //牛逼啊这句话

//NFCONT,nandflash control register
#define S3C2440_NFCONT_LockTight_init (0<<13)//disable lock-tight
#define S3C2440_NFCONT_SoftLock_init (0<<12)//disable lock
#define S3C2440_NFCONT_EnbIllegalAccINT_init (1<<10)//illegal access interrupt enable
#define S3C2440_NFCONT_EnbRnBINT_init (0<<9)//RnB ready not busy
#define S3C2440_NFCONT_RnB_TransMode_init (0<<8)//detect RnB type is rising edge
#define S3C2440_NFCONT_SpareECCLock_init (1<<6)//1 is to lock sparearea ecc generation
#define S3C2440_NFCONT_MainECCLock_init (1<<5)//1 is to lock main area ecc generation
#define S3C2440_NFCONT_InitECC_init (1<<4)//1 is to initialize ecc decoder and encoder
#define S3C2440_NFCONT_Reg_nCE_init (1<<1)//force nFCE to high,namely disable chip-select
#define S3C2440_NFCONT_MODE_init (0)//disable nandflash controller
#define S3C2440_NFCONT_init() ( rNFCONT = S3C2440_NFCONT_LockTight_init | /
S3C2440_NFCONT_SoftLock_init | /
S3C2440_NFCONT_EnbIllegalAccINT_init | /
S3C2440_NFCONT_EnbRnBINT_init | /
S3C2440_NFCONT_RnB_TransMode_init | /
S3C2440_NFCONT_SpareECCLock_init | /
S3C2440_NFCONT_MainECCLock_init | /
S3C2440_NFCONT_InitECC_init | /
S3C2440_NFCONT_Reg_nCE_init | /
S3C2440_NFCONT_MODE_init )

//NFSTAT
#define S3C2440_NFSTAT_init() ( rNFSTAT &= 0x3 )//NFSTAT 8 bits, 0x3 means nCE output high,
//nandflash is ready to operate
//NFESTAT0
#define S3C2440_NFESTAT0_init() ( rNFESTAT0 = 0 )//ecc status for io0-io7,k9f1208 only io0-i07

//NFESTAT1
#define S3C2440_NFESTAT1_init() ( rNFESTAT1 = 0 )//ecc status for io8-io15

//
#define select_nand() ( rNFCONT &= ~(1<<1) )
#define dis_select_nand() ( rNFCONT |= 1<<1 )片选信号设置不说了啊
#define controller_enable() ( rNFCONT |= 1 )
#define controller_disable() ( rNFCONT &= ~1 )nandflash操控器使能与否也不说了

//
extern void nand_flash_init(void);//初始化,extern意思是提供给外部上层函数要调用的进口
extern int nand_block_erase(U32 num);//num要删去的块号,总共2048个块,这么大变量浪费了!
extern int nand_page_write(U32 addr,U8 *buffer,U32 size);//addr要写的起始页地址,buffer要写的缓存,size要写的字节巨细最大为4G,这儿是针对u32说的
extern int nand_page_read(U32 addr,U8 *buffer,U32 size);//addr开端页地址,从每页00地址开端读
extern int nand_random_read(U32 paddr,U32 offset,U8 *data); //随机读数据 paddr页地址,offset页内偏移地址,每次一个字节
extern int nand_random_write(U32 paddr,U32 offset,U8 data);//随机写,paddr页地址,offset页内偏移地址
extern void nand_test_bad_block(void);//测验坏块函数,并符号在nand_bbi变量里和spare区最终一个地址(假设非0xff则为坏块??原因是什么)

#endif

NAND-FLASH.c内容:

#include “2440addr.h”
#include “NAND-FLASH.h”
#include “uart.h”
#include “lhg_def.h”
//#include “iic_lhg.h”

#define NAND_DEBUG 1
#define USE_ECC 1

nand_id_info nand_id;//界说挂号芯片ID的全局变量
bad_block_info nand_bbi;//界说来挂号坏用的全局变量

void init_nand_bbi(void)//初始化变量
{
U32 i;
nand_bbi.sum=0;
for (i=0;i nand_bbi.area[i]=0;//这儿放的是块数,针对k9f1208是2048块
}

void nand_mask_bad_block(U32 n)//标志坏块,n是坏块的块号
{
#ifdef NAND_DEBUG//宏界说的一种,尼玛也能够写在这儿
Uart_Printf(“NAND found and mask a bad block=%d .”,n);
#endif
if (nand_bbi.area[n]!=1)//留意这儿是对进口参数n操作的
{
nand_bbi.area[n]=1;
nand_bbi.sum++;
nand_random_write(n*64,2048+64-1,0);//每块的第一个spare的最终一个字节,标志本块是否为坏块,非0xff为坏块,页地址核算中要看详细芯片一块中有多少页,例如k9f1208是32页
}
}

int detect_nand_busy(void)//检测是否忙
{
U32 a;
a=0;
while(!(rNFSTAT&(1<<2)))//也即RnB状况,0表明忙
{
a++;
if (a==5000000)//等候超时
{
Uart_Printf(“/r/n Error: Detect Nand Busy time out!!! /r/n”);
rNFSTAT |= (1<<2);//清忙标志,1表明不忙
return -1;//过错回来-1,这个-1表明的是你他妈的nandflash一向忙,这儿是有问题的
}
}

rNFSTAT |= (1<<2);//清忙标志,没有超时,我给你正常设为悠闲,回来值也没问题
return 1;
}

void nand_reset(void)//复位
{
rNFCMD = NAND_CMD_RES;//?从哪里查到的NFCMD指令调集?和韦教材相同,0xff为复位指令
detect_nand_busy();//检测忙,?为什么复位后检测nandflash忙不忙呢?假设忙阐明程序犯错在读写
}

void control_start(void){ //敞开
select_nand();
controller_enable();//也即最终两位启用nandflash和选中nandflash
rNFSTAT |= (1<<2);//清忙标志
nand_reset();
}

void control_end(void) //封闭
{
dis_select_nand();//撤销片选,封闭nandflash操控器
controller_disable();
}

void ecc_main_init(void)//初始化ECC值
{
rNFCONT |= 1<<4;//NFCONT[4]初始化ecc编解码器
void ecc_main_start(void)//开端main ECC
{
rNFCONT &= ~(1<<5);//unlock NFCONT[5],main area能够发生ecc
}

ecc_main_end(void)//完毕main ECC
{
rNFCONT |= 1<<5;//unlock,main area不能够再发生ecc 了
}

void ecc_spare_start(void)//开端spare ECC
{
// rNFCONT |= 1<<4; //initEcc
rNFCONT &= ~(1<<6); //unlock,NFCONT[6]操控spare area的ecc发生
}

void ecc_spare_end(void)//完毕spare ECC,相同道理封闭ecc的发生
{
rNFCONT |= 1<<6; //unlock
}

void __irq nandINT(void) //中止函数
{
//此处写处理代码
#ifdef NAND_DEBUG
Uart_Printf(“/r/n Nand Error… In interrupt now!!!”);//只要过错才会进入中止
#endif
rSRCPND |= 0x1< rINTPND |= 0x1<}

void nand_read_id(void)//读取芯片ID信息
{
control_start();//开操控选中nandflash和敞开nandflash操控器
rNFCMD = NAND_CMD_READ_ID;//读id指令为0x90,韦教材上有
rNFADDR = 0;//nandflash address set register,不是宣布4个地址序列吗????
//读ID
nand_id.IDm=(U8)rNFDATA8;//强制转换为8位的,制造商
nand_id.IDd=(U8)rNFDATA8; //设备代码
nand_id.ID3rd=(U8)rNFDATA8;//保存字节
nand_id.ID4th=(U8)rNFDATA8;//多层操作代码
nand_id.ID5th=(U8)rNFDATA8;//??不知道是什么,横竖总共5个信息数据

#ifdef NAND_DEBUG
Uart_Printf(“/r/n Read NAND Flash ID:”);
Uart_Printf(“/r/n NAND Mark code: 0x%x “,nand_id.IDm);//打印ID信息
Uart_Printf(“/r/n NAND Device code: 0x%x “,nand_id.IDd);
Uart_Printf(“/r/n NAND 3rdID code: 0x%x “,nand_id.ID3rd);
Uart_Printf(“/r/n NAND 4thID code: 0x%x “,nand_id.ID4th);
Uart_Printf(“/r/n NAND 5thID code: 0x%x “,nand_id.ID5th);
#endif

control_end();//关操控,撤销片选和封闭nandflash操控器
}

int nand_block_erase(U32 num)//num要擦除的块号
{
num=num*64;//表明要擦除的块地址,这种nandflash每一个块有64页,其他的就不必定了哈哈
control_start();//开操控
nand_reset();//复位
rNFCMD = NAND_CMD_BLOCK_ERASE_1st;//0x60指令
rNFADDR = num&0xff;//需求发3个地址序列,这儿有3个,非常好!!!
rNFADDR = (num>>8)&0xff;
rNFADDR = (num>>16)&0xff;
rNFCMD = NAND_CMD_BLOCK_ERASE_2st;//0xd0指令
detect_nand_busy();//看看nandflash忙不忙

rNFCMD =NAND_CMD_READ_STATUS; //读擦出的成果状况,指令是0x70
if (rNFDATA8&1)//假设最高位是1,下面报错,便是说擦除这个块没有成功,这个得记住!
{
#ifdef NAND_DEBUG
Uart_Printf(“/r/n Error:nand erase error… block=0x%x”,num/64);
#endif
control_end();//关操控
nand_mask_bad_block(num/64);//挂号为坏块
return -1;//删去过错回来0
}

control_end();//关操控
#ifdef NAND_DEBUG
Uart_Printf(“/r/n NAND block %d erase completed.”,num/64);
#endif
return 1;
}

int nand_page_write(U32 addr,U8 *buffer,U32 size)

//addr要写的起始页地址,buffer要写的缓存,size要写的字节巨细最大为4G

//这样的话addr是有格局要求的比方结尾几个零,成果这个函数里边没有加上所谓“对齐判别”失利啊!!
{
U32 i,n,p,temp,ecc;
U8 *bu;
bu=buffer;
temp=0;
//我自己加上的对齐判别,假设每页是2kbyte的话,也能够再加上串口打印信息

if(addr & 0xfff) {return -1;}

//

n=size/2048+(((size 48)==0)?0:1); //核算出要写的页数,小于一页的部分当作一页

for (i=0;i{
control_start();//开操控,选中nandflash和敞开nandflash操控器
nand_reset();//复位

#ifdef USE_ECC
ecc_main_init();
ecc_main_start();//能够发生main区ECC
#endif

// detect_nand_busy();

//检测忙,这儿有适当所以复位nandflash后检测nandflash,复位都不信任了,擦!

//检测了更好考虑问题更全面
rNFCMD = NAND_CMD_WRITE_PAGE_1st;//0x80指令,
rNFADDR = 0; //从每页的0地址开端
rNFADDR = 0; //从每页的0地址开端
rNFADDR = (addr)&0xff;//???不是发送四个地址序列吗?
rNFADDR = (addr>>8)&0xff;
rNFADDR = (addr>>16)&0xff;

for (p=0;p<2048;p++)//写入一页
{
temp=temp+1;
if (temp>size)//这个temp并没有在每一页中从头置零!!!
rNFDATA8 = 0xff;//剩余的填写0xff,NFDATA是32位数据
else
rNFDATA8 = *(bu+p);
}
delay_lhg(100,100);//?草详细的延时函数在哪里
#ifdef USE_ECC//也即宏界说里边是否启用了ecc发生记载
ecc_main_end();//确定main区ecc
ecc=rNFMECC0;//main ECC值写入备用区的头0~4个地址内,NFMECCO是main aera的ecc发生的暂时当地

ecc_spare_start();//开端spare区ECC
rNFDATA8 = ecc&0xff;//这样来看ecc32位数据,
rNFDATA8 = (ecc>>8)&0xff;
rNFDATA8 = (ecc>>16)&0xff;
rNFDATA8 = (ecc>>24)&0xff;//主动完结写入
ecc_spare_end();
delay_lhg(100,100);//
ecc = rNFSECC;//spare ECC值写入备用区的5~6两个地址内,NFSECC是spare area生成ecc的暂时当地
rNFDATA8 = ecc&0xff;
rNFDATA8 = (ecc>>8)&0xff;//我靠 spare area的ecc只要16位

#endif

bu=bu+2048;//页增量
addr++;//起始页地址为何是++?

rNFCMD = NAND_CMD_WRITE_PAGE_2st;//这个指令是ox10,意思是发动写操作
detect_nand_busy();//检测忙
rNFCMD =NAND_CMD_READ_STATUS; //读nandflash忙不忙的状况指令,这个指令是0x70
if (rNFDATA8&1)//???为什么出来最终一位是1则是有问题啊!!!!
{
#ifdef NAND_DEBUG
Uart_Printf(“/r/n nand write page error: page addr=0x%d”,addr-1);//写入失利
#endif
control_end();//关操控,撤销选中nandflash然后封闭nandflash操控器
nand_mask_bad_block((addr-1)/64);//挂号为坏块,我靠整个块都是坏的!!!
return -1;//写入过错回来-1
}
control_end();//关操控
}
return 1;//成功回来1
}

int nand_page_read(U32 addr,U8 *buffer,U32 size)//addr开端页地址,从每页00地址开端读
{
U32 i,n,p,temp,ecc;
U8 *bu,no;
bu=buffer;
temp=0;

n=size/2048+(((size 48)==0)?0:1); //核算出要读的页数,小于一页的部分当作一页

for (i=0;i++;i {
control_start();//开操控,选中nandflash而且翻开nandflash操控器
nand_reset();//复位,擦 下边例行监测nandflash的busy与否
detect_nand_busy();

#ifdef USE_ECC
rNFESTAT0 = 0;//复位过错标志位
ecc_main_init();
ecc_main_start();//能够发生main区ECC
#endif

rNFCMD = NAND_CMD_READ_1st;
rNFADDR = 0;
rNFADDR = 0;
rNFADDR = addr&0xff;
rNFADDR = (addr>>8)&0xff;
rNFADDR = (addr>>16)&0xff;//尼玛地址序列发送的这么紊乱!!!
rNFCMD = NAND_CMD_READ_2st;//这个指令应该是0x50,读取的是c区的数据
detect_nand_busy();
for (p=0;p<2048;p++)
{
temp=temp+1;
if (temp>size)
no=rNFDATA8;//剩余的读出来丢掉,给了一个无用的暂时变量
else
*(bu+p) = rNFDATA8;
}

#ifdef USE_ECC
rNFESTAT0=0;//这个表明io0-io7的ecc状况
ecc_main_end();//确定main区ECC
delay_lhg(100,100);//
ecc_spare_start();//解锁spare区ecc
ecc=rNFDATA8;//从flash读出main区ECC
no=rNFDATA8;
ecc |= ((U32)no)<<8;
no=rNFDATA8;
ecc |= ((U32)no)<<16;
no=rNFDATA8;
ecc |= ((U32)no)<<24;

//这个是什么意思啊?便是用中心变量no让ecc存储了32位的main area的ecc
rNFMECCD0 = ((ecc&0xff00)<<8)|(ecc&0xff);//硬件查验main ECC,一次查验16位
rNFMECCD1 = ((ecc&0xff000000)>>8)|((ecc&0xff0000)>>16);
ecc_spare_end();//确定spare区ecc
delay_lhg(100,100);//
ecc=rNFDATA8;//从flash读出spare区ECC的值
no=rNFDATA8;
ecc |= ((U32)no)<<8;

rNFSECCD = ((ecc&0xff00)<<8)|(ecc&0xff);//硬件查验spare ECC
delay_lhg(100,100);//延时一会

ecc=rNFESTAT0&0xffffff;//ecc仅仅暂时用一下过错状况,并非ecc内容

if (ecc!=0)//有过错
{
//今后再优化
#ifdef NAND_DEBUG
Uart_Printf(“/r/n Nand ecc check error… page addr=0x%x,NFESTAT0=0x%x “,addr,ecc);
#endif
nand_mask_bad_block((addr+i)/64);//挂号为坏块
return -1;//
}
#endif

bu=bu+2048;
addr++;
control_end();//关操控
}

return 1;
}

int nand_random_read(U32 paddr,U32 offset,U8 *data) //随机读数据 paddr页地址,offset页内偏移地址
{
control_start();//开操控
nand_reset();//复位

rNFCMD = NAND_CMD_READ_1st;
rNFADDR = 0;
rNFADDR = 0;
rNFADDR = paddr&0xff;
rNFADDR = (paddr>>8)&0xff;
rNFADDR = (paddr>>16)&0xff;
rNFCMD = NAND_CMD_READ_2st;

detect_nand_busy();
rNFCMD = NAND_CMD_RANDOM_READ_1st;
rNFADDR = offset&0xff; //写入页内偏移地址
rNFADDR = (offset>>8)&0xff;
rNFCMD = NAND_CMD_RANDOM_READ_2st;

*data = rNFDATA8;
control_end();
return 1;
}

int nand_random_write(U32 paddr,U32 offset,U8 data)//随机写,paddr页地址,offset页内偏移地址
{
control_start();//开操控
nand_reset();//复位

rNFCMD = NAND_CMD_WRITE_PAGE_1st;
rNFADDR = 0;
rNFADDR = 0;
rNFADDR = paddr&0xff;
rNFADDR = (paddr>>8)&0xff;
rNFADDR = (paddr>>16)&0xff;

rNFCMD = NAND_CMD_RANDOM_WRITE;
rNFADDR = offset&0xff; //写入页内偏移地址
rNFADDR = (offset>>8)&0xff;

rNFDATA8 = data;
rNFCMD = NAND_CMD_WRITE_PAGE_2st;
detect_nand_busy();//检测忙

rNFCMD =NAND_CMD_READ_STATUS; //读状况
if (rNFDATA8&1)
{
#ifdef NAND_DEBUG
Uart_Printf(“/r/n Error:nand random write error… paddr=0x%x,offset=0x%x “,paddr,offset);
#endif
return -1;//删去过错回来0
}

control_end();
return 1;//成功回来1
}

void nand_test_bad_block(void)//测验坏块函数,并符号spare区最终一个地址,假设非0xff则为坏块
{

U8 dest[64*2048];//一个块的main区容量
U8 src [64*2048];
U32 i,k;

#ifdef NAND_DEBUG
Uart_Printf(“/r/n test and mask bad block is begain. /r/n”);
#endif
//
//main区检测
for (i=0;i<64*2048;i++)
{
dest[i]=0xff;//初始化缓冲区
src [i]=0;
}
//删去一切块
for (i=0;i
{
nand_block_erase(i);
}

for (i=0;i
{
nand_page_write(i*64,src,64*2048);
nand_page_read(i*64,dest,64*2048);//运用了ecc校验读出来即可挂号坏块信息
}

for (i=0;i<64*2048;i++)
{
dest[i]=0;//初始化缓冲区
src [i]=0xff;
}
//删去一切块
for (i=0;i
{
nand_block_erase(i);
}

for (i=0;i
{
nand_page_write(i*64,src,64*2048);
nand_page_read(i*64,dest,64*2048);//运用了ecc校验读出来即可挂号坏块信息
}

//
//spare区检测
for (i=0;i<64;i++)
{
dest[i]=0xff;//初始化缓冲区
src [i]=0;
}
//删去一切块
for (i=0;i
{
nand_block_erase(i);
}
for (i=0;i
{
if ( nand_bbi.area[i/64] ==1 )//假设是坏块则越过
continue;

for (k=0;k<64;k++)
{
nand_random_write(i,2048+k,src[k]);
nand_random_read(i,2048+k,&dest[k]);
if (dest[k]!=src[k])//不相等则挂号为坏块
{
nand_mask_bad_block(i/64);
break;
}
}

}

for (i=0;i<64;i++)
{
dest[i]=0x0;//初始化缓冲区
src [i]=0xff;
}
//删去一切块
for (i=0;i
{
nand_block_erase(i);
}
for (i=0;i
{
if ( nand_bbi.area[i/64] ==1 )//假设是坏块则越过
continue;

for (k=0;k<64;k++)
{
nand_random_write(i,2048+k,src[k]);
nand_random_read(i,2048+k,&dest[k]);
if (dest[k]!=src[k])//不相等则挂号为坏块
{
nand_mask_bad_block(i/64);
break;
}
}
}

#ifdef NAND_DEBUG
Uart_Printf(“/r/n test and mask bad block is over. /r/n”);
#endif
}

void nand_flash_init(void)//初始化
{
#ifdef NAND_DEBUG
Uart_Printf(“/r/nNAND FLASH init”);//
#endif

//中止进口地址
pISR_NFCON = (U32)nandINT;

//装备GPIO
rGPGUP |= 0x7<<13; //GPG13~15封闭上位
rGPGCON &= ~((U32)0x3f<<26);//GPG13~15为输入

//初始化各寄存器
S3C2440_NFCONF_init();
S3C2440_NFCONT_init();
S3C2440_NFSTAT_init();
S3C2440_NFESTAT0_init();
S3C2440_NFESTAT1_init();

//关于中止
rINTMSK &= ~(0x1< rINTMOD &= ~(0x1< rSRCPND |= 0x1< rINTPND |= 0x1<
init_nand_bbi();//初始化全局变量
nand_read_id();//读ID

nand_test_bad_block();//测验并挂号坏块
}

声明:本文内容来自网络转载或用户投稿,文章版权归原作者和原出处所有。文中观点,不代表本站立场。若有侵权请联系本站删除(kf@86ic.com)https://www.86ic.net/qianrushi/xitong/262907.html

为您推荐

联系我们

联系我们

在线咨询: QQ交谈

邮箱: kf@86ic.com

关注微信
微信扫一扫关注我们

微信扫一扫关注我们

返回顶部