iop_comedi.cpp
Go to the documentation of this file.
1 
2 /** @file iop_comedi.cpp Low-level access to physical device over comedi-driver*/
3 
4 /*
5  FAU Discrete Event Systems Library (libfaudes)
6 
7  Copyright (C) 2008, Thomas Moor
8  Exclusive copyright is granted to Klaus Schmidt
9 
10 */
11 
12 
13 // include header
14 #include "iop_comedi.h"
15 
16 namespace faudes {
17 
18 // only compile for comedi support
19 #ifdef FAUDES_IODEVICE_COMEDI
20 
21 // std faudes, incl dummy
22 FAUDES_TYPE_IMPLEMENTATION(ComediDevice,cDevice,sDevice)
23 
24 // autoregister
25 AutoRegisterType<cDevice> gRtiRegisterComediDevice("ComediDevice");
26 
27 //constructor
28 cDevice::cDevice(void) : sDevice(), mDev(0) {
29  FD_DHV("cDevice(" << mName << ")::cDevice()");
30  // have appropriate default label for token io
31  mDefaultLabel = "ComediDevice";
32  // invalidate images
33  mpInputImage=NULL;
34  mpOutputImage=NULL;
35 }
36 
37 //deconstructor
38 cDevice::~cDevice(void) {
39  FD_DHV("cDevice(" << mName << ")::~cDevice()");
40  Stop();
41 }
42 
43 //DoWrite(rTr,rLabel,pContext)
44 void cDevice::DoWritePreface(TokenWriter& rTw, const std::string& rLabel, const Type* pContext) const {
45  FD_DHV("cDevice("<<mName<<")::DoWritePreface()");
46  //call base
47  sDevice::DoWritePreface(rTw,"",pContext);
48  // write mSystemFile
49  Token sysf;
50  sysf.SetBegin("DeviceFile");
51  sysf.InsAttribute("value",mSystemFile);
52  rTw << sysf;
53 }
54 
55 
56 //DoReadPreface(rTr,rLabel,pContext)
57 void cDevice::DoReadPreface(TokenReader& rTr,const std::string& rLabel, const Type* pContext){
58  FD_DHV("cDevice("<<mName<<")::DoReadPreface()");
59  //call base
60  sDevice::DoReadPreface(rTr,"",pContext);
61 
62  // sense and digest pre 2.16 format
63  Token token;
64  rTr.Peek(token);
65  if(token.IsString()) {
66  mSystemFile = rTr.ReadString();
67  return;
68  }
69 
70  // loop my members
71  while(true) {
72  Token token;
73  rTr.Peek(token);
74  // system file
75  if(token.IsBegin("DeviceFile")) {
76  rTr.ReadBegin("DeviceFile", token);
77  mSystemFile=token.AttributeStringValue("value");
78  rTr.ReadEnd("DeviceFile");
79  continue;
80  }
81  // break on unknown
82  break;
83  }
84 }
85 
86 
87 // Start(void)
88 void cDevice::Start(void) {
89  //open comedi-device
90  if(mState!=Down) return;
91  FD_DH("cDevice(" << mName << ")::Start(): open devices");
92  mDev=comedi_open(mSystemFile.c_str());
93 
94  // throw exception if opening device failed
95  if(!mDev) {
96  std::stringstream errstr;
97  errstr << "cannot open device /dev/comedi0 (inputs)";
98  throw Exception("cDevice()::Start()", errstr.str(), 552);
99  }
100 
101  // check some properties on input card
102  for(int bit=0; bit<=mMaxBitAddress; bit++) {
103 
104  // map to subdevice/channel
105  int sub=bit/32;
106  int chan=bit%32;
107 
108 
109  // dio config is not implemented for advantech boards (?)
110  /*
111  ComediInt32 res;
112  // get info
113  if(comedi_dio_get_config(mDev, sub, chan, &res) !=0) {
114  std::stringstream errstr;
115  errstr << "cannot open device " << mSystemFile << ": no digital io at bit address " << bit;
116  throw Exception("cDevice()::Start()", errstr.str(), 552);
117  }
118  // is there a comedi input?
119  if((!mInputPosEdgeIndexMap[bit].Empty()) || (!mInputNegEdgeIndexMap[bit].Empty())) {
120  if(res != COMEDI_INPUT) {
121  std::stringstream errstr;
122  errstr << "cannot open device " << mSystemFile << ": no digital input at bit address " << bit;
123  throw Exception("cDevice()::Start()", errstr.str(), 552);
124  }
125  }
126  // is there a comedi output?
127  if(!mOutputLevelIndexMap[bit].Empty()) {
128  if(res != COMEDI_OUTPUT) {
129  std::stringstream errstr;
130  errstr << "cannot open device " << mSystemFile << ": no digital output at bit address " << bit;
131  throw Exception("cDevice()::Start()", errstr.str(), 552);
132  }
133  }
134  */
135 
136  // at least we can test whether we can read inputs
137  lsampl_t val;
138  if((!mInputPosEdgeIndexMap[bit].Empty()) || (!mInputNegEdgeIndexMap[bit].Empty())) {
139  if(comedi_data_read(mDev,sub,chan,0,AREF_GROUND,&val)!=1) {
140  std::stringstream errstr;
141  errstr << "cannot open device " << mSystemFile << ": failed to test read from digital input at bit address " << bit;
142  throw Exception("cDevice()::Start()", errstr.str(), 552);
143  }
144  }
145 
146  }
147 
148  // allocate image
149  mComediSubdevs = (mMaxBitAddress / 32) + 1;
150  if(mComediSubdevs<=0) mComediSubdevs=1;
151  mpInputImage = new ComediInt32[mComediSubdevs];
152  mpOutputImage = new ComediInt32[mComediSubdevs];
153  // precompute mask
154  for(int bit=0; bit<32; ++bit) mComediMask[bit] = 0x000000001U << bit;
155  // call base
156  sDevice::Start();
157 }
158 
159 
160 // Stop()
161 void cDevice::Stop(void) {
162  //close comedi-device
163  if(mState != Up && mState != StartUp) return;
164  FD_DHV("cDevice(" << mName << ")::Stop()");
165  // call base
166  sDevice::Stop();
167  // close device
168  comedi_close(mDev);
169  mDev=0;
170  // invalidate buffers
171  delete mpInputImage;
172  delete mpOutputImage;
173  mpInputImage=NULL;
174  mpOutputImage=NULL;
175 }
176 
177 
178 
179 // Input Hook: we use a bit image (libFAUDES 2.23)
180 bool cDevice::DoReadSignalsPre(void) {
181  // read all bits to buffer
182  for(int sub =0 ; sub<mComediSubdevs; ++sub)
183  comedi_dio_bitfield2(mDev, sub, 0, &mpInputImage[sub], 0);
184  // never fail (i.e. ignore errors)
185  return true;
186 }
187 
188 
189 // Input Hook: bit image does not need further attention
190 void cDevice::DoReadSignalsPost(void) {
191 }
192 
193 
194 //ReadSignal(int)
195 bool cDevice::DoReadSignal(int bit){
196  // pre libFAUDES 2.23 bit-read (for reference)
197  /*
198  lsampl_t input=0;
199  comedi_data_read(mDev,bit/32,bit%32,0,AREF_GROUND,&input);
200  return (input!=0);
201  */
202  // read from buffer
203  return (mpInputImage[bit/32] & mComediMask[bit%32]) != 0;
204 }
205 
206 
207 // Output Hook: we use bit-write
208 bool cDevice::DoWriteSignalsPre(void) { return true; }
209 void cDevice::DoWriteSignalsPost(void) {}
210 
211 
212 //WriteSignal(int,int)
213 void cDevice::DoWriteSignal(int bit, bool value){
214  // write one actuator value, adressed by bit number (0 to 63);
215  // ignore error
216  lsampl_t output= (value ? 1 : 0);
217  comedi_data_write(mDev,bit/32,bit%32,0,AREF_GROUND,output);
218 }
219 
220 
221 #endif // if comedi
222 
223 } // namespace
224 
225 
#define FAUDES_TYPE_IMPLEMENTATION(ftype, ctype, cbase)
faudes type implementation macros, overall
Definition: cfl_types.h:946
Hardware access via comedi.
#define FD_DHV(message)
Definition: iop_vdevice.h:37
#define FD_DH(message)
Definition: iop_vdevice.h:27
libFAUDES resides within the namespace faudes.

libFAUDES 2.32b --- 2024.03.01 --- c++ api documentaion by doxygen