📄 nandmtd.c
字号:
/* void */
/* */
/* Returns: */
/* TRUE if device is ready */
/* */
/*----------------------------------------------------------------------*/
FLBoolean waitForReady (void)
{
int val;
int n=0;
do
{
n++;
val = readStatus();
val &= 0x40; /* R/B 接 I/O(6) 读R/B状态判断设备状态 */
if(n>10000)
{
printf("nand_erase_block time out!\n");
break;
}
} while(val == 0);
return TRUE;
}
/*----------------------------------------------------------------------*/
/* m a k e C o m m a n d */
/* */
/* Set Page Pointer to Area A, B or C in page. */
/* */
/* Author: kuangyaowen Date:2007-11-21 */
/* */
/* Parameters: */
/* vol : Pointer identifying drive */
/* cmd : receives command relevant to area */
/* addr : receives the address to the right area. */
/* modes : mode of operation (EXTRA ...) */
/* */
/*----------------------------------------------------------------------*/
static void makeCommand (PointerOp *cmd, CardAddress address, int modes)
{
int bit8;
if (modes & EXTRA)
{
*cmd = AREA_C;
}
else
{
bit8 = (unsigned short)address & 0x100;
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 )
{
nand_ale_high();
nand_write_address((unsigned char)address&0xff);
nand_write_address((unsigned char)(address>>9)&0xff);
nand_write_address((unsigned char)(address>>17)&0xff);
nand_write_address((unsigned char)(address>>25)&0x01);
nand_ale_low();
}
/*----------------------------------------------------------------------*/
/* 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)
{
nand_write_command (cmd); /* move flash pointer to respective area of the page*/
setAddress (address);
taskDelay(1);
}
/*----------------------------------------------------------------------*/
/* 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)
{
nand_write_command(cmd); /* move flash pointer to respective area of the page */
nand_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 ;
nand_write_command(READ_STATUS);
chipStatus = nand_read_data();
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)
{
nand_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;
int i=0;
int j=0;
int x=0,y=0;
nand_ce_low(); /*片选有效*/
/* move flash pointer to areas A,B or C of page*/
if (modes & EXTRA)
{
cmd = AREA_C;
}
else
{
bit8 = (unsigned short)address & 0x100;
if(bit8 == 0)
{
cmd = AREA_A;
}
else
{
cmd = AREA_B;
}
}
nand_write_command(cmd); /* move flash pointer to respective area of the page */
nand_ale_high();
nand_write_address((unsigned char)(address&0xff)); /* A0 ~ A7 */
nand_write_address((unsigned char)(address>>9)&0xff); /* A9 ~ A16 */
nand_write_address((unsigned char)(address>>17)&0xff); /* A17 ~ A24 */
nand_write_address((unsigned char)(address>>25)&0x01); /* A25*/
nand_ale_low();
taskDelay(1);
/*for(i=0;i<10000;i++)
{
j=j+1;
}*/
for(i=0;i<length;i++)
{
buffer[i]=nand_read_data(); /*读取数据*/
/*printf("read:buffer[%d]=0x%x,address=0x%x\n",i,buffer[i],address);*/
}
nand_ce_high(); /*片选取消*/
#ifdef DEBUG_PRINT
printf("READ: address = 0x%x, length = 0x%x,modes = 0x%x\n", address, length,modes);
#endif
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: kuangyaowen Date:2007-11-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;
int i=0;
int x=0,y=0;
nand_ce_low(); /*片选有效*/
/* move flash pointer to areas A,B or C of page */
if (modes & EXTRA)
{
cmd = AREA_C;
}
else
{
bit8 = (unsigned short)address & 0x100;
if(bit8 == 0)
{
cmd = AREA_A;
}
else
{
cmd = AREA_B;
}
}
nand_write_command(cmd); /* move flash pointer to respective area of the page */
nand_write_command(SERIAL_DATA_INPUT); /* start data loading for write */
nand_ale_high();
nand_write_address((unsigned char)(address&0xff)); /* A0 ~ A7 */
nand_write_address((unsigned char)(address>>9)&0xff); /* A9 ~ A16 */
nand_write_address((unsigned char)(address>>17)&0xff); /* A17 ~ A24 */
nand_write_address((unsigned char)(address>>25)&0x01); /* A25*/
nand_ale_low();
/* load data and syndrom*/
for(i=0;i<length;i++)
{
nand_write_data(buffer[i]);
/*printf("write:buffer[%d]=0x%x,address=0x%x\n",i,buffer[i],address);*/
}
nand_write_command(SETUP_WRITE); /* execute page program*/
waitForReady();
if(readStatus() & FAIL)
{
status = flWriteFault ;
}
else
{
status = flOK ;
}
#ifdef DEBUG_PRINT
printf("WRITE: address = 0x%x, length = 0x%x, mode = %d\n", address, length, modes);
#endif
nand_ce_high(); /*片选取消*/
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: kuangyaowen Date:2007-11-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;
/* read in sectors; first and last might be partial */
int page = modes & EXTRA ? 16 : 512;
#if 0
if(1==nand_is_bad_block((address&(~page))/32))/*坏块判断*/
{
address+=page;
}
#endif
readNow = page - ((unsigned short)address & (page - 1));
temp = (char FAR1 *)buffer;
for ( ; length > 0 ; )
{
if (readNow > length) /* 如果要读的长度小于一个页面中偏移地址之后的空间大小 */
{
readNow = length; /* 那要读的就是该长度 07-11-21 */
}
/* 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: kuangyaowen Date:2007-11-21 */
/* */
/* Parameters: */
/* vol : Pointer identifying drive */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -