This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

What is MSP430 maximum interrupt frequency?

Other Parts Discussed in Thread: MSP430F2617

Hey guys,

I'm working with the MSP430F2617 running at a clockspeed of 3,9 Mhz. I'm using the Contiki OS on it to experiment in the WSN domain.

I connected a light sensor to an interrupt pin and wanted to read out the frequency (number of pulses/interrupts generated in one second). For low frequencies my program doesn't encounter problems and can count the exact number of pulses. However, when the frequency goes to around 70, 80, 90 kHz It start reading out completely wrong values. Above a frequency of 90kHz the µC starts to have problems and seems to reboot itself and is not working properly.

I was now wondering why this was happening. Can the µC not handle the interrupt frequencies above 70 kHz because they are generated too fast, or is there something happening in the register? Because the register in which I increment the number of pulses is 16 bit so 65536 pulses which is close to the frequency of 70kHz where things go wrong.

How can I compute or now the maximum number of interrupts? I looked in the data sheet to see how many cycles an instruction takes, but I can not guess how many instructions there are executed in the interrupt routine.

The interrupt routine is very short:

interrupt(PORT2_VECTOR)
     irq_p2(void)
{
  ENERGEST_ON(ENERGEST_TYPE_IRQ);
  P2IFG = 0x00;
  puls = puls+1;
  leds_toggle(LEDS_GREEN);
  ENERGEST_OFF(ENERGEST_TYPE_IRQ);
}

Hope someone can give me an answer.

Best regards!

  •  Hi, just a moment I use my magic sphere:

    peter charl said:

    interrupt(PORT2_VECTOR)
         irq_p2(void)
    {
      ENERGEST_ON(ENERGEST_TYPE_IRQ);
      P2IFG = 0x00;
      puls = puls+1;
      leds_toggle(LEDS_GREEN);
      ENERGEST_OFF(ENERGEST_TYPE_IRQ);
    }

    Hope someone can give me an answer.

     The answer is : there where some obscure part we cannot imagine what are doing and can grow stack or mangle something or waste too much cpu time and also reenable interrupt too....

  • peter charl said:

    How can I compute or now the maximum number of interrupts? I looked in the data sheet to see how many cycles an instruction takes, but I can not guess how many instructions there are executed in the interrupt routine.

    In the MSP430 2xx family user guide, it states that it takes 6 cycles from when an interrupt request is accepted to when the first instruction is executed. An interrupt service routine, at the very minimum, contains RETI (return from interrupt) instruction, which takes 5 cycles. So in total this bare-bone ISR takes 11 cycles. This then gives the theoretical maximum of ~354k interrupts per second for MCLK of 3.9MHz.

    Of course this ISR doesn't do much. If you add an instruction that toggles, say, the entire P2, then you need to add

    INV.B &P2OUT

    to the ISR, which takes 4 cycles (register to absolute addressing mode). Now the ISR takes 15 cycles, and you can toggle PORT2 at a frequency of 260KHz.

    However, this is all in pure assembly doing fairly trivial stuff. If you write the ISR in C with external function calls and possibly pushing/popping the stack, then you would get a lot more overhead; add in the RTOS, and I'd say you're lucky to get 70KHz at 3.9MHz.

    If you're counting input frequency, then I would suggest using Timer_A in MSP430 which can count, trigger, and capture much more precisely than in software, all without CPU intervention (works even down to LPM3). It's fairly painless to use, see TI's code examples for MSP430F261x.

    Tony

  • Hey Tony,

    Thanks for the answer, that's what I wanted to know. I was trying to guess the number of cycles like you did by looking in the user guide but found it hard to make assumptions since I work in higher level language instead of assembler.

    I just wanted to have an indication to be sure that the cpu was reaching maximum interrupt frequency and therfore stopped functioning normally.

    I already implemented the Timer_A for counting the pulses and like you say that worked fine for me. I did some tests a couple of days ago and I can count much higher frequencies pretty accurate. Now there is only 1 interrupt every 65536 pulses which is an ideal solution for my application.

    Thank you

  • peter charl said:
    How can I compute or now the maximum number of interrupts?

    The maximum number of interrupts is the number of different interrupt sources. But I don't think that's what you want to know :)

    The maximum interrupt frequency is determined by the CPU speed, the tiem for exiting LPM (if used), the latency for entring and exiting the ISR (see users guide, about 11 MCLK cycles) and the execution time of the code inside the ISR.
    And here your code uses three function calls which may require an unknown execution time and also clobber soem registers which need to be saved and restored by the ISR entry/exit code.

    On 3.6MHz PCU speed and 70kHz pulse frequency, you have 3.6m/70k?51 clock cycles per interrupt.  Each function call (including the return from the function) takes 7, preparign the passed parameter rquires 1 or 3 each (depending on the parameter value), = 24 to 30 total. The ISR takes 11,  12 for the saving of registers during the function calls, the assignment and increment take 7. So we are at 54-60 cycles, without the code in the three funciton you call.

    Guess what happens? Yeah, you're losing interrupts. Plain math.

    For counting pulses at high frequencies, one usually uses a hardware counter. Such as one of the timers. Then you can go up to maximum system frequency without losing a pulse. Well, you cannot do fancy things then on every pulse. But who wants to see an LED blink with 70kHz anyway?

  • Jens-Michael Gross said:
    Guess what happens? Yeah, you're losing interrupts. Plain math.

     Losing interrupt service never restart cpu, I suppose one of called routine reenable interrupt so stack grow to variable area then to empty space.

  • Roberto Romano said:
    Losing interrupt service never restart cpu

    Yep, not directly (well, it can prevent main from triggerign the WDT in time, if main isn't executed at all anymore due to eternal ISR loop), bu tI was responding to 'start reading out completely wrng values'

    Without knowing the other code, trying to detect the cause for a reset is fruitless anyway.

**Attention** This is a public forum