simple GPIO Interrupts frustrating

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

I am struggling to get to grips with a simple GPIO interrupt. I see this issue has come up numerous times, but no adequate solution for my specific application.

I have an ATUC3A0512 cpu device on my own PCB. I am wanting to use port pin PX33 to create an interrupt when a radio module receives data.

Now to use

void INTC_register_interrupt (__int_handler handler, uint32_t irq, uint32_t ,int_level)

I need to know "˜irq' as would be applicable to pin PX33.

Datasheet refers to groups by nowhere can I find any suitable documentation regards the "group" PX33 interrupt would be associated to.

As an example, the USART example provided for EVK1105 uses "EXAMPLE_USART_IRQ" which equates to a value of 192.

So far, I have the USART interrupt working, but cannot get a simple GPIO interrupt working via INTC. I have tried a few values for IRQ such as 71 (GPIO pin number is 71), but none have resulting in a working interrupt.

Anybody have any idea as to the correct value to be used for IRQ

Thanx
Brian

void register_DR_interupt(void)
{

// Disable all interrupts
Disable_global_interrupt();
INTC_init_interrupts();

// Register GPIO Pin Change Interrupt
INTC_register_interrupt(&DR_int_handler, 71, AVR32_INTC_INT2);

// Enable pin change interrupt for GPIO_PIN
gpio_enable_pin_interrupt(PIN_DR, GPIO_RISING_EDGE);
// Enable all interrupts
Enable_global_interrupt();
} :( :(

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

You need to go through the "External Interrupt Controller" (EIC) module on the UC3 devices to get pin state change interrupts. You can find some examples for the EIC in ASF inside Atmel Studio 6.

- Dean :twisted:

Make Atmel Studio better with my free extensions. Open source and feedback welcome!

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

Thanx for the reply Dean

Just for my information .. my understanding is that EIC module deals with specific dedicated pins for EIC. My pin PX33 is not a "dedicated" interrupt pin, thus my understanding is to use INTC module. Is this understanding not correct?

Thanx
Brian

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

The INTC module is the overall interrupt controller for the device - it manages interrupts for the entire device, by mapping input lines from other peripherals to user provided functions. You can't link anything you want via the INTC; it needs a valid internal interrupt line from another module (such as the ADC, DAC, etc.).

Interrupts from external pins (to detect rising/falling edges) are managed by the EIC module, which can read the current state of certain GPIO pins and perform the neccesary edge detection. When the EIC module detects a condition you have set up, it can raise the INTC module to run your interrupt handler.

This means you can't map a GPIO directly to the INTC, it has to go through the EIC first.

- Dean :twisted:

Make Atmel Studio better with my free extensions. Open source and feedback welcome!

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

Thanx Dean .. I understand what your saying.

I had a look at 3 examples in Studio 6 and all use dedicated external interrupt pins. No examples exist for using a general GPIO pin.

Now from the mapping examples, I would assume I need to provide a link to my pin PX33

eic_options[0].eic_line = ??????

I get no help from Studio 6 help prompts.

Brian

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

Just for your information. It's possible to get interrupt straight from GPIO module as well. Just set IMRn registers accordingly to enable pin change, rising edge or falling edge, and then enable GPIO interrupts via IER register.

In UC3A1 there are 14 general purpose i/o interrupts that go to group 2. PA00-13 can be used for these.

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

Well that's what ....

gpio_enable_pin_interrupt(PIN_DR, GPIO_RISING_EDGE);

does. I can see via JTAGICE that IMR is set and so is IER. But you got to register the interrupt still and there lies the problem.

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

MrDIY wrote:
But you got to register the interrupt still and there lies the problem.
Of course INTC has to be setup properly as well and I think I understand the problem now. There's a simple formula to calculate IRQ values from line and group. I bet I have seen that in datasheet or AVR32 header files. However, couldn't found that now, but found these from uc3a1128.h header file:
#define AVR32_GPIO_IRQ_0                  64
#define AVR32_GPIO_IRQ_1                  65
#define AVR32_GPIO_IRQ_2                  66
#define AVR32_GPIO_IRQ_3                  67
#define AVR32_GPIO_IRQ_4                  68
#define AVR32_GPIO_IRQ_5                  69
#define AVR32_GPIO_IRQ_6                  70
#define AVR32_GPIO_IRQ_7                  71
#define AVR32_GPIO_IRQ_8                  72

Now I'm just wondering why only 9? As far as I understand there should be 14. Whatever... the main problem is that in A0/1 series of AVR32 micros, only PA00-13 can be used for GPIO interrupts. PX33 cannot be used. See the datasheet page 42. GPIO 0-13 are PA00-13 and PX33 would be GPIO 71.

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

I found those #defines as well ... and they apply to dedicated external interrupt pins only.

Regarding comment about PX33 can not be used ... for EIC yes (at least that was my understanding) ... but datasheet page 170 says ...

Quote:
Configurable pin-change, rising-edge or falling-edge interrupt on any I/O line.

I am now starting to suspect that this feature is not supported within ASF ? I have already given up on this and used a polling mechanism. Pity though .. would prefer the interrupt driven solution.

If I am wrong, I would love to hear of a solution for pins other than the dedicated external interrupts ... and I am sure, many other members as well.

Brian

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

Starting from datasheet page 41 there's an interrupt request signal map table. In group 1 you have 8 EIC signals and in group 2 you have 14 GPIO signal. INTC just does not support interrupts from every GPIO.

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

Quote:
INTC just does not support interrupts from every GPIO.

That table makes better sense to me now. But datasheet still says that any GPIO pin can have an interrupt. So if intc is not able, then maybe EIC as already noted in this thread. But no examples or docs exist to show how to access a vanilla flavor GPIO pin.

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

MrDIY wrote:
So if intc is not able, then maybe EIC as already noted in this thread. But no examples or docs exist to show how to access a vanilla flavor GPIO pin.
Refer to datasheet page 45 and check every EIM - EXTINT[...] function and a pin where this function can be assigned. PX33 cannot be assigned to EIC. In that table EIM is most likely a typo and should be EIC (controller vs. manager).

To access GPIO register...

volatile avr32_gpio_port_t *porta = &AVR32_GPIO.port[0];

porta->gpers = (1 << 2); // etc.
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

The table on page 45 was the first thing I checked.
If I understand you correctly, your confirming that PX33 can not be used as an interrupt. This was my understanding when posting first comment.

Not sure how your attached code helps me.

I guess if I really want to, I could wire up a mod wire from PX33 to a free ext interrupt pin. Its just that the datasheet states something that appears impossible to make happen at present.

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

MrDIY,
interrupt from any GPIO pin is possible. Interrupt section in GPIO chapter says, eight pins of each port are grouped together and is connected to INTC. So basically there are four interrupt lines on each port. and irq line for a gpio will be (gpio_irq0 + gpio pin number/ eight ) i.e. in your case
AVR32_GPIO_IRQ_0 + (71 / eight) = 8
So try this
// Register GPIO Pin Change Interrupt
INTC_register_interrupt(&DR_int_handler, AVR32_GPIO_IRQ_8 , AVR32_INTC_INT2);

:)