/* lib/sv.c comedi library routines - sv section COMEDI - Linux Control and Measurement Device Interface Copyright (C) 1997-8 David A. Schleef 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 program 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. */ #include #include #include #include #include #include #include #include #include #include #include #include int sv_measure_l(comedi_sv_t *it,double *data); int sv_measure_s(comedi_sv_t *it,double *data); int comedi_sv_init(comedi_sv_t *it,comedi_t *dev,unsigned int subd,unsigned int chan) { if(!valid_chan(dev,subd,chan))return -1; if(!it)return -1; memset(it,0,sizeof(*it)); it->dev=dev; it->subdevice=subd; it->chan=chan; it->n=100; return comedi_sv_update(it); } int comedi_sv_update(comedi_sv_t *it) { if(!it)return -1; if(!valid_chan(it->dev,it->subdevice,it->chan))return -1; it->maxdata=comedi_get_maxdata(it->dev,it->subdevice,it->chan); /* check current range policy */ /* check n */ return 0; } int comedi_sv_measure(comedi_sv_t *it,double *data) { if(it->dev->subdevices[it->subdevice].subd_flags & SDF_LSAMPL){ return sv_measure_l(it,data); }else{ return sv_measure_s(it,data); } } int sv_measure_l(comedi_sv_t *it,double *data) { comedi_trig t; int ret=0; lsampl_t *val; unsigned int chan; comedi_range *rng; double sum; int i; int n; val=malloc(sizeof(*val)*it->n); chan=CR_PACK(it->chan,it->range,it->aref); t.subdev=it->subdevice; t.mode=0; t.flags=TRIG_DITHER; t.n_chan=1; t.chanlist=&chan; t.trigsrc=0; t.trigvar=0; t.trigvar1=0; rng=comedi_get_range(it->dev,it->subdevice,it->chan,it->range); for(n=0;nn;){ t.data=(void *)(val+n); t.n=it->n-n; i=ioctl_trigger(it->dev->fd,&t); if(i<=0){ ret=i; goto out; } n+=i; } sum=0; for(i=0;in;i++){ sum+=comedi_to_phys(val[i],rng,it->maxdata); } *data=sum/it->n; out: free(val); return ret; } /* yes, these functions are _almost_ exactly the same... */ int sv_measure_s(comedi_sv_t *it,double *data) { comedi_trig t; int ret=0; sampl_t *val; unsigned int chan; comedi_range *rng; double sum; int i; int n; val=malloc(sizeof(*val)*it->n); chan=CR_PACK(it->chan,it->range,it->aref); t.subdev=it->subdevice; t.mode=0; t.flags=TRIG_DITHER; t.n_chan=1; t.chanlist=&chan; t.data=val; t.n=it->n; t.trigsrc=0; t.trigvar=0; t.trigvar1=0; rng=comedi_get_range(it->dev,it->subdevice,it->chan,it->range); for(n=0;nn;){ t.data=val+n; t.n=it->n-n; i=ioctl_trigger(it->dev->fd,&t); if(i<=0){ ret=i; goto out; } n+=i; } sum=0; for(i=0;in;i++){ sum+=comedi_to_phys(val[i],rng,it->maxdata); } *data=sum/it->n; out: free(val); return ret; }