Mini2440存储控制器

以前杂事比较多,没有仔细学习,这学期尽可能利用空闲时间好好学习理解。

 

@*************************************************************************
@ 设置SDRAM,将程序复制到SDRAM,然后跳到SDRAM继续执行
@ 2015.11.8 by Huangtao
@*************************************************************************       
@ 总结的相关ARM汇编指令用法:
@ 1.mov只能在寄存器之间移动数据,或者把立即数移动到寄存器
@ 2.数据从内存到CPU之间的移动只能通过L/S指令来完成,也就是ldr/str指令
@   LDR是内存数据放到寄存器,即装载,是读 
@   STR是寄存器数据到内存,即存储,是写 
@ 3.B指令是最简单的跳转指令
@ 4.BL是另一个跳转指令,但跳转之前,会在寄存器R14中保存PC的当前内容
@ 5.bne 1b 是向后跳转到局部标签1处执行,bne 1f 向前跳到局部标签1处执行,相等则 beq

@宏定义
.equ        MEM_CTL_BASE,       0x48000000  @ 存储控制器起始地址
.equ        SDRAM_BASE,         0x30000000  @ BANK6 SDRAM起始地址

.text
.global _start
_start:
    bl  disable_watch_dog               @ 关闭WATCHDOG,否则CPU会不断重启
    bl  memsetup                        @ 设置存储控制器
    bl  copy_steppingstone_to_sdram     @ 复制代码到SDRAM中
    ldr pc, =on_sdram                   @ 跳到SDRAM中继续执行
on_sdram:
    ldr sp, =0x34000000                 @ 设置堆栈
    bl  main
halt_loop:
    b   halt_loop

disable_watch_dog:
    @ 往WATCHDOG寄存器写0

    mov r0,     #0x53000000
    mov r1,     #0x0
    str r1,     [r0]
    mov pc,     lr      @ 返回

memsetup:
    @ 设置存储控制器以便使用SDRAM等外设

    mov r1,     #MEM_CTL_BASE       @ 存储控制器的13个寄存器的开始地址
    adrl    r2, mem_cfg_val         @ 这13个起始地址载入寄存器
    add r3,     r1, #52             @ 13*4 = 52
1:                                  @局部标签1 
    ldr r4,     [r2], #4            @ 读取设置值,并让r2加4
    str r4,     [r1], #4            @ 将此值写入寄存器,并让r1加4
    cmp r1,     r3                  @ 判断是否设置完所有13个寄存器
    bne 1b                          @ 若没有写成,继续
    mov pc,     lr                  @ 返回

copy_steppingstone_to_sdram:
    @ 将Steppingstone的4K数据全部复制到SDRAM中去
    @ Steppingstone起始地址为0x00000000,SDRAM中起始地址为0x30000000
    
    mov r1, #0
    ldr r2, =SDRAM_BASE
    mov r3, #4*1024
1:  
    ldr r4, [r1],#4     @ 从Steppingstone读取4字节的数据,并让源地址加4
    str r4, [r2],#4     @ 将此4字节的数据复制到SDRAM中,并让目地地址加4
    cmp r1, r3          @ 判断是否完成:源地址==Steppingstone的未地址
    bne 1b              @ 若没有复制完,继续
    mov pc,     lr      @ 返回

.align 4                @ 按4的倍数对齐
mem_cfg_val:
    @ 存储控制器13个寄存器的设置值
    @ 根据s3c2440手册及开发板引脚进行设置相应值
    
    .long   0x22011110      @ BWSCON
    .long   0x00000700      @ BANKCON0
    .long   0x00000700      @ BANKCON1
    .long   0x00000700      @ BANKCON2
    .long   0x00000700      @ BANKCON3  
    .long   0x00000700      @ BANKCON4
    .long   0x00000700      @ BANKCON5
    .long   0x00018005      @ BANKCON6
    .long   0x00018005      @ BANKCON7
    .long   0x008C07A3      @ REFRESH
    .long   0x000000B1      @ BANKSIZE
    .long   0x00000030      @ MRSRB6
    .long   0x00000030      @ MRSRB7
//******************************************
//Mini2440 LED_GPIO
//2015.11.8 by Huangtao
//******************************************
#define GPBCON (*(volatile unsigned long *)0x56000010)
#define GPBDAT (*(volatile unsigned long *)0x56000014)

#define GPB5_out (1<<(5*2))
#define GPB6_out (1<<(6*2))
#define GPB7_out (1<<(7*2))
#define GPB8_out (1<<(8*2))

void  wait(unsigned long dly)
{
    for(; dly > 0; dly--);
}

int main(void)
{
    unsigned long i = 0;
    GPBCON = GPB5_out|GPB6_out|GPB7_out|GPB8_out; // 将LED1-4对应的GPB5/6/7/8四个引脚设为输出
    
    while(1)
    {
        wait(30000);
        GPBDAT = (~(i<<5)); // 根据i的值,点亮LED1-4,实现流水灯
        if(++i == 16)
            i = 0;
    }

    return 0;
}
sdram.bin : head.S  leds.c
    arm-linux-gcc  -c -o head.o head.S
    arm-linux-gcc -c -o leds.o leds.c
    arm-linux-ld -Ttext 0x30000000 head.o leds.o -o sdram_elf
    arm-linux-objcopy -O binary -S sdram_elf sdram.bin
    arm-linux-objdump -D -m arm  sdram_elf > sdram.dis
clean:
    rm -f   sdram.dis sdram.bin sdram_elf *.o

 

posted @ 2015-11-08 10:59  ht-beyond  阅读(278)  评论(0编辑  收藏  举报