Name

SAM9 interrupt controller — Advanced Interrupt Controller definitions and usage

Interrupt controller definitions

The file <cyg/hal/var_ints.h> (located at hal/arm/arm9/sam9/VERSION/include/var_ints.h in the eCos source repository) contains interrupt vector number definitions for use with the eCos kernel and driver interrupt APIs:

// The following are common to all SAM9 devices. Per-variant
// variations are supplied later.

#define CYGNUM_HAL_INTERRUPT_FIQ     0 // Advanced Interrupt Controller (FIQ)
#define CYGNUM_HAL_INTERRUPT_SYSTEM  1 // System Peripheral (debug unit, system timer)
#define CYGNUM_HAL_INTERRUPT_PIOA    2 // Parallel IO Controller A
#define CYGNUM_HAL_INTERRUPT_PIOB    3 // Parallel IO Controller B
#define CYGNUM_HAL_INTERRUPT_PIOC    4 // Parallel IO Controller C
                                       // Vector 5 variant specific
#define CYGNUM_HAL_INTERRUPT_US0     6 // USART 0
#define CYGNUM_HAL_INTERRUPT_US1     7 // USART 1
#define CYGNUM_HAL_INTERRUPT_US2     8 // USART 2
#define CYGNUM_HAL_INTERRUPT_MCI     9 // Multimedia Card Interface
#define CYGNUM_HAL_INTERRUPT_UDP    10 // USB Device Port
#define CYGNUM_HAL_INTERRUPT_TWI    11 // Two-Wire Interface
#define CYGNUM_HAL_INTERRUPT_SPI    12 // Serial Peripheral Interface 0
#define CYGNUM_HAL_INTERRUPT_SPI1   13 // Serial Peripheral Interface 1
#define CYGNUM_HAL_INTERRUPT_SSC0   14 // Serial Synchronous Controller 0
                                       // Vector 15 variant specific
                                       // Vector 16 variant specific
#define CYGNUM_HAL_INTERRUPT_TC0    17 // Timer Counter 0
#define CYGNUM_HAL_INTERRUPT_TC1    18 // Timer Counter 1
#define CYGNUM_HAL_INTERRUPT_TC2    19 // Timer Counter 2
#define CYGNUM_HAL_INTERRUPT_UHP    20 // USB Host port
                                       // Vectors 21..28 variant specific
#define CYGNUM_HAL_INTERRUPT_IRQ0   29 // Advanced Interrupt Controller (IRQ0)
#define CYGNUM_HAL_INTERRUPT_IRQ1   30 // Advanced Interrupt Controller (IRQ1)
#define CYGNUM_HAL_INTERRUPT_IRQ2   31 // Advanced Interrupt Controller (IRQ2)

// Variant specific vectors

#if defined(CYGHWR_HAL_ARM_ARM9_SAM9_SAM9260)

#define CYGNUM_HAL_INTERRUPT_ADC     5 // Analog to Digital Converter
                                       // Vector 15 unused
                                       // Vector 16 unused
#define CYGNUM_HAL_INTERRUPT_EMAC   21 // Ethernet MAC
#define CYGNUM_HAL_INTERRUPT_ISI    22 // Image Sensor Interface
#define CYGNUM_HAL_INTERRUPT_US3    23 // USART 3
#define CYGNUM_HAL_INTERRUPT_US4    24 // USART 4
#define CYGNUM_HAL_INTERRUPT_US5    25 // USART 5
#define CYGNUM_HAL_INTERRUPT_TC3    26 // Timer Counter 3
#define CYGNUM_HAL_INTERRUPT_TC4    27 // Timer Counter 4
#define CYGNUM_HAL_INTERRUPT_TC5    28 // Timer Counter 5

#elif defined(CYGHWR_HAL_ARM_ARM9_SAM9_SAM9261)

                                       // Vector 5 unused
#define CYGNUM_HAL_INTERRUPT_SSC1   15 // Serial Synchronous Controller 1
#define CYGNUM_HAL_INTERRUPT_SSC2   16 // Serial Synchronous Controller 2
#define CYGNUM_HAL_INTERRUPT_LCD    21 // LCD controller
                                       // Vectors 22..28 unused

#else
#error Unknown SAM9 variant
#endif

// The following interrupts are derived from the SYSTEM interrupt
#define CYGNUM_HAL_INTERRUPT_PITC   32 // System Timer Period Interval Timer
#define CYGNUM_HAL_INTERRUPT_DEBUG  33 // Debug unit
#define CYGNUM_HAL_INTERRUPT_WDTC   34 // Watchdog
#define CYGNUM_HAL_INTERRUPT_RTTC   35 // Real Time Clock
#define CYGNUM_HAL_INTERRUPT_PMC    36 // Power Management Controller
#define CYGNUM_HAL_INTERRUPT_RSTC   37 // Reset Controller

As indicated above, further decoding is performed on the SYSTEM interrupt to identify the cause more specifically. Note that as a result, placing an interrupt handler on the SYSTEM interrupt will not work as expected. Conversely, masking a decoded derivative of the SYSTEM interrupt will not work as this would mask other SYSTEM interrupts, but masking the SYSTEM interrupt itself will work. On the other hand, unmasking a decoded SYSTEM interrupt will unmask the SYSTEM interrupt as a whole, thus unmasking interrupts for the other units on this shared interrupt.

The list of interrupt vectors may be augmented on a per-platform basis. Consult the platform HAL documentation for your platform for whether this is the case.

Interrupt controller functions

The source file src/sam9_misc.c within this package provides most of the support functions to manipulate the interrupt controller. The hal_IRQ_handler queries the IRQ status register to determine the interrupt cause. Functions hal_interrupt_mask and hal_interrupt_unmask enable or disable interrupts within the interrupt controller.

Interrupts are configured in the hal_interrupt_configure function, where the level and up arguments are interpreted as follows:

levelupinterrupt on
00Falling Edge
01Rising Edge
10Low Level
11High Level

To fit into the eCos interrupt model, interrupts essentially must be acknowledged immediately once decoded, and as a result, the hal_interrupt_acknowledge function is empty.

The hal_interrupt_set_level is used to set the priority level of the supplied interrupt within the Advanced Interrupt Controller.

Note that in all the above, it is not recommended to call the described functions directly. Instead either the HAL macros (HAL_INTERRUPT_MASK et al) or preferably the kernel or driver APIs should be used to control interrupts.

Using the Advanced Interrupt Controller for VSRs

The SAM9 HAL has been designed to exploit benefits of the on-chip Advanced Interrupt Controller (AIC) on the SAM9. Support has been included for exploiting its ability to provide hardware vectoring for VSR interrupt handlers.

This support is dependent on definitions that may only be provided by the platform HAL and therefore is only enabled if the platform HAL package implements the CYGINT_HAL_SAM9_AIC_VSR CDL interface. The necessary definitions are available to all platform HALs which use the facilities of the sam9_init.inc header file.

The interrupt decoding path has been optimised by allowing the AIC to be interrogated for the interrupt handler VSR to use. These vectored interrupts are by default still configured to point to the default ARM architecture HAL IRQ and FIQ VSRs. However applications may set their own VSRs to override this default behaviour to allow optimised interrupt handling.

The VSR vector numbers to use when overriding are defined as follows:

// FIQ is already defined as vector 7 in the architecture hal_intr.h
#define CYGNUM_HAL_VECTOR_SYSTEM  8 // System Peripheral (debug unit, system timer)
#define CYGNUM_HAL_VECTOR_PIOA    9 // Parallel IO Controller A
#define CYGNUM_HAL_VECTOR_PIOB   10 // Parallel IO Controller B
#define CYGNUM_HAL_VECTOR_PIOC   11 // Parallel IO Controller C
                                    // VSR 12 variant specific
