Standard Parallel Port Control Using ppdevUsing inb and outb isn't the only way to query and control the PC parallel port's data, control, and status registers. The Linux parallel port device driver, ppdev, also allows for this control, by using ioctl.2 This approach is similar to the approach used in Chapter 6, "Asynchronous Serial Communication Interfacing," to control the serial port. A file (/dev/parport0) is opened, and a file descriptor is returned. With this descriptor, calls to ioctl can set individual control bits, query the port status, and read and write to the port's data bus. The program in Listing 7.3, snowmakingcontrolppdev.c, uses ppdev to control the parallel port registers that control the interface circuit in Figure 7.3. ("The Linux 2.4 Parallel Port Subsystem"2 provides a complete discussion of parport and ppdev.) The following are the steps that the snowmakingcontrolppdev program takes:
Listing 7.3 The snowmakingcontrolppdev.c Program/* * snowmakingcontrolppdev v0.1 9/25/01 * www.embeddedlinuxinterfacing.com * * The original location of this code is * http://www.embeddedlinuxinterfacing.com/chapters/07/ * snowmakingcontrolppdev.c * * Copyright (C) 2001 by Craig Hollabaugh * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU Library General Public License as * published by the Free Software Foundation; either version 2 of the * License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Library General Public License for more details. * * You should have received a copy of the GNU Library General Public * License along with this program; if not, write to the * Free Software Foundation, Inc., * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ /* snowmakingcontrolppdev * snowmakingcontrolppdev uses /dev/parport0 to control an interface * circuit connected the PC parallel printer port. The port's * control port drives the interface circuit's output latch signals. */ /* * For more information, see The Linux 2.4 Parallel Port Subsystem, T. Waugh * http://people.redhat.com/twaugh/parport/html/parportguide.html */ /* gcc -O2 -o snowmakingcontrolppdev snowmakingcontrolppdev.c */ #include <stdio.h> #include <unistd.h> #include <asm/io.h> #include <linux/ioctl.h> #include <linux/parport.h> #include <linux/ppdev.h> #include <fcntl.h> #define SPPDATAPORT 0x378 #define SPPSTATUSPORT (SPPDATAPORT + 1) #define SPPCONTROLPORT (SPPDATAPORT + 2) #define OUTPUTENABLE 0x02 #define OUTPUTLATCH 0x04 struct ppdev_frob_struct frob; int main(int argc, char *argv[]) { int fd, mode; unsigned char status, data; /* 1. get the file descriptor for the parallel port */ fd = open("/dev/parport0",O_RDWR); if (fd == -1) { perror("open"); exit(1); } /* 2. request access to the port */ if (ioctl(fd,PPCLAIM)) { perror("PPCLAIM"); close(fd); exit(1); } /* 3. configure the port for SPP mode */ mode = IEEE1284_MODE_COMPAT; if (ioctl(fd, PPNEGOT, &mode)) { perror ("PPNEGOT"); close (fd); return 1; } /* 4. assert the latch's OUTPUTENABLE signal */ frob.mask = OUTPUTENABLE ; frob.val = OUTPUTENABLE; ioctl(fd, PPFCONTROL, &frob); /* 5. put the command line argument 1 on the data bus */ ioctl(fd,PPWDATA,argv[1][0]); /* 6. toggle the OUTPUTLATCH signal to latch data */ frob.mask = OUTPUTENABLE | OUTPUTLATCH ; frob.val = OUTPUTENABLE | OUTPUTLATCH; ioctl(fd, PPFCONTROL, &frob); frob.mask = OUTPUTENABLE ; frob.val = OUTPUTENABLE; ioctl(fd, PPFCONTROL, &frob); /* 7. release the port */ ioctl (fd, PPRELEASE); /* 8. close the device file */ close(fd); } As mentioned previously, using ppdev doesn't solve the two port I/O drawbacks (OUTPUT_ENABLE and latch output value retention). Then why discuss ppdev? Using ppdev gives you another approach to control the parallel port. snowmakingcontrol.c uses inb and outb system calls that require ioperm calls. Use of ioperm requires root operation. SPP control using ppdev doesn't require root operation. Access to the parallel port device driver, /dev/parport0, can be controlled through file permissions. Non-root users can access the parallel port by using ppdev. |
Top |