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

📄 inand.lst

📁 linux下数据下载器的设计与实现
💻 LST
📖 第 1 页 / 共 4 页
字号:
 246   1          AUTOPTR1H = MSB(offset);
 247   1          AUTOPTR1L = LSB(offset);
 248   1      #ifdef NAND_2K
 249   1          bReload   = xLBA3 ==0 && bCnt;    // compute bReload
 250   1          bMsk      = xLBA3 & 3;   
 251   1          if (!bMsk) xPhyAdd++;             // 2K NAND address inc
 252   1      #else
                  if (bInterLeave)
                  {   
                      // Set this flag when all the pages in the block are done
                      // Interleave total pages are 64
                      // Non-Interleave total pages are 32
                      bReload   = (xLBA3 & cInterLeaveMsk)==0 && bCnt;    // compute bReload
                      // Select bank base on the dwLBA bit 0
                      if (bLBA0) gBankSel = cBank1; else gBankSel = cBank0;
                  }
                  else
                  {
                      gBankSel = cBank3;     // non interleave keep the default value
                      bReload   = (xLBA3 & (c512PageSize-1))==0 && bCnt;    // compute bReload
                  }
              #endif
 268   1          while (P_GPIFTCB1);          // Read the first 256 ECC registers
 269   1          ecc0[0] = P_ECC1B0[0];       // save to local buffers
 270   1          ecc0[1] = P_ECC1B0[1]; 
 271   1          ecc0[2] = P_ECC1B0[2]; 
 272   1          while (P_GPIFTCB0 & 0xf8);   // Read second 256 ECC registers       
 273   1          ecc0[3] = P_ECC1B0[3];       // save ECC 
 274   1          ecc0[4] = P_ECC1B0[4];       // GPIF will be done afer reading these
 275   1          ecc0[5] = P_ECC1B0[5];       // registers
 276   1          // Stored 6-byte ECC data from NAND Flash
 277   1          ecc1[0] = P_XAUTODAT1;    
 278   1          ecc1[1] = P_XAUTODAT1;    
 279   1          ecc1[2] = P_XAUTODAT1;    
 280   1          ecc1[3] = P_XAUTODAT1;    
 281   1          ecc1[4] = P_XAUTODAT1;    
 282   1          ecc1[5] = P_XAUTODAT1;    
 283   1          P_INPKTEND   = 0x84;          // skip 16-byte of the redundant data
 284   1      }
 285          
 286          //==========================================================================
 287          //  Check ECC, if fail, return bErr=1
 288          //  Should call CorrectData if more than ECC 2bit error, the b2BitErr will 
 289          //  be set.
 290          //  Modify:
 291          //     bCnt = 0 will terminate the while loop
 292          //     bErr = 1 will send STALL to USB Host
 293          //==========================================================================
 294          void CheckECC()
 295          {
 296   1           if   ( (ecc0[0] != ecc1[0]) || (ecc0[1] != ecc1[1]) || (ecc0[2] != ecc1[2]) ||
 297   1                  (ecc0[3] != ecc1[3]) || (ecc0[4] != ecc1[4]) || (ecc0[5] != ecc1[5]) )
 298   1           {
 299   2               bErr = 1; bCnt = 0; // Will stall in the Status phase
 300   2           }
 301   1      }
 302          
