第八课JZ2440裸板开发之SDRAM

一、SDRAM介绍

JZ2440上使用的SDRAM如下:
JZ2440开发板上使用的是EtronTech公司的EM63A165TSSDRAM芯片,该芯片是一个16M x 16 bit Synchronous DRAM (SDRAM)的芯片,就是说共有16M存储单元,每个存储单元的数据宽度是16bit,即整个芯片大小是32MB。
我们的开发板由两个16位的SDRAM组成一个32位的SDRAN,大小为64M,我们也可以计算出来,使用到的地址线是0-14 一共15根,所以每个SDRAM的大小就是2^15=32768 = 32M,两个加起来就是64M,由原理图还可以看出来,SDRAM是在内存控制器的bake6区域,因为使用的是CS6片选。根据上节课我们知道,CS6基地址是0x30000000
在这里插入图片描述
在这里插入图片描述

这里的SDRAM总共有4个块(Banks),可以认为每个块就是一个表格,里面的每个格子表示的是16bit数据。
CPU怎么访问SDRAM中的地址:
①CPU发出的片选信号nGCS6有效,它选中SDRAM芯片。
②SDRAM中有4个L-Bank,需要两根地址信号来选中其中之一,根据原理图,可知使用ADDR24,ADDR25作为L-Bank的选择信号。
③对被选中的芯片进行统一的行/列(存储单元)寻址。

这里就会有疑问,back用哪一个?行列地址怎么计算得来的?
答: 根据SDRAM芯片的列地址线数目设置CPU的相关寄存器后,CPU就会从32位的地址中自动分出L_Bank片选信号,行地址信号,列地址信号,然后先后发出行地址信号,列地址信号。L_Bank选择信号在发出行地址信号的同时发出,并维持到列地址信号结束。

由原理图可知,这里行列地址共用地址总线,所以需要使用nSRAS、nSCAS两个信号来区分它们。SDRAM芯片K4s5m632的行地址数为13,列地址数为9,所以当nSRAS信号有时,ADDR2—ADDR14上发出是行地址信号,当nSCAS信号有效时,ADDR2—ADDR10上发出的是列地址信号.

二、查看芯片手册

由于需要设置内存控制器,所以需要了解内存控制器的寄存器,这里分别介绍一下:

①总线位宽与等待寄存器BUS WIDTH & WAIT CONTROL REGISTER (BWSCON)
这个寄存器的32位,对应着八个BANK,每个BANK的信息用其中的四位表示,我们的SDRAM是接在BANK的,所以对应【24:27】这四位,如下:
(1)ST6[27]: 启动/禁止SDRAM的数据掩码引脚,对于SDRAM,此位为0:对于SRAM此位为1。
(2)WS6[26]:是否使用存储器的WAIT信号,通常设为0。
(3)DW6[25:24]:使用两位来设置相应BANK的位宽,0b00对应8位,0b01对应16位,0b10对应32位(开发板用的就是32位的),0b11表示保留。
这里我们初始化SDRAM,【27】位设置为0,【26】设置为0,【25:24】设置为10,所以我么该寄存器的配置如下:
BWSCON = 0x22000000;

在这里插入图片描述

②BANK控制寄存器BANKCON6(BANKCONTROLREGISTER)
(1)下面是BANK0-BANK5的控制寄存器
在这里插入图片描述
在这里插入图片描述

(2)下面是BANK6与BANK7的,由下图可知,当【16:15】配置为00的时候,BACKCON6与BANKCON7跟上面的BANKCON0-5是一样的配置,只有在【16;15】配置成11的时候,代表外接的是SDRAM。然后只需要配置【3:2】【1:0】。
我们查看SDRAM的芯片手册知道,列地址数为9,所以【1:0】配置为01;Trcd[3:2]:行地址和列地址间隔多长时间,看芯片手册时间间隔是20ns,本来开发板的HCLK是100MHZ,clocks为10ns,所以设置为推荐值0b00(2clocks),所以该寄存器我们配置如下(这里我们6 7一起配置):
BANKCON6 = 0x18001;
BANKCON7 = 0x18001;

在这里插入图片描述

③刷新控制寄存器(REFRESH CONTROL REGISTER)
下面是刷新控制寄存器,我们这里分析,
(a)首先打开刷新使能 【23】置1;
(b)配置为自动刷新 【22】置0;
(c)trp【21:20】根据芯片手册设置为00即可;
(d)Tsrc【19:18】:根据芯片手册设为默认值0b01即可;
(e)RefreshCounter[10:0]:即R_CNT
R_CNT可如下汁算(SDRAM时钟频率就是HCLK):
R_CNT=2^11+1-SDRAM时钟频率(MZ)*SDRAM刷新周期(us)
SDRAM的刷新周期在SDRAM的数据手册上有标明,在本开发板使用的SDRAM:K4S561632的数据手册上,可看见这么一行“64msrefreshpenod(8KCycle)所以,刷新周期=64ms/8192=7.8125us。
Refreshcount=2^11+1-100x7.8=1269=0x4F5。
因此,本开发板中REFRESH配置如下:
REFRESH = 0x8404f5;

在这里插入图片描述
在这里插入图片描述
④KANKSIZE寄存器

(1)BURST_EN[7]:0=ARM核禁上突发传输,1=ARM核支持突发传输(推荐);
(2)SCKEEN[5]:0=不使用SCKE信号令SDRAM进入省电模式,1=使用SCKE信号令SDRAM进入省电模式(推荐);
(3)SCLK-EN[4]:0=时刻发出SCLK信号,1=仅在访问SDRAM期间发出SCLK信号(推荐);
(4)BK76MAP[2:0]:设置BANK6的大小。本开发板BANK6外接64MB的SDRAM,令[2:0]=b001(64M/64M),表示BANK6/7的容量都是64MB,虽然BANK7没有使用。
因此,本开发板中BANKSIZE配置如下:
BANKSIZE = 0xb1;
在这里插入图片描述
⑤SMRAM模式设置寄存器

能修改的只有位CL[6:4],这是SDRAM时序的一个时间参数,表示发出行、列地址后,等多久才返回收到数据,
CL可以取值为0b0l0(2 clocks)或0b011(3 clocks)。
本开发板取最保守的值0b010,所以MRSRB6的配置如下:
MRSRB6 = 0x20;
MRSRB7 = 0x20;

在这里插入图片描述

三、代码部分

(1)我们这里在第五节时钟体系的的代码上做修改,start.S文件不做改动,增加两个文件init.c 跟init.h 如下:
init.c:

#include "s3c2440_soc.h"
void sdram_init(void)
{
	BWSCON = 0x22000000;
	BANKCON6 = 0x18001;
	BANKCON7 = 0x18001;
	REFRESH  = 0x8404f5;
	BANKSIZE = 0xb1;
	MRSRB6   = 0x20;
	MRSRB7   = 0x20;
}

int sdram_test(void)
{
	volatile unsigned char *p = (volatile unsigned char *)0x30000000;
	int i;
	// write sdram
	for (i = 0; i < 1000; i++)
		p[i] = 0x55;
	// read sdram
	for (i = 0; i < 1000; i++)
		if (p[i] != 0x55)
			return -1;
	return 0;
}

init.h:

#ifndef _INIT_H
#define _INIT_H

void sdram_init(void);
int sdram_test(void);

#endif

(2)增加led.c及led.h文件,文件内容为原来main.c实现的循环点灯的功能:

#include "s3c2440_soc.h"

void delay(volatile int d)
{
	while (d--);
}

int led_test(void)
{
	int val = 0;  /* val: 0b000, 0b111 */
	int tmp;

	/* 设置GPFCON让GPF4/5/6配置为输出引脚 */
	GPFCON &= ~((3<<8) | (3<<10) | (3<<12));
	GPFCON |=  ((1<<8) | (1<<10) | (1<<12));

	/* 循环点亮 */
	while (1)
	{
		tmp = ~val;
		tmp &= 7;
		GPFDAT &= ~(7<<4);
		GPFDAT |= (tmp<<4);
		delay(100000);
		val++;
		if (val == 8)
			val =0;
	}
	return 0;
}
#ifndef _LED_H
#define _LED_H

int led_test(void);

#endif

(3)然后修改main.c函数,我们给初始化之后的SDRAM中写入数据再读出来,判断读出来的数据跟写入数据是否相等,相等则执行循环点灯的程序。
main.c

#include "s3c2440_soc.h"
#include "init.h"
#include "led.h"

int main(void)
{
	uart0_init();

	sdram_init();

	if (sdram_test() == 0)
		led_test();
	
	return 0;
}

(4)Makefile

all:
	arm-linux-gcc -c -o led.o led.c
	arm-linux-gcc -c -o init.o init.c
	arm-linux-gcc -c -o main.o main.c
	arm-linux-gcc -c -o start.o start.S
	arm-linux-ld -Ttext 0 start.o led.o  init.o main.o -o sdram.elf
	arm-linux-objcopy -O binary -S sdram.elf sdram.bin
	arm-linux-objdump -D sdram.elf > sdram.dis
clean:
	rm *.bin *.o *.elf *.dis

四、程序编译与烧写

编写并烧写到NAND flash,启动开发板,发现灯亮,说明SDRAM可以使用。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值