nandflash ID 读取错误
我使用的是三星的k9f1208uoc ID本应是ec76,结果我每次读到的都不一样,没有一次正确,没有规律可言。仔细检查了程序的流程感觉没有问题。程序如下:int TreadFlashID ( void)
{
unsigned char vendorId_p=0, chipId_p=0,i;
int a;
TflashInit();
NAND_ENABLE_CE();
a =(*(volatile UINT32 *) AT91C_PIOC_PDSR )& AT91C_PIO_PC15 ;
printf("CE=0x%x\n",a);
WRITE_COMMAND(RESET_FLASH);
for(i=0;i<10;i++);
TwaitForReady();
WRITE_COMMAND(READ_ID);
WRITE_ADDRESS(0x00);/* Address. 1cycle */
for(i=0;i<100;i++);
vendorId_p=TREAD_DATA();/* EC */
printf("vendorId_p=0x%x\n",vendorId_p);
chipId_p=TREAD_DATA(); /* 76 */
printf("chipId_p=0x%x\n",chipId_p);
if ((vendorId_p == 0xec)&&(chipId_p==0x76))/* Samsung */
{
printf("K9F1208UOM ID is 0xec76!");
}
else
{printf("flash is not recongnized!");
NAND_DISABLE_CE();
return FALSE;
}
NAND_DISABLE_CE();
return TRUE ;
}
查看打印信息,片选都没有问题,处理器是9200,基地址是0x40000000,那位仁兄指点下小弟,不胜感激!! 读ID比较简单的啊,
如果确认程序没有问题,看看硬件连线。或者芯片是否坏了。 注意:操作flash的时候,程序必须不能在flash运行,不然肯定不能正确操作flash 读ID比较简单的啊,
如果确认程序没有问题,看看硬件连线。或者芯片是否坏了。
gooogleman 发表于 2009-9-12 14:24 https://bbs.21ic.com/images/common/back.gif走哪儿都看到你!-|- 哈哈“走哪儿都看到你!-|-” 还是看看芯片有没有问题和nand的时序有没有配置正确吧 请问楼主问题解决了吧
小弟也遇到这个问题,读到的ID是全 0 本帖最后由 nicholasldf 于 2011-4-11 13:47 编辑
这是我的驱动程序,CPU为atmel的ARM9芯片9260,要注意一下接口的参数,CPU和NandFlash芯片的速度匹配::)
//*----------------------------------------------------------------------------
//* AT91NandFlash_initialise
//*----------------------------------------------------------------------------
int AT91NandFlash_initialise(struct yaffs_dev *dev)
{
/* SMC init - 在汇编代码配置向导中设置读写时序 */
//BOARD_ConfigureNandFlash(8);
//CS Pio Init
AT91_NAND_PIO_CS->IO_PER= AT91_NAND_PIN_CS;//PIO Enable Register
AT91_NAND_PIO_CS->IO_OER= AT91_NAND_PIN_CS;//Output Enable Register
AT91_NAND_PIO_CS->IO_SODR = AT91_NAND_PIN_CS;//Set Output Data Register
//Ready/Busy Pio Init
AT91_NAND_PIO_BUSY->IO_PER= AT91_NAND_PIN_BUSY;//PIO Enable Register
AT91_NAND_PIO_BUSY->IO_ODR= AT91_NAND_PIN_BUSY;//Output Disable Registerr
//reset
AT91NandFlash_Reset();
//check device id - 0xEC76A5C0 or 0xEC765A3F
//it should be samsung k9f1208 device
if(NAND_DEVICE_ID != (0xFFFF0000 & AT91NandFlash_rd_id())){
Debug_Printf(ARM_INTERNAL_UNIT, LOG_ERROR, "NandFlash : read device id failed\n\r");
return YAFFS_FAIL;
}
//Check Device Status Register - 0xC0
if(STATUS_REGISTER_VALUE != AT91NandFlash_rd_status()){
Debug_Printf(ARM_INTERNAL_UNIT, LOG_ERROR, "NandFlash : Status Register Wrong(not %x)\n\r", STATUS_REGISTER_VALUE);
return YAFFS_FAIL;
}else{
return YAFFS_OK;
}
}
//*----------------------------------------------------------------------------
//* AT91F_NandFlash_Reset
//* The device offers a reset feature, executed by writing FFh to the command
//* register. When the device is in Busy state during random read, program or
//* erase mode, the reset operation will abort these operations. The contents
//* of memory cells being altered are no longer valid, as the data will be
//* partially programmed or erased. The command register is cleared to wait
//* for the next command, and the Status Register is cleared to value C0h when
//* WP is high. If the device is already in reset state a new reset command
//* will not be accepted by the command register. The R/B pin transitions to
//* low for tRST after the Reset command is written.
//*----------------------------------------------------------------------------
void AT91NandFlash_Reset(void)
{
NAND_ENABLE_CE();//Enable the NAND Flash device
WRITE_NAND_COMMAND(NAND_CMD_RESET);
//Device Resetting Time(Read/Program/Erase) tRST - 5/10/500uS
OSTimeDlyHMSM(0, 0, 0, 10);//10mS
NAND_WAIT_READY();//Wait for Read/Busy Signal assertion
NAND_DISABLE_CE();//Disable the NAND Flash device
}
//*----------------------------------------------------------------------------
//* AT91NandFlash_rd_id - 0xEC76A5C0 or 0xEC765A3F
//*----------------------------------------------------------------------------
unsigned int AT91NandFlash_rd_id(void)
{
unsigned int DeviceID;
NAND_ENABLE_CE();//Enable the NAND Flash device
// Write the Read ID Command
WRITE_NAND_COMMAND(NAND_CMD_READID);
//Write the Address
WRITE_NAND_ADDRESS(0x00);
//ALE to RE Delay( ID read ) tAR1 10 - ns
//WE High to RE Low tWHR 60 - ns
delay_ns(100);
DeviceID <<= 8;
DeviceID |= READ_NAND();
DeviceID <<= 8;
DeviceID |= READ_NAND();
DeviceID <<= 8;
DeviceID |= READ_NAND();
DeviceID <<= 8;
DeviceID |= READ_NAND();
NAND_DISABLE_CE();//Disable the NAND Flash device
return DeviceID;//should be 0xEC76A5C0 or 0xEC765A3F
}
//*----------------------------------------------------------------------------
//* AT91NandFlash_rd_status
//*----------------------------------------------------------------------------
unsigned char AT91NandFlash_rd_status(void)
{
unsigned char status;
NAND_ENABLE_CE();//Enable the NAND Flash device
WRITE_NAND_COMMAND(NAND_CMD_STATUS);//Status Command
//WE High to RE Low tWHR 60 - ns
//CLE to RE Delay tCLR 50 - ns
delay_ns(100);
//bit7 bit6 bit5 bit4 bit3 bit2 bit1 bit0
//NWP(1)Ready(1) - - - - - Pass(0)
status = READ_NAND();//should be 0xC0
NAND_DISABLE_CE();//Disable the NAND Flash device
return status;
}
//*----------------------------------------------------------------------------
//* identifying bad block(s)
//* All device locations are erased(FFh) except locations where the invalid block(s)
//* information is written prior to shipping. The invalid block(s) status is defined
//* by the 6th byte in the spare area. Samsung makes sure that either the 1st or 2nd
//* page of every invalid block has non-FFh data at the Byte address of 517. Since
//* the invalid block information is also erasable in most cases, it is impossible to
//* recover the information once it has been erased. Therefore, the system must be
//* able to recognize the invalid block(s) based on the original invalid block
//* information and create the invalid block table via the following suggested flow
//* chart(Figure 1). Any intentional erasure of the original invalid block
//* information is prohibited.
//*----------------------------------------------------------------------------
unsigned int AT91NandFlash_Identify_Bad_Block(int blockNumber)
{
struct yaffs_spare spare;
unsigned char BlockStatus1;
unsigned char BlockStatus2;
AT91NandFlash_rd_chunk(NULL, blockNumber * NAND_PAGES_PER_BLOCK, NULL, &spare);
BlockStatus1 = spare.block_status;
//CE High Hold Time(at the last serial read) tCEH 100 - ns
delay_ns(100);
AT91NandFlash_rd_chunk(NULL, blockNumber * NAND_PAGES_PER_BLOCK + 1, NULL, &spare);
BlockStatus2 = spare.block_status;
if( (0xFF != BlockStatus1) || (0xFF != BlockStatus2) ){
return YAFFS_FAIL;
}else{
return YAFFS_OK;
}
}
//*----------------------------------------------------------------------------
//* AT91NandFlash_erase_block
//*----------------------------------------------------------------------------
int AT91NandFlash_erase_block(struct yaffs_dev *dev, int blockNumber)
{
/* Block address loading is accomplished in three cycles initiated by an
Erase Setup command(60h). Only address A14 to A26 is valid while A9 to A13
is ignored. */
blockNumber <<= 5;//5 bit page address offset
NAND_ENABLE_CE(); // Enable the NAND Flash device
WRITE_NAND_COMMAND(NAND_CMD_ERASE1);//Erase Command 1
WRITE_NAND_ADDRESS(blockNumber);//block address
WRITE_NAND_ADDRESS(blockNumber >> 8);//block address
WRITE_NAND_ADDRESS(blockNumber >> 16);//block address
WRITE_NAND_COMMAND(NAND_CMD_ERASE2);//Erase Command 2
//WE High to Busy tWB - 100 ns
//Block Erase Time tBERS - 2-3 ms
delay_us(100);
NAND_WAIT_READY();//Wait for Read/Busy Signal assertion
delay_us(2);
NAND_WAIT_READY();//Wait for Read/Busy Signal assertion
NAND_DISABLE_CE();//Disable the NAND Flash device
delay_us(1);
if(AT91NandFlash_rd_status() & STATUS_BIT0_PASS_OR_FAIL){
return YAFFS_FAIL;
}else{
return YAFFS_OK;
}
}
//*----------------------------------------------------------------------------
//* AT91NandFlash_format
//*----------------------------------------------------------------------------
void AT91NandFlash_format(void)
{
unsigned int i;
unsigned int ret = YAFFS_FAIL;
for(i=0; i < NAND_TOTAL_BLOCKS; i++){
//if(YAFFS_OK == AT91NandFlash_Identify_Bad_Block(i))
ret = AT91NandFlash_erase_block(NULL, i);
if(YAFFS_FAIL == ret)
Debug_Printf(ARM_INTERNAL_UNIT, LOG_ERROR, "NandFlash : Block(%d) erase failed\n\r", i);
}
}
//*----------------------------------------------------------------------------
//* AT91NandFlash_List_Bad_Block
//*----------------------------------------------------------------------------
void AT91NandFlash_List_Bad_Block(void)
{
unsigned int i;
for(i=0; i < NAND_TOTAL_BLOCKS; i++){
if(YAFFS_FAIL == AT91NandFlash_Identify_Bad_Block(i))
Debug_Printf(ARM_INTERNAL_UNIT, LOG_ERROR, "NandFlash : Find Bad Block(%d)\n\r", i);
}
} 我今天也遇到这个问题,开始读出02,02后面读出来的就是00,00了,但是我的擦除操作确实正确的。不过好像芯片ID并不代表芯片的好坏哦,即使读不出正确的芯片ID,好像芯片也不能说明是坏的…… 我怎么用smart arm 2200的程序读出来ID为0xff,有没有遇到类似情况的
页:
[1]