⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 inand.lst

📁 linux下数据下载器的设计与实现
💻 LST
📖 第 1 页 / 共 4 页
字号:
                  if ( zz != gCurZone || z != gBank)
                  { 
              #ifndef USE_2NAND
                      gEnableBank0 = aBank0[z];        // pre-load fast variables
                      gEnableBank1 = aBank1[z];        // pre-load fast variables
              #endif
                      gBank    = z;                    // update bank
                      gCurZone = zz;
                      // 1K Zone
                      // gPhyAdd  = ((DWORD)gCurZone << (cMaxBlock2N+c512PageSize2N));   // Get Page address
                      ((BYTE *)&gPhyAdd)[3] = 0;
                      ((BYTE *)&gPhyAdd)[2] = gCurZone<<7; 
                      ((BYTE *)&gPhyAdd)[1] = gCurZone>>1;
              
                      // 2K Zone
                      //((BYTE *)&gPhyAdd)[3] = 0;
                      //((BYTE *)&gPhyAdd)[2] = 0;                                        // optimize for speed
                      //((BYTE *)&gPhyAdd)[1] = gCurZone;
              
                      //==========================================================================
                      // This function build the LUT for Logical to Physical translation
                      // need gCurZone
                      //==========================================================================
              
                      memset16((xbyte*)gLog2Phy, MSB(cBLK_INIT), (cMaxBlock*2)/16);
                      for (wi=0; wi<cMaxBlock; wi++)
                      {   // read the redundant section of the page into EP6           
                          NandSetAdd(cNAND_READ_REDUNDANT, 0); 
                          for (z=0; z <3; z++) // retry 3 times
                          {
                              xbyte *p = &gLog2Phy[wi];             // get address pointer
                              // for InterLeave case
                              // if either block in bank0 or bank1 is bad, will mark both blocks bad
                              if (bInterLeave) bank_select(cBank0);  // check bank0                
                              Fifo6In();
                              NandRead(cEP6, 16);
                              bFreeBlk = (EP6FIFOBUF[0] == 0xff) && (EP6FIFOBUF[1] == 0xff);
                              if (bInterLeave)                       // check bank1
                              { 
                                  bank_select(cBank1);
                                  NandRead(cEP6, 16);
                                  if (EP6FIFOBUF[16] != 0xff || EP6FIFOBUF[17] != 0xff) bFreeBlk = 0;
                              }
                              if (!bFreeBlk) 
                              {
                                  *p |= MSB(cBLK_CFG);  // special block or bad block
                                  break;
                              }
                              else
                              {
C51 COMPILER V7.50   INAND                                                                 10/12/2007 17:05:46 PAGE 10  

                                  ((BYTE *)&wTmp)[0] = EP6FIFOBUF[cAddOffset];     // MSB address1
                                  if  (((BYTE *)&wTmp)[0]==0xff) break;            // free block
                                  ((BYTE *)&wTmp)[1] = EP6FIFOBUF[cAddOffset+1];   // LSB address1
              
                                  if ( (((BYTE *)&wTmp)[0] == EP6FIFOBUF[cAddOffset+2]) &&   // check if both addresses 
             -are matched
                                       (((BYTE *)&wTmp)[1] == EP6FIFOBUF[cAddOffset+3]) )
                                  {
                                      xword *pTmp = &gLog2Phy[wTmp];
                                      wTmp = *pTmp;
                                      if (wTmp & cBLK_INIT)                   // multiple blocks map check
                                      {
                                          *pTmp =  ( wTmp & cBLK_uMSK ) | wi; // store the remap block                  
             -  
                                          *p    |= MSB(cBLK_USE);             // Set Block Use
                                      }
                                      else
                                      {
                                          NandSendCmd(cNAND_RESET);           // fix the multiple blocks case
                                          nand_blk_erase(gPhyAdd); 
                                      }
                                      break;
                                  }
                              }
                              if (z == 2) *p |= MSB(cBLK_BAD);
                          }
                          gPhyAdd += c512PageSize;  // next block
                      } // for gi
                      bank_default();               // set default
                      NandSendCmd(cNAND_RESET);     // must reset afer REDUNDANT read
                      bFreeFound = 0;               // cross the Zone, reset the Free Block Found
                  } // update table again
              
                  wTmp  = zz << cMaxBlock2N;        // compute Zone 
                  pDst  = gLog2Phy + gDst;          // pDst = &gLog2Phy[gDst]
                  gSrc  = *pDst & cBLK_aMSK;        // gLog2Phy[gDst]: Get Physical block
                  if (directionIn)                  // Host Read data
                  {
                      wTmp |= gSrc;    
                      nand_ready3();
                      NAND_CLE  = 1;
                      P_XGPIFSGLDATLX = cNAND_READ_DATA;
                      NAND_CLE  = 0; 
                      NAND_ALE  = 1;
                      P_XGPIFSGLDATLX = 0;     
                      P_XGPIFSGLDATLX = ( ((BYTE *)&wTmp)[1] << 5 ) | npage;
                      P_XGPIFSGLDATLX = ( ((BYTE *)&wTmp)[1] >> 3 ) | ( ((BYTE *)&wTmp)[0] << 5 );
                      P_XGPIFSGLDATLX = ( ((BYTE *)&wTmp)[0] >> 3 );
                      NAND_ALE  = 0;              
                      Fifo6In();
                      if (bInterLeave) ready_ignore(); 
                      nand_ready3();       
                  }
                  else
                  {   
                      nGetFreeBlk();                                // get Free Block
                      wi = gFreeBlk;
                      if (gSrc&cBLK_INIT) gSrc=wi;                  // default value set to free block
                      bNeedErase = (wi != gSrc);                    // don't erase if Src = Dst && block free
                      *(xbyte*)&gLog2Phy[gSrc] &=  MSB(~cBLK_USE);  // set this block free
                      *(xbyte*)&gLog2Phy[wi]   |=  MSB(cBLK_USE);   // Set this block is used        
                      *pDst = (*pDst & cBLK_uMSK) | wi;             // update Logical address
C51 COMPILER V7.50   INAND                                                                 10/12/2007 17:05:46 PAGE 11  

               
                      wi |= wTmp;    
                      //gPhyAdd = ((DWORD)(wTmp | wi) << c512PageSize2N);
                      ((BYTE *)&gPhyAdd)[3] = ( ((BYTE *)&wi)[1] << 5 );
                      ((BYTE *)&gPhyAdd)[2] = ( ((BYTE *)&wi)[1] >> 3 ) | ( ((BYTE *)&wi)[0] << 5 );
                      ((BYTE *)&gPhyAdd)[1] = ( ((BYTE *)&wi)[0] >> 3 );
                      //gSrcAdd = ((DWORD)(wTmp | gSrc) << c512PageSize2N);
                      wTmp |= gSrc;    
                      gSrcBlk0 = ((BYTE *)&gSrcAdd)[3] = ( ((BYTE *)&wTmp)[1] << 5 );
                      ((BYTE *)&gSrcAdd)[2] = ( ((BYTE *)&wTmp)[1] >> 3 ) | ( ((BYTE *)&wTmp)[0] << 5 );
                      ((BYTE *)&gSrcAdd)[1] = ( ((BYTE *)&wTmp)[0] >> 3 );
                      // check for head copy here
                      if (page) nCopyPages(page, 0);
                  }
              #endif
 624   1          DBUG_DUMP();
 625   1      }
 626          
 627          //==========================================================================
 628          // Nand Copy Pages:
 629          //   always perform ECC correction for SOFT error.
 630          //   If more than 2-bit error, return b2BitErr will be set
 631          //==========================================================================
 632          void nCopyPages(BYTE cnt, BYTE cc)
 633          {
 634   1      #ifdef NAND_2K
 635   1          BYTE xdata msk=cc&3;   
 636   1          do
 637   1          { 
 638   2              Fifo6In();
 639   2      
 640   2              P_GPIFTCB1 = MSB(cNAND_DSIZE+8);               // setup GPIF Count
 641   2              P_ECCRESET = P_GPIFTCB0 = LSB(cNAND_DSIZE+8);  // Reading 512+2(status)+6(ECC)
 642   2              n2k_radd(gSrcAdd, msk);
 643   2              GPIFTRIG = 0x04 | cEP6;                       // Arm EP6
 644   2              bCnt = --cnt;   
 645   2              // When copy pages, all the data will have ECC correction
 646   2              AUTOPTR1H = MSB(cEP6FIFO);
 647   2              AUTOPTR1L = LSB(cEP6FIFO);
 648   2              while (P_GPIFTCB1);          // Read the first 256 ECC registers
 649   2              ecc0[0] = P_ECC1B0[0];       // save to local buffers
 650   2              ecc0[1] = P_ECC1B0[1]; 
 651   2              ecc0[2] = P_ECC1B0[2]; 
 652   2              while (!gpifIdle());
 653   2      
 654   2              
 655   2                      //while (P_GPIFTCB0 & 0xf8);   // Read second 256 ECC registers       
 656   2              ecc0[3] = P_ECC1B0[3];       // save ECC 
 657   2              ecc0[4] = P_ECC1B0[4];       // GPIF will be done afer reading these
 658   2              ecc0[5] = P_ECC1B0[5];       // registers
 659   2              // Stored 6-byte ECC data from NAND Flash
 660   2              ecc1[0] = P_XAUTODAT1;    
 661   2              ecc1[1] = P_XAUTODAT1;    
 662   2              ecc1[2] = P_XAUTODAT1;    
 663   2              ecc1[3] = P_XAUTODAT1;     
 664   2              ecc1[4] = P_XAUTODAT1;    
 665   2              ecc1[5] = P_XAUTODAT1;    
 666   2              CorrectData();
 667   2      
 668   2      
 669   2              fifo6_out();                        // CFG Out for copy data 
 670   2              n2k_wadd(gPhyAdd, msk);
C51 COMPILER V7.50   INAND                                                                 10/12/2007 17:05:46 PAGE 12  

 671   2              P_GPIFTCB1 = MSB(cNAND_DSIZE+8);    // setup GPIF Count: Ignore 4-bytes
 672   2              P_GPIFTCB0 = LSB(cNAND_DSIZE+8);    // Reading 528 take 36us
 673   2              GPIFTRIG=cEP6;
 674   2              cc++;
 675   2              msk = cc & 3;                       // use by 2K NAND
 676   2              if (msk==0) { xSrcAdd++; xPhyAdd++; }      
 677   2              while (!gpifIdle());
 678   2              P_XGPIFSGLDATLX = MSB(gDst);        // Phy2Log
 679   2              P_XGPIFSGLDATLX = LSB(gDst);        
 680   2              P_XGPIFSGLDATLX = MSB(gDst);        
 681   2              P_XGPIFSGLDATLX = LSB(gDst);        
 682   2              nand_send_command(cNAND_PROGRAM_PAGE);
 683   2          } while ( bCnt ); 
 684   1      #else
                  bit lba0 = cc&1;
                  do
                  { 
                      Fifo6In();
                      P_GPIFTCB1 = MSB(cNAND_DSIZE+8);               // setup GPIF Count
                      P_ECCRESET = P_GPIFTCB0 = LSB(cNAND_DSIZE+8);  // Reading 512+2(status)+6(ECC)
                      if (bInterLeave)
                      {
              #ifdef USE_2NAND
                          if (lba0) CE0_OFF(), CE1_ON(); else CE0_ON(), CE1_OFF();
              #else
                          if (lba0) IOD=gEnableBank1; else IOD=gEnableBank0;
              #endif
                      }
                      nand_ready3();                            // wait for previous program done
                      n512_setadd(cNAND_READ_DATA,gSrcAdd);     // read program pages            
                      GPIFTRIG = 0x04 | cEP6;                   // Arm EP6
                      lba0 = !lba0;          
                      bCnt = --cnt;   
              
                      // When copy pages, all the data will have ECC correction
                      AUTOPTR1H = MSB(cEP6FIFO);
                      AUTOPTR1L = LSB(cEP6FIFO);
                      while (P_GPIFTCB1);          // Read the first 256 ECC registers
                      ecc0[0] = P_ECC1B0[0];       // save to local buffers
                      ecc0[1] = P_ECC1B0[1]; 
                      ecc0[2] = P_ECC1B0[2]; 
              
                      while (P_GPIFTCB0 & 0xf8);   // Read second 256 ECC registers       
                      ecc0[3] = P_ECC1B0[3];       // save ECC 
                      ecc0[4] = P_ECC1B0[4];       // GPIF will be done afer reading these
                      ecc0[5] = P_ECC1B0[5];       // registers
                      // Stored 6-byte ECC data from NAND Flash
                      ecc1[0] = P_XAUTODAT1;    
                      ecc1[1] = P_XAUTODAT1;    
                      ecc1[2] = P_XAUTODAT1;    
                      ecc1[3] = P_XAUTODAT1;     
                      ecc1[4] = P_XAUTODAT1;    
                      ecc1[5] = P_XAUTODAT1;    
                      CorrectData();
                      fifo6_out();                         // CFG Out for copy data            
                      P_GPIFTCB1 = MSB(cNAND_DSIZE+8);     // setup GPIF Count: Ignore 4-bytes
                      P_GPIFTCB0 = LSB(cNAND_DSIZE+8);     // Reading 528 take 36us
                      n512_setadd(cNAND_WRITE_DATA, gPhyAdd);
                      GPIFTRIG=cEP6;
                      if (!lba0 || bInterLeave==0) { xSrcAdd++; xPhyAdd++; }      
                      while (!gpifIdle());
                      P_XGPIFSGLDATLX = MSB(gDst);               // Phy2Log
C51 COMPILER V7.50   INAND                                                                 10/12/2007 17:05:46 PAGE 13  

                      P_XGPIFSGLDATLX = LSB(gDst);        
                      P_XGPIFSGLDATLX = MSB(gDst);        
                      P_XGPIFSGLDATLX = LSB(gDst);        
                      nand_send_command(cNAND_PROGRAM_PAGE);
                  } while ( bCnt ); 
              #endif
 739   1      
 740   1      }
 741          
 742          //==========================================================================
 743          //  Adding this code to support Wear-Leveling. 
 744          //  Note: This subroutine should call only USB Idle, NAND Busy or
 745          //  Waiting GPIF Idle.
 746          //==========================================================================
 747          void nSearchFreeBlock(BYTE i)
 748          {
 749   1          WORD xdata tmp;
 750   1          if (bFreeFound) return;      // if found do need to search again
 751   1          tmp = (WORD)gLog2Phy + gFreeBlk*2;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -