cancel
Showing results for 
Search instead for 
Did you mean: 

Is my interrupt handler correct??

dan1
Associate II
Posted on July 15, 2009 at 18:15

Is my interrupt handler correct??

1 REPLY 1
dan1
Associate II
Posted on May 17, 2011 at 09:59

I'm *still* having problems with interrupts apparently interacting with each other. Our design has timer0, ADC, UART0/1, and RTC running. The basic problem we're seeing is various anomalies in the UART interrupts, which I've discussed previously here. Since I never found a ''canonical'' reference for the Interrupt Handler, I've used various references over the past year. Originally I was using the version from the ST USB demo (RIDE), but that apparently is incomplete. I then switched to the version used by IAR, but I really have no guarantee that this is complete and correct in our current (Yagarto) build environment.

I would be grateful if people here (especially those who are also using multiple interrupts, and are building with Yagarto or other GnuArm environments) could comment on this code, which I'm enclosing below.

Thank you all very much!!

Dan Miller

/*;*******************************************************************************

;* Macro Name : SaveContext

;* Description : This macro used to save the context before entering

; an exception handler.

;* Input : The range of registers to store.

;* Output : none

;*******************************************************************************/

.macro SaveContext reg1 reg2

STMFD sp!,{\reg1-\reg2,lr} /* Save The workspace plus the current return */

/* address lr_ mode into the stack */

MRS r1, spsr /* Save the spsr_mode into r1 */

STMFD sp!, {r1} /* Save spsr */

.endm

/*;*******************************************************************************

;* Macro Name : RestoreContext

;* Description : This macro used to restore the context to return from

; an exception handler and continue the program execution.

;* Input : The range of registers to restore.

;* Output : none

;*******************************************************************************/

.macro RestoreContext reg1 reg2

LDMFD sp!, {r1} /* Restore the saved spsr_mode into r1 */

MSR spsr_cxsf, r1 /* Restore spsr_mode */

LDMFD sp!, {\reg1-\reg2,pc}^ /* Return to the instruction following */

/* the exception interrupt */

.endm

/********************************************************************************

* Function Name : IRQHandler

* Description : This function is called when IRQ exception is entered.

* Input : none

* Output : none

********************************************************************************/

IRQHandler:

# STR9 firmware method from ST (Ride code)

# SUB lr,lr ,#4

# SaveContext r0,r4

# LDR r0, = VectorAddress

# LDR r0, [r0] /* Read the routine address from VIC0 Vector Address register */

#

# BLX r0 /* Branch with link to the IRQ handler. */

# RestoreContext r0,r4

# STR9 firmware method from IAR

SUB lr,lr,#4 /* ; Update the link register */

SaveContext r0,r12 /* ; Save the workspace plus the current */

/* ; return address lr_irq and spsr_irq */

LDR r0, = VectorAddress

LDR r0, [r0] /* ; Read the routine address */

LDR r1, = VectorAddressDaisy

LDR r1, [r1]

/* ; Padding between the acknowledge and re-enable of interrupts */

/* ; For more details, please refer to the following URL */

/* ;

http://www.arm.com/support/faqip/3682.html

*/

NOP

NOP

MSR cpsr_c, #Mode_SYS /* Switch to SYS mode and enable IRQ */

STMFD sp!,{lr} /* ; Save the link register. */

LDR lr, =IRQ_ReturnAddress /* ; Read the return address. */

BX r0 /* ; Branch to the IRQ handler. */

IRQ_ReturnAddress:

LDMFD sp!,{lr} /* ; Restore the link register. */

MSR cpsr_c, #Mode_IRQ|I_Bit|F_Bit /* Switch to IRQ mode and disable IRQ */

LDR r0, =VectorAddress /* ; Write to the VectorAddress to clear the */

STR r0, [r0] /* ; respective interrupt in the internal interrupt */

LDR r1, =VectorAddressDaisy /* ; Write to the VectorAddressDaisy to clear the */

STR r1,[r1] /* ; respective interrupt in the internal interrupt */

RestoreContext r0,r12 /* ; Restore the context and return to the program execution. */