📄 ri.c
字号:
#include <linux/module.h>#include <linux/moduleparam.h>#include <linux/init.h>#include <linux/time.h>#include <linux/kernel.h> /* printk() */#include <linux/fs.h> /* everything... */#include <linux/cdev.h>#include <linux/interrupt.h> /* request_irq() */#include <asm/arch/regs-gpio.h>#include <asm/arch/regs-irq.h>#include <asm/io.h>#include <asm/uaccess.h> /* copy_to_user() */#include <linux/delay.h> /* mdelay() */#include <asm/hardware.h>#include <linux/poll.h>#include <asm/irq.h>#include <asm/mach/time.h>#include <asm/hardware/clock.h>#include <asm/arch/regs-timer.h>#ifdef CONFIG_DEVFS_FS#include <linux/devfs_fs_kernel.h>#endifstatic int RI_major = 0;static int RI_minor = 0;static struct cdev *RI_cdev;volatile unsigned long timecount = 0;volatile unsigned long timecount0 = 0;volatile unsigned long time = 0;static int cr = 0;static int dr = 0;static int ir = 0;static int code = 0;unsigned int a = 0;static DECLARE_WAIT_QUEUE_HEAD(RI_waitq);static irqreturn_t RI_interrupt(int irq, void *dev_id){ //读计数器的值 timecount = __raw_readl(S3C2410_TCNTO(0)); if(timecount <= timecount0) { time = timecount0 - timecount; timecount0 = timecount; } else { time = timecount0 + 65533 - timecount; timecount0 = timecount; } //判断接收值 if(cr == 1) { //接收8位数值 //code = 10; if((time >= 110) && (time <= 130)) { code &=~ (0<<a); a++; } else if((time >= 230) && (time <= 260)) { code |= (1<<a); a++; } } else { //接收头码 if((time >= 350) && (time <= 450)) { cr = 1; //code = time; } } if(a==8) { a = 0; cr = 0; ir = 1; wake_up_interruptible(&RI_waitq); } //i = 0; //cr = 0; return IRQ_RETVAL(IRQ_HANDLED);}static int RI_read(struct file *file, char __user *buff, size_t count, loff_t *offp){ int retval; wait_event_interruptible(RI_waitq, ir); retval = copy_to_user(buff, &code, sizeof(unsigned int)); ir = 0; code = 0; return retval ? -EFAULT : sizeof(unsigned int);}static int RI_open(struct inode *inode, struct file *file){ int err; unsigned long tcon; unsigned long tcfg1; unsigned long tcfg0;//注册中断处理函数 使用EINT17 /*s3c2410_gpio_cfgpin(S3C2410_GPG11, S3C2410_GPG11_EINT19); err = request_irq(IRQ_EINT19, RI_interrupt, NULL, "RI", NULL); set_irq_type(IRQ_EINT19, IRQT_FALLING);*/ s3c2410_gpio_cfgpin(S3C2410_GPG1, S3C2410_GPG1_EINT9); err = request_irq(IRQ_EINT9, RI_interrupt, NULL, "RI", NULL); set_irq_type(IRQ_EINT9, IRQT_FALLING); if(err) { return -EBUSY; }//初始化定时器0 //set GPB0 as tout0, pwm output s3c2410_gpio_cfgpin(S3C2410_GPB0, S3C2410_GPB0_TOUT0); tcon = __raw_readl(S3C2410_TCON); tcfg1 = __raw_readl(S3C2410_TCFG1); tcfg0 = __raw_readl(S3C2410_TCFG0); //prescaler = 255 tcfg0 &= ~S3C2410_TCFG_PRESCALER0_MASK; tcfg0 |= (256 - 1); //mux = 1/2 tcfg1 &= ~S3C2410_TCFG1_MUX0_MASK; tcfg1 |= S3C2410_TCFG1_MUX0_DIV2; __raw_writel(tcfg1, S3C2410_TCFG1); __raw_writel(tcfg0, S3C2410_TCFG0); __raw_writel(65533, S3C2410_TCNTB(0)); __raw_writel(0, S3C2410_TCMPB(0)); tcon &= ~0x1f; tcon |= 0xb; //disable deadzone, not auto-reload, inv-off, update TCNTB0&TCMPB0, stop timer 0 __raw_writel(tcon, S3C2410_TCON); tcon &= ~2; //clear manual update bit __raw_writel(tcon, S3C2410_TCON); return 0;}static int RI_close(struct inode *inode, struct file *file){ free_irq(IRQ_EINT9, NULL); return 0;}//文件操作结构初始化static struct file_operations RI_fops = { .owner = THIS_MODULE, .read = RI_read, .open = RI_open, .release = RI_close,};//初始化函数static int __init RI_init(void){ int result; dev_t dev = 0;//动态分配主设备号 if(RI_major) { dev = MKDEV(RI_major, RI_minor); result = register_chrdev_region(dev, 1, "utuRI"); } else { result = alloc_chrdev_region(&dev, 0, 1, "utuRI"); RI_major = MAJOR(dev); } if(result < 0) { printk(KERN_WARNING "RI : can't get major number!!\n"); return result; }//字符设备注册 RI_cdev = cdev_alloc(); cdev_init(RI_cdev, &RI_fops); RI_cdev -> owner = THIS_MODULE; RI_cdev -> ops = &RI_fops; result = cdev_add(RI_cdev, dev, 1); if(result) { unregister_chrdev_region(dev, 1); printk(KERN_NOTICE "error adding RI"); return result; } //printk(KERN_INFO "Todo: mknod c /dev/%s %d 0\n","utuRI",RI_major); return 0;}//清除函数static void __exit RI_cleanup(void){ dev_t dev = MKDEV(RI_major, RI_minor); cdev_del(RI_cdev); unregister_chrdev_region(dev, 1); printk(KERN_INFO "unregistered the %s\n","utuRI");}module_init(RI_init);module_exit(RI_cleanup);MODULE_LICENSE("Dual BSD/GPL");
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -