该函数是由__tsOpen注册的中断服务函数,在中断服务函数中进行判断,判断不同中断信号进行不同的中断处理,并给__tsThread发送二进制信号量。具体实现如程序清单 36所示。
程序清单 36
static irqreturn_t __tsIsr (void *arg) { …… /* * 检测触摸转换是否完成 */ if(uisr & ADC_ISR_TF) { writel(ADC_ISR_TF, REG_ADC_ISR); /* 清除标志位 */ /* * 若转换完成,赋值并使touchGetXY返回1 * 否则清零并使touchGetXY返回0 */ uiRegVal = readl(REG_ADC_XYDATA); abs_xp = (uiRegVal >> ADC_XYDATA_XBIT) & 0xFFF; abs_yp = (uiRegVal >> ADC_XYDATA_YBIT) & 0xFFF; send_press = TF_ON; printk("%d abs_xp = %d, abs_yp = %d \n", __LINE__, abs_xp, abs_yp); API_SemaphoreBPost(adc_sem); /* 释放一个信号给等待任务 */ } else { abs_xp = XDATA_CLR; abs_yp = YDATA_CLR; send_press = TF_OFF; API_SemaphoreBPost(adc_sem); } /* * 检测是否触摸按下 / 松开 */ if((uisr & ADC_ISR_PEUEF) && (uier & ADC_IER_PEUEIEN)) { uiRegVal = ADC_ISR_PEUEF | ADC_ISR_PEDEF; writel(uiRegVal, REG_ADC_ISR); } else if((uisr & ADC_ISR_PEDEF) && (uisr & ADC_IER_PEDEIEN)) { uiRegVal = readl(REG_ADC_ISR) | ADC_ISR_PEUEF | ADC_ISR_PEDEF; writel(uiRegVal, REG_ADC_ISR); API_SemaphoreBPost(adc_mst); } /* * 检测所有转换是否完成 */ if(uisr & ADC_ISR_MF) { uiRegVal = readl(REG_ADC_ISR) | ADC_ISR_MF; writel(uiRegVal, REG_ADC_ISR); } return (LW_IRQ_HANDLED); }
__tsOpen
Open函数调用Init函数初始化并创建触摸屏服务线程。具体实现如程序清单 37所示。
程序清单 37
static LONG __tsOpen (TS_DEV *ptsDev, PCHAR pcName, INT iFlags, INT iMode) { …… __tsInit(); …… /* * 创建触摸屏服务线程 */ ptsDev->TS_hThread = API_ThreadCreate("t_touch", (PTHREAD_START_ROUTINE)__tsThread, &threadattr, LW_NULL); …… }
__tsInit
Init函数中创建二进制信号量,注册中断服务函数。具体实现如程序清单 38所示。
程序清单 38
static void __tsInit (void) { …… API_SemaphoreBCreate("ad_thread_sem", 0, LW_OPTION_WAIT_FIFO, &adc_sem); API_SemaphoreBCreate("ad_thread_mst", 0, LW_OPTION_WAIT_FIFO, &adc_mst); …… /* * 安装ADC 中断服务程序, */ API_InterVectorConnect(VIC_CHANNEL_ADC, (PINT_SVR_ROUTINE)__tsIsr, (PVOID)NULL, "touchscr"); API_InterVectorEnable(VIC_CHANNEL_ADC); …… }
__tsClose
Close函数用于删除之前创建的信号量和线程。具体实现如程序清单 39所示。