⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 touchpdd.c

📁 WinCE 3.0 BSP, 包含Inter SA1110, Intel_815E, Advantech_PCM9574 等
💻 C
📖 第 1 页 / 共 2 页
字号:
/*
 * Copyright (C) NEC Electronics Inc. 1998, 1999.
 *
 * File:    Touchpdd.c
 *
 *
 */

const int MIN_CAL_COUNT = 10;


#include <windows.h>
#include <tchar.h>
#include <types.h>
#include <excpt.h>
#include <memory.h>
//#include <nkintr.h>
//#include <oalintr.h>
#include <kfuncs.h>
#include <tchddsi.h>
#include <drvlib.h>
#include <vrc4173.h>
#include "piu_hw.h"

INT     CurrentSampleRateSetting = 0;   //  Low sample rate set ting

UINT16  g_SamplingPeriod;

BOOL    Enabled = FALSE;

static  UINT16  Xbuf[5];
static  UINT16  Ybuf[5];
static  int nsample;
static  int cursample;

//extern DWORD gIntrTouch;// = SYSINTR_TOUCH;
//extern DWORD gIntrTouchChanged;// = SYSINTR_TOUCH_CHANGED;

//
// PDD internal support routines
//


static BOOL
EvaluateSampleVs(int p1, int p2, int p3)
{
    int VsX, VsY;
    int ExX, ExY;

    VsX = ABS(Xbuf[p2] - Xbuf[p1]);
    VsY = ABS(Ybuf[p2] - Ybuf[p1]);
    ExX = Xbuf[p2]*2 - Xbuf[p1];
    ExY = Ybuf[p2]*2 - Ybuf[p1];

    return ABS(ExX-Xbuf[p3])<DELTA_X_COORD_VARIANCE && ABS(ExY-Ybuf[p3])<DELTA_Y_COORD_VARIANCE;
}


/*++

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.

    @devnote
    Determined empirically that the variance of the X coordinate of the
    first 2 samples from all other samples is large enough that in order
    to keep the nominal variance small, we discard the first samples.


--*/
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.
    UINT                        PageNumber     //@PARM Number of Page buffer
    )
{
    PIU_PENSAMPLE    rgPointSamples;
    PPIU_PENSAMPLE  ioPenPointer;
    INT p1, p2, p3, p4, p5;
    INT ev;

    if (PageNumber == 0) {
        ioPenPointer = (PPIU_PENSAMPLE)(pVRC4173+PIUPB00REG);
    } else {
        ioPenPointer = (PPIU_PENSAMPLE)(pVRC4173+PIUPB10REG);
    }

    rgPointSamples.XSample0 = ioPenPointer->XSample0 & penDataFormatValidMask16;
    rgPointSamples.XSample1 = ioPenPointer->XSample1 & penDataFormatValidMask16;
    rgPointSamples.YSample0 = ioPenPointer->YSample0 & penDataFormatValidMask16;
    rgPointSamples.YSample1 = ioPenPointer->YSample1 & penDataFormatValidMask16;

    cursample = (cursample+1) % 5;
    Xbuf[cursample] = (rgPointSamples.YSample1 + (0xFFF-rgPointSamples.YSample0)) >> 1;
    Ybuf[cursample] = (rgPointSamples.XSample1 + (0xFFF-rgPointSamples.XSample0)) >> 1;

    if (nsample < 5)
        nsample++;

    p1 = (cursample+1) % 5;
    p2 = (cursample+2) % 5;
    p3 = (cursample+3) % 5;
    p4 = (cursample+4) % 5;
    p5 = cursample;

    switch (nsample) {
    case 1:
        *pSampleFlags = TouchSampleIgnore;
        break;
    case 2:
        p3 = p4;
        p4 = p5;
        // fall through
    case 3:
        p2 = p3;
        // fall through
    case 4:
        p1 = p2;
        // fall through
    case 5:
        // Evaluate linearity of samples for large noise
        ev = 0;
        if (EvaluateSampleVs(p1, p2, p3)) ev |= 1;
        if (EvaluateSampleVs(p2, p3, p4)) ev |= 2;
        if (EvaluateSampleVs(p3, p4, p5)) ev |= 4;

        switch (ev) {
        case 0: // 000  reject
            *pSampleFlags = TouchSampleIgnore;
            break;

        case 4: // 100  reject
            *pSampleFlags = TouchSampleIgnore;
            break;

        case 1: // 001  reject
            *pSampleFlags = TouchSampleIgnore;
            break;

        case 3: // 011  use
            // OK, but don't use p1,p5
            // maybe p5 is bad sample
            *pSampleFlags |= TouchSampleDownFlag;
            *pUncalX = (Xbuf[p2] + Xbuf[p3]*2 + Xbuf[p4]) >> 2;
            *pUncalY = (Ybuf[p2] + Ybuf[p3]*2 + Ybuf[p4]) >> 2;
            break;

        case 6: // 110  use
            // OK, but don't use p1,p5
            // maybe p1 is bad sample
            *pSampleFlags |= TouchSampleDownFlag;
            *pUncalX = (Xbuf[p2] + Xbuf[p3]*2 + Xbuf[p4]) >> 2;
            *pUncalY = (Ybuf[p2] + Ybuf[p3]*2 + Ybuf[p4]) >> 2;
            break;

        case 2: // 010  use
            // OK, but don't use p1,p5
            *pSampleFlags |= TouchSampleDownFlag;
            *pUncalX = (Xbuf[p2] + Xbuf[p3]*2 + Xbuf[p4]) >> 2;
            *pUncalY = (Ybuf[p2] + Ybuf[p3]*2 + Ybuf[p4]) >> 2;
            break;

        case 5: // 101  use
        case 7: // 111  use
            // OK
            *pSampleFlags |= TouchSampleDownFlag;
            *pUncalX = (Xbuf[p1] + Xbuf[p2]*4 + Xbuf[p3]*6 + Xbuf[p4]*4 + Xbuf[p5]) >> 4;
            *pUncalY = (Ybuf[p1] + Ybuf[p2]*4 + Ybuf[p3]*6 + Ybuf[p4]*4 + Ybuf[p5]) >> 4;
            break;
        }
#if 0
        if (*pSampleFlags & TouchSampleIgnore) {
            RETAILMSG(1, (TEXT("rej\r\n")));
        }
#endif
    }
#if 0
    if (*pSampleFlags & TouchSampleDownFlag) {
        RETAILMSG(1, (TEXT("x=%d y=%d\r\n"), *pUncalX, *pUncalY));
    }
#endif
}


//
// DDSI Implementation
//


//  @DOC    EX_TOUCH_DDSI EXTERNAL DRIVERS TOUCH_DRIVER
/*  @FUNC   BOOL | TouchDriverCalibrationPointGet |

Gives a single calibration point.

    @XREF
        <l TouchPanelReadCalibrationPoint.TouchPanelReadCalibrationPoint>
        <l TouchPanelSetCalibration.TouchPanelSetCalibration>
        <l TouchPanelReadCalibrationAbort.TouchPanelReadCalibrationAbort>


    @COMM

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 <l TouchPanelSetCalibration.TouchPanelSetCalibration>.

*/

BOOL
TouchDriverCalibrationPointGet(
    struct TPDC_CALIBRATION_POINT   far *pTCP //@PARM pointer to returned calibration point
    )
{
    INT32   cDisplayWidth = pTCP -> cDisplayWidth;
    INT32   cDisplayHeight = pTCP -> cDisplayHeight;

    int CalibrationRadiusX = cDisplayWidth/20;
    int CalibrationRadiusY = cDisplayHeight/10;

    switch (pTCP -> PointNumber) {
    case 0:
        pTCP -> CalibrationX = cDisplayWidth/2;
        pTCP -> CalibrationY = cDisplayHeight/2;
        break;

    case 1:
        pTCP -> CalibrationX = CalibrationRadiusX*2;
        pTCP -> CalibrationY = CalibrationRadiusY*2;
        break;

    case 2:
        pTCP -> CalibrationX = CalibrationRadiusX*2;
        pTCP -> CalibrationY = cDisplayHeight - CalibrationRadiusY*2;
        break;

    case 3:
        pTCP -> CalibrationX = cDisplayWidth - CalibrationRadiusX*2;
        pTCP -> CalibrationY = cDisplayHeight - CalibrationRadiusY*2;
        break;

    case 4:
        pTCP -> CalibrationX = cDisplayWidth - CalibrationRadiusX*2;
        pTCP -> CalibrationY = CalibrationRadiusY*2;
        break;

    default:
        pTCP -> CalibrationX = cDisplayWidth/2;
        pTCP -> CalibrationY = cDisplayHeight/2;
        SetLastError(ERROR_INVALID_PARAMETER);
        return FALSE;
    }

    return TRUE;
}




// @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.
//

BOOL
DdsiTouchPanelGetDeviceCaps(
    INT     iIndex,
    LPVOID  lpOutput
    )
{
    struct TPDC_SAMPLE_RATE far *pTSR;
    struct TPDC_CALIBRATION_POINT_COUNT far *pTCPC;

    if (lpOutput == NULL) {
        ERRORMSG(1, (__TEXT("TouchPanelGetDeviceCaps: invalid parameter.\r\n")));
        SetLastError(ERROR_INVALID_PARAMETER);
        DebugBreak();
        return FALSE;
    }

    switch (iIndex) {
    case TPDC_SAMPLE_RATE_ID:
        pTSR = (struct TPDC_SAMPLE_RATE far *)lpOutput;

        pTSR -> SamplesPerSecondLow  = SAMPLES_PER_SECOND_DEFAULT;
        pTSR -> SamplesPerSecondHigh = SAMPLES_PER_SECOND_HIGH;
        pTSR -> CurrentSampleRateSetting = CurrentSampleRateSetting;
        break;

    case TPDC_CALIBRATION_POINT_COUNT_ID:
        pTCPC = (struct TPDC_CALIBRATION_POINT_COUNT *)lpOutput;

        pTCPC -> flags = 0;
        pTCPC -> cCalibrationPoints = 5;
        break;

    case TPDC_CALIBRATION_POINT_ID:
        return(TouchDriverCalibrationPointGet((struct TPDC_CALIBRATION_POINT far *)lpOutput));

    default:
        ERRORMSG(1, (__TEXT("TouchPanelGetDeviceCaps: invalid parameter.\r\n")));
        SetLastError(ERROR_INVALID_PARAMETER);
        DebugBreak();
        return FALSE;
    }

    return TRUE;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -