MIDAS
Loading...
Searching...
No Matches
feoV1720.cxx
Go to the documentation of this file.
1/*****************************************************************************/
98#include <stdio.h>
99#include <stdlib.h>
100#include <sys/time.h>
101#include <sched.h>
102#include <sys/resource.h>
103
104#include <vector>
105using std::vector;
106
107#include "midas.h"
108
109extern "C" {
110#include "CAENComm.h"
111#include "ov1720drv.h"
112}
113
114#include "v1720CONET2.hxx"
115
116// __________________________________________________________________
117// --- General feov1720 parameters
118
119#if SIMULATION
120#define Nv1720 2
121#else
122#define NBLINKSPERA3818 1
123#define NBLINKSPERFE 1
124#define NB1720PERLINK 2
125#define NBV1720TOTAL 2
126#endif
127
128#define EQ_EVID 1
129#define EQ_TRGMSK 0
130#if SIMULATION
131#define FE_NAME "feov1720_SIM"
132#else
133#define FE_NAME "feov1720"
134#endif
135
136#define UNUSED(x) ((void)(x))
137
138// __________________________________________________________________
139// --- MIDAS global variables
140extern HNDLE hDB;
141extern BOOL debug;
142
145
146/* make frontend functions callable from the C framework */
147#ifdef __cplusplus
148extern "C" {
149#endif
150
151/*-- Globals -------------------------------------------------------*/
152
154char *frontend_name = (char*)FE_NAME;
162INT max_event_size = 32 * 34000;
164INT max_event_size_frag = 5 * 1024 * 1024;
167
168bool runInProgress = false;
169bool runOver = false;
170bool runStopRequested = false;
171
172
173// __________________________________________________________________
174/*-- MIDAS Function declarations -----------------------------------------*/
177INT begin_of_run(INT run_number, char *error);
178INT end_of_run(INT run_number, char *error);
179INT pause_run(INT run_number, char *error);
180INT resume_run(INT run_number, char *error);
182extern void interrupt_routine(void);
183
184INT read_trigger_event(char *pevent, INT off);
185INT read_scaler_event(char *pevent, INT off);
186
187// __________________________________________________________________
188/*-- Equipment list ------------------------------------------------*/
189#undef USE_INT
192{
193 {
194#if SIMULATION
195 "FEv1720_SIM", /* equipment name */
196 {
197 EQ_EVID, EQ_TRGMSK, /* event ID, trigger mask */
198 "SYSTEM", /* event buffer */
199# ifdef USE_INT
200 EQ_INTERRUPT, /* equipment type */
201# else
202 EQ_POLLED, /* equipment type */
203# endif //USE_INT
204
205#else
206 "FEv1720I%0d", /* equipment name */
207 {
208 EQ_EVID, EQ_TRGMSK, /* event ID, trigger mask */
209 // //Use this to make different frontends (indexes) write
210 // //to different buffers
211 // "BUF%0d", /* event buffer */
212 "SYSTEM", /* event buffer */
213
214# ifdef USE_INT
215 EQ_INTERRUPT, /* equipment type */
216# else
217 EQ_POLLED | EQ_EB, /* equipment type */
218# endif //USE_INT
219
220#endif //SIMULATION
221
222 LAM_SOURCE(0, 0x0), /* event source crate 0, all stations */
223 "MIDAS", /* format */
224 TRUE, /* enabled */
225 RO_RUNNING, /* read only when running */
226 500, /* poll for 500ms */
227 0, /* stop run after this event limit */
228 0, /* number of sub events */
229 0, /* don't log history */
230 "", "", ""
231 },
232 read_trigger_event, /* readout routine */
233 },
234 {""}
235};
236
237#ifdef __cplusplus
238}
239#endif
240
242vector<v1720CONET2>::iterator itv1720;
243
244
245/********************************************************************/
246/********************************************************************/
247/********************************************************************/
248
259 KEY key;
260
261 for (itv1720 = ov1720.begin(); itv1720 != ov1720.end(); ++itv1720) {
262 if (hseq == itv1720->GetODBHandle()){
264 itv1720->SetSettingsTouched(true);
265 printf("Settings %s touched. Changes will take effect at start of next run.\n", key.name);
266 }
267 }
268}
269
270
281
282 set_equipment_status(equipment[0].name, "Initializing...", "#FFFF00");
283
284 // --- Suppress watchdog for PICe for now
286
287#if SIMULATION
288 for (int iBoard=0; iBoard < Nv1720; iBoard++)
289 {
290 printf("<<< Init board %i\n", iBoard);
291 ov1720.push_back(v1720CONET2(iBoard));
292 ov1720[iBoard].verbose = 1;
293
294 //load ODB settings
295 ov1720[iBoard].SetODBRecord(hDB,seq_callback);
296
297 // Open Optical interface
299 sCAEN = ov1720[iBoard].Connect();
300 if (sCAEN != CAENComm_Success) {
301 cm_msg(MERROR, "fe", "Could not connect to board; error:%d", sCAEN);
302 }
303 else {
304 printf("Connected successfully to module; handle: %d\n",ov1720[iBoard].GetHandle());
305
306 ov1720[iBoard].InitializeForAcq();
307 ov1720[iBoard].mZLE = false;
308 }
309 }
310
311 // Lock to one core on the processor. Need to be moved to TFeCommon
313 CPU_ZERO(&mask);
314 CPU_SET(4, &mask); // arbitrarily chose 4
315 if( sched_setaffinity(0, sizeof(mask), &mask) < 0 ){
316 printf("ERROR: affinity not set\n");
317 }
318 printf(">>> End of Init.\n\n");
319#else
320 // --- Get the frontend index. Derive the Optical link number
322
323 int tNActivev1720=0; //Number of v1720 boards activated at the end of frontend_init
324
325 // If no index was supplied on the command-line, assume 1 frontend
326 // to control all the links and boards
327 if(feIndex == -1){
328
329 printf("<<< No index supplied! Assuming only 1 frontend only and starting all boards on all links\n");
330 for (int iLink=0; iLink < NBLINKSPERA3818; iLink++)
331 {
332 for (int iBoard=0; iBoard < NB1720PERLINK; iBoard++)
333 {
334 printf("<<< Begin of Init \n link:%i, board:%i\n", iLink, iBoard);
335
336 // Compose unique module ID
338
339 // Create module objects
341 ov1720.back().verbose = 1;
342
343 // Setup ODB record (create if necessary)
344 ov1720.back().SetODBRecord(hDB,seq_callback);
345
346 // Open Optical interface
347 printf("Opening optical interface Link %d, Board %d\n", iLink, iBoard);
349 sCAEN = ov1720.back().Connect();
350 if (sCAEN != CAENComm_Success) {
351 cm_msg(MERROR, "fe", "Link#:%d iBoard#:%d error:%d", iLink, iBoard, sCAEN);
352 }
353 else {
355 printf("Link#:%d Board#:%d Module_Handle[%d]:%d (active:%d)\n",
356 iLink, iBoard, moduleID, ov1720.back().GetHandle(), tNActivev1720);
357
358 ov1720.back().InitializeForAcq();
359
360 }
361 }
362 }
363 }
364 else { //index supplied
365
367 printf("Incorrect setup: the number of boards controlled by each frontend"
368 " is not a fraction of the total number of boards.");
369 }
370
373 printf("Front end index must be between 0 and %d\n", maxIndex);
374 exit(1);
375 }
376
378 int lastLink = firstLink + NBLINKSPERFE - 1;
379 for (int iLink=firstLink; iLink <= lastLink; iLink++)
380 {
381 for (int iBoard=0; iBoard < NB1720PERLINK; iBoard++)
382 {
383
384 printf("<<< Begin of Init \n feIndex:%i, link:%i, board:%i\n",
386
387 // Compose unique module ID
389
390 // Create module objects
392 ov1720.back().verbose = 1;
393
394 // Setup ODB record (create if necessary)
395 ov1720.back().SetODBRecord(hDB,seq_callback);
396
397 // Open Optical interface
398 printf("Opening optical interface Link %d, Board %d\n", iLink, iBoard);
400 sCAEN = ov1720.back().Connect();
401 if (sCAEN != CAENComm_Success) {
402 cm_msg(MERROR, "fe", "Link#:%d iBoard#:%d error:%d", iLink, iBoard, sCAEN);
403 }
404 else {
406 printf("Link#:%d Board#:%d Module_Handle[%d]:%d (active:%d)\n",
407 iLink, iBoard, moduleID, ov1720.back().GetHandle(), tNActivev1720);
408
409 ov1720.back().InitializeForAcq();
410 }
411 }
412 }
413 }
414
415 // Lock to one core on the processor. Need to be moved to TFeCommon
417 CPU_ZERO(&mask);
418 CPU_SET(4, &mask); // arbitrarily chose 4
419 if( sched_setaffinity(0, sizeof(mask), &mask) < 0 ){
420 printf("ERROR: affinity not set\n");
421 }
422
423 if(feIndex == -1 )
424 printf(">>> End of Init. %d active v1720. Expected %d\n\n",
426 else
427 printf(">>> End of Init. %d active v1720. Expected %d\n\n",
429#endif //SIMULATION
430
431
432 set_equipment_status(equipment[0].name, "Initialized", "#00ff00");
433
434#if SIMULATION
435 printf("*** RUNNING SIMULATION ***\n");
436#endif
437
438 return SUCCESS;
439}
440
441
450
451 set_equipment_status(equipment[0].name, "Exiting...", "#FFFF00");
452
453 for (itv1720 = ov1720.begin(); itv1720 != ov1720.end(); ++itv1720) {
454 if (itv1720->IsConnected()){
455 itv1720->Disconnect();
456 }
457 }
458 set_equipment_status(equipment[0].name, "Exited", "#00ff00");
459 return SUCCESS;
460}
461
472
473 set_equipment_status(equipment[0].name, "Starting run...", "#FFFF00");
474
475 printf("<<< Begin of begin_of_run\n");
476
478 //we've decided to only initialize at start of frontend
479 //if odb stuff is changed, will need to restart fe to take effect.
480
481 // Reset and Start v1720s
482 for (itv1720 = ov1720.begin(); itv1720 != ov1720.end(); ++itv1720) {
483 if (! itv1720->IsConnected()) continue; // Skip unconnected board
484 printf("Starting module iBoard %d\n", itv1720->GetModuleID());
485 // Reset card (Alex) Moved to the beginning
486 //sCAEN = ov1720[iBoard]->WriteReg(v1720_SW_RESET, 0x1);
487 //sCAEN = ov1720[iBoard]->WriteReg(v1720_SW_CLEAR, 0x1);
488 // Start run then wait for trigger
489 itv1720->StartRun();
490 }
491
492 runInProgress = true;
493
494 printf(">>> End of begin_of_run\n\n");
495 set_equipment_status(equipment[0].name, "Started run", "#00ff00");
496
497 return (sCAEN == CAENComm_Success ? SUCCESS : sCAEN);
498}
499
510
512
513 set_equipment_status(equipment[0].name, "Ending run...", "#FFFF00");
514
515 printf("<<< Beging of end_of_run \n");
516 // Stop run
518
519 for (itv1720 = ov1720.begin(); itv1720 != ov1720.end(); ++itv1720) {
520 if (itv1720->IsConnected()) { // Skip unconnected board
521 sCAEN = itv1720->StopRun();
522 }
523 }
524
525 runOver = false;
526 runStopRequested = false;
527 runInProgress = false;
528
529#if SIMULATION
530 sCAEN = ov1720[0].Poll(&buffLvl);
531#else
532 sCAEN = ov1720[0].Poll(&buffLvl);
533 if(buffLvl != 0x0) {
534 cm_msg(MERROR, "feov1720:EOR", "Events left in the v1720: %d",buffLvl);
535 }
536#endif
537
538 printf(">>> End Of end_of_run\n\n");
539 set_equipment_status(equipment[0].name, "Ended run", "#00ff00");
540
541 return (sCAEN == CAENComm_Success ? SUCCESS : sCAEN);
542}
543
555{
556 runInProgress = false;
557 return SUCCESS;
558}
559
571{
572 runInProgress = true;
573 return SUCCESS;
574}
575
585{
586 char str[128];
587 static DWORD evlimit;
588
589 if (runStopRequested && !runOver) {
590 db_set_value(hDB,0,"/logger/channels/0/Settings/Event limit", &evlimit, sizeof(evlimit), 1, TID_DWORD);
591 if (cm_transition(TR_STOP, 0, str, sizeof(str), ASYNC, FALSE) != CM_SUCCESS) {
592 cm_msg(MERROR, "feov1720", "cannot stop run: %s", str);
593 }
594 runInProgress = false;
595 runOver = true;
596 cm_msg(MERROR, "feov1720","feov1720 Stop requested");
597 }
598 return SUCCESS;
599}
600
601/*------------------------------------------------------------------*/
602/********************************************************************\
603 Readout routines for different events
604\********************************************************************/
605int Nloop;
607
608// ___________________________________________________________________
609/*-- Trigger event routines ----------------------------------------*/
619extern "C" INT poll_event(INT source, INT count, BOOL test)
620{
621 register int i; // , mod=-1;
622 register DWORD lam;
623 register DWORD buffLvl;
625 for (i = 0; i < count; i++) {
626 // if (gv1720Handle[board] < 0) continue; // Skip unconnected board
627 lam = 0;
628 sCAEN = ov1720[0].Poll(&buffLvl);
629
630 if (debugpolling) printf("loop: %d lam:%x, sCAEN:%d\n", i, lam, sCAEN);
631
632 if (buffLvl > 0) { // Why was this set to > 5? (Alex 01/03/13)
633
634 //event available
635 Nloop = i;
636 Ncount = count;
637#if 0
640 ov1720[0].ReadReg(v1720_EVENT_STORED ,&buffLvl);
641 printf("vme %i | acq %i | buff lvl %i | count %i\n",lam, acqStat, buffLvl, Nloop);
642#endif
643 if (!test) return 1;
644 } else {
645 ss_sleep(1);
646 }
647 }
648 return 0;
649}
650
663extern "C" INT interrupt_configure(INT cmd, INT source, POINTER_T adr)
664{
665 switch (cmd) {
667 break;
669 break;
671 break;
673 break;
674 }
675 return SUCCESS;
676}
677
692
693 if (!runInProgress) return 0;
694
696
697 sn = SERIAL_NUMBER(pevent);
698
699 bk_init32(pevent);
700 char bankName[5];
701 char statBankName[5];
703
704 for (itv1720 = ov1720.begin(); itv1720 != ov1720.end(); ++itv1720) {
705
706 if (! itv1720->IsConnected()) continue; // Skip unconnected board
707
708 // >>> Get time before read (for data throughput analysis. To be removed)
709 timeval tv;
710 gettimeofday(&tv,0);
711 suseconds_t usStart = tv.tv_usec;
712
713 // >>> Read a few registers
715 sCAEN = itv1720->ReadReg(V1720_EVENT_SIZE, &eSize);
716 eSizeTot = eSize; // eSize will be decremented later on
718 DWORD lam;
719 sCAEN = itv1720->ReadReg(V1720_VME_STATUS, &lam);
720 // printf("S/N:%i B:%i eSt:%i eSze%i Lvl:%i Lam:%i \n",sn,iBoard,eStored,eSize,buffLvl,lam);
721
722 if(debugtrigger){
723 printf("Module:%02d Hndle:%d S/N:%8.8d Nloop:%d/%d (%5.2f) sCAEN:%d Event Stored:0x%x Event Size:0x%x\n"
724 , itv1720->GetModuleID(), itv1720->GetHandle(), sn, Nloop, Ncount, (100.*Nloop/Ncount), sCAEN, eStored, eSize);
725 }
726
727 // >>> Calculate module number
728 int module = itv1720->GetModuleID();
729
730 // >>> create data bank
731 if(itv1720->IsZLEData()){
732 sprintf(bankName, "ZL%02d", module);
733 }
734 else{
735 sprintf(bankName, "W2%02d", module);
736 }
737 bk_create(pevent, bankName, TID_DWORD, &pdata);
738
739 //read event into bank
740 int dwords_read = 0;
741 sCAEN = itv1720->ReadEvent(pdata, &dwords_read);
742
743 // >>> close data bank
744 bk_close(pevent, pdata + dwords_read);
745
746 //might eventually move this stuff into helper
747
748 // >>> Fill Qt bank if ZLE data
749 if(itv1720->IsZLEData()){
750 itv1720->fillQtBank(pevent, pdata, module);
751 }
752
753 // >>> Statistical bank for data throughput analysis
754 sprintf(statBankName, "ST%02d", module);
756 *pdata++ = module;
757 *pdata++ = eStored;
758 *pdata++ = eSizeTot;
759 *pdata++ = buffLvl;
760 gettimeofday(&tv,0);
761 *pdata++ = usStart;
762 *pdata++ = tv.tv_usec;
763 bk_close(pevent, pdata);
764
765 }
766
767 //primitive progress bar
768 if (sn % 100 == 0) printf(".");
769
770 return bk_size(pevent);
771}
#define FALSE
Definition cfortran.h:309
BOOL frontend_call_loop
frontend_loop is called periodically if this variable is TRUE
Definition feoV1720.cxx:158
bool runOver
run is over
Definition feoV1720.cxx:169
int Nloop
Number of loops executed in event polling.
Definition feoV1720.cxx:605
void seq_callback(INT hDB, INT hseq, void *info)
Sequencer callback info.
Definition feoV1720.cxx:258
INT max_event_size
maximum event size produced by this frontend
Definition feoV1720.cxx:162
INT frontend_exit()
Frontend exit.
Definition feoV1720.cxx:449
BOOL debugpolling
debug msgs polling loop
Definition feoV1720.cxx:143
bool runStopRequested
stop run requested
Definition feoV1720.cxx:170
INT frontend_init()
Frontend initialization.
Definition feoV1720.cxx:280
BOOL debugtrigger
debug msgs read trigger event
Definition feoV1720.cxx:144
INT event_buffer_size
buffer size to hold events
Definition feoV1720.cxx:166
bool runInProgress
run is in progress
Definition feoV1720.cxx:168
#define EQ_TRGMSK
Trigger mask.
Definition feoV1720.cxx:129
INT max_event_size_frag
maximum event size for fragmented events (EQ_FRAGMENTED)
Definition feoV1720.cxx:164
#define NBV1720TOTAL
Number of v1720 boards in total.
Definition feoV1720.cxx:125
INT interrupt_configure(INT cmd, INT source, POINTER_T adr)
Interrupt configuration (not implemented)
Definition feoV1720.cxx:663
int Ncount
Loop count for event polling timeout.
Definition feoV1720.cxx:606
BOOL debug
debug printouts
Definition mana.cxx:254
#define NB1720PERLINK
Number of daisy-chained v1720s per optical link.
Definition feoV1720.cxx:124
void interrupt_routine(void)
Interrupt Service Routine.
#define NBLINKSPERFE
Number of optical links controlled by each frontend.
Definition feoV1720.cxx:123
INT poll_event(INT source, INT count, BOOL test)
Polling routine for events.
Definition feoV1720.cxx:619
#define FE_NAME
Frontend name.
Definition feoV1720.cxx:133
INT read_trigger_event(char *pevent, INT off)
Event readout.
Definition feoV1720.cxx:691
vector< v1720CONET2 > ov1720
objects for the v1720 modules controlled by this frontend
Definition feoV1720.cxx:241
EQUIPMENT equipment[]
Main structure for midas equipment.
Definition feoV1720.cxx:191
HNDLE hDB
main ODB handle
Definition mana.cxx:207
INT display_period
a frontend status page is displayed with this frequency in ms
Definition feoV1720.cxx:160
char * frontend_name
The frontend name (client name) as seen by other MIDAS clients.
Definition feoV1720.cxx:154
char * frontend_file_name
The frontend file name, don't change it.
Definition feoV1720.cxx:156
#define EQ_EVID
Event ID.
Definition feoV1720.cxx:128
INT begin_of_run(INT run_number, char *error)
Begin of Run.
Definition feoV1720.cxx:471
INT frontend_loop()
Frontend loop.
Definition feoV1720.cxx:584
#define NBLINKSPERA3818
Number of optical links used per A3818.
Definition feoV1720.cxx:122
INT end_of_run(INT run_number, char *error)
End of Run.
Definition feoV1720.cxx:509
INT read_scaler_event(char *pevent, INT off)
Placeholder.
Definition ebfe.cxx:295
vector< v1720CONET2 >::iterator itv1720
iterator
Definition feoV1720.cxx:242
DWORD evlimit
INT bk_close(void *event, void *pdata)
Definition midas.cxx:16788
void bk_init32(void *event)
Definition midas.cxx:16477
void bk_create(void *event, const char *name, WORD type, void **pdata)
Definition midas.cxx:16569
INT bk_size(const void *event)
Definition midas.cxx:16503
INT cm_transition(INT transition, INT run_number, char *errstr, INT errstr_size, INT async_flag, INT debug_flag)
Definition midas.cxx:5294
INT cm_set_watchdog_params(BOOL call_watchdog, DWORD timeout)
Definition midas.cxx:3283
#define CM_SUCCESS
Definition midas.h:582
#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 int DWORD
Definition mcstd.h:51
#define SUCCESS
Definition mcstd.h:54
#define EQ_POLLED
Definition midas.h:415
#define EQ_EB
Definition midas.h:421
#define MERROR
Definition midas.h:559
#define EQ_INTERRUPT
Definition midas.h:416
#define TR_STOP
Definition midas.h:406
#define RO_RUNNING
Definition midas.h:426
#define TID_DWORD
Definition midas.h:336
INT ss_sleep(INT millisec)
Definition system.cxx:3628
INT cm_msg(INT message_type, const char *filename, INT line, const char *routine, const char *format,...)
Definition midas.cxx:915
INT db_get_key(HNDLE hDB, HNDLE hKey, KEY *key)
Definition odb.cxx:6019
INT db_set_value(HNDLE hDB, HNDLE hKeyRoot, const char *key_name, const void *data, INT data_size, INT num_values, DWORD type)
Definition odb.cxx:5261
void ** info
Definition fesimdaq.cxx:41
INT run_number[2]
Definition mana.cxx:246
double count
Definition mdump.cxx:33
KEY key
Definition mdump.cxx:34
INT i
Definition mdump.cxx:32
INT get_frontend_index()
Definition mfe.cxx:2368
int set_equipment_status(const char *name, const char *equipment_status, const char *status_class)
Definition mfe.cxx:863
INT HNDLE
Definition midas.h:132
DWORD BOOL
Definition midas.h:105
int INT
Definition midas.h:129
#define LAM_SOURCE(c, s)
Definition midas.h:469
#define TRUE
Definition midas.h:182
#define POINTER_T
Definition midas.h:166
#define SERIAL_NUMBER(e)
Definition midas.h:880
#define resume_run
#define mask(slot)
Definition midas_macro.h:54
#define name(x)
Definition midas_macro.h:24
#define pause_run
program test
Definition miniana.f:6
int gettimeofday(struct timeval *tp, void *tzp)
timeval tv
Definition msysmon.cxx:1095
char str[256]
Definition odbhist.cxx:33
TH1X EXPRT * h1_book(const char *name, const char *title, int bins, double min, double max)
Definition rmidas.h:24
Definition midas.h:1026
char name[NAME_LENGTH]
Definition midas.h:1029