Reply by Miroslav Kostadinov●March 9, 20062006-03-09
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..
> >
> >
> >
>
------
> >
> >
>
>
> __________________________________________________
>
>
__________________________________________________
Reply by Miroslav Kostadinov●March 9, 20062006-03-09
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..
>
>
>
------
>
>
__________________________________________________
Reply by Henk Visser●March 8, 20062006-03-08
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 >