Design of I2C-based embedded multi-point touch screen driver
Abstract: With Samsung's 7958 processor, the driver Management System of Embedded Linux is used to implement the design of multi-point touch screen Driver Based on I2C bus protocol, such as cypress and snaptics tm1444. Practice has proved that the qtopia Platform Based on Linux core and the andriod embedded operating system run smoothly, with a high degree of recognition and accuracy.
Introduction
With the development and promotion of embedded devices, touch screens can be seen everywhere as new input devices. Mobile phones, PDAs, mid, and ATM devices have all used touch screens. As technology continues to develop, touch screens have evolved from the first 4-wire single-point resistive touch screen to various multi-point capacitive touch screens today. By studying the capacitive multi-point touch screen of I2C bus interface represented by Cypress 7958, this paper designs a multi-point touch screen driver for Linux operating system, the single-chip microcomputer driver for touch screen without running the operating system has achieved good results.
1 Introduction to the research platform
1.1 arm11 processor x
Based on the arm1176jzfs core, the general-purpose processor for handheld, mobile, and other terminal devices. Cloud6410x is a low-power, cost-effective, and high-performance rsic processor for mobile phones and general-purpose processing. It provides optimized hardware performance for 2G and 3G communication services. It adopts a 64/32-bit internal BUS architecture and integrates the Axi, AHB, and APB bus. There are also many powerful hardware accelerators, including motion video processing, audio processing, 2D acceleration, display processing, and scaling.
1.2 capacitive multi-point touch screen
Capacitive touch screens are plated with long and narrow electrodes on four sides of the touch screen, forming a low voltage AC electric field in the conductive body. When you touch the screen, due to the human electric field, a coupling capacitor is formed between the finger and the conductor, and the current sent from the four edges will flow to the contact, and the current intensity is proportional to the distance from the finger to the electrode, the Controller located behind the touch screen will calculate the ratio and strength of the current and accurately calculate the position of the touch point. Capacitive touch screen dual glass not only protects the conductor and sensor, but also effectively prevents external environmental factors from affecting the touch screen, even if the screen is stained with dirt, dust or oil, capacitive touch screen can still accurately calculate the touch position. Compared with the resistive touch screen, capacitive touch screen supports multi-touch human-computer interaction. A general resistive touch screen can only touch a single touch.
1.3 arm tool chain
This article uses the armnonelinuxgnueabi4.3.2 cross-compilation chain for the single-chip microcomputer of the ARM core to compile binary files supported by the arm. It is used to successfully compile the armlinux 2.6.28 kernel.
1.4 transplantation Conditions
All processors (including embedded processors) that support Linux operating systems can run as described in this article, all single-chip microcomputer that supports I2C bus protocol can also use the touch screen as a common input device without using the operating system.
2 study process
Figure 1 shows the hardware and software architecture of the driver for the embedded Linux platform.
Figure 1 drive hardware and software architecture
2.1 I2C device platform part Declaration
The I2C address of Cypress 7958 multi-point touch screen is 0x20. Before use, you must declare the I2C device at the platform device so that the Linux driver can find the corresponding I2C address for operation. First, declare the I2C device struct. The Code is as follows:
Static struct i2c_board_info i2c_devs1 [] _ initdata = {
{I2c_board_info ("cypress7958", 0x20),},/* cypress7958 touch pannel controller */
};
Then declare the I2C device in the static void _ init smdk6410_machine_init (void) function:
I2c_register_board_info (1, i2c_devs1, array_size (i2c_devs1 ));
2.2 cypress 7958 driver part design
2.2.1 registration and cancellation Module
First, create the I2C driver struct cypress_7958_driver. The Code is as follows:
Static struct i2c_driver cypress_7958_driver = {
. Probe = cypress_7958_probe,
. Remove = cypress_7958_remove,
. Id_table = cypress_7958_id,
. Driver = {
. Name = cypress_7958_name,
},
};
Then create the _ init initialization function and the _ exit function to log out of the device: static int _ devinit cypress_7958_ts_init (void), static void _ exit cypress_7958_exit (void ), the i2c_add_driver and i2c_del_driver functions are used to register and deregister I2C devices.
2.2.2 Design of touch screen drive entry function
According to the I2C struct declared in the previous section, when the device is checked, it enters the static int synaptics_ts_probe (struct i2c_client * client, const struct i2c_device_id * ID) function, in this function, you need to initialize the touch screen working mode, register the device name of the touch screen driver on the Linux platform as the input device, and initialize the interrupt operation triggered by the touch event.
(1) cypress 7958 Mode Initialization
As a multi-point touch screen, cypress 7958 has many related configuration registers, which are not described in this article. The initialization part only needs to check whether the screen works in normal working mode, read the 0x28 address register. If the value is 0x07, the screen works normally; otherwise, an error value is returned.
Ret = i2c_smbus_read_byte_data (TS> client, 0x28 );
If (Ret! = 0x07 ){
Printk (kern_err, "Cypress detect errorn ");
Return ret;
}
(2) enter the device name for registration
Create a struct input_dev struct, use the input_allocate_device () function to create a device name, and then use the set_bit function to input the device function declaration. Because it is a multi-point touch screen, you can generate ev_syn, ev_key, btn_touch, btn_2 (multi-point touch), ev_abs and other functions, so declare it:
Set_bit (ev_syn, TS> input_dev> evbit );
Set_bit (ev_key, TS> input_dev> evbit );
Set_bit (btn_touch, TS> input_dev> keybit );
Set_bit (btn_2, TS> input_dev> keybit );
Set_bit (ev_abs, TS> input_dev> evbit );
Then complete the specific configuration of the event:
Input_set_abs_params (TS> input_dev, abs_x, 0, max_y, 0, 0 );
Input_set_abs_params (TS> input_dev, abs_y, 0, max_x, 0, 0 );
Input_set_abs_params (TS> input_dev, abs_pressure, 0,255, 0, 0 );
Input_set_abs_params (TS> input_dev, abs_tool_width, 0, 15, 0, 0 );
Input_set_abs_params (TS> input_dev, abs_hat0x, 0, max_y, 0, 0 );
Input_set_abs_params (TS> input_dev, abs_hat0y, 0, max_x, 0, 0 );
Input_set_abs_params (TS> input_dev, abs_mt_position_x, 0, max_y, 0, 0 );
Input_set_abs_params (TS> input_dev, abs_mt_position_y, 0, max_x, 0, 0 );
Input_set_abs_params (TS> input_dev, abs_mt_touch_major, 0,255, 0, 0 );
Input_set_abs_params (TS> input_dev, abs_mt_width_major, 0, 15, 0, 0 );
Finally, you can use the input_register_device (TS> input_dev) function to register the device name.
(3) interrupt function initialization for Driver events
When a touch event occurs, the cypress 7958 touch screen generates a low-level signal on the IRQ pin, connects the pin to the GPN (15) pin, and creates a gpio interrupt function:
Cloud_gpio_cfgpin (cloud64xx_gpn (15), cloud_gpio_sfn (2 ));
Client> IRQ = gpio_to_irq (89c64xx_gpn (15 ));
Irqflags = ir1__trigger_low;
Then, use ret = request_irq (client> IRQ, cypress_7958_irq_handler, irqflags, client> name, TS) to apply for an interrupt function. Create the cypress_7958_irq_handler function:
Static irqreturn_t cypress_7958_irq_handler (int irq, void * dev_id ){
Struct synaptics_ts_data * Ts = dev_id;
// Int ret = gpio_get_value (89c64xx_gpn (15 ));
// Printk ("% s: ret = % DN" ,__ func __, RET );
Disable_irq_nosync (TS> client> IRQ );
Queue_work (cypress_7958_wq, & TS> work );
Return irq_handled;
}
After the driver event is triggered, use the queue_work function to enter the cypress_7958_wq driver workspace. Then, the driver layer reports information on the application layer.
2.2.3 function design of the touch screen work zone
The Touch Screen workspace function needs to obtain the event information and report the information of the driver layer to the application layer. The initialization Declaration of the driver workspace function is completed through the init_work (& TS> Work, cypress_7958_work_func) function, enter the workspace function cypress_7958_work_func after the driver event is interrupted.
(1) touch screen event information acquisition
Cypress 7958 event trigger information is stored in registers. You only need to read its register information through the i2c_smbus_read_byte_data function to obtain its event information, you can also use i2c_transfer to read its register information in batches:
Buf [0] = i2c_smbus_read_byte_data (TS> client, 0x12 );
Buf [1] = i2c_smbus_read_byte_data (TS> client, 0x13 );
Buf [2] = i2c_smbus_read_byte_data (TS> client, 0x14 );
Buf [3] = i2c_smbus_read_byte_data (TS> client, 0x15 );
Buf [4] = i2c_smbus_read_byte_data (TS> client, 0x16 );
Buf [5] = i2c_smbus_read_byte_data (TS> client, 0x17 );
Buf [6] = i2c_smbus_read_byte_data (TS> client, 0x18 );
Buf [7] = i2c_smbus_read_byte_data (TS> client, 0x19 );
Buf [8] = i2c_smbus_read_byte_data (TS> client, 0x1a );
Buf [9] = i2c_smbus_read_byte_data (TS> client, 0x1b );
Buf [10] = i2c_smbus_read_byte_data (TS> client, 0x1c );
Buf [11] = i2c_smbus_read_byte_data (TS> client, 0x1d );
Buf [12] = i2c_smbus_read_byte_data (TS> client, 0x1e );
Buf [13] = i2c_smbus_read_byte_data (TS> client, 0x1f );
(2) Report touch screen event information
Analyze the Buf array to obtain the specific information of the current event, and then use the input_report series functions to report the event information at the application layer:
If (fingermark = 2 ){
Input_report_key (TS> input_dev, abs_mt_tracking_id, 0 );
Input_report_abs (TS> input_dev, abs_mt_touch_major, f1z );
Input_report_abs (TS> input_dev, abs_mt_position_x, f1x );
Input_report_abs (TS> input_dev, abs_mt_position_y, f1y );
Input_mt_sync (TS> input_dev );
Input_report_key (TS> input_dev, abs_mt_tracking_id, 1 );
Input_report_abs (TS> input_dev, abs_mt_touch_major, f2z );
Input_report_abs (TS> input_dev, abs_mt_position_x, F2X );
Input_report_abs (TS> input_dev, abs_mt_position_y, f2y );
Input_mt_sync (TS> input_dev)
Input_sync (TS> input_dev );
}
Else if (fingermark = 1 ){
Input_report_key (TS> input_dev, abs_mt_tracking_id, 0 );
Input_report_abs (TS> input_dev, abs_mt_touch_major, f1z );
Input_report_abs (TS> input_dev, abs_mt_position_x, f1x );
Input_report_abs (TS> input_dev, abs_mt_position_y, f1y );
Input_mt_sync (TS> input_dev );
Input_sync (TS> input_dev );
}
Else {
Input_report_abs (TS> input_dev, abs_mt_touch_major, 0 );
Input_mt_sync (TS> input_dev );
Input_sync (TS> input_dev );
}
Port 2.3 cypress 7958 driver in Kernel
Run makefile and kconfig to port cypress 7985 in the kernel to help the GCC tool chain compile the kernel.
2.3.1 kconfig Modification
Add the following statement to/driver/input/touchscreen/kconfig:
Config touchscreen_cypress
Tristate "Cypress 7958 touchscreens"
Help
Say y here if you have a cypress 7958 touchscreen connected to your system.
If unsure, say n.
To add the file compilation option to make menuconfig. Because the touch screen driver is the driver of the system's basic input device, it calls the I/O interrupt and cannot compile modules. It can only be fully compiled into the kernel. In subsequent research and development, we found that clock interruption can be used to modularize the compilation into the kernel. However, since clock interruption affects the running of the uClinux time slice, we should discard it.
2.3.2 modify makefile
Then add the corresponding compilation information to/driver/input/touchscreen/makefile:
OBJ $ (config_touchscreen_cypress) + = touchscreen_cypress.o
In the final compilation option, set the arch option in/makefile to. In the options after the make menuconfig command, select the touchsreen_cypress option and compile it into the kernel.
Conclusion
This design uses I2C mode to drive multi-point touch screen. Using embedded Linux, the multi-point touch input mode is applied to the embedded application system, which enriches the single keyboard input and single point input mode, the system size is reduced, and the system reliability is improved. This makes the input method of the embedded system simple and easy, and enhances the communication capability between the embedded system and the human, simplifying the tedious debugging. Using Samsung's arm11 processor, the experiment was accelerated. Practice has proved that the speed and stability of the multi-point touch screen driven by the design can meet the debugging requirements. This design can be directly applied to single-chip microcomputer and all other embedded systems that can run Linux.