📄 touchpdd.c
字号:
}
//
// @doc EX_TOUCH_DDSI EXTERNAL DRIVERS DDSI TOUCH_PANEL
//
// @func BOOL | DdsiTouchPanelSetMode |
// Sets information about the physical touch panel device.
//
// @parm ULONG | iIndex |
// Specifies the mode to set. They are one of the following:
//
// @flag TPSM_SAMPLERATE_HIGH_ID |
// Sets the sample rate to the high rate.
// @flag TPSM_SAMPLERATE_LOW_ID |
// Sets the sample rate to the low rate.
//
// @parm LPVOID | lpInput |
// Points to the memory location(s) where the update information
// resides. The format of the memory referenced depends on the
// Points to the memory location(s) where the queried information
// will be placed.
//
// @rdesc
// If the function succeeds the return value is TRUE, otherwise, it is FALSE.
//
// @comm
// Implemented in the PDD.
//
BOOL
DdsiTouchPanelSetMode(
INT iIndex,
LPVOID lpInput
)
{
BOOL ReturnCode = FALSE;
UINT16 WorkSamplingPeriod;
switch (iIndex) {
case TPSM_SAMPLERATE_LOW_ID:
case TPSM_SAMPLERATE_HIGH_ID:
if (iIndex == TPSM_SAMPLERATE_LOW_ID) {
WorkSamplingPeriod = INTVAL_DEFAULT;
CurrentSampleRateSetting = 0;
} else {
WorkSamplingPeriod = INTVAL_HIGH;
CurrentSampleRateSetting = 1;
}
REG16(pVRC4173+PIUSIVLREG) = WorkSamplingPeriod;
g_SamplingPeriod = WorkSamplingPeriod;
SetLastError( ERROR_SUCCESS );
ReturnCode = TRUE;
break;
default:
SetLastError( ERROR_INVALID_PARAMETER );
break;
}
return ReturnCode;
}
//
// @doc EX_TOUCH_DDSI EXTERNAL DRIVERS DDSI TOUCH_PANEL
//
// @func BOOL | DdsiTouchPanelEnable |
// Powers up and initializes the touch panel hardware for operation.
//
// @rdesc
// If the function succeeds, the return value is TRUE; otherwise, it is FALSE.
//
// @comm
// Implemented in the PDD.
//
BOOL
DdsiTouchPanelEnable(
VOID
)
{
if (Enabled)
return TRUE;
if (!Find4173()) {
DEBUGMSG(ZONE_ERROR, (TEXT("TouchPanelEnable: VRC4173 not found\r\n")));
return 2; // HACK ALERT
}
g_SamplingPeriod = INTVAL_DEFAULT; //12ms
DdsiTouchPanelPowerHandler(FALSE); // Power the system up
Enabled = TRUE;
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)
{
//RETAILMSG( 1,(TEXT("Touch Disable\r\n")));
// Check pointers in case the enable failed.
//
if (!Enabled)
return;
DdsiTouchPanelPowerHandler(TRUE); // Power down the device
Free4173();
Enabled = FALSE;
}
//
// @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 1;
}
//
// @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;
}
static VOID
PIUDisable(VOID)
{
// Disable sequencer
REG16(pVRC4173+PIUCNTREG) &= ~PIUSEQEN;
// Wait standby state
while (((REG16(pVRC4173+PIUCNTREG)>>10)&0x07) != PAD_STAT_STANDBY);
}
static VOID
PIUEnable(VOID)
{
REG16(pVRC4173+SELECTREG) &= 0xFFF7;
// Set PIUMODE (Penscan mode:00)
REG16(pVRC4173+PIUCNTREG) &= ~PIUMODE;
// Enable autostop
REG16(pVRC4173+PIUCNTREG) |= PADATSTOP;
// Enable autostart
REG16(pVRC4173+PIUCNTREG) |= PADATSTART;
// Enable sequencer
REG16(pVRC4173+PIUCNTREG) |= PIUSEQEN;
}
//
// @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.
//
VOID
DdsiTouchPanelGetPoint(
TOUCH_PANEL_SAMPLE_FLAGS *pTipStateFlags,
INT *pUncalX,
INT *pUncalY
)
{
static INT PrevX, PrevY;
UINT PageNumber;
USHORT Csr = 0; // read for PIUCNTREG
USHORT Isr = 0; // read for PIUINTREG
USHORT IsrClear = 0; // clear for PIUINTREG
Csr = REG16(pVRC4173+PIUCNTREG);
Isr = REG16(pVRC4173+PIUINTREG);
*pTipStateFlags = TouchSampleIgnore;
// Lost data interrupt(Pen sampling mode).
if (Isr & PADDLOSTINTR) {
RETAILMSG( 1,(TEXT("TOUCH:Lost data interrupt\r\n")));
DEBUGMSG( ZONE_ERROR, (TEXT("Touch Data Lost (Pen scan mode) \r\n")) );
IsrClear |= PADDLOSTINTR | PADPAGE0INTR | PADPAGE1INTR; // discard all data in page buffer
} else if (Isr & PENCHGINTR) {
// pen changed interrupt.
//RETAILMSG(1, (TEXT("Touch PDD: PenChgIntr.\r\n")));
//RETAILMSG(1, (TEXT("PIUCNTREG = 0x%04x PIUINTREG = 0x%04x\r\n"), Csr,Isr));
IsrClear |= PENCHGINTR;
*pTipStateFlags = TouchSampleValidFlag;
nsample = 0;
} else if (Isr & (PADPAGE0INTR | PADPAGE1INTR)) {
// page buffer interrupt.
if ((Isr & PADPAGE0INTR) && (Isr & PADPAGE1INTR)) {
if ((Isr & OVP) == 0) {
IsrClear |= PADPAGE0INTR;
PageNumber = 0;
} else {
IsrClear |= PADPAGE1INTR;
PageNumber = 1;
}
} else {
if (Isr & PADPAGE0INTR) {
IsrClear |= PADPAGE0INTR;
PageNumber = 0;
} else if (Isr & PADPAGE1INTR) {
IsrClear |= PADPAGE1INTR;
PageNumber = 1;
}
}
*pTipStateFlags = TouchSampleValidFlag;
//
// Evaluate the samples, returning the tipstate and point
// To handle hardware problem, always return previous sample,
// not current.
//
if (Csr & PENSTC) {
PddpTouchPanelEvaluateSamples(pTipStateFlags, &PrevX, &PrevY, PageNumber);
}
}
*pUncalX = PrevX;
*pUncalY = PrevY;
REG16(pVRC4173+PIUINTREG) = IsrClear;
InterruptDone(gIntrTouch);
InterruptDone(gIntrTouchChanged);
// Recovery from Lost data interrupt.
if (Isr & PADDLOSTINTR) {
PIUEnable();
}
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)
{
if (bOff) {
PIUDisable();
// save sampling period
g_SamplingPeriod = REG16(pVRC4173+PIUSIVLREG);
// Clear Isr bits
REG16(pVRC4173+PIUINTREG) = ALL_TCHINTR | PADCMDINTR;
// Disable power
REG16(pVRC4173+PIUCNTREG) &= ~PIUPWR;
// Disable PIU Clock
REG16(pVRC4173+CMU73CLKMSK) &= ~MSKPIU;
} else {
// Enable PIU Clock
REG16(pVRC4173+CMU73CLKMSK) |= MSKPIU;
// Wait disable state
while (((REG16(pVRC4173+PIUCNTREG)>>10)&0x07) != PAD_STAT_DISABLE);
// Enable power
REG16(pVRC4173+PIUCNTREG) |= PIUPWR;
// Wait standby state
while (((REG16(pVRC4173+PIUCNTREG)>>10)&0x07) != PAD_STAT_STANDBY);
// Clear Isr bits
REG16(pVRC4173+PIUINTREG) = ALL_TCHINTR | PADCMDINTR;
// Set interval
REG16(pVRC4173+PIUSIVLREG) = g_SamplingPeriod;
// Stable set
REG16(pVRC4173+PIUSTBLREG) = STABLE_DEFAULT;
// Stable ON
REG16(pVRC4173+PIUCMDREG) |= STABLEON;
PIUEnable();
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -