REVISION
Definition in file nand.c.
#include "../SYSTEM/sys_hardware.h"
#include "nand.h"
#include "nand_assert.h"
#include "eccutil.h"
Include dependency graph for nand.c:

Go to the source code of this file.
Defines | |
| #define | MAKER_SANDISK 0x98 |
| LOCAL DEFINITIONS. | |
| #define | FORMAT_RETRY (10) |
| NAND chip format retry times before reporting fatal error. | |
Functions | |
| BOOL | NAND__replaceDataSec (unsigned long *) |
| Function tries to replace the defected block where phySec resides in. | |
| BOOL | NAND__flushBlock (unsigned short *) |
| Function erases block and writes specified data back. | |
| BOOL | NAND__buildSysInfo (st_NAND *) |
| Function builds and writes the system information to the active flash. | |
| unsigned short | NAND__formatChip (unsigned short) |
| Function formats NAND flash and returns number of read/writable data blocks. | |
| unsigned short | NAND__loadTab (unsigned long, unsigned long, unsigned short) |
| Function loads the specified map table and returs of length of the table in words. | |
| BOOL | NAND__mount (unsigned short) |
| Function initializes NAND flash hardware and read back the system information. | |
| BOOL | NAND__swapSec (unsigned long *, unsigned long) |
| Function tries to allocate a free block and swap with the one the specified logSec resides in. | |
| BOOL | NAND__checkID (void) |
| Function checks NAND flash ID and set up chip parameters. | |
| NAND_COPYERR | NAND__copySec (unsigned short srcPhyBlock, unsigned short *pDstPhyBlock, unsigned short secOffset, unsigned short secNum) |
| Function copies contiguous sector(s) from source block to destination block. | |
| BOOL | NAND__eraseBlock (unsigned short phyBlock) |
| Function erases specified physical block. | |
| BOOL | NAND__flush (BOOL bPARTIAL) |
| Function flushes flash data area if any pending block exists. | |
| BOOL | NAND__historyCheck (void) |
| Function checks to manage the data sector history to yield to operating system while NAND interface is busy. | |
| void | NAND__historySet (unsigned short *pBuf, BOOL swap) |
| Function records a new history sector. | |
| unsigned long | NAND__log2phySec (unsigned long logSec) |
| Function maps the logical sector number to physical sector number if it is available. | |
| BOOL | NAND__markInvalidBlock (unsigned short phyBlock) |
| Function marks the specified block to be invalid if it is already a problematic one, otherwise marks it to be problematic. | |
| BOOL | NAND__readRdnt (unsigned long phySec, unsigned short *pData, unsigned short offSet, unsigned short len) |
| Function reads byte(s) from redundant area. | |
| BOOL | NAND__writeRdnt (unsigned long phySec, unsigned short *pData, unsigned short offSet, unsigned short len) |
| Function writes byte(s) to redundant area. | |
| BOOL | NAND__readSec (unsigned long phySec, unsigned short *pBuf, BOOL swap) |
| Function reads back the specified page/sector. | |
| BOOL | NAND__readDataSec (unsigned long phySec, unsigned short *pBuf, BOOL swap) |
| Function reads back to verify the specified data page/sector. | |
| BOOL | NAND__writeSec (unsigned long phySec, unsigned short *pBuf, BOOL swap) |
| Function writes to the specified blank page/sector. | |
| void | NAND__writeDataSec (unsigned long phySec, unsigned short *pBuf, BOOL swap) |
| Function writes data to the specified blank page/sector. | |
| BOOL | NAND__write (unsigned long phySec, unsigned long pData, unsigned short length) |
| Function writes the specified data back to specified sector(s), it is the caller's responsibility to make sure the corresponding sector(s) is/are blank and cross block shall never happen. | |
| BOOL | NAND__wrSysInfo (void) |
| Function checks to write the system info area. | |
| BOOL | NAND_flush (void) |
| Function flushes the NAND flash and makes all change final. | |
| unsigned long | NAND_format (void) |
| Function will format the nand flash. | |
| unsigned long | NAND_mount (void) |
| Function initializes NAND flash interface. | |
| BOOL | NAND_readSec (unsigned long sec, unsigned short *pBuf, BOOL swap) |
| Function reads back the specified logical sector with disk I/O lock wrapper. | |
| BOOL | NAND__rdSec (unsigned long sec, unsigned short *pBuf, BOOL swap) |
| Function reads back the specified logical sector, specified by the FAT file system layer. | |
| void | NAND_revive (unsigned short blkNum) |
| Function erases entire NAND chip, all information will be lost. | |
| BOOL | NAND__test (void) |
| Function tests NAND interface. | |
| BOOL | NAND_unmount (void) |
| Function unmounts NAND flash and releases memory allocated to flash driver. | |
| BOOL | NAND_writeSec (unsigned long sec, unsigned short *pBuf, BOOL swap) |
| Function writes to the logical sector with I/O lock wrapper. | |
| BOOL | NAND__wrSec (unsigned long sec, unsigned short *pBuf, BOOL swap) |
| Function writes to the logical sector, which is specified by the FAT file system layer, NAND flash will always appear to be contiguous to the FAT file system on a sector level. | |
| BOOL | NAND__isBlockValid (unsigned short phyBlock) |
| Function checks if specified physical block is valid. | |
| BOOL | NAND__isBlockGood (unsigned short phyBlock) |
| Function checks if specified physical block is in good status. | |
Variables | |
| st_SECT_HISTORY | sectHistory |
| GLOBAL DATA. | |
|
|
Function builds and writes the system information to the active flash. There is no block replacement algorithm for this area. If error happens here, it will be treated as a sector 0 failure of a volume disk and reformat is needed to revive flash.
Definition at line 1952 of file nand.c. References st_NAND::curRpBlkNum, st_NAND::dataBlkNum, st_NAND::fmtCtrl, st_NAND::mapTabPhySecOffset, NAND__eraseBlock(), NAND__writeRdnt(), NAND__writeSec(), st_NAND::pagePerBlk, st_NAND::pageSz, st_NAND::rpTabBackPhyBlk, st_NAND::rpTabPhyBlk, and st_NAND::sysPhySec. Referenced by NAND__wrSysInfo(). 01953 {
01954 unsigned short buf[256];
01955 unsigned short ii;
01956 unsigned long phySec;
01957
01958 // Rebuild and write the system data block.
01959 for(ii= 0; ii<pNand->pageSz; ii++) buf[ii] = 0xFFFF;
01960
01961 // Signature.
01962 buf[0] = NAND_MANUFACTURE_ID;
01963
01964 // Format control flag.
01965 buf[1] = 0xFF00 | pNand->fmtCtrl;
01966
01967 buf[2] = pNand->pageSz;
01968 buf[3] = pNand->pagePerBlk;
01969
01970 // Data block num.
01971 buf[4] = pNand->dataBlkNum[pNand->actvChip];
01972
01973 // Maximum replacement block num.
01974 buf[64] = pNand->curRpBlkNum;
01975
01976 // Replacement table physical block.
01977 buf[65] = pNand->rpTabPhyBlk[pNand->actvChip];
01978
01979 buf[66] = pNand->mapTabPhySecOffset[pNand->actvChip];
01980
01981 // Update block map table index.
01982 buf[67] = pNand->rpTabBackPhyBlk[pNand->actvChip];
01983
01984 buf[255] = NAND_SIGNATURE;
01985
01986 // Erase the sysinfo block.
01987 if(NAND__eraseBlock(pNand->sysPhySec[pNand->actvChip] >> 6 ))
01988 {
01989 if(NAND__writeSec(pNand->sysPhySec[pNand->actvChip], buf, FALSE))
01990 {
01991 ii = 0;
01992 //ensure thr downdate of new nand driver
01993 phySec = pNand->sysPhySec[pNand->actvChip] + 1;//
01994 if(NAND__writeRdnt(phySec,&ii,NAND_BLOCK_STATUS_BYTE,1))
01995 {
01996 phySec += 1;
01997 if(NAND__writeRdnt(phySec,&ii,NAND_BLOCK_STATUS_BYTE,1))
01998 return TRUE;
01999 }
02000 }
02001 }
02002
02003 return FALSE;
02004 }
|
Here is the call graph for this function:

|
|
Function checks NAND flash ID and set up chip parameters.
Definition at line 100 of file nand.c. References st_NAND::blkSz, NAND_WAIT4READY, st_NAND::pagePerBlk, st_NAND::pageRednt, st_NAND::pageSz, and st_NAND::totalBlkNum. Referenced by NAND__formatChip(), and NAND__mount(). 00101 {
00102 unsigned short temp0;
00103
00104 NAND_WAIT4READY(temp0);
00105
00106 // Assert CLE: write to the port will set CLE to HIGH
00107 CPLD_CLE = 0;
00108
00109 // NAND chip 0, write to the port will enable CE0
00110 CPLD_CE0 = 0;
00111
00112 // send 'Read ID (1)' command
00113 CPLD_RDWR = NAND_CMD__ID_READ1;
00114
00115 // Deassert CLE: read from the port will reset CLE to LOW
00116 temp0 = CPLD_CLE;
00117
00118 // Assert ALE, TBD by cpld code
00119 CPLD_ALE = 0;
00120
00121 // send address to NAND chip
00122 CPLD_RDWR = 0;
00123 CPLD_RDWR = 0;
00124 CPLD_RDWR = 0;
00125 CPLD_RDWR = 0;
00126
00127 // Deassert ALE, TBD by cpld code
00128 temp0 = CPLD_ALE;
00129
00130 // Wait for Ready/#Busy signal (input on D0) goes to HIGH.
00131 NAND_WAIT4READY(temp0);
00132
00133 // Read maker code.
00134 temp0 = CPLD_RDWR & 0x00FF;
00135
00136 // Disable Sandisk Maker ID check here.
00137 //if(temp0 != MAKER_SANDISK) NAND_Die(kNandErr+978);
00138
00139 // Read device code.
00140 temp0 = CPLD_RDWR & 0x00FF;
00141
00142 // Save the nand size to help calculate various assert limits.
00143 NAND_setSize(temp0);
00144
00145 //ii = (temp0 == DEVICE_128MB)? 0 : 1;
00146 // Setup total physical block number.
00147 switch( temp0 )
00148 {
00149 case DEVICE_128MB: /* 128MB */
00150 Nand.totalBlkNum = 0x1000; break;
00151 case DEVICE_256MB: /* 256MB */
00152 Nand.totalBlkNum = 0x2000; break;
00153 default: /* 64MB */
00154 Nand.totalBlkNum = 0x800; break;
00155 }
00156
00157 // Deassert CE, read from the port will disable CE0
00158 temp0 = CPLD_CE0;
00159
00160 // Nand parameters are hard-coded here.
00161 Nand.pageSz = 0x100; // in words
00162 Nand.pageRednt = 0x08;
00163 Nand.pagePerBlk = 64;
00164 Nand.blkSz = Nand.pagePerBlk * Nand.pageSz;
00165
00166 return ( TRUE );
00167 }
|
|
||||||||||||||||||||
|
Function copies contiguous sector(s) from source block to destination block. it is the caller's responsibility to make sure the destination block is blank. It is also the caller's responsibility to make sure sector will not cross block boundary.
Definition at line 187 of file nand.c. References NAND__readSec(), NAND__writeSec(), st_NAND::pagePerBlk, and st_NAND::pRpTab. Referenced by NAND__flush(), NAND__replaceDataSec(), and NAND__swapSec(). 00191 {
00192 unsigned long srcPhySec;
00193 unsigned long dstPhySec;
00194 unsigned short dstPhyBlock;
00195 unsigned short block;
00196 unsigned short buf[256];
00197 unsigned short ii;
00198 unsigned short secnumber;
00199
00200 NAND_assert (pDstPhyBlock != NULL , NAND__COPYSEC);
00201 NAND_assert (srcPhyBlock < NAND_BLOCK_CNT , NAND__COPYSEC2);
00202 NAND_assert (secOffset <= NAND_SEC_PER_BLOCK , NAND__COPYSEC3);
00203 NAND_assert (secNum <= NAND_SEC_PER_BLOCK , NAND__COPYSEC4);
00204
00205 // We don't want to cross block boundaries during the copy.
00206 NAND_assert (secOffset+secNum <= NAND_SEC_PER_BLOCK , NAND__COPYSEC5);
00207
00208 dstPhyBlock = *pDstPhyBlock;
00209
00210 //optimization
00211 secnumber = secNum;
00212
00213 #ifdef HARD_CODED_OPTIMIZATION
00214 srcPhySec = ((unsigned long)srcPhyBlock << 6) + secOffset;
00215 dstPhySec = ((unsigned long)dstPhyBlock << 6) + secOffset;
00216 #else
00217 srcPhySec = (unsigned long)srcPhyBlock * Nand.pagePerBlk + secOffset;
00218 dstPhySec = (unsigned long)dstPhyBlock * Nand.pagePerBlk + secOffset;
00219 #endif
00220
00221 while(1)
00222 {
00223 for( ii = 0; ii < secnumber; ii++ )
00224 {
00225 if(NAND__readSec((long)(srcPhySec+ii), buf, FALSE) == FALSE)
00226 {
00227 // Unable to read source, report error. It will be
00228 // the caller's responsibility to erase the destination
00229 // if necessary. For example, in replace and swap
00230 // case we need to erase the destination to maintain
00231 // a free replacement block list all the time, while
00232 // we do not want to erase destination if flushing data
00233 // block is in process.
00234 //NAND__markInvalidBlock(srcPhyBlock);
00235 *pDstPhyBlock = dstPhyBlock;
00236 return CPYERR_READ;
00237 }
00238
00239 if(NAND__writeSec(dstPhySec+ii, buf, FALSE) == FALSE )
00240 {
00241 // Unable to write destination, try to replace it
00242 // before reporting error.
00243 break;
00244 }
00245 }
00246
00247 //if(ii == secNum)
00248 if(ii == secnumber)
00249 {
00250 // Done with the copy, update destination block pointer.
00251 *pDstPhyBlock = dstPhyBlock;
00252 break;
00253 }
00254
00255 else
00256 {
00257 block = dstPhyBlock;
00258
00259 // linda: in this place, i should record sth to be in case of forget the algorithm
00260 // the copysec is to do data copy and keep the status before the function was called
00261 // OK, two function will call this function,they are swap and flush.
00262 // the difference between them is where the dest_block logined.
00263 // if everything is OK,this structure will not executed
00264 // but if sth goes wrong.
00265
00266 // swap: when this function was called ,the desti doesnot be swaped,that means it
00267 // logined in replacement table.so (block == dstPhyBlock) will goes TRUE,so do notify
00268 // this block goes bad,do NAND__wrRpHis(0xFFFE,FALSE),then get the first valid block,
00269 // and every loop,you'll find this justify will go same.so when the function is over,
00270 // the status is the desti-block is in the replacenment table and in the first place.
00271
00272 // flush: when this function was called, the desti was swapped already, that means it
00273 // logined in the map table,so the (block == dstPhyBlock) will goes FALSE,so do notify
00274 // this block(donot logined in rep table)does bad,do NAND__wrRpHis(block,FALSE), and
00275 // that func will do sth to deal with this block and think that the first valid block
00276 // is taken out by the caller,so it do find the other valid block and put it in the
00277 // first place ( attention this block does not equal to dstPhyBlock. so we can get
00278 // the conclusion, that from the beginning to the end, dstPhyBlock does not belongs
00279 // to the replacement table, OK, whatever the caller will do does not have sth to do
00280 // with the replacement table
00281
00282 // so we get the point: the status does not change
00283 GEN_rdSRAM(Nand.pRpTab,&dstPhyBlock,1);
00284 if(block == dstPhyBlock)
00285 {
00286 if(!NAND__wrRpHis(0xFFFE,FALSE)) return CPYERR_WRITE;
00287
00288 GEN_rdSRAM(Nand.pRpTab,&dstPhyBlock,1);
00289 }
00290 else
00291 if(!NAND__wrRpHis(block,FALSE)) return CPYERR_WRITE;
00292
00293 // Recover the dst block flushed sectors if there is any.
00294 // Data shall be read directly from the source block.
00295
00296 #ifdef HARD_CODED_OPTIMIZATION
00297 srcPhySec = (unsigned long)srcPhyBlock << 6;
00298 dstPhySec = (unsigned long)dstPhyBlock << 6;
00299 #else
00300 srcPhySec = (unsigned long)srcPhyBlock * Nand.pagePerBlk;
00301 dstPhySec = (unsigned long)dstPhyBlock * Nand.pagePerBlk;
00302 #endif
00303
00304 secnumber = secNum + secOffset;
00305 }
00306 }
00307
00308 return ( CPYERR_NONE );
00309 }
|
Here is the call graph for this function:

|
|
Function erases specified physical block.
Definition at line 320 of file nand.c. References NAND_WAIT4READY. Referenced by NAND__buildSysInfo(), NAND__formatChip(), NAND__markInvalidBlock(), NAND__replaceDataSec(), NAND__swapSec(), NAND__wrSysInfo(), NAND_flush(), NAND_mount(), NAND_revive(), and NAND_unmount(). 00321 {
00322 unsigned long columnAddr;
00323 unsigned short temp;
00324 unsigned char addr_9_16;
00325 unsigned char addr_17_24;
00326 unsigned char addr_25_27;
00327
00328 NAND_assert(phyBlock < NAND_BLOCK_CNT, NAND__ERASEBLOCK);
00329
00330 NAND_WAIT4READY(temp);
00331
00332 // remove write protection
00333 //CPLD_nWP = 0;
00334
00335 // Assert CLE: write to the port will set CLE to HIGH
00336 CPLD_CLE = 0;
00337
00338 // NAND chip 0, write to the port will enable CE0
00339 CPLD_CE0 = 0;
00340
00341 // Form the column address on whole blocks
00342 columnAddr = (unsigned long)phyBlock << 15;
00343
00344 // Parse the column address
00345 addr_9_16 = (unsigned char)((columnAddr >> 9) & 0xFF);
00346 addr_17_24 = (unsigned char)((columnAddr >> 17) & 0xFF);
00347 addr_25_27 = (unsigned char)((columnAddr >> 25) & 0x07);
00348
00349 // send 1st byte of 'Auto Block Erase' command
00350 CPLD_RDWR = NAND_CMD__AUTO_BLOCK_ERASE1;
00351
00352 // Deassert CLE: read from the port will reset CLE to LOW
00353 temp = CPLD_CLE;
00354
00355 // Assert ALE, TBD by cpld code
00356 CPLD_ALE = 0;
00357
00358 // send address to NAND chip
00359 CPLD_RDWR = addr_9_16;
00360 CPLD_RDWR = addr_17_24;
00361 CPLD_RDWR = addr_25_27;
00362
00363 // Deassert ALE, TBD by cpld code
00364 temp = CPLD_ALE;
00365
00366 // Assert CLE: write to the port will set CLE to HIGH
00367 CPLD_CLE = 0;
00368
00369 // send 2nd byte of 'Auto Block Erase' command
00370 CPLD_RDWR = NAND_CMD__AUTO_BLOCK_ERASE2;
00371
00372 // Deassert CLE: read from the port will reset CLE to LOW
00373 temp = CPLD_CLE;
00374
00375 // Wait for Ready/#Busy signal (input on D0) goes to HIGH.
00376 NAND_WAIT4READY(temp);
00377
00378 // Assert CLE: write to the port will set CLE to HIGH
00379 CPLD_CLE = 0;
00380
00381 // send 'Status Read (1)' command
00382 CPLD_RDWR = NAND_CMD__STATUS_READ1;
00383
00384 // Deassert CLE: read from the port will reset CLE to LOW
00385 temp = CPLD_CLE;
00386
00387 // Restore write protection
00388 //temp = CPLD_nWP;
00389
00390 // Read status data
00391 temp = CPLD_RDWR;
00392
00393 // Deassert CE, read from the port will disable CE0
00394 addr_9_16 = CPLD_CE0;
00395
00396 if ( (temp & 0x0001 ) == 0 )
00397 {
00398 /* Erase pass. */
00399 return (TRUE);
00400 }
00401 else
00402 {
00403 /* Erase fail. */
00404 return (FALSE);
00405 }
00406 }
|
|
|
Function flushes flash data area if any pending block exists.
Definition at line 416 of file nand.c. References st_NAND::actvBlk, st_NAND::actvBlkEndSec, st_NAND::actvPhyBlk, st_NAND::actvRpPhyBlk, st_NAND::actvSec, st_NAND::actvSecOffset, st_NAND::flag, NAND__copySec(), NAND_COPYERR, st_NAND::pagePerBlk, st_NAND::pMapTab, and st_NAND::writingSec. Referenced by NAND__wrSec(), NAND_flush(), and NAND_unmount(). 00417 {
00418 NAND_COPYERR err;
00419 unsigned short endsect;
00420
00421 if(TRUE == bPARTIAL)
00422 endsect = Nand.writingSec - Nand.actvSec;
00423 else
00424 endsect = Nand.pagePerBlk - Nand.actvSecOffset;
00425
00426 err = NAND__copySec( Nand.actvRpPhyBlk,
00427 &Nand.actvPhyBlk,
00428 (unsigned short)(Nand.actvSecOffset + 1),
00429 (unsigned short)(endsect - 1) );
00430
00431 if(err == CPYERR_NONE )
00432 {
00433 GEN_wrSRAM((long)Nand.pMapTab + Nand.actvBlk,&Nand.actvPhyBlk,1);
00434 if(!bPARTIAL)
00435 {
00436 Nand.actvBlkEndSec = NAND_INVALID_SEC;
00437 Nand.actvSec = NAND_INVALID_SEC;
00438 Nand.flag &= ~NAND_FLUSH_DATA_BLOCK_PENDING;
00439 }
00440 return TRUE;
00441 }
00442
00443 if( err == CPYERR_WRITE )
00444 {
00445 GEN_wrSRAM(Nand.pMapTab + Nand.actvBlk, &Nand.actvRpPhyBlk, 1);
00446 // in case of the inside danger,now there exist two copy of
00447 // actvrpphyblk in the replace and map table
00448
00449 Nand.flag &= ~NAND_FLUSH_DATA_BLOCK_PENDING;
00450 }
00451
00452 else if( err == CPYERR_READ )
00453 {
00454 GEN_wrSRAM((long)Nand.pMapTab + Nand.actvBlk,&Nand.actvPhyBlk,1);
00455
00456 NAND__wrRpHis(Nand.actvRpPhyBlk,FALSE);
00457
00458 Nand.flag |= NAND_FLUSH_REPLACE_TAB_PENDING;
00459 }
00460
00461 return FALSE;
00462 }
|
Here is the call graph for this function:

|
|
Function erases block and writes specified data back. This function is ONLY called to flush the block map table and the replacement map table.
Definition at line 1890 of file nand.c. References st_NAND::actvChip, st_NAND::dataBlkNum, st_NAND::flag, st_NAND::mapTabPhySecOffset, st_NAND::maxRpBlkNum, NAND__write(), NAND__writeRdnt(), st_NAND::pagePerBlk, st_NAND::pMapTab, and st_NAND::pRpTab. Referenced by NAND__wrSysInfo(). 01891 {
01892 unsigned long sec;
01893 unsigned short tmp;
01894
01895 NAND_assert (*pPhyBlock < NAND_BLOCK_CNT, NAND__FLUSHBLOCK);
01896
01897 while(1)
01898 {
01899 tmp = *pPhyBlock;
01900
01901 #ifdef HARD_CODED_OPTIMIZATION
01902 sec = (long)tmp << 6;
01903 #else
01904 sec = (long)tmp*Nand.pagePerBlk;
01905 #endif
01906
01907 /* but i think we need it
01908 NAND__readRdnt((sec + Nand.pagePerBlk - 3),&tmp,NAND_BLOCK_STATUS_BYTE,1);
01909 if(tmp != 0xFF)
01910 NAND__eraseBlock(tmp);*/
01911
01912
01913 //write into replacement table information
01914 if( NAND__write(sec, Nand.pRpTab, Nand.maxRpBlkNum[Nand.actvChip]))
01915 {
01916 if(NAND__write(sec + Nand.mapTabPhySecOffset[0],
01917 Nand.pMapTab,Nand.dataBlkNum[Nand.actvChip]))
01918 {
01919 // confusion: the rdnt of the last third sector show this block is valid replace block
01920 sec = sec + Nand.pagePerBlk - 3;
01921 tmp = 0;
01922 NAND__writeRdnt(sec,&tmp,NAND_BLOCK_STATUS_BYTE,1);
01923
01924 return TRUE;
01925 }
01926 }
01927
01928 //attention!!!!!!!!!!!!!!!!!
01929 if(Nand.flag & NAND_READ_ONLY) return FALSE;
01930
01931 GEN_rdSRAM(Nand.pRpTab, pPhyBlock, 1);
01932
01933 NAND__wrRpHis(tmp,FALSE);
01934
01935 Nand.flag |= NAND_SYSINFO_CHANGE;
01936 }
01937 }
|
Here is the call graph for this function:

