User guide

IOPort1,IOPort2
Are offsets to the two data registers to be read. Reading a data register clears the
interrupt for the corresponding port.
r9
Points to the memory location to which data from the first port is being transferred.
r10
Points to the memory location to which data from the second port is being transferred.
r11,r12
Point to the last address to transfer to (r11 for the first port, r12 for the second).
The entire sequence to handle a normal transfer takes nine instructions. Code situated after the conditional return is
used to signal that the transfer is complete.
Example 5-16
LDR r13, [r8, #IOStat] ; Load status register to find which port
; caused the interrupt.
TST r13, #IOPort1Active
LDREQ r13, [r8, #IOPort1] ; Load port 1 data.
LDRNE r13, [r8, #IOPort2] ; Load port 2 data.
STREQ r13, [r9], #4 ; Store to buffer 1.
STRNE r13, [r10], #4 ; Store to buffer 2.
CMP r9, r11 ; Reached the end?
CMPLE r10, r12 ; On either channel?
SUBNES pc, lr, #4 ; Return
; Insert transfer complete code here.
Byte transfers can be made by replacing the load instructions with load byte instructions. Transfers from memory to
an I/O device are made by swapping the addressing modes between the conditional load instructions and the
conditional store instructions.
Interrupt prioritization
Example 5-17 dispatches up to 32 interrupt sources to their appropriate handler routines. Because it is designed for
use with the normal interrupt vector (IRQ), it should be branched to from location 0x18.
External hardware is used to prioritize the interrupt and present the high-priority active interrupt in an I/O register.
In the example code:
IntBase
Holds the base address of the interrupt controller.
IntLevel
Holds the offset of the register containing the highest-priority active interrupt.
r13
Is assumed to point to a small full descending stack.
Interrupts are enabled after ten instructions, including the branch to this code.
The specific handler for each interrupt is entered after a further two instructions (with all registers preserved on the
stack).
In addition, the last three instructions of each handler are executed with interrupts turned off again, so that the SPSR
can be safely recovered from the stack.
Note
Application Note 30: Software Prioritization of Interrupts describes multiple-source prioritization of interrupts using
software, as opposed to using hardware as described here.
Example 5-17
; first save the critical state
SUB lr, lr, #4 ; Adjust the return address
; before we save it.
STMFD sp!, {lr} ; Stack return address
MRS r14, SPSR ; get the SPSR ...
STMFD sp!, {r12, r14} ; ... and stack that plus a
; working register too.
; Now get the priority level of the
; highest priority active interrupt.
MOV r12, #IntBase ; Get the interrupt controller's
; base address.
LDR r12, [r12, #IntLevel] ; Get the interrupt level (0 to 31).
; Now read-modify-write the CPSR to enable interrupts.
MRS r14, CPSR ; Read the status register.
BIC r14, r14, #0x80 ; Clear the I bit
; (use 0x40 for the F bit).
MSR CPSR_c, r14 ; Write it back to re-enable
; interrupts and
LDR PC, [PC, r12, LSL #2] ; jump to the correct handler.
Handling Processor Exceptions
Copyright ?1999 2001 ARM Limited 5-17