00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030 #include "ComediSubDeviceAIn.hpp"
00031 #include "comedi_internal.h"
00032 #include <rtt/os/fosi.h>
00033
00034 namespace OCL
00035 {
00036
00037
00038
00039 ComediSubDeviceAIn::ComediSubDeviceAIn( ComediDevice* cd, const std::string& name, unsigned int subdevice )
00040 : RTT::AnalogInInterface( name ),
00041 myCard( cd ), _subDevice( subdevice ),
00042 _sd_range(0), _aref(0), channels(0), rrange(0),
00043 max(0), min(0)
00044 {
00045 init();
00046 }
00047
00048 ComediSubDeviceAIn::ComediSubDeviceAIn( ComediDevice* cd, unsigned int subdevice )
00049 : myCard( cd ), _subDevice( subdevice ),
00050 _sd_range(0), _aref(0), channels(0), rrange(0),
00051 max(0), min(0)
00052 {
00053 init();
00054 }
00055
00056 ComediSubDeviceAIn::~ComediSubDeviceAIn()
00057 {
00058 delete[] _sd_range;
00059 delete[] _aref;
00060 delete[] max;
00061 delete[] min;
00062 }
00063
00064 void ComediSubDeviceAIn::init()
00065 {
00066 if ( !myCard) {
00067 log(Error) << "Error creating ComediSubDeviceAIn: null ComediDevice given." <<endlog();
00068 return;
00069 }
00070 if ( myCard->getSubDeviceType( _subDevice ) != COMEDI_SUBD_AI )
00071 {
00072 log(Error) << "comedi_get_subdevice_type failed" << endlog();
00073 myCard = 0;
00074 return;
00075 }
00076
00077 channels = comedi_get_n_channels(myCard->getDevice()->it, _subDevice);
00078
00079 _sd_range = new unsigned int[channels];
00080 _aref = new unsigned int[channels];
00081 max = new double[channels];
00082 min = new double[channels];
00083
00084 for (unsigned int i = 0; i < channels ; i++)
00085 {
00086 _sd_range[i] = 0;
00087 _aref[i] = AREF_GROUND;
00088 highest(i);
00089 lowest(i);
00090 }
00091
00092 rawRange();
00093 }
00094
00095 void ComediSubDeviceAIn::rangeSet(unsigned int chan, unsigned int range )
00096 {
00097 if ( chan < channels )
00098 {
00099 _sd_range[chan] = range;
00100 highest(chan);
00101 lowest(chan);
00102 }
00103 else log(Error) << "Channel does not exist" << endlog();
00104 }
00105
00106 void ComediSubDeviceAIn::arefSet(unsigned int chan, unsigned int aref )
00107 {
00108 if ( chan < channels )
00109 {
00110 _aref[chan] = aref;
00111 highest(chan);
00112 lowest(chan);
00113 }
00114 else log(Error) << "Channel does not exist" << endlog();
00115 }
00116
00117 int ComediSubDeviceAIn::rawRead( unsigned int chan, int& value )
00118 {
00119 if ( myCard ) {
00120 unsigned int uval;
00121 int ret = myCard->read( _subDevice,chan, _sd_range[chan],
00122 _aref[chan], uval );
00123 value = uval;
00124 return ret;
00125 }
00126 return -1;
00127 }
00128
00129 int ComediSubDeviceAIn::read( unsigned int chan, double& value )
00130 {
00131 unsigned int ival = 0;
00132 if ( myCard && myCard->read( _subDevice,chan, _sd_range[chan],
00133 _aref[chan], ival ) == 0) {
00134 value = min[chan] + ival / resolution(chan);
00135 return 0;
00136 }
00137 return -1;
00138 }
00139
00140 unsigned int ComediSubDeviceAIn::rawRange() const
00141 {
00142 return myCard ? (rrange = myCard->getMaxData(_subDevice)) : (rrange = 0);
00143 }
00144
00145 double ComediSubDeviceAIn::lowest(unsigned int chan) const
00146 {
00147 if (!myCard)
00148 return 0.0;
00149
00150
00151
00152
00153 #ifdef __KERNEL__
00154
00155 comedi_krange range;
00156 comedi_get_krange(myCard->getDevice()->it, _subDevice, chan,
00157 _sd_range[chan], &range);
00158 return (min[chan] = (double) range.min / 1000000.);
00159 #else
00160 #ifdef OROPKG_OS_LXRT
00161
00162 comedi_krange range;
00163 comedi_get_krange(myCard->getDevice()->it, _subDevice, chan,
00164 _sd_range[chan], &range);
00165 return (min[chan] = (double) range.min / 1000000.);
00166 #else // Userspace
00167 comedi_range * range_p;
00168 if ((range_p = comedi_get_range(myCard->getDevice()->it,
00169 _subDevice, chan,
00170 _sd_range[chan])) != 0)
00171 {
00172 return (min[chan] = range_p->min);
00173 }
00174 else
00175 {
00176 log(Error) << "Error getting comedi_range struct for channel " << chan << endlog();
00177 return -1.0;
00178 }
00179 #endif // Userspace
00180 #endif // __KERNEL__
00181 }
00182
00183 double ComediSubDeviceAIn::highest(unsigned int chan) const
00184 {
00185 if (!myCard)
00186 return 0.0;
00187
00188
00189
00190
00191 #ifdef __KERNEL__
00192
00193 comedi_krange range;
00194 comedi_get_krange(myCard->getDevice()->it, _subDevice, chan,
00195 _sd_range[chan], &range);
00196 return (max[chan] = (double) range.max / 1000000.);
00197 #else
00198 #ifdef OROPKG_OS_LXRT
00199
00200 comedi_krange range;
00201 comedi_get_krange(myCard->getDevice()->it, _subDevice, chan,
00202 _sd_range[chan], &range);
00203 return (max[chan] = (double) range.max / 1000000.);
00204 #else // Userspace
00205 comedi_range * range_p;
00206 if ((range_p = comedi_get_range(myCard->getDevice()->it,
00207 _subDevice, chan,
00208 _sd_range[chan])) != 0)
00209 {
00210 return (max[chan] = range_p->max);
00211 }
00212 else
00213 {
00214 log(Error) << "Error getting comedi_range struct for channel " << chan << endlog();
00215 return -1.0;
00216 }
00217 #endif // Userspace
00218 #endif // __KERNEL__
00219 }
00220
00221 double ComediSubDeviceAIn::resolution(unsigned int chan) const
00222 {
00223 if (!myCard)
00224 return 0.0;
00225 return rrange / ( max[chan] - min[chan] );
00226 }
00227
00228 unsigned int ComediSubDeviceAIn::nbOfChannels() const
00229 {
00230 return channels;
00231 }
00232 }