|  
 
 
  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]  
 |