Igloopatch

pri=-10 Stuart Lynne sl at van-bc.UUCP
Sun Oct 23 06:22:09 AEST 1988


In article <1058 at igloo.UUCP> learn at igloo.UUCP (william vajk) writes:

>Briefly explained, the software John uses to initialize the chip sets a
>depth of FIFO fillup to 8 characters, and the cpu is interrupted, all this 
>utilizing the semi-intelligent merits of the 16550A itself, no cpu specific 
>horsepower required. It also appears that an x-off is issued out the port.a
>The 16550A handles flow control whenever its buffer is about to overflow.
     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

It's interesting that National Semiconductor Corporation doesn't know about
this feature. They certainly don't claim that the chip does this. The
documentation certainly doesn't claim that the chip does this. And of course
I've never noticed uucico get screwed up by the chip doing this. Oh maybe
that's it, it notices when uucp "g" is running and disables the feature :-)

The chip *also* doesn't do hardware flow control by itself. It would have been
*very* nice of NS to include that, but full duplex RTS/CTS flow contol (a la
Trailblazer) is not standardized yet so few of the USART manufacturers
support it. 

What the NS16550 does do is to provide a 16 byte RCV buffer AND a 16 byte
XMT buffer; essentially grafted on top of an NS16450. When enabled the XMT
FIFO will accept up to 16 bytes of data and send it without interrupting
the CPU until it is empty. When enabled the RCV FIFO will buffer upto 16
bytes of data before reporting an overrun; and will interrupt when 1, 4, 8
or 14 bytes (as programmed) of data have been received.

The big limitations of this chip lie in the complete lack of built in flow
control given that there is no way of controlling the data in the FIFO's.
There is *no* way of knowing how much data is in either FIFO, other than
that there is a least one character available to read in the RCV FIFO and
the XMT FIFO is not empty.

This leads to problems for sending. To reduce overheads you want to fill up
the XMT FIFO with 16 bytes of data. But if you then receive an XOFF or CTS
drops you don't have any control over the data in the XMT FIFO; other than
flushing it. If you flush you can't tell what was flushed. So you basically
have to just let it drain. So you have to tailor the amount of data you put
into the XMT FIFO to what is receiving at the far end. The Trailblazer
fortunately does work well and will accept 16 bytes without problems.

The lack of built in flow control for inbound data means that this must be
done in the driver at a higher level. Usually you just let the line
discipline routines (ttin) handle it. It T_BLOCK's when more than TTXOHI
characters have been received. If you want to support RTS flow control then
you need an extra test in your rintr routine to drop RTS when more than (for
example) TTXOHI routines characters have been put into the raw clist.

This means that you can't count on flow control for more than regulating the
amount of data you have received so that you don't overflow your clist's.
You can't use it to prevent overruns in your USART. AT 19.2 kbps you have
about 500 microseconds to respond to a received data interrupt with an
NS16450, as it simply buffers one character. What the NS16550 does for you
is to extend this time considerably. For example if you set the interrupt
level to 8 characters, you then have 8 * 500 or 4 milliseconds to respond
before the RCV FIFO will overrun. But if you don't respond in that time it
will still overrun. 

The other big problem is not related to the USART but to the way interrupts
are used in the PC architecture. If you have a card with (for example) 4
USART's on it, generating one interrupt; you must check each and everyone of
the USART's and ensure that it does not have an interrupt pending for
*EVERY* interupt you receive. Plus to make things reliable you must do
something like:

	restart:;
	for ( i = 0; i<MAXUSARTS; i++) {
	  if ( haveint(i) ) {
	    switch(whichint(i)){
	    ....
	    };
	    goto restart;
	  }
	}

This is because you have to ensure that you go from start to finish without
encountering *ANY* interrupts before you *KNOW* that every USART has brought
it's interrupt line down so that the PIC will acknowledge the next
interrupt. If you don't then you can get a situation where you have left a
USART with an interrupt high and you well *NEVER* receive another interrupt
for that board. 

What would really help here would be a little smarts on the part of the
board manufacturers so that you could just go through the USART's once. Even
better would be a status register telling you which USART's had an active
interrupt.

-- 
Stuart.Lynne at wimsey.bc.ca {ubc-cs,uunet}!van-bc!sl     Vancouver,BC,604-937-7532



More information about the Comp.unix.microport mailing list