⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 nand.c

📁 Embest IDE下s3c2440的测试工程
💻 C
📖 第 1 页 / 共 4 页
字号:

//	NF8_Init();

      rINTMSK = BIT_ALLMSK; 	
      srcAddress=0x30200000; 
      downloadProgramSize = filesize;
      targetSize = filesize;

	targetBlock = block;

   	Uart_Printf("Input target bolock number: ");
    if(1)//targetSize==0)
    {
	targetBlock = Uart_GetIntNum();
    }	
	
    if(1)//targetSize==0)
    {
   	Uart_Printf("Input program file size(bytes): ");
    	targetSize=Uart_GetIntNum();	// Total byte size
    }
	
#if ((ID_NAND == ID_K9F1G08U0A)||(ID_NAND == ID_K9K8G08U0A))
	no_block = (U32)((targetSize/2048)/64);
	no_page = (U32)((targetSize/2048)%64);
	no_byte = (U32)(targetSize%2048);
	Uart_Printf("File:%d[%d-block,%d-page,%d-bytes].\n", targetSize, no_block, no_page, no_byte);
#elif ID_NAND == ID_K9S1208V0M
	no_block = (U32)((targetSize/512)/32);
	no_page = (U32)((targetSize/512)%32);
	no_byte = (U32)(targetSize%512);
	Uart_Printf("File:%d[%d-block,%d-page,%d-bytes].\n", targetSize, no_block, no_page, no_byte);
#endif
	
      srcPt=(U8 *)srcAddress;
      blockIndex=targetBlock;

     while(1) {
        saveSrcPt=srcPt;	

		#if BAD_CHECK
		if(NF8_IsBadBlock(blockIndex)==FAIL) {
		    blockIndex++;   // for next block
		    continue;
		}
		#endif

		if(NF8_EraseBlock(blockIndex)==FAIL) {
		    blockIndex++;   // for next block
		    continue;
		}
#if  ID_NAND == ID_K9F1G08U0A
		// After 1-Block erase, Write 1-Block(64 pages).
		for(i=0;i<64;i++) {
		    if(NF8_WritePage(blockIndex,i,srcPt)==FAIL) {// block num, page num, buffer
		        programError=1;
		        break;
		    }

		#if ECC_CHECK
		    if(NF8_ReadPage(blockIndex,i,srcPt)==FAIL) {
				Uart_Printf("ECC Error(block=%d,page=%d!!!\n",blockIndex,i);
		    }
		#endif
			
		srcPt+=2048;	// Increase buffer addr one pase size
		if(i==0)  Uart_Printf(".");
			//Uart_Printf("\b\b\b\b\b\b\b\b%04d,%02d]", blockIndex, i);
		if((U32)srcPt>=(srcAddress+targetSize)) // Check end of buffer
		break;	// Exit for loop
		}
		
		if(programError==1) {
		    blockIndex++;
		    srcPt=saveSrcPt;
		    programError=0;
		    continue;
		}

		if((U32)srcPt>=(srcAddress+targetSize)) break;	// Exit while loop
#elif  ID_NAND == ID_K9K8G08U0A
		// After 1-Block erase, Write 1-Block(64 pages).
		for(i=0;i<64;i++) {
		    if(NF8_WritePage(blockIndex,i,srcPt)==FAIL) {// block num, page num, buffer
		        programError=1;
		        break;
		    }

		#if ECC_CHECK
		    if(NF8_ReadPage(blockIndex,i,srcPt)==FAIL) {
				Uart_Printf("ECC Error(block=%d,page=%d!!!\n",blockIndex,i);
		    }
		#endif
			
		srcPt+=2048;	// Increase buffer addr one pase size
		if(i==0)  Uart_Printf(".");
			//Uart_Printf("\b\b\b\b\b\b\b\b%04d,%02d]", blockIndex, i);
		if((U32)srcPt>=(srcAddress+targetSize)) // Check end of buffer
		break;	// Exit for loop
		}
		
		if(programError==1) {
		    blockIndex++;
		    srcPt=saveSrcPt;
		    programError=0;
		    continue;
		}

		if((U32)srcPt>=(srcAddress+targetSize)) break;	// Exit while loop
#elif ID_NAND == ID_K9S1208V0M
		// After 1-Block erase, Write 1-Block(32 pages).
		for(i=0;i<32;i++) {
		    if(NF8_WritePage(blockIndex,i,srcPt)==FAIL) {// block num, page num, buffer
		        programError=1;
		        break;
		    }

		#if ECC_CHECK
		    if(NF8_ReadPage(blockIndex,i,srcPt)==FAIL) {
				Uart_Printf("ECC Error(block=%d,page=%d!!!\n",blockIndex,i);
		    }
		#endif
			
		srcPt+=512;	// Increase buffer addr one pase size
		if(i==0)  Uart_Printf(".");
			//Uart_Printf("\b\b\b\b\b\b\b\b%04d,%02d]", blockIndex, i);
		if((U32)srcPt>=(srcAddress+targetSize)) // Check end of buffer
		break;	// Exit for loop
		}
		
		if(programError==1) {
		    blockIndex++;
		    srcPt=saveSrcPt;
		    programError=0;
		    continue;
		}

		if((U32)srcPt>=(srcAddress+targetSize)) break;	// Exit while loop#endif
#endif
		blockIndex++;
    }

}


void InputTargetBlock(void)
{
	U32 no_block, no_page, no_byte;
	
	Uart_Printf("\nSource size:0h~%xh\n",downloadProgramSize);
	Uart_Printf("\nAvailable target block number: 0~4095\n");
	Uart_Printf("Input target block number:");
#if 1
	targetBlock=Uart_GetIntNum();	// Block number(0~4095)
#else
	targetBlock = 3;
#endif
    if(targetSize==0)
    {
    #if 0
    	Uart_Printf("Input target size(0x4000*n):");
    	targetSize=31457280;//Uart_GetIntNum();	// Total byte size
	#else
   	Uart_Printf("Input program file size(bytes): ");
    	targetSize=Uart_GetIntNum();	// Total byte size
    	#endif
    }
	
#if ((ID_NAND == ID_K9F1G08U0A)||(ID_NAND == ID_K9K8G08U0A))
	no_block = (U32)((targetSize/2048)/64);
	no_page = (U32)((targetSize/2048)%64);
	no_byte = (U32)(targetSize%2048);
	Uart_Printf("File:%d[%d-block,%d-page,%d-bytes].\n", targetSize, no_block, no_page, no_byte);
#elif ID_NAND == ID_K9S1208V0M
	no_block = (U32)((targetSize/512)/32);
	no_page = (U32)((targetSize/512)%32);
	no_byte = (U32)(targetSize%512);
	Uart_Printf("File:%d[%d-block,%d-page,%d-bytes].\n", targetSize, no_block, no_page, no_byte);
#endif
}


void NF8_PrintBadBlockNum(void)
{
    int i;
    U16 id;

    Uart_Printf("\n[SMC(K9S1208V0M) NAND Flash bad block check]\n");
    
    id=NF8_CheckId();
    Uart_Printf("ID=%x(0xec76)\n",id);
    if((id!=0xec76)&&(id!=0xecf1)&&(id!=0xecd3))
    return;
    if(id == 0xec76)	
    	for(i=0;i<4096;i++)  	NF8_IsBadBlock(i);   // Print bad block
    else if(id == 0xecf1)
    	for(i=0;i<1024;i++)  	NF8_IsBadBlock(i);   // Print bad block
    else if(id ==0xecd3)
	for(i=0;i<8192;i++)	NF8_IsBadBlock(i);  // print bad block
}


void Test_NF8_Lock(void)
{
       U32 num;
       U32 S_block, E_block;
	Uart_Printf("SMC(K9S1208V0M) NAND Lock Test !!!\n");
	Uart_Printf("Select Lock type, Softlock(1)/Lock-tight(2) : ");

	num=Uart_GetIntNum();;
			
	Uart_Printf("\nEnter programmable start block address ");
	S_block = Uart_GetIntNum();
	Uart_Printf("Enter programmable end block address ");
       E_block = Uart_GetIntNum();

	rNFSBLK=(S_block<<5);
	rNFEBLK=(E_block<<5);
	
	if(num==1){
		rNFCONT|=(1<<12);
              Uart_Printf("Software Locked\n ");
	}
	if(num==2){
		rNFCONT|=(1<<13);
              Uart_Printf("Lock-tight: To clear Lock-tight, reset S3C2440!!!\n ");
	}
      Uart_Printf("%d block ~ %d block are Programmable\n ", S_block, (E_block-1));
}


void Test_NF8_SoftUnLock(void)
{
       U32 S_block, E_block;
	Uart_Printf("SMC(K9S1208V0M) NAND SoftUnLock Test !!!\n");
	
	rNFSBLK=0x0;
	rNFEBLK=0x0;

	rNFCONT&=~(1<<12);
	if(rNFCONT&(1<<13)){
		rNFCONT&=~(1<<13);
		Uart_Printf("Lock-tight\n ");
		Uart_Printf("You can't unlock Protected blocks !!!\n ");
		Uart_Printf("%d block ~ %d block are Programmable\n ", (rNFSBLK>>5), ((rNFEBLK>>5)-1));
	}
       else Uart_Printf("All blocks are Programmable\n ");
}


