⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 das6402.c

📁 rtlinux-3.2-pre3.tar.bz2 rtlinux3.2-pre3的源代码
💻 C
字号:
/*   Some comments on the code..   - it shouldn't be necessary to use outb_p().   - ignoreirq creates a race condition.  It needs to be fixed. *//*   An experimental driver for Computerboards' DAS6402 I/O card   Copyright (C) 1999 Oystein Svendsen <svendsen@pvv.org>   This program is free software; you can redistribute it and/or modify   it under the terms of the GNU General Public License as published by   the Free Software Foundation; either version 2 of the License, or   (at your option) any later version.   This program is distributed in the hope that it will be useful,   but WITHOUT ANY WARRANTY; without even the implied warranty of   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the   GNU General Public License for more details.   You should have received a copy of the GNU General Public License   along with this program; if not, write to the Free Software   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. *//*Driver: das6402.oDescription: Keithley Metrabyte DAS6402 (& compatibles)Author: Oystein Svendsen <svendsen@pvv.org>Status: bitrottenDevices: [Keithley Metrabyte] DAS6402 (das6402)This driver has suffered bitrot.*/#include <linux/comedidev.h>#include <linux/ioport.h>#define DAS6402_SIZE 16#define N_WORDS 3000*64#define STOP    0#define START   1#define SCANL 0x3f00#define BYTE unsigned char#define WORD unsigned short/*----- register 8 ----*/#define CLRINT 0x01#define CLRXTR 0x02#define CLRXIN 0x04#define EXTEND 0x10#define ARMED 0x20   /* enable conting of post sample conv */#define POSTMODE 0x40#define MHZ 0x80    /* 10 MHz clock *//*---------------------*//*----- register 9 ----*/#define IRQ (0x04 << 4)   /* these two are                         */#define IRQV 10           /*               dependent on each other */#define CONVSRC 0x03  /* trig src is Intarnal pacer */#define BURSTEN 0x04  /* enable burst */#define XINTE 0x08     /* use external int. trig */#define INTE 0x80      /* enable analog interrupts *//*---------------------*//*----- register 10 ---*/#define TGEN 0x01   /* Use pin DI1 for externl trigging? */#define TGSEL 0x02  /* Use edge triggering */#define TGPOL 0x04  /* active edge is falling */#define PRETRIG 0x08 /* pretrig *//*---------------------*//*----- register 11 ---*/#define EOB 0x0c#define FIFOHFULL 0x08#define GAIN 0x01#define FIFONEPTY 0x04#define MODE 0x10#define SEM 0x20#define BIP 0x40/*---------------------*/#define M0 0x00#define M2 0x04#define	C0 0x00#define	C1 0x40#define	C2 0x80#define	RWLH 0x30 static int das6402_attach(comedi_device *dev,comedi_devconfig *it);static int das6402_detach(comedi_device *dev);static comedi_driver driver_das6402={	driver_name:	"das6402",	module:		THIS_MODULE,	attach:		das6402_attach,	detach:		das6402_detach,};COMEDI_INITCLEANUP(driver_das6402);typedef struct{	int ai_bytes_to_read;	int das6402_ignoreirq;}das6402_private;#define devpriv ((das6402_private *)dev->private)static void das6402_ai_fifo_dregs(comedi_device *dev,comedi_subdevice *s);static void das6402_setcounter(comedi_device *dev){	BYTE p;	unsigned short ctrlwrd;	/* set up counter0 first, mode 0 */    	p=M0|C0|RWLH;	outb_p(p,dev->iobase+15);	ctrlwrd=2000;	p=(BYTE) (0xff & ctrlwrd);	outb_p(p,dev->iobase+12);	p=(BYTE) (0xff & (ctrlwrd >> 8));	outb_p(p,dev->iobase+12);	/* set up counter1, mode 2 */	p=M2|C1|RWLH;	outb_p(p,dev->iobase+15);	ctrlwrd=10;	p=(BYTE) (0xff & ctrlwrd);	outb_p(p,dev->iobase+13);	p=(BYTE) (0xff & (ctrlwrd >> 8));	outb_p(p,dev->iobase+13);	/* set up counter1, mode 2 */	p=M2|C2|RWLH;	outb_p(p,dev->iobase+15);	ctrlwrd=1000;	p=(BYTE) (0xff & ctrlwrd);	outb_p(p,dev->iobase+14);	p=(BYTE) (0xff & (ctrlwrd >> 8));	outb_p(p,dev->iobase+14);}static void intr_handler(int irq,void *d,struct pt_regs *regs){	comedi_device *dev=d;	comedi_subdevice *s=dev->subdevices;	if (devpriv->das6402_ignoreirq){		printk("das6402: BUG: spurious interrupt\n");		return;	}#ifdef DEBUG	printk("das6402: interrupt! das6402_irqcount=%i\n",devpriv->das6402_irqcount);	printk("das6402: iobase+2=%i\n",inw_p(dev->iobase+2));#endif	das6402_ai_fifo_dregs(dev,s);	if(s->async->buf_write_count >= devpriv->ai_bytes_to_read){		outw_p(SCANL,dev->iobase+2);  /* clears the fifo */		outb(0x07,dev->iobase+8);  /* clears all flip-flops */#ifdef DEBUG		printk("das6402: Got %i samples\n\n",devpriv->das6402_wordsread-diff);#endif		s->async->events |= COMEDI_CB_EOA;		comedi_event(dev,s,s->async->events);	}	outb(0x01,dev->iobase+8);   /* clear only the interrupt flip-flop */	comedi_event(dev,s,s->async->events);}#if 0static void das6402_ai_fifo_read(comedi_device *dev,sampl_t *data,int n){	int i;	for(i=0;i<n;i++)data[i]=inw(dev->iobase);}#endifstatic void das6402_ai_fifo_dregs(comedi_device *dev,comedi_subdevice *s){	while(1){		if(!(inb(dev->iobase+8)&0x01))			return;		comedi_buf_put( s->async, inw(dev->iobase) );	}}static int das6402_ai_cancel(comedi_device *dev,comedi_subdevice *s){	/*	 *  This function should reset the board from whatever condition it	 *  is in (i.e., acquiring data), to a non-active state.	 */	devpriv->das6402_ignoreirq=1;#ifdef DEBUG	printk("das6402: Stopping acquisition\n");#endif	devpriv->das6402_ignoreirq=1;	outb_p(0x02,dev->iobase+10);  /* disable external trigging */	outw_p(SCANL,dev->iobase+2);  /* resets the card fifo */	outb_p(0,dev->iobase+9); /* disables interrupts */	outw_p(SCANL,dev->iobase+2);		return 0;}#ifdef unusedstatic int das6402_ai_mode2(comedi_device *dev,comedi_subdevice *s,comedi_trig *it){	devpriv->das6402_ignoreirq=1;#ifdef DEBUG	printk("das6402: Starting acquisition\n");#endif	outb_p(0x03,dev->iobase+10);  /* enable external trigging */	outw_p(SCANL,dev->iobase+2);  /* resets the card fifo */	outb_p(IRQ|CONVSRC|BURSTEN|INTE,dev->iobase+9);	devpriv->ai_bytes_to_read=it->n*sizeof(sampl_t);	/* um... ignoreirq is a nasty race condition */	devpriv->das6402_ignoreirq=0;	outw_p(SCANL,dev->iobase+2);		return 0;}#endifstatic int board_init(comedi_device *dev){	BYTE b;	devpriv->das6402_ignoreirq=1;	outb(0x07,dev->iobase+8);		/* register 11  */	outb_p(MODE,dev->iobase+11);	b=BIP|SEM|MODE|GAIN|FIFOHFULL;	outb_p(b, dev->iobase+11);		/* register 8   */	outb_p(EXTEND,dev->iobase+8);	b=EXTEND|MHZ;	outb_p(b,dev->iobase+8);	b=       MHZ|CLRINT|CLRXTR|CLRXIN;	outb_p(b,dev->iobase+8);	/* register 9    */	b=IRQ|CONVSRC|BURSTEN|INTE;	outb_p(b,dev->iobase+9);	/* register 10   */	b=TGSEL|TGEN; 	outb_p(b,dev->iobase+10);	b=0x07;	outb_p(b,dev->iobase+8);	das6402_setcounter(dev);	outw_p(SCANL,dev->iobase+2);  /* reset card fifo */	devpriv->das6402_ignoreirq=0;        return 0;}static int das6402_detach(comedi_device *dev){        if(dev->irq)comedi_free_irq(dev->irq,dev);	if(dev->iobase)release_region(dev->iobase,DAS6402_SIZE);	return 0;}static int das6402_attach(comedi_device *dev,comedi_devconfig *it){	int irq;	int iobase;	int ret;	comedi_subdevice *s;	dev->board_name="das6402";	iobase=it->options[0];	if(iobase==0)iobase=0x300;	printk("comedi%d: das6402: 0x%04x",dev->minor,iobase);	if(check_region(iobase,DAS6402_SIZE)<0){		printk(" I/O port conflict\n");		return -EIO;	}	request_region(iobase,DAS6402_SIZE,"das6402");	dev->iobase=iobase;	/* should do a probe here */	irq=it->options[0];	printk(" ( irq = %d )", irq);	ret=comedi_request_irq(irq, intr_handler, 0, "das6402", dev);	if(ret<0){		printk("irq conflict\n");		return ret;	}	dev->irq=irq;	if((ret=alloc_private(dev,sizeof(das6402_private)))<0)		return ret;	if((ret=alloc_subdevices(dev, 1))<0)		return ret;	/* ai subdevice */	s=dev->subdevices+0;	s->type=COMEDI_SUBD_AI;	s->subdev_flags=SDF_READABLE|SDF_GROUND;	s->n_chan=8;	//s->trig[2]=das6402_ai_mode2;	s->cancel=das6402_ai_cancel;	s->maxdata=(1<<12)-1;	s->len_chanlist=16;	/* ? */	s->range_table = &range_unknown;	board_init(dev);	return 0;}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -