TI中文支持网
TI专业的中文技术问题搜集分享网站

AM335x读写双口ram问题

参考了网上的这篇文章来编写双口ram的驱动:

http://bbs.eeworld.com.cn/thread-333652-1-1.html

我选用的是gpmc_csn1做片选,采用异步的方式读写16位双口ram(大小为4K*16),使用gpmc_oen_ren和gpmc_wen控制ram的读写,gpmc_a0~gpmc_a11做地址线,gpmc_ad0~gpmc_ad15做数据线。读写双口ram时,主要出现两个问题:

(1)读写偶数地址时,结果都是正确的,能够测得gpmc_ad0~gpmc_ad15数据线上的值是对的,gpmc_a0~gpmc_a11地址线也正确,示波器测得的三个控制信号的波形为图1,图2所示;但当写奇数地址的值时写不到ram中,数据总线上只有gpmc_ad0~gpmc_ad7上有发送数据,gpmc_ad8~gpmc_ad15上的电平全是高,示波器测得的三个控制信号的波形为图3,图4所示。

                                                         图1     读偶数地址

                                                                 图2     写偶数地址

                                                                图3     读奇数地址

                                                            图4   写奇数地址

    从控制信号波形上看,读写奇数地址时的波形与读写偶数地址时的不一样,是不是这个原因导致的读写双口ram奇数地址就不成功呢?

(2)刚开始时,就是问题一中说的那种情况,读写偶数地址结果是没问题的,但不知道什么原因,现在写双口ram写不进去了,用示波器测gpmc_cs1、gpmc_oen_ren、gpmc_wen没有变化,测不到控制信号,但读双口ram可以看到这三个控制信号的变化波形,波形和上图1中的一样。程序也不知道什么原因有时候行,有时候不行,希望前辈们能够帮我解决这两个问题,谢谢!

***********************************************************************************************************************************************************************

我使用的是飞凌的ok335xd开发板对双口ram进行访问的。下面是我的配置:

=================================== board-am335xevm.c

static struct pinmux_config dual_ram_mux[] = {
{"gpmc_ad0.gpmc_ad0", OMAP_MUX_MODE0 | AM33XX_PIN_INPUT_PULLUP},
{"gpmc_ad1.gpmc_ad1", OMAP_MUX_MODE0 | AM33XX_PIN_INPUT_PULLUP},
{"gpmc_ad2.gpmc_ad2", OMAP_MUX_MODE0 | AM33XX_PIN_INPUT_PULLUP},
{"gpmc_ad3.gpmc_ad3", OMAP_MUX_MODE0 | AM33XX_PIN_INPUT_PULLUP},
{"gpmc_ad4.gpmc_ad4", OMAP_MUX_MODE0 | AM33XX_PIN_INPUT_PULLUP},
{"gpmc_ad5.gpmc_ad5", OMAP_MUX_MODE0 | AM33XX_PIN_INPUT_PULLUP},
{"gpmc_ad6.gpmc_ad6", OMAP_MUX_MODE0 | AM33XX_PIN_INPUT_PULLUP},
{"gpmc_ad7.gpmc_ad7", OMAP_MUX_MODE0 | AM33XX_PIN_INPUT_PULLUP},
{"gpmc_ad8.gpmc_ad8", OMAP_MUX_MODE0 | AM33XX_PIN_INPUT_PULLUP},
{"gpmc_ad9.gpmc_ad9", OMAP_MUX_MODE0 | AM33XX_PIN_INPUT_PULLUP},
{"gpmc_ad10.gpmc_ad10", OMAP_MUX_MODE0 | AM33XX_PIN_INPUT_PULLUP},
{"gpmc_ad11.gpmc_ad11", OMAP_MUX_MODE0 | AM33XX_PIN_INPUT_PULLUP},
{"gpmc_ad12.gpmc_ad12", OMAP_MUX_MODE0 | AM33XX_PIN_INPUT_PULLUP},
{"gpmc_ad13.gpmc_ad13", OMAP_MUX_MODE0 | AM33XX_PIN_INPUT_PULLUP},
{"gpmc_ad14.gpmc_ad14", OMAP_MUX_MODE0 | AM33XX_PIN_INPUT_PULLUP},
{"gpmc_ad15.gpmc_ad15", OMAP_MUX_MODE0 | AM33XX_PIN_INPUT_PULLUP},

{"gpmc_a0.gpmc_a0", OMAP_MUX_MODE0 | AM33XX_PIN_OUTPUT | AM33XX_PULL_DISA},
{"gpmc_a1.gpmc_a1", OMAP_MUX_MODE0 | AM33XX_PIN_OUTPUT | AM33XX_PULL_DISA},
{"gpmc_a2.gpmc_a2", OMAP_MUX_MODE0 | AM33XX_PIN_OUTPUT | AM33XX_PULL_DISA},
{"gpmc_a3.gpmc_a3", OMAP_MUX_MODE0 | AM33XX_PIN_OUTPUT | AM33XX_PULL_DISA},
{"gpmc_a4.gpmc_a4", OMAP_MUX_MODE0 | AM33XX_PIN_OUTPUT | AM33XX_PULL_DISA},
{"gpmc_a5.gpmc_a5", OMAP_MUX_MODE0 | AM33XX_PIN_OUTPUT | AM33XX_PULL_DISA},
{"gpmc_a6.gpmc_a6", OMAP_MUX_MODE0 | AM33XX_PIN_OUTPUT | AM33XX_PULL_DISA},
{"gpmc_a7.gpmc_a7", OMAP_MUX_MODE0 | AM33XX_PIN_OUTPUT | AM33XX_PULL_DISA},
{"gpmc_a8.gpmc_a8", OMAP_MUX_MODE0 | AM33XX_PIN_OUTPUT | AM33XX_PULL_DISA},
{"gpmc_a9.gpmc_a9", OMAP_MUX_MODE0 | AM33XX_PIN_OUTPUT | AM33XX_PULL_DISA},
{"gpmc_a10.gpmc_a10", OMAP_MUX_MODE0 | AM33XX_PIN_OUTPUT | AM33XX_PULL_DISA},
{"gpmc_a11.gpmc_a11", OMAP_MUX_MODE0 | AM33XX_PIN_OUTPUT | AM33XX_PULL_DISA},

{"gpmc_advn_ale.gpio2_2", OMAP_MUX_MODE7 | AM33XX_PIN_INPUT},
{"gpmc_ben0_cle.gpio2_5", OMAP_MUX_MODE7 | AM33XX_PIN_INPUT},
{"gpmc_clk.gpio2_1", OMAP_MUX_MODE7 | AM33XX_PIN_INPUT}, {"gpmc_csn1.gpmc_csn1", OMAP_MUX_MODE0 | AM33XX_PULL_DISA}, {"gpmc_csn2.gpio1_31", OMAP_MUX_MODE7 | AM33XX_PIN_INPUT},
{"gpmc_oen_ren.gpmc_oen_ren", OMAP_MUX_MODE0 | AM33XX_PULL_DISA},
{"gpmc_wait0.gpio0_30", OMAP_MUX_MODE7 | AM33XX_PIN_INPUT},
{"gpmc_wen.gpmc_wen", OMAP_MUX_MODE0 | AM33XX_PULL_DISA},
{NULL, 0},
};

…….

============gpmc driver===========================

#define GPMC_CS 1

…….

#define SYNC_NOR_CONFIG1 0x578e1000
#define SYNC_NOR_CONFIG2 0x000f0f01
#define SYNC_NOR_CONFIG3 0x00000000
#define SYNC_NOR_CONFIG4 0x0f010f01
#define SYNC_NOR_CONFIG5 0x01030f0f
#define SYNC_NOR_CONFIG6 0x2303010f

……

if (gpmc_cs_request(GPMC_CS, FPGA_SIZE, (unsigned long *)&fpga_phy_base) < 0)
{
……
}
if (request_mem_region(fpga_phy_base,FPGA_SIZE, "fpga") == NULL)

{
……
}

fpga_vir_base = ioremap(fpga_phy_base, SZ_4K);

……

//读写函数,从双口ram的0xaaa地址开始读写

static ssize_t fpgadev_read(struct file *p_file, char __user *u_buf, size_t size, loff_t *p_pos)
{
        ……
        long addr = 0xaaa;

      for (i=0; i<len; i=i+2)
     {
            tmp = readw(fpga_vir_base + addr);

            …….
          addr=addr+1;
          for(j=50000;j>0;j–)
                for(k=200;k>0;k–);
    }

……

}

static ssize_t fpgadev_write(struct file *p_file, const char __user *u_buf, size_t size, loff_t *p_pos)
{

       ……

      for (i=0; i<len; i=i+2)
     {
            tmp = ((p_fpgadev->m_buf[i+1])<<8);
            tmp = tmp | (p_fpgadev->m_buf[i]);
            writew(tmp, fpga_vir_base+addr);            printk(KERN_ALERT "*****Write*****%p, %04x\n", fpga_vir_base+addr, tmp);            addr=addr+1;
            for(j=50000;j>0;j–)
                  for(k=200;k>0;k–);
       }
      ……

}

通过上面的read和write函数读写0xaaa这个地址时验证是正确的,读写0xaab这个地址就不对了。不过现在又突然写ram时三个控制信号没有了,程序什么都没动,为什么有时候可以,有时候又不可以了呢?还请前辈高手指教,谢谢!

Gary Wu:

程序未改动,一会有信号,一会无信号,我的理解是

(1)示波器测试时是否恰当?

(2)硬件问题是否排除?可否多块板对比测试?

science:

回复 Gary Wu:

Gary Wu 谢谢你的回答。

(1)示波器测试时应该没有问题的,我读双口ram时,示波器能够检测到gpmc_oen、gpmc_cs1、gpmc_wen这三个控制信号的变化,以前示波器调好后,读写双口ram的控制信号都能检测到,现在示波器的调整和以前的一样,但是就是检测不到写ram的控制信号变化,只能检测到读ram的了,应该不是示波器的问题。

(2)硬件上我采用的是gpmc_a0~gpmc_a11这12个地址线,采用异步16-Bit Non-multiplexed方式读写双口ram,我看到TRM 手册(SPRUH73H)的第7部分的Figure 7-4(第259页)上地址线用的是从gpmc_a1开始的,原理图上这点和手册上的不同,不知道跟这个有关吗?访问外部16位的ram时,这个gpmc_a0能当地址线使用吗?

开始时只做了两块板,另一块有点问题,系统启动不了,多块板对比测试现在条件不行了,问题到现在还没有解决,还请多指教,期待您的回复,谢谢!

leo chen:

回复 science:

16位的时候,gpmc_a0不能作为地址线需要空出,

估计是你原理图设计错了

science:

回复 leo chen:

leo chen谢谢您的回答。

我也在想是不是硬件设计的问题,一直拿不准。不知道下面我的理解对不对:

        如果采用16位Non-multiplexed方式访问外部ram设备,地址线必须从gpmc_a1开始使用,gpmc_a1~gpmc_a16这16位地址线用来分别连接外部ram的a0~a15地址接口上,当我读写外部ram的某一个地址时,am335x会自动将这个地址的值通过gpmc_a1~gpmc_a16地址线传到ram的a0~a15地址接口接口上,而不会使用到gpmc_a0这个地址线,读写地址的最低位地址是gpmc_a1。地址会通过gpmc_a0还是gpmc_a1开始传,am335x会通过是否是按照16位方式来自动判断。

        leo chen,以上我的理解对吗?期待您的回复,非常感谢!

赞(0)
未经允许不得转载:TI中文支持网 » AM335x读写双口ram问题
分享到: 更多 (0)