void PrintSubMessage(void)
{
	int i;
	
	i=0;	
	Uart_Printf("\n\n");
	while(1)
	{   //display menu
	    Uart_Printf("%2d:%s",i,n8_func[i][1]);
	    i++;
	    if((int)(n8_func[i][0])==0)
	    {
		 Uart_Printf("\n");
		 break;
	    }
	    if((i%4)==0) Uart_Printf("\n");
	}
}


static int NF8_EraseBlock(U32 block)
{
	U32 blockPage=(block<<6);
	int i;

#if  USE_NFINIT
    NFConDone=0;

    rNFCONT|=(1<<9);
    rNFCONT|=(1<<10);
    pISR_NFCON= (unsigned)NFCon_Int;
    rSRCPND=BIT_NFCON;
    rINTMSK=~(BIT_NFCON);
#endif

#if BAD_CHECK
    if(NF8_IsBadBlock(block) ==FAIL)
	return FAIL;
#endif

	NF_nFCE_L();
    
	NF_CMD(0x60);   // Erase one block 1st command, Block Addr:A9-A25
	// Address 3-cycle
	NF_ADDR(blockPage&0xff);	    // Page number=0
	NF_ADDR((blockPage>>8)&0xff);   
#if ID_NAND == ID_K9K8G08U0A 
	NF_ADDR((blockPage>>16)&0xff);
#elif ID_NAND == ID_K9S1208V0M
	blockPage = (block <<5);
	NF_ADDR((blockPage>>16)&0xff);
#endif


	NF_CLEAR_RB();
	NF_CMD(0xd0);	// Erase one blcok 2nd command
#if  USE_NFINIT
        while(NFConDone==0);
	 rNFCONT&=~(1<<9);
	 rNFCONT&=~(1<<10); // Disable Illegal Access Interrupt
#else
	NF_DETECT_RB();
#endif

       if(rNFSTAT&0x8) return FAIL;

	NF_CMD(0x70);   // Read status command

      if (NF_RDDATA()&0x1) // Erase error
      {	
    	NF_nFCE_H();
	Uart_Printf("[ERASE_ERROR:block#=%d]\n",block);
	NF8_MarkBadBlock(block);
	return FAIL;
       }
       else 
       {
    	NF_nFCE_H();
       return OK;
       }
}


void __irq NFCon_Int(void)
{
       NFConDone=1;
	rINTMSK|=BIT_NFCON;
	ClearPending(BIT_NFCON);
	if(rNFSTAT&0x8) Uart_Printf("Illegal Access is detected!!!\n");
	else Uart_Printf("RnB is Detected!!!\n"); 
}


static int NF8_IsBadBlock(U32 block)
{

     int i;
       unsigned int blockPage;
	U8 data;
    
#if ID_NAND == ID_K9F1G08U0A
	blockPage=(block<<6);	// For 2'nd cycle I/O[7:5] 
	NF_nFCE_L();
	NF_CLEAR_RB();

	NF_CMD(0x00);		 // Spare array read command
	NF_ADDR((2048+5)&0xff);		 // Read the mark of bad block in spare array(M addr=5), A4-A7:Don't care
	NF_ADDR(((2048)>>8)&0xff);		// A[10:8]
	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_CMD(0x30);	// 2'nd command
	NF_DETECT_RB();	 // Wait tR(max 12us)
#elif ID_NAND == ID_K9K8G08U0A
	blockPage=(block<<6);	// For 2'nd cycle I/O[7:5] 
	NF_nFCE_L();
	NF_CLEAR_RB();

	NF_CMD(0x00);		 // Spare array read command
	NF_ADDR((2048+5)&0xff);		 // Read the mark of bad block in spare array(M addr=5), A4-A7:Don't care
	NF_ADDR(((2048)>>8)&0xff);		// A[10:8]
	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);
	NF_CMD(0x30);	// 2'nd command
	NF_DETECT_RB();	 // Wait tR(max 12us)

#elif ID_NAND == ID_K9S1208V0M
	blockPage=(block<<5);	// For 2'nd cycle I/O[7:5] 
    
	NF_nFCE_L();
	NF_CLEAR_RB();

	NF_CMD(0x50);		 // Spare array read command
	NF_ADDR((512+5)&0xf);		 // Read the mark of bad block in spare array(M addr=5), A4-A7:Don't care
	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]
