?? vend_cbw.c
字號:
//-----------------------------------------------------------------------------
void GetNandCfg()
{
BYTE n, ID, ntype, bank;
bit nand=0;
gZones = cMaxZone; // 512: default = 8 zone
#ifdef USE_2NAND
CE0_ON();
#else
IOD = 0xFE; // start from Bank0
#endif
GetNandType(); // Get ID & Status byte
GetNandType(); // Get ID & Status byte
ID = EP6FIFOBUF[0]; // get NAND ID
ntype = EP6FIFOBUF[1]; // get NAND ID
for (bank=0; bank<2 && nand==0; bank++)
{
for (n=0; n<cMaxBlkChk; n++)
{
if (bNand2k==0) gPhyAdd = n << 5; else gPhyAdd = n << 6;
if ( (nReadCfgPage()==cOK) && // make sure no ECC error
(CheckSignature()==cOK) ) // check signature and NAND configuration
{
nand = 1; // CFG found break out loop
break;
}
}
#ifdef USE_2NAND
CE0_OFF(), CE1_ON();
#else
IOD=0xFD; // bank1: Scan on bank1
#endif
}
if (nand) // If found, extract the VID, PID and Strings
{ // Use the first 256 byte of halfKBuffer
mymemmovexx(pDscrVID, EP6FIFOBUF+cVID_OFFSET, 4);
mymemmovexx(halfKBuffer+cHALF_BUFF_OFFSET, EP6FIFOBUF+cINQUIRY_OFFSET, cNAND_CFG_LENGTH);
}
else
{ //Fill the string index with zero, if FW is not found in the NAND
//mymemmovexx(pStr3Offset, halfKBuffer+cHALF_BUFF_OFFSET, 3);
//mymemmovexx(pVendorOffset, halfKBuffer+cHALF_BUFF_OFFSET, 3);
AUTOPTR1H = MSB(halfKBuffer); // load EP6FIFOBUF into AUTOPTR1H
AUTOPTR1L = LSB(&(BYTE)Str3Offset);
P_XAUTODAT1 = 0;
P_XAUTODAT1 = 0;
P_XAUTODAT1 = 0;
AUTOPTR1L = LSB(&(BYTE)VendorOffset);
P_XAUTODAT1 = 0;
}
//===============================================================
// Auto Detect number of Nand chips
//===============================================================
#ifdef USE_2NAND // Maxium detection only 1 NAND
bank = 1;
GetNandType();
if (ntype == EP6FIFOBUF[1]) bank=2;
#else
for (bank=1; bank<8; bank++)
{
IOD = nBank[bank]; // select bank
GetNandType();
if (ntype != EP6FIFOBUF[1]) break;
}
#endif
DISABLE_NAND();
#ifndef NAND_2K
bInterLeave = !(bank&1); // even nand chip, interleave on
#endif
gDriveCapacity = 0;
do
{
// Compute capacity of NAND based on bank variable
switch (gZones)
{
case 4: // 512, Zones = 4; 2K = Zones = 4
if (bNand2k)
gDriveCapacity += (TOTAL_SECTORS*4);
else
gDriveCapacity += TOTAL_SECTORS/2;
break;
case 2: // 2K, Zones = 2;
gDriveCapacity += (TOTAL_SECTORS*2);
break;
default: //case 8: // 512, Zones = 8; case 1: // 2K, Zones = 1
gDriveCapacity += TOTAL_SECTORS;
break;
}
} while (--bank>0);
// bSoftErr=0= will correct repeat soft error on ECC
// if (!bNand2k) bSoftErr=1; // !!! need to work with Manufacturing tool
if (ID==0x98 || ID == 0xec) bInternalMove = b30nsCycle = 1;
#ifdef USE_2LUN
gDriveCapacity -= (cLUN1_Capacity+1);
#else
gDriveCapacity--;
#endif
}
//-----------------------------------------------------------------------------
// bit CheckSignature(void)
// return the signature in the configuration data. In addition, it get
// the gCodePage and gBootImage from configuration data.
//
//typedef struct
//{
// char bSignature[6]; //"SMTDMG"
// WORD wNextBlk; // pointer to next FW image block (no parity)
// char bCodePage; // This number should be in multiple block and < 30
// char bBootImage; // 0-3, number of 512P in a Page
// char bNandDev; // 0xa: MFG tool need to detect number of NAND chips
// char bPage; // 0xb: 5: 2^5=32 (512P); 6=2^6=64 (2KP)
// char bMaxBlk; // 0xc: 2^bMaxBlk i.e. 13=8K => 8K*512*32=128MB
// char bNandCfg; // 0xd: bit0=cache read, bit1=prog cache, bit2=30ns/50ns
// char bFwCfg; // 0xe: bit0=WriteProtec, bit1=ECC enable
// char bFwRev; // 0xf: 0-3=LSB, 4-7: MSB
// char bPads[512-16];
//} NandCfg;
//-----------------------------------------------------------------------------
bit CheckSignature()
{
AUTOPTR1H = MSB(EP6FIFOBUF); // load EP6FIFOBUF into AUTOPTR1H
AUTOPTR1L = LSB(EP6FIFOBUF); // load EPFIFOBUF into AUTOPTR1L
// Check for "SMTDMG" signature
if (P_XAUTODAT1 != 'S' ||
P_XAUTODAT1 != 'M' ||
P_XAUTODAT1 != 'T' ||
P_XAUTODAT1 != 'D' ||
P_XAUTODAT1 != 'M' ||
P_XAUTODAT1 != 'G')
{
return 1;
}
// This code will ignore all the Option, except these variables below
gZones = 1 << (EP6FIFOBUF[0xc]-10); // Number of Zones in a NAND block
// Possible Zones will be defined as follows:
// 8: 512, 8 Zones; 128MB
// 1: 2K, 1 Zone; 128MB
// 4: 512, 4 Zones; 64MB 4: 2K, 4 Zone; 512MB
// 2: 2K, 2 Zones; 256MB
NandCfg = EP6FIFOBUF[0xd]; // bNandCfg
FwCfg = EP6FIFOBUF[0xe]; // bFwCfg
return nReadCfgPage(); // this is Vendor configuration page
}
//-----------------------------------------------------------------------------
// NX2LP NAND Command support for Manufacturing tools and Validation
// CBW SCSI hook on the command 0xC8
//-----------------------------------------------------------------------------
bit handleVendorCBW()
{
BYTE bank, cmd = EP2FIFOBUF[0x10];
WORD add, len = dataTransferLen;
bank = EP2FIFOBUF[CBW_DATA_START+6];
#ifdef USE_2NAND
if (bank>1) DISABLE_NAND();
else if (bank==0) CE0_ON(); else CE1_ON();
#else
IOD = nBank[bank];
#endif
add = gPhyAdd = dwLBA;
P_OUTPKTEND = 0x82;
switch (cmd)
{
case CBW_NAND_ERASE_ALL:
gPhyAdd=0;
// NAND page size
if (bNand2k) cmd = c2KPageSize; else cmd = c512PageSize;
len = gZones << 10; // Zones * 1024
do
{
nand_blk_erase(gPhyAdd);
gPhyAdd += cmd;
} while (--len > 0);
break;
case CBW_NAND_READ_PAGE:
waitForInBuffer();
NandSetAdd(cNAND_READ_DATA, 0);
NandRead(cEP4, len-1);
P_INPKTEND = 4;
break;
case CBW_NAND_ERASE_BLK:
if (bNand2k==0) gPhyAdd <<= 5; else gPhyAdd <<= 6;
nand_blk_erase(gPhyAdd);
break;
case CBW_NAND_WRITE_PAGE:
while (!(P_EP2CS & bmEPEMPTY)) // commit any packets that have already shown up
P_OUTPKTEND = 0x02;
P_EP2FIFOCFG = bmAUTOOUT | bmOEP;
NandSetAdd(cNAND_WRITE_DATA, 0);
FifoWr(cEP2, len-1); // write out the data area
NandSendCmd(cNAND_PROGRAM_PAGE);
P_EP2FIFOCFG = 0;
gCurZone = 0xff; // require fresh LUT table
break;
case CBW_NAND_READ_REDUNDANT:
Fifo6In();
cmd = cNAND_READ_REDUNDANT;
if (bNand2k) cmd = cNAND_READ_DATA;
for (bank=0; bank<64; bank++)
{
NandSetAdd(cmd, 4);
NandRead(cEP6, cNAND_REDUNDANT_SIZE);
xPhyAdd++;
}
NandSendCmd(cNAND_RESET);
goto ep8_out;
case CBW_8051_LUT_DUMP: //dump LUT
add = (WORD)gLog2Phy;
goto mem_rd;
case CBW_NAND_READ_FLASH_ID:
GetNandType();
ep8_out:
add = (WORD)EP6FIFOBUF;
// fall through
case CBW_8051_MEM_READ: // data should be less than 64K
mem_rd:
while (len>wPacketSize)
{
mymemmovexx(EP4FIFOBUF, (char xdata*)add, wPacketSize);
len -= wPacketSize;
add += wPacketSize;
EP4BCH = MSB(wPacketSize);
EP4BCL = LSB(wPacketSize);
waitForInBuffer();
}
if (len)
{
mymemmovexx(EP4FIFOBUF, (char xdata*)add, len);
EP4BCH = MSB(len); EP4BCL = LSB(len);
}
break;
case CBW_8051_MEM_WRITE: // len should not be more 1K
while ((P_EP2CS & bmEPEMPTY)); // Wait for host to send data
mymemmovexx((volatile char xdata*)add, EP2FIFOBUF, len);
loadEP2BC();
break;
case CBW_8051_RENUM: // re-enumeration
sendUSBS(USBS_PASSED);
EZUSB_Delay(200);
EZUSB_Discon(TRUE); // renumerate until setup received
break;
}
dataTransferLen = 0;
DISABLE_NAND();
return(USBS_PASSED);
}
//-----------------------------------------------------------------------------
// void loadEP2BC()
//-----------------------------------------------------------------------------
void loadEP2BC()
{
WORD len = dataTransferLen;
bit bShortPacketReceived = 0;
// Toss away all of the data received with the command
while (len && !bShortPacketReceived)
{
if(!(P_EP2CS & bmEPEMPTY))
{
len -= min(EP2BC, len);
if (EP2BC != wPacketSize)
bShortPacketReceived = 1;
OUTPKTEND = 0x82;
}
}
}
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -