转自:http://blog.csdn.net/garby2004/article/details/4605261
;rGPFDAT = (rGPFDAT & ~(0xf<<4)) | ((~data & 0xf)<<4);
;To reduce PLL lock time, adjust the LOCKTIME register.
; Added for confirm clock divide. for 2440.
; Setting value Fclk:Hclk:Pclk
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.
; MMU_SetAsyncBusMode and MMU_SetFastBusMode over 4K, so do not call here
; [ CLKDIV_VAL>1 ; means Fclk:Hclk is not 1:1.
; bl MMU_SetFastBusMode ; default value.
;利用的协处理器的命令实现了对总线模式的设置
;===============================================================
;program has not been copied, so use these directly
[ CLKDIV_VAL>1 ; means Fclk:Hclk is not 1:1.
orr r0,r0,#0xc0000000;R1_nF:OR:R1_iA
bic r0,r0,#0xc0000000;R1_iA:OR:R1_nF
;Configure UPLL.配置 MPLL 一定要使最后的频率为16.9344MHz,不然你甭想用USB接口了,
ldr r1,=((U_MDIV<<12)+(U_PDIV<<4)+U_SDIV)
ldr r1,=((M_MDIV<<12)+(M_PDIV<<4)+M_SDIV) ;Fin=16.9344MHz
;Check if the boot is caused by the wake-up from SLEEP mode.
tst r0,#0x2 ; Check GSTATUS2[2] in order to know whether or not
;the power-up is caused by the wake-up from SLEEP mode.
bne WAKEUP_SLEEP ;如果是,则跳转到WAKEUP_SLEEP
EXPORT StartPointAfterSleepWakeUp ;定义外部的StartPointAfterSleepWakeUp
;===============================================================
;设置存储器控制寄存器,此段代码把13个存储控制器的内容批量的读取到了对应的特殊功能寄存器中
;首先是有一个数据区SMRDATA,在程序的后面有定义,这个数据区给13个寄存器分配52字节的地址空间。在下面
;的代码中,r0是这个数据区的起始地址,r2是数据区的结束地址,r1是寄存器的起始地址。这样,用一个判断语句
; bne %B0,就可以把内存中的数据赋给这13个存储控制寄存器了。
;===============================================================
ldr r1,=BWSCON ;BWSCON Address
add r2, r0, #52 ;End address of SMRDATA
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;; When EINT0 is pressed, Clear SDRAM
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; check if EIN0 button is pressed
bic r0,r0,#(0x1e<<1) ; bit clear
;64MB的SDRAM,0x30000000—0x34000000
;===========================================================
这段程序能在nor nand flash 运行,也可以在内存中运行。在nor nand flash运行,需要拷贝数据;
;===========================================================
ands r0, r0, #6 ;OM[1:0] != 0, NOR FLash 或者内存启动
bne copy_proc_beg ;不要读取 nand flash
adr r0, ResetEntry ;OM[1:0] == 0, NAND FLash 启动
cmp r0, #0 ;再比较入口是否为0地址处,如果不是则用了仿真器
bne copy_proc_beg ;用仿真器的情况也不要用 nand flash启动
;===========================================================
nand_boot_beg ;这一段代码完成从NAND读代码到RAM
mov r5, #NFCONF ;设置NAND FLASH的控制寄存器
ldr r0, =(7<<12)|(7<<8)|(7<<4)
ldr r0, =(0<<13)|(0<<12)|(0<<10)|(0<<9)|(0<<8)|(1<<6)|(1<<5)|(1<<4)|(1<<1)|(1<<0)
str r0, [r5, #4] ;设置NFCONT,使能NAND FLASH
bl ReadNandID ;按着读取NAND的ID号,结果保存在r5里
bl ReadNandStatus ;读取NAND状态,结果放在r1里
;一样 也就是说,我如我们编译程序时RO BASE指定的地址在RAM里,而把生成的
;文件拷到 NAND里运行,由ldr加载的r9的值还是定位在内存.
ands r0, r8, #0x1f ;凡r8为0x1f(32)的整数倍,eq有效,ne无效
addne r8, r8, #32 ;存在坏块的话就跳过这个坏块
bl ReadNandPage ;读取该页的NAND数据到RAM
add r9, r9, #512 ;每一页的大小是512Bytes
bcc %B2 ;如果r8小于8192(没读完),就返回前面的标号2处
mov r5, #NFCONF ;设置NAND FLASH 控制寄存器
str r0, [r5, #4] ; NAND flash controller enable
ldr pc, =copy_proc_beg ;copy nand flash 到ram
;===========================================================
adr r0, ResetEntry ;ResetEntry值->r0
ldr r2, ;BaseOfROM BaseOfROM值(后面有定义)->r2