www.pudn.com > ucos_lwip_at91rm9200.rar > ASM_ISR.S


;------------------------------------------------------------------------------ 
;-         ATMEL Microcontroller Software Support  -  ROUSSET  - 
;------------------------------------------------------------------------------ 
; The software is delivered "AS IS" without warranty or condition of any 
; kind, either express, implied or statutory. This includes without 
; limitation any warranty or condition with respect to merchantability or 
; fitness for any particular purpose, or against the infringements of 
; intellectual property rights of others. 
;----------------------------------------------------------------------------- 
;- File source          : it_handler.s 
;- Object               : Example of IT handler calling a C function 
;- Compilation flag     : None 
;- 
;- 1.0 16/03/01 	ODi, : Creation ARM ADS 
;------------------------------------------------------------------------------ 
	AREA        itHandler, CODE, READONLY 
;------------------------------------------------------------------------------ 
;- LISR vector handler for system peripherals 
;-------------------------------- 
;- ARM Core Mode and Status Bits 
;-------------------------------- 
I_BIT      EQU             0x80 
 
AT91C_BASE_AIC	EQU	0xFFFFF000 
AIC_EOICR		EQU 0x130 
 
 
;------------------------------------------------------------------------------ 
;- IRQ Entry 
;----------- 
;------------------------------------------------------------------------------ 
	MACRO 
	IRQ_ENTRY     $reg 
 
; We will use R0-R3 as temporary registers     
    STMFD   SP!,{R0-R3}                     
    MOV     R1,SP 
    ADD     SP,SP,#16 
    SUB     R2,LR,#4 
 
; Disable interrupts for when we go back to SVC mode 
    MRS     R3,SPSR                          
    ORR     R0,R3,#I_BIT 
    MSR     SPSR_c,R0 
 
; Switch back to SVC mode (Code below, current location + 2 instructions)             
    LDR     R0,=.+8                          
    MOVS    PC,R0                            
             
    STMFD   SP!,{R2}                         
    STMFD   SP!,{R4-R12,LR}                 
    MOV     R4,R1                           
    MOV     R5,R3 
    LDMFD   R4!,{R0-R3}                     
    STMFD   SP!,{R0-R3}                     
    STMFD   SP!,{R5}                        
    MRS     R4,SPSR 
    STMFD   SP!,{R4}                        
                 
	MEND 
 
;------------------------------------------------------------------------------ 
;- IRQ Exit 
; --------- 
;------------------------------------------------------------------------------ 
 	MACRO 
	IRQ_EXIT      $reg 
    
; - Mark the End of Interrupt on the AIC 
    ldr     r0, =AT91C_BASE_AIC 
    str     r0, [r0, #AIC_EOICR] 
 
    LDMFD   SP!,{R4}                         
    MSR     SPSR_cxsf,R4 
    LDMFD   SP!,{R4}                         
    MSR     CPSR_cxsf,R4 
 
    LDMFD   SP!,{R0-R12,LR,PC}               
 
 
	MEND 
 
;------------------------------------------------------------------------------ 
; OSTickISR 
; --------------------- 
;       Handler called by the AIC 
;        
;	Save context 
;       Call C handler 
; 	Restore context 
;------------------------------------------------------------------------------ 
	EXPORT OSTickISR 
	IMPORT OSIntEnter 
    IMPORT timer1_c_irq_handler 
    IMPORT OSIntExit 
    IMPORT OSTCBCur 
    IMPORT OSIntNesting 
    IMPORT OSIntCtxSwFlag  
 
OSTickISR 
	 
	 
	IRQ_ENTRY 
	 
    BL      OSIntEnter  
    LDR     R0,=OSIntNesting                ; See if we need to do a context switch 
    LDR     R1,[R0] 
    CMP     R1,#1 
    BNE     NoSave1 
    LDR     R4,=OSTCBCur                    ; Get current task's OS_TCB address 
    LDR     R5,[R4] 
    STR     SP,[R5]                         ; store sp in preempted tasks's TCB                   
 
NoSave1     
     
    BL      timer1_c_irq_handler             
    BL      OSIntExit                        
 
;- Disable Interrupt and switch back in IRQ mode    
     
    MRS     R3,CPSR 
    ORR     R3,R3,#I_BIT 
    MSR     CPSR_c,R3 
     
    LDR     R0,=OSIntCtxSwFlag              
    LDR     R1,[R0] 
    CMP     R1,#1 
    BEQ     OS_IntCtxSw 
     
    IRQ_EXIT 
   
;------------------------------------------------------------------------------     
    EXPORT irqEMACISR 
    IMPORT EMACISR 
 
irqEMACISR 
 
	 IRQ_ENTRY 
	  
    BL      OSIntEnter    
    LDR     R0,=OSIntNesting                ; See if we need to do a context switch 
    LDR     R1,[R0] 
    CMP     R1,#1 
    BNE     NoSave2 
    LDR     R4,=OSTCBCur                    ; Get current task's OS_TCB address 
    LDR     R5,[R4] 
    STR     SP,[R5]                         ; store sp in preempted tasks's TCB                   
NoSave2 
    BL      EMACISR             
    BL      OSIntExit  
                    
;- Disable Interrupt and switch back in IRQ mode    
     
    MRS     R3,CPSR 
    ORR     R3,R3,#I_BIT 
    MSR     CPSR_c,R3 
     
    LDR     R0,=OSIntCtxSwFlag              
    LDR     R1,[R0] 
    CMP     R1,#1 
    BEQ     OS_IntCtxSw                    
 
    IRQ_EXIT 
;  
;------------------------------------------------------------------------------ 
 
    EXPORT irqUHPISR 
    IMPORT UHPISR 
 
irqUHPISR 
 
	 IRQ_ENTRY 
	  
    BL      OSIntEnter    
    LDR     R0,=OSIntNesting                ; See if we need to do a context switch 
    LDR     R1,[R0] 
    CMP     R1,#1 
    BNE     NoSave3 
    LDR     R4,=OSTCBCur                    ; Get current task's OS_TCB address 
    LDR     R5,[R4] 
    STR     SP,[R5]                         ; store sp in preempted tasks's TCB                   
NoSave3 
    BL      UHPISR             
    BL      OSIntExit  
                    
;- Disable Interrupt and switch back in IRQ mode    
     
    MRS     R3,CPSR 
    ORR     R3,R3,#I_BIT 
    MSR     CPSR_c,R3 
     
    LDR     R0,=OSIntCtxSwFlag              
    LDR     R1,[R0] 
    CMP     R1,#1 
    BEQ     OS_IntCtxSw                    
 
    IRQ_EXIT 
;  
;------------------------------------------------------------------------------ 
 
    EXPORT  OS_IntCtxSw 
    IMPORT  OS_CtxSW 
 
OS_IntCtxSw 
     
;- set OSIntCtxSwflag=0 
     
    LDR     R0,=OSIntCtxSwFlag              
    MOV     R1,#0 
    STR     R1,[R0] 
         
;- Mark the End of Interrupt on the AIC 
	ldr     r6, =AT91C_BASE_AIC 
	str     r6, [r6, #AIC_EOICR] 
     
    B   OS_CtxSW 
     
    END