📄 nandmtd.c
字号:
if(bit8 == 0)
*cmd = AREA_A;
else
*cmd = AREA_B;
}
}
/*----------------------------------------------------------------------*/
/* s e t A d d r e s s */
/* */
/* Latch address to selected flash device. */
/* */
/* Parameters: */
/* address : address to set. */
/* */
/*----------------------------------------------------------------------*/
static void setAddress( CardAddress address )
{
WRITE_ADDRESS((unsigned char)address);
WRITE_ADDRESS((unsigned char)(address >> 9));
WRITE_ADDRESS((unsigned char)(address >> 17));
WRITE_ADDRESS((unsigned char)(address >> 25));
}
/*----------------------------------------------------------------------*/
/* r e a d C o m m a n d */
/* */
/* Issue read command. */
/* */
/* Parametes: */
/* cmd : Command to issue (according to area). */
/* address : address to read from. */
/* */
/*----------------------------------------------------------------------*/
static void readCommand (PointerOp cmd, CardAddress address)
{
WRITE_COMMAND (cmd); /* move flash pointer to respective area of the page*/
setAddress (address);
waitForReady();
}
/*----------------------------------------------------------------------*/
/* w r i t e C o m m a n d */
/* */
/* Issue write command. */
/* */
/* Parametes: */
/* cmd : Command to issue (according to area). */
/* address : address to write to. */
/* */
/*----------------------------------------------------------------------*/
static void writeCommand (PointerOp cmd, CardAddress address)
{
WRITE_COMMAND(cmd); /* move flash pointer to respective area of the page */
WRITE_COMMAND(SERIAL_DATA_INPUT); /* start data loading for write */
setAddress (address);
}
/*----------------------------------------------------------------------*/
/* r e a d S t a t u s */
/* */
/* Read status of selected flash device. */
/* */
/* Parameters: */
/* */
/* Returns: */
/* Chip status. */
/* */
/*----------------------------------------------------------------------*/
unsigned char readStatus(void)
{
unsigned char chipStatus ;
WRITE_COMMAND(READ_STATUS);
READ_DATA(chipStatus);
return chipStatus;
}
/*----------------------------------------------------------------------*/
/* w r i t e E x e c u t e */
/* */
/* Execute write. */
/* */
/* Parametes: */
/* Returns: */
/* FLStatus : 0 on success, otherwise failed. */
/* */
/*----------------------------------------------------------------------*/
static FLStatus writeExecute (void)
{
WRITE_COMMAND(SETUP_WRITE); /* execute page program*/
waitForReady();
if(readStatus() & FAIL)
return flWriteFault ;
return flOK ;
}
/*----------------------------------------------------------------------*/
/* r e a d O n e S e c t o r */
/* */
/* Read up to one 512-byte block from flash. */
/* */
/* Parameters: */
/* vol : Pointer identifying drive */
/* address : Address to read from. */
/* buffer : buffer to read to. */
/* length : number of bytes to read (up to sector size). */
/* modes : EDC flag etc. */
/* */
/* Returns: */
/* FLStatus: 0 on success, otherwise failed. */
/* */
/*----------------------------------------------------------------------*/
static FLStatus readOnePage (FLFlash vol,
CardAddress address, /* starting flash address*/
char FAR1 *buffer, /* target buffer */
int length, /* bytes to read */
int modes) /* EDC flag etc.*/
{
FLStatus status = flOK;
PointerOp cmd;
int bit8;
/* move flash pointer to areas A,B or C of page*/
makeCommand (&cmd, address, modes);
readCommand (cmd, address);
tffscpy16((unsigned char*)buffer, (const unsigned char *) 0x1000000, length );
return status;
}
/*----------------------------------------------------------------------*/
/* w r i t e O n e S e c t o r */
/* */
/* Write data in one 512-byte block to flash. */
/* Assuming that EDC mode never requested on partial block writes. */
/* */
/* Author: 王辉 Date:2004-8-21 */
/* */
/* Parameters: */
/* vol : Pointer identifying drive */
/* address : Address of sector to write to. */
/* buffer : buffer to write from. */
/* length : number of bytes to write (up to sector size). */
/* modes : OVERWRITE, EDC flags etc. */
/* */
/* Returns: */
/* FLStatus: 0 on success, otherwise failed. */
/* */
/*----------------------------------------------------------------------*/
static FLStatus writeOnePage(FLFlash vol,
CardAddress address, /* target flash addres */
const char FAR1 *buffer, /* source RAM buffer */
int length, /* bytes to write (up to BLOCK) */
int modes) /* OVERWRITE, EDC flags etc. */
{
FLStatus status;
PointerOp cmd;
int bit8;
if (flWriteProtected(vol.socket))
return flWriteProtect;
/* move flash pointer to areas A,B or C of page */
makeCommand (&cmd, address, modes);
writeCommand (cmd, address);
/* load data and syndrom*/
tffscpy16((unsigned char FAR0 *) 0x1000000, (const unsigned char *)buffer, length );
status = writeExecute();
#ifdef DEBUG_PRINT
DEBUG_PRINT("WRITE: address = 0x%x, length = 0x%x, mode = %d\n", address, length, modes);
#endif
return status;
}
/* Core MTD methods - read, write and erase */
/*----------------------------------------------------------------------*/
/* n a n d R e a d */
/* */
/* Read some data from the flash. This routine will be registered as */
/* the read routine for this MTD. */
/* */
/* Author: 王辉 Date:2004-8-21 */
/* */
/* Parameters: */
/* vol : Pointer identifying drive */
/* address : Address to read from. */
/* buffer : buffer to read to. */
/* length : number of bytes to read (up to sector size). */
/* modes : EDC flag etc. */
/* */
/* Returns: */
/* FLStatus: 0 on success, otherwise failed. */
/* */
/*----------------------------------------------------------------------*/
static FLStatus nandMTDRead( FLFlash vol,
CardAddress address, /* target flash address */
void FAR1 *buffer, /* source RAM buffer */
int length, /* bytes to write */
int modes) /* Overwrite, EDC flags etc. */
{
char FAR1 *temp;
int readNow;
int page;
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位总线宽度*/
/* read in sectors; first and last might be partial */
page = modes & EXTRA ? 16 : 512;
readNow = page - ((unsigned short)address & (page - 1));
temp = (char FAR1 *)buffer;
#ifdef DEBUG_PRINT
DEBUG_PRINT("READ: address = 0x%x, length = 0x%x\n", address, length);
#endif
for ( ; length > 0 ; )
{
if (readNow > length) /* 如果要读的长度小于一个页面中偏移地址之后的空间大小 */
readNow = length; /* 那要读的就是该长度 04-8-6 */
/* turn off EDC on partial block read*/ /* 如果要读的长度大于一个页面的大小,就先读一个页面 */
checkStatus( readOnePage(&vol, address, temp, readNow,
(readNow != SECTOR_SIZE ? (modes & ~EDC) : modes)) );
length -= readNow;
address += readNow;
temp += readNow;
/* align at sector */
readNow = page;
}
return flOK ;
}
/*----------------------------------------------------------------------*/
/* n a n d W r i t e */
/* */
/* Write some data to the flash. This routine will be registered as the */
/* write routine for this MTD. */
/* */
/* Author: 王辉 Date:2004-8-21 */
/* */
/* Parameters: */
/* vol : Pointer identifying drive */
/* address : Address of sector to write to. */
/* buffer : buffer to write from. */
/* length : number of bytes to write (up to sector size). */
/* modes : OVERWRITE, EDC flags etc. */
/* */
/* Returns: */
/* FLStatus: 0 on success, otherwise failed. */
/* */
/*----------------------------------------------------------------------*/
static FLStatus nandMTDWrite( FLFlash vol,
CardAddress address, /* target flash address*/
const void FAR1 *buffer, /* source RAM buffer */
int length, /* bytes to write */
int modes) /* Overwrite, EDC flags etc.*/
{
int writeNow;
int page;
const char FAR1 *temp;
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位总线宽度*/
#ifdef VERIFY_AFTER_WRITE
CardAddress saveAddress = address;
unsigned short flReadback[SECTOR_SIZE / sizeof(unsigned short)];
#endif
/* write in sectors; first and last might be partial*/
page = modes & EXTRA ? 16 : 512;
writeNow = page - ((unsigned short)address & (page - 1));
temp = (const char FAR1 *)buffer;
for ( ; length > 0 ; )
{
if (writeNow > length)
writeNow = length;
/* turn off EDC on partial block write*/
status = writeOnePage(&vol, address, temp, writeNow,
writeNow != 512 ? (modes & ~EDC) : modes);
if (status != flOK)
break;
#ifdef VERIFY_AFTER_WRITE
status = readOnePage (&vol, address, (char FAR1 *)flReadback,
writeNow, (writeNow != SECTOR_SIZE ? (modes & ~EDC) : modes));
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -