How to conditionally choosing between ISRs?

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

Hi all

I am implementing a software uart where I have to implement the corresponding ISR function(PCINT0/1/2) depending on the pin chosen for Rx.For example,what i want is,if the pin belongs to PORTA,ISR will be ISR (PCINT0_vect).If the pin belongs to PORTB,then ISR (PCINT1_vect) & lastly if the pin belongs to PORTC,ISR (PCINT1_vect) will work.But in every case,the ISR body(code inside ISR) will remain the same.

I tried like this below:

#if PORT=='A'
	ISR (PCINT0_vect)
#elif PORT=='B'	
	ISR (PCINT1_vect)
#elif PORT=='C'
	ISR (PCINT2_vect)
#endif		
{
	//This ISR will be entered after the falling edge of the start bit will be detected
	//After that,disable the ISR
	swuartrx_disable();
	swuart_state = RECEIVE;//change the state to receive
	swuart_bitcount = 0x00;//reset the bit count
	OCR0A = ticks2onenhalf;//wait one & half bit period after first falling edge of the start bit is detected
	TCNT0 = 0x00;//reset counter
	enable_timerinterrupt();//start timer
}

I already defined the PORT names as 'A','B'/'C' for simplicity.

But my code is working fine if I write only PCINT1_vect(if the Rx pin is at PC1 for ex).

But Neither the compiler is throwing error,nor the code is working in above case!Any type of guidance about how to do that.....

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0
#define PORT B





#ifdef A
  #error Macro A already defined, but is required for internal use.
#endif
#ifdef B
  #error Macro B already defined, but is required for internal use.
#endif
#ifdef C
  #error Macro C already defined, but is required for internal use.
#endif
#define A 0
#define B 1
#define C 2

#if (PORT == 0)
  #define MY_VECT PCINT0_vect
#elif (PORT == 1)
  #define MY_VECT PCINT1_vect
#elif (PORT == 2)
  #define MY_VECT PCINT2_vect
#end

#undef A
#undef B
#undef C
#undef D

ISR(MY_VECT){
  // Your ISR code here.
}

 

 

You can use the same technique to construct macros for the SFR name and bit names you need to configure the interrupt.

 

 

"Experience is what enables you to recognise a mistake the second time you make it."

"Good judgement comes from experience.  Experience comes from bad judgement."

"Wisdom is always wont to arrive late, and to be a little approximate on first possession."

"When you hear hoofbeats, think horses, not unicorns."

"Fast.  Cheap.  Good.  Pick two."

"We see a lot of arses on handlebars around here." - [J Ekdahl]

 

Last Edited: Sat. Jul 6, 2019 - 09:14 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Do you have other code section(s) that depend upon which pin is being used?  Where do you enable the particular interrupt that is to be used?

When in the dark remember-the future looks brighter than ever.   I look forward to being able to predict the future!

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

I would keep as many defines together as possible, so you don't have to wade through a bunch of #if's in your code. You already have a handful created in one spot I presume, so add a few more in the same place so you can see them all at once when making any changes.

 

I used your naming-

https://www.avrfreaks.net/forum/changing-isr-depending-pin-definition

 

#define swuart_port_ltr B

#if swuart_port_ltr == B
#define swuart_vector PCINT0_vect
#elif swuart_port_ltr == C
#define swuart_vector PCINT1_vect
#elif swuart_port_ltr == D
#define swuart_vector PCINT2_vect
#else
error "Invalid swuart port letter"
#endif

ISR (swuart_vector)
{
}

 

You can also just use PCINT0 for any pin interrupt and alias PCINT1/2 to the same isr, not sure if useful but can be done (this is found in interrupt.h)-

ISR (PCINT0_vect)
{
}
ISR(PCINT1_vect, ISR_ALIASOF(PCINT0_vect));
ISR(PCINT2_vect, ISR_ALIASOF(PCINT0_vect));

 

Last Edited: Sun. Jul 7, 2019 - 06:18 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Yes,they are being handled perfectly fine except the ISR part.I also tried like this below previously but that was throwing error that maybe the ISR is misspelled.

 

#if PORT=='B'
	#if rx_pin==0
	#define PCINT PCINT0
	#elif rx_pin==1
	#define PCINT PCINT1
	#elif rx_pin==2
	#define PCINT PCINT2
	#elif rx_pin==3
	#define PCINT PCINT3
	#elif rx_pin==4
	#define PCINT PCINT4
	#elif rx_pin==5
	#define PCINT PCINT5
	#elif rx_pin==6
	#define PCINT PCINT6
	#elif rx_pin==7
	#define PCINT PCINT7
	#define PCINTvect PCINT0_vect
	#endif
#elif PORT=='C'
	#if rx_pin==0
	#define PCINT PCINT8
	#elif rx_pin==1
	#define PCINT PCINT9
	#elif rx_pin==2
	#define PCINT PCINT10
	#elif rx_pin==3
	#define PCINT PCINT11
	#elif rx_pin==4
	#define PCINT PCINT12
	#elif rx_pin==5
	#define PCINT PCINT13
	#define PCINTvect PCINT1_vect
	#endif
#elif PORT=='D'
	#if rx_pin==0
	#define PCINT PCINT16
	#elif rx_pin==1
	#define PCINT PCINT17
	#elif rx_pin==2
	#define PCINT PCINT18
	#elif rx_pin==3
	#define PCINT PCINT19
	#elif rx_pin==4
	#define PCINT PCINT20
	#elif rx_pin==5
	#define PCINT PCINT21
	#elif rx_pin==6
	#define PCINT PCINT22
	#elif rx_pin==7
	#define PCINT PCINT23
	#define PCINTvect PCINT2_vect
	#endif	
#endif


static inline void swuartrx_enable(void)	 
{								
	if(PORT=='B')
	{
		PCICR |= (1<<PCIE0);		
		PCMSK0 |= (1<<PCINT);
	}
	else if(PORT=='C')
	{				
		PCICR |= (1<<PCIE1);		
		PCMSK1 |= (1<<PCINT);
	}
	else if(PORT=='D')
	{				
		PCICR |= (1<<PCIE2);		
		PCMSK1 |= (1<<PCINT);		
	}
}


static inline void swuartrx_disable(void)
{
	PCICR = 0X00;
	
	if(PORT=='B')
	{
		PCMSK0  = 0x00;
	}
	else if(PORT=='C')
	{				
		PCMSK1 = 0x00;
	}
	else if(PORT=='D')
	{				
		PCMSK2  = 0x00;		
	}
}

static inline void enable_timerinterrupt(void)
 {
	TCCR0A |= (1<<WGM01);
	TCCR0B |= ((1<<CS01)|(1<<CS00));
	TIMSK0 |= (1<<OCIE0A);
	TCNT0 = 0X00;
}

/* CTC mode,timerclock - sysclk/64 i.e 0.25MHz,so each tick = 4uS */

static inline void  disable_timerinterrupt()
{
	TCCR0A = 0X00;
	TCCR0B = 0X00;
	TIMSK0 = 0x00;
}

static inline void clear_timerinterrupt(void)
{
	TIFR0 |= (1<<OCF0A);
}

 

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


same warning appearing like mine....."misspelled signal handler".

 

 

I modified the code like below.

 

#if PORT=='B'
	#if rx_pin==0
	#define PCINT PCINT0
	#elif rx_pin==1
	#define PCINT PCINT1
	#elif rx_pin==2
	#define PCINT PCINT2
	#elif rx_pin==3
	#define PCINT PCINT3
	#elif rx_pin==4
	#define PCINT PCINT4
	#elif rx_pin==5
	#define PCINT PCINT5
	#elif rx_pin==6
	#define PCINT PCINT6
	#elif rx_pin==7
	#define PCINT PCINT7
	#define MY_VECT PCINT0_vect
	#endif
#elif PORT=='C'
	#if rx_pin==0
	#define PCINT PCINT8
	#elif rx_pin==1
	#define PCINT PCINT9
	#elif rx_pin==2
	#define PCINT PCINT10
	#elif rx_pin==3
	#define PCINT PCINT11
	#elif rx_pin==4
	#define PCINT PCINT12
	#elif rx_pin==5
	#define PCINT PCINT13
	#define MY_VECT PCINT1_vect
	#endif
#elif PORT=='D'
	#if rx_pin==0
	#define PCINT PCINT16
	#elif rx_pin==1
	#define PCINT PCINT17
	#elif rx_pin==2
	#define PCINT PCINT18
	#elif rx_pin==3
	#define PCINT PCINT19
	#elif rx_pin==4
	#define PCINT PCINT20
	#elif rx_pin==5
	#define PCINT PCINT21
	#elif rx_pin==6
	#define PCINT PCINT22
	#elif rx_pin==7
	#define PCINT PCINT23
	#define MY_VECT PCINT2_vect
	#endif	
#endif

 

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

>"misspelled signal handler"

 

That means you have defined a signal/interrupt name that does not start with __vector

 

Which means whatever you put in the ISR macro is not correct. Since you do not show how you define PORT anywhere that I can see, I assume that is the source of the problem.

 

#define PORT B

#if PORT == B

 

#define PORT 'B'

#if PORT == 'B'

 

Mix them up and they will not match, which ultimately means the MY_VECT is not defined, and not expanded in the ISR macro, hence the bad name (ends up with MY_VECT as the name).

 

If your ide does not expand macros so you can see what's going on, just add a fail option-

#else
error "Invalid letter here, fix it"
#endif

 

 

edit-

this will also cause your problem-

	#elif rx_pin==5
	#define PCINT PCINT13
	#define MY_VECT PCINT1_vect
	#endif

you are only defining MY_VECT for the last pin in each port group (in the last code posted)

I can't really piece together what your code is, but the last bit posted would cause the isr problem if you are using anything other than the last pin in a group.

Last Edited: Sun. Jul 7, 2019 - 04:29 AM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

edit-

this will also cause your problem-

	#elif rx_pin==5
	#define PCINT PCINT13
	#define MY_VECT PCINT1_vect
	#endif

you are only defining MY_VECT for the last pin in each port group (in the last code posted)

I can't really piece together what your code is, but the last bit posted would cause the isr problem if you are using anything other than the last pin in a group.

Excellent observation....this was creating my problem.Now,I simply tweaked the code like this & the "misspelled" error is gone...Though i didn't test the code in real time but should work as expected.

 

#if PORT=='B'
	#define MY_VECT PCINT0_vect
	#if rx_pin==0
	#define PCINT PCINT0
	#elif rx_pin==1
	#define PCINT PCINT1
	#elif rx_pin==2
	#define PCINT PCINT2
	#elif rx_pin==3
	#define PCINT PCINT3
	#elif rx_pin==4
	#define PCINT PCINT4
	#elif rx_pin==5
	#define PCINT PCINT5
	#elif rx_pin==6
	#define PCINT PCINT6
	#elif rx_pin==7
	#define PCINT PCINT7
	#endif
#elif PORT=='C'
	#define MY_VECT PCINT1_vect
	#if rx_pin==0
	#define PCINT PCINT8
	#elif rx_pin==1
	#define PCINT PCINT9
	#elif rx_pin==2
	#define PCINT PCINT10
	#elif rx_pin==3
	#define PCINT PCINT11
	#elif rx_pin==4
	#define PCINT PCINT12
	#elif rx_pin==5
	#define PCINT PCINT13
	#endif
#elif PORT=='D'
	#define MY_VECT PCINT2_vect
	#if rx_pin==0
	#define PCINT PCINT16
	#elif rx_pin==1
	#define PCINT PCINT17
	#elif rx_pin==2
	#define PCINT PCINT18
	#elif rx_pin==3
	#define PCINT PCINT19
	#elif rx_pin==4
	#define PCINT PCINT20
	#elif rx_pin==5
	#define PCINT PCINT21
	#elif rx_pin==6
	#define PCINT PCINT22
	#elif rx_pin==7
	#define PCINT PCINT23
	#endif	
#endif