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

📄 fmd.cpp

📁 SMDK2450的BSP 有很多新的特性,记得升级PB啊.
💻 CPP
📖 第 1 页 / 共 4 页
字号:
	NF_CLEAR_RB();	// NFSTAT狼 [4]甫 1肺 悸泼 ... RnB_TransDetect ... 
	
	//  Issue command
	NF_CMD(CMD_WRITE);	//0x80
	
	//  Setup address to write Main data
	NF_ADDR((NewDataAddr)&0xff);	// 2bytes for column address
	NF_ADDR((NewDataAddr>>8)&0xff);
	NF_ADDR((NewSectorAddr)&0xff);	// 3bytes for row address
	NF_ADDR((NewSectorAddr>>8)&0xff);
	if (LB_NEED_EXT_ADDR)
	{
		NF_ADDR((NewSectorAddr>>16)&0xff);
	}

	// Write each Sector in the Page. (4 Sector per Page, Loop 4 times.)
	for (nSectorLoop = 0; nSectorLoop < SECTORS_PER_PAGE; nSectorLoop++)
	{
		//  Initialize ECC register
		NF_RSTECC();
		NF_MECC_UnLock();
	
		// Special case to handle un-aligned buffer pointer.
		if( ((DWORD) (pSectorBuff+nSectorLoop*SECTOR_SIZE)) & 0x3) 
		{
			//  Write the data
			for(i=0; i<SECTOR_SIZE/sizeof(DWORD); i++)
			{
				wrdata = (pSectorBuff+nSectorLoop*SECTOR_SIZE)[i*4+0];
				wrdata |= (pSectorBuff+nSectorLoop*SECTOR_SIZE)[i*4+1]<<8;
				wrdata |= (pSectorBuff+nSectorLoop*SECTOR_SIZE)[i*4+2]<<16;
				wrdata |= (pSectorBuff+nSectorLoop*SECTOR_SIZE)[i*4+3]<<24;
				NF_WRDATA_WORD(wrdata);
			}
		}
		else
		{
			WrPage512(pSectorBuff+nSectorLoop*SECTOR_SIZE);
		}
	
		NF_MECC_Lock();
		
		//  Read out the ECC value generated by HW
		MECCBuf[nSectorLoop] = NF_RDMECC0();	// 秦寸 Sector俊 措茄 Main ECC 历厘 
	}
	
	// Random data input command for storing Spare area
	NF_CMD(CMD_RDI);

	// Set Address to access Spare area
	NF_ADDR((NewSpareAddr)&0xff);
	NF_ADDR((NewSpareAddr>>8)&0xff);
	
	// Write the SectorInfo data to the media
	// NOTE: This hardware is odd: only a byte can be written at a time and it must reside in the
	//       upper byte of a USHORT.
	if(pSectorInfoBuff)	// SectorInfoBuff啊 瞒 乐促搁, 角力 Sector Info甫 持绰促. 
	{
		// Initialize MECC module
		NF_RSTECC();
		NF_MECC_UnLock();
		// Write SectorInfo
		NF_WRDATA_BYTE(pSectorInfoBuff->bBadBlock);
		NF_WRDATA_WORD(pSectorInfoBuff->dwReserved1);
		NF_WRDATA_BYTE(pSectorInfoBuff->bOEMReserved);
		NF_MECC_Lock();		// SECC off

		// Store SECC parity code for SectorInfo
		SECCBuf1 = NF_RDMECC0();

		NF_WRDATA_BYTE(pSectorInfoBuff->wReserved2&0xff);
		NF_WRDATA_BYTE((pSectorInfoBuff->wReserved2>>8)&0xff);
	}
	else			// SectorInfoBuff啊 厚绢乐促搁, 歹固 data甫 持绰促. (0xffffffff ffffffff)
	{
		// Make sure we advance the Flash's write pointer (even though we aren't writing the SectorInfo data)
		for(i=0; i<sizeof(SectorInfo)/sizeof(DWORD); i++)
		{
			NF_WRDATA_WORD(0xffffffff);
		}
	}
	
	//  Write the Main ECC value to the flash (16 bytes for 4 sectors)
	// Initialize MECC module
	NF_RSTECC();
	NF_MECC_UnLock();

	// Store MECC parity code for main data... 16bytes
	NF_WRDATA_WORD(MECCBuf[0]);
	NF_WRDATA_WORD(MECCBuf[1]);
	NF_WRDATA_WORD(MECCBuf[2]);
	NF_WRDATA_WORD(MECCBuf[3]);

	NF_MECC_Lock();		// SECC off

	// Store MECC parity code for MECC parity code
	SECCBuf2 = NF_RDMECC0();

	// Store SECC1, SECC2
	NF_WRDATA_WORD(SECCBuf1);
	NF_WRDATA_WORD(SECCBuf2);	
	
	//  Finish up the write operation
	NF_CMD(CMD_WRITE2);	// 0x10
	
	//  Wait for RB. 促 结龙 锭 鳖瘤 扁促赴促. 
	NF_DETECT_RB();	 // Wait tR(max 12us)
	
	// Error啊 乐绰瘤 眉农茄促. 
	if ( NF_RDSTAT & STATUS_ILLACC )
	{
		RETAILMSG(1, (TEXT("FMD_WriteSector() ######## Error Programming page (Illigar Access) %d!\n"), startSectorAddr));
		s2450NAND->NFSTAT =  STATUS_ILLACC;	// Write 1 to clear.
		bRet = FALSE;
	}
	else
	{
		//  Check the status
		NF_CMD(CMD_STATUS);
	
		if(NF_RDDATA_BYTE() & STATUS_ERROR) {
			RETAILMSG(1, (TEXT("FMD_WriteSector() ######## Error Programming page %d!\n"), startSectorAddr));
			bRet = FALSE;
		}
	}
	
	//  Disable the chip
	NF_nFCE_H();
	
	SetKMode(bLastMode);	// Dummy function.
	
	return bRet;
}


