|
;-----------------------------------------------------------------------
;配置時鐘
;如果邏輯上沒有定義 NO_CLOCK_SETUP并且 CLOCK_SETUP != 0執(zhí)行下面程序
;-----------------------------------------------------------------------
IF (:LNOT:(:DEF:NO_CLOCK_SETUP)):LAND:(CLOCK_SETUP != 0)
LDR R0, =CLOCK_BASE ;加載時鐘基址
LDR R1, =LOCKTIME_Val ;加載PLL鎖定時間計數(shù)值
STR R1, [R0, #LOCKTIME_OFS] ;并將該值配置到PLL鎖定時間計數(shù)器
MOV R1, #CLKDIVN_Val
STR R1, [R0, #CLKDIVN_OFS] ;配置時鐘分頻器
LDR R1, =CAMDIVN_Val
STR R1, [R0, #CAMDIVN_OFS] ;配置攝像頭分頻控制寄存器
LDR R1, =MPLLCON_Val
STR R1, [R0, #MPLLCON_OFS] ;配置MPLL配置寄存器
LDR R1, =UPLLCON_Val
STR R1, [R0, #UPLLCON_OFS] ;配置UPLL配置寄存器
MOV R1, #CLKSLOW_Val
STR R1, [R0, #CLKSLOW_OFS] ;配置時鐘減慢控制寄存器
LDR R1, =CLKCON_Val
STR R1, [R0, #CLKCON_OFS] ;配置時鐘配控制寄存器
ENDIF
;-----------------------------------------------------------------------
;存儲器設(shè)定
;如果沒有定義NO_MC_SETUP且CLOCK_SETUP != 0則執(zhí)行下面的程序
;-----------------------------------------------------------------------
IF (:LNOT:(:DEF:NO_MC_SETUP)):LAND:(CLOCK_SETUP != 0)
LDR R0, =MC_BASE ;加載存儲控制器基址
LDR R1, =BWSCON_Val
STR R1, [R0, #BWSCON_OFS] ;配置總線寬度和等待控制寄存器
LDR R1, =BANKCON0_Val
STR R1, [R0, #BANKCON0_OFS] ;配置BLANK0控制寄存器
LDR R1, =BANKCON1_Val
STR R1, [R0, #BANKCON1_OFS] ;配置BLANK1控制寄存器
LDR R1, =BANKCON2_Val
STR R1, [R0, #BANKCON2_OFS] ;配置BLANK2控制寄存器
LDR R1, =BANKCON3_Val
STR R1, [R0, #BANKCON3_OFS] ;配置BLANK3控制寄存器
LDR R1, =BANKCON4_Val
STR R1, [R0, #BANKCON4_OFS] ;配置BLANK4控制寄存器
LDR R1, =BANKCON5_Val
STR R1, [R0, #BANKCON5_OFS] ;配置BLANK5控制寄存器
LDR R1, =BANKCON6_Val
STR R1, [R0, #BANKCON6_OFS] ;配置BLANK6控制寄存器
LDR R1, =BANKCON7_Val
STR R1, [R0, #BANKCON7_OFS] ;配置BLANK7控制寄存器
LDR R1, =REFRESH_Val
STR R1, [R0, #REFRESH_OFS] ;配置DRAM/SDRAM刷新控制寄存器
MOV R1, #BANKSIZE_Val
STR R1, [R0, #BANKSIZE_OFS] ;配置可調(diào)的bank大小寄存器
MOV R1, #MRSRB6_Val
STR R1, [R0, #MRSRB6_OFS] ;配置bank6模式控制寄存器
MOV R1, #MRSRB7_Val
STR R1, [R0, #MRSRB7_OFS] ;配置bank7模式控制寄存器
ENDIF
;-----------------------------------------------------------------------
;IO端口配置
;如果沒有定義NO_GP_SETUP并且GP_SETUP != 0則執(zhí)行下面的程序
;-----------------------------------------------------------------------
IF (:LNOT:(:DEF:NO_GP_SETUP)):LAND:(GP_SETUP != 0)
IF GPA_SETUP != 0
LDR R0, =GPA_BASE ;配置端口A功能
LDR R1, =GPACON_Val ;A口有25個口,做IO時只能做輸出口
STR R1, [R0, #GPCON_OFS]
ENDIF
IF GPB_SETUP != 0
LDR R0, =GPB_BASE ;配置端口B功能
LDR R1, =GPBCON_Val
STR R1, [R0, #GPCON_OFS]
LDR R1, =GPBUP_Val ;配置端口B上拉寄存器
STR R1, [R0, #GPUP_OFS]
ENDIF
IF GPC_SETUP != 0
LDR R0, =GPC_BASE ;配置端口C功能
LDR R1, =GPCCON_Val
STR R1, [R0, #GPCON_OFS]
LDR R1, =GPCUP_Val ;配置端口C上拉寄存器
STR R1, [R0, #GPUP_OFS]
ENDIF
IF GPD_SETUP != 0
LDR R0, =GPD_BASE ;配置端口D功能
LDR R1, =GPDCON_Val
STR R1, [R0, #GPCON_OFS]
LDR R1, =GPDUP_Val ;配置端口D上位寄存器
STR R1, [R0, #GPUP_OFS]
ENDIF
IF GPE_SETUP != 0
LDR R0, =GPE_BASE
LDR R1, =GPECON_Val ;配置端口E功能
STR R1, [R0, #GPCON_OFS]
LDR R1, =GPEUP_Val ;配置端口E上位寄存器
STR R1, [R0, #GPUP_OFS]
ENDIF
IF GPF_SETUP != 0
LDR R0, =GPF_BASE
LDR R1, =GPFCON_Val ;配置端口F功能
STR R1, [R0, #GPCON_OFS]
LDR R1, =GPFUP_Val ;配置端口F上位寄存器
STR R1, [R0, #GPUP_OFS]
ENDIF
IF GPG_SETUP != 0
LDR R0, =GPG_BASE
LDR R1, =GPGCON_Val ;配置端口G功能
STR R1, [R0, #GPCON_OFS]
LDR R1, =GPGUP_Val ;配置端口G上位寄存器
STR R1, [R0, #GPUP_OFS]
ENDIF
IF GPH_SETUP != 0
LDR R0, =GPH_BASE
LDR R1, =GPHCON_Val ;配置端口H功
STR R1, [R0, #GPCON_OFS]
LDR R1, =GPHUP_Val ;配置端口H上位寄存器
STR R1, [R0, #GPUP_OFS]
ENDIF
IF GPJ_SETUP != 0
LDR R0, =GPJ_BASE
LDR R1, =GPJCON_Val ;配置端口J功
STR R1, [R0, #GPCON_OFS]
LDR R1, =GPJUP_Val ;配置端口J上位寄存
STR R1, [R0, #GPUP_OFS]
ENDIF
ENDIF
;-----------------------------------------------------------------------
;拷貝異常向量到內(nèi)部RAM
;如果定義了RAM_INTVEC就執(zhí)行下面一段程序
;-----------------------------------------------------------------------
IF :DEF:RAM_INTVEC
ADR R8, Vectors ; 讀取向量源地址
LDR R9, =IRAM_BASE ; 讀取片上SRAM的基地址
LDMIA R8!, {R0-R7} ; 批量加載異常向量
STMIA R9!, {R0-R7} ; 批量存儲向量
LDMIA R8!, {R0-R7} ; 加載程序入口地址(Load Handler Addresses )
STMIA R9!, {R0-R7} ; 存儲程序入口地址(Store Handler Addresses)
ENDIF
;-----------------------------------------------------------------------
;配置相應(yīng)模式棧的大小(Setup Stack for each mode )
;下面這一段主要是設(shè)置各個異常模式的堆棧,注意在設(shè)置的時候需要禁止IRQ和FIQ.
;這段代碼也是系統(tǒng)復(fù)位后執(zhí)行的第一段代碼。執(zhí)行完這段代碼后系統(tǒng)處于系統(tǒng)模
;式,并且IRQ和FIQ都是禁止的。
;-----------------------------------------------------------------------
LDR R0, =Stack_Top ;加載棧頂指針地址
;-----------------------------------------------------------------------
;進入未定義模式,并設(shè)定其棧指針
;-----------------------------------------------------------------------
;將(Mode_UND | I_Bit | F_Bit)賦值給 CPSR_c即CPSR[7:0]
MSR CPSR_c, #Mode_UND:OR:I_Bit:OR:F_Bit
MOV SP, R0 ;棧頂指針地址賦值給SP指針
SUB R0, R0, #UND_Stack_Size ;分其棧指針
;-----------------------------------------------------------------------
;進入異常中斷模式,并設(shè)定其棧指針
;下面這三句話與上面原理一樣
;-----------------------------------------------------------------------
MSR CPSR_c, #Mode_ABT:OR:I_Bit:OR:F_Bit
MOV SP, R0
SUB R0, R0, #ABT_Stack_Size
;-----------------------------------------------------------------------
;進入FIQ模式,并設(shè)定其棧指針
;下面這三句話與上面原理一樣
;-----------------------------------------------------------------------
MSR CPSR_c, #Mode_FIQ:OR:I_Bit:OR:F_Bit
MOV SP, R0
SUB R0, R0, #FIQ_Stack_Size
;-----------------------------------------------------------------------
;進入IRQ模式,并設(shè)定其棧指針
;下面這三句話與上面原理一樣
;-----------------------------------------------------------------------
MSR CPSR_c, #Mode_IRQ:OR:I_Bit:OR:F_Bit
MOV SP, R0
SUB R0, R0, #IRQ_Stack_Size
;-----------------------------------------------------------------------
;進入Supervisor模式,并設(shè)定其棧指針
;下面這三句話與上面原理一樣
;-----------------------------------------------------------------------
MSR CPSR_c, #Mode_SVC:OR:I_Bit:OR:F_Bit
MOV SP, R0
SUB R0, R0, #SVC_Stack_Size
;-----------------------------------------------------------------------
;進入用戶模式,并設(shè)定其棧指針
;下面這三句話與上面原理一樣
;-----------------------------------------------------------------------
; Enter User Mode and set its Stack Pointer
MSR CPSR_c, #Mode_USR
MOV SP, R0
SUB SL, SP, #USR_Stack_Size
;-----------------------------------------------------------------------
;進入用戶模式
;-----------------------------------------------------------------------
MSR CPSR_c, #Mode_USR
IF :DEF:__MICROLIB ;如果定義了__MICROLIB
EXPORT __initial_sp ;那么就聲明__initial_sp
ELSE
MOV SP, R0 ;否則就設(shè)定用戶模式棧指針
SUB SL, SP, #USR_Stack_Size
ENDIF
;-----------------------------------------------------------------------
;些處開始正式進入C代碼區(qū)
;反匯編以后C程序中的main函數(shù)名就變成了__main
;-----------------------------------------------------------------------
IMPORT __main ;聲明__main 函數(shù)
LDR R0, =__main ;加載__main 函數(shù)入口地址
BX R0 ;跳轉(zhuǎn)到__main處
IF :DEF:__MICROLIB ;如果定義了__MICROLIB
EXPORT __heap_base ;則聲明__heap_base
EXPORT __heap_limit ;聲明__heap_limit
ELSE
;-----------------------------------------------------------------------
;用戶初始化堆與棧,用于動態(tài)申請內(nèi)存使用
;__use_two_region_memory這是MDK的庫函
;__user_initial_stackheap也是一個庫函數(shù),它的返回值有
; * 堆基址(heap base) --> R0
; * �;�(stack base) --> R1 一般為棧的最高地址
; * 堆頂(heap limit) --> R2
; * 棧頂(stack limit) --> R3
;
;-----------------------------------------------------------------------
AREA |.text|, CODE, READONLY
IMPORT __use_two_region_memory
EXPORT __user_initial_stackheap
__user_initial_stackheap
LDR R0, = Heap_Mem ;堆內(nèi)存起始地址 -->R0
LDR R1, =(Stack_Mem + USR_Stack_Size) ;棧起始地址 -->R1
LDR R2, = (Heap_Mem + Heap_Size) ;堆頂 -->R2
LDR R3, = Stack_Mem ;棧頂?shù)刂?--> R3
BX LR ;子程序返回
ENDIF
END
|
|