I am trying to use an EPP parallel port to transfer data from my
PIC-O'Scope to my PC and I am having trouble. I am using a PDF file
documentation which I got from some web site (I can't remember where) but
it isn't clear about some things. Let me ask a few questions and maybe
someone will know some answers:
1) The nWAIT line is the only handshaking line (out of three) which is in
input to the PC. It seems, however, to have a 1k (about) pull up to 5v
internally in the PC. Is this what it should be, or am I doing something
wrong, or (worse) is this maybe a quirk in my PC?
2) One of the pins on the pic is connected to this nWAIT line. It is
supposed to pulse high and then low again for about 1us to ack the EPP
port data transfer. I don't have a scope fast enough to see this very
well, but if I hook up a 115MHz counter chip to it, I actually see about
three pulses when it should have only pulsed once. If I disconnect the
line from the PIC and just measure the output of the pic, I get only 1
pulse, just as I should. If I hook up a long wire from the pic pin and
terminate it in a 1.5k resistor, I still only see 1 pulse, as it should
be. However, when it gets hooked up to the actual nWAIT line on the
parallel port, it goes wacky. This happens both with a 4 foot cable
between the PC and the PIC, and also even if I reduce the cable to 1 foot.
If I buffer this line with a pair of 7404s (one right after the other so
it is not inverting), I get only 1 pulse if I measure the pic pin, but I
get erratic (somewhere around 3 pulses) if I look at the output of the
buffer. I also tried using pin RA4 (open collector) with a small pull up
(1k), thinking that this might give the pic a better ability to drive the
line: same results, several pulses instead of one.
3) The code on the pic is supposed to read in a character from the EPP
port and send it back again. The PC software is acting as if it is being
properly ack'd, and it is receiving the proper character. However,
if I ,for example,send the letter A (or any ascii character for
that matter) and then send B, I'll get A back for both of them, and then
B back for the next one (in other words, I'm not sure if the acking is
occuring at the right time or if it is staying in sync).
I'm sorry to be so long winded and confusing, but I have been working on
this on and off for a few months, and I have been at it very intensily
these past few days and I think I have traced my problem down to this,
and I'd appreciate it if someone could either answer my questions or
point me to a better tutorial.
On Wed, 1 Jul 1998 18:37:13 -0400, Sean Breheny wrote:
>Dear Piclisters,
>
>I am trying to use an EPP parallel port to transfer data from my
>PIC-O'Scope to my PC and I am having trouble. I am using a PDF file
>documentation which I got from some web site (I can't remember where) but
>it isn't clear about some things. Let me ask a few questions and maybe
>someone will know some answers:
>
>2) One of the pins on the pic is connected to this nWAIT line. It is
>supposed to pulse high and then low again for about 1us to ack the EPP
My guess is that it should be normally high (inactive) and you generate the
ACK by pulling it low for 1uS, then let it go high again.
Instead of driving it high, let it float.
Andy
==================================================================
Andy Kunz - Statistical Research, Inc. - Westfield, New Jersey USA
==================================================================
You can find a lot of info on interfacing to the parallel port in
the book "Parallel Port Complete" by Jan Axelson (ISBN 0-9650819-1-5).
The book covers all types of ports (including EPP, ECP, IEEE1284)
with timing diagrams and VB programming examples (floppy included).
You can also find some info (and excerpts from the book) on the web
site of the author: http://www.lvr.com
Thanks to all who responded. I will try your suggestions tonight when I
get home from work. In the mean time, I would like to post my code to see
if anyone sees anything else obviously wrong with what I'm trying to do.
The code is short. Even so, I understand that it is annoying to look at
other people's code, but I appreciate it very much.
In short, regardless of what I am seeing electrically, the problem that
is actually being experienced is that there is a one character "lag" in
the character echo. In other words, if I send an "a", and get back a "b"
like I should (the code increments the ascii code before echoing it), and
then I press "c", I'll get back a "b". If I press "c" again, then I get
"d" instead of right after pressing "c".
Thanks and here's the code:
PIC CODE FIRST, THEN PC CODE
; EPP2.SRC
; This code accepts data from a PC EPP Parallel Port,increments it
; and then spits it back out to the EPP Port.
; EPP Data 0-7 = RB0-RB7
; EPP Write = RA0
; EPP Data Strobe = RA1
; EPP Wait = RA2
incf 0Ch ;increment holding reg.
movf 0Ch,0 ;set PORTB to contents of holding reg.
movwf PORTB
nop ;wait for PORTB to stabilize and overcome capacitance
nop
nop
bsf PORTA,2 ;ACK by setting nWAIT high
call wloop ;wait for nDATA_STROBE to go inactive
bsf STATUS,5 ;PORTB set to input again
movlw 0FFh
movwf TRISB
bcf STATUS,5
bcf PORTA,2 ;clear nWAIT, and go wait for next cycle
> void main (void)
> {
>
> int a,b;
>
> //outportb ( 888 + 1 , inportb ( 888 + 1 ) & 0xFE );
> // THIS LINE MAKES NO DIFFERENCE EITHER WAY ^^^^^^^^^
>
> aloop:
>
> outportb ( 888 + 2 , 4); //Set control register
> outportb ( 888 + 1 , 0xFF ); //Clear possible timeout
> while ( ! kbhit ( ) ); //Wait for keystroke
> outportb ( 888 + 4 , getch ( ) ); //Send keystroke
> delay ( 10 ); //Wait for PIC to finish what it is doing
> b = inportb ( 888 + 4 ); //Read in port contents
> printf ( "%d\n" , b ); //print it
> goto aloop; //Do it again
> };
I can see a few problems here, first of all, I would expect the parallel
port to have it's control lines inactive and high when you first start
off. You therefore have to initialise them, but before you can
initialise the port, you have to tell the PC what sort of port you wish
to use. This register is at your base address + 0x0402h and you need to
write the value 0x80h for the EPP port. You can now write the value
XXXX0100 B into the control register to initialise this port (base
address + 2). Now you need to set the data direction bit to a '1' for an
inport command and a '0' for an outport command.
I spent some bang-head-on-wall time trying to get a new Canon printer
installed. The problem was that their driver did not initialize the int.
vector associated with EPP. Setting the port to "standard LPT" in the BIOS
was the instant cure for all the problems. Good luck!
Status Reporters
Type From
Initials CR
Name Domain NOTES
Native Name CN=Claudio Rachiele IW0DZG/OU=Italy/O=IBM@IBMIT
Foreign Native Name CN=Claudio Rachiele IW0DZG/OU=Italy/O=IBM\nIBMIT\n\n
Organization IBM
Org Unit 1 Italy
Last Name IW0DZG
First Name Claudio
Status 769
Explanation Invalid recipient
X.400 Status 769
Explanation Router: Unable to open mailbox file D14HUBM1/14/H/IBM mail.box: Server not responding
Hello to all who responded about my EPP port problems,
I finally fixed my problem, and it was a very simple one: my routine was
not fast enough. The EPP port has about a 10uS timeout timer on most PCs.
If the PIC doesn't ack the PC's data strobe within 10uS, it finishes the
cycle right then and there. My PIC routene was taking about 15uS to
create the ack. When I lowered it to about 5uS, it worked fine.
Apparently all the strange behavior with the WAIT line pulsing multiple
times was just due to the PIC pin's very fast rise time, combined with
cable length and my fast counter that I was using to detect it.
ALSO, the reason for the "lag" phenomenon was that the PIC's code to get
data from the PC was working, but its code to send data TO the PC was
where the timeout was occuring. SO, the cycle was enbding before the
PIC's output latches were being loaded with the new value.
Thanks to all,
Sean
P.S. Now that I have fixed this proble, I have found another having to do
with the SRAM in my DSO, so I may have some more questions for all of you
soon :)
> Sean Breheny wrote:
>
> > void main (void)
> > {
> >
> > int a,b;
> >
> > //outportb ( 888 + 1 , inportb ( 888 + 1 ) & 0xFE );
> > // THIS LINE MAKES NO DIFFERENCE EITHER WAY ^^^^^^^^^
> >
> > aloop:
> >
> > outportb ( 888 + 2 , 4); //Set control register
> > outportb ( 888 + 1 , 0xFF ); //Clear possible timeout
> > while ( ! kbhit ( ) ); //Wait for keystroke
> > outportb ( 888 + 4 , getch ( ) ); //Send keystroke
> > delay ( 10 ); //Wait for PIC to finish what it is doing
> > b = inportb ( 888 + 4 ); //Read in port contents
> > printf ( "%d\n" , b ); //print it
> > goto aloop; //Do it again
> > };
>
>
> I can see a few problems here, first of all, I would expect the parallel
> port to have it's control lines inactive and high when you first start
> off. You therefore have to initialise them, but before you can
> initialise the port, you have to tell the PC what sort of port you wish
> to use. This register is at your base address + 0x0402h and you need to
> write the value 0x80h for the EPP port. You can now write the value
> XXXX0100 B into the control register to initialise this port (base
> address + 2). Now you need to set the data direction bit to a '1' for an
> inport command and a '0' for an outport command.
>
> By the way, this information and more can be found at
> http://www.geocities.com/SiliconValley/Bay/8302/epp.htm/ for the EPP port
> and http://www.senet.com.au/~cpeacock/ for everythig else!
>
> Hope this helps,
>
> Brian.
>
>Hello to all who responded about my EPP port problems,
>
>I finally fixed my problem, and it was a very simple one: my routine was
>not fast enough. The EPP port has about a 10uS timeout timer on most PCs.
>If the PIC doesn't ack the PC's data strobe within 10uS, it finishes the
>cycle right then and there. My PIC routene was taking about 15uS to
>create the ack. When I lowered it to about 5uS, it worked fine.
>
>Apparently all the strange behavior with the WAIT line pulsing multiple
>times was just due to the PIC pin's very fast rise time, combined with
>cable length and my fast counter that I was using to detect it.
>
>ALSO, the reason for the "lag" phenomenon was that the PIC's code to get
>data from the PC was working, but its code to send data TO the PC was
>where the timeout was occuring. SO, the cycle was enbding before the
>PIC's output latches were being loaded with the new value.
>
>Thanks to all,
>
>Sean
>
>P.S. Now that I have fixed this proble, I have found another having to do
>with the SRAM in my DSO, so I may have some more questions for all of you
>soon :)
I have used a hardware method to overcome this feature by attaching
set/reset latch between the STROBE and WAIT/BUSY lines of a printer port.
Connect the STROBE line to the set of the latch and the WAIT/BUSY line to
the latch output.
You can then monitor the WAIT/BUSY line to see if there is any new data
available from the printer port, when there is this line will be pulled high
by the by the set/reset latch.
When you have read the available data you can then reset the latch and wait
for the next character.
Stuart Broad wrote:
>
> >Hello to all who responded about my EPP port problems,
> >
> >I finally fixed my problem, and it was a very simple one: my routine was
> >not fast enough. The EPP port has about a 10uS timeout timer on most PCs.
> >If the PIC doesn't ack the PC's data strobe within 10uS, it finishes the
> >cycle right then and there. My PIC routene was taking about 15uS to
> >create the ack. When I lowered it to about 5uS, it worked fine.
> >
> I have used a hardware method to overcome this feature by attaching
> set/reset latch between the STROBE and WAIT/BUSY lines of a printer port.
> Connect the STROBE line to the set of the latch and the WAIT/BUSY line to
> the latch output.
The EPP interface is not suited very well to connecting a
software-driven peripheral to your PC. Investigate ECP mode, this is
much more suitable
because of its use of interlocked handshake. You also get a FIFO of
usually
16 bytes which improves performance. Contrary to public misconceptions,
you
don't need to use DMA when you're using ECP -- you can add DMA code if
and
when you want a higher data rate and/or lower CPU overhead.
In interlocked handshake, the two devices acknowledge *both* edges of
the
control signals; this allows for slow peripherals. Here is what it
might
look like if both strobe and acknowledge signals are active low:
Event 1: Source (can be host or peripheral) wants to send some data,
and
asserts its strobe signal
Event 2: After a while (depending on how often the destination polls
the
strobe line) the destination acknowledges the asserted strobe
by asserting the ack signal. Now is probably a good time to
latch the data as well.
Event 3: The source notices the asserted ack signal and negates the
strobe signal
Event 4: After a while the destination negates the ack signal.
If you want your device to comply to IEEE1284, then you better read the
standard. There is an elaborate negotiation sequence required before
you
can switch to EPP or ECP modes -- failure to do this negotiation may
cause
your PC to blow up its parallel port or your PIC. This is perhaps not
important for a hobby project that you're only going to use on one PC,
but if you bring your device to a friend and blow up his parallel port
he won't be amused.
The standard is about $100 and available from the IEEE.
Frank
------------------------------------------------------------------------
Frank A. Vorstenbosch <SPAM_ACCEPT="NONE"> Phone: 0181 - 636 3000
Electronics and Software Engineer Mobile: 0976 - 430 569
Eidos Technologies Ltd., Wimbledon, London Email: favKILLspameidos.co.uk