- 论坛徽章:
- 0
|
我根据自己的需要对之前发的那个adc0809的驱动进行了修改
目的:利用2410的timer0做一个定时中断,比如10ms中断一次,
获取数据并对一个阈值进行判读,最后置为0,1,再吧之前获取的数据和刚获取的对比 不同则加1
最后再read函数输出这个累加值
但是不解编译可以,安装insmod的时候会出现0oops错误 不解啊·~~~~~~
麻烦帮我看看啊 感激不及啊~~~~
- /* driver/char/adc0809.c
- * this is a adc0809 char device driver.
- * Any problem pls contact [email]support@hhcn.com[/email]
- */
- #include <linux/module.h>
- #include <linux/kernel.h>
- #include <linux/init.h>
- #include <linux/signal.h>
- #include <linux/sched.h>
- #include <linux/timer.h>
- #include <linux/interrupt.h>
- #include <asm/irq.h>
- #include <asm/arch/hardware.h>
- #include <asm/arch/irqs.h>
- #include <asm/io.h>
- #include "adc0809_ioctl.h"
- MODULE_LICENSE("GPL");
- #define ADC0809_MAJOR 231
- /*define the adc0809 major node is 231*/
- #define adc0809_sle (*(volatile unsigned long *)ADC_GPACON)
- #define adc0809_sle_data (*(volatile unsigned long *)ADC_GPADATA)
- unsigned long ADC_GPACON, ADC_GPADATA;
- static unsigned long ADC_0, ADC_1, ADC_2, ADC_3, ADC_4, ADC_5, ADC_6, ADC_7;
- unsigned long ADC_DATA;
- static unsigned int r_TCFG0,r_TCFG1,r_TCNTB1,r_TCMPB1,r_TCON,r_GPCCON;
- //unsigned long adc_write_addr;
- //unsigned long adc_read_addr;
- int * adc_read_addr,* adc_write_addr;
- devfs_handle_t devfs_adc;
- void adc0809_interrupt(int,void *,struct pt_regs *);
- int adc0809_open(struct inode *, struct file *);
- int adc0809_release(struct inode *, struct file *);
- //int adc0809_ioctl(struct inode *, struct file *, unsigned int, unsigned long);
- ssize_t adc0809_read(struct file *, char * , size_t , loff_t *);
- ssize_t adc0809_write(struct file *, const char *, size_t , loff_t *);
- static struct file_operations adc0809_fops = {
- // ioctl: adc0809_ioctl, //根据参数确定读取的引脚;
- open: adc0809_open, //选中片选NGCS2(初始化ADC0809的管脚配置),初始化adc_read_addr;
- read: adc0809_read,
- write: adc0809_write,
- release: adc0809_release,
- };
- //struct timer_list timer_ForData; // 定时器
- char data; //变量类型不同也会出错,之前使用unsigned long所得是一连串八位数字要么是-1
- unsigned long addr;
- int adc0809_sum=0;
- /*------------中断处理函数------------------*/
- void adc0809_interrupt(int irq,void *d,struct pt_regs *regs)
- {
- char adc0809_v=0,adc0809_u=0;
- /*clear interrupt register for INT_TIMER0*/
- SRCPND &= (~0x00000800); //bit11
- INTPND = INTPND;
- [b]/*---下面这一段使自己加的--------*/[/b]
- data = (*(volatile unsigned long *) adc_read_addr);
- if(data<200){adc0809_v=0;}
- else adc0809_v=1;
- if(adc0809_v<adc0809_u){adc0809_sum=adc0809_sum+1;}
- else adc0809_sum=adc0809_sum;
- adc0809_u=adc0809_v;
- printk("data:%d\n",data);
- printk("adc0809_u:%d\n",adc0809_u);
- printk("adc0809_v:%d\n",adc0809_v);
- printk("adc0809_sum:%d\n",adc0809_sum);
- }
- /*------- Open/close code for raw IO.-----*/
- int adc0809_open(struct inode *inode, struct file *filp)
- {
- adc_read_addr = ADC_DATA;
- adc_write_addr = ADC_1;
- (*(volatile unsigned char *) adc_write_addr) = (char) 0;
- printk("open ok\n");
- return 0;
- }
- /*------------read()----------------*/
- ssize_t adc0809_read(struct file *filp, char * buf,
- size_t size, loff_t *offp)
- {
- char key;
-
-
- key =adc0809_sum;
- printk("key_driver:%d\n",key);
- copy_to_user(buf,&key,1);//put_user(key,buf);
- //printk("adc0809_read:adc_read_addr=0x%x\n",adc_read_addr);
- return 1;
- }
- /*------------------write()-------------------------------*/
- ssize_t adc0809_write(struct file *filp, const char *buf,
- size_t size, loff_t *offp)
- {
- char key;
- if (get_user(key, buf))
- return -EFAULT;
- printk("adc0809_write:adc_write_addr=0x%x; key = %c\n",adc_write_addr,key);
- (*(volatile unsigned char *) adc_write_addr) = key;
- //put_user(key,buf);
- return 1;
- }
- /*----------------release()---------------------*/
- int adc0809_release(struct inode *inode, struct file *filp)
- {
- printk("release ok\n");
- return 0;
- }
- [b]/*---这里我吧ioctl函数给删除了 就是不使用它,而是在初始化函数中来选着引脚并赋值[/b]
- Deal with ioctls against the raw-device control interface, to bind
- and unbind other raw devices.
-
- int adc0809_ioctl(struct inode *inode, //octl选着待测的引脚 并触发中断
- struct file *flip, //就是给 是0809的寄存器 一旦这个引角得到一个触发信号
- unsigned int command, //那么相应的管脚就工作,然后才能输出ADC_DATA
- unsigned long arg)
- {
- int err = 0;
- switch (command) {
- case IOCTRL_ADC_0:
- adc_write_addr = ADC_0;
- //printk("adc0809_ioctl: adc addr: %x\n",adc_write_addr);
- /* start collect and convert
- (*(volatile unsigned char *) adc_write_addr) = (char) arg;
-
- return 0;
- case IOCTRL_ADC_1: //通道选择 因为ADC0809工作通道选择是由ADDC,ADDB,ADDA来实现的.
- adc_write_addr = ADC_1;
- (*(volatile unsigned char *) adc_write_addr) = (char) arg;
- return 0;
- default:
- err = -EINVAL;
- }
- // adc_read_addr = ADC_DATA;
- //adc_write_addr = ADC_2;
- //(*(volatile unsigned char *) adc_write_addr) = (char) arg;
-
- return err;
- }
- /*-------------------iormap()--地址影射函数---*/
- static int address_map(void)
- {
- r_TCFG0 = ioremap(0x51000000,4); //定时器配置寄存器0
- r_TCFG1 = ioremap(0x51000004,4); //定时器配置寄存器1
- r_TCNTB1 = ioremap(0x51000018,4);
- r_TCMPB1 = ioremap(0x5100001C,4);
- r_TCON = ioremap(0x51000008,4);
- r_GPCCON = ioremap(0x56000020,4);
- ADC_GPACON = (unsigned int)ioremap(0x56000000,4); //物理寄存器的影射,个人认为这里都是指CPLD的物理寄存器
- ADC_GPADATA = ioremap(0x56000004,4);
- ADC_0 = ioremap(0x10000010,4);
- ADC_1 = ioremap(0x10002010,4);
- ADC_2 = ioremap(0x10004010,4);
- ADC_3 = ioremap(0x10006010,4);
- ADC_4 = ioremap(0x10008010,4);
- ADC_5 = ioremap(0x1000a010,4);
- ADC_6 = ioremap(0x1000c010,4);
- ADC_7 = ioremap(0x1000e010,4);
- ADC_DATA = ioremap(0x10000020,4);
- return 0;
- }
- /*--------------------------------------------------------------------------*/
- int __init adc0809_init(void)
- {
- static int result;
- // unsigned long gpfup;
- //volatile unsigned int bankcon2;
- address_map();
- printk("*********************adc0809_init**************\n");
- adc_write_addr = ADC_0; [b] //ioctl函数的功能放到初始化函数中[/b]
- (*(volatile unsigned char *) adc_write_addr) = (char) arg;
-
- // bankcon2=(volatile unsigned int)ioremap(0x4800000c,4);
- // *(volatile unsigned int*)bankcon2 |= 3<<13; //
- /* select NGCS2 */
- adc0809_sle |= 0x2000;
- adc0809_sle_data &= (~0x2000);
- [b]/*-----------初始化S3C2410的时钟timer0-------------原驱动没有的后来添加的-------------*/[/b]
- (*(volatile unsigned int *)r_TCFG0) &= 0x11111100;//prescaler=0
- (*(volatile unsigned int *)r_TCFG1) &= (~0x000000F0);//MUX1=1/2
- // (*(volatile unsigned int *)r_TCFG1) &= (~0x000000D0);//MUX1=1/8 时间T=r_TCNTB1/625000(s)
- (*(volatile unsigned int *)r_TCNTB1) = 25000; //时间为10ms
- (*(volatile unsigned int *)r_TCMPB1) = 0x00000000;
- (*(volatile unsigned int *)r_TCON) |= 0x00000E00;
- (*(volatile unsigned int *)r_TCON) &= (~0x00000200);
- (*(volatile unsigned int *)r_TCON) |= 0x00000100;
- disable_irq(IRQ_TIMER1);
- enable_irq(IRQ_TIMER1);
- result=request_irq(IRQ_TIMER1,&adc0809_interrupt,SA_INTERRUPT,"adc0809",NULL);
- if (!result)
- {
- printk("Get assigned irq %d,result=%d\n",IRQ_TIMER1,result);
- // return result;
- }
- printk("***********Init ok!!***********\n");
-
-
- devfs_adc =
- devfs_register(NULL,"adc0809",DEVFS_FL_DEFAULT,
- ADC0809_MAJOR, 0,
- S_IFCHR | S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP,
- &adc0809_fops,NULL);
- return 0;
- }
- int __init adc0809_exit(void)
- {
- (*(volatile unsigned int *)r_TCON) &= (~0x00000100);
- disable_irq(IRQ_TIMER1);
- free_irq(IRQ_TIMER1, adc0809_interrupt);
- printk("exit ok\n");
- //free_irq(IRQ_EINT2, adc0809_interrupt);
- devfs_unregister(devfs_adc);
- return 0;
- }
- /*
- __initcall(adc0809_init);
- */
- module_init(adc0809_init);
- module_exit(adc0809_exit);
复制代码
[ 本帖最后由 ady2002 于 2008-11-18 11:34 编辑 ] |
|