天嵌 ARM开发社区

 找回密码
 注册
查看: 3359|回复: 4

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

[复制链接]
bafeite 发表于 2013-8-4 11:17:44 | 显示全部楼层 |阅读模式
本帖最后由 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
    bl  copy_steppingstone_to_sdram
    ldr pc, =on_sdram
on_sdram:
    ldr sp, =0x34000000
    bl  main

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

    mov r1, #0
    ldr r2, =0x30000000
    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      /*返回*/
 楼主| bafeite 发表于 2013-8-4 11:19:31 | 显示全部楼层
Board.h

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

要对此进行优化*/




#define U32 unsigned long
#define U8  unsigned 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_RATE  115200      // 波特率
#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[0] == 'v' &&buff[1] == 'e'&&buff[2] == 'r'&&buff[3] == 's'&&buff[4] ==

'i'&&buff[5] == 'o'&&buff[6] == '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[i] = 0;
    }
}


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

    if(getc(&ucTemp) == 0)
    {
        if(ucTemp != 0x0d)
        {
            buff[CNT] = 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为输出口, 位[11:10]=0b01
        GPBDAT = 0x00000000;    // GPB5输出0,LED1点亮    return 0;

        Delay();


        GPBCON = 0x00001400;    // 设置GPB5为输出口, 位[11:10]=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 arm  BootLoader_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 -f  nand.dis nand.bin nand_elf *.o         

BootLoader.lds
SECTIONS {
firtst    0x30000000 : {start.o Board.o}
}
亚瑟王 发表于 2013-8-5 10:44:08 | 显示全部楼层
检查内存初始化吧。
256Mbit=32MByte。
推荐使用uboot,省时间。可以把精力放到真正的开发中。
您需要登录后才可以回帖 登录 | 注册

本版积分规则

关闭

i.MX8系列ARM cortex A53 M4 工控板上一条 /1 下一条

Archiver|手机版|小黑屋|天嵌 嵌入式开发社区 ( 粤ICP备11094220号 )

GMT+8, 2024-5-29 18:56 , Processed in 1.062500 second(s), 18 queries .

Powered by Discuz! X3.4

Copyright © 2001-2020, Tencent Cloud.

快速回复 返回顶部 返回列表