?? nandflash.c
字號:
#include "def.h"
#include "2410addr.h"
#include "2410lib.h"
#include "nandflash.h"
/**************************************
*** 初始化 K9F1208U0M nand flash ***
**************************************/
void InitNandCfg(void)
{
//(1<<15)-->enable nand flash control
//(1<<12)-->initilize ecc decoder/encoder
//(1<<11)-->nand flash nFCE=H(inactive),chip disable
//(7<<8) -->Duration=HCLK*(TACLS+1)
//(7<<4) -->Duration=HCLK*(TWRPH0+1)
//(7<<0) -->Duration=HCLK*(TWRPH1+1)
rNFCONF = (1<<15)|(1<<12)|(1<<11)|(7<<8)|(7<<4)|(7<<0);
}
/**************************************
**** K9F1208U0M nand flash 的ID ****
**************************************/
U32 ReadChipId(void)
{
U32 id;
NFChipEn(); //bit11=0 NAND flash nFCE = L (active)
WrNFCmd(RdIDCMD); //rNFCMD = 0x90,Read ID Command
WrNFAddr(0); //rNFADDR = 0x00,
//whether nand flash is busy?
//rNFSTAT&1 = 1 ,busy
//rNFSTAT&1 = 0 ,no busy
NF_WAITRB();
id = RdNFDat()<<8; // Maker code(K9S1208V:0xec)
id |= RdNFDat(); // Devide code(K9S1208V:0x76)
NFChipDs(); //bit11=1 NAND flash nFCE = H (inactive)
return id;
}
/****************************************
**** K9F1208U0M nand flash 的狀態 ****
****************************************/
static U16 ReadStatus(void)
{
U16 stat;
NFChipEn();
WrNFCmd(NFSTATUS);//NFSTATUS = 0x70
stat = RdNFDat();
NFChipDs();
return stat;
}
/**********************************************
**** K9F1208U0M nand flash 的塊擦除操作 ****
**********************************************/
U32 EraseBlock(U32 addr)
{
U8 status;
U32 i;
NFChipEn();
WrNFCmd(ERASECMD0); //ERASECMD0 = 0x60,Erase one block 1st command
WrNFAddr(NFBlcokAddr>>9&0xff);
WrNFAddr((NFBlcokAddr>>17)&0xff);
WrNFAddr((NFBlcokAddr>>25)&0xff);
WrNFCmd(ERASECMD1); //ERASECMD1 = 0xd0,Erase one blcok 2nd command
for(i=0;i<10;i++); //wait tWB(100ns)
NF_WAITRB(); // Wait tBERS max 3ms.
status = ReadStatus(); // Read status command
if (status&0x1) // Erase error
{
NFChipDs();
MarkBadBlk(addr);
return 0;
}
else
{
NFChipDs();;
return 1;
}
NFChipDs();
}
/********************************************
**** K9F1208U0M nand flash 的頁數據讀 ****
********************************************/
U32 ReadPage(U32 addr, U8 *buf)//addr = page address
{
U16 i;
U8 tmp[3],se[16];
InitEcc();
NFChipEn();
WrNFCmd(READCMD0);//READCMD0 = 0//read the first half page
WrNFAddr(addr&0xff);
WrNFAddr((addr>>9)&0xff);
WrNFAddr((addr>>17)&0xff);
WrNFAddr((addr>>25)&0xff);
for(i=0;i<10;i++); //wait tWB(100ns)
NF_WAITRB();
for(i=0; i<256; i++)
buf[i] = RdNFDat();
tmp[0] = rNFECC0;
tmp[1] = rNFECC1;
tmp[2] = rNFECC2;
for(i=0;i<16;i++)
{
se[i]=RdNFDat(); // Read spare array
}
NFChipDs();
if(tmp[0]==se[0] && tmp[1]==se[1] && tmp[2]==se[2])
{
Uart_Printf("\n[ECC OK:%x,%x,%x]\n",se[0],se[1],se[2]);
return 1;
}
else
{
Uart_Printf("\n[ECC ERROR(RD):read:%x,%x,%x, reg:%x,%x,%x]\n",
se[0],se[1],se[2],tmp[0],tmp[1],tmp[2]);
return 0;
}
}
/********************************************
**** K9F1208U0M nand flash 的頁數據讀 ****
********************************************/
U32 WritePage(U32 addr, U8 *buf)
{
U16 i;
U8 status;
U32 tmp[3];
InitEcc();
NFChipEn();
WrNFCmd(0x00);////write the first half page
WrNFCmd(PROGCMD0); //PROGCMD0 = 0x80
WrNFAddr(addr&0xff);
WrNFAddr((addr>>9)&0xff);
WrNFAddr((addr>>17)&0xff);
WrNFAddr((addr>>25)&0xff);
for(i=0; i<256; i++)
WrNFDat(buf[i]);//Write one page to nand flash from buffer
tmp[0] = rNFECC0;
tmp[1] = rNFECC1;
tmp[2] = rNFECC2;
WrNFDat(tmp[0]);
WrNFDat(tmp[1]);
WrNFDat(tmp[2]);
WrNFCmd(PROGCMD1);//PROGCMD1 = 0x10
for(i=0;i<10;i++); //tWB = 100ns.
NF_WAITRB(); //wait tPROG 200~500us;
status = ReadStatus();
for(i=0;i<3;i++); //twhr=60ns
if (status&0x1) // Page write error
{
NFChipDs();
Uart_Printf("[PROGRAM_ERROR:block#=%d]\n",addr);
MarkBadBlk(addr);
return 0;
}
else
{
NFChipDs();
return 1;
}
}
/*********************************************
**** 屏蔽 K9F1208U0M nand flash 的壞塊 ****
*********************************************/
U32 MarkBadBlk(U32 addr)
{
int i;
U16 status;
addr = addr<<5;
NFChipEn();
WrNFCmd(READCMD2); //READCMD2=0x50
WrNFCmd(PROGCMD0); //PROGCMD0=0x80
WrNFAddr(4); //mark offset 4,5,6,7
WrNFAddr(addr);
WrNFAddr(addr>>8);
WrNFAddr(addr>>16);
WrNFDat(0); //mark with 0
WrNFDat(0);
WrNFDat(0); //mark with 0
WrNFDat(0);
WrNFCmd(PROGCMD1); //PROGCMD1=0x10
for(i=0;i<10;i++); //tWB = 100ns.
NF_WAITRB(); //needn't check return status
WrNFCmd(READCMD0); //READCMD0=0
status = ReadStatus();
for(i=0;i<3;i++); //twhr=60ns
if (status&0x1) // Spare arrray write error
{
NFChipDs();
Uart_Printf("[Program error is occurred but ignored]\n");
}
else
{
NFChipDs();
}
Uart_Printf("[block #%d is marked as a bad block]\n",addr);
return 1;
NFChipDs();
}
/*********************************************
**** 檢查 K9F1208U0M nand flash 的壞塊 ****
*********************************************/
static int CheckBadBlk(U32 addr)
{
U8 data;
int i;
addr = addr<<5;
NFChipEn();
WrNFCmd(READCMD2); //READCMD2 = 0x50
WrNFAddr(5); //mark offset 4,5,6,7
WrNFAddr(addr);
WrNFAddr(addr>>8);
WrNFAddr(addr>>16);
for(i=0;i<10;i++); // wait tWB(100ns) //
NF_WAITRB(); // Wait tR(max 12us)
data = RdNFDat();
NFChipDs();
if(data!=0xff)
{
Uart_Printf("[block %d has been marked as a bad block(%x)]\n",addr,data);
return 1;
}
else
{
return 0;
}
}
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -