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

📄 digi.c

📁 触摸屏的开发
💻 C
📖 第 1 页 / 共 3 页
字号:
 * Description: support touch pannel interrupt,since MX1 and MX21 adopted different ADC chip,in MX1,AD7843 will *				generate interrupt according to level trigger configuration, so can generate one interrupt to  *				detect pen down, then reconfigure it to generate pen up interrupt.But in MX21, the AD7873 will *				have the pen irq line reassert after each pen sample is taken. It will deassert when you take a *				sample. When the pen is down, we disable the interrupt and take a sample every 20ms. Before we  *				take the sample, we check if the pen irq line is deasserted. If it is deasserted, then this means  *				the pen is up. */static void digi_isr(int irq, void *dev_id, struct pt_regs *regs){	if(((_reg_GPIO_ISR(GPIOC) & _reg_GPIO_IMR(GPIOC))&0x00004000)!=0)	{		touch_pan_clear_inter(); 		//tasklet_schedule(&digi_tasklet);		touch_pan_disable_inter();		pen_timer.expires = jiffies + HZ/50 + 2*HZ/100;		add_timer(&pen_timer);		pen_timer_status = 1;	        //INFO("Pen Interrupt\n");	}	  	return;}/***	Function Name: digi_tasklet_action*	Input		 : data*	Output		 : none*	Description  : The tasklet function used in MX1.*	**/static void digi_tasklet_action(unsigned long data){	//#ifdef CONFIG_ARCH_MX1ADS	u32	newX;	u32  newY;	u32  maxDelay;	newX = TPNL_PEN_UPVALUE;	maxDelay = 0;//	save_flags(touchflags);//	cli();		//check the interrupt polarity to see it is pen up or down.	if(touch_pan_check_int_pol())//it is pen down	{		if((_reg_GPIO_SSR(GPIOC) & 0x00004000) == 0)//judge if is pen down		{			return;					}		//then just change the interrupt polarity to be pen up		touch_pan_set_neg_inter();		//check if the pen sampling timer is in use		if(pen_timer_status!=0)//in use		{			//then just change the interrupt polarity to be pen up			return;		}		else //no sampling timer		{			//9/8 Karen			touch_pan_disable_inter();			//end 9/8			//read data with MAX delay from ADC			touch_pan_read_data(&newX, &newY);			while((newX == TPNL_PEN_UPVALUE)&&(maxDelay <= 50))			{				touch_pan_read_data(&newX, &newY);				maxDelay++;			}			if(newX == TPNL_PEN_UPVALUE)			{				//clear the interrupt bit//				FAILED("TouchPanIsr: error always PEN_UP \n");				return;		   	}			TRACE("TouchPanIsr:get pendata x= %d, y=%d \n",newX,newY);			add_x_y(newX, newY, PENDOWN);			wake_up_interruptible(&digi_wait);				if(ts_fasync)   			kill_fasync(&ts_fasync, SIGIO, POLL_IN);			//then just change the interrupt polarity to be pen up			//then just change the interrupt polarity to be pen up			touch_pan_set_neg_inter();			spin_lock_irq(&pen_lock);			pen_timer.expires = jiffies + HZ/50 + 2*HZ/100;			add_timer(&pen_timer);			pen_timer_status = 1;			spin_unlock_irq (&pen_lock);			return;		}	}	else//pen up interrupt	{		if((_reg_GPIO_SSR(GPIOC) & 0x00004000) != 0) //value is high		{			return;					}		//check if the pen sampling timer is in use		if(pen_timer_status!=0)//in use		{			//disable pen down interrupt			//get Pen up			TRACE("TouchPanIsr:get pen up 0,0,penup \n");			add_x_y(0, 0, PENUP);		// if there is a pen up, shall tell apps to handle the event, and it shall		// be data there			if (!NODATA())			{				wake_up_interruptible(&digi_wait);				if(ts_fasync)				kill_fasync(&ts_fasync, SIGIO, POLL_IN);			}			//release timer			spin_lock_irq(&pen_lock);			pen_timer_status = 0;			del_timer(&pen_timer);			spin_unlock_irq(&pen_lock);						touch_pan_set_pos_inter();//set polarity to detach pen down		}		else //no timer		{//			FAILED("TouchPanIsr :pen up, no timer \n");		}		return;			}//#endif	}/****************************************************************************** * Function Name: digi_sam_callback * * Input: 		: * * Value Returned: * * Description: spi sampling timer call back * *****************************************************************************/static void digi_sam_callback(unsigned long data){	u32 newX,newY;	u32  maxDelay;	maxDelay = 0;	newX = TPNL_PEN_UPVALUE;//	save_flags(samflags);//	cli();	if(pen_timer_status !=0)		mod_timer(&pen_timer, jiffies + HZ/50 + 2*HZ/100);#ifdef CONFIG_ARCH_MX2ADS	if((_reg_GPIO_SSR(GPIOC) & 0x00004000) == 0)//judge if is pen down#endif#ifdef CONFIG_ARCH_MX1ADS	if((REG_PD_SSR & 0x80000000) == 0)//judge if is pen down#endif		{		if(pen_timer_status!=0)//in use		{			//get Pen up			add_x_y(0, 0, PENUP);			// if there is a pen up, shall tell apps to handle the event, and it shall be data there			if (!NODATA())			{				wake_up_interruptible(&digi_wait);				if(ts_fasync)				kill_fasync(&ts_fasync, SIGIO, POLL_IN);			}						//release timer			spin_lock_irq(&pen_lock);			pen_timer_status = 0;			del_timer(&pen_timer);			spin_unlock_irq(&pen_lock);#ifdef CONFIG_ARCH_MX2ADS			touch_pan_set_pos_inter();#endif#ifdef CONFIG_ARCH_MX1ADS			touch_pan_set_pos_inter();//set polarity to detach pen down#endif			touch_pan_clear_inter();			//9/8 Karen			touch_pan_enable_inter();			//end 9/8				}		return;	}#ifdef CONFIG_ARCH_MX2ADS	if((_reg_GPIO_SSR(GPIOC) & 0x00004000) != 0)//positive,it is pen down	//if(!touch_pan_check_int_pol())//positive,it is pen down#endif#ifdef CONFIG_ARCH_MX1ADS	if(!touch_pan_check_int_pol())//positive,it is pen down#endif	{		//read data with MAX delay from ADC		while((newX == TPNL_PEN_UPVALUE)&&(maxDelay <= 100))		{			touch_pan_read_data(&newX, &newY);			maxDelay++;		}		if(newX == TPNL_PEN_UPVALUE)		{//			FAILED("SpiSamCallback: error always PEN_UP \n");			return;		}		//add element into buffer		add_x_y(newX, newY, PENDOWN);		//printk("newx = %d,newy = %d\n",newX,newY);		wake_up_interruptible(&digi_wait);				if(ts_fasync)			kill_fasync(&ts_fasync, SIGIO, POLL_IN);		return;		}	else	{		FAILED(" error to call me \n");		return;	}}/************************************************Misc functions for SPI *************************************************/void spi_init(void){	int datarate,i;	int cs;	datarate = 0x8;//1024	cs = 0x0;//ss0	//cspi1_mosi--pd31 output	//cspi1_miso--pd30 input	//cspi1_sclk--pd29 output	//cspi1_ss0 --pd28,output it connect with pen_cs_b		_reg_GPIO_GIUS(GPIOD) &= 0x0fffffff;	_reg_GPIO_GPR(GPIOD) &= 0x0fffffff;	_reg_GPIO_DDIR(GPIOD) |= 0xb0000000;	_reg_GPIO_DDIR(GPIOD) &= 0xbfffffff;		//reset spi1	*((P_U32)CSPI1_RESETREG1) = 0x00000001;		for(i=0;i<20000;i++);		// use 32.768kHz	*((P_U32)CSPI1_PERIODREG1) = 0x00008000;		//bit19,18 CS[1:0], bit 17~14 datarate[3:0]	*((P_U32)CSPI1_CONTROLREG1) |= (cs<<18);	*((P_U32)CSPI1_CONTROLREG1) |= (datarate<<14);	*((P_U32)CSPI1_CONTROLREG1) |= 0x00000c07;//ss low active, 8 bit transfer,master mode		_reg_CRM_PCCR0 |= 0x00000010;}//To polling when Spi transfer is not finishedstatic void spi_poll_done(void){	//here should poll the IRQ bit in IRQ reg to see 	while(!(*((P_U32)CSPI1_INTREG1) & SPI_TE_INT_BIT));//transfer FIFO is empty	udelay(20);    /* Reset SPI IRQ bit */	*((P_U32)CSPI1_INTREG1) &= SPI_TE_INT_BIT;	udelay(20);	//wait until XCH bit is clear, hence exchange is complete	while(!(*((P_U32)CSPI1_CONTROLREG1) & SPI_XCH_BIT));	udelay(20);}static int spi_tx_fifo_empty(void){	int ret;		ret = *((P_U32)CSPI1_INTREG1) & SPI_TE_INT_BIT;	//printk("tx_ret = 0x%x\n",ret);	//for(i=0;i<10000;i++);	udelay(20);	return ret;}static int spi_rx_fifo_data_ready(void){	int ret;	ret = *((P_U32)CSPI1_INTREG1) & SPI_RR_INT_BIT;	//for(i=0;i<10000;i++);	udelay(20);	//printk("rx_ret = 0x%x\n",ret);	return ret;}static unsigned int spi_exchange_data(unsigned int dataTx){	while(!spi_tx_fifo_empty());	*((P_U32)CSPI1_TXDATAREG1)  = dataTx;			//transfer data    *((P_U32)CSPI1_CONTROLREG1) |= SPI_XCH_BIT;		// exchange data        while(!spi_rx_fifo_data_ready());        return *((P_U32)CSPI1_RXDATAREG1);}void spi_flush_fifo(void){	U32 i,j;	for(i=0;i<8;i++)	{			if(*((P_U32)CSPI1_INTREG1)&SPI_RR_INT_BIT)		j = *((P_U32)CSPI1_RXDATAREG1);	}}static void spi_tx_data(u16 data){    /* ensure data will not be transmitted while writing to SPI */    *((P_U32)CSPI1_CONTROLREG1) &= SPI_XCH_MASK;    *((P_U32)CSPI1_CONTROLREG1) |= SPI_EN_BIT;    *((P_U32)CSPI1_TXDATAREG1)  = (u32)data;//transfer data    *((P_U32)CSPI1_CONTROLREG1) |= SPI_XCH_BIT;    spi_poll_done();    *((P_U32)CSPI1_CONTROLREG1) &= SPI_XCH_MASK;}/****************************************************************************** * Function Name: check_device * * Input: 		inode	: * Value Returned:	int	: Return status.If no error, return 0. * * Description: verify if the inode is a correct inode * *****************************************************************************/static int check_device(struct inode *pInode){	int minor;	kdev_t dev = pInode->i_rdev;		if( MAJOR(dev) != g_digi_major)	{//		printk("DIGI: check_device bad major = %d\n",MAJOR(dev) );		return -1;	}	minor = MINOR(dev);		if ( minor < MAX_ID )		return minor;	else	{       //		printk("DIGI: check_device bad minor = %d\n",minor );		return -1;	}}/**************************************************Misc functions for buffer***************************************************//* local buffer for store data * a new feature is read block, assume the buffer is a continuous buffer * so, if there is enough data, read data from current position to  * buffer end, then next time, from buffer head to data end. -- the buffer * is a loop buffer. */ts_event_t * buffer;#define BUFLEN		250#define BUFSIZE 	(BUFLEN*sizeof(ts_event_t))#define NEXTI(i)	{i=(i==BUFLEN-1)?0:i+1;}#define GETNEXTI(i)	((i==BUFLEN-1)?0:i+1)#define BLKEND(i)	((i)==0)#if 1#define DSIZE()		((wptr<rptr)?(BUFLEN-rptr):(wptr-rptr))#else#define DSIZE()		((wptr<rptr)?(BUFLEN-rptr+wptr):(wptr-rptr))#endif/****************************************************************************** * Function Name: init_buf  * * Input: 		void	: * Value Returned:	int	: Return status.If no error, return 0. * * Description: init the loop buffer for store data read out from spi FIFO * 	and shall be copied to user * *****************************************************************************/static int init_buf(void){	buffer = (ts_event_t*) vmalloc(BUFSIZE);		if(!buffer){//		printk(KERN_ERR"no enough kernel memory for spi data buffer\n");		return -1;	}	rptr = wptr = 0;	return 1;}/****************************************************************************** * Function Name: add_x_y * * Input: 		i	: * Value Returned:	void	:  * * Description: add pen data to buffer * *****************************************************************************/static void add_x_y(unsigned x, unsigned y, unsigned flag){		if (GETNEXTI(wptr) == rptr)		return;	buffer[wptr].x = x;	buffer[wptr].y = y;

⌨️ 快捷键说明

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