Monday, January 4, 2010

Section 22.5. Parallel Ports










22.5. Parallel Ports


Parallel ports are most common on PCs. Many Sun workstations from the Sparc V on also have them. However, Macs do not have them nor do many non-x86 workstations. Parallel ports are sometimes called printer ports because their original purpose was to support printers. The names of the parallel
ports
"LPT1," "LPT2," etc.stand for "line printer," reflecting this usage. Nowadays, parallel ports are also used for Zip drives, tape drives, and various other devices. However, parallel ports are still largely limited by their original goal of providing a simple connector for printers. A parallel port sends data eight bits at a time on eight wires. These bits are sent at the same time in parallel, hence the name. The original parallel ports only allowed data to flow one way, from the PC to the printer. The printer could only respond by sending a few standard messages on other wires. Each return wire corresponded to a particular message, like "Out of paper" or "Printer busy." Modern parallel ports allow full, bidirectional communication.


The ParallelPort
class is a concrete subclass of CommPort that provides various methods and constants useful for working with parallel ports and devices. The main purposes of the class are to allow the programmer to inspect, adjust, and monitor changes in the settings of the parallel port. Simple input and output are accomplished with the methods of the superclass, CommPort. ParallelPort has a single public constructor, but that shouldn't be used by applications. Instead, you should simply call the open( ) method of a CommPortIdentifier that maps to the port you want to communicate with and then cast it to ParallelPort:



CommPortIdentifier cpi = CommPortIdentifier.getPortIdentifier("LPT2");
if (cpi.getType( ) == CommPortIdentifier.PORT_PARALLEL) {
try {
ParallelPort printer = (ParallelPort) cpi.open ( );
}
catch (PortInUseException ex) {
System.err.println(ex);
}
}



Methods in the ParallelPort class fall into roughly four categories:


  • Methods that adjust the port mode

  • Methods to control the port

  • Methods to inspect the state of the port

  • Methods that listen for changes in the state of the port



22.5.1. Parallel Port Modes




Like most other computer hardware, parallel ports have evolved over the last two decades. Modern parallel ports support bidirectional communication and other features never envisioned for the original parallel port that was only supposed to send data to a daisy-wheel printer. However, older peripherals may not work with newer parallel ports, so they can, if necessary, be downgraded to any of several various compatibility modes.

All of these are available as named int constants in the ParallelPort class:



ParallelPort.LPT_MODE_ANY // Use the most advanced mode possible.
ParallelPort.LPT_MODE_SPP // Original lineprinter mode. Unidirectional
// transfer from PC to printer. Most compatible
// with older peripherals.
ParallelPort.LPT_MODE_PS2 // Byte at a time, bidirectional mode as
// introduced in the IBM PS/2 family.
ParallelPort.LPT_MODE_EPP // Extended parallel port.
ParallelPort.LPT_MODE_ECP // Enhanced capabilities port.
ParallelPort.LPT_MODE_NIBBLE // Nibble (4 bits, half a byte) at a time mode,
// bidirectional, used by some Hewlett Packard
// equipment.



The mode the parallel port uses is returned by the getMode( ) method and set by passing the appropriate constant to the setMode( ) method:



public abstract int getMode( )
public abstract int setMode(int mode) throws UnsupportedCommOperationException



Attempts to set the port to an unsupported mode throw an Unsupported-CommOperationException.




22.5.2. Controlling the Parallel Port





Data is sent to the parallel port and its attached device using the output stream returned by the CommPort class's getOutputStream( ) method. You can interrupt this data by sending the appropriate signals out the parallel port to the printer. The suspend( ) and restart( ) methods send these signals:



public abstract void restart( )
public abstract void suspend( )



These methods are generally interpreted as stopping and restarting printing. You normally suspend and restart printing if the printer reports an error. These methods do not automatically start a print job over from the beginning. You are still responsible for sending the printer whatever data it needs to print from whatever point it was printing or from the point where you want to restart printing.




22.5.3. Checking the State of the Port


The original parallel port allowed printers to send only a few predefined messages. Each message was sent by raising the voltage on a specific wire connecting the port to the printer. These messages are always sent from the printer to the CPU, never in the other direction. Therefore, Java only allows you to check the state

of each of these pins, not to set them. The methods are:



public abstract boolean isPaperOut( )
public abstract boolean isPrinterBusy( )
public abstract boolean isPrinterSelected( )
public abstract boolean isPrinterTimedOut( )
public abstract boolean isPrinterError( )



Each of these methods returns true if the matching wire is showing voltage relative to ground or false if it isn't.


There is also a getOutputBufferFree( ) method that returns the number of bytes currently available in the parallel port's output bufferin other words, the number of bytes you can write before the buffer fills up:



public abstract int getOutputBufferFree( )





22.5.4. Parallel Port Events




Although you can check the various pins used to send information from a printer to the computer whenever you want to, it's more convenient to do it asynchronously. The model used for notification is the same one used for JavaBeans, the AWT, and serial port events:

when the runtime detects a change in state at a monitored parallel port, it fires a parallel port event to the registered parallel port listener. A parallel port event signals some sort of activity on the parallel port, either an error or an empty output buffer.



22.5.4.1. Parallel Port Event Listeners

There are three steps to respond to parallel port events:


  1. Implement the ParallelPortEventListener interface.

  2. Register your ParallelPortEventListener object with the ParallelPort object representing the parallel port you want to monitor.

  3. Tell the parallel port the types of events you want to be notified of.


This is the same pattern as a SerialPortEventListener.




Step 1


As you would probably guess, you listen for parallel port events with a ParallelPortEventListener:



public interface ParallelPortEventListener extends EventListener



This interface declares a single method, parallelEvent( ):



public abstract void parallelEvent(ParallelPortEvent ppe)



Inside this method, you generally use the getEventType( ) method of Parallel-PortEvent to determine exactly what caused the parallel port event:



public int getEventType( )



This should return ParallelPortEvent.PAR_EV_BUFFER to signal an empty output buffer or ParallelPortEvent.PAR_EV_ERROR to signal some other sort of error.





Step 2


Once you've constructed a ParallelPortEventListener, you need to pass it to the ParallelPort object's addEventListener( ) method:



public abstract void addEventListener(ParallelPortEventListener listener)
throws TooManyListenersException



You are limited to one event listener per port. Attempting to add a second event listener throws a java.util.TooManyListenersException.


Should you need to, you can remove a listener from the port with the ParallelPort object's removeEventListener( ) method:



public abstract void removeEventListener( )



This method takes no arguments because there's never more than one event listener registered directly with the port.





Step 3


In many circumstances, you may not be interested in both of these events. By default, neither of these events is fired unless you first enable them with the right notify method in ParallelPort:



public abstract void notifyOnError(boolean notify)
public abstract void notifyOnBuffer(boolean notify)



By default, no events are fired when the parallel port's state changes. However, if you pass true to either of these methods, it fires a parallel port event when the matching state changes.





22.5.4.2. ParallelPortEvent



Parallel port events are represented by instances of the ParallelPortEvent class, a subclass of java.util.EventObject:



public class ParallelPortEvent extends EventObject



The getEventType( ) method returns a named constant from the ParallelPortEvent class that specifies what caused the event to be fired. There are two possibilities: an error and an empty output buffer. Each parallel port event has an eventType field; its value should be one of these mnemonic constants:



ParallelPortEvent.PAR_EV_ERROR // An error occurred on the port.
ParallelPortEvent.PAR_EV_BUFFER // The output buffer is empty.



These represent a change from one state to another, from on to off or off to on. Therefore, there are also getNewValue( ) and getOldValue( ) methods to tell you the state of the pin before and after the event:



public boolean getNewValue( )
public boolean getOldValue( )















No comments: