Guest User

Untitled

a guest
Jul 10th, 2013
158
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 72.63 KB | None | 0 0
  1. //
  2. // Copyright (c) Microsoft Corporation.  All rights reserved.
  3. //
  4. //
  5. // Use of this sample source code is subject to the terms of the Microsoft
  6. // license agreement under which you licensed this sample source code. If
  7. // you did not accept the terms of the license agreement, you are not
  8. // authorized to use this sample source code. For the terms of the license,
  9. // please see the license agreement between you and Microsoft or, if applicable,
  10. // see the LICENSE.RTF on your install media or the root of your tools installation.
  11. // THE SAMPLE SOURCE CODE IS PROVIDED "AS IS", WITH NO WARRANTIES OR INDEMNITIES.
  12. //
  13. // All rights reserved ADENEO EMBEDDED 2010
  14. // Copyright (c) 2007, 2008 BSQUARE Corporation. All rights reserved.
  15.  
  16. /*
  17. ================================================================================
  18. *             Texas Instruments OMAP(TM) Platform Software
  19. * (c) Copyright Texas Instruments, Incorporated. All Rights Reserved.
  20. *
  21. * Use of this software is controlled by the terms and conditions found
  22. * in the license agreement under which this software has been supplied.
  23. *
  24. ================================================================================
  25. */
  26. #pragma warning(push)
  27. #pragma warning(disable: 4127 4201 4244 4101 4189)
  28. //------------------------------------------------------------------------------
  29. // Public
  30. //
  31. #include <windows.h>
  32. #include <types.h>
  33. #include <nkintr.h>
  34. #include <creg.hxx>
  35. #include <tchstream.h>
  36. #include <tchstreamddsi.h>
  37. #include <pm.h>
  38.  
  39. //------------------------------------------------------------------------------
  40. //
  41. //  Global:  dpCurSettings
  42. //
  43. DBGPARAM dpCurSettings = {
  44.     L"TouchDriver", {
  45.         L"Errors",      L"Warnings",    L"Function",    L"Info",
  46.         L"Undefined" ,  L"Undefined",   L"Undefined",   L"Undefined",
  47.         L"Undefined",   L"Undefined",   L"Undefined",   L"Undefined",
  48.         L"Undefined",   L"Undefined",   L"Undefined",   L"Undefined"
  49.     },
  50.     0x000B
  51. };
  52.  
  53. #if defined(BSP_LCD_PRISM0700W) || defined(BSP_LVDS_PRISM1010W)
  54.  
  55. //------------------------------------------------------------------------------
  56. // Platform
  57. //
  58. #include "omap.h"
  59. #include "am3517.h"
  60. #include <ceddk.h>
  61. #include <ceddkex.h>
  62. #include <oal.h>
  63. #include <oalex.h>
  64. #include <initguid.h>
  65. #include <sdk_gpio.h>
  66. #include "gpio_ioctls.h"
  67. #include "sdk_spi.h"
  68. #include "sdk_i2c.h"
  69. #include "omap_mcspi_regs.h"
  70. #include "touchscreenpdd.h"
  71.  
  72. //------------------------------------------------------------------------------
  73. // Defines
  74. //
  75. #define SPI1_DEVICE_NAME         L"SPI1:"
  76. //------------------------------------------------------------------------------
  77. // Debug zones
  78. //
  79. #ifndef SHIP_BUILD
  80.  
  81. #undef ZONE_ERROR
  82. #undef ZONE_WARN
  83. #undef ZONE_FUNCTION
  84. #undef ZONE_INFO
  85. #undef ZONE_TIPSTATE
  86.  
  87. #define ZONE_ERROR          DEBUGZONE(0)
  88. #define ZONE_WARN           DEBUGZONE(1)
  89. #define ZONE_FUNCTION       DEBUGZONE(2)
  90. #define ZONE_INFO           DEBUGZONE(3)
  91. #define ZONE_TIPSTATE       DEBUGZONE(4)
  92.  
  93. #endif
  94.  
  95. //------------------------------------------------------------------------------
  96. // globals
  97. //
  98. static DWORD                          s_mddContext;
  99. static PFN_TCH_MDD_REPORTSAMPLESET    s_pfnMddReportSampleSet;
  100.  
  101.  
  102. //==============================================================================
  103. // Function Name: TchPdd_Init
  104. //
  105. // Description: PDD should always implement this function. MDD calls it during
  106. //              initialization to fill up the function table with rest of the
  107. //              Helper functions.
  108. //
  109. // Arguments:
  110. //              [IN] pszActiveKey - current active touch driver key
  111. //              [IN] pMddIfc - MDD interface info
  112. //              [OUT]pPddIfc - PDD interface (the function table to be filled)
  113. //              [IN] hMddContext - mdd context (send to MDD in callback fn)
  114. //
  115. // Ret Value:   pddContext.
  116. //==============================================================================
  117. extern "C" DWORD WINAPI TchPdd_Init(LPCTSTR pszActiveKey,
  118.     TCH_MDD_INTERFACE_INFO* pMddIfc,
  119.     TCH_PDD_INTERFACE_INFO* pPddIfc,
  120.     DWORD hMddContext
  121.     )
  122. {
  123.     DWORD pddContext = 0;
  124.  
  125.     DEBUGMSG(ZONE_FUNCTION, (TEXT("TchPdd_Init+\r\n")));
  126.  
  127.     // Initialize once only
  128.     if (s_TouchDevice.bInitialized)
  129.     {
  130.         pddContext = (DWORD) &s_TouchDevice;
  131.         goto cleanup;
  132.     }
  133.  
  134.     // Create the event for touch panel events.
  135.     // If creation fails, return failure.
  136.     s_TouchDevice.hTouchPanelEvent = CreateEvent( NULL, FALSE, FALSE, NULL);
  137.     if (s_TouchDevice.hTouchPanelEvent  == NULL)
  138.     {
  139.         DEBUGMSG(ZONE_ERROR, (TEXT("ERROR: TOUCH: Touch Event Creation Failed\r\n")));
  140.         goto cleanup;
  141.     }
  142.  
  143.     // Remember the callback function pointer
  144.     s_pfnMddReportSampleSet = pMddIfc->pfnMddReportSampleSet;
  145.  
  146.     // Remember the mdd context
  147.     s_mddContext = hMddContext;
  148.  
  149.     s_TouchDevice.nSampleRate = DEFAULT_SAMPLE_RATE;
  150.     s_TouchDevice.dwPowerState = D0;
  151.     s_TouchDevice.dwSamplingTimeOut = INFINITE;
  152.     s_TouchDevice.bTerminateIST = FALSE;
  153.     s_TouchDevice.hTouchPanelEvent = 0;
  154.  
  155.     // Initialize HW
  156.     if (!PDDInitializeHardware(pszActiveKey))
  157.     {
  158.         DEBUGMSG(ZONE_ERROR,  (TEXT("ERROR: TOUCH: Failed to initialize touch PDD.\r\n")));
  159.         goto cleanup;
  160.     }
  161.  
  162.     // Get sysintr values from the OAL for PENIRQ interrupt
  163.     if (!KernelIoControl(
  164.             IOCTL_HAL_REQUEST_SYSINTR,
  165.             &s_TouchDevice.nPenIRQ,
  166.             sizeof(s_TouchDevice.nPenIRQ),
  167.             &s_TouchDevice.dwSysIntr,
  168.             sizeof(s_TouchDevice.dwSysIntr),
  169.             NULL
  170.             ) )
  171.     {
  172.         DEBUGMSG(ZONE_ERROR, (TEXT("ERROR: TOUCH: Failed to request the touch sysintr.\r\n")));
  173.         s_TouchDevice.dwSysIntr = (DWORD)SYSINTR_UNDEFINED;
  174.         goto cleanup;
  175.     }
  176.  
  177.     //Calibrate the screen, if the calibration data is not already preset in the registry
  178.     PDDStartCalibrationThread();
  179.  
  180.     //Initialization of the h/w is done
  181.     s_TouchDevice.bInitialized = TRUE;
  182.  
  183.     pddContext = (DWORD) &s_TouchDevice;
  184.  
  185.     // fill up pddifc table
  186.     pPddIfc->version        = 1;
  187.     pPddIfc->pfnDeinit      = TchPdd_Deinit;
  188.     pPddIfc->pfnIoctl       = TchPdd_Ioctl;
  189.     pPddIfc->pfnPowerDown   = TchPdd_PowerDown;
  190.     pPddIfc->pfnPowerUp     = TchPdd_PowerUp;
  191.  
  192.  
  193. cleanup:
  194.     DEBUGMSG(ZONE_FUNCTION, (TEXT("TchPdd_Init-\r\n")));
  195.     return pddContext;
  196. }
  197.  
  198.  
  199. //==============================================================================
  200. // Function Name: TchPdd_DeInit
  201. //
  202. // Description: MDD calls it during deinitialization. PDD should deinit hardware
  203. //              and deallocate memory etc.
  204. //
  205. // Arguments:   [IN] hPddContext. pddcontext returned in TchPdd_Init
  206. //
  207. // Ret Value:   None
  208. //
  209. //==============================================================================
  210. void WINAPI TchPdd_Deinit(DWORD hPddContext)
  211. {
  212.     DEBUGMSG(ZONE_FUNCTION, (TEXT("TchPdd_Deinit+\r\n")));
  213.  
  214.     // Remove-W4: Warning C4100 workaround
  215.     UNREFERENCED_PARAMETER(hPddContext);
  216.  
  217.     // Close the IST and release the resources before
  218.     // de-initializing.
  219.     PDDTouchPanelDisable();
  220.  
  221.     //  Shutdown HW
  222.     PDDDeinitializeHardware();
  223.  
  224.     // Release interrupt
  225.     if (s_TouchDevice.dwSysIntr != 0)
  226.         {
  227.         KernelIoControl(
  228.             IOCTL_HAL_RELEASE_SYSINTR,
  229.             &s_TouchDevice.dwSysIntr,
  230.             sizeof(s_TouchDevice.dwSysIntr),
  231.             NULL,
  232.             0,
  233.             NULL
  234.             );
  235.         }
  236.  
  237.     s_TouchDevice.bInitialized = FALSE;
  238.  
  239.  
  240.     DEBUGMSG(ZONE_FUNCTION, (TEXT("TchPdd_Deinit-\r\n")));
  241. }
  242.  
  243.  
  244. //==============================================================================
  245. // Function Name: TchPdd_Ioctl
  246. //
  247. // Description: The MDD controls the touch PDD through these IOCTLs.
  248. //
  249. // Arguments:   [IN] hPddContext. pddcontext returned in TchPdd_Init
  250. //              DOWRD dwCode. IOCTL code
  251. //              PBYTE pBufIn. Input Buffer pointer
  252. //              DWORD dwLenIn. Input buffer length
  253. //              PBYTE pBufOut. Output buffer pointer
  254. //              DWORD dwLenOut. Output buffer length
  255. //              PWORD pdwAcutalOut. Actual output buffer length.
  256. //
  257. // Ret Value:   TRUE if success else FALSE. SetLastError() if FALSE.
  258. //==============================================================================
  259. BOOL WINAPI TchPdd_Ioctl(DWORD hPddContext,
  260.       DWORD dwCode,
  261.       PBYTE pBufIn,
  262.       DWORD dwLenIn,
  263.       PBYTE pBufOut,
  264.       DWORD dwLenOut,
  265.       PDWORD pdwActualOut
  266. )
  267. {
  268.     DWORD dwResult = ERROR_INVALID_PARAMETER;
  269.  
  270.     // Remove-W4: Warning C4100 workaround
  271.     UNREFERENCED_PARAMETER(hPddContext);
  272.  
  273.     switch (dwCode)
  274.     {
  275.         //  Enable touch panel
  276.         case IOCTL_TOUCH_ENABLE_TOUCHPANEL:
  277.             DEBUGMSG(ZONE_FUNCTION, (L"TchPdd_Ioctl: IOCTL_TOUCH_ENABLE_TOUCHPANEL\r\n"));
  278.             PDDTouchPanelEnable();
  279.             dwResult = ERROR_SUCCESS;
  280.             break;
  281.  
  282.         //  Disable touch panel
  283.         case IOCTL_TOUCH_DISABLE_TOUCHPANEL:
  284.             DEBUGMSG(ZONE_FUNCTION, (L"TchPdd_Ioctl: IOCTL_TOUCH_DISABLE_TOUCHPANEL\r\n"));
  285.             PDDTouchPanelDisable();
  286.             dwResult = ERROR_SUCCESS;
  287.             break;
  288.  
  289.  
  290.         //  Get current sample rate
  291.         case IOCTL_TOUCH_GET_SAMPLE_RATE:
  292.             DEBUGMSG(ZONE_FUNCTION, (L"TchPdd_Ioctl: IOCTL_TOUCH_GET_SAMPLE_RATE\r\n"));
  293.  
  294.             //  Check parameter validity
  295.             if ((pBufOut != NULL) && (dwLenOut == sizeof(DWORD)))
  296.             {
  297.                 if (pdwActualOut)
  298.                     *pdwActualOut = sizeof(DWORD);
  299.  
  300.                 //  Get the sample rate
  301.                 *((DWORD*)pBufOut) = s_TouchDevice.nSampleRate;
  302.                 dwResult = ERROR_SUCCESS;
  303.             }
  304.             break;
  305.  
  306.         //  Set the current sample rate
  307.         case IOCTL_TOUCH_SET_SAMPLE_RATE:
  308.             DEBUGMSG(ZONE_FUNCTION, (L"TchPdd_Ioctl: IOCTL_TOUCH_SET_SAMPLE_RATE\r\n"));
  309.  
  310.             //  Check parameter validity
  311.             if ((pBufIn != NULL) && (dwLenIn == sizeof(DWORD)))
  312.             {
  313.                 //  Set the sample rate
  314.                 s_TouchDevice.nSampleRate = *((DWORD*)pBufIn);
  315.                 dwResult = ERROR_SUCCESS;
  316.  
  317.             }
  318.             break;
  319.  
  320.         //  Get touch properties
  321.         case IOCTL_TOUCH_GET_TOUCH_PROPS:
  322.             //  Check parameter validity
  323.             if ((pBufOut != NULL) && (dwLenOut == sizeof(TCH_PROPS)))
  324.             {
  325.                 if (pdwActualOut)
  326.                     *pdwActualOut = sizeof(TCH_PROPS);\
  327.  
  328.                 //  Fill out the touch driver properties
  329.                 ((TCH_PROPS*)pBufOut)->minSampleRate            = TOUCHPANEL_SAMPLE_RATE_LOW;
  330.                 ((TCH_PROPS*)pBufOut)->maxSampleRate            = TOUCHPANEL_SAMPLE_RATE_HIGH;
  331.                 ((TCH_PROPS*)pBufOut)->minCalCount              = 5;
  332.                 ((TCH_PROPS*)pBufOut)->maxSimultaneousSamples   = 1;
  333.                 ((TCH_PROPS*)pBufOut)->touchType                = TOUCHTYPE_MULTITOUCH;
  334.                 ((TCH_PROPS*)pBufOut)->calHoldSteadyTime        = CAL_HOLD_STEADY_TIME;
  335.                 ((TCH_PROPS*)pBufOut)->calDeltaReset            = CAL_DELTA_RESET;
  336.                 ((TCH_PROPS*)pBufOut)->xRangeMin                = RANGE_MIN;
  337.                 ((TCH_PROPS*)pBufOut)->xRangeMax                = RANGE_MAX;
  338.                 ((TCH_PROPS*)pBufOut)->yRangeMin                = RANGE_MIN;
  339.                 ((TCH_PROPS*)pBufOut)->yRangeMax                = RANGE_MAX;
  340.  
  341.                 dwResult = ERROR_SUCCESS;
  342.             }
  343.             break;
  344.  
  345.         //  Power management IOCTLs
  346.         case IOCTL_POWER_CAPABILITIES:
  347.             DEBUGMSG(ZONE_FUNCTION, (L"TchPdd_Ioctl: IOCTL_POWER_CAPABILITIES\r\n"));
  348.             if (pBufOut != NULL && dwLenOut == sizeof(POWER_CAPABILITIES))
  349.             {
  350.                 PPOWER_CAPABILITIES ppc = (PPOWER_CAPABILITIES) pBufOut;
  351.                 memset(ppc, 0, sizeof(*ppc));
  352.                 ppc->DeviceDx = DX_MASK(D0) | DX_MASK(D1) | DX_MASK(D2) | DX_MASK(D3) | DX_MASK(D4);
  353.  
  354.                 if (pdwActualOut)
  355.                     *pdwActualOut = sizeof(POWER_CAPABILITIES);
  356.  
  357.                 dwResult = ERROR_SUCCESS;
  358.             }
  359.             break;
  360.  
  361.         case IOCTL_POWER_GET:
  362.             DEBUGMSG(ZONE_FUNCTION, (L"TchPdd_Ioctl: IOCTL_POWER_GET\r\n"));
  363.             if(pBufOut != NULL && dwLenOut == sizeof(CEDEVICE_POWER_STATE))
  364.             {
  365.                 *(PCEDEVICE_POWER_STATE) pBufOut = (CEDEVICE_POWER_STATE) s_TouchDevice.dwPowerState;
  366.  
  367.                 if (pdwActualOut)
  368.                     *pdwActualOut = sizeof(CEDEVICE_POWER_STATE);
  369.  
  370.                 dwResult = ERROR_SUCCESS;
  371.             }
  372.             break;
  373.  
  374.         case IOCTL_POWER_SET:
  375.             DEBUGMSG(ZONE_FUNCTION, (L"TchPdd_Ioctl: IOCTL_POWER_SET\r\n"));
  376.             if(pBufOut != NULL && dwLenOut == sizeof(CEDEVICE_POWER_STATE))
  377.             {
  378.                 CEDEVICE_POWER_STATE dx = *(CEDEVICE_POWER_STATE*)pBufOut;
  379.                 if( VALID_DX(dx) )
  380.                 {
  381.                     DEBUGMSG(ZONE_FUNCTION, (L"TchPdd_Ioctl: IOCTL_POWER_SET = to D%u\r\n", dx));
  382.                     s_TouchDevice.dwPowerState = dx;
  383.  
  384.                     if (pdwActualOut)
  385.                         *pdwActualOut = sizeof(CEDEVICE_POWER_STATE);
  386.  
  387.                     //  Enable touchscreen for D0-D2; otherwise disable
  388.                     switch( dx )
  389.                     {
  390.                         case D0:
  391.                         case D1:
  392.                         case D2:
  393.                             //  Enable touchscreen
  394.                             PDDTouchPanelPowerHandler(FALSE);    //Enable Touch ADC
  395.                             break;
  396.  
  397.                         case D3:
  398.                         case D4:
  399.                             //  Disable touchscreen
  400.                             PDDTouchPanelPowerHandler(TRUE); //Disable Touch ADC
  401.                             break;
  402.  
  403.                         default:
  404.                             //  Ignore
  405.                             break;
  406.                     }
  407.  
  408.                     dwResult = ERROR_SUCCESS;
  409.                 }
  410.             }
  411.             break;
  412.  
  413.         default:
  414.             dwResult = ERROR_NOT_SUPPORTED;
  415.             break;
  416.     }
  417.  
  418.     if (dwResult != ERROR_SUCCESS)
  419.     {
  420.         SetLastError(dwResult);
  421.         return FALSE;
  422.     }
  423.     return TRUE;
  424. }
  425.  
  426.  
  427. //==============================================================================
  428. // Function Name: TchPdd_PowerUp
  429. //
  430. // Description: MDD passes xxx_PowerUp stream interface call to PDD.
  431. //
  432. // Arguments:   [IN] hPddContext. pddcontext returned in TchPdd_Init
  433. //
  434. // Ret Value:   None
  435. //==============================================================================
  436. void WINAPI TchPdd_PowerUp(
  437.     DWORD hPddContext
  438.     )
  439. {
  440.     DEBUGMSG(ZONE_FUNCTION, (TEXT("TchPdd_PowerUp+\r\n")));
  441.     // Remove-W4: Warning C4100 workaround
  442.     UNREFERENCED_PARAMETER(hPddContext);
  443.     DEBUGMSG(ZONE_FUNCTION, (TEXT("TchPdd_PowerUp-\r\n")));
  444. }
  445.  
  446. //==============================================================================
  447. // Function Name: TchPdd_PowerDown
  448. //
  449. // Description: MDD passes xxx_PowerDown stream interface call to PDD.
  450. //
  451. // Arguments:   [IN] hPddContext. pddcontext returned in TchPdd_Init
  452. //
  453. // Ret Value:   None
  454. //==============================================================================
  455. void WINAPI TchPdd_PowerDown(
  456.     DWORD hPddContext
  457.     )
  458. {
  459.     DEBUGMSG(ZONE_FUNCTION, (TEXT("TchPdd_PowerDown+\r\n")));
  460.     // Remove-W4: Warning C4100 workaround
  461.     UNREFERENCED_PARAMETER(hPddContext);
  462.     DEBUGMSG(ZONE_FUNCTION, (TEXT("TchPdd_PowerDown-\r\n")));
  463. }
  464.  
  465.  
  466. //==============================================================================
  467. //Internal Functions
  468. //==============================================================================
  469.  
  470. //==============================================================================
  471. // Function Name: PDDCalibrationThread
  472. //
  473. // Description: This function is called from the PDD Init to calibrate the screen.
  474. //              If the calibration data is already present in the registry,
  475. //              this step is skipped, else a call is made into the GWES for calibration.
  476. //
  477. // Arguments:   None.
  478. //
  479. // Ret Value:   Success(1), faliure(0)
  480. //==============================================================================
  481. static HRESULT PDDCalibrationThread()
  482. {
  483.     HKEY hKey;
  484.     DWORD dwType;
  485.     LONG lResult;
  486.     HANDLE hAPIs;
  487.  
  488.     DEBUGMSG(ZONE_FUNCTION, (TEXT("CalibrationThread+\r\n")));
  489.  
  490.     // try to open [HKLM\hardware\devicemap\touch] key
  491.     if (ERROR_SUCCESS != RegOpenKeyEx(HKEY_LOCAL_MACHINE, RK_HARDWARE_DEVICEMAP_TOUCH, 0, KEY_ALL_ACCESS, &hKey))
  492.     {
  493.         DEBUGMSG(ZONE_CALIBRATE, (TEXT("CalibrationThread: calibration: Can't find [HKLM/%s]\r\n"), RK_HARDWARE_DEVICEMAP_TOUCH));
  494.         return E_FAIL;
  495.     }
  496.  
  497.     // check for calibration data (query the type of data only)
  498.     lResult = RegQueryValueEx(hKey, RV_CALIBRATION_DATA, 0, &dwType, NULL, NULL);
  499.     RegCloseKey(hKey);
  500.     if (lResult == ERROR_SUCCESS)
  501.     {
  502.         // registry contains calibration data, return
  503.         return S_OK;
  504.     }
  505.  
  506.     hAPIs = OpenEvent(EVENT_ALL_ACCESS, FALSE, TEXT("SYSTEM/GweApiSetReady"));
  507.     if (hAPIs)
  508.     {
  509.         WaitForSingleObject(hAPIs, INFINITE);
  510.         CloseHandle(hAPIs);
  511.     }
  512.  
  513.     // Perform calibration
  514.     TouchCalibrate();
  515.  
  516.     // try to open [HKLM\hardware\devicemap\touch] key
  517.     if (ERROR_SUCCESS != RegOpenKeyEx(HKEY_LOCAL_MACHINE, RK_HARDWARE_DEVICEMAP_TOUCH, 0, KEY_ALL_ACCESS, &hKey))
  518.     {
  519.         DEBUGMSG(ZONE_CALIBRATE, (TEXT("CalibrationThread: calibration: Can't find [HKLM/%s]\r\n"), RK_HARDWARE_DEVICEMAP_TOUCH));
  520.         return E_FAIL;
  521.     }
  522.  
  523.     // display new calibration data
  524.     lResult = RegQueryValueEx(hKey, RV_CALIBRATION_DATA, 0, &dwType, NULL, NULL);
  525.     if (lResult == ERROR_SUCCESS)
  526.     {
  527.         TCHAR szCalibrationData[100];
  528.         DWORD Size = sizeof(szCalibrationData);
  529.  
  530.         RegQueryValueEx(hKey, RV_CALIBRATION_DATA, 0, &dwType, (BYTE *) szCalibrationData, (DWORD *) &Size);
  531.         DEBUGMSG(ZONE_CALIBRATE, (TEXT("touchp: calibration: new calibration data is \"%s\"\r\n"), szCalibrationData));
  532.         RETAILMSG(1, (TEXT("touchp: calibration: new calibration data is \"%s\"\r\n"), szCalibrationData));        
  533.     }
  534.     RegCloseKey(hKey);
  535.  
  536.     DEBUGMSG(ZONE_FUNCTION, (TEXT("CalibrationThread-\r\n")));
  537.  
  538.     return S_OK;
  539. }
  540.  
  541.  
  542. //==============================================================================
  543. // Function Name: PDDStartCalibrationThread
  544. //
  545. // Description: This function is creates the calibration thread with
  546. //              PDDCalibrationThread as entry.
  547. //
  548. // Arguments:   None.
  549. //
  550. // Ret Value:   None
  551. //==============================================================================
  552. void PDDStartCalibrationThread()
  553. {
  554.     HANDLE hThread;
  555.  
  556.     hThread = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)PDDCalibrationThread, NULL, 0, NULL);
  557.     // We don't need the handle, close it here
  558.     CloseHandle(hThread);
  559. }
  560.  
  561.  
  562. //==============================================================================
  563. // Function Name: PDDGetTouchIntPinState
  564. //
  565. // Description: This function is called from the IST to get the status of pen.
  566. //
  567. // Arguments:   None.
  568. //
  569. // Ret Value:   Status of the pen.
  570. //==============================================================================
  571. inline BOOL PDDGetTouchIntPinState()
  572. {
  573.     //  Return state of pen down
  574.     return( GPIOGetBit(s_TouchDevice.hGPIO, s_TouchDevice.nPenGPIO) == 1 );
  575. }
  576.  
  577. //==============================================================================
  578. // Function Name: PDDGetControllerData
  579. //
  580. // Description: This function is used to get the ADC data through SPI
  581. //
  582. // Arguments:   None.
  583. //
  584. // Ret Value:   Status of the pen.
  585. //==============================================================================
  586. void PDDGetControllerData(UINT32 control, UINT32 * read_data1, UINT32 * read_data2, UINT8 * tip)
  587. {
  588.  
  589.     UINT8 i2c_data[12];
  590.     DWORD len;
  591.  
  592.     len = I2CRead(s_TouchDevice.hI2C, 0x01, &i2c_data, sizeof(i2c_data));
  593.     if (len != sizeof(i2c_data)) {
  594.         ERRORMSG(ZONE_ERROR, (TEXT("I2CRead Failed!!\r\n")));
  595.         goto out;
  596.     }
  597.  
  598.     UINT16 px1, py1, pt1, px2, py2, pt2;
  599.  
  600.     px1 = i2c_data[2] << 8 | i2c_data[3];
  601.     py1 = i2c_data[0] << 8 | i2c_data[1];
  602.     pt1 = i2c_data[5] & 0x0f;
  603.  
  604.     px2 = i2c_data[8] << 8 | i2c_data[9];
  605.     py2 = i2c_data[6] << 8 | i2c_data[7];
  606.     pt2 = i2c_data[11] & 0x0f;
  607.  
  608.     px1 = RANGE_MAX_X - px1;
  609.     py1 = RANGE_MAX_Y - py1;
  610.     px2 = RANGE_MAX_X - px2;
  611.     py2 = RANGE_MAX_Y - py2;
  612.     *read_data1 = py1 << 16 | px1;
  613.     *read_data2 = py2 << 16 | px2;
  614.     *tip = pt2 << 4 | pt1;
  615.  
  616. out:
  617.     return;
  618. }
  619.  
  620. //==============================================================================
  621. // Function: PDDTouchPanelPowerHandler
  622. //
  623. // This function indicates to the driver that the system is entering
  624. // or leaving the suspend state.
  625. //
  626. // Parameters:
  627. //      bOff
  628. //          [in] TRUE indicates that the system is turning off. FALSE
  629. //          indicates that the system is turning on.
  630. //
  631. // Returns:
  632. //      None.
  633. //==============================================================================
  634. void PDDTouchPanelPowerHandler(BOOL boff)
  635. {
  636.     DEBUGMSG(ZONE_FUNCTION, (_T("PDDTouchPanelPowerHandler+\r\n")));
  637.  
  638.     if (s_TouchDevice.dwSysIntr != SYSINTR_NOP)
  639.         InterruptMask(s_TouchDevice.dwSysIntr, boff);
  640.  
  641.     DEBUGMSG(ZONE_FUNCTION, (_T("PDDTouchPanelPowerHandler-\r\n")));
  642.  
  643.     return;
  644. }
  645.  
  646. //==============================================================================
  647. // Function Name: PDDTouchPanelGetPoint
  648. //
  649. // Description: This function is used to read the touch coordinates from the h/w.
  650. //
  651. // Arguments:
  652. //                  TOUCH_PANEL_SAMPLE_FLAGS * - Pointer to the sample flags. This flag is filled with the
  653. //                                                                      values TouchSampleDownFlag or TouchSampleValidFlag;
  654. //                  INT * - Pointer to the x coordinate of the sample.
  655. //                  INT * - Pointer to the y coordinate of the sample.
  656. //
  657. // Ret Value:   None
  658. //==============================================================================
  659. void PDDTouchPanelGetPoint(
  660.     TOUCH_PANEL_SAMPLE_FLAGS *pTipStateFlags1,
  661.     TOUCH_PANEL_SAMPLE_FLAGS *pTipStateFlags2,
  662.     INT *pUncalX1,
  663.     INT *pUncalY1,
  664.     INT *pUncalX2,
  665.     INT *pUncalY2
  666.     )
  667. {
  668.     // MDD needs us to hold on to last valid sample and previous pen state.
  669.     static USHORT usLastFilteredX       = 0;    // This holds the previous X sample
  670.     static USHORT usLastFilteredY       = 0;    // This holds the previous Y sample
  671.     static USHORT usSavedFilteredX      = 0;    // This holds the last reported X sample
  672.     static USHORT usSavedFilteredY      = 0;    // This holds the last reported Y sample
  673.     static BOOL bPrevReportedPenDown1    = FALSE;
  674.     static BOOL bPrevReportedPenDown2    = FALSE;
  675.     static DWORD DelayedSampleCount     = 0;
  676.  
  677.     BOOL bReportedPenDown1              = FALSE; // This indicates if we are reporting pen down to the mdd
  678.     BOOL bReportedPenDown2              = FALSE; // This indicates if we are reporting pen down to the mdd
  679.     BOOL bActualPenDown                 = FALSE; // This indicates if the pen is actually down, whether we report or not
  680.     UINT32 xpos1 = 0;
  681.     UINT32 ypos1 = 0;
  682.     UINT32 xpos2 = 0;
  683.     UINT32 ypos2 = 0;
  684.     UINT8  tip  = 0;
  685.  
  686.     DEBUGMSG(ZONE_FUNCTION&&ZONE_SAMPLES, (TEXT("PDDTouchPanelGetPoint+\r\n")));
  687. //  RETAILMSG(1, (L"PDDTouchPanelGetPoint\r\n"));
  688.  
  689.     // By default, any sample returned will be ignored.
  690.     *pTipStateFlags1 = TouchSampleIgnore;
  691.     *pTipStateFlags2 = TouchSampleIgnore;
  692.  
  693.     // Check if pen data are available If so, get the data.
  694.     // Note that we always return data from the previous sample to avoid returning data nearest
  695.     // the point where the pen is going up.  Data during light touches is not accurate and should
  696.     // normally be rejected.  Without the ability to do pressure measurement, we are limited to
  697.     // rejecting points near the beginning and end of the pen down period.
  698.     bActualPenDown  = PDDGetTouchIntPinState();
  699.     if (bActualPenDown == TRUE)
  700.     {
  701.         PDDGetTouchData(&xpos1, &ypos1, &xpos2, &ypos2, &tip);
  702.         bReportedPenDown1 = ((tip & 0x0f) == 1) ? TRUE : FALSE;
  703.         bReportedPenDown2 = ((tip & 0xf0) == 0x10) ? TRUE : FALSE;
  704.  
  705.     }
  706.  
  707.     // Check if we have valid data to report to the MDD.
  708.     if (bReportedPenDown1)
  709.     {
  710.         *pUncalX1 = xpos1;
  711.         *pUncalY1 = ypos1;
  712.  
  713.         DEBUGMSG(ZONE_SAMPLES, ( TEXT( "X1(0x%X) Y1(0x%X)\r\n" ), *pUncalX1, *pUncalY1 ) );
  714.  
  715.         // Store reported pen state.
  716.         *pTipStateFlags1 = TouchSampleDownFlag | TouchSampleValidFlag;
  717.     }
  718.     else    // Otherwise, assume pen is up.
  719.     {
  720.         // Check if previously down and valid.
  721.         if ( bPrevReportedPenDown1 )
  722.         {
  723.             DEBUGMSG(ZONE_TIPSTATE, ( TEXT( "Pen Up!\r\n" ) ) );
  724.             *pUncalX1 = xpos1;
  725.             *pUncalY1 = ypos1;
  726.             *pTipStateFlags1 = TouchSampleValidFlag;
  727.         }
  728.         DEBUGMSG(ZONE_SAMPLES, ( TEXT( "Point: (%d,%d)\r\n" ), *pUncalX1, *pUncalY1 ) );
  729.     }
  730.  
  731.     // Check if we have valid data to report to the MDD.
  732.     if (bReportedPenDown2)
  733.     {
  734.         *pUncalX2 = xpos2;
  735.         *pUncalY2 = ypos2;
  736.  
  737.         DEBUGMSG(ZONE_SAMPLES, ( TEXT( "X2(0x%X) Y2(0x%X)\r\n" ), *pUncalX2, *pUncalY2 ) );
  738.  
  739.         // Store reported pen state.
  740.         *pTipStateFlags2 = TouchSampleDownFlag | TouchSampleValidFlag;
  741.     }
  742.     else    // Otherwise, assume pen is up.
  743.     {
  744.         // Check if previously down and valid.
  745.         if ( bPrevReportedPenDown2 )
  746.         {
  747.             DEBUGMSG(ZONE_TIPSTATE, ( TEXT( "Pen Up!\r\n" ) ) );
  748.             *pUncalX2 = xpos2;
  749.             *pUncalY2 = ypos2;
  750.             *pTipStateFlags1 = TouchSampleValidFlag;
  751.         }
  752.         DEBUGMSG(ZONE_SAMPLES, ( TEXT( "Point: (%d,%d)\r\n" ), *pUncalX2, *pUncalY2 ) );
  753.     }
  754.  
  755.     // Save current reported pen state.
  756.     bPrevReportedPenDown1 = bReportedPenDown1;
  757.     bPrevReportedPenDown2 = bReportedPenDown2;
  758.  
  759.     // Set up interrupt/timer for next sample
  760.     if (bActualPenDown)
  761.     {
  762.         // Reset the delayed sample counter
  763.         DelayedSampleCount = 0;
  764.         usLastFilteredX = 0;
  765.         usLastFilteredY = 0;
  766.  
  767.         UINT8 i2c_data;
  768.         DWORD len;
  769.  
  770.         // write scan_complete to touch controller.
  771.         i2c_data = 0x00;
  772.         len = I2CWrite(s_TouchDevice.hI2C, 0x11, &i2c_data, sizeof(UINT8));
  773.         if (len != sizeof(UINT8)) {
  774.             ERRORMSG(ZONE_ERROR, (TEXT("I2CWrite Failed!!\r\n")));
  775.             goto out;
  776.         }
  777.  
  778.         // Pen up so set MDD timeout for interrupt mode.
  779.         s_TouchDevice.dwSamplingTimeOut = INFINITE;
  780.  
  781.         // Set the proper state for the next interrupt.
  782.         InterruptDone( s_TouchDevice.dwSysIntr );
  783.     }
  784.  
  785. out:
  786.     DEBUGMSG(ZONE_FUNCTION&&ZONE_SAMPLES, (TEXT("PDDTouchPanelGetPoint-\r\n")));
  787.  
  788.     return;
  789. }
  790.  
  791. //==============================================================================
  792. // Function Name: PDDGetTouchData
  793. //
  794. // Description: Helper function to read 3 samples and find the average of them.
  795. //
  796. // Arguments:
  797. //                  INT * - Pointer to the x coordinate of the sample.
  798. //                  INT * - Pointer to the y coordinate of the sample.
  799. //
  800. // Ret Value:   TRUE
  801. //==============================================================================
  802. BOOL PDDGetTouchData(UINT32 * xpos1,  UINT32 * ypos1, UINT32 * xpos2,  UINT32 * ypos2, UINT8 * tip)
  803. {
  804.     UINT32 tempdata1 = 0;
  805.     UINT32 tempdata2 = 0;
  806.     UINT8  temptip  = 0;
  807.     UINT16 px1, py1, px2, py2;
  808.     UINT32 pxAvg = 0, pyAvg = 0;
  809.     int i;
  810.     int iAvg = 0;
  811.  
  812.     DEBUGMSG(ZONE_FUNCTION, ( TEXT("PDDGetTouchData+\r\n" )) );
  813.  
  814.     PDDGetControllerData(0, &tempdata1, &tempdata2, &temptip);
  815.     px1 = tempdata1 & 0x0000FFFF;
  816.     py1 = (tempdata1 & 0xFFFF0000) >> 16;
  817.     px2 = tempdata2 & 0x0000FFFF;
  818.     py2 = (tempdata2 & 0xFFFF0000) >> 16;
  819.  
  820.     *xpos1 = px1;
  821.     *ypos1 = py1;
  822.     *xpos2 = px2;
  823.     *ypos2 = py2;
  824.     *tip = temptip;
  825.  
  826.     // Possibly Pen Up, give pen status detection a chance to debounce
  827.     if(temptip == 0 && s_TouchDevice.PenUpDebounceMS) Sleep(s_TouchDevice.PenUpDebounceMS);
  828.  
  829.     DEBUGMSG(ZONE_FUNCTION, ( TEXT("PDDGetTouchData-\r\n" )) );
  830.  
  831.     return TRUE;
  832. }
  833.  
  834.  
  835. //==============================================================================
  836. // Function Name: PDDTouchIST
  837. //
  838. // Description: This is the IST which waits on the touch event or Time out value.
  839. //              Normally the IST waits on the touch event infinitely, but once the
  840. //              pen down condition is recognized the time out interval is changed
  841. //              to dwSamplingTimeOut.
  842. //
  843. // Arguments:
  844. //                  PVOID - Reseved not currently used.
  845. //
  846. // Ret Value:   None
  847. //==============================================================================
  848. ULONG PDDTouchIST(PVOID   reserved)
  849. {
  850.     TOUCH_PANEL_SAMPLE_FLAGS    SampleFlags1 = 0;
  851.     TOUCH_PANEL_SAMPLE_FLAGS    SampleFlags2 = 0;
  852.     CETOUCHINPUT input;
  853.     INT32                       RawX1, RawY1, RawX2, RawY2;
  854.  
  855.     // Remove-W4: Warning C4100 workaround
  856.     UNREFERENCED_PARAMETER(reserved);
  857.  
  858.     DEBUGMSG(ZONE_TOUCH_IST, (L"PDDTouchIST: IST thread started\r\n"));
  859.  
  860.     //  Loop until told to stop
  861.     while(!s_TouchDevice.bTerminateIST)
  862.     {
  863.         //  Wait for touch IRQ, timeout or terminate flag
  864.        WaitForSingleObject(s_TouchDevice.hTouchPanelEvent, s_TouchDevice.dwSamplingTimeOut);
  865.  
  866.         //  Check for terminate flag
  867.         if (s_TouchDevice.bTerminateIST)
  868.             break;
  869.  
  870.         PDDTouchPanelGetPoint( &SampleFlags1, &SampleFlags2, &RawX1, &RawY1, &RawX2, &RawY2);
  871.  
  872.         if ( SampleFlags1 & SampleFlags2 & TouchSampleIgnore )
  873.         {
  874.             // do nothing, not a valid sample
  875.             continue;
  876.         }
  877.  
  878.         if ( !(SampleFlags1 & TouchSampleIgnore) )
  879.         {
  880.             //convert x-y coordination to one sample set before sending it to touch MDD.
  881.             if(PrismConvertTouchPanelToTouchInput(SampleFlags1, RawX1, RawY1, &input, 0))
  882.             {
  883.                 //send this 1 sample to mdd
  884.                 s_pfnMddReportSampleSet(s_mddContext, 1, &input);
  885.             }
  886.  
  887.             DEBUGMSG(ZONE_TOUCH_SAMPLES, ( TEXT( "Sample:   (%d, %d)\r\n" ), RawX1, RawY1 ) );
  888.         }
  889.         if ( !(SampleFlags2 & TouchSampleIgnore) )
  890.         {
  891.             //convert x-y coordination to one sample set before sending it to touch MDD.
  892.             if(PrismConvertTouchPanelToTouchInput(SampleFlags2, RawX2, RawY2, &input, 1))
  893.             {
  894.                 //send this 1 sample to mdd
  895.                 s_pfnMddReportSampleSet(s_mddContext, 1, &input);
  896.             }
  897.  
  898.             DEBUGMSG(ZONE_TOUCH_SAMPLES, ( TEXT( "Sample:   (%d, %d)\r\n" ), RawX2, RawY2 ) );
  899.         }
  900.  
  901.     }
  902.  
  903.     // IST thread terminating
  904.     InterruptDone(s_TouchDevice.dwSysIntr);
  905.     InterruptDisable(s_TouchDevice.dwSysIntr);
  906.  
  907.     CloseHandle(s_TouchDevice.hTouchPanelEvent);
  908.     s_TouchDevice.hTouchPanelEvent = NULL;
  909.  
  910.     DEBUGMSG(ZONE_TOUCH_IST, (L"PDDTouchIST: IST thread ending\r\n"));
  911.  
  912.     return ERROR_SUCCESS;
  913. }
  914.  
  915. //==============================================================================
  916. // Function Name: PDDInitializeHardware
  917. //
  918. // Description: This routine configures the SPI channel and GPIO pin for interrupt mode.
  919. //
  920. // Arguments:  None
  921. //
  922. // Ret Value:   TRUE - Success
  923. //                   FAIL - Failure
  924. //==============================================================================
  925. BOOL PDDInitializeHardware(LPCTSTR pszActiveKey)
  926. {
  927.     BOOL   rc = FALSE;
  928.     DWORD  config;
  929.     UINT32 spiBuffer;
  930.     UINT32 xPos, yPos;
  931.  
  932.     DEBUGMSG(ZONE_FUNCTION, (TEXT("PDDInitializeHardware+\r\n")));
  933.  
  934.     if (IsDVIMode())
  935.         goto cleanup;
  936.  
  937.     // Read parameters from registry
  938.     if (GetDeviceRegistryParams(
  939.             pszActiveKey,
  940.             &s_TouchDevice,
  941.             dimof(s_deviceRegParams),
  942.             s_deviceRegParams) != ERROR_SUCCESS)
  943.     {
  944.         DEBUGMSG(ZONE_ERROR, (TEXT("ERROR: PDDInitializeHardware: Error reading from Registry.\r\n")));
  945.         goto cleanup;
  946.     }
  947.  
  948.     // Open GPIO driver
  949.     s_TouchDevice.hGPIO = GPIOOpen();
  950.     if (s_TouchDevice.hGPIO == NULL)
  951.     {
  952.         DEBUGMSG(ZONE_ERROR, (TEXT("ERROR: PDDInitializeHardware: Failed open GPIO device driver\r\n")));
  953.         goto cleanup;
  954.     }
  955.  
  956.     // RESET LOW
  957.     GPIOClrBit(s_TouchDevice.hGPIO, 176);
  958.     GPIOSetMode(s_TouchDevice.hGPIO, 176, GPIO_DIR_OUTPUT);
  959.     Sleep ( 10 );
  960.     GPIOSetBit(s_TouchDevice.hGPIO, 176);   // RESET HIGH
  961.     Sleep ( 130 );
  962.    
  963.     // Setup nPENIRQ for input mode, raising edge detect, debounce enable
  964.     GPIOSetMode(s_TouchDevice.hGPIO, s_TouchDevice.nPenGPIO, GPIO_DIR_INPUT|GPIO_INT_LOW_HIGH|GPIO_DEBOUNCE_ENABLE);
  965.  
  966.     // Get the IRQ for the GPIO
  967.     s_TouchDevice.nPenIRQ = GPIOGetSystemIrq(s_TouchDevice.hGPIO, s_TouchDevice.nPenGPIO);
  968.     RETAILMSG(1, (L"s_TouchDevice.nPenGPIO=%d\r\n", s_TouchDevice.nPenGPIO));
  969.     // Set debounce time on GPIO
  970.     IOCTL_GPIO_SET_DEBOUNCE_TIME_IN debounce;
  971.  
  972.     debounce.gpioId = s_TouchDevice.nPenGPIO;
  973.     debounce.debounceTime = 10;
  974.  
  975.     // Open I2C driver
  976.     s_TouchDevice.hI2C = I2COpen(OMAP_DEVICE_I2C2);
  977.     if (s_TouchDevice.hI2C == NULL)
  978.     {
  979.         DEBUGMSG(ZONE_ERROR, (TEXT("ERROR: PDDInitializeHardware: Failed open I2C device driver\r\n")));
  980.         goto cleanup;
  981.     }
  982.  
  983.     I2CSetSlaveAddress(s_TouchDevice.hI2C, 0x10);
  984.     I2CSetSubAddressMode(s_TouchDevice.hI2C, I2C_SUBADDRESS_MODE_8);
  985.     I2CSetBaudIndex(s_TouchDevice.hI2C, SLOWSPEED_MODE);
  986.  
  987.     UINT8 i2c_data = 0;
  988.     DWORD len = 0;
  989.  
  990.     // read one byte thru i2c
  991.     len = I2CRead(s_TouchDevice.hI2C, 0x0e, &i2c_data, sizeof(UINT8));
  992.     RETAILMSG(1, (L"i2c_data : 0x0e=%04X, len=%x\r\n", i2c_data, len));
  993.     len = I2CRead(s_TouchDevice.hI2C, 0x0f, &i2c_data, sizeof(UINT8));
  994.     RETAILMSG(1, (L"i2c_data : 0x0f=%04X, len=%x\r\n", i2c_data, len));
  995.    
  996.     if (len != sizeof(UINT8)) {
  997.         ERRORMSG(ZONE_ERROR, (TEXT("I2CRead Failed!!\r\n")));
  998.         goto cleanup;
  999.     }
  1000.  
  1001.     // write scan_complete to clean up interrupt line.
  1002.     //i2c_data = 0x80;
  1003.     //len = I2CWrite(s_TouchDevice.hI2C, 0x10, &i2c_data, sizeof(UINT8));
  1004.     //Sleep(130);
  1005.  
  1006.     // write scan_complete to clean up interrupt line.
  1007.     i2c_data = 0x00;
  1008.     len = I2CWrite(s_TouchDevice.hI2C, 0x11, &i2c_data, sizeof(UINT8));
  1009.     if (len != sizeof(UINT8)) {
  1010.         ERRORMSG(ZONE_ERROR, (TEXT("I2CWrite Failed!!\r\n")));
  1011.         goto cleanup;
  1012.     }
  1013.  
  1014.     // Done
  1015.     rc = TRUE;
  1016.  
  1017. cleanup:
  1018.  
  1019.     DEBUGMSG(ZONE_FUNCTION, (TEXT("PDDInitializeHardware-\r\n")));
  1020.     if( rc == FALSE )
  1021.     {
  1022.         PDDDeinitializeHardware();
  1023.     }
  1024.  
  1025.     return rc;
  1026. }
  1027.  
  1028.  
  1029. //==============================================================================
  1030. // Function Name: PDDDeinitializeHardware
  1031. //
  1032. // Description: This routine Deinitializes the h/w by closing the SPI channel and GPIO pin
  1033. //
  1034. // Arguments:  None
  1035. //
  1036. // Ret Value:   None
  1037. //==============================================================================
  1038. VOID PDDDeinitializeHardware()
  1039. {
  1040.     DEBUGMSG(ZONE_FUNCTION, (TEXT("PDDDeinitializeHardware+\r\n")));
  1041.  
  1042.     // Close I2C device
  1043.     if (s_TouchDevice.hI2C != NULL)
  1044.     {
  1045.         I2CClose(s_TouchDevice.hI2C);
  1046.         s_TouchDevice.hI2C = NULL;
  1047.     }
  1048.  
  1049.     // Close GPIO device
  1050.     if (s_TouchDevice.hGPIO != NULL)
  1051.     {
  1052.         GPIOClose(s_TouchDevice.hGPIO);
  1053.         s_TouchDevice.hGPIO = NULL;
  1054.     }
  1055.  
  1056.     DEBUGMSG(ZONE_FUNCTION, (TEXT("PDDDeinitializeHardware-\r\n")));
  1057. }
  1058.  
  1059.  
  1060. //==============================================================================
  1061. // Function Name: PDDTouchPanelEnable
  1062. //
  1063. // Description: This routine creates the touch thread(if it is not already created)
  1064. //              initializes the interrupt and unmasks it.
  1065. //
  1066. // Arguments:  None
  1067. //
  1068. // Ret Value:   TRUE - Success
  1069. //==============================================================================
  1070. BOOL  PDDTouchPanelEnable()
  1071. {
  1072.     DEBUGMSG(ZONE_FUNCTION, (TEXT("PDDTouchPanelEnable+\r\n")));
  1073.  
  1074.     //  Check if already running
  1075.     if( s_TouchDevice.hTouchPanelEvent == NULL )
  1076.     {
  1077.         //  Clear terminate flag
  1078.         s_TouchDevice.bTerminateIST = FALSE;
  1079.  
  1080.         //  Create touch event
  1081.         s_TouchDevice.hTouchPanelEvent = CreateEvent( NULL, FALSE, FALSE, NULL );
  1082.         if( !s_TouchDevice.hTouchPanelEvent )
  1083.         {
  1084.             DEBUGMSG(ZONE_ERROR,(TEXT("PDDTouchPanelEnable: Failed to initialize touch event.\r\n")));
  1085.             return FALSE;
  1086.         }
  1087.  
  1088.         //  Map SYSINTR to event
  1089.         if (!InterruptInitialize(s_TouchDevice.dwSysIntr, s_TouchDevice.hTouchPanelEvent, NULL, 0))
  1090.         {
  1091.             DEBUGMSG(ZONE_ERROR, (TEXT("PDDTouchPanelEnable: Failed to initialize interrupt.\r\n")));
  1092.             return FALSE;
  1093.         }
  1094.  
  1095.         //  Create IST thread
  1096.        s_TouchDevice.hIST = CreateThread( NULL, 0, PDDTouchIST, 0, 0, NULL );
  1097.         if( s_TouchDevice.hIST == NULL )
  1098.         {
  1099.             DEBUGMSG(ZONE_ERROR, (TEXT("PDDTouchPanelEnable: Failed to create IST thread\r\n")));
  1100.             return FALSE;
  1101.         }
  1102.  
  1103.         // set IST thread priority
  1104.         CeSetThreadPriority ( s_TouchDevice.hIST, s_TouchDevice.dwISTPriority);
  1105.  
  1106.  
  1107.         if (s_TouchDevice.dwSysIntr != SYSINTR_NOP)
  1108.             InterruptMask(s_TouchDevice.dwSysIntr, FALSE);
  1109.     }
  1110.  
  1111.     DEBUGMSG(ZONE_FUNCTION, (TEXT("PDDTouchPanelEnable-\r\n")));
  1112.     return TRUE;
  1113. }
  1114.  
  1115. //==============================================================================
  1116. // Function Name: PDDTouchPanelDisable
  1117. //
  1118. // Description: This routine closes the IST and releases other resources.
  1119. //
  1120. // Arguments:  None
  1121. //
  1122. // Ret Value:   TRUE - Success
  1123. //==============================================================================
  1124. VOID  PDDTouchPanelDisable()
  1125. {
  1126.     DEBUGMSG(ZONE_FUNCTION, (TEXT("PDDTouchPanelDisable+\r\n")));
  1127.  
  1128.     //  Disable touch interrupt service thread
  1129.     if( s_TouchDevice.hTouchPanelEvent )
  1130.     {
  1131.         if (s_TouchDevice.dwSysIntr != SYSINTR_NOP)
  1132.             InterruptMask(s_TouchDevice.dwSysIntr, TRUE);
  1133.  
  1134.         s_TouchDevice.bTerminateIST = TRUE;
  1135.         SetEvent( s_TouchDevice.hTouchPanelEvent );
  1136.         s_TouchDevice.hTouchPanelEvent = 0;
  1137.     }
  1138.  
  1139.     //Closing IST handle
  1140.     if(s_TouchDevice.hIST)
  1141.     {
  1142.         CloseHandle(s_TouchDevice.hIST);
  1143.         s_TouchDevice.hIST=NULL;
  1144.      }
  1145.  
  1146.     DEBUGMSG(ZONE_FUNCTION, (TEXT("PDDTouchPanelDisable-\r\n")));
  1147. }
  1148.  
  1149. #else
  1150.  
  1151. //------------------------------------------------------------------------------
  1152. // Platform
  1153. //
  1154. #include "omap.h"
  1155. #include <ceddk.h>
  1156. #include <ceddkex.h>
  1157. #include <oal.h>
  1158. #include <oalex.h>
  1159. #include <initguid.h>
  1160. #include <sdk_gpio.h>
  1161. #include "gpio_ioctls.h"
  1162. #include "sdk_spi.h"
  1163. #include "omap_mcspi_regs.h"
  1164. #include "touchscreenpdd.h"
  1165.  
  1166. //------------------------------------------------------------------------------
  1167. // Defines
  1168. //
  1169. #define SPI1_DEVICE_NAME         L"SPI1:"
  1170. //------------------------------------------------------------------------------
  1171. // Debug zones
  1172. //
  1173. #ifndef SHIP_BUILD
  1174.  
  1175. #undef ZONE_ERROR
  1176. #undef ZONE_WARN
  1177. #undef ZONE_FUNCTION
  1178. #undef ZONE_INFO
  1179. #undef ZONE_TIPSTATE
  1180.  
  1181. #define ZONE_ERROR          DEBUGZONE(0)
  1182. #define ZONE_WARN           DEBUGZONE(1)
  1183. #define ZONE_FUNCTION       DEBUGZONE(2)
  1184. #define ZONE_INFO           DEBUGZONE(3)
  1185. #define ZONE_TIPSTATE       DEBUGZONE(4)
  1186.  
  1187. #endif
  1188.  
  1189.  
  1190. //------------------------------------------------------------------------------
  1191. // globals
  1192. //
  1193. static DWORD                          s_mddContext;
  1194. static PFN_TCH_MDD_REPORTSAMPLESET    s_pfnMddReportSampleSet;
  1195.  
  1196.  
  1197. //==============================================================================
  1198. // Function Name: TchPdd_Init
  1199. //
  1200. // Description: PDD should always implement this function. MDD calls it during
  1201. //              initialization to fill up the function table with rest of the
  1202. //              Helper functions.
  1203. //
  1204. // Arguments:
  1205. //              [IN] pszActiveKey - current active touch driver key
  1206. //              [IN] pMddIfc - MDD interface info
  1207. //              [OUT]pPddIfc - PDD interface (the function table to be filled)
  1208. //              [IN] hMddContext - mdd context (send to MDD in callback fn)
  1209. //
  1210. // Ret Value:   pddContext.
  1211. //==============================================================================
  1212. extern "C" DWORD WINAPI TchPdd_Init(LPCTSTR pszActiveKey,
  1213.     TCH_MDD_INTERFACE_INFO* pMddIfc,
  1214.     TCH_PDD_INTERFACE_INFO* pPddIfc,
  1215.     DWORD hMddContext
  1216.     )
  1217. {
  1218.     DWORD pddContext = 0;
  1219.  
  1220.     DEBUGMSG(ZONE_FUNCTION, (TEXT("TchPdd_Init+\r\n")));
  1221.        
  1222.     // Initialize once only
  1223.     if (s_TouchDevice.bInitialized)
  1224.     {
  1225.         pddContext = (DWORD) &s_TouchDevice;
  1226.         goto cleanup;
  1227.     }
  1228.  
  1229.     // Create the event for touch panel events.
  1230.     // If creation fails, return failure.
  1231.     s_TouchDevice.hTouchPanelEvent = CreateEvent( NULL, FALSE, FALSE, NULL);
  1232.     if (s_TouchDevice.hTouchPanelEvent  == NULL)
  1233.     {
  1234.         DEBUGMSG(ZONE_ERROR, (TEXT("ERROR: TOUCH: Touch Event Creation Failed\r\n")));
  1235.         goto cleanup;
  1236.     }
  1237.  
  1238.     // Remember the callback function pointer
  1239.     s_pfnMddReportSampleSet = pMddIfc->pfnMddReportSampleSet;
  1240.  
  1241.     // Remember the mdd context
  1242.     s_mddContext = hMddContext;
  1243.  
  1244.     s_TouchDevice.nSampleRate = DEFAULT_SAMPLE_RATE;
  1245.     s_TouchDevice.dwPowerState = D0;
  1246.     s_TouchDevice.dwSamplingTimeOut = INFINITE;
  1247.     s_TouchDevice.bTerminateIST = FALSE;
  1248.     s_TouchDevice.hTouchPanelEvent = 0;
  1249.  
  1250.     // Initialize HW
  1251.     if (!PDDInitializeHardware(pszActiveKey))
  1252.     {
  1253.         DEBUGMSG(ZONE_ERROR,  (TEXT("ERROR: TOUCH: Failed to initialize touch PDD.\r\n")));
  1254.         goto cleanup;
  1255.     }
  1256.  
  1257.     // Get sysintr values from the OAL for PENIRQ interrupt
  1258.     if (!KernelIoControl(
  1259.             IOCTL_HAL_REQUEST_SYSINTR,
  1260.             &s_TouchDevice.nPenIRQ,
  1261.             sizeof(s_TouchDevice.nPenIRQ),
  1262.             &s_TouchDevice.dwSysIntr,
  1263.             sizeof(s_TouchDevice.dwSysIntr),
  1264.             NULL
  1265.             ) )
  1266.     {
  1267.         DEBUGMSG(ZONE_ERROR, (TEXT("ERROR: TOUCH: Failed to request the touch sysintr.\r\n")));
  1268.         s_TouchDevice.dwSysIntr = (DWORD)SYSINTR_UNDEFINED;
  1269.         goto cleanup;
  1270.     }
  1271.  
  1272.     //Calibrate the screen, if the calibration data is not already preset in the registry
  1273.     PDDStartCalibrationThread();
  1274.  
  1275.     //Initialization of the h/w is done
  1276.     s_TouchDevice.bInitialized = TRUE;
  1277.  
  1278.     pddContext = (DWORD) &s_TouchDevice;
  1279.  
  1280.     // fill up pddifc table
  1281.     pPddIfc->version        = 1;
  1282.     pPddIfc->pfnDeinit      = TchPdd_Deinit;
  1283.     pPddIfc->pfnIoctl       = TchPdd_Ioctl;
  1284.     pPddIfc->pfnPowerDown   = TchPdd_PowerDown;
  1285.     pPddIfc->pfnPowerUp     = TchPdd_PowerUp;
  1286.  
  1287.  
  1288. cleanup:
  1289.     DEBUGMSG(ZONE_FUNCTION, (TEXT("TchPdd_Init-\r\n")));
  1290.     return pddContext;
  1291. }
  1292.  
  1293.  
  1294. //==============================================================================
  1295. // Function Name: TchPdd_DeInit
  1296. //
  1297. // Description: MDD calls it during deinitialization. PDD should deinit hardware
  1298. //              and deallocate memory etc.
  1299. //
  1300. // Arguments:   [IN] hPddContext. pddcontext returned in TchPdd_Init
  1301. //
  1302. // Ret Value:   None
  1303. //
  1304. //==============================================================================
  1305. void WINAPI TchPdd_Deinit(DWORD hPddContext)
  1306. {
  1307.     DEBUGMSG(ZONE_FUNCTION, (TEXT("TchPdd_Deinit+\r\n")));
  1308.  
  1309.     // Remove-W4: Warning C4100 workaround
  1310.     UNREFERENCED_PARAMETER(hPddContext);
  1311.  
  1312.     // Close the IST and release the resources before
  1313.     // de-initializing.
  1314.     PDDTouchPanelDisable();
  1315.  
  1316.     //  Shutdown HW
  1317.     PDDDeinitializeHardware();
  1318.  
  1319.     // Release interrupt
  1320.     if (s_TouchDevice.dwSysIntr != 0)
  1321.         {
  1322.         KernelIoControl(
  1323.             IOCTL_HAL_RELEASE_SYSINTR,
  1324.             &s_TouchDevice.dwSysIntr,
  1325.             sizeof(s_TouchDevice.dwSysIntr),
  1326.             NULL,
  1327.             0,
  1328.             NULL
  1329.             );
  1330.         }
  1331.  
  1332.     s_TouchDevice.bInitialized = FALSE;
  1333.  
  1334.  
  1335.     DEBUGMSG(ZONE_FUNCTION, (TEXT("TchPdd_Deinit-\r\n")));
  1336. }
  1337.  
  1338.  
  1339. //==============================================================================
  1340. // Function Name: TchPdd_Ioctl
  1341. //
  1342. // Description: The MDD controls the touch PDD through these IOCTLs.
  1343. //
  1344. // Arguments:   [IN] hPddContext. pddcontext returned in TchPdd_Init
  1345. //              DOWRD dwCode. IOCTL code
  1346. //              PBYTE pBufIn. Input Buffer pointer
  1347. //              DWORD dwLenIn. Input buffer length
  1348. //              PBYTE pBufOut. Output buffer pointer
  1349. //              DWORD dwLenOut. Output buffer length
  1350. //              PWORD pdwAcutalOut. Actual output buffer length.
  1351. //
  1352. // Ret Value:   TRUE if success else FALSE. SetLastError() if FALSE.
  1353. //==============================================================================
  1354. BOOL WINAPI TchPdd_Ioctl(DWORD hPddContext,
  1355.       DWORD dwCode,
  1356.       PBYTE pBufIn,
  1357.       DWORD dwLenIn,
  1358.       PBYTE pBufOut,
  1359.       DWORD dwLenOut,
  1360.       PDWORD pdwActualOut
  1361. )
  1362. {
  1363.     DWORD dwResult = ERROR_INVALID_PARAMETER;
  1364.  
  1365.     // Remove-W4: Warning C4100 workaround
  1366.     UNREFERENCED_PARAMETER(hPddContext);
  1367.  
  1368.     switch (dwCode)
  1369.     {
  1370.         //  Enable touch panel
  1371.         case IOCTL_TOUCH_ENABLE_TOUCHPANEL:
  1372.             DEBUGMSG(ZONE_FUNCTION, (L"TchPdd_Ioctl: IOCTL_TOUCH_ENABLE_TOUCHPANEL\r\n"));
  1373.             PDDTouchPanelEnable();
  1374.             dwResult = ERROR_SUCCESS;
  1375.             break;
  1376.  
  1377.         //  Disable touch panel
  1378.         case IOCTL_TOUCH_DISABLE_TOUCHPANEL:
  1379.             DEBUGMSG(ZONE_FUNCTION, (L"TchPdd_Ioctl: IOCTL_TOUCH_DISABLE_TOUCHPANEL\r\n"));
  1380.             PDDTouchPanelDisable();
  1381.             dwResult = ERROR_SUCCESS;
  1382.             break;
  1383.  
  1384.  
  1385.         //  Get current sample rate
  1386.         case IOCTL_TOUCH_GET_SAMPLE_RATE:
  1387.             DEBUGMSG(ZONE_FUNCTION, (L"TchPdd_Ioctl: IOCTL_TOUCH_GET_SAMPLE_RATE\r\n"));
  1388.  
  1389.             //  Check parameter validity
  1390.             if ((pBufOut != NULL) && (dwLenOut == sizeof(DWORD)))
  1391.             {
  1392.                 if (pdwActualOut)
  1393.                     *pdwActualOut = sizeof(DWORD);
  1394.  
  1395.                 //  Get the sample rate
  1396.                 *((DWORD*)pBufOut) = s_TouchDevice.nSampleRate;
  1397.                 dwResult = ERROR_SUCCESS;
  1398.             }
  1399.             break;
  1400.  
  1401.         //  Set the current sample rate
  1402.         case IOCTL_TOUCH_SET_SAMPLE_RATE:
  1403.             DEBUGMSG(ZONE_FUNCTION, (L"TchPdd_Ioctl: IOCTL_TOUCH_SET_SAMPLE_RATE\r\n"));
  1404.  
  1405.             //  Check parameter validity
  1406.             if ((pBufIn != NULL) && (dwLenIn == sizeof(DWORD)))
  1407.             {
  1408.                 //  Set the sample rate
  1409.                 s_TouchDevice.nSampleRate = *((DWORD*)pBufIn);
  1410.                 dwResult = ERROR_SUCCESS;
  1411.  
  1412.             }
  1413.             break;
  1414.  
  1415.         //  Get touch properties
  1416.         case IOCTL_TOUCH_GET_TOUCH_PROPS:
  1417.             //  Check parameter validity
  1418.             if ((pBufOut != NULL) && (dwLenOut == sizeof(TCH_PROPS)))
  1419.             {
  1420.                 if (pdwActualOut)
  1421.                     *pdwActualOut = sizeof(TCH_PROPS);\
  1422.  
  1423.                 //  Fill out the touch driver properties
  1424.                 ((TCH_PROPS*)pBufOut)->minSampleRate            = TOUCHPANEL_SAMPLE_RATE_LOW;
  1425.                 ((TCH_PROPS*)pBufOut)->maxSampleRate            = TOUCHPANEL_SAMPLE_RATE_HIGH;
  1426.                 ((TCH_PROPS*)pBufOut)->minCalCount              = 5;
  1427.                 ((TCH_PROPS*)pBufOut)->maxSimultaneousSamples   = 1;
  1428.                 ((TCH_PROPS*)pBufOut)->touchType                = TOUCHTYPE_SINGLETOUCH;
  1429.                 ((TCH_PROPS*)pBufOut)->calHoldSteadyTime        = CAL_HOLD_STEADY_TIME;
  1430.                 ((TCH_PROPS*)pBufOut)->calDeltaReset            = CAL_DELTA_RESET;
  1431.                 ((TCH_PROPS*)pBufOut)->xRangeMin                = RANGE_MIN;
  1432.                 ((TCH_PROPS*)pBufOut)->xRangeMax                = RANGE_MAX;
  1433.                 ((TCH_PROPS*)pBufOut)->yRangeMin                = RANGE_MIN;
  1434.                 ((TCH_PROPS*)pBufOut)->yRangeMax                = RANGE_MAX;
  1435.  
  1436.                 dwResult = ERROR_SUCCESS;
  1437.             }
  1438.             break;
  1439.  
  1440.         //  Power management IOCTLs
  1441.         case IOCTL_POWER_CAPABILITIES:
  1442.             DEBUGMSG(ZONE_FUNCTION, (L"TchPdd_Ioctl: IOCTL_POWER_CAPABILITIES\r\n"));
  1443.             if (pBufOut != NULL && dwLenOut == sizeof(POWER_CAPABILITIES))
  1444.             {
  1445.                 PPOWER_CAPABILITIES ppc = (PPOWER_CAPABILITIES) pBufOut;
  1446.                 memset(ppc, 0, sizeof(*ppc));
  1447.                 ppc->DeviceDx = DX_MASK(D0) | DX_MASK(D1) | DX_MASK(D2) | DX_MASK(D3) | DX_MASK(D4);
  1448.  
  1449.                 if (pdwActualOut)
  1450.                     *pdwActualOut = sizeof(POWER_CAPABILITIES);
  1451.  
  1452.                 dwResult = ERROR_SUCCESS;
  1453.             }
  1454.             break;
  1455.  
  1456.         case IOCTL_POWER_GET:
  1457.             DEBUGMSG(ZONE_FUNCTION, (L"TchPdd_Ioctl: IOCTL_POWER_GET\r\n"));
  1458.             if(pBufOut != NULL && dwLenOut == sizeof(CEDEVICE_POWER_STATE))
  1459.             {
  1460.                 *(PCEDEVICE_POWER_STATE) pBufOut = (CEDEVICE_POWER_STATE) s_TouchDevice.dwPowerState;
  1461.  
  1462.                 if (pdwActualOut)
  1463.                     *pdwActualOut = sizeof(CEDEVICE_POWER_STATE);
  1464.  
  1465.                 dwResult = ERROR_SUCCESS;
  1466.             }
  1467.             break;
  1468.  
  1469.         case IOCTL_POWER_SET:
  1470.             DEBUGMSG(ZONE_FUNCTION, (L"TchPdd_Ioctl: IOCTL_POWER_SET\r\n"));
  1471.             if(pBufOut != NULL && dwLenOut == sizeof(CEDEVICE_POWER_STATE))
  1472.             {
  1473.                 CEDEVICE_POWER_STATE dx = *(CEDEVICE_POWER_STATE*)pBufOut;
  1474.                 if( VALID_DX(dx) )
  1475.                 {
  1476.                     DEBUGMSG(ZONE_FUNCTION, (L"TchPdd_Ioctl: IOCTL_POWER_SET = to D%u\r\n", dx));
  1477.                     s_TouchDevice.dwPowerState = dx;
  1478.  
  1479.                     if (pdwActualOut)
  1480.                         *pdwActualOut = sizeof(CEDEVICE_POWER_STATE);
  1481.  
  1482.                     //  Enable touchscreen for D0-D2; otherwise disable
  1483.                     switch( dx )
  1484.                     {
  1485.                         case D0:
  1486.                         case D1:
  1487.                         case D2:
  1488.                             //  Enable touchscreen
  1489.                             PDDTouchPanelPowerHandler(FALSE);    //Enable Touch ADC
  1490.                             break;
  1491.  
  1492.                         case D3:
  1493.                         case D4:
  1494.                             //  Disable touchscreen
  1495.                             PDDTouchPanelPowerHandler(TRUE); //Disable Touch ADC
  1496.                             break;
  1497.  
  1498.                         default:
  1499.                             //  Ignore
  1500.                             break;
  1501.                     }
  1502.  
  1503.                     dwResult = ERROR_SUCCESS;
  1504.                 }
  1505.             }
  1506.             break;
  1507.  
  1508.         default:
  1509.             dwResult = ERROR_NOT_SUPPORTED;
  1510.             break;
  1511.     }
  1512.  
  1513.     if (dwResult != ERROR_SUCCESS)
  1514.     {
  1515.         SetLastError(dwResult);
  1516.         return FALSE;
  1517.     }
  1518.     return TRUE;
  1519. }
  1520.  
  1521.  
  1522. //==============================================================================
  1523. // Function Name: TchPdd_PowerUp
  1524. //
  1525. // Description: MDD passes xxx_PowerUp stream interface call to PDD.
  1526. //
  1527. // Arguments:   [IN] hPddContext. pddcontext returned in TchPdd_Init
  1528. //
  1529. // Ret Value:   None
  1530. //==============================================================================
  1531. void WINAPI TchPdd_PowerUp(
  1532.     DWORD hPddContext
  1533.     )
  1534. {
  1535.     DEBUGMSG(ZONE_FUNCTION, (TEXT("TchPdd_PowerUp+\r\n")));
  1536.     // Remove-W4: Warning C4100 workaround
  1537.     UNREFERENCED_PARAMETER(hPddContext);
  1538.     DEBUGMSG(ZONE_FUNCTION, (TEXT("TchPdd_PowerUp-\r\n")));
  1539. }
  1540.  
  1541. //==============================================================================
  1542. // Function Name: TchPdd_PowerDown
  1543. //
  1544. // Description: MDD passes xxx_PowerDown stream interface call to PDD.
  1545. //
  1546. // Arguments:   [IN] hPddContext. pddcontext returned in TchPdd_Init
  1547. //
  1548. // Ret Value:   None
  1549. //==============================================================================
  1550. void WINAPI TchPdd_PowerDown(
  1551.     DWORD hPddContext
  1552.     )
  1553. {
  1554.     DEBUGMSG(ZONE_FUNCTION, (TEXT("TchPdd_PowerDown+\r\n")));
  1555.     // Remove-W4: Warning C4100 workaround
  1556.     UNREFERENCED_PARAMETER(hPddContext);
  1557.     DEBUGMSG(ZONE_FUNCTION, (TEXT("TchPdd_PowerDown-\r\n")));
  1558. }
  1559.  
  1560.  
  1561. //==============================================================================
  1562. //Internal Functions
  1563. //==============================================================================
  1564.  
  1565. //==============================================================================
  1566. // Function Name: PDDCalibrationThread
  1567. //
  1568. // Description: This function is called from the PDD Init to calibrate the screen.
  1569. //              If the calibration data is already present in the registry,
  1570. //              this step is skipped, else a call is made into the GWES for calibration.
  1571. //
  1572. // Arguments:   None.
  1573. //
  1574. // Ret Value:   Success(1), faliure(0)
  1575. //==============================================================================
  1576. static HRESULT PDDCalibrationThread()
  1577. {
  1578.     HKEY hKey;
  1579.     DWORD dwType;
  1580.     LONG lResult;
  1581.     HANDLE hAPIs;
  1582.  
  1583.     DEBUGMSG(ZONE_FUNCTION, (TEXT("CalibrationThread+\r\n")));
  1584.  
  1585.     // try to open [HKLM\hardware\devicemap\touch] key
  1586.     if (ERROR_SUCCESS != RegOpenKeyEx(HKEY_LOCAL_MACHINE, RK_HARDWARE_DEVICEMAP_TOUCH, 0, KEY_ALL_ACCESS, &hKey))
  1587.     {
  1588.         DEBUGMSG(ZONE_CALIBRATE, (TEXT("CalibrationThread: calibration: Can't find [HKLM/%s]\r\n"), RK_HARDWARE_DEVICEMAP_TOUCH));
  1589.         return E_FAIL;
  1590.     }
  1591.  
  1592.     // check for calibration data (query the type of data only)
  1593.     lResult = RegQueryValueEx(hKey, RV_CALIBRATION_DATA, 0, &dwType, NULL, NULL);
  1594.     RegCloseKey(hKey);
  1595.     if (lResult == ERROR_SUCCESS)
  1596.     {
  1597.         // registry contains calibration data, return
  1598.         return S_OK;
  1599.     }
  1600.  
  1601.     hAPIs = OpenEvent(EVENT_ALL_ACCESS, FALSE, TEXT("SYSTEM/GweApiSetReady"));
  1602.     if (hAPIs)
  1603.     {
  1604.         WaitForSingleObject(hAPIs, INFINITE);
  1605.         CloseHandle(hAPIs);
  1606.     }
  1607.  
  1608.     // Perform calibration
  1609.     TouchCalibrate();
  1610.  
  1611.     // try to open [HKLM\hardware\devicemap\touch] key
  1612.     if (ERROR_SUCCESS != RegOpenKeyEx(HKEY_LOCAL_MACHINE, RK_HARDWARE_DEVICEMAP_TOUCH, 0, KEY_ALL_ACCESS, &hKey))
  1613.     {
  1614.         DEBUGMSG(ZONE_CALIBRATE, (TEXT("CalibrationThread: calibration: Can't find [HKLM/%s]\r\n"), RK_HARDWARE_DEVICEMAP_TOUCH));
  1615.         return E_FAIL;
  1616.     }
  1617.  
  1618.     // display new calibration data
  1619.     lResult = RegQueryValueEx(hKey, RV_CALIBRATION_DATA, 0, &dwType, NULL, NULL);
  1620.     if (lResult == ERROR_SUCCESS)
  1621.     {
  1622.         TCHAR szCalibrationData[100];
  1623.         DWORD Size = sizeof(szCalibrationData);
  1624.  
  1625.         RegQueryValueEx(hKey, RV_CALIBRATION_DATA, 0, &dwType, (BYTE *) szCalibrationData, (DWORD *) &Size);
  1626.         DEBUGMSG(ZONE_CALIBRATE, (TEXT("touchp: calibration: new calibration data is \"%s\"\r\n"), szCalibrationData));
  1627.         RETAILMSG(1, (TEXT("touchp: calibration: new calibration data is \"%s\"\r\n"), szCalibrationData));        
  1628.     }
  1629.     RegCloseKey(hKey);
  1630.  
  1631.     DEBUGMSG(ZONE_FUNCTION, (TEXT("CalibrationThread-\r\n")));
  1632.  
  1633.     return S_OK;
  1634. }
  1635.  
  1636.  
  1637. //==============================================================================
  1638. // Function Name: PDDStartCalibrationThread
  1639. //
  1640. // Description: This function is creates the calibration thread with
  1641. //              PDDCalibrationThread as entry.
  1642. //
  1643. // Arguments:   None.
  1644. //
  1645. // Ret Value:   None
  1646. //==============================================================================
  1647. void PDDStartCalibrationThread()
  1648. {
  1649.     HANDLE hThread;
  1650.  
  1651.     hThread = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)PDDCalibrationThread, NULL, 0, NULL);
  1652.     // We don't need the handle, close it here
  1653.     CloseHandle(hThread);
  1654. }
  1655.  
  1656.  
  1657. //==============================================================================
  1658. // Function Name: PDDGetTouchIntPinState
  1659. //
  1660. // Description: This function is called from the IST to get the status of pen.
  1661. //
  1662. // Arguments:   None.
  1663. //
  1664. // Ret Value:   Status of the pen.
  1665. //==============================================================================
  1666. inline BOOL PDDGetTouchIntPinState()
  1667. {
  1668.     //  Return state of pen down
  1669.    return( GPIOGetBit(s_TouchDevice.hGPIO, s_TouchDevice.nPenGPIO) == 0 );
  1670. }
  1671.  
  1672. //==============================================================================
  1673. // Function Name: PDDGetControllerData
  1674. //
  1675. // Description: This function is used to get the ADC data through SPI
  1676. //
  1677. // Arguments:   None.
  1678. //
  1679. // Ret Value:   Status of the pen.
  1680. //==============================================================================
  1681. void PDDGetControllerData(UINT32 control, UINT32 * read_data)
  1682. {
  1683.     SPIWriteRead(s_TouchDevice.hSPI, 3, &control, read_data);
  1684. }
  1685.  
  1686. //==============================================================================
  1687. // Function: PDDTouchPanelPowerHandler
  1688. //
  1689. // This function indicates to the driver that the system is entering
  1690. // or leaving the suspend state.
  1691. //
  1692. // Parameters:
  1693. //      bOff
  1694. //          [in] TRUE indicates that the system is turning off. FALSE
  1695. //          indicates that the system is turning on.
  1696. //
  1697. // Returns:
  1698. //      None.
  1699. //==============================================================================
  1700. void PDDTouchPanelPowerHandler(BOOL boff)
  1701. {
  1702.     DEBUGMSG(ZONE_FUNCTION, (_T("PDDTouchPanelPowerHandler+\r\n")));
  1703.  
  1704.     if (s_TouchDevice.dwSysIntr != SYSINTR_NOP)
  1705.         InterruptMask(s_TouchDevice.dwSysIntr, boff);
  1706.  
  1707.     DEBUGMSG(ZONE_FUNCTION, (_T("PDDTouchPanelPowerHandler-\r\n")));
  1708.  
  1709.     return;
  1710. }
  1711.  
  1712. //==============================================================================
  1713. // Function Name: PDDTouchPanelGetPoint
  1714. //
  1715. // Description: This function is used to read the touch coordinates from the h/w.
  1716. //
  1717. // Arguments:
  1718. //                  TOUCH_PANEL_SAMPLE_FLAGS * - Pointer to the sample flags. This flag is filled with the
  1719. //                                                                      values TouchSampleDownFlag or TouchSampleValidFlag;
  1720. //                  INT * - Pointer to the x coordinate of the sample.
  1721. //                  INT * - Pointer to the y coordinate of the sample.
  1722. //
  1723. // Ret Value:   None
  1724. //==============================================================================
  1725. void PDDTouchPanelGetPoint(
  1726.     TOUCH_PANEL_SAMPLE_FLAGS *pTipStateFlags,
  1727.     INT *pUncalX,
  1728.     INT *pUncalY
  1729.     )
  1730. {
  1731.     // MDD needs us to hold on to last valid sample and previous pen state.
  1732.     static USHORT usLastFilteredX       = 0;    // This holds the previous X sample
  1733.     static USHORT usLastFilteredY       = 0;    // This holds the previous Y sample
  1734.     static USHORT usSavedFilteredX      = 0;    // This holds the last reported X sample
  1735.     static USHORT usSavedFilteredY      = 0;    // This holds the last reported Y sample
  1736.     static BOOL bPrevReportedPenDown    = FALSE;
  1737.     static DWORD DelayedSampleCount     = 0;
  1738.  
  1739.     BOOL bReportedPenDown               = FALSE; // This indicates if we are reporting pen down to the mdd
  1740.     BOOL bActualPenDown                 = FALSE; // This indicates if the pen is actually down, whether we report or not
  1741.     UINT32 xpos = 0;
  1742.     UINT32 ypos = 0;
  1743.  
  1744.     DEBUGMSG(ZONE_FUNCTION&&ZONE_SAMPLES, (TEXT("PDDTouchPanelGetPoint+\r\n")));
  1745.  
  1746.     // By default, any sample returned will be ignored.
  1747.     *pTipStateFlags = TouchSampleIgnore;
  1748.  
  1749.     // Check if pen data are available If so, get the data.
  1750.     // Note that we always return data from the previous sample to avoid returning data nearest
  1751.     // the point where the pen is going up.  Data during light touches is not accurate and should
  1752.     // normally be rejected.  Without the ability to do pressure measurement, we are limited to
  1753.     // rejecting points near the beginning and end of the pen down period.
  1754.     bActualPenDown  = PDDGetTouchIntPinState();
  1755.     if (bActualPenDown == TRUE)
  1756.     {
  1757.         PDDGetTouchData(&xpos, &ypos);
  1758.  
  1759.         // Check if pen is still down to validate the data.
  1760.         bActualPenDown = PDDGetTouchIntPinState();
  1761.         if (bActualPenDown == TRUE)
  1762.         {
  1763.             if (DelayedSampleCount > s_TouchDevice.nInitialSamplesDropped)
  1764.             {
  1765.                 // Indicate pen down so we can return valid data.
  1766.                 bReportedPenDown = TRUE;
  1767.             }
  1768.             else
  1769.             {
  1770.                 DelayedSampleCount++;
  1771.             }
  1772.         }
  1773.     }
  1774.  
  1775.     // Check if we have valid data to report to the MDD.
  1776.     if (bReportedPenDown)
  1777.     {
  1778.         // Return the valid pen data.  Note that this data was actually obtained on the
  1779.         // previous sample
  1780.         *pUncalX = usLastFilteredX;
  1781.         *pUncalY = usLastFilteredY;
  1782.  
  1783.         // Save the data that we returned.
  1784.         // This will also be returned on penup to help avoid returning data obtained during
  1785.         // a light press
  1786.         usSavedFilteredX = usLastFilteredX;
  1787.         usSavedFilteredY = usLastFilteredY;
  1788.  
  1789.         DEBUGMSG(ZONE_SAMPLES, ( TEXT( "X(0x%X) Y(0x%X)\r\n" ), *pUncalX, *pUncalY ) );
  1790.  
  1791.         // Store reported pen state.
  1792.         *pTipStateFlags = TouchSampleDownFlag | TouchSampleValidFlag;
  1793.     }
  1794.     else    // Otherwise, assume pen is up.
  1795.     {
  1796.         // Check if previously down and valid.
  1797.         if ( bPrevReportedPenDown )
  1798.         {
  1799.             DEBUGMSG(ZONE_TIPSTATE, ( TEXT( "Pen Up!\r\n" ) ) );
  1800.  
  1801.             // Use the last valid sample. MDD needs an up with valid data.
  1802.             *pUncalX = usSavedFilteredX;
  1803.             *pUncalY = usSavedFilteredY;
  1804.             *pTipStateFlags = TouchSampleValidFlag;
  1805.         }
  1806.         DEBUGMSG(ZONE_SAMPLES, ( TEXT( "Point: (%d,%d)\r\n" ), *pUncalX, *pUncalY ) );
  1807.     }
  1808.  
  1809.     // Save current reported pen state.
  1810.     bPrevReportedPenDown = bReportedPenDown;
  1811.  
  1812.     // Set up interrupt/timer for next sample
  1813.     if (bActualPenDown)
  1814.     {
  1815.         // Pen down so set MDD timeout for polling mode.
  1816.         s_TouchDevice.dwSamplingTimeOut = 1000 / s_TouchDevice.nSampleRate;
  1817.         // Save point measured during this sample so it can be reported on the next sample
  1818.         usLastFilteredX = (USHORT)xpos;
  1819.         usLastFilteredY = (USHORT)ypos;
  1820.     }
  1821.     else
  1822.     {
  1823.         // Reset the delayed sample counter
  1824.         DelayedSampleCount = 0;
  1825.         usLastFilteredX = 0;
  1826.         usLastFilteredY = 0;
  1827.  
  1828.         // Pen up so set MDD timeout for interrupt mode.
  1829.         s_TouchDevice.dwSamplingTimeOut = INFINITE;
  1830.  
  1831.         // Set the proper state for the next interrupt.
  1832.         InterruptDone( s_TouchDevice.dwSysIntr );
  1833.     }
  1834.  
  1835.     DEBUGMSG(ZONE_FUNCTION&&ZONE_SAMPLES, (TEXT("PDDTouchPanelGetPoint+\r\n")));
  1836.  
  1837.     return;
  1838. }
  1839.  
  1840. //==============================================================================
  1841. // Function Name: PDDGetTouchData
  1842. //
  1843. // Description: Helper function to read 3 samples and find the average of them.
  1844. //
  1845. // Arguments:
  1846. //                  INT * - Pointer to the x coordinate of the sample.
  1847. //                  INT * - Pointer to the y coordinate of the sample.
  1848. //
  1849. // Ret Value:   TRUE
  1850. //==============================================================================
  1851. BOOL PDDGetTouchData(UINT32 * xpos,  UINT32 * ypos)
  1852. {
  1853.     UINT32 tempdata = 0;
  1854.     UINT16 px, py;
  1855.     UINT32 pxAvg = 0, pyAvg = 0;
  1856.     int i;
  1857.     int iAvg = 0;
  1858.  
  1859.     DEBUGMSG(ZONE_FUNCTION, ( TEXT("PDDGetTouchData+\r\n" )) );
  1860.  
  1861.     do
  1862.     {
  1863.         for( i = 0; i < MAX_PTS; i++ )
  1864.         {
  1865.             PDDGetControllerData(COMMAND_XPOS, &tempdata);
  1866.             px = (tempdata & 0x7FF8) >> 3;
  1867.             PDDGetControllerData(COMMAND_YPOS, &tempdata);
  1868.             py = (tempdata & 0x7FF8) >> 3;
  1869.  
  1870.             if (i == 0)
  1871.             {
  1872.                 pxAvg = px;
  1873.                 pyAvg = py;
  1874.                 iAvg = 1;
  1875.             }
  1876.             else if  ((((pxAvg >= px)  &  ((UINT16)(px+DELTA) >= pxAvg)) | ((px > pxAvg)  &  ((UINT16)(pxAvg+DELTA) > px))) &
  1877.                           (((pyAvg >=py)  &  ((UINT16)(py+DELTA) >=pyAvg)) | ((py > pyAvg)  &  ((UINT16)(pyAvg+DELTA) > py))) )
  1878.             {
  1879.                 pxAvg = (pxAvg +px)/2;
  1880.                 pyAvg = (pyAvg +py)/2;
  1881.                 iAvg++;
  1882.             }
  1883.             else
  1884.                 break;
  1885.         }
  1886.  
  1887.     }while(iAvg < MAX_PTS);
  1888.  
  1889.     *xpos = pxAvg;
  1890.     *ypos = pyAvg;
  1891.  
  1892.     // Possibly Pen Up, give pen status detection a chance to debounce
  1893.     if(pyAvg == 0 && s_TouchDevice.PenUpDebounceMS) Sleep(s_TouchDevice.PenUpDebounceMS);
  1894.  
  1895.     DEBUGMSG(ZONE_FUNCTION, ( TEXT("PDDGetTouchData-\r\n" )) );
  1896.  
  1897.     return TRUE;
  1898. }
  1899.  
  1900.  
  1901. //==============================================================================
  1902. // Function Name: PDDTouchIST
  1903. //
  1904. // Description: This is the IST which waits on the touch event or Time out value.
  1905. //              Normally the IST waits on the touch event infinitely, but once the
  1906. //              pen down condition is recognized the time out interval is changed
  1907. //              to dwSamplingTimeOut.
  1908. //
  1909. // Arguments:
  1910. //                  PVOID - Reseved not currently used.
  1911. //
  1912. // Ret Value:   None
  1913. //==============================================================================
  1914. ULONG PDDTouchIST(PVOID   reserved)
  1915. {
  1916.     TOUCH_PANEL_SAMPLE_FLAGS    SampleFlags = 0;
  1917.     CETOUCHINPUT input;
  1918.     INT32                       RawX, RawY;
  1919.  
  1920.     // Remove-W4: Warning C4100 workaround
  1921.     UNREFERENCED_PARAMETER(reserved);
  1922.  
  1923.     DEBUGMSG(ZONE_TOUCH_IST, (L"PDDTouchIST: IST thread started\r\n"));
  1924.  
  1925.     //  Loop until told to stop
  1926.     while(!s_TouchDevice.bTerminateIST)
  1927.     {
  1928.         //  Wait for touch IRQ, timeout or terminate flag
  1929.        WaitForSingleObject(s_TouchDevice.hTouchPanelEvent, s_TouchDevice.dwSamplingTimeOut);
  1930.  
  1931.         //  Check for terminate flag
  1932.         if (s_TouchDevice.bTerminateIST)
  1933.             break;
  1934.  
  1935.         PDDTouchPanelGetPoint( &SampleFlags, &RawX, &RawY);
  1936.  
  1937.         if ( SampleFlags & TouchSampleIgnore )
  1938.         {
  1939.             // do nothing, not a valid sample
  1940.             continue;
  1941.         }
  1942.  
  1943.          //convert x-y coordination to one sample set before sending it to touch MDD.
  1944.          if(ConvertTouchPanelToTouchInput(SampleFlags, RawX, RawY, &input))
  1945.          {
  1946.                //send this 1 sample to mdd
  1947.                s_pfnMddReportSampleSet(s_mddContext, 1, &input);
  1948.          }
  1949.  
  1950.         DEBUGMSG(ZONE_TOUCH_SAMPLES, ( TEXT( "Sample:   (%d, %d)\r\n" ), RawX, RawY ) );
  1951.  
  1952.     }
  1953.  
  1954.     // IST thread terminating
  1955.     InterruptDone(s_TouchDevice.dwSysIntr);
  1956.     InterruptDisable(s_TouchDevice.dwSysIntr);
  1957.  
  1958.     CloseHandle(s_TouchDevice.hTouchPanelEvent);
  1959.     s_TouchDevice.hTouchPanelEvent = NULL;
  1960.  
  1961.     DEBUGMSG(ZONE_TOUCH_IST, (L"PDDTouchIST: IST thread ending\r\n"));
  1962.  
  1963.     return ERROR_SUCCESS;
  1964. }
  1965.  
  1966. //==============================================================================
  1967. // Function Name: PDDInitializeHardware
  1968. //
  1969. // Description: This routine configures the SPI channel and GPIO pin for interrupt mode.
  1970. //
  1971. // Arguments:  None
  1972. //
  1973. // Ret Value:   TRUE - Success
  1974. //                   FAIL - Failure
  1975. //==============================================================================
  1976. BOOL PDDInitializeHardware(LPCTSTR pszActiveKey)
  1977. {
  1978.     BOOL   rc = FALSE;
  1979.     DWORD  config;
  1980.     UINT32 spiBuffer;
  1981.     UINT32 xPos, yPos;
  1982.  
  1983.     DEBUGMSG(ZONE_FUNCTION, (TEXT("PDDInitializeHardware+\r\n")));
  1984.  
  1985.     if (IsDVIMode())
  1986.         goto cleanup;
  1987.  
  1988.     // Read parameters from registry
  1989.     if (GetDeviceRegistryParams(
  1990.             pszActiveKey,
  1991.             &s_TouchDevice,
  1992.             dimof(s_deviceRegParams),
  1993.             s_deviceRegParams) != ERROR_SUCCESS)
  1994.     {
  1995.         DEBUGMSG(ZONE_ERROR, (TEXT("ERROR: PDDInitializeHardware: Error reading from Registry.\r\n")));
  1996.         goto cleanup;
  1997.     }
  1998.  
  1999.     // Open GPIO driver
  2000.     s_TouchDevice.hGPIO = GPIOOpen();
  2001.     if (s_TouchDevice.hGPIO == NULL)
  2002.     {
  2003.         DEBUGMSG(ZONE_ERROR, (TEXT("ERROR: PDDInitializeHardware: Failed open GPIO device driver\r\n")));
  2004.         goto cleanup;
  2005.     }
  2006.  
  2007.     // Setup nPENIRQ for input mode, falling edge detect, debounce enable
  2008.     GPIOSetMode(s_TouchDevice.hGPIO, s_TouchDevice.nPenGPIO, GPIO_DIR_INPUT|GPIO_INT_HIGH_LOW|GPIO_DEBOUNCE_ENABLE);
  2009.  
  2010.     // Get the IRQ for the GPIO
  2011.     s_TouchDevice.nPenIRQ = GPIOGetSystemIrq(s_TouchDevice.hGPIO, s_TouchDevice.nPenGPIO);
  2012.  
  2013.     // Set debounce time on GPIO
  2014.     IOCTL_GPIO_SET_DEBOUNCE_TIME_IN debounce;
  2015.  
  2016.     debounce.gpioId = s_TouchDevice.nPenGPIO;
  2017.     debounce.debounceTime = 10;
  2018.  
  2019.     // Open SPI driver
  2020.     s_TouchDevice.hSPI = SPIOpen(SPI1_DEVICE_NAME);
  2021.     if (s_TouchDevice.hSPI == NULL)
  2022.     {
  2023.         DEBUGMSG(ZONE_ERROR, (TEXT("ERROR: PDDInitializeHardware: Failed open SPI device driver\r\n")));
  2024.         goto cleanup;
  2025.     }
  2026.  
  2027.     //  Settings for Touchscreen device
  2028.     //
  2029.     //      Tx/Rx
  2030.     //      Tx enable on data line 0
  2031.     //
  2032.  
  2033.     // Raising clock rate can make the touch screen sample unstable, although the rate is in the nominal range.
  2034.  
  2035.     config =    MCSPI_PHA_ODD_EDGES |
  2036.                 MCSPI_POL_ACTIVEHIGH |
  2037.                 MCSPI_CHCONF_CLKD(10) |
  2038.                 MCSPI_CSPOLARITY_ACTIVELOW |
  2039.                 MCSPI_CHCONF_WL(24) |
  2040.                 MCSPI_CHCONF_TRM_TXRX |
  2041.                 MCSPI_CHCONF_DMAW_DISABLE |
  2042.                 MCSPI_CHCONF_DMAR_DISABLE |
  2043.                 MCSPI_CHCONF_DPE0;
  2044.  
  2045.     // Configure SPI channel
  2046.     if (!SPIConfigure(s_TouchDevice.hSPI, s_TouchDevice.nSPIAddr, config))
  2047.     {
  2048.         DEBUGMSG(ZONE_ERROR, (TEXT("ERROR: PDDInitializeHardware: Failed configure SPI device driver\r\n")));
  2049.         goto cleanup;
  2050.     }
  2051.  
  2052.     // Enable the touchscreen
  2053.     spiBuffer = COMMAND_EN_TOUCH;
  2054.     if (!SPIWriteRead(s_TouchDevice.hSPI, sizeof(UINT32), &spiBuffer, &spiBuffer))
  2055.     {
  2056.         DEBUGMSG(ZONE_ERROR, (TEXT("ERROR: PDDInitializeHardware: failed to enable touchpad on spi bus\r\n")));
  2057.         goto cleanup;
  2058.     }
  2059.  
  2060.     // Grab a point from touchscreen
  2061.     PDDGetTouchData( &xPos, &yPos );
  2062.  
  2063.     // Done
  2064.     rc = TRUE;
  2065.  
  2066. cleanup:
  2067.  
  2068.     DEBUGMSG(ZONE_FUNCTION, (TEXT("PDDInitializeHardware-\r\n")));
  2069.     if( rc == FALSE )
  2070.     {
  2071.         PDDDeinitializeHardware();
  2072.     }
  2073.  
  2074.     return rc;
  2075. }
  2076.  
  2077.  
  2078. //==============================================================================
  2079. // Function Name: PDDDeinitializeHardware
  2080. //
  2081. // Description: This routine Deinitializes the h/w by closing the SPI channel and GPIO pin
  2082. //
  2083. // Arguments:  None
  2084. //
  2085. // Ret Value:   None
  2086. //==============================================================================
  2087. VOID PDDDeinitializeHardware()
  2088. {
  2089.     DEBUGMSG(ZONE_FUNCTION, (TEXT("PDDDeinitializeHardware+\r\n")));
  2090.  
  2091.     // Close SPI device
  2092.     if (s_TouchDevice.hSPI != NULL)
  2093.     {
  2094.         SPIClose(s_TouchDevice.hSPI);
  2095.         s_TouchDevice.hSPI = NULL;
  2096.     }
  2097.  
  2098.     // Close GPIO device
  2099.     if (s_TouchDevice.hGPIO != NULL)
  2100.     {
  2101.         GPIOClose(s_TouchDevice.hGPIO);
  2102.         s_TouchDevice.hGPIO = NULL;
  2103.     }
  2104.  
  2105.     DEBUGMSG(ZONE_FUNCTION, (TEXT("PDDDeinitializeHardware-\r\n")));
  2106. }
  2107.  
  2108.  
  2109. //==============================================================================
  2110. // Function Name: PDDTouchPanelEnable
  2111. //
  2112. // Description: This routine creates the touch thread(if it is not already created)
  2113. //              initializes the interrupt and unmasks it.
  2114. //
  2115. // Arguments:  None
  2116. //
  2117. // Ret Value:   TRUE - Success
  2118. //==============================================================================
  2119. BOOL  PDDTouchPanelEnable()
  2120. {
  2121.     DEBUGMSG(ZONE_FUNCTION, (TEXT("PDDTouchPanelEnable+\r\n")));
  2122.  
  2123.     //  Check if already running
  2124.     if( s_TouchDevice.hTouchPanelEvent == NULL )
  2125.     {
  2126.         //  Clear terminate flag
  2127.         s_TouchDevice.bTerminateIST = FALSE;
  2128.  
  2129.         //  Create touch event
  2130.         s_TouchDevice.hTouchPanelEvent = CreateEvent( NULL, FALSE, FALSE, NULL );
  2131.         if( !s_TouchDevice.hTouchPanelEvent )
  2132.         {
  2133.             DEBUGMSG(ZONE_ERROR,(TEXT("PDDTouchPanelEnable: Failed to initialize touch event.\r\n")));
  2134.             return FALSE;
  2135.         }
  2136.  
  2137.         //  Map SYSINTR to event
  2138.         if (!InterruptInitialize(s_TouchDevice.dwSysIntr, s_TouchDevice.hTouchPanelEvent, NULL, 0))
  2139.         {
  2140.             DEBUGMSG(ZONE_ERROR, (TEXT("PDDTouchPanelEnable: Failed to initialize interrupt.\r\n")));
  2141.             return FALSE;
  2142.         }
  2143.  
  2144.         //  Create IST thread
  2145.        s_TouchDevice.hIST = CreateThread( NULL, 0, PDDTouchIST, 0, 0, NULL );
  2146.         if( s_TouchDevice.hIST == NULL )
  2147.         {
  2148.             DEBUGMSG(ZONE_ERROR, (TEXT("PDDTouchPanelEnable: Failed to create IST thread\r\n")));
  2149.             return FALSE;
  2150.         }
  2151.  
  2152.         // set IST thread priority
  2153.         CeSetThreadPriority ( s_TouchDevice.hIST, s_TouchDevice.dwISTPriority);
  2154.  
  2155.  
  2156.         if (s_TouchDevice.dwSysIntr != SYSINTR_NOP)
  2157.             InterruptMask(s_TouchDevice.dwSysIntr, FALSE);
  2158.     }
  2159.  
  2160.     DEBUGMSG(ZONE_FUNCTION, (TEXT("PDDTouchPanelEnable-\r\n")));
  2161.     return TRUE;
  2162. }
  2163.  
  2164. //==============================================================================
  2165. // Function Name: PDDTouchPanelDisable
  2166. //
  2167. // Description: This routine closes the IST and releases other resources.
  2168. //
  2169. // Arguments:  None
  2170. //
  2171. // Ret Value:   TRUE - Success
  2172. //==============================================================================
  2173. VOID  PDDTouchPanelDisable()
  2174. {
  2175.     DEBUGMSG(ZONE_FUNCTION, (TEXT("PDDTouchPanelDisable+\r\n")));
  2176.  
  2177.     //  Disable touch interrupt service thread
  2178.     if( s_TouchDevice.hTouchPanelEvent )
  2179.     {
  2180.         if (s_TouchDevice.dwSysIntr != SYSINTR_NOP)
  2181.             InterruptMask(s_TouchDevice.dwSysIntr, TRUE);
  2182.  
  2183.         s_TouchDevice.bTerminateIST = TRUE;
  2184.         SetEvent( s_TouchDevice.hTouchPanelEvent );
  2185.         s_TouchDevice.hTouchPanelEvent = 0;
  2186.     }
  2187.  
  2188.     //Closing IST handle
  2189.     if(s_TouchDevice.hIST)
  2190.     {
  2191.         CloseHandle(s_TouchDevice.hIST);
  2192.         s_TouchDevice.hIST=NULL;
  2193.      }
  2194.  
  2195.     DEBUGMSG(ZONE_FUNCTION, (TEXT("PDDTouchPanelDisable-\r\n")));
  2196. }
  2197. #endif
Add Comment
Please, Sign In to add comment