s3c2440 bare metal - Memory Controller (five, SDRAM programming)

Configure the memory controller programmed configuration -SDRAM

The memory controller 2440 a total of 13 registers.

BANK0 - BANK5 just set BWSCON and BANKCONx (x is 0-5) two registers;
when BANK6, BANK7 external SDRAM, and other BWSCON BANKCONx (x 6,7), but also set the REFRESH, BANKSIZE, MRSRB6, MRSRB7 other four registers.

The following are descriptions of each register is provided from:

1 -bit wide registers and wait control BWSCON (the BUSWIDTH & WAITCONTROLREGISTER)

我们SDRAM的位宽为32,DW6[25:24]设置成10, 没有使用等待信号,所以WS6[26]=0。 bank7跟随bank6的配置,
因此BWSCON寄存器的值为:0x22000000。

2. the BANK control register BANKCON6 (BANKCONTROLREGISTER)

In eight BANK, only BANK6 and BANK7 external SRAM may or SDRAM.

MT[16:15]:设置BANK是ROM/SRAM还是DRAM,我们用的SDRAM,属于DRAM。
Trcd[3:2]:行地址和列地址间隔多长时间,看SDRAM芯片手册时间间隔Trcd>18ns,我们HCLK=100MHZ,clocks为10ns,所以设置为2clocks即可。

SCAN[1:0]:SDRAM的列地址位数,上面的图片已经查看sdram手册分析过,列地址位数为9。
综上所述,本开发板中BANKCON6设为0x017001

3. Refresh Control Register the REFRESH (REFRESHCONTROLREGISTER)

REFEN[23]:设置开启SDRAM的刷新功能。
TREFMD[22]:SDRAM的刷新模式,0=CBR/AutoRefresh,选择自动刷新。

Trp[21:20]:根据sdram手册Trp>18ns, 设为0(2 clocks)即可。
Tsrc[19:18]: Tsrc = Trc - Trp = Trc-20, 根据sdram手册Trc>=60,我们取Trc =70, 则Tsrc= 50ns(5clocks)即可。
RefreshCounter[10:0]:Refresh period = (211-refresh_count+1)/HCLK,
RefreshCount = 211 + 1 - 100*Refresh period,看SDRAM手册“8192 refresh cycles/64ms”, Refresh period= 64000us/8192 = 7.8us,
RefreshCount取推荐值1269= 0x4f5.
综上,REFRESH寄存器设为0x8404F5。

4. BANKSIZE register the REFRESH (BANKSIZEREG ister)

BURST_EN[7]:0=ARM核禁上突发传输,1=ARM核支持突发传输(推荐);
SCKEEN[5]:0=不使用SCKE信号令SDRAM进入省电模式,1=使用SCKE信号令SDRAM进入省电模式(推荐);
SCLK-EN[4]:0=时刻发出SCLK信号,1=仅在访问SDRAM期间发出SCLK信号(推荐);
BK76MAP[2:0]:配置banksize成64M
因此,BANKSIZE寄存器设为0xB1。

5. The the SDRAM mode register set MRSRBx6 (the SDRAM the MODE the REGISTER the SET the REGISTER)

CL[6:4]:表示发出行、列地址后,等多久才返回收到数据, 看SDRAM手册发现Tcas >=18ns,所以配置成2 clocks即可。
MRSRB6寄存器设置为0x20。

code show as below:

void sdram_init(void)
{
    BWSCON = 0x22000000;

    BANKCON6 = 0x18001;
    BANKCON7 = 0x18001;

    REFRESH  = 0x8404f5;

    BANKSIZE = 0xb1;

    MRSRB6   = 0x20;
    MRSRB7   = 0x20;
}

int sdram_test(void)
{
    volatile unsigned char *p = (volatile unsigned char *)0x30000000;//sdram base addr
    int i;

    // write sdram
    for (i = 0; i < 1000; i++)
        p[i] = 0x55;

    // read sdram
    for (i = 0; i < 1000; i++)
        if (p[i] != 0x55)
            return -1;

    return 0;
}
int main(void)
{
    uart0_init();

    sdram_init();

    if (sdram_test() == 0)
        led_test();
    
    return 0;
}

Test result:
When the content can be accessed after sdram_init 0x3000_0000 address, led water lights flashing.
Not initialize sdram_init, run the program stuck.

Guess you like

Origin www.cnblogs.com/fuzidage/p/12024056.html