Datasheet

2017 Microchip Technology Inc. DS60001516A-page 301
SAM9G20
This feature is often not used when the application is based on an operating system (either real time or not). Operating systems often have
a single entry point for all the interrupts and the first task performed is to discern the source of the interrupt.
However, it is strongly recommended to port the operating system on AT91 products by supporting the interrupt vectoring. This can be
performed by defining all the AIC_SVR of the interrupt source to be handled by the operating system at the address of its interrupt handler.
When doing so, the interrupt vectoring permits a critical interrupt to transfer the execution on a specific very fast handler and not onto the
operating system’s general interrupt handler. This facilitates the support of hard real-time tasks (input/outputs of voice/audio buffers and
software peripheral handling) to be handled efficiently and independently of the application running under an operating system.
26.7.3.4 Interrupt Handlers
This section gives an overview of the fast interrupt handling sequence when using the AIC. It is assumed that the programmer understands
the architecture of the Arm processor, and especially the processor interrupt modes and the associated status bits.
It is assumed that:
1. The Advanced Interrupt Controller has been programmed, AIC_SVR registers are loaded with corresponding interrupt service rou-
tine addresses and interrupts are enabled.
2. The instruction at the Arm interrupt exception vector address is required to work with the vectoring
LDR PC, [PC, # -&F20]
When nIRQ is asserted, if the bit “I” of CPSR is 0, the sequence is as follows:
1. The CPSR is stored in SPSR_irq, the current value of the Program Counter is loaded in the Interrupt link register (R14_irq) and the
Program Counter (R15) is loaded with 0x18. In the following cycle during fetch at address 0x1C, the Arm core adjusts R14_irq,
decrementing it by four.
2. The Arm core enters Interrupt mode, if it has not already done so.
3. When the instruction loaded at address 0x18 is executed, the program counter is loaded with the value read in AIC_IVR. Reading
the AIC_IVR has the following effects:
- Sets the current interrupt to be the pending and enabled interrupt with the highest priority. The current level is the priority level of
the current interrupt.
- De-asserts the nIRQ line on the processor. Even if vectoring is not used, AIC_IVR must be read in order to de-assert nIRQ.
- Automatically clears the interrupt, if it has been programmed to be edge-triggered.
- Pushes the current level and the current interrupt number on to the stack.
- Returns the value written in the AIC_SVR corresponding to the current interrupt.
4. The previous step has the effect of branching to the corresponding interrupt service routine. This should start by saving the link
register (R14_irq) and SPSR_IRQ. The link register must be decremented by four when it is saved if it is to be restored directly into
the program counter at the end of the interrupt. For example, the instruction SUB PC, LR, #4 may be used.
5. Further interrupts can then be unmasked by clearing the “I” bit in CPSR, allowing re-assertion of the nIRQ to be taken into account
by the core. This can happen if an interrupt with a higher priority than the current interrupt occurs.
6. The interrupt handler can then proceed as required, saving the registers that will be used and restoring them at the end. During this
phase, an interrupt of higher priority than the current level will restart the sequence from step 1.
Note: If the interrupt is programmed to be level sensitive, the source of the interrupt must be cleared during this phase.
7. The “I” bit in CPSR must be set in order to mask interrupts before exiting to ensure that the interrupt is completed in an orderly
manner.
8. The End of Interrupt Command Register (AIC_EOICR) must be written in order to indicate to the AIC that the current interrupt is
finished. This causes the current level to be popped from the stack, restoring the previous current level if one exists on the stack.
If another interrupt is pending, with lower or equal priority than the old current level but with higher priority than the new current
level, the nIRQ line is re-asserted, but the interrupt sequence does not immediately start because the “I” bit is set in the core.
SPSR_irq is restored. Finally, the saved value of the link register is restored directly into the PC. This has the effect of returning
from the interrupt to whatever was being executed before, and of loading the CPSR with the stored SPSR, masking or unmasking
the interrupts depending on the state saved in SPSR_irq.
Note: The “I” bit in SPSR is significant. If it is set, it indicates that the Arm core was on the verge of masking an interrupt when the
mask instruction was interrupted. Hence, when SPSR is restored, the mask instruction is completed (interrupt is masked).