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

📄 s3c6410_touch.cpp

📁 6410BSP3
💻 CPP
📖 第 1 页 / 共 2 页
字号:
//
// Copyright (c) Microsoft Corporation.  All rights reserved.
//
//
// Use of this source code is subject to the terms of the Microsoft end-user
// license agreement (EULA) under which you licensed this SOFTWARE PRODUCT.
// If you did not accept the terms of the EULA, you are not authorized to use
// this source code. For a copy of the EULA, please see the LICENSE.RTF on your
// install media.
//
/*++
THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF
ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO
THE IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A
PARTICULAR PURPOSE.
Copyright (c) 2005. Samsung Electronics, co. ltd  All rights reserved.

Module Name:

Abstract:

    Platform dependent TOUCH initialization functions

rev:
    2004.4.27    : S3C2440 port 
    2005.05.23    : Magneto porting revision
    2006.06.29    : S3C2443 port
    2007.02.21    : S3C6410 port

Notes:
--*/

#include <bsp.h>
#include <tchddsi.h>
#include "s3c6410_adc_touch_macro.h"

#ifndef DEBUG
DBGPARAM dpCurSettings = {
    TEXT("Touch"), { 
    TEXT("Samples"),TEXT("Calibrate"),TEXT("Stats"),TEXT("Thread"),
    TEXT("TipState"),TEXT("Init"),TEXT(""),TEXT(""),
    TEXT(""),TEXT("Misc"),TEXT("Delays"),TEXT("Timing"),
    TEXT("Alloc"),TEXT("Function"),TEXT("Warning"),TEXT("Error") },
    0x8000              // error
};
#endif


//------------------------------------------------------------------------------
// Global Variables
//------------------------------------------------------------------------------
DWORD gIntrTouch = SYSINTR_NOP;
DWORD gIntrTouchChanged = SYSINTR_NOP;

//------------------------------------------------------------------------------
// Local Variables
//------------------------------------------------------------------------------
static volatile S3C6410_GPIO_REG * g_pGPIOReg = NULL;
static volatile S3C6410_ADC_REG * g_pADCReg = NULL;
static volatile S3C6410_VIC_REG * g_pVIC0Reg = NULL;
static volatile S3C6410_VIC_REG * g_pVIC1Reg = NULL;
static volatile S3C6410_PWM_REG * g_pPWMReg = NULL;

static BOOL g_bTSP_Initialized = FALSE;
static BOOL g_bTSP_DownFlag = FALSE;
static int g_TSP_CurRate = 0;
static unsigned int g_SampleTick_High;
static unsigned int g_SampleTick_Low;
static CRITICAL_SECTION g_csTouchADC;    // Critical Section for ADC Done

//------------------------------------------------------------------------------
// External Variables
//------------------------------------------------------------------------------
extern "C" const int MIN_CAL_COUNT = 1;

static VOID TSP_VirtualFree(VOID);
static BOOL Touch_Pen_Filtering(int *px, int *py);
static VOID TSP_SampleStop(VOID);

static BOOL
TSP_VirtualAlloc(VOID)
{
    BOOL bRet = TRUE;
    PHYSICAL_ADDRESS    ioPhysicalBase = {0,0};

    DEBUGMSG(TSP_ZONE_FUNCTION,(_T("[TSP] ++TSP_VirtualAlloc()\r\n")));

    ioPhysicalBase.LowPart = S3C6410_BASE_REG_PA_GPIO;
    g_pGPIOReg = (S3C6410_GPIO_REG *)MmMapIoSpace(ioPhysicalBase, sizeof(S3C6410_GPIO_REG), FALSE);
    if (g_pGPIOReg == NULL)
    {
        RETAILMSG(TSP_ZONE_ERROR,(_T("[TSP:ERR] TSP_VirtualAlloc() : g_pGPIOReg Allocation Fail\r\n")));
        bRet = FALSE;
        goto CleanUp;
    }

    ioPhysicalBase.LowPart = S3C6410_BASE_REG_PA_ADC;
    g_pADCReg = (S3C6410_ADC_REG *)MmMapIoSpace(ioPhysicalBase, sizeof(S3C6410_ADC_REG), FALSE);
    if (g_pADCReg == NULL)
    {
        RETAILMSG(TSP_ZONE_ERROR,(_T("[TSP:ERR] TSP_VirtualAlloc() : g_pADCReg Allocation Fail\r\n")));
        bRet = FALSE;
        goto CleanUp;
    }
    
    ioPhysicalBase.LowPart = S3C6410_BASE_REG_PA_VIC0;
    g_pVIC0Reg = (S3C6410_VIC_REG *)MmMapIoSpace(ioPhysicalBase, sizeof(S3C6410_VIC_REG), FALSE);
    if (g_pVIC0Reg == NULL)
    {
        RETAILMSG(TSP_ZONE_ERROR,(_T("[TSP:ERR] TSP_VirtualAlloc() : g_pVIC0Reg Allocation Fail\r\n")));
        bRet = FALSE;
        goto CleanUp;
    }

    ioPhysicalBase.LowPart = S3C6410_BASE_REG_PA_VIC1;
    g_pVIC1Reg = (S3C6410_VIC_REG *)MmMapIoSpace(ioPhysicalBase, sizeof(S3C6410_VIC_REG), FALSE);
    if (g_pVIC1Reg == NULL)
    {
        RETAILMSG(TSP_ZONE_ERROR,(_T("[TSP:ERR] TSP_VirtualAlloc() : g_pVIC1Reg Allocation Fail\r\n")));
        bRet = FALSE;
        goto CleanUp;
    }

    ioPhysicalBase.LowPart = S3C6410_BASE_REG_PA_PWM;
    g_pPWMReg = (S3C6410_PWM_REG *)MmMapIoSpace(ioPhysicalBase, sizeof(S3C6410_PWM_REG), FALSE);
    if (g_pPWMReg == NULL)
    {
        RETAILMSG(TSP_ZONE_ERROR,(_T("[TSP:ERR] TSP_VirtualAlloc() : g_pPWMReg Allocation Fail\r\n")));
        bRet = FALSE;
        goto CleanUp;
    }

CleanUp:

    if (bRet == FALSE)
    {
        RETAILMSG(TSP_ZONE_ERROR,(_T("[TSP:ERR] TSP_VirtualAlloc() : Failed\r\n")));

        TSP_VirtualFree();
    }

    TSPMSG((_T("[TSP] --TSP_VirtualAlloc() = %d\r\n"), bRet));

    return bRet;
}

static VOID
TSP_VirtualFree(VOID)
{
    TSPMSG((_T("[TSP] ++TSP_VirtualFree()\r\n")));

    if (g_pGPIOReg)
    {
        MmUnmapIoSpace((PVOID)g_pGPIOReg, sizeof(S3C6410_SYSCON_REG));
        g_pGPIOReg = NULL;
    }

    if (g_pADCReg)
    {
        MmUnmapIoSpace((PVOID)g_pADCReg, sizeof(S3C6410_ADC_REG));
        g_pADCReg = NULL;
    }

    if (g_pVIC0Reg)
    {
        MmUnmapIoSpace((PVOID)g_pVIC0Reg, sizeof(S3C6410_VIC_REG));
        g_pVIC0Reg = NULL;
    }

    if (g_pVIC1Reg)
    {
        MmUnmapIoSpace((PVOID)g_pVIC1Reg, sizeof(S3C6410_VIC_REG));
        g_pVIC1Reg = NULL;
    }

    if (g_pPWMReg)
    {
        MmUnmapIoSpace((PVOID)g_pPWMReg, sizeof(S3C6410_PWM_REG));
        g_pPWMReg = NULL;
    }

    TSPMSG((_T("[TSP] --TSP_VirtualFree()\r\n")));
}


static VOID
TSP_PowerOn(VOID)
{
    TSPMSG((_T("[TSP] ++TSP_PowerOn()\r\n")));

    g_pADCReg->ADCDLY = ADC_DELAY(TSP_ADC_DELAY);

    g_pADCReg->ADCCON = RESSEL_12BIT | PRESCALER_EN | PRESCALER_VAL(TSP_ADC_PRESCALER) | STDBM_NORMAL;
    
    g_pADCReg->ADCTSC = ADCTSC_WAIT_PENDOWN;
    g_pADCReg->ADCCLRINT = CLEAR_ADC_INT;
    g_pADCReg->ADCCLRWK = CLEAR_ADCWK_INT;

    g_SampleTick_Low = TSP_TIMER_CNT_LOW;
    g_SampleTick_High = TSP_TIMER_CNT_HIGH;

    // Set Divider MUX for Timer3
    SET_TIMER3_DIVIDER_MUX(g_pPWMReg, TSP_TIMER_DIVIDER);    

    g_pPWMReg->TCNTB3  = g_SampleTick_Low;

    // timer3 interrupt disable
    g_pPWMReg->TINT_CSTAT = TINT_CSTAT_INTMASK(g_pPWMReg->TINT_CSTAT) & ~TIMER3_INTERRUPT_ENABLE;

    // timer3 interrupt status clear
    g_pPWMReg->TINT_CSTAT = TINT_CSTAT_INTMASK(g_pPWMReg->TINT_CSTAT) | TIMER3_PENDING_CLEAR;

    TSPMSG((_T("[TSP] --TSP_PowerOn()\r\n")));
}

static VOID
TSP_PowerOff(VOID)
{
    TSPMSG((_T("[TSP] ++TSP_PowerOff()\r\n")));

    TSP_SampleStop();

    // To prevent touch locked after wake up,
    // Wait for ADC Done
    // Do not turn off ADC before its A/D conversion finished
    EnterCriticalSection(&g_csTouchADC);
    // ADC Done in TSP_GETXy()..
    LeaveCriticalSection(&g_csTouchADC);

    g_pADCReg->ADCTSC = UD_SEN_DOWN | YM_SEN_EN | YP_SEN_DIS | XM_SEN_DIS | XP_SEN_DIS | PULL_UP_DIS | AUTO_PST_DIS | XY_PST_NOP;

    // ADC Standby Mode, conversion data will be preserved.
    g_pADCReg->ADCCON |= STDBM_STANDBY; 

    TSPMSG((_T("[TSP] --TSP_PowerOff()\r\n")));
}

static VOID
TSP_SampleStart(VOID)
{
    // timer3 interrupt status clear, Do not use OR/AND operation on TINTC_CSTAT directly
    g_pPWMReg->TINT_CSTAT = TINT_CSTAT_INTMASK(g_pPWMReg->TINT_CSTAT) | TIMER3_PENDING_CLEAR;

    // timer3 interrupt enable, Do not use OR/AND operation on TINTC_CSTAT directly
    g_pPWMReg->TINT_CSTAT = TINT_CSTAT_INTMASK(g_pPWMReg->TINT_CSTAT) | TIMER3_INTERRUPT_ENABLE;

    STOP_TIMER3(g_pPWMReg);

    UPDATE_TCNTB3(g_pPWMReg);
    NOUPDATE_TCNTB3(g_pPWMReg);

    SET_TIMER3_AUTORELOAD(g_pPWMReg);
    START_TIMER3(g_pPWMReg);
}

static VOID
TSP_SampleStop(VOID)
{
    STOP_TIMER3(g_pPWMReg);

    // timer3 interrupt disable, Do not use OR/AND operation on TINTC_CSTAT directly
    g_pPWMReg->TINT_CSTAT = TINT_CSTAT_INTMASK(g_pPWMReg->TINT_CSTAT) & ~TIMER3_INTERRUPT_ENABLE;

    // timer3 interrupt status clear, Do not use OR/AND operation on TINTC_CSTAT directly
    g_pPWMReg->TINT_CSTAT = TINT_CSTAT_INTMASK(g_pPWMReg->TINT_CSTAT) | TIMER3_PENDING_CLEAR;
}

static BOOL
TSP_CalibrationPointGet(TPDC_CALIBRATION_POINT *pTCP)
{
    int cDisplayWidth, cDisplayHeight;
    int CalibrationRadiusX, CalibrationRadiusY;

    TSPMSG((_T("[TSP] ++TSP_CalibrationPointGet()\r\n")));

    cDisplayWidth = pTCP->cDisplayWidth;
    cDisplayHeight = pTCP->cDisplayHeight;

    CalibrationRadiusX = cDisplayWidth  / 20;
    CalibrationRadiusY = cDisplayHeight / 20;

    switch (pTCP->PointNumber)
    {
    case    0:
        pTCP->CalibrationX = cDisplayWidth  / 2;
        pTCP->CalibrationY = cDisplayHeight / 2;
        break;

    case    1:
        pTCP->CalibrationX = CalibrationRadiusX * 2;
        pTCP->CalibrationY = CalibrationRadiusY * 2;
        break;

    case    2:
        pTCP->CalibrationX = CalibrationRadiusX * 2;
        pTCP->CalibrationY = cDisplayHeight - CalibrationRadiusY * 2;
        break;

    case    3:
        pTCP->CalibrationX = cDisplayWidth  - CalibrationRadiusX * 2;
        pTCP->CalibrationY = cDisplayHeight - CalibrationRadiusY * 2;
        break;

    case    4:
        pTCP->CalibrationX = cDisplayWidth - CalibrationRadiusX * 2;
        pTCP->CalibrationY = CalibrationRadiusY * 2;
        break;

    default:
        pTCP->CalibrationX = cDisplayWidth  / 2;
        pTCP->CalibrationY = cDisplayHeight / 2;
        SetLastError(ERROR_INVALID_PARAMETER);
        RETAILMSG(TSP_ZONE_ERROR,(_T("[TSP:ERR] TSP_CalibrationPointGet() : ERROR_INVALID_PARAMETER\r\n")));
        return FALSE;
    }

    TSPMSG((_T("[TSP] --TSP_CalibrationPointGet()\r\n")));

    return TRUE;
}

static BOOL
TSP_GetXY(int *px, int *py)
{
    int i,j,k;
    int temp;
    int x[TSP_SAMPLE_NUM], y[TSP_SAMPLE_NUM];
    int dx, dy;
    int TimeOut = 100;  // about 100ms

    EnterCriticalSection(&g_csTouchADC);

    for (i = 0; i < TSP_SAMPLE_NUM; i++)
    {
        g_pADCReg->ADCTSC = ADCTSC_AUTO_ADC;    // Auto Conversion
        g_pADCReg->ADCCON |= ENABLE_START_EN;    // ADC Conversion Start

        while (g_pADCReg->ADCCON & ENABLE_START_EN)
        {    // Wait for Start Bit Cleared
            if(TimeOut-- < 0)
            {
                RETAILMSG(ZONE_ERROR,(TEXT("ADC cannot start\n")));
                goto ADCfails;
            }        
            Sleep(1);
        }

        TimeOut = 100;  // about 100ms
        while (!(g_pADCReg->ADCCON & ECFLG_END))
        {    // Wait for ADC Conversion Ended
            if(TimeOut-- < 0)
            {
                RETAILMSG(ZONE_ERROR,(TEXT("ADC Conversion cannot be done\n")));
                goto ADCfails;
            }        
            Sleep(1);
        }

        x[i] = D_XPDATA_MASK(g_pADCReg->ADCDAT0);
        y[i] = D_YPDATA_MASK(g_pADCReg->ADCDAT1);
    }

ADCfails:
    LeaveCriticalSection(&g_csTouchADC);

    for (j = 0; j < TSP_SAMPLE_NUM -1; ++j)
    {
        for (k = j+1; k < TSP_SAMPLE_NUM; ++k)
        {
            if(x[j]>x[k])
            {
                temp = x[j];
                x[j]=x[k];
                x[k]=temp;
            }

            if(y[j]>y[k])
            {
                temp = y[j];
                y[j]=y[k];
                y[k]=temp;
            }
        }
    }

#ifdef    DETAIL_SAMPLING
    // 8 samples Interpolation (weighted 4 samples)
    *px = (x[2] + ((x[3]+x[4])<<1) + (x[3]+x[4]) + x[5]);
    *py = (y[2] + ((y[3]+y[4])<<1) + (y[3]+y[4]) + y[5]);

    if ((*px & 0x7) > 3) *px = (*px>>3) + 1;
    else *px = *px>>3;

    if ((*py & 0x7) > 3) *py = (*py>>3) + 1;
    else *py = *py>>3;

    dx = x[5] - x[2];
    dy = y[5] - y[2];
#else
    // 2 samples average
    *px = (x[1] + x[2] + 1)>>1;
    *py = (y[1] + y[2] + 1)>>1;

    dx = x[2] - x[1];
    dy = y[2] - y[1];
#endif


    if ((dx > TSP_INVALIDLIMIT) || (dy > TSP_INVALIDLIMIT))
    {
        return FALSE;
    }
    else
    {
        return TRUE;
    }
}


//---------------------------------------------------------------------------

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -