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

📄 tchpdd.cpp

📁 wince底层驱动开发代码 ARM作为一种嵌入式系统处理器
💻 CPP
📖 第 1 页 / 共 3 页
字号:
    //
    if(v_pADCregs == NULL) 
        return ;

    TouchPanelPowerOff();  // Power down the device

    PddpTouchPanelDeallocateVm();  // free up any resources
}

//
// @doc EX_TOUCH_DDSI EXTERNAL DRIVERS DDSI TOUCH_PANEL
//
// @func LONG | DdsiTouchPanelAttach |
// This routine no longer does anything.  All functionallity has been moved
// from here into DdsiTouchPanelEnable to allow this code to be statically
// linked with GWE rather than existing as a DLL.  Technically, when built
// as a DLL we should keep an attach count and only allow touh.dll to be
// loaded once.  But, since we are loaded at boot time by GWE, there is
// no real concern about multiple loads (unless gwe has a bug!).
//
// @rdesc
// Always returns 0
//
// @comm
// Implemented in the PDD.
//

LONG
DdsiTouchPanelAttach(
    VOID
    )
{
    return( 1 );
}


//
// @doc EX_TOUCH_DDSI EXTERNAL DRIVERS DDSI TOUCH_PANEL
//
// @func LONG | DdsiTouchPanelDetach |
// See the descrition for attach.  All functionallity has been moved into
// DdsiTouchPanelDisable.
//
// @rdesc
// The updated global counter.  If the initializations failed, the returned
// count is 0.
//
// @comm
// Implemented in the PDD.
//


LONG
DdsiTouchPanelDetach(
    VOID
    )
{
    return ( 0 );
}

#define COODI_Y

//
// @doc EX_TOUCH_DDSI EXTERNAL DRIVERS DDSI TOUCH_PANEL
//
// @func void | DdsiTouchPanelGetPoint |
// Returns the most recently acquired point and its associated tip state
// information.
//
// @parm PDDSI_TOUCHPANEL_TIPSTATE | pTipState |
// Pointer to where the tip state information will be returned.
// @parm PLONG | pUnCalX |
// Pointer to where the x coordinate will be returned.
// @parm PLONG | pUnCalY |
// Pointer to where the y coordinate will be returned.
//
// @comm
// Implmented in the PDD.
//
#if ( LCD_TYPE == TFT640_480 )
	#define TOUCH_MAX_X 890
	#define TOUCH_MIN_X 125
	#define TOUCH_MAX_Y 860
	#define TOUCH_MIN_Y 140

	#define TOUCH_X	640
	#define TOUCH_Y	480
#else 
	#define TOUCH_MAX_X 900 // 950
	#define TOUCH_MIN_X 100 // 90
	#define TOUCH_MAX_Y 920 // 960 // 910
	#define TOUCH_MIN_Y 100 // 70 //50

	#define TOUCH_X	240
	#define TOUCH_Y	320
#endif

#define TOUCH_ERR	50

static int second = 0;

VOID Touch_CoordinateConversion(INT *px, INT *py)
{
	INT TmpX, TmpY;
	INT TmpX0, TmpY0;
	
	TmpX0 = *px; TmpY0 = *py;
	
	TmpX = (*px >= TOUCH_MAX_X) ? (TOUCH_MAX_X-1) : *px;
	TmpY = (*py >= TOUCH_MAX_Y) ? (TOUCH_MAX_Y-1) : *py;
	
	TmpX -= TOUCH_MIN_X;
    TmpY -= TOUCH_MIN_Y;
    
    TmpX = (TmpX) ? TmpX : 0;
    TmpY = (TmpY) ? TmpY : 0;
    
	*px = ((TmpX * TOUCH_X) / (TOUCH_MAX_X-TOUCH_MIN_X))*4;
	*py = ((TmpY * TOUCH_Y) / (TOUCH_MAX_Y-TOUCH_MIN_Y))*4;
	
	return;
}


VOID
DdsiTouchPanelGetPoint(
	TOUCH_PANEL_SAMPLE_FLAGS	*pTipStateFlags,
	INT				*pUncalX,
	INT				*pUncalY
    )
{
	ULONG status;
	// USHORT ioAdcCntr;
	// USHORT intrMask;
	static int SampleCount = 0;
	static TOUCH_PANEL_SAMPLE_FLAGS PrevStateFlags = TouchSampleIgnore;
	static INT PrevX = 0;
	static INT PrevY = 0;
	TOUCH_PANEL_SAMPLE_FLAGS TmpStateFlags;
	INT TmpX = 0;
	INT TmpY = 0;
	int i;
    
    //RETAILMSG(1, (TEXT(":::::::::::: DdsiTouchPanelGetPoint routine !!!\r\n")));

    // Read the status passed back by the HAL
    status = READ_REGISTER_ULONG( &(v_pDriverGlobals->tch.status) );

    if(status == TOUCH_PEN_UP) {
		v_pADCregs->rADCTSC = 0xD3;	// Set stylus down interrupt
		*pTipStateFlags = TouchSampleValidFlag;
		*pUncalX = PrevX;
		*pUncalY = PrevY;
		InterruptDone( gIntrTouchChanged );
		RETAILMSG(0, (TEXT("8 - (%d, %d) 0x%X\r\n"), *pUncalX, *pUncalY, *pTipStateFlags));
    }
    else if(status == TOUCH_PEN_DOWN){
		*pTipStateFlags = TouchSampleIgnore;
		*pUncalX = PrevX;
		*pUncalY = PrevY;
		Touch_Timer0_Setup();
		InterruptDone( gIntrTouchChanged );

		RETAILMSG(0, (TEXT("9 - (%d, %d) 0x%X\r\n"), *pUncalX, *pUncalY, *pTipStateFlags));
	}
	else {		
		if( (v_pADCregs->rADCDAT0 & 0x8000) || (v_pADCregs->rADCDAT1 & 0x8000) ){
			v_pADCregs->rADCTSC = 0xD3;	// Set stylus down interrupt
			*pTipStateFlags = TouchSampleValidFlag;
			*pUncalX = PrevX;
			*pUncalY = PrevY;
			InterruptDone( gIntrTouchChanged );
			RETAILMSG(0, (TEXT("91 - (%d, %d) 0x%X\r\n"), *pUncalX, *pUncalY, *pTipStateFlags));
		}
		else{		// charlie
			// <Auto X-Position and Y-Position Read>

			for (i =0; i < 3; i++) {
				// v_pADCregs->rADCTSC=(0<<8)|(1<<7)|(1<<6)|(0<<5)|(1<<4)|(1<<3)|(1<<2)|(0);
				v_pADCregs->rADCTSC=(1<<3)|(1<<2);
				// Stylus Down,Don't care,Don't care,Don't care,Don't care,XP pullup Dis,Auto,No operation
				v_pADCregs->rADCCON|=0x1;	// Start Auto conversion

				while(v_pADCregs->rADCCON & 0x1);		//check if Enable_start is low
				while(!(0x8000&v_pADCregs->rADCCON));	// Check ECFLG
		
				ybuf[i] = 0x3ff - (0x3ff & v_pADCregs->rADCDAT0);
				xbuf[i] = 0x3ff & v_pADCregs->rADCDAT1;
			}	

	 		PddpTouchPanelEvaluateSamples( &TmpStateFlags, &TmpX, &TmpY);
	
	
			v_pADCregs->rADCTSC=(1<<8)|(1<<7)|(1<<6)|(0<<5)|(1<<4)|(0<<3)|(0<<2)|(3);
	
			Touch_CoordinateConversion(&TmpX, &TmpY);    
			
			
			if (Touch_Pen_filtering(&TmpX, &TmpY)) // Valid touch pen
		    {
		    	//RETAILMSG(1, (TEXT("valid touch pen\r\n")));
				*pTipStateFlags = TouchSampleValidFlag | TouchSampleDownFlag;			
				*pTipStateFlags &= ~TouchSampleIgnore;
			}
			else	// Invalid touch pen 
			{
		    	//RETAILMSG(1, (TEXT("invalid touch pen\r\n")));
				*pTipStateFlags = TouchSampleValidFlag;
				*pTipStateFlags |= TouchSampleIgnore;				
			}		
			*pUncalX = PrevX = TmpX;
			*pUncalY = PrevY = TmpY;
	
	   		InterruptDone( gIntrTouch );
	   		
   			RETAILMSG(0, (TEXT("0 - (%d, %d) 0x%X\r\n"), *pUncalX, *pUncalY, *pTipStateFlags));

		}
	}

    return;

}

#define FILTER_LIMIT 25

static BOOL
Touch_Pen_filtering(INT *px, INT *py)
{
	BOOL RetVal = TRUE;
	// TRUE  : Valid pen sample
	// FALSE : Invalid pen sample
	static int count = 0;
	static INT x[2], y[2];
	INT TmpX, TmpY;
	INT dx, dy;
	

	count++;

	if (count > 2) 
	{ // apply filtering rule

		count = 2;
		
		// average between x,y[0] and *px,y
		TmpX = (x[0] + *px) / 2;
		TmpY = (y[0] + *py) / 2;
		
		// difference between x,y[1] and TmpX,Y
		dx = (x[1] > TmpX) ? (x[1] - TmpX) : (TmpX - x[1]);
		dy = (y[1] > TmpY) ? (y[1] - TmpY) : (TmpY - y[1]);
		
		if ((dx > FILTER_LIMIT) || (dy > FILTER_LIMIT)) {
			// Invalid pen sample
			*px = x[1];
			*py = y[1]; // previous valid sample

			RetVal = FALSE;
			count = 0;
		} 
		else		
		{			
			// Valid pen sample
			x[0] = x[1]; y[0] = y[1];		
			x[1] = *px; y[1] = *py; // reserve pen samples
			
			RetVal = TRUE;
			//RETAILMSG(1, (TEXT("RetVal = TRUE\r\n")));
		}
		
	} else { // till 2 samples, no filtering rule
	
		x[0] = x[1]; y[0] = y[1];		
		x[1] = *px; y[1] = *py; // reserve pen samples
		
		RetVal = FALSE;	// <- TRUE jylee 2003.03.04 
	}
	
	//if (RetVal==FALSE) {
	//}
	
	return RetVal;
}



/*++

 @func VOID | DdsiTouchPanelPowerHandler |
 System power state notification.

 @parm BOOL | bOff | TRUE, the system is powering off; FALSE, the system is powering up.

 @comm
 This routine is called in a kernel context and may not make any system
 calls whatsoever.  It may read and write its own memory and that's about
 it.  This routine is called by the MDD and also serves as an internal
 helper routine for touch enable/disable.

 @devnote This routine will run in kernel context, and may not make
 any system calls.  If you can any subroutines inside here, make sure
 that they also follow this restriction.

--*/
void
DdsiTouchPanelPowerHandler(
	BOOL	bOff
	)
{
    // USHORT mask;

    // Set flag so we know to avoid system calls
    bInPowerHandler = TRUE;

    if (bOff) {
        TouchPanelPowerOff();
    }
    else {
        TouchPanelPowerOn();
        PddpSetupPenDownIntr(TRUE);
    }

    bInPowerHandler = FALSE;
}

static void
TouchPanelPowerOff()
{
    // Powering down, stop DMA and power off touch screen
    RETAILMSG(0,(TEXT("Touch Power Off\r\n")));
}


