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

📄 hal_supt.c

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

#include "hal.h"
#include "hal_indirect.h"
#include "hal_Supt.h"

#if defined(INTEL_W32)

#include <windows.h>
#include <winioctl.h>
#include "ioctl.h"

#endif

// Define some useful pre-processor macros.
#if defined(offsetof)
#error A chipdef.cpp pre-processor macro is already in use!
#else
#define offsetof(s,m)				(int)&(((s *)0)->m)
#endif

#define ABS(x)		(((x) >= 0) ? (x) : -(x))

//===========================================================================
//							Global Variables
//===========================================================================
extern int           gnHalErrCode;
extern pvUInt32      gpHalMemAddr;
extern pvUInt32      gpHalRegAddr;

//---------------------------------------------------------------------------
#if defined(INTEL_W32)

//---------------------------------------------------------------------------

static UInt32 gulLinearAddress;
static HANDLE hDriver;

//---------------------------------------------------------------------------
//  FUNCTION:	halpGetLinearAddress()
//
//  DESCRIPTION:
//		This routine dynamically loads the VxD and requests a linear address
//		for the address space of the S1D13A03 PCI eval card.
//
//  PARAMETERS:
//		ulPhysAddr	- A DWORD value containing the memory address offset
//					  to the S1D13700.
//					  If this value is zero (NULL) then the routine will
//					  load the VxD and determine the linear address of
//					  the S1D13700.
//					  If set to anything other than NULL then the value
//					  is assumed to be a physical address and this routine
//					  will return the linear address reprsenting that
//					  physical address.
//		pulLinearAddr- Pointer to a DWORD to recieve the linear address
//					  for representing the physical address for the
//					  S1D13700.
//
//  RETURNS:
//		ERR_NONE					- No errors, the function succeeded.
//		ERR_PCI_DRIVER_NOT_FOUND	- S1D13xxx.VxD was not found/loaded.
//		ERR_PCI_ADAPTER_NOT_FOUND	- The VxD was unable to locate an S1D13xxx.
//
//		If there are no errors then * LinAddr will contain the linear address
//		of the start of S1D13xxx address space. If there was a problem then
//		* ulLinAddr will be zero (NULL).
//
//	MODIFIES:
//---------------------------------------------------------------------------
int halpGetLinearAddress( UInt32 ulPhysAddr, UInt32 * pulLinearAddr )
{
	DWORD		cbReturned;
	int			rc, retVal;
    unsigned	retArr[2];

	// 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.
	halpFreeLinearAddress();

	// Determine the operating system we are running under and act accordingly.
	if (GetVersion() < 0x80000000) 
	{
		// Attempt to open the device NT fashion.
		hDriver = CreateFile("\\\\.\\S1D13xxx", GENERIC_READ | GENERIC_WRITE,
							 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
	}
	else    //Win95,98...
	{
		// Attempt to open the device 95/98 fashion.
		// The FILE_FLAG_DELETE_ON_CLOSE flag is used so that CloseHandle()
		// can be used to dynamically unload the VxD.
		// The CREATE_NEW flag is not necessary
		hDriver = CreateFile("\\\\.\\S1D13xxx.VXD", 0, 0, 0, CREATE_NEW,
							 FILE_FLAG_DELETE_ON_CLOSE, 0);
	}

	// If we have an invalid handle then we didn't load the VxD.
	if (hDriver == INVALID_HANDLE_VALUE)
	{
		hDriver = NULL;
		return ERR_PCI_DRIVER_NOT_FOUND;
	}

	//---------------------------------------------------
	// From now on, the code is common for Win95 & WinNT
	//---------------------------------------------------
	if (ulPhysAddr == 0)		// map in a PCI Board
	{
		char Buffer[80];
		int boardnum = 0;

		// Check the environment for:
		//	S1DBOARD=x
		//	where x is a number 0,1,2,3,4,...
		// This is for those rare situations, where we have multiple
		// PCI boards and we have "assigned" a command prompt window
		// to a particular board using the environment variables.
		if (GetEnvironmentVariable("SEDBOARD", Buffer, sizeof(Buffer)))
			boardnum = atoi(Buffer);

		rc = DeviceIoControl(hDriver, IOCTL_SED_MAP_PCI_BOARD,
							 &boardnum, sizeof(ULONG), retArr,
							 2*sizeof(ULONG), &cbReturned,NULL);

		// Upon exit from DeviceIoControl():
		//	retArr[0] : linear address
		//	retArr[1] : physical address 

		if (rc)
		{
			*pulLinearAddr = retArr[0];
			gulLinearAddress = retArr[0];
		}
	}
	else					// The user insists on a particular physical address
	{
		retArr[0] = ulPhysAddr;
		retArr[1] = 4 * 1024 * 1024;

		rc = DeviceIoControl(hDriver, IOCTL_SED_MAP_PHYSICAL_MEMORY,
							 &retArr[0], 2 * sizeof(ULONG), &retVal,
							 sizeof(ULONG), &cbReturned, NULL);         
		if (rc)
		{
			*pulLinearAddr = retVal;
			gulLinearAddress = retVal;
		}
	}
     
	if (rc)
		return ERR_NONE;

	return ERR_PCI_ADAPTER_NOT_FOUND;
}

//---------------------------------------------------------------------------
//  FUNCTION:	halpFreeLinearAddress()
//
//  DESCRIPTION:
//		This routine frees the memory allocated by GetLinearAddrW32().
//		Failure to release the memory blocks will result in the eventual
//		failure of the program to run.
//
//  PARAMETERS:
//
//  RETURNS:
//		ERR_NONE					- No errors, the function succeeded.
//		ERR_PCI_ADAPTER_NOT_FOUND	- The VxD was unable to locate an S1D13xxx.
//
//	MODIFIES:
//---------------------------------------------------------------------------
int halpFreeLinearAddress( void )
{
	int    rc = ERR_NONE;
	DWORD  cbReturned;

	// Only free up these resources, if they are currently allocated and in use.
	if (hDriver)
	{
		// We already have a handle to the VxD and to the memory we wish to free.
		// Simply call the VxD with the appropriate values to free the our memory.
		if ( gulLinearAddress )
			if ( !DeviceIoControl(hDriver, IOCTL_SED_UNMAP_LINEAR_MEMORY, &gulLinearAddress,
									sizeof(PVOID), NULL, 0, &cbReturned, NULL) )
				rc = ERR_PCI_ADAPTER_NOT_FOUND;

		// Close the handle. This dynamically UNLOADs the VxD under Win9x.  Also
		// flag the SED driver closed and the allocated memory freed.
		CloseHandle(hDriver);
		hDriver = NULL;
		gulLinearAddress = 0;
	}
     
	return rc;
}

#endif


static UInt32 fREF = 14318180;	// 14.31818 MHz




//---------------------------------------------------------------------------
//  FUNCTION:		halpInitRegisters()
//
//  DESCRIPTION:
//		This function simply takes the register list in the HalInfo structure
//		and writes it to the registers.
//
//		Certain control codes (eg. REG_END_OF_TABLE) are interpreted and
//		appropriate action taken.
//
//  PARAMETERS:		none.
//
//  RETURNS:		Nothing
//
//	MODIFIES:
//		Pretty much every LCD controller register will be written to.
//---------------------------------------------------------------------------
void halpInitRegisters( void )
{
    UInt16 i;
    UInt16 wReg08 = HalInfo.Regs[REG0007_SYSTEMSET_P8].Value;       // Save register 8
    HalInfo.Regs[REG0007_SYSTEMSET_P8].Value = 0;                   // Power up
    halWriteReg8( (UInt16)REG0007_SYSTEMSET_P8, 0 );                // Power up
    //
    if( HalInfo.dwFlags&fINDIRECT_INTERFACE )
    {
        PICOMMAND pCurCmd, pPreCmd = NULL;
        //
        for( i=0; i<HAL_NUMREGS; i++ )
        {
            pCurCmd = gCmdTbl[i];
            //
            if( pPreCmd!=pCurCmd )
            {
                halIndirectRegCmd( pCurCmd );
                pPreCmd = pCurCmd;
            }
        }
    } else
    {
        for( i=0; i<HAL_NUMREGS; i++ ) halWriteReg8( i, (UInt8)HalInfo.Regs[i].Value );
    }
    //
    HalInfo.Regs[8].Value = wReg08;

    HalInfo.Regs[REG0007_SYSTEMSET_P8].Value = wReg08;              // Restore register 8
    halWriteReg8( (UInt16)REG0007_SYSTEMSET_P8, (UInt8)wReg08 );           // Finally restore power state that is
                                                                    // intended as the register setting
    return;
}



//---------------------------------------------------------------------------
//  FUNCTION:		halpClearVmem()
//
//  DESCRIPTION:
//		This routine calculates the amount of video memory present and clears
//		all of it by setting the memory to zero.
//
//		Any memory amounts hinted in the HAL are not used.
//
//  PARAMETERS:		None.
//
//  RETURNS:		Nothing.
//
//	MODIFIES:		Sets all of video memory to zero.
//---------------------------------------------------------------------------
void halpClearVmem( void )
{
	pvUInt32 ptr;
	UInt32   ulCount;
	UInt32   cnt;
		
	ptr = gpHalMemAddr;
	ulCount = 0x8000;

	if (HalInfo.dwFlags & fINDIRECT_INTERFACE)
		{
		//halIndirectWriteDisplayAddress(0);

		for (cnt = 0; cnt < ulCount; cnt++)
			*pIndirectDataWrite = (UInt8)0;
		}
	else
		{
		for (cnt = 0; cnt < ulCount; cnt++, ptr++)
			*ptr = (UInt8)0;
		}
}

//---------------------------------------------------------------------------
//  FUNCTION: halpCalculateHalInfoCRC()
//
//  DESCRIPTION:
//		This routine is taken directly from 13700CFG. However, to accomodate
//		differences between C and C++ there are a couple of small changes.
//
//		This private method is used to calculate a 16-bit CRC for the contents
//		of a HalInfo structure. The bits included in the calculation are those
//		from the first byte following the wHalCRC member up to and including
//		the last byte of the structure.  The formula used is CRC16-CCITT, which
//		is the polynomial x^16 + x^12 + x^5 + 1 (0x1021).
//
//  PARAMETERS:
//		HalData	- Pointer to a HAL_STRUCT structure
//
//  RETURNS:
//		The calculated CRC value.
//---------------------------------------------------------------------------
UInt16 halpCalculateHalInfoCRC( const PHAL_STRUCT pHalData )
{
	const UInt8 *pHalByte;
	int i, nBytes;
	UInt16 crc;

	// Setup the pointer, counter, and initial CRC value.
	pHalByte = (UInt8 *) &(pHalData->wHalCRC) + sizeof(HalInfo.wHalCRC);
	nBytes  = sizeof(HalInfo) - offsetof(HAL_STRUCT,wHalCRC) - sizeof(HalInfo.wHalCRC);
	crc = 0xFFFF;

	// Calculate the CRC for the HalInfo structure (from byte after wHalCRC to end).
	for (i = 0; i < nBytes; i++)
	{
		crc  = (crc << 8) | ((crc >> 8) ^ pHalByte[i]);
		crc ^= (crc & 0x00FF) >> 4;
		crc ^= (crc << 12) ^ ((crc & 0x00FF) << 5);
	}

	// Return the calculated CRC.
	return crc;
}

⌨️ 快捷键说明

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