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

📄 fmd.cpp

📁 wince5.0 bsp 下K9F2G08Flash的驱动源代码
💻 CPP
📖 第 1 页 / 共 3 页
字号:
			//RETAILMSG(1,(TEXT("11 ECCBuf[%d]=0x%x\r\n"),i,ECCBuf[i]));
    		}
  //  Copmare with the ECC generated from the HW
 
    		if(ECCBuf[0] != ECCBufN[0] ||
           	   ECCBuf[1] != ECCBufN[1] ||
                 ECCBuf[2] != ECCBufN[2] || 
                 ECCBuf[3] != ECCBufN[3])
           	   {
         	   	 RETAILMSG(1,(TEXT("FMD_ReadSector1G08 ECC Error,page %d parameters\r\n"), startSectorAddr));
		    	 RETAILMSG(1,(TEXT("FMD_ReadSector1G08 ECCBuf %x %x %x %x\r\n"),ECCBuf[0], ECCBuf[1],ECCBuf[2],ECCBuf[3]));
	           	 RETAILMSG(1,(TEXT("FMD_ReadSector1G08 ECCBufN %x %x %x %x\r\n"),ECCBufN[0], ECCBufN[1],ECCBufN[2],ECCBufN[3]));
                      //changed by yangrui for hardware ECC 20080416
                      //  Copmare with the ECC generated from the HW
			WRITE_REGISTER_ULONG(&s2440NAND->rNFMECCD0, (DWORD)((DWORD)(ECCBuf[1]<<16) | (DWORD)(ECCBuf[0]&0xff)));
	              WRITE_REGISTER_ULONG(&s2440NAND->rNFMECCD1, (DWORD)((DWORD)(ECCBuf[3]<<16) | (DWORD)(ECCBuf[2]&0xff)));

        		//  Now try to correct them
        		ecc_state = READ_REGISTER_ULONG(&s2440NAND->rNFESTAT0);
			RETAILMSG(1, (TEXT("FMD_ReadSector1G08: ecc_state=0x%x(page %d)\r\n"),(ecc_state & 0x3),startSectorAddr));
			//The S3C2440 has the ECC status register,we can use it to corret the false.
        		if(((ecc_state & 0x3) == 0x2) || ((ecc_state & 0x3) == 0x3)) 
			{
            			RETAILMSG(1, (TEXT("FMD_ReadSector1G08: Unable to correct the ECC error - Page #: %d\r\n"),startSectorAddr));
				if((startSectorAddr >= (Register_Start_Block*NAND_PAGE_CNT)) && (startSectorAddr <= (Register_End_Block*NAND_PAGE_CNT)))
				{
				       RETAILMSG(1, (TEXT("Page #: %d is Hive Register Block!!\r\n"),startSectorAddr));
				}
				else
				{
				       NF_nFCE_H();           //changed by yangrui 20080620
				       bRet = FALSE;
				}
        		}
			else if((ecc_state & 0x3) == 0x1)
			{
	     			bitLocation = ((ecc_state >> 4) & (0x7));
	     			byteLocation = ((ecc_state >> 7) & (0x7FF)); 
	   			if(pSectorBuff[byteLocation] & (0x01 << bitLocation))
	    			{
		  			pSectorBuff[byteLocation] &= ~(0x01 << bitLocation);		// 0->1 error, set bit to 0
	    			}
	    			else
	    			{
		  			pSectorBuff[byteLocation] |= (0x01 <<  bitLocation);		// 1->0 error, set bit to 1
	     			}
	     	
			}
                      //changed 20080416 end
        		//  Now try to correct them
        		//if(!ECC_CorrectData2048(pSectorBuff, ECCBuf, ECCBufN)) 
        		//{
            			//RETAILMSG(1,(TEXT("NandFlash FMD_ReadSector fatal ECC Error\r\n")));
         		//}//end if(!ECC_CorrectData2048(pSectorBuff, ECCBuf, ECCBufN)) 
	     	}//end if(ECCBuf[0] != ECCBufN[0] ||
  	}//end if (pSectorBuff) 
    	NF_nFCE_H();                             // Deselect the flash chip.

	RELEASEMUTEX();             //Relase when last!
    
    	return bRet;
}


/*
    @func   BOOL | FMD_EraseBlock | Erases the specified flash block.
    @rdesc  TRUE = Success, FALSE = Failure.
    @comm    
    @xref   
*/
BOOL FMD_EraseBlock1G08(BLOCK_ID blockID)
{
    	BYTE Status;
    	ULONG blockPage = (blockID * NAND_PAGE_CNT);    // Convert block address to page address.





	GRABMUTEX();          //we should MUTEX first
	
    	NF_nFCE_L();                        // Select the flash chip.
	NF_WAITRnB();
	
    	NF_CLEAR_RB();
    	NF_CMD(CMD_ERASE);                    // Send block erase command.
	// Address 2-cycle
	NF_ADDR((blockPage)&0xff);	    // Page number=0
	NF_ADDR((blockPage>>8)&0xff);   	
	#if (K9F2G08_SUPPORT||K9F4G08_SUPPORT||K9F8G08_SUPPORT)
	if((g_pNandFlashChip->FlashID!=0xECF1)&&(g_pNandFlashChip->FlashID!=0xECA1))
	NF_ADDR((blockPage>>16)&0xff);
	#endif
    	NF_CMD(CMD_ERASE2);                    // Send block erase confirm command.
    	//NF_WAITRB();                        // Wait for flash to complete command.
    	NF_DETECT_RB();
    	//  Check the status
    	NF_CMD(CMD_STATUS);
    	Status = NF_RDDATA();                // Read command status.
    	NF_nFCE_H();                        // Deselect the flash chip.

	RELEASEMUTEX();             //Relase when last!
		
    	return((Status & 1) ? FALSE : TRUE);
}




/*
    @func   BOOL | FMD_WriteSector | Writes the specified data to the specified NAND flash sector/page.
    @rdesc  TRUE = Success, FALSE = Failure.
    @comm    
    @xref   
*/
BOOL FMD_WriteSector1G08(SECTOR_ADDR startSectorAddr, LPBYTE pSectorBuff, PSectorInfo pSectorInfoBuff, DWORD dwNumSectors)
{
    	BYTE Status;
    	ULONG SectorAddr = (ULONG)startSectorAddr;
    	DWORD i;
    	BOOL  bRet = TRUE;    

//20080228 ADD 2048 BYTE ECC
	DWORD dwECCVal;
	BYTE ECCBuf[4];
//20080228 BY YQX


    	if((!pSectorBuff && !pSectorInfoBuff) || dwNumSectors != 1) 
    	{
        	RETAILMSG(1, (TEXT("Invalid parameters!\n")));
        	return FALSE;
    	}
        
	GRABMUTEX();          //we should MUTEX first
    
    	NF_nFCE_L();                            // Select the flash chip.
	NF_WAITRnB();
    	//delete at 20080919
//    	NF_CLEAR_RB();  
//    	NF_CMD(CMD_RESET);                        // Send reset command.
//    	for(i=0;i<10;i++); 
//    	NF_DETECT_RB();
  	//delete at 20080919

    	ULONG blockPage = SectorAddr;//(((SectorAddr / NAND_PAGE_CNT) * NAND_PAGE_CNT) | (SectorAddr % NAND_PAGE_CNT));
    	if (!pSectorBuff)
    	{         	
	    	NF_CLEAR_RB();    
	    	NF_CMD(CMD_WRITE);   // Write 1st command
	    	NF_ADDR((2048+0)&0xff); 	// Column (A[7:0]) = 0
	    	NF_ADDR(((2048+0)>>8)&0xff); 	// A[11:8]
	    	NF_ADDR((blockPage)&0xff);	// A[19:12]
	    	NF_ADDR((blockPage>>8)&0xff);	// A[27:20]
	        #if (K9F2G08_SUPPORT||K9F4G08_SUPPORT||K9F8G08_SUPPORT)
	        	if((g_pNandFlashChip->FlashID!=0xECF1)&&(g_pNandFlashChip->FlashID!=0xECA1))
	        		NF_ADDR((blockPage>>16)&0xff);
	        #endif
			        
		NF_WRDATA( (pSectorInfoBuff->bBadBlock) );

        	//  Write the first reserved field (DWORD)
        	NF_DATA_W4(pSectorInfoBuff->dwReserved1);

        	//  Write OEM reserved flag
        	NF_WRDATA( (pSectorInfoBuff->bOEMReserved) );

        	//  Write the second reserved field
        	NF_WRDATA( (pSectorInfoBuff->wReserved2 >> 8) & 0xff );
        	NF_WRDATA( (pSectorInfoBuff->wReserved2) & 0xff );
            	pSectorInfoBuff++;
        }
        else
        {
         //20080228 add 2048 ecc        
           	NF_RSTECC();                            // Initialize ECC.
         	NF_MECC_UnLock();
         //20080228 by yqx
         
       //	NF_CMD(CMD_READ);                     // Send read command.
       	NF_CLEAR_RB();    
       	NF_CMD(CMD_WRITE);   // Write 1st command
       	NF_ADDR(0); 	// Column (A[7:0]) = 0
       	NF_ADDR(0); 	// A[11:8]
       	NF_ADDR((blockPage)&0xff);	// A[19:12]
       	NF_ADDR((blockPage>>8)&0xff);	// A[27:20]
          #if (K9F2G08_SUPPORT||K9F4G08_SUPPORT||K9F8G08_SUPPORT)
          		if((g_pNandFlashChip->FlashID!=0xECF1)&&(g_pNandFlashChip->FlashID!=0xECA1))
          			NF_ADDR((blockPage>>16)&0xff);
          #endif
		           	
	      	if( ((DWORD) pSectorBuff) & 0x3) 
		{
              	//  Write the data
              	WrPage2048Unalign (pSectorBuff,(PULONG)&s2440NAND->rNFDATA);
              }
              else
              {
#if (TRANS_MODE == C_LANG)
                      WrPage2048(pSectorBuff,(PULONG)&s2440NAND->rNFDATA);                // Write page/sector data.
#elif (TRANS_MODE == DMA)
              memcpy( pVirDMAbuf, pSectorBuff, 2048 );
		// Nand to memory dma setting
		s2440INT->rSRCPND=BIT_DMA0;	// Init DMA src pending.
		s2440DMAregs->rDISRC0=(unsigned)pPhyDMAbuffer; 	// Nand flash data register
		s2440DMAregs->rDISRCC0=(0<<1) | (0<<0); //dst=AHB,dst_addr=inc;
		s2440DMAregs->rDIDST0=NFDATA; 	// Nand flash data register
		s2440DMAregs->rDIDSTC0=(0<<1) | (1<<0); //arc=AHB,src_addr=fix
		s2440DMAregs->rDCON0=(1<<31)|(1<<30)|(1<<29)|(0<<28)|(1<<27)|(0<<23)|(1<<22)|(2<<20)|(2048/4);
		//Handshake,AHB,interrupt,(no-burst),whole,S/W,no_autoreload,word,count=128;
	
		// DMA on and start.
		s2440DMAregs->rDMASKTRIG0=(1<<1)|(1<<0);
	
		while(!((s2440INT->rSRCPND) & BIT_DMA0));	// Wait until Dma transfer is done.			
		s2440INT->rSRCPND=BIT_DMA0;               
#endif
	      	 }

	      	
            	//  Read out the ECC value generated by HW
           	NF_MECC_Lock();
           	dwECCVal = NF_ECC();          
           
	    	if(pSectorInfoBuff)
	    	{
		     //  Write the bad block flag
	            NF_WRDATA( (pSectorInfoBuff->bBadBlock) );
             
	            //  Write the first reserved field (DWORD)
	            NF_DATA_W4(pSectorInfoBuff->dwReserved1);
             
	            //  Write OEM reserved flag
	            NF_WRDATA( (pSectorInfoBuff->bOEMReserved) );
             	            
	            //  Write the second reserved field
	            NF_WRDATA( (pSectorInfoBuff->wReserved2 >> 8) & 0xff );
	            NF_WRDATA( (pSectorInfoBuff->wReserved2) & 0xff );
	        }
        	else
         	{
		        // Make sure we advance the Flash's write pointer (even though we aren't writing the SectorInfo data)
		        //we often erase block when write data to this sector, so write 0xff will not overlay the former data.
		           for(i=0; i<sizeof(SectorInfo); i++)
		           {
                    			NF_WRDATA(0xff);
		           }
	       }
//RETAILMSG(1,(TEXT("NandFlash FMD_WriteSector startSectorAddr %d\r\n"),startSectorAddr));	  
//RETAILMSG(1,(TEXT("NandFlash FMD_WriteSector ECC %x\r\n"),dwECCVal));
//RETAILMSG(1,(TEXT("NandFlash FMD_WriteSector ECCD0 %x\r\n"),dwECCD0));
//RETAILMSG(1,(TEXT("NandFlash FMD_WriteSector ECCD1 %x\r\n"),dwECCD1));

        	//  ECC stuff should be here
        	ECCBuf[0] = (BYTE) ((dwECCVal) & 0xff);
        	ECCBuf[1] = (BYTE) ((dwECCVal >> 8) & 0xff);
        	ECCBuf[2] = (BYTE) ((dwECCVal >> 16) & 0xff);
        	ECCBuf[3] = (BYTE) ((dwECCVal >> 24) & 0xff);
        
//RETAILMSG(1,(TEXT("NandFlash FMD_WriteSector ECCBuf %x %x %x %x\r\n"),ECCBuf[3],ECCBuf[2],ECCBuf[1],ECCBuf[0]));  
 
         	//  Write the ECC value to the flash
         	for(i=0; i<4; i++) 
		{
             		NF_WRDATA(ECCBuf[i]);
         	}     	
            	pSectorBuff += NAND_PAGE_SIZE;
        }//end else psectorbuff
        
    	NF_CLEAR_RB();    
    	NF_CMD(CMD_WRITE2);                    // Send write confirm command.
     	//  Wait for RB
	NF_DETECT_RB();	 // Wait tR(max 12us)

  	//  Check the status
    	NF_CMD(CMD_STATUS);
    	Status = NF_RDDATA();
    	if (Status & 1)
    	{
        	NF_nFCE_H();                            // Deselect the flash chip.
		RETAILMSG(1,(TEXT("ERROR: FMD_WriteSector: failed sector write.\r\n")));
		bRet = FALSE;    
        }
    	NF_nFCE_H();                            // Deselect the flash chip.

	RELEASEMUTEX();             //Relase when last!

    	return bRet;
}
static BOOL IsBlockBad1G08(BLOCK_ID blockID)
{
    	BYTE Data1,Data2;
    	BOOL    bRet = FALSE;
    	SECTOR_ADDR blockPage = (blockID * NAND_PAGE_CNT);
		
	GRABMUTEX();          //we should MUTEX first

	NF_nFCE_L();
	NF_WAITRnB();
	
	NF_CLEAR_RB();
       NF_CMD(0x00);	// Read command
       NF_ADDR((2048+0)&0xff);			
	NF_ADDR(((2048+0)>>8)&0xff);
       NF_ADDR((blockPage)&0xff);	// A[19:12]
       NF_ADDR((blockPage>>8)&0xff);	// A[27:20]
	#if (K9F2G08_SUPPORT||K9F4G08_SUPPORT||K9F8G08_SUPPORT)
	if((g_pNandFlashChip->FlashID!=0xECF1)&&(g_pNandFlashChip->FlashID!=0xECA1))
		NF_ADDR((blockPage>>16)&0xff);
	#endif
       NF_CLEAR_RB();
       NF_CMD(0x30);	// 2'nd command
       NF_DETECT_RB();	
       Data1=NF_RDDATA();

	blockPage++;         //in K9F1G08 Datasheet,you should check 1st and 2nd page in this block   
	NF_CLEAR_RB();
       NF_CMD(0x00);	// Read command
       NF_ADDR((2048+0)&0xff);			
	NF_ADDR(((2048+0)>>8)&0xff);
       NF_ADDR((blockPage)&0xff);	// A[19:12]
       NF_ADDR((blockPage>>8)&0xff);	// A[27:20]
	#if (K9F2G08_SUPPORT||K9F4G08_SUPPORT||K9F8G08_SUPPORT)
	if((g_pNandFlashChip->FlashID!=0xECF1)&&(g_pNandFlashChip->FlashID!=0xECA1))
		NF_ADDR((blockPage>>16)&0xff);
	#endif
       NF_CLEAR_RB();
       NF_CMD(0x30);	// 2'nd command
       NF_DETECT_RB();	
       Data2=NF_RDDATA();

    	if((0xff != Data1) || (0xff != Data2))
    	{
		RETAILMSG(1,(TEXT("IsBlockBad(%d): TRUE\r\n"),blockID));
        	bRet = TRUE;
    	}

    	NF_nFCE_H();            // Deassert the flash chip.
    	
    	RELEASEMUTEX();
    	return bRet;
}

static BOOL MarkBlockBad1G08(BLOCK_ID blockID)
{
    	BYTE Status;
    	ULONG blockPage = (blockID * NAND_PAGE_CNT);    // Convert block address to page address.

	GRABMUTEX();          //we should MUTEX first
	
    	NF_nFCE_L();            // Select the flash chip.
	NF_WAITRnB();
    	NF_CLEAR_RB();

	NF_CMD(0x80);   // Write 1st command
	
	NF_ADDR((2048+0)&0xff);			// 2060 = 0x080c
	NF_ADDR(((2048+0)>>8)&0xff);	// A[10:8]
	NF_ADDR((blockPage)&0xff);	// A[11;18]
	NF_ADDR((blockPage>>8)&0xff);	// A[26:19]	
	#if (K9F2G08_SUPPORT||K9F4G08_SUPPORT||K9F8G08_SUPPORT)
	if((g_pNandFlashChip->FlashID!=0xECF1)&&(g_pNandFlashChip->FlashID!=0xECA1))
		NF_ADDR((blockPage>>16)&0xff);
	#endif
	
	NF_WRDATA(0);	// Write Bad block information

	NF_CLEAR_RB();
	NF_CMD(CMD_WRITE2);        // Send write confirm command.
    	//  Wait for RB
	NF_DETECT_RB();	 // Wait tR(max 12us)

    	//  Get the status
    	NF_CMD(CMD_STATUS);
    	Status = NF_RDDATA();    // Read command status.
    	NF_nFCE_H();            // Deassert the flash chip.

    	RELEASEMUTEX();
    	return((Status & 1) ? FALSE : TRUE);
}

⌨️ 快捷键说明

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