fmd.c

来自「ebd9307开发板wince bsp源码,包括cs8900,lcd,nand,」· C语言 代码 · 共 801 行 · 第 1/2 页

C
801
字号
	{
		if(!MarkBlockBad(blockID))
		{
			RETAILMSG(1, (TEXT("M Error")));
			return FALSE;
		}
	}
	if (dwStatus & (BLOCK_STATUS_READONLY | BLOCK_STATUS_RESERVED)) {
        	if (!FMD_ReadSector(sectorAddr, 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 (sectorAddr, NULL, &SI, 1)) 
            		return FALSE;
	}
	return TRUE;
}



BOOL FMD_WriteSector(SECTOR_ADDR startSectorAddr,
			LPBYTE pSectorBuff,
			PSectorInfo pSectorInfoBuff,
			DWORD dwNumSectors)
{
	UCHAR ucAddr[3],ucStatus = 0;
	ULONG i;
	BOOL bRet = TRUE;
	
	GRABMUTEX();
	ucAddr[0] = (UCHAR)(startSectorAddr & 0xff);
	ucAddr[1] = (UCHAR)((startSectorAddr >> 8) & 0xff);
	ucAddr[2] = (UCHAR)((startSectorAddr >> 16) & 0xff);
	
	if(!pSectorBuff && !pSectorInfoBuff || dwNumSectors >1)
	{
		NKDbgPrintfW(TEXT("Write sector failed.\r\n"));
		bRet = FALSE;
		goto Exit;
	}
	
	NF_Reset();
	
	if(!pSectorBuff){
	
		DelayInuSecond(5);
		NF_CE_L();
		DelayInuSecond(5);
		CheckBusy();
		DelayInuSecond(5);
		NF_CLE_H();
		DelayInuSecond(5);
		WriteByte(CMD_READ2);
		DelayInuSecond(5);
		NF_CLE_L();
		DelayInuSecond(5);
		CheckBusy();
		DelayInuSecond(5);
		NF_CLE_H();
		DelayInuSecond(5);
		WriteByte(CMD_WRITE);
		DelayInuSecond(5);
		NF_CLE_L();
		DelayInuSecond(5);
		CheckBusy();
		DelayInuSecond(5);
		NF_ALE_H();
		DelayInuSecond(5);
		WriteByte(0x00);
		WriteByte(ucAddr[0]);
		WriteByte(ucAddr[1]);
		WriteByte(ucAddr[2]);
		DelayInuSecond(5);
		NF_ALE_L();
		DelayInuSecond(5);
		CheckBusy();
		DelayInuSecond(1);
		if(pSectorInfoBuff)
		{
			WriteByte((UCHAR)(pSectorInfoBuff->dwReserved1));
			WriteByte((UCHAR)(pSectorInfoBuff->dwReserved1>> 8 & 0xFF));
			WriteByte((UCHAR)(pSectorInfoBuff->dwReserved1>> 16 & 0xFF));
			WriteByte((UCHAR)(pSectorInfoBuff->dwReserved1>> 24 & 0xFF));
			WriteByte((UCHAR)(pSectorInfoBuff->bOEMReserved));
			WriteByte((UCHAR)(pSectorInfoBuff->bBadBlock));
			WriteByte((UCHAR)(pSectorInfoBuff->wReserved2));
			WriteByte((UCHAR)(pSectorInfoBuff->wReserved2 >> 8 & 0xFF));
		}
		DelayInuSecond(5);
		CheckBusy();
		NF_CLE_H();
		DelayInuSecond(5);
		WriteByte(CMD_WRITE2);
		DelayInuSecond(5);
		NF_CLE_L();
		DelayInuSecond(5);
		CheckBusy();
		DelayInuSecond(5);
		NF_CLE_H();
		DelayInuSecond(5);
		WriteByte(CMD_STATUS);
		DelayInuSecond(5);
		NF_CLE_L();
		DelayInuSecond(5);
		CheckBusy();
		ucStatus = ReadByte();
		DelayInuSecond(5);
		NF_CE_H();
		DelayInuSecond(5);
		if(ucStatus & 0x01)
		{
			RETAILMSG(1, (TEXT("Write Info failed!!  %d \r\n"),startSectorAddr));
			bRet = FALSE;
			goto Exit;
		}
		bRet = TRUE;
		goto Exit;
	}

	DelayInuSecond(5);
	NF_CE_L();
	DelayInuSecond(10);
	CheckBusy();
	NF_CLE_H();
	DelayInuSecond(5);
	WriteByte(CMD_WRITE);
	DelayInuSecond(5);
	NF_CLE_L();
	CheckBusy();
	DelayInuSecond(10);
	NF_ALE_H();
	DelayInuSecond(5);
	WriteByte(0x00);
	WriteByte(ucAddr[0]);
	WriteByte(ucAddr[1]);
	WriteByte(ucAddr[2]);
	DelayInuSecond(5);
	NF_ALE_L();
	DelayInuSecond(5);
	CheckBusy();
	DelayInuSecond(5);
	for(i=0; i<SECTOR_SIZE; i++)
	{
		WriteByte(*(pSectorBuff + i));
	}

	if(pSectorInfoBuff)
	{
		WriteByte((UCHAR)(pSectorInfoBuff->dwReserved1));
		WriteByte((UCHAR)(pSectorInfoBuff->dwReserved1>> 8 & 0xFF));
		WriteByte((UCHAR)(pSectorInfoBuff->dwReserved1>> 16 & 0xFF));
		WriteByte((UCHAR)(pSectorInfoBuff->dwReserved1>> 24 & 0xFF));
		WriteByte((UCHAR)(pSectorInfoBuff->bOEMReserved));
		WriteByte((UCHAR)(pSectorInfoBuff->bBadBlock));
		WriteByte((UCHAR)(pSectorInfoBuff->wReserved2));
		WriteByte((UCHAR)(pSectorInfoBuff->wReserved2 >> 8 & 0xFF));
	}


	DelayInuSecond(5);
	CheckBusy();
	NF_CLE_H();
	DelayInuSecond(5);
	WriteByte(CMD_WRITE2);
	DelayInuSecond(5);
	NF_CLE_L();
	DelayInuSecond(5);
	CheckBusy();
	DelayInuSecond(5);
	NF_CLE_H();
	DelayInuSecond(5);
	WriteByte(CMD_STATUS);
	DelayInuSecond(5);
	NF_CLE_L();
	DelayInuSecond(5);
	CheckBusy();
	DelayInuSecond(1);
	ucStatus = ReadByte();
	DelayInuSecond(5);
	NF_CE_H();
	DelayInuSecond(5);

	if(ucStatus & 0x01)
	{
		RETAILMSG(1, (TEXT("Write Sector failed %d \r\n"),startSectorAddr));
		bRet = FALSE;
	}
	
Exit: 	
	RELEASEMUTEX();
	
    return bRet;
}


