296 lines
12 KiB
C++
296 lines
12 KiB
C++
#include "macro.h"
|
|
#include "ClassData.h"
|
|
#include "ClassDigitizer.h"
|
|
#include "influxdb.h"
|
|
#include <condition_variable>
|
|
#include <mutex>
|
|
#include <sys/time.h> /** struct timeval, select() */
|
|
#include <termios.h> /** tcgetattr(), tcsetattr() */
|
|
#include <vector>
|
|
#include <thread>
|
|
#include "TString.h"
|
|
#include "TSystem.h"
|
|
#include <iostream>
|
|
#include <fstream>
|
|
#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<std::mutex> 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;d<nDig;d++){
|
|
dig[d] = new Digitizer(0, d, false, true);
|
|
}
|
|
//""""""""""""""""""""""""""""""
|
|
//Register value assignment
|
|
//""""""""""""""""""""""""""""""
|
|
double BoardConfigurationval[4] ={0x014E8905,0x014E0105,0x014E0105,0x014E0105}; //Reg=8000
|
|
double DPPAlgoCtrl[4] ={0x0831200E,0x0831200E,0x0831200E,0x0831200E}; //Reg=1080
|
|
double DPPAlgoCtrl_10A0[4] ={0x00000000,0x00000000,0x00000000,0x00000000}; //Reg=10A0
|
|
double DPPAlgoCtrl_10AC[4] ={0x0010010E,0x0010010E,0x0010010E,0x0010010E}; //Reg=10AC
|
|
double ShapedTriggerWidthVal = 6; //Reg=1084 in steps of 16ns
|
|
|
|
//1==RecordLength input N such length (ns) == N*8*4 , 2==PreTrigger input N such length (ns) == N*4*4
|
|
//5==DCoffset DC% = 1 - input/65535, 6==CoarseGain 0=x1 or 1=x4
|
|
double InputSec[4][7] ={ {0, 375, 200,0,0,0x00004CCC, 0},
|
|
{0, 375, 200,0,0,0x00004CCC, 0},
|
|
{0, 375, 200,0,0,0x00004CCC, 0},
|
|
{0, 375, 200,0,0,0x00004CCC, 0}};
|
|
//0==TriggerThreshold in lsb, 1==TriggerHoldOffWidth in steps of 16ns, 2==FastDiscriSmooth (20=64samp, 63=128samp),
|
|
// 3==InputRiseTime in steps of 16ns, 144=9*16 ns
|
|
double DiscriSec[4][4]={ {100, 30, 63, 56},
|
|
{100, 30, 63, 56},
|
|
{100, 30, 63, 56},
|
|
{100, 30, 63, 56}};
|
|
//0==RiseTime in steps of 16ns, 496=31*16, 1==FlatTop in steps of 16ns, 2=PoleZero in steps of 16ns
|
|
//3==PeakingTime in steps of 16ns, 60% of flat top, 5==PeakHoldOff in steps of 16ns, fine gain 1==0x00006C3A
|
|
double TrapSec[4][7]={{31, 187, 625,94, 0, 62, 0x00006C3A},
|
|
{31, 187, 625,94, 0, 62, 0x00006C3A},
|
|
{31, 187, 625,94, 0, 62, 0x00006C3A},
|
|
{31, 187, 625,94, 0, 62, 0x00006C3A}};
|
|
for( int i = 0; i < nDig; i++){
|
|
dig[i]->ProgramPHABoard();
|
|
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<nDig;i++){delete dig[i];}
|
|
return 0;
|
|
}
|