|
|
Function formats NAND flash and returns number of read/writable data blocks. Function will do low level format of the volume and rebuild the system data in the following format, starting from first valid page. (a page is valid only when it sits in a valid block. )
Definition at line 2179 of file nand.c. References GEN_free(), GEN_malloc(), NAND__checkID(), NAND__eraseBlock(), NAND__isBlockValid(), NAND__write(), NAND__writeRdnt(), NAND__writeSec(), NAND_revive(), st_NAND::pagePerBlk, st_NAND::pageSz, and st_NAND::totalBlkNum. Referenced by NAND_format(). 02180 {
02181 // Format retry counter to recursively handle format error.
02182 static short retry = 0;
02183
02184 unsigned short secoffset;
02185 unsigned short tmp;
02186 unsigned short ii;
02187 unsigned short phyBlock;
02188 unsigned short logBlock;
02189 unsigned short maxReplaceBlockNum;
02190 unsigned short dataBlockNum;
02191 unsigned short * pBuf;
02192
02193 unsigned long pMapTab;
02194 unsigned long pTab;
02195 unsigned long phySec;
02196 BOOL status;
02197
02198 // Remove write protection.
02199 CPLD_nWP = 0;
02200
02201 // Check ID to get physical parameters.
02202 if( NAND__checkID() == FALSE ) return 0L;
02203
02204 // Allocate map table buffer and initialize it to all 0xFFFFs,
02205 if( (pMapTab = GEN_malloc(Nand.totalBlkNum) ) == 0L ) return 0L;
02206
02207 else
02208 {
02209 // Initialize block map table.
02210
02211 // Let's speed this up if memory is available.
02212 pBuf = (unsigned short *)malloc(Nand.totalBlkNum*sizeof(unsigned short));
02213 if(pBuf)
02214 {
02215 for(ii=0; ii<Nand.totalBlkNum; ii++) pBuf[ii] = 0xFFFF;
02216 GEN_wrSRAM(pMapTab, pBuf, Nand.totalBlkNum);
02217 free(pBuf);
02218 }
02219
02220 else
02221 {
02222 tmp = 0xFFFF;
02223 for(ii=0; ii<Nand.totalBlkNum; ii++) GEN_wrSRAM(pMapTab + ii, &tmp, 1);
02224 }
02225 }
02226
02227
02228 // Check to build the entire block map table for all valid blocks if any.
02229 phyBlock = startPhyBlock;
02230
02231 logBlock = 0;
02232
02233 while(1)
02234 {
02235 if( NAND__isBlockValid(phyBlock) )
02236 {
02237 if( NAND__eraseBlock(phyBlock) )
02238 {
02239 GEN_wrSRAM(pMapTab + logBlock++, &phyBlock, 1);
02240 }
02241
02242 else
02243 {
02244 // Mark this block to be bad.
02245 #ifdef HARD_CODED_OPTIMIZATION
02246 phySec = ((unsigned long)phyBlock << 6) + 63;
02247 #else
02248 phySec = ((unsigned long)Nand.pagePerBlk * phyBlock) + Nand.pagePerBlk - 1;
02249 #endif
02250
02251 ii = NAND_BLOCK_STATUS_BAD;
02252
02253 NAND__writeRdnt(phySec, &ii, NAND_BLOCK_STATUS_BYTE, 1);
02254 }
02255 }
02256
02257 if(++phyBlock >= (startPhyBlock + Nand.totalBlkNum) ) break;
02258
02259 }
02260
02261 // If less than (256)??? blocks left, flash is considered
02262 // permanently damaged or worn out.
02263 // We'll try to revive it anyway, knowing that this revival
02264 // will bring the NAND to an unstable state by loosing all
02265 // block information. But it is better than leaving the player dead.
02266 if( logBlock < 256 )
02267 {
02268 GEN_free(pMapTab);
02269 NAND_revive(Nand.totalBlkNum);
02270 return (NAND__formatChip(startPhyBlock));
02271 }
02272
02273 // Allocate sector buffer and initialize to all 0xFFFFs.
02274 if ( (pBuf = (unsigned short *)
02275 malloc(Nand.pageSz * sizeof(unsigned short)) )
02276 == NULL )
02277 {
02278 GEN_free(pMapTab);
02279 return 0L;
02280 }
02281
02282 else
02283 {
02284 // Initialize buffer to all empty.
02285 for(ii= 0; ii<Nand.pageSz; ii++) *pBuf++ = 0xFFFF;
02286 pBuf -= Nand.pageSz;
02287 }
02288
02289 // Rebuild and write the system data block hereafter, this
02290 // will revive the flash if there is valid blocks left.
02291
02292 pBuf[0] = NAND_MANUFACTURE_ID;
02293
02294 // Format control flag.
02295 pBuf[1] = 0xFF00;
02296
02297 pBuf[2] = Nand.pageSz;
02298 pBuf[3] = Nand.pagePerBlk;
02299
02300 // Reserve 3.125% (1/32) of valid blocks for replacement and
02301 // storing map table, system info etc.
02302 dataBlockNum = logBlock - (logBlock >> 5);
02303
02304 // Data block num.
02305 pBuf[4] = dataBlockNum;
02306
02307 // System info, replacement map table, and block map table
02308 // take 3 blocks.
02309 maxReplaceBlockNum = logBlock - dataBlockNum - 3;
02310
02311 // Maximum replacement block num.
02312 pBuf[64] = maxReplaceBlockNum;
02313
02314 // Replacement table physical block.
02315 GEN_rdSRAM(pMapTab + 1, &pBuf[65], 1);
02316
02317 // Block num per block map table.
02318 //pBuf[66] = blockPerMapTab;
02319
02320 //the sector offset of map table in the replacement block
02321 #ifdef HARD_CODED_OPTIMIZATION
02322 secoffset =((64 - 2)>>5) + 2;
02323 #else
02324 secoffset = ((Nand.pagePerBlk - 2)>>5) + 2;
02325 #endif
02326
02327 pBuf[66] = secoffset;
02328
02329 // backup table of data block map table.
02330 GEN_rdSRAM(pMapTab + 2, &pBuf[67], 1);
02331
02332 pBuf[255] = NAND_SIGNATURE;
02333
02334 status = TRUE;
02335 pTab = pMapTab + dataBlockNum + 3;
02336 GEN_rdSRAM(pMapTab + 1, &tmp, 1);
02337 phySec = (unsigned long)tmp*Nand.pagePerBlk;
02338
02339 if(status &= NAND__write(phySec, pTab, maxReplaceBlockNum))
02340 {
02341 pTab = pMapTab + 3;
02342 phySec = phySec + secoffset;
02343
02344 if(status &= NAND__write(phySec, pTab, dataBlockNum))
02345 {
02346 phySec = (unsigned long)tmp*Nand.pagePerBlk + Nand.pagePerBlk - 3;//2
02347 tmp = 0;
02348 NAND__writeRdnt(phySec,&tmp,NAND_BLOCK_STATUS_BYTE,1);
02349
02350 GEN_rdSRAM(pMapTab, &tmp, 1);
02351 phySec = (unsigned long)tmp*Nand.pagePerBlk;
02352
02353 if( status &= NAND__writeSec(phySec, pBuf, FALSE))
02354 {
02355 tmp = 0;
02356 phySec = phySec + 1;//1
02357 NAND__writeRdnt(phySec,&tmp,NAND_BLOCK_STATUS_BYTE,1);
02358
02359 phySec += 1;//1
02360 NAND__writeRdnt(phySec,&tmp,NAND_BLOCK_STATUS_BYTE,1);
02361 }
02362 }
02363 }
02364
02365 if(!status)
02366 {
02367 GEN_free(pMapTab);
02368 free(pBuf);
02369
02370 if(++retry < FORMAT_RETRY )
02371 return NAND__formatChip(startPhyBlock);
02372
02373 else return 0;
02374 }
02375
02376 // End of chip formatting, reset retry counter.
02377 retry = 0;
02378 GEN_free(pMapTab);
02379 free(pBuf);
02380
02381 // return available data blocks.
02382 return( dataBlockNum );
02383 }
|
Here is the call graph for this function:

|
|
Function checks to manage the data sector history to yield to operating system while NAND interface is busy.
Definition at line 474 of file nand.c. References st_NAND::flag, NAND__readDataSec(), NAND__replaceDataSec(), NAND__writeSec(), NAND_WAIT4READY, st_SECT_HISTORY::phySec, st_SECT_HISTORY::secBuf, sectHistory, and st_SECT_HISTORY::swap. Referenced by NAND__rdSec(), NAND__wrSec(), NAND_flush(), and NAND_unmount(). 00475 {
00476 BOOL ret = TRUE;
00477 unsigned long phySec;
00478
00479 if(Nand.flag & NAND_HISTORY_AVAILABLE)
00480 {
00481 // Check to see if there was any error.
00482 #ifdef NAND_PWR_SUPPORT
00483 ret = NAND__readDataSec(sectHistory.phySec,
00484 sectHistory.secBuf,
00485 sectHistory.swap);
00486
00487 #else
00488 NAND_WAIT4READY(temp);
00489
00490 // NAND chip 0, write to the port will enable CE0
00491 CPLD_CE0 = 0;
00492
00493 CPLD_CLE = 0;
00494
00495 // send 'Status Read (1)' command
00496 CPLD_RDWR = NAND_CMD__STATUS_READ1;
00497
00498 // Deassert CLE: read from the port will reset CLE to LOW
00499 temp = CPLD_CLE;
00500
00501 // Read status data
00502 temp = CPLD_RDWR;
00503
00504 // Deassert CE, read from the port will disable CE0
00505 ret = CPLD_CE0;
00506
00507 ret = ( (temp & 0x0001 ) == 0 )? TRUE: FALSE;
00508 #endif
00509 }
00510
00511 if( ret == FALSE )
00512 {
00513 // Error detected, let's replace it.
00514 phySec = sectHistory.phySec;
00515 ret = TRUE;
00516 do
00517 {
00518 if( NAND__replaceDataSec(&phySec) == FALSE)
00519 {
00520 ret = FALSE;
00521 break;
00522 }
00523 } while(NAND__writeSec( phySec,
00524 sectHistory.secBuf,
00525 sectHistory.swap) == FALSE );
00526 }
00527
00528 Nand.flag &= ~NAND_HISTORY_AVAILABLE;
00529 return ret;
00530 }
|
Here is the call graph for this function:

|
||||||||||||
|
Function records a new history sector.
Definition at line 542 of file nand.c. References st_NAND::actvBlk, st_NAND::actvPhyBlk, st_NAND::actvPhySec, st_NAND::actvSecOffset, st_NAND::flag, st_SECT_HISTORY::logBlk, st_SECT_HISTORY::phyBlk, st_SECT_HISTORY::phySec, st_SECT_HISTORY::secBuf, st_SECT_HISTORY::secOffset, sectHistory, and st_SECT_HISTORY::swap. Referenced by NAND__wrSec(). 00543 {
00544 unsigned short ii;
00545 unsigned short * pSrc;
00546 unsigned short * pDst;
00547
00548 NAND_assert (pBuf != NULL, NAND__HISTORYSET);
00549
00550 pSrc = pBuf;
00551 pDst = sectHistory.secBuf;
00552 for(ii = 0; ii<256; ii++) *pDst++ = *pSrc++;
00553
00554 sectHistory.phyBlk = Nand.actvPhyBlk;
00555 sectHistory.phySec = Nand.actvPhySec;
00556 sectHistory.secOffset = Nand.actvSecOffset;
00557 sectHistory.logBlk = Nand.actvBlk;
00558 sectHistory.swap = swap;
00559
00560 Nand.flag |= NAND_HISTORY_AVAILABLE;
00561 }
|
|
|
Function checks if specified physical block is in good status. @ param phyBlock physical block number. @ return TRUE if block is in good status, otherwise FALSE. Definition at line 3275 of file nand.c. References NAND__readRdnt(), and st_NAND::pagePerBlk. Referenced by NAND__mount(). 03276 {
03277 unsigned long phySec;
03278 unsigned short byte;
03279
03280 NAND_assert(phyBlock < NAND_BLOCK_CNT, NAND__ISBLOCKGOOD);
03281
03282 #ifdef HARD_CODED_OPTIMIZATION
03283 phySec = ((long)phyBlock<<6) + 63;
03284 #else
03285 phySec = ((long)Nand.pagePerBlk * phyBlock) + Nand.pagePerBlk - 1;
03286 #endif
03287
03288 NAND__readRdnt( phySec, &byte, NAND_BLOCK_STATUS_BYTE, 1 );
03289
03290 if( byte == NAND_BLOCK_STATUS_GOOD ) return TRUE;
03291
03292 else return FALSE;
03293 }
|
Here is the call graph for this function:

|
|
Function checks if specified physical block is valid. A block is considered valid if it is good or problematic. A block will be marked invalid when an error is detected on a problematic one. @ param phyBlock physical block number. @ return TRUE if block is valid, otherwise FALSE. Definition at line 3244 of file nand.c. References NAND__readRdnt(), and st_NAND::pagePerBlk. Referenced by NAND__formatChip(), and NAND_mount(). 03245 {
03246
03247 unsigned long phySec;
03248 unsigned short byte;
03249
03250 NAND_assert(phyBlock < NAND_BLOCK_CNT, NAND__ISBLOCKVALID);
03251
03252 #ifdef HARD_CODED_OPTIMIZATION
03253 phySec = ((long)phyBlock<<6) + 63;
03254 #else
03255 phySec = ((long)Nand.pagePerBlk * phyBlock) + Nand.pagePerBlk - 1;
03256 #endif
03257
03258 NAND__readRdnt( phySec, &byte, NAND_BLOCK_STATUS_BYTE, 1 );
03259
03260 if(byte >= NAND_BLOCK_STATUS_PROBLEMATIC) return TRUE;
03261
03262 else return FALSE;
03263 }
|
Here is the call graph for this function:

|
||||||||||||||||
|
Function loads the specified map table and returs of length of the table in words. It is the caller's responsibility to make sure that read will NOT cross block boundary.
Definition at line 2727 of file nand.c. References NAND__readSec(), and st_NAND::pageSz. Referenced by NAND_mount(). 02730 {
02731 unsigned short count;
02732 unsigned short ii;
02733 unsigned short buf[256];
02734 unsigned short temp;
02735
02736 ii = 0;
02737 count = maxLen;
02738 while(count)
02739 {
02740 if(NAND__readSec(physec + ii, buf, FALSE) == FALSE ) return 0;
02741
02742 if(count > Nand.pageSz)
02743 temp = Nand.pageSz;
02744 else
02745 temp = count;
02746
02747 GEN_wrSRAM(pTab, buf, temp);
02748
02749 pTab += temp;
02750 count -= temp;
02751 ii++;
02752 }
02753
02754 while(temp--)
02755 {
02756 // if buf[temp] equal to 0xFFFF or 0xFFFE, the following will equal to zero,
02757 // else it doesnot
02758 if((~buf[temp])>>1) break;
02759 count++;
02760 }
02761
02762 return (maxLen - count);
02763 }
|
Here is the call graph for this function:

