#include <EppRulbusInterface.h>
Inherits TheRulbusInterface.
Public Member Functions | |
Construction | |
EppRulbusInterface (Quad base=DEF_EPP_BASE, bool docheck=true) | |
(default) constructor - setup EPP Rulbus Interface, check if present. | |
Accessors | |
Quad | base () const |
the interface's base address. | |
bool | invariant () const |
check class invariant. | |
Printer | |
bool | printOn (std::ostream &stream) const |
report configuration. | |
Static Public Attributes | |
const Quad | DEF_EPP_BASE = 0x0378 |
default EPP Rulbus Interface base address. | |
Protected Member Functions | |
Construction | |
EppRulbusInterface (EppRulbusInterfaceRef) | |
prevent copying. | |
EppRulbusInterfaceRef | operator= (EppRulbusInterfaceRef) |
prevent copying. | |
Provider interface | |
int | putReg (int offset, int byte) const |
write a byte to the Rulbus. | |
int | getReg (int offset) const |
read a byte from the Rulbus. | |
Accessors | |
bool | interfacePresent (int *pCode) const |
check if EPP Rulbus Interface is present. | |
int | readAddress () const |
read current EPP address from the EPP. | |
int | readData () const |
read a databyte from the EPP. | |
bool | EppTimedOut () const |
get EPP timeout status. | |
Mutators | |
void | writeAddress (int addr) const |
write an address to the EPP. | |
void | writeData (int byte) const |
write a databyte to the EPP. | |
void | resetInterface () const |
reset EPP Rulbus Interface by asserting nReset control bit; allow for reset signal to pass through RC filter. | |
void | initializeEpp () const |
initialize EPP port control lines. | |
bool | clearEppTimeout () const |
clear EPP timeout state, return true if timeout persists. | |
Private Attributes | |
Quad | theBase |
parallel printer port base address | |
Static Private Attributes | |
CharCptr | msgtitle = "Initialize EPP Rulbus Interface" |
title for error message boxes concerning initialization errors. | |
SPP register offsets | |
const int | OFF_SPP_DATA = 0 |
SPP data register. | |
const int | OFF_SPP_STAT = 1 |
SPP status register. | |
const int | OFF_SPP_CTRL = 2 |
SPP control register. | |
const int | OFF_EPP_ADDR = 3 |
EPP address register. | |
const int | OFF_EPP_DATA = 4 |
EPP data register. | |
SPP status bits | |
const int | MSK_EPP_Timeout = 0x01 |
EPP extension to SPP (was Reserved1)! | |
const int | MSK_SPP_Reserved2 = 0x02 |
SPP reserved2 mask. | |
const int | MSK_SPP_nIRQ = 0x04 |
SPP !IRQ mask. | |
const int | MSK_SPP_nError = 0x08 |
SPP !error mask. | |
const int | MSK_SPP_SelectIn = 0x10 |
SPP select in mask. | |
const int | MSK_SPP_PaperOut = 0x20 |
SPP paper out mask. | |
const int | MSK_SPP_nAck = 0x40 |
SPP !acknowledge mask. | |
const int | MSK_SPP_nBusy = 0x80 |
SPP !busy mask. | |
SPP control bits | |
const int | MSK_SPP_Strobe = 0x01 |
SPP strobe mask. | |
const int | MSK_SPP_AutoLF = 0x02 |
SPP auto linefeed mask. | |
const int | MSK_SPP_nReset = 0x04 |
SPP !reset mask. | |
const int | MSK_SPP_SelectPrinter = 0x08 |
SPP select printer mask. | |
const int | MSK_SPP_EnaIRQVAL = 0x10 |
SPP enable IRQ mask. | |
const int | MSK_SPP_EnaBiDirect = 0x20 |
SPP enable bidirectional mask. | |
const int | MSK_SPP_Unused1 = 0x40 |
SPP unused1 mask. | |
const int | MSK_SPP_Unused2 = 0x80 |
SPP unused2 mask. |
|
The (default) constructor does the following:
The constructor throws a RulbusInterfaceError if the base address is invalid, if the address range could not be opened, or if the EPP Interface is not present. |
|
clearEppTimeout() clears the EPP timeout state. Some chips reset the timeout by writing a 1, some by writing a 0 in to the EPP Timeout bit (MSK_EPP_Timeout). Documentation we found for the SMC 665/666 chips (and UMC, WinBond) tells to clear the timeout by writing a one (1) to this bit, whereas the bit is cleared for National Semiconductor chips by reading it. Also, there are chips that require a double status-register read to reset.
We chose to do the following in the hope that it will do the job irrespective of the chip used for the EPP:
See also Linux drivers parallel port module, file parport_pc.c [LXR]. |
|
Reading a byte from the Rulbus via the EPP Rulbus Interface consists of:
To be sure the EPP is not in a timeout state, we first clear a possible EPP timeout with clearEppTimeout(). Then after write address and read data, we check if a timeout persists and if so, we throw a RulbusTimeoutError to indicate failure.
int getReg(int offset) { clearEppTimeout(); writeAddress( offset ); if ( clearEppTimeout() ) throw RulbusTimeoutError( "EPP Rulbus Interface", "writing address in getReg()" ); int data = readData(); if ( clearEppTimeout() ) throw RulbusTimeoutError( "EPP Rulbus Interface", "reading data in getReg()" ); return data; } Implements TheRulbusInterface. |
|
Function initializeEPP() sets the SPP control line as follows:
|
|
interfacePresent() returns true if
To check for the presence of the EPP Rulbus Interface, we write two different patterns (0xA5 and 0x5A) to the EPP address register and check if we can read these patterns again and check if no EPP timeouts occurred.
If parameter
8 4 2 1 | | | |_ timeout pattern 1 | | |___ pattern 1 read != pattern 1 written | |_____ timeout pattern 2 |_______ pattern 2 read != pattern 2 written |
|
Writing a byte to the Rulbus via the EPP Rulbus Interface consists of:
To be sure the EPP is not in a timeout state, we first clear a possible EPP timeout with clearEppTimeout(). Then after each write, we check if a timeout persists and if so, we throw a RulbusTimeoutError to indicate failure.
int putReg(int offset, int byte) { clearEppTimeout(); // clear timeout just to be sure writeAddress( offset ); if ( clearEppTimeout() ) throw RulbusTimeoutError( "EPP Rulbus Interface", "writing address in putReg()" ); writeData( byte ); if ( clearEppTimeout() ) throw RulbusTimeoutError( "EPP Rulbus Interface", "writing data in putReg()" ); return byte; } Implements TheRulbusInterface. |