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_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_bor().

Function Documentation

INT caenV767_bor ( )

Definition at line 219 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.

220 {
221  // Use the ODB to find any CAENV767 modules
222  for(int j = 0; j < MAX_CAENV767; j++) {
223 
224  bool enabled = false;
225 
226  if (odb_find_key("/Equipment/Crate %d/Settings/CAEN %d", crate_number, j)) {
227  diag_print(1, "ODB says CAEN %d is present, ", j);
228  enabled =
229  odb_get_bool("/Equipment/Crate %d/Settings/CAEN %d/enabled status",
230  crate_number, j);
231  if (enabled) {
232  diag_print(1, "and is enabled. Initializing...\n");
233  } else {
234  diag_print(1, "but is disabled.\n");
235  }
236  }
237 
238  caenV767[j].enabled = enabled;
239 
240  // Set up the name of the MIDAS bank associated with the module
241  sprintf(caenV767[j].bank_name, "CAE%d", j);
242  sprintf(caenV767[j].odb_name, "CAEN %d", j);
243 
244  if(enabled) {
245  caenV767_bor1(&caenV767[j]);
246  }
247  }
248 
249  return SUCCESS;
250 }
INT caenV767_bor1 ( struct caenV767 caen)

Definition at line 128 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.

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

Definition at line 253 of file caenV767.cpp.

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

254 {
255  vme_close(caen->vme_handle);
256  delete[] caen->active_readout_buffer;
257  return SUCCESS;
258 }
INT caenV767_fifo_read ( struct caenV767 caen,
unsigned char *  buffer,
int  max_size,
bool  in_active_readout 
)

Definition at line 283 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().

285 {
286  if(!in_active_readout) {
287  int status = vme_dma_read(caen->vme_handle,
288  caen->vme_base | CAENV767_OUTBUF,
289  buffer,
290  max_size);
291  return status;
292  } else {
293  int size = 0;
294 
295  for(int i = 0; i < max_size / sizeof(DWORD); i++) {
296  DWORD word =
298 
299  if((word & CAENV767_NOT_VALID) == CAENV767_NOT_VALID) {
300  break;
301  }
302 
303  *((DWORD *) buffer) = word;
304  buffer += sizeof(DWORD);
305  size += sizeof(DWORD);
306  }
307 
308  return size;
309  }
310 }
short caenV767_opcode_read ( struct caenV767 caen)

Definition at line 107 of file caenV767.cpp.

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

108 {
109  // Wait for the microcontroller to become ready
110  while(!(vme_read_d16(caen->vme_handle, caen->vme_base | CAENV767_OPHAND) &
111  0x1)) {
112  ss_sleep(10);
113  }
114 
115  // Wait a little longer
116  ss_sleep(10);
117 
118  // Read the opcode value
119  return vme_read_d16(caen->vme_handle, caen->vme_base | CAENV767_OPCODE);
120 }
void caenV767_opcode_write ( struct caenV767 caen,
short  code 
)

Definition at line 91 of file caenV767.cpp.

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

92 {
93  // Wait for the microcontroller to become ready
94  while(!(vme_read_d16(caen->vme_handle, caen->vme_base | CAENV767_OPHAND) &
95  0x0002)) {
96  ss_sleep(10);
97  }
98 
99  // Wait a little longer
100  ss_sleep(10);
101 
102  // Write the opcode value
103  vme_write_d16(caen->vme_handle, caen->vme_base | CAENV767_OPCODE, code);
104 }
INT caenV767_poll1 ( struct caenV767 caen)

Definition at line 318 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.

319 {
320  // If active readout is not enabled, skip it.
321  if(!caen->do_active_readout) {
322  return SUCCESS;
323  }
324 
325  // Check whether there's anything at all in the buffer.
326 
327  // How many words do we expect?
328  struct timeval now;
329  gettimeofday(&now, NULL);
330  double block_seconds = (now.tv_sec - block_start_time.tv_sec) +
331  1e-6*(now.tv_usec - block_start_time.tv_usec);
332  int expected_words =
333  (int) (caen->bytes_per_second / block_seconds / sizeof(DWORD));
334 
335  // First check how much space we have available in the active
336  // readout buffer.
337  int size_left = caen->active_readout_buffer_size - caen->active_readout_size;
338  int size = MIN(ACTIVE_READOUT_MAX_PER_POLL, size_left);
339  size = MIN(size, expected_words);
340 
341  // Now try to read up to that amount, without using block transfers,
342  // which can potentially drop the last data word.
343  int status =
344  caenV767_fifo_read(caen,
346  size,
347  TRUE);
348 
349  // Check the status
350  if(status >= 0) {
351  caen->active_readout_size += status;
352  } else {
353  diag_print(0, "Status from caenV767_fifo_read is %d for %s\n", status,
354  caen->odb_name);
355  return FE_ERR_HW;
356  }
357 
359  return FE_NEED_STOP;
360  } else {
361  return SUCCESS;
362  }
363 }
INT caenV767_poll_live ( )
INT caenV767_read ( char *  pevent)
INT caenV767_read1 ( struct caenV767 caen,
char *  pevent 
)

Definition at line 401 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, status, SUCCESS, caenV767::vme_base, caenV767::vme_handle, vme_read_d16(), and vme_write_d16().

402 {
403  // Create the MIDAS bank
404  DWORD *pdata;
405  bk_create(pevent, caen->bank_name, TID_DWORD, &pdata);
406 
407  // Copy data that was read during the active readout
408  int active_size = caen->active_readout_size;
409  memcpy(pdata, caen->active_readout_buffer, active_size);
410 
411  // Read any data remaining in the module
412  int status =
413  caenV767_fifo_read(caen, ((unsigned char *) pdata) + active_size,
415 
416  // Check the status
417  int final_size = 0;
418  if(status >= 0) {
419  final_size = status;
420  } else {
421  // handle the error
422  }
423 
424  // Check the TDC status for error codes (typically "DLL unlocked" problems)
425  // and add an error flag word if a problem is found.
426  short str2 = vme_read_d16(caen->vme_handle, caen->vme_base | CAENV767_STR2);
427  if(str2 & CAENV767_GLOBAL_TDC_ERROR) {
428  DWORD flag_word = CAENV767_NOT_VALID;
429  for(int tdc = 0; tdc < 4; tdc++) {
430  short ind_tdc_error_mask = (1 << (12+tdc));
431  if(str2 & (1 << (12+tdc))) {
432  flag_word |= (1 << tdc);
433  }
434  }
435 
436  pdata[(active_size + final_size)/sizeof(DWORD)] = flag_word;
437  final_size += sizeof(DWORD);
438 
439  diag_print(0, "TDC error in %s: 0x%08x\n", caen->odb_name, flag_word);
440  }
441 
442  // Close the bank
443  bk_close(pevent, pdata + (active_size + final_size)/sizeof(DWORD));
444 
445  // Clear for the next block
446  caen->active_readout_size = 0;
447 
448  // Reset the TDC
449  vme_write_d16(caen->vme_handle, caen->vme_base | CAENV767_CLEAR, 1);
450 
451  // Update the expected rate.
452  if(block_start_time.tv_sec != 0) {
453  struct timeval now;
454  gettimeofday(&now, NULL);
455  double block_seconds = (now.tv_sec - block_start_time.tv_sec) +
456  1e-6*(now.tv_usec - block_start_time.tv_usec);
457  caen->bytes_per_second = (active_size + final_size)/block_seconds;
458  }
459  block_start_time.tv_sec = block_start_time.tv_usec = 0;
460 
461  return SUCCESS;
462 }

Variable Documentation

struct timeval block_start_time

Definition at line 53 of file caenV767.cpp.

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.