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

📄 pci.c

📁 用C语言设计的EPSON LCD控制器S1D13700驱动。
💻 C
📖 第 1 页 / 共 2 页
字号:
//===========================================================================
//	PCI.C
// (Tabs set to every 4)
//---------------------------------------------------------------------------
//  Copyright (c) 2002, 2003 Epson Research and Development, Inc.
//  All Rights Reserved.
//===========================================================================
#include <windows.h>
#include <winioctl.h>

#include "pcibridge.h"
#include "s1d_ioctl.h"

static int			gLastError;				// PCIBridge last error code
static HANDLE		ghPCIDriver;			// Handle to PCI driver
static UInt32		gPCIAddress;			// Pointer to PCI memory

static ISR_STRUCT	gISRInfo;				// Interrupt Service Routine info passed to PCI driver
static DWORD		ghISRId;				// Handle to driver-returned ISR ID (0-31)

static PISR_CALLBACK gpISRCallback;			// Application supplied callback function
static Boolean		gfISRHooked;			// True if device driver has hooked ISR

static void		UnhookInterrupt( void );
static Boolean	DispatchPCIInterrupt( LPVOID hISREvent );
static int		Pci2Hal( Boolean fPCIResult );


//===========================================================================
// PRIVATE GLOBAL VARIABLES (local to HAL only)
//===========================================================================
#define HAL_STRUCT_NAME HalInfo

	typedef struct tagDataStruct
	{
		const char *pszHALRevision;		// Full HAL revision string, in SourceSafe format.
		const char *pszLIBRevision;		// Full LIB revision string, in SourceSafe format.
		const char *pszCopyright;		// Epson Copyright text
		UInt32		BaseAddress;		// HAL acquired base address (virtual)
		UInt32		RegisterAddress;	// HAL acquired register address (virtual)
		UInt32		MemoryAddress;		// HAL acquired memory address (virtual)
		UInt32		BlockSize;			// HAL acquired memory block size (bytes)
		int			nErrorCode;			// HAL error code value
		Boolean		fDebugRegWrites;	// True if debugging all register writes
		Boolean		fDebugHalDelay;		// True if debugging HAL delays
	} DATA_STRUCT,*PDATA_STRUCT;

static DATA_STRUCT gHD;


// CRITICAL: The messages in this array MUST correspond to the error codes contained in the HAL.H enumeration.

enum
{
	ERR_NONE = 0,				// No error, call was successful.
	ERR_PCI_DRIVER_NOT_FOUND,	// The file SED13xx.VxD was not found/loaded.
	ERR_PCI_ADAPTER_NOT_FOUND,	// The VxD was unable to locate the LCD controller.
	ERR_NOT_ACQUIRED,			// The controller has not been acquired.
	ERR_IRQ_FAILURE,			// The interrupt handler failed.
	ERR_FAILED					// Catch-all error condition.
};


static const char * const gapszErrMsg[ERR_FAILED + 1] =
{
	"There was no error detected",					// ERR_NONE
	"Unable to find/load the S1D13xxx driver",		// ERR_PCI_DRIVER_NOT_FOUND
	"Unable to locate an S1D13xxx controller",		// ERR_PCI_ADAPTER_NOT_FOUND
	"The controller has not been acquired",			// ERR_NOT_ACQUIRED
	"IRQ interrupt handler failure",				// ERR_IRQ_FAILURE
	"An unspecified error occured"					// ERR_FAILED
};


const DATA_STRUCT* const gpHalData = &gHD;


int halpMapPhysicalToVirtual( UInt32 PhysicalAddr, UInt32 *pVirtualAddr, UInt32 *pBlockSize );

//---------------------------------------------------------------------------
//  FUNCTION:	halAcquireController()
//
//  DESCRIPTION:
//		This is the discovery portion of the the start-up sequence.
//		On the Intel platform, halAcquireController() initiates the link
//		between the application and the hardware by attempting to load
//		S1D13xxx.VxD. If the driver is loaded successfully then a call
//		is made to the VxD to determine the presence and the address
//		of the S1D13700. On all other platforms, this routine takes
//		the register and display memory addresses provided by 13700CFG.
//
//		This routine MUST be called before any other call to the HAL is made!
//		(i.e. halInitController)
//		
//		Applications can call this routine only to obtain pointers to the
//		registers and display memory and from there take over all access
//		to the S1D13700.
//
//  PARAMETERS:
//		pMem - Pointer to receive the address of the first byte of display
//			   memory.
//		pReg - Pointer to receive the address of the first byte of register
//			   space.
//
//  RETURNS:
//		TRUE if the routine is able to locate an S1D13700.
//			*pMem will be the address of the first byte of display memory.
//			*pReg will be the address of the first 13700 control register.
//		FALSE if an S1D13700 is not located.
//			If additional error information is required call
//			halGetLastError().
//
//	MODIFIES:
//		This routine does not modify any register contents.
//---------------------------------------------------------------------------
int AcquireController( UInt32 * pMem )
{
	static Boolean fFirstTime = FALSE;
	gHD.nErrorCode = ERR_NONE;

	if( gHD.BaseAddress == 0 )		// Only do this once, so we are re-entrant.
	{
		gHD.nErrorCode = halpMapPhysicalToVirtual( 0, &gHD.BaseAddress, &gHD.BlockSize );

		if( gHD.nErrorCode != ERR_NONE )
		{
			gHD.BaseAddress = 0;
			return FALSE;
		}

		gHD.MemoryAddress   = gHD.BaseAddress;
	}

	if( pMem )	*pMem = gHD.BaseAddress;

	return TRUE;
}



