FSUDAQ/ClassDigitizer.cpp

671 lines
31 KiB
C++
Raw Normal View History

2022-08-09 16:02:45 -04:00
#include "ClassDigitizer.h"
Digitizer::Digitizer(){
portID = -1;
boardID = -1;
handle = -1;
NChannel = 0;
ADCbits = 1;
DPPType = 0;
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();
2022-08-09 16:02:45 -04:00
settingFileName = "";
settingFileExist = false;
settingFile = NULL;
ret = -1;
isConnected = false;
AcqRun = false;
}
Digitizer::Digitizer(int boardID, int portID){
Digitizer();
OpenDigitizer(boardID, portID);
}
Digitizer::~Digitizer(){
CloseDigitizer();
delete data;
2022-08-09 16:02:45 -04:00
///delete settingFile; /// not needed, settingFile open and close at everytime
}
void Digitizer::Reset(){
ret = CAEN_DGTZ_Reset(handle);
if( ret != 0 ) ErrorMsg("Reset");
}
2022-08-04 18:02:03 -04:00
int Digitizer::OpenDigitizer(int boardID, int portID, bool verbose){
this->boardID = boardID;
this->portID = portID;
/***************************************************/
/** Open the digitizer and read board information */
/***************************************************/
2022-08-04 18:02:03 -04:00
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) {
2022-08-04 18:02:03 -04:00
if( verbose) printf("Can't open digitizer\n");
2022-08-05 16:32:46 -04:00
return -1;
}else{
///----- Getting Board Info
ret = (int) CAEN_DGTZ_GetInfo(handle, &BoardInfo);
if (ret != 0) {
2022-08-04 18:02:03 -04:00
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
2022-08-04 18:02:03 -04:00
}
ADCbits = BoardInfo.ADC_NBits;
ADCFullSize = (unsigned int)( pow(2, ADCbits) -1 );
2022-08-04 18:02:03 -04:00
if( verbose) {
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 DPPType;
sscanf(BoardInfo.AMC_FirmwareRel, "%d", &DPPType);
if (DPPType < 128) {
2022-08-04 18:02:03 -04:00
if( verbose) printf("This digitizer does not have DPP-PHA firmware\n");
}
}
}
///====================== Check DPP firmware revision
sscanf(BoardInfo.AMC_FirmwareRel, "%d", &DPPType);
if (DPPType >= 0x80 && verbose) {
printf("\t==== This digitizer has a DPP firmware!\n");
printf("\e[32m");
switch (DPPType){
case V1724_DPP_PHA_CODE: printf("\tDPP-PHA for x724 boards \n"); break;
case V1720_DPP_CI_CODE : printf("\tDPP-CI for x720 boards \n"); break;
case V1720_DPP_PSD_CODE: printf("\tDPP-PSD for x720 boards \n"); break;
case V1751_DPP_PSD_CODE: printf("\tDPP-PSD for x751 boards \n"); break;
case V1751_DPP_ZLE_CODE: printf("\tDPP-ZLE for x751 boards \n"); break;
case V1743_DPP_CI_CODE: printf("\tDPP-PSD for x743 boards \n"); break;
case V1740_DPP_QDC_CODE: printf("\tDPP-QDC for x740 boards \n"); break;
case V1730_DPP_PSD_CODE: printf("\tDPP-PSD for x730 boards \n"); break;
case V1730_DPP_PHA_CODE: printf("\tDPP-PHA for x730 boards \n"); break;
case V1730_DPP_ZLE_CODE: printf("\tDPP-ZLE for x730 boards \n"); break;
case V1730_DPP_DAW_CODE: printf("\tDPP-DAW for x730 boards \n"); break;
}
printf("\e[0m");
}
///======================= Check virtual probe
int probes[MAX_SUPPORTED_PROBES];
int numProbes;
ret = CAEN_DGTZ_GetDPP_SupportedVirtualProbes(handle, 1, probes, &numProbes);
2022-08-04 18:02:03 -04:00
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 ) {
ProgramBoard();
}
return ret;
}
int Digitizer::CloseDigitizer(){
2022-08-06 01:38:01 -04:00
if( !isConnected ) return 0;
2022-08-04 18:02:03 -04:00
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);
data->FreeMemory(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(){
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
2022-08-05 16:32:46 -04:00
SetRecordLength(2000); /// ns
/// Set Extras 2 to enable, this override Accusition mode, focring list mode
2022-08-05 16:32:46 -04:00
ret |= CAEN_DGTZ_WriteRegister(handle, Register::BoardConfiguration , 0x00E8114 );
/// Set how many events to accumulate in the board memory before being available for readout
SetEventAggregation(0); /// when zero, digitizer auto set
/// 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 */
ret |= CAEN_DGTZ_SetExtTriggerInputMode(handle, CAEN_DGTZ_TRGMODE_ACQ_ONLY);
/** Set the mode used to syncronize the acquisition between different boards.
In this example the sync is disabled */
ret |= CAEN_DGTZ_SetRunSynchronizationMode(handle, CAEN_DGTZ_RUN_SYNC_Disabled);
ErrorMsg("End of ProgramBoard");
return ret;
}
//========================================================= ACQ control
void Digitizer::StartACQ(){
if ( AcqRun ) return;
ret = CAEN_DGTZ_SWStartAcquisition(handle);
if( ret != 0 ) {
ErrorMsg("Start ACQ");
return;
}
printf("Acquisition Started for Board %d\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;
}
void Digitizer::ReadData(){
uint32_t BufferSize = 10000000;
//char buffer[10000];
char *buffer;
buffer = (char *) malloc( BufferSize);
//ret = CAEN_DGTZ_MallocReadoutBuffer(handle, &buffer, &BufferSize);
printf("Allocated %d byte for buffer \n", BufferSize);
//ErrorMsg("CAEN_DGTZ_MallocReadoutBuffer");
CAEN_DGTZ_DPP_PHA_Event_t * Events[MaxNChannels]; /// events buffer
for( int i = 0 ; i < MaxNChannels ; i++ ) Events[i] = (CAEN_DGTZ_DPP_PHA_Event_t *) malloc( BufferSize);
//ret = CAEN_DGTZ_MallocDPPEvents(handle, reinterpret_cast<void**>(&Events), &BufferSize) ;
printf("Allocated %d byte for Events \n", BufferSize);
//ErrorMsg("CAEN_DGTZ_MallocReadoutBuffer");
ret = CAEN_DGTZ_ReadData(handle, CAEN_DGTZ_SLAVE_TERMINATED_READOUT_MBLT, buffer, &BufferSize);
printf("Read Buffer size %d byte \n", BufferSize);
if (ret) {
ErrorMsg("ReadData");
return;
}
data->nByte = BufferSize;
if (data->nByte == 0 ) {
return;
}
uint32_t NumEvents[MaxNChannels];
ret = (CAEN_DGTZ_ErrorCode) CAEN_DGTZ_GetDPPEvents(handle, buffer, BufferSize, reinterpret_cast<void**>(&Events), NumEvents);
for( int i = 0 ; i < MaxNChannels; i++){
printf(" extracted %d events in ch-%02d\n", NumEvents[i], i);
}
ErrorMsg("GetDPPEvents");
}
//===========================================================
void Digitizer::WriteRegister(uint32_t address, uint32_t value, int ch ){
/// only for channel setting.
if( ch < 0 ) {
ret = CAEN_DGTZ_WriteRegister(handle, address + 0x7000, value);
for( int i = 0; i < NChannel; i++) EditByte(value, address + (i << 8));
}else{
ret = CAEN_DGTZ_WriteRegister(handle, address + (ch<<8), value);
EditByte( value, address + (ch<<8) );
}
ErrorMsg("WriteRegister");
}
2022-08-09 17:31:36 -04:00
uint32_t Digitizer::ReadRegister(uint32_t address, int ch, string str ){
uint32_t * Data = new uint32_t[NChannel];
2022-08-09 16:02:45 -04:00
if( address < 0x8000) {
if( ch < 0 ) {
ret = CAEN_DGTZ_ReadRegister(handle, address + 0x7000, Data);
2022-08-09 16:02:45 -04:00
}else{
ret = CAEN_DGTZ_ReadRegister(handle, address + (ch << 8), Data);
}
}else{
2022-08-09 16:02:45 -04:00
ret = CAEN_DGTZ_ReadRegister(handle, address, Data);
}
ErrorMsg("ReadRegister");
if( str != "" ) printf("%s : 0x%x \n", str.c_str(), Data[0]);
return Data[0];
}
void Digitizer::SetChannelMask(uint32_t mask){
channelMask = mask;
ret |= CAEN_DGTZ_SetChannelEnableMask(handle, channelMask);
EditByteByRegister(Register::DPP::ChannelEnableMask);
ErrorMsg("SetChannelMask");
}
void Digitizer::SetRecordLength(unsigned int ns, int ch){
int ch_coupled = ch + int(pow(-1, ch));
WriteRegister( Register::DPP::RecordLength_G, ns / ch2ns / 8 , ch);
WriteRegister( Register::DPP::RecordLength_G, ns / ch2ns / 8 , ch_coupled);
ErrorMsg("SetRecordLength");
}
void Digitizer::SetEventAggregation(unsigned int numEvent, int ch){
int ch_coupled = ch + int(pow(-1, ch));
WriteRegister( Register::DPP::NumberEventsPerAggregate_G,numEvent, ch);
WriteRegister( Register::DPP::NumberEventsPerAggregate_G,numEvent, ch_coupled);
ErrorMsg("SetEventAggregation");
}
void Digitizer::SetInputDynamicRange(unsigned int TwoVol_0_or_halfVol_1, int ch){ WriteRegister( Register::DPP::InputDynamicRange, TwoVol_0_or_halfVol_1, ch); ErrorMsg("SetInputDynamicRange");}
2022-08-05 16:32:46 -04:00
void Digitizer::SetPreTriggerSample(unsigned int nSample, int ch) { WriteRegister( Register::DPP::PreTrigger, nSample / 4, ch); ErrorMsg("SetPreTriggerSample");}
void Digitizer::SetPreTriggerDuration(unsigned int ns, int ch) { WriteRegister( Register::DPP::PreTrigger, ns / ch2ns / 4, ch); ErrorMsg("SetPreTriggerSample");}
2022-08-04 18:02:03 -04:00
void Digitizer::SetDCOffset(float offsetPrecentage, int ch) { WriteRegister( Register::DPP::ChannelDCOffset, uint( ADCFullSize * offsetPrecentage), ch ); ErrorMsg("SetDCOffset");}
void Digitizer::SetVetoWidth(uint32_t bit, int ch) { WriteRegister( Register::DPP::VetoWidth, bit, ch); ErrorMsg("SetVetoWidth");}
void Digitizer::SetTriggerPolarity(bool RiseingIsZero, int ch ){
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("SetTriggerPolarity");
}
//============================== 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 = selftrigger used to acquire and propagated to the trigger logic;
/// 1 = selftrigger 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("SetDPPAlgorithmControl");
}
void Digitizer::SetBits(uint32_t address, unsigned int bitValue, unsigned int bitLength, unsigned int bitSmallestPos, int ch){
uint32_t bit ;
uint32_t bitmask = (uint(pow(2, bitLength)-1) << bitSmallestPos);
if (ch < 0 ) ch = 0; /// take ch-0
bit = ReadRegister(address, ch);
bit = (bit & ~bitmask) | (bitValue << bitSmallestPos);
WriteRegister(address, bit, ch);
if( ret != 0 ) ErrorMsg("SetBits");
}
void Digitizer::SetExtra2WordOutput(bool OnOff) { SetBits(Register::BoardConfiguration, OnOff, 1, 17); ErrorMsg("PHA-SetExtra2WordOutput");}
int Digitizer::SetAcqMode(string list_mixed){
if( list_mixed == "list"){
AcqMode = CAEN_DGTZ_DPP_ACQ_MODE_List; /// enables the acquisition of time stamps and energy value
}else if ( list_mixed == "mixed"){
AcqMode = CAEN_DGTZ_DPP_ACQ_MODE_Mixed; /// enables the acquisition of both waveforms, energies, and timestamps.
}else{
printf("############ AcqMode must be either list or mixed\n");
return -1;
}
int ret = 0;
if( isConnected ){
/********************* Set the DPP acquisition mode
This setting affects the modes Mixed and List (see CAEN_DGTZ_DPP_AcqMode_t definition for details)
CAEN_DGTZ_DPP_SAVE_PARAM_EnergyOnly Only energy (DPP-PHA) or charge (DPP-PSD/DPP-CI v2) is returned
CAEN_DGTZ_DPP_SAVE_PARAM_TimeOnly Only time is returned
CAEN_DGTZ_DPP_SAVE_PARAM_EnergyAndTime Both energy/charge and time are returned
CAEN_DGTZ_DPP_SAVE_PARAM_None No histogram data is returned */
if( AcqMode == CAEN_DGTZ_DPP_ACQ_MODE_List){
ret = CAEN_DGTZ_SetDPPAcquisitionMode(handle, AcqMode, CAEN_DGTZ_DPP_SAVE_PARAM_EnergyAndTime);
}
if( AcqMode == CAEN_DGTZ_DPP_ACQ_MODE_Mixed ){
///ret = CAEN_DGTZ_SetDPPAcquisitionMode(handle, AcqMode, CAEN_DGTZ_DPP_SAVE_PARAM_TimeOnly);
ret = CAEN_DGTZ_SetDPPAcquisitionMode(handle, AcqMode, CAEN_DGTZ_DPP_SAVE_PARAM_EnergyAndTime);
}
SetExtra2WordOutput(true);
if( ret == 0 ) {
printf("Setting digitizer to \e[33m%s\e[0m mode.\n", list_mixed.c_str());
}else{
ErrorMsg("Set AcqMode");
}
}
return ret;
}
int Digitizer::GetChTemperature(int ch){
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("GetChTemperature");
return temp[0];
}
2022-08-09 17:31:36 -04:00
void Digitizer::PrintACQStatue(){
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;
2022-08-09 17:31:36 -04:00
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);
}
//========================================== setting file IO
2022-08-09 16:02:45 -04:00
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);
2022-08-09 16:02:45 -04:00
}else{
settingFileExist = true;
}
}
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
EditByteByRegister(Register::DPP::BoardConfiguration);
EditByteByRegister(Register::DPP::GlobalTriggerMask);
EditByteByRegister(Register::DPP::ChannelEnableMask);
EditByteByRegister(Register::DPP::ROM_BoardVersion);
EditByteByRegister(Register::DPP::ROM_BoardFromFactor);
EditByteByRegister(Register::DPP::ROM_BoardIDByte1);
EditByteByRegister(Register::DPP::ROM_BoardIDByte0);
EditByteByRegister(Register::DPP::ROM_BoardSerialNumByte1);
EditByteByRegister(Register::DPP::ROM_BoardSerialNumByte0);
EditByteByRegister(Register::DPP::ROCFPGAFirmwareRevision);
EditByteByRegister(Register::DPP::BoardInfo);
///================ channel settings
for( int ch = 0; ch < NChannel ; ch++){
EditByteByRegister(Register::DPP::RecordLength_G, ch);
EditByteByRegister(Register::DPP::InputDynamicRange, ch);
EditByteByRegister(Register::DPP::PreTrigger, ch);
EditByteByRegister(Register::DPP::ChannelDCOffset, ch);
EditByteByRegister(Register::DPP::NumberEventsPerAggregate_G, ch);
EditByteByRegister(Register::DPP::DPPAlgorithmControl, ch);
EditByteByRegister(Register::DPP::AMCFirmwareRevision, ch);
EditByteByRegister(Register::DPP::VetoWidth, ch);
if( DPPType == 0x8B ) { /// DPP-PHA
EditByteByRegister(Register::DPP::PHA::TriggerThreshold, ch);
EditByteByRegister(Register::DPP::PHA::RCCR2SmoothingFactor, ch);
EditByteByRegister(Register::DPP::PHA::RiseTimeValidationWindow, ch);
EditByteByRegister(Register::DPP::PHA::TriggerHoldOffWidth, ch);
EditByteByRegister(Register::DPP::PHA::InputRiseTime, ch);
EditByteByRegister(Register::DPP::PHA::ShapedTriggerWidth, ch);
EditByteByRegister(Register::DPP::PHA::TrapezoidRiseTime, ch);
EditByteByRegister(Register::DPP::PHA::TrapezoidFlatTop, ch);
EditByteByRegister(Register::DPP::PHA::DecayTime, ch);
EditByteByRegister(Register::DPP::PHA::PeakingTime, ch);
EditByteByRegister(Register::DPP::PHA::PeakHoldOff, ch);
EditByteByRegister(Register::DPP::PHA::DPPAlgorithmControl2_G, ch);
EditByteByRegister(Register::DPP::PHA::FineGain, 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);
2022-08-09 16:02:45 -04:00
///printf(" data at pos %lu : %x \n", ftell(settingFile), lala[0]);
fclose (settingFile);
return lala[0];
}
void Digitizer::EditByte(unsigned int value, uint32_t filePos){
if ( !settingFileExist ) return ;
2022-08-09 16:02:45 -04:00
if( filePos >= 0x8000 ) filePos = filePos & 0x0FFF;
///printf(" file Pos : 0x%x \n", filePos);
2022-08-09 16:02:45 -04:00
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]);
2022-08-09 16:02:45 -04:00
fclose (settingFile);
}
void Digitizer::EditByteByRegister(uint32_t registerAddress, int ch){
EditByte( ReadRegister(registerAddress, ch), registerAddress);
}