/* This is the default Startup for LPC21x devices for the GNU toolchain It has been designed by Raisonance. You can use it, modify it, distribute it freely but without any waranty. ****** (C) COPYRIGHT 2009 RAISONANCE ***** */ .extern main ;/* the following are useful for initializing the .data section */ .extern _sidata ;/* start address for the initialization values of the .data section. defined in linker script */ .extern _sdata ;/* start address for the .data section. defined in linker script */ .extern _edata ;/* end address for the .data section. defined in linker script */ ;/* the following are useful for initializing the .bss section */ .extern _sbss ;/* start address for the .bss section. defined in linker script */ .extern _ebss ;/* end address for the .bss section. defined in linker script */ /*; Standard definitions of Mode bits and Interrupt (I & F) flags in PSRs*/ ;/* Standard definitions of Mode bits and Interrupt (I & F) flags in PSRs */ .set Mode_USR, 0x10 ;/* User Mode */ .set Mode_FIQ, 0x11 ;/* FIQ Mode */ .set Mode_IRQ, 0x12 ;/* IRQ Mode */ .set Mode_SVC, 0x13 ;/* Supervisor Mode */ .set Mode_ABT, 0x17 ;/* Abort Mode */ .set Mode_UNDEF, 0x1B ;/* Undefined Mode */ .set Mode_SYS, 0x1F ;/* System Mode */ .equ I_Bit, 0x80 /*; when I bit is set, IRQ is disabled*/ .equ F_Bit, 0x40 /*; when F bit is set, FIQ is disabled*/ ;/* init value for the stack pointer. defined in linker script */ .extern _estack /*; --- System memory locations */ ;/* init value for the stack pointer. defined in linker script */ .extern _estack ;/* Stack Sizes. The default values are in the linker script, but they can be overriden. */ .extern _UND_Stack_Init .extern _SVC_Stack_Init .extern _ABT_Stack_Init .extern _FIQ_Stack_Init .extern _IRQ_Stack_Init .extern _USR_Stack_Init .extern _UND_Stack_Size .extern _SVC_Stack_Size .extern _ABT_Stack_Size .extern _FIQ_Stack_Size .extern _IRQ_Stack_Size .extern _USR_Stack_Size SVC_Stack = _SVC_Stack_Init /*_estack*/ /*; 256 byte SVC stack at*/ /*; top of memory */ IRQ_Stack = _IRQ_Stack_Init /*SVC_Stack - 256*/ /*; followed by IRQ stack */ USR_Stack = _USR_Stack_Init /*IRQ_Stack-1024*/ /*; followed by USR stack */ FIQ_Stack = _FIQ_Stack_Init /*USR_Stack-1024*/ /*; followed by FIQ stack*/ ABT_Stack = _ABT_Stack_Init /*FIQ_Stack-256*/ /*; followed by ABT stack */ UNDEF_Stack = _UND_Stack_Init /*ABT_Stack-256*/ /*; followed by UNDEF stack */ /*; --- LPC23xx specific definitions --- */ /*; System Control Block (SCB) Module Definitions*/ .equ SCB_BASE, 0xE01FC000 /*; SCB Base Address*/ .equ PLLCON_OFS, 0x80 /*; PLL Control Offset*/ .equ PLLCFG_OFS, 0x84 /*; PLL Configuration Offset*/ .equ PLLSTAT_OFS, 0x88 /*; PLL Status Offset*/ .equ PLLFEED_OFS, 0x8C /*; PLL Feed Offset*/ .equ CCLKCFG_OFS, 0x104 /*; CPU Clock Divider Reg Offset*/ .equ USBCLKCFG_OFS, 0x108 /*; USB Clock Divider Reg Offset*/ .equ CLKSRCSEL_OFS, 0x10C /*; Clock Source Sel Reg Offset*/ .equ SCS_OFS, 0x1A0 /*; Sys Control and Status Reg Offset*/ .equ PCLKSEL0_OFS, 0x1A8 /*; Periph Clock Sel Reg 0 Offset*/ .equ PCLKSEL1_OFS, 0x1AC /*; Periph Clock Sel Reg 0 Offset*/ /*; Constants*/ .equ OSCRANGE, (1<<4) /*; Oscillator Range Select*/ .equ OSCEN, (1<<5) /*; Main oscillator Enable*/ .equ OSCSTAT, (1<<6) /*; Main Oscillator Status*/ .equ PLLCON_PLLE, (1<<0) /*; PLL Enable*/ .equ PLLCON_PLLC, (1<<1) /*; PLL Connect*/ .equ PLLSTAT_M, (0x7FFF<<0) /*; PLL M Value*/ .equ PLLSTAT_N, (0xFF<<16) /*; PLL N Value*/ .equ PLLSTAT_PLOCK, (1<<26) /*; PLL Lock Status*/ /*; VPBDIV definitions*/ .equ VPBDIV, 0xE01FC100 /*; VPBDIV Address*/ .equ VPBDIV_SETUP, 0 .equ VPBDIV_Val, 0x00000000 .equ PLL_SETUP, 1 .equ CLOCK_SETUP, 1 .equ SCS_Val, 0x00000020 .equ CLKSRCSEL_Val, 0x00000001 .equ PLLCFG_Val, 0x00000007 .equ CCLKCFG_Val, 0x00000003 .equ USBCLKCFG_Val, 0x00000003 .equ PCLKSEL0_Val, 0x00000000 .equ PCLKSEL1_Val, 0x00000000 /*; Memory Accelerator Module (MAM) definitions*/ .equ MAM_BASE, 0xE01FC000 /*; MAM Base Address*/ .equ MAMCR_OFS, 0x00 /*; MAM Control Offset*/ .equ MAMTIM_OFS, 0x04 /*; MAM Timing Offset*/ .equ MAM_SETUP, 1 .equ MAMCR_Val, 0x00000002 .equ MAMTIM_Val, 0x00000004 /***************************************************************************************/ .globl _start .globl _startup /*.globl End_Handler*/ .section .flashtext,"ax",%progbits _startup: _start: Vectors: ldr PC, =Reset_Handler ldr PC, =UndefinedHandler ldr PC, =SWIHandler ldr PC, =PrefetchAbortHandler ldr PC, =DataAbortHandler nop /*; Reserved vector*/ ldr PC, =IRQHandler ldr PC, =FIQHandler /*; Reset Handler*/ .text Reset_Handler: nop nop nop nop nop nop /*; Setup Stacks */ MSR CPSR_c, #Mode_ABT|F_Bit|I_Bit LDR SP, =ABT_Stack MSR CPSR_c, #Mode_UNDEF|F_Bit|I_Bit LDR SP, =UNDEF_Stack MSR CPSR_c, #Mode_SVC|F_Bit|I_Bit LDR SP, =SVC_Stack MSR CPSR_c, #Mode_FIQ LDR SP, =FIQ_Stack MSR CPSR_c, #Mode_IRQ LDR SP, =IRQ_Stack MSR CPSR_c, #Mode_USR LDR SP, =USR_Stack /*MSR CPSR_c, #Mode_SYS*/ /* ; Change to System mode*/ /* ;copy the initial values for .data section from FLASH to RAM */ ldr R1, =_sidata ldr R2, =_sdata ldr R3, =_edata _reset_inidata_loop: cmp R2, R3 ldrlO R0, [R1], #4 strlO R0, [R2], #4 blO _reset_inidata_loop ;/* Clear the .bss section */ .if(1) ;/*this can be removed for speed as the C standard does not require it*/ mov r0,#0 ;/* get a zero */ ldr r1,=_sbss ;/* point to bss start */ ldr r2,=_ebss ;/* point to bss end */ _reset_inibss_loop: cmp r1,r2 ;/* check if some data remains to clear */ strlo r0,[r1],#4 ;/* clear 4 bytes */ blo _reset_inibss_loop ;/* loop until done */ .endif ;/*this can be removed for speed as the C standard does not require it*/ /*; --- Now enter the C code */ b main /*; Note : use B not BL, because an application will*/ /*; never return this way*/ /*; infinite loop after main returns, which should never happen */ loop_after_main: /*b Reset_Handler*/ /*;or maybe you prefer a reset?*/ b loop_after_main /***************************************************************************************/ /*;******************************************************************************* ;* Macro Name : SaveContext ;* Description : This macro used to save the context before entering ; an exception handler. ;* Input : The range of registers to store. ;* Output : none ;*******************************************************************************/ .macro Savecontext $r0,$r12 STMFD sp!,{r0-r12,lr} MRS r1,spsr STMFD sp!,{r1} .endm /*;******************************************************************************* ;* Macro Name : RestoreContext ;* Description : This macro used to restore the context to return from ; an exception handler and continue the program execution. ;* Input : The range of registers to restore. ;* Output : none ;*******************************************************************************/ .macro RestoreContext $r0,$r12 LDMFD sp!,{r1} /*; Restore the saved spsr_mode into r1.*/ MSR spsr_cxsf,r1 /*; Restore spsr_mode.*/ LDMFD sp!,{r0-r12,pc}^ /*; Return to the instruction following...*/ .endm /*; ...the exception interrupt.*/ /*;******************************************************************************* ;* Function Name : FIQHandler ;* Description : This function is called when FIQ ; exception is entered. ;* Input : none ;* Output : none ;******************************************************************************* */ FIQHandler: SUB lr,lr,#4 /*; Update the link register.*/ SaveContext r0,r7 /* ; Save the workspace plus the current*/ /*; return address lr_ fiq and spsr_fiq.*/ ldr PC,=FIQ_Handler /*; Branch to FIQ_Handler.*/ RestoreContext r0,r7 /*; Restore the context and return to the...*/ /*; ...program execution.*/ /*;******************************************************************************* ;* Function Name : UndefinedHandler ;* Description : This function called when undefined instruction ; exception is entered. ;* Input : none ;* Output : none ;*******************************************************************************/ UndefinedHandler: SaveContext r0,r12 /*; Save the workspace plus the current*/ ldr PC,=Undefined_Handler /*; Branch to Undefined_Handler.*/ RestoreContext r0,r12 /*; Return to the instruction following..*/ /*; ...the undefined instruction.*/ /*;******************************************************************************* ;* Function Name : SWIHandler ;* Description : This function called when SWI instruction executed. ;* Input : none ;* Output : none ;*******************************************************************************/ SWIHandler: SaveContext r0,r12 /*; Save the workspace plus the current*/ /*; return address lr_ svc and spsr_svc.*/ ldr PC,=SWI_Handler /*; Branch to SWI_Handler.*/ RestoreContext r0,r12 /*; Return to the instruction following...*/ /*; ...the SWI instruction.*/ /*;******************************************************************************* ;* Function Name : IRQHandler ;* Description : This function called when IRQ exception is entered. ;* Input : none ;* Output : none ;*******************************************************************************/ IRQHandler: SUB lr,lr,#4 /* ; Update the link register.*/ SaveContext r0,r12 /*; Save the workspace plus the current*/ /*; return address lr_abt and spsr_abt.*/ ldr PC,=IRQ_Handler /*; Branch to Prefetch_Handler. */ RestoreContext r0,r12 /*; Return to the instruction following that... */ /*; ...has generated the prefetch abort exception.*/ /*;******************************************************************************* ;* Function Name : PrefetchAbortHandler ;* Description : This function called when Prefetch Abort ; exception is entered. ;* Input : none ;* Output : none ;*******************************************************************************/ PrefetchAbortHandler: SUB lr,lr,#4 /* ; Update the link register.*/ SaveContext r0,r12 /*; Save the workspace plus the current*/ /*; return address lr_abt and spsr_abt.*/ ldr PC,=Prefetch_Handler /*; Branch to Prefetch_Handler. */ RestoreContext r0,r12 /*; Return to the instruction following that... */ /*; ...has generated the prefetch abort exception.*/ /*;******************************************************************************* ;* Function Name : DataAbortHandler ;* Description : This function is called when Data Abort ; exception is entered. ;* Input : none ;* Output : none ;********************************************************************************/ DataAbortHandler: SUB lr,lr,#8 /*; Update the link register.*/ SaveContext r0,r12 /*; Save the workspace plus the current*/ /*; return address lr_ abt and spsr_abt.*/ ldr PC,=Abort_Handler /*; Branch to Abort_Handler.*/ RestoreContext r0,r12 /*; Return to the instruction following that...*/ /*; ...has generated the data abort exception.*/ /* END OF FILE */ .END