📄 inand.lst
字号:
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 + -