TOBI SignalServer
0.1
|
00001 /* 00002 This file is part of the TOBI SignalServer. 00003 00004 Commercial Usage 00005 Licensees holding valid Graz University of Technology Commercial 00006 licenses may use this file in accordance with the Graz University 00007 of Technology Commercial License Agreement provided with the 00008 Software or, alternatively, in accordance with the terms contained in 00009 a written agreement between you and Graz University of Technology. 00010 00011 -------------------------------------------------- 00012 00013 GNU General Public License Usage 00014 Alternatively, this file may be used under the terms of the GNU 00015 General Public License version 3.0 as published by the Free Software 00016 Foundation and appearing in the file gpl.txt included in the 00017 packaging of this file. Please review the following information to 00018 ensure the GNU General Public License version 3.0 requirements will be 00019 met: http://www.gnu.org/copyleft/gpl.html. 00020 00021 In case of GNU General Public License Usage ,the TOBI SignalServer 00022 is distributed in the hope that it will be useful, 00023 but WITHOUT ANY WARRANTY; without even the implied warranty of 00024 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00025 GNU General Public License for more details. 00026 00027 You should have received a copy of the GNU General Public License 00028 along with the TOBI SignalServer. If not, see <http://www.gnu.org/licenses/>. 00029 00030 Copyright 2010 Graz University of Technology 00031 Contact: SignalServer@tobi-project.org 00032 */ 00033 00038 #include "hardware/dataq.h" 00039 #include "extern/include/dataq/err_codes.h" 00040 00041 00042 #include <boost/asio/error.hpp> 00043 #include <boost/lexical_cast.hpp> 00044 #include <boost/format.hpp> 00045 #include <boost/current_function.hpp> 00046 #include <math.h> 00047 #include <iostream> 00048 00049 using boost::lexical_cast; 00050 using boost::bad_lexical_cast; 00051 using std::string; 00052 using std::cout; 00053 using std::cerr; 00054 using std::endl; 00055 00056 namespace tobiss 00057 { 00058 00059 const unsigned int DataQ::DMA_IN_SIZ = 0xF000; 00060 const unsigned int DataQ::RING_BUFFER_SIZE = 512; 00061 00062 const std::string DataQ::hw_dataq_range_("range"); 00063 const std::string DataQ::hw_dataq_bipolar_("bipolar"); 00064 const std::string DataQ::hw_dataq_value_("value"); 00065 00066 static const unsigned int DI_720_MAX_SUPPORTED_CH = 32; 00067 static const unsigned int DI_720_MIN_BURST_COUNT = 80; // --> 200000 Hz (64 lt. DataQ SDK ... 250000Hz) 00068 static const unsigned int DI_720_MAX_BURST_COUNT = 32000; // --> 500 Hz (32767 lt. DataQ SDK ... 488Hz) 00069 static const unsigned int DI_720_BURST_RATE_VALUE = 16000000; 00070 static const unsigned int DI_720_NR_VOLTAGE_RANGES = 4; 00071 static const double DI_720_VOLTAGE_RANGES[DI_720_NR_VOLTAGE_RANGES] = {10, 5, 2.5, 1.25}; 00072 00073 const HWThreadBuilderTemplateRegistratorWithoutIOService<DataQ> DataQ::factory_registrator_ ("DI-720"); 00074 00075 //----------------------------------------------------------------------------- 00076 00077 DataQ::DataQ(ticpp::Iterator<ticpp::Element> hw) 00078 : acq_thread_(0), dataq_dev_ptr_(0), dev_nr_(0), dev_buffer_(0), device_opened_(0), 00079 acqu_running_(0), burst_rate_count_(0), last_pos_(0), inlist_ptr_(0), 00080 buffer_(RING_BUFFER_SIZE), sleep_timer_(io_service_), sleep_time_(0) 00081 { 00082 #ifdef DEBUG 00083 std::cout << "DataQ: Constructor" << std::endl; 00084 #endif 00085 00086 00087 dataq_dev_ptr_ = new DataQWrapper("di720nt.dll"); 00088 00089 setType("DataQ -- DI-720"); 00090 gain_index_.resize(1,0); 00091 bipolar_list_.resize(1,0); 00092 v_max_.resize(1, DI_720_VOLTAGE_RANGES[0] ); 00093 v_min_.resize(1, DI_720_VOLTAGE_RANGES[0] *(-1) ); 00094 setHardware(hw); 00095 00096 burst_rate_count_ = DI_720_BURST_RATE_VALUE/(nr_ch_ * fs_); 00097 if(burst_rate_count_ > DI_720_MAX_BURST_COUNT) 00098 throw(std::invalid_argument("Burst rate too low -- choose a sampling rate > " 00099 + boost::lexical_cast<std::string>(DI_720_BURST_RATE_VALUE/(nr_ch_*DI_720_MAX_BURST_COUNT)) 00100 +" or increase the number of channels!")); 00101 00102 if(burst_rate_count_ < DI_720_MIN_BURST_COUNT) 00103 throw(std::invalid_argument("Burst rate too high -- choose a sampling rate < " 00104 + boost::lexical_cast<std::string>(DI_720_BURST_RATE_VALUE/(nr_ch_*DI_720_MIN_BURST_COUNT)) 00105 +" or reduce the number of channels!")); 00106 00107 sleep_time_ = boost::posix_time::microseconds(1000000/fs_); 00108 00109 try 00110 { 00111 openDev(true); 00112 setInList(); 00113 setDaqMode(); 00114 //dataq_dev_ptr_->di_maximum_rate(40000); 00115 00116 struct di_outlist_struct outlist[16] = {0}; 00117 checkErrorCode( dataq_dev_ptr_->di_outlist(outlist), true ); 00118 00119 //std::cout << " Burst rate: " << DI_720_BURST_RATE_VALUE/burst_rate_count_ << ", Burst rate count: " << burst_rate_count_ << ", Fs: " << fs_ << std::endl; 00120 checkErrorCode( dataq_dev_ptr_->di_burst_rate(burst_rate_count_), true ); 00121 00122 dev_buffer_ = dataq_dev_ptr_->di_buffer_alloc(0, DMA_IN_SIZ); 00123 if(!dev_buffer_) 00124 { 00125 closeDev(true); 00126 throw(std::runtime_error("Failed to allocate buffer!")); 00127 } 00128 VirtualLock(dev_buffer_,(unsigned)DMA_IN_SIZ*2); 00129 00130 #ifdef DEBUG 00131 //checkErrorCode(dataq_dev_ptr_->di_info( &info_ ), true); 00132 //printDataQInfo(); 00133 #endif 00134 00135 data_.init(blocks_ , nr_ch_ , channel_types_); 00136 } 00137 catch(...) 00138 { 00139 closeDev(false); 00140 throw; 00141 } 00142 } 00143 00144 //----------------------------------------------------------------------------- 00145 00146 DataQ::~DataQ() 00147 { 00148 #ifdef DEBUG 00149 std::cout << "DataQ: Destructor" << std::endl << std::flush; 00150 #endif 00151 00152 VirtualLock(dev_buffer_,(unsigned)DMA_IN_SIZ*2); 00153 checkErrorCode(dataq_dev_ptr_->di_buffer_free(0), false); 00154 dev_buffer_ = 0; 00155 00156 closeDev(false); 00157 if(dataq_dev_ptr_) 00158 delete dataq_dev_ptr_; 00159 dataq_dev_ptr_ = 0; 00160 00161 if(inlist_ptr_) 00162 delete[] inlist_ptr_; 00163 inlist_ptr_ = 0; 00164 00165 } 00166 00167 //----------------------------------------------------------------------------- 00168 00169 SampleBlock<double> DataQ::getSyncData() 00170 { 00171 #ifdef DEBUG 00172 std::cout << "DataQ: getSyncData" << std::endl << std::flush; 00173 #endif 00174 00175 while((buffer_.getNumAvail() < (nr_ch_*blocks_) ) && acqu_running_) 00176 Sleep(1); 00177 // { 00178 // sleep_timer_.expires_from_now(sleep_time_, error_); 00179 // if(error_) 00180 // std::cerr << BOOST_CURRENT_FUNCTION << std::endl; 00181 00182 // sleep_timer_.wait(); 00183 // } 00184 00185 if(!acqu_running_) 00186 return(data_); 00187 00188 std::vector<double> vals(nr_ch_); 00189 short val = 0; 00190 data_.reset(); 00191 for(unsigned int m = 0; m < blocks_; m++) 00192 { 00193 for(unsigned int n = 0; n < nr_ch_; n++) 00194 { 00195 buffer_.getNext_blocking(&val); 00196 vals[n] = getVoltageValue(val, n); 00197 //file_stream_ << vals[n] << ", "; 00198 } 00199 00200 data_.appendBlock(vals,1); 00201 } 00202 return(data_); 00203 } 00204 00205 //----------------------------------------------------------------------------- 00206 00207 SampleBlock<double> DataQ::getAsyncData() 00208 { 00209 throw(std::runtime_error("DataQ::getAsyncData -- Asynchronous operation as slave not supported yet!")); 00210 return(data_); 00211 } 00212 00213 //----------------------------------------------------------------------------- 00214 00215 void DataQ::run() 00216 { 00217 #ifdef DEBUG 00218 std::cout << "DataQ: run()" << std::endl; 00219 #endif 00220 00221 // struct di_inlist_struct inlist[256] = {0}; 00222 //for(int i = 0; i < 1; i++) 00223 //{ 00224 // inlist[i].chan = i; 00225 // inlist[i].gain = 0; 00226 // inlist[i].ave = 1; 00227 // inlist[i].counter = 400 - 1; 00228 //} 00229 00230 //struct di_outlist_struct outlist[16] = {0}; 00231 //checkErrorCode( dataq_dev_ptr_->di_inlist(inlist), true ); 00232 //checkErrorCode( dataq_dev_ptr_->di_outlist(outlist), true ); 00233 00234 startAcqu(true); 00235 acq_thread_ = new boost::thread( boost::bind(&DataQ::acquireData, this)); 00236 } 00237 00238 //----------------------------------------------------------------------------- 00239 00240 void DataQ::stop() 00241 { 00242 #ifdef DEBUG 00243 std::cout << "DataQ: stop" << std::endl; 00244 #endif 00245 00246 stopAcqu(true); 00247 // boost::chrono::duration<long long, boost::nano> dur = boost::chrono::system_clock::now() - chrono_start_; 00248 00249 // boost::chrono::duration<double> sec = dur; 00250 00251 // std::cout << " Spent " << dur << " ns acquiring from DataQ!" << std::endl; 00252 // std::cout << " ( sec: " << sec << " )" << std::endl; 00253 // std::cout << " ... acquired " << iteration_ << " samples from "<< nr_ch_ << " channel(s)." << std::endl; 00254 // std::cout << " --> estimated fs: " << iteration_/sec.count() << std::endl; 00255 } 00256 00257 //----------------------------------------------------------------------------- 00258 00259 void DataQ::setDeviceSettings(ticpp::Iterator<ticpp::Element>const &father) 00260 { 00261 #ifdef DEBUG 00262 std::cout << "DataQ: setDeviceSettings" << std::endl; 00263 #endif 00264 00265 ticpp::Iterator<ticpp::Element> elem(father->FirstChildElement(hw_fs_,true)); 00266 setSamplingRate(elem); 00267 00268 elem = father->FirstChildElement(hw_channels_,false); 00269 if(elem != elem.end()) 00270 setDeviceChannels(elem); 00271 00272 gain_index_.resize(nr_ch_,0); 00273 bipolar_list_.resize(nr_ch_,0); 00274 v_max_.resize(nr_ch_, DI_720_VOLTAGE_RANGES[0] ); 00275 v_min_.resize(nr_ch_, DI_720_VOLTAGE_RANGES[0] *(-1) ); 00276 00277 elem = father->FirstChildElement(hw_blocksize_,false); 00278 if(elem != elem.end()) 00279 setBlocks(elem); 00280 00281 elem = father->FirstChildElement(hw_dataq_range_,false); 00282 if(elem != elem.end()) 00283 setDeviceRange(elem); 00284 00285 elem = father->FirstChildElement(hw_dataq_bipolar_,false); 00286 if(elem != elem.end()) 00287 setDeviceBipolar(elem); 00288 00289 } 00290 00291 //----------------------------------------------------------------------------- 00292 00293 void DataQ::setChannelSettings(ticpp::Iterator<ticpp::Element>const &father) 00294 { 00295 #ifdef DEBUG 00296 std::cout << "DataQ: setChannelSettings" << std::endl; 00297 #endif 00298 00299 ticpp::Iterator<ticpp::Element> elem(father->FirstChildElement(hw_chset_sel_,false)); 00300 if (elem != elem.end()) 00301 setChannelSelection(elem); 00302 00303 00304 gain_index_.resize(nr_ch_,gain_index_.at(0)); 00305 bipolar_list_.resize(nr_ch_,bipolar_list_.at(0)); 00306 v_max_.resize(nr_ch_, v_max_.at(0) ); 00307 v_min_.resize(nr_ch_, v_min_.at(0) ); 00308 00309 elem = father->FirstChildElement(hw_dataq_range_,false); 00310 if(elem != elem.end()) 00311 setChannelRange(elem); 00312 00313 elem = father->FirstChildElement(hw_dataq_bipolar_,false); 00314 if(elem != elem.end()) 00315 setChannelBipolar(elem); 00316 } 00317 00318 //----------------------------------------------------------------------------- 00319 00320 void DataQ::setHardware(ticpp::Iterator<ticpp::Element>const &hw) 00321 { 00322 #ifdef DEBUG 00323 std::cout << "DataQ: setHardware" << std::endl; 00324 #endif 00325 00326 checkMandatoryHardwareTags(hw); 00327 ticpp::Iterator<ticpp::Element> ds(hw->FirstChildElement(hw_devset_, true)); 00328 00329 setDeviceSettings(ds); 00330 00331 ticpp::Iterator<ticpp::Element> cs(hw->FirstChildElement(hw_chset_, false)); 00332 if (cs != cs.end()) 00333 { 00334 for(ticpp::Iterator<ticpp::Element> it(cs); ++it != it.end(); ) 00335 if(it->Value() == hw_chset_) 00336 { 00337 std::string ex_str(type_ + " -- "); 00338 ex_str += "Multiple channel_settings found!"; 00339 throw(std::invalid_argument(ex_str)); 00340 } 00341 setChannelSettings(cs); 00342 } 00343 checkChannels(); 00344 checkBiploarConfig(); 00345 } 00346 00347 //----------------------------------------------------------------------------- 00348 00349 int DataQ::openDev(bool throw_on_error) 00350 { 00351 #ifdef DEBUG 00352 std::cout << "DataQ: openDev" << std::endl; 00353 #endif 00354 00355 if(device_opened_) 00356 return 0; 00357 00358 int ec = checkErrorCode( dataq_dev_ptr_->di_open(dev_nr_), throw_on_error ); 00359 device_opened_ = (!ec); 00360 return(ec); 00361 00362 // if( error_code == DI_ALREADY_OPEN_ERR) 00363 // { 00364 // std::cerr << "Device already running --> closing!" << std::endl; 00365 // dataq_dev.di_close(); 00366 // checkErrorCode(dataq_dev, dataq_dev.di_open(0) ); 00367 // return; 00368 // } 00369 } 00370 00371 //----------------------------------------------------------------------------- 00372 00373 int DataQ::closeDev(bool throw_on_error) 00374 { 00375 #ifdef DEBUG 00376 std::cout << "DataQ: closeDev" << std::endl; 00377 #endif 00378 00379 if(!device_opened_) 00380 return 0; 00381 00382 stopAcqu(throw_on_error); 00383 00384 int ec = checkErrorCode( dataq_dev_ptr_->di_close(), throw_on_error ); 00385 device_opened_ = (ec); 00386 return( ec ); 00387 } 00388 00389 //----------------------------------------------------------------------------- 00390 00391 int DataQ::startAcqu(bool throw_on_error) 00392 { 00393 #ifdef DEBUG 00394 std::cout << "DataQ: startAcqu-- running: " << acqu_running_ << std::endl; 00395 #endif 00396 00397 if( acqu_running_ ) 00398 return 0; 00399 00400 int ec = checkErrorCode(dataq_dev_ptr_->di_start_scan(), throw_on_error); 00401 acqu_running_ = (!ec); 00402 return( ec ); 00403 } 00404 00405 //----------------------------------------------------------------------------- 00406 00407 int DataQ::stopAcqu(bool throw_on_error) 00408 { 00409 #ifdef DEBUG 00410 std::cout << "DataQ: stopAcqu -- running: " << acqu_running_ << std::endl; 00411 #endif 00412 00413 if( !acqu_running_ ) 00414 return 0; 00415 00416 acqu_running_ = 0; 00417 acq_thread_->interrupt(); 00418 00419 while(buffer_.getNumAvail() ) 00420 buffer_.dropOldest(); 00421 00422 00423 Sleep(10); 00424 std::cout << "DataQ: stopAcqu -- waiting to join " << std::endl; 00425 acq_thread_->join(); 00426 std::cout << "DataQ: stopAcqu -- joined " << std::endl; 00427 00428 int ec = checkErrorCode(dataq_dev_ptr_->di_stop_scan(), throw_on_error); 00429 return( ec ); 00430 } 00431 00432 //----------------------------------------------------------------------------- 00433 00434 int DataQ::checkErrorCode(int error_code, bool throw_on_error) 00435 { 00436 #ifdef DEBUG 00437 std::cout << "DataQ: checkErrorCode" << std::endl; 00438 #endif 00439 00440 if( error_code == DI_NO_ERR) 00441 return error_code; 00442 00443 char err_msg[256]; 00444 dataq_dev_ptr_->di_strerr(error_code, err_msg); 00445 std::string ex_str( std::string("DataQ Error: ").append(err_msg) ); 00446 00447 if(error_code == DI_DRIVER_ERR) 00448 ex_str += " -- please check if the device is connected and turned on!"; 00449 00450 if(throw_on_error) 00451 { 00452 closeDev(false); 00453 throw(std::runtime_error( ex_str ) ); 00454 } 00455 00456 std::cerr << " ### " << ex_str << " ### " << std::endl; 00457 return error_code; 00458 } 00459 00460 //----------------------------------------------------------------------------- 00461 00462 void DataQ::printDataQInfo() 00463 { 00464 #ifdef DEBUG 00465 std::cout << "DataQ: printDataQInfo" << std::endl; 00466 #endif 00467 00468 printf("\nPort: %04X\n",info_.port); 00469 printf("Input chn: %04X\n",info_.buf_in_chn); 00470 printf("Output chn: %04X\n",info_.buf_out_chn); 00471 printf("Sft lvl: %04X\n",info_.sft_lvl); 00472 printf("Hrd lvl: %04X\n",info_.hrd_lvl); 00473 printf("Input ptr: %08lX\n",info_.buf_in_ptr); 00474 printf("Output ptr: %08lX\n",info_.buf_out_ptr); 00475 printf("Input size: %04X\n",info_.buf_in_size); 00476 printf("Output size: %04X\n",info_.buf_out_size); 00477 printf("TSR Ver: %s\n",info_.tsr_version); 00478 printf("DSP Ver: %s\n",info_.dsp_version); 00479 printf("SDK Ver: %s\n",info_.sdk_version); 00480 printf("Serial #: %08lX\n",info_.serial_no); 00481 printf("Board ID: %s\n",info_.board_id); 00482 printf("PGH/PGL(1/0): %0x1\n",info_.pgh_pgl); 00483 } 00484 00485 //----------------------------------------------------------------------------- 00486 00487 void DataQ::setInList() 00488 { 00489 #ifdef DEBUG 00490 std::cout << "DataQ: setInList" << std::endl; 00491 #endif 00492 00493 //struct di_inlist_struct inlist[256] = {0}; 00494 //for(int i = 0; i < 2; i++) 00495 //{ 00496 // inlist[i].chan = i; 00497 // inlist[i].gain = 0; 00498 // inlist[i].ave = 0; 00499 // inlist[i].counter = 0; 00500 //} 00501 00502 inlist_ptr_ = new tobiss::di_inlist_struct[256]; 00503 00504 for(unsigned int n = 0; n < 256; n++) 00505 { 00506 inlist_ptr_[n].chan = 0; 00507 inlist_ptr_[n].diff = 0; 00508 inlist_ptr_[n].gain = 0; 00509 inlist_ptr_[n].unipolar = 0; 00510 inlist_ptr_[n].dig_out = 0; 00511 inlist_ptr_[n].dig_out_enable = 0; 00512 inlist_ptr_[n].ave = 0; 00513 inlist_ptr_[n].counter = 0; 00514 } 00515 00516 unsigned int n = 0; 00517 for(std::map<boost::uint16_t, std::pair<std::string, boost::uint32_t> >::iterator it(channel_info_.begin()); 00518 it != channel_info_.end(); it++) 00519 { 00520 inlist_ptr_[n].chan = it->first -1; 00521 inlist_ptr_[n].diff = bipolar_list_.at( getChannelPosition(it->first) ); 00522 inlist_ptr_[n].gain = gain_index_.at( getChannelPosition(it->first) ); 00523 inlist_ptr_[n].unipolar = 0; 00524 inlist_ptr_[n].dig_out = 0; 00525 inlist_ptr_[n].dig_out_enable = 0; 00526 inlist_ptr_[n].ave = 0; 00527 inlist_ptr_[n].counter = 0; 00528 n++; 00529 } 00530 00531 checkErrorCode(dataq_dev_ptr_->di_list_length(nr_ch_, 0), true ); 00532 checkErrorCode( dataq_dev_ptr_->di_inlist(inlist_ptr_), true ); 00533 } 00534 00535 //----------------------------------------------------------------------------- 00536 00537 void DataQ::setDaqMode() 00538 { 00539 #ifdef DEBUG 00540 std::cout << "DataQ: setDaqMode" << std::endl; 00541 #endif 00542 00543 mode_.mode = 0; 00544 mode_.hystx = 0; 00545 mode_.scnx = 0; 00546 mode_.trig_level = 0; //0x01 00547 mode_.trig_slope = 0; //1 00548 mode_.trig_pre = 0; 00549 mode_.trig_post = 0; //0xFF0 00550 00551 checkErrorCode(dataq_dev_ptr_->di_mode( &mode_ ), true ); 00552 } 00553 00554 //----------------------------------------------------------------------------- 00555 00556 inline double DataQ::getVoltageValue(short val, boost::uint16_t ch_nr) 00557 { 00558 return( val *(v_max_[ch_nr] - v_min_[ch_nr])/65536 ); 00559 } 00560 00561 //----------------------------------------------------------------------------- 00562 00563 void DataQ::acquireData() 00564 { 00565 #ifdef DEBUG 00566 std::cout << "DataQ: acquireData" << std::endl; 00567 #endif 00568 00569 unsigned int current_pos = 0; 00570 unsigned int num_vals = 0; 00571 00572 boost::system::error_code error; 00573 00574 while(acqu_running_) 00575 { 00576 current_pos = dataq_dev_ptr_->di_buffer_status(0); 00577 00578 if(last_pos_ != current_pos) 00579 { 00580 if(current_pos > last_pos_) 00581 { 00582 num_vals = current_pos - last_pos_; 00583 for(unsigned int n = 0; (n < num_vals) && acqu_running_; n++) 00584 { 00585 buffer_.insert_blocking( *(dev_buffer_ + last_pos_ + n) ); 00586 //file_stream_ << getVoltageValue( *(dev_buffer_ + last_pos_ + n) ) << ","; 00587 } 00588 } 00589 else 00590 { 00591 num_vals = DMA_IN_SIZ - last_pos_; 00592 for(unsigned int n = 0; (n < num_vals) && acqu_running_; n++) 00593 if(last_pos_ + n > DMA_IN_SIZ-1) 00594 std::cerr << "Error - would read beyond the buffer -- " << DMA_IN_SIZ << ", " << last_pos_ + n << std::endl; 00595 else 00596 { 00597 buffer_.insert_blocking( *(dev_buffer_ + last_pos_ + n) ); 00598 //file_stream_ << getVoltageValue( *(dev_buffer_ + last_pos_ + n) ) << ","; 00599 } 00600 00601 for(unsigned int n = 0; (n < current_pos) && acqu_running_; n++) 00602 { 00603 buffer_.insert_blocking( *(dev_buffer_ + n) ); 00604 //file_stream_ << getVoltageValue( *(dev_buffer_ + n) ) << ","; 00605 } 00606 } 00607 00608 last_pos_ = current_pos; 00609 } 00610 else 00611 { 00612 Sleep(1); 00613 // sleep_timer_.expires_from_now(sleep_time_, error); 00614 00615 // if(error) 00616 // std::cerr << BOOST_CURRENT_FUNCTION << std::endl; 00617 // sleep_timer_.wait(); 00618 } 00619 00620 } // while(acqu_running) 00621 } 00622 00623 //----------------------------------------------------------------------------- 00624 00625 void DataQ::setDeviceRange(ticpp::Iterator<ticpp::Element>const &father) 00626 { 00627 #ifdef DEBUG 00628 std::cout << "DataQ: setDeviceRange" << std::endl; 00629 #endif 00630 00631 double value = 0; 00632 try{ 00633 value = lexical_cast<double>(boost::format("%d") % father->GetText(true) ); 00634 } 00635 catch(bad_lexical_cast &) 00636 { 00637 string ex_str(type_ + " -- "); 00638 ex_str += "Tag <"+ hw_dataq_range_ + "> : Value is not a floating point one!"; 00639 throw(std::invalid_argument(ex_str)); 00640 } 00641 00642 unsigned int n = 0; 00643 for( ; n < DI_720_NR_VOLTAGE_RANGES; n++) 00644 { 00645 if(value == DI_720_VOLTAGE_RANGES[n]) 00646 break; 00647 } 00648 00649 if(n >= DI_720_NR_VOLTAGE_RANGES) 00650 { 00651 string ex_str(type_ + " -- "); 00652 ex_str += "Tag <"+ hw_dataq_range_ + "> : Invalid range value: "+ lexical_cast<string>(value) + 00653 + " -- check supported values in the HW manual!"; 00654 } 00655 00656 for (unsigned int n = 0; n < nr_ch_; n++) 00657 { 00658 gain_index_[n] = n; 00659 v_max_[n] = DI_720_VOLTAGE_RANGES[n]; 00660 //if(bipolar_list_.at(n)) 00661 v_min_[n] = (-1)*DI_720_VOLTAGE_RANGES[n]; 00662 //else 00663 // v_min_[n] = 0; 00664 } 00665 } 00666 00667 //----------------------------------------------------------------------------- 00668 00669 void DataQ::setDeviceBipolar(ticpp::Iterator<ticpp::Element>const &father) 00670 { 00671 #ifdef DEBUG 00672 std::cout << "DataQ: setDeviceBipolar" << std::endl; 00673 #endif 00674 00675 bool bipolar = equalsOnOrOff(father->GetText(true)); 00676 00677 for (unsigned int n = 0; n < nr_ch_; n++) 00678 { 00679 bipolar_list_[n] = bipolar; 00680 if(bipolar) 00681 v_min_[n] = (-1)*v_max_[n]; 00682 } 00683 } 00684 00685 //----------------------------------------------------------------------------- 00686 00687 void DataQ::setChannelRange(ticpp::Iterator<ticpp::Element>const &father) 00688 { 00689 #ifdef DEBUG 00690 std::cout << "DataQ: setChannelRange" << std::endl; 00691 #endif 00692 00693 ticpp::Iterator<ticpp::Element> elem = father->FirstChildElement(hw_chset_ch_,false); 00694 00695 cout << " * DataQ -- individual ranges activated on channels:" << endl; 00696 00697 for( ; elem != elem.end(); elem++) 00698 if(elem->Value() == hw_chset_ch_) 00699 { 00700 if(!elem.Get()->HasAttribute(hw_ch_nr_)) 00701 { 00702 string ex_str(type_ + " -- "); 00703 ex_str += "Tag <"+hw_dataq_range_+"> given, but channel number ("+hw_ch_nr_+") not given!"; 00704 throw(std::invalid_argument(ex_str)); 00705 } 00706 if(!elem.Get()->HasAttribute(hw_dataq_value_)) 00707 { 00708 string ex_str(type_ + " -- "); 00709 ex_str += "Tag <"+hw_dataq_range_+"> given, but attribute ("+hw_dataq_value_+") (on/off) not given!"; 00710 throw(std::invalid_argument(ex_str)); 00711 } 00712 00713 uint16_t ch = 0; 00714 try{ 00715 ch = lexical_cast<boost::uint16_t>( elem.Get()->GetAttribute(hw_ch_nr_) ); 00716 } 00717 catch(bad_lexical_cast &) 00718 { 00719 string ex_str(type_ + " -- "); 00720 ex_str += "Tag <"+ hw_dataq_range_ + "> : Channel is not a number!"; 00721 throw(std::invalid_argument(ex_str)); 00722 } 00723 if( channel_info_.find(ch) == channel_info_.end() ) 00724 { 00725 string ex_str(type_ + " -- "); 00726 ex_str += "Tag <"+ hw_dataq_range_ + "> - Channel "+ 00727 boost::lexical_cast<std::string>(ch) +" not set for recording!"; 00728 throw(std::invalid_argument(ex_str)); 00729 } 00730 00731 double value = 0; 00732 try{ 00733 value = lexical_cast<double>( boost::format("%d") % elem.Get()->GetAttribute(hw_dataq_value_) ); 00734 } 00735 catch(bad_lexical_cast &) 00736 { 00737 string ex_str(type_ + " -- "); 00738 ex_str += "Tag <"+ hw_dataq_range_ + "> : Value is not a floating point one!"; 00739 throw(std::invalid_argument(ex_str)); 00740 } 00741 00742 unsigned int n = 0; 00743 for( ; n < DI_720_NR_VOLTAGE_RANGES; n++) 00744 { 00745 if(value == DI_720_VOLTAGE_RANGES[n]) 00746 break; 00747 } 00748 00749 00750 if(n >= DI_720_NR_VOLTAGE_RANGES) 00751 { 00752 string ex_str(type_ + " -- "); 00753 ex_str += "Tag <"+ hw_dataq_range_ + "> : Invalid range value: "+ lexical_cast<string>(value) + 00754 + " -- check supported values in the HW manual!"; 00755 throw(std::invalid_argument(ex_str)); 00756 } 00757 00758 00759 gain_index_[ getChannelPosition(ch) ] = n; 00760 v_max_[ getChannelPosition(ch) ] = value; 00761 00762 //if( bipolar_list_[ getChannelPosition(ch) ] ) 00763 v_min_[ getChannelPosition(ch) ] = value * (-1); 00764 //else 00765 // v_min_[ getChannelPosition(ch) ] = 0; 00766 00767 cout << " ... ch " << ch << " (pos " << getChannelPosition(ch) << "): " << value; 00768 cout <<"/"<< v_min_[ getChannelPosition(ch) ] << "; "; 00769 } 00770 else 00771 throw(std::invalid_argument("DataQ::setChannelRange -- Tag not equal to \""+hw_chset_ch_+"\"!")); 00772 } 00773 00774 //----------------------------------------------------------------------------- 00775 00776 void DataQ::setChannelBipolar(ticpp::Iterator<ticpp::Element>const &father) 00777 { 00778 #ifdef DEBUG 00779 std::cout << "DataQ: setChannelBipolar" << std::endl; 00780 #endif 00781 00782 ticpp::Iterator<ticpp::Element> elem = father->FirstChildElement(hw_chset_ch_,false); 00783 00784 cout << " * DataQ -- bipolar recording activated on channels:" << endl; 00785 00786 for( ; elem != elem.end(); elem++) 00787 if(elem->Value() == hw_chset_ch_) 00788 { 00789 if(!elem.Get()->HasAttribute(hw_ch_nr_)) 00790 { 00791 string ex_str(type_ + " -- "); 00792 ex_str += "Tag <"+hw_dataq_bipolar_+"> given, but channel number ("+hw_ch_nr_+") not given!"; 00793 throw(std::invalid_argument(ex_str)); 00794 } 00795 if(!elem.Get()->HasAttribute(hw_dataq_value_)) 00796 { 00797 string ex_str(type_ + " -- "); 00798 ex_str += "Tag <"+hw_dataq_bipolar_+"> given, but attribute ("+hw_dataq_value_+") (on/off) not given!"; 00799 throw(std::invalid_argument(ex_str)); 00800 } 00801 00802 uint16_t ch = 0; 00803 try{ 00804 ch = lexical_cast<boost::uint16_t>( elem.Get()->GetAttribute(hw_ch_nr_) ); 00805 } 00806 catch(bad_lexical_cast &) 00807 { 00808 string ex_str(type_ + " -- "); 00809 ex_str += "Tag <"+ hw_dataq_bipolar_ + "> : Channel is not a number!"; 00810 throw(std::invalid_argument(ex_str)); 00811 } 00812 if( channel_info_.find(ch) == channel_info_.end() ) 00813 { 00814 string ex_str(type_ + " -- "); 00815 ex_str += "Tag <"+ hw_dataq_bipolar_ + "> - Channel "+ 00816 boost::lexical_cast<std::string>(ch) +" not set for recording!"; 00817 throw(std::invalid_argument(ex_str)); 00818 } 00819 00820 bool value = equalsOnOrOff( elem.Get()->GetAttribute(hw_dataq_value_) ); 00821 00822 bipolar_list_[ getChannelPosition(ch) ] = value; 00823 cout << " ... ch " << ch << " (pos " << getChannelPosition(ch) << "): " << value << "; "; 00824 00825 } 00826 else 00827 throw(std::invalid_argument("DataQ::setChannelBipolar -- Tag not equal to \""+hw_chset_ch_+"\"!")); 00828 } 00829 00830 //----------------------------------------------------------------------------- 00831 00832 void DataQ::checkBiploarConfig() 00833 { 00834 #ifdef DEBUG 00835 std::cout << "DataQ: checkBiploarConfig" << std::endl; 00836 #endif 00837 00838 for(std::map<boost::uint16_t, std::pair<std::string, boost::uint32_t> >::iterator it(channel_info_.begin()); 00839 it != channel_info_.end(); it++) 00840 { 00841 boost::uint16_t ch_nr = it->first; 00842 int ch_pos = getChannelPosition(ch_nr); 00843 00844 if( (ch_nr < 9) || ( ch_nr > 16 && ch_nr < 25 ) ) 00845 { 00846 //std::cout << "CH pos: " << ch_pos << ", "<< bipolar_list_.size() << std::endl << std::flush; 00847 if(bipolar_list_.at( ch_pos ) ) 00848 if(channel_info_.find(ch_nr + 8) != channel_info_.end()) 00849 { 00850 string ex_str(type_ + " -- "); 00851 ex_str += "Tag <"+ hw_dataq_bipolar_ + "> - Channel "+ 00852 boost::lexical_cast<std::string>(ch_nr +8) +" must not be set for recording in a bipolar measurement!"; 00853 throw(std::invalid_argument(ex_str)); 00854 } 00855 } 00856 } 00857 } 00858 00859 //----------------------------------------------------------------------------- 00860 00861 void DataQ::checkChannels() 00862 { 00863 #ifdef DEBUG 00864 std::cout << "DataQ: checkChannels" << std::endl; 00865 #endif 00866 00867 for(std::map<boost::uint16_t, std::pair<std::string, boost::uint32_t> >::iterator it(channel_info_.begin()); 00868 it != channel_info_.end(); it++) 00869 if(it->first > DI_720_MAX_SUPPORTED_CH) 00870 { 00871 string ex_str(type_ + " -- "); 00872 ex_str += "Too many channels, maximum supported number: "+ 00873 boost::lexical_cast<std::string>(DI_720_MAX_SUPPORTED_CH) +"!"; 00874 throw(std::invalid_argument(ex_str)); 00875 } 00876 } 00877 00878 //----------------------------------------------------------------------------- 00879 00880 } // tobiss 00881