setup the base for Qt6

This commit is contained in:
carina@hades 2023-04-11 11:13:23 -04:00
commit a35bd6e577
14 changed files with 3421 additions and 0 deletions

38
.gitignore vendored Normal file
View File

@ -0,0 +1,38 @@
*.o
FSUDAQ_Qt6
*~
*.autosave
moc_*
*.a
*.core
*.moc
*.o
*.obj
*.orig
*.rej
*.so
*.so.*
*_pch.h.cpp
*_resource.rc
*.qm
.#*
*.*#
core
!core/
tags
.DS_Store
.directory
*.debug
Makefile*
*.prl
*.app
moc_*.cpp
ui_*.h
qrc_*.cpp
Thumbs.db
*.res
*.rc
/.qmake.cache
/.qmake.stash

18
.vscode/c_cpp_properties.json vendored Normal file
View File

@ -0,0 +1,18 @@
{
"configurations": [
{
"name": "Hades",
"includePath": [
"${workspaceFolder}/**",
"/usr/include/x86_64-linux-gnu/qt6/**",
"/usr/local/cern/root_v6.26.06/include/**"
],
"defines": [],
"compilerPath": "/usr/bin/gcc",
"cStandard": "c17",
"cppStandard": "gnu++17",
"intelliSenseMode": "linux-gcc-x64"
}
],
"version": 4
}

87
.vscode/settings.json vendored Normal file
View File

@ -0,0 +1,87 @@
{
"better-comments.tags": [
{
"tag": "!",
"color": "#FF2D00",
"strikethrough": false,
"backgroundColor": "transparent",
"bold": false,
"italic": false
},
{
"tag": "?",
"color": "#0076FF",
"strikethrough": false,
"backgroundColor": "transparent",
"bold": false,
"italic": false
},
{
"tag": "@",
"color": "#00F8FF",
"strikethrough": false,
"backgroundColor": "transparent",
"bold": false,
"italic": false
},
{
"tag": "/",
"color": "#00A0FF",
"strikethrough": false,
"backgroundColor": "transparent",
"bold": false,
"italic": false
},
{
"tag": "//",
"color": "#474747",
"strikethrough": true,
"backgroundColor": "transparent",
"bold": false,
"italic": false
},
{
"tag": "^",
"color": "#EAF622",
"strikethrough": false,
"backgroundColor": "transparent",
"bold": false,
"italic": false
},
{
"tag": "*",
"color": "#28FF00",
"strikethrough": false,
"backgroundColor": "transparent",
"bold": false,
"italic": false
},
{
"tag": "&",
"color": "#FF06A0",
"strikethrough": false,
"backgroundColor": "transparent",
"bold": false,
"italic": false
},
{
"tag": "~",
"color": "#BE00FF",
"strikethrough": false,
"backgroundColor": "transparent",
"bold": false,
"italic": false
},
{
"tag": "todo",
"color": "#FF8C00",
"strikethrough": false,
"backgroundColor": "transparent",
"bold": false,
"italic": false
}
],
"files.associations": {
"mainWindow.C": "cpp"
}
}

698
ClassData.h Normal file
View File

@ -0,0 +1,698 @@
#ifndef DATA_H
#define DATA_H
#include <stdio.h>
#include <string>
#include <sstream>
#include <cmath>
#include <cstring> ///memset
#include <iostream> ///cout
#include <bitset>
#include <vector>
#include "CAENDigitizerType.h"
#include "macro.h"
#define MaxNData 10000 /// 10k events per channels
class Data{
public:
int DPPType; /// this is set from the boardID from the Board Agg. header when it is > 0
unsigned short boardSN;
float ch2ns;
unsigned int nByte; /// number of byte from read buffer
char *buffer; /// readout buffer
uint32_t AllocatedSize;
double TriggerRate[MaxNChannels]; /// Hz
unsigned long TotNumEvents[MaxNChannels];
unsigned short NumEventsDecoded[MaxNChannels];
/// stored Raw event
bool IsNotRollOverFakeAgg;
unsigned short NumEvents[MaxNChannels];
unsigned long long Timestamp[MaxNChannels][MaxNData]; /// 47 bit
unsigned short fineTime[MaxNChannels][MaxNData]; /// 10 bits, in unit of ch2ns / 1000 = ps
unsigned short Energy[MaxNChannels][MaxNData]; /// 15 bit
unsigned short Energy2[MaxNChannels][MaxNData]; /// 15 bit, in PSD, Energy = Qshort, Energy2 = Qlong
std::vector<unsigned short> Waveform1[MaxNChannels][MaxNData];
std::vector<unsigned short> Waveform2[MaxNChannels][MaxNData];
std::vector<bool> DigiWaveform1[MaxNChannels][MaxNData];
std::vector<bool> DigiWaveform2[MaxNChannels][MaxNData];
public:
Data();
~Data();
void Allocate80MBMemory();
void AllocateMemory(uint32_t size);
void SetSaveWaveToMemory(bool OnOff) { this->SaveWaveToMemory = OnOff; }
void ClearData();
void ClearTriggerRate();
void ClearBuffer();
void CopyBuffer( const char * buffer, const unsigned int size);
void SaveBuffer(const char * fileName);
unsigned int GetPresentFileSize() {return presentFileSizeByte;}
void PrintBuffer() const; //Incorrect
void DecodeBuffer(bool fastDecode, int verbose = 0); /// fastDecode will not save waveform
void DecodeBuffer(char * buffer, unsigned int size, bool fastDecode, int verbose = 0); // for outside data
void PrintStat() const;
void PrintData() const;
protected:
unsigned int nw;
bool SaveWaveToMemory;
///for temperary
std::vector<unsigned short> tempWaveform1;
std::vector<unsigned short> tempWaveform2;
std::vector<bool> tempDigiWaveform1;
std::vector<bool> tempDigiWaveform2;
unsigned int ReadBuffer(unsigned int nWord, int verbose = 0);
int DecodePHADualChannelBlock(unsigned int ChannelMask, bool fastDecode, int verbose);
int DecodePSDDualChannelBlock(unsigned int ChannelMask, bool fastDecode, int verbose);
unsigned int presentFileSizeByte;
unsigned short saveFileIndex;
};
//==========================================
inline Data::Data(){
ch2ns = 2.0;
boardSN = 0;
DPPType = V1730_DPP_PHA_CODE;
IsNotRollOverFakeAgg = false;
buffer = NULL;
for ( int i = 0; i < MaxNChannels; i++) TotNumEvents[i] = 0;
ClearData();
ClearTriggerRate();
SaveWaveToMemory = true;
nw = 0;
saveFileIndex = 0;
}
inline Data::~Data(){
if( buffer != NULL ) delete buffer;
}
inline void Data::AllocateMemory(uint32_t size){
ClearBuffer();
AllocatedSize = size;
buffer = (char *) malloc( AllocatedSize);
printf("Allocated %u byte for buffer = %u words\n", AllocatedSize, AllocatedSize / 4);
}
inline void Data::Allocate80MBMemory(){
AllocateMemory( 80 * 1024 * 1024 ); /// 80 M Byte
}
inline void Data::ClearTriggerRate(){
for( int i = 0 ; i < MaxNChannels; i++) {
TriggerRate[i] = 0.0;
NumEventsDecoded[i] = 0;
}
}
inline void Data::ClearData(){
nByte = 0;
AllocatedSize = 0;
IsNotRollOverFakeAgg = false;
for( int i = 0 ; i < MaxNChannels; i++){
NumEvents[i] = 0;
for( int j = 0; j < MaxNData; j++){
Timestamp[i][j] = 0;
fineTime[i][j] = 0;
Energy[i][j] = 0;
Energy2[i][j] = 0;
Waveform1[i][j].clear();
Waveform2[i][j].clear();
DigiWaveform1[i][j].clear();
DigiWaveform2[i][j].clear();
}
}
tempWaveform1.clear();
tempWaveform2.clear();
tempDigiWaveform1.clear();
tempDigiWaveform2.clear();
}
inline void Data::ClearBuffer(){
delete buffer;
AllocatedSize = 0;
nByte = 0;
}
inline void Data::CopyBuffer(const char * buffer, const unsigned int size){
std::memcpy(this->buffer, buffer, size);
}
inline void Data::SaveBuffer(const char * fileName){
char saveFileName[100];
sprintf(saveFileName, "%s_%03d_%03d_%03u.fsu", fileName , boardSN, DPPType, saveFileIndex);
FILE * haha = fopen(saveFileName, "a+");
fseek(haha, 0L, SEEK_END);
unsigned int inFileSize = ftell(haha); /// unsigned int = Max ~ 4 GB
///printf("file Size = %u Byte\n", inFileSize);
if( inFileSize > (unsigned int)MaxSaveFileSize ) { /// 2 GB
fclose(haha);
saveFileIndex ++;
sprintf(saveFileName, "%s_%03u.fsu", fileName , saveFileIndex);
FILE * haha = fopen(saveFileName, "a+");
}
fwrite(buffer, nByte, 1, haha);
presentFileSizeByte = ftell(haha);
///printf("=========== file Size : %u Byte = %.2f MB\n", presentFileSizeByte, presentFileSizeByte/1024./1024.);
fclose(haha);
}
inline void Data::PrintStat() const{
if( !IsNotRollOverFakeAgg ) {
printf(" this is roll-over fake event or no events.\n");
return;
}
printf("%2s | %6s | %9s | %6s\n", "ch", "# Evt.", "Rate [Hz]", "Tot. Evt.");
printf("---+--------+-----------+----------\n");
for(int ch = 0; ch < MaxNChannels; ch++){
printf("%2d | %6d | %9.2f | %6lu\n", ch, NumEventsDecoded[ch], TriggerRate[ch], TotNumEvents[ch]);
}
printf("---+--------+-----------+----------\n");
}
inline void Data::PrintBuffer() const{
unsigned int length = sizeof(buffer);
for( int i = 0; i < length; i++){
printf("%3d | 0x%08x \n", i, buffer[i]);
}
}
inline void Data::PrintData() const{
printf("============================= Print Data\n");
for( int ch = 0; ch < MaxNChannels ; ch++){
if( NumEvents[ch] == 0 ) continue;
printf("------------ ch : %d, %d \n", ch, NumEvents[ch]);
for( int ev = 0; ev < NumEvents[ch] ; ev++){
printf("%4d, %5u, %15llu, %5u \n", ev, Energy[ch][ev], Timestamp[ch][ev], fineTime[ch][ev]);
}
}
}
//####################################################### Decode
inline unsigned int Data::ReadBuffer(unsigned int nWord, int verbose){
if( buffer == NULL ) return 0;
unsigned int word = 0;
for( int i = 0 ; i < 4 ; i++) word += ((buffer[i + 4 * nWord] & 0xFF) << 8*i);
if( verbose >= 2) printf("%6d | 0x%08X | ", nWord, word);
return word;
}
inline void Data::DecodeBuffer(char * buffer, unsigned int size, bool fastDecode, int verbose){
this->buffer = buffer;
this->nByte = size;
DecodeBuffer(fastDecode, verbose);
}
inline void Data::DecodeBuffer(bool fastDecode, int verbose){
/// verbose : 0 = off, 1 = only energy + timestamp, 2 = show header, 3 = wave
if( buffer == NULL ) {
if( verbose >= 1 ) printf(" buffer is empty \n");
return;
}
if( nByte == 0 ) {
return;
}
nw = 0;
ClearTriggerRate();
do{
if( verbose >= 1 ) printf("Data::DecodeBuffer ######################################### Board Agg.\n");
unsigned int word = ReadBuffer(nw, verbose);
if( ( (word >> 28) & 0xF ) == 0xA ) { /// start of Board Agg
unsigned int nWord = word & 0x0FFFFFFF ;
if( verbose >= 1 ) printf("Number of words in this Agg : %u = %u Byte\n", nWord, nWord * 4);
nw = nw + 1; word = ReadBuffer(nw, verbose);
unsigned int BoardID = ((word >> 27) & 0x1F);
unsigned short pattern = ((word >> 8 ) & 0x7FFF );
bool BoardFailFlag = ((word >> 26) & 0x1 );
unsigned int ChannelMask = ( word & 0xFF ) ;
if( verbose >= 1 ) printf("Board ID(type) : %d, FailFlag = %d, Patten = %u, ChannelMask = 0x%X\n",
BoardID, BoardFailFlag, pattern, ChannelMask);
if( BoardID > 0 ) {
switch(BoardID){
case 0x8 : DPPType = V1730_DPP_PSD_CODE; break;
case 0xB : DPPType = V1730_DPP_PHA_CODE; break;
}
}
nw = nw + 1;
unsigned int bdAggCounter = ReadBuffer(nw, verbose);
if( verbose >= 1 ) printf("Board Agg Counter : %u \n", bdAggCounter & 0x7FFFFF);
nw = nw + 1;
unsigned int bdAggTimeTag = ReadBuffer(nw, verbose);
if( verbose >= 2 ) printf("Agg Counter : %u \n", bdAggTimeTag);
for( int chMask = 0; chMask < MaxNChannels/2 ; chMask ++ ){
if( ((ChannelMask >> chMask) & 0x1 ) == 0 ) continue;
if( verbose >= 2 ) printf("==================== Dual Channel Block, ch Mask : %d, nw : %d\n", chMask *2, nw);
if( DPPType == V1730_DPP_PHA_CODE ) {
if ( DecodePHADualChannelBlock(chMask, fastDecode, verbose) < 0 ) break;
}
if( DPPType == V1730_DPP_PSD_CODE ) {
if ( DecodePHADualChannelBlock(chMask, fastDecode, verbose) < 0 ) break;
}
}
}else{
if( verbose >= 1 ) printf("nw : %d, incorrect buffer header. \n", nw);
break;
}
nw++;
///printf("nw : %d ,x 4 = %d, nByte : %d \n", nw, 4*nw, nByte);
}while(4*nw < nByte);
///Calculate trigger rate and first and last Timestamp
for(int ch = 0; ch < MaxNChannels; ch++){
if( NumEventsDecoded[ch] > 0 ) IsNotRollOverFakeAgg = true;
unsigned long long dTime = Timestamp[ch][NumEvents[ch]-1] - Timestamp[ch][NumEvents[ch] - NumEventsDecoded[ch]];
double sec = dTime * ch2ns / 1e9;
if( sec != 0 && NumEventsDecoded[ch] > 1 ){
TriggerRate[ch] = NumEventsDecoded[ch]/sec;
}
}
}
inline int Data::DecodePHADualChannelBlock(unsigned int ChannelMask, bool fastDecode, int verbose){
nw = nw + 1;
unsigned int word = ReadBuffer(nw, verbose);
bool hasFormatInfo = ((word >> 31) & 0x1);
unsigned int aggSize = ( word & 0x7FFFFFFF ) ;
if( verbose >= 2 ) printf("Dual Channel size : %d \n", aggSize);
unsigned int nSample = 0; /// wave form;
unsigned int nEvents = 0;
unsigned int extra2Option = 0;
bool hasExtra2 = false;
bool hasDualTrace = 0 ;
if( hasFormatInfo ){
nw = nw + 1; word = ReadBuffer(nw, verbose);
nSample = ( word & 0xFFFF ) * 8;
extra2Option = ( (word >> 24 ) & 0x7 );
hasExtra2 = ( (word >> 28 ) & 0x1 );
if( !fastDecode || verbose >= 2){
unsigned int digitalProbe = ( (word >> 16 ) & 0xF );
unsigned int analogProbe2 = ( (word >> 20 ) & 0x3 );
unsigned int analogProbe1 = ( (word >> 22 ) & 0x3 );
bool hasWaveForm = ( (word >> 27 ) & 0x1 );
bool hasTimeStamp = ( (word >> 29 ) & 0x1 );
bool hasEnergy = ( (word >> 30 ) & 0x1 );
hasDualTrace = ( (word >> 31 ) & 0x1 );
if( verbose >= 2 ) {
printf("DualTrace : %d, Energy : %d, Time: %d, Wave : %d, Extra2: %d \n",
hasDualTrace, hasEnergy, hasTimeStamp, hasWaveForm, hasExtra2);
}
if( verbose >= 3){
if( hasExtra2 ){
printf("...... extra 2 : ");
switch (extra2Option){
case 0: printf("[0:15] trapwzoid baseline * 4 [16:31] Extended timestamp (16-bit)\n"); break;
case 1: printf("Reserved\n"); break;
case 2: printf("[0:9] Fine time stamp [10:15] Reserved [16:31] Extended timestamp (16-bit)\n"); break;
case 3: printf("Reserved\n"); break;
case 4: printf("[0:15] Total trigger counter [16:31] Lost trigger counter\n"); break;
case 5: printf("[0:15] Event after Zero crossing [16:31] Event before Zero crossing\n"); break;
case 6: printf("Reserved\n"); break;
case 7: printf("Reserved\n"); break;
}
}
printf("...... Analog Probe 1 : ");
switch (analogProbe1 ){
case 0 : printf("Input \n"); break;
case 1 : printf("RC-CR (1st derivative) \n"); break;
case 2 : printf("RC-CR2 (2st derivative) \n"); break;
case 3 : printf("trapazoid \n"); break;
}
printf("...... Analog Probe 2 : ");
switch (analogProbe2 ){
case 0 : printf("Input \n"); break;
case 1 : printf("Theshold \n"); break;
case 2 : printf("trapezoid - baseline \n"); break;
case 3 : printf("baseline \n"); break;
}
printf("...... Digital Probe : ");
switch (digitalProbe ){
case 0 : printf("Peaking \n"); break;
case 1 : printf("Armed (trigger) \n"); break;
case 2 : printf("Peak Run \n"); break;
case 3 : printf("Pile up \n"); break;
case 4 : printf("Peaking \n"); break;
case 5 : printf("Trigger Validation Window \n"); break;
case 6 : printf("Baseline for energy calculation \n"); break;
case 7 : printf("Trigger holdoff \n"); break;
case 8 : printf("Trigger Validation \n"); break;
case 9 : printf("ACQ Busy \n"); break;
case 10 : printf("Trigger window \n"); break;
case 11 : printf("Ext. Trigger \n"); break;
case 12 : printf("Busy = memory is full \n"); break;
}
}
}
nEvents = (aggSize - 2) / (nSample/2 + 2 + hasExtra2 );
if( verbose >= 2 ) printf("-------------------nEvents : %d \n", nEvents);
}else{
if( verbose >= 2 ) printf("does not has format info. unable to read buffer.\n");
return 0;
}
///========== decode an event
for( int ev = 0; ev < nEvents ; ev++){
if( verbose >= 2 ) printf("------ event : %d\n", ev);
nw = nw +1 ; word = ReadBuffer(nw, verbose);
bool channelTag = ((word >> 31) & 0x1);
unsigned int timeStamp0 = (word & 0x7FFFFFFF);
int channel = ChannelMask*2 + channelTag;
if( verbose >= 2 ) printf("ch : %d, timeStamp0 %u \n", channel, timeStamp0);
//TODO Skip
///===== read waveform
if( !fastDecode && SaveWaveToMemory ) {
tempWaveform1.clear();
tempWaveform2.clear();
tempDigiWaveform1.clear();
}
unsigned int triggerAtSample = 0 ;
if( fastDecode ){
nw += nSample/2;
}else{
for( int wi = 0; wi < nSample/2; wi++){
nw = nw +1 ; word = ReadBuffer(nw, verbose-2);
///The CAEN manual is wrong, the bit [31:16] is anaprobe 1
bool isTrigger1 = (( word >> 31 ) & 0x1 );
bool dp1 = (( word >> 30 ) & 0x1 );
unsigned short wave1 = (( word >> 16) & 0x3FFF);
///The CAEN manual is wrong, the bit [31:16] is anaprobe 2
bool isTrigger0 = (( word >> 15 ) & 0x1 );
bool dp0 = (( word >> 14 ) & 0x1 );
unsigned short wave0 = ( word & 0x3FFF);
if( SaveWaveToMemory){
if( hasDualTrace ){
tempWaveform1.push_back(wave1);
tempWaveform2.push_back(wave0);
tempDigiWaveform1.push_back(dp0);
}else{
tempWaveform1.push_back(wave1);
tempWaveform1.push_back(wave0);
tempDigiWaveform1.push_back(dp0);
tempDigiWaveform1.push_back(dp1);
}
}
if( isTrigger0 == 1 ) triggerAtSample = 2*wi ;
if( isTrigger1 == 1 ) triggerAtSample = 2*wi + 1;
if( verbose >= 4 && ev == 0 ){
if( !hasDualTrace ){
printf("%4d| %5d, %d, %d \n", 2*wi, wave0, dp0, isTrigger0);
printf("%4d| %5d, %d, %d \n", 2*wi+1, wave1, dp1, isTrigger1);
}else{
printf("%4d| %5d, %5d | %d, %d | %d %d\n", wi, wave0, wave1, dp0, dp1, isTrigger0, isTrigger1);
}
}
}
if( SaveWaveToMemory ) {
if( hasDualTrace ){
Waveform1[channel][NumEvents[channel]] = tempWaveform1;
Waveform2[channel][NumEvents[channel]] = tempWaveform2;
}else{
Waveform1[channel][NumEvents[channel]] = tempWaveform1;
}
DigiWaveform1[channel][NumEvents[channel]] = tempDigiWaveform1;
}
}
unsigned long long extTimeStamp = 0;
unsigned int extra2 = 0;
if( hasExtra2 ){
nw = nw +1 ; word = ReadBuffer(nw, verbose);
extra2 = word;
if( extra2Option == 0 || extra2Option == 2 ) extTimeStamp = (extra2 >> 16);
}
unsigned long long timeStamp = (extTimeStamp << 31) ;
timeStamp = timeStamp + timeStamp0;
if( verbose >= 2 && hasExtra2 ) printf("extra2 : 0x%0X, TimeStamp : %llu\n", extra2, timeStamp);
nw = nw +1 ; word = ReadBuffer(nw, verbose);
unsigned int extra = (( word >> 16) & 0x3FF);
unsigned int energy = (word & 0x7FFF);
bool rollOver = (extra & 0x002);
bool pileUp = (extra & 0x200);
bool pileUpOrRollOver = ((word >> 15) & 0x1);
if( verbose >= 3 ) {
printf("PileUp : %d , extra : 0x%03x, energy : %d \n", pileUp, extra, energy);
printf(" lost event : %d \n", ((extra >> 0) & 0x1) );
printf(" roll-over : %d (fake event)\n", ((extra >> 1) & 0x1) );
printf(" fake-event : %d \n", ((extra >> 3) & 0x1) );
printf(" input sat. : %d \n", ((extra >> 4) & 0x1) );
printf(" lost trg : %d \n", ((extra >> 5) & 0x1) );
printf(" tot trg : %d \n", ((extra >> 6) & 0x1) );
printf(" coincident : %d \n", ((extra >> 7) & 0x1) );
printf(" not coin. : %d \n", ((extra >> 8) & 0x1) );
printf(" pile-up : %d \n", ((extra >> 9) & 0x1) );
printf(" trapezoid sat. : %d \n", ((extra >> 10) & 0x1) );
}
if( rollOver == 0 ) {
Energy[channel][NumEvents[channel]] = energy;
Timestamp[channel][NumEvents[channel]] = timeStamp;
if(extra2Option == 0 || extra2Option == 2 ) fineTime[channel][NumEvents[channel]] = (extra2 & 0x07FF );
NumEvents[channel] ++;
NumEventsDecoded[channel] ++;
TotNumEvents[channel] ++;
}
if( verbose >= 1 ) printf("%4d | ch : %2d, PileUp : %d , energy : %5d, rollOver: %d, timestamp : %10llu, triggerAt : %d, nSample : %d, %f sec\n",
NumEvents[channel], channel, pileUp, energy, rollOver, timeStamp, triggerAtSample, nSample , timeStamp * 4. / 1e9);
}
///=========== Key information
/// ch, energy, timestamp
/// trace
return nw;
}
inline int Data::DecodePSDDualChannelBlock(unsigned int ChannelMask, bool fastDecode, int verbose){
nw = nw + 1;
unsigned int word = ReadBuffer(nw, verbose);
if( (word >> 31) != 1 ) return 0;
unsigned int aggSize = ( word & 0x3FFFFF ) ;
if( verbose >= 2 ) printf(" size : %d \n", aggSize);
unsigned int nEvents = 0;
nw = nw + 1; word = ReadBuffer(nw, verbose);
unsigned int nSample = ( word & 0xFFFF ) * 8;
unsigned int digitalProbe1 = ( (word >> 16 ) & 0x7 );
unsigned int digitalProbe2 = ( (word >> 19 ) & 0x7 );
unsigned int analogProbe = ( (word >> 22 ) & 0x3 );
unsigned int extraOption = ( (word >> 24 ) & 0x7 );
bool hasWaveForm = ( (word >> 27 ) & 0x1 );
bool hasExtra = ( (word >> 28 ) & 0x1 );
bool hasTimeStamp = ( (word >> 29 ) & 0x1 );
bool hasCharge = ( (word >> 30 ) & 0x1 );
bool hasDualTrace = ( (word >> 31 ) & 0x1 );
if( verbose >= 2 ) {
printf("dualTrace : %d, Charge : %d, Time: %d, Wave : %d, Extra: %d\n",
hasDualTrace, hasCharge, hasTimeStamp, hasWaveForm, hasExtra);
if( hasExtra ){
printf(".... extra : ");
switch(extraOption){
case 0: printf("[0:15] trapwzoid baseline * 4 [16:31] Extended timestamp (16-bit)\n"); break;
case 1: printf("[0:11] reserved [12] lost trigger counted [13] 1024 trigger counted [14] Over-range\n");
printf("[15] trigger lost [16:31] Extended timestamp (16-bit)\n"); break;
case 2: printf("[0:9] Fine time stamp [10:15] flag [10:15] Reserved [16:31] Extended timestamp (16-bit)\n"); break;
case 3: printf("Reserved\n"); break;
case 4: printf("[0:15] Total trigger counter [16:31] Lost trigger counter\n"); break;
case 5: printf("[0:15] Event after Zero crossing [16:31] Event before Zero crossing\n"); break;
case 6: printf("Reserved\n"); break;
case 7: printf("debug, must be 0x12345678\n"); break;
}
}
printf(".... digital Probe 1 : ");
switch(digitalProbe1){
case 0 : printf("Long gate \n"); break;
case 1 : printf("Over threshold \n"); break;
case 2 : printf("Shaped TRG \n"); break;
case 3 : printf("TRG Val. Acceptance \n"); break;
case 4 : printf("Pile-Up \n"); break;
case 5 : printf("Coincidence \n"); break;
case 6 : printf("Reserved \n"); break;
case 7 : printf("Trigger \n"); break;
}
printf(".... digital Probe 2 : ");
switch(digitalProbe2){
case 0 : printf("Short gate \n"); break;
case 1 : printf("Over threshold \n"); break;
case 2 : printf("TRG Validation \n"); break;
case 3 : printf("TRG HoldOff \n"); break;
case 4 : printf("Pile-Up \n"); break;
case 5 : printf("Coincidence \n"); break;
case 6 : printf("Reserved \n"); break;
case 7 : printf("Trigger \n"); break;
}
printf(".... analog Probe (dual trace : %d): ", hasDualTrace);
if( hasDualTrace ) {
switch(analogProbe){
case 0 : printf("Input and baseline \n"); break;
case 1 : printf("CFD and baseline \n"); break;
case 2 : printf("Input and CFD \n"); break;
}
}else{
switch(analogProbe){
case 0 : printf("Input \n"); break;
case 1 : printf("CFD \n"); break;
}
}
}
nEvents = (aggSize -2) / (nSample/2 + 2 + hasExtra );
if( verbose >= 2 ) printf("----------------- nEvents : %d \n", nEvents);
///========= Decode an event
for( int ev = 0; ev < nEvents ; ev++){
if( verbose >= 2 ) printf("--------------------------- event : %d\n", ev);
nw = nw +1 ; word = ReadBuffer(nw, verbose);
bool channelTag = ((word >> 31) & 0x1);
unsigned int timeStamp0 = (word & 0x7FFFFFFF);
int channel = ChannelMask*2 + channelTag;
if( verbose >= 2 ) printf("ch : %d, timeStamp %u \n", channel, timeStamp0);
///===== read waveform
if( !fastDecode && SaveWaveToMemory ) {
tempWaveform1.clear();
tempWaveform2.clear();
tempDigiWaveform1.clear();
tempDigiWaveform2.clear();
}
if( fastDecode ){
nw += nSample/2;
}else{
for( int wi = 0; wi < nSample/2; wi++){
nw = nw +1 ; word = ReadBuffer(nw, verbose - 2);
bool dp2b = (( word >> 31 ) & 0x1 );
bool dp1b = (( word >> 30 ) & 0x1 );
unsigned short waveb = (( word >> 16) & 0x3FFF);
bool dp2a = (( word >> 15 ) & 0x1 );
bool dp1a = (( word >> 14 ) & 0x1 );
unsigned short wavea = ( word & 0x3FFF);
if( SaveWaveToMemory){
if( hasDualTrace ){
tempWaveform1.push_back(wavea);
tempWaveform2.push_back(waveb);
}else{
tempWaveform1.push_back(wavea);
tempWaveform1.push_back(waveb);
}
tempDigiWaveform1.push_back(dp1a);
tempDigiWaveform1.push_back(dp1b);
tempDigiWaveform2.push_back(dp2a);
tempDigiWaveform2.push_back(dp2b);
}
if( verbose >= 3 && ev == 0 ){
printf("%4d| %5d, %d, %d \n", 2*wi, wavea, dp1a, dp2a);
printf("%4d| %5d, %d, %d \n", 2*wi+1, waveb, dp1b, dp2b);
}
}
if( SaveWaveToMemory ) {
if( hasDualTrace ){
Waveform1[channel][NumEvents[channel]] = tempWaveform1;
Waveform2[channel][NumEvents[channel]] = tempWaveform2;
}else{
Waveform1[channel][NumEvents[channel]] = tempWaveform1;
}
DigiWaveform1[channel][NumEvents[channel]] = tempDigiWaveform1;
DigiWaveform2[channel][NumEvents[channel]] = tempDigiWaveform2;
}
}
nw = nw +1 ; word = ReadBuffer(nw, verbose);
unsigned int extra = word;
unsigned long long extTimeStamp = 0;
if( extraOption == 0 || extraOption == 2 ) extTimeStamp = (extra >> 16);
unsigned long long timeStamp = (extTimeStamp << 31) ;
timeStamp = timeStamp + timeStamp0;
nw = nw +1 ; word = ReadBuffer(nw, verbose);
unsigned int Qlong = (( word >> 16) & 0xFFFF);
unsigned int Qshort = (word & 0x7FFF);
bool isEnergyCorrect = ((word >> 15) & 0x1);
if( isEnergyCorrect == 1 ) {
NumEvents[channel] ++;
NumEventsDecoded[channel] ++;
TotNumEvents[channel] ++;
}
if( verbose >= 2 ) printf("extra : 0x%08x, Qshort : %d, Qlong : %d \n", extra, Qshort, Qlong);
if( verbose >= 1 ) printf("ch : %2d, Qshort : %d, Qlong : %d, timestamp : %llu\n",
channel, Qshort, Qlong, timeStamp);
Timestamp[channel][NumEvents[channel]] = timeStamp;
}
///=========== Key information
/// ch, Qshort, Qlong , timestamp
/// trace
return nw;
}
#endif

943
ClassDigitizer.cpp Normal file
View File

@ -0,0 +1,943 @@
#include "ClassDigitizer.h"
Digitizer::Digitizer(){
Initalization();
}
Digitizer::Digitizer(int boardID, int portID, bool program, bool verbose){
Initalization();
OpenDigitizer(boardID, portID, program, verbose);
}
Digitizer::~Digitizer(){
CloseDigitizer();
delete data;
}
void Digitizer::Initalization(){
data = new Data();
portID = -1;
boardID = -1;
handle = -1;
NChannel = 16;
ADCbits = 1;
DPPType = 0;
ADCFullSize = 0;
ch2ns = 0;
BoardInfo = {};
channelMask = 0xFFFF;
VMEBaseAddress = 0;
LinkType = CAEN_DGTZ_USB; /// default USB
IOlev = CAEN_DGTZ_IOLevel_NIM; ///default NIM
isSettingFilledinMemeory = false;
settingFileName = "";
settingFileExist = false;
settingFile = NULL;
ret = -1;
isConnected = false;
AcqRun = false;
isDummy = true;
}
void Digitizer::Reset(){
ret = CAEN_DGTZ_Reset(handle);
if( ret != 0 ) ErrorMsg(__func__);
ret |= CAEN_DGTZ_WriteRegister(handle, Register::DPP::SoftwareClear_W, 1);
if( ret != 0 ) ErrorMsg("Reset-SoftwareClear_W");
}
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("DPPType : %d (%s)\n", DPPType, GetDPPString().c_str());
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;
if( boardID < 0 || portID < 0 ) return 0; /// for using the Digitizer Class without open digitizer
/***************************************************/
/** 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);
}
ErrorMsg("=== Open Digitizer port " +std::to_string(portID) + " board " + std::to_string(boardID));
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
default : ch2ns = 4.0; break;
}
data->ch2ns = ch2ns;
data->boardSN = BoardInfo.SerialNumber;
ADCbits = BoardInfo.ADC_NBits;
ADCFullSize = (unsigned int)( pow(2, ADCbits) -1 );
}
}
///====================== Check DPP firmware revision
sscanf(BoardInfo.AMC_FirmwareRel, "%d", &DPPType);
data->DPPType = DPPType;
/// change address 0xEF08 (5 bits), this will reflected in the 2nd word of the Board Agg. header.
ret = CAEN_DGTZ_WriteRegister(handle, Register::DPP::BoardID, (DPPType & 0xF));
if ( verbose ){
PrintBoard();
if (DPPType < 0x80 ) {
printf("This digitizer does not have DPP-PHA firmware\n");
}else {
printf("\t==== This digitizer has a DPP firmware!\n");
printf("\e[32m\t %s \e[0m", GetDPPString().c_str());
}
}
ErrorMsg("========== Set BoardID");
///======================= Check virtual probe
int probes[MAX_SUPPORTED_PROBES];
int numProbes;
ret = CAEN_DGTZ_GetDPP_SupportedVirtualProbes(handle, 1, probes, &numProbes);
ErrorMsg("=== Get Supported Virtual Probes");
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 ) isDummy = false;
if( isConnected && program) {
ProgramBoard();
}
if( isConnected ) ReadAllSettingsFromBoard();
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::SetChannelMask(uint32_t mask){
if( !isConnected ) return;
channelMask = mask;
ret |= CAEN_DGTZ_SetChannelEnableMask(handle, channelMask);
SaveSettingToFile(Register::DPP::ChannelEnableMask, mask);
SetSettingToMemory(Register::DPP::ChannelEnableMask, mask);
ErrorMsg(__func__);
}
void Digitizer::SetChannelOnOff(unsigned short ch, bool onOff){
if( !isConnected ) return;
channelMask = ((channelMask & ~( 1 << ch) ) | ( onOff << ch)) ;
SetChannelMask(channelMask);
}
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
ret |= CAEN_DGTZ_SetRecordLength(handle, 2000);
/// 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
CAEN_DGTZ_DPP_AcqMode_t AcqMode = CAEN_DGTZ_DPP_ACQ_MODE_List;
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;
}
int Digitizer::ProgramPHABoard(){
ret = CAEN_DGTZ_Reset(handle);
printf("======== program board PHA\n");
ret = CAEN_DGTZ_WriteRegister(handle, Register::DPP::RecordLength_G + 0x7000, 62);
ret = CAEN_DGTZ_WriteRegister(handle, Register::DPP::BoardConfiguration, 0x0F8915); /// has Extra2
///ret = CAEN_DGTZ_WriteRegister(handle, Register::DPP::BoardConfiguration, 0x0D8115); /// diable Extra2
//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");
uint32_t address;
address = Register::DPP::PHA::DecayTime; ret |= CAEN_DGTZ_WriteRegister(handle, address + 0x7000 , 5000 );
address = Register::DPP::PHA::TrapezoidFlatTop; ret |= CAEN_DGTZ_WriteRegister(handle, address + 0x7000 , 0x1A );
address = Register::DPP::PHA::TrapezoidRiseTime; ret |= CAEN_DGTZ_WriteRegister(handle, address + 0x7000 , 6 );
address = Register::DPP::PHA::PeakingTime; ret |= CAEN_DGTZ_WriteRegister(handle, address + 0x7000 , 6 );
address = Register::DPP::PHA::RCCR2SmoothingFactor; ret |= CAEN_DGTZ_WriteRegister(handle, address + 0x7000 , 4 );
address = Register::DPP::PHA::InputRiseTime; ret |= CAEN_DGTZ_WriteRegister(handle, address + 0x7000 , 6 );
address = Register::DPP::PHA::TriggerThreshold; ret |= CAEN_DGTZ_WriteRegister(handle, address + 0x7000 , 1000 );
address = Register::DPP::PHA::PeakHoldOff; ret |= CAEN_DGTZ_WriteRegister(handle, address + 0x7000 , 0x3E );
address = Register::DPP::PHA::TriggerHoldOffWidth; ret |= CAEN_DGTZ_WriteRegister(handle, address + 0x7000 , 0x3E );
address = Register::DPP::PHA::RiseTimeValidationWindow;ret |= CAEN_DGTZ_WriteRegister(handle, address + 0x7000 , 0x0 );
ret |= CAEN_DGTZ_WriteRegister(handle, (uint32_t)(Register::DPP::ChannelDCOffset) + 0x7000 , 0xEEEE );
ret |= CAEN_DGTZ_WriteRegister(handle, (uint32_t)(Register::DPP::PreTrigger) + 0x7000 , 32 );
ret |= CAEN_DGTZ_WriteRegister(handle, (uint32_t)(Register::DPP::InputDynamicRange) + 0x7000 , 0x0 );
ret |= CAEN_DGTZ_WriteRegister(handle, (int32_t)(Register::DPP::NumberEventsPerAggregate_G) + 0x7000, 511);
ret |= CAEN_DGTZ_WriteRegister(handle, (int32_t)(Register::DPP::AggregateOrganization), 2);
ret |= CAEN_DGTZ_WriteRegister(handle, (int32_t)(Register::DPP::MaxAggregatePerBlockTransfer), 4);
ret |= CAEN_DGTZ_WriteRegister(handle, (int32_t)(Register::DPP::DPPAlgorithmControl) + 0x7000, 0xC30200f);
if( ret != 0 ) { printf("==== set channels error.\n"); return 0;}
printf("End of program board and channels\n");
isSettingFilledinMemeory = false; /// unlock the ReadAllSettingsFromBoard();
ReadAllSettingsFromBoard();
return ret;
}
//========================================================= ACQ control
void Digitizer::StartACQ(){
if ( AcqRun ) return;
unsigned int bufferSize = CalByteForBuffer();
if( bufferSize > 160 * 1024 * 1024 ){
printf("============= buffer size bigger than 160 MB");
return;
}
data->AllocateMemory(bufferSize);
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;
data->ClearTriggerRate();
}
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;
data->ClearTriggerRate();
}
unsigned int Digitizer::CalByteForBuffer(){
unsigned int numAggBLT;
unsigned int chMask ;
unsigned int boardCfg ;
unsigned int eventAgg[NChannel/2];
unsigned int recordLength[NChannel/2];
unsigned int aggOrgan;
if( isConnected ){
numAggBLT = ReadRegister(Register::DPP::MaxAggregatePerBlockTransfer, 0, false);
chMask = ReadRegister(Register::DPP::ChannelEnableMask, 0, false);
boardCfg = ReadRegister(Register::DPP::BoardConfiguration, 0, false);
aggOrgan = ReadRegister(Register::DPP::AggregateOrganization, 0, false);
for( int pCh = 0; pCh < NChannel/2; pCh++){
eventAgg[pCh] = ReadRegister(Register::DPP::NumberEventsPerAggregate_G, pCh * 2 , false);
recordLength[pCh] = ReadRegister(Register::DPP::RecordLength_G, pCh * 2 , false);
}
}else{
numAggBLT = GetSettingFromMemory(Register::DPP::MaxAggregatePerBlockTransfer);
chMask = GetSettingFromMemory(Register::DPP::ChannelEnableMask);
boardCfg = GetSettingFromMemory(Register::DPP::BoardConfiguration);
aggOrgan = GetSettingFromMemory(Register::DPP::AggregateOrganization);
for( int pCh = 0; pCh < NChannel/2; pCh++){
eventAgg[pCh] = GetSettingFromMemory(Register::DPP::NumberEventsPerAggregate_G, pCh * 2 );
recordLength[pCh] = GetSettingFromMemory(Register::DPP::RecordLength_G, pCh * 2);
}
}
///printf(" agg. orgainzation (bit) : 0x%X \n", aggOrgan);
///printf(" Channel Mask : %04X \n", chMask);
///printf("Max number of Agg per Readout : %u \n", numAggBLT);
///printf(" is Extra2 enabed : %u \n", ((boardCfg >> 17) & 0x1) );
///printf(" is Record wave : %u \n", ((boardCfg >> 16) & 0x1) );
///for( int pCh = 0; pCh < NChannel/2; pCh++){
/// printf("Paired Ch : %d, RecordLength (bit value): %u, Event per Agg. : %u \n", pCh, recordLength[pCh], eventAgg[pCh]);
///}
unsigned int bufferSize = 0;
for( int pCh = 0; pCh < NChannel/2 ; pCh++){
if( (chMask & ( 3 << (2 * pCh) )) == 0 ) continue;
bufferSize += 2 + ( 2 + ((boardCfg >> 17) & 0x1) + ((boardCfg >> 16) & 0x1)*recordLength[pCh]*4 ) * eventAgg[pCh] ;
}
bufferSize += 4; /// Bd. Agg Header
bufferSize = bufferSize * numAggBLT * 4; /// 1 words = 4 byte
///printf("=============== Buffer Size : %8d Byte \n", bufferSize );
return bufferSize ;
}
void Digitizer::ReadData(){
if( !isConnected ) return;
if( !AcqRun) 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::PrintACQStatue(){
if( !isConnected ) return;
unsigned int status = ReadRegister(Register::DPP::AcquisitionStatus_R);
printf("=================== Print ACQ status \n");
printf(" 32 28 24 20 16 12 8 4 0\n");
printf(" | | | | | | | | |\n");
std::cout <<" 0b" << std::bitset<32>(status) << std::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);
}
//===========================================================
//===========================================================
//===========================================================
void Digitizer::WriteRegister (Reg registerAddress, uint32_t value, int ch, bool isSave2MemAndFile){
printf("%30s[0x%04X](ch-%02d) [0x%04X]: 0x%08X \n", registerAddress.GetNameChar(), registerAddress.GetAddress(),ch, registerAddress.ActualAddress(ch), value);
if( !isConnected ) {
SetSettingToMemory(registerAddress, value, ch);
SaveSettingToFile(registerAddress, value, ch);
return;
}
if( registerAddress.GetType() == RW::ReadONLY ) return;
ret = CAEN_DGTZ_WriteRegister(handle, registerAddress.ActualAddress(ch), value);
if( ret == 0 && isSave2MemAndFile && registerAddress.GetType() == RW::ReadWrite) {
SetSettingToMemory(registerAddress, value, ch);
SaveSettingToFile(registerAddress, value, ch);
}
ErrorMsg("WriteRegister:" + std::to_string(registerAddress));
}
uint32_t Digitizer::ReadRegister(Reg registerAddress, unsigned short ch, bool isSave2MemAndFile, std::string str ){
if( !isConnected ) return 0;
if( registerAddress.GetType() == RW::WriteONLY ) return 0;
uint32_t data[1];
ret = CAEN_DGTZ_ReadRegister(handle, registerAddress.ActualAddress(ch), data);
if( ret == 0 && isSave2MemAndFile) {
SetSettingToMemory(registerAddress, data[0], ch);
SaveSettingToFile(registerAddress, data[0], ch);
}
ErrorMsg("ReadRegister:" + std::to_string(registerAddress));
if( str != "" ) printf("%s : 0x%04X(0x%04X) is 0x%08X \n", str.c_str(),
registerAddress.ActualAddress(ch), registerAddress.GetAddress(), data[0]);
return data[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(), "");
std::cout << " : 0b" << std::bitset<32>(value[0]) << std::endl;
printf(" %*s : 0x%X\n", (int) msg.length(), msg.c_str(), value[0]);
return value[0];
}
//========================================== setting file IO
Reg Digitizer::FindRegister(uint32_t address){
Reg tempReg;
///========= Find Match Register
for( int p = 0; p < (int) RegisterDPPList[p]; p++){
if( address == RegisterDPPList[p].GetAddress() ) {
tempReg = RegisterDPPList[p];
break;
}
}
if( tempReg.GetName() == ""){
if( DPPType == V1730_DPP_PHA_CODE ){
for( int p = 0; p < (int) RegisterPHAList[p]; p++){
if( address == RegisterPHAList[p].GetAddress() ) {
tempReg = RegisterPHAList[p];
break;
}
}
}
if( DPPType == V1730_DPP_PSD_CODE ){
for( int p = 0; p < (int) RegisterPSDList[p]; p++){
if( address == RegisterPSDList[p].GetAddress() ) {
tempReg = RegisterPSDList[p];
break;
}
}
}
}
return tempReg;
}
void Digitizer::ReadAllSettingsFromBoard(bool force){
if( !isConnected ) return;
if( AcqRun ) return;
if( isSettingFilledinMemeory && !force) return;
printf("===== %s \n", __func__);
/// board setting
for( int p = 0; p < (int) RegisterDPPList[p]; p++){
if( RegisterDPPList[p].GetType() == RW::WriteONLY) continue;
ReadRegister(RegisterDPPList[p]);
}
channelMask = GetSettingFromMemory(Register::DPP::ChannelEnableMask);
/// Channels Setting
for( int ch = 0; ch < NChannel; ch ++){
if( DPPType == V1730_DPP_PHA_CODE ){
for( int p = 0; p < (int) RegisterPHAList[p]; p++){
if( RegisterPHAList[p].GetType() == RW::WriteONLY) continue;
ReadRegister(RegisterPHAList[p], ch);
}
}
if( DPPType == V1730_DPP_PSD_CODE ){
for( int p = 0; p < (int) RegisterPSDList[p]; p++){
if( RegisterPSDList[p].GetType() == RW::WriteONLY) continue;
ReadRegister(RegisterPSDList[p], ch);
}
}
}
isSettingFilledinMemeory = true;
}
void Digitizer::ProgramSettingsToBoard(){
if( !isConnected ) return;
if( isDummy ) return;
Reg haha;
/// board setting
for( int p = 0; p < (int) RegisterDPPList[p]; p++){
if( RegisterDPPList[p].GetType() == RW::ReadONLY) continue;
haha = RegisterDPPList[p];
WriteRegister(haha, GetSettingFromMemory(haha), -1, false);
usleep(100 * 1000);
}
/// Channels Setting
for( int ch = 0; ch < NChannel; ch ++){
if( DPPType == V1730_DPP_PHA_CODE ){
for( int p = 0; p < (int) RegisterPHAList[p]; p++){
if( RegisterPHAList[p].GetType() == RW::ReadONLY) continue;
haha = RegisterPHAList[p];
WriteRegister(haha, GetSettingFromMemory(haha, ch), ch, false);
usleep(100 * 1000);
}
}
if( DPPType == V1730_DPP_PSD_CODE ){
for( int p = 0; p < (int) RegisterPSDList[p]; p++){
if( RegisterPSDList[p].GetType() == RW::ReadONLY) continue;
haha = RegisterPHAList[p];
WriteRegister(haha, GetSettingFromMemory(haha, ch), ch, false);
usleep(100 * 1000);
}
}
}
}
void Digitizer::SetSettingToMemory(Reg registerAddress, unsigned int value, unsigned short ch ){
unsigned short index = registerAddress.Index(ch);
if( index > SETTINGSIZE ) return;
setting[index] = value;
}
unsigned int Digitizer::GetSettingFromMemory(Reg registerAddress, unsigned short ch ){
unsigned short index = registerAddress.Index(ch);
if( index > SETTINGSIZE ) return 0xFFFF;
return setting[index] ;
}
void Digitizer::PrintSettingFromMemory(){
for( int i = 0; i < SETTINGSIZE; i++) printf("%4d | 0x%04X |0x%08X = %u \n", i, i*4, setting[i], setting[i]);
}
void Digitizer::SetSettingBinaryPath(std::string fileName){
settingFile = fopen(fileName.c_str(), "r+");
if( settingFile == NULL ){
printf("cannot open file %s. Create one.\n", fileName.c_str());
ReadAllSettingsFromBoard();
SaveAllSettingsAsBin(fileName);
this->settingFileName = fileName;
settingFileExist = true;
}else{
this->settingFileName = fileName;
settingFileExist = true;
fclose(settingFile);
printf("setting file already exist. do nothing. Should program the digitizer\n");
}
}
int Digitizer::LoadSettingBinaryToMemory(std::string fileName){
settingFile = fopen(fileName.c_str(), "r");
if( settingFile == NULL ) {
printf(" %s does not exist or cannot load.\n", fileName.c_str());
settingFileExist = false;
return -1;
}else{
settingFileExist = true;
settingFileName = fileName;
fclose (settingFile);
uint32_t fileDPP = ((ReadSettingFromFile(Register::DPP::AMCFirmwareRevision_R, 0) >> 8) & 0xFF);
/// compare seeting DPP version;
if( isConnected && DPPType != fileDPP ){
printf("DPPType in the file is %s(0x%X), but the dgitizer DPPType is %s(0x%X). \n", GetDPPString(fileDPP).c_str(), fileDPP, GetDPPString().c_str(), DPPType);
return -1;
}else{
/// load binary to memoery
DPPType = fileDPP;
printf("DPPType in the file is %s(0x%X). \n", GetDPPString(fileDPP).c_str(), fileDPP);
settingFile = fopen(fileName.c_str(), "r");
size_t dummy = fread( setting, SETTINGSIZE * sizeof(unsigned int), 1, settingFile);
fclose (settingFile);
uint32_t boardInfo = GetSettingFromMemory(Register::DPP::BoardInfo_R);
if( (boardInfo & 0xFF) == 0x0E ) ch2ns = 4.0;
if( (boardInfo & 0xFF) == 0x0B ) ch2ns = 2.0;
///Should seperate file<->memory, memory<->board
///ProgramSettingsToBoard(); /// do nothing if not connected.
return 0;
}
}
}
unsigned int Digitizer::ReadSettingFromFile(Reg registerAddress, unsigned short ch){
if ( !settingFileExist ) return -1;
unsigned short index = registerAddress.Index(ch);
settingFile = fopen (settingFileName.c_str(),"r");
///fseek( settingFile, address, SEEK_SET);
fseek( settingFile, index * 4, SEEK_SET);
///printf(" at pos %lu Byte = index(%lu)\n", ftell(settingFile), ftell(settingFile)/4);
unsigned int lala[1];
size_t dummy = fread( lala, sizeof(unsigned int), 1, settingFile);
///printf(" data at pos %lu(%lu) : %X = %d\n", ftell(settingFile) - sizeof(unsigned int), (ftell(settingFile) - sizeof(unsigned int))/4, lala[0], lala[0]);
fclose (settingFile);
return lala[0];
}
void Digitizer::SaveSettingToFile(Reg registerAddress, unsigned int value, unsigned short ch){
if ( !settingFileExist ) return ;
unsigned short index = registerAddress.Index(ch);
setting[index] = value;
settingFile = fopen (settingFileName.c_str(),"r+");
///fseek( settingFile, address, SEEK_SET);
fseek( settingFile, index * 4, SEEK_SET);
unsigned int jaja[1] = {value};
size_t dummy = fwrite( jaja, sizeof(unsigned int), 1, settingFile);
///printf("fwrite ret : %d, 0x%0X, 0x%0X, %d, 0x%X = %d\n", (int)dummy, registerAddress, index*4, index, jaja[0], jaja[0]);
fclose (settingFile);
}
void Digitizer::SaveAllSettingsAsBin(std::string fileName){
if( !isSettingFilledinMemeory ) return;
FILE * binFile = fopen(fileName.c_str(), "w+");
if( binFile == NULL ) {
printf("Cannot open %s.\n", fileName.c_str());
return;
}
fwrite(setting, SETTINGSIZE * sizeof(unsigned int), 1, binFile);
fseek(binFile, 0L, SEEK_END);
unsigned int inFileSize = ftell(binFile);
printf("Created file : %s. file size : %d Byte\n", fileName.c_str(), inFileSize);
fclose (binFile);
}
void Digitizer::SaveAllSettingsAsText(std::string fileName){
if( !isSettingFilledinMemeory ) return;
FILE * txtFile = fopen(fileName.c_str(), "w+");
if( txtFile == NULL ) {
printf("Cannot open %s.\n", fileName.c_str());
return;
}
Reg haha;
for( unsigned int i = 0; i < SETTINGSIZE ; i++){
haha.SetName("");
uint32_t actualAddress = haha.CalAddress(i);
///printf("%7d--- 0x%04X, 0x%04X\n", i, haha->GetAddress(), haha->ActualAddress());
for( int p = 0; p < (int) RegisterDPPList.size(); p++){
if( haha.GetAddress() == (uint32_t) RegisterDPPList[p] ) haha = RegisterDPPList[p];
}
if( DPPType == V1730_DPP_PHA_CODE) {
for( int p = 0; p < (int) RegisterPHAList.size(); p++){
if( haha.GetAddress() == (uint32_t) RegisterPHAList[p] ) haha = RegisterPHAList[p];
}
}
if( DPPType == V1730_DPP_PSD_CODE) {
for( int p = 0; p < (int) RegisterPSDList.size(); p++){
if( haha.GetAddress() == (uint32_t) RegisterPSDList[p] ) haha = RegisterPSDList[p];
}
}
if( haha.GetName() != "" ) {
std::string typeStr ;
if( haha.GetType() == RW::ReadWrite ) typeStr = "R/W";
if( haha.GetType() == RW::ReadONLY ) typeStr = "R ";
if( haha.GetType() == RW::WriteONLY ) typeStr = " W";
fprintf( txtFile, "0x%04X %30s 0x%08X %s %u\n", actualAddress,
haha.GetNameChar(),
setting[i],
typeStr.c_str(),
setting[i]);
}
}
}
std::string Digitizer::GetDPPString(int DPPType){
std::string DPPTypeStr = "";
if( DPPType == 0 ) DPPType = this->DPPType;
switch (DPPType){
case V1724_DPP_PHA_CODE: DPPTypeStr = "DPP-PHA x724"; break; /// 0x80
case V1720_DPP_CI_CODE : DPPTypeStr = "DPP-CI x720"; break; /// 0x82
case V1720_DPP_PSD_CODE: DPPTypeStr = "DPP-PSD x720"; break; /// 0x83
case V1751_DPP_PSD_CODE: DPPTypeStr = "DPP-PSD x751"; break; /// 0x84
case V1751_DPP_ZLE_CODE: DPPTypeStr = "DPP-ZLE x751"; break; /// 0x85
case V1743_DPP_CI_CODE: DPPTypeStr = "DPP-PSD x743"; break; /// 0x86
case V1740_DPP_QDC_CODE: DPPTypeStr = "DPP-QDC x740"; break; /// 0x87
case V1730_DPP_PSD_CODE: DPPTypeStr = "DPP-PSD x730"; break; /// 0x88
case V1730_DPP_PHA_CODE: DPPTypeStr = "DPP-PHA x730"; break; /// 0x8B
case V1730_DPP_ZLE_CODE: DPPTypeStr = "DPP-ZLE x730"; break; /// 0x8C
case V1730_DPP_DAW_CODE: DPPTypeStr = "DPP-DAW x730"; break; /// 0x8D
}
return DPPTypeStr;
}
void Digitizer::ErrorMsg(std::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::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_G, 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){
WriteRegister( Register::DPP::DPPAlgorithmControl, bit, ch);
if( ret != 0 ) ErrorMsg(__func__);
}
unsigned int Digitizer::ReadBits(Reg 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(Reg 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];
}
*/

179
ClassDigitizer.h Normal file
View File

@ -0,0 +1,179 @@
#ifndef DIGITIZER_H
#define DIGITIZER_H
#include <stdio.h>
#include <string>
#include <sstream>
#include <cmath>
#include <cstring> ///memset
#include <iostream> ///cout
#include <bitset>
#include "CAENDigitizer.h"
#include "CAENDigitizerType.h"
#include "macro.h"
#include "ClassData.h"
#include "RegisterAddress.h"
//################################################################
class Digitizer{
protected:
Data * data;
///---- 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 channelMask ; /// the channel mask from NChannel
uint32_t VMEBaseAddress; /// For direct USB or Optical-link connection, VMEBaseAddress must be 0
CAEN_DGTZ_ConnectionType LinkType; /// USB or Optic
CAEN_DGTZ_IOLevel_t IOlev; /// TTL signal (1 = 1.5 to 5V, 0 = 0 to 0.7V ) or NIM signal (1 = -1 to -0.8V, 0 = 0V)
///------- other parameters
int ret; /// return value, refer to CAEN_DGTZ_ErrorCode
bool isConnected; /// true for digitizer communication estabished.
bool AcqRun; /// true when digitizer is taking data
bool isDummy; /// true for a dummy digitizer.
/// ------- setting
std::string settingFileName; ///
FILE * settingFile; ///
bool settingFileExist; ///
bool isSettingFilledinMemeory; /// false for disabled ReadAllSettingFromBoard()
unsigned int setting[SETTINGSIZE]; /// Setting, 4bytes x 2048 = 8192 bytes
///---------- protected functions
void ErrorMsg(std::string header = "");
public:
Digitizer(); /// no digitizer open
Digitizer(int boardID, int portID = 0, bool program = false, bool verbose = false);
~Digitizer();
/// portID is for optical link for using PCIe card, from 0, 1, 2, 3
int OpenDigitizer(int boardID, int portID = 0, bool program = false, bool verbose = false);
void SetDPPType (int type) { this->DPPType = type;} /// for manual override, or, digitizer does not open
void SetChannelMask (uint32_t mask);
void SetChannelOnOff (unsigned short ch, bool onOff);
int CloseDigitizer();
void Initalization();
void Reset();
bool IsDummy() {return isDummy;};
void PrintBoard() ;
virtual int ProgramBoard() ; /// program a generic board, no program channel
int ProgramPHABoard() ; /// program a default PHA board
///================ ACQ control
void StopACQ();
void StartACQ();
void ReadData();
bool IsRunning() const {return AcqRun;}
Data * GetData() const {return data;}
void PrintACQStatue();
unsigned int CalByteForBuffer();
///=================Settings
/// write value to digitizer, memory, and settingFile (if exist)
/// ONLY WriteRegister can have ch = -1, for writting all channels
/// for board setting, ignore ch
void WriteRegister (Reg registerAddress, uint32_t value, int ch = -1, bool isSave2MemAndFile = true);
/// read value from digitizer and memory, and save to memory, and settingFile(if exist),
/// for board setting, ignore ch
uint32_t ReadRegister (Reg registerAddress, unsigned short ch = 0, bool isSave2MemAndFile = true, std::string str = "" );
uint32_t PrintRegister(uint32_t address, std::string msg);
///================ Get Board info
std::string GetModelName() const {return BoardInfo.ModelName;}
int GetSerialNumber() const {return BoardInfo.SerialNumber;}
int GetChannelMask() const {return channelMask;}
bool GetChannelOnOff(unsigned ch) const {return (channelMask & ( 1 << ch) );}
float GetCh2ns() const {return ch2ns;}
int GetNChannel() const {return NChannel;}
int GetHandle() const {return handle;}
bool GetConnectionStatus() const {return isConnected;}
int GetDPPType() const {return DPPType;}
std::string GetDPPString(int DPPType = 0); /// if no input, use digitizer DPPType
int GetADCBits() const {return BoardInfo.ADC_NBits;}
std::string GetROCVersion() const {return BoardInfo.ROC_FirmwareRel;}
std::string GetAMCVersion() const {return BoardInfo.AMC_FirmwareRel;}
CAEN_DGTZ_ConnectionType GetLinkType() const {return LinkType;}
///================ Setting
Reg FindRegister(uint32_t address);
/// board <--> memory functions
void ReadAllSettingsFromBoard (bool force = false);
void ProgramSettingsToBoard ();
/// simply read settings from memory
void SetSettingToMemory (Reg registerAddress, unsigned int value, unsigned short ch = 0);
unsigned int GetSettingFromMemory (Reg registerAddress, unsigned short ch = 0);
void PrintSettingFromMemory ();
unsigned int * GetSettings() {return setting;};
/// memory <--> file
void SaveAllSettingsAsText (std::string fileName);
void SaveAllSettingsAsBin (std::string fileName);
std::string GetSettingFileName() {return settingFileName;}
/// tell the digitizer where to look at the setting file.
/// if not exist, call SaveAllSettinsAsBin();
void SetSettingBinaryPath (std::string fileName);
/// load setting file to memory
/// if problem, return -1; load without problem, return 0;
int LoadSettingBinaryToMemory (std::string fileName);
void SaveSettingToFile (Reg registerAddress, unsigned int value, unsigned short ch = 0); /// also save to memory
unsigned int ReadSettingFromFile (Reg registerAddress, unsigned short ch = 0); /// read from setting binary
///=================== Relic methods
///void SetRecordLength (unsigned int ns, int ch = -1); /// when ch == -1, mean set all channels
///void SetInputDynamicRange (unsigned int TwoVol_0_or_halfVol_1, int ch = -1);
///void SetPreTriggerSample (unsigned int nSample, int ch = -1 );
///void SetPreTriggerDuration (unsigned int ns, int ch = -1 );
///void SetDCOffset (float offsetPrecentage, int ch = -1);
///void SetVetoWidth (uint32_t bit, int ch = -1); /// See manual
///void SetTriggerPolarity (bool RiseingIsZero, int ch = -1); ///not used for DPP firmware
///
///void SetEventAggregation (unsigned int numEvent, int ch = -1);
///void SetAggregateOrganization (unsigned int bit);
///void SetMaxAggregatePerBlockTransfer (unsigned int numEvent);
///
///void SetBits(Reg address, unsigned int bitValue, unsigned int bitLength, unsigned int bitSmallestPos, int ch = -1);
///void SetDPPAlgorithmControl(uint32_t bit, int ch = -1);
///
///void SetACQControl(uint32_t bit);
///void SetGlobalTriggerMask(uint32_t bit);
///void SetFrontPanelTRGOUTMask(uint32_t bit);
///void SetFrontPanelIOControl(uint32_t bit);
///void SetTriggerValidationMask(uint32_t bit);
///void SetBoardID(unsigned int ID) {WriteRegister(Register::DPP::BoardID, ID));
///unsigned int GetRecordLengthSample(int ch) {return ReadRegister(Register::DPP::RecordLength_G, ch) * 8;}
///unsigned int GetInputDynamicRange(int ch) {return ReadRegister(Register::DPP::InputDynamicRange, ch);}
///unsigned int GetPreTriggerSample(int ch) {return ReadRegister(Register::DPP::PreTrigger, ch) * 4;}
///float GetDCOffset(int ch) {return 100.0 - ReadRegister(Register::DPP::ChannelDCOffset, ch) * 100. / 0xFFFFF; }
///unsigned int GetVetoWidth(int ch) {return ReadRegister(Register::DPP::VetoWidth, ch);}
///unsigned int GetEventAggregation(int ch = -1) {return ReadRegister(Register::DPP::NumberEventsPerAggregate_G, ch);}
///unsigned int GetAggregateOrganization() {return ReadRegister(Register::DPP::AggregateOrganization);}
///unsigned int GetMaxNumberOfAggregatePerBlockTransfer() {return ReadRegister(Register::DPP::MaxAggregatePerBlockTransfer);}
///
///unsigned int ReadBits(Reg address, unsigned int bitLength, unsigned int bitSmallestPos, int ch = -1 );
///unsigned int GetDPPAlgorithmControl(int ch = -1) {return ReadRegister(Register::DPP::DPPAlgorithmControl, ch);}
///
///int GetChTemperature(int ch) ;
};
#endif

22
FSUDAQ_Qt6.pro Normal file
View File

@ -0,0 +1,22 @@
######################################################################
# Automatically generated by qmake (3.1) Tue Apr 11 11:05:33 2023
######################################################################
TEMPLATE = app
TARGET = FSUDAQ_Qt6
INCLUDEPATH += .
QT += widgets charts
LIBS += -lCAENDigitizer
# You can make your code fail to compile if you use deprecated APIs.
# In order to do so, uncomment the following line.
# Please consult the documentation of the deprecated API in order to know
# how to port your code away from it.
# You can also select to disable deprecated APIs only up to a certain version of Qt.
#DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0x060000 # disables all the APIs deprecated before Qt 6.0.0
# Input
HEADERS += ClassData.h ClassDigitizer.h macro.h mainWindow.h RegisterAddress.h
SOURCES += ClassDigitizer.cpp main.cpp mainWindow.C

608
RegisterAddress.h Normal file
View File

@ -0,0 +1,608 @@
#ifndef REGISTERADDRESS_H
#define REGISTERADDRESS_H
#include <vector>
///=======
/// All 0x1XXX registers are either indiviual or Group
/// Indiviual register are all independence
/// Group register, 2m and 2m+1 channels setting are shared. and the name will have _G as prefix
/// Most 0x8XXX registers are common, which share for all channel
/// For adding Register, two things needed.
/// 1) add to the namepace
/// 2) add to the RegisterXXXList
/// The Reg Class has conversion operator
/// Reg haha("haha", 0x1234);
/// uint32_t papa = haha; /// papa = 0x1234
enum RW { ReadWrite = 0, ReadONLY = 1, WriteONLY = 2};
class Reg{
public:
Reg(){
this->name = "";
this->address = 0;
this->type = 0;
this->group = 0;
}
Reg(std::string name, uint32_t address, char type = 0, bool group = 0){
this->name = name;
this->address = address;
this->type = type;
this->group = group;
};
~Reg(){};
operator uint32_t () const {return this->address;} /// this allows Reg kaka("kaka", 0x1234) uint32_t haha = kaka;
std::string GetName() const {return this->name;}
const char * GetNameChar() const {return this->name.c_str();}
uint32_t GetAddress() const {return this->address; }
char GetType() const {return this->type;}
bool GetGroup() const {return this->group;}
void Print() const ;
uint32_t ActualAddress(int ch = -1){
if( address == 0x8180 ) return (ch < 0 ? address : (address + 4*(ch/2)));
if( address < 0x8000 ) return (ch < 0 ? (address + 0x7000) : (address + (ch << 8)) );
if( address >= 0x8000 ) return address;
return 0;
}
unsigned short Index (unsigned short ch);
uint32_t CalAddress(unsigned int index); /// output actual address, also write the registerAddress
void SetName(std::string str) {this->name = str;}
private:
uint32_t address; /// This is the table of register, the actual address should call ActualAddress();
std::string name;
char type; /// read/write = 0; read = 1; write = 2
bool group;
};
inline void Reg::Print() const{
printf(" Name: %s\n", name.c_str());
printf("Address: 0x%04X\n", address);
printf(" Type: %s\n", type == RW::ReadWrite ? "Read/Write" : (type == RW::ReadONLY ? "Read-Only" : "Write-Only") );
printf(" Group: %s\n", group ? "True" : "False");
}
inline unsigned short Reg::Index (unsigned short ch){
unsigned short index;
if( address == 0x8180){
index = ((address + 4*(ch/2)) & 0x0FFF) / 4;
}else if( address < 0x8000){
index = (address + (ch << 8)) / 4;
}else{
if(address < 0xF000) {
index = (address & 0x0FFF) / 4;
}else{
index = ((address & 0x0FFF) + 0x0200 ) / 4;
}
}
return index;
}
inline uint32_t Reg::CalAddress(unsigned int index){
uint32_t actualAddress = 0xFFFF;
this->address = 0xFFFF;
if( index < 0x0200 /4 ) {actualAddress = index * 4 + 0x8000; this->address = index * 4 + 0x8000; }
if( 0x0200 / 4 <= index && index < 0x0300 /4 ) {actualAddress = index * 4 + 0xEE00; this->address = index * 4 + 0xEE00; }/// EE00 == F000 - 0200
if( 0x0F00 / 4 <= index && index < 0x1000 /4 ) {actualAddress = index * 4 + 0xE000; this->address = index * 4 + 0xE000; }
if( 0x1000 / 4 <= index ) {actualAddress = index * 4; this->address = (index * 4) & 0xF0FF; }
///for TriggerValidationMask
if( index == ((0x8180 + 4) & 0x0FFF) / 4 ) {actualAddress = 0x8180 + 4; address = 0x8180;} /// 1
if( index == ((0x8180 + 8) & 0x0FFF) / 4 ) {actualAddress = 0x8180 + 8; address = 0x8180;} /// 2
if( index == ((0x8180 + 12) & 0x0FFF) / 4 ) {actualAddress = 0x8180 + 12; address = 0x8180;} /// 3
if( index == ((0x8180 + 16) & 0x0FFF) / 4 ) {actualAddress = 0x8180 + 16; address = 0x8180;} /// 4
if( index == ((0x8180 + 20) & 0x0FFF) / 4 ) {actualAddress = 0x8180 + 20; address = 0x8180;} /// 5
if( index == ((0x8180 + 24) & 0x0FFF) / 4 ) {actualAddress = 0x8180 + 24; address = 0x8180;} /// 6
if( index == ((0x8180 + 28) & 0x0FFF) / 4 ) {actualAddress = 0x8180 + 28; address = 0x8180;} /// 7
return actualAddress;
}
namespace Register {
const Reg EventReadOutBuffer("EventReadOutBuffer", 0x0000, 1); /// R
///========== Channel or Group
const Reg ChannelDummy32 ("ChannelDummy32" , 0x1024); /// R/W
const Reg InputDynamicRange ("InputDynamicRange" , 0x1028); /// R/W
const Reg ChannelPulseWidth ("ChannelPulseWidth" , 0x1070); /// R/W
const Reg ChannelTriggerThreshold ("ChannelTriggerThreshold" , 0x1080); /// R/W
const Reg CoupleSelfTriggerLogic_G ("CoupleSelfTriggerLogic_G" , 0x1084, 0 , 1); /// R/W
const Reg ChannelStatus_R ("ChannelStatus_R" , 0x1088, 1); /// R
const Reg AMCFirmwareRevision_R ("AMCFirmwareRevision_R" , 0x108C, 1); /// R
const Reg ChannelDCOffset ("ChannelDCOffset" , 0x1098); /// R/W
const Reg ChannelADCTemperature_R ("ChannelADCTemperature_R" , 0x10A8, 1); /// R
const Reg ChannelSelfTriggerRateMeter_R ("ChannelSelfTriggerRateMeter_R", 0x10EC, 1); /// R
///========== Board
const Reg BoardConfiguration ("BoardConfiguration" , 0x8000, 0); /// R/W
const Reg BufferOrganization ("BufferOrganization" , 0x800C, 0); /// R/W
const Reg CustomSize ("CustomSize" , 0x8020, 0); /// R/W
const Reg ADCCalibration_W ("ADCCalibration_W" , 0x809C, 2); /// W
const Reg AcquisitionControl ("AcquisitionControl" , 0x8100, 0); /// R/W
const Reg AcquisitionStatus_R ("AcquisitionStatus_R" , 0x8104, 1); /// R
const Reg SoftwareTrigger_W ("SoftwareTrigger_W" , 0x8108, 2); /// W
const Reg GlobalTriggerMask ("GlobalTriggerMask" , 0x810C, 0); /// R/W
const Reg FrontPanelTRGOUTEnableMask ("FrontPanelTRGOUTEnableMask" , 0x8110, 0); /// R/W
const Reg PostTrigger ("PostTrigger" , 0x8114, 0); /// R/W
const Reg LVDSIOData ("LVDSIOData" , 0x8118, 0); /// R/W
const Reg FrontPanelIOControl ("FrontPanelIOControl" , 0x811C, 0); /// R/W
const Reg ChannelEnableMask ("ChannelEnableMask" , 0x8120, 0); /// R/W
const Reg ROCFPGAFirmwareRevision_R ("ROCFPGAFirmwareRevision_R" , 0x8124, 1); /// R
const Reg EventStored_R ("EventStored_R" , 0x812C, 1); /// R
const Reg VoltageLevelModeConfig ("VoltageLevelModeConfig" , 0x8138, 0); /// R/W
const Reg SoftwareClockSync_W ("SoftwareClockSync_W" , 0x813C, 2); /// W
const Reg BoardInfo_R ("BoardInfo_R" , 0x8140, 1); /// R
const Reg AnalogMonitorMode ("AnalogMonitorMode" , 0x8144, 0); /// R/W
const Reg EventSize_R ("EventSize_R" , 0x814C, 1); /// R
const Reg FanSpeedControl ("FanSpeedControl" , 0x8168, 0); /// R/W
const Reg MemoryBufferAlmostFullLevel ("MemoryBufferAlmostFullLevel" , 0x816C, 0); /// R/W
const Reg RunStartStopDelay ("RunStartStopDelay" , 0x8170, 0); /// R/W
const Reg BoardFailureStatus_R ("BoardFailureStatus_R" , 0x8178, 1); /// R
const Reg FrontPanelLVDSIONewFeatures ("FrontPanelLVDSIONewFeatures" , 0x81A0, 0); /// R/W
const Reg BufferOccupancyGain ("BufferOccupancyGain" , 0x81B4, 0); /// R/W
const Reg ChannelsShutdown_W ("ChannelsShutdown_W" , 0x81C0, 2); /// W
const Reg ExtendedVetoDelay ("ExtendedVetoDelay" , 0x81C4, 0); /// R/W
const Reg ReadoutControl ("ReadoutControl" , 0xEF00, 0); /// R/W
const Reg ReadoutStatus_R ("ReadoutStatus_R" , 0xEF04, 1); /// R
const Reg BoardID ("BoardID" , 0xEF08, 0); /// R/W
const Reg MCSTBaseAddressAndControl ("MCSTBaseAddressAndControl" , 0xEF0C, 0); /// R/W
const Reg RelocationAddress ("RelocationAddress" , 0xEF10, 0); /// R/W
const Reg InterruptStatusID ("InterruptStatusID" , 0xEF14, 0); /// R/W
const Reg InterruptEventNumber ("InterruptEventNumber" , 0xEF18, 0); /// R/W
const Reg MaxAggregatePerBlockTransfer ("MaxAggregatePerBlockTransfer" , 0xEF1C, 0); /// R/W
const Reg Scratch ("Scratch" , 0xEF20, 0); /// R/W
const Reg SoftwareReset_W ("SoftwareReset_W" , 0xEF24, 2); /// W
const Reg SoftwareClear_W ("SoftwareClear_W" , 0xEF28, 2); /// W
///====== Common for PHA and PSD
namespace DPP {
const Reg RecordLength_G ("RecordLength_G" , 0x1020, 0, 1); /// R/W
const Reg InputDynamicRange ("InputDynamicRange" , 0x1028, 0); /// R/W
const Reg NumberEventsPerAggregate_G ("NumberEventsPerAggregate_G" , 0x1034, 0, 1); /// R/W
const Reg PreTrigger ("PreTrigger" , 0x1038, 0); /// R/W
const Reg TriggerThreshold ("TriggerThreshold" , 0x106C, 0); /// R/W
const Reg TriggerHoldOffWidth ("TriggerHoldOffWidth" , 0x1074, 0); /// R/W
const Reg DPPAlgorithmControl ("DPPAlgorithmControl" , 0x1080, 0); /// R/W
const Reg ChannelStatus_R ("ChannelStatus_R" , 0x1088, 1); /// R
const Reg AMCFirmwareRevision_R ("AMCFirmwareRevision_R" , 0x108C, 1); /// R
const Reg ChannelDCOffset ("ChannelDCOffset" , 0x1098, 0); /// R/W
const Reg ChannelADCTemperature_R ("ChannelADCTemperature_R" , 0x10A8, 1); /// R
const Reg IndividualSoftwareTrigger_W ("IndividualSoftwareTrigger_W" , 0x10C0, 2); /// W
const Reg VetoWidth ("VetoWidth" , 0x10D4, 0); /// R/W
/// I know there are many duplication, it is the design.
const Reg BoardConfiguration ("BoardConfiguration" , 0x8000, 0 ); /// R/W
const Reg AggregateOrganization ("AggregateOrganization" , 0x800C, 0 ); /// R/W
const Reg ADCCalibration_W ("ADCCalibration_W" , 0x809C, 2 ); /// W
const Reg ChannelShutdown_W ("ChannelShutdown_W" , 0x80BC, 2 ); /// W
const Reg AcquisitionControl ("AcquisitionControl" , 0x8100, 0 ); /// R/W
const Reg AcquisitionStatus_R ("AcquisitionStatus_R" , 0x8104, 1 ); /// R
const Reg SoftwareTrigger_W ("SoftwareTrigger_W" , 0x8108, 2 ); /// W
const Reg GlobalTriggerMask ("GlobalTriggerMask" , 0x810C, 0 ); /// R/W
const Reg FrontPanelTRGOUTEnableMask ("FrontPanelTRGOUTEnableMask" , 0x8110, 0 ); /// R/W
const Reg LVDSIOData ("LVDSIOData" , 0x8118, 0 ); /// R/W
const Reg FrontPanelIOControl ("FrontPanelIOControl" , 0x811C, 0 ); /// R/W
const Reg ChannelEnableMask ("ChannelEnableMask" , 0x8120, 0 ); /// R/W
const Reg ROCFPGAFirmwareRevision_R ("ROCFPGAFirmwareRevision_R" , 0x8124, 1 ); /// R
const Reg EventStored_R ("EventStored_R" , 0x812C, 1 ); /// R
const Reg VoltageLevelModeConfig ("VoltageLevelModeConfig" , 0x8138, 0 ); /// R/W
const Reg SoftwareClockSync_W ("SoftwareClockSync_W" , 0x813C, 2 ); /// W
const Reg BoardInfo_R ("BoardInfo_R" , 0x8140, 1 ); /// R
const Reg AnalogMonitorMode ("AnalogMonitorMode" , 0x8144, 0 ); /// R/W
const Reg EventSize_R ("EventSize_R" , 0x814C, 1 ); /// R
const Reg TimeBombDowncounter_R ("TimeBombDowncounter_R" , 0x8158, 1 ); /// R
const Reg FanSpeedControl ("FanSpeedControl" , 0x8168, 0 ); /// R/W
const Reg RunStartStopDelay ("RunStartStopDelay" , 0x8170, 0 ); /// R/W
const Reg BoardFailureStatus_R ("BoardFailureStatus_R" , 0x8178, 1 ); /// R
const Reg DisableExternalTrigger ("DisableExternalTrigger" , 0x817C, 0 ); /// R/W
const Reg TriggerValidationMask_G ("TriggerValidationMask_G" , 0x8180, 0 , 1); /// R/W,
const Reg FrontPanelLVDSIONewFeatures ("FrontPanelLVDSIONewFeatures" , 0x81A0, 0 ); /// R/W
const Reg BufferOccupancyGain ("BufferOccupancyGain" , 0x81B4, 0 ); /// R/W
const Reg ExtendedVetoDelay ("ExtendedVetoDelay" , 0x81C4, 0 ); /// R/W
const Reg ReadoutControl ("ReadoutControl" , 0xEF00, 0 ); /// R/W
const Reg ReadoutStatus_R ("ReadoutStatus_R" , 0xEF04, 1 ); /// R
const Reg BoardID ("BoardID" , 0xEF08, 0 ); /// R/W
const Reg MCSTBaseAddressAndControl ("MCSTBaseAddressAndControl" , 0xEF0C, 0 ); /// R/W
const Reg RelocationAddress ("RelocationAddress" , 0xEF10, 0 ); /// R/W
const Reg InterruptStatusID ("InterruptStatusID" , 0xEF14, 0 ); /// R/W
const Reg InterruptEventNumber ("InterruptEventNumber" , 0xEF18, 0 ); /// R/W
const Reg MaxAggregatePerBlockTransfer("MaxAggregatePerBlockTransfer", 0xEF1C, 0 ); /// R/W
const Reg Scratch ("Scratch" , 0xEF20, 0 ); /// R/W
const Reg SoftwareReset_W ("SoftwareReset_W" , 0xEF24, 2 ); /// W
const Reg SoftwareClear_W ("SoftwareClear_W" , 0xEF28, 2 ); /// W
const Reg ConfigurationReload_W ("ConfigurationReload_W" , 0xEF34, 2 ); /// W
const Reg ROMChecksum_R ("ROMChecksum_R" , 0xF000, 1 ); /// R
const Reg ROMChecksumByte2_R ("ROMChecksumByte2_R" , 0xF004, 1 ); /// R
const Reg ROMChecksumByte1_R ("ROMChecksumByte1_R" , 0xF008, 1 ); /// R
const Reg ROMChecksumByte0_R ("ROMChecksumByte0_R" , 0xF00C, 1 ); /// R
const Reg ROMConstantByte2_R ("ROMConstantByte2_R" , 0xF010, 1 ); /// R
const Reg ROMConstantByte1_R ("ROMConstantByte1_R" , 0xF014, 1 ); /// R
const Reg ROMConstantByte0_R ("ROMConstantByte0_R" , 0xF018, 1 ); /// R
const Reg ROM_C_Code_R ("ROM_C_Code_R" , 0xF01C, 1 ); /// R
const Reg ROM_R_Code_R ("ROM_R_Code_R" , 0xF020, 1 ); /// R
const Reg ROM_IEEE_OUI_Byte2_R ("ROM_IEEE_OUI_Byte2_R" , 0xF024, 1 ); /// R
const Reg ROM_IEEE_OUI_Byte1_R ("ROM_IEEE_OUI_Byte1_R" , 0xF028, 1 ); /// R
const Reg ROM_IEEE_OUI_Byte0_R ("ROM_IEEE_OUI_Byte0_R" , 0xF02C, 1 ); /// R
const Reg ROM_BoardVersion_R ("ROM_BoardVersion_R" , 0xF030, 1 ); /// R
const Reg ROM_BoardFromFactor_R ("ROM_BoardFromFactor_R" , 0xF034, 1 ); /// R
const Reg ROM_BoardIDByte1_R ("ROM_BoardIDByte1_R" , 0xF038, 1 ); /// R
const Reg ROM_BoardIDByte0_R ("ROM_BoardIDByte0_R" , 0xF03C, 1 ); /// R
const Reg ROM_PCB_rev_Byte3_R ("ROM_PCB_rev_Byte3_R" , 0xF040, 1 ); /// R
const Reg ROM_PCB_rev_Byte2_R ("ROM_PCB_rev_Byte2_R" , 0xF044, 1 ); /// R
const Reg ROM_PCB_rev_Byte1_R ("ROM_PCB_rev_Byte1_R" , 0xF048, 1 ); /// R
const Reg ROM_PCB_rev_Byte0_R ("ROM_PCB_rev_Byte0_R" , 0xF04C, 1 ); /// R
const Reg ROM_FlashType_R ("ROM_FlashType_R" , 0xF050, 1 ); /// R
const Reg ROM_BoardSerialNumByte1_R ("ROM_BoardSerialNumByte1_R" , 0xF080, 1 ); /// R
const Reg ROM_BoardSerialNumByte0_R ("ROM_BoardSerialNumByte0_R" , 0xF084, 1 ); /// R
const Reg ROM_VCXO_Type_R ("ROM_VCXO_Type_R" , 0xF088, 1 ); /// R
namespace PHA {
const Reg DataFlush_W ("DataFlush_W" , 0x103C, 2); /// W not sure
const Reg ChannelStopAcquisition ("ChannelStopAcquisition" , 0x1040); /// R/W not sure
const Reg RCCR2SmoothingFactor ("RCCR2SmoothingFactor" , 0x1054); /// R/W Trigger Filter smoothing, triggerSmoothingFactor
const Reg InputRiseTime ("InputRiseTime" , 0x1058); /// R/W OK
const Reg TrapezoidRiseTime ("TrapezoidRiseTime" , 0x105C); /// R/W OK
const Reg TrapezoidFlatTop ("TrapezoidFlatTop" , 0x1060); /// R/W OK
const Reg PeakingTime ("PeakingTime" , 0x1064); /// R/W OK
const Reg DecayTime ("DecayTime" , 0x1068); /// R/W OK
const Reg TriggerThreshold ("TriggerThreshold" , 0x106C); /// R/W OK
const Reg RiseTimeValidationWindow ("RiseTimeValidationWindow" , 0x1070); /// R/W OK
const Reg TriggerHoldOffWidth ("TriggerHoldOffWidth" , 0x1074); /// R/W OK
const Reg PeakHoldOff ("PeakHoldOff" , 0x1078); /// R/W OK
const Reg ShapedTriggerWidth ("ShapedTriggerWidth" , 0x1084); /// R/W not sure
const Reg DPPAlgorithmControl2_G ("DPPAlgorithmControl2_G" , 0x10A0, 0, 1); /// R/W OK
const Reg FineGain ("FineGain" , 0x10C4); /// R/W OK
}
namespace PSD {
const Reg CFDSetting ("CFDSetting" , 0x103C); /// R/W
const Reg ForcedDataFlush_W ("ForcedDataFlush_W" , 0x1040, 2); /// W
const Reg ChargeZeroSuppressionThreshold ("ChargeZeroSuppressionThreshold" , 0x1044); /// R/W
const Reg ShortGateWidth ("ShortGateWidth" , 0x1054); /// R/W
const Reg LongGateWidth ("LongGateWidth" , 0x1058); /// R/W
const Reg GateOffset ("GateOffset" , 0x105C); /// R/W
const Reg TriggerThreshold ("TriggerThreshold" , 0x1060); /// R/W
const Reg FixedBaseline ("FixedBaseline" , 0x1064); /// R/W
const Reg TriggerLatency ("TriggerLatency" , 0x106C); /// R/W
const Reg ShapedTriggerWidth ("ShapedTriggerWidth" , 0x1070); /// R/W
const Reg TriggerHoldOffWidth ("TriggerHoldOffWidth" , 0x1074); /// R/W
const Reg ThresholdForPSDCut ("ThresholdForPSDCut" , 0x1078); /// R/W
const Reg PurGapThreshold ("PurGapThreshold" , 0x107C); /// R/W
const Reg DPPAlgorithmControl2_G ("DPPAlgorithmControl2_G" , 0x1084, 0, 1); /// R/W
const Reg EarlyBaselineFreeze ("EarlyBaselineFreeze" , 0x10D8); /// R/W
}
}
};
const std::vector<Reg> RegisterPHAList = {
Register::DPP::PHA::DataFlush_W ,
Register::DPP::PHA::ChannelStopAcquisition ,
Register::DPP::PHA::RCCR2SmoothingFactor ,
Register::DPP::PHA::InputRiseTime ,
Register::DPP::PHA::TrapezoidRiseTime ,
Register::DPP::PHA::TrapezoidFlatTop ,
Register::DPP::PHA::PeakingTime ,
Register::DPP::PHA::DecayTime ,
Register::DPP::PHA::TriggerThreshold ,
Register::DPP::PHA::RiseTimeValidationWindow ,
Register::DPP::PHA::TriggerHoldOffWidth ,
Register::DPP::PHA::PeakHoldOff ,
Register::DPP::PHA::ShapedTriggerWidth ,
Register::DPP::PHA::DPPAlgorithmControl2_G ,
Register::DPP::PHA::FineGain ,
Register::DPP::RecordLength_G ,
Register::DPP::InputDynamicRange ,
Register::DPP::NumberEventsPerAggregate_G ,
Register::DPP::PreTrigger ,
Register::DPP::TriggerThreshold ,
Register::DPP::TriggerHoldOffWidth ,
Register::DPP::DPPAlgorithmControl ,
Register::DPP::ChannelStatus_R ,
Register::DPP::AMCFirmwareRevision_R ,
Register::DPP::ChannelDCOffset ,
Register::DPP::ChannelADCTemperature_R ,
Register::DPP::IndividualSoftwareTrigger_W,
Register::DPP::VetoWidth ,
Register::DPP::TriggerValidationMask_G
};
const std::vector<Reg> RegisterPSDList = {
Register::DPP::PSD::CFDSetting ,
Register::DPP::PSD::ForcedDataFlush_W ,
Register::DPP::PSD::ChargeZeroSuppressionThreshold ,
Register::DPP::PSD::ShortGateWidth ,
Register::DPP::PSD::LongGateWidth ,
Register::DPP::PSD::GateOffset ,
Register::DPP::PSD::TriggerThreshold ,
Register::DPP::PSD::FixedBaseline ,
Register::DPP::PSD::TriggerLatency ,
Register::DPP::PSD::ShapedTriggerWidth ,
Register::DPP::PSD::TriggerHoldOffWidth ,
Register::DPP::PSD::ThresholdForPSDCut ,
Register::DPP::PSD::PurGapThreshold ,
Register::DPP::PSD::DPPAlgorithmControl2_G ,
Register::DPP::PSD::EarlyBaselineFreeze ,
Register::DPP::RecordLength_G ,
Register::DPP::InputDynamicRange ,
Register::DPP::NumberEventsPerAggregate_G ,
Register::DPP::PreTrigger ,
Register::DPP::TriggerThreshold ,
Register::DPP::TriggerHoldOffWidth ,
Register::DPP::DPPAlgorithmControl ,
Register::DPP::ChannelStatus_R ,
Register::DPP::AMCFirmwareRevision_R ,
Register::DPP::ChannelDCOffset ,
Register::DPP::ChannelADCTemperature_R ,
Register::DPP::IndividualSoftwareTrigger_W,
Register::DPP::VetoWidth ,
Register::DPP::TriggerValidationMask_G
};
/// Only Board Setting
const std::vector<Reg> RegisterDPPList = {
Register::DPP::BoardConfiguration ,
Register::DPP::AggregateOrganization ,
Register::DPP::ADCCalibration_W ,
Register::DPP::ChannelShutdown_W ,
Register::DPP::AcquisitionControl ,
Register::DPP::AcquisitionStatus_R ,
Register::DPP::SoftwareTrigger_W ,
Register::DPP::GlobalTriggerMask ,
Register::DPP::FrontPanelTRGOUTEnableMask ,
Register::DPP::LVDSIOData ,
Register::DPP::FrontPanelIOControl ,
Register::DPP::ChannelEnableMask ,
Register::DPP::ROCFPGAFirmwareRevision_R ,
Register::DPP::EventStored_R ,
Register::DPP::VoltageLevelModeConfig ,
Register::DPP::SoftwareClockSync_W ,
Register::DPP::BoardInfo_R ,
Register::DPP::AnalogMonitorMode ,
Register::DPP::EventSize_R ,
Register::DPP::TimeBombDowncounter_R ,
Register::DPP::FanSpeedControl ,
Register::DPP::RunStartStopDelay ,
Register::DPP::BoardFailureStatus_R ,
Register::DPP::DisableExternalTrigger ,
Register::DPP::FrontPanelLVDSIONewFeatures ,
Register::DPP::BufferOccupancyGain ,
Register::DPP::ExtendedVetoDelay ,
Register::DPP::ReadoutControl ,
Register::DPP::ReadoutStatus_R ,
Register::DPP::BoardID ,
Register::DPP::MCSTBaseAddressAndControl ,
Register::DPP::RelocationAddress ,
Register::DPP::InterruptStatusID ,
Register::DPP::InterruptEventNumber ,
Register::DPP::MaxAggregatePerBlockTransfer,
Register::DPP::Scratch ,
Register::DPP::SoftwareReset_W ,
Register::DPP::SoftwareClear_W ,
Register::DPP::ConfigurationReload_W ,
Register::DPP::ROMChecksum_R ,
Register::DPP::ROMChecksumByte2_R ,
Register::DPP::ROMChecksumByte1_R ,
Register::DPP::ROMChecksumByte0_R ,
Register::DPP::ROMConstantByte2_R ,
Register::DPP::ROMConstantByte1_R ,
Register::DPP::ROMConstantByte0_R ,
Register::DPP::ROM_C_Code_R ,
Register::DPP::ROM_R_Code_R ,
Register::DPP::ROM_IEEE_OUI_Byte2_R ,
Register::DPP::ROM_IEEE_OUI_Byte1_R ,
Register::DPP::ROM_IEEE_OUI_Byte0_R ,
Register::DPP::ROM_BoardVersion_R ,
Register::DPP::ROM_BoardFromFactor_R ,
Register::DPP::ROM_BoardIDByte1_R ,
Register::DPP::ROM_BoardIDByte0_R ,
Register::DPP::ROM_PCB_rev_Byte3_R ,
Register::DPP::ROM_PCB_rev_Byte2_R ,
Register::DPP::ROM_PCB_rev_Byte1_R ,
Register::DPP::ROM_PCB_rev_Byte0_R ,
Register::DPP::ROM_FlashType_R ,
Register::DPP::ROM_BoardSerialNumByte1_R ,
Register::DPP::ROM_BoardSerialNumByte0_R ,
Register::DPP::ROM_VCXO_Type_R
};
/***************************
namespace Register {
const uint32_t EventReadOutBuffer = 0x0000; /// R
///========== Channel or Group
const uint32_t ChannelDummy32 = 0x1024; /// R/W
const uint32_t InputDynamicRange = 0x1028; /// R/W
const uint32_t ChannelPulseWidth = 0x1070; /// R/W
const uint32_t ChannelTriggerThreshold = 0x1080; /// R/W
const uint32_t CoupleSelfTriggerLogic_G = 0x1084; /// R/W
const uint32_t ChannelStatus_R = 0x1088; /// R
const uint32_t AMCFirmwareRevision_ = 0x108C; /// R
const uint32_t ChannelDCOffset = 0x1098; /// R/W
const uint32_t ChannelADCTemperature_R = 0x10A8; /// R
const uint32_t ChannelSelfTriggerRateMeter_R = 0x10EC; /// R
///========== Board
const uint32_t BoardConfiguration = 0x8000; /// R/W
const uint32_t BufferOrganization = 0x800C; /// R/W
const uint32_t CustomSize = 0x8020; /// R/W
const uint32_t ADCCalibration_W = 0x809C; /// W
const uint32_t AcquisitionControl = 0x8100; /// R/W
const uint32_t AcquisitionStatus_R = 0x8104; /// R
const uint32_t SoftwareTrigger_W = 0x8108; /// W
const uint32_t GlobalTriggerMask = 0x810C; /// R/W
const uint32_t FrontPanelTRGOUTEnableMask = 0x8110; /// R/W
const uint32_t PostTrigger = 0x8114; /// R/W
const uint32_t LVDSIOData = 0x8118; /// R/W
const uint32_t FrontPanelIOControl = 0x811C; /// R/W
const uint32_t ChannelEnableMask = 0x8120; /// R/W
const uint32_t ROCFPGAFirmwareRevision_R = 0x8124; /// R
const uint32_t EventStored_R = 0x812C; /// R
const uint32_t VoltageLevelModeConfig = 0x8138; /// R/W
const uint32_t SoftwareClockSync_W = 0x813C; /// W
const uint32_t BoardInfo_R = 0x8140; /// R
const uint32_t AnalogMonitorMode = 0x8144; /// R/W
const uint32_t EventSize_R = 0x814C; /// R
const uint32_t FanSpeedControl = 0x8168; /// R/W
const uint32_t MemoryBufferAlmostFullLevel = 0x816C; /// R/W
const uint32_t RunStartStopDelay = 0x8170; /// R/W
const uint32_t BoardFailureStatus_R = 0x8178; /// R
const uint32_t FrontPanelLVDSIONewFeatures = 0x81A0; /// R/W
const uint32_t BufferOccupancyGain = 0x81B4; /// R/W
const uint32_t ChannelsShutdown_W = 0x81C0; /// W
const uint32_t ExtendedVetoDelay = 0x81C4; /// R/W
const uint32_t ReadoutControl = 0xEF00; /// R/W
const uint32_t ReadoutStatus_R = 0xEF04; /// R
const uint32_t BoardID = 0xEF08; /// R/W
const uint32_t MCSTBaseAddressAndControl = 0xEF0C; /// R/W
const uint32_t RelocationAddress = 0xEF10; /// R/W
const uint32_t InterruptStatusID = 0xEF14; /// R/W
const uint32_t InterruptEventNumber = 0xEF18; /// R/W
const uint32_t MaxAggregatePerBlockTransfer = 0xEF1C; /// R/W
const uint32_t Scratch = 0xEF20; /// R/W
const uint32_t SoftwareReset_W = 0xEF24; /// W
const uint32_t SoftwareClear_W = 0xEF28; /// W
///====== Common for PHA and PSD
namespace DPP {
const uint32_t RecordLength_G = 0x1020; /// R/W
const uint32_t InputDynamicRange = 0x1028; /// R/W
const uint32_t NumberEventsPerAggregate_G = 0x1034; /// R/W
const uint32_t PreTrigger = 0x1038; /// R/W
const uint32_t TriggerThreshold = 0x106C; /// R/W
const uint32_t TriggerHoldOffWidth = 0x1074; /// R/W
const uint32_t DPPAlgorithmControl = 0x1080; /// R/W
const uint32_t ChannelStatus_R = 0x1088; /// R
const uint32_t AMCFirmwareRevision_R = 0x108C; /// R
const uint32_t ChannelDCOffset = 0x1098; /// R/W
const uint32_t ChannelADCTemperature_R = 0x10A8; /// R
const uint32_t IndividualSoftwareTrigger_W = 0x10C0; /// W
const uint32_t VetoWidth = 0x10D4; /// R/W
/// I know there are many duplication, it is the design.
const uint32_t BoardConfiguration = 0x8000; /// R/W
const uint32_t AggregateOrganization = 0x800C; /// R/W
const uint32_t ADCCalibration_W = 0x809C; /// W
const uint32_t ChannelShutdown_W = 0x80BC; /// W
const uint32_t AcquisitionControl = 0x8100; /// R/W
const uint32_t AcquisitionStatus_R = 0x8104; /// R
const uint32_t SoftwareTrigger_W = 0x8108; /// W
const uint32_t GlobalTriggerMask = 0x810C; /// R/W
const uint32_t FrontPanelTRGOUTEnableMask = 0x8110; /// R/W
const uint32_t LVDSIOData = 0x8118; /// R/W
const uint32_t FrontPanelIOControl = 0x811C; /// R/W
const uint32_t ChannelEnableMask = 0x8120; /// R/W
const uint32_t ROCFPGAFirmwareRevision_R = 0x8124; /// R
const uint32_t EventStored_R = 0x812C; /// R
const uint32_t VoltageLevelModeConfig = 0x8138; /// R/W
const uint32_t SoftwareClockSync_W = 0x813C; /// W
const uint32_t BoardInfo_R = 0x8140; /// R /// [0:7] 0x0E = 725, 0x0B = 730, [8:15] 0x01 = 640 kSample, 0x08 = 5.12 MSample, [16:23] channel number
const uint32_t AnalogMonitorMode = 0x8144; /// R/W
const uint32_t EventSize_R = 0x814C; /// R
const uint32_t TimeBombDowncounter_R = 0x8158; /// R
const uint32_t FanSpeedControl = 0x8168; /// R/W
const uint32_t RunStartStopDelay = 0x8170; /// R/W
const uint32_t BoardFailureStatus_R = 0x8178; /// R
const uint32_t DisableExternalTrigger = 0x817C; /// R/W
const uint32_t TriggerValidationMask_G = 0x8180; /// R/W, 0x8180 + 4n
const uint32_t FrontPanelLVDSIONewFeatures = 0x81A0; /// R/W
const uint32_t BufferOccupancyGain = 0x81B4; /// R/W
const uint32_t ExtendedVetoDelay = 0x81C4; /// R/W
const uint32_t ReadoutControl = 0xEF00; /// R/W
const uint32_t ReadoutStatus_R = 0xEF04; /// R
const uint32_t BoardID = 0xEF08; /// R/W /// Geo address on VME crate
const uint32_t MCSTBaseAddressAndControl = 0xEF0C; /// R/W
const uint32_t RelocationAddress = 0xEF10; /// R/W
const uint32_t InterruptStatusID = 0xEF14; /// R/W
const uint32_t InterruptEventNumber = 0xEF18; /// R/W
const uint32_t MaxAggregatePerBlockTransfer= 0xEF1C; /// R/W
const uint32_t Scratch = 0xEF20; /// R/W
const uint32_t SoftwareReset_W = 0xEF24; /// W
const uint32_t SoftwareClear_W = 0xEF28; /// W
const uint32_t ConfigurationReload_W = 0xEF34; /// W
const uint32_t ROMChecksum_R = 0xF000; /// R
const uint32_t ROMChecksumByte2_R = 0xF004; /// R
const uint32_t ROMChecksumByte1_R = 0xF008; /// R
const uint32_t ROMChecksumByte0_R = 0xF00C; /// R
const uint32_t ROMConstantByte2_R = 0xF010; /// R
const uint32_t ROMConstantByte1_R = 0xF014; /// R
const uint32_t ROMConstantByte0_R = 0xF018; /// R
const uint32_t ROM_C_Code_R = 0xF01C; /// R
const uint32_t ROM_R_Code_R = 0xF020; /// R
const uint32_t ROM_IEEE_OUI_Byte2_R = 0xF024; /// R
const uint32_t ROM_IEEE_OUI_Byte1_R = 0xF028; /// R
const uint32_t ROM_IEEE_OUI_Byte0_R = 0xF02C; /// R
const uint32_t ROM_BoardVersion_R = 0xF030; /// R
const uint32_t ROM_BoardFromFactor_R = 0xF034; /// R
const uint32_t ROM_BoardIDByte1_R = 0xF038; /// R
const uint32_t ROM_BoardIDByte0_R = 0xF03C; /// R
const uint32_t ROM_PCB_rev_Byte3_R = 0xF040; /// R
const uint32_t ROM_PCB_rev_Byte2_R = 0xF044; /// R
const uint32_t ROM_PCB_rev_Byte1_R = 0xF048; /// R
const uint32_t ROM_PCB_rev_Byte0_R = 0xF04C; /// R
const uint32_t ROM_FlashType_R = 0xF050; /// R
const uint32_t ROM_BoardSerialNumByte1_R = 0xF080; /// R
const uint32_t ROM_BoardSerialNumByte0_R = 0xF084; /// R
const uint32_t ROM_VCXO_Type_R = 0xF088; /// R
namespace PHA {
const uint32_t DataFlush_W = 0x103C; /// W not sure
const uint32_t ChannelStopAcquisition = 0x1040; /// R/W not sure
const uint32_t RCCR2SmoothingFactor = 0x1054; /// R/W Trigger Filter smoothing, triggerSmoothingFactor
const uint32_t InputRiseTime = 0x1058; /// R/W OK
const uint32_t TrapezoidRiseTime = 0x105C; /// R/W OK
const uint32_t TrapezoidFlatTop = 0x1060; /// R/W OK
const uint32_t PeakingTime = 0x1064; /// R/W OK
const uint32_t DecayTime = 0x1068; /// R/W OK
const uint32_t TriggerThreshold = 0x106C; /// R/W OK
const uint32_t RiseTimeValidationWindow = 0x1070; /// R/W OK
const uint32_t TriggerHoldOffWidth = 0x1074; /// R/W OK
const uint32_t PeakHoldOff = 0x1078; /// R/W OK
const uint32_t ShapedTriggerWidth = 0x1084; /// R/W not sure
const uint32_t DPPAlgorithmControl2_G = 0x10A0; /// R/W OK
const uint32_t FineGain = 0x10C4; /// R/W OK
}
namespace PSD {
const uint32_t CFDSetting = 0x103C; /// R/W
const uint32_t ForcedDataFlush_W = 0x1040; /// W
const uint32_t ChargeZeroSuppressionThreshold = 0x1044; /// R/W
const uint32_t ShortGateWidth = 0x1054; /// R/W
const uint32_t LongGateWidth = 0x1058; /// R/W
const uint32_t GateOffset = 0x105C; /// R/W
const uint32_t TriggerThreshold = 0x1060; /// R/W
const uint32_t FixedBaseline = 0x1064; /// R/W
const uint32_t TriggerLatency = 0x106C; /// R/W
const uint32_t ShapedTriggerWidth = 0x1070; /// R/W
const uint32_t TriggerHoldOffWidth = 0x1074; /// R/W
const uint32_t ThresholdForPSDCut = 0x1078; /// R/W
const uint32_t PurGapThreshold = 0x107C; /// R/W
const uint32_t DPPAlgorithmControl2_G = 0x1084; /// R/W
const uint32_t EarlyBaselineFreeze = 0x10D8; /// R/W
}
}
}
*********************************/
#endif

23
macro.h Normal file
View File

@ -0,0 +1,23 @@
#ifndef MACRO_H
#define MACRO_H
#define MaxNPorts 4
#define MaxNBoards 22
#define MaxNChannels 16
#define MaxRecordLength 0x3fff * 8
#define MaxSaveFileSize 1024 * 1024 * 1024 * 2
#define SETTINGSIZE 2048
#include <sys/time.h> /** struct timeval, select() */
inline unsigned int get_time(){
unsigned int time_us;
struct timeval t1;
struct timezone tz;
gettimeofday(&t1, &tz);
time_us = (t1.tv_sec) * 1000 * 1000 + t1.tv_usec;
return time_us;
}
#endif

11
main.cpp Normal file
View File

@ -0,0 +1,11 @@
#include "mainWindow.h"
#include <QApplication>
int main(int argc, char *argv[]){
QApplication a(argc, argv);
MainWindow w;
w.show();
return a.exec();
}

17
mainWindow.C Normal file
View File

@ -0,0 +1,17 @@
#include "mainWindow.h"
#include <QWidget>
MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent){
setWindowTitle("FSU DAQ");
setGeometry(500, 100, 1000, 500);
}
MainWindow::~MainWindow(){
}

16
mainWindow.h Normal file
View File

@ -0,0 +1,16 @@
#ifndef MAINWINDOW_H
#define MAINWINDOW_H
#include <QMainWindow>
//^#===================================================== MainWindow
class MainWindow : public QMainWindow{
Q_OBJECT
public:
MainWindow(QWidget *parent = nullptr);
~MainWindow();
};
#endif // MAINWINDOW_H

284
test.cpp Normal file
View File

@ -0,0 +1,284 @@
#include "macro.h"
#include "ClassData.h"
#include "ClassDigitizer.h"
#include <TROOT.h>
#include <TSystem.h>
#include <TApplication.h>
#include <TCanvas.h>
#include <TGraph.h>
#include <TH1.h>
#include <TFile.h>
#include <TTree.h>
#include <sys/time.h> /** struct timeval, select() */
#include <termios.h> /** tcgetattr(), tcsetattr() */
#include <vector>
static struct termios g_old_kbd_mode;
static void cooked(void){
tcsetattr(0, TCSANOW, &g_old_kbd_mode);
}
static void uncooked(void){
struct termios new_kbd_mode;
/** put keyboard (stdin, actually) in raw, unbuffered mode */
tcgetattr(0, &g_old_kbd_mode);
memcpy(&new_kbd_mode, &g_old_kbd_mode, sizeof(struct termios));
new_kbd_mode.c_lflag &= ~(ICANON | ECHO);
new_kbd_mode.c_cc[VTIME] = 0;
new_kbd_mode.c_cc[VMIN] = 1;
tcsetattr(0, TCSANOW, &new_kbd_mode);
}
static void raw(void){
static char init;
if(init) return;
/** put keyboard (stdin, actually) in raw, unbuffered mode */
uncooked();
/** when we exit, go back to normal, "cooked" mode */
atexit(cooked);
init = 1;
}
int keyboardhit(){
struct timeval timeout;
fd_set read_handles;
int status;
raw();
/** check stdin (fd 0) for activity */
FD_ZERO(&read_handles);
FD_SET(0, &read_handles);
timeout.tv_sec = timeout.tv_usec = 0;
status = select(0 + 1, &read_handles, NULL, NULL, &timeout);
if(status < 0){
printf("select() failed in keyboardhit()\n");
exit(1);
}
return (status);
}
int getch(void){
unsigned char temp;
raw();
/** stdin = fd 0 */
if(read(0, &temp, 1) != 1) return 0;
return temp;
}
//^======================================
int main(int argc, char* argv[]){
/**////##################### Demo for loading and change setting without open a digitizer
/**
Digitizer * dig = new Digitizer();
dig->OpenDigitizer(0, 1, false, true);
dig->LoadSettingBinaryToMemory("expDir/settings/setting_323.bin");
//dig->ProgramPHABoard();
//dig->OpenSettingBinary("setting_323.bin");
//dig->ReadAllSettingsFromBoard();
//dig->PrintSettingFromMemory();
//dig->StopACQ();
//dig->WriteRegister(Register::DPP::SoftwareClear_W, 1);
printf("========== %d \n", dig->ReadSettingFromFile(Register::DPP::MaxAggregatePerBlockTransfer));
///dig->SaveSettingAsText("haha.txt");
///std::remove("Test_323_139_000.fsu");
//printf("========== %d \n", dig->ReadRegister(Register::DPP::MaxAggregatePerBlockTransfer));
delete dig;
/**
{///============ Checking the buffer size calculation
unsigned short B = 10; /// BLT
unsigned short Eg = 511; /// Event / dual channel
bool DT = 1; /// dual trace
bool E2 = 1; /// extra 2;
bool Wr = 1; /// wave record;
unsigned short AP2 = 0; /// 00 = input, 01 = Threshold, 10 = Trapezoid - Baseline, 11 = baseline
unsigned short AP1 = 1; /// 00 = input, 01 = RC-CR, 10 = RC-CR2, 11 = Trapezoid
unsigned short DP1 = 0x0000; /// peaking,
unsigned short RL = 100; /// record Length
unsigned short AO = 0x0;
for( int i = 0; i < dig->GetNChannel(); i++){
dig->WriteRegister(Register::DPP::NumberEventsPerAggregate_G, Eg, i);
dig->WriteRegister(Register::DPP::RecordLength_G, RL, i);
}
dig->WriteRegister(Register::DPP::MaxAggregatePerBlockTransfer, B);
dig->WriteRegister(Register::DPP::AggregateOrganization, AO);
uint32_t bit = 0x0C0115;
bit += (DT << 11);
bit += (AP1 << 12);
bit += (AP2 << 14);
bit += (Wr << 16);
bit += (E2 << 17);
bit += (DP1 << 20);
printf("---- Bd Config : 0x%08X \n", bit);
dig->WriteRegister(Register::DPP::BoardConfiguration, bit);
unsigned int bSize = dig->CalByteForBuffer();
int bbbb = (((2 + E2 + Wr*RL*4) * Eg + 2)*8 + 2)*B *4 *2 + 4 * 4;
printf("=========== exp Buffer size : %8u byte \n", bbbb);
usleep(1e6);
///using CAEN method
char * buffer = NULL;
uint32_t size;
CAEN_DGTZ_MallocReadoutBuffer(dig->GetHandle(), (char **)& buffer, &size);
printf("CAEN calculated Buffer Size : %8u byte = %.2f MB \n", size, size/1024./1024.);
printf(" diff : %8u byte \n", size > 2*bSize ? size - 2*bSize : 2*bSize - size);
delete buffer;
}/**/
//dig->GetData()->SetSaveWaveToMemory(true);
//dig->StartACQ();
//
//for( int i = 0; i < 60; i++){
// usleep(500*1000);
// dig->ReadData();
// printf("------------------- %d\n", i);
// unsigned long time1 = get_time();
// dig->GetData()->DecodeBuffer(false,0);
// unsigned long time2 = get_time();
// printf("********************* decode time : %lu usec\n", time2-time1);
// dig->GetData()->PrintStat();
// //dig->GetData()->SaveBuffer("Test");
//}
//
//dig->StopACQ();
/**///##################### test with 2 digitizers
/**
const int nBoard = 2;
Digitizer **dig = new Digitizer *[nBoard];
for( int i = 0 ; i < nBoard; i++){
int board = i % 3;
int port = i/3;
dig[i] = new Digitizer(board, port, false, true);
dig[i]->OpenSettingBinary("setting_" + to_string(dig[i]->GetSerialNumber()) + ".bin");
dig[i]->LoadSettingBinaryToMemory("setting_" + to_string(dig[0]->GetSerialNumber()) + ".bin");
}
dig[0]->SaveSettingAsText("haha.txt");
delete dig[0];
delete dig[1];
TApplication * app = new TApplication("app", &argc, argv);
TCanvas * canvas = new TCanvas("c", "haha", 1200, 400);
canvas->Divide(3, 1);
TH1F * h1 = new TH1F("h1", "count", dig[0]->GetNChannel(), 0, dig[0]->GetNChannel());
TH1F * h2 = new TH1F("h2", "energy ch-0", 400, 0, 40000);
TGraph * g1 = new TGraph();
canvas->cd(1); h1->Draw("hist");
canvas->cd(2); h2->Draw();
canvas->cd(3); g1->Draw("AP");
Data * data = dig[0]->GetData();
data->AllocateMemory();
remove("test.bin");
dig[0]->StartACQ();
std::vector<unsigned short> haha ;
uint32_t PreviousTime = get_time();
uint32_t CurrentTime = 0;
uint32_t ElapsedTime = 0;
while(true){
if(keyboardhit()) {
break;
}
usleep(50000);
dig[0]->ReadData();
if( data->nByte > 0 ){
data->SaveBuffer("test");
data->DecodeBuffer(0);
unsigned short nData = data->NumEvents[0]; //channel-0
haha = data->Waveform1[0][nData-1];
for( int i = 0; i < waveFormLength; i++) g1->SetPoint(i, i*ch2ns, haha[i]);
canvas->cd(3); g1->Draw("AP");
canvas->Modified();
canvas->Update();
gSystem->ProcessEvents();
}
CurrentTime = get_time();
ElapsedTime = CurrentTime - PreviousTime; /// milliseconds
if( ElapsedTime > 1000 ){
int temp = system("clear");
data->PrintStat();
for(int i = 0; i < dig[0]->GetNChannel(); i++){
h1->Fill(i, data->NumEvents[i]);
}
for( int i = 0; i < data->NumEvents[0]; i++){
h2->Fill( data->Energy[0][i]);
}
data->ClearData();
canvas->cd(1); h1->Draw("hist");
canvas->cd(2); h2->Draw();
canvas->Modified();
canvas->Update();
gSystem->ProcessEvents();
PreviousTime = CurrentTime;
printf("Press any key to Stop\n");
}
}
dig[0]->StopACQ();
app->Run();
delete [] dig;
/*********************/
return 0;
}

477
test_indep.cpp Normal file
View File

@ -0,0 +1,477 @@
#include <stdio.h>
#include <string>
#include <sstream>
#include <cmath>
#include <cstring> ///memset
#include <iostream> ///cout
#include <bitset>
#include "CAENDigitizer.h"
#include "CAENDigitizerType.h"
#include "macro.h"
#include "RegisterAddress.h"
using namespace std;
void PrintChannelSettingFromDigitizer(int handle, int ch, float ch2ns){
printf("\e[33m================================================\n");
printf("================ Setting for channel %d \n", ch);
printf("================================================\e[0m\n");
///DPP algorithm Control
uint32_t * value = new uint32_t[16];
CAEN_DGTZ_ReadRegister(handle, Register::DPP::DPPAlgorithmControl + (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]);
printf(" = 0x%x\n", value[0]);
int trapRescaling = int(value[0]) & 0x1f ;
int polarity = int(value[0] >> 16) & 0x1; /// in bit[16]
int baseline = int(value[0] >> 20) & 0x7; /// in bit[22:20]
int NsPeak = int(value[0] >> 12) & 0x3; /// in bit[13:12]
int rollOver = int(value[0] >> 26) & 0x1;
int pileUp = int(value[0] >> 27) & 0x1;
///DPP algorithm Control 2
CAEN_DGTZ_ReadRegister(handle, Register::DPP::PHA::DPPAlgorithmControl2_G + (ch << 8), value);
cout <<" DPP algorithm Control 2: 0b" << bitset<32>(value[0]) ;
printf(" = 0x%x\n", value[0]);
int extras2WordOption = int(value[0] >> 8) & 0x3;
string extra2WordOptStr = "";
switch (extras2WordOption){
case 0 : extra2WordOptStr = "[0:15] Baseline *4 [16:31] Extended Time Stamp"; break;
case 2 : extra2WordOptStr = "[0:9] Fine Time Stamp [10:15] Reserved [16:31] Extended Time Stamp"; break;
case 4 : extra2WordOptStr = "[0:15] Total Trigger Counter [16:31] Lost Trigger Counter"; break;
case 5 : extra2WordOptStr = "[0:15] Event After the Zero Crossing [16:31] Event Before the Zero Crossing"; break;
default: extra2WordOptStr = "Reserved"; break;
}
printf(" ch2ns : %.0f ns\n", ch2ns);
printf("==========----- input \n");
CAEN_DGTZ_ReadRegister(handle, Register::DPP::RecordLength_G + (ch << 8), value); printf("%24s %5d samples = %5.0f ns \n", "Record Length", ((value[0] * 8) & MaxRecordLength), ((value[0] * 8) & MaxRecordLength) * ch2ns); ///Record length
CAEN_DGTZ_ReadRegister(handle, Register::DPP::PreTrigger + (ch << 8), value); printf("%24s %5d samples = %5.0f ns \n", "Pre-tigger", value[0] * 4, value[0] * 4 * ch2ns); ///Pre-trigger
printf("%24s %5.0f samples, DPP-[20:22]\n", "baseline mean", pow(4, 1 + baseline)); ///Ns baseline
CAEN_DGTZ_ReadRegister(handle, Register::DPP::ChannelDCOffset + (ch << 8), value); printf("%24s %.2f %% \n", "DC offset", 100.0 - value[0] * 100./ 0xFFFF); ///DC offset
CAEN_DGTZ_ReadRegister(handle, Register::DPP::InputDynamicRange + (ch << 8), value); printf("%24s %.1f Vpp \n", "input Dynamic", value[0] == 0 ? 2 : 0.5); ///InputDynamic
printf("%24s %s, DPP-[16]\n", "polarity", polarity == 0 ? "Positive" : "negative"); ///Polarity
printf("==========----- discriminator \n");
CAEN_DGTZ_ReadRegister(handle, Register::DPP::PHA::TriggerThreshold + (ch << 8), value); printf("%24s %4d LSB\n", "Threshold", value[0]); ///Threshold
CAEN_DGTZ_ReadRegister(handle, Register::DPP::PHA::TriggerHoldOffWidth + (ch << 8), value); printf("%24s %4d samples, %5.0f ns \n", "trigger hold off", value[0], value[0] * 4 * ch2ns); ///Trigger Hold off
CAEN_DGTZ_ReadRegister(handle, Register::DPP::PHA::RCCR2SmoothingFactor + (ch << 8), value); printf("%24s %4d samples, %5.0f ns \n", "Fast Dis. smoothing", (value[0] & 0x1f) * 2, (value[0] & 0x1f) * 2 * ch2ns ); ///Fast Discriminator smoothing
CAEN_DGTZ_ReadRegister(handle, Register::DPP::PHA::ShapedTriggerWidth + (ch << 8), value); printf("%24s %4d samples, %5.0f ns \n", "Fast Dis. output width", value[0], value[0] * 4 * ch2ns); ///Fast Dis. output width
CAEN_DGTZ_ReadRegister(handle, Register::DPP::PHA::InputRiseTime + (ch << 8), value); printf("%24s %4d samples, %5.0f ns \n", "Input rise time ", value[0], value[0] * 4 * ch2ns); ///Input rise time
printf("==========----- Trapezoid \n");
CAEN_DGTZ_ReadRegister(handle, Register::DPP::PHA::TrapezoidRiseTime + (ch << 8), value); printf("%24s %4d samples, %5.0f ns \n", "Trap. rise time", value[0], value[0] * 4 * ch2ns); ///Trap. rise time, 2 for 1 ch to 2ns
int riseTime = value[0] * 4 * ch2ns;
CAEN_DGTZ_ReadRegister(handle, Register::DPP::PHA::TrapezoidFlatTop + (ch << 8), value); printf("%24s %4d samples, %5.0f ns \n", "Trap. flat time", value[0], value[0] * 4 * ch2ns); ///Trap. flat time
int flatTopTime = value[0] * 4 * ch2ns;
double shift = log(riseTime * flatTopTime ) / log(2) - 2;
printf("%24s %4d bit =? %.1f = Ceil( Log(rise [ns] x decay [ns])/Log(2) ), DPP-[0:5]\n", "Trap. Rescaling", trapRescaling, shift ); ///Trap. Rescaling Factor
CAEN_DGTZ_ReadRegister(handle, Register::DPP::PHA::DecayTime + (ch << 8), value); printf("%24s %4d samples, %5.0f ns \n", "Decay time", value[0], value[0] * 4 * ch2ns); ///Trap. pole zero
CAEN_DGTZ_ReadRegister(handle, Register::DPP::PHA::PeakingTime + (ch << 8), value); printf("%24s %4d samples, %5.0f ns = %.2f %% of FlatTop\n", "Peaking time", value[0], value[0] * 4 * ch2ns, value[0] * 400. * ch2ns / flatTopTime ); ///Peaking time
CAEN_DGTZ_ReadRegister(handle, Register::DPP::PHA::PeakHoldOff + (ch << 8), value); printf("%24s %4d samples, %5.0f ns \n", "Peak hole off", value[0], value[0] * 4 *ch2ns ); ///Peak hold off
printf("%24s %4.0f samples, DPP-[12:13]\n", "Peak mean", pow(4, NsPeak)); ///Ns peak
printf("==========----- Other \n");
CAEN_DGTZ_ReadRegister(handle, Register::DPP::PHA::FineGain + (ch << 8), value); printf("%24s %d = 0x%x\n", "Energy fine gain", value[0], value[0]); ///Energy fine gain
CAEN_DGTZ_ReadRegister(handle, Register::DPP::ChannelADCTemperature_R + (ch << 8), value); printf("%24s %d C\n", "Temperature", value[0]); ///Temperature
CAEN_DGTZ_ReadRegister(handle, Register::DPP::PHA::RiseTimeValidationWindow + (ch << 8), value); printf("%24s %.0f ns \n", "RiseTime Vaild Win.", value[0] * ch2ns);
CAEN_DGTZ_ReadRegister(handle, Register::DPP::PHA::ChannelStopAcquisition + (ch << 8), value); printf("%24s %d = %s \n", "Stop Acq bit", value[0] & 1 , (value[0] & 1 ) == 0 ? "Run" : "Stop");
CAEN_DGTZ_ReadRegister(handle, Register::DPP::ChannelStatus_R + (ch << 8), value); printf("%24s 0x%x \n", "Status bit", (value[0] & 0xff) );
CAEN_DGTZ_ReadRegister(handle, Register::DPP::AMCFirmwareRevision_R + (ch << 8), value); printf("%24s 0x%x \n", "AMC firmware rev.", value[0] );
CAEN_DGTZ_ReadRegister(handle, Register::DPP::VetoWidth + (ch << 8), value); printf("%24s 0x%x \n", "VetoWidth bit", value[0] );
printf("%24s %d = %s\n", "RollOverFlag, DPP-[26]", rollOver, rollOver ? "enable" : "disable" );
printf("%24s %d = %s\n", "Pile-upFlag, DPP-[27]", pileUp, pileUp ? "enable" : "disable" );
printf("%24s %d, %s \n", "Extra2 opt, DPP2-[8:10]", extras2WordOption, extra2WordOptStr.c_str());
printf("========= events storage and transfer\n");
CAEN_DGTZ_ReadRegister(handle, Register::DPP::NumberEventsPerAggregate_G + (ch << 8), value); printf("%24s %d \n", "Event Aggregate", value[0] & 0x3FF);
CAEN_DGTZ_ReadRegister(handle, Register::DPP::AggregateOrganization, value); printf("%24s %d \n", "Buffer Division", ((value[0] & 0x007) < 2 ? 0 : (int)pow(2, value[0] & 7)));
CAEN_DGTZ_ReadRegister(handle, Register::DPP::MaxAggregatePerBlockTransfer , value); printf("%24s %d \n", "Num of Agg. / ReadData", value[0] & 0x1FF);
printf("========================================= end of ch-%d\n", ch);
}
void PrintBoardConfiguration(int handle){
printf("\e[33m================================================\n");
printf("================ Setting for Board \n");
printf("================================================\e[0m\n");
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(" : 0x%x\n", value[0]);
printf(" Bit[ 0] = %d = Auto Data Flush \n", value[0] & 0x1);
printf(" Bit[ 1] = %d = Decimated waveform \n", (value[0] >> 1) & 0x1 );
printf(" Bit[ 2] = %d = Trigger propagation \n", (value[0] >> 2) & 0x1 );
printf(" Bit[ 3:10] = %d = must be 001 0001 0 = 22 \n", (value[0] >> 3) & 0xFF );
printf(" Bit[ 11] = %d = Dual Trace \n", (value[0] >> 11) & 0x1 );
printf(" Bit[12:13] = %d = Analog probe 1 : ",((value[0] >> 12) & 0x3 ));
switch ( ((value[0] >> 12) & 0x3 ) ){
case 0 : printf("input\n"); break;
case 1 : printf("RC-CR (1st derivative)\n");break;
case 2 : printf("RC-CR2 (2nd derivative)\n"); break;
case 3 : printf("Trapezoid \n"); break;
}
printf(" Bit[14:15] = %d = Analog probe 2 : ", ((value[0] >> 14) & 0x3 ));
switch ( ((value[0] >> 14) & 0x3 ) ){
case 0 : printf("input\n"); break;
case 1 : printf("Threshold\n"); break;
case 2 : printf("Trapezoid - Baseline\n"); break;
case 3 : printf("baseline.\n"); break;
}
printf(" Bit[ 16] = %d = WaveForm Recording \n",((value[0] >> 16) & 0x1 ) );
printf(" Bit[ 17] = %d = Extras 2 word enable \n", ((value[0] >> 17) & 0x1 ));
printf(" Bit[ 18] = %d = Record Time Stamp \n", ((value[0] >> 18) & 0x1 ));
printf(" Bit[ 19] = %d = Record Energy \n", ((value[0] >> 19) & 0x1 ));
printf(" Bit[20:23] = %d = Digital Virtual probe 1 : ", ((value[0] >> 20) & 0x7 ));
switch (((value[0] >> 20) & 0xF )) {
case 0: printf("Peaking, shows where the energy is calculated; \n"); break;
case 1: printf("”Armed”, digital input showing where the RCCR2 crosses the Threshold\n");
case 2: printf("”Peak Run”, starts with the trigger and last for the whole event\n");
case 3: printf("”Pileup”, shows where a pileup event occurred\n");
case 4: printf("”Peaking”, shows where the energy is calculated\n");
case 5: printf("”TRG Validation Win”, digital input showing the trigger validation acceptance window TVAW\n");
case 6: printf("”Baseline freeze”, shows where the algorithm stops calculating the baseline and its value is frozen\n");
case 7: printf("”TRG Holdoff”, shows the trigger holdoff parameter\n");
case 8: printf("”TRG Validation”, shows the trigger validation signal TRG_VAL \n");
case 9: printf("”Acq Busy”, this is 1 when the board is busy (saturated input signal or full memory board) or there is a veto\n");
case 10: printf("”Zero Cross. Win.”, shows the RT Discrimination Width\n");
case 11: printf("”Ext TRG”, shows the external trigger, when available\n");
case 12: printf("”Busy”, shows when the memory board is full.\n");
}
printf(" Bit[26:28] = %d = Digital Virtual probe 2 : ", ((value[0] >> 26) & 0x7 ));
if( ((value[0] >> 26) & 0x7 ) == 0 ) {
printf("Trigger\n");
}else{
printf("Reserved\n");
}
printf("====================================== \n");
}
unsigned int ReadBuffer(unsigned int nWord, char * buffer, bool verbose = true){
if( buffer == NULL ) return 0;
unsigned int word = 0;
for( int i = 0 ; i < 4 ; i++) word += ((buffer[i + 4 * nWord] & 0xFF) << 8*i);
if( verbose) printf("%d | 0x%08x\n", nWord, word);
return word;
}
int main(int argc, char* argv[]){
///============== open digitizer
int handle;
printf("======== open board\n");
int ret = CAEN_DGTZ_OpenDigitizer(CAEN_DGTZ_OpticalLink, 1, 0, 0, &handle);
CAEN_DGTZ_BoardInfo_t BoardInfo;
ret = (int) CAEN_DGTZ_GetInfo(handle, &BoardInfo);
int NChannel = BoardInfo.Channels;
uint32_t channelMask = 0xFFFF;
float ch2ns = 4.0;
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
}
unsigned int ADCbits = BoardInfo.ADC_NBits;
if( ret != 0 ) { printf("==== open digitizer\n"); return 0;}
///======= reset
ret = CAEN_DGTZ_Reset(handle);
printf("======== program board\n");
///ret |= CAEN_DGTZ_SetDPPAcquisitionMode(handle, CAEN_DGTZ_DPP_ACQ_MODE_List, CAEN_DGTZ_DPP_SAVE_PARAM_EnergyAndTime);
///ret |= CAEN_DGTZ_SetDPPAcquisitionMode(handle, CAEN_DGTZ_DPP_ACQ_MODE_Mixed, CAEN_DGTZ_DPP_SAVE_PARAM_EnergyAndTime); /// Board Configure can do that
/// Set the number of samples for each waveform
ret = CAEN_DGTZ_WriteRegister(handle, Register::DPP::RecordLength_G + 0x7000, 625);
if( ret != 0 ) { printf("==== set Record Length.\n"); return 0;}
//ret |= CAEN_DGTZ_WriteRegister(handle, Register::DPP::BoardConfiguration, 0x4F8115); // with wave
ret |= CAEN_DGTZ_WriteRegister(handle, Register::DPP::BoardConfiguration, 0x4E8115); // with-out wave
/// 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
/// Set the I/O level (CAEN_DGTZ_IOLevel_NIM or CAEN_DGTZ_IOLevel_TTL)
ret |= CAEN_DGTZ_SetIOLevel(handle, CAEN_DGTZ_IOLevel_NIM);
/** 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);
if( ret != 0 ) { printf("==== CAEN_DGTZ_SetExtTriggerInputMode.\n"); return 0;}
ret = CAEN_DGTZ_SetChannelEnableMask(handle, 0xFFFF);
if( ret != 0 ) { printf("==== CAEN_DGTZ_SetChannelEnableMask.\n"); return 0;}
ret = CAEN_DGTZ_SetNumEventsPerAggregate(handle, 0);
if( ret != 0 ) { printf("==== CAEN_DGTZ_SetNumEventsPerAggregate. %d\n", ret); return 0;}
//ret = CAEN_DGTZ_SetDPPEventAggregation(handle, 0, 0);
//if( ret != 0 ) { printf("==== CAEN_DGTZ_SetDPPEventAggregation. %d\n", ret); return 0;}
/** 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 != 0 ) { printf("==== set board error.\n"); return 0;}
printf("======== program Channels\n");
///CAEN_DGTZ_DPP_PHA_Params_t DPPParams;
///memset(&DPPParams, 0, sizeof(CAEN_DGTZ_DPP_PHA_Params_t));
///for(int i = 0; i < NChannel; i++){
/// DPPParams.M[i] = 5000; /// decay time [ns]
/// DPPParams.m[i] = 992; /// flat-top [ns]
/// DPPParams.k[i] = 96; /// rise-time [ns]
/// DPPParams.ftd[i] = 192; /// flat-top delay, peaking time [ns]
/// DPPParams.a[i] = 4; /// Trigger Filter smoothing factor, 1, 2, 3, 4, 16, 32
/// DPPParams.b[i] = 96; /// input rise time [ns]
/// DPPParams.thr[i] = 100; /// Threshold [LSB]
/// DPPParams.nsbl[i] = 3; /// Baseline samples, 0 = 0, when > 0, pow(4, n+1) /// in DPP Control
/// DPPParams.nspk[i] = 2; /// peak samples, 4^n /// in DPP Control
/// DPPParams.pkho[i] = 992 ; /// peak hold off [ns]
/// DPPParams.trgho[i] = 480 ; /// trigger hold off [ns]
/// DPPParams.twwdt[i] = 0 ; /// rise time validation window, 0x1070
/// DPPParams.trgwin[i] = 0 ; /// trigger coincident window
/// DPPParams.dgain[i] = 0; /// digial gain for digial probe, 2^n
/// DPPParams.enf[i] = 1 ; /// energy normalization factor (fine gain?)
/// DPPParams.decimation[i] = 0 ; /// waveform decimation, 2^n, when n = 0, disable
/// DPPParams.blho[i] = 0; /// not use
///}
///ret = CAEN_DGTZ_SetDPPParameters(handle, channelMask, &DPPParams);
ret |= CAEN_DGTZ_WriteRegister(handle, Register::DPP::PHA::DecayTime + 0x7000 , 5000 );
ret |= CAEN_DGTZ_WriteRegister(handle, Register::DPP::PHA::TrapezoidFlatTop + 0x7000 , 62 );
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 , 64 );
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::BoardConfiguration , 0x10E0114 );
ret |= CAEN_DGTZ_WriteRegister(handle, Register::DPP::NumberEventsPerAggregate_G + 0x7000, 5);
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("================ allowcate memory \n");
int Nb; /// number of byte
char *buffer = NULL; /// readout buffer
uint32_t NumEvents[MaxNChannels];
uint32_t AllocatedSize, BufferSize;
CAEN_DGTZ_DPP_PHA_Event_t *Events[MaxNChannels]; /// events buffer
CAEN_DGTZ_DPP_PHA_Waveforms_t *Waveform[MaxNChannels]; /// waveforms buffer
ret = CAEN_DGTZ_MallocReadoutBuffer(handle, &buffer, &AllocatedSize);
printf("allowcated %d byte ( %d words) for buffer\n", AllocatedSize, AllocatedSize/4);
ret |= CAEN_DGTZ_MallocDPPEvents(handle, reinterpret_cast<void**>(&Events), &AllocatedSize) ;
printf("allowcated %d byte for Events\n", AllocatedSize);
for( int i = 0 ; i < NChannel; i++){
ret |= CAEN_DGTZ_MallocDPPWaveforms(handle, reinterpret_cast<void**>(&Waveform[i]), &AllocatedSize);
printf("allowcated %d byte for waveform-%d\n", AllocatedSize, i);
}
if( ret != 0 ) { printf("==== memory allocation error.\n"); return 0;}
PrintBoardConfiguration(handle);
PrintChannelSettingFromDigitizer(handle, 4, ch2ns);
printf("============ Start ACQ \n");
CAEN_DGTZ_SWStartAcquisition(handle);
sleep(1);
printf("============ Read Data \n");
ret = CAEN_DGTZ_ReadData(handle, CAEN_DGTZ_SLAVE_TERMINATED_READOUT_MBLT, buffer, &BufferSize);
if (ret) {
printf("Error when reading data %d\n", ret);
return 0;
}
Nb = BufferSize;
if (Nb == 0 || ret) {
return 0;
}
ret |= (CAEN_DGTZ_ErrorCode) CAEN_DGTZ_GetDPPEvents(handle, buffer, BufferSize, reinterpret_cast<void**>(&Events), NumEvents);
if (ret) {
printf("Error when getting events from data %d\n", ret);
return 0;
}
for (int ch = 0; ch < NChannel; ch++) {
if( NumEvents[ch] > 0 ) printf("------------------------ %d, %d\n", ch, NumEvents[ch]);
for (int ev = 0; ev < NumEvents[ch]; ev++) {
///TrgCnt[ch]++;
if( ev == 0 ){
printf("%3s, %6s, %13s | %5s | %13s | %13s \n", "ev", "energy", "timetag", "ex2", "rollover", "timeStamp");
}
if (Events[ch][ev].Energy > 0 && Events[ch][ev].TimeTag > 0 ) {
///ECnt[ch]++;
unsigned long long timetag = (unsigned long long) Events[ch][ev].TimeTag;
unsigned long long rollOver = Events[ch][ev].Extras2 >> 16;
rollOver = rollOver << 31;
timetag += rollOver ;
printf("%3d, %6d, %13lu | %5u | %13llu | %13llu \n",
ev, Events[ch][ev].Energy,
Events[ch][ev].TimeTag,
Events[ch][ev].Extras2 ,
rollOver >> 32, timetag);
} else { /// PileUp
///PurCnt[ch]++;
}
} /// loop on events
} /// loop on channels
printf("============ Stop ACQ \n");
ret |= CAEN_DGTZ_ClearData(handle);
printf("============= Read Buffer \n");
unsigned int nw = 0;
do{
printf("######################################### Board Agg.\n");
unsigned int word = ReadBuffer(nw, buffer);
if( ( (word >> 28) & 0xF ) == 0xA ) { /// start of Board Agg
unsigned int nWord = word & 0x0FFFFFFF ;
printf(" number of words in this Agg : %d \n", nWord);
nw = nw + 1; word = ReadBuffer(nw, buffer);
unsigned int BoardID = ((word >> 27) & 0x1F);
bool BoardFailFlag = ((word >> 26) & 0x1 );
unsigned int ChannelMask = ( word & 0xFF ) ;
printf("Board ID : %d, FailFlag = %d, ChannelMask = 0x%x\n", BoardID, BoardFailFlag, ChannelMask);
nw = nw + 2;
unsigned int AggCounter = ReadBuffer(nw, buffer);
printf("Agg Counter : %d \n", AggCounter);
for( int chMask = 0; chMask < 8 ; chMask ++ ){
if( ((ChannelMask >> chMask) & 0x1 ) == 0 ) continue;
printf("---------------------- Dual Channel Block : %d\n", chMask *2 );
nw = nw + 1; word = ReadBuffer(nw, buffer);
bool hasFormatInfo = ((word >> 31) & 0x1);
unsigned int aggSize = ( word & 0x3FFFFFF ) ;
printf(" size : %d \n", aggSize);
unsigned int nSample = 0; /// wave form;
unsigned int nEvents = 0;
if( hasFormatInfo ){
nw = nw + 1; word = ReadBuffer(nw, buffer);
nSample = ( word & 0xFFFF ) * 8;
unsigned int digitalProbe = ( (word >> 16 ) & 0xF );
unsigned int analogProbe2 = ( (word >> 20 ) & 0x3 );
unsigned int analogProbe1 = ( (word >> 22 ) & 0x3 );
unsigned int extra2Option = ( (word >> 24 ) & 0x7 );
bool hasWaveForm = ( (word >> 27 ) & 0x1 );
bool hasExtra2 = ( (word >> 28 ) & 0x1 );
bool hasTimeStamp = ( (word >> 29 ) & 0x1 );
bool hasEnergy = ( (word >> 30 ) & 0x1 );
bool hasDualTrace = ( (word >> 31 ) & 0x1 );
printf("dualTrace : %d, Energy : %d, Time: %d, Wave : %d, Extra2: %d, Extra2Option: %d \n",
hasDualTrace, hasEnergy, hasTimeStamp, hasWaveForm, hasExtra2, extra2Option);
printf("Ana Probe 1 & 2: %d %d , Digi Probe: %d, nSample : %d \n",
analogProbe1, analogProbe2, digitalProbe, nSample);
nEvents = aggSize / (nSample/2 + 2 + hasExtra2 );
printf("=========== nEvents : %d \n", nEvents);
}else{
printf("does not has format info. unable to read buffer.\n");
break;
}
for( int ev = 0; ev < nEvents ; ev++){
printf("=================================== event : %d\n", ev);
nw = nw +1 ; word = ReadBuffer(nw, buffer);
bool channelTag = ((word >> 31) & 0x1);
unsigned int timeStamp = (word & 0x7FFFFFFF);
int channel = chMask*2 + channelTag;
printf("ch : %d, timeStamp %u \n", channel, timeStamp);
///===== read waveform
for( int wi = 0; wi < nSample/2; wi++){
nw = nw +1 ; word = ReadBuffer(nw, buffer, false);
bool isTrigger1 = (( word >> 31 ) & 0x1 );
unsigned int wave1 = (( word >> 16) & 0x3FFF);
bool isTrigger0 = (( word >> 15 ) & 0x1 );
unsigned int wave0 = ( word & 0x3FFF);
if( ev == 0 ){
printf("%4d| %5d, %d \n", 2*wi, wave0, isTrigger0);
printf("%4d| %5d, %d \n", 2*wi+1, wave1, isTrigger1);
}
}
nw = nw +1 ; word = ReadBuffer(nw, buffer);
unsigned int extra2 = word;
nw = nw +1 ; word = ReadBuffer(nw, buffer);
unsigned int extra = (( word >> 16) & 0x3FF);
unsigned int energy = (word & 0x7FFF);
bool pileUp = ((word >> 15) & 0x1);
printf("PileUp : %d , extra : 0x%04x, energy : %d \n", pileUp, extra, energy);
}
}
}else{
printf("incorrect buffer header. \n");
break;
}
nw++;
}while(true);
printf("=========== close Digitizer \n");
CAEN_DGTZ_SWStopAcquisition(handle);
CAEN_DGTZ_CloseDigitizer(handle);
CAEN_DGTZ_FreeReadoutBuffer(&buffer);
CAEN_DGTZ_FreeDPPEvents(handle, reinterpret_cast<void**>(&Events));
CAEN_DGTZ_FreeDPPWaveforms(handle, Waveform);
return 0;
}