MIDAS
Loading...
Searching...
No Matches
fevme.cxx
Go to the documentation of this file.
1
2/********************************************************************\
3
4 Name: fevme.cxx
5 Created by: K.Olchanski
6
7 Contents: Frontend for the generic VME DAQ using CAEN ADC, TDC, TRIUMF VMEIO and VF48
8$Id$
9\********************************************************************/
10
11#include <stdio.h>
12#include <errno.h>
13#include <unistd.h>
14#include <string.h>
15#include <stdlib.h>
16#include <stdint.h>
17#include <sys/time.h>
18#include <assert.h>
19#include "midas.h"
20#include "mvmestd.h"
21
22#define HAVE_V792
23#define HAVE_V895
24#define HAVE_V1190B
25
26extern "C" {
27#ifdef HAVE_VMEIO
28#include "vme/vmeio.h"
29#endif
30#ifdef HAVE_V792
31#include "vme/v792.h"
32#endif
33#ifdef HAVE_V895
34#include "v895.h"
35#endif
36#ifdef HAVE_V1190B
37#include "vme/v1190B.h"
38#endif
39#ifdef HAVE_VF48
40#include "vme/VF48.h"
41#endif
42}
43
44/* make frontend functions callable from the C framework */
45#ifdef __cplusplus
46extern "C" {
47#endif
48
49/*-- Globals -------------------------------------------------------*/
50
51/* The frontend name (client name) as seen by other MIDAS clients */
52 char *frontend_name = "fevme";
53/* The frontend file name, don't change it */
55
56/* frontend_loop is called periodically if this variable is TRUE */
58
59/* a frontend status page is displayed with this frequency in ms */
61
62/* maximum event size produced by this frontend */
63 INT max_event_size = 100*1024;
64
65/* maximum event size for fragmented events (EQ_FRAGMENTED) */
67
68/* buffer size to hold events */
70
71 extern INT run_state;
72 extern HNDLE hDB;
73
74/*-- Function declarations -----------------------------------------*/
77 INT begin_of_run(INT run_number, char *error);
78 INT end_of_run(INT run_number, char *error);
79 INT pause_run(INT run_number, char *error);
80 INT resume_run(INT run_number, char *error);
82
83 INT read_event(char *pevent, INT off);
84/*-- Bank definitions ----------------------------------------------*/
85
86/*-- Equipment list ------------------------------------------------*/
87
89
90 {"Trigger", /* equipment name */
91 {1, TRIGGER_ALL, /* event ID, trigger mask */
92 "SYSTEM", /* event buffer */
93 EQ_POLLED, /* equipment type */
94 LAM_SOURCE(0, 0xFFFFFF), /* event source */
95 "MIDAS", /* format */
96 TRUE, /* enabled */
97 RO_RUNNING, /* read only when running */
98
99 500, /* poll for 500ms */
100 0, /* stop run after this event limit */
101 0, /* number of sub events */
102 0, /* don't log history */
103 "", "", "",}
104 ,
105 read_event, /* readout routine */
106 NULL, NULL,
107 NULL, /* bank list */
108 }
109 ,
110
111 {""}
112 };
113
114#ifdef __cplusplus
115}
116#endif
117/********************************************************************\
118 Callback routines for system transitions
119
120 These routines are called whenever a system transition like start/
121 stop of a run occurs. The routines are called on the following
122 occations:
123
124 frontend_init: When the frontend program is started. This routine
125 should initialize the hardware.
126
127 frontend_exit: When the frontend program is shut down. Can be used
128 to releas any locked resources like memory, commu-
129 nications ports etc.
130
131 begin_of_run: When a new run is started. Clear scalers, open
132 rungates, etc.
133
134 end_of_run: Called on a request to stop a run. Can send
135 end-of-run event and close run gates.
136
137 pause_run: When a run is paused. Should disable trigger events.
138
139 resume_run: When a run is resumed. Should enable trigger events.
140\********************************************************************/
141
143
144int gVmeioBase = 0x780000;
145int gAdcBase = 0x110000;
146int gDisBase[] = { 0xE00000, 0 };
147int gTdcBase = 0xf10000;
148int gVF48base = 0xa00000;
149
155
161
163{
164 pdata[0] = (value&0x000000FF)>>0;
165 pdata[1] = (value&0x0000FF00)>>8;
166 pdata[2] = (value&0x00FF0000)>>16;
167 pdata[3] = (value&0xFF000000)>>24;
168}
169
171{
172 int status;
173 uint32_t value = 0;
174 int size = 4;
175 HNDLE hkey;
177 if (status != SUCCESS)
178 {
179 cm_msg (MERROR,frontend_name,"Cannot read \'%s\'[%d] from odb, status %d",name,index,status);
180 return defaultValue;
181 }
182 return value;
183}
184
186{
187#ifdef HAVE_VMEIO
189#endif
190 return 0;
191}
192
193
195{
196#ifdef HAVE_VMEIO
198#endif
199 return 0;
200}
201
203{
204#ifdef HAVE_VMEIO
207 printf("VMEIO at 0x%x CSR is 0x%x\n",gVmeioBase,vmeio_CsrRead(gVme,gVmeioBase));
208#endif
209
210#ifdef HAVE_V792
213#endif
214
215#ifdef HAVE_V895
216 for (int i=0; gDisBase[i] != 0; i++)
217 {
219
220 v895_writeReg16(gVme,gDisBase[i],0x40,255); // width 0-7
221 v895_writeReg16(gVme,gDisBase[i],0x42,255); // width 8-15
222 v895_writeReg16(gVme,gDisBase[i],0x48,56); // majority
223 v895_writeReg16(gVme,gDisBase[i],0x4A,0xFFFF); // enable all channels
224 //v895_writeReg8(gVme,gDisBase[i],0x4A,0x0000); // enable all channels
225 for (int j=0; j<16; j++)
226 {
227 int thr_mV = 12;
228 v895_writeReg16(gVme,gDisBase[i],j*2,thr_mV); // threshold in mV
229 }
230 //v895_TestPulse(gVme,gDisBase[i]); // fire test pulse
231
232 //v895_writeReg16(gVme,gDisBase[i],0*2,250); // threshold in mV
233 }
234#endif
235
236#ifdef HAVE_V1190B
239#endif
240
241#ifdef HAVE_VF48
243 printf("VF48 at 0x%x CSR is 0x%x\n",gVF48base,VF48_CsrRead(gVme,gVF48base));
244#endif
245
246 return SUCCESS;
247}
248
249/*-- Frontend Init -------------------------------------------------*/
250
252{
253 int status;
254
257
258 status = mvme_open(&gVme,0);
260
262
264
265 return status;
266}
267
268static int gHaveRun = 0;
269
270/*-- Frontend Exit -------------------------------------------------*/
271
273{
274 gHaveRun = 0;
276
278
279 return SUCCESS;
280}
281
282/*-- Begin of Run --------------------------------------------------*/
283
285{
286 gHaveRun = 1;
287 printf("begin run %d\n",run_number);
288
290
292 return SUCCESS;
293}
294
295/*-- End of Run ----------------------------------------------------*/
297{
298 static bool gInsideEndRun = false;
299
300 if (gInsideEndRun)
301 {
302 printf("breaking recursive end_of_run()\n");
303 return SUCCESS;
304 }
305
306 gInsideEndRun = true;
307
308 gHaveRun = 0;
309 printf("end run %d\n",run_number);
311
312 gInsideEndRun = false;
313
314 return SUCCESS;
315}
316
317/*-- Pause Run -----------------------------------------------------*/
319{
320 gHaveRun = 0;
322 return SUCCESS;
323}
324
325/*-- Resume Run ----------------------------------------------------*/
327{
328 gHaveRun = 1;
330 return SUCCESS;
331}
332
333/*-- Frontend Loop -------------------------------------------------*/
335{
336 /* if frontend_call_loop is true, this routine gets called when
337 the frontend is idle or once between every event */
338 return SUCCESS;
339}
340
341/********************************************************************\
342
343 Readout routines for different events
344
345\********************************************************************/
346
347/*-- Trigger event routines ----------------------------------------*/
348extern "C" INT poll_event(INT source, INT count, BOOL test)
349/* Polling routine for events. Returns TRUE if event
350 is available. If test equals TRUE, don't return. The test
351 flag is used to time the polling */
352{
353 //printf("poll_event %d %d %d!\n",source,count,test);
354
355 for (int i=0 ; i<count ; i++)
356 {
358 //printf("source: 0x%x, lam: 0x%x\n", source, lam);
359
360 if (lam)
361 if (!test)
362 return TRUE;
363 }
364
365 return FALSE;
366
367#if 0
368 for (int i = 0; i < count; i++)
369 {
370 usleep(1000);
371 if (true)
372 if (!test)
374 }
375 return 1;
376
378#endif
379}
380
381/*-- Interrupt configuration ---------------------------------------*/
382extern "C" INT interrupt_configure(INT cmd, INT source, PTYPE adr)
383{
384 switch (cmd) {
386 break;
388 break;
390 break;
392 break;
393 }
394 return SUCCESS;
395}
396
397/*-- Event readout -------------------------------------------------*/
398
399int read_v792(int base,const char*bname,char*pevent,int nchan)
400{
401 int i;
402 int wcount = 0;
403 DWORD data[100];
404 int counter = 0;
405 WORD* pdata;
406
407 /* Event counter */
409
410 /* Read Event */
412
413 /* create ADCS bank */
414 bk_create(pevent, bname, TID_WORD, &pdata);
415
416 for (i=0; i<32; i++)
417 pdata[i] = 0;
418
419 for (i=0; i<wcount; i++)
420 {
421 uint32_t w = data[i];
422 if (((w>>24)&0x7) != 0) continue;
423 int chan = (w>>16)&0x1F;
424 int val = (w&0x1FFF);
425 pdata[chan] = val;
426 }
427
428 //printf("counter %6d, words: %3d, header: 0x%08x, ADC0: 0x%08x, ADC0,1,2: %6d %6d %6d\n",counter,wcount,data[0],pdata[0],pdata[0],pdata[1],pdata[2]);
429
430 pdata += nchan;
431 bk_close(pevent, pdata);
432
433 return wcount;
434}
435
436#ifdef HAVE_V1190B
437int read_tdc(int base,char*pevent)
438{
439 int time0 = 0;
440 int time1 = 0;
441 int time2 = 0;
442 int count;
443 const int kDataSize = 10000;
445 int* pdata32;
446
447 /* create TOPA bank */
448 bk_create(pevent, "TDCS", TID_INT, &pdata32);
449
450 //while (count <
451 count = v1190_DataRead(gVme, base, data, 10000);
452
453 if (count > 0)
454 {
455#if 0
456 if (count > 1000)
457 printf("reading TDC got %d words\n",count);
458
459 printf("reading TDC got %d words\n",count);
460#endif
461 for (int i=0; i<count; i++)
462 {
463 int code = 0x1F&(data[i]>>27);
464
465 if (data[i] == 0)
466 continue;
467
468 switch (code)
469 {
470 case 0:
471 {
472 int edge = 0x1&(data[i]>>26);
473 int chan = 0x3F&(data[i]>>19);
474 int time = 0x3FFFF&data[i];
475#if 0
476 printf("tdc %3d: 0x%08x, code 0x%02x, edge %d, chan %2d, time %6d\n",
477 i,
478 data[i],
479 code,
480 edge,
481 chan,
482 time);
483#endif
484 if ((chan==0) && (time0==0))
485 time0 = time;
486 if ((chan==1) && (time0!=0) && (time1==0) && (time>time0))
487 time1 = time;
488 if ((chan==2) && (time0!=0) && (time2==0) && (time>time0))
489 time2 = time;
490 }
491 break;
492 //case 0x18:
493 //break;
494 default:
495#if 0
496 printf("tdc %3d: 0x%08x, code 0x%02x\n",i,data[i],code);
497#endif
498 break;
499 }
500 }
501
502#if 0
503 if (time1 && time2)
504 printf("time %8d %8d %8d, diff %8d\n",time0,time1,time2,time1-time2);
505#endif
506 }
507
508 int xdata = time1-time2;
509 if (xdata < -10000)
510 xdata = 0;
511 else if (xdata > 10000)
512 xdata = 0;
513
514#if 0
515 if (xdata == 0)
516 printf("count %d, time %8d %8d %8d, diff %8d\n",count,time0,time1,time2,xdata);
517#endif
518
519 *pdata32++ = xdata;
520
521 bk_close(pevent, pdata32);
522
524
525 return 0;
526}
527#endif
528
529#ifdef HAVE_VF48
530int read_vf48(int base,char* pevent)
531{
532 int count = 0xF;
533 DWORD buf[10000];
534 int* pdata32;
535
536 /* create TOPA bank */
537 bk_create(pevent, "VF48", TID_INT, &pdata32);
538
539 VF48_EventRead(gVme, base, buf, &count);
540
541 for (int i=0; i<count; i++)
542 *pdata32++ = buf[i];
543
544 bk_close(pevent, pdata32);
545
546 return 0;
547}
548#endif
549
550INT read_event(char *pevent, INT off)
551{
552 //printf("read event!\n");
553
554 /* init bank structure */
555 bk_init32(pevent);
556
557#ifdef HAVE_V792
558 read_v792(gAdcBase,"ADC1",pevent,32);
559#endif
560#ifdef HAVE_V1190B
561 read_tdc(gTdcBase,pevent);
562#endif
563#ifdef HAVE_VF48
564 read_vf48(gVF48base,pevent);
565#endif
566
567 return bk_size(pevent);
568}
569
#define FALSE
Definition cfortran.h:309
BOOL frontend_call_loop
frontend_loop is called periodically if this variable is TRUE
Definition fevme.cxx:57
INT max_event_size
maximum event size produced by this frontend
Definition fevme.cxx:63
INT frontend_exit()
Frontend exit.
Definition fevme.cxx:272
int gVF48base
Definition fevme.cxx:148
INT read_event(char *pevent, INT off)
Definition fevme.cxx:550
int gDisBase[]
Definition fevme.cxx:146
INT frontend_init()
Frontend initialization.
Definition fevme.cxx:251
int disable_trigger()
Definition fevme.cxx:194
int read_v792(int base, const char *bname, char *pevent, int nchan)
Definition fevme.cxx:399
INT event_buffer_size
buffer size to hold events
Definition fevme.cxx:69
INT max_event_size_frag
maximum event size for fragmented events (EQ_FRAGMENTED)
Definition fevme.cxx:66
INT interrupt_configure(INT cmd, INT source, PTYPE adr)
Definition fevme.cxx:382
int mvme_read16(int addr)
Definition fevme.cxx:150
void encodeU32(char *pdata, uint32_t value)
Definition fevme.cxx:162
uint32_t odbReadUint32(const char *name, int index, uint32_t defaultValue=0)
Definition fevme.cxx:170
MVME_INTERFACE * gVme
Definition fevme.cxx:142
INT init_vme_modules()
Definition fevme.cxx:202
INT run_state
Definition mfe.cxx:35
int mvme_read32(int addr)
Definition fevme.cxx:156
INT poll_event(INT source, INT count, BOOL test)
Polling routine for events.
Definition fevme.cxx:348
int enable_trigger()
Definition fevme.cxx:185
EQUIPMENT equipment[]
Main structure for midas equipment.
Definition fevme.cxx:88
HNDLE hDB
main ODB handle
Definition mana.cxx:207
INT display_period
a frontend status page is displayed with this frequency in ms
Definition fevme.cxx:60
char * frontend_name
The frontend name (client name) as seen by other MIDAS clients.
Definition fevme.cxx:52
int gAdcBase
Definition fevme.cxx:145
char * frontend_file_name
The frontend file name, don't change it.
Definition fevme.cxx:54
int read_tdc(int base, char *pevent)
Definition fevme.cxx:437
int gVmeioBase
Definition fevme.cxx:144
int gTdcBase
Definition fevme.cxx:147
static int gHaveRun
Definition fevme.cxx:268
INT begin_of_run(INT run_number, char *error)
Begin of Run.
Definition fevme.cxx:284
INT frontend_loop()
Frontend loop.
Definition fevme.cxx:334
INT end_of_run(INT run_number, char *error)
End of Run.
Definition fevme.cxx:296
INT bk_close(void *event, void *pdata)
Definition midas.cxx:16780
void bk_init32(void *event)
Definition midas.cxx:16469
void bk_create(void *event, const char *name, WORD type, void **pdata)
Definition midas.cxx:16561
INT bk_size(const void *event)
Definition midas.cxx:16495
#define CMD_INTERRUPT_ATTACH
Definition midas.h:822
#define CMD_INTERRUPT_DISABLE
Definition midas.h:821
#define CMD_INTERRUPT_ENABLE
Definition midas.h:820
#define CMD_INTERRUPT_DETACH
Definition midas.h:823
unsigned short int WORD
Definition mcstd.h:49
unsigned int DWORD
Definition mcstd.h:51
#define SUCCESS
Definition mcstd.h:54
#define EQ_POLLED
Definition midas.h:415
#define TRIGGER_ALL
Definition midas.h:538
#define TID_WORD
Definition midas.h:332
#define MERROR
Definition midas.h:559
#define TID_INT
Definition midas.h:338
#define RO_RUNNING
Definition midas.h:426
#define TID_DWORD
Definition midas.h:336
INT cm_msg(INT message_type, const char *filename, INT line, const char *routine, const char *format,...)
Definition midas.cxx:915
int EXPRT mvme_open(MVME_INTERFACE **vme, int idx)
unsigned int EXPRT mvme_read_value(MVME_INTERFACE *vme, mvme_addr_t vme_addr)
int EXPRT mvme_set_dmode(MVME_INTERFACE *vme, int dmode)
int EXPRT mvme_close(MVME_INTERFACE *vme)
int EXPRT mvme_set_am(MVME_INTERFACE *vme, int am)
#define MVME_DMODE_D32
Definition mvmestd.h:82
#define MVME_DMODE_D16
Definition mvmestd.h:81
#define MVME_AM_A24_ND
Definition mvmestd.h:120
INT db_get_data_index(HNDLE hDB, HNDLE hKey, void *data, INT *buf_size, INT idx, DWORD type)
Definition odb.cxx:6893
INT run_number[2]
Definition mana.cxx:246
INT index
Definition mana.cxx:271
void * data
Definition mana.cxx:268
char addr[128]
Definition mcnaf.cxx:104
double count
Definition mdump.cxx:33
INT i
Definition mdump.cxx:32
INT HNDLE
Definition midas.h:132
DWORD BOOL
Definition midas.h:105
int INT
Definition midas.h:129
#define PTYPE
Definition midas.h:170
#define LAM_SOURCE(c, s)
Definition midas.h:469
#define TRUE
Definition midas.h:182
#define resume_run
#define name(x)
Definition midas_macro.h:24
#define pause_run
program test
Definition miniana.f:6
INT j
Definition odbhist.cxx:40
double value[100]
Definition odbhist.cxx:42
DWORD status
Definition odbhist.cxx:39
TH1X EXPRT * h1_book(const char *name, const char *title, int bins, double min, double max)
Definition rmidas.h:24
static te_expr * base(state *s)
Definition tinyexpr.c:357