mini2440开发板中启动代码2440INIT.S分析
?
声明:文章转自别处,非本人自创
http://hi.baidu.com/haijie0707/blog/item/6ff41a3bff7ccef93a87ced5.html ;========================================= ; 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 s for testing STOP,Sleep mode ; 2003.03.14:DonGo: Modified for 2440. ;========================================= ;首先,启动代码定义了一些常量 ;汇编不能使用include包含头文件,所有用Get ;汇编也不认识*.h 文件,所有只能用*.inc ?GET option.inc??? ;定义芯片相关的配置 ?GET memcfg.inc??? ;定义存储器配置 ?GET 2440addr.inc? ;定义了寄存器符号 ?
;处理器模式常量: CPSR寄存器的后5位决定目前处理器模式 M[4:0]
USERMODE EQU 0x10
FIQMODE EQU 0x11
IRQMODE EQU 0x12
SVCMODE EQU 0x13
ABORTMODE EQU 0x17
UNDEFMODE EQU 0x1b
MODEMASK EQU 0x1f
NOINT EQU 0xc0
;定义处理器各模式下堆栈地址常量
;_STACK_BASEADDRESS定义在option.inc中
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 ~
;arm处理器有两种工作状态 1.arm:32位 这种工作状态下执行字对准的arm指令 2.Thumb:16位 这种工状;态执行半字对准的Thumb指令
;因为处理器分为16位 32位两种工作状态 程序的编译器也是分16位和32两种编译方式 所以下面的程序用
;于根据处理器工作状态确定编译器编译方式
;code16伪指令指示汇编编译器后面的指令为16位的thumb指令
;code32伪指令指示汇编编译器后面的指令为32位的arm指令
;
;Arm上电时处于ARM状态,故无论指令为ARM集或Thumb集,都先强制成ARM集,待init.s初始化完成后
;再根据用户的编译配置转换成相应的指令模式。为此,定义变量THUMBCODE作为指示,跳转到main之前
;根据其值切换指令模式
;
;这段是为了统一目前的处理器工作状态和软件编译方式(16位编译环境使用tasm.exe编译
;检查在tasm.exe里是否设置了采用THUMB(16位)代码(armasm -16 ...@ADS 1.0)
?
?
?GBLL THUMBCODE?????????????? ?;定义THUMBCODE全局变量
?? [ {CONFIG} = 16?
???????????????????????????????? ;如果发现是在用16位代码的话(编译选项中指定使用thumb指令
???? THUMBCODE SETL {TRUE} ?? ;把THUMBCODE设置为TURE ????
?????? CODE32 ?????????????????? ;把处理器从新设置成为ARM模式 ????????
??????? ?| ????????????????????? ;如果处理器现在就是ARM模式
??? THUMBCODE SETL {FALSE}?? ;把THUMBCODE设置为FALSE就行了 ???
?? ] ??
?MACRO?
??????????????;一个根据THUMBCODE把PC寄存的值保存到LR的宏,宏 MOV_PC_LR
? MOV_PC_LR [?? THUMBCODE bx lr?? ;([表示if)
?????????????????????????????????????
;在ARM模式中要使用BX指令转跳到THUMB指令,并转换模式
|????????? ;(|表示else)如果编译选项本来就指定为ARM模式 mov pc,lr? ;如果目标地址也是ARM指令的话就采用这种方式 ]?????????????? ;(]表示endif) MEND MACRO??????????? ?;和上面的宏一样,只是多了一个相等的条件 MOVEQ_PC_LR [???? THUMBCODE bxeq lr | moveq pc,lr ] MEND ;======================================================================================= ;下面这个宏是用于第一次查表过程的实现中断向量的重定向,如果你比较细心的话就是发现 ;在_ISR_STARTADDRESS=0x33FF_FF00里定义的第一级中断向量表是采用型如Handle***的方式的. ;而在程序的ENTRY处(程序开始处)采用的是b Handler***的方式. ;在这里Handler***就是通过HANDLER这个宏和Handle***进立联系的. ;这种方式的优点就是正真定义的向量数据在内存空间里,而不是在ENTRY处的ROM(FLASH)空间里, ;这样,我们就可以在程序里灵活的改动向量的数据了. ;========================================================================================? ;;这段程序用于把中断服务程序的首地址装载到pc中,有人称之为“加载程序”。 ;本初始化程序定义了一个数据区(在文件最后),34个字空间,存放相应中断服务程序的首地址。每个字 ;空间都有一个标号,以Handle***命名。 ;在向量中断模式下使用“加载程序”来执行中断服务程序。 ;这里就必须讲一下向量中断模式和非向量中断模式的概念 ;向量中断模式是当cpu读取位于0x18处的IRQ中断指令的时候,系统自动读取对应于该中断源确定地址上的; ;指令取代0x18处的指令,通过跳转指令系统就直接跳转到对应地址 ;函数中 节省了中断处理时间提高了中断处理速度标 例如 ADC中断的向量地址为0xC0,则在0xC0处放如下 ;代码:ldr PC,=HandlerADC 当ADC中断产生的时候系统会 ;自动跳转到HandlerADC函数中 ;非向量中断模式处理方式是一种传统的中断处理方法,当系统产生中断的时候,系统将interrupt ;pending寄存器中对应标志位置位 然后跳转到位于0x18处的统一中断 ;函数中 该函数通过读取interrupt pending寄存器中对应标志位 来判断中? 断? 源 并根据优先级关系再跳到 ;对应中断源的处理代码中 ; MACRO $HandlerLabel HANDLER $HandleLabel $HandlerLabel?????? ;标号 sub sp,sp,#4??????? ;减少sp(用于存放转跳地址) stmfd sp!,{r0}????? ;把工作寄存器压入栈(lr does not push because it return to original address) ldr???? r0,=$HandleLabel??? ;将HandleXXX的址址放入r0 ldr???? r0,[r0]????????????????????????? ;把HandleXXX所指向的内容(也就是中断程序的入口)放入r0 str???? r0,[sp,#4]?????????????????? ?;把中断服务程序(ISR)压入栈 ldmfd?? sp!,{r0,pc}???????????? ? ;用出栈的方式恢复r0的原值和为pc设定新值(也就完成了到ISR的转跳) MEND ;========================================================================================= ;在这里用IMPORT伪指令(和c语言的extren一样)引入|Image$$RO$$Base|,|Image$$RO$$Limit|... ;这些变量是通过ADS的工程设置里面设定的RO Base和RW Base设定的, ;最终由编译脚本和连接程序导入程序. ;那为什么要引入这玩意呢,最简单的用处是可以根据它们拷贝自已 ;========================================================================================== IMPORT? |Image$$RO$$Base|?? ; ROM code(也就是代码)的开始地址 IMPORT? |Image$$RO$$Limit|?? ?; ROM code的结束地址 (=ROM data的开始地址) IMPORT? |Image$$RW$$Base|?? ; 要初始化的RAM的开始地址 IMPORT? |Image$$ZI$$Base|???? ?; area(需要清零的RAM区域)的开始地址 IMPORT? |Image$$ZI$$Limit|??? ?? ; area的结束地址 ;这里引入一些在其它文件中实现在函数,包括为我们所熟知的main函数 IMPORT MMU_SetAsyncBusMode IMPORT MMU_SetFastBusMode ;hzh? ? ? ? IMPORT?Main
??????????????????????????是在本源文件中,是在别的中定义???????????????????????? 的 在本源文件中要用到
__ENTRY
ResetEntry? ? ? ?
?
?
????????? ;条件编译,在编译成机器码前就设定好 ????? ;下面是大小端的一个判断,在Option.inc里已经设?FALSE? ?????????????? ;在bigendian中,地址为A的字单元包括字节单元A,A+1,A+2,A+3,字节单元由高位到低位为A,A+1,A+2,A+3 ;========================================================================================= ;void EnterPWDN(int CLKCON); ??ldr? r0,=rCLKCON?? ???????????????????????????????????? ;//进入PWDN后如果不是sleep则进入stop ?????????????????????????????????????;//进入Stop mode ? mov r1,#32 ?ldr r0,=REFRESH????????????????????????????? ;exit from SDRAM self refresh mode. ENTER_SLEEP ?mov r1,#16????????????????????????????? ??;Wait until self-refresh is issued,which may not be needed. ?ldr?r1,=MISCCR????????????????????????? ;IO register ?b .??????????????????????????????????????????? ;CPU will die here. WAKEUP_SLEEP ????????????????????????????????? ;Set memory control registers ?ldr r1,=GSTATUS3??????????????;GSTATUS3 has the start address just after SLEEP wake-up ??????????????????????????????????????????????? ?;4.得有些表示了,该点点LED灯了,不过被FALSE掉了.? ;6.下面就来设置PLL了,你的板快不快就看这了!!? ;这里介绍一下计算公式 ;Fpllo必须大于200Mhz小于600Mhz ??? ? ; Added for confirm clock divide. for 2440. /****************************************************************************************************************************************************/
上接mini2440开发板中启动代码2440INIT.S分析(1)
;配置 UPLL? ;//Configure UPLL Fin=12.0MHz UFout=48MHz 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? nop ; delay must be inserted for setting hardware be completed. nop nop nop nop nop? ;配置 MPLL ;//Configure MPLL Fin=12.0MHz MFout=304.8MHz一定要使最后的频率为16.9344MHz,不然你甭想用USB接口了? ldr r0,=MPLLCON ldr r1,=((M_MDIV<<12)+(M_PDIV<<4)+M_SDIV) str r1,[r0] ? ] ;检查是否从SLEEP模式中恢复 ldr r1,=GSTATUS2 ldr r0,[r1] tst r0,#0x2 ;如果是从SLEEP模式中恢复,转跳到SLEEP_WAKEUP. bne WAKEUP_SLEEP EXPORT?? ?StartPointAfterSleepWakeUp?????? ;导出符号StartPointAfterSleepWakeUp StartPointAfterSleepWakeUp ;=============================================================================== ;设置内存控制器等寄存器的值,因为这些寄存器是连续排列的,所以采用如下办法对这些 ;寄存器进行连续设置.其中用到了 SMRDATA的数据,这在代码后面有定义 ;=============================================================================== ? ;ldr r0,=SMRDATA adrl r0,SMRDATA????????????????? ;be careful!,hzh ldr r1,=BWSCON???????????????? ?;BWSCON 地址 add r2,#52 ;??????????????????????? SMRDATA数据的结束地址,共有52字节的数据 0 ldr r3,#4 str r3,#4 cmp r2,r0 bne %B0 ;================================================================================ ;如果 EINT0 产生(这中断就是我们按键产生的),就清除SDRAM,不过好像没人会在这个时候按 ;================================================================================ ; check if EIN0 button is pressed ldr r0,=0x0 str r1,=GPFUP ldr r1,=0xff str r1,[r0] ldr r1,=GPFDAT ldr r0,[r1] bic r0,#(0x1e<<1)? ; bit clear tst r0,#0x1 bne %F1?? ;如果没有按,就跳到后面的1标号处 ; 这就是清零内存的代码 ldr r0,=0x55aa str r1,[r0] ; ldr r0,=GPFUP ; ldr r1,=0xff ; str r1,[r0] ;LED=**** mov r1,#0 mov r2,#0 mov r3,#0 mov r4,#0 mov r5,#0 mov r6,#0 mov r7,#0 mov r8,#0 ldr r9,=0x4000000?? ;64MB ldr r0,=0x30000000 0? stmia r0!,{r1-r8} subs r9,#32? bne %B0 ;到这就结束了. 1 bl InitStacks ;初始化堆栈 ;bl Led_Test ;又是LED,注掉了 ;======================================================================= ; 哈哈,下面又有看头了,这个初始化程序好像被名曰hzh的高手改过 ; 能在NOR NAND 还有内存中运行,当然了,在内存中运行最简单了. ; 在NOR NAND中运行的话都要先把自己拷到内存中. ; 此外,还记得上面提到的|Image$$RO$$Base|,|Image$$RO$$Limit|...吗? ; 这就是拷贝的依据了!!! ;========================================================================= ldr r0,=BWSCON ldr r0,[r0] ands 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地址处 ;========================================================================== ;如果不是,则表示主板设置了从NAND启动,但这个程序由于其它原因, ;并没有从NAND启动,这种情况最有可能的原因就是用仿真器. ;========================================================================== bne copy_proc_beg???? ?;这种情况也不读取NAND FLASH. ;nop?????????????????????????????????? ;如果是0才是真正从NAND 启动,因为其4k被复制到0地址??????????????????????????????????????????????????? 开始的stepingstone 内部sram中 ; 注意adr得到的是 相对 地址,非绝对地址 == if use Multi-ice, ;=========================================================== nand_boot_beg???????????????????????? ?;这一段代码完成从NAND读代码到RAM mov r5,#NFCONF??????????????????????? ;首先设定NAND的一些控制寄存器 ;set timing value ldr r0,=(7<<12)|(7<<8)|(7<<4) str r0,[r5] ;enable control?????????????????? 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] bl ReadNandID ;按着读取NAND的ID号,结果保存在r5里 mov r6,#0? ;r6设初值0. ldr r0,=0xec73 ;期望的NAND ID号 cmp r5,r0 ;这里进行比较 beq %F1? ;相等的话就跳到下一个1标号处 ldr r0,=0xec75 ;这是另一个期望值 cmp r5,r0 beq %F1? ;相等的话就跳到下一个1标号处 mov r6,#1? ;不相等了,设置r6=1. 1? bl ReadNandStatus???????????????????????????? ;读取NAND状态,结果放在r1里 mov r8,#0????????????????????????????????????????????? ?;r8设初值0,意义为页号 ldr r9,=ResetEntry???????????????????????????????? ;r9设初值为初始化程序入口地址 ;========================================================================= ; 注意,在这里使用的是ldr伪指令,而不是上面用的adr伪指令,它加载的是ResetEntry ; 的决对地址,也就是我们期望的RAM中的地址,在这里,它和|Image$$RO$$Base|一样 ; 也就是说,我如我们编译程序时RO BASE指定的地址在RAM里,而把生成的文件拷到 ; NAND里运行,由ldr加载的r9的值还是定位在内存. ;========================================================================= 2? ands r0,#0x1f??????????????????????????? ;凡r8为0x1f(32)的整数倍-1,eq有效,ne无效 bne? %F3?????????????????????????????????????????;这句的意思是对每个块(32页)进行检错 mov? r0,r8??????????????????????????????????????? ;r8->r0 bl? CheckBadBlk?????????????????????????????;检查NAND的坏区 cmp? r0,#0?????????????????????????????????????? ;比较r0和0 addne r8,#32 ;存在坏块的话就跳过这个坏块 bne? %F4 ;没有的话就跳到标???? 号4处 3? mov r0,r8? ;当前页号->r0 mov r1,r9? ;当前目标地址->r1 bl ReadNandPage ;读取该页的NAND数据到RAM add r9,#512 ;每一页的大小是512Bytes add r8,#1 ;r8指向下一页 4? cmp r8,#256???????????????????????????????? ;比较是否读完256页即128KBytes bcc %B2?????????????????????????????????????? ?;如果r8小于256(没读完),就返回前面的标号2处 mov r5,#NFCONF??????????????????? ?? ;DsNandFlash ldr r0,#4] bic r0,#1 str r0,#4] ldr pc,=copy_proc_beg???????????????????????????? ;调用copy_proc_beg ;=========================================================== copy_proc_beg adr r0,ResetEntry??????????????????????????? ?;ResetEntry值->r0 ldr r2,BaseOfROM????????????????????????? ;BaseOfROM值(后面有定义)->r2 cmp r0,r2????????????????????????????????????????? ;比较r0和r2 ldreq r0,TopOfROM?????????????????????????;如果相等的话(在内存运行),TopOfROM->r0 beq InitRam???????????????????????????????????? ;同时跳到InitRam ;========================================================= ;下面这个是针对代码在NOR FLASH时的拷贝方法 ;功能为把从ResetEntry起,TopOfROM-BaseOfROM大小的数据拷到BaseOfROM ;TopOfROM和BaseOfROM为|Image$$RO$$Limit|和|Image$$RO$$Base| ;|Image$$RO$$Limit|和|Image$$RO$$Base|由连接器生成 ;为生成的代码的代码段运行时的起启和终止地址 ;BaseOfBSS和BaseOfZero为|Image$$RW$$Base|和|Image$$ZI$$Base| ;|Image$$RW$$Base|和|Image$$ZI$$Base|也是由连接器生成 ;两者之间就是初始化数据的存放地放 ;======================================================= ldr r3,TopOfROM? 0 ldmia r0!,{r4-r7} stmia r2!,{r4-r7} cmp r2,r3 bcc %B0 sub r2,r2,r3? ;r2=BaseOfROM-TopOfROM=(-)代码长度?? sub r0,r2 ;r0=ResetEntry-(-)代码长度=ResetEntry+代码长度? InitRam? ldr r2,BaseOfBSS??????????????????????????? ;BaseOfBSS->r2 ldr r3,BaseOfZero??????????????????????????? ?;BaseOfZero->r3 0 cmp r2,r3????????????????????????? ?;比较BaseOfBSS和BaseOfZero ldrcc r1,#4? ;要是r21?? ; means Fclk:Hclk is not 1:1. ; bl MMU_SetAsyncBusMode ; | ; bl MMU_SetFastBusMode ; default value. ; ] ;bl Led_Test ;=========================================================== ; 进入C语言前的最后一步了,就是把我们用说查二级向量表 ; 的中断例程安装到一级向量表(异常向量表)里. ldr r0,=HandleIRQ?????? ;This routine is needed ldr r1,=IsrIRQ?? ;if there is not 'subs pc,lr,#4' at 0x18,0x1c str r1,[r0] ; ;Copy and paste RW data/zero initialized data ; ldr r0,=|Image$$RO$$Limit| ; Get pointer to ROM data ; ldr r1,=|Image$$RW$$Base|? ; and RAM copy ; ldr r3,=|Image$$ZI$$Base| ; ; ;Zero init base => top of initialised data ; cmp r0,r1????? ; Check that they are different ; beq %F2 ;1 ; cmp r1,r3????? ; Copy init data ; ldrcc r2,#4??? ;--> LDRCC r2,[r0] + ADD r0,#4 ; strcc r2,#4??? ;--> STRCC r2,[r1] + ADD r1,#4 ; bcc %B1 ;2 ; ldr r1,=|Image$$ZI$$Limit| ; Top of zero init segment ; mov r2,#0 ;3 ; cmp r3,r1????? ; Zero init ; strcc r2,[r3],#4 ; bcc %B3 ;***************************************************************************** ;!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! ; 妈呀,终说见到艳阳天了!!!!!!!!!! ;?????? 跳到C语言的main函数处了. ;!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! ;***************************************************************************** [ :LNOT:THUMBCODE bl Main ;Do not use main() because ...... ;ldr pc,=Main ;hzh 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 ] ; 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,#MODEMASK orr r1,#UNDEFMODE|NOINT msr cpsr_cxsf,r1? ;UndefMode ldr sp,=UndefStack? ; UndefStack=0x33FF_5C00 orr r1,#ABORTMODE|NOINT msr cpsr_cxsf,r1? ;AbortMode ldr sp,=AbortStack? ; AbortStack=0x33FF_6000 orr r1,#IRQMODE|NOINT msr cpsr_cxsf,r1? ;IRQMode ldr sp,=IRQStack? ; IRQStack=0x33FF_7000 orr r1,#FIQMODE|NOINT msr cpsr_cxsf,r1? ;FIQMode ldr sp,=FIQStack? ; FIQStack=0x33FF_8000 bic r0,#MODEMASK|NOINT orr r1,#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. ;=========================================================== ReadNandID mov????? r7,#NFCONF ldr????? r0,[r7,#4]? ;NFChipEn(); bic????? r0,#2 str????? r0,#4] mov????? r0,#0x90? ;WrNFCmd(RdIDCMD); strb???? r0,#8] mov????? r4,#0?? ;WrNFAddr(0); strb???? r4,#0xc] 1?????? ;while(NFIsBusy()); ldr????? r0,#0x20] tst????? r0,#1 beq????? %B1 ldrb???? r0,#0x10] ;id? = RdNFDat()<<8; mov????? r0,lsl #8 ldrb???? r1,#0x10] ;id |= RdNFDat(); orr????? r5,r0 ldr????? r0,#4]? ;NFChipDs(); orr????? r0,#4] mov?? pc,lr? ReadNandStatus mov?? r7,#0x70? ;WrNFCmd(QUERYCMD); strb???? r0,#8]? ldrb???? r1,#0x10] ;r1 = RdNFDat(); ldr????? r0,lr WaitNandBusy mov????? r0,#0x70? ;WrNFCmd(QUERYCMD); mov????? r1,#NFCONF strb???? r0,[r1,#8] 1?????? ;while(!(RdNFDat()&0x40));? ldrb???? r0,#0x10] tst????? r0,#0x40 beq?? %B1 mov????? r0,#0?? ;WrNFCmd(READCMD0); strb???? r0,#8] mov????? pc,lr CheckBadBlk mov? r7,lr mov? r5,#NFCONF bic????? r0,#0x1f ;addr &= ~0x1f; ldr????? r1,#4]? ;NFChipEn() bic????? r1,#2 str????? r1,#4] mov????? r1,#0x50? ;WrNFCmd(READCMD2) strb???? r1,#8] mov????? r1,#5;6? ;6->5 strb???? r1,#0xc] ;WrNFAddr(5);(6) 6->5 strb???? r0,#0xc] ;WrNFAddr(addr) mov????? r1,lsr #8 ;WrNFAddr(addr>>8) strb???? r1,#0xc] cmp????? r6,#0?? ;if(NandAddr)?? movne??? r0,lsr #16 ;WrNFAddr(addr>>16) strneb?? r0,#0xc] ; bl? WaitNandBusy ;WaitNFBusy() ;do not use WaitNandBusy,after WaitNandBusy will read part A! mov r0,#100 1 subs r0,#1 bne %B1 2 ldr r0,#0x20] tst r0,#1 beq %B2? ldrb r0,#0x10] ;RdNFDat() sub? r0,#0xff mov????? r1,#0?? ;WrNFCmd(READCMD0) strb???? r1,#8] ldr????? r1,#4]? ;NFChipDs() orr????? r1,#4] mov? pc,r7 ReadNandPage mov?? r7,lr mov????? r4,r1 mov????? r5,#NFCONF ldr????? r1,#4]? mov????? r1,#8]? strb???? r1,#0xc] ;WrNFAddr(0) strb???? r0,#0xc]? cmp????? r6,#0xc] ldr????? r0,#4]? ;InitEcc() orr????? r0,#0x10 str????? r0,#4] bl?????? WaitNandBusy ;WaitNFBusy() mov????? r0,#0?? ;for(i=0; i<512; i++) 1 ldrb???? r1,#0x10] ;buf[i] = RdNFDat() strb???? r1,[r4,r0] add????? r0,#1 bic????? r0,#0x10000 cmp????? r0,#0x200 bcc????? %B1 ldr????? r0,#4]? ;NFChipDs() orr????? r0,#4] mov?? pc,r7 ;--------------------LED test EXPORT Led_Test Led_Test mov r0,#0x56000000 mov r1,#0x5500 str r1,#0x50] 0? mov r1,#0x50 str r1,#0x54] mov r2,#0x100000 1 subs r2,#1 bne %B1 mov r1,#0xa0 str r1,#0x100000 2 subs r2,#1 bne %B2 b %B0 mov pc,lr ;=========================================================== LTORG ;GCS0->SST39VF1601 ;GCS1->16c550 ;GCS2->IDE ;GCS3->CS8900 ;GCS4->DM9000 ;GCS5->CF Card ;GCS6->SDRAM ;GCS7->unused SMRDATA DATA ; Memory configuration should be optimized for best performance ; The following parameter is not optimized. ; Memory access cycle parameter strategy ; 1) The memory settings is? safe parameters even at HCLK=75Mhz. ; 2) SDRAM refresh period is for HCLK<=75Mhz. DCD (0+(B1_BWSCON<<4)+(B2_BWSCON<<8)+(B3_BWSCON<<12)+(B4_BWSCON<<16)+(B5_BWSCON<<20)+(B6_BWSCON<<24)+(B7_BWSCON<<28)) DCD ((B0_Tacs<<13)+(B0_Tcos<<11)+(B0_Tacc<<8)+(B0_Tcoh<<6)+(B0_Tah<<4)+(B0_Tacp<<2)+(B0_PMC))?? ;GCS0 DCD ((B1_Tacs<<13)+(B1_Tcos<<11)+(B1_Tacc<<8)+(B1_Tcoh<<6)+(B1_Tah<<4)+(B1_Tacp<<2)+(B1_PMC))?? ;GCS1 DCD ((B2_Tacs<<13)+(B2_Tcos<<11)+(B2_Tacc<<8)+(B2_Tcoh<<6)+(B2_Tah<<4)+(B2_Tacp<<2)+(B2_PMC))?? ;GCS2 DCD ((B3_Tacs<<13)+(B3_Tcos<<11)+(B3_Tacc<<8)+(B3_Tcoh<<6)+(B3_Tah<<4)+(B3_Tacp<<2)+(B3_PMC))?? ;GCS3 DCD ((B4_Tacs<<13)+(B4_Tcos<<11)+(B4_Tacc<<8)+(B4_Tcoh<<6)+(B4_Tah<<4)+(B4_Tacp<<2)+(B4_PMC))?? ;GCS4 DCD ((B5_Tacs<<13)+(B5_Tcos<<11)+(B5_Tacc<<8)+(B5_Tcoh<<6)+(B5_Tah<<4)+(B5_Tacp<<2)+(B5_PMC))?? ;GCS5 DCD ((B6_MT<<15)+(B6_Trcd<<2)+(B6_SCAN))??? ;GCS6 DCD ((B7_MT<<15)+(B7_Trcd<<2)+(B7_SCAN))??? ;GCS7 DCD ((REFEN<<23)+(TREFMD<<22)+(Trp<<20)+(Tsrc<<18)+(Tchr<<16)+REFCNT) DCD 0x32???? ;SCLK power saving mode,BANKSIZE 128M/128M DCD 0x30???? ;MRSR6 CL=3clk DCD 0x30???? ;MRSR7 CL=3clk BaseOfROM DCD |Image$$RO$$Base| TopOfROM DCD |Image$$RO$$Limit| BaseOfBSS DCD |Image$$RW$$Base| BaseOfZero DCD |Image$$ZI$$Base| EndOfBSS DCD |Image$$ZI$$Limit| ALIGN ; for entering power down mode ; 1. SDRAM should be in self-refresh mode. ; 2. All interrupt should be maksked for SDRAM/DRAM self-refresh. ; 3. LCD controller should be disabled for SDRAM/DRAM self-refresh. ; 4. The I-cache may have to be turned on. ; 5. The location of the following code may have not to be changed. ;void EnterPWDN(int CLKCON); EnterPWDN mov r2,r0? ;r2=rCLKCON tst r0,#0x8? ;SLEEP mode? bne ENTER_SLEEP ENTER_STOP ldr r0,=REFRESH ldr r3,[r0]? ;r3=rREFRESH mov r1,r3 orr r1,#BIT_SELFREFRESH str r1,[r0]? ;Enable SDRAM self-refresh mov r1,#16?? ;wait until self-refresh is issued. may not be needed. 0 subs r1,#1 bne %B0 ldr r0,=CLKCON? ;enter STOP mode. str r2,[r0] mov r1,#32 0 subs r1,#1 ;1) wait until the STOP mode is in effect. bne %B0? ;2) Or wait here until the CPU&Peripherals will be turned-off ;?? Entering SLEEP mode,only the reset by wake-up is available. ldr r0,=REFRESH ;exit from SDRAM self refresh mode. str r3,[r0] MOV_PC_LR ENTER_SLEEP ;NOTE. ;1) rGSTATUS3 should have the return address after wake-up from SLEEP mode. ldr r0,=REFRESH ldr r1,[r0]? ;r1=rREFRESH orr r1,#16?? ;Wait until self-refresh is issued,which may not be needed. 0 subs r1,#1 bne %B0 ldr r1,=MISCCR ldr r0,[r1] orr r0,#(7<<17)? ;Set SCLK0=0,SCLK1=0,SCKE=0. str r0,[r1] ldr r0,=CLKCON? ; Enter sleep mode str r2,[r0] b .?? ;CPU will die here. WAKEUP_SLEEP ;Release SCLKn after wake-up from the SLEEP mode. ldr r1,#(7<<17)? ;SCLK0:0->SCLK,SCKE:0->=SCKE. str r0,[r1] ;Set memory control registers ldr r0,=SMRDATA ;be careful!,=BWSCON ;BWSCON Address add r2,#52 ;Endaddress of SMRDATA 0 ldr r3,r0 bne %B0 mov r1,#256 0 subs 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 ;===================================================================== ; Clock division test ; Assemble code,because VSYNC time is very short ;===================================================================== EXPORT CLKDIV124 EXPORT CLKDIV144 CLKDIV124 ldr???? r0,= CLKDIVN ldr???? r1,= 0x3? ; 0x3 = 1:2:4 str???? r1,[r0] ; wait until clock is stable nop nop nop nop nop ldr???? r0,= REFRESH ldr???? r1,[r0] bic? r1,#0xff bic? r1,#(0x7<<8) orr? r1,#0x470 ; REFCNT135 str???? r1,[r0] nop nop nop nop nop mov???? pc,lr CLKDIV144 ldr???? r0,= 0x4? ; 0x4 = 1:4:4 str???? r1,#0x630 ; REFCNT675 - 1520 str???? r1,lr ALIGN AREA RamData,DATA,READWRITE ^?? _ISR_STARTADDRESS? ; _ISR_STARTADDRESS=0x33FF_FF00 HandleReset? #?? 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 theaddress 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 (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |