TI论坛
直播中

常静娜

8年用户 162经验值
私信 关注
[问答]

am335x的GPMC驱动问题

大家好,我用的是异步传输,地址数据不共用地址数据,单独读写,我在board_am335xevm.c下面修改了如下信息
static struct pinmux_config gpmc_FPGA_pin_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_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_csn1.gpmc_csn1", OMAP_MUX_MODE0 | AM33XX_PULL_DISA],
["gpmc_oen_ren.gpmc_oen_ren", OMAP_MUX_MODE0 | AM33XX_PULL_DISA],
["gpmc_wen.gpmc_wen", OMAP_MUX_MODE0 | AM33XX_PULL_DISA],
["gpmc_clk.gpmc_wait1", OMAP_MUX_MODE2 | AM33XX_PIN_INPUT_PULLUP],
[NULL, 0],
];  //引脚的定义

static void gpmc_fpga_init(void)  
[
//struct gpmc_devices_info gpmc_device[2] =[
//[NULL, GPMC_DEVICE_NOR],

//];
//omap_init_gpmc(gpmc_device,sizeof(gpmc_device));
setup_pin_mux(gpmc_fpga_pin_mux);
//omap_init_elm();
]

[gpmc_fpga_init,   DEV_ON_BASEBOARD,PROFILE_ALL],
6个寄存器的配置如下
#define STNOR_GPMC_CONFIG1 0x00251000 
#define STNOR_GPMC_CONFIG2 0x00080801
#define STNOR_GPMC_CONFIG3 0x00020201
#define STNOR_GPMC_CONFIG4 0x0602c662
#define STNOR_GPMC_CONFIG5 0x01050808
#define STNOR_GPMC_CONFIG6 0x05070142
//#define STNOR_GPMC_CONFIG7 0x00000f50

请问各位在board_am335xevm.c中的static void gpmc_fpga_init(void)  函数里是否应该加上omap_init_gpmc(gpmc_device,sizeof(gpmc_device));和omap_init_elm();

回帖(10)

常静娜

2018-6-4 15:50:54
驱动是按照网上的一个帖子写的http://bbs.eeworld.com.cn/thread-333652-1-1.html。做了一点修改该,下面是我的驱动

#define STNOR_GPMC_CONFIG1 0x00251000 //002a2000,28601000
#define STNOR_GPMC_CONFIG2 0x00080801//0x00011001
#define STNOR_GPMC_CONFIG3 0x00020201
#define STNOR_GPMC_CONFIG4 0x0602c662//0x08031003
#define STNOR_GPMC_CONFIG5 0x01050808//0x000f1111
#define STNOR_GPMC_CONFIG6 0x05070142//0x0f030080
//#define STNOR_GPMC_CONFIG7 0x00000f50
static const u32 gpmc_nor[7] = [
STNOR_GPMC_CONFIG1,
STNOR_GPMC_CONFIG2,
STNOR_GPMC_CONFIG3,
STNOR_GPMC_CONFIG4,
STNOR_GPMC_CONFIG5,
STNOR_GPMC_CONFIG6,
//STNOR_GPMC_CONFIG7,
0,
];
int fpga_ioctl(struct file *filp,unsigned int cmd,unsigned long arg)
[
ssize_t status;
char write_buff[] = "the gpmc driver is ok!";
switch(cmd)
[
case 0:
if(down_interruptible(&fpga_dev.sem))
return -ERESTARTSYS;
fpga_dev.addr = arg;
printk("n*********write add = 0x%xn",fpga_dev.addr);
//up(&fpga_dev.sem);
break;
case 1:
if(down_interruptible(&fpga_dev.sem))
return -ERESTARTSYS;
if(copy_to_user(((char *)arg),write_buff,sizeof(write_buff)+1))
[
status = -EFAULT;
goto read_done_xd;
]
//printk("read_buff_done:%snr",write_buff);
//up(&fpga_dev.sem);
break;
default:
return ENOTTY;
]
read_done_xd:
[
printk("ioctl done!!nr");
up(&fpga_dev.sem);
]
return status;

]
static ssize_t fpga_write(struct file *filp, const char __user *buff, size_t count, loff_t *f_pos)
[
ssize_t status;
size_t len = USER_BUFF_SIZE - 1;
int i,tmp;
if (count == 0)
return 0;
if (down_interruptible(&fpga_dev.sem))
return -ERESTARTSYS;
if (len > count)
len = count;
memset(fpga_dev.user_buff, 0, USER_BUFF_SIZE);
if (copy_from_user(fpga_dev.user_buff, buff, len)) [
status = -EFAULT;
goto fpga_write_done;
]
/* do something with the user data */
printk("fpga_write_xdn");
for (i = 0; i < len; i=i+2) [
tmp = fpga_dev.user_buff | fpga_dev.user_buff[i+1] << 8;
writew(tmp,fpga_base+fpga_dev.addr+fpga_dev.addr); //在指定地址里写入数据16BIT;
]
for (i = 0; i < len; i++) [
printk("0x%x ",fpga_dev.user_buff);
]
printk("n");
fpga_write_done:
printk("*******before write up sem******n");
up(&fpga_dev.sem);
printk("*******after write up sem******n");
return status;
]

static ssize_t fpga_read(struct file *filp, const char __user *buff, size_t count, loff_t *f_pos)
[
size_t status;
size_t len = USER_BUFF_SIZE -1;

if(count == 0)
return 0;
printk("*******before read down sem******n");
if(down_interruptible( &fpga_dev.sem))
return -ERESTARTSYS;
printk("*******after read down sem******n");
if(len>count)
len = count;
memset(fpga_dev.user_buff,0,USER_BUFF_SIZE);
printk("*******before readb******n");
fpga_dev.user_buff[0]= readb(fpga_base+fpga_dev.addr+fpga_dev.addr);
fpga_dev.user_buff[1]= readb(fpga_base+fpga_dev.addr+fpga_dev.addr+1);
printk("fpga_read_xd len= n");
if(copy_to_user(buff,fpga_dev.user_buff,len))
[
status = -EFAULT;
goto fpga_read_done;
]
fpga_read_done:
printk("fpga_read_done_xdn");
up(&fpga_dev.sem);
return status;

]

static int fpga_open(struct inode *inode, struct file *filp)
[
int status = 0;
if (down_interruptible(&fpga_dev.sem))
return -ERESTARTSYS;
if (!fpga_dev.user_buff)
[
fpga_dev.user_buff = kmalloc(USER_BUFF_SIZE, GFP_KERNEL);
if (!fpga_dev.user_buff)
[
printk(KERN_ALERT "fpga_open: user_buff alloc failedn");
status = -ENOMEM;
]
]
up(&fpga_dev.sem);
return status;
]
static const struct file_operations fpga_fops = [
.owner = THIS_MODULE,
.open = fpga_open,
.read = fpga_read,
.write = fpga_write,
.unlocked_ioctl = fpga_ioctl,
];
static int __init fpga_init_cdevice(void)
[
int error;
u32 val;
fpga_dev.devt = MKDEV(251,0);
error = alloc_chrdev_region(&fpga_dev.devt,0,1,"fpga");
if (error)
[
printk(KERN_ALERT "alloc_chrdev_region() failed: %dn", error);
return error;
]
cdev_init(&fpga_dev.cdev, &fpga_fops);
fpga_dev.cdev.owner = THIS_MODULE;
error = cdev_add(&fpga_dev.cdev, fpga_dev.devt, 1);
if (error)
[
printk(KERN_ALERT "cdev_add() failed: %dn", error);
unregister_chrdev_region(fpga_dev.devt, 1);
return error;
]
printk("Getting Chip Selectn");
val = gpmc_cs_read_reg(GPMC_CS,GPMC_CS_CONFIG7); //关闭片选
val &= ~GPMC_CONFIG7_CSVALID;
gpmc_cs_write_reg(GPMC_CS,GPMC_CS_CONFIG7,val);

gpmc_cs_configure(GPMC_CS, GPMC_SET_IRQ_STATUS, 0); /*set irq status*/
gpmc_cs_configure(GPMC_CS, GPMC_ENABLE_IRQ, 0); /*disable irqs*/
gpmc_cs_write_reg(GPMC_CS, GPMC_CS_CONFIG1, gpmc_nor[0]);
gpmc_cs_write_reg(GPMC_CS, GPMC_CS_CONFIG2, gpmc_nor[1]);
gpmc_cs_write_reg(GPMC_CS, GPMC_CS_CONFIG3, gpmc_nor[2]);
gpmc_cs_write_reg(GPMC_CS, GPMC_CS_CONFIG4, gpmc_nor[3]);
gpmc_cs_write_reg(GPMC_CS, GPMC_CS_CONFIG5, gpmc_nor[4]);
gpmc_cs_write_reg(GPMC_CS, GPMC_CS_CONFIG6, gpmc_nor[5]);
//gpmc_cs_write_reg(GPMC_CS, GPMC_CS_CONFIG7, gpmc_nor[6]);
val = gpmc_cs_read_reg(GPMC_CS, GPMC_CS_CONFIG7);
printk("GPMC_CS_CONFIG7 value 0x%xn", val);
if (gpmc_cs_request(GPMC_CS, SZ_2K, (unsigned long *)&mem_base) < 0)
[
printk(KERN_ERR "Failed request for GPMC mem for usrp_en");
return -1;
]

printk("Got CS2, address = %lxn", mem_base);
if (!request_mem_region(mem_base, SZ_2K, "mem_fpga"))
[
printk(KERN_ERR "Request_mem_region failed.n");
gpmc_cs_free(GPMC_CS);
return -1;
]
fpga_base = ioremap(mem_base, SZ_2K);
gpmc_cs_configure(GPMC_CS, GPMC_ENABLE_IRQ, 1);
val = gpmc_cs_read_reg(GPMC_CS,GPMC_CS_CONFIG7);
val |= GPMC_CONFIG7_CSVALID;
gpmc_cs_write_reg(GPMC_CS,GPMC_CS_CONFIG7,val);
return 0;
]

static int __init fpga_init_class(void)
[
struct device *device;
fpga_dev.class = class_create(THIS_MODULE, "fpga");
if (IS_ERR(fpga_dev.class))
[
printk(KERN_ALERT "class_create(fpga) failedn");
return PTR_ERR(fpga_dev.class);
]
device = device_create(fpga_dev.class, NULL, fpga_dev.devt, NULL, "fpga");
if (IS_ERR(device))
[
class_destroy(fpga_dev.class);
return PTR_ERR(device);
]
return 0;
]
static int __init fpga_init(void)
[
printk(KERN_INFO "fpga_init()n");
memset(&fpga_dev, 0, sizeof(struct fpga_dev));
sema_init(&fpga_dev.sem, 1);
if (fpga_init_cdevice())
goto init_fail_1;
if (fpga_init_class())
goto init_fail_2;
return 0;
init_fail_2:
cdev_del(&fpga_dev.cdev);
unregister_chrdev_region(fpga_dev.devt, 1);
init_fail_1:
return -1;
]
module_init(fpga_init);
static void __exit fpga_exit(void)
[
printk(KERN_INFO "fpga_exit()n");
device_destroy(fpga_dev.class, fpga_dev.devt);
class_destroy(fpga_dev.class);
cdev_del(&fpga_dev.cdev);
unregister_chrdev_region(fpga_dev.devt, 1);
release_mem_region(mem_base, SZ_2K);
gpmc_cs_free(GPMC_CS);
iounmap(fpga_base);
if (fpga_dev.user_buff)
kfree(fpga_dev.user_buff);
]
module_exit(fpga_exit);
举报

常静娜

2018-6-4 16:10:53
引用: 60user99 发表于 2018-6-4 15:50
驱动是按照网上的一个帖子写的http://bbs.eeworld.com.cn/thread-333652-1-1.html。做了一点修改该,下面是我的驱动

#define STNOR_GPMC_CONFIG1 0x00251000 //002a2000,28601000

int fd,i,res;
unsigned char buf[PAGE_SIZE];

unsigned char read_buff[2];
printf("GPMC Test startnr");
fd=open(FPGA_DEV,O_RDWR);
if(fd<0)
[
printf("Can't Open %s !!!nr",FPGA_DEV);
return -1;
]

for(i=0;i [
buf = i%256;
]
ioctl(fd,0,0xaa);
//ioctl(fd,1,read_buff);
//printf("%snr",read_buff);

for(i=0;i<100;i++)
[
write(fd,&buf,PAGE_SIZE);
]
//read(fd,&read_buff,2);
//printf(" read from gpmc : 0x%x,0x%xnr",read_buff[1],read_buff[0]);
close(fd);
return 0;

这个是测试程序,但是每次都只写入一次10个字节,到下一个循环式就卡死了

在第二fpga_write那里就卡住了。。。
printk("fpga_write_xdn");
for (i = 0; i < len; i=i+2) [
tmp = fpga_dev.user_buff | fpga_dev.user_buff[i+1] << 8;
writew(tmp,fpga_base+fpga_dev.addr+fpga_dev.addr); //在指定地址里写入数据16BIT;
]
求大家帮忙分析
举报

常静娜

2018-6-4 16:26:13
引用: 60user99 发表于 2018-6-4 16:10
int fd,i,res;
unsigned char buf;

进一步发现在第二轮写时在写第7第8字节时就卡在了writew。不知道什么原因
举报

罗兰君

2018-6-4 16:31:25
引用: 60user99 发表于 2018-6-4 16:26
进一步发现在第二轮写时在写第7第8字节时就卡在了writew。不知道什么原因

很多客户都是参考那个帖子写的FPGA读写代码,能够正常工作的。但是具体FPGA的读写时序和工作方式不一样,需要修改GPMC的配置
举报

更多回帖

×
20
完善资料,
赚取积分