• 2012.02.03(S3C6410中文手册笔记)(一)


    主存:0x0000 0000 ~ 0x6FFF FFFF:引导镜像区、内部存储区、静态存储区、动态存储区

    引导镜像区:0x0000 0000 ~ 0x07FF FFFF,无实际的映像内存

    内存存储区:用于启动代码访问内部ROM和内部RAM:ROM 0x0800 000 ~ 0x0BFF FFFF实际仅32KB,只读,内部RAM:0x0C00 0000~0x0FFFFFFF,实际存储仅4KB,可读可写;当NAND启动被选择时能映射到引导镜像区

    静态存储区的地址范围是0x1000_0000~0x3FFF_FFFF。通过该地址区域能访问SROM、SRAM、 NOR Flash、
    同步NOR接口设备、和Steppingstone。

    动态存储区的地址范围是0x4000_0000~0x6FFF_FFFF。DMC0有权使用地址0x4000_0000~
    0x4FFF_FFFF,并且DMC1有权使用地址0x5000_0000~0x6FFF_FFFF。对于每一块芯片选择的起始地址是可
    以进行配置的

    外设区域通过PERI 总线被访问,它的地址范围是0x7000_0000~0x7FFF_FFFF。这个地址范围的所有
    的SFR 能被访问。而且如果数据需要从NFCON 或CFCON 传输,这些数据需要通过PERI 总线传输

    0x7F00_4000 ~ 0x7F00_4FFF   IIC地址

    //S3C6410的IIC端口设置:

    static volatile S3C6410_GPIO_REG     *g_pGPIOReg     = NULL;

    /////////
    // Function Name : InitializeGPIOPort
    // Function Description : Initializing GPIO port for IIC.
    // Input :
    // Output :
    // Version : v0.9
    void     InitializeGPIOPort(void)
    {
        // set SCL
        g_pGPIOReg->GPBCON = (g_pGPIOReg->GPBCON & ~(0xf<<20)) | (0x2<<20);

        // set SDA
        g_pGPIOReg->GPBCON = (g_pGPIOReg->GPBCON & ~(0xf<<24)) | (0x2<<24);

        // set SCL pull-up
        g_pGPIOReg->GPBPUD = (g_pGPIOReg->GPBPUD & ~(0x3<<10)) | (0x0<<10);

        // set SDA pull-up
        g_pGPIOReg->GPBPUD = (g_pGPIOReg->GPBPUD & ~(0x3<<12)) | (0x0<<12);
    }

    通过设置SFR寄存器支持选择外部存储器选型:

    //////////
    // Function Name : MapVirtualAddress
    // Function Description : Mapping Virtual address of Registers.
    // Input :
    // Output :The return is a BOOL, representing success (TRUE) or failure (FALSE).
    // Version : v0.1
    BOOL         MapVirtualAddress(void)
    {
        BOOL            RetVal           = TRUE;        // Initialize to success
        PHYSICAL_ADDRESS    ioPhysicalBase = {0,0};

        DEBUGMSG (ZONE_FUNCTION,
                  (TEXT("++%s\r\n"), __FUNCTION__));

        // GPIO SFR
        ioPhysicalBase.LowPart = S3C6410_BASE_REG_PA_GPIO;
        g_pGPIOReg = (S3C6410_GPIO_REG *)MmMapIoSpace(ioPhysicalBase, sizeof(S3C6410_GPIO_REG), FALSE);
        if (g_pGPIOReg == NULL)
        {
            DEBUGMSG(ZONE_ERROR, (_T("%s : g_pGPIOReg MmMapIoSpace() Failed \n\r"), __FUNCTION__));
            return FALSE;
        }

        // SYSCON SFR
        ioPhysicalBase.LowPart = S3C6410_BASE_REG_PA_SYSCON;   
        g_pSYSCONReg = (S3C6410_SYSCON_REG *)MmMapIoSpace(ioPhysicalBase, sizeof(S3C6410_SYSCON_REG), FALSE);
        if (g_pSYSCONReg == NULL)
        {
            DEBUGMSG(ZONE_ERROR, (_T("%s : g_pSYSCONReg MmMapIoSpace() Failed \n\r"), __FUNCTION__));
            return FALSE;
        }

        // IIC SFR
        ioPhysicalBase.LowPart = S3C6410_BASE_REG_PA_IICBUS;   
        g_pIICReg = (S3C6410_IIC_REG *)MmMapIoSpace(ioPhysicalBase, sizeof(S3C6410_IIC_REG), FALSE);
        if (g_pIICReg == NULL)
        {
            DEBUGMSG(ZONE_ERROR, (_T("%s : g_pIICReg MmMapIoSpace() Failed \n\r"), __FUNCTION__));
            return FALSE;
        }

        DEBUGMSG (ZONE_FUNCTION,
                  (TEXT("--%s\r\n"),__FUNCTION__));
        return (RetVal);
    }

    //////////
    // Function Name : HW_Init
    // Function Description : IIC device H/W initialization.
    // Input :     PHW_INIT_INFO    pInitContext
    // Output :The return is a BOOL, representing success (TRUE) or failure (FALSE).
    // Version : v0.1
    BOOL         HW_Init (PHW_INIT_INFO pInitContext)
    {
        BOOL    RetVal           = TRUE;        // Initialize to success
        UINT32     Irq;

        DEBUGMSG (ZONE_FUNCTION,
                  (TEXT("+HW_Init(0x%X)\r\n"),
                   pInitContext));

        if(!MapVirtualAddress())
        {
            RetVal = FALSE;
            goto CleanUp;
        }

        InitializeGPIOPort();

        /* Create tx and rx events. Check return.
         */
        g_hTransferEvent = CreateEvent(0,FALSE,FALSE,NULL);
        if ( !g_hTransferEvent ) {
            DEBUGMSG(ZONE_ERROR,
                     (TEXT("Error creating event, HW_Init failed\n\r")));
            RetVal = FALSE;
            goto CleanUp;
        }

        g_hTransferDone = CreateEvent(0,FALSE,FALSE,NULL);
        if ( !g_hTransferDone ) {
            DEBUGMSG(ZONE_ERROR,
                     (TEXT("Error creating done event, HW_Init failed\n\r")));
            RetVal = FALSE;
            goto CleanUp;
        }

     /*
          OAL的全称是OEM Adaption Layer,即原始设备制造商适配层。从逻辑结构上看,它位于操作系统的内核与硬件之间,
          是连接系统与硬件的枢纽;从功能上看,OAL颇似桌面机上的BIOS,具有初始化设备、引导操作系统以及抽象硬件功能等作用。
          与B10S不同的是,0AL隶属于操作系统,是操作系统的一部分。从存在方式上,讲OAL是一组函数的集合体,这些函数体现出0AL的功能
      */


        // Obtain sysintr values from the OAL for the IIC interrupt.
        //
        Irq = IRQ_I2C;
        if (!KernelIoControl(IOCTL_HAL_REQUEST_SYSINTR, &Irq, sizeof(UINT32), &g_IntrIIC, sizeof(UINT32), NULL))
        {
            DEBUGMSG(ZONE_ERROR, (TEXT("ERROR: Failed to request the IIC sysintr.\r\n")));
            g_IntrIIC = SYSINTR_UNDEFINED;
            RetVal = FALSE;
            goto CleanUp;
        }

        DEBUGMSG(ZONE_INFO, (TEXT("IIC IRQ mapping: [IRQ:%d->sysIRQ:%d].\r\n"), Irq, g_IntrIIC));

        // initialize the interrupt
        if( !InterruptInitialize(g_IntrIIC, g_hTransferEvent, NULL, 0) )
        {
            DEBUGMSG(ZONE_ERROR,(TEXT("HW_Init ERROR: Unable to initialize interrupt: %u\r\n"), GetLastError()));
            RetVal = FALSE;
            goto CleanUp;
        }


        // create the IST
        if ( (g_hTransferThread = CreateThread(NULL, 0, IIC_IST, (LPVOID)pInitContext, 0, NULL)) == NULL)
        {
            DEBUGMSG(ZONE_ERROR,(TEXT("HW_Init ERROR: Unable to create IST: %u\r\n"), GetLastError()));
            RetVal = FALSE;
            goto CleanUp;
        }

        if ( !CeSetThreadPriority(g_hTransferThread, pInitContext->Priority256)) {

            DEBUGMSG(ZONE_ERROR,(TEXT("HW_Init ERROR: CeSetThreadPriority ERROR:%d\n"), GetLastError()));
            RetVal = FALSE;
            goto CleanUp;
        }

    CleanUp:
        DEBUGMSG (ZONE_FUNCTION|(RetVal == FALSE?ZONE_ERROR:0),
                  (TEXT("-HW_Init %s Ecode=%d\r\n"),
                   (RetVal == TRUE) ? TEXT("Success") : TEXT("Error"),
                   GetLastError()));
        return (RetVal);
    }

    1.1  S3C6410体系结构

    S3C6410 RISC处理器特性包括:

    1、基于CPU的子系统的ARM1176JZF-S,核心时钟频率最高是667MHz;3个片上操作时钟:APLL、MPLL、EPLL

    2、专用的IRDA端口:用于FIR,MIF和SIR

    3、RTC实时时钟:32.768KHz频率,ms、s、m、h、week、mouth、year;报警中断,时间节拍中断

    4、16位看门狗定时器

    时钟超时,则中断请求或系统复位

    5、四个DMA通用嵌入式;每个DMA有两个主端口

    支持存储器与外设之间的相互通讯;脉冲数据传输,目的:提供传输效率

    1.3 S3C6410引脚信号描述

    ADDR[15:0] 存储器端口0共同地址总线

    DATA[15:0] 存储器端口0共同数据总线

    nCS[7:6]    存储器端口0DRAM片选支持高达两个存储页

    ALE :NAND FLASH地址锁存有效

    CLE: NAND FLASH命令锁存有效

    RnB: I 存储器端口0 NAND Flash准备/忙

    WAITn:存储器端口OSROM等待

    NAND Flash和CF/ATAPI不能通过静态存储区访问,因此,任何Xm0CSn[5:2]映射到NFCON或CFCON,

     DDR-SDRAM:

    CK,/CK  input 

    FPGA接收数字信号-->存储在DDR SDRAM;

    通过FPGA读取DDR中的数据,处理后再送回DDR SDRAM,最后由FPGA负责将数据分两路输出

    DDR-SDRAM工作方式:

    在DDR-SDRAM能够被存储数据之前,需先对其初始化。

    设置DDRSDRAM的普通模式寄存器和扩展模式寄存器,用来制定DDR SDRAM的工作方式:

    这些设置包括:突发长度、突发类型、CAS潜伏期和工作模式、扩展模式寄存器中的对DDR SDRAM内部DLL的使能与输出驱动能力设置。

    .macro setup_sdram_ddr

         ldr r0,SOC_ESDCTL_BASE_W;

        mov r2,#SOC_CSD0_BASE //0xA000_0000

        mov r1,#0x8  //initial reset

    S3C6410 DRAM Controller (转),编辑了一下  

    2010-08-22 08:47:58|  分类: CPU(ARM/MIPS/X86 |  标签: |字号 订阅

     
     

    项目中更换了DRAM,所以需要重新配置S3C6410的DRAM控制器,结果发现S3C6410中的DRAM控制器还是挺复杂的。

    S3C6410支持两个DRAM片选,可以分别接最大256MB的内存,该处理器用的DRAM控制器是来自ARM的PrimeCell Dynamic Memory Controller(PL340)。只看S3C6410的Datasheet中的DRAM部分介绍是不够的,你还需要看PL340的技术参考文档。想完全了解6410的DRAM控制器,必须两篇文档都看。

    我用的是mobile DDR-SDRAM,所以在这里大概介绍一下寄存器及配置流程。先介绍一下寄存器:

    1. DRAM Controller Status Register (Address: 0x7E001000) DRAM状态寄存器,这是一个RO寄存器,用于读取DRAM的状态。 Name Bit Description Memory chips [8:7] 01=2 chips Memory type [6:4] 100=MSDR, SDR, MDDR and DDR Memory width [3:2] 00=16-bit 01=32-bit Controller Status [1:0] 00=config 01=ready 10=paused 11=low-power 实际上,读到的有用信息就是Controller Status和Memory width。

    2. DRAM Controller Command Register (Address: 0x7E001004) DRAM命令寄存器,设置DRAM的工作状态。 Name Bit Description Memc_cmd [2:0] 000=Go 001=Sleep 010=Wakeup 011=Pause 100=Configure 最开始应该配置为0x4,是处于Configure状态。在配置完所有的DRAM之后,将该寄存器设置为0x0,处于运行状态。

    3. Direct Command Register (Address: 0x7E001008) DRAM命令寄存器,用于发送命令到DRAM和访问DRAM中的MRS和EMRS寄存器。 Name Bit Description Extended memory command [22] 扩展命令,该bit用于连接下面的Memory command[19:18],从而组成DRAM命令 Chip number [21:20] 00=chip_0 01=chip_1 10=chip_2 11=chip_3 Memory command [19:18] 和Extended Memory command组成DRAM命令字 000=PrechargeAll 001=Autorefresh 010=MRS/EMRS访问 011=NOP 100=Deep Power Down Bank address [17:16] 访问MRS和EMRS的时候,映射为Bank地址位 Address_13_to_0 [13:0] 访问MRS和EMRS的时候,映射为memory address[13:0] 通过该寄存器初始化DRAM,先设置为NOP模式,然后设置为PrechargeAll进行充电,然后设置EMRS和MRS寄存器,一般是这么一个流程。具体的要参见你所使用的DRAM的datasheet。

    4. Memory Configuration Register (Address: 0x7E00100C) DRAM的配置寄存器,这个与需要参照你所使用的DRAM的datasheet。 Name Bit Description Memory burst [17:15] 设置Burst大小 000=Burst 1 001=Burst 2 010=Burst4 011=Burst 8 100=Burst 16 Stop_mem_clock 没有访问时,Memory Clock自动停止 Power_down_prd [21:20] 自动掉电所需的时钟周期 AP bit [19:18] 0=Address bit 10 1=Address bit 8 Row bits [17:16] 行地址 000=11 bits 001=12 bits 010=13bits 011=14 bits 100=15bits 101=16bits Column bits [13:0] 列地址 000=8 bits 001=9 bits 010=10 bits 011=11 bits 100=12 bits 该寄存器肯定是要配的,看看DRAM的datasheet就知道了。

    5. Refresh Period Register (Address: 0x7E001010) DRAM的刷新频率寄存器,用于配置刷新频率的。 Name Bit Description Refresh period [14:0] 多少个Memory的时钟周期

    6. CAS Latency Register (Address: 0x7E001014) DRAM的CAS延时寄存器,一定要配,参考DRAM的datasheet。 Name Bit Description CAS Latency [3:1] CAS延时多少个时钟周期 CAS half cycle [0] 0=0周期偏移 1=半周期偏移 对于MDDR和SDR只能设置为0

    7. t_dqss/t_mrd/t-ras/t_rc/t_rcd/t_rfc/t_rp/t_rrd/t_wr/t_wtr/t_xp/t_xsr/t_esr Registers (Address: 0x7E001018---0x7E001048) DRAM操作中所需时间和延时寄存器,这里不作过多介绍,具体可以参考PL340文档。

    8. Memory Configuration 2 Register (Address: 0x7E00104C) DRAM的配置寄存器2。 Name Bit Description Read delay [12:11] 读延时 00=0 cycle 01=1 cycle 10,11=2 cycle Memory type [10:8] DRAM类型 000=SDR 001=DDR 011=Mobile DDR Memory width [7:6] 00=16 bits 01=32 bits cke_init [3] 复位后,设置CKE输出的值 dqm_init [2] 复位后,设置DQM输出的值 a_gt_m_sync [1] ACLK频率高于MCLK时,设置为1 Sync [0] ACLK和MCLK同步时,设置为1

    9. CHIP_N_CFG Register (Address: 0x7E001200/0x7E001204) DRAM的Chip配置寄存器,用于片选decoding设置 Name Bit Description BRC_RBC [16] DRAM结构 0=Row-Bank-Column 1=Bank-Row-Column Address match [15:8] 片选地址比较值 Address mask [7:0] 片选地址掩码 上面介绍了一些寄存器,还有一些寄存器由于没有用到,所以没有去了解。

    下面给一个DRAM初始化的例子:

    WriteReg: 0x7e001004 0x4 //设置DRAM控制器状态为

    Configure WriteReg: 0x7e001010 0x40d //设置DRAM的刷新周期

    WriteReg: 0x7e001014 0x6 //设置CAS延时

    WriteReg: 0x7e001018 0x3 //设置t_DQSS

    WriteReg: 0x7e00101c 0xf //设置t_MRD

    WriteReg: 0x7e001020 0xf //设置t_RAS

    WriteReg: 0x7e001024 0xf //设置t_RC

    WriteReg: 0x7e001028 0x1f //设置t_RCD

    WriteReg: 0x7e00102c 0x21f //设置t_RFC

    WriteReg: 0x7e001030 0xf //设置t_RP

    WriteReg: 0x7e001034 0xf //设置t_RRD

    WriteReg: 0x7e001038 0x7 //设置t_WR

    WriteReg: 0x7e00103c 0x7 //设置t_WTR

    WriteReg: 0x7e001040 0xf //设置t_XP

    WriteReg: 0x7e001044 0x1f //设置t_XSR

    WriteReg: 0x7e001048 0x1f //设置t_ESR

    WriteReg: 0x7e00100c 0x10012 //设置DRAM的Column, Row等属性

    WriteReg: 0x7e00104c 0x0b45 //设置DRAM的buswidth,type等属性

    WriteReg: 0x7e001200 0x150f8 //设置RBC以及片选属性

    WriteReg: 0x7e001304 0x0 //设置DQS延时

    WriteReg: 0x7e001008 0xc0000 //发送NOP命令到DRAM

    WriteReg: 0x7e001008 0x0 //发送Precharge命令到DRAM

    WriteReg: 0x7e001008 0x40000 //发送Autorefresh命令到DRAM

    WriteReg: 0x7e001008 0x40000 //发送Autorefresh命令到DRAM

    WriteReg: 0x7e001008 0xa0000 //设置DRAM的EMRS寄存器

    WriteReg: 0x7e001008 0x80032 //设置DRAM的MRS寄存器

    WriteReg: 0x7e001004 0x0 //设置DRAM控制器开始运行

    关于DRAM控制器的配置要参见所使用的DRAM的Datasheet,了解DRAM的结构和初始化过程,才能正确配置。S3C6410的DRAM控制器比较复杂,有些寄存器也不是很理解,在ARM的PL340的文档中也没做太多解释。 我的建议就是能不换DRAM最好,换了也要尽量和S3C6410板上的DRAM相近。

  • 相关阅读:
    How to make MySQL handle UTF-8 properly
    如何禁用Firefox,chrome浏览器“不安全密码警告”
    How to start a VirtualBox VM headless in Windows 10
    Centos7安装activeMQ
    centos7 redis配置
    VirtualBox配置
    Oracle中序列(Sequence)详解
    oracle函数的创建及调用
    jdbcTemplate insert 封装
    macbook eclipse 快捷键
  • 原文地址:https://www.cnblogs.com/itxiaocaiyidie/p/2337256.html
Copyright © 2020-2023  润新知