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
16namespace faudes {
17
18// only compile for comedi support
19#ifdef FAUDES_IODEVICE_COMEDI
20
21// std faudes, incl dummy
22FAUDES_TYPE_IMPLEMENTATION(ComediDevice,cDevice,sDevice)
23
24// autoregister
25AutoRegisterType<cDevice> gRtiRegisterComediDevice("ComediDevice");
26
27//constructor
28cDevice::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
38cDevice::~cDevice(void) {
39 FD_DHV("cDevice(" << mName << ")::~cDevice()");
40 Stop();
41}
42
43//DoWrite(rTr,rLabel,pContext)
44void 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)
57void 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)
88void 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()
161void 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)
180bool 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
190void cDevice::DoReadSignalsPost(void) {
191}
192
193
194//ReadSignal(int)
195bool 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
208bool cDevice::DoWriteSignalsPre(void) { return true; }
209void cDevice::DoWriteSignalsPost(void) {}
210
211
212//WriteSignal(int,int)
213void 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)
Definition cfl_types.h:958
#define FD_DHV(message)
Definition iop_vdevice.h:37
#define FD_DH(message)
Definition iop_vdevice.h:27

libFAUDES 2.33k --- 2025.09.16 --- c++ api documentaion by doxygen