Parallel port: Difference between revisions

[unchecked revision][unchecked revision]
Content deleted Content added
added header to section. added stub tag.
m Bot: Replace deprecated source tag with syntaxhighlight
 
(11 intermediate revisions by 7 users not shown)
Line 1:
{{NoteBox|<b>NOTE:</b> Before doing anything, make sure to set the parallel ports mode to Standard or Normal in the BIOS instead of ECP/EPP if anything fails from your programming efforts, preferably before exhausting your options}}
 
 
The parallel port uses a sub-d 25 connector to provide a 8-bit data bus. It is commonly used by printers. There are 3 kinds of parallel ports: Standard Parallel Port (SPP), Enhanced Parallel Port (EPP) and Extended Capabilities Parallel Port (ECP). iirc they are all part of IEEE Standard 1284, or is it just the second two?
==Pin types==
Line 9 ⟶ 12:
* LPT3: 0x3BC (IRQ 5)
 
The [[Memory Map (x86)#BIOS_Data_Area_.28BDA.29|BIOS Data Area]] should contain the IO base addresses of any existing parallel ports
==Using the Parallel Port==
 
==Parallel Port Software Interface==
{{Stub}}
 
Each parallel port has three IO port registers, Data, Status and Control. Their addresses are relative to the base address of the parallel port in question.
 
===Data Register===
Address = Base Address + 0
Line 16 ⟶ 24:
Any byte writen to this register is put on pins 2 through 9 of the port.
Any read from this register reflects the state of the port.
 
===Status Register===
Address = Base Address + 1
 
<table border style="width: 100%">
<tr><td>Bit 0</td><td>Bit 1</td><td>Bit 2</td><td>Bit 3</td><td>Bit 4</td><td>Bit 5</td><td>Bit 6</td><td>Bit 7</td></tr>
<tr><td>Reserved</td><td>Reserved</td><td>IRQ</td><td>ERROR</td><td>SELECT_IN</td><td>PAPER_OUT</td><td>ACK</td><td>BUSY</td></tr>
</table>
 
The ERROR, ACK and BUSY signals are active low when reading from the IO port.
 
===Control Register===
Address = Base Address + 2
 
<table border style="width: 100%">
<tr><td>Bit 0</td><td>Bit 1</td><td>Bit 2</td><td>Bit 3</td><td>Bit 4</td><td>Bit 5</td><td>Bit 6</td><td>Bit 7</td></tr>
<tr><td>STROBE</td><td>AUTO_LF</td><td>INITIALISE</td><td>SELECT</td><td>IRQACK</td><td>BIDI</td><td>Unused</td><td>Unused</td></tr>
</table>
 
The INITIALISE signal is active low when writing to the IO port.
 
The STROBE signal is for handshaking and alerts the printer to data being ready at the data port.
 
AUTO_LF is the Automatic Line-Feed signal. If this is set and the printer receives a Carriage-Return character (0x0D), the printer will automatically perform a Line-Feed (character 0x0A) as well.
 
INITIALISE, sometimes called PRIME, alerts the device that data that a data conversation is about to start. This signal may result in a printer performing a reset and any buffers being flushed.
 
 
==Standard Parallel Port Mode==
 
This is the most basic of the parallel modes. The other modes are EPP and ECP. All systems should support this mode and it may well be the default at boot time. Some BIOSes also support setting the default mode of the parallel port. In this mode, the Data register and the Control register are Write-Only and the Status register is Read-Only.
 
In Standard (or Compatibility) mode, data is sent using a mechanism called Centronics Handshaking, described below.
 
This mode requires communuication handshaking to be performed by software which limits the maximum data throughput of the port. This means that a standard mode has a maximum transfer rate of around 1000 bytes per second, depending on the timings of the computer and receiving device. The more advanced types (or modes) of parallel ports, EPP and ECP, reduce this by providing hardware-based handshaking. Relieving software of this requirement reduces CPU load and increases the port's maximum potential speed.
 
For a line printer, this method should be enough to get things going, simply sending characters using this method to the parallel port while the printer is online should get the print head moving, assuming no buffers are in the way to store the values.
 
Depending on the connected device, you may have to raise the INITIALISE signal before data transmission to ready the device, and possibly again after in order to flush any buffers.
 
===Centronics Handshaking===
 
In Standard (or Compatibility) mode, data is sent to the connected device by writing the byte to the data port, then pulsing the STROBE signal. This pulse informs the device that data is ready to be read. The device will respond by raising its BUSY signal and then reading the data and performing some processing on it. Once this processing is complete, the device will lower the Busy signal and may raise a brief ACK signal to indicate that it has finished.
 
<syntaxhighlight lang="c">
// Sends a byte to the printer
void Parallel_SendByte( unsigned char pData )
{
unsigned char lControl;
// Wait for the printer to be receptive
while ( ! inb( 0x379 ) & 0x80 )
{
Timer_Delay( 10 );
}
// Now put the data onto the data lines
outb( 0x378, pData );
// Now pulse the strobe line to tell the printer to read the data
lControl = Ports_In8( 0x37A);
outb( 0x37A, lControl | 1 );
Timer_Delay( 10 );
outb( 0x37A, lControl );
// Now wait for the printer to finish processing
while ( ! inb( 0x379 ) & 0x80 )
{
Timer_Delay( 10 );
}
}
</syntaxhighlight>
 
<tt>Timer_Delay()</tt> pauses processing for the specified number of milliseconds. <tt>inb()</tt> and <tt>outb()</tt> read and write a byte of data to/from the IO port. You can find the IO functions in the [[Inline_Assembly/Examples#OUTx|Inline Assembly Examples page]].
 
 
 
[http://devel.archefire.org/TextRecordings/lpthandler.tar <b><code>lpthandler.tar:</code></b> Code and binary for "LPT Handler for Windows"]
 
[http://www.youtube.com/watch?v=sJRbGohmA3M <b>YouTube video:</b> Basics of Parallel Port Programming Under Windows, Part 1 of 2]
 
[http://www.youtube.com/watch?v=zAxeCLuWZCk <b>YouTube video:</b> Basics of Parallel Port Programming Under Windows, Part 2 of 2]
 
[[File:Win32_lpthandler_exe_0000.jpg]]
 
<syntaxhighlight lang="c">
/*
In short we only need:
 
outl(LPT_Base_Address+2, 0); //Reset Control port with 0
outl(LPT_Base_Address, 0xFF-0x00); //Write Data Port with any byte value
*/
 
 
 
//Here the LPT_Base_Address can be:
//
// 0x3BC -- LPT1
// 0x378 -- LPT1
// 0x278 -- LPT2
// 0x3BC -- LPT3
///
 
//We need to reset the Control Port writing a 0
//to configure their options, controlled for each of
//their bits:
///
outl(LPT_Base_Address+2, 0);
 
//Now send an value betwewen 0 and 255 to the data port:
///
outl(LPT_Base_Address, 0xFF-0x00);
 
</syntaxhighlight>
 
== See Also ==
=== Threads ===
* [[Topic:30279|Easy Parallel Port Programming Tests (Under Windows)]]
 
 
 
[[Category:Common Devices]]
[[Category:Hardware Interfaces]]