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

📄 inand.c

📁 CY7C68033芯片 USB DEVICE 代码;标准c代码
💻 C
📖 第 1 页 / 共 3 页
字号:
        ecc0[2] = P_ECC1B0[2]; 
        while (!gpifIdle());
        //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  
        n2k_wadd(gPhyAdd, msk);
        P_GPIFTCB1 = MSB(cNAND_DSIZE+8);    // setup GPIF Count: Ignore 4-bytes
        P_GPIFTCB0 = LSB(cNAND_DSIZE+8);    // Reading 528 take 36us
        GPIFTRIG=cEP6;
        cc++;
        msk = cc & 3;                       // use by 2K NAND
        if (msk==0) { xSrcAdd++; xPhyAdd++; }      
        while (!gpifIdle());
        P_XGPIFSGLDATLX = MSB(gDst);        // Phy2Log
        P_XGPIFSGLDATLX = LSB(gDst);        
        P_XGPIFSGLDATLX = MSB(gDst);        
        P_XGPIFSGLDATLX = LSB(gDst);        
        nand_send_command(cNAND_PROGRAM_PAGE);
    } while ( bCnt ); 
#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
        P_XGPIFSGLDATLX = LSB(gDst);        
        P_XGPIFSGLDATLX = MSB(gDst);        
        P_XGPIFSGLDATLX = LSB(gDst);        
        nand_send_command(cNAND_PROGRAM_PAGE);
    } while ( bCnt ); 
#endif

}

//==========================================================================
//  Adding this code to support Wear-Leveling. 
//  Note: This subroutine should call only USB Idle, NAND Busy or
//  Waiting GPIF Idle.
//==========================================================================
void nSearchFreeBlock(BYTE i)
{
    WORD tmp;
    if (bFreeFound) return;      // if found do need to search again
    tmp = (WORD)gLog2Phy + gFreeBlk*2;
    AUTOPTR1H = MSB(tmp); AUTOPTR1L = LSB(tmp);
    do
    {
        if (!(P_XAUTODAT1 & MSB(cBLK_uMSK)))
        {
            bFreeFound = 1;            // Mark found a free erased block
            return;
        }
        P_XAUTODAT1;
        gFreeBlk++;                // Search Next block
        if (gFreeBlk & cMaxBlock)
            gFreeBlk = 0, AUTOPTR1H = MSB(gLog2Phy), AUTOPTR1L = LSB(gLog2Phy);
    } while (--i);                     // 1-256 search entries
}

//==========================================================================
// Write NAND Pages: support both interleave and non-interleave code
//   Use gFreeBlk as the back ground searching free erased block
//==========================================================================
void nWritePages()
{
#ifdef NAND_2K
    BYTE wcmd;
    bit prog;
    if (gPartialCpy==0) Log2Phy();  
    // Need to queue up more buffers to avoid hang up on the Write transfer
    // for 512-byte just wait for empty
    if ((gSectorcount>1) || !EZUSB_HIGHSPEED())
       while (!(P_EP2CS & bmEPFULL));     // wait for host send all data
    else
       while ((P_EP2CS & bmEPEMPTY));     // Wait for host to send data
    ARM_EP2(); 
    P_EP2FIFOCFG = bmAUTOOUT | bmOEP;    // set auto mode
    NandSetAdd(cNAND_WRITE_DATA, (xLBA3 & 3));     
    do 
    {
        P_GPIFTCB1 = MSB(cNAND_DSIZE);
        P_ECCRESET = P_GPIFTCB0 = LSB(cNAND_DSIZE);
        GPIFTRIG = cEP2;
        //-----------------------------------------------------
        // PreProcess calculation while waiting transfer done
        //-----------------------------------------------------
        bCnt = --gSectorcount;
        dwLBA++;                                // next sector
        prog = (xLBA3 & 3)==0;
        wcmd = cNAND_PROGRAM_CACHE;
        bReload = (xLBA3 == 0);
        if (bReload || !bCnt) wcmd = cNAND_PROGRAM_PAGE; 
        bReload &= bCnt;
        
        if (prog) { xPhyAdd++; xSrcAdd++;  }    // next address       
        prog |= !bCnt;                   
        while (!gpifIdle());
        WriteRedundant();
        if (prog) 
        {
            nand_send_command(wcmd);
            if (bReload) { nEraseBlock(); Log2Phy(); }
            if (bCnt) n2k_set_wadd(); 
        }        
    } while (bCnt);
    gPartialCpy = xLBA3;
    // partial block must leave the nand chip select asserted
    if (gPartialCpy)
        gPartialCpy = 0-gPartialCpy;
    else  
    {
        nEraseBlock();
        DISABLE_NAND();
    }
    P_EP2FIFOCFG = 0;
#else
    if (gPartialCpy==0) Log2Phy();  
    // Need to queue up more buffers to avoid hang up on the Write transfer
    // for 512-byte just wait for empty
    if ((gSectorcount>1) || !EZUSB_HIGHSPEED())
       while (!(P_EP2CS & bmEPFULL));     // wait for host send all data
    else
       while ((P_EP2CS & bmEPEMPTY));     // Wait for host to send data
    ARM_EP2(); 
    P_EP2FIFOCFG = bmAUTOOUT | bmOEP;     // set auto mode
    do 
    {
        P_GPIFTCB1 = MSB(cNAND_DSIZE);
        P_ECCRESET = P_GPIFTCB0 = LSB(cNAND_DSIZE);
        if (bInterLeave)
        {
#ifdef USE_2NAND
            if (bLBA0) {  CE1_ON(), CE0_OFF(); nand_ready1(); }     // bank1
            else       {  CE0_ON(), CE1_OFF(); nand_ready0(); }     // bank0
#else
            if (bLBA0) {  IOD=gEnableBank1; nand_ready1(); }     // bank1
            else       {  IOD=gEnableBank0; nand_ready0(); }     // bank0
#endif
        }
        else nand_ready3();    
        n512_setadd(cNAND_WRITE_DATA,gPhyAdd);                   // send program pages             
        GPIFTRIG = cEP2;
        //-----------------------------------------------------
        // PreProcess calculation while waiting transfer done
        //-----------------------------------------------------
        bCnt = --gSectorcount;
        dwLBA++;                                         // next sector
        if (bInterLeave)
           gPartialCpy = xLBA3 & cInterLeaveMsk;
        else
           gPartialCpy = xLBA3 & (c512PageSize-1);
        if (!bLBA0 || bInterLeave==0) { xPhyAdd++; xSrcAdd++;  }       // next address
        
        bReload = bCnt && gPartialCpy==0;
        while (!gpifIdle());
        WriteRedundant();
        nand_send_command(cNAND_PROGRAM_PAGE);
        // nSearchFreeBlock(64); 
        if (bReload) { nEraseBlock(); Log2Phy(); }
    } while (bCnt);

    // partial block must leave the nand chip select asserted
    if (gPartialCpy)
    { 
        if (bInterLeave) gPartialCpy = 64-gPartialCpy; 
        else gPartialCpy = c512PageSize-gPartialCpy;
    } 
    else  
    {
        nEraseBlock();
        DISABLE_NAND();
    }
    P_EP2FIFOCFG = 0;
#endif
}

//==========================================================================
// Redundant mappping for Configuration block
//  0-9: 0xff, 01, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff
//  a-f: ecc1b0, ecc1b1, ecc1b2, ecc2b0, ecc2b1, ecc2b2   
// Redundant mappping for data block
//  0-7: 0xff, 0xff, ecc1b0, ecc1b1, ecc1b2, ecc2b0, ecc2b1, ecc2b2
//  8-b: add1, add2
//  c-f: ignore
// set b2BitErr when more than 2 bit ECC error
//==========================================================================
bit CorrectData()
{    
    BYTE a,b,c,x,i;

    for (i=0;  i<2;  i++)
    {       
        b = ecc0[0] ^ ecc1[0];
        a = ecc0[1] ^ ecc1[1];
        c = ecc0[2] ^ ecc1[2];
        if (a|b|c)
        {
            if ((((a^(a>>1)) & 0x55) == 0x55) && // Does each pair of parity bits contain
                (((b^(b>>1)) & 0x55) == 0x55) && // one error and one match?
                 (((c^(c>>1)) & 0x54) == 0x54))
            {
                x = (a & 0x80); // If so, there's a one-bit error in data[].
                if (a & 0x20) x |= 0x40; // Find which byte is in error...
                if (a & 0x08) x |= 0x20;
                if (a & 0x02) x |= 0x10;
                if (b & 0x80) x |= 0x08;
                if (b & 0x20) x |= 0x04;
                if (b & 0x08) x |= 0x02;
                if (b & 0x02) x |= 0x01;
                a = 0; // ... and which bit...
                if (c & 0x80) a |= 0x04; 
                if (c & 0x20) a |= 0x02;
                if (c & 0x08) a |= 0x01;
                EP6FIFOBUF[x+ (WORD)(i<<8)] ^= (1 << a); // ... and correct it.
                // one bit is ok
            }
            else { b2BitErr=1; return cFail; }  //  two bits return error
        }
        ecc0[0] = ecc0[3];
        ecc0[1] = ecc0[4];
        ecc0[2] = ecc0[5];
        ecc1[0] = ecc1[3];
        ecc1[1] = ecc1[4];
        ecc1[2] = ecc1[5];
    }
    return cOK;
}

#ifdef NAND_2K
//==========================================================================
// Internal Move:
//    Partial page will use nCopyPages, the full 2K page will use 
//    internal move
//==========================================================================
void nNandMove(BYTE cnt, BYTE cc)
{
    BYTE z, msk = cc&3;

    if (!bInternalMove) { nCopyPages(cnt,cc); return; }

    if (msk) { z = 4-msk; nCopyPages(z, msk); cnt -= z; }
    msk = cnt/4;

    // if the src is blank, need to have valid page
    if (cc==0 && msk && bFreeBlk)
    {
       nCopyPages(4, 0); // ONLY need to copy 1st page
       cnt -= 4;
       msk--;
    }           
    for (z=0; z<msk; z++)
    {              
        nand_ready3();
        NAND_CLE=1,P_XGPIFSGLDATLX=0, NAND_CLE=0;
        NAND_ALE = 1;
        P_XGPIFSGLDATLX = 0; cnt -= 4; P_XGPIFSGLDATLX = 0;
        P_XGPIFSGLDATLX = ((BYTE *)&gSrcAdd)[3]; 
        P_XGPIFSGLDATLX = ((BYTE *)&gSrcAdd)[2];    
        P_XGPIFSGLDATLX = ((BYTE *)&gSrcAdd)[1];     
        NAND_ALE = 0;                       
        NAND_CLE=1, P_XGPIFSGLDATLX=0x35, NAND_CLE=0;
        
        nand_ready3();  // wait for tr
        NAND_CLE=1,P_XGPIFSGLDATLX=0x85, NAND_CLE=0;
        NAND_ALE = 1;
        P_XGPIFSGLDATLX = 0; xSrcAdd++; P_XGPIFSGLDATLX = 0;
        P_XGPIFSGLDATLX = ((BYTE *)&gPhyAdd)[3]; 
        P_XGPIFSGLDATLX = ((BYTE *)&gPhyAdd)[2];    
        P_XGPIFSGLDATLX = ((BYTE *)&gPhyAdd)[1];     
        NAND_ALE = 0;                       
        NAND_CLE=1, P_XGPIFSGLDATLX=0x10, NAND_CLE=0;
        xPhyAdd++;
    }  
    if (cnt) nCopyPages(cnt, 0);
}
#endif

⌨️ 快捷键说明

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