?? vend_cbw.c
字號:
//-----------------------------------------------------------------------------
// Copyright (c) 2005 Cypress Semiconductor, Inc. All rights reserved
//-----------------------------------------------------------------------------
//
// This file contains the NX2LPL manufacturing validation command and
// Security support
//
// $Archive: /USB/atapifx2/NX2LP/SRC/CY3686FW/vend_cbw.c $
//
// $Date: 8/08/05 10:49a $
// $Revision: 1 $
//
// History:
//-----------------------------------------------------------------------------
//
// 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.
//
//--------------------------------------------------------------------------
#include "globals.h"
#define NX2LP_CMD 0xC8 // NX2LP Manufacturing/Validation command support
#define CBW_NAND_READ_PAGE 0 // <bank><page><len> Read NAND Page (only 528 or 2K+64)
#define CBW_NAND_WRITE_PAGE 1 // <bank><page><len> Write NAND page (only 528 or 2K+64)
#define CBW_NAND_ERASE_BLK 2 // <bank><block> Erase Block (single block)
#define CBW_NAND_READ_REDUNDANT 3 // <bank><page> Read Redundant <block number>
#define CBW_NAND_READ_FLASH_ID 4 // <bank><len=7> Read Flash ID: return 4-byte ID, 2-status, 1-nandtype
#define CBW_NAND_ERASE_ALL 5 // <bank><skip> Erase All with <skip bad block=1>
#define CBW_NAND_SET_ERR 6 // Simulate NAND error on NAND Read Status
#define CBW_NAND_GEN_CMD 7 // TBD (need design)
#define CBW_8051_LUT_DUMP 8 // <len>
#define CBW_8051_MEM_READ 9 // <address><len> 8051 memory read
#define CBW_8051_MEM_WRITE 0xa // <address><len> 8051 memory write
#define CBW_8051_RENUM 0xb // re-enumeration
#define CBW_READ_UNIQUE_ID 0xc // Read NAND unique ID
//-----------------------------------------------------------------------------
// Configure FIFO6 to read data from NAND
//-----------------------------------------------------------------------------
void Fifo6In() { P_FIFORESET=6, P_EP6CFG=EP6CFG_IN_DEFAULT; }
//-----------------------------------------------------------------------------
// Send Command to NAND chip
// cmd = NAND Command
//-----------------------------------------------------------------------------
void NandSendCmd(BYTE cmd)
{
NAND_CLE=1, P_XGPIFSGLDATLX=cmd, NAND_CLE=0;
}
//-----------------------------------------------------------------------------
// General read data from NAND using GPIF wave form 0
//-----------------------------------------------------------------------------
void NandRead(BYTE ep, WORD len)
{
nand_ready3();
FifoRd(ep, len);
}
//-----------------------------------------------------------------------------
// Get NAND Type
// EP6FIFOBUF contains 4-bytes ID, 2-byte status, 1-byte=bNand2k
//-----------------------------------------------------------------------------
void GetNandType()
{
Fifo6In(); // need this for reading data, see waveform
NandSendCmd(cNAND_READ_ID);
NAND_ALE=1, P_XGPIFSGLDATLX=0, NAND_ALE=0;
NandRead(cEP6,4-1); // read NAND ID: 4 bytes
NandSendCmd(cNAND_READ_STATUS);
NandRead(cEP6,2-1); // read status 2 bytes
// 512/2K NAND Auto detect should be done here
// Use NAND_2K as sharing 2K/512 FW code
#ifdef NAND_2K
bNand2k = 1; // force this bit = 2K NAND
#else
bNand2k = 0; // force this bit = 512 NAND
#endif
EP6FIFOBUF[6]= bNand2k; // return NAND type
}
//-----------------------------------------------------------------------------
// NAND Set Address: Take 2.2 us for 512P NAND
// msk = 0-3, read page 1-4
// msk = 4, read offset 0x830 = redundant
// return none
// global: bit bNand2k = 1 = 2KP NAND, else 512P NAND
// gPhyAdd: set this before call this subroutine
//-----------------------------------------------------------------------------
// for 2K NAND sub-page address: 0=0x000 1=0x210, 2=0x420, 3=0x630, 4=0x830
const char code nadd0[5]={0, 0x10, 0x20, 0x30, 0x30};
const char code nadd1[5]={0, 0x02, 0x04, 0x06, 0x08};
void NandSetAdd(BYTE cmd, BYTE msk)
{
nand_ready3();
NAND_CLE=1,P_XGPIFSGLDATLX=cmd, NAND_CLE=0;
NAND_ALE = 1;
if (bNand2k)
{
P_XGPIFSGLDATLX = nadd0[msk];
P_XGPIFSGLDATLX = nadd1[msk];
}
else
P_XGPIFSGLDATLX = 0;
P_XGPIFSGLDATLX = ((BYTE *)&gPhyAdd)[3];
P_XGPIFSGLDATLX = ((BYTE *)&gPhyAdd)[2];
P_XGPIFSGLDATLX = ((BYTE *)&gPhyAdd)[1];
NAND_ALE = 0;
if (bNand2k && cmd==cNAND_READ_DATA) NAND_CLE=1, P_XGPIFSGLDATLX=cNAND_READ_START, NAND_CLE=0;
}
//-----------------------------------------------------------------------------
// Reading NAND Configuration page
// The reading always support ECC correction
//-----------------------------------------------------------------------------
bit nReadCfgPage()
{
Fifo6In();
P_ECCRESET=0;
NandSetAdd(cNAND_READ_DATA, 0);
NandRead(cEP6, cNAND_PSIZE); // always read 512+16 bytes
ECCSetup(EP6FIFOBUF+512+cCFG_ECC_OFF);
gPhyAdd++; // next page
return CorrectData(); // always correct data
}
//-----------------------------------------------------------------------------
// nCopyBlock:
// Correct Bad ECC Block for both 2K NAND and 512 NAND
// Mark the block bad with 0xF0 if there is more than 2-bit ECC error
// bSofErr will control the
/// Mark the block bad with multiple repeat 1-bit ECC errors
//-----------------------------------------------------------------------------
void nCopyBlock()
{
#ifdef NAND_2K // 2K FW code
BYTE cnt;
bit bECC_Retry;
xbyte *p;
WORD pa0;
#ifdef USE_2NAND
if (gBank==0) CE0_ON(); else CE1_ON();
#else
IOD = gEnableBanks;
#endif
p = (xbyte*)&gLog2Phy[gSrc];
bECC_Retry = (*p & MSB(cBLK_ECC));
*p |= MSB(cBLK_ECC); // set ECC bit
pa0 = gCurZone << cMaxBlock2N; // compute Zone
gSrcAdd = ((DWORD)(pa0 | gSrc) << c2KPageSize2N);
gSrcBlk0 = ((BYTE *)&gSrcAdd)[3];
nGetFreeBlk(); // return gFreeBlk
gPhyAdd = ((DWORD)(pa0 | gFreeBlk) << c2KPageSize2N);
b2BitErr = 0;
nCopyPages(0, 0); // copy and correct ECC data
bNeedErase=1;
if (b2BitErr || (bECC_Retry && !bSoftErr))
{
if (b2BitErr) // more than 2 bit need to erase
{
xPhyAdd -= c2KPageSize2N; // need to erase good block
nand_blk_erase(gPhyAdd);
}
// mask the src block bad
((BYTE *)&gPhyAdd)[3] = gSrcBlk0;
((BYTE *)&gPhyAdd)[2] = ((BYTE *)&gSrcAdd)[2];
((BYTE *)&gPhyAdd)[1] = ((BYTE *)&gSrcAdd)[1];
NandSetAdd(cNAND_WRITE_DATA, 3);
for (cnt=0; cnt<(528/4); cnt++) // mask this block bad
{
P_XGPIFSGLDATLX = 0xf0; _nop_();
P_XGPIFSGLDATLX = 0xf0; _nop_();
P_XGPIFSGLDATLX = 0xf0; _nop_();
P_XGPIFSGLDATLX = 0xf0;
}
NandSendCmd(cNAND_PROGRAM_PAGE); // program only one page
gCurZone = 0xff; // refresh the LUT
}
else
{
*p &= MSB(~cBLK_USE); // set this block free
*(xbyte*)&gLog2Phy[gFreeBlk] |= MSB(cBLK_USE); // Set this block is used
*pDst = (*pDst & cBLK_uMSK) | gFreeBlk; // update Logical address
nEraseBlock(); // erase block
}
#else // 512 FW code
BYTE cnt=32;
bit bECC_Retry;
xbyte *p;
WORD pa0;
if (bInterLeave) cnt=64; // (32 page per NAND)*2
#ifdef USE_2NAND
CE0_ON(), CE1_ON();
#else
IOD = gEnableBanks;
#endif
p = (xbyte*)&gLog2Phy[gSrc];
bECC_Retry = (*p & MSB(cBLK_ECC));
*p |= MSB(cBLK_ECC); // set ECC bit
pa0 = gCurZone << cMaxBlock2N; // compute Zone
gSrcAdd = ((DWORD)(pa0 | gSrc) << c512PageSize2N);
gSrcBlk0 = ((BYTE *)&gSrcAdd)[3];
nGetFreeBlk(); // return gFreeBlk
gPhyAdd = ((DWORD)(pa0 | gFreeBlk) << c512PageSize2N);
b2BitErr = 0;
nCopyPages(cnt, 0); // copy and correct ECC data
bNeedErase=1;
if (b2BitErr || (bECC_Retry && !bSoftErr))
{
#ifdef USE_2NAND
CE0_ON(), CE1_ON();
#else
IOD = gEnableBanks;
#endif
if (b2BitErr) // more than 2 bit need to erase
{
xPhyAdd -= c512PageSize2N; // need to erase good block
nand_blk_erase(gPhyAdd);
}
// mask the src block bad
((BYTE *)&gPhyAdd)[3] = gSrcBlk0;
((BYTE *)&gPhyAdd)[2] = ((BYTE *)&gSrcAdd)[2];
((BYTE *)&gPhyAdd)[1] = ((BYTE *)&gSrcAdd)[1];
NandSetAdd(cNAND_WRITE_DATA, 3);
for (cnt=0; cnt<(528/4); cnt++) // mask this block bad
{
P_XGPIFSGLDATLX = 0xf0; _nop_();
P_XGPIFSGLDATLX = 0xf0; _nop_();
P_XGPIFSGLDATLX = 0xf0; _nop_();
P_XGPIFSGLDATLX = 0xf0;
}
NandSendCmd(cNAND_PROGRAM_PAGE); // program only one page
gCurZone = 0xff; // refresh the LUT
}
else
{
*p &= MSB(~cBLK_USE); // set this block free
*(xbyte*)&gLog2Phy[gFreeBlk] |= MSB(cBLK_USE); // Set this block is used
*pDst = (*pDst & cBLK_uMSK) | gFreeBlk; // update Logical address
nEraseBlock(); // erase block
}
#endif
DISABLE_NAND();
}
//-----------------------------------------------------------------------------
// Get NAND configuration data
// This code follow the Boot-Loader code to get configuration data and
// Vendor Strings
// This code supports both 2K and 512 NAND types
?? 快捷鍵說明
復(fù)制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -