예제 #1
0
static int nandll_read_page(unsigned char *buf, unsigned long addr, int large_block)
{
	int i;
	int page_size = 512;

	if (large_block)
		page_size = 2048;

	show("in this fucn\n");
	NF_ENABLE_CE;
	NF_CLEAR_RB;

    NF_CMD(NAND_CMD_READ0);

	NF_ADDR(0x0);
	if (large_block)
		NF_ADDR(0x0); 				/*从0x0地址开始拷贝*/
	NF_ADDR(addr & 0xff);
	NF_ADDR((addr >> 8) & 0xff);
	NF_ADDR((addr >> 16) & 0xff);

    if (large_block)
	    NF_CMD(NAND_CMD_READSTART);

    NF_DETECT_RB;

	for (i = 0; i < page_size; i++)
		buf[i] =  NF_RDDATA8;

	NF_DISABLE_CE;

	return 0;
}
예제 #2
0
파일: nand.c 프로젝트: cyj1988jyc/2440-test
static void rLB_ReadPage(U32 addr, unsigned char * to)
{
	U32 i;

	rNF_Reset();

	//  Enable the chip
	NF_nFCE_L();   
	NF_CLEAR_RB();

	// Issue Read command
	NF_CMD(CMD_READ);

	//  Set up address
	NF_ADDR(0x00);
	NF_ADDR(0x00);
	NF_ADDR((addr) & 0xff);
	NF_ADDR((addr >> 8) & 0xff);
	NF_ADDR((addr >> 16) & 0xff);

	NF_CMD(CMD_READ3);

	NF_DETECT_RB();		// wait tR(max 12us)

	for (i = 0; i < 2048; i++)
	{
		to[i] =  NF_RDDATA8();
	}

	NF_nFCE_H();

}
예제 #3
0
파일: armboot.c 프로젝트: paulhsu/sbl24x0
static int NAND_WritePage(unsigned long block,unsigned long page,unsigned char *buffer)  //?Flash 
{
    int i;
    unsigned long blockPage=(block<<5)+page;
    //NF_RSTECC();                              // Initialize ECC    
    unsigned volatile short *NFCONF;
    unsigned volatile short *NFCMD;
    unsigned volatile short *NFSTAT;
    unsigned volatile short *NFADDR;
    unsigned volatile short *NFDATA;

    NFCONF=(unsigned short *)0x4e000000;
    NFCMD=(unsigned short *)0x4e000004;
    NFSTAT=(unsigned short *)0x4e000010;
    NFDATA=(unsigned short *)0x4e00000C;
    NFADDR=(unsigned short *)0x4e000008;

    NF_nFCE_L(); 
    NF_CMD(0x0);                            //?????\\Read Mode 1
    NF_CMD(0x80);                               // Write 1st command,?Õu?¤J
    NF_ADDR(0);                                 // Column 0
    NF_ADDR(blockPage&0xff);        
    NF_ADDR((blockPage>>8)&0xff);               // Block & page num.
    NF_ADDR((blockPage>>16)&0xff);  

    for(i=0;i<512;i++)
    {
        NF_WRDATA(*buffer++);                    // Write one page to NFM from buffer
    }  
#if 0
    seBuf[0]=rNFECC0;
    seBuf[1]=rNFECC1;
    seBuf[2]=rNFECC2;
    seBuf[5]=0xff;                          // Marking good block  

    for(i=0;i<16;i++)
        NF_WRDATA(seBuf[i]);                    // Write spare array(ECC and Mark)
#endif  

    NF_CMD(0x10);                           // Write 2nd command
    for(i=0;i<10;i++);                      //tWB = 100ns. ////??????

    NF_WAITRB();                            //wait tPROG 200~500us; 
    NF_CMD(0x70);                           // Read status command   

    for(i=0;i<3;i++);                       //twhr=60ns   
    if (NF_RDDATA()&0x1) 
    {
        NF_nFCE_H();
       	return 0;
    }//error }
    else 
    {
        NF_nFCE_H();
       	return 1;
    }

}
예제 #4
0
파일: k9s1208.c 프로젝트: TLARP/research
static int NF_WritePage(U32 block,U32 page,U8 *buffer,U8 *spareBuf)
{
    int i;
    U32 blockPage=(block<<5)+page;
    U8 *bufPt=buffer;

    NF_nFCE_L(); 
    NF_CMD(0x0);
    NF_CMD(0x80);		    // Write 1st command
    NF_ADDR(0);			    // Column 0
    NF_ADDR(blockPage&0xff);	    //
    NF_ADDR((blockPage>>8)&0xff);   // Block & page num.
    NF_ADDR((blockPage>>16)&0xff);  //

    for(i=0;i<512;i++)
    {
	NF_WRDATA(*bufPt++);	// Write one page to NFM from buffer
    }  

    if(spareBuf!=NULL)
    {
	for(i=0;i<16;i++)
	{
	    NF_WRDATA(spareBuf[i]);	// Write spare array(ECC and Mark)
	}
    }

    NF_CMD(0x10);   // Write 2nd command
    
    Delay(1);	    //tWB = 100ns. 

    NF_WAITRB();    //wait tPROG 200~500us;
 
    NF_CMD(0x70);   // Read status command   
    
    Delay(1);	    //twhr=60ns
    
    if (NF_RDDATA()&0x1) // Page write error
    {	
    	NF_nFCE_H();
	printf("[PROGRAM_ERROR:block#=%d]\n",block);
	NF_MarkBadBlock(block);
	return 0;
    }
    else 
    {
    	NF_nFCE_H();
    #if (WRITEVERIFY==1)
	//return NF_VerifyPage(block,page,pPage);	
    #else
	return 1;
    #endif
    }
}
예제 #5
0
char __low_nand_write_page(unsigned int page_addr,unsigned char *from)
{
	U32 i;
	char nfstatus;
	unsigned int *pfrom = (unsigned int *)from;//2440的NFADDR寄存器是32位的

	// printk("write page addr :%.8x \r\n",page_addr);



	// __low_nand_reset();

	//  Enable the chip
	NF_nFCE_L();
	NF_CLEAR_RB();

	// Issue Read command
	NF_CMD(CMD_WRITE1);

	//  Set up address
	
	NF_ADDR(page_addr & 0xff);		
	NF_ADDR((page_addr >> 8) & 0x0f);
	NF_ADDR((page_addr >> 12) & 0xff);
	NF_ADDR((page_addr >> 20) & 0xff);
	NF_ADDR((page_addr >> 28) & 0x01);
	


	// NF_WRDATA(0xffffffff);
	// NF_WRDATA(0xffffffff);
	// NF_WRDATA(0xffffffff);
	// NF_WRDATA(0xffffffff);

	for(i = 0;i < (NAND_PAGE_SIZE+64) >> 2;++i) {
		NF_WRDATA( *((unsigned*)pfrom++));
	}
	NF_CMD(CMD_WRITE2);

	
	NF_DETECT_RB();		// wait tR(max 12us)
	NF_CMD(CMD_STATUS);

	return (NF_RDDATA8() & 0x01);
	// nfstatus =  NF_RDDATA8();

	// NF_nFCE_H();
	// printk("nand status:%x\r\n",nfstatus);
}
예제 #6
0
char __low_nand_erase_block(unsigned int row_addr)
{
	NF_nFCE_L();
	NF_CLEAR_RB();
	NF_CMD(CMD_ERASE1);
	NF_ADDR((row_addr >> 12) & 0xff);
	NF_ADDR((row_addr >> 20) & 0xff);
	NF_ADDR((row_addr >> 28) & 0x01);
	NF_CMD(CMD_ERASE2);
	NF_DETECT_RB();		

	NF_CMD(CMD_STATUS);
	return (NF_RDDATA8() & 0x01);

}
예제 #7
0
파일: nand.c 프로젝트: cyj1988jyc/2440-test
static char rNF_ReadID()
{
	char	pMID;
	char	pDID;
	char	nBuff;
	char	n4thcycle;
	int	i;


	NF_nFCE_L();    
	NF_CLEAR_RB();
	NF_CMD(CMD_READID);	// read id command
	NF_ADDR(0x0);
	for ( i = 0; i < 100; i++ );

	pMID = NF_RDDATA8();
	pDID = NF_RDDATA8();

	nBuff     = NF_RDDATA8();
	n4thcycle = NF_RDDATA8();
	NF_nFCE_H();


	return (pDID);
}
예제 #8
0
파일: armboot.c 프로젝트: paulhsu/sbl24x0
static int NAND_ReadPage(unsigned long block,unsigned long page,unsigned char *buffer)        //?Flash
{
    int i;
    unsigned int blockPage;    
    unsigned volatile short *NFCONF;
    unsigned volatile short *NFCMD;
    unsigned volatile short *NFSTAT;
    unsigned volatile short *NFADDR;
    unsigned volatile short *NFDATA;

    NFCONF=(unsigned short *)0x4e000000;
    NFCMD=(unsigned short *)0x4e000004;
    NFSTAT=(unsigned short *)0x4e000010;
    NFDATA=(unsigned short *)0x4e00000C;
    NFADDR=(unsigned short *)0x4e000008;

    page=page&0x1f;
    blockPage=(block<<5)+page;                      //1Bolck¥]§t32page
    //NF_RSTECC();                                    // Initialize ECC    
    NF_nFCE_L();    
    NF_CMD(0x00);                                   // Read command
    NF_ADDR(0);                                     // Column = 0
    NF_ADDR(blockPage&0xff);                        //
    NF_ADDR((blockPage>>8)&0xff);                   // Block & Page num.
    NF_ADDR((blockPage>>16)&0xff);                  //

    for(i=0;i<10;i++);                              //wait tWB(100ns)    
    NF_WAITRB();                                    // Wait tR(max 12us)
    for(i=0;i<512;i++)
    {
        *buffer++=NF_RDDATA();                       // Read one page
    }
    NF_nFCE_H();   
}
예제 #9
0
파일: k9s1208.c 프로젝트: TLARP/research
static int NF_ReadPage(U32 block,U32 page,U8 *buffer,U8 *spareBuf)
{
    int i;
    unsigned int blockPage;
    U8 *bufPt=buffer;
    
    page=page&0x1f;
    blockPage=(block<<5)+page;
        
    NF_nFCE_L();    
    NF_CMD(0x00);   // Read command
    NF_ADDR(0);	    // Column = 0
    NF_ADDR(blockPage&0xff);	    //
    NF_ADDR((blockPage>>8)&0xff);   // Block & Page num.
    NF_ADDR((blockPage>>16)&0xff);  //

    Delay(1);	    //wait tWB(100ns)/////??????
    
    NF_WAITRB();    // Wait tR(max 12us)
    
    for(i=0;i<(512);i++)
    {
    	*bufPt++=NF_RDDATA();	// Read one page
    }

    if(spareBuf!=NULL)
    {
	for(i=0;i<16;i++)
	    spareBuf[i]=NF_RDDATA();	// Read spare array
    }

    NF_nFCE_H();    

    return 1;
}
예제 #10
0
파일: k9s1208.c 프로젝트: TLARP/research
static int NF_IsBadBlock(U32 block)
{
    unsigned int blockPage;
    U8 data;
    
    
    blockPage=(block<<5);	// For 2'nd cycle I/O[7:5] 
    
    NF_nFCE_L();    
    NF_CMD(0x50);		// Spare array read command
    NF_ADDR(517&0xf);		// Read the mark of bad block in spare array(M addr=5) 
    NF_ADDR(blockPage&0xff);	// The mark of bad block is in 0 page
    NF_ADDR((blockPage>>8)&0xff);   // For block number A[24:17]
    NF_ADDR((blockPage>>16)&0xff);  // For block number A[25]

    Delay(1);		// wait tWB(100ns)
    
    NF_WAITRB();	// Wait tR(max 12us)
    
    data=NF_RDDATA();

    NF_nFCE_H();    

    if(data!=0xff)
    {
    	printf("[block %d:bad block(%x)]\n",block,data);
    	return 1;
    }
    else
    {
	printf(".");
    	return 0;
    }
}
예제 #11
0
파일: k9s1208.c 프로젝트: TLARP/research
static int NF_MarkBadBlock(U32 block)
{
    int i;
    U32 blockPage=(block<<5);
 
    seBuf[0]=0xff;
    seBuf[1]=0xff;    
    seBuf[2]=0xff;    
    seBuf[5]=0x44;   // Bad blcok mark=0
    
    NF_nFCE_L(); 
    NF_CMD(0x50);   
    NF_CMD(0x80);   // Write 1st command
    
    NF_ADDR(0x0);		    // The mark of bad block is 
    NF_ADDR(blockPage&0xff);	    // marked 5th spare array 
    NF_ADDR((blockPage>>8)&0xff);   // in the 1st page.
    NF_ADDR((blockPage>>16)&0xff);  
    
    for(i=0;i<16;i++)
    {
	NF_WRDATA(seBuf[i]);	// Write spare array
    }

    NF_CMD(0x10);   // Write 2nd command
    
    Delay(1);  //tWB = 100ns. 

    NF_WAITRB();      // Wait tPROG(200~500us)
  
    NF_CMD(0x70);
    
    Delay(1);	 //twhr=60ns//
    
    if (NF_RDDATA()&0x1) // Spare arrray write error
    {	
    	NF_nFCE_H();
    	printf("[Program error is occurred but ignored]\n");
    }
    else 
    {
    	NF_nFCE_H();
    }

    printf("[block #%d is marked as a bad block]\n",block);
    return 1;
}
예제 #12
0
// int printk(const char *fmt, ...);
 void __low_nand_reset()
{
	NF_CE_L();
	NF_CLEAR_RB();
	NF_CMD(CMD_RESET);  
	NF_DETECT_RB();
	NF_CE_H();
}
예제 #13
0
static void nandll_reset(void)
{
	NF_ENABLE_CE;             /* 片选使能 */
	NF_CLEAR_RB;         /* 清除就绪/忙位 */
	NF_CMD(NAND_CMD_RESET); /* 写复位命令 */
	NF_DETECT_RB;         /* 等待复位完成 */
	NF_DISABLE_CE;            /* 片选禁用 */
}
예제 #14
0
파일: k9s1208.c 프로젝트: TLARP/research
static void NF_Init(void)
{
    NF_Reset();

    //NF_nFCE_L();
    NF_CMD(READ_1_1);        
    //NF_nFCE_H();
}
예제 #15
0
static void NF_Reset()
{
  NF_nFCE_L(); // 片选 Nand Flash 芯片
  NF_CLEAR_RB(); // 清除 RnB 信号
  NF_CMD( NF_CMD_RST ); // 复位命令
  NF_WAIT_RB(); // 等待 RnB 信号变高,即不忙
  NF_nFCE_H(); // 取消 Nand Flash 选中
}
예제 #16
0
파일: nand.c 프로젝트: cyj1988jyc/2440-test
//
//  Reset the chip
//
static void rNF_Reset()
{
	NF_CE_L();
	NF_CLEAR_RB();
	NF_CMD(CMD_RESET);  
	NF_DETECT_RB();
	NF_CE_H();
}
예제 #17
0
WORD NF_ReadPage(WORD block,WORD page,BYTE* buffer)
{
  int i;
  WORD blockPage = (block << 5) + page;
  BYTE* bufPt = buffer;
  BYTE ECCbuf[6];

  NF_RSTECC(); // 复位 ECC
  NF_MainECCUnlock(); // 解锁本页 main 区域的 ECC 校验,允许生成 ECC 校验码
  NF_nFCE_L();
  NF_CLEAR_RB(); // 清 RnB 信号
  NF_CMD( NF_CMD_RD1 ); // 从本页的上半部分开始读
  
  NF_ADDR( 0 ); // 从本页的第一个列(字节)开始读
  NF_ADDR( blockPage & 0xff ); // 这三行代码指明页号
  NF_ADDR( ( blockPage >> 8 ) & 0xff );
  NF_ADDR( ( blockPage >> 16 ) & 0xff );

  NF_WAIT_RB();

  // 往本页的 main 区里写入 buffer 里的内容
  for(i=0 ; i<NF_MAINSIZE ; i++)
    {
      buffer[i] = NF_RDDATA8();
    }

  NF_MainECCLock(); // 锁定 main 区域的 ECC 校验码
  NF_SpareECCUnlock(); // 解锁本页 spare 区域的 ECC 校验  

  // 读 spare 区域的前4个字节,即 main 区域的 ECC 校验码部分
  for(i=0 ; i<4 ; i++)
    {
      ECCbuf[i] = NF_RDDATA8();
    }

  NF_SpareECCLock(); // 锁定 spare 区域的 ECC 校验码

  // 读 spare 区域的第5,第6个字节,即 spare 区域的 ECC 校验码部分
  for(i=4 ; i<6 ; i++)
    {
      ECCbuf[i] = NF_RDDATA8();
    }

  
  /* 下面就是验证 ECC 校验码了 */

  if(( ECCbuf[0] == (NFMECCD0 & 0xff)) && 
     ( ECCbuf[1] == ((NFMECCD0 >> 16) & 0xff)) &&
     ( ECCbuf[2] == (NFMECCD1 & 0xff)) &&
     ( ECCbuf[3] == ((NFMECCD1 >> 16) & 0xff)) &&
     ( ECCbuf[4] == (NFSECCD & 0xff)) &&
     ( ECCbuf[5] == ((NFSECCD >> 16) & 0xff)))
    { // ECC 校验全部成功
      NF_nFCE_H();
      return 1;
    }
  else
    { // ECC 校验不成功
예제 #18
0
파일: fmd_lb.cpp 프로젝트: blueskycoco/w7
void SubmitSpareAreaReadCmd(DWORD SectorStartAddr, DWORD SpareStartAddr)
{
    NF_nFCE_L();

    NF_CLEAR_RB();

    NF_CMD(CMD_READ);                            // Send read command.

    NF_ADDR((SpareStartAddr)&0xff);
    NF_ADDR((SpareStartAddr>>8)&0xff);
    NF_ADDR((SectorStartAddr) & 0xff);
    NF_ADDR((SectorStartAddr >> 8) & 0xff);
    if(g_bNeedExtAddr)
    {
        NF_ADDR((SectorStartAddr >> 16) & 0xff);
    }

    NF_CMD(CMD_READ3);                        // 2nd command

    NF_DETECT_RB();                                // Wait for command to complete.
}
예제 #19
0
파일: k9s1208.c 프로젝트: TLARP/research
static void NF_Reset(void)
{
    NF_nFCE_L();

    NF_CMD(0xFF);   //reset command

    Delay(1);	    //tWB = 100ns. 

    NF_WAITRB();    //wait 200~500us;
     
    NF_nFCE_H();    
}
예제 #20
0
 void __low_nand_read_page(unsigned int page_addr,unsigned char *to)
{
	U32 i;
	char nfstatus;
	unsigned int *pto = (unsigned int *)to;
	// printk("read page addr :%.8x \r\n",page_addr);



	// __low_nand_reset();

	//  Enable the chip
	NF_nFCE_L();
	NF_CLEAR_RB();

	// Issue Read command
	NF_CMD(CMD_READ);

	//  Set up address
	NF_ADDR(page_addr & 0xff);		
	NF_ADDR((page_addr >> 8) & 0x0f);
	NF_ADDR((page_addr >> 12) & 0xff);
	NF_ADDR((page_addr >> 20) & 0xff);
	NF_ADDR((page_addr >> 28) & 0x01);
	NF_CMD(CMD_READ2);


	NF_DETECT_RB();		// wait tR(max 12us)

	for (i = 0; i < (NAND_PAGE_SIZE+64) >> 2;++i) {
		*((unsigned*)pto++) = NF_RDDATA();	
	}
	
	// for (i = 0; i < NAND_PAGE_SIZE ;++i)
	// {
		
	// 	to[i] = NF_RDDATA8();
	// }
	NF_nFCE_H();
}
예제 #21
0
파일: k9s1208.c 프로젝트: TLARP/research
static int NF_EraseBlock(U32 block)
{
    U32 blockPage=(block<<5);

#if BAD_CHECK
    if(NF_IsBadBlock(block) && block!=0) //block #0 can't be bad block for NAND boot
	return 0;
#endif

    NF_nFCE_L();
    
    NF_CMD(0x60);   // Erase one block 1st command

    NF_ADDR(blockPage&0xff);	    // Page number=0
    NF_ADDR((blockPage>>8)&0xff);   
    NF_ADDR((blockPage>>16)&0xff);

    NF_CMD(0xd0);   // Erase one blcok 2nd command
    
    Delay(1); //wait tWB(100ns)

    NF_WAITRB();    // Wait tBERS max 3ms.
    NF_CMD(0x70);   // Read status command

    if (NF_RDDATA()&0x1) // Erase error
    {	
    	NF_nFCE_H();
	printf("[ERASE_ERROR:block#=%d]\n",block);
	NF_MarkBadBlock(block);
	return 0;
    }
    else 
    {
    	NF_nFCE_H();
        return 1;
    }
}
예제 #22
0
WORD NF_CheckId()
{
  WORD id;

  NF_nFCE_L();
  NF_CLEAR_RB();
  NF_CMD( NF_CMD_RDD );
  NF_ADDR( 0x0 ); // 指定地址 0x0, 芯片手册要求
  NF_WAIT_RB();
  id = NF_RDDATA8() << 8; // 厂商 ID
  id |= NF_RDDATA8(); // 设备 ID
  NF_nFCE_H();

  return id;
}
예제 #23
0
파일: k9s1208.c 프로젝트: TLARP/research
static U16 NF_CheckId(void)
{
    U16 id;
    
    NF_nFCE_L();
    
    NF_CMD(0x90);
    NF_ADDR(0x0);
    
    Delay(1);	//wait tWB(100ns)
    
    id=NF_RDDATA()<<8;	// Maker code(K9S1208V:0xec)
    id|=NF_RDDATA();	// Devide code(K9S1208V:0x76)
    
    NF_nFCE_H();
    
    return id;
}
예제 #24
0
 char __low_nand_readid(unsigned int *part1,unsigned *part2)
{
	char g_nfid1;
	char g_nfid2;
	char g_nfid3;
	char g_nfid4;
	char g_nfid5;

	char	pMID;
	char	pDID;
	char	nBuff;
	char	n4thcycle;
	int	i;


	NF_nFCE_L();    
	NF_CLEAR_RB();
	NF_CMD(CMD_READID);	// read id command
	NF_ADDR(0x00);
	for ( i = 0; i < 100; i++ );

	g_nfid1 = NF_RDDATA8();
	g_nfid2 = NF_RDDATA8();
	g_nfid3 = NF_RDDATA8();
	g_nfid4 = NF_RDDATA8();
	g_nfid5 = NF_RDDATA8();

	pMID = g_nfid1;
	pDID = g_nfid2;

	nBuff     = NF_RDDATA8();
	n4thcycle = NF_RDDATA8();
	NF_nFCE_H();
	



	return (pDID);
}
예제 #25
0
파일: fmd_lb.cpp 프로젝트: blueskycoco/w7
BOOL FMD_LB_ReadSector(SECTOR_ADDR startSectorAddr, LPBYTE pSectorBuff, PSectorInfo pSectorInfoBuff, DWORD dwNumSectors)
{
    ULONG SectorAddr = (ULONG)startSectorAddr;
    DWORD       i;
    volatile DWORD        rddata;
    UINT32 nRetEcc = 0;
    DWORD MECCBuf[MAX_SECTORS_PER_PAGE];
    
    UINT16 nSectorLoop;
    int NewSpareAddr = NAND_PAGE_SIZE;
    int NewDataAddr = 0;
    int NewSectorAddr = startSectorAddr;

    DWORD SECCBuf1;         // 1st Spare ECC
    DWORD SECCBuf2;         // 2nd Spare ECC(cloned from 1st)
    BYTE RawSectorInfo[8];

    RETAILMSG(FMD_ZONE_FUNCTION,(TEXT("#### FMD_DRIVER:::FMD_LB_READSECTOR %x %x\r\n"),startSectorAddr,NewDataAddr));

    if (!pSectorBuff && !pSectorInfoBuff)
    {
        return(FALSE);
    }

    if ( dwNumSectors > 1 )
    {
        RETAILMSG(FMD_ZONE_ERROR, (TEXT("######## FATAL ERROR => FMD::FMD_ReadSector->dwNumsectors is bigger than 1. \r\n")));
        return FALSE;
    }

    if (!pSectorBuff)
    {
        return NAND_LB_ReadSectorInfo(startSectorAddr, pSectorInfoBuff);
    }

    SubmitSpareAreaReadCmd(NewSectorAddr, NewSpareAddr+NAND_SECC1_OFFSET);    //< Spare Area Start Address, SECTOR_SIZE(512)*SECTOS_PER_PAGE(4)=2048 -> Physical Page Size

    // Read SECC1, SECC2 from Spare area
    SECCBuf1 = NF_RDDATA_WORD();
    SECCBuf2 = NF_RDDATA_WORD();

    // Set address for random access to read SectorInfo and MECC code from Spare Area
    NF_CMD(CMD_RDO);    // Send read random data output command
    NF_ADDR((NewSpareAddr)&0xff);
    NF_ADDR(((NewSpareAddr)>>8)&0xff);
    NF_CMD(CMD_RDO2);   // Command done

    if (pSectorInfoBuff)            /// Read SectorInfo doesn't check this
    {
        ReadOneSectorInfo(RawSectorInfo);        ///< Read One SectorInfo by sizeof(SectorInfo)
        
        // Check ECC abour SectorInfo         
        NF_WRMECCD0( ((SECCBuf1&0xff00)<<8)|(SECCBuf1&0xff) );    
        NF_WRMECCD1( ((SECCBuf1&0xff000000)>>8)|((SECCBuf1&0xff0000)>>16) );

        nRetEcc = NF_ECC_ERR0;

        if (!ECC_CorrectData(startSectorAddr, RawSectorInfo, nRetEcc, ECC_CORRECT_SPARE1)) // Use specific byte
        {
            RETAILMSG(FMD_ZONE_ERROR, (TEXT("#### SECC1 ECC correction failed\n")));   
            NF_nFCE_H();
            return FALSE;
        }

        RestructSectorInfo(pSectorInfoBuff, RawSectorInfo);
    }
    else
    {
         for(i=0; i<sizeof(SectorInfo)/sizeof(DWORD); i++)