SRAM 静态随机存储器
SROM 静态只读存储器
RAM 随机存储器
ROM 只读存储器
DRAM 动态随机存储器
SDRAM 同步动态随机存储器
NOR FLASH, NAND FLASH 非易失闪存技术
支持大/小端(通过软件选择)
每个BANK的地址空间为128M,总共1GB(8 BANKs)
可编程控制的总线位宽(8/16/32bit),不过BANK0只能选择两种位宽(16/32bit)
总共8个BANK,BANK0-BANK5可以外接ROM,SRAM等,BANK6-BANK7除可以支持ROM, SRAM外还支持SDRAM等
BANK0-BANK6共7个BANK的起始地址是固定的
BANK6,BANK7的地址空间大小是可编程控制的
每个BANK的访问周期均可编程控制
在外接SDRAM时,支持自刷新和省电模式
CPU对外引出了8根片选信号nGCS~nGCS7。对应BANK0~BANK7,当访问BANKx的地址空间时,nGCSx引脚输出低电平来选中外接的设备。这样每个nGCSx对应128M地址空间,每个nGCSx信号总共对应了1GB的地址空间。
对于Nand Flash,在原理图上它的地址线并没有连接到CPU,因此它不参与CPU的统一编址。但它的数据线也接到了数据总线上,为了防止干扰,它也有一个片选信号(CE)。当CPU访问Nand Flash时,Nand Flash控制器才会片选Nand Flash,让其接收数据总线上的数据。
8位位宽 A0接A0,A1-A1,A2-A2...
16位位宽 A1接A0,A2-A1,A3-A2...
32位位宽 A2接A0,A3-A1,A4-A2...
8位位宽 内部结构为8bit
16位位宽 内部结构为两个8bit组合
32位位宽 内部结构为4个8bit组合
假设CPU执行
mov r0, #3
ldrb r1, [r0]
解析:
ldrb:读出一个字节
mov r0, #4
ldr r1, [r0]
解析:读4字节
其中的参数需要根据外接的设备来进行设置
我们需要设置2440设置其信号满足外接设备的要求
NOR FLASH是 MX29LV160DBTI,2M大小,接在nGCS0,所以基址是0.
Taa 地址信号Taa后数据有效70ns
Tce 片选信号Tce后数据有效70ns
Toe 数据在oe后Toe有效30ns
Toh 数据保持时间0ns
Tdf 在Tdf内数据不稳定,也就是不允许访问其他芯片,30ns
一般不需要理会这个,因为再次访问的时候,还需要时序前面的Taa
等到稳定的时候,数据已经稳定了
Trc 读周期时间,最小70ns,也就是速度性能 70ns
为了简单把地址数据(Addresses),片选信号(CE#),读信号(OE#),同时发出,然后让它们都等待70ns(等待信号有效)。对应S3C2440的Nor Flash控制器的读时序图,需要让地址信号A[24:0]、片选信号nGCS、读信号nOE同时发出,保持Tacc大于等于70ns。然后设置读之后的那些时序tdf,toh为0[因为下一次使用会又有片选的70ns
BANK0~BANK5 只需要设置BWSCON和BANKCONx这两个寄存器
BANK6~BANK7 外接SDRAM时,除BWSCON和BANKCONx还要设置REFRESH, BANKSIZE, MRSRB6, MRSRB7等4个寄存器
解析:
STx:对于SDRAM,此位为0。对于SRAM,此位为1。
内存芯片驱动的非常慢,当CPU发出信息后,内存芯片在规定时间内未准备好。此时可以先CPU发出一个等待信号。wait信号是内存芯片向2440CPU发出的
解析:
为什么一上电就能使用NOR FLASH。这里Tacc默认值是111最大为14个时钟,也就是为什么不用设置NOR FLASH就能开机使用。上电的时候使用晶振12M,也就是
tacc=14*Hclk=1/12M*14=1166ns>70ns
解析:
当选择外接SDRAM时,地址才会被拆分为BANK地址,行地址,列地址。如果不是的话地址会一次性发出去。
解析:
因为NOR FLASH外接在BANK0所以BWSCON无需控制
将HCLK设置为100MHz,T=1000/100=10ns,Tacc需要大于等于70ns,因此设置Tacc等于101,8个clocks即可。
void bank0_tacc_set(int val)
{
BANKCON0 = val << 8; //设置【10:8】
}
init.h
#ifndef _INIT_H
#define _INIT_H
void sdram_init(void);
int sdram_test(void);
#endif
init.c
#include "s3c2440_soc.h"
void sdram_init(void)
{
BWSCON = 0x22000000;
BANKCON6 = 0x18001;
BANKCON7 = 0x18001;
REFRESH = 0x008404f5;
BANKSIZE = 0xb1;
MRSRB6 = 0x20;
MRSRB7 = 0x20;
}
//测试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++)
if (p[i] != 0x55)
return -1;
return 0;
}
原文:https://www.cnblogs.com/huangdengtao/p/12148271.html