This discussion has been locked.
You can no longer post new replies to this discussion. If you have a question you can start a new discussion

LPC2000 nested Interrupts /Realview

Dear People,

I am interested to use the Nested Interrupt in Software in a simple way shown in Examples, but in current RealView Tools it is not possible to access the Registers SP, LR, PSR via Inline Assembly with Assembler Macros.
Macros for GCC and legacy Keil Tools:

// Macros for Interrupt Nesting
#define IENABLE
__asm { MRS LR, SPSR }
__asm { STMFD SP!, {LR} }
__asm { MSR CPSR_c, #0x1F }
__asm { STMFD SP!, {LR} }

#define IDISABLE
__asm { LDMFD SP!, {LR} }
__asm { MSR CPSR_c, #0x92 }
__asm { LDMFD SP!, {LR} }
__asm { MSR SPSR_cxsf, LR }

Instead of the Macros, Mr. Dietmar Wengler developed the following Assembler Functions for Embedded Assembler:

nested_irq_enable:
STMFD SP!, {R0}
MOV R0, LR
MRS LR, SPSR
STMFD SP!, {LR}
MSR CPSR_c, #0x1F
STMFD SP!, {LR}
BX R0

nested_irq_disable:
MOV R0, LR
LDMFD SP!, {LR}
MSR CPSR_c, #0x92
LDMFD SP!, {LR}
MSR SPSR_cxsf, LR
MOV LR, R0
LDMFD SP!, {R0}
BX LR

could you tell me how can i the call the nested_irq_enable and the nested_irq_disable in the c-Code. I use the Realview Compiler.

Thanks.

Parents Reply Children
  • Hello Michael here is the reposted question,

    the 1. variant with separate function worked wonderful.

    1. Variant:

    void __asm nestedIrqEnable(void){
    
    STMFD SP!, {R0}
    
    MOV R0, LR
    
    MRS LR, SPSR
    
    STMFD SP!, {LR}
    
    MSR CPSR_c, #0x1F
    
    STMFD SP!, {LR}
    
    BX R0
    }
    
    void __asm nestedIrqDisable(void){
    
    MOV R0, LR
    
    LDMFD SP!, {LR}
    
    MSR CPSR_c, #0x92
    
    LDMFD SP!, {LR}
    
    MSR SPSR_cxsf, LR
    
    MOV LR, R0
    
    LDMFD SP!, {R0}
    
    BX LR
    }
    

    By the 2. Variant with SWI-function the variable intrp_count in the eint1_srv() interrupt subroutine is not inceremented.

    2. Variant:

    void __asm __swi(0) nestedIrqEnable(void);
    
    void __asm __SWI_0(void) { //Nested Interrupts Entry: STMFD SP!, {R0}
    
    MOV R0, LR
    
    MRS LR, SPSR
    
    STMFD SP!, {LR}
    
    MSR CPSR_c, #0x1F
    
    STMFD SP!, {LR}
    
    BX R0
    }
    
    void __asm __swi(1) nestedIrqDisable(void);
    void __asm __SWI_1 (void) {//Nested Interrupts Exit:
    MOV R0, LR
    
    LDMFD SP!, {LR}
    
    MSR CPSR_c, #0x92
    
    LDMFD SP!, {LR}
    
    MSR SPSR_cxsf, LR
    
    MOV LR, R0
    
    LDMFD SP!, {R0}
    
    BX LR
    }
    
    /* Create a long time delay */
    
    void delay (void) {
    
    int i;
    
    for (i = 0; i < 0x50000; i++) {
    
    ;
    
    }
    
    }
    
    void eint1_srv (void) __irq {
    
    EXTINT = 2; // Clear EINT1 interrupt flag
    
    nestedIrqEnable(); // allow nested interrupts
    
    delay (); // wait a long time
    
    ++intrp_count; // increment interrupt count
    
    nestedIrqDisable(); // disable interrupt nesting
    
    VICVectAddr = 0; // Acknowledge Interrupt
    
    }
    


    I tested previously the SWI-Mode in the same Project with the folowing code in conjunction with the below SWI.s file

    nt __swi(0) swi_sum(int x, int y);
    int __SWI_0 (int x, int y){
    return (x+y);
    }
    int __swi(1) swi_mul (int x, int y);
    int __SWI_1 (int x, int y){
    return (x*y);
    }
    

    SWI.S-File:

    T_Bit EQU 0x20
    
    PRESERVE8 ;8-Byte aligned Stack
    
    AREA SWI_Area, CODE, READONLY
    
    ARM
    
    EXPORT SWI_Handler
    
    SWI_Handler
    
    STMFD SP!, {R12, LR} ; Store R12, LR
    
    MRS R12, SPSR ; Get SPSR
    
    STMFD SP!, {R8, R12} ; Store R8, SPSR
    
    TST R12, #T_Bit ; Check Thumb Bit LDRNEH R12, [LR,#-2] ; Thumb: Load Halfword
    
    BICNE R12, R12, #0xFF00
    
    ; Extract SWI Number LDREQ R12, [LR,#-4] ;
    ARM: Load Word BICEQ R12, R12, #0xFF000000
    
    ; Extract SWI Number
    
    LDR R8, SWI_Count
    
    CMP R12, R8
    
    BHS SWI_Dead ;
    Overflow ADR R8, SWI_Table
    
    LDR R12, [R8,R12,LSL #2] ; Load
    SWI Function Address MOV LR, PC ; Return Address
    
    BX R12 ; Call SWI Function
    
    LDMFD SP!, {R8, R12} ; Load R8, SPSR
    
    MSR SPSR_cxsf, R12 ; Set SPSR
    
    LDMFD SP!, {R12, PC}^ ; Restore R12 and Return
    
    SWI_Dead B SWI_Dead ; None Existing SWI
    
    SWI_Cnt EQU (SWI_End-SWI_Table)/4
    
    SWI_Count DCD SWI_Cnt
    
    IMPORT __SWI_0
    
    IMPORT __SWI_1
    
    SWI_Table DCD __SWI_0 ; SWI 0 Function Entry DCD __SWI_1 ; SWI 1 Function Entry
    
    ; ...
    SWI_End
    
    END
    


    The code for the swi_sum and swi_mul functioned.

    Thank you for your Help