Path: utzoo!utgpu!water!watmath!clyde!att!osu-cis!tut.cis.ohio-state.edu!mailrus!cornell!batcomputer!itsgw!steinmetz!uunet!van-bc!sl From: sl@van-bc.UUCP (pri=-10 Stuart Lynne) Newsgroups: comp.unix.microport Subject: Re: Igloopatch Keywords: serial port relief Message-ID: <1926@van-bc.UUCP> Date: 22 Oct 88 20:22:09 GMT References: <1058@igloo.UUCP> Reply-To: sl@van-bc.UUCP (pri=-10 Stuart Lynne) Organization: Wimsey Associates, Vancouver, BC. Lines: 89 In article <1058@igloo.UUCP> learn@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