AlcapDAQ  1
Data Structures | Macros | Functions | Variables
caenV767.cpp File Reference
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/time.h>
#include <time.h>
#include "midas.h"
#include "crate.h"
#include "vme.h"
#include "odb_wrapper.h"
#include "diag.h"

Go to the source code of this file.

Data Structures

struct  caenV767
 

Macros

#define CAENV767_MAX_DMA_SIZE   256
 
#define CAENV767_MAX_SIZE   (32*1024*4)
 
#define ACTIVE_READOUT_MAX_PER_POLL   (2*1024)
 
#define CAENV767_NUM_CHANNELS   128
 
#define MAX_CAENV767   4
 
#define CAENV767_OUTBUF   0x00
 
#define CAENV767_CTR1   0x10
 
#define CAENV767_STR2   0x48
 
#define CAENV767_EVT_COUNT   0x4C
 
#define CAENV767_OPHAND   0x50
 
#define CAENV767_OPCODE   0x52
 
#define CAENV767_CLEAR   0x54
 
#define CAENV767_NOT_VALID   0x00600000
 
#define CAENV767_GLOBAL_TDC_ERROR   0x0008
 

Functions

INT caenV767_pre_bor ()
 
INT caenV767_eor ()
 
INT caenV767_poll_live ()
 
INT caenV767_read (char *pevent)
 
void caenV767_opcode_write (struct caenV767 *caen, short code)
 
short caenV767_opcode_read (struct caenV767 *caen)
 
INT caenV767_bor1 (struct caenV767 *caen)
 
INT caenV767_eor1 (struct caenV767 *caen)
 
INT caenV767_fifo_read (struct caenV767 *caen, unsigned char *buffer, int max_size, bool in_active_readout)
 
INT caenV767_poll1 (struct caenV767 *caen)
 
INT caenV767_read1 (struct caenV767 *caen, char *pevent)
 

Variables

struct readout_module caenV767_module
 
struct timeval block_start_time
 
struct caenV767 caenV767 [MAX_CAENV767]
 

Macro Definition Documentation

#define ACTIVE_READOUT_MAX_PER_POLL   (2*1024)

Definition at line 35 of file caenV767.cpp.

Referenced by caenV767_poll1().

#define CAENV767_CLEAR   0x54

Definition at line 65 of file caenV767.cpp.

Referenced by caenV767_bor1(), and caenV767_read1().

#define CAENV767_CTR1   0x10

Definition at line 60 of file caenV767.cpp.

Referenced by caenV767_bor1().

#define CAENV767_EVT_COUNT   0x4C

Definition at line 62 of file caenV767.cpp.

#define CAENV767_GLOBAL_TDC_ERROR   0x0008

Definition at line 71 of file caenV767.cpp.

Referenced by caenV767_read1().

#define CAENV767_MAX_DMA_SIZE   256

Definition at line 33 of file caenV767.cpp.

Referenced by caenV767_bor1().

#define CAENV767_MAX_SIZE   (32*1024*4)

Definition at line 34 of file caenV767.cpp.

Referenced by caenV767_read1().

#define CAENV767_NOT_VALID   0x00600000

Definition at line 68 of file caenV767.cpp.

Referenced by caenV767_fifo_read(), and caenV767_read1().

#define CAENV767_NUM_CHANNELS   128

Definition at line 36 of file caenV767.cpp.

Referenced by caenV767_bor1().

#define CAENV767_OPCODE   0x52

Definition at line 64 of file caenV767.cpp.

Referenced by caenV767_opcode_read(), and caenV767_opcode_write().

#define CAENV767_OPHAND   0x50

Definition at line 63 of file caenV767.cpp.

Referenced by caenV767_opcode_read(), and caenV767_opcode_write().

#define CAENV767_OUTBUF   0x00

Definition at line 59 of file caenV767.cpp.

Referenced by caenV767_fifo_read().

#define CAENV767_STR2   0x48

Definition at line 61 of file caenV767.cpp.

Referenced by caenV767_read1().

#define MAX_CAENV767   4

Definition at line 55 of file caenV767.cpp.

Referenced by caenV767_eor(), caenV767_poll_live(), caenV767_pre_bor(), and caenV767_read().

Function Documentation

INT caenV767_bor1 ( struct caenV767 caen)

Definition at line 108 of file caenV767.cpp.

References caenV767::active_readout_buffer, caenV767::active_readout_buffer_size, caenV767::active_readout_size, CAENV767_CLEAR, CAENV767_CTR1, CAENV767_MAX_DMA_SIZE, CAENV767_NUM_CHANNELS, caenV767_opcode_write(), channel, crate_number, diag_print(), caenV767::do_active_readout, caenV767::half_full_level, handle, odb_get_bool(), odb_get_boolarray(), odb_get_dword(), odb_get_int(), caenV767::odb_name, caenV767::record_trailing_edges, SUCCESS, caenV767::vme_base, caenV767::vme_handle, vme_open(), vme_write_d16(), VMEMAP_ASPACE_A32, VMEMAP_DWIDTH_32, VMEMAP_PRGDATAAM_DATA, and VMEMAP_SUPUSERAM_SUPER.

Referenced by caenV767_bor(), and caenV767_pre_bor().

109 {
110  // Get the VME base address of the module
111  caen->vme_base = odb_get_dword("/Equipment/Crate %d/Settings/%s/vme address",
112  crate_number, caen->odb_name);
113 
114  // Open a VME handle for memory-mapped access
115  struct vme_mapping_ctrl mapping = {
120  };
121 
122  struct vme_handle *handle =
123  vme_open(caen->vme_base, mapping, 0x200, CAENV767_MAX_DMA_SIZE);
124  caen->vme_handle = handle;
125 
126  // Determine whether we're supposed to do active readout
127  caen->do_active_readout =
128  odb_get_bool("/Equipment/Crate %d/Settings/%s/Active Readout mode",
129  crate_number, caen->odb_name);
130 
131  // Determine whether we should record trailing edges, or only leading edges
132  caen->record_trailing_edges =
133  odb_get_bool("/Equipment/Crate %d/Settings/%s/Record trailing edges",
134  crate_number, caen->odb_name);
135 
136  // Request a bus error when DMA transfer reaches end of data
137  vme_write_d16(caen->vme_handle, caen->vme_base | CAENV767_CTR1, 0x0020);
138 
139  // Read the half-full mark and the active readout buffer size
140  caen->half_full_level =
141  odb_get_int("/Equipment/Crate %d/Settings/%s/Half-full level",
142  crate_number, caen->odb_name);
144  odb_get_int("/Equipment/Crate %d/Settings/%s/Active readout buffer size",
145  crate_number, caen->odb_name);
146 
147  // Allocate the active readout buffer
148  caen->active_readout_buffer = new unsigned char[caen->active_readout_buffer_size];
149 
150  // Set various TDC options
151  caenV767_opcode_write(caen, 0x1200); // set start gating mode
152  caenV767_opcode_write(caen, 0x7100); // set DRDY = almost full
153  caenV767_opcode_write(caen, 0x7400); // prepare to set almost full level...
154  caenV767_opcode_write(caen, caen->half_full_level); // ...set almost full level
155  caenV767_opcode_write(caen, 0x4000); // enable readout of start time
156  caenV767_opcode_write(caen, 0x4300); // enable subtraction of start time
157  // from hit times
158 
159  if(caen->record_trailing_edges) {
160  caenV767_opcode_write(caen, 0x6600); // enable both edges on all channels
161  // and start
162  } else {
163  caenV767_opcode_write(caen, 0x6000); // enable only leading edge on all
164  // channels and start
165  }
166 
167  // Enable the CAEN channels according to the ODB settings
168  diag_print(1, "Enabling all channels on %s.\n", caen->odb_name);
169  caenV767_opcode_write(caen, 0x2300); // enable all channels first
170  BOOL channel_enable_array[CAENV767_NUM_CHANNELS], channelstatus;
171  odb_get_boolarray(&channel_enable_array[0], CAENV767_NUM_CHANNELS,
172  "/Equipment/Crate %d/Settings/%s/channels/channel enabled",
173  crate_number, caen->odb_name);
174  // disable each masked channel
175  for (int channel=0; channel<=(CAENV767_NUM_CHANNELS-1); channel++) {
176  channelstatus = channel_enable_array[channel];
177  if (channelstatus == 0) {
178  diag_print(1, "Disabling %s channel %d.\n", caen->odb_name, channel);
179  caenV767_opcode_write(caen, 0x2100 | channel);
180  }
181  }
182 
183  // Reset the TDC
184  vme_write_d16(caen->vme_handle, caen->vme_base | CAENV767_CLEAR, 1);
185 
186  // Clear for the next block
187  caen->active_readout_size = 0;
188 
189  return SUCCESS;
190 }
INT caenV767_eor ( )

Definition at line 244 of file caenV767.cpp.

References caenV767_eor1(), enabled, i, MAX_CAENV767, status, and SUCCESS.

245 {
246 
247  for(int i = 0; i < MAX_CAENV767; i++) {
248  if(caenV767[i].enabled) {
249  int status = caenV767_eor1(&caenV767[i]);
250  if(status != SUCCESS) {
251  return status;
252  }
253  }
254  }
255 
256  return SUCCESS;
257 }
INT caenV767_eor1 ( struct caenV767 caen)

Definition at line 231 of file caenV767.cpp.

References caenV767::active_readout_buffer, SUCCESS, vme_close(), and caenV767::vme_handle.

Referenced by caenV767_eor().

232 {
233  vme_close(caen->vme_handle);
234  delete[] caen->active_readout_buffer;
235  return SUCCESS;
236 }
INT caenV767_fifo_read ( struct caenV767 caen,
unsigned char *  buffer,
int  max_size,
bool  in_active_readout 
)

Definition at line 259 of file caenV767.cpp.

References CAENV767_NOT_VALID, CAENV767_OUTBUF, i, size, status, caenV767::vme_base, vme_dma_read(), caenV767::vme_handle, and vme_read_d32().

Referenced by caenV767_poll1(), and caenV767_read1().

261 {
262  if(!in_active_readout) {
263  int status = vme_dma_read(caen->vme_handle,
264  caen->vme_base | CAENV767_OUTBUF,
265  buffer,
266  max_size);
267  return status;
268  } else {
269  int size = 0;
270 
271  for(int i = 0; i < max_size / sizeof(DWORD); i++) {
272  DWORD word =
274 
275  if((word & CAENV767_NOT_VALID) == CAENV767_NOT_VALID) {
276  break;
277  }
278 
279  *((DWORD *) buffer) = word;
280  buffer += sizeof(DWORD);
281  size += sizeof(DWORD);
282  }
283 
284  return size;
285  }
286 }
short caenV767_opcode_read ( struct caenV767 caen)

Definition at line 88 of file caenV767.cpp.

References CAENV767_OPCODE, CAENV767_OPHAND, caenV767::vme_base, caenV767::vme_handle, and vme_read_d16().

89 {
90  // Wait for the microcontroller to become ready
91  while(!(vme_read_d16(caen->vme_handle, caen->vme_base | CAENV767_OPHAND) &
92  0x1)) {
93  ss_sleep(10);
94  }
95 
96  // Wait a little longer
97  ss_sleep(10);
98 
99  // Read the opcode value
100  return vme_read_d16(caen->vme_handle, caen->vme_base | CAENV767_OPCODE);
101 }
void caenV767_opcode_write ( struct caenV767 caen,
short  code 
)

Definition at line 73 of file caenV767.cpp.

References CAENV767_OPCODE, CAENV767_OPHAND, caenV767::vme_base, caenV767::vme_handle, vme_read_d16(), and vme_write_d16().

Referenced by caenV767_bor1().

74 {
75  // Wait for the microcontroller to become ready
76  while(!(vme_read_d16(caen->vme_handle, caen->vme_base | CAENV767_OPHAND) &
77  0x0002)) {
78  ss_sleep(10);
79  }
80 
81  // Wait a little longer
82  ss_sleep(10);
83 
84  // Write the opcode value
85  vme_write_d16(caen->vme_handle, caen->vme_base | CAENV767_OPCODE, code);
86 }
INT caenV767_poll1 ( struct caenV767 caen)

Definition at line 293 of file caenV767.cpp.

References caenV767::active_readout_buffer, caenV767::active_readout_buffer_size, ACTIVE_READOUT_MAX_PER_POLL, caenV767::active_readout_size, block_start_time, caenV767::bytes_per_second, caenV767_fifo_read(), diag_print(), caenV767::do_active_readout, FE_NEED_STOP, MIN, caenV767::odb_name, size, status, SUCCESS, and TRUE.

Referenced by caenV767_poll_live().

294 {
295  // If active readout is not enabled, skip it.
296  if(!caen->do_active_readout) {
297  return SUCCESS;
298  }
299 
300  // Check whether there's anything at all in the buffer.
301 
302  // How many words do we expect?
303  struct timeval now;
304  gettimeofday(&now, NULL);
305  double block_seconds = (now.tv_sec - block_start_time.tv_sec) +
306  1e-6*(now.tv_usec - block_start_time.tv_usec);
307  int expected_words =
308  (int) (caen->bytes_per_second / block_seconds / sizeof(DWORD));
309 
310  // First check how much space we have available in the active
311  // readout buffer.
312  int size_left = caen->active_readout_buffer_size - caen->active_readout_size;
313  int size = MIN(ACTIVE_READOUT_MAX_PER_POLL, size_left);
314  size = MIN(size, expected_words);
315 
316  // Now try to read up to that amount, without using block transfers,
317  // which can potentially drop the last data word.
318  int status =
319  caenV767_fifo_read(caen,
321  size,
322  TRUE);
323 
324  // Check the status
325  if(status >= 0) {
326  caen->active_readout_size += status;
327  } else {
328  diag_print(0, "Status from caenV767_fifo_read is %d for %s\n", status,
329  caen->odb_name);
330  return FE_ERR_HW;
331  }
332 
334  return FE_NEED_STOP;
335  } else {
336  return SUCCESS;
337  }
338 }
INT caenV767_poll_live ( )

Definition at line 350 of file caenV767.cpp.

References block_start_time, caenV767_poll1(), enabled, i, MAX_CAENV767, status, and SUCCESS.

351 {
352  // If this is our first active readout pass, just remember the time.
353  if(block_start_time.tv_sec == 0 && block_start_time.tv_usec == 0) {
354  return SUCCESS;
355  }
356 
357  for(int i = 0; i < MAX_CAENV767; i++) {
358  if(caenV767[i].enabled) {
359  int status = caenV767_poll1(&caenV767[i]);
360  if(status != SUCCESS) {
361  return status;
362  }
363  }
364  }
365 
366  return SUCCESS;
367 }
INT caenV767_pre_bor ( )

Definition at line 198 of file caenV767.cpp.

References bank_name, caenV767_bor1(), crate_number, diag_print(), enabled, caenV767::enabled, MAX_CAENV767, odb_find_key(), odb_get_bool(), sprintf(), and SUCCESS.

199 {
200  // Use the ODB to find any CAENV767 modules
201  for(int j = 0; j < MAX_CAENV767; j++) {
202 
203  bool enabled = false;
204 
205  if (odb_find_key("/Equipment/Crate %d/Settings/CAEN %d", crate_number, j)) {
206  diag_print(1, "ODB says CAEN %d is present, ", j);
207  enabled =
208  odb_get_bool("/Equipment/Crate %d/Settings/CAEN %d/enabled status",
209  crate_number, j);
210  if (enabled) {
211  diag_print(1, "and is enabled. Initializing...\n");
212  } else {
213  diag_print(1, "but is disabled.\n");
214  }
215  }
216 
217  caenV767[j].enabled = enabled;
218 
219  // Set up the name of the MIDAS bank associated with the module
220  sprintf(caenV767[j].bank_name, "CAE%d", j);
221  sprintf(caenV767[j].odb_name, "CAEN %d", j);
222 
223  if(enabled) {
224  caenV767_bor1(&caenV767[j]);
225  }
226  }
227 
228  return SUCCESS;
229 }
INT caenV767_read ( char *  pevent)

Definition at line 453 of file caenV767.cpp.

