Interrupt Recovery

30 Mar 2010

I have been trying to measure the time between 2 pulses on a serial pulse train. see code below...

#include "mbed.h"
Serial pc(USBTX,USBRX);
Timer timer;
InterruptIn event(p16);

int end;

void trigger() {
    end = timer.read_us();
    timer.reset();
    timer.start();
}

int main() {

    event.rise(&trigger);
    
    while(1){
        pc.printf("Time = %d us \r",end);
        wait(0.2);
    }
}

This works fine, until the point where the time between pulses <90 us. At this point the whole thing falls apart. Is this something to do with the IRQ handler's recovery time?

Is there a way round this?

31 Mar 2010

I don't think you need the timer.start() to happen repeatedly. Just start it once. When you reset, the timer doesn't stop.

02 Apr 2010

Thanks Igor, I didn't realise that.

It still takes 90 us to reset - any other ideas?

07 Apr 2010

You can disable the timer in the handler, howver you will miss a pulses if it is that fast. I have not looked at the datasheet but does the microprocessor support multiple stacked interrupts at? was having similar problems at one point, only option that I can think of would be to write your own ISR that is optimized for your needs

07 Apr 2010

I've written a program like this to read the incoming pulses on a pin. Using similar interrupt routines.
But instead of waiting for another rise pulse, I stopped the timer when it was going low. Then i would start it again when going high.
But you can the the opposite, then you'll be reading the low pulse.

27 May 2010

I have the same question about nested interrupts.  Is there a stack?  If so, how deep is it?  If not a stack, is there a queue?

On your pulse problem, I'm doing something similar, but made my own "counter".  Set a "ticker" up to call back every 5 us.  This callback just increments a counter.  Now set another interrupt based on the pulse train level (rising or falling).  The callback for this one gets the current counter value and resets it.  The advantage is that you're not resetting the timer, so you never miss a pulse.  The disadvantage is that the maximum (minimum?) resolution is 5 us. 

I put in some code to make sure the counter didn't ovrerun (not needed - it takes forever using a unsigned ctr), and some more code to make sure that the increment didn't get stomped by a reset or vice versa.  However, the interference never seems to happen.  Also, If you decrease the call back to below 5 us, it gets lost inside the counter increment routine.  Based on these behaviors, I suspect that an interrupt routine can't get interrupted by another, but they queue up somehow. 

Perhaps someone else knows how nested interrupts actually behave. 

--stephen