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 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....
Regards
Roberto
Please login & click Verify Answer if this post answered your question.
peter charl 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 charlHow can I compute or now the maximum number of interrupts?
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?
_____________________________________Before posting bug reports or ask for help, do at least quick scan over this article. It applies to any kind of problem reporting. On any forum. And/or look here.If you cannot discuss your problem in the public, feel free to start a private conversation: click on my name and then 'start conversation'. But please do so only if you really cannot do it in a public thread, as I usually read all threads. And I prefer to answer where others can profit from it (or contribute to it) too.
Jens-Michael GrossGuess 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 RomanoLosing interrupt service never restart cpu
Without knowing the other code, trying to detect the cause for a reset is fruitless anyway.