hi, Am using LPC2366.From the keil sample software i took two macros IENABLE and IDISABLE and their definitions,used in ISR routine as in sample code.But my software hangs at PAbt_Addr DCD PAbt_Handler.what is the reason?
// Macro for enabling interrupts, moving to System mode and relevant stack operations #define IENABLE /* Nested Interrupts Entry */ \ __asm { MRS LR, SPSR } /* Copy SPSR_irq to LR */ \ __asm { STMFD SP!, {LR} } /* Save SPSR_irq */ \ __asm { MSR CPSR_c, #0x1F } /* Enable IRQ (Sys Mode) */ \ __asm { STMFD SP!, {LR} } /* Save LR */ \ // Macro for disabling interrupts, switching back to IRQ and relevant stack operations #define IDISABLE /* Nested Interrupts Exit */ \ __asm { LDMFD SP!, {LR} } /* Restore LR */ \ __asm { MSR CPSR_c, #0x92 } /* Disable IRQ (IRQ Mode) */ \ __asm { LDMFD SP!, {LR} } /* Restore SPSR_irq to LR */ \ __asm { MSR SPSR_cxsf, LR } /* Copy LR to SPSR_irq */ \ i got the following error.Can u suggest whats the problem?? compiling irq2366.c... ..\Src\LowLevel\irq2366.c(250): error: #20: identifier "LR" is undefined ..\Src\LowLevel\irq2366.c(250): error: #20: identifier "SP" is undefined ..\Src\LowLevel\irq2366.c(250): error: #20: identifier "LR" is undefined ..\Src\LowLevel\irq2366.c(250): warning: #1287-D: LDM/STM instruction may be expanded ..\Src\LowLevel\irq2366.c(250): error: #20: identifier "SP" is undefined ..\Src\LowLevel\irq2366.c(250): error: #20: identifier "LR" is undefined
Thanks in Advance.
Haven't you asserted that
my software hangs at PAbt_Addr DCD PAbt_Handler ?
sorry for previous one .
#define I_Bit 0x80 #define F_Bit 0x40 #define SYS32Mode 0x1F #define IRQ32Mode 0x12 #define FIQ32Mode 0x11 static DWORD sysreg; /* used as LR register */ //#define IENABLE __asm { MRS sysreg, SPSR; MSR CPSR_c, #SYS32Mode } //#define IDISABLE __asm { MSR CPSR_c, #(IRQ32Mode|I_Bit); MSR SPSR_cxsf, sysreg }
the above results in hanging.
sorry for previous one
#define I_Bit 0x80 #define F_Bit 0x40 #define SYS32Mode 0x1F #define IRQ32Mode 0x12 #define FIQ32Mode 0x11 static DWORD sysreg; /* used as LR register */ #define IENABLE __asm { MRS sysreg, SPSR; MSR CPSR_c, #SYS32Mode } #define IDISABLE __asm { MSR CPSR_c, #(IRQ32Mode|I_Bit); MSR SPSR_cxsf, sysreg }
this results in hanging
keshan, how can anybody help you when you consistently fail to provide full details! now you posted commented code. post the implementation - how you USED there macros and where.
#define I_Bit 0x80 #define F_Bit 0x40 #define SYS32Mode 0x1F #define IRQ32Mode 0x12 #define FIQ32Mode 0x11 static DWORD sysreg; /* used as LR register */ #define IENABLE __asm { MRS sysreg, SPSR; MSR CPSR_c, #SYS32Mode } #define IDISABLE __asm { MSR CPSR_c, #(IRQ32Mode|I_Bit); MSR SPSR_cxsf, sysreg } void PWMHandler (void) __irq { DWORD regVal; IENABLE; /* handles nested interrupt */ regVal = PWM0IR; if ( regVal & MR0_INT ) { match_counter0++; } PWM0IR |= regVal; /* clear interrupt flag on match 0 */ regVal = PWM1IR; if ( regVal & MR0_INT ) { match_counter1++; } PWM1IR |= regVal; /* clear interrupt flag on match 0 */ IDISABLE; VICVectAddr = 0; /* Acknowledge Interrupt */ return; }
Hi Keshan,
the macros you are trying to use to get nested interrupts don't really work. ARM provides a document called "Exception_Handling.ppt" which explains in detail how to handle nested interrupts. I can tell you that you can not use the compiler provided interrupt interface "__irq" to fulfill the ARM requirements. You may have to implement your own assembly interface for nested interrupts and write your high-level handlers in C or C++.
Frank