From 072879e9bd3e22a1c34eb73d640954d6bee43f88 Mon Sep 17 00:00:00 2001 From: Frank Mori Hess Date: Wed, 29 Dec 2004 01:07:18 +0000 Subject: [PATCH] Fixed bugs reported by csp@andrew.cmu.edu. The bug report was as follows: I have been attempting to get a NI-ATAO10, a 10 channel legacy ISA analog output board, working with comedi. Apparantely the way comedi_from_phys works to convert voltage to sample doesn't seem to work correctly with the ATAO10 board. I found that the correct sample data for the ATAO10 board is as follows: In unipolar mode 0V = 2048 +10V = 6143 In bipolar mode -10V = 2048 +10V = 6143 It seems that comedi_from_phys is somehow shifted by 2048 from what it should be (comedi_from_phys gives values from 0 to 4095). Furthermore, comedi does not detect the polarity of the board (I'm not sure if this is possible on this board); thus the range is always reported as -10V to +10V even if the board is set on unipolar mode (which is achieved by setting jumpers on the board). Finally, for some reason, channel 0 does not work with Comedi (the board fully works in Windows). The other 9 channels work. --- comedi/drivers/ni_at_ao.c | 41 +++++++++++++++++++++++++++++---------- 1 file changed, 31 insertions(+), 10 deletions(-) diff --git a/comedi/drivers/ni_at_ao.c b/comedi/drivers/ni_at_ao.c index c8656f4e..546013ea 100644 --- a/comedi/drivers/ni_at_ao.c +++ b/comedi/drivers/ni_at_ao.c @@ -24,11 +24,15 @@ Driver: ni_at_ao.o Description: National Instruments AT-AO-6/10 Devices: [National Instruments] AT-AO-6 (at-ao-6), AT-AO-10 (at-ao-10) -Status: untested +Status: should work Author: ds -Updated: Fri, 7 Jun 2002 13:20:30 -0700 +Updated: Sun Dec 26 12:26:28 EST 2004 -This driver has not been tested, but should work. +Configuration options: + [0] - I/O port base address + [1] - IRQ (unused) + [2] - DMA (unused) + [3] - analog output range, set by jumpers on hardware (0 for -10 to 10V bipolar, 1 for 0V to 10V unipolar) */ /* @@ -204,10 +208,12 @@ static int atao_attach(comedi_device *dev,comedi_devconfig *it) { comedi_subdevice *s; unsigned long iobase; - + int ao_unipolar; + iobase = it->options[0]; if(iobase==0)iobase = 0x1c0; - + ao_unipolar = it->options[3]; + printk("comedi%d: ni_at_ao: 0x%04lx",dev->minor,iobase); if(check_region(iobase, ATAO_SIZE) < 0){ @@ -233,7 +239,10 @@ static int atao_attach(comedi_device *dev,comedi_devconfig *it) s->subdev_flags=SDF_WRITABLE; s->n_chan=thisboard->n_ao_chans; s->maxdata=(1<<12)-1; - s->range_table=&range_bipolar10; + if(ao_unipolar) + s->range_table=&range_unipolar10; + else + s->range_table=&range_bipolar10; s->insn_write = &atao_ao_winsn; s->insn_read = &atao_ao_rinsn; @@ -299,14 +308,14 @@ static void atao_reset(comedi_device *dev) inw(dev->iobase + ATAO_FIFO_CLEAR); - devpriv->cfg1 = GRP2WR; + devpriv->cfg1 |= GRP2WR; outw(devpriv->cfg1, dev->iobase + ATAO_CFG1); outw(0, dev->iobase + ATAO_2_INT1CLR); outw(0, dev->iobase + ATAO_2_INT2CLR); outw(0, dev->iobase + ATAO_2_DMATCCLR); - devpriv->cfg1 = 0; + devpriv->cfg1 &= ~GRP2WR; outw(devpriv->cfg1, dev->iobase + ATAO_CFG1); } @@ -315,9 +324,21 @@ static int atao_ao_winsn(comedi_device *dev,comedi_subdevice *s,comedi_insn *ins { int i; int chan = CR_CHAN(insn->chanspec); - + short bits; + for(i=0;in;i++){ - outw(data[i], dev->iobase + ATAO_DACn(chan)); + bits = data[i] - 0x800; + if(chan == 0) + { + devpriv->cfg1 |= GRP2WR; + outw(devpriv->cfg1, dev->iobase + ATAO_CFG1); + } + outw(bits, dev->iobase + ATAO_DACn(chan)); + if(chan == 0) + { + devpriv->cfg1 &= ~GRP2WR; + outw(devpriv->cfg1, dev->iobase + ATAO_CFG1); + } devpriv->ao_readback[chan] = data[i]; } -- 2.26.2