Yahoo Groups archive

Lpc2000

Index last updated: 2026-04-28 23:31 UTC

Thread

Undocumented Timer Interrupt Feature, or Silicon Bug...

Undocumented Timer Interrupt Feature, or Silicon Bug...

2004-10-11 by vaughan_anztec

...Or am I doing something wrong?
 
I've been implementing a bit bashed serial port on an LPC2114. The 
code relied upon the timer module's input capture facility to 
generate an interrupt whenever there was a 1->0 or 0->1 transition on 
the RS232 receive line (buffered by  a Max232 equivalent). This 
loaded a match register (MR1) with a value equal to half a bit time 
so the incoming bit could be sampled at its mid-point. Transmission 
used another match register (MR2) to generate appropriately timed 
interrupts to send bits as required. Another match register (MR0) in 
the same timer was also used to generate a 1ms tick. 
 
When I was testing the code's full duplex operation, I found that the 
1ms tick or the transmission tick interrupt would sometimes be missed 
(refer to posts 3510 and 3514). Robert Adsett suggested not servicing 
multiple events in the ISR. This did not fix the problem. The only 
way I've found to work around the problem of missing interrupts is to 
stop the counter while I process any pending match or capture 
interrupts. Is this an undocumented feature or am I doing something 
wrong? 
 
Here's some sample code that demonstrates the problem: 
 
Code to initialise the timer and input capture pin (timer register 
access macros etc. taken straight from Keil's lpc21xx.h header file. 
Compiler used is ARM's RVCT 2.1):
void InitTimer0(void)
{
    /*Set T0 up to use the FIQ*/
    VICIntSelect = 
      VICIntSelect | 1 << TIMER0_ID; /*FIQ interrupt source selected*/
    VICIntEnable = 
      VICIntEnable | 1 << TIMER0_ID; /*Interrupt enabled*/
 
    /*Set up T0*/
    TIMER0_TCR = 0x0UL;       /*Disable T0*/
    TIMER0_TC  = 0x0UL;       /*Clear current counter value*/
    TIMER0_PR  = 59UL;        /*Set counter to have 1us resolution*/
    TIMER0_PC  = 0UL;         /*Clear precount value*/
    TIMER0_MR0 = 1000UL;      /*First MR0 match @ 1ms*/
    TIMER0_MR2 = 52UL;        /*First MR2 match @ 52us*/
 
    TIMER0_MCR = 0x49UL;      /*Interrupt on MR0, MR1 and MR2 match*/ 
    
 
    /*Set up T0 input capture*/
    PINSEL1 |= 0x00800000UL;  /*Pin 0.27 = capture input 0.1*/
    TIMER0_CCR |= 0x0038UL;   /*Capture and interrupt on falling
                                and rising edge*/ 
    
    /*Finally, enable T0*/
    TIMER0_TCR = 0x01UL;
}    
 
 
 
Timer 0 interrupt code that misses MR0 or MR2 matches when there are 
many bit transitions on P0.27. 
#define TIMER0_IR_CR1 0x20
__irq void TIMER0_IRQHandler( void )
{
    /*Look at one source of interrupt at a time as per Robert
      Adsett's suggestion*/
    if((TIMER0_IR & TIMER0_IR_CR1) != 0)
    {
        /*Capture interrupt - generated on positive or negative 
          edge of P0.27
          Whenever an edge occurs, set MR1 to interrupt in 26us*/
        TIMER0_IR = TIMER0_IR_CR1;
        TIMER0_MR1 =  TIMER0_CR1 + 26UL;
    }
    else if((TIMER0_IR & TIMER0_IR_MR1) != 0)
    {
        /*MR1 occurs 26us after CR1 edge, or if no edges detected, 
          every 52us*/
        TIMER0_IR = TIMER0_IR_MR1;
        TIMER0_MR1 = TIMER0_TC + 52UL;
    }
    else if((TIMER0_IR & TIMER0_IR_MR2) != 0)
    {
        /*MR2 is a free running 52us tick
          Clear current interrupt flag and set when next match is 
          to occur*/
        TIMER0_IR = TIMER0_IR_MR2;
        /*Wiggle a bit so DSO can be used to seen when match 
          interrupt is lost (no output for 2^32us!)*/
        IOSET1 = 1UL << 22;
        TIMER0_MR2 = TIMER0_TC + 52UL;
        IOCLR1 = 1UL << 22;
    }
    else if((TIMER0_IR & TIMER0_IR_MR0) != 0)
    {
        /*MR0 is a free running 1ms tick
          Clear current interrupt flag and set when next match 
          is to occur*/
        TIMER0_IR = TIMER0_IR_MR0;
        /*Wiggle a bit so DSO can be used to seen when match 
          interrupt is lost (no output for 2^32us!)*/
        IOSET0 = 1UL << 15;
        TIMER0_MR0 = TIMER0_TC + 1000UL;
        IOCLR0 = 1UL << 15;
    }
}
 

Timer 0 interrupt code showing work-around to prevent loss of match 
register interrupts
#define TIMER0_IR_CR1 0x20
__irq void TIMER0_IRQHandler( void )
{
    unsigned long TimerIR;
    
    TIMER0_TCR = 0; /*Stop the clock before doing anything*/
    while((TimerIR = TIMER0_IR) != 0)
    {
        if((TimerIR & TIMER0_IR_CR1) != 0)
        {
            /*Capture interrupt - generated on positive or negative 
              edge of P0.27
              Whenever an edge occurs, set MR1 to interrupt in 26us*/
            TIMER0_IR = TIMER0_IR_CR1;
            TIMER0_MR1 =  TIMER0_CR1 + 26UL;
        }
        if((TimerIR & TIMER0_IR_MR1) != 0)
        {
            /*MR1 occurs 26us after CR1 edge, or if no edges 
              detected, every 52us*/
            TIMER0_IR = TIMER0_IR_MR1;
            TIMER0_MR1 = TIMER0_TC + 52UL;
        }
        if((TimerIR & TIMER0_IR_MR2) != 0)
        {
            TIMER0_IR = TIMER0_IR_MR2;
            /*MR2 is a free running 52us tick
              Clear current interrupt flag and set when next match 
              is to occur*/
            TIMER0_IR = TIMER0_IR_MR2;
            /*Wiggle a bit so DSO can be used to seen if match 
              interrupt is lost*/
            IOSET1 = 1UL << 22;
            TIMER0_MR2 = TIMER0_TC + 52UL;
            IOCLR1 = 1UL << 22;
        }
        if((TimerIR & TIMER0_IR_MR0) != 0)
        {
            /*MR0 is a free running 1ms tick
              Clear current interrupt flag and set when next match 
              is to occur*/
            TIMER0_IR = TIMER0_IR_MR0;
            /*Wiggle a bit so DSO can be used to seen if match 
              interrupt is lost*/
            IOSET0 = 1UL << 15;
            TIMER0_MR0 = TIMER0_TC + 1000UL;
            IOCLR0 = 1UL << 15;
        }
    }
    
    /*When we get here, all interrupt sources have been cleared*/
    TIMER0_TC++;    /*Advance clock to stop double firing of 
                      previous match(es)*/
    TIMER0_TCR = 1; /*Restart the clock*/
}

Re: [lpc2000] Undocumented Timer Interrupt Feature, or Silicon Bug...

2004-10-12 by Robert Adsett

At 08:03 PM 10/11/04 +0000, you wrote:


>...Or am I doing something wrong?
>
>I've been implementing a bit bashed serial port on an LPC2114. The
>code relied upon the timer module's input capture facility to
>generate an interrupt whenever there was a 1->0 or 0->1 transition on
>the RS232 receive line (buffered by  a Max232 equivalent). This
>loaded a match register (MR1) with a value equal to half a bit time
>so the incoming bit could be sampled at its mid-point. Transmission
>used another match register (MR2) to generate appropriately timed
>interrupts to send bits as required. Another match register (MR0) in
>the same timer was also used to generate a 1ms tick.
>
>When I was testing the code's full duplex operation, I found that the
>1ms tick or the transmission tick interrupt would sometimes be missed
>(refer to posts 3510 and 3514). Robert Adsett suggested not servicing
>multiple events in the ISR. This did not fix the problem. The only
>way I've found to work around the problem of missing interrupts is to
>stop the counter while I process any pending match or capture
>interrupts. Is this an undocumented feature or am I doing something
>wrong?

No answers, only questions.

You are running at full speed, ie MAM fully enabled, a divisor of 1 on the 
peripheral bus?

Have you measured how long an interrupt takes?  IE done something like 
toggle a pin at the beginning and end of your dispatch routine?  If 
possible I'd consider generating assembly from the C and inserting the pin 
toggle as close to the start and end of your interrupt as possible.  I'm 
wondering if latency or simple overhead and execution time isn't a part of 
the issue.

One of the reasons I'm asking is I did some measurements on timing (polled, 
no Interrupts) and found that the smallest time period I could effectively 
wait for was about 11uS.  That obviously included overhead but your 
routines will too.  If your timing was similar (and I would naively expect 
it might be faster) then that would give an overhead of 44uS if all four 
happened at the 'same' time.  That's close enough to your 52uS cycle time 
that I'd want to check how long it was actually taking.

Robert

" 'Freedom' has no meaning of itself.  There are always restrictions,
be they legal, genetic, or physical.  If you don't believe me, try to
chew a radio signal. "

                         Kelvin Throop, III

Re: Undocumented Timer Interrupt Feature, or Silicon Bug...

2004-10-12 by vaughan_anztec

--- In lpc2000@yahoogroups.com, Robert Adsett <subscriptions@a...> 
wrote:
> At 08:03 PM 10/11/04 +0000, you wrote:
> 
> 
> >...Or am I doing something wrong?
> No answers, only questions.
> 
> You are running at full speed, ie MAM fully enabled, a divisor of 1 
> on the peripheral bus?

External clock is 10MHz, PLL is enabled and multiplies this to 60MHz. 
MAM is enabled and MAMTIM is set to 3. VPBDIV is set to 1. As far as 
I can see, the core is working at 60MHz (e.g. baud rate divisors work 
out as expected for this value). Interestingly, I tried clocking TC 
at this rate (i.e. one count every 16.7ns) with appropriate MR 
values. The problem I've outlined was much much worse i.e. interrupts 
were lost almost immediately.



> Have you measured how long an interrupt takes?  IE done something 
like 
> toggle a pin at the beginning and end of your dispatch routine?  If 
> possible I'd consider generating assembly from the C and inserting 
the pin 
> toggle as close to the start and end of your interrupt as 
possible.  I'm 
> wondering if latency or simple overhead and execution time isn't a 
part of 
> the issue.

That's what I initally thought. However, the final code only takes 
around 2us to action ANY of the various events. Assuming ALL events 
occur simultaneously, I could get a maximum of 6us latency (give or 
take!). The sample code I posted also exhibits the same behavior and 
it is very minimalistic (I didn't measure the various execution paths 
but I would be surprised to see any event taking much longer than 1us 
to process). Also, my bit bashed port with the clock stopping 
workaround is very reliable at 9600 bps full duplex and passably so 
at 19k2 full duplex. This wouldn't be the case if my event processing 
was taking a long time.


I think your previous post hit the nail on the head - when there are 
simulataneous accesses to an interrupt register, it does not 
accurately reflect what's happened. 


> One of the reasons I'm asking is I did some measurements on timing 
(polled, 
> no Interrupts) and found that the smallest time period I could 
effectively 
> wait for was about 11uS.  That obviously included overhead but your 
> routines will too.  If your timing was similar (and I would naively 
expect 
> it might be faster) then that would give an overhead of 44uS if all 
four 
> happened at the 'same' time.  That's close enough to your 52uS 
cycle time 
> that I'd want to check how long it was actually taking.
Hmmmm.... It still shouldn't miss events though!


> 
> Robert
> 
> " 'Freedom' has no meaning of itself.  There are always 
restrictions,
> be they legal, genetic, or physical.  If you don't believe me, try 
to
Show quoted textHide quoted text
> chew a radio signal. "
> 
>                          Kelvin Throop, III

Re: [lpc2000] Re: Undocumented Timer Interrupt Feature, or Silicon Bug...

2004-10-12 by Robert Adsett

At 12:42 AM 10/12/04 +0000, you wrote:


>--- In lpc2000@yahoogroups.com, Robert Adsett <subscriptions@a...>
>wrote:
> > At 08:03 PM 10/11/04 +0000, you wrote:
> >
> >
> > >...Or am I doing something wrong?
> > No answers, only questions.
> >
> > You are running at full speed, ie MAM fully enabled, a divisor of 1
> > on the peripheral bus?
>
>External clock is 10MHz, PLL is enabled and multiplies this to 60MHz.
>MAM is enabled and MAMTIM is set to 3. VPBDIV is set to 1. As far as
>I can see, the core is working at 60MHz (e.g. baud rate divisors work
>out as expected for this value). Interestingly, I tried clocking TC
>at this rate (i.e. one count every 16.7ns) with appropriate MR
>values. The problem I've outlined was much much worse i.e. interrupts
>were lost almost immediately.

Interesting, not sure what that means but interesting.

> > Have you measured how long an interrupt takes?  IE done something
>like
> > toggle a pin at the beginning and end of your dispatch routine?  If
> > possible I'd consider generating assembly from the C and inserting
>the pin
> > toggle as close to the start and end of your interrupt as
>possible.  I'm
> > wondering if latency or simple overhead and execution time isn't a
>part of
> > the issue.
>
>That's what I initally thought. However, the final code only takes
>around 2us to action ANY of the various events. Assuming ALL events
>occur simultaneously, I could get a maximum of 6us latency (give or
>take!). The sample code I posted also exhibits the same behavior and
>it is very minimalistic (I didn't measure the various execution paths
>but I would be surprised to see any event taking much longer than 1us
>to process). Also, my bit bashed port with the clock stopping
>workaround is very reliable at 9600 bps full duplex and passably so
>at 19k2 full duplex. This wouldn't be the case if my event processing
>was taking a long time.

That's sort of what I was expecting, but it did need to be checked.


>I think your previous post hit the nail on the head - when there are
>simulataneous accesses to an interrupt register, it does not
>accurately reflect what's happened.

And on reflection, I'm wondering if it isn't more similar to what I saw on 
the serial port IIR than I first thought.  What I saw appeared to behave as 
if the interrupt flag was lost if the event causing the interrupt occurred 
at the same time that the previous interrupt condition was being 
cleared.  You do have places where that sequence can occur and turning off 
the counter would eliminate the problem (no interrupt source, no chance of 
conflict).

If that is the case it should be possible to narrow the region that the 
clock/counter must be disabled.

Specifically you have several lines of this form

             TIMER0_IR = TIMER0_IR_CR1;

to clear the interrupt source just serviced, and you (in your 'working' 
version) disable the counter for the entire interrupt.  If you replace the 
above line with

     TIMER0_TCR = 0; /*Stop the clock before clearing the interrupt source. */
     TIMER0_IR = TIMER0_IR_CR1;
     TIMER0_TCR = 1; /*Restart the clock*/

then if that hypothesized race condition actually exists you should still 
be protected against it (I suppose it might be possible you would have to 
wait an instruction for the counter to stop).

Hmm, this might also explain why a faster counter showed the problem more 
readily.  A faster counter would be more likely to have an edge just as the 
constant was being stored in TIMER0_IR.

If you try this please let us know.  I, for one, would be very interested 
in the results.


> > One of the reasons I'm asking is I did some measurements on timing
>(polled,
> > no Interrupts) and found that the smallest time period I could
>effectively
> > wait for was about 11uS.  That obviously included overhead but your
> > routines will too.  If your timing was similar (and I would naively
>expect
> > it might be faster) then that would give an overhead of 44uS if all
>four
> > happened at the 'same' time.  That's close enough to your 52uS
>cycle time
> > that I'd want to check how long it was actually taking.
>Hmmmm.... It still shouldn't miss events though!

