005 sdram裸机编程

前面我们使用过uart来打印输出信息。

今天我们来学习一下sdram的使用。

sdram的功能相当我们在使用PC机的时候里面插的ram,当然我们S3C2440在芯片内部会有一个自带的SRAM(大小为4K),

当这个自带的sram不够用的时候,就会需要使用我们外接的sdram了。

缺点是sdram在使用的时候,需要先把数据搬进去,处理好以后再搬出来给到cpu使用,与内部sram相比降低了运行速度。

但我们在配置的时候,把性能配置好,依然很快。

这里建议大家看一篇关于sdram的文章,讲的很深很好。

《SDRAM参考文档: 高手进阶,终极内存技术指南——完整/进阶版》百度一下这篇文章即可。

 

然后我们来学习一下本节sdram的一些知识和使用。不足之处希望大家指出,谢谢。

首先我们了解一下原理图,看下硬件构成。

我们使用的是16bits * 2  两块sdram。

那么我们由原理图可以看出,addr线是并接的,且从addr2开始接sdram的addr0线。

其原因有二:

1、并接的原因是因为我们s3c2440是32bit,所以把两个16bit的sdram组合成32bit来处理cpu的一个带宽数据。

2、addr2接sdram的addr0是因为如下图:

当我们cpu想访问的地址为A0A1A2A3 = 0010时,则sdram收到的地址是A2A3也就是SDRAM(A0A1)=10。

也就是我们两块sdram的第二个word。然后把两个sdram的③④组装成一个32bit的数据data,返回给内存控制器,再由内存控制器根据上s3c2440的A0A1地址数据,取出data中对应的那个byte数据给到cpu。

这里的原理和2440的spec写的一样:

 

接下来我们要看cpu是如何选中sdram的。原理图中可以看到,有一个片选引脚LnGS6, 由2440 spec可以看到这块内存接口是专门用来外接sdram的。

我们可以看到sdram是可编程内存空间的,2MB~128MB,我们用的是2个32MB的sdram组成一个64MB的sdram供cpu使用。

 

接下来我们讲一下sdram的内部结构和寻址方式:

目前我们的sdram内部采用的是逻辑分区为4个,然后是行列地址。

比如要写一个数据到sdram,那么我们需要先选中L_BANKx,然后行地址,再列地址。找到对应地址后再把数据写入目的地址。

再bank中的寻址方式类似于excel的单元格查找。

由原理图可以看到我们使用LADDR24/25来选中逻辑bank,再由laddr2~laddr14来写入行列地址。

行地址为laddr2~laddr14,列地址为9bit, laddr2~laddr1(sdram spec得到)

 

2440和sdram之间的通信时序如下图:

 

要注意的地方是,要根据sdram的时间要求来修改地址和数据之间的时间差。

 

到这里我们原理分析完毕。然后配置寄存器。

我们直接借用韦东山老师的讲课图。

 

上面说那么多原理,其实就是这几个寄存器的配置。我们只使用了基本的功能。一些busrt等等模式还没有使用。

 

上代码:

/*
 * brief: init sdram registers config.
 * param: none
 * return: none
 * notice: none
 */
void sdram_init(void)
{
    /* not using UB/LB, wait disble, data bus width 32bits */
    BWSCON   = 0x22000000;

    /* memory type sdram, RAS to CAS time 2clocks, column address 9bits */
    BANKCON6 = 0x18001;
    BANKCON7 = 0x18001;     //bank7 config same param also.

    /* enable auto refresh... */
    REFRESH  = 0x8404F5;

    /* Enable burst operation, SDRAM power down mode enable,
     * SCLK is active only during the access (recommended),
     * 64MB SDRAM */
    BANKSIZE = 0xB1;

    /*  CAS latency 2clocks */
    MRSRB6   = 0x20;
    MRSRB7   = 0x20;    //bank7 config same param also.
}
 

到这里我们就可以使用sdram了。

下面加了一段sdram测试。

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++)
    {
        //printf("write data to sdram p[%d] = %d \r\n", i, p[i]);
        if(p[i] != 0x55)
            return -1;
        
    }

    return 0;
}

 

最后再做这个实验的时候,有两个问题捣鼓了一下午没解开?

1、添加uart的时候,使用了printf函数,Makefile中把-Tdata段设置在0xe80和0xee0之间都可以正常打印。但是设置到0xef0以后就不能正常输出%d %x等这些格式,都是空白输出。  我查了代码段和只读数据段最后地址都没有覆盖到-Tdata。

2、printf函数放到sdram.c里面就打印不出来。根源未知。

 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值