?? tchpdd.cpp
字號:
// @comm
// Implemented in the PDD.
//
VOID
DdsiTouchPanelDisable(
VOID
)
{
//
// Check pointers in case the enable failed.
//
if(v_pADCregs == NULL)
return ;
TouchPanelPowerOff(); // Power down the device
PddpTouchPanelDeallocateVm(); // free up any resources
}
//
// @doc EX_TOUCH_DDSI EXTERNAL DRIVERS DDSI TOUCH_PANEL
//
// @func LONG | DdsiTouchPanelAttach |
// This routine no longer does anything. All functionallity has been moved
// from here into DdsiTouchPanelEnable to allow this code to be statically
// linked with GWE rather than existing as a DLL. Technically, when built
// as a DLL we should keep an attach count and only allow touh.dll to be
// loaded once. But, since we are loaded at boot time by GWE, there is
// no real concern about multiple loads (unless gwe has a bug!).
//
// @rdesc
// Always returns 0
//
// @comm
// Implemented in the PDD.
//
LONG
DdsiTouchPanelAttach(
VOID
)
{
return( 1 );
}
//
// @doc EX_TOUCH_DDSI EXTERNAL DRIVERS DDSI TOUCH_PANEL
//
// @func LONG | DdsiTouchPanelDetach |
// See the descrition for attach. All functionallity has been moved into
// DdsiTouchPanelDisable.
//
// @rdesc
// The updated global counter. If the initializations failed, the returned
// count is 0.
//
// @comm
// Implemented in the PDD.
//
LONG
DdsiTouchPanelDetach(
VOID
)
{
return ( 0 );
}
#define COODI_Y
//
// @doc EX_TOUCH_DDSI EXTERNAL DRIVERS DDSI TOUCH_PANEL
//
// @func void | DdsiTouchPanelGetPoint |
// Returns the most recently acquired point and its associated tip state
// information.
//
// @parm PDDSI_TOUCHPANEL_TIPSTATE | pTipState |
// Pointer to where the tip state information will be returned.
// @parm PLONG | pUnCalX |
// Pointer to where the x coordinate will be returned.
// @parm PLONG | pUnCalY |
// Pointer to where the y coordinate will be returned.
//
// @comm
// Implmented in the PDD.
//
#define TOUCH_MAX_X 960 // 950
#define TOUCH_MIN_X 50 // 90
#define TOUCH_MAX_Y 900 // 960 // 910
#define TOUCH_MIN_Y 30 // 70 //50
#define TOUCH_X 320 //vencent
#define TOUCH_Y 240
#define TOUCH_ERR 15
static int second = 0;
VOID Touch_CoordinateConversion(INT *px, INT *py)
{
INT TmpX, TmpY;
INT TmpX0, TmpY0;
TmpX0 = *px; TmpY0 = *py;
TmpX = (*px >= TOUCH_MAX_X) ? (TOUCH_MAX_X-1) : *px;
TmpY = (*py >= TOUCH_MAX_Y) ? (TOUCH_MAX_Y-1) : *py;
TmpX -= TOUCH_MIN_X;
TmpY -= TOUCH_MIN_Y;
TmpX = (TmpX) ? TmpX : 0;
TmpY = (TmpY) ? TmpY : 0;
*px = ((TmpX * TOUCH_X) / (TOUCH_MAX_X-TOUCH_MIN_X))*4;
*py = ((TmpY * TOUCH_Y) / (TOUCH_MAX_Y-TOUCH_MIN_Y))*4;
return;
}
VOID
DdsiTouchPanelGetPoint(
TOUCH_PANEL_SAMPLE_FLAGS *pTipStateFlags,
INT *pUncalX,
INT *pUncalY
)
{
ULONG status;
// USHORT ioAdcCntr;
// USHORT intrMask;
static int SampleCount = 0;
static TOUCH_PANEL_SAMPLE_FLAGS PrevStateFlags = TouchSampleIgnore;
static INT PrevX = 0;
static INT PrevY = 0;
TOUCH_PANEL_SAMPLE_FLAGS TmpStateFlags;
INT TmpX = 0;
INT TmpY = 0;
int i;
//RETAILMSG(1, (TEXT(":::::::::::: DdsiTouchPanelGetPoint routine !!!\r\n")));
// Read the status passed back by the HAL
status = READ_REGISTER_ULONG( &(v_pDriverGlobals->tch.status) );
if(status == TOUCH_PEN_UP) {
v_pADCregs->rADCTSC = 0xD3; // Set stylus down interrupt
*pTipStateFlags = TouchSampleValidFlag;
*pUncalX = PrevX;
*pUncalY = PrevY;
InterruptDone( gIntrTouchChanged );
RETAILMSG(0, (TEXT("8 - (%d, %d) 0x%X\r\n"), *pUncalX, *pUncalY, *pTipStateFlags));
}
else if(status == TOUCH_PEN_DOWN){
*pTipStateFlags = TouchSampleIgnore;
*pUncalX = PrevX;
*pUncalY = PrevY;
Touch_Timer0_Setup();
InterruptDone( gIntrTouchChanged );
RETAILMSG(0, (TEXT("9 - (%d, %d) 0x%X\r\n"), *pUncalX, *pUncalY, *pTipStateFlags));
}
else {
if( (v_pADCregs->rADCDAT0 & 0x8000) || (v_pADCregs->rADCDAT1 & 0x8000) ){
v_pADCregs->rADCTSC = 0xD3; // Set stylus down interrupt
*pTipStateFlags = TouchSampleValidFlag;
*pUncalX = PrevX;
*pUncalY = PrevY;
InterruptDone( gIntrTouchChanged );
RETAILMSG(0, (TEXT("91 - (%d, %d) 0x%X\r\n"), *pUncalX, *pUncalY, *pTipStateFlags));
}
else{ // charlie
// <Auto X-Position and Y-Position Read>
for (i =0; i < 3; i++) {
//v_pADCregs->rADCTSC=(0<<8)|(1<<7)|(1<<6)|(0<<5)|(1<<4)|(1<<3)|(1<<2)|(0);
v_pADCregs->rADCTSC=(1<<3)|(1<<2);
// Stylus Down,Don't care,Don't care,Don't care,Don't care,XP pullup Dis,Auto,No operation
v_pADCregs->rADCCON|=0x1; // Start Auto conversion
while(v_pADCregs->rADCCON & 0x1); //check if Enable_start is low
while(!(0x8000&v_pADCregs->rADCCON)); // Check ECFLG
// ybuf[i] = 0x3ff - (0x3ff & v_pADCregs->rADCDAT0);
ybuf[i] = 0x3ff & v_pADCregs->rADCDAT0;
xbuf[i] = 0x3ff & v_pADCregs->rADCDAT1;
}
PddpTouchPanelEvaluateSamples( &TmpStateFlags, &TmpX, &TmpY);
v_pADCregs->rADCTSC=(1<<8)|(1<<7)|(1<<6)|(0<<5)|(1<<4)|(0<<3)|(0<<2)|(3);
Touch_CoordinateConversion(&TmpX, &TmpY);
if (Touch_Pen_filtering(&TmpX, &TmpY)) // Valid touch pen
{
//RETAILMSG(1, (TEXT("valid touch pen\r\n")));
*pTipStateFlags = TouchSampleValidFlag | TouchSampleDownFlag;
*pTipStateFlags &= ~TouchSampleIgnore;
}
else // Invalid touch pen
{
//RETAILMSG(1, (TEXT("invalid touch pen\r\n")));
*pTipStateFlags = TouchSampleValidFlag;
*pTipStateFlags |= TouchSampleIgnore;
}
*pUncalX = PrevX = TmpX;
*pUncalY = PrevY = TmpY;
InterruptDone( gIntrTouch );
RETAILMSG(0, (TEXT("0 - (%d, %d) 0x%X\r\n"), *pUncalX, *pUncalY, *pTipStateFlags));
}
}
return;
}
#define FILTER_LIMIT 25
static BOOL
Touch_Pen_filtering(INT *px, INT *py)
{
BOOL RetVal = TRUE;
// TRUE : Valid pen sample
// FALSE : Invalid pen sample
static int count = 0;
static INT x[2], y[2];
INT TmpX, TmpY;
INT dx, dy;
count++;
if (count > 2)
{ // apply filtering rule
count = 2;
// average between x,y[0] and *px,y
TmpX = (x[0] + *px) / 2;
TmpY = (y[0] + *py) / 2;
// difference between x,y[1] and TmpX,Y
dx = (x[1] > TmpX) ? (x[1] - TmpX) : (TmpX - x[1]);
dy = (y[1] > TmpY) ? (y[1] - TmpY) : (TmpY - y[1]);
if ((dx > FILTER_LIMIT) || (dy > FILTER_LIMIT)) {
// Invalid pen sample
*px = x[1];
*py = y[1]; // previous valid sample
RetVal = FALSE;
count = 0;
}
else
{
// Valid pen sample
x[0] = x[1]; y[0] = y[1];
x[1] = *px; y[1] = *py; // reserve pen samples
RetVal = TRUE;
//RETAILMSG(1, (TEXT("RetVal = TRUE\r\n")));
}
} else { // till 2 samples, no filtering rule
x[0] = x[1]; y[0] = y[1];
x[1] = *px; y[1] = *py; // reserve pen samples
RetVal = FALSE; // <- TRUE jylee 2003.03.04
}
//if (RetVal==FALSE) {
//}
return RetVal;
}
/*++
@func VOID | DdsiTouchPanelPowerHandler |
System power state notification.
@parm BOOL | bOff | TRUE, the system is powering off; FALSE, the system is powering up.
@comm
This routine is called in a kernel context and may not make any system
calls whatsoever. It may read and write its own memory and that's about
it. This routine is called by the MDD and also serves as an internal
helper routine for touch enable/disable.
@devnote This routine will run in kernel context, and may not make
any system calls. If you can any subroutines inside here, make sure
that they also follow this restriction.
--*/
void
DdsiTouchPanelPowerHandler(
BOOL bOff
)
{
// USHORT mask;
// Set flag so we know to avoid system calls
bInPowerHandler = TRUE;
if (bOff) {
TouchPanelPowerOff();
}
else {
TouchPanelPowerOn();
PddpSetupPenDownIntr(TRUE);
}
bInPowerHandler = FALSE;
}
static void
TouchPanelPowerOff()
{
// Powering down, stop DMA and power off touch screen
RETAILMSG(0,(TEXT("Touch Power Off\r\n")));
}
static void
TouchPanelPowerOn()
{
DWORD tmp = 0;
RETAILMSG(1,(TEXT("Touch Init\r\n")));
//
// Setup GPIOs for touch
//
// Clear GPG15, 14, 13, 12
v_pIOPregs->rGPGCON &= ~((0x03 << 30)|(0x03 << 28)|(0x03 << 26)|(0x03 << 24));
// Set GPG15 to use as nYPON, GPG14 to use as YMON, GPG13 to use as nXPON, GPG12 to use as XMON
v_pIOPregs->rGPGCON |= ((0x01 << 30)|(0x01 << 28)|(0x01 << 26)|(0x01 << 24));
// Disable full up function
v_pIOPregs->rGPGUP |= ((0x01 << 15)|(0x01 << 14)|(0x01 << 13)|(0x01 << 12));
//
// Setup ADC register
//
// Down Int, YMON:0, nYPON:1, XMON:0;nXPON:1, Pullup:1, Auto Conv.,Waiting.
v_pADCregs->rADCTSC = (0<<8)|(1<<7)|(1<<6)|(0<<5)|(1<<4)|(0<<3)|(0<<2)|(3);
//v_pADCregs->rADCTSC=(1<<3)|(1<<2);
v_pADCregs->rADCDLY = ADC_DELAY_TIME;//default value for delay.
v_pADCregs->rADCCON = (1<<14)|(ADCPRS<<6)|(7<<3); //setup channel, ADCPRS, Touch Input
/*
RETAILMSG(1, (TEXT("v_pIOPregs->rGPBCON = 0x%X\r\n"), v_pIOPregs->rGPBCON));
RETAILMSG(1, (TEXT("v_pIOPregs->rGPBDAT = 0x%X\r\n"), v_pIOPregs->rGPBDAT));
RETAILMSG(1, (TEXT("v_pIOPregs->rGPBUP = 0x%X\r\n"), v_pIOPregs->rGPBUP));
RETAILMSG(1, (TEXT("S2440PCLK = %d\r\n"), S2440PCLK));
RETAILMSG(1, (TEXT("v_pPWMregs->rTCFG0 = 0x%X\r\n"), v_pPWMregs->rTCFG0));
RETAILMSG(1, (TEXT("v_pPWMregs->rTCFG1 = 0x%X\r\n"), v_pPWMregs->rTCFG1));
RETAILMSG(1, (TEXT("v_pPWMregs->rTCON = 0x%X\r\n"), v_pPWMregs->rTCON));
RETAILMSG(1, (TEXT("v_pPWMregs->rTCNTB0 = 0x%X\r\n"), v_pPWMregs->rTCNTB0));
RETAILMSG(1, (TEXT("v_pPWMregs->rTCMPB0 = 0x%X\r\n"), v_pPWMregs->rTCMPB0));
RETAILMSG(1, (TEXT("v_pPWMregs->rTCNTO0 = 0x%X\r\n"), v_pPWMregs->rTCNTO0));
RETAILMSG(1, (TEXT("v_pPWMregs->rTCNTB1 = 0x%X\r\n"), v_pPWMregs->rTCNTB1));
RETAILMSG(1, (TEXT("v_pPWMregs->rTCMPB1 = 0x%X\r\n"), v_pPWMregs->rTCMPB1));
RETAILMSG(1, (TEXT("v_pPWMregs->rTCNTO1 = 0x%X\r\n"), v_pPWMregs->rTCNTO1));
RETAILMSG(1, (TEXT("v_pPWMregs->rTCNTB2 = 0x%X\r\n"), v_pPWMregs->rTCNTB2));
RETAILMSG(1, (TEXT("v_pPWMregs->rTCMPB2 = 0x%X\r\n"), v_pPWMregs->rTCMPB2));
RETAILMSG(1, (TEXT("v_pPWMregs->rTCNTO2 = 0x%X\r\n"), v_pPWMregs->rTCNTO2));
RETAILMSG(1, (TEXT("v_pPWMregs->rTCNTB3 = 0x%X\r\n"), v_pPWMregs->rTCNTB3));
RETAILMSG(1, (TEXT("v_pPWMregs->rTCMPB3 = 0x%X\r\n"), v_pPWMregs->rTCMPB3));
RETAILMSG(1, (TEXT("v_pPWMregs->rTCNTO3 = 0x%X\r\n"), v_pPWMregs->rTCNTO3));
RETAILMSG(1, (TEXT("v_pPWMregs->rTCNTB4 = 0x%X\r\n"), v_pPWMregs->rTCNTB4));
RETAILMSG(1, (TEXT("v_pPWMregs->rTCNTO4 = 0x%X\r\n"), v_pPWMregs->rTCNTO4));
*/
return ;
}
static BOOL Touch_Timer0_Setup(void) {
unsigned int TmpTCON;
//
// We use Timer1 of PWM as OS Clock.
// Disable Timer1 Init..
v_pINTregs->rINTMSK |= BIT_TIMER1; // Mask timer1 interrupt.
v_pINTregs->rSRCPND = BIT_TIMER1; // Clear pending bit
v_pINTregs->rINTPND = BIT_TIMER1;
//we operate our board with PCLK=203M/4 = 50750000Hz (50.75 Mhz)
v_pPWMregs->rTCFG0 &= ~(0xff); /* Prescaler 1's Value */
v_pPWMregs->rTCFG0 |= (PRESCALER); // prescaler value = 24 + 1
v_pPWMregs->rTCFG1 &= ~(0xf<<4);
#if( SYS_TIMER_DIVIDER == 2 )
v_pPWMregs->rTCFG1 |= (0 << 4); /* 1/2 */
#elif ( SYS_TIMER_DIVIDER == 4 )
v_pPWMregs->rTCFG1 |= (1 << 4); /* 1/4 */
#elif ( SYS_TIMER_DIVIDER == 8 )
v_pPWMregs->rTCFG1 |= (2 << 4); /* 1/8 */
#elif ( SYS_TIMER_DIVIDER == 16 )
v_pPWMregs->rTCFG1 |= (3 << 4); /* 1/16 */
#endif
// v_pPWMregs->rTCNTB1 = 1000; // about 10 ms(203M/4/2/(255+1))=10ms
v_pPWMregs->rTCNTB1 = (10 * (S2440PCLK / (PRESCALER+1) / SYS_TIMER_DIVIDER)) / 1000; // 10msec, Charlie
v_pPWMregs->rTCMPB1 = 0;
TmpTCON = v_pPWMregs->rTCON; // get TCON value to temp TCON register
TmpTCON &= ~0xf00; // clear fields of Timer 1
TmpTCON |= 0x200; // interval mode(auto reload), update TCVNTB4, stop
v_pPWMregs->rTCON = TmpTCON; // put the value to TCON register
TmpTCON = v_pPWMregs->rTCON; // get TCON value to temp TCON register
TmpTCON &= ~0xf00; // clear fields of Timer 1
TmpTCON |= 0x100; // interval mode, no operation, start for Timer 4
v_pPWMregs->rTCON = TmpTCON; // put the value to TCON register
v_pINTregs->rINTMSK &= ~BIT_TIMER1;
return TRUE;
}
?? 快捷鍵說明
復(fù)制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -