微波EDA网,见证研发工程师的成长!
首页 > 硬件设计 > 嵌入式设计 > arm2440的nandflash相关函数

arm2440的nandflash相关函数

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

函数要调用的入口
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)

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

网站地图

Top