📄 toucher_modify_from_samsung.c
字号:
/***************************************************
Copyright(c) 版权所有,1998-2003微逻辑。保留所有权利。
***************************************************/
/*****************************************************
文件说明:触摸屏驱动程序
版本号:1.0.0
开发时期:2003-12-01
作者:AlexZeng
修改记录:
******************************************************/
#include "ewindows.h"
#include <oalintr.h>
#include <s2410.h>
#include <touch.h>
#include <drv_glob.h>
#include <reg.h>
#include <tchpdd.h>
const UINT uMinCalCount = 25;
const UINT idTouchIrq = SYSINTR_TOUCH;
const UINT idTouchChangedIrq = SYSINTR_TOUCH_CHANGED;
static volatile IOPreg * const v_pIOPregs = (volatile IOPreg *)IOP_BASE;
static volatile ADCreg * const v_pADCregs = (volatile ADCreg *)ADC_BASE;
static volatile PWMreg * const v_pPWMregs = (volatile PWMreg *)PWM_BASE;
static volatile INTreg * const v_pINTregs = (volatile INTreg *)INT_BASE;
static volatile PDRIVER_GLOBALS const v_pDriverGlobals = (PDRIVER_GLOBALS)DRIVER_GLOBALS_PHYSICAL_MEMORY_SIZE;
static void TouchPanelPowerOn( void );
static void TouchPanelPowerOff( void );
// Global flag to indicate whether we are in power handler routine, so
// we know to avoid system calls.
static BOOL bInPowerHandler = FALSE;
static volatile unsigned short xbuf[10], ybuf[10];
#define TOUCH_TIMER_PRESCALER 24
#define TOUCH_TIMER_DIVIDER 4
#define JYLEE_TEST 1
#define TFT240_320 1
#define TFT640_480 4
#define LCD_TYPE TFT240_320 //TFT640_480
#define MAX_ADVAL 1020
#if ( LCD_TYPE == TFT640_480 )
#define ADC_DELAY_TIME 5000 // charlie, 020620
#else
//lilin
// #define ADC_DELAY_TIME 1000 // Charlie
#define ADC_DELAY_TIME 0xff // Charlie
#endif
//#define ADCPRS 49
//lilin
#define ADCPRS 49
#define DELAY 1000
#define SDELAY 5
#define FILTER_LIMIT 25
#define INT int
//
// PDD Internal Support Routines
//
/*++
@doc IN_TOUCH_DDSI INTERNAL DRIVERS PDD TOUCH_PANEL
@func VOID | PddpTouchPanelGetSamples |
Copies from the pen dma area the most recent point sample into the location
pointed to by pPointSamples. During the copy the sample information is
adjusted to be consistent with the 12 bit pen data format.
Has the side effect of reinitializing ioPenPointer if we are near the
end of the pen sample area.
--*/
static
void
PddpTouchPanelGetSamples(
PTOUCHPANEL_POINT_SAMPLE pPointSamples //@PARM Pointer to where the samples will be stored.
)
{
// ULONG devDrvPointer;
ULONG irg;
//
// Copy the samples to our buffer munging the data for the 12 bit
// pen data format.
//
for ( irg = 0; irg < NUMBER_SAMPLES_PER_POINT; irg++ )
{
pPointSamples[ irg ].XSample = xbuf[irg];
pPointSamples[ irg ].YSample = ybuf[irg];
}
}
/*++
Routine Description:
Gathers the most recent sample and evaluates the sample returing
the determined tip state and the `best guess' for the X and Y coordinates.
Note: Determined empirically that the variance of the X coordinate of the
first sample from all other samples is large enough that in order
to keep the nominal variance small, we discard the first sample.
Cases of a light touch that locks the ADC into
seeing X and Y coordinate samples of 0x277 regardless of how the pen
moves or presses have been seen. XXXXX
Arguments:
pTipState Pointer to where the tip state information will be returned.
pUnCalX Pointer to where the x coordinate will be returned.
pUnCalY Pointer to where the y coordinate will be returned.
Return Value:
None.
Autodoc Information:
@doc IN_TOUCH_DDI INTERNAL DRIVERS PDD TOUCH_PANEL
@func VOID | PddpTouchPanelEvaluateSamples |
Gathers the most recent sample and evaluates the sample returing
the determined tip state and the `best guess' for the X and Y coordinates.
--*/
#define ZONE_SAMPLES 0
static void
PddpTouchPanelEvaluateSamples(
DWORD *pSampleFlags, //@PARM Pointer to where the tip state information will be returned.
INT *pUncalX, //@PARM Pointer to where the x coordinate will be returned.
INT *pUncalY //@PARM Pointer to where the y coordinate will be returned.
)
{
LONG dlXDiff0;
LONG dlXDiff1;
LONG dlXDiff2;
LONG dlYDiff0;
LONG dlYDiff1;
LONG dlYDiff2;
TOUCHPANEL_POINT_SAMPLES rgPointSamples;
//
// Get the sample.
//
PddpTouchPanelGetSamples( rgPointSamples );
//
// Calcuate the differences for the X samples and insure that
// the resulting number is positive.
//
dlXDiff0 = rgPointSamples[ 0 ].XSample - rgPointSamples[ 1 ].XSample;
dlXDiff1 = rgPointSamples[ 1 ].XSample - rgPointSamples[ 2 ].XSample;
dlXDiff2 = rgPointSamples[ 2 ].XSample - rgPointSamples[ 0 ].XSample;
dlXDiff0 = dlXDiff0 > 0 ? dlXDiff0 : -dlXDiff0;
dlXDiff1 = dlXDiff1 > 0 ? dlXDiff1 : -dlXDiff1;
dlXDiff2 = dlXDiff2 > 0 ? dlXDiff2 : -dlXDiff2;
//
// Calcuate the differences for the Y samples and insure that
// the resulting number is positive.
//
dlYDiff0 = rgPointSamples[ 0 ].YSample - rgPointSamples[ 1 ].YSample;
dlYDiff1 = rgPointSamples[ 1 ].YSample - rgPointSamples[ 2 ].YSample;
dlYDiff2 = rgPointSamples[ 2 ].YSample - rgPointSamples[ 0 ].YSample;
dlYDiff0 = dlYDiff0 > 0 ? dlYDiff0 : -dlYDiff0;
dlYDiff1 = dlYDiff1 > 0 ? dlYDiff1 : -dlYDiff1;
dlYDiff2 = dlYDiff2 > 0 ? dlYDiff2 : -dlYDiff2;
//
// The final X coordinate is the average of coordinates of
// the two MIN of the differences.
//
if ( dlXDiff0 < dlXDiff1 )
{
if ( dlXDiff2 < dlXDiff0 )
{
*pUncalX = (ULONG)( ( ( rgPointSamples[ 0 ].XSample + rgPointSamples[ 2 ].XSample ) >> 1 ) );
}
else
{
*pUncalX = (ULONG)( ( ( rgPointSamples[ 0 ].XSample + rgPointSamples[ 1 ].XSample ) >> 1 ) );
}
}
else if ( dlXDiff2 < dlXDiff1 )
{
*pUncalX = (ULONG)( ( ( rgPointSamples[ 0 ].XSample + rgPointSamples[ 2 ].XSample ) >> 1 ) );
}
else
{
*pUncalX = (ULONG)( ( ( rgPointSamples[ 1 ].XSample + rgPointSamples[ 2 ].XSample ) >> 1 ) );
}
//
//
// The final Y coordinate is the average of coordinates of
// the two MIN of the differences.
//
if ( dlYDiff0 < dlYDiff1 )
{
if ( dlYDiff2 < dlYDiff0 )
{
*pUncalY = (ULONG)( ( ( rgPointSamples[ 0 ].YSample + rgPointSamples[ 2 ].YSample ) >> 1 ) );
}
else
{
*pUncalY = (ULONG)( ( ( rgPointSamples[ 0 ].YSample + rgPointSamples[ 1 ].YSample ) >> 1 ) );
}
}
else if ( dlYDiff2 < dlYDiff1 )
{
*pUncalY = (ULONG)( ( ( rgPointSamples[ 0 ].YSample + rgPointSamples[ 2 ].YSample ) >> 1 ) );
}
else
{
*pUncalY = (ULONG)( ( ( rgPointSamples[ 1 ].YSample + rgPointSamples[ 2 ].YSample ) >> 1 ) );
}
//
// Validate the coordinates and set the tip state accordingly.
//
if ( dlXDiff0 > DELTA_X_COORD_VARIANCE ||
dlXDiff1 > DELTA_X_COORD_VARIANCE ||
dlXDiff2 > DELTA_X_COORD_VARIANCE ||
dlYDiff0 > DELTA_Y_COORD_VARIANCE ||
dlYDiff1 > DELTA_Y_COORD_VARIANCE ||
dlYDiff2 > DELTA_Y_COORD_VARIANCE )
{
//#ifdef DBGPOINTS1
DEBUGMSG( ZONE_SAMPLES, (TEXT("Sample 0: X 0x%x Y 0x%x\r\n"),
rgPointSamples[ 0 ].XSample, rgPointSamples[ 0 ].YSample) );
DEBUGMSG( ZONE_SAMPLES, (TEXT("Sample 1: X 0x%x Y 0x%x\r\n"),
rgPointSamples[ 1 ].XSample, rgPointSamples[ 1 ].YSample) );
DEBUGMSG( ZONE_SAMPLES, (TEXT("Sample 2: X 0x%x Y 0x%x\r\n"),
rgPointSamples[ 2 ].XSample, rgPointSamples[ 2 ].YSample) );
if ( dlXDiff0 > DELTA_X_COORD_VARIANCE )
DEBUGMSG( ZONE_SAMPLES, (TEXT("XDiff0 too large 0x%x\r\n"), dlXDiff0) );
if ( dlXDiff1 > DELTA_X_COORD_VARIANCE )
DEBUGMSG( ZONE_SAMPLES, (TEXT("XDiff1 too large 0x%x\r\n"), dlXDiff1) );
if ( dlXDiff2 > DELTA_X_COORD_VARIANCE )
DEBUGMSG( ZONE_SAMPLES, (TEXT("XDiff2 too large 0x%x\r\n"), dlXDiff2) );
if ( dlYDiff0 > DELTA_Y_COORD_VARIANCE )
DEBUGMSG( ZONE_SAMPLES, (TEXT("YDiff0 too large 0x%x\r\n"), dlYDiff0) );
if ( dlYDiff1 > DELTA_Y_COORD_VARIANCE )
DEBUGMSG( ZONE_SAMPLES, (TEXT("YDiff1 too large 0x%x\r\n"), dlYDiff1) );
if ( dlYDiff2 > DELTA_Y_COORD_VARIANCE )
DEBUGMSG( ZONE_SAMPLES, (TEXT("YDiff2 too large 0x%x\r\n"), dlYDiff2) );
//#endif // DBGPOINTS1
}
else
{
//
// Sample is valid. Set tip state accordingly.
//
*pSampleFlags = SAMPLE_VALID | SAMPLE_DOWN;//TouchSampleValidFlag | TouchSampleDownFlag;
}
DEBUGMSG( ZONE_SAMPLES, (TEXT("Filtered - SampleFlags: 0x%x X: 0x%x Y: 0x%x\r\n"),
*pSampleFlags, *pUncalX, *pUncalY) );
}
// **************************************************
// 申明:static BOOL Touch_Pen_filtering(INT *px, INT *py)
// 参数:
// INT px -
// INT py
// 返回值:
// TRUE/FALSE 创建(成功/失败)
// 功能描述:
// 检查x,y的有效性
// 引用:
// **************************************************
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;
}
//
// PddpSetupPenDownIntr()
//
// Set up the UCB to give pen down interrupts. If EnableIntr flag is set, enable
// the interrupt, otherwise, leave it disabled. Note: - Caller must hold semaphore
// when this function is called to protect access to the shared UCB registers.
//
static BOOL PddpSetupPenDownIntr(BOOL EnableIntr)
{
// USHORT intrMask;
// I don't know why we enable the interrupt here.
//
// Setup ADC register
//
// kang code
// Enable Prescaler,Prescaler,AIN5/7 fix,Normal,Disable read start,No operation
// Down,YM:GND,YP:AIN5,XM:Hi-z,XP:AIN7,XP pullup En,Normal,Waiting for interrupt mode
// kang code end
// Down Int, YMON:0, nYPON:1, XMON:0;nXPON:1, Pullup:1, Auto Conv.,Waiting.
// xp_ain=(1 << 4)
// YP_AIN = (1 << 6)
// YM_GND= (1 << 7)
// v_pADCregs->rADCTSC =(0<<8)|(1<<7)|(1<<6)|(0<<5)|(1<<4)|(0<<3)|(0<<2)|(3);
// v_pADCregs->rADCTSC =(0<<8)|(1<<7)|(1<<6)|(0<<5)|(1<<4)|(0<<3)|(0<<2)|(3);
v_pADCregs->rADCTSC =(0<<8)|(1<<7)|(1<<6)|(0<<5)|(0<<4)|(0<<3)|(0<<2)|(3);
// v_pADCregs->rADCTSC=(1 << 5) | (1 << 6) | (1 << 3);
v_pADCregs->rADCDLY = ADC_DELAY_TIME;//default value for delay.
// v_pADCregs->rADCCON = (1<<14)|(ADCPRS<<6)|(7<<3); //setup channel, ADCPRS, Touch Input
v_pADCregs->rADCCON = (1<<14)|(ADCPRS<<6)|(2<<3); //setup channel, ADCPRS, Touch Input
// v_pADCregs->rADCCON = (1<<14)|(ADCPRS<<6)|(0<<3); //setup channel, ADCPRS, Touch Input
return TRUE;
}
// **************************************************
// 申明:void TouchPanelPowerOn( void )
// 参数:
// 无
// 返回值:
// TRUE/FALSE (成功/失败)
// 功能描述:
// 加电操作/使Touch可以工作
// 引用:
// ************************************************
static void TouchPanelPowerOn( void )
{
DWORD tmp = 0;
RETAILMSG(1,(TEXT("TouchPanelPowerOn entry.\r\n")));
//
// Setup GPIOs for touch
//
// Clear GPG15, 14, 13, 12
v_pIOPregs->rGPGCON &= ~((0x03 << 30)|(0x03 << 28)|(0x03 << 26)|(0x03 << 24));
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -