If I want to build a device (a PIC programmer, print buffer, printer switch etc...) that connects between the PC and the printer so that the printer is connected at the same time as my device, how can I know that the direction on the data bus has been reversed?
This information is necessary because the bus must be buffered to prevent the Peripheral from seeing signals from the host intended for the inline device and because not reverseing the buffer will cause a "data crash" where both my buffer and the Peripheral are trying to drive the data lines at the same time. This issue can be avoided if the data signals from the Host can be guareenteed not to activate functions in the Peripheral without coorisponding changes in the status signals (which do not change direction) but this is not always the case today as more and more devices respond to "wiggeling" of data lines without nStrobe etc.... inorder to implement cheap inline capabilitys.
Buffering the data lines also alows the inline device it "inject" data to the Peripheral (using the printer to print status messages, reports or collected data, etc..)
The signal "IEEE 1284 Active" (pin 17-36, nSelect Input) must always be set high by the host before the data bus direction can be reversed except in EPP mode. The Host must also direct the Peripheral to drive data bus by setting HostBusy (pin 14, nAutoFeed) low while in Byte mode, nReverseRequest (pin 16-31, nInit)low in ECP reverse mode, or nWrite (pin 1, nStrobe) high in EPP mode. The direction on the data bus has been reversed when "IEEE1284Active" AND (NOT "HostBusy" OR NOT "nReverseRequest") OR "something that tells us we are in EPP mode" AND "nWrite"? I doubt that this is reliable.
All these signals are defined EXCEPT "something that tells us we are in EPP mode." Unlike the other modes that use IEEE 1284 Active and are terminated when it is not asserted which would then indicate a normal SPP mode, EPP is terminated by nInit (pin 16-31) which would not normally be asserted during SPP operation and cannot be used as an EPP mode indicator.
pin number SPP signal negotiation nibble mode byte mode ECP mode EPP mode host periph name function function function function function ---- ------ ----------- --------------------- ---------------- ---------------- ----------------- ------------------ 1 > 1 nStrobe "mode # on data bus" nWrite(H=Rev, L=Fwd) 12 < 12 PError bit 2 then 6 nDataAvail(L) nAckRevReq(L=Fwd) User Defined 16 > 31 nInit Always high always high nRevReq(L=Rev) nInit(L=Exit) 17 > 36 nSelectIn (H=Start) IEEE1284(L=Exit) IEEE1284(L=Exit) nAStrb
Monitoring the negotiation phase to detect request and acceptance of EPP operation would seem to be the only other alternative. The question then becomes, "how few signals can I monitor to verify that EPP (or another) mode has been entered." My guess is that only the host request for negotiation via nSelectIn high and nAutoFeed low, the data lines (to see what mode was requested) clocked by nStrobe and the peripherals response via nAck (asserted BEFORE nStrobe so we know we are "not in SPP land anymore, Toto" and then released to clock Select) and Select (high if the mode was accepted and low if not, except for nibble mode which is implicitly accepted by responding to the negotiation request and is finally accepted by setting Select LOW rather than high.) are required.
Then I can monitor nSelectIn as "IEEE 1284 active" to see an exit from Byte or ECP modes and nAutoFeed as HostBusy to see reversals in Byte mode and nStrobe as nWrite to see reversals in EPP mode.
But then, I also have to monitor pin 16-31 as "nInit" to see the exit from EPP mode and as nReverseRequest to see reversals in ECP mode and pin 12 as "nAckRevReq" to see a return to forward transfers in ECP mode so the total is 8 status pins and the 8 data pins. No seperated connections are required but, this prevents me from also injecting data to the printer, so it's only usefull if we add seperated connections for nAck, Busy and maybe nStrobe. Total: 11 pins for status 8 for data.
pin number SPP signal negotiation byte mode ECP mode EPP mode host periph name function function function function ---- ------ ----------- --------------------- ---------------- ----------------- ------------------ 1 > 1 nStrobe "mode # on data bus" nWrite(H=Rev, L=Fwd) 10 < 10 nAck L=1284Ack, H=Ans ready 11 < 11 Busy 12 < 12 PError H=1284ok nAckRevReq(L=Fwd) 13 < 13 Select XFlag(H*=mode ack) 14 > 14 nAutoFeed (L=Start then H=1284) HostBusy(L=Rev) 16 > 31 nInit nRevReq(L=Rev) nInit(L=Exit) 17 > 36 nSelectIn (H=Start) IEEE1284(L=Exit) IEEE1284(L=Exit) nAStrb *=except for nibble mode where L=mode ack
If we are willing to degrade the speed of the reverse connection of the peripheral to the host, we can interfere with the negotiation phase and deny access to all but nibble mode for reverses thereby eliminateing the problem.
pin number SPP signal negotiation nibble mode host periph name function function ---- ------ ----------- --------------------- ---------------- 1 >> 1 nStrobe "mode # on data bus" N/A 10 << 10 nAck L=1284Ack, H=Ans ready PtrClk(L=clock nibble, H=AckHostBusy) 11 << 11 Busy Bit 3 then 7 14 > 14 nAutoFeed (L=Start then H=1284) HostBusy(L=ready,H=recieved) 17 > 36 nSelectIn (H=Start) IEEE1284(L=Exit) 12 < 12 PError H=1284ok Bit 2 then 6 13 < 13 Select XFlag(L*=mode ack) Bit 1 then 5 15 < 32 nError L=data avail Bit 0 then 4 *=only for nibble mode. Normaly L=mode ack
I'm a little concirned that PError and nError High are the real signal from
the Peripheral that it is 1284 aware rather than nAck but the spec does say
that nAck will be set low at the same time. Also, the Host will not set nAutoFeed
high if it didn't see all the correct signals so we will at least know if
we screwed up, and sending a zero isn't usually a killer except with binary
data. If I had some extra pins, I would monitor PError, Select and nError
which would also allow me to device ID the Peripheral and capture Peripheral
to Host data transfers.
Also, we should avoid interferring with Device ID request via Nibble mode
(data byte 04h) so we will not always place 00h on the data lines.
Extensability Link (data 80h) may also require further investigation incase
there are usefull modes defined that use only the Nibble reverse transfer.
If we are willing to eliminate IEEE 1284 compatibility, we can prevent negotiation by overriding the peripherals responce to the Host request for negotiation (setting nSelectIn high and nAutoFeed low) and preventing it from setting nAck low, and nError, PE and Select high.
pin number SPP signal negotiation host periph name function ---- ------ ----------- --------------------- 1 >> 1 nStrobe "mode # on data bus" 10 << 10 nAck L=1284Ack, H=Ans ready 11 << 11 Busy 12 < 12 PError 13 < 13 Select XFlag(H=mode ack) 14 > 14 nAutoFeed (L=Start then H=1284) 17 > 36 nSelectIn (H=Start)
OK: So the questions are:
1. Can normal (SPP) operation mimic a mode that reverses the data direction to the extent that "IEEE 1284 Active" would be low (the SPP printer is selected) and nAutoFeed is low or nInit is low? In other words will something use nAutoFeed or nInit while using nSelect? Probably: YES.
2. What is "something that tells us we are in EPP mode." Probably: ONLY MODE NEGOTIATION
3. What is the minimum number of pins that can be used to reliably detect negotiation to other than SPP mode and see directional change requests? Probably: 8 STATUS, 8 DATA
4. Is there a way that the Host/Peripheral could leave a mode or not reverse that these pins would not indicate?
5. Is there a better (electronic: sense the direction current wants to flow?) way to do this? If we could be assured that the Peripheral would always terminate the data lines with pull-ups to Vdd, we could insert a buffer between the Host and Peripheral and tri-state it when $FF is read at the Host side then reverse and drive the Host when anything other than $FF is read at the Peripheral side. Terminate reverse when $FF again appears at the Peripheral (but then what if the Peripheral was trying to SEND $FF? can we be assured that the Host will have pull ups?)
The questions I am not going to ask are:
1. Has there ever been a virus written that drives the PC parallel port to simulate mode negotiation into a reverse data capable mode and then signals a reversal while at the same time driving the data lines, thereby blowing out the PC parallel port or the printers parallel port?
2. How do manufacturers of printers etc... protect against this?
3. Has anyone ever made a PIC programmer or other device specific PC program that would accidentally get a IEEE 1284 printer into reverse mode when run with the printer (erroneously) still attached?