📄 nflash.c
字号:
#endif
#endif//NORBOOT
#endif
chip_ID = nfshReadID() ;
current_nand_chip = (&flash_table[cou++]) ;
while (current_nand_chip->device_ID !=0)
{
if (chip_ID == current_nand_chip->device_ID)
break ;
current_nand_chip = (&flash_table[cou++]) ;
}
return current_nand_chip->total_size ;
}
void read_ecc(unsigned long offset)
{
unsigned char ecc_data[16] ;
unsigned short kk ;
NFLASH_ENB_CE;
__DELAY();
nfshCommandLatch(NFLASH_READ2);/* 1st half of register */
nfshAddressLatch(offset);
check_busy();
nfshReadSpareLatch(ecc_data);
NFLASH_DIS_CE;
}
void write_ecc(unsigned long offset)
{
unsigned char ecc_data[16] ;
unsigned short kk ;
for (kk=0;kk<16;kk++)
ecc_data[kk] = kk ;
NFLASH_ENB_CE;
__DELAY();
nfshCommandLatch(NFLASH_READ2); /* 1st half of register */
nfshCommandLatch(NFLASH_FRAME_PROGRAM0);
nfshAddressLatch(offset);
nfshWriteSpareLatch(ecc_data);
nfshCommandLatch(NFLASH_FRAME_PROGRAM1);
check_busy();
NFLASH_DIS_CE;
}
int nfshReadSpareOfFrame(unsigned long offset, unsigned char data[])
{
offset &= 0xFFFFFE00;
NFLASH_ENB_CE;
__DELAY();
nfshCommandLatch(NFLASH_READ2);/* 1st half of register */
nfshAddressLatch(offset);
check_busy();
nfshReadSpareLatch(data);
NFLASH_DIS_CE;
return NFLASH_OK;//OK
}
int nfshWriteSpareOfFrame(unsigned long offset, unsigned char data[])
{
unsigned char status;
offset &= 0xFFFFFE00;
NFLASH_ENB_CE;
__DELAY();
nfshCommandLatch(NFLASH_READ2);/* 1st half of register */
nfshCommandLatch(NFLASH_FRAME_PROGRAM0);
nfshAddressLatch(offset);
nfshWriteSpareLatch(data);
nfshCommandLatch(NFLASH_FRAME_PROGRAM1);
check_busy();
status = nfshStatusRead();
NFLASH_DIS_CE;
return (int)((status & NFLASH_PROGRAM_SUCCESS)?NFLASH_FAIL:NFLASH_OK);
}
int nfshReadBlockAddr(unsigned long offset, unsigned char data[])
{
register int i;
offset = (offset & 0xFFFFFE00) | 0x00000006;/* Block address area-1 */
NFLASH_ENB_CE;
__DELAY();
nfshCommandLatch(NFLASH_READ2);/* 1st half of register */
nfshAddressLatch(offset);
check_busy();
data[0] = NFLASH_DATA_READ;/* Big Endian */
data[1] = NFLASH_DATA_READ;
NFLASH_DIS_CE;
return NFLASH_OK;//OK
}
int nfshWriteBlockAddr(unsigned long offset, unsigned char data[])
{
unsigned char status;
offset = (offset & 0xFFFFFE00) | 0x00000006;/* Block address area-1 */
NFLASH_ENB_CE;
__DELAY();
nfshCommandLatch(NFLASH_READ2);/* 1st half of register */
nfshCommandLatch(NFLASH_FRAME_PROGRAM0);
nfshAddressLatch(offset);
NFLASH_DATA_WRITE = data[0];/* Big Endian */
NFLASH_DATA_WRITE = data[1];
NFLASH_DATA_WRITE = 0xFF;/* Dummy */
NFLASH_DATA_WRITE = 0xFF;
NFLASH_DATA_WRITE = 0xFF;
NFLASH_DATA_WRITE = data[0]; /* Block address area-2 */
NFLASH_DATA_WRITE = data[1];
/* We must write until reaching the end of Spare space, I don't know why??? */
NFLASH_DATA_WRITE = 0xFF;/* Dummy */
NFLASH_DATA_WRITE = 0xFF;
NFLASH_DATA_WRITE = 0xFF;
nfshCommandLatch(NFLASH_FRAME_PROGRAM1);
check_busy();
status = nfshStatusRead();
NFLASH_DIS_CE;
return (int)((status & NFLASH_PROGRAM_SUCCESS)?NFLASH_FAIL:NFLASH_OK);
}
int nfshReadFrame(unsigned long offset, unsigned char data[])
{
unsigned char ecc_data[16] ;
unsigned char gen_ecc[3] ;
if (offset> current_nand_chip->total_size)
return NFLASH_FAIL;
NFLASH_ENB_CE;
__DELAY();
if ( offset & 0x00000100 )
nfshCommandLatch(NFLASH_READ1);/* 2nd half of register */
else
nfshCommandLatch(NFLASH_READ0);/* 1st half of register */
nfshAddressLatch(offset);
check_busy();
nfshReadDataLatch(data);
#ifdef ECC_DEBUG
nfshCommandLatch(NFLASH_READ2);/* 1st half of register */
nfshAddressLatch(offset);
check_busy();
nfshReadSpareLatch(ecc_data);
ecc_gen(data ,gen_ecc ) ;
{
extern unsigned char disp_flash_flag ;
if (disp_flash_flag!=0)
{
if ( offset & 0x00000100 )
{
if((ecc_data[8]!=gen_ecc[0])||(ecc_data[9]!=gen_ecc[1])||(ecc_data[10]!=gen_ecc[2]))
disp_flash_flag++ ;
}
else
{
/* 1st half of register */
if((ecc_data[13]!=gen_ecc[0])||(ecc_data[14]!=gen_ecc[1])||(ecc_data[15]!=gen_ecc[2]))
disp_flash_flag++ ;
}
}
}
#endif
NFLASH_DIS_CE;
return NFLASH_OK; //Sean Fri 06-21-2002
}
int nfshSeqRead(unsigned long offset, unsigned char *data, unsigned int blockNo)
{
seqAddr = data;
for (seqOut=0;seqOut<blockNo; seqOut++)
{
NFLASH_ENB_CE;
__DELAY();
nfshCommandLatch(NFLASH_READ0);/* 1st half of register */
nfshAddressLatch(offset+(seqOut*528*32));
for (seqIn=0;seqIn<current_nand_chip->block_size;seqIn++)
{
check_busy();
nfshReadDataLatchSeq(seqAddr);
seqAddr += NFLASH_FRAME_SIZE;
}
}
}
int nfshProgramFrame(unsigned long offset, unsigned char data[])
{
unsigned char status;
unsigned char ecc_data[16] ,gen_ecc[3] ;
if (offset> current_nand_chip->total_size)
return NFLASH_FAIL;
NFLASH_ENB_CE;
__DELAY();
if ( offset & 0x00000100 )
nfshCommandLatch(NFLASH_READ1);/* 2nd half of register */
else
nfshCommandLatch(NFLASH_READ0);/* 1st half of register */
nfshCommandLatch(NFLASH_FRAME_PROGRAM0);
nfshAddressLatch(offset);
nfshInputDataLatch(data);
nfshCommandLatch(NFLASH_FRAME_PROGRAM1);
check_busy();
#ifdef ECC_DEBUG
nfshCommandLatch(NFLASH_READ2);/* 1st half of register */
nfshAddressLatch(offset);
check_busy();
nfshReadSpareLatch(ecc_data);
ecc_gen(data ,gen_ecc ) ;
if ( offset & 0x00000100 )
{
/* 2nd half of register */
ecc_data[8] = gen_ecc[0] ;
ecc_data[9] = gen_ecc[1] ;
ecc_data[10]= gen_ecc[2] ;
}
else
{
/* 1st half of register */
ecc_data[13] = gen_ecc[0] ;
ecc_data[14] = gen_ecc[1] ;
ecc_data[15] = gen_ecc[2] ;
}
// write ECC data
nfshCommandLatch(NFLASH_READ2); /* 1st half of register */
nfshCommandLatch(NFLASH_FRAME_PROGRAM0);
nfshAddressLatch(offset);
nfshWriteSpareLatch(ecc_data);
nfshCommandLatch(NFLASH_FRAME_PROGRAM1);
check_busy();
#endif
status = nfshStatusRead();
NFLASH_DIS_CE;
return (int)((status & NFLASH_PROGRAM_SUCCESS)?NFLASH_FAIL:NFLASH_OK);
}
// Return value 0: erase ok; 1: invalid block, could not erase
int nfshEraseBlock(unsigned long offset)
{
unsigned char status;//Sean
if (offset> current_nand_chip->total_size)
{
return NFLASH_FAIL;
}
if ( current_nand_chip->block_size > 8*1024 )
offset &= 0xFFFFC000;
else
offset &= 0xFFFFE000; // for 8 k Block address , jason
if ( nfshCheckBadBlock(offset) == NFLASH_FAIL )
return NFLASH_FAIL;
NFLASH_ENB_CE;
__DELAY();
nfshCommandLatch(NFLASH_BLOCK_ERASE0);
nfshBlockAddressLatch(offset);
nfshCommandLatch(NFLASH_BLOCK_ERASE1);
check_busy();
status = nfshStatusRead();
NFLASH_DIS_CE;
return (int)((status & NFLASH_PROGRAM_SUCCESS)?NFLASH_FAIL:NFLASH_OK);
// NFLASH_DIS_CE;
// return 1;
}
// Return value 0: erase ok; 1: invalid block, could not erase
/* Don't care anything, just erase all, it is dangerous */
int nfshEraseAllBlock( void )
{
unsigned char status;//Sean
unsigned long offset = 0;
int i;
while ( offset <= current_nand_chip->total_size )
{
NFLASH_ENB_CE;
__DELAY();
nfshCommandLatch(NFLASH_BLOCK_ERASE0);
nfshBlockAddressLatch(offset);
nfshCommandLatch(NFLASH_BLOCK_ERASE1);
check_busy();
status = nfshStatusRead();
NFLASH_DIS_CE;
if ( status & NFLASH_PROGRAM_SUCCESS )
return NFLASH_FAIL;
offset += NAND_FLASH_BLOCK_SIZE;
}
}
// Return value 0: erase ok; 1: invalid block, could not erase
/* Don't care anything, just erase all, it is dangerous */
int nfshErasePartBlock( unsigned int address )
{
unsigned char status;//gk 2005-3-21 16:55
unsigned long offset = address;
int i;
while ( offset <= current_nand_chip->total_size )
{
NFLASH_ENB_CE;
__DELAY();
nfshCommandLatch(NFLASH_BLOCK_ERASE0);
nfshBlockAddressLatch(offset);
nfshCommandLatch(NFLASH_BLOCK_ERASE1);
check_busy();
status = nfshStatusRead();
NFLASH_DIS_CE;
if ( status & NFLASH_PROGRAM_SUCCESS )
return NFLASH_FAIL;
offset += NAND_FLASH_BLOCK_SIZE;
}
}
/* thhuang, 2002/7/4 , add for bad block check */
int nfshCheckBadBlock(unsigned long offset)
{
unsigned char data;
/* Check the Block status flag of second page */
if ( current_nand_chip->block_size > 8*1024 )
offset = (offset & 0xFFFFC000) | 0x00000005;/* Block status flag */
else
offset = (offset & 0xFFFFE000) | 0x00000005;/* Block status flag */
NFLASH_ENB_CE;
__DELAY();
nfshCommandLatch(NFLASH_READ2);/* 1st half of register */
nfshAddressLatch(offset);
check_busy();
data = NFLASH_DATA_READ;
if ( data!= 0xFF )/* More than two zero */
// if ( CountZero(data) >= 1 )/* More than two zero */
{
NFLASH_DIS_CE;
return NFLASH_FAIL;
}
/* Check the Block status flag of second page */
offset += NFLASH_FRAME_SIZE;/* 2nd */
nfshCommandLatch(NFLASH_READ2);/* 1st half of register */
nfshAddressLatch(offset);
check_busy();
data = NFLASH_DATA_READ;
NFLASH_DIS_CE;
if ( data!= 0xFF )/* More than two zero */
// if ( CountZero(data) >= 1 )/* More than two zero */
return NFLASH_FAIL;
else
return NFLASH_OK;
}
/* thhuang, 2002/11/15 , add for bad block write */
int nfshWriteBadBlock(unsigned long offset)
{
int i;
unsigned char data[16];
for ( i=0;i<16;i++)
data[i] = 0xff;
data[5] = 0;
/* Write Bad Block flag on first page */
offset &= 0xFFFFE000;
if ( nfshWriteSpareOfFrame( offset, data ) == NFLASH_FAIL )
return NFLASH_FAIL;
/* Write Bad Block flag on second page */
return (nfshWriteSpareOfFrame( offset+NFLASH_FRAME_SIZE, data ));
}
/* End of thhuang, 2002/1/8 , add for bad block check */
int nfshReadID()
{
unsigned char c1, c2;
NFLASH_ENB_CE;
__DELAY();
nfshCommandLatch(NFLASH_READ_ID);
#ifndef AR2000
NFLASH_ALE_HIGH;
#endif
NFLASH_ALE = 0x00;
#ifndef AR2000
NFLASH_ALE_LOW;
#endif
c1 = NFLASH_DATA_READ;
c2 = NFLASH_DATA_READ;
NFLASH_DIS_CE;
return((c1<<8) | c2);
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -