00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023 #include <stdlib.h>
00024 #include <string.h>
00025 #include <unistd.h>
00026
00027 #include "ComediIO.hh"
00028
00029
00030 void clComediIO::SetError ()
00031 {
00032 if (cpErrorMsg != NULL)
00033 free(cpErrorMsg);
00034 cpErrorMsg = strdup(comedi_strerror(comedi_errno()));
00035 }
00036
00037
00038 bool clComediIO::PcmStart (int iSubDev, double *dpSampleRate, int iChannels,
00039 unsigned int *uipScanList, unsigned int uiListLength, bool bDither,
00040 bool bDoubleClock)
00041 {
00042 struct comedi_cmd_struct sComediCmd;
00043
00044 memset(&sComediCmd, 0x00, sizeof(sComediCmd));
00045 sComediCmd.subdev = (unsigned int) iSubDev;
00046 sComediCmd.flags = ((bDither) ? TRIG_DITHER : 0) | TRIG_DEGLITCH;
00047 sComediCmd.start_src = TRIG_NOW;
00048 sComediCmd.start_arg = 0;
00049 sComediCmd.scan_begin_src = TRIG_TIMER;
00050 sComediCmd.scan_begin_arg = (unsigned int)
00051 (1.0 / *dpSampleRate * 1.0e9 + 0.5);
00052
00053
00054 if (bDoubleClock)
00055 {
00056 sComediCmd.convert_src = TRIG_TIMER;
00057 sComediCmd.convert_arg = (unsigned int)
00058 (1.0 / (*dpSampleRate * iChannels) * 1.0e9 + 0.5);
00059 }
00060 else
00061 {
00062 sComediCmd.convert_src = TRIG_NONE;
00063 sComediCmd.convert_arg = 0;
00064 }
00065 sComediCmd.scan_end_src = TRIG_NONE;
00066 sComediCmd.scan_end_arg = 0;
00067 sComediCmd.stop_src = TRIG_NONE;
00068 sComediCmd.stop_arg = 0;
00069 sComediCmd.chanlist = uipScanList;
00070 sComediCmd.chanlist_len = uiListLength;
00071
00072 comedi_command_test(comediDev, &sComediCmd);
00073 *dpSampleRate =
00074 1.0 / ((double) sComediCmd.scan_begin_arg / 1.0e9);
00077 if (comedi_command(comediDev, &sComediCmd) != 0)
00078 {
00079 SetError();
00080 return false;
00081 }
00082 return true;
00083 }
00084
00085
00086 long clComediIO::PcmRead (sampl_t **ipDest, long lCount)
00087 {
00088 int iInSize;
00089 int iReadRes;
00090 int iBytesRead = 0;
00091 char *cpInBuf;
00092 sampl_t *ipInBuf;
00093
00094 iInSize = lCount * sizeof(sampl_t);
00095 ipInBuf = (sampl_t *) InBuf.Size(lCount * sizeof(sampl_t));
00096 cpInBuf = InBuf;
00097 *ipDest = ipInBuf;
00098 do
00099 {
00100 iReadRes = read(comedi_fileno(comediDev),
00101 &cpInBuf[iBytesRead], iInSize - iBytesRead);
00102 iBytesRead += iReadRes;
00103 } while (iBytesRead < iInSize && iReadRes >= 0);
00104 return (iBytesRead / sizeof(sampl_t));
00105 }
00106
00107
00108 clComediIO::clComediIO ()
00109 {
00110 cpErrorMsg = NULL;
00111 comediDev = NULL;
00112 iInSubDev = -1;
00113 }
00114
00115
00116 clComediIO::~clComediIO ()
00117 {
00118 Close();
00119 }
00120
00121
00122 bool clComediIO::Open (const char *cpDevice)
00123 {
00124 comediDev = comedi_open(cpDevice);
00125 if (comediDev == NULL)
00126 {
00127 SetError();
00128 return false;
00129 }
00130 return true;
00131 }
00132
00133
00134 bool clComediIO::Close ()
00135 {
00136 if (iInSubDev >= 0)
00137 {
00138 if (comedi_unlock(comediDev, (unsigned int) iInSubDev) != 0)
00139 {
00140 SetError();
00141 return false;
00142 }
00143 iInSubDev = -1;
00144 }
00145 if (comediDev != NULL)
00146 {
00147 if (comedi_close(comediDev) != 0)
00148 {
00149 SetError();
00150 return false;
00151 }
00152 comediDev = NULL;
00153 }
00154 if (cpErrorMsg != NULL)
00155 {
00156 free(cpErrorMsg);
00157 cpErrorMsg = NULL;
00158 }
00159 return true;
00160 }
00161
00162
00163 int clComediIO::GetSubdeviceCount ()
00164 {
00165 return comedi_get_n_subdevices(comediDev);
00166 }
00167
00168
00169 int clComediIO::GetVersionCode ()
00170 {
00171 int iRetVal;
00172
00173 iRetVal = comedi_get_version_code(comediDev);
00174 if (iRetVal < 0)
00175 SetError();
00176 return iRetVal;
00177 }
00178
00179
00180 const char *clComediIO::GetDriverName ()
00181 {
00182 return comedi_get_driver_name(comediDev);
00183 }
00184
00185
00186 const char *clComediIO::GetBoardName ()
00187 {
00188 return comedi_get_board_name(comediDev);
00189 }
00190
00191
00192 bool clComediIO::PcmInOpen ()
00193 {
00194 iInSubDev = comedi_get_read_subdevice(comediDev);
00195 if (iInSubDev < 0)
00196 {
00197 SetError();
00198 return false;
00199 }
00200 if (comedi_lock(comediDev, (unsigned int) iInSubDev) != 0)
00201 {
00202 iInSubDev = -1;
00203 SetError();
00204 return false;
00205 }
00206 iInMaxValue = comedi_get_maxdata(comediDev, (unsigned int) iInSubDev, 0);
00207 if (iInMaxValue == 0)
00208 {
00209 SetError();
00210 return false;
00211 }
00212 return true;
00213 }
00214
00215
00216 bool clComediIO::PcmInClose ()
00217 {
00218 if (iInSubDev >= 0)
00219 {
00220 if (comedi_unlock(comediDev, (unsigned int) iInSubDev) != 0)
00221 {
00222 SetError();
00223 return false;
00224 }
00225 iInSubDev = -1;
00226 }
00227 return true;
00228 }
00229
00230
00231 int clComediIO::PcmInGetChannelCount ()
00232 {
00233 int iRetVal;
00234
00235 iRetVal = comedi_get_n_channels(comediDev, (unsigned int) iInSubDev);
00236 if (iRetVal < 0)
00237 SetError();
00238 return iRetVal;
00239 }
00240
00241
00242 bool clComediIO::PcmInStart (double *dpSampleRate, int iChannels,
00243 double dRange, bool bDither, bool bDoubleClock)
00244 {
00245 int iRange;
00246 int iChanCntr;
00247 unsigned int *uipScanList;
00248
00249 iRange = comedi_find_range(comediDev, (unsigned int) iInSubDev, 0,
00250 UNIT_volt, -dRange, dRange);
00251 if (iRange < 0)
00252 {
00253 SetError();
00254 return false;
00255 }
00256 uipScanList = (unsigned int *)
00257 InScanList.Size(iChannels * sizeof(unsigned int));
00258 for (iChanCntr = 0; iChanCntr < iChannels; iChanCntr++)
00259 uipScanList[iChanCntr] = CR_PACK(iChanCntr, iRange, AREF_GROUND);
00260 return PcmStart(iInSubDev, dpSampleRate, iChannels, uipScanList,
00261 iChannels, bDither, bDoubleClock);
00262 }
00263
00264
00265 bool clComediIO::PcmInStop ()
00266 {
00267 if (comedi_cancel(comediDev, (unsigned int) iInSubDev) != 0)
00268 {
00269 SetError();
00270 return false;
00271 }
00272 return true;
00273 }
00274
00275
00276 long clComediIO::PcmInRead (float *fpDest, long lCount)
00277 {
00278 int iSampleCntr;
00279 long lReadRes;
00280 sampl_t *ipInBuf;
00281 float fScale;
00282
00283 fScale = 1.0f / iInMaxValue;
00284 lReadRes = PcmRead(&ipInBuf, lCount);
00285 if (lReadRes < 0)
00286 {
00287 SetError();
00288 return lReadRes;
00289 }
00290 for (iSampleCntr = 0; iSampleCntr < lReadRes; iSampleCntr++)
00291 fpDest[iSampleCntr] = (float) ipInBuf[iSampleCntr] * fScale;
00292 return lReadRes;
00293 }
00294
00295
00296 long clComediIO::PcmInRead (double *dpDest, long lCount)
00297 {
00298 int iSampleCntr;
00299 long lReadRes;
00300 sampl_t *ipInBuf;
00301 double dScale;
00302
00303 dScale = 1.0 / iInMaxValue;
00304 lReadRes = PcmRead(&ipInBuf, lCount);
00305 if (lReadRes < 0)
00306 {
00307 SetError();
00308 return lReadRes;
00309 }
00310 for (iSampleCntr = 0; iSampleCntr < lReadRes; iSampleCntr++)
00311 dpDest[iSampleCntr] = (double) ipInBuf[iSampleCntr] * dScale;
00312 return lReadRes;
00313 }
00314
00315
00316 bool clComediIO::PcmBufferSizeSet (unsigned int uiBufSize)
00317 {
00318
00319
00320
00321
00322
00323
00324 if (comedi_set_buffer_size(comediDev, (unsigned int) iInSubDev,
00325 uiBufSize) < 0)
00326 {
00327 SetError();
00328 return false;
00329 }
00330 return true;
00331 }
00332
00333
00334 int clComediIO::PcmBufferSizeGet ()
00335 {
00336 int iRetVal;
00337
00338 iRetVal = comedi_get_buffer_size(comediDev, (unsigned int) iInSubDev);
00339 if (iRetVal < 0)
00340 SetError();
00341 return iRetVal;
00342 }