📄 inand.lst
字号:
246 1 AUTOPTR1H = MSB(offset);
247 1 AUTOPTR1L = LSB(offset);
248 1 #ifdef NAND_2K
249 1 bReload = xLBA3 ==0 && bCnt; // compute bReload
250 1 bMsk = xLBA3 & 3;
251 1 if (!bMsk) xPhyAdd++; // 2K NAND address inc
252 1 #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
268 1 while (P_GPIFTCB1); // Read the first 256 ECC registers
269 1 ecc0[0] = P_ECC1B0[0]; // save to local buffers
270 1 ecc0[1] = P_ECC1B0[1];
271 1 ecc0[2] = P_ECC1B0[2];
272 1 while (P_GPIFTCB0 & 0xf8); // Read second 256 ECC registers
273 1 ecc0[3] = P_ECC1B0[3]; // save ECC
274 1 ecc0[4] = P_ECC1B0[4]; // GPIF will be done afer reading these
275 1 ecc0[5] = P_ECC1B0[5]; // registers
276 1 // Stored 6-byte ECC data from NAND Flash
277 1 ecc1[0] = P_XAUTODAT1;
278 1 ecc1[1] = P_XAUTODAT1;
279 1 ecc1[2] = P_XAUTODAT1;
280 1 ecc1[3] = P_XAUTODAT1;
281 1 ecc1[4] = P_XAUTODAT1;
282 1 ecc1[5] = P_XAUTODAT1;
283 1 P_INPKTEND = 0x84; // skip 16-byte of the redundant data
284 1 }
285
286 //==========================================================================
287 // Check ECC, if fail, return bErr=1
288 // Should call CorrectData if more than ECC 2bit error, the b2BitErr will
289 // be set.
290 // Modify:
291 // bCnt = 0 will terminate the while loop
292 // bErr = 1 will send STALL to USB Host
293 //==========================================================================
294 void CheckECC()
295 {
296 1 if ( (ecc0[0] != ecc1[0]) || (ecc0[1] != ecc1[1]) || (ecc0[2] != ecc1[2]) ||
297 1 (ecc0[3] != ecc1[3]) || (ecc0[4] != ecc1[4]) || (ecc0[5] != ecc1[5]) )
298 1 {
299 2 bErr = 1; bCnt = 0; // Will stall in the Status phase
300 2 }
301 1 }
302
C51 COMPILER V7.50 INAND 10/12/2007 17:05:46 PAGE 6
303 //==========================================================================
304 // Get Physical block from LUT
305 // return gCurZone = (dwLBA/PageSize)/cMaxLogical
306 // = (dwLBA/PageSize) % cMaxLogical
307 // gPhyAdd = Physical block
308 // gSrcAdd = Physical Source Address for Write
309 //==========================================================================
310 void Log2Phy()
311 {
312 1 BYTE xdata page, zz, z;
313 1 WORD xdata wi, wTmp;
314 1 #ifdef NAND_2K
315 1 if (bErr) return;
316 1 page = xLBA3; // 2K: pagesize = 256
317 1 ((BYTE *)&gDst)[0] = ((BYTE *)&dwLBA)[1]; // MSB: gDst = (WORD)(dwLBA>>16);
318 1 ((BYTE *)&gDst)[1] = ((BYTE *)&dwLBA)[2]; // LSB: Dst = 2K Block number
319 1 z = 0;
320 1 while (gDst >= cMaxLogical) { gDst -= cMaxLogical; z++; } // z = gDst/cMaxLogical
321 1
322 1 zz = z & (gZones-1);
323 1 z /= gZones; // z = number of NAND bank
324 1 #ifdef USE_2NAND
if (z==0) CE0_ON(), CE1_OFF(); else CE1_ON(), CE0_OFF();
#else
327 1 gEnableBanks = IOD = nBank[z]; // enable banks
328 1 #endif
329 1
330 1 if ((gBank != z) || (zz != gCurZone)) // need to reload when bank switch
331 1 {
332 2 //UM_SendString("\nREFISH************\n");
333 2 gBank = z; // update bank
334 2 gCurZone = zz; // update zone
335 2 //=================================================================
336 2 // BuildTable();
337 2 // This function build the LUT for Logical to Physical translation
338 2 // need gCurZone
339 2 //=================================================================
340 2 memset16((xbyte*)gLog2Phy, MSB(cBLK_INIT), (cMaxBlock*2)/16);
341 2 ((BYTE *)&gPhyAdd)[3] = 0;
342 2 ((BYTE *)&gPhyAdd)[2] = 0; // optimize for speed
343 2 ((BYTE *)&gPhyAdd)[1] = gCurZone; // gPhyAdd <<= 16;
344 2
345 2 for (wi=0; wi<cMaxBlock; wi++)
346 2 { // read the redundant section of the page into EP6
347 3 xbyte *p = &gLog2Phy[wi]; // get address pointer
348 3 NandSetAdd(cNAND_READ_DATA, 4);
349 3 Fifo6In();
350 3 NandRead(cEP6, cNAND_RSIZ);
351 3 ////////////////////////////////////////////////
352 3 //LigangWang for debug
353 3 //if(dwLBA == 0)
354 3 //{
355 3 // UM_SendString("\n");
356 3 // for(i = 0;i < (cNAND_RSIZ+1);i++)
357 3 // UM_SendByte(EP6FIFOBUF[i]);
358 3 //}
359 3 ////////////////////////////////////////////////
360 3 bFreeBlk = (EP6FIFOBUF[0] == 0xff) && (EP6FIFOBUF[1] == 0xff);
361 3 if (!bFreeBlk)
362 3 *p |= MSB(cBLK_CFG); // special block or bad block
363 3 else
364 3 {
C51 COMPILER V7.50 INAND 10/12/2007 17:05:46 PAGE 7
365 4 ((BYTE *)&wTmp)[0] = EP6FIFOBUF[cAddOffset]; // MSB address1
366 4 // check if the block is not free
367 4 if (((BYTE *)&wTmp)[0] != 0xff)
368 4 {
369 5 ((BYTE *)&wTmp)[1] = EP6FIFOBUF[cAddOffset+1]; // LSB address1
370 5 if ( (((BYTE *)&wTmp)[0] == EP6FIFOBUF[cAddOffset+2]) && // check if both addresses
-are matched
371 5 (((BYTE *)&wTmp)[1] == EP6FIFOBUF[cAddOffset+3]) )
372 5 {
373 6 xword *pTmp = &gLog2Phy[wTmp];
374 6
375 6 wTmp = *pTmp;
376 6 if (wTmp & cBLK_INIT) // multiple blocks map check
377 6 { *pTmp = ( wTmp & cBLK_uMSK ) | wi; // store the remap block
-
378 7 *p |= MSB(cBLK_USE); // Set Block Use
379 7 }
380 6 else
381 6 {
382 7 nand_blk_erase(gPhyAdd);
383 7 *(xbyte*)0xe100 = 0xee;
384 7 }
385 6 }
386 5 } // else this block is free
387 4 }
388 3 gPhyAdd += c2KPageSize; // next block for 2K NAND
389 3
390 3 } // for wi
391 2 bFreeFound = 0; // cross the Zone, reset the Free Block Found
392 2 } // update table again
393 1
394 1
395 1 wTmp = zz << cMaxBlock2N; // compute Zone
396 1 pDst = gLog2Phy + gDst; // pDst = &gLog2Phy[gDst]
397 1 gSrc = *pDst & cBLK_aMSK; // gLog2Phy[gDst]: Get Physical block
398 1
399 1 //UM_SendString("R:LBA=");
400 1 //UM_SendByte(((BYTE *)&dwLBA)[3]);
401 1 //UM_SendByte(((BYTE *)&dwLBA)[2]);
402 1 //UM_SendByte(((BYTE *)&dwLBA)[1]);
403 1 //UM_SendByte(((BYTE *)&dwLBA)[0]);
404 1
405 1 if (directionIn) // read just get the table
406 1 {
407 2
408 2 wTmp |= gSrc;
409 2 ((BYTE *)&gPhyAdd)[3] = ( ((BYTE *)&wTmp)[1] << 6 ) | (page>>2);
410 2 ((BYTE *)&gPhyAdd)[2] = ( ((BYTE *)&wTmp)[1] >> 2 ) | ( ((BYTE *)&wTmp)[0] << 6 );
411 2 ((BYTE *)&gPhyAdd)[1] = ( ((BYTE *)&wTmp)[0] >> 2 );
412 2 NandSetAdd(cNAND_READ_DATA, (page&3));
413 2
414 2 //UM_SendString("RPHY=");
415 2 //UM_SendByte(((BYTE *)&gPhyAdd)[3]);
416 2 //UM_SendByte(((BYTE *)&gPhyAdd)[2]);
417 2 //UM_SendByte(((BYTE *)&gPhyAdd)[1]);
418 2 //UM_SendString("\n");
419 2 }
420 1 else
421 1 {
422 2 xbyte *p;
423 2 nGetFreeBlk(); // get Free Block
424 2 wi = gFreeBlk;
C51 COMPILER V7.50 INAND 10/12/2007 17:05:46 PAGE 8
425 2 if (gSrc&cBLK_INIT) gSrc=wi; // default value set to free block
426 2 bNeedErase = (wi != gSrc); // don't erase if Src = Dst && block free
427 2
428 2 // *(xbyte*)&gLog2Phy[gSrc] &= MSB(~cBLK_USE); // set this block free
429 2 p = (xbyte*)&gLog2Phy[gSrc]; // point to the SRC block
430 2 // July-07-05 Free Block must exclude CFG block as well
431 2 bFreeBlk = !(*p & MSB(cBLK_uMSK)); // free block
432 2 *p = *p & MSB(~cBLK_USE); // set this block free
433 2
434 2 *(xbyte*)&gLog2Phy[wi] |= MSB(cBLK_USE); // Set this block is used
435 2 *pDst = (*pDst & cBLK_uMSK) | wi; // update Logical address
436 2
437 2 wi |= wTmp;
438 2 ((BYTE *)&gPhyAdd)[3] = ( ((BYTE *)&wi)[1] << 6 );
439 2 ((BYTE *)&gPhyAdd)[2] = ( ((BYTE *)&wi)[1] >> 2 ) | ( ((BYTE *)&wi)[0] << 6 );
440 2 ((BYTE *)&gPhyAdd)[1] = ( ((BYTE *)&wi)[0] >> 2 );
441 2
442 2
443 2 wTmp |= gSrc;
444 2 gSrcBlk0 = ((BYTE *)&gSrcAdd)[3] = ( ((BYTE *)&wTmp)[1] << 6 );
445 2 ((BYTE *)&gSrcAdd)[2] = ( ((BYTE *)&wTmp)[1] >> 2 ) | ( ((BYTE *)&wTmp)[0] << 6 );
446 2 ((BYTE *)&gSrcAdd)[1] = ( ((BYTE *)&wTmp)[0] >> 2 );
447 2
448 2 if (page)
449 2 {
450 3 NAND_PCPY(page, 0);
451 3 }
452 2
453 2 //UM_SendString("WPHY=");
454 2 //UM_SendByte(((BYTE *)&gPhyAdd)[3]);
455 2 //UM_SendByte(((BYTE *)&gPhyAdd)[2]);
456 2 //UM_SendByte(((BYTE *)&gPhyAdd)[1]);
457 2
458 2 //UM_SendString("SPHY=");
459 2 //UM_SendByte(((BYTE *)&gSrcAdd)[3]);
460 2 //UM_SendByte(((BYTE *)&gSrcAdd)[2]);
461 2 //UM_SendByte(((BYTE *)&gSrcAdd)[1]);
462 2 //UM_SendString("\n");
463 2
464 2 }
465 1 #else
BYTE npage;
if (bErr) return;
gSrc = (WORD)dwLBA;
((BYTE *)&gDst)[0] = ((BYTE *)&dwLBA)[0]; // MSB: gDst = (WORD)(dwLBA>>16);
((BYTE *)&gDst)[1] = ((BYTE *)&dwLBA)[1]; // LSB
if (bInterLeave)
{
page = xLBA3 & cInterLeaveMsk;
npage = page>>1; // remove bit0 for interleave
gDst <<= 16-(c512PageSize2N+1); // dwLBA >>= c512PageSize2N+1
gSrc >>= c512PageSize2N+1;
}
else
{
npage = page = xLBA3 & (c512PageSize-1); // mask page 5-bits 0x1F
gDst <<= 16-c512PageSize2N; // dwLBA >>= c512PageSize2N
gSrc >>= c512PageSize2N;
}
gDst |= gSrc; // gDst = dwLBA/c512PageSize
C51 COMPILER V7.50 INAND 10/12/2007 17:05:46 PAGE 9
z = 0;
while (gDst >= cMaxLogical) { gDst -= cMaxLogical; z++; } // z = gDst/cMaxLogical
zz = z & (gZones-1); // zz = zone numbers within a NAND
z /= gZones; // gZones=8=8192, gZones=4=4096
#ifdef USE_2NAND
CE0_ON(),CE1_ON(); // enable both NAND chip select
#else
gEnableBanks = IOD = aBanks[z]; // pre-load fast variables
#endif
// Reload the LUT when cross bank and zone
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -