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