gtkIOStream  1.7.0
GTK+ << C++ IOStream operators for GTK+. Now with ORBing, numerical computation, audio client and more ...
IIO.H
Go to the documentation of this file.
1 /* Copyright 2000-2018 Matt Flax <flatmax@flatmax.org>
2  This file is part of GTK+ IOStream class set
3 
4  GTK+ IOStream is free software; you can redistribute it and/or modify
5  it under the terms of the GNU General Public License as published by
6  the Free Software Foundation; either version 2 of the License, or
7  (at your option) any later version.
8 
9  GTK+ IOStream is distributed in the hope that it will be useful,
10  but WITHOUT ANY WARRANTY; without even the implied warranty of
11  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12  GNU General Public License for more details.
13 
14  You have received a copy of the GNU General Public License
15  along with GTK+ IOStream
16 */
17 
18 #ifndef IIO_H_
19 #define IIO_H_
20 
21 #include "IIODevice.H"
22 #pragma GCC diagnostic push
23 #pragma GCC diagnostic ignored "-Wignored-attributes"
24 #pragma GCC diagnostic ignored "-Wdeprecated-declarations"
25 #include <Eigen/Dense>
26 #pragma GCC diagnostic pop
27 
28 #include "DirectoryScanner.H"
29 
30 #include <sstream>
31 #include <fstream>
32 
33 #include <Thread.H>
34 
35 struct iio_channel_info;
36 
72 class IIO : public std::vector<IIODevice> {
73  static const char *iioDir;
74 
79  std::string findChipName(std::string devicePath) {
80  std::string chipName;
81  std::ifstream nameFile((devicePath+"/name").c_str());
82  if (nameFile.good()) // if we can open the name
83  nameFile>>chipName;
84  return chipName;
85  }
86 
87 public:
88  IIO() {}
89  virtual ~IIO() {
90  close();
91  }
92 
97  int findDevicesByChipName(std::string chipName) {
98  vector<std::string> excluded; // paths we don't want to search
99  excluded.push_back(".");
100  excluded.push_back("..");
101 
102  DirectoryScanner ds(iioDir);
103  if (ds.findAll(excluded)!=NO_ERROR) // find all of the directories
105  ds.keepWithPattern("iio:device"); // only keep the entries of interest, namely the iio devices
106 
107  // If any of the devices have a name which matches the chipName we are after, then keep it.
108  for (unsigned int i=0; i<ds.size(); i++) {
109  std::string devicePath(iioDir);
110  devicePath+=ds[i];
111  //cout<<findChipName(devicePath)<<endl;
112  // search for chipName (e.g. "ADAU7476") in the sysfs name file, which can be chipName+"_1" or some other suffix.
113  if (findChipName(devicePath).find(chipName)!=std::string::npos) {
114  push_back(IIODevice(devicePath, chipName)); // found a relevant device, so add it to the known devices
115  operator[](size()-1).scanDevice();
116  }
117  }
118  return NO_ERROR;
119  }
120 
121 // /** Open an iio device by name.
122 // \param deviceName The name of the iio device, e.g. "iio:1"
123 // \return NOERROR on success, or the appropriate error number otherwise.
124 // */
125 // int open(std::string deviceName);
126 
131  return size();
132  }
133 
138  int chCnt=0;
139  for (uint i=0; i<getDeviceCnt(); i++)
140  chCnt+=operator[](i).getChCnt();
141  return chCnt;
142  }
143 
146  void printInfo() {
147  for (uint i=0; i<getDeviceCnt(); i++) {
148  printf("Device %d\t",i);
149  operator[](i).printInfo();
150  }
151  }
152 
156  int open(void) {
157  if (getDeviceCnt()<1)
159  int ret=NO_ERROR;
160  for (unsigned int i=0; i<getDeviceCnt(); i++) {
161  if ((ret=operator[](i).open())!=NO_ERROR) {
162  std::stringstream deviceDetail;
163  deviceDetail<<" Device "<<i;
164  IIODebug().evaluateError(ret, deviceDetail.str());
165  break;
166  }
167  }
168  int closeRet;
169  if (ret!=NO_ERROR) // if we couldn't open everything, then close everything
170  for (unsigned int i=0; i<getDeviceCnt(); i++)
171  if ((closeRet=operator[](i).close())!=NO_ERROR)
172  IIODebug().evaluateError(closeRet);
173  return ret;
174  }
175 
179  int close(void) {
180  int closeRet;
181  for (unsigned int i=0; i<getDeviceCnt(); i++)
182  if ((closeRet=operator[](i).close())!=NO_ERROR)
183  return IIODebug().evaluateError(closeRet);
184  return NO_ERROR;
185  }
186 
190  int getChFrameSize(void) {
191  if (getDeviceCnt()<1)
193  uint frameSize=operator[](0).getChFrameSize();
194  if (frameSize<0)
195  return frameSize;
196  for (unsigned int i=1; i<getDeviceCnt(); i++)
197  if (operator[](i).getChFrameSize() != frameSize)
199  return frameSize;
200  }
201 
205  int getDevFrameSize(void) {
206  if (getDeviceCnt()<1)
208 
209  int frameSize=getChFrameSize();
210  if (frameSize<0)
211  return frameSize;
212  return frameSize*getDeviceCnt();
213  }
214 
221  template<typename TYPE>
222  int getReadArray(uint N, Eigen::Array<TYPE, Eigen::Dynamic, Eigen::Dynamic> &array) {
223  if (getDeviceCnt()<1)
225  if (sizeof(TYPE)!=operator[](0).getChFrameSize()) {
226  std::stringstream msg;
227  msg<<"The provided array type has "<<sizeof(TYPE)<<" bytes per sample, where as the IIO devices have "<<getChFrameSize()<<" bytes per sample\n";
229  }
230 
231  if (array.rows()!=N*operator[](0).getChCnt() && array.cols()!=getDeviceCnt())
232  array.resize(N*operator[](0).getChCnt(), getDeviceCnt());
233  return NO_ERROR;
234  }
235 
240  template<typename TYPE>
241  int getReadArraySampleCount(Eigen::Array<TYPE, Eigen::Dynamic, Eigen::Dynamic> &array) {
242  if (getDeviceCnt()<1)
244  return array.rows()/operator[](0).getChCnt();
245  }
246 
253  template<typename TYPE>
254  int read(uint N, const Eigen::Array<TYPE, Eigen::Dynamic, Eigen::Dynamic> &array) {
255  if (sizeof(TYPE)!=operator[](0).getChFrameSize()) {
256  std::stringstream msg;
257  msg<<"The provided array type has "<<sizeof(TYPE)<<" bytes per sample, where as the IIO devices have "<<getChFrameSize()<<" bytes per sample\n";
259  }
260  if (array.rows()!=N*operator[](0).getChCnt() && array.cols()>getDeviceCnt()) {
261  std::stringstream msg;
262  msg<<"The provided array is not shaped correctly, size=("<<array.rows()<<", "<<array.cols()<<") but size=(N*device ch cnt, device cnt) is required, where size=("<<N*getChCnt()<<", "<<getDeviceCnt()<<")\n";
264  }
265  uint NOrig=N;
266  while (N){
267  uint toRead=NOrig;
268  //uint toRead=1024;
269  if (toRead>N) toRead=N;
270  for (int i=0; i <array.cols(); i++) { // read N samples from each device which is requested
271  int ret=operator[](i).read(toRead, (void*)array.col(i).data());
272  if (ret<0){ // error
273  std::stringstream msg;
274  msg<<"Couldn't read the desired number of samples from device "<<i<<std::endl;
275  return IIODebug().evaluateError(IIODEVICE_READ_ERROR, msg.str());
276  } else
277  if (i==0){ // follow the lead of the first device
278  toRead=ret;
279  N-=ret;
280  //cout<<"read "<<ret<<" frames \t with "<<N<<" frames left\n";
281  }
282  }
283  }
284  return NO_ERROR;
285  }
286 
290  int enable(bool enable) {
291  if (getDeviceCnt()<1)
293  for (unsigned int i=0; i<getDeviceCnt(); i++)
294  operator[](i).enable(enable);
295  return NO_ERROR;
296  }
297 
302  if (getDeviceCnt()<1)
304  int chBufCnt=operator[](0).getChannelBufferCnt();
305  for (unsigned int i=1; i<getDeviceCnt(); i++)
306  if (operator[](i).getChannelBufferCnt()!=chBufCnt)
308  return chBufCnt;
309  }
310 
315  int setChannelBufferCnt(int chBufCnt){
316  if (getDeviceCnt()<1)
318  int chBufCntOrig=getChannelBufferCnt();
319  chBufCnt=operator[](0).setChannelBufferCnt(chBufCnt);
320  for (unsigned int i=1; i<getDeviceCnt(); i++)
321  if (operator[](i).setChannelBufferCnt(chBufCnt)!=chBufCnt){
322  setChannelBufferCnt(chBufCntOrig); // try to rewind ... may be dissasterous ! TODO remove recurrence here
324  }
325  return chBufCnt;
326  }
327 };
328 
329 const char *IIO::iioDir = "/sys/bus/iio/devices/";
330 
331 #endif // IIO_H_
int open(void)
Definition: IIO.H:156
size(signal)
int getChannelBufferCnt()
Definition: IIO.H:301
static const char * iioDir
The sys fs location of iio devcies "/sys/bus/iio/devices/".
Definition: IIO.H:73
int N
#define IIO_FRAEMSIZE_MISMATCH_ERROR
The channel frame sizes differ between devices.
Definition: IIOChannel.H:34
int getChFrameSize(void)
Definition: IIO.H:190
virtual int evaluateError(int errorNum)
Definition: Debug.H:132
void printInfo()
Definition: IIO.H:146
int getDevFrameSize(void)
Definition: IIO.H:205
#define IIO_BAD_DEVICE_NAME_ERROR
Error when the specified device name is bad or can&#39;t be found.
Definition: IIOChannel.H:25
int setChannelBufferCnt(int chBufCnt)
Definition: IIO.H:315
int findDevicesByChipName(std::string chipName)
Definition: IIO.H:97
int getReadArraySampleCount(Eigen::Array< TYPE, Eigen::Dynamic, Eigen::Dynamic > &array)
Definition: IIO.H:241
#define NO_ERROR
There is no error.
Definition: Debug.H:33
int read(uint N, const Eigen::Array< TYPE, Eigen::Dynamic, Eigen::Dynamic > &array)
Definition: IIO.H:254
#define IIODEVICE_CHBUFCNT_ERROR
One of the devices has a different buffer size to the other devices.
Definition: IIOChannel.H:41
The iio_channel_info structure is external.
Definition: IIO.H:72
uint getChCnt()
Definition: IIO.H:137
#define IIODEVICE_READ_ERROR
There was an error whilst reading from a device.
Definition: IIOChannel.H:38
int findAll(const std::vector< std::string > &dontInclude)
IIO()
Definition: IIO.H:88
unsigned int uint
Definition: Box.H:28
int getReadArray(uint N, Eigen::Array< TYPE, Eigen::Dynamic, Eigen::Dynamic > &array)
Definition: IIO.H:222
#define IIO_ARRAY_FRAME_MISMATCH_ERROR
The sample type of the provided array doesn&#39;t match the sample type of the devices.
Definition: IIOChannel.H:36
int enable(bool enable)
Definition: IIO.H:290
std::string findChipName(std::string devicePath)
Definition: IIO.H:79
virtual ~IIO()
Definition: IIO.H:89
int close(void)
Definition: IIO.H:179
#define IIO_ARRAY_SIZE_MISMATCH_ERROR
The provided array doesn&#39;t match the number of channels and requested samples.
Definition: IIOChannel.H:37
uint getDeviceCnt()
Definition: IIO.H:130
#define IIO_NODEVICES_ERROR
There are no devices.
Definition: IIOChannel.H:35
void keepWithPattern(const std::string pattern)
gtkIOStream: /tmp/gtkiostream/include/IIO/IIO.H Source File
GTK+ IOStream  Beta