天天看點

tiny6410裸機實驗第5章--------------DDR初始化等(代碼)

【說明】

              根據上一節介紹的原理,很容易寫出DDR的初始化代碼,這節附上代碼,包括代碼重定位,以及初始化DDR。

【初始化DDR】

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

[cpp]  view plain copy

tiny6410裸機實驗第5章--------------DDR初始化等(代碼)
tiny6410裸機實驗第5章--------------DDR初始化等(代碼)
  1. #ifndef __COMMON_H  
  2. #define __COMMON_H  
  3. #define vi *( volatile unsigned int * )   
  4. #define set_zero( addr, bit ) ( (vi addr) &= ( ~ ( 1 << (bit) ) ) )  
  5. #define set_one( addr, bit ) ( (vi addr) |= ( 1 << ( bit ) ) )  
  6. #define set_bit( addr, bit, val ) ( (vi addr) = (( vi addr)&=(~(1<<(bit))) ) | ( (val)<<(bit) ) )  
  7. #define set_2bit( addr, bit, val ) ( (vi addr) = (( vi addr)&(~(3<<(bit))) ) | ( (val)<<(bit) ) )  
  8. #define set_nbit( addr, bit, len,  val ) \  
  9.         ( (vi addr) = ((( vi addr)&(~(( ((1<<(len))-1) )<<(bit))))  | ( (val)<<(bit) ) ))  
  10. #define get_bit( addr, bit ) ( (( vi addr ) & ( 1 << (bit) )) > 0  )  
  11. #define get_val( addr, val ) ( (val) = vi addr )  
  12. #define read_val( addr ) ( vi ( addr ) )  
  13. #define set_val( addr, val ) ( (vi addr) = (val) )  
  14. #define or_val( addr, val ) ( (vi addr) |= (val) )   
  15. ///  
  16. typedef unsigned char u8;  
  17. typedef unsigned short u16;  
  18. typedef unsigned int u32;  
  19. // function declare  
  20. int delay( int );  
  21. #endif   

             sdram.c  初始化代碼

[cpp]  view plain copy

tiny6410裸機實驗第5章--------------DDR初始化等(代碼)
tiny6410裸機實驗第5章--------------DDR初始化等(代碼)
  1. // 功能:初始化dram控制器(dramc)  
  2. #include "common.h"  
  3. #define MEMCCMD         0x7e001004  
  4. #define P1REFRESH       0x7e001010  
  5. #define P1CASLAT        0x7e001014  
  6. #define MEM_SYS_CFG     0x7e00f120  
  7. #define P1MEMCFG        0x7e00100c  
  8. #define P1T_DQSS        0x7e001018  
  9. #define P1T_MRD         0x7e00101c  
  10. #define P1T_RAS         0x7e001020  
  11. #define P1T_RC          0x7e001024  
  12. #define P1T_RCD         0x7e001028  
  13. #define P1T_RFC         0x7e00102c  
  14. #define P1T_RP          0x7e001030  
  15. #define P1T_RRD         0x7e001034  
  16. #define P1T_WR          0x7e001038  
  17. #define P1T_WTR         0x7e00103c  
  18. #define P1T_XP          0x7e001040  
  19. #define P1T_XSR         0x7e001044  
  20. #define P1T_ESR         0x7e001048  
  21. #define P1MEMCFG2       0X7e00104c  
  22. #define P1_chip_0_cfg   0x7e001200  
  23. #define P1MEMSTAT       0x7e001000  
  24. #define P1MEMCCMD       0x7e001004  
  25. #define P1DIRECTCMD     0x7e001008  
  26. #define HCLK    133000000  
  27. #define nstoclk(ns)     ( ns/(1000000000/HCLK)+1 )                      //+1是四舍五入  
  28. int sdram_init( void )  
  29. {  
  30.         set_val(P1MEMCCMD, 0x4);  
  31.         set_val(P1REFRESH, nstoclk(7800));                                      //重新整理周期:(7.8us)/((1/HCLK)s)=(7.8*10^3)/(1/133*10^6)  
  32.         set_val( P1CASLAT, ( 3 << 1 ) );                                        //CAS Latency:指的是記憶體存取資料所需的延遲時間,簡單的說,就是記憶體接到CPU的指令後的反應速度。一般的參數值是2和3兩種。K4X1G163PQ的晶片手冊上CAS Latency=3   
  33.         set_val( P1T_DQSS, 0x1 );                                                       //下列設定均在sdram手冊中可查詢到  
  34.         set_val( P1T_MRD, 0x2 );  
  35.         set_val( P1T_RAS, nstoclk(42) );  
  36.         set_val( P1T_RC, nstoclk(60) );  
  37.         u32 trcd = nstoclk( 18 );  
  38.         set_val( P1T_RCD, trcd | (( trcd - 3 ) << 3 ) );  
  39.         u32 trfc = nstoclk( 72 );  
  40.         set_val( P1T_RFC, trfc | ( ( trfc-3 ) << 5 ) );     
  41.         u32 trp = nstoclk( 18 );  
  42.         set_val( P1T_RP, trp | ( ( trp - 3 ) << 3 ) );   
  43.         set_val( P1T_RRD, nstoclk(12) );  
  44.         set_val( P1T_WR, nstoclk(12) );  
  45.         set_val( P1T_WTR, 0x1 );  
  46.         set_val( P1T_XP, 0x1 );  
  47.         set_val( P1T_XSR, nstoclk(120) );  
  48.         set_val( P1T_ESR, nstoclk(120) );  
  49.         set_nbit( P1MEMCFG, 0, 3, 0x2 );                                        // column address(10):A0~A9  
  50.         set_nbit( P1MEMCFG, 3, 3, 0x3 );                                        // row address(14):A0~A13  
  51.         set_zero( P1MEMCFG, 6 );                                                        // A10/AP   
  52.         set_nbit( P1MEMCFG, 15, 3, 0x2 );                                       //  Burst Length (2, 4, 8, 16)  
  53.         set_nbit( P1MEMCFG2, 0, 4, 0x5 );  
  54.         set_2bit( P1MEMCFG2, 6, 0x1 );                                          // 32 bit   
  55.         set_nbit( P1MEMCFG2, 8, 3, 0x3 );                                       // Mobile DDR SDRAM   
  56.         set_2bit( P1MEMCFG2, 11, 0x1 );  
  57.         set_one( P1_chip_0_cfg, 16 );                                           // Bank-Row-Column organization   
  58.         set_val( P1DIRECTCMD, 0xc0000 );                                        // NOP  
  59.         set_val( P1DIRECTCMD, 0x000 );                                          // precharge  
  60.         set_val( P1DIRECTCMD, 0x40000 );                                        // auto refresh  
  61.         set_val( P1DIRECTCMD, 0x40000 );                                        // auto refresh  
  62.         set_val( P1DIRECTCMD, 0xa0000 );                                        // EMRS  
  63.         set_val( P1DIRECTCMD, 0x80032 );                                        // MRS  
  64.         set_val( MEM_SYS_CFG, 0x0 );  
  65.         set_val( P1MEMCCMD, 0x000 );  
  66.         while( !(( read_val( P1MEMSTAT ) & 0x3 ) == 0x1));// 等待dramc進入"ready"狀态  
  67. }  

