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

📄 hal.c

📁 用C语言设计的EPSON LCD控制器S1D13700驱动。
💻 C
📖 第 1 页 / 共 3 页
字号:
//=============================================================================
//	HAL.C
// (Tabs set to every 4 spaces)
//---------------------------------------------------------------------------
//	The routines in this file comprise the core of the S1D13700 miniHAL.
//---------------------------------------------------------------------------
//
//  ㏒EIKO EPSON CORPORATION 2003-2005. All rights reserved.
//
//=============================================================================

#if defined INLINE_FUNCTIONS
	#define INLINE inline
#else
	#define INLINE
#endif

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

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

#include "hal.h"
#include "HAL_platform.h"
#include "HAL_private.h"
#include "hal_indirect.h"
#include "hal_config.c"
#include "halmutex.h"
#include "libmutex.h"

#ifdef _WIN32
#pragma warning( disable : 4100 )	// Disable "unreferenced formal parameter" warning.
#endif

//===========================================================================
// PUBLIC GLOBAL VARIABLES
//===========================================================================

char	gszHALRevision[] = "$Revision: 10 $";

int		gnHalErrCode;

//===========================================================================
// PRIVATE (STATIC) FUNCTION PROTOTYPES (local to HAL only)
//===========================================================================

static void		InitRegisters( void );
static void		ClearVideoMemory( void );

//===========================================================================
// Timing globals and defines
//===========================================================================
static __int64	gSysClockBase;						// Value of CPU SysClock at calibration time
static __int64	gSysClockPS;						// Calculated number of picoseconds per SysClock

static Boolean	CalibrateSystemClock( void );

#define RDTSC(var64)						\
	__asm									\
	{										\
		__asm rdtsc							\
		__asm mov dword ptr [var64+0],eax	\
		__asm mov dword ptr [var64+4],edx	\
	} ((void)0)


//===========================================================================
// PRIVATE GLOBAL VARIABLES (local to HAL only)
//===========================================================================

static DATA_STRUCT gHD =							// Global HAL private data storage
{
	HAL_MUTEX_REVISION,
	LIB_MUTEX_REVISION,
	"Copyright (c) Seiko Epson Corporation 2003-2005.\nAll rights reserved.\n"
	// Remaining members are default initialized to zero.
};

// CRITICAL: The messages in this array MUST correspond to the error codes contained in the HAL.H enumeration.
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
	"This program has not been configured",			// ERR_NOT_CONFIGURED
	"Config CRC does not match configuration",		// ERR_BAD_CFG_DATA
	"I2C bus/device initialization failure",		// ERR_BAD_I2C_INIT
	"The controller has not been acquired",			// ERR_NOT_ACQUIRED
	"IRQ interrupt handler failure",				// ERR_IRQ_FAILURE
	"The CNF1 pin is low (all GPIOs are outputs)",	// ERR_BAD_CNF1_SETTING
	"An unspecified error occured"					// ERR_FAILED
};


const DATA_STRUCT* const gpHalData = &gHD;

/*****************************************************************************/
/*                      FUNCTIONS exported in hal.h                          */
/*****************************************************************************/

//=============================================================================
//                                 Start Up
//=============================================================================

//---------------------------------------------------------------------------
//  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.
//---------------------------------------------------------------------------
Boolean halAcquireController( UInt32 * pMem, UInt32 * pReg )
{
	static Boolean fFirstTime = FALSE;
	gHD.nErrorCode = ERR_NONE;
	// Init, one time, default state of debug register writes flag.
	if( !fFirstTime )
	{
		fFirstTime = TRUE;
#ifdef _DEBUG
		gHD.fDebugHalDelay = gHD.fDebugRegWrites = !!(HalInfo.dwFlags & fDEBUG_REG_WRITES);
#else
		gHD.fDebugHalDelay = gHD.fDebugRegWrites = FALSE;
#endif
	}

		if ( HalInfo.dwFlags & fPCCARD_INTERFACE )
		{
			// force to PCI addressing
			gHD.BaseAddress = 0;
			HalInfo.dwRegisterOffset = 0;
		}

	// Use the configured base address to retrieve the virtual address, if any.  On
	// non-Windows platforms, the base address will be copied to the virtual address.

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

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

		if ( HalInfo.dwFlags & fPCCARD_INTERFACE )
		{
			gHD.MemoryAddress	= gHD.BaseAddress;
			gHD.RegisterAddress	= gHD.BaseAddress + 0x8000UL * 2; //0x8000 is the offset of reg base addr from video mem bas eaddr 
		}
 		else
		{

			gHD.RegisterAddress = gHD.BaseAddress + HalInfo.dwRegisterOffset;
			// If the configured register and memory offsets are the same, assume we are
			// using the PCI evaluation board, and default the memory offset accordingly.
			gHD.MemoryAddress = gHD.BaseAddress + HAL_PCI_VRAM_OFFSET;
		}
	}

#ifndef HAL_SIMULATE
	if( (HalInfo.dwFlags & fINDIRECT_INTERFACE) )
		halpInitIndirectInterface( gHD.MemoryAddress );
#else
	HalInfo.dwFlags &= ~fINDIRECT_INTERFACE;	// In simulate mode, don't simulate any indirect interface!
#endif

	if( pReg )  *pReg = gHD.RegisterAddress;
	if( pMem )	*pMem = gHD.MemoryAddress;
	//
	return TRUE;
}


//---------------------------------------------------------------------------
//  FUNCTION:		halInitController()
//
//  DESCRIPTION:
//		This routine performs the initialization portion of the startup
//		sequence.
//
//		Initialization consists of several steps:
//			- Programming the ICD2061A clock generator
//			- Setting the contol registers the state defined by CFG.
//			- Setting the LUT to its default value.
//			- Clearing video memory
//
//		Parameters passed in dwFlags can cause any or all of these steps to
//		be bypassed. This allows for run-time operational changes.
//
//  PARAMETERS:
//		Flags	- contains initialization specific information.
//
//  RETURNS:
//		TRUE if the initialization was successful.
//		FALSE if the HAL was unable to initialize the S1D13700
//
//		If additional error information is required call halGetLastError()
//
//	MODIFIES:
//		Nearly every register and all display memory can or will be affected.
//---------------------------------------------------------------------------
Boolean halInitController( UInt32 Flags )
{
	gHD.nErrorCode = ERR_NONE;
	// If the program has not been CFGed then we CANNOT init the controller.
	// Set and error code and return FALSE.


	// If the program has not been CFGed then we CANNOT init the controller.
	// Set and error code and return FALSE. 
#ifndef HAL_SIMULATE
	if ( HalInfo.wHalCRC == 0x0000 )
	{
		gHD.nErrorCode = ERR_NOT_CONFIGURED;
		return FALSE;
	}

#if 0
	When registers' value are changed, the CRC of HalInfo will changed and result in CRC incorrect.
	gHD.nErrorCode is not checked, instead gnHalErrorCode is checked. Should gHD.nErrorCode be gnHalErrorCode ?
	remove the following code for above reason.
	// CRC is not zero so we have been configured. Check that the CRC
	// and the data match.
	if ( !(Flags & fDONT_CHECK_CRC) && HalInfo.wHalCRC != CalculateHalInfoCRC(&HalInfo) )
	{
		gHD.nErrorCode = ERR_BAD_CFG_DATA;
		return FALSE;
	}
#endif
#endif

	// Fail if halAcquireController() was not called, or if it failed.
	if ( gHD.BaseAddress == 0 )
	{
		gHD.nErrorCode = ERR_NOT_ACQUIRED;
		return FALSE;
	}

	gHD.fDebugHalDelay = FALSE;		// Don't debug delays during init, as they are special-cased!
	DEBUGMSG( TRUE, ("   List of HAL Initialization Events:\n") );

	// Init the registers - unless the caller has requested us not to
	if ( !(Flags & fDONT_INIT_REGS) )
	{
		InitRegisters();
		DEBUGMSG( TRUE, ("   - Registers initialized as per configured settings.\n") );
	}
	else
		DEBUGMSG( TRUE, ("   - Registers NOT initialized!\n") );

	// Clear video memory - unless the caller has requested us not to
	if ( !(Flags & fDONT_CLEAR_MEM) )
	{
		ClearVideoMemory();
		DEBUGMSG( TRUE, ("   - All video memory cleared to 00h.\n") );
	}
	else
		DEBUGMSG( TRUE, ("   - Video memory NOT cleared!\n") );

	gHD.fDebugHalDelay = gHD.fDebugRegWrites;

	return ( gHD.nErrorCode == ERR_NONE );
}


//===========================================================================
//                              Memory Access
//===========================================================================

//	*** NOTE ***
//
//	The memory access routines do not perform any error checking. This means:
//	 1) NEVER call these routines if halAcquireController() did not succeed.
//	 2) Memory boundaries are not checked. It is possible to request a read
//		or write outside of display memory.


//-----------------------------------------------------------------------------
// COMMON FUNCTION: halReadDisplay8()
// COMMON FUNCTION: halReadDisplay16()
// COMMON FUNCTION: halReadDisplay32()
//-----------------------------------------------------------------------------
UInt8 halReadDisplay8( UInt32 Offset )
{
	if ( HalInfo.dwFlags & fPCCARD_INTERFACE )
	{
		if( HalInfo.dwFlags & fINDIRECT_INTERFACE )
			return halpIndReadDisplay8( (UInt16)(Offset*2) );
		else
			return *(pvUInt8)(gHD.MemoryAddress + (Offset*2));
	}
	else
	{
		if( HalInfo.dwFlags & fINDIRECT_INTERFACE )
			return halpIndReadDisplay8( (UInt16)Offset );
		else
			return *(pvUInt8)(gHD.MemoryAddress + Offset);
	}
}


UInt16 halReadDisplay16( UInt32 Offset )
{
	if ( HalInfo.dwFlags & fPCCARD_INTERFACE )
	{
		if( HalInfo.dwFlags & fINDIRECT_INTERFACE )
			return halpIndReadDisplay16( (UInt16)(Offset*2) );
		else
		{
			UInt16  wRetVal;
			
			wRetVal  =  *(pvUInt8)(gHD.MemoryAddress + Offset*2);
			wRetVal |= (*(pvUInt8)(gHD.MemoryAddress + (Offset + 1)*2))<<8;

			return wRetVal;
		}
	}
	else
	{
		if( HalInfo.dwFlags & fINDIRECT_INTERFACE )
			return halpIndReadDisplay16( (UInt16)Offset );
		else
		{
			UInt16  wRetVal;
			
			wRetVal  =  *(pvUInt8)(gHD.MemoryAddress + Offset);
			wRetVal |= (*(pvUInt8)(gHD.MemoryAddress + Offset + 1))<<8;

			return wRetVal;
		}
	}
}


UInt32 halReadDisplay32( UInt32 Offset )
{
	if ( HalInfo.dwFlags & fPCCARD_INTERFACE )
	{
		if( HalInfo.dwFlags & fINDIRECT_INTERFACE )
			return halpIndReadDisplay32( (UInt16)(Offset*2) );
		else
		{
			UInt32  dwRetVal;

			dwRetVal  =  *(pvUInt8)(gHD.MemoryAddress + Offset*2);
			dwRetVal |= (*(pvUInt8)(gHD.MemoryAddress + (Offset + 1)*2))<< 8;
			dwRetVal |= (*(pvUInt8)(gHD.MemoryAddress + (Offset + 1)*2))<<16;
			dwRetVal |= (*(pvUInt8)(gHD.MemoryAddress + (Offset + 1)*2))<<24;

⌨️ 快捷键说明

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