Forums

Interrupt pending but not raised

Started by andersryl December 6, 2005
Hi,

I have a very peculiar problem regarding interrupts on my Olimex
E2214 board (using gcc and gld with Eclipse).

I'm trying to get my board to communicate with a Windows application
using the UART1. The way it works is that the Win app sends frames
with commands to the test board to which the ARM responds by sending
a new frame back to the PC. I have set the UART1 to give interrupts
when the RxFIFO is filled with 8 bytes.

Each frame consists of 12 to 100 bytes (11 bytes header and 1-89
bytes of data).

The communication works fine the first 4 rounds (request+reply).

However the fifth time the Win app starts sending a "request-frame"
the ARM does not generate any interrupts. I can see that there are
interrupts pending (by debug print-outs with the other UART from a
busy-waiting loop*) and that the peripherals that should give
interrupts are enabled to do so.

I also have a timer running giving an interrupt after 2 seconds if
no data is received (should not happen in normal operation due to
frequent requests from the Win app). This timer interrupt works fine
until the Win app starts sending frames. After the last request
(as described above) this interrupt is also pending but no interrupt
is raised.

From debug print-outs from the ISRs I also see that I never leave my
two ISRs (One for UART1 and one for Timer0) with any interrupts
pending.

*) Debug print-outs after the fifth Win app request frame:
VICIRQStatus: 0x00000080
VICIntEnable: 0x00000090
VICVectAddr: 0x000000D4
T0IR: 0x00
T0TCR: 0x01
T0MCR: 0x0003
U1IIR: 0xC4

VICIRQStatus: 0x00000090
VICIntEnable: 0x00000090
VICVectAddr: 0x00000000
T0IR: 0x01
T0TCR: 0x01
T0MCR: 0x0003
U1IIR: 0xC4

Sorry about the long post.
Any help is greatly accepted.

/Anders


An Engineer's Guide to the LPC2100 Series

On the first thought you have problems in your ISR's.
Perhaps you are not correctly handle and acknowledge
IRQ's.
Be sure that before exiting the ISR you are correctly
clearing the interrupt flags in the peripheral
registers(UART and Timer) and that you have a write to
the VICVectAddr register in the VIC in order to update
the VIC priority.

Hope this helps.

Zdravko

--- andersryl <andersryl@ande...> wrote:

> Hi,
>
> I have a very peculiar problem regarding interrupts
> on my Olimex
> E2214 board (using gcc and gld with Eclipse).
>
> I'm trying to get my board to communicate with a
> Windows application
> using the UART1. The way it works is that the Win
> app sends frames
> with commands to the test board to which the ARM
> responds by sending
> a new frame back to the PC. I have set the UART1 to
> give interrupts
> when the RxFIFO is filled with 8 bytes.
>
> Each frame consists of 12 to 100 bytes (11 bytes
> header and 1-89
> bytes of data).
>
> The communication works fine the first 4 rounds
> (request+reply).
>
> However the fifth time the Win app starts sending a
> "request-frame"
> the ARM does not generate any interrupts. I can see
> that there are
> interrupts pending (by debug print-outs with the
> other UART from a
> busy-waiting loop*) and that the peripherals that
> should give
> interrupts are enabled to do so.
>
> I also have a timer running giving an interrupt
> after 2 seconds if
> no data is received (should not happen in normal
> operation due to
> frequent requests from the Win app). This timer
> interrupt works fine
> until the Win app starts sending frames. After the
> last request
> (as described above) this interrupt is also pending
> but no interrupt
> is raised.
>
> From debug print-outs from the ISRs I also see that
> I never leave my
> two ISRs (One for UART1 and one for Timer0) with any
> interrupts
> pending.
>
> *) Debug print-outs after the fifth Win app request
> frame:
> VICIRQStatus: 0x00000080
> VICIntEnable: 0x00000090
> VICVectAddr: 0x000000D4
> T0IR: 0x00
> T0TCR: 0x01
> T0MCR: 0x0003
> U1IIR: 0xC4
>
> VICIRQStatus: 0x00000090
> VICIntEnable: 0x00000090
> VICVectAddr: 0x00000000
> T0IR: 0x01
> T0TCR: 0x01
> T0MCR: 0x0003
> U1IIR: 0xC4
>
> Sorry about the long post.
> Any help is greatly accepted.
>
> /Anders

__________________________________________
Yahoo! DSL Something to write home about.
Just $16.99/mo. or less.
dsl.yahoo.com


Thanks for your reply.

The fact that the ISR's servicing the interrupts from both UART1 and
Timer0 work up to a certain point makes me think that the ISR's are
working properly. I'm not 100% sure though...

Here is the code for the ISR's if anyone wants to have a look:

irq.s:
*******************************
UART1_Routine: subs lr, lr, #4
stmfd sp!, {R0-R12, lr}
ldr r4, =UART1Handler
mov lr, pc
bx r4

ldmfd sp!, {R0-R12, pc}^
/* End UART1_Routine */

Timer0_Routine: subs lr, lr, #4
stmfd sp!, {R0-R12, lr}
ldr r4, =Timer0Handler
mov lr,pc
bx r4

ldmfd sp!, {R0-R12, pc}^
/* End Timer0_Routine */
******************************* main.c:
*******************************
void UART1Handler (void) {
BYTE stat;
WORD i;
stat = U1IIR & 0x0F;

while (stat != 1) {
switch (stat) {
case 4: /* Rx FIFO filled to threshold level. Read bytes */
for (i=0; i<RX_FIFO_THRESHOLD; i++) {
uart0RxBuffer[uart0RxByteCounter++ % uart0RxBufferSize]
= U1RBR;
}
break;
case 12: /* Old bytes still in RX FIFO. Read the bytes */
while ((U1LSR & 0x01) == 1) {
uart0RxBuffer[uart0RxByteCounter++ % uart0RxBufferSize]
= U1RBR;
}
break;
default: /* Unidentified interrupt cause */
sendString("Error:"); /* Debug print-out */
sendString(stat); /* Debug print-out */
break;
}

stat = U1IIR & 0x0F;
}

VICVectAddr = 0; // Enable new IRQ-interrupts

return;
}

void Timer0Handler (void) {
T0TCR = 0x03; // Reset and stop timer0

switch (T0IR) {
case 1: // MR0 interrupt
T0IR = 0x01; // Clear MR0 interrupt
sendString("Time out"); // Debug print-out
break;
default: // Other interrupt
T0IR = 0xFF; // Clear the generating interrupt
sendString("Undefined"); // Debug print-out
break;
}

T0TCR = 0x01; // Restart timer0
VICVectAddr = 0; // Enable new IRQ-interrupts

return;
}
*******************************

Am I missing something?

/Anders

--- In lpc2000@lpc2..., 3gpabko <zdravko_k_d@y...> wrote:
>
> On the first thought you have problems in your ISR's.
> Perhaps you are not correctly handle and acknowledge
> IRQ's.
> Be sure that before exiting the ISR you are correctly
> clearing the interrupt flags in the peripheral
> registers(UART and Timer) and that you have a write to
> the VICVectAddr register in the VIC in order to update
> the VIC priority.
>
> Hope this helps.
>
> Zdravko
>
> --- andersryl <andersryl@y...> wrote:
>
> > Hi,
> >
> > I have a very peculiar problem regarding interrupts
> > on my Olimex
> > E2214 board (using gcc and gld with Eclipse).
> >
> > I'm trying to get my board to communicate with a
> > Windows application
> > using the UART1. The way it works is that the Win
> > app sends frames
> > with commands to the test board to which the ARM
> > responds by sending
> > a new frame back to the PC. I have set the UART1 to
> > give interrupts
> > when the RxFIFO is filled with 8 bytes.
> >
> > Each frame consists of 12 to 100 bytes (11 bytes
> > header and 1-89
> > bytes of data).
> >
> > The communication works fine the first 4 rounds
> > (request+reply).
> >
> > However the fifth time the Win app starts sending a
> > "request-frame"
> > the ARM does not generate any interrupts. I can see
> > that there are
> > interrupts pending (by debug print-outs with the
> > other UART from a
> > busy-waiting loop*) and that the peripherals that
> > should give
> > interrupts are enabled to do so.
> >
> > I also have a timer running giving an interrupt
> > after 2 seconds if
> > no data is received (should not happen in normal
> > operation due to
> > frequent requests from the Win app). This timer
> > interrupt works fine
> > until the Win app starts sending frames. After the
> > last request
> > (as described above) this interrupt is also pending
> > but no interrupt
> > is raised.
> >
> > From debug print-outs from the ISRs I also see that
> > I never leave my
> > two ISRs (One for UART1 and one for Timer0) with any
> > interrupts
> > pending.
> >
> > *) Debug print-outs after the fifth Win app request
> > frame:
> > VICIRQStatus: 0x00000080
> > VICIntEnable: 0x00000090
> > VICVectAddr: 0x000000D4
> > T0IR: 0x00
> > T0TCR: 0x01
> > T0MCR: 0x0003
> > U1IIR: 0xC4
> >
> > VICIRQStatus: 0x00000090
> > VICIntEnable: 0x00000090
> > VICVectAddr: 0x00000000
> > T0IR: 0x01
> > T0TCR: 0x01
> > T0MCR: 0x0003
> > U1IIR: 0xC4
> >
> > Sorry about the long post.
> > Any help is greatly accepted.
> >
> > /Anders
> >
> >
> >
> >
> >
>
> __________________________________________
> Yahoo! DSL Something to write home about.
> Just $16.99/mo. or less.
> dsl.yahoo.com
>




andersryl wrote:

>Thanks for your reply.
>
>The fact that the ISR's servicing the interrupts from both UART1 and
>Timer0 work up to a certain point makes me think that the ISR's are
>working properly. I'm not 100% sure though...
>
>Here is the code for the ISR's if anyone wants to have a look:
>main.c:
>*******************************
>void UART1Handler (void) {
> BYTE stat;
> WORD i;
> stat = U1IIR & 0x0F;
>
> while (stat != 1) {
> switch (stat) {
> case 4: /* Rx FIFO filled to threshold level. Read bytes */
> for (i=0; i<RX_FIFO_THRESHOLD; i++) {
> uart0RxBuffer[uart0RxByteCounter++ % uart0RxBufferSize]
>= U1RBR;
> }
> break;
> case 12: /* Old bytes still in RX FIFO. Read the bytes */
> while ((U1LSR & 0x01) == 1) {
> uart0RxBuffer[uart0RxByteCounter++ % uart0RxBufferSize]
>= U1RBR;
> }
> break;
> default: /* Unidentified interrupt cause */
> sendString("Error:"); /* Debug print-out */
> sendString(stat); /* Debug print-out */
> break;
> }
>
> stat = U1IIR & 0x0F;
> }
>
> VICVectAddr = 0; // Enable new IRQ-interrupts
>
> return;
>}
FWIW, I'd declare stat as volatile:

volatile BYTE stat;

Just to ensure it isn't going to get optimized into a static (assumed
unchanging) value.

TomW --
Tom Walsh - WN3L - Embedded Systems Consultant
http://openhardware.net, http://cyberiansoftware.com
"Windows? No thanks, I have work to do..."
----------------


Oh my God!

I was so sure that there was "something going on behind the
curtains" I didn't understand that I didn't even bother to check any
code "not near" the ISR's.

Apparently I had disabled both IRQ and FIQ...

Shame on me. :(

/Anders

--- In lpc2000@lpc2..., Tom Walsh <tom@o...> wrote:
>
> andersryl wrote:
>
> >Thanks for your reply.
> >
> >The fact that the ISR's servicing the interrupts from both UART1
and
> >Timer0 work up to a certain point makes me think that the ISR's
are
> >working properly. I'm not 100% sure though...
> >
> >Here is the code for the ISR's if anyone wants to have a look:
> >main.c:
> >*******************************
> >void UART1Handler (void) {
> > BYTE stat;
> > WORD i;
> > stat = U1IIR & 0x0F;
> >
> > while (stat != 1) {
> > switch (stat) {
> > case 4: /* Rx FIFO filled to threshold level. Read
bytes */
> > for (i=0; i<RX_FIFO_THRESHOLD; i++) {
> > uart0RxBuffer[uart0RxByteCounter++ %
uart0RxBufferSize]
> >= U1RBR;
> > }
> > break;
> > case 12: /* Old bytes still in RX FIFO. Read the
bytes */
> > while ((U1LSR & 0x01) == 1) {
> > uart0RxBuffer[uart0RxByteCounter++ %
uart0RxBufferSize]
> >= U1RBR;
> > }
> > break;
> > default: /* Unidentified interrupt cause */
> > sendString("Error:"); /* Debug print-out */
> > sendString(stat); /* Debug print-out */
> > break;
> > }
> >
> > stat = U1IIR & 0x0F;
> > }
> >
> > VICVectAddr = 0; // Enable new IRQ-interrupts
> >
> > return;
> >}
> >
> >
> FWIW, I'd declare stat as volatile:
>
> volatile BYTE stat;
>
> Just to ensure it isn't going to get optimized into a static
(assumed
> unchanging) value.
>
> TomW > --
> Tom Walsh - WN3L - Embedded Systems Consultant
> http://openhardware.net, http://cyberiansoftware.com
> "Windows? No thanks, I have work to do..."
> ----------------
>