#include <windows.h>
#include <types.h>
#include <memory.h>
#include <nkintr.h>
#include <tchddsi.h>
#include <nkintr.h>
#include <oalintr.h>
#include <s2410.h>
#define PUBLIC
#define PRIVATE static
#define TSP_SAMPLE_RATE_LOW 100
#define TSP_SAMPLE_RATE_HIGH 100
#define TSP_SAMPLETICK (OEM_CLOCK_FREQ / TSP_SAMPLE_RATE_LOW)
#define ADCPRS 200
#define TSP_MINX 85
#define TSP_MINY 105
#define TSP_MAXX 965
#define TSP_MAXY 980
#define TSP_CHANGE 15
#define TSP_INVALIDLIMIT 40
#define TSP_LCDX (LCD_XSIZE_TFT * 4)
#define TSP_LCDY (LCD_YSIZE_TFT * 4)
#define TSP_SAMPLE_NUM 4
DWORD gIntrTouch = SYSINTR_TOUCH;
DWORD gIntrTouchChanged = SYSINTR_TOUCH_CHANGED;
extern "C" const int MIN_CAL_COUNT = 1;
PRIVATE INT TSP_CurRate = TSP_SAMPLE_RATE_HIGH;
PRIVATE volatile IOPreg * v_pIOPregs;
PRIVATE volatile ADCreg * v_pADCregs;
PRIVATE volatile INTreg * v_pINTregs;
PRIVATE volatile PWMreg * v_pPWMregs;
PRIVATE BOOL bTSP_DownFlag;
VOID TSP_VirtualFree(VOID);
BOOL TSP_VirtualAlloc(VOID);
PRIVATE PVOID
TSP_RegAlloc(PVOID addr, INT sz)
{
PVOID reg;
reg = (PVOID)VirtualAlloc(0, sz, MEM_RESERVE, PAGE_NOACCESS);
if (reg)
{
if (!VirtualCopy(reg, addr, sz, PAGE_READWRITE | PAGE_NOCACHE ))
{
VirtualFree(reg, sz, MEM_RELEASE);
reg = NULL;
}
}
return reg;
}
PRIVATE BOOL
TSP_VirtualAlloc(VOID)
{
BOOL r = FALSE;
RETAILMSG(0,(TEXT("::: TSP_VirtualAlloc()\r\n")));
do
{
v_pIOPregs = (volatile IOPreg *)TSP_RegAlloc((PVOID)IOP_BASE, sizeof(IOPreg));
if (v_pIOPregs == NULL)
{
ERRORMSG(1,(TEXT("For IOPreg: VirtualAlloc failed!\r\n")));
break;
}
v_pADCregs = (volatile ADCreg *)TSP_RegAlloc((PVOID)ADC_BASE, sizeof(ADCreg));
if (v_pADCregs == NULL)
{
ERRORMSG(1,(TEXT("For ADCreg: VirtualAlloc failed!\r\n")));
break;
}
v_pINTregs = (volatile INTreg *)TSP_RegAlloc((PVOID)INT_BASE, sizeof(INTreg));
if (v_pADCregs == NULL)
{
ERRORMSG(1,(TEXT("For INTregs: VirtualAlloc failed!\r\n")));
break;
}
v_pPWMregs = (volatile PWMreg *)TSP_RegAlloc((PVOID)PWM_BASE, sizeof(PWMreg));
if (v_pPWMregs == NULL)
{
ERRORMSG(1,(TEXT("For PWMregs: VirtualAlloc failed!\r\n")));
break;
}
r = TRUE;
} while (0);
if (!r)
{
TSP_VirtualFree();
RETAILMSG(0,(TEXT("::: TSP_VirtualAlloc() - Fail\r\n")));
}
else
{
RETAILMSG(0,(TEXT("::: TSP_VirtualAlloc() - Success\r\n")));
}
return r;
}
PRIVATE void
TSP_VirtualFree(VOID)
{
RETAILMSG(0,(TEXT("::: TSP_VirtualFree()\r\n")));
if (v_pIOPregs)
{
VirtualFree((PVOID)v_pIOPregs, sizeof(IOPreg), MEM_RELEASE);
v_pIOPregs = NULL;
}
if (v_pADCregs)
{
VirtualFree((PVOID)v_pADCregs, sizeof(ADCreg), MEM_RELEASE);
v_pADCregs = NULL;
}
if (v_pINTregs)
{
VirtualFree((PVOID)v_pINTregs, sizeof(INTreg), MEM_RELEASE);
v_pINTregs = NULL;
}
if (v_pPWMregs)
{
VirtualFree((PVOID)v_pPWMregs, sizeof(INTreg), MEM_RELEASE);
v_pPWMregs = NULL;
}
}
PRIVATE VOID
TSP_SampleStart(VOID)
{
DWORD tmp;
tmp = v_pPWMregs->rTCON & (~(0xf << 16));
v_pPWMregs->rTCON = tmp | (2 << 16); /* update TCVNTB3, stop */
v_pPWMregs->rTCON = tmp | (9 << 16); /* interval mode, start */
// v_pPWMregs->rTCON = tmp | (1 << 16); /* one-shot mode, start */
}
PRIVATE VOID
TSP_SampleStop(VOID)
{
v_pPWMregs->rTCON &= ~(1 << 16); /* Timer3, stop */
}
PRIVATE VOID
TSP_PowerOn(VOID)
{
RETAILMSG(0,(TEXT("::: TSP_PowerOn()\r\n")));
/* Use TSXM, TSXP, TSYM, TSYP */
v_pIOPregs->rGPGCON |= ((0x3 << 30) | (0x3 << 28) | (0x3 << 26) | (0x3 << 24));
v_pADCregs->rADCDLY = 50000;
v_pADCregs->rADCCON = (1 << 14) | /* A/D Converter Enable */
(ADCPRS << 6) | /* Prescaler Setting */
(0 << 3) | /* Analog Input Channel : 0 */
(0 << 2) | /* Normal Operation Mode */
(0 << 1) | /* Disable Read Start */
(0 << 0); /* No Operation */
v_pADCregs->rADCTSC = (0 << 8) | /* UD_Sen */
(1 << 7) | /* YMON 1 (YM = GND) */
(1 << 6) | /* nYPON 1 (YP Connected AIN[n]) */
(0 << 5) | /* XMON 0 (XM = Z) */
(1 << 4) | /* nXPON 1 (XP = AIN[7]) */
(0 << 3) | /* Pull Up Disable */
(0 << 2) | /* Normal ADC Conversion Mode */
(3 << 0); /* Waiting Interrupt */
v_pINTregs->rINTSUBMSK &= ~BIT_SUB_TC;
v_pPWMregs->rTCFG1 &= ~(0xf << 12); /* Timer3's Divider Value */
v_pPWMregs->rTCFG1 |= (0 << 12); /* 1/2 */
v_pPWMregs->rTCNTB3 = TSP_SAMPLETICK; /* Interrupt Frequency */
}
PRIVATE VOID
TSP_PowerOff(VOID)
{
RETAILMSG(0,(TEXT("::: TSP_PowerOff()\r\n")));
v_pINTregs->rINTSUBMSK |= BIT_SUB_TC;
}
PRIVATE BOOL
TSP_CalibrationPointGet(TPDC_CALIBRATION_POINT *pTCP)
{
INT32 cDisplayWidth = pTCP->cDisplayWidth;
INT32 cDisplayHeight = pTCP->cDisplayHeight;
int CalibrationRadiusX = cDisplayWidth / 20;
int CalibrationRadiusY = cDisplayHeight / 20;
switch (pTCP -> PointNumber)
{
case 0:
pTCP->CalibrationX = cDisplayWidth / 2;
pTCP->CalibrationY = cDisplayHeight / 2;
break;
case 1:
pTCP->CalibrationX = CalibrationRadiusX * 2;
pTCP->CalibrationY = CalibrationRadiusY * 2;
break;
case 2:
pTCP->CalibrationX = CalibrationRadiusX * 2;
pTCP->CalibrationY = cDisplayHeight - CalibrationRadiusY * 2;
break;
case 3:
pTCP->CalibrationX = cDisplayWidth - CalibrationRadiusX * 2;
pTCP->CalibrationY = cDisplayHeight - CalibrationRadiusY * 2;
break;
case 4:
pTCP->CalibrationX = cDisplayWidth - CalibrationRadiusX * 2;
pTCP->CalibrationY = CalibrationRadiusY * 2;
break;
default:
pTCP->CalibrationX = cDisplayWidth / 2;
pTCP->CalibrationY = cDisplayHeight / 2;
SetLastError(ERROR_INVALID_PARAMETER);
return FALSE;
}
RETAILMSG(0, (TEXT("::: TSP_CalibrationPointGet()\r\n")));
RETAILMSG(0, (TEXT("cDisplayWidth : %4X\r\n"), cDisplayWidth ));
RETAILMSG(0, (TEXT("cDisplayHeight : %4X\r\n"), cDisplayHeight ));
RETAILMSG(0, (TEXT("CalibrationRadiusX : %4d\r\n"), CalibrationRadiusX));
RETAILMSG(0, (TEXT("CalibrationRadiusY : %4d\r\n"), CalibrationRadiusY));
RETAILMSG(0, (TEXT("pTCP -> PointNumber : %4d\r\n"), pTCP->PointNumber));
RETAILMSG(0, (TEXT("pTCP -> CalibrationX : %4d\r\n"), pTCP->CalibrationX));
RETAILMSG(0, (TEXT("pTCP -> CalibrationY : %4d\r\n"), pTCP->CalibrationY));
return TRUE;
}
PRIVATE void
TSP_TransXY(INT *px, INT *py)
{
*px = (*px - TSP_MINX) * TSP_LCDX / (TSP_MAXX - TSP_MINX);
*py = (*py - TSP_MINY) * TSP_LCDY / (TSP_MAXY - TSP_MINY);
if (*px < 0) *px = 0;
if (*px >= TSP_LCDX) *px = TSP_LCDX - 1;
if (*py < 0) *py = 0;
if (*py >= TSP_LCDY) *py = TSP_LCDY - 1;
}
PRIVATE BOOL
TSP_GetXY(INT *px, INT *py)
{
INT i;
INT xsum, ysum;
INT x, y;
INT dx, dy;
xsum = ysum = 0;
for (i = 0; i < TSP_SAMPLE_NUM; i++)
{
v_pADCregs->rADCTSC = (0 << 8) | /* UD_Sen */
(1 << 7) | /* YMON 1 (YM = GND) */
(1 << 6) | /* nYPON 1 (YP Connected AIN[n]) */
(0 << 5) | /* XMON 0 (XM = Z) */
(1 << 4) | /* nXPON 1 (XP = AIN[7]) */
(1 << 3) | /* Pull Up Enable */
(1 << 2) | /* Auto ADC Conversion Mode */
(0 << 0); /* No Operation Mode */
v_pADCregs->rADCCON |= (1 << 0); /* Start Auto conversion */
while (v_pADCregs->rADCCON & 0x1); /* check if Enable_start is low */
while (!(v_pADCregs->rADCCON & (1 << 15))); /* Check ECFLG */
x = (0x3ff & v_pADCregs->rADCDAT1);
y = 0x3ff - (0x3ff & v_pADCregs->rADCDAT0);
xsum += x;
ysum += y;
}
*px = xsum / TSP_SAMPLE_NUM;
*py = ysum / TSP_SAMPLE_NUM;
v_pADCregs->rADCTSC = (1 << 8) | /* UD_Sen */
(1 << 7) | /* YMON 1 (YM = GND) */
(1 << 6) | /* nYPON 1 (YP Connected AIN[n]) */
(0 << 5) | /* XMON 0 (XM = Z) */
(1 << 4) | /* nXPON 1 (XP = AIN[7]) */
(0 << 3) | /* Pull Up Disable */
(0 << 2) | /* Normal ADC Conversion Mode */
(3 << 0); /* Waiting Interrupt */
dx = (*px > x) ? (*px - x) : (x - *px);
dy = (*py > y) ? (*py - y) : (y - *py);
return ((dx > TSP_INVALIDLIMIT || dy > TSP_INVALIDLIMIT) ? FALSE : TRUE);
}
/* :::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: */
/* :::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: */
PUBLIC BOOL
DdsiTouchPanelGetDeviceCaps(INT iIndex, LPVOID lpOutput)
{
RETAILMSG(0, (TEXT("::: DdsiTouchPanelGetDeviceCaps\r\n")));
if ( lpOutput == NULL )
{
ERRORMSG(1, (__TEXT("TouchPanelGetDeviceCaps: invalid parameter.\r\n")));
SetLastError(ERROR_INVALID_PARAMETER);
DebugBreak();
return FALSE;
}
switch ( iIndex )
{
case TPDC_SAMPLE_RATE_ID:
{
TPDC_SAMPLE_RATE *pTSR = (TPDC_SAMPLE_RATE*)lpOutput;
RETAILMSG(0, (TEXT("TouchPanelGetDeviceCaps::TPDC_SAMPLE_RATE_ID\r\n")));
pTSR->SamplesPerSecondLow = TSP_SAMPLE_RATE_LOW;
pTSR->SamplesPerSecondHigh = TSP_SAMPLE_RATE_HIGH;
pTSR->CurrentSampleRateSetting = TSP_CurRate;
}
break;
case TPDC_CALIBRATION_POINT_COUNT_ID:
{
TPDC_CALIBRATION_POINT_COUNT *pTCPC = (TPDC_CALIBRATION_POINT_COUNT*)lpOutput;
RETAILMSG(0, (TEXT("TouchPanelGetDeviceCaps::TPDC_CALIBRATION_POINT_COUNT_ID\r\n")));
pTCPC->flags = 0;
pTCPC->cCalibrationPoints = 5;
}
break;
case TPDC_CALIBRATION_POINT_ID:
RETAILMSG(0, (TEXT("TouchPanelGetDeviceCaps::TPDC_CALIBRATION_POINT_ID\r\n")));
return(TSP_CalibrationPointGet((TPDC_CALIBRATION_POINT*)lpOutput));
default:
ERRORMSG(1, (__TEXT("TouchPanelGetDeviceCaps: invalid parameter.\r\n")));
SetLastError(ERROR_INVALID_PARAMETER);
DebugBreak();
return FALSE;
}
return TRUE;
}
/* :::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: */
/* :::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: */
PUBLIC BOOL
DdsiTouchPanelSetMode(INT iIndex, LPVOID lpInput)
{
BOOL ReturnCode = FALSE;
RETAILMSG(0, (TEXT("::: DdsiTouchPanelSetMode()\r\n")));
switch ( iIndex )
{
case TPSM_SAMPLERATE_LOW_ID:
case TPSM_SAMPLERATE_HIGH_ID:
SetLastError( ERROR_SUCCESS );
ReturnCode = TRUE;
break;
default:
SetLastError( ERROR_INVALID_PARAMETER );
break;
}
return ( ReturnCode );
}
/* :::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: */
/* :::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: */
PUBLIC BOOL
DdsiTouchPanelEnable(VOID)
{
BOOL r;
RETAILMSG(0, (TEXT("::: DdsiTouchPanelEnable()\r\n")));
r = TSP_VirtualAlloc();
if (r)
{
TSP_PowerOn();
}
return r;
}
/* :::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: */
/* :::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: */
PUBLIC VOID
DdsiTouchPanelDisable(VOID)
{
RETAILMSG(0, (TEXT("::: DdsiTouchPanelDisable()\r\n")));
if (v_pADCregs)
{
TSP_PowerOff();
TSP_VirtualFree();
}
}
/* :::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: */
/* :::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: */
LONG
DdsiTouchPanelAttach(VOID)
{
return (0);
}
LONG
DdsiTouchPanelDetach(VOID)
{
return (0);
}
/* :::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: */
/* :::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: */
PUBLIC VOID
DdsiTouchPanelPowerHandler(BOOL bOff)
{
RETAILMSG(0, (TEXT("::: DdsiTouchPanelPowerHandler()\r\n")));
if (bOff)
{
TSP_PowerOff();
}
else
{
TSP_PowerOn();
}
}
/* :::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: */
/* :::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: */
PUBLIC VOID
DdsiTouchPanelGetPoint(TOUCH_PANEL_SAMPLE_FLAGS * pTipStateFlags,
INT * pUncalX,
INT * pUncalY)
{
static INT x, y;
//DEBUGMSG(1, (TEXT("::: DdsiTouchPanelGetPoint()\r\n")));
if (v_pINTregs->rSUBSRCPND & BIT_SUB_TC) /* SYSINTR_TOUCH Interrupt Case */
{
*pTipStateFlags = TouchSampleValidFlag;
if ( (v_pADCregs->rADCDAT0 & (1 << 15)) |
(v_pADCregs->rADCDAT1 & (1 << 15)) )
{
bTSP_DownFlag = FALSE;
DEBUGMSG(ZONE_TIPSTATE, (TEXT("up\r\n")));
v_pADCregs->rADCTSC &= 0xff;
*pUncalX = x;
*pUncalY = y;
TSP_SampleStop();
}
else
{
bTSP_DownFlag = TRUE;
if (!TSP_GetXY(&x, &y))
*pTipStateFlags = TouchSampleIgnore;
TSP_TransXY(&x, &y);
*pUncalX = x;
*pUncalY = y;
*pTipStateFlags |= TouchSampleDownFlag;
DEBUGMSG(ZONE_TIPSTATE, (TEXT("down %x %x\r\n"), x, y));
TSP_SampleStart();
}
v_pINTregs->rSUBSRCPND = BIT_SUB_TC;
v_pINTregs->rINTSUBMSK &= ~BIT_SUB_TC;
InterruptDone(gIntrTouch);
}
else /* SYSINTR_TOUCH_CHANGED Interrupt Case */
{
// TSP_SampleStart();
if (bTSP_DownFlag)
{
INT tx, ty;
INT dx, dy;
if (!TSP_GetXY(&tx, &ty))
*pTipStateFlags = TouchSampleIgnore;
else
{
TSP_TransXY(&tx, &ty);
// insert by mostek@dstcorp.com
#define X_ERRV 0x3bf
#define Y_ERRV 0x4ff
if ((tx == X_ERRV) && (ty == Y_ERRV))
{
tx = x;
ty = y;
}
// =================== mostek
dx = (tx > x) ? (tx - x) : (x - tx);
dy = (ty > y) ? (ty - y) : (y - ty);
if (dx > TSP_CHANGE || dy > TSP_CHANGE)
{
*pUncalX = x = tx;
*pUncalY = y = ty;
DEBUGMSG(ZONE_TIPSTATE, (TEXT("down-c-v %x %x\r\n"), x, y));
*pTipStateFlags = TouchSampleValidFlag | TouchSampleDownFlag;
}
else
{
*pUncalX = x;
*pUncalY = y;
DEBUGMSG(ZONE_TIPSTATE, (TEXT("down-c %x %x\r\n"), x, y));
*pTipStateFlags = TouchSampleIgnore;
}
}
}
else
{
*pTipStateFlags = TouchSampleIgnore;
TSP_SampleStop();
}
InterruptDone(gIntrTouchChanged);
}
}
#if 0
PUBLIC VOID
DdsiTouchPanelGetPoint(TOUCH_PANEL_SAMPLE_FLAGS * pTipStateFlags,
INT * pUncalX,
INT * pUncalY)
{
static INT x, y;
//RETAILMSG(0, (TEXT("::: DdsiTouchPanelGetPoint()\r\n")));
if (v_pINTregs->rSUBSRCPND & BIT_SUB_TC) /* SYSINTR_TOUCH Interrupt Case */
{
*pTipStateFlags = TouchSampleValidFlag;
if (v_pADCregs->rADCTSC & (1 << 8))
{
bTSP_DownFlag = FALSE;
RETAILMSG(0, (TEXT("up\r\n")));
v_pADCregs->rADCTSC &= 0xff;
*pUncalX = x;
*pUncalY = y;
TSP_SampleStop();
}
else
{
bTSP_DownFlag = TRUE;
if (!TSP_GetXY(&x, &y))
*pTipStateFlags = TouchSampleIgnore;
TSP_TransXY(&x, &y);
*pUncalX = x;
*pUncalY = y;
*pTipStateFlags |= TouchSampleDownFlag;
RETAILMSG(0, (TEXT("down %x %x\r\n"), x, y));
TSP_SampleStart();
}
v_pINTregs->rSUBSRCPND = BIT_SUB_TC;
v_pINTregs->rINTSUBMSK &= ~BIT_SUB_TC;
InterruptDone(gIntrTouch);
}
else /* SYSINTR_TOUCH_CHANGED Interrupt Case */
{
// TSP_SampleStart();
if (bTSP_DownFlag)
{
INT tx, ty;
INT dx, dy;
if (!TSP_GetXY(&tx, &ty))
*pTipStateFlags = TouchSampleIgnore;
else
{
TSP_TransXY(&tx, &ty);
dx = (tx > x) ? (tx - x) : (x - tx);
dy = (ty > y) ? (ty - y) : (y - ty);
if (dx > TSP_CHANGE || dy > TSP_CHANGE)
{
*pUncalX = x = tx;
*pUncalY = y = ty;
RETAILMSG(0, (TEXT("down-c-v %x %x\r\n"), x, y));
*pTipStateFlags = TouchSampleValidFlag | TouchSampleDownFlag;
}
else
{
*pUncalX = x;
*pUncalY = y;
RETAILMSG(0, (TEXT("down-c %x %x\r\n"), x, y));
*pTipStateFlags = TouchSampleIgnore;
}
}
}
else
{
*pTipStateFlags = TouchSampleIgnore;
TSP_SampleStop();
}
InterruptDone(gIntrTouchChanged);
}
}
#endif