AlcapDAQ  1
ReadoutTest_DPP_PHA_x724.c
Go to the documentation of this file.
1 /******************************************************************************
2 *
3 * CAEN SpA - Front End Division
4 * Via Vetraia, 11 - 55049 - Viareggio ITALY
5 * +390594388398 - www.caen.it
6 *
7 ***************************************************************************/
17 #include <CAENDigitizer.h>
18 
19 #include <stdio.h>
20 #include <stdlib.h>
21 
22 //#define INDIVIDUAL_TRIGGER_INPUTS
23 // The following define must be set to the actual number of connected boards
24 #define MAXNB 1
25 // NB: the following define MUST specify the ACTUAL max allowed number of board's channels
26 // it is needed for consistency inside the CAENDigitizer's functions used to allocate the memory
27 #define MaxNChannels 8
28 
29 #define MAXNBITS 14
30 
31 /* include some useful functions from file Functions.c
32 you can find this file in the src directory */
33 #include "Functions.h"
34 
35 /* ###########################################################################
36 * Functions
37 * ########################################################################### */
38 
39 /* --------------------------------------------------------------------------------------------------------- */
43 /* --------------------------------------------------------------------------------------------------------- */
45 {
46  /* This function uses the CAENDigitizer API functions to perform the digitizer's initial configuration */
47  int i, ret = 0;
48 
49  /* Reset the digitizer */
50  ret |= CAEN_DGTZ_Reset(handle);
51 
52  if (ret) {
53  printf("ERROR: can't reset the digitizer.\n");
54  return -1;
55  }
56  ret |= CAEN_DGTZ_WriteRegister(handle, 0x8000, 0x01000114); // Channel Control Reg (indiv trg, seq readout) ??
57 
58  /* Set the DPP acquisition mode
59  This setting affects the modes Mixed and List (see CAEN_DGTZ_DPP_AcqMode_t definition for details)
60  CAEN_DGTZ_DPP_SAVE_PARAM_EnergyOnly Only energy (DPP-PHA) or charge (DPP-PSD/DPP-CI v2) is returned
61  CAEN_DGTZ_DPP_SAVE_PARAM_TimeOnly Only time is returned
62  CAEN_DGTZ_DPP_SAVE_PARAM_EnergyAndTime Both energy/charge and time are returned
63  CAEN_DGTZ_DPP_SAVE_PARAM_None No histogram data is returned */
65 
66  // Set the digitizer acquisition mode (CAEN_DGTZ_SW_CONTROLLED or CAEN_DGTZ_S_IN_CONTROLLED)
68 
69  // Set the number of samples for each waveform
70  ret |= CAEN_DGTZ_SetRecordLength(handle, Params.RecordLength);
71 
72  // Set the I/O level (CAEN_DGTZ_IOLevel_NIM or CAEN_DGTZ_IOLevel_TTL)
73  ret |= CAEN_DGTZ_SetIOLevel(handle, Params.IOlev);
74 
75  /* Set the digitizer's behaviour when an external trigger arrives:
76 
77  CAEN_DGTZ_TRGMODE_DISABLED: do nothing
78  CAEN_DGTZ_TRGMODE_EXTOUT_ONLY: generate the Trigger Output signal
79  CAEN_DGTZ_TRGMODE_ACQ_ONLY = generate acquisition trigger
80  CAEN_DGTZ_TRGMODE_ACQ_AND_EXTOUT = generate both Trigger Output and acquisition trigger
81 
82  see CAENDigitizer user manual, chapter "Trigger configuration" for details */
84 
85  // Set the enabled channels
86  ret |= CAEN_DGTZ_SetChannelEnableMask(handle, Params.ChannelMask);
87 
88  // Set how many events to accumulate in the board memory before being available for readout
89  ret |= CAEN_DGTZ_SetDPPEventAggregation(handle, Params.EventAggr, 0);
90 
91  /* Set the mode used to syncronize the acquisition between different boards.
92  In this example the sync is disabled */
94 
95  // Set the DPP specific parameters for the channels in the given channelMask
96  ret |= CAEN_DGTZ_SetDPPParameters(handle, Params.ChannelMask, &DPPParams);
97 
98  for(i=0; i<MaxNChannels; i++) {
99  if (Params.ChannelMask & (1<<i)) {
100  // Set a DC offset to the input signal to adapt it to digitizer's dynamic range
101  ret |= CAEN_DGTZ_SetChannelDCOffset(handle, i, 0x8000);
102 
103  // Set the Pre-Trigger size (in samples)
104  ret |= CAEN_DGTZ_SetDPPPreTriggerSize(handle, i, 80);
105 
106  // Set the polarity for the given channel (CAEN_DGTZ_PulsePolarityPositive or CAEN_DGTZ_PulsePolarityNegative)
107  ret |= CAEN_DGTZ_SetChannelPulsePolarity(handle, i, Params.PulsePolarity);
108  }
109  }
110 
111  /* Set the virtual probes settings
112  DPP-PHA can save:
113  2 analog waveforms:
114  the first and the second can be specified with the VIRTUALPROBE 1 and 2 parameters
115 
116  4 digital waveforms:
117  the first is always the trigger
118  the second is always the gate
119  the third and fourth can be specified with the DIGITALPROBE 1 and 2 parameters
120 
121  CAEN_DGTZ_DPP_VIRTUALPROBE_SINGLE -> Save only the Input Signal waveform
122  CAEN_DGTZ_DPP_VIRTUALPROBE_DUAL -> Save also the waveform specified in VIRTUALPROBE
123 
124  Virtual Probes 1 types:
125  CAEN_DGTZ_DPP_PHA_VIRTUALPROBE1_trapezoid
126  CAEN_DGTZ_DPP_PHA_VIRTUALPROBE1_Delta
127  CAEN_DGTZ_DPP_PHA_VIRTUALPROBE1_Delta2
128  CAEN_DGTZ_DPP_PHA_VIRTUALPROBE1_Input
129 
130  Virtual Probes 2 types:
131  CAEN_DGTZ_DPP_PHA_VIRTUALPROBE2_Input
132  CAEN_DGTZ_DPP_PHA_VIRTUALPROBE2_S3
133  CAEN_DGTZ_DPP_PHA_VIRTUALPROBE2_DigitalCombo
134  CAEN_DGTZ_DPP_PHA_VIRTUALPROBE2_trapBaseline
135  CAEN_DGTZ_DPP_PHA_VIRTUALPROBE2_None
136 
137  Digital Probes types:
138  CAEN_DGTZ_DPP_PHA_DIGITAL_PROBE_trgKln
139  CAEN_DGTZ_DPP_PHA_DIGITAL_PROBE_Armed
140  CAEN_DGTZ_DPP_PHA_DIGITAL_PROBE_PkRun
141  CAEN_DGTZ_DPP_PHA_DIGITAL_PROBE_PkAbort
142  CAEN_DGTZ_DPP_PHA_DIGITAL_PROBE_Peaking
143  CAEN_DGTZ_DPP_PHA_DIGITAL_PROBE_PkHoldOff
144  CAEN_DGTZ_DPP_PHA_DIGITAL_PROBE_Flat
145  CAEN_DGTZ_DPP_PHA_DIGITAL_PROBE_trgHoldOff */
147 
148  if (ret) {
149  printf("Warning: errors found during the programming of the digitizer.\nSome settings may not be executed\n");
150  return ret;
151  } else {
152  return 0;
153  }
154 }
155 
156 /* ########################################################################### */
157 /* MAIN */
158 /* ########################################################################### */
159 int main(int argc, char *argv[])
160 {
161  /* The following variable is the type returned from most of CAENDigitizer
162  library functions and is used to check if there was an error in function
163  execution. For example:
164  ret = CAEN_DGTZ_some_function(some_args);
165  if(ret) printf("Some error"); */
167 
168  /* Buffers to store the data. The memory must be allocated using the appropriate
169  CAENDigitizer API functions (see below), so they must not be initialized here
170  NB: you must use the right type for different DPP analysis (in this case PHA) */
171  char *buffer = NULL; // readout buffer
172  CAEN_DGTZ_DPP_PHA_Event_t *Events[MaxNChannels]; // events buffer
173  CAEN_DGTZ_DPP_PHA_Waveforms_t *Waveform=NULL; // waveforms buffer
174 
175  /* The following variables will store the digitizer configuration parameters */
177  DigitizerParams_t Params[MAXNB];
178 
179  /* Arrays for data analysis */
180  uint64_t PrevTime[MAXNB][MaxNChannels];
181  uint64_t ExtendedTT[MAXNB][MaxNChannels];
182  uint32_t *EHisto[MAXNB][MaxNChannels]; // Energy Histograms
183  int ECnt[MAXNB][MaxNChannels];
184  int TrgCnt[MAXNB][MaxNChannels];
185  int PurCnt[MAXNB][MaxNChannels];
186 
187  /* The following variable will be used to get an handler for the digitizer. The
188  handler will be used for most of CAENDigitizer functions to identify the board */
189  int handle[MAXNB];
190 
191  /* Other variables */
192  int i, b, ch, ev;
193  int Quit=0;
194  int AcqRun = 0;
195  uint32_t AllocatedSize, BufferSize;
196  int Nb=0;
197  int DoSaveWave[MAXNB][MaxNChannels];
198  int MajorNumber;
199  int BitMask = 0;
200  uint64_t CurrentTime, PrevRateTime, ElapsedTime;
201  uint32_t NumEvents[MaxNChannels];
202  CAEN_DGTZ_BoardInfo_t BoardInfo;
203 
204  memset(DoSaveWave, 0, MAXNB*MaxNChannels*sizeof(int));
205  for (i=0; i<MAXNBITS; i++)
206  BitMask |= 1<<i; /* Create a bit mask based on number of bits of the board */
207 
208  /* *************************************************************************************** */
209  /* Set Parameters */
210  /* *************************************************************************************** */
211  memset(&Params, 0, MAXNB*sizeof(DigitizerParams_t));
212  memset(&DPPParams, 0, MAXNB*sizeof(CAEN_DGTZ_DPP_PHA_Params_t));
213  for(b=0; b<MAXNB; b++) {
214  for(ch=0; ch<MaxNChannels; ch++)
215  EHisto[b][ch] = NULL; //set all histograms pointers to NULL (we will allocate them later)
216 
217  /****************************\
218  * Communication Parameters *
219  \****************************/
220  // Direct USB connection
221  Params[b].LinkType = CAEN_DGTZ_USB; // Link Type
222  Params[b].VMEBaseAddress = 0; // For direct USB connection, VMEBaseAddress must be 0
223 
224  // Direct optical connection
225  //Params[b].LinkType = CAEN_DGTZ_PCI_OpticalLink; // Link Type
226  //Params[b].VMEBaseAddress = 0; // For direct CONET connection, VMEBaseAddress must be 0
227 
228  // Optical connection to A2818 (or A3818) and access to the board with VME bus
229  //Params[b].LinkType = CAEN_DGTZ_PCI_OpticalLink; // Link Type (CAEN_DGTZ_PCIE_OpticalLink for A3818)
230  //Params[b].VMEBaseAddress = 0x32100000; // VME Base Address (only for VME bus access; must be 0 for direct connection (CONET or USB)
231 
232  // USB connection to V1718 bridge and access to the board with VME bus
233  //Params[b].LinkType = CAEN_DGTZ_USB; // Link Type
234  //Params[b].VMEBaseAddress = 0x32100000; // VME Base Address (only for VME bus access; must be 0 for direct connection (CONET or USB)
235 
236  Params[b].IOlev = CAEN_DGTZ_IOLevel_TTL;
237  /****************************\
238  * Acquisition parameters *
239  \****************************/
240  Params[b].AcqMode = CAEN_DGTZ_DPP_ACQ_MODE_Mixed; // CAEN_DGTZ_DPP_ACQ_MODE_List or CAEN_DGTZ_DPP_ACQ_MODE_Oscilloscope
241  Params[b].RecordLength = 400; // Num of samples of the waveforms (only for Oscilloscope mode)
242  Params[b].ChannelMask = 0xF; // Channel enable mask
243  Params[b].EventAggr = 0; // number of events in one aggregate (0=automatic)
244  Params[b].PulsePolarity = CAEN_DGTZ_PulsePolarityNegative; // Pulse Polarity (this parameter can be individual)
245 
246  /****************************\
247  * DPP parameters *
248  \****************************/
249  for(ch=0; ch<MaxNChannels; ch++) {
250  DPPParams[b].thr[ch] = 200; // Trigger Threshold
251  DPPParams[b].k[ch] = 1000; // Trapezoid Rise Time (N*10ns)
252  DPPParams[b].m[ch] = 500; // Trapezoid Flat Top (N*10ns)
253  DPPParams[b].M[ch] = 200; // Decay Time Constant (N*10ns) HACK-FPEP the one expected from fitting algorithm?
254  DPPParams[b].ftd[ch] = 30; // Flat top delay (peaking time) (N*10ns) ??
255  DPPParams[b].a[ch] = 2; // Trigger Filter smoothing factor
256  DPPParams[b].b[ch] = 100; // Input Signal Rise time (N*10ns)
257  DPPParams[b].trgho[ch] = 600; // Trigger Hold Off
258  DPPParams[b].nsbl[ch] = 2; // 3 = bx10 = 64 samples
259  DPPParams[b].nspk[ch] = 2;
260  DPPParams[b].pkho[ch] = 770;
261  DPPParams[b].blho[ch] = 100;
262  DPPParams[b].enf[ch] = 1.0; // Energy Normalization Factor
263  //DPPParams[b].tsampl[ch] = 10;
264  //DPPParams[b].dgain[ch] = 1;
265  }
266  }
267 
268 
269  /* *************************************************************************************** */
270  /* Open the digitizer and read board information */
271  /* *************************************************************************************** */
272  /* The following function is used to open the digitizer with the given connection parameters
273  and get the handler to it */
274  for(b=0; b<MAXNB; b++) {
275  /* IMPORTANT: The following function identifies the different boards with a system which may change
276  for different connection methods (USB, Conet, ecc). Refer to CAENDigitizer user manual for more info.
277  Some examples below */
278 
279  /* The following is for b boards connected via b USB direct links
280  in this case you must set Params[b].LinkType = CAEN_DGTZ_USB and Params[b].VMEBaseAddress = 0 */
281  ret = CAEN_DGTZ_OpenDigitizer(Params[b].LinkType, b, 0, Params[b].VMEBaseAddress, &handle[b]);
282 
283  /* The following is for b boards connected via 1 opticalLink in dasy chain
284  in this case you must set Params[b].LinkType = CAEN_DGTZ_PCI_OpticalLink and Params[b].VMEBaseAddress = 0 */
285  //ret = CAEN_DGTZ_OpenDigitizer(Params[b].LinkType, 0, b, Params[b].VMEBaseAddress, &handle[b]);
286 
287  /* The following is for b boards connected to A2818 (or A3818) via opticalLink (or USB with A1718)
288  in this case the boards are accessed throught VME bus, and you must specify the VME address of each board:
289  Params[b].LinkType = CAEN_DGTZ_PCI_OpticalLink (CAEN_DGTZ_PCIE_OpticalLink for A3818 or CAEN_DGTZ_USB for A1718)
290  Params[0].VMEBaseAddress = <0xXXXXXXXX> (address of first board)
291  Params[1].VMEBaseAddress = <0xYYYYYYYY> (address of second board)
292  etc */
293  //ret = CAEN_DGTZ_OpenDigitizer(Params[b].LinkType, 0, 0, Params[b].VMEBaseAddress, &handle[b]);
294 
295  if (ret) {
296  printf("Can't open digitizer\n");
297  goto QuitProgram;
298  }
299 
300  /* Once we have the handler to the digitizer, we use it to call the other functions */
301  ret = CAEN_DGTZ_GetInfo(handle[b], &BoardInfo);
302  if (ret) {
303  printf("Can't read board info\n");
304  goto QuitProgram;
305  }
306  printf("\nConnected to CAEN Digitizer Model %s, recognized as board %d\n", BoardInfo.ModelName, b);
307  printf("ROC FPGA Release is %s\n", BoardInfo.ROC_FirmwareRel);
308  printf("AMC FPGA Release is %s\n", BoardInfo.AMC_FirmwareRel);
309 
310  /* Check firmware revision (only DPP firmwares can be used with this Demo) */
311  sscanf(BoardInfo.AMC_FirmwareRel, "%d", &MajorNumber);
312  if (MajorNumber != 128) {
313  printf("This digitizer has not a DPP-PHA firmware\n");
314  goto QuitProgram;
315  }
316  }
317 
318  /* *************************************************************************************** */
319  /* Program the digitizer (see function ProgramDigitizer) */
320  /* *************************************************************************************** */
321  for(b=0; b<MAXNB; b++) {
322  ret = ProgramDigitizer(handle[b], Params[b], DPPParams[b]);
323  if (ret) {
324  printf("Failed to program the digitizer\n");
325  goto QuitProgram;
326  }
327  }
328 
329  /* WARNING: The mallocs MUST be done after the digitizer programming,
330  because the following functions needs to know the digitizer configuration
331  to allocate the right memory amount */
332  /* Allocate memory for the readout buffer */
333  ret = CAEN_DGTZ_MallocReadoutBuffer(handle[0], &buffer, &AllocatedSize);
334  /* Allocate memory for the events */
335  ret |= CAEN_DGTZ_MallocDPPEvents(handle[0], Events, &AllocatedSize);
336  /* Allocate memory for the waveforms */
337  ret |= CAEN_DGTZ_MallocDPPWaveforms(handle[0], &Waveform, &AllocatedSize);
338  if (ret) {
339  printf("Can't allocate memory buffers\n");
340  goto QuitProgram;
341  }
342 
343 
344  /* *************************************************************************************** */
345  /* Readout Loop */
346  /* *************************************************************************************** */
347  // Clear Histograms and counters
348  for(b=0; b<MAXNB; b++) {
349  for(ch=0; ch<MaxNChannels; ch++) {
350  EHisto[b][ch] = (uint32_t *)malloc( (1<<MAXNBITS)*sizeof(uint32_t) );
351  memset(EHisto[b][ch], 0, (1<<MAXNBITS)*sizeof(uint32_t));
352  TrgCnt[b][ch] = 0;
353  ECnt[b][ch] = 0;
354  PrevTime[b][ch] = 0;
355  ExtendedTT[b][ch] = 0;
356  PurCnt[b][ch] = 0;
357  }
358  }
359  PrevRateTime = get_time();
360  AcqRun = 0;
361  PrintInterface();
362  printf("Type a command: ");
363  while(!Quit) {
364 
365  // Check keyboard
366  if(kbhit()) {
367  char c;
368  c = getch();
369  if (c=='q') Quit = 1;
370  if (c=='t')
371  for(b=0; b<MAXNB; b++)
372  CAEN_DGTZ_SendSWtrigger(handle[b]); /* Send a software trigger to each board */
373  if (c=='h')
374  for(b=0; b<MAXNB; b++)
375  for(ch=0; ch<MaxNChannels; ch++)
376  if( ECnt[b][ch] != 0)
377  SaveHistogram("Histo", b, ch, EHisto[b][ch]); /* Save Histograms to file for each board */
378  if (c=='w')
379  for(b=0; b<MAXNB; b++)
380  for(ch=0; ch<MaxNChannels; ch++)
381  DoSaveWave[b][ch] = 1; /* save waveforms to file for each channel for each board (at next trigger) */
382  if (c=='r') {
383  for(b=0; b<MAXNB; b++) {
384  CAEN_DGTZ_SWStopAcquisition(handle[b]);
385  printf("Restarted\n");
386  CAEN_DGTZ_ClearData(handle[b]);
387  CAEN_DGTZ_SWStartAcquisition(handle[b]);
388  }
389  }
390  if (c=='s') {
391  for(b=0; b<MAXNB; b++) {
392  // Start Acquisition
393  // NB: the acquisition for each board starts when the following line is executed
394  // so in general the acquisition does NOT starts syncronously for different boards
395  CAEN_DGTZ_SWStartAcquisition(handle[b]);
396  printf("Acquisition Started for Board %d\n", b);
397  }
398  AcqRun = 1;
399  }
400  if (c=='S') {
401  for(b=0; b<MAXNB; b++) {
402  // Stop Acquisition
403  CAEN_DGTZ_SWStopAcquisition(handle[b]);
404  printf("Acquisition Stopped for Board %d\n", b);
405  }
406  AcqRun = 0;
407  }
408  }
409  if (!AcqRun) {
410  Sleep(10);
411  continue;
412  }
413 
414  /* Calculate throughput and trigger rate (every second) */
415  CurrentTime = get_time();
416  ElapsedTime = CurrentTime - PrevRateTime; /* milliseconds */
417  if (ElapsedTime > 1000) {
418  system(CLEARSCR);
419  PrintInterface();
420  printf("Readout Rate=%.2f MB\n", (float)Nb/((float)ElapsedTime*1048.576f));
421  for(b=0; b<MAXNB; b++) {
422  printf("\nBoard %d:\n",b);
423  for(i=0; i<MaxNChannels; i++) {
424  if (TrgCnt[b][i]>0)
425  printf("\tCh %d:\tTrgRate=%.2f KHz\tPileUpRate=%.2f%%\n", i, (float)TrgCnt[b][i]/(float)ElapsedTime, (float)PurCnt[b][i]*100/(float)TrgCnt[b][i]);
426  else
427  printf("\tCh %d:\tNo Data\n", i);
428  TrgCnt[b][i]=0;
429  PurCnt[b][i]=0;
430  }
431  }
432  Nb = 0;
433  PrevRateTime = CurrentTime;
434  printf("\n\n");
435  }
436 
437  /* Read data from the boards */
438  for(b=0; b<MAXNB; b++) {
439  /* Read data from the board */
440  ret = CAEN_DGTZ_ReadData(handle[b], CAEN_DGTZ_SLAVE_TERMINATED_READOUT_MBLT, buffer, &BufferSize);
441  if (ret) {
442  printf("Readout Error\n");
443  goto QuitProgram;
444  }
445  if (BufferSize == 0)
446  continue;
447 
448  Nb += BufferSize;
449  //ret = DataConsistencyCheck((uint32_t *)buffer, BufferSize/4);
450  ret |= CAEN_DGTZ_GetDPPEvents(handle[b], buffer, BufferSize, Events, NumEvents);
451  if (ret) {
452  printf("Data Error: %d\n", ret);
453  goto QuitProgram;
454  }
455 
456  /* Analyze data */
457  //for(b=0; b<MAXNB; b++) printf("%d now: %d\n", b, Params[b].ChannelMask);
458  for(ch=0; ch<MaxNChannels; ch++) {
459  if (!(Params[b].ChannelMask & (1<<ch)))
460  continue;
461 
462  /* Update Histograms */
463  for(ev=0; ev<NumEvents[ch]; ev++) {
464  TrgCnt[b][ch]++;
465  /* Time Tag */
466  if (Events[ch][ev].TimeTag < PrevTime[b][ch])
467  ExtendedTT[b][ch]++;
468  PrevTime[b][ch] = Events[ch][ev].TimeTag;
469  /* Energy */
470  if (Events[ch][ev].Energy > 0) {
471  // Fill the histograms
472  EHisto[b][ch][(Events[ch][ev].Energy)&BitMask]++;
473  ECnt[b][ch]++;
474  } else { /* PileUp */
475  PurCnt[b][ch]++;
476  }
477  /* Get Waveforms (only from 1st event in the buffer) */
478  if ((Params[b].AcqMode != CAEN_DGTZ_DPP_ACQ_MODE_List) && DoSaveWave[b][ch] && (ev == 0)) {
479  int size;
480  int16_t *WaveLine;
481  uint8_t *DigitalWaveLine;
482  CAEN_DGTZ_DecodeDPPWaveforms(handle[b], &Events[ch][ev], Waveform);
483 
484  // Use waveform data here...
485  size = (int)(Waveform->Ns); // Number of samples
486  WaveLine = Waveform->Trace1; // First trace (VIRTUALPROBE1 set with CAEN_DGTZ_SetDPP_PSD_VirtualProbe)
487  SaveWaveform(b, ch, 1, size, WaveLine);
488 
489  WaveLine = Waveform->Trace2; // Second Trace (if single trace mode, it is a sequence of zeroes)
490  SaveWaveform(b, ch, 2, size, WaveLine);
491 
492  DigitalWaveLine = Waveform->DTrace1; // First Digital Trace (DIGITALPROBE1 set with CAEN_DGTZ_SetDPP_PSD_VirtualProbe)
493  SaveDigitalProbe(b, ch, 1, size, DigitalWaveLine);
494 
495  DigitalWaveLine = Waveform->DTrace2; // Second Digital Trace (for DPP-PHA it is ALWAYS Trigger)
496  SaveDigitalProbe(b, ch, 2, size, DigitalWaveLine);
497  DoSaveWave[b][ch] = 0;
498  printf("Waveforms saved to 'Waveform_<board>_<channel>_<trace>.txt'\n");
499  } // loop to save waves
500  } // loop on events
501  } // loop on channels
502  } // loop on boards
503  } // End of readout loop
504 
505 
506 QuitProgram:
507  /* stop the acquisition, close the device and free the buffers */
508  for(b=0; b<MAXNB; b++) {
509  CAEN_DGTZ_SWStopAcquisition(handle[b]);
510  CAEN_DGTZ_CloseDigitizer(handle[b]);
511  for (ch=0; ch<MaxNChannels; ch++)
512  if (EHisto[b][ch] != NULL)
513  free(EHisto[b][ch]);
514  }
516  CAEN_DGTZ_FreeDPPEvents(handle[0], Events);
517  CAEN_DGTZ_FreeDPPWaveforms(handle[0], Waveform);
518  return ret;
519 }
520