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

📄 s3c6410_touch.cpp

📁 SAMSUNG S3C6410 CPU BSP for winmobile6
💻 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 (Hoyjoon Kim)
	2005.05.23	: Magneto porting revision (junkim)
	2006.06.29	: S3C2443 port(JJG)
	2007.02.21	: S3C6410 port (dodan2)

Notes:
--*/

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

#ifdef	REMOVE_BEFORE_RELEASE
#define TSPMSG(x)
#define TSPINF(x)
#define TSPERR(x)	RETAILMSG(TRUE, x)
#else
//#define TSPMSG(x)	RETAILMSG(TRUE, x)
#define TSPMSG(x)
#define TSPINF(x)	RETAILMSG(TRUE, x)
//#define TSPINF(...)
#define TSPERR(x)	RETAILMSG(TRUE, x)
//#define TSPERR(...)
#endif

#define DETAIL_SAMPLING
#define NEW_FILTER_SCHEME

#define TSP_ADC_DELAY			(10000)	// 40000
#define TSP_ADC_PRESCALER		(24)		// 49 // 200

#define TSP_SAMPLE_RATE_LOW	(50)		// 50 Samples per Sec
#define TSP_SAMPLE_RATE_HIGH	(100)	// 100 Samples per Sec

#define TSP_TIMER_DIVIDER		(1)
#define TSP_TIMER_CNT_LOW		(S3C6410_PCLK/SYS_TIMER_PRESCALER/TSP_TIMER_DIVIDER/TSP_SAMPLE_RATE_LOW-1)
#define TSP_TIMER_CNT_HIGH		(S3C6410_PCLK/SYS_TIMER_PRESCALER/TSP_TIMER_DIVIDER/TSP_SAMPLE_RATE_HIGH-1)

#define TSP_INVALIDLIMIT		(40)

#ifdef NEW_FILTER_SCHEME
#define TSP_FILTER_LIMIT		(3)
#else
#define TSP_FILTER_LIMIT		(25)
#endif

#ifdef DETAIL_SAMPLING
#define TSP_SAMPLE_NUM			(8)
#else
#define TSP_SAMPLE_NUM			(4)
#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;

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

	g_pGPIOReg = (S3C6410_GPIO_REG *)DrvLib_MapIoSpace(S3C6410_BASE_REG_PA_GPIO, sizeof(S3C6410_GPIO_REG), FALSE);
	if (g_pGPIOReg == NULL)
	{
		TSPERR((_T("[TSP:ERR] TSP_VirtualAlloc() : g_pGPIOReg Allocation Fail\r\n")));
		bRet = FALSE;
		goto CleanUp;
	}

	g_pADCReg = (S3C6410_ADC_REG *)DrvLib_MapIoSpace(S3C6410_BASE_REG_PA_ADC, sizeof(S3C6410_ADC_REG), FALSE);
	if (g_pADCReg == NULL)
	{
		TSPERR((_T("[TSP:ERR] TSP_VirtualAlloc() : g_pADCReg Allocation Fail\r\n")));
		bRet = FALSE;
		goto CleanUp;
	}

	g_pVIC0Reg = (S3C6410_VIC_REG *)DrvLib_MapIoSpace(S3C6410_BASE_REG_PA_VIC0, sizeof(S3C6410_VIC_REG), FALSE);
	if (g_pVIC0Reg == NULL)
	{
		TSPERR((_T("[TSP:ERR] TSP_VirtualAlloc() : g_pVIC0Reg Allocation Fail\r\n")));
		bRet = FALSE;
		goto CleanUp;
	}

	g_pVIC1Reg = (S3C6410_VIC_REG *)DrvLib_MapIoSpace(S3C6410_BASE_REG_PA_VIC1, sizeof(S3C6410_VIC_REG), FALSE);
	if (g_pVIC1Reg == NULL)
	{
		TSPERR((_T("[TSP:ERR] TSP_VirtualAlloc() : g_pVIC1Reg Allocation Fail\r\n")));
		bRet = FALSE;
		goto CleanUp;
	}

	g_pPWMReg = (S3C6410_PWM_REG *)DrvLib_MapIoSpace(S3C6410_BASE_REG_PA_PWM, sizeof(S3C6410_PWM_REG), FALSE);
	if (g_pPWMReg == NULL)
	{
		TSPERR((_T("[TSP:ERR] TSP_VirtualAlloc() : g_pPWMReg Allocation Fail\r\n")));
		bRet = FALSE;
		goto CleanUp;
	}

CleanUp:

	if (bRet == FALSE)
	{
		TSPERR((_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)
	{
		DrvLib_UnmapIoSpace((PVOID)g_pGPIOReg);
		g_pGPIOReg = NULL;
	}

	if (g_pADCReg)
	{
		DrvLib_UnmapIoSpace((PVOID)g_pADCReg);
		g_pADCReg = NULL;
	}

	if (g_pVIC0Reg)
	{
		DrvLib_UnmapIoSpace((PVOID)g_pVIC0Reg);
		g_pVIC0Reg = NULL;
	}

	if (g_pVIC1Reg)
	{
		DrvLib_UnmapIoSpace((PVOID)g_pVIC1Reg);
		g_pVIC1Reg = NULL;
	}

	if (g_pPWMReg)
	{
		DrvLib_UnmapIoSpace((PVOID)g_pPWMReg);
		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);
	#if		(CPU_NAME == S3C6410)
	g_pADCReg->ADCCON = RESSEL_12BIT | PRESCALER_EN | PRESCALER_VAL(TSP_ADC_PRESCALER);
	#elif	(CPU_NAME == S3C6400)
	g_pADCReg->ADCCON = PRESCALER_EN | PRESCALER_VAL(TSP_ADC_PRESCALER);
	#endif			// add by shin.0322
	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
	switch(TSP_TIMER_DIVIDER)
	{
	case 1:
		g_pPWMReg->TCFG1 = (g_pPWMReg->TCFG1 & ~(0xf<<12)) | (0<<12);
		break;
	case 2:
		g_pPWMReg->TCFG1 = (g_pPWMReg->TCFG1 & ~(0xf<<12)) | (1<<12);
		break;
	case 4:
		g_pPWMReg->TCFG1 = (g_pPWMReg->TCFG1 & ~(0xf<<12)) | (2<<12);
		break;
	case 8:
		g_pPWMReg->TCFG1 = (g_pPWMReg->TCFG1 & ~(0xf<<12)) | (3<<12);
		break;
	case 16:
		g_pPWMReg->TCFG1 = (g_pPWMReg->TCFG1 & ~(0xf<<12)) | (4<<12);
		break;
	default:
		g_pPWMReg->TCFG1 = (g_pPWMReg->TCFG1 & ~(0xf<<12)) | (0<<12);
		break;
	}

	g_pPWMReg->TCNTB3  = g_SampleTick_Low;

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

	// timer3 interrupt status clear
	//g_pPWMReg->TINT_CSTAT |= (1<<8);		// Do not use OR/AND operation on TINTC_CSTAT
	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..
	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;

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

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

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

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

	g_pPWMReg->TCON &= ~(0xf<<16);	// Timer3 Stop

	g_pPWMReg->TCON |= (1<<17);	// update TCNTB3
	g_pPWMReg->TCON &= ~(1<<17);

	g_pPWMReg->TCON |= ((1<<19)|(1<<16));	// AutoReload mode, Timer3 Start

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

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

	g_pPWMReg->TCON &= ~(0xf<<16);		// Timer3 stop

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

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

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

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

	TSPMSG((_T("[TSP] ++TSP_CalibrationPointGet()\r\n")));
	
#if(LCD_TYPE==LCD_TYPE_LANDSCAPE)	
	cDisplayWidth = pTCP->cDisplayHeight;
	cDisplayHeight = pTCP->cDisplayWidth;	
#elif (LCD_TYPE==LCD_TYPE_PORTRAIT)		
	cDisplayWidth = pTCP->cDisplayWidth;
	cDisplayHeight = pTCP->cDisplayHeight;
#else
#error 	LCD_TYPE_UNDEFINED_ERROR	
#endif	

	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);
		TSPERR((_T("[TSP:ERR] TSP_CalibrationPointGet() : ERROR_INVALID_PARAMETER\r\n")));
		return FALSE;
	}

#if(LCD_TYPE==LCD_TYPE_LANDSCAPE)	
	int orig_x = pTCP->CalibrationX;
	int orig_y = pTCP->CalibrationY;
	pTCP->CalibrationX = orig_y;
	pTCP->CalibrationY = cDisplayWidth - orig_x - 1;
#endif	


	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;

	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
			Sleep(1);
		}

		while (!(g_pADCReg->ADCCON & ECFLG_END))
		{	// Wait for ADC Conversion Ended
			Sleep(1);
		}

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

	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;

⌨️ 快捷键说明

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