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

📄 adv_pci_dio.c

📁 rtlinux-3.2-pre3.tar.bz2 rtlinux3.2-pre3的源代码
💻 C
📖 第 1 页 / 共 3 页
字号:
#define devpriv ((pci_dio_private *)dev->private)#define this_board ((boardtype *)dev->board_ptr)/*==============================================================================*/static int pci_dio_insn_bits_di_b(comedi_device *dev, comedi_subdevice *s, 	comedi_insn *insn, lsampl_t *data){	diosubd_data *d=(diosubd_data *)s->private;	int i;		data[1]=0;	for (i=0; i<d->regs;i++) {		data[1]|=inb(dev->iobase+d->addr+i)<<(8*i);	}	return 2;}/*==============================================================================*/static int pci_dio_insn_bits_di_w(comedi_device *dev, comedi_subdevice *s, 	comedi_insn *insn, lsampl_t *data){	diosubd_data *d=(diosubd_data *)s->private;	int i;		data[1]=0;	for (i=0; i<d->regs; i++)		data[1]|=inw(dev->iobase+d->addr+2*i)<<(16*i);	return 2;}/*==============================================================================*/static int pci_dio_insn_bits_do_b(comedi_device *dev, comedi_subdevice *s, 	comedi_insn *insn, lsampl_t *data){	diosubd_data *d=(diosubd_data *)s->private;	int i;	if (data[0]) {		s->state &= ~data[0];		s->state |= (data[0]&data[1]);		for (i=0; i<d->regs; i++)			outb((s->state>>(8*i))&0xff, dev->iobase+d->addr+i);	}	data[1] = s->state;	return 2;}/*==============================================================================*/static int pci_dio_insn_bits_do_w(comedi_device *dev, comedi_subdevice *s, 	comedi_insn *insn,lsampl_t *data){	diosubd_data *d=(diosubd_data *)s->private;	int i;	if (data[0]) {		s->state &= ~data[0];		s->state |= (data[0]&data[1]);		for (i=0; i<d->regs; i++)		    outw((s->state>>(16*i))&0xffff, dev->iobase+d->addr+2*i);	}	data[1] = s->state;	return 2;}/*==============================================================================*/static int pci1760_mbxrequest(comedi_device *dev, comedi_subdevice *s,	unsigned char *omb, unsigned char *imb, 	int repeats){	int cnt, tout, ok=0;		for (cnt=0; cnt<repeats; cnt++) {		outb(omb[0], dev->iobase+OMB0);		outb(omb[1], dev->iobase+OMB1);		outb(omb[2], dev->iobase+OMB2);		outb(omb[3], dev->iobase+OMB3);		for(tout=0; tout<251; tout++) {			if ((imb[2]=inb(dev->iobase+IMB2))==omb[2]) {				imb[0]=inb(dev->iobase+IMB0);				imb[1]=inb(dev->iobase+IMB1);				imb[3]=inb(dev->iobase+IMB3);				ok=1;				break;			}			comedi_udelay(1);		}		if (ok) return 0;	}		comedi_error(dev, "PCI-1760 mailbox request timeout!");	return -ETIME;}/*==============================================================================*/static int pci1760_insn_bits_di(comedi_device *dev, comedi_subdevice *s, 	comedi_insn *insn, lsampl_t *data){	int ret;	unsigned char omb[4]={		0x00, 		0x00, 		CMD_ClearIMB2, 		0x00};	unsigned char imb[4];		if (!(ret=pci1760_mbxrequest(dev, s, omb, imb, OMBCMD_RETRY)))		return ret;	data[1]=imb[3];	return 2;}/*==============================================================================*/static int pci1760_insn_read_di(comedi_device *dev, comedi_subdevice *s, 	comedi_insn *insn, lsampl_t *data){	int ret, n;	unsigned char omb[4]={		0x00, 		0x00, 		CMD_ClearIMB2, 		0x00};	unsigned char imb[4];		for (n=0; n<insn->n; n++) {		if (!(ret=pci1760_mbxrequest(dev, s, omb, imb, OMBCMD_RETRY)))			return ret;		data[n] = imb[3];	}	return n;}/*==============================================================================*/static int pci1760_insn_bits_do(comedi_device *dev, comedi_subdevice *s, 	comedi_insn *insn, lsampl_t *data){	int ret;	unsigned char omb[4]={		0x00, 		0x00, 		CMD_SetRelaysOutput, 		0x00};	unsigned char imb[4];	if (data[0]) {		s->state &= ~data[0];		s->state |= (data[0]&data[1]);		omb[0] = s->state;		if (!(ret=pci1760_mbxrequest(dev, s, omb, imb, OMBCMD_RETRY)))			return ret;	}	data[1] = s->state;	return 2;}/*==============================================================================*/static int pci1760_insn_cnt_read(comedi_device *dev, comedi_subdevice *s, 	comedi_insn *insn, lsampl_t *data){	int ret, n;	unsigned char omb[4]={		CR_CHAN(insn->chanspec)&0x07, 		0x00, 		CMD_GetIDICntCurValue, 		0x00};	unsigned char imb[4];	for (n=0; n<insn->n; n++) {		if (!(ret=pci1760_mbxrequest(dev, s, omb, imb, OMBCMD_RETRY)))			return ret;		data[n] = (imb[1]<<8) + imb[0];	}	return n;}/*==============================================================================*/static int pci1760_insn_cnt_write(comedi_device *dev, comedi_subdevice *s, 	comedi_insn *insn, lsampl_t *data){	int ret;	unsigned char chan=CR_CHAN(insn->chanspec)&0x07;	unsigned char bitmask=1<<chan;	unsigned char omb[4]={		data[0]&0xff, 		(data[0]>>8)&0xff, 		CMD_SetIDI0CntResetValue+chan, 		0x00};	unsigned char imb[4];	if (devpriv->CntResValue[chan] != (data[0]&0xffff)) { // Set reset value if different		if (!(ret=pci1760_mbxrequest(dev, s, omb, imb, OMBCMD_RETRY)))			return ret;		devpriv->CntResValue[chan] = data[0]&0xffff;	}	omb[0] = bitmask;	// reset counter to it reset value	omb[2] = CMD_ResetIDICounters;	if (!(ret=pci1760_mbxrequest(dev, s, omb, imb, OMBCMD_RETRY)))		return ret;	if (!(bitmask & devpriv->IDICntEnable)) {	// start counter if it don't run		omb[0] = bitmask;		omb[2] = CMD_EnableIDICounters;		if (!(ret=pci1760_mbxrequest(dev, s, omb, imb, OMBCMD_RETRY)))			return ret;		devpriv->IDICntEnable |= bitmask;	}	return 1;}/*==============================================================================*/static int pci1760_reset(comedi_device *dev){	int i;	unsigned char omb[4]={0x00, 0x00, 0x00, 0x00 };	unsigned char imb[4];	outb(0, dev->iobase+INTCSR0);	// disable IRQ	outb(0, dev->iobase+INTCSR1);	outb(0, dev->iobase+INTCSR2);	outb(0, dev->iobase+INTCSR3);	devpriv->GlobalIrqEnabled = 0;	omb[0] = 0x00;	omb[2] = CMD_SetRelaysOutput;	// reset relay outputs	pci1760_mbxrequest(dev, NULL, omb, imb, OMBCMD_RETRY);		omb[0] = 0x00;	omb[2] = CMD_EnableIDICounters;	// disable IDI up counters	pci1760_mbxrequest(dev, NULL, omb, imb, OMBCMD_RETRY);	devpriv->IDICntEnable = 0;	omb[0] = 0x00;	omb[2] = CMD_OverflowIDICounters;	// disable counters overflow interrupts	pci1760_mbxrequest(dev, NULL, omb, imb, OMBCMD_RETRY);	devpriv->IDICntOverEnable = 0;	omb[0] = 0x00;	omb[2] = CMD_MatchIntIDICounters;	// disable counters match value interrupts	pci1760_mbxrequest(dev, NULL, omb, imb, OMBCMD_RETRY);	devpriv->IDICntMatchEnable = 0;	omb[0] = 0x00;	omb[1] = 0x80;	for (i=0; i<8; i++) {	// set IDI up counters match value		omb[2] = CMD_SetIDI0CntMatchValue+i;		pci1760_mbxrequest(dev, NULL, omb, imb, OMBCMD_RETRY);		devpriv->CntMatchValue[i] = 0x8000;	}	omb[0] = 0x00;	omb[1] = 0x00;	for (i=0; i<8; i++) {	// set IDI up counters reset value		omb[2] = CMD_SetIDI0CntResetValue+i;		pci1760_mbxrequest(dev, NULL, omb, imb, OMBCMD_RETRY);		devpriv->CntResValue[i] = 0x0000;	}		omb[0] = 0xff;	omb[2] = CMD_ResetIDICounters;	// reset IDI up counters to reset values	pci1760_mbxrequest(dev, NULL, omb, imb, OMBCMD_RETRY);	omb[0] = 0x00;	omb[2] = CMD_EdgeIDICounters;	// set IDI up counters count edge	pci1760_mbxrequest(dev, NULL, omb, imb, OMBCMD_RETRY);	devpriv->IDICntEdge = 0x00;	omb[0] = 0x00;	omb[2] = CMD_EnableIDIFilters;	// disable all digital in filters	pci1760_mbxrequest(dev, NULL, omb, imb, OMBCMD_RETRY);	devpriv->IDIFiltersEn = 0x00;	omb[0] = 0x00;	omb[2] = CMD_EnableIDIPatternMatch;	// disable pattern matching	pci1760_mbxrequest(dev, NULL, omb, imb, OMBCMD_RETRY);	devpriv->IDIPatMatchEn = 0x00;	omb[0] = 0x00;	omb[2] = CMD_SetIDIPatternMatch;	// set pattern match value	pci1760_mbxrequest(dev, NULL, omb, imb, OMBCMD_RETRY);	devpriv->IDIPatMatchValue = 0x00;	return 0;}/* ==============================================================================*/static int pci_dio_reset(comedi_device *dev){	DPRINTK("adv_pci_dio EDBG: BGN: pci171x_reset(...)\n");		switch (this_board->cardtype) {	case TYPE_PCI1730:		outb(0, dev->iobase+PCI1730_DO);	// clear outputs		outb(0, dev->iobase+PCI1730_DO+1);		outb(0, dev->iobase+PCI1730_IDO);		outb(0, dev->iobase+PCI1730_IDO+1);		/* NO break there! */	case TYPE_PCI1733:		outb(0, dev->iobase+PCI1730_3_INT_EN);	// disable interrupts		outb(0x0f, dev->iobase+PCI1730_3_INT_CLR);// clear interrupts		outb(0, dev->iobase+PCI1730_3_INT_RF);	// set rising edge trigger		break;	case TYPE_PCI1734:		outb(0, dev->iobase+PCI1734_IDO);	// clear outputs		outb(0, dev->iobase+PCI1734_IDO+1);		outb(0, dev->iobase+PCI1734_IDO+2);		outb(0, dev->iobase+PCI1734_IDO+3);		break;	case TYPE_PCI1750:	case TYPE_PCI1751:		outb(0x88, dev->iobase+PCI1750_ICR);	// disable & clear interrupts		break;	case TYPE_PCI1752:		outw(0, dev->iobase+PCI1752_6_CFC);	// disable channel freeze function		outw(0, dev->iobase+PCI1752_IDO);	// clear outputs

⌨️ 快捷键说明

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