参考了网上的这篇文章来编写双口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时三个控制信号没有了,程序什么都没动,为什么有时候可以,有时候又不可以了呢?还请前辈高手指教,谢谢!



