OpenEdv-开源电子网

 找回密码
 立即注册
正点原子全套STM32/Linux/FPGA开发资料,上千讲STM32视频教程免费下载...
查看: 4565|回复: 0

mini2440启动代码分析之第七篇(ResetHandler和存储控制寄存器初始化)

[复制链接]

79

主题

394

帖子

0

精华

金牌会员

Rank: 6Rank: 6

积分
1712
金钱
1712
注册时间
2015-9-21
在线时间
529 小时
发表于 2021-11-24 18:02:45 | 显示全部楼层 |阅读模式
LTORG       ;用于声明一个数据缓冲池,也叫文字池
;=============================================================================
上电和复位后,程序开始从位于0x0 执行b ResetHandler 程序跳转到这里执行,将看门狗,中断之类的程序关掉,以免打扰初始化程序的进行。
; ENTRY
;=============================================================================
ResetHandler
       ldr   r0,=WTCON       ;watch dog disable
       ldr   r1,=0x0
       str    r1,[r0]
;WTCON 为看门狗控制寄存器,此处将其写入0x0,就是禁止它的所有功能,包括定时器定时,溢出中断及溢出复位。
       ldr   r0,=INTMSK
       ldr   r1,=0xffffffff ;all interrupt disable
       str    r1,[r0]
;INTMSK 为中断屏蔽寄存器,写入0xffffffff,就是禁止所有的中断产生,因为中断向量表还未初始化,如果此时产生中断会使程序进入未知的状态而跑飞。因为外设的中断太多,INTMSK 不够用,还需要将子中断INTSUBMSK 来将剩余的中断源也禁止掉。
       ldr   r0,=INTSUBMSK
       ldr   r1,=0x7fff             ;all sub interrupt disable
       str    r1,[r0]
      [ {FALSE}                ;亮灯用的,可以用来调试用
             ;rGPFDAT = (rGPFDAT & ~(0xf<<4)) | ((~data & 0xf)<<4);
             ; Led_Display
              ldr   r0,=GPBCON
              ldr   r1,=0x155500
              str    r1,[r0]
              ldr   r0,=GPBDAT
              ldr   r1,=0x0
              str    r1,[r0]
       ]
       ;To reduce PLL lock time, adjust the LOCKTIME register.
       ldr   r0,=LOCKTIME                ;设置pll 锁定时间
       ldr   r1,=0xffffff
       str    r1,[r0]
;LOCKTIME PLL 锁定时间计数寄存器,重新设定分频值时,PLL 进入锁定,输出稳定频率的时钟需要一定的时间。这里设置成默认的值,以满足锁定的要求。
       [ PLL_ON_START     ;在option.inc中定义,初始化为真
              ; Added for confirm clock divide. for 2440为2440添加时钟设备.
              ; Setting value Fclk:Hclkclk
              ldr   r0,=CLKDIVN             ;用于设定FCLKHCLKPCLK的比例
              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.,在option.inc中有定义
              str    r1,[r0]
; MMU_SetAsyncBusMode and MMU_SetFastBusMode over 4K, so do not call here
; call it after copy
; [ CLKDIV_VAL>1   ; means Fclk:Hclk is not 1:1.
; bl MMU_SetAsyncBusMode
; |
; bl MMU_SetFastBusMode ; default value.
; ]
;三星手册里提供的MMU_SetAsyncBusMode 和 MMU_SetFastBusMode 函数都在4K代码以上(三星2440芯片就提供4K的内部SRAM),如果你想你编译出来的程序能在NAND上运行的话,就不能在这调用这两函数了.如果你不要求的话,你就可以直接调用.下面的代码就是实现和上面两函数一样的功能. 利用的协处理器的命令实现了对总线模式的设置
       ;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
              ]
;配置UPLL一定要使最后的频率为48MHz,不然你甭想用USB接口了, 先赔UPLL再配MPLL,不能颠倒了
              ;Configure UPLL
              ldr   r0,=UPLLCON
              ldr   r1,=((U_MDIV<<12)+(U_PDIV<<4)+U_SDIV)          ;Fin = 12.0MHz, UCLK = 48MHz
              str    r1,[r0]
              nop       ;UPP 设定之后,必须等待7 个时钟的延迟,设定才会有效(因为5级流水线,搞不懂)
              nop
              nop
              nop
              nop
              nop
              nop
;Configure MPLL,设置MPLL, 2440主频可达400MHz
              ldr   r0,=MPLLCON
              ldr   r1,=((M_MDIV<<12)+(M_PDIV<<4)+M_SDIV)         ;Fin = 12.0MHz, FCLK = 400MHz
              str   r1,[r0]
       ]
;查看是否是由睡眠状态启动,如果是则跳转到WAKEUP_SLEEP状态
;Check if the boot is caused by the wake-up from SLEEP mode.
       ldr   r1,=GSTATUS2
       ldr   r0,[r1]
       tst    r0,#0x2    ;In case of the wake-up from SLEEP mode, go to SLEEP_WAKEUP handler.
       bne  WAKEUP_SLEEP
       EXPORT StartPointAfterSleepWakeUp
StartPointAfterSleepWakeUp
;初始化内存控制器其实就是对S3C2440 memory bank 进行设置,使其扩展的存储器或外部设备能够被处理器通过内存控制器正确读写。由于S3C2440 的最终应用程序是在SDRAMbank6)中运行,并与C 语言变量等的用户数据,各种模式的堆栈,中断向量表,都被定位在SDRAM 的空间,所以它必须在涉及这些处理之前完成初始化工作。
      ;Set memory control registers,设置存储器控制寄存器,SMRDATA中涉及的值请参考memcfg.inc程序
      ;ldr  r0,=SMRDATA
      adrl  r0, SMRDATA       ;be careful!不要用错,adr装载相对地址,ldr装载绝对地址,ro是数据区起始地址
       ldr   r1,=BWSCON       ;BWSCON Address,BWSCON地址,r1是寄存器的起始地址
       add  r2, r0, #52            ;End address of SMRDATA,SMRDATA结束地址,r2是数据区结束地址
0
       ldr   r3, [r0], #4
       str    r3, [r1], #4
       cmp r2, r0
       bne  %B0
;这段是功能寄存器初始化,把13 个存储控制器的内容批量的读取到了对应的特殊功能寄存器中,首先是下面有一个数据区SMRDATA,在程序的后面有定义,这个数据区给13 个寄存器分配52 字节的地址空间。在上面的代码中,r0 是这个数据区的起始地址,r2 是数据区的结束地址,r1 是寄存器的起始地址。这样,用一个判断语句就可以把内存中的数据赋给这13 个存储控制寄存器了。


正点原子逻辑分析仪DL16劲爆上市
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则



关闭

原子哥极力推荐上一条 /2 下一条

正点原子公众号

QQ|手机版|OpenEdv-开源电子网 ( 粤ICP备12000418号-1 )

GMT+8, 2024-5-29 08:20

Powered by OpenEdv-开源电子网

© 2001-2030 OpenEdv-开源电子网

快速回复 返回顶部 返回列表