Interrupt-Driven IO

Interrupt Service Routine (ISR)

Info

An interrupt service routine (ISR) (handler) performs I/O instead of the main program doing polling

Steps

  1. Write ISR (keep as short as possible)
  2. Store IRS address in the vector table (since we made a custom handler)
  3. Enable IRQss at the device
  4. Run the main program
  5. Whenever an IRQ is received, the ISR is run by the IC to do the IO

Example - ADC Interrupts

See ARM V7 Assembly

Note that ADC generates IRQ22

ADINTEN EQU   0x4003400C ; ADC Interrupt Enable
ADDR    EQU   0x40034010
SAMPLES SPACE 100        ; Each integer is 4 bytes, we can fit 25 integers here
POINTER DCD   SAMPLES    ; Creates 1-word variable in memory,
                         ; initialized with the address of the first slot in SAMPLES

(See Directives#Data Reservation Directives)

  1. Write ISR
ISR
    MOV32 R0, #ADDR
    MOV32 R1, #POINTER   ; R1 <- pointer to current sample array address
    LDR   R2, [R1]       ; Loaded samples pointer
    LDR   R3, [R0]       ; Reads sample (also clears IRQ)
    AND   R3, #0x000FFFD ; Grab bits 4-15
    LSR   R3, #4
    STR   R3, [R2], #4 ; Store to array
    STR   R2, [R1]     ; Update pointer (registers don't persist)
    BX    LR           ; Return from exception
  1. Store the ISR address in the vector table
    • (since we are using IRQ22 and vector 16 is IRQ0)
MOV32 R0, #ISR    ; or LDR R0, =ISR or ADR
MOV   R1, #38 * 4 ; or ADR R0, ISR
                  ; Vector table entries are 4 bytes
STR   R0, [R1]
  1. Enable the IRQ on the device (device specific)
MOV32 R0, #ADINTEN
MOV   R1, #1
STR   R1, [R0] ; Sets bit 0 to 1 which enables the IRQ