内存初始化

内存分类:
DRAM:它的基本原件是小电容,电容可以在两个极板上保留电荷,但是需要定期的充电(刷新),否则数据会丢失。缺点:由于要定期刷新存储介质,存取速度慢。
SRAM:静止存取功能的内存,不需要定期刷新电路就能保存它内部存储的数据,优点:存取速度快,缺点:功耗大,成本高。用于stepping stone.
DRAM:SDRAM(同步(内存工作需要同步时钟,数据的传输都以该时钟为基准。)动态随机存储器2440),DDR(双倍速率同步动态随机存储器6410),DDR2(210)
------------------------------------------------------
内存内部结构:内存的内部结构如图表格,数据就存储在每个单元格中,数据存储是先提供L-Bank的选择信号,行号,在指定列号,我们就可以找到单元格了。
一个内存芯片通常会分为4个L-Bank.
-------------------------------------------------
推到内存容量的计算公式:4*L-Bank*单元格数目*每个单元格容量。接下来打开一个芯片的手册:如4Bank*4M*16Bit=32Mb
2440内存初始化:
2440地址空间:我们发现2440的芯片共有27根地址线,意味着它可以访问2^27=128M的地址空间。我们知道这个地址空间是非常小的,那么我们需要通过一种方式让它的地址空间变大。这里使用了片选信号:
片选信号:通过发送片选信号,是的27根地址线旋转,然后可以指定的访问不同的芯片。S3C2440有8个片选信号,因此他可以转向八个不同的芯片。因此他可以访问的空间达到了8*128M(但同时只能选择一个NGC0) OK6419核心板原理手册:p
------------------------------------------------------
S3C2440手册p194页,我们可以看到S3C2440芯片的一个片选分布图。
存储控制器:就是需要访问的内存转化成Bank号,行号,列号。
初始化内存就是编写代码初始化存储控制器。只有将它初始化后我们才能访问相应的内存芯片。
------------------------------------------------
内存芯片与开发板芯片的硬件连接:4*4*16
16bit有两层含义:一是:单元格的容量为16bit,二是数据宽度为16
但查看芯片手册我们知道2440是32位数据线的,这样的话就有16位数据线浪费了,所以这里采用的是将2440,同时连在两个16位的内存芯片上。
存储控制寄存器:主要是控制对外设的访问,
--------------------------------------
设置2440的存储控制器:翻到S3C2440p206页。很快我们就看到了我们要设置的第一个寄存器:BWSCON:主要用来设置总线宽度和等待状态控制。
这个寄存器主要是用来设置bank的,从芯片手册上我们可以看到并没有使用UB/IB,所,
31wei:ST7设置为0,
30wei,WS7(是否使能等待状态)通常不使用,设为0.
29位,28位,DW7(决定数据总线的宽度)为32位,设为10
其他类似设置。0010 0010 0000 0000 0000 0000 0000 0000其他因为暂时不要,所以保持默认值。0x22000000
接下来我们发现有6组BANKCON0,1,..寄存器:对于这六组寄存器我们保持它的默认值就可以了。0x00000700*6
----------------------------------------------------
接下来是BANK6和BANK7寄存器的设置:
15,16wei:MT(在BANK6,7中内存的类型):我们知道类型为Sync.DRAM,这里我们设置为11.
接下来的这些为分为两种情况:ROM和SDRAM这里我们使用的是SDRAM
所以我们只需要设置4位。
1 0100 0000 0000 0001
2,3wei:Trcd(行列选择信号的延时)往上看时序图p205,这里选择的是两个时钟,设为00
0,1wei:SCAN(列地址的数目),从内存芯片手册上我们知道这里是9位。设为01.0x00018001*2
-------------------------------------------------------
接下来的一个寄存器是REFRESH:(用于SDRAM refresh )
23wei:REFEN(是否要刷新)这里选择是,这位1
22wei:TREFMD(选择刷新模式)这里选择自动刷新,设为0
20,21wei:Trp(选择充电时间)找到时序图,这里为两个时钟,设为00
18,19wei:tsrc(进行一次刷新的时间)通常为7个时钟,设为11
16,17wei:00
11..15:00000
0-10:刷新周期()Refresh period = (2^11-refresh_count+1)/HCLKEx).HCLK是用来控制内存时钟的。这里取1269徐转成16进制。0x008c04f5
----------------------------------------------------
接下来是BANKSIZE:
7wei:BURST_EN(ARM核的突发操作(访问内存的时候是否可以批量使用数据)是否使能)这里选择enable,设为1
6wei:0
5wei:是否使用节电模式,是,设为1
4wei:这里设为recommended 即设为1
3wei:不用,设为0
0-2:设置bank6,7memory,这里是64M,001
0xb1
---------------------------------------------------
接下来是:MRSRRB6 MRSRRB7设置bank6,7模式的register
这里只需要设置4-6wei:CL(CAS信号的潜伏期(latency)),看到时序图中,找到NSCAS:潜伏期指的是nSRAS的低电平-》nSCAS的低电平的时钟;这里为3个:设为:011000
0x30*2
-----------------------------------------------
手把手带你写代码:
bl init_sdram
bl light_led
#define mem_contrl 0x48000000
init_sdram:
ldr r0,=mem_contrl //设定初值
add r3,r0,#4*13 //循环结束值
adrl r1,mem_data //装载长地址
@循环设置
0:
ldr r2,[r1],#4 //将r1装载到r2,再将r1移动4位
str r2,[r0],#4 //将r2中的信息存放到r0中
cmp r0,r3 //比较r0,r3的大小
bne 0b //如果不等,跳转到0处b("before")

mov pc,lr
mem_data: //类似数组
.long 0x22000000
.long 0x00000700
.long 0x00000700
.long 0x00000700
.long 0x00000700
.long 0x00000700
.long 0x00000700
.long 0x00018001
.long 0x00018001
.long 0x008c04f5
.long 0x000000b1
.long 0x00000030
.long 0x00000030
-----------------------------------------------------------
6410:
地址空间:6410用于32位的地址总线,寻址空间为4G,其中高2G为保留区(0x80000000-0xfffffff),低2G区域分为主存储区(1972,0x0000000-0x6fffffff),外设区(256,0x70000000-0x7fffffff).
外设区:
主存储区:
1.boot镜像区(0x00000000-0x07ffffff):这个区域不会固定的去关联某个硬件,当选择某个硬件进行启动的时候,它会把个硬件映射到这个区域来。
2.内部存储区(0x07ffffff-0x0fffffff,128M):包含stepping stone 等。
3.静态存储区:可以用来接nor flash one nand6*128分为了6个bank.
4.动态存储区(内存的起始地址0x50000000):DDR的就是放在了动态存储区。
---------------------------------------------
内存芯片连接(使用的是2片128M的内存芯片):
内存控制器的初始化:S3C6410X:p192页5.4.1描述了SDRAM初始化的流程。
1.向Memc_cmd中写入3位100,使DRAM控制器进入config状态。p193
2.想一系列寄存器(参数时序,芯片配置,id配置)中写入参数
3.等待200us,这一步可以省略。
4.执行内存(DDR)的初始化。5.4.3
5.将存储控制器设置到ready state
6.检查memory status 是否设置为b01,如果是则存储控制器为ready状态。
----------------------------------------------------
下面我们来看一段内存初始化能正常工作的代码:cpu->s3c64xx->
s3c6410->cpu_init.S
bl mem_init
bl light_led
更改makefile
vi makefile
all : mem.o
touch mem.S
vim mem.S
.text
.global mem_init
mem_init:
@向memc_cmd中写入0b100
ldr r0,=0x7e00104
mov r1,0x4
str r1,[r0]
@different register set
....
@内存序列的设置5.4.3
ldr r0,=0x7e00108
mov r1,0xc0000 @发出一个nop的指令,将第19,18位设置为0b11
str r1,[r0]
@issue prechangeall
ldr r0,=0x7e00108
mov r1,0x0
str r1,[r0]
@issue autorefresh
ldr r0,=0x7e00108
mov r1,0x4
str r1,[r0]
ldr r0,=0x7e00108
mov r1,0x4
str r1,[r0]
@参考u-boot写的,内存初始化的第五,六步。
ldr r0,=0x7e00108
mov r1,0x0a0000
str r1,[r0]

ldr r0,=0x7e00108
mov r1,0x80032
str r1,[r0]
@将DRAM控制器设置为准备状态。
ldr r0,=0x7e001004
mov r1,0x0
str r1,[r0]
@check ready
check_ready:
ldr r0,0x7e001000
ldr r1,[r0]
mov r2,#0x3
and r1,r1,r2
cmp r1,#0x1
bne check_ready
mov pc,lr
我们查看u-boot代码,发现第一步我们是没有做的。在手册上find"MEM_SYS_CFG"p160页,这里我们主要看他的第七位(设置xml引脚是否作为数据线,0 = Xm1DATA[16:31] pins are used for DMC1 upper halfword,1 = Xm1DATA[16:31] pins are used for SROMC upper 11-bit address field, address[26:16]. ):这里我们将这位设置为0,作为DMC的数据线来使用。
在最前面加上:
@set data pin
ldr r0,=0x7e00f120
mov r1,#0x0
str r1,[r0]

 

posted @ 2015-08-24 20:24  高傲的monkey  阅读(2191)  评论(0编辑  收藏  举报