📄 inand.lst
字号:
C51 COMPILER V7.50 INAND 10/12/2007 17:05:46 PAGE 1
C51 COMPILER V7.50, COMPILATION OF MODULE INAND
OBJECT MODULE PLACED IN inand.OBJ
COMPILER INVOKED BY: d:\Keil\C51\BIN\C51.EXE inand.c OBJECTADVANCED OPTIMIZE(11,SIZE) REGFILE(.\nand_fw2k.ORC) BROWSE OR
-DER INCDIR(c:\cypress\usb\target\inc) DEFINE(NAND_2K) DEBUG
line level source
1 //-----------------------------------------------------------------------------
2 // Copyright (c) 2005 Cypress Semiconductor, Inc. All rights reserved
3 //
4 // File: inand.c
5 // Contents:
6 // Interleave NAND support the bInterLeave Flag will enable
7 // Odd number NAND chips, the interleave FW will be disable
8 // Even number NAND chips, then interleave FW will be enable
9 //
10
11 //-----------------------------------------------------------------------------
12 #include "globals.h"
13
14
15 WORD xdata gLog2Phy[cMaxBlock] ; // bit0-11 addr map, bit12=1=free, 0=used
16 BYTE xdata gCurZone, gZones, gBankSel, gPartialCpy; // Use this byte to reload the Table
17 WORD gDst, gSrc, gFreeBlk; // These variable will be shared
18
19 DWORD gSrcAdd, gPhyAdd, gNextLBA; // sharing variables in multiple subrountines
20 BYTE ecc0[6], ecc1[6]; // Optimize ECC variables
21 BYTE xdata gSrcBlk0; // use for EraseBlock
22 xword *pDst;
23
24 #ifndef USE_2NAND
25 // fast coding for bank select
26 const char code aBanks[4]={0xfc, 0xf3, 0xcf, 0x3f}; // interleave bank
27 const char code aBank0[4]={0xfe, 0xfb, 0xef, 0xbf}; // interleave bank
28 const char code aBank1[4]={0xfd, 0xf7, 0xdf, 0x7f}; // interleave bank
29 const char code nBank[8]={0xfe, 0xfd, 0xfb, 0xf7, 0xef, 0xdf, 0xbf, 0x7f};
30 BYTE xdata gEnableBanks;
31
32 #ifndef NAND_2K
BYTE gEnableBank0, gEnableBank1; // optimize variables
#endif
35
36 #endif
37
38
39 // Note: These variables below will be used to optimize speed
40 // These variables use in conjunction with MPAGE that map to 0xE6xx
41 pbyte P_GPIFTCB0 _at_ 0xd1; // GPIFTCB0
42 pbyte P_GPIFTCB1 _at_ 0xd0; // GPIFTCB1
43 pbyte P_XAUTODAT1 _at_ 0x7b; // XAUTODAT1
44 pbyte P_XAUTODAT2 _at_ 0x7c; // XAUTODAT2
45 pbyte P_ECC1B0[6] _at_ 0x2a; // 6 bytes ECC registers
46 pbyte P_INPKTEND _at_ 0x48; // INPKTEND
47 pbyte P_OUTPKTEND _at_ 0x49; // OUTPKTEND
48 pbyte P_ECCCFG _at_ 0x28; // ECCCFG
49 pbyte P_ECCRESET _at_ 0x29; // ECCRESET
50 pbyte P_EP6BCH _at_ 0x98; // EP6BCH
51 pbyte P_EP6BCL _at_ 0x99; // EP6BCL
52 pbyte P_EP4BCH _at_ 0x94; // EP4BCH
53 pbyte P_EP4BCL _at_ 0x95; // EP4BCL
54 pbyte P_GPIFREADYSTAT _at_ 0xf4; // GPIFREADYSTAT
C51 COMPILER V7.50 INAND 10/12/2007 17:05:46 PAGE 2
55 pbyte P_FIFORESET _at_ 0x04; // FIFORESET
56 pbyte P_EP6CFG _at_ 0x14; // EP6CFG
57 pbyte P_EP2FIFOCFG _at_ 0x18; // EP2FIFOCFG
58 pbyte P_XGPIFSGLDATLX _at_ 0xf1; // XGPIFSGLDATLX
59 pbyte P_XGPIFSGLDATLNOX _at_ 0xf2; // XGPIFSGLDATLNOX
60 pbyte P_EP2CS _at_ 0xa3; // EP2CS
61 pbyte P_EP4CS _at_ 0xa4; // EP4CS
62 pbyte P_EP6CS _at_ 0xa5; // EP4CS
63
64
65 //==========================================================================
66 // NAND Hardware/software init
67 // Donot call this subroutine during the SOFT RESET (i.e. softReset)
68 //==========================================================================
69 void InitNAND()
70 {
71 1 gNandBits = 0; // all the NAND bits variables = 0
72 1 FwCfg = 0;
73 1 NandCfg = 0;
74 1 gFreeBlk = 0;
75 1 gPartialCpy = 0;
76 1 dwLBA = 0;
77 1 GetNandCfg(); // Get NAND Configuration from MFG TOOL
78 1 directionIn=1; // Compute Log2Phy Table at init time
79 1 NAND_WP = 1;
80 1 gCurZone = 0xff; // Load current zone
81 1 //UM_SendChar('A');
82 1 //UM_SendString("InitNand:Log2phy\n");
83 1 Log2Phy();
84 1 ready_default(); // restore default value
85 1 #ifndef NO_WP
86 1 bWPSwitchState = NAND_WP_SWITCH;
87 1 #endif
88 1 DISABLE_NAND();
89 1 }
90
91 //==========================================================================
92 // Get Free block from LUT
93 // This search always return a free block
94 //==========================================================================
95 void nGetFreeBlk()
96 {
97 1 while (!bFreeFound) // search until found free block
98 1 nSearchFreeBlock(0); // will search for 256 entries
99 1 bFreeFound = 0;
100 1 }
101
102 //==========================================================================
103 // NAND EraseBlocks on both banks
104 // input: gSrcAdd = Current Src Block
105 //==========================================================================
106 void nEraseBlock()
107 {
108 1 if (bNeedErase) // only erase if needed
109 1 { // erase both banks in the interleave mode
110 2 #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
C51 COMPILER V7.50 INAND 10/12/2007 17:05:46 PAGE 3
117 2 xSrcAdd = gSrcBlk0;
118 2 nand_blk_erase(gSrcAdd);
119 2 // after erasing the NAND, there are some spare time for background search
120 2 nSearchFreeBlock(0); // will search for 256 entries
121 2 }
122 1 }
123
124 #pragma OT(7, SPEED) // Use this optimize for the speed
125
126 //==========================================================================
127 // Clear 16-byte each pass.
128 // Maximun 4K buffer
129 //==========================================================================
130 void memset16(BYTE xdata *dest, BYTE c, BYTE len)
131 {
132 1 AUTOPTR1H = MSB(dest); AUTOPTR1L = LSB(dest);
133 1 do
134 1 { // Unrole the loop to speed up memory fill
135 2 P_XAUTODAT1 = P_XAUTODAT1 = P_XAUTODAT1 = P_XAUTODAT1 =
136 2 P_XAUTODAT1 = P_XAUTODAT1 = P_XAUTODAT1 = P_XAUTODAT1 =
137 2 P_XAUTODAT1 = P_XAUTODAT1 = P_XAUTODAT1 = P_XAUTODAT1 =
138 2 P_XAUTODAT1 = P_XAUTODAT1 = P_XAUTODAT1 = P_XAUTODAT1 = c;
139 2 } while (--len>0);
140 1 }
141
142 //==========================================================================
143 // Read NAND Pages: Supports for both interleave and non-interleave
144 // return bErr and b2BitErr, which will send STALL to USB Host
145 // Modify:
146 // ecc0[] and ecc1[]
147 // bMsk, bCnt
148 //==========================================================================
149 void nReadPages()
150 {
151 1 #ifdef NAND_2K
152 1 Log2Phy(); // remap logical blocks
153 1
154 1 // Read the first 512 byte data and save all the ECC data in ecc0[]
155 1 // and ecc1[] buffers. The CheckECC will be called to verify the ECC
156 1 // during the polling for GPIF DMA done (USB data transfer to USB Host)
157 1
158 1 P_GPIFTCB1 = MSB(cNAND_PSIZE); // Setup GPIF count high
159 1 P_ECCRESET = P_GPIFTCB0 = LSB(cNAND_PSIZE); // Reset ECC and GPIF low count
160 1 GPIFTRIG = 0x04 | cEP4; // Arm EP4
161 1 // Compute while GPIF Busy
162 1 ECCSetup(EP4FIFO); // Poll GPIF and store ECC data
163 1 if (!bMsk)
164 1 {
165 2 if (bReload) { CheckECC(); Log2Phy(); } // check if need to remap page
166 2 else n2k_set_radd();
167 2 }
168 1 if (bCnt)
169 1 {
170 2 do
171 2 {
172 3 P_GPIFTCB1 = MSB(cNAND_PSIZE); // Setup GPIF count high
173 3 P_ECCRESET = P_GPIFTCB0 = LSB(cNAND_PSIZE); // Reset ECC and GPIF low count
174 3 GPIFTRIG = 0x04 | cEP4; // Arm EP4
175 3 //=========================================================================
176 3 // local computation while polling GPIF done to optimize the speed
177 3 //=========================================================================
178 3 CheckECC(); // Verify previous ECC data
C51 COMPILER V7.50 INAND 10/12/2007 17:05:46 PAGE 4
179 3 ECCSetup(EP4FIFO);
180 3 if (!bMsk)
181 3 {
182 4 if (bReload) Log2Phy();
183 4 else n2k_set_radd();
184 4 }
185 3 } while (bCnt);
186 2 }
187 1 CheckECC(); // Verify last ECC data
188 1 #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
231 1 DISABLE_NAND();
232 1 }
233
234 //==========================================================================
235 // Setup AUTO pointer for P_XAUTODAT1
236 // Read ECC registers when first 256 ECC calculation done
237 // Read 512 byte data and save:
238 // ecc0[] contains GPIF HW generate 6 ECC bytes
239 // ecc1[] contains ECC data from redundant area
240 //==========================================================================
C51 COMPILER V7.50 INAND 10/12/2007 17:05:46 PAGE 5
241 void ECCSetup(WORD offset)
242 {
243 1 dwLBA++; // next sector
244 1 bCnt = --gSectorcount && !bErr;
245 1 // Loading the Pointer of stored 6-bytes ECC data
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -