tchpdd.cpp
来自「S3C24A0的完整BSP包,对开发此芯片的开发者很有用.」· C++ 代码 · 共 1,273 行 · 第 1/3 页
CPP
1,273 行
// Implemented in the PDD.
//
LONG
DdsiTouchPanelAttach(
VOID
)
{
RETAILMSG(TCHPDD_TEST,(_T("TOUCHP::DdsiTouchPanelAttach\r\n")));
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
)
{
RETAILMSG(TCHPDD_TEST,(_T("TOUCHP::DdsiTouchPanelDetach\r\n")));
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 1000
#define TOUCH_MIN_X 30
#define TOUCH_MAX_Y 980
#define TOUCH_MIN_Y 30
#define TOUCH_X 640
#define TOUCH_Y 480
#else
#if (S3C24A0A)
#define TOUCH_MAX_X 890 //955 //950
#define TOUCH_MIN_X 120 //100 //90
#define TOUCH_MAX_Y 890 //925 //960
#define TOUCH_MIN_Y 90 //70 //50
#define TOUCH_X 240
#define TOUCH_Y 320
#else
#define TOUCH_MAX_X 890 //955 //950
#define TOUCH_MIN_X 130 //100 //90
#define TOUCH_MAX_Y 920 //925 //960
#define TOUCH_MIN_Y 140 //70 //50
#define TOUCH_X 240
#define TOUCH_Y 320
#endif
#endif
#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) : *px;
TmpY = (*py >= TOUCH_MAX_Y) ? (TOUCH_MAX_Y) : *py;
TmpX -= TOUCH_MIN_X;
TmpY -= TOUCH_MIN_Y;
TmpX = (TmpX) ? TmpX : 0;
TmpY = (TmpY) ? TmpY : 0;
#if (!S3C24A0A)
*px = (TOUCH_X - (TmpX * TOUCH_X) / (TOUCH_MAX_X-TOUCH_MIN_X))*4;
*py = ((TmpY * TOUCH_Y) / (TOUCH_MAX_Y-TOUCH_MIN_Y))*4;
#else
*px = (TOUCH_X - (TmpX * TOUCH_X) / (TOUCH_MAX_X-TOUCH_MIN_X))*4;
*py = ((TmpY * TOUCH_Y) / (TOUCH_MAX_Y-TOUCH_MIN_Y))*4;
#endif
*px = (*px >= TOUCH_X*4)? (TOUCH_X*4 - 1) : *px;
*py = (*py >= TOUCH_Y*4)? (TOUCH_Y*4 - 1) : *py;
#if (TCHPDD_TEST)
RETAILMSG(1, (TEXT("first *px,y = (%d, %d)\r\n"), TmpX0, TmpY0));
RETAILMSG(1, (TEXT("TOUCH_MAX_X : %d\r\n"), TOUCH_MAX_X));
RETAILMSG(1, (TEXT("TOUCH_MAX_Y : %d\r\n"), TOUCH_MAX_Y));
RETAILMSG(1, (TEXT("TOUCH_MIN_X : %d\r\n"), TOUCH_MIN_X));
RETAILMSG(1, (TEXT("TOUCH_MIN_Y : %d\r\n"), TOUCH_MIN_Y));
RETAILMSG(1, (TEXT("TOUCH_X : %d\r\n"), TOUCH_X));
RETAILMSG(1, (TEXT("TOUCH_Y : %d\r\n"), TOUCH_Y));
RETAILMSG(1, (TEXT("last *px,y = (%d, %d)\r\n"), *px, *py));
#endif
return;
}
VOID
DdsiTouchPanelGetPoint(
TOUCH_PANEL_SAMPLE_FLAGS *pTipStateFlags,
INT *pUncalX,
INT *pUncalY
)
{
ULONG status;
// USHORT ioAdcCntr, 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;
static int i = 0;
RETAILMSG(TCHPDD_TEST,(_T("DdsiTouchPanelGetPoint\r\n")));
// Read the status passed back by the HAL
// status = READ_REGISTER_ULONG( &(v_pDriverGlobals->tch.status) );
status = v_pDriverGlobals->tch.status;
i++;
RETAILMSG(TCHPDD_TEST,(_T("TCHPDD::0x%X - %d\r\n"), i, i));
if(status == TOUCH_PEN_UP) {
RETAILMSG(TCHPDD_TEST,(_T("status = TOUHC_PEN_UP\r\n")));
*pTipStateFlags = TouchSampleValidFlag;
*pUncalX = PrevX;
*pUncalY = PrevY;
InterruptDone( gIntrTouchChanged );
}
else if(status == TOUCH_PEN_DOWN) {
RETAILMSG(TCHPDD_TEST,(_T("status = TOUHC_PEN_DOWN\r\n")));
*pTipStateFlags |= TouchSampleIgnore;
*pUncalX = PrevX;
*pUncalY = PrevY;
// now start timer1 (oneshot)
Touch_Timer0_Setup();
InterruptDone( gIntrTouchChanged );
} else {
RETAILMSG(TCHPDD_TEST,(_T("status etc -> get touch sample\r\n")));
if ( (v_pADCregs->ADCDAX & 0x8000) || (v_pADCregs->ADCDAY & 0x8000) )
{
v_pADCregs->ADCTSC = 0xD3; // Set stylus down interrupt
*pTipStateFlags = TouchSampleValidFlag;
*pUncalX = PrevX;
*pUncalY = PrevY;
InterruptDone( gIntrTouchChanged );
}
else {
// <Auto X-Position and Y-Position Read>
for (i =0; i < NUMBER_SAMPLES_PER_POINT; i++) {
v_pADCregs->ADCTSC = (0<<8)|(13<<4)|(1<<3)|(1<<2)|(0);
v_pADCregs->ADCCON |= 0x1; // Start Auto conversion
while(v_pADCregs->ADCCON & 0x1); //check if Enable_start is low
while(!(0x8000&(v_pADCregs->ADCCON))); // Check ECFLG
#if (!S3C24A0A)
xbuf[i] = 0x3ff & v_pADCregs->ADCDAX;
ybuf[i] = 0x3ff & v_pADCregs->ADCDAY;
#else
xbuf[i] = 0x3ff & v_pADCregs->ADCDAX;
ybuf[i] = 0x3ff & v_pADCregs->ADCDAY;
#endif
}
v_pADCregs->ADCTSC=(0<<8)|(13<<4)|(0<<3)|(0<<2)|1;//for returning to X-position....
PddpTouchPanelEvaluateSamples( &TmpStateFlags, &TmpX, &TmpY);
v_pADCregs->ADCTSC = 0xd3; //for waiting interruupt
Touch_CoordinateConversion(&TmpX, &TmpY);
if (Touch_Pen_filtering(&TmpX, &TmpY)) // Valid touch pen
{
RETAILMSG(TCHPDD_TEST, (TEXT("valid touch pen\r\n")));
*pTipStateFlags = TouchSampleValidFlag | TouchSampleDownFlag;
*pTipStateFlags &= ~TouchSampleIgnore;
}
else // Invalid touch pen
{
RETAILMSG(TCHPDD_TEST, (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;
}
} 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
}
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
)
{
RETAILMSG(1,(_T("DdsiTouchPanelPowerHandler\r\n")));
// 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(1,(TEXT("Touch Power Off\r\n")));
}
static void
TouchPanelPowerOn()
{
DWORD tmp = 0;
//
// Setup ADC register
//
RETAILMSG(1,(TEXT("Touch Power On\r\n")));
// Down Int, YMON:1, nYPON:1, XMON:0;nXPON:1, Pullup:1, Auto Conv.,Waiting.
// XP pullup En,Normal,Waiting for interrupt mode
// v_pADCregs->ADCTSC = (0<<8)|(13<<4)|(0<<3)|(0<<2)|(3);
v_pADCregs->ADCDLY = ADC_DELAY_TIME; //default value for delay.
// v_pADCregs->ADCCON = (1<<14)|(ADCPRS<<6)|(0<<3)|(0<<2)|(0<<1)|0;
v_pADCregs->ADCCON = (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->ADCTSC = (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
RETAILMSG(1,(TEXT("Touch Init.. done\r\n")));
return ;
}
static BOOL Touch_Timer0_Setup(void)
{
unsigned int TmpTCON;
//
// We use Timer1 of PWM as OS Clock.
RETAILMSG(TCHPDD_TEST,(TEXT("Touch_Timer0_Setup\r\n")));
// Disable Timer1 Init..
v_pINTregs->INTMSK |= BIT_TIMER1; // Mask timer1 interrupt.
v_pINTregs->SRCPND = BIT_TIMER1; // Clear pending bit
v_pINTregs->INTPND = BIT_TIMER1;
v_pPWMregs->TCFG0 = (v_pPWMregs->TCFG0 & ~(0xff)) | (TOUCH_TIMER_PRESCALER);
// prescaler value = 24 + 1
v_pPWMregs->TCFG1 &= ~(0xf0);
#if( TOUCH_TIMER_DIVIDER == 2 )
v_pPWMregs->TCFG1 |= (0 << 4); /* 1/2 */
#elif ( TOUCH_TIMER_DIVIDER == 4 )
v_pPWMregs->TCFG1 |= (1 << 4); /* 1/4 */
#elif ( TOUCH_TIMER_DIVIDER == 8 )
v_pPWMregs->TCFG1 |= (2 << 4); /* 1/8 */
#elif ( TOUCH_TIMER_DIVIDER == 16 )
v_pPWMregs->TCFG1 |= (3 << 4); /* 1/16 */
#endif
v_pPWMregs->TCNTB1 = (10 * (S3C24A0_PCLK / (TOUCH_TIMER_PRESCALER+1) / TOUCH_TIMER_DIVIDER)) / 1000;
RETAILMSG(0,(_T("TCHPDD::TIMER1 COUNT VALUE=%d\r\n"), v_pPWMregs->TCNTB1));
v_pPWMregs->TCMPB1 = 0;
TmpTCON = v_pPWMregs->TCON; // get TCON value to temp TCON register
v_pPWMregs->TCON = (TmpTCON & ~(0xf00)) | (0x200); // stop, one-shot, inverter off, TCNTB1 update
v_pPWMregs->TCON = (TmpTCON & ~(0xf00)) | (0x100); // start
v_pINTregs->INTMSK &= ~BIT_TIMER1;
return TRUE;
}
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?