不好意思,不晓得怎么实现驱动下打印触摸笔的坐标。
附上touchp.cpp代码:
/*++
THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF
ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO
THE IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A
PARTICULAR PURPOSE.
Copyright (c) 2002. Samsung Electronics, co. ltd All rights reserved.
Module Name:
tchpdd.cpp
Abstract:
This module contains the DDSI implementation and PDD support routines
for the touch panel for the P2 implementation.
static BOOL Touch_Pen_filtering(INT *px, INT *py);
// The MDD requires a minimum of MIN_CAL_COUNT consecutive samples before
// it will return a calibration coordinate to GWE. This value is defined
// in the PDD so that each OEM can control the behaviour of the touch
// panel and still use the Microsoft supplied MDD. Note that the extern "C"
// is required so that the variable name doesn't get decorated, and
// since we have an initializer the 'extern' is actually ignored and
// space is allocated.
extern "C" const int MIN_CAL_COUNT = 40;
INT CurrentSampleRateSetting = 0; // Low sample rate setting
// @globalvar PTCHAUD_ASIC_REGISTERS | v_pTchAudAsicRegisters | Pointer to Asic regs
// @globalvar PTOUCHPANEL_POINT_SAMPLE | v_pPenSamples | Pointer to pen samples area
PDRIVER_GLOBALS v_pDriverGlobals = NULL;
volatile static PVOID v_pCpuRegs = NULL;
TOUCH_PANEL_SAMPLE_FLAGS SampleFlags;
#ifdef CHECK_RATE
UINT32 tmp_leds = 0x55;
#endif
// Mutex to prevent contention with audio while accessing shared registers
static HANDLE v_hTchAudMutex;
// Global flag to indicate whether we are in power handler routine, so
// we know to avoid system calls.
static BOOL bInPowerHandler = FALSE;
// Macros for aquiring semaphore for shared access to ASIC registers. If
// we are in the power handler routines, we don't need/want to aquire semaphore,
// since we are serialized at that point, and can't make any system calls.
#define TCHAUD_SEM_LOCK() \
if (!bInPowerHandler) { \
DEBUGMSG(ZONE_TIPSTATE,(TEXT("TchPDD Getting semaphore...\r\n"))); \
TchAudLock(v_hTchAudMutex, &(v_pDriverGlobals->tch.semaphore)); \
}
#define TCHAUD_SEM_UNLOCK() \
if (!bInPowerHandler) { \
DEBUGMSG(ZONE_TIPSTATE,(TEXT("TchPDD Releasing semaphore...\r\n"))); \
TchAudUnlock(v_hTchAudMutex, &(v_pDriverGlobals->tch.semaphore)); \
}
// Macros for accessing registers on the touch audio ASIC. The code for
// these functions is in drvlib so it can be shared between touch and audio.
#define ASIC_READ_REG(reg, pval) \
TchAudReadReg(reg, pval, v_pTchAudAsicRegisters, bInPowerHandler)
#define ASIC_WRITE_REG(reg, val) \
TchAudWriteReg(reg, val, v_pTchAudAsicRegisters, bInPowerHandler)
#define ASIC_AND_REG(reg, val) \
TchAudAndReg(reg, val, v_pTchAudAsicRegisters, bInPowerHandler)
#define ASIC_OR_REG(reg, val) \
TchAudOrReg(reg, val, v_pTchAudAsicRegisters, bInPowerHandler)
@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.
//
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.
@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.
--*/
static
void
PddpTouchPanelEvaluateSamples(
TOUCH_PANEL_SAMPLE_FLAGS *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.
//
//#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 = TouchSampleValidFlag | TouchSampleDownFlag;
}
//
// 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.
//
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.
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
return TRUE;
}
//
// PddpDisableClearPenDownIntr(void)
//
// Tell the UCB to clear pen down interrupts
//
BOOL
PddpDisableClearPenDownIntr(void)
{
// Acquire semaphore to prevent contention with audio driver while accessing UCB regs
TCHAUD_SEM_LOCK();
// Clear bit 12 in UCB address 3 to disable interrupts on falling tspx (tspx_fal_int)
// Read data from UCB address 0x03
if (! ASIC_AND_REG(3, ~((USHORT)0x1000)))
goto error_return;
// Clear the pen down interrupt
// Write UCB address 4 bit 12 to a 0
if (! ASIC_WRITE_REG(4, 0))
goto error_return;
// Write UCB address 4 bit 12 to a 1, to clear tspx interrupts
if (! ASIC_WRITE_REG(4, 0x1000))
goto error_return;
This function is called to get a single calibration point, in screen
coordinates, when the input system is calibrating the touch driver. The input system
will then draw a target on the screen for the user to press on.
The driver may use the cDisplayX and cDisplayY to compute a coordinate.
It does not need to remember this computed value internally since it will
be passed back when the input system has collected all of the points and
calls .
*/
extern "C"
BOOL
TouchDriverCalibrationPointGet(
TPDC_CALIBRATION_POINT *pTCP //@PARM pointer to returned calibration point
)
{
// @doc EX_TOUCH_DDSI EXTERNAL DRIVERS DDSI TOUCH_PANEL
//
// @func ULONG | DdsiTouchPanelGetDeviceCaps |
//
// Queries capabilities about the physical touch panel device.
//
// @parm ULONG | iIndex |
//
// Specifies the capability to query. They are one of the following:
//
// @flag TPDC_SAMPLERATE_ID |
// The sample rate.
// @flag TPDC_CALIBRATIONPOINTS_ID |
// The X and Y coordinates used for calibration.
// @flag TPDC_CALIBRATIONDATA_ID |
// The X and Y coordinates used for calibration mapping.
//
// @parm LPVOID | lpOutput |
// Points to the memory location(s) where the queried information
// will be placed. The format of the memory referenced depends on
// the setting of iIndex. If 0, returns the number of words
// required for the output data.
//
// @rdesc
// The return values is set to the amount of information supplied and depends
// on the setting of the iIndex argument.
//
// @comm
// Implemented in the PDD.
//
//
// @doc EX_TOUCH_DDSI EXTERNAL DRIVERS DDSI TOUCH_PANEL
//
// @func BOOL | DdsiTouchPanelSetMode |
// Sets information about the physical touch panel device.
//
// @parm ULONG | iIndex |
// Specifies the mode to set. They are one of the following:
//
// @flag TPSM_SAMPLERATE_HIGH_ID |
// Sets the sample rate to the high rate.
// @flag TPSM_SAMPLERATE_LOW_ID |
// Sets the sample rate to the low rate.
//
// @parm LPVOID | lpInput |
// Points to the memory location(s) where the update information
// resides. The format of the memory referenced depends on the
// Points to the memory location(s) where the queried information
// will be placed.
//
// @rdesc
// If the function succeeds the return value is TRUE, otherwise, it is FALSE.
//
// @comm
// Implemented in the PDD.
//
//
// @doc EX_TOUCH_DDSI EXTERNAL DRIVERS DDSI TOUCH_PANEL
//
// @func BOOL | DdsiTouchPanelEnable |
// Powers up and initializes the touch panel hardware for operation.
//
// @rdesc
// If the function succeeds, the return value is TRUE; otherwise, it is FALSE.
//
// @comm
// Implemented in the PDD.
//