This is a driver for the PIUIO arcade I/O board that maps panels and buttons to a standard Linux event interface which typically appears as a joystick.
To compile the kernel module, run make
inside the mod
directory. This will
build a kernel object file piuio.ko
which is compatible with your currently
installed kernel. To build against different kernel headers, you may specify
the path to a source tree using the KDIR
variable when building, e.g.:
make KDIR=~/src/linux-3.15.7
To install this module once you have built it, use the make install
command.
By default this will attempt to install the module directly to your system;
note that doing so will require root privileges. To specify a path under
which to install (e.g. for packaging), you can specify a DESTDIR
:
make DESTDIR="$pkgdir" install
Note: during this step, you may see the following error:
At main.c:160:
- SSL error:02001002:system library:fopen:No such file or directory: crypto/bio/bss_file.c:72
- SSL error:2006D080:BIO routines:BIO_new_file:no such file: crypto/bio/bss_file.c:79
sign-file: certs/signing_key.pem: No such file or directory
Unless you are trying to build a cryptographically signed module, you may safely ignore these messages.
Since this module uses the input subsystem, you can use standard tools such as
evemu to test it. Outputs are
implemented using the leds subsystem and are consequently located in the
/sys/class/leds
directory. You can test these by echoing zero/nonzero values
to the brightness
file in a given led directory:
echo 1 > /sys/class/leds/piuio::output3/brightness
This driver is designed to provide the fastest possible response to inputs, and thereby the best possible timing accuracy. Below are some of the considerations made in reducing the time from triggering an input sensor to generating the input event.
The Linux kernel provides the input_polldev
framework for input devices
such as the PIUIO which must be polled rather than generating interrupts.
This framework allows the driver to define a poll
function which is
called at regular intervals to generate input events.
Unfortunately, this framework is designed for general input devices, such as keyboards, where accurate event timing is not critical. As a result the mechanics behind its implementation can lead to extra time between polls. This driver implements polling itself to avoid the extra delay (which is compounded by the use of a multiplexer as described below).
PIUIO units are typically attached to a four-way multiplexer so that four sensors can be connected to each input. If any one sensor is triggered, the input is considered to be pressed. The current implementation assumes that such a multiplexer is in use. At a low level, the driver must send a USB output message to select one set of sensors from the multiplexer, then an input message to read their values.
However, the USB standard requires that each message consist of a request from the host and a response from the device, and only one of those may carry data. Because of this, the output message to set up the multiplexer and the input message to request the sensor state cannot be combined in one round-trip from host to device and back; two round-trips are necessary.
To get the best possible timing accuracy, these internal mechanics have to be taken into account.
The first accuracy improvement that this driver makes is taking a different approach with respect to when input events are reported. Previous drivers, as well as previous versions of this driver, have used a "block" strategy when polling multiple sets of sensors. With this approach, each set is polled once, the results are combined, and then any changes in the input are reported as press or release events.
Remember that polling one set of sensors requires two USB messages. This means that, in a typical setup with four sensor sets, eight round-trips take place between consecutive polls of the same sensor. So the delay between a change in the state of any given sensor and the corresponding input event will range from 0 to 8 RTTs, with an average of 4.
This driver instead staggers the input reporting. After each set of sensors is polled, input events are generated, using the most recent polled values from the other sets.
At first, this does not seem to change anything, since there are still eight round-trips between consecutive polls of a single sensor. However, consider the case in which more than one related sensor is triggered at the same time (for example, if there are multiple sensors under a single panel). The time from trigger to input event will be that of the sensor which will be polled next, i.e. the one with the least delay.
With the block strategy, the average delay is always 4 RTTs, even if multiple sensors are triggered. With the staggered strategy, hitting one sensor will average 4 RTTs, two sensors 2.33 RTTs, three sensors 1.5 RTTs, and hitting all four related sensors will bring the average delay to 1 RTT.
Given that the typical round-trip response time for a PIUIO device is 250 μs, this means this is the first PIUIO driver capable of sub-millisecond accuracy on average.
However, there is something else that can be done to reduce delay and improve accuracy. USB messages can be queued asynchronously so that they are sent as quickly as possible, one after the other. There is no need to wait for an output message to complete before sending the following input message, and vice versa. This means that one response can be processed while the next request is already being sent, using the USB link much more efficiently. In testing, the asynchronous driver was able to handle requests 35–40% faster than synchronous drivers.