把代码从steppingstone拷贝到sdram中运行,大小为4kb
学习存储器寄存器的配置。
参考s3c2440和sdram的datasheet,很容易地把寄存器配置好,就可以使用SDRAM了
存储控制器的寄存器总共有13个:SWSCON, BANKCONx (x=0~7), REFRESH, BANKSIZE, MRSRB6, MRSRB7
SDRAM只需配置好SWSCON, BANKCON6,, BANKCON7, REFRESH, BANKSIZE, MRSRB6, MRSRB7, 一共7个寄存器
1.BWSCON位宽和等待控制寄存器
每4位控制一个BANK。最高4位控制bank7,递减类推。
STx: 内存为SDRAM,此位为0,SRAM的为1
WSx:通常设为0
DWx:用两位来设置位宽,0b00为八位,0b01为16位,0b10为32位,0b11为保留
我的开发板上是MT48LC16M16A2P型号的16位SDRAM,由2片组成32为的SDRAM,所以我设置的高4位为0b0010,。BANK6与BANK7的设置需相
同,不管你用不用到BANK7,所以这里设子和为BWSCON=0x22000000
BANKCON6与BANKCON7
MT[16:15]: 设置bank外接的存储器类型,0b00为SRAM,0b11为SDRAM
设置为0b00的sram,其他位的设置与bank[1:5]的类似,设置为SDRAM的,其他未进行如下设置:
Trcd[3:2]: RAS to CAS delay, 我使用保守值:0b10
Scan[1:0]: SDRAM的列地址位数,0b00表示8位,0b01表示9位,0b10表示10位。查阅内存的datasheet得知,我的开发板上的是9
位,
所以,本开发板的bank6,bank7都设置为BANKCONx=0x00018005
刷新控制REFRESH
R_CNT[10:0]: 由公式R_CNT=2^11 + 1 - SDRAM频率(MHz) * SDRAM刷新周期(us)
查阅内存datasheet,我的是64ms 8,192-cycle refresh,所以刷新周期=64ms/8192=7.8125us
这里我还没使用PLL,sdram频率为晶振频率12MHz,
计算R_CNT=2^11 + 1 - 12 * 7.8125 = 1955
所以我的REFRESH设置为0x008c0000(其他位的固定设置) + 1955 = 0x008c07a3
BANKZIZE
Bk76map[2:0]: bank6,7的大小,0b001为65mb
我这里设置为0xb1
SDRAM模式设置
只需修改为CL[6:4],这是时序时间参数,我用保守值MRSRB67=0X30
设置好这些寄存器,内存就可以使用了。
TQ2440开发板
编译环境:
Arm-linux-gcc 3.4.5(编译器版本不同可能出错)
硬件配置:
ARM: S3C2440A
MEM: MT48LC16M16A2
资料:S3C2440官方文档与MT48LC16M16A2的datasheet
附录源码:
源码文件如下
启动代码:
@******************************************************************
@ file:2440init.S
@ set SDRAM, copy code to SDRAM, and run it
@******************************************************************
.equ BWSCON, 0x48000000
.equ SDRAM_BASE, 0x30000000
.equ WTCON, 0x53000000
.extern main
.text
.global start
start:
bl disable_watch_dog @关闭看门狗
bl memsetup @设置内存寄存器
bl copy_steppingstone_to_sdram
ldr pc, =on_sdram @转跳到SDRAM中执行代码
@程序连接时设置开头为0x30000000,这里使pc等于绝对地址,就到SDRAM里执行去了
@******************************************************************
on_sdram:
ldr sp, =0x34000000 @设置栈
bl main
@******************************************************************
halt_loop:
b halt_loop
@******************************************************************
disable_watch_dog:
mov r1, #WTCON
mov r2, #0x0
str r2, [r1]
mov pc, lr @返回
@******************************************************************
copy_steppingstone_to_sdram:
@把steppingstone的4kb数据全部复制到sdram中
@ 0x00000000 ==> 0x30000000
mov r1, #0x00000000
ldr r2, =SDRAM_BASE
mov r3, #1024*4
copyloop:
ldr r4, [r1], #4
str r4, [r2], #4
cmp r1, r3
bne copyloop
mov pc, lr
@******************************************************************
memsetup:
mov r1, #BWSCON @MEM 13个寄存器的开始地址
adrl r2, mem_conf
add r3, r1, #52 @13 * 4 = 52
memloop:
ldr r4, [r2], #4
str r4, [r1], #4
cmp r1, r3
bne memloop
mov pc, lr
.align 4
mem_conf:
@13个MEM寄存器设置值
.long 0x22000000 @BWSCN
.long 0x00000700 @BANKCON0
.long 0x00000700 @BANKCON1
.long 0x00000700 @BANKCON2
.long 0x00000700 @BANKCON3
.long 0x00000700 @BANKCON4
.long 0x00000700 @BANKCON5
.long 0x00018005 @BANKCON6
.long 0x00018005 @BANKCON7
.long 0x008c07a3 @REFRESH
.long 0x000000b1 @BANKSIZE
.long 0x00000030 @MRSRB6
.long 0x00000030 @MRSRB7
C文件:
/*
* file: led.c
* 功能:流水灯(学习io的使用)
* 硬件:GPB[5:8] 对应led[1:4],低电平点亮
* 多功能IO口的寄存器有3个:(查阅ARM芯片资料)
GPxCON:选择引脚功能,两位对应一根引脚,00输入,01输出,10特殊功能,11保留
GPxDAT: 用于读写引脚
GPxUP: 上拉电阻,0使用上拉电阻,1禁止上拉电阻
* crazyleen <[email protected]> 2010/10/14 10:59:42
*/
//sfr
#define GPBCON (*(volatile unsigned long *)0x56000010)
#define GPBDAT (*(volatile unsigned long *)0x56000014)
//0b01,选择输出功能
#define GPB5_OUT (1 << (5 * 2))
#define GPB6_OUT (1 << (6 * 2))
#define GPB7_OUT (1 << (7 * 2))
#define GPB8_OUT (1 << (8 * 2))
void delay(void)
{
int i;
for(i = 50000; i > 0; i--);
}
void ledplayer()
{
unsigned int led = (1 << 5);
for( ; led < (1 << 10); led <<= 1){
GPBDAT = ~led;
delay();
}
GPBDAT = 0;
delay();
GPBDAT = ~0;
delay();
}
int main()
{
GPBCON = GPB5_OUT | GPB6_OUT | GPB7_OUT | GPB8_OUT; //初始化GPB[5:8],输出功能
while(1){
ledplayer();
}
return 0;
}
Makefile文件:
sdram_led.bin: 2440init.S led.c
arm-linux-gcc -g -c -o 2440init.o 2440init.S
arm-linux-gcc -g -c -o led.o led.c
arm-linux-ld -Ttext 0x30000000 -g 2440init.o led.o -o sdram_led_elf
arm-linux-objcopy -O binary -S sdram_led_elf sdram_led.bin
arm-linux-objdump -D -m arm sdram_led_elf > sdram_led.dis
clean:
rm -f *.o sdram_led_elf sdram_led.dis sdram_led.bin