10 years, 10 months ago.

Can I use InterruptIn to receive interrupt at freq > 90 kHz

Dear all, I try to use example from InterruptIn (code below). I feed pin 5 with square signal. The interrupt service routing flip() simply toggle pin 7. So if pin 5 is feed with signal at frequency 50 kHz, then pin 7 will be toggled at frequency 25 kHz, this is because the toggling happens between 2 interrupts. I check the output at pin 7 using oscilloscope and it is correct. The problem is when I feed pin 5 with signal 100 kHz, then pin 7 is not toggled in frequency 50 kHz. The limit is 90 kHz in pin 5 an 45 kHz in pin 7. What is the problem? I checked the SystemCoreClock is 96 MHz, I suppose that the interrupt latency and the ISR code can handle interrupt frequency > 100 kHz. Please help me with this problem.

Below is my test code:

InterruptIn pin5(p5); DigitalOut pin7(p7); int out_value = 0;

/* Interrupt service routine. In this method we just toggle pin7, to see the response time using Ch. A connected to pin7

  • / int mask_pin7 = 1 << 7; static void flip() { toggle ^= 1; if (toggle) { LPC_GPIO0->FIOSET |= mask_pin7; } else { LPC_GPIO0->FIOCLR |= mask_pin7; } }

int main() { printf("SystemCoreClock = %d Hz\n", SystemCoreClock); pin5.rise(&flip); while (1) {

I looked more into it, and the main issue is that here is only a single GPIO interrupt vector, so when an interrupt is created the mbed library needs to search for which pin it is. Luckily that can be faster than currently is done, see: http://mbed.org/users/mbed_official/code/mbed/issues/4

Specifically, if you import http://mbed.org/users/Sissors/code/mbed-src/, delete the current mbed library from your program, it should work up to roughly 4 times higher speeds. It would be nice to know if that indeed works for you.

posted by Erik - 22 Jun 2013

1 Answer

10 years, 10 months ago.

Putting your code between code tags (<<code>> and <</code>>) helps.

I just did a quick and dirty test: Connected p9 with p10, start timer, write a 1 to p9, with interrupt attached to p10 which stops the timer. With that I get 4us runtime (1us was the reference of just the digitalout code + timer start/stop, of course it has 1us resolution with the standard mbed timer). Also if I directly added a timer read after the DigitalOut = 1, to see if it took more time to leave the interrupt routine, but that also returned 4us.

So with that you would guess you should be able to get above 90kHz. Still the InterruptIn has quite a bit of overhead. Directly writing to the interrupt registers should be able to significantly reduce that. Or maybe you can use one of the timers for whatever it is you want to do with an input pin.

EDIT: That 4us is incorrect, it will be longer. So your result is probably accurate. The problem is that it is one interrupt for all GPIO pins, so when an interrupt goes off it has to search which ones happened. This can be done more efficiently than it is now probably, but it still will be longer than when you manually set the registers for your specific requirement.