www.delorie.com/archives/browse.cgi   search  
Mail Archives: djgpp/1999/08/18/06:58:09

Message-Id: <199908180539.IAA10495@ankara.Foo.COM>
From: "S. M. Halloran" <mitch AT duzen DOT com DOT tr>
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
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

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

- Raw text -


  webmaster     delorie software   privacy  
  Copyright © 2019   by DJ Delorie     Updated Jul 2019