BOOL IsBlockBad(BLOCK_ID blockID)
{
	DWORD dwPage_ID = blockID << 5;
	UCHAR ucFlag,ucAddr[3];
	GRABMUTEX();
	ucAddr[0] = (UCHAR)(dwPage_ID & 0xff);
	ucAddr[1] = (UCHAR)((dwPage_ID >> 8) & 0xff);
	ucAddr[2] = (UCHAR)((dwPage_ID >> 16) & 0xff);

	NF_Reset();
	DelayInuSecond(5);
	NF_CE_L();
	DelayInuSecond(5);
	CheckBusy();
	DelayInuSecond(5);
	NF_CLE_H();
	DelayInuSecond(5);
	WriteByte(CMD_READ2);
	DelayInuSecond(5);
	NF_CLE_L();
	DelayInuSecond(5);
	CheckBusy();
	DelayInuSecond(5);
	NF_ALE_H();
	DelayInuSecond(5);
	WriteByte(VALIDADDR);
	WriteByte(ucAddr[0]);
	WriteByte(ucAddr[1]);
	WriteByte(ucAddr[2]);
	DelayInuSecond(5);
	NF_ALE_L();
	DelayInuSecond(5);
	CheckBusy();
	ucFlag = ReadByte();
	DelayInuSecond(5);
	NF_CE_H();
	DelayInuSecond(5);

	RELEASEMUTEX();
	if(ucFlag != 0xff)
		return TRUE;
	return FALSE;
}

BOOL MarkBlockBad(BLOCK_ID blockID)
{
	DWORD dwPageID = blockID << 5;
	UCHAR ucAddr[3],ucFlag;
	
	GRABMUTEX();
	ucAddr[0] = (UCHAR)(dwPageID & 0xff);
	ucAddr[1] = (UCHAR)((dwPageID >> 8) & 0xff);
	ucAddr[2] = (UCHAR)((dwPageID >> 16) & 0xff);
	
	NF_Reset();

	DelayInuSecond(5);
	NF_CE_L();
	DelayInuSecond(5);
	CheckBusy();
	DelayInuSecond(5);
	NF_CLE_H();
	DelayInuSecond(5);
	WriteByte(CMD_READ2);
	DelayInuSecond(5);
	NF_CLE_L();
	DelayInuSecond(5);
	CheckBusy();
	DelayInuSecond(5);
	NF_CLE_H();
	DelayInuSecond(5);
	WriteByte(CMD_WRITE);
	DelayInuSecond(5);
	NF_CLE_L();
	DelayInuSecond(5);
	CheckBusy();
	DelayInuSecond(5);
	NF_ALE_H();
	DelayInuSecond(5);
	WriteByte(VALIDADDR);
	WriteByte(ucAddr[0]);
	WriteByte(ucAddr[1]);
	WriteByte(ucAddr[2]);
	DelayInuSecond(5);
	NF_ALE_L();
	DelayInuSecond(5);
	CheckBusy();
	WriteByte(BADBLOCKMARK);
	DelayInuSecond(5);
	NF_CLE_H();
	DelayInuSecond(5);
	CheckBusy();
	WriteByte(CMD_WRITE2);
	DelayInuSecond(5);
	NF_CLE_L();
	DelayInuSecond(5);
	CheckBusy();
	DelayInuSecond(5);
	NF_CLE_H();
	DelayInuSecond(5);
	WriteByte(CMD_STATUS);
	DelayInuSecond(5);
	NF_CLE_L();
	DelayInuSecond(5);
	CheckBusy();
	ucFlag = ReadByte();
	DelayInuSecond(5);
	NF_CE_H();
	DelayInuSecond(5);
	
	RELEASEMUTEX();
	if(ucFlag & STATUS_ERROR)
	{
		RETAILMSG(1, (TEXT("M Error")));
		return FALSE;
	}
	return TRUE;
}


BOOL FMD_ReadSpare(DWORD dwStartPage, LPBYTE pBuff, DWORD dwNumPages)
{
	DWORD i,j;
	UCHAR ucAddr[3];

	ucAddr[0] = (UCHAR)(dwStartPage & 0xff);
	ucAddr[1] = (UCHAR)((dwStartPage >> 8) & 0xff);
	ucAddr[2] = (UCHAR)((dwStartPage >> 16) & 0xff);

	NF_Reset();
	DelayInuSecond(1);
	NF_CE_L();
	DelayInuSecond(1);
	NF_CLE_H();
	DelayInuSecond(1);
	WriteByte(CMD_READ2);
	DelayInuSecond(1);
	NF_CLE_L();
	DelayInuSecond(1);
	WriteByte(0x00);
	DelayInuSecond(1);
	WriteByte(ucAddr[0]);
	DelayInuSecond(1);
	WriteByte(ucAddr[1]);
	DelayInuSecond(1);
	WriteByte(ucAddr[2]);
	DelayInuSecond(1);
	NandWaitBusy()
	DelayInuSecond(1);
	for(i=0; i<dwNumPages; i++)
	{
		for(j=0; j<16; j++)
		{
			pBuff[i*16 + j] = ReadByte();
			DelayInuSecond(1);
		}
			
	}
	DelayInuSecond(1);
	NF_CE_H();
	DelayInuSecond(1);

	return TRUE;
}

void CheckBusy(void)
{
	UINT i;
	for(i=0; i<600; i++);
	NandWaitBusy()
	for(i=0; i<100; i++);
}

static void DelayInuSecond(ULONG ulMicroSec)
{
    LARGE_INTEGER liStart, liCurrent;
    BOOL b;
    b = QueryPerformanceCounter(&liStart);
    ASSERT(b);
    
    do
    {
        Sleep(0);
        b = QueryPerformanceCounter(&liCurrent);
        ASSERT(b);
    } while((liStart.QuadPart + (LONGLONG)ulMicroSec) >=liCurrent.QuadPart);
}


void GRABMUTEX()
{
    if (g_bTakeMutex) {
        WaitForSingleObject(g_hMutex, INFINITE);
    }
}

void RELEASEMUTEX()
{
    if (g_bTakeMutex) {
        ReleaseMutex(g_hMutex);
    }
}

⌨️ 快捷键说明

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