//---------------------------------------------------------------------------
// PUBLIC FUNCTION: pcibMapAddress()
//---------------------------------------------------------------------------
int pcibMapAddress( UInt32 PhysicalAddr, UInt32 *pVirtualAddr, UInt32 *pBlockSize )
{
	BOOL	fRet;
	DWORD	nReturned;
	UInt32	aRetPCI[3];

	gLastError = PCIB_ERR_NONE;

	// Free and release driver, if one's currently in use.  This makes
	// this function and halAquireController() fully rentrant so they
	// can be called multiple times, if required by the application.

	pcibUnmapAddress();

	// Determine the operating system we are running under and act accordingly.

	if ( GetVersion() < 0x80000000 )	// Open the device using NT semantics.
		ghPCIDriver = CreateFile( "\\\\.\\S1D13xxx", GENERIC_READ | GENERIC_WRITE,	0, NULL, OPEN_EXISTING,	FILE_FLAG_OVERLAPPED,		NULL );
	else								// Open the device using Win9x semantics.
		ghPCIDriver = CreateFile( "\\\\.\\S1D13xxx.VXD", 0,							0, NULL, CREATE_NEW,	FILE_FLAG_DELETE_ON_CLOSE,	NULL );

	// If we have an invalid handle then we couldn't open the driver.

	if ( ghPCIDriver != INVALID_HANDLE_VALUE )
	{
		OVERLAPPED OverLapped;
		ZeroMemory( &OverLapped, sizeof(OverLapped) );

		if ( PhysicalAddr == 0 )		// Map in a PCI Board
		{
			char Buffer[32];
			int boardnum = 0;

			// Check the environment for: S1DBOARD=n
			// This is for rare situations where there are multiple PCI boards and a command prompt window
			// can be assigned to a particular PCI board using the environment variable.

			if ( GetEnvironmentVariable("S1DBOARD",Buffer,sizeof(Buffer)) )
				boardnum = atoi( Buffer );

			// Get virtual address into our PCI array ([0]=virtual, [1]=physical, [2]=blocksize (future))

			fRet = DeviceIoControl( ghPCIDriver, IOCTL_SED_MAP_PCI_BOARD, &boardnum, sizeof(boardnum), aRetPCI, sizeof(aRetPCI), &nReturned, &OverLapped );
			gPCIAddress = aRetPCI[0];
		}
		else							// The user insists on a particular physical address
		{
			aRetPCI[0] = PhysicalAddr;
			aRetPCI[1] = ISA_BLOCK_SIZE;
			fRet = DeviceIoControl( ghPCIDriver, IOCTL_SED_MAP_PHYSICAL_MEMORY, aRetPCI, sizeof(aRetPCI), &gPCIAddress, sizeof(gPCIAddress), &nReturned, &OverLapped );
		}

		if ( fRet )
		{
			if ( pVirtualAddr )
				*pVirtualAddr = gPCIAddress;

			if ( pBlockSize )
			{
				if ( nReturned > 2*sizeof(aRetPCI[0]) )
					*pBlockSize = aRetPCI[2];
				else
					*pBlockSize = PCI_BLOCK_SIZE;
			}
		}
		else
		{
			gPCIAddress = 0;
			gLastError = PCIE_ERR_ADAPTER_NOT_FOUND;
		}
	}
	else
	{
		ghPCIDriver = NULL;
		gLastError = PCIB_ERR_DRIVER_NOT_FOUND;
	}

	return (gLastError == PCIB_ERR_NONE);
}



//---------------------------------------------------------------------------
// PUBLIC FUNCTION: pcibUnmapAddress()
//---------------------------------------------------------------------------
void pcibUnmapAddress( void )
{
	DWORD nReturned;

	// Free up any active interrupt objects to ensure handles are sync'd with resources.

	UnhookInterrupt();

	// Only free up these resources, if they are currently allocated and in use.

	if ( ghPCIDriver )
	{
		// We already have a handle to the driver and the memory we wish to free.
		// Simply call the driver with the appropriate values to free the our memory.

		if ( gPCIAddress )
		{
			OVERLAPPED OverLapped;
			ZeroMemory( &OverLapped, sizeof(OverLapped) );

			DeviceIoControl( ghPCIDriver, IOCTL_SED_UNMAP_LINEAR_MEMORY, &gPCIAddress, sizeof(gPCIAddress), NULL, 0, &nReturned, &OverLapped );
			gPCIAddress = 0;
		}

		// Close the handle. This also dynamically UNLOADs the driver under Win9x.

⌨️ 快捷键说明

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