对fl2440的时钟,看门狗,内存等等初始化汇编程序的理解

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;定义数据段结束
	


 

 

 

 

 


 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值