0
votes

I am using an LPC2378 (ARM7TDMI-S) uC for a project. Timer0 on the uC is being used to measure frequency of a signal on one of the inputs of the uC. It is setup to interrupt on the rising edge of the signal (input capture) as well as interrupt on match register. The match register interrupt is set such that an interrupt occurs every 50mS. In my main code I have a while loop, which will only exit if a variable is set which only happens whenever the match interrupt of timer0 occurs. My ISR looks like this

static __irq __arm void TIMER_handler0(void) {
  
  DWORD T0int;
  T0int = T0IR;
  
  if (T0int & IIR_CR0) {          // interrupt due to rising edge
    T0IR_bit.CR0INT = 1;    // acknowledge interrupt 
    //Do stuff to figure out frequency of input signal

  }
  
  if ((T0int & IIR_MR0) || (T0int & IIR_MR1)) {    // interrupt due to match
    T0IR_bit.MR0INT = 1;    // acknowledge interrupt
    T0CCR_bit.CAP0I = 0;    // turn off both interrupts (capture & match)
    T0MCR_bit.MR0I = 0;   
    T0TCR_bit.CE = 0;       // turn off the counter and reset the counter register
    T0TC = 0;
    timer0busy = 0;
  } 
  VICADDRESS = 0x0;   
}

While loop in my main code checks "timer0busy" flag and looks like this

while(timer0busy) {
       //Do stuff
}

"timer0busy" flag is set to 1 when the timer0 is enable which is done before this while loop

On some occasions I have noticed that my uC would stop sending output through the UART. On further invertigation I found that it was stuck in the above while loop because "timer0busy" flag never became 0. I did some more testing and figured that this usually happens when the frequency of the input signal (which is measured by timer0) is increased. Now my understanding is that as the frequency of the input signal is increased the interrupts due to rising edge will also increase, but what I cannot figure out is that why does at some point the interrupt due to match register stops happening. The match register is setup to interrupt every 50mS regardless of the frequency of the input signal, and when this interrupt happens, interrupts are disabled and flag is set to 0. For both capture and match register interrupts the ISR is the same. Is the timer overshooting the match value without getting caught?. I don' know how that could happen. What would happen if the rising edge and match happens at the same time?. Could this be the result when that happens

1

1 Answers

1
votes

At what frequency approximately does interrupt no longer work?

From what I understand this part of interrupt runs at every rising edge of the signal:

  if (T0int & IIR_CR0) {          // interrupt due to rising edge
      T0IR_bit.CR0INT = 1;    // acknowledge interrupt 
      //Do stuff to figure out frequency of input signal
  }

Are you sure it has enough time to run before interrupt is triggered again? I would count clock cycles if you're unsure.

LPC2378 Does not have a Nester VIC, just a regular VIC. What that means is if interrupt A has occurred, and while it is mid-way through running, interrupt B is triggered, regular VIC cannot pause process called by A, run process B, then reenter A. It runs process A to completion, then runs process B.

My guess is that when frequency of your signal is high enough, your system calls interrupt upon interrupt without time to execute them to completion, causing a rapidly growing build up of work until VIC panics.

Try limiting the frequency of interrupts due to rising edge (like every second edge) when frequency gets too high.