Title: EECE 631 Microcomputer System Design Lecture 11
1EECE 631Microcomputer System DesignLecture 11
- Spring 2007
- Chris Lewis
- clewis_at_ksu.edu
2Interrupts
3Sources
- Peripherals
- Peripheral ID corresponds to source number/bit
number - External sources are termed peripherals too
- Names of Sources
- FIQ (fast source)
- SYS (source 1)
- PID2-PID31
4Mode set via AIC_SMR
- Level Sensitive
- High
- low
- Edge Triggered
- Positive
- Negative
5Operation
- Enable/Disable
- AIC_IECR
- AIC_IDCR
- Set/Clear
- AIC_ISCR
- AIC_ICCR
- Allow software interrupts
- Reading AIC_IVR automatically clears
- Not for Fast forcing interrupt
- Status
- AIC_IPR (pending)
- AIC_IMR(mask)
- AIC_ISR(status)
- AIC_CISR (current signal)
6Block Diagram
7Priority Controller
- Level 0-7 set in AIC_SMR (mode reg)
- As soon as detected nIRQ set
- If Another detected, nIRQ remains set, but read
of AIC_IVR changes to highest priority of those
pending - If Another detected of same priority, lowest
numbered source is in AIC_IVR - nIRQ remains clear until
- Higher priority interrupt occurs (ISR must
enable) - AIC_EOICR (End of Interrupt Cmd Reg) is written
8Nesting
- Low priority ISR re-enables interrupts
- Higher priority ISR reads AIC_IVR
- Hardware pushes Lower priority number and
priority level to hardware stack - Upon AIC_EOICR write, hardware stack restores
these values - Hardware has 8 levels of capability
9- Key points
- Processor jumps to 0x18
- AIC_IVR contains location of ISRn
- If 0x18 contains LDR PC,PC, -F20
- Jump to ISRn
- Sets current interrupt to be pending
- De-asserts nIRQ line
- Automatically clears edge triggered
- Pushes level and number on hw stack
10FIRQ vectoring
- Processor jumps to 0x1C
- AIC_FVR contains address of FIRQ ISR
- If 0x1C has LDR PC, PC, -F20
- Jump to FISR
- Sets current interrupt to be pending
- De-asserts nIRQ line
- Automatically clears edge triggered
- Pushes level and number on hw stack
11Hardware operations
- CPSR is stored in SPSR_irq
- PC is stored in R14_irq
- PC is loaded with
- 0x18 (nIRQ)
- 0x2C (FIRQ)
- Arm core enters interrupt mode
12FIRQ mode
- R8-R13 are banked, and dont have to be saved.
13CPU Registers
14CPU Registers
15AIC_SMRn
16AIC_SVRn
17AIC_IVR
18AIC_FVR
19AIC_EOICR
20- //-----------------------------------------------
----------------------------- - // \fn AT91F_AIC_ConfigureIt
- // \brief Interrupt Handler Initialization
- //-----------------------------------------------
----------------------------- - __inline unsigned int AT91F_AIC_ConfigureIt (
- AT91PS_AIC pAic, // \arg pointer to the AIC
registers - unsigned int irq_id, // \arg interrupt
number to initialize - unsigned int priority, // \arg priority to
give to the interrupt - unsigned int src_type, // \arg activation and
sense of activation - void (newHandler) () ) // \arg address of the
interrupt handler -
- unsigned int oldHandler
- unsigned int mask
- oldHandler pAic-gtAIC_SVRirq_id
- mask 0x1 ltlt irq_id
- // Disable the interrupt on the interrupt
controller - pAic-gtAIC_IDCR mask
21Latency
22- AIC_SRV loaded
- 0x18 Coded
- CPSR gt SPSR_irq
- PC gt R14_irq
- PC0x18
- R14_irq R14_irq-4
2. CPSR mode irq 3. 0x18 instruction loads PC
with AIC_IVR Reading AIC_IVR sets ISR
(source) Clears nIRQ Clears edge-trigger push
stack?
234. ISR needs to save R14_irq SPSR_IRQ If it
wants to enable Interrupts of higher priority 5.
ISR may enable interrupts of higher priority 6.
ISR must save and then restore any registers it
uses 7. ISR should again disable interrupts
before return 8. Return AIC_EOICR
248. Return AIC_EOICR level automatically popped
from stack, restores previous level
IF an interrupt is pending that is of higher
priority than this new level, nIRQ is
reasserted. etc.
25IARs Solution in C for ISRs
- __irq __arm void conversion()
- unsigned char data
- data AT91F_ADC_GetConvertedDataCH6(pADC)0xff
- AT91F_PWMC_UpdateChannel(AT91C_BASE_PWMC, 0,
data) - pAIC-gtAIC_EOICR 1
- return
26Installing an ISR
- //enable ADC interrupt
- AT91F_AIC_ConfigureIt(pAIC,
- AT91C_ID_ADC,
- 7,
AT91C_AIC_SRCTYPE_INT_POSITIVE_EDGE, - (void ()())conversion)
27Whats done
- define AT91C_AIC_BRANCH_OPCODE ((void () ())
0xE51FFF20) // ldr, pc, pc, -F20 - __inline unsigned int AT91F_AIC_ConfigureIt (
- AT91PS_AIC pAic, // \arg pointer to the AIC
registers - unsigned int irq_id, // \arg interrupt
number to initialize - unsigned int priority, // \arg priority to
give to the interrupt - unsigned int src_type, // \arg activation and
sense of activation - void (newHandler) () ) // \arg address of the
interrupt handler -
- unsigned int oldHandler
- unsigned int mask
- oldHandler pAic-gtAIC_SVRirq_id
- mask 0x1 ltlt irq_id
- pAic-gtAIC_IDCR mask // Disable the
interrupt on the interrupt controller - // Save the interrupt handler routine
pointer and the interrupt priority - pAic-gtAIC_SVRirq_id (unsigned int)
newHandler - pAic-gtAIC_SMRirq_id src_type priority
// Store the Source Mode Register - pAic-gtAIC_ICCR mask // Clear the
interrupt on the interrupt controller - return oldHandler
-
28Set Vector
- __inline unsigned int AT91F_AIC_SetExceptionVecto
r ( - unsigned int pVector, // \arg pointer to the
AIC registers - void (Handler) () ) // \arg Interrupt Handler
-
- unsigned int oldVector pVector
- if ((unsigned int) Handler (unsigned int)
AT91C_AIC_BRANCH_OPCODE) - pVector (unsigned int) AT91C_AIC_BRANCH_OPCOD
E - else
- pVector (((((unsigned int) Handler) -
((unsigned int) pVector) - 0x8) gtgt 2)
0x00FFFFFF) 0xEA000000 - return oldVector
-