> The question is: will be cpsr_of-current-mode copied to SPSR when I
manually
> switch the modes?
According to the Addison Wesley's ARM Architecture Reference Manual,
MSR will update your choice of CPSR or SPSR but not BOTH. However,
changing modes will switch registers, so when CPSR is updated, SPSR
will be switched to the new mode's.
You should not exit an IRQ or FIQ with SUB but with SUBS in order to
return to the previous (user or other) mode. Otherwise, you would be
leaving the IRQ still in IRQ mode.
The way I see it:
; Scenario: IRQ triggered when in user mode
; The µP saves user mode CPSR to spsr@IRQ, switches to IRQ mode
(switching registers) and jumps to xxx_IRS
; spsr@FIQ has some unknown value
xxx_IRS:
msr cpsr_c, #MODE_FIQ|FIQ_BIT|IRQ_BIT ; @ switch to FIQ with ints
dsbld.
; both spsr@FIQ and spsr@IRQ remain unchanged; you've got now
spsr@FIQ visible, which has garbage (i.e., a previous unpredictable
value)
... ISR code ...
msr cpsr_c, #MODE_IRQ|FIQ_BIT|IRQ_BIT ; @ back to IRQ mode
; both spsr@FIQ and spsr@IRQ remain unchanged; you've got now
spsr@IRQ visible, which has the user mode CPSR
subs pc,lr,#4 ; @ return from interrupt
; subs copies spsr@IRQ to CPSR and now everybody is happy ;)
Guille
--- In lpc2000@yahoogroups.com, Dmitry Diky <ddiky@a...> wrote:
>
> Hi Sten,
>
> > Uuuuuuuuuhhhhhhh, ... Are you sure you know what you are doing?
>
> Well, I am pretty sure...
> To be precise I got two possible interrupt requests: - timer and
SPI ones.
> I assign timer interupt to IRQ and SPI to FIQ. However, on timer
interrupt,
> the SPI transfer should be initiated.
>
> To save some interrupt processing time I initiate timer and SPI
register, the
> switch to FIQ mode (via swi interrupt) and assign some peripherial
regs to
> FIQ registers r8_fiq, r8_fiq, ... So, in FIQ mode I do not have to
load
> complicated values (0xe0020000 for example) to the register.
>
> However, in timer ISR I have to manipulate with timer registers and
SPI
> registers which are already assigned to _fiq registers... So, why
not to
> switch to FIQ mode in IRQ ISR providing no other interrupts can
occur during
> IRQ processing?
>
> > FIQ- and IRQ-mode are dedicated modes for the two types of
interrupts (FIQ
> > and IRQ) ARM have. If you define an interrupt as a fast-IRQ (FIQ)
than you
> > have the goal that the system automatically enters FIQ mode and
will save
> > some additional registers when this interrupt occurs.
>
> Yes, thats why I assign FIQ to SPI - I need a counter which I keep
in a
> register and therefore do not have to load it from memory...
> The overall process is the following:
>
> fiq_isr: (located at 0x1c)
> ... just maipulate with SPI
> ... uses r8_fiq... r13_fiq as general-purpose
registers
>
> sub pc, lr, #4 <- exit from FIQ
>
> timer_isr: (called via vectored interrupt controller)
> msr cpsr_c, #mode_fiq|i_bit|f_bit
> ... manipulate with timer
> ... start SPI transfer
> ... uses r8_fiq...r13_fiq
> msr cpsr_c, #mode_irq|i_bit|f_bit
>
> sub pc, lr, #4
>
>
>
>
> I am pretty sure, that timer interrupts can occur only when CPU is
in idle
> state, except when UART transfer is in progress. However, I do not
facilitate
> nested interrupts, so no problems with cpsr_c should happen...
>
> The question is: will be cpsr_of-current-mode copied to SPSR when I
manually
Show quoted textHide quoted text
> switch the modes?
>
> Thanks,
> Dmitry.
>