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

📄 hal_platform.c

📁 用C语言设计的EPSON LCD控制器S1D13700驱动。
💻 C
字号:
//===========================================================================
//	HAL_PLATFORM.C
//---------------------------------------------------------------------------
//
//  Copyright (c) 2002 Epson Research and Development, Inc.
//  All Rights Reserved.
//
//===========================================================================


#include <stdlib.h>
#include "hal_private.h"
#include "hal_platform.h"
#include "pcibridge.h"

#if defined(_WIN32)
  #define WIN32_LEAN_AND_MEAN
  #include <windows.h>
	static HANDLE	ghHalMutex;				// Process synchronization mutex handle

  #ifdef HAL_SIMULATE
	static HANDLE	ghSharedMemory;			// Handle to shared memory
	static VOID	   *gpSharedMemory;			// Pointer to shared memory
  #endif
#elif defined(_MSDOS)
  #include "dos32.h"
#endif



#define DEFAULT_BLOCK_SIZE	0x00400000UL			// Total size of PCI virtual memory block



static void		ExitHandler( void );
static int		Pci2Hal( Boolean fPCIResult );
static UInt32	Get13xxxBaseAddress( Boolean fEnable );
static int		AllocateSharedMemory( UInt32 PhysicalAddr, UInt32 *pVirtualAddr, UInt32 *pBlockSize );
static void		FreeSharedMemory( void );




//----------------------------------------------------------------------------
// PLATFORM FUNCTION: halpDelayUS()
//----------------------------------------------------------------------------
Boolean halpDelayUS( UInt32 microseconds )
{
#ifdef _WIN32

	static UInt32 NsPerTick = 0;
	__int64 nanoseconds = microseconds*1000i64;
	__int64 Count, Target;

	// Init the ns/Tick constant if this is the first time here.

	if ( !NsPerTick )
	{
		if ( QueryPerformanceFrequency((PLARGE_INTEGER)&Count) )
			NsPerTick = (UInt32)(1000000000i64/Count);
		else
			return FALSE;
	}

	// Exit OK if requested delay is too short.

	if ( nanoseconds < NsPerTick )
		return TRUE;

	// Get the starting initial counter value now.

	if ( !QueryPerformanceCounter((PLARGE_INTEGER)&Target) )
		return FALSE;

	// Calculate the terminal count of ticks required for requested delay.

	Target += nanoseconds/NsPerTick;

	// Loop until the counter exceeds the number of ticks in the requested delay.

	do
	{
		QueryPerformanceCounter( (PLARGE_INTEGER)&Count );
	} while ( Count < Target );

	return TRUE;

#elif defined(MV850E)

	volatile UInt32 i;
	volatile UInt32 adjust;

	adjust = (microseconds * 10L) / 18L;

	for (i = 0; i < adjust; ++i)
		continue;

	return TRUE;

#elif defined(_MSDOS)

	UInt32 nTicks = (((microseconds+1UL)/2UL)*105UL)/(88UL/2UL);

	dos32Delay838NS( nTicks );

	return TRUE;

#else //_WIN32

	#pragma message(">>>>> Function halpDelayUS() must be written for this platform. <<<<<")
	return FALSE;

#endif
}



//---------------------------------------------------------------------------
// PLATFORM FUNCTION: halpMapPhysicalToVirtual()
//---------------------------------------------------------------------------
int halpMapPhysicalToVirtual( UInt32 PhysicalAddr, UInt32 *pVirtualAddr, UInt32 *pBlockSize )
{
	static Boolean fExitHandler = FALSE;

	// Always register the atexit routine at least once, so any allocated
	// resources are guaranteed to be released and freed.

	if ( !fExitHandler )
	{
		fExitHandler = TRUE;
		atexit( ExitHandler );
	}

#if defined(_WIN32)

  #ifndef HAL_SIMULATE
	return Pci2Hal( pcibMapAddress(PhysicalAddr,pVirtualAddr,pBlockSize) );
  #else
	return AllocateSharedMemory( PhysicalAddr, pVirtualAddr, pBlockSize );
  #endif

#else

  #if defined(_MSDOS)
	{
		MIDStruct MemData;

		dos32Initialize( &MemData );
		if ( MemData.fV86Mode || !MemData.fA20State )
			return ERR_FAILED;

		if ( !PhysicalAddr )
			PhysicalAddr = Get13xxxBaseAddress( TRUE );
	}
  #endif

	// On non-Windows system, a physical address of zero is bad karma.

	if ( PhysicalAddr == 0 )
		return ERR_FAILED;

	if ( pVirtualAddr )
		*pVirtualAddr = PhysicalAddr;
	if ( pBlockSize )
		*pBlockSize = DEFAULT_BLOCK_SIZE;

	return ERR_NONE;

#endif
}



