Monday 14 December 2009

Windows Embedded CE touch driver consideration

Hi folks,

As you might have noticed, the Windows Embedded CE touch driver uses TWO interrupts. One interrupt (SYSINTR_TOUCH) to wait for the user to touch the screen, while the other interrupt is a timer (SYSINTR_TOUCH_CHANGED). Upon its expiration the touch driver determines if the touch is still pressed, if so the coordinates are measured and the timer is reset; if not the touch driver switches back to the first interrupt to wait for the user to press the screen.

This is a relict from Windows CE versions prior to 3.0 when the systemtick was still 20ms. Hence the systemtick was too long to be used as a timer for the touch screen.

However, this implementation sometimes leads to unexplainable behavior/errors due to the fact that interrupt events are queued differently in your system then regular events. An interrupt service thread (IST) should therefore only consist of ONE (and only ONE) WaitForSingleObject() as well as ONE (and only ONE) InterruptDone()! Unfortunately this implementation uses TWO WaitForSingleObject() calls in its IST!

On top of that, it also utilized unnecessary resources namely the extra timer.

An elegant solution would be to get rid of the extra timer and use a Sleep() in its stead:


static ULONG TouchPanelpISR(PVOID Reserved)
{
...

static BOOL fStartIST = TRUE;

...

while(!bTerminate)

{

if(CurrentDown)

{

...

Sleep(5); // use appropriate value here

}

else

{

// don't call InterruptDone the first time

// as this is done by InterruptInitialize

if (!fStartIST)

{

InterruptDone( gIntrTouch );

...

}

else

{

fStartIST = FALSE;

}

WaitForSingleObject( hTouchPanelEvent, gdwTouchIstTimeout );

}

...

}

...

}

Stay tuned for part II!

Have Fun!

No comments: