![]() |
RTXI 1.3
|
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