#include "ClassDigitizer.h" Digitizer::Digitizer(){ Initalization(); } Digitizer::Digitizer(int boardID, int portID, bool program, bool verbose){ Initalization(); OpenDigitizer(boardID, portID, program, verbose); } Digitizer::~Digitizer(){ delete data; CloseDigitizer(); } void Digitizer::Initalization(){ portID = -1; boardID = -1; handle = -1; NChannel = 0; ADCbits = 1; DPPType = 0; DPPTypeStr = ""; ADCFullSize = 0; ch2ns = 0; BoardInfo = {}; VMEBaseAddress = 0; LinkType = CAEN_DGTZ_USB; /// default USB IOlev = CAEN_DGTZ_IOLevel_NIM; ///default NIM AcqMode = CAEN_DGTZ_DPP_ACQ_MODE_List; ///default list mode channelMask = 0xFFFF; data = new Data(); settingFileName = ""; settingFileExist = false; settingFile = NULL; ret = -1; isConnected = false; AcqRun = false; } void Digitizer::Reset(){ ret = CAEN_DGTZ_Reset(handle); if( ret != 0 ) ErrorMsg(__func__); ret |= CAEN_DGTZ_WriteRegister(handle, Register::DPP::SoftwareClear, 1); if( ret != 0 ) ErrorMsg("Reset-SoftwareClear"); } void Digitizer::PrintBoard(){ printf("Connected to Model %s with handle %d using %s\n", BoardInfo.ModelName, handle, LinkType == CAEN_DGTZ_USB ? "USB" : "Optical Link"); printf("Sampling rate : %.0f MHz = %.1f ns \n", 1000/ch2ns, ch2ns); printf("Number of Channels : %d = 0x%X\n", NChannel, channelMask); printf("SerialNumber :\e[1m\e[33m %d\e[0m\n", BoardInfo.SerialNumber); printf("ADC bit is \e[33m%d\e[0m, %d = 0x%x\n", ADCbits, ADCFullSize, ADCFullSize); printf("ROC FPGA Release is %s\n", BoardInfo.ROC_FirmwareRel); printf("AMC FPGA Release is %s\n", BoardInfo.AMC_FirmwareRel); } int Digitizer::OpenDigitizer(int boardID, int portID, bool program, bool verbose){ this->boardID = boardID; this->portID = portID; /***************************************************/ /** Open the digitizer and read board information */ /***************************************************/ if( verbose) printf("============= Opening Digitizer at Board %d, Port %d \n", boardID, portID); ///-------- try USB first LinkType = CAEN_DGTZ_USB; /// Link Type ret = (int) CAEN_DGTZ_OpenDigitizer(LinkType, boardID, 0, VMEBaseAddress, &handle); if (ret != 0){ ///---------- try Optical link LinkType = CAEN_DGTZ_OpticalLink ; ret = (int) CAEN_DGTZ_OpenDigitizer(LinkType, portID, boardID, VMEBaseAddress, &handle); } if (ret != 0) { if( verbose) printf("Can't open digitizer\n"); return -1; }else{ ///----- Getting Board Info ret = (int) CAEN_DGTZ_GetInfo(handle, &BoardInfo); if (ret != 0) { if( verbose) printf("Can't read board info\n"); }else{ isConnected = true; NChannel = BoardInfo.Channels; channelMask = pow(2, NChannel)-1; switch(BoardInfo.Model){ case CAEN_DGTZ_V1730: ch2ns = 2.0; break; ///ns -> 500 MSamples/s case CAEN_DGTZ_V1725: ch2ns = 4.0; break; ///ns -> 250 MSamples/s } ADCbits = BoardInfo.ADC_NBits; ADCFullSize = (unsigned int)( pow(2, ADCbits) -1 ); if( verbose) PrintBoard(); sscanf(BoardInfo.AMC_FirmwareRel, "%d", &DPPType); if (DPPType < 128 && verbose) printf("This digitizer does not have DPP-PHA firmware\n"); //SetBoardID(BoardInfo.SerialNumber); } } ///====================== Check DPP firmware revision sscanf(BoardInfo.AMC_FirmwareRel, "%d", &DPPType); switch (DPPType){ case V1724_DPP_PHA_CODE: DPPTypeStr = "DPP-PHA x724"; break; case V1720_DPP_CI_CODE : DPPTypeStr = "DPP-CI x720"; break; case V1720_DPP_PSD_CODE: DPPTypeStr = "DPP-PSD x720"; break; case V1751_DPP_PSD_CODE: DPPTypeStr = "DPP-PSD x751"; break; case V1751_DPP_ZLE_CODE: DPPTypeStr = "DPP-ZLE x751"; break; case V1743_DPP_CI_CODE: DPPTypeStr = "DPP-PSD x743"; break; case V1740_DPP_QDC_CODE: DPPTypeStr = "DPP-QDC x740"; break; case V1730_DPP_PSD_CODE: DPPTypeStr = "DPP-PSD x730"; break; case V1730_DPP_PHA_CODE: DPPTypeStr = "DPP-PHA x730"; break; case V1730_DPP_ZLE_CODE: DPPTypeStr = "DPP-ZLE x730"; break; case V1730_DPP_DAW_CODE: DPPTypeStr = "DPP-DAW x730"; break; } if (DPPType >= 0x80 && verbose) { printf("\t==== This digitizer has a DPP firmware!\n"); printf("\e[32m\t %s \e[0m", DPPTypeStr.c_str()); } ///======================= Check virtual probe int probes[MAX_SUPPORTED_PROBES]; int numProbes; ret = CAEN_DGTZ_GetDPP_SupportedVirtualProbes(handle, 1, probes, &numProbes); if( verbose ){ printf("\t==== supported virtual probe (number of Probe : %d)\n", numProbes); for( int i = 0 ; i < numProbes; i++){ switch (probes[i]){ case 0: printf("\t\t CAEN_DGTZ_DPP_VIRTUALPROBE_Input\n"); break; case 1: printf("\t\t CAEN_DGTZ_DPP_VIRTUALPROBE_Delta\n"); break; case 2: printf("\t\t CAEN_DGTZ_DPP_VIRTUALPROBE_Delta2\n"); break; case 3: printf("\t\t CAEN_DGTZ_DPP_VIRTUALPROBE_Trapezoid\n"); break; case 4: printf("\t\t CAEN_DGTZ_DPP_VIRTUALPROBE_TrapezoidReduced\n"); break; case 5: printf("\t\t CAEN_DGTZ_DPP_VIRTUALPROBE_Baseline\n"); break; case 6: printf("\t\t CAEN_DGTZ_DPP_VIRTUALPROBE_Threshold\n"); break; case 7: printf("\t\t CAEN_DGTZ_DPP_VIRTUALPROBE_CFD\n"); break; case 8: printf("\t\t CAEN_DGTZ_DPP_VIRTUALPROBE_SmoothedInput\n"); break; case 9: printf("\t\t CAEN_DGTZ_DPP_VIRTUALPROBE_None\n"); break; case 10: printf("\t\t CAEN_DGTZ_DPP_DIGITALPROBE_TRGWin\n"); break; case 11: printf("\t\t CAEN_DGTZ_DPP_DIGITALPROBE_Armed\n"); break; case 12: printf("\t\t CAEN_DGTZ_DPP_DIGITALPROBE_PkRun\n"); break; case 13: printf("\t\t CAEN_DGTZ_DPP_DIGITALPROBE_Peaking\n"); break; case 14: printf("\t\t CAEN_DGTZ_DPP_DIGITALPROBE_CoincWin\n"); break; case 15: printf("\t\t CAEN_DGTZ_DPP_DIGITALPROBE_BLHoldoff\n"); break; case 16: printf("\t\t CAEN_DGTZ_DPP_DIGITALPROBE_TRGHoldoff\n"); break; case 17: printf("\t\t CAEN_DGTZ_DPP_DIGITALPROBE_TRGVal\n"); break; case 18: printf("\t\t CAEN_DGTZ_DPP_DIGITALPROBE_ACQVeto\n"); break; case 19: printf("\t\t CAEN_DGTZ_DPP_DIGITALPROBE_BFMVeto\n"); break; case 20: printf("\t\t CAEN_DGTZ_DPP_DIGITALPROBE_ExtTRG\n"); break; case 21: printf("\t\t CAEN_DGTZ_DPP_DIGITALPROBE_OverThr\n"); break; case 22: printf("\t\t CAEN_DGTZ_DPP_DIGITALPROBE_TRGOut\n"); break; case 23: printf("\t\t CAEN_DGTZ_DPP_DIGITALPROBE_Coincidence \n"); break; case 24: printf("\t\t CAEN_DGTZ_DPP_DIGITALPROBE_PileUp \n"); break; case 25: printf("\t\t CAEN_DGTZ_DPP_DIGITALPROBE_Gate \n"); break; case 26: printf("\t\t CAEN_DGTZ_DPP_DIGITALPROBE_GateShort \n"); break; case 27: printf("\t\t CAEN_DGTZ_DPP_DIGITALPROBE_Trigger \n"); break; case 28: printf("\t\t CAEN_DGTZ_DPP_DIGITALPROBE_None \n"); break; case 29: printf("\t\t CAEN_DGTZ_DPP_DIGITALPROBE_BLFreeze \n"); break; case 30: printf("\t\t CAEN_DGTZ_DPP_DIGITALPROBE_Busy \n"); break; case 31: printf("\t\t CAEN_DGTZ_DPP_DIGITALPROBE_PrgVeto \n"); break; } } } ErrorMsg("end of OpenDigitizer"); if( isConnected && program) { ProgramBoard(); } return ret; } int Digitizer::CloseDigitizer(){ if( !isConnected ) return 0; isConnected = false; printf("-------- Closing Digtizer Board : %d Port : %d \n", boardID, portID); printf(" Model %s with handle %d using %s\n", BoardInfo.ModelName, handle, LinkType == CAEN_DGTZ_USB ? "USB" : "Optical Link"); ret = CAEN_DGTZ_SWStopAcquisition(handle); ret |= CAEN_DGTZ_CloseDigitizer(handle); return ret; } void Digitizer::ErrorMsg(string header){ switch (ret){ ///case CAEN_DGTZ_Success : /** 0 */ printf("%s | Operation completed successfully.\n", header.c_str()); break; case CAEN_DGTZ_CommError : /** -1 */ printf("%s | Communication Error.\n", header.c_str()); break; case CAEN_DGTZ_GenericError : /** -2 */ printf("%s | Unspecified error.\n", header.c_str()); break; case CAEN_DGTZ_InvalidParam : /** -3 */ printf("%s | Invalid parameter.\n", header.c_str()); break; case CAEN_DGTZ_InvalidLinkType : /** -4 */ printf("%s | Invalid Link Type.\n", header.c_str()); break; case CAEN_DGTZ_InvalidHandle : /** -5 */ printf("%s | Invalid device handler.\n", header.c_str()); break; case CAEN_DGTZ_MaxDevicesError : /** -6 */ printf("%s | Maximum number of devices exceeded.\n", header.c_str()); break; case CAEN_DGTZ_BadBoardType : /** -7 */ printf("%s | Operation not allowed on this type of board.\n", header.c_str()); break; case CAEN_DGTZ_BadInterruptLev : /** -8 */ printf("%s | The interrupt level is not allowed.\n", header.c_str()); break; case CAEN_DGTZ_BadEventNumber : /** -9 */ printf("%s | The event number is bad.\n", header.c_str()); break; case CAEN_DGTZ_ReadDeviceRegisterFail : /** -10 */ printf("%s | Unable to read the registry.\n", header.c_str()); break; case CAEN_DGTZ_WriteDeviceRegisterFail : /** -11 */ printf("%s | Unable to write the registry.\n", header.c_str()); break; case CAEN_DGTZ_InvalidChannelNumber : /** -13 */ printf("%s | The channel number is invalid.\n", header.c_str()); break; case CAEN_DGTZ_ChannelBusy : /** -14 */ printf("%s | The channel is busy.\n", header.c_str()); break; case CAEN_DGTZ_FPIOModeInvalid : /** -15 */ printf("%s | Invalid FPIO mode.\n", header.c_str()); break; case CAEN_DGTZ_WrongAcqMode : /** -16 */ printf("%s | Wrong Acquistion mode.\n", header.c_str()); break; case CAEN_DGTZ_FunctionNotAllowed : /** -17 */ printf("%s | This function is not allowed on this module.\n", header.c_str()); break; case CAEN_DGTZ_Timeout : /** -18 */ printf("%s | Communication Timeout.\n", header.c_str()); break; case CAEN_DGTZ_InvalidBuffer : /** -19 */ printf("%s | The buffer is invalid.\n", header.c_str()); break; case CAEN_DGTZ_EventNotFound : /** -20 */ printf("%s | The event is not found.\n", header.c_str()); break; case CAEN_DGTZ_InvalidEvent : /** -21 */ printf("%s | The event is invalid.\n", header.c_str()); break; case CAEN_DGTZ_OutOfMemory : /** -22 */ printf("%s | Out of memory.\n", header.c_str()); break; case CAEN_DGTZ_CalibrationError : /** -23 */ printf("%s | Unable to calibrate the board.\n", header.c_str()); break; case CAEN_DGTZ_DigitizerNotFound : /** -24 */ printf("%s | Unbale to open the digitizer.\n", header.c_str()); break; case CAEN_DGTZ_DigitizerAlreadyOpen : /** -25 */ printf("%s | The digitizer is already open.\n", header.c_str()); break; case CAEN_DGTZ_DigitizerNotReady : /** -26 */ printf("%s | The digitizer is not ready.\n", header.c_str()); break; case CAEN_DGTZ_InterruptNotConfigured : /** -27 */ printf("%s | The digitizer has no IRQ configured.\n", header.c_str()); break; case CAEN_DGTZ_DigitizerMemoryCorrupted: /** -28 */ printf("%s | The digitizer flash memory is corrupted.\n", header.c_str()); break; case CAEN_DGTZ_DPPFirmwareNotSupported : /** -29 */ printf("%s | The digitier DPP firmware is not supported in this lib version.\n", header.c_str()); break; case CAEN_DGTZ_InvalidLicense : /** -30 */ printf("%s | Invalid firmware licence.\n", header.c_str()); break; case CAEN_DGTZ_InvalidDigitizerStatus : /** -31 */ printf("%s | The digitizer is found in a corrupted status.\n", header.c_str()); break; case CAEN_DGTZ_UnsupportedTrace : /** -32 */ printf("%s | The given trace is not supported.\n", header.c_str()); break; case CAEN_DGTZ_InvalidProbe : /** -33 */ printf("%s | The given probe is not supported.\n", header.c_str()); break; case CAEN_DGTZ_UnsupportedBaseAddress : /** -34 */ printf("%s | The base address is not supported.\n", header.c_str()); break; case CAEN_DGTZ_NotYetImplemented : /** -99 */ printf("%s | The function is not yet implemented.\n", header.c_str()); break; } } int Digitizer::ProgramBoard(){ printf("----- program Board\n"); ret = CAEN_DGTZ_Reset(handle); if (ret) { printf("ERROR: can't reset the digitizer.\n"); return -1; } /// Board Configuration without PHA or PSD fireware ///bx0000 0000 0000 0000 0000 0000 0001 0000 = /// | | +- (1) trigger overlap not allowed /// | +- (3) test pattern disable /// + (6) Self-trigger polarity, 1 = negative, 0 = Positive ret = CAEN_DGTZ_WriteRegister(handle, (uint32_t) Register::BoardConfiguration , 0x000E0114); /// Channel Control Reg (indiv trg, seq readout) ?? /// Set the I/O level (CAEN_DGTZ_IOLevel_NIM or CAEN_DGTZ_IOLevel_TTL) ret |= CAEN_DGTZ_SetIOLevel(handle, IOlev); /// Set the enabled channels ret |= CAEN_DGTZ_SetChannelEnableMask(handle, channelMask); /// Set the number of samples for each waveform SetRecordLength(2000); /// ns /// Set Extras 2 to enable, this override Accusition mode, focring list mode ret |= CAEN_DGTZ_WriteRegister(handle, Register::BoardConfiguration , 0x00E8114 ); /// Set the digitizer acquisition mode (CAEN_DGTZ_SW_CONTROLLED or CAEN_DGTZ_S_IN_CONTROLLED) ret |= CAEN_DGTZ_SetAcquisitionMode(handle, CAEN_DGTZ_SW_CONTROLLED); /// software command ret |= CAEN_DGTZ_SetDPPAcquisitionMode(handle, AcqMode, CAEN_DGTZ_DPP_SAVE_PARAM_EnergyAndTime); /** Set the digitizer's behaviour when an external trigger arrives: CAEN_DGTZ_TRGMODE_DISABLED: do nothing CAEN_DGTZ_TRGMODE_EXTOUT_ONLY: generate the Trigger Output signal CAEN_DGTZ_TRGMODE_ACQ_ONLY = generate acquisition trigger CAEN_DGTZ_TRGMODE_ACQ_AND_EXTOUT = generate both Trigger Output and acquisition trigger see CAENDigitizer user manual, chapter "Trigger configuration" for details */ //TODO set bit ret |= CAEN_DGTZ_SetExtTriggerInputMode(handle, CAEN_DGTZ_TRGMODE_ACQ_ONLY); ret |= CAEN_DGTZ_SetRunSynchronizationMode(handle, CAEN_DGTZ_RUN_SYNC_Disabled); /// Set how many events to accumulate in the board memory before being available for readout ret |= CAEN_DGTZ_WriteRegister(handle, Register::DPP::NumberEventsPerAggregate_G + 0x7000, 100); ret |= CAEN_DGTZ_WriteRegister(handle, Register::DPP::AggregateOrganization, 0); ret |= CAEN_DGTZ_WriteRegister(handle, Register::DPP::MaxAggregatePerBlockTransfer, 50); ErrorMsg(__func__); return ret; } //========================================================= ACQ control void Digitizer::StartACQ(){ if ( AcqRun ) return; ret = CAEN_DGTZ_SWStartAcquisition(handle); if( ret != 0 ) { ErrorMsg("Start ACQ"); return; } printf("\e[1m\e[33m======= Acquisition Started for Board %d\e[0m\n", boardID); AcqRun = true; } void Digitizer::StopACQ(){ if( !AcqRun ) return; int ret = CAEN_DGTZ_SWStopAcquisition(handle); ret |= CAEN_DGTZ_ClearData(handle); if( ret != 0 ) ErrorMsg("something wrong when try to stop ACQ and clear buffer"); printf("\n\e[1m\e[33m====== Acquisition STOPPED for Board %d\e[0m\n", boardID); AcqRun = false; } unsigned int Digitizer::CalByteForBuffer(){ //TODO unsigned int numAggBLT = ReadRegister(Register::DPP::MaxAggregatePerBlockTransfer); /// Channel Mask /// is takeing waveForm /// Record Length return 0; } void Digitizer::ReadData(){ if( !isConnected ) return; if( data->buffer == NULL ) { printf("need allocate memory for readout buffer\n"); return; } ret = CAEN_DGTZ_ReadData(handle, CAEN_DGTZ_SLAVE_TERMINATED_READOUT_MBLT, data->buffer, &(data->nByte)); uint32_t EventSize = ReadRegister(Register::DPP::EventSize); // Is it as same as data->nByte? //printf("Read Buffer size %d byte, Event Size : %d byte \n", data->nByte, EventSize); if (ret || data->nByte == 0) { ErrorMsg(__func__); return; } } //=========================================================== void Digitizer::WriteRegister(uint32_t address, uint32_t value, int ch ){ if( !isConnected ) return; if( address < 0x8000){ ///printf("0x%x, 0x%x=%u, ch:%d\n", address, value, value, ch); if( ch < 0 ) { ret = CAEN_DGTZ_WriteRegister(handle, address + 0x7000, value); for( int i = 0; i < NChannel; i++) SaveSettingEditByte(value, address + (i << 8)); }else{ ret = CAEN_DGTZ_WriteRegister(handle, address + (ch<<8), value); SaveSettingEditByte( value, address + (ch<<8) ); } }else{ ret = CAEN_DGTZ_WriteRegister(handle, address, value); } ErrorMsg("WriteRegister:" + std::to_string(address)); } uint32_t Digitizer::ReadRegister(uint32_t address, int ch, string str ){ if( !isConnected ) { //TODO read from Setting file; return 0; }else{ uint32_t * data = new uint32_t[NChannel]; if( address < 0x8000) { if( ch < 0 ) { ret = CAEN_DGTZ_ReadRegister(handle, address + 0x7000, data); }else{ ret = CAEN_DGTZ_ReadRegister(handle, address + (ch << 8), data); } }else{ ret = CAEN_DGTZ_ReadRegister(handle, address, data); } ErrorMsg("ReadRegister:" + std::to_string(address)); if( str != "" ) printf("%s : 0x%08x \n", str.c_str(), data[0]); return data[0]; } } void Digitizer::SetChannelMask(uint32_t mask){ if( !isConnected ) return; channelMask = mask; ret |= CAEN_DGTZ_SetChannelEnableMask(handle, channelMask); SaveSettingEditByteByRegister(Register::DPP::ChannelEnableMask); ErrorMsg(__func__); } void Digitizer::SetRecordLength(unsigned int ns, int ch){ WriteRegister( Register::DPP::RecordLength_G, ns / ch2ns / 8 , ch); if( ch >= 0 ) WriteRegister( Register::DPP::RecordLength_G, ns / ch2ns / 8 , ch + int(pow(-1, ch))); ErrorMsg(__func__); } void Digitizer::SetAggregateOrganization(unsigned int bit){ WriteRegister(Register::DPP::AggregateOrganization, bit & 0x7); ErrorMsg(__func__); } void Digitizer::SetEventAggregation(unsigned int numEvent, int ch){ WriteRegister( Register::DPP::NumberEventsPerAggregate_G,numEvent, ch); if( ch >= 0 ) WriteRegister( Register::DPP::NumberEventsPerAggregate_G,numEvent, ch + int(pow(-1, ch))); ErrorMsg(__func__); } void Digitizer::SetMaxAggregatePerBlockTransfer(unsigned int numEvent){ WriteRegister( Register::DPP::MaxAggregatePerBlockTransfer,numEvent); ErrorMsg(__func__); } void Digitizer::SetACQControl(uint32_t bit){ WriteRegister( Register::DPP::AcquisitionControl, bit); ErrorMsg(__func__); } void Digitizer::SetGlobalTriggerMask(uint32_t bit){ WriteRegister( Register::DPP::GlobalTriggerMask, bit); ErrorMsg(__func__); } void Digitizer::SetFrontPanelTRGOUTMask(uint32_t bit){ WriteRegister( Register::DPP::FrontPanelTRGOUTEnableMask, bit); ErrorMsg(__func__); } void Digitizer::SetFrontPanelIOControl(uint32_t bit){ WriteRegister( Register::DPP::FrontPanelIOControl, bit); ErrorMsg(__func__); } void Digitizer::SetTriggerValidationMask(uint32_t bit){ WriteRegister( Register::DPP::TriggerValidationMask, bit); ErrorMsg(__func__); } void Digitizer::SetInputDynamicRange(unsigned int TwoVol_0_or_halfVol_1, int ch){ WriteRegister( Register::DPP::InputDynamicRange, TwoVol_0_or_halfVol_1, ch); ErrorMsg(__func__);} void Digitizer::SetPreTriggerSample(unsigned int nSample, int ch) { WriteRegister( Register::DPP::PreTrigger, nSample / 4, ch); ErrorMsg(__func__);} void Digitizer::SetPreTriggerDuration(unsigned int ns, int ch) { WriteRegister( Register::DPP::PreTrigger, ns / ch2ns / 4, ch); ErrorMsg(__func__);} void Digitizer::SetDCOffset(float offsetPrecentage, int ch) { WriteRegister( Register::DPP::ChannelDCOffset, uint( 0xFFFF * (1.0-offsetPrecentage)), ch ); ErrorMsg(__func__);} void Digitizer::SetVetoWidth(uint32_t bit, int ch) { WriteRegister( Register::DPP::VetoWidth, bit, ch); ErrorMsg(__func__);} void Digitizer::SetTriggerPolarity(bool RiseingIsZero, int ch ){ if( !isConnected ) return; if ( DPPType >= 128 ) return; /// do thing for DPP firmware if( ch < 0 ) { ret = 0; for (int i = 0; i < NChannel; i++){ ret |= CAEN_DGTZ_SetTriggerPolarity(handle, i, CAEN_DGTZ_TriggerPolarity_t(RiseingIsZero)); } }else{ ret = CAEN_DGTZ_SetTriggerPolarity(handle, ch, CAEN_DGTZ_TriggerPolarity_t(RiseingIsZero)); } if( ret != 0 ) ErrorMsg(__func__); } //============================== DPP-Alpgorthm Control void Digitizer::SetDPPAlgorithmControl(uint32_t bit, int ch){ ///============= DPP algorithm control is 32 bit /// [ 0: 5] Trapazoid Rescaling. the trapazoid ADC is 48 bit. it need to bit-shift before the 0x3FFF (14 bit filter) /// [ 8: 9] Decimation. 00 = disable, 01 = 2 samples, 10 = 4 samples, 11 = 8 sample /// [10:11] Decimation Gain. This gain apply to the Trapazoid Rescaling and fine gain /// [12:13] Peak Mean. sample for averaging the trapezoid height calculation. 00 = 1 sample, 01 = 4 samples, 10 = 16 sample, 11 = 64 sample /// [16] pulse polarity. 0 = positve, 1 = negative /// [18:19] Trigger mode. 00 = normal, 01 = coincident, 10 = reserved. 11 = anti coincident /// [20:22] number of samples for the baseline average calculation. 000 = baseline disable (energy not subtraced with baseline) /// 001 = 16 samples /// 010 = 64 samples /// 011 = 256 samples /// 100 = 1024 samples /// 101 = 4096 samples /// 110 = 16384 samples /// 111 = resertved. /// [24] Disable self trigger. 0 = self‐trigger used to acquire and propagated to the trigger logic; /// 1 = self‐trigger only propagated to the trigger logic. /// [26] Enable Roll-Over flag. see manual 0 = disable, 1 = enable /// [27] Enable pile-up flag. ///============= PHA - DPP algorithm control 2 is 32 bit /// [ 0: 1] Local Shaped Trigger mode. see manual /// [ 2] Enable Local Shaped Trigger /// [ 4: 5] Local Trigger Validation mode, see manual /// [ 6] Enable Local Trigger Validation /// [ 8:10] Extra 2 word option. 000 = [0:15] baseline *4 [16:31] extended time stamp /// 001 = reserved /// 010 = [0:15] fine time stamp [16:31] extended time stamp /// 011 = reserved /// 100 = [0:15] total tigger counter [16:31] Lost trigger counter /// 101 = [0:15] event after the zero crosiing [16:31] event before zero crossing /// 110, 111 = reserved. /// [14:15] source of veto. 00 = disable, 01 veto is common to all channels, 10 = veto for coupled channels, 11 = veto comes from negative saturation /// [16:17] Select the step for the trigger counter rate flag. see manual /// [18] baseline calculation is active also when the acquisition is not running. 0 = disbale, 1 = enable /// [19] Tag correlated events. see manual 0 = disbale, 1 = enable /// [29] Enable the optimization of the Baseline Restorer to avoid tails in the energy peaks. 0 = disbale, 1 = enable WriteRegister( Register::DPP::DPPAlgorithmControl, bit, ch); if( ret != 0 ) ErrorMsg(__func__); } unsigned int Digitizer::ReadBits(uint32_t address, unsigned int bitLength, unsigned int bitSmallestPos, int ch ){ int tempCh = ch; if (ch < 0 && address < 0x8000 ) tempCh = 0; /// take ch-0 uint32_t bit = ReadRegister(address, tempCh); bit = (bit >> bitSmallestPos ) & uint(pow(2, bitLength)-1); return bit; } void Digitizer::SetBits(uint32_t address, unsigned int bitValue, unsigned int bitLength, unsigned int bitSmallestPos, int ch){ ///printf("address : 0x%x, value : 0x%x, len : %d, pos : %d, ch : %d \n", address, bitValue, bitLength, bitSmallestPos, ch); uint32_t bit ; uint32_t bitmask = (uint(pow(2, bitLength)-1) << bitSmallestPos); int tempCh = ch; if (ch < 0 && address < 0x8000 ) tempCh = 0; /// take ch-0 bit = ReadRegister(address, tempCh); ///printf("bit : 0x%x, bitmask : 0x%x \n", bit, bitmask); bit = (bit & ~bitmask) | (bitValue << bitSmallestPos); ///printf("bit : 0x%x, ch : %d \n", bit, ch); WriteRegister(address, bit, ch); if( ret != 0 ) ErrorMsg(__func__); } int Digitizer::GetChTemperature(int ch){ if( !isConnected ) return -404; if( BoardInfo.Model != CAEN_DGTZ_V1730 && BoardInfo.Model != CAEN_DGTZ_V1725 && BoardInfo.Model != CAEN_DGTZ_V1751 ) return -404; uint32_t * temp; ret |= CAEN_DGTZ_ReadTemperature(handle, ch, temp); if( ret != 0 ) ErrorMsg(__func__); return temp[0]; } uint32_t Digitizer::PrintRegister(uint32_t address, std::string msg){ if( !isConnected ) return 0 ; printf("\e[33m----------------------------------------------------\n"); printf("------------ %s = 0x%x \n", msg.c_str(), address); printf("----------------------------------------------------\e[0m\n"); uint32_t * value = new uint32_t[1]; CAEN_DGTZ_ReadRegister(handle, address, value); printf(" %*s 32 28 24 20 16 12 8 4 0\n", (int) msg.length(), ""); printf(" %*s | | | | | | | | |\n", (int) msg.length(), ""); printf(" %*s", (int) msg.length(), ""); cout << " : 0b" << bitset<32>(value[0]) << endl; printf(" %*s : 0x%x\n", (int) msg.length(), msg.c_str(), value[0]); return value[0]; } void Digitizer::PrintACQStatue(){ if( !isConnected ) return; unsigned int status = ReadRegister(Register::DPP::AcquisitionStatus); printf("=================== Print ACQ status \n"); printf(" 32 28 24 20 16 12 8 4 0\n"); printf(" | | | | | | | | |\n"); cout <<" 0b" << bitset<32>(status) << endl; printf(" Acq state (0x%1x): %s \n", (status >> 2) & 0x1, ((status >> 2) & 0x1) == 0? "stopped" : "running"); printf(" Event Ready (0x%1x): %s \n", (status >> 3) & 0x1, ((status >> 3) & 0x1) == 0? "no event in buffer" : "event in buffer"); printf(" Event Full (0x%1x): %s \n", (status >> 4) & 0x1, ((status >> 4) & 0x1) == 0? "not full" : "full"); printf(" Clock source (0x%1x): %s \n", (status >> 5) & 0x1, ((status >> 5) & 0x1) == 0? "internal" : "external"); printf(" Board ready (0x%1x): %s \n", (status >> 8) & 0x1, ((status >> 8) & 0x1) == 0? "not ready" : "ready"); printf(" Ch shutDown (0x%1x): %s \n", (status >> 19) & 0x1, ((status >> 19) & 0x1) == 0? "Channels are on" : "channels are shutdown"); printf(" TRG-IN 0x%1x \n", (status >> 16) & 0x1); printf(" Ch temp state 0x%04x \n", (status >> 20) & 0xF); } //===================================================== int Digitizer::ProgramPHABoard(){ ret = CAEN_DGTZ_Reset(handle); printf("======== program board PHA\n"); ret = CAEN_DGTZ_WriteRegister(handle, Register::DPP::RecordLength_G + 0x7000, 625); ret = CAEN_DGTZ_WriteRegister(handle, Register::DPP::BoardConfiguration, 0x4E8115); //TODO change to write register ret = CAEN_DGTZ_SetAcquisitionMode(handle, CAEN_DGTZ_SW_CONTROLLED); /// software command ret |= CAEN_DGTZ_SetIOLevel(handle, CAEN_DGTZ_IOLevel_NIM); ret |= CAEN_DGTZ_SetExtTriggerInputMode(handle, CAEN_DGTZ_TRGMODE_ACQ_ONLY); ret = CAEN_DGTZ_SetChannelEnableMask(handle, 0xFFFF); //ret = CAEN_DGTZ_SetNumEventsPerAggregate(handle, 0); ret = CAEN_DGTZ_SetRunSynchronizationMode(handle, CAEN_DGTZ_RUN_SYNC_Disabled); if( ret != 0 ) { printf("==== set board error.\n"); return 0;} printf("======== program Channels PHA\n"); ret |= CAEN_DGTZ_WriteRegister(handle, Register::DPP::PHA::DecayTime + 0x7000 , 5000 ); ret |= CAEN_DGTZ_WriteRegister(handle, Register::DPP::PHA::TrapezoidFlatTop + 0x7000 , 0x62 ); ret |= CAEN_DGTZ_WriteRegister(handle, Register::DPP::PHA::TrapezoidRiseTime + 0x7000 , 6 ); ret |= CAEN_DGTZ_WriteRegister(handle, Register::DPP::PHA::PeakingTime + 0x7000 , 6 ); ret |= CAEN_DGTZ_WriteRegister(handle, Register::DPP::PHA::RCCR2SmoothingFactor + 0x7000 , 4 ); ret |= CAEN_DGTZ_WriteRegister(handle, Register::DPP::PHA::InputRiseTime + 0x7000 , 6 ); ret |= CAEN_DGTZ_WriteRegister(handle, Register::DPP::PHA::TriggerThreshold + 0x7000 , 1000 ); ret |= CAEN_DGTZ_WriteRegister(handle, Register::DPP::PHA::PeakHoldOff + 0x7000 , 0x3E ); ret |= CAEN_DGTZ_WriteRegister(handle, Register::DPP::PHA::TriggerHoldOffWidth + 0x7000 , 0x3E ); ret |= CAEN_DGTZ_WriteRegister(handle, Register::DPP::PHA::RiseTimeValidationWindow + 0x7000 , 0x0 ); ret |= CAEN_DGTZ_WriteRegister(handle, Register::DPP::ChannelDCOffset + 0x7000 , 0xEEEE ); ret |= CAEN_DGTZ_WriteRegister(handle, Register::DPP::PreTrigger + 0x7000 , 124 ); ret |= CAEN_DGTZ_WriteRegister(handle, Register::DPP::InputDynamicRange + 0x7000 , 0x0 ); ret |= CAEN_DGTZ_WriteRegister(handle, Register::DPP::NumberEventsPerAggregate_G + 0x7000, 100); ret |= CAEN_DGTZ_WriteRegister(handle, Register::DPP::AggregateOrganization, 0); ret |= CAEN_DGTZ_WriteRegister(handle, Register::DPP::MaxAggregatePerBlockTransfer, 40); ret |= CAEN_DGTZ_WriteRegister(handle, Register::DPP::DPPAlgorithmControl + 0x7000, 0xe30200f); if( ret != 0 ) { printf("==== set channels error.\n"); return 0;} printf("End of program board and channels\n"); return ret; } //========================================== setting file IO void Digitizer::OpenSettingBinary(string fileName){ settingFile = NULL; this->settingFileName = fileName; settingFile = fopen(fileName.c_str(), "r+"); if( settingFile == NULL ){ printf("cannot open file %s. \n", fileName.c_str()); CreateAndSaveSettingBinary(fileName); }else{ settingFileExist = true; printf("setting file already exist.\n"); } } void Digitizer::CreateAndSaveSettingBinary(string fileName){ /// for 1 digitizer, 16 channels, needs 0x10XX to 0x1FXX /// Board setting is 0x8000 --> 0x0000 /// Saved date YYYYMMDDHH --> 0x0004 /// Global Trigger Mask 0x810C --> 0x010C /// Channel mask 0x8120 --> 0x0120 /// ROM Board version 0xF030 --> 0x0030 /// Board Form factor 0xF034 --> 0x0034 /// Board ID Byte 1 0xF038 --> 0x0038 /// Board ID Byte 0 0xF03C --> 0x003C /// Board Serial Num Byte1 0xF080 --> 0x0080 /// Board Serial Num Byte0 0xF084 --> 0x0084 /// serial number = byte0 << 8 + byte1 /// ROC fireware version is 0x8124 --> 0x0124 /// Board Info is 0x8140 --> 0x0140 /// ------------------------------------- /// for 1 channel is 0x2000 = 8192 byte should be enough for all setting for 1 board settingFileName = fileName; settingFile = fopen(settingFileName.c_str(), "w+"); unsigned int haha[1] = {0x00000000}; /// 4 bytes for(int i = 0; i < 8192/4 ; i++){ fwrite(haha, sizeof(unsigned int), 1, settingFile); } fseek(settingFile, 0L, SEEK_END); unsigned int inFileSize = ftell(settingFile); printf("Created file : %s. file size : %d Byte\n", settingFileName.c_str(), inFileSize); fclose (settingFile); settingFileExist = true; ///Save board setting SaveSettingEditByteByRegister(Register::DPP::BoardConfiguration); /// 0x8000 SaveSettingEditByteByRegister(Register::DPP::AggregateOrganization); /// 0x800C SaveSettingEditByteByRegister(Register::DPP::GlobalTriggerMask); /// 0x810C SaveSettingEditByteByRegister(Register::DPP::ChannelEnableMask); /// 0x8120 SaveSettingEditByteByRegister(Register::DPP::ROM_BoardVersion); /// 0xF030 SaveSettingEditByteByRegister(Register::DPP::ROM_BoardFromFactor); /// 0xF034 SaveSettingEditByteByRegister(Register::DPP::ROM_BoardIDByte1); /// 0xF038 SaveSettingEditByteByRegister(Register::DPP::ROM_BoardIDByte0); /// 0xF03C SaveSettingEditByteByRegister(Register::DPP::ROM_BoardSerialNumByte1); /// 0xF080 SaveSettingEditByteByRegister(Register::DPP::ROM_BoardSerialNumByte0); /// 0xF084 SaveSettingEditByteByRegister(Register::DPP::FrontPanelTRGOUTEnableMask); /// 0x8110 SaveSettingEditByteByRegister(Register::DPP::FrontPanelIOControl); /// 0x811C SaveSettingEditByteByRegister(Register::DPP::ROCFPGAFirmwareRevision); /// 0x8124 SaveSettingEditByteByRegister(Register::DPP::BoardInfo); /// 0x8140 SaveSettingEditByteByRegister(Register::DPP::DisableExternalTrigger); /// 0x817C SaveSettingEditByteByRegister(Register::DPP::TriggerValidationMask); /// 0x8180 SaveSettingEditByteByRegister(Register::DPP::MaxAggregatePerBlockTransfer); /// 0xEF1C ///================ channel settings for( int ch = 0; ch < NChannel ; ch++){ SaveSettingEditByteByRegister(Register::DPP::RecordLength_G, ch); SaveSettingEditByteByRegister(Register::DPP::InputDynamicRange, ch); SaveSettingEditByteByRegister(Register::DPP::PreTrigger, ch); SaveSettingEditByteByRegister(Register::DPP::ChannelDCOffset, ch); SaveSettingEditByteByRegister(Register::DPP::NumberEventsPerAggregate_G, ch); SaveSettingEditByteByRegister(Register::DPP::DPPAlgorithmControl, ch); SaveSettingEditByteByRegister(Register::DPP::AMCFirmwareRevision, ch); SaveSettingEditByteByRegister(Register::DPP::VetoWidth, ch); if( DPPType == V1730_DPP_PHA_CODE ) { /// DPP-PHA SaveSettingEditByteByRegister(Register::DPP::PHA::TriggerThreshold, ch); SaveSettingEditByteByRegister(Register::DPP::PHA::RCCR2SmoothingFactor, ch); SaveSettingEditByteByRegister(Register::DPP::PHA::RiseTimeValidationWindow, ch); SaveSettingEditByteByRegister(Register::DPP::PHA::TriggerHoldOffWidth, ch); SaveSettingEditByteByRegister(Register::DPP::PHA::InputRiseTime, ch); SaveSettingEditByteByRegister(Register::DPP::PHA::ShapedTriggerWidth, ch); SaveSettingEditByteByRegister(Register::DPP::PHA::TrapezoidRiseTime, ch); SaveSettingEditByteByRegister(Register::DPP::PHA::TrapezoidFlatTop, ch); SaveSettingEditByteByRegister(Register::DPP::PHA::DecayTime, ch); SaveSettingEditByteByRegister(Register::DPP::PHA::PeakingTime, ch); SaveSettingEditByteByRegister(Register::DPP::PHA::PeakHoldOff, ch); SaveSettingEditByteByRegister(Register::DPP::PHA::DPPAlgorithmControl2_G, ch); SaveSettingEditByteByRegister(Register::DPP::PHA::FineGain, ch); } if( DPPType == V1730_DPP_PSD_CODE ) { /// DPP-PSD SaveSettingEditByteByRegister(Register::DPP::PSD::CFDSetting, ch); SaveSettingEditByteByRegister(Register::DPP::PSD::ForcedDataFlush, ch); SaveSettingEditByteByRegister(Register::DPP::PSD::ChargeZeroSuppressionThreshold, ch); SaveSettingEditByteByRegister(Register::DPP::PSD::ShortGateWidth, ch); SaveSettingEditByteByRegister(Register::DPP::PSD::LongGateWidth, ch); SaveSettingEditByteByRegister(Register::DPP::PSD::GateOffset, ch); SaveSettingEditByteByRegister(Register::DPP::PSD::TriggerThreshold, ch); SaveSettingEditByteByRegister(Register::DPP::PSD::FixedBaseline, ch); SaveSettingEditByteByRegister(Register::DPP::PSD::TriggerLatency, ch); SaveSettingEditByteByRegister(Register::DPP::PSD::ShapedTriggerWidth, ch); SaveSettingEditByteByRegister(Register::DPP::PSD::TriggerHoldOffWidth, ch); SaveSettingEditByteByRegister(Register::DPP::PSD::ThresholdForPSDCut, ch); SaveSettingEditByteByRegister(Register::DPP::PSD::PurGapThreshold, ch); SaveSettingEditByteByRegister(Register::DPP::PSD::DPPAlgorithmControl2_G, ch); SaveSettingEditByteByRegister(Register::DPP::PSD::EarlyBaselineFreeze, ch); } } } unsigned long Digitizer::ReadSettingBinary(uint32_t filePos, int ch){ if ( !settingFileExist ) return -1; if( filePos >= 0x8000 ) { filePos = filePos & 0x0FFF; }else{ if( ch >= 0 ) { filePos = filePos + (ch << 8); }else{ return -1; } } settingFile = fopen (settingFileName.c_str(),"r"); fseek( settingFile, filePos, SEEK_SET); ///printf(" at pos %lu \n", ftell(settingFile)); unsigned int lala[1]; size_t dummy = fread( lala, sizeof(unsigned int), 1, settingFile); ///printf(" data at pos %lu : %x \n", ftell(settingFile), lala[0]); fclose (settingFile); return lala[0]; } void Digitizer::SaveSettingEditByte(unsigned int value, uint32_t filePos){ if ( !settingFileExist ) return ; if( filePos >= 0x8000 ) filePos = filePos & 0x0FFF; ///printf(" file Pos : 0x%x \n", filePos); settingFile = fopen (settingFileName.c_str(),"r+"); fseek( settingFile, filePos, SEEK_SET); unsigned int jaja[1] = {value}; size_t dummy = fwrite( jaja, sizeof(unsigned int), 1, settingFile); ///printf("fwrie ret : %d, %x = %d\n", (int)dummy, jaja[0], jaja[0]); fclose (settingFile); } void Digitizer::SaveSettingEditByteByRegister(uint32_t registerAddress, int ch){ SaveSettingEditByte( ReadRegister(registerAddress, ch), registerAddress); }