//---------------------------------------------------------------------------------------
// PLATFORM FUNCTION: halpAddInterruptRegister()
//---------------------------------------------------------------------------------------
int halpAddInterruptRegister( UInt32 EnableReg, UInt32 StatusReg, UInt32 BitMask, UInt32 AccessSize, Boolean fRawStatus )
{
#ifdef _WIN32

  #ifndef HAL_SIMULATE
	EnableReg += HalInfo.dwRegisterOffset;
	StatusReg += HalInfo.dwRegisterOffset;
	return Pci2Hal( pcibAddInterruptRegister(EnableReg,StatusReg,BitMask,AccessSize,fRawStatus) );
  #else
	EnableReg, StatusReg, BitMask, AccessSize, fRawStatus;
	return ERR_IRQ_FAILURE;					// Not simulated.
  #endif

#else

	// On non-Windows system, new code to handle interrupts must be written.

	#pragma message(">>>>> halpAddInterruptRegister() must be written for this platform. <<<<<")
	return ERR_IRQ_FAILURE;

#endif
}



//---------------------------------------------------------------------------------------
// PLATFORM FUNCTION: halpSetISRCallback()
//---------------------------------------------------------------------------------------
int halpSetISRCallback( void(*pISRCallback)(void) )
{
#ifdef _WIN32

  #ifndef HAL_SIMULATE
	return Pci2Hal( pcibHookInterrupt(pISRCallback) );
  #else
	pISRCallback;
	return ERR_IRQ_FAILURE;					// Not simulated.
  #endif

#else

	// On non-Windows system, new code to handle interrupts must be written.

	#pragma message(">>>>> halpSetISRCallback() must be written for this platform. <<<<<")
	return ERR_IRQ_FAILURE;

#endif
}



//---------------------------------------------------------------------------------------
// PLATFORM FUNCTION: halpDirectRead()
//---------------------------------------------------------------------------------------
UInt32 halpDirectRead( int Size, UInt32 Address )
{
#if !defined(_MSDOS)

	if ( Size == sizeof(UInt8) )
	{
		return *(pUInt8)Address;
	}
	else if ( Size == sizeof(UInt16) )
	{
		return *(pUInt16)Address;
	}
	else if ( Size == sizeof(UInt32) )
	{
		return *(pUInt32)Address;
	}

#else //_MSDOS

	if ( Size == sizeof(UInt8) || Size == sizeof(UInt16) || Size == sizeof(UInt32) )
	{
		return dos32ReadAbsolute( Address, Size );
	}

#endif //_MSDOS

	return 0;
}



//---------------------------------------------------------------------------------------
// PLATFORM FUNCTION: halpDirectWrite()
//---------------------------------------------------------------------------------------
void halpDirectWrite( int Size, UInt32 Address, UInt32 Value, UInt32 Count )
{
	if ( Count )
	{

#if !defined(_MSDOS)

		if ( Size == sizeof(UInt8) )
		{
			pUInt8 pWrite = (pUInt8)Address;
			do
				*pWrite++ = (UInt8)Value;
			while ( --Count );
		}
		else if ( Size == sizeof(UInt16) )
		{
			pUInt16 pWrite = (pUInt16)Address;
			do
				*pWrite++ = (UInt16)Value;
			while ( --Count );
		}
		else if ( Size == sizeof(UInt32) )
		{
			pUInt32 pWrite = (pUInt32)Address;
			do
				*pWrite++ = Value;
			while ( --Count );
		}

#else //_MSDOS

		if ( Size == sizeof(UInt8) || Size == sizeof(UInt16) || Size == sizeof(UInt32) )
		{
			do
			{
				dos32WriteAbsolute( Address, Value, Size );
				Address += Size;
			}
			while ( --Count );
		}

#endif //_MSDOS

	}
}



