Parallel port control in Linux
The program also has support for the serial rs232 port. Although the IO is different from that of the parallel port, the serial connector rs232 can prove useful in many situations since it offers a serious amount of power (a voltage of +-12V or in some cases +-5V and short circuit current flow of 7-10mA) depending on the circuit types used in the PC circuitry. This is all at the cost of signal lines. The parallel port has eight data pins as we have seen above whereas the serial port has only three: TD(Transmit Data), DTS(Data Terminal Ready), RTS(Request to Send). However, only the last two are usable since TD is logic true(-12V) when no data is sent:
Based on the equivalence of both parallel port versions, pport accepts both standards transparently, either 9 pin or 25 pin serial rs232 connector.
Options
- -p, –port <serial>
- With this option one can select an alternative port.
- -s, –set <pin1,pin2…|all|none|even|odd|random|dtr,rts>
- Causes pport to set one, some, or all pins to high. Or to set all low with “none”. dtr and rts are available only in combination with the serial port. One can also use all and none with the serial port option in order to set both RTS and DTR lines to high respectively low.
- -t, –toggle <pin1,pin2…|all|even|odd|random>
- Causes pport to toggle the state of the specified pins.
- -w, –wait <Nd|Nh|Nm|Ns>
- Where n is a number, causes pport to wait a specific time before altering the state of the specified pins, where n is a number, and d stands for days, h for hours, m for minutes and s for seconds.
- -r, –restore
- Causes pport to restore the previous state of the pins stored in the data file.
- –status
- Makes pport give a status report on the parallel port.
- –debug
- Will turn on debugging for the following command.
- –raw
- Will send raw data through the parallel port.
Examples
Here are a few examples for using this program:
- pport -s all -w 10m
- Will set all the pins to high after a 10 minutes delay.
- pport -s random -w 5s
- Will set some random pins to high after a 5 seconds delay.
- pport -r
- Will restore the previous pin states. This can be useful if you want to include pport in your startup scripts so it can restore your device status on system startup.
- pport -t 2,4,7 -w 10s
- Will toggle pins 2, 4 and 7 into their complementary state after 10 seconds.
- pport -p serial -s rts
- Will set the rts line of the rs232 port to the high state.
- pport -p serial -s rts,dtr
- Will set both lines of the rs232 port to the high state.
- pport -p serial -s none
- Will set both lines of the rs232 port to the low state.
- pport –raw “Hello world”
- Will send data through the parallel port.
Notes
1. The pport utility, must be able to access the ports in the first place. Failure to do so will result in an error. Thus pport must have superuser priviledges at runtime.
Parallel Port Accessing using C Code
Below are listed two options for controlling the parallel port under Linux. The first option writes directly to the parallel port memory address. It’s simple and works well, but because of the low level access, you’ll need to have root privileges. The second option, uses the ppdev
module for user-space access, that means you don’t need root privileges.
Compile either source file using the following command line.
1 |
> gcc cableTest.c -o cableTest |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 |
#include <stdio.h> #include <inttypes.h> #include <sys/io.h> #include <signal.h> #define BASE 0x378 int running = 1; void signalHandler(int sig) { running = 0; } int main(void) { printf("Parallel Port Interface Test (Base: 0x%x)n", BASE); signal(SIGINT, signalHandler); // Set permission bits of 4 ports starting from BASE int result = ioperm(BASE, 4, 1); // If setting permission failed, return if (result != 0) { printf("ERROR: Could not set permissions on ports"); return result; } // This loop will keep running until ctrl-c is pressed while (running) { outb(0xFF, BASE); outb(0x00, BASE); } // Clear permission bits of 4 ports starting from BASE result = ioperm(BASE, 4, 0); if (result != 0) { printf("ERROR: Could not clear permissions on ports"); return result; } return 0; } |
User-Mode Access
The code below is the user-mode version. It accesses the parallel port via the ppdev
driver. You’ll need to make sure that the driver is compiled into your kernel, or compiled as a module then loaded. The first command below can be used to check if the module is loaded, the second will load it.
1 2 |
> lsmod | grep ppdev > modprobe ppdev |
The ppdev
kernel driver can be found in the location shown below.
1 2 3 |
-> Device Drivers -> Character Devices -> <M> Support for user-space parallel port device drivers |
NOTE: Arguments to the ioctl function are passed by pointer, so be careful when using the functions. This is why mode
, dir
, dataH
and dataL
are defined first, then their addresses are passed to ioctl.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 |
#include <stdio.h> #include <sys/ioctl.h> #include <linux/parport.h> #include <linux/ppdev.h> #include <fcntl.h> #include <unistd.h> #include <stdlib.h> #include <signal.h> int running = 1; void signalHandler(int sig) { running = 0; } int main(void) { int fd; int result; printf("Parallel Port Interface Testn"); // Set ctrl-c handler signal(SIGINT, signalHandler); // Open the parallel port for reading and writing fd = open("/dev/parport0", O_RDWR); if (fd == -1) { perror("Could not open parallel port"); return 1; } // Try to claim port if (ioctl(fd, PPCLAIM, NULL)) { perror("Could not claim parallel port"); close(fd); return 1; } // Set the Mode int mode = IEEE1284_MODE_BYTE; if (ioctl(fd, PPSETMODE, &mode)) { perror("Could not set mode"); ioctl(fd, PPRELEASE); close(fd); return 1; } // Set data pins to output int dir = 0x00; if (ioctl(fd, PPDATADIR, &dir)) { perror("Could not set parallel port direction"); ioctl(fd, PPRELEASE); close(fd); return 1; } char dataH = 0xFF; char dataL = 0x00; // This loop will keep running until ctrl-c is pressed while(running) { // Output some data // Note that data is passed by a pointer ioctl(fd, PPWDATA, &dataH); ioctl(fd, PPWDATA, &dataL); } printf("Shutting downn"); // Release and close the parallel port ioctl(fd, PPRELEASE); close(fd); return 0; } |
Happy Hacking with parallel port!!