;/*****************************************************************************/ | |
;/* STARTUP.S: Startup file for Philips LPC2000 */ | |
;/*****************************************************************************/ | |
;/* <<< Use Configuration Wizard in Context Menu >>> */ | |
;/*****************************************************************************/ | |
;/* This file is part of the uVision/ARM development tools. */ | |
;/* Copyright (c) 2005-2007 Keil Software. All rights reserved. */ | |
;/* This software may only be used under the terms of a valid, current, */ | |
;/* end user licence from KEIL for a compatible version of KEIL software */ | |
;/* development tools. Nothing else gives you the right to use this software. */ | |
;/*****************************************************************************/ | |
;/* | |
; * The STARTUP.S code is executed after CPU Reset. This file may be | |
; * translated with the following SET symbols. In uVision these SET | |
; * symbols are entered under Options - ASM - Define. | |
; * | |
; * REMAP: when set the startup code initializes the register MEMMAP | |
; * which overwrites the settings of the CPU configuration pins. The | |
; * startup and interrupt vectors are remapped from: | |
; * 0x00000000 default setting (not remapped) | |
; * 0x80000000 when EXTMEM_MODE is used | |
; * 0x40000000 when RAM_MODE is used | |
; * | |
; * EXTMEM_MODE: when set the device is configured for code execution | |
; * from external memory starting at address 0x80000000. | |
; * | |
; * RAM_MODE: when set the device is configured for code execution | |
; * from on-chip RAM starting at address 0x40000000. | |
; * | |
; * EXTERNAL_MODE: when set the PIN2SEL values are written that enable | |
; * the external BUS at startup. | |
; */ | |
; Standard definitions of Mode bits and Interrupt (I & F) flags in PSRs | |
Mode_USR EQU 0x10 | |
Mode_FIQ EQU 0x11 | |
Mode_IRQ EQU 0x12 | |
Mode_SVC EQU 0x13 | |
Mode_ABT EQU 0x17 | |
Mode_UND EQU 0x1B | |
Mode_SYS EQU 0x1F | |
I_Bit EQU 0x80 ; when I bit is set, IRQ is disabled | |
F_Bit EQU 0x40 ; when F bit is set, FIQ is disabled | |
;// <h> Stack Configuration (Stack Sizes in Bytes) | |
;// <o0> Undefined Mode <0x0-0xFFFFFFFF:8> | |
;// <o1> Supervisor Mode <0x0-0xFFFFFFFF:8> | |
;// <o2> Abort Mode <0x0-0xFFFFFFFF:8> | |
;// <o3> Fast Interrupt Mode <0x0-0xFFFFFFFF:8> | |
;// <o4> Interrupt Mode <0x0-0xFFFFFFFF:8> | |
;// <o5> User/System Mode <0x0-0xFFFFFFFF:8> | |
;// </h> | |
UND_Stack_Size EQU 0x00000008 | |
SVC_Stack_Size EQU 0x00000300 | |
ABT_Stack_Size EQU 0x00000008 | |
FIQ_Stack_Size EQU 0x00000008 | |
IRQ_Stack_Size EQU 0x00000300 | |
USR_Stack_Size EQU 0x00000008 | |
Stack_Size EQU (UND_Stack_Size + SVC_Stack_Size + ABT_Stack_Size + \ | |
FIQ_Stack_Size + IRQ_Stack_Size + USR_Stack_Size ) | |
AREA STACK, NOINIT, READWRITE, ALIGN=3 | |
Stack_Mem SPACE Stack_Size | |
;__initial_sp SPACE ISR_Stack_Size | |
Stack_Top EQU Stack_Mem + Stack_Size | |
;// <h> Heap Configuration | |
;// <o> Heap Size (in Bytes) <0x0-0xFFFFFFFF> | |
;// </h> | |
Heap_Size EQU 0x00000000 | |
AREA HEAP, NOINIT, READWRITE, ALIGN=3 | |
__heap_base | |
Heap_Mem SPACE Heap_Size | |
__heap_limit | |
; VPBDIV definitions | |
VPBDIV EQU 0xE01FC100 ; VPBDIV Address | |
;// <e> VPBDIV Setup | |
;// <i> Peripheral Bus Clock Rate | |
;// <o1.0..1> VPBDIV: VPB Clock | |
;// <0=> VPB Clock = CPU Clock / 4 | |
;// <1=> VPB Clock = CPU Clock | |
;// <2=> VPB Clock = CPU Clock / 2 | |
;// <o1.4..5> XCLKDIV: XCLK Pin | |
;// <0=> XCLK Pin = CPU Clock / 4 | |
;// <1=> XCLK Pin = CPU Clock | |
;// <2=> XCLK Pin = CPU Clock / 2 | |
;// </e> | |
VPBDIV_SETUP EQU 0 | |
VPBDIV_Val EQU 0x00000000 | |
; Phase Locked Loop (PLL) definitions | |
PLL_BASE EQU 0xE01FC080 ; PLL Base Address | |
PLLCON_OFS EQU 0x00 ; PLL Control Offset | |
PLLCFG_OFS EQU 0x04 ; PLL Configuration Offset | |
PLLSTAT_OFS EQU 0x08 ; PLL Status Offset | |
PLLFEED_OFS EQU 0x0C ; PLL Feed Offset | |
PLLCON_PLLE EQU (1<<0) ; PLL Enable | |
PLLCON_PLLC EQU (1<<1) ; PLL Connect | |
PLLCFG_MSEL EQU (0x1F<<0) ; PLL Multiplier | |
PLLCFG_PSEL EQU (0x03<<5) ; PLL Divider | |
PLLSTAT_PLOCK EQU (1<<10) ; PLL Lock Status | |
;// <e> PLL Setup | |
;// <o1.0..4> MSEL: PLL Multiplier Selection | |
;// <1-32><#-1> | |
;// <i> M Value | |
;// <o1.5..6> PSEL: PLL Divider Selection | |
;// <0=> 1 <1=> 2 <2=> 4 <3=> 8 | |
;// <i> P Value | |
;// </e> | |
PLL_SETUP EQU 1 | |
PLLCFG_Val EQU 0x00000024 | |
; Memory Accelerator Module (MAM) definitions | |
MAM_BASE EQU 0xE01FC000 ; MAM Base Address | |
MAMCR_OFS EQU 0x00 ; MAM Control Offset | |
MAMTIM_OFS EQU 0x04 ; MAM Timing Offset | |
;// <e> MAM Setup | |
;// <o1.0..1> MAM Control | |
;// <0=> Disabled | |
;// <1=> Partially Enabled | |
;// <2=> Fully Enabled | |
;// <i> Mode | |
;// <o2.0..2> MAM Timing | |
;// <0=> Reserved <1=> 1 <2=> 2 <3=> 3 | |
;// <4=> 4 <5=> 5 <6=> 6 <7=> 7 | |
;// <i> Fetch Cycles | |
;// </e> | |
MAM_SETUP EQU 1 | |
MAMCR_Val EQU 0x00000002 | |
MAMTIM_Val EQU 0x00000004 | |
; External Memory Controller (EMC) definitions | |
EMC_BASE EQU 0xFFE00000 ; EMC Base Address | |
BCFG0_OFS EQU 0x00 ; BCFG0 Offset | |
BCFG1_OFS EQU 0x04 ; BCFG1 Offset | |
BCFG2_OFS EQU 0x08 ; BCFG2 Offset | |
BCFG3_OFS EQU 0x0C ; BCFG3 Offset | |
;// <e> External Memory Controller (EMC) | |
EMC_SETUP EQU 0 | |
;// <e> Bank Configuration 0 (BCFG0) | |
;// <o1.0..3> IDCY: Idle Cycles <0-15> | |
;// <o1.5..9> WST1: Wait States 1 <0-31> | |
;// <o1.11..15> WST2: Wait States 2 <0-31> | |
;// <o1.10> RBLE: Read Byte Lane Enable | |
;// <o1.26> WP: Write Protect | |
;// <o1.27> BM: Burst ROM | |
;// <o1.28..29> MW: Memory Width <0=> 8-bit <1=> 16-bit | |
;// <2=> 32-bit <3=> Reserved | |
;// </e> | |
BCFG0_SETUP EQU 0 | |
BCFG0_Val EQU 0x0000FBEF | |
;// <e> Bank Configuration 1 (BCFG1) | |
;// <o1.0..3> IDCY: Idle Cycles <0-15> | |
;// <o1.5..9> WST1: Wait States 1 <0-31> | |
;// <o1.11..15> WST2: Wait States 2 <0-31> | |
;// <o1.10> RBLE: Read Byte Lane Enable | |
;// <o1.26> WP: Write Protect | |
;// <o1.27> BM: Burst ROM | |
;// <o1.28..29> MW: Memory Width <0=> 8-bit <1=> 16-bit | |
;// <2=> 32-bit <3=> Reserved | |
;// </e> | |
BCFG1_SETUP EQU 0 | |
BCFG1_Val EQU 0x0000FBEF | |
;// <e> Bank Configuration 2 (BCFG2) | |
;// <o1.0..3> IDCY: Idle Cycles <0-15> | |
;// <o1.5..9> WST1: Wait States 1 <0-31> | |
;// <o1.11..15> WST2: Wait States 2 <0-31> | |
;// <o1.10> RBLE: Read Byte Lane Enable | |
;// <o1.26> WP: Write Protect | |
;// <o1.27> BM: Burst ROM | |
;// <o1.28..29> MW: Memory Width <0=> 8-bit <1=> 16-bit | |
;// <2=> 32-bit <3=> Reserved | |
;// </e> | |
BCFG2_SETUP EQU 0 | |
BCFG2_Val EQU 0x0000FBEF | |
;// <e> Bank Configuration 3 (BCFG3) | |
;// <o1.0..3> IDCY: Idle Cycles <0-15> | |
;// <o1.5..9> WST1: Wait States 1 <0-31> | |
;// <o1.11..15> WST2: Wait States 2 <0-31> | |
;// <o1.10> RBLE: Read Byte Lane Enable | |
;// <o1.26> WP: Write Protect | |
;// <o1.27> BM: Burst ROM | |
;// <o1.28..29> MW: Memory Width <0=> 8-bit <1=> 16-bit | |
;// <2=> 32-bit <3=> Reserved | |
;// </e> | |
BCFG3_SETUP EQU 0 | |
BCFG3_Val EQU 0x0000FBEF | |
;// </e> End of EMC | |
; External Memory Pins definitions | |
PINSEL2 EQU 0xE002C014 ; PINSEL2 Address | |
PINSEL2_Val EQU 0x0E6149E4 ; CS0..3, OE, WE, BLS0..3, | |
; D0..31, A2..23, JTAG Pins | |
PRESERVE8 | |
; Area Definition and Entry Point | |
; Startup Code must be linked first at Address at which it expects to run. | |
AREA RESET, CODE, READONLY | |
ARM | |
; Exception Vectors | |
; Mapped to Address 0. | |
; Absolute addressing mode must be used. | |
; Dummy Handlers are implemented as infinite loops which can be modified. | |
IMPORT vPortYieldProcessor | |
Vectors LDR PC, Reset_Addr | |
LDR PC, Undef_Addr | |
LDR PC, SWI_Addr | |
LDR PC, PAbt_Addr | |
LDR PC, DAbt_Addr | |
NOP ; Reserved Vector | |
; LDR PC, IRQ_Addr | |
LDR PC, [PC, #-0x0FF0] ; Vector from VicVectAddr | |
LDR PC, FIQ_Addr | |
Reset_Addr DCD Reset_Handler | |
Undef_Addr DCD Undef_Handler | |
SWI_Addr DCD vPortYieldProcessor | |
PAbt_Addr DCD PAbt_Handler | |
DAbt_Addr DCD DAbt_Handler | |
DCD 0 ; Reserved Address | |
IRQ_Addr DCD IRQ_Handler | |
FIQ_Addr DCD FIQ_Handler | |
Undef_Handler B Undef_Handler | |
SWI_Handler B SWI_Handler | |
PAbt_Handler B PAbt_Handler | |
DAbt_Handler B DAbt_Handler | |
IRQ_Handler B IRQ_Handler | |
FIQ_Handler B FIQ_Handler | |
; Reset Handler | |
EXPORT Reset_Handler | |
Reset_Handler | |
; Setup External Memory Pins | |
IF :DEF:EXTERNAL_MODE | |
LDR R0, =PINSEL2 | |
LDR R1, =PINSEL2_Val | |
STR R1, [R0] | |
ENDIF | |
; Setup External Memory Controller | |
IF EMC_SETUP <> 0 | |
LDR R0, =EMC_BASE | |
IF BCFG0_SETUP <> 0 | |
LDR R1, =BCFG0_Val | |
STR R1, [R0, #BCFG0_OFS] | |
ENDIF | |
IF BCFG1_SETUP <> 0 | |
LDR R1, =BCFG1_Val | |
STR R1, [R0, #BCFG1_OFS] | |
ENDIF | |
IF BCFG2_SETUP <> 0 | |
LDR R1, =BCFG2_Val | |
STR R1, [R0, #BCFG2_OFS] | |
ENDIF | |
IF BCFG3_SETUP <> 0 | |
LDR R1, =BCFG3_Val | |
STR R1, [R0, #BCFG3_OFS] | |
ENDIF | |
ENDIF ; EMC_SETUP | |
; Setup VPBDIV | |
IF VPBDIV_SETUP <> 0 | |
LDR R0, =VPBDIV | |
LDR R1, =VPBDIV_Val | |
STR R1, [R0] | |
ENDIF | |
; Setup PLL | |
IF PLL_SETUP <> 0 | |
LDR R0, =PLL_BASE | |
MOV R1, #0xAA | |
MOV R2, #0x55 | |
; Configure and Enable PLL | |
MOV R3, #PLLCFG_Val | |
STR R3, [R0, #PLLCFG_OFS] | |
MOV R3, #PLLCON_PLLE | |
STR R3, [R0, #PLLCON_OFS] | |
STR R1, [R0, #PLLFEED_OFS] | |
STR R2, [R0, #PLLFEED_OFS] | |
; Wait until PLL Locked | |
PLL_Loop LDR R3, [R0, #PLLSTAT_OFS] | |
ANDS R3, R3, #PLLSTAT_PLOCK | |
BEQ PLL_Loop | |
; Switch to PLL Clock | |
MOV R3, #(PLLCON_PLLE:OR:PLLCON_PLLC) | |
STR R3, [R0, #PLLCON_OFS] | |
STR R1, [R0, #PLLFEED_OFS] | |
STR R2, [R0, #PLLFEED_OFS] | |
ENDIF ; PLL_SETUP | |
; Setup MAM | |
IF MAM_SETUP <> 0 | |
LDR R0, =MAM_BASE | |
MOV R1, #MAMTIM_Val | |
STR R1, [R0, #MAMTIM_OFS] | |
MOV R1, #MAMCR_Val | |
STR R1, [R0, #MAMCR_OFS] | |
ENDIF ; MAM_SETUP | |
; Memory Mapping (when Interrupt Vectors are in RAM) | |
MEMMAP EQU 0xE01FC040 ; Memory Mapping Control | |
IF :DEF:REMAP | |
LDR R0, =MEMMAP | |
IF :DEF:EXTMEM_MODE | |
MOV R1, #3 | |
ELIF :DEF:RAM_MODE | |
MOV R1, #2 | |
ELSE | |
MOV R1, #1 | |
ENDIF | |
STR R1, [R0] | |
ENDIF | |
; Initialise Interrupt System | |
; ... | |
; Setup Stack for each mode | |
LDR R0, =Stack_Top | |
; Enter Undefined Instruction Mode and set its Stack Pointer | |
MSR CPSR_c, #Mode_UND:OR:I_Bit:OR:F_Bit | |
MOV SP, R0 | |
SUB R0, R0, #UND_Stack_Size | |
; Enter Abort Mode and set its Stack Pointer | |
MSR CPSR_c, #Mode_ABT:OR:I_Bit:OR:F_Bit | |
MOV SP, R0 | |
SUB R0, R0, #ABT_Stack_Size | |
; Enter FIQ Mode and set its Stack Pointer | |
MSR CPSR_c, #Mode_FIQ:OR:I_Bit:OR:F_Bit | |
MOV SP, R0 | |
SUB R0, R0, #FIQ_Stack_Size | |
; Enter IRQ Mode and set its Stack Pointer | |
MSR CPSR_c, #Mode_IRQ:OR:I_Bit:OR:F_Bit | |
MOV SP, R0 | |
SUB R0, R0, #IRQ_Stack_Size | |
; Enter Supervisor Mode and set its Stack Pointer | |
MSR CPSR_c, #Mode_SVC:OR:I_Bit:OR:F_Bit | |
MOV SP, R0 | |
SUB R0, R0, #SVC_Stack_Size | |
; Enter the C code | |
IMPORT __main | |
LDR R0, =__main | |
BX R0 | |
IF :DEF:__MICROLIB | |
EXPORT __heap_base | |
EXPORT __heap_limit | |
ELSE | |
; User Initial Stack & Heap | |
AREA |.text|, CODE, READONLY | |
IMPORT __use_two_region_memory | |
EXPORT __user_initial_stackheap | |
__user_initial_stackheap | |
LDR R0, = Heap_Mem | |
LDR R1, = (Stack_Mem + IRQ_Stack_Size + USR_Stack_Size) | |
LDR R2, = (Heap_Mem + Heap_Size) | |
LDR R3, = Stack_Mem | |
BX LR | |
ENDIF | |
END |