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

📄 lpc32xx_touch.cpp

📁 NXP LPC3000系列 wince BSP包
💻 CPP
📖 第 1 页 / 共 2 页
字号:
    if (!lpc32xx_ts_init())
    {
        goto cleanup;
    }

	// Get pen sysintr value
    if (!KernelIoControl(IOCTL_HAL_REQUEST_SYSINTR, &irqt, sizeof(irqt),
		&gIntrTouch, sizeof(gIntrTouch), NULL))
    {
        RETAILMSG(ZONE_ERROR, 
            (TEXT("ERROR: TOUCH: Failed to request the touch sysintr.\r\n")));

        gIntrTouch = SYSINTR_UNDEFINED;
        goto cleanup;
    }

	s_TouchPad.predownflag = FALSE;

	rc = TRUE;
    
cleanup:
    DEBUGMSG(ZONE_FUNCTION, (TEXT("DdsiTouchPanelEnable- (rc = %d)\r\n"), rc));
    return rc;
}

//------------------------------------------------------------------------------
//
//  DdsiTouchPanelDisable
//
//  Disable the touchscreen
//
VOID DdsiTouchPanelDisable()
{
    DEBUGMSG(ZONE_FUNCTION, (TEXT("DdsiTouchPanelDisable+\r\n")));

    // Close pen event and kill thread.
    lpc32xx_ts_deinit();

    // Release interrupts
    if (gIntrTouch != SYSINTR_UNDEFINED)
    {
        KernelIoControl(IOCTL_HAL_RELEASE_SYSINTR, &gIntrTouch, 
            sizeof(gIntrTouch), NULL, 0, NULL);
    }

    DEBUGMSG(ZONE_FUNCTION, (TEXT("DdsiTouchPanelDisable-\r\n")));
}

//------------------------------------------------------------------------------
//
//  DdsiTouchPanelAttach
//
//
LONG DdsiTouchPanelAttach()
{
    DEBUGMSG(ZONE_FUNCTION, (TEXT("DdsiTouchPanelAttach+\r\n")));

    // Increment the number of process attach calls.
    s_TouchPad.nProcessAttached++;

    DEBUGMSG(ZONE_FUNCTION, (TEXT("DdsiTouchPanelAttach-\r\n")));
        
    // Return the number.
    return s_TouchPad.nProcessAttached;
}

//------------------------------------------------------------------------------
//
//  DdsiTouchPanelDetach
//
//
LONG DdsiTouchPanelDetach()
{
    DEBUGMSG(ZONE_FUNCTION, (TEXT("DdsiTouchPanelDetach+\r\n")));
    
    // Decrement the number of process attach calls.
    s_TouchPad.nProcessAttached--;

    DEBUGMSG(ZONE_FUNCTION, (TEXT("DdsiTouchPanelDetach\r\n")));
    
    // Return the number.
    return s_TouchPad.nProcessAttached;
}

//------------------------------------------------------------------------------
//
//  DdsiTouchPanelGetPoint
//
//  The driver handles the touchscreen interrupt via the touch MDD. When the
//  touchscreen interrupt occurs, the touch MDD will call this function to
//  determine the touch state. 
//
void DdsiTouchPanelGetPoint(TOUCH_PANEL_SAMPLE_FLAGS *pTipStateFlags,
    INT *pUncalX, INT *pUncalY)
{
	TOUCHP_T TPoint;
    // MDD needs us to hold on to last valid sample and previous pen state.
    static INT usFilteredX       = 0;
    static INT usFilteredY       = 0;
    static DWORD dwTimeNextEvent = -1;
        
    DEBUGMSG(ZONE_FUNCTION, (TEXT("DdsiTouchPanelGetPoint+\r\n")));

    // Check if pen data are available If so, get the data.
    if (lpc32xx_get_point(&TPoint))
    {
		if (TPoint.pendown == FALSE)
		{
		    // If the previous pen down state was set and this is a pen up state,
			// then tell the MDD the pen was released and set the MDD thread time
			// back to INFINITE
			if (s_TouchPad.predownflag == TRUE)
			{
		        *pUncalX = usFilteredX;
			    *pUncalY = usFilteredY;
				s_TouchPad.predownflag = FALSE;
				*pTipStateFlags = TouchSampleValidFlag;
			}

			gdwTouchIstTimeout = INFINITE;
		}
		else
		{
			// Pen is currently down
			if (s_TouchPad.predownflag == FALSE)
			{
				// Pen has just been put down
				s_TouchPad.predownflag = TRUE;
			}

			// Save last samples
			*pUncalX = usFilteredX = TPoint.xpoint;
			*pUncalY = usFilteredY = TPoint.ypoint;
			*pTipStateFlags = (TouchSampleValidFlag | TouchSampleDownFlag);

			// Pen down timeout is 23mS, this is slightly longer than the longest
			// time between touchscreen interrupts
	        gdwTouchIstTimeout = 23;
 		}
	}
	else 
	{
		// By default, any sample returned will be ignored.
	    *pTipStateFlags = TouchSampleIgnore;
	}

    DEBUGMSG(ZONE_FUNCTION, (TEXT("DdsiTouchPanelGetPoint-\r\n")));
}

