Standard Windows API interface

Standard Windows API interface

Standard Windows API for parallel port programming is targeted for sending out characters to printer onneced to parallel port. It is not designed for contrlling single pins on or off.

Using the parallel port for digital output can be made to work with the normal Windows API with a simple hardware hack. The main trick is to tie pins 11(Busy) and 12 (Paper Error) to ground. Otherwise, the hardware driver will think the printer it is talking to is busy or experiencing an error and will not output any data.

Just send one character to parallel port, and the Windows wii send the value of that character to printer port data pins, plus generate one pulse to strobe line. The port will maintain the last value written to it until another value is written or until the computer is powered down or new data is sent to port. If you output more than one byte at a time the driver will send them to the port in sequence and toggle the Strobe line (line 1) off and on for each byte. The timing involved varies somewhat from one computer to the next.

This means that in a Windows environment we can output data to the parallel port. You can send data even through Windows command line with copy command like this:

copy somefile.bin LPT1

This will send the contents of file somefile.bin to the parallel port. The value of the last byte in the file will be left as the state of the parallel port after the command execution.

Besides need for the hardware hack, there are other limitations on the Windows API method. Windows API does not have built in support for input operations nor reading back the last sent value. Even though the parallel port hardware supports it, the software driver does not.

Parallel port controlling in Linux

Linux will allow acess to any port using the ioperm syscall. Here is some code parts for Linux to write 255 to printer port:

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <asm/io.h>

#define base 0x378           /* printer port base address */
#define value 255            /* numeric value to send to printer port */

main(int argc, char **argv)
   if (ioperm(base,1,1))
    fprintf(stderr, "Couldn't get the port at %x\n", base), exit(1);

   outb(value, base);

Save the source code to file lpt_test.c and compile it with command:

gcc -O lpt_test.c -o lpt_test

The user has to have the previledges to have access to the ports for the program to run, so you have to be root to be able to ron this kind of programs without access problems. If you want to make a program which can be run by anybody then you have to first set the owner of the program to be root (for example do compilation when yhou are root), give the users rights to execute the program and then set the program to be always executed with owner (root) rights instead of the right of the user who runs it. You can set the programn to be run on owner rights by using following command:

chmod +s lpt_test

Notes on source code: Some people have reported that for some reason this code does not work on theuir systems. If you have problems in getting this to work, try tho following chagest to code: replace the lines “#include <unistd.h%gt;” and “#include <asm/io.h>” with line “#include <sys/io.h>” and then replace line “#define base 0x378” with “#define base 0x0378”.

If you want a more useful program, then download my lptout.c parallel port controlling program source code. That program works so that you can give the data to send to parallel port as the command line argument (both decimal and hexadecimal numbers supported) to that program and it will then output that value to parallel port. You can compile the source code to lptout command using the following line to do the compilation:

gcc -O lptout.c -o lptout

After you have compiled the program you can run it easily. For example running ./lptout 0xFF will turn all data pins to 1 and running ./lptout 0x00 will turn all data pins to 0.

In some systems the I/O port addresses can be different than one used in my example program. In this case you need to modify the address in #define base line. There are different ways to know the port address. First you could try your graphical configuration tools to look for this information. Those tools and how to use them vary quite much between different Linux distributions. There are also some command line tools you can try:

  • In many linux systems you can get information on I/O devices and ports they use with command “cat /proc/ioports”. This list should include your parallel port or parallel ports in it. The first parallel port (port in motherboard) typically has name parport0. There are some cases where you might not see your device in your list or sometimes you see the sama name twice (usually the first one is the right one).
  • In some systems you might have additional parallel ports on I/O cards in the PCI bus. In many new Linux systems you can run “lspci -v | more” to get information of each device on your PCI bus (this should tell make and model, interrupt and port and memory block assignments).

I have also written a more feature rich program to control. portconrol is a simple general purpose I/O port control program for Linux. It allows you to write and read the supported I/O ports. The software allows writing specified value to port, reading value at given I/O address and printing it out to screen in different formats and bit-level manipulation of the port data. The portcontrol software is available asportcontrol.tar package that includes the source code, instructions for compiling/installing and instructions for use. For more details check theREADME and the portcontrol.c source code.

Programming I/O



Fill in your details below or click an icon to log in: Logo

You are commenting using your account. Log Out /  เปลี่ยนแปลง )

Google+ photo

You are commenting using your Google+ account. Log Out /  เปลี่ยนแปลง )

Twitter picture

You are commenting using your Twitter account. Log Out /  เปลี่ยนแปลง )

Facebook photo

You are commenting using your Facebook account. Log Out /  เปลี่ยนแปลง )


Connecting to %s

%d bloggers like this: