微波EDA网,见证研发工程师的成长!
首页 > 硬件设计 > 嵌入式设计 > TQ2440之nand flash读写

TQ2440之nand flash读写

时间:11-21 来源:互联网 点击:
自己写的一个nand flash读写

#include"2440addr.h"

#include"def.h"

#include"Nand.h"

S8 ECCBuf[6];

U32 PCLK;

extern void Port_Init(void);//以下四个函数在2440lib.c中

extern void Uart_Select(int ch);

extern void Uart_Init(int pclk,int baud);

extern void Uart_Printf(char *fmt,...);

extern void rNF_Reset();//以下三个函数在nand.c中

extern void rNF_Init(void);

extern char rNF_ReadID();

void delay(U32 time)

{

U32 i,j;

for(i=0;i

for(j=0;j<1000;j++)

;

}

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~A7

NF_ADDR(0x00); //列地址A8~A11

NF_ADDR((page_number) & 0xff); //行地址A12~A19

NF_ADDR((page_number >> 8) & 0xff); //行地址A20~A27

NF_ADDR((page_number >> 16) & 0xff); //行地址A28

NF_CMD(CMD_READ2); //页读命令周期2

NF_DETECT_RB(); //等待RnB信号变高,即不忙

NF_CMD(CMD_RANDOMREAD1); //随意读命令周期1

//页内地址

NF_ADDR((char)(add&0xff)); //列地址A0~A7

NF_ADDR((char)((add>>8)&0x0f)); //列地址A8~A11

NF_CMD(CMD_RANDOMREAD2); //随意读命令周期2

return NF_RDDATA8(); //读取数据

}

U8 rNF_RamdomWrite(U32 page_number, U32 add, U8 dat)

{

U8 stat;

NF_nFCE_L(); //打开Nand Flash片选

NF_CLEAR_RB(); //清RnB信号

NF_CMD(CMD_WRITE1); //页写命令周期1

//写入5个地址周期

NF_ADDR(0x00); //列地址A0~A7

NF_ADDR(0x00); //列地址A8~A11

NF_ADDR((page_number) & 0xff); //行地址A12~A19

NF_ADDR((page_number >> 8) & 0xff); //行地址A20~A27

NF_ADDR((page_number >> 16) & 0xff); //行地址A28

NF_CMD(CMD_RANDOMWRITE); //随意写命令

//页内地址

NF_ADDR((char)(add&0xff)); //列地址A0~A7

NF_ADDR((char)((add>>8)&0x0f)); //列地址A8~A11

NF_WRDATA8(dat); //写入数据

NF_CMD(CMD_WRITE2); //页写命令周期2

delay(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; //失败

else

return 0x66; //成功

}

U8 rNF_IsBadBlock(U32 block)

{

return rNF_RamdomRead(block*64, 2054);

}

U8 rNF_MarkBadBlock(U32 block)

{

U8 result;

result = rNF_RamdomWrite(block*64, 2054, 0x33);

if(result == 0x44)

return 0x21; //写坏块标注失败

else

return 0x60; //写坏块标注成功

}

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~A19

NF_ADDR((block_number >> 2) & 0xff); //行地址A20~A27

NF_ADDR((block_number >> 10) & 0xff); //行地址A28

NF_CMD(CMD_ERASE2); //擦除命令周期2

delay(100); //延时一段时间

NF_CMD(CMD_STATUS); //读状态命令

//判断状态值的第6位是否为1,即是否在忙,该语句的作用与NF_DETECT_RB();相同

NF_DETECT_RB();

NF_nFCE_H(); //关闭Nand Flash片选

//判断状态值的第0位是否为0,为0则擦除操作正确,否则错误

if (stat & 0x1)

{

temp = rNF_MarkBadBlock(block_number); //标注该块为坏块

if (temp == 0x21)

return 0x43; //标注坏块失败

else

return 0x44; //擦除操作失败

}

else

return 0x66; //擦除操作成功

}

U8 rNF_WritePage(U32 page_number,S8 mydata)

{

U32 i, mecc0, secc;

U8 stat, temp;

temp = rNF_IsBadBlock(page_number>>6); //判断该块是否为坏块

if(temp == 0x33)

return 0x42; //是坏块,返回

NF_RSTECC(); //复位ECC

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

网站地图

Top