gordon@vaxeline.COM (Gordon Lee) (10/30/90)
I have encountered some ambiguity in the IBM AT Tech Ref concerning the interaction between the 8250 and 8259 PIC chip. The 8250 generates four types of interrupt, namely: Modem Status, Receive, Transmit Completion, and Line Status. To service an interrupt, the interrupt handling routine must read the Interrupt Identification Register (IIR) to demux on the type of interrupt. This much is fairly clear. My Interrupt Service Routine (ISR) is currently defficient in that it can miss a transmit completion, thereby wedging my outgoing data stream. This only happens under heavy bidirectional traffic, which leads me to believe that my ISR is losing when a transmit completion intr and a receive intr happen "simultaneously". I think my routine is handling the receive interrupt while allowing the transmit completion interrupt to drop on the floor. Under a description of the IIR, the Tech Ref says: "When the IIR is addressed, the pending interrupt with the highest priority is held and no other interrupts are acknowledged until the microprocessor services that interrupt." I interpret that as follows: - more than one interrupt type can be pending at once - of the interrupts pending, the IIR returns that which has the highest priority, and occured before any other interrupts of the same type What I have not been able to determine, is exactly what condition/state constitutes "(when the) microprocessor services that interrupt". I also cannot determine what my issuing a specific EOI to the PIC will do to the state of the machine. And above all, I cannot determine how interrupts of other types are dealt with while my ISR is executing. The crux of what I need to know and what the manual doesn't want to tell me is: how to cleanly service a single physical interrupt which is signalling the occurence of more than one type of UART interrupt condition. I also need to know how to expect a subsequent interrupt while I am in my service routine, and the proper way to acknowledge to the PIC notification of multiple "simultaneous" interrupts. Any advice or pointers would be much appreciated. -- ========================================================================== Gordon Lee Member, Technical Staff FTP Software, Inc. (617) 246-0900 x287
markd@silogic.UUCP (Mark DiVecchio) (11/05/90)
In <1210@vaxeline.COM> gordon@vaxeline.COM (Gordon Lee) writes: > My Interrupt Service Routine (ISR) is currently defficient in that it > can miss a transmit completion, thereby wedging my outgoing data stream. I had this problem here is a summary of what I found (take directly from the source file of my program PC-VT : ; There is problem with the 8250-A USART chips in the ; PC and PC compatible communications ports. The problem is that if ; there are several stacked interrupts, only the highest priority ; one is ever processed. PC-VT will just hang up waiting for the ; others. The 8250 and 8250-B work fine in the PC. ; ; I have rewritten PC-VT to only use one interrupt, the Data Ready ; interrupt. This should reduce the problem considerably. ; ; The problem is not "in" the 8250 but is in the interface between the ; 8250 and the 8259. The 8259 is operated in edge-trigger mode, but some ; of the versions of the 8250 do not drop their interrupt line if several ; interrupts are stacked up. Thus the 8259 never "sees" them. ; Specifically, the 8250 and 8250-B do "glitch" their interrupt lines. ; The 8250-A does not. Therefore, if you have a PC with an 8250-A, PC-VT ; would regularly hangup. ; ; In the PC AT, the problem compounds. The AT uses the new Serial ; chip from National, the 16450. All I know at this point, is that ; with only one interrupt, PC-VT works ok on the AT ; ; I would like to thank Marty in the applications department at ; National Semi in Santa Clara for his help. Two relevant documents ; from NSC are B01361 and B01511-1 ; -- Mark DiVecchio, Silogic Systems, 619-549-9841 K3FWT ----- 9888 Carroll Center Road, Suite 113, San Diego, CA 92126 ----- markd@silogic.uucp BBS 619-549-3927 ...!ucsd!celit!silogic!markd celit!silogic!markd@ucsd.edu
david@csource.oz.au (david nugent) (11/06/90)
In <1210@vaxeline.COM> gordon@vaxeline.COM (Gordon Lee) writes: > My Interrupt Service Routine (ISR) is currently defficient in that it > can miss a transmit completion, thereby wedging my outgoing data stream. > This only happens under heavy bidirectional traffic, which leads me to > believe that my ISR is losing when a transmit completion intr and a receive > intr happen "simultaneously". I think my routine is handling the receive > interrupt while allowing the transmit completion interrupt to drop on > the floor. You are no doubt absolutely correct. This is a real pain, and somewhat of an "undocumented feature" of most UARTS. Even 16550A series UARTS have the same problem. > > [....] > > The crux of what I need to know and what the manual doesn't want > to tell me is: how to cleanly service a single physical interrupt > which is signalling the occurence of more than one type of UART > interrupt condition. I also need to know how to expect a subsequent > interrupt while I am in my service routine, and the proper way to > acknowledge to the PIC notification of multiple "simultaneous" interrupts. Ok, within the ISR the state of the PIC is irrelevent except that it's always a good idea, however, to rearm the PIC as soon as possible (assuming you're working in a standard PC/AT edge triggered non-autoEOI mode). Within a communications ISR, you simply loop back and re-test the UART's IID register for new interrupts - you've probably done this. The "bug" I refer to above is within the UART itself - it will not recognise lower priority interrupts (ie. modem status changes and transmit empty) when servicing interupts of a higher priority. Wonderful design. :-( If your ISR depends on getting each and every transmit interrupt, one such missing interrupt causes a transmitter "freeze". Only by actually sending another character can you restart it. A partial solution is to read the line status register on the way out of the ISR, and loop back of a) there are any characters in your software transmit queue, and b) if the transmit holding register bit is empty. Partial, I say, because it's not entirely reliable. The INS8250 lies through it's teeth - it often says it's empty when it isn't, resulting in loss of characters in the transmit stream since the ISR stuffs something into the THR when it isn't really empty. Most other UARTs I've come across don't suffer this same problem, so it should work just fine. The best solution I've come up with is to disable transmitter interrupts by masking out the appropriate bit in the IED, then masking it again - immediately before servicing the higher priority interrupts - receive data available, and on delta receive line status. This does effectively prevent the UART not noticing that the transmit holding register becomes empty while within the service routine. I've used this technique with great success, and some more. The transmitter I've developed is now entirely driven by the transmit enable bit of the IER; and relies on the feature in UARTS that triggers a THRE interrupt whenever that bit is set while the transmit holding register is empty. That makes it entirely possible to limit all UART I/O to within the interrupt service code. There's probably not enough bandwidth here for further expansion on the subject and all the horror stories I could tell you about it, so email if you need any further clarification or help. - david -- Fidonet: 3:632/348 SIGnet: 28:4100/1 Imex: 90:833/387 Data: +61-3-885-7864 Voice: +61-3-826-6711 Internet/ACSnet: david@csource.oz.au Uucp: ..!uunet!munnari!csource!david