V172X_Daq.cc

00001 /* --------------------------------------------------------
00002 CAEN_V172XDAQ.cc
00003 This is the implementation for the CAEN_V172XDAQ class, 
00004 which inherits from the WARP_VetoDAQ class.
00005 ----------------------------------------------------------*/
00006 
00007 #include "V172X_Daq.hh"
00008 //#include "CAEN_V172XEvent.hh"
00009 #include "CAENVMElib.h"
00010 #include "RawEvent.hh"
00011 #include "Message.hh"
00012 #include "ConfigHandler.hh"
00013 #include "EventHandler.hh"
00014 #include <string>
00015 #include <time.h>
00016 #include <bitset>
00017 #include <algorithm>
00018 #include "boost/ref.hpp"
00019 #include "boost/timer.hpp"
00020 #include "boost/date_time/posix_time/posix_time_duration.hpp"
00021 #include <sstream>
00022 
00023 //declare some useful constants
00024 const int event_size_padding = 8;
00025 
00026 enum VME_REGISTERS{
00027   VME_ChZSThresh =         0x1024,
00028   VME_ChZSNsamples =       0x1028,
00029   VME_ChTrigThresh =       0x1080,
00030   VME_ChTrigSamples =      0x1084,
00031   VME_ChStatus =           0x1088,
00032   VME_ChBuffersFull =      0x1094,
00033   VME_ChDAC =              0x1098,
00034   VME_ChannelsConfig =     0x8000,
00035   VME_BufferCode =         0x800C,
00036   VME_BufferFree =         0x8010,
00037   VME_CustomSize =         0x8020,
00038   VME_AcquisitionControl = 0x8100,
00039   VME_AcquisitionStatus =  0x8104,
00040   VME_SWTrigger =          0x8108,
00041   VME_TrigSourceMask =     0x810C,
00042   VME_TrigOutMask =        0x8110,
00043   VME_PostTriggerSetting = 0x8114,
00044   VME_FrontPanelIO =       0x811C,
00045   VME_ChannelMask =        0x8120,
00046   VME_DownsampleFactor =   0x8128,
00047   VME_EventsStored =       0x812C,
00048   VME_BoardInfo =          0x8140,
00049   VME_EventSize =          0x814C,
00050   VME_VMEControl =         0xEF00,
00051   VME_VMEStatus =          0xEF04,
00052   VME_BoardID =            0xEF08,
00053   VME_RelocationAddress =  0xEF10,
00054   VME_InterruptID =        0xEF14,
00055   VME_InterruptOnEvent =   0xEF18,
00056   VME_BLTEvents =          0xEF1C,
00057   VME_SWReset =            0xEF24,
00058   VME_SWClear =            0xEF28,
00059 };
00060 
00061 V172X_Daq::V172X_Daq() : BaseDaq(), _initialized(false), 
00062                          _params(), _triggers(0), _vme_mutex()
00063 {
00064   ConfigHandler::GetInstance()->RegisterParameter(_params.GetDefaultKey(),
00065                                                   _params);
00066   _handle_vme_bridge = 0;
00067   std::fill (_handle_board, _handle_board + _params.nboards, 0);
00068 }
00069 
00070 V172X_Daq::~V172X_Daq()
00071 {
00072   if (_params.vme_bridge_link >= 0) CAENVME_End(_handle_vme_bridge);
00073 
00074   for(int i=0; i < _params.nboards; i++)
00075     if(_params.board[i].enabled && _params.board[i].link > 0 && _params.board[i].link != _params.vme_bridge_link) CAENVME_End(_handle_board[i]);
00076 }
00077 
00078 int init_link (int link, int board, bool usb, int32_t *handle) {
00079   CVErrorCodes err = CAENVME_Init(usb ? cvV1718 : cvV2718, link, board, handle);
00080   if(err != cvSuccess){
00081     Message m(ERROR);
00082     m<<"Unable to initialize CAEN VME bridge for link " << link;
00083     if(usb) m<<" on USB ";
00084     m<< ": "<<std::endl;
00085     m<<"\t"<<CAENVME_DecodeError(err)<<std::endl;
00086     return -1;
00087   }
00088   char message[100];
00089   Message(DEBUG)<<"CAEN VME bridge successfully initialized for link " 
00090                 << link << "!"<<std::endl;
00091   CAENVME_BoardFWRelease(*handle,message);
00092   Message(DEBUG)<<"\tFirmware Release: "<<message<<std::endl;
00093   CAENVME_DriverRelease(*handle,message);
00094   Message(DEBUG)<<"\tDriver Release: "<<message<<std::endl;
00095   Message(INFO)<< "Link " << link << " initialized on handle " 
00096                << *handle <<std::endl;
00097   return 0;
00098 }
00099 
00100 
00101 int V172X_Daq::Initialize()
00102 {
00103   if(_initialized){
00104     Message(WARNING)<<"Reinitializing V172X_Daq..."<<std::endl;
00105     if (_params.vme_bridge_link >= 0) CAENVME_End(_handle_vme_bridge);
00106 
00107     for(int i=0; i < _params.nboards; i++)
00108       if(_params.board[i].enabled && _params.board[i].link > 0 && _params.board[i].link != _params.vme_bridge_link) CAENVME_End(_handle_board[i]);
00109   }
00110       
00111   if (_params.vme_bridge_link >= 0) {
00112     if (init_link (_params.vme_bridge_link, 0, false, &_handle_vme_bridge) < 0){
00113       _status=INIT_FAILURE;
00114       return -1;
00115     }
00116     //reset everything
00117     //CAENVME_SystemReset(_handle_vme_bridge);
00118     //CAENVME_DeviceReset(_handle_vme_bridge);
00119     if(_params.send_start_pulse) {
00120       CAENVME_ClearOutputRegister(_handle_vme_bridge, 0xFFFF);
00121       for(int line = 0; line<5; line++){
00122         CVErrorCodes err = CAENVME_SetOutputConf(_handle_vme_bridge, (CVOutputSelect)line, cvDirect, 
00123             cvActiveHigh, cvManualSW);
00124         if(err != cvSuccess){
00125           Message(ERROR)<<"Unable to configure the V2718 output registers.\n";
00126           return -2;
00127         }
00128       }
00129     }
00130   } 
00131   else if (_params.send_start_pulse) {
00132     Message(WARNING)<<"send_start_pulse enabled but no bridge link present, disabling pulses" << std::endl;
00133     _params.send_start_pulse = 0;
00134   }
00135 
00136   for(int i=0; i < _params.nboards; i++) {
00137     if(_params.board[i].enabled && 
00138        ( ( _params.board[i].link >= 0 && 
00139          _params.board[i].link != _params.vme_bridge_link )
00140          || _params.board[i].usb ) ){
00141       if (init_link (_params.board[i].link, _params.board[i].chainindex, 
00142                      _params.board[i].usb, _handle_board + i) < 0) {
00143         _status=INIT_FAILURE;
00144         return -3;
00145       }
00146     } 
00147     else _handle_board[i] = _handle_vme_bridge;
00148   }
00149 
00150   for(int i=0; i < _params.nboards; i++){
00151     //Initialize each enabled board
00152     if(!_params.board[i].enabled) 
00153       continue;
00154     try{
00155       if(InitializeBoard(i)){
00156         _status = INIT_FAILURE;
00157         return -5;
00158       }
00159       
00160     }
00161     catch(std::exception &error)
00162       {
00163         Message(EXCEPTION)<<error.what()<<std::endl;
00164         return -6;
00165       }
00166   }
00167   _initialized = true;
00168   return Update();
00169 }
00170 
00171 int V172X_Daq::InitializeBoard(int boardnum)
00172 {
00173   V172X_BoardParams& board = _params.board[boardnum];
00174   WriteVMERegister(board.address + VME_SWReset, 1, _handle_board[boardnum]);
00175   uint32_t data = ReadVMERegister(board.address+VME_BoardInfo, _handle_board[boardnum]);
00176   board.board_type = (BOARD_TYPE)(data&0xFF);
00177   board.nchans = (data>>16)&0xFF;
00178   board.mem_size = (data>>8)&0xFF;
00179   if(board.UpdateBoardSpecificVariables()){ //returns -1 on error
00180     Message(CRITICAL)<<"Board "<<boardnum<<" with address "
00181                      <<std::hex<<std::showbase
00182                      <<board.address<<std::dec<<std::noshowbase
00183                      <<" is not a V172X digitizer!"<<std::endl;
00184     _status = INIT_FAILURE;
00185     return -2;
00186   }
00187   WriteVMERegister(board.address+VME_BoardID,
00188                    board.id, _handle_board[boardnum]);
00189   WriteVMERegister(board.address+VME_InterruptID,
00190                    board.id, _handle_board[boardnum]);
00191   return 0;
00192 }
00193 
00194 int V172X_Daq::Update()
00195 {
00196   if(!_initialized){
00197     Message(ERROR)<<"Attempt to update parameters before initializations!"
00198                   <<std::endl;
00199     return -1;
00200   }
00201   if(_is_running){
00202     Message(ERROR)<<"Attempt to update parameters while in run."
00203                   <<std::endl;
00204     return -2;
00205   }
00206   try{
00207     for(int iboard=0; iboard < _params.nboards; iboard++){
00208       V172X_BoardParams& board = _params.board[iboard];
00209       //downsample factor is not implemented in modern firmware
00210       board.downsample_factor=1; 
00211       if(!board.enabled) 
00212         continue;
00213       //determine the trigger acquisition window for the database
00214       //WARNING: Assumes it is the same for all boards!!!
00215       runinfo* info = EventHandler::GetInstance()->GetRunInfo();
00216       if(info){
00217         std::stringstream ss;
00218         ss<<"board"<<iboard<<".pre_trigger_time_us";
00219         info->SetMetadata(ss.str(), board.pre_trigger_time_us);
00220         ss.str("");
00221         ss<<"board"<<iboard<<".post_trigger_time_us";
00222         info->SetMetadata(ss.str(), board.post_trigger_time_us);
00223         
00224       }
00225        
00226       uint32_t channel_mask = 0;
00227       uint32_t trigger_mask = 0;
00228       uint32_t trigger_out_mask = 0;
00229       //need to know total_nsamps to estimate event size
00230       //do the per-channel stuff
00231       for(int i=0; i<board.nchans; i++){
00232         V172X_ChannelParams& channel = board.channel[i];
00233         channel_mask += (1<<i) * channel.enabled;
00234         trigger_mask += (1<<i) * channel.enable_trigger_source;
00235         trigger_out_mask += (1<<i) * channel.enable_trigger_out;
00236         //write the per-channel stuff
00237         //Zero suppression threshold
00238         uint32_t zs_thresh = (1<<31) * channel.zs_polarity +
00239           channel.zs_threshold;
00240         WriteVMERegister(board.address+VME_ChZSThresh+i*0x100,zs_thresh, _handle_board[iboard]);
00241         //zero suppression time over threshold
00242         uint32_t nsamp = channel.zs_thresh_time_us * board.GetSampleRate();
00243         if(nsamp >= (1<<20)) nsamp = (1<<20) -1;
00244         if(board.zs_type == ZLE){
00245           //nsamp contains the pre and post samples
00246           if(channel.zs_pre_samps>=(1<<16)) channel.zs_pre_samps = (1<<16)-1;
00247           if(channel.zs_post_samps>=(1<<16)) channel.zs_post_samps = (1<<16)-1;
00248           uint32_t npre = 
00249             std::ceil(channel.zs_pre_samps/board.stupid_size_factor);
00250           uint32_t npost = 
00251             std::ceil(channel.zs_pre_samps/board.stupid_size_factor);
00252           nsamp = (npre<<16) + npost;
00253         }
00254         WriteVMERegister(board.address+ VME_ChZSNsamples+i*0x100, nsamp, _handle_board[iboard]);
00255         //trigger threshold
00256         WriteVMERegister(board.address+ VME_ChTrigThresh+i*0x100, 
00257                          channel.threshold, _handle_board[iboard]);
00258         //time over trigger threhsold
00259         nsamp = std::ceil(channel.thresh_time_us * board.GetSampleRate()) 
00260           / board.stupid_size_factor;
00261         
00262         if(nsamp >= (1<<12)) nsamp = (1<<12) - 1;
00263         WriteVMERegister(board.address+ VME_ChTrigSamples+i*0x100, nsamp, _handle_board[iboard]);
00264         //dc offset
00265         WriteVMERegister(board.address+ VME_ChDAC+i*0x100, channel.dc_offset, _handle_board[iboard]);
00266         //wait until the dac has updated
00267         uint32_t status = 0x4;
00268         while( channel.enabled &&( (status&0x4) || !(status&0x2)) ){
00269           //std::cerr<<"Waiting for channel "<<i<<" of board "<<iboard<<" to update DAC...";
00270           status = ReadVMERegister(board.address+VME_ChStatus +i*0x100, _handle_board[iboard]);
00271           //std::cerr<<" status is now "<<status<<std::endl;
00272         }
00273       }
00274       //finish up with the board parameters
00275       uint32_t channel_config = (1<<16) * board.zs_type + 
00276         (1<<6) * board.trigger_polarity + 
00277         (1<<4) + //Memory Sequential access
00278         (1<<3) * board.enable_test_pattern + 
00279         (1<<1) * board.enable_trigger_overlap;
00280       WriteVMERegister(board.address+ VME_ChannelsConfig, channel_config, _handle_board[iboard]);
00281       //Buffer code (determines total trigger time
00282       WriteVMERegister(board.address+VME_BufferCode, board.GetBufferCode(), _handle_board[iboard]);
00283       //Custom size of register
00284       
00285       WriteVMERegister(board.address+ VME_CustomSize, 
00286                        board.GetCustomSizeSetting(), _handle_board[iboard]);
00287       
00288       //Acquisition Control
00289       uint32_t acq_control =  
00290         (1<<3) * board.count_all_triggers +
00291         _params.send_start_pulse;
00292 //      acq_control = (1<<3) * board.count_all_triggers + 4;
00293       WriteVMERegister(board.address+VME_AcquisitionControl,acq_control, _handle_board[iboard]);
00294       board.acq_control_val = acq_control;
00295       //trigger mask
00296       if(board.local_trigger_coincidence >7) 
00297         board.local_trigger_coincidence = 7;
00298       trigger_mask += (1<<31) * board.enable_software_trigger 
00299         + (1<<30) * board.enable_external_trigger
00300         + (1<<24) * board.local_trigger_coincidence;
00301       WriteVMERegister(board.address+ VME_TrigSourceMask, trigger_mask, _handle_board[iboard]);
00302       //trigger out mask
00303       trigger_out_mask += (1<<31) * board.enable_software_trigger_out +
00304         (1<<30) * board.enable_external_trigger_out;
00305       WriteVMERegister(board.address+ VME_TrigOutMask, trigger_out_mask, _handle_board[iboard]);
00306       //post trigger setting
00307       
00308       WriteVMERegister(board.address+VME_PostTriggerSetting, 
00309                        board.GetPostTriggerSetting(), _handle_board[iboard]);
00310       //signal logic and front panel programming
00311       WriteVMERegister(board.address+ VME_FrontPanelIO,
00312                        board.signal_logic + (1<<6), _handle_board[iboard]);
00313       //channel mask
00314       WriteVMERegister(board.address+ VME_ChannelMask, channel_mask, 
00315                        _handle_board[iboard]);
00316       //VME control
00317       uint32_t vme_control = (1<<5) * _params.align64 + 
00318         (1<<4) + //enable bus error
00319         (1<<3) + //enable optical link error
00320         1; //interrupt level
00321       WriteVMERegister(board.address+ VME_VMEControl, vme_control, _handle_board[iboard]);
00322       //Interrupt num, BLT event num
00323       WriteVMERegister(board.address+VME_InterruptOnEvent, 0, _handle_board[iboard]);
00324       WriteVMERegister(board.address+VME_BLTEvents, 1, _handle_board[iboard]);
00325       //wait until the board is ready to take data
00326       uint32_t status = 0;
00327       int count = 0;
00328       while( !((status&0x100) && (status&0xc0)) ){
00329         status = ReadVMERegister(board.address+VME_AcquisitionStatus, _handle_board[iboard]);
00330         if(count++ > 500){
00331           Message(ERROR)<<"Unable to initialize board "<<iboard<<" at address "
00332                         <<std::hex<<board.address<<std::dec<<"\n";
00333           return 1;
00334         }
00335       }
00336       
00337     }
00338     /*Find the max expected event size in bytes
00339     The header size is 16 bytes per board
00340     The data size is 2 bytes per sample per channel
00341     */
00342     Message(DEBUG)<<"The expected event size is "<<_params.GetEventSize()
00343                   <<" bytes."<<std::endl;   
00344     //wait 2 seconds for DC offset levels to adjust
00345     time_t now = time(0);
00346     while(time(0) - now < 2) {}
00347   }
00348   catch(...){ 
00349     return -3;
00350   }
00351   return 0;
00352 }
00353 
00354 //predicate for find_if function used to test if any board has data
00355 bool DataAvailable(uint32_t status)
00356 {
00357   return (status & 0x8);
00358 }
00359 
00360 void V172X_Daq::DataAcquisitionLoop()
00361 {
00362   if(!_initialized) Initialize();
00363   //prepare some variables
00364   _triggers = 0;
00365   std::vector<uint32_t> acq_status(_params.enabled_boards);
00366   //Arm the boards
00367   try{
00368     std::vector<uint32_t> acq_write;
00369     for(int i=0; i<_params.nboards; i++){
00370       if(_params.board[i].enabled){
00371         acq_write.push_back(_params.board[i].acq_control_val+0x4);
00372       }
00373     }
00374     WriteVMERegisters(VME_SWClear,1);
00375     WriteVMERegisters(VME_AcquisitionControl,&(acq_write[0]));
00376     if(_params.send_start_pulse)
00377       CAENVME_SetOutputRegister(_handle_vme_bridge, 
00378                                 cvOut0Bit | cvOut1Bit | cvOut2Bit | 
00379                                 cvOut3Bit | cvOut4Bit );
00380   }
00381   catch(std::exception& e){
00382     Message(ERROR)<<"Unable to arm the board for run!\n";
00383     _initialized=false;
00384     _status=INIT_FAILURE;
00385     return;
00386   }
00387   int32_t irq_handle = _handle_vme_bridge;
00388   if (_params.vme_bridge_link) 
00389     for(int i=0; i < _params.nboards; i++) { 
00390       irq_handle = _handle_board[i]; 
00391       if (_params.board[i].enabled && _params.board[i].link >= 0) break;
00392     }
00393   
00394   //figure out whether we can use interrupts
00395   //usb interface can't do interrupts, so use polling only
00396   
00397   bool use_interrupt = true;
00398   for(int i=0; i<_params.nboards; i++){
00399     if(_params.board[i].enabled && _params.board[i].usb) 
00400       use_interrupt = false;
00401   }
00402 
00403   
00404   while(_is_running ){
00405 
00406     CVErrorCodes err = cvTimeoutError;
00407     
00408     if(use_interrupt){
00409       //Enable IRQ lines and wait for an interrupt
00410       CAENVME_IRQEnable(irq_handle,0xFF);
00411       err = CAENVME_IRQWait(irq_handle,0xFF,
00412                                          _params.trigger_timeout_ms);
00413       CAENVME_IRQDisable(irq_handle,0xFF);
00414     }
00415     else{
00416       for(int i=0; i<_params.nboards; i++){
00417         if(!_params.board[i].enabled) continue;
00418         //see if there is an event ready on the board
00419         if(DataAvailable(ReadVMERegister(_params.board[i].address+
00420                                          VME_AcquisitionStatus, 
00421                                          _handle_board[i])) ){
00422           err = cvSuccess;
00423           break;
00424         }
00425       }
00426     }
00427 
00428     //Check to see if there was an interrupt or just the timeout
00429     switch(err){
00430     case cvSuccess:
00431       break;
00432     case cvGenericError:
00433       Message(DEBUG)<<"Generic error occurred. Probably just a timeout...\n";
00434       //notice: no break here!
00435     case cvTimeoutError:
00436       if(!use_interrupt){
00437         //sleep for the timeout interval
00438         boost::this_thread::sleep(
00439             boost::posix_time::millisec(_params.trigger_timeout_ms));
00440       }
00441       if(_params.auto_trigger){
00442         Message(DEBUG)<<"Triggering...\n";
00443         WriteVMERegisters(VME_SWTrigger,1);
00444       }
00445       else
00446         Message(DEBUG)<<"Waiting for trigger..."<<std::endl;
00447       continue;
00448       break;
00449     default:
00450       Message(ERROR)<<"Unknown error waiting for trigger interrupt\n";
00451       break;
00452     }
00453     
00454     //if we get here, there is an event ready for download
00455     //get a new event ready 
00456     RawEventPtr next_event(new RawEvent);
00457     size_t blocknum = 
00458       next_event->AddDataBlock(RawEvent::CAEN_V172X,
00459                                _params.event_size_bytes+event_size_padding);
00460     unsigned char* buffer = next_event->GetRawDataBlock(blocknum);
00461     const uint32_t UNSET_EVENT_COUNTER = 0xFFFFFFFF;
00462     uint32_t event_counter = UNSET_EVENT_COUNTER;
00463     //get the data
00464     int data_transferred = 0;
00465     for(int i=0; i<_params.nboards; i++){
00466       if(!_params.board[i].enabled) continue;
00467       //wait until the event is ready on the board
00468       
00469       int tries = 0;
00470       const int maxtries = 50;
00471       while(!DataAvailable(ReadVMERegister(_params.board[i].address+
00472                                            VME_AcquisitionStatus, _handle_board[i])) &&
00473             tries++ < maxtries) {}
00474       if(tries >= maxtries){
00475         Message(DEBUG)<<"No trigger received on board "<<i<<"\n";
00476         continue;
00477       }
00478       
00479       int this_dl_size = 0;
00480       tries=0;
00481       CVErrorCodes err = cvSuccess;
00482       while(this_dl_size == 0 && ++tries<maxtries ){
00483         err = 
00484           CAENVME_FIFOBLTReadCycle(_handle_board[i], _params.board[i].address,
00485                                    buffer + data_transferred,
00486                                    _params.board[i].event_size_bytes,
00487                                    cvA32_U_MBLT, cvD64, &this_dl_size);
00488         if(err != cvSuccess && err != cvBusError){
00489           Message(ERROR)<<"Error generated while downloading event from board"
00490                         <<i<<": "<<CAENVME_DecodeError(err)<<"\n";
00491           continue;
00492         }
00493       }
00494       
00495       if(this_dl_size<=0){
00496         Message(ERROR)<<"0 bytes downloaded for board "<<i<<std::endl;
00497         Message(DEBUG)<<"Events stored on this board: "
00498                       <<ReadVMERegister(_params.board[i].address+
00499                                         VME_EventsStored, _handle_board[i])<<"\n";
00500         uint32_t out;
00501         out = ReadVMERegister(_params.board[i].address+VME_VMEStatus, 
00502                               _handle_board[i]);
00503         Message(DEBUG)<<"VME status:"
00504                       <<"\n\tBERR flag: "<< (out&4)
00505                       <<"\n\tOutput buffer full: "<< (out&2)
00506                       <<"\n\tData ready: "<< (out&1)<<"\n";
00507         out = ReadVMERegister(_params.board[i].address+VME_AcquisitionStatus, 
00508                               _handle_board[i]);
00509         Message(DEBUG)<<"Acquisition status:"
00510                       <<"\n\tReady for acquisition: "<< (out&256)
00511                       <<"\n\tPLL Status: "<< (out&128)
00512                       <<"\n\tPLL Bypass: "<< (out&64)
00513                       <<"\n\tClock source: "<< (out&32)
00514                       <<"\n\tEvents full: "<< (out&16)
00515                       <<"\n\tEvent ready: "<< (out&8)
00516                       <<"\n\t Run on: "<< (out&4) <<"\n";
00517         out = ReadVMERegister(_params.board[i].address+VME_EventSize, 
00518                               _handle_board[i]);
00519         Message(DEBUG)<<"Next event size: "<<out<<"\n";
00520         Message(DEBUG)<<"Expected event size "
00521                       <<_params.board[i].event_size_bytes/4<<"\n";
00522         
00523         
00524         //free the buffer so we don't re-trigger spuriously
00525         WriteVMERegister(_params.board[i].address+VME_BufferFree,1, 
00526                          _handle_board[i]);
00527         Message(DEBUG)<<"Events stored on this board: "
00528                       <<ReadVMERegister(_params.board[i].address+
00529                                         VME_EventsStored, _handle_board[i])
00530                       <<"\n";
00531         WriteVMERegister(_params.board[i].address+VME_BufferFree,2, 
00532                          _handle_board[i]);
00533         Message(DEBUG)<<"Events stored on this board: "
00534                       <<ReadVMERegister(_params.board[i].address+
00535                                         VME_EventsStored, _handle_board[i])
00536                       <<"\n";
00537         Message(ERROR)<<"Boards don't usually recover from this error! "
00538                       <<"Aborting!\n";
00539         _status = COMM_ERROR;
00540         _is_running = false;
00541         break;
00542       }
00543       else{
00544         
00545         //this could ignore potential align64 extra bits:
00546         //data_transferred += this_dl_size;
00547         //instead, we check the actual event
00548         long ev_size = (*((uint32_t*)(buffer+data_transferred)) & 
00549                              0x0FFFFFFF) * sizeof(uint32_t);
00550         if(std::abs(ev_size - this_dl_size) > 5){
00551           Message(WARNING)<<"Event size does not match download count!\n\t"
00552                           <<"Event size: "<<ev_size<<"; download size: "
00553                           <<this_dl_size<<"; requested download "
00554                           <<_params.board[i].event_size_bytes<<std::endl;
00555           Message(ERROR)<<"Boards don't usually recover from this error! "
00556                       <<"Aborting!\n";
00557           _status = COMM_ERROR;
00558           _is_running = false;
00559           break;
00560         }
00561         //check for event ID misalignment
00562         uint32_t evct = (((uint32_t*)(buffer+data_transferred))[2])&0xFFFFFF;
00563         if(event_counter == UNSET_EVENT_COUNTER)
00564           event_counter = evct;
00565         else if(evct != event_counter){
00566           Message(CRITICAL)<<"Mismatched event ID on board "<<i
00567                            <<"; received "<<evct<<", expected "<<event_counter
00568                            <<"; Aboring run\n";
00569           _status = GENERIC_ERROR;
00570           _is_running=false;
00571           break;
00572         }
00573       
00574         data_transferred += ev_size;
00575         
00576       }
00577     }
00578     if(GetStatus() != NORMAL){
00579       _is_running = false;
00580       break;
00581     }
00582     if(data_transferred <= 0){
00583       Message(ERROR)<<"No boards transferred usable data this event!\n";
00584       continue;
00585     }
00586     else{
00587       _triggers++;
00588       next_event->SetDataBlockSize(blocknum, data_transferred);
00589       PostEvent(next_event);
00590     }    
00591   }//end while(_is_running)
00592    //We only reach here once the event has stopped, so clean up any mess
00593   //First, end the run, and clear the buffers
00594   if(_params.send_start_pulse)
00595     CAENVME_ClearOutputRegister(_handle_vme_bridge, 0xFFFF);
00596   for(int i=0; i<_params.nboards; i++){
00597     if(_params.board[i].enabled){
00598       WriteVMERegister(_params.board[i].address+ VME_AcquisitionControl,
00599                        _params.board[i].acq_control_val, _handle_board[i]);
00600       WriteVMERegister(_params.board[i].address+VME_SWClear,0x1, _handle_board[i]);
00601     }
00602   }
00603   WriteVMERegisters(VME_SWReset,1);
00604   Message(DEBUG)<<_triggers<<" total triggers downloaded."<<std::endl;
00605 }  
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Defines

Generated on 20 Jun 2014 for daqman by  doxygen 1.6.1