|
|
Function maps the logical sector number to physical sector number if it is available. This function call ONLY be called from NAND_readSec and NAND_writeSec. Return of this function shall set up the following NAND globals, Nand.actvSec Nand.actvSecOffset Nand.actvBlk Nand.actvPhyBlk Nand.actvPhySec
Definition at line 639 of file nand.c. References st_NAND::actvBlk, st_NAND::actvPhyBlk, st_NAND::actvPhySec, st_NAND::actvSec, st_NAND::actvSecOffset, st_NAND::pagePerBlk, and st_NAND::pMapTab. Referenced by NAND__wrSec(). 00640 {
00641 unsigned long phySec;
00642
00643 NAND_assert (logSec < NAND_SEC_CNT, NAND__LOG2PHYSEC);
00644
00645 // Record active sector.
00646 Nand.actvSec = logSec;
00647
00648 // Record active sector offset in block.
00649 #ifdef HARD_CODED_OPTIMIZATION
00650 Nand.actvSecOffset = (unsigned long)logSec & 0x003F;
00651 #else
00652 Nand.actvSecOffset = (unsigned long)logSec % Nand.pagePerBlk;
00653 #endif
00654
00655 // Record active logical block number.
00656 #ifdef HARD_CODED_OPTIMIZATION
00657 Nand.actvBlk = (unsigned long)(logSec) >> 6;
00658 #else
00659 Nand.actvBlk = (unsigned long)(logSec) / Nand.pagePerBlk;
00660 #endif
00661
00662 // Look up block map table and map logical to physical.
00663 GEN_rdSRAM(Nand.pMapTab + Nand.actvBlk, &Nand.actvPhyBlk, 1);
00664
00665 // Calculate active physical sector.
00666 Nand.actvPhySec =
00667 phySec =
00668
00669 #ifdef HARD_CODED_OPTIMIZATION
00670 ((unsigned long)Nand.actvPhyBlk << 6) + Nand.actvSecOffset;
00671 #else
00672 (unsigned long)Nand.actvPhyBlk * Nand.pagePerBlk + Nand.actvSecOffset;
00673 #endif
00674
00675 return phySec;
00676 }
|
|
|
Function marks the specified block to be invalid if it is already a problematic one, otherwise marks it to be problematic.
Definition at line 688 of file nand.c. References NAND__eraseBlock(), NAND__readRdnt(), NAND__writeRdnt(), and st_NAND::pagePerBlk. Referenced by NAND__readSec(). 00689 {
00690 unsigned long phySec;
00691 unsigned short byte;
00692 BOOL ret;
00693
00694 NAND_assert(phyBlock < NAND_BLOCK_CNT, NAND__MARKINVALIDBLOCK);
00695
00696 // Block status stores in the last sector.
00697
00698 #ifdef HARD_CODED_OPTIMIZATION
00699 phySec = ((unsigned long)phyBlock << 6) + 63;
00700 #else
00701 phySec = ((unsigned long)Nand.pagePerBlk * phyBlock) + Nand.pagePerBlk - 1;
00702 #endif
00703
00704 NAND_assert(phySec < NAND_SEC_CNT, NAND__MARKINVALIDBLOCK2);
00705
00706 // Check current block status.
00707 NAND__readRdnt(phySec, &byte, NAND_BLOCK_STATUS_BYTE, 1);
00708
00709 if( byte == NAND_BLOCK_STATUS_GOOD)
00710 {
00711 ret = FALSE;
00712 byte = NAND_BLOCK_STATUS_PROBLEMATIC;
00713 }
00714 else
00715 {
00716 ret = TRUE;
00717 byte = NAND_BLOCK_STATUS_BAD;
00718 }
00719
00720 // Erase block to prvent partial programming.
00721 NAND__eraseBlock(phyBlock);
00722
00723 // Mark block to proper state.
00724 NAND__writeRdnt(phySec, &byte, NAND_BLOCK_STATUS_BYTE, 1);
00725
00726 return ret;
00727 }
|
Here is the call graph for this function:

|
|
Function initializes NAND flash hardware and read back the system information.
Definition at line 2587 of file nand.c. References st_NAND::currentpipo, st_NAND::dataBlkNum, st_NAND::flag, st_NAND::fmtCtrl, st_NAND::mapTabPhySecOffset, st_NAND::maxRpBlkNum, NAND__checkID(), NAND__isBlockGood(), NAND__readRdnt(), NAND__readSec(), st_NAND::pagePerBlk, st_NAND::pageSz, st_NAND::rpTabBackPhyBlk, st_NAND::rpTabPhyBlk, st_NAND::sysPhySec, and st_NAND::totalBlkNum. Referenced by NAND_mount(). 02588 {
02589 unsigned short phyBlock;
02590 unsigned long phySec;
02591 unsigned short buf[256];
02592 unsigned short ii;
02593 unsigned short startPhyBlock[NAND_CHIP_NUM];
02594
02595 Nand.flag = 0;
02596
02597 // remove write protection, make the entire chip writable.
02598 CPLD_nWP = 0;
02599
02600 if( NAND__checkID() == FALSE ) return FALSE;
02601
02602 // Physical block addresses of multiple chips might not
02603 // be contiguous.
02604 NAND__hwBlockMap(startPhyBlock);
02605
02606 phyBlock = startPhyBlock[chip];
02607
02608 // Search for the first valid block, which should
02609 // contain system info sector.
02610 while(NAND__isBlockGood(phyBlock) == FALSE)
02611 {
02612 // No valid block available, volume damaged or unformatted.
02613 if(++phyBlock > (Nand.totalBlkNum + startPhyBlock[chip]) )
02614 return FALSE;
02615 }
02616
02617 #ifdef HARD_CODED_OPTIMIZATION
02618 Nand.sysPhySec[chip] = (unsigned long)phyBlock<<6;
02619 #else
02620 Nand.sysPhySec[chip] = phyBlock*Nand.pagePerBlk;
02621 #endif
02622
02623 NAND__readRdnt(Nand.sysPhySec[chip] + 2,&ii,NAND_BLOCK_STATUS_BYTE,1);
02624 if(ii != 0x00) return FALSE;
02625
02626 // Read back system info sector.
02627 if(NAND__readSec(Nand.sysPhySec[chip], buf, FALSE) == FALSE)
02628 {
02629 /* Fatal error!, system area is unreadable. */
02630 return FALSE;
02631 }
02632
02633
02634 // Check manufacture ID and disk signature.
02635 if( (buf[0] != NAND_MANUFACTURE_ID) ||
02636 (buf[255] != NAND_SIGNATURE) ) return FALSE;
02637
02638 // Check if format control flag has been set.
02639 if( (Nand.fmtCtrl = buf[1] & 0x00FF) != 0)
02640 {
02641 // Format flag has been set, there is no replacement
02642 // block left, entire flash will be read only.
02643 Nand.flag |= NAND_READ_ONLY;
02644 }
02645
02646 Nand.pageSz = buf[2];
02647
02648 // Page size other than 0x100 words is not supported.
02649 if(Nand.pageSz != 0x100) return FALSE;
02650
02651 Nand.pagePerBlk = buf[3];
02652
02653 Nand.dataBlkNum[chip] = buf[4];
02654
02655 Nand.maxRpBlkNum[chip] = buf[64];
02656
02657 Nand.rpTabPhyBlk[chip] = buf[65];
02658
02659 Nand.mapTabPhySecOffset[chip] = buf[66];
02660
02661 // Read the map table of data block map table.
02662 Nand.rpTabBackPhyBlk[chip] = buf[67];
02663
02664 #ifdef HARD_CODED_OPTIMIZATION
02665 //phySec = ((unsigned long)(Nand.rpTabPhyBlk[chip]))<<6;
02666 phySec = ((unsigned long)buf[65])<<6;
02667 #else
02668 //phySec = ((unsigned long)(Nand.rpTabPhyBlk[chip]))*((unsigned long)Nand.pagePerBlk);
02669 phySec = ((unsigned long)buf[65])*((unsigned long)Nand.pagePerBlk);
02670 #endif
02671
02672 NAND__readRdnt(phySec + Nand.pagePerBlk - 3, &ii, NAND_BLOCK_STATUS_BYTE, 1);
02673
02674 Nand.currentpipo[chip] = (ii != 0xFF);
02675 if(!(Nand.currentpipo[chip]))
02676 // too complicate, unreadable
02677 //if(!(Nand.currentpipo[chip] = (ii != 0xFF)))
02678 {
02679 #ifdef HARD_CODED_OPTIMIZATION
02680 //phySec = ((unsigned long)(Nand.rpTabBackPhyBlk[chip]))<<6;
02681 phySec = ((unsigned long)buf[67])<<6;
02682 #else
02683 //phySec = ((unsigned long)(Nand.rpTabBackPhyBlk[chip]))*((unsigned long)Nand.pagePerBlk);
02684 phySec = ((unsigned long)buf[67])*((unsigned long)Nand.pagePerBlk);
02685 #endif
02686
02687 }
02688 phySec = phySec + Nand.pagePerBlk - 2;
02689
02690 /*if(ii != 0xFF)
02691 Nand.currentpipo[chip] = TRUE;
02692 else
02693 Nand.currentpipo[chip] = FALSE;
02694 */
02695
02696 // Read back FlushFlag.
02697 //phySec = Nand.sysPhySec[chip] + Nand.pagePerBlk - 2;
02698 NAND__readRdnt(Nand.sysPhySec[chip] + Nand.pagePerBlk - 2, &ii, NAND_BLOCK_STATUS_BYTE, 1);
02699
02700 if(ii != 0xFF)
02701 {
02702 NAND__readRdnt(phySec, &ii, NAND_BLOCK_STATUS_BYTE, 1);
02703 if(ii != 0xFF)
02704 Nand.flag |= NAND_ERASEALL_NEED;
02705 else
02706 Nand.flag |= NAND_ERASE_NEED;
02707 }
02708
02709 return (TRUE);
02710 }
|
Here is the call graph for this function:

|
||||||||||||||||
|
Function reads back the specified logical sector, specified by the FAT file system layer.
Definition at line 2807 of file nand.c. References st_NAND::actvBlkEndSec, st_NAND::actvPhyBlk, st_NAND::actvRpPhyBlk, st_NAND::flag, NAND__historyCheck(), NAND__readSec(), st_NAND::pagePerBlk, st_NAND::pMapTab, and st_NAND::writingSec. Referenced by NAND_readSec(). 02808 {
02809 unsigned long phySec;
02810 USHORT phyBlk;
02811 BOOL ret = FALSE;
02812
02813 if( TRUE == NAND__historyCheck() )
02814 {
02815 // Always flush if flag is set before any reading.
02816 if(Nand.flag & NAND_FLUSH_DATA_BLOCK_PENDING)
02817 {
02818 // Shall NOT flush if sector is still in current block range.
02819 // directly read from the replaced block or current writing
02820 // block.
02821 if( ((unsigned long)sec >= (unsigned long)(Nand.actvBlkEndSec - 64)) &&
02822 ((unsigned long)sec < (unsigned long)Nand.actvBlkEndSec) )
02823 {
02824
02825 if( sec > Nand.writingSec )
02826 // Read from replaced block.
02827 phyBlk = Nand.actvRpPhyBlk;
02828 else
02829 phyBlk = Nand.actvPhyBlk;
02830
02831 // Read from current block.
02832 #ifdef HARD_CODED_OPTIMIZATION
02833 phySec = ((unsigned long)phyBlk<<6) + ((unsigned long)sec & 0x003F);
02834 #else
02835 phySec = (unsigned long)phyBlk * Nand.pagePerBlk + (unsigned long)sec % Nand.pagePerBlk;
02836 #endif
02837
02838 // Report any error directly to upper file system layer.
02839 ret = NAND__readSec(phySec, pBuf, swap);
02840
02841 return ret;
02842 }
02843 }
02844
02845 // Look up block map table and map logical to physical.
02846 GEN_rdSRAM(Nand.pMapTab + ((unsigned long)sec>>6), &phyBlk, 1);
02847
02848 // Calculate active physical sector.
02849 phySec = ((unsigned long)phyBlk << 6) + ((unsigned long)sec & 0x003F);
02850
02851 // Report any error directly to upper file system layer.
02852 ret = NAND__readSec(phySec, pBuf, swap);
02853 }
02854
02855 return ret;
02856 }
|
Here is the call graph for this function:

|
||||||||||||||||
|
Function reads back to verify the specified data page/sector.
Definition at line 1076 of file nand.c. References NAND_WAIT4READY. Referenced by NAND__historyCheck(), and NAND__writeSec(). 01077 {
01078
01079 unsigned short ii;
01080 unsigned long columnAddr;
01081
01082 unsigned short temp0, temp1, value;
01083 unsigned char addr_0_7;
01084 unsigned char addr_9_16;
01085 unsigned char addr_17_24;
01086 unsigned char addr_25_27;
01087 BOOL ret;
01088
01089 NAND_assert (phySec < NAND_SEC_CNT, NAND__READDATASEC);
01090 NAND_assert (pBuf != NULL, NAND__READDATASEC2);
01091
01092 NAND_WAIT4READY(temp0);
01093
01094 // Assert CLE: write to the port will set CLE to HIGH
01095 CPLD_CLE = 0;
01096
01097 // NAND chip 0, write to the port will enable CE0
01098 CPLD_CE0 = 0;
01099
01100 // Form the column address on whole pages
01101 columnAddr = (unsigned long) (phySec << 9);
01102
01103 // Parse the column address
01104 //addr_0_7 = (unsigned char)(columnAddr) & 0xFF;
01105 addr_0_7 = 0;
01106 addr_9_16 = (unsigned char)((unsigned long)columnAddr >> 9) & 0xFF;
01107 addr_17_24 = (unsigned char)((unsigned long)columnAddr >> 17) & 0xFF;
01108 addr_25_27 = (unsigned char)((unsigned long)columnAddr >> 25) & 0x7;
01109
01110 // send 'Read Mode (1)' command
01111 CPLD_RDWR = NAND_CMD__READ1;
01112
01113 // Deassert CLE: read from the port will reset CLE to LOW
01114 temp0 = CPLD_CLE;
01115
01116 // Assert ALE, TBD by cpld code
01117 CPLD_ALE = 0;
01118
01119 // send address to NAND chip
01120 CPLD_RDWR = addr_0_7;
01121 CPLD_RDWR = addr_9_16;
01122 CPLD_RDWR = addr_17_24;
01123 CPLD_RDWR = addr_25_27;
01124
01125 // Deassert ALE, TBD by cpld code
01126 temp0 = CPLD_ALE;
01127
01128 ret = TRUE;
01129 // Wait for Ready/#Busy signal (input on D0) goes to HIGH.
01130 NAND_WAIT4READY(temp0);
01131
01132 // Read sector to verify.
01133 for(ii = 0; ii < 256; ii++)
01134 {
01135 temp0 = CPLD_RDWR;
01136 temp1 = CPLD_RDWR;
01137
01138 value = (swap == TRUE)? (temp1<<8)|(temp0 & 0x00ff):
01139 (temp0<<8)|(temp1 & 0x00ff);
01140
01141 if(*pBuf != value)
01142 {
01143 ret = FALSE;
01144 break;
01145 }
01146
01147 pBuf++;
01148 }
01149
01150
01151 // Deassert CE, read from the port will disable CE0
01152 temp1 = CPLD_CE0;
01153
01154 return ret;
01155 } //BOOL NAND__readDataSec( unsigned long phySec, unsigned short * pBuf, BOOL swap)
|
|
||||||||||||||||||||
|
Function reads byte(s) from redundant area.
Definition at line 743 of file nand.c. References NAND_WAIT4READY. Referenced by NAND__isBlockGood(), NAND__isBlockValid(), NAND__markInvalidBlock(), and NAND__mount(). 00747 {
00748 unsigned long columnAddr;
00749 unsigned long RdntByteAddr;
00750 unsigned short ii;
00751 unsigned short temp0;
00752 unsigned char addr_0_7;
00753 unsigned char addr_9_16;
00754 unsigned char addr_17_24;
00755 unsigned char addr_25_27;
00756
00757 NAND_assert (phySec < NAND_SEC_CNT, NAND__READRDNT);
00758 NAND_assert (pData != NULL, NAND__READRDNT2);
00759
00760 NAND_WAIT4READY(temp0);
00761
00762 // Assert CLE: write to the port will set CLE to HIGH
00763 CPLD_CLE = 0;
00764
00765 // Currently one single 128M chip is used.
00766 // NAND chip 0, write to the port will enable CE0
00767 CPLD_CE0 = 0;
00768
00769 // Form the column address on whole pages
00770 columnAddr = (unsigned long) (phySec << 9);
00771
00772 // Form the redundant byte (column) address:
00773 // columnAddr (= phySec<<9) +
00774 // in-page main storage byte-offset (= 512) +
00775 // redundant byte offset ( = offSet);
00776 RdntByteAddr = columnAddr + (unsigned long) offSet;
00777
00778 // Parse the column address
00779 addr_0_7 = (unsigned char)(RdntByteAddr & 0xFF);
00780 addr_9_16 = (unsigned char)(((unsigned long)RdntByteAddr >> 9) & 0xFF);
00781 addr_17_24 = (unsigned char)(((unsigned long)RdntByteAddr >> 17) & 0xFF);
00782 addr_25_27 = (unsigned char)(((unsigned long)RdntByteAddr >> 25) & 0x7);
00783
00784 // send 'Read Mode (3)' command
00785 CPLD_RDWR = NAND_CMD__READ3;
00786
00787 // Deassert CLE: read from the port will reset CLE to LOW
00788 temp0 = CPLD_CLE;
00789
00790 // Assert ALE, TBD by cpld code
00791 CPLD_ALE = 0;
00792
00793 // send address to NAND chip
00794 CPLD_RDWR = addr_0_7;
00795 CPLD_RDWR = addr_9_16;
00796 CPLD_RDWR = addr_17_24;
00797 CPLD_RDWR = addr_25_27;
00798
00799 // Deassert ALE, TBD by cpld code
00800 temp0 = CPLD_ALE;
00801
00802 // Wait for Ready/#Busy signal (input on D0) goes to HIGH.
00803 NAND_WAIT4READY(temp0);
00804
00805 // Read byte
00806 for(ii = 0; ii < len; ii++) *pData++ = (CPLD_RDWR & 0x00FF);
00807
00808 // Deassert CE, read from the port will disable CE0
00809 addr_0_7 = CPLD_CE0;
00810
00811 return TRUE;
00812 }
|
|
||||||||||||||||
|
Function reads back the specified page/sector.
Definition at line 945 of file nand.c. References NAND__markInvalidBlock(), NAND_WAIT4READY, and st_NAND::pagePerBlk. Referenced by NAND__copySec(), NAND__loadTab(), NAND__mount(), and NAND__rdSec(). 00946 {
00947
00948 unsigned short ii;
00949 unsigned long columnAddr;
00950
00951 unsigned short temp0, temp1;
00952 unsigned char addr_0_7;
00953 unsigned char addr_9_16;
00954 unsigned char addr_17_24;
00955 unsigned char addr_25_27;
00956
00957 unsigned char redundant[16];
00958 unsigned char ecc1_1, ecc1_2, ecc1_3;
00959 unsigned char ecc2_1, ecc2_2, ecc2_3;
00960
00961 unsigned short * pData = pBuf;
00962
00963 NAND_assert (phySec < NAND_SEC_CNT, NAND__READSEC);
00964 NAND_assert (pBuf != NULL, NAND__READSEC2);
00965
00966 NAND_WAIT4READY(temp0);
00967
00968 // Assert CLE: write to the port will set CLE to HIGH.
00969 CPLD_CLE = 0;
00970
00971 // NAND chip 0, write to the port will enable CE0
00972 CPLD_CE0 = 0;
00973
00974 // Form the column address on whole pages
00975 columnAddr = (unsigned long) (phySec << 9);
00976
00977 // Parse the column address
00978 //addr_0_7 = (unsigned char)(columnAddr) & 0xFF;
00979 addr_0_7 = 0;
00980 addr_9_16 = (unsigned char)((unsigned long)columnAddr >> 9) & 0xFF;
00981 addr_17_24 = (unsigned char)((unsigned long)columnAddr >> 17) & 0xFF;
00982 addr_25_27 = (unsigned char)((unsigned long)columnAddr >> 25) & 0x7;
00983
00984 // send 'Read Mode (1)' command
00985 CPLD_RDWR = NAND_CMD__READ1;
00986
00987 // Deassert CLE: read from the port will reset CLE to LOW
00988 temp0 = CPLD_CLE;
00989
00990 // Assert ALE, TBD by cpld code
00991 CPLD_ALE = 0;
00992
00993 // send address to NAND chip
00994 CPLD_RDWR = addr_0_7;
00995 CPLD_RDWR = addr_9_16;
00996 CPLD_RDWR = addr_17_24;
00997 CPLD_RDWR = addr_25_27;
00998
00999 // Deassert ALE, TBD by cpld code
01000 temp0 = CPLD_ALE;
01001
01002 // Wait for Ready/#Busy signal (input on D0) goes to HIGH.
01003 NAND_WAIT4READY(temp0);
01004
01005
01006 // Read sector
01007 ReadAndEncode256bytes( pBuf, swap, &ecc1_1, &ecc1_2, &ecc1_3);
01008 ReadAndEncode256bytes( pBuf+128, swap, &ecc2_1, &ecc2_2, &ecc2_3);
01009
01010 //Read redundant area.
01011 pBuf = (unsigned short *)redundant;
01012
01013 for(ii = 0; ii < 16; ii++)
01014 {
01015 *pBuf++ = (CPLD_RDWR & 0x00FF);
01016 }
01017
01018 if( eccCorrectDataRedundant((UCHAR SDFAR *)redundant,
01019 (UCHAR SDFAR *)&redundant[NAND_ECC3_1_OFFSET],
01020 (UCHAR SDFAR *)&redundant[NAND_ECC3_2_OFFSET] ) == YES )
01021 {
01022 // Deassert CE, read from the port will disable CE0
01023 temp1 = CPLD_CE0;
01024
01025 if( eccCorrectDataCommon( (UCHAR SDFAR *)pData, swap,
01026 (UCHAR SDFAR *)&redundant[NAND_ECC1_1_OFFSET],
01027 (UCHAR SDFAR *)&redundant[NAND_ECC1_2_OFFSET],
01028 (UCHAR SDFAR *)&redundant[NAND_ECC1_3_OFFSET],
01029 ecc1_1, ecc1_2, ecc1_3) == YES )
01030 {
01031 if( eccCorrectDataCommon( (UCHAR SDFAR *)pData + 128, swap,
01032 (UCHAR SDFAR *)&redundant[NAND_ECC2_1_OFFSET],
01033 (UCHAR SDFAR *)&redundant[NAND_ECC2_2_OFFSET],
01034 (UCHAR SDFAR *)&redundant[NAND_ECC2_3_OFFSET],
01035 ecc2_1, ecc2_2, ecc2_3) == YES )
01036 {
01037 return TRUE;
01038 }
01039 }
01040 }
01041
01042 // Mark the block to be invalid, the caller will then try to handle the error.
01043 // Well, nobody can handle the read error, the caller will eventually reformat
01044 // the chip.
01045
01046 #ifdef HARD_CODED_OPTIMIZATION
01047 if(NAND__markInvalidBlock((unsigned long)phySec>>6) == FALSE )
01048 {
01049 NAND__markInvalidBlock((unsigned long)phySec>>6);
01050 }
01051 #else
01052 if(NAND__markInvalidBlock((unsigned long)(phySec) / Nand.pagePerBlk) == FALSE)
01053 {
01054 NAND__markInvalidBlock((unsigned long)(phySec) / Nand.pagePerBlk);
01055 }
01056 #endif
01057
01058 return FALSE;
01059
01060 }// BOOL NAND__readSec( unsigned long phySec, unsigned short * pBuf, BOOL swap )
|
Here is the call graph for this function:

|
|
Function tries to replace the defected block where phySec resides in. This function assumes that any sectors prior to the defectd one ( pPhySec ) are still be readable.
Definition at line 575 of file nand.c. References st_NAND::actvPhyBlk, st_NAND::actvPhySec, st_NAND::actvRpPhyBlk, st_NAND::actvSecOffset, st_NAND::flag, st_SECT_HISTORY::logBlk, NAND__copySec(), NAND__eraseBlock(), NAND_COPYERR, st_NAND::pagePerBlk, st_SECT_HISTORY::phyBlk, st_NAND::pMapTab, st_NAND::pRpTab, st_SECT_HISTORY::secOffset, and sectHistory. Referenced by NAND__historyCheck(). 00576 {
00577 NAND_COPYERR err;
00578 unsigned short tmp;
00579
00580 GEN_rdSRAM(Nand.pRpTab, &tmp, 1);
00581 err = NAND__copySec(sectHistory.phyBlk,
00582 &tmp,
00583 0,
00584 Nand.actvSecOffset );
00585
00586 if(err == CPYERR_NONE)
00587 {
00588 #ifdef HARD_CODED_OPTIMIZATION
00589 Nand.actvPhySec =
00590 *pPhySec = ((long)tmp<<6) + sectHistory.secOffset;
00591 #else
00592 Nand.actvPhySec =
00593 *pPhySec = (long)tmp*Nand.pagePerBlk + sectHistory.secOffset;
00594 #endif
00595
00596 Nand.actvPhyBlk = tmp;
00597 GEN_wrSRAM(Nand.pMapTab + sectHistory.logBlk, &tmp, 1);
00598
00599 NAND__wrRpHis(sectHistory.phyBlk,FALSE);
00600 return TRUE;
00601 }
00602
00603 if(err == CPYERR_READ) NAND__eraseBlock(tmp);
00604
00605 NAND__getLastRpInsert();
00606
00607 GEN_wrSRAM(Nand.pMapTab + sectHistory.logBlk,
00608 &Nand.actvRpPhyBlk,
00609 1);
00610
00611 GEN_wrSRAM(Nand.pRpTab, &(sectHistory.phyBlk), 1);
00612
00613 NAND__wrRpHis(0xFFFE,FALSE);
00614
00615 Nand.flag &= ~NAND_FLUSH_DATA_BLOCK_PENDING;
00616 return FALSE;
00617 }
|
Here is the call graph for this function:

|
||||||||||||
|
Function tries to allocate a free block and swap with the one the specified logSec resides in. It is the caller's responsibility to make sure there is no pending data block before this function gets called.
Definition at line 3137 of file nand.c. References st_NAND::actvBlk, st_NAND::actvBlkEndSec, st_NAND::actvPhyBlk, st_NAND::actvPhySec, st_NAND::actvRpPhyBlk, st_NAND::actvSecOffset, CPYERR_NONE, CPYERR_READ, CPYERR_WRITE, st_NAND::flag, NAND__copySec(), NAND__eraseBlock(), NAND_COPYERR, st_NAND::pagePerBlk, st_NAND::pMapTab, and st_NAND::pRpTab. Referenced by NAND__wrSec(). 03138 {
03139 NAND_COPYERR err;
03140 unsigned short tmp;
03141
03142 NAND_assert (pPhySec != NULL , NAND__SWAPSEC);
03143 NAND_assert (logSec < NAND_SEC_CNT , NAND__SWAPSEC2);
03144
03145 // If replacement block is used up, return immediately.
03146 //if(Nand.curRpBlkNum == 0) return FALSE;
03147
03148 // Calculate block end sector.
03149 #ifdef HARD_CODED_OPTIMIZATION
03150 Nand.actvBlkEndSec = (unsigned long)((unsigned long)logSec & 0xFFFFFFC0L)
03151 + Nand.pagePerBlk;
03152 #else
03153 Nand.actvBlkEndSec = (unsigned long)((unsigned long)logSec/Nand.pagePerBlk)*Nand.pagePerBlk
03154 + Nand.pagePerBlk;
03155 #endif
03156
03157 // Set flag to flush data block and block map table.
03158 //Nand.flag |= ( NAND_FLUSH_DATA_BLOCK_PENDING |
03159 //NAND_FLUSH_REPLACE_TAB_PENDING |
03160 //NAND_FLUSH_MAP_TABLE_PENDING );
03161
03162 // If not marked FLUSH_PENDING already, mark it.
03163 /*if( !(Nand.flag & NAND_FLUSH_PENDING) )
03164 {
03165 Nand.flag |= NAND_FLUSH_PENDING;
03166
03167 tmp = 0;
03168
03169 NAND_Assert (Nand.actvChip < _N, kNandErr+431);
03170
03171 NAND__writeRdnt( Nand.sysPhySec[Nand.actvChip] + 1,
03172 &tmp,
03173 NAND_BLOCK_STATUS_BYTE,
03174 1);
03175 }*/
03176
03177 // Remember which block is swaped.
03178 Nand.actvRpPhyBlk = Nand.actvPhyBlk;
03179
03180 // Reserve the first replacement block.
03181 //Nand.rsvRpBlk = 1;
03182
03183 // Attempt to replace it with the first available
03184 // replacement block.
03185 GEN_rdSRAM(Nand.pRpTab, &tmp, 1);
03186
03187 // Copy from src to dst, function returns the dst block in tmp.
03188 err = NAND__copySec( Nand.actvPhyBlk,
03189 &tmp,
03190 0,
03191 Nand.actvSecOffset );
03192
03193 switch(err)
03194 {
03195 case CPYERR_WRITE: return FALSE;
03196
03197 case CPYERR_READ:
03198 // Error read the source block, unable to swap.
03199 // Erase the destination block to maintain free
03200 // replacement block all the time.
03201 NAND__eraseBlock(tmp);
03202
03203 // we'll go ahead and replace the bad block if
03204 // there is any replacement block available thus to make
03205 // the entire flash to be as contiguous as possible.
03206 GEN_wrSRAM(Nand.pMapTab + Nand.actvBlk, &tmp, 1);
03207
03208 NAND__wrRpHis(Nand.actvPhyBlk,FALSE);
03209 return FALSE;
03210
03211 case CPYERR_NONE:
03212 default:
03213 #ifdef HARD_CODED_OPTIMIZATION
03214 Nand.actvPhySec =
03215 *pPhySec = ((unsigned long)tmp<<6) + Nand.actvSecOffset;
03216 #else
03217 Nand.actvPhySec =
03218 *pPhySec = (unsigned long)tmp*Nand.pagePerBlk + Nand.actvSecOffset;
03219 #endif
03220
03221 //block = Nand.actvPhyBlk;
03222
03223 Nand.actvPhyBlk = tmp;
03224
03225 GEN_wrSRAM(Nand.pMapTab + Nand.actvBlk, &tmp, 1);
03226
03227 Nand.flag |= NAND_FLUSH_DATA_BLOCK_PENDING;
03228
03229 return NAND__wrRpHis((Nand.actvRpPhyBlk),TRUE);
03230 }
03231 }
|
Here is the call graph for this function:

|
|
Function tests NAND interface.
Definition at line 2887 of file nand.c. References NAND_format(), NAND_mount(), NAND_readSec(), NAND_unmount(), and NAND_writeSec(). 02888 {
02889 unsigned long maxAddr, jj, kk;
02890 unsigned short buf[256];
02891 unsigned short ii;
02892 unsigned short a, b, c;
02893
02894 a = 0;
02895 b = 0;
02896 c = 0;
02897 kk = 0x33333;
02898
02899 if(a == 0) return TRUE;
02900
02901 if(c) NAND_format();
02902
02903 maxAddr = NAND_mount();
02904 if(0 == maxAddr) return FALSE;
02905
02906 {
02907 for(ii = 0; ii < 256; ii++) buf[ii] = ii;
02908
02909 if(b)
02910 {
02911 for(jj = 0; jj < kk; jj++)
02912 {
02913 NAND_writeSec(jj, buf, TRUE);
02914 }
02915 }
02916
02917 for(jj = 0; jj < kk; jj++)
02918 {
02919 NAND_readSec(jj, buf, TRUE);
02920 for(ii = 0; ii < 256; ii++)
02921 {
02922 if(buf[ii] != ii) break;
02923 }
02924 }
02925 }
02926 NAND_unmount();
02927
02928 return (ii == 256)? TRUE:FALSE;
02929 }
|
Here is the call graph for this function:

|
||||||||||||||||
|
Function writes the specified data back to specified sector(s), it is the caller's responsibility to make sure the corresponding sector(s) is/are blank and cross block shall never happen.
Definition at line 1581 of file nand.c. References NAND__writeSec(), and st_NAND::pageSz. Referenced by NAND__flushBlock(), and NAND__formatChip(). 01584 {
01585 unsigned short ii;
01586 unsigned short jj;
01587 unsigned short *pBuf;
01588 unsigned short modlen;
01589 unsigned short buf[256];
01590
01591 NAND_assert (phySec < NAND_SEC_CNT , NAND__WRITE);
01592 NAND_assert (pData != 0 , NAND__WRITE2);
01593
01594 ii = 0;
01595 while(length)
01596 {
01597 modlen = (length > Nand.pageSz)? Nand.pageSz : length;
01598
01599 #ifdef HARD_CODED_OPTIMIZATION
01600 GEN_rdSRAM((unsigned long)((unsigned long)pData + (ii<<8)), buf, modlen);
01601 #else
01602 GEN_rdSRAM((unsigned long)((unsigned long)pData + ii*Nand.pageSz), buf, modlen);
01603 #endif
01604
01605 pBuf = &buf[modlen];
01606 for(jj = modlen; jj < Nand.pageSz; jj++) *pBuf++ = 0xFFFF;
01607
01608 if(NAND__writeSec(phySec + ii, buf, FALSE) == FALSE ) return FALSE;
01609
01610 ii++;
01611
01612 length -= modlen;
01613 }
01614
01615 return TRUE;
01616 }
|
Here is the call graph for this function:

|
||||||||||||||||
|
Function writes data to the specified blank page/sector.
Definition at line 1317 of file nand.c. References NAND_WAIT4READY. Referenced by NAND__wrSec(). 01318 {
01319 unsigned short ii;
01320 unsigned long columnAddr;
01321
01322 unsigned short temp;
01323 unsigned char addr_0_7;
01324 unsigned char addr_9_16;
01325 unsigned char addr_17_24;
01326 unsigned char addr_25_27;
01327 unsigned char redundant[16]; // 16 redundant bytes.
01328 unsigned char * pC;
01329
01330 NAND_assert (phySec < NAND_SEC_CNT, NAND__WRITEDATASEC);
01331 NAND_assert (pBuf != NULL, NAND__WRITEDATASEC2);
01332
01333 ii = 16;
01334 pC = &redundant[0];
01335 while(ii--)*pC++ = 0x00ff;
01336
01337 // Wait till interface is ready.
01338 NAND_WAIT4READY(temp);
01339
01340 // Remove write protection
01341 //CPLD_nWP = 0;
01342
01343 // Assert CLE: write to the port will set CLE to HIGH
01344 CPLD_CLE = 0;
01345
01346 // NAND chip 0, write to the port will enable CE0
01347 CPLD_CE0 = 0;
01348
01349 // Form the column address on whole pages
01350 columnAddr = (unsigned long) ((unsigned long)phySec << 9);
01351
01352 // Parse the column address
01353 //addr_0_7 = (unsigned char)(columnAddr) & 0xFF;
01354 addr_0_7 = 0;
01355 addr_9_16 = (unsigned char)((unsigned long)columnAddr >> 9) & 0xFF;
01356 addr_17_24 = (unsigned char)((unsigned long)columnAddr >> 17) & 0xFF;
01357 addr_25_27 = (unsigned char)((unsigned long)columnAddr >> 25) & 0x7;
01358
01359 // send 'Read Mode (1)' command to set the pointer
01360 // in A area on NAND chip
01361 CPLD_RDWR = NAND_CMD__READ1;
01362
01363 // send 'Serial Data input' command
01364 CPLD_RDWR = NAND_CMD__DATAIN;
01365
01366 // Deassert CLE: read from the port will reset CLE to LOW
01367 temp = CPLD_CLE;
01368
01369 // Assert ALE, TBD by cpld code
01370 CPLD_ALE = 0;
01371
01372 // send address to NAND chip
01373 CPLD_RDWR = addr_0_7;
01374 CPLD_RDWR = addr_9_16;
01375 CPLD_RDWR = addr_17_24;
01376 CPLD_RDWR = addr_25_27;
01377
01378 // Deassert ALE, TBD by cpld code
01379 temp = CPLD_ALE;
01380
01381 // send data
01382 // Send and encode first 256 bytes
01383 WriteAndEncode256bytes(pBuf,swap,
01384 (UCHAR SDFAR *) &redundant[NAND_ECC1_1_OFFSET],
01385 (UCHAR SDFAR *) &redundant[NAND_ECC1_2_OFFSET],
01386 (UCHAR SDFAR *) &redundant[NAND_ECC1_3_OFFSET] );
01387
01388 // Send and encode second 256 bytes
01389 WriteAndEncode256bytes(pBuf+128,swap,
01390 (UCHAR SDFAR *) &redundant[NAND_ECC2_1_OFFSET],
01391 (UCHAR SDFAR *) &redundant[NAND_ECC2_2_OFFSET],
01392 (UCHAR SDFAR *) &redundant[NAND_ECC2_3_OFFSET] );
01393
01394 eccEncodeRedundant((UCHAR SDFAR *)redundant,
01395 (UCHAR SDFAR *)&redundant[NAND_ECC3_1_OFFSET],
01396 (UCHAR SDFAR *)&redundant[NAND_ECC3_2_OFFSET]);
01397
01398 // Sending out redundant data.
01399 pBuf = (unsigned short *)redundant;
01400 for( ii = 0; ii < 16; ii++) CPLD_RDWR = *pBuf++;
01401
01402
01403 // Assert CLE: write to the port will set CLE to HIGH
01404 CPLD_CLE = 0;
01405
01406 // send 'Auto Program (True)' command
01407 CPLD_RDWR = NAND_CMD__AUTO_PROGRAM_TRUE;
01408
01409 // Deassert CLE: read from the port will reset CLE to LOW
01410 temp = CPLD_CLE;
01411 temp = 0;
01412
01413 // Deassert CE, read from the port will disable CE0
01414 addr_0_7 = CPLD_CE0;
01415 }// void NAND__writeDataSec( unsigned long phySec, unsigned short * pBuf, BOOL swap )
|
|
||||||||||||||||||||
|
Function writes byte(s) to redundant area.
Definition at line 828 of file nand.c. References NAND_WAIT4READY. Referenced by NAND__buildSysInfo(), NAND__flushBlock(), NAND__formatChip(), NAND__markInvalidBlock(), and NAND_mount(). 00832 {
00833 unsigned short temp;
00834 unsigned short ii;
00835 unsigned long columnAddr;
00836 unsigned long RdntByteAddr;
00837 unsigned char addr_0_7;
00838 unsigned char addr_9_16;
00839 unsigned char addr_17_24;
00840 unsigned char addr_25_27;
00841
00842 NAND_assert (phySec < NAND_SEC_CNT, NAND__WRITERDNT);
00843 NAND_assert (pData != NULL, NAND__WRITERDNT2);
00844
00845 NAND_WAIT4READY(temp);
00846
00847 // Remove write protection
00848 //CPLD_nWP = 0;
00849
00850 // Assert CLE: write to the port will set CLE to HIGH
00851 CPLD_CLE = 0;
00852
00853 // NAND chip 0, write to the port will enable CE0
00854 CPLD_CE0 = 0;
00855
00856 // Form the column address on whole pages
00857 columnAddr = (unsigned long) ((unsigned long)phySec << 9);
00858
00859 // Form the redundant byte (column) address:
00860 // columnAddr (= phySec<<9) +
00861 // in-page main storage byte-offset (= 512) +
00862 // redundant byte offset ( = offSet);
00863 RdntByteAddr = columnAddr + (unsigned long) offSet;
00864
00865 // Parse the column address
00866 addr_0_7 = (unsigned char)(RdntByteAddr & 0xFF);
00867 addr_9_16 = (unsigned char)(((unsigned long)RdntByteAddr >> 9) & 0xFF);
00868 addr_17_24 = (unsigned char)(((unsigned long)RdntByteAddr >> 17) & 0xFF);
00869 addr_25_27 = (unsigned char)(((unsigned long)RdntByteAddr >> 25) & 0x7);
00870
00871 // send 'Read Mode (3)' command to set pointer to region C
00872 // (between 512 to 527 byte address in-page) on NAND chip.
00873 CPLD_RDWR = NAND_CMD__READ3;
00874
00875 // send 'Serial Data input' command
00876 CPLD_RDWR = NAND_CMD__DATAIN;
00877
00878 // Deassert CLE: read from the port will reset CLE to LOW
00879 temp = CPLD_CLE;
00880
00881 // Assert ALE, TBD by cpld code
00882 CPLD_ALE = 0;
00883
00884 // send address to NAND chip
00885 CPLD_RDWR = addr_0_7;
00886 CPLD_RDWR = addr_9_16;
00887 CPLD_RDWR = addr_17_24;
00888 CPLD_RDWR = addr_25_27;
00889
00890 // Deassert ALE
00891 temp = CPLD_ALE;
00892
00893 // send data
00894 for( ii = 0; ii < len; ii++) CPLD_RDWR = *pData++;
00895
00896 // Assert CLE: write to the port will set CLE to HIGH
00897 CPLD_CLE = 0;
00898
00899 // send 'Auto Program (True)' command
00900 CPLD_RDWR = NAND_CMD__AUTO_PROGRAM_TRUE;
00901
00902 // Wait for Ready/#Busy signal (input on D0) goes to HIGH.
00903 NAND_WAIT4READY(temp);
00904
00905 // send 'Status Read (1)' command
00906 CPLD_RDWR = NAND_CMD__STATUS_READ1;
00907
00908 // Deassert CLE: read from the port will reset CLE to LOW
00909 temp = CPLD_CLE;
00910
00911 // Restore write protection
00912 //addr_0_7 = CPLD_nWP;
00913
00914 // Read status data
00915 temp = CPLD_RDWR;
00916
00917 // Deassert CE
00918 addr_0_7 = CPLD_CE0; // read from the port will disable CE0
00919
00920 if ( (temp & 0x0001 ) == 0 )
00921 {
00922 // programming pass
00923 return (TRUE);
00924 }
00925 else
00926 {
00927 // programming fail
00928 return (FALSE);
00929 }
00930 }
|
|
||||||||||||||||
|
Function writes to the specified blank page/sector.
Definition at line 1170 of file nand.c. References NAND__readDataSec(), and NAND_WAIT4READY. Referenced by NAND__buildSysInfo(), NAND__copySec(), NAND__formatChip(), NAND__historyCheck(), and NAND__write(). 01171 {
01172 unsigned short ii;
01173 unsigned long columnAddr;
01174 unsigned short temp;
01175 unsigned char addr_0_7;
01176 unsigned char addr_9_16;
01177 unsigned char addr_17_24;
01178 unsigned char addr_25_27;
01179 unsigned short * pData;
01180 unsigned char redundant[16]; // 16 redundant bytes.
01181
01182 NAND_assert (phySec < NAND_SEC_CNT, NAND__WRITESEC);
01183 NAND_assert (pBuf != NULL, NAND__WRITESEC2);
01184
01185 ii = 16;
01186 pData = (unsigned short *)&redundant[0];
01187 while(ii--)*pData++ = 0x00ff;
01188
01189 NAND_WAIT4READY(temp);
01190
01191 // Remove write protection
01192 //CPLD_nWP = 0;
01193
01194 // Assert CLE: write to the port will set CLE to HIGH
01195 CPLD_CLE = 0;
01196
01197 // NAND chip 0, write to the port will enable CE0
01198 CPLD_CE0 = 0;
01199
01200 // Form the column address on whole pages
01201 columnAddr = (unsigned long) ((unsigned long)phySec << 9);
01202
01203 // Parse the column address
01204 //addr_0_7 = (unsigned char)(columnAddr) & 0xFF;
01205 addr_0_7 = 0;
01206 addr_9_16 = (unsigned char)((unsigned long)columnAddr >> 9) & 0xFF;
01207 addr_17_24 = (unsigned char)((unsigned long)columnAddr >> 17) & 0xFF;
01208 addr_25_27 = (unsigned char)((unsigned long)columnAddr >> 25) & 0x7;
01209
01210
01211 // send 'Read Mode (1)' command to set the pointer in A area on NAND chip
01212 CPLD_RDWR = NAND_CMD__READ1;
01213
01214 // send 'Serial Data input' command
01215 CPLD_RDWR = NAND_CMD__DATAIN;
01216
01217 // Deassert CLE: read from the port will reset CLE to LOW
01218 temp = CPLD_CLE;
01219
01220 // Assert ALE, TBD by cpld code
01221 CPLD_ALE = 0;
01222
01223 // send address to NAND chip
01224 CPLD_RDWR = addr_0_7;
01225 CPLD_RDWR = addr_9_16;
01226 CPLD_RDWR = addr_17_24;
01227 CPLD_RDWR = addr_25_27;
01228
01229 // Deassert ALE, TBD by cpld code
01230 temp = CPLD_ALE;
01231
01232 // send data
01233 // Send and encode first 256 bytes
01234 WriteAndEncode256bytes(pBuf,swap,
01235 (UCHAR SDFAR *) &redundant[NAND_ECC1_1_OFFSET],
01236 (UCHAR SDFAR *) &redundant[NAND_ECC1_2_OFFSET],
01237 (UCHAR SDFAR *) &redundant[NAND_ECC1_3_OFFSET] );
01238
01239 // Send and encode second 256 bytes
01240 WriteAndEncode256bytes(pBuf+128,swap,
01241 (UCHAR SDFAR *) &redundant[NAND_ECC2_1_OFFSET],
01242 (UCHAR SDFAR *) &redundant[NAND_ECC2_2_OFFSET],
01243 (UCHAR SDFAR *) &redundant[NAND_ECC2_3_OFFSET] );
01244
01245
01246 eccEncodeRedundant((UCHAR SDFAR *)redundant,
01247 (UCHAR SDFAR *)&redundant[NAND_ECC3_1_OFFSET],
01248 (UCHAR SDFAR *)&redundant[NAND_ECC3_2_OFFSET]);
01249
01250 // Sending out redundant data.
01251 pData = (unsigned short *)&redundant[0];
01252 ii = 16;
01253 while(ii--) CPLD_RDWR = *pData++;
01254
01255
01256 // Assert CLE: write to the port will set CLE to HIGH
01257 CPLD_CLE = 0;
01258
01259 // send 'Auto Program (True)' command
01260 CPLD_RDWR = NAND_CMD__AUTO_PROGRAM_TRUE;
01261
01262
01263 // Wait for Ready/#Busy signal (input on D0) goes to HIGH.
01264 NAND_WAIT4READY(temp);
01265
01266
01267 // Restore write protection
01268 //temp = CPLD_nWP;
01269 #ifdef NAND_PWR_SUPPORT
01270 // Check to see if there was any error.
01271 return NAND__readDataSec(phySec, pBuf, swap);
01272 #else
01273 // send 'Status Read (1)' command
01274 CPLD_RDWR = NAND_CMD__STATUS_READ1;
01275
01276 // Deassert CLE: read from the port will reset CLE to LOW
01277 temp = CPLD_CLE;
01278
01279 // Restore write protection
01280 //addr_0_7 = CPLD_nWP;
01281
01282 // Read status data
01283 temp = CPLD_RDWR;
01284
01285 // Deassert CE, read from the port will disable CE0
01286 addr_0_7 = CPLD_CE0;
01287
01288 NAND_ClearReadWriteBusy();
01289
01290 if ( (temp & 0x0001 ) == 0 )
01291 {
01292 // programming pass
01293 return (TRUE);
01294 }
01295 else
01296 {
01297 // programming fail
01298 return (FALSE);
01299 }
01300 #endif
01301 }
|
Here is the call graph for this function:

|
||||||||||||||||
|
Function writes to the logical sector, which is specified by the FAT file system layer, NAND flash will always appear to be contiguous to the FAT file system on a sector level.
Definition at line 3025 of file nand.c. References st_NAND::actvBlkEndSec, st_NAND::actvPhyBlk, st_NAND::actvPhySec, st_NAND::actvSec, st_NAND::actvSecOffset, st_NAND::flag, NAND__flush(), NAND__historyCheck(), NAND__historySet(), NAND__log2phySec(), NAND__swapSec(), NAND__writeDataSec(), and st_NAND::writingSec. Referenced by NAND_writeSec(). 03026 {
03027 unsigned long phySec;
03028 BOOL bBLANK = FALSE;
03029 BOOL ret = FALSE;
03030
03031 if(Nand.flag & NAND_READ_ONLY ) return FALSE;
03032
03033 // Remember the writing sector.
03034 Nand.writingSec = sec;
03035
03036 if( TRUE == NAND__historyCheck() )
03037 {
03038 // First to check if there is any data block is pending to be flushed,
03039 // which means block might have been remapped and only been partially
03040 // written.
03041 if(Nand.flag & NAND_FLUSH_DATA_BLOCK_PENDING)
03042 {
03043 // Check if we really need to flush.
03044 if( ( (unsigned long)sec != (unsigned long)(Nand.actvSec + 1) ) ||
03045 ( (unsigned long)sec == Nand.actvBlkEndSec) )
03046 {
03047 // Flush only if sectors are not contiguous or sector
03048 // is cross block boundary. If unable to flush,
03049 // report error.
03050 if( ((unsigned long)sec > (unsigned long)(Nand.actvSec + 1)) &&
03051 ((unsigned long)sec < (unsigned long)Nand.actvBlkEndSec) )
03052 {
03053
03054 // Partial flush needed.
03055 if(NAND__flush(TRUE) == FALSE)
03056 {
03057 return FALSE;
03058 }
03059
03060 // If it is partial flush, block shall not be swapped.
03061 Nand.actvSec = sec;
03062
03063 Nand.actvSecOffset = (unsigned long)sec & 0x003F;
03064
03065 phySec =
03066 Nand.actvPhySec = ((unsigned long)Nand.actvPhyBlk << 6) + Nand.actvSecOffset;
03067
03068 bBLANK = TRUE;
03069 }
03070
03071 // Full flush is needed.
03072 else if(NAND__flush(FALSE) == FALSE)
03073 {
03074 return FALSE;
03075 }
03076 }
03077
03078 else
03079 {
03080 // Sector is contiguous, increase active sector offset.
03081 Nand.actvSecOffset++;
03082 Nand.actvSec++;
03083 Nand.actvPhySec++;
03084 phySec = Nand.actvPhySec;
03085
03086 // Sector has to be blank.
03087 bBLANK = TRUE;
03088 }
03089 }
03090
03091 if(bBLANK == FALSE )
03092 {
03093 // Map to physical sector.
03094 phySec = NAND__log2phySec(sec);
03095
03096 // As long as it is NOT contiguous writing, we'll swap the block
03097 // no matter the target sector is blank or not.
03098 if( NAND__swapSec(&phySec, sec) == FALSE )
03099 {
03100 // Can not find replacement block or source is
03101 // unreadable, report error. If it was due source block
03102 // read error, that block gets replaced anyway if we can.
03103 // Note that if a static block buffer is available in RAM,
03104 // this might not be the case.
03105 return FALSE;
03106 }
03107 }
03108
03109 // By now, a blank physical sector has been successfully mapped
03110 // to the specified logical sector.
03111 NAND__historySet(pBuf, swap);
03112
03113 // Write data sector function has delayed status check, always
03114 // return TRUE here.
03115 NAND__writeDataSec(phySec, pBuf, swap);
03116
03117 ret = TRUE;
03118 }
03119
03120 return ret;
03121 }
|
Here is the call graph for this function:

|
|
Function checks to write the system info area.
Definition at line 1830 of file nand.c. References st_NAND::currentpipo, st_NAND::flag, NAND__buildSysInfo(), NAND__eraseBlock(), NAND__flushBlock(), st_NAND::rpTabBackPhyBlk, and st_NAND::rpTabPhyBlk. Referenced by NAND_flush(), and NAND_unmount(). 01831 {
01832 unsigned short temp;
01833 unsigned short* pphyblk;
01834
01835 if((Nand.flag&NAND_FLUSH_MAP_TABLE_PENDING)|(Nand.flag&NAND_FLUSH_REPLACE_TAB_PENDING))
01836 {
01837 // Uable to flush map table, replacement blocks have been used up.
01838 if(Nand.currentpipo[0])
01839 {
01840 pphyblk = &Nand.rpTabBackPhyBlk[0];
01841 //ret = NAND__flushBlock(&Nand.rpTabBackPhyBlk[Nand.actvChip]);
01842 temp = Nand.rpTabPhyBlk[0];
01843 }
01844 else
01845 {
01846 pphyblk = &Nand.rpTabPhyBlk[0];
01847 //ret = NAND__flushBlock(&Nand.rpTabPhyBlk[Nand.actvChip]);
01848 temp = Nand.rpTabBackPhyBlk[0];
01849 }
01850
01851 if(NAND__flushBlock(pphyblk))
01852 {
01853 NAND__eraseBlock(temp);
01854 Nand.currentpipo[0] = !Nand.currentpipo[0];
01855
01856 Nand.flag &= ~(NAND_FLUSH_MAP_TABLE_PENDING|NAND_FLUSH_REPLACE_TAB_PENDING|NAND_FLUSH_PENDING);
01857 }
01858 else
01859 return FALSE;
01860
01861 }
01862
01863 if(Nand.flag & NAND_SYSINFO_CHANGE)
01864 {
01865 // Flush the system info. If unable to flush, volume
01866 // sector 0 is corrupted, thus volume needs a low
01867 // level format to revive. To make system more robust,
01868 // we could reserve more than one block for the
01869 // system area, and report error only when all of them
01870 // are defected.
01871 if(!NAND__buildSysInfo(&Nand)) return FALSE;
01872
01873 Nand.flag &= ~(NAND_FLUSH_SYSINFO_PENDING|NAND_SYSINFO_CHANGE);
01874 }
01875
01876 return TRUE;
01877 }
|
Here is the call graph for this function:

