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

📄 adv_pci1710.c

📁 rtlinux-3.2-pre3.tar.bz2 rtlinux3.2-pre3的源代码
💻 C
📖 第 1 页 / 共 3 页
字号:
/* * comedi/drivers/adv_pci1710.c * * Author: Michal Dobes <dobes@tesnet.cz> * * Thanks to ZhenGang Shang <ZhenGang.Shang@Advantech.com.cn> * for testing and informations. * *  hardware driver for Advantech cards: *   card:   PCI-1710, PCI-1710HG, PCI-1711, PCI-1713, PCI-1720, PCI-1731 *   driver: pci1710,  pci1710hg,  pci1711,  pci1713,  pci1720,  pci1731 * * Options: *  [0] - PCI bus number - if bus number and slot number are 0,  *                         then driver search for first unused card *  [1] - PCI slot number  * *//*Driver: adv_pci1710.oDescription: Advantech PCI-1710, PCI-1710HG, PCI-1711, PCI-1713,             Advantech PCI-1720, PCI-1731Author: Michal Dobes <dobes@tesnet.cz>Devices: [Advantech] PCI-1710 (pci1710), PCI-1710HG (pci1710hg),  PCI-1711 (pci1711), PCI-1713 (pci1713), PCI-1720 (pci1720),  PCI-1731 (pci1731)Status: worksThis driver supports AI, AO, DI and DO subdevices.AI subdevice supports cmd and insn interface,other subdevices support only insn interface.The PCI-1710 and PCI-1710HG have the same PCI device ID, so thedriver cannot distinguish between them, as would be normal for aPCI driver.Configuration options:  [0] - PCI bus of device (optional)  [1] - PCI slot of device (optional)          If bus/slot is not specified, the first available PCI          device will be used.*/#include <linux/comedidev.h>#include <linux/pci.h>#include "8253.h"#include "amcc_s5933.h"#define PCI171x_PARANOIDCHECK		/* if defined, then is used code which control correct channel number on every 12 bit sample */#undef PCI171X_EXTDEBUG#undef DPRINTK#ifdef PCI171X_EXTDEBUG#define DPRINTK(fmt, args...) rt_printk(fmt, ## args)#else#define DPRINTK(fmt, args...)#endif// hardware types of the cards#define TYPE_PCI171X	0#define TYPE_PCI1713	2#define TYPE_PCI1720	3#define IORANGE_171x 	32		#define IORANGE_1720 	16		#define PCI171x_AD_DATA	 0		/* R:   A/D data */#define PCI171x_SOFTTRG	 0		/* W:   soft trigger for A/D */#define PCI171x_RANGE	 2		/* W:   A/D gain/range register */#define PCI171x_MUX	 4		/* W:   A/D multiplexor control */#define PCI171x_STATUS	 6		/* R:   status register */#define PCI171x_CONTROL	 6		/* W:   control register */#define PCI171x_CLRINT	 8		/* W:   clear interrupts request */#define PCI171x_CLRFIFO	 9		/* W:   clear FIFO */#define PCI171x_DA1	10		/* W:   D/A register */#define PCI171x_DA2	12		/* W:   D/A register */#define PCI171x_DAREF	14		/* W:   D/A reference control */#define PCI171x_DI	16		/* R:   digi inputs */#define PCI171x_DO	16		/* R:   digi inputs */#define PCI171x_CNT0	24		/* R/W: 8254 couter 0 */#define PCI171x_CNT1	26		/* R/W: 8254 couter 1 */#define PCI171x_CNT2	28		/* R/W: 8254 couter 2 */#define PCI171x_CNTCTRL	30		/* W:   8254 counter control */// upper bits from status register (PCI171x_STATUS) (lower is same woth control reg)#define	Status_FE	0x0100		/* 1=FIFO is empty */#define Status_FH	0x0200		/* 1=FIFO is half full */#define Status_FF	0x0400		/* 1=FIFO is full, fatal error */#define Status_IRQ	0x0800		/* 1=IRQ occured */// bits from control register (PCI171x_CONTROL)#define Control_CNT0	0x0040		/* 1=CNT0 have external source, 0=have internal 100kHz source */#define Control_ONEFH	0x0020		/* 1=IRQ on FIFO is half full, 0=every sample */#define Control_IRQEN	0x0010		/* 1=enable IRQ */#define Control_GATE	0x0008		/* 1=enable external trigger GATE (8254?) */#define Control_EXT	0x0004		/* 1=external trigger source */#define Control_PACER	0x0002		/* 1=enable internal 8254 trigger source */#define Control_SW	0x0001		/* 1=enable software trigger source */#define PCI1720_DA0	 0		/* W:   D/A register 0 */#define PCI1720_DA1	 2		/* W:   D/A register 1 */#define PCI1720_DA2	 4		/* W:   D/A register 2 */#define PCI1720_DA3	 6		/* W:   D/A register 3 */#define PCI1720_RANGE	 8		/* R/W: D/A range register */#define PCI1720_SYNCOUT	 9		/* W:   D/A synchronized output register */#define PCI1720_SYNCONT	15		/* R/W: D/A synchronized control */// D/A synchronized control (PCI1720_SYNCONT)#define Syncont_SC0	 1		/* set synchronous output mode */static comedi_lrange range_pci1710_3={ 9, {	BIP_RANGE(5),	BIP_RANGE(2.5),	BIP_RANGE(1.25),	BIP_RANGE(0.625),	BIP_RANGE(10),	UNI_RANGE(10),	UNI_RANGE(5),	UNI_RANGE(2.5),	UNI_RANGE(1.25)	}};static char range_codes_pci1710_3[]={0x00, 0x01, 0x02, 0x03, 0x04, 0x10, 0x11, 0x12, 0x13 };static comedi_lrange range_pci1710hg={ 12, {	BIP_RANGE(5),	BIP_RANGE(0.5),	BIP_RANGE(0.05),	BIP_RANGE(0.005),	BIP_RANGE(10),	BIP_RANGE(1),	BIP_RANGE(0.1),	BIP_RANGE(0.01),	UNI_RANGE(10),	UNI_RANGE(1),	UNI_RANGE(0.1),	UNI_RANGE(0.01)	}};static char range_codes_pci1710hg[]={0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x10, 0x11, 0x12, 0x13 };static comedi_lrange range_pci17x1={ 5, {	BIP_RANGE(10),	BIP_RANGE(5),	BIP_RANGE(2.5),	BIP_RANGE(1.25),	BIP_RANGE(0.625)	}};static char range_codes_pci17x1[]={0x00, 0x01, 0x02, 0x03, 0x04 };static comedi_lrange range_pci1720={ 4, {	UNI_RANGE(5),	UNI_RANGE(10),	BIP_RANGE(5),	BIP_RANGE(10)	}};static comedi_lrange range_pci171x_da={ 2, {	UNI_RANGE(5),	UNI_RANGE(10),	}};static int pci1710_attach(comedi_device *dev,comedi_devconfig *it);static int pci1710_detach(comedi_device *dev);static unsigned short	pci_list_builded=0;	/*=1 list of card is know */typedef struct {	char 		*name;		// driver name	int		device_id;	int		iorange;	// I/O range len	char		have_irq;	// 1=card support IRQ	char		cardtype;	// 0=1710& co. 2=1713, ...	int 		n_aichan;	// num of A/D chans	int 		n_aichand;	// num of A/D chans in diff mode	int 		n_aochan;	// num of D/A chans	int 		n_dichan;	// num of DI chans	int 		n_dochan;	// num of DO chans	int		ai_maxdata;	// resolution of A/D	int		ao_maxdata;	// resolution of D/A	comedi_lrange	*rangelist_ai;	// rangelist for A/D	char		*rangecode_ai;	// range codes for programming	comedi_lrange	*rangelist_ao;	// rangelist for D/A	unsigned int	ai_ns_min;	// max sample speed of card v ns	unsigned int	fifo_half_size;	// size of FIFO/2} boardtype;static struct pci_device_id pci1710_pci_table[] = __devinitdata {	{ PCI_VENDOR_ID_ADVANTECH, 0x1710, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },	{ PCI_VENDOR_ID_ADVANTECH, 0x1711, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },	{ PCI_VENDOR_ID_ADVANTECH, 0x1713, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },	{ PCI_VENDOR_ID_ADVANTECH, 0x1720, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },	{ PCI_VENDOR_ID_ADVANTECH, 0x1731, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },	{ 0 }};MODULE_DEVICE_TABLE(pci, pci1710_pci_table);static boardtype boardtypes[] ={	{"pci1710", 0x1710,	 IORANGE_171x, 1, TYPE_PCI171X,	 16, 8, 2, 16, 16,  0x0fff, 0x0fff,	 &range_pci1710_3, range_codes_pci1710_3, &range_pci171x_da,	 10000, 2048 },	{"pci1710hg", 0x1710,	 IORANGE_171x, 1, TYPE_PCI171X,	 16, 8, 2, 16, 16,  0x0fff, 0x0fff,	 &range_pci1710hg, range_codes_pci1710hg, &range_pci171x_da,	 10000, 2048 },	{"pci1711", 0x1711,	 IORANGE_171x, 1, TYPE_PCI171X,	 16, 0, 2, 16, 16,  0x0fff, 0x0fff,	 &range_pci17x1, range_codes_pci17x1, &range_pci171x_da,	 10000, 512 },	{"pci1713", 0x1713,	 IORANGE_171x, 1, TYPE_PCI1713,	 32,16, 0,  0,  0,  0x0fff, 0x0000,	 &range_pci17x1, range_codes_pci1710_3, NULL,	 10000, 2048 },	{"pci1720", 0x1720,	 IORANGE_1720, 0, TYPE_PCI1720,	 0, 0, 4, 0, 0,  0x0000, 0x0fff,	 NULL, NULL, &range_pci1720,	 0, 0 },	{"pci1731", 0x1731,	 IORANGE_171x, 1, TYPE_PCI171X,	 16, 0, 0, 16, 16,  0x0fff, 0x0000,	 &range_pci17x1, range_codes_pci17x1, NULL,	 10000, 512 },};#define n_boardtypes (sizeof(boardtypes)/sizeof(boardtype))static comedi_driver driver_pci1710={	driver_name:	"adv_pci1710",	module:		THIS_MODULE,	attach:		pci1710_attach,	detach:		pci1710_detach,	num_names:	n_boardtypes,	board_name:	boardtypes,	offset:		sizeof(boardtype),};typedef struct{	char			valid;		// card is usable	char			neverending_ai;	// we do unlimited AI	unsigned int		CntrlReg;	// Control register	unsigned int		i8254_osc_base;	// frequence of onboard oscilator	unsigned int		ai_do;		// what do AI? 0=nothing, 1 to 4 mode	unsigned int		ai_act_scan;// how many scans we finished	unsigned int		ai_act_chan;// actual position in actual scan	unsigned int 		ai_buf_ptr;	// data buffer ptr in samples	unsigned char		ai_eos;		// 1=EOS wake up	unsigned char		ai_et;	unsigned int		ai_et_CntrlReg;	unsigned int		ai_et_MuxVal;	unsigned int		ai_et_div1, ai_et_div2;	unsigned int		act_chanlist[32];// list of scaned channel	unsigned char		act_chanlist_len;// len of scanlist	unsigned char 		act_chanlist_pos;// actual position in MUX list	unsigned char		da_ranges;	// copy of D/A outpit range register	unsigned int		ai_scans;	// len of scanlist	unsigned int		ai_n_chan;	// how many channels is measured		unsigned int		*ai_chanlist;	// actaul chanlist	unsigned int		ai_flags;	// flaglist	unsigned int		ai_data_len;	// len of data buffer	sampl_t			*ai_data;	// data buffer	unsigned int		ai_timer1;	// timers	unsigned int		ai_timer2;	sampl_t			ao_data[4];	// data output buffer} pci1710_private;#define devpriv ((pci1710_private *)dev->private)#define this_board ((boardtype *)dev->board_ptr)/* ==============================================================================*/static int check_channel_list(comedi_device * dev, comedi_subdevice * s, unsigned int *chanlist, unsigned int n_chan);static void setup_channel_list(comedi_device * dev, comedi_subdevice * s, unsigned int *chanlist,	unsigned int n_chan, unsigned int seglen);static void start_pacer(comedi_device * dev, int mode, unsigned int divisor1, unsigned int divisor2);static int pci1710_reset(comedi_device *dev);static int pci171x_ai_cancel(comedi_device * dev, comedi_subdevice * s);static unsigned int muxonechan[] ={ 0x0000, 0x0101, 0x0202, 0x0303, 0x0404, 0x0505, 0x0606, 0x0707, // used for gain list programming                                    0x0808, 0x0909, 0x0a0a, 0x0b0b, 0x0c0c, 0x0d0d, 0x0e0e, 0x0f0f,                                    0x1010, 0x1111, 0x1212, 0x1313, 0x1414, 0x1515, 0x1616, 0x1717,                                    0x1818, 0x1919, 0x1a1a, 0x1b1b, 0x1c1c, 0x1d1d, 0x1e1e, 0x1f1f};/* ==============================================================================*/static int pci171x_insn_read_ai(comedi_device * dev, comedi_subdevice * s, comedi_insn *insn, lsampl_t *data) {	int n,timeout;#ifdef PCI171x_PARANOIDCHECK	unsigned int idata;#endif	DPRINTK("adv_pci1710 EDBG: BGN: pci171x_insn_read_ai(...)\n");	devpriv->CntrlReg&=Control_CNT0;	devpriv->CntrlReg|=Control_SW;  // set software trigger	outw(devpriv->CntrlReg, dev->iobase+PCI171x_CONTROL);	outb(0,dev->iobase + PCI171x_CLRFIFO);	outb(0,dev->iobase + PCI171x_CLRINT);		setup_channel_list(dev,s,&insn->chanspec, 1, 1);	DPRINTK("adv_pci1710 A ST=%4x IO=%x\n",inw(dev->iobase+PCI171x_STATUS), dev->iobase+PCI171x_STATUS);	for (n=0; n<insn->n; n++) {		outw(0, dev->iobase+PCI171x_SOFTTRG); /* start conversion */    		DPRINTK("adv_pci1710 B n=%d ST=%4x\n",n,inw(dev->iobase+PCI171x_STATUS));		//comedi_udelay(1);    		DPRINTK("adv_pci1710 C n=%d ST=%4x\n",n,inw(dev->iobase+PCI171x_STATUS));    		timeout=100;    		while (timeout--) {			if (!(inw(dev->iobase+PCI171x_STATUS) & Status_FE)) goto conv_finish;			if (!(timeout%10))				DPRINTK("adv_pci1710 D n=%d tm=%d ST=%4x\n",n,timeout,inw(dev->iobase+PCI171x_STATUS));    		}    		comedi_error(dev,"A/D insn timeout");		outb(0,dev->iobase + PCI171x_CLRFIFO);		outb(0,dev->iobase + PCI171x_CLRINT);    		data[n]=0;		DPRINTK("adv_pci1710 EDBG: END: pci171x_insn_read_ai(...) n=%d\n",n);    		return -ETIME;conv_finish:#ifdef PCI171x_PARANOIDCHECK		idata=inw(dev->iobase+PCI171x_AD_DATA);		if (this_board->cardtype!=TYPE_PCI1713)			if ((idata & 0xf000)!=devpriv->act_chanlist[0]) {				comedi_error(dev,"A/D insn data droput!");				return -ETIME;			}		data[n] = idata & 0x0fff; #else		data[n] = inw(dev->iobase+PCI171x_AD_DATA) & 0x0fff; #endif	}		outb(0,dev->iobase + PCI171x_CLRFIFO);	outb(0,dev->iobase + PCI171x_CLRINT);	DPRINTK("adv_pci1710 EDBG: END: pci171x_insn_read_ai(...) n=%d\n",n);	return n;}/* ==============================================================================*/static int pci171x_insn_write_ao(comedi_device * dev, comedi_subdevice * s, comedi_insn *insn, lsampl_t *data) {	int n,chan,range,ofs;	chan=CR_CHAN(insn->chanspec);	range=CR_RANGE(insn->chanspec);	if (chan) { 		devpriv->da_ranges&=0xfb;		devpriv->da_ranges|=(range<<2);		outw(devpriv->da_ranges, dev->iobase+PCI171x_DAREF);		ofs=PCI171x_DA2;	} else {		devpriv->da_ranges&=0xfe;		devpriv->da_ranges|=range;		outw(devpriv->da_ranges, dev->iobase+PCI171x_DAREF);		ofs=PCI171x_DA1;	}	for (n=0; n<insn->n; n++) 		outw(data[n], dev->iobase + ofs);	devpriv->ao_data[chan]=data[n];	return n;}/* ==============================================================================*/static int pci171x_insn_read_ao(comedi_device * dev, comedi_subdevice * s, comedi_insn *insn, lsampl_t *data) {	int n,chan;		chan=CR_CHAN(insn->chanspec);	for (n=0; n<insn->n; n++) 		data[n]=devpriv->ao_data[chan];	return n;}/*==============================================================================*/static int pci171x_insn_bits_di(comedi_device *dev,comedi_subdevice *s, comedi_insn *insn,lsampl_t *data){	data[1] = inw(dev->iobase + PCI171x_DI);	return 2;}/*==============================================================================*/static int pci171x_insn_bits_do(comedi_device *dev,comedi_subdevice *s, comedi_insn *insn,lsampl_t *data){	if(data[0]){		s->state &= ~data[0];		s->state |= (data[0]&data[1]);		outw(s->state, dev->iobase + PCI171x_DO);	}	data[1] = s->state;	return 2;}/* ==============================================================================*/static int pci1720_insn_write_ao(comedi_device * dev, comedi_subdevice * s, comedi_insn *insn, lsampl_t *data) {

⌨️ 快捷键说明

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