Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- //
- // Copyright (c) Microsoft Corporation. All rights reserved.
- //
- //
- // Use of this sample source code is subject to the terms of the Microsoft
- // license agreement under which you licensed this sample source code. If
- // you did not accept the terms of the license agreement, you are not
- // authorized to use this sample source code. For the terms of the license,
- // please see the license agreement between you and Microsoft or, if applicable,
- // see the LICENSE.RTF on your install media or the root of your tools installation.
- // THE SAMPLE SOURCE CODE IS PROVIDED "AS IS", WITH NO WARRANTIES OR INDEMNITIES.
- //
- // All rights reserved ADENEO EMBEDDED 2010
- // Copyright (c) 2007, 2008 BSQUARE Corporation. All rights reserved.
- /*
- ================================================================================
- * Texas Instruments OMAP(TM) Platform Software
- * (c) Copyright Texas Instruments, Incorporated. All Rights Reserved.
- *
- * Use of this software is controlled by the terms and conditions found
- * in the license agreement under which this software has been supplied.
- *
- ================================================================================
- */
- #pragma warning(push)
- #pragma warning(disable: 4127 4201 4244 4101 4189)
- //------------------------------------------------------------------------------
- // Public
- //
- #include <windows.h>
- #include <types.h>
- #include <nkintr.h>
- #include <creg.hxx>
- #include <tchstream.h>
- #include <tchstreamddsi.h>
- #include <pm.h>
- //------------------------------------------------------------------------------
- //
- // Global: dpCurSettings
- //
- DBGPARAM dpCurSettings = {
- L"TouchDriver", {
- L"Errors", L"Warnings", L"Function", L"Info",
- L"Undefined" , L"Undefined", L"Undefined", L"Undefined",
- L"Undefined", L"Undefined", L"Undefined", L"Undefined",
- L"Undefined", L"Undefined", L"Undefined", L"Undefined"
- },
- 0x000B
- };
- #if defined(BSP_LCD_PRISM0700W) || defined(BSP_LVDS_PRISM1010W)
- //------------------------------------------------------------------------------
- // Platform
- //
- #include "omap.h"
- #include "am3517.h"
- #include <ceddk.h>
- #include <ceddkex.h>
- #include <oal.h>
- #include <oalex.h>
- #include <initguid.h>
- #include <sdk_gpio.h>
- #include "gpio_ioctls.h"
- #include "sdk_spi.h"
- #include "sdk_i2c.h"
- #include "omap_mcspi_regs.h"
- #include "touchscreenpdd.h"
- //------------------------------------------------------------------------------
- // Defines
- //
- #define SPI1_DEVICE_NAME L"SPI1:"
- //------------------------------------------------------------------------------
- // Debug zones
- //
- #ifndef SHIP_BUILD
- #undef ZONE_ERROR
- #undef ZONE_WARN
- #undef ZONE_FUNCTION
- #undef ZONE_INFO
- #undef ZONE_TIPSTATE
- #define ZONE_ERROR DEBUGZONE(0)
- #define ZONE_WARN DEBUGZONE(1)
- #define ZONE_FUNCTION DEBUGZONE(2)
- #define ZONE_INFO DEBUGZONE(3)
- #define ZONE_TIPSTATE DEBUGZONE(4)
- #endif
- //------------------------------------------------------------------------------
- // globals
- //
- static DWORD s_mddContext;
- static PFN_TCH_MDD_REPORTSAMPLESET s_pfnMddReportSampleSet;
- //==============================================================================
- // Function Name: TchPdd_Init
- //
- // Description: PDD should always implement this function. MDD calls it during
- // initialization to fill up the function table with rest of the
- // Helper functions.
- //
- // Arguments:
- // [IN] pszActiveKey - current active touch driver key
- // [IN] pMddIfc - MDD interface info
- // [OUT]pPddIfc - PDD interface (the function table to be filled)
- // [IN] hMddContext - mdd context (send to MDD in callback fn)
- //
- // Ret Value: pddContext.
- //==============================================================================
- extern "C" DWORD WINAPI TchPdd_Init(LPCTSTR pszActiveKey,
- TCH_MDD_INTERFACE_INFO* pMddIfc,
- TCH_PDD_INTERFACE_INFO* pPddIfc,
- DWORD hMddContext
- )
- {
- DWORD pddContext = 0;
- DEBUGMSG(ZONE_FUNCTION, (TEXT("TchPdd_Init+\r\n")));
- // Initialize once only
- if (s_TouchDevice.bInitialized)
- {
- pddContext = (DWORD) &s_TouchDevice;
- goto cleanup;
- }
- // Create the event for touch panel events.
- // If creation fails, return failure.
- s_TouchDevice.hTouchPanelEvent = CreateEvent( NULL, FALSE, FALSE, NULL);
- if (s_TouchDevice.hTouchPanelEvent == NULL)
- {
- DEBUGMSG(ZONE_ERROR, (TEXT("ERROR: TOUCH: Touch Event Creation Failed\r\n")));
- goto cleanup;
- }
- // Remember the callback function pointer
- s_pfnMddReportSampleSet = pMddIfc->pfnMddReportSampleSet;
- // Remember the mdd context
- s_mddContext = hMddContext;
- s_TouchDevice.nSampleRate = DEFAULT_SAMPLE_RATE;
- s_TouchDevice.dwPowerState = D0;
- s_TouchDevice.dwSamplingTimeOut = INFINITE;
- s_TouchDevice.bTerminateIST = FALSE;
- s_TouchDevice.hTouchPanelEvent = 0;
- // Initialize HW
- if (!PDDInitializeHardware(pszActiveKey))
- {
- DEBUGMSG(ZONE_ERROR, (TEXT("ERROR: TOUCH: Failed to initialize touch PDD.\r\n")));
- goto cleanup;
- }
- // Get sysintr values from the OAL for PENIRQ interrupt
- if (!KernelIoControl(
- IOCTL_HAL_REQUEST_SYSINTR,
- &s_TouchDevice.nPenIRQ,
- sizeof(s_TouchDevice.nPenIRQ),
- &s_TouchDevice.dwSysIntr,
- sizeof(s_TouchDevice.dwSysIntr),
- NULL
- ) )
- {
- DEBUGMSG(ZONE_ERROR, (TEXT("ERROR: TOUCH: Failed to request the touch sysintr.\r\n")));
- s_TouchDevice.dwSysIntr = (DWORD)SYSINTR_UNDEFINED;
- goto cleanup;
- }
- //Calibrate the screen, if the calibration data is not already preset in the registry
- PDDStartCalibrationThread();
- //Initialization of the h/w is done
- s_TouchDevice.bInitialized = TRUE;
- pddContext = (DWORD) &s_TouchDevice;
- // fill up pddifc table
- pPddIfc->version = 1;
- pPddIfc->pfnDeinit = TchPdd_Deinit;
- pPddIfc->pfnIoctl = TchPdd_Ioctl;
- pPddIfc->pfnPowerDown = TchPdd_PowerDown;
- pPddIfc->pfnPowerUp = TchPdd_PowerUp;
- cleanup:
- DEBUGMSG(ZONE_FUNCTION, (TEXT("TchPdd_Init-\r\n")));
- return pddContext;
- }
- //==============================================================================
- // Function Name: TchPdd_DeInit
- //
- // Description: MDD calls it during deinitialization. PDD should deinit hardware
- // and deallocate memory etc.
- //
- // Arguments: [IN] hPddContext. pddcontext returned in TchPdd_Init
- //
- // Ret Value: None
- //
- //==============================================================================
- void WINAPI TchPdd_Deinit(DWORD hPddContext)
- {
- DEBUGMSG(ZONE_FUNCTION, (TEXT("TchPdd_Deinit+\r\n")));
- // Remove-W4: Warning C4100 workaround
- UNREFERENCED_PARAMETER(hPddContext);
- // Close the IST and release the resources before
- // de-initializing.
- PDDTouchPanelDisable();
- // Shutdown HW
- PDDDeinitializeHardware();
- // Release interrupt
- if (s_TouchDevice.dwSysIntr != 0)
- {
- KernelIoControl(
- IOCTL_HAL_RELEASE_SYSINTR,
- &s_TouchDevice.dwSysIntr,
- sizeof(s_TouchDevice.dwSysIntr),
- NULL,
- 0,
- NULL
- );
- }
- s_TouchDevice.bInitialized = FALSE;
- DEBUGMSG(ZONE_FUNCTION, (TEXT("TchPdd_Deinit-\r\n")));
- }
- //==============================================================================
- // Function Name: TchPdd_Ioctl
- //
- // Description: The MDD controls the touch PDD through these IOCTLs.
- //
- // Arguments: [IN] hPddContext. pddcontext returned in TchPdd_Init
- // DOWRD dwCode. IOCTL code
- // PBYTE pBufIn. Input Buffer pointer
- // DWORD dwLenIn. Input buffer length
- // PBYTE pBufOut. Output buffer pointer
- // DWORD dwLenOut. Output buffer length
- // PWORD pdwAcutalOut. Actual output buffer length.
- //
- // Ret Value: TRUE if success else FALSE. SetLastError() if FALSE.
- //==============================================================================
- BOOL WINAPI TchPdd_Ioctl(DWORD hPddContext,
- DWORD dwCode,
- PBYTE pBufIn,
- DWORD dwLenIn,
- PBYTE pBufOut,
- DWORD dwLenOut,
- PDWORD pdwActualOut
- )
- {
- DWORD dwResult = ERROR_INVALID_PARAMETER;
- // Remove-W4: Warning C4100 workaround
- UNREFERENCED_PARAMETER(hPddContext);
- switch (dwCode)
- {
- // Enable touch panel
- case IOCTL_TOUCH_ENABLE_TOUCHPANEL:
- DEBUGMSG(ZONE_FUNCTION, (L"TchPdd_Ioctl: IOCTL_TOUCH_ENABLE_TOUCHPANEL\r\n"));
- PDDTouchPanelEnable();
- dwResult = ERROR_SUCCESS;
- break;
- // Disable touch panel
- case IOCTL_TOUCH_DISABLE_TOUCHPANEL:
- DEBUGMSG(ZONE_FUNCTION, (L"TchPdd_Ioctl: IOCTL_TOUCH_DISABLE_TOUCHPANEL\r\n"));
- PDDTouchPanelDisable();
- dwResult = ERROR_SUCCESS;
- break;
- // Get current sample rate
- case IOCTL_TOUCH_GET_SAMPLE_RATE:
- DEBUGMSG(ZONE_FUNCTION, (L"TchPdd_Ioctl: IOCTL_TOUCH_GET_SAMPLE_RATE\r\n"));
- // Check parameter validity
- if ((pBufOut != NULL) && (dwLenOut == sizeof(DWORD)))
- {
- if (pdwActualOut)
- *pdwActualOut = sizeof(DWORD);
- // Get the sample rate
- *((DWORD*)pBufOut) = s_TouchDevice.nSampleRate;
- dwResult = ERROR_SUCCESS;
- }
- break;
- // Set the current sample rate
- case IOCTL_TOUCH_SET_SAMPLE_RATE:
- DEBUGMSG(ZONE_FUNCTION, (L"TchPdd_Ioctl: IOCTL_TOUCH_SET_SAMPLE_RATE\r\n"));
- // Check parameter validity
- if ((pBufIn != NULL) && (dwLenIn == sizeof(DWORD)))
- {
- // Set the sample rate
- s_TouchDevice.nSampleRate = *((DWORD*)pBufIn);
- dwResult = ERROR_SUCCESS;
- }
- break;
- // Get touch properties
- case IOCTL_TOUCH_GET_TOUCH_PROPS:
- // Check parameter validity
- if ((pBufOut != NULL) && (dwLenOut == sizeof(TCH_PROPS)))
- {
- if (pdwActualOut)
- *pdwActualOut = sizeof(TCH_PROPS);\
- // Fill out the touch driver properties
- ((TCH_PROPS*)pBufOut)->minSampleRate = TOUCHPANEL_SAMPLE_RATE_LOW;
- ((TCH_PROPS*)pBufOut)->maxSampleRate = TOUCHPANEL_SAMPLE_RATE_HIGH;
- ((TCH_PROPS*)pBufOut)->minCalCount = 5;
- ((TCH_PROPS*)pBufOut)->maxSimultaneousSamples = 1;
- ((TCH_PROPS*)pBufOut)->touchType = TOUCHTYPE_MULTITOUCH;
- ((TCH_PROPS*)pBufOut)->calHoldSteadyTime = CAL_HOLD_STEADY_TIME;
- ((TCH_PROPS*)pBufOut)->calDeltaReset = CAL_DELTA_RESET;
- ((TCH_PROPS*)pBufOut)->xRangeMin = RANGE_MIN;
- ((TCH_PROPS*)pBufOut)->xRangeMax = RANGE_MAX;
- ((TCH_PROPS*)pBufOut)->yRangeMin = RANGE_MIN;
- ((TCH_PROPS*)pBufOut)->yRangeMax = RANGE_MAX;
- dwResult = ERROR_SUCCESS;
- }
- break;
- // Power management IOCTLs
- case IOCTL_POWER_CAPABILITIES:
- DEBUGMSG(ZONE_FUNCTION, (L"TchPdd_Ioctl: IOCTL_POWER_CAPABILITIES\r\n"));
- if (pBufOut != NULL && dwLenOut == sizeof(POWER_CAPABILITIES))
- {
- PPOWER_CAPABILITIES ppc = (PPOWER_CAPABILITIES) pBufOut;
- memset(ppc, 0, sizeof(*ppc));
- ppc->DeviceDx = DX_MASK(D0) | DX_MASK(D1) | DX_MASK(D2) | DX_MASK(D3) | DX_MASK(D4);
- if (pdwActualOut)
- *pdwActualOut = sizeof(POWER_CAPABILITIES);
- dwResult = ERROR_SUCCESS;
- }
- break;
- case IOCTL_POWER_GET:
- DEBUGMSG(ZONE_FUNCTION, (L"TchPdd_Ioctl: IOCTL_POWER_GET\r\n"));
- if(pBufOut != NULL && dwLenOut == sizeof(CEDEVICE_POWER_STATE))
- {
- *(PCEDEVICE_POWER_STATE) pBufOut = (CEDEVICE_POWER_STATE) s_TouchDevice.dwPowerState;
- if (pdwActualOut)
- *pdwActualOut = sizeof(CEDEVICE_POWER_STATE);
- dwResult = ERROR_SUCCESS;
- }
- break;
- case IOCTL_POWER_SET:
- DEBUGMSG(ZONE_FUNCTION, (L"TchPdd_Ioctl: IOCTL_POWER_SET\r\n"));
- if(pBufOut != NULL && dwLenOut == sizeof(CEDEVICE_POWER_STATE))
- {
- CEDEVICE_POWER_STATE dx = *(CEDEVICE_POWER_STATE*)pBufOut;
- if( VALID_DX(dx) )
- {
- DEBUGMSG(ZONE_FUNCTION, (L"TchPdd_Ioctl: IOCTL_POWER_SET = to D%u\r\n", dx));
- s_TouchDevice.dwPowerState = dx;
- if (pdwActualOut)
- *pdwActualOut = sizeof(CEDEVICE_POWER_STATE);
- // Enable touchscreen for D0-D2; otherwise disable
- switch( dx )
- {
- case D0:
- case D1:
- case D2:
- // Enable touchscreen
- PDDTouchPanelPowerHandler(FALSE); //Enable Touch ADC
- break;
- case D3:
- case D4:
- // Disable touchscreen
- PDDTouchPanelPowerHandler(TRUE); //Disable Touch ADC
- break;
- default:
- // Ignore
- break;
- }
- dwResult = ERROR_SUCCESS;
- }
- }
- break;
- default:
- dwResult = ERROR_NOT_SUPPORTED;
- break;
- }
- if (dwResult != ERROR_SUCCESS)
- {
- SetLastError(dwResult);
- return FALSE;
- }
- return TRUE;
- }
- //==============================================================================
- // Function Name: TchPdd_PowerUp
- //
- // Description: MDD passes xxx_PowerUp stream interface call to PDD.
- //
- // Arguments: [IN] hPddContext. pddcontext returned in TchPdd_Init
- //
- // Ret Value: None
- //==============================================================================
- void WINAPI TchPdd_PowerUp(
- DWORD hPddContext
- )
- {
- DEBUGMSG(ZONE_FUNCTION, (TEXT("TchPdd_PowerUp+\r\n")));
- // Remove-W4: Warning C4100 workaround
- UNREFERENCED_PARAMETER(hPddContext);
- DEBUGMSG(ZONE_FUNCTION, (TEXT("TchPdd_PowerUp-\r\n")));
- }
- //==============================================================================
- // Function Name: TchPdd_PowerDown
- //
- // Description: MDD passes xxx_PowerDown stream interface call to PDD.
- //
- // Arguments: [IN] hPddContext. pddcontext returned in TchPdd_Init
- //
- // Ret Value: None
- //==============================================================================
- void WINAPI TchPdd_PowerDown(
- DWORD hPddContext
- )
- {
- DEBUGMSG(ZONE_FUNCTION, (TEXT("TchPdd_PowerDown+\r\n")));
- // Remove-W4: Warning C4100 workaround
- UNREFERENCED_PARAMETER(hPddContext);
- DEBUGMSG(ZONE_FUNCTION, (TEXT("TchPdd_PowerDown-\r\n")));
- }
- //==============================================================================
- //Internal Functions
- //==============================================================================
- //==============================================================================
- // Function Name: PDDCalibrationThread
- //
- // Description: This function is called from the PDD Init to calibrate the screen.
- // If the calibration data is already present in the registry,
- // this step is skipped, else a call is made into the GWES for calibration.
- //
- // Arguments: None.
- //
- // Ret Value: Success(1), faliure(0)
- //==============================================================================
- static HRESULT PDDCalibrationThread()
- {
- HKEY hKey;
- DWORD dwType;
- LONG lResult;
- HANDLE hAPIs;
- DEBUGMSG(ZONE_FUNCTION, (TEXT("CalibrationThread+\r\n")));
- // try to open [HKLM\hardware\devicemap\touch] key
- if (ERROR_SUCCESS != RegOpenKeyEx(HKEY_LOCAL_MACHINE, RK_HARDWARE_DEVICEMAP_TOUCH, 0, KEY_ALL_ACCESS, &hKey))
- {
- DEBUGMSG(ZONE_CALIBRATE, (TEXT("CalibrationThread: calibration: Can't find [HKLM/%s]\r\n"), RK_HARDWARE_DEVICEMAP_TOUCH));
- return E_FAIL;
- }
- // check for calibration data (query the type of data only)
- lResult = RegQueryValueEx(hKey, RV_CALIBRATION_DATA, 0, &dwType, NULL, NULL);
- RegCloseKey(hKey);
- if (lResult == ERROR_SUCCESS)
- {
- // registry contains calibration data, return
- return S_OK;
- }
- hAPIs = OpenEvent(EVENT_ALL_ACCESS, FALSE, TEXT("SYSTEM/GweApiSetReady"));
- if (hAPIs)
- {
- WaitForSingleObject(hAPIs, INFINITE);
- CloseHandle(hAPIs);
- }
- // Perform calibration
- TouchCalibrate();
- // try to open [HKLM\hardware\devicemap\touch] key
- if (ERROR_SUCCESS != RegOpenKeyEx(HKEY_LOCAL_MACHINE, RK_HARDWARE_DEVICEMAP_TOUCH, 0, KEY_ALL_ACCESS, &hKey))
- {
- DEBUGMSG(ZONE_CALIBRATE, (TEXT("CalibrationThread: calibration: Can't find [HKLM/%s]\r\n"), RK_HARDWARE_DEVICEMAP_TOUCH));
- return E_FAIL;
- }
- // display new calibration data
- lResult = RegQueryValueEx(hKey, RV_CALIBRATION_DATA, 0, &dwType, NULL, NULL);
- if (lResult == ERROR_SUCCESS)
- {
- TCHAR szCalibrationData[100];
- DWORD Size = sizeof(szCalibrationData);
- RegQueryValueEx(hKey, RV_CALIBRATION_DATA, 0, &dwType, (BYTE *) szCalibrationData, (DWORD *) &Size);
- DEBUGMSG(ZONE_CALIBRATE, (TEXT("touchp: calibration: new calibration data is \"%s\"\r\n"), szCalibrationData));
- RETAILMSG(1, (TEXT("touchp: calibration: new calibration data is \"%s\"\r\n"), szCalibrationData));
- }
- RegCloseKey(hKey);
- DEBUGMSG(ZONE_FUNCTION, (TEXT("CalibrationThread-\r\n")));
- return S_OK;
- }
- //==============================================================================
- // Function Name: PDDStartCalibrationThread
- //
- // Description: This function is creates the calibration thread with
- // PDDCalibrationThread as entry.
- //
- // Arguments: None.
- //
- // Ret Value: None
- //==============================================================================
- void PDDStartCalibrationThread()
- {
- HANDLE hThread;
- hThread = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)PDDCalibrationThread, NULL, 0, NULL);
- // We don't need the handle, close it here
- CloseHandle(hThread);
- }
- //==============================================================================
- // Function Name: PDDGetTouchIntPinState
- //
- // Description: This function is called from the IST to get the status of pen.
- //
- // Arguments: None.
- //
- // Ret Value: Status of the pen.
- //==============================================================================
- inline BOOL PDDGetTouchIntPinState()
- {
- // Return state of pen down
- return( GPIOGetBit(s_TouchDevice.hGPIO, s_TouchDevice.nPenGPIO) == 1 );
- }
- //==============================================================================
- // Function Name: PDDGetControllerData
- //
- // Description: This function is used to get the ADC data through SPI
- //
- // Arguments: None.
- //
- // Ret Value: Status of the pen.
- //==============================================================================
- void PDDGetControllerData(UINT32 control, UINT32 * read_data1, UINT32 * read_data2, UINT8 * tip)
- {
- UINT8 i2c_data[12];
- DWORD len;
- len = I2CRead(s_TouchDevice.hI2C, 0x01, &i2c_data, sizeof(i2c_data));
- if (len != sizeof(i2c_data)) {
- ERRORMSG(ZONE_ERROR, (TEXT("I2CRead Failed!!\r\n")));
- goto out;
- }
- UINT16 px1, py1, pt1, px2, py2, pt2;
- px1 = i2c_data[2] << 8 | i2c_data[3];
- py1 = i2c_data[0] << 8 | i2c_data[1];
- pt1 = i2c_data[5] & 0x0f;
- px2 = i2c_data[8] << 8 | i2c_data[9];
- py2 = i2c_data[6] << 8 | i2c_data[7];
- pt2 = i2c_data[11] & 0x0f;
- px1 = RANGE_MAX_X - px1;
- py1 = RANGE_MAX_Y - py1;
- px2 = RANGE_MAX_X - px2;
- py2 = RANGE_MAX_Y - py2;
- *read_data1 = py1 << 16 | px1;
- *read_data2 = py2 << 16 | px2;
- *tip = pt2 << 4 | pt1;
- out:
- return;
- }
- //==============================================================================
- // Function: PDDTouchPanelPowerHandler
- //
- // This function indicates to the driver that the system is entering
- // or leaving the suspend state.
- //
- // Parameters:
- // bOff
- // [in] TRUE indicates that the system is turning off. FALSE
- // indicates that the system is turning on.
- //
- // Returns:
- // None.
- //==============================================================================
- void PDDTouchPanelPowerHandler(BOOL boff)
- {
- DEBUGMSG(ZONE_FUNCTION, (_T("PDDTouchPanelPowerHandler+\r\n")));
- if (s_TouchDevice.dwSysIntr != SYSINTR_NOP)
- InterruptMask(s_TouchDevice.dwSysIntr, boff);
- DEBUGMSG(ZONE_FUNCTION, (_T("PDDTouchPanelPowerHandler-\r\n")));
- return;
- }
- //==============================================================================
- // Function Name: PDDTouchPanelGetPoint
- //
- // Description: This function is used to read the touch coordinates from the h/w.
- //
- // Arguments:
- // TOUCH_PANEL_SAMPLE_FLAGS * - Pointer to the sample flags. This flag is filled with the
- // values TouchSampleDownFlag or TouchSampleValidFlag;
- // INT * - Pointer to the x coordinate of the sample.
- // INT * - Pointer to the y coordinate of the sample.
- //
- // Ret Value: None
- //==============================================================================
- void PDDTouchPanelGetPoint(
- TOUCH_PANEL_SAMPLE_FLAGS *pTipStateFlags1,
- TOUCH_PANEL_SAMPLE_FLAGS *pTipStateFlags2,
- INT *pUncalX1,
- INT *pUncalY1,
- INT *pUncalX2,
- INT *pUncalY2
- )
- {
- // MDD needs us to hold on to last valid sample and previous pen state.
- static USHORT usLastFilteredX = 0; // This holds the previous X sample
- static USHORT usLastFilteredY = 0; // This holds the previous Y sample
- static USHORT usSavedFilteredX = 0; // This holds the last reported X sample
- static USHORT usSavedFilteredY = 0; // This holds the last reported Y sample
- static BOOL bPrevReportedPenDown1 = FALSE;
- static BOOL bPrevReportedPenDown2 = FALSE;
- static DWORD DelayedSampleCount = 0;
- BOOL bReportedPenDown1 = FALSE; // This indicates if we are reporting pen down to the mdd
- BOOL bReportedPenDown2 = FALSE; // This indicates if we are reporting pen down to the mdd
- BOOL bActualPenDown = FALSE; // This indicates if the pen is actually down, whether we report or not
- UINT32 xpos1 = 0;
- UINT32 ypos1 = 0;
- UINT32 xpos2 = 0;
- UINT32 ypos2 = 0;
- UINT8 tip = 0;
- DEBUGMSG(ZONE_FUNCTION&&ZONE_SAMPLES, (TEXT("PDDTouchPanelGetPoint+\r\n")));
- // RETAILMSG(1, (L"PDDTouchPanelGetPoint\r\n"));
- // By default, any sample returned will be ignored.
- *pTipStateFlags1 = TouchSampleIgnore;
- *pTipStateFlags2 = TouchSampleIgnore;
- // Check if pen data are available If so, get the data.
- // Note that we always return data from the previous sample to avoid returning data nearest
- // the point where the pen is going up. Data during light touches is not accurate and should
- // normally be rejected. Without the ability to do pressure measurement, we are limited to
- // rejecting points near the beginning and end of the pen down period.
- bActualPenDown = PDDGetTouchIntPinState();
- if (bActualPenDown == TRUE)
- {
- PDDGetTouchData(&xpos1, &ypos1, &xpos2, &ypos2, &tip);
- bReportedPenDown1 = ((tip & 0x0f) == 1) ? TRUE : FALSE;
- bReportedPenDown2 = ((tip & 0xf0) == 0x10) ? TRUE : FALSE;
- }
- // Check if we have valid data to report to the MDD.
- if (bReportedPenDown1)
- {
- *pUncalX1 = xpos1;
- *pUncalY1 = ypos1;
- DEBUGMSG(ZONE_SAMPLES, ( TEXT( "X1(0x%X) Y1(0x%X)\r\n" ), *pUncalX1, *pUncalY1 ) );
- // Store reported pen state.
- *pTipStateFlags1 = TouchSampleDownFlag | TouchSampleValidFlag;
- }
- else // Otherwise, assume pen is up.
- {
- // Check if previously down and valid.
- if ( bPrevReportedPenDown1 )
- {
- DEBUGMSG(ZONE_TIPSTATE, ( TEXT( "Pen Up!\r\n" ) ) );
- *pUncalX1 = xpos1;
- *pUncalY1 = ypos1;
- *pTipStateFlags1 = TouchSampleValidFlag;
- }
- DEBUGMSG(ZONE_SAMPLES, ( TEXT( "Point: (%d,%d)\r\n" ), *pUncalX1, *pUncalY1 ) );
- }
- // Check if we have valid data to report to the MDD.
- if (bReportedPenDown2)
- {
- *pUncalX2 = xpos2;
- *pUncalY2 = ypos2;
- DEBUGMSG(ZONE_SAMPLES, ( TEXT( "X2(0x%X) Y2(0x%X)\r\n" ), *pUncalX2, *pUncalY2 ) );
- // Store reported pen state.
- *pTipStateFlags2 = TouchSampleDownFlag | TouchSampleValidFlag;
- }
- else // Otherwise, assume pen is up.
- {
- // Check if previously down and valid.
- if ( bPrevReportedPenDown2 )
- {
- DEBUGMSG(ZONE_TIPSTATE, ( TEXT( "Pen Up!\r\n" ) ) );
- *pUncalX2 = xpos2;
- *pUncalY2 = ypos2;
- *pTipStateFlags1 = TouchSampleValidFlag;
- }
- DEBUGMSG(ZONE_SAMPLES, ( TEXT( "Point: (%d,%d)\r\n" ), *pUncalX2, *pUncalY2 ) );
- }
- // Save current reported pen state.
- bPrevReportedPenDown1 = bReportedPenDown1;
- bPrevReportedPenDown2 = bReportedPenDown2;
- // Set up interrupt/timer for next sample
- if (bActualPenDown)
- {
- // Reset the delayed sample counter
- DelayedSampleCount = 0;
- usLastFilteredX = 0;
- usLastFilteredY = 0;
- UINT8 i2c_data;
- DWORD len;
- // write scan_complete to touch controller.
- i2c_data = 0x00;
- len = I2CWrite(s_TouchDevice.hI2C, 0x11, &i2c_data, sizeof(UINT8));
- if (len != sizeof(UINT8)) {
- ERRORMSG(ZONE_ERROR, (TEXT("I2CWrite Failed!!\r\n")));
- goto out;
- }
- // Pen up so set MDD timeout for interrupt mode.
- s_TouchDevice.dwSamplingTimeOut = INFINITE;
- // Set the proper state for the next interrupt.
- InterruptDone( s_TouchDevice.dwSysIntr );
- }
- out:
- DEBUGMSG(ZONE_FUNCTION&&ZONE_SAMPLES, (TEXT("PDDTouchPanelGetPoint-\r\n")));
- return;
- }
- //==============================================================================
- // Function Name: PDDGetTouchData
- //
- // Description: Helper function to read 3 samples and find the average of them.
- //
- // Arguments:
- // INT * - Pointer to the x coordinate of the sample.
- // INT * - Pointer to the y coordinate of the sample.
- //
- // Ret Value: TRUE
- //==============================================================================
- BOOL PDDGetTouchData(UINT32 * xpos1, UINT32 * ypos1, UINT32 * xpos2, UINT32 * ypos2, UINT8 * tip)
- {
- UINT32 tempdata1 = 0;
- UINT32 tempdata2 = 0;
- UINT8 temptip = 0;
- UINT16 px1, py1, px2, py2;
- UINT32 pxAvg = 0, pyAvg = 0;
- int i;
- int iAvg = 0;
- DEBUGMSG(ZONE_FUNCTION, ( TEXT("PDDGetTouchData+\r\n" )) );
- PDDGetControllerData(0, &tempdata1, &tempdata2, &temptip);
- px1 = tempdata1 & 0x0000FFFF;
- py1 = (tempdata1 & 0xFFFF0000) >> 16;
- px2 = tempdata2 & 0x0000FFFF;
- py2 = (tempdata2 & 0xFFFF0000) >> 16;
- *xpos1 = px1;
- *ypos1 = py1;
- *xpos2 = px2;
- *ypos2 = py2;
- *tip = temptip;
- // Possibly Pen Up, give pen status detection a chance to debounce
- if(temptip == 0 && s_TouchDevice.PenUpDebounceMS) Sleep(s_TouchDevice.PenUpDebounceMS);
- DEBUGMSG(ZONE_FUNCTION, ( TEXT("PDDGetTouchData-\r\n" )) );
- return TRUE;
- }
- //==============================================================================
- // Function Name: PDDTouchIST
- //
- // Description: This is the IST which waits on the touch event or Time out value.
- // Normally the IST waits on the touch event infinitely, but once the
- // pen down condition is recognized the time out interval is changed
- // to dwSamplingTimeOut.
- //
- // Arguments:
- // PVOID - Reseved not currently used.
- //
- // Ret Value: None
- //==============================================================================
- ULONG PDDTouchIST(PVOID reserved)
- {
- TOUCH_PANEL_SAMPLE_FLAGS SampleFlags1 = 0;
- TOUCH_PANEL_SAMPLE_FLAGS SampleFlags2 = 0;
- CETOUCHINPUT input;
- INT32 RawX1, RawY1, RawX2, RawY2;
- // Remove-W4: Warning C4100 workaround
- UNREFERENCED_PARAMETER(reserved);
- DEBUGMSG(ZONE_TOUCH_IST, (L"PDDTouchIST: IST thread started\r\n"));
- // Loop until told to stop
- while(!s_TouchDevice.bTerminateIST)
- {
- // Wait for touch IRQ, timeout or terminate flag
- WaitForSingleObject(s_TouchDevice.hTouchPanelEvent, s_TouchDevice.dwSamplingTimeOut);
- // Check for terminate flag
- if (s_TouchDevice.bTerminateIST)
- break;
- PDDTouchPanelGetPoint( &SampleFlags1, &SampleFlags2, &RawX1, &RawY1, &RawX2, &RawY2);
- if ( SampleFlags1 & SampleFlags2 & TouchSampleIgnore )
- {
- // do nothing, not a valid sample
- continue;
- }
- if ( !(SampleFlags1 & TouchSampleIgnore) )
- {
- //convert x-y coordination to one sample set before sending it to touch MDD.
- if(PrismConvertTouchPanelToTouchInput(SampleFlags1, RawX1, RawY1, &input, 0))
- {
- //send this 1 sample to mdd
- s_pfnMddReportSampleSet(s_mddContext, 1, &input);
- }
- DEBUGMSG(ZONE_TOUCH_SAMPLES, ( TEXT( "Sample: (%d, %d)\r\n" ), RawX1, RawY1 ) );
- }
- if ( !(SampleFlags2 & TouchSampleIgnore) )
- {
- //convert x-y coordination to one sample set before sending it to touch MDD.
- if(PrismConvertTouchPanelToTouchInput(SampleFlags2, RawX2, RawY2, &input, 1))
- {
- //send this 1 sample to mdd
- s_pfnMddReportSampleSet(s_mddContext, 1, &input);
- }
- DEBUGMSG(ZONE_TOUCH_SAMPLES, ( TEXT( "Sample: (%d, %d)\r\n" ), RawX2, RawY2 ) );
- }
- }
- // IST thread terminating
- InterruptDone(s_TouchDevice.dwSysIntr);
- InterruptDisable(s_TouchDevice.dwSysIntr);
- CloseHandle(s_TouchDevice.hTouchPanelEvent);
- s_TouchDevice.hTouchPanelEvent = NULL;
- DEBUGMSG(ZONE_TOUCH_IST, (L"PDDTouchIST: IST thread ending\r\n"));
- return ERROR_SUCCESS;
- }
- //==============================================================================
- // Function Name: PDDInitializeHardware
- //
- // Description: This routine configures the SPI channel and GPIO pin for interrupt mode.
- //
- // Arguments: None
- //
- // Ret Value: TRUE - Success
- // FAIL - Failure
- //==============================================================================
- BOOL PDDInitializeHardware(LPCTSTR pszActiveKey)
- {
- BOOL rc = FALSE;
- DWORD config;
- UINT32 spiBuffer;
- UINT32 xPos, yPos;
- DEBUGMSG(ZONE_FUNCTION, (TEXT("PDDInitializeHardware+\r\n")));
- if (IsDVIMode())
- goto cleanup;
- // Read parameters from registry
- if (GetDeviceRegistryParams(
- pszActiveKey,
- &s_TouchDevice,
- dimof(s_deviceRegParams),
- s_deviceRegParams) != ERROR_SUCCESS)
- {
- DEBUGMSG(ZONE_ERROR, (TEXT("ERROR: PDDInitializeHardware: Error reading from Registry.\r\n")));
- goto cleanup;
- }
- // Open GPIO driver
- s_TouchDevice.hGPIO = GPIOOpen();
- if (s_TouchDevice.hGPIO == NULL)
- {
- DEBUGMSG(ZONE_ERROR, (TEXT("ERROR: PDDInitializeHardware: Failed open GPIO device driver\r\n")));
- goto cleanup;
- }
- // RESET LOW
- GPIOClrBit(s_TouchDevice.hGPIO, 176);
- GPIOSetMode(s_TouchDevice.hGPIO, 176, GPIO_DIR_OUTPUT);
- Sleep ( 10 );
- GPIOSetBit(s_TouchDevice.hGPIO, 176); // RESET HIGH
- Sleep ( 130 );
- // Setup nPENIRQ for input mode, raising edge detect, debounce enable
- GPIOSetMode(s_TouchDevice.hGPIO, s_TouchDevice.nPenGPIO, GPIO_DIR_INPUT|GPIO_INT_LOW_HIGH|GPIO_DEBOUNCE_ENABLE);
- // Get the IRQ for the GPIO
- s_TouchDevice.nPenIRQ = GPIOGetSystemIrq(s_TouchDevice.hGPIO, s_TouchDevice.nPenGPIO);
- RETAILMSG(1, (L"s_TouchDevice.nPenGPIO=%d\r\n", s_TouchDevice.nPenGPIO));
- // Set debounce time on GPIO
- IOCTL_GPIO_SET_DEBOUNCE_TIME_IN debounce;
- debounce.gpioId = s_TouchDevice.nPenGPIO;
- debounce.debounceTime = 10;
- // Open I2C driver
- s_TouchDevice.hI2C = I2COpen(OMAP_DEVICE_I2C2);
- if (s_TouchDevice.hI2C == NULL)
- {
- DEBUGMSG(ZONE_ERROR, (TEXT("ERROR: PDDInitializeHardware: Failed open I2C device driver\r\n")));
- goto cleanup;
- }
- I2CSetSlaveAddress(s_TouchDevice.hI2C, 0x10);
- I2CSetSubAddressMode(s_TouchDevice.hI2C, I2C_SUBADDRESS_MODE_8);
- I2CSetBaudIndex(s_TouchDevice.hI2C, SLOWSPEED_MODE);
- UINT8 i2c_data = 0;
- DWORD len = 0;
- // read one byte thru i2c
- len = I2CRead(s_TouchDevice.hI2C, 0x0e, &i2c_data, sizeof(UINT8));
- RETAILMSG(1, (L"i2c_data : 0x0e=%04X, len=%x\r\n", i2c_data, len));
- len = I2CRead(s_TouchDevice.hI2C, 0x0f, &i2c_data, sizeof(UINT8));
- RETAILMSG(1, (L"i2c_data : 0x0f=%04X, len=%x\r\n", i2c_data, len));
- if (len != sizeof(UINT8)) {
- ERRORMSG(ZONE_ERROR, (TEXT("I2CRead Failed!!\r\n")));
- goto cleanup;
- }
- // write scan_complete to clean up interrupt line.
- //i2c_data = 0x80;
- //len = I2CWrite(s_TouchDevice.hI2C, 0x10, &i2c_data, sizeof(UINT8));
- //Sleep(130);
- // write scan_complete to clean up interrupt line.
- i2c_data = 0x00;
- len = I2CWrite(s_TouchDevice.hI2C, 0x11, &i2c_data, sizeof(UINT8));
- if (len != sizeof(UINT8)) {
- ERRORMSG(ZONE_ERROR, (TEXT("I2CWrite Failed!!\r\n")));
- goto cleanup;
- }
- // Done
- rc = TRUE;
- cleanup:
- DEBUGMSG(ZONE_FUNCTION, (TEXT("PDDInitializeHardware-\r\n")));
- if( rc == FALSE )
- {
- PDDDeinitializeHardware();
- }
- return rc;
- }
- //==============================================================================
- // Function Name: PDDDeinitializeHardware
- //
- // Description: This routine Deinitializes the h/w by closing the SPI channel and GPIO pin
- //
- // Arguments: None
- //
- // Ret Value: None
- //==============================================================================
- VOID PDDDeinitializeHardware()
- {
- DEBUGMSG(ZONE_FUNCTION, (TEXT("PDDDeinitializeHardware+\r\n")));
- // Close I2C device
- if (s_TouchDevice.hI2C != NULL)
- {
- I2CClose(s_TouchDevice.hI2C);
- s_TouchDevice.hI2C = NULL;
- }
- // Close GPIO device
- if (s_TouchDevice.hGPIO != NULL)
- {
- GPIOClose(s_TouchDevice.hGPIO);
- s_TouchDevice.hGPIO = NULL;
- }
- DEBUGMSG(ZONE_FUNCTION, (TEXT("PDDDeinitializeHardware-\r\n")));
- }
- //==============================================================================
- // Function Name: PDDTouchPanelEnable
- //
- // Description: This routine creates the touch thread(if it is not already created)
- // initializes the interrupt and unmasks it.
- //
- // Arguments: None
- //
- // Ret Value: TRUE - Success
- //==============================================================================
- BOOL PDDTouchPanelEnable()
- {
- DEBUGMSG(ZONE_FUNCTION, (TEXT("PDDTouchPanelEnable+\r\n")));
- // Check if already running
- if( s_TouchDevice.hTouchPanelEvent == NULL )
- {
- // Clear terminate flag
- s_TouchDevice.bTerminateIST = FALSE;
- // Create touch event
- s_TouchDevice.hTouchPanelEvent = CreateEvent( NULL, FALSE, FALSE, NULL );
- if( !s_TouchDevice.hTouchPanelEvent )
- {
- DEBUGMSG(ZONE_ERROR,(TEXT("PDDTouchPanelEnable: Failed to initialize touch event.\r\n")));
- return FALSE;
- }
- // Map SYSINTR to event
- if (!InterruptInitialize(s_TouchDevice.dwSysIntr, s_TouchDevice.hTouchPanelEvent, NULL, 0))
- {
- DEBUGMSG(ZONE_ERROR, (TEXT("PDDTouchPanelEnable: Failed to initialize interrupt.\r\n")));
- return FALSE;
- }
- // Create IST thread
- s_TouchDevice.hIST = CreateThread( NULL, 0, PDDTouchIST, 0, 0, NULL );
- if( s_TouchDevice.hIST == NULL )
- {
- DEBUGMSG(ZONE_ERROR, (TEXT("PDDTouchPanelEnable: Failed to create IST thread\r\n")));
- return FALSE;
- }
- // set IST thread priority
- CeSetThreadPriority ( s_TouchDevice.hIST, s_TouchDevice.dwISTPriority);
- if (s_TouchDevice.dwSysIntr != SYSINTR_NOP)
- InterruptMask(s_TouchDevice.dwSysIntr, FALSE);
- }
- DEBUGMSG(ZONE_FUNCTION, (TEXT("PDDTouchPanelEnable-\r\n")));
- return TRUE;
- }
- //==============================================================================
- // Function Name: PDDTouchPanelDisable
- //
- // Description: This routine closes the IST and releases other resources.
- //
- // Arguments: None
- //
- // Ret Value: TRUE - Success
- //==============================================================================
- VOID PDDTouchPanelDisable()
- {
- DEBUGMSG(ZONE_FUNCTION, (TEXT("PDDTouchPanelDisable+\r\n")));
- // Disable touch interrupt service thread
- if( s_TouchDevice.hTouchPanelEvent )
- {
- if (s_TouchDevice.dwSysIntr != SYSINTR_NOP)
- InterruptMask(s_TouchDevice.dwSysIntr, TRUE);
- s_TouchDevice.bTerminateIST = TRUE;
- SetEvent( s_TouchDevice.hTouchPanelEvent );
- s_TouchDevice.hTouchPanelEvent = 0;
- }
- //Closing IST handle
- if(s_TouchDevice.hIST)
- {
- CloseHandle(s_TouchDevice.hIST);
- s_TouchDevice.hIST=NULL;
- }
- DEBUGMSG(ZONE_FUNCTION, (TEXT("PDDTouchPanelDisable-\r\n")));
- }
- #else
- //------------------------------------------------------------------------------
- // Platform
- //
- #include "omap.h"
- #include <ceddk.h>
- #include <ceddkex.h>
- #include <oal.h>
- #include <oalex.h>
- #include <initguid.h>
- #include <sdk_gpio.h>
- #include "gpio_ioctls.h"
- #include "sdk_spi.h"
- #include "omap_mcspi_regs.h"
- #include "touchscreenpdd.h"
- //------------------------------------------------------------------------------
- // Defines
- //
- #define SPI1_DEVICE_NAME L"SPI1:"
- //------------------------------------------------------------------------------
- // Debug zones
- //
- #ifndef SHIP_BUILD
- #undef ZONE_ERROR
- #undef ZONE_WARN
- #undef ZONE_FUNCTION
- #undef ZONE_INFO
- #undef ZONE_TIPSTATE
- #define ZONE_ERROR DEBUGZONE(0)
- #define ZONE_WARN DEBUGZONE(1)
- #define ZONE_FUNCTION DEBUGZONE(2)
- #define ZONE_INFO DEBUGZONE(3)
- #define ZONE_TIPSTATE DEBUGZONE(4)
- #endif
- //------------------------------------------------------------------------------
- // globals
- //
- static DWORD s_mddContext;
- static PFN_TCH_MDD_REPORTSAMPLESET s_pfnMddReportSampleSet;
- //==============================================================================
- // Function Name: TchPdd_Init
- //
- // Description: PDD should always implement this function. MDD calls it during
- // initialization to fill up the function table with rest of the
- // Helper functions.
- //
- // Arguments:
- // [IN] pszActiveKey - current active touch driver key
- // [IN] pMddIfc - MDD interface info
- // [OUT]pPddIfc - PDD interface (the function table to be filled)
- // [IN] hMddContext - mdd context (send to MDD in callback fn)
- //
- // Ret Value: pddContext.
- //==============================================================================
- extern "C" DWORD WINAPI TchPdd_Init(LPCTSTR pszActiveKey,
- TCH_MDD_INTERFACE_INFO* pMddIfc,
- TCH_PDD_INTERFACE_INFO* pPddIfc,
- DWORD hMddContext
- )
- {
- DWORD pddContext = 0;
- DEBUGMSG(ZONE_FUNCTION, (TEXT("TchPdd_Init+\r\n")));
- // Initialize once only
- if (s_TouchDevice.bInitialized)
- {
- pddContext = (DWORD) &s_TouchDevice;
- goto cleanup;
- }
- // Create the event for touch panel events.
- // If creation fails, return failure.
- s_TouchDevice.hTouchPanelEvent = CreateEvent( NULL, FALSE, FALSE, NULL);
- if (s_TouchDevice.hTouchPanelEvent == NULL)
- {
- DEBUGMSG(ZONE_ERROR, (TEXT("ERROR: TOUCH: Touch Event Creation Failed\r\n")));
- goto cleanup;
- }
- // Remember the callback function pointer
- s_pfnMddReportSampleSet = pMddIfc->pfnMddReportSampleSet;
- // Remember the mdd context
- s_mddContext = hMddContext;
- s_TouchDevice.nSampleRate = DEFAULT_SAMPLE_RATE;
- s_TouchDevice.dwPowerState = D0;
- s_TouchDevice.dwSamplingTimeOut = INFINITE;
- s_TouchDevice.bTerminateIST = FALSE;
- s_TouchDevice.hTouchPanelEvent = 0;
- // Initialize HW
- if (!PDDInitializeHardware(pszActiveKey))
- {
- DEBUGMSG(ZONE_ERROR, (TEXT("ERROR: TOUCH: Failed to initialize touch PDD.\r\n")));
- goto cleanup;
- }
- // Get sysintr values from the OAL for PENIRQ interrupt
- if (!KernelIoControl(
- IOCTL_HAL_REQUEST_SYSINTR,
- &s_TouchDevice.nPenIRQ,
- sizeof(s_TouchDevice.nPenIRQ),
- &s_TouchDevice.dwSysIntr,
- sizeof(s_TouchDevice.dwSysIntr),
- NULL
- ) )
- {
- DEBUGMSG(ZONE_ERROR, (TEXT("ERROR: TOUCH: Failed to request the touch sysintr.\r\n")));
- s_TouchDevice.dwSysIntr = (DWORD)SYSINTR_UNDEFINED;
- goto cleanup;
- }
- //Calibrate the screen, if the calibration data is not already preset in the registry
- PDDStartCalibrationThread();
- //Initialization of the h/w is done
- s_TouchDevice.bInitialized = TRUE;
- pddContext = (DWORD) &s_TouchDevice;
- // fill up pddifc table
- pPddIfc->version = 1;
- pPddIfc->pfnDeinit = TchPdd_Deinit;
- pPddIfc->pfnIoctl = TchPdd_Ioctl;
- pPddIfc->pfnPowerDown = TchPdd_PowerDown;
- pPddIfc->pfnPowerUp = TchPdd_PowerUp;
- cleanup:
- DEBUGMSG(ZONE_FUNCTION, (TEXT("TchPdd_Init-\r\n")));
- return pddContext;
- }
- //==============================================================================
- // Function Name: TchPdd_DeInit
- //
- // Description: MDD calls it during deinitialization. PDD should deinit hardware
- // and deallocate memory etc.
- //
- // Arguments: [IN] hPddContext. pddcontext returned in TchPdd_Init
- //
- // Ret Value: None
- //
- //==============================================================================
- void WINAPI TchPdd_Deinit(DWORD hPddContext)
- {
- DEBUGMSG(ZONE_FUNCTION, (TEXT("TchPdd_Deinit+\r\n")));
- // Remove-W4: Warning C4100 workaround
- UNREFERENCED_PARAMETER(hPddContext);
- // Close the IST and release the resources before
- // de-initializing.
- PDDTouchPanelDisable();
- // Shutdown HW
- PDDDeinitializeHardware();
- // Release interrupt
- if (s_TouchDevice.dwSysIntr != 0)
- {
- KernelIoControl(
- IOCTL_HAL_RELEASE_SYSINTR,
- &s_TouchDevice.dwSysIntr,
- sizeof(s_TouchDevice.dwSysIntr),
- NULL,
- 0,
- NULL
- );
- }
- s_TouchDevice.bInitialized = FALSE;
- DEBUGMSG(ZONE_FUNCTION, (TEXT("TchPdd_Deinit-\r\n")));
- }
- //==============================================================================
- // Function Name: TchPdd_Ioctl
- //
- // Description: The MDD controls the touch PDD through these IOCTLs.
- //
- // Arguments: [IN] hPddContext. pddcontext returned in TchPdd_Init
- // DOWRD dwCode. IOCTL code
- // PBYTE pBufIn. Input Buffer pointer
- // DWORD dwLenIn. Input buffer length
- // PBYTE pBufOut. Output buffer pointer
- // DWORD dwLenOut. Output buffer length
- // PWORD pdwAcutalOut. Actual output buffer length.
- //
- // Ret Value: TRUE if success else FALSE. SetLastError() if FALSE.
- //==============================================================================
- BOOL WINAPI TchPdd_Ioctl(DWORD hPddContext,
- DWORD dwCode,
- PBYTE pBufIn,
- DWORD dwLenIn,
- PBYTE pBufOut,
- DWORD dwLenOut,
- PDWORD pdwActualOut
- )
- {
- DWORD dwResult = ERROR_INVALID_PARAMETER;
- // Remove-W4: Warning C4100 workaround
- UNREFERENCED_PARAMETER(hPddContext);
- switch (dwCode)
- {
- // Enable touch panel
- case IOCTL_TOUCH_ENABLE_TOUCHPANEL:
- DEBUGMSG(ZONE_FUNCTION, (L"TchPdd_Ioctl: IOCTL_TOUCH_ENABLE_TOUCHPANEL\r\n"));
- PDDTouchPanelEnable();
- dwResult = ERROR_SUCCESS;
- break;
- // Disable touch panel
- case IOCTL_TOUCH_DISABLE_TOUCHPANEL:
- DEBUGMSG(ZONE_FUNCTION, (L"TchPdd_Ioctl: IOCTL_TOUCH_DISABLE_TOUCHPANEL\r\n"));
- PDDTouchPanelDisable();
- dwResult = ERROR_SUCCESS;
- break;
- // Get current sample rate
- case IOCTL_TOUCH_GET_SAMPLE_RATE:
- DEBUGMSG(ZONE_FUNCTION, (L"TchPdd_Ioctl: IOCTL_TOUCH_GET_SAMPLE_RATE\r\n"));
- // Check parameter validity
- if ((pBufOut != NULL) && (dwLenOut == sizeof(DWORD)))
- {
- if (pdwActualOut)
- *pdwActualOut = sizeof(DWORD);
- // Get the sample rate
- *((DWORD*)pBufOut) = s_TouchDevice.nSampleRate;
- dwResult = ERROR_SUCCESS;
- }
- break;
- // Set the current sample rate
- case IOCTL_TOUCH_SET_SAMPLE_RATE:
- DEBUGMSG(ZONE_FUNCTION, (L"TchPdd_Ioctl: IOCTL_TOUCH_SET_SAMPLE_RATE\r\n"));
- // Check parameter validity
- if ((pBufIn != NULL) && (dwLenIn == sizeof(DWORD)))
- {
- // Set the sample rate
- s_TouchDevice.nSampleRate = *((DWORD*)pBufIn);
- dwResult = ERROR_SUCCESS;
- }
- break;
- // Get touch properties
- case IOCTL_TOUCH_GET_TOUCH_PROPS:
- // Check parameter validity
- if ((pBufOut != NULL) && (dwLenOut == sizeof(TCH_PROPS)))
- {
- if (pdwActualOut)
- *pdwActualOut = sizeof(TCH_PROPS);\
- // Fill out the touch driver properties
- ((TCH_PROPS*)pBufOut)->minSampleRate = TOUCHPANEL_SAMPLE_RATE_LOW;
- ((TCH_PROPS*)pBufOut)->maxSampleRate = TOUCHPANEL_SAMPLE_RATE_HIGH;
- ((TCH_PROPS*)pBufOut)->minCalCount = 5;
- ((TCH_PROPS*)pBufOut)->maxSimultaneousSamples = 1;
- ((TCH_PROPS*)pBufOut)->touchType = TOUCHTYPE_SINGLETOUCH;
- ((TCH_PROPS*)pBufOut)->calHoldSteadyTime = CAL_HOLD_STEADY_TIME;
- ((TCH_PROPS*)pBufOut)->calDeltaReset = CAL_DELTA_RESET;
- ((TCH_PROPS*)pBufOut)->xRangeMin = RANGE_MIN;
- ((TCH_PROPS*)pBufOut)->xRangeMax = RANGE_MAX;
- ((TCH_PROPS*)pBufOut)->yRangeMin = RANGE_MIN;
- ((TCH_PROPS*)pBufOut)->yRangeMax = RANGE_MAX;
- dwResult = ERROR_SUCCESS;
- }
- break;
- // Power management IOCTLs
- case IOCTL_POWER_CAPABILITIES:
- DEBUGMSG(ZONE_FUNCTION, (L"TchPdd_Ioctl: IOCTL_POWER_CAPABILITIES\r\n"));
- if (pBufOut != NULL && dwLenOut == sizeof(POWER_CAPABILITIES))
- {
- PPOWER_CAPABILITIES ppc = (PPOWER_CAPABILITIES) pBufOut;
- memset(ppc, 0, sizeof(*ppc));
- ppc->DeviceDx = DX_MASK(D0) | DX_MASK(D1) | DX_MASK(D2) | DX_MASK(D3) | DX_MASK(D4);
- if (pdwActualOut)
- *pdwActualOut = sizeof(POWER_CAPABILITIES);
- dwResult = ERROR_SUCCESS;
- }
- break;
- case IOCTL_POWER_GET:
- DEBUGMSG(ZONE_FUNCTION, (L"TchPdd_Ioctl: IOCTL_POWER_GET\r\n"));
- if(pBufOut != NULL && dwLenOut == sizeof(CEDEVICE_POWER_STATE))
- {
- *(PCEDEVICE_POWER_STATE) pBufOut = (CEDEVICE_POWER_STATE) s_TouchDevice.dwPowerState;
- if (pdwActualOut)
- *pdwActualOut = sizeof(CEDEVICE_POWER_STATE);
- dwResult = ERROR_SUCCESS;
- }
- break;
- case IOCTL_POWER_SET:
- DEBUGMSG(ZONE_FUNCTION, (L"TchPdd_Ioctl: IOCTL_POWER_SET\r\n"));
- if(pBufOut != NULL && dwLenOut == sizeof(CEDEVICE_POWER_STATE))
- {
- CEDEVICE_POWER_STATE dx = *(CEDEVICE_POWER_STATE*)pBufOut;
- if( VALID_DX(dx) )
- {
- DEBUGMSG(ZONE_FUNCTION, (L"TchPdd_Ioctl: IOCTL_POWER_SET = to D%u\r\n", dx));
- s_TouchDevice.dwPowerState = dx;
- if (pdwActualOut)
- *pdwActualOut = sizeof(CEDEVICE_POWER_STATE);
- // Enable touchscreen for D0-D2; otherwise disable
- switch( dx )
- {
- case D0:
- case D1:
- case D2:
- // Enable touchscreen
- PDDTouchPanelPowerHandler(FALSE); //Enable Touch ADC
- break;
- case D3:
- case D4:
- // Disable touchscreen
- PDDTouchPanelPowerHandler(TRUE); //Disable Touch ADC
- break;
- default:
- // Ignore
- break;
- }
- dwResult = ERROR_SUCCESS;
- }
- }
- break;
- default:
- dwResult = ERROR_NOT_SUPPORTED;
- break;
- }
- if (dwResult != ERROR_SUCCESS)
- {
- SetLastError(dwResult);
- return FALSE;
- }
- return TRUE;
- }
- //==============================================================================
- // Function Name: TchPdd_PowerUp
- //
- // Description: MDD passes xxx_PowerUp stream interface call to PDD.
- //
- // Arguments: [IN] hPddContext. pddcontext returned in TchPdd_Init
- //
- // Ret Value: None
- //==============================================================================
- void WINAPI TchPdd_PowerUp(
- DWORD hPddContext
- )
- {
- DEBUGMSG(ZONE_FUNCTION, (TEXT("TchPdd_PowerUp+\r\n")));
- // Remove-W4: Warning C4100 workaround
- UNREFERENCED_PARAMETER(hPddContext);
- DEBUGMSG(ZONE_FUNCTION, (TEXT("TchPdd_PowerUp-\r\n")));
- }
- //==============================================================================
- // Function Name: TchPdd_PowerDown
- //
- // Description: MDD passes xxx_PowerDown stream interface call to PDD.
- //
- // Arguments: [IN] hPddContext. pddcontext returned in TchPdd_Init
- //
- // Ret Value: None
- //==============================================================================
- void WINAPI TchPdd_PowerDown(
- DWORD hPddContext
- )
- {
- DEBUGMSG(ZONE_FUNCTION, (TEXT("TchPdd_PowerDown+\r\n")));
- // Remove-W4: Warning C4100 workaround
- UNREFERENCED_PARAMETER(hPddContext);
- DEBUGMSG(ZONE_FUNCTION, (TEXT("TchPdd_PowerDown-\r\n")));
- }
- //==============================================================================
- //Internal Functions
- //==============================================================================
- //==============================================================================
- // Function Name: PDDCalibrationThread
- //
- // Description: This function is called from the PDD Init to calibrate the screen.
- // If the calibration data is already present in the registry,
- // this step is skipped, else a call is made into the GWES for calibration.
- //
- // Arguments: None.
- //
- // Ret Value: Success(1), faliure(0)
- //==============================================================================
- static HRESULT PDDCalibrationThread()
- {
- HKEY hKey;
- DWORD dwType;
- LONG lResult;
- HANDLE hAPIs;
- DEBUGMSG(ZONE_FUNCTION, (TEXT("CalibrationThread+\r\n")));
- // try to open [HKLM\hardware\devicemap\touch] key
- if (ERROR_SUCCESS != RegOpenKeyEx(HKEY_LOCAL_MACHINE, RK_HARDWARE_DEVICEMAP_TOUCH, 0, KEY_ALL_ACCESS, &hKey))
- {
- DEBUGMSG(ZONE_CALIBRATE, (TEXT("CalibrationThread: calibration: Can't find [HKLM/%s]\r\n"), RK_HARDWARE_DEVICEMAP_TOUCH));
- return E_FAIL;
- }
- // check for calibration data (query the type of data only)
- lResult = RegQueryValueEx(hKey, RV_CALIBRATION_DATA, 0, &dwType, NULL, NULL);
- RegCloseKey(hKey);
- if (lResult == ERROR_SUCCESS)
- {
- // registry contains calibration data, return
- return S_OK;
- }
- hAPIs = OpenEvent(EVENT_ALL_ACCESS, FALSE, TEXT("SYSTEM/GweApiSetReady"));
- if (hAPIs)
- {
- WaitForSingleObject(hAPIs, INFINITE);
- CloseHandle(hAPIs);
- }
- // Perform calibration
- TouchCalibrate();
- // try to open [HKLM\hardware\devicemap\touch] key
- if (ERROR_SUCCESS != RegOpenKeyEx(HKEY_LOCAL_MACHINE, RK_HARDWARE_DEVICEMAP_TOUCH, 0, KEY_ALL_ACCESS, &hKey))
- {
- DEBUGMSG(ZONE_CALIBRATE, (TEXT("CalibrationThread: calibration: Can't find [HKLM/%s]\r\n"), RK_HARDWARE_DEVICEMAP_TOUCH));
- return E_FAIL;
- }
- // display new calibration data
- lResult = RegQueryValueEx(hKey, RV_CALIBRATION_DATA, 0, &dwType, NULL, NULL);
- if (lResult == ERROR_SUCCESS)
- {
- TCHAR szCalibrationData[100];
- DWORD Size = sizeof(szCalibrationData);
- RegQueryValueEx(hKey, RV_CALIBRATION_DATA, 0, &dwType, (BYTE *) szCalibrationData, (DWORD *) &Size);
- DEBUGMSG(ZONE_CALIBRATE, (TEXT("touchp: calibration: new calibration data is \"%s\"\r\n"), szCalibrationData));
- RETAILMSG(1, (TEXT("touchp: calibration: new calibration data is \"%s\"\r\n"), szCalibrationData));
- }
- RegCloseKey(hKey);
- DEBUGMSG(ZONE_FUNCTION, (TEXT("CalibrationThread-\r\n")));
- return S_OK;
- }
- //==============================================================================
- // Function Name: PDDStartCalibrationThread
- //
- // Description: This function is creates the calibration thread with
- // PDDCalibrationThread as entry.
- //
- // Arguments: None.
- //
- // Ret Value: None
- //==============================================================================
- void PDDStartCalibrationThread()
- {
- HANDLE hThread;
- hThread = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)PDDCalibrationThread, NULL, 0, NULL);
- // We don't need the handle, close it here
- CloseHandle(hThread);
- }
- //==============================================================================
- // Function Name: PDDGetTouchIntPinState
- //
- // Description: This function is called from the IST to get the status of pen.
- //
- // Arguments: None.
- //
- // Ret Value: Status of the pen.
- //==============================================================================
- inline BOOL PDDGetTouchIntPinState()
- {
- // Return state of pen down
- return( GPIOGetBit(s_TouchDevice.hGPIO, s_TouchDevice.nPenGPIO) == 0 );
- }
- //==============================================================================
- // Function Name: PDDGetControllerData
- //
- // Description: This function is used to get the ADC data through SPI
- //
- // Arguments: None.
- //
- // Ret Value: Status of the pen.
- //==============================================================================
- void PDDGetControllerData(UINT32 control, UINT32 * read_data)
- {
- SPIWriteRead(s_TouchDevice.hSPI, 3, &control, read_data);
- }
- //==============================================================================
- // Function: PDDTouchPanelPowerHandler
- //
- // This function indicates to the driver that the system is entering
- // or leaving the suspend state.
- //
- // Parameters:
- // bOff
- // [in] TRUE indicates that the system is turning off. FALSE
- // indicates that the system is turning on.
- //
- // Returns:
- // None.
- //==============================================================================
- void PDDTouchPanelPowerHandler(BOOL boff)
- {
- DEBUGMSG(ZONE_FUNCTION, (_T("PDDTouchPanelPowerHandler+\r\n")));
- if (s_TouchDevice.dwSysIntr != SYSINTR_NOP)
- InterruptMask(s_TouchDevice.dwSysIntr, boff);
- DEBUGMSG(ZONE_FUNCTION, (_T("PDDTouchPanelPowerHandler-\r\n")));
- return;
- }
- //==============================================================================
- // Function Name: PDDTouchPanelGetPoint
- //
- // Description: This function is used to read the touch coordinates from the h/w.
- //
- // Arguments:
- // TOUCH_PANEL_SAMPLE_FLAGS * - Pointer to the sample flags. This flag is filled with the
- // values TouchSampleDownFlag or TouchSampleValidFlag;
- // INT * - Pointer to the x coordinate of the sample.
- // INT * - Pointer to the y coordinate of the sample.
- //
- // Ret Value: None
- //==============================================================================
- void PDDTouchPanelGetPoint(
- TOUCH_PANEL_SAMPLE_FLAGS *pTipStateFlags,
- INT *pUncalX,
- INT *pUncalY
- )
- {
- // MDD needs us to hold on to last valid sample and previous pen state.
- static USHORT usLastFilteredX = 0; // This holds the previous X sample
- static USHORT usLastFilteredY = 0; // This holds the previous Y sample
- static USHORT usSavedFilteredX = 0; // This holds the last reported X sample
- static USHORT usSavedFilteredY = 0; // This holds the last reported Y sample
- static BOOL bPrevReportedPenDown = FALSE;
- static DWORD DelayedSampleCount = 0;
- BOOL bReportedPenDown = FALSE; // This indicates if we are reporting pen down to the mdd
- BOOL bActualPenDown = FALSE; // This indicates if the pen is actually down, whether we report or not
- UINT32 xpos = 0;
- UINT32 ypos = 0;
- DEBUGMSG(ZONE_FUNCTION&&ZONE_SAMPLES, (TEXT("PDDTouchPanelGetPoint+\r\n")));
- // By default, any sample returned will be ignored.
- *pTipStateFlags = TouchSampleIgnore;
- // Check if pen data are available If so, get the data.
- // Note that we always return data from the previous sample to avoid returning data nearest
- // the point where the pen is going up. Data during light touches is not accurate and should
- // normally be rejected. Without the ability to do pressure measurement, we are limited to
- // rejecting points near the beginning and end of the pen down period.
- bActualPenDown = PDDGetTouchIntPinState();
- if (bActualPenDown == TRUE)
- {
- PDDGetTouchData(&xpos, &ypos);
- // Check if pen is still down to validate the data.
- bActualPenDown = PDDGetTouchIntPinState();
- if (bActualPenDown == TRUE)
- {
- if (DelayedSampleCount > s_TouchDevice.nInitialSamplesDropped)
- {
- // Indicate pen down so we can return valid data.
- bReportedPenDown = TRUE;
- }
- else
- {
- DelayedSampleCount++;
- }
- }
- }
- // Check if we have valid data to report to the MDD.
- if (bReportedPenDown)
- {
- // Return the valid pen data. Note that this data was actually obtained on the
- // previous sample
- *pUncalX = usLastFilteredX;
- *pUncalY = usLastFilteredY;
- // Save the data that we returned.
- // This will also be returned on penup to help avoid returning data obtained during
- // a light press
- usSavedFilteredX = usLastFilteredX;
- usSavedFilteredY = usLastFilteredY;
- DEBUGMSG(ZONE_SAMPLES, ( TEXT( "X(0x%X) Y(0x%X)\r\n" ), *pUncalX, *pUncalY ) );
- // Store reported pen state.
- *pTipStateFlags = TouchSampleDownFlag | TouchSampleValidFlag;
- }
- else // Otherwise, assume pen is up.
- {
- // Check if previously down and valid.
- if ( bPrevReportedPenDown )
- {
- DEBUGMSG(ZONE_TIPSTATE, ( TEXT( "Pen Up!\r\n" ) ) );
- // Use the last valid sample. MDD needs an up with valid data.
- *pUncalX = usSavedFilteredX;
- *pUncalY = usSavedFilteredY;
- *pTipStateFlags = TouchSampleValidFlag;
- }
- DEBUGMSG(ZONE_SAMPLES, ( TEXT( "Point: (%d,%d)\r\n" ), *pUncalX, *pUncalY ) );
- }
- // Save current reported pen state.
- bPrevReportedPenDown = bReportedPenDown;
- // Set up interrupt/timer for next sample
- if (bActualPenDown)
- {
- // Pen down so set MDD timeout for polling mode.
- s_TouchDevice.dwSamplingTimeOut = 1000 / s_TouchDevice.nSampleRate;
- // Save point measured during this sample so it can be reported on the next sample
- usLastFilteredX = (USHORT)xpos;
- usLastFilteredY = (USHORT)ypos;
- }
- else
- {
- // Reset the delayed sample counter
- DelayedSampleCount = 0;
- usLastFilteredX = 0;
- usLastFilteredY = 0;
- // Pen up so set MDD timeout for interrupt mode.
- s_TouchDevice.dwSamplingTimeOut = INFINITE;
- // Set the proper state for the next interrupt.
- InterruptDone( s_TouchDevice.dwSysIntr );
- }
- DEBUGMSG(ZONE_FUNCTION&&ZONE_SAMPLES, (TEXT("PDDTouchPanelGetPoint+\r\n")));
- return;
- }
- //==============================================================================
- // Function Name: PDDGetTouchData
- //
- // Description: Helper function to read 3 samples and find the average of them.
- //
- // Arguments:
- // INT * - Pointer to the x coordinate of the sample.
- // INT * - Pointer to the y coordinate of the sample.
- //
- // Ret Value: TRUE
- //==============================================================================
- BOOL PDDGetTouchData(UINT32 * xpos, UINT32 * ypos)
- {
- UINT32 tempdata = 0;
- UINT16 px, py;
- UINT32 pxAvg = 0, pyAvg = 0;
- int i;
- int iAvg = 0;
- DEBUGMSG(ZONE_FUNCTION, ( TEXT("PDDGetTouchData+\r\n" )) );
- do
- {
- for( i = 0; i < MAX_PTS; i++ )
- {
- PDDGetControllerData(COMMAND_XPOS, &tempdata);
- px = (tempdata & 0x7FF8) >> 3;
- PDDGetControllerData(COMMAND_YPOS, &tempdata);
- py = (tempdata & 0x7FF8) >> 3;
- if (i == 0)
- {
- pxAvg = px;
- pyAvg = py;
- iAvg = 1;
- }
- else if ((((pxAvg >= px) & ((UINT16)(px+DELTA) >= pxAvg)) | ((px > pxAvg) & ((UINT16)(pxAvg+DELTA) > px))) &
- (((pyAvg >=py) & ((UINT16)(py+DELTA) >=pyAvg)) | ((py > pyAvg) & ((UINT16)(pyAvg+DELTA) > py))) )
- {
- pxAvg = (pxAvg +px)/2;
- pyAvg = (pyAvg +py)/2;
- iAvg++;
- }
- else
- break;
- }
- }while(iAvg < MAX_PTS);
- *xpos = pxAvg;
- *ypos = pyAvg;
- // Possibly Pen Up, give pen status detection a chance to debounce
- if(pyAvg == 0 && s_TouchDevice.PenUpDebounceMS) Sleep(s_TouchDevice.PenUpDebounceMS);
- DEBUGMSG(ZONE_FUNCTION, ( TEXT("PDDGetTouchData-\r\n" )) );
- return TRUE;
- }
- //==============================================================================
- // Function Name: PDDTouchIST
- //
- // Description: This is the IST which waits on the touch event or Time out value.
- // Normally the IST waits on the touch event infinitely, but once the
- // pen down condition is recognized the time out interval is changed
- // to dwSamplingTimeOut.
- //
- // Arguments:
- // PVOID - Reseved not currently used.
- //
- // Ret Value: None
- //==============================================================================
- ULONG PDDTouchIST(PVOID reserved)
- {
- TOUCH_PANEL_SAMPLE_FLAGS SampleFlags = 0;
- CETOUCHINPUT input;
- INT32 RawX, RawY;
- // Remove-W4: Warning C4100 workaround
- UNREFERENCED_PARAMETER(reserved);
- DEBUGMSG(ZONE_TOUCH_IST, (L"PDDTouchIST: IST thread started\r\n"));
- // Loop until told to stop
- while(!s_TouchDevice.bTerminateIST)
- {
- // Wait for touch IRQ, timeout or terminate flag
- WaitForSingleObject(s_TouchDevice.hTouchPanelEvent, s_TouchDevice.dwSamplingTimeOut);
- // Check for terminate flag
- if (s_TouchDevice.bTerminateIST)
- break;
- PDDTouchPanelGetPoint( &SampleFlags, &RawX, &RawY);
- if ( SampleFlags & TouchSampleIgnore )
- {
- // do nothing, not a valid sample
- continue;
- }
- //convert x-y coordination to one sample set before sending it to touch MDD.
- if(ConvertTouchPanelToTouchInput(SampleFlags, RawX, RawY, &input))
- {
- //send this 1 sample to mdd
- s_pfnMddReportSampleSet(s_mddContext, 1, &input);
- }
- DEBUGMSG(ZONE_TOUCH_SAMPLES, ( TEXT( "Sample: (%d, %d)\r\n" ), RawX, RawY ) );
- }
- // IST thread terminating
- InterruptDone(s_TouchDevice.dwSysIntr);
- InterruptDisable(s_TouchDevice.dwSysIntr);
- CloseHandle(s_TouchDevice.hTouchPanelEvent);
- s_TouchDevice.hTouchPanelEvent = NULL;
- DEBUGMSG(ZONE_TOUCH_IST, (L"PDDTouchIST: IST thread ending\r\n"));
- return ERROR_SUCCESS;
- }
- //==============================================================================
- // Function Name: PDDInitializeHardware
- //
- // Description: This routine configures the SPI channel and GPIO pin for interrupt mode.
- //
- // Arguments: None
- //
- // Ret Value: TRUE - Success
- // FAIL - Failure
- //==============================================================================
- BOOL PDDInitializeHardware(LPCTSTR pszActiveKey)
- {
- BOOL rc = FALSE;
- DWORD config;
- UINT32 spiBuffer;
- UINT32 xPos, yPos;
- DEBUGMSG(ZONE_FUNCTION, (TEXT("PDDInitializeHardware+\r\n")));
- if (IsDVIMode())
- goto cleanup;
- // Read parameters from registry
- if (GetDeviceRegistryParams(
- pszActiveKey,
- &s_TouchDevice,
- dimof(s_deviceRegParams),
- s_deviceRegParams) != ERROR_SUCCESS)
- {
- DEBUGMSG(ZONE_ERROR, (TEXT("ERROR: PDDInitializeHardware: Error reading from Registry.\r\n")));
- goto cleanup;
- }
- // Open GPIO driver
- s_TouchDevice.hGPIO = GPIOOpen();
- if (s_TouchDevice.hGPIO == NULL)
- {
- DEBUGMSG(ZONE_ERROR, (TEXT("ERROR: PDDInitializeHardware: Failed open GPIO device driver\r\n")));
- goto cleanup;
- }
- // Setup nPENIRQ for input mode, falling edge detect, debounce enable
- GPIOSetMode(s_TouchDevice.hGPIO, s_TouchDevice.nPenGPIO, GPIO_DIR_INPUT|GPIO_INT_HIGH_LOW|GPIO_DEBOUNCE_ENABLE);
- // Get the IRQ for the GPIO
- s_TouchDevice.nPenIRQ = GPIOGetSystemIrq(s_TouchDevice.hGPIO, s_TouchDevice.nPenGPIO);
- // Set debounce time on GPIO
- IOCTL_GPIO_SET_DEBOUNCE_TIME_IN debounce;
- debounce.gpioId = s_TouchDevice.nPenGPIO;
- debounce.debounceTime = 10;
- // Open SPI driver
- s_TouchDevice.hSPI = SPIOpen(SPI1_DEVICE_NAME);
- if (s_TouchDevice.hSPI == NULL)
- {
- DEBUGMSG(ZONE_ERROR, (TEXT("ERROR: PDDInitializeHardware: Failed open SPI device driver\r\n")));
- goto cleanup;
- }
- // Settings for Touchscreen device
- //
- // Tx/Rx
- // Tx enable on data line 0
- //
- // Raising clock rate can make the touch screen sample unstable, although the rate is in the nominal range.
- config = MCSPI_PHA_ODD_EDGES |
- MCSPI_POL_ACTIVEHIGH |
- MCSPI_CHCONF_CLKD(10) |
- MCSPI_CSPOLARITY_ACTIVELOW |
- MCSPI_CHCONF_WL(24) |
- MCSPI_CHCONF_TRM_TXRX |
- MCSPI_CHCONF_DMAW_DISABLE |
- MCSPI_CHCONF_DMAR_DISABLE |
- MCSPI_CHCONF_DPE0;
- // Configure SPI channel
- if (!SPIConfigure(s_TouchDevice.hSPI, s_TouchDevice.nSPIAddr, config))
- {
- DEBUGMSG(ZONE_ERROR, (TEXT("ERROR: PDDInitializeHardware: Failed configure SPI device driver\r\n")));
- goto cleanup;
- }
- // Enable the touchscreen
- spiBuffer = COMMAND_EN_TOUCH;
- if (!SPIWriteRead(s_TouchDevice.hSPI, sizeof(UINT32), &spiBuffer, &spiBuffer))
- {
- DEBUGMSG(ZONE_ERROR, (TEXT("ERROR: PDDInitializeHardware: failed to enable touchpad on spi bus\r\n")));
- goto cleanup;
- }
- // Grab a point from touchscreen
- PDDGetTouchData( &xPos, &yPos );
- // Done
- rc = TRUE;
- cleanup:
- DEBUGMSG(ZONE_FUNCTION, (TEXT("PDDInitializeHardware-\r\n")));
- if( rc == FALSE )
- {
- PDDDeinitializeHardware();
- }
- return rc;
- }
- //==============================================================================
- // Function Name: PDDDeinitializeHardware
- //
- // Description: This routine Deinitializes the h/w by closing the SPI channel and GPIO pin
- //
- // Arguments: None
- //
- // Ret Value: None
- //==============================================================================
- VOID PDDDeinitializeHardware()
- {
- DEBUGMSG(ZONE_FUNCTION, (TEXT("PDDDeinitializeHardware+\r\n")));
- // Close SPI device
- if (s_TouchDevice.hSPI != NULL)
- {
- SPIClose(s_TouchDevice.hSPI);
- s_TouchDevice.hSPI = NULL;
- }
- // Close GPIO device
- if (s_TouchDevice.hGPIO != NULL)
- {
- GPIOClose(s_TouchDevice.hGPIO);
- s_TouchDevice.hGPIO = NULL;
- }
- DEBUGMSG(ZONE_FUNCTION, (TEXT("PDDDeinitializeHardware-\r\n")));
- }
- //==============================================================================
- // Function Name: PDDTouchPanelEnable
- //
- // Description: This routine creates the touch thread(if it is not already created)
- // initializes the interrupt and unmasks it.
- //
- // Arguments: None
- //
- // Ret Value: TRUE - Success
- //==============================================================================
- BOOL PDDTouchPanelEnable()
- {
- DEBUGMSG(ZONE_FUNCTION, (TEXT("PDDTouchPanelEnable+\r\n")));
- // Check if already running
- if( s_TouchDevice.hTouchPanelEvent == NULL )
- {
- // Clear terminate flag
- s_TouchDevice.bTerminateIST = FALSE;
- // Create touch event
- s_TouchDevice.hTouchPanelEvent = CreateEvent( NULL, FALSE, FALSE, NULL );
- if( !s_TouchDevice.hTouchPanelEvent )
- {
- DEBUGMSG(ZONE_ERROR,(TEXT("PDDTouchPanelEnable: Failed to initialize touch event.\r\n")));
- return FALSE;
- }
- // Map SYSINTR to event
- if (!InterruptInitialize(s_TouchDevice.dwSysIntr, s_TouchDevice.hTouchPanelEvent, NULL, 0))
- {
- DEBUGMSG(ZONE_ERROR, (TEXT("PDDTouchPanelEnable: Failed to initialize interrupt.\r\n")));
- return FALSE;
- }
- // Create IST thread
- s_TouchDevice.hIST = CreateThread( NULL, 0, PDDTouchIST, 0, 0, NULL );
- if( s_TouchDevice.hIST == NULL )
- {
- DEBUGMSG(ZONE_ERROR, (TEXT("PDDTouchPanelEnable: Failed to create IST thread\r\n")));
- return FALSE;
- }
- // set IST thread priority
- CeSetThreadPriority ( s_TouchDevice.hIST, s_TouchDevice.dwISTPriority);
- if (s_TouchDevice.dwSysIntr != SYSINTR_NOP)
- InterruptMask(s_TouchDevice.dwSysIntr, FALSE);
- }
- DEBUGMSG(ZONE_FUNCTION, (TEXT("PDDTouchPanelEnable-\r\n")));
- return TRUE;
- }
- //==============================================================================
- // Function Name: PDDTouchPanelDisable
- //
- // Description: This routine closes the IST and releases other resources.
- //
- // Arguments: None
- //
- // Ret Value: TRUE - Success
- //==============================================================================
- VOID PDDTouchPanelDisable()
- {
- DEBUGMSG(ZONE_FUNCTION, (TEXT("PDDTouchPanelDisable+\r\n")));
- // Disable touch interrupt service thread
- if( s_TouchDevice.hTouchPanelEvent )
- {
- if (s_TouchDevice.dwSysIntr != SYSINTR_NOP)
- InterruptMask(s_TouchDevice.dwSysIntr, TRUE);
- s_TouchDevice.bTerminateIST = TRUE;
- SetEvent( s_TouchDevice.hTouchPanelEvent );
- s_TouchDevice.hTouchPanelEvent = 0;
- }
- //Closing IST handle
- if(s_TouchDevice.hIST)
- {
- CloseHandle(s_TouchDevice.hIST);
- s_TouchDevice.hIST=NULL;
- }
- DEBUGMSG(ZONE_FUNCTION, (TEXT("PDDTouchPanelDisable-\r\n")));
- }
- #endif
Add Comment
Please, Sign In to add comment