fmd.c

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

C
801
字号
#include <hwdefs.h>
#include <windows.h>
#include <pcireg.h>
#include <ceddk.h>
#include "Nand.h"

#define NandFlashPHYIO   (0x70000000)

HANDLE g_hMutex = NULL;

BOOL g_bTakeMutex = TRUE;

void CheckBusy(void);


volatile PUCHAR NandFlashVIO;

void GRABMUTEX();
void RELEASEMUTEX();

BOOL NF_Reset(void);
BOOL IsBlockBad(BLOCK_ID blockID);
BOOL MarkBlockBad(BLOCK_ID blockID);
static void DelayInuSecond(ULONG ulMicroSec);


BOOL NandInit(void)
{
	*GPIO_PFDDR |= 0xA1;
	*GPIO_PBDDR &= 0x7F;
	
	*SMC_SMCBCR7 &= 0xCFFFFFFF;
	NF_Reset();

	return TRUE;
}


BOOL NF_Reset(void)
{
	GRABMUTEX();
	
	DelayInuSecond(5);
	NF_CE_L();
	DelayInuSecond(5);
	NF_ALE_L();
	DelayInuSecond(5);
	NF_CLE_H();
	DelayInuSecond(5);
	WriteByte(CMD_RESET);
	DelayInuSecond(5);
	NF_CLE_L();
	DelayInuSecond(5);
	CheckBusy();
	DelayInuSecond(5);
	NF_CE_H();
	DelayInuSecond(5);
	
	RELEASEMUTEX();

	return TRUE;
}


BOOL FMD_Deinit(PVOID hFMD)
{
	RETAILMSG(1, (TEXT("Nand Flash:FMD_Deinit...\r\n")));
	
	CloseHandle(g_hMutex);
	
	VirtualFree((LPVOID)(NandFlashVIO), 0, MEM_RELEASE);
	return TRUE;
}


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

	if(blockID < IMAGE_BLOCK)
	{
		bRet =  FALSE;
		goto ExitE;
	}

	NF_Reset();
	DelayInuSecond(5);
	NF_CE_L();
	DelayInuSecond(5);
	CheckBusy();
	DelayInuSecond(5);
	NF_CLE_H();
	DelayInuSecond(5);
	WriteByte(CMD_ERASE);
	DelayInuSecond(5);
	NF_CLE_L();
	DelayInuSecond(10);
	NF_ALE_H();
	DelayInuSecond(5);
	WriteByte(ucAddr[0]);
	WriteByte(ucAddr[1]);
	WriteByte(ucAddr[2]);
	DelayInuSecond(5);
	NF_ALE_L();
	DelayInuSecond(5);
	CheckBusy();
	DelayInuSecond(5);
	NF_CLE_H();
	DelayInuSecond(5);
	WriteByte(CMD_ERASE2);
	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);
	for(i=0; i<100; i++);
	ucFlag = ReadByte();
	DelayInuSecond(5);
	NF_CE_H();
	DelayInuSecond(5);

	if(ucFlag & STATUS_ERROR)
	{
		RETAILMSG(1, (TEXT("Erase %d Block Error.\r\n"),blockID));
		bRet = FALSE;
	}

ExitE:
	RELEASEMUTEX();
	
	return bRet;
}


DWORD FMD_GetBlockStatus(BLOCK_ID blockID)
{
	SECTOR_ADDR sectorAddr = blockID << 5;
	SectorInfo SI;
	DWORD dwResult = 0;

	if (IsBlockBad (blockID))
        	return BLOCK_STATUS_BAD;
        	
	if(!FMD_ReadSector(sectorAddr, NULL, &SI,1))
	{
		return BLOCK_STATUS_UNKNOWN;
	}
	
	if(!(SI.bOEMReserved & OEM_BLOCK_READONLY))
	{
		dwResult |= BLOCK_STATUS_READONLY;
	}
	
	if(!(SI.bOEMReserved & OEM_BLOCK_RESERVED))  
       		dwResult |= BLOCK_STATUS_RESERVED;

	return dwResult;
}


BOOL FMD_GetInfo(PFlashInfo pFlashInfo)
{
	RETAILMSG(1, (TEXT("Nand Flash:FMD_GetInfo...\r\n")));
	pFlashInfo->flashType               = NAND;
	pFlashInfo->dwNumBlocks             = NUM_BLOCKS;
	pFlashInfo->dwBytesPerBlock         = BYTES_PER_BLOCK;
	pFlashInfo->wDataBytesPerSector     = SECTOR_SIZE;
	pFlashInfo->wSectorsPerBlock        = SECTORS_PER_BLOCK;
	return(TRUE);
}


PVOID FMD_Init(LPCTSTR lpActiveReg,PPCI_REG_INFO pRegIn,PPCI_REG_INFO pRegOut)
{
	ULONG ulRet = 1;


	 if (g_hMutex == NULL)
         {
         	g_hMutex = CreateMutex(NULL, FALSE, TEXT("_FLASH_MUTEX_"));
        	// was mutex creation successful?
        	if (g_hMutex == NULL) 
        	{
                	RETAILMSG(1,(TEXT("FlashDrv!FMD!FMD_Init: Unable to create mutex\r\n")));
                }
        }
	
	NandFlashVIO = (volatile PUCHAR)(VirtualAlloc(0,0x04,MEM_RESERVE, PAGE_NOACCESS));
	if(NandFlashVIO == NULL)
	{
		RETAILMSG(1, (TEXT("Nand Flash:Initialize VirtualAlloc Failed...\r\n")));
	}
	
	
	if(!VirtualCopy(NandFlashVIO, (PVOID)(NandFlashPHYIO>>8), 0x04, PAGE_READWRITE | PAGE_NOCACHE | PAGE_PHYSICAL))
	{
		RETAILMSG(1, (TEXT("Nand Flash:Initialize VirtualCopy Failed...\r\n")));
		return FALSE;
	}

	NandInit();
	
	RETAILMSG(1, (TEXT("Nand Flash:Initialize...\r\n")));
	
	return (PVOID)(ulRet);
}


BOOL FMD_OEMIoControl(DWORD dwIoControlCode,
			PBYTE pInBuf,
			DWORD nInBufSize,
			PBYTE pOutBuf,
			DWORD nOutBufSize,
			PDWORD pByteReturned)
{
	
	/*
	switch(dwIoControlCode)
	{
		case IOCTL_FMD_GET_INTERFACE:
			//pOutBuf = (PBYTE)(&mFMDInterface);
			//nOutBufSize = sizeof(FMDInterface);
			NKDbgPrintfW(TEXT("IOCTL_FMD_GET_INTERFACE ...\r\n"));
			break;
			
		case IOCTL_FMD_SET_XIPMODE:
			NKDbgPrintfW(TEXT("IOCTL_FMD_SET_XIPMODE ...\r\n"));
			break;
			
		case IOCTL_FMD_LOCK_BLOCKS:
			NKDbgPrintfW(TEXT("IOCTL_FMD_LOCK_BLOCKS ...\r\n"));
			break;
			
		case IOCTL_FMD_UNLOCK_BLOCKS:
			NKDbgPrintfW(TEXT("IOCTL_FMD_UNLOCK_BLOCKS: ...\r\n"));
			break;
			
		case IOCTL_FMD_GET_XIPMODE:
			NKDbgPrintfW(TEXT("IOCTL_FMD_GET_XIPMODE ...\r\n"));
			break;
			
		default:
			NKDbgPrintfW(TEXT("default ...\r\n"));
			return FALSE;
	}
	*/
	return FALSE;
}


VOID FMD_PowerDown(VOID)
{
	return;
}

VOID FMD_PowerUp(VOID)
{
	return;
}


BOOL FMD_ReadSector(SECTOR_ADDR startSectorAddr,
			LPBYTE pSectorBuff,
			PSectorInfo pSectorInfoBuff,
			DWORD dwNumSectors)
{
	ULONG i;
	UCHAR ucAddr[3];
	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("Read sector failed!!\r\n"));
		bRet = FALSE;
		goto ExitR;
	}
	
	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_ALE_H();
		DelayInuSecond(5);
		WriteByte(0x00);
		WriteByte(ucAddr[0]);
		WriteByte(ucAddr[1]);
		WriteByte(ucAddr[2]);
		DelayInuSecond(5);
		NF_ALE_L();
		DelayInuSecond(5);
		CheckBusy();
		if(pSectorInfoBuff)
		{
			pSectorInfoBuff->dwReserved1 = ReadByte();
			pSectorInfoBuff->dwReserved1 |= ReadByte() <<8;
			pSectorInfoBuff->dwReserved1 |= ReadByte() <<16;
			pSectorInfoBuff->dwReserved1 |= ReadByte() <<24;
			pSectorInfoBuff->bOEMReserved = ReadByte();
			pSectorInfoBuff->bBadBlock = ReadByte();
			pSectorInfoBuff->wReserved2 = ReadByte();
			pSectorInfoBuff->wReserved2 |= ReadByte() <<8;
		}
		DelayInuSecond(5);
		NF_CE_H();
		DelayInuSecond(5);
			
		bRet = TRUE;
		goto ExitR;
	}

	DelayInuSecond(5);
	NF_CE_L();
	DelayInuSecond(5);
	CheckBusy();
	DelayInuSecond(5);
	NF_CLE_H();
	DelayInuSecond(5);
	WriteByte(CMD_READ);
	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(5);
	for(i=0; i<SECTOR_SIZE; i++)
	{
		*(pSectorBuff + i) = ReadByte();
	}
		
	if(pSectorInfoBuff != NULL)
	{
		pSectorInfoBuff->dwReserved1 = ReadByte();
		pSectorInfoBuff->dwReserved1 |= ReadByte() << 8;
		pSectorInfoBuff->dwReserved1 |= ReadByte() << 16;
		pSectorInfoBuff->dwReserved1 |= (ReadByte() << 24);
		pSectorInfoBuff->bOEMReserved = ReadByte();
		pSectorInfoBuff->bBadBlock = ReadByte();
		pSectorInfoBuff->wReserved2 = ReadByte();
		pSectorInfoBuff->wReserved2 |= ReadByte() << 8;
	}

	DelayInuSecond(5);
	NF_CE_H();
	DelayInuSecond(5);
	
ExitR:
	RELEASEMUTEX();
	return bRet;	
}																	 					




BOOL FMD_SetBlockStatus(BLOCK_ID blockID,DWORD dwStatus)
{
	SECTOR_ADDR sectorAddr = blockID << 5;
	SectorInfo SI;
	BYTE bStatus = 0;

	if(dwStatus & BLOCK_STATUS_BAD)

⌨️ 快捷键说明

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