《单片机小白转嵌入式Linux学习记录,基于S3C2440----目录》
CPU 通过地址线/数据线访问 -> GPIO控制器
-> UART/I2C/I2S/SPI控制器
-> NAND控制器
-> 内存控制器 NOR flash/SDRAM/网卡
所有的外设控制器和内存设备都属于CPU统一编址,NAND控制属于内存编址,NAND flash 不属于CPU统一编址。
NOR flash/SDRAM/网卡 共用地址线/数据线,如何互不干扰?
答:通过片选信号来区分,根据访问地址范围来使能不同的片选信号。每个地址范围128MB = 2^27 所以地址线有A0~A26 27条线。片选用来使能不同的内存设备,LnOE 控制读信号,LnWE控制写信号。SDRAM只用LnWE一条线来控制读/写,低电平写,高电平读。
------------------------------------------------------------
CPU发出32位内存地址 -> 内存控制器 ->A[26:0]->外部内存设备
数据位宽与地址线的接线方式
8位宽 A0 -> A0
16位宽 A1 -> A0 内存控制器根据未发出位A0的值来判断是高8位还是第8位
32位宽 A2 -> A0 内存控制器根据未发出位A0,A1的值来组装数据返回给CPU
高位宽在访问大量数据时,内存控制器需要发送1/2(16bit) 或1/4(32bit)次读写即可,提高访问速度。
怎么确定内存设备的地址范围?
答:1.根据片选信号确定基址。
2.根据地址线确定范围。
----------------------------------------------------------
Nor flash
时序图 MX29LV160DBTI-70G(NOR FLASH).pdf P32-33
CPU 可编程时序 P205
接线
LnOE 读信号
LnWE 写信号
nGCS0 片选
nREST 复位
LDATA[15:0] 数据线 16位宽
LADDR[20:1] 地址线 2^21 = 2MB 容量
寄存器设置
BANKCON0(0x48000004) = 0x0500
Tacc 0b101 80ns>70ns 访问时钟
BWSON(0x48000000) 不用设置
DW0[2:1] 只读不需要设置,根据OM[1:0]电平选择位宽 0b01 16bit 0b10 32bit
通过修改BANKCON0[10:8]可以修改norflash的读取速度。只有在Nor启动下才能感觉到程序的差异。
------------------------------------------------------
SDRAM
步骤
1.内存控制器根据地址发出nGCS6片选
2.根据内存类型(SDRAM)拆分地址
a.L_BANK地址
b.行地址
c.列地址
-> 怎么拆分地址,通过寄存器来配置
3.读写数据
BANK6 寄存器配置 SDRAM
BWSON(0x48000000) = 0x22000000 P207 Bus width & wait status control register
ST6[27] SRAM UB/LB专用引脚 SDRAM不用
WS6[26] 等待信号未用到
DW6[25:24] 0b10 32位宽 -> 0b10 32bit
BANK7不用 配置成与BANK6 一样
BANKCON6(0x4800001C) = 0x00018001 P210
BANKCON7(0x48000020) = 0x00018001
MT[16:15] 0b11 Sync.DRAM 确定内存类型
Trcd[3:2] 0b00 2clock=20ns RAS to CAS delay 行地址到列地址延时 在芯片手册中搜索 Trcd P18 最大21ns
SCAN[1:0] 0b01 9bit 列地址内存块数量
REFRESH(0x48000024) = 0x008404F5 SDRAM refresh control register
REFEN[23] 1 SDRAM 刷新使能
TREFMD[22] 0 SDRAM 刷新模式 0自动刷新
Trp[21:20] 0b00 20ns RAS行访问预充电时间 手册21ns
Tsrc[19:18] 0b01 50ns SDRAM Semi Row cycle time Trc=Tsrc+Trp 行地址保持时间 = 时钟周期-充电时间
Refresh Counter[10:0] 0x4F5(1269) 64ms/8k=7.8us 刷新计数时间
BANKSIZE(0x48000028) = 0xb1 Flexible bank size register 灵活的块大小配置寄存器
BURST_EN[7] 1 突发操作使能
SCKE_EN[5] 1 休眠模式使能
SCLK_EN[4] 1 SCLK 仅在访问时活跃
BK76MAP[2:0] 0b001 BANKCON6/BANK7 64M/64M 内存映射大小
MRSRB6(0x4800002C) = 0x20
MRSRB7(0x48000030) = 0x20
WBL[9] 0 写突发长度 默认值
TM[8:7] 0b00 测试模式 默认值
CL[6:4] 0b010 CAS 列访问后延时 2或3时钟周期 根据芯片手册
BT[3] 0 突发类型 固定值
BL[2:0] 0b000 突发长度 固定值
测试代码
#define BANKCON0 (*(volatile unsigned int *)0x48000004) //volatile 防止编译器优化
#define BWSON (*(volatile unsigned int *)0x48000000) //位宽控制
#define BANKCON6 (*(volatile unsigned int *)0x4800001C)
#define BANKCON7 (*(volatile unsigned int *)0x48000020)
#define REFRESH (*(volatile unsigned int *)0x48000024)
#define BANKSIZE (*(volatile unsigned int *)0x48000028)
#define MRSRB6 (*(volatile unsigned int *)0x4800002C)
#define MRSRB7 (*(volatile unsigned int *)0x48000030)
/* Nor 初始化 */
void norflash_init(void)
{
BANKCON0 = 0x0500; //Tacc 0b101 80ns>70ns 访问时钟
}
/* SDRAM 初始化 */
void sdram_init(void)
{
BWSON = 0x22000000;
BANKCON6 = 0x18001;
BANKCON7 = 0x18001;
REFRESH = 0x8404F5;
BANKSIZE = 0xb1;
MRSRB6 = 0x20;
MRSRB7 = 0x20;
}
/* SDRAM 测试 */
int sdram_test(void)
{
volatile unsigned int *p = (volatile unsigned int *)0x30000000; //BANK6 基址
int i;
// write sdram
for (i = 0; i < 10000; i++)
p[i] = i;
// read sdram
for (i = 0; i < 10000; i++)
if (p[i] != i)
return -1;
return 0;
}
离线