📄 mx1touch.cpp
字号:
/*--------------------------------------------------------------------------*/
/*--------------------------------------------------------------------------*/
// MX1TOUCH- Touch Screen driver written to utilize the FreeScale MX1
// built-in touch controller.
//
// Author: Kenneth G. Maxwell
// Swell Software, Inc.
// 2920 Pine Grove Ave.
// Port Huron, MI 48060
// PH: 810 982-5955
// URL: www.swellsoftware.com
//
// Notes:
//
// This source code is provided "as is" with no warrenty, expressed or implied,
// regarding fitness for use for any particular use or application.
//
// You may use, modify, change, create derivitive works, copy, and distribute
// this source code as you see fit.
//
// This driver has been tested with the MX1 ADS eval board exclusively.
//
// This driver has been tested with the following operating systems:
//
// RTXC Quadros
// Micro Digital SMX
// Express Logic ThreadX
// eSOL PrKernel
//
// If you are running with another operating system, please contact Swell
// Software regarding availabilty of a version for your RTOS.
//
/*--------------------------------------------------------------------------*/
/*--------------------------------------------------------------------------*/
#include "peg.hpp" // data types, UI drawing classes
#include "mx1touch.hpp"
#include "imxregs.hpp" // for reg address definitions
// TouchCalData holds the data values obtained during calibration and used
// to scale touch raw coords to screen coords
TOUCH_CAL_DATA TouchCal;
// A structure defining the layout of the ASP controller registers
ASP_REG_BLOCK *pTouchRegs;
// We copy the ASP FIFO here when the FIFO is full:
PEGUSHORT TouchResponseVals[ASP_FIFO_DEPTH];
/*--------------------------------------------------------------------------*/
// Prototype functions implemented for each RTOS
//
// The group of functions below are are implemented at the end of this file,
// one implementation for each supported RTOS.
/*--------------------------------------------------------------------------*/
extern "C" {
void TouchInterruptHandler(void);
void InstallTouchInterruptHandler(void);
void WaitTouchDataReady(void);
}
/*--------------------------------------------------------------------------*/
// TouchConfigureHardware- Configure ASP registers.
/*--------------------------------------------------------------------------*/
void TouchConfigureHardware(void)
{
// base address of ASP register block:
pTouchRegs = (ASP_REG_BLOCK *) 0x00215000L;
pTouchRegs->Control = 0x00800000; // soft reset
TOUCH_DELAY(TOUCH_POLLING_PERIOD);
pTouchRegs->Control = ASP_INIT_VAL;
// we want about a 50Hz sample rate. The input clock to the ASP is
// set to 8MHz.
pTouchRegs->SampleRate = (ASP_DMCNT << 12) |
(ASP_BIT_SEL << 10) |
(ASP_IDLE_CNT << 4) |
(ASP_DATA_SETUP);
pTouchRegs->Compare = 0;
pTouchRegs->IntCtrl = 0x12; // enable pen down and FIFO full
pTouchRegs->ClockDiv = 0x00000001; // divide 16MHz PERCLK2 by 2
// Install our interrupt handler:
InstallTouchInterruptHandler();
}
/*--------------------------------------------------------------------------*/
// DetectTouch- Read the PEN IRQ interrupt pending bit to see if the screen
// is touched or not.
/*--------------------------------------------------------------------------*/
PEGBOOL DetectTouch(void)
{
PEGULONG uVal = pTouchRegs->Status;
pTouchRegs->Status = uVal | 0x40;
uVal = pTouchRegs->Status;
if (uVal & 0x40) // PEN interrupt pending?
{
pTouchRegs->Status = uVal | 0x40; // clear by writing 1
return TRUE;
}
return FALSE;
}
/*--------------------------------------------------------------------------*/
// WaitForTouchState-
//
// This function is used only during calibration.
/*--------------------------------------------------------------------------*/
void WaitForTouchState(PEGBOOL WantTouch)
{
// Poll until the IRQ is in the state requested. We have to
// get two consecutive readings in the requested state before
// we return:
PEGINT iCount = 0;
PEGBOOL IsTouched;
while(iCount < 2)
{
IsTouched = DetectTouch();
if (WantTouch) // waiting for touch?
{
if (IsTouched)
{
iCount++;
}
else
{
iCount = 0;
}
}
else // waiting for not touched?
{
if (IsTouched)
{
iCount = 0;
}
else
{
iCount++;
}
}
TOUCH_DELAY(TOUCH_POLLING_PERIOD);
}
}
/*--------------------------------------------------------------------------*/
// TouchSample
//
// Reads raw X and Y conversion values and returns the result.
//
// We run the ASP until the input FIFO is full. Check to see if all
// reading are within the error margin, if so we average and accept them.
// Otherwise, we return FALSE to indicate that the screen is fluctuating.
/*--------------------------------------------------------------------------*/
PEGBOOL TouchSample(PEGUSHORT *pPutData)
{
PEGUINT xVal = 0;
PEGUINT yVal = 0;
volatile PEGINT uStat;
// make sure the data input FIFO is cleared:
uStat = pTouchRegs->Status;
while(uStat & 1)
{
TouchResponseVals[0] = pTouchRegs->DataIn;
uStat = pTouchRegs->Status;
}
pTouchRegs->Control = ASP_ENABLE;
WaitTouchDataReady();
PEGINT Loop;
PEGINT iIndex = 2;
if (abs(TouchResponseVals[8] - TouchResponseVals[2]) > TOUCH_NOISE_LIMIT)
{
return FALSE;
}
if (abs(TouchResponseVals[9] - TouchResponseVals[3]) > TOUCH_NOISE_LIMIT)
{
return FALSE;
}
for (Loop = 0; Loop < 4; Loop++)
{
xVal += TouchResponseVals[iIndex];
iIndex++;
yVal += TouchResponseVals[iIndex];
iIndex++;
}
xVal /= 4;
yVal /= 4;
// The touch screen x-y values are mechanically swapped (assuming the
// screen orientation is 240W x 320H).
*pPutData = (PEGUSHORT) xVal;
*(pPutData + 1) = (PEGUSHORT) yVal;
return TRUE;
}
/*--------------------------------------------------------------------------*/
// GetScaledTouchPos
//
// Reads touch screen raw values and interpolates to find best accuracy pixel
// coordinates. Returns pixel coordinates.
/*--------------------------------------------------------------------------*/
PEGBOOL GetScaledTouchPos(PEGINT *pPutX, PEGINT *pPutY)
{
PEGUSHORT RawVals[2];
while(1)
{
if (DetectTouch())
{
if (TouchSample(RawVals))
{
// screen is touched and we read a stable value,
// proceed to scaling to pixel coords:
if (DetectTouch())
{
// screen is still touched, return position
break;
}
else
{
return FALSE;
}
}
else
{
// couldn't get a stable value, delay and try again:
TOUCH_DELAY(TOUCH_POLLING_PERIOD);
}
}
else
{
return FALSE; // screen is not touched
}
}
if (RawVals[1] < TouchCal.CenterY)
{
// we are in the top half of the screen, use the
// upper X coords:
*pPutX = (RawVals[0] - TouchCal.RawXVals[TC_UL]) *
TouchCal.ScreenWidth /
(TouchCal.RawXVals[TC_UR] - TouchCal.RawXVals[TC_UL]);
}
else
{
// Bottom half of the screen, use bottom coords:
*pPutX = (RawVals[0] - TouchCal.RawXVals[TC_LL]) *
TouchCal.ScreenWidth /
(TouchCal.RawXVals[TC_LR] - TouchCal.RawXVals[TC_LL]);
}
if (RawVals[0] < TouchCal.CenterX)
{
// we are in the left half of the screen, use the
// upper left y coords:
*pPutY = (RawVals[1] - TouchCal.RawYVals[TC_UL]) *
TouchCal.ScreenHeight /
(TouchCal.RawYVals[TC_LL] - TouchCal.RawYVals[TC_UL]);
}
else
{
// Right half of the screen, use right Y coords:
*pPutY = (RawVals[1] - TouchCal.RawYVals[TC_UR]) *
TouchCal.ScreenHeight /
(TouchCal.RawYVals[TC_LR] - TouchCal.RawYVals[TC_UR]);
}
return TRUE;
}
/*--------------------------------------------------------------------------*/
// TouchMeBitmap:
//
// A bitmap created using PegImageConvert program. This is a small
// target that indicates to the user where to touch the screen during
// calibration.
/*--------------------------------------------------------------------------*/
ROMDATA PEGUBYTE ucTouchMeBitmap[424] = {
0x1f,0x09,0x1f,0x09,0x82,0x09,0x09,0x0f,0x19,0x00,0x82,0x0f,0x09,0x09,0x83,0x09,
0x09,0x00,0x0f,0x17,0x00,0x83,0x0f,0x00,0x09,0x09,0x84,0x09,0x09,0x00,0x00,0x0f,
0x15,0x00,0x84,0x0f,0x00,0x00,0x09,0x09,0x81,0x09,0x09,0x02,0x00,0x80,0x0f,0x13,
0x00,0x80,0x0f,0x02,0x00,0x81,0x09,0x09,0x81,0x09,0x09,0x03,0x00,0x80,0x0f,0x11,
0x00,0x80,0x0f,0x03,0x00,0x81,0x09,0x09,0x81,0x09,0x09,0x04,0x00,0x80,0x0f,0x0f,
0x00,0x80,0x0f,0x04,0x00,0x81,0x09,0x09,0x81,0x09,0x09,0x05,0x00,0x80,0x0f,0x0d,
0x00,0x80,0x0f,0x05,0x00,0x81,0x09,0x09,0x81,0x09,0x09,0x06,0x00,0x80,0x0f,0x0b,
0x00,0x80,0x0f,0x06,0x00,0x81,0x09,0x09,0x81,0x09,0x09,0x07,0x00,0x80,0x0f,0x09,
0x00,0x80,0x0f,0x07,0x00,0x81,0x09,0x09,0x81,0x09,0x09,0x08,0x00,0x80,0x0f,0x07,
0x00,0x80,0x0f,0x08,0x00,0x81,0x09,0x09,0x81,0x09,0x09,0x09,0x00,0x80,0x0f,0x05,
0x00,0x80,0x0f,0x09,0x00,0x81,0x09,0x09,0x81,0x09,0x09,0x0a,0x00,0x80,0x0f,0x03,
0x00,0x80,0x0f,0x0a,0x00,0x81,0x09,0x09,0x81,0x09,0x09,0x0b,0x00,0x83,0x0f,0x00,
0x00,0x0f,0x0b,0x00,0x81,0x09,0x09,0x81,0x09,0x09,0x0c,0x00,0x81,0x0f,0x0f,0x0c,
0x00,0x81,0x09,0x09,0x81,0x09,0x09,0x0c,0x00,0x81,0x0f,0x0f,0x0c,0x00,0x81,0x09,
0x09,0x81,0x09,0x09,0x0b,0x00,0x83,0x0f,0x00,0x00,0x0f,0x0b,0x00,0x81,0x09,0x09,
0x81,0x09,0x09,0x0a,0x00,0x80,0x0f,0x03,0x00,0x80,0x0f,0x0a,0x00,0x81,0x09,0x09,
0x81,0x09,0x09,0x09,0x00,0x80,0x0f,0x05,0x00,0x80,0x0f,0x09,0x00,0x81,0x09,0x09,
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -