[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Parallel port fails because /INIT held low
I've been studying this dratted printer port problem of mine.
And so I'll share my thinking with you, if only because
writing it down helps me :-)
Assumption 1: linux lp code is correct in that lp_reset()
for example does a parport_write_control( LP_PINITP)
to *deassert* /INIT
This is confirmed by some parallel port FAQs
eg http://www.lvr.com/files/ibmlpt.txt which
indicates that the register -> electrical path
is non-inverting for "init"
ie parport_write_control( LP_PINITP) sets the register bit = 1
which in turn sets /INIT to 1 (Vcc) which thus deasserts
"init" from the printer's perspective.
So we have a reasonable belief that parport_write_control (LP_PINITP)
in the PC/linux world *DEASSERTS* init, ie /INIT goes to 1 (Vcc).
Now under Cris-linux
parport_write_control( LP_PINITP ) maps to
parport_etrax_write_control( LP_PINITP )
which for the "init" bit value maps to
SETF( ..., R_PAR0_CTRL_DATA, init, 1)
(assuming "(unsigned)LP_PINITP > 0" == 1 and not -1, I forget )
now the relevant bits (no pun intended) of SETF() use IO_FIELD()
to set the init bit in the CTRL register to the given value (here == 1)
Now "1" written into the init bit (refer Etrax100LX Desiger Ref Manual pg
means pin is "active".
According to the documentation on page 105, 106 making init "active"
means ASSERTING /p0init (the chip output pin), ie /p0init -> 0 (Gnd)
because it is active low.
But there are two catches to this:
1) the (flexible) Extrax100LX chip has a config register which can be used
to INVERT the signal sense: 19.113 "iinit"
2) The Developer LX board has a chip inverter on the output U1-C
(refer schematic pg 10)
The axis-cris parport driver init code SETS iinit to INVERT.
So the pin is inverted in the chip and then reinverted on the board.
The nett effect of this is that 1) and 2) cancel each other out.
So we end up with:
(Note i've omitted the double inversion from iinit and U1-C)
parport_write_control( LP_PINITP ) // in lp.c means "deassert /INIT"
-> /INIT = 0 // ie "ASSERT /INIT"
WHICH IS WRONG!!
Or to be fairer, the etrax code is SELF consistent
and the linux lp code is SELF consistent
but the two have opposite interpretations of how LP_PINIT is used.
Personally I think I prefer the Axis interpretion, I prefer
to have cleared bits set to their default state, so that 0 should deassert
but that is just a personal preference.
So how to fix?
well I'm not touching the linux lp.c standard code
and I'm not taking a soldering iron to the developer board
I'm tossing up between
a) changing parport_etrax_write_control() function
b) setting the "iinit" bit to non-inverting.
IO_STATE(.. init, inactive) needs to "do the right thing"
Now inactive in THIS case is 0 (include/asm-cris/sv_addr.agh and pg
so register init = 0 (inactive) should deassert /INIT to be internally
consistent with axis logic.
-> /INIT = 1 // ie "DEASSERT /INIT"
WHICH IS CORRECT
Now recall I am skipping over the double inversion within that sequence
but this does mean that unless I redefine all the axis defines from
their ASIC and docs etc I need to keep the double inversion intact.
Therefore I cannot change the iinit config to non-inivert.
Which means the bug is formally in the etrax <-> linux interface layer
So I gotta go hack that to be something like
(control & LP_PINITP) == 0 // instead of > 0
NOW I suppose I ahve to worry about which other status bits
may be wrong too... (eg STROBE, AUTOFD, FAULT and SELECT_IN for output,
and ACK, BUSY, SELECT, PAPER_ERROR on input) *sigh*
Hopefully since the ouputs at least are handled (I think) interally by
the chip (in non-manual mode) that they are all correct
and it is just the explicit linux-etrax 'manual' toggling that is wrong.
Incidentally the lp_reset() also sets LP_PSELECP permanently
to select the printer (I don't recall the exact use of this line)
but it is also an active low, however my PC parallel port guide
notes that it is an inverted pin in the PC world. ie register=high ==
(the opposite of LP_PINITP)
The extrax_write_control() does the same logic for all control bits, so it
may be that this just happens to be correct.
Taking this line of thinking AutoFd is also inverted in the PC world so
it too is correct, and strobe is likewise correct (being inverted).
Thus it seems that ONLY the /INIT line is "perverse" in the PC world.
For etrax inputs (ack, bust, paper end, selectin) none of these are
on the PCB... oh heck I'm sick of this...
Well AXIS I think I;ve found bug#1
change line 207 of the extrax parport.c (ver 1.8)
(control & PARPORT_CONTROL_INIT) > 0);
(control & PARPORT_CONTROL_INIT) == 0);
Well now would someone care to comment on my logic and tell me if
it is all rubbish and I've got the wrong end of the stick or what...
Do I get a sweety ?
Datafusion and Visualisation Systems