DDR学习笔记

发布者:科技革新者最新更新时间:2024-10-15 来源: cnblogs关键字:DDR  学习笔记 手机看文章 扫描二维码
随时随地手机看文章

DDR

15条地址线32k 

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


查看6410芯片手册;

5.4.3 DDR/MOBILE DDR SDRAM INITIALIZATION SEQUENCE 

• Program mem_cmd in direct_cmd to ‘2’b10’, which makes DRAM Controller issue ‘NOP’ memory command. 

• Program mem_cmd in direct_cmd to ‘2’b00’, which makes DRAM Controller issue ‘Prechargeall’ memory 

command. 

• Program mem_cmd in direct_cmd to ‘2’b11’, which makes DRAM Controller issue ‘Autorefresh’ memory 

command. 

• Program mem_cmd in direct_cmd to ‘2’b11’, which makes DRAM Controller issue ‘Autorefresh’ memory 

command. 

• Program mem_cmd to ‘2’b10’ in direct_cmd, which makes DRAM Controller issue ‘MRS’ memory command 

− Bank address for EMRS must be set. 

• Program mem_cmd to ‘2’b10’ in direct_cmd, which makes DRAM Controller issue ‘MRS’ memory command. 

− Bank address for MRS must be set. 

 

 

0x50000000  0x5FFFFFFF  - -  - - - DRAM Ctrl 1  

 

示例代码如下:

sratr.S文件

.globl _start

_start:

/*硬件相关设置*/

ldr r0, =0x70000000

orr r0,r0,#0x13

mcr p15,0,r0,c15,c2,4

/*关看门狗*/

ldr r0,=0x7E00400

mov r1,#0

str r1,[r0]

 

/*初始化时钟*/

bl clock_init

 

/*为C函数准备环境*/

ldr sp,=8*1024

bl sdram_init

 

/*重定位代码*/

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

ldr r1,=_start /*_start 的链接地址*/

 

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

 

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

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

 

copy_loop:

ldr r3,[r0],#4

str r3,[r1],#4

cmp r1,r2

bne copy_loop

 

/*清除bss段*/

clean_bss:

ldr r0,=bss_start

ldr r1,=bss_end

mov r3,#0

cmp r0,r1

beq on_ddr

clean_loop:

str r3,[r0],#4

cmp r0,r1

bne clean_loop

 

/*调用C函数*/

on_ddr:

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

 

 

clock.S文件

#define APLL_CLOCK 0x7e00f000

#define MPLL_CLOCK 0x7e00f004

#define EPLL_CLOCK 0x7e00f008

#define LOCK_TIME 0xffff

 

#define OTHERS 0x7e00f900

#define CLK_DIV0 0x7e00f020

#define CLK_SRC 0x7e00f01c

 

.text

.global clock_init

clock_init:

/*设置lock_time*/

ldr r0,=APLL_CLOCK

ldr r1,=LOCK_TIME

 

str r1,[r0] /*APLL_LOCK*/

str r1,[r0,#4] /*MPLL_LOCK*/

str r1,[r0,#8] /*EPLL_LOCK*/

 

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

ldr r0,=OTHERS

ldr r1,[r0]

bic r1,#0xc0

str r1,[r0]

 

loop1:

ldr r0,=OTHERS

ldr r1,[r0]

and r1,#0xf00

cmp r1,#0

bne loop1

 

#define ARM_RATIO 0

#define HCLKX2_RATIO 1

#define HCLK_RATIO 1

#define PCLK_RATIO 3

#define MPLL_RATIO 0

 

ldr r0,=CLK_DIV0

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

str r1,[r0]

 

/*配置时钟 apll mpll epll*/

#define SDIV 1

#define PDIV 3

#define MDIV 266

#define PLL_ENABLE (1<<31)

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

#define MPLL_VAL APLL_VAL

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

#define EPLL1_VAL (0)

 

#define APLL_CON 0x7e00f00c

#define MPLL_CON 0x7e00f010

#define EPLL_CON0 0x7e00f014

#define EPLL_CON1 0x7e00f018

 

ldr r0,=APLL_CON

ldr r1,=APLL_VAL

str r1,[r0]

 

ldr r0, =MPLL_CON

ldr r1, =MPLL_VAL

str r1, [r0]

 

ldr r0, =EPLL_CON0

ldr r1, =EPLL0_VAL

str r1, [r0]

 

ldr r0, =EPLL_CON1

ldr r1, =EPLL1_VAL

str r1, [r0]

 

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

ldr r0, =CLK_SRC

mov r1, #7

str r1, [r0]

 

mov pc, lr

 

 

Common.h文件

#ifndef __COMMON_H

#define __COMMON_H

 

#define vi *( volatile unsigned int * ) 

 

#define set_zero( addr, bit ) ( (vi addr) &= ( ~ ( 1 << (bit) ) ) )

#define set_one( addr, bit ) ( (vi addr) |= ( 1 << ( bit ) ) )

 

#define set_bit( addr, bit, val ) ( (vi addr) = (( vi addr)&=(~(1<<(bit))) ) | ( (val)<<(bit) ) )

 

#define set_2bit( addr, bit, val ) ( (vi addr) = (( vi addr)&(~(3<<(bit))) ) | ( (val)<<(bit) ) )

 

#define set_nbit( addr, bit, len,  val ) 

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

 

#define get_bit( addr, bit ) ( (( vi addr ) & ( 1 << (bit) )) > 0  )

 

#define get_val( addr, val ) ( (val) = vi addr )

#define read_val( addr ) ( vi ( addr ) )

#define set_val( addr, val ) ( (vi addr) = (val) )

#define or_val( addr, val ) ( (vi addr) |= (val) ) 

 

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

 

typedef unsigned char u8;

typedef unsigned short u16;

typedef unsigned int u32;

 

// function declare

 

int delay( int );

 

#endif /* __COMMON_H */

 

 

 

Sdram.c文件

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

 

// 设置refresh period

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

 

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

 

// 设置mem cfg 

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

 

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

 

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

set_val( P1MEMCCMD, 0x000 );

 

// 准备就绪

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

[1] [2]
关键字:DDR  学习笔记 引用地址:DDR学习笔记

上一篇:nand flash学习笔记一
下一篇:链接地址学习笔记

推荐阅读最新更新时间:2026-03-25 17:55

s3c6410学习笔记-将内核zImage、文件系统写到nandflash、屏幕校准
1、之前已经将uboot写到nandflash里面了,接下来将内核zImage、文件系统写到nandflash。 2、编译内核 cd linux-2.6.28_smdk6410 make clean make distclean cp smdk6410_config .config make menuconfig    将Device Drivers ---》Graphics support --- Support for frame buffer devices --- select LCD       Type 分辨率调到480*272 保存(之后要校准屏幕) make   make 完成之后将 /arch/a
[单片机]
s3c6410学习笔记-烧写uboot+构建文件系统
一、进入目录 #cd u-boot-1.1.6_sndk6410 二、SD卡 make clean make distclean vim Makefile (/CROSS 修改cross-compile= ....) vim /include/configs/smdk6410.h (改205行名字,改448行启动方式为SD卡) make smdk6410_config make ./mkmovi (生成u-boot-movi.bin) ./write_sd /dev/sdb u-boot-movi.bin (写到SD卡) 三、nandfl
[单片机]
IMX6ULL学习笔记(21)——MMDC接口使用(DDR3测试)
一、MMDC简介 MMDC 接口与 STM32 的 FSMC 接口类似,只不过 MMDC 接口专用于外接 DDR,并且 MMDC 外部引脚不复用。MMDC 是一个多模的 DDR 控制器,可以连接 16 位宽的 DDR3/DDR3L、16 位宽的 LPDDR2。 MMDC 是一个可配置、高性能的 DDR 控制器。MMDC 外设包含一个内核(MMDC_CORE)和 PHY(MMDC_PHY),内核和 PHY 的功能如下: MMDC_CORE 负责通过 AXI 接口与系统进行通信,实现 DDR 命令生成、DDR 命令优化和读写数据路径。控制整个 MMDC 的功能实现。 MMDC_PHY 负责时序调整和校准,使用特殊的校准机制以
[单片机]
IMX6ULL<font color='red'>学习</font><font color='red'>笔记</font>(21)——MMDC接口使用(<font color='red'>DDR</font>3测试)
OK6410A学习笔记一:一键烧录Linux
去年5月份买的飞凌OK6410A开发板,但是一直没有怎么用,主要是自己懒,呵呵,都是废话 开发环境: windows7 + vmware 6.5 + ubuntu 9.10 烧录步骤: 1)SD卡,格式化成FAT32格式,然后用SD_Write.exe将mmc.bin烧录进去。 windows7下要在管理员模式下运行SD_Write.exe,烧录mmc.bin之前要点击Format 2)把u-boot.bin,zImage,cramfs拷贝到SD卡中 OK6410A支持cramfs和yaffs2文件系统,前者为compressed ram file system,后者为yet another f
[单片机]
6410平台上配置Linux的DDR参数
前段时间为了解决一个从128M升级到256M的DDR问题,搞的是焦头烂额。最后在别人讨论的情况下终于试出来了正确结果,下来还得自己总结下。 自己的硬件平台才采用的是6410的DMC1即32位的DRAM控制器,两个16位128M的DDR的地址线是共在一起连在6410的16根地址线上,数据线是并在一起成32位连在6410上,其它控制脚对应接上。软件之前写入128M运行OK,改成256M出现页面分配错误导致fatal error而死机。最后发觉是少改了一个地方。 综合起来有以下三个地方要确认: 1,UBOOT中的smdk6410.h #define MEMORY_BASE_ADDRESS 0x50000
[单片机]
【STM32学习笔记】深入解析EXTI外部中断功能
EXTI外部中断 表的详细内容在STM32F10xxx参考手册132页有, 然后右边这里还有个中断的地址,这个地址是干什么的呢?这个是因为我们程序中的中断函数,它的地址是由编译器来分配的,是不固定的。但是我们的中断跳转由于硬件的限制,只能跳到固定的地址执行程序,所以为了能让硬件跳转到一个不固定的中断函数里,这里就需要在内存中定义一个地址的列表。这个列表地址是固定的,中断发生后,就跳到这个固定位置,然后在这个固定位置由编译器,再加上一条跳转到中断函数的代码,这样中断跳转就可以跳转到任意位置。这个中断地址的列表,就叫中断向量表。 NVIC基本结构 这个NVIC的名字叫做嵌套中断向量控制器,在STM32中,它是用来统一分配
[单片机]
【STM32<font color='red'>学习</font><font color='red'>笔记</font>】深入解析EXTI外部中断功能
stm32通用定时器(TIMx)学习笔记
1:通用定时器包括一个由可编程的预分频器驱动的16 位自动重载计数器。通用定时器可用于多种用途,例如测量输入信号的脉冲宽度(输入捕获),生成输出波形(输出比较和PWM)。脉冲宽度和波形周期可通过定时器的预分频器及RCC 时钟控制器的预分频器在几微秒到几毫秒之间调整。这些通用定时器是完全独立的,不共享任何资源。 2:特性 16 位的向上,向下,向上/向下的自动重载计数器 16 位的可编程预分频器(也可以不工作)允许以在1 到65535 范围内的任何因子对计数器时钟进行分频 多达4 个独立的通道用于: - 输入捕获 - 输出比较 - 产生PWM(边沿和中心对齐模式) - 单脉冲输出 同步电
[单片机]
单片机STM32的启动文件详解--学习笔记
  启动文件简介   启动文件由汇编编写,是系统上电复位后第一个执行的程序。主要做了以下工作:   1、初始化堆栈指针SP=_initial_sp   2、初始化PC 指针=Reset_Handler   3、初始化中断向量表   4、配置系统时钟   5、调用C 库函数_main 初始化用户堆栈,从而最终调用main 函数去到C 的世界   查找ARM 汇编指令   在讲解启动代码的时候,会涉及到ARM 的汇编指令和Cortex 内核的指令,剩下的ARM的汇编指令我们可以在MDK- Help- Uvision Help 中搜索到,以EQU 为例,检索如下:      图1 ARM 汇编指令索引   检索出来的结果会有很多,
[单片机]
单片机STM32的启动文件详解--<font color='red'>学习</font><font color='red'>笔记</font>
小广播
最新单片机文章
何立民专栏 单片机及嵌入式宝典

北京航空航天大学教授,20余年来致力于单片机与嵌入式系统推广工作。

厂商技术中心

 
EEWorld订阅号

 
EEWorld服务号

 
汽车开发圈

 
机器人开发圈

电子工程世界版权所有 京ICP证060456号 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2026 EEWORLD.com.cn, Inc. All rights reserved