由于程序太大导致程序运行会出错误,也就是8K的内容不够用,这时候就需要用到DDR,前面的博文提到过,但是在使用DDR之前,我们需要初始化DDR,初始化DDR之前我们先来了解一下DDR,打开OK6410核心板的电路图可以找到DDR、2片
然后找到DDR的芯片手册可以知道DDR能提供128M的容量
这样算可以得到容量=32M*16bits*2=4*32M字节也就是128M字节的容量
控制访问块和控制行地址列地址的引脚为
先找到行地址
接下来具体介绍访问DDR的指令
1、 MOV R0,#0X50000000
LDR R1,R0
这样我们就可读取到里面的内容
2、 访问DDR首先需要初始化DRAMC动态内存控制寄存器
(1) 地址线的设置(行地址、列地址的设置)
(2) 位宽(两片DDR合并成一个32位的内存芯片)
(3) 设置访问时序
DRAM DRAM DRAM 控制器初始化顺序
然后了解一下DDR存储器的初始化
1)在 direct_cmd,以‘2’b10’执行 mem_cmd,使得 DRAM 控制器产生‘NOP’存储器命令。
(2)在 direct_cmd,以‘2’b00’执行 mem_cmd,使得 DRAM 控制器产生 ‘Prechargeall’存储器命令。
(3)在 direct_cmd,以‘2’b11’执行 mem_cmd,使得 DRAM 控制器产生‘Autorefresh’存储器命令。
(4)在 direct_cmd,以‘2’b10’执行 mem_cmd,使得 DRAM 控制器产生‘MRS’存储器命令。
EMRS 块地址必须被设置。
(5)在 direct_cmd,以‘2’b10’执行 mem_cmd,使得 DRAM 控制器产生‘MRS’存储器命令。
MRS 块地址必须被设置。
(6)在 direct_cmd,以‘2’b11’执行 mem_cmd,使得 DRAM 控制器产生‘Autorefresh’存储器命令。
(7)在 direct_cmd,以‘2’b11’执行 mem_cmd,使得 DRAM 控制器产生‘Autorefresh’存储器命令。
(8)在 direct_cmd,以‘2’b11’执行 mem_cmd,使得 DRAM 控制器产生 ‘Prechargeall’存储器命令。
以下未初始化代码:
#include "common.h"
#define MEMCCMD 0x7e001004
#define P1REFRESH 0x7e001010
#define P1CASLAT 0x7e001014
#define MEM_SYS_CFG 0x7e00f120
#define P1MEMCFG 0x7e00100c
#define P1T_DQSS 0x7e001018
#define P1T_MRD 0x7e00101c
#define P1T_RAS 0x7e001020
#define P1T_RC 0x7e001024
#define P1T_RCD 0x7e001028
#define P1T_RFC 0x7e00102c
#define P1T_RP 0x7e001030
#define P1T_RRD 0x7e001034
#define P1T_WR 0x7e001038
#define P1T_WTR 0x7e00103c
#define P1T_XP 0x7e001040
#define P1T_XSR 0x7e001044
#define P1T_ESR 0x7e001048
#define P1MEMCFG2 0X7e00104c
#define P1_chip_0_cfg 0x7e001200
#define P1MEMSTAT 0x7e001000
#define P1MEMCCMD 0x7e001004
#define P1DIRECTCMD 0x7e001008
#define HCLK 133000000
#define nstoclk(ns) (ns/( 1000000000/HCLK)+1)
int sdram_init( void )
{
//tell dramc to configure
set_val(MEMCCMD, 0x4 );
//set refresh period
set_val(P1REFRESH, nstoclk(7800) );
//set timing para
set_val(P1CASLAT, ( 3 << 1 ) );
set_val(P1T_DQSS, 0x1 ); // 0.75 - 1.25
set_val(P1T_MRD, 0x2 );
set_val(P1T_RAS, nstoclk(45) );
set_val(P1T_RC, nstoclk(68) );
u32trcd = nstoclk( 23 );
set_val(P1T_RCD, trcd | (( trcd - 3 ) << 3 ) );
u32trfc = nstoclk( 80 );
set_val(P1T_RFC, trfc | ( ( trfc-3 ) << 5 ) );
u32trp = nstoclk( 23 );
set_val(P1T_RP, trp | ( ( trp - 3 ) << 3 ) );
set_val(P1T_RRD, nstoclk(15) );
set_val(P1T_WR, nstoclk(15) );
set_val(P1T_WTR, 0x7 );
set_val(P1T_XP, 0x2 );
set_val(P1T_XSR, nstoclk(120) );
set_val(P1T_ESR, nstoclk(120) );
//set mem cfg
set_nbit(P1MEMCFG, 0, 3, 0x2 ); /* 10 columnaddress */
/*set_nbit: 把从第bit位开始的一共len位消零,然后把这几位设为val */
set_nbit(P1MEMCFG, 3, 3, 0x2 ); /* 13 row address*/
set_zero(P1MEMCFG, 6 ); /* A10/AP */
set_nbit(P1MEMCFG, 15, 3, 0x2 ); /* Burst 4 */
set_nbit(P1MEMCFG2, 0, 4, 0x5 );
set_2bit(P1MEMCFG2, 6, 0x1 ); /* 32bit */
set_nbit(P1MEMCFG2, 8, 3, 0x3 ); /* Mobile DDRSDRAM */
set_2bit(P1MEMCFG2, 11, 0x1 );
set_one(P1_chip_0_cfg, 16 ); /*Bank-Row-Column organization */
//memory init
set_val(P1DIRECTCMD, 0xc0000 ); // NOP
set_val(P1DIRECTCMD, 0x000 ); // precharge
set_val(P1DIRECTCMD, 0x40000 );// auto refresh
set_val(P1DIRECTCMD, 0x40000 );// auto refresh
set_val(P1DIRECTCMD, 0xa0000 ); // EMRS
set_val(P1DIRECTCMD, 0x80032 ); // MRS
set_val(MEM_SYS_CFG, 0x0 );
//set dramc to "go" status
set_val(P1MEMCCMD, 0x000 );
//wait ready
while(!(( read_val( P1MEMSTAT ) & 0x3 ) == 0x1));
}