C51 COMPILER V7.50   INAND                                                                 10/12/2007 17:05:46 PAGE 6   

 303          //==========================================================================
 304          // Get Physical block from LUT
 305          // return gCurZone    = (dwLBA/PageSize)/cMaxLogical
 306          //                    = (dwLBA/PageSize) % cMaxLogical
 307          //        gPhyAdd     = Physical block
 308          //        gSrcAdd     = Physical Source Address for Write
 309          //==========================================================================
 310          void Log2Phy()
 311          {
 312   1          BYTE xdata page, zz, z;
 313   1          WORD xdata wi, wTmp;
 314   1      #ifdef NAND_2K
 315   1          if (bErr) return;    
 316   1          page    = xLBA3;                           // 2K: pagesize = 256
 317   1          ((BYTE *)&gDst)[0] = ((BYTE *)&dwLBA)[1];  // MSB: gDst = (WORD)(dwLBA>>16);
 318   1          ((BYTE *)&gDst)[1] = ((BYTE *)&dwLBA)[2];  // LSB:  Dst = 2K Block number   
 319   1          z = 0;
 320   1          while (gDst >= cMaxLogical) { gDst -= cMaxLogical; z++; }  // z = gDst/cMaxLogical
 321   1        
 322   1          zz  = z & (gZones-1);
 323   1          z   /= gZones;                     // z = number of NAND bank
 324   1      #ifdef USE_2NAND
                  if (z==0) CE0_ON(), CE1_OFF(); else CE1_ON(), CE0_OFF();
              #else
 327   1          gEnableBanks = IOD = nBank[z];     // enable banks
 328   1      #endif
 329   1      
 330   1          if ((gBank != z) || (zz != gCurZone))     // need to reload when bank switch
 331   1          { 
 332   2                      //UM_SendString("\nREFISH************\n");
 333   2              gBank    = z;                 // update bank
 334   2              gCurZone = zz;                // update zone
 335   2              //=================================================================
 336   2              // BuildTable(); 
 337   2              // This function build the LUT for Logical to Physical translation
 338   2              // need gCurZone
 339   2              //=================================================================
 340   2              memset16((xbyte*)gLog2Phy, MSB(cBLK_INIT), (cMaxBlock*2)/16);
 341   2              ((BYTE *)&gPhyAdd)[3] = 0;
 342   2              ((BYTE *)&gPhyAdd)[2] = 0;                  // optimize for speed
 343   2              ((BYTE *)&gPhyAdd)[1] = gCurZone;           // gPhyAdd <<= 16;
 344   2      
 345   2              for (wi=0; wi<cMaxBlock; wi++)
 346   2              {   // read the redundant section of the page into EP6
 347   3                  xbyte *p = &gLog2Phy[wi];             // get address pointer
 348   3                  NandSetAdd(cNAND_READ_DATA, 4); 
 349   3                  Fifo6In();
 350   3                  NandRead(cEP6, cNAND_RSIZ);
 351   3                              ////////////////////////////////////////////////
 352   3                              //LigangWang for debug
 353   3                              //if(dwLBA == 0)
 354   3                              //{
 355   3                              //      UM_SendString("\n");
 356   3                              //      for(i = 0;i < (cNAND_RSIZ+1);i++)
 357   3                              //              UM_SendByte(EP6FIFOBUF[i]);
 358   3                              //}
 359   3                              ////////////////////////////////////////////////
 360   3                  bFreeBlk = (EP6FIFOBUF[0] == 0xff) && (EP6FIFOBUF[1] == 0xff);
 361   3                  if (!bFreeBlk)
 362   3                      *p |= MSB(cBLK_CFG);  // special block or bad block
 363   3                  else
 364   3                  {
C51 COMPILER V7.50   INAND                                                                 10/12/2007 17:05:46 PAGE 7   

 365   4                      ((BYTE *)&wTmp)[0] = EP6FIFOBUF[cAddOffset];     // MSB address1
 366   4                      // check if the block is not free
 367   4                      if (((BYTE *)&wTmp)[0] != 0xff) 
 368   4                      {
 369   5                          ((BYTE *)&wTmp)[1] = EP6FIFOBUF[cAddOffset+1];   // LSB address1
 370   5                          if ( (((BYTE *)&wTmp)[0] == EP6FIFOBUF[cAddOffset+2]) &&   // check if both addresses 
             -are matched
 371   5                               (((BYTE *)&wTmp)[1] == EP6FIFOBUF[cAddOffset+3]) )
 372   5                          {
 373   6                              xword *pTmp = &gLog2Phy[wTmp];
 374   6      
 375   6                              wTmp = *pTmp;
 376   6                              if (wTmp & cBLK_INIT)                   // multiple blocks map check
 377   6                              {   *pTmp =  ( wTmp & cBLK_uMSK ) | wi; // store the remap block                  
             -  
 378   7                                  *p    |= MSB(cBLK_USE);             // Set Block Use
 379   7                              }
 380   6                              else
 381   6                              {
 382   7                                  nand_blk_erase(gPhyAdd); 
 383   7                                  *(xbyte*)0xe100 = 0xee;
 384   7                              }
 385   6                          }
 386   5                      }  // else this block is free
 387   4                  }
 388   3                  gPhyAdd += c2KPageSize;  // next block for 2K NAND
 389   3      
 390   3              } // for wi
 391   2              bFreeFound = 0;               // cross the Zone, reset the Free Block Found
 392   2          } // update table again
 393   1              
 394   1      
 395   1          wTmp  = zz << cMaxBlock2N;        // compute Zone 
 396   1          pDst  = gLog2Phy + gDst;          // pDst = &gLog2Phy[gDst]
 397   1          gSrc  = *pDst & cBLK_aMSK;        // gLog2Phy[gDst]: Get Physical block
 398   1              
 399   1              //UM_SendString("R:LBA=");
 400   1              //UM_SendByte(((BYTE *)&dwLBA)[3]);
 401   1              //UM_SendByte(((BYTE *)&dwLBA)[2]);
 402   1              //UM_SendByte(((BYTE *)&dwLBA)[1]);
 403   1              //UM_SendByte(((BYTE *)&dwLBA)[0]);
 404   1          
 405   1              if (directionIn)                  // read just get the table
 406   1          {
 407   2      
 408   2              wTmp |= gSrc;    
 409   2              ((BYTE *)&gPhyAdd)[3] = ( ((BYTE *)&wTmp)[1] << 6 ) | (page>>2);
 410   2              ((BYTE *)&gPhyAdd)[2] = ( ((BYTE *)&wTmp)[1] >> 2 ) | ( ((BYTE *)&wTmp)[0] << 6 );
 411   2              ((BYTE *)&gPhyAdd)[1] = ( ((BYTE *)&wTmp)[0] >> 2 );
 412   2              NandSetAdd(cNAND_READ_DATA, (page&3));
 413   2                      
 414   2                      //UM_SendString("RPHY=");
 415   2                      //UM_SendByte(((BYTE *)&gPhyAdd)[3]);
 416   2                      //UM_SendByte(((BYTE *)&gPhyAdd)[2]);
 417   2                      //UM_SendByte(((BYTE *)&gPhyAdd)[1]);
 418   2                      //UM_SendString("\n");
 419   2          }
 420   1          else
 421   1          {
 422   2              xbyte  *p;
 423   2              nGetFreeBlk();                                // get Free Block
 424   2              wi = gFreeBlk;
C51 COMPILER V7.50   INAND                                                                 10/12/2007 17:05:46 PAGE 8   

 425   2              if (gSrc&cBLK_INIT) gSrc=wi;                  // default value set to free block
 426   2              bNeedErase = (wi != gSrc);                    // don't erase if Src = Dst && block free
 427   2      
 428   2              // *(xbyte*)&gLog2Phy[gSrc] &=  MSB(~cBLK_USE);  // set this block free
 429   2              p = (xbyte*)&gLog2Phy[gSrc];                  // point to the SRC block
 430   2              // July-07-05 Free Block must exclude CFG block as well
 431   2              bFreeBlk = !(*p & MSB(cBLK_uMSK));             // free block 
 432   2              *p = *p & MSB(~cBLK_USE);                      // set this block free
 433   2              
 434   2              *(xbyte*)&gLog2Phy[wi]   |=  MSB(cBLK_USE);   // Set this block is used        
 435   2              *pDst = (*pDst & cBLK_uMSK) | wi;             // update Logical address
 436   2      
 437   2              wi |= wTmp;    
 438   2              ((BYTE *)&gPhyAdd)[3] = ( ((BYTE *)&wi)[1] << 6 );
 439   2              ((BYTE *)&gPhyAdd)[2] = ( ((BYTE *)&wi)[1] >> 2 ) | ( ((BYTE *)&wi)[0] << 6 );
 440   2              ((BYTE *)&gPhyAdd)[1] = ( ((BYTE *)&wi)[0] >> 2 );
 441   2                      
 442   2              
 443   2                      wTmp |= gSrc;    
 444   2                      gSrcBlk0 = ((BYTE *)&gSrcAdd)[3] = ( ((BYTE *)&wTmp)[1] << 6 );
 445   2              ((BYTE *)&gSrcAdd)[2] = ( ((BYTE *)&wTmp)[1] >> 2 ) | ( ((BYTE *)&wTmp)[0] << 6 );
 446   2              ((BYTE *)&gSrcAdd)[1] = ( ((BYTE *)&wTmp)[0] >> 2 );
 447   2                      
 448   2              if (page) 
 449   2                      {
 450   3                              NAND_PCPY(page, 0);
 451   3                      }
 452   2      
 453   2                      //UM_SendString("WPHY=");
 454   2                      //UM_SendByte(((BYTE *)&gPhyAdd)[3]);
 455   2                      //UM_SendByte(((BYTE *)&gPhyAdd)[2]);
 456   2                      //UM_SendByte(((BYTE *)&gPhyAdd)[1]);
 457   2      
 458   2                      //UM_SendString("SPHY=");
 459   2                      //UM_SendByte(((BYTE *)&gSrcAdd)[3]);
 460   2                      //UM_SendByte(((BYTE *)&gSrcAdd)[2]);
 461   2                      //UM_SendByte(((BYTE *)&gSrcAdd)[1]);
 462   2                      //UM_SendString("\n");
 463   2                      
 464   2          }
 465   1      #else
                  BYTE npage;
              
                  if (bErr) return;    
                  gSrc    = (WORD)dwLBA; 
                  ((BYTE *)&gDst)[0] = ((BYTE *)&dwLBA)[0];  // MSB: gDst = (WORD)(dwLBA>>16);
                  ((BYTE *)&gDst)[1] = ((BYTE *)&dwLBA)[1];  // LSB 
                  if (bInterLeave)
                  {    
                      page = xLBA3 & cInterLeaveMsk;      
                      npage = page>>1;                       // remove bit0 for interleave
                      gDst <<= 16-(c512PageSize2N+1);        // dwLBA >>= c512PageSize2N+1
                      gSrc >>= c512PageSize2N+1;
                  }
                  else
                  {
                      npage = page = xLBA3 & (c512PageSize-1); // mask page 5-bits 0x1F
                      gDst <<= 16-c512PageSize2N;              // dwLBA >>= c512PageSize2N
                      gSrc >>= c512PageSize2N;
                  }   
                  gDst |= gSrc;                                // gDst = dwLBA/c512PageSize
              
C51 COMPILER V7.50   INAND                                                                 10/12/2007 17:05:46 PAGE 9   

                  z = 0;
                  while (gDst >= cMaxLogical) { gDst -= cMaxLogical; z++; }  // z = gDst/cMaxLogical   
                  zz  =  z & (gZones-1);    // zz = zone numbers within a NAND
                  z   /= gZones;            // gZones=8=8192, gZones=4=4096
              
              #ifdef USE_2NAND
                  CE0_ON(),CE1_ON();       // enable both NAND chip select
              #else
                  gEnableBanks = IOD = aBanks[z];  // pre-load fast variables
              #endif
                
                  //  Reload the LUT when cross bank and zone

⌨️ 快捷键说明

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