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