diff --git a/ClassData.h b/ClassData.h index a541d7e..e92965d 100644 --- a/ClassData.h +++ b/ClassData.h @@ -59,7 +59,8 @@ class Data{ void CopyBuffer( const char * buffer, const unsigned int size); - void SaveBuffer(const char * fileName); + void SetOutputFileName(std::string fileName); + void SaveBuffer(); unsigned int GetPresentFileSize() {return presentFileSizeByte;} void PrintBuffer() const; //Incorrect @@ -74,6 +75,8 @@ class Data{ unsigned int nw; bool SaveWaveToMemory; + + std::string outputFileName; ///for temperary std::vector tempWaveform1; @@ -105,6 +108,8 @@ inline Data::Data(){ SaveWaveToMemory = true; nw = 0; saveFileIndex = 0; + + outputFileName = ""; } inline Data::~Data(){ @@ -163,10 +168,14 @@ inline void Data::CopyBuffer(const char * buffer, const unsigned int size){ std::memcpy(this->buffer, buffer, size); } -inline void Data::SaveBuffer(const char * fileName){ +inline void Data::SetOutputFileName(std::string fileName){ + this->outputFileName = fileName; +} + +inline void Data::SaveBuffer(){ char saveFileName[100]; - sprintf(saveFileName, "%s_%03d_%03d_%03u.fsu", fileName , boardSN, DPPType, saveFileIndex); + sprintf(saveFileName, "%s_%03d_%03d_%03u.fsu", outputFileName.c_str() , boardSN, DPPType, saveFileIndex); FILE * haha = fopen(saveFileName, "a+"); fseek(haha, 0L, SEEK_END); @@ -176,7 +185,7 @@ inline void Data::SaveBuffer(const char * fileName){ if( inFileSize > (unsigned int)MaxSaveFileSize ) { /// 2 GB fclose(haha); saveFileIndex ++; - sprintf(saveFileName, "%s_%03u.fsu", fileName , saveFileIndex); + sprintf(saveFileName, "%s_%03u.fsu", outputFileName.c_str() , saveFileIndex); fclose(haha); haha = fopen(saveFileName, "a+"); } diff --git a/ClassDigitizer.cpp b/ClassDigitizer.cpp index 544cb76..615cf0d 100644 --- a/ClassDigitizer.cpp +++ b/ClassDigitizer.cpp @@ -394,7 +394,8 @@ unsigned int Digitizer::CalByteForBuffer(){ /// printf("Paired Ch : %d, RecordLength (bit value): %u, Event per Agg. : %u \n", pCh, recordLength[pCh], eventAgg[pCh]); ///} - unsigned int bufferSize = 0; + unsigned int bufferSize = aggOrgan; // just for get rip of the warning in complier + bufferSize = 0; for( int pCh = 0; pCh < NChannel/2 ; pCh++){ if( (chMask & ( 3 << (2 * pCh) )) == 0 ) continue; bufferSize += 2 + ( 2 + ((boardCfg >> 17) & 0x1) + ((boardCfg >> 16) & 0x1)*recordLength[pCh]*4 ) * eventAgg[pCh] ; @@ -406,12 +407,12 @@ unsigned int Digitizer::CalByteForBuffer(){ return bufferSize ; } -void Digitizer::ReadData(){ - if( !isConnected ) return; - if( !AcqRun) return; +int Digitizer::ReadData(){ + if( !isConnected ) return CAEN_DGTZ_DigitizerNotFound; + if( !AcqRun) return CAEN_DGTZ_WrongAcqMode; if( data->buffer == NULL ) { printf("need allocate memory for readout buffer\n"); - return; + return CAEN_DGTZ_InvalidBuffer; } ret = CAEN_DGTZ_ReadData(handle, CAEN_DGTZ_SLAVE_TERMINATED_READOUT_MBLT, data->buffer, &(data->nByte)); @@ -420,8 +421,9 @@ void Digitizer::ReadData(){ if (ret || data->nByte == 0) { ErrorMsg(__func__); - return; } + + return ret; } void Digitizer::PrintACQStatue(){ @@ -665,6 +667,8 @@ int Digitizer::LoadSettingBinaryToMemory(std::string fileName){ settingFile = fopen(fileName.c_str(), "r"); size_t dummy = fread( setting, SETTINGSIZE * sizeof(unsigned int), 1, settingFile); fclose (settingFile); + + if( dummy == 0 ) printf("reach the end of file\n"); uint32_t boardInfo = GetSettingFromMemory(Register::DPP::BoardInfo_R); if( (boardInfo & 0xFF) == 0x0E ) ch2ns = 4.0; @@ -691,6 +695,9 @@ unsigned int Digitizer::ReadSettingFromFile(Reg registerAddress, unsigned short size_t dummy = fread( lala, sizeof(unsigned int), 1, settingFile); ///printf(" data at pos %lu(%lu) : %X = %d\n", ftell(settingFile) - sizeof(unsigned int), (ftell(settingFile) - sizeof(unsigned int))/4, lala[0], lala[0]); fclose (settingFile); + + if( dummy == 0 ) printf("reach the end of file\n"); + return lala[0]; } diff --git a/ClassDigitizer.h b/ClassDigitizer.h index 82ee001..ffb97a6 100644 --- a/ClassDigitizer.h +++ b/ClassDigitizer.h @@ -23,7 +23,7 @@ class Digitizer{ Data * data; - ///---- fixed parameter + //^---- fixed parameter int portID; /// port ID for optical link for using PCIe card, from 0, 1, 2, 3 int boardID; /// board identity int handle; /// i don't know why, but better separete the handle from boardID @@ -34,35 +34,34 @@ class Digitizer{ float ch2ns; /// channel to ns CAEN_DGTZ_BoardInfo_t BoardInfo; - ///----- adjustable parameters + //^----- adjustable parameters uint32_t channelMask ; /// the channel mask from NChannel uint32_t VMEBaseAddress; /// For direct USB or Optical-link connection, VMEBaseAddress must be 0 CAEN_DGTZ_ConnectionType LinkType; /// USB or Optic CAEN_DGTZ_IOLevel_t IOlev; /// TTL signal (1 = 1.5 to 5V, 0 = 0 to 0.7V ) or NIM signal (1 = -1 to -0.8V, 0 = 0V) - ///------- other parameters + //^------- other parameters int ret; /// return value, refer to CAEN_DGTZ_ErrorCode bool isConnected; /// true for digitizer communication estabished. bool AcqRun; /// true when digitizer is taking data bool isDummy; /// true for a dummy digitizer. - /// ------- setting + //^-------- setting std::string settingFileName; /// FILE * settingFile; /// bool settingFileExist; /// bool isSettingFilledinMemeory; /// false for disabled ReadAllSettingFromBoard() unsigned int setting[SETTINGSIZE]; /// Setting, 4bytes x 2048 = 8192 bytes - ///---------- protected functions - + //^-------- other protected functions void ErrorMsg(std::string header = ""); public: Digitizer(); /// no digitizer open Digitizer(int boardID, int portID = 0, bool program = false, bool verbose = false); - ~Digitizer(); + virtual ~Digitizer(); - /// portID is for optical link for using PCIe card, from 0, 1, 2, 3 + //^------ portID is for optical link for using PCIe card, from 0, 1, 2, 3 int OpenDigitizer(int boardID, int portID = 0, bool program = false, bool verbose = false); void SetDPPType (int type) { this->DPPType = type;} /// for manual override, or, digitizer does not open void SetChannelMask (uint32_t mask); @@ -74,20 +73,20 @@ class Digitizer{ bool IsConnected() {return isConnected;} void PrintBoard() ; - virtual int ProgramBoard() ; /// program a generic board, no program channel + virtual int ProgramBoard() ; /// program a generic board, no program channel int ProgramPHABoard() ; /// program a default PHA board - ///================ ACQ control + //^================ ACQ control void StopACQ(); void StartACQ(); - void ReadData(); + int ReadData(); bool IsRunning() const {return AcqRun;} Data * GetData() const {return data;} void PrintACQStatue(); unsigned int CalByteForBuffer(); - ///=================Settings + //^================= Settings /// write value to digitizer, memory, and settingFile (if exist) /// ONLY WriteRegister can have ch = -1, for writting all channels /// for board setting, ignore ch @@ -97,7 +96,7 @@ class Digitizer{ uint32_t ReadRegister (Reg registerAddress, unsigned short ch = 0, bool isSave2MemAndFile = true, std::string str = "" ); uint32_t PrintRegister(uint32_t address, std::string msg); - ///================ Get Board info + //^================ Get Board info std::string GetModelName() const {return BoardInfo.ModelName;} int GetSerialNumber() const {return BoardInfo.SerialNumber;} int GetChannelMask() const {return channelMask;} @@ -105,7 +104,6 @@ class Digitizer{ float GetCh2ns() const {return ch2ns;} int GetNChannel() const {return NChannel;} int GetHandle() const {return handle;} - bool GetConnectionStatus() const {return isConnected;} int GetDPPType() const {return DPPType;} std::string GetDPPString(int DPPType = 0); /// if no input, use digitizer DPPType int GetADCBits() const {return BoardInfo.ADC_NBits;} @@ -113,7 +111,7 @@ class Digitizer{ std::string GetAMCVersion() const {return BoardInfo.AMC_FirmwareRel;} CAEN_DGTZ_ConnectionType GetLinkType() const {return LinkType;} - ///================ Setting + //^================ Setting Reg FindRegister(uint32_t address); /// board <--> memory functions void ReadAllSettingsFromBoard (bool force = false); @@ -138,42 +136,6 @@ class Digitizer{ void SaveSettingToFile (Reg registerAddress, unsigned int value, unsigned short ch = 0); /// also save to memory unsigned int ReadSettingFromFile (Reg registerAddress, unsigned short ch = 0); /// read from setting binary - ///=================== Relic methods - ///void SetRecordLength (unsigned int ns, int ch = -1); /// when ch == -1, mean set all channels - ///void SetInputDynamicRange (unsigned int TwoVol_0_or_halfVol_1, int ch = -1); - ///void SetPreTriggerSample (unsigned int nSample, int ch = -1 ); - ///void SetPreTriggerDuration (unsigned int ns, int ch = -1 ); - ///void SetDCOffset (float offsetPrecentage, int ch = -1); - ///void SetVetoWidth (uint32_t bit, int ch = -1); /// See manual - ///void SetTriggerPolarity (bool RiseingIsZero, int ch = -1); ///not used for DPP firmware - /// - ///void SetEventAggregation (unsigned int numEvent, int ch = -1); - ///void SetAggregateOrganization (unsigned int bit); - ///void SetMaxAggregatePerBlockTransfer (unsigned int numEvent); - /// - ///void SetBits(Reg address, unsigned int bitValue, unsigned int bitLength, unsigned int bitSmallestPos, int ch = -1); - ///void SetDPPAlgorithmControl(uint32_t bit, int ch = -1); - /// - ///void SetACQControl(uint32_t bit); - ///void SetGlobalTriggerMask(uint32_t bit); - ///void SetFrontPanelTRGOUTMask(uint32_t bit); - ///void SetFrontPanelIOControl(uint32_t bit); - ///void SetTriggerValidationMask(uint32_t bit); - ///void SetBoardID(unsigned int ID) {WriteRegister(Register::DPP::BoardID, ID)); - - ///unsigned int GetRecordLengthSample(int ch) {return ReadRegister(Register::DPP::RecordLength_G, ch) * 8;} - ///unsigned int GetInputDynamicRange(int ch) {return ReadRegister(Register::DPP::InputDynamicRange, ch);} - ///unsigned int GetPreTriggerSample(int ch) {return ReadRegister(Register::DPP::PreTrigger, ch) * 4;} - ///float GetDCOffset(int ch) {return 100.0 - ReadRegister(Register::DPP::ChannelDCOffset, ch) * 100. / 0xFFFFF; } - ///unsigned int GetVetoWidth(int ch) {return ReadRegister(Register::DPP::VetoWidth, ch);} - ///unsigned int GetEventAggregation(int ch = -1) {return ReadRegister(Register::DPP::NumberEventsPerAggregate_G, ch);} - ///unsigned int GetAggregateOrganization() {return ReadRegister(Register::DPP::AggregateOrganization);} - ///unsigned int GetMaxNumberOfAggregatePerBlockTransfer() {return ReadRegister(Register::DPP::MaxAggregatePerBlockTransfer);} - /// - ///unsigned int ReadBits(Reg address, unsigned int bitLength, unsigned int bitSmallestPos, int ch = -1 ); - ///unsigned int GetDPPAlgorithmControl(int ch = -1) {return ReadRegister(Register::DPP::DPPAlgorithmControl, ch);} - /// - ///int GetChTemperature(int ch) ; }; diff --git a/CustomThreads.h b/CustomThreads.h new file mode 100644 index 0000000..9b6b4c7 --- /dev/null +++ b/CustomThreads.h @@ -0,0 +1,135 @@ +#ifndef CUSTOMTHREADS_H +#define CUSTOMTHREADS_H + +#include +#include + +#include "macro.h" +#include "ClassDigitizer.h" + +static QMutex digiMTX[MaxNBoards * MaxNPorts]; + +//^#===================================================== ReadData Thread +class ReadDataThread : public QThread { + Q_OBJECT +public: + ReadDataThread(Digitizer * dig, int digiID, QObject * parent = 0) : QThread(parent){ + this->digi = dig; + this->ID = digiID; + isSaveData = false; + } + void SetSaveData(bool onOff) {this->isSaveData = onOff;} + void run(){ + clock_gettime(CLOCK_REALTIME, &ta); + while(true){ + digiMTX[ID].lock(); + int ret = digi->ReadData(); + digiMTX[ID].unlock(); + + if( ret == CAEN_DGTZ_Success ){ + digiMTX[ID].lock(); + if( isSaveData ) { + digi->GetData()->SaveBuffer(); + }else{ + digi->GetData()->DecodeBuffer(false); + } + digiMTX[ID].unlock(); + + }else{ + printf("%s------------ ret : %d \n", __func__, ret); + if( ret == CAEN_DGTZ_WrongAcqMode) break; + } + + // // if( ret == CAEN_FELib_Success){ + // // if( isSaveData) digi->SaveDataToFile(); + // // }else if(ret == CAEN_FELib_Stop){ + // // digi->ErrorMsg("No more data"); + // // //emit endOfLastData(); + // // break; + // // }else{ + // // //digi->ErrorMsg("ReadDataLoop()"); + // // digi->evt->ClearTrace(); + // // } + + // // if( isSaveData ){ + // // clock_gettime(CLOCK_REALTIME, &tb); + // // if( tb.tv_sec - ta.tv_sec > 2 ) { + // // emit sendMsg("FileSize ("+ QString::number(digi->GetSerialNumber()) +"): " + QString::number(digi->GetTotalFilesSize()/1024./1024.) + " MB"); + // // //emit checkFileSize(); + // // //double duration = tb.tv_nsec-ta.tv_nsec + tb.tv_sec*1e+9 - ta.tv_sec*1e+9; + // // //printf("%4d, duration : %10.0f, %6.1f\n", readCount, duration, 1e9/duration); + // // ta = tb; + // // } + // // } + } + } +signals: + void sendMsg(const QString &msg); + //void endOfLastData(); + //void checkFileSize(); +private: + Digitizer * digi; + int ID; + timespec ta, tb; + bool isSaveData; +}; + +//^#===================================================== UpdateTrace Thread +class UpdateTraceThread : public QThread { + Q_OBJECT +public: + UpdateTraceThread(QObject * parent = 0) : QThread(parent){ + waitTime = 2; + stop = false; + } + unsigned int GetWaitTimeSec() const {return waitTime;} + void SetWaitTimeSec(unsigned sec) {waitTime = sec;} + void Stop() {this->stop = true;} + void run(){ + unsigned int count = 0; + stop = false; + do{ + usleep(100000); + count ++; + if( count % waitTime == 0){ + emit updateTrace(); + } + }while(!stop); + } +signals: + void updateTrace(); + +private: + bool stop; + unsigned int waitTime; //100 of milisec +}; + +//^#======================================================= Scalar Thread +class ScalarThread : public QThread { + Q_OBJECT +public: + ScalarThread(QObject * parent = 0 ) : QThread(parent){ + waitTime = 20; // 10 x 100 milisec + stop = false; + } + void Stop() { this->stop = true;} + unsigned int GetWaitTimeinSec() const {return waitTime/10;} + void run(){ + unsigned int count = 0; + stop = false; + do{ + usleep(100000); + count ++; + if( count % waitTime == 0){ + emit updataScalar(); + } + }while(!stop); + } +signals: + void updataScalar(); +private: + bool stop; + unsigned int waitTime; +}; + +#endif diff --git a/CustomWidgets.h b/CustomWidgets.h new file mode 100644 index 0000000..e588ab5 --- /dev/null +++ b/CustomWidgets.h @@ -0,0 +1,53 @@ +#ifndef CustomWidgets_H +#define CustomWidgets_H + +#include +#include +#include +#include +#include + +//^======================================= +class RSpinBox : public QDoubleSpinBox{ + Q_OBJECT + public : + RSpinBox(QWidget * parent = nullptr, int decimal = 0): QDoubleSpinBox(parent){ + setFocusPolicy(Qt::StrongFocus); + setDecimals(decimal); + } + + void SetToolTip(double min = -1){ + if( min == -1 ){ + setToolTip("(" + QString::number(minimum()) + " - " + QString::number(maximum()) + ", " + QString::number(singleStep()) + ")"); + }else{ + setToolTip("(" + QString::number(min) + " - " + QString::number(maximum()) + ", " + QString::number(singleStep()) + ")"); + } + setToolTipDuration(-1); + } + + signals: + void returnPressed(); + protected: + void wheelEvent(QWheelEvent * event) override{ event->ignore(); } + + void keyPressEvent(QKeyEvent * event) override{ + if (event->key() == Qt::Key_Return || event->key() == Qt::Key_Enter) { + emit returnPressed(); + } else { + QDoubleSpinBox::keyPressEvent(event); + } + } +}; + +//^======================================= +class RComboBox : public QComboBox{ + public : + RComboBox(QWidget * parent = nullptr): QComboBox(parent){ + setFocusPolicy(Qt::StrongFocus); + } + protected: + void wheelEvent(QWheelEvent * event) override{ event->ignore(); } +}; + + +#endif \ No newline at end of file diff --git a/FSUDAQ_Qt6.pro b/FSUDAQ_Qt6.pro index 560bc36..b8bcee1 100644 --- a/FSUDAQ_Qt6.pro +++ b/FSUDAQ_Qt6.pro @@ -21,7 +21,7 @@ LIBS += -lCAENDigitizer `root-config --cflags --glibs` #DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0x060000 # disables all the APIs deprecated before Qt 6.0.0 # Input -HEADERS += ClassData.h ClassDigitizer.h macro.h mainWindow.h RegisterAddress.h +HEADERS += ClassData.h ClassDigitizer.h macro.h mainWindow.h RegisterAddress.h CustomWidgets.h CustomThreads.h SOURCES += ClassDigitizer.cpp main.cpp mainWindow.C diff --git a/RegisterAddress.h b/RegisterAddress.h index 508febd..da5299c 100644 --- a/RegisterAddress.h +++ b/RegisterAddress.h @@ -425,184 +425,4 @@ const std::vector RegisterDPPList = { }; - -/*************************** -namespace Register { - const uint32_t EventReadOutBuffer = 0x0000; /// R - - ///========== Channel or Group - const uint32_t ChannelDummy32 = 0x1024; /// R/W - const uint32_t InputDynamicRange = 0x1028; /// R/W - const uint32_t ChannelPulseWidth = 0x1070; /// R/W - const uint32_t ChannelTriggerThreshold = 0x1080; /// R/W - const uint32_t CoupleSelfTriggerLogic_G = 0x1084; /// R/W - const uint32_t ChannelStatus_R = 0x1088; /// R - const uint32_t AMCFirmwareRevision_ = 0x108C; /// R - const uint32_t ChannelDCOffset = 0x1098; /// R/W - const uint32_t ChannelADCTemperature_R = 0x10A8; /// R - const uint32_t ChannelSelfTriggerRateMeter_R = 0x10EC; /// R - - ///========== Board - const uint32_t BoardConfiguration = 0x8000; /// R/W - const uint32_t BufferOrganization = 0x800C; /// R/W - const uint32_t CustomSize = 0x8020; /// R/W - const uint32_t ADCCalibration_W = 0x809C; /// W - const uint32_t AcquisitionControl = 0x8100; /// R/W - const uint32_t AcquisitionStatus_R = 0x8104; /// R - const uint32_t SoftwareTrigger_W = 0x8108; /// W - const uint32_t GlobalTriggerMask = 0x810C; /// R/W - const uint32_t FrontPanelTRGOUTEnableMask = 0x8110; /// R/W - const uint32_t PostTrigger = 0x8114; /// R/W - const uint32_t LVDSIOData = 0x8118; /// R/W - const uint32_t FrontPanelIOControl = 0x811C; /// R/W - const uint32_t ChannelEnableMask = 0x8120; /// R/W - const uint32_t ROCFPGAFirmwareRevision_R = 0x8124; /// R - const uint32_t EventStored_R = 0x812C; /// R - const uint32_t VoltageLevelModeConfig = 0x8138; /// R/W - const uint32_t SoftwareClockSync_W = 0x813C; /// W - const uint32_t BoardInfo_R = 0x8140; /// R - const uint32_t AnalogMonitorMode = 0x8144; /// R/W - const uint32_t EventSize_R = 0x814C; /// R - const uint32_t FanSpeedControl = 0x8168; /// R/W - const uint32_t MemoryBufferAlmostFullLevel = 0x816C; /// R/W - const uint32_t RunStartStopDelay = 0x8170; /// R/W - const uint32_t BoardFailureStatus_R = 0x8178; /// R - const uint32_t FrontPanelLVDSIONewFeatures = 0x81A0; /// R/W - const uint32_t BufferOccupancyGain = 0x81B4; /// R/W - const uint32_t ChannelsShutdown_W = 0x81C0; /// W - const uint32_t ExtendedVetoDelay = 0x81C4; /// R/W - const uint32_t ReadoutControl = 0xEF00; /// R/W - const uint32_t ReadoutStatus_R = 0xEF04; /// R - const uint32_t BoardID = 0xEF08; /// R/W - const uint32_t MCSTBaseAddressAndControl = 0xEF0C; /// R/W - const uint32_t RelocationAddress = 0xEF10; /// R/W - const uint32_t InterruptStatusID = 0xEF14; /// R/W - const uint32_t InterruptEventNumber = 0xEF18; /// R/W - const uint32_t MaxAggregatePerBlockTransfer = 0xEF1C; /// R/W - const uint32_t Scratch = 0xEF20; /// R/W - const uint32_t SoftwareReset_W = 0xEF24; /// W - const uint32_t SoftwareClear_W = 0xEF28; /// W - - ///====== Common for PHA and PSD - namespace DPP { - const uint32_t RecordLength_G = 0x1020; /// R/W - const uint32_t InputDynamicRange = 0x1028; /// R/W - const uint32_t NumberEventsPerAggregate_G = 0x1034; /// R/W - const uint32_t PreTrigger = 0x1038; /// R/W - const uint32_t TriggerThreshold = 0x106C; /// R/W - const uint32_t TriggerHoldOffWidth = 0x1074; /// R/W - const uint32_t DPPAlgorithmControl = 0x1080; /// R/W - const uint32_t ChannelStatus_R = 0x1088; /// R - const uint32_t AMCFirmwareRevision_R = 0x108C; /// R - const uint32_t ChannelDCOffset = 0x1098; /// R/W - const uint32_t ChannelADCTemperature_R = 0x10A8; /// R - const uint32_t IndividualSoftwareTrigger_W = 0x10C0; /// W - const uint32_t VetoWidth = 0x10D4; /// R/W - - /// I know there are many duplication, it is the design. - const uint32_t BoardConfiguration = 0x8000; /// R/W - const uint32_t AggregateOrganization = 0x800C; /// R/W - const uint32_t ADCCalibration_W = 0x809C; /// W - const uint32_t ChannelShutdown_W = 0x80BC; /// W - const uint32_t AcquisitionControl = 0x8100; /// R/W - const uint32_t AcquisitionStatus_R = 0x8104; /// R - const uint32_t SoftwareTrigger_W = 0x8108; /// W - const uint32_t GlobalTriggerMask = 0x810C; /// R/W - const uint32_t FrontPanelTRGOUTEnableMask = 0x8110; /// R/W - const uint32_t LVDSIOData = 0x8118; /// R/W - const uint32_t FrontPanelIOControl = 0x811C; /// R/W - const uint32_t ChannelEnableMask = 0x8120; /// R/W - const uint32_t ROCFPGAFirmwareRevision_R = 0x8124; /// R - const uint32_t EventStored_R = 0x812C; /// R - const uint32_t VoltageLevelModeConfig = 0x8138; /// R/W - const uint32_t SoftwareClockSync_W = 0x813C; /// W - const uint32_t BoardInfo_R = 0x8140; /// R /// [0:7] 0x0E = 725, 0x0B = 730, [8:15] 0x01 = 640 kSample, 0x08 = 5.12 MSample, [16:23] channel number - const uint32_t AnalogMonitorMode = 0x8144; /// R/W - const uint32_t EventSize_R = 0x814C; /// R - const uint32_t TimeBombDowncounter_R = 0x8158; /// R - const uint32_t FanSpeedControl = 0x8168; /// R/W - const uint32_t RunStartStopDelay = 0x8170; /// R/W - const uint32_t BoardFailureStatus_R = 0x8178; /// R - const uint32_t DisableExternalTrigger = 0x817C; /// R/W - const uint32_t TriggerValidationMask_G = 0x8180; /// R/W, 0x8180 + 4n - const uint32_t FrontPanelLVDSIONewFeatures = 0x81A0; /// R/W - const uint32_t BufferOccupancyGain = 0x81B4; /// R/W - const uint32_t ExtendedVetoDelay = 0x81C4; /// R/W - const uint32_t ReadoutControl = 0xEF00; /// R/W - const uint32_t ReadoutStatus_R = 0xEF04; /// R - const uint32_t BoardID = 0xEF08; /// R/W /// Geo address on VME crate - const uint32_t MCSTBaseAddressAndControl = 0xEF0C; /// R/W - const uint32_t RelocationAddress = 0xEF10; /// R/W - const uint32_t InterruptStatusID = 0xEF14; /// R/W - const uint32_t InterruptEventNumber = 0xEF18; /// R/W - const uint32_t MaxAggregatePerBlockTransfer= 0xEF1C; /// R/W - const uint32_t Scratch = 0xEF20; /// R/W - const uint32_t SoftwareReset_W = 0xEF24; /// W - const uint32_t SoftwareClear_W = 0xEF28; /// W - const uint32_t ConfigurationReload_W = 0xEF34; /// W - const uint32_t ROMChecksum_R = 0xF000; /// R - const uint32_t ROMChecksumByte2_R = 0xF004; /// R - const uint32_t ROMChecksumByte1_R = 0xF008; /// R - const uint32_t ROMChecksumByte0_R = 0xF00C; /// R - const uint32_t ROMConstantByte2_R = 0xF010; /// R - const uint32_t ROMConstantByte1_R = 0xF014; /// R - const uint32_t ROMConstantByte0_R = 0xF018; /// R - const uint32_t ROM_C_Code_R = 0xF01C; /// R - const uint32_t ROM_R_Code_R = 0xF020; /// R - const uint32_t ROM_IEEE_OUI_Byte2_R = 0xF024; /// R - const uint32_t ROM_IEEE_OUI_Byte1_R = 0xF028; /// R - const uint32_t ROM_IEEE_OUI_Byte0_R = 0xF02C; /// R - const uint32_t ROM_BoardVersion_R = 0xF030; /// R - const uint32_t ROM_BoardFromFactor_R = 0xF034; /// R - const uint32_t ROM_BoardIDByte1_R = 0xF038; /// R - const uint32_t ROM_BoardIDByte0_R = 0xF03C; /// R - const uint32_t ROM_PCB_rev_Byte3_R = 0xF040; /// R - const uint32_t ROM_PCB_rev_Byte2_R = 0xF044; /// R - const uint32_t ROM_PCB_rev_Byte1_R = 0xF048; /// R - const uint32_t ROM_PCB_rev_Byte0_R = 0xF04C; /// R - const uint32_t ROM_FlashType_R = 0xF050; /// R - const uint32_t ROM_BoardSerialNumByte1_R = 0xF080; /// R - const uint32_t ROM_BoardSerialNumByte0_R = 0xF084; /// R - const uint32_t ROM_VCXO_Type_R = 0xF088; /// R - - namespace PHA { - const uint32_t DataFlush_W = 0x103C; /// W not sure - const uint32_t ChannelStopAcquisition = 0x1040; /// R/W not sure - const uint32_t RCCR2SmoothingFactor = 0x1054; /// R/W Trigger Filter smoothing, triggerSmoothingFactor - const uint32_t InputRiseTime = 0x1058; /// R/W OK - const uint32_t TrapezoidRiseTime = 0x105C; /// R/W OK - const uint32_t TrapezoidFlatTop = 0x1060; /// R/W OK - const uint32_t PeakingTime = 0x1064; /// R/W OK - const uint32_t DecayTime = 0x1068; /// R/W OK - const uint32_t TriggerThreshold = 0x106C; /// R/W OK - const uint32_t RiseTimeValidationWindow = 0x1070; /// R/W OK - const uint32_t TriggerHoldOffWidth = 0x1074; /// R/W OK - const uint32_t PeakHoldOff = 0x1078; /// R/W OK - const uint32_t ShapedTriggerWidth = 0x1084; /// R/W not sure - const uint32_t DPPAlgorithmControl2_G = 0x10A0; /// R/W OK - const uint32_t FineGain = 0x10C4; /// R/W OK - } - - namespace PSD { - const uint32_t CFDSetting = 0x103C; /// R/W - const uint32_t ForcedDataFlush_W = 0x1040; /// W - const uint32_t ChargeZeroSuppressionThreshold = 0x1044; /// R/W - const uint32_t ShortGateWidth = 0x1054; /// R/W - const uint32_t LongGateWidth = 0x1058; /// R/W - const uint32_t GateOffset = 0x105C; /// R/W - const uint32_t TriggerThreshold = 0x1060; /// R/W - const uint32_t FixedBaseline = 0x1064; /// R/W - const uint32_t TriggerLatency = 0x106C; /// R/W - const uint32_t ShapedTriggerWidth = 0x1070; /// R/W - const uint32_t TriggerHoldOffWidth = 0x1074; /// R/W - const uint32_t ThresholdForPSDCut = 0x1078; /// R/W - const uint32_t PurGapThreshold = 0x107C; /// R/W - const uint32_t DPPAlgorithmControl2_G = 0x1084; /// R/W - const uint32_t EarlyBaselineFreeze = 0x10D8; /// R/W - } - } - -} -*********************************/ - #endif diff --git a/macro.h b/macro.h index 19ad7b6..c97ad32 100644 --- a/macro.h +++ b/macro.h @@ -2,7 +2,7 @@ #define MACRO_H #define MaxNPorts 4 -#define MaxNBoards 22 +#define MaxNBoards 6 #define MaxNChannels 16 #define MaxRecordLength 0x3fff * 8 #define MaxSaveFileSize 1024 * 1024 * 1024 * 2 diff --git a/mainWindow.C b/mainWindow.C index 92a5b06..14eafba 100644 --- a/mainWindow.C +++ b/mainWindow.C @@ -1,19 +1,259 @@ #include "mainWindow.h" #include +#include +#include +#include +#include + +#include +#include +#include +#include #include +#include "CustomWidgets.h" + MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent){ setWindowTitle("FSU DAQ"); setGeometry(500, 100, 1000, 500); + digi = nullptr; + nDigi = 0; + QWidget * mainLayoutWidget = new QWidget(this); + setCentralWidget(mainLayoutWidget); + QVBoxLayout * layoutMain = new QVBoxLayout(mainLayoutWidget); + mainLayoutWidget->setLayout(layoutMain); + + {//^======================= + QGroupBox * box = new QGroupBox("Digitizer(s)", mainLayoutWidget); + layoutMain->addWidget(box); + QGridLayout * layout = new QGridLayout(box); + + QPushButton * bnOpenDigitizers = new QPushButton("Open Digitizers", this); + layout->addWidget(bnOpenDigitizers, 0, 0); + connect(bnOpenDigitizers, &QPushButton::clicked, this, &MainWindow::OpenDigitizers); + + QPushButton * bnCloseDigitizers = new QPushButton("Close Digitizers", this); + layout->addWidget(bnCloseDigitizers, 0, 1); + connect(bnCloseDigitizers, &QPushButton::clicked, this, &MainWindow::OpenDigitizers); + + QPushButton * bnOpenScope = new QPushButton("Open Scope", this); + layout->addWidget(bnOpenScope, 1, 0); + //connect(bnDigiSettings, &QPushButton::clicked, this, &MainWindow::OpenDigiSettings); + + QPushButton * bnDigiSettings = new QPushButton("Digitizers Settings", this); + layout->addWidget(bnDigiSettings, 1, 1); + //connect(bnDigiSettings, &QPushButton::clicked, this, &MainWindow::OpenDigiSettings); + + } + + {//^====================== ACQ control + QGroupBox * box = new QGroupBox("ACQ Control", mainLayoutWidget); + layoutMain->addWidget(box); + QGridLayout * layout = new QGridLayout(box); + + int rowID = 0; + QLabel * lbDataPath = new QLabel("Data Path : ", this); + lbDataPath->setAlignment(Qt::AlignRight | Qt::AlignCenter); + leDataPath = new QLineEdit(this); + leDataPath->setEnabled(false); + QPushButton * bnSetDataPath = new QPushButton("Set Path", this); + connect(bnSetDataPath, &QPushButton::clicked, this, &MainWindow::OpenDataPath); + + layout->addWidget(lbDataPath, rowID, 0); + layout->addWidget(leDataPath, rowID, 1, 1, 3); + layout->addWidget(bnSetDataPath, rowID, 4); + + rowID ++; + QLabel * lbPrefix = new QLabel("Prefix : ", this); + lbPrefix->setAlignment(Qt::AlignRight | Qt::AlignCenter); + lePrefix = new QLineEdit(this); + + QLabel * lbRunID = new QLabel("Run No. :", this); + lbRunID->setAlignment(Qt::AlignRight | Qt::AlignCenter); + QLineEdit * leRunID = new QLineEdit(this); + leRunID->setEnabled(false); + + QPushButton * bnOpenScaler = new QPushButton("Scalar", this); + + layout->addWidget(lbPrefix, rowID, 0); + layout->addWidget(lePrefix, rowID, 1); + layout->addWidget(lbRunID, rowID, 2); + layout->addWidget(leRunID, rowID, 3); + layout->addWidget(bnOpenScaler, rowID, 4); + + rowID ++; + QLabel * lbComment = new QLabel("Run Comment : ", this); + lbComment->setAlignment(Qt::AlignRight | Qt::AlignCenter); + + leComment = new QLineEdit(this); + leComment->setEnabled(false); + + QPushButton * bnStartACQ = new QPushButton("Start ACQ", this); + connect( bnStartACQ, &QPushButton::clicked, this, &MainWindow::StartACQ); + QPushButton * bnStopACQ = new QPushButton("Stop ACQ", this); + connect( bnStopACQ, &QPushButton::clicked, this, &MainWindow::StopACQ); + + layout->addWidget(lbComment, rowID, 0); + layout->addWidget(leComment, rowID, 1, 1, 2); + layout->addWidget(bnStartACQ, rowID, 3); + layout->addWidget(bnStopACQ, rowID, 4); + + + layout->setColumnStretch(0, 1); + layout->setColumnStretch(1, 2); + layout->setColumnStretch(2, 1); + layout->setColumnStretch(3, 3); + layout->setColumnStretch(4, 3); + + } + + + {//^===================== Log Msg + + logMsgHTMLMode = true; + QGroupBox * box3 = new QGroupBox("Log Message", mainLayoutWidget); + layoutMain->addWidget(box3); + layoutMain->setStretchFactor(box3, 1); + QVBoxLayout * layout3 = new QVBoxLayout(box3); + logInfo = new QPlainTextEdit(this); + logInfo->isReadOnly(); + QFont font; + font.setFamily("Courier New"); + logInfo->setFont(font); + layout3->addWidget(logInfo); + + } + + LogMsg("Welcome to FSU DAQ."); } MainWindow::~MainWindow(){ + if( digi ) CloseDigitizers(); + } + +//*************************************************************** +//*************************************************************** +void MainWindow::OpenDigitizers(){ + + //sereach for digitizers + LogMsg("Searching digitizers via optical link.....Please wait"); + logMsgHTMLMode = false; + nDigi = 0; + std::vector> portList; //boardID, portID + Digitizer dig; + for(int port = 0; port < MaxNPorts; port++){ + for( int board = 0; board < MaxNBoards; board ++){ /// max number of iasy chain + dig.OpenDigitizer(board, port); + if( dig.IsConnected() ){ + nDigi++; + portList.push_back(std::pair(board, port)); + LogMsg(QString("... Found at port: %1, board: %2. SN: %3 %4").arg(port).arg(board).arg(dig.GetSerialNumber(), 3, 10, QChar(' ')).arg(dig.GetDPPString().c_str())); + dig.CloseDigitizer(); + QCoreApplication::processEvents(); //to prevent Qt said application not responding. + }//else{ + //LogMsg(QString("... Nothing at port: %1, board: %2.").arg(port).arg(board)); + //} + } + } + LogMsg(QString("Done seraching. Found %1 digitizer(s). Opening digitizer(s)....").arg(nDigi)); + logMsgHTMLMode = true; + + digi = new Digitizer * [nDigi]; + readDataThread = new ReadDataThread * [nDigi]; + for( unsigned int i = 0; i < nDigi; i++){ + digi[i] = new Digitizer(portList[i].first, portList[i].second); + readDataThread[i] = new ReadDataThread(digi[i], i); + } + + LogMsg(QString("Done. Opened %1 digitizer(s).").arg(nDigi)); + +} + +void MainWindow::CloseDigitizers(){ + + LogMsg("Closing Digitizer(s)...."); + + for(unsigned int i = 0; i < nDigi; i ++){ + digi[i]->CloseDigitizer(); + delete digi[i]; + digi[i] = nullptr; + + delete readDataThread[i]; + } + delete [] digi; + digi = nullptr; + + delete [] readDataThread; + readDataThread = nullptr; + + LogMsg("Done. Closed " + QString::number(nDigi) + " Digitizer(s)."); + nDigi = 0; +} + +//*************************************************************** +//*************************************************************** +void MainWindow::OpenDataPath(){ + + QFileDialog fileDialog(this); + fileDialog.setFileMode(QFileDialog::Directory); + int result = fileDialog.exec(); + + //qDebug() << fileDialog.selectedFiles(); + if( result > 0 ) { + leDataPath->setText(fileDialog.selectedFiles().at(0)); + }else{ + leDataPath->clear(); + } + +} + +void MainWindow::StartACQ(){ + if( digi == nullptr ) return; + + for( unsigned int i = 0; i < nDigi ; i++){ + digi[i]->GetData()->SetOutputFileName("haha"); + digi[i]->StartACQ(); + readDataThread[i]->SetSaveData(true); + readDataThread[i]->start(); + } + +} + +void MainWindow::StopACQ(){ + if( digi == nullptr ) return; + + for( unsigned int i = 0; i < nDigi; i++){ + digi[i]->StopACQ(); + + if( readDataThread[i]->isRunning() ) { + readDataThread[i]->quit(); + readDataThread[i]->wait(); + } + + } + +} + +//*************************************************************** +//*************************************************************** +void MainWindow::LogMsg(QString msg){ + QString outputStr = QStringLiteral("[%1] %2").arg(QDateTime::currentDateTime().toString("MM.dd hh:mm:ss"), msg); + if( logMsgHTMLMode ){ + logInfo->appendHtml(outputStr); + }else{ + logInfo->appendPlainText(outputStr); + } + QScrollBar *v = logInfo->verticalScrollBar(); + v->setValue(v->maximum()); + //qDebug() << msg; + logInfo->repaint(); +} diff --git a/mainWindow.h b/mainWindow.h index 6c55081..d0fcbc2 100644 --- a/mainWindow.h +++ b/mainWindow.h @@ -2,6 +2,13 @@ #define MAINWINDOW_H #include +#include +#include +#include +#include + +#include "ClassDigitizer.h" +#include "CustomThreads.h" //^#===================================================== MainWindow class MainWindow : public QMainWindow{ @@ -10,6 +17,40 @@ public: MainWindow(QWidget *parent = nullptr); ~MainWindow(); + +private slots: + + void OpenDigitizers(); + void CloseDigitizers(); + + void OpenDataPath(); + + void StartACQ(); + void StopACQ(); + +private: + + Digitizer ** digi; + unsigned int nDigi; + + //@----- log msg + QPlainTextEdit * logInfo; + void LogMsg(QString msg); + bool logMsgHTMLMode = true; + + //@----- + QLineEdit * leDataPath; + QLineEdit * lePrefix; + QLineEdit * leComment; + + //@----- Scalar + QMainWindow * scalar; + QLineEdit *** leTrigger; // need to delete manually + QLineEdit *** leAccept; // need to delete manually + + //@----- ACQ + ReadDataThread ** readDataThread; + };