BOOL NAND_LB_WriteSectorInfo(SECTOR_ADDR sectorAddr, PSectorInfo pInfo, int mode)
{
	BOOL    bRet = TRUE;
	int NewSpareAddr = 2048;
	int NewSectorAddr = sectorAddr;
	DWORD SECCBuf1;

	BOOL bLastMode = SetKMode(TRUE);

    	//  Chip enable
	NF_nFCE_L();

	NF_CLEAR_RB();

    	//  Write the command
    	//  First, let's point to the spare area
	NF_CMD(CMD_WRITE);

    	//  Write the address
	NF_ADDR((NewSpareAddr)&0xff);
	NF_ADDR((NewSpareAddr>>8)&0xff);
	NF_ADDR((NewSectorAddr)&0xff);
	NF_ADDR((NewSectorAddr>>8)&0xff);
	if (LB_NEED_EXT_ADDR)
	{
		NF_ADDR((NewSectorAddr>>16)&0xff);
	}

	// Initialize MECC module
	NF_RSTECC();
	NF_MECC_UnLock();

	//  Now let's write the SectorInfo data
 	//  Write the first reserved field (DWORD)
	NF_WRDATA_BYTE(pInfo->bBadBlock);
	NF_WRDATA_WORD(pInfo->dwReserved1);
	NF_WRDATA_BYTE(pInfo->bOEMReserved);

	NF_MECC_Lock();

	// Store generated MECC for SectorInfo
	SECCBuf1 = NF_RDMECC0();

	NF_WRDATA_BYTE(pInfo->wReserved2&0xff);
	NF_WRDATA_BYTE((pInfo->wReserved2>>8)&0xff);

	 //  Issue the write complete command
	NF_CMD(CMD_RDI);
	// Set address to access SECC1 in Spare Area
	NF_ADDR((NewSpareAddr+24)&0xff);
	NF_ADDR(((NewSpareAddr+24)>>8)&0xff);

	// Write SECC1
	NF_WRDATA_WORD(SECCBuf1);
	NF_CMD(CMD_WRITE2);

	 //  Check ready bit
	NF_DETECT_RB();	 // Wait tR(max 12us)

	// Check Write Status
	if ( NF_RDSTAT & STATUS_ILLACC )
	{
		RETAILMSG(1, (TEXT("NAND_LB_WriteSectorInfo() ######## Error Programming page (Illigar Access) %d!\n"), sectorAddr));
		s2450NAND->NFSTAT =  STATUS_ILLACC;	// Write 1 to clear.
       		bRet = FALSE;
	}
	else
	{
		//  Check the status of program
		NF_CMD(CMD_STATUS);

		if( NF_RDDATA_BYTE() & STATUS_ERROR) {
			RETAILMSG(1, (TEXT("NAND_LB_WriteSectorInfo() ######## Error Programming page %d!\n"), sectorAddr));
			bRet = FALSE;
		}
	}

	NF_nFCE_H();	// disable chip

	SetKMode(bLastMode);	// Dummy Function.

	return bRet;
}


// 茄 Page甫 烹掳肺 佬绢坷绰 function (Spare 康开 器窃)
BOOL RAW_LB_ReadPage(SECTOR_ADDR startSectorAddr, LPBYTE pSectorBuff, LPBYTE pSectorInfoBuff)
{
	UINT SectorAddr = (UINT)startSectorAddr;
	DWORD       i;
	volatile DWORD		rddata;	
	UINT32 SpareAddr = 2048;
	UINT32 ColAddr = 0;

	//RETAILMSG(1,(TEXT("#### FMD_DRIVER:::RAW_LB_ReadPage %x\r\n"),startSectorAddr));

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

	BOOL bLastMode = SetKMode(TRUE);

    	//  Enable Chip
	NF_nFCE_L();
	
	NF_CLEAR_RB();

	NF_CMD(CMD_READ);							// Send read command.

	NF_ADDR((ColAddr)&0xff);
	NF_ADDR(((ColAddr)>>8)&0xff);
	NF_ADDR((SectorAddr) & 0xff);
	NF_ADDR((SectorAddr>>8) & 0xff);
	if (LB_NEED_EXT_ADDR)
	{
		NF_ADDR((SectorAddr>>16) & 0xff);  
	}

	NF_CMD(CMD_READ3);	// 2nd command
	NF_DETECT_RB();								// Wait for command to complete.

	if( ((DWORD) pSectorBuff) & 0x3) 
	{
		for(i=0; i<(2048/sizeof(DWORD)); i++) {
			rddata = (DWORD) NF_RDDATA_WORD();
			pSectorBuff[i*4+0] = (BYTE)(rddata & 0xff);
			pSectorBuff[i*4+1] = (BYTE)(rddata>>8 & 0xff);
			pSectorBuff[i*4+2] = (BYTE)(rddata>>16 & 0xff);
			pSectorBuff[i*4+3] = (BYTE)(rddata>>24 & 0xff);
		}
	}
	else 
	{
		RdPage2048(pSectorBuff);					// Read page/sector data.
	}

	NF_CMD(CMD_RDO);
	//  Set up address
	NF_ADDR((SpareAddr)&0xff);
	NF_ADDR(((SpareAddr)>>8)&0xff);

	NF_CMD(CMD_RDO2);

	if (pSectorInfoBuff)
	{
		RdPageSpare((PBYTE)pSectorInfoBuff);		// Read page/sector information.
	}

	NF_nFCE_H();

	SetKMode (bLastMode);

	return(TRUE);
}	

BOOL RAW_SB_ReadPage(SECTOR_ADDR startSectorAddr, LPBYTE pSectorBuff, LPBYTE pSectorInfoBuff)
{
	ULONG SectorAddr = (ULONG)startSectorAddr;
	UINT32* pSBuf = (UINT32*)pSectorInfoBuff;

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

	BOOL bLastMode = SetKMode(TRUE);

	//RETAILMSG(1, (TEXT("FMD::FMD_SB_ReadSector 0x%x \r\n"), startSectorAddr));

	NF_nFCE_L();
	
	NF_CLEAR_RB();

	NF_CMD(CMD_READ);							// Send read command.

	NF_ADDR(0);									// Column = 0.
	NF_ADDR((SectorAddr)   &0xff);			// Page address.
	NF_ADDR((SectorAddr>>8)&0xff);
	if (SB_NEED_EXT_ADDR)
		NF_ADDR((SectorAddr>>16)&0xff);  

	NF_DETECT_RB();								// Wait for command to complete.
	
	if( ((DWORD) pSectorBuff) & 0x3) 
	{
		RdPage512Unalign (pSectorBuff);
	}
	else 
	{
		RdPage512(pSectorBuff);					// Read page/sector data.
	}

	if (pSectorInfoBuff)
	{
		*pSBuf++ = NF_RDDATA_WORD();
		*pSBuf++ = NF_RDDATA_WORD();
		*pSBuf++ = NF_RDDATA_WORD();
		*pSBuf++ = NF_RDDATA_WORD();
	}

	NF_nFCE_H();

	SetKMode (bLastMode);

	return(TRUE);
}


