📄 tchpdd.cpp
字号:
}
for (irg=0;irg<PENUP_SAMPLE_REJECT;irg++)
{
iPipe[irg].Flags=TouchSampleIgnore;
}
DEBUGMSG(1, (TEXT("DdsiTouchPanelEnable - TIMER : %2x%2x%2x%2x size:0x%x \r\n"),
pTimer->TimerPeriphID3, pTimer->TimerPeriphID2,
pTimer->TimerPeriphID1, pTimer->TimerPeriphID0, sizeof( stDualTimerRegs) ) );
pTimer->Timer0.Control = 0;
pTimer->Timer0.InterruptClear = 1;
pTimer->Timer0.Control = TimerControlIntEnable | TimerControlPeriodic | TimerControlSize32 | TimerControlOneShot;
pTimer->Timer0.Load = OEM_COUNT_1MS * MS_BETWEEN_READINGS;
// Power on touch panel
TouchPanelPowerOn();
// Init SSP control structure.
pSspHead = (PL022 *)(&SspStruc);
PhysicalAddress.HighPart = 0;
PhysicalAddress.LowPart = PHYS_SSP_BASE; //PHYS_SSP_BASE
pSspHead = (PL022 *)MmMapIoSpace( PhysicalAddress, sizeof(PL022), FALSE);
if(pSspHead== NULL)
{
DEBUGMSG(1, (TEXT("GIO_Init: Error SSP MmMapIoSpace failed\r\n")));
return FALSE;
}
else
DEBUGMSG(1, (TEXT("GIO_Init: SSP MmMapIoSpace 0x%x\r\n"), pSspHead));
pSspHead->SSPCR0 = 0x0F27; //*(SSP_BASE + 0x00) = 0x0F27; // SCR[7:0] = f, NS mode, 8-bits/ts
pSspHead->SSPIMSC = 0x0000; //*(SSP_BASE + 0x14) = 0x0000; // interrupt is mask
pSspHead->SSPCPSR = 0x0014; //*(SSP_BASE + 0x10) = 0x0014; // pre-scale : CPSDVSR=20
pSspHead->SSPDMACR = 0x0000; //*(SSP_BASE + 0x24) = 0x0000; // disable Tx&Rx DMA
pSspHead->SSPCR1 = 0x0000; //*(SSP_BASE + 0x04) = 0x0000; // disable SSP
// Init GPIO control structure.
pGpioHead = (PGPIO_REGS)(&GpioStruc);
PhysicalAddress.HighPart = 0;
PhysicalAddress.LowPart = GPIO6_BASE; //PHYS_GPIO6_BASE
pGpioHead = (PGPIO_REGS)MmMapIoSpace( PhysicalAddress, sizeof(GPIO_REGS), FALSE);
if(pGpioHead == NULL)
{
DEBUGMSG(1, (TEXT("GIO_Init: Error GPIO2 MmMapIoSpace failed\r\n")));
return FALSE;
}
pGpioHead->dwGPIODir &= ~0x80;
pGpioHead->dwGPIOIE &= ~0x80;
pGpioHead->dwGPIOIC |= 0x80;
DEBUGMSG(1, (TEXT("GIO_Init: Intr disable\r\n")));
Sleep(1); // sleep for 1ms to alow screen to recharge
PddpSetupPenDownIntr(TRUE);
ResetEvent(hTouchPanelEvent); // clear down interrupt event (belt and braces)
return( TRUE ); // we always succeed
}
// @doc EX_TOUCH_DDSI EXTERNAL DRIVERS DDSI TOUCH_PANEL
//
// @func ULONG | DdsiTouchPanelDisable |
// Powers down the touch panel device.
//
// @comm
// Implemented in the PDD.
//
VOID
DdsiTouchPanelDisable(
VOID
)
{
DEBUGMSG(1, (_T("Touchscreen: DdsiTouchPanelDisable\r\n")));
PddpTouchPanelDeallocateVm();
if (pGpioHead != NULL)
{
MmUnmapIoSpace(pGpioHead, sizeof(GPIO_REGS));
pGpioHead = NULL;
}
if (pSspHead!= NULL)
{
MmUnmapIoSpace(pSspHead, sizeof(PL022));
pSspHead= NULL;
}
}
//
// @doc EX_TOUCH_DDSI EXTERNAL DRIVERS DDSI TOUCH_PANEL
//
// @func LONG | DdsiTouchPanelAttach |
// This routine no longer does anything. All functionallity has been moved
// from here into DdsiTouchPanelEnable to allow this code to be statically
// linked with GWE rather than existing as a DLL. Technically, when built
// as a DLL we should keep an attach count and only allow touh.dll to be
// loaded once. But, since we are loaded at boot time by GWE, there is
// no real concern about multiple loads (unless gwe has a bug!).
//
// @rdesc
// Always returns 0
//
// @comm
// Implemented in the PDD.
//
LONG
DdsiTouchPanelAttach(
VOID
)
{
return( 0 );
}
//
// @doc EX_TOUCH_DDSI EXTERNAL DRIVERS DDSI TOUCH_PANEL
//
// @func LONG | DdsiTouchPanelDetach |
// See the descrition for attach. All functionallity has been moved into
// DdsiTouchPanelDisable.
//
// @rdesc
// The updated global counter. If the initializations failed, the returned
// count is 0.
//
// @comm
// Implemented in the PDD.
//
LONG
DdsiTouchPanelDetach(
VOID
)
{
return ( 0 );
}
//
// @doc EX_TOUCH_DDSI EXTERNAL DRIVERS DDSI TOUCH_PANEL
//
// @func void | DdsiTouchPanelGetPoint |
// Returns the most recently acquired point and its associated tip state
// information.
//
// @parm PDDSI_TOUCHPANEL_TIPSTATE | pTipState |
// Pointer to where the tip state information will be returned.
// @parm PLONG | pUnCalX |
// Pointer to where the x coordinate will be returned.
// @parm PLONG | pUnCalY |
// Pointer to where the y coordinate will be returned.
//
// @comm
// Implmented in the PDD.
//
//const SAMPLE INITSAMPLES ={TouchSampleIgnore,0,0};
BOOL PrevTipUp=TRUE;
VOID
DdsiTouchPanelGetPoint(
TOUCH_PANEL_SAMPLE_FLAGS *pTipStateFlags,
INT *pUncalX,
INT *pUncalY
)
{
DEBUGMSG(1, (TEXT("Touchscreen: DdsiTouchPanelGetPoint\r\n")));
ULONG status;
static int SampleCount = 0;
TOUCH_PANEL_SAMPLE_FLAGS TmpStateFlags;
INT TmpX = 0;
INT TmpY = 0;
// First check if the pen was down
if (PddpTouchPanelPenDown())
{
status=TOUCH_PEN_DOWN;
}
else
{
status=TOUCH_PEN_UP;
}
// By default, any sample returned will be ignored
*pTipStateFlags = TouchSampleIgnore;
// int PrevTipUp_temp = PrevTipUp?1:0;
// DEBUGMSG(1, (_T("Touchscreen: DdsiTouchPanelGetPoint - PrevTipUp:%d\r\n"), PrevTipUp_temp));
// Handle the interrupt appropriately.
// The possible causes of the interrupt are
// - Pen down event
// - Pen up event
// - Pen coordinate sample ready.
if ((status == TOUCH_PEN_DOWN) && (PrevTipUp))
{
DEBUGMSG(1, (TEXT("DdsiTouchPanelGetPoint - Pen has gone down!!.\r\n") ) );
// We ONLY get here by a pen down GPIO interrupt
// Pen has gone down - enable the timer and disable the pen down interrupt.
PddpSetupPenDownIntr(FALSE);
// the timer will trigger the same response as the PENIRQ line, thus
// setting up a timer callback
DEBUGMSG(1, (TEXT("DdsiTouchPanelGetPoint - Running Timer\r\n") ) );
pTimer->Timer0.InterruptClear = 1;
pTimer->Timer0.Control = pTimer->Timer0.Control | (TimerControlEnable);
// The position returned is to be ignored
for (unsigned long irg=0;irg<PENUP_SAMPLE_REJECT;irg++)
{
iPipe[irg].Flags=TouchSampleIgnore;
}
// don't give TouchSampleDown here for cases where the pen touch is really brief!
*pTipStateFlags = TouchSampleIgnore;
PrevTipUp =FALSE;
DEBUGMSG(1, (TEXT("DdsiTouchPanelGetPoint - Sending Pen down to MDD \r\n") ) );
if (*pTipStateFlags & TouchSampleValidFlag) {
DEBUGMSG(1, (TEXT("Valid sample. X = 0x%4X, Y = 0x%4X, Flags = 0x%4X\r\n"),
*pUncalX, *pUncalY,*pTipStateFlags) );
} else {
DEBUGMSG(1, (TEXT("Invalid sample. X = 0x%4X, Y = 0x%4X, Flags = 0x%4X\r\n"),
*pUncalX, *pUncalY,*pTipStateFlags) );
}
}
else if (status == TOUCH_PEN_UP)
{
DEBUGMSG(1, (TEXT("DdsiTouchPanelGetPoint - Pen has gone up.\r\n") ) );
// Pen has gone up
// We only get here by a timer call
// But as the pen is now up we ought to remove the ability of the timer thread
DEBUGMSG(1, (TEXT("DdsiTouchPanelGetPoint - Disabling Timer\r\n") ) );
pTimer->Timer0.Control = pTimer->Timer0.Control & ~(TimerControlEnable);
pTimer->Timer0.InterruptClear = 1;
// Pen up is indicated by the absence of TouchSampleDownFlag in
// the TipStateFlags. Where available, the most recent valid x
// and y coords are returned with the pen up state. It appears
// from the PeRP driver that this these coords are not important,
// however.
// Only report a pen up if the last valid thing reported wasn't
// a pen up (to ensure that GWE doesn't get multiple pen up events)
if ((iPipe[0].Flags & TouchSampleDownFlag) &&
(iPipe[0].Flags & TouchSampleValidFlag) &&
(SampleCount >= TOUCH_NUM_REJECT))
{
// we have to show previous valid sample and pen up
*pTipStateFlags = TouchSampleValidFlag;
*pUncalX = iPipe[0].Xval;
*pUncalY = iPipe[0].Yval;
DEBUGMSG(1, (TEXT("Sending pen up to MDD\r\n") ) );
}
else
{
DEBUGMSG(1, (TEXT("Pen is up, but was never down to system \r\n") ) );
}
// Clear the previous state storage
iPipe[0].Flags = TouchSampleIgnore;
iPipe[0].Xval = iPipe[0].Yval = 0;
SampleCount = 0;
PrevTipUp =TRUE;
// Re-enable that GPIO line for interrupts (no timer)
PddpSetupPenDownIntr(TRUE);
if (*pTipStateFlags & TouchSampleValidFlag) {
DEBUGMSG(1, (TEXT("Valid sample. X = 0x%4X, Y = 0x%4X, Flags = 0x%4X\r\n"),
*pUncalX, *pUncalY,*pTipStateFlags) );
} else {
DEBUGMSG(1, (TEXT("Invalid sample. X = 0x%4X, Y = 0x%4X, Flags = 0x%4X\r\n"),
*pUncalX, *pUncalY,*pTipStateFlags) );
}
}
else
{
// New pen coordinate sample is ready
// We only get here by a timer thread event - but as we want these to
// continue - so do nothing to it!
// We always return the previously sampled X and Y coords.
// This ensures that if a pen up occurs, we won't return an
// (x,y) pair that was sampled at the same time as the pen up.
// Not doing this results in the ends of some lines having a tail
// as the pen went up after pen up sampling but before x,y sampling
*pTipStateFlags = iPipe[0].Flags;
*pUncalX = iPipe[0].Xval;
*pUncalY = iPipe[0].Yval;
PrevTipUp =FALSE;
// Get the coordinates
// The pen is down, but the coordinates are still by default ignored
TmpStateFlags = TouchSampleDownFlag | TouchSampleIgnore;
// Get and evaluate the coordinates. If they are OK, the state flags
// will be altered to indicate that they are valid.
PddpTouchPanelEvaluateSamples( &TmpStateFlags, &TmpX, &TmpY);
// To work around hardware problems, ignore first few samples
// left in for possible future use
if( SampleCount < TOUCH_NUM_REJECT ) {
SampleCount++;
*pTipStateFlags = TouchSampleIgnore;
TmpStateFlags = TouchSampleIgnore;
}
// If this is a valid sample, remember it
if (TmpStateFlags & TouchSampleValidFlag)
{
for (int i=0;i<(PENUP_SAMPLE_REJECT-1); i++)
{
iPipe[i] = iPipe[i+1];
}
iPipe[i].Flags= TmpStateFlags;
iPipe[i].Xval = TmpX;
iPipe[i].Yval = TmpY;
}
if (*pTipStateFlags & TouchSampleValidFlag) {
DEBUGMSG(1, (TEXT("Valid sample. X = 0x%4X, Y = 0x%4X, Flags = 0x%4X\r\n"),
*pUncalX, *pUncalY,*pTipStateFlags) );
} else {
DEBUGMSG(1, (TEXT("Invalid sample. X = 0x%4X, Y = 0x%4X, Flags = 0x%4X\r\n"),
*pUncalX, *pUncalY,*pTipStateFlags) );
}
}
ResetEvent(hTouchPanelEvent);
pTimer->Timer0.Load = OEM_COUNT_1MS * MS_BETWEEN_READINGS;
pTimer->Timer0.InterruptClear = 1;
InterruptDone(gIntrTouch);
InterruptDone(gIntrTouchChanged);
return;
}
/*++
@func VOID | DdsiTouchPanelPowerHandler |
System power state notification.
@parm BOOL | bOff | TRUE, the system is powering off; FALSE, the system is powering up.
@comm
This routine is called in a kernel context and may not make any system
calls whatsoever. It may read and write its own memory and that's about
it. This routine is called by the MDD and also serves as an internal
helper routine for touch enable/disable.
@devnote This routine will run in kernel context, and may not make
any system calls. If you can any subroutines inside here, make sure
that they also follow this restriction.
--*/
void
DdsiTouchPanelPowerHandler(
BOOL bOff
)
{
DEBUGMSG(1, (TEXT("Touchscreen: DdsiTouchPanelPowerHandler\r\n")));
}
static inline void
TouchPanelPowerOff()
{
// the Touchscreen will automatically power down between samples, so
// no further work to be done here
// If the ^PenIRQ line was pulled up using GPIO instead of Vcc then
// it could be turned off here
}
static void
TouchPanelPowerOn()
{
// as we don't do anything above then we can't do anything here
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -