tiny6410裸机实验第5章--------------DDR初始化等(代码)

【说明】

              根据上一节介绍的原理,很容易写出DDR的初始化代码,这节附上代码,包括代码重定位,以及初始化DDR。

 

【初始化DDR】

                common.h...包含了一些通用宏定义

                 

[cpp]  view plain copy 在CODE上查看代码片 派生到我的代码片
  1. #ifndef __COMMON_H  
  2. #define __COMMON_H  
  3.   
  4. #define vi *( volatile unsigned int * )   
  5.   
  6. #define set_zero( addr, bit ) ( (vi addr) &= ( ~ ( 1 << (bit) ) ) )  
  7. #define set_one( addr, bit ) ( (vi addr) |= ( 1 << ( bit ) ) )  
  8.   
  9. #define set_bit( addr, bit, val ) ( (vi addr) = (( vi addr)&=(~(1<<(bit))) ) | ( (val)<<(bit) ) )  
  10.   
  11. #define set_2bit( addr, bit, val ) ( (vi addr) = (( vi addr)&(~(3<<(bit))) ) | ( (val)<<(bit) ) )  
  12.   
  13. #define set_nbit( addr, bit, len,  val ) \  
  14.         ( (vi addr) = ((( vi addr)&(~(( ((1<<(len))-1) )<<(bit))))  | ( (val)<<(bit) ) ))  
  15.   
  16. #define get_bit( addr, bit ) ( (( vi addr ) & ( 1 << (bit) )) > 0  )  
  17.   
  18. #define get_val( addr, val ) ( (val) = vi addr )  
  19. #define read_val( addr ) ( vi ( addr ) )  
  20. #define set_val( addr, val ) ( (vi addr) = (val) )  
  21. #define or_val( addr, val ) ( (vi addr) |= (val) )   
  22.   
  23. ///  
  24.   
  25. typedef unsigned char u8;  
  26. typedef unsigned short u16;  
  27. typedef unsigned int u32;  
  28.   
  29. // function declare  
  30.   
  31. int delay( int );  
  32.   
  33. #endif /* __COMMON_H */  


 

             sdram.c  初始化代码

            

[cpp]  view plain copy 在CODE上查看代码片 派生到我的代码片
  1. // 功能:初始化dram控制器(dramc)  
  2.   
  3. #include "common.h"  
  4. #define MEMCCMD         0x7e001004  
  5. #define P1REFRESH       0x7e001010  
  6. #define P1CASLAT        0x7e001014  
  7. #define MEM_SYS_CFG     0x7e00f120  
  8. #define P1MEMCFG        0x7e00100c  
  9. #define P1T_DQSS        0x7e001018  
  10. #define P1T_MRD         0x7e00101c  
  11. #define P1T_RAS         0x7e001020  
  12. #define P1T_RC          0x7e001024  
  13. #define P1T_RCD         0x7e001028  
  14. #define P1T_RFC         0x7e00102c  
  15. #define P1T_RP          0x7e001030  
  16. #define P1T_RRD         0x7e001034  
  17. #define P1T_WR          0x7e001038  
  18. #define P1T_WTR         0x7e00103c  
  19. #define P1T_XP          0x7e001040  
  20. #define P1T_XSR         0x7e001044  
  21. #define P1T_ESR         0x7e001048  
  22. #define P1MEMCFG2       0X7e00104c  
  23. #define P1_chip_0_cfg   0x7e001200  
  24.   
  25. #define P1MEMSTAT       0x7e001000  
  26. #define P1MEMCCMD       0x7e001004  
  27. #define P1DIRECTCMD     0x7e001008  
  28.   
  29.   
  30. #define HCLK    133000000  
  31.   
  32. #define nstoclk(ns)     ( ns/(1000000000/HCLK)+1 )                      //+1是四舍五入  
  33.   
  34. /* 根据6410手册P192页相关步骤和sdram手册来初始化dram控制器(dramc) */  
  35. int sdram_init( void )  
  36. {  
  37.         /* 1. 使dramc进入"config"状态 */  
  38.         set_val(P1MEMCCMD, 0x4);  
  39.   
  40.         /* 2. 设置timing parameter, chip configuration,id configuration registers */  
  41.         /* 2.1 刷新周期 */  
  42.         set_val(P1REFRESH, nstoclk(7800));                                      //刷新周期:(7.8us)/((1/HCLK)s)=(7.8*10^3)/(1/133*10^6)  
  43.         /* 2.2 时间参数,下列设置全都是取了最小值 */  
  44.         set_val( P1CASLAT, ( 3 << 1 ) );                                        //CAS Latency:指的是内存存取数据所需的延迟时间,简单的说,就是内存接到CPU的指令后的反应速度。一般的参数值是2和3两种。K4X1G163PQ的芯片手册上CAS Latency=3   
  45.         set_val( P1T_DQSS, 0x1 );                                                       //下列设置均在sdram手册中可查询到  
  46.         set_val( P1T_MRD, 0x2 );  
  47.         set_val( P1T_RAS, nstoclk(42) );  
  48.         set_val( P1T_RC, nstoclk(60) );  
  49.         u32 trcd = nstoclk( 18 );  
  50.         set_val( P1T_RCD, trcd | (( trcd - 3 ) << 3 ) );  
  51.         u32 trfc = nstoclk( 72 );  
  52.         set_val( P1T_RFC, trfc | ( ( trfc-3 ) << 5 ) );     
  53.         u32 trp = nstoclk( 18 );  
  54.         set_val( P1T_RP, trp | ( ( trp - 3 ) << 3 ) );   
  55.         set_val( P1T_RRD, nstoclk(12) );  
  56.         set_val( P1T_WR, nstoclk(12) );  
  57.   
  58.         set_val( P1T_WTR, 0x1 );  
  59.         set_val( P1T_XP, 0x1 );  
  60.         set_val( P1T_XSR, nstoclk(120) );  
  61.         set_val( P1T_ESR, nstoclk(120) );  
  62.   
  63.         /* 2.3 chip configuration */  
  64.         set_nbit( P1MEMCFG, 0, 3, 0x2 );                                        // column address(10):A0~A9  
  65.         set_nbit( P1MEMCFG, 3, 3, 0x3 );                                        // row address(14):A0~A13  
  66.         set_zero( P1MEMCFG, 6 );                                                        // A10/AP   
  67.         set_nbit( P1MEMCFG, 15, 3, 0x2 );                                       //  Burst Length (2, 4, 8, 16)  
  68.         set_nbit( P1MEMCFG2, 0, 4, 0x5 );  
  69.         set_2bit( P1MEMCFG2, 6, 0x1 );                                          // 32 bit   
  70.         set_nbit( P1MEMCFG2, 8, 3, 0x3 );                                       // Mobile DDR SDRAM   
  71.         set_2bit( P1MEMCFG2, 11, 0x1 );  
  72.         set_one( P1_chip_0_cfg, 16 );                                           // Bank-Row-Column organization   
  73.   
  74.         /* 3. 初始化sdram */  
  75.         set_val( P1DIRECTCMD, 0xc0000 );                                        // NOP  
  76.         set_val( P1DIRECTCMD, 0x000 );                                          // precharge  
  77.         set_val( P1DIRECTCMD, 0x40000 );                                        // auto refresh  
  78.         set_val( P1DIRECTCMD, 0x40000 );                                        // auto refresh  
  79.         set_val( P1DIRECTCMD, 0xa0000 );                                        // EMRS  
  80.         set_val( P1DIRECTCMD, 0x80032 );                                        // MRS  
  81.   
  82.         set_val( MEM_SYS_CFG, 0x0 );  
  83.   
  84.         /* 4. 使dramc进入"ready"状态    */  
  85.         set_val( P1MEMCCMD, 0x000 );  
  86.         while( !(( read_val( P1MEMSTAT ) & 0x3 ) == 0x1));// 等待dramc进入"ready"状态  
  87. }  


【代码重定位】

                  start.S       其中的_bss_start  等符号来至链接脚本,,,链接脚本同以前

                 

[cpp]  view plain copy 在CODE上查看代码片 派生到我的代码片
  1. // 启动代码  
  2. .global _start  
  3.   
  4. _start:  
  5.   
  6.         // 把外设的基地址告诉CPU  
  7.         ldr r0, =0x70000000   
  8.         orr r0, r0, #0x13  
  9.         mcr p15,0,r0,c15,c2,4  
  10.   
  11.         // 关看门狗  
  12.         ldr r0, =0x7E004000  
  13.         mov r1, #0  
  14.         str r1, [r0]   
  15.   
  16.         // 设置栈  
  17.         ldr sp, =8*1024  
  18.   
  19.         // 开启icaches  
  20. #ifdef  CONFIG_SYS_ICACHE_OFF  
  21.         bic r0, r0, #0x00001000                                 @ clear bit 12 (I) I-cache  
  22. #else  
  23.         orr r0, r0, #0x00001000                                 @ set bit 12 (I) I-cache  
  24. #endif  
  25.         mcr p15, 0, r0, c1, c0, 0  
  26.   
  27.         // 设置时钟  
  28.         bl clock_init  
  29.   
  30.         // 初始化sdram  
  31.         bl sdram_init  
  32.   
  33.         // 重定位  
  34.         adr r0, _start   
  35.         ldr r1, =_start  
  36.         ldr r2, =bss_start  
  37.         cmp r0, r1              // 这里是看程序是否已经在需要的位置了,如果是就不用重定位了  
  38.         beq clean_bss                   
  39. copy_loop:                     //这里真正的是重定位代码,很简单,就是读写读写。。。  
  40.         ldr r3, [r0], #4  
  41.         str r3, [r1], #4  
  42.         cmp r1, r2  
  43.         bne copy_loop  
  44.   
  45.         // 清BSS段  
  46. clean_bss:  
  47.         ldr r0, =bss_start  
  48.         ldr r1, =bss_end  
  49.         mov r3, #0  
  50.         cmp r0, r1  
  51.         beq on_ddr  
  52. clean_loop:  
  53.         str r3, [r0], #4  
  54.         cmp r0, r1  
  55.         bne clean_loop  
  56.   
  57.   
  58.         // 调用main函数  
  59. on_ddr:  
  60.         ldr pc, =main  
  61. halt:  
  62.         b halt  

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值