The gamepad f310 game controller of Logitech needs to be transplanted to the Android system, so it took two days to detail the main development logic process.
1. First test on PC and Linux:
Install the Logitech driver on the PC.
For general Linux platform installation:
Use the gamepad in Ubuntu:
1. Install the handle DRIVER:
# Modprobe joydev
2. Install the handle testing software:
# Sudo apt-Get install joystick
3. Test handle:
# Jstest/dev/js0
Or
# Jstest/dev/input/js0
2. To use USB direct connection, you must first detect the device and use Linux kernel2.6.35. The configuration is as follows:
Make menuconfig
General setup --->
Device Drivers --->
Input Device Support -->
The main configuration is as follows:
The most important configuration is: joystick Interface
The most important here is X-Box gamepad support
After some of the above configurations are added, plug in USB joystick to work. My job log is as follows:
The Kernel configuration has been modified and can work properly now:
$ USB 1-2.2: new full speed USB device using hiusb-EHCI and address 4
USB 1-2.2: new USB device found, idvendor = 046d, idproduct = c30d
USB 1-2.2: new USB device strings: MFR = 1, Product = 2, serialnumber = 3
USB 1-2.2: Product: gamepad f310
USB 1-2.2: Manufacturer: Logitech
USB 1-2.2: serialnumber: 991241bc
Input: Generic X-Box pad as/devices/platform/hiusb-ehci.0/usb1/1-2/1-2.2/1-2.2: 1.0/input/input1
During plug-in:
$ LS-l
CrW-RW ---- root input 13, 65 1970-01-02 08:02 event1
CrW-RW ---- root input 13, 0 1970-01-02 08:02 js0
CrW-RW ---- root input 13, 64 1970-01-01 08:00 event0
CrW-RW ---- root input 13, 32 1970-01-01 08:00 mouse0
CrW-RW ---- root input 13, 63 1970-01-01 08:00 Mice
After unplugging:
$ LS-l
CrW-RW ---- root input 13, 64 1970-01-01 08:00 event0
CrW-RW ---- root input 13, 32 1970-01-01 08:00 mouse0
CrW-RW ---- root input 13, 63 1970-01-01 08:00 Mice
There are obviously two more device nodes: js0 and event1. This is the name of the read node for the joystick device.
In Android, you can use getevent to obtain the scan code of the key most directly. for debugging of the device input in Android, you can determine the information transmitted by the underlying input device from the source.
The code is in the/system/CORE/toolbox/getevent. C code.
# Getevent
Getevent
Add device 1:/dev/input/event1
Name: "generic X-Box pad"
Cocould not get driver version for/dev/input/js0, invalid argument
Add device 2:/dev/input/event0
Name: "hi3716_keypad"
Cocould not get driver version for/dev/input/mouse0, not a typewriter
Cocould not get driver version for/dev/input/mice, not a typewriter
Node Type code value
Ev_key + key code + up/down
/Dev/input/event1: 0001 0133 00000001 // X button
/Dev/input/event1: 0000 0000 00000000
/Dev/input/event1: 0001 0133 00000000
/Dev/input/event1: 0000 0000 00000000
/Dev/input/event1: 0001 0134 00000001 // y button
/Dev/input/event1: 0000 0000 00000000
/Dev/input/event1: 0001 0134 00000000
/Dev/input/event1: 0000 0000 00000000
/Dev/input/event1: 0001 0131 00000001 // e button
/Dev/input/event1: 0000 0000 00000000
/Dev/input/event1: 0001 0131 00000000
/Dev/input/event1: 0000 0000 00000000
/Dev/input/event1: 0001 0130 00000001 // a button
/Dev/input/event1: 0000 0000 00000000
/Dev/input/event1: 0001 0130 00000000
/Dev/input/event1: 0000 0000 00000000
/Dev/input/event1: 0001 0116 00000001 // back button
/Dev/input/event1: 0000 0000 00000000
/Dev/input/event1: 0001 0116 00000000
/Dev/input/event1: 0000 0000 00000000
Dev/input/event1: 0001 013b 00000001 // start button
Dev/input/event1: 0000 0000 00000000
Dev/input/event1: 0001 013b 00000000
Dev/input/event1: 0000 0000 00000000
Ev_abs + scan code + axis
/Dev/input/event1: 0003 0001 ffff8000 //
/Dev/input/event1: 0000 0000 00000000
/Dev/input/event1: 0003 0001 ffffff7f
/Dev/input/event1: 0000 0000 00000000
/Dev/input/event1: 0003 0001 running 7fff //
/Dev/input/event1: 0000 0000 00000000
/Dev/input/event1: 0003 0001 ffffff7f
/Dev/input/event1: 0000 0000 00000000
/Dev/input/event1: 0003 0000 ffff8000 // left
/Dev/input/event1: 0000 0000 00000000
/Dev/input/event1: 0003 0000 00000080
/Dev/input/event1: 0000 0000 00000000
/Dev/input/event1: 0003 0000 running 7fff // right
/Dev/input/event1: 0000 0000 00000000
/Dev/input/event1: 0003 0000 00000080
/Dev/input/event1: 0000 0000 00000000
Test Case code:
# Include <Linux/input. h> # include <Linux/joystick. h> int main (void) {int js_fd; struct js_event JS; int N, type = 0; int axis_value, button_value; int number_of_axis, number_of_buttons; js_fd = open ("/dev/input/js0", o_rdonly); // open the device file if (js_fd = NULL) {printf ("Open joystick device failed "); return-1;} while (1) {n = read (js_fd, & JS, sizeof (struct js_event); If (n <0 | n! = Sizeof (struct js_event) {printf ("read data failed"); usleep (10*1000); continue;} type = Js. Type &(~ Js_event_init); Switch (type) {Case js_event_axis: number_of_axis = Js. number; axis_value = Js. value; printf ("number: % 2D: Value: % 6D \ n", number_of_axis, axis_value); break; Case js_event_button: number_of_buttons = Js. number; button_value = Js. value; printf ("number: % 2D: Value: % 2D \ n", number_of_buttons, button_value); break;} usleep (10*1000);} return 0 ;}
3. Modify framework code
You can refer to the android4.0 code. This version fully supports this function. Just port the main eventhub. cpp file and joystickinputmapper in inputreader:
As follows:
// See if this device is a joystick.
// Assumes that joysticks always have gamepad buttons in order to distinguish them
// From other devices such as accelerometers that also have absolute axes.
If (havegamepadbuttons ){
Uint32_t assumedclasses = device-> classes | input_device_class_joystick;
For (INT I = 0; I <= abs_max; I ++ ){
If (test_bit (I, device-> absbitmask)
& (Getabsaxisusage (I, assumedclasses) & input_device_class_joystick )){
Device-> classes = assumedclasses;
Break;
}
}
}
Generally, the key button follows the keyboardinputmapper process. This joystickinputmapper is used only for Axis () of ev_abs.
Note:
1. Obtain some additional parameters of the handle:
IOCTL (FD, jsiocgaxes, & number_of_axes); // Number of game axes. The default value is 0, 1, and 2, indicating the X axis, Y axis, and Z axis.
IOCTL (FD, jsiocgbuttons, & number_of_btns); // Number of game buttons
IOCTL (FD, jsiocgname (sizeof (js_name_str), js_name_str); // game handle name
2. Numeric value:
Axis value range:-32767 ~ 32767
For example:
int *axis = NULL;int *button = NULL;struct js_event jse;axis = (int*)calloc(number_of_axes,sizeof(int));button = (int*)calloc(number_of_btns,sizeof(int);read(fd,&jse,sizeof(struct js_event));switch(jse.type & ~JS_EVENT_INIT){case JS_EVENT_AXIS:if ((jse->number & 1) == 0) {axes[jse.number / 2].x = jse.value;}else {axes[jse.number / 2].y = jse.value;}break;case JS_EVENT_BUTTON:if (jse->value) {buttons_state |= (1 << jse->number);}else {buttons_state &= ~(1 << jse->number);}break;default:break;}
3. Read eventx -- value generated by the joystick device:
Ev_abs + code + axis
The analysis is as follows:
First, it indicates the absolute value of type = ev_abs. The code value represents the X axis (0), the Y axis (1), the Z axis value (2), and the value represents the coordinate value, here the corresponding value conversion problem will be involved, taking the amotion_event_action_move route.
The core code is as follows:
switch (rawEvent->type) { case EV_ABS: { ssize_t index = mAxes.indexOfKey(rawEvent->scanCode); if (index >= 0) { Axis& axis = mAxes.editValueAt(index); float newValue, highNewValue; switch (axis.axisInfo.mode) { case AxisInfo::MODE_INVERT: newValue = (axis.rawAxisInfo.maxValue - rawEvent->value) * axis.scale + axis.offset; highNewValue = 0.0f; break; case AxisInfo::MODE_SPLIT: if (rawEvent->value < axis.axisInfo.splitValue) { newValue = (axis.axisInfo.splitValue - rawEvent->value) * axis.scale + axis.offset; highNewValue = 0.0f; } else if (rawEvent->value > axis.axisInfo.splitValue) { newValue = 0.0f; highNewValue = (rawEvent->value - axis.axisInfo.splitValue) * axis.highScale + axis.highOffset; } else { newValue = 0.0f; highNewValue = 0.0f; } break; default: newValue = rawEvent->value * axis.scale + axis.offset; highNewValue = 0.0f; break; } axis.newValue = newValue; axis.highNewValue = highNewValue; } break; } case EV_SYN: switch (rawEvent->scanCode) { case SYN_REPORT: sync(rawEvent->when, false /*force*/); break; } break; }}