EmbeddedRelated.com
Forums
Memfault Beyond the Launch

Miro -- Interrupts

Started by Henk Visser March 8, 2006
Miro,
 
Thanks for the post!  I have included my comments/questions below.
----- Original Message -----
From: Miroslav Kostadinov
To: A...@yahoogroups.com
Sent: Wednesday, March 08, 2006 5:32 AM
Subject: Re: [AT91SAM] Any Interrupt Hot Shots out there?

I had similar problem...

Some interrupts that were properly configured, enabled
etc were never processed from the CPU.

I spent a lot of time solving this problem and I can
say it is a complicated issue. Here I will just
recommend 3 simple things if you want to get rid of
the problem:

1) If you use IAR & CSPY make sure it is version 4.30A
(or newer). Version 4.11 was too bad...
 
*** I'm using the IAR Workbench version 4.30A.


2) Use Protected mode for the AIC so you can watch the
AIC registers in the debugger without causing
troubles...
 
*** Entering Protect Mode is done by writing 0x1 to AIC_DCR (Debug Control Register).  In section 24.7.5 of the AT91SAM7S256 datasheet there is an explaination of Protect Mode and I had a question about the followign line:
 
"The Interrupt Service Routine must write (arbitrary data) to the AIC_IVR just after reading it."
 
I don't see how I am to write to this register when it is read-only!  If you could please explain this further that would be great.  Do you mind
pasting in your interrupt routine that handles the interrupt that worked in the debugger for you?
 

3) After reset, write AIC_EOICR >8 times with
something.
This is very important, as your code may crash during
interrupt processing or just stop at breakpoint inside
of interrupt, then if you reset/reprogram your system
you may not get any interrupt working...
 
****  Right at the begingging of main() before I do anything I write to AIC_EOICR 10 times. Hopefully that will do! Thanks for your comments!


Regards,
Miro
--- Andreas Siebel <i...@gmx.de> wrote:

> Hi Henk!

> Did you have a look at the datasheet at the point
> Protect Mode in the
> section of the AIC ? Its on page 162 in my
> Datasheet (Version of
> 5Dec05) or just search for Protect Mode.

> Andreas


__________________________________________________



Henk,

About the implementation...

I have modified AT91F_LowLevelInit() to enter
protected mode and clear any pending interrupts after
reset.
I think this the best place because it is the first
function ever called after reset and it is defenetly
called with all interrupts disabled, so you can write
AIC_EOICR safely.

Here is the code:

// Set up the default interrupts handler vectors
AT91C_BASE_AIC->AIC_SVR[0] = (int)
AT91F_Default_FIQ_handler ;
for (int i=2;i < 31; i++)
{
    AT91C_BASE_AIC->AIC_SVR[i] = (int)
AT91F_Default_IRQ_handler ;
    AT91C_BASE_AIC->AIC_EOICR = 0;
}
AT91C_BASE_AIC->AIC_SPU  = (int)
AT91F_Spurious_handler ;

AT91C_BASE_AIC->AIC_DCR = AT91C_AIC_DCR_PROT;

......
As you can see I write 32 times EOICR - I was too lazy
to code my own loop ;-)
	About the ISR - yep! You must write something in
AIC_IVR...

I can give you my code, but I have context switching
etc (I make my own RTOS) so you may get confused...

With simple words I use SWP instead of LDR instruction
to load the pending vector. It is like this:

   ldr  r4, =AT91C_AIC_IVR
   swp  r0, r0, [r4]

in this way you don't have extra code to support
protected mode
Just find the LDR instruction in your IRQ handler and
replace it with SWP....

If you want send me your IRQ handler and I will make
it shorter, faster and protected mode compatible ;-)
	Good Luck
Miro
	--- Henk Visser <dutchman1234@dutc...> wrote:

> Miro,
> 
> Thanks for the post!  I have included my
> comments/questions below.
>   *** Entering Protect Mode is done by writing 0x1
> to AIC_DCR (Debug Control Register).  In section
> 24.7.5 of the AT91SAM7S256 datasheet there is an
> explaination of Protect Mode and I had a question
> about the followign line:
> 
>   "The Interrupt Service Routine must write
> (arbitrary data) to the AIC_IVR just after reading
> it."
> 
>   I don't see how I am to write to this register
> when it is read-only!  If you could please explain
> this further that would be great.  Do you mind
>   pasting in your interrupt routine that handles the
> interrupt that worked in the debugger for you? 
> 
> 
>   3) After reset, write AIC_EOICR >8 times with
>   something.
>   This is very important, as your code may crash
> during
>   interrupt processing or just stop at breakpoint
> inside
>   of interrupt, then if you reset/reprogram your
> system
>   you may not get any interrupt working... 
> 
>   ****  Right at the begingging of main() before I
> do anything I write to AIC_EOICR 10 times. Hopefully
> that will do! Thanks for your comments!
> 
> 
>   Regards,
>   Miro
> 
> 
> 
>   --- Andreas Siebel <im_urlaub@im_u...> wrote:
> 
>   > Hi Henk!
>   >  
>   > Did you have a look at the datasheet at the
> point
>   > "Protect Mode" in the
>   > section of the AIC ? It's on page 162 in my
>   > Datasheet (Version of
>   > 5Dec05) or just search for "Protect Mode".
>   >  
>   > Andreas
>   >  
> 
>   __________________________________________________
>    
> 
> 
> 
>   SPONSORED LINKS Microcontrollers  Cpu chip  Arms  
>         Development tool  Microprocessor  
> 
> 
>
------
>   YAHOO! GROUPS LINKS 
> 
>     a..   
> 
> 
>
------
> 
>
	__________________________________________________
 

I just realized that Atmel have fixed their IRQ
handler already so it can support protected mode....
(the earliest version was bugous)

However, it is still not imporoved in terms of speed
and size... here are some suggestions for thouse who
use the standard handlers:

; Atmel version
; 20 instructions 
; 52 bus cycles
IRQ_Handler_Entry:
	sub         lr, lr, #4						;1
	stmfd       sp!, {lr}						;2
	mrs         r14, SPSR						;1
	stmfd       sp!, {r14}						;2
	stmfd       sp!, {r0}						;2
	ldr         r14, =AT91C_BASE_AIC			;3
	ldr         r0 , [r14, #AIC_IVR]			;3
	str         r14, [r14, #AIC_IVR]			;2
	msr         CPSR_c, #ARM_MODE_SVC			;1
	stmfd       sp!, { r1-r3, r12, r14}			;6
	mov         r14, pc							;1
	bx          r0								;3
	
	ldmia       sp!, { r1-r3, r12, r14}			;7
	msr         CPSR_c, #I_BIT | ARM_MODE_IRQ	;1
	ldr         r14, =AT91C_BASE_AIC			;3
	str         r14, [r14, #AIC_EOICR]			;2
	ldmia       sp!, {r0}						;3
	ldmia       sp!, {r14}						;3
	msr         SPSR_cxsf, r14					;1
	ldmia       sp!, {pc}^						;5
	;same as original, just improved...    
;15 instructions
;45 bus cycles
IRQ_Handler_Entry:
	sub         lr, lr, #4						;1
	stmfd       sp!, {r0, r4, lr}				;4
	mrs         r4, SPSR						;1
	ldr         r14, =AT91C_BASE_AIC			;3
	swp         r0 , r0, [r14, #AIC_IVR]		;4
	msr         CPSR_c, #ARM_MODE_SVC			;1
	stmfd       sp!, { r1-r3, r12, r14}			;6
	mov         r14, pc							;1
	bx          r0								;3
	
	ldmia       sp!, { r1-r3, r12, r14}			;7
	msr         CPSR_c, #I_BIT | ARM_MODE_IRQ	;1
	ldr         r14, =AT91C_BASE_AIC			;3
	str         r14, [r14, #AIC_EOICR]			;2
	msr         SPSR_cxsf, r4					;1
	ldmia       sp!, {r0, r4, pc}^				;7
	; using more IRQ stack... the linker config file may
have to be fixed
;14 instruction
;43 bus cycles
IRQ_Handler_Entry:

	sub         lr, lr, #4						;1
	stmfd		sp!, {r0-r6, r12, lr}			;10
	mrs			r5, SPSR						;1
	ldr			r4, =AT91C_BASE_AIC				;3
	swp			r0, r0, [r4, #AIC_IVR]			;4
	msr			CPSR_c, #ARM_MODE_SVC			;1
	mov			r6, lr							;1
	mov			lr, pc							;1
	bx			r0								;3

	mov			lr, r6							;1
	msr			CPSR_c, #ARM_MODE_IRQ | I_BIT	;1
	str			lr, [r4, #AIC_EOICR]			;2
	msr			SPSR_cxsf, R5					;1
	ldmfd		sp!, {r0-r6, r12, pc}^			;13
	--- Miroslav Kostadinov <miro_atc@miro...> wrote:

> Henk,
> 
> About the implementation...
> 
> I have modified AT91F_LowLevelInit() to enter
> protected mode and clear any pending interrupts
> after
> reset.
> I think this the best place because it is the first
> function ever called after reset and it is defenetly
> called with all interrupts disabled, so you can
> write
> AIC_EOICR safely.
> 
> Here is the code:
> 
> // Set up the default interrupts handler vectors
> AT91C_BASE_AIC->AIC_SVR[0] = (int)
> AT91F_Default_FIQ_handler ;
> for (int i=2;i < 31; i++)
> {
>     AT91C_BASE_AIC->AIC_SVR[i] = (int)
> AT91F_Default_IRQ_handler ;
>     AT91C_BASE_AIC->AIC_EOICR = 0;
> }
> AT91C_BASE_AIC->AIC_SPU  = (int)
> AT91F_Spurious_handler ;
> 
> AT91C_BASE_AIC->AIC_DCR = AT91C_AIC_DCR_PROT;
> 
> ......
> As you can see I write 32 times EOICR - I was too
> lazy
> to code my own loop ;-)
> 
> 
> About the ISR - yep! You must write something in
> AIC_IVR...
> 
> I can give you my code, but I have context switching
> etc (I make my own RTOS) so you may get confused...
> 
> With simple words I use SWP instead of LDR
> instruction
> to load the pending vector. It is like this:
> 
>    ldr  r4, =AT91C_AIC_IVR
>    swp  r0, r0, [r4]
> 
> in this way you don't have extra code to support
> protected mode
> Just find the LDR instruction in your IRQ handler
> and
> replace it with SWP....
> 
> If you want send me your IRQ handler and I will make
> it shorter, faster and protected mode compatible ;-)
> 
> 
> Good Luck
> Miro
> 
> 
> 
> 
> 
> 
> 
> 
> 
> 
> 
> --- Henk Visser <dutchman1234@dutc...> wrote:
> 
> > Miro,
> > 
> > Thanks for the post!  I have included my
> > comments/questions below.
> >   *** Entering Protect Mode is done by writing 0x1
> > to AIC_DCR (Debug Control Register).  In section
> > 24.7.5 of the AT91SAM7S256 datasheet there is an
> > explaination of Protect Mode and I had a question
> > about the followign line:
> > 
> >   "The Interrupt Service Routine must write
> > (arbitrary data) to the AIC_IVR just after reading
> > it."
> > 
> >   I don't see how I am to write to this register
> > when it is read-only!  If you could please explain
> > this further that would be great.  Do you mind
> >   pasting in your interrupt routine that handles
> the
> > interrupt that worked in the debugger for you? 
> > 
> > 
> >   3) After reset, write AIC_EOICR >8 times with
> >   something.
> >   This is very important, as your code may crash
> > during
> >   interrupt processing or just stop at breakpoint
> > inside
> >   of interrupt, then if you reset/reprogram your
> > system
> >   you may not get any interrupt working... 
> > 
> >   ****  Right at the begingging of main() before I
> > do anything I write to AIC_EOICR 10 times.
> Hopefully
> > that will do! Thanks for your comments!
> > 
> > 
> >   Regards,
> >   Miro
> > 
> > 
> > 
> >   --- Andreas Siebel <im_urlaub@im_u...> wrote:
> > 
> >   > Hi Henk!
> >   >  
> >   > Did you have a look at the datasheet at the
> > point
> >   > "Protect Mode" in the
> >   > section of the AIC ? It's on page 162 in my
> >   > Datasheet (Version of
> >   > 5Dec05) or just search for "Protect Mode".
> >   >  
> >   > Andreas
> >   >  
> > 
> >  
> __________________________________________________
> >    
> > 
> > 
> > 
> >   SPONSORED LINKS Microcontrollers  Cpu chip  Arms
>  
> >         Development tool  Microprocessor  
> > 
> > 
> >
>
------
> >   YAHOO! GROUPS LINKS 
> > 
> >     a..   
> > 
> > 
> >
>
------
> > 
> > 
> 
> 
> __________________________________________________
>  
>
	__________________________________________________
 


Memfault Beyond the Launch