新闻  |   论坛  |   博客  |   在线研讨会
samsung 的flash芯片k9f1208的读写操作
mayer | 2009-06-25 18:30:49    阅读:2179   发布文章

 

nand flash芯片是k9f1208,它的读写操作、包括块擦除函数如下所示:

//addr = page address 参数addr是页对齐的地址,每个页是512个字节

U32 EraseBlock(U32 addr)
{
 U8 stat;

 addr &= ~0x1f;
  
 NFChipEn(); 
 WrNFCmd(ERASECMD0);  
 WrNFAddr(addr);
 WrNFAddr(addr>>8);
 if(NandAddr)
  WrNFAddr(addr>>16);
 WrNFCmd(ERASECMD1);  
 stat = WaitNFBusy();
 NFChipDs();
 
#ifdef ER_BAD_BLK_TEST
 if(!((addr+0xe0)&0xff)) stat = 1; //just for test bad block
#endif
 
 //printf("Erase block 0x%x %s\n", addr, stat?"fail":"ok");
 putch('.');
 return stat;
}

 

//addr = page address
void ReadPage(U32 addr, U8*buf)
{
 U16 i;
 //printf("read page %x",addr);
 NFChipEn();
 WrNFCmd(READCMD0);
 WrNFAddr(0);
 WrNFAddr(addr);
 WrNFAddr(addr>>8);
 if(NandAddr)
  WrNFAddr(addr>>16);
 InitEcc();
 WaitNFBusy();
 for(i=0; i<512; i++)
  buf[i] = RdNFDat();
 NFChipDs();
}
void ReadSpare(U32 addr, U8*buf)
{
   
 //U8 dat;
 U8 i;
 //printf("read spare %x",addr);
 //addr &= ~0x1f;
 
 NFChipEn();
 
 WrNFCmd(READCMD2); //point to area c
 WrNFAddr(0);  //mark offset 0~15
 WrNFAddr(addr);
 WrNFAddr(addr>>8);
 if(NandAddr)
  WrNFAddr(addr>>16);
 WaitNFBusy();
    for(i=0;i<16;i++){
  buf[i] = RdNFDat();
     
    }
 WrNFCmd(READCMD0); //point to area a
 
 NFChipDs();

 //return (dat!=0xff);
}

写页内容的函数,除了对512个字节操作以外,还对于16个spare的字节做了操作,可以根据自己的要求决定是否包含对spare的操作。
U32 WritePage(U32 addr, const U8 *buf, U16 blk_idx)
{
 U16 i;
 U8 stat;
 U8 ecc_code[3];
 U8 oob_info[16];
 //printf("write page %x",addr); 
 for(i=0; i<sizeof(oob_info); i++)
  oob_info[i] = 0xff;
 
 nand_calculate_ecc(buf, ecc_code);
 oob_info[eccpos[0]] = ecc_code[0];
 oob_info[eccpos[1]] = ecc_code[1];
 oob_info[eccpos[2]] = ecc_code[2];
 nand_calculate_ecc(buf+256, ecc_code);
 oob_info[eccpos[3]] = ecc_code[0];
 oob_info[eccpos[4]] = ecc_code[1];
 oob_info[eccpos[5]] = ecc_code[2];
 oob_info[BLK_IDXL]  = blk_idx;
 oob_info[BLK_IDXH]  = blk_idx>>8;
 oob_info[FMT_TAG]   = format_tags[addr&0x1f];
 
 NFChipEn();
 WrNFCmd(PROGCMD0);
 WrNFAddr(0);
 WrNFAddr(addr);
 WrNFAddr(addr>>8);
 if(NandAddr)
  WrNFAddr(addr>>16);
// InitEcc(); 
 for(i=0; i<512; i++)
  WrNFDat(buf[i]);
  
 /*if(!addr) {
  WrNFDat('b');
  WrNFDat('o');
  WrNFDat('o');
  WrNFDat('t');  
 } else {  
  for(i=0; i<sizeof(oob_info); i++)
   WrNFDat(oob_info[i]);
 }*/
/* tmp[0] = rNFECC0;
    tmp[1] = rNFECC1;
    tmp[2] = rNFECC2;
     
 WrNFDat(tmp[0]);
 WrNFDat(tmp[1]);
 WrNFDat(tmp[2]);
*/  
 WrNFCmd(PROGCMD1);
 stat = WaitNFBusy();
 NFChipDs();
 
#ifdef WR_BAD_BLK_TEST
 if((addr&0xff)==0x17) stat = 1; //just for test bad block
#endif
  
 if(stat)
  printf("Write nand flash 0x%x fail\n", addr);
 else { 
  U8 RdDat[512];
  
  ReadPage(addr, RdDat);  
  for(i=0; i<512; i++)
   if(RdDat[i]!=buf[i]) {
    printf("Check data at page 0x%x, offset 0x%x fail\n", addr, i);
    stat = 1;
    break;
   }
 }
  
 return stat; 
}
void WriteSpare(U32 addr,const U8* buf)
{
    int i;
 //addr &= ~0x1f;
 //printf("write spare %x",addr);
 NFChipEn();
 
 WrNFCmd(READCMD2); //point to area c
 
 WrNFCmd(PROGCMD0);
 WrNFAddr(0);  //mark offset 0
 WrNFAddr(addr);
 WrNFAddr(addr>>8);
 if(NandAddr)
  WrNFAddr(addr>>16);
 for(i=0;i<16;i++){
  WrNFDat(buf[i]);
 }

 //WrNFDat(0);   //mark with 0
 //WrNFDat(0);
 //WrNFDat(0);   //mark with 0
 //WrNFDat(0);
 WrNFCmd(PROGCMD1);
 WaitNFBusy();  //needn't check return status
 
 WrNFCmd(READCMD0); //point to area a
  
 NFChipDs();
}

*博客内容为网友个人发布,仅代表博主个人观点,如有侵权请联系工作人员删除。

参与讨论
登录后参与讨论
推荐文章
最近访客