📄 nandflash.c
字号:
WRITE_BYTE(*buf++);
}
WRITE_CMD(PAGE_PROGRAM_CMD);
while(!NANDFLASH_READY());
if((Status = ReadStatus()) == PROGRAM_ERROR)
{
break;
}
}
NANDFLASH_DISABLE();
return Status;
}
/** 向NandFlash中写一块数据.
**
** 输入参数: UCHAR *pbyBuf -- 要写入的数据的缓冲区
** ULONG nBlockNum -- 要写入的块号
**
** 返回值: 0 -- 写成功; 其他 -- 读失败
**
** @param pbyBuf 要写入的数据的缓冲区
** @param nBlockNum 要写入的块号
** @return whatever
** @author 吕剑国
** @version v0.1 beta
** @see
*/
UCHAR
NandProgramBlock(UCHAR *pbyBuf, ULONG nBlockNum)
{
UWORD i, j;
UCHAR Status = 0;
ULONG nSector;
// 擦除要写入的块
if (EraseBlock(nBlockNum))
return (PROGRAM_ERROR);
nSector = nBlockNum << 5;
NANDFLASH_ENABLE();
for (i = 0; i < SECTOR_PER_BLOCK; i++) {
WRITE_CMD(SDATA_INPUT_CMD);
ADD_LATCH_ENABLE();
WRITE_BYTE(0);
WRITE_BYTE((UCHAR) nSector);
WRITE_BYTE((UCHAR) (nSector >> 8));
ADD_LATCH_DISABLE();
nSector++;
for(j = 0; j < 512; j++)
WRITE_BYTE(*pbyBuf++);
WRITE_CMD(PAGE_PROGRAM_CMD);
while(!NANDFLASH_READY());
if ((Status = ReadStatus()) == PROGRAM_ERROR)
break;
}
NANDFLASH_DISABLE();
return (Status);
}
void
EraseNandFlash(void)
{
UWORD i;
for (i=0; i<BLOCK_NUM*2; i++)
{
EraseBlock(i);
}
}
/*
UCHAR Tep_Buf1[512*32];
UCHAR Tep_Buf2[512*32];
UCHAR WriteSector1(UCHAR *buf, ULONG startsector, UWORD sectornum)//武东宏添加
{
ULONG blocknum;
UWORD front_sectornum,back_secternum,i;
UWORD begin_block,end_block;
ULONG front_startsector,back_startsector;
UCHAR result;
if(sectornum>0)
{
begin_block = startsector/32;
end_block = (startsector+sectornum-1)/32;
blocknum = end_block - begin_block+1;
front_sectornum = startsector - begin_block*32;
back_secternum = (end_block+1)*32 - startsector - sectornum;
front_startsector = startsector - front_sectornum;
back_startsector = startsector + sectornum;
if(front_sectornum>0)
{
ReadSector1(Tep_Buf1, front_startsector, front_sectornum);
}
if(back_secternum>0)
{
ReadSector1(Tep_Buf2, back_startsector, back_secternum);
}
for(i=0;i<blocknum;i++)
{
result = EraseBlock(begin_block++);
if (result)
return (result);
}
if(front_sectornum>0)
{
result = ProgramSector(Tep_Buf1, front_startsector, front_sectornum);
if (result)
return (result);
}
if(back_secternum>0)
{
result = ProgramSector(Tep_Buf2, back_startsector, back_secternum);
if (result)
return (result);
}
result = ProgramSector(buf, startsector, sectornum);
}
return (result);
}
*/
UCHAR
WriteSector1(UCHAR *buf, ULONG startsector, UWORD sectornum)
{
NAND_CACHE_HEADER *pstHeader;
ULONG nBlockNum, nSectorNum = startsector, nSectorOffsetInBlock, nSectors;
SWORD sIndex;
UCHAR cIndex, *pbyBuf = buf;
do {
nBlockNum = nSectorNum >> 5;
nSectorOffsetInBlock = nSectorNum & (SECTOR_PER_BLOCK - 1);
nSectors = (sectornum > (SECTOR_PER_BLOCK - nSectorOffsetInBlock) ?
(SECTOR_PER_BLOCK - nSectorOffsetInBlock) : sectornum);
sIndex = IsBlockInCache(nBlockNum);
// Found!!!
if (sIndex >= 0) {
pstHeader = (NAND_CACHE_HEADER *) (nand_cache_start + (sIndex << 6));
}
// Not Found!!!
else {
cIndex = LRUSearchBlock();
pstHeader = (NAND_CACHE_HEADER *) (nand_cache_start + (cIndex << 6));
if (pstHeader->bDirty) {
NandProgramBlock(pstHeader->pSectorBuf, pstHeader->nBlockNum);
}
pstHeader->bUsed = 1;
pstHeader->nUseCount = 0;
pstHeader->bDirty = 1;
pstHeader->nBlockNum = nBlockNum;
NandReadBlock(pstHeader->pSectorBuf, nBlockNum);
}
NandBufferCopy((UCHAR *) (pstHeader->pSectorBuf + (nSectorOffsetInBlock << 9)), pbyBuf,
nSectors << 9);
pbyBuf += nSectors << 9;
sectornum -= nSectors;
nSectorNum += nSectors;
pstHeader->nTickCount = nand_cache_tick_count++;
pstHeader->nUseCount++;
} while (sectornum > 0);
return (NOERR);
}
// ----------------------------------------------------------------------
/*
//UCHAR printread = 0;
UWORD Exec_ATAPI_Command1() //Writed by zhangjj
{
ULONG tmp = 0;
UCHAR i;
UWORD secnum;
ULONG secindex;
UCHAR opcode;
//ddfor (tmp=0; tmp<10000; tmp++);
opcode = TPBulk_CommandBlock_bAtapi_CommandPackage0;
switch(opcode)
{
//ATAPI read command,read data from NANDFlash
case ATAPI_READ10:
secnum = TPBulk_CommandBlock_bAtapi_CommandPackage7;
secnum <<=8;
secnum |= TPBulk_CommandBlock_bAtapi_CommandPackage8;
//Get the start sector
secindex = TPBulk_CommandBlock_bAtapi_CommandPackage2;
secindex <<=8;
secindex |= TPBulk_CommandBlock_bAtapi_CommandPackage3;
secindex <<=8;
secindex |= TPBulk_CommandBlock_bAtapi_CommandPackage4;
secindex <<=8;
secindex |= TPBulk_CommandBlock_bAtapi_CommandPackage5;
// printk("secindex = %x, secnum = %x\n", secindex, secnum);
// for (i=0; i<32; i++)
// {
// Buffer_Pointer[i] = 0;
// }
ReadSector1(Buffer_Pointer, secindex, secnum);
//if (printread)
// {
// for (i=0; i<12; i++)
// printk("%02x\t", CBWBuf[15+i]);
// printk("\n-------------");
// printread = 0;
// for (i=0; i<32; i++)
// printk("%02x\t", Buffer_Pointer[i]);
// printk("\n");
// }
break;
//ATAPI Write command,Write data to NANDFlash
case ATAPI_WRITE10:
secnum = TPBulk_CommandBlock_bAtapi_CommandPackage7;
secnum <<=8;
secnum |= TPBulk_CommandBlock_bAtapi_CommandPackage8;
//Get the start sector
secindex = TPBulk_CommandBlock_bAtapi_CommandPackage2;
secindex <<=8;
secindex |= TPBulk_CommandBlock_bAtapi_CommandPackage3;
secindex <<=8;
secindex |= TPBulk_CommandBlock_bAtapi_CommandPackage4;
secindex <<=8;
secindex |= TPBulk_CommandBlock_bAtapi_CommandPackage5;
// printk("secindex = %x, secnum = %x\n", secindex, secnum);
// for (i=0; i<12; i++)
// printk("%02x\t", CBWBuf[15+i]);
// printk("\n---------------");
WriteSector1(Buffer_Pointer, secindex, secnum);
// for (i=0; i<32; i++)
// printk("%02x\t", Buffer_Pointer[i]);
// printk("\n");
// printread = 1;
break;
case ATAPI_READFORMATCAPA:
i=0;
Buffer_Pointer[i++] = 0x00;
Buffer_Pointer[i++] = 0x00;
Buffer_Pointer[i++] = 0x00;
Buffer_Pointer[i++] = 0x10;
Buffer_Pointer[i++] = 0x00;
Buffer_Pointer[i++] = 0x00;
Buffer_Pointer[i++] = 0xff;
Buffer_Pointer[i++] = 0x00;
Buffer_Pointer[i++] = 0x01;
Buffer_Pointer[i++] = 0x00;
Buffer_Pointer[i++] = 0x02;
Buffer_Pointer[i++] = 0x00;
Buffer_Pointer[i++] = 0x00;
Buffer_Pointer[i++] = 0x00;
Buffer_Pointer[i++] = 0xff;
Buffer_Pointer[i++] = 0x00;
Buffer_Pointer[i++] = 0x00;
Buffer_Pointer[i++] = 0x00;
Buffer_Pointer[i++] = 0x02;
Buffer_Pointer[i++] = 0x00;
//Buffer_Pointer[i++] = 0xd0;
break;
case ATAPI_RAEDCAPACITY: //需要底层提供读NANDFlash容量的函数
i=0;
Buffer_Pointer[i++] = 0x00;
//Buffer_Pointer[i++] = 0x01;
//Buffer_Pointer[i++] = 0x00;
//Buffer_Pointer[i++] = 0x00;
Buffer_Pointer[i++] = 0x00;
Buffer_Pointer[i++] = 0xff;
Buffer_Pointer[i++] = 0x00;
Buffer_Pointer[i++] = 0x00;
Buffer_Pointer[i++] = 0x00;
Buffer_Pointer[i++] = 0x02;
Buffer_Pointer[i++] = 0x00;
break;
case ATAPI_INQUIRE: //Command 0x12:to request the configuration of the NANDFlash
i=0;
Buffer_Pointer[i++] = 0x00;
Buffer_Pointer[i++] = 0x80;
Buffer_Pointer[i++] = 0x00;
Buffer_Pointer[i++] = 0x01;
Buffer_Pointer[i++] = 0x75;
Buffer_Pointer[i++] = 0x00;
Buffer_Pointer[i++] = 0x00;
Buffer_Pointer[i++] = 0x00;
Buffer_Pointer[i++] = 0x20;
Buffer_Pointer[i++] = 'E';
Buffer_Pointer[i++] = '-';
Buffer_Pointer[i++] = 'W';
Buffer_Pointer[i++] = 'O';
Buffer_Pointer[i++] = 'R';
Buffer_Pointer[i++] = 'L';
Buffer_Pointer[i++] = 'D';
Buffer_Pointer[i++] = 0x20;
Buffer_Pointer[i++] = 'N';
Buffer_Pointer[i++] = 'A';
Buffer_Pointer[i++] = 'N';
Buffer_Pointer[i++] = 'D';
Buffer_Pointer[i++] = '-';
Buffer_Pointer[i++] = 'F';
Buffer_Pointer[i++] = 'L';
Buffer_Pointer[i++] = 'A';
Buffer_Pointer[i++] = 'S';
Buffer_Pointer[i++] = 'H';
Buffer_Pointer[i++] = '1';
Buffer_Pointer[i++] = '.';
Buffer_Pointer[i++] = '0';
Buffer_Pointer[i++] = 0x20;
Buffer_Pointer[i++] = 0x20;
Buffer_Pointer[i++] = 0x33;
Buffer_Pointer[i++] = 0x31;
Buffer_Pointer[i++] = 0x61;
Buffer_Pointer[i++] = 0x59;
break;
case ATAPI_REQUESTSENSE: //Command 0x03:allows the host to request status and sense data from the PocketZip drive.
for( i=0; i<TPBulk_CommandBlock_bAtapi_CommandPackage4; i++ )
{
Buffer_Pointer[i] = 0;
}
Buffer_Pointer[0] = 0x70;
break;
case ATAPI_MODESENSE5A:
Buffer_Pointer[0] = 0;
Buffer_Pointer[1] = 0;
Buffer_Pointer[2] = 0;
Buffer_Pointer[3] = 0;
Buffer_Pointer[4] = 0;
Buffer_Pointer[5] = 0;
Buffer_Pointer[6] = 0;
Buffer_Pointer[7] = 0;
break;
case ATAPI_NONSENSE: //Command 0x06:Non-sense is used to report vendor specific drive and disk data including current status and diagnostic information.
switch(TPBulk_CommandBlock_bAtapi_CommandPackage2)
{ //*****Allocation Length is not used
case 0x00: //Supported Page Codes Page (00h)
//Non-Sense Page Header
Buffer_Pointer[0] = 0;
Buffer_Pointer[1] = 4;
Buffer_Pointer[2] = 0x00;
Buffer_Pointer[3] = 0x01;
Buffer_Pointer[4] = 0x02;
Buffer_Pointer[5] = 0x03;
break;
case 0x01: //Format Data page (Page 01h)
//Non-Sense Page Header
Buffer_Pointer[0] = 1;
Buffer_Pointer[1] = 0x56;
Buffer_Pointer[2] = 0x01;
Buffer_Pointer[3] = 0x00;
Buffer_Pointer[4] = 0x00;
Buffer_Pointer[5] = 0x00;
Buffer_Pointer[6] = 0x00;
Buffer_Pointer[7] = 0x00;
Buffer_Pointer[8] = 0x00;
Buffer_Pointer[9] = 0x00;
Buffer_Pointer[10] = 0x00; //-
Buffer_Pointer[11] = 0x00; //w
Buffer_Pointer[12] = 0x00; //o
Buffer_Pointer[13] = 0x00; //r
Buffer_Pointer[14] = 0x00; //l
Buffer_Pointer[15] = 0x00; //d
Buffer_Pointer[16] = 0x00;
break;
case 0x02: //Cartridge Status page (Page 02h)
//Non-Sense Page Header
Buffer_Pointer[0] = 2;
Buffer_Pointer[1] = 62;
Buffer_Pointer[2] = 0x00;
Buffer_Pointer[3] = 0x01;
Buffer_Pointer[4] = 0x00;
Buffer_Pointer[5] = 0x00;
Buffer_Pointer[6] = 0x00;
Buffer_Pointer[7] = 0x00;
Buffer_Pointer[8] = 0x00;
Buffer_Pointer[9] = 0x00;
Buffer_Pointer[10] = 0x00; //-
Buffer_Pointer[11] = 0x02; //w
Buffer_Pointer[12] = 0x00; //o
Buffer_Pointer[13] = 0x00; //r
Buffer_Pointer[14] = 0x00; //l
Buffer_Pointer[15] = 0x00; //d
Buffer_Pointer[16] = 0x00;
Buffer_Pointer[17] = 0x00;
Buffer_Pointer[18] = 0x00;
Buffer_Pointer[29] = 0x00;
Buffer_Pointer[20] = 0x00;
for( i=21; i<64; i++ )
{
Buffer_Pointer[i] = 0;
}
break;
}
case ATAPI_MODESELECT55: //Command 0x15:Mode Select(0x15),specify media or device parameters
break; //Is not use to NANDFalsh
case ATAPI_TESTUNIT: //Command 0x00:Test unit Ready tests the readiness of the drive for disk access.
for( i=0; i<TPBulk_CommandBlock_bAtapi_CommandPackage4; i++ )
{
Buffer_Pointer[i] = 0;
}
break;
case 0x1e: //Command 0x00:Test unit Ready tests the readiness of the drive for disk access.
for( i=0; i<TPBulk_CommandBlock_bAtapi_CommandPackage4; i++ )
{
Buffer_Pointer[i] = 0;
}
break;
case 0x2f: ////Command 0x2f: Verify Packet Command confirms that the drive wrote the data correctly in the requested LBAs.
//for (i=0; i<12; i++)
// printf("%02x\t", CBWBuf[15+i]);
//printf("\n");
break; //Is not use to NANDFalsh
}
return 0;
}
*/
// That's all
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -