added some dependency file generation
[comedilib.git] / lib / filler.c
index dde1e0e095b6838ad43793339483c8014b1616e0..fd304f1ba6ce6cbeec5731e3c88ff668bb316b33 100644 (file)
@@ -1,24 +1,24 @@
 /*
     lib/filler.c
-    comedi library routines
+    functions to retrieve kernel data
 
-    COMEDI - Linux Control and Measurement Device Interface
-    Copyright (C) 1997-8 David A. Schleef <ds@stm.lbl.gov>
+    COMEDILIB - Linux Control and Measurement Device Interface Library
+    Copyright (C) 1997-2001 David A. Schleef <ds@schleef.org>
 
-    This program is free software; you can redistribute it and/or modify
-    it under the terms of the GNU General Public License as published by
-    the Free Software Foundation; either version 2 of the License, or
-    (at your option) any later version.
+    This library is free software; you can redistribute it and/or
+    modify it under the terms of the GNU Lesser General Public
+    License as published by the Free Software Foundation, version 2.1
+    of the License.
 
-    This program is distributed in the hope that it will be useful,
+    This library is distributed in the hope that it will be useful,
     but WITHOUT ANY WARRANTY; without even the implied warranty of
-    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-    GNU General Public License for more details.
-
-    You should have received a copy of the GNU General Public License
-    along with this program; if not, write to the Free Software
-    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+    Lesser General Public License for more details.
 
+    You should have received a copy of the GNU Lesser General Public
+    License along with this library; if not, write to the Free Software
+    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307
+    USA.
 */
 
 #include <stdio.h>
 #include <comedi.h>
 #include <string.h>
 
-#include <libinternal.h>
+#include "libinternal.h"
 
 
 /* these functions download information from the comedi module. */
 
+static int do_test_for_cmd(comedi_t *dev,unsigned int subdevice);
+static int do_test_for_insn(comedi_t *dev);
+static int do_test_for_insnlist(comedi_t *dev);
+static int do_test_for_insn_bits(comedi_t *dev,unsigned int subdevice);
 
 
 int get_subdevices(comedi_t *it)
@@ -45,10 +49,13 @@ int get_subdevices(comedi_t *it)
        int i,j;
        int ret;
        comedi_subdinfo *s;
+       comedi_chaninfo ci;
        subdevice *r;
 
        s=malloc(sizeof(comedi_subdinfo)*it->n_subdevices);
-       ret=ioctl_subdinfo(it->fd,s);
+       debug_ptr(s);
+
+       ret = comedi_ioctl(it->fd, COMEDI_SUBDINFO, (unsigned long)s);
        debug_int(ret);
 
        r=it->subdevices=realloc(it->subdevices,
@@ -56,6 +63,8 @@ int get_subdevices(comedi_t *it)
        debug_ptr(r);
        memset(r,0,sizeof(subdevice)*it->n_subdevices);
 
+       it->has_insnlist_ioctl = do_test_for_insnlist(it);
+       it->has_insn_ioctl = do_test_for_insn(it);
        for(i=0;i<it->n_subdevices;i++){
                r[i].type       = s[i].type;
                if(r[i].type==COMEDI_SUBD_UNUSED)continue;
@@ -79,7 +88,11 @@ int get_subdevices(comedi_t *it)
                        r[i].range_type_list=malloc(sizeof(*r[i].range_type_list)*r[i].n_chan);
                        debug_ptr(r[i].range_type_list);
                }
-               ret=ioctl_chaninfo(it->fd,i,r[i].maxdata_list,r[i].flags_list,r[i].range_type_list);
+               ci.subdev = i;
+               ci.flaglist = r[i].flags_list;
+               ci.rangelist = r[i].range_type_list;
+               ci.maxdata_list = r[i].maxdata_list;
+               ret = comedi_ioctl(it->fd, COMEDI_CHANINFO, (unsigned long)&ci);
                debug_int(ret);
 
                if(r[i].subd_flags&SDF_RANGETYPE){
@@ -91,6 +104,13 @@ int get_subdevices(comedi_t *it)
                }else{
                        r[i].rangeinfo=get_rangeinfo(it->fd,r[i].range_type);
                }
+
+               r[i].has_cmd = do_test_for_cmd(it,i);
+               if(it->has_insnlist_ioctl){
+                       r[i].has_insn_bits = do_test_for_insn_bits(it,i);
+               }else{
+                       r[i].has_insn_bits = 0;
+               }
        }
 
        free(s);
@@ -102,17 +122,24 @@ comedi_range *get_rangeinfo(int fd,unsigned int range_type)
 {
        comedi_krange *kr;
        comedi_range *r;
+       comedi_rangeinfo ri;
+       int ret;
        int i;
 
        kr=malloc(sizeof(comedi_krange)*RANGE_LENGTH(range_type));
        r=malloc(sizeof(comedi_range)*RANGE_LENGTH(range_type));
 
-       ioctl_rangeinfo(fd,range_type,kr);
+       ri.range_type = range_type;
+       ri.range_ptr = kr;
+       ret = comedi_ioctl(fd, COMEDI_RANGEINFO, (unsigned long)&ri);
+       if(ret<0){
+               fprintf(stderr,"ioctl(%d,COMEDI_RANGEINFO,0x%08x,%p)\n",fd,range_type,kr);
+       }
 
        for(i=0;i<RANGE_LENGTH(range_type);i++){
                r[i].min=kr[i].min*1e-6;
                r[i].max=kr[i].max*1e-6;
-               r[i].unit=RF_UNIT(kr[i].flags);
+               r[i].unit=kr[i].flags;
        }
        free(kr);
 
@@ -120,3 +147,130 @@ comedi_range *get_rangeinfo(int fd,unsigned int range_type)
 }
 
 
+/* some command testing */
+
+static int do_test_for_cmd(comedi_t *dev,unsigned int subdevice)
+{
+       /* SDF_CMD was added in 0.7.57 */
+       if(dev->devinfo.version_code >= COMEDI_VERSION_CODE(0,7,57)){
+               if(dev->subdevices[subdevice].subd_flags & SDF_CMD)
+                       return 1;
+               return 0;
+       }else{
+               comedi_cmd it;
+               int ret;
+
+               memset(&it,0,sizeof(it));
+
+               it.subdev = subdevice;
+               it.start_src = TRIG_ANY;
+               it.scan_begin_src = TRIG_ANY;
+               it.convert_src = TRIG_ANY;
+               it.scan_end_src = TRIG_ANY;
+               it.stop_src = TRIG_ANY;
+
+               ret = comedi_ioctl(dev->fd, COMEDI_CMDTEST, (unsigned long)&it);
+
+               if(ret<0 && errno==EIO){
+                       return 0;
+               }
+               if(ret<0){
+                       fprintf(stderr,"BUG in do_test_for_cmd()\n");
+                       return 0;
+               }
+               return 1;
+       }
+}
+
+static int do_test_for_insnlist(comedi_t *dev)
+{
+       comedi_insn insn;
+       comedi_insnlist il;
+       lsampl_t data[2];
+       int ret;
+
+       memset(&insn,0,sizeof(insn));
+
+       il.n_insns = 1;
+       il.insns = &insn;
+
+       insn.insn = INSN_GTOD;
+       insn.n = 2;
+       insn.data = data;
+
+       ret = comedi_ioctl(dev->fd, COMEDI_INSNLIST, (unsigned long)&il);
+
+       if(ret<0){
+               if(errno!=EIO){
+                       fprintf(stderr,"BUG in do_test_for_insn()\n");
+               }
+               return 0;
+       }
+       return 1;
+}
+
+/* the COMEID_INSN ioctl was introduced in comedi-0.7.60 */
+static int do_test_for_insn(comedi_t *dev)
+{
+       comedi_insn insn;
+       comedi_insnlist il;
+       lsampl_t data[2];
+       int ret;
+
+       memset(&insn,0,sizeof(insn));
+
+       il.n_insns = 1;
+       il.insns = &insn;
+
+       insn.insn = INSN_GTOD;
+       insn.n = 2;
+       insn.data = data;
+
+       ret = comedi_ioctl(dev->fd, COMEDI_INSN, (unsigned long)&insn);
+
+       if(ret<0){
+               if(errno!=EIO){
+                       fprintf(stderr,"BUG in do_test_for_insn()\n");
+               }
+               return 0;
+       }
+       return 1;
+}
+
+static int do_test_for_insn_bits(comedi_t *dev,unsigned int subdevice)
+{
+       comedi_insn insn;
+       comedi_insnlist il;
+       lsampl_t data[2];
+       int ret;
+
+       if(dev->subdevices[subdevice].maxdata != 1)
+               return 0;
+
+       memset(&insn,0,sizeof(insn));
+
+       il.n_insns = 1;
+       il.insns = &insn;
+
+       insn.insn = INSN_BITS;
+       insn.n = 2;
+       insn.data = data;
+       insn.subdev = subdevice;
+
+       data[0]=0;
+       data[1]=0;
+
+       ret = comedi_do_insnlist(dev,&il);
+
+       if(ret<0 && (errno==EINVAL || errno==EIO)){
+               return 0;
+       }
+       if(ret<0){
+               perror("BUG in do_test_for_insn_bits()\n");
+               return 0;
+       }
+       return 1;
+}
+
+
+