parint - A linux device driver for the PC's parallel for using the parport interface.
Description
parint is a linux kernel module that uses the PC's parallel port to timestamp a
TTL signal via an interrupt. The driver's Interrupt Service Routine records
the time an ACK signal occured. I wrote this driver in order to timestamp
a shutter TTL output from a camera we have.
There are also function to control the data line D0-D7. We also used parint
when we need to control few TTL digital out line from the PC.
Documentation is mininal. The driver is very simple, and the testpi user
program illustrates the driver's function. Using very basic
device driver knowledge, you should be able to take this code and use it.
There are many tutorials on writing linux device driver
using the PC's parallel port ... many use outb_p/inb_p(), which don't
work for new kernel. The parport interface needs to be used.
I am posting this to share with everyone. Do with it as you like.
If you did find this usefully, drop me a email letting me know.
Written by Tony Denault.
anthonydenaultgmailcom
Making the driver & test code
To compile the driver modules:
# make
To compile testpi and supporting library:
> make -f makefile.app
Or better, the 'm' script does both:
> m
How to load the module
Note, you may need to unload the lp modules so parint can get to the parallel port:
# rmmod lp
1. To make a /dev entry for parint (centos 5.x/6.x):
# mknod --mode=666 /dev/parint c 67 0
Make a udev entry for CentOS 4.x:
# mknod --mode=666 /etc/udev/devices/parint c 67 0
2. manual loading:
# insmod parint.ko
if you get an error: insmod: ERROR: could not insert module parint.ko: Unknown symbol in module
you may need to load the parport module first:
# modporbe parport
3. manual unloading:
# rmmod parint
manual installation
This driver is could use some improvement in how it handles mknod, udev, and install.
But here is what I do:
1. copy parint.ko to /lib/modules//kernel/drivers
cp parint.ko /lib/modules/`uname -r`/kernel/drivers/char
2. Add to /etc/rc.d/rc.local:
rmmod lp
mknod --mode=666 /dev/parint c 67 0
insmod /lib/modules/`uname -r`/kernel/drivers/char/parint.ko
parint module source code
Makefile - Module makefile
parint.c - parint.c
parint.h - parint.h
Also
fifo-notes.html - notes on how the driver implements the FIFO.
testpi
testpi is a user program used to test the driver. testpi demonstrates
how to use the parint driver function calls. Here is the user code:
makefile.apps - makefile.apps
parint_nice.c - nice wrapper for parint ioctl calls.
testpi.c - testpi.c - user application to test parint
m - command to make the module and testpi.
For testing, I connected pin 10(ACK) to pin 3 (D1). Then ran 2 copies of
testpi. testpi #1 used to "get.time", and the other generated pulses ("pulse").
Here is a picture of the pinouts:
How well does the interrupt response work?
Tested response with centos5/AMD Sempron(tm) Processor 3300+.
Worst cast sample was 300 microseconds, while most in the 5-15 micorseconds range.
Seem details here: test1/index.html
In 2012, I tested response with CentOS 6/i3-2120 CPU.
Did a single test, 100000 pulse at 0.005 seconds. Worst ase was 90usec, all other under 50
Seem details here: test2/index.html
In 2017, I tested response with CentOS 7/i5-3570K CPU
Did a single test, 200000 pulse at 0.0025 seconds. Worst case was 300usec.
Seem details here: test3/index.html
In general I say, "Parint responds faster good ~500 microseconds 99.999% of the time."
Changelog and old versions....
current
Tested with CentOS 7/x64 (3.10.0-514.2.2.el7.x86_64)
and CentOS 7/x64 (2.6.32-642.15.1.el6.x86_64)
save/170331
version 13.04
Bug fix on calcuating number of element in fifo.
added to readme notes on how fifo buffer works.
Test under 64bit version centos 6.4
save/130411
version 12.05
Tested using centos 6.x. (32bits)
Added more iocntl calls to control the data out lines (DO to D7)
save/120425
version 11.05
Developed and tested using CentOS 5.x. Did a save before testing on centos 6.x.
Replace the inb()/outb() with parport functions.
save/101020
version 10.09
Developed and tested using CentOS 4.6 ( kernel 2.6.9-78.0.17.EL )
This version uses inb()/outb() to talks to 0x378, the hardware register
of the parallel port directly. Working in 2.6.9, but broken in 2.6.18.
Seems like we are unable to access the parallel IO addresses in the
later kernels.