📄 tchpdd.cpp
字号:
//
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.
//
#if ( LCD_TYPE == TFT640_480 )
#define TOUCH_MAX_X 890
#define TOUCH_MIN_X 125
#define TOUCH_MAX_Y 860
#define TOUCH_MIN_Y 140
#define TOUCH_X 640
#define TOUCH_Y 480
#else
#define TOUCH_MAX_X 900 // 950
#define TOUCH_MIN_X 100 // 90
#define TOUCH_MAX_Y 920 // 960 // 910
#define TOUCH_MIN_Y 100 // 70 //50
#define TOUCH_X 240
#define TOUCH_Y 320
#endif
#define TOUCH_ERR 50
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);
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;
v_pIOPregs->rGPGCON &= ~((0x3 << 16));
v_pIOPregs->rGPGCON |= ((0x2 << 16)); /* External Interrupt #16 Enable */
v_pIOPregs->rEXTINT2 &= ~(0x7 << 8); // Configure EINT18 as Both Edge Mode
v_pIOPregs->rEXTINT2 |= (0x7 << 8);
v_pIOPregs->rEINTPEND = (1 << 16);
v_pIOPregs->rEINTMASK &= ~(1 << 16);
RETAILMSG(1,(TEXT("SDMMC config set rGPGCON: %x\r\n"), v_pIOPregs->rGPGCON));
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;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -