Sign in

username or email:

password:



Not a member?
Forgot your Password?

Search lpc2000



Search tips

Subscribe to lpc2000



Discussion Groups

See Also

DSPFPGA

Discussion Groups | LPC2000 | timer0 interrupt eventually hangs

Discussion group dedicated to the Philips LPC2000 family of ARM MCUs


So far in May, you have voted 0 times ou of a total of 20 votes by the community.
Please help us clean the archives from unuseful discussion threads by using the voting system! Details here.


Is this thread worth a thumbs up?

0

timer0 interrupt eventually hangs - frantechman - Apr 17 19:16:09 2010


Hi all,

I'm a newby to Keil tools, lpc2138 microcontroller, and C programming
language. I'm doing this on a Keil MCB2130 dev board. I have some code
that I have either pieced together or wrote that works for a bit and
then stops. I have been reading, researching, debugging, and trial and
erroring it for about 2 weeks and I just can't seem to solve it. I set
up timer0 for interrupts to kick off the A2D. The timer count is a
number that is derived from a number that is recieved from an I2C
master. The lpc2138 is configured as an I2C slave using the app note
from NXP (TN06005). I wouldn't have thought this would be too difficult
as interrupts for the I2C code and for timer0 do not occur at the same
time. Therefore I have tried disabling I2C interrupts and only
re-enabling them right before it is required. And the same with timer0,
I enable it right before it is needed and then disable them after the
function is completed. Whether I do this or just leave both enabled from
the start I end up with the same results. The I2C communication never
fails however, it appears that timer0 interrupts will fail to occur at
the same point. When it fails, after the command to enable timer0
interrupt occurs, it is stuck in a Do-While loop waiting for an
interrupt that never happens. I don't know much yet about using the
debugger but when I stop it when it fails, it is always at this point. I
put a couple of statements in the timer0 isr to turn on and off an LED
and it does not light when it fails again further confirming to me that
the interrupt is failing. Being an absolute novice I don't doubt that I
am missing something very basic but I just don't see it. I would
appreciate it if anyone could take a look at it and see if you spot
anything that may be causing this. Once this is solved, everything is
working fine. I just don't know why, seemingly randomly, the interrupt
for timer0 would quit working. I will try to attach what I think is
just the pertinent parts of my code.

Thanks,

Fran

// This routine intializes the timer0 interrupt

void timer0_init(void)

{

T0MR0 = sample_time; // This is varied and set up by the I2C value
received

T0MCR = 3; // timer 0 triggers on match and resets itself

T0TCR = 1; // start the clock

VICVectAddr0 = (unsigned long) tc0;

VICVectCntl0 = 0x20 | 4;

}

// This is the start of a function that starts timer0 interrupting and
then disables it when it is complete

void calculate(void)

{

VICIntEnable = (1 << 4); // start sampling

do

{

// Pertinent code goes here.

}

}

while(counter < CYCLE_COUNT);

VICIntEnClr = (1 << 4); // stop interrupting

// This is the pertinent part of timer0 ISR

void tc0 (void) __irq

// Timer 0 interrupt routine

{

LED_on(); //*** here for testing purposes only

// ISR related code for sampling the A2D here

LED_off(); //*** here for testing purposes only

T0IR = 0x01; // clear the flag

VICVectAddr = 0;

}

// Note that this is NXP code from their appnote, because their example
used Addr0,

// I changed it to 1 as timer0 needs to be highest priority, once I get
this working

// I will try and change timer0 interrupts to FIQ as my understanding is
that will reduce latency.

void I2C0_Init(void)

{

PINSEL0 |= 0x50; // P0.3 = SDA, P0.2 = SCL

I2C0ADR = 0xD0; // set I2C slave address

I2C0CONSET = 0x44; // enable I2C hardwar and set AA (ack)

I2C0SCLH=0x4B; // 100 KHz 0x4B

I2C0SCLL=0x4B; // 0x4B

VICVectAddr1 = (unsigned int) &I2C0_Isr;

VICVectCntl1 = 0x29; // Channel1 on Source#9 ... enabled

VICIntEnable |= 0x200; // 9th bit is the I2C

}

// This is the ISR for I2C slave communications out of the NXP app note

void I2C0_Isr(void) __irq

{

unsigned char st;

st = I2C0STAT;

I2C0CONCLR = 0x2C; // clear STA, AA and SI

switch(st)

{

case 0x60: // own SLA+W received, Ack returned (slave
receiver)

case 0x68: // Addressed as slave

I2C0CONSET = 0x04; // set AA, return ACK on first byte

break;

case 0x80: // Data received, ACK returned

SlaveRcv = I2C0DAT; // read and store data, NACK on next byte

break;

case 0x88: // data received, NACK returned

case 0xA0: // STOP or REP.START received while addressed as
slave

case 0xC0: // Data transmitted, NOT ACK received

case 0xC8: // Last data transmitted, ACK received

I2C0CONSET = 0x04; // set AA, switch to not addressed slave
mode

donecheck = 1;

break;

case 0xA8: // own SLA+R received, Ack returned (slave
transmitter)

case 0xB8: // Data transmitted, ACK received

I2C0DAT = SlaveSnd; // Transmit last data AA = 0

break;

default:

break;

}

VICVectAddr = 0x01; // reset VIC

}


(You need to be a member of lpc2000 -- send a blank email to lpc2000-subscribe@yahoogroups.com )

Re: timer0 interrupt eventually hangs - Fran Tech - Apr 18 13:25:26 2010

I converted the Timer0 interrupt to FIQ, left I2C interrupt as vectored, and
it behaves the same way. Why would the interrupt just suddenly stop
firing???
Fran

On Sat, Apr 17, 2010 at 5:04 PM, frantechman wrote:

> Hi all,
>
> I'm a newby to Keil tools, lpc2138 microcontroller, and C programming
> language. I'm doing this on a Keil MCB2130 dev board. I have some code that
> I have either pieced together or wrote that works for a bit and then stops.
> I have been reading, researching, debugging, and trial and erroring it for
> about 2 weeks and I just can't seem to solve it. I set up timer0 for
> interrupts to kick off the A2D. The timer count is a number that is derived
> from a number that is recieved from an I2C master. The lpc2138 is configured
> as an I2C slave using the app note from NXP (TN06005). I wouldn't have
> thought this would be too difficult as interrupts for the I2C code and for
> timer0 do not occur at the same time. Therefore I have tried disabling I2C
> interrupts and only re-enabling them right before it is required. And the
> same with timer0, I enable it right before it is needed and then disable
> them after the function is completed. Whether I do this or just leave both
> enabled from the start I end up with the same results. The I2C communication
> never fails however, it appears that timer0 interrupts will fail to occur at
> the same point. When it fails, after the command to enable timer0 interrupt
> occurs, it is stuck in a Do-While loop waiting for an interrupt that never
> happens. I don't know much yet about using the debugger but when I stop it
> when it fails, it is always at this point. I put a couple of statements in
> the timer0 isr to turn on and off an LED and it does not light when it fails
> again further confirming to me that the interrupt is failing. Being an
> absolute novice I don't doubt that I am missing something very basic but I
> just don't see it. I would appreciate it if anyone could take a look at it
> and see if you spot anything that may be causing this. Once this is solved,
> everything is working fine. I just don't know why, seemingly randomly, the
> interrupt for timer0 would quit working. I will try to attach what I think
> is just the pertinent parts of my code.
>
> Thanks,
>
> Fran
>
> // This routine intializes the timer0 interrupt
>
> void timer0_init(void)
>
> {
>
> T0MR0 = sample_time; // This is varied and set up by the I2C value
> received
>
> T0MCR = 3; // timer 0 triggers on match and resets itself
>
> T0TCR = 1; // start the clock
>
> VICVectAddr0 = (unsigned long) tc0;
>
> VICVectCntl0 = 0x20 | 4;
>
> }
>
> // This is the start of a function that starts timer0 interrupting and then
> disables it when it is complete
>
> void calculate(void)
>
> {
>
> VICIntEnable = (1 << 4); // start sampling
>
> do
>
> {
>
> // Pertinent code goes here.
>
> }
>
> }
>
> while(counter < CYCLE_COUNT);
>
> VICIntEnClr = (1 << 4); // stop interrupting
>
> // This is the pertinent part of timer0 ISR
>
> void tc0 (void) __irq
>
> // Timer 0 interrupt routine
>
> {
>
> LED_on(); //*** here for testing purposes only
>
> // ISR related code for sampling the A2D here
>
> LED_off(); //*** here for testing purposes only
>
> T0IR = 0x01; // clear the flag
>
> VICVectAddr = 0;
>
> }
>
> // Note that this is NXP code from their appnote, because their example
> used Addr0,
>
> // I changed it to 1 as timer0 needs to be highest priority, once I get
> this working
>
> // I will try and change timer0 interrupts to FIQ as my understanding is
> that will reduce latency.
>
> void I2C0_Init(void)
>
> {
>
> PINSEL0 |= 0x50; // P0.3 = SDA, P0.2 = SCL
>
> I2C0ADR = 0xD0; // set I2C slave address
>
> I2C0CONSET = 0x44; // enable I2C hardwar and set AA (ack)
>
> I2C0SCLH=0x4B; // 100 KHz 0x4B
>
> I2C0SCLL=0x4B; // 0x4B
>
> VICVectAddr1 = (unsigned int) &I2C0_Isr;
>
> VICVectCntl1 = 0x29; // Channel1 on Source#9 ... enabled
>
> VICIntEnable |= 0x200; // 9th bit is the I2C
>
> }
>
> // This is the ISR for I2C slave communications out of the NXP app note
>
> void I2C0_Isr(void) __irq
>
> {
>
> unsigned char st;
>
> st = I2C0STAT;
>
> I2C0CONCLR = 0x2C; // clear STA, AA and SI
>
> switch(st)
>
> {
>
> case 0x60: // own SLA+W received, Ack returned (slave receiver)
>
> case 0x68: // Addressed as slave
>
> I2C0CONSET = 0x04; // set AA, return ACK on first byte
>
> break;
>
> case 0x80: // Data received, ACK returned
>
> SlaveRcv = I2C0DAT; // read and store data, NACK on next byte
>
> break;
>
> case 0x88: // data received, NACK returned
>
> case 0xA0: // STOP or REP.START received while addressed as slave
>
> case 0xC0: // Data transmitted, NOT ACK received
>
> case 0xC8: // Last data transmitted, ACK received
>
> I2C0CONSET = 0x04; // set AA, switch to not addressed slave mode
>
> donecheck = 1;
>
> break;
>
> case 0xA8: // own SLA+R received, Ack returned (slave
> transmitter)
>
> case 0xB8: // Data transmitted, ACK received
>
> I2C0DAT = SlaveSnd; // Transmit last data AA = 0
>
> break;
>
> default:
>
> break;
>
> }
>
> VICVectAddr = 0x01; // reset VIC
>
> }
>



(You need to be a member of lpc2000 -- send a blank email to lpc2000-subscribe@yahoogroups.com )

Re: timer0 interrupt eventually hangs - rtstofer - Apr 18 16:39:06 2010



--- In l..., "Michael Anton" wrote:
>
> Well, it would miss the interrupt if the timer count was already past the
> match time. It will fire eventually, but not until the timer wraps around,
> which could take a long time. This might occur if you were, for example,
> using a longer sample_time, and then reduced it.
>
> Mike

I have lost track (old age)...

Somebody was using Keil and having problems with the interrupts when there was a wrapper in the startup code. So, the recommendation was to get rid of the __IRQ attributes and use regular functions. This will work fine for all IRQ interrupts because the IRQ vector points to the wrapper and the wrapper deals with the VIC to get the vector address of either a dedicated handler or a default handler.

FIQ interrupts are not vectored by the VIC. There is just a fast branch to the FIQ vector. Here, I believe you have to use the __IRQ attributes in order to get the preamble and postamble code. Unfortunately, there has been much discussion over the years about whether the preamble is safe. It is almost certainly unsafe for nested interrupts.

But, again, I have lost track... What chip are we talking about? What is CCLK and PCLK? What is the timer interrupt rate? What is the I2C interrupt rate (OK. this is hard to guess. What is the bus rate?)? Given that the wrapper allows for nested interrupts, why is it necessary to go to the FIQ? Are nested interrupts desired? What are the implications of nesting on the project? I didn't really look at the wrapper, is it re-enabling interrupts? What priority is being assigned to each interrupt (assuming vectored IRQs)?

The whole point of using the wrapper is to get rid of the preamble and postamble code. Code which is known to crash. Which is why the wrapper was created, BTW. Adding FIQ back in the mix seems to make this more likely unless there is a SEPARATE FIQ wrapper (and there could be!).

Then there is the matter of the FIQ stack size. This is set in the startup code. Is it large enough? Sometimes space isn't allocated at all because the original programmers never really expected FIQ to be used.

Richard





(You need to be a member of lpc2000 -- send a blank email to lpc2000-subscribe@yahoogroups.com )

Re: timer0 interrupt eventually hangs - Fran Tech - Apr 18 22:12:06 2010

Mike and Richard,
Thanks for the replies. I was incorrect in my last message when I thought I
had setup timer0 in FIQ mode. I now have it correctly working in FIQ mode.
The problem with timer 0 locking at the point it was before seems to have
been cured, however it is doing it when the number is sent over from the
master via I2C for the timer0 match value. I'll play with this some more
and ask for help if I can't find a solution. Strange because the I2C
communications (and interrupt) never has an issue but Timer0 interrupt does.
Thanks,
Fran

On Sun, Apr 18, 2010 at 3:32 PM, rtstofer wrote:

> --- In l... , "Michael
> Anton" wrote:
> >
> > Well, it would miss the interrupt if the timer count was already past the
> > match time. It will fire eventually, but not until the timer wraps
> around,
> > which could take a long time. This might occur if you were, for example,
> > using a longer sample_time, and then reduced it.
> >
> > Mike
>
> I have lost track (old age)...
>
> Somebody was using Keil and having problems with the interrupts when there
> was a wrapper in the startup code. So, the recommendation was to get rid of
> the __IRQ attributes and use regular functions. This will work fine for all
> IRQ interrupts because the IRQ vector points to the wrapper and the wrapper
> deals with the VIC to get the vector address of either a dedicated handler
> or a default handler.
>
> FIQ interrupts are not vectored by the VIC. There is just a fast branch to
> the FIQ vector. Here, I believe you have to use the __IRQ attributes in
> order to get the preamble and postamble code. Unfortunately, there has been
> much discussion over the years about whether the preamble is safe. It is
> almost certainly unsafe for nested interrupts.
>
> But, again, I have lost track... What chip are we talking about? What is
> CCLK and PCLK? What is the timer interrupt rate? What is the I2C interrupt
> rate (OK. this is hard to guess. What is the bus rate?)? Given that the
> wrapper allows for nested interrupts, why is it necessary to go to the FIQ?
> Are nested interrupts desired? What are the implications of nesting on the
> project? I didn't really look at the wrapper, is it re-enabling interrupts?
> What priority is being assigned to each interrupt (assuming vectored IRQs)?
>
> The whole point of using the wrapper is to get rid of the preamble and
> postamble code. Code which is known to crash. Which is why the wrapper was
> created, BTW. Adding FIQ back in the mix seems to make this more likely
> unless there is a SEPARATE FIQ wrapper (and there could be!).
>
> Then there is the matter of the FIQ stack size. This is set in the startup
> code. Is it large enough? Sometimes space isn't allocated at all because the
> original programmers never really expected FIQ to be used.
>
> Richard
>
>
>



(You need to be a member of lpc2000 -- send a blank email to lpc2000-subscribe@yahoogroups.com )

Re: timer0 interrupt eventually hangs - Fran Tech - Apr 19 8:43:34 2010

Interesting Idea, I will try that tonight.
Thanks again,
Fran

On Sun, Apr 18, 2010 at 9:14 PM, rtstofer wrote:

> --- In l... , Fran Tech
> wrote:
> >
> > Mike and Richard,
> > Thanks for the replies. I was incorrect in my last message when I thought
> I
> > had setup timer0 in FIQ mode. I now have it correctly working in FIQ
> mode.
> > The problem with timer 0 locking at the point it was before seems to have
> > been cured, however it is doing it when the number is sent over from the
> > master via I2C for the timer0 match value. I'll play with this some more
> > and ask for help if I can't find a solution. Strange because the I2C
> > communications (and interrupt) never has an issue but Timer0 interrupt
> does.
> > Thanks,
> > Fran
>
> Try setting the new value from inside the interrupt routine. Keep the new
> value in a global variable and just set it after every interrupt.
>
> See what happens...
>
> Richard
>
>
>



(You need to be a member of lpc2000 -- send a blank email to lpc2000-subscribe@yahoogroups.com )

Re: timer0 interrupt eventually hangs - rtstofer - Apr 19 12:35:10 2010



--- In l..., Fran Tech wrote:
>
> Mike and Richard,
> Thanks for the replies. I was incorrect in my last message when I thought I
> had setup timer0 in FIQ mode. I now have it correctly working in FIQ mode.
> The problem with timer 0 locking at the point it was before seems to have
> been cured, however it is doing it when the number is sent over from the
> master via I2C for the timer0 match value. I'll play with this some more
> and ask for help if I can't find a solution. Strange because the I2C
> communications (and interrupt) never has an issue but Timer0 interrupt does.
> Thanks,
> Fran

Try setting the new value from inside the interrupt routine. Keep the new value in a global variable and just set it after every interrupt.

See what happens...

Richard





(You need to be a member of lpc2000 -- send a blank email to lpc2000-subscribe@yahoogroups.com )