一、Mini2440地址空间

1.1 存储器控制器介绍

在之前的文章中,我们已经介绍过S3C2440自带4KB SRAM和2MB的NOR FALSH。片内4KB的内存其实是很小,为了能够运行操作系统和更大的应用程序,需要在处理器存储接口上进行扩展,如SDRAM、SRAM、ROM、FLASH等。ARM提供一个存储管理器部件,为访问外部存储设备提供存储地址信号和控制信号,即存储器控制器。

1.2 存储器控制器作用

CPU在执行指令时候,CPU只会发出指令从某个地址读数据,此时存储器控制器会根据地址判断时什么设备,并负责数据操作,把CPU想操作的数据反馈给CPU。

比如指令:

COUNT ADDR 0x30000000    
MOV R1,=ADDR      ;R0=0x30000000
LDR R0,[R1]           ;R0=*R1  加载到寄存器

从内存地址0x30000000处读取4个字节的值,写入寄存器R0。存储器控制器根据地址0x30000000知道这是片内SDRAM,然后发出nGCS6片选信号。

访问一个存储芯片,正来说需要具备以下条件:

  • 地址线;
  • 数据线;
  • 时钟频率;
  • 芯片相关特性;

1.3 地址空间分布

S3C2440对外引出了27位地址线ADDR0~ADDR26,32位数据线,最多能够寻址128MB。而S3C2440的寻址空间可以达到1GB,这是由于S3C2440将1GB的地址空间分成了8个BANKS(Bank0~Bank7),其中每一个BANK对应一根片选信号线nGCS0~nGCS7,当访问BANKx的时候,nGCSx管脚电平拉低,用来选中外接设备, S3C2440通过8根选信号线和27根地址线,就可以访问1GB。CPU系统上电将从bank0开始执行。

空间分布图如下: Bank0-Bank7的地址范围如下:

  • 0x00000000-0x3FFFFFFF:Bank0-Bank7;
  • 0x4000 0000-0x47FF FFFF :根据启动方式不同,作用不同;
  • 0x4800 0000-0x5FFF FFFF:特殊功能寄存器;
  • 0x6000 0000-0xFFFF FFFF;未被使用;

S3C2440是32位CPU,可以使用的地址范围理论达到4GB,除去上面连接外设的1GB空间外,还有一部分是CPU内部寄存器的地址,剩下的地址空间没有使用。

Mini2440裸机开发之存储器控制器_数据

1.4 SDRAM工作原理

我们观察S3C2440内存空间分布图,我们可以发现Bank0~Bank5可以焊接ROM或SRAM类型存储器,Bank6~Bank7可以焊接ROM,SRAM,SDRAM类型存储器,也就是说,S3C2440的SDRAM内存应该焊接在Bank6~Bank7上,最大支持内存256M,Bank0~Bank5通常焊接一些用于引导系统启动小容量ROM,具体焊接什么样存储器,多大容量,根据每个开发板生产商不同而不同。

SDRAM的内部是一个存储阵列。阵列就如同表格一样,将数据“填”进去。在数据读写时和表格的检索原理一样,先指定一个行(Row),再指定一个列(Column),我们就可以准确地找到所需要的单元格,这就是内存芯片寻址的基本原理,如图所示。

Mini2440裸机开发之存储器控制器_列地址_02

这个单元格(存储阵列)就叫逻辑 Bank(Logical Bank,下文简称 L-Bank)。 由于技术、成本等原因,不可能只做一个全容量的 L-Bank,而且最重要的是,由于SDRAM的工作原理限制,单一的 L-Ban k将会造成非常严重的寻址冲突,大幅降低内存效率。所以人们在 SDRAM内部分割成多个 L-Bank,目前基本都是 4个(这也是SDRAM规范中的最高L-Bank数量),由此可见,在进行寻址时就要先确定是哪个 L-Bank,然后在这个选定的 L-Bank中选择相应的行与列进行寻址。因此对内存的访问,一次只能是一个 L-Bank工作。

当对内存进行操作时,先要确定操作L-Bank,因此要对L-Bank进行选择。在内存芯片的外部管脚上多出了两个管脚BA0, BA1,用来片选4个L-Bank。

如前所述, 32位的地址长度由于其存储结构特点,分成了行地址和列地址。以Mini2440开发板为例:将两片32MB,16位宽SDRAM内存(型号HY57V561620FTP)焊接在Bank6,并联形成64M,32位内存。通过下面的内存原理图可知:

Mini2440裸机开发之存储器控制器_列地址_03

内存外接管脚地址线只有13根地址线A0~A12,它最多只能寻址8M内存空间,到底使用什么机制来实现对64M内存空间进行寻址的呢?

SDRAM的行地址线和列地址线是分时复用的,即地址要分两次送出,两次送到芯片上去的地址分别称为行地址和列地址。它们被锁存到芯片内部的行地址锁存器和列地址锁存器。这样,可以大幅度减少地址线的数目,提高器件的性能和制作工艺复杂度。

  • 先送出行地址,行地址使用A0~A12(13条)(nSRAS是行地址锁存信号,该信号将行地址锁存在芯片内部的行地址锁存器中);
  • 再送出列地址,列地址使用A0~A8(9条)(nSCAS是列地址锁存信号,该信号将列地址锁存在芯片内部的列地址锁存器中);

实际上,现在的SDRAM一般都以L-Bank为基本寻址对象的。由L-Bank地址线BA1~BA0控制L-Bank间的选择:

  • BA0-BA1是bank选择引脚。(Bank选择与行地址(row address)同时下发,在列地址下发时,有其他用途)。

13+9+2=24,相当于24个地址,每个地址2个字节,内存大小2^25=32MB。

需要注意的是LADDR2接的引脚是A0,这是因为一个地址对应4个字节,32位数据位宽。

BA0,BA1ADDR24,ADDR25,为什么用这两根地址线呢?

  • BA0~BA1代表了SDRAM的最高地址位。因为CPU的寻址空间是以字节(byte)为单位的,本系统SDRAM容量为64MB,那就需要A25~A0(64M=2^26)地址线来寻址,所以BA1~BA0地址线应该接到S3C2440的ADDR25~ADDR24引脚上。

左侧DQ0~DQ15接接LDATA0~LDATA15,右侧DQ0~DQ15接接LDATA16~LDATA31,共计数据宽度为32位。

当地址线发出地址位0x33FFFFFC,二进制位0011 0011 1111 1111 1111 1111 1111 1100,存储器控制器会发出nGCS6(与nGCS0同一引脚)片选信号,

nGCS6片选   ADDR27 ADDR26 ADDR25 ADDR24   ADDR23 ADDR22 ADDR21 ADDR20   ADDR19 ADDR18 ADDR17 ADDR16
0 0 1 1   0 0 1 1   1 1 1 1   1 1 1 1
              BA1 BA0   A12 A11 A10 A9   A8 A7 A6 A5

 

   ADDR15 ADDR14  ADDR13   ADDR12    ADDR11  ADDR10 ADDR9  ADDR8    ADDR7   ADDR6 ADDR5  ADDR4    ADDR3 ADDR2  ADDR1  ADDR0 
  1 1 1 1   1 1 1 1   1 1 1 1   1 1 0 0
  A4 A3 A2 A1   A0 A8 A7 A6   A5 A4 A3 A2   A1 A0    

所以当行地址A0~A12全部位1,列地址A0~A8全部位1,BA0~BA1可以访问SDRAM最高内存地址,一次取出32位数据,对应0x33FFFFFC~0x33FFFFFF。

SDRAM地址空间:0x30000000~0x33FFFFFF;

二、SDRAM读写操作

2.1 SDRAM读操作

Mini2440裸机开发之存储器控制器_寄存器_04

  • CPU发出片选信号nSCS0(与nGCS6是同一引脚)有效,选中SDRAM芯片;
  • 对被选中的芯片进行同一的行/列(存储单元)寻址:
    • 根据SDRAM芯片的列地址线数目设置CPU相关寄存器后,CPU会从32位地址中自动分出L-BANK选择信号、行地址信号、列地址信号,然后先后发出行地址信号、列地址信号。
    • 确定Bank,通过ADDR24、ADDR25信号线选定,总共4个Bank;
    • 确定行地址:A0~A12地址线发送具体的行地址,共有13根地址线(可表示8192行),A0~A12的不同数值就确定了具体的行地址;
    • 确定列地址:行地址确定之后,就要对列地址进行寻址了,行地址与列地址线是复用的。列地址复用了A0~A8,共9根(可表示512列);
  •  找到存储单元后,被选中的芯片就要进行统一的数据传输;

在地址线上送完行地址之后,要等到行地址稳定定位后再送出列地址,这个间隔被定义为 tRCD,即RAS to CAS Delay(RAS至 CAS延迟),tRCD是SDRAM的一个重要时序参数,相关数值参看对应芯片硬件手册。通常tRCD以时钟周期(tCK,Clock Time)数为单位,比如Mini2440所用内存芯片里面写到tRCD为20ns,如果内存工作在100MHz,那么RCD至少要为2个时钟周期, RCD=2。

在列地址选通信号CAS 发出之后,仍要经过一定的时间才能有数据输出,从CAS与到第一笔数据输出的这段时间,被定义为 CL(CAS Latency,CAS潜伏期)。

三、寄存器

存储控制器一共有13个寄存器,6种寄存器,对BANK0~BANK5进行访问时,只需要配置BWSCON和BANKCONx寄存器,但是对SDRAM访问,不仅仅需要对这俩个寄存器进行配置,还需要额外配置4个寄存器。

3.1 总线宽度和等待控制寄存器(BWSCON)

寄存器信息:

寄存器 地址 R/W 描述 复位值
BWSCON 0x48000000 R/W 总线宽度和等待控制寄存器 0x000000

寄存器位信息:

BWSCON 描述 初始状态
ST7 [31]

决定SRAM 是否对Bank 7 使用UB/LB

0 = 未使用UB/LB(引脚对应nWBE[3:0]) 1 = 使用UB/LB(引脚对应nBE[3:0])

0
WS7 [30]

决定Bank 7 的WAIT 状态

0 = WAIT 禁止 1 = WAIT 使能

0
DW7 [29:28]

决定Bank 7 的数据总线宽度

00 = 8 位 01 = 16 位 10 = 32 位 11 = 保留

0
ST6 [27]

决定SRAM 是否对Bank 6 使用UB/LB

0 = 未使用UB/LB(引脚对应nWBE[3:0]) 1 = 使用UB/LB(引脚对应nBE[3:0])

0
WS6 [26]

决定Bank 6 的WAIT 状态

0 = WAIT 禁止  1 = WAIT 使能

0
DW6 [25:24]

决定Bank 6 的数据总线宽度

00 = 8 位  01 = 16 位  10 = 32 位  11 = 保留

0

ST5

[23]

决定SRAM 是否对Bank 5 使用UB/LB

0 = 未使用UB/LB(引脚对应nWBE[3:0]) 1 = 使用UB/LB(引脚对应nBE[3:0])

0

 

WS5 [22]  决定Bank 5 的WAIT 状态

0 = WAIT 禁止 1 = WAIT 使能

 0
DW5 [21:20] 决定Bank 5 的数据总线宽度

00 = 8 位 01 = 16 位 10 = 32 位 11 = 保留

 0

ST4

[19] 决定SRAM 是否对Bank 4 使用UB/LB

0 = 未使用UB/LB(引脚对应nWBE[3:0]) 1 = 使用UB/LB(引脚对应nBE[3:0])

 0

WS4

[18] 决定Bank 4 的WAIT 状态

0 = WAIT 禁止 1 = WAIT 使能

 0
DW4 [17:16]  决定Bank 4 的数据总线宽度

00 = 8 位 01 = 16 位 10 = 32 位 11 = 保留

 0
ST3 [15]  决定SRAM 是否对Bank 3 使用UB/LB

0 = 未使用UB/LB(引脚对应nWBE[3:0]) 1 = 使用UB/LB(引脚对应nBE[3:0])

 0
WS3 [14] 决定Bank 3 的WAIT 状态

0 = WAIT 禁止 1 = WAIT 使能

 0
DW3 [13:12] 决定Bank 3 的数据总线宽度

00 = 8 位 01 = 16 位 10 = 32 位 11 = 保留

 0
ST2 [11]  决定SRAM 是否对Bank 2使用UB/LB

0 = 未使用UB/LB(引脚对应nWBE[3:0]) 1 = 使用UB/LB(引脚对应nBE[3:0])

 0
WS2 [10] 决定Bank 2 的WAIT 状态

0 = WAIT 禁止 1 = WAIT 使能

 0
DW2 [9:8] 决定Bank 2 的数据总线宽度

00 = 8 位 01 = 16 位 10 = 32 位 11 = 保留

 0
ST1 [7]  决定SRAM 是否对Bank 1使用UB/LB

0 = 未使用UB/LB(引脚对应nWBE[3:0]) 1 = 使用UB/LB(引脚对应nBE[3:0])

 0
WS1 [6] 决定Bank 1 的WAIT 状态

0 = WAIT 禁止 1 = WAIT 使能

 0
DW1 [5:4] 决定Bank 1 的数据总线宽度

00 = 8 位 01 = 16 位 10 = 32 位 11 = 保留

 0
DW0 [2:1]

表明Bank 1 的数据总线宽度(只读)

01 = 16位 10 =32位

该状态由OM[1:0]引脚决定

 -
保留 [0]  保留为0  0
  • ST6:决定是否使用SDRAM的数据掩码,对SDRAM时为0,对SRAM时为1。
  • WS6:决定是否使用WAIT信号,一般不使用。(WAIT信号就是在SDRAM没准备好的时候,由SDRAM发给CPU,请求延迟一段时间)
  • DW6:决定BANK位宽,自然是32位。

所以,BWSCON寄存器要或运算的值为:0x02000000。

3.2 BANK 控制寄存器(BANKCONn:nGCS0 至nGCS5)

寄存器信息:

 

寄存器 地址 R/W 描述 复位值
BANKCON0 0x48000004 R/W Bank0 控制寄存器 0x0700
BANKCON1 0x48000008 R/W Bank1 控制寄存器 0x0700
BANKCON2 0x4800000C R/W Bank2 控制寄存器 0x0700
BANKCON3 0x48000010 R/W Bank3 控制寄存器 0x0700
BANKCON4 0x48000014 R/W Bank4 控制寄存器 0x0700
BANKCON5 0x48000018 R/W Bank5 控制寄存器 0x0700

寄存器位信息:

BANKCONn 描述 初始状态
Tacs [14:13]

nGCSn 前的地址建立时间

00 = 0 个时钟 01 = 1个时钟
10 = 2 个时钟 11 = 4 个时钟

00
Tcos [12:11]

nOE 前的片选建立时间

00 = 0 个时钟 01 = 1个时钟
10 = 2 个时钟 11 = 4 个时钟

00
Tacc [10:8]

访问周期

000 = 1 个时钟 001 = 2 个时钟
010 = 3 个时钟 011 = 4 个时钟
100 = 6 个时钟 101 = 8 个时钟
110 = 10 个时钟 111 = 14 个时钟

注意:当使用nWAIT 信号时,Tacc ≥ 4 个时钟

111
Tcoh [7:6]

nOE 后的片选保持时间

00 = 0 个时钟 01 = 1个时钟
10 = 2 个时钟 11 = 4 个时钟

00
Tcah [5:4]

nGCSn 后的地址保持时间

00 = 0 个时钟 01 = 1个时钟
10 = 2 个时钟 11 = 4 个时钟

00
Tacp [3:2]

Page 模式下的Page 模式访问周期

00 = 0 个时钟 01 = 1个时钟
10 = 2 个时钟 11 = 4 个时钟

00

PMC

[1:0]

Page 模式配置

00 = 正常(1个数据) 01 = 4个数据
10 = 8 个数据 11 = 16 个数据

00

 

3.3 BANK 控制寄存器(BANKCONn:nGCS6 至nGCS7)

寄存器信息:

寄存器 地址 R/W 描述 复位值
BANKCON6 0x4800001C R/W Bank6 控制寄存器 0x18008
BANKCON7 0x48000020 R/W Bank7 控制寄存器 0x18008

