bafeite 发表于 2013-8-4 11:17:44

请专家们帮我解答一下SDRAM的初始化,可回复联系方式,解决有酬谢!

本帖最后由 bafeite 于 2013-8-4 11:24 编辑

坛内大侠请帮忙:
1、背景描述:自己写的简单的BootLoader,当前工作为初始化SDRAM,将代码搬移到SDRAM,看了下板子上

SDRAM的芯片上的字是:H57V2562GTR-60C

2、现象:当执行程序,先写入一个,再回读一下,不一样,怀疑SDRAM没初始化好,但是程序好像能跑,

串口还能打印

3、疑问:
   a.H57V2562GTR-60C,我看芯片手册是256M(4BANKS*4M*16),但是看坛子里的朋友说是32M的
   b.一般通过什么情况能验证我的SDRAM是否初始化成功
   c.我以下代码比较奇怪若不拷贝到SRAM运行一切OK,但是拷贝到SRAM运行,程序虽然能跑,但是初始

打印均不对;

QQ:68075211

bafeite 发表于 2013-8-4 11:18:18

代码:
srat.s:
.text
.global _start
_start:

/*设置堆栈*/
    /*栈是往下增长的,这里片内RAM总共4K,我们就设置到最后,前面应该用不完*/
    ldr sp,=1024*4

/*调用函数*/
    bl Init
    bl memsetup
    blcopy_steppingstone_to_sdram
    ldr pc, =on_sdram
on_sdram:
    ldr sp, =0x34000000
    blmain

copy_steppingstone_to_sdram:
    /*将Steppingstone的4K数据全部复制到SDRAM中去*/
    /*Steppingstone起始地址为0x00000000,SDRAM中起始地址为0x30000000*/

    mov r1, #0
    ldr r2, =0x30000000
    mov r3, #4*1024
1:
    ldr r4, ,#4   /*从Steppingstone读取4字节的数据,并让源地址加4*/
    str r4, ,#4   /*将此4字节的数据复制到SDRAM中,并让目地地址加4*/
    cmp r1, r3          /*判断是否完成:源地址等于Steppingstone的未地址*/
    bne 1b            /*若没有复制完,继续*/
    mov pc,   lr      /*返回*/

bafeite 发表于 2013-8-4 11:19:31

Board.h

#define CPU_REG32(addr)      (*(volatile unsigned long *)(addr))/*volatile 表示告诉编译器不

要对此进行优化*/




#define U32 unsigned long
#define U8unsigned char



#define DOGCON      CPU_REG32(0x53000000)

/*GPIO registers*/
#define GPBCON            CPU_REG32(0x56000010)
#define GPBDAT            CPU_REG32(0x56000014)

#define GPFCON            CPU_REG32(0x56000050)
#define GPFDAT            CPU_REG32(0x56000054)
#define GPFUP               CPU_REG32(0x56000058)

#define GPGCON            CPU_REG32(0x56000060)
#define GPGDAT            CPU_REG32(0x56000064)
#define GPGUP               CPU_REG32(0x56000068)

#define GPHCON            CPU_REG32(0x56000070)
#define GPHDAT            CPU_REG32(0x56000074)
#define GPHUP               CPU_REG32(0x56000078)



/*UART registers*/
#define ULCON0            CPU_REG32(0x50000000)
#define UCON0               CPU_REG32(0x50000004)
#define UFCON0            CPU_REG32(0x50000008)
#define UMCON0            CPU_REG32(0x5000000c)
#define UTRSTAT0            CPU_REG32(0x50000010)
#define UTXH0               CPU_REG32(0x50000020)
#define URXH0               CPU_REG32(0x50000024)
#define UBRDIV0             CPU_REG32(0x50000028)

/*clock registers*/
#define        LOCKTIME                (*(volatile unsigned long *)0x4c000000)
#define        MPLLCON                (*(volatile unsigned long *)0x4c000004)
#define        UPLLCON                (*(volatile unsigned long *)0x4c000008)
#define        CLKCON                (*(volatile unsigned long *)0x4c00000c)
#define        CLKSLOW                (*(volatile unsigned long *)0x4c000010)
#define        CLKDIVN                (*(volatile unsigned long *)0x4c000014)





#define PCLK            50000000    // init.c中的clock_init函数设置PCLK为50MHz
#define UART_CLK      PCLK      //UART0的时钟源设为PCLK
#define UART_BAUD_RATE115200      // 波特率
#define UART_BRD      ((UART_CLK/ (UART_BAUD_RATE * 16)) - 1)

#define TXD0READY   (1<<2)
#define RXD0READY   (1)


Board.c
#include "Board.h"




void Delay()
{
    U32 i;

    for(i=0; i<100000; i++)
    {
    }
}
void CloseWatchDog()
{
    DOGCON = 0x00000000;
}

#define S3C2440_MPLL_200MHZ   ((0x5c<<12)|(0x01<<4)|(0x02))
void SetClock()
{
    CLKDIVN = 0x00000003;

    /* 如果HDIVN非0,CPU的总线模式应该从“fast bus mode”变为“asynchronous bus mode” */
    __asm__(
      "mrc    p15, 0, r1, c1, c0, 0\n"      /* 读出控制寄存器 */
      "orr    r1, r1, #0xc0000000\n"          /* 设置为“asynchronous bus mode” */
      "mcr    p15, 0, r1, c1, c0, 0\n"      /* 写入控制寄存器 */
    );

    MPLLCON = S3C2440_MPLL_200MHZ;/* 现在,FCLK=200MHz,HCLK=100MHz,PCLK=50MHz */
}

void uart0_init(void)
{
    GPHCON|= 0xa0;    // GPH2,GPH3用作TXD0,RXD0
    GPHUP   = 0x0c;   // GPH2,GPH3内部上拉

    ULCON0= 0x03;   // 8N1(8个数据位,无较验,1个停止位)
    UCON0   = 0x05;   // 查询方式,UART时钟源为PCLK
    UFCON0= 0x00;   // 不使用FIFO
    UMCON0= 0x00;   // 不使用流控
    UBRDIV0 = UART_BRD; // 波特率为115200
}

void putc(unsigned char c)
{
    /* 等待,直到发送缓冲区中的数据已经全部发送出去 */
    while (!(UTRSTAT0 & TXD0READY));

    /* 向UTXH0寄存器中写入数据,UART即自动将它发送出去 */
    UTXH0 = c;
}

U32 getc(U8* out)
{
    if((UTRSTAT0 & RXD0READY))
    {
      *out = URXH0;
      return 0;
    }
    else
    {
      return 1;
    }
}
void MyPrintf(U8 *buff) //一个简单的类似于printf的实现,//参数必须都是int 类型
{
    while (*buff != 0)
    {
      putc (*buff);

      buff++;
    }
}

void memsetup(void)
{
    U32 TEMP = 0;

    CPU_REG32(0X48000000) = 0x2201d550;   //BWSCON;
    CPU_REG32(0X48000004) = 0x00000700;   //BANKCON0;
    CPU_REG32(0X48000008) = 0x00000700;   //BANKCON1;
    CPU_REG32(0X4800000C) = 0x00000700;   //BANKCON2;
    CPU_REG32(0X48000010) = 0x00001f4c;   //BANKCON3;
    CPU_REG32(0X48000014) = 0x00000700;   //BANKCON4;
    CPU_REG32(0X48000018) = 0x00000700;   //BANKCON5;
    CPU_REG32(0X4800001C) = 0x00018005;   //BANKCON6;
    CPU_REG32(0X48000020) = 0x00018005;   //BANKCON7;
    CPU_REG32(0X48000024) = 0x008e04f4;   //REFRESH;
    CPU_REG32(0X48000028) = 0x00000032;   //BANKSIZE;
    CPU_REG32(0X4800002C) = 0x00000030;   //MRSRB6;
    CPU_REG32(0X48000030) = 0x00000030;   //MRSRB7;



    /*CPU_REG32(0X48000000) = 0x22011110;
    CPU_REG32(0X48000004) = 0x00000700;
    CPU_REG32(0X48000008) = 0x00000700;
    CPU_REG32(0X4800000C) = 0x00000700;
    CPU_REG32(0X48000010) = 0x00000700;
    CPU_REG32(0X48000014) = 0x00000700;
    CPU_REG32(0X48000018) = 0x00000700;
    CPU_REG32(0X4800001C) = 0x00018005;
    CPU_REG32(0X48000020) = 0x00018005;
    CPU_REG32(0X48000024) = 0x008C07A3;
    CPU_REG32(0X48000028) = 0x000000B1;
    CPU_REG32(0X4800002C) = 0x00000030;
    CPU_REG32(0X48000030) = 0x00000030;*/


    CPU_REG32(0X30000000) = 0x12345678;
    CPU_REG32(0X33ffffff) = 0x87654321;

    if(CPU_REG32(0X30000000) == 0x12345678 && CPU_REG32(0X33ffffff) == 0x87654321)
    {
      MyPrintf("Init Sdram,size is 64M!\r\n");
    }
    else
    {
      MyPrintf("Init Sdram fail!\r\n");
    }


    TEMP = CPU_REG32(0X30000000);
    putc((U8)((TEMP>>28)&0x0000000f+0x30));
    putc((U8)((TEMP>>24)&0x0000000f+0x30));
    putc((U8)((TEMP>>20)&0x0000000f+0x30));
    putc((U8)((TEMP>>16)&0x0000000f+0x30));
    putc((U8)((TEMP>>12)&0x0000000f+0x30));
    putc((U8)((TEMP>>8)&0x0000000f+0x30));
    putc((U8)((TEMP>>4)&0x0000000f+0x30));
    putc((U8)((TEMP&0x0000000f+0x30)));
    MyPrintf("\r\n");











}
void do_cmd(U8* buff)
{
    U32 i = 0;
    U32 TEMP = 0;

    if(buff == 'v' &&buff == 'e'&&buff == 'r'&&buff == 's'&&buff ==

'i'&&buff == 'o'&&buff == 'n')
    {
      MyPrintf("version is 20130803003! \r\n");
      MyPrintf("TQ2440#");
    }
    else if(*buff == '1')
    {

      MyPrintf("cmd is 1! \r\n");
      MyPrintf("TQ2440#");
    }
    else if(*buff == '2')
    {
      MyPrintf("cmd is 2! \r\n");
      MyPrintf("TQ2440#");

      CPU_REG32(0X30000000+*buff) = 0X12345678;
      TEMP = CPU_REG32(0X30000000+*buff);
      putc((U8)((TEMP>>28)&0x0000000f+0x30));
      putc((U8)((TEMP>>24)&0x0000000f+0x30));
      putc((U8)((TEMP>>20)&0x0000000f+0x30));
      putc((U8)((TEMP>>16)&0x0000000f+0x30));
      putc((U8)((TEMP>>12)&0x0000000f+0x30));
      putc((U8)((TEMP>>8)&0x0000000f+0x30));
      putc((U8)((TEMP>>4)&0x0000000f+0x30));
      putc((U8)((TEMP&0x0000000f+0x30)));
      MyPrintf("\r\n");


    }
    else
    {
      MyPrintf("\r\n");
      MyPrintf("TQ2440#");
    }





    /*clear*/
    for(i=0; i<100; i++)
    {
      buff = 0;
    }
}


void consonle()
{
    U8 buff;
    U8 ucTemp = 0;
    static U32 CNT = 0;

    if(getc(&ucTemp) == 0)
    {
      if(ucTemp != 0x0d)
      {
            buff = ucTemp;
            if(CNT < 99)
            {
                CNT++;
            }
            else
            {
                CNT = 0;
            }
      }
      else
      {
            CNT = 0;
            do_cmd(buff);
      }


    }

}
void main()
{
    int i;
    U8 TEMP;;
    U32 tmpu32 = 0;
    U8 BUFF;

    for(i = 0; i<10; i++)
    {
      /*灯*/
      GPBCON = 0x00000400;    // 设置GPB5为输出口, 位=0b01
      GPBDAT = 0x00000000;    // GPB5输出0,LED1点亮    return 0;

      Delay();


      GPBCON = 0x00001400;    // 设置GPB5为输出口, 位=0b01
      GPBDAT = 0x00000000;    // GPB5输出0,LED1点亮    return 0;

      Delay();
    }

    MyPrintf("Run My App \r\n");
    MyPrintf("TQ2440#");

    for(;;)
    {
      //consonle();

      if(getc(&TEMP) == 0)
      {
            if(TEMP != 0x0d)
            {
               BUFF = TEMP;
            }
            else
            {
                if(BUFF == '1')
                {
                  MyPrintf("version is 20130804003! \r\n");
                  MyPrintf("TQ2440#");
                }
                else if(BUFF == '2')
                {
                  MyPrintf("cmd is 2! \r\n");
                  MyPrintf("TQ2440#");
                  CPU_REG32(0X30000000+BUFF-0x30) = 0X12345678;
                  tmpu32 = CPU_REG32(0X30000000+BUFF-0x30);
                  putc((U8)((tmpu32>>28)&0x0000000f+0x30));
                  putc((U8)((tmpu32>>24)&0x0000000f+0x30));
                  putc((U8)((tmpu32>>20)&0x0000000f+0x30));
                  putc((U8)((tmpu32>>16)&0x0000000f+0x30));
                  putc((U8)((tmpu32>>12)&0x0000000f+0x30));
                  putc((U8)((tmpu32>>8)&0x0000000f+0x30));
                  putc((U8)((tmpu32>>4)&0x0000000f+0x30));
                  putc((U8)((tmpu32&0x0000000f+0x30)));
                  MyPrintf("\r\n");
                }
                else
                {
                  MyPrintf("\r\n");
                  MyPrintf("TQ2440#");
                }
            }
      }
    }
}
void Init()
{
    /*狗*/
    CloseWatchDog();
    /*时钟*/
    SetClock();
    /*串口*/
    uart0_init();
    MyPrintf("Init Clock,FCLK=200MHz,HCLK=100MHz,PCLK=50MHz!\r\n");
    MyPrintf("Init Uart,Baudrate is 115200!\r\n");
    //memsetup();

}

bafeite 发表于 2013-8-4 11:19:49

makefile:
objs := start.o Board.o

BootLoader.bin : $(objs)
        arm-linux-ld -TBootLoader.lds        -o BootLoader_elf $^
        arm-linux-objcopy -O binary -S BootLoader_elf $@
        arm-linux-objdump -D -m armBootLoader_elf > BootLoader.dis

start.o : start.S                        
        arm-linux-gcc -c -o start.o start.S   
                                                 
Board.o : Board.c                        
        arm-linux-gcc -c -o Board.o Board.c   

clean:
        rm -fnand.dis nand.bin nand_elf *.o         

BootLoader.lds
SECTIONS {
firtst    0x30000000 : {start.o Board.o}
}

亚瑟王 发表于 2013-8-5 10:44:08

检查内存初始化吧。
256Mbit=32MByte。
推荐使用uboot,省时间。可以把精力放到真正的开发中。
页: [1]
查看完整版本: 请专家们帮我解答一下SDRAM的初始化,可回复联系方式,解决有酬谢!