📄 k9f1208.c
字号:
NF_CMD(0x70); // Read status command
if (NF_RDDATA()&0x1) // Erase error
{
NF_nFCE_H();
Uart_Printf("[ERASE_ERROR:block#=%d]\n" ,block);
NF_MarkBadBlock(block);
return 0;
}
else
{
NF_nFCE_H();
return 1;
}
}
static int NF_IsBadBlock(U32 block)
{
unsigned int blockPage;
U8 data;
blockPage=(block<<5); // For 2'nd cycle I/O[7:5]
NF_nFCE_L();
//NF_CLEAR_RB();
NF_CMD(0x50); // Spare array read command
NF_ADDR(517&0xf); // Read the mark of bad block in spare array(M addr=5)
NF_ADDR(blockPage&0xff); // The mark of bad block is in 0 page
NF_ADDR((blockPage>>8)&0xff); // For block number A[24:17]
NF_ADDR((blockPage>>16)&0xff); // For block number A[25]
Delay(1); // wait tWB(100ns)
NF_WAITRB(); // Wait tR(max 12us)
//NF_DETECT_RB();//by xh
data=NF_RDDATA();
NF_nFCE_H();
if(data!=0xff)
{
Uart_Printf("[block %d:bad block(%x)]\n",block,data);
return 1;
}
else
{
Uart_Printf(".");
return 0;
}
}
static int NF_MarkBadBlock(U32 block)
{
int i;
U32 blockPage=(block<<5);
seBuf[0]=0xff;
seBuf[1]=0xff;
seBuf[2]=0xff;
seBuf[5]=0x44; // Bad blcok mark=0
NF_nFCE_L();
NF_CMD(0x50);
NF_CMD(0x80); // Write 1st command
NF_ADDR(0x0); // The mark of bad block is
NF_ADDR(blockPage&0xff); // marked 5th spare array
NF_ADDR((blockPage>>8)&0xff); // in the 1st page.
NF_ADDR((blockPage>>16)&0xff);
for(i=0;i<16;i++)
{
NF_WRDATA(seBuf[i]); // Write spare array
}
NF_CMD(0x10); // Write 2nd command
Delay(1); //tWB = 100ns.
NF_WAITRB(); // Wait tPROG(200~500us)
NF_CMD(0x70);
Delay(1); //twhr=60ns//
if (NF_RDDATA()&0x1) // Spare arrray write error
{
NF_nFCE_H();
Uart_Printf("[Program error is occurred but ignored]\n");
}
else
{
NF_nFCE_H();
}
Uart_Printf("[block #%d is marked as a bad block]\n",block);
return 1;
}
static int NF_ReadPage(U32 block,U32 page,U8 *buffer,U8 *spareBuf)
{
int i;
unsigned int blockPage;
U8 *bufPt=buffer;
page=page&0x1f;
blockPage=(block<<5)+page;
NF_nFCE_L();
//NF_CLEAR_RB();
NF_CMD(0x00); // Read command
NF_ADDR(0); // Column = 0
NF_ADDR(blockPage&0xff); //
NF_ADDR((blockPage>>8)&0xff); // Block & Page num.
NF_ADDR((blockPage>>16)&0xff); //
Delay(1); //wait tWB(100ns)/////??????
NF_WAITRB(); // Wait tR(max 12us)
//NF_DETECT_RB();// BY XH
for(i=0;i<(512);i++)
{
*bufPt++=NF_RDDATA(); // Read one page
}
if(spareBuf!=NULL)
{
for(i=0;i<16;i++)
spareBuf[i]=NF_RDDATA(); // Read spare array
}
NF_nFCE_H();
return 1;
}
static int NF_WritePage(U32 block,U32 page,U8 *buffer,U8 *spareBuf)
{
int i;
U32 blockPage=(block<<5)+page,ecc;
U8 *bufPt=buffer;
NF_Init();//by xh
NF_RSTECC();//init ECC
NF_nFCE_L();
//NF_CLEAR_RB();
NF_CMD(0x0); //write from A region
NF_CMD(0x80); // Write 1st command
NF_ADDR(0); // Column 0
NF_ADDR(blockPage&0xff); //
NF_ADDR((blockPage>>8)&0xff); // Block & page num.
NF_ADDR((blockPage>>16)&0xff); //
for(i=0;i<512;i++)
{
NF_WRDATA(*bufPt++); // Write one page to NFM from buffer
}
/*
if(spareBuf!=NULL)
{
for(i=0;i<16;i++)
{
NF_WRDATA(spareBuf[i]); // Write spare array(ECC and Mark)
}
}*/
i=rNFMECC0;
seBuf[0] = (U8)(ecc &0xff);
seBuf[1] = (U8)((ecc>>8) & 0xff);
seBuf[2] = (U8)((ecc>>16) & 0xff);
//seBuf[0]=rNFMECC0; /* 读取ECC检验码0 */
//seBuf[1]=rNFMECC1; /* 读取ECC检验码1 */
//seBuf[2]=rNFECC2; /* 读取ECC检验码2 */
seBuf[5]=0xff; /* 非坏块标志 */
for(i=0;i<16;i++)
{
NF_WRDATA(seBuf[i]); /* 写该页的OOB数据块 */
}//by xh
NF_CMD(0x10); // Write 2nd command
//Delay(1); //tWB = 100ns.
for(i=0;i<40;i++);//400MHz 2.5ns by xh
NF_WAITRB(); //wait tPROG 200~500us;
//NF_DETECT_RB();//BY XH
NF_CMD(0x70); // Read status command
//Delay(1); //twhr=60ns
for(i=0;i<24;i++);
if (NF_RDDATA()&0x1) // Page write error
{
NF_nFCE_H();
Uart_Printf("[PROGRAM_ERROR:block#=%d]\n",block);
NF_MarkBadBlock(block);
return 0;
}
else
{
NF_nFCE_H();
#if (WRITEVERIFY==1)
//return NF_VerifyPage(block,page,pPage);
#else
return 1;
#endif
}
}
static U16 NF_CheckId(void)
{
U16 id ,temp;
NF_nFCE_L();
NF_CMD(0x90);
NF_ADDR(0x0);
Delay(1); //wait tWB(100ns)
id=NF_RDDATA()<<8; // Maker code(K9S1208V:0xec)
//id|=NF_RDDATA(); // Devide code(K9S1208V:0x76)
temp=NF_RDDATA()&0xff;//by xh
id=id|temp;//by xh
NF_nFCE_H();
return id;
}
static void NF_Reset(void)
{
Nand_Reset();
/*
NF_nFCE_L();
NF_CMD(0xFF); //reset command
Delay(1); //tWB = 100ns.
NF_WAITRB(); //wait 200~500us;
NF_nFCE_H(); */
}
/*
static void NF_Init(void)
{
NF_Reset();
//NF_nFCE_L();
NF_CMD(READ_1_1);
//NF_nFCE_H();
}*/
static void NF_Init(void)//by xh
{
// for S3C2440
rNFCONF = (TACLS<<12)|(TWRPH0<<8)|(TWRPH1<<4)|(0<<0);
// TACLS [14:12] CLE&ALE duration = HCLK*TACLS.
// TWRPH0 [10:8] TWRPH0 duration = HCLK*(TWRPH0+1)
// TWRPH1 [6:4] TWRPH1 duration = HCLK*(TWRPH1+1)
// AdvFlash(R) [3] Advanced NAND, 0:256/512, 1:1024/2048
// PageSize(R) [2] NAND memory page size
// when [3]==0, 0:256, 1:512 bytes/page.
// when [3]==1, 0:1024, 1:2048 bytes/page.
// AddrCycle(R) [1] NAND flash addr size
// when [3]==0, 0:3-addr, 1:4-addr.
// when [3]==1, 0:4-addr, 1:5-addr.
// BusWidth(R/W) [0] NAND bus width. 0:8-bit, 1:16-bit.
rNFCONT = (0<<13)|(0<<12)|(0<<10)|(0<<9)|(0<<8)|(0<<6)|(0<<5)|(1<<4)|(1<<1)|(1<<0);
// Lock-tight [13] 0:Disable lock, 1:Enable lock.
// Soft Lock [12] 0:Disable lock, 1:Enable lock.
// EnablillegalAcINT[10] Illegal access interupt control. 0:Disable, 1:Enable
// EnbRnBINT [9] RnB interrupt. 0:Disable, 1:Enable
// RnB_TrandMode[8] RnB transition detection config. 0:Low to High, 1:High to Low
// SpareECCLock [6] 0:Unlock, 1:Lock
// MainECCLock [5] 0:Unlock, 1:Lock
// InitECC(W) [4] 1:Init ECC decoder/encoder.
// Reg_nCE [1] 0:nFCE=0, 1:nFCE=1.
// NANDC Enable [0] operating mode. 0:Disable, 1:Enable.
//rNFSTAT = 0;//by xh
//Nand_Reset();//by xh
}
U32 factorial(U8 num,U8 rank)
{
U32 value = num ,i;
if (rank==0) return 1;
else
{
for (i=1;i<rank;i++)
value = value * num;
return value;
}
}
U32 GETVALUE(char *buf)
{
U32 value=0 ,i ,temp=0;
for (i=0;i<10;i++)
*(buf+i)=0;//clear buf
Uart_GetString(buf);
for (i=0;i<10;i++)
if (*(buf+i)!=0) temp++;//count nums
for(i=0;i<temp;i++)
value = value + (*(buf+i)-48)*factorial(10,temp-1-i);//ascii-48=num, mul 10^rank
return value;
}
int LoadImageFile(U8 *buf,int size)
{
/* int i,readSize=size;
for(i=0;i<size;i++)
{
if(feof(stream))
{
readSize=i;
for(;i<size;i++)buf[i]=0;
break;
}
buf[i] = fgetc(stream);
}
return readSize;*/
int i,readSize=size;
for(i=0;i<size;i++)
{
buf[i] = *BufBase++;
//((volatile unsigned char *)0x30900000)[i] = *BufBase++;
}
return readSize;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -