#include "macro.h" #include "ClassData.h" #include "ClassDigitizer.h" #include "influxdb.h" #include #include #include /** struct timeval, select() */ #include /** tcgetattr(), tcsetattr() */ #include #include #include "TString.h" #include "TSystem.h" #include #include #define nDig 4 Digitizer * dig[4]; std::mutex mtx[nDig]; std::condition_variable cv; bool ready = false; bool stop_acquisition = false; timespec ts[nDig]; static struct termios g_old_kbd_mode; char* path_to_run="/home/bavarians/FSUDAQ_MUSIC/Run/"; char* path_to_DAQ="/home/bavarians/FSUDAQ_MUSIC/"; static void cooked(void){ tcsetattr(0, TCSANOW, &g_old_kbd_mode); } static void uncooked(void){ struct termios new_kbd_mode; /** put keyboard (stdin, actually) in raw, unbuffered mode */ tcgetattr(0, &g_old_kbd_mode); memcpy(&new_kbd_mode, &g_old_kbd_mode, sizeof(struct termios)); new_kbd_mode.c_lflag &= ~(ICANON | ECHO); new_kbd_mode.c_cc[VTIME] = 0; new_kbd_mode.c_cc[VMIN] = 1; tcsetattr(0, TCSANOW, &new_kbd_mode); } static void raw(void){ static char init; if(init) return; /** put keyboard (stdin, actually) in raw, unbuffered mode */ uncooked(); /** when we exit, go back to normal, "cooked" mode */ atexit(cooked); init = 1; } int keyboardhit(){ struct timeval timeout; fd_set read_handles; int status; raw(); /** check stdin (fd 0) for activity */ FD_ZERO(&read_handles); FD_SET(0, &read_handles); timeout.tv_sec = timeout.tv_usec = 0; status = select(0 + 1, &read_handles, NULL, NULL, &timeout); if(status < 0){ printf("select() failed in keyboardhit()\n"); exit(1); } return (status); } int getch(void){ unsigned char temp; raw(); /** stdin = fd 0 */ if(read(0, &temp, 1) != 1) return 0; return temp; } void go() { ready = true; cv.notify_all(); } void func(Digitizer * dig, double RunTime, int Rid, int Bid){ std::unique_lock lck(mtx[Bid]); while (!ready ){ printf("waiting for unlock %d\n", Bid); cv.wait(lck); } cv.notify_all(); clock_gettime(CLOCK_REALTIME, &ts[Bid]); printf("----thread %d ready. %ld ns\n", Bid, ts[Bid].tv_nsec); dig->StartACQ(); if(RunTime>0){ unsigned long time; unsigned long time0 = get_time(); do{ usleep(5*1000); dig->ReadData(); dig->GetData()->DecodeBuffer(true,0); //dig->GetData()->PrintStat(); //dig->GetData()->PrintData(); gSystem->cd(path_to_run); dig->GetData()->SaveBuffer(Form("Run_%03u_B%01u",Rid, Bid)); time = get_time(); //printf("********************* time : %lu usec\n", time-time0); } while((time-time0)*1e-6<=(RunTime)); time = get_time(); //printf("********************* end time : %lu usec\n", time-time0); dig->StopACQ(); } if(RunTime<=0){ do{ usleep(5*1000); dig->ReadData(); unsigned long time1 = get_time(); dig->GetData()->DecodeBuffer(true,0); unsigned long time2 = get_time(); //dig->GetData()->PrintStat(); //dig->GetData()->PrintData(); gSystem->cd(path_to_run); dig->GetData()->SaveBuffer(Form("Run_%03u_B%01u",Rid, Bid)); } while(RunTime<=0 && !stop_acquisition); dig->StopACQ(); } printf("thread %d finished.\n", Bid); } void boardSetParameters(int BI, Digitizer * dig, double BoardConfigurationval, double DPPAlgoCtrl, double DPPAlgoCtrl_10A0,double DPPAlgoCtrl_10AC, double ShapedTriggerWidthVal, double InputSec[7], double DiscriSec[4], double TrapSec[7]){ //ALL channels //GENERAL dig->WriteRegister(Register::DPP::BoardConfiguration, BoardConfigurationval); //Reg=0x8000 dig->WriteRegister(Register::DPP::DPPAlgorithmControl, DPPAlgoCtrl);//Reg=0x1080 dig->WriteRegister(Register::DPP::PHA::DPPAlgorithmControl2_G, DPPAlgoCtrl_10A0); //Reg=0x10A0 dig->WriteRegister(Register::DPP::PHA::DPPAlgorithmControl22_G, DPPAlgoCtrl_10AC); //Reg=0x10AC //Input Section dig->WriteRegister(Register::DPP::RecordLength_G, InputSec[1]); //Reg=0x1020 //Syncrhonization Section //Trigger/Veto/coinc Section dig->WriteRegister(Register::DPP::PHA::ShapedTriggerWidth, ShapedTriggerWidthVal); //Reg=0x1084 //Miscellaneaous Section //per channel for(int i=0;i<16;i++){ //GENERAL //Input Section dig->WriteRegister(Register::DPP::PreTrigger, InputSec[2], i);//Reg=0x1038 dig->WriteRegister(Register::DPP::ChannelDCOffset, InputSec[5], i);//Reg=0x1098 dig->WriteRegister(Register::DPP::InputDynamicRange, InputSec[6], i);//Reg=0x1028 //Discriminator Section dig->WriteRegister(Register::DPP::PHA::TriggerThreshold,DiscriSec[0], i);//Reg=0x106C dig->WriteRegister(Register::DPP::PHA::TriggerHoldOffWidth, DiscriSec[1], i);//Reg=0x1074 dig->WriteRegister(Register::DPP::PHA::RCCR2SmoothingFactor,DiscriSec[2], i);//Reg=0x1054 dig->WriteRegister(Register::DPP::PHA::InputRiseTime, DiscriSec[3], i);//Reg=0x1058 //Trapezoid Section dig->WriteRegister(Register::DPP::PHA::TrapezoidRiseTime,TrapSec[0], i);//Reg=0x105C dig->WriteRegister(Register::DPP::PHA::TrapezoidFlatTop, TrapSec[1], i);//Reg=0x1060 dig->WriteRegister(Register::DPP::PHA::DecayTime, TrapSec[2], i);//Reg=0x1068 dig->WriteRegister(Register::DPP::PHA::PeakingTime,TrapSec[3], i);//Reg=0x1064 dig->WriteRegister(Register::DPP::PHA::PeakHoldOff,TrapSec[5], i);//Reg=0x1078 dig->WriteRegister(Register::DPP::PHA::FineGain,TrapSec[6], i);//Reg=0x10C4 } } void boardCommonParameters(Digitizer * dig){ //all channels dig->WriteRegister(Register::DPP::TriggerValidationMask_G , 0x00000000);//Reg=0x8100 //per channels for(int i=0;i<16;i++){ dig->WriteRegister(Register::DPP::PHA::RiseTimeValidationWindow, 0x00000000, i);//Reg=0x1070 dig->WriteRegister(Register::DPP::VetoWidth, 0x0000000A, i);//Reg=0x10D4 dig->WriteRegister(Register::DPP::Scratch, 0xAAAAAAAA, i);//Reg=0xEF20 dig->WriteRegister(Register::DPP::InterruptEventNumber, 0x00000000,i);//Reg=0xEF18 dig->WriteRegister(Register::DPP::InterruptStatusID, 0x000000DD,i);//Reg=0xEF14 dig->WriteRegister(Register::DPP::RelocationAddress, 0x00000000,i);//Reg=0xEF10 dig->WriteRegister(Register::DPP::MCSTBaseAddressAndControl , 0x000000AA, i);//Reg=0xEF0C dig->WriteRegister(Register::DPP::ReadoutControl, 0x00000010, i);//Reg=0xEF00 dig->WriteRegister(Register::DPP::ExtendedVetoDelay, 0x12340014,i);//Reg=0x81C4 dig->WriteRegister(Register::DPP::BufferOccupancyGain , 0x00000000, i);//Reg=0x81B4 dig->WriteRegister(Register::DPP::FrontPanelLVDSIONewFeatures , 0x00001111, i);//Reg=0x81A0 dig->WriteRegister(Register::DPP::RunStartStopDelay , 0x00000000, i);//Reg=0x8170 dig->WriteRegister(Register::DPP::DisableExternalTrigger, 0x00000000,i);//Reg=0x817C dig->WriteRegister(Register::DPP::FanSpeedControl, 0x00000020, i);//Reg=0x8168 dig->WriteRegister(Register::MemoryBufferAlmostFullLevel, 0x00000000, i);//Reg=0x816C dig->WriteRegister(Register::DPP::AcquisitionControl, 00000000,i);//Reg=0x8100 dig->WriteRegister(Register::DPP::GlobalTriggerMask, 0x80000000,i);//Reg=0x810C dig->WriteRegister(Register::DPP::FrontPanelTRGOUTEnableMask, 0x00000000, i);//Reg=0x8110 dig->WriteRegister(Register::DPP::LVDSIOData, 0x0000FFFF, i);//Reg=0x8118 dig->WriteRegister(Register::DPP::FrontPanelIOControl, 0x00008100, i);//Reg=0x811C dig->WriteRegister(Register::DPP::ChannelEnableMask, 0x0000FFFF, i);//Reg=0x8120 dig->WriteRegister(Register::DPP::VoltageLevelModeConfig, 0x00000000, i);//Reg=0x8138 dig->WriteRegister(Register::DPP::AnalogMonitorMode, 0x00000000, i);//Reg=0x8144 } } int main(int argc, char* argv[]){ printf("=====================================\n"); printf("=== FSU DAQ ===\n"); printf("=====================================\n"); if (argc < 2) { printf("Incorrect number of arguments:\n"); printf("%s [RunTime] [RunId] \n", argv[0]); printf(" RunTime in sec, default = -1 if unstoppped \n"); return 1; } double RunTime = atoi(argv[1]); int Rid= atoi(argv[2]); //"""""""""""""""""""""""""""""" //Opening digitizers //"""""""""""""""""""""""""""""" for(int d=0;dProgramPHABoard(); dig[i]->ReadAllSettingsFromBoard(); dig[i]->WriteRegister(Register::DPP::SoftwareClear_W, 1); dig[i]->WriteRegister(Register::DPP::MaxAggregatePerBlockTransfer, 40);//80 Reg=0xEF1C dig[i]->WriteRegister(Register::DPP::NumberEventsPerAggregate_G, 511);//1023-->forced in WriteRegisterFromFile Reg=0x1034 printf("========== %d \n", dig[i]->ReadSettingFromFile(Register::DPP::MaxAggregatePerBlockTransfer)); boardSetParameters(i, dig[i], BoardConfigurationval[i],DPPAlgoCtrl[i], DPPAlgoCtrl_10A0[i],DPPAlgoCtrl_10AC[i], ShapedTriggerWidthVal, InputSec[i], DiscriSec[i], TrapSec[i] ); boardCommonParameters(dig[i]); dig[i]-> SaveAllSettingsAsText(Form("reg_Board%i.txt",i)); dig[i]->GetData()->SetSaveWaveToMemory(false); } //"""""""""""""""""""""""""""""" //Parallel digitizer data taking //"""""""""""""""""""""""""""""" std::thread fdig[nDig]; for (int i = 0; i < nDig; ++i){ fdig[i] = std::thread(func, dig[i],RunTime , Rid, i); } printf("%d threads ready to race...\n", nDig); usleep(1000*1000); if(RunTime<=0){ printf("Enter to stop ..\n"); if(getchar()){stop_acquisition=true;} } go(); for (auto& f : fdig) f.join(); printf("=========== finsihed.\n"); long avg = 0; for( int i =0; i < nDig ; i++) avg += ts[i].tv_nsec; avg = avg/nDig; long min , max; for( int i =0; i < nDig; i++) { if( i == 0 ){ min = ts[i].tv_nsec; max = ts[i].tv_nsec; continue; } if( min > ts[i].tv_nsec) min = ts[i].tv_nsec; if( max < ts[i].tv_nsec) max = ts[i].tv_nsec; } printf(" avg : %ld\n", avg); printf(" min : %ld, %ld\n", min, avg - min); printf(" max : %ld, %ld\n", max, max - avg); printf(" diff : %ld\n", max-min); for(int i=0;i