完善资料让更多小伙伴认识你,还能领取20积分哦, 立即完善>
|
|
相关推荐
1个回答
|
|
1. 电阻屏原理
电阻屏X层上X-到X+和Y-到Y+的电阻是均匀分布的。 当计算触摸点时分为两步: 1、计算Y坐标,在Y+电极施加驱动电压V,Y-接地,芯片通过X+测量接触点的电压。 由于ITO层均匀导电,触点电压与V电压之比等于触点Y坐标与屏高度之比。 2、计算X坐标,在X+电极施加驱动电压V, X-电极接地,Y+做为引出端测量得到接触点的电压,由于ITO层均匀导电,触点电压与Vdrive电压之比等于触点X坐标与屏宽度之比。 测得的电压通常由ADC转化为数字信号,再进行简单处理就可以做为坐标判断触点的实际位置。 2. ADC 2.1 Device: /* TSc controller */ static struct tsc_data am335x_touchscreen_data = { .wires = 4, .x_plate_resistance = 600, .steps_to_configure = 5, }; static struct adc_data am335x_adc_data = { .adc_channels = 4, }; static struct mfd_tscadc_board tscadc = { .tsc_init = &am335x_touchscreen_data, .adc_init = &am335x_adc_data, }; 创建了对应的Platform Device:mfd_tscadc_init() -》 am33xx_register_mfd_tscadc() -》 omap_device_build() -》 omap_device_build_ss() -》 omap_device_register() 2.2 Driver: kernelarcharmplat-omapomap_device.c中定义了driver: static struct platform_driver ti_tscadc_driver = { .driver = { .name = “ti_tscadc”, .owner = THIS_MODULE, }, .probe = ti_tscadc_probe, .remove = __devexit_p(ti_tscadc_remove), .suspend = tscadc_suspend, .resume = tscadc_resume, }; ↓ static int __devinit ti_tscadc_probe(struct platform_device *pdev) { /* 解析出Touch Screen Controller的配置: 其中4路ADC用来做为电阻式触摸屏控制器 */ /* TSC Cell */ if (pdata-》tsc_init) { cell = &tscadc-》cells[children]; cell-》name = “tsc”; cell-》platform_data = tscadc; cell-》pdata_size = sizeof(*tscadc); children++; } /* 解析出ADC的配置: 另外4路ADC用来做独立的ADC使用 */ /* ADC Cell */ if (pdata-》adc_init) { cell = &tscadc-》cells[children]; cell-》name = “tiadc”; cell-》platform_data = tscadc; cell-》pdata_size = sizeof(*tscadc); children++; } /* 创建TSC和ADC对应的Platform Device */ err = mfd_add_devices(&pdev-》dev, pdev-》id, tscadc-》cells, children, NULL, 0); } 3. TouchSceen 触摸屏设备对应event1和touchscreen0: root@am335x-evm:~# ls /dev/input/event1 /dev/input/event1 root@am335x-evm:~# ls -l /dev/input/touchscreen0 lrwxrwxrwx 1 root root 6 Jan 1 00:03 /dev/input/touchscreen0 -》 event1 /dev/input/event1读取出的数据是原始的ADC数据,它的最大值为2^12。需要经过tslib根据fb的分辨率转换以后,才能得到需要使用的X、Y轴的坐标值。 3.1 Device 在kernelarcharmplat-omapomap_device.c驱动的ti_tscadc_probe函数中创建了TSC的Platform Device。 3.2 Driver drivers/input/touchscreen/ti_tsc.c: static struct platform_driver ti_tsc_driver = { .probe = tscadc_probe, .remove = __devexit_p(tscadc_remove), .driver = { .name = “tsc”, .owner = THIS_MODULE, }, .suspend = tsc_suspend, .resume = tsc_resume, }; ↓ 初始化时注册input_device,对应/sys/class/input/input0/: static int __devinit tscadc_probe(struct platform_device *pdev) { input_dev = input_allocate_device(); input_dev-》name = “ti-tsc”; input_dev-》dev.parent = &pdev-》dev; input_dev-》evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_ABS); input_dev-》keybit[BIT_WORD(BTN_TOUCH)] = BIT_MASK(BTN_TOUCH); input_set_abs_params(input_dev, ABS_X, 0, MAX_12BIT, 0, 0); input_set_abs_params(input_dev, ABS_Y, 0, MAX_12BIT, 0, 0); input_set_abs_params(input_dev, ABS_PRESSURE, 0, MAX_12BIT, 0, 0); /* register to the input system */ err = input_register_device(input_dev); } 中断时上报input_event: static irqreturn_t tscadc_interrupt(int irq, void *dev) { /* * Sample found inconsistent by debouncing * or pressure is beyond the maximum. * Don‘t report it to user space. */ /* 上报电阻触摸屏的X、Y、Z值。 X、Y为坐标值,Z为压力值 */ if (pen == 0) { if ((diffx 《 15) && (diffy 《 15) && (z 《= MAX_12BIT)) { input_report_abs(input_dev, ABS_X, val_x); input_report_abs(input_dev, ABS_Y, val_y); input_report_abs(input_dev, ABS_PRESSURE, z); input_report_key(input_dev, BTN_TOUCH, 1); input_sync(input_dev); } } status = tscadc_readl(ts_dev, TSCADC_REG_RAWIRQSTATUS); if (status & TSCADC_IRQENB_PENUP) { /* Pen up event */ fsm = tscadc_readl(ts_dev, TSCADC_REG_ADCFSM); if (fsm == 0x10) { pen = 1; bckup_x = 0; bckup_y = 0; input_report_key(input_dev, BTN_TOUCH, 0); input_report_abs(input_dev, ABS_PRESSURE, 0); input_sync(input_dev); } else { pen = 0; } irqclr |= TSCADC_IRQENB_PENUP; } } 3.3 uDev Udev就是在用户空间接收内核sysfs netlink热插拔消息的程序,而内核态调用用户空间程序的方式调用的是“/***in/hotplug”,后一种方式已经被淘汰。 用户空间对热插拔消息的处理有几类动作: 1、创建或者移除设备的设备节点;如果设备有devt属性,即“/sys/class/” 路径下包含“dev”文件属性的内核设备,发生增加或移除操作时,udev会帮其在用户空间“/dev”路径下增加或移除设备节点。2、根据规则文件,给设备改名、创建符号链接等。3、根据规则文件,调用外部程序。例如,调用modprobe插入驱动。 /etc/udev/rules.d/local.rules: # Create a symlink to any touchscreen input deviceSUBSYSTEM, KERNEL, ATTRS{modalias}==“input:*-e0*,3,*a0,1 4. KeyBoard 键盘设备对应event0: root@am335x-evm:~# ls /dev/input/event0 /dev/input/event0 4.1 Device kernelarcharmmach-omap2board-am335xevm.c中定义了device: /* Matrix GPIO Keypad Support for profile-0 only: TODO */ /* pinmux for keypad device */ static struct pinmux_config matrix_keypad_pin_mux[] = { {”gpmc_a7.gpio1_23“, OMAP_MUX_MODE7 | AM33XX_PIN_INPUT}, //T15 {”gpmc_a10.gpio1_26“, OMAP_MUX_MODE7 | AM33XX_PIN_INPUT}, //T16 {”gpmc_a2.gpio1_18“, OMAP_MUX_MODE7 | AM33XX_PIN_INPUT}, //U14 {”gpmc_a8.gpio1_24“, OMAP_MUX_MODE7 | AM33XX_PIN_OUTPUT}, //V16 {”gpmc_a6.gpio1_22“, OMAP_MUX_MODE7 | AM33XX_PIN_OUTPUT}, //U15 {”gpmc_a5.gpio1_21“, OMAP_MUX_MODE7 | AM33XX_PIN_OUTPUT}, //V15 {”gpmc_a1.gpio1_17“, OMAP_MUX_MODE7 | AM33XX_PIN_OUTPUT}, //V14 {”gpmc_a4.gpio1_20“, OMAP_MUX_MODE7 | AM33XX_PIN_OUTPUT}, //R14 {”gpmc_a3.gpio1_19“, OMAP_MUX_MODE7 | AM33XX_PIN_OUTPUT}, //T14 {”mcasp0_axr0.gpio3_16“, OMAP_MUX_MODE7 | AM33XX_PIN_OUTPUT}, //D12 // {”ecap0_in_pwm0_out.gpio0_7“, OMAP_MUX_MODE7 | AM33XX_PIN_OUTPUT}, //C18. hx del 12.13 {”uart1_rxd.gpio0_14“, OMAP_MUX_MODE7 | AM33XX_PIN_OUTPUT},//D16 {NULL, 0}, }; /* Keys mapping */ static const uint32_t am335x_evm_matrix_keys[] = { KEY(0, 0, KEY_F1), KEY(0, 1, KEY_F2), KEY(0, 2, KEY_F3), KEY(0, 3, KEY_F4), KEY(0, 4, KEY_1), KEY(0, 5, KEY_2), KEY(0, 6, KEY_3), KEY(0, 7, KEY_0), KEY(1, 0, KEY_F5), KEY(1, 1, KEY_F6), KEY(1, 2, KEY_F7), KEY(1, 3, KEY_BACKSPACE), KEY(1, 4, KEY_4), KEY(1, 5, KEY_5), KEY(1, 6, KEY_6), KEY(1, 7, KEY_MINUS), KEY(2, 0, KEY_F9), KEY(2, 1, KEY_ENTER), KEY(2, 2, KEY_F11), KEY(2, 3, KEY_F12), KEY(2, 4, KEY_7), KEY(2, 5, KEY_8), KEY(2, 6, KEY_9), KEY(2, 7, KEY_DOT), }; const struct matrix_keymap_data am335x_evm_keymap_data = { .keymap = am335x_evm_matrix_keys, .keymap_size = ARRAY_SIZE(am335x_evm_matrix_keys), }; static const unsigned int am335x_evm_keypad_row_gpios[] = { GPIO_TO_PIN(1, 18), GPIO_TO_PIN(1, 26), GPIO_TO_PIN(1, 23) }; static const unsigned int am335x_evm_keypad_col_gpios[] = { GPIO_TO_PIN(1, 24), GPIO_TO_PIN(1, 22), GPIO_TO_PIN(1, 21), GPIO_TO_PIN(1, 17), GPIO_TO_PIN(1, 20), GPIO_TO_PIN(1, 19), GPIO_TO_PIN(3, 16), GPIO_TO_PIN(0, 14) }; static struct matrix_keypad_platform_data am335x_evm_keypad_platform_data = { .keymap_data = &am335x_evm_keymap_data, .row_gpios = am335x_evm_keypad_row_gpios, .num_row_gpios = ARRAY_SIZE(am335x_evm_keypad_row_gpios), .col_gpios = am335x_evm_keypad_col_gpios, .num_col_gpios = ARRAY_SIZE(am335x_evm_keypad_col_gpios), .active_low = false, .debounce_ms = 5, .col_scan_delay_us = 2, }; static struct platform_device am335x_evm_keyboard = { .name = ”matrix-keypad“, .id = -1, .dev = { .platform_data = &am335x_evm_keypad_platform_data, }, }; static void matrix_keypad_init(int evm_id, int profile) { int err; setup_pin_mux(matrix_keypad_pin_mux); err = platform_device_register(&am335x_evm_keyboard); if (err) { pr_err(”failed to register matrix keypad (2x3) devicen“); } } 4.2 Driver kerneldriversinputkeyboardmatrix_keypad.c: static struct platform_driver matrix_keypad_driver = { .probe = matrix_keypad_probe, .remove = __devexit_p(matrix_keypad_remove), .driver = { .name = ”matrix-keypad“, .owner = THIS_MODULE, #ifdef CONFIG_PM .pm = &matrix_keypad_pm_ops, #endif }, }; ↓ |
|
|
|
只有小组成员才能发言,加入小组>>
4515个成员聚集在这个小组
加入小组3337 浏览 0 评论
航顺(HK)联合电子发烧友推出“近距离体验高性能Cortex-M3,免费申请价值288元评估板
4266 浏览 1 评论
4292 浏览 0 评论
小黑屋| 手机版| Archiver| 电子发烧友 ( 湘ICP备2023018690号 )
GMT+8, 2024-12-23 22:04 , Processed in 0.618293 second(s), Total 73, Slave 58 queries .
Powered by 电子发烧友网
© 2015 bbs.elecfans.com
关注我们的微信
下载发烧友APP
电子发烧友观察
版权所有 © 湖南华秋数字科技有限公司
电子发烧友 (电路图) 湘公网安备 43011202000918 号 电信与信息服务业务经营许可证:合字B2-20210191 工商网监 湘ICP备2023018690号