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 + -
显示快捷键?