- To: email@example.com (D. Crompton)
- Subject: 16550 THRE
- From: Pete Carah <ames!elroy.Jpl.Nasa.Gov!grian!puffin!pete>
- Date: Wed, 22 Jan 92 22:25:21 PST
> Can anyone explain the THRE TO vs. NOS to a little more detail than the
> one sentence in the manual.
Well, it's really pretty simple - a rather nasty oversight on NS's
(or maybe WD's) part early on; all the 8250 derivatives show the
I can't explain the NOS code for same (I haven't looked at it), but I did
get a good understanding from a fairly recent (1.5 yrs ago or so) NS app
note. The 8250 has existed since 1981 or so with this problem; only since
abt 1989 has this error actually been publically explained. I ran into it
long ago with no explanation, and fixed it with a timeout in one case, and
not using interrupt-driven send in the other (not an option for NOS).
There is a third fix (see below).
The problem is that a read of the IID register resets THRE. That is the
case whenever you read IID with THRE asserted; since THRE is the lowest
priority interrupt (rightly), a read or read status interrupt will cover
up a thre interrupt. I had originally been led to believe that IID reads
would only reset THRE if it was the identified interrupt, but noooooo :-(
There are two easy fixes in software; one is a timeout which checks for
a non-empty transmit queue and THRE in the LSR; the other is a rather
complicated loop (which you need part of anyhow) within the interrupt
routine where you check for thre in the LSR instead of in the IID only.
The problem with that is that a read of LSR will reset all of the pending
interrupts except modem changes (and maybe read data? the app notes aren't
clear on that)... Thus you need to parse ALL of lsr any time you read it.
> I recently switched from a slow XT where I got no THRE TO's to a
> much faster 386 system and I get occasional THRE TO's. I am using the
> same I/O card and UART's from the old system. IT does not seem to effect
> performance although the existence of the TO probably indicates lost
Shouldn't indicate lost data if the software is written right; only lost
performance. Shouldn't affect performance too much on 16550A's if
they send 16 bytes every time.
> In an attempt to see if it would help I recompiled the code with
> the TX buffer size set to 16 characters rather than 1 and the fifo
> limit to 4 rather than 1. The values of 1 were used by Kelvin early on
> when there were troubles and has been historically carried on since.
The real nasty with the 16550A is that there is NO status bit for transmit
FIFO full. You have to count 16 from a tx fifo empty status. This makes
it hard (impossible in theory) to add characters to a partially full fifo.
> It did not seem to make a difference with the THRE TO's though. It
> now does show 16X more TX characters than TX interrupts. And 4X more
> RX characters than RX interrupts.
> What is the desireable setting for these two values? Is it good to
> minimize the number of interrupts and maximize the number characters
> transfered at each interrupt?
I think so; that's how I've written my interrupt routines. The RX count
of 4 only hurts on packet tails.
> Set the way it currently is with the PA0 code it interrupts on each
> character TX and RX.
> I guess I never really understood the TX interrupt problem. That is
> generally where more problem seems to exist but why is this the case.
> I have the character to send and as long as I have enough room to
> store them all should be well. On the other hand on RX something is
> trying to dump characters to me and if I do not service it often enough
> characters will be dropped. Seems yoiu have much more control over TX
> than RX. What am I missing?
TO shouldn't indicate anything lost, if the software is written right.
> I never see RX hardware overflows.
Better not (though I get them in unix with 16450A's at 9600, all the time.)
-- Pete (firstname.lastname@example.org; elroy.jpl.nasa.gov!grian!puffin!pete)