TOBI SignalServer  0.1
/home/breidi/Dropbox/signalserver/src/hardware/dataq.cpp
Go to the documentation of this file.
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 
 All Data Structures Files Functions Variables