;------------------------------------------------------------------------------ | |
;- ATMEL Microcontroller Software Support - ROUSSET - | |
;------------------------------------------------------------------------------ | |
; The software is delivered "AS IS" without warranty or condition of any | |
; kind, either express, implied or statutory. This includes without | |
; limitation any warranty or condition with respect to merchantability or | |
; fitness for any particular purpose, or against the infringements of | |
; intellectual property rights of others. | |
;----------------------------------------------------------------------------- | |
;- File source : Cstartup.s79 | |
;- Object : Generic CStartup for IAR No Use REMAP | |
;- Compilation flag : None | |
;- | |
;- 1.0 15/Jun/04 JPP : Creation | |
;------------------------------------------------------------------------------ | |
#include "AT91SAM7X256_inc.h" | |
;------------------------------------------------------------------------------ | |
;- Area Definition | |
;------------------------------------------------------------------------------ | |
;--------------------------------------------------------------- | |
; ?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. | |
;------------------------------------------------------------- | |
PROGRAM ?RESET | |
RSEG INTRAMSTART_REMAP | |
RSEG INTRAMEND_REMAP | |
EXTERN vPortYieldProcessor | |
RSEG ICODE:CODE:ROOT(2) | |
CODE32 ; Always ARM mode after reset | |
org 0 | |
reset | |
;------------------------------------------------------------------------------ | |
;- Exception vectors | |
;-------------------- | |
;- These vectors can be read at address 0 or at RAM address | |
;- They ABSOLUTELY requires to be in relative addresssing mode in order to | |
;- guarantee a valid jump. For the moment, all are just looping. | |
;- If an exception occurs before remap, this would result in an infinite loop. | |
;- To ensure if a exeption occurs before start application to infinite loop. | |
;------------------------------------------------------------------------------ | |
B InitReset ; 0x00 Reset handler | |
undefvec: | |
B undefvec ; 0x04 Undefined Instruction | |
swivec: | |
B vPortYieldProcessor ; 0x08 Software Interrupt | |
pabtvec: | |
B pabtvec ; 0x0C Prefetch Abort | |
dabtvec: | |
B dabtvec ; 0x10 Data Abort | |
rsvdvec: | |
B rsvdvec ; 0x14 reserved | |
irqvec: | |
LDR PC, [PC, #-0xF20] ; Jump directly to the address given by the AIC | |
fiqvec: ; 0x1c FIQ | |
;------------------------------------------------------------------------------ | |
;- Function : FIQ_Handler_Entry | |
;- Treatments : FIQ Controller Interrupt Handler. | |
;- Called Functions : AIC_FVR[interrupt] | |
;------------------------------------------------------------------------------ | |
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 | ARM_MODE_SVC | |
;- 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 | ARM_MODE_FIQ | |
;- 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 | |
InitReset: | |
;------------------------------------------------------------------------------ | |
;- Low level Init (PMC, AIC, ? ....) by C function AT91F_LowLevelInit | |
;------------------------------------------------------------------------------ | |
EXTERN AT91F_LowLevelInit | |
#define __iramend SFB(INTRAMEND_REMAP) | |
;- minumum C initialization | |
;- call AT91F_LowLevelInit( void) | |
ldr r13,=__iramend ; temporary stack in internal RAM | |
;--Call Low level init function in ABSOLUTE through the Interworking | |
ldr r0,=AT91F_LowLevelInit | |
mov lr, pc | |
bx r0 | |
;------------------------------------------------------------------------------ | |
;- Stack Sizes Definition | |
;------------------------ | |
;- Interrupt Stack requires 2 words x 8 priority level x 4 bytes when using | |
;- the vectoring. This assume that the IRQ management. | |
;- The Interrupt Stack must be adjusted depending on the interrupt handlers. | |
;- Fast Interrupt not requires stack If in your application it required you must | |
;- be definehere. | |
;- The System stack size is not defined and is limited by the free internal | |
;- SRAM. | |
;------------------------------------------------------------------------------ | |
;------------------------------------------------------------------------------ | |
;- Top of Stack Definition | |
;------------------------- | |
;- Interrupt and Supervisor Stack are located at the top of internal memory in | |
;- order to speed the exception handling context saving and restoring. | |
;- ARM_MODE_SVC (Application, C) Stack is located at the top of the external memory. | |
;------------------------------------------------------------------------------ | |
IRQ_STACK_SIZE EQU 300 | |
ARM_MODE_FIQ EQU 0x11 | |
ARM_MODE_IRQ EQU 0x12 | |
ARM_MODE_SVC EQU 0x13 | |
I_BIT EQU 0x80 | |
F_BIT EQU 0x40 | |
;------------------------------------------------------------------------------ | |
;- Setup the stack for each mode | |
;------------------------------- | |
ldr r0, =__iramend | |
;- Set up Fast Interrupt Mode and set FIQ Mode Stack | |
msr CPSR_c, #ARM_MODE_FIQ | I_BIT | F_BIT | |
;- Init the FIQ register | |
ldr r8, =AT91C_BASE_AIC | |
;- Set up Interrupt Mode and set IRQ Mode Stack | |
msr CPSR_c, #ARM_MODE_IRQ | I_BIT | F_BIT | |
mov r13, r0 ; Init stack IRQ | |
sub r0, r0, #IRQ_STACK_SIZE | |
;- Enable interrupt & Set up Supervisor Mode and set Supervisor Mode Stack | |
msr CPSR_c, #ARM_MODE_SVC | |
mov r13, r0 | |
;--------------------------------------------------------------- | |
; ?CSTARTUP | |
;--------------------------------------------------------------- | |
EXTERN __segment_init | |
EXTERN main | |
; Initialize segments. | |
; __segment_init is assumed to use | |
; instruction set and to be reachable by BL from the ICODE segment | |
; (it is safest to link them in segment ICODE). | |
ldr r0,=__segment_init | |
mov lr, pc | |
bx r0 | |
PUBLIC __main | |
?jump_to_main: | |
ldr lr,=?call_exit | |
ldr r0,=main | |
__main: | |
bx r0 | |
;------------------------------------------------------------------------------ | |
;- Loop for ever | |
;--------------- | |
;- End of application. Normally, never occur. | |
;- Could jump on Software Reset ( B 0x0 ). | |
;------------------------------------------------------------------------------ | |
?call_exit: | |
End | |
b End | |
;--------------------------------------------------------------- | |
; ?EXEPTION_VECTOR | |
; This module is only linked if needed for closing files. | |
;--------------------------------------------------------------- | |
PUBLIC AT91F_Default_FIQ_handler | |
PUBLIC AT91F_Default_IRQ_handler | |
PUBLIC AT91F_Spurious_handler | |
CODE32 ; 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 | |
ENDMOD | |
END | |