Multiple GPIO pin activity monitored in a common interrupt handler example?

Status
Not open for further replies.

araasch

New member
I want to decode servo pulses on up to 8 channels using a Teensy 3.1 that are received from a RF servo receiver., I successfully implemented a solution for 4 channels using four separate ISR routines and attachInterrupt() calls.

The signals are positive going pulses with a duration of 1 to 2 ms. The information is encoded in the duration of the pulses so it is desired to measure the pulse width of these 8 channels.

Expanding this multiple ISR scheme out to 8 channels lacks elegance. (Eight ISR handlers where one should do).

It should be possible to code a common ISR to handle all eight of the servo inputs if they are all on GPIO pins from the same port, I.E. PORTC.

I have tried to figure out how to code a common ISR that is triggered when any of the desired GPIO pins change state (falling or rising edge trigger), but have not been successful so far.

Is there any example code available that shows something like this? What I would like is a skeleton program that shows setting up the ISR, enabling a couple GPIO pins on PORTC , I.E. pins 23 and 22 to have an interrupt triggered when the GPIO pins change state.

I am using Arduino 1.6.6 and Teensyduino.

Thanks in advance.
 
Not got much time sorry but have a look at attachinterruptvector()

And this from pins_teensy.c
Code:
static void portc_interrupt(void)
{
	// TODO: these are inefficent.  Use CLZ somehow....
	uint32_t isfr = PORTC_ISFR;
	PORTC_ISFR = isfr;
	if ((isfr & CORE_PIN9_BITMASK) && intFunc[9]) intFunc[9]();
	if ((isfr & CORE_PIN10_BITMASK) && intFunc[10]) intFunc[10]();
	if ((isfr & CORE_PIN11_BITMASK) && intFunc[11]) intFunc[11]();
	if ((isfr & CORE_PIN12_BITMASK) && intFunc[12]) intFunc[12]();
	if ((isfr & CORE_PIN13_BITMASK) && intFunc[13]) intFunc[13]();
	if ((isfr & CORE_PIN15_BITMASK) && intFunc[15]) intFunc[15]();
	if ((isfr & CORE_PIN22_BITMASK) && intFunc[22]) intFunc[22]();
	if ((isfr & CORE_PIN23_BITMASK) && intFunc[23]) intFunc[23]();
	if ((isfr & CORE_PIN27_BITMASK) && intFunc[27]) intFunc[27]();
	if ((isfr & CORE_PIN28_BITMASK) && intFunc[28]) intFunc[28]();
	if ((isfr & CORE_PIN29_BITMASK) && intFunc[29]) intFunc[29]();
	if ((isfr & CORE_PIN30_BITMASK) && intFunc[30]) intFunc[30]();
}
 
I want to decode servo pulses on up to 8 channels using a Teensy 3.1 that are received from a RF servo receiver., I successfully implemented a solution for 4 channels using four separate ISR routines and attachInterrupt() calls.

The signals are positive going pulses with a duration of 1 to 2 ms. The information is encoded in the duration of the pulses so it is desired to measure the pulse width of these 8 channels.

Expanding this multiple ISR scheme out to 8 channels lacks elegance. (Eight ISR handlers where one should do).

It should be possible to code a common ISR to handle all eight of the servo inputs if they are all on GPIO pins from the same port, I.E. PORTC.

I have tried to figure out how to code a common ISR that is triggered when any of the desired GPIO pins change state (falling or rising edge trigger), but have not been successful so far.

Is there any example code available that shows something like this? What I would like is a skeleton program that shows setting up the ISR, enabling a couple GPIO pins on PORTC , I.E. pins 23 and 22 to have an interrupt triggered when the GPIO pins change state.

I am using Arduino 1.6.6 and Teensyduino.

Thanks in advance.

I ran into the same issue. Unfortunately, as you found out, the way this is implemented in teensy, your user code will "lack elegance". This is not the case with AVR library. What you want to do is a standard software engineering code pattern. The closest thing you can do without changing teensy library is to write your separate ISRs, but they all have 1 line calling a common function with a parameter. Then you can do all your processing in one function.
 
Status
Not open for further replies.
Back
Top