iop_comedi.cppGo to the documentation of this file.00001 00002 /** @file iop_comedi.cpp Low-level access to physical device over comedi-driver*/ 00003 00004 /* 00005 FAU Discrete Event Systems Library (libfaudes) 00006 00007 Copyright (C) 2008, Thomas Moor 00008 Exclusive copyright is granted to Klaus Schmidt 00009 00010 */ 00011 00012 00013 // include header 00014 #include "iop_comedi.h" 00015 00016 namespace faudes { 00017 00018 // only compile for comedi support 00019 #ifdef FAUDES_IODEVICE_COMEDI 00020 00021 // std faudes, incl dummy 00022 FAUDES_TYPE_IMPLEMENTATION(ComediDevice,cDevice,sDevice) 00023 00024 // autoregister 00025 AutoRegisterType<cDevice> gRtiRegisterComediDevice("ComediDevice"); 00026 00027 //constructor 00028 cDevice::cDevice(void) : sDevice(), mDev(0) { 00029 FD_DHV("cDevice(" << mName << ")::cDevice()"); 00030 // have appropriate default label for token io 00031 mDefaultLabel = "ComediDevice"; 00032 // invalidate images 00033 mpInputImage=NULL; 00034 mpOutputImage=NULL; 00035 } 00036 00037 //deconstructor 00038 cDevice::~cDevice(void) { 00039 FD_DHV("cDevice(" << mName << ")::~cDevice()"); 00040 Stop(); 00041 } 00042 00043 //DoWrite(rTr,rLabel,pContext) 00044 void cDevice::DoWritePreface(TokenWriter& rTw, const std::string& rLabel, const Type* pContext) const { 00045 FD_DHV("cDevice("<<mName<<")::DoWritePreface()"); 00046 //call base 00047 sDevice::DoWritePreface(rTw,"",pContext); 00048 // write mSystemFile 00049 Token sysf; 00050 sysf.SetBegin("DeviceFile"); 00051 sysf.InsAttribute("value",mSystemFile); 00052 rTw << sysf; 00053 } 00054 00055 00056 //DoReadPreface(rTr,rLabel,pContext) 00057 void cDevice::DoReadPreface(TokenReader& rTr,const std::string& rLabel, const Type* pContext){ 00058 FD_DHV("cDevice("<<mName<<")::DoReadPreface()"); 00059 //call base 00060 sDevice::DoReadPreface(rTr,"",pContext); 00061 00062 // sense and digest pre 2.16 format 00063 Token token; 00064 rTr.Peek(token); 00065 if(token.IsString()) { 00066 mSystemFile = rTr.ReadString(); 00067 return; 00068 } 00069 00070 // loop my members 00071 while(true) { 00072 Token token; 00073 rTr.Peek(token); 00074 // system file 00075 if(token.IsBegin("DeviceFile")) { 00076 rTr.ReadBegin("DeviceFile", token); 00077 mSystemFile=token.AttributeStringValue("value"); 00078 rTr.ReadEnd("DeviceFile"); 00079 continue; 00080 } 00081 // break on unknown 00082 break; 00083 } 00084 } 00085 00086 00087 // Start(void) 00088 void cDevice::Start(void) { 00089 //open comedi-device 00090 if(mState!=Down) return; 00091 FD_DH("cDevice(" << mName << ")::Start(): open devices"); 00092 mDev=comedi_open(mSystemFile.c_str()); 00093 00094 // throw exception if opening device failed 00095 if(!mDev) { 00096 std::stringstream errstr; 00097 errstr << "cannot open device /dev/comedi0 (inputs)"; 00098 throw Exception("cDevice()::Start()", errstr.str(), 552); 00099 } 00100 00101 // check some properties on input card 00102 for(int bit=0; bit<=mMaxBitAddress; bit++) { 00103 00104 // map to subdevice/channel 00105 int sub=bit/32; 00106 int chan=bit%32; 00107 00108 00109 // dio config is not implemented for advantech boards (?) 00110 /* 00111 ComediInt32 res; 00112 // get info 00113 if(comedi_dio_get_config(mDev, sub, chan, &res) !=0) { 00114 std::stringstream errstr; 00115 errstr << "cannot open device " << mSystemFile << ": no digital io at bit address " << bit; 00116 throw Exception("cDevice()::Start()", errstr.str(), 552); 00117 } 00118 // is there a comedi input? 00119 if((!mInputPosEdgeIndexMap[bit].Empty()) || (!mInputNegEdgeIndexMap[bit].Empty())) { 00120 if(res != COMEDI_INPUT) { 00121 std::stringstream errstr; 00122 errstr << "cannot open device " << mSystemFile << ": no digital input at bit address " << bit; 00123 throw Exception("cDevice()::Start()", errstr.str(), 552); 00124 } 00125 } 00126 // is there a comedi output? 00127 if(!mOutputLevelIndexMap[bit].Empty()) { 00128 if(res != COMEDI_OUTPUT) { 00129 std::stringstream errstr; 00130 errstr << "cannot open device " << mSystemFile << ": no digital output at bit address " << bit; 00131 throw Exception("cDevice()::Start()", errstr.str(), 552); 00132 } 00133 } 00134 */ 00135 00136 // at least we can test whether we can read inputs 00137 lsampl_t val; 00138 if((!mInputPosEdgeIndexMap[bit].Empty()) || (!mInputNegEdgeIndexMap[bit].Empty())) { 00139 if(comedi_data_read(mDev,sub,chan,0,AREF_GROUND,&val)!=1) { 00140 std::stringstream errstr; 00141 errstr << "cannot open device " << mSystemFile << ": failed to test read from digital input at bit address " << bit; 00142 throw Exception("cDevice()::Start()", errstr.str(), 552); 00143 } 00144 } 00145 00146 } 00147 00148 // allocate image 00149 mComediSubdevs = (mMaxBitAddress / 32) + 1; 00150 if(mComediSubdevs<=0) mComediSubdevs=1; 00151 mpInputImage = new ComediInt32[mComediSubdevs]; 00152 mpOutputImage = new ComediInt32[mComediSubdevs]; 00153 // precompute mask 00154 for(int bit=0; bit<32; ++bit) mComediMask[bit] = 0x000000001U << bit; 00155 // call base 00156 sDevice::Start(); 00157 } 00158 00159 00160 // Stop() 00161 void cDevice::Stop(void) { 00162 //close comedi-device 00163 if(mState != Up && mState != StartUp) return; 00164 FD_DHV("cDevice(" << mName << ")::Stop()"); 00165 // call base 00166 sDevice::Stop(); 00167 // close device 00168 comedi_close(mDev); 00169 mDev=0; 00170 // invalidate buffers 00171 delete mpInputImage; 00172 delete mpOutputImage; 00173 mpInputImage=NULL; 00174 mpOutputImage=NULL; 00175 } 00176 00177 00178 00179 // Input Hook: we use a bit image (libFAUDES 2.23) 00180 bool cDevice::DoReadSignalsPre(void) { 00181 // read all bits to buffer 00182 for(int sub =0 ; sub<mComediSubdevs; ++sub) 00183 comedi_dio_bitfield2(mDev, sub, 0, &mpInputImage[sub], 0); 00184 // never fail (i.e. ignore errors) 00185 return true; 00186 } 00187 00188 00189 // Input Hook: bit image does not need further attention 00190 void cDevice::DoReadSignalsPost(void) { 00191 } 00192 00193 00194 //ReadSignal(int) 00195 bool cDevice::DoReadSignal(int bit){ 00196 // pre libFAUDES 2.23 bit-read (for reference) 00197 /* 00198 lsampl_t input=0; 00199 comedi_data_read(mDev,bit/32,bit%32,0,AREF_GROUND,&input); 00200 return (input!=0); 00201 */ 00202 // read from buffer 00203 return (mpInputImage[bit/32] & mComediMask[bit%32]) != 0; 00204 } 00205 00206 00207 // Output Hook: we use bit-write 00208 bool cDevice::DoWriteSignalsPre(void) { return true; } 00209 void cDevice::DoWriteSignalsPost(void) {} 00210 00211 00212 //WriteSignal(int,int) 00213 void cDevice::DoWriteSignal(int bit, bool value){ 00214 // write one actuator value, adressed by bit number (0 to 63); 00215 // ignore error 00216 lsampl_t output= (value ? 1 : 0); 00217 comedi_data_write(mDev,bit/32,bit%32,0,AREF_GROUND,output); 00218 } 00219 00220 00221 #endif // if comedi 00222 00223 } // namespace 00224 00225 libFAUDES 2.23h --- 2014.04.03 --- c++ api documentaion by doxygen |