📄 lhtouch.cpp
字号:
/*--------------------------------------------------------------------------*/
// touch.cpp
//
// Touch Driver for Sharp LH79524 using on-board ADC controller.
//
// Author: Kenneth G. Maxwell
//
// Notes:
//
// This driver runs in Polled mode. The high-level application software
// must do these things to use this touch driver:
//
// 1) Instantiate TouchDevice instance.
// 2) Call TouchDevice::Calibrate to calibrate the touch screen.
// 3) Periodically call TouchDevice::Poll to poll for touch input changes.
//
//
// Example:
//
// #include "touch.hpp"
//
// void main(int argc, char **argv)
// {
// TouchDevice *pTouch = new TouchDevice();
// pTouch->Calibrate();
//
// while(1)
// {
// pTouch->Poll();
// }
// }
//
//
//
/*--------------------------------------------------------------------------*/
#include "peg.hpp"
#include "touch.hpp"
#include "lh795_8.hpp" // for register addresses
/*--------------------------------------------------------------------------*/
/*--------------------------------------------------------------------------*/
TouchDevice::TouchDevice()
{
PEGINT iLoop;
PEGULONG lVal;
PEGULONG *pReg;
ADC_REGS *pADC = (ADC_REGS *) ADC_REG_BASE;
// program GPIO pins as analog input pins:
pReg = (PEGULONG *) (IOCON_REG_BASE + 0xc0); // mux ctrl 25
*pReg = 0;
// unlock clock control:
pReg = (PEGULONG *) RCPC_REG_BASE;
lVal = *pReg;
lVal |= 0x200; // set bit 9 to unlock
*pReg = lVal;
pReg = (PEGULONG *) (RCPC_REG_BASE + 0x48); // adc clock divisor
*pReg = 0x10; // div by 32. With 192 MHz HCLK, this is
// a 6 MHz ADC clock
pReg = (PEGULONG *) (RCPC_REG_BASE + 0x28); // peripheral clock 1
lVal = *pReg;
lVal &= ~0x04; // enable ADC clock
*pReg = lVal;
// program all writable ADC registers to zero:
pADC->IntClear = 0x03;
pADC->IntClear = 0;
pADC->IntMask = 0;
pADC->PowerConfig = 0;
pADC->GeneralConfig = 0;
for (iLoop = 0; iLoop < 16; iLoop++)
{
pADC->HiWordBank[iLoop] = 0;
pADC->LoWordBank[iLoop] = 0;
}
pADC->IdleHiWord = 0;
pADC->IdleLoWord = 0;
// Read FIFO until empty:
while((pADC->FifoStatus & 0x04) == 0)
{
lVal = pADC->Results;
}
pReg = (PEGULONG *) INT_ENABLE_CLEAR; // IntEnableClear
*pReg = 0x10000; // set bit 16
// setup ADC Regs
pADC->IntMask = 0; // Polled Mode
pADC->PowerConfig = (ADC_CLOCK_SEL << 8) | 0x6b;
pADC->GeneralConfig = 0x02; // SSB starts conversions
pADC->HiWordBank[0] = ADC_SETTLE_TIME;
pADC->HiWordBank[1] = ADC_SETTLE_TIME;
pADC->HiWordBank[2] = ADC_SETTLE_TIME | 0x11;
pADC->HiWordBank[3] = ADC_SETTLE_TIME | 0x11;
pADC->HiWordBank[4] = ADC_SETTLE_TIME | 0x11;
pADC->HiWordBank[5] = ADC_SETTLE_TIME | 0x11;
pADC->HiWordBank[6] = ADC_SETTLE_TIME | 0x02;
pADC->HiWordBank[7] = ADC_SETTLE_TIME | 0x02;
pADC->HiWordBank[8] = ADC_SETTLE_TIME | 0x02;
pADC->HiWordBank[9] = ADC_SETTLE_TIME | 0x02;
pADC->HiWordBank[10] = ADC_SETTLE_TIME;
pADC->HiWordBank[11] = ADC_SETTLE_TIME;
pADC->LoWordBank[0] = 0x0004;
pADC->LoWordBank[1] = 0x1080;
pADC->LoWordBank[2] = 0x0015;
pADC->LoWordBank[3] = 0x0015;
pADC->LoWordBank[4] = 0x0015;
pADC->LoWordBank[5] = 0x0015;
pADC->LoWordBank[6] = 0x00a2;
pADC->LoWordBank[7] = 0x00a2;
pADC->LoWordBank[8] = 0x00a2;
pADC->LoWordBank[9] = 0x00a2;
pADC->LoWordBank[10] = 0x0004;
pADC->LoWordBank[11] = 0x1080;
mDummy = 0;
mLastTouched = 0;
mLastPos.x = mLastPos.y = 0;
TouchCal.CenterX = TouchCal.CenterY = 0;
TouchCal.IsCalibrated = FALSE;
TouchCal.SwapAxis = FALSE;
}
/*--------------------------------------------------------------------------*/
/*--------------------------------------------------------------------------*/
// Scan
//
// Called during calibration or normal operation to do one polled read.
//
// Return:
//
// Boolean touched or not
// If touched, passes back raw x and rawy values.
/*--------------------------------------------------------------------------*/
PEGBOOL TouchDevice::Scan(PEGINT *pRawX, PEGINT *pRawY)
{
ADC_REGS *pADC = (ADC_REGS *) ADC_REG_BASE;
PEGULONG lVal;
PEGINT loop;
PEGBOOL Touched = FALSE;
PEGINT xVal;
PEGINT yVal;
pADC->IntClear = 0x01; // write EOSINTC bit
Sleep(100);
pADC->GeneralConfig = 0x06; // trigger conversion
// poll end-of-sequence interrupt status:
while((pADC->IntStatus & 0x04) == 0)
{
mDummy++;
}
lVal = pADC->Results; // pre-bias
lVal = pADC->Results >> 6; // touch detect
if (lVal > TOUCH_DETECT_VAL)
{
for (loop = 0; loop < 10; loop++)
{
lVal = pADC->Results;
}
Touched = FALSE;
}
else
{
xVal = pADC->Results >> 6;
xVal += pADC->Results >> 6;
xVal += pADC->Results >> 6;
xVal += pADC->Results >> 6;
xVal /= 4;
yVal = pADC->Results >> 6;
yVal += pADC->Results >> 6;
yVal += pADC->Results >> 6;
yVal += pADC->Results >> 6;
yVal /= 4;
lVal = pADC->Results; // pre-bias
lVal = pADC->Results >> 6; // touch detect
if (lVal > TOUCH_DETECT_VAL)
{
Touched = FALSE;
}
else
{
if (TouchCal.SwapAxis)
{
*pRawX = yVal;
*pRawY = xVal;
}
else
{
*pRawX = xVal;
*pRawY = yVal;
}
Touched = TRUE;
}
}
return Touched;
}
/*--------------------------------------------------------------------------*/
/*--------------------------------------------------------------------------*/
PEGBOOL TouchDevice::Poll(void)
{
PegMessage TouchMessage;
PEGBOOL ReturnVal = FALSE;
PEGINT RawX;
PEGINT RawY;
PegPoint CurPos;
PEGBOOL Touched = Scan(&RawX, &RawY);
if (Touched) // am I touched now?
{
CurPos = ScaleRawVals(RawX, RawY);
if (mLastTouched) // was I touched last time?
{
if (CurPos.x != mLastPos.x ||
CurPos.y != mLastPos.y)
{
// position changed, report new position:
TouchMessage.pTarget = TouchMessage.pSource = NULL;
TouchMessage.wType = PM_POINTER_MOVE;
TouchMessage.Point = CurPos;
PegThing::MessageQueue()->Push(TouchMessage);
ReturnVal = TRUE;
}
}
else
{
// here for new touch
TouchMessage.pTarget = TouchMessage.pSource = NULL;
TouchMessage.wType = PM_LBUTTONDOWN;
TouchMessage.Point = CurPos;
PegThing::MessageQueue()->Push(TouchMessage);
ReturnVal = TRUE;
}
mLastPos = CurPos;
}
else
{
if (mLastTouched)
{
// here for LBUTTONUP:
TouchMessage.pTarget = TouchMessage.pSource = NULL;
TouchMessage.wType = PM_LBUTTONUP;
TouchMessage.Point = mLastPos;
PegThing::MessageQueue()->Push(TouchMessage);
ReturnVal = TRUE;
}
}
mLastTouched = Touched;
return ReturnVal;
}
/*--------------------------------------------------------------------------*/
void TouchDevice::Sleep(PEGINT Time)
{
PEGINT iLoop;
while(Time >= 0)
{
for (iLoop = 0; iLoop < 100; iLoop++)
{
mDummy++;
}
Time--;
}
}
/*--------------------------------------------------------------------------*/
/*--------------------------------------------------------------------------*/
PegPoint TouchDevice::ScaleRawVals(PEGINT RawX, PEGINT RawY)
{
PegPoint Pos;
Pos.x = (RawX - TouchCal.xRawMin) *
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -