`

DDR学习笔记

阅读更多

DDR

15条地址线32k

128M*2(20)=2(27)

 

 

 

查看6410芯片手册;

5.4.3DDR/MOBILEDDRSDRAMINITIALIZATIONSEQUENCE

Programmem_cmdindirect_cmdto2b10,whichmakesDRAMControllerissueNOPmemorycommand.

Programmem_cmdindirect_cmdto2b00,whichmakesDRAMControllerissuePrechargeallmemory

command.

Programmem_cmdindirect_cmdto2b11,whichmakesDRAMControllerissueAutorefreshmemory

command.

Programmem_cmdindirect_cmdto2b11,whichmakesDRAMControllerissueAutorefreshmemory

command.

Programmem_cmdto2b10indirect_cmd,whichmakesDRAMControllerissueMRSmemorycommand

BankaddressforEMRSmustbeset.

Programmem_cmdto2b10indirect_cmd,whichmakesDRAMControllerissueMRSmemorycommand.

BankaddressforMRSmustbeset.

 

 

0x500000000x5FFFFFFF-----DRAMCtrl1

 

示例代码如下:

sratr.S文件

.globl_start

_start:

/*硬件相关设置*/

ldrr0,=0x70000000

orrr0,r0,#0x13

mcrp15,0,r0,c15,c2,4

/*关看门狗*/

ldrr0,=0x7E00400

movr1,#0

strr1,[r0]

 

/*初始化时钟*/

blclock_init

 

/*C函数准备环境*/

ldrsp,=8*1024

blsdram_init

 

/*重定位代码*/

adrr0,_start/*取得_start指令当前所在位置*/

ldrr1,=_start/*_start的链接地址*/

 

ldrr2,=bss_start/*bss段的起始地址*/

 

cmpr0,r1/*比较两寄存器的值*/

beqclean_bss/*如果两个值相同,跳转到clean_bss*/

 

copy_loop:

ldrr3,[r0],#4

strr3,[r1],#4

cmpr1,r2

bnecopy_loop

 

/*清除bss*/

clean_bss:

ldrr0,=bss_start

ldrr1,=bss_end

movr3,#0

cmpr0,r1

beqon_ddr

clean_loop:

strr3,[r0],#4

cmpr0,r1

bneclean_loop

 

/*调用C函数*/

on_ddr:

ldrpc,=main/*pc等于main的链接地址*/

 

 

clock.S文件

#defineAPLL_CLOCK0x7e00f000

#defineMPLL_CLOCK0x7e00f004

#defineEPLL_CLOCK0x7e00f008

#defineLOCK_TIME0xffff

 

#defineOTHERS0x7e00f900

#defineCLK_DIV00x7e00f020

#defineCLK_SRC0x7e00f01c

 

.text

.globalclock_init

clock_init:

/*设置lock_time*/

ldrr0,=APLL_CLOCK

ldrr1,=LOCK_TIME

 

strr1,[r0]/*APLL_LOCK*/

strr1,[r0,#4]/*MPLL_LOCK*/

strr1,[r0,#8]/*EPLL_LOCK*/

 

/*cpu时钟!=HCLK时,设置为异步模式*/

ldrr0,=OTHERS

ldrr1,[r0]

bicr1,#0xc0

strr1,[r0]

 

loop1:

ldrr0,=OTHERS

ldrr1,[r0]

andr1,#0xf00

cmpr1,#0

bneloop1

 

#defineARM_RATIO0

#defineHCLKX2_RATIO1

#defineHCLK_RATIO1

#definePCLK_RATIO3

#defineMPLL_RATIO0

 

ldrr0,=CLK_DIV0

ldrr1,=(ARM_RATIO)|(MPLL_RATIO<<4)|(HCLK_RATIO<<8)|(HCLKX2_RATIO<<9)|(PCLK_RATIO<<12)

strr1,[r0]

 

/*配置时钟apllmpllepll*/

#defineSDIV1

#definePDIV3

#defineMDIV266

#definePLL_ENABLE(1<<31)

#defineAPLL_VAL((SDIV<<0)|(PDIV<<8)|(MDIV<<16)|(PLL_ENABLE))

#defineMPLL_VALAPLL_VAL

#defineEPLL0_VAL((2<<0)|(1<<8)|(32<<16)|PLL_ENABLE)

#defineEPLL1_VAL(0)

 

#defineAPLL_CON 0x7e00f00c

#defineMPLL_CON 0x7e00f010

#defineEPLL_CON0 0x7e00f014

#defineEPLL_CON1 0x7e00f018

 

ldrr0,=APLL_CON

ldrr1,=APLL_VAL

strr1,[r0]

 

ldrr0,=MPLL_CON

ldrr1,=MPLL_VAL

strr1,[r0]

 

ldrr0,=EPLL_CON0

ldrr1,=EPLL0_VAL

strr1,[r0]

 

ldrr0,=EPLL_CON1

ldrr1,=EPLL1_VAL

strr1,[r0]

 

/*选择PLL的输出作为时钟源*/

ldrr0,=CLK_SRC

movr1,#7

strr1,[r0]

 

movpc,lr

 

 

Common.h文件

#ifndef__COMMON_H

#define__COMMON_H

 

#definevi*(volatileunsignedint*)

 

#defineset_zero(addr,bit)((viaddr)&=(~(1<<(bit))))

#defineset_one(addr,bit)((viaddr)|=(1<<(bit)))

 

#defineset_bit(addr,bit,val)((viaddr)=((viaddr)&=(~(1<<(bit))))|((val)<<(bit)))

 

#defineset_2bit(addr,bit,val)((viaddr)=((viaddr)&(~(3<<(bit))))|((val)<<(bit)))

 

#defineset_nbit(addr,bit,len,val)\

((viaddr)=(((viaddr)&(~((((1<<(len))-1))<<(bit))))|((val)<<(bit))))

 

#defineget_bit(addr,bit)(((viaddr)&(1<<(bit)))>0)

 

#defineget_val(addr,val)((val)=viaddr)

#defineread_val(addr)(vi(addr))

#defineset_val(addr,val)((viaddr)=(val))

#defineor_val(addr,val)((viaddr)|=(val))

 

/**********************************************/

 

typedefunsignedcharu8;

typedefunsignedshortu16;

typedefunsignedintu32;

 

//functiondeclare

 

intdelay(int);

 

#endif/*__COMMON_H*/

 

 

 

Sdram.c文件

#include"common.h"

 

#defineMEMCCMD 0x7e001004

#defineP1REFRESH 0x7e001010

#defineP1CASLAT 0x7e001014

#defineMEM_SYS_CFG 0x7e00f120

#defineP1MEMCFG 0x7e00100c

#defineP1T_DQSS 0x7e001018

#defineP1T_MRD 0x7e00101c

#defineP1T_RAS 0x7e001020

#defineP1T_RC 0x7e001024

#defineP1T_RCD 0x7e001028

#defineP1T_RFC 0x7e00102c

#defineP1T_RP 0x7e001030

#defineP1T_RRD 0x7e001034

#defineP1T_WR 0x7e001038

#defineP1T_WTR 0x7e00103c

#defineP1T_XP 0x7e001040

#defineP1T_XSR 0x7e001044

#defineP1T_ESR 0x7e001048

#defineP1MEMCFG2 0X7e00104c

#defineP1_chip_0_cfg 0x7e001200

 

#defineP1MEMSTAT 0x7e001000

#defineP1MEMCCMD 0x7e001004

#defineP1DIRECTCMD 0x7e001008

 

 

#defineHCLK 133000000

 

#definenstoclk(ns) (ns/(1000000000/HCLK)+1)

 

intsdram_init(void)

{

//telldramctoconfigure

set_val(MEMCCMD,0x4);

 

//设置refreshperiod

set_val(P1REFRESH,nstoclk(7800));

 

//设置时序

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));

 

//设置memcfg

set_nbit(P1MEMCFG,0,3,0x2);/*10columnaddress*/

 

/*set_nbit:把从第bit位开始的一共len位消零,然后把这几位设为val*/

 

set_nbit(P1MEMCFG,3,3,0x2);/*13rowaddress*/

set_zero(P1MEMCFG,6); /*A10/AP*/

set_nbit(P1MEMCFG,15,3,0x2);/*Burst4*/

 

set_nbit(P1MEMCFG2,0,4,0x5);

set_2bit(P1MEMCFG2,6,0x1); /*32bit*/

set_nbit(P1MEMCFG2,8,3,0x3); /*MobileDDRSDRAM*/

set_2bit(P1MEMCFG2,11,0x1);

 

set_one(P1_chip_0_cfg,16); /*Bank-Row-Columnorganization*/

 

//memoryinit

set_val(P1DIRECTCMD,0xc0000);//NOP

set_val(P1DIRECTCMD,0x000); //precharge

set_val(P1DIRECTCMD,0x40000);//autorefresh

set_val(P1DIRECTCMD,0x40000);//autorefresh

set_val(P1DIRECTCMD,0xa0000);//EMRS

set_val(P1DIRECTCMD,0x80032);//MRS

 

set_val(MEM_SYS_CFG,0x0);

 

//设置内存控制器(dramc)状态为go

set_val(P1MEMCCMD,0x000);

 

//准备就绪

while(!((read_val(P1MEMSTAT)&0x3)==0x1));

}

 

 

 

Led.c

voiddelay(){

volatileinti=0x10000000;

while(i--);

}

 

intmain(){

inti=0;

volatileunsignedlong*gpkcon=(volatileunsignedlong*)0x7F008800;

volatileunsignedlong*gpkdat=(volatileunsignedlong*)0x7F008808;

*gpkcon=0x11110000;

while(1){

*gpkdat=i;

i++;

if(i==16)

i=0;

delay();

}

return0;

}

 

 

Led.lds文件

SECTIONS

{

.=0x50000000;

.text:

{

start.o

*(.text)

}

 

.=ALIGN(4);

.rodata:

{

*(.rodata)

}

 

.=ALIGN(4);

.data:

{

*(.data)

}

 

.=ALIGN(4);

 

bss_start=.;/*0x50000450*/

 

.bss:

{

*(.bss)/*i*/

*(.common)

}

 

bss_end=.;/*0x50000450*/

}

 

Makefile文件

led.bin:start.oclock.osdram.oled.o

arm-linux-ld-Tled.lds-oled.elf$^

arm-linux-objcopy-Obinaryled.elfled.bin

arm-linux-objdump-Dled.elf>led.dis

 

%.o:%.S

arm-linux-gcc-g-c-O2-o$@$^

 

%.o:%.c

arm-linux-gcc-g-c-O2-o$@$^

 

clean:

rm-f*.o*.bin*.elf*.dis

分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics