;* ---------------------------------------------------------------------------- | |
;* ATMEL Microcontroller Software Support - ROUSSET - | |
;* ---------------------------------------------------------------------------- | |
;* Copyright (c) 2006, Atmel Corporation | |
; | |
;* All rights reserved. | |
;* | |
;* Redistribution and use in source and binary forms, with or without | |
;* modification, are permitted provided that the following conditions are met: | |
;* | |
;* - Redistributions of source code must retain the above copyright notice, | |
;* this list of conditions and the disclaimer below. | |
;* | |
;* - Redistributions in binary form must reproduce the above copyright notice, | |
;* this list of conditions and the disclaimer below in the documentation and/or | |
;* other materials provided with the distribution. | |
;* | |
;* Atmel's name may not be used to endorse or promote products derived from | |
;* this software without specific prior written permission. | |
;* | |
;* DISCLAIMER: THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR | |
;* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF | |
;* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE | |
;* DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR ANY DIRECT, INDIRECT, | |
;* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT | |
;* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, | |
;* OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF | |
;* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING | |
;* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, | |
;* EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | |
;* ---------------------------------------------------------------------------- | |
;------------------------------------------------------------------------------ | |
; Include your AT91 Library files | |
;------------------------------------------------------------------------------ | |
#include "AT91SAM7X256_inc.h" | |
;------------------------------------------------------------------------------ | |
#define TOP_OF_MEMORY (AT91C_ISRAM + AT91C_ISRAM_SIZE) | |
#define IRQ_STACK_SIZE 200 | |
; 3 words to be saved per interrupt priority level | |
; Mode, correspords to bits 0-5 in CPSR | |
MODE_BITS DEFINE 0x1F ; Bit mask for mode bits in CPSR | |
USR_MODE DEFINE 0x10 ; User mode | |
FIQ_MODE DEFINE 0x11 ; Fast Interrupt Request mode | |
IRQ_MODE DEFINE 0x12 ; Interrupt Request mode | |
SVC_MODE DEFINE 0x13 ; Supervisor mode | |
ABT_MODE DEFINE 0x17 ; Abort mode | |
UND_MODE DEFINE 0x1B ; Undefined Instruction mode | |
SYS_MODE DEFINE 0x1F ; System mode | |
I_BIT DEFINE 0x80 | |
F_BIT DEFINE 0x40 | |
;------------------------------------------------------------------------------ | |
; ?RESET | |
; Reset Vector. | |
; Normally, segment INTVEC is linked at address 0. | |
; For debugging purposes, INTVEC may be placed at other addresses. | |
; A debugger that honors the entry point will start the | |
; program in a normal way even if INTVEC is not at address 0. | |
;------------------------------------------------------------------------------ | |
SECTION .intvec:CODE:NOROOT(2) | |
PUBLIC __vector | |
PUBLIC __iar_program_start | |
EXTERN vPortYieldProcessor | |
ARM | |
__vector: | |
ldr pc,[pc,#+24] ;; Reset | |
__und_handler: | |
ldr pc,[pc,#+24] ;; Undefined instructions | |
__swi_handler: | |
ldr pc,[pc,#+24] ;; Software interrupt (SWI/SVC) | |
__prefetch_handler: | |
ldr pc,[pc,#+24] ;; Prefetch abort | |
__data_handler: | |
ldr pc,[pc,#+24] ;; Data abort | |
DC32 0xFFFFFFFF ;; RESERVED | |
__irq_handler: | |
LDR PC, [PC, #-0xF20] | |
__fiq_handler: | |
ldr pc,[pc,#+24] ;; FIQ | |
DC32 __iar_program_start | |
DC32 __und_handler | |
DC32 vPortYieldProcessor | |
DC32 __prefetch_handler | |
DC32 __data_handler | |
B . | |
DC32 IRQ_Handler_Entry | |
DC32 FIQ_Handler_Entry | |
;------------------------------------------------------------------------------ | |
;- Manage exception: The exception must be ensure in ARM mode | |
;------------------------------------------------------------------------------ | |
SECTION text:CODE:NOROOT(2) | |
ARM | |
;------------------------------------------------------------------------------ | |
;- Function : FIQ_Handler_Entry | |
;- Treatments : FIQ Controller Interrupt Handler. | |
;- R8 is initialize in Cstartup | |
;- Called Functions : None only by FIQ | |
;------------------------------------------------------------------------------ | |
FIQ_Handler_Entry: | |
;- Switch in SVC/User Mode to allow User Stack access for C code | |
; because the FIQ is not yet acknowledged | |
;- Save and r0 in FIQ_Register | |
mov r9,r0 | |
ldr r0 , [r8, #AIC_FVR] | |
msr CPSR_c,#I_BIT | F_BIT | SVC_MODE | |
;- Save scratch/used registers and LR in User Stack | |
stmfd sp!, { r1-r3, r12, lr} | |
;- Branch to the routine pointed by the AIC_FVR | |
mov r14, pc | |
bx r0 | |
;- Restore scratch/used registers and LR from User Stack | |
ldmia sp!, { r1-r3, r12, lr} | |
;- Leave Interrupts disabled and switch back in FIQ mode | |
msr CPSR_c, #I_BIT | F_BIT | FIQ_MODE | |
;- Restore the R0 ARM_MODE_SVC register | |
mov r0,r9 | |
;- Restore the Program Counter using the LR_fiq directly in the PC | |
subs pc,lr,#4 | |
;------------------------------------------------------------------------------ | |
;- Function : IRQ_Handler_Entry | |
;- Treatments : IRQ Controller Interrupt Handler. | |
;- Called Functions : AIC_IVR[interrupt] | |
;------------------------------------------------------------------------------ | |
IRQ_Handler_Entry: | |
;------------------------- | |
;- Manage Exception Entry | |
;------------------------- | |
;- Adjust and save LR_irq in IRQ stack | |
sub lr, lr, #4 | |
stmfd sp!, {lr} | |
;- Save r0 and SPSR (need to be saved for nested interrupt) | |
mrs r14, SPSR | |
stmfd sp!, {r0,r14} | |
;- Write in the IVR to support Protect Mode | |
;- No effect in Normal Mode | |
;- De-assert the NIRQ and clear the source in Protect Mode | |
ldr r14, =AT91C_BASE_AIC | |
ldr r0 , [r14, #AIC_IVR] | |
str r14, [r14, #AIC_IVR] | |
;- Enable Interrupt and Switch in Supervisor Mode | |
msr CPSR_c, #SVC_MODE | |
;- Save scratch/used registers and LR in User Stack | |
stmfd sp!, { r1-r3, r12, r14} | |
;---------------------------------------------- | |
;- Branch to the routine pointed by the AIC_IVR | |
;---------------------------------------------- | |
mov r14, pc | |
bx r0 | |
;---------------------------------------------- | |
;- Manage Exception Exit | |
;---------------------------------------------- | |
;- Restore scratch/used registers and LR from User Stack | |
ldmia sp!, { r1-r3, r12, r14} | |
;- Disable Interrupt and switch back in IRQ mode | |
msr CPSR_c, #I_BIT | IRQ_MODE | |
;- Mark the End of Interrupt on the AIC | |
ldr r14, =AT91C_BASE_AIC | |
str r14, [r14, #AIC_EOICR] | |
;- Restore SPSR_irq and r0 from IRQ stack | |
ldmia sp!, {r0,r14} | |
msr SPSR_cxsf, r14 | |
;- Restore adjusted LR_irq from IRQ stack directly in the PC | |
ldmia sp!, {pc}^ | |
;------------------------------------------------------------------------------ | |
;- Exception Vectors | |
;------------------------------------------------------------------------------ | |
PUBLIC AT91F_Default_FIQ_handler | |
PUBLIC AT91F_Default_IRQ_handler | |
PUBLIC AT91F_Spurious_handler | |
ARM ; Always ARM mode after exeption | |
AT91F_Default_FIQ_handler | |
b AT91F_Default_FIQ_handler | |
AT91F_Default_IRQ_handler | |
b AT91F_Default_IRQ_handler | |
AT91F_Spurious_handler | |
b AT91F_Spurious_handler | |
;------------------------------------------------------------------------------ | |
; ?INIT | |
; Program entry. | |
;------------------------------------------------------------------------------ | |
SECTION FIQ_STACK:DATA:NOROOT(3) | |
SECTION IRQ_STACK:DATA:NOROOT(3) | |
SECTION SVC_STACK:DATA:NOROOT(3) | |
SECTION ABT_STACK:DATA:NOROOT(3) | |
SECTION UND_STACK:DATA:NOROOT(3) | |
SECTION CSTACK:DATA:NOROOT(3) | |
SECTION text:CODE:NOROOT(2) | |
REQUIRE __vector | |
EXTERN ?main | |
PUBLIC __iar_program_start | |
EXTERN AT91F_LowLevelInit | |
__iar_program_start: | |
;------------------------------------------------------------------------------ | |
;- Low level Init is performed in a C function: AT91F_LowLevelInit | |
;- Init Stack Pointer to a valid memory area before calling AT91F_LowLevelInit | |
;------------------------------------------------------------------------------ | |
;- Retrieve end of RAM address | |
ldr r13,=TOP_OF_MEMORY ;- Temporary stack in internal RAM for Low Level Init execution | |
ldr r0,=AT91F_LowLevelInit | |
mov lr, pc | |
bx r0 ;- Branch on C function (with interworking) | |
; Initialize the stack pointers. | |
; The pattern below can be used for any of the exception stacks: | |
; FIQ, IRQ, SVC, ABT, UND, SYS. | |
; The USR mode uses the same stack as SYS. | |
; The stack segments must be defined in the linker command file, | |
; and be declared above. | |
mrs r0,cpsr ; Original PSR value | |
bic r0,r0,#MODE_BITS ; Clear the mode bits | |
orr r0,r0,#SVC_MODE ; Set SVC mode bits | |
msr cpsr_c,r0 ; Change the mode | |
ldr sp,=SFE(SVC_STACK) ; End of SVC_STACK | |
bic r0,r0,#MODE_BITS ; Clear the mode bits | |
orr r0,r0,#UND_MODE ; Set UND mode bits | |
msr cpsr_c,r0 ; Change the mode | |
ldr sp,=SFE(UND_STACK) ; End of UND_STACK | |
bic r0,r0,#MODE_BITS ; Clear the mode bits | |
orr r0,r0,#ABT_MODE ; Set ABT mode bits | |
msr cpsr_c,r0 ; Change the mode | |
ldr sp,=SFE(ABT_STACK) ; End of ABT_STACK | |
bic r0,r0,#MODE_BITS ; Clear the mode bits | |
orr r0,r0,#FIQ_MODE ; Set FIQ mode bits | |
msr cpsr_c,r0 ; Change the mode | |
ldr sp,=SFE(FIQ_STACK) ; End of FIQ_STACK | |
;- Init the FIQ register | |
ldr r8, =AT91C_BASE_AIC | |
bic r0,r0,#MODE_BITS ; Clear the mode bits | |
orr r0,r0,#IRQ_MODE ; Set IRQ mode bits | |
msr cpsr_c,r0 ; Change the mode | |
ldr sp,=SFE(IRQ_STACK) ; End of IRQ_STACK | |
bic r0,r0,#MODE_BITS ; Clear the mode bits | |
orr r0,r0,#SYS_MODE ; Set System mode bits | |
msr cpsr_c,r0 ; Change the mode | |
ldr sp,=SFE(CSTACK) ; End of CSTACK | |
#ifdef __ARMVFP__ | |
; Enable the VFP coprocessor. | |
mov r0, #0x40000000 ; Set EN bit in VFP | |
fmxr fpexc, r0 ; FPEXC, clear others. | |
; Disable underflow exceptions by setting flush to zero mode. | |
; For full IEEE 754 underflow compliance this code should be removed | |
; and the appropriate exception handler installed. | |
mov r0, #0x01000000 ; Set FZ bit in VFP | |
fmxr fpscr, r0 ; FPSCR, clear others. | |
#endif | |
; Add more initialization here | |
msr CPSR_c,#I_BIT | F_BIT | SVC_MODE | |
; Continue to ?main for more IAR specific system startup | |
ldr r0,=?main | |
bx r0 | |
END ;- Terminates the assembly of the last module in a file |