Mail Archives: djgpp/1999/08/18/06:58:09
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 -