References caenV767_read1(), enabled, i, MAX_CAENV767, status, and SUCCESS.

454 {
455  for(int i = 0; i < MAX_CAENV767; i++) {
456  if(caenV767[i].enabled) {
457  int status = caenV767_read1(&caenV767[i], pevent);
458  if(status != SUCCESS) {
459  return status;
460  }
461  }
462  }
463 
464  return SUCCESS;
465 }
INT caenV767_read1 ( struct caenV767 caen,
char *  pevent 
)

Definition at line 374 of file caenV767.cpp.

References caenV767::active_readout_buffer, caenV767::active_readout_size, caenV767::bank_name, block_start_time, caenV767::bytes_per_second, CAENV767_CLEAR, caenV767_fifo_read(), CAENV767_GLOBAL_TDC_ERROR, CAENV767_MAX_SIZE, CAENV767_NOT_VALID, CAENV767_STR2, diag_print(), FALSE, caenV767::odb_name, printf(), status, SUCCESS, caenV767::vme_base, caenV767::vme_handle, vme_read_d16(), and vme_write_d16().

Referenced by caenV767_read().

375 {
376  // Create the MIDAS bank
377  DWORD *pdata;
378  bk_create(pevent, caen->bank_name, TID_DWORD, &pdata);
379 
380  // Copy data that was read during the active readout
381  int active_size = caen->active_readout_size;
382  memcpy(pdata, caen->active_readout_buffer, active_size);
383 
384  // Read any data remaining in the module
385  int status =
386  caenV767_fifo_read(caen, ((unsigned char *) pdata) + active_size,
388 
389  // Check the status
390  int final_size = 0;
391  if(status >= 0) {
392  final_size = status;
393  } else {
394  // handle the error
395  }
396 
397  // Check the TDC status for error codes (typically "DLL unlocked" problems)
398  // and add an error flag word if a problem is found.
399  short str2 = vme_read_d16(caen->vme_handle, caen->vme_base | CAENV767_STR2);
400  if(str2 & CAENV767_GLOBAL_TDC_ERROR) {
401  DWORD flag_word = CAENV767_NOT_VALID;
402  for(int tdc = 0; tdc < 4; tdc++) {
403  short ind_tdc_error_mask = (1 << (12+tdc));
404  if(str2 & (1 << (12+tdc))) {
405  flag_word |= (1 << tdc);
406  }
407  }
408 
409  pdata[(active_size + final_size)/sizeof(DWORD)] = flag_word;
410  final_size += sizeof(DWORD);
411 
412  diag_print(0, "TDC error in %s: 0x%08x\n", caen->odb_name, flag_word);
413  }
414 
415  // Close the bank
416  // Modified by VT on Oct-29-2010
417  //bk_close(pevent, pdata + (active_size + final_size)/sizeof(DWORD));
418  int total_size = active_size + final_size;
419  if ( total_size > 500000 ) {
420  printf("ERROR! Event size is too big (%i). The event will be rejected\n");
421  bk_close(pevent, pdata + 0);
422  } else {
423  bk_close(pevent, pdata + (active_size + final_size)/sizeof(DWORD));
424  }
425 
426 
427 
428  // Clear for the next block
429  caen->active_readout_size = 0;
430 
431  // Reset the TDC
432  vme_write_d16(caen->vme_handle, caen->vme_base | CAENV767_CLEAR, 1);
433 
434  // Update the expected rate.
435  if(block_start_time.tv_sec != 0) {
436  struct timeval now;
437  gettimeofday(&now, NULL);
438  double block_seconds = (now.tv_sec - block_start_time.tv_sec) +
439  1e-6*(now.tv_usec - block_start_time.tv_usec);
440  caen->bytes_per_second = (active_size + final_size)/block_seconds;
441  }
442  block_start_time.tv_sec = block_start_time.tv_usec = 0;
443 
444  return SUCCESS;
445 }

Variable Documentation

struct timeval block_start_time

Definition at line 56 of file caenV767.cpp.

struct readout_module caenV767_module
Initial value:
= {
NULL,
NULL,
NULL,
NULL,
NULL,
NULL,
}

Definition at line 20 of file caenV767.cpp.