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

📄 inand.c

📁 CY7C68033芯片 USB DEVICE 代码;标准c代码
💻 C
📖 第 1 页 / 共 3 页
字号:
//-----------------------------------------------------------------------------
// Copyright (c) 2005 Cypress Semiconductor, Inc. All rights reserved
//
// File: inand.c
//  Contents: 
//    Interleave NAND support the bInterLeave Flag will enable
//    Odd number NAND chips, the interleave FW will be disable
//    Even number NAND chips, then interleave FW will be enable
//
// Support: Both 512 NAND and 2K NAND
//    To support 2K NAND use the compiler switch NAND_2K
//
// indent 4.  NO TABS!
//--------------------------------------------------------------------------
//
// Copyright 2005, Cypress Semiconductor Corporation.
//
// This software is owned by Cypress Semiconductor Corporation (Cypress)
// and is protected by and subject to worldwide patent protection (United
// States and foreign), United States copyright laws and international 
// treaty provisions. Cypress hereby grants to licensee a personal, 
// non-exclusive, non-transferable license to copy, use, modify, create 
// derivative works of, and compile the Cypress Source Code and derivative 
// works for the sole purpose of creating custom software in support of 
// licensee product to be used only in conjunction with a Cypress integrated 
// circuit as specified in the applicable agreement. Any reproduction, 
// modification, translation, compilation, or representation of this 
// software except as specified above is prohibited without the express 
// written permission of Cypress.
//
// Disclaimer: CYPRESS MAKES NO WARRANTY OF ANY KIND,EXPRESS OR IMPLIED, 
// WITH REGARD TO THIS MATERIAL, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 
// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
// Cypress reserves the right to make changes without further notice to the
// materials described herein. Cypress does not assume any liability arising
// out of the application or use of any product or circuit described herein.
// Cypress does not authorize its products for use as critical components in
// life-support systems where a malfunction or failure may reasonably be
// expected to result in significant injury to the user. The inclusion of
// Cypress' product in a life-support systems application implies that the
// manufacturer assumes all risk of such use and in doing so indemnifies
// Cypress against all charges.
//
// Use may be limited by and subject to the applicable Cypress software
// license agreement.
//
//--------------------------------------------------------------------------
//
// Note:
//    This code has been optimized for Performance, so there are global variables
//    have been used instead of passing variables to subroutines.  
//      Any variables start with the prefix letter "g" indicates "Global" variable.
//
//    pragma OT(7, SPEED) should not be removed.  If remove, the compiler might generate
//    the code which will result slower performance
//
//    The design of this code does not follow Smart Media standard for the following:
//
//      1. Redundant structure
//               BYTE   data_status  = 0xff = good, else bad block
//               BYTE   boot_loader_status = 0xff = free block else used block
//               BYTE   ECC[6]
//               WORD   Address1, Address2
//               BYTE   Reserved[4] = 0xff
//
//      2. The "Address1" and "Address2" do not have parity bit.  The BuidTable does
//         support error bit checking via compare these address fields.  If not mach
//         if will continue to search for good address fields in the next page until
//         3 times of retry.  
//
//      3. Zone table size is 1000
//
// $Workfile: inand.c $
// $Date: 8/08/05 10:49a $
// $Revision: 1 $
// History:  May/12/05   Initial Release to customer
//-----------------------------------------------------------------------------
#include "globals.h"


xdata WORD gLog2Phy[cMaxBlock];         // bit0-11 addr map, bit12=1=free, 0=used
BYTE  gCurZone, gZones, gBankSel, gPartialCpy;  // Use this byte to reload the Table
WORD  gDst, gSrc, gFreeBlk;             // These variable will be shared

DWORD gSrcAdd, gPhyAdd, gNextLBA;       // sharing variables in multiple subrountines
BYTE  ecc0[6], ecc1[6];                 // Optimize ECC variables
BYTE  gSrcBlk0;                         // use for EraseBlock
xword *pDst;

#ifndef USE_2NAND
// fast coding for bank select
const char code aBanks[4]={0xfc, 0xf3, 0xcf, 0x3f};  // interleave bank
const char code aBank0[4]={0xfe, 0xfb, 0xef, 0xbf};  // interleave bank
const char code aBank1[4]={0xfd, 0xf7, 0xdf, 0x7f};  // interleave bank
const char code nBank[8]={0xfe, 0xfd, 0xfb, 0xf7, 0xef, 0xdf, 0xbf, 0x7f};
BYTE  gEnableBanks;

#ifndef NAND_2K
BYTE  gEnableBank0, gEnableBank1;      // optimize variables
#endif

#endif