寄存器位信息:

BANKCONn 描述 初始状态
MT [16:15]

决定Bank6 和Bank7 的存储器类型

00 = ROM或SRAM  01 = 保留(不要使用)
10 = 保留(不要使用) 11 = SDRAM

 11

存储器类型 = ROM 或SRAM [MT=00]

Tacs [14:13]

nGCSn 前的地址建立时间

00 = 0 个时钟 01 = 1个时钟
10 = 2 个时钟 11 = 4 个时钟

00
Tcos [12:11]

nOE 前的片选建立时间

00 = 0 个时钟 01 = 1个时钟
10 = 2 个时钟 11 = 4 个时钟

00
Tacc [10:8]

访问周期

000 = 1 个时钟 001 = 2 个时钟
010 = 3 个时钟 011 = 4 个时钟
100 = 6 个时钟 101 = 8 个时钟
110 = 10 个时钟 111 = 14 个时钟

111
Tcoh [7:6]

nOE 后的片选保持时间

00 = 0 个时钟 01 = 1个时钟
10 = 2 个时钟 11 = 4 个时钟

00
Tcah [5:4]

nGCSn 后的地址保持时间

00 = 0 个时钟 01 = 1个时钟
10 = 2 个时钟 11 = 4 个时钟

00
 Tacp  [3:2]  

Page 模式下的Page 模式访问周期

00 = 2 个时钟 01 = 3个时钟
10 = 4 个时钟 11 = 6 个时钟

 00
 PMC  [1:0]  

Page 模式配置

00 = 正常(1个数据) 01 = 4个数据
10 = 8 个数据 11 = 16 个数据

 00
存储器类型 = SDRAM [MT=11]
Trcd [3:2]

RAS 到CAS 的延迟

00 = 2 个时钟 01 = 3 个时钟 10 = 4 个时钟

00

SCAN

[1:0]

列地址数

00 = 8 位 01 = 9 位 10 = 10 位

00

 

对于SDRAM的访问,我们需要配置的就是图中蓝色标注地方:

  • MT:决定BANK外接的是SDRAM还是SRAM,SDRAM选择11;

  • Trcd:行列信号之间的延迟时间,根据芯片手册得知最小为20ns,而我们的HCLK时钟为100MHz,一个clock 10ns,所以保险起见选择01,3个时钟;

Mini2440裸机开发之存储器控制器_行地址_05

  •  SCAN:设置列地址位,这里使用的SDRAM列地址一共9位,所以为:01;

所以,BANKCON6寄存器要或运算的值为:0x00018005。

3.4 刷新控制寄存器

刷新控制寄存器,用来控制SDRAM的刷新模式和刷新频率。我们知道,SDRAM中的存储阵列需要不断的刷新来保证数据不丢失,所以就要配置刷新控制寄存器。

寄存器信息:

寄存器 地址 R/W 描述 复位值
REFRESH 0x48000024 R/W SDRAM 刷新控制寄存器 0xAC0000

寄存器位信息:

REFRESH 描述 初始状态
REFEN [23]

SDRAM 刷新使能

0 = 禁止  1 = 使能(自或CBR/自动刷新)

 1
TREFMD [22]

SDRAM 刷新模式

在自刷新期间,驱动SDRAM 控制信号为适当电平

0
Trp [21:20]

SDRAM RAS 预充电时间

00 = 2 个时钟 01 = 3 个时钟
10 = 4 个时钟 11 = 不支持

10
Tsrc [19:18]

SDRAM 半行周期时间

00 = 4 个时钟 01 = 5 个时钟
10 = 6个时钟 11 = 7个时钟
SDRAM 行周期时间:Trc=Tsrc+Trp
如果Trp=3 个时钟并且Tsrc=7 个时钟,则Trc=3+7=10 个时钟

11
保留 [17:16]

未使用

00
保留 [15:11]  未使用 0000
刷新计数器 [10:0] SDRAM刷新计数值。 参阅第6 章SDRAM刷新控制器总线优先级部分。

$$refresh_period = (2^11 - refrest_count + 1) / HCLK$$
例. 如果刷新周期为7.8 μs 并且HCLK 为100 MHz,刷新计数如下:
$$refrest\_count  = 2^{11} + 1 - 100 × 7.8 = 1269$$

0
  • REFEN:决定使能刷新功能,当然是开启了,值为:1;
  • TREFMD:刷新的模式,一般自动刷新,值为:0;
  • Trp:根据芯片手册得知20ns,对应2个时钟,值为:00;
  • Tsrc:默认即可;
  • Refresh Counter:刷新计数的值,查SDRAM的手册可得8192个刷新周期为64ms,则每一个刷新周期为$64*10^6/8192/1000=7.8125μs$,如果内存工作在100MHz下,那么通过公式计算可得:

$$refrest\_count  =2^{11}+1-100*7.8125=1269(取大整数)$$

Mini2440裸机开发之存储器控制器_寄存器_06

所以,REFRESH寄存器要或运算的值为:0x8e0000 + 1269 = 0x008e04f5(HCLK = 100MHz)

3.5 Bank 大小寄存器

寄存器信息:

寄存器 地址 R/W 描述 复位值
BANKSIZE 0x48000028 R/W 可变Bank 大小寄存器 0x00

寄存器位信息:

BANKSIZE 描述 初始状态
BURST_EN [7]

ARM 核突发(Burst)操作使能

0 = 禁止突发操作 1 = 使能突发操作

 0
保留 [6]

未使用

0
SCKE_EN [5]

SDRAM 省电模式使能SCKE 控制

0 = 禁止SDRAM省电模式  1 = 使能SDRAM省电模式

0
SCLK_EN [4]

只在SDRAM访问周期期间SCLK使能,以降低功耗。当未访问SDRAM,SCLK变为低电平

0 = SCLK一直有效  1 = SCLK 只在访问期间有效(推荐)

0
保留 [3]

未使用

0
BK76MAP [2:0]

Bank6/7 存储器映射

010 = 128MB/128MB 001 = 64MB/64MB
000 = 32M/32M 111 = 16M/16M
110 = 8M/8M 101 = 4M/4M

100 = 2M/2M

010

设置内存的突发传输模式,省电模式和内存容量。

  • BURST_EN:决定是否允许突发操作,值为:1;
  • SCKE_EN:决定是否使用SCKE信号来决定省电模式,值为:1;
  • SCLK_EN:决定SCLK时钟信号的产生模式,值为:1;
  • BK76MAP:决定BANK6、BANK7的大小,这里SDRAM是64M,所以值为:001;

所以,BANKSIZE寄存器要或运算的值为:0x000000b1

3.6 SDRAM 模式 寄存器组寄存器(MRSR)

寄存器信息:

寄存器 地址 R/W 描述 复位值
MRSRB6 0x4800002C R/W 模式寄存器组寄存器Bank6 xxx
MRSRB7 0x48000030 R/W 模式寄存器组寄存器Bank7 xxx

寄存器位信息:

MRSR 描述 初始状态
保留 [11:10]

未使用

-
WBL [9]

写突发长度

0 = 突发(固定) 1 = 保留

x
TM [8:7]

测试模式
00 = 模式寄存器组(固定) 01 = 保留
00 = 保留 00 = 保留

xx
CL [6:4]

CAS 等待时间(latency)
000 = 1个时钟 010 = 2个时钟
011 = 3 个时钟 其它 = 保留

xxx
BT [3]

突发类型
0 = 连续(固定) 1 = 保留

x
BL [2:1] 突发长度

000 = 1(固定) 其它 = 保留

xxx 
该寄存器用于设置CAS潜伏周期,可以手动设置的位只有CL[6:4]位,查询芯片手册设置CL=3,即0b011,MRSR6,MRSR7设置为:0x00000030.
Mini2440裸机开发之存储器控制器_引脚_07

注意:

  • 当代码在SDRAM 中运行时一定不要改变MRSR 寄存器。

重要注意:

  • 睡眠模式中,SDRAM 必须使能SDRAM 自刷新模式。

参考文章

[1]02-JZ2440裸机学习之存储管理器

[2]s3c2440存储控制器详解

[3]S3C2440—8.读写SDRAM

[4]HY57V561620FTP-H