 |
s3c2410触摸屏在linux下的驱动分析二 |
|
 |
|
s3c2410触摸屏在linux下的驱动分析二 |
|
副标题:s3c2410触摸屏在linux下的驱动分析二 |
| 日期:2008-03-19 22:44:57 来源:雪竹的BLOG 编辑:51Touch |
|
最后用ARM 汇编指令实现了对IRQ 的使能和禁止。 spin_lock_irq(&(tsdev.lock)); 这样调用spin_lock_irq 宏函数,实际上只是做了local_irq_disable();一步,就是禁止IRQ 中断。
if (tsdev.penStatus == PEN_UP) s3c2410_get_XY(); 然后根据变量tsdev.penStatus 所处的状态,若为笔抬起则调用s3c2410_get_XY 函数来取得A/D转换得到的坐标值,该函数会在后面说明。 #ifdef HOOK_FOR_DRAG else s3c2410_get_XY(); #endif 这里表示如果定义了笔拖曳,且在笔没有抬起的情况下,继续调用s3c2410_get_XY 函数来得到最新的坐标值。 spin_unlock_irq(&(tsdev.lock)); 最后调用spin_unlock_irq 宏函数,相当于只做了local_irq_enable();一步,来重新使能IRQ 中断。最后退出这个中断服务子程序。
继续来看一下另一个中断处理函数,即触摸屏触摸中断处理函数: static void s3c2410_isr_tc(int irq, void *dev_id, struct pt_regs *reg) 该函数的参数和上面A/D转换中断处理函数的定义一样,不再累赘。 spin_lock_irq(&(tsdev.lock));
也同上面的意思一样,首先禁止IRQ 中断。 if (tsdev.penStatus == PEN_UP) { start_ts_adc(); } 接着根据变量tsdev.penStatus 的状态值判断是否进行A/D转换。若笔抬起,则调用函数start_ts_adc 来进行A/D转换,该函数会在后面说明。 else { tsdev.penStatus = PEN_UP; DPRINTK("PEN UP: x: d, y: d\n", x, y); wait_down_int(); tsEvent(); } 如果变量tsdev.penStatus 的状态值不是笔抬起,则先将该变量状态设为笔抬起,然后调用宏函数wait_down_int()。该宏函数已在前面说明,用来设置触摸屏为等待中断模式。最后调用tsEvent 函数指针所指的函数,在模块初始化函数s3c2410_ts_init 中,tsEvent 指向的是一个空函数tsEvent_dummy,而在打开设备函数s3c2410_ts_open 中,tsEvent 会指向tsEvent_raw 函数,该函数负责填充触摸屏缓冲区,并唤醒等待的进程。该函数也会在后面加以说明。 spin_unlock_irq(&(tsdev.lock)); 中断处理函数的最后一步都一样,重新使能IRQ 中断。退出中断服务子程序。
下面先来看启动A/D转换的函数: static inline void start_ts_adc(void) adc_state = 0; mode_x_axis(); start_adc_x(); 简简单单的3步。 第一步,对A/D转换的状态变量清零。 第二步,调用mode_x_axis 宏函数,具体定义如下: #define mode_x_axis() { ADCTSC = XP_EXTVLT | XM_GND | YP_AIN | YM_HIZ | \ XP_PULL_UP_DIS | XP_PST(X_AXIS_MODE); }
该宏函数用来设置ADC触摸屏控制寄存器为测量X坐标模式,参考S3C2410 芯datasheet 中关于触摸屏的章节,具体设置参数如下: XP_EXTVLT = 1<<4 * 0 选择nXPON 引脚输出值,设为0 表示nXPON 引脚输出0,则XP 引脚为接外部电压 XM_GND = 1<<5 * 1 选择XMON 引脚输出值,设为1 表示XMON 引脚输出1,则XM 引脚为接地 YP_AIN = 1<<6 * 1 选择nYPON 引脚输出值,设为1 表示nYPON 引脚输出1,则YP 引脚连接AIN[5] 引脚 YM_HIZ = 1<<7 * 0 选择YMON 引脚输出值,设为0 表示YMON 引脚输出0,则YM 引脚为高阻态 XP_PULL_UP_DIS = 1<<3 * 1 上拉开关使能,设为1 表示XP 引脚上拉禁止 XP_PST(X_AXIS_MODE); = 1 X坐标Y坐标手动测量设置,设为1 表示X坐标测量模式 第三步,调用start_adc_x 宏函数,具体定义如下: #define start_adc_x() { ADCCON = PRESCALE_EN | PRSCVL(49) | \ ADC_INPUT(ADC_IN5) | ADC_START_BY_RD_EN | \ ADC_NORMAL_MODE; \ ADCDAT0; } 该宏函数用来设置ADC控制寄存器启动X坐标的A/D转换,参考S3C2410 芯片datasheet 中关于触摸屏的章节,具体设置参数如下: PRESCALE_EN = 1<<14 * 1 A/D转换器使能,设为1 表示使能A/D转换器 PRSCVL(49) = 49<<6 A/D转换器值,设为49 ADC_INPUT(ADC_IN5) = 5<<3 选择模拟输入通道,设为5 表示AIN[5] 引脚作为模拟输入通道 ADC_START_BY_RD_EN = 1<<1 * 1 A/D转换通过读启动,设为1 表示通过读操作启动A/D转换使能 ADC_NORMAL_MODE; = 1<<2 * 0 选择待命模式,设为0 表示正常操作模式 ADCDAT0; 读取X坐标的ADC转换数据寄存器 由于设置了A/D转换通过读启动,则该ADCCON 寄存器的最低位ENABLE_START 启动A/D转换位就无效了。在最后一步读取ADCDAT0 寄存器这一操作时就启动了A/D转换。
static inline void s3c2410_get_XY(void) 这就是获取A/D转换所得到的坐标值的函数。 if (adc_state == 0) { adc_state = 1; disable_ts_adc(); y = (ADCDAT0 & 0x3ff); mode_y_axis(); start_adc_y(); } 这里首先查看A/D转换的状态变量,若为0 表示进行过X坐标的A/D转换,将该变量设为1。然后调用宏函数disable_ts_adc,该宏函数定义如下: #define disable_ts_adc() { ADCCON &= ~(ADCCON_READ_START); } 这个宏函数主要工作就是禁止通过读操作启动A/D转换,参考S3C2410 芯片datasheet 中关于触摸屏的章节,具体设置参数如下: ADCCON_READ_START = 1<<1 A/D转换通过读启动,设为0 表示通过读操作启动A/D转换禁止 然后y = (ADCDAT0 & 0x3ff); 这一步将X坐标的ADC转换数据寄存器的D9~D0 这10为读出到变量y(这里由于是竖屏,参考原理图后知道,硬件连线有过改动,将XP,XM 和YP,YM 进行了对换,这样ADCDAT0 里读出的是YP,YM 方向电阻导通的值,也就是y轴坐标值)。这个mode_y_axis 宏函数定义如下: #define mode_y_axis() { ADCTSC = XP_AIN | XM_HIZ | YP_EXTVLT | YM_GND | \ XP_PULL_UP_DIS | XP_PST(Y_AXIS_MODE); } 该宏函数用来设置ADC触摸屏控制寄存器为测量Y坐标模式,参考S3C2410 芯片datasheet 中关于触摸屏的章节,具体设置参数如下: XP_AIN = 1<<4 * 1 选择nXPON 引脚输出值,设为1 表示nXPON 引脚输出1,则XP 引脚连接AIN[7] 引脚 XM_HIZ = 1<<5 * 0 选择XMON 引脚输出值,设为0 表示XMON 引脚输出0,则XM 引脚为高阻态 YP_EXTVLT = 1<<6 * 0 选择nYPON 引脚输出值,设为0 表示nYPON 引脚输出0,则YP 引脚为接外部电压 YM_GND = 1<<7 * 1 选择YMON 引脚输出值,设为1 表示YMON 引脚输出1,则YM 引脚为接地 XP_PULL_UP_DIS = 1<<3 * 1 上拉开关使能,设为1 表示XP 引脚上拉禁止 XP_PST(Y_AXIS_MODE); = 2 X坐标Y坐标手动测量设置,设为2 表示Y坐标测量模式 最后调用start_adc_y 宏函数,具体定义如下: #define start_adc_y() { ADCCON = PRESCALE_EN | PRSCVL(49) | \ ADC_INPUT(ADC_IN7) | ADC_START_BY_RD_EN | \ ADC_NORMAL_MODE; \ ADCDAT1; } 该宏函数用来设置ADC控制寄存器启动Y坐标的A/D转换,参考S3C2410 芯片datasheet 中关于触摸屏的章节,具体设置参数如下: PRESCALE_EN = 1<<14 * 1 A/D转换器使能,设为1 表示使能A/D转换器 PRSCVL(49) = 49<<6 A/D转换器值,设为49 ADC_INPUT(ADC_IN7) = 7<<3 选择模拟输入通道,设为7 表示AIN[7] 引脚作为模拟输入通道 ADC_START_BY_RD_EN = 1<<1 * 1 A/D转换通过读启动,设为1 表示通过读操作启动A/D转换使能 ADC_NORMAL_MODE; = 1<<2 * 0 选择待命模式,设为0 表示正常操作模式 ADCDAT1; 读取Y坐标的ADC转换数据寄存器
|
|
|
| 对这篇文章您有更多的想法?
请去论坛发表意见吧
|
 |
“s3c2410触摸屏在linux下的驱动分析二” 的相关新闻 |
 |
|
|
|
|
|
 |
站内搜索 |
 |
|