Option.inc
;===========================================
; NAME: OPTION.A
; DESC: Configuration options for .S files
; HISTORY:
; 02.28.2002: ver 0.0
; 03.11.2003: ver 0.0 attached for 2440.
; jan E, 2004: ver0.03 modified for 2440A01.
;===========================================
;Start address of each stacks,
_STACK_BASEADDRESS EQU 0x33ff8000 ;堆栈起始地址
_MMUTT_STARTADDRESS EQU 0x33ff8000 ;内存管理起始地址
_ISR_STARTADDRESS EQU 0x33ffff00 ;中断起始地址
;GBLL定义全局逻辑变量
GBLL PLL_ON_START
;给逻辑变量赋值
PLL_ON_START SETL {TRUE}
GBLL ENDIAN_CHANGE
ENDIAN_CHANGE SETL {FALSE}
;定义全局数字变量
GBLA ENTRY_BUS_WIDTH
ENTRY_BUS_WIDTH SETA 16
;BUSWIDTH = 16,32
GBLA BUSWIDTH ;max. bus width for the GPIO configuration
BUSWIDTH SETA 32 ;设置总线宽度
GBLA UCLK
UCLK SETA 48000000
GBLA XTAL_SEL ;声明全局数字变量
GBLA FCLK
GBLA CPU_SEL
;(1) Select CPU
;CPU_SEL SETA 32440000 ; 32440000:2440X.
CPU_SEL SETA 32440001 ; 32440001:2440A
;(2) Select XTaL
XTAL_SEL SETA 12000000
;(3) Select FCLK
FCLK SETA 304000000
FCLK SETA 400000000
;(4) Select Clock Division (Fclk:Hclk:Pclk)
;FCLK = 100000000
;CLKDIV_VAL EQU 1 ; 0=1:1:1, 1=1:1:2, 2=1:2:2, 3=1:2:4, 4=1:4:4, 5=1:4:8, 6=1:3:3, 7=1:3:6.
;FCLK = 200000000
;CLKDIV_VAL EQU 3 ; 0=1:1:1, 1=1:1:2, 2=1:2:2, 3=1:2:4, 4=1:4:4, 5=1:4:8, 6=1:3:3, 7=1:3:6.
;FCLK = 400000000
CLKDIV_VAL EQU 5 ; 0=1:1:1, 1=1:1:2, 2=1:2:2, 3=1:2:4, 4=1:4:4, 5=1:4:8, 6=1:3:3, 7=1:3:6.
;FCLK = 304000000 or 271500000
;CLKDIV_VAL EQU 7 ; 0=1:1:1, 1=1:1:2, 2=1:2:2, 3=1:2:4, 4=1:4:4, 5=1:4:8, 6=1:3:3, 7=1:3:6.
;以下是设置时钟的一些选项
[ XTAL_SEL = 12000000
[ FCLK = 271500000 ;"[ 表示 if"
M_MDIV EQU 173 ;Fin=12.0MHz Fout=271.5MHz
M_PDIV EQU 2
[ CPU_SEL = 32440001 ; "] 表示endif"
M_SDIV EQU 2 ; 2440A
| ; "|表示 else"
M_SDIV EQU 1 ; 2440X
]
]
[ FCLK = 304000000
M_MDIV EQU 68 ;Fin=12.0MHz Fout=304.8MHz
M_PDIV EQU 1
[ CPU_SEL = 32440001
M_SDIV EQU 1 ; 2440A
|
M_SDIV EQU 0 ; 2440X
]
]
[ FCLK = 100000000
M_MDIV EQU 42 ;Fin=12.0MHz Fout=100MHz
M_PDIV EQU 4
[ CPU_SEL = 32440001
M_SDIV EQU 1 ; 2440A
|
M_SDIV EQU 0 ; 2440X
]
]
[ FCLK = 200000000
M_MDIV EQU 92 ;Fin=12.0MHz Fout=200MHz
M_PDIV EQU 4
[ CPU_SEL = 32440001
M_SDIV EQU 1 ; 2440A
|
M_SDIV EQU 0 ; 2440X
]
]
[ FCLK = 400000000
M_MDIV EQU 92 ;Fin=12.0MHz Fout=400MHz
M_PDIV EQU 1
[ CPU_SEL = 32440001
M_SDIV EQU 1 ; 2440A
|
M_SDIV EQU 0 ; 2440X
]
]
[ UCLK = 48000000
U_MDIV EQU 56 ;Fin=12.0MHz Fout=48MHz
U_PDIV EQU 2
[ CPU_SEL = 32440001
U_SDIV EQU 2 ; 2440A
|
U_SDIV EQU 1 ; 2440X
]
]
[ UCLK = 96000000
U_MDIV EQU 56 ;Fin=12.0MHz Fout=96MHz
U_PDIV EQU 2
[ CPU_SEL = 32440001
U_SDIV EQU 1 ; 2440A
|
U_SDIV EQU 0 ; 2440X
]
]
| ; else if XTAL_SEL = 16.9344Mhz
[ FCLK = 266716800
M_MDIV EQU 118 ;Fin=16.9344MHz
M_PDIV EQU 2
[ CPU_SEL = 32440001
M_SDIV EQU 2 ; 2440A
|
M_SDIV EQU 1 ; 2440X
]
]
[ FCLK = 296352000
M_MDIV EQU 97 ;Fin=16.9344MHz
M_PDIV EQU 1
[ CPU_SEL = 32440001
M_SDIV EQU 2 ; 2440A
|
M_SDIV EQU 1 ; 2440X
]
]
[ FCLK = 541900800
M_MDIV EQU 120 ;Fin=16.9344MHz
M_PDIV EQU 2
[ CPU_SEL = 32440001
M_SDIV EQU 1 ; 2440A
|
M_SDIV EQU 0 ; 2440X
]
]
[ UCLK = 48000000
U_MDIV EQU 60 ;Fin=16.9344MHz Fout=48MHz
U_PDIV EQU 4
[ CPU_SEL = 32440001
U_SDIV EQU 2 ; 2440A
|
U_SDIV EQU 1 ; 2440X
]
]
[ UCLK = 96000000
U_MDIV EQU 60 ;Fin=16.9344MHz Fout=96MHz
U_PDIV EQU 4
[ CPU_SEL = 32440001
U_SDIV EQU 1 ; 2440A
|
U_SDIV EQU 0 ; 2440X
]
]
] ; end of if XTAL_SEL = 12000000.
END
其代码主要是定义一些系统时钟初始化的参数,类似c语言的宏一样,一边在设置寄存器的时候方便,其中用的汇编语法有:
EQU 类似c语言中的define
[ 类似c语言中的 “if” ,"]" 表示if语句的结束 ---"endif", “|” 表示else的意思;
GBLA 定义全局数字变量
GBLL定义全局逻辑变量
GBLS定义全局字符变量
汇编结束的时候有一个END,表示汇编文件结束。
对于option.inc里面的堆栈地址这些到底是依据哪里来设定了?
2440addr.inc
其中只是定义了寄存器的对应地址,没有什么好说的。
2440init.s
;=========================================
; NAME: 2440INIT.S
; DESC: C start up codes
; Configure memory, ISR ,stacks
; Initialize C-variables
; HISTORY:
; 2002.02.25:kwtark: ver 0.0
; 2002.03.20:purnnamu: Add some functions for testing STOP,Sleep mode
; 2003.03.14:DonGo: Modified for 2440.
;=========================================
GET Option.inc ;相当于"c语言中的include",其中的option.inc里面都是预定义好了的类似c语言中的宏,以便后面的芯片初始化做好准备。
GET Memcfg.inc ;其内部定义了内存初始化的一些参数
GET 2440addr.inc;其定义了系统管理的各个寄存器的地址
BIT_SELFREFRESH EQU (1<<22)
;工作模式定义
;Pre-defined constants
USERMODE EQU 0x10
FIQMODE EQU 0x11
IRQMODE EQU 0x12
SVCMODE EQU 0x13
ABORTMODE EQU 0x17
UNDEFMODE EQU 0x1b
MODEMASK EQU 0x1f
NOINT EQU 0xc0
;堆栈的起始位置
;The location of stacks
UserStack EQU (_STACK_BASEADDRESS-0x3800) ;0x33ff4800 ~
SVCStack EQU (_STACK_BASEADDRESS-0x2800) ;0x33ff5800 ~
UndefStack EQU (_STACK_BASEADDRESS-0x2400) ;0x33ff5c00 ~
AbortStack EQU (_STACK_BASEADDRESS-0x2000) ;0x33ff6000 ~
IRQStack EQU (_STACK_BASEADDRESS-0x1000) ;0x33ff7000 ~
FIQStack EQU (_STACK_BASEADDRESS-0x0) ;0x33ff8000 ~
;Check if tasm.exe(armasm -16 ...@ADS 1.0) is used.
;
GBLL THUMBCODE ;声明全局逻辑变量
[ {CONFIG} = 16 ;if
THUMBCODE SETL {TRUE};
CODE32
| ;else
THUMBCODE SETL {FALSE}
]
MACRO
MOV_PC_LR
[ THUMBCODE
bx lr
|
mov pc,lr
]
MEND
MACRO
MOVEQ_PC_LR
[ THUMBCODE
bxeq lr
|
moveq pc,lr
]
MEND
MACRO
$HandlerLabel HANDLER $HandleLabel
;$表示变量
$HandlerLabel
sub sp,sp,#4 ;decrement sp(to store jump address)
stmfd sp!,{r0} ;PUSH the work register to stack(lr does not push because it return to original address)
ldr r0,=$HandleLabel;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)
MEND
;stmfd 堆栈满递减,LDM/STM 的主要用途是把需要保存的寄存器复制到栈上
;‘xx’是 LD 表示装载,或 ST 表示存储。
;-----------------------------------------------
; |---------|
; |---------|
; |---------|
; | r0 |
; |HandleLab|
; |[Hand..] |
; pc = isr
;-----------------------------------------------
IMPORT Main ; The main entry of mon program
AREA Init,CODE,READONLY
ENTRY
EXPORT __ENTRY
__ENTRY
ResetEntry
;1)The code, which converts to Big-endian, should be in little endian code.
;2)The following little endian code will be compiled in Big-Endian mode.
; The code byte order should be changed as the memory bus width.
;3)The pseudo instruction,DCD can not be used here because the linker generates error.
; DCB 预备一个字节(8 位值)
; DCW 预备一个半字(16 位值)
; DCD 预备一个字(32 位值)
; DCS 按给出的字符串的要求预备直到 255 个的字符
ASSERT :DEF:ENDIAN_CHANGE
[ ENDIAN_CHANGE
ASSERT :DEF:ENTRY_BUS_WIDTH
[ ENTRY_BUS_WIDTH=16
andeq r14,r7,r0,lsl #20 ;DCD 0x0007ea00
]
[ ENTRY_BUS_WIDTH=8
streq r0,[r0,-r10,ror #1] ;DCD 0x070000ea
]
|
b ResetHandler
]
b HandlerUndef ;handler for Undefined mode
b HandlerSWI ;handler for SWI interrupt
b HandlerPabort ;handler for PAbort
b HandlerDabort ;handler for DAbort
b . ;reserved
b HandlerIRQ ;handler for IRQ interrupt
b HandlerFIQ ;handler for FIQ interrupt
;@0x20
; b EnterPWDN ; Must be @0x20.
;宏调用
HandlerFIQ HANDLER HandleFIQ
HandlerIRQ HANDLER HandleIRQ
HandlerUndef HANDLER HandleUndef
HandlerSWI HANDLER HandleSWI
HandlerDabort HANDLER HandleDabort
HandlerPabort HANDLER HandlePabort
;不是
用中断向量表,软件方式
IsrIRQ
sub sp,sp,#4 ;reserved for PC
stmfd sp!,{r8-r9}
ldr r9,=INTOFFSET
ldr r9,[r9]
ldr r8,=HandleEINT0
add r8,r8,r9,lsl #2
ldr r8,[r8]
str r8,[sp,#8]
ldmfd sp!,{r8-r9,pc}
;定义池
LTORG
;=======
; ENTRY
;=======
ResetHandler
;关闭看门狗
ldr r0,=WTCON ;watch dog disable
ldr r1,=0x0
str r1,[r0]
;屏蔽所有中断
ldr r0,=INTMSK
ldr r1,=0xffffffff ;all interrupt disable
str r1,[r0]
;屏蔽所有子中断
ldr r0,=INTSUBMSK
ldr r1,=0x7fff ;all sub interrupt disable
str r1,[r0]
;
;To reduce PLL lock time, adjust the LOCKTIME register.
ldr r0,=LOCKTIME
ldr r1,=0xffffff
str r1,[r0]
[ PLL_ON_START
; Added for confirm clock divide. for 2440.
; Setting value Fclk:Hclk:Pclk
ldr r0,=CLKDIVN
ldr r1,=CLKDIV_VAL ; 0=1:1:1, 1=1:1:2, 2=1:2:2, 3=1:2:4, 4=1:4:4, 5=1:4:8, 6=1:3:3, 7=1:3:6.
str r1,[r0]
;program has not been copied, so use these directly,
[ CLKDIV_VAL>1 ; means Fclk:Hclk is not 1:1.
mrc p15,0,r0,c1,c0,0
orr r0,r0,#0xc0000000;R1_nF:OR:R1_iA
mcr p15,0,r0,c1,c0,0
|
mrc p15,0,r0,c1,c0,0
bic r0,r0,#0xc0000000;R1_iA:OR:R1_nF
mcr p15,0,r0,c1,c0,0
]
;Configure UPLL
ldr r0,=UPLLCON
ldr r1,=((U_MDIV<<12)+(U_PDIV<<4)+U_SDIV)
str r1,[r0]
nop ; Caution: After UPLL setting, at least 7-clocks delay must be inserted for setting hardware be completed.
nop
nop
nop
nop
nop
nop
;Configure MPLL
ldr r0,=MPLLCON
ldr r1,=((M_MDIV<<12)+(M_PDIV<<4)+M_SDIV) ;Fin=16.9344MHz
str r1,[r0]
]
;Check if the boot is caused by the wake-up from SLEEP mode.
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;; When EINT0 is pressed, Clear SDRAM
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; check if EIN0 button is pressed
1 bl InitStacks
;===========================================================
; Setup IRQ handler
ldr r0,=HandleIRQ ;This routine is needed
ldr r1,=IsrIRQ ;if there is not 'subs pc,lr,#4' at 0x18, 0x1c
str r1,[r0]
[ :LNOT:THUMBCODE
bl Main ;Do not use main() because ......
b .
]
[ THUMBCODE ;for start-up code for Thumb mode
orr lr,pc,#1
bx lr
CODE16
bl Main ;Do not use main() because ......
b .
CODE32
]
;function initializing stacks
InitStacks
;Do not use DRAM,such as stmfd,ldmfd......
;SVCstack is initialized before
;Under toolkit ver 2.5, 'msr cpsr,r1' can be used instead of 'msr cpsr_cxsf,r1'
mrs r0,cpsr
bic r0,r0,#MODEMASK
orr r1,r0,#UNDEFMODE|NOINT
msr cpsr_cxsf,r1 ;UndefMode
ldr sp,=UndefStack ; UndefStack=0x33FF_5C00
orr r1,r0,#ABORTMODE|NOINT
msr cpsr_cxsf,r1 ;AbortMode
ldr sp,=AbortStack ; AbortStack=0x33FF_6000
orr r1,r0,#IRQMODE|NOINT
msr cpsr_cxsf,r1 ;IRQMode
ldr sp,=IRQStack ; IRQStack=0x33FF_7000
orr r1,r0,#FIQMODE|NOINT
msr cpsr_cxsf,r1 ;FIQMode
ldr sp,=FIQStack ; FIQStack=0x33FF_8000
bic r0,r0,#MODEMASK|NOINT
orr r1,r0,#SVCMODE
msr cpsr_cxsf,r1 ;SVCMode
ldr sp,=SVCStack ; SVCStack=0x33FF_5800
;USER mode has not be initialized.
mov pc,lr
;The LR register will not be valid if the current mode is not SVC mode.
;===========================================================
;=====================================================================
; Clock division test
; Assemble code, because VSYNC time is very short
;=====================================================================
;创建数据段
;异常中断向量
ALIGN
AREA RamData, DATA, READWRITE
;起始地址
^ _ISR_STARTADDRESS ; _ISR_STARTADDRESS=0x33FF_FF00
HandleReset # 4;定义了一个空间站4个字节。
HandleUndef # 4
HandleSWI # 4
HandlePabort # 4
HandleDabort # 4
HandleReserved # 4
HandleIRQ # 4
HandleFIQ # 4
;Do not use the label 'IntVectorTable',
;The value of IntVectorTable is different with the address you think it may be.
;IntVectorTable
;@0x33FF_FF20
HandleEINT0 # 4
HandleEINT1 # 4
HandleEINT2 # 4
HandleEINT3 # 4
HandleEINT4_7 # 4
HandleEINT8_23 # 4
HandleCAM # 4 ; Added for 2440.
HandleBATFLT # 4
HandleTICK # 4
HandleWDT # 4
HandleTIMER0 # 4
HandleTIMER1 # 4
HandleTIMER2 # 4
HandleTIMER3 # 4
HandleTIMER4 # 4
HandleUART2 # 4
;@0x33FF_FF60
HandleLCD # 4
HandleDMA0 # 4
HandleDMA1 # 4
HandleDMA2 # 4
HandleDMA3 # 4
HandleMMC # 4
HandleSPI0 # 4
HandleUART1 # 4
HandleNFCON # 4 ; Added for 2440.
HandleUSBD # 4
HandleUSBH # 4
HandleIIC # 4
HandleUART0 # 4
HandleSPI1 # 4
HandleRTC # 4
HandleADC # 4
;@0x33FF_FFA0
END;定义数据段结束