Postpone interrupts on LPC21xx

Started by Jan Thogersen September 1, 2006
Hi all,

I have a software fifo that is being filled up by my main loop and then
grabbed by an interrupts routine (TMR0). When entering the function that
pushes a value onto the fifo I have to disable the TMR0 interrups to
avoid that the interrupt routine breaks into the push algorithm and
messes up the fifo pointer before the push algorithm is done.
But by doing that I looses some TMR0 interrupts... Here is what I do...

uint8 DAC_fifo_put(int16 *X, int16 *Y) {
register uint8 bufpos = buf_inpos, ucT0MCR;

ucT0MCR = T0MCR; // Remember the state of the
Timer Interrupt
T0MCR &= ~T0MCR_MR0I; // Disable the Timer interrupt
if (bufpos == ((buf_outpos - 1) & (pointbuf_size-1))) {
// The fifo is full
T0TCR = T0TCR_Counter_Enable; // The buffer is full so start
timer 0
T0MCR |= T0MCR_MR0I; // Enable the Timer interrupt
return(0);
}
PointFIFO.pointbuf[bufpos].X = *X;
PointFIFO.pointbuf[bufpos].Y = *Y;
bufpos = (bufpos + 1) & (pointbuf_size-1);
buf_inpos = bufpos;

T0MCR = ucT0MCR; // Set the reg back to it's entry
state
return(1);
}

Is it possible to just postpone the interrupt so if the interrupt flag
(while disabled) is set by the timer it will execute the timer interrupt
as soon as the timer 0 interrupt is re-enabled?

It's was very easy in the days where I worked with Atmel AVR, so I guess
it's possible on the ARM as well.

Thanks in advance...!

Regards
Jan

An Engineer's Guide to the LPC2100 Series

--- In l..., Jan Thogersen wrote:

Hi Jan,

I had simular problems in my projects. Didn't liked the idea to
disable all the interrupts when accessing shared data for a single
resource. Experienced the same problems as you (also on the serial
ports and others). I now disable/enable the interrupts on the VIC and
that works fine for me. I've attached the code I'm currently using.
Read the note for disabling the interrupt - more info on this in the
VIC reference manual for the ARM7.

Regards,

Patrick

tpVoid TimersL1DisableInterrupts()
{
/* Disable vector interrupt for
UART0. */
VICIntEnClear = 1 << VIC_TIMER1;

/* Due to the pipelined architecture an interrupt could still
occure within 13 cycles after writing
* the VIC register.
* Keep CPU busy until we are sure that no interrupt will
come trough
*/
__asm("NOP");
__asm("NOP");
__asm("NOP");
__asm("NOP");
__asm("NOP");
__asm("NOP");
__asm("NOP");
__asm("NOP");
__asm("NOP");
__asm("NOP");
__asm("NOP");
__asm("NOP");
__asm("NOP");
__asm("NOP");
__asm("NOP");
}

tpVoid TimersL1EnableInterrupts()
{
/* Enable vector interrupt for
UART0. */
VICIntEnable = (1 << VIC_TIMER1);
}

>
> Hi all,
>
> I have a software fifo that is being filled up by my main loop and
then
> grabbed by an interrupts routine (TMR0). When entering the function
that
> pushes a value onto the fifo I have to disable the TMR0 interrups
to
> avoid that the interrupt routine breaks into the push algorithm and
> messes up the fifo pointer before the push algorithm is done.
> But by doing that I looses some TMR0 interrupts... Here is what I
do...
>
> uint8 DAC_fifo_put(int16 *X, int16 *Y) {
> register uint8 bufpos = buf_inpos, ucT0MCR;
>
> ucT0MCR = T0MCR; // Remember the state of
the
> Timer Interrupt
> T0MCR &= ~T0MCR_MR0I; // Disable the Timer
interrupt
> if (bufpos == ((buf_outpos - 1) & (pointbuf_size-1))) {
> // The fifo is full
> T0TCR = T0TCR_Counter_Enable; // The buffer is full so
start
> timer 0
> T0MCR |= T0MCR_MR0I; // Enable the Timer
interrupt
> return(0);
> }
> PointFIFO.pointbuf[bufpos].X = *X;
> PointFIFO.pointbuf[bufpos].Y = *Y;
> bufpos = (bufpos + 1) & (pointbuf_size-1);
> buf_inpos = bufpos;
>
> T0MCR = ucT0MCR; // Set the reg back to it's
entry
> state
> return(1);
> }
>
> Is it possible to just postpone the interrupt so if the interrupt
flag
> (while disabled) is set by the timer it will execute the timer
interrupt
> as soon as the timer 0 interrupt is re-enabled?
>
> It's was very easy in the days where I worked with Atmel AVR, so I
guess
> it's possible on the ARM as well.
>
> Thanks in advance...!
>
> Regards
> Jan
>