#define CYGNUM_HAL_VECTOR_US0    13 // USART 0
#define CYGNUM_HAL_VECTOR_US1    14 // USART 1
#define CYGNUM_HAL_VECTOR_US2    15 // USART 2
#define CYGNUM_HAL_VECTOR_MCI    16 // Multimedia Card Interface
#define CYGNUM_HAL_VECTOR_UDP    17 // USB Device Port
#define CYGNUM_HAL_VECTOR_TWI    18 // Two-Wire Interface
#define CYGNUM_HAL_VECTOR_SPI    19 // Serial Peripheral Interface
#define CYGNUM_HAL_VECTOR_SPI1   20 // Serial Peripheral Interface
#define CYGNUM_HAL_VECTOR_SSC0   21 // Serial Synchronous Controller 0
                                    // VSR 22 variant specific
                                    // VSR 23 variant specific
#define CYGNUM_HAL_VECTOR_TC0    24 // Timer Counter 0
#define CYGNUM_HAL_VECTOR_TC1    25 // Timer Counter 1
#define CYGNUM_HAL_VECTOR_TC2    26 // Timer Counter 2
#define CYGNUM_HAL_VECTOR_UHP    27 // USB Host port
                                    // VSRs 28..35 variant specific
#define CYGNUM_HAL_VECTOR_IRQ0   36 // Advanced Interrupt Controller (IRQ0)
#define CYGNUM_HAL_VECTOR_IRQ1   37 // Advanced Interrupt Controller (IRQ1)
#define CYGNUM_HAL_VECTOR_IRQ2   38 // Advanced Interrupt Controller (IRQ2)

// Variant specific vectors

#if defined(CYGHWR_HAL_ARM_ARM9_SAM9_SAM9260)

#define CYGNUM_HAL_VECTOR_ADC    12 // Analog to Digital Converter
                                    // Vector 22 unused
                                    // Vector 23 unused
#define CYGNUM_HAL_VECTOR_EMAC   28 // Ethernet MAC
#define CYGNUM_HAL_VECTOR_ISI    29 // Image Sensor Interface
#define CYGNUM_HAL_VECTOR_US3    30 // USART 3
#define CYGNUM_HAL_VECTOR_US4    31 // USART 4
#define CYGNUM_HAL_VECTOR_US5    32 // USART 5
#define CYGNUM_HAL_VECTOR_TC3    33 // Timer Counter 3
#define CYGNUM_HAL_VECTOR_TC4    34 // Timer Counter 4
#define CYGNUM_HAL_VECTOR_TC5    35 // Timer Counter 5


#elif defined(CYGHWR_HAL_ARM_ARM9_SAM9_SAM9261)

                                    // Vector 12 unused
#define CYGNUM_HAL_VECTOR_SSC1   22 // Serial Synchronous Controller 1
#define CYGNUM_HAL_VECTOR_SSC2   23 // Serial Synchronous Controller 2
#define CYGNUM_HAL_VECTOR_LCD    28 // LCD controller
                                    // Vectors 29..35 unused

#else

#error Unknown SAM9 variant

#endif

Consult the kernel and generic HAL documentation for more information on VSRs and how to set them.

Interrupt handling withing standalone applications

For non-eCos standalone applications running under RedBoot, it is possible to install an interrupt handler into the interrupt vector table manually. Memory mappings are platform-dependent and so the platform documentation should be consulted, but in general the address of the interrupt table can be determined by analyzing RedBoot's symbol table, and searching for the address of the symbol name hal_interrupt_handlers. Table slots correspond to the interrupt numbers above. Pointers inserted in this table should be pointers to a C/C++ function with the following prototype:

extern unsigned int isr( unsigned int vector, unsigned int data );

For non-eCos applications run from RedBoot, the return value can be ignored. The vector argument will also be the interrupt vector number. The data argument is extracted from a corresponding table named hal_interrupt_data which immediately follows the interrupt vector table. It is still the responsibility of the application to enable and configure the interrupt source appropriately if needed.