![]() |
RTXI 1.3
|
00001 /* 00002 A C++ binding for comedilib. Requires the Boost C++ libraries. 00003 Copyright (C) 2006-2007 Frank Mori Hess <fmhess@users.sourceforge.net> 00004 00005 This program is free software; you can redistribute it and/or modify 00006 it under the terms of the GNU Lesser General Public License as published by 00007 the Free Software Foundation; either version 2 of the License, or 00008 (at your option) any later version. 00009 00010 This program is distributed in the hope that it will be useful, 00011 but WITHOUT ANY WARRANTY; without even the implied warranty of 00012 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00013 GNU General Public License for more details. 00014 00015 You should have received a copy of the GNU Lesser General Public License 00016 along with this program; if not, write to the Free Software 00017 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 00018 */ 00019 00020 #ifndef _COMEDILIB_WRAPPER_HPP 00021 #define _COMEDILIB_WRAPPER_HPP 00022 00023 #include <boost/shared_ptr.hpp> 00024 #include <comedilib.h> 00025 #include <cstring> 00026 #include <iostream> 00027 #include <sstream> 00028 #include <stdexcept> 00029 #include <string> 00030 #include <vector> 00031 00032 namespace comedi 00033 { 00034 class subdevice; 00035 00036 // wrapper for comedi_to_physical() 00037 class to_physical 00038 { 00039 public: 00040 to_physical() 00041 { 00042 memset(&_polynomial, 0, sizeof(_polynomial)); 00043 } 00044 to_physical(const comedi_polynomial_t &polynomial): 00045 _polynomial(polynomial) 00046 {} 00047 double operator()(lsampl_t data) const 00048 { 00049 return comedi_to_physical(data, &_polynomial); 00050 } 00051 private: 00052 comedi_polynomial_t _polynomial; 00053 }; 00054 00055 // wrapper for comedi_from_physical() 00056 class from_physical 00057 { 00058 public: 00059 from_physical() 00060 { 00061 memset(&_polynomial, 0, sizeof(_polynomial)); 00062 } 00063 from_physical(const comedi_polynomial_t &polynomial): 00064 _polynomial(polynomial) 00065 {} 00066 lsampl_t operator()(double physical_value) const 00067 { 00068 return comedi_from_physical(physical_value, &_polynomial); 00069 } 00070 private: 00071 comedi_polynomial_t _polynomial; 00072 }; 00073 00074 class device { 00075 public: 00076 device() {} 00077 device(const std::string &device_file) 00078 { 00079 this->open(device_file); 00080 } 00081 std::string board_name() const 00082 { 00083 const char *name = comedi_get_board_name(comedi_handle()); 00084 if(name == 0) 00085 { 00086 std::ostringstream message; 00087 message << __PRETTY_FUNCTION__ << ": comedi_get_board_name() failed."; 00088 std::cerr << message.str() << std::endl; 00089 comedi_perror("comedi_get_board_name"); 00090 throw std::runtime_error(message.str()); 00091 } 00092 return name; 00093 } 00094 int command_test(comedi_cmd *cmd) const 00095 { 00096 int retval = comedi_command_test(comedi_handle(), cmd); 00097 if(retval < 0) 00098 { 00099 std::ostringstream message; 00100 message << __PRETTY_FUNCTION__ << ": comedi_command_test() returned error."; 00101 std::cerr << message.str() << std::endl; 00102 comedi_perror("comedi_command_test"); 00103 throw std::runtime_error(message.str()); 00104 } 00105 return retval; 00106 } 00107 void command(comedi_cmd *cmd) const 00108 { 00109 int retval = comedi_command(comedi_handle(), cmd); 00110 if(retval < 0) 00111 { 00112 std::ostringstream message; 00113 message << __PRETTY_FUNCTION__ << ": comedi_command() failed, return value=" << retval << " ."; 00114 std::cerr << message.str() << std::endl; 00115 comedi_perror("comedi_command"); 00116 throw std::runtime_error(message.str()); 00117 } 00118 } 00119 std::string default_calibration_path() const 00120 { 00121 char *c_string_file_path = comedi_get_default_calibration_path(comedi_handle()); 00122 if(c_string_file_path == NULL) 00123 { 00124 comedi_perror("comedi_get_default_calibration_path"); 00125 throw std::runtime_error(__PRETTY_FUNCTION__); 00126 } 00127 std::string file_path = c_string_file_path; 00128 free(c_string_file_path); 00129 return file_path; 00130 } 00131 void do_insn(comedi_insn *instruction) const 00132 { 00133 int retval = comedi_do_insn(comedi_handle(), instruction); 00134 if(retval < 0) 00135 { 00136 std::ostringstream message; 00137 message << __PRETTY_FUNCTION__ << ": comedi_do_insn() failed."; 00138 std::cerr << message.str() << std::endl; 00139 comedi_perror("comedi_do_insn"); 00140 throw std::runtime_error(message.str()); 00141 } 00142 } 00143 std::string driver_name() const 00144 { 00145 const char *name = comedi_get_driver_name(comedi_handle()); 00146 if(name == 0) 00147 { 00148 std::ostringstream message; 00149 message << __PRETTY_FUNCTION__ << ": comedi_get_driver_name() failed."; 00150 std::cerr << message.str() << std::endl; 00151 comedi_perror("comedi_get_driver_name"); 00152 throw std::runtime_error(message.str()); 00153 } 00154 return name; 00155 } 00156 inline subdevice find_subdevice_by_type(int type, const subdevice *start_subdevice = 0) const; 00157 int fileno() const 00158 { 00159 int fd = comedi_fileno(comedi_handle()); 00160 if(fd < 0) 00161 { 00162 std::ostringstream message; 00163 message << __PRETTY_FUNCTION__ << ": comedi_fileno() failed."; 00164 std::cerr << message.str() << std::endl; 00165 comedi_perror("comedi_fileno"); 00166 throw std::runtime_error(message.str()); 00167 } 00168 return fd; 00169 } 00170 unsigned n_subdevices() const 00171 { 00172 int retval = comedi_get_n_subdevices(comedi_handle()); 00173 if(retval < 0) 00174 { 00175 std::ostringstream message; 00176 message << __PRETTY_FUNCTION__ << ": comedi_get_n_subdevices() failed."; 00177 std::cerr << message.str() << std::endl; 00178 comedi_perror("comedi_get_n_subdevices"); 00179 throw std::runtime_error(message.str()); 00180 } 00181 return retval; 00182 } 00183 void open(const std::string &device_file) 00184 { 00185 comedi_t *dev = comedi_open(device_file.c_str()); 00186 if(dev == 0) 00187 { 00188 std::ostringstream message; 00189 message << __PRETTY_FUNCTION__ << ": comedi_open() failed, with device file name: \"" << device_file << "\"."; 00190 std::cerr << message.str() << std::endl; 00191 comedi_perror("comedi_open"); 00192 throw std::runtime_error(message.str().c_str()); 00193 } 00194 _comedi_handle.reset(dev, &comedi_close); 00195 } 00196 private: 00197 friend class subdevice; 00198 00199 comedi_t* comedi_handle() const 00200 { 00201 if(_comedi_handle == 0) 00202 { 00203 std::ostringstream message; 00204 message << __PRETTY_FUNCTION__ << ": device not open."; 00205 std::cerr << message.str() << std::endl; 00206 throw std::invalid_argument(message.str()); 00207 } 00208 return _comedi_handle.get(); 00209 } 00210 00211 boost::shared_ptr<comedi_t> _comedi_handle; 00212 }; 00213 00214 class calibration 00215 { 00216 public: 00217 calibration() {} 00218 calibration(const device &dev) 00219 { 00220 init(dev.default_calibration_path()); 00221 } 00222 calibration(const std::string &file_path) 00223 { 00224 init(file_path); 00225 } 00226 const comedi_calibration_t* c_calibration() const 00227 { 00228 return _c_calibration.get(); 00229 } 00230 private: 00231 void init(const std::string &file_path) 00232 { 00233 comedi_calibration_t *cal = comedi_parse_calibration_file(file_path.c_str()); 00234 if(cal == NULL) 00235 { 00236 std::ostringstream message; 00237 message << __PRETTY_FUNCTION__ << ": comedi_parse_calibration_file() failed."; 00238 std::cerr << message.str() << std::endl; 00239 comedi_perror("comedi_parse_calibration_file"); 00240 throw std::runtime_error(message.str()); 00241 } 00242 _c_calibration.reset(cal, &comedi_cleanup_calibration); 00243 } 00244 boost::shared_ptr<comedi_calibration_t> _c_calibration; 00245 }; 00246 00247 class subdevice 00248 { 00249 public: 00250 subdevice(): _index(-1) 00251 {} 00252 subdevice(const device &dev, unsigned subdevice_index): 00253 _device(dev), _index(subdevice_index) 00254 { 00255 if(_index >= _device.n_subdevices()) 00256 { 00257 std::ostringstream message; 00258 message << __PRETTY_FUNCTION__ << ": invalid subdevice index."; 00259 std::cerr << message.str() << std::endl; 00260 throw std::invalid_argument(message.str()); 00261 } 00262 } 00263 void apply_hard_calibration(unsigned channel, unsigned range, unsigned aref, const calibration &cal) 00264 { 00265 if(cal.c_calibration() == 0) throw std::invalid_argument(__PRETTY_FUNCTION__); 00266 int retval = comedi_apply_parsed_calibration(comedi_handle(), index(), 00267 channel, range, aref, cal.c_calibration()); 00268 if(retval < 0) 00269 { 00270 comedi_perror("comedi_apply_parsed_calibration"); 00271 throw std::runtime_error(__PRETTY_FUNCTION__); 00272 } 00273 } 00274 void apply_hard_calibration(unsigned channel, unsigned range, unsigned aref) 00275 { 00276 apply_hard_calibration(channel, range, aref, calibration(dev())); 00277 } 00278 unsigned buffer_size() const 00279 { 00280 int retval = comedi_get_buffer_size(comedi_handle(), index()); 00281 if(retval < 0) 00282 { 00283 std::ostringstream message; 00284 message << __PRETTY_FUNCTION__ << ": comedi_get_buffer_size() failed."; 00285 std::cerr << message.str() << std::endl; 00286 comedi_perror("comedi_get_buffer_size"); 00287 throw std::runtime_error(message.str()); 00288 } 00289 return retval; 00290 } 00291 void cancel() 00292 { 00293 int retval = comedi_cancel(comedi_handle(), index()); 00294 if(retval < 0) 00295 { 00296 std::ostringstream message; 00297 message << __PRETTY_FUNCTION__ << ": comedi_cancel() failed, return value=" << retval << " ."; 00298 std::cerr << message.str() << std::endl; 00299 comedi_perror("comedi_cancel"); 00300 throw std::runtime_error(message.str()); 00301 } 00302 } 00303 lsampl_t data_read(unsigned channel, unsigned range, unsigned aref) const 00304 { 00305 lsampl_t value; 00306 int retval = comedi_data_read(comedi_handle(), index(), channel, range, aref, &value); 00307 if(retval < 0) 00308 { 00309 std::ostringstream message; 00310 message << __PRETTY_FUNCTION__ << ": comedi_data_read() failed, return value=" << retval << " ."; 00311 std::cerr << message.str() << std::endl; 00312 comedi_perror("comedi_data_read"); 00313 throw std::runtime_error(message.str()); 00314 } 00315 return value; 00316 } 00317 std::vector<lsampl_t> data_read_n(unsigned channel, unsigned range, unsigned aref, unsigned num_samples) const 00318 { 00319 std::vector<lsampl_t> values(num_samples); 00320 int retval = comedi_data_read_n(comedi_handle(), index(), channel, range, aref, &values.at(0), values.size()); 00321 if(retval < 0) 00322 { 00323 std::ostringstream message; 00324 message << __PRETTY_FUNCTION__ << ": comedi_data_read_n() failed, return value=" << retval << " ."; 00325 std::cerr << message.str() << std::endl; 00326 comedi_perror("comedi_data_read_n"); 00327 throw std::runtime_error(message.str()); 00328 } 00329 return values; 00330 } 00331 void data_read_hint(unsigned channel, unsigned range, unsigned aref) const 00332 { 00333 int ret = comedi_data_read_hint(comedi_handle(), index(), channel, range, aref); 00334 if(ret < 0) 00335 { 00336 std::ostringstream message; 00337 message << __PRETTY_FUNCTION__ << ": comedi_data_read_hint() failed, return value = " << ret << " ."; 00338 std::cerr << message.str() << std::endl; 00339 comedi_perror("comedi_data_read_hint"); 00340 throw std::runtime_error(message.str()); 00341 } 00342 } 00343 void data_write(unsigned channel, unsigned range, unsigned aref, lsampl_t data) const 00344 { 00345 int retval = comedi_data_write(comedi_handle(), index(), channel, range, aref, data); 00346 if(retval < 0) 00347 { 00348 std::ostringstream message; 00349 message << __PRETTY_FUNCTION__ << ": comedi_data_write() failed."; 00350 std::cerr << message.str() << std::endl; 00351 comedi_perror("comedi_data_write"); 00352 throw std::runtime_error(message.str()); 00353 } 00354 } 00355 device dev() const {return _device;} 00356 void dio_bitfield2(unsigned write_mask, unsigned *bits, unsigned base_channel) 00357 { 00358 int retval = comedi_dio_bitfield2(comedi_handle(), index(), 00359 write_mask, bits, base_channel); 00360 if(retval < 0) 00361 { 00362 std::ostringstream message; 00363 message << __PRETTY_FUNCTION__ << ": comedi_dio_bitfield2() failed."; 00364 std::cerr << message.str() << std::endl; 00365 comedi_perror("comedi_dio_bitfield2"); 00366 throw std::runtime_error(message.str()); 00367 } 00368 } 00369 void dio_config(unsigned channel, enum comedi_io_direction direction) 00370 { 00371 int retval = comedi_dio_config(comedi_handle(), index(), channel, direction); 00372 if(retval < 0) 00373 { 00374 std::ostringstream message; 00375 message << __PRETTY_FUNCTION__ << ": comedi_dio_config() failed."; 00376 std::cerr << message.str() << std::endl; 00377 comedi_perror("comedi_dio_config"); 00378 throw std::runtime_error(message.str()); 00379 } 00380 } 00381 unsigned find_range(unsigned channel, unsigned unit, double min, double max) 00382 { 00383 int retval = comedi_find_range(comedi_handle(), index(), channel, 00384 unit, min, max); 00385 if(retval < 0) 00386 { 00387 std::ostringstream message; 00388 message << __PRETTY_FUNCTION__ << ": comedi_find_range() failed."; 00389 std::cerr << message.str() << std::endl; 00390 comedi_perror("comedi_find_range"); 00391 throw std::runtime_error(message.str()); 00392 } 00393 return retval; 00394 } 00395 unsigned flags() const 00396 { 00397 int retval = comedi_get_subdevice_flags(comedi_handle(), index()); 00398 if(retval < 0) 00399 { 00400 std::ostringstream message; 00401 message << __PRETTY_FUNCTION__ << ": comedi_get_subdevice_flags() failed."; 00402 std::cerr << message.str() << std::endl; 00403 comedi_perror("comedi_get_subdevice_flags"); 00404 throw std::runtime_error(message.str()); 00405 } 00406 return retval; 00407 } 00408 unsigned get_buffer_contents() const 00409 { 00410 int retval = comedi_get_buffer_contents(comedi_handle(), index()); 00411 if(retval < 0) 00412 { 00413 std::ostringstream message; 00414 message << __PRETTY_FUNCTION__ << ": comedi_get_buffer_contents() failed."; 00415 std::cerr << message.str() << std::endl; 00416 comedi_perror("comedi_get_buffer_contents"); 00417 throw std::runtime_error(message.str()); 00418 } 00419 return retval; 00420 } 00421 void get_clock_source(unsigned *clock, unsigned *period_ns) const 00422 { 00423 int retval = comedi_get_clock_source(comedi_handle(), index(), clock, period_ns); 00424 if(retval < 0) 00425 { 00426 std::ostringstream message; 00427 message << __PRETTY_FUNCTION__ << ": comedi_get_clock_source() failed."; 00428 std::cerr << message.str() << std::endl; 00429 comedi_perror("comedi_get_clock_source"); 00430 throw std::runtime_error(message.str()); 00431 } 00432 } 00433 unsigned get_routing(unsigned channel) const 00434 { 00435 unsigned routing = 0; 00436 int retval = comedi_get_routing(comedi_handle(), index(), channel, &routing); 00437 if(retval < 0) 00438 { 00439 std::ostringstream message; 00440 message << __PRETTY_FUNCTION__ << ": comedi_get_routing() failed."; 00441 std::cerr << message.str() << std::endl; 00442 comedi_perror("comedi_get_routing"); 00443 throw std::runtime_error(message.str()); 00444 } 00445 return routing; 00446 } 00447 comedi_polynomial_t hardcal_converter(unsigned channel, unsigned range, 00448 enum comedi_conversion_direction direction) const 00449 { 00450 comedi_polynomial_t result; 00451 int retval = comedi_get_hardcal_converter(comedi_handle(), index(), 00452 channel, range, direction, &result); 00453 if(retval < 0) 00454 { 00455 comedi_perror("comedi_get_hardcal_converter"); 00456 throw std::runtime_error(__PRETTY_FUNCTION__); 00457 } 00458 return result; 00459 } 00460 unsigned hardware_buffer_size(enum comedi_io_direction direction) const 00461 { 00462 int retval = comedi_get_hardware_buffer_size(comedi_handle(), index(), direction); 00463 if(retval < 0) 00464 { 00465 std::ostringstream message; 00466 message << __PRETTY_FUNCTION__ << ": comedi_get_hardware_buffer_size() failed."; 00467 std::cerr << message.str() << std::endl; 00468 comedi_perror("comedi_get_hardware_buffer_size"); 00469 throw std::runtime_error(message.str()); 00470 } 00471 return retval; 00472 } 00473 unsigned index() const {return _index;}; 00474 void internal_trigger(unsigned trig_num) const 00475 { 00476 int retval = comedi_internal_trigger(comedi_handle(), index(), trig_num); 00477 if(retval < 0) 00478 { 00479 std::ostringstream message; 00480 message << __PRETTY_FUNCTION__ << ": comedi_internal_trigger() failed."; 00481 std::cerr << message.str() << std::endl; 00482 comedi_perror("comedi_internal_trigger"); 00483 throw std::runtime_error(message.str()); 00484 } 00485 } 00486 unsigned max_buffer_size() const 00487 { 00488 int retval = comedi_get_max_buffer_size(comedi_handle(), index()); 00489 if(retval < 0) 00490 { 00491 std::ostringstream message; 00492 message << __PRETTY_FUNCTION__ << ": comedi_get_max_buffer_size() failed."; 00493 std::cerr << message.str() << std::endl; 00494 comedi_perror("comedi_get_max_buffer_size"); 00495 throw std::runtime_error(message.str()); 00496 } 00497 return retval; 00498 } 00499 unsigned n_channels() const 00500 { 00501 int retval = comedi_get_n_channels(comedi_handle(), index()); 00502 if(retval < 0) 00503 { 00504 std::ostringstream message; 00505 message << __PRETTY_FUNCTION__ << ": comedi_get_n_channels() failed."; 00506 std::cerr << message.str() << std::endl; 00507 comedi_perror("comedi_get_n_channels"); 00508 throw std::runtime_error(message.str()); 00509 } 00510 return retval; 00511 } 00512 unsigned n_ranges(unsigned channel = 0) const 00513 { 00514 int retval = comedi_get_n_ranges(comedi_handle(), index(), channel); 00515 if(retval < 0) 00516 { 00517 std::ostringstream message; 00518 message << __PRETTY_FUNCTION__ << ": comedi_get_n_ranges() failed."; 00519 std::cerr << message.str() << std::endl; 00520 comedi_perror("comedi_get_n_ranges"); 00521 throw std::runtime_error(message.str()); 00522 } 00523 return retval; 00524 } 00525 lsampl_t max_data(unsigned channel = 0) const 00526 { 00527 lsampl_t value = comedi_get_maxdata(comedi_handle(), index(), channel); 00528 if(value == 0) 00529 { 00530 std::ostringstream message; 00531 message << __PRETTY_FUNCTION__ << ": comedi_get_maxdata() failed."; 00532 std::cerr << message.str() << std::endl; 00533 comedi_perror("comedi_get_maxdata"); 00534 throw std::runtime_error(message.str()); 00535 } 00536 return value; 00537 } 00538 const comedi_range* range(unsigned channel, unsigned range_index) const 00539 { 00540 comedi_range *cRange = comedi_get_range(comedi_handle(), index(), channel, range_index); 00541 if(cRange == 0) 00542 { 00543 std::ostringstream message; 00544 message << __PRETTY_FUNCTION__ << ": comedi_get_range() failed."; 00545 std::cerr << message.str() << std::endl; 00546 comedi_perror("comedi_get_range"); 00547 throw std::runtime_error(message.str()); 00548 } 00549 return cRange; 00550 } 00551 void reset() const 00552 { 00553 int retval = comedi_reset(comedi_handle(), index()); 00554 if(retval < 0) 00555 { 00556 std::ostringstream message; 00557 message << __PRETTY_FUNCTION__ << ": comedi_reset() failed."; 00558 std::cerr << message.str() << std::endl; 00559 comedi_perror("comedi_reset"); 00560 throw std::runtime_error(message.str()); 00561 } 00562 } 00563 void set_buffer_size(unsigned num_bytes) const 00564 { 00565 int retval = comedi_set_buffer_size(comedi_handle(), index(), num_bytes); 00566 if(retval < 0) 00567 { 00568 std::ostringstream message; 00569 message << __PRETTY_FUNCTION__ << ": comedi_set_buffer_size() failed."; 00570 std::cerr << message.str() << std::endl; 00571 comedi_perror("comedi_set_buffer_size"); 00572 throw std::runtime_error(message.str()); 00573 } 00574 } 00575 void set_clock_source(unsigned clock, unsigned period_ns) 00576 { 00577 int retval = comedi_set_clock_source(comedi_handle(), index(), clock, period_ns); 00578 if(retval < 0) 00579 { 00580 std::ostringstream message; 00581 message << __PRETTY_FUNCTION__ << ": comedi_set_clock_source() failed."; 00582 std::cerr << message.str() << std::endl; 00583 comedi_perror("comedi_set_clock_source"); 00584 throw std::runtime_error(message.str()); 00585 } 00586 } 00587 void set_counter_mode(unsigned channel, unsigned mode_bits) 00588 { 00589 int retval = comedi_set_counter_mode(comedi_handle(), index(), channel, mode_bits); 00590 if(retval < 0) 00591 { 00592 std::ostringstream message; 00593 message << __PRETTY_FUNCTION__ << ": comedi_set_counter_mode() failed."; 00594 std::cerr << message.str() << std::endl; 00595 comedi_perror("comedi_set_counter_mode"); 00596 throw std::runtime_error(message.str()); 00597 } 00598 } 00599 void set_gate_source(unsigned channel, unsigned gate_index, unsigned gate_source) 00600 { 00601 int retval = comedi_set_gate_source(comedi_handle(), index(), channel, gate_index, gate_source); 00602 if(retval < 0) 00603 { 00604 std::ostringstream message; 00605 message << __PRETTY_FUNCTION__ << ": comedi_set_gate_source() failed."; 00606 std::cerr << message.str() << std::endl; 00607 comedi_perror("comedi_set_gate_source"); 00608 throw std::runtime_error(message.str()); 00609 } 00610 } 00611 void set_max_buffer_size(unsigned num_bytes) const 00612 { 00613 int retval = comedi_set_max_buffer_size(comedi_handle(), index(), num_bytes); 00614 if(retval < 0) 00615 { 00616 std::ostringstream message; 00617 message << __PRETTY_FUNCTION__ << ": comedi_set_max_buffer_size() failed."; 00618 std::cerr << message.str() << std::endl; 00619 comedi_perror("comedi_set_max_buffer_size"); 00620 throw std::runtime_error(message.str()); 00621 } 00622 } 00623 void set_routing(unsigned channel, unsigned routing) 00624 { 00625 int retval = comedi_set_routing(comedi_handle(), index(), channel, routing); 00626 if(retval < 0) 00627 { 00628 std::ostringstream message; 00629 message << __PRETTY_FUNCTION__ << ": comedi_set_routing() failed."; 00630 std::cerr << message.str() << std::endl; 00631 comedi_perror("comedi_set_routing"); 00632 throw std::runtime_error(message.str()); 00633 } 00634 } 00635 comedi_polynomial_t softcal_converter(unsigned channel, unsigned range, 00636 enum comedi_conversion_direction direction, const calibration &cal) const 00637 { 00638 if(cal.c_calibration() == 0) throw std::invalid_argument(__PRETTY_FUNCTION__); 00639 comedi_polynomial_t result; 00640 int retval = comedi_get_softcal_converter(index(), 00641 channel, range, direction, cal.c_calibration(), &result); 00642 if(retval < 0) 00643 { 00644 comedi_perror("comedi_get_softcal_converter"); 00645 throw std::runtime_error(__PRETTY_FUNCTION__); 00646 } 00647 return result; 00648 } 00649 comedi_subdevice_type subdevice_type() const 00650 { 00651 int retval = comedi_get_subdevice_type(comedi_handle(), index()); 00652 if(retval < 0) 00653 { 00654 std::ostringstream message; 00655 message << __PRETTY_FUNCTION__ << ": comedi_get_subdevice_type() failed."; 00656 std::cerr << message.str() << std::endl; 00657 comedi_perror("comedi_get_subdevice_type"); 00658 throw std::runtime_error(message.str()); 00659 } 00660 return comedi_subdevice_type(retval); 00661 } 00662 private: 00663 comedi_t* comedi_handle() const {return dev().comedi_handle();} 00664 00665 device _device; 00666 unsigned _index; 00667 }; 00668 00669 subdevice device::find_subdevice_by_type(int type, const subdevice *start_subdevice) const 00670 { 00671 unsigned start_index; 00672 if(start_subdevice) start_index = start_subdevice->index() + 1; 00673 else start_index = 0; 00674 int subdev = comedi_find_subdevice_by_type(comedi_handle(), type, start_index); 00675 if(subdev < 0) 00676 { 00677 std::ostringstream message; 00678 message << __PRETTY_FUNCTION__ << ": failed to find subdevice of type " << type << " ."; 00679 std::cerr << message.str() << std::endl; 00680 comedi_perror("comedi_find_subdevice_by_type"); 00681 throw std::runtime_error(message.str()); 00682 } 00683 return subdevice(*this, subdev); 00684 } 00685 }; 00686 00687 #endif // _COMEDILIB_WRAPPER_HPP