~ubuntu-branches/ubuntu/feisty/comedilib/feisty

« back to all changes in this revision

Viewing changes to lib/filler.c

  • Committer: Bazaar Package Importer
  • Author(s): David Schleef
  • Date: 2003-09-23 18:11:12 UTC
  • Revision ID: james.westby@ubuntu.com-20030923181112-sat05jyh702rb1at
Tags: upstream-0.7.21
ImportĀ upstreamĀ versionĀ 0.7.21

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
    lib/filler.c
 
3
    functions to retrieve kernel data
 
4
 
 
5
    COMEDILIB - Linux Control and Measurement Device Interface Library
 
6
    Copyright (C) 1997-2001 David A. Schleef <ds@schleef.org>
 
7
 
 
8
    This library is free software; you can redistribute it and/or
 
9
    modify it under the terms of the GNU Lesser General Public
 
10
    License as published by the Free Software Foundation, version 2.1
 
11
    of the License.
 
12
 
 
13
    This library is distributed in the hope that it will be useful,
 
14
    but WITHOUT ANY WARRANTY; without even the implied warranty of
 
15
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 
16
    Lesser General Public License for more details.
 
17
 
 
18
    You should have received a copy of the GNU Lesser General Public
 
19
    License along with this library; if not, write to the Free Software
 
20
    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307
 
21
    USA.
 
22
*/
 
23
 
 
24
#include <stdio.h>
 
25
#include <math.h>
 
26
#include <stdlib.h>
 
27
#include <sys/types.h>
 
28
#include <sys/stat.h>
 
29
#include <fcntl.h>
 
30
#include <unistd.h>
 
31
#include <sys/ioctl.h>
 
32
#include <errno.h>
 
33
#include <string.h>
 
34
 
 
35
#include "libinternal.h"
 
36
 
 
37
 
 
38
/* these functions download information from the comedi module. */
 
39
 
 
40
static int do_test_for_cmd(comedi_t *dev,unsigned int subdevice);
 
41
static int do_test_for_insn(comedi_t *dev);
 
42
static int do_test_for_insnlist(comedi_t *dev);
 
43
static int do_test_for_insn_bits(comedi_t *dev,unsigned int subdevice);
 
44
 
 
45
 
 
46
int get_subdevices(comedi_t *it)
 
47
{
 
48
        int i,j;
 
49
        int ret;
 
50
        comedi_subdinfo *s;
 
51
        comedi_chaninfo ci;
 
52
        subdevice *r;
 
53
 
 
54
        s=malloc(sizeof(comedi_subdinfo)*it->n_subdevices);
 
55
        debug_ptr(s);
 
56
 
 
57
        ret = comedi_ioctl(it->fd, COMEDI_SUBDINFO, (unsigned long)s);
 
58
        debug_int(ret);
 
59
 
 
60
        r=it->subdevices=realloc(it->subdevices,
 
61
                sizeof(subdevice)*it->n_subdevices);
 
62
        debug_ptr(r);
 
63
        memset(r,0,sizeof(subdevice)*it->n_subdevices);
 
64
 
 
65
        it->has_insnlist_ioctl = do_test_for_insnlist(it);
 
66
        it->has_insn_ioctl = do_test_for_insn(it);
 
67
        for(i=0;i<it->n_subdevices;i++){
 
68
                r[i].type       = s[i].type;
 
69
                if(r[i].type==COMEDI_SUBD_UNUSED)continue;
 
70
                r[i].n_chan     = s[i].n_chan;
 
71
                r[i].subd_flags = s[i].subd_flags;
 
72
                r[i].timer_type = s[i].timer_type;
 
73
                r[i].len_chanlist = s[i].len_chanlist;
 
74
                r[i].maxdata    = s[i].maxdata;
 
75
                r[i].flags      = s[i].flags;
 
76
                r[i].range_type = s[i].range_type;
 
77
 
 
78
                if(r[i].subd_flags&SDF_FLAGS){
 
79
                        r[i].flags_list=malloc(sizeof(*r[i].flags_list)*r[i].n_chan);
 
80
                        debug_ptr(r[i].flags_list);
 
81
                }
 
82
                if(r[i].subd_flags&SDF_MAXDATA){
 
83
                        r[i].maxdata_list=malloc(sizeof(*r[i].maxdata_list)*r[i].n_chan);
 
84
                        debug_ptr(r[i].maxdata_list);
 
85
                }
 
86
                if(r[i].subd_flags&SDF_RANGETYPE){
 
87
                        r[i].range_type_list=malloc(sizeof(*r[i].range_type_list)*r[i].n_chan);
 
88
                        debug_ptr(r[i].range_type_list);
 
89
                }
 
90
                ci.subdev = i;
 
91
                ci.flaglist = r[i].flags_list;
 
92
                ci.rangelist = r[i].range_type_list;
 
93
                ci.maxdata_list = r[i].maxdata_list;
 
94
                ret = comedi_ioctl(it->fd, COMEDI_CHANINFO, (unsigned long)&ci);
 
95
                debug_int(ret);
 
96
 
 
97
                if(r[i].subd_flags&SDF_RANGETYPE){
 
98
                        r[i].rangeinfo_list=malloc(sizeof(*r[i].rangeinfo_list)*r[i].n_chan);
 
99
                        debug_ptr(r[i].rangeinfo_list);
 
100
                        for(j=0;j<r[i].n_chan;j++){
 
101
                                r[i].rangeinfo_list[j]=get_rangeinfo(it->fd,r[i].range_type_list[j]);
 
102
                        }
 
103
                }else{
 
104
                        r[i].rangeinfo=get_rangeinfo(it->fd,r[i].range_type);
 
105
                }
 
106
 
 
107
                r[i].has_cmd = do_test_for_cmd(it,i);
 
108
                if(it->has_insnlist_ioctl){
 
109
                        r[i].has_insn_bits = do_test_for_insn_bits(it,i);
 
110
                }else{
 
111
                        r[i].has_insn_bits = 0;
 
112
                }
 
113
        }
 
114
 
 
115
        free(s);
 
116
 
 
117
        return 0;
 
118
}
 
119
 
 
120
comedi_range *get_rangeinfo(int fd,unsigned int range_type)
 
121
{
 
122
        comedi_krange *kr;
 
123
        comedi_range *r;
 
124
        comedi_rangeinfo ri;
 
125
        int ret;
 
126
        int i;
 
127
 
 
128
        kr=malloc(sizeof(comedi_krange)*RANGE_LENGTH(range_type));
 
129
        r=malloc(sizeof(comedi_range)*RANGE_LENGTH(range_type));
 
130
 
 
131
        ri.range_type = range_type;
 
132
        ri.range_ptr = kr;
 
133
        ret = comedi_ioctl(fd, COMEDI_RANGEINFO, (unsigned long)&ri);
 
134
        if(ret<0){
 
135
                fprintf(stderr,"ioctl(%d,COMEDI_RANGEINFO,0x%08x,%p)\n",fd,range_type,kr);
 
136
        }
 
137
 
 
138
        for(i=0;i<RANGE_LENGTH(range_type);i++){
 
139
                r[i].min=kr[i].min*1e-6;
 
140
                r[i].max=kr[i].max*1e-6;
 
141
                r[i].unit=kr[i].flags;
 
142
        }
 
143
        free(kr);
 
144
 
 
145
        return r;
 
146
}
 
147
 
 
148
 
 
149
/* some command testing */
 
150
 
 
151
static int do_test_for_cmd(comedi_t *dev,unsigned int subdevice)
 
152
{
 
153
        /* SDF_CMD was added in 0.7.57 */
 
154
        if(dev->devinfo.version_code >= COMEDI_VERSION_CODE(0,7,57)){
 
155
                if(dev->subdevices[subdevice].subd_flags & SDF_CMD)
 
156
                        return 1;
 
157
                return 0;
 
158
        }else{
 
159
                comedi_cmd it;
 
160
                int ret;
 
161
 
 
162
                memset(&it,0,sizeof(it));
 
163
 
 
164
                it.subdev = subdevice;
 
165
                it.start_src = TRIG_ANY;
 
166
                it.scan_begin_src = TRIG_ANY;
 
167
                it.convert_src = TRIG_ANY;
 
168
                it.scan_end_src = TRIG_ANY;
 
169
                it.stop_src = TRIG_ANY;
 
170
 
 
171
                ret = comedi_ioctl(dev->fd, COMEDI_CMDTEST, (unsigned long)&it);
 
172
 
 
173
                if(ret<0 && errno==EIO){
 
174
                        return 0;
 
175
                }
 
176
                if(ret<0){
 
177
                        fprintf(stderr,"BUG in do_test_for_cmd()\n");
 
178
                        return 0;
 
179
                }
 
180
                return 1;
 
181
        }
 
182
}
 
183
 
 
184
static int do_test_for_insnlist(comedi_t *dev)
 
185
{
 
186
        comedi_insn insn;
 
187
        comedi_insnlist il;
 
188
        lsampl_t data[2];
 
189
        int ret;
 
190
 
 
191
        memset(&insn,0,sizeof(insn));
 
192
 
 
193
        il.n_insns = 1;
 
194
        il.insns = &insn;
 
195
 
 
196
        insn.insn = INSN_GTOD;
 
197
        insn.n = 2;
 
198
        insn.data = data;
 
199
 
 
200
        ret = comedi_ioctl(dev->fd, COMEDI_INSNLIST, (unsigned long)&il);
 
201
 
 
202
        if(ret<0){
 
203
                if(errno!=EIO){
 
204
                        fprintf(stderr,"BUG in do_test_for_insn()\n");
 
205
                }
 
206
                return 0;
 
207
        }
 
208
        return 1;
 
209
}
 
210
 
 
211
/* the COMEID_INSN ioctl was introduced in comedi-0.7.60 */
 
212
static int do_test_for_insn(comedi_t *dev)
 
213
{
 
214
        comedi_insn insn;
 
215
        comedi_insnlist il;
 
216
        lsampl_t data[2];
 
217
        int ret;
 
218
 
 
219
        memset(&insn,0,sizeof(insn));
 
220
 
 
221
        il.n_insns = 1;
 
222
        il.insns = &insn;
 
223
 
 
224
        insn.insn = INSN_GTOD;
 
225
        insn.n = 2;
 
226
        insn.data = data;
 
227
 
 
228
        ret = comedi_ioctl(dev->fd, COMEDI_INSN, (unsigned long)&insn);
 
229
 
 
230
        if(ret<0){
 
231
                if(errno!=EIO){
 
232
                        fprintf(stderr,"BUG in do_test_for_insn()\n");
 
233
                }
 
234
                return 0;
 
235
        }
 
236
        return 1;
 
237
}
 
238
 
 
239
static int do_test_for_insn_bits(comedi_t *dev,unsigned int subdevice)
 
240
{
 
241
        comedi_insn insn;
 
242
        comedi_insnlist il;
 
243
        lsampl_t data[2];
 
244
        int ret;
 
245
 
 
246
        if(dev->subdevices[subdevice].maxdata != 1)
 
247
                return 0;
 
248
 
 
249
        memset(&insn,0,sizeof(insn));
 
250
 
 
251
        il.n_insns = 1;
 
252
        il.insns = &insn;
 
253
 
 
254
        insn.insn = INSN_BITS;
 
255
        insn.n = 2;
 
256
        insn.data = data;
 
257
        insn.subdev = subdevice;
 
258
 
 
259
        data[0]=0;
 
260
        data[1]=0;
 
261
 
 
262
        ret = comedi_do_insnlist(dev,&il);
 
263
 
 
264
        if(ret<0 && (errno==EINVAL || errno==EIO)){
 
265
                return 0;
 
266
        }
 
267
        if(ret<0){
 
268
                perror("BUG in do_test_for_insn_bits()\n");
 
269
                return 0;
 
270
        }
 
271
        return 1;
 
272
}
 
273
 
 
274
 
 
275