Pointing multiple interrupt vectors to the same ISR

Go To Last Post
7 posts / 0 new
Author
Message
#1
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Hello All,

 

I am working with an ATMega128, which has INT5, INT6, and INT7 pin interrupts enabled and set to pin change mode. I would like to have a single ISR called whenever either of the three pins change states, however, I'm not sure how to accomplish this in the most efficient way.

 

If the ATMega128 had pin-change interrupts, this would be solved. However, as far as I know, the ATMega128 has no PCINT pins. I know that I could simply setup three ISR functions, one for each INT# pin and just have them all call the same function, but I'm wondering if there is a more effective way to do this?

 

So far, the only thing I have found is the ISR_ALIAS() and ISR_ALIASOF() attributes, but It *seems* like you can only make two vectors point to the same routine (at best). Is there another, more clever way to approach this? Again, ideally, I would like to have all three interrupt pins map to the same function when any of their states change.

 

Thanks!

Jason O

This topic has a solution.
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

I guess if you are using more than two ISRs then writing same code for all three ISRs is only solution.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

My understanding is that you can have more than 2 interrupts vectoring to the same ISR by using alias, I'm fairly sure I've done so myself in the past, but I'm sure someone will be along soon with a definitive answer.

How have you concluded that it doesn't work? Do you get an error message?

 

Four legs good, two legs bad, three legs stable.

This reply has been marked as the solution. 
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 1

This seems to work and inserts the same address in all three vectors

ISR(INT1_vect, ISR_ALIASOF(INT0_vect));
ISR(INT2_vect, ISR_ALIASOF(INT0_vect));

ISR(INT0_vect)
{
    PORTB ^= 1;
}

and this will also work, but costs an extra jump for INT1 and INT2.

ISR_ALIAS(INT1_vect, INT0_vect)
ISR_ALIAS(INT2_vect, INT0_vect)

ISR(INT0_vect)
{
    PORTB ^= 1;
}

 

Last Edited: Fri. May 15, 2015 - 08:01 AM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Hello,

 

Thank you all! I suspected that I needed to use the ISR_ALIASOF() attribute but wasn't sure how to set it up correctly. It compiles fine now!

 

- Jason O

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

@ snigelen it would be helpful if you explain the difference between ALIAS and ALIASOF and how ALIAS costs extra jump?

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 1

@ snigelen it would be helpful if you explain the difference between ALIAS and ALIASOF and how ALIAS costs extra jump?

Well the user manual:

 

http://www.nongnu.org/avr-libc/u...

 

says this:

Note that the ISR_ALIASOF() feature requires GCC 4.2 or above (or a patched version of GCC 4.1.x). See the documentation of the ISR_ALIAS() macro for an implementation which is less elegant but could be applied to all compiler versions.

also (about the original ISR_ALIAS()):

Note

This macro creates a trampoline function for the aliased macro. This will result in a two cycle penalty for the aliased vector compared to the ISR the vector is aliased to, due to the JMP/RJMP opcode used.

Deprecated:

For new code, the use of ISR(..., ISR_ALIASOF(...)) is recommended.

There's clearly a pattern here! Use ISR_ALIASOF() rather than ISR_ALIAS() unless you are using really old, out of data avr-gcc from before GCC 4.2 (current is around 4.8 or 4.9 and 5.0 will be along soon).