tchpdd.cpp
上传用户:qiulin1960
上传日期:2013-10-16
资源大小:2844k
文件大小:38k
源码类别:

Windows CE

开发平台:

Windows_Unix

  1. /*++
  2. THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF
  3. ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO
  4. THE IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A
  5. PARTICULAR PURPOSE.
  6. Copyright (c) 2002. Samsung Electronics, co. ltd  All rights reserved.
  7. Module Name:
  8.   tchpdd.cpp
  9. Abstract:
  10.   This module contains the DDSI implementation and PDD support routines
  11.   for the touch panel for the P2 implementation.
  12. Functions:
  13.   TouchDriverCalibrationPointGet
  14.   DdsiTouchPanelGetDeviceCaps
  15.   DdsiTouchPanelSetMode
  16.   DdsiTouchPanelEnable
  17.   DdsiTouchPanelDisable
  18.   DdsiTouchPanelAttach
  19.   DdsiTouchPanelDetach
  20.   DdsiTouchPanelGetPoint
  21.   DdsiTouchPanelPowerHandler
  22. Notes:
  23. Revision History:
  24. --*/
  25. #define DBGPOINTS1 1
  26. #define TRACE_TIP_STATE
  27. #include    <windows.h>
  28. #include <types.h>
  29. #include    <memory.h>
  30. #include    <nkintr.h>
  31. #include    <oalintr.h>
  32. #include    <tchddsi.h>
  33. #include    <tchpdd.h>
  34. #include    <drv_glob.h>
  35. //#include    <p2debug.h>
  36. #include    <S2440.H>
  37. #include  "reg.h"
  38. #define SYS_TIMER_PRESCALER 24
  39. //#define SYS_TIMER_DIVIDER 4 // 2
  40. //#define OEM_CLOCK_FREQ (S2440PCLK / (SYS_TIMER_PRESCALER+1) / SYS_TIMER_DIVIDER)
  41. #define JYLEE_TEST 0
  42. #define JYLEE_TEST1 0
  43. //#define TFT240_320 1
  44. //#define TFT640_480 4
  45. //#define LCD_TYPE TFT240_320
  46. //#define LCD_TYPE TFT640_480
  47. #if ( LCD_TYPE == TFT640_480 )
  48. #define ADC_DELAY_TIME 65530
  49. #else
  50. #define ADC_DELAY_TIME 40000 // yhkim
  51. #endif
  52. DWORD gIntrTouch = SYSINTR_TOUCH;
  53. DWORD gIntrTouchChanged = SYSINTR_TOUCH_CHANGED;
  54. #ifdef TRACE_TIP_STATE
  55. BOOL PenIsUp = TRUE;
  56. #endif
  57. #if defined(MIPS) || defined(PPC821) || defined(PPC823) || defined(ARM) || defined(SH4)
  58. #define PAGE_MASK 0x0fff
  59. #define PAGE_SIZE 0x1000
  60. volatile static PVOID pTmpRegs;
  61. #endif
  62. static void TouchPanelPowerOff();
  63. static void TouchPanelPowerOn();
  64. static BOOL Touch_Timer0_Setup(void) ;
  65. static BOOL Touch_Pen_filtering(INT *px, INT *py);
  66. // The MDD requires a minimum of MIN_CAL_COUNT consecutive samples before
  67. // it will return a calibration coordinate to GWE.  This value is defined
  68. // in the PDD so that each OEM can control the behaviour of the touch
  69. // panel and still use the Microsoft supplied MDD.  Note that the extern "C"
  70. // is required so that the variable name doesn't get decorated, and
  71. // since we have an initializer the 'extern' is actually ignored and
  72. // space is allocated.
  73. extern "C" const int MIN_CAL_COUNT = 40;
  74. INT CurrentSampleRateSetting = 0; // Low sample rate setting
  75. // @globalvar PTCHAUD_ASIC_REGISTERS | v_pTchAudAsicRegisters | Pointer to Asic regs
  76. PTCHAUD_ASIC_REGISTERS              v_pTchAudAsicRegisters = NULL;
  77. // @globalvar PTOUCHPANEL_POINT_SAMPLE | v_pPenSamples | Pointer to pen samples area
  78. PDRIVER_GLOBALS      v_pDriverGlobals = NULL;
  79. volatile static PVOID v_pCpuRegs = NULL;
  80. TOUCH_PANEL_SAMPLE_FLAGS SampleFlags;
  81. #ifdef CHECK_RATE
  82.     UINT32 tmp_leds = 0x55;
  83. #endif
  84. // Mutex to prevent contention with audio while accessing shared registers
  85. static HANDLE v_hTchAudMutex;
  86. // Global flag to indicate whether we are in power handler routine, so
  87. // we know to avoid system calls.
  88. static BOOL bInPowerHandler = FALSE;
  89. // Macros for aquiring semaphore for shared access to ASIC registers. If
  90. // we are in the power handler routines, we don't need/want to aquire semaphore,
  91. // since we are serialized at that point, and can't make any system calls.
  92. #define TCHAUD_SEM_LOCK()  
  93.     if (!bInPowerHandler) { 
  94.         DEBUGMSG(ZONE_TIPSTATE,(TEXT("TchPDD Getting semaphore...rn"))); 
  95.         TchAudLock(v_hTchAudMutex, &(v_pDriverGlobals->tch.semaphore)); 
  96.     }
  97. #define TCHAUD_SEM_UNLOCK() 
  98.     if (!bInPowerHandler) { 
  99.         DEBUGMSG(ZONE_TIPSTATE,(TEXT("TchPDD Releasing semaphore...rn"))); 
  100.         TchAudUnlock(v_hTchAudMutex, &(v_pDriverGlobals->tch.semaphore)); 
  101.     }
  102. // Macros for accessing registers on the touch audio ASIC.  The code for
  103. // these functions is in drvlib so it can be shared between touch and audio.
  104. #define ASIC_READ_REG(reg, pval) 
  105.     TchAudReadReg(reg, pval, v_pTchAudAsicRegisters, bInPowerHandler)
  106. #define ASIC_WRITE_REG(reg, val) 
  107.     TchAudWriteReg(reg, val, v_pTchAudAsicRegisters, bInPowerHandler)
  108. #define ASIC_AND_REG(reg, val) 
  109.     TchAudAndReg(reg, val, v_pTchAudAsicRegisters, bInPowerHandler)
  110. #define ASIC_OR_REG(reg, val) 
  111.     TchAudOrReg(reg, val, v_pTchAudAsicRegisters, bInPowerHandler)
  112. volatile IOPreg *v_pIOPregs;
  113. volatile ADCreg *v_pADCregs;
  114. volatile PWMreg *v_pPWMregs;
  115. volatile INTreg *v_pINTregs;    
  116. volatile unsigned short xbuf[10], ybuf[10];
  117. static unsigned int touch_down = 1;
  118. //#define ADCPRS  49 // 200Mhz
  119. #define ADCPRS  49 // 200Mhz
  120. //#define ADCPRS  65 // 532Mhz
  121. /*++
  122. Routine Description:
  123.     Deallocates the virtual memory reserved for the Touch/Audio Asic registers,
  124.     and the pen samples dma area.
  125. Arguments:
  126.     None.
  127. Return Value:
  128.     None.
  129. Autodoc Information:
  130.     @doc IN_TOUCH_DDSI INTERNAL DRIVERS PDD TOUCH_PANEL
  131.     @func VOID | PddpTouchPanelDeallocateVm |
  132.     Deallocates the virtual memory reserved for the Touch/Audio Asic registers,
  133.     and the pen samples dma area.
  134. --*/
  135. static
  136. void
  137. PddpTouchPanelDeallocateVm(
  138.     VOID
  139.     )
  140. {
  141.     if(v_pIOPregs)
  142.     {
  143.         VirtualFree((void*)v_pIOPregs, sizeof(IOPreg), MEM_RELEASE);
  144.         v_pIOPregs=NULL;
  145.     }
  146.     if(v_pADCregs)
  147.     {   
  148.         VirtualFree((void*)v_pADCregs, sizeof(ADCreg), MEM_RELEASE);
  149.         v_pADCregs = NULL;
  150.     }        
  151.     if ( v_pDriverGlobals )
  152.     {
  153.         VirtualFree( v_pDriverGlobals,
  154.                      DRIVER_GLOBALS_PHYSICAL_MEMORY_SIZE ,
  155.                      MEM_RELEASE
  156.                     );
  157.         v_pDriverGlobals = NULL;
  158.     }    
  159. }
  160. //
  161. // PDD Internal Support Routines
  162. //
  163. /*++
  164.     @doc IN_TOUCH_DDSI INTERNAL DRIVERS PDD TOUCH_PANEL
  165.     @func VOID | PddpTouchPanelGetSamples |
  166.     Copies from the pen dma area the most recent point sample into the location
  167.     pointed to by pPointSamples.  During the copy the sample information is
  168.     adjusted to be consistent with the 12 bit pen data format.
  169.     Has the side effect of reinitializing ioPenPointer if we are near the
  170.     end of the pen sample area.
  171. --*/
  172. static
  173. void
  174. PddpTouchPanelGetSamples(
  175.     PTOUCHPANEL_POINT_SAMPLE pPointSamples //@PARM Pointer to where the samples will be stored.
  176.     )
  177. {
  178.     // ULONG   devDrvPointer;
  179.     ULONG   irg;
  180.     //
  181.     // Copy the samples to our buffer munging the data for the 12 bit
  182.     //  pen data format.
  183.     //
  184.     for ( irg = 0; irg < NUMBER_SAMPLES_PER_POINT; irg++ )
  185.     {
  186.         pPointSamples[ irg ].XSample = xbuf[irg];
  187.         pPointSamples[ irg ].YSample = ybuf[irg];
  188.     }
  189. }
  190. /*++
  191. Routine Description:
  192.     Gathers the most recent sample and evaluates the sample returing
  193.     the determined tip state and the `best guess' for the X and Y coordinates.
  194.     Note: Determined empirically that the variance of the X coordinate of the
  195.           first sample from all other samples is large enough that in order
  196.           to keep the nominal variance small, we discard the first sample.
  197.           Cases of a light touch that locks the ADC into
  198.           seeing X and Y coordinate samples of 0x277 regardless of how the pen
  199.           moves or presses have been seen. XXXXX
  200. Arguments:
  201.     pTipState   Pointer to where the tip state information will be returned.
  202.     pUnCalX     Pointer to where the x coordinate will be returned.
  203.     pUnCalY     Pointer to where the y coordinate will be returned.
  204. Return Value:
  205.     None.
  206. Autodoc Information:
  207.     @doc IN_TOUCH_DDI INTERNAL DRIVERS PDD TOUCH_PANEL
  208.     @func VOID | PddpTouchPanelEvaluateSamples |
  209.     Gathers the most recent sample and evaluates the sample returing
  210.     the determined tip state and the `best guess' for the X and Y coordinates.
  211. --*/
  212. static
  213. void
  214. PddpTouchPanelEvaluateSamples(
  215.     TOUCH_PANEL_SAMPLE_FLAGS *pSampleFlags, //@PARM Pointer to where the tip state information will be returned.
  216.     INT *pUncalX,      //@PARM Pointer to where the x coordinate will be returned.
  217. INT *pUncalY       //@PARM Pointer to where the y coordinate will be returned.
  218.     )
  219. {
  220.     LONG    dlXDiff0;
  221.     LONG    dlXDiff1;
  222.     LONG    dlXDiff2;
  223.     LONG    dlYDiff0;
  224.     LONG    dlYDiff1;
  225.     LONG    dlYDiff2;
  226.     TOUCHPANEL_POINT_SAMPLES rgPointSamples;
  227.     //
  228.     // Get the sample.
  229.     //
  230.     PddpTouchPanelGetSamples( rgPointSamples );
  231.     //
  232.     // Calcuate the differences for the X samples and insure that
  233.     // the resulting number is positive.
  234.     //
  235.     dlXDiff0 = rgPointSamples[ 0 ].XSample - rgPointSamples[ 1 ].XSample;
  236.     dlXDiff1 = rgPointSamples[ 1 ].XSample - rgPointSamples[ 2 ].XSample;
  237.     dlXDiff2 = rgPointSamples[ 2 ].XSample - rgPointSamples[ 0 ].XSample;
  238.     dlXDiff0 = dlXDiff0 > 0  ? dlXDiff0 : -dlXDiff0;
  239.     dlXDiff1 = dlXDiff1 > 0  ? dlXDiff1 : -dlXDiff1;
  240.     dlXDiff2 = dlXDiff2 > 0  ? dlXDiff2 : -dlXDiff2;
  241.     //
  242.     // Calcuate the differences for the Y samples and insure that
  243.     // the resulting number is positive.
  244.     //
  245.     dlYDiff0 = rgPointSamples[ 0 ].YSample - rgPointSamples[ 1 ].YSample;
  246.     dlYDiff1 = rgPointSamples[ 1 ].YSample - rgPointSamples[ 2 ].YSample;
  247.     dlYDiff2 = rgPointSamples[ 2 ].YSample - rgPointSamples[ 0 ].YSample;
  248.     dlYDiff0 = dlYDiff0 > 0  ? dlYDiff0 : -dlYDiff0;
  249.     dlYDiff1 = dlYDiff1 > 0  ? dlYDiff1 : -dlYDiff1;
  250.     dlYDiff2 = dlYDiff2 > 0  ? dlYDiff2 : -dlYDiff2;
  251.     //
  252.     // The final X coordinate is the average of coordinates of
  253.     // the two MIN of the differences.
  254.     //
  255.     if ( dlXDiff0 < dlXDiff1 )
  256.     {
  257.         if ( dlXDiff2 < dlXDiff0 )
  258.         {
  259.             *pUncalX = (ULONG)( ( ( rgPointSamples[ 0 ].XSample + rgPointSamples[ 2 ].XSample ) >> 1 ) );
  260.         }
  261.         else
  262.         {
  263.             *pUncalX = (ULONG)( ( ( rgPointSamples[ 0 ].XSample + rgPointSamples[ 1 ].XSample ) >> 1 ) );
  264.         }
  265.     }
  266.     else if ( dlXDiff2 < dlXDiff1 )
  267.     {
  268.             *pUncalX = (ULONG)( ( ( rgPointSamples[ 0 ].XSample + rgPointSamples[ 2 ].XSample ) >> 1 ) );
  269.     }
  270.     else
  271.     {
  272.             *pUncalX = (ULONG)( ( ( rgPointSamples[ 1 ].XSample + rgPointSamples[ 2 ].XSample ) >> 1 ) );
  273.     }
  274.     //
  275.     //
  276.     // The final Y coordinate is the average of coordinates of
  277.     // the two MIN of the differences.
  278.     //
  279.     if ( dlYDiff0 < dlYDiff1 )
  280.     {
  281.         if ( dlYDiff2 < dlYDiff0 )
  282.         {
  283.             *pUncalY = (ULONG)( ( ( rgPointSamples[ 0 ].YSample + rgPointSamples[ 2 ].YSample ) >> 1 ) );
  284.         }
  285.         else
  286.         {
  287.             *pUncalY = (ULONG)( ( ( rgPointSamples[ 0 ].YSample + rgPointSamples[ 1 ].YSample ) >> 1 ) );
  288.         }
  289.     }
  290.     else if ( dlYDiff2 < dlYDiff1 )
  291.     {
  292.             *pUncalY = (ULONG)( ( ( rgPointSamples[ 0 ].YSample + rgPointSamples[ 2 ].YSample ) >> 1 ) );
  293.     }
  294.     else
  295.     {
  296.             *pUncalY = (ULONG)( ( ( rgPointSamples[ 1 ].YSample + rgPointSamples[ 2 ].YSample ) >> 1 ) );
  297.     }
  298.     //
  299.     // Validate the coordinates and set the tip state accordingly.
  300.     //
  301.     if ( dlXDiff0 > DELTA_X_COORD_VARIANCE ||
  302.          dlXDiff1 > DELTA_X_COORD_VARIANCE ||
  303.          dlXDiff2 > DELTA_X_COORD_VARIANCE ||
  304.          dlYDiff0 > DELTA_Y_COORD_VARIANCE ||
  305.          dlYDiff1 > DELTA_Y_COORD_VARIANCE ||
  306.          dlYDiff2 > DELTA_Y_COORD_VARIANCE )
  307.     {
  308. //#ifdef DBGPOINTS1
  309.         DEBUGMSG( ZONE_SAMPLES, (TEXT("Sample 0: X 0x%x Y 0x%xrn"),
  310.                rgPointSamples[ 0 ].XSample, rgPointSamples[ 0 ].YSample) );
  311.         DEBUGMSG( ZONE_SAMPLES, (TEXT("Sample 1: X 0x%x Y 0x%xrn"),
  312.                rgPointSamples[ 1 ].XSample, rgPointSamples[ 1 ].YSample) );
  313.         DEBUGMSG( ZONE_SAMPLES, (TEXT("Sample 2: X 0x%x Y 0x%xrn"),
  314.                rgPointSamples[ 2 ].XSample, rgPointSamples[ 2 ].YSample) );
  315.         if ( dlXDiff0 > DELTA_X_COORD_VARIANCE )
  316.             DEBUGMSG( ZONE_SAMPLES, (TEXT("XDiff0 too large 0x%xrn"), dlXDiff0) );
  317.         if ( dlXDiff1 > DELTA_X_COORD_VARIANCE )
  318.             DEBUGMSG( ZONE_SAMPLES, (TEXT("XDiff1 too large 0x%xrn"), dlXDiff1) );
  319.         if ( dlXDiff2 > DELTA_X_COORD_VARIANCE )
  320.             DEBUGMSG( ZONE_SAMPLES, (TEXT("XDiff2 too large 0x%xrn"), dlXDiff2) );
  321.         if ( dlYDiff0 > DELTA_Y_COORD_VARIANCE )
  322.             DEBUGMSG( ZONE_SAMPLES, (TEXT("YDiff0 too large 0x%xrn"), dlYDiff0) );
  323.         if ( dlYDiff1 > DELTA_Y_COORD_VARIANCE )
  324.             DEBUGMSG( ZONE_SAMPLES, (TEXT("YDiff1 too large 0x%xrn"), dlYDiff1) );
  325.         if ( dlYDiff2 > DELTA_Y_COORD_VARIANCE )
  326.             DEBUGMSG( ZONE_SAMPLES, (TEXT("YDiff2 too large 0x%xrn"), dlYDiff2) );
  327. //#endif // DBGPOINTS1
  328.     }
  329.     else
  330.     {
  331.         //
  332.         // Sample is valid. Set tip state accordingly.
  333.         //
  334. *pSampleFlags = TouchSampleValidFlag | TouchSampleDownFlag;
  335.     }
  336.     DEBUGMSG( ZONE_SAMPLES, (TEXT("Filtered - SampleFlags: 0x%x X: 0x%x Y: 0x%xrn"),
  337.            *pSampleFlags, *pUncalX, *pUncalY) );
  338. }
  339. //
  340. // PddpSetupPenDownIntr()
  341. //
  342. // Set up the UCB to give pen down interrupts.  If EnableIntr flag is set, enable
  343. // the interrupt, otherwise, leave it disabled.  Note: - Caller must hold semaphore
  344. // when this function is called to protect access to the shared UCB registers.
  345. //
  346. BOOL
  347. PddpSetupPenDownIntr(BOOL EnableIntr)
  348. {
  349. // USHORT intrMask;
  350.     // I don't know why we enable the interrupt here.
  351.     
  352.     
  353.     //
  354.     // Setup ADC register
  355.     //
  356. // kang code
  357.     // Enable Prescaler,Prescaler,AIN5/7 fix,Normal,Disable read start,No operation
  358.     // Down,YM:GND,YP:AIN5,XM:Hi-z,XP:AIN7,XP pullup En,Normal,Waiting for interrupt mode
  359. // kang code end
  360.     // Down Int, YMON:0, nYPON:1, XMON:0;nXPON:1, Pullup:1, Auto Conv.,Waiting.
  361.     v_pADCregs->rADCTSC =(0<<8)|(1<<7)|(1<<6)|(0<<5)|(1<<4)|(0<<3)|(0<<2)|(3);
  362.     //v_pADCregs->rADCTSC=(1<<3)|(1<<2);
  363.     v_pADCregs->rADCDLY = ADC_DELAY_TIME;//default value for delay.    
  364.     v_pADCregs->rADCCON = (1<<14)|(ADCPRS<<6)|(7<<3); //setup channel, ADCPRS, Touch Input
  365. return TRUE;
  366. }
  367. //
  368. // PddpDisableClearPenDownIntr(void)
  369. //
  370. // Tell the UCB to clear pen down interrupts
  371. //
  372. BOOL
  373. PddpDisableClearPenDownIntr(void)
  374. {
  375.     // Acquire semaphore to prevent contention with audio driver while accessing UCB regs
  376.     TCHAUD_SEM_LOCK();
  377.     // Clear bit 12 in UCB address 3 to disable interrupts on falling tspx (tspx_fal_int)
  378.     // Read data from UCB address 0x03
  379.     if (! ASIC_AND_REG(3, ~((USHORT)0x1000)))
  380.         goto error_return;
  381.     // Clear the pen down interrupt
  382.     // Write UCB address 4 bit 12 to a 0
  383.     if (! ASIC_WRITE_REG(4, 0))
  384.         goto error_return;
  385.     // Write UCB address 4 bit 12 to a 1, to clear tspx interrupts
  386.     if (! ASIC_WRITE_REG(4, 0x1000))
  387.         goto error_return;
  388.     TCHAUD_SEM_UNLOCK();
  389.     return TRUE;
  390. error_return:
  391.     RETAILMSG(1,(TEXT("TchPdd: Error accessing UCB register!rn")));
  392.     TCHAUD_SEM_UNLOCK();
  393.     return FALSE;
  394. }
  395. //
  396. // DDSI Implementation
  397. //
  398. // @DOC EX_TOUCH_DDSI EXTERNAL DRIVERS TOUCH_DRIVER
  399. /* @FUNC   BOOL | TouchDriverCalibrationPointGet |
  400. Gives a single calibration point.
  401. @XREF
  402. <l TouchPanelReadCalibrationPoint.TouchPanelReadCalibrationPoint>
  403. <l TouchPanelSetCalibration.TouchPanelSetCalibration>
  404. <l TouchPanelReadCalibrationAbort.TouchPanelReadCalibrationAbort>
  405. @COMM
  406. This function is called to get a single calibration point, in screen
  407. coordinates, when the input system is calibrating the touch driver.  The input system
  408. will then draw a target on the screen for the user to press on.
  409. The driver may use the cDisplayX and cDisplayY to compute a coordinate.
  410. It does not need to remember this computed value internally since it will
  411. be passed back when the input system has collected all of the points and
  412. calls <l TouchPanelSetCalibration.TouchPanelSetCalibration>.
  413. */
  414. extern "C"
  415. BOOL
  416. TouchDriverCalibrationPointGet(
  417. TPDC_CALIBRATION_POINT *pTCP //@PARM pointer to returned calibration point
  418. )
  419. {
  420.     
  421. INT32 cDisplayWidth = pTCP -> cDisplayWidth;
  422. INT32 cDisplayHeight = pTCP -> cDisplayHeight;
  423. int CalibrationRadiusX = cDisplayWidth/20;
  424. int CalibrationRadiusY = cDisplayHeight/20;
  425. switch (pTCP -> PointNumber)
  426. {
  427. case 0:
  428. pTCP -> CalibrationX = cDisplayWidth/2;
  429. pTCP -> CalibrationY = cDisplayHeight/2;
  430. break;
  431. case 1:
  432. pTCP -> CalibrationX = CalibrationRadiusX*2;
  433. pTCP -> CalibrationY = CalibrationRadiusY*2;
  434. break;
  435. case 2:
  436. pTCP -> CalibrationX = CalibrationRadiusX*2;
  437. pTCP -> CalibrationY = cDisplayHeight - CalibrationRadiusY*2;
  438. break;
  439. case 3:
  440. pTCP -> CalibrationX = cDisplayWidth - CalibrationRadiusX*2;
  441. pTCP -> CalibrationY = cDisplayHeight - CalibrationRadiusY*2;
  442. break;
  443. case 4:
  444. pTCP -> CalibrationX = cDisplayWidth - CalibrationRadiusX*2;
  445. pTCP -> CalibrationY = CalibrationRadiusY*2;
  446. break;
  447. default:
  448. pTCP -> CalibrationX = cDisplayWidth/2;
  449. pTCP -> CalibrationY = cDisplayHeight/2;
  450. SetLastError(ERROR_INVALID_PARAMETER);
  451. return FALSE;
  452. }
  453. RETAILMSG(0,(TEXT("TouchDriverCalibrationPointGetrn")));
  454. RETAILMSG(0,(TEXT("cDisplayWidth : %4Xrn"),cDisplayWidth));
  455. RETAILMSG(0,(TEXT("cDisplayHeight : %4Xrn"),cDisplayHeight));
  456. RETAILMSG(0,(TEXT("CalibrationRadiusX : %4drn"),CalibrationRadiusX));
  457. RETAILMSG(0,(TEXT("CalibrationRadiusY : %4drn"),CalibrationRadiusY));
  458. RETAILMSG(0,(TEXT("pTCP -> PointNumber : %4drn"),pTCP -> PointNumber));
  459. RETAILMSG(0,(TEXT("pTCP -> CalibrationX : %4drn"),pTCP -> CalibrationX));
  460. RETAILMSG(0,(TEXT("pTCP -> CalibrationY : %4drn"),pTCP -> CalibrationY));
  461. return TRUE;
  462. }
  463. // @doc EX_TOUCH_DDSI EXTERNAL DRIVERS DDSI TOUCH_PANEL
  464. //
  465. // @func ULONG | DdsiTouchPanelGetDeviceCaps |
  466. //
  467. // Queries capabilities about the physical touch panel device.
  468. //
  469. // @parm ULONG | iIndex |
  470. //
  471. // Specifies the capability to query. They are one of the following:
  472. //
  473. // @flag TPDC_SAMPLERATE_ID |
  474. // The sample rate.
  475. // @flag TPDC_CALIBRATIONPOINTS_ID |
  476. // The X and Y coordinates used for calibration.
  477. // @flag TPDC_CALIBRATIONDATA_ID |
  478. // The X and Y coordinates used for calibration mapping.
  479. //
  480. // @parm LPVOID | lpOutput |
  481. // Points to the memory location(s) where the queried information
  482. // will be placed. The format of the memory referenced depends on
  483. // the setting of iIndex. If 0, returns the number of words
  484. // required for the output data.
  485. //
  486. // @rdesc
  487. // The return values is set to the amount of information supplied and depends
  488. // on the setting of the iIndex argument.
  489. //
  490. // @comm
  491. // Implemented in the PDD.
  492. //
  493. extern "C"
  494. BOOL
  495. DdsiTouchPanelGetDeviceCaps(
  496. INT iIndex,
  497.     LPVOID  lpOutput
  498.     )
  499. {
  500. if ( lpOutput == NULL )
  501. {
  502. ERRORMSG(1, (__TEXT("TouchPanelGetDeviceCaps: invalid parameter.rn")));
  503. SetLastError(ERROR_INVALID_PARAMETER);
  504. DebugBreak();
  505. return FALSE;
  506. }
  507. switch ( iIndex )
  508. {
  509. case TPDC_SAMPLE_RATE_ID:
  510. {
  511. TPDC_SAMPLE_RATE *pTSR = (TPDC_SAMPLE_RATE*)lpOutput;
  512. pTSR -> SamplesPerSecondLow = TOUCHPANEL_SAMPLE_RATE_LOW;
  513. pTSR -> SamplesPerSecondHigh = TOUCHPANEL_SAMPLE_RATE_HIGH;
  514. pTSR -> CurrentSampleRateSetting = CurrentSampleRateSetting;
  515. }
  516. break;
  517. case TPDC_CALIBRATION_POINT_COUNT_ID:
  518. {
  519. TPDC_CALIBRATION_POINT_COUNT *pTCPC = (TPDC_CALIBRATION_POINT_COUNT*)lpOutput;
  520. pTCPC -> flags = 0;
  521. pTCPC -> cCalibrationPoints = 5;
  522. }
  523. break;
  524. case TPDC_CALIBRATION_POINT_ID:
  525. return(TouchDriverCalibrationPointGet((TPDC_CALIBRATION_POINT*)lpOutput));
  526. default:
  527. ERRORMSG(1, (__TEXT("TouchPanelGetDeviceCaps: invalid parameter.rn")));
  528. SetLastError(ERROR_INVALID_PARAMETER);
  529. DebugBreak();
  530. return FALSE;
  531. }
  532. return TRUE;
  533. }
  534. //
  535. // @doc EX_TOUCH_DDSI EXTERNAL DRIVERS DDSI TOUCH_PANEL
  536. //
  537. // @func BOOL | DdsiTouchPanelSetMode |
  538. // Sets information about the physical touch panel device.
  539. //
  540. // @parm ULONG | iIndex |
  541. // Specifies the mode to set. They are one of the following:
  542. //
  543. // @flag TPSM_SAMPLERATE_HIGH_ID |
  544. // Sets the sample rate to the high rate.
  545. // @flag TPSM_SAMPLERATE_LOW_ID |
  546. // Sets the sample rate to the low rate.
  547. //
  548. // @parm LPVOID | lpInput |
  549. // Points to the memory location(s) where the update information
  550. // resides. The format of the memory referenced depends on the
  551. // Points to the memory location(s) where the queried information
  552. // will be placed.
  553. //
  554. // @rdesc
  555. // If the function succeeds the return value is TRUE, otherwise, it is FALSE.
  556. //
  557. // @comm
  558. // Implemented in the PDD.
  559. //
  560. BOOL
  561. DdsiTouchPanelSetMode(
  562. INT iIndex,
  563.     LPVOID  lpInput
  564.     )
  565. {
  566.     BOOL  ReturnCode = FALSE;
  567.     switch ( iIndex )
  568.     {
  569.         case TPSM_SAMPLERATE_LOW_ID:
  570.         case TPSM_SAMPLERATE_HIGH_ID:
  571.             SetLastError( ERROR_SUCCESS );
  572.             ReturnCode = TRUE;
  573.             break;
  574.         default:
  575.             SetLastError( ERROR_INVALID_PARAMETER );
  576.             break;
  577.     }
  578.     return ( ReturnCode );
  579. }
  580. //
  581. // @doc EX_TOUCH_DDSI EXTERNAL DRIVERS DDSI TOUCH_PANEL
  582. //
  583. // @func BOOL | DdsiTouchPanelEnable |
  584. // Powers up and initializes the touch panel hardware for operation.
  585. //
  586. // @rdesc
  587. // If the function succeeds, the return value is TRUE; otherwise, it is FALSE.
  588. //
  589. // @comm
  590. // Implemented in the PDD.
  591. //
  592. BOOL
  593. DdsiTouchPanelEnable(
  594.     VOID
  595.     )
  596. {
  597.     BOOL    Ret;
  598.     if(v_pIOPregs == NULL) {
  599.      v_pIOPregs = (volatile IOPreg *) 
  600.      VirtualAlloc(0,sizeof(IOPreg),MEM_RESERVE, PAGE_NOACCESS);
  601.      if(v_pIOPregs == NULL) {
  602.      ERRORMSG(1,(TEXT("For IOPreg: VirtualAlloc failed!rn")));
  603.     return (FALSE);
  604.     }
  605.      else {
  606.      if(!VirtualCopy((PVOID)v_pIOPregs,(PVOID)(IOP_BASE),sizeof(IOPreg),
  607.      PAGE_READWRITE | PAGE_NOCACHE )) {
  608.     ERRORMSG(1,(TEXT("For pIOPregs: VirtualCopy failed!rn")));
  609.                 PddpTouchPanelDeallocateVm();
  610.      return (FALSE);
  611.      }
  612.     }
  613. }
  614.     if(v_pADCregs == NULL) {
  615.      v_pADCregs = (volatile ADCreg *) 
  616.      VirtualAlloc(0,sizeof(ADCreg),MEM_RESERVE, PAGE_NOACCESS);
  617.      if(v_pADCregs == NULL) {
  618.      ERRORMSG(1,(TEXT("For ADCreg: VirtualAlloc failed!rn")));
  619.     return (FALSE);
  620.     }
  621.      else {
  622.      if(!VirtualCopy((PVOID)v_pADCregs,(PVOID)(ADC_BASE),sizeof(ADCreg),
  623.      PAGE_READWRITE | PAGE_NOCACHE )) {
  624.     ERRORMSG(1,(TEXT("For pADCregs: VirtualCopy failed!rn")));
  625.                 PddpTouchPanelDeallocateVm();
  626.      return (FALSE);
  627.      }
  628.     }
  629. }
  630.     if(v_pPWMregs == NULL) {
  631.      v_pPWMregs = (volatile PWMreg *) 
  632.      VirtualAlloc(0,sizeof(PWMreg),MEM_RESERVE, PAGE_NOACCESS);
  633.      if(v_pPWMregs == NULL) {
  634.      ERRORMSG(1,(TEXT("For PWMreg: VirtualAlloc failed!rn")));
  635.     return (FALSE);
  636.     }
  637.      else {
  638.      if(!VirtualCopy((PVOID)v_pPWMregs,(PVOID)(PWM_BASE),sizeof(PWMreg),
  639.      PAGE_READWRITE | PAGE_NOCACHE )) {
  640.     ERRORMSG(1,(TEXT("For PWMreg: VirtualCopy failed!rn")));
  641.      return (FALSE);
  642.      }
  643.     }
  644. }
  645.     if(v_pINTregs == NULL) {
  646.      v_pINTregs = (volatile INTreg *) 
  647.      VirtualAlloc(0,sizeof(INTreg),MEM_RESERVE, PAGE_NOACCESS);
  648.      if(v_pINTregs == NULL) {
  649.      ERRORMSG(1,(TEXT("For INTreg: VirtualAlloc failed!rn")));
  650.     return (FALSE);
  651.     }
  652.      else {
  653.      if(!VirtualCopy((PVOID)v_pINTregs,(PVOID)(INT_BASE),sizeof(INTreg),
  654.      PAGE_READWRITE | PAGE_NOCACHE )) {
  655.     ERRORMSG(1,(TEXT("For INTreg: VirtualCopy failed!rn")));
  656.      return (FALSE);
  657.      }
  658.     }
  659. }
  660.     //
  661.     // If the address space of the client process doesn't yet have the
  662.     //  mapping to the pen dma area; map it.  If the mapping fails
  663.     //  we return FALSE
  664.     //
  665.     if ( v_pDriverGlobals == NULL )
  666.     {
  667.         v_pDriverGlobals =
  668.             (PDRIVER_GLOBALS)
  669.                   VirtualAlloc( 0,
  670.                                 DRIVER_GLOBALS_PHYSICAL_MEMORY_SIZE,
  671.                                 MEM_RESERVE,
  672.                                 PAGE_NOACCESS
  673.                               );
  674.         if ( v_pDriverGlobals == NULL )
  675.         {
  676.             DEBUGMSG( ZONE_ERROR, (TEXT( "TouchPanelEnable: VirtualAlloc failed!rn")) );
  677.             PddpTouchPanelDeallocateVm();
  678.             return ( FALSE );
  679.         }
  680.         Ret = VirtualCopy( (LPVOID)v_pDriverGlobals,
  681.                            (LPVOID)DRIVER_GLOBALS_PHYSICAL_MEMORY_START,
  682.                            DRIVER_GLOBALS_PHYSICAL_MEMORY_SIZE,
  683.                            PAGE_READWRITE | PAGE_NOCACHE
  684.                            );
  685.         if ( Ret == FALSE )
  686.         {
  687.             DEBUGMSG( ZONE_ERROR, (TEXT( "TouchPanelEnable: VirtualCopy failed!rn")) );
  688.             PddpTouchPanelDeallocateVm();
  689.             return ( FALSE );
  690.         }
  691.     }
  692.     // Set up mutex for access to shared registers
  693.     if ((v_hTchAudMutex = CreateMutex(NULL, FALSE, TCHAUD_MUTEX_NAME)) == NULL) {
  694.         DEBUGMSG(ZONE_ERROR, (TEXT("TouchPanelEnable: Error %u in CreateMutexrn"),
  695.                               GetLastError()));
  696.         return ( FALSE );
  697.     }
  698.     // Power on touch panel
  699.     TouchPanelPowerOn();
  700.     // Setup pen down interrupts, but leave ints disabled until InterruptEnable().
  701.     TCHAUD_SEM_LOCK();
  702.     PddpSetupPenDownIntr(FALSE);
  703.     TCHAUD_SEM_UNLOCK();
  704.     return( TRUE );     // we always succeed!!!!!!
  705. }
  706. // @doc EX_TOUCH_DDSI EXTERNAL DRIVERS DDSI TOUCH_PANEL
  707. //
  708. // @func ULONG | DdsiTouchPanelDisable |
  709. // Powers down the touch panel device.
  710. //
  711. // @comm
  712. // Implemented in the PDD.
  713. //
  714. VOID
  715. DdsiTouchPanelDisable(
  716.     VOID
  717.     )
  718. {
  719.     //
  720.     // Check pointers in case the enable failed.
  721.     //
  722.     if(v_pADCregs == NULL) 
  723.         return ;
  724.     TouchPanelPowerOff();  // Power down the device
  725.     PddpTouchPanelDeallocateVm();  // free up any resources
  726. }
  727. //
  728. // @doc EX_TOUCH_DDSI EXTERNAL DRIVERS DDSI TOUCH_PANEL
  729. //
  730. // @func LONG | DdsiTouchPanelAttach |
  731. // This routine no longer does anything.  All functionallity has been moved
  732. // from here into DdsiTouchPanelEnable to allow this code to be statically
  733. // linked with GWE rather than existing as a DLL.  Technically, when built
  734. // as a DLL we should keep an attach count and only allow touh.dll to be
  735. // loaded once.  But, since we are loaded at boot time by GWE, there is
  736. // no real concern about multiple loads (unless gwe has a bug!).
  737. //
  738. // @rdesc
  739. // Always returns 0
  740. //
  741. // @comm
  742. // Implemented in the PDD.
  743. //
  744. LONG
  745. DdsiTouchPanelAttach(
  746.     VOID
  747.     )
  748. {
  749.     return( 1 );
  750. }
  751. //
  752. // @doc EX_TOUCH_DDSI EXTERNAL DRIVERS DDSI TOUCH_PANEL
  753. //
  754. // @func LONG | DdsiTouchPanelDetach |
  755. // See the descrition for attach.  All functionallity has been moved into
  756. // DdsiTouchPanelDisable.
  757. //
  758. // @rdesc
  759. // The updated global counter.  If the initializations failed, the returned
  760. // count is 0.
  761. //
  762. // @comm
  763. // Implemented in the PDD.
  764. //
  765. LONG
  766. DdsiTouchPanelDetach(
  767.     VOID
  768.     )
  769. {
  770.     return ( 0 );
  771. }
  772. #define COODI_Y
  773. //
  774. // @doc EX_TOUCH_DDSI EXTERNAL DRIVERS DDSI TOUCH_PANEL
  775. //
  776. // @func void | DdsiTouchPanelGetPoint |
  777. // Returns the most recently acquired point and its associated tip state
  778. // information.
  779. //
  780. // @parm PDDSI_TOUCHPANEL_TIPSTATE | pTipState |
  781. // Pointer to where the tip state information will be returned.
  782. // @parm PLONG | pUnCalX |
  783. // Pointer to where the x coordinate will be returned.
  784. // @parm PLONG | pUnCalY |
  785. // Pointer to where the y coordinate will be returned.
  786. //
  787. // @comm
  788. // Implmented in the PDD.
  789. //
  790. #if ( LCD_TYPE == TFT640_480 )
  791. #define TOUCH_MAX_X 890
  792. #define TOUCH_MIN_X 125
  793. #define TOUCH_MAX_Y 860
  794. #define TOUCH_MIN_Y 140
  795. #define TOUCH_X 640
  796. #define TOUCH_Y 480
  797. #else 
  798. #define TOUCH_MAX_X 900 // 950
  799. #define TOUCH_MIN_X 100 // 90
  800. #define TOUCH_MAX_Y 920 // 960 // 910
  801. #define TOUCH_MIN_Y 100 // 70 //50
  802. #define TOUCH_X 240
  803. #define TOUCH_Y 320
  804. #endif
  805. #define TOUCH_ERR 50
  806. static int second = 0;
  807. VOID Touch_CoordinateConversion(INT *px, INT *py)
  808. {
  809. INT TmpX, TmpY;
  810. INT TmpX0, TmpY0;
  811. TmpX0 = *px; TmpY0 = *py;
  812. TmpX = (*px >= TOUCH_MAX_X) ? (TOUCH_MAX_X-1) : *px;
  813. TmpY = (*py >= TOUCH_MAX_Y) ? (TOUCH_MAX_Y-1) : *py;
  814. TmpX -= TOUCH_MIN_X;
  815.     TmpY -= TOUCH_MIN_Y;
  816.     
  817.     TmpX = (TmpX) ? TmpX : 0;
  818.     TmpY = (TmpY) ? TmpY : 0;
  819.     
  820. *px = ((TmpX * TOUCH_X) / (TOUCH_MAX_X-TOUCH_MIN_X))*4;
  821. *py = ((TmpY * TOUCH_Y) / (TOUCH_MAX_Y-TOUCH_MIN_Y))*4;
  822. return;
  823. }
  824. VOID
  825. DdsiTouchPanelGetPoint(
  826. TOUCH_PANEL_SAMPLE_FLAGS *pTipStateFlags,
  827. INT *pUncalX,
  828. INT *pUncalY
  829.     )
  830. {
  831. ULONG status;
  832. // USHORT ioAdcCntr;
  833. // USHORT intrMask;
  834. static int SampleCount = 0;
  835. static TOUCH_PANEL_SAMPLE_FLAGS PrevStateFlags = TouchSampleIgnore;
  836. static INT PrevX = 0;
  837. static INT PrevY = 0;
  838. TOUCH_PANEL_SAMPLE_FLAGS TmpStateFlags;
  839. INT TmpX = 0;
  840. INT TmpY = 0;
  841. int i;
  842.     
  843.     //RETAILMSG(1, (TEXT(":::::::::::: DdsiTouchPanelGetPoint routine !!!rn")));
  844.     // Read the status passed back by the HAL
  845.     status = READ_REGISTER_ULONG( &(v_pDriverGlobals->tch.status) );
  846.     if(status == TOUCH_PEN_UP) {
  847. v_pADCregs->rADCTSC = 0xD3; // Set stylus down interrupt
  848. *pTipStateFlags = TouchSampleValidFlag;
  849. *pUncalX = PrevX;
  850. *pUncalY = PrevY;
  851. InterruptDone( gIntrTouchChanged );
  852. RETAILMSG(0, (TEXT("8 - (%d, %d) 0x%Xrn"), *pUncalX, *pUncalY, *pTipStateFlags));
  853.     }
  854.     else if(status == TOUCH_PEN_DOWN){
  855. *pTipStateFlags = TouchSampleIgnore;
  856. *pUncalX = PrevX;
  857. *pUncalY = PrevY;
  858. Touch_Timer0_Setup();
  859. InterruptDone( gIntrTouchChanged );
  860. RETAILMSG(0, (TEXT("9 - (%d, %d) 0x%Xrn"), *pUncalX, *pUncalY, *pTipStateFlags));
  861. }
  862. else {
  863. if( (v_pADCregs->rADCDAT0 & 0x8000) || (v_pADCregs->rADCDAT1 & 0x8000) ){
  864. v_pADCregs->rADCTSC = 0xD3; // Set stylus down interrupt
  865. *pTipStateFlags = TouchSampleValidFlag;
  866. *pUncalX = PrevX;
  867. *pUncalY = PrevY;
  868. InterruptDone( gIntrTouchChanged );
  869. RETAILMSG(0, (TEXT("91 - (%d, %d) 0x%Xrn"), *pUncalX, *pUncalY, *pTipStateFlags));
  870. }
  871. else{ // charlie
  872. // <Auto X-Position and Y-Position Read>
  873. for (i =0; i < 3; i++) {
  874. // v_pADCregs->rADCTSC=(0<<8)|(1<<7)|(1<<6)|(0<<5)|(1<<4)|(1<<3)|(1<<2)|(0);
  875. v_pADCregs->rADCTSC=(1<<3)|(1<<2);
  876. // Stylus Down,Don't care,Don't care,Don't care,Don't care,XP pullup Dis,Auto,No operation
  877. v_pADCregs->rADCCON|=0x1; // Start Auto conversion
  878. while(v_pADCregs->rADCCON & 0x1); //check if Enable_start is low
  879. while(!(0x8000&v_pADCregs->rADCCON)); // Check ECFLG
  880. ybuf[i] = 0x3ff - (0x3ff & v_pADCregs->rADCDAT0);
  881. xbuf[i] = 0x3ff & v_pADCregs->rADCDAT1;
  882. }
  883.   PddpTouchPanelEvaluateSamples( &TmpStateFlags, &TmpX, &TmpY);
  884. v_pADCregs->rADCTSC=(1<<8)|(1<<7)|(1<<6)|(0<<5)|(1<<4)|(0<<3)|(0<<2)|(3);
  885. Touch_CoordinateConversion(&TmpX, &TmpY);    
  886. if (Touch_Pen_filtering(&TmpX, &TmpY)) // Valid touch pen
  887.     {
  888.      //RETAILMSG(1, (TEXT("valid touch penrn")));
  889. *pTipStateFlags = TouchSampleValidFlag | TouchSampleDownFlag;
  890. *pTipStateFlags &= ~TouchSampleIgnore;
  891. }
  892. else // Invalid touch pen 
  893. {
  894.      //RETAILMSG(1, (TEXT("invalid touch penrn")));
  895. *pTipStateFlags = TouchSampleValidFlag;
  896. *pTipStateFlags |= TouchSampleIgnore;
  897. }
  898. *pUncalX = PrevX = TmpX;
  899. *pUncalY = PrevY = TmpY;
  900.     InterruptDone( gIntrTouch );
  901.    
  902.     RETAILMSG(0, (TEXT("0 - (%d, %d) 0x%Xrn"), *pUncalX, *pUncalY, *pTipStateFlags));
  903. }
  904. }
  905.     return;
  906. }
  907. #define FILTER_LIMIT 25
  908. static BOOL
  909. Touch_Pen_filtering(INT *px, INT *py)
  910. {
  911. BOOL RetVal = TRUE;
  912. // TRUE  : Valid pen sample
  913. // FALSE : Invalid pen sample
  914. static int count = 0;
  915. static INT x[2], y[2];
  916. INT TmpX, TmpY;
  917. INT dx, dy;
  918. count++;
  919. if (count > 2) 
  920. { // apply filtering rule
  921. count = 2;
  922. // average between x,y[0] and *px,y
  923. TmpX = (x[0] + *px) / 2;
  924. TmpY = (y[0] + *py) / 2;
  925. // difference between x,y[1] and TmpX,Y
  926. dx = (x[1] > TmpX) ? (x[1] - TmpX) : (TmpX - x[1]);
  927. dy = (y[1] > TmpY) ? (y[1] - TmpY) : (TmpY - y[1]);
  928. if ((dx > FILTER_LIMIT) || (dy > FILTER_LIMIT)) {
  929. // Invalid pen sample
  930. *px = x[1];
  931. *py = y[1]; // previous valid sample
  932. RetVal = FALSE;
  933. count = 0;
  934. else
  935. {
  936. // Valid pen sample
  937. x[0] = x[1]; y[0] = y[1];
  938. x[1] = *px; y[1] = *py; // reserve pen samples
  939. RetVal = TRUE;
  940. //RETAILMSG(1, (TEXT("RetVal = TRUErn")));
  941. }
  942. } else { // till 2 samples, no filtering rule
  943. x[0] = x[1]; y[0] = y[1];
  944. x[1] = *px; y[1] = *py; // reserve pen samples
  945. RetVal = FALSE; // <- TRUE jylee 2003.03.04 
  946. }
  947. //if (RetVal==FALSE) {
  948. //}
  949. return RetVal;
  950. }
  951. /*++
  952.  @func VOID | DdsiTouchPanelPowerHandler |
  953.  System power state notification.
  954.  @parm BOOL | bOff | TRUE, the system is powering off; FALSE, the system is powering up.
  955.  @comm
  956.  This routine is called in a kernel context and may not make any system
  957.  calls whatsoever.  It may read and write its own memory and that's about
  958.  it.  This routine is called by the MDD and also serves as an internal
  959.  helper routine for touch enable/disable.
  960.  @devnote This routine will run in kernel context, and may not make
  961.  any system calls.  If you can any subroutines inside here, make sure
  962.  that they also follow this restriction.
  963. --*/
  964. void
  965. DdsiTouchPanelPowerHandler(
  966. BOOL bOff
  967. )
  968. {
  969.     // USHORT mask;
  970.     // Set flag so we know to avoid system calls
  971.     bInPowerHandler = TRUE;
  972.     if (bOff) {
  973.         TouchPanelPowerOff();
  974.     }
  975.     else {
  976.         TouchPanelPowerOn();
  977.         PddpSetupPenDownIntr(TRUE);
  978.     }
  979.     bInPowerHandler = FALSE;
  980. }
  981. static void
  982. TouchPanelPowerOff()
  983. {
  984.     // Powering down, stop DMA and power off touch screen
  985.     RETAILMSG(0,(TEXT("Touch Power Offrn")));
  986. }
  987. static void
  988. TouchPanelPowerOn()
  989. {
  990.     DWORD tmp = 0;
  991. v_pIOPregs->rGPGCON &= ~((0x3 << 16));   
  992. v_pIOPregs->rGPGCON |=  ((0x2 << 16)); /* External Interrupt #16 Enable */
  993. v_pIOPregs->rEXTINT2 &= ~(0x7 << 8); // Configure EINT18 as Both Edge Mode
  994. v_pIOPregs->rEXTINT2 |=  (0x7 << 8);
  995. v_pIOPregs->rEINTPEND  = (1 << 16);
  996. v_pIOPregs->rEINTMASK &= ~(1 << 16);
  997. RETAILMSG(1,(TEXT("SDMMC config set rGPGCON: %xrn"), v_pIOPregs->rGPGCON));   
  998.     RETAILMSG(1,(TEXT("Touch Initrn")));
  999.     //
  1000.     // Setup GPIOs for touch
  1001.     // 
  1002.     
  1003.     // Clear GPG15, 14, 13, 12
  1004.     v_pIOPregs->rGPGCON &= ~((0x03 << 30)|(0x03 << 28)|(0x03 << 26)|(0x03 << 24));
  1005.     // Set GPG15 to use as nYPON, GPG14 to use as YMON, GPG13 to use as nXPON, GPG12 to use as XMON
  1006.     v_pIOPregs->rGPGCON |= ((0x01 << 30)|(0x01 << 28)|(0x01 << 26)|(0x01 << 24));
  1007.     // Disable full up function
  1008.     v_pIOPregs->rGPGUP |= ((0x01 << 15)|(0x01 << 14)|(0x01 << 13)|(0x01 << 12));
  1009.     
  1010.     //
  1011.     // Setup ADC register
  1012.     //
  1013.     // Down Int, YMON:0, nYPON:1, XMON:0;nXPON:1, Pullup:1, Auto Conv.,Waiting.
  1014.     v_pADCregs->rADCTSC = (0<<8)|(1<<7)|(1<<6)|(0<<5)|(1<<4)|(0<<3)|(0<<2)|(3);
  1015.     //v_pADCregs->rADCTSC=(1<<3)|(1<<2);
  1016. v_pADCregs->rADCDLY = ADC_DELAY_TIME;//default value for delay.    
  1017.     v_pADCregs->rADCCON = (1<<14)|(ADCPRS<<6)|(7<<3); //setup channel, ADCPRS, Touch Input
  1018. /*
  1019. RETAILMSG(1, (TEXT("v_pIOPregs->rGPBCON = 0x%Xrn"), v_pIOPregs->rGPBCON));
  1020. RETAILMSG(1, (TEXT("v_pIOPregs->rGPBDAT = 0x%Xrn"), v_pIOPregs->rGPBDAT));
  1021. RETAILMSG(1, (TEXT("v_pIOPregs->rGPBUP = 0x%Xrn"), v_pIOPregs->rGPBUP));
  1022. RETAILMSG(1, (TEXT("S2440PCLK = %drn"), S2440PCLK));
  1023. RETAILMSG(1, (TEXT("v_pPWMregs->rTCFG0 = 0x%Xrn"), v_pPWMregs->rTCFG0));
  1024. RETAILMSG(1, (TEXT("v_pPWMregs->rTCFG1 = 0x%Xrn"), v_pPWMregs->rTCFG1));
  1025. RETAILMSG(1, (TEXT("v_pPWMregs->rTCON = 0x%Xrn"), v_pPWMregs->rTCON));
  1026. RETAILMSG(1, (TEXT("v_pPWMregs->rTCNTB0 = 0x%Xrn"), v_pPWMregs->rTCNTB0));
  1027. RETAILMSG(1, (TEXT("v_pPWMregs->rTCMPB0 = 0x%Xrn"), v_pPWMregs->rTCMPB0));
  1028. RETAILMSG(1, (TEXT("v_pPWMregs->rTCNTO0 = 0x%Xrn"), v_pPWMregs->rTCNTO0));
  1029. RETAILMSG(1, (TEXT("v_pPWMregs->rTCNTB1 = 0x%Xrn"), v_pPWMregs->rTCNTB1));
  1030. RETAILMSG(1, (TEXT("v_pPWMregs->rTCMPB1 = 0x%Xrn"), v_pPWMregs->rTCMPB1));
  1031. RETAILMSG(1, (TEXT("v_pPWMregs->rTCNTO1 = 0x%Xrn"), v_pPWMregs->rTCNTO1));
  1032. RETAILMSG(1, (TEXT("v_pPWMregs->rTCNTB2 = 0x%Xrn"), v_pPWMregs->rTCNTB2));
  1033. RETAILMSG(1, (TEXT("v_pPWMregs->rTCMPB2 = 0x%Xrn"), v_pPWMregs->rTCMPB2));
  1034. RETAILMSG(1, (TEXT("v_pPWMregs->rTCNTO2 = 0x%Xrn"), v_pPWMregs->rTCNTO2));
  1035. RETAILMSG(1, (TEXT("v_pPWMregs->rTCNTB3 = 0x%Xrn"), v_pPWMregs->rTCNTB3));
  1036. RETAILMSG(1, (TEXT("v_pPWMregs->rTCMPB3 = 0x%Xrn"), v_pPWMregs->rTCMPB3));
  1037. RETAILMSG(1, (TEXT("v_pPWMregs->rTCNTO3 = 0x%Xrn"), v_pPWMregs->rTCNTO3));
  1038. RETAILMSG(1, (TEXT("v_pPWMregs->rTCNTB4 = 0x%Xrn"), v_pPWMregs->rTCNTB4));
  1039. RETAILMSG(1, (TEXT("v_pPWMregs->rTCNTO4 = 0x%Xrn"), v_pPWMregs->rTCNTO4));
  1040. */
  1041. return ;
  1042. }
  1043. static BOOL Touch_Timer0_Setup(void) {
  1044. unsigned int TmpTCON;
  1045.     //
  1046.     // We use Timer1 of PWM as OS Clock.
  1047.     // Disable Timer1 Init..
  1048.     v_pINTregs->rINTMSK |= BIT_TIMER1;     // Mask timer1 interrupt.
  1049.     v_pINTregs->rSRCPND = BIT_TIMER1;     // Clear pending bit
  1050.     v_pINTregs->rINTPND = BIT_TIMER1;
  1051.     //we operate our board with PCLK=203M/4 = 50750000Hz (50.75 Mhz)    
  1052. v_pPWMregs->rTCFG0 &= ~(0xff); /* Prescaler 1's Value */
  1053.     v_pPWMregs->rTCFG0 |= (PRESCALER); // prescaler value = 24 + 1
  1054.    v_pPWMregs->rTCFG1 &= ~(0xf<<4);
  1055. #if( SYS_TIMER_DIVIDER == 2 )
  1056.    v_pPWMregs->rTCFG1  |=  (0   << 4); /* 1/2 */
  1057. #elif ( SYS_TIMER_DIVIDER == 4 )
  1058.    v_pPWMregs->rTCFG1  |=  (1   << 4); /* 1/4 */
  1059. #elif ( SYS_TIMER_DIVIDER == 8 )
  1060.    v_pPWMregs->rTCFG1  |=  (2   << 4); /* 1/8 */
  1061. #elif ( SYS_TIMER_DIVIDER == 16 )
  1062.    v_pPWMregs->rTCFG1  |=  (3   << 4); /* 1/16 */
  1063. #endif
  1064. //    v_pPWMregs->rTCNTB1 = 1000; // about 10 ms(203M/4/2/(255+1))=10ms  
  1065.     v_pPWMregs->rTCNTB1 = (10 * (S2440PCLK / (PRESCALER+1) / SYS_TIMER_DIVIDER)) / 1000; // 10msec, Charlie
  1066.     v_pPWMregs->rTCMPB1 = 0;   
  1067. TmpTCON = v_pPWMregs->rTCON; // get TCON value to temp TCON register
  1068. TmpTCON &= ~0xf00;      // clear fields of Timer 1 
  1069. TmpTCON |= 0x200;      // interval mode(auto reload), update TCVNTB4, stop 
  1070. v_pPWMregs->rTCON = TmpTCON; // put the value to TCON register
  1071. TmpTCON = v_pPWMregs->rTCON; // get TCON value to temp TCON register
  1072. TmpTCON &= ~0xf00;      // clear fields of Timer 1 
  1073. TmpTCON |= 0x100;      // interval mode, no operation, start for Timer 4 
  1074. v_pPWMregs->rTCON = TmpTCON; // put the value to TCON register
  1075.     v_pINTregs->rINTMSK &= ~BIT_TIMER1;    
  1076.  
  1077.   return TRUE;   
  1078. }