parint - A linux device driver for the PC's parallel for using the parport interface.


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.

Making the driver & test code

To compile the driver modules:
   # make

To compile testpi and supporting library:
   > make -f

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
fifo-notes.html - notes on how the driver implements the FIFO.


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....

   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)

   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

   version 12.05
   Tested using centos 6.x. (32bits)
   Added more iocntl calls to control the data out lines (DO to D7)

   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.

   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.