Tiny6410之重定位代码到SDRAM
在上一章中,将代码重定位到了SRAM中,但是这样的做法作用不大。正确的做法的是将代码重定位到更大的主存中,即DRAM。Tiny6410的DRAM控制寄存器最多只能支持两个同一类型的芯片。每个芯片最多可分配256MB的地址空间,所有的芯片在相同的端口共享所有的引脚,除了时钟启动信号和片选信号。
通过原理图
DRAM的地址为0x50000000
通过原理图可知SDRAM的使用的是K4X1G163PE-L(F)E/GC6。通过查看该芯片的数据手册可知道,如何启动SDRAM控制寄存器。
SDRAM 初始化顺序
上电复位时,软件必须初始化 DRAM 控制器,SDRAM 的每一项都连接到 DRAM 控制器?仅以 SDRAM 的数据表为启动程序
1 1 . M DRAM 控制器初始化顺序
(1)以 ‘3’b100’ 执行 memc_cmd,使得 DRAM 控制器输入‘配置’状态
(2)写存储器时间参数,芯片配置和 ID 配置寄存器
(3)等待 200μs 来使 SDRAM 电源和时钟稳定?当 CPU 开始工作时,电源和时钟已经被稳定下来
(4)执行存储器初始化顺序
(5)以 ‘3’b000’ 执行 memc_cmd,使得 DRAM 控制器输入‘准备’状态
(6)在 memc_stat 中检查存储器状态域,直到存储器状态变为 ‘2’b01’ ,即‘准备’
DDR/ 移动 M DDR SDRAM 初始化顺序
(1)在 direct_cmd,以‘ 2’b10 ’执行 mem_cmd,使得 DRAM 控制器产生‘NOP’存储器命令
(2)在 direct_cmd,以‘ 2’b00 ’执行 mem_cmd,使得 DRAM 控制器产生‘Prechargeall’存储器命令
(3)在 direct_cmd,以‘ 2’b11 ’执行 mem_cmd,使得 DRAM 控制器产生‘Autorefresh’存储器命令
(4)在 direct_cmd,以‘ 2’b10 ’执行 mem_cmd,使得 DRAM 控制器产生‘MRS’存储器命令
EMRS 块地址必须被设置
(5)在 direct_cmd,以‘ 2’b10 ’执行 mem_cmd,使得 DRAM 控制器产生‘MRS’存储器命令
MRS 块地址必须被设置
(6)在 direct_cmd,以‘ 2’b11 ’执行 mem_cmd,使得 DRAM 控制器产生‘Autorefresh’存储器命令
(7)在 direct_cmd,以‘ 2’b11 ’执行 mem_cmd,使得 DRAM 控制器产生‘Autorefresh’存储器命令
(8)在 direct_cmd,以‘ 2’b11 ’执行 mem_cmd,使得 DRAM 控制器产生‘Prechargeall’存储器命令
具体代码如下:
1 //Tiny6410Addr.h 2 #ifndef _Tiny6410Addr_H 3 #define _Tiny6410Addr_H 4 //GPK 5 #define GPKIO_BASE (0x7F008800) 6 #define rGPKCON0 (*((volatile unsigned long *)(GPKIO_BASE+0x00))) 7 #define rGPKDAT (*((volatile unsigned long *)(GPKIO_BASE+0x08))) 8 9 //CLOCK 10 #define APLL_LOCK (*((volatile unsigned long *)0x7E00F000)) 11 #define MPLL_LOCK (*((volatile unsigned long *)0x7E00F004)) 12 #define EPLL_LOCK (*((volatile unsigned long *)0x7E00F008)) 13 #define OTHERS (*((volatile unsigned long *)0x7e00f900)) 14 #define CLK_DIV0 (*((volatile unsigned long *)0x7E00F020)) 15 #define APLL_CON (*((volatile unsigned long *)0x7E00F00C)) 16 #define MPLL_CON (*((volatile unsigned long *)0x7E00F010)) 17 #define CLK_SRC (*((volatile unsigned long *)0x7E00F01C)) 18 19 20 21 //GPA /uart 22 #define ULCON0 (*((volatile unsigned long *)0x7F005000)) 23 #define UCON0 (*((volatile unsigned long *)0x7F005004)) 24 #define UFCON0 (*((volatile unsigned long *)0x7F005008)) 25 #define UMCON0 (*((volatile unsigned long *)0x7F00500C)) 26 #define UTRSTAT0 (*((volatile unsigned long *)0x7F005010)) 27 #define UFSTAT0 (*((volatile unsigned long *)0x7F005018)) 28 #define UTXH0 (*((volatile unsigned char *)0x7F005020)) 29 #define URXH0 (*((volatile unsigned char *)0x7F005024)) 30 #define UBRDIV0 (*((volatile unsigned short *)0x7F005028)) 31 #define UDIVSLOT0 (*((volatile unsigned short *)0x7F00502C)) 32 #define GPACON (*((volatile unsigned long *)0x7F008000)) 33 34 35 //SDRAM 36 #define P1MEMCCMD (*((volatile unsigned long *)0x7e001004)) 37 #define P1REFRESH (*((volatile unsigned long *)0x7e001010)) 38 #define P1CASLAT (*((volatile unsigned long *)0x7e001014)) 39 40 #define MEM_SYS_CFG (*((volatile unsigned long *)0x7e00f120)) 41 #define P1MEMCFG (*((volatile unsigned long *)0x7e00100c)) 42 #define P1T_DQSS (*((volatile unsigned long *)0x7e001018)) 43 #define P1T_MRD (*((volatile unsigned long *)0x7e00101c)) 44 #define P1T_RAS (*((volatile unsigned long *)0x7e001020)) 45 #define P1T_RC (*((volatile unsigned long *)0x7e001024)) 46 #define P1T_RCD (*((volatile unsigned long *)0x7e001028)) 47 #define P1T_RFC (*((volatile unsigned long *)0x7e00102c)) 48 #define P1T_RP (*((volatile unsigned long *)0x7e001030)) 49 #define P1T_RRD (*((volatile unsigned long *)0x7e001034)) 50 #define P1T_WR (*((volatile unsigned long *)0x7e001038)) 51 #define P1T_WTR (*((volatile unsigned long *)0x7e00103c)) 52 #define P1T_XP (*((volatile unsigned long *)0x7e001040)) 53 #define P1T_XSR (*((volatile unsigned long *)0x7e001044)) 54 #define P1T_ESR (*((volatile unsigned long *)0x7e001048)) 55 #define P1MEMCFG2 (*((volatile unsigned long *)0X7e00104c)) 56 #define P1_chip_0_cfg (*((volatile unsigned long *)0x7e001200)) 57 58 #define P1MEMSTAT (*((volatile unsigned long *)0x7e001000)) 59 60 #define P1DIRECTCMD (*((volatile unsigned long *)0x7e001008)) 61 62 #endif 63 64 //start.S 65 // 启动代码 66 .global _start 67 68 _start: 69 70 // 把外设的基地址告诉CPU 71 ldr r0, =0x70000000 72 orr r0, r0, #0x13 73 mcr p15,0,r0,c15,c2,4 74 75 // 关看门狗 76 ldr r0, =0x7E004000 77 mov r1, #0 78 str r1, [r0] 79 80 // 设置栈 81 ldr sp, =8*1024 82 83 // 开启icaches 84 #ifdef CONFIG_SYS_ICACHE_OFF 85 bic r0, r0, #0x00001000 @ clear bit 12 (I) I-cache 86 #else 87 orr r0, r0, #0x00001000 @ set bit 12 (I) I-cache 88 #endif 89 mcr p15, 0, r0, c1, c0, 0 90 91 // 设置时钟 92 bl clock_init 93 94 // 初始化sdram 95 bl sdram_init 96 97 // 重定位 98 adr r0, _start 99 ldr r1, =_start 100 ldr r2, =bss_start 101 cmp r0, r1 102 beq clean_bss 103 copy_loop: 104 ldr r3, [r0], #4 105 str r3, [r1], #4 106 cmp r1, r2 107 bne copy_loop 108 109 // 清BSS段 110 clean_bss: 111 ldr r0, =bss_start 112 ldr r1, =bss_end 113 mov r3, #0 114 cmp r0, r1 115 beq on_ddr 116 clean_loop: 117 str r3, [r0], #4 118 cmp r0, r1 119 bne clean_loop 120 121 122 // 调用main函数 123 on_ddr: 124 ldr pc, =main 125 halt: 126 b halt 127 //clock.c 128 #include "Tiny6410Addr.h" 129 // 功能:c语言初始化时钟 130 131 132 #define ARM_RATIO 0 // ARMCLK = DOUTAPLL / (ARM_RATIO + 1) = 532/(0+1) = 532 MHz 133 #define MPLL_RATIO 0 // DOUTMPLL = MOUTMPLL / (MPLL_RATIO + 1) = 532/(0+1) = 532 MHz 134 #define HCLKX2_RATIO 1 // HCLKX2 = HCLKX2IN / (HCLKX2_RATIO + 1) = 532/(1+1) = 266 MHz 135 #define HCLK_RATIO 1 // HCLK = HCLKX2 / (HCLK_RATIO + 1) = 266/(1+1) = 133 MHz 136 #define PCLK_RATIO 3 // PCLK = HCLKX2 / (PCLK_RATIO + 1) = 266/(3+1) = 66.5 MHz 137 138 139 140 #define APLL_CON_VAL ((1<<31) | (266 << 16) | (3 << 8) | (1)) 141 142 143 #define MPLL_CON_VAL ((1<<31) | (266 << 16) | (3 << 8) | (1)) 144 145 146 147 void clock_init(void) 148 { 149 /* 1. 设置各PLL的LOCK_TIME,使用默认值 */ 150 APLL_LOCK = 0xffff; // APLL_LOCK,供cpu使用 151 MPLL_LOCK = 0xffff; // MPLL_LOCK,供AHB(存储/中断/lcd等控制器)/APB(看门狗,定时器,SD等)总线上的设备使用 152 EPLL_LOCK = 0xffff; // EPLL_LOCK,供UART,IIS,IIC使用 153 154 /* 2. 设置为异步模式(Asynchronous mode) */ 155 OTHERS &= ~0xc0; //《linux installation for u-boot》3.7中:用MPLL作为HCLK和PCLK的Source是异步(ASYNC)模式,用APLL是同步(SYNC)模式 156 while ((OTHERS & 0xf00) != 0); 157 158 /* 3. 设置分频系数 */ 159 CLK_DIV0 = (ARM_RATIO) | (MPLL_RATIO << 4) | (HCLK_RATIO << 8) | (HCLKX2_RATIO << 9) | (PCLK_RATIO << 12); 160 161 /* 4. 设置PLL,放大时钟 */ 162 APLL_CON = APLL_CON_VAL; 163 MPLL_CON = MPLL_CON_VAL; 164 165 /* 5. 选择PLL的输出作为时钟源 */ 166 CLK_SRC = 0x03; 167 } 168 169 //sdram.c 170 #include "Tiny6410Addr.h" 171 172 #define set_zero( addr, bit ) ( addr &= ( ~ ( 1 << (bit) ) ) ) 173 #define set_one( addr, bit ) ( addr |= ( 1 << ( bit ) ) ) 174 175 #define set_bit( addr, bit, val ) ( addr = (addr &=(~(1<<(bit))) ) | ( (val)<<(bit) ) ) 176 177 #define set_2bit( addr, bit, val ) ( addr = (addr &(~(3<<(bit))) ) | ( (val)<<(bit) ) ) 178 179 #define set_nbit( addr, bit, len, val ) \ 180 ( (addr) = (((addr)&(~(( ((1<<(len))-1) )<<(bit)))) | ( (val)<<(bit) ) )) 181 182 #define get_bit( addr, bit ) ( ((addr ) & ( 1 << (bit) )) > 0 ) 183 184 #define get_val( addr, val ) ( (val) = addr ) 185 #define read_val( addr ) addr 186 #define set_val( addr, val ) ( addr = (val) ) 187 #define or_val( addr, val ) ( addr |= (val) ) 188 189 190 #define HCLK 133000000 191 192 #define nstoclk(ns) ( ns/(1000000000/HCLK)+1 ) 193 /// 194 195 typedef unsigned char u8; 196 typedef unsigned short u16; 197 typedef unsigned int u32; 198 199 // function declare 200 201 int delay( int ); 202 203 /* 根据6410手册P192页相关步骤和sdram手册来初始化dram控制器(dramc) */ 204 int sdram_init( void ) 205 { 206 /* 1. 使dramc进入"config"状态 */ 207 set_val(P1MEMCCMD, 0x4); 208 209 /* 2. 设置timing parameter, chip configuration,id configuration registers */ 210 /* 2.1 刷新周期 */ 211 set_val(P1REFRESH, nstoclk(7800)); //刷新周期:(7.8us)/((1/HCLK)s)=(7.8*10^3)/(1/133*10^6) 212 /* 2.2 时间参数,下列设置全都是取了最小值 */ 213 set_val( P1CASLAT, ( 3 << 1 ) ); //CAS Latency:指的是内存存取数据所需的延迟时间,简单的说,就是内存接到CPU的指令后的反应速度。一般的参数值是2和3两种。K4X1G163PQ的芯片手册上CAS Latency=3 214 set_val( P1T_DQSS, 0x1 ); //下列设置均在sdram手册中可查询到 215 set_val( P1T_MRD, 0x2 ); 216 set_val( P1T_RAS, nstoclk(42) ); 217 set_val( P1T_RC, nstoclk(60) ); 218 u32 trcd = nstoclk( 18 ); 219 set_val( P1T_RCD, trcd | (( trcd - 3 ) << 3 ) ); 220 u32 trfc = nstoclk( 72 ); 221 set_val( P1T_RFC, trfc | ( ( trfc-3 ) << 5 ) ); 222 u32 trp = nstoclk( 18 ); 223 set_val( P1T_RP, trp | ( ( trp - 3 ) << 3 ) ); 224 set_val( P1T_RRD, nstoclk(12) ); 225 set_val( P1T_WR, nstoclk(12) ); 226 227 set_val( P1T_WTR, 0x1 ); 228 set_val( P1T_XP, 0x1 ); 229 set_val( P1T_XSR, nstoclk(120) ); 230 set_val( P1T_ESR, nstoclk(120) ); 231 232 /* 2.3 chip configuration */ 233 set_nbit( P1MEMCFG, 0, 3, 0x2 ); // column address(10):A0~A9 234 set_nbit( P1MEMCFG, 3, 3, 0x3 ); // row address(14):A0~A13 235 set_zero( P1MEMCFG, 6 ); // A10/AP 236 set_nbit( P1MEMCFG, 15, 3, 0x2 ); // Burst Length (2, 4, 8, 16) 237 set_nbit( P1MEMCFG2, 0, 4, 0x5 ); 238 set_2bit( P1MEMCFG2, 6, 0x1 ); // 32 bit 239 set_nbit( P1MEMCFG2, 8, 3, 0x3 ); // Mobile DDR SDRAM 240 set_2bit( P1MEMCFG2, 11, 0x1 ); 241 set_one( P1_chip_0_cfg, 16 ); // Bank-Row-Column organization 242 243 /* 3. 初始化sdram */ 244 set_val( P1DIRECTCMD, 0xc0000 ); // NOP 245 set_val( P1DIRECTCMD, 0x000 ); // precharge 246 set_val( P1DIRECTCMD, 0x40000 ); // auto refresh 247 set_val( P1DIRECTCMD, 0x40000 ); // auto refresh 248 set_val( P1DIRECTCMD, 0xa0000 ); // EMRS 249 set_val( P1DIRECTCMD, 0x80032 ); // MRS 250 251 set_val( MEM_SYS_CFG, 0x0 ); 252 253 /* 4. 使dramc进入"ready"状态 */ 254 set_val( P1MEMCCMD, 0x000 ); 255 while( !(( read_val( P1MEMSTAT ) & 0x3 ) == 0x1));// 等待dramc进入"ready"状态 256 } 257 //main.c 258 259 #include "Tiny6410Addr.h" 260 #define GPK4_OUT (1<<4*4) 261 #define GPK5_OUT (1<<4*5) 262 #define GPK6_OUT (1<<4*6) 263 #define GPK7_OUT (1<<4*7) 264 //延时函数 265 void delay() 266 { 267 volatile int i = 0x10000; 268 while (i--); 269 } 270 271 int main() 272 { 273 unsigned int i = 0x10; 274 //将GPK4-7设置为输出 275 rGPKCON0 = GPK4_OUT | GPK5_OUT |GPK6_OUT |GPK7_OUT; 276 //跑马灯式 277 while (1) 278 { 279 rGPKDAT = 0x00; 280 delay(); 281 rGPKDAT = 0xF0; 282 283 } 284 285 return 0; 286 } 287 288 //ddr.lds 289 SECTIONS 290 { 291 . = 0x50000000; 292 .text : 293 { 294 start.o 295 * (.text) 296 } 297 298 . = ALIGN(4); 299 .rodata : 300 { 301 * (.rodata) 302 } 303 304 . = ALIGN(4); 305 .data : 306 { 307 * (.data) 308 } 309 310 . = ALIGN(4); 311 312 bss_start = . ; 313 314 .bss : 315 { 316 * (.bss) 317 * (.common) 318 } 319 320 bss_end = . ; 321 }
View Code
转载于:https://www.cnblogs.com/chenshikun/p/5840200.html
Tiny6410之重定位代码到SDRAM相关推荐
- Tiny6410之重定位代码到SRAM+4096
重定位代码 两个不同的地址概念: 对于程序而言,需要理解两个地址,一个是程序当前所处的地址,即程序运行时所处的当前地址.二是程序应该位于的运行地址,即编译程序时所指定的程序的链接地址.在Tiny641 ...
- uboot重定位代码分析(转)
概述 重定位(relocate)代码将BootLoader自身由Flash复制到SDRAM,以便跳转到SDRAM执行.之所以需要进行重定位是因为在Flash中执行速度比较慢,而系统复位后总是从0x00 ...
- tiny4412 裸机程序 七、重定位代码到DRAM【转】
本文转载自:http://blog.csdn.net/eshing/article/details/37116637 一.关于DRAM 上一章我们讲解了如何对代码进行重定位,但是将代码重定位到只有25 ...
- uboot为什么要重定位/代码拷贝?
参考自:https://www.cnblogs.com/Cqlismy/p/12152400.html 必看.这个老哥写的uboot启动的博客非常棒,感谢. 还有https://blog.csdn.n ...
- tiny4412 裸机程序 六、重定位代码到IRAM+0x8000【转】
本文转载自:http://blog.csdn.net/eshing/article/details/37115697 一.重定向 对于程序而言,我们需要理解两个概念,一是程序当前所处的地址,即程序在运 ...
- tiny4412 裸机程序 六、重定位代码到IRAM+0x8000
一.重定向 对于程序而言,我们需要理解两个概念,一是程序当前所处的地址,即程序在运行时,所处的当前地址:二是程序的链接地址,即程序运行时应该位于的运行地址.编译程序时,可以指定程序的链接地址.对于Ti ...
- 重定位代码Repair
此类指令都为6个字节 大致试验结果如下: 第一个字节跟操作类型相关,第二个字节跟寄存器相关,后面四个字节为地址 第二个字节高四位必须为8,9,A,B四个中的一个,低四位必为5和D中的一个,产生8种排列 ...
- 《5.SDRAM和重定位relocate》
转自 https://edu.csdn.net/lecturer/505 朱老师物联网大讲堂 <5.SDRAM和重定位relocate> 第一部分.章节目录 1.5.1.汇编写启动代码之关 ...
- 第四天:关看门狗、设置栈、控制icache、重定位、链接脚本
1.汇编写启动代码:关看门狗 什么是看门狗? 看门狗(watch dog timer看门狗定时器),比如:家门口有一只狗,这个狗定时会饿(譬如两小时一饿),狗饿了就会胡乱咬人,人进进出出要想保证安全必 ...
最新文章
- 3D视觉从入门到进阶学习路线
- LPC43xx双核笔记
- 亿级Web系统搭建――单机到分布式集群 转载
- RABBITMQ 管理指南(添加虚拟HOST)
- springboot 中根据数据库表生成所有表的model,mapper和xml文件
- 百度网盘7.3.1.10版本增加工作空间功能,可实现百度网盘与电脑文件夹同步
- flask sqlalchemy 单表查询
- python编辑器_自学python第一课之下载安装编辑器
- php易错,PHP学习1:几种常见数据类型及其易错点
- Sprin boot 加载位置顺序
- PCoIP卡由火炮升级为喀秋莎
- DHCP server 冒充及DOS攻击处理方案
- 重磅!清华大学网上课程面向全国免费开放!无需登录、注册!在家上清华!...
- 【iOS篇】在iPhone上安装描述文件
- 小程序上传图片前将图片剪切成固定尺寸
- java网页作业提交_基于JAVA网上作业提交批改系统的设计(SQL)(含录像)
- OpenCV基础入门【C++及python语言】
- Linux文件名包含小括号处理
- 诺贝尔物理学奖揭晓:LED灯将点亮整个21世纪
- python 批量打开网页并截图_Python自动截图html页面
热门文章
- Linux如何在线修改hostname
- Noip 2016 愤怒的小鸟 题解
- 某大型企业私有云建设思路解析
- 收集的安全网站【公司】
- CSS3 display:flex和display:box有什么区别?
- MSP430G2553需要注意的一些参数
- XenDesktop 5.6 PVS6.1测试中出现的一例错误:Management Interface:Remote request failed
- 我的20天项目经历--至今令我难忘的技术难题
- MongoDb 中 serverStatus was very slow 的原因分析
- DAO(Data Access Object ,数据访问对象)设计模式