微波EDA网,见证研发工程师的成长!
首页 > 硬件设计 > 嵌入式设计 > ARM启动代码分析(2440init.c)

ARM启动代码分析(2440init.c)

时间:11-22 来源:互联网 点击:

lf-refresh is issued,which may not be needed.
0subs r1,r1,#1
bne %B0

ldrr1,=MISCCR
ldrr0,[r1]
orrr0,r0,#(7<17) ;Set SCLK0=0, SCLK1=0, SCKE=0.
strr0,[r1]

ldr r0,=CLKCON; Enter sleep mode
str r2,[r0]

b .;CPU will die here.

;进入Sleep Mode,1)设置SDRAM为self-refresh
; 2)设置MISCCR bit[17] 1:sclk0=sclk 0:sclk0=0
;bit[18] 1:sclk1=sclk 0:sclk1=0
;bit[19] 1:Self refresh retain enable
;0:Self refresh retain disable
;When 1, After wake-up from sleep, The self-refresh will be retained.
WAKEUP_SLEEP
;Release SCLKn after wake-up from the SLEEP mode.
ldrr1,=MISCCR
ldrr0,[r1]
bicr0,r0,#(7<17) ;SCLK0:0->SCLK, SCLK1:0->SCLK, SCKE:0->=SCKE.
strr0,[r1]

;设置MISCCR
;Set memory control registers
ldrr0,=SMRDATA
ldrr1,=BWSCON;BWSCON Address;总线宽度和等待控制寄存器
addr2, r0, #52;End address of SMRDATA
0
ldrr3, [r0], #4 ;数据处理后R0自加4,[R0]->R3,R0+4->R0
strr3, [r1], #4
cmpr2, r0
bne%B0
;设置所有的memory control register,他的初始地址为BWSCON,初始化
;数据在以SMRDATA为起始的存储区

mov r1,#256
0subs r1,r1,#1;1) wait until the SelfRefresh is released.
bne %B0

ldr r1,=GSTATUS3 ;GSTATUS3 has the start address just after SLEEP wake-up
ldr r0,[r1]

mov pc,r0
;跳出Sleep Mode,进入Sleep状态前的PC
;异常中断宏调用

LTORG
HandlerFIQ HANDLER HandleFIQ
HandlerIRQ HANDLER HandleIRQ
HandlerUndef HANDLER HandleUndef
HandlerSWI HANDLER HandleSWI
HandlerDabort HANDLER HandleDabort
HandlerPabort HANDLER HandlePabort

IsrIRQ
subsp,sp,#4 ;reserved for PC
stmfdsp!,{r8-r9}

ldrr9,=INTOFFSET ;地址为0x4a000014的空间存着中断的偏移
ldrr9,[r9]
ldrr8,=HandleEINT0
addr8,r8,r9,lsl #2
ldrr8,[r8]
strr8,[sp,#8]
ldmfdsp!,{r8-r9,pc}
;外部中断号判断,通过中断服务程序入口地址存储器的地址偏移确定
;PC=[HandleEINT0+[INTOFFSET]]

;=======
; ENTRY
;=======
;扳子上电和复位后 程序开始从位于0x0执行b ResetHandler 程序从跳转到这里执行
;板子上电复位后 执行几个步骤这里通过标号在注释中加1,2,3....标示 标号表示执行顺序
ResetHandler
;1.禁止看门狗 屏蔽所有中断
;WTCON定义在2440addr.inc里面,WTCON EQU 0x53000000
;把WTCON地址放到R0里,然后在设置r1为0,最后把r1中的0值
;拷贝到r0所指向的地址里面,即禁用watch dog
ldrr0,=WTCON ;watch dog disable
ldrr1,=0x0
strr1,[r0]

;基本同上,INTMSK 0x4A000008 R/W Interrupt mask control
ldrr0,=INTMSK
ldrr1,=0xffffffff ;all interrupt disable关闭所有中断
strr1,[r0]

;基本同上,INTMSK 0X4A00001C R/W SubInterrupt mask control
ldrr0,=INTSUBMSK
ldrr1,=0x3ff;all sub interrupt disable关闭所有子中断(这个寄存器有11位)
strr1,[r0]

;由于条件为FALSE,这段根本就不会执行
[ {FALSE}
; rGPFDAT = (rGPFDAT & ~(0xf<4)) | ((~data & 0xf)<4);
; Led_Display
ldrr0,=GPFCON
ldrr1,=0x5500
strr1,[r0]
ldrr0,=GPFDAT
ldrr1,=0x10
strr1,[r0]
]

;2.根据工作频率设置pll
;这里介绍一下计算公式
;Fpllo=(m*Fin)/(p*2^s)
;m=Mdiv+8,p=Pdiv+2,s=Sdiv
;The proper range of P and M: 1<=P<=62, 1<=M<=248
;Fpllo必须大于20Mhz小于66Mhz
;Fpllo*2^s必须小于170Mhz
;如下面的PLLCON设定中的M_div P_div S_div是取自option.h中
;#elif (MCLK==40000000)
;#define PLL_M (0x48)
;#define PLL_P (0x3)
;#define PLL_S (0x2)
;所以m=Mdiv+8=80,p=Pdiv+2=5,s=Sdiv=2
;硬件使用晶振为10Mhz,即Fin=10Mhz
;Fpllo=80*10/5*2^2=40Mhz
;设置PLL的重置延迟
;由于在更改了主时钟控制器(MPLL)之后,新的频率需要一定时间过后才能稳定
;所以需要等待一段时间,而这个等待的时间就是使用LOCKTIME(地址为0x4c000000)寄存器来设置的
;LOCKTIME[15:00] MPLL lock time count value for FCLK, HCLK, and PCLK
;LOCKTIME[32:16] UPLL lock time count value for UCLK.
;FCLK用于CPU核
;HCLK用于AHB总线的设备(比如SDRAM)
;PCLK用于APB总线的设备(比如UART)
;UPLL为USB的控制时钟,根据USB规范,好像是48MHz
;ARM920T内核使用FCLK
;内存控制器,LCD控制器等使用HCLK;
; 看门狗、串口等使用PCLK

;刚设置好PLL时,系统认为这是PLL还没稳定,所有这时不用PLL的时钟,而用外部晶振做时钟,
;将PLL锁住,过了LOCKTIME后认为PLL已经稳定了,才使用PLL给系统提供时钟。例如S3c2410手
;;册上给出锁住时间必须大于150us,外部晶振为12M,那么(1/12M)*N>150us,其中N为U_LTIME
或M_LTIME,N>1800,可以设置U_LTIME或和M_LTIME为0xfff,(0xfff=4096>1800),此时LOCKTIME=0xffffff.
;To reduce PLL lock time, adjust the LOCKTIME register.
ldrr0,=LOCKTIME
ldrr1,=0xffffff
strr1,[r0]

Copyright © 2017-2020 微波EDA网 版权所有

网站地图

Top