//------------------------------------------------------------------------------
//  DdsiTouchPanelPowerHandler
//
//  Power down between samples (nothing to do here)
//
void DdsiTouchPanelPowerHandler(BOOL bOff)
{
    DEBUGMSG(ZONE_FUNCTION, (TEXT("DdsiTouchPanelPowerHandler\r\n")));
}

//------------------------------------------------------------------------------
//
//  lpc32xx_update_samplerate
//
//  Sets the sample rate of the touchscreen by adjusting the same update time
//  Sample rate is based on s_TouchPad.nSampleRate.
//
BOOL lpc32xx_update_samplerate(void)
{
	BOOL rc = FALSE;

	// Compute update delay (the time between samples when pendown is detected)
	// These are based off the 32KHz TC clock and are ok for hardcoded values
	if (s_TouchPad.nSampleRate == 0)
	{
		s_TouchPad.pTSCREGs->tsc_utr = TSC_UTR_UPDATE_TIME(100); // About 52Hz
	}
	else
	{
		s_TouchPad.pTSCREGs->tsc_utr = TSC_UTR_UPDATE_TIME(25); // About 101Hz
	}

	return rc;
}

//------------------------------------------------------------------------------
//
//  lpc32xx_ts_init
//
//  Initializes the touchscreen controller for auto operation
//
BOOL lpc32xx_ts_init(void)
{
	UINT32 tscval;
    PHYSICAL_ADDRESS pa;
	CLKENID_T clkinfo;
    DWORD bytesret;

	// Map register space
    pa.QuadPart = ADC_BASE;
	s_TouchPad.pTSCREGs = (LPC3250_ADCTSC_REGS_T *)
		MmMapIoSpace(pa, sizeof (LPC3250_ADCTSC_REGS_T), FALSE);
	if (s_TouchPad.pTSCREGs == NULL)
	{
		// Not mapped
		RETAILMSG(ZONE_ERROR, (TEXT("lpc32xx_ts_init: Register map failure\r\n")));
		return FALSE;
	}

	/* Enable clock to ADC block - 32KHz clock */
	clkinfo.clkid = CLKPWR_ADC_CLK;
    clkinfo.enable = TRUE;
    if (KernelIoControl(IOCTL_LPC32XX_ENSYSCLK, &clkinfo, sizeof (clkinfo),
		NULL, 0, &bytesret) == FALSE)
	{
		RETAILMSG(ZONE_ERROR, (TEXT("lpc32xx_ts_init: Error enabling touch clock\r\n")));
	}

	/* Ensure ADC is not powered */
    s_TouchPad.pTSCREGs->adc_con &= ~TSC_ADCCON_POWER_UP;

	/* Set the TSC FIFO depth to 4 samples of 10-bit size */
	s_TouchPad.pTSCREGs->adc_con = (TSC_ADCCON_IRQ_TO_FIFO_4 |
		TSC_ADCCON_X_SAMPLE_SIZE(10) | TSC_ADCCON_Y_SAMPLE_SIZE(10));

    /* set TSC SEL to default state */
    s_TouchPad.pTSCREGs->adc_sel = 0x284;

    // min/max x/y registers
	s_TouchPad.pTSCREGs->tsc_min_x = 0;  
	s_TouchPad.pTSCREGs->tsc_max_x = 0x3ff;  
	s_TouchPad.pTSCREGs->tsc_max_y = 0;  
	s_TouchPad.pTSCREGs->tsc_min_y = 0x3ff;  

    // Aux registers
	s_TouchPad.pTSCREGs->tsc_aux_utr = 0;
	s_TouchPad.pTSCREGs->tsc_aux_min = 0;   
	s_TouchPad.pTSCREGs->tsc_aux_max = 0;   

 	// Rise Time
	s_TouchPad.pTSCREGs->tsc_dtr = TSC_RTR_RISE_TIME(0x2);

	// Update Time
	s_TouchPad.pTSCREGs->tsc_utr = TSC_UTR_UPDATE_TIME(446);

	// Delay Time
	s_TouchPad.pTSCREGs->tsc_dtr = TSC_DTR_DELAY_TIME(0x2);

	// Touch time
	s_TouchPad.pTSCREGs->tsc_ttr = TSC_TTR_TOUCH_TIME(0x10);

	// Drain X Plate time
	s_TouchPad.pTSCREGs->tsc_dxp = TSC_DXP_DRAINX_TIME(0x4);

	// Update the sample rate 
	lpc32xx_update_samplerate();

	// Empty the touchscreen FIFO
	while ((s_TouchPad.pTSCREGs->tsc_stat & TSC_STAT_FIFO_EMPTY) == 0)
	{
		tscval = s_TouchPad.pTSCREGs->tsc_fifo;
	}

	// TSC Auto mode enable, this also sets AUTO bit
	s_TouchPad.pTSCREGs->adc_con |= TSC_ADCCON_AUTO_EN;		     

	return TRUE;
}

//------------------------------------------------------------------------------
//
//  lpc32xx_ts_deinit
//
//  Disables touchscreen
//
void lpc32xx_ts_deinit(void)
{
	CLKENID_T clkinfo;
    DWORD bytesret;

	if (s_TouchPad.pTSCREGs != NULL)
	{
		s_TouchPad.pTSCREGs->adc_con &= ~TSC_ADCCON_AUTO_EN;
		MmUnmapIoSpace(s_TouchPad.pTSCREGs, sizeof(LPC3250_ADCTSC_REGS_T));
	}

	// Disable touchscreen clock
	clkinfo.clkid = CLKPWR_ADC_CLK;
    clkinfo.enable = FALSE;
	KernelIoControl(IOCTL_LPC32XX_ENSYSCLK, &clkinfo, sizeof (clkinfo),
		NULL, 0, &bytesret);
}

//------------------------------------------------------------------------------
//
//  lpc32xx_fifo_empty
//
//  Empty touchscreen FIFO
//
static void lpc32xx_fifo_empty(void)
{
	UINT32 tsval;

	// Empty FIFO
	while ((s_TouchPad.pTSCREGs->tsc_stat & TSC_STAT_FIFO_EMPTY) == 0)
	{
		tsval = s_TouchPad.pTSCREGs->tsc_fifo;
	}
}

//------------------------------------------------------------------------------
//
//  lpc32xx_get_point
//
//  Returns the touchscreen state
//
BOOL lpc32xx_get_point(TOUCHP_T* pPoint)
{
	UINT32 tsamples, tsval, rval [16], xval [16], yval [16];
	BOOL pvalid = FALSE;

	if (s_TouchPad.pTSCREGs != NULL)
	{
		// Has touchscreen FIFO overflowed?
		if ((s_TouchPad.pTSCREGs->tsc_stat & TSC_STAT_FIFO_OVRRN) != 0)
		{
			// FIFO overrun, toss sample
			lpc32xx_fifo_empty();
		}
		else if ((s_TouchPad.pTSCREGs->tsc_stat & TSC_STAT_FIFO_EMPTY) == 0)
		{
			// Get sample data
			tsamples = 0;
			while ((tsamples < 16) &&
				((s_TouchPad.pTSCREGs->tsc_stat & TSC_STAT_FIFO_EMPTY) == 0))
			{
				tsval = s_TouchPad.pTSCREGs->tsc_fifo;
				xval [tsamples] = TSC_FIFO_NORMALIZE_X_VAL(tsval);
				yval [tsamples] = TSC_FIFO_NORMALIZE_Y_VAL(tsval);
				rval [tsamples] = tsval;
				tsamples++;
			}

			// Data is only valid if pen is still down
			pPoint->pendown = FALSE;
			if ((rval [3] & TSC_FIFO_TS_P_LEVEL) == 0)
				{
				// Average samples 1 and 2 only, toss sample 0 and 3
				if (tsamples >= 4)
				{
					pPoint->xpoint = 0x3FF - (INT) ((xval [1] + xval [2]) / 2);
					pPoint->ypoint = 0x3FF - (INT) ((yval [1] + yval [2]) / 2);
					pPoint->pendown = TRUE;
				}
			}
			else
			{
				lpc32xx_fifo_empty();
			}

			pvalid = TRUE;
		}
		else
		{
			// Pen is released
			pPoint->pendown = FALSE;
			pvalid = TRUE;
			lpc32xx_fifo_empty();
		}
	}

	InterruptDone(gIntrTouch);

	return pvalid;
}

⌨️ 快捷键说明

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