【代碼重定位】

                  start.S       其中的_bss_start  等符号來至連結腳本,,,連結腳本同以前

[cpp]  view plain copy

tiny6410裸機實驗第5章--------------DDR初始化等(代碼)
tiny6410裸機實驗第5章--------------DDR初始化等(代碼)
  1. // 啟動代碼  
  2. .global _start  
  3. _start:  
  4.         // 把外設的基位址告訴CPU  
  5.         ldr r0, =0x70000000   
  6.         orr r0, r0, #0x13  
  7.         mcr p15,0,r0,c15,c2,4  
  8.         // 關看門狗  
  9.         ldr r0, =0x7E004000  
  10.         mov r1, #0  
  11.         str r1, [r0]   
  12.         // 設定棧  
  13.         ldr sp, =8*1024  
  14.         // 開啟icaches  
  15. #ifdef  CONFIG_SYS_ICACHE_OFF  
  16.         bic r0, r0, #0x00001000                                 @ clear bit 12 (I) I-cache  
  17. #else  
  18.         orr r0, r0, #0x00001000                                 @ set bit 12 (I) I-cache  
  19. #endif  
  20.         mcr p15, 0, r0, c1, c0, 0  
  21.         // 設定時鐘  
  22.         bl clock_init  
  23.         // 初始化sdram  
  24.         bl sdram_init  
  25.         // 重定位  
  26.         adr r0, _start   
  27.         ldr r1, =_start  
  28.         ldr r2, =bss_start  
  29.         cmp r0, r1              // 這裡是看程式是否已經在需要的位置了,如果是就不用重定位了  
  30.         beq clean_bss                   
  31. copy_loop:                     //這裡真正的是重定位代碼,很簡單,就是讀寫讀寫。。。  
  32.         ldr r3, [r0], #4  
  33.         str r3, [r1], #4  
  34.         cmp r1, r2  
  35.         bne copy_loop  
  36.         // 清BSS段  
  37. clean_bss:  
  38.         ldr r0, =bss_start  
  39.         ldr r1, =bss_end  
  40.         mov r3, #0  
  41.         cmp r0, r1  
  42.         beq on_ddr  
  43. clean_loop:  
  44.         str r3, [r0], #4  
  45.         cmp r0, r1  
  46.         bne clean_loop  
  47.         // 調用main函數  
  48. on_ddr:  
  49.         ldr pc, =main  
  50. halt:  
  51.         b halt  

繼續閱讀