comedi.h update
[comedilib.git] / lib / dio.c
1 /*
2     lib/dio.c
3     comedi library routines
4
5     COMEDI - Linux Control and Measurement Device Interface
6     Copyright (C) 1997-8 David A. Schleef <ds@stm.lbl.gov>
7
8     This program is free software; you can redistribute it and/or modify
9     it under the terms of the GNU General Public License as published by
10     the Free Software Foundation; either version 2 of the License, or
11     (at your option) any later version.
12
13     This program 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
16     GNU General Public License for more details.
17
18     You should have received a copy of the GNU General Public License
19     along with this program; if not, write to the Free Software
20     Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
21
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 <comedi.h>
34 #include <string.h>
35
36 #include <libinternal.h>
37
38
39 int comedi_dio_config(comedi_t *it,unsigned int subdev,unsigned int chan,unsigned int io)
40 {
41         comedi_trig trig;
42         lsampl_t data=io;
43
44         if(!valid_chan(it,subdev,chan))
45                 return -1;
46         
47         if(it->subdevices[subdev].type!=COMEDI_SUBD_DIO)
48                 return -1;
49
50         if(io!=COMEDI_INPUT && io!=COMEDI_OUTPUT)
51                 return -1;
52
53         memset(&trig,0,sizeof(trig));
54         trig.flags=TRIG_CONFIG|TRIG_WRITE;
55         trig.n_chan=1;
56         trig.n=1;
57         trig.subdev=subdev;
58         trig.chanlist=&chan;
59         trig.data=(sampl_t *)&data;
60
61         return ioctl_trigger(it->fd,&trig);
62 }
63
64 int comedi_dio_read(comedi_t *it,unsigned int subdev,unsigned int chan,
65         unsigned int *val)
66 {
67         comedi_trig trig;
68         lsampl_t data;
69         int ret;
70
71         if(!valid_chan(it,subdev,chan))
72                 return -1;
73
74         if(it->subdevices[subdev].type!=COMEDI_SUBD_DIO &&
75            it->subdevices[subdev].type!=COMEDI_SUBD_DO &&
76            it->subdevices[subdev].type!=COMEDI_SUBD_DI)
77                 return -1;
78
79         memset(&trig,0,sizeof(trig));
80         trig.n_chan=1;
81         trig.n=1;
82         trig.subdev=subdev;
83         trig.chanlist=&chan;
84         trig.data=(sampl_t *)&data;
85
86         ret=ioctl_trigger(it->fd,&trig);
87
88         if(ret>=0 && val)*val=data;
89
90         return ret;
91 }
92
93 int comedi_dio_write(comedi_t *it,unsigned int subdev,unsigned int chan,
94         unsigned int val)
95 {
96         comedi_trig trig;
97         lsampl_t data;
98
99         if(!valid_chan(it,subdev,chan))
100                 return -1;
101         
102         if(it->subdevices[subdev].type!=COMEDI_SUBD_DIO &&
103            it->subdevices[subdev].type!=COMEDI_SUBD_DO)
104                 return -1;
105
106         data=val;
107
108         memset(&trig,0,sizeof(trig));
109         trig.n_chan=1;
110         trig.n=1;
111         trig.flags=TRIG_WRITE;
112         trig.subdev=subdev;
113         trig.chanlist=&chan;
114         trig.data=(sampl_t *)&data;
115
116         return ioctl_trigger(it->fd,&trig);
117 }
118
119 int comedi_dio_bitfield(comedi_t *it,unsigned int subdev,unsigned int mask,unsigned int *bits)
120 {
121         int ret;
122         unsigned int i,n_chan;
123         unsigned int m,bit;
124         subdevice *s;
125
126         if(!valid_subd(it,subdev))
127                 return -1;
128
129         if(it->subdevices[subdev].type!=COMEDI_SUBD_DIO &&
130            it->subdevices[subdev].type!=COMEDI_SUBD_DO &&
131            it->subdevices[subdev].type!=COMEDI_SUBD_DI)
132                 return -1;
133         
134         s=it->subdevices+subdev;
135
136         n_chan=comedi_get_n_channels(it,subdev);
137         if(n_chan>32)n_chan=32;
138         for(i=0,m=1;i<n_chan;i++,m<<=1){
139                 if(mask&m){
140                         bit=(*bits&m)?1:0;
141                         ret=comedi_dio_write(it,subdev,i,bit);
142                 }else{
143                         ret=comedi_dio_read(it,subdev,i,&bit);
144                         if(bit) *bits|=m;
145                         else (*bits)&=~m;
146                 }
147                 if(ret<0)return ret;
148         }
149
150         return (int)n_chan;
151 }
152