//---------------------------------------------------------------------------------------
// PLATFORM FUNCTION: halpDirectReadData()
//---------------------------------------------------------------------------------------
void halpDirectReadData( int Size, UInt32 Address, void* pData, UInt32 Count )
{
	if ( Count && pData )
	{

#if !defined(_MSDOS)

		if ( Size == sizeof(UInt8) )
		{
			pUInt8 pRead = (pUInt8)Address;
			pUInt8 pWrite = pData;
			do
				*pWrite++ = *pRead++;
			while ( --Count );
		}
		else if ( Size == sizeof(UInt16) )
		{
			pUInt16 pRead = (pUInt16)Address;
			pUInt16 pWrite = pData;
			do
				*pWrite++ = *pRead++;
			while ( --Count );
		}
		else if ( Size == sizeof(UInt32) )
		{
			pUInt32 pRead = (pUInt32)Address;
			pUInt32 pWrite = pData;
			do
				*pWrite++ = *pRead++;
			while ( --Count );
		}

#else //_MSDOS

	#pragma message(">>>>> halpDirectReadData() must be written for this platform. <<<<<")

#endif //_MSDOS

	}
}



//---------------------------------------------------------------------------------------
// PLATFORM FUNCTION: halpDirectWriteData()
//---------------------------------------------------------------------------------------
void halpDirectWriteData( int Size, UInt32 Address, const void* pData, UInt32 Count )
{
	if ( Count && pData )
	{

#if !defined(_MSDOS)

		if ( Size == sizeof(UInt8) )
		{
			const UInt8* pRead = pData;
			pUInt8 pWrite = (pUInt8)Address;
			do
				*pWrite++ = *pRead++;
			while ( --Count );
		}
		else if ( Size == sizeof(UInt16) )
		{
			const UInt16* pRead = pData;
			pUInt16 pWrite = (pUInt16)Address;
			do
				*pWrite++ = *pRead++;
			while ( --Count );
		}
		else if ( Size == sizeof(UInt32) )
		{
			const UInt32* pRead = pData;
			pUInt32 pWrite = (pUInt32)Address;
			do
				*pWrite++ = *pRead++;
			while ( --Count );
		}

#else //_MSDOS

	#pragma message(">>>>> halpDirectWriteData() must be written for this platform. <<<<<")

#endif //_MSDOS

	}
}



//---------------------------------------------------------------------------------------
// PLATFORM FUNCTION: halpSetProcessExclusivity()
//---------------------------------------------------------------------------------------
void halpSetProcessExclusivity( Boolean fExclusive )
{
#ifdef _WIN32

	if ( fExclusive )
	{
		if ( !ghHalMutex )
			ghHalMutex = CreateMutex( NULL, FALSE, HALCHIPID"HalMutex" );

		if ( ghHalMutex )
			WaitForSingleObject( ghHalMutex, INFINITE );
	}
	else
	{
		if ( ghHalMutex )
			ReleaseMutex( ghHalMutex );
	}

#else

	#pragma message(">>>>> halpSetProcessExclusivity() must be written for this platform. <<<<<")

#endif
}




//---------------------------------------------------------------------------
// PRIVATE FUNCTION: ExitHandler() - Free up resources at exit time.
//---------------------------------------------------------------------------
static void ExitHandler( void )
{
#if defined(_WIN32)

  #ifndef HAL_SIMULATE
	pcibUnmapAddress();
  #else
	FreeSharedMemory();
  #endif

	if ( ghHalMutex )
		CloseHandle( ghHalMutex ), ghHalMutex = NULL;

#elif defined(_MSDOS)

	dos32Terminate();

#endif
}



#ifdef _WIN32

//---------------------------------------------------------------------------
// PRIVATE FUNCTION: Pci2Hal() - Map PCI to HAL return code. >>>WIN32 ONLY<<<
//---------------------------------------------------------------------------
static int Pci2Hal( Boolean fPCIResult )
{
	int Result = ERR_NONE;

	if ( !fPCIResult )
	{
		switch ( pcibGetLastError() )
		{
		  case PCIE_ERR_ADAPTER_NOT_FOUND:		Result = ERR_PCI_ADAPTER_NOT_FOUND;		break;
		  case PCIB_ERR_DRIVER_NOT_FOUND:		Result = ERR_PCI_DRIVER_NOT_FOUND;		break;
		  case PCIB_ERR_IRQ_FAILURE:			Result = ERR_IRQ_FAILURE;				break;
		  case PCIB_ERR_ADAPTER_NOT_MAPPED:		Result = ERR_NOT_ACQUIRED;				break;
		  default:								Result = ERR_FAILED;					break;
		}
	}

	return Result;
}

#endif	//_WIN32



#ifdef _MSDOS

#define VENDEV			0x002014EBL		// device_Id + vendor_Id
#define CONFIG_ADDRESS	0x0CF8
#define CONFIG_DATA		0x0CFC
#define PCI_ENABLE		(1L<<31)

//---------------------------------------------------------------------------
// PRIVATE FUNCTION: Get13xxxBaseAddress() - Find S1D13xxx PCI. >>>MSDOS ONLY<<<
//---------------------------------------------------------------------------
static UInt32 Get13xxxBaseAddress( Boolean fEnable )
{
	UInt32	b, d, f, f2, x;
	UInt32	Addr = 0UL;

	for (b = 0; b < (1L<<24); b += (1L<<16))
	{
		for (d = 0; d < (1L<<16); d += (1L<<11))
		{
			outpd( CONFIG_ADDRESS, PCI_ENABLE | b | d | 0x0C );
			if ( (x = inpd(CONFIG_DATA)) == -1 )
				continue;

			f2 = (x & 0x00800000L) ? (1L<<11) : (1L<<8);
			for (f = 0; f < f2; f += (1L<<8))
			{
				outpd( CONFIG_ADDRESS, PCI_ENABLE | b | d | f | 0x00 );
				x = inpd( CONFIG_DATA );

				if ( x == VENDEV )
				{
					if ( fEnable )		// Enable decoding (may be enabled by BIOS)
					{
						outpd( CONFIG_ADDRESS, PCI_ENABLE | b | d | f | 0x04 );
						x = inpd( CONFIG_DATA );
						outpd( CONFIG_DATA, x | 2 );
					}

					// Read DWREG[5] to get the physical ("base") address

					outpd( CONFIG_ADDRESS, PCI_ENABLE | b | d | f | 0x10 );
					Addr = inpd( CONFIG_DATA );
				}
			}
		}
	}

	return Addr;
}

#endif	//_MSDOS



#if defined(_WIN32) && defined(HAL_SIMULATE)

//---------------------------------------------------------------------------
// PRIVATE FUNCTION: AllocateSharedMemory()		>>>HAL_SIMULATE ONLY<<<
//---------------------------------------------------------------------------
static int AllocateSharedMemory( UInt32 PhysicalAddr, UInt32 *pVirtualAddr, UInt32 *pBlockSize )
{
	DWORD dwLastError;

	// We can't simulate a specific user-specified physical address.

	if ( PhysicalAddr )
		return ERR_FAILED;

	// If we haven't allocated shared memory yet, do it now.

	if ( gpSharedMemory == NULL )
	{
		ghSharedMemory = CreateFileMapping( INVALID_HANDLE_VALUE, NULL, PAGE_READWRITE, 0, DEFAULT_BLOCK_SIZE, HALCHIPID"HalSharedMemory" );
		dwLastError = GetLastError();				// Remember result code for later.

		// If we allocated shared memory successfully, then get a pointer to it.

		if ( ghSharedMemory != NULL && ghSharedMemory != INVALID_HANDLE_VALUE )
		{
			gpSharedMemory = MapViewOfFile( ghSharedMemory, FILE_MAP_ALL_ACCESS, 0, 0, 0 );
			if ( gpSharedMemory == NULL )
			{
				CloseHandle( ghSharedMemory );
				ghSharedMemory = NULL;
			}
		}

		// If we failed to allocation shared memory, exit with error condition.

		if ( gpSharedMemory == NULL )
			return ERR_FAILED;

		// If we are the first to allocate shared memory, then initialize it to ZERO.

		if ( dwLastError != ERROR_ALREADY_EXISTS )
			ZeroMemory( gpSharedMemory, DEFAULT_BLOCK_SIZE );
	}

	if ( pVirtualAddr )
		*pVirtualAddr = (UInt32)gpSharedMemory;
	if ( pBlockSize )
		*pBlockSize = DEFAULT_BLOCK_SIZE;

	return ERR_NONE;
}



//---------------------------------------------------------------------------
// PRIVATE FUNCTION: FreeSharedMemory()			>>>HAL_SIMULATE ONLY<<<
//---------------------------------------------------------------------------
static void FreeSharedMemory( void )
{
	// Only free up these resources, if they are currently allocated and in use.

	if ( gpSharedMemory )
	{
		UnmapViewOfFile( gpSharedMemory );
		gpSharedMemory = NULL;
	}
	if ( ghSharedMemory )
	{
		CloseHandle( ghSharedMemory );
		ghSharedMemory = NULL;
	}
}

#endif //defined(_WIN32) && defined(HAL_SIMULATE)

⌨️ 快捷键说明

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