ARM DDR SDRAM 初始化
2.DDR 控制器初始化以及DDR SDRAM初始化流程
3.ARM編程初始化DRAM Controller 和DDR SDRAM細(xì)節(jié)details
備注: 由于DDR SDRAM時序比較復(fù)雜,具體時序細(xì)節(jié)在未來的另一篇博文用FPGA來設(shè)計(jì)DDR SDRAM控制器中記錄。 用FPGA來設(shè)計(jì)DDR SDRAM控制器相對于直接使用ARM片上的DRAM Controller 要復(fù)雜的多。
1.DDR SDRAM introduction
DDR SDRAM本質(zhì)上就是一個存儲器件。它是易失性存儲器件。掉電后數(shù)據(jù)就消失。 你可以把它想象成和簡單的單端口RAM和雙端口RAM功能一樣,可以通過讀,寫命令,以及對應(yīng)的地址來訪問內(nèi)部數(shù)據(jù)。但是它又不像普通的RAM。
(1)首先>> DDR SDRAM在使用前要做一系列的初始化工作。初始化工作包括使能時鐘,預(yù)充電,自刷新,等待200clks ,設(shè)置模式寄存器以及擴(kuò)展模式寄存器等。初始化完成后,才能進(jìn)入讀寫數(shù)據(jù)狀態(tài) 。 而且在工作工程中要定期進(jìn)行刷新,防止電荷丟失掉。
(2)其次>> DDR SDRAM 芯片本身有很多參數(shù)需要來設(shè)置。
2.1 比如,在寫操作時,你先要設(shè)定行(row),然后過一段時間再設(shè)定列(column)。這段時間就叫RCD (Row Column Delay )【行地址到列地址的有效時間】
2.2 還有,在讀操作時,讀命令發(fā)出之后數(shù)據(jù)不會立即被讀出,要經(jīng)過一定的時鐘周期。 而這段延時就叫CAS Latency(Column Address Strobe latency)
2.3 自動刷新時間的設(shè)置:Ddrsdram芯片一般來說是每64ms刷新一次,刷新是整個bank都要刷新,即有多少行需要來刷新,如果行地址為A12-A0,即有2.*(13)=8192行,即刷新一行需要64ms/8192時間。
還有一些參數(shù),如有時間,今后更新博客中完善。
(3)再者>> DDR SDRAM的行地址和列地址共用同一地址總線,不過這個地址總線何時被用來做行地址或列地址,可以翻看DDR 數(shù)據(jù)手冊,時序是關(guān)鍵。
(4)數(shù)據(jù)讀寫時,是在時鐘上升沿和下降沿都會有數(shù)據(jù)傳輸。這就是DDR SDRAM速度快于SDRAM的原因,這也是名字的由來(Double Data rate SDRAM)。
2.DDR 控制器初始化以及DDR SDRAM初始化流程
見圖:
3.ARM編程初始化DRAM Controller 和DDR SDRAM細(xì)節(jié)details
按著上圖所示操作流程,依次寫下即可,設(shè)置好相關(guān)寄存器的值,參考S3C6410手冊以及你板子上所用DDR SDRAM芯片手冊。sdram初始化子函數(shù)如下。
本文引用地址:http://butianyuan.cn/article/201611/317138.htm
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) );
u32 trcd = nstoclk( 23 );
set_val( P1T_RCD, trcd | (( trcd - 3 ) << 3 ) );
u32 trfc = nstoclk( 80 );
set_val( P1T_RFC, trfc | ( ( trfc-3 ) << 5 ) );
u32 trp = 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 column address */
/* set_nbit: 把從第bit位開始的一共len位消零,然后把這幾位設(shè)為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 ); /* 32 bit */
set_nbit( P1MEMCFG2, 8, 3, 0x3 ); /* Mobile DDR SDRAM */
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));
}
時間倉促,該文章還需完善。
評論