打印

nandflash ID 读取错误

[复制链接]
7472|9
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
meadow163|  楼主 | 2009-9-9 21:06 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
我使用的是三星的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,那位仁兄指点下小弟,不胜感激!!

相关帖子

沙发
gooogleman| | 2009-9-12 14:24 | 只看该作者
读ID比较简单的啊,
如果确认程序没有问题,看看硬件连线。或者芯片是否坏了。

使用特权

评论回复
板凳
usecoolful| | 2009-9-13 20:49 | 只看该作者
注意:操作flash的时候,程序必须不能在flash运行,不然肯定不能正确操作flash

使用特权

评论回复
地板
cqhtk| | 2009-9-14 17:27 | 只看该作者
读ID比较简单的啊,
如果确认程序没有问题,看看硬件连线。或者芯片是否坏了。
gooogleman 发表于 2009-9-12 14:24
走哪儿都看到你!-|-

使用特权

评论回复
5
czdo| | 2009-9-14 17:29 | 只看该作者
哈哈“走哪儿都看到你!-|-”

使用特权

评论回复
6
woncf| | 2009-9-15 10:05 | 只看该作者
还是看看芯片有没有问题和nand的时序有没有配置正确吧

使用特权

评论回复
7
jutyy| | 2011-4-8 00:02 | 只看该作者
请问楼主问题解决了吧
小弟也遇到这个问题,读到的ID是全 0

使用特权

评论回复
8
nicholasldf| | 2011-4-11 13:45 | 只看该作者
本帖最后由 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);        
        }
}

使用特权

评论回复
9
ji_dan| | 2012-3-8 19:27 | 只看该作者
我今天也遇到这个问题,开始读出02,02后面读出来的就是00,00了,但是我的擦除操作确实正确的。不过好像芯片ID并不代表芯片的好坏哦,即使读不出正确的芯片ID,好像芯片也不能说明是坏的……

使用特权

评论回复
10
lsszl| | 2012-7-8 16:54 | 只看该作者
我怎么用smart arm 2200的程序读出来ID为0xff,有没有遇到类似情况的

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

7

主题

9

帖子

0

粉丝