Low-Energy Muon (LEM) Experiment  0.5.1
vme_fe.c
Go to the documentation of this file.
1 /********************************************************************\
2 
3  Name: vme_fe.c
4  Created by: Thomas Prokscha 21-Sep-2005, PSI
5  22-Jan-2010, PSI
6 
7  Copyright (c) 2009 by Paul Scherrer Institut, 5232 Villigen PSI, Switzerland
8 
9  Contents: Midas frontend for periodic readout of the
10  Struck SIS3820 VME multiscaler and test
11  readout of a CAEN V1190B 64-channel multihit
12  TDC.
13  It uses the sis3820.c library which communicates with the VME
14  module using a SIS3100/1100 VME-PCI interface.
15 
16  January 2010: extend to 64 channels to cope with new APD spectrometer.
17  Add red/green mode.
18 
19  For the V1190 readout:
20  -----------------------
21  ch 00 empty (Ip in scaler)
22  #define CLOCK 1 (10kHz)
23  #define MCP1 2
24  #define TD 4
25  #define BCL1 5
26  #define BCL2 6
27  #define BCL3 7
28  #define BCL4 8
29  #define BCR1 9
30  #define BCR2 10
31  #define BCR3 11
32  #define BCR4 12
33  #define POSMCP1I 13
34  #define POSMCP1O 14
35 
36  #define POSLDI 16
37  #define POSLDO 17
38  #define POSLUI 18
39  #define POSLUO 19
40 
41  #define POSBDI 20
42  #define POSBDO 21
43  #define POSBUI 22
44  #define POSBUO 23
45 
46  #define POSRDI 24
47  #define POSRDO 25
48  #define POSRUI 26
49  #define POSRUO 27
50 
51  #define POSTDI 28
52  #define POSTDO 29
53  #define POSTUI 30
54  #define POSTUO 31
55 
56  // for "red/green mode"
57  #define EXTON1 32
58  #define EXTOFF1 33
59 
60  #define MCP2F 34 MCP2-T1(Front MCP signal)
61  #define MCP2R 35 MCP2-T2(Rear MCP signal)
62  #define MCP2X1 36 MCP2-T3(X1)
63  #define MCP2X2 37 MCP2-T4(X2)
64  #define MCP2Y1 38 MCP2-T5(Y1)
65  #define MCP2Y2 39 MCP2-T6(Y2)
66 
67  - read TDC in frontend_loop(), scan TDC output buffer for
68  possible events; call evaluate_event() if a candidate for a "good"
69  event is found
70  - build events in evaluate_event(), put data into a ring buffer
71  - poll on read/write pointer position in ring buffer; if positions
72  are different read data from ring buffer, else do nothing
73  - 0.2ns resolution
74  - set ALM_FULL bit to 1024 (register 0x1022)
75  - check if ALM_FULL bit is set (0x2) (register 0x1002)
76  - if yes read the TDC output buffer completely in BLT32 mode, if not skip
77  - after read check if ALM_FULL bit is still set: if yes
78  - repeat read, if not, return
79  - three event types: Ev0 (BC)-MCP1-(e+MCP1)
80  Ev1 (BC)-TD-MCP2-(e+)
81  Ev2 (BC)-TD-e+ (LE-muSR setup)
82  For all event types the e+ are now always active in TDC
83  whereas the BC is only active in TDC if it is required
84  in the trigger condition
85  ( trigger_settings.event_(0,1,2)_settings.beamcounter_active = true)
86 
87  - if one adds a 1MHz clock one has to poll in order to
88  get all events, but >80% CPU load, about 0.5% loss of data;
89  -- reading periodically every millisec leads to a BUFFER FULL at TDC
90  -- poll and ss_sleep(1ms): about 1% data loss due to output buffer full,
91  low CPU load
92  - 200kHz can be read periodically with 1ms period
93 
94  - For time-of-flight (TOF) measurements with the beam counter (BC) we have the problem
95  that in a sequence of BC-MCP1/2/TD-e+ the "master" detector is after the BC and before the positrons.
96  The easiest way to solve the problem of finding all correlated events in the software trigger is to
97  have all signals a f t e r the master. This means that BC has to be delayed. This will be implemented
98  after version 1718 from 14-Mar-2006, 15:37. As an example, let's have a look on BC-MCP1:
99  -- all the pileup checking is done with the original TDC times
100  -- to get a BC-MCP1 "trigger" (a valid TOF within the TOF gate):
101  in original timing the corresponding detector flags are set if we have "clean" (no pre-pileup)
102  signals. If the detector pattern requested by the Event definition is found start to "evaluate"
103  the event, i.e. check if the timing between detector hits is ok. For this we will use the modified
104  times
105  t_BC --> t'_BC = t_BC + trigger_settings.tof_bc_window (delay BC time by TOF window length)
106  t_MCP1 --> t'_MCP1 = t_MCP1 + trigger_settings.event_0_settings.mcp1_delay
107  In evaluate_fast_muon() search the first t'_BC hit after t'_MCP1 which falls within the TOF window
108  If this is a "clean" we have an event;
109  to be continued...
110  - further improvement to avoid losses of BC events:
111  -- do not use time exceeding anymore; an event gets evaluated after the first "clean" (no pre-pileup)
112  master detector (MCP1 or TD or MCP2) is found, and if additional event-specific detector hits are
113  registered; in this case the event evaluation starts at the earliest at t = t_Master + t_dataWindow.
114  -- keep reverse timing for BC
115 
116  - 26-Apr-2006: add new banks for saving selected slow control ODB structure in DATA file
117  introduce new Event type "3" = "SlowControl";
118  create ODB hot-links to selected ODB structures, and write corresponding ODB
119  values periodically every 60sec to MIDAS banks.
120 
121 
122 \********************************************************************/
123 
124 #include <stdio.h>
125 #include <stdlib.h>
126 #include <errno.h>
127 #include <string.h>
128 #include <sys/types.h>
129 #include <unistd.h>
130 #include <fcntl.h>
131 #include <sys/mman.h>
132 #include <sys/ioctl.h>
133 #include <sys/time.h>
134 #include <math.h>
135 
136 //from /lib/modules/<KernelVersion>/build/include/linux
137 #include <include/linux/version.h>
138 
139 #include "midas.h"
140 #include "mcstd.h"
141 
142 #include "sis3820.h"
143 #include "v1190.h"
144 
146 #include "experim.h"
147 
149 #include "nemu_experim.h"
150 
151 /* make frontend functions callable from the C framework */
152 #ifdef __cplusplus
153 extern "C" {
154 #endif
155 
156 /*------------------------- Globals --------------------------------*/
157 
159 char *frontend_name = "VME_FE";
160 
162 char *frontend_file_name = __FILE__;
163 
165 BOOL frontend_call_loop = TRUE;
166 
168 INT display_period = 3000;
169 
171 INT max_event_size = 128000;
172 
174 INT max_event_size_frag = 5*1024*1024;
175 
177 INT event_buffer_size = 60*10000;
178 
179 /* ---------------- ODB structures ---------------------------*/
187 //EXP_PARAM exp_param; //!< /Experiment/Run parameters
190 RUNINFO runinfo;
194 
204 //as35 OVEN_EVENT oven_event;
207 /*HV_VACCLEANER hv_vaccleaner; //!< ODB key which contains information about pulsing of RA segments*/
208 
210 #define SIS3820_ADDRESS_0 0x38000000
211 #define SIS3820_ADDRESS_1 0x39000000
212 #define V1190_ADDRESS 0xEE000000
213 #define MAX_NUMBER_LWORDS 1024
214 #define ALMOST_FULL_LEVEL 1024
215 #define DATABUFFER_SIZE 131072
216 #define DIFF_TOLERANCE -12200
217 #define TD_EVENT (1<<0)
220 #define LE_POSITRON_EVENT (1<<1)
221 #define M2_EVENT (1<<2)
222 #define BC_EVENT (1<<3)
223 #define M1_EVENT (1<<4)
224 #define M1_POSITRON_EVENT (1<<5)
225 
227 #define MASTERLAST 1
228 #define MASTERFIRST 2
229 
230 typedef struct {
242  INT tdc_data[N_TDC_CHANNELS*DATA_N_HITS];
243  INT set_t0;
245  INT foundChannel[N_TDC_CHANNELS];
246  INT tdc_event[N_TDC_CHANNELS][N_HITS];
247  INT pileup[N_TDC_CHANNELS][N_HITS];
249  INT indexFastMuon, indexFastMuonSet;
250  INT indexSlowMuon, indexSlowMuonSet;
251  DWORD thisTimeSlowMuon, thisTimeFastMuon, lastTimeSlowMuon, lastTimeFastMuon;
256 
257 typedef struct{
264 } TDC_PILEUP;
265 
269 static INT hdev;
270 static DWORD *databuffer;
271 static DWORD *p_read, *p_write;
272 static DWORD masterFlagSlowMuon;
273 static DWORD eventDefinedSlowMuon;
274 static DWORD eventDefinedFastMuon;
275 static DWORD masterChannelSlowMuon;
276 static DWORD masterChannelFastMuon;
277 static U_LONG runTime;
280 static INT t0_offset;
281 static BOOL flag_external_on;
283 INT mode;
284 static struct timeval tvLastTime;
285 static BOOL flag_on_puls;
286 // static float ra_hv_1, ra_hv_2;
287 // static BOOL vacuum_cleaner_active;
288 // static DWORD lasttime;
289 
290 /*-- Function declarations -----------------------------------------*/
291 INT frontend_init();
292 INT frontend_exit();
293 INT begin_of_run(INT run_number, char *error);
294 INT end_of_run(INT run_number, char *error);
295 INT pause_run(INT run_number, char *error);
296 INT resume_run(INT run_number, char *error);
297 INT frontend_loop();
298 INT read_trigger_event(char *pevent, INT off);
299 INT poll_event(INT source, INT count, BOOL test);
300 INT read_scaler_event(char *pevent, INT off);
301 INT read_slowcontrol_event(char *pevent, INT off);
302 INT do_channel(INT ch, INT time);
303 INT do_master_channel(INT ch, INT event_type);
304 U_LONG pileup_end(INT pileupWindow);
307 BOOL check_tof_and_pileup(INT timing, INT tofWindow, INT firstCh, INT lastCh, INT masterChannel, INT masterIndex,
308  INT *channel, INT *ind);
309 BOOL check_positron(INT decWindow, INT coincWindow, INT firstCh, INT lastCh, INT masterChannel, INT masterIndex,
310  INT *channel, INT *ind);
311 
312 void scaler_mode(u_int32_t module_address);
313 int init_sis3820(u_int32_t module_address);
314 int init_v1190(u_int32_t module_address);
315 void OnOff_mode();
316 /*void vacuum_cleaner();*/
317 
318 //#define TESTOUT
319 #ifdef TESTOUT
320 FILE *fp;
321 #endif
322 
323 /*-- Equipment list ------------------------------------------------*/
324 #undef USE_INT
325 
326 EQUIPMENT equipment[] = {
327 
328  { "Trigger", /* equipment name */
329  { 1, 0, /* event ID, trigger mask */
330  "SYSTEM", /* event buffer */
331  EQ_POLLED, /* equipment type */
332  LAM_SOURCE(0,0xFFFFFF),/* event source crate 0, all stations */
333  "MIDAS", /* format */
334  TRUE, /* enabled */
335  RO_RUNNING | RO_ODB, /* read only when running */
336  100, /* poll 100ms */
337  0, /* stop run after this event limit */
338  0, /* number of sub events */
339  0, /* don't log history */
340  "", "", "",},
341  read_trigger_event, /* readout routine */
342  },
343 
344  { "Scaler", /* equipment name */
345  { 2, 0, /* event ID, trigger mask */
346  "SYSTEM", /* event buffer */
347  EQ_PERIODIC, /* equipment type, MAN trigger disabled */
348  0, /* event source */
349  "MIDAS", /* format */
350  TRUE, /* enabled */
351  RO_ALWAYS |
352  RO_TRANSITIONS | /* read when running and on transitions */
353  RO_ODB, /* and update ODB */
354  3000, /* read every 3 sec */
355  0, /* stop run after this event limit */
356  0, /* number of sub events */
357  0, /* log history */
358  "", "", "",},
359  read_scaler_event, /* readout routine */
360  },
361 
362  { "SlowControl", /* equipment name */
363  { 3, 0, /* event ID, trigger mask */
364  "SYSTEM", /* event buffer */
365  EQ_PERIODIC, /* equipment type, MAN trigger disabled */
366  0, /* event source */
367  "MIDAS", /* format */
368  TRUE, /* enabled */
369  RO_RUNNING |
370  RO_TRANSITIONS | /* read when running and on transitions */
371  RO_ODB, /* and update ODB */
372  30000, /* read every 30 sec */
373  0, /* stop run after this event limit */
374  0, /* number of sub events */
375  0, /* log history */
376  "", "", "",},
377  read_slowcontrol_event, /* readout routine */
378  },
379 
380 
381  { "" }
382 };
383 
384 #ifdef __cplusplus
385 }
386 #endif
387 
388 /********************************************************************\
389  Callback routines for system transitions
390 
391  These routines are called whenever a system transition like start/
392  stop of a run occurs. The routines are called on the following
393  occations:
394 
395  frontend_init: When the frontend program is started. This routine
396  should initialize the hardware.
397 
398  frontend_exit: When the frontend program is shut down. Can be used
399  to releas any locked resources like memory, commu-
400  nications ports etc.
401 
402  begin_of_run: When a new run is started. Clear scalers, open
403  rungates, etc.
404 
405  end_of_run: Called on a request to stop a run. Can send
406  end-of-run event and close run gates.
407 
408  pause_run: When a run is paused. Should disable trigger events.
409 
410  resume_run: When a run is resumed. Should enable trigger events.
411 
412 \********************************************************************/
413 
414 /*-- Frontend Init -------------------------------------------------*/
415 
417 {
418  HNDLE hDB, hkey;
419  char vme_device[32];
420  EXP_PARAM_STR(exp_param_str);
421  TRIGGER_SETTINGS_STR(trigger_settings_str);
422  SCALER_SETTINGS_STR(scaler_settings_str);
423  VME_STATS_STR(vme_stats_str);
424  BEAMLINE_SETTINGS_STR(beamline_settings_str);
425  BEAMLINE_EVENT_STR(beamline_event_str);
426  LEMVAC_SETTINGS_STR(lemvac_settings_str);
427  LEMVAC_EVENT_STR(lemvac_event_str);
428  MODCRYO_SETTINGS_STR(modcryo_settings_str);
429  MODCRYO_EVENT_STR(modcryo_event_str);
430  SAMPLECRYO_SETTINGS_STR(samplecryo_settings_str);
431  SAMPLECRYO_EVENT_STR(samplecryo_event_str);
432  SCS2001M_SETTINGS_STR(scs2001m_settings_str);
433  SCS2001M_EVENT_STR(scs2001m_event_str);
434  HV_SETTINGS_STR(hv_settings_str);
435  HV_EVENT_STR(hv_event_str);
436  HV_DETECTORS_SETTINGS_STR(hv_detectors_settings_str);
437  HV_DETECTORS_EVENT_STR(hv_detectors_event_str);
438 // HV_VACCLEANER_STR(hv_vaccleaner_str);
439  // ------------------------ ODB ------------------------------------------
440  //
441  // open (or create, if not exist) ODB structures;
442  //
443  cm_get_experiment_database(&hDB, NULL);
444 
445  db_create_record(hDB, 0, "/Experiment/Run Parameters", strcomb(exp_param_str));
446  db_create_record(hDB, 0, "/Equipment/Trigger/Settings", strcomb(trigger_settings_str));
447  db_create_record(hDB, 0, "/Equipment/Scaler/Settings", strcomb(scaler_settings_str));
448  db_create_record(hDB, 0, "/Equipment/Trigger/Vme_Statistics", strcomb(vme_stats_str));
449  db_create_record(hDB, 0, "/Equipment/Beamline/Settings", strcomb(beamline_settings_str));
450  db_create_record(hDB, 0, "/Equipment/Beamline/Variables", strcomb(beamline_event_str));
451  db_create_record(hDB, 0, "/Equipment/LEMVAC/Settings", strcomb(lemvac_settings_str));
452  db_create_record(hDB, 0, "/Equipment/LEMVAC/Variables", strcomb(lemvac_event_str));
453  db_create_record(hDB, 0, "/Equipment/ModCryo/Settings", strcomb(modcryo_settings_str));
454  db_create_record(hDB, 0, "/Equipment/ModCryo/Variables", strcomb(modcryo_event_str));
455  db_create_record(hDB, 0, "/Equipment/SampleCryo/Settings", strcomb(samplecryo_settings_str));
456  db_create_record(hDB, 0, "/Equipment/SampleCryo/Variables", strcomb(samplecryo_event_str));
457  db_create_record(hDB, 0, "/Equipment/SCS2001M/Settings", strcomb(scs2001m_settings_str));
458  db_create_record(hDB, 0, "/Equipment/SCS2001M/Variables", strcomb(scs2001m_event_str));
459  db_create_record(hDB, 0, "/Equipment/HV/Settings", strcomb(hv_settings_str));
460  db_create_record(hDB, 0, "/Equipment/HV/Variables", strcomb(hv_event_str));
461  db_create_record(hDB, 0, "/Equipment/HV Detectors/Settings", strcomb(hv_detectors_settings_str));
462  db_create_record(hDB, 0, "/Equipment/HV Detectors/Variables", strcomb(hv_detectors_event_str));
463 // db_create_record(hDB, 0, "/VacuumCleaner", strcomb(hv_vaccleaner_str));
464 
466  if ( db_find_key(hDB, 0, "/Equipment/Trigger/Settings", &hkey))
467  db_open_record(hDB, hkey, &trigger_settings, sizeof(trigger_settings), MODE_READ, NULL, NULL);
468 
469  if ( db_find_key(hDB, 0, "/Equipment/Trigger/Vme_Statistics", &hkey))
470  db_open_record(hDB, hkey, &vme_stats, sizeof(vme_stats), MODE_WRITE, NULL, NULL);
471 
472  if ( db_find_key(hDB, 0, "/Runinfo", &hkey))
473  db_open_record(hDB, hkey, &runinfo, sizeof(runinfo), MODE_READ, NULL, NULL);
474 
475 /* if (db_find_key(hDB, 0, "/VacuumCleaner", &hkey))
476  db_open_record(hDB, hkey, &hv_vaccleaner, sizeof(hv_vaccleaner), MODE_READ, NULL, NULL);*/
477 
478  if (db_find_key(hDB, 0, "/Info", &hkey))
479  db_open_record(hDB, hkey, &info, sizeof(info), MODE_READ, NULL, NULL);
480 
482  if ( db_find_key(hDB, 0, "/Equipment/Beamline/Variables", &hkey))
483  db_open_record(hDB, hkey, &beamline_event, sizeof(beamline_event), MODE_READ, NULL, NULL);
484  if ( db_find_key(hDB, 0, "/Equipment/LEMVAC/Variables", &hkey))
485  db_open_record(hDB, hkey, &lemvac_event, sizeof(lemvac_event), MODE_READ, NULL, NULL);
486  if ( db_find_key(hDB, 0, "/Equipment/ModCryo/Variables", &hkey))
487  db_open_record(hDB, hkey, &moddy_event, sizeof(moddy_event), MODE_READ, NULL, NULL);
488  if ( db_find_key(hDB, 0, "/Equipment/SampleCryo/Variables", &hkey))
489  db_open_record(hDB, hkey, &sample_event, sizeof(sample_event), MODE_READ, NULL, NULL);
490 /*//as35 -- I think this is obsolate since we are likely never to use the Oven LS340/Thermocouple anymore
491  if ( db_find_key(hDB, 0, "/Equipment/Oven/Variables", &hkey))
492  db_open_record(hDB, hkey, &oven_event, sizeof(oven_event), MODE_READ, NULL, NULL);
493 */
494  if ( db_find_key(hDB, 0, "/Equipment/Omega/Variables", &hkey))
495  db_open_record(hDB, hkey, &omega_event, sizeof(omega_event), MODE_READ, NULL, NULL);
496  if ( db_find_key(hDB, 0, "/Equipment/SCS2001M/Variables", &hkey))
497  db_open_record(hDB, hkey, &scs2001m_event, sizeof(scs2001m_event), MODE_READ, NULL, NULL);
498  if ( db_find_key(hDB, 0, "/Equipment/HV/Variables", &hkey))
499  db_open_record(hDB, hkey, &hv_event, sizeof(hv_event), MODE_READ, NULL, NULL);
500  if ( db_find_key(hDB, 0, "/Equipment/HV Detectors/Variables", &hkey))
501  db_open_record(hDB, hkey, &hvdet_event, sizeof(hvdet_event), MODE_READ, NULL, NULL);
502  memset(&vme_stats, 0x00, sizeof(vme_stats));
503  memset(&tdc_eval_event, 0x00, sizeof(tdc_eval_event));
504  memset(&tdc_pileup, 0x00, sizeof(tdc_pileup));
505  databuffer = malloc(DATABUFFER_SIZE * sizeof(DWORD));//allocate memory for data buffer
506  p_read = &databuffer[0];
507  p_write = &databuffer[0];
508  eventDefinedSlowMuon = 0xffff;
509  eventDefinedFastMuon = 0xffff;
510  flag_external_on = FALSE;
511  flag_scaler_address_0 = TRUE;
512  flag_scaler_address_1 = TRUE;
513  flag_on_puls = FALSE;
514 
515  /*--- VME initialization ---*/
516 #ifdef HAVE_TEST_RUN
517  hdev = 0;
518 #else
519  cm_msg(MINFO, "frontend_init","LINUX_VERSION = 0x%x",LINUX_VERSION_CODE);
520  cm_yield(0);
521  if ( LINUX_VERSION_CODE < 0x20600 ) // for sis1100 drivers < V2, Linux kernel 2.4
522  sprintf(vme_device, "/dev/sis1100");
523  else // for sis1100 driver V2.02, Linux kernel 2.6.9, V2.04 for kernel 2.6.18
524  sprintf(vme_device, "/dev/sis1100_00remote");
525 
526  if ( ( hdev = open(vme_device, O_RDWR, 0)) < 0 )
527  {
528  cm_msg(MERROR, "frontend_init", "Error on opening VME device %s", vme_device);
529  cm_yield(0);
530  return FE_ERR_HW;
531  }
532 #endif
533 
534  //SIS3820 scaler initialization
535  if ( init_sis3820(SIS3820_ADDRESS_0) == FE_ERR_HW)
536  flag_scaler_address_0 = FALSE;
537 
538  if ( init_sis3820(SIS3820_ADDRESS_1) == FE_ERR_HW)
539  flag_scaler_address_1 = FALSE;
540 
541  cm_msg(MINFO,"frontend_init","scaler flags, address 0x%8.8x = %d, 0x%8.8x = %d",
543  cm_yield(0);
544 
545  // V1190 TDC initialisation
546  if ( init_v1190(V1190_ADDRESS) == FE_ERR_HW)
547  return FE_ERR_HW;
548 
549  gettimeofday(&tvLastTime, 0);
550 // lasttime = ss_millitime();
551 /* vacuum_cleaner_active = FALSE;*/
552  return SUCCESS;
553 }
554 
555 /*-- Frontend Exit -------------------------------------------------*/
556 
558 {
559  int status;
560 
561  /* reset SIS3820 */
562  if ( flag_scaler_address_0){
564  if ( status !=0){
565  cm_msg(MERROR, "frontend_exit",
566  "Error on access to SIS3820_0, key reset failed, return code %x\n", status);
567  cm_yield(0);
568  }
569  }
570  if ( flag_scaler_address_1){
572  if ( status !=0){
573  cm_msg(MERROR, "frontend_exit",
574  "Error on access to SIS3820_1, key reset failed, return code %x\n", status);
575  cm_yield(0);
576  }
577  }
578  /* close VME device */
579  if ( hdev >= 0 )
580  close (hdev);
581 
582  free (databuffer);
583 
584  return SUCCESS;
585 }
586 
587 /*-- Begin of Run --------------------------------------------------*/
588 
589 INT begin_of_run(INT run_number, char *error)
590 {
591  int status, i;
592  WORD ch_pattern[4];
593  DWORD pattern_1stChip, pattern_2ndChip;
594 
595  // ------------------------------------------------------------
596  // on TDC enable active channels according to event definition in ODB
597  //
598  memset(&ch_pattern, 0x00, sizeof(ch_pattern));
599  pattern_1stChip = pattern_2ndChip = 0;
600 
601  for (i = 0; i<N_TDC_CHANNELS; i++){
602  switch (i){
603  case CLOCK:
604  if (i < 32)
605  pattern_1stChip = pattern_1stChip | (1<<i); //clock always enabled
606  else
607  pattern_2ndChip = pattern_2ndChip | (1<<(i%32));
608  break;
609 
610  case EXTON1: case EXTOFF1:
611  if ( !trigger_settings.enable_onoff_mode) break; //continue if not enabled
612  if (i < 32)
613  pattern_1stChip = pattern_1stChip | (1<<i);
614  else
615  pattern_2ndChip = pattern_2ndChip | (1<<(i%32));
616  break;
617 
618  case MCP1: case POSMCP1I: case POSMCP1O:
620  if (i < 32)
621  pattern_1stChip = pattern_1stChip | (1<<i);
622  else
623  pattern_2ndChip = pattern_2ndChip | (1<<(i%32));
624  break;
625 
626  case BCL1: case BCL2: case BCL3: case BCL4:
627  case BCR1: case BCR2: case BCR3: case BCR4:
631  if (i < 32)
632  pattern_1stChip = pattern_1stChip | (1<<i);
633  else
634  pattern_2ndChip = pattern_2ndChip | (1<<(i%32));
635  }
636  break;
637 
638  case TD:
639  case POSLDI: case POSLDO: case POSLUI: case POSLUO:
640  case POSTDI: case POSTDO: case POSTUI: case POSTUO:
641  case POSRDI: case POSRDO: case POSRUI: case POSRUO:
642  case POSBDI: case POSBDO: case POSBUI: case POSBUO:
645  if (i < 32)
646  pattern_1stChip = pattern_1stChip | (1<<i);
647  else
648  pattern_2ndChip = pattern_2ndChip | (1<<(i%32));
649  }
650  break;
651 
652  case MCP2F: case MCP2R:
653  case MCP2X1: case MCP2X2: case MCP2Y1: case MCP2Y2:
655  if (i < 32)
656  pattern_1stChip = pattern_1stChip | (1<<i);
657  else
658  pattern_2ndChip = pattern_2ndChip | (1<<(i%32));
659 
660  break;
661 
662  default:
663  break;
664  }
665  }
666 
667  cm_msg(MINFO,"begin_of_run","pattern_1stChip = 0x%08x", pattern_1stChip);
668  cm_msg(MINFO,"begin_of_run","pattern_2ndChip = 0x%08x", pattern_2ndChip);
669  cm_yield(0);
670  ch_pattern[0] = pattern_1stChip & 0xFFFF;
671  ch_pattern[1] = (pattern_1stChip & 0xFFFF0000)>>16;
672  ch_pattern[2] = pattern_2ndChip & 0xFFFF;
673  ch_pattern[3] = (pattern_2ndChip & 0xFFFF0000)>>16;
674 
675 #ifndef HAVE_TEST_RUN
676  status = vme_A32D16_write(hdev, V1190_ADDRESS+V1190_OPCODE_ADDRESS, 0x4600); // pattern for 1st TDC chip
677  for ( i = 0; i<2; i++){
678  ss_sleep(20);
679  status = vme_A32D16_write(hdev, V1190_ADDRESS+V1190_OPCODE_ADDRESS, ch_pattern[i]);
680  cm_msg(MINFO, "begin_of_run", "V1190 1st Chip channel pattern: pattern = 0x%04x", ch_pattern[i]);
681  cm_yield(0);
682  }
683  if ( status != 0 ){
684  cm_msg(MERROR, "begin_of_run", "Error writing channel pattern to TDC V1190, return code %x\n", status);
685  cm_yield(0);
686  return FE_ERR_HW;
687  }
688 
689  ss_sleep(50);
690  status = vme_A32D16_write(hdev, V1190_ADDRESS+V1190_OPCODE_ADDRESS, 0x4601); // pattern for 2nd TDC chip
691  for ( i = 2; i<4; i++){
692  ss_sleep(20);
693  status = vme_A32D16_write(hdev, V1190_ADDRESS+V1190_OPCODE_ADDRESS, ch_pattern[i]);
694  cm_msg(MINFO, "begin_of_run", "V1190 2nd Chip channel pattern: pattern = 0x%04x", ch_pattern[i]);
695  cm_yield(0);
696  }
697  if ( status != 0 ){
698  cm_msg(MERROR, "begin_of_run", "Error writing channel pattern to TDC V1190, return code %x\n", status);
699  cm_yield(0);
700  return FE_ERR_HW;
701  }
702 
703  ss_sleep(20);
704 
705  // -----------------------------------------------------------------------
706  // clear TDC
707  //
708  status = vme_A32D16_write(hdev, V1190_ADDRESS+V1190_SOFTWARE_CLEAR, 0x0);
709  if ( status !=0){
710  cm_msg(MERROR, "begin_of_run",
711  "Error on resetting TDC V1190, return code %x\n", status);
712  cm_yield(0);
713  return FE_ERR_HW;
714  }
715 #endif
716  // -----------------------------------------------------------------------
717  // reset 1st Scaler module SIS3820_0
718  //
719  // disable SIS3820
720  if ( flag_scaler_address_0){
722  if ( status !=0){
723  cm_msg(MERROR, "begin_of_run",
724  "Error on access to SIS3820_0, key disable failed, return code %x\n", status);
725  cm_yield(0);
726  return FE_ERR_HW;
727  }
728  // reset SIS3820
730  if ( status !=0){
731  cm_msg(MERROR, "begin_of_run",
732  "Error on access to SIS3820_0, key reset failed, return code %x\n", status);
733  cm_yield(0);
734  return FE_ERR_HW;
735  }
736  // check/change scaler mode
738  // enable SIS3820
740  if ( status !=0){
741  cm_msg(MERROR, "begin_of_run",
742  "Error on access to SIS3820_0, key enable failed, return code %x\n", status);
743  cm_yield(0);
744  return FE_ERR_HW;
745  }
746  }
747  // -----------------------------------------------------------------------
748  // reset 2nd Scaler module SIS3820_1
749  //
750  // disable SIS3820
751  if ( flag_scaler_address_1){
753  if ( status !=0){
754  cm_msg(MERROR, "begin_of_run",
755  "Error on access to SIS3820_1, key disable failed, return code %x\n", status);
756  cm_yield(0);
757  return FE_ERR_HW;
758  }
759  // reset SIS3820
761  if ( status !=0){
762  cm_msg(MERROR, "begin_of_run",
763  "Error on access to SIS3820_1, key reset failed, return code %x\n", status);
764  cm_yield(0);
765  return FE_ERR_HW;
766  }
767  // check/change scaler mode
769  // enable SIS3820
771  if ( status !=0){
772  cm_msg(MERROR, "begin_of_run",
773  "Error on access to SIS3820_1, key enable failed, return code %x\n", status);
774  cm_yield(0);
775  return FE_ERR_HW;
776  }
777  }
778 
779  // event definition
780  eventDefinedSlowMuon = 0x8000;
781  eventDefinedFastMuon = 0x8000;
785  flag_external_on = FALSE;
786  flag_on_puls = FALSE;
787 
788  if ( trigger_settings.events.event_0_active ){ // "fast" muons on MCP1
793 
796  }
797 
798  if ( trigger_settings.events.event_1_active){ // "slow" muons on TD/MCP2/Sample
802  else
804 
807 
810 
813 
817  }
818  else{
821  }
822  }
830  }
831 
832  cm_msg(MINFO,"begin_of_run","Fast Muon event_defined = 0x%04x, master channel fast muon= %d",
834  cm_yield(0);
835  cm_msg(MINFO,"begin_of_run","Slow Muon event_defined = 0x%04x, master channel slow muon= %d",
837  cm_yield(0);
838 
839  // reset array and pointers
840  memset(&vme_stats, 0x00, sizeof(vme_stats));
841  memset(&tdc_eval_event, 0x00, sizeof(tdc_eval_event));
842  memset(&tdc_pileup, 0x00, sizeof(tdc_pileup));
843  memset(databuffer, 0x00, sizeof(databuffer));
844  p_read = &databuffer[0]; // set read data pointer to beginning of data buffer
845  p_write = &databuffer[0]; // set write data pointer to beginning of data buffer
846  runTime = t0_offset;
847  nextGoodTime = 0;
848  vme_stats.last_TDCtime = -1; //signal that last_TDCime has not been set
849 #ifdef TESTOUT
850  fp = fopen( "/data/nemu/fe.log", "w");
851  if ( fp == NULL ) return FE_ERR_HW;
852 #endif
853  return SUCCESS;
854 }
855 
856 /*-- End of Run ----------------------------------------------------*/
857 
858 INT end_of_run(INT run_number, char *error)
859 {
860  INT return_code;
861 
862  /* disable all channels if set in ODB */
864  return_code = vme_A32D16_write(hdev, V1190_ADDRESS+V1190_OPCODE_ADDRESS, V1190_DISABLE_ALL_CHANNEL);
865  cm_msg(MINFO, "end_of_run", "V1190 Disabled all channels: return_code = 0x%08x", return_code);
866  cm_yield(0);
867  }
868 
869  cm_msg(MINFO, "end_of_run","total number of written slow muon events = %15.0f", vme_stats.slowMuonEvents);
870  cm_msg(MINFO, "end_of_run","total number of written fast muon events = %15.0f", vme_stats.fastMuonEvents);
871  cm_msg(MINFO, "end_of_run","total number of read events = %15.0f", vme_stats.readcounts);
872  cm_msg(MINFO, "end_of_run","TDC error counts = %15.0f", vme_stats.tdc_error_counts);
873  cm_msg(MINFO, "end_of_run","p_read = 0x%x, p_write = 0x%x", p_read, p_write);
874  cm_msg(MINFO, "end_of_run","total Run time in TDC bins (double) = %18.0f", vme_stats.run_time);
875  cm_msg(MINFO, "end_of_run","total Run time 10kHz clock = %18.5f", vme_stats.channelCounts[1]/10000.);
876  cm_yield(0);
877 #ifdef TESTOUT
878  fclose(fp);
879 #endif
880 
881  return SUCCESS;
882 }
883 
884 /*-- Pause Run -----------------------------------------------------*/
885 
886 INT pause_run(INT run_number, char *error)
887 {
888  return SUCCESS;
889 }
890 
891 /*-- Resume Run ----------------------------------------------------*/
892 
893 INT resume_run(INT run_number, char *error)
894 {
895  int status;
896 
897  // clear TDC
898  status = vme_A32D16_write(hdev, V1190_ADDRESS+V1190_SOFTWARE_CLEAR, 0x0);
899  if ( status !=0){
900  cm_msg(MERROR, "resume_run",
901  "Error on resetting TDC V1190, return code %x\n", status);
902  cm_yield(0);
903  return FE_ERR_HW;
904  }
905 
906  if ( flag_scaler_address_0){
910  }
911  if ( flag_scaler_address_1){
915  }
916  return SUCCESS;
917 }
918 
919 /*-- Frontend Loop -------------------------------------------------*/
920 
950 {
951  /* if frontend_call_loop is true, this routine gets called when
952  the frontend is idle or once between every event */
953  u_int16_t data;
954  u_int32_t blt_data[MAX_NUMBER_LWORDS] ;
955  u_int32_t *output_buffer; //[V1190_OUTPUT_BUFFER_SIZE];
956  u_int32_t get_lwords, sum_lwords;
957  INT return_code;
958  INT loop_counter, i, j, k;
959  INT tdc_time, channel, diffTimeSlowMuon, diffTimeFastMuon;
960  V1190_DATA *v1190_data;
961 
962  //-----------------------------------------------------------------------------------
963  // pulse RA high voltage, if requested; return from frontend loop if
964  // vacuum_cleaner is active, i.e. RA potentials are changing
965  /* if (hv_vaccleaner.pulse || vacuum_cleaner_active){
966  vacuum_cleaner();
967  if (vacuum_cleaner_active) return SUCCESS;
968  }*/
969 
970  //-----------------------------------------------------------------------------------
971  // in case of On_Off_Mode enabled generate a short pulse on SIS3100 output 1
972  //
974  OnOff_mode();
975  }
976 
977 
978 #ifdef HAVE_TEST_RUN
979  return SUCCESS;
980 #endif
981 
982 
983  if ( runinfo.state != STATE_RUNNING ) // don't read TDC if we are not running
984  return SUCCESS;
985 
986  vme_stats.frontend_loop_counts++; // for test purposes only
987  diffTimeSlowMuon = diffTimeFastMuon = 0;
988 
990  //------------------------------------------------------------------------------------
991  // check fill level of TDC output buffer; return if ALMOST_FULL_BIT is not yet set
992  //
993  return_code = vme_A32D16_read(hdev, V1190_ADDRESS+V1190_STATUS_REGISTER, &data );
994  if ( !(data & V1190_ALMFULL_BIT)) return SUCCESS;
995 
997  //cm_msg(MINFO, "frontend_loop","p_read = 0x%x, p_write = 0x%x", p_read, p_write);
998 }
999  //--------------------------------------------------------------------------------------
1000  // read complete TDC output buffer; break if no more data are present in output buffer
1001  //
1002  sum_lwords = 0;
1003  output_buffer = malloc(V1190_OUTPUT_BUFFER_SIZE * sizeof(u_int32_t));
1004 
1005 // ----------------------------
1006 // simulate pure, uncorrelated background
1007 //
1009 #define BINNING 0.1953125 // TDC bin in ns
1010  double rate[4], ran; // rates 1/ns
1011  U_LONG time[4];
1012  DWORD mincounter, tdctime; // times in TDC channels, assume 0.1953125ns LSB
1013 
1014  rate[0] = 1.e-5; // 10kHz clock
1015  rate[1] = trigger_settings.event_0_settings.mcp1_rate; // MCP1, counts/ns
1016  rate[2] = trigger_settings.event_0_settings.bc_rate; // BCL2, counts/ns
1017  rate[3] = trigger_settings.event_0_settings.bc_rate; // BCL3, counts/ns
1018  ss_sleep(10);
1019  memset(&time, 0x00, sizeof(time));
1020  sum_lwords = V1190_OUTPUT_BUFFER_SIZE/2;
1021  for ( i=0; i<sum_lwords; i++ ){
1022  if ( i == 0 ){
1023  ran = (double) rand()/ (double) RAND_MAX;
1024  time[0] = ran*1.e+5/BINNING; // next occurence of 10kHz
1025  for (j=1; j<4; j++){
1026  ran = (double) rand()/ (double) RAND_MAX;
1027  time[j] = (-1./rate[j]*log(1.- ran))/BINNING;
1028  }
1029  }
1030 
1031  for ( j = 0; j < 4; j++){// find the next event
1032  mincounter = 0;
1033  for ( k =0; k < 4; k++){
1034  if ( j!=k && time[j] <= time[k]) mincounter++;
1035  }
1036  if ( mincounter == 3) break;
1037  }
1038 
1039  switch (j){
1040  case 0:
1041  channel = CLOCK;
1042  tdctime = time[0]%TDC_BIT_RANGE;
1043  tdctime = tdctime | (channel<<19);
1044  time[0] = time[0] + (U_LONG) 1.e+5/BINNING; // the next 10kHz clock time
1045  break;
1046 
1047  case 1:
1048  channel = MCP1;
1049  tdctime = time[1]%TDC_BIT_RANGE;
1050  tdctime = tdctime | (channel<<19);
1051  ran = (double) rand()/(double) RAND_MAX;
1052  time[1] = time[1] + (U_LONG) (-1./rate[j]*log(1. - ran))/BINNING;;
1053  break;
1054 
1055  case 2:
1056  channel = BCL2;
1057  tdctime = time[2]%TDC_BIT_RANGE;
1058  tdctime = tdctime | (channel<<19);
1059  ran = (double) rand()/(double) RAND_MAX;
1060  time[2] = time[2] + (U_LONG) (-1./rate[j]*log(1. - ran))/BINNING;;
1061  break;
1062 
1063  case 3:
1064  channel = BCL3;
1065  tdctime = time[3]%TDC_BIT_RANGE;
1066  tdctime = tdctime | (channel<<19);
1067  ran = (double) rand()/(double) RAND_MAX;
1068  time[3] = time[3] + (U_LONG) (-1./rate[j]*log(1. - ran))/BINNING;;
1069  break;
1070 
1071  default:
1072  break;
1073  }
1074  //fprintf(fp,"i=%6d, times = %12u %12u %12u %12u\n",i,time[0],time[1],time[2],time[3]);
1075  output_buffer[i] = tdctime;
1076  }
1077 }
1078 // -----------------------------
1079 // read TDC data
1080 else {
1081  for ( i = 0; i < 32; i++){
1082  return_code = vme_A32BLT32_read(hdev, V1190_ADDRESS, blt_data, MAX_NUMBER_LWORDS, &get_lwords);
1083  memcpy(output_buffer + sum_lwords, &blt_data, get_lwords * sizeof(u_int32_t));
1084  sum_lwords += get_lwords;
1085  if ( return_code == 0x211) // VME Bus error indicating that output buffer is empty
1086  break; // this does not work at rates > 1MHz; new events in output buffer
1087  }
1088 }
1089  //-----------------------------------------------------------------------------------------
1090  // scan output buffer and search events; if a possible event is found evaluate_event()
1091  // is executed
1092  //
1093  for ( i = 0; i < sum_lwords; i++ ){
1094  v1190_data = (V1190_DATA *) &output_buffer[i];
1095  tdc_time = v1190_data->data;
1096  channel = v1190_data->channel;
1097  if ( vme_stats.last_TDCtime == -1 ) //at BOR last_TDCtime is set to -1
1098  vme_stats.last_TDCtime = tdc_time;
1099 
1100  if ( v1190_data->buffer == 4 ){ //this means a TDC error occured, bit 29 is set; this can happen
1101  //if input rate is > 1MHz; in this case the error condition
1102  //above (return_code == 0x211) does not work
1103 #ifdef TESTOUT
1104  fprintf(fp,"found TDC error\n");
1105 #endif
1107  memset(&tdc_eval_event, 0x00, sizeof(tdc_eval_event)); // reset structure for next event
1108  continue;
1109  }
1110 
1111  if ( tdc_eval_event.foundChannel[channel] > N_HITS-1 ){ // didn't yet find an event
1112 #ifdef TESTOUT
1113  fprintf(fp,"Event reset due to channel %d overflow\n", channel);
1114 #endif
1115  memset(&tdc_eval_event, 0x00, sizeof(tdc_eval_event)); // reset structure for next event to avoid
1116  continue; // buffer overflow
1117  }
1118 
1119  vme_stats.channelCounts[channel]++;
1120  do_channel(channel, tdc_time); //update channel statistics, copy TDC times in temporary buffer
1121  //tdc_event[ch][index] to be used in evaluate_event():
1122 
1123  //check pre-pileups for "master" channels, set event flags, add delays to TDC times
1124  switch (channel){
1125 /* --------------------------------------------------------------------------------------------------------
1126  the "Master" detectors for event types 0 (BC-MCP1-e+), Event 1 (BC-TD-MCP2-e+), Event 2 (BC-TD-e+, LEmuSR)
1127  --------------------------------------------------------------------------------------------------------
1128 */
1129  case MCP1:
1130  tdc_eval_event.tdc_event[MCP1][tdc_eval_event.foundChannel[MCP1]-1] += // incremented by do_channel()
1132 
1133  if ( masterChannelFastMuon == MCP1 )
1134  do_master_channel(MCP1, EVENT_0_TYPE); //to determine pre-pileup
1135 
1136  // set detector flag only if "clean" signal, i.e. no pre-pileup
1140  break;
1141 
1142  case MCP2F:
1143  //add time delay
1144  if ( masterChannelSlowMuon == MCP2F ){
1147  do_master_channel(MCP2F, EVENT_1_TYPE); //to determine pre-pileup
1148  }
1149  // set detector flag only if "clean" signal, i.e. no pre-pileup, and if event enabled
1150  // in case of MCP2F not used as "master" tdc_eval_event.pileup[MCP2F][j]=0 for all j
1151  if ( tdc_eval_event.pileup[MCP2F][tdc_eval_event.foundChannel[MCP2F]-1] == 0 && // incremented by do_channel()
1154  break;
1155 
1156  case TD:
1157  //add time delay
1159  tdc_eval_event.tdc_event[TD][tdc_eval_event.foundChannel[TD]-1] += // incremented by do_channel()
1162  tdc_eval_event.tdc_event[TD][tdc_eval_event.foundChannel[TD]-1] += // incremented by do_channel()
1164 
1165  if ( masterChannelSlowMuon == TD )
1166  do_master_channel(TD, EVENT_1_TYPE | EVENT_2_TYPE); //to determine pre-pileup
1167 
1168  // set detector flag only if "clean" signal, i.e. no pre-pileup, and if event enabled
1169  // in case of TD not used as "master" tdc_eval_event.pileup[TD][j]=0 for all j
1171  (eventDefinedSlowMuon & TD_EVENT) ) // incremented by do_channel()
1173  break;
1174 /* -------------------- e n d of "Master" detectors -----------------------------------------------*/
1175 
1176 /* ------------------- beam counter with 8 segments ------------------------------------------------*/
1177  case BCL1: case BCL2: case BCL3: case BCL4: case BCR1: case BCR2: case BCR3: case BCR4:
1178  // check pre-pileup
1180  tdc_eval_event.pileup[channel][tdc_eval_event.foundChannel[channel]-1] = 1;
1182  vme_stats.bc_clean++;
1183  else // this means tdc_pileup.endBeamCounterEvent - runTime = bc_pileup_window; event "re-evaluated"
1185 
1188 
1189  // set detector flag only if "clean" signal, i.e. no pre-pileup
1190  if ( tdc_eval_event.pileup[channel][tdc_eval_event.foundChannel[channel]-1] == 0 &&
1193 
1194  if ( tdc_eval_event.pileup[channel][tdc_eval_event.foundChannel[channel]-1] == 0 &&
1195  (eventDefinedSlowMuon & BC_EVENT))
1197 
1198  // problem: BC appears before the "Master" detectors MCP1 or TD/MCP2; for event evaluation it is more simple
1199  // to have the master first, otherwise, there can be data lost accross a new event evaluation.
1200  // BC event losses can be avoided by "reverse" timing: delay BC by TOF window width; add this delay
1201  // to the tdc_eval_event.thisTime's: in this way an event evaluation can be initiated by a BC instead of
1202  // a nearby MCP1 - if the MCP1 is less than TOF window later than BC
1203 /* -------------------------------------------------------------------------------
1204  *
1205  * For the experiment of Paolo Crivelli, ETH Zurich, use the BC channels for the Ly-alpha detectors. Now, we have normal timing
1206  *
1207  tdc_eval_event.tdc_event[channel][tdc_eval_event.foundChannel[channel]-1] += trigger_settings.tof_bc_window;
1208  if ( eventDefinedFastMuon & BC_EVENT)
1209  tdc_eval_event.thisTimeFastMuon += trigger_settings.tof_bc_window;
1210  if ( eventDefinedSlowMuon & BC_EVENT)
1211  tdc_eval_event.thisTimeSlowMuon += trigger_settings.tof_bc_window;
1212  -------------------------------------------------------------------------------
1213 */
1214 
1215  break;
1216 /* ---------------- e n d of beam counter -----------------------------------------------------------*/
1217 
1218  case POSMCP1I: case POSMCP1O:
1219  tdc_eval_event.tdc_event[channel][tdc_eval_event.foundChannel[channel]-1] +=
1223  break;
1224 
1225  case POSLDI: case POSLDO: case POSLUI: case POSLUO:
1226  case POSTDI: case POSTDO: case POSTUI: case POSTUO:
1227  case POSRDI: case POSRDO: case POSRUI: case POSRUO:
1228  case POSBDI: case POSBDO: case POSBUI: case POSBUO:
1230  tdc_eval_event.tdc_event[channel][tdc_eval_event.foundChannel[channel]-1] +=
1232  else
1233  tdc_eval_event.tdc_event[channel][tdc_eval_event.foundChannel[channel]-1] +=
1235 
1238  break;
1239 
1240  case MCP2R: case MCP2X1: case MCP2X2: case MCP2Y1: case MCP2Y2:
1241  if ( masterChannelSlowMuon == MCP2F )
1242  tdc_eval_event.tdc_event[channel][tdc_eval_event.foundChannel[channel]-1] +=
1244  break;
1245 
1246  case EXTON1:
1247  flag_external_on = TRUE;
1248  nextGoodTime = runTime + (U_LONG) 5120*trigger_settings.delay_daq_usec_; // 1usec = 5120 TDC bins
1249  break;
1250 
1251  case EXTOFF1:
1252  flag_external_on = FALSE;
1253  nextGoodTime = runTime + (U_LONG) 5120*trigger_settings.delay_daq_usec_; // 1usec = 5120 TDC bins
1254  break;
1255 
1256  case CLOCK:
1257  break;
1258 
1259  default:
1260  break;
1261  }
1262 
1265  // 28-Mar-2006: the following corrections on diffTimeFast/SlowMuon are still needed,
1266  // ----------- since tdc_eval_event.t0 is obsolete
1267  //
1268  // the following is needed to avoid segmentation fault of the frontend in case of
1269  // enabled events 0 and 1 (M1,TD/M2); due to non-ascening order of time stamps in
1270  // TDC it may happen that we have a new event like
1271  // 1 (clock) 336 = t0 event time 0
1272  // 2 (MCP1) 312 event time -24 --> 524264, difftime 0
1273  // 2 (MCP1) 1012 event time 676 --> difftime to last MCP1 -523588 instead of 700
1274  // in this case the MCP1
1275  //
1276  if ( diffTimeFastMuon < 0 && abs(diffTimeFastMuon) >= t0_offset)
1277  diffTimeFastMuon += TDC_BIT_RANGE;
1278  else if ( diffTimeFastMuon < 0 && abs(diffTimeFastMuon) < t0_offset )
1279  diffTimeFastMuon += t0_offset;
1280 
1281  if ( diffTimeSlowMuon < 0 && abs(diffTimeSlowMuon) >= t0_offset)
1282  diffTimeSlowMuon += TDC_BIT_RANGE;
1283  else if ( diffTimeSlowMuon < 0 && abs(diffTimeSlowMuon) < t0_offset )
1284  diffTimeSlowMuon += t0_offset;
1285 
1286 #ifdef TESTOUT
1287  fprintf(fp,
1288  "raw data = %6d %3d %7d 0x%08x, vmeTime = %10.5e, difftime = %8d, ev.time = %8d, pu-flag = %2d, 0x%04x\n",
1289  i, channel, tdc_time, output_buffer[i],
1291  diffTimeSlowMuon, tdc_eval_event.event_time,
1292  tdc_eval_event.pileup[channel][tdc_eval_event.foundChannel[channel]-1],
1294 #endif
1295 
1297  (diffTimeSlowMuon > (dataWindowSlowMuon + t0_offset)) ){
1299  i--; // we have to check if the current hit is a candidate for a new event
1300  vme_stats.channelCounts[channel]--; // avoid double counting
1301  }
1303  (diffTimeFastMuon > (dataWindowFastMuon + t0_offset)) ){
1305  i--; // we have to check if the current hit is a candidate for a new event
1306  vme_stats.channelCounts[channel]--; // avoid double counting
1307  }
1308  else if (channel == CLOCK ){
1309  //check for successice clock events; if present reset tdc_eval_event structure
1310  if ( i - tdc_eval_event.clockIndex == 1 && i !=1 ){
1311  memset(&tdc_eval_event, 0x00, sizeof(tdc_eval_event));
1312  //continue;
1313  }
1314  if ( i == sum_lwords - 1) // two handle successive clock events correctly when new
1315  tdc_eval_event.clockIndex = -1; // output buffer is scanned
1316  else
1318  }
1319 
1320  // removed all the time exceeding handling which appeared here at versions <= 1738
1321  }
1322 
1323  free(output_buffer);
1324 
1325  return SUCCESS;
1326 }
1327 /*-----------------------------------------------------------------------------------------*/
1334 INT do_channel(INT ch, INT TDCtime)
1335 {
1336  INT diff_toLastEvent;
1337 
1338  //introduce a trigger_settings.t0_offset to handle events like:
1339  // MCP1 380
1340  // e+_I 370
1341  // e+_O 375
1342  // without special handling this would lead to a diff_time = diff_time + TDC_BIT_RANGE
1343  // which is a big number and can be greater than the data gate - in which case the event
1344  // would be rejected
1345  if ( tdc_eval_event.set_t0 == 0) { //a new event evaluation has started;
1348  }
1349 
1350  diff_toLastEvent = TDCtime - vme_stats.last_TDCtime;
1351  if ( diff_toLastEvent < DIFF_TOLERANCE )
1352  diff_toLastEvent += TDC_BIT_RANGE; //only add TDC_BIT_RANGE if time difference is > abs(DIFF_TOLERANCE)
1353  //allow for "small" negative time differences, i.e. for event sequences
1354  //as shown above
1355  vme_stats.last_TDCtime = TDCtime;
1356  tdc_eval_event.event_time += diff_toLastEvent;
1357  //calculate the absolute run time in TDC LSB units
1358  runTime += (U_LONG) diff_toLastEvent;
1359  vme_stats.run_time = (double) runTime; //copy to ODB structure
1360 
1362 
1365 
1366  return SUCCESS;
1367 }
1368 /*-----------------------------------------------------------------------------------------*/
1369 INT do_master_channel(INT ch, INT event_type)
1370 {
1371  switch (event_type){
1372  case EVENT_0_TYPE: // "fast" muons
1373  //check pre-pileup
1374  //the following works because we're using unsigned integers:
1375  //for a clean signal, tdc_pileup.endMasterEvent0 - runTime < 0, but this becomes
1376  //"a large number > 0" if we are dealing with unsigned integers only.
1377  if ( (tdc_pileup.endMasterEvent0 - runTime) < (U_LONG) dataWindowFastMuon ) // we had a pre-pileup
1379  else if ( (tdc_pileup.endMasterEvent0 - runTime) > (U_LONG) dataWindowFastMuon){ // this is a "clean" signal
1380  vme_stats.mcp1_clean++; // i.e. no pre-pileup
1381  vme_stats.mcp1_good++; //this could be a potential "good" event
1386  }
1387  }
1388  else{ // this means tdc_pileup.endMasterEvent0 - runTime = dataWindowFastMuon; event "re-evaluated"
1390  // for mcp1_good event determination across two tdc_eval_event's
1392  }
1393 
1394  // check for post-pileup to count "mcp1_good" event (no pre- and post-pileup)
1395  // - check, if we had a pile-up
1396  // - then check, if previous event was a clean event; in this case lower mcp1_good;
1397  // in case of subsequent pileup events don't decrease mcp1_good
1398  // - the "tdc_eval_event.indexFastMuonSet > 0" condition is needed to get the correct
1399  // counting across two event evaluations
1400  if (tdc_eval_event.pileup[ch][tdc_eval_event.foundChannel[ch]-1] == 1){
1403  vme_stats.mcp1_good--;
1404  }
1406  tdc_pileup.endMasterEvent0 = pileup_end(dataWindowFastMuon);
1407 #ifdef TESTOUT
1408  fprintf(fp,"runTime = %12d, PUend = %12d, pu = %04d, clean = %6d, good = %6d\n",
1409  (int) runTime,
1412  (int) vme_stats.mcp1_clean, (int) vme_stats.mcp1_good);
1413 #endif
1414  break;
1415 
1416  case EVENT_1_TYPE: case EVENT_2_TYPE: case EVENT_1_TYPE | EVENT_2_TYPE: // "slow" muons
1417  //check pre-pileup
1418  if ( (tdc_pileup.endMasterEvent1or2 - runTime) < (U_LONG) dataWindowSlowMuon ) // we have a pre-pileup
1420  else if ( (tdc_pileup.endMasterEvent1or2 - runTime) > (U_LONG) dataWindowSlowMuon){ // this is a "clean" signal
1421  if ( ch == MCP2F){
1422  vme_stats.mcp2_clean++; // i.e. no pre-pileup
1423  vme_stats.mcp2_good++; // a potential candidate without post-pileup
1424  }
1425  if ( ch == TD ){
1426  vme_stats.td_clean++; // i.e. no pre-pileup
1427  vme_stats.td_good++; // a potential candidate without post-pileup
1428  }
1429 
1431  // to avoid that an event sequence like
1432  // 4-26-27-28-29-30-31-4 (== TD-MCP2F-MCP2R-MCP2X1-MCP2X2-MCP2Y1-MCP2Y2-TD)
1433  // get's the wrong TD_clean signal for event evaluatio (the 2nd one in this example)
1437  }
1438  }
1439  else{ // this means tdc_pileup.endMasterEvent1or2 - runTime = dataWindowSlowMuon; event "re-evaluated"
1441  // for mcp2/TD_good event determination across two tdc_eval_event's
1443  }
1444  // check for post-pileup to count "mcp2/TD_good" event (no pre- and post-pileup)
1445  // - check, if we had a pile-up
1446  // - then check, if previous event was a clean event; in this case lower mcp1_good;
1447  // in case of subsequent pileup events don't decrease mcp2/TD_good
1448  // - the "tdc_eval_event.indexSlowMuonSet > 0" condition is needed to get the correct
1449  // counting across two event evaluations
1450  if (tdc_eval_event.pileup[ch][tdc_eval_event.foundChannel[ch]-1] == 1){
1453  if ( ch == MCP2F ) vme_stats.mcp2_good--;
1454  if ( ch == TD ) vme_stats.td_good--;
1455  }
1456  }
1458  tdc_pileup.endMasterEvent1or2 = pileup_end(dataWindowSlowMuon);
1459  break;
1460 
1461  default:
1462  break;
1463  }
1464 
1465  return 0;
1466 }
1467 /*-----------------------------------------------------------------------------------------*/
1474 U_LONG pileup_end(INT pileupWindow)
1475 {
1476  U_LONG end_time;
1477 
1478  end_time = runTime + (U_LONG) pileupWindow;
1479  return end_time;
1480 }
1481 /*-----------------------------------------------------------------------------------------*/
1490 {
1491  INT i, j, k, diff_time, masterIndex;
1492  INT decChannel[8], decInd[8], bcChannel, bcInd, tdChannel, tdInd, m2Channel, m2Ind;
1493  DWORD tofPileupWindow, tofWindow, dataWindow;
1494  BOOL good_event, pos_event, bc_event, posL_event, posT_event, posR_event, posB_event;
1495  BOOL mcp2_event;
1496  LEM_DATA *lem_data;
1497  U_LONG masterRunTime;
1498 
1499 #ifdef TESTOUT
1500  fprintf(fp,"evaluate_slow_muon_event, M2clean = %10.0f, TDclean = %10.0f\n", vme_stats.mcp2_clean, vme_stats.td_clean);
1501 #endif
1502 
1503  good_event = pos_event = bc_event = mcp2_event = FALSE;
1504  posL_event = posT_event = posR_event = posB_event = FALSE;
1505  tofPileupWindow = trigger_settings.tof_bc_pileup_window;
1506  tofWindow = trigger_settings.tof_bc_window;
1507  masterIndex = tdc_eval_event.indexSlowMuon;
1508 
1509  //for "on/off" ("red/green") mode check if we are ready for next event after waiting
1510  //trigger_settings.delay_onoff_mode TDC channels
1511  //we have to check if the last "clean" master channel time in absolute runTime is > nextGoodTime.
1512  //if not, return immediately
1514  masterRunTime = runTime -
1516  if (masterRunTime < nextGoodTime){
1517  memset(&tdc_eval_event, 0x00, sizeof(tdc_eval_event));
1518  return SUCCESS;
1519  }
1520  }
1521 
1522  bcChannel = bcInd = m2Channel = m2Ind = tdChannel = tdInd = -1; //initialize
1523 
1524  for ( i=0; i<8; i++)
1525  decChannel[i] = decInd[i] = -1;
1526 
1529  //always check TOF TD-MCP2 for Event1 type
1530  if ( masterChannelSlowMuon == TD )
1532  MCP2F, MCP2F, TD, masterIndex, &m2Channel, &m2Ind);
1533  else
1535  TD, TD, MCP2F, masterIndex, &tdChannel, &tdInd);
1536  }
1537  else
1539 
1540  //check positrons always, since they are always enabled in TDC
1541  posL_event = check_positron(dataWindow, 50, POSLDI, POSLDO, masterChannelSlowMuon, masterIndex,
1542  &decChannel[0], &decInd[0]) ||
1543  check_positron(dataWindow, 50, POSLUI, POSLUO, masterChannelSlowMuon, masterIndex,
1544  &decChannel[1], &decInd[1]);
1545  posT_event = check_positron(dataWindow, 50, POSTDI, POSTDO, masterChannelSlowMuon, masterIndex,
1546  &decChannel[2], &decInd[2]) ||
1547  check_positron(dataWindow, 50, POSTUI, POSTUO, masterChannelSlowMuon, masterIndex,
1548  &decChannel[3], &decInd[3]);
1549  posR_event = check_positron(dataWindow, 50, POSRDI, POSRDO, masterChannelSlowMuon, masterIndex,
1550  &decChannel[4], &decInd[4]) ||
1551  check_positron(dataWindow, 50, POSRUI, POSRUO, masterChannelSlowMuon, masterIndex,
1552  &decChannel[5], &decInd[5]);
1553  posB_event = check_positron(dataWindow, 50, POSBDI, POSBDO, masterChannelSlowMuon, masterIndex,
1554  &decChannel[6], &decInd[6]) ||
1555  check_positron(dataWindow, 50, POSBUI, POSBUO, masterChannelSlowMuon, masterIndex,
1556  &decChannel[7], &decInd[7]);
1557  pos_event = posL_event || posT_event || posR_event || posB_event;
1558 
1559  //check BC if enabled in Event definition
1560  if ( eventDefinedSlowMuon & BC_EVENT ){
1561  if ( masterChannelSlowMuon == TD )
1562  bc_event = check_tof_and_pileup( MASTERFIRST, tofWindow, BCL1, BCR4, masterChannelSlowMuon, masterIndex,
1563  &bcChannel, &bcInd);
1564  else
1565  bc_event = check_tof_and_pileup( MASTERLAST, tofWindow, BCL1, BCR4, masterChannelSlowMuon, masterIndex,
1566  &bcChannel, &bcInd);
1567  }
1568 
1569  switch (eventDefinedSlowMuon){
1570  case (M2_EVENT):
1571  case (TD_EVENT):
1572  good_event = TRUE;
1573  break;
1574 
1575  case (TD_EVENT | M2_EVENT):
1576  good_event = mcp2_event;
1577  break;
1578 
1579  case ( M2_EVENT | BC_EVENT):
1580  case ( TD_EVENT | BC_EVENT ):
1581  good_event = bc_event;
1582  break;
1583 
1584  case ( M2_EVENT | LE_POSITRON_EVENT ):
1585  case ( TD_EVENT | LE_POSITRON_EVENT ):
1586  good_event = pos_event;
1587  break;
1588 
1589  case ( M2_EVENT | BC_EVENT | LE_POSITRON_EVENT ):
1590  case ( TD_EVENT | BC_EVENT | LE_POSITRON_EVENT ):
1591  good_event = pos_event && bc_event;
1592  break;
1593 
1594  case (TD_EVENT | M2_EVENT | BC_EVENT):
1595  good_event = mcp2_event && bc_event;
1596  break;
1597 
1598  case (TD_EVENT | M2_EVENT | LE_POSITRON_EVENT):
1599  good_event = mcp2_event && pos_event;
1600  break;
1601 
1602  case (TD_EVENT | M2_EVENT | BC_EVENT | LE_POSITRON_EVENT):
1603  good_event = mcp2_event && pos_event && bc_event;
1604  break;
1605 
1606  default:
1607  break;
1608  }
1609 
1610  // ----------------------
1611  // no event found, reset arrays and return
1612  if ( !good_event ){
1613  memset(&tdc_eval_event, 0x00, sizeof(tdc_eval_event));
1614  return SUCCESS;
1615  }
1616 
1617  // -----------------------
1618  // we have a valid event
1619  // build event in the form
1620  // ch4:1st Hit (1st MCP2/TD clean)
1621  // ch4:2nd Hit
1622  // ...
1623  // ch6:1st Hit
1624  // ...
1625  k = 0;
1626  for ( i=2; i<N_TDC_CHANNELS; i++ ){ // i=0 is Ip, i=1 10kHz clock
1627  switch (i){
1628  case BCL1: case BCL2: case BCL3: case BCL4: case BCR1: case BCR2: case BCR3: case BCR4:
1629  if ( bcChannel == -1 ) continue;
1630  break;
1631  case POSLDI: case POSLDO:
1632  if ( decChannel[0] == -1 ) continue;
1633  break;
1634  case POSLUI: case POSLUO:
1635  if ( decChannel[1] == -1 ) continue;
1636  break;
1637  case POSTDI: case POSTDO:
1638  if ( decChannel[2] == -1 ) continue;
1639  break;
1640  case POSTUI: case POSTUO:
1641  if ( decChannel[3] == -1 ) continue;
1642  break;
1643  case POSRDI: case POSRDO:
1644  if ( decChannel[4] == -1 ) continue;
1645  break;
1646  case POSRUI: case POSRUO:
1647  if ( decChannel[5] == -1 ) continue;
1648  break;
1649  case POSBDI: case POSBDO:
1650  if ( decChannel[6] == -1 ) continue;
1651  break;
1652  case POSBUI: case POSBUO:
1653  if ( decChannel[7] == -1 ) continue;
1654  break;
1655 
1656  default:
1657  break;
1658  }
1659  for ( j=0; j<tdc_eval_event.foundChannel[i]; j++){
1660  switch (i){
1661  case TD:
1662  if ( masterChannelSlowMuon == TD && j < masterIndex ) // this is not a "clean" signal
1663  continue;
1664  if ( masterChannelSlowMuon == MCP2F )
1665  if ( j < tdInd || tdInd == -1) continue; // one could "save" the || if default would be 2^(16) instead of
1666  break; // -1, for example; with -1 it may be better "readable" for human
1667  // beings
1668  case MCP2F: case MCP2R:
1669  if ( masterChannelSlowMuon == MCP2F && j < masterIndex ) // this is not a "clean" signal
1670  continue;
1671  if ( masterChannelSlowMuon == TD)
1672  if ( j < m2Ind || m2Ind == -1 ) continue;
1673  break;
1674 
1675  case MCP2X1: case MCP2X2: case MCP2Y1: case MCP2Y2:
1676  if ( masterChannelSlowMuon == MCP2F){
1677  if ( (tdc_eval_event.tdc_event[MCP2F][masterIndex] - tdc_eval_event.tdc_event[i][j]) > 0 )
1678  continue;
1679  }
1680  if ( masterChannelSlowMuon == TD){
1681  if ( m2Ind == -1) continue;
1682  if ( (tdc_eval_event.tdc_event[MCP2F][m2Ind] - tdc_eval_event.tdc_event[i][j]) > 0 )
1683  continue;
1684  }
1685  break;
1686 
1687  case BCL1: case BCL2: case BCL3: case BCL4: case BCR1: case BCR2: case BCR3: case BCR4:
1688  // don't put BC data to data buffer if they are more than 1musec from the "good" BC count
1689  if ( abs(tdc_eval_event.tdc_event[i][j] - tdc_eval_event.tdc_event[bcChannel][bcInd]) >
1690  tofPileupWindow)
1691  continue;
1692  break;
1693 
1694  case POSLDI: case POSLDO:
1695  // don't put e+ data to data buffer if they appeared earlier than masterchannel
1696  if ( i == decChannel[0] && j < decInd[0] ) // the first e+ event in the data of i=decChannel
1697  continue; // will be the first coincidence found
1698  if ( (tdc_eval_event.tdc_event[masterChannelSlowMuon][masterIndex] - tdc_eval_event.tdc_event[i][j]) > 0)
1699  continue;
1700  break;
1701  case POSLUI: case POSLUO:
1702  // don't put e+ data to data buffer if they appeared earlier than masterchannel
1703  if ( i == decChannel[1] && j < decInd[1] ) // the first e+ event in the data of i=decChannel
1704  continue; // will be the first coincidence found
1705  if ( (tdc_eval_event.tdc_event[masterChannelSlowMuon][masterIndex] - tdc_eval_event.tdc_event[i][j]) > 0)
1706  continue;
1707  break;
1708  case POSTDI: case POSTDO:
1709  // don't put e+ data to data buffer if they appeared earlier than masterchannel
1710  if ( i == decChannel[2] && j < decInd[2] ) // the first e+ event in the data of i=decChannel
1711  continue; // will be the first coincidence found
1712  if ( (tdc_eval_event.tdc_event[masterChannelSlowMuon][masterIndex] - tdc_eval_event.tdc_event[i][j]) > 0)
1713  continue;
1714  break;
1715  case POSTUI: case POSTUO:
1716  // don't put e+ data to data buffer if they appeared earlier than masterchannel
1717  if ( i == decChannel[3] && j < decInd[3] ) // the first e+ event in the data of i=decChannel
1718  continue; // will be the first coincidence found
1719  if ( (tdc_eval_event.tdc_event[masterChannelSlowMuon][masterIndex] - tdc_eval_event.tdc_event[i][j]) > 0)
1720  continue;
1721  break;
1722  case POSRDI: case POSRDO:
1723  // don't put e+ data to data buffer if they appeared earlier than masterchannel
1724  if ( i == decChannel[4] && j < decInd[4] ) // the first e+ event in the data of i=decChannel
1725  continue; // will be the first coincidence found
1726  if ( (tdc_eval_event.tdc_event[masterChannelSlowMuon][masterIndex] - tdc_eval_event.tdc_event[i][j]) > 0)
1727  continue;
1728  break;
1729  case POSRUI: case POSRUO:
1730  // don't put e+ data to data buffer if they appeared earlier than masterchannel
1731  if ( i == decChannel[5] && j < decInd[5] ) // the first e+ event in the data of i=decChannel
1732  continue; // will be the first coincidence found
1733  if ( (tdc_eval_event.tdc_event[masterChannelSlowMuon][masterIndex] - tdc_eval_event.tdc_event[i][j]) > 0)
1734  continue;
1735  break;
1736  case POSBDI: case POSBDO:
1737  // don't put e+ data to data buffer if they appeared earlier than masterchannel
1738  if ( i == decChannel[6] && j < decInd[6] ) // the first e+ event in the data of i=decChannel
1739  continue; // will be the first coincidence found
1740  if ( (tdc_eval_event.tdc_event[masterChannelSlowMuon][masterIndex] - tdc_eval_event.tdc_event[i][j]) > 0)
1741  continue;
1742  break;
1743  case POSBUI: case POSBUO:
1744  // don't put e+ data to data buffer if they appeared earlier than masterchannel
1745  if ( i == decChannel[7] && j < decInd[7] ) // the first e+ event in the data of i=decChannel
1746  continue; // will be the first coincidence found
1747  if ( (tdc_eval_event.tdc_event[masterChannelSlowMuon][masterIndex] - tdc_eval_event.tdc_event[i][j]) > 0)
1748  continue;
1749  break;
1750 
1751  default:
1752  break;
1753  }
1754  k = ++tdc_eval_event.eventSize;
1755  if ( k > DATA_N_HITS){ //max. DATA_N_HITS hits to output data stream
1757  break;
1758  }
1759  lem_data = (LEM_DATA *) &tdc_eval_event.tdc_data[k];
1760  lem_data->data = tdc_eval_event.tdc_event[i][j];
1761  lem_data->channel = i;
1762 // tdc_eval_event.tdc_data[k] =
1763 // ((tdc_eval_event.tdc_data[k] | i)<<24 ) | tdc_eval_event.tdc_event[i][j]; //copy channel
1764  }
1765  }
1768  else
1770 
1771  if (flag_external_on){
1773  (tdc_eval_event.tdc_data[0] | NEW_EVENT_MASK) | // bits 24-30 set indicating new event
1777  }
1778  else{
1780  (tdc_eval_event.tdc_data[0] | NEW_EVENT_MASK) | // bits 24-30 set indicating new event
1784  }
1785  for ( j = 0; j < tdc_eval_event.eventSize+1; j++){
1788  }
1789  else{ //jump to beginning of ring buffer
1790  p_write = &databuffer[0];
1792  }
1793 #ifdef TESTOUT
1794  lem_data = (LEM_DATA *) &tdc_eval_event.tdc_data[j];
1795  fprintf(fp,"tdc data = %02d, %8d, channel %4d, hex = 0x%08x\n", j,
1796  lem_data->data,
1797  lem_data->channel,
1799 #endif
1800  }
1801 
1803  memset(&tdc_eval_event, 0x00, sizeof(tdc_eval_event));
1804 
1805  return SUCCESS;
1806 }
1807 /*-----------------------------------------------------------------------------------------*/
1816 {
1817  INT i, j, k, diff_time, bcChannel, bcInd, decChannel, decInd, masterIndex;
1818  BOOL good_event, bc_event, pos_event;
1819  DWORD tofPileupWindow, tofWindow, dataWindow;
1820  LEM_DATA *lem_data;
1821 
1822 #ifdef TESTOUT
1823  fprintf(fp,"evaluate_fast_muon_event, mcp1 = %10.0f, mcp1 clean = %10.0f\n",
1825 #endif
1826 
1827  good_event = bc_event = pos_event = FALSE;
1828  tofPileupWindow = trigger_settings.tof_bc_pileup_window;
1829  tofWindow = trigger_settings.tof_bc_window;
1831  masterIndex = tdc_eval_event.indexFastMuon;
1832  bcChannel = bcInd = decChannel = decInd = -1; //initialize
1833 
1834  //always check positron since they are always enabled if Ev0 is active
1835  pos_event = check_positron(dataWindow, 50, POSMCP1I, POSMCP1O, MCP1, masterIndex, &decChannel, &decInd);
1836 
1838  bc_event = check_tof_and_pileup( MASTERFIRST, tofWindow, BCL1, BCR4, MCP1, masterIndex, &bcChannel, &bcInd);
1839 
1840  switch (eventDefinedFastMuon){
1841  case (BC_EVENT | M1_EVENT):
1842  good_event = bc_event;
1843  break;
1844 
1845  case (M1_EVENT | M1_POSITRON_EVENT ):
1846  good_event = pos_event;
1847  break;
1848 
1849  case (M1_EVENT | M1_POSITRON_EVENT | BC_EVENT):
1850  good_event = bc_event && pos_event;
1851  break;
1852 
1853  default:
1854  break;
1855  }
1856 
1857  // ----------------------
1858  // if no event found, reset arrays and return
1859  if ( !good_event ){
1860  memset(&tdc_eval_event, 0x00, sizeof(tdc_eval_event));
1861  return SUCCESS;
1862  }
1863  // -----------------------
1864  // we have a valid event
1865  // build event in the form
1866  // ch2:1st Hit (1st MCP1 clean)
1867  // ch2:2nd Hit
1868  // ...
1869  // ch6:1st Hit
1870  // ...
1871  k = 0;
1872  for ( i=2; i<N_TDC_CHANNELS; i++ ){// i=0 is Ip, i=1 10kHz clock
1873  switch (i){
1874  case BCL1: case BCL2: case BCL3: case BCL4: case BCR1: case BCR2: case BCR3: case BCR4:
1875  if ( bcChannel == -1 ) continue;
1876  break;
1877 
1878  case POSMCP1I: case POSMCP1O:
1879  if ( decChannel == -1 ) continue;
1880  break;
1881 
1882  default:
1883  break;
1884  }
1885 
1886  for ( j=0; j<tdc_eval_event.foundChannel[i]; j++){
1887  switch (i){
1888  case MCP1:
1889  if ( masterChannelFastMuon == MCP1 && j < masterIndex) // this is not a "clean" signal
1890  continue;
1891  break;
1892 
1893  case BCL1: case BCL2: case BCL3: case BCL4: case BCR1: case BCR2: case BCR3: case BCR4:
1894  // don't put BC data to data buffer if they are more than 1musec from the "good" BC count
1895  if ( abs(tdc_eval_event.tdc_event[i][j] - tdc_eval_event.tdc_event[bcChannel][bcInd]) >
1896  tofPileupWindow)
1897  continue;
1898  break;
1899 
1900  case POSMCP1I: case POSMCP1O:
1901  // don't put e+ data to data buffer if they appeared earlier than masterchannel
1902  if ( i == decChannel && j < decInd ) // the first e+ event in the data of i=decChannel
1903  continue; // will be the first coincidence found
1904  if ( (tdc_eval_event.tdc_event[MCP1][masterIndex] - tdc_eval_event.tdc_event[i][j]) > 0)
1905  continue;
1906  break;
1907 
1908  default:
1909  break;
1910  }
1911  k = ++tdc_eval_event.eventSize;
1912  if ( k > DATA_N_HITS){ //max. DATA_N_HITS hits to output data stream
1914  break;
1915  }
1916  lem_data = (LEM_DATA *) &tdc_eval_event.tdc_data[k];
1917  lem_data->data = tdc_eval_event.tdc_event[i][j];
1918  lem_data->channel = i;
1919 // tdc_eval_event.tdc_data[k] =
1920 // ((tdc_eval_event.tdc_data[k] | i)<<24 ) | tdc_eval_event.tdc_event[i][j]; //copy channel
1921  }
1922  }
1924  (tdc_eval_event.tdc_data[0] | NEW_EVENT_MASK) | // bits 24-30 set indicating new event
1925  ((tdc_eval_event.tdc_data[0] | EVENT_0_TYPE)<<16) |
1927 
1928  for ( j = 0; j < tdc_eval_event.eventSize+1; j++){
1931  }
1932  else{ //jump to beginning of ring buffer
1933  p_write = &databuffer[0];
1935  }
1936 #ifdef TESTOUT
1937  lem_data = (LEM_DATA *) &tdc_eval_event.tdc_data[j];
1938  fprintf(fp,"tdc data = %02d, %8d, channel %4d, hex = 0x%08x, ch = %4d, index = %4d\n",
1939  j,
1940  lem_data->data,
1941  lem_data->channel,
1943  bcChannel, bcInd);
1944 #endif
1945  }
1946 
1948  memset(&tdc_eval_event, 0x00, sizeof(tdc_eval_event));
1949 
1950  return SUCCESS;
1951 }
1952 /* -------------------------------------------------------------------- */
1969 BOOL check_tof_and_pileup(INT timing, INT tofWindow, INT firstCh, INT lastCh, INT masterChannel, INT masterIndex,
1970  INT *channel, INT *ind)
1971 {
1972  INT i, j, k, l;
1973  INT difftime_now, difftime_last;
1974 
1975  if ( timing == MASTERLAST )
1976  difftime_now = difftime_last = 0;
1977  else
1978  difftime_now = difftime_last = 2 * tofWindow;
1979  *channel = *ind = -1;
1980  for ( i = firstCh; i <= lastCh; i++){
1981  //the following is for "MasterLast" timing; may lead to loss of some events
1982  if ( timing == MASTERLAST){
1983  for ( j = 0; j < tdc_eval_event.foundChannel[i]; j++){ // get the most distant hit within the TOF window
1984  difftime_now = tdc_eval_event.tdc_event[masterChannel][masterIndex] - tdc_eval_event.tdc_event[i][j];
1985 
1986  if ( difftime_now < tofWindow && difftime_now > 0){
1987  if ( difftime_now > difftime_last ){
1988  difftime_last = difftime_now;
1989  *channel = i;
1990  *ind = j;
1991  }
1992  }
1993  }
1994  }
1995  else{
1996  // for "MasterFirst" timing: each "good" hit is assumed to appear after the master detector hit
1997  for ( j = 0; j < tdc_eval_event.foundChannel[i]; j++){ // get the nearest hit within the TOF window
1998  difftime_now = tdc_eval_event.tdc_event[i][j] - tdc_eval_event.tdc_event[masterChannel][masterIndex];
1999 
2000  if ( difftime_now < tofWindow && difftime_now > 0){
2001  if ( difftime_now < difftime_last ){
2002  difftime_last = difftime_now;
2003  *channel = i;
2004  *ind = j;
2005  }
2006  }
2007  }
2008  }
2009  }
2010  if ( *channel == -1 ) return FALSE; // we didn't find an tof/decay event
2011 
2012  // ----------------------
2013  // check pileup;
2014  //
2015  if ( tdc_eval_event.pileup[*channel][*ind] == 1 ){
2016 #ifdef TESTOUT
2017  fprintf(fp, " TOF pileup at channel %d, hit %d\n", *channel, *ind);
2018 #endif
2019  return FALSE;
2020  }
2021  return TRUE; // if we come to this point we found an event and no pre-pileup
2022 }
2023 /* -------------------------------------------------------------------- */
2038 BOOL check_positron(INT decWindow, INT coincWindow, INT firstCh, INT lastCh, INT masterChannel, INT masterIndex,
2039  INT *channel, INT *ind)
2040 {
2041  INT i, j;
2042  INT difftime_now, difftime_last, difftime;
2043  INT n_coincidence;
2044 
2045  difftime_now = difftime_last = 2*decWindow; // initialise variables
2046  *channel = *ind = -1;
2047 
2048  if ( coincWindow < 0 ){
2049  // the following is for single e+ counters
2050  for ( i = firstCh; i <= lastCh; i++){
2051  for ( j = 0; j < tdc_eval_event.foundChannel[i]; j++){ // get the nearest hit within the decay window
2052  difftime_now = tdc_eval_event.tdc_event[i][j] - tdc_eval_event.tdc_event[masterChannel][masterIndex];
2053 
2054  if ( difftime_now < decWindow && difftime_now > 0){
2055  if ( difftime_now < difftime_last ){
2056  difftime_last = difftime_now;
2057  *channel = i;
2058  *ind = j;
2059  }
2060  }
2061  }
2062  }
2063  }
2064  else{// search for coincidences
2065  if ( (tdc_eval_event.foundChannel[firstCh] == 0) || (tdc_eval_event.foundChannel[lastCh] == 0) ) return FALSE;
2066 
2067  // check now for coincidences;
2068  // here: assume that corresponding detectors have the ID's
2069  // firstCh, lastCh
2070  // search the next nearest e+ coincidence with respect to the masterChannel
2071  // firstCh makes the timing
2072  for ( i = 0; i < tdc_eval_event.foundChannel[firstCh]; i++ ){
2073  for ( j = 0; j < tdc_eval_event.foundChannel[lastCh]; j++ ){
2074  difftime = abs(tdc_eval_event.tdc_event[firstCh][i] - tdc_eval_event.tdc_event[lastCh][j]);
2075 
2076  if ( difftime < coincWindow ){
2077  difftime_now = tdc_eval_event.tdc_event[firstCh][i] - tdc_eval_event.tdc_event[masterChannel][masterIndex];
2078  if ( difftime_now < decWindow && difftime_now > 0){
2079  if ( difftime_now < difftime_last ){
2080  difftime_last = difftime_now;
2081  *channel = firstCh;
2082  *ind = i;
2083  }
2084  }
2085  }
2086  }
2087  }
2088  }
2089 
2090  if ( *channel == -1 ) return FALSE; // we didn't find a decay event
2091 
2092  return TRUE; // if we come to this point we found a positron event
2093 }
2094 /********************************************************************\
2095 
2096  Readout routines for different events
2097 
2098 \********************************************************************/
2099 
2100 /*-- Trigger event routines ----------------------------------------*/
2101 
2102 INT poll_event(INT source, INT count, BOOL test)
2103 /* Polling routine for events. Returns TRUE if event
2104  is available. If test equals TRUE, don't return. The test
2105  flag is used to time the polling */
2106 {
2107  //frontend_loop();
2108  if ( vme_stats.poll_counts == 0 ) ss_sleep(100); //if count==1 first call of poll_event from mfe.c
2110  if ( (p_read != p_write) && !test ){
2111  //fprintf(fp, "p_read = 0x%x, p_write = 0x%x\n", p_read, p_write);
2112  return 1;
2113  }
2114  return 0;
2115 }
2116 
2117 /*-- Interrupt configuration ---------------------------------------*/
2118 
2119 INT interrupt_configure(INT cmd, INT source, PTYPE adr)
2120 {
2121  switch(cmd)
2122  {
2123  case CMD_INTERRUPT_ENABLE:
2124  break;
2125  case CMD_INTERRUPT_DISABLE:
2126  break;
2127  case CMD_INTERRUPT_ATTACH:
2128  break;
2129  case CMD_INTERRUPT_DETACH:
2130  break;
2131  }
2132  return SUCCESS;
2133 }
2134 
2135 /*-- Event readout -------------------------------------------------*/
2141 INT read_trigger_event(char *pevent, INT off)
2142 {
2143 INT i;
2144 DWORD *pdata;
2145 DWORD ndata;
2146 /*
2147  // SUPER event does not work properly, has to be checked...
2148  //init bank structure, Super event
2149  if ( off == 0 ){
2150  // FIRST event of Super event
2151  bk_init(pevent);
2152  bk_create(pevent, "TDC0", TID_DWORD, &pdata);
2153  }
2154  else if ( off == -1 ){
2155  bk_close(pevent, pdata); //close the super event if off=-1, from mfe.c
2156  return bk_size(pevent);
2157  }
2158 */
2159  //init bank structure
2160  bk_init(pevent);
2161  bk_create(pevent, "TDC0", TID_DWORD, (void**)&pdata);
2162 
2163  // read data from output buffer;
2164  if (p_read == &databuffer[DATABUFFER_SIZE]) //we are 4 bytes off the end of the data buffer, jump
2165  p_read = &databuffer[0]; //to the beginning of the data buffer
2166 
2167  if ( ( *p_read & NEW_EVENT_MASK) != NEW_EVENT_MASK ) return 0; //causes event rate to be 0
2168  //this happens if the read pointer is
2169  //out of sync to the write pointer
2170  ndata = (*p_read & 0x0000FFFF) + 1; //the first entry in the data buffer contains the event size - 1
2171  //fprintf(fp,"eventSize = %d, p_read=0x%08x, p_write=0x%08x\n",ndata, p_read, p_write);
2172  for (i=0; i < ndata; i++){
2173  if (p_read < &databuffer[DATABUFFER_SIZE]){
2174  *pdata++ = *p_read;
2175  *p_read = 0;
2176  p_read++;
2177  }
2178  else{ //jump to beginning of ring buffer
2179  p_read = &databuffer[0];
2180  *pdata++ = *p_read;
2181  *p_read = 0;
2182  p_read++;
2183  }
2184  }
2185 
2187 /*
2188  if (off == 0){
2189  // Compute the proper event length on the FIRST event in the Super Event
2190  // N_TDC correspond to the !! N_TDC DWORD above !!
2191  // sizeof(BANK_HEADER) + sizeof(BANK) will make the 16 bytes header
2192  // sizeof(DWORD) is defined by the TID_DWORD in bk_create()
2193  return N_TDC * sizeof(DWORD) + sizeof(BANK_HEADER) + sizeof(BANK);
2194  }
2195  else{
2196  // Return the data section size only
2197  // sizeof(DWORD) is defined by the TID_DWORD in bk_create()
2198 
2199  return N_TDC * sizeof(DWORD);
2200  }
2201 */
2202  bk_close(pevent, pdata);
2203  return bk_size(pevent);
2204 }
2205 
2220 INT read_scaler_event(char *pevent, INT off)
2221 {
2222 int status;
2223 u_int32_t data[100], channel;
2224 DWORD *pdata, i;
2225 
2226  /* init bank structure */
2227  bk_init(pevent);
2228 
2229  /* create SCL0 bank */
2230  bk_create(pevent, "SCL0", TID_DWORD, (void**)&pdata);
2231 
2232  /* read out scaler module */
2233 #ifdef HAVE_TEST_RUN
2234  for (i = 0; i<N_SCALER ; i++){
2235  /*---------------------------------------------------------
2236  simulate the case when user bits and channel number are sent
2237  in the first 8 bits, scaler data in the remaining 24 bits
2238  ---------------------------------------------------------
2239  */
2241  channel = i << 24;
2242  else
2243  channel = 0;
2244  *pdata++ = (100 + rand()%40-20) | channel;
2245  }
2246 #else
2247  //read 1st scaler
2248  if ( flag_scaler_address_0){
2250  if ( status != 0 ){
2251  for ( i = 0; i<N_SCALER_MODULE; i++)
2252  *pdata++ = -1;
2253  cm_msg(MERROR, "read_scaler_event", "Error reading data from VME Scaler SIS3820!");
2254  cm_yield(0);
2255  }
2256  else
2257  for ( i = 0; i<N_SCALER_MODULE; i++)
2258  *pdata++ = data[i];
2259  }
2260  else //scaler disabled or not present
2261  for ( i = 0; i<N_SCALER_MODULE; i++)
2262  *pdata++ = 0;
2263 
2264  //read 2nd scaler
2265  if ( flag_scaler_address_1){
2266  status = sis3820_scaler_read( hdev, SIS3820_ADDRESS_1, A32BLT32, N_SCALER_MODULE, data);
2267  if ( status != 0 ){
2268  for ( i = 0; i<N_SCALER_MODULE; i++)
2269  *pdata++ = -1;
2270  cm_msg(MERROR, "read_scaler_event", "Error reading data from VME Scaler SIS3820!");
2271  cm_yield(0);
2272  }
2273  else
2274  for ( i = 0; i<N_SCALER_MODULE; i++)
2275  *pdata++ = data[i];
2276  }
2277  else //scaler disabled or not present
2278  for ( i = 0; i<N_SCALER_MODULE; i++)
2279  *pdata++ = 0;
2280 
2281 #endif
2282 
2283  bk_close(pevent, pdata);
2284  return bk_size(pevent);
2285 }
2292 INT read_slowcontrol_event(char *pevent, INT off)
2293 {
2294 INT i, n_max;
2295 float *pdata;
2296 
2297  /* init bank structure */
2298  bk_init(pevent);
2299 
2300  /* --- beamline demand values ----------- */
2301  bk_create(pevent, "DBEA", TID_FLOAT, (void**)&pdata);
2302  n_max = sizeof(beamline_event.demand)/sizeof(float);
2303  for (i = 0; i < n_max; i++)
2304  *pdata++ = beamline_event.demand[i];
2305  bk_close(pevent, pdata);
2306 
2307  /* --- beamline measured values ---------- */
2308  bk_create(pevent, "MBEA", TID_FLOAT, (void**)&pdata);
2309  n_max = sizeof(beamline_event.measured)/sizeof(float);
2310  for (i = 0; i < n_max; i++)
2311  *pdata++ = beamline_event.measured[i];
2312  bk_close(pevent, pdata);
2313 
2314  /* --- lemvac measured values ---------- */
2315  bk_create(pevent, "MVAC", TID_FLOAT, (void**)&pdata);
2316  n_max = sizeof(lemvac_event.input)/sizeof(float);
2317  for (i = 0; i < n_max; i++)
2318  *pdata++ = lemvac_event.input[i];
2319  bk_close(pevent, pdata);
2320 
2321  /* --- Moderator Cryo measured values ---------- */
2322  bk_create(pevent, "MMOD", TID_FLOAT, (void**)&pdata);
2323  n_max = sizeof(moddy_event.input)/sizeof(float);
2324  for (i = 0; i < n_max; i++)
2325  *pdata++ = moddy_event.input[i];
2326  bk_close(pevent, pdata);
2327 
2328  /* --- Sample Cryo measured values ---------- */
2329  bk_create(pevent, "MSAM", TID_FLOAT, (void**)&pdata);
2330  n_max = sizeof(sample_event.input)/sizeof(float);
2331 /*//as35
2332  if (strstr(info.sample_cryo, "Oven"))
2333  sample_event.input[0] = oven_event.input[0];
2334 */
2335  if (strstr(info.sample_cryo, "Omega"))
2336  sample_event.input[0] = omega_event.input[0]+273.16; // Omega temperature in °C whereas sample temp. should be in K
2337  for (i = 0; i < n_max; i++)
2338  *pdata++ = sample_event.input[i];
2339  bk_close(pevent, pdata);
2340 
2341  /* --- SCS2001M measured values ---------- */
2342  bk_create(pevent, "M900", TID_FLOAT, (void**)&pdata);
2343  n_max = sizeof(scs2001m_event.input)/sizeof(float);
2344  for (i = 0; i < n_max; i++)
2345  *pdata++ = scs2001m_event.input[i];
2346  bk_close(pevent, pdata);
2347 
2348  /* --- HV transport (FUG) measured values ---------- */
2349  bk_create(pevent, "MHVT", TID_FLOAT, (void**)&pdata);
2350  n_max = sizeof(hv_event.measured)/sizeof(float);
2351  for (i = 0; i < n_max; i++)
2352  *pdata++ = hv_event.measured[i];
2353  bk_close(pevent, pdata);
2354 
2355  /* --- HV Detectors measured values ---------- */
2356  bk_create(pevent, "MHVD", TID_FLOAT, (void**)&pdata);
2357  n_max = sizeof(hvdet_event.measured)/sizeof(float);
2358  for (i = 0; i < n_max; i++)
2359  *pdata++ = hvdet_event.measured[i];
2360  bk_close(pevent, pdata);
2361 
2362  return bk_size(pevent);
2363 }
2364 
2365 /* -------------- other functions -----------
2366 void scaler_mode(u_int32_t module_address )
2367 int init_sis3820(u_int32_t module_address)
2368 int init_v1190(u_int32_t module_address)
2369 */
2370 
2383 void scaler_mode(u_int32_t module_address)
2384 {
2385  INT size, status;
2386  u_int32_t control;
2387  HNDLE hDB, hkey;
2388 
2389  cm_get_experiment_database(&hDB, NULL);
2390 
2391  status = 0;
2392  control = 0;
2393 
2394  size = sizeof(scaler_settings);
2395  db_find_key(hDB, 0, "/Equipment/Scaler/Settings", &hkey);
2396  db_get_record(hDB, hkey, &scaler_settings, &size, 0);
2397 
2400  else
2402 
2403  status = sis3820_operation_mode_write( hdev, module_address, control);
2404  if ( status !=0) {
2405  cm_msg(MERROR, "scaler_mode", "Error on setting mode of SIS3820, return code %x\n", status);
2406  cm_yield(0);
2407  }
2408 
2410  status = sis3820_control_write( hdev, module_address, CTRL_REFERENCE_CH1_ENABLE);
2411  else
2412  status = sis3820_control_write( hdev, module_address, CTRL_REFERENCE_CH1_DISABLE);
2413 
2414  if ( status !=0) {
2415  cm_msg(MERROR, "scaler_mode", "Error on setting control status of SIS3820, return code %x\n", status);
2416  cm_yield(0);
2417  }
2418 
2419  /* read control status and operation mode */
2420  status = sis3820_control_read( hdev, module_address, &control);
2421  if ( status !=0)
2422  cm_msg(MERROR, "scaler_mode", "Error on reading control status of SIS3820, return code %x\n", status);
2423  else
2424  cm_msg(MINFO,"scaler_mode","SIS3820 control status reads: 0x%8.8x \n",control);
2425  cm_yield(0);
2426 
2427  status =sis3820_operation_mode_read( hdev, module_address, &control);
2428  if ( status != 0)
2429  cm_msg(MERROR, "scaler_mode", "Error on reading operation mode of SIS3820, return code %x\n", status);
2430  else
2431  cm_msg(MINFO,"scaler_mode","SIS3820 operation mode reads: 0x%8.8x \n",control);
2432  cm_yield(0);
2433 
2434 }
2435 
2452 int init_sis3820(u_int32_t module_address)
2453 {
2454  int status;
2455  u_int32_t modid, control, mode;
2456 
2457  /* reset SIS3820 */
2458  status = sis3820_key_reset( hdev, module_address);
2459  if ( status !=0){
2460  cm_msg(MERROR, "frontend_init",
2461  "Error on access to SIS3820 0x%8.8x, key reset failed, return code %x\n", module_address, status);
2462  cm_yield(0);
2463  return FE_ERR_HW;
2464  }
2465 
2466  status = 0;
2467  status += sis3820_modid_read( hdev, module_address, &modid);
2468  status += sis3820_control_read( hdev, module_address, &control);
2469  status += sis3820_operation_mode_read( hdev, module_address, &mode);
2470  if ( status !=0){
2471  cm_msg(MERROR, "frontend_init",
2472  "Error on access to SIS3820, couldn't get module info, return code %x\n", status);
2473  cm_yield(0);
2474  return FE_ERR_HW;
2475  }
2476  cm_msg(MINFO,"frontend_init", "SIS3820 modid and firmware = 0x%8.8x", modid);
2477  cm_msg(MINFO,"frontend_init", "SIS3820 control status = 0x%8.8x", control);
2478  cm_msg(MINFO,"frontend_init", "SIS3820 operation mode = 0x%8.8x", mode);
2479  cm_yield(0);
2480 
2481  /* enable SIS3820 for counting, default mode (scaler, 32 bit) */
2482  status = sis3820_key_enable( hdev, module_address);
2483  if ( status !=0){
2484  cm_msg(MERROR, "frontend_init",
2485  "Error on access to SIS3820, key enable failed, return code %x\n", status);
2486  cm_yield(0);
2487  return FE_ERR_HW;
2488  }
2489  cm_msg(MINFO, "frontent_init","SIS3820 enabled for counting");
2490  cm_yield(0);
2491 
2492  return FE_SUCCESS;
2493 }
2494 /*----------------------------------------------------------------------*/
2503 int init_v1190(u_int32_t module_address)
2504 {
2505 u_int16_t data;
2506 int return_code;
2507 
2508 #ifdef HAVE_TEST_RUN
2509  return FE_SUCCESS;
2510 #endif
2511  /* reset module to its default configuration */
2512  data = 0x0;
2513  return_code = vme_A32D16_write(hdev, module_address+V1190_MODULE_RESET, data) ;
2514  cm_msg(MINFO, "init_v1190","V1190 Module Reset: return_code = 0x%08x", return_code );
2515  cm_yield(0);
2516  if ( return_code != 0x0 ) return FE_ERR_HW;
2517  sleep(1);
2518 
2519  /* set leading edge mode */
2520  return_code = vme_A32D16_write(hdev, module_address+V1190_OPCODE_ADDRESS, V1190_SET_DETECTION);
2521  cm_msg(MINFO, "init_v1190","V1190 Set_Detection: return_code = 0x%08x", return_code );
2522  cm_yield(0);
2523  if ( return_code != 0x0 ) return FE_ERR_HW;
2524  return_code = vme_A32D16_write(hdev, module_address+V1190_OPCODE_ADDRESS, V1190_EDGE_LEADING_MODE);
2525  cm_msg(MINFO, "init_v1190", "V1190 Set_to_Leading_Edge: return_code = 0x%08x", return_code );
2526  cm_yield(0);
2527  if ( return_code != 0x0 ) return FE_ERR_HW;
2528  sleep(1);
2529 
2530  /* set 200ps LSB */
2531  return_code = vme_A32D16_write(hdev, module_address+V1190_OPCODE_ADDRESS, V1190_SET_TR_LEAD_LSB);
2532  cm_msg(MINFO, "init_v1190", "V1190 Set_LSB: return_code = 0x%08x", return_code );
2533  cm_yield(0);
2534  if ( return_code != 0x0 ) return FE_ERR_HW;
2535  return_code = vme_A32D16_write(hdev, module_address+V1190_OPCODE_ADDRESS, V1190_LSB_200PS);
2536  cm_msg(MINFO, "init_v1190", "V1190 Set_LSB_200ps: return_code = 0x%08x", return_code );
2537  cm_yield(0);
2538  if ( return_code != 0x0 ) return FE_ERR_HW;
2539  sleep(1);
2540 
2541  /* disable all channels if set in ODB */
2543  return_code = vme_A32D16_write(hdev, module_address+V1190_OPCODE_ADDRESS, V1190_DISABLE_ALL_CHANNEL);
2544  cm_msg(MINFO, "init_v1190", "V1190 Disable all channels: return_code = 0x%08x", return_code);
2545  cm_yield(0);
2546  sleep(1);
2547  }
2548 
2549  /* set continuous storage mode */
2550  return_code = vme_A32D16_write(hdev, module_address+V1190_OPCODE_ADDRESS, V1190_CONT_STOR);
2551  cm_msg(MINFO, "init_v1190","V1190 Set_Continuous storage: return_code = 0x%08x", return_code );
2552  cm_yield(0);
2553 
2554  if ( return_code != 0x0 ) return FE_ERR_HW;
2555  sleep(1);
2556 
2557  /* set almost full level */
2558  return_code = vme_A32D16_write(hdev, module_address+V1190_ALMOST_FULL_LEVEL, ALMOST_FULL_LEVEL);
2559  cm_msg(MINFO, "init_v1190","V1190 Set_Almost_Full_Level: return_code = 0x%08x", return_code );
2560  cm_yield(0);
2561 
2562  /* enable VME Bus error to indicate that Output Buffer is empty */
2563  data = 0x21;
2564  return_code = vme_A32D16_write(hdev, module_address+V1190_CONTROL_REGISTER, data);
2565  cm_msg(MINFO, "init_v1190","V1190 Control_Register: return_code = 0x%08x", return_code );
2566  cm_yield(0);
2567 
2568  /* read module status */
2569  return_code = vme_A32D16_read(hdev, module_address+V1190_ALMOST_FULL_LEVEL, &data ) ;
2570  cm_msg(MINFO, "init_v1190", "V1190 Almost Full Level: return_code = 0x%08x", return_code);
2571  cm_msg(MINFO, "init_v1190", "V1190 Almost Full Level: data = 0x%04x", data );
2572  cm_yield(0);
2573 
2574  return_code = vme_A32D16_read(hdev, module_address+V1190_STATUS_REGISTER, &data ) ;
2575  cm_msg(MINFO, "init_v1190", "V1190 Modul status: return_code = 0x%08x", return_code);
2576  cm_msg(MINFO, "init_v1190", "V1190 Modul status: data = 0x%04x", data );
2577  cm_yield(0);
2578 
2579  return_code = vme_A32D16_read(hdev, module_address+V1190_CONTROL_REGISTER, &data ) ;
2580  cm_msg(MINFO, "init_v1190", "V1190 Control Register: return_code = 0x%08x", return_code);
2581  cm_msg(MINFO, "init_v1190", "V1190 Control Register: data = 0x%04x", data );
2582  cm_yield(0);
2583 
2584  if ( return_code != 0x0 ) return FE_ERR_HW;
2585 
2586  return FE_SUCCESS;
2587 }
2588 /*----------------------------------------------------------------------*/
2594 {
2595  struct timeval tvNowTime, tvDiffTime;
2596 
2597  gettimeofday(&tvNowTime, 0);
2598 
2599  timersub(&tvNowTime, &tvLastTime, &tvDiffTime);
2600 
2601  if (1000000*tvDiffTime.tv_sec+tvDiffTime.tv_usec > trigger_settings.period_onpuls_usec_){
2602  s3100_control_write(hdev, 0x80, 1<<28); // 12.5 ns NIM pulse on output 1
2603  gettimeofday(&tvLastTime, 0);
2604  flag_on_puls = TRUE;
2605  }
2606 
2607  if (flag_on_puls){
2608 // gettimeofday(&tvNowTime, 0);
2609  timersub(&tvNowTime, &tvLastTime, &tvDiffTime);
2610 
2611  if (1000000*tvDiffTime.tv_sec+tvDiffTime.tv_usec > trigger_settings.delay_offpuls_usec_){//turn puls off
2612  s3100_control_write(hdev, 0x80, 1<<29); // 12.5 ns NIM pulse on output 2
2613  flag_on_puls = FALSE;
2614  }
2615  }
2616 
2617  return;
2618 }
2619 
2620 /*----------------------------------------------------------------------*/
2624 // void vacuum_cleaner()
2625 // {
2626 // HNDLE hDB, hkey;
2627 // DWORD nowtime, difftime, deltapulsetime;
2628 // int size, status;
2629 // float pulse_hv_1, pulse_hv_2, ramp, current_limit;
2630 //
2631 // nowtime = ss_millitime();
2632 // difftime = nowtime - lasttime;
2633 //
2634 // /* if ( hv_vaccleaner.deltatime_msec_ > 0.99* hv_vaccleaner.period_msec_)
2635 // return FALSE;*/
2636 //
2637 // if ( difftime > hv_vaccleaner.period_msec_ && !vacuum_cleaner_active){
2638 // /* set current limit and ramping speed */
2639 // vacuum_cleaner_active = TRUE;
2640 // ramp = 0.;
2641 // current_limit = 0.6;
2642 // size = sizeof(float);
2643 // cm_get_experiment_database(&hDB, NULL);
2644 // db_find_key(hDB, 0, "/Equipment/HV/Settings/Ramp Up Speed", &hkey);
2645 // db_set_data_index(hDB, hkey, &ramp, size, hv_vaccleaner.channel_1, TID_FLOAT);
2646 // db_find_key(hDB, 0, "/Equipment/HV/Settings/Ramp Down Speed", &hkey);
2647 // db_set_data_index(hDB, hkey, &ramp, size, hv_vaccleaner.channel_1, TID_FLOAT);
2648 // db_find_key(hDB, 0, "/Equipment/HV/Settings/Current Limit", &hkey);
2649 // db_set_data_index(hDB, hkey, &current_limit, size, hv_vaccleaner.channel_1, TID_FLOAT);
2650 //
2651 // db_find_key(hDB, 0, "/Equipment/HV/Settings/Ramp Up Speed", &hkey);
2652 // db_set_data_index(hDB, hkey, &ramp, size, hv_vaccleaner.channel_2, TID_FLOAT);
2653 // db_find_key(hDB, 0, "/Equipment/HV/Settings/Ramp Down Speed", &hkey);
2654 // db_set_data_index(hDB, hkey, &ramp, size, hv_vaccleaner.channel_2, TID_FLOAT);
2655 // db_find_key(hDB, 0, "/Equipment/HV/Settings/Current Limit", &hkey);
2656 // db_set_data_index(hDB, hkey, &current_limit, size, hv_vaccleaner.channel_2, TID_FLOAT);
2657 //
2658 // /* change pulse direction each time automatically */
2659 // /* hv_vaccleaner.deltau_1_kv_ = -1.0*hv_vaccleaner.deltau_1_kv_;
2660 // hv_vaccleaner.deltau_2_kv_ = -1.0*hv_vaccleaner.deltau_2_kv_;*/
2661 // ra_hv_1 = hv_event.demand[hv_vaccleaner.channel_1];
2662 // pulse_hv_1 = ra_hv_1 + hv_vaccleaner.deltau_1_kv_;
2663 // ra_hv_2 = hv_event.demand[hv_vaccleaner.channel_2];
2664 // pulse_hv_2 = ra_hv_2 + hv_vaccleaner.deltau_2_kv_;
2665 //
2666 // lasttime = ss_millitime();
2667 // if ( pulse_hv_1 > 0 && pulse_hv_2 > 0 ){
2668 // /* change RAs to pulse_hv */
2669 // db_find_key(hDB, 0, "/Equipment/HV/Variables/Demand", &hkey);
2670 // db_set_data_index(hDB, hkey, &pulse_hv_1, size, hv_vaccleaner.channel_1, TID_FLOAT);
2671 // db_set_data_index(hDB, hkey, &pulse_hv_2, size, hv_vaccleaner.channel_2, TID_FLOAT);
2672 // }
2673 // return;
2674 // }
2675 //
2676 // deltapulsetime = ss_millitime() - lasttime;
2677 // if ( deltapulsetime > hv_vaccleaner.deltatime_msec_ && vacuum_cleaner_active){
2678 // /* restore old RA values */
2679 // db_set_data_index(hDB, hkey, &ra_hv_1, size, hv_vaccleaner.channel_1, TID_FLOAT);
2680 // db_set_data_index(hDB, hkey, &ra_hv_2, size, hv_vaccleaner.channel_2, TID_FLOAT);
2681 // ss_sleep(1000); /* wait 1000ms to ramp up HV */
2682 //
2683 // ramp = 0.1;
2684 // current_limit = 0.001;
2685 // size = sizeof(float);
2686 // db_find_key(hDB, 0, "/Equipment/HV/Settings/Ramp Up Speed", &hkey);
2687 // db_set_data_index(hDB, hkey, &ramp, size, hv_vaccleaner.channel_1, TID_FLOAT);
2688 // db_find_key(hDB, 0, "/Equipment/HV/Settings/Current Limit", &hkey);
2689 // db_set_data_index(hDB, hkey, &current_limit, size, hv_vaccleaner.channel_1, TID_FLOAT);
2690 //
2691 // db_find_key(hDB, 0, "/Equipment/HV/Settings/Ramp Up Speed", &hkey);
2692 // db_set_data_index(hDB, hkey, &ramp, size, hv_vaccleaner.channel_2, TID_FLOAT);
2693 // db_find_key(hDB, 0, "/Equipment/HV/Settings/Current Limit", &hkey);
2694 // db_set_data_index(hDB, hkey, &current_limit, size, hv_vaccleaner.channel_2, TID_FLOAT);
2695 //
2696 // vacuum_cleaner_active = FALSE;
2697 //
2698 // #ifndef HAVE_TEST_RUN
2699 // // clear TDC
2700 // status = vme_A32D16_write(hdev, V1190_ADDRESS+V1190_SOFTWARE_CLEAR, 0x0);
2701 // if ( status !=0)
2702 // cm_msg(MERROR, "vacuum_cleaner",
2703 // "vacuum_cleaner: Error on resetting TDC V1190, return code %x\n", status);
2704 // cm_yield(0);
2705 // #endif
2706 // }
2707 //
2708 // return;
2709 // }
2710 /* -----------------------------------------------------------------------
2711  E O F vme_fe.c
2712  ------------------------------------------------------------------------
2713 */
double frontend_loop_counts
Definition: nemu_experim.h:105
#define BCR1
Definition: nemu_experim.h:22
U_LONG pileup_end(INT pileupWindow)
Definition: vme_fe.c:1474
static DWORD masterFlagSlowMuon
use either TD_EVENT or M2_EVENT as slow muon master
Definition: vme_fe.c:272
#define POSRDI
Definition: nemu_experim.h:39
#define POSLUO
Definition: nemu_experim.h:32
float input[21]
Definition: experim.h:2857
#define HV_DETECTORS_EVENT_STR(_name)
Definition: experim.h:5987
WORD channel
Definition: nemu_experim.h:93
#define V1190_SET_TR_LEAD_LSB
Definition: v1190.h:86
#define DIFF_TOLERANCE
Definition: vme_fe.c:216
#define BEAMLINE_EVENT_STR(_name)
Definition: experim.h:1419
float input[44]
Definition: experim.h:8605
float input[10]
Definition: experim.h:12201
#define MCP2R
Definition: nemu_experim.h:50
#define HV_EVENT_STR(_name)
Definition: experim.h:4957
BOOL positrons_active
Definition: experim.h:662
INT positron_delay
Definition: experim.h:666
INT interrupt_configure(INT cmd, INT source, PTYPE adr)
Definition: vme_fe.c:2119
#define A32BLT32
Definition: sis3820.h:206
static DWORD eventDefinedFastMuon
bit pattern containing trigger mode for fast muons (BC-M1)
Definition: vme_fe.c:274
INFO info
Definition: vme_fe.c:206
DWORD thisTimeSlowMuon
Definition: vme_fe.c:251
HV_SETTINGS hv_settings
Definition: vme_fe.c:203
static BOOL flag_external_on
flag to indicate &quot;on/off&quot;, &quot;red/green&quot; mode
Definition: vme_fe.c:281
#define BC_EVENT
Definition: vme_fe.c:222
double channelCounts[N_TDC_CHANNELS]
Definition: nemu_experim.h:104
double run_time
Definition: nemu_experim.h:99
#define SCS2001M_EVENT_STR(_name)
Definition: experim.h:8609
float demand[40]
Definition: experim.h:1415
char * frontend_name
experiment specific ODB structures
Definition: vme_fe.c:159
#define EXTON1
Definition: nemu_experim.h:57
#define HV_DETECTORS_SETTINGS_STR(_name)
Definition: experim.h:6729
EQUIPMENT equipment[]
Definition: vme_fe.c:326
static U_LONG runTime
absolute run time in TDC LSB units
Definition: vme_fe.c:277
#define LE_POSITRON_EVENT
Definition: vme_fe.c:220
INT do_channel(INT ch, INT time)
Definition: vme_fe.c:1334
double slowMuonEvents
Definition: nemu_experim.h:101
INT max_event_size_frag
maximum event size for fragmented events (EQ_FRAGMENTED)
Definition: vme_fe.c:174
#define BCR4
Definition: nemu_experim.h:25
#define MCP2X2
Definition: nemu_experim.h:52
DWORD period_onpuls_usec_
Definition: experim.h:695
static INT t0_offset
Definition: vme_fe.c:280
static BOOL flag_scaler_address_1
flags to indicate status of VME scalers
Definition: vme_fe.c:282
#define POSBUI
Definition: nemu_experim.h:36
#define BCL4
Definition: nemu_experim.h:21
#define LEMVAC_SETTINGS_STR(_name)
Definition: experim.h:4063
static DWORD * databuffer
ring buffer for TDC data
Definition: vme_fe.c:270
static INT hdev
handle for VME-PCI device
Definition: vme_fe.c:269
struct TRIGGER_SETTINGS::@20 event_2_settings
#define V1190_ALMFULL_BIT
Definition: v1190.h:193
BOOL simulation_flag
Definition: experim.h:667
BOOL event_2_active
Definition: experim.h:659
void scaler_mode(u_int32_t module_address)
Definition: vme_fe.c:2383
DWORD doEvaluateFastMuonEvent
Definition: vme_fe.c:253
int sis3820_key_disable(int device, u_int32_t sis3820_base)
Definition: sis3820.c:84
#define TD_EVENT
Event flags.
Definition: vme_fe.c:219
HV_DETECTORS_EVENT hvdet_event
Definition: vme_fe.c:202
#define MCP2Y2
Definition: nemu_experim.h:54
U_LONG endBeamCounterEvent
Definition: vme_fe.c:260
#define HV_SETTINGS_STR(_name)
Definition: experim.h:5460
OMEGA_EVENT omega_event
Definition: vme_fe.c:205
#define SAMPLECRYO_SETTINGS_STR(_name)
Definition: experim.h:3192
#define SIS3820_CONTROL_INPUT_MODE3
Definition: sis3820.h:179
#define N_HITS
a single detector may have up to N_HITS hits for event evaluation
Definition: nemu_experim.h:65
BOOL event_1_active
Definition: experim.h:658
BOOL beamcounter_active
Definition: experim.h:663
#define EXTOFF1
Definition: nemu_experim.h:58
static DWORD dataWindowFastMuon
Definition: vme_fe.c:279
double mcp1_good
Definition: nemu_experim.h:103
static DWORD dataWindowSlowMuon
Definition: vme_fe.c:279
#define V1190_MODULE_RESET
Definition: v1190.h:39
SCALER_SETTINGS scaler_settings
Definition: vme_fe.c:189
INT end_of_run(INT run_number, char *error)
Definition: vme_fe.c:858
#define DATABUFFER_SIZE
set size of FiFo (ring) buffer, 2^17
Definition: vme_fe.c:215
#define POSMCP1O
Definition: nemu_experim.h:27
#define SIS3820_SCALER_DATA_FORMAT_32BIT
Definition: sis3820.h:162
#define EXTON1_FLAG
flag for &quot;red/green&quot;, &quot;on/off&quot; mode: ON
Definition: nemu_experim.h:68
#define SIS3820_CONTROL_INPUT_MODE0
Definition: sis3820.h:176
int sis3820_key_enable(int device, u_int32_t sis3820_base)
Definition: sis3820.c:62
DWORD doEvaluateSlowMuonEvent
bit pattern for trigger condition:
Definition: vme_fe.c:252
INT pileup[N_TDC_CHANNELS][N_HITS]
save information for each hit if it had a pre pileup or not
Definition: vme_fe.c:248
#define V1190_CONTROL_REGISTER
Definition: v1190.h:31
#define SIS3820_SCALER_DATA_FORMAT_24BIT
Definition: sis3820.h:163
INT foundChannel[N_TDC_CHANNELS]
count appearance of channel i
Definition: vme_fe.c:245
RUNINFO runinfo
/Runinfo ODB key, defined in from midas.h
Definition: vme_fe.c:193
int init_v1190(u_int32_t module_address)
Definition: vme_fe.c:2503
INT indexSlowMuonSet
Definition: vme_fe.c:250
#define POSTDI
Definition: nemu_experim.h:44
static BOOL flag_on_puls
flag to indicate that &quot;puls&quot; was turned on, &quot;on/off&quot; or &quot;red/green&quot; mode
Definition: vme_fe.c:285
DWORD lastTimeFastMuon
Definition: vme_fe.c:251
INT frontend_init()
Definition: vme_fe.c:416
BEAMLINE_EVENT beamline_event
for slow control parameters
Definition: vme_fe.c:196
unsigned long long U_LONG
GNU C-Compiler 64bit integer.
Definition: nemu_experim.h:87
INT eventType
Definition: vme_fe.c:239
static TDC_EVAL_EVENT tdc_eval_event
Definition: vme_fe.c:267
INT lastBeamCounterEventPileup
Definition: vme_fe.c:262
#define TDC_BIT_RANGE
2^19 is the bit range of the TDC in 100ps and 200ps mode
Definition: nemu_experim.h:70
static DWORD * p_read
Definition: vme_fe.c:271
#define V1190_DISABLE_ALL_CHANNEL
Definition: v1190.h:111
#define MCP2Y1
Definition: nemu_experim.h:53
#define SIS3820_ADDRESS_1
VME address of 2nd scaler module.
Definition: vme_fe.c:211
float measured[16]
Definition: experim.h:4953
#define BCL1
Definition: nemu_experim.h:18
#define CTRL_REFERENCE_CH1_DISABLE
Definition: sis3820.h:147
#define VME_STATS_STR(_name)
Definition: nemu_experim.h:112
INT frontend_loop()
Definition: vme_fe.c:949
#define MODCRYO_EVENT_STR(_name)
Definition: experim.h:1891
#define BCL3
Definition: nemu_experim.h:20
DWORD tof_bc_pileup_window
Definition: experim.h:693
INT lastMasterEvent1or2Pileup
Definition: vme_fe.c:263
BOOL check_tof_and_pileup(INT timing, INT tofWindow, INT firstCh, INT lastCh, INT masterChannel, INT masterIndex, INT *channel, INT *ind)
Definition: vme_fe.c:1969
INT indexFastMuonSet
Definition: vme_fe.c:249
#define POSRUO
Definition: nemu_experim.h:42
int sis3820_operation_mode_read(int device, u_int32_t sis3820_base, u_int32_t *mode)
Definition: sis3820.c:97
INT set_t0
flag indicating if t0 has been set
Definition: vme_fe.c:243
static struct timeval tvLastTime
Definition: vme_fe.c:284
BOOL frontend_call_loop
frontend_loop is called periodically if this variable is TRUE
Definition: vme_fe.c:165
int sis3820_operation_mode_write(int device, u_int32_t sis3820_base, u_int32_t mode)
Definition: sis3820.c:165
struct TRIGGER_SETTINGS::@17 events
static INT rate[N_SCALER]
#define TRIGGER_SETTINGS_STR(_name)
Definition: experim.h:700
U_LONG endMasterEvent0
U_LONG==unsigned long long, GNU C-compiler 64bit integer.
Definition: vme_fe.c:258
HNDLE hDB
Definition: write_summary.c:97
int sis3820_control_read(int device, u_int32_t sis3820_base, u_int32_t *control_status)
Definition: sis3820.c:191
static DWORD masterChannelSlowMuon
&quot;master&quot; TDC channel for slow muons (TD or M2)
Definition: vme_fe.c:275
struct TRIGGER_SETTINGS::@19 event_1_settings
DWORD thisTimeFastMuon
Definition: vme_fe.c:251
INT max_event_size
maximum event size produced by this frontend
Definition: vme_fe.c:171
INT pause_run(INT run_number, char *error)
Definition: vme_fe.c:886
INT masterChannel
DWORD tof_bc_window
Definition: experim.h:692
#define V1190_LSB_200PS
Definition: v1190.h:163
INT tdc_data[N_TDC_CHANNELS *DATA_N_HITS]
this array is actually the Midas event
Definition: vme_fe.c:242
#define V1190_STATUS_REGISTER
Definition: v1190.h:32
INT evaluate_fast_muon_event()
Definition: vme_fe.c:1815
INT frontend_exit()
Definition: vme_fe.c:557
#define V1190_EDGE_LEADING_MODE
Definition: v1190.h:159
#define M1_POSITRON_EVENT
Definition: vme_fe.c:224
INT read_slowcontrol_event(char *pevent, INT off)
Definition: vme_fe.c:2292
BOOL event_0_active
Definition: experim.h:657
INT do_master_channel(INT ch, INT event_type)
Definition: vme_fe.c:1369
WORD buffer
Definition: v1190.h:16
DWORD data
Definition: v1190.h:13
HV_EVENT hv_event
Definition: vme_fe.c:201
INT mode
scaler mode, see scaler_mode()
Definition: vme_fe.c:283
double mcp2_good
Definition: nemu_experim.h:103
#define BCR2
Definition: nemu_experim.h:23
#define MCP2F
Definition: nemu_experim.h:49
DWORD tof_m2_window
Definition: experim.h:678
double frontend_loop_readtdc
Definition: nemu_experim.h:106
#define POSMCP1I
Definition: nemu_experim.h:26
#define DATA_N_HITS
max. of DATA_N_HITS in data file
Definition: nemu_experim.h:66
#define EVENT_1_TYPE
Event type 1 = (BC)-TD-MC2-(e+)
Definition: nemu_experim.h:76
char sample_cryo[NAME_LENGTH]
Definition: nemu_experim.h:281
#define LEMVAC_EVENT_STR(_name)
Definition: experim.h:3938
#define MODCRYO_SETTINGS_STR(_name)
Definition: experim.h:2230
MODCRYO_EVENT moddy_event
Definition: vme_fe.c:198
#define CTRL_REFERENCE_CH1_ENABLE
Definition: sis3820.h:148
WORD channel
Definition: v1190.h:14
double td_clean
Definition: nemu_experim.h:102
double mcp2_clean
Definition: nemu_experim.h:102
#define POSRUI
Definition: nemu_experim.h:41
#define EXTOFF1_FLAG
flag for &quot;red/green&quot;, &quot;on/off&quot; mode: OFF
Definition: nemu_experim.h:69
INT event_time
absolute time in event after reset of structure
Definition: vme_fe.c:244
#define POSLDO
Definition: nemu_experim.h:30
INT evaluate_slow_muon_event()
Definition: vme_fe.c:1489
BOOL mcp2_active
Definition: experim.h:675
#define BCR3
Definition: nemu_experim.h:24
INT read_scaler_event(char *pevent, INT off)
Definition: vme_fe.c:2220
INT event_buffer_size
buffer size to hold events
Definition: vme_fe.c:177
BOOL check_positron(INT decWindow, INT coincWindow, INT firstCh, INT lastCh, INT masterChannel, INT masterIndex, INT *channel, INT *ind)
Definition: vme_fe.c:2038
#define V1190_SOFTWARE_CLEAR
Definition: v1190.h:40
INT lastMasterEvent0Pileup
Definition: vme_fe.c:261
double bc_rate
Definition: experim.h:669
float input[38]
Definition: experim.h:1887
DWORD delay_daq_usec_
Definition: experim.h:697
#define POSBDO
Definition: nemu_experim.h:35
INT read_trigger_event(char *pevent, INT off)
Definition: vme_fe.c:2141
#define V1190_ALMOST_FULL_LEVEL
Definition: v1190.h:45
#define V1190_OUTPUT_BUFFER_SIZE
Definition: v1190.h:27
static BOOL flag_scaler_address_0
Definition: vme_fe.c:282
#define NEW_EVENT_MASK
Definition: nemu_experim.h:67
double fastMuonEvents
Definition: nemu_experim.h:101
INT indexFastMuon
Definition: vme_fe.c:249
#define M2_EVENT
Definition: vme_fe.c:221
#define POSBUO
Definition: nemu_experim.h:37
char * frontend_file_name
The frontend file name, don&#39;t change it.
Definition: vme_fe.c:162
int sis3820_key_reset(int device, u_int32_t sis3820_base)
Definition: sis3820.c:39
INT poll_event(INT source, INT count, BOOL test)
Definition: vme_fe.c:2102
#define V1190_ADDRESS
the VME address of the CAEN V1190 TDC
Definition: vme_fe.c:212
DWORD delay_offpuls_usec_
Definition: experim.h:696
#define MAX_NUMBER_LWORDS
max number of block data transfer */
Definition: vme_fe.c:213
double readcounts
Definition: nemu_experim.h:108
TRIGGER_SETTINGS trigger_settings
/Equipment/Trigger/Settings
Definition: vme_fe.c:188
#define N_TDC_CHANNELS
number of TDC channels
Definition: nemu_experim.h:64
#define BCL2
Definition: nemu_experim.h:19
float measured[94]
Definition: experim.h:5981
#define POSRDO
Definition: nemu_experim.h:40
#define SCALER_SETTINGS_STR(_name)
Definition: experim.h:1195
#define POSTDO
Definition: nemu_experim.h:45
#define SAMPLECRYO_EVENT_STR(_name)
Definition: experim.h:2861
DWORD data_window
Definition: experim.h:664
SAMPLECRYO_EVENT sample_event
Definition: vme_fe.c:199
#define N_SCALER
total number of scaler channels
Definition: nemu_experim.h:63
static DWORD masterChannelFastMuon
&quot;master&quot; TDC channel for BC-M1 (usually M1)
Definition: vme_fe.c:276
#define POSBDI
Definition: nemu_experim.h:34
double td_good
Definition: nemu_experim.h:103
#define N_SCALER_MODULE
number of channels of one scaler module
Definition: nemu_experim.h:62
#define MASTERLAST
timing flags
Definition: vme_fe.c:227
void OnOff_mode()
Definition: vme_fe.c:2593
double bc_clean
Definition: nemu_experim.h:102
#define V1190_OPCODE_ADDRESS
Definition: v1190.h:51
#define POSTUO
Definition: nemu_experim.h:47
BOOL enable_onoff_mode
Definition: experim.h:694
#define SCS2001M_SETTINGS_STR(_name)
Definition: experim.h:8747
#define EXP_PARAM_STR(_name)
Definition: experim.h:30
#define V1190_SET_DETECTION
Definition: v1190.h:84
float measured[40]
Definition: experim.h:1416
static VME_STATS vme_stats
Definition: vme_fe.c:266
#define EVENT_2_TYPE
Event type 2 = TD-e+-(BC), LE-muSR.
Definition: nemu_experim.h:77
double mcp1_clean
Definition: nemu_experim.h:102
DWORD data
Definition: nemu_experim.h:92
#define CLOCK
TDC channel assignments.
Definition: nemu_experim.h:15
static DWORD eventDefinedSlowMuon
bit pattern containing trigger mode for slow muons (BC-TD-M2)
Definition: vme_fe.c:273
#define BEAMLINE_SETTINGS_STR(_name)
Definition: experim.h:1570
#define MCP2X1
Definition: nemu_experim.h:51
double tdc_error_counts
Definition: nemu_experim.h:109
int sis3820_scaler_read(int device, u_int32_t sis3820_base, int mode, int nwords, u_int32_t *data)
Definition: sis3820.c:281
float input[27]
Definition: experim.h:3934
#define MCP1
Definition: nemu_experim.h:16
int sis3820_modid_read(int device, u_int32_t sis3820_base, u_int32_t *modid)
Definition: sis3820.c:178
#define POSLDI
Definition: nemu_experim.h:29
#define POSTUI
Definition: nemu_experim.h:46
INT begin_of_run(INT run_number, char *error)
Definition: vme_fe.c:589
double mcp1_rate
Definition: experim.h:668
int last_TDCtime
Definition: nemu_experim.h:100
INT eventSize
Definition: vme_fe.c:240
#define POSLUI
Definition: nemu_experim.h:31
BOOL tdc_disable_atstartup
Definition: experim.h:691
SCS2001M_EVENT scs2001m_event
Definition: vme_fe.c:200
DWORD lastTimeSlowMuon
Definition: vme_fe.c:251
#define TD
Definition: nemu_experim.h:17
#define BINNING
static U_LONG nextGoodTime
absolute run time when new events are accepted (for on/off mode)
Definition: vme_fe.c:278
INT tdc_event[N_TDC_CHANNELS][N_HITS]
Definition: vme_fe.c:246
#define M1_EVENT
Definition: vme_fe.c:223
INT clockIndex
Definition: vme_fe.c:241
#define MASTERFIRST
Definition: vme_fe.c:228
int sis3820_control_write(int device, u_int32_t sis3820_base, u_int32_t control_status)
Definition: sis3820.c:229
LEMVAC_EVENT lemvac_event
Definition: vme_fe.c:197
int init_sis3820(u_int32_t module_address)
Definition: vme_fe.c:2452
struct TRIGGER_SETTINGS::@18 event_0_settings
static TDC_PILEUP tdc_pileup
Definition: vme_fe.c:268
double poll_counts
Definition: nemu_experim.h:107
#define SIS3820_ADDRESS_0
Local definitions to connect to VME module.
Definition: vme_fe.c:210
INT indexSlowMuon
Definition: vme_fe.c:250
INT display_period
a frontend status page is displayed with this frequency in ms
Definition: vme_fe.c:168
U_LONG endMasterEvent1or2
Definition: vme_fe.c:259
#define EVENT_0_TYPE
EVENT type 0 = BC-MCP1-(e+)
Definition: nemu_experim.h:75
INT resume_run(INT run_number, char *error)
Definition: vme_fe.c:893
#define V1190_CONT_STOR
Definition: v1190.h:64
static DWORD * p_write
read and write pointers for data ring buffer
Definition: vme_fe.c:271
#define ALMOST_FULL_LEVEL
Definition: vme_fe.c:214