📄 ii_pci20kc.c
字号:
s->range_table_list = sdp->pci20006.ao_range_list; return 0;}static int pci20006_insn_read(comedi_device * dev, comedi_subdevice * s, comedi_insn *insn, lsampl_t *data){ pci20xxx_subdev_private *sdp = s->private; data[0] = sdp->pci20006.last_data[CR_CHAN(insn->chanspec)]; return 1;}static int pci20006_insn_write(comedi_device * dev, comedi_subdevice * s, comedi_insn *insn, lsampl_t *data){ pci20xxx_subdev_private *sdp = s->private; int hi, lo; unsigned int boarddata; sdp->pci20006.last_data[CR_CHAN(insn->chanspec)] = data[0]; boarddata = (((unsigned int)data[0]+0x8000) & 0xffff); /* comedi-data -> board-data */ lo = (boarddata & 0xff); hi = ((boarddata >> 8) & 0xff); switch ( CR_CHAN(insn->chanspec)) { case 0: writeb(lo, sdp->iobase + PCI20006_LCHAN0); writeb(hi, sdp->iobase + PCI20006_LCHAN0 + 1); writeb(0x00, sdp->iobase + PCI20006_STROBE0); break; case 1: writeb(lo, sdp->iobase + PCI20006_LCHAN1); writeb(hi, sdp->iobase + PCI20006_LCHAN1 + 1); writeb(0x00, sdp->iobase + PCI20006_STROBE1); break; default: printk(" comedi%d: pci20xxx: ao channel Error!\n", dev->minor); return -EINVAL; } return 1;}/* PCI20341M */static int pci20341_insn_read(comedi_device * dev, comedi_subdevice * s, comedi_insn *insn, lsampl_t *data);static int pci20341_timebase[] = { 0x00, 0x00, 0x00, 0x04 };static int pci20341_settling_time[] = { 0x58, 0x58, 0x93, 0x99 };static comedi_lrange range_bipolar0_5 = { 1, { BIP_RANGE(0.5) }};static comedi_lrange range_bipolar0_05 = { 1, { BIP_RANGE(0.05) }};static comedi_lrange range_bipolar0_025 = { 1, { BIP_RANGE(0.025) }};static comedi_lrange *pci20341_ranges[] = { &range_bipolar5, &range_bipolar0_5, &range_bipolar0_05, &range_bipolar0_025, };static int pci20341_init(comedi_device * dev,comedi_subdevice *s, int opt0,int opt1){ pci20xxx_subdev_private *sdp = s->private; int option; /* options handling */ if(opt0<0 || opt0>3)opt0=0; sdp->pci20341.timebase = pci20341_timebase[opt0]; sdp->pci20341.settling_time = pci20341_settling_time[opt0]; /* ai subdevice */ s->type = COMEDI_SUBD_AI; s->subdev_flags = SDF_READABLE; s->n_chan = PCI20341_CHAN_NR; s->len_chanlist = PCI20341_SCANLIST; s->insn_read = pci20341_insn_read; s->maxdata = 0xffff; s->range_table = pci20341_ranges[opt0]; option = sdp->pci20341.timebase | PCI20341_REPMODE; /* depends on gain, trigger, repetition mode */ writeb(PCI20341_INIT, sdp->iobase + PCI20341_CONFIG_REG); /* initialize Module */ writeb(PCI20341_PACER, sdp->iobase + PCI20341_MOD_STATUS); /* set Pacer */ writeb(option, sdp->iobase + PCI20341_OPT_REG); /* option register */ writeb(sdp->pci20341.settling_time, sdp->iobase + PCI20341_SET_TIME_REG); /* settling time counter */ /* trigger not implemented */ return 0;}static int pci20341_insn_read(comedi_device * dev, comedi_subdevice * s, comedi_insn *insn, lsampl_t *data){ pci20xxx_subdev_private *sdp = s->private; unsigned int i = 0, j = 0; int lo, hi; unsigned char eoc; /* end of conversion */ unsigned int clb; /* channel list byte */ unsigned int boarddata; writeb(1, sdp->iobase + PCI20341_LCHAN_ADDR_REG); /* write number of input channels */ clb = PCI20341_DAISY_CHAIN | PCI20341_MUX | (sdp->pci20341.ai_gain << 3) | CR_CHAN(insn->chanspec); writeb(clb, sdp->iobase + PCI20341_CHAN_LIST); writeb(0x00, sdp->iobase + PCI20341_CC_RESET); /* reset settling time counter and trigger delay counter */ writeb(0x00, sdp->iobase + PCI20341_CHAN_RESET); /* generate Pacer */ for (i=0; i < insn->n; i++) { /* data polling isn't the niciest way to get the data, I know, * but there are only 6 cycles (mean) and it is easier than * the whole interrupt stuff */ j=0; readb(sdp->iobase + PCI20341_SOFT_PACER); /* generate Pacer */ eoc = readb(sdp->iobase + PCI20341_STATUS_REG); while ((eoc < 0x80) && j < 100) { /* poll Interrupt Flag */ j++; eoc = readb(sdp->iobase + PCI20341_STATUS_REG); } if (j >= 100) { printk("comedi%d: pci20xxx: AI interrupt channel %i polling exit !\n", dev->minor, i); return -EINVAL; } lo = readb(sdp->iobase + PCI20341_LDATA); hi = readb(sdp->iobase + PCI20341_LDATA + 1); boarddata = lo + 0x100 * hi; data[i] = (sampl_t)((boarddata + 0x8000) & 0xffff); /* board-data -> comedi-data */ } return i;}/* native DIO */static void pci20xxx_dio_config(comedi_device * dev,comedi_subdevice *s);static int pci20xxx_dio_insn_bits(comedi_device *dev,comedi_subdevice *s, comedi_insn *insn, lsampl_t *data);static int pci20xxx_dio_insn_config(comedi_device *dev,comedi_subdevice *s, comedi_insn *insn, lsampl_t *data);/* initialize pci20xxx_private */static int pci20xxx_dio_init(comedi_device * dev,comedi_subdevice *s){ s->type = COMEDI_SUBD_DIO; s->subdev_flags = SDF_READABLE | SDF_WRITABLE; s->n_chan = 32; s->insn_bits = pci20xxx_dio_insn_bits; s->insn_config = pci20xxx_dio_insn_config; s->maxdata = 1; s->len_chanlist = 32; s->range_table = &range_digital; s->io_bits = 0; /* digital I/O lines default to input on board reset. */ pci20xxx_dio_config(dev,s); return 0;}static int pci20xxx_dio_insn_config(comedi_device *dev,comedi_subdevice *s, comedi_insn *insn, lsampl_t *data){ int mask,bits; mask = 1<<CR_CHAN(insn->chanspec); if(mask&0x000000ff){ bits = 0x000000ff; }else if(mask & 0x0000ff00){ bits = 0x0000ff00; }else if(mask & 0x00ff0000){ bits = 0x00ff0000; }else { bits = 0xff000000; } if(data[0]){ s->io_bits |= bits; }else{ s->io_bits &= ~bits; } pci20xxx_dio_config(dev,s); return 1;}static int pci20xxx_dio_insn_bits(comedi_device *dev,comedi_subdevice *s, comedi_insn *insn, lsampl_t *data){ unsigned int mask = data[0]; s->state &= ~mask; s->state |= (mask&data[1]); mask &= s->io_bits; if(mask&0x000000ff) writeb((s->state>>0)&0xff, dev->iobase + PCI20000_DIO_0 ); if(mask&0x0000ff00) writeb((s->state>>8)&0xff, dev->iobase + PCI20000_DIO_1 ); if(mask&0x00ff0000) writeb((s->state>>16)&0xff, dev->iobase + PCI20000_DIO_2 ); if(mask&0xff000000) writeb((s->state>>24)&0xff, dev->iobase + PCI20000_DIO_3 ); data[1] = readb(dev->iobase + PCI20000_DIO_0 ); data[1] |= readb(dev->iobase + PCI20000_DIO_1 )<<8; data[1] |= readb(dev->iobase + PCI20000_DIO_2 )<<16; data[1] |= readb(dev->iobase + PCI20000_DIO_3 )<<24; return 2;}static void pci20xxx_dio_config(comedi_device * dev,comedi_subdevice *s){ unsigned char control_01; unsigned char control_23; unsigned char buffer; control_01 = readb(dev->iobase + PCI20000_DIO_CONTROL_01); control_23 = readb(dev->iobase + PCI20000_DIO_CONTROL_23); buffer = readb(dev->iobase + PCI20000_DIO_BUFFER); if(s->io_bits & 0x000000ff ){ /* output port 0 */ control_01 &= PCI20000_DIO_EOC; buffer = (buffer &(~(DIO_BE<<DIO_PS_0)))|(DIO_BO<<DIO_PS_0); }else{ /* input port 0 */ control_01 = (control_01 & DIO_CAND) | PCI20000_DIO_EIC; buffer = (buffer &(~(DIO_BI<<DIO_PS_0))); } if(s->io_bits & 0x0000ff00 ){ /* output port 1 */ control_01 &= PCI20000_DIO_OOC; buffer = (buffer &(~(DIO_BE<<DIO_PS_1)))|(DIO_BO<<DIO_PS_1); }else{ /* input port 1 */ control_01 = (control_01 & DIO_CAND) | PCI20000_DIO_OIC; buffer = (buffer &(~(DIO_BI<<DIO_PS_1))); } if(s->io_bits & 0x00ff0000 ){ /* output port 2 */ control_23 &= PCI20000_DIO_EOC; buffer = (buffer &(~(DIO_BE<<DIO_PS_2)))|(DIO_BO<<DIO_PS_2); }else{ /* input port 2 */ control_23 = (control_23 & DIO_CAND) | PCI20000_DIO_EIC; buffer = (buffer &(~(DIO_BI<<DIO_PS_2))); } if(s->io_bits & 0xff000000 ){ /* output port 3 */ control_23 &= PCI20000_DIO_OOC; buffer = (buffer &(~(DIO_BE<<DIO_PS_3)))|(DIO_BO<<DIO_PS_3); }else{ /* input port 3 */ control_23 = (control_23 & DIO_CAND) | PCI20000_DIO_OIC; buffer = (buffer &(~(DIO_BI<<DIO_PS_3))); } writeb(control_01, dev->iobase + PCI20000_DIO_CONTROL_01); writeb(control_23, dev->iobase + PCI20000_DIO_CONTROL_23); writeb(buffer, dev->iobase + PCI20000_DIO_BUFFER); }#if 0static void pci20xxx_do(comedi_device * dev, comedi_subdevice * s){ /* XXX if the channel is configured for input, does this do bad things? */ /* XXX it would be a good idea to only update the registers that _need_ to be updated. This requires changes to comedi, however. */ writeb((s->state>>0)&0xff, dev->iobase + PCI20000_DIO_0 ); writeb((s->state>>8)&0xff, dev->iobase + PCI20000_DIO_1 ); writeb((s->state>>16)&0xff, dev->iobase + PCI20000_DIO_2 ); writeb((s->state>>24)&0xff, dev->iobase + PCI20000_DIO_3 );}static unsigned int pci20xxx_di(comedi_device * dev, comedi_subdevice * s){ /* XXX same note as above */ unsigned int bits; bits = readb(dev->iobase + PCI20000_DIO_0 ); bits |= readb(dev->iobase + PCI20000_DIO_1 )<<8; bits |= readb(dev->iobase + PCI20000_DIO_2 )<<16; bits |= readb(dev->iobase + PCI20000_DIO_3 )<<24; return bits;}#endifCOMEDI_INITCLEANUP(driver_pci20xxx);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -