📄 wmtouch.c
字号:
/*
* Clean up if this was pen up.
*/
if ( !penDown )
{
/* WM_INCREMENT_COUNTER( pDeviceContext, TouchPenUps ); */
/* Stop the ADCs streaming */
if ( penWasDown && !private_IsPenDebouncing( hDevice ) )
{
WMTouchEndCapture( hDevice );
}
pDeviceContext->v_pADCData->flags &= ~WM_TOUCH_HISTORY_PEN_DOWN;
status = WMS_NO_PEN_DOWN;
}
/*
* Let other threads in.
*/
WMUnlockGlobalData( hDevice );
return status;
error1:
WMUnlockGlobalData( hDevice );
error0:
*pXCoord = WM_INVALID_SAMPLE;
*pYCoord = WM_INVALID_SAMPLE;
return status;
}
/*-----------------------------------------------------------------------------
* Function: private_FillHistoryBuffer
*
* Reads points until we've got enough to fill the history buffer.
*
* Note: this function assumes the global memory is already locked.
*
* Parameters:
* hDevice handle to the device (from WMOpenDevice)
*
* Returns: WMSTATUS
* See WMStatus.h
*---------------------------------------------------------------------------*/
static WMSTATUS private_FillHistoryBuffer( WM_DEVICE_HANDLE hDevice )
{
WM_DEVICE_CONTEXT *pDeviceContext = WMHANDLE_TO_DEVICE( hDevice );
volatile WM_TOUCH_HISTORY *pTouchHistory = &pDeviceContext->v_pADCData->touchHistory;
WMSTATUS status = WMS_NO_DATA, newStatus;
WM_TOUCH_POINT point;
/*
* Always get at least one point, and continue until either the buffer's
* full or we get an error.
*/
do
{
newStatus = WMGetRawTouchCoordinates( hDevice, &point.x, &point.y );
if ( WM_ERROR( newStatus ) )
{
/*
* No data is only an error first time round.
* Anything else is always an error.
*/
if ( WMS_NO_DATA != newStatus )
{
status = newStatus;
}
goto done;
}
status = newStatus;
# if WM_STREAM_AUXADC && ( 0 < WM_TOUCH_NUM_REJECT )
/*
* Some platforms have stale points in the FIFO in streaming mode.
* We reject the first few points to deal with this.
* See WMConfig.h to configure this.
*/
if ( pTouchHistory->rejected < WM_TOUCH_NUM_REJECT )
{
pTouchHistory->rejected++;
continue;
}
# endif
/* Add the point to the buffer and update the buffer status */
private_AddHistoryPoint( hDevice, &point );
}
while ( pTouchHistory->numPoints < WM_NUM_SAMPLES_PER_POINT );
done:
return status;
}
/*-----------------------------------------------------------------------------
* Function: private_AddHistoryPoint
*
* Reads points until we've got enough to fill the history buffer.
*
* Note: this function assumes the global memory is already locked.
*
* Parameters:
* hDevice handle to the device (from WMOpenDevice)
* point The point to add.
*
* Returns: void
*---------------------------------------------------------------------------*/
static void private_AddHistoryPoint( WM_DEVICE_HANDLE hDevice,
const WM_TOUCH_POINT *pPoint
)
{
WM_DEVICE_CONTEXT *pDeviceContext = WMHANDLE_TO_DEVICE( hDevice );
WM_TOUCH_HISTORY *pTouchHistory = (WM_TOUCH_HISTORY*) &pDeviceContext->v_pADCData->touchHistory;
int currPoint = pTouchHistory->nextPoint;
WM_TOUCH_POINT *pCurrPoint = &pTouchHistory->points[currPoint];
int xDiff, yDiff;
int point;
/* Add this point to the buffer */
*pCurrPoint = *pPoint;
pCurrPoint->matches = 0;
pCurrPoint->timestamp = GetMillisecondTimestamp( hDevice );
/*
* Update the matches flags.
*/
for ( point = 0; point < WM_NUM_SAMPLES_PER_POINT; point++ )
{
/* Don't check against itself */
if ( currPoint == point )
continue;
/* If both x and y are reasonable, remember that. */
xDiff = pPoint->x - pTouchHistory->points[point].x;
if ( xDiff < 0 )
xDiff = -xDiff;
yDiff = pPoint->y - pTouchHistory->points[point].y;
if ( yDiff < 0 )
yDiff = -yDiff;
if ( xDiff < WM_TOUCH_COORD_VARIANCE && yDiff < WM_TOUCH_COORD_VARIANCE )
{
pCurrPoint->matches |= 1 << point;
pTouchHistory->points[point].matches |= 1 << currPoint;
}
else
{
pTouchHistory->points[point].matches &= ~(1 << currPoint);
}
}
/* And move the pointer on */
pTouchHistory->lastPoint = pTouchHistory->nextPoint;
pTouchHistory->nextPoint++;
if ( WM_NUM_SAMPLES_PER_POINT <= pTouchHistory->nextPoint )
pTouchHistory->nextPoint = 0;
if ( pTouchHistory->numPoints < WM_NUM_SAMPLES_PER_POINT )
pTouchHistory->numPoints++;
}
/*-----------------------------------------------------------------------------
* Function: private_GetAveragedCoordinates
*
* Calculates the average of the points in the buffer which are within range
* of at least one other point in the buffer.
*
* Note: this function assumes the global memory is already locked.
*
* Parameters:
* hDevice handle to the device (from WMOpenDevice)
* pXCoord Variable to receive X coordinate
* pYCoord Variable to receive Y coordinate
*
* Returns: WMSTATUS
* WMS_SUCCESS - it worked
* WMS_NO_DATA - no data to work with
*---------------------------------------------------------------------------*/
WMSTATUS private_GetAveragedCoordinates( WM_DEVICE_HANDLE hDevice,
WM_REGVAL *pXCoord,
WM_REGVAL *pYCoord
)
{
WM_DEVICE_CONTEXT *pDeviceContext = WMHANDLE_TO_DEVICE( hDevice );
volatile WM_TOUCH_HISTORY *pTouchHistory = &pDeviceContext->v_pADCData->touchHistory;
unsigned int xTotal = 0, yTotal = 0;
unsigned int numPoints = 0;
volatile WM_TOUCH_POINT *pPoint;
int point;
WMSTATUS status;
/* If we've not got any points, we've got no data. */
if ( 0 == pTouchHistory->numPoints )
{
status = WMS_NO_DATA;
goto error;
}
/* Build up the total */
for ( point = 0; point < pTouchHistory->numPoints; point++ )
{
pPoint = &pTouchHistory->points[point];
/* It's a match if any of the bits are set */
if ( pPoint->matches )
{
numPoints++;
xTotal += pPoint->x;
yTotal += pPoint->y;
}
}
/* If there are no points within range of each other, just return the last one */
if ( 0 == numPoints )
{
*pXCoord = pTouchHistory->points[pTouchHistory->lastPoint].x;
*pYCoord = pTouchHistory->points[pTouchHistory->lastPoint].y;
}
else
{
/* Calculate and return the averages */
*pXCoord = (WM_REGVAL) (xTotal / numPoints);
*pYCoord = (WM_REGVAL) (yTotal / numPoints);
}
return WMS_SUCCESS;
error:
return status;
}
/*-----------------------------------------------------------------------------
* Function: private_ResetHistory
*
* Resets the point history when we've had pen up.
*
* Note: this function assumes the global memory is already locked.
*
* Parameters:
* hDevice handle to the device (from WMOpenDevice)
*
* Returns: void
*---------------------------------------------------------------------------*/
static void private_ResetHistory( WM_DEVICE_HANDLE hDevice )
{
WM_DEVICE_CONTEXT *pDeviceContext = WMHANDLE_TO_DEVICE( hDevice );
volatile WM_TOUCH_HISTORY *pTouchHistory = &pDeviceContext->v_pADCData->touchHistory;
unsigned int point, tNow;
/*
* Set all the timestamps to now for our pen-down debouncing,
* and zap everything else.
*/
tNow = GetMillisecondTimestamp( hDevice );
for ( point = 0; point < WM_NUM_SAMPLES_PER_POINT; point++ )
{
pTouchHistory->points[point].timestamp = tNow;
pTouchHistory->points[point].x = 0;
pTouchHistory->points[point].y = 0;
pTouchHistory->points[point].matches = 0;
}
pTouchHistory->nextPoint = 0;
pTouchHistory->lastPoint = 0;
pTouchHistory->numPoints = 0;
pTouchHistory->rejected = 0;
}
/*-----------------------------------------------------------------------------
* Function: private_IsPenDebouncing
*
* This function works out whether we're currently in pen debounce.
*
* Parameters:
* hDevice handle to the device (from WMOpenDevice)
*
* Returns: WM_BOOL
* TRUE if the pen is in debounce (i.e. up but only in the last
* few moments).
*---------------------------------------------------------------------------*/
static WM_BOOL private_IsPenDebouncing( WM_DEVICE_HANDLE hDevice )
{
WM_DEVICE_CONTEXT *pDeviceContext = WMHANDLE_TO_DEVICE( hDevice );
volatile WM_TOUCH_HISTORY *pTouchHistory = &pDeviceContext->v_pADCData->touchHistory;
WM_BOOL debouncing = FALSE;
if ( pDeviceContext->v_pADCData->flags & WM_TOUCH_HISTORY_DEBOUNCING )
{
unsigned int lastPointTime, delay;
lastPointTime = pTouchHistory->points[pTouchHistory->lastPoint].timestamp;
delay = GetMillisecondTimestamp( hDevice ) - lastPointTime;
/* We add 1ms so we can deal with NO_DATA at the start even if the timeout is 0 */
if ( (WM_DEBOUNCE_TIME + 1) > delay )
{
/* We're still in debounce. */
debouncing = TRUE;
}
}
#ifdef DEBUG
else
{
/* Set to FALSE so we've got somewhere to set a breakpoint */
debouncing = FALSE;
}
#endif
return debouncing;
}
#ifdef DEBUG
/*-----------------------------------------------------------------------------
* Function: WMTouchDebugState
*
* Returns some internal touch driver state to help with debugging drivers.
*
* Parameters:
* hDevice handle to the device (from WMOpenDevice)
*
* Returns: unsigned int
* See WM_TOUCH_DEBUG_* flags.
*---------------------------------------------------------------------------*/
unsigned int WMTouchDebugState( WM_DEVICE_HANDLE hDevice )
{
WM_DEVICE_CONTEXT *pDeviceContext = WMHANDLE_TO_DEVICE( hDevice );
unsigned int retval = 0;
if ( pDeviceContext->v_pADCData->flags & WM_TOUCH_HISTORY_PEN_DOWN )
retval |= WM_TOUCH_DEBUG_PEN_DOWN;
if ( pDeviceContext->v_pADCData->flags & WM_TOUCH_HISTORY_DEBOUNCING )
retval |= WM_TOUCH_DEBUG_PEN_DEBOUNCING;
return retval;
}
#endif /* DEBUG */
#endif /* WM_TOUCH */
/*------------------------------ END OF FILE ---------------------------------*/
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -