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

« back to all changes in this revision

Viewing changes to lib/data.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/data.c
 
3
    functions for reading/writing 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
EXPORT_ALIAS_DEFAULT(_comedi_data_write,comedi_data_write,0.7.18);
 
39
int _comedi_data_write(comedi_t *it,unsigned int subdev,unsigned int chan,unsigned int range,
 
40
                unsigned int aref,lsampl_t data)
 
41
{
 
42
        subdevice *s;
 
43
 
 
44
        if(!valid_chan(it,subdev,chan))
 
45
                return -1;
 
46
 
 
47
        s=it->subdevices+subdev;
 
48
        
 
49
        if(it->has_insnlist_ioctl){
 
50
                comedi_insn insn;
 
51
 
 
52
                memset(&insn,0,sizeof(insn));
 
53
 
 
54
                insn.insn = INSN_WRITE;
 
55
                insn.n = 1;
 
56
                insn.data = &data;
 
57
                insn.subdev = subdev;
 
58
                insn.chanspec = CR_PACK(chan,range,aref);
 
59
 
 
60
                return comedi_do_insn(it,&insn);
 
61
        }else{
 
62
                comedi_trig cmd={
 
63
                        mode:           0,
 
64
                        flags:          TRIG_WRITE,
 
65
                        n_chan:         1,
 
66
                        n:              1,
 
67
                        trigsrc:        0,
 
68
                        trigvar:        0,
 
69
                        trigvar1:       0,
 
70
                };
 
71
                sampl_t sdata=data;
 
72
 
 
73
                chan=CR_PACK(chan,range,aref);
 
74
 
 
75
                cmd.subdev=subdev;
 
76
                if(it->subdevices[subdev].subd_flags & SDF_LSAMPL){
 
77
                        cmd.data=(sampl_t *)(&data);
 
78
                }else{
 
79
                        cmd.data=&sdata;
 
80
                }
 
81
                cmd.chanlist=&chan;
 
82
 
 
83
                return comedi_ioctl(it->fd, COMEDI_TRIG, (unsigned long)&cmd);
 
84
        }
 
85
}
 
86
 
 
87
static int comedi_internal_data_read_n(comedi_t *it,
 
88
        unsigned int subdev, unsigned int chanspec, lsampl_t *data,
 
89
        unsigned int n)
 
90
{
 
91
        subdevice *s;
 
92
 
 
93
        if(!valid_subd(it,subdev))
 
94
                return -1;
 
95
 
 
96
        s = it->subdevices + subdev;
 
97
 
 
98
        if(it->has_insnlist_ioctl){
 
99
                comedi_insn insn;
 
100
 
 
101
                memset(&insn,0,sizeof(insn));
 
102
 
 
103
                insn.insn = INSN_READ;
 
104
                insn.n = n;
 
105
                insn.data = data;
 
106
                insn.subdev = subdev;
 
107
                insn.chanspec = chanspec;
 
108
 
 
109
                return comedi_do_insn(it,&insn);
 
110
        }else{
 
111
                comedi_trig cmd={
 
112
                        mode:           0,
 
113
                        flags:          0,
 
114
                        n_chan:         1,
 
115
                        n:              n,
 
116
                        trigsrc:        0,
 
117
                        trigvar:        0,
 
118
                        trigvar1:       0,
 
119
                };
 
120
                int ret;
 
121
                sampl_t sdata[n];
 
122
                unsigned int i;
 
123
 
 
124
                cmd.subdev=subdev;
 
125
                cmd.chanlist=&chanspec;
 
126
                if(s->subd_flags & SDF_LSAMPL){
 
127
                        cmd.data=(sampl_t *)data;
 
128
                }else{
 
129
                        cmd.data=sdata;
 
130
                }
 
131
 
 
132
                ret = comedi_ioctl(it->fd, COMEDI_TRIG, (unsigned long)&cmd);
 
133
                if(ret<0)
 
134
                        return ret;
 
135
 
 
136
                if(!(s->subd_flags & SDF_LSAMPL)){
 
137
                        for( i = 0; i < n; i++)
 
138
                                data[i] = sdata[i];
 
139
                }
 
140
 
 
141
                return 0;
 
142
        }
 
143
}
 
144
 
 
145
EXPORT_ALIAS_DEFAULT(_comedi_data_read_n,comedi_data_read_n,0.7.18);
 
146
int _comedi_data_read_n(comedi_t *it, unsigned int subdev,
 
147
        unsigned int chan, unsigned int range,
 
148
        unsigned int aref, lsampl_t *data, unsigned int n)
 
149
{
 
150
        static const int max_chunk_size = 100;
 
151
        unsigned int chunk_size;
 
152
        unsigned int sample_count = 0;
 
153
        int retval;
 
154
 
 
155
        while( n )
 
156
        {
 
157
                if( n > max_chunk_size)
 
158
                        chunk_size = max_chunk_size;
 
159
                else
 
160
                        chunk_size = n;
 
161
                retval = comedi_internal_data_read_n(it, subdev,
 
162
                        CR_PACK(chan, range, aref),
 
163
                        data+sample_count, chunk_size);
 
164
                if( retval < 0 ) return retval;
 
165
                n -= chunk_size;
 
166
                sample_count += chunk_size;
 
167
        }
 
168
        return 0;
 
169
}
 
170
 
 
171
EXPORT_ALIAS_DEFAULT(_comedi_data_read,comedi_data_read,0.7.18);
 
172
int _comedi_data_read(comedi_t *it, unsigned int subdev, unsigned int chan,
 
173
        unsigned int range, unsigned int aref, lsampl_t *data)
 
174
{
 
175
        return comedi_internal_data_read_n(it, subdev,
 
176
                CR_PACK(chan, range, aref), data, 1);
 
177
}
 
178
 
 
179
EXPORT_ALIAS_DEFAULT(_comedi_data_read_hint,comedi_data_read_hint,0.7.19);
 
180
int _comedi_data_read_hint(comedi_t *it, unsigned int subdev,
 
181
        unsigned int chan, unsigned int range, unsigned int aref)
 
182
{
 
183
        lsampl_t dummy_data;
 
184
        return comedi_internal_data_read_n(it, subdev,
 
185
                CR_PACK(chan, range, aref), &dummy_data, 0);
 
186
}
 
187
 
 
188
EXPORT_ALIAS_DEFAULT(_comedi_data_read_delayed,comedi_data_read_delayed,0.7.19);
 
189
int _comedi_data_read_delayed( comedi_t *it, unsigned int subdev,
 
190
        unsigned int chan, unsigned int range, unsigned int aref,
 
191
        lsampl_t *data, unsigned int nano_sec)
 
192
{
 
193
        subdevice *s;
 
194
        comedi_insnlist ilist;
 
195
        comedi_insn insn[3];
 
196
        lsampl_t delay = nano_sec;
 
197
        
 
198
        if( !valid_chan( it, subdev, chan ) )
 
199
                return -1;
 
200
 
 
201
        s = it->subdevices + subdev;
 
202
 
 
203
        memset( insn, 0, sizeof(insn) );
 
204
        memset( &ilist, 0, sizeof(ilist) );
 
205
 
 
206
        // setup, no conversions
 
207
        insn[0].insn = INSN_READ;
 
208
        insn[0].n = 0;
 
209
        insn[0].data = data;
 
210
        insn[0].subdev = subdev;
 
211
        insn[0].chanspec = CR_PACK( chan, range, aref );
 
212
        // delay
 
213
        insn[1].insn = INSN_WAIT;
 
214
        insn[1].n = 1;
 
215
        insn[1].data = &delay;
 
216
        // take conversion
 
217
        insn[2].insn = INSN_READ;
 
218
        insn[2].n = 1;
 
219
        insn[2].data = data;
 
220
        insn[2].subdev = subdev;
 
221
        insn[2].chanspec = CR_PACK( chan, range, aref );
 
222
 
 
223
        ilist.insns = insn;
 
224
        ilist.n_insns = sizeof(insn) / sizeof(insn[0]);
 
225
 
 
226
        return comedi_do_insnlist(it, &ilist);
 
227
}
 
228