版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
1、#ifndef _FPGA_H_#define _FPGA_H_#define INTMSK (0x4A000008)#define EINTMASK (0x560000A4)#define S3C2410_ENABLE_EINT8_23 (1<<5)#define S3C2410_ENABLE_EINT18 (1<<18)#undef PDEBUG /* undef it, just in case */#define DEBUG /调试时添加此行程序,实际产品中需要注释掉#ifdef DEBUG# define PDEBUG(fmt, args.) printk(
2、KERN_WARNING "fpga: " fmt, # args)#else# define PDEBUG(fmt, args.) /* not debugging: nothing */#endif#define DEVICE_NAME "FPGA"#ifndef FPGA_NR_DEVS#define FPGA_NR_DEVS 1 /*设备数*/#endif#define FPGAMEM_SIZE1024/*FPGA每次产生中断可以读取到缓存的数据大小*/#define FPGACMD_SIZE3 /*FPGA每次产生中断可以读取到缓存的数据大小*
3、/#define FPGA_ADDR_START (0x08000000) /nGCS1地址#define FPGA_ADDR_SIZE 0x30 /申请IO内存的大小#define FPGA_ADDR_DATA 0x10 /FPGA数据寄存器偏移地址#define FPGA_ADDR_CMD 0x14 /FPGA命令寄存器偏移地址/* 定义幻数 ,定义一个字符,8位,用于检测是否是这类设备,ioctl-number.txt中给出了已经使用的幻数,定义的时候注意避免冲突*/#define FPGA_IOC 'k' /* 定义命令 ,这里的命令都是unsigned int类型*/
4、#define FPGA_IOC_ALLON _IO(FPGA_IOC, 0) /#define FPGA_IOC_ALLDOWN _IO(FPGA_IOC, 1) /#define FPGA_IOC_SET _IOW(FPGA_IOC, 2, int) /#define FPGA_IOC_CLEAR _IOW(FPGA_IOC, 3, int)/#define FPGA_IOC_MAXNR 4 /定义命令的最大序列号/* Per-device (per-bank) structure */struct fpga_dev struct cdev cdev; /* The cdev struct
5、ure */ unsigned int readlength; /* 每次中断从FPGA读取数据的实际字节数 */ char bus_dataFPGAMEM_SIZE; /* 缓存从FPGA读取的数据 */ char cmd_dataFPGACMD_SIZE; /* 缓存发送给FPGA的命令 */ struct fasync_struct *async_queue;/* 异步结构体指针,用于读 */ /* . */ /* Mutexes, spinlocks, wait queues, . */ wait_queue_head_t r_wait; /* 阻塞读用的等待队列头 */ *fpga_
6、devp;#endif /* _FPGA_H_ */#include <linux/delay.h>/#include <asm/irq.h>#include <asm/io.h>#include <asm/signal.h>#include <asm-generic/siginfo.h>#include <asm/irq.h>#include <mach/regs-gpio.h>#include <mach/regs-mem.h>#include <mach/hardware.h>#i
7、nclude <linux/kernel.h>#include <linux/module.h>#include <linux/init.h>#include <linux/interrupt.h>#include <linux/mm.h>#include <linux/fs.h>#include <linux/irq.h>#include <linux/types.h>#include <linux/moduleparam.h>#include <linux/slab.h>
8、#include <linux/errno.h>#include <linux/ioctl.h>#include <linux/cdev.h>#include <linux/string.h>#include <linux/list.h>#include <asm/uaccess.h>#include <asm/atomic.h>#include <asm/unistd.h>#include <linux/device.h>#include <linux/ioport.h>#
9、include <linux/gpio.h>#include <linux/sched.h>#include <linux/wait.h>/#include <asm/arch-s3c2410/irqs.h>/#include <asm/arch-s3c2410/regs-gpio.h>#include "fpga.h"/#define FPGADATA (*(volatile unsigned long *)(fpga_addr + 0x10)/FPGA data/#define FPGACON (*(volat
10、ile unsigned long *)(fpga_addr + 0x08)/FPGA control/struct cdev cdev;static struct class *fpga_class;static struct device *fpga_dev;static void _iomem *fpga_addr; /FPGA在Linux中映射的虚拟地址/static struct resource *fpga_mem;static dev_t fpga_num;static volatile int ev_fpga = 0;unsigned int temp = 0;unsigned
11、 int i;static irqreturn_t fpga_interrupt(int irq, void *dev_id, struct pt_regs *regs)/disable_irq(IRQ_EINT18);/PDEBUG("read %d bytes from FPGA:n", count);for (i=0; i<FPGAMEM_SIZE/2; i+) temp = ioread16(fpga_addr+FPGA_ADDR_DATA); /从FPGA读取16位数据 fpga_devp->readlength = fpga_devp->rea
12、dlength + 2;/字节数加2/ PDEBUG("data %d:%dt",i,temp); fpga_devp->bus_data2*i+1 = temp; /将16位数据的低8位转换到字节数组中 fpga_devp->bus_data2*i = temp >> 8; /将16位数据的高8位转换到字节数组中temp = 0;ev_fpga = 1;wake_up_interruptible(&(fpga_devp->r_wait);/* 产生异步读信号 */ if (fpga_devp->async_queue)/ kil
13、l_fasync(&fpga_devp->async_queue, SIGIO, POLL_IN);return IRQ_HANDLED;static int fpga_open(struct inode *inode, struct file *file)int ret;struct fpga_dev *fpga_devp; /* Get the per-device structure that contains this cdev */ fpga_devp = container_of(inode->i_cdev, struct fpga_dev, cdev); /*
14、 Easy access to cmos_devp from rest of the entry points */ file->private_data = fpga_devp; /* Initialize some fields */ s3c2410_gpio_cfgpin(S3C2410_GPG(10), S3C2410_GPG10_EINT18);/使GPG10为中断EINT18s3c2410_gpio_pullup(S3C2410_GPG(10), 0);/禁止上拉/* 申请中断 */set_irq_type(IRQ_EINT18,IRQ_TYPE_LEVEL_LOW);/低电
15、平产生中断 ret = request_irq(IRQ_EINT18, fpga_interrupt, 0, DEVICE_NAME, (void *)NULL);if(ret) PDEBUG("request interrupt failn");return ret;/* 初始化读等待队列 */ init_waitqueue_head(&(fpga_devp->r_wait); PDEBUG("FPGA openedn"); return 0;static ssize_t fpga_read(struct file *file, char
16、 _user *buffer, size_t size, loff_t *ppos)unsigned int count = size;unsigned int ret = 0;struct fpga_dev *fpga_devp = file->private_data;/*获得设备结构体指针*/wait_event_interruptible(fpga_devp->r_wait, ev_fpga);ev_fpga = 0;/* 每次中断从FPGA读取的数据的数量不等于应用程序需要读取的数据时,返回0 */if (fpga_devp->readlength != count
17、)return 0;/*内核空间->用户空间*/ if (copy_to_user(buffer, (void*)(fpga_devp->bus_data), count) ret = - EFAULT; else ret = count; return ret;static ssize_t fpga_write(struct file *file,const char _user *buffer, size_t size, loff_t *ppos)unsigned int count = size;unsigned int tempcmd = 0;unsigned int re
18、t = 0;unsigned int i;struct fpga_dev *fpga_devp = file->private_data;/*获得设备结构体指针*/*用户空间->内核空间*/ if (copy_from_user(void*)(fpga_devp->cmd_data), buffer, count) ret = - EFAULT; else ret = count; PDEBUG("write %d bytes to FPGA:n", count); for (i=0; i<count; i+)tempcmd=fpga_devp-&g
19、t;cmd_datai;/temp=temp<<8;/temp=temp|fpga_devp->cmd_data2*i+1; iowrite16(tempcmd,fpga_addr+FPGA_ADDR_CMD); /向FPGA写入16位数据 PDEBUG("data %d:%dt",i,tempcmd);return ret;/static int fpga_fasync(int fd, struct file *file, int mode)/ struct fpga_dev *fpga_devp = file->private_data;/*获得
20、设备结构体指针*/ return fasync_helper(fd, file, mode, &fpga_devp->async_queue);/static int fpga_release(struct inode *inode, struct file *file)/fpga_fasync(-1, file, 0); /* 将文件从异步通知列表中删除 */free_irq(IRQ_EINT18,NULL);s3c2410_gpio_cfgpin(S3C2410_GPG(10), S3C2410_GPIO_INPUT); PDEBUG("FPGA closedn&q
21、uot;); return 0;/static int fpga_ioctl(/struct inode *inode, /struct file *file, /unsigned int cmd, /unsigned long arg)/int i;/int cmddata;/* 检测命令的有效性 */ if (_IOC_TYPE(cmd) != FPGA_IOC)/命令是否操作这一类设备/ return -EINVAL;/ if (_IOC_NR(cmd) > fpga_IOC_MAXNR) /命令序列号是否超出定义/ return -EINVAL;/switch(cmd) / ca
22、se fpga_IOC_ALLON:/ for(i=0; i<4; i+) / s3c2410_gpio_setpin(led_tablei, 0); /设置IO口为0,LED为全亮状态/ / break;/ / case fpga_IOC_ALLDOWN:/ for(i=0; i<4; i+) / s3c2410_gpio_setpin(led_tablei, 1); /设置IO口为1,LED为全灭状态/ / break;/ / case fpga_IOC_SET: / if (copy_from_user(&cmddata, (int *)arg, sizeof(int
23、)/ return -EFAULT;/ s3c2410_gpio_setpin(led_tablecmddata, 0);/ break;/ / case fpga_IOC_CLEAR: / if (copy_from_user(&cmddata, (int *)arg, sizeof(int)/ return -EFAULT;/ s3c2410_gpio_setpin(led_tablecmddata, 1); / break;/ /default: / return -EINVAL;/return 0;/*文件操作结构体*/static const struct file_oper
24、ations fpga_fops = .owner = THIS_MODULE,/ .ioctl = fpga_ioctl, / .llseek = fpga_llseek, .read = fpga_read, .write = fpga_write,/ .fasync = fpga_fasync, .open = fpga_open, .release = fpga_release,;static int _init fpga_init(void)int ret; struct resource *fpga_res; unsigned int oldval_bwscon; static v
25、oid *intmsk; static void *eintmask; intmsk = ioremap_nocache(INTMSK,0x0000004); eintmask = ioremap_nocache(EINTMASK,0x0000004); /* 设置S3C2410_BWSCON:数据总线宽度16bits,使用UB/LB,禁止WAIT */ oldval_bwscon = *(volatile unsigned int *)S3C2410_BWSCON; *(volatile unsigned int *)S3C2410_BWSCON) = (oldval_bwscon &
26、; (3<<5) | S3C2410_BWSCON_DW1_16 | S3C2410_BWSCON_ST1; /* 设置S3C2410_BANKCON1 */ *(volatile unsigned int *)S3C2410_BANKCON1) = 0x0300; /* 设置S3C2410_GPGCON,使GPG10为中断EINT18 */ oldval_gpgcon = *(volatile unsigned int *)S3C2410_GPGCON;/ *(volatile unsigned int *)S3C2410_GPGCON = oldval_gpgcon | S3C
27、2410_GPG10_EINT18; /* 设置S3C2410_GPGUP,禁止GPG10上拉 */ oldval_gpgup = *(volatile unsigned int *)S3C2410_GPGUP;/ *(volatile unsigned int *)S3C2410_GPGUP = oldval_gpgup | S3C2410_GPG_PUPDIS(10); /* 设置INTMSK,使能中断EINT8_23 */ writel(readl(intmsk) & S3C2410_ENABLE_EINT8_23,intmsk); /* 设置EINTMASK,使能中断EINT1
28、8 */ writel(readl(eintmask) & S3C2410_ENABLE_EINT18,eintmask); / val |= S3C2410_BWSCON_DW2_16;/ S3C2410_BWSCON = S3C2410_BWSCON | (0x02<<7); / _raw_writel(val, S3C2410_BWSCON); /设置bank2的数据总线为16位宽度/ / val = 0x2a60;/ BANKCON2 = 0x2a60; / _raw_writel(val,S3C2410_BANKCON2); /设置满足S3C2440A的nGCS时
29、序 /*动态分配设备号*/ret = alloc_chrdev_region(&fpga_num, 0, FPGA_NR_DEVS, DEVICE_NAME); if (ret < 0) PDEBUG (DEVICE_NAME"can't be registeredn"); return ret; /* 申请设备结构体内存 */ fpga_devp = kmalloc(sizeof(struct fpga_dev), GFP_KERNEL); if (!fpga_devp) /*申请失败*/ PDEBUG("request device st
30、ruct memery failn"); ret = - ENOMEM; goto fail_kmalloc; /* 清零设备缓存 */ memset(fpga_devp, 0, sizeof(struct fpga_dev);/ memset(fpga_devp->cmd_data, 0, FPGACMD_SIZE);/ memset(&(fpga_devp->readlength), 0, sizeof(unsigned int); /* 申请I/O内存 */ fpga_res = request_mem_region(FPGA_ADDR_START,FPGA
31、_ADDR_SIZE,DEVICE_NAME); if(fpga_res = NULL) PDEBUG("request io memery failn"); ret = -EINVAL; goto fail_request_mem; /* 物理地址到虚拟地址映射 */ fpga_addr = ioremap(FPGA_ADDR_START,FPGA_ADDR_SIZE); if(fpga_addr = NULL) PDEBUG("remap address failn"); ret = -ENOMEM; goto fail_ioremap; /*初始化cdev结构*/ cdev_init(&fpga_devp->cdev, &fpga_fops); fpga_devp->cdev.owner = THIS_MODULE; fpga_devp->cdev.ops = &fpga_fops; /* 注册字符设备 */ cdev_add(&fpga_devp->cdev, fpga_num, FPGA_NR_DEVS); fpga_class = class_create(THIS_MODULE,DEVICE_NAME); f
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 2026年河北省沙河市重点中学初三第四次调研诊断考试物理试题理试题含解析
- 护理小组长团队培训计划
- 2026年大学大一(教育学)教育法律法规基础测试题及答案
- 护理人员的专业技能与操作规范
- 2025年前台电子入住礼仪模拟
- 护理自考考试技巧与经验
- 护理礼仪与医疗纠纷预防
- 急诊科护理记录与文书管理
- 护理讲师课件内容广度
- 专题二 选区的创建与编辑(课件)-职教高考电子与信息《图形图像处理》专题复习讲练测
- 2025年11月1日安徽省直遴选面试真题及解析
- 拒绝校园欺凌+课件-2025-2026学年上学期主题班会
- GB/T 9722-2023化学试剂气相色谱法通则
- 2025年中考语文(湖南卷)真题详细解读及评析
- GB/T 9944-2025不锈钢丝绳
- 2025高考历史小论文10种题型范文
- 2025版煤矿安全规程宣贯培训课件
- 鱼腥草种植课件
- 2025年城市垃圾转运站运营成本分析初步设计评估报告
- 2025年政府采购评审专家考试试题库(附答案)
- 河北省2021-2024年中考满分作文74篇
评论
0/150
提交评论