trouble with gpio interrupt

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

Hi, I'm using EVK1101 and there is two push buttons PB0 and PB1 connected to pins PB02 and PB03.
I'm trying to make a simple program which will execute appropriate interrupt routine when I push the button PB0 or PB1 without using EIC controller.

// Include Files
#include "board.h"
#include "intc.h"
#include "gpio.h"
#include "print_funcs.h"
#include "pm.h"


// interrupt handler 1
__attribute__((__interrupt__))
static void prekidni_handler_1 (void)
{
	print_dbg("first handler\n");
	gpio_tgl_gpio_pin(LED0_GPIO); // Toggle the LED0.
	int i=0;
	while(i<65000)
		i++;
    gpio_clear_pin_interrupt_flag(AVR32_PIN_PB02);
}

// interrupt handler 2
__attribute__((__interrupt__))
static void prekidni_handler_2 (void)
{
	print_dbg("second handler\n");
	gpio_tgl_gpio_pin(LED1_GPIO); // Toggle the LED1.
	int i=0;
	while(i<65000)
		i++;
    gpio_clear_pin_interrupt_flag(AVR32_PIN_PB03);
}

int main(void) {

	pm_switch_to_osc0(&AVR32_PM, FOSC0, OSC0_STARTUP);
	init_dbg_rs232(FOSC0);
	print_dbg("inicijalizacija\n");

	gpio_set_gpio_pin(LED0_GPIO);//led 1 off
	gpio_clr_gpio_pin(LED1_GPIO);//led 2 on

	gpio_enable_pin_interrupt(AVR32_PIN_PB02 , GPIO_RISING_EDGE);
	gpio_enable_pin_interrupt(AVR32_PIN_PB03 , GPIO_RISING_EDGE);

	// Disable all interrupts.
	Disable_global_interrupt();

	  // Initialize interrupt vectors.
	INTC_init_interrupts();
	INTC_register_interrupt(&prekidni_handler_1,AVR32_GPIO_IRQ_0+AVR32_PIN_PB02/8,AVR32_INTC_INT0);
	INTC_register_interrupt(&prekidni_handler_2,AVR32_GPIO_IRQ_0+AVR32_PIN_PB03/8,AVR32_INTC_INT0);

	  Enable_global_interrupt();
	  while(1);
	return 0;
}

This code doesn't work. It works if I use only one push button and one interrupt handler, like this one:

// Include Files
#include "board.h"
#include "intc.h"
#include "gpio.h"
#include "print_funcs.h"
#include "pm.h"


// interrupt handler 1
__attribute__((__interrupt__))
static void prekidni_handler_1 (void)
{
	print_dbg("first handler\n");
	gpio_tgl_gpio_pin(LED0_GPIO); // Toggle the LED0.
	int i=0;
	while(i<65000)
		i++;
        gpio_clear_pin_interrupt_flag(AVR32_PIN_PB02);
}

int main(void) {

	pm_switch_to_osc0(&AVR32_PM, FOSC0, OSC0_STARTUP);
	init_dbg_rs232(FOSC0);
	print_dbg("inicijalizacija\n");

	gpio_set_gpio_pin(LED0_GPIO);//led 1 off

	gpio_enable_pin_interrupt(AVR32_PIN_PB02 , GPIO_RISING_EDGE);

	// Disable all interrupts.
	Disable_global_interrupt();

	  // Initialize interrupt vectors.
	INTC_init_interrupts();
	INTC_register_interrupt(&prekidni_handler_1,AVR32_GPIO_IRQ_0+AVR32_PIN_PB02/8,AVR32_INTC_INT0);

	  Enable_global_interrupt();
	  while(1);
	return 0;
}

What is wrong with the first code?

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

Hi
Those lines seem strange to me:
INTC_register_interrupt(&prekidni_handler_1,AVR32_GPIO_IRQ_0+AVR32_PIN_PB02/8,AVR32_INTC_INT0); INTC_register_interrupt(&prekidni_handler_2,AVR32_GPIO_IRQ_0+AVR32_PIN_PB03/8,AVR32_INTC_INT0);

Second argument can be incorrect. Chech AVR32_GPIO_IRQ_0+AVR32_PIN_PB03/8. AVR32_PIN_PB03 is odd value. It seems that it is caclulated wrong. Try to use clear defined value here

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

Hello!

this is my example in other board, EVK1100 but is similar to EVK1101. I use the joystick of the board to simulate an interrupt external.

/** CONFIGURING THE JOYSTICK PUSH EXTERNAL INTERRUPT **/

  gpio_enable_pin_interrupt(AVR32_EIC_EXTINT_8_PIN, GPIO_PIN_CHANGE);

  //One group of interrupt has 8 interrupt.We need to known the group
  INTC_register_interrupt( (__int_handler)&joystickPush_ISR, AVR32_GPIO_IRQ_0 + (AVR32_EIC_EXTINT_8_PIN/8), AVR32_INTC_INT0);
 

I´m using FreeRTOS, but if you don´t use it, you haven´t to declarate the naked function.


//function to attend the interrupt external
__attribute__((__noinline__))
static portBASE_TYPE prvjoystickPush_ISR_NonNakedBehaviour( void )
{
	/* Now we can declare the code */
        The rest of code of interrupt

    gpio_clear_pin_interrupt_flag(GPIO_JOYSTICK_PUSH);
    /* The return value will be used by portEXIT_SWITCHING_ISR() to know if it
       should perform a vTaskSwitchContext(). */
    // False because don't change the task when the interrupt happened
    //Reset the Interrupt
	return (pdFALSE);
}


__attribute__((__naked__))
void joystickPush_ISR( void )
{
   /* This ISR can cause a context switch, so the first statement must be a
  	call to the portENTER_SWITCHING_ISR() macro.  This must be BEFORE any
  	variable declarations. */
  	portENTER_SWITCHING_ISR();

  	prvjoystickPush_ISR_NonNakedBehaviour();

  	/* Exit the ISR.  If a task was woken then a context switch will occur. */
  	portEXIT_SWITCHING_ISR();
}

i hope that useful for you

Gary

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

Hi, thanks for helping, but I solved it before with using one interrupt function and testing which button is pressed, like this:

__attribute__((__interrupt__))
static void prekidni_handler (void)
{
  if( gpio_get_pin_interrupt_flag( AVR32_PIN_PB02 ) )
  {      // PB2 generated the interrupt.
	  print_dbg("Interrupt for PB0\n");
	  gpio_tgl_gpio_pin(LED0_GPIO);
		int i=0;
		while(i<65000)
			i++;

      gpio_clear_pin_interrupt_flag(AVR32_PIN_PB02);
  }
  if( gpio_get_pin_interrupt_flag( AVR32_PIN_PB03 ) )
  {      // PB3 generated the interrupt.
	  print_dbg("Interrupt for PB01\n");
	  gpio_tgl_gpio_pin(LED1_GPIO);
		int i=0;
		while(i<65000)
			i++;
      gpio_clear_pin_interrupt_flag(AVR32_PIN_PB03);
  }

}

and this

	INTC_register_interrupt(&prekidni_handler,AVR32_GPIO_IRQ_0+AVR32_PIN_PB02/8,AVR32_INTC_INT0);
	INTC_register_interrupt(&prekidni_handler,AVR32_GPIO_IRQ_0+AVR32_PIN_PB03/8,AVR32_INTC_INT0);
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Please do not busy wait in an interrupt handler ;)

Hans-Christian

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

hce wrote:
Please do not busy wait in an interrupt handler ;)

:D ok