#endif
	 
	NF_DETECT_RB();	 // Wait tR(max 12us)

       data=NF_RDDATA();

	NF_nFCE_H();    

     if(data!=0xff)
     {
    	Uart_Printf("[block %d has been marked as a bad block(%x)]\n",block,data);
    	return FAIL;
     }
     else
     {
    	return OK;
     }

  return OK;   
}

/*
static BOOL  NF8_SetBlockStatus(DWORD blockID, DWORD dwStatus)
{
    if (dwStatus & (BLOCK_STATUS_READONLY | BLOCK_STATUS_RESERVED)) {
        
        SECTOR_ADDR Sector = blockID>>6;
        SectorInfo SI;

        if (!FMD_ReadSector(Sector, NULL, &SI, 1)) {
            return FALSE;
        }

        if (dwStatus & BLOCK_STATUS_READONLY) {
            SI.bOEMReserved &= ~OEM_BLOCK_READONLY;
        }
        
        if (dwStatus & BLOCK_STATUS_RESERVED) {
            SI.bOEMReserved &= ~OEM_BLOCK_RESERVED;
        }

        if (!FMD_WriteSector (Sector, NULL, &SI, 1)) {
            return FALSE;
        }

    }    
    
    return TRUE;
}
*/

static int NF8_MarkBadBlock(U32 block)
{
       int i;
#if ID_NAND==ID_K9F1G08U0A
	U32 blockPage=(block<<6);
     se8Buf[0]=0xff;
     se8Buf[1]=0xff;    
     se8Buf[2]=0xff;    
     se8Buf[5]=0x44;   // Bad blcok mark=44
    
	NF_nFCE_L(); 
	NF_CMD(0x00);   //????
	NF_CMD(0x80);   // Write 1st command
    
	NF_ADDR(0x0);		    // The mark of bad block is 
	NF_ADDR(0x0);
	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<64;i++)
      {
	   NF_WRDATA(se8Buf[i]);	// Write spare array
      }

	NF_CLEAR_RB();
	NF_CMD(0x10);   // Write 2nd command
	NF_DETECT_RB();

	NF_CMD(0x70);
    
	for(i=0;i<3;i++);  //twhr=60ns////??????
    
      if (NF_RDDATA()&0x1) // Spare arrray write error
      {	
    	NF_nFCE_H();
    	Uart_Printf("[Program error is occurred but ignored]\n");
       }
      else 
      {
    	NF_nFCE_H();
      }
#elif ID_NAND == ID_K9K8G08U0A
	U32 blockPage=(block<<6);
     se8Buf[0]=0xff;
     se8Buf[1]=0xff;    
     se8Buf[2]=0xff;    
     se8Buf[5]=0x44;   // Bad blcok mark=44
    
	NF_nFCE_L(); 
	NF_CMD(0x00);   //????
	NF_CMD(0x80);   // Write 1st command
    
	NF_ADDR(0x0);		    // The mark of bad block is 
	NF_ADDR(0x0);
	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<64;i++)
      {
	   NF_WRDATA(se8Buf[i]);	// Write spare array
      }

	NF_CLEAR_RB();
	NF_CMD(0x10);   // Write 2nd command
	NF_DETECT_RB();

	NF_CMD(0x70);
    
	for(i=0;i<3;i++);  //twhr=60ns////??????
    
      if (NF_RDDATA()&0x1) // Spare arrray write error
      {	
    	NF_nFCE_H();
    	Uart_Printf("[Program error is occurred but ignored]\n");
       }
      else 
      {
    	NF_nFCE_H();
      }
#elif ID_NAND == ID_K9S1208V0M
	U32 blockPage=(block<<5);
     se8Buf[0]=0xff;
     se8Buf[1]=0xff;    
     se8Buf[2]=0xff;    
     se8Buf[5]=0x44;   // Bad blcok mark=44
    
	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(se8Buf[i]);	// Write spare array
      }

	NF_CLEAR_RB();
	NF_CMD(0x10);   // Write 2nd command
	NF_DETECT_RB();

	NF_CMD(0x70);
    
	for(i=0;i<3;i++);  //twhr=60ns////??????
    
      if (NF_RDDATA()&0x1) // Spare arrray write error
      {	
    	NF_nFCE_H();
    	Uart_Printf("[Program error is occurred but ignored]\n");
       }
      else 
      {
    	NF_nFCE_H();
      }

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -