Date: Wed, 12 Nov 1997 18:59:59 GMT From: mouth@ibm.net (John Kelly) To: Bruce Evans <bde@zeta.org.au> Cc: hackers@freebsd.org Subject: Re: Status of 650 UART support Message-ID: <3469e29a.47593226@smtp-gw01.ny.us.ibm.net> In-Reply-To: <199711120647.RAA10782@godzilla.zeta.org.au> References: <199711120647.RAA10782@godzilla.zeta.org.au>
next in thread | previous in thread | raw e-mail | index | archive | help
On Wed, 12 Nov 1997 17:47:08 +1100, Bruce Evans <bde@zeta.org.au> wrote: >>Did you know that the 650 UART has on-chip "auto" RTS flow control >On some (early? all?) 16650s it is said to be just a pessimization >to use it, since it is invoked when the trigger level is reached, >so it is invoked for almost every input interrupt. It may seem like a pessimization if your ISR always starts quickly enough to avoid UART overruns. However, when using a 550 UART, presumably the serial ISR could safely raise RTS as its first duty when the FIFO trigger level has been reached, since the external device would be expected to have a large buffer of its own. If true, then why not have the 650 chip raise RTS automatically? That buys insurance against interrupt latency, pessimistically or not. Don't tell me you don't have life insurance. :-) Does the sio.c ISR raise RTS when servicing a UART trigger level interrupt, or does it simply drain the UART FIFO while letting the external device keep streaming inbound bytes? If the latter is true, I can see how 650 auto RTS might be viewed as a pessimization, although it's still unclear to me whether it might cause any loss of efficiency. >I don't know what happens when the driver sets RTS directly. The Startech databook says: > RTS pin will be forced to high state regardless of its original > state when receive FIFO reaches to the programmed trigger > level. RTS pin resumes it original state after content of the > data buffer (FIFO) drops below the next lower trigger level. > ... hardware ... flow controls can be enabled for automatic > operation. During these conditions the ST16C650 will accept > additional data to fill the unused ... recieve FIFO locations. My understanding of this is: 1) The 650 RTS pin honors the driver setting, unless overridden by the automatic on-chip RTS, and in all cases the on-chip value takes precedence. In other words, the 650 does not change the value set by the driver, it simply hides it when it wants to raise RTS on its own. Or in yet other words, the state of the actual UART RTS pin results from ORing MCR bit 1 (RTS controlled by the software driver) and the current state of the auto on-chip RTS. 2) Receive (not transmit) FIFO trigger levels, 550 vs. 650: FCR bit 7 and 6 550 650 00 1 8 01 4 16 10 8 24 11 14 28 If the software driver sets FCR to "10" as you would expect in the case of a 550 UART, the 650 trigger level will actually be 24 and the next lower trigger level will be 16. The excerpt from the databook above indicates that when using auto RTS, the chip will raise RTS as soon as the external device fills the UART up to its trigger lever of 24. Perhaps one more byte will come into the UART before the external can recognize RTS and stop streaming. At that point the FIFO interrupt should invoke the ISR which will drain enough bytes to cause the UART to drop RTS when 16 bytes, the next lower trigger level, remain in the UART. At that instant, the external device will start streaming again because the chip dropped RTS, unless of course, the software driver had raised it, in which case the external device will remain silent until the ISR drains the UART completely and drops RTS again. Since the behavior will be different depending on whether the ISR raises RTS or not, I need to learn how sio.c acts in that regard. > Perhaps auto flow control interferes with this and causes your buffer > overflows. Possible fix: turn off auto flow control at least when clearing > RTS directly. Turning auto flow control on once when opening your device is fine, but turning it off and back on again during data transfer would cause a loss of efficiency. You must first write hex "BF" to the LCR to make the EFR visible, then you must set bit 6 in the EFR, then you must restore the previous value to the LCR. Not to mention the fact that changing the LCR values even momentarily to make the EFR visible may cause unexpected side effects or bring out heretofore unknown bugs in the 650 chip, as the LCR controls word size and parity. I would not feel safe changing the LCR after establishing communications with the external device. It should not be necessary anyway, since as stated by the databook, auto RTS vs. driver RTS will have no adverse impact on each other. >I think the best available setup is to use 16550 mode with the tx fifo >size set to match the flow control. The 16650 configuration is too >specific - it forces 16650 flow control and a 32 byte tx fifo size. I don't follow you here. FCR bits 5 and 4 on the 650 allow setting the transmit FIFO to 16, 8, 24, or 30. The default is 16. However, none of these are in effect unless, as the databook says: > ... user can write to transmit trigger levels but activation will not > take place till ST16C650 special mode is selected (EFR bit-4 > is set to "1"). > ... to be compatible with ... 550, 1 bytes transmit trigger level is > selected after reset. So if you don't set EFR bit 4, the 650 transmit FIFO is still only one byte just like a 550. And I don't recall seeing any code in sio.c to set EFR bit 4. Whew! I'm getting hungry. I'll have to analyze the rest of your message later. John
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?3469e29a.47593226>