最近在写一个am3354和FPGA通信的Linux驱动, FPGA是16位,异步,不复用引脚设备,使用的片选2,下面是我的驱动程序,无法实现两者的数据传输,跪求指教!
#include <linux/kernel.h> #include <linux/platform_device.h> #include <linux/gpio.h> #include <linux/delay.h> #include <linux/interrupt.h> #include <linux/io.h> #include <linux/module.h> #include <linux/slab.h> #include <linux/init.h> #include <linux/fs.h> #include <linux/delay.h> #include <plat/board.h> #include <plat/gpmc.h> #include <plat/gpmc-smc91x.h> #include <asm/uaccess.h> #include <linux/dma-mapping.h> #include <linux/string.h>
static int major ; static struct class *gpmc_fpga_cls; static struct device *gpmc_fpga_dev; static char __iomem *fpga_access_base; dma_addr_t fpga_phy_base;
#define GPCM_FPGA_CS 2 //FPGA选择通道3 #define FPGA_ACCESS_SIZE SZ_16M//FPGA通道的大小
static struct gpmc_timings fpga_default_timings = {
.sync_clk = 0,
.cs_on = 0, .cs_rd_off = 89, .cs_wr_off = 57,
.adv_on = 3, .adv_rd_off = 9, .adv_wr_off = 9,
.we_on = 3, .we_off = 48, .oe_off = 89,
.access = 80, .rd_cycle = 96, .wr_cycle = 57,
}; static void gpmc_write_reg(int idx, u32 val) { writel(val, gpmc->io_base + idx); }
static u32 gpmc_read_reg(int idx) { return readl(gpmc->io_base + idx); }
static int gpmc_fpga_open(struct inode * inode, struct file * file) { unsigned long val;
/*申请GPMC通道*/ if(gpmc_cs_request(GPCM_FPGA_CS,FPGA_ACCESS_SIZE,&fpga_phy_base) < 0) { printk("fail to gpmc_cs_request!\n"); return -1; }
if (!request_mem_region(fpga_phy_base, FPGA_ACCESS_SIZE, "gpmc_fpga_mem"))
{ printk("fail to request_mem_region\n"); return -EBUSY; }
else printk("fpga_phy_base = 0x%0x\n",fpga_phy_base);
fpga_access_base = ioremap(fpga_phy_base,FPGA_ACCESS_SIZE);
if(fpga_access_base == NULL) { printk("fail to ioremap!\n"); return -ENOMEM; }
gpmc_write_reg(GPMC_IRQENABLE, 0);
gpmc_write_reg(GPMC_TIMEOUT_CONTROL, 0);
/*3,利用内核提供的函数设置时序*/
gpmc_cs_set_timings(GPCM_FPGA_CS,&fpga_default_timings);
return 0; }
static ssize_t gpmc_fpga_read(struct file *flle, char __user *ubuf, size_t count, loff_t *ppos)
{ int ret = 0;
unsigned int temp;
temp = readl(fpga_access_base + 0x31);
if(copy_to_user(ubuf,&temp ,count))
{ ret = -EINVAL; }
return ret; }
static ssize_t gpmc_fpga_write(struct file *file, const char __user *ubuf, size_t count, loff_t *ppos)
{ int ret = 0;
unsigned int temp;
if(copy_from_user(&temp ,ubuf ,count)) ret = -EINVAL; else { writel(temp,fpga_access_base + 0x31); *ppos += count; ret = count; }
return ret;
}
static struct file_operations gpmc_fpga_fops =
{ .open = gpmc_fpga_open,
.read = gpmc_fpga_read,
.write = gpmc_fpga_write,
.owner = THIS_MODULE, };
static int gpmc_fpga_init(void)
{ int val;
printk("gpmc_fpga_init\n");
major = register_chrdev(0, "gpmc_fpga", &gpmc_fpga_fops);
gpmc_fpga_cls = class_create(THIS_MODULE, "gpmc_fpga");
gpmc_fpga_dev = device_create(gpmc_fpga_cls, NULL, MKDEV(major, 0), NULL, "gpmc_fpga_dev"); /* /dev/buttons */
return 0; }
static void gpmc_fpga_exit(void)
{ iounmap(fpga_access_base);
gpmc_cs_free(GPCM_FPGA_CS);
device_destroy(gpmc_fpga_cls,MKDEV(major, 0));
class_destroy(gpmc_fpga_cls);
unregister_chrdev(major,"gpmc_fpga"); return ; }
module_init(gpmc_fpga_init);
module_exit(gpmc_fpga_exit);
MODULE_LICENSE("GPL");
leo chen:
要说的详细一点嘛
使用的是哪个版本的SDK
如何测试的,测试结果是什么样的