飞凌Ok6410之SDRAM的学习

来源:互联网 发布:淘宝上开茶叶店 编辑:程序博客网 时间:2024/05/21 05:43

由于程序太大导致程序运行会出错误,也就是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));

}

原创粉丝点击