// Note: These variables below will be used to optimize speed
// These variables use in conjunction with MPAGE that map to 0xE6xx
pbyte P_GPIFTCB0        _at_ 0xd1;    // GPIFTCB0
pbyte P_GPIFTCB1        _at_ 0xd0;    // GPIFTCB1
pbyte P_XAUTODAT1       _at_ 0x7b;    // XAUTODAT1
pbyte P_XAUTODAT2       _at_ 0x7c;    // XAUTODAT2
pbyte P_ECC1B0[6]       _at_ 0x2a;    // 6 bytes ECC registers
pbyte P_INPKTEND        _at_ 0x48;    // INPKTEND
pbyte P_OUTPKTEND       _at_ 0x49;    // OUTPKTEND
pbyte P_ECCCFG          _at_ 0x28;    // ECCCFG
pbyte P_ECCRESET        _at_ 0x29;    // ECCRESET
pbyte P_EP6BCH          _at_ 0x98;    // EP6BCH
pbyte P_EP6BCL          _at_ 0x99;    // EP6BCL
pbyte P_EP4BCH          _at_ 0x94;    // EP4BCH
pbyte P_EP4BCL          _at_ 0x95;    // EP4BCL
pbyte P_GPIFREADYSTAT   _at_ 0xf4;    // GPIFREADYSTAT
pbyte P_FIFORESET       _at_ 0x04;    // FIFORESET
pbyte P_EP6CFG          _at_ 0x14;    // EP6CFG
pbyte P_EP2FIFOCFG      _at_ 0x18;    // EP2FIFOCFG
pbyte P_XGPIFSGLDATLX   _at_ 0xf1;    // XGPIFSGLDATLX
pbyte P_XGPIFSGLDATLNOX _at_ 0xf2;    // XGPIFSGLDATLNOX
pbyte P_EP2CS           _at_ 0xa3;    // EP2CS
pbyte P_EP4CS           _at_ 0xa4;    // EP4CS


//==========================================================================
// NAND Hardware/software init
//   Donot call this subroutine during the SOFT RESET (i.e. softReset)
//==========================================================================
void InitNAND()
{
    gNandBits = 0;      // all the NAND bits variables = 0
    FwCfg = 0;
    NandCfg = 0;
    gFreeBlk = 0; 
    gPartialCpy = 0;
    dwLBA = 0;
    GetNandCfg();       // Get NAND Configuration from MFG TOOL
    directionIn=1;      // Compute Log2Phy Table at init time
    NAND_WP = 1;
    gCurZone = 0xff;    // Load current zone
    Log2Phy();
    ready_default();    // restore default value
#ifndef NO_WP
    bWPSwitchState = NAND_WP_SWITCH;
#endif
    DISABLE_NAND();    
}

//==========================================================================
// Get Free block from LUT
// This search always return a free block
//==========================================================================
void nGetFreeBlk()
{
    while (!bFreeFound)          // search until found free block
        nSearchFreeBlock(0);     // will search for 256 entries
    bFreeFound = 0;
}

//==========================================================================
// NAND EraseBlocks on both banks
//  input: gSrcAdd     = Current Src Block
//==========================================================================
void nEraseBlock()
{
    if (bNeedErase)              // only erase if needed
    {   // erase both banks in the interleave mode
#ifndef NAND_2K
#ifdef USE_2NAND
        CE0_ON(), CE1_ON();      // Enable both banks for interleave mode
#else
        IOD=gEnableBanks;        // non-interleave this should be only 1 bank
#endif
#endif
        xSrcAdd = gSrcBlk0;
        nand_blk_erase(gSrcAdd);    
        // after erasing the NAND, there are some spare time for background search
        nSearchFreeBlock(0);     // will search for 256 entries
    }
}

#pragma OT(7, SPEED)            // Use this optimize for the speed

//==========================================================================
// Clear 16-byte each pass.  
// Maximun 4K buffer 
//==========================================================================
void memset16(BYTE xdata *dest, BYTE c, BYTE len)
{
    AUTOPTR1H = MSB(dest); AUTOPTR1L = LSB(dest);
    do
    {    // Unrole the loop to speed up memory fill
         P_XAUTODAT1 = P_XAUTODAT1 = P_XAUTODAT1 = P_XAUTODAT1 = 
         P_XAUTODAT1 = P_XAUTODAT1 = P_XAUTODAT1 = P_XAUTODAT1 = 
         P_XAUTODAT1 = P_XAUTODAT1 = P_XAUTODAT1 = P_XAUTODAT1 = 
         P_XAUTODAT1 = P_XAUTODAT1 = P_XAUTODAT1 = P_XAUTODAT1 = c;
    } while (--len>0);
}

//==========================================================================
// Read NAND Pages: Supports for both interleave and non-interleave
//   return bErr and b2BitErr, which will send STALL to USB Host
// Modify:
//    ecc0[] and ecc1[]
//    bMsk, bCnt
//==========================================================================
void nReadPages()
{
#ifdef NAND_2K
    Log2Phy();                                      // remap logical blocks

    // Read the first 512 byte data and save all the ECC data in ecc0[]
    // and ecc1[] buffers.  The CheckECC will be called to verify the ECC
    // during the polling for GPIF DMA done (USB data transfer to USB Host)
   
    P_GPIFTCB1 = MSB(cNAND_PSIZE);                  // Setup GPIF count high
    P_ECCRESET = P_GPIFTCB0 = LSB(cNAND_PSIZE);     // Reset ECC and GPIF low count
    GPIFTRIG = 0x04 | cEP4;                         // Arm EP4
    // Compute while GPIF Busy
    ECCSetup(EP4FIFO);                              // Poll GPIF and store ECC data
    if (!bMsk)
    {
        if (bReload) { CheckECC(); Log2Phy(); }     // check if need to remap page
        else n2k_set_radd();
    }
    if (bCnt)
    {
        do
        {
            P_GPIFTCB1 = MSB(cNAND_PSIZE);              // Setup GPIF count high
            P_ECCRESET = P_GPIFTCB0 = LSB(cNAND_PSIZE); // Reset ECC and GPIF low count
            GPIFTRIG = 0x04 | cEP4;                     // Arm EP4
            //=========================================================================
            // local computation while polling GPIF done to optimize the speed
            //=========================================================================
            CheckECC();                                 // Verify previous ECC data
            ECCSetup(EP4FIFO);
            if (!bMsk) 
            {
                if (bReload) Log2Phy(); 
                else n2k_set_radd();
            }
        } while (bCnt);
    }
    CheckECC();                              // Verify last ECC data
#else
    Log2Phy();                               // remap logical blocks
    if (bInterLeave)                         // interleave FW
    {
        bank_select(cBank0);                 // select bank 0
        if (bLBA0)                           // if Odd sector, need aligment
        {
            FifoRd(cEP6, 528);               // dummy read-> next sector
            bank_select(cBank1);
        }
    }
    // Read the first 512 byte data and save all the ECC data in ecc0[]
    // and ecc1[] buffers.  The CheckECC will be called to verify the ECC
    // during the polling for GPIF DMA done (USB data transfer to USB Host)
    P_GPIFTCB1 = MSB(cNAND_PSIZE);               // Setup GPIF count high
    P_ECCRESET = P_GPIFTCB0 = LSB(cNAND_PSIZE);  // Reset ECC and GPIF low count
    GPIFTRIG = 0x04 | cEP4;                      // Arm EP4
    // Compute while GPIF Busy
    ECCSetup(EP4FIFO);
    if (bReload) { CheckECC(); Log2Phy(); }      // check if need to remap page
    if (bCnt)
    {
       AUTOPTRH2 = MSB(cGPIFBANK);
       AUTOPTRL2 = LSB(cGPIFBANK);
       do
       {
            P_GPIFTCB1 = MSB(cNAND_PSIZE);               // Setup GPIF count high
            P_ECCRESET = P_GPIFTCB0 = LSB(cNAND_PSIZE);  // Reset ECC and GPIF low count
            fast_bank_sel(gBankSel);                     // use AUTO PTR2
            GPIFTRIG = 0x04 | cEP4;                      // Arm EP4
            AUTOPTRL2 = LSB(cGPIFBANK);                  // init again
            //=========================================================================
            // local computation while polling GPIF done to optimize the speed
            //=========================================================================
            CheckECC();
            ECCSetup(EP4FIFO);
            if (bReload) Log2Phy(); 
        }  while (bCnt);
        AUTOPTRH2 = MSB(EP4FIFOBUF);
    }
    CheckECC();                              // if ECC error, will send stall
    bank_default();
#endif
    DISABLE_NAND();
}

//==========================================================================
// Setup AUTO pointer for P_XAUTODAT1
// Read ECC registers when first 256 ECC calculation done
// Read 512 byte data and save:
//     ecc0[] contains GPIF HW generate 6 ECC bytes
//     ecc1[] contains ECC data from redundant area
//==========================================================================
void ECCSetup(WORD offset)
{
    dwLBA++;                // next sector     
    bCnt = --gSectorcount && !bErr;
    // Loading the Pointer of stored 6-bytes ECC data
    AUTOPTR1H = MSB(offset);
    AUTOPTR1L = LSB(offset);
#ifdef NAND_2K
    bReload   = xLBA3 ==0 && bCnt;    // compute bReload
    bMsk      = xLBA3 & 3;   
    if (!bMsk) xPhyAdd++;             // 2K NAND address inc
#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
    while (P_GPIFTCB1);          // Read the first 256 ECC registers
    ecc0[0] = P_ECC1B0[0];       // save to local buffers
    ecc0[1] = P_ECC1B0[1]; 

⌨️ 快捷键说明

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