0
\$\begingroup\$

I'm using an ATUC128D3 microcontroller and have 5 switches connected to it. I have the GPIO interrupt configured to trigger on a falling edge and this works just fine.

It enters the interrupt and the LED turns on, but upon completing the ISR, gets stuck in an "unrecoverable exception handler" in "exception.S". Can someone shed some light on why this is happening?

My code:

#include <avr32/io.h>
#include <stdint.h>
#include "system.h"
#include "io.h"
#include "interrupts.h"
#include "lcd.h"
#include <intc.h>

void intHandlerPortA()
{
     ioPinHigh(&LED_PORT, LED2_PIN);                         //Turn on an LED.
     ioClearIntFlag(&SW_PORT, SW1_bm | SW2_bm | SW3_bm      
                    | SW4_bm | SW5_bm);                     //Don't care which switch triggered it clear them all.
}    

int main(void)
{
    /*Debug LEDs as IO and output.*/
    ioSetPinIO(&LED_PORT, LED1_PIN | LED2_PIN | LED3_PIN);      
    ioSetPinOutput(&LED_PORT, LED1_PIN | LED2_PIN | LED3_PIN);
    
    /*Enable OSC0 and select it as the main clock*/
    systemOSC0init();
    if (systemMainClockSelect() == true)
    {
        ioPinHigh(&LED_PORT, LED1_PIN); 
    }

    /*Switches as IO inputs, enable falling interrupt for all*/
    ioSetPinIO(&SW_PORT, SW1_bm | SW2_bm | SW3_bm | SW4_bm | SW5_bm);
    ioEnableInterrupt(&SW_PORT, SW1_bm | SW2_bm | SW3_bm | SW4_bm | SW5_bm);
    ioInterruptMode(&SW_PORT, GPIO_IMR_FALLING_bm, 
                    SW1_bm | SW2_bm | SW3_bm | SW4_bm | SW5_bm);
    
    /*intc.h built in functions.*/
    INTC_init_interrupts();
    INTC_register_interrupt(&intHandlerPortA, AVR32_GPIO_IRQ_2, 3);
    INTC_register_interrupt(&intHandlerPortA, AVR32_GPIO_IRQ_3, 3);
    Enable_global_interrupt();

    while(1)
    {

    }
}

From exception.S:

// Start of Exception Vector Table.

/*
 * EVBA must be aligned with a power of two strictly greater than the
 * EVBA-relative offset of the last vector.
 */
.balign 0x200

// Export symbol.
.global _evba
.type _evba, @function
_evba:

    .org  0x000
    // Unrecoverable Exception.
_handle_Unrecoverable_Exception:                          /* GETS STUCK ON THIS LINE*/
    rjmp $

    .org  0x004
    // TLB Multiple Hit.
_handle_TLB_Multiple_Hit:
    rjmp $

    .org  0x008
    // Bus Error Data Fetch.
_handle_Bus_Error_Data_Fetch:
    rjmp $

    .org  0x00C
    // Bus Error Instruction Fetch.
_handle_Bus_Error_Instruction_Fetch:
    rjmp $

    .org  0x010
    // NMI.
_handle_NMI:
    rjmp $

    .org  0x014
    // Instruction Address.
_handle_Instruction_Address:
    rjmp $

    .org  0x018
    // ITLB Protection.
_handle_ITLB_Protection:
    rjmp $

    .org  0x01C
    // Breakpoint.
_handle_Breakpoint:
    rjmp $

    .org  0x020
    // Illegal Opcode.
_handle_Illegal_Opcode:
    rjmp $

    .org  0x024
    // Unimplemented Instruction.
_handle_Unimplemented_Instruction:
    rjmp $

    .org  0x028
    // Privilege Violation.
_handle_Privilege_Violation:
    rjmp $

    .org  0x02C
    // Floating-Point: UNUSED IN AVR32UC and AVR32AP.
_handle_Floating_Point:
    rjmp $

    .org  0x030
    // Coprocessor Absent: UNUSED IN AVR32UC.
_handle_Coprocessor_Absent:
    rjmp $

    .org  0x034
    // Data Address (Read).
_handle_Data_Address_Read:
    rjmp $

    .org  0x038
    // Data Address (Write).
_handle_Data_Address_Write:
    rjmp $

    .org  0x03C
    // DTLB Protection (Read).
_handle_DTLB_Protection_Read:
    rjmp $

    .org  0x040
    // DTLB Protection (Write).
_handle_DTLB_Protection_Write:
    rjmp $

    .org  0x044
    // DTLB Modified: UNUSED IN AVR32UC.
_handle_DTLB_Modified:
    rjmp $

    .org  0x050
    // ITLB Miss.
_handle_ITLB_Miss:
    rjmp $

    .org  0x060
    // DTLB Miss (Read).
_handle_DTLB_Miss_Read:
    rjmp $

    .org  0x070
    // DTLB Miss (Write).
_handle_DTLB_Miss_Write:
    rjmp $

    .org  0x100
    // Supervisor Call.
_handle_Supervisor_Call:
    rjmp $
\$\endgroup\$
3
  • 1
    \$\begingroup\$ Probably you need some extra syntax to declare an interrupt handler. Something like "_attribute__((_interrupt)) static void intHandlerPortA()", the syntax is compiler dependent. \$\endgroup\$
    – Jens
    Commented Oct 19, 2022 at 2:08
  • \$\begingroup\$ As @Jens says, you do not mark your ISR as such. So it returns with a "normal" return-from-subroutine, but it needs a return-from-interrupt. -- Without knowing the compiler you use, we cannot make this a real answer. \$\endgroup\$ Commented Oct 19, 2022 at 6:05
  • \$\begingroup\$ Thank you guys, you were correct. It was right in front of me but I didn't know what I was looking at/for so I missed it. I will post an answer with details. \$\endgroup\$ Commented Oct 21, 2022 at 18:04

1 Answer 1

1
\$\begingroup\$

The function attribute __attribute__((interrupt)) should be used on the interrupt handler function with the GCC GNU for AVR32 compiler or __interrupt with IAR Embedded Workbench for Atmel AVR32 compiler.

From: https://asf.microchip.com/docs/latest/avr32.drivers.intc.example.evk1105/html/interrupt__usart__example_8c.html

\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.