📄 robot_face.c
字号:
/** system depend file*/#include <linux/init.h>#include <linux/config.h>#include <linux/module.h>#include <linux/moduleparam.h>#include <linux/init.h>#include <linux/sched.h>#include <linux/kernel.h> /* printk() */#include <linux/slab.h> /* kmalloc() */#include <linux/fs.h> /* everything... */#include <linux/errno.h> /* error codes */#include <linux/types.h> /* size_t */#include <linux/delay.h>#include <linux/proc_fs.h>#include <linux/fcntl.h> /* O_ACCMODE */#include <linux/aio.h>#include <asm/uaccess.h>#include <asm/leds.h>#include <linux/ioctl.h>#include <linux/cdev.h>#include <asm/semaphore.h>#include <asm/arch/map.h>#include <asm/arch/regs-timer.h>#include <asm/arch/regs-irq.h>#include <asm/arch/regs-gpio.h>#define DEVFS_FL_DEFAULT 0x000#define FACE_DEVNAME "robot_face"#define FACE_MASK 0xFFFF //GPD are all output#define FACE_ADDR_MASK 0x003F //GPE<5..0>=face addr#define BIT_TIMER0 (0x1<<10)#define BIT_TIMER1 (0x1<<11)#define BIT_TIMER2 (0x1<<12)#define BIT_TIMER3 (0x1<<13)#define BIT_TIMER4 (0x1<<14)static int nFaceMajor = 0;extern devfs_mk_dir(const char *fmt,...);int face_major = 0;int face_devs = 1; /* number of bare face devices */struct unit { struct semaphore lock; u32 *GPD_CON; u32 *GPD_DAT; u32 *GPD_UP; u32 *GPE_CON; u32 *GPE_DAT; u32 *GPE_UP; u32 *TCFG0; u32 *TCFG1; u32 *TCON; u32 *TCNTB; u32 *INTMSK; u32 *SRCPND; u32 *INTPND; }; static struct unit face_unit={ .GPD_CON = (u32 *)S3C2410_GPDCON, .GPD_DAT = (u32 *)S3C2410_GPDDAT, .GPD_UP = (u32 *)S3C2410_GPDUP, .GPE_CON = (u32 *)S3C2410_GPECON, .GPE_DAT = (u32 *)S3C2410_GPEDAT, .GPE_UP = (u32 *)S3C2410_GPEUP, .TCFG0 = (u32 *)S3C2410_TCFG0, .TCFG1 = (u32 *)S3C2410_TCFG1, .TCON = (u32 *)S3C2410_TCON, .TCNTB = (u32 *)S3C2410_TCNTB(1), .INTMSK = (u32 *)S3C2410_INTMSK, .SRCPND = (u32 *)S3C2410_SRCPND, .INTPND = (u32 *)S3C2410_INTPND, };void delay(int usecs){ volatile int loops; for(loops = usecs * 12; loops > 0; loops--) /* nothing */; }volatile int face_counter;u16 face_tmp[40];//[0-15]:left eye; [16..31]:right eye;[32..39]:mousestatic irqreturn_t Timer1Done(void) { u32 temp; int j; //printk("t0\n"); *face_unit.SRCPND=BIT_TIMER1; *face_unit.INTPND=BIT_TIMER1; *face_unit.INTPND; *face_unit.GPE_DAT=*face_unit.GPE_DAT & (~FACE_ADDR_MASK) | face_counter;//set face address *face_unit.GPD_DAT=*face_unit.GPD_DAT & (~FACE_MASK) | face_tmp[face_counter];//set face value face_counter++; if(face_counter>=40) face_counter=0; } int face_open (struct inode *inode, struct file *file) { printk("open\n"); file->private_data=&face_unit; *face_unit.INTMSK=*face_unit.INTMSK & (~BIT_TIMER1) ;//enable init_timer1 *face_unit.TCON=*face_unit.TCON & ~(0x000f00) | 0x000900; //enable timer1 return 0; /* success */ } static int face_release_f (struct inode *inode, struct file *file) { //printk("release\n"); return 0; } static ssize_t face_write (struct file *file, const char *buf, size_t count, loff_t *offset) { int j,ret; struct unit *unit=(struct unit *)file->private_data; ret=copy_from_user(face_tmp, buf, count) ? -EFAULT:count; return ret; }static struct file_operations face_ops = { .owner = THIS_MODULE, .write = face_write, .open = face_open, .release = face_release_f,};void face_init(void) { int i,res; #ifdef CONFIG_DEVFS_FS res= register_chrdev(0,FACE_DEVNAME, &face_ops); if(res<0) { printk("robot_face.o:unable to get major for face device.\n"); return res; } //create the devfs: /driver/face/ devfs_mk_dir(FACE_DEVNAME); devfs_mk_cdev(MKDEV(res,0),S_IFCHR | S_IRUSR |S_IWUSR, FACE_DEVNAME"/%d",0); #else res = register_chrdev(nFaceMajor, FACE_DEVNAME, &face_ops); #endif //get the major number if(nFaceMajor==0) { nFaceMajor = res; printk("Face major number = %d.\n",nFaceMajor); } /* for (i=0;i<40;i++) face_tmp[i]=0xffff; */ *face_unit.GPD_DAT=(*face_unit.GPD_DAT)&0x0; *face_unit.GPD_CON=(*face_unit.GPD_CON)&0x0 | 0x55555555; *face_unit.GPD_UP=(*face_unit.GPD_UP) | 0xffff ;//disabled pull-up *face_unit.GPE_DAT=(*face_unit.GPE_DAT) & (~FACE_ADDR_MASK) | 0x3;//not show *face_unit.GPE_CON=(*face_unit.GPD_CON) & 0xFFFFF000 | 0x00000555; //GPE[5..0]=OUTPUT *face_unit.GPE_UP=(*face_unit.GPD_UP) & 0xFFC0; // GPE[5..0] pull up enabled face_counter=0; //*face_unit.GPD_DAT=face_unit.f; int ret=request_irq(IRQ_TIMER1,Timer1Done,SA_INTERRUPT,FACE_DEVNAME,NULL); *face_unit.INTMSK=*face_unit.INTMSK | (BIT_TIMER1) ;//disable init_timer1 if(ret) { printk("IRQ_TIMER1: :could not register interrupt,ret=0x%X\n",ret); return ret; } printk("IRQ_TIMER1: register interrupt succeed,ret=0x%X\n",ret); *face_unit.TCFG0=*face_unit.TCFG0 & ~(0x0000ff) | 0x000000; *face_unit.TCFG1=*face_unit.TCFG1 & ~(0x0000f0) | 0x000030; *face_unit.TCNTB=0x271; //5kHz *face_unit.TCON=*face_unit.TCON & ~(0x000f00) | 0x000a00; //*face_unit.TCON=*face_unit.TCON & ~(0x000f00) | 0x000900; //printk("IRQ_TIMER1: INTMSK=0x%X\n",*face_unit.INTMSK); }static void __exit face_exit(void) { int ret; free_irq(IRQ_TIMER1,FACE_DEVNAME); ret=unregister_chrdev(nFaceMajor, FACE_DEVNAME); if (ret<0) printk("error in module unregistering\n"); printk("Out,Out.\n"); //printk(KERN_ALERT "Out,Out.\n"); }module_init(face_init);module_exit(face_exit);MODULE_AUTHOR("JORRY");MODULE_LICENSE("GPL");
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -