added analog out insn for 1602 series
authorFrank Mori Hess <fmhess@speakeasy.net>
Thu, 9 Aug 2001 23:36:18 +0000 (23:36 +0000)
committerFrank Mori Hess <fmhess@speakeasy.net>
Thu, 9 Aug 2001 23:36:18 +0000 (23:36 +0000)
comedi/drivers/cb_pcidas.c

index f6d78c2f272a8d037360b348ce6cfd7248d43ab6..0990f28eb1bfabd86056d3e947304069b035d6b0 100644 (file)
@@ -43,9 +43,9 @@ TODO:
 
 add a calibration subdevice
 
-add analog out support for 1600 series
+finish analog out support for 1602 series
 
-fix pci detection to ignore unsupported boards from computerboards
+analog triggering on 1602 series
 */
 
 #include <linux/kernel.h>
@@ -137,6 +137,10 @@ fix pci detection to ignore unsupported boards from computerboards
 #define DAC_CSR        0x8     // dac control and status register
 #define   DACEN        0x2     // dac enable
 #define   DAC_RANGE(channel, range)    (((range) & 0x3) << (8 + 2 * channel) ) // dac range
+// bits for 1602 series only
+#define   DAC_EMPTY    0x1     // dac fifo empty, read, write clear
+#define   DAC_START    0x4     // start/arm dac fifo operations
+#define   DAC_CHAN_EN(x)               (1 << (5 + ((x) & 0x1)))        // enable channel 0 or 1
 
 // analog output registers for 100x, 1200 series
 #define DAC_DATA_REG(channel)  ((channel) & 0x1)
@@ -364,6 +368,7 @@ comedi_driver driver_cb_pcidas={
 
 static int cb_pcidas_ai_rinsn(comedi_device *dev,comedi_subdevice *s,comedi_insn *insn,lsampl_t *data);
 static int cb_pcidas_ao_nofifo_winsn(comedi_device *dev,comedi_subdevice *s,comedi_insn *insn,lsampl_t *data);
+static int cb_pcidas_ao_fifo_winsn(comedi_device *dev,comedi_subdevice *s,comedi_insn *insn,lsampl_t *data);
 static int cb_pcidas_ao_readback_insn(comedi_device *dev,comedi_subdevice *s,comedi_insn *insn,lsampl_t *data);
 static int cb_pcidas_ai_cmd(comedi_device *dev,comedi_subdevice *s);
 static int cb_pcidas_ai_cmdtest(comedi_device *dev,comedi_subdevice *s,
@@ -555,20 +560,20 @@ found:
        s = dev->subdevices + 1;
        if(thisboard->ao_nchan)
        {
+               s->type = COMEDI_SUBD_AO;
+               s->subdev_flags = SDF_READABLE | SDF_WRITEABLE | SDF_GROUND;
+               s->n_chan = thisboard->ao_nchan;
+               // ao_bits is the same as ai_bits
+               s->maxdata = (1 << thisboard->ai_bits) - 1;
+               s->range_table = &cb_pcidas_ao_ranges;
+               s->insn_read = cb_pcidas_ao_readback_insn;
                if(thisboard->has_ao_fifo)
                {
-                       // XXX todo: support fancy analog output
-                       s->type = COMEDI_SUBD_UNUSED;
+                       s->insn_write = cb_pcidas_ao_fifo_winsn;
+                       // XXX todo: support analog output cmd
                }else
                {
-                       s->type = COMEDI_SUBD_AO;
-                       s->subdev_flags = SDF_READABLE | SDF_WRITEABLE | SDF_GROUND;
-                       s->n_chan = thisboard->ao_nchan;
-                       // ao_bits is the same as ai_bits
-                       s->maxdata = (1 << thisboard->ai_bits) - 1;
-                       s->range_table = &cb_pcidas_ao_ranges;
                        s->insn_write = cb_pcidas_ao_nofifo_winsn;
-                       s->insn_read = cb_pcidas_ao_readback_insn;
                }
        }else
        {
@@ -699,6 +704,31 @@ static int cb_pcidas_ao_nofifo_winsn(comedi_device *dev, comedi_subdevice *s,
        return 1;
 }
 
+// analog output insn for pcidas-1602 series
+static int cb_pcidas_ao_fifo_winsn(comedi_device *dev, comedi_subdevice *s,
+       comedi_insn *insn, lsampl_t *data)
+{
+       int bits, channel;
+
+       // clear dac fifo
+       outw(0, devpriv->ao_registers + ADCFIFOCLR);
+
+       // set channel and range
+       channel = CR_CHAN(insn->chanspec);
+       bits = DACEN;
+       bits |= DAC_RANGE(channel, CR_RANGE(insn->chanspec));
+       bits |= DAC_CHAN_EN(channel);
+       bits |= DAC_START;      // not sure if this is necessary
+       outw(bits, devpriv->control_status + DAC_CSR);
+
+       // remember value for readback
+       devpriv->ao_value[channel] = data[0];
+       // send data
+       outw(data[0], devpriv->ao_registers + ADCDATA);
+
+       return 1;
+}
+
 // analog output readback insn
 static int cb_pcidas_ao_readback_insn(comedi_device *dev, comedi_subdevice *s,
        comedi_insn *insn, lsampl_t *data)