;------------------------------------------------------------------------------ ;- 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 ;- 1.2 04/Feb/05 JPP : Add Copy Flash vector to RAM and remap ;- 1.3 08/Feb/05 JPP : Remap ;- 1.4 01/Apr/05 JPP : save SPSR ;------------------------------------------------------------------------------ #include "AT91SAM7S256_inc.h" #define ARM_MODE_FIQ ( 0x11) // Core Mode #define ARM_MODE_IRQ ( 0x12) // Core Mode #define ARM_MODE_SVC ( 0x13) // Core Mode #define I_BIT ( 0x80) // Core Mode #define F_BIT ( 0x40) // Core Mode ;------------------------------------------------------------------------------ ;- Area Definition ;------------------------------------------------------------------------------ ;--------------------------------------------------------------- ; ?RESET ; Reset Vector. ; Normally, segment INTVEC is linked at address 0. ; For debugging purposes, INTVEC may be placed at other ; addresses. ;------------------------------------------------------------- PROGRAM ?RESET RSEG ICODE:CODE:ROOT(2) CODE32 ; Always ARM mode after reset ORG 0 PUBLIC reset EXTERN InitReset reset ;------------------------------------------------------------------------------ ;- Program RESET ;-------------------- ;- 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 swivec ; 0x08 Software Interrupt pabtvec: B pabtvec ; 0x0C Prefetch Abort dabtvec: B dabtvec ; 0x10 Data Abort rsvdvec: B rsvdvec ; 0x14 reserved irqvec: B IRQ_Handler_Entry ; 0x18 IRQ 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 ;------------------------------------------------------------------------------ ;- Manage exception ;--------------- ;- This module The exception must be ensure in ARM mode ;------------------------------------------------------------------------------ ;------------------------------------------------------------------------------ ;- 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 SPSR need to be saved for nested interrupt mrs r14, SPSR stmfd sp!, {r14} ;- Save and r0 in IRQ stack stmfd sp!, {r0} ;- 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, #ARM_MODE_SVC ;- 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 ;- 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 | ARM_MODE_IRQ ;- Mark the End of Interrupt on the AIC ldr r14, =AT91C_BASE_AIC str r14, [r14, #AIC_EOICR] ;- Restore R0 ldmia sp!, {r0} ;- Restore SPSR_irq and r0 from IRQ stack ldmia sp!, {r14} msr SPSR_cxsf, r14 ;- Restore adjusted LR_irq from IRQ stack directly in the PC ldmia sp!, {pc}^ ;--------------------------------------------------------------- ; ?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 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 ;------------------------------------------------------------------------------ ;- Program RESET_init ;-------------------- ;- This Program continous the initialization. ;------------------------------------------------------------------------------ PROGRAM ?RESET_init RSEG INTRAMEND_REMAP RSEG INTRAMSTART RSEG INTRAMEND_BEFORE_REMAP RSEG ICODE:CODE:ROOT(2) CODE32 ; Always ARM mode after reset PUBLIC InitReset EXTERN AT91F_LowLevelInit InitReset: ;------------------------------------------------------------------------------ ;- Low level Init (PMC, AIC, ? ....) by C function AT91F_LowLevelInit ;------------------------------------------------------------------------------ #define __iStack_end SFB(INTRAMEND_BEFORE_REMAP) ;- minumum C initialization ;- call AT91F_LowLevelInit( void) ; note this fonction can be write in Assembeler ldr r13,=__iStack_end ; temporary stack in internal RAM ;--Call Low level init function in ABSOLUTE through the Interworking ldr r0,=AT91F_LowLevelInit ldr r1,=0x0000FFFF and r0,r0,r1 mov lr, pc bx r0 ;--------------------------------------------------------------- ; ?CSTARTUP ;--------------------------------------------------------------- ; copy the flash code to RAM code this product use a very littel RAM ; and no need to get the code size #define __intram SFB(INTRAMSTART) ldr r12, = __intram ; get the relative address offset EXTERN reset add_pc: sub r11,pc,#((add_pc+8)-InitReset) #ifndef RAM_DEBUG add_pc_1: sub r10,pc,#((add_pc_1+4)-reset) ; copy the UndefVec at Software vec to protect a software reset ldr r1,[r10],#4 str r1,[r12],#4 #else add_pc_1: sub r10,pc,#((add_pc_1+8)-reset) ; copy the UndefVec at Software vec to protect a software reset ldr r1,[r10],#4 str r1,[r12],#4 ldr r1,[r10],#4 #endif str r1,[r12],#4 ; copy next address copy: ldr r1,[r10],#4 str r1,[r12],#4 cmp r10,r11 BNE copy ;------------------------------------------------------------------------------ ;- 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 (3*8*4) ; 3 words per interrupt priority level ;------------------------------------------------------------------------------ ;- Setup the stack for each mode ;------------------------------- #define __iramend SFB(INTRAMEND_REMAP) 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 ;-------------------------------------------- ;- Remap Command and jump on ABSOLUT address ;-------------------------------------------- ldr r12, PtInitRemap ; Get the real jump address ( after remap ) ldr r0,=AT91C_MC_RCR ; Get remap address mov r1,#1 ; Get the REMAP value #ifndef RAM_DEBUG str r1,[r0] #endif ;- Jump to LINK address at its absolut address mov pc, r12 ; Jump and break the pipeline PtInitRemap: DCD InitRemap ; Address where to jump after REMAP InitRemap: ;--------------------------------------------------------------- ; ?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 ENDMOD END