📄 hal_init.c
字号:
/*
**===========================================================================
** HAL_INIT.C
**---------------------------------------------------------------------------
** Copyright (c) 2000, 2001 Epson Research and Development, Inc.
** All Rights Reserved.
**===========================================================================
*/
#include <string.h>
#include "hal.h"
#include "assert.h"
#include "nonsefns.h"
/*-------------------------------------------------------------------------*/
static const char Revision[] = "HAL_INIT.C=$Revision: 19 $";
/*-------------------------------------------------------------------------*/
extern BYTE LUT1[2*3];
extern BYTE LUT2_Color[4*3];
extern BYTE LUT2_Mono[4*3];
extern BYTE LUT4_Color[16*3];
extern BYTE LUT8_Color[256*3];
/*-------------------------------------------------------------------------*/
DWORD _MemorySize;
BOOL _EndianReverseDisplayBytes = FALSE;
BOOL _EndianReverseRegisterBytes = FALSE;
BOOL _AllowHardwareDisplaySwapping = FALSE;
BOOL _OnValidBppAllowHardwareDisplaySwapping = FALSE;
/*-------------------------------------------------------------------------*/
/*
** Find the register value in _HalInfo[]
*/
int _FindReg(unsigned index, unsigned *pValue, int *iArray)
{
int i;
defReg *pRegs;
int GotReg;
GotReg = FALSE;
*pValue = 0;
*iArray = 0;
pRegs = &(_HalInfo->Regs[0]);
/*
** Get the last entry in Reg table referring to REG[index]
*/
for (i = 0; (i < MAX_REG) && (pRegs->index != FINISHED_REG_CFG); ++i, ++pRegs)
{
if (pRegs->index == index)
{
*pValue = pRegs->val;
*iArray = i;
GotReg = TRUE;
}
}
if (GotReg)
return ERR_OK;
else
return ERR_FAILED;
}
/*-------------------------------------------------------------------------*/
/*
** The following registration function will not perform any
** register I/O
*/
int _RegisterDevice(const LPHAL_STRUCT lpHalInfo)
{
int err;
pLcdPowerDelayMsg = NULL;
pLcdPowersaveDelayMsg = NULL;
_InitPlat();
// Clear surfaces
memset(&_MainWinSurface, 0, sizeof(_SURFACE_STRUCT));
memset(&_SubWinSurface, 0, sizeof(_SURFACE_STRUCT));
_MainWinSurface.DisplayMode = MAIN_WIN;
_SubWinSurface.DisplayMode = SUB_WIN;
_ActiveImageSurface = &_MainWinSurface;
_ThreadPriorityNestCount = 0;
_EndianReverseDisplayBytes = FALSE;
_EndianReverseRegisterBytes = FALSE;
_AllowHardwareDisplaySwapping = FALSE;
_OnValidBppAllowHardwareDisplaySwapping = FALSE;
_HalInfo = lpHalInfo;
_SubWin.x1 = 0;
_SubWin.y1 = 0;
_SubWin.x2 = 1;
_SubWin.y2 = 1;
err = _InitLinear();
if (err != ERR_OK)
return err;
_MemorySize = DISPLAY_BUFFER_SIZE;
_seVmemInit(_MemorySize);
//
// Default to software swapping for big-endian systems.
//
seCheckEndian(&_EndianReverseRegisterBytes);
_EndianReverseDisplayBytes = _EndianReverseRegisterBytes;
seAllocMainWinSurface(0x10000); // allocate some memory just to prevent HAL from crashing
seSetMainWinAsActiveSurface();
return ERR_OK;
}
/*-------------------------------------------------------------------------*/
/*
** seRegisterDevice()
**
** This function MUST be called first to set up the HAL library.
*/
int seRegisterDevice(const LPHAL_STRUCT lpHalInfo)
{
int id;
int err;
err = _RegisterDevice(lpHalInfo);
if (err != ERR_OK)
return err;
_MemorySize = DISPLAY_BUFFER_SIZE;
_seVmemInit(_MemorySize);
err = seGetId(&id);
_AutoAllocSurface(MAIN_WIN);
return err;
}
/*-------------------------------------------------------------------------*/
int seHalTerminate(void)
{
#ifdef INTEL_W32
switch (_IntelUnmapLinearMemory())
{
case 0:
return ERR_OK;
case 1:
return ERR_PCI_DRIVER_NOT_FOUND;
case 2:
return ERR_PCI_BRIDGE_ADAPTER_NOT_FOUND;
default:
return ERR_FAILED;
}
#else
return ERR_OK;
#endif
}
/*-------------------------------------------------------------------------*/
DWORD seGetInstalledMemorySize(void)
{
return _MemorySize;
}
/*-------------------------------------------------------------------------*/
int _InitializeClockChip(void)
{
int iFreq;
int errClock;
DWORD bits;
char *szFreq;
/*
** Initialize clock chip
*/
errClock = ERR_OK;
/* First initialize CLKI (VREG0 in clock chip) */
for (iFreq = 0; iFreq < MAX_FREQ_INDEX; ++iFreq)
{
if (_VClkBits[iFreq].dwFreq == _HalInfo->dwClkI)
break;
}
/*
** Couldn't find CLKI in table
*/
if (iFreq >= MAX_FREQ_INDEX)
errClock = ERR_CLKI_NOT_IN_TABLE;
else
{
if (_GetClockChipBits(iFreq, CLK_VREG0, &bits, &szFreq) != ERR_OK)
errClock = ERR_CLKI_NOT_IN_TABLE;
}
if (errClock != ERR_CLKI_NOT_IN_TABLE)
_ProgramClockChip(bits, CLK_VREG0); /* pgm VREG0 in clock chip */
/*
** Next program CLKI2 (MREG in clock chip)
*/
for (iFreq = 0; iFreq < MAX_FREQ_INDEX; ++iFreq)
{
if (_MClkBits[iFreq].dwFreq == _HalInfo->dwClkI2)
break;
}
/*
** Couldn't find CLKI2 in table
*/
if (iFreq >= MAX_FREQ_INDEX)
errClock = ERR_CLKI2_NOT_IN_TABLE;
else
{
if (_GetClockChipBits(iFreq, CLK_MREG, &bits, &szFreq) != ERR_OK)
errClock = ERR_CLKI2_NOT_IN_TABLE;
}
if (errClock != ERR_CLKI2_NOT_IN_TABLE)
_ProgramClockChip(bits, CLK_VREG0); /* pgm MREG in clock chip, then select VREG0 */
return errClock;
}
/*-------------------------------------------------------------------------*/
//
// _UpdateHardwareDisplaySwapping() is designed to be called only from seSetMode().
//
// If swapping is required, use hardware display swapping
// (but only for bytes, not words).
//
void _UpdateHardwareDisplaySwapping(void)
{
int ValidBitsPerPixel;
if (seGetBitsPerPixel() == 16)
ValidBitsPerPixel = TRUE;
else
ValidBitsPerPixel = FALSE;
if (!ValidBitsPerPixel || !_EndianReverseDisplayBytes || !_OnValidBppAllowHardwareDisplaySwapping)
{
_AllowHardwareDisplaySwapping = FALSE;
//
// Disable Display Data Word and Byte Swapping.
//
seWriteRegByte(REG_SPECIAL_EFFECTS, seReadRegByte(REG_SPECIAL_EFFECTS) & ~0xc0);
// Don't try again if not big-endian system
if (!_EndianReverseDisplayBytes)
_OnValidBppAllowHardwareDisplaySwapping = FALSE;
}
else
{
_AllowHardwareDisplaySwapping = TRUE;
//
// Enable Display Data Byte Swapping (but not word swapping since this is 16 bpp).
//
seWriteRegByte(REG_SPECIAL_EFFECTS, seReadRegByte(REG_SPECIAL_EFFECTS) | 0x40);
}
}
/*-------------------------------------------------------------------------*/
//
// If swapping is required, use hardware display swapping
// (but only for bytes, not words).
//
// Returns ERR_OK if OK.
// Returns ERR_FAILED if not in 16 bpp or not in big-endian platform.
//
int seEnableHardwareDisplaySwapping(int enable)
{
int ValidBitsPerPixel;
if (seGetBitsPerPixel() == 16)
ValidBitsPerPixel = TRUE;
else
ValidBitsPerPixel = FALSE;
if (!enable || !ValidBitsPerPixel || !_EndianReverseDisplayBytes)
{
_AllowHardwareDisplaySwapping = FALSE;
//
// Disable Display Data Word and Byte Swapping.
//
seWriteRegByte(REG_SPECIAL_EFFECTS, seReadRegByte(REG_SPECIAL_EFFECTS) & ~0xc0);
if (!enable)
{
_OnValidBppAllowHardwareDisplaySwapping = FALSE;
return ERR_OK; // caller asked to turn off HW swapping
}
else
{
// Just wrong bits-per-pixel; bpp might be changed with a later call to seSetMode()
if (!ValidBitsPerPixel && _EndianReverseDisplayBytes)
_OnValidBppAllowHardwareDisplaySwapping = TRUE;
else
_OnValidBppAllowHardwareDisplaySwapping = FALSE;
return ERR_FAILED; // caller asked to turn on HW swapping, but in wrong mode
}
}
else
{
_AllowHardwareDisplaySwapping = TRUE;
_OnValidBppAllowHardwareDisplaySwapping = TRUE;
//
// Enable Display Data Byte Swapping (but not word swapping since this is 16 bpp).
//
seWriteRegByte(REG_SPECIAL_EFFECTS, seReadRegByte(REG_SPECIAL_EFFECTS) | 0x40);
return ERR_OK;
}
}
/*-------------------------------------------------------------------------*/
/*
** This routine sets the register values for the given device.
** The reason for setting the registers separately from the
** the registration is to support programs like PLAY where
** it is undesirable to indiscriminately update the registers.
*/
/*
** If DisplayMode is non-zero, this value overrides that
** in the CFG register structure.
**
** Legal values for flags:
** CLEAR_MEM, DISP_BLANK
** To combine the above flags, use the logical OR operation.
** For example, (CLEAR_MEM | DISP_BLANK) clears memory and
** turns off the display FIFO.
**
** WARNING: seInitReg() can NOT call any function which
** relies on the display surface. The display surface
** is initialized AFTER all other registers are initialized.
**
** If the hardware display swapping flag is set, seInitReg() will cancel this flag.
** seEnableHardwareDisplaySwapping() must be called again if hardware display swapping
** is required.
*/
int seInitReg(unsigned flags)
{
int idx, index;
defReg *pRegs;
BYTE *pGcpData;
int i;
BYTE color[3];
unsigned val;
unsigned regDisplayMode;
int err;
int errClock = ERR_OK;
int iDisplayMode;
/*
** Cancel hardware display swapping because the registers are being re-initialized.
*/
_AllowHardwareDisplaySwapping = FALSE;
_OnValidBppAllowHardwareDisplaySwapping = FALSE;
/*
** Don't program clock if panel is D-TFD
*/
_FindReg(REG_PANEL_TYPE, &val, &iDisplayMode);
if ((val & 0x03) != 0x03)
errClock = _InitializeClockChip();
/*
** Write to registers.
*/
pRegs = &(_HalInfo->Regs[0]);
for (index = 0; index < MAX_REG; ++index, ++pRegs)
{
idx = pRegs->index;
val = pRegs->val;
if (idx == FINISHED_REG_CFG)
break;
if (flags & DISP_BLANK)
{
if (idx == REG_DISPLAY_MODE)
val |= 0x80; /* Set Display Blank */
}
if (idx == REG_GPIO_STATUS_CONTROL0)
val &= ~0x20; // GPIO5 should be 0 (needed for D-TFD panel)
seWriteRegByte(idx, val);
}
/*
** Initialize D-TFD data register if panel is D-TFD
*/
if ((seReadRegByte(REG_PANEL_TYPE) & 0x03) == 0x03)
{
// Set GPIO5 low
seWriteRegByte(REG_GPIO_STATUS_CONTROL0, seReadRegByte(REG_GPIO_STATUS_CONTROL0) & ~0x20);
pGcpData = &(_HalInfo->GcpData[0]);
for (index = 0; index < MAX_GCP_DATA; ++index, ++pGcpData)
{
seWriteRegByte(REG_DTFD_GCP_INDEX, index);
seWriteRegByte(REG_DTFD_GCP_DATA, *pGcpData);
}
seWriteRegByte(REG_GPIO_CONFIG0, 0x7f); // force pins to outputs
}
/*
** Based on the current BPP - set the LUT to default values.
*/
regDisplayMode = seReadRegByte(REG_DISPLAY_MODE);
if (seReadRegByte(REG_PANEL_TYPE) & 0x40) /* color */
{
/*
** Initialize LCD LUT
*/
switch (regDisplayMode & 0x07)
{
case 0: /* 1 bpp */
_WriteLut(LUT1, 2);
break;
case 1: /* 2 bpp color */
_WriteLut(LUT2_Color, 4);
break;
case 2: /* 4 bpp color */
_WriteLut(LUT4_Color, 16);
break;
case 3: /* 8 bpp color */
_WriteLut(LUT8_Color, 256);
break;
default:
break;
}
}
else switch (regDisplayMode & 0x07)
{
case 0: /* 1 bpp */
_WriteLut(LUT1, 2);
break;
case 1: /* 2 bpp mono */
_WriteLut(LUT2_Mono, 4);
break;
case 2: /* 4 bpp mono */
for (i = 0; i < 16; ++i)
{
color[HAL_RED] = (BYTE) (i << 4);
color[HAL_GREEN] = (BYTE) (i << 4);
color[HAL_BLUE] = (BYTE) (i << 4);
_WriteLutEntry(i, color);
}
break;
case 3: /* 8 bpp mono */
for (i = 0; i < 256; ++i)
{
color[HAL_RED] = (BYTE) (i << 2);
color[HAL_GREEN] = (BYTE) (i << 2);
color[HAL_BLUE] = (BYTE) (i << 2);
_WriteLutEntry(i, color);
}
break;
default:
break;
}
seSetPowerSaveMode(FALSE); // go into power up sequence
// Free all display memory
_seVmemInit(_MemorySize);
if (flags & DISP_BLANK)
{
/*
** Disable Display blank to show image
*/
val = seReadRegByte(REG_DISPLAY_MODE) & ~0x80;
seWriteRegByte(REG_DISPLAY_MODE, val);
}
err = _AutoAllocSurface(MAIN_WIN);
/*
** Clear all visible display memory.
*/
if (flags & CLEAR_MEM)
seWriteDisplayDwords(0, 0, seGetAvailableMemorySize() / 4);
seGetSubWinCoordinates(&_SubWin.x1, &_SubWin.y1, &_SubWin.x2, &_SubWin.y2);
if (errClock != ERR_OK)
return errClock;
else if ((err == ERR_OK) || (err == ERR_DISPLAY_NOT_ENABLED))
return ERR_OK;
else
return err;
}
/*-------------------------------------------------------------------------*/
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -