using multiple mutually exclusive interrupt handers on the same interrupt

I was going through several pages trying to find out if it is possible to setup multiple mutually exclusive interrupt handlers on the same interrupt, and I am not getting anywhere. Here are a couple of those pages:

So, my idea is that I setup a handler, use it for a while, and then change that same handler to another handler, perhaps even back to the default handler. However, defining a replacement ISR such as ISR(TIMER0_COMPA_vect) would seem to override the default handler, thus permanently invalidating millis() and delay() usage for any programme I would write.

Is there a way of getting the default handler back? Can I change the handler to another handler (user or default) mid-execution? I don't see why I shouldn't since I'm think I should be just changing a pointer in the vector table. Or is there more going on than this?

I know that I could put in a function pointer that I can call within my declared vector and change that pointer, but I was wondering if there was a lower way of doing this.

Thanks,

Adrian

Hmmm, no one has an answer? I'm thinking that I could modify the vector table directly... I'll have to experiment.

When I want to intercept one of the interrupts that is already handled by the Arduino core (such as timer 0), I generally modify the core, adding a function I can call to hook my own interrupt handler in.

What I usually do is have a global variable (volatile) which is a function pointer. You have one ISR which inspects that function pointer, and if it's set, call the function it points to. You just point that pointer to whatever function you want to use at the time.

This is what I have for my ChipKit RTCC library's interrupt routine:

void (*_RTCCInterrupt)();

void __ISR(_RTCC_VECTOR, _RTCC_IPL_ISR) _RTCCInterruptHandler(void)
{
    if(_RTCCInterrupt)
    {
        _RTCCInterrupt();
    }
    IFS1CLR=0x00008000;
}

void RTCCClass::attachInterrupt(void (*i)())
{
    _RTCCInterrupt = i;
}

(Of course, the IFS stuff is PIC32 specific, but it gives you the idea).

_RTCCInterrupt is a function pointer which if set is called from within the interrupt routine. RTCC.attachInterrupt(&function) assigns a function to that pointer for later use.

majenko:
What I usually do is have a global variable (volatile) which is a function pointer.

Yeah, I stated that in my 1st post. But thanks. :slight_smile:

majenko:
(Of course, the IFS stuff is PIC32 specific, but it gives you the idea).

Are you referring to IFS1CLR? It isn't even reference in the UNO datasheet.

Thanks again.

dc42:
When I want to intercept one of the interrupts that is already handled by the Arduino core (such as timer 0), I generally modify the core, adding a function I can call to hook my own interrupt handler in.

Eek! :slight_smile: I hate to mod the core except as an absolute last resort. But yeah, I can see that.

I was trying to see if the ISR handler could just be switched around at runtime at the ISR vector table level.

Thanks

adrian_h:

majenko:
What I usually do is have a global variable (volatile) which is a function pointer.

Yeah, I stated that in my 1st post. But thanks. :slight_smile:

TL;DR. :slight_smile:

majenko:
(Of course, the IFS stuff is PIC32 specific, but it gives you the idea).

Are you referring to IFS1CLR? It isn't even reference in the UNO datasheet.

Thanks again.

Yeah, you can ignore that line :wink: It won't be in the UNO datasheet. The ATMega328P data sheet gives details of an equivalent for clearing the interrupt flag once it has occurred (if needed).

The custom ISR vector variable is the normal way of doing it. On some ISRs I maintain an array of callbacks for calling when the ISR is triggered. One fancy one I have uses a structure including a frequency and counter variable, and the timer triggers the ISR every millisecond. The counters of all the callback entries are decremented (starting at the frequency value), and when it hits 0 it calls the callback, resetting the counter to frequency. Allows me to set up many time triggered callbacks with 1ms granularity off just one timer - very useful.

Can be a bit expensive, but very flexible. Nice.

adrian_h:
Can be a bit expensive, but very flexible. Nice.

Depends on your chip. I wouldn't do it on an UNO, but on something like DUE it's fine.