BOOL isChecked() { *((UINT32 *)(0xf0010128))=0x50000801;/*Base Register bank5*/ *((UINT32 *)(0xf001012c))=0xfff00856;/*Option Register bank5*/ set_command(0x00); set_addr(0x00); set_addr(0x00); set_addr(0x00); set_addr(0x00); set_addr(0x00); set_command(0x30); if(wait()) return FALSE; return(0x1==nand_read()); } LOCAL int read_id() { UCHAR id[5]; UCHAR idd[5]={0xec,0xd3,0x51,0x95,0x58}; int i,j; set_command(0x90); set_addr(0x00); for(j = 0; j < 5; j++) { id[j] = nand_read(); for(i=0;i<100000;i++); } DEBUG_PRINT(DEBUG_ID,("flash ID: %x %x %x %x %x\n",id[0],id[1],id[2],id[3],id[4])); for(i = 0; i < 5; i++) { if(id[i]!=idd[i]) return -1; } return 0; } LOCAL void reset_nand() { set_command(0xFF); wait(); } LOCAL void initalBadBlockCheck() { int i = 0,j = 0; UINT32 blocknum; UINT32 addr; for(i = 0;i < 8192;i++) { blocknum = i; addr = make_addr( blocknum, 0, 0,0,1); set_command(0x00); set_data_addr(addr,1); set_command(0x30); wait(); if(0xFF!=nand_read()) { nand_info.badBlockTable[i] = 0x1; if(i>=4097) { nand_info.bottomHaltInValid[i-4097] = 0x1; } continue; } addr = make_addr( blocknum, 1, 0, 0,1); set_command(0x00); set_data_addr(addr,1); set_command(0x30); wait(); if(0xFF!=nand_read()) { nand_info.badBlockTable[i] = 0x1; if(i>=4097) { nand_info.bottomHaltInValid[i-4097] = 0x1; } continue; } DEBUG_PRINT(DEBUG_BLKCHK,("block: %d \n",i)); } for(i = 0; i < 4096; i++) { if(nand_info.badBlockTable[i]) { for( j=0;j<4095;j++) { if(!nand_info.bottomHaltInValid[j]) { nand_info.map.map_short[i] = j+4097; nand_info.bottomHaltInValid[j] = 0x1; break; } } if(j==4095) printf("no valid block for bad block replacement!\n"); } } } void print_block_bad() { int i; for(i = 0;i < 8192;i++) { if(nand_info.badBlockTable[i]) printf(" block %d is bad block \n",i ); } } int nand_write_vblock(UINT32 vblocknum,UCHAR* buf,UINT32 len) { UINT32 blocknum,j; if(vblocknum > 4095) { printf("nand_write_vblock : vblocknum > 4095\n"); return -1; } if(nand_info.checked != 1) { printf("nand_write_vblock : flash info missed\n"); return -1; } if(len > 64*2048) { printf("nand_write_vblock : len > 64*2048\n"); return -1; } blocknum = nand_info.map.map_short[vblocknum]; if(blocknum > 8192) { printf("nand_write_vblock : blocknum > 8192\n"); return -1; } retry: while(nand_erase(blocknum)) { printf("error in erasing block %d\n",blocknum); nand_info.badBlockTable[blocknum]=1; for( j=0;j<4095;j++)/*find a valid bak block replace the bad one*/ { if(!nand_info.bottomHaltInValid[j]) { nand_info.map.map_short[vblocknum] = j+4097; nand_info.bottomHaltInValid[j] = 0x1; blocknum = j+4097; break; } } if(j==4095) { printf("no valid block for bad block replacement!\n"); return -1; } } DEBUG_PRINT(DEBUG_ERASE,("erase block %d\n",blocknum)); if(nand_program_block(buf,blocknum,len)) { printf("error in programming block %d\n",blocknum); goto retry; } return 0; } LOCAL int nand_write_block0(UCHAR* buf,UINT32 len) { UINT32 blocknum,j; if(nand_info.checked != 1) { DEBUG_PRINT(DEBUG_ERROR,("nand_write_block0 : flash info missed\n")); return -1; } if(len > 64*2048) { DEBUG_PRINT(DEBUG_ERROR,("nand_write_block0 : len > 64*2048\n")); return -1; } blocknum = 0; if(nand_erase(blocknum)) { DEBUG_PRINT(DEBUG_ERROR,("error in erasing block 0\n")); nand_info.checked=0; return -1; } printf("erase block %d\n",blocknum); if(nand_program_block(buf,blocknum,len)) { DEBUG_PRINT(DEBUG_ERROR,("error in programming block %d\n",blocknum)); nand_info.checked=0; return -1; } return 0; } int nand_read_vblock(UINT32 vblocknum,UCHAR* buf,UINT32 len) { UINT32 blocknum,i,j,k; UCHAR tmpbuf[512]; if(vblocknum > 4095) { printf("nand_read_vblock : vblocknum > 4095\n"); return -1; } if(nand_info.checked != 1) { printf("nand_read_vblock : flash info missed\n"); return -1; } if(len > 64*2048) { printf("nand_read_vblock : len > 64*2048\n"); return -1; } blocknum = nand_info.map.map_short[vblocknum]; if(blocknum > 8192) { printf("nand_read_vblock : blocknum > 8192\n"); return -1; } for(i=0;i<64;i++) for(j=0;j<4;j++) { for(k=0;k<3;k++)/*3次重试*/ { if(nand_read_sector(tmpbuf, blocknum,i,j)==0) { if(len<=512) { memcpy(buf,tmpbuf,len); return 0; } else { memcpy(buf,tmpbuf,512); buf +=512; len -=512; } break; } } if(k == 3) { printf("error in read block %d page %d sector %d \n",blocknum,i,j); return -1; } } } int nand_read_block0(UCHAR* buf,UINT32 len) { UINT32 blocknum,i,j,k; UCHAR tmpbuf[512]; if(nand_info.checked != 1) { DEBUG_PRINT(DEBUG_ERROR,("nand_read_block0 : flash info missed\n")); return -1; } if(len > 64*2048) { DEBUG_PRINT(DEBUG_ERROR,("nand_read_block0 : len > 64*2048\n")); return -1; } blocknum = 0; for(i=0;i<64;i++) for(j=0;j<4;j++) { for(k=0;k<3;k++)/*3次重试*/ { if(nand_read_sector(tmpbuf, blocknum,i,j)==0) { if(len<=512) { memcpy(buf,tmpbuf,len); printf("%d %d %d\n",i,j,k); return 0; } else { printf("%d %d %d\n",i,j,k); memcpy(buf,tmpbuf,512); buf +=512; len -=512; } break; } } if(k == 3) { DEBUG_PRINT(DEBUG_ERROR,("error in read block %d page %d sector %d \n",blocknum,i,j)); return -1; } } } int nand_read_vaddr(UINT32 vaddr,UCHAR* buf,UINT32 len) { UINT32 vblocknum,blocknum,page,sector,offset,addr,first=1,k; UCHAR tmpbuf[512]; if(nand_info.checked != 1) { printf("nand_read_vaddr : flash info missed\n"); return -1; } if(vaddr+len>0x20000000) { printf("error in nand_read_vaddr : vaddr+len>0x20000000\n"); return -1; } vblocknum = (vaddr & 0x1FFE0000)>>17; blocknum = nand_info.map.map_short[vblocknum]; page = (vaddr & 0x1F800)>>11; sector = (vaddr & 0x600)>>9; offset = (vaddr & 0x1FF); while(TRUE) { for(k=0;k<3;k++)/*3次重试*/ { if(nand_read_sector(tmpbuf, blocknum,page,sector)==0) { if(first)/*第一个sector*/ { if(offset+len<=512)/*only one left*/ { memcpy(buf,tmpbuf+offset,len); return 0; } else/*need more read*/ { memcpy(buf,tmpbuf+offset,512-offset); buf +=512-offset; len -=512-offset; } first = 0; break; } else { if(len<=512)/*only one left*/ { memcpy(buf,tmpbuf,len); return 0; } else/*need more read*/ { memcpy(buf,tmpbuf,512); buf +=512; len -=512; } break; } } } if(k == 3) { return -1; } } } void test_nand() { UCHAR buf[1000]; UCHAR buf2[1000]; UCHAR buf3[1000]; int i; for(i=0;i<1000;i++) { buf[i]=i; buf2[i]=0; } nand_write_vblock(2345,buf,1000); nand_read_vblock(2345,buf2,1000); printf("%x %x %x %x %x \n",buf2[995],buf2[996],buf2[997],buf2[998],buf2[999]); nand_read_vaddr((2345<<17)+995,buf3,5); printf("%x %x %x %x %x \n",buf3[0],buf3[1],buf3[2],buf3[3],buf3[4]); } void test_nand_read() { UCHAR buf3[1000]; nand_read_vaddr((2345<<17)+3,buf3,1000-3); printf("%x %x %x %x %x \n",buf3[0],buf3[1],buf3[2],buf3[3],buf3[999-3]); } void print_info() { int i; printf("nand_info.checked=%d\n",nand_info.checked); for(i = 0; i < 8192; i++) { if(nand_info.badBlockTable[i]) printf("nand_info.badBlockTable[%d]=%d\n",i,nand_info.badBlockTable[i]); } for(i = 0; i < 4096 ; i++) { printf("nand_info.map.map_short[%d]=%d\n",i,nand_info.map.map_short[i]); } for(i = 0; i < 4095 ; i++) { if(nand_info.bottomHaltInValid[i]) printf("nand_info.bottomHaltInValid[%d]=%d\n",i,nand_info.bottomHaltInValid[i]); } } LOCAL int program_info() { if(nand_write_block0((UCHAR*)&nand_info,sizeof(NAND_INFO))) { printf("error in programming block 0\n"); return -1; } printf("nand_program_block(0) ok\n"); return 0; } LOCAL int load_info()/*/*加 ecc*/ { if(nand_read_block0((void *)&nand_info,sizeof(NAND_INFO))) { printf("error in programming block 0\n"); return -1; } return 0; } #ifdef DEBUG void set_debug(UINT32 value) { debug = value; } #endif /* void make_bad_block(UINT32 blocknum) { UCHAR col[2]; UCHAR raw[3]; int len = 512; int i=0; UINT32 page,sector; page = 0; sector= 0; raw[0] = ((blocknum<<6)&0xC0 )+ (page&0x3F); raw[1] = (blocknum>>2)&0xFF; raw[2] = (blocknum>>10)&0x07; col[0] = (sector<<4); col[1] = 0x08; set_command(0x80); set_addr(col[0]); set_addr(col[1]); set_addr(raw[0]); set_addr(raw[1]); set_addr(raw[2]); nand_write(0); set_command(0x10); while(isBusy()); set_command(0x70); if(nand_read()&0x1) { printf("erase: error in programming ecc for block %d page %d sector $d!\n",blocknum,page,sector); } }*/上一页 [1] [2] [3] [4]
|