static void
TouchPanelPowerOn()
{
    DWORD tmp = 0;

	v_pIOPregs->rGPGCON &= ~((0x3 << 16));   
	v_pIOPregs->rGPGCON |=  ((0x2 << 16));		/* External Interrupt #16 Enable				*/


	v_pIOPregs->rEXTINT2 &= ~(0x7 << 8);		// Configure EINT18 as Both Edge Mode
	v_pIOPregs->rEXTINT2 |=  (0x7 << 8);

	v_pIOPregs->rEINTPEND  = (1 << 16);
	v_pIOPregs->rEINTMASK &= ~(1 << 16);

	RETAILMSG(1,(TEXT("SDMMC config set rGPGCON: %x\r\n"), v_pIOPregs->rGPGCON));   


    RETAILMSG(1,(TEXT("Touch Init\r\n")));

    //
    // Setup GPIOs for touch
    // 
    
    // Clear GPG15, 14, 13, 12
    v_pIOPregs->rGPGCON &= ~((0x03 << 30)|(0x03 << 28)|(0x03 << 26)|(0x03 << 24));
    // Set GPG15 to use as nYPON, GPG14 to use as YMON, GPG13 to use as nXPON, GPG12 to use as XMON
    v_pIOPregs->rGPGCON |= ((0x01 << 30)|(0x01 << 28)|(0x01 << 26)|(0x01 << 24));
    // Disable full up function
    v_pIOPregs->rGPGUP |= ((0x01 << 15)|(0x01 << 14)|(0x01 << 13)|(0x01 << 12));
    
    //
    // Setup ADC register
    //

    // Down Int, YMON:0, nYPON:1, XMON:0;nXPON:1, Pullup:1, Auto Conv.,Waiting.
    v_pADCregs->rADCTSC = (0<<8)|(1<<7)|(1<<6)|(0<<5)|(1<<4)|(0<<3)|(0<<2)|(3);
    //v_pADCregs->rADCTSC=(1<<3)|(1<<2);
	v_pADCregs->rADCDLY = ADC_DELAY_TIME;//default value for delay.    
    v_pADCregs->rADCCON	= (1<<14)|(ADCPRS<<6)|(7<<3);	//setup channel, ADCPRS, Touch Input

/*
	RETAILMSG(1, (TEXT("v_pIOPregs->rGPBCON = 0x%X\r\n"), v_pIOPregs->rGPBCON));
	RETAILMSG(1, (TEXT("v_pIOPregs->rGPBDAT = 0x%X\r\n"), v_pIOPregs->rGPBDAT));
	RETAILMSG(1, (TEXT("v_pIOPregs->rGPBUP = 0x%X\r\n"), v_pIOPregs->rGPBUP));

	RETAILMSG(1, (TEXT("S2440PCLK = %d\r\n"), S2440PCLK));
	RETAILMSG(1, (TEXT("v_pPWMregs->rTCFG0 = 0x%X\r\n"), v_pPWMregs->rTCFG0));
	RETAILMSG(1, (TEXT("v_pPWMregs->rTCFG1 = 0x%X\r\n"), v_pPWMregs->rTCFG1));
	RETAILMSG(1, (TEXT("v_pPWMregs->rTCON = 0x%X\r\n"), v_pPWMregs->rTCON));
	RETAILMSG(1, (TEXT("v_pPWMregs->rTCNTB0 = 0x%X\r\n"), v_pPWMregs->rTCNTB0));
	RETAILMSG(1, (TEXT("v_pPWMregs->rTCMPB0 = 0x%X\r\n"), v_pPWMregs->rTCMPB0));
	RETAILMSG(1, (TEXT("v_pPWMregs->rTCNTO0 = 0x%X\r\n"), v_pPWMregs->rTCNTO0));
	RETAILMSG(1, (TEXT("v_pPWMregs->rTCNTB1 = 0x%X\r\n"), v_pPWMregs->rTCNTB1));
	RETAILMSG(1, (TEXT("v_pPWMregs->rTCMPB1 = 0x%X\r\n"), v_pPWMregs->rTCMPB1));
	RETAILMSG(1, (TEXT("v_pPWMregs->rTCNTO1 = 0x%X\r\n"), v_pPWMregs->rTCNTO1));
	RETAILMSG(1, (TEXT("v_pPWMregs->rTCNTB2 = 0x%X\r\n"), v_pPWMregs->rTCNTB2));
	RETAILMSG(1, (TEXT("v_pPWMregs->rTCMPB2 = 0x%X\r\n"), v_pPWMregs->rTCMPB2));
	RETAILMSG(1, (TEXT("v_pPWMregs->rTCNTO2 = 0x%X\r\n"), v_pPWMregs->rTCNTO2));
	RETAILMSG(1, (TEXT("v_pPWMregs->rTCNTB3 = 0x%X\r\n"), v_pPWMregs->rTCNTB3));
	RETAILMSG(1, (TEXT("v_pPWMregs->rTCMPB3 = 0x%X\r\n"), v_pPWMregs->rTCMPB3));
	RETAILMSG(1, (TEXT("v_pPWMregs->rTCNTO3 = 0x%X\r\n"), v_pPWMregs->rTCNTO3));
	RETAILMSG(1, (TEXT("v_pPWMregs->rTCNTB4 = 0x%X\r\n"), v_pPWMregs->rTCNTB4));
	RETAILMSG(1, (TEXT("v_pPWMregs->rTCNTO4 = 0x%X\r\n"), v_pPWMregs->rTCNTO4));
*/
	return ;
}


static BOOL Touch_Timer0_Setup(void) {
	unsigned int TmpTCON;

    //
    // We use Timer1 of PWM as OS Clock.

    // Disable Timer1 Init..
    v_pINTregs->rINTMSK |= BIT_TIMER1;     // Mask timer1 interrupt.
    v_pINTregs->rSRCPND = BIT_TIMER1;     // Clear pending bit
    v_pINTregs->rINTPND = BIT_TIMER1;

    //we operate our board with PCLK=203M/4 = 50750000Hz (50.75 Mhz)    
	v_pPWMregs->rTCFG0 &= ~(0xff);		/* Prescaler 1's Value			*/
    v_pPWMregs->rTCFG0 |= (PRESCALER); // prescaler value = 24 + 1
  	v_pPWMregs->rTCFG1 &= ~(0xf<<4);
#if( SYS_TIMER_DIVIDER == 2 )
  	v_pPWMregs->rTCFG1  |=  (0   << 4);		/* 1/2							*/
#elif ( SYS_TIMER_DIVIDER == 4 )
  	v_pPWMregs->rTCFG1  |=  (1   << 4);		/* 1/4							*/
#elif ( SYS_TIMER_DIVIDER == 8 )
  	v_pPWMregs->rTCFG1  |=  (2   << 4);		/* 1/8							*/
#elif ( SYS_TIMER_DIVIDER == 16 )
  	v_pPWMregs->rTCFG1  |=  (3   << 4);		/* 1/16							*/
#endif
//    v_pPWMregs->rTCNTB1 = 1000; // about 10 ms(203M/4/2/(255+1))=10ms  	
    v_pPWMregs->rTCNTB1 = (10 * (S2440PCLK / (PRESCALER+1) / SYS_TIMER_DIVIDER)) / 1000;		// 10msec, Charlie
							
    v_pPWMregs->rTCMPB1 = 0;   	

	TmpTCON = v_pPWMregs->rTCON;	// get TCON value to temp TCON register
	TmpTCON &= ~0xf00;     			// clear fields of Timer 1 
	TmpTCON |= 0x200;     			// interval mode(auto reload), update TCVNTB4, stop 
	v_pPWMregs->rTCON = TmpTCON;	// put the value to TCON register

	TmpTCON = v_pPWMregs->rTCON;	// get TCON value to temp TCON register
	TmpTCON &= ~0xf00;     			// clear fields of Timer 1 
	TmpTCON |= 0x100;     			// interval mode, no operation, start for Timer 4 
	v_pPWMregs->rTCON = TmpTCON;	// put the value to TCON register

    v_pINTregs->rINTMSK &= ~BIT_TIMER1;    
 
 	return TRUE;   
}    
	

⌨️ 快捷键说明

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