Interrupt Handling Advanced Interrupt Controller (AIC) ARM Core Interrupt Sources The ARM processor has only 2 Interrupt lines IRQ (Normal Interrupt) - Standard interrupt request FIQ (Fast Interrupt) - Used for fast interrupt handling - Private registers - Initialization in C-startup - Last vector: directly accessible - Save the jump to the handler ARM-Based Products Group IRQ FIQ ARM Core ARM Interrupt Vectors The interrupt vector is the first instruction executed by the ARM core when getting the interrupt Stored at location 0x18 (IRQ) or 0x1C (FIQ) Normally, jump is performed, either with instruction B Interrupt_Service_Routine - Up to 32Mbytes accessible, much more than expected on SAM7 products LDR pc, [pc, #Interrupt_Service_Routine] - PC relative, requires an additional 32-bit word - Full 4GBytes address space accessible Interrupt_Service_Routine The FIQ handler can be directly written ARM-Based Products Group Advanced Interrupt Controller (AIC) The AIC is an ATMEL additional layer allowing the handling of up to 32 interrupt sources, coming either from the internal peripherals or from the interrupt input pins ARM-Based Products Group AIC Interrupt Sources External Interrupts Two kinds of interrupt sources: External (IRQx and FIQ pins): FIQ System Interrupt - High or Low Level Sensitive - Rising or Falling Edge Triggered Internal (internal peripherals): - High Level Sensitive (recommended) - Rising Edge Triggered AT91SAM7S Example: 16 sources - 1 System interrupt - 12 internal peripherals - 3 external sources: FIQ, IRQ0, IRQ1 IRQ0 IRQ1 ARM-Based Products Group What’s the System Interrupt ? The wired-OR of all the sources coming from the System Controller’s peripherals, including: Memory Controller PIT RTT WDT DBGU PMC RSTC … ARM-Based Products Group How to manage the System Interrupt ? By reading the Status Registers of all the system peripherals and check which interrupt(s) is/are pending: Void ISR_SystemInterrupt (void){ // PIT Timer Interrupt Processing status = PIT_SR & PIT_IMR; if (status != 0x0){ … } // DBGU Interrupt Processing status = DBGU_SR & DBGU_IMR; if (status != 0x0){ if ((status & TXRDY) != 0) {…} if ((status & RXRDY) != 0) {…} } } ARM-Based Products Group Non-Vectored Interrupts Interrupt Source 5 Common IRQ Handler LUT @ Fixed Address AIC_IVR Vector Address ARM Exception Vector Table Load PC with Fixed Address Common IRQ Handler ISR Source 1 0x18 Look-Up Table ISR Source 5 ISR Source 32 ARM-Based Products Group Vectored Interrupts Benefit Interrupt Source 5 Vector 1 Address AIC_SVR1 Vector 5 Address AIC_SVR5 Vector 32 Address AIC_SVR32 AIC_IVR Vector Address ARM Exception Vector Table Load PC with Vector Address 0x18 ARM-Based Products Group ISR Source 5 AIC Automatic Vectoring Benefit All sources are individually and dynamically vectored Management for FIQ and IRQ are independent: AIC_IVR returns the handler address of the current IRQ AIC_FVR returns the handler address of the current FIQ Handler addresses are saved in their corresponding Source Vector Register (AIC_SVRx) ARM Exception vectors AIC Interrupt vectors AIC Source vectors AIC_ISR AIC_SVR31 0xFFFFF0FC AIC_SVR30 0x0000001C 0x00000018 FIQ IRQ ABORT (Data) ABORT (Fetch) SWI UNDEF RESET 0xFFFFF104 0xFFFFF100 AIC_FVR AIC_IVR Index = Interrupt Id. AIC_SVR1 AIC_SVR0 ARM-Based Products Group 0xFFFFF080 AIC IRQ Priority Management The ARM Core IRQ line is controlled by an 8-level priority encoder Each source has a programmable priority level of 7 to 0 (AIC_SMR). Level 7 is the highest priority. The AIC manages the IRQ prioritization by using an hardware internal stack on which the current interrupt level is: Automatically pushed when AIC_IVR is read Automatically popped when AIC_EOICR is written No internal stack needed for FIQ (no prioritization) ARM-Based Products Group AIC Interrupt Handling When an interrupt source is detected, the AIC asserts the ARM Core IRQ line: The ARM Core is interrupted (automatic branch on ARM Vector 0x18) The ARM Core enters its IRQ mode (IRQ are automatically disabled at core level) The application must read the Interrupt Vector register (AIC_IVR) By reading the AIC_IVR register, the AIC: De-asserts the ARM Core IRQ line Determines the highest level pending and enabled interrupt source Pushes the level of the current interrupt in the AIC hardware stack Clears the interrupt if it’s configured as edge triggered Returns the vector corresponding to the current interrupt The ISR can re-enable as soon as possible the interrupt at core level (nested interrupts) A higher level interrupt can occur and restarts this sequence The ISR Exit code must disable the interrupt at core level Finally, the application must write the End Of Interrupt Command Register (EOICR) in the ISR Exit code AIC pops from its hardware stack the current level ARM-Based Products Group AIC Interrupt Handling Example IRQ P is interrupted by IRQ P+ which is interrupted by FIQ (nested interrupts) ARM-Based Products Group AIC Fast Forcing Any interrupt sources can generate a Fast Interrupt Keep in mind there is no priority management for FIQ If several interrupts are forced Fast, each pending interrupt bit in AIC_IPR must be tested => less interesting than 1 single FIQ!!! ARM-Based Products Group The True Interrupt latency Interrupt latency in a system might be affected by: AIC External/Internal Interrupt latency (less than 5 cycles) Return from Core Idle mode (max. 2 cycles) PDC using the bus (<10 cycles in worst cases) Interrupt Disabling - several hundreds/thousands of cycles depending on the tasks required for the interrupt to be masked That’s why it is so important to get Atomic Interrupt Other interrupts handling - might be up to 100 cycles depending on the interrupt management policy Priority and Interrupt Nesting can improve a lot ARM-Based Products Group AT91 Single-cycle Bit Manipulation ARM7TDMI processors do not provide any bit manipulation Requires read-modify-write sequence of operations AT91SAM series feature atomic bit set/reset facility for all peripheral control registers Enabling or Disabling an interrupt is performed with only one instruction (store STR), thus is un-interruptible. Interrupt Enable Register (IER) 0 1 Set Q Reset 1 Interrupt Mask Register (IMR) Set 0 Q 0 Reset 1 Interrupt Disable Register (IDR) ARM-Based Products Group AIC Debug Features Spurious Interrupt Handling: a Spurious Interrupt occurs when the ARM Core is interrupted and the source of interrupt has disappeared when IVR is read This may occur: - By applying a pulse on an external interrupt signal programmed as level sensitive - By disabling an interrupt just at the time it happens - By double management (PDC and IRQ) AIC_SPU register: returned when AIC detects a spurious interrupt ( when AIC_IVR is read) ARM-Based Products Group AIC Debug Features (cont.) Protect Mode Why? - If the AIC_IVR register is read by the debugger on a memory display window, it will corrupt interrupts handling processes. - As the debugger never writes AIC_EOICR, AIC may stay in an undefined state. Activated by setting the PROT bit in the AIC Debug Control Register The automatic operations performed by the AIC are now executed only when IVR is written: - AIC de-asserts the nIRQ line - AIC clears the interrupt if it’s edge triggered ARM-Based Products Group