⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 mx1touch.cpp

📁 完整的触摸屏驱动源程序
💻 CPP
📖 第 1 页 / 共 3 页
字号:
/*--------------------------------------------------------------------------*/
/*--------------------------------------------------------------------------*/
// 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 + -