下里巴人的笔记 https://bbs.21ic.com/?81022 [收藏] [复制] [RSS]

日志

2410触摸屏校验算法

已有 2492 次阅读2006-8-2 13:25


#include <windows.h>
#include <types.h>
#include <memory.h>
#include <nkintr.h>
#include <tchddsi.h>
#include <nkintr.h>
#include <oalintr.h>


#include <s2410.h>


#define PUBLIC  
#define PRIVATE       static


#define TSP_SAMPLE_RATE_LOW    100
#define TSP_SAMPLE_RATE_HIGH   100
#define TSP_SAMPLETICK     (OEM_CLOCK_FREQ / TSP_SAMPLE_RATE_LOW)


#define ADCPRS       200


#define TSP_MINX      85
#define TSP_MINY      105


#define TSP_MAXX      965
#define TSP_MAXY      980


#define TSP_CHANGE      15
#define TSP_INVALIDLIMIT    40



#define TSP_LCDX      (LCD_XSIZE_TFT * 4)
#define TSP_LCDY      (LCD_YSIZE_TFT * 4)


#define TSP_SAMPLE_NUM     4



DWORD gIntrTouch        = SYSINTR_TOUCH;
DWORD gIntrTouchChanged = SYSINTR_TOUCH_CHANGED;


extern "C" const int MIN_CAL_COUNT   = 1;


PRIVATE INT TSP_CurRate = TSP_SAMPLE_RATE_HIGH;


PRIVATE volatile IOPreg * v_pIOPregs;
PRIVATE volatile ADCreg * v_pADCregs;
PRIVATE volatile INTreg * v_pINTregs;
PRIVATE volatile PWMreg * v_pPWMregs;


PRIVATE BOOL  bTSP_DownFlag;


VOID TSP_VirtualFree(VOID);
BOOL TSP_VirtualAlloc(VOID);


PRIVATE PVOID
TSP_RegAlloc(PVOID addr, INT sz)
{
 PVOID reg;


 reg = (PVOID)VirtualAlloc(0, sz, MEM_RESERVE, PAGE_NOACCESS);


 if (reg)
 {
  if (!VirtualCopy(reg, addr, sz, PAGE_READWRITE | PAGE_NOCACHE ))
  {
   VirtualFree(reg, sz, MEM_RELEASE);
   reg = NULL;
  }
 }


 return reg;
}



PRIVATE BOOL
TSP_VirtualAlloc(VOID)
{
 BOOL r = FALSE;


    RETAILMSG(0,(TEXT("::: TSP_VirtualAlloc()\r\n")));


 do
 {
  v_pIOPregs = (volatile IOPreg *)TSP_RegAlloc((PVOID)IOP_BASE, sizeof(IOPreg));
  if (v_pIOPregs == NULL)
  {
   ERRORMSG(1,(TEXT("For IOPreg: VirtualAlloc failed!\r\n")));
   break;
  }
 
  v_pADCregs = (volatile ADCreg *)TSP_RegAlloc((PVOID)ADC_BASE, sizeof(ADCreg));
  if (v_pADCregs == NULL)
  {
      ERRORMSG(1,(TEXT("For ADCreg: VirtualAlloc failed!\r\n")));
      break;
  }


  v_pINTregs = (volatile INTreg *)TSP_RegAlloc((PVOID)INT_BASE, sizeof(INTreg));
  if (v_pADCregs == NULL)
  {
      ERRORMSG(1,(TEXT("For INTregs: VirtualAlloc failed!\r\n")));
      break;
  }


  v_pPWMregs = (volatile PWMreg *)TSP_RegAlloc((PVOID)PWM_BASE, sizeof(PWMreg));
  if (v_pPWMregs == NULL)
  {
      ERRORMSG(1,(TEXT("For PWMregs: VirtualAlloc failed!\r\n")));
      break;
  }
  
  r = TRUE;
 } while (0);


 if (!r)
 {
  TSP_VirtualFree();


  RETAILMSG(0,(TEXT("::: TSP_VirtualAlloc() - Fail\r\n")));
 }
 else
 {
  RETAILMSG(0,(TEXT("::: TSP_VirtualAlloc() - Success\r\n")));
 }



 return r;
}


PRIVATE void
TSP_VirtualFree(VOID)
{
    RETAILMSG(0,(TEXT("::: TSP_VirtualFree()\r\n")));


 if (v_pIOPregs)
    {
        VirtualFree((PVOID)v_pIOPregs, sizeof(IOPreg), MEM_RELEASE);
        v_pIOPregs = NULL;
    }
    if (v_pADCregs)
    {  
        VirtualFree((PVOID)v_pADCregs, sizeof(ADCreg), MEM_RELEASE);
        v_pADCregs = NULL;
    }
    if (v_pINTregs)
    {  
        VirtualFree((PVOID)v_pINTregs, sizeof(INTreg), MEM_RELEASE);
        v_pINTregs = NULL;
    }
    if (v_pPWMregs)
    {  
        VirtualFree((PVOID)v_pPWMregs, sizeof(INTreg), MEM_RELEASE);
        v_pPWMregs = NULL;
    }
}


PRIVATE VOID
TSP_SampleStart(VOID)
{
 DWORD tmp;


 tmp = v_pPWMregs->rTCON & (~(0xf << 16));


 v_pPWMregs->rTCON = tmp | (2 << 16);  /* update TCVNTB3, stop     */
 v_pPWMregs->rTCON = tmp | (9 << 16);  /* interval mode,  start    */
// v_pPWMregs->rTCON = tmp | (1 << 16);  /* one-shot mode,  start    */
}


PRIVATE VOID
TSP_SampleStop(VOID)
{
 v_pPWMregs->rTCON &= ~(1 << 16);   /* Timer3, stop       */
}



PRIVATE VOID
TSP_PowerOn(VOID)
{
    RETAILMSG(0,(TEXT("::: TSP_PowerOn()\r\n")));


            /* Use TSXM, TSXP, TSYM, TSYP   */
 v_pIOPregs->rGPGCON |=  ((0x3 << 30) | (0x3 << 28) | (0x3 << 26) | (0x3 << 24));


 v_pADCregs->rADCDLY = 50000; 


    v_pADCregs->rADCCON = (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->rADCTSC = (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     */



 v_pINTregs->rINTSUBMSK  &= ~BIT_SUB_TC;


   v_pPWMregs->rTCFG1  &= ~(0xf << 12);  /* Timer3's Divider Value    */
   v_pPWMregs->rTCFG1  |=  (0   << 12);  /* 1/2         */
    v_pPWMregs->rTCNTB3  = TSP_SAMPLETICK;  /* Interrupt Frequency     */
}


PRIVATE VOID
TSP_PowerOff(VOID)
{
    RETAILMSG(0,(TEXT("::: TSP_PowerOff()\r\n")));


    v_pINTregs->rINTSUBMSK |= BIT_SUB_TC;
}


PRIVATE BOOL
TSP_CalibrationPointGet(TPDC_CALIBRATION_POINT *pTCP)
{
   
 INT32 cDisplayWidth  = pTCP->cDisplayWidth;
 INT32 cDisplayHeight = pTCP->cDisplayHeight;


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


 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;
 }


 RETAILMSG(0, (TEXT("::: TSP_CalibrationPointGet()\r\n")));
 RETAILMSG(0, (TEXT("cDisplayWidth        : %4X\r\n"), cDisplayWidth     ));
 RETAILMSG(0, (TEXT("cDisplayHeight       : %4X\r\n"), cDisplayHeight    ));
 RETAILMSG(0, (TEXT("CalibrationRadiusX   : %4d\r\n"), CalibrationRadiusX));
 RETAILMSG(0, (TEXT("CalibrationRadiusY   : %4d\r\n"), CalibrationRadiusY));
 RETAILMSG(0, (TEXT("pTCP -> PointNumber  : %4d\r\n"), pTCP->PointNumber));
 RETAILMSG(0, (TEXT("pTCP -> CalibrationX : %4d\r\n"), pTCP->CalibrationX));
 RETAILMSG(0, (TEXT("pTCP -> CalibrationY : %4d\r\n"), pTCP->CalibrationY));


 return TRUE;
}


PRIVATE void
TSP_TransXY(INT *px, INT *py)
{
 *px = (*px - TSP_MINX) * TSP_LCDX / (TSP_MAXX - TSP_MINX);
 *py = (*py - TSP_MINY) * TSP_LCDY / (TSP_MAXY - TSP_MINY);


 if (*px  <        0) *px = 0;
 if (*px >= TSP_LCDX) *px = TSP_LCDX - 1;


 if (*py  <        0) *py = 0;
 if (*py >= TSP_LCDY) *py = TSP_LCDY - 1;
}


PRIVATE BOOL
TSP_GetXY(INT *px, INT *py)
{
 INT i;
 INT xsum, ysum;
 INT x, y;
 INT dx, dy;


 xsum = ysum = 0;


 for (i = 0; i < TSP_SAMPLE_NUM; i++)
 {
  v_pADCregs->rADCTSC = (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])    */
        (1      <<  3) |  /* Pull Up Enable      */
        (1      <<  2) |  /* Auto ADC Conversion Mode    */
        (0  <<  0);   /* No Operation Mode     */


  v_pADCregs->rADCCON |= (1 << 0);    /* Start Auto conversion    */


  while (v_pADCregs->rADCCON & 0x1);    /* check if Enable_start is low   */
  while (!(v_pADCregs->rADCCON & (1 << 15)));  /* Check ECFLG       */


  x = (0x3ff & v_pADCregs->rADCDAT1);
  y = 0x3ff - (0x3ff & v_pADCregs->rADCDAT0);


  xsum += x;
  ysum += y;
 }



 *px = xsum / TSP_SAMPLE_NUM;
 *py = ysum / TSP_SAMPLE_NUM;


 v_pADCregs->rADCTSC = (1  << 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     */


 dx = (*px > x) ? (*px - x) : (x - *px);
 dy = (*py > y) ? (*py - y) : (y - *py);


 return ((dx > TSP_INVALIDLIMIT || dy > TSP_INVALIDLIMIT) ? FALSE : TRUE);
}


/* :::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: */
/* :::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: */


PUBLIC BOOL
DdsiTouchPanelGetDeviceCaps(INT iIndex, LPVOID  lpOutput)
{
 RETAILMSG(0, (TEXT("::: DdsiTouchPanelGetDeviceCaps\r\n")));


 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:
  {
   TPDC_SAMPLE_RATE *pTSR = (TPDC_SAMPLE_RATE*)lpOutput;
   RETAILMSG(0, (TEXT("TouchPanelGetDeviceCaps::TPDC_SAMPLE_RATE_ID\r\n")));


   pTSR->SamplesPerSecondLow      = TSP_SAMPLE_RATE_LOW;
   pTSR->SamplesPerSecondHigh     = TSP_SAMPLE_RATE_HIGH;
   pTSR->CurrentSampleRateSetting = TSP_CurRate;
  }
  break;


 case TPDC_CALIBRATION_POINT_COUNT_ID:
  {
   TPDC_CALIBRATION_POINT_COUNT *pTCPC = (TPDC_CALIBRATION_POINT_COUNT*)lpOutput;
   RETAILMSG(0, (TEXT("TouchPanelGetDeviceCaps::TPDC_CALIBRATION_POINT_COUNT_ID\r\n")));


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


 case TPDC_CALIBRATION_POINT_ID:
  RETAILMSG(0, (TEXT("TouchPanelGetDeviceCaps::TPDC_CALIBRATION_POINT_ID\r\n")));
  return(TSP_CalibrationPointGet((TPDC_CALIBRATION_POINT*)lpOutput));


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


 }


 return TRUE;
}


/* :::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: */
/* :::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: */
PUBLIC BOOL
DdsiTouchPanelSetMode(INT iIndex, LPVOID  lpInput)
{
    BOOL  ReturnCode = FALSE;


 RETAILMSG(0, (TEXT("::: DdsiTouchPanelSetMode()\r\n")));


    switch ( iIndex )
    {
 case TPSM_SAMPLERATE_LOW_ID:
 case TPSM_SAMPLERATE_HIGH_ID:
  SetLastError( ERROR_SUCCESS );
  ReturnCode = TRUE;
  break;


 default:
  SetLastError( ERROR_INVALID_PARAMETER );
  break;
    }



    return ( ReturnCode );
}


/* :::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: */
/* :::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: */


PUBLIC BOOL
DdsiTouchPanelEnable(VOID)
{
    BOOL r;


 RETAILMSG(0, (TEXT("::: DdsiTouchPanelEnable()\r\n")));


 r = TSP_VirtualAlloc();


 if (r)
 {
  TSP_PowerOn();
 }


    return r;
}


 


/* :::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: */
/* :::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: */


PUBLIC VOID
DdsiTouchPanelDisable(VOID)
{
 RETAILMSG(0, (TEXT("::: DdsiTouchPanelDisable()\r\n")));
    if (v_pADCregs)
 {
     TSP_PowerOff();
  TSP_VirtualFree();
 }
}


/* :::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: */
/* :::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: */


LONG
DdsiTouchPanelAttach(VOID)
{
    return (0);
}



LONG
DdsiTouchPanelDetach(VOID)
{
    return (0);
}



/* :::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: */
/* :::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: */
PUBLIC VOID
DdsiTouchPanelPowerHandler(BOOL bOff)
{
 RETAILMSG(0, (TEXT("::: DdsiTouchPanelPowerHandler()\r\n")));
    if (bOff)
 {
        TSP_PowerOff();
    }
    else
 {
        TSP_PowerOn();
    }
}



/* :::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: */
/* :::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: */


 


PUBLIC VOID
DdsiTouchPanelGetPoint(TOUCH_PANEL_SAMPLE_FLAGS * pTipStateFlags,
        INT * pUncalX,
        INT * pUncalY)
{
 static INT x, y;


 //DEBUGMSG(1, (TEXT("::: DdsiTouchPanelGetPoint()\r\n")));


 if (v_pINTregs->rSUBSRCPND & BIT_SUB_TC)  /* SYSINTR_TOUCH Interrupt Case    */
 {
  *pTipStateFlags = TouchSampleValidFlag;


  if ( (v_pADCregs->rADCDAT0 & (1 << 15)) |
    (v_pADCregs->rADCDAT1 & (1 << 15)) )
  {
   bTSP_DownFlag = FALSE;


   DEBUGMSG(ZONE_TIPSTATE, (TEXT("up\r\n")));


   v_pADCregs->rADCTSC &= 0xff;


   *pUncalX = x;
   *pUncalY = y;


   TSP_SampleStop();
  }
  else
  {
   bTSP_DownFlag = TRUE;


   if (!TSP_GetXY(&x, &y))
    *pTipStateFlags = TouchSampleIgnore;


   TSP_TransXY(&x, &y);


   *pUncalX = x;
   *pUncalY = y;


   *pTipStateFlags |= TouchSampleDownFlag;


   DEBUGMSG(ZONE_TIPSTATE, (TEXT("down %x %x\r\n"), x, y));


   TSP_SampleStart();
  }


  v_pINTregs->rSUBSRCPND  =  BIT_SUB_TC;
  v_pINTregs->rINTSUBMSK &= ~BIT_SUB_TC;


  InterruptDone(gIntrTouch);
 }
 else  /* SYSINTR_TOUCH_CHANGED Interrupt Case  */
 {
//  TSP_SampleStart();
  
  if (bTSP_DownFlag)
  {
   INT  tx, ty;
   INT  dx, dy;


   if (!TSP_GetXY(&tx, &ty))
    *pTipStateFlags = TouchSampleIgnore;
   else
   {
    TSP_TransXY(&tx, &ty);
// insert by mostek@dstcorp.com
#define X_ERRV 0x3bf
#define Y_ERRV 0x4ff


    if ((tx == X_ERRV) && (ty == Y_ERRV))
    {
     tx = x;
     ty = y;
    }
// =================== mostek
    dx = (tx > x) ? (tx - x) : (x - tx);
    dy = (ty > y) ? (ty - y) : (y - ty);


    if (dx > TSP_CHANGE || dy > TSP_CHANGE)
    {
     *pUncalX = x = tx;
     *pUncalY = y = ty;


     DEBUGMSG(ZONE_TIPSTATE, (TEXT("down-c-v %x %x\r\n"), x, y));


     *pTipStateFlags = TouchSampleValidFlag | TouchSampleDownFlag;
    }
    else
    {
     *pUncalX = x;
     *pUncalY = y;


     DEBUGMSG(ZONE_TIPSTATE, (TEXT("down-c %x %x\r\n"), x, y));


     *pTipStateFlags = TouchSampleIgnore;
    }
   }
  }
  else
  {
   *pTipStateFlags = TouchSampleIgnore;


   TSP_SampleStop();
  }


  InterruptDone(gIntrTouchChanged);
 }
}


#if 0
PUBLIC VOID
DdsiTouchPanelGetPoint(TOUCH_PANEL_SAMPLE_FLAGS * pTipStateFlags,
        INT      * pUncalX,
        INT      * pUncalY)
{
 static INT x, y;


 //RETAILMSG(0, (TEXT("::: DdsiTouchPanelGetPoint()\r\n")));


 if (v_pINTregs->rSUBSRCPND & BIT_SUB_TC)  /* SYSINTR_TOUCH Interrupt Case    */
 {
  *pTipStateFlags = TouchSampleValidFlag;


  if (v_pADCregs->rADCTSC & (1 << 8))
  {
   bTSP_DownFlag = FALSE;


   RETAILMSG(0, (TEXT("up\r\n")));


   v_pADCregs->rADCTSC &= 0xff;


   *pUncalX = x;
   *pUncalY = y;


   TSP_SampleStop();
  }
  else
  {
   bTSP_DownFlag = TRUE;


   if (!TSP_GetXY(&x, &y))
    *pTipStateFlags = TouchSampleIgnore;


   TSP_TransXY(&x, &y);


   *pUncalX = x;
   *pUncalY = y;


   *pTipStateFlags |= TouchSampleDownFlag;


   RETAILMSG(0, (TEXT("down %x %x\r\n"), x, y));


   TSP_SampleStart();
  }


  v_pINTregs->rSUBSRCPND  =  BIT_SUB_TC;
  v_pINTregs->rINTSUBMSK &= ~BIT_SUB_TC;


  InterruptDone(gIntrTouch);
 }
 else           /* SYSINTR_TOUCH_CHANGED Interrupt Case  */
 {
//  TSP_SampleStart();
  
  if (bTSP_DownFlag)
  {
   INT  tx, ty;
   INT  dx, dy;


   if (!TSP_GetXY(&tx, &ty))
    *pTipStateFlags = TouchSampleIgnore;
   else
   {
    TSP_TransXY(&tx, &ty);


    dx = (tx > x) ? (tx - x) : (x - tx);
    dy = (ty > y) ? (ty - y) : (y - ty);


    if (dx > TSP_CHANGE || dy > TSP_CHANGE)
    {
     *pUncalX = x = tx;
     *pUncalY = y = ty;


     RETAILMSG(0, (TEXT("down-c-v %x %x\r\n"), x, y));


     *pTipStateFlags = TouchSampleValidFlag | TouchSampleDownFlag;
    }
    else
    {
     *pUncalX = x;
     *pUncalY = y;


     RETAILMSG(0, (TEXT("down-c %x %x\r\n"), x, y));


     *pTipStateFlags = TouchSampleIgnore;
    }
   }
  }
  else
  {
   *pTipStateFlags = TouchSampleIgnore;


   TSP_SampleStop();
  }


  InterruptDone(gIntrTouchChanged);
 }
}


#endif


路过

鸡蛋

鲜花

握手

雷人

发表评论 评论 (1 个评论)

回复 2007lxm 2006-8-3 08:58
没有注释