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