📄 bsptouch.cpp
字号:
//------------------------------------------------------------------------------
//
// Copyright (C) 2004, Motorola Inc. All Rights Reserved
//
//------------------------------------------------------------------------------
//
// Copyright (C) 2004-2007, Freescale Semiconductor, Inc. All Rights Reserved.
// THIS SOURCE CODE, AND ITS USE AND DISTRIBUTION, IS SUBJECT TO THE TERMS
// AND CONDITIONS OF THE APPLICABLE LICENSE AGREEMENT
//
//------------------------------------------------------------------------------
//------------------------------------------------------------------------------
//
// File: bsptouch.cpp
//
// Provides the implementation for BSP-specific touch support.
//
//------------------------------------------------------------------------------
#include <windows.h>
#include <tchddsi.h>
#include "bsp.h"
//-----------------------------------------------------------------------------
// External Variables
extern "C" const int MIN_CAL_COUNT = 25;
extern DWORD gIntrTouch;
extern DWORD gIntrTouchChanged;
extern DWORD CurSampleRateStatic;
//------------------------------------------------------------------------------
// MACRO DEFINITIONS
//------------------------------------------------------------------------------
// Numbers of samples to obtain per CSPI exchange(sample number <= 3)
#define TOUCH_NUMBER_OF_SAMPLES 5
// These macros define the commands that will send to AD7873
// We use 12-bit resolution and differential reference inputs.
// Power management bits (PD1, PD0) are set to 0.
// Get X, 12 bit, Differential, Ref off, ADC off between conversation
#define TOUCH_CMD_GET_X 0x00D00000
// Get Y, 12 bit, Differential, Ref OFF, ADC off between conversation
#define TOUCH_CMD_GET_Y 0x00900000
#define TOUCH_CMD_INTR_DISABLE 0x00030000
#define TOUCH_CMD_INTR_ENABLE 0x00E00000 //(outputs identity code)
// Touch SPI settings
#define TOUCH_CSPI_FREQ 125000
#define TOUCH_CSPI_PORT CSPISS0
#define TOUCH_CSPI_BIT_LEN 24 // change to 24 bit length
#define TOUCH_CSPI_MODE CSPI_CONTROLREG_MODE_MASTER
// This value is the minimum valid x point.
#define MIN_VALID_PEN_X 25
// Minimum delta to check if two points are too close after calibration
// Note: This is dependent on both the panel size & ADC resolution
#define DELTA_X_PIXEL_VAR 18
#define DELTA_Y_PIXEL_VAR 13
// Samples should not be more than 2 pixels off from each other.
#define DELTA_X_COORD_VARIANCE (2*DELTA_X_PIXEL_VAR)
#define DELTA_Y_COORD_VARIANCE (2*DELTA_Y_PIXEL_VAR)
//------------------------------------------------------------------------------
// GLOBAL OR STATIC VARIABLES
//------------------------------------------------------------------------------
UINT32 gIntrTouchIrq = BSP_PEN_IRQ;
UINT32 gIntrTouchChangedIrq = IRQ_GPT2;
UINT32 gIntrTouchIrqType = OAL_INTR_FORCE_STATIC;
static GPIOHANDLE pTouchGpio = NULL;
static CSPIHANDLE pTouchCspi = NULL;
static CSPICONFIGDATA_T cspiConfigDataStatic;
static CSP_GPT_REGS *pTouchTimerStatic = NULL;
static UINT32 TouchCmdStatic[TOUCH_NUMBER_OF_SAMPLES*2];
static DWORD dwOldX=0, dwOldY=0;
//-----------------------------------------------------------------------------
//
// Function: BSPTouchDeallocate
//
// This function frees the resources allocated by the touch driver.
//
// Parameters:
// None.
//
// RETURNS:
// None.
//
//-----------------------------------------------------------------------------
void BSPTouchDeallocate(void)
{
GPIO_IOCTL_CFG cfg;
HWCLOCK_ID clockId;
DWORD dwTransferred;
// Release IO pin used for touch interrupt
GPIO_SET_IOCTL_STRUCT(cfg, INTR_TOUCH);
KernelIoControl(IOCTL_HAL_DISABLE_GPIO, &cfg, sizeof(cfg), NULL, 0, &dwTransferred);
// Disable Timer2 clock
clockId = HWCLOCK_ID_GPT2;
if(KernelIoControl(IOCTL_HAL_SHUTDOWN_HW_CLK, &clockId, sizeof(clockId),
NULL, 0, &dwTransferred) == FALSE)
DEBUGMSG(ZONE_ERROR, (_T("Timer2 clock disable failed!\r\n")));
// Release sysintrs
if(gIntrTouch != SYSINTR_UNDEFINED){
if (!KernelIoControl(IOCTL_HAL_RELEASE_SYSINTR, &gIntrTouch, sizeof(DWORD), NULL, 0, NULL))
DEBUGMSG(ZONE_FUNCTION, (TEXT("ERROR: Failed to release sysintr for touch.\r\n")));
}
if(gIntrTouchChanged != SYSINTR_UNDEFINED){
if (!KernelIoControl(IOCTL_HAL_RELEASE_SYSINTR, &gIntrTouchChanged, sizeof(DWORD), NULL, 0, NULL))
DEBUGMSG(ZONE_FUNCTION, (TEXT("ERROR: Failed to release sysintr for touch timer.\r\n")));
}
if (pTouchGpio != NULL){
DDKDeleteObject(pTouchGpio);
pTouchGpio = NULL;
}
if (pTouchCspi != NULL){
DDKDeleteObject(pTouchCspi);
pTouchCspi = NULL;
}
if (pTouchTimerStatic != NULL){
MmUnmapIoSpace((void *)pTouchTimerStatic, 0);
pTouchTimerStatic = NULL;
}
}
//-----------------------------------------------------------------------------
//
// Function: BSPTouchInit
//
// Initializes BSP-specific interfaces and data structures for touch support
//
// Parameters:
// None.
//
// Returns:
// TRUE indicates success. FALSE indicates failure.
//
//-----------------------------------------------------------------------------
BOOL BSPTouchInit(void)
{
DWORD dwTransferred;
BOOL status;
HWCLOCK_ID clockId;
PHYSICAL_ADDRESS phyAddr;
GPIO_IOCTL_CFG cfg;
//Initialize GPIO class for pen
DEBUGMSG(ZONE_FUNCTION, (TEXT("DdsiTouchPanelEnable: GPIO\r\n")));
if (pTouchGpio == NULL){
pTouchGpio = DDKCreateGpioObject();
if(!pTouchGpio)
goto cleanUp;
}
DEBUGMSG(ZONE_FUNCTION, (TEXT("DdsiTouchPanelEnable: CSPI\r\n")));
// Initialize SPI class for pen
if (pTouchCspi == NULL){
// Use CSPI1 for
pTouchCspi = DDKCreateCSPIObject(CSPI1);
}
//Initialize Timer for pen to generate interrupt 100 times per second by default
DEBUGMSG(ZONE_FUNCTION, (TEXT("DdsiTouchPanelEnable: GPT\r\n")));
phyAddr.QuadPart = CSP_BASE_REG_PA_GPT2;
pTouchTimerStatic = (CSP_GPT_REGS *)MmMapIoSpace(phyAddr, sizeof(CSP_GPT_REGS), FALSE);
if (pTouchTimerStatic == NULL){
DEBUGMSG(ZONE_ERROR, (_T("GPT2 NULL pointer!\r\n")));
goto cleanUp;
}
// Enable timer2 clock
clockId = HWCLOCK_ID_GPT2;
if(KernelIoControl(IOCTL_HAL_POWER_HW_CLK, &clockId, sizeof(clockId),
NULL, 0, &dwTransferred) == FALSE){
DEBUGMSG(ZONE_ERROR, (_T("Timer2 clock enable failed!\r\n")));
goto cleanUp;
}
// Configure IO used for Pen Interrupt
DEBUGMSG(ZONE_FUNCTION, (TEXT("GPIO pin configuration\r\n")));
GPIO_SET_IOCTL_STRUCT(cfg, INTR_TOUCH);
status = KernelIoControl(IOCTL_HAL_ENABLE_GPIO, &cfg, sizeof(cfg), NULL, 0, &dwTransferred);
if(!status){
DEBUGMSG(ZONE_ERROR, (_T("Enable GPIO pin for touch interrupt failed!\r\n")));
goto cleanUp;
}
// Cmd sequence: (X_CMD, Y_CMD) * TOUCH_NUMBER_OF_SAMPLES
for (int i=0; i<TOUCH_NUMBER_OF_SAMPLES;i++){
if(i == (TOUCH_NUMBER_OF_SAMPLES - 1)){
TouchCmdStatic[i*2] = TOUCH_CMD_GET_X | TOUCH_CMD_INTR_DISABLE;
TouchCmdStatic[i*2+1] = TOUCH_CMD_GET_Y | TOUCH_CMD_INTR_DISABLE;
}else{
TouchCmdStatic[i*2] = TOUCH_CMD_GET_X;
TouchCmdStatic[i*2+1] = TOUCH_CMD_GET_Y;
}
}
// Configure GPIO Interrupt for pen IRQ.
DDKSetGpioInterruptType(pTouchGpio, GPIO_INTR_TOUCH_PORT, GPIO_INTR_TOUCH_PIN, GPIO_INTR_TOUCH_INT_TYPE);
DDKSetGpioInterruptState(pTouchGpio, GPIO_INTR_TOUCH_PORT, GPIO_INTR_TOUCH_PIN, FALSE, TRUE);
// init cspi configure data
cspiConfigDataStatic.CSPIBITLENGTH = TOUCH_CSPI_BIT_LEN;
cspiConfigDataStatic.CSPIFREQUENCY = TOUCH_CSPI_FREQ;
cspiConfigDataStatic.CSPIMODE = TOUCH_CSPI_MODE;
cspiConfigDataStatic.CSPIPHA = CSPI_CONTROLREG_PHA0;
cspiConfigDataStatic.CSPIPOL = CSPI_CONTROLREG_POL_ACTIVE_LOW;
cspiConfigDataStatic.CSPISSCTL = CSPI_CONTROLREG_SSCTL_ASSERT;
cspiConfigDataStatic.CSPISSPOL = CSPI_CONTROLREG_SSPOL_ACTIVE_LOW;
return TRUE;
cleanUp:
BSPTouchDeallocate();
return FALSE;
}
//-----------------------------------------------------------------------------
//
// Function: BSPTouchGetSample
//
// This function is used to get touch screen samples from the ADS7843
// touch screen controller.
//
// Parameters:
// x
// [out] Points to x sample coordinate.
//
// y
// [out] Points to y sample coordinate.
//
// Returns:
// Current touch panel status as TOUCH_PANEL_SAMPLE_FLAGS type.
//
//-----------------------------------------------------------------------------
TOUCH_PANEL_SAMPLE_FLAGS BSPTouchGetSample(INT *x, INT *y)
{
UINT32 dwX[TOUCH_NUMBER_OF_SAMPLES], dwX_Max, dwX_Min;
UINT32 dwY[TOUCH_NUMBER_OF_SAMPLES], dwY_Max, dwY_Min;
UINT32 RxBuf[TOUCH_NUMBER_OF_SAMPLES*2];
UINT32 dwtmp;
UINT NumOfWords;
int i, flag;
TOUCH_PANEL_SAMPLE_FLAGS StateFlags = TouchSampleDownFlag;
// Use Conversion Timing, 16-Clocks per Conversion, 8-bit Bus Interface.
//Write data 0xD0 to CSPI to send command to AD7873
//Measure X, 12 bit, differential, ref OFF, ADC off between conversation = 11010000
//Write data 0x90 to CSPI to send command to AD7873
// Measure Y, 12 bit, differential, ref OFF, ADC off between conversation = 10010000
// Read X and Y Axis
NumOfWords = sizeof(TouchCmdStatic) / sizeof(UINT32);
// Lock the cspi hardware resource
//pTouchCspi->CspiHwResourceLock(TRUE);
DDKCspiHwResourceLock(pTouchCspi, TRUE);
// Configure Cspi
DEBUGMSG(ZONE_FUNCTION, (TEXT("Configuring the cspi hardware\r\n")));
//pTouchCspi->Configure(&cspiConfigDataStatic);
DDKCspiConfigure(pTouchCspi, &cspiConfigDataStatic);
// Select AD7873
//pTouchCspi->ChipSelect(TOUCH_CSPI_PORT);
DDKCspiChipSelect(pTouchCspi, TOUCH_CSPI_PORT);
//pTouchCspi->Exchange((UINT32*)TouchCmdStatic, RxBuf, NumOfWords);
DDKCspiExchange(pTouchCspi, (UINT32*)TouchCmdStatic, RxBuf, NumOfWords);
// Release CSPI hardware resource
//pTouchCspi->CspiHwResourceLock(FALSE);
DDKCspiHwResourceLock(pTouchCspi, FALSE);
// get the x, y coordinate.
for (i = 0; i < TOUCH_NUMBER_OF_SAMPLES; i++){
dwX[i] = (RxBuf[(i*2)] >> 3) & 0xFFF;
dwY[i] = (RxBuf[(i*2)+1] >> 3) & 0xFFF;
DEBUGMSG(ZONE_FUNCTION, (TEXT("dwX[%d](%d) dwY[%d](%d)\r\n"), i, dwX[i], i, dwY[i]));
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -