?? nandmtd.c
字號:
if((status != flOK) || (tffscmp(temp, flReadback, writeNow) != 0))
{ status = flWriteFault; break; }
#endif
length -= writeNow;
address += writeNow;
temp += writeNow;
/* align at sector */
writeNow = page;
}
return flOK ;
}
/*----------------------------------------------------------------------*/
/* n a n d E r a s e */
/* */
/* Erase number of blocks. This routine will be registered as the */
/* erase routine for this MTD. */
/* */
/* Author: 王輝 Date:2004-8-21 */
/* */
/* Parameters: */
/* vol : Pointer identifying drive */
/* blockNo : First block to erase. */
/* blocksToErase : Number of blocks to erase. */
/* */
/* Returns: */
/* FLStatus : 0 on success, otherwise failed. */
/* */
/*----------------------------------------------------------------------*/
static FLStatus nandMTDErase( FLFlash vol,
int blockNo, /* start' block (0 .. chipNoOfBlocks-1)*/
int blocksToErase) /* Number of blocks to be erased */
{
int i;
FLStatus status = flOK;
NAND_InitECC(); /*初始化ECC編/解碼器*/
NAND_ENABLE_CE(); /*使能NAND Flash的片選*/
NAND_ENABLE_CONT(); /*置位NFCONT第0位(Mode),NAND Flash controller enable*/
NAND_BW8(); /*NFCONF的第0位(BusWidth(R/W))置0,即8位總線寬度*/
if (flWriteProtected(vol.socket))
return flWriteProtect;
/* blockNo %= thisVars->noOfBlocks; */ /* within flash device */
if ( blockNo + blocksToErase > thisVars->noOfBlocks ) /* accross device boundary */
return flBadParameter;
#ifdef DEBUG_PRINT
DEBUG_PRINT("firstBlock = 0x%x, numOfBlock = 0x%x\n", blockNo, blocksToErase);
#endif
for ( i=0; i < blocksToErase; i++, blockNo++ )
{
unsigned short pageNo = blockNo * PAGES_PER_BLOCK ;
WRITE_COMMAND(SETUP_ERASE);
WRITE_ADDRESS((unsigned char)pageNo); /* A9 ~ A16 */
WRITE_ADDRESS((unsigned char)(pageNo >> 8)); /* A17 ~ A22 */
WRITE_ADDRESS((unsigned char)(pageNo >> 16)); /* A25 */
WRITE_COMMAND(CONFIRM_ERASE);
waitForReady();
if(readStatus() & FAIL)
{
status = flWriteFault; /* erase operation failed */
}
#ifdef DEBUG_PRINT
DEBUG_PRINT("ERASE: blockNo = 0x%x\n", blockNo);
#endif
if (status != flOK) /* reset flash device and abort */
{
#ifdef DEBUG_PRINT
DEBUG_PRINT("Debug: erase failed in K9F1208U0C.\n");
#endif
WRITE_COMMAND(RESET_FLASH);
waitForReady();
break ;
}
} /* block loop */
return status;
}
/*----------------------------------------------------------------------*/
/* c d s n M a p */
/* */
/* Map through buffer. This routine will be registered as the map */
/* routine for this MTD. */
/* */
/* Parameters: */
/* vol : Pointer identifying drive */
/* address : Flash address to be mapped. */
/* length : number of bytes to map. */
/* */
/* Returns: */
/* Pointer to the buffer data was mapped to. */
/* */
/*----------------------------------------------------------------------*/
static void FAR0 * nandMTDMap ( FLFlash vol,
CardAddress address,
int length )
{
/* address -= 0x1000000;*/
nandMTDRead(&vol,address,thisBuffer,length, 0);
vol.socket->remapped = TRUE;
return (void FAR0 *)thisBuffer;
}
/*----------------------------------------------------------------------*/
/* i s K n o w n M e d i a */
/* */
/* Check if this flash media is supported. Initialize relevant fields */
/* in data structures. */
/* */
/* Parameters: */
/* vol : Pointer identifying drive */
/* vendorId_P : vendor ID read from chip. */
/* chipId_p : chip ID read from chip. */
/* dev : dev chips were accessed before this one. */
/* */
/* Returns: */
/* TRUE if this media is supported, FALSE otherwise. */
/* */
/*----------------------------------------------------------------------*/
#define KM29N16000_FLASH 0xec64
#define KM29N32000_FLASH 0xece5
#define K9F6408X0C_FLASH 0xece6
#define K9F1208U0M_FLASH 0xec76
static FLBoolean isKnownMedia( FLFlash vol,
unsigned short vendorId_p,
unsigned short chipId_p,
int dev )
{
if (dev == 1)
{
thisVars->vendorID = vendorId_p; /* remember for next chips */
thisVars->chipID = chipId_p;
if (vendorId_p == 0xEC) /* Samsung */
{
switch (chipId_p)
{
case 0x64: /* 2M */
case 0xEA:
vol.type = KM29N16000_FLASH ;
vol.chipSize = 0x200000L;
return TRUE;
case 0xE5:
case 0xE3: /* 4M */
vol.type = KM29N32000_FLASH;
vol.flags |= BIG_PAGE;
vol.chipSize = 0x400000L;
return TRUE;
case 0xE6: /* 8M */
vol.type = K9F6408X0C_FLASH;
vol.flags |= BIG_PAGE;
vol.chipSize = 0x800000L;
return TRUE;
case 0x76: /* 64M */
vol.type = K9F1208U0M_FLASH;
vol.flags |= BIG_PAGE;
vol.chipSize = 0x4000000L;
return TRUE;
}
}
}
else /* dev != 0*/
if( (vendorId_p == thisVars->vendorID) && (chipId_p == thisVars->chipID) )
return TRUE ;
return FALSE ;
}
/*----------------------------------------------------------------------*/
/* r e a d F l a s h I D */
/* */
/* Read vendor and chip IDs, count flash devices. Initialize relevant */
/* fields in data structures. */
/* */
/* Parameters: */
/* vol : Pointer identifying drive */
/* interface : Pointer to window. */
/* dev : dev chips were accessed before this one. */
/* */
/* Returns: */
/* TRUE if this media is supported, FALSE otherwise. */
/* */
/*----------------------------------------------------------------------*/
static int readFlashID (FLFlash vol, int dev)
{
unsigned char vendorId_p, chipId_p;
NAND_ENABLE_CONT(); /*NFCONF的第0位(BusWidth(R/W))置0,即8位總線寬度*/
NAND_INIT1();
NAND_INIT();
NAND_ENABLE_CE(); /*使能NAND Flash的片選*/
NAND_ENABLE_CONT(); /*置位NFCONT第0位(Mode),NAND Flash controller enable*/
NAND_BW8(); /*NFCONF的第0位(BusWidth(R/W))置0,即8位總線寬度*/
WRITE_COMMAND(RESET_FLASH);
waitForReady();
NAND_InitECC(); /*初始化ECC編/解碼器*/
WRITE_COMMAND(READ_ID);
WRITE_ADDRESS(0x00); /* Address. 1cycle */
READ_DATA(vendorId_p);
READ_DATA(chipId_p);
if (isKnownMedia(&vol, vendorId_p, chipId_p, dev) != TRUE) /* no chip or diff.*/
return FALSE ; /* type of flash */
/* set flash parameters*/
if ( dev == 1 )
{
thisVars->pageAreaSize = 0x100 * vol.interleaving;
thisVars->pageSize = (vol.flags & BIG_PAGE ? 0x200 : 0x100) * vol.interleaving;
thisVars->tailSize = (vol.flags & BIG_PAGE ? 16 : 8) * vol.interleaving;
thisVars->pageMask = thisVars->pageSize - 1 ;
vol.erasableBlockSize = PAGES_PER_BLOCK * thisVars->pageSize;
thisVars->noOfBlocks = (unsigned short)( (vol.chipSize * vol.interleaving)
/ vol.erasableBlockSize ) ;
}
return TRUE ;
}
/*----------------------------------------------------------------------*/
/* n a n d M T D I d e n t i f y */
/* */
/* Identify flash. This routine will be registered as the */
/* identification routine for this MTD. */
/* */
/* Returns: */
/* FLStatus: 0 on success, otherwise failed. */
/* */
/*----------------------------------------------------------------------*/
FLStatus nandMTDIdentify(FLFlash vol)
{
#ifdef DEBUG_PRINT
DEBUG_PRINT("Debug: Entering K9F1208U0C identification routine\n");
#endif
flSetWindowBusWidth(vol.socket,8);/* use 16-bits */
flSetWindowSpeed(vol.socket,120); /* 120 nsec. */
flSetWindowSize(vol.socket,2); /* 4 KBytes */
vol.mtdVars = &mtdVars[flSocketNoOf(vol.socket)];
/* get pointer to buffer (we assume SINGLE_BUFFER is not defined) */
thisVars->buffer = flBufferOf(flSocketNoOf(vol.socket));
vol.interleaving = 1;
vol.noOfChips = 1; /* 以1為起始 */
if(readFlashID(&vol, vol.noOfChips) != TRUE )
{
#ifdef DEBUG_PRINT
DEBUG_PRINT("Debug: did not identify K9F1208U0C flash media.\n");
#endif
return flUnknownMedia;
}
/* Register our flash handlers */
vol.write = nandMTDWrite;
vol.erase = nandMTDErase;
vol.read = nandMTDRead;
vol.map = nandMTDMap;
vol.flags |= SUSPEND_FOR_WRITE;
#ifdef DEBUG_PRINT
DEBUG_PRINT("Debug: Identified K9F1208U0C.\n");
#endif
return flOK;
}
#if FALSE
/*----------------------------------------------------------------------*/
/* f l R e g i s t e r N A N D */
/* */
/* Registers this MTD for use */
/* */
/* Parameters: */
/* None */
/* */
/* Returns: */
/* FLStatus : 0 on success, otherwise failure */
/*----------------------------------------------------------------------*/
FLStatus flRegisterNAND(void)
{
if (noOfMTDs >= MTDS)
return flTooManyComponents;
mtdTable[noOfMTDs++] = nandMTDIdentify;
return flOK;
}
#endif /* FALSE */
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -