856 lines
38 KiB
C
856 lines
38 KiB
C
|
#ifndef DIGITIZER_H
|
|||
|
#define DIGITIZER_H
|
|||
|
|
|||
|
#include <stdio.h>
|
|||
|
#include <string>
|
|||
|
#include <sstream>
|
|||
|
#include <cmath>
|
|||
|
#include <cstring> ///memset
|
|||
|
#include <iostream> ///cout
|
|||
|
#include <bitset>
|
|||
|
|
|||
|
//#include <TQObject.h>
|
|||
|
//#include <RQ_OBJECT.h>
|
|||
|
|
|||
|
#include "CAENDigitizer.h"
|
|||
|
#include "CAENDigitizerType.h"
|
|||
|
|
|||
|
#include "RegisterAddress.h"
|
|||
|
|
|||
|
#define MaxNChannels 16
|
|||
|
#define MaxRecordLength 0x1fff /// 8191
|
|||
|
|
|||
|
using namespace std;
|
|||
|
|
|||
|
|
|||
|
struct DigitizerChannelSetting {
|
|||
|
|
|||
|
/// combined all DPP, PHA, and PSD
|
|||
|
unsigned int recordLength; /// ch
|
|||
|
unsigned int EventAggr; /// number of events in one aggregate (0=automatic), number of event acculated for read-off
|
|||
|
unsigned int dynamicRange; /// 0 = 2 Vpp, 1 = 0.5 Vpp
|
|||
|
unsigned int preTrigger; /// the number of samples before the trigger in the waveform saved into memory
|
|||
|
float DCOffsetPrecentage; /// precentage of Max ADC
|
|||
|
uint32_t VetoWidth; /// see manual, uint32_t to ensure it is 32 bit
|
|||
|
bool triggerPolarity; /// 0 = on rising edge, 1 = on falling edge
|
|||
|
|
|||
|
uint32_t DPPAlgorithmControl;
|
|||
|
unsigned int baselineSampling;
|
|||
|
unsigned int peakSampling;
|
|||
|
bool pulsePolarity_DPP; /// 0 = positive, 1 = negative
|
|||
|
bool rollOverFlag;
|
|||
|
bool pileUpFlag;
|
|||
|
|
|||
|
uint32_t DPPAlgorithmControl2;
|
|||
|
|
|||
|
unsigned int triggerThreshold; /// [LSB]
|
|||
|
unsigned int triggerHoldOff; /// [ch], Other triggers are inhibited for the overall Trigger Hold‐Off duration.
|
|||
|
|
|||
|
|
|||
|
unsigned int shapedTriggerWidth;
|
|||
|
|
|||
|
|
|||
|
/// PHA
|
|||
|
unsigned int triggerSmoothingFactor; /// 0x0 = disabled; 0x1 = 2 sample; 0x2 = 4 samples; 0x4 = 8 samples; 0x8 = 16 samples; 0x10 = 32 samples; 0x20 = 64 samples; 0x3F = 128 samples
|
|||
|
unsigned int inputRiseTime; /// [ch]
|
|||
|
|
|||
|
unsigned int trapRiseTime; /// [ch]
|
|||
|
unsigned int trapFlatTop; /// [ch]
|
|||
|
unsigned int decayTime; /// [ch]
|
|||
|
unsigned int peakingTime; /// [ch] flatTop delay, where the samples are used for the calculation of the peak height
|
|||
|
unsigned int peakHoldOff; /// [ch] how close must be two trapezoids to be considered piled‐up after the start of flat top
|
|||
|
|
|||
|
unsigned int fineGain;
|
|||
|
unsigned int riseTimeValidWindow; /// [ch] used by the rise time discriminator (RTD) to reject pulses that overlap in the rise time
|
|||
|
|
|||
|
|
|||
|
/// PDS
|
|||
|
unsigned int cfdSetting;
|
|||
|
unsigned int chargeZeroSuppThreshold;
|
|||
|
unsigned int shortGateWidth;
|
|||
|
unsigned int longGateWidth;
|
|||
|
unsigned int gateOffset;
|
|||
|
unsigned int fixedBaseline;
|
|||
|
unsigned int triggerLatency;
|
|||
|
unsigned int thresholdPSDCut;
|
|||
|
unsigned int pureGapThreshold;
|
|||
|
unsigned int earlyBaselineFreeze;
|
|||
|
|
|||
|
};
|
|||
|
|
|||
|
//################################################################
|
|||
|
|
|||
|
class Digitizer{
|
|||
|
|
|||
|
public:
|
|||
|
Digitizer();
|
|||
|
Digitizer(int boardID, int portID = 0);
|
|||
|
~Digitizer();
|
|||
|
|
|||
|
void Reset();
|
|||
|
int OpenDigitizer(int boardID, int portID = 0);/// portID is for optical link for using PCIe card, from 0, 1, 2, 3
|
|||
|
int CloseDigitizer();
|
|||
|
|
|||
|
///=================Settings
|
|||
|
void WriteRegister(uint32_t address, uint32_t value, int ch = -1);
|
|||
|
uint32_t ReadRegister(uint32_t address, unsigned int ch);
|
|||
|
|
|||
|
///common for PHA and PSD digitizers
|
|||
|
void SetChannelMask(uint32_t mask);
|
|||
|
void SetRecordLength(unsigned int lenght, int ch = -1); /// when ch == -1, mean set all channels
|
|||
|
void SetEventAggregation(unsigned int numEvent, int ch = -1);
|
|||
|
void SetInputDynamicRange(unsigned int TwoVol_0_or_halfVol_1, int ch = -1);
|
|||
|
void SetNumSamplePreTrigger(unsigned int nSample, 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);
|
|||
|
|
|||
|
void SetDPPAlgorithmControl(uint32_t bit, bool useControl2 = false, int ch = -1);
|
|||
|
void SetDPPAlgorithmControlBit(unsigned int bitValue, unsigned int bitLength, unsigned int bitSmallestPos, bool useControl2 = false, int ch = -1);
|
|||
|
void SetTrapezoidRescaling(unsigned int rightShiftBits, int ch = -1); /// DPPAlgoritmControl bit-0:5
|
|||
|
void SetPeakSampling(unsigned int bit, int ch = -1); /// DPPAlgoritmControl bit-10:11
|
|||
|
void SetPulsePolarity(bool PositiveIsZero, int ch = -1); /// DPPAlgoritmControl bit-16
|
|||
|
void SetBaselineSampling(unsigned int bit, int ch = -1); /// DPPAlgoritmControl bit-20:22
|
|||
|
void SetRollOverFlag(bool isRollOver, int ch = -1); /// DPPAlgoritmControl bit-26
|
|||
|
void SetPileUpFlag(bool isPileUpFlag, int ch = -1); /// DPPAlgoritmControl bit-27
|
|||
|
|
|||
|
//int SetChannelParity(int ch, bool isPositive);
|
|||
|
//int SetChannelThreshold(int ch, string folder, int threshold);
|
|||
|
//int SetInputDynamicRange(int ch, string folder, int dyRange);
|
|||
|
|
|||
|
int SetAcqMode(string mode);
|
|||
|
|
|||
|
///================ Get Settings
|
|||
|
int GetSerialNumber() {return BoardInfo.SerialNumber;}
|
|||
|
int GetChannelMask() {return channelMask;}
|
|||
|
float GetCh2ns() {return ch2ns;}
|
|||
|
int GetNChannel() {return NChannel;}
|
|||
|
|
|||
|
|
|||
|
int GetChTemperature(int ch) ;
|
|||
|
|
|||
|
|
|||
|
void PrintBoardConfiguration();
|
|||
|
uint32_t GetChannelStatus(unsigned int ch);
|
|||
|
|
|||
|
|
|||
|
///================ ACQ control
|
|||
|
void StopACQ();
|
|||
|
void StartACQ();
|
|||
|
|
|||
|
protected:
|
|||
|
|
|||
|
///---- 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
|
|||
|
int NChannel; /// number of channel
|
|||
|
int ADCbits; /// ADC bit
|
|||
|
int DPPType; /// DPP verion
|
|||
|
unsigned int ADCFullSize; /// pow(2, ADCbits) - 1
|
|||
|
float ch2ns; /// channel to ns
|
|||
|
CAEN_DGTZ_BoardInfo_t BoardInfo;
|
|||
|
|
|||
|
|
|||
|
///----- adjustable parameters
|
|||
|
uint32_t VMEBaseAddress; /// For direct USB or Optical-link connection, VMEBaseAddress must be 0
|
|||
|
CAEN_DGTZ_ConnectionType LinkType;
|
|||
|
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)
|
|||
|
CAEN_DGTZ_DPP_AcqMode_t AcqMode;
|
|||
|
|
|||
|
uint32_t channelMask ; /// the channel mask from NChannel
|
|||
|
DigitizerChannelSetting setting[MaxNChannels];
|
|||
|
|
|||
|
|
|||
|
///------- other parameters
|
|||
|
int ret; /// return value, refer to CAEN_DGTZ_ErrorCode
|
|||
|
bool isConnected;
|
|||
|
|
|||
|
///==========
|
|||
|
virtual int ProgramBoard();
|
|||
|
void ErrorMsg(string header = "");
|
|||
|
};
|
|||
|
|
|||
|
//========================================== methods
|
|||
|
|
|||
|
Digitizer::Digitizer(){
|
|||
|
|
|||
|
portID = -1;
|
|||
|
boardID = -1;
|
|||
|
handle = -1;
|
|||
|
NChannel = 0;
|
|||
|
ADCbits = 1;
|
|||
|
ch2ns = 0;
|
|||
|
BoardInfo = {};
|
|||
|
|
|||
|
channelMask = 0xFFFF;
|
|||
|
for( int ch = 0; ch < MaxNChannels ; ch ++ ) {
|
|||
|
setting[ch] = {};
|
|||
|
setting[ch].recordLength = 2000;
|
|||
|
setting[ch].EventAggr = 0;
|
|||
|
}
|
|||
|
ret = -1;
|
|||
|
|
|||
|
isConnected = false;
|
|||
|
|
|||
|
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
|
|||
|
|
|||
|
}
|
|||
|
|
|||
|
Digitizer::Digitizer(int boardID, int portID){
|
|||
|
Digitizer();
|
|||
|
OpenDigitizer(boardID, portID);
|
|||
|
}
|
|||
|
|
|||
|
Digitizer::~Digitizer(){
|
|||
|
CloseDigitizer();
|
|||
|
}
|
|||
|
|
|||
|
void Digitizer::Reset(){
|
|||
|
ret = CAEN_DGTZ_Reset(handle);
|
|||
|
if( ret != 0 ) ErrorMsg("Reset");
|
|||
|
}
|
|||
|
|
|||
|
int Digitizer::OpenDigitizer(int boardID, int portID){
|
|||
|
|
|||
|
this->boardID = boardID;
|
|||
|
this->portID = portID;
|
|||
|
|
|||
|
/***************************************************/
|
|||
|
/** Open the digitizer and read board information */
|
|||
|
/***************************************************/
|
|||
|
|
|||
|
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) {
|
|||
|
printf("Can't open digitizer\n");
|
|||
|
}else{
|
|||
|
///----- Getting Board Info
|
|||
|
ret = (int) CAEN_DGTZ_GetInfo(handle, &BoardInfo);
|
|||
|
if (ret != 0) {
|
|||
|
printf("Can't read board info\n");
|
|||
|
}else{
|
|||
|
isConnected = true;
|
|||
|
printf("Connected to Model %s with handle %d using %s\n", BoardInfo.ModelName, handle, LinkType == CAEN_DGTZ_USB ? "USB" : "Optical Link");
|
|||
|
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
|
|||
|
}
|
|||
|
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);
|
|||
|
ADCbits = BoardInfo.ADC_NBits;
|
|||
|
ADCFullSize = (unsigned int)( pow(2, ADCbits) -1 );
|
|||
|
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 != V1730_DPP_PHA_CODE) {
|
|||
|
printf("This digitizer does not have DPP-PHA firmware\n");
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
// Check firmware revision (DPP firmwares cannot be used with this demo */
|
|||
|
sscanf(BoardInfo.AMC_FirmwareRel, "%d", &DPPType);
|
|||
|
if (DPPType >= 128) {
|
|||
|
printf("\t==== This digitizer has a DPP firmware!\n");
|
|||
|
printf("\e[32m");
|
|||
|
switch (DPPType){
|
|||
|
case 0x80: printf("\tDPP-PHA for x724 boards \n"); break;
|
|||
|
case 0x82: printf("\tDPP-CI for x720 boards \n"); break;
|
|||
|
case 0x83: printf("\tDPP-PSD for x720 boards \n"); break;
|
|||
|
case 0x84: printf("\tDPP-PSD for x751 boards \n"); break;
|
|||
|
case 0x85: printf("\tDPP-ZLE for x751 boards \n"); break;
|
|||
|
case 0x86: printf("\tDPP-PSD for x743 boards \n"); break;
|
|||
|
case 0x87: printf("\tDPP-QDC for x740 boards \n"); break;
|
|||
|
case 0x88: printf("\tDPP-PSD for x730 boards \n"); break;
|
|||
|
case 0x8B: printf("\tDPP-PHA for x730 boards \n"); break;
|
|||
|
case 0x8C: printf("\tDPP-ZLE for x730 boards \n"); break;
|
|||
|
case 0x8D: printf("\tDPP-DAW for x730 boards \n"); break;
|
|||
|
}
|
|||
|
printf("\e[0m");
|
|||
|
}
|
|||
|
|
|||
|
int probes[MAX_SUPPORTED_PROBES];
|
|||
|
int numProbes;
|
|||
|
ret = CAEN_DGTZ_GetDPP_SupportedVirtualProbes(handle, 1, probes, &numProbes);
|
|||
|
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(){
|
|||
|
|
|||
|
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;
|
|||
|
}
|
|||
|
|
|||
|
}
|
|||
|
|
|||
|
void Digitizer::PrintBoardConfiguration(){
|
|||
|
uint32_t * value = new uint32_t[1];
|
|||
|
CAEN_DGTZ_ReadRegister(handle, (uint32_t) Register::BoardConfiguration, value);
|
|||
|
printf(" 32 28 24 20 16 12 8 4 0\n");
|
|||
|
printf(" | | | | | | | | |\n");
|
|||
|
cout <<" Board Configuration : 0b" << bitset<32>(value[0]) << endl;
|
|||
|
printf(" Bit[ 0] = Auto Data Flush \n");
|
|||
|
printf(" Bit[16] = WaveForm Recording \n");
|
|||
|
printf(" Bit[17] = Extended Time Tag \n");
|
|||
|
printf(" Bit[18] = Record Time Stamp \n");
|
|||
|
printf(" Bit[19] = Record Energy \n");
|
|||
|
printf("====================================== \n");
|
|||
|
}
|
|||
|
|
|||
|
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
|
|||
|
SetRecordLength(2000); /// default 2000 ch
|
|||
|
///ret |= CAEN_DGTZ_SetRecordLength(handle, recordLength);
|
|||
|
|
|||
|
/// Set how many events to accumulate in the board memory before being available for readout
|
|||
|
SetEventAggregation(0);
|
|||
|
///ret |= CAEN_DGTZ_SetDPPEventAggregation(handle, EventAggr, 0);
|
|||
|
|
|||
|
/// 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);
|
|||
|
|
|||
|
if (ret) {
|
|||
|
ErrorMsg("End of ProgramBoard");
|
|||
|
return ret;
|
|||
|
} else {
|
|||
|
return 0;
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
//===========================================================
|
|||
|
void Digitizer::WriteRegister(uint32_t address, uint32_t value, int ch ){
|
|||
|
if( ch < 0 ) {
|
|||
|
ret = CAEN_DGTZ_WriteRegister(handle, address + 0x7000, value);
|
|||
|
}else{
|
|||
|
ret = CAEN_DGTZ_WriteRegister(handle, address + (ch<<8), value);
|
|||
|
}
|
|||
|
if( ret != 0 ) ErrorMsg("WriteRegister");
|
|||
|
}
|
|||
|
|
|||
|
uint32_t Digitizer::ReadRegister(uint32_t address, unsigned int ch = 0){
|
|||
|
uint32_t * Data = new uint32_t[NChannel];
|
|||
|
if( ch < 0 ) {
|
|||
|
ret = CAEN_DGTZ_ReadRegister(handle, address + 0x7000, Data);
|
|||
|
}else{
|
|||
|
ret = CAEN_DGTZ_ReadRegister(handle, address + (ch << 8), Data);
|
|||
|
}
|
|||
|
if( ret != 0 ) ErrorMsg("ReadRegister");
|
|||
|
///printf("ch = %2d | %d \n", ch, Data[0]);
|
|||
|
return Data[0];
|
|||
|
}
|
|||
|
|
|||
|
void Digitizer::SetChannelMask(uint32_t mask){
|
|||
|
channelMask = mask;
|
|||
|
ret |= CAEN_DGTZ_SetChannelEnableMask(handle, channelMask);
|
|||
|
if( ret != 0 ) ErrorMsg("SetChannelMask");
|
|||
|
}
|
|||
|
|
|||
|
void Digitizer::SetRecordLength(unsigned int lenght, int ch){
|
|||
|
if ( ch < 0 ){
|
|||
|
for( int i = 0; i < MaxNChannels; i++ ) setting[i].recordLength = min((int)lenght, MaxRecordLength );
|
|||
|
ret |= CAEN_DGTZ_SetRecordLength(handle, lenght);
|
|||
|
}else{
|
|||
|
setting[ch].recordLength = min((int)lenght, MaxRecordLength );
|
|||
|
WriteRegister((uint32_t) RegisterDPP::RecordLength, setting[ch].recordLength, ch);
|
|||
|
}
|
|||
|
if( ret != 0 ) ErrorMsg("SetRecordLength");
|
|||
|
}
|
|||
|
|
|||
|
void Digitizer::SetEventAggregation(unsigned int numEvent, int ch){
|
|||
|
if( ch < 0 ){
|
|||
|
for( int i = 0; i < MaxNChannels; i++ ) setting[i].EventAggr = numEvent;
|
|||
|
ret |= CAEN_DGTZ_SetDPPEventAggregation(handle, numEvent, 0);
|
|||
|
}else{
|
|||
|
setting[ch].EventAggr = numEvent;
|
|||
|
WriteRegister((uint32_t) RegisterDPP::NumberEventsPerAggregate, numEvent, ch);
|
|||
|
}
|
|||
|
if( ret != 0 ) ErrorMsg("SetEventAggregation");
|
|||
|
}
|
|||
|
|
|||
|
void Digitizer::SetInputDynamicRange(unsigned int TwoVol_0_or_halfVol_1, int ch){
|
|||
|
if( ch < 0 ) {
|
|||
|
for( int i = 0; i < MaxNChannels; i++) setting[i].dynamicRange = TwoVol_0_or_halfVol_1;
|
|||
|
}else{
|
|||
|
setting[ch].dynamicRange = TwoVol_0_or_halfVol_1;
|
|||
|
}
|
|||
|
WriteRegister((uint32_t) Register::InputDynamicRange, TwoVol_0_or_halfVol_1, ch);
|
|||
|
if( ret != 0 ) ErrorMsg("SetInputDynamicRange");
|
|||
|
}
|
|||
|
|
|||
|
void Digitizer::SetNumSamplePreTrigger(unsigned int nSample, int ch){
|
|||
|
if( ch < 0 ) {
|
|||
|
for( int i = 0; i < MaxNChannels; i++) setting[i].preTrigger = nSample;
|
|||
|
}else{
|
|||
|
setting[ch].preTrigger = nSample;
|
|||
|
}
|
|||
|
WriteRegister((uint32_t) RegisterDPP::PreTrigger, nSample, ch);
|
|||
|
if( ret != 0 ) ErrorMsg("SetNumSamplePreTrigger");
|
|||
|
}
|
|||
|
|
|||
|
void Digitizer::SetDCOffset(float offsetPrecentage, int ch){
|
|||
|
if( ch < 0 ) {
|
|||
|
for( int i = 0; i < MaxNChannels; i++) setting[i].DCOffsetPrecentage = offsetPrecentage;
|
|||
|
}else{
|
|||
|
setting[ch].DCOffsetPrecentage = offsetPrecentage;
|
|||
|
}
|
|||
|
WriteRegister((uint32_t) RegisterDPP::ChannelDCOffset, uint( ADCFullSize * offsetPrecentage), ch );
|
|||
|
if( ret != 0 ) ErrorMsg("SetDCOffset");
|
|||
|
}
|
|||
|
|
|||
|
void Digitizer::SetVetoWidth(uint32_t bit, int ch){
|
|||
|
if( ch < 0 ) {
|
|||
|
for( int i = 0; i < MaxNChannels; i++) setting[i].VetoWidth = bit;
|
|||
|
}else{
|
|||
|
setting[ch].VetoWidth = bit;
|
|||
|
}
|
|||
|
WriteRegister((uint32_t) RegisterDPP::VetoWidth, bit, ch);
|
|||
|
if( ret != 0 ) ErrorMsg("SetVetoWidth");
|
|||
|
}
|
|||
|
|
|||
|
void Digitizer::SetTriggerPolarity(bool RiseingIsZero, int ch ){
|
|||
|
if( ch < 0 ) {
|
|||
|
ret = 0;
|
|||
|
for (int i = 0; i < NChannel; i++){
|
|||
|
setting[i].triggerPolarity = RiseingIsZero;
|
|||
|
ret |= CAEN_DGTZ_SetTriggerPolarity(handle, i, CAEN_DGTZ_TriggerPolarity_t(RiseingIsZero));
|
|||
|
}
|
|||
|
}else{
|
|||
|
setting[ch].triggerPolarity = RiseingIsZero;
|
|||
|
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, bool useControl2, 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
|
|||
|
|
|||
|
uint32_t address = (uint32_t) RegisterDPP::DPPAlgorithmControl;
|
|||
|
if( useControl2 == true) {
|
|||
|
if (DPPType == 0x88) address = (uint32_t) RegisterPSD::DPPAlgorithmControl2;
|
|||
|
if (DPPType == 0x8B) address = (uint32_t) RegisterPHA::DPPAlgorithmControl2;
|
|||
|
if (DPPType != 0x88 && DPPType != 0x8B ) {
|
|||
|
printf(" DPP version is nto PSD or PHA, not supported. \n");
|
|||
|
return;
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
if (ch < 0 ){
|
|||
|
for( int i = 0; i < MaxNChannels; i++) setting[i].DPPAlgorithmControl = bit;
|
|||
|
WriteRegister( address, bit);
|
|||
|
}else{
|
|||
|
setting[ch].DPPAlgorithmControl = bit;
|
|||
|
WriteRegister( address, bit, ch);
|
|||
|
}
|
|||
|
if( ret != 0 ) ErrorMsg("SetDPPAlgorithmControl");
|
|||
|
}
|
|||
|
|
|||
|
void Digitizer::SetDPPAlgorithmControlBit(unsigned int bitValue, unsigned int bitLength, unsigned int bitSmallestPos, bool useControl2, int ch){
|
|||
|
uint32_t address = (uint32_t) RegisterDPP::DPPAlgorithmControl;
|
|||
|
if( useControl2 == true){
|
|||
|
if (DPPType == 0x88) address = (uint32_t) RegisterPSD::DPPAlgorithmControl2;
|
|||
|
if (DPPType == 0x8B) address = (uint32_t) RegisterPHA::DPPAlgorithmControl2;
|
|||
|
if (DPPType != 0x88 && DPPType != 0x8B ) {
|
|||
|
printf(" DPP version is nto PSD or PHA, not supported. \n");
|
|||
|
return;
|
|||
|
}
|
|||
|
}
|
|||
|
uint32_t bit ;
|
|||
|
uint32_t bitmask = (uint(pow(2, bitLength)-1) << bitSmallestPos);
|
|||
|
if (ch < 0 ){
|
|||
|
/// take ch-0
|
|||
|
bit = ReadRegister(address, 0);
|
|||
|
bit = (bit & ~bitmask) | (bitValue << bitSmallestPos);
|
|||
|
for( int i = 0; i < MaxNChannels; i++) setting[i].DPPAlgorithmControl = bit;
|
|||
|
}else{
|
|||
|
bit = ReadRegister(address, ch);
|
|||
|
bit = (bit & ~bitmask) | (bitValue << bitSmallestPos);
|
|||
|
setting[ch].DPPAlgorithmControl = bit;
|
|||
|
}
|
|||
|
WriteRegister(address, bit, ch);
|
|||
|
if( ret != 0 ) ErrorMsg("SetDPPAlgorithmControlBit");
|
|||
|
}
|
|||
|
|
|||
|
void Digitizer::SetTrapezoidRescaling(unsigned int rightShiftBits, int ch ){
|
|||
|
SetDPPAlgorithmControlBit(rightShiftBits, 5, 0, false, ch);
|
|||
|
if( ret != 0 ) ErrorMsg("SetTrapezoidRescaling");
|
|||
|
}
|
|||
|
|
|||
|
void Digitizer::SetPeakSampling(unsigned int bit, int ch){
|
|||
|
if (ch < 0 ){
|
|||
|
for( int i = 0; i < MaxNChannels; i++) setting[i].peakSampling = bit;
|
|||
|
}else{
|
|||
|
setting[ch].peakSampling = bit;
|
|||
|
}
|
|||
|
SetDPPAlgorithmControlBit(bit, 2, 12, false, ch);
|
|||
|
if( ret != 0 ) ErrorMsg("SetPeakSampling");
|
|||
|
}
|
|||
|
|
|||
|
void Digitizer::SetPulsePolarity(bool PositiveIsZero, int ch){
|
|||
|
if (ch < 0 ){
|
|||
|
for( int i = 0; i < MaxNChannels; i++) setting[i].pulsePolarity_DPP = PositiveIsZero;
|
|||
|
}else{
|
|||
|
setting[ch].pulsePolarity_DPP = PositiveIsZero;
|
|||
|
}
|
|||
|
SetDPPAlgorithmControlBit(PositiveIsZero, 1, 16, false, ch);
|
|||
|
if( ret != 0 ) ErrorMsg("SetPulsePolarity");
|
|||
|
}
|
|||
|
|
|||
|
void Digitizer::SetBaselineSampling(unsigned int bit, int ch){
|
|||
|
if (ch < 0 ){
|
|||
|
for( int i = 0; i < MaxNChannels; i++) setting[i].baselineSampling = bit;
|
|||
|
}else{
|
|||
|
setting[ch].baselineSampling = bit;
|
|||
|
}
|
|||
|
SetDPPAlgorithmControlBit(bit, 2, 20, false, ch);
|
|||
|
if( ret != 0 ) ErrorMsg("SetBaselineSampling");
|
|||
|
}
|
|||
|
|
|||
|
void Digitizer::SetRollOverFlag(bool isRollOver, int ch){
|
|||
|
if (ch < 0 ){
|
|||
|
for( int i = 0; i < MaxNChannels; i++) setting[i].rollOverFlag = isRollOver;
|
|||
|
}else{
|
|||
|
setting[ch].rollOverFlag = isRollOver;
|
|||
|
}
|
|||
|
SetDPPAlgorithmControlBit(isRollOver, 1, 26, false, ch);
|
|||
|
if( ret != 0 ) ErrorMsg("SetRollOverFlag");
|
|||
|
}
|
|||
|
|
|||
|
void Digitizer::SetPileUpFlag(bool isPileUpFlag, int ch){
|
|||
|
if (ch < 0 ){
|
|||
|
for( int i = 0; i < MaxNChannels; i++) setting[i].pileUpFlag = isPileUpFlag;
|
|||
|
}else{
|
|||
|
setting[ch].pileUpFlag = isPileUpFlag;
|
|||
|
}
|
|||
|
SetDPPAlgorithmControlBit(isPileUpFlag, 1, 27, false, ch);
|
|||
|
if( ret != 0 ) ErrorMsg("SetPileUpFlag");
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
int Digitizer::SetAcqMode(string mode){
|
|||
|
|
|||
|
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];
|
|||
|
}
|
|||
|
|
|||
|
//################################################################
|
|||
|
|
|||
|
class DigitizerPHA : public Digitizer {
|
|||
|
|
|||
|
public:
|
|||
|
DigitizerPHA();
|
|||
|
DigitizerPHA(int boardID, int portID = 0);
|
|||
|
~DigitizerPHA();
|
|||
|
|
|||
|
int ProgramBoard();
|
|||
|
|
|||
|
void GetChannelSetting(int ch);
|
|||
|
|
|||
|
};
|
|||
|
|
|||
|
DigitizerPHA::DigitizerPHA(){
|
|||
|
|
|||
|
}
|
|||
|
|
|||
|
DigitizerPHA::DigitizerPHA(int boardID, int portID){
|
|||
|
OpenDigitizer(boardID, portID);
|
|||
|
}
|
|||
|
|
|||
|
DigitizerPHA::~DigitizerPHA(){
|
|||
|
|
|||
|
}
|
|||
|
|
|||
|
int DigitizerPHA::ProgramBoard(){
|
|||
|
|
|||
|
/// Board Configuration for PHA
|
|||
|
///bx0000 0000 0000 1110 0000 0001 0001 0100 =
|
|||
|
/// | | |||| | | | | ||+- (0) automatic data flush, 0 = disable
|
|||
|
/// | | |||| | | | | |+- (1) decimated smae of waveform, 0 = disable
|
|||
|
/// | | |||| | | | | +- (2) trigger propagation, required in case of coincident trigger
|
|||
|
/// | | |||| | | | +- (8) indivual trigger: must be 1
|
|||
|
/// | | |||| | | + (11) dual trace. use 12:13 bit and 14:15 bit for choice of trace. but the trace recorded in half ADC frequency.
|
|||
|
/// | | |||| | + (12:13) Analog Probe 1, 00 = input, 01 = input 1st derivative, 10 = input 2nd derivative, 11 = Trapezoid
|
|||
|
/// | | |||| + (14:15) Analog Probe 2, 00 = input, 01 = threshold, 10 = Trapezoid - Baseline, 11 = baseline
|
|||
|
/// | | |||+ (16) Waveform recording, 0 = disable, 1 = enable
|
|||
|
/// | | ||+ (17) Enable Extra 2, i.e. 64 bit timestamp
|
|||
|
/// | | |+ (18) time stamp recording: must be 1
|
|||
|
/// | | + (19) peak recording: must be 1
|
|||
|
/// | + (20:23) Digital Virtual probe 1: in mixed mode, virual probe can be enabled. See manual
|
|||
|
/// + (26:28) Digitial Virtual probe 2
|
|||
|
|
|||
|
ret |= CAEN_DGTZ_WriteRegister(handle, (uint32_t) Register::BoardConfiguration , 0x000E0114); /// Channel Control Reg (indiv trg, seq readout) ??
|
|||
|
|
|||
|
ErrorMsg("PHA-ProgramBoard");
|
|||
|
return ret;
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
void DigitizerPHA::GetChannelSetting(int ch){
|
|||
|
|
|||
|
uint32_t * value = new uint32_t[NChannel];
|
|||
|
printf("\e[33m================================================\n");
|
|||
|
printf("================ Getting setting for channel %d \n", ch);
|
|||
|
printf("================================================\e[0m\n");
|
|||
|
///DPP algorithm Control
|
|||
|
CAEN_DGTZ_ReadRegister(handle, 0x1080 + (ch << 8), value);
|
|||
|
printf(" 32 28 24 20 16 12 8 4 0\n");
|
|||
|
printf(" | | | | | | | | |\n");
|
|||
|
cout <<" DPP algorithm Control : 0b" << bitset<32>(value[0]) << endl;
|
|||
|
|
|||
|
int trapRescaling = int(value[0]) & 31 ;
|
|||
|
int polarity = int(value[0] >> 16); /// in bit[16]
|
|||
|
int baseline = int(value[0] >> 20) ; /// in bit[22:20]
|
|||
|
int NsPeak = int(value[0] >> 12); /// in bit[13:12]
|
|||
|
///DPP algorithm Control 2
|
|||
|
CAEN_DGTZ_ReadRegister(handle, 0x10A0 + (ch << 8), value);
|
|||
|
cout <<" DPP algorithm Control 2: 0b" << bitset<32>(value[0]) << endl;
|
|||
|
|
|||
|
printf("* = multiple of 8 \n");
|
|||
|
printf("** = multiple of 16 \n");
|
|||
|
|
|||
|
printf("==========----- input \n");
|
|||
|
CAEN_DGTZ_ReadRegister(handle, 0x1020 + (ch << 8), value); printf("%20s %d ch \n", "Record Length", value[0] * 8); ///Record length
|
|||
|
CAEN_DGTZ_ReadRegister(handle, 0x1038 + (ch << 8), value); printf("%20s %d ch \n", "Pre-tigger", value[0] * 4); ///Pre-trigger
|
|||
|
printf("%20s %s \n", "polarity", (polarity & 1) == 0 ? "Positive" : "negative"); ///Polarity
|
|||
|
printf("%20s %.0f sample \n", "Ns baseline", pow(4, 1 + baseline & 7)); ///Ns baseline
|
|||
|
CAEN_DGTZ_ReadRegister(handle, 0x1098 + (ch << 8), value); printf("%20s %.2f %% of %d\n", "DC offset", value[0] * 100./ ADCFullSize, ADCFullSize); ///DC offset
|
|||
|
CAEN_DGTZ_ReadRegister(handle, 0x1028 + (ch << 8), value); printf("%20s %.1f Vpp \n", "input Dynamic", value[0] == 0 ? 2 : 0.5); ///InputDynamic
|
|||
|
|
|||
|
printf("==========----- discriminator \n");
|
|||
|
CAEN_DGTZ_ReadRegister(handle, 0x106C + (ch << 8), value); printf("%20s %d LSB\n", "Threshold", value[0]); ///Threshold
|
|||
|
CAEN_DGTZ_ReadRegister(handle, 0x1074 + (ch << 8), value); printf("%20s %d ch \n", "trigger hold off *", value[0] * 8); ///Trigger Hold off
|
|||
|
CAEN_DGTZ_ReadRegister(handle, 0x1054 + (ch << 8), value); printf("%20s %d sample \n", "Fast Dis. smoothing", value[0] ); ///Fast Discriminator smoothing
|
|||
|
CAEN_DGTZ_ReadRegister(handle, 0x1058 + (ch << 8), value); printf("%20s %.1f ns \n", "Input rise time **", value[0] * 8 * ch2ns); ///Input rise time
|
|||
|
|
|||
|
printf("==========----- Trapezoid \n");
|
|||
|
CAEN_DGTZ_ReadRegister(handle, 0x1080 + (ch << 8), value); printf("%20s %d bit = Floor( rise x decay / 64 )\n", "Trap. Rescaling", trapRescaling ); ///Trap. Rescaling Factor
|
|||
|
CAEN_DGTZ_ReadRegister(handle, 0x105C + (ch << 8), value); printf("%20s %.1f ns \n", "Trap. rise time **", value[0] * 8 * ch2ns ); ///Trap. rise time, 2 for 1 ch to 2ns
|
|||
|
CAEN_DGTZ_ReadRegister(handle, 0x1060 + (ch << 8), value);
|
|||
|
int flatTopTime = value[0] * 8 * ch2ns; printf("%20s %d ns \n", "Trap. flat time **", flatTopTime); ///Trap. flat time
|
|||
|
CAEN_DGTZ_ReadRegister(handle, 0x1068 + (ch << 8), value); printf("%20s %.1f ns \n", "Decay time **", value[0] * 8 * ch2ns); ///Trap. pole zero
|
|||
|
CAEN_DGTZ_ReadRegister(handle, 0x1064 + (ch << 8), value); printf("%20s %.1f ns = %.2f %% \n", "peaking time **", value[0] * 8 * ch2ns, value[0] * 800. * ch2ns / flatTopTime ); //Peaking time
|
|||
|
printf("%20s %.0f sample\n", "Ns peak", pow(4, NsPeak & 3)); //Ns peak
|
|||
|
CAEN_DGTZ_ReadRegister(handle, 0x1078 + (ch << 8), value); printf("%20s %.1f ns \n", "Peak hole off **", value[0] * 8 *ch2ns ); ///Peak hold off
|
|||
|
|
|||
|
printf("==========----- Other \n");
|
|||
|
CAEN_DGTZ_ReadRegister(handle, 0x10C4 + (ch << 8), value); printf("%20s %d \n", "Energy fine gain ?", value[0]); ///Energy fine gain
|
|||
|
|
|||
|
printf("========================================= end of ch-%d\n", ch);
|
|||
|
|
|||
|
}
|
|||
|
|
|||
|
//################################################################
|
|||
|
|
|||
|
class DigitizerPSD : public Digitizer {
|
|||
|
public:
|
|||
|
DigitizerPSD();
|
|||
|
DigitizerPSD(int boardID, int portID = 0);
|
|||
|
~DigitizerPSD();
|
|||
|
|
|||
|
//int ProgramBoard();
|
|||
|
//
|
|||
|
//void GetChannelSetting(int ch);
|
|||
|
|
|||
|
};
|
|||
|
|
|||
|
|
|||
|
DigitizerPSD::DigitizerPSD(){
|
|||
|
|
|||
|
}
|
|||
|
|
|||
|
DigitizerPSD::DigitizerPSD(int boardID, int portID){
|
|||
|
OpenDigitizer(boardID, portID);
|
|||
|
}
|
|||
|
|
|||
|
DigitizerPSD::~DigitizerPSD(){
|
|||
|
|
|||
|
}
|
|||
|
#endif
|