2440地址空间
1.地址线
ADDR0-ADDR26,27根地址线。可以访问2^27=128M的地址空间
2.片选线
nGCS0-nGCS7,8根片选线。可以访问8个bank,也就是8*128M=1G的地址空间。在2440地址分布中SDRAM被安排在nGCS6和nGCS7上,每个片选可以寻址128MB的地址空间。在datasheet中的Memory Controller可以找到相关信息。
3.存储控制器
CPU在访问外设时只提供地址,并不知道要访问的是什么外设。CPU访问外设时给出一个地址,通过相应的控制器来翻译地址信号,从而来访问外设的。需要访问内存,就要初始化存储控制器。值得注意的是CPU是按字节寻址,但内存数据线是16位。
内存芯片硬件连接
2440使用的内存芯片是4*4*16=32MB的。每个内存芯片16位,2440数据线是32位的,所以使用了2片32MB的内存芯片构成64MB
存储控制器
1.存储控制器控制对内存的访问和NorFlash的访问
2.要对内存进行访问,首先要设置存储控制器的寄存器
3.存储控制器寄存器:
3.1.BWSCON(0x48000000,总线位宽和等待状态控制寄存器)
用来控制8个Bank,每个Bank的控制对应4位,分析后设置值为0x22000000
3.2.BANKCON6(0x4800001C,Bank6控制寄存器) BANKCON7(0x48000020,Bank7控制寄存器)
Trcd延时2个时钟(在2440芯片手册中有描述),SCAN列地址9位(在内存芯片手册中有描述),分析设置值为0x00018001
3.3.REFRESH(0x48000024,刷新控制寄存器)
Trp充电周期为2个时钟(在2440芯片手册中可以找到相关描述),Tsrc semi行刷新周期通常为7个时钟,刷新计数根据HCLK值来计算刚好为1269,分析设置值为0x008C04F5
3.4.BANKSIZE(0x48000028,Bank大小寄存器)
BURST_EN突发模式表示是否允许一次访问多位,一般设置为允许,BK76MAP设置内存的大小设置为64M,分析设置值为0x000000B1
3.5.MRSRB6(0x480000C2,设置bank6的模式) MRSRB7(0x48000030)
CL潜伏期根据内存手册时序图设置为3个时钟,分析设置为0x00000030
3.6.存储控制寄存器
BWSCON (0x48000000) 0x22000000
BAMKCON0 (0x48000004) 0x00000000
BAMKCON1 (0x48000008) 0x00000000
BAMKCON2 (0x4800000C) 0x00000000
BAMKCON3 (0x48000010) 0x00000000
BAMKCON4 (0x48000014) 0x00000000
BAMKCON5 (0x48000018) 0x00000000
BAMKCON6 (0x4800001C) 0x00018001
BAMKCON7 (0x48000020) 0x00018001
REFRESH (0x48000024) 0x008C04F5
BANKSIZE (0x48000028) 0x000000B1
MRSRB6 (0x4800002C) 0x00000030
MRSRB7 (0x48000030) 0x00000030
4. 完成了内存初始化就可以使用内存了
.data mem_control_val: //内存控制寄存器值 .long 0x22000000 //BWSCON 0x48000000 .long 0x00000700 //BAMKCON0 0x48000004 .long 0x00000700 //BAMKCON1 0x48000008 .long 0x00000700 //BAMKCON2 0x4800000C .long 0x00000700 //BAMKCON3 0x48000010 .long 0x00000700 //BAMKCON4 0x48000014 .long 0x00000700 //BAMKCON5 0x48000018 .long 0x00018001 //BAMKCON6 0x4800001C .long 0x00018001 //BAMKCON7 0x48000020 .long 0x008C04F5 //REFRESH 0x48000024 .long 0x000000B1 //BANKSIZE 0x48000028 .long 0x00000030 //MRSRB6 0x4800002C .long 0x00000030 //MRSRB7 0x48000030 /* *名称:init_memory *功能:初始化内存 */ init_memory: //地址初始化 ldr r1, =MEM_CONTROL //载入[内存控制寄存器]起始地址到r1 ldr r2, =mem_control_val //载入[内存控制寄存器值]地址到r2,标号相当于地址的立即数 //adrl r2, mem_control_val //也可用adrl装载长地址指令,但是mem_conrol_val标号必须定义在代码段中,否则编译会报错找不到符号 add r0, r1, #MEM_CONTROL_LENGTH //载入[内存控制寄存器]结束地址到r0 //载入[内存控制寄存器值]到对应的[内存控制寄存器]中 loop: ldr r3, [r2], #4 //载入对应的[内存控制寄存器值]值到r3,然后让[内存控制寄存器值]地址加4字节 str r3, [r1], #4 //保存r3到对应的[内存控制寄存器]中,然后让[内存控制寄存器]地址加4字节 cmp r1, r0 bne loop //如果内存控制寄存器地址不为结束地址,那么循环 mov pc, lr