Message-Id: <199908180539.IAA10495@ankara.Foo.COM> From: "S. M. Halloran" Organization: User RFC 822- and 1123-compliant To: djgpp AT delorie DOT com Date: Wed, 18 Aug 1999 09:45:32 +0200 MIME-Version: 1.0 Content-type: text/plain; charset=US-ASCII Content-transfer-encoding: 7BIT Subject: Re: COM port interrupts don't happen? In-reply-to: <7pcqfj$flj@tandem.CAM.ORG> X-mailer: Pegasus Mail for Win32 (v3.12) Reply-To: djgpp AT delorie DOT com X-Mailing-List: djgpp AT delorie DOT com X-Unsubscribes-To: listserv AT delorie DOT com Precedence: bulk On 17 Aug 99, Martin Peach was found to have commented thusly: > I'm trying to process received characters from COM1. I have set up the UART and > can receive OK by polling the device. I have set up a protected-mode interrupt > routine which works fine if I assign INT0 (timer) interrupt to it. When I assign > IRQ4 (INT0x0C, COM1) to it, nothing happens. The interrupt identification > register says there is an interrupt pending when I poll it, the PIC mask has the > corresponding bit cleared, the CPU ints are enabled using enable(), but my > service routine is never called. Is this normal? I've tried this on a 486 and a > pentium machine with identical results. What am I missing here? There are a great many things to contend with in getting bytes read in from the UART. I have a general checklist for the open/read/write/close and interrupt service handler routines, and there are some modifications when wondering about using real- or protected-mode handlers and having to lock the memory of the handler *and* the read/write circular buffers that the interrupt handler deals with. I might have some recommendations/questions here: * In your open routine, do you first set IER to 0 then set IER to 3 after setting the LCR to 0x7f to turn off the latch? This might be done with interrupts disabled and after you set the vector to the new interrupt handler and lock its memory. * You might follow this with a loop that reads in your base, your LSR, and your MSR in that sequence as long as IIR & 0x01 == 0, to clear out these registers of things that fill them up. * You might then set your MCR to activate the OUT2 line (as DTR and RTS) and baud after setting the latch in the LCR, then enable interrupts. Your interrupt handler should take care to set up a loop to always test the IIR for all four types of interrupts if you have enabled them: moving bytes coming in from the UART to the read buffer, checking for bytes to be written out, clearing and reporting the MSR and LSR if necessary. Then just before leaving your ISR, you should do the following: 1. signal the PIC of an end-of-interrupt (EOI) 2. make sure the OUT2 line is set in the MCR 3. finally, create an interrupt edge by setting the IER to zero after getting its present value, then re-setting. The code at the end of your ISR might look something like this: outportb(0x20, 0x20); outportb(MCR, inportb(MCR) | OUT2); currentIERvalue = inportb(IER); outportb(IER, 0); outportb(IER, currentIERvalue); This code has worked for me in the past. > \/\/\/*= Martin > Mitch Halloran Research (Bio)chemist Duzen Laboratories Group Ankara TURKEY