[comp.os.msdos.programmer] U8250 Questions

viraf@seas.gwu.edu (Viraf Bankwalla) (01/15/91)

Hi,

  I'm writing an isr to handle COM1 and COM2, and had a couple 
  of questions.

  The Interrupt Identification Register indicates if an 
  interrupt is pending, and which one it is.  The interrupts
  are assigned priorities, the higest one being serviced first.

	   PRIORITY        Interrupt ID
	   --------        -------------------------------
		  1            Receive Line Status
		  2            Receive Data Available
		  3            Transmit Holding Register Empty
		  4            Modem Status Changed

  Say I'm in my isr, processing Receive Data Available,
  and the modem status changes, am I interrupted, or
  will I notice the change the next time I poll the
  IIR in the loop, as I havn't issued the End Of Interrupt ?

  I've also noticed, that on turning the modem OFF, the DCD,
  and other bits in the Modem Status Register get set, resulting
  in me returning a false result.
  Assuming that DCD always reflects the true state of the
  carrier, how could I avoid the above problem ?

  Any help, and references would be greatly appreciated.

  Thanks in advance.

  viraf bankwalla
  viraf@seas.gwu.edu
  ...!uunet!gwusun!viraf

david@csource.oz.au (david nugent) (01/15/91)

In <2535@sparko.gwu.edu> viraf@seas.gwu.edu (Viraf Bankwalla) writes:

>   The Interrupt Identification Register indicates if an 
>   interrupt is pending, and which one it is.  The interrupts
>   are assigned priorities, the higest one being serviced first.

> 	   PRIORITY        Interrupt ID
> 	   --------        -------------------------------
> 		  1            Receive Line Status
> 		  2            Receive Data Available
> 		  3            Transmit Holding Register Empty
> 		  4            Modem Status Changed

>   Say I'm in my isr, processing Receive Data Available,
>   and the modem status changes, am I interrupted, or
>   will I notice the change the next time I poll the
>   IIR in the loop, as I havn't issued the End Of Interrupt ?


Hmm, since you mention the 8250 you touch on a sort point.

There's a bug in the 8250 relating to interrupt priorities. Specifically,
if you are servicing an RLSI or RDAI, you can loose both THRE and
MSI interrupts during their service since they won't be flagged in 
the IIR (bit 0).

But to answer your questions...

No, you aren't interrupted.  At least not if you've kept interrupts 
disabled and not rearmed the PIC.  Until and unless you do both, you 
won't, but as I've said, you'll often miss the interrupt anyway, since 
the UART is buggy.  The result is loosing track of whether the 
transmitter is ready to fire again and often results in a "stuck 
transmitter".

I used to read the line status register and specifically test for the
transmit holding register empty bit, but experience turned out to
be a good teacher - that lies too. :-(  It won't indicate that it's
empty unless the UART has seen the interrupt as well.

So, the solution is:

	rearm the PIC prior reading the IID (and before each time 
		it is read, but DON'T enable interrupts)

	Toggle the THE/MSI bit in the interrupt enable register on 
	  the UART before servicing either an RDAI or RLSI

Actually, I found turning OFF the THR on the interrupt enable register
when the transmitter wasn't active helped a great deal.  You keep a 
static flag when it's idle, and enable it as soon as you have anything
to send.  As soon as you re-enable it, the UART will generate an interrupt
and you have your transmitter auto-firing instead of having to manually
send the first character to kick off transmitter interrupts.  All
in all a better, more robust approach and you end up having all UART I/O
isolated inside the ISR where it should be anyway.

One other warning if you're using this approach.  Don't enable transmit
interrupts if they are already enabled on the INS8250B (the National
Semiconductor one).  It doesn't seem to register that the THRE state
should be low for some time after you actually place a character in the
holding register for transmission.  As a result, there's a time period
in between in which this could possibly trigger another interrupt,
resulting in transmitter overflow and, of course, loss of characters
in transmission.  Also, the line status register can't be trusted during
this period since it suffers the same fate (not correctly reflecting the
transmitter's real state).

Also, don't expect this to work with the 82450C.  It doesn't (the UART
that is :-)).  But that particular UART has more bugs than I cared to
investigate, so I completely dropped supporting it quite some time ago.

The end result of that is that it's very difficult to build a driver which
both allows for this bug in the UART and is somewhat tolerant of some
interrupt latency in the environment which might occasionally cause loss
of interrupts. I'm still attempting to find a simple and elegant workaround 
to this problem that I'm completely comfortable with.


>   I've also noticed, that on turning the modem OFF, the DCD,
>   and other bits in the Modem Status Register get set, resulting
>   in me returning a false result.

That's simply the modem.  The powerdown does this on many of them.


>   Assuming that DCD always reflects the true state of the
>   carrier, how could I avoid the above problem ?

Not a real problem since you'll find DCD will almost immediately (well,
I guess 'immediately' in terms of an ISR is a long time...) drop again.


>   Any help, and references would be greatly appreciated.

Hope this helps.  The above is the result of a long long battle with
these damned UART thingies over around 3 years off and on. :-)


Regards,

  david

randys@cpqhou.uucp (Randy Spurlock) (01/16/91)

in article <2535@sparko.gwu.edu>, viraf@seas.gwu.edu (Viraf Bankwalla) says:
> 
> Hi,
> 
>	***** 8250 Interrupt Description Deleted *****
> 
>   Say I'm in my isr, processing Receive Data Available,
>   and the modem status changes, am I interrupted, or
>   will I notice the change the next time I poll the
>   IIR in the loop, as I havn't issued the End Of Interrupt ?

	It depends on the order of things done in your interrupt routine,
if you have already issued the EOI to the interrupt controller the 8250
will still NOT generate an interrupt until you clear the receive data
interrupt by reading the data register. Also I have noticed that more 
than one interrupt condition can occur at the same time and this condition
will *****NEVER***** generate more than ONE interrupt to the interrupt
controller, therefore you should ALWAYS loop back to the start of the
interrupt handler and check the 8250 for more interrupt conditions pending
or you could wind up hanging your 8250, I know it happened to me!

> 
>   I've also noticed, that on turning the modem OFF, the DCD,
>   and other bits in the Modem Status Register get set, resulting
>   in me returning a false result.
>   Assuming that DCD always reflects the true state of the
>   carrier, how could I avoid the above problem ?
> 

	The DCD is Delta Carrier Detect, not actual Carrier Detect (CD)
this bit in the modem status is used to indicate that the carrier detect
signal has changed state and should be checked.

>   Any help, and references would be greatly appreciated.
> 

	You should get a data sheet on the Intel 8250 or any other 
company that made and 8250 compatible device, i.e., Motorola, Western
Digital, etc. The data sheet, although not the best written or easy to
understand usually has the most complete information.

>   Thanks in advance.

	I have a very old (Vintage 1985) MS-DOS serial device driver 
that supports interrupt driven serial communications that I could e-mail
to you if you are interested in examining an 8250 interrupt routine.

> 
>   viraf bankwalla
>   viraf@seas.gwu.edu
>   ...!uunet!gwusun!viraf


=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
          - Randy Spurlock -	      |      Compaq Computer Corporation    
---------------------------------------------------------------------------
These opinions are mine...all mine... | He fired his hyper-jets and...  
just ask anyone who's heard them!     | blasted into the 5th dimension!
--------------------------------------| 
UUCP: ...!uunet!cpqhou!randys         |                     Space Man Spiff
=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= 

resnicks@netcom.UUCP (Steve Resnick) (01/16/91)

In article <1991Jan15.160612.7474@cpqhou.uucp> randys@cpqhou.uucp (Randy Spurlock) writes:
[Lots of stuff delete]
>	You should get a data sheet on the Intel 8250 or any other 
>company that made and 8250 compatible device, i.e., Motorola, Western
>Digital, etc. The data sheet, although not the best written or easy to
>understand usually has the most complete information.
>

Whoa! The INTEL 8250 is a UART, but it is NOT INS8250 compatible. What you
want is the Data sheet for an INS8250 or WD8250, I don't know whether
Morotola makes a PC compatible 8250 or not, but the Intel unit is NOT the
same device. (I found this out by writing a serial driver using the
Intel data sheet from their Microprocessors and Peripherals handbook and
had to undo a lot of code. *sigh*)

- Steve

-- 
-------------------------------------------------------------------------------
resnicks@netcom.com, stever@octopus.com, steve.resnick@f105.n143.z1.FIDONET.ORG
apple!camphq!105!steve.resnick, {apple|pyramid|vsi1}!octopus!stever
- In real life: Steve Resnick. Flames, grammar and spelling errors >/dev/null
0x2b |~ 0x2b, THAT is the question.
-------------------------------------------------------------------------------