九 ARM9(2440)對nand flash的讀寫操作-程序?qū)嵗治?/h1>
我相信上一篇文章已經(jīng)對nand flash的操作有了一定的了解,下面一起看一下程序?qū)嵗?p>
#include "include.h"本文引用地址:http://m.butianyuan.cn/article/201611/322173.htm
extern void Uart_Printf(char *fmt,...);
extern void Uart_Init(int baud);
//extern void Uart_Select(int ch);
static void InitNandCfg(void)
{
rGPACON = (rGPACON &~(0x3f<<17)) | (0x3f<<17); //配置芯片引腳,因?yàn)镚PACON復(fù)位后各位的值為1,所以此步也可沒有
//TACLS為1個(gè)HCLK,TWRPH0為5個(gè)HCLK,TWRPH1為2個(gè)HCLK,數(shù)據(jù)寬度8位
rNFCONF = (TACLS<<12)|(TWRPH0<<8)|(TWRPH1<<4)|(0<<0);
//禁止緊鎖,軟件禁止上鎖,禁止非法訪問中斷,禁止RnB 中斷,RnB檢測上升沿,鎖定備份ECC,鎖定主數(shù)據(jù)區(qū)域ECC生成,初始化ECC 編碼器/譯碼器,
//強(qiáng)制nFCE 為高(禁止片選),NAND Flash 控制器使能
rNFCONT = (0<<13)|(0<<12)|(0<<10)|(0<<9)|(0<<8)|(1<<6)|(1<<5)|(1<<4)|(1<<1)|(1<<0);
}
static U32 WaitNFBusy(void) // R/B 未接好?
{
U8 stat;
WrNFCmd(QUERYCMD);//0x70,讀狀態(tài)命令
do
{
stat = RdNFDat();//讀取NFDATA
}
while (!(stat&0x40));//,第6位,判斷是否在忙
WrNFCmd(READCMD0);//寫頁讀命令周期0
return stat&1; //注意0為操作成功
}
static U32 ReadChipId(void)
{
U32 id,k;
NFChipEn(); //使能片選
WrNFCmd(RdIDCMD);//讀ID命令
WrNFAddr(0);//寫入地址0
while(NFIsBusy()); //等待不忙
id = RdNFDat()<<8;//應(yīng)該是只讀的廠商ID
for(k=0;k<500;k++);//延時(shí)
id |= RdNFDat();//低8位為設(shè)備ID
NFChipDs(); //關(guān)閉片選
return id;//返回ID值
}
static U16 ReadStatus(void)
{
U16 stat;
NFChipEn(); //片選使能
WrNFCmd(QUERYCMD); //讀狀態(tài)命令
stat = RdNFDat(); //讀取狀態(tài)值
NFChipDs();//關(guān)閉片選
return stat;
}
U32 EraseBlock(U32 addr)//輸入?yún)?shù)是具體的頁數(shù),擦除的是頁數(shù)所在的塊
{
U8 stat;
addr &= ~0x3f;//為了將地址賦給A18~A19
NFChipEn(); //片選使能
WrNFCmd(ERASECMD0); //擦除命令周期0
WrNFAddr(addr);//寫地址寫3個(gè)行周期A18~A19
WrNFAddr(addr>>8);//A20~A27
WrNFAddr(addr>>16);//A28
WrNFCmd(ERASECMD1); // 擦除命令周期1
stat = WaitNFBusy();//等待不忙
NFChipDs();//關(guān)閉片選
return ~stat;//返回1則操作成功
}
void ReadPage(U32 addr, U8 *buf)//并沒有使用ECC校驗(yàn)
{
U16 i;
NFChipEn();//片選使能
WrNFCmd(READCMD0);//讀命令周期0
WrNFAddr(0);//寫列地址A0~A7
WrNFAddr(0);//寫列地址A8~A11
WrNFAddr(addr);//行地址A12~A19
WrNFAddr(addr>>8);//行地址A20~A27
WrNFAddr(addr>>16);//行地址A28
WrNFCmd(READCMD1);//讀命令周期1
InitEcc();//復(fù)位ECC
WaitNFBusy();
for(i=0; i<2048; i++)
buf[i] = RdNFDat();//讀取數(shù)據(jù)存入buf中
NFChipDs();//關(guān)閉片選
}
U32 WritePage(U32 addr, U8 *buf)
{
U32 i, mecc;
U8 stat, tmp[7];
NFChipEn();
WrNFCmd(PROGCMD0);//頁寫命令周期1
WrNFAddr(0);
WrNFAddr(0);
WrNFAddr(addr);
WrNFAddr(addr>>8);
WrNFAddr(addr>>16);
InitEcc(); //reset mecc and secc
MEccUnlock();//ECC解鎖
for(i=0; i<2048; i++)
WrNFDat(buf[i]);//寫數(shù)據(jù)
MEccLock();//鎖定ECC值
mecc =RdNFMEcc();//讀取ECC碼
//把ECC碼轉(zhuǎn)化為字節(jié)型
tmp[0] = mecc&0xff;
tmp[1] = (mecc>>8)&0xff;
tmp[2] = (mecc>>16)&0xff;
tmp[3] = (mecc>>24)&0xff;
tmp[5] = 0xff; //mark good block
WrNFDat(0xff);//2048,壞塊標(biāo)志
SEccUnlock();//解鎖spare區(qū)ECC
WrNFDat(tmp[0]);//把main區(qū)的ECC寫入spare區(qū)的前4個(gè)字節(jié)
WrNFDat(tmp[1]);
WrNFDat(tmp[2]);
WrNFDat(tmp[3]);
SEccLock();//鎖定spare區(qū)ECC
WrNFCmd(PROGCMD1);//頁寫命令周期1
stat = WaitNFBusy();
NFChipDs();
return ~stat;
}
void nandMain(void)
{
U16 ID,i;
U8 buf[2048];
U32 NFBlockNO=6;
U32 NFPagesNO = 25; //第6塊第25頁
U32 status;
U32 BlockPages;
BlockPages =(NFBlockNO<<6)+NFPagesNO; //轉(zhuǎn)化為總頁數(shù)
Uart_Init(115200);
Uart_Printf("nthe main is runningn");
InitNandCfg(); //初始化函數(shù)
ID=ReadChipId();//ID 我的是現(xiàn)代的FLash,ID為:adda
Uart_Printf("nnand flash`s ID is:%xn",ID);
if(EraseBlock(BlockPages)&0x1==TRUE)//因?yàn)镋raseBlock()的輸入?yún)?shù)是頁數(shù),所以輸入的是BlockPages
{
Uart_Printf("nblock %d is erasedn",NFBlockNO);//打印擦除的是那一塊
ReadPage(BlockPages,buf);//讀取擦除后的數(shù)據(jù)
Uart_Printf("nn");
for(i=0; i<2048; i++)
Uart_Printf("%4x", buf[i]); //將讀出的數(shù)據(jù)進(jìn)行打印
Uart_Printf("nn");
for(i=0; i<2048; i++)
{
buf[i] = i;
Uart_Printf("%4x", buf[i]);
}
Uart_Printf("nWrite data[%d block, %d page].n", NFBlockNO,NFPagesNO);
status = WritePage(BlockPages,buf);//寫入數(shù)據(jù)
if(status&0x1==TRUE )//返回成功值
Uart_Printf("nWrite OK.n");
else
Uart_Printf("nWrite Error.n");
for(i=0; i<2048; i++)
buf[i] = 1; //為驗(yàn)證后邊數(shù)組中的數(shù)據(jù)是來自flash,實(shí)際上相當(dāng)于是在數(shù)組中擦除了flash的數(shù)據(jù),因?yàn)槿绻鹒lash擦除時(shí)內(nèi)容就全為1
ReadPage(BlockPages,buf); //將讀取的數(shù)據(jù)存入buf中
Uart_Printf("nRead data[%d block, %d page].n", NFBlockNO,NFPagesNO);//輸出塊號和頁號
Uart_Printf("nn");
for(i=0; i<2048; i++)
Uart_Printf("%4x", buf[i]);//打印所讀取的數(shù)據(jù)
}
else
Uart_Printf("nblock %4x erased is badn",NFBlockNO); //否則是壞塊,并打印信息
while(1);
}
#include "include.h"本文引用地址:http://m.butianyuan.cn/article/201611/322173.htm
extern void Uart_Printf(char *fmt,...);
extern void Uart_Init(int baud);
//extern void Uart_Select(int ch);
static void InitNandCfg(void)
{
}
static U32 WaitNFBusy(void)
{
}
static U32 ReadChipId(void)
{
}
static U16 ReadStatus(void)
{
}
U32 EraseBlock(U32 addr)//輸入?yún)?shù)是具體的頁數(shù),擦除的是頁數(shù)所在的塊
{
}
void ReadPage(U32 addr, U8 *buf)//并沒有使用ECC校驗(yàn)
{
}
U32 WritePage(U32 addr, U8 *buf)
{
}
void nandMain(void)
{
}
評論