📄 2410init.s
字号:
;-----------------------------------------------------------------------------
;
; Cstartup file for MBA-2410
;
; This file contains the startup code used by the ICCARM C compiler.
;
; The modules in this file are included in the libraries, and may be replaced
; by any user-defined modules that define the PUBLIC symbols ?cstartup etc.
; If this entire file is assembled and linked with the provided
; libraries, the XLINK option -C must be used to avoid a clash with
; PROGRAM module ?RESET.
; EWARM also has a check box to "Ignore CSTARTUP in library", that has
; the same effect.
;
; All code in the modules (except ?RESET) will be placed in the ICODE segment,
; that must be reachable by a B instruction in ARM mode from segment INTVEC
; (within the first 32 Mbytes).
;
; Define preprocessor symbol __THUMB_LIBRARY__ for Thumb libraries
; or __ARM_LIBRARIES__ for ARM libraries.
;
; Based on cstartup.s79 1.34.
; $Revision: 1.2 $
; modified for MBA-2410 by Wooki of AIJISystem Co., Ltd.
;-----------------------------------------------------------------------------
#include "Option.inc"
#include "memcfg.inc"
#include "2410addr.inc"
; Make sure that __ARM_LIBRARY__ or __THUMB_LIBRARY__ is defined
#define __ARM_LIBRARY__ 1
#ifdef __ARM_LIBRARY__
#ifdef __THUMB_LIBRARY__
#error "Cannot have both __ARM_LIBRARY__ and __THUMB_LIBRARY__ set!"
#endif
#else
#ifndef __THUMB_LIBRARY__
#error "Must have one of __ARM_LIBRARY__ or __THUMB_LIBRARY__ set!"
#endif
#endif
;
; Naming covention of labels in this file:
;
; ?xxx - External labels only accessed from assembler.
; __xxx - External labels accessed from or defined in C.
; xxx - Labels local to one module (note: this file contains
; several modules).
; main - The starting point of the user program.
;
#if __LITTLE_ENDIAN__==1
; RTMODEL attribute __endian
#define ENDIAN_MODE "little"
#else
#define ENDIAN_MODE "big"
#endif
#ifdef __THUMB_LIBRARY__
; RTMODEL attribute __cpu_mode
#define CPU_MODE_NAME "thumb"
; Segment used for libraries
#define LIB_SEGMENT CODE
CPU_MODE MACRO
CODE16
ENDM
MOV_PC_LR MACRO
bx lr
ENDM
MOVEQ_PC_LR MACRO
bxeq lr
ENDM
#else /////// __ARM_LIBRARY__
; RTMODEL attribute __cpu_mode
#define CPU_MODE_NAME "arm"
; Segment used for libraries
#define LIB_SEGMENT CODE
CPU_MODE MACRO
CODE32
ENDM
MOV_PC_LR MACRO
mov pc,lr
ENDM
MOVEQ_PC_LR MACRO
moveq pc,lr
ENDM
#endif
//#define _ISR_STARTADDRESS ISR_AREA
#define _ISR_STARTADDRESS 0x33FFFF00
SEGMENT_ALIGN DEFINE 2 ; Align all segments to 2^2
BIT_SELFREFRESH DEFINE (1<<22)
USERMODE DEFINE 0x10
FIQMODE DEFINE 0x11
IRQMODE DEFINE 0x12
SVCMODE DEFINE 0x13
ABORTMODE DEFINE 0x17
UNDEFMODE DEFINE 0x1b
MODEMASK DEFINE 0x1f
NOINT DEFINE 0xc0
UserStack DEFINE (_STACK_BASEADDRESS-0x3800) ;0x30ff4800 ~
SVCStack DEFINE (_STACK_BASEADDRESS-0x2800) ;0x30ff5800 ~
UndefStack DEFINE (_STACK_BASEADDRESS-0x2400) ;0x30ff5c00 ~
AbortStack DEFINE (_STACK_BASEADDRESS-0x2000) ;0x30ff6000 ~
IRQStack DEFINE (_STACK_BASEADDRESS-0x1000) ;0x30ff7000 ~
FIQStack DEFINE (_STACK_BASEADDRESS-0x0) ;0x30ff8000 ~
;---------------------------------------------------------------
; ?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.
;---------------------------------------------------------------
RSEG DATA_ID:DATA(2)
RSEG DATA_I:DATA(2)
RSEG DATA_Z:DATA(2)
//EXTERN Main // The main entry of mon program
EXTERN ?main // The main entry of mon program
RSEG ICODE:CODE:NOROOT(2)
PUBLIC __program_start
LTORG
CODE32 ; Always ARM mode after reset
org 0
__program_start
B ?cstartup
B HandlerUndef
B HandlerSWI
B HandlerPabort
B HandlerDabort
B .
B HandlerIRQ
B HandlerFIQ
LTORG
;void EnterPWDN(int CLKCON);
EnterPWDN
mov r2,r0 ;r2=rCLKCON
tst r0,#0x8 ;POWER_OFF mode?
bne ENTER_POWER_OFF
ENTER_STOP
ldr r0,=REFRESH
ldr r3,[r0] ;r3=rREFRESH
mov r1, r3
orr r1, r1, #BIT_SELFREFRESH
str r1, [r0] ;Enable SDRAM self-refresh
mov r1,#16 ;wait until self-refresh is issued. may not be needed.
EX_XX0 subs r1,r1,#1
bne EX_XX0
ldr r0,=CLKCON ;enter STOP mode.
str r2,[r0]
mov r1,#32
EX_XX1 subs r1,r1,#1 ;1) wait until the STOP mode is in effect.
bne EX_XX0 ;2) Or wait here until the CPU&Peripherals will be turned-off
; Entering POWER_OFF mode, only the reset by wake-up is available.
ldr r0,=REFRESH ;exit from SDRAM self refresh mode.
str r3,[r0]
MOV_PC_LR
ENTER_POWER_OFF
;NOTE.
;1) rGSTATUS3 should have the return address after wake-up from POWER_OFF mode.
ldr r0,=REFRESH
ldr r1,[r0] ;r1=rREFRESH
orr r1, r1, #BIT_SELFREFRESH
str r1, [r0] ;Enable SDRAM self-refresh
mov r1,#16 ;Wait until self-refresh is issued,which may not be needed.
E_XX0 subs r1,r1,#1
bne E_XX0
ldr r1,=MISCCR
ldr r0,[r1]
orr r0,r0,#(7<<17) ;Make sure that SCLK0:SCLK->0, SCLK1:SCLK->0, SCKE=L during boot-up
str r0,[r1]
ldr r0,=CLKCON
str r2,[r0]
b . ;CPU will die here.
WAKEUP_POWER_OFF
;Release SCLKn after wake-up from the POWER_OFF mode.
ldr r1,=MISCCR
ldr r0,[r1]
bic r0,r0,#(7<<17) ;SCLK0:0->SCLK, SCLK1:0->SCLK, SCKE:L->H
str r0,[r1]
;Set memory control registers
ldr r0,=SMRDATA
ldr r1,=BWSCON ;BWSCON Address
add r2, r0, #52 ;End address of SMRDATA
W_XX0
ldr r3, [r0], #4
str r3, [r1], #4
cmp r2, r0
bne W_XX0
mov r1,#256
W_XX1 subs r1,r1,#1 ;1) wait until the SelfRefresh is released.
bne W_XX1
ldr r1,=GSTATUS3 ;GSTATUS3 has the start address just after POWER_OFF wake-up
ldr r0,[r1]
mov pc,r0
LTORG
?ex_hander:
HandlerIRQ:
sub sp,sp,#4 ;decrement sp(to store jump address)
stmfd sp!,{r0} ;PUSH the work register to stack(lr does't push because it return to original address)
ldr r0,=HandleIRQ ;load the address of HandleXXX to r0
ldr r0,[r0] ;load the contents(service routine start address) of HandleXXX
str r0,[sp,#4] ;store the contents(ISR) of HandleXXX to stack
ldmfd sp!,{r0,pc} ;POP the work register and pc(jump to ISR)
// ldmia sp!,{r0,pc} ;POP the work register and pc(jump to ISR)
HandlerUndef:
sub sp,sp,#4 ;decrement sp(to store jump address)
stmfd sp!,{r0} ;PUSH the work register to stack(lr does't push because it return to original address)
ldr r0,=HandleUndef ;load the address of HandleXXX to r0
ldr r0,[r0] ;load the contents(service routine start address) of HandleXXX
str r0,[sp,#4] ;store the contents(ISR) of HandleXXX to stack
ldmfd sp!,{r0,pc} ;POP the work register and pc(jump to ISR)
HandlerSWI:
sub sp,sp,#4 ;decrement sp(to store jump address)
stmfd sp!,{r0} ;PUSH the work register to stack(lr does't push because it return to original address)
ldr r0,=HandleSWI ;load the address of HandleXXX to r0
ldr r0,[r0] ;load the contents(service routine start address) of HandleXXX
str r0,[sp,#4] ;store the contents(ISR) of HandleXXX to stack
ldmfd sp!,{r0,pc} ;POP the work register and pc(jump to ISR)
HandlerDabort:
sub sp,sp,#4 ;decrement sp(to store jump address)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -