RTXI 1.3
comedilib/lib/range.c
Go to the documentation of this file.
00001 /*
00002     lib/range.c
00003     functions to manipulate physical unit conversion
00004 
00005     COMEDILIB - Linux Control and Measurement Device Interface Library
00006     Copyright (C) 1997-2001 David A. Schleef <ds@schleef.org>
00007 
00008     This library is free software; you can redistribute it and/or
00009     modify it under the terms of the GNU Lesser General Public
00010     License as published by the Free Software Foundation, version 2.1
00011     of the License.
00012 
00013     This library is distributed in the hope that it will be useful,
00014     but WITHOUT ANY WARRANTY; without even the implied warranty of
00015     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00016     Lesser General Public License for more details.
00017 
00018     You should have received a copy of the GNU Lesser General Public
00019     License along with this library; if not, write to the Free Software
00020     Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307
00021     USA.
00022 */
00023 
00024 #include <stdio.h>
00025 
00026 #define __USE_GNU
00027 
00028 #include <math.h>
00029 #include <stdlib.h>
00030 #include <sys/types.h>
00031 #include <sys/stat.h>
00032 #include <fcntl.h>
00033 #include <unistd.h>
00034 #include <sys/ioctl.h>
00035 #include <errno.h>
00036 #include <string.h>
00037 
00038 #include "libinternal.h"
00039 
00040 
00041 /* sometimes we can't find a definition of NAN */
00042 
00043 #ifndef NAN
00044 #define NAN \
00045   (__extension__ ((union { unsigned char __c[8];                              \
00046                            double __d; })                                     \
00047                   { { 0, 0, 0, 0, 0, 0, 0xf8, 0x7f } }).__d)
00048 #endif
00049 
00050 
00051 static enum comedi_oor_behavior comedi_oor_is_nan = COMEDI_OOR_NAN;
00052 
00053 EXPORT_ALIAS_DEFAULT(_comedi_set_global_oor_behavior,comedi_set_global_oor_behavior,0.7.18);
00054 enum comedi_oor_behavior _comedi_set_global_oor_behavior(
00055         enum comedi_oor_behavior behavior)
00056 {
00057         int old_behavior=comedi_oor_is_nan;
00058 
00059         comedi_oor_is_nan=behavior;
00060 
00061         return old_behavior;
00062 }
00063 
00064 
00065 EXPORT_ALIAS_DEFAULT(_comedi_to_phys,comedi_to_phys,0.7.18);
00066 double _comedi_to_phys(lsampl_t data,comedi_range *rng,lsampl_t maxdata)
00067 {
00068         double x;
00069 
00070         if(!rng)return NAN;
00071         if(!maxdata)return NAN;
00072 
00073         if(comedi_oor_is_nan==COMEDI_OOR_NAN && (data==0 || data==maxdata))
00074                 return NAN;
00075 
00076         x=data;
00077         x/=maxdata;
00078         x*=(rng->max-rng->min);
00079         x+=rng->min;
00080 
00081         return x;
00082 }
00083 
00084 EXPORT_ALIAS_DEFAULT(_comedi_from_phys,comedi_from_phys,0.7.18);
00085 lsampl_t _comedi_from_phys(double data,comedi_range *rng,lsampl_t maxdata)
00086 {
00087         double s;
00088 
00089         if(!rng)return 0;
00090         if(!maxdata)return 0;
00091 
00092         s=(data-rng->min)/(rng->max-rng->min)*maxdata;
00093         if(s<0)return 0;
00094         if(s>maxdata)return maxdata;
00095 
00096         return (lsampl_t)(floor(s+0.5));
00097 }
00098 
00099 EXPORT_ALIAS_DEFAULT(_comedi_find_range,comedi_find_range,0.7.18);
00100 int _comedi_find_range(comedi_t *it,unsigned int subd,unsigned int chan,unsigned int unit,double min,double max)
00101 {
00102         unsigned int range_type;
00103         int best;
00104         comedi_range *range_ptr,*best_ptr;
00105         int i;
00106         
00107         if(!valid_chan(it,subd,chan))return -1;
00108 
00109         range_type=comedi_get_rangetype(it,subd,chan);
00110         best=-1;
00111         best_ptr=NULL;
00112         for(i=0;i<RANGE_LENGTH(range_type);i++){
00113                 range_ptr=comedi_get_range(it,subd,chan,i);
00114                 if(range_ptr->min<=min && range_ptr->max>=max){
00115                         if(best<0 || (range_ptr->max-range_ptr->min) < 
00116                            (best_ptr->max-best_ptr->min)){
00117                                 best=i;
00118                                 best_ptr=range_ptr;
00119                         }
00120                 }
00121         }
00122         return best;
00123 }
00124 
00125 EXPORT_ALIAS_DEFAULT(_comedi_get_n_ranges,comedi_get_n_ranges,0.7.18);
00126 int _comedi_get_n_ranges(comedi_t *it,unsigned int subd,unsigned int chan)
00127 {
00128         unsigned int range_type;
00129 
00130         if(!valid_chan(it,subd,chan))return -1;
00131 
00132         range_type=comedi_get_rangetype(it,subd,chan);
00133         return RANGE_LENGTH(range_type);
00134 }
00135 
00136 EXPORT_ALIAS_DEFAULT(_comedi_range_is_chan_specific,comedi_range_is_chan_specific,0.7.18);
00137 int _comedi_range_is_chan_specific(comedi_t *it,unsigned int subd)
00138 {
00139         if(!valid_subd(it,subd)) return -1;
00140         return (it->subdevices[subd].subd_flags&SDF_RANGETYPE)?1:0;
00141 }
00142 
00143 EXPORT_ALIAS_DEFAULT(_comedi_sampl_to_phys,comedi_sampl_to_phys,0.7.18);
00144 int _comedi_sampl_to_phys(double *dest, int dst_stride, sampl_t *src,
00145         int src_stride, comedi_range *rng, lsampl_t maxdata, int n)
00146 {
00147         int oor = 0;
00148         int i;
00149         double mult;
00150 
00151         if(!rng)return -1;
00152         if(!maxdata)return -1;
00153 
00154         mult = (rng->max-rng->min)/maxdata;
00155         if(comedi_oor_is_nan==COMEDI_OOR_NAN){
00156                 for(i=0;i<n;i++){
00157                         if(*src==0 || *src==maxdata){
00158                                 oor++;
00159                                 *dest=NAN;
00160                         }else{
00161                                 *dest = rng->min + mult*(*src);
00162                         }
00163                         dest = ((void *)dest) + dst_stride;
00164                         src = ((void *)src) + src_stride;
00165                 }
00166         }else{
00167                 for(i=0;i<n;i++){
00168                         if(*src==0 || *src==maxdata){
00169                                 oor++;
00170                         }
00171                         *dest = rng->min + mult*(*src);
00172                         dest = ((void *)dest) + dst_stride;
00173                         src = ((void *)src) + src_stride;
00174                 }
00175         }
00176 
00177         return oor;
00178 }
00179 
00180 EXPORT_ALIAS_DEFAULT(_comedi_sampl_from_phys,comedi_sampl_from_phys,0.7.18);
00181 int _comedi_sampl_from_phys(sampl_t *dest,int dst_stride,double *src,
00182         int src_stride, comedi_range *rng, lsampl_t maxdata, int n)
00183 {
00184         int oor = 0;
00185         double mult;
00186         int i;
00187 
00188         if(!rng)return -1;
00189         if(!maxdata)return -1;
00190 
00191         mult = (maxdata+1)/(rng->max-rng->min);
00192         for(i=0;i<n;i++){
00193                 *dest=mult*(*src-rng->min);
00194                 if(*src<rng->min){
00195                         *dest=0;
00196                         oor++;
00197                 }
00198                 if(*src>rng->min){
00199                         *dest=maxdata;
00200                         oor++;
00201                 }
00202                 dest = ((void *)dest) + dst_stride;
00203                 src = ((void *)src) + src_stride;
00204         }
00205 
00206         return oor;
00207 }
00208 
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines