Path: utzoo!attcan!utgpu!jarvis.csri.toronto.edu!mailrus!csd4.milw.wisc.edu!cs.utexas.edu!uunet!mcvax!unido!rwthinf!franke From: franke@rwthinf.UUCP (Christian Franke) Newsgroups: comp.sys.ibm.pc Subject: HELP! Interrupts on COM ports Keywords: COM port, Interrupt, Device Driver Message-ID: <1137@rwthinf.UUCP> Date: 18 Jul 89 08:39:03 GMT Organization: RBI - RWTH Aachen Lines: 106 I've written a interrupt driver for the COM{12} ports of an AT. If the receiver side uses interrupts and the transmitter side uses polling, everything is OK. If the transmitter uses interrupts also, the following problem occurs: When the transmitter and the receiver interrupts occur simultaneously, then sometimes the transmitter interrupt is lost: The IIR register of the 8250 does not report "Transmitter empty interrupt" after the "Receiver data available interrupt" has been processed. Both (8250 internal) interrupts should occur during the same hardware interrupt cycle of the 8259. After this situation, the LSR of the 8250 correctly reports "transmitter ready" (bit 5). Is that a problem with the edge-sensitive mode of the 8259? Here is a fragment of the interrupt routine (MS-C 5.1): -------------------------------------- /* 8250 Communikations Controller Port Offsets */ #define THR 0xf8 /* Transmitter holding register w/o */ #define RBR 0xf8 /* Receiver buffer register r/o */ #define IER 0xf9 /* Interrupt enable register */ #define IIR 0xfa /* Interrupt identification register */ #define LCR 0xfb /* Line control register */ #define MCR 0xfc /* Modem control register */ #define LSR 0xfd /* Line status register */ #define MSR 0xfe /* Modem status register */ /* 8259 Interrupt Controller Port Numbers */ #define ICC 0x20 /* Control word register */ #define ICM 0x21 /* Interrupt mask register */ #define COMx 0x0300 /* Port base address */ #define IRQx 4 /* Hardware interrupt number */ /* COM interrupt handler routine */ static void interrupt far ComIntHandler(void) { register unsigned char ch; /* Determine interrupt source */ for (;;) switch (inp(COMx+IIR)) { case 0x6: /* * Receiver line status interrupt */ ch = inp(COMx+LSR); /* get status, clear interrupt */ /* .... */ break; case 0x4: /* * Receiver data available interrupt */ ch = inp(COMx+RBR); /* get character, clear interrupt */ /* ... queue data ... */ break; case 0x2: /* * Transmitter empty interrupt * (interrupt cleared by read of IIR) */ if (/* Data available in queue */) /* Send next character from queue */ outp(COMx+THR,/* Next char in queue */); break; case 0x0: /* * Modem status interrupt */ ch = inp(COMx+MSR); /* get status, clear interrupt */ /* ... */ break; /* case 0x1: */ default: /* * No interrupt from COM port */ outp(ICC,0x20); /* Say 8259: End of Interrupt */ return; } /*NOTREACHED*/ } ------------------------------ Perhaps someone can help me. Thanks in advance Christian Franke Aachen University of Technology Lehrstuhl fuer Informatik I Ahornstrasse 55 D-5100 Aachen Federal Republic of Germany Tel.: 0241 / 80-3586 UUCP: franke@rwthinf.uucp ({...mcvax}!unido!rwthinf!franke)