|
|
Function flushes the NAND flash and makes all change final.
Definition at line 2013 of file nand.c. References st_NAND::flag, NAND__eraseBlock(), NAND__flush(), NAND__historyCheck(), NAND__wrSysInfo(), and st_NAND::pRpTab. Referenced by FAT_flushDisk(), and NAND_unmount(). 02014 {
02015 BOOL ret = TRUE;
02016 unsigned short phyblk;
02017 unsigned short ii;
02018 int pri;
02019
02020 NAND_lock(&pri, 1);
02021
02022 if( NAND__historyCheck() == TRUE )
02023 {
02024
02025 if(Nand.flag & NAND_FLUSH_DATA_BLOCK_PENDING)
02026 {
02027 // Flush the entire block.
02028 if( NAND__flush(FALSE) == FALSE) ret = FALSE;
02029 }
02030
02031 if( TRUE == ret )
02032 {
02033 if(Nand.flag & NAND_FLUSH_SYSINFO_PENDING) Nand.flag |= NAND_SYSINFO_CHANGE;
02034
02035 //erase all the occupied block
02036 for(ii=0;ii<NAND_PRESERVE_NUM;ii++)
02037 {
02038 GEN_rdSRAM(Nand.pRpTab + 1 + ii, &phyblk , 1);
02039 //donot consider the block is bad
02040 NAND__eraseBlock(phyblk);
02041 }
02042
02043 Nand.flag &= ~NAND_ERASE_NEED;
02044
02045 ret = NAND__wrSysInfo();
02046 }
02047 }
02048
02049 NAND_unlock(pri, 1);
02050 return ret;
02051 }
|
Here is the call graph for this function:

|
|
Function will format the nand flash. This function is built to support multiple NAND chips.
Definition at line 2061 of file nand.c. References NAND__formatChip(), and st_NAND::pagePerBlk. Referenced by FAT__format(), and NAND__test(). 02062 {
02063 unsigned short num = 0;
02064 unsigned short ii;
02065 unsigned short startPhyBlock[NAND_CHIP_NUM];
02066
02067 // Physical block addresses of multiple chips might not
02068 // be contiguous.
02069 NAND__hwBlockMap(startPhyBlock);
02070
02071 for( ii = 0; ii < NAND_CHIP_NUM; ii++ )
02072 {
02073 // Format chips.
02074 num += NAND__formatChip(startPhyBlock[ii]);
02075 }
02076
02077 // return total available data sectors.
02078 return( (unsigned long) num * Nand.pagePerBlk );
02079 }
|
Here is the call graph for this function:

|
|
Function initializes NAND flash interface.
Definition at line 2392 of file nand.c. References st_NAND::actvBlkEndSec, st_NAND::actvChip, st_NAND::actvSec, st_NAND::currentpipo, st_NAND::curRpBlkNum, st_NAND::dataBlkNum, st_NAND::flag, GEN_free(), GEN_malloc(), st_NAND::mapTabPhySecOffset, st_NAND::maxRpBlkNum, NAND__eraseBlock(), NAND__isBlockValid(), NAND__loadTab(), NAND__mount(), NAND__writeRdnt(), st_NAND::nativeMaxAddr, st_NAND::pagePerBlk, st_NAND::pMapTab, st_NAND::pRpTab, st_NAND::rpTabBackPhyBlk, st_NAND::rpTabPhyBlk, and SYS_die(). Referenced by FAT__format(), and NAND__test(). 02393 {
02394 unsigned int i;
02395 unsigned int count;
02396 unsigned long phySec;
02397 unsigned short ii;
02398 unsigned short temp;
02399 unsigned long pRpTab;
02400 unsigned short dataBlkNum;
02401 unsigned short rpBlkNum;
02402 unsigned short *pD1;
02403 unsigned short *pD2;
02404
02405 // See comment in NAND_wrRpHis.c.
02406 internpresvnum = 0;
02407
02408 Nand.flag = 0;
02409 dataBlkNum = 0;
02410 rpBlkNum = 0;
02411
02412 // Initialize the hardware interface.
02413 pD1 = &Nand.dataBlkNum[0];
02414 pD2 = &Nand.maxRpBlkNum[0];
02415 for(ii = 0; ii < NAND_CHIP_NUM; ii++)
02416 {
02417 if( NAND__mount(ii)==FALSE) return 0L;
02418
02419 if (*pD1 > dataBlkNum )
02420 dataBlkNum = *pD1;
02421
02422 // Search the max number of replacement blocks.
02423 if (*pD2 > rpBlkNum )
02424 rpBlkNum = *pD2;
02425
02426 pD1++; pD2++;
02427 }
02428
02429
02430 // Allocate data block map table, buffer map table upto
02431 // one block.
02432 if ( (Nand.pMapTab = GEN_malloc(dataBlkNum) ) == 0L )
02433 {
02434 // Out of memory, fatal error.
02435 SYS_die(NAND_MOUNT);
02436 }
02437
02438
02439 // Allocate replace block table, assuming replacement block
02440 // map table is always less than one block.
02441 if( (Nand.pRpTab = GEN_malloc(rpBlkNum) ) == 0L)
02442 {
02443 GEN_free(Nand.pMapTab);
02444 // Out of memory, fatal error.
02445 SYS_die(NAND_MOUNT2);
02446 }
02447
02448 // Load the replacement block table of the first chip.
02449 if(Nand.currentpipo[0])
02450 temp = Nand.rpTabPhyBlk[0];
02451 else
02452 temp = Nand.rpTabBackPhyBlk[0];
02453
02454 #ifdef HARD_CODED_OPTIMIZATION
02455 phySec = (unsigned long)temp<<6;
02456 #else
02457 phySec = (unsigned long)temp*Nand.pagePerBlk;
02458 #endif
02459
02460 if( (Nand.curRpBlkNum = NAND__loadTab(phySec,Nand.pRpTab, rpBlkNum) ) == 0 )
02461 {
02462 // No replacement blocks, flash is read-only.
02463 Nand.flag |= NAND_READ_ONLY;
02464
02465 // Current no GUI support for a read-only NAND. we'll simply return
02466 // failure here.
02467 GEN_free(Nand.pMapTab);
02468 GEN_free(Nand.pRpTab);
02469 return 0L;
02470 }
02471
02472 // Read the first map table block if map table covers multiple blocks,
02473 // otherwise read back the entire map table.
02474 if( NAND__loadTab(phySec + Nand.mapTabPhySecOffset[0], Nand.pMapTab, dataBlkNum) == 0 )
02475 {
02476 GEN_free(Nand.pMapTab);
02477 GEN_free(Nand.pRpTab);
02478 return 0L;
02479 }
02480
02481 if(Nand.flag & NAND_ERASEALL_NEED)
02482 {
02483 if ((pRpTab = GEN_malloc(Nand.curRpBlkNum)) == 0L )
02484 {
02485 // Out of memory, fatal error.
02486 SYS_die(NAND_MOUNT3);
02487 }
02488
02489 count=0;
02490
02491 for(i=0;i<Nand.curRpBlkNum;i++)
02492 {
02493 GEN_rdSRAM(Nand.pRpTab + i, &temp, 1);
02494
02495 if(temp >= NAND_BLOCK_CNT)
02496 {
02497 GEN_free(Nand.pMapTab);
02498 GEN_free(Nand.pRpTab);
02499 GEN_free(pRpTab);
02500 return 0L;
02501 }
02502
02503 if(NAND__isBlockValid(temp))
02504 {
02505 if( NAND__eraseBlock(temp))
02506 {
02507 GEN_wrSRAM(pRpTab+count, &temp, 1);
02508 count++;
02509 }
02510
02511 else
02512 {
02513 #ifdef HARD_CODED_OPTIMIZATION
02514 phySec = ((unsigned long)temp << 6) + 63;
02515 #else
02516 phySec = ((unsigned long)Nand.pagePerBlk * temp) + Nand.pagePerBlk - 1;
02517 #endif
02518
02519 ii = NAND_BLOCK_STATUS_BAD;
02520
02521 NAND__writeRdnt(phySec, &ii, NAND_BLOCK_STATUS_BYTE, 1);
02522 }
02523 }
02524 }
02525
02526 GEN_free(Nand.pRpTab);
02527 Nand.pRpTab = pRpTab;
02528 Nand.curRpBlkNum = count;
02529
02530 Nand.flag &= ~NAND_ERASEALL_NEED;
02531 }
02532
02533 else if(Nand.flag & NAND_ERASE_NEED)
02534 {
02535 for(ii=0;ii<NAND_PRESERVE_NUM;ii++)
02536 {
02537 GEN_rdSRAM(Nand.pRpTab + 1 + ii, &temp , 1);
02538
02539 if(temp >= NAND_BLOCK_CNT)
02540 {
02541 GEN_free(Nand.pMapTab);
02542 GEN_free(Nand.pRpTab);
02543 return 0L;
02544 }
02545 // do not consider the block as bad
02546 NAND__eraseBlock(temp);
02547 }
02548
02549 Nand.flag &= ~NAND_ERASE_NEED;
02550 }
02551
02552 // Initialize global controls.
02553 Nand.actvBlkEndSec = (unsigned long)NAND_INVALID_SEC;
02554 Nand.actvSec = (unsigned long)NAND_INVALID_SEC;
02555
02556 Nand.actvChip = 0;
02557
02558 // Calculate valid flash size.
02559 dataBlkNum = 0;
02560 pD1 = &Nand.dataBlkNum[0];
02561 for(ii = 0; ii < NAND_CHIP_NUM; ii++)
02562 {
02563 dataBlkNum += *pD1;
02564 pD1++;
02565 }
02566
02567
02568 #ifdef HARD_CODED_OPTIMIZATION
02569 Nand.nativeMaxAddr = ( (unsigned long)dataBlkNum << 6 ) - 1;
02570 #else
02571 Nand.nativeMaxAddr = ( (unsigned long)dataBlkNum * Nand.pagePerBlk ) - 1;
02572 #endif
02573
02574 return Nand.nativeMaxAddr;
02575 }
|
Here is the call graph for this function:

|
||||||||||||||||
|
Function reads back the specified logical sector with disk I/O lock wrapper.
Definition at line 2779 of file nand.c. References NAND__rdSec(). Referenced by ENCODER_cache(), NAND__test(), SYS_getParams(), and SYS_setParams(). 02780 {
02781 BOOL ret;
02782 int pri;
02783
02784 NAND_lock(&pri, 1);
02785 ret = NAND__rdSec(sec, pBuf, swap);
02786 NAND_unlock(pri, 1);
02787
02788 return ret;
02789 }
|
Here is the call graph for this function:

|
|
Function erases entire NAND chip, all information will be lost.
Definition at line 2866 of file nand.c. References NAND__eraseBlock(). Referenced by NAND__formatChip(). 02867 {
02868 int kk;
02869
02870 // remove write protection
02871 CPLD_nWP = 0;
02872 for(kk = 0; kk < blkNum; kk++)
02873 {
02874 NAND__eraseBlock(kk);
02875 }
02876 // Apply write protection.
02877 kk = CPLD_nWP;
02878 }
|
Here is the call graph for this function:

|
|
Function unmounts NAND flash and releases memory allocated to flash driver.
Definition at line 2938 of file nand.c. References st_NAND::flag, GEN_free(), NAND__eraseBlock(), NAND__flush(), NAND__historyCheck(), NAND__wrSysInfo(), NAND_flush(), st_NAND::pMapTab, and st_NAND::pRpTab. Referenced by FAT__unmountDisk(), and NAND__test(). 02939 {
02940 BOOL ret = TRUE;
02941 unsigned short ii;
02942 #if 0
02943 unsigned short phyblk;
02944
02945 if( NAND__historyCheck() == FALSE)
02946 {
02947 // restore write protection
02948 ii = CPLD_nWP;
02949 return FALSE;
02950 }
02951
02952
02953 if(Nand.flag & NAND_FLUSH_DATA_BLOCK_PENDING)
02954 {
02955 // Flush the entire block.
02956 ret = NAND__flush(FALSE);
02957 }
02958
02959 if(Nand.flag & NAND_FLUSH_SYSINFO_PENDING) Nand.flag |= NAND_SYSINFO_CHANGE;
02960
02961 //erase all the occupied block
02962 for(ii=0;ii<NAND_PRESERVE_NUM;ii++)
02963 {
02964 GEN_rdSRAM(Nand.pRpTab + 1 + ii, &phyblk , 1);
02965 //donot consider the block is bad
02966 NAND__eraseBlock(phyblk);
02967 }
02968
02969 Nand.flag &= ~NAND_ERASE_NEED;
02970 NAND__wrSysInfo();
02971 #else
02972 ret = NAND_flush();
02973 #endif
02974 // Release data objects.
02975 GEN_free(Nand.pMapTab);
02976 GEN_free(Nand.pRpTab);
02977
02978 // restore write protection
02979 ii = CPLD_nWP;
02980 return ret;
02981 }
|
Here is the call graph for this function:

|
||||||||||||||||
|
Function writes to the logical sector with I/O lock wrapper.
Definition at line 2997 of file nand.c. References NAND__wrSec(). Referenced by DECODER_cache(), ENCODER_putData(), NAND__test(), and SYS_setParams(). 02998 {
02999 BOOL ret;
03000 int pri;
03001
03002 NAND_lock(&pri, 1);
03003 ret = NAND__wrSec(sec, pBuf, swap);
03004 NAND_unlock(pri, 1);
03005
03006 return ret;
03007 }
|
Here is the call graph for this function:

1.3.9.1