BOOL FMD_SB_WriteSector(SECTOR_ADDR startSectorAddr, LPBYTE pSectorBuff, PSectorInfo pSectorInfoBuff, DWORD dwNumSectors,int mode)
{
	BYTE Status;
	ULONG SectorAddr = (ULONG)startSectorAddr;
	ULONG MECC;

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

	//RETAILMSG(1,(TEXT("#### FMD_DRIVER:::FMD_sbwrite \r\n")));
		
	BOOL bLastMode = SetKMode(TRUE);

	NF_nFCE_L();						// Select the flash chip.

	while (dwNumSectors--)
	{
		if (!pSectorBuff)	// Only spare area
		{
			// If we are asked just to write the SectorInfo, we will do that separately
			NF_CMD(CMD_READ2);					 		// Send read command.

			NF_CMD(CMD_WRITE);							// Send write command.
			NF_ADDR(0);									// Column = 0.
			NF_ADDR(SectorAddr		 & 0xff);			// Page address.
			NF_ADDR((SectorAddr >>  8) & 0xff);
			if (SB_NEED_EXT_ADDR)
				NF_ADDR((SectorAddr >> 16) & 0xff);  

			// Write the SectorInfo data to the media.
			// Spare area[7:0]
			WrPageInfo((PBYTE)pSectorInfoBuff);

			NF_CLEAR_RB();
			NF_CMD(CMD_WRITE2);				// Send write confirm command.
			NF_DETECT_RB();

			NF_CMD(CMD_STATUS);
			Status = NF_RDDATA_BYTE();					// Read command status.
			
			if (Status & STATUS_ERROR)
			{
				NF_nFCE_H();							// Deselect the flash chip.
				SetKMode (bLastMode);
				return(FALSE);
			}
			pSectorInfoBuff++;
		}
		else 		// Main area+Spare area.
		{
			NF_CMD(CMD_READ);					 		// Send read command.
			NF_CMD(CMD_WRITE);							// Send write command.
			NF_ADDR(0);									// Column = 0.
			NF_ADDR(SectorAddr		 & 0xff);			// Page address.
			NF_ADDR((SectorAddr >>  8) & 0xff);
			if (SB_NEED_EXT_ADDR)
				NF_ADDR((SectorAddr >> 16) & 0xff);  

			//  Special case to handle un-aligned buffer pointer.
			NF_RSTECC();
			NF_MECC_UnLock();
			if( ((DWORD) pSectorBuff) & 0x3) 
			{
				WrPage512Unalign (pSectorBuff);
			}
			else
			{
				WrPage512(pSectorBuff);					// Write page/sector data.
			}
			NF_MECC_Lock();
			
			// Write the SectorInfo data to the media.
			// Spare area[7:0]
			if(pSectorInfoBuff)
			{
				WrPageInfo((PBYTE)pSectorInfoBuff);
				pSectorInfoBuff++;
			}
			else	// Make sure we advance the Flash's write pointer (even though we aren't writing the SectorInfo data)
			{
				BYTE TempInfo[] = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF};
				WrPageInfo(TempInfo);
			}

			// Write the SectorInfo data to the media.
			// Spare area[11:8]
			// Get the ECC data from status register.
			MECC = NF_RDMECC0();
			// Now, Write the ECC data to Spare area[11:8]
			NF_WRDATA_BYTE((UCHAR)((MECC	  ) & 0xff));		// Spare area offset 8
			NF_WRDATA_BYTE((UCHAR)((MECC >>  8) & 0xff));	// Spare area offset 9
			NF_WRDATA_BYTE((UCHAR)((MECC >> 16) & 0xff));	// Spare area offset 10
			NF_WRDATA_BYTE((UCHAR)((MECC >> 24) & 0xff));	// Spare area offset 11

			NF_CLEAR_RB();
			NF_CMD(CMD_WRITE2);							// Send write confirm command.
			NF_DETECT_RB();
			
			do
			{
				NF_CMD(CMD_STATUS);
				Status = NF_RDDATA_BYTE();					// Read command status.
			}while(!(Status & STATUS_READY));

			if (Status & STATUS_ERROR)
			{
				NF_nFCE_H();							// Deselect the flash chip.
				SetKMode (bLastMode);
				return(FALSE);
			}

⌨️ 快捷键说明

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