Well, it might, if you wrote to clear an event just as (or after) a second 
one of the same kind had been flagged.  That doesn't fit with your timing 
though.  I think the possibility of a HW race is a better fit to the 
observations, ugly though.

Robert

" 'Freedom' has no meaning of itself.  There are always restrictions,
be they legal, genetic, or physical.  If you don't believe me, try to
chew a radio signal. "

                         Kelvin Throop, III

Re: Undocumented Timer Interrupt Feature, or Silicon Bug...

2004-10-12 by itsjustimpossible

As an aside, you MAY have cured a wierd problem I am seeing. I am 
also using Keil but with the LPC2294. I have a similar setup, MAM 
enabled, PLL to 60MHz, VPBDIV is set to 1 & 10MHz clock. I am running 
(and debugging) from internal FLASH.

Sometimes when debugging the timer interrupt would just stop working. 
Everything else appears normal.
I have added a timer stop to the interrupt and it seems to have 
helped. I don't want to appear too positive because as soon as I say 
its OK it will fail again ;-)

void tc0 (void) __irq
{
  T0TCR = 0;		// Stop the clock while we do the interrupt

  if(Auto == TRUE)DO_FAST_PULSE;
  ++timeval;

  T0IR  = 1;		// Clear interrupt flag
  T0TCR = 1;		// ReStart the clock counter
  VICVectAddr = 0;	// Acknowledge Interrupt
}

The IRQ is now as above, and so far seems OK.

Thanks for your help!
cheers
Simon

--- In lpc2000@yahoogroups.com, Robert Adsett <subscriptions@a...> 
wrote:
> At 12:42 AM 10/12/04 +0000, you wrote:
> 
> 
> >--- In lpc2000@yahoogroups.com, Robert Adsett <subscriptions@a...>
> >wrote:
> > > At 08:03 PM 10/11/04 +0000, you wrote:
> > >
> > >
> > > >...Or am I doing something wrong?
> > > No answers, only questions.
> > >
> > > You are running at full speed, ie MAM fully enabled, a divisor 
of 1
> > > on the peripheral bus?
> >
> >External clock is 10MHz, PLL is enabled and multiplies this to 
60MHz.
> >MAM is enabled and MAMTIM is set to 3. VPBDIV is set to 1. As far 
as
> >I can see, the core is working at 60MHz (e.g. baud rate divisors 
work
> >out as expected for this value). Interestingly, I tried clocking TC
> >at this rate (i.e. one count every 16.7ns) with appropriate MR
> >values. The problem I've outlined was much much worse i.e. 
interrupts
Show quoted textHide quoted text
> >were lost almost immediately.
> 
> Interesting, not sure what that means but interesting.

Re: Undocumented Timer Interrupt Feature, or Silicon Bug...

2004-10-12 by g2100g

There is a silicon bug, which Philips has confirmed, but has yet to 
publish.

If the timer hardware triggers an interrupt at the same time that the 
core is writing to the timer IR register to clear an interrupt on a 
different channel, the new interrupt does not get set.  This problem 
can occur with an input capture, as well as with a match.  That is a 
bit more difficult to work around.

As for there being a similar problem on the UART IIR, do you have a 
reproducible situation to determine this?

I suspect there are probably other registers (which can be written to 
by both the core and peripheral hardware) which exhibit a similar 
problem.  I don't know how much Philips has determined about the 
specifics and extent of this bug, since first confirming its 
existence.



--- In lpc2000@yahoogroups.com, Robert Adsett <subscriptions@a...> 
wrote:
> At 12:42 AM 10/12/04 +0000, you wrote:
> 
> 
> >--- In lpc2000@yahoogroups.com, Robert Adsett <subscriptions@a...>
> >wrote:
> > > At 08:03 PM 10/11/04 +0000, you wrote:
> > >
> > >
> > > >...Or am I doing something wrong?
> > > No answers, only questions.
> > >
> > > You are running at full speed, ie MAM fully enabled, a divisor 
of 1
> > > on the peripheral bus?
> >
> >External clock is 10MHz, PLL is enabled and multiplies this to 
60MHz.
> >MAM is enabled and MAMTIM is set to 3. VPBDIV is set to 1. As far 
as
> >I can see, the core is working at 60MHz (e.g. baud rate divisors 
work
> >out as expected for this value). Interestingly, I tried clocking TC
> >at this rate (i.e. one count every 16.7ns) with appropriate MR
> >values. The problem I've outlined was much much worse i.e. 
interrupts
> >were lost almost immediately.
> 
> Interesting, not sure what that means but interesting.
> 
> > > Have you measured how long an interrupt takes?  IE done 
something
> >like
> > > toggle a pin at the beginning and end of your dispatch 
routine?  If
> > > possible I'd consider generating assembly from the C and 
inserting
> >the pin
> > > toggle as close to the start and end of your interrupt as
> >possible.  I'm
> > > wondering if latency or simple overhead and execution time 
isn't a
> >part of
> > > the issue.
> >
> >That's what I initally thought. However, the final code only takes
> >around 2us to action ANY of the various events. Assuming ALL events
> >occur simultaneously, I could get a maximum of 6us latency (give or
> >take!). The sample code I posted also exhibits the same behavior 
and
> >it is very minimalistic (I didn't measure the various execution 
paths
> >but I would be surprised to see any event taking much longer than 
1us
> >to process). Also, my bit bashed port with the clock stopping
> >workaround is very reliable at 9600 bps full duplex and passably so
> >at 19k2 full duplex. This wouldn't be the case if my event 
processing
> >was taking a long time.
> 
> That's sort of what I was expecting, but it did need to be checked.
> 
> 
> >I think your previous post hit the nail on the head - when there 
are
> >simulataneous accesses to an interrupt register, it does not
> >accurately reflect what's happened.
> 
> And on reflection, I'm wondering if it isn't more similar to what I 
saw on 
> the serial port IIR than I first thought.  What I saw appeared to 
behave as 
> if the interrupt flag was lost if the event causing the interrupt 
occurred 
> at the same time that the previous interrupt condition was being 
> cleared.  You do have places where that sequence can occur and 
turning off 
> the counter would eliminate the problem (no interrupt source, no 
chance of 
> conflict).
> 
> If that is the case it should be possible to narrow the region that 
the 
> clock/counter must be disabled.
> 
> Specifically you have several lines of this form
> 
>              TIMER0_IR = TIMER0_IR_CR1;
> 
> to clear the interrupt source just serviced, and you (in 
your 'working' 
> version) disable the counter for the entire interrupt.  If you 
replace the 
> above line with
> 
>      TIMER0_TCR = 0; /*Stop the clock before clearing the interrupt 
source. */
>      TIMER0_IR = TIMER0_IR_CR1;
>      TIMER0_TCR = 1; /*Restart the clock*/
> 
> then if that hypothesized race condition actually exists you should 
still 
> be protected against it (I suppose it might be possible you would 
have to 
> wait an instruction for the counter to stop).
> 
> Hmm, this might also explain why a faster counter showed the 
problem more 
> readily.  A faster counter would be more likely to have an edge 
just as the 
> constant was being stored in TIMER0_IR.
> 
> If you try this please let us know.  I, for one, would be very 
interested 
> in the results.
> 
> 
> > > One of the reasons I'm asking is I did some measurements on 
timing
> >(polled,
> > > no Interrupts) and found that the smallest time period I could
> >effectively
> > > wait for was about 11uS.  That obviously included overhead but 
your
> > > routines will too.  If your timing was similar (and I would 
naively
> >expect
> > > it might be faster) then that would give an overhead of 44uS if 
all
> >four
> > > happened at the 'same' time.  That's close enough to your 52uS
> >cycle time
> > > that I'd want to check how long it was actually taking.
> >Hmmmm.... It still shouldn't miss events though!
> 
> Well, it might, if you wrote to clear an event just as (or after) a 
second 
> one of the same kind had been flagged.  That doesn't fit with your 
timing 
> though.  I think the possibility of a HW race is a better fit to 
the 
> observations, ugly though.
> 
> Robert
> 
> " 'Freedom' has no meaning of itself.  There are always 
restrictions,
> be they legal, genetic, or physical.  If you don't believe me, try 
to
Show quoted textHide quoted text
> chew a radio signal. "
> 
>                          Kelvin Throop, III

Re: [lpc2000] Re: Undocumented Timer Interrupt Feature, or Silicon Bug...

2004-10-12 by Robert Adsett

At 09:09 PM 10/12/04 +0000, you wrote:
>There is a silicon bug, which Philips has confirmed, but has yet to
>publish.

Note to Philips: Timely publication of errata is a MUST.  If nothing else 
it saves a lot of bloody foreheads.


>If the timer hardware triggers an interrupt at the same time that the
>core is writing to the timer IR register to clear an interrupt on a
>different channel, the new interrupt does not get set.  This problem
>can occur with an input capture, as well as with a match.  That is a
>bit more difficult to work around.

That certainly explains it.

>As for there being a similar problem on the UART IIR, do you have a
>reproducible situation to determine this?

Yes, I did.  The situation came up while working with serial port 
interrupts (naturally).  It required that both transmit and receive 
interrupts be on simultaneously.  I then just had a simple echo program 
running on the micro and had the terminal emulator on the PC dumping a file 
continuously out the serial port.  At some point the echo would stop (it 
could take several Mbytes).  As in the timer case I couldn't see any 
possible way for the SW to miss the interrupt completely.

Two workarounds seems to 'fix' the problem
  - one was to check the transmit ready flags in the receive interrupt and 
restart the transmission if a transmit interrupt was missed,
  - the second was to only service a single interrupt source on each 
interrupt (only read IIR once)

The first workaround is obviously problematic since it requires a received 
character to restart the transmit.  The second one appeared to be 
successful, but since the bug appeared to be somewhat timing sensitive I 
don't know for sure if it was eliminated or simply had it's probability 
drop by an order of magnitude or so.

Note that the nature of the test would mask any missing receive interrupts 
if only an occasional character was dropped.  Receive should be more robust 
anyway since each receipt should conceivably re-trigger the interrupt 
whereas the transmit interrupt only fires once.

I don't think I kept the original failing code (silly me) but I should be 
able to reproduce it if anyone can make use of it.

I first reported on this in this group back on June 23 (see thread "Missing 
THRE interrupt?").  It was met with resounding silence so I thought I was 
the only one seeing anything like it until this timer interrupt thread.

I've been uncomfortable that I haven't been able to pin down a definitive 
cause but I've had other things to do so it's been on the back burner with 
a mental "Here be dragons!" sign for future attention.  You have just given 
me hope that the cause may yet be found (and more importantly confirmed).

>I suspect there are probably other registers (which can be written to
>by both the core and peripheral hardware) which exhibit a similar
>problem.  I don't know how much Philips has determined about the
>specifics and extent of this bug, since first confirming its
>existence.

Certainly if it exists for one peripheral it raises the possibility that it 
has occurred in others.

If I knew for sure that the problem was some sort of race condition there 
is a chance I could work around it.

Robert

" 'Freedom' has no meaning of itself.  There are always restrictions,
be they legal, genetic, or physical.  If you don't believe me, try to
chew a radio signal. "

                         Kelvin Throop, III

Re: Undocumented Timer Interrupt Feature, or Silicon Bug...

2004-10-12 by vaughan_anztec

Thanks for the confirmation. And thank you to Robert for his prompt 
and insightful replies.

Now, time to go and fix that wall that I'd been bashing my head 
against... :-)

Regards




Vaughan

--- In lpc2000@yahoogroups.com, "g2100g" <g2100g@e...> wrote:
> 
> There is a silicon bug, which Philips has confirmed, but has yet to 
> publish.
> 
> If the timer hardware triggers an interrupt at the same time that 
the 
> core is writing to the timer IR register to clear an interrupt on a 
> different channel, the new interrupt does not get set.  This 
problem 
> can occur with an input capture, as well as with a match.  That is 
a 
> bit more difficult to work around.
> 
> As for there being a similar problem on the UART IIR, do you have a 
> reproducible situation to determine this?
> 
> I suspect there are probably other registers (which can be written 
to 
> by both the core and peripheral hardware) which exhibit a similar 
> problem.  I don't know how much Philips has determined about the 
> specifics and extent of this bug, since first confirming its 
> existence.
> 
> 
> 
> --- In lpc2000@yahoogroups.com, Robert Adsett <subscriptions@a...> 
> wrote:
> > At 12:42 AM 10/12/04 +0000, you wrote:
> > 
> > 
> > >--- In lpc2000@yahoogroups.com, Robert Adsett 
<subscriptions@a...>
> > >wrote:
> > > > At 08:03 PM 10/11/04 +0000, you wrote:
> > > >
> > > >
> > > > >...Or am I doing something wrong?
> > > > No answers, only questions.
> > > >
> > > > You are running at full speed, ie MAM fully enabled, a 
divisor 
> of 1
> > > > on the peripheral bus?
> > >
> > >External clock is 10MHz, PLL is enabled and multiplies this to 
> 60MHz.
> > >MAM is enabled and MAMTIM is set to 3. VPBDIV is set to 1. As 
far 
> as
> > >I can see, the core is working at 60MHz (e.g. baud rate divisors 
> work
> > >out as expected for this value). Interestingly, I tried clocking 
TC
> > >at this rate (i.e. one count every 16.7ns) with appropriate MR
> > >values. The problem I've outlined was much much worse i.e. 
> interrupts
> > >were lost almost immediately.
> > 
> > Interesting, not sure what that means but interesting.
> > 
> > > > Have you measured how long an interrupt takes?  IE done 
> something
> > >like
> > > > toggle a pin at the beginning and end of your dispatch 
> routine?  If
> > > > possible I'd consider generating assembly from the C and 
> inserting
> > >the pin
> > > > toggle as close to the start and end of your interrupt as
> > >possible.  I'm
> > > > wondering if latency or simple overhead and execution time 
> isn't a
> > >part of
> > > > the issue.
> > >
> > >That's what I initally thought. However, the final code only 
takes
> > >around 2us to action ANY of the various events. Assuming ALL 
events
> > >occur simultaneously, I could get a maximum of 6us latency (give 
or
> > >take!). The sample code I posted also exhibits the same behavior 
> and
> > >it is very minimalistic (I didn't measure the various execution 
> paths
> > >but I would be surprised to see any event taking much longer 
than 
> 1us
> > >to process). Also, my bit bashed port with the clock stopping
> > >workaround is very reliable at 9600 bps full duplex and passably 
so
> > >at 19k2 full duplex. This wouldn't be the case if my event 
> processing
> > >was taking a long time.
> > 
> > That's sort of what I was expecting, but it did need to be 
checked.
> > 
> > 
> > >I think your previous post hit the nail on the head - when there 
> are
> > >simulataneous accesses to an interrupt register, it does not
> > >accurately reflect what's happened.
> > 
> > And on reflection, I'm wondering if it isn't more similar to what 
I 
> saw on 
> > the serial port IIR than I first thought.  What I saw appeared to 
> behave as 
> > if the interrupt flag was lost if the event causing the interrupt 
> occurred 
> > at the same time that the previous interrupt condition was being 
> > cleared.  You do have places where that sequence can occur and 
> turning off 
> > the counter would eliminate the problem (no interrupt source, no 
> chance of 
> > conflict).
> > 
> > If that is the case it should be possible to narrow the region 
that 
> the 
> > clock/counter must be disabled.
> > 
> > Specifically you have several lines of this form
> > 
> >              TIMER0_IR = TIMER0_IR_CR1;
> > 
> > to clear the interrupt source just serviced, and you (in 
> your 'working' 
> > version) disable the counter for the entire interrupt.  If you 
> replace the 
> > above line with
> > 
> >      TIMER0_TCR = 0; /*Stop the clock before clearing the 
interrupt 
> source. */
> >      TIMER0_IR = TIMER0_IR_CR1;
> >      TIMER0_TCR = 1; /*Restart the clock*/
> > 
> > then if that hypothesized race condition actually exists you 
should 
> still 
> > be protected against it (I suppose it might be possible you would 
> have to 
> > wait an instruction for the counter to stop).
> > 
> > Hmm, this might also explain why a faster counter showed the 
> problem more 
> > readily.  A faster counter would be more likely to have an edge 
> just as the 
> > constant was being stored in TIMER0_IR.
> > 
> > If you try this please let us know.  I, for one, would be very 
> interested 
> > in the results.
> > 
> > 
> > > > One of the reasons I'm asking is I did some measurements on 
> timing
> > >(polled,
> > > > no Interrupts) and found that the smallest time period I could
> > >effectively
> > > > wait for was about 11uS.  That obviously included overhead 
but 
> your
> > > > routines will too.  If your timing was similar (and I would 
> naively
> > >expect
> > > > it might be faster) then that would give an overhead of 44uS 
if 
> all
> > >four
> > > > happened at the 'same' time.  That's close enough to your 52uS
> > >cycle time
> > > > that I'd want to check how long it was actually taking.
> > >Hmmmm.... It still shouldn't miss events though!
> > 
> > Well, it might, if you wrote to clear an event just as (or after) 
a 
> second 
> > one of the same kind had been flagged.  That doesn't fit with 
your 
> timing 
> > though.  I think the possibility of a HW race is a better fit to 
> the 
> > observations, ugly though.
> > 
> > Robert
> > 
> > " 'Freedom' has no meaning of itself.  There are always 
> restrictions,
> > be they legal, genetic, or physical.  If you don't believe me, 
try 
Show quoted textHide quoted text
> to
> > chew a radio signal. "
> > 
> >                          Kelvin Throop, III

Re: Undocumented Timer Interrupt Feature, or Silicon Bug...

2004-10-12 by philips_apps

See the "Timer_Issue" pdf in the file section, it will be removed 
when the updated errata is published.

Philips Apps.

--- In lpc2000@yahoogroups.com, Robert Adsett <subscriptions@a...> 
wrote:
> At 09:09 PM 10/12/04 +0000, you wrote:
> >There is a silicon bug, which Philips has confirmed, but has yet to
> >publish.
> 
> Note to Philips: Timely publication of errata is a MUST.  If 
nothing else 
> it saves a lot of bloody foreheads.
> 
> 
> >If the timer hardware triggers an interrupt at the same time that 
the
> >core is writing to the timer IR register to clear an interrupt on a
> >different channel, the new interrupt does not get set.  This 
problem
> >can occur with an input capture, as well as with a match.  That is 
a
> >bit more difficult to work around.
> 
> That certainly explains it.
> 
> >As for there being a similar problem on the UART IIR, do you have a
> >reproducible situation to determine this?
> 
> Yes, I did.  The situation came up while working with serial port 
> interrupts (naturally).  It required that both transmit and receive 
> interrupts be on simultaneously.  I then just had a simple echo 
program 
> running on the micro and had the terminal emulator on the PC 
dumping a file 
> continuously out the serial port.  At some point the echo would 
stop (it 
> could take several Mbytes).  As in the timer case I couldn't see 
any 
> possible way for the SW to miss the interrupt completely.
> 
> Two workarounds seems to 'fix' the problem
>   - one was to check the transmit ready flags in the receive 
interrupt and 
> restart the transmission if a transmit interrupt was missed,
>   - the second was to only service a single interrupt source on 
each 
> interrupt (only read IIR once)
> 
> The first workaround is obviously problematic since it requires a 
received 
> character to restart the transmit.  The second one appeared to be 
> successful, but since the bug appeared to be somewhat timing 
sensitive I 
> don't know for sure if it was eliminated or simply had it's 
probability 
> drop by an order of magnitude or so.
> 
> Note that the nature of the test would mask any missing receive 
interrupts 
> if only an occasional character was dropped.  Receive should be 
more robust 
> anyway since each receipt should conceivably re-trigger the 
interrupt 
> whereas the transmit interrupt only fires once.
> 
> I don't think I kept the original failing code (silly me) but I 
should be 
> able to reproduce it if anyone can make use of it.
> 
> I first reported on this in this group back on June 23 (see 
thread "Missing 
> THRE interrupt?").  It was met with resounding silence so I thought 
I was 
> the only one seeing anything like it until this timer interrupt 
thread.
> 
> I've been uncomfortable that I haven't been able to pin down a 
definitive 
> cause but I've had other things to do so it's been on the back 
burner with 
> a mental "Here be dragons!" sign for future attention.  You have 
just given 
> me hope that the cause may yet be found (and more importantly 
confirmed).
> 
> >I suspect there are probably other registers (which can be written 
to
> >by both the core and peripheral hardware) which exhibit a similar
> >problem.  I don't know how much Philips has determined about the
> >specifics and extent of this bug, since first confirming its
> >existence.
> 
> Certainly if it exists for one peripheral it raises the possibility 
that it 
> has occurred in others.
> 
> If I knew for sure that the problem was some sort of race condition 
there 
> is a chance I could work around it.
> 
> Robert
> 
> " 'Freedom' has no meaning of itself.  There are always 
restrictions,
> be they legal, genetic, or physical.  If you don't believe me, try 
to
Show quoted textHide quoted text
> chew a radio signal. "
> 
>                          Kelvin Throop, III

Re: Undocumented Timer Interrupt Feature, or Silicon Bug...

2004-10-14 by g2100g

There are a variety of other registers which can be written to by 
both hardware and software.  Has Philips determined which ones 
exhibit similar problems?



--- In lpc2000@yahoogroups.com, "philips_apps" <philips_apps@y...> 
wrote:
Show quoted textHide quoted text
> 
> See the "Timer_Issue" pdf in the file section, it will be removed 
> when the updated errata is published.
> 
> Philips Apps.

Re: Undocumented Timer Interrupt Feature, or Silicon Bug...

2004-12-16 by dave_albert

I was having the same problem with one of the capture interrupts; the
interrupt was configured to be rising-edge-triggered and was
multiplexed together with the other timer interrupt sources including
a fast match interrupt (every 10ms).  The match interrupt clear would
occasionally clear the capture interrupt before it had been serviced. 

The test to see if this was happening also turned out to fix the
problem:  in the ISR, if the capture interrupt flag was not set, I set
the pin_connect block to make the capture input a GPIO, read the state
of the input pin, and then set it back to a capture input.  This
confirmed the problem (input was high (active) but interrupt flag was
clear) and also seemed to solve it...I suspect when I turned the pin
from GPIO back into a capture pin, it saw a transition, the interrupt
fired, and the ISR serviced the peripheral.

Can you confirm this mechanism?

--- In lpc2000@yahoogroups.com, "philips_apps" <philips_apps@y...> wrote:
Show quoted textHide quoted text
> 
> See the "Timer_Issue" pdf in the file section, it will be removed 
> when the updated errata is published.
> 
> Philips Apps.
> 
> --- In lpc2000@yahoogroups.com, Robert Adsett <subscriptions@a...> 
> wrote:
> > At 09:09 PM 10/12/04 +0000, you wrote:
> > >There is a silicon bug, which Philips has confirmed, but has yet to
> > >publish.
> > 
> > Note to Philips: Timely publication of errata is a MUST.  If 
> nothing else 
> > it saves a lot of bloody foreheads.
> > 
> > 
> > >If the timer hardware triggers an interrupt at the same time that 
> the
> > >core is writing to the timer IR register to clear an interrupt on a
> > >different channel, the new interrupt does not get set.  This 
> problem
> > >can occur with an input capture, as well as with a match.  That is 
> a
> > >bit more difficult to work around.
> > 
> > That certainly explains it.
> > 
> > >As for there being a similar problem on the UART IIR, do you have a
> > >reproducible situation to determine this?
> > 
> > Yes, I did.  The situation came up while working with serial port 
> > interrupts (naturally).  It required that both transmit and receive 
> > interrupts be on simultaneously.  I then just had a simple echo 
> program 
> > running on the micro and had the terminal emulator on the PC 
> dumping a file 
> > continuously out the serial port.  At some point the echo would 
> stop (it 
> > could take several Mbytes).  As in the timer case I couldn't see 
> any 
> > possible way for the SW to miss the interrupt completely.
> > 
> > Two workarounds seems to 'fix' the problem
> >   - one was to check the transmit ready flags in the receive 
> interrupt and 
> > restart the transmission if a transmit interrupt was missed,
> >   - the second was to only service a single interrupt source on 
> each 
> > interrupt (only read IIR once)
> > 
> > The first workaround is obviously problematic since it requires a 
> received 
> > character to restart the transmit.  The second one appeared to be 
> > successful, but since the bug appeared to be somewhat timing 
> sensitive I 
> > don't know for sure if it was eliminated or simply had it's 
> probability 
> > drop by an order of magnitude or so.
> > 
> > Note that the nature of the test would mask any missing receive 
> interrupts 
> > if only an occasional character was dropped.  Receive should be 
> more robust 
> > anyway since each receipt should conceivably re-trigger the 
> interrupt 
> > whereas the transmit interrupt only fires once.
> > 
> > I don't think I kept the original failing code (silly me) but I 
> should be 
> > able to reproduce it if anyone can make use of it.
> > 
> > I first reported on this in this group back on June 23 (see 
> thread "Missing 
> > THRE interrupt?").  It was met with resounding silence so I thought 
> I was 
> > the only one seeing anything like it until this timer interrupt 
> thread.
> > 
> > I've been uncomfortable that I haven't been able to pin down a 
> definitive 
> > cause but I've had other things to do so it's been on the back 
> burner with 
> > a mental "Here be dragons!" sign for future attention.  You have 
> just given 
> > me hope that the cause may yet be found (and more importantly 
> confirmed).
> > 
> > >I suspect there are probably other registers (which can be written 
> to
> > >by both the core and peripheral hardware) which exhibit a similar
> > >problem.  I don't know how much Philips has determined about the
> > >specifics and extent of this bug, since first confirming its
> > >existence.
> > 
> > Certainly if it exists for one peripheral it raises the possibility 
> that it 
> > has occurred in others.
> > 
> > If I knew for sure that the problem was some sort of race condition 
> there 
> > is a chance I could work around it.
> > 
> > Robert
> > 
> > " 'Freedom' has no meaning of itself.  There are always 
> restrictions,
> > be they legal, genetic, or physical.  If you don't believe me, try 
> to
> > chew a radio signal. "
> > 
> >                          Kelvin Throop, III

Move to quarantaine

This moves the raw source file on disk only. The archive index is not changed automatically, so you still need to run a manual refresh afterward.