📄 flash.c
字号:
NF_CMD(0x70); // Read status command
if (NF_RDDATA()&0x1){ // Erase error
NF_nFCE_H();
printf("[ERASE_ERROR:block#=%d]\n",block);
NF_MarkBadBlock(block);
return FAIL;
}
NF_nFCE_H();
#endif
return OK;
}
//检测一个页是否擦除,擦除则返回0,否则返回1
int CheckPageEreased(unsigned int block,unsigned int page)
{
int ret=0;
int i;
unsigned int blockPage;
page=page&0x1f;
blockPage=(block<<5)+page;
NF_nFCE_L();
NF_CMD(NAND_READ0); // Read 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<10;i++); //wait tWB(100ns)/////??????
NF_WAITRB(); // Wait tR(max 12us)
for(i=0;i<NandPageSize;i++){ // Read one page
if(0xff!=NF_RDDATA()){
ret=1;
break;
}
}
NF_nFCE_H();
return ret;
}
/*****************************************************************\
功能:读取FLASH的某个Block中的1 space page数据512byte
参数 block: 读取的块位置
page: 读取的page位置
pPage: 返回的数据
返回值 成功返回OK,否则返回FAIL
注意: pPage指向的缓冲区的大小必须大于等于512 byte
\*****************************************************************/
int ReadPage512(unsigned int block,unsigned int page, unsigned char* pPage)
{
int i;
unsigned int blockPage;
// U8 ecc0,ecc1,ecc2;
U8 se[16];
page=page&0x1f;
blockPage=(block<<5)+page;
NF_RSTECC(); // Initialize ECC
NF_nFCE_L();
NF_CMD(NAND_READ0); // Read 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<10;i++); //wait tWB(100ns)/////??????
NF_WAITRB(); // Wait tR(max 12us)
for(i=0;i<NandPageSize;i++){
*pPage++=NF_RDDATA(); // Read one page
}
/* ecc0=rNFECC0;
ecc1=rNFECC1;
ecc2=rNFECC2;*/
for(i=0;i<16;i++){
se[i]=NF_RDDATA(); // Read spare array
}
NF_nFCE_H();
/*
if(ecc0==se[0] && ecc1==se[1] && ecc2==se[2])
{
//printf("[ECC OK:%x,%x,%x]\n",se[0],se[1],se[2]);
return OK;
}
printf("[ECC ERROR(RD):read:%x,%x,%x, reg:%x,%x,%x]\n",se[0],se[1],se[2],ecc0,ecc1,ecc2);*/
return OK;
}
/*****************************************************************\
功能:读取FLASH的某个Block中的1 space page数据16byte
参数 block: 读取的块位置
page: 读取的page位置
pPage: 返回的数据
返回值 成功返回OK,否则返回FAIL
注意: pPage指向的缓冲区的大小必须大于等于16 byte
\*****************************************************************/
int ReadSparePage(unsigned int block,unsigned int page, unsigned char* pPage)
{
int i;
unsigned int blockPage;
blockPage=(block<<5)+(page&0x1f); // For 2'nd cycle I/O[7:5]
NF_nFCE_L();
NF_CMD(NAND_READ2); // Spare array read command
NF_ADDR(0);
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]
for(i=0;i<10;i++); // wait tWB(100ns) //?????
NF_WAITRB(); // Wait tR(max 12us)
for(i=0;i<16;i++)
*pPage++=NF_RDDATA();
NF_nFCE_H();
return OK;
}
/*****************************************************************\
功能:写入FLASH的某个Block中的1 page数据, 大小512 byte
参数 block: 写入的块位置
page: 写入的page位置
pPage: 返回的数据
返回值 成功返回OK,否则返回FAIL
注意: pPage指向的缓冲区的大小必须大于等于512 byte
\*****************************************************************/
int WritePage512(unsigned int block,unsigned int page, const unsigned char *pPage)
{
int i;
U32 blockPage=(block<<5)+page;
NF_RSTECC(); // Initialize ECC
NF_nFCE_L();
NF_CMD(NAND_READ0);//??????
NF_CMD(NAND_SEQDATAINPUT); // 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(*pPage++); // Write one page to NFM from buffer
}
/* seBuf[0]=rNFECC0;
seBuf[1]=rNFECC1;
seBuf[2]=rNFECC2;
seBuf[5]=0xff; // Marking good block
for(i=0;i<16;i++){
NF_WRDATA(seBuf[i]); // Write spare array(ECC and Mark)
} */
NF_CMD(NAND_PAGEPROG); // Write 2nd command
for(i=0;i<10;i++); //tWB = 100ns. ////??????
NF_WAITRB(); //wait tPROG 200~500us;
NF_CMD(NAND_STATUS); // Read status command
for(i=0;i<3;i++); //twhr=60ns
if (NF_RDDATA()&0x1){ // Page write error
NF_nFCE_H();
printf("[PROGRAM_ERROR:block#=%d]\n",block);
NF_MarkBadBlock(block);
return FAIL;
}
NF_nFCE_H();
return OK;
}
/*****************************************************************\
功能:写入FLASH的某个Block中的1 spare page数据, 大小16 byte
参数 block: 写入的块位置
page: 写入的page位置
pPage: 返回的数据
返回值 成功返回OK,否则返回FAIL
注意: pPage指向的缓冲区的大小必须大于等于16 byte
\*****************************************************************/
int WriteSparePage(unsigned int block,unsigned int page, const unsigned char *pPage)
{
int i;
U32 blockPage=(block<<5)+(page&0x1f);
NF_nFCE_L();
NF_CMD(NAND_READ2); //????
NF_CMD(NAND_SEQDATAINPUT); // Write 1st command
NF_ADDR(0x0);
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(pPage[i]); // Write spare array
}
NF_CMD(NAND_PAGEPROG); // Write 2nd command
for(i=0;i<10;i++); //tWB = 100ns. ///???????
NF_WAITRB(); // Wait tPROG(200~500us)
NF_CMD(NAND_STATUS);
for(i=0;i<3;i++); //twhr=60ns////??????
if (NF_RDDATA()&0x1){ // Spare arrray write error
NF_nFCE_H();
printf("[Program error is occurred but ignored]\n");
return FAIL;
}
NF_nFCE_H();
return FAIL;
}
/*******************************************************************\
功能:Nand Flash是否有效
返回值: TRUE or FALSE
\********************************************************************/
BOOL NandFlashOK(void)
{
return ((nand_flashinfo.PagePerBlock==0)?FALSE:TRUE);
}
/*******************************************************************\
功能:显示FLASH的数据
\********************************************************************/
int Flash_Tools(int argc, char *argv[])
{
static unsigned char bbb[NandPageSize];
unsigned int i,block,page;
/* for(i=0;i<8;i++)
Erase_Block(i);
for(i=0;i<256;i++){
memset(bbb, i, sizeof(bbb));
WritePage(i/32, i%32, bbb);
}*/
if(NandFlashOK()==FALSE)
{
printf("* No Nand flash Found.Please check your hardware! *\n");
printf("*-----------------------------------------------------------------------*\n");
return FAIL;
}
i = 0;
block = 0;
page = 0;
while(1){
char aa;
printf("* C(c)>>Point to Configure zone(Block0) *\n");
printf("* A(a)>>Point to Application zone(Block1~) *\n");
printf("* B(b)>>Point to Next Block *\n");
printf("* P(p)>>Point to Next Page *\n");
printf("* Q(q)>>Quit *\n");
printf("*-----------------------------------------------------------------------*\n");
aa = getchar();
if (aa == 'q' || aa=='Q') break;
switch(aa)
{
case 'c':
case 'C':
block = 0;
page = 0;
printf("*---------------------Configure Zone at Block %4d, Page %2d----------------*\n",block,page);
break;
case 'a':
case 'A':
block = 1;
page = 0;
printf("*---------------------Application Zone at Block %4d, Page %2d---------*\n",block,page);
break;
case 'b':
case 'B':
block++;
if (block>=nand_flashinfo.totalBlock)
block = 0;
page = 0;
printf("*---------------------Block %4d, Page %2d---------------------------*\n",block,page);
break;
case 'p':
case 'P':
default:
page++;
if (page>=nand_flashinfo.PagePerBlock)
{
page = 0;
block ++;
if (block>=nand_flashinfo.totalBlock) block = 0;
}
printf("*---------------------Block %4d, Page %2d---------------------------*\n",block,page);
}
if(ReadPage(block,page,bbb)==FAIL){
printf("Failed to read page at block %4d, Page %4d", block,page);
continue;
}
for(i=0;i<NandPageSize;i=i+16)
{
printf("BYTE%4x:%4x%4x%4x%4x%4x%4x%4x%4x%4x%4x%4x%4x%4x%4x%4x%4x\n",\
i,bbb[i],bbb[i+1],bbb[i+2],bbb[i+3],bbb[i+4],bbb[i+5],bbb[i+6],bbb[i+7],\
bbb[i+8],bbb[i+9],bbb[i+10],bbb[i+11],bbb[i+12],bbb[i+13],bbb[i+14],bbb[i+15]);
}
}
return OK;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -