cb_pcidas: Applied patch from Brice DUBOST to support CR_EDGE and CR_INVERT
authorIan Abbott <abbotti@mev.co.uk>
Mon, 22 Nov 2010 10:23:56 +0000 (10:23 +0000)
committerIan Abbott <abbotti@mev.co.uk>
Mon, 22 Nov 2010 10:23:56 +0000 (10:23 +0000)
start_arg flags for AI commands on PCI_DAS1602 series.

comedi/drivers/cb_pcidas.c

index 534d726c75f67a6a1764b7e287263ed5df4b9949..39f48bb9d4f5fba2a7103c989c808163018f0bd2 100644 (file)
@@ -4,6 +4,7 @@
     Developed by Ivan Martinez and Frank Mori Hess, with valuable help from
     David Schleef and the rest of the Comedi developers comunity.
 
+    Copyright (C) 2010      Brice Dubost <braice@braice.net>
     Copyright (C) 2001-2003 Ivan Martinez <imr@oersted.dtu.dk>
     Copyright (C) 2001,2002 Frank Mori Hess <fmhess@users.sourceforge.net>
 
@@ -30,8 +31,9 @@
 Driver: cb_pcidas
 Description: MeasurementComputing PCI-DAS series with the AMCC S5933 PCI controller
 Author: Ivan Martinez <imr@oersted.dtu.dk>,
-  Frank Mori Hess <fmhess@users.sourceforge.net>
-Updated: 2003-3-11
+  Frank Mori Hess <fmhess@users.sourceforge.net>,
+  Brice Dubost <braice@braice.net>
+Updated: 2010-11-19
 Devices: [Measurement Computing] PCI-DAS1602/16 (cb_pcidas),
   PCI-DAS1602/16jr, PCI-DAS1602/12, PCI-DAS1200, PCI-DAS1200jr,
   PCI-DAS1000, PCI-DAS1001, PCI_DAS1002
@@ -53,6 +55,15 @@ Configuration options:
 For commands, the scanned channels must be consecutive
 (i.e. 4-5-6-7, 2-3-4,...), and must all have the same
 range and aref.
+
+AI Triggering:
+   For start_src == TRIG_EXT, the A/D EXTERNAL TRIGGER IN (pin 45) is used.
+   For 1602 series, the start_arg is interpreted as follows:
+     start_arg == 0                   => gated triger (level high)
+     start_arg == CR_INVERT           => gated triger (level low)
+     start_arg == CR_EDGE             => Rising edge
+     start_arg == CR_EDGE | CR_INVERT => Falling edge
+   For the other boards the trigger will be done on rising edge
 */
 /*
 
@@ -134,6 +145,8 @@ analog triggering on 1602 series
 #define   EXT_TRIGGER 0x2      // external start trigger
 #define   ANALOG_TRIGGER 0x3   // external analog trigger
 #define   TRIGGER_MASK 0x3     // mask of bits that determine start trigger
+#define   TGPOL        0x04            // invert the edge/level of the external trigger (1602 only)
+#define   TGSEL        0x08            //  if set edge triggered, otherwise level trigerred (1602 only)
 #define   TGEN 0x10            // enable external start trigger
 #define   BURSTE 0x20          // burst mode enable
 #define   XTRCL        0x80            // clear external trigger
@@ -255,6 +268,8 @@ typedef struct cb_pcidas_board_struct {
        const comedi_lrange *ranges;
        enum trimpot_model trimpot;
        unsigned has_dac08:1;
+       unsigned has_ai_trig_gated:1;   /* Tells if the AI trigger can be gated */
+       unsigned has_ai_trig_invert:1;  /* Tells if the AI trigger can be inverted */
 } cb_pcidas_board;
 
 static const cb_pcidas_board cb_pcidas_boards[] = {
@@ -272,6 +287,8 @@ static const cb_pcidas_board cb_pcidas_boards[] = {
              ranges:   &cb_pcidas_ranges,
              trimpot:  AD8402,
              has_dac08:1,
+             has_ai_trig_gated:1,
+             has_ai_trig_invert:1,
                },
        {
              name:     "pci-das1200",
@@ -286,6 +303,8 @@ static const cb_pcidas_board cb_pcidas_boards[] = {
              ranges:   &cb_pcidas_ranges,
              trimpot:  AD7376,
              has_dac08:0,
+             has_ai_trig_gated:0,
+             has_ai_trig_invert:0,
                },
        {
              name:     "pci-das1602/12",
@@ -301,6 +320,8 @@ static const cb_pcidas_board cb_pcidas_boards[] = {
              ranges:   &cb_pcidas_ranges,
              trimpot:  AD7376,
              has_dac08:0,
+             has_ai_trig_gated:1,
+             has_ai_trig_invert:1,
                },
        {
              name:     "pci-das1200/jr",
@@ -315,6 +336,8 @@ static const cb_pcidas_board cb_pcidas_boards[] = {
              ranges:   &cb_pcidas_ranges,
              trimpot:  AD7376,
              has_dac08:0,
+             has_ai_trig_gated:0,
+             has_ai_trig_invert:0,
                },
        {
              name:     "pci-das1602/16/jr",
@@ -329,6 +352,8 @@ static const cb_pcidas_board cb_pcidas_boards[] = {
              ranges:   &cb_pcidas_ranges,
              trimpot:  AD8402,
              has_dac08:1,
+             has_ai_trig_gated:1,
+             has_ai_trig_invert:1,
                },
        {
              name:     "pci-das1000",
@@ -343,6 +368,8 @@ static const cb_pcidas_board cb_pcidas_boards[] = {
              ranges:   &cb_pcidas_ranges,
              trimpot:  AD7376,
              has_dac08:0,
+             has_ai_trig_gated:0,
+             has_ai_trig_invert:0,
                },
        {
              name:     "pci-das1001",
@@ -357,6 +384,8 @@ static const cb_pcidas_board cb_pcidas_boards[] = {
              ranges:   &cb_pcidas_alt_ranges,
              trimpot:  AD7376,
              has_dac08:0,
+             has_ai_trig_gated:0,
+             has_ai_trig_invert:0,
                },
        {
              name:     "pci-das1002",
@@ -371,6 +400,8 @@ static const cb_pcidas_board cb_pcidas_boards[] = {
              ranges:   &cb_pcidas_ranges,
              trimpot:  AD7376,
              has_dac08:0,
+             has_ai_trig_gated:0,
+             has_ai_trig_invert:0,
                },
 };
 
@@ -1080,9 +1111,26 @@ static int cb_pcidas_ai_cmdtest(comedi_device * dev, comedi_subdevice * s,
 
        /* step 3: make sure arguments are trivially compatible */
 
-       if (cmd->start_arg != 0) {
-               cmd->start_arg = 0;
-               err++;
+       switch (cmd->start_src) {
+       case TRIG_EXT:
+               /* External trigger, only CR_EDGE and CR_INVERT flags allowed */
+               if ((cmd->start_arg
+                    & (CR_FLAGS_MASK & ~(CR_EDGE | CR_INVERT))) != 0) {
+                       cmd->start_arg &= ~(CR_FLAGS_MASK & ~(CR_EDGE | CR_INVERT));
+                       err++;
+               }
+               if(!thisboard->has_ai_trig_invert && 
+                  (cmd->start_arg & CR_INVERT)) {
+                       cmd->start_arg &= (CR_FLAGS_MASK & ~CR_INVERT);
+                       err++;
+               }
+               break;
+       default:
+               if (cmd->start_arg != 0) {
+                       cmd->start_arg = 0;
+                       err++;
+               }
+               break;
        }
 
        if (cmd->scan_begin_src == TRIG_TIMER) {
@@ -1233,9 +1281,13 @@ static int cb_pcidas_ai_cmd(comedi_device * dev, comedi_subdevice * s)
        bits = 0;
        if (cmd->start_src == TRIG_NOW)
                bits |= SW_TRIGGER;
-       else if (cmd->start_src == TRIG_EXT)
+       else if (cmd->start_src == TRIG_EXT) {
                bits |= EXT_TRIGGER | TGEN | XTRCL;
-       else {
+               if(thisboard->has_ai_trig_invert && (cmd->start_arg & CR_INVERT))
+                       bits |= TGPOL;
+               if(thisboard->has_ai_trig_gated && (cmd->start_arg & CR_EDGE))
+                       bits |= TGSEL;
+       } else {
                comedi_error(dev, "bug!");
                return -1;
        }