Subversion Repositories f9daq

Rev

Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
326 f9daq 1
#include <stdlib.h>
2
#include <stdio.h>
3
#include <stdint.h>
4
#include <string.h>
5
#include <unistd.h>
6
#include <ctype.h>
7
#include <zlib.h>
8
#include <vector>
9
#include <sys/time.h>
10
#include <sys/stat.h>
11
#include <signal.h>
12
#include <string>
13
#include "vme.h"
14
#include "dataio.h"
15
#include "SA02_DEF.h"
16
#include "sa02lib.h"
17
#include "H2D.h"
18
 
19
#define TRUE 1
20
#define FALSE 0
21
#define TIMEOUT 3
22
 
23
 
24
RUNINFO runinfo;
25
EVTREC evtrec;
26
 
27
//const int mux_map[4]={ 1,3,0,2};
28
const int mux_map[4]= { 2,0,3,1};
29
 
30
int verbose=0;
31
int timer_out;
32
struct sigaction oact;
33
int bltreadout=0;
34
int ctrl_c=0;
35
 
36
void SigInt (int sig) {
37
  ctrl_c = 1;
38
  timer_out=TRUE;
39
  sa02TimerOut = TRUE;
40
}
41
 
42
void sa02Timerast (int signumber) {
43
  timer_out = TRUE;
44
  sa02TimerOut = TRUE;
45
  sa02Printf("->>> TIMEOUT !!!\n");
46
}
47
 
48
void tmlnk (int tout) {
49
  timer_out = FALSE;
50
  struct sigaction act;
51
  struct itimerval tdelay;
52
 
53
  act.sa_handler = sa02Timerast;
54
  sigemptyset (&act.sa_mask);
55
  act.sa_flags = 0;
56
  tdelay.it_value.tv_sec = tout / 100;
57
  tdelay.it_value.tv_usec = 10000 * (tout % 100);
58
  tdelay.it_interval.tv_sec = 0;
59
  tdelay.it_interval.tv_usec = 0;
60
  if (sigaction (SIGALRM, &act, &oact) < 0) {
61
    perror ("sigaction(tmlnk)");
62
    exit (EXIT_FAILURE);
63
  }
64
  if (setitimer (ITIMER_REAL, &tdelay, NULL) < 0) {
65
    perror ("setitimer(tmlnk)");
66
    exit (EXIT_FAILURE);
67
  }
68
}
69
 
70
void tmulk () {
71
  struct itimerval tdelay;
72
 
73
  tdelay.it_value.tv_sec = 0;
74
  tdelay.it_value.tv_usec = 0;
75
  tdelay.it_interval.tv_sec = 0;
76
  tdelay.it_interval.tv_usec = 0;
77
  if (setitimer (ITIMER_REAL, &tdelay, NULL) < 0) {
78
    perror ("setitimer(tmulk)");
79
    exit (EXIT_FAILURE);
80
  }
81
  if (sigaction (SIGALRM, &oact, NULL) < 0) {
82
    perror ("sigaction(tmulk)");
83
    exit (EXIT_FAILURE);
84
  }
85
}
86
 
87
void sa02Tmlnk (int tout) {
88
  sa02TimerOut = FALSE;
89
  tmlnk (tout);
90
//  ResetTimer (p1h, P1_DAQ_TIMEOUT);
91
}
92
 
93
void sa02Tmulk () {
94
  tmulk();
95
}
96
 
97
int help() {
98
  printf ("*********************************************************************************:\n");
99
  printf ("Usage: Performs single/multiple read or write access to SA02 via Belle PTS multipurpose IO board:\n\n");
100
  printf ("Arguments: \n");
101
  printf ("-i input parameter filename // can be specified multiple times  \n");
102
  printf ("-v verbosity \n");
103
  printf ("-g bltreadout \n");
104
  printf ("-o output filename \n");
105
  printf ("-f output filename - append data to file\n");
106
  printf ("-w write command (FE TP DLY0 MUX MUXASIC VTH0 VTH1 TPLVL0 TPLVL1 GREG CREG CMON TMON0 TMON1 DMON) \n");
107
  printf ("-a vme base address 0x32100000 \n");
108
  printf ("-c asic chip number (0..3) \n");
109
  printf ("-x asic channel number (0..36) \n");
110
  printf ("-t sleep time bewteen events (sec) \n");
111
  printf ("-d data\n");
112
  printf ("-b dataoff - scan over the asic channels instead of the parameter, data step is the channel step, chip and channel are initial chip and  channel. Should apper after -p or-w\n");
113
  printf ("-s data step or in case of -b the channel step \n");
114
  printf ("-r number of readouts for each event\n");
115
  printf ("-n number of events\n");
116
  printf ("-h <command> at each event execute external command after readouts are done");
117
  printf ("-q  set status register bit TPENB of the CAEN1495 IO before event loop\n");
118
  printf ("-e send software trigger before reading the data\n");
119
  printf ("-p asicparameter ( PHASECMPS GAIN SHAPINGTIME COMPARATOR VRDRIVE MONITOR ID)\n");
120
  printf ("-p asicparameter ( DECAYTIME OFFSET FINEADJ_UNIPOL FINEADJ_DIFF TPENB KILL)\n\n");
121
  printf ("-u value ... send test SEU software trigger \n");
122
  printf ("-z value ... finish the execution of the program in <value> s \n");
123
  printf ("-m fixeddata : test fixed data, if error occurs, abort \n");
124
  printf ("-l board number   \n");
125
  printf ("*********************************************************************************:\n");
126
  printf ("Examples:\n\n");
127
  printf ("Threshold scan:\n");
128
  printf ("100 events TMON0 reading and 10 readings of the data for each event:\n");
129
  printf ("./sa02_ctrl  -a 0x32100000  -w TMON0 -n 100 -r 10 -t 10000 -v 1\n\n");
130
  printf ("scan 9 points TPLVL0 inital data 111 stepsize 11, send 1 test pulse, read data :\n");
131
  printf ("./sa02_ctrl  -a 0x32100000  -w TPLVL0 -d 111 -s 11 -n 9 -e 1 -r 1 -v 1\n\n");
132
  printf ("Initialize the board from input.param, Read 10000 events of data. the result is saved in the output.dat\n");
133
  printf ("./sa02_ctrl  -a 0x32100000  -i input.param -n 10000 -r 1 -o output.dat \n\n");
134
  printf ("Initialize the board from input.param, Read 10000 events of data. scan TPENB from 0 to 144 channels, send test pulse before the data acquisition,\n ");
135
  printf ("set TPENB to b after the acquisition, the result is saved in the output.dat\n");
136
  printf ("./sa02_ctrl  -a 0x32100000  -i input.param -p TPENB -d 1 -b 0 -s 1 -n 144 -c 0 -x 0 -e 1 -r 10000 -o output.dat \n\n");
137
  return 0;
138
}
139
 
140
int module_header(int recid,uint32_t *data,int len) {
141
  data[0] = recid;
142
  data[1] = (len >0)? len : 0 ;
143
  return data[1]+2;
144
}
145
 
146
//-------------------------------------------------------------------------
147
int PrintData(uint32_t *rdata, int count) {
148
  for (int j=0; j<count; j++) {
149
    uint32_t recid   = rdata[j++];
150
    uint32_t len     = rdata[j++];
151
    printf(" recid=0x%0x len=%d pos=%d(maxpos %d) val=",recid, len, j, count);
152
    if (len>2) printf("\n");
153
    for (uint32_t i=0; i<len; i++) {
154
      if (j< count) printf("0x%0x\t", rdata[j]);
155
      if (i%4==3) printf("\n");
156
      j++;
157
    }
158
    printf("\n");
159
    if (len) j--;
160
  }
161
  return 0;
162
}
163
 
164
//-------------------------------------------------------------------------
165
int main( int argc , char ** argv) {
166
  // intercept routine
167
  if (signal (SIGINT, SigInt) == SIG_ERR) {
168
    perror ("sigignore");
169
  }
170
 
171
  uint32_t fixeddata =0;
172
  int testfixeddata =0;
173
  uint32_t data    =0;
174
  uint32_t dataoff =0;
175
  uint32_t address =0;
176
  uint32_t cmd     =0;
177
  uint32_t chip    =0;
178
  uint32_t asicpar =0;
179
  uint32_t asicshft=0;
180
  uint32_t dstep   =0;
181
  uint32_t sendswtrg  =0;
182
  uint32_t tpenb   =0;
183
  uint32_t sendseutrg  =0;
184
 
185
  int aborttimeout =0;
186
  int append   =0;
187
  int remap    =0;
188
  int dt0      =0;
189
  int neve     =0;
190
  int towrite  =0;
191
  int toread   =0;
192
  int ch       =0;
193
  int output   =0;
194
  int externalcmd   =0;
195
  int getstatus   =0;
196
  int writeevent   =1;
197
  int c;
198
 
199
  char filename[0xFF]="";
200
  char externalcommand[0xFF]="";
201
  int sa02BoardMask = 0xF;
202
  opterr = 0;
203
  std::vector<std::pair<std::string,uint32_t> > inputfiles;
204
  while ((c = getopt (argc, argv, "a:b:c:d:e:f:g:h:i:j:k:l:m:n:o:p:q:r:s:t:u:v:z:x:w:y:")) != -1)
205
    switch (c) {
206
      case 'i':
207
        inputfiles.push_back(make_pair(std::string(optarg), sa02BoardMask));
208
        break;       // input file
209
      case 'f':
210
        append=1;    // append the data to the file filename
211
      case 'o':
212
        sprintf(filename,"%s", optarg );
213
        break;       // output
214
      case 'z':
215
        aborttimeout=atoi (optarg);    // abort timeout in s
216
        break;
217
      case 'h':
218
        sprintf(externalcommand,"%s", optarg );
219
        externalcmd=1;
220
        break;       // output
221
      case 'm':
222
        fixeddata =  strtoul (optarg,NULL,0);
223
        testfixeddata=1;
224
        break;             // address
225
      case 'a':
226
        address =  strtoul (optarg,NULL,0);
227
        break;             // address
228
      case 'r':
229
        toread =  strtoul (optarg,NULL,0);
230
        break;             // number of readings per event
231
      case 'v':
232
        verbose =  strtoul (optarg,NULL,0);
233
        break;             // verbosity
234
      case 't':
235
        dt0 =  strtoul (optarg,NULL,0);
236
        break;                // sec sleep between events
237
      case 's':
238
        dstep =  strtoul (optarg,NULL,0);
239
        break;                // step size in data or channel increase
240
      case 'g':
241
        bltreadout =  strtoul (optarg,NULL,0);
242
        break;                // bltreadout
243
      case 'l':
244
        sa02BoardMask =  strtoul (optarg,NULL,0);
245
        if ( sa02BoardMask > 0xF) {
246
          printf("Error! Board Mask 0..15 . Set to 0.");
247
          sa02BoardMask = 0xF;
248
        }
249
        break;                // board mask
250
      case 'j':
251
        sa02BoardType =  strtoul (optarg,NULL,0);
252
        if ( sa02BoardType > 3) {
253
          printf("Error! Board type sa02 0 / sa03 1 / FEB1_0 2 / FEB1_1 3 . Set to 3");
254
          sa02BoardType = 3;
255
        }
256
        break;                // board number
257
      case 'n':
258
        neve =  atoi (optarg);
259
        break;                          // number of events or number of scan points
260
      case 'e':
261
        sendswtrg =  strtoul (optarg,NULL,0);
262
        break;         // send sotware trigger before reading out the data
263
      case 'u':
264
        sendseutrg =  strtoul (optarg,NULL,0);
265
        break;         // send software SEU trigger before reading out the data
266
      case 'w':
267
        towrite=1;
268
        if (strcmp(optarg,"MUXASIC")==0)  remap=1;
269
        cmd =sa02GetCmdCode(optarg);
270
        break;         // write command
271
      case 'p':
272
        towrite=2;
273
        cmd = sa02GetAsicCode(optarg, &asicpar, &asicshft);
274
        break;  // asic parameter
275
      case 'b':
276
        towrite=3;
277
        dataoff  = strtoul (optarg,NULL,0);
278
        break;    // scan channels instead of parameter; the value is the off value of the channel
279
      case 'c':
280
        chip  = strtoul (optarg,NULL,0);
281
        break;                // chip number  or initial channel number in the case of -b option
282
      case 'x':
283
        ch  = strtoul (optarg,NULL,0);
284
        break;                 // channel number or initial channel in the case of -b option
285
      case 'd':
286
        data  = strtoul (optarg,NULL,0);
287
        if (remap) {
288
          data = mux_map[data];
289
          printf("MUX %d\n",data);
290
        }
291
        break;                 // data or initial data in the case of scan
292
      case 'q':
293
        tpenb  = strtoul (optarg,NULL,0);
294
        break;                 // set TPENB bit of the CAEN1495 IO
295
      case 'y':
296
        writeevent  = strtoul (optarg,NULL,0);
297
        break;                 // write event data
298
      case 'k':
299
        getstatus  = strtoul (optarg,NULL,0);
300
        break;                 //  print board status
301
      case '?':
302
        if (optopt == 'c')
303
          fprintf (stderr, "Option -%c requires an argument.\n", optopt);
304
        else if (isprint (optopt))
305
          fprintf (stderr, "Unknown option `-%c'.\n", optopt);
306
        else
307
          fprintf (stderr,
308
                   "Unknown option character `\\x%x'.\n",
309
                   optopt);
310
        return 1;
311
      default:
312
        abort ();
313
    }
314
 
315
  for (int i=optind; i<argc; i++) data = strtoul (argv[i],NULL,0);
316
 
317
  if (argc <2) {
318
    help();
319
    exit(-1);
320
  }
321
 
322
  // printf ("[neve=%d] a=0x%08x cmd= 0x%08x Data 0x%0x ",neve,address, cmd,data);
323
 
324
  //VME_START(CAEN_V1718);
325
  VME_START(ZYNQ_XILLINUX);
326
  int daqmode =3;
327
  int trglen = 1000;
328
  Sa02DaqMode (daqmode);
329
  Sa02SelectTriggerWithMaskAndLength (sendswtrg, sa02BoardMask , trglen);
330
 
331
  for (unsigned int i=0; i<inputfiles.size(); i++) {
332
 
333
    sa02LoadParametersFromFile(inputfiles[i].first.c_str(), inputfiles[i].second);
334
  }
335
 
336
  if (getstatus){
337
    char saddress[0xFF];
338
    double sdata[20];
339
    for (int board=0;board<4;board++){
340
      if (sa02BoardMask &(1<<board)) {
341
        printf("sa02Status => board %d\n",board);
342
        sa02Status(board, saddress,sdata);
343
      }
344
    }
345
  }
346
  if (sendseutrg)  Sa02SEUTrigger();
347
#define MAXSIZE 10000
348
  int maxsize = MAXSIZE;
349
  uint32_t *rdata = new uint32_t[maxsize];
350
  FILE * fp=NULL;
351
//  uint32_t hdr[10];
352
  int nbtotal=0;
353
  if (strlen(filename)>0) {
354
    if (verbose) printf("Data in the file:%s\n", filename);
355
    if (append) fp=fopen(filename,"ab");
356
    else fp=fopen(filename,"wb");
357
    output=1;
358
    // run header
359
    runinfo.id= RUNINFO_ID; // run record ID
360
    runinfo.len= sizeof(runinfo);
361
    runinfo.cmd= cmd;
362
    runinfo.x0 = data;
363
    runinfo.dx = dstep;
364
    runinfo.nx = neve;
365
    runinfo.chip= chip;
366
    runinfo.ch  = ch;
367
    runinfo.neve= toread;
368
    runinfo.writemode= towrite;
369
    sa02Printf("RUNINFO x0=%d nx=%d dx=%d\n", runinfo.x0,runinfo.dx,runinfo.nx);
370
    nbtotal+=fwrite(&runinfo, 1,sizeof(runinfo),fp); //gzip
371
  } else {
372
    if (verbose) printf("Data are not written to the file!\n");
373
  }
374
 
375
//  hdr[0]= 0x1; // event record ID
376
  if (!neve & (towrite || toread) ) neve=1;
377
 
378
  time_t t,told,tstart;
379
  time(&t);
380
  tstart=t;
381
  int ncount=0;
382
  int nerrors=0;
383
  int readerror=0;
384
  uint32_t response[2]= {0,0};
385
 
386
  Sa02TestPulseEnable(address, tpenb);
387
  ///////////////////////////////////////////////////////////////
388
  int h2=0;
389
  if(neve>1) {
390
    H2DInit(h2, "h2d","Sa02 Chip Scan", 144, 0,1,neve,data, dstep);
391
    H2DSetTitleX(h2,"channel");
392
    H2DSetTitleY(h2,"Scan");
393
  }
394
  for (int i=0; i<neve; i++) {
395
    int nb = sizeof(uint32_t);
396
    int count=0;
397
    switch (towrite) {
398
      case 1: {
399
        rdata[count+2]= data;
400
        rdata[count+3]= sa02Cmd(address,cmd, data, chip, ch , 2, response);
401
        count+=module_header(cmd,&rdata[count],2 );
402
        break;
403
      }
404
      case 2: {
405
        uint32_t datal = asicpar & (data << asicshft);
406
        rdata[count+2] =  data;
407
        rdata[count+3] =  sa02AsicWrite(address, cmd, datal, chip, ch, asicpar,asicshft);
408
        count+=module_header(cmd ,&rdata[count],2); // recid cmd
409
        break;
410
      }
411
      case 3: {
412
        rdata[count+2] =  chip*36+ch;
413
        rdata[count+3] =  sa02AsicWrite(address, cmd, data, chip, ch, asicpar,asicshft);  // switch on the channel
414
        count+=module_header(cmd ,&rdata[count],2); // recid cmd
415
        break;
416
      }
417
    }
418
//    const int dsize = ( FEB_DATA_STOP - FEB_DATA_START) / FEB_DATA_INC;
419
    const int dsize = 144*4;
420
 
421
    Sa02SetNeve(toread);
422
    sa02Reset();
423
 
424
    for ( int j=0; j< toread; j++) {
425
      int eventerror =  0;
426
      if ((count+2+dsize) >= maxsize) {
427
        int oldsize = maxsize;
428
        maxsize*=2;
429
        printf("Increasing data buffer to %d elements\n", maxsize);
430
        uint32_t *tmpdata = rdata;
431
        rdata = new uint32_t[maxsize];
432
        //memcpy(tmpdata,rdata, oldsize*sizeof(uint32_t));
433
        for (int ki=0; ki<oldsize; ki++) rdata[ki]=tmpdata[ki];
434
        delete tmpdata;
435
      }
436
      Sa02TestPulseEnable(address, tpenb);
437
      if (sendswtrg)  Sa02SoftwareTrigger();
438
      nb  = sa02Read(sa02BoardMask, &rdata[count+2] );
439
      if (neve>1) {
440
        for (int ich=0; ich<144*4; ich++){
441
          int xch = (143 - ich%144) + ich/144*144;
442
          H2DFillBin(h2, xch,i,rdata[count+2+ich]);
443
        }
444
      }
445
      if (testfixeddata && nb>0) {
446
        int len = nb / sizeof(uint32_t);
447
        for (int ir=0; ir<len; ir++) {
448
          if ( rdata[count+2+ir]!=fixeddata ) {
449
            time(&t);
450
            printf("INSERT INTO fixederror VALUES ( '%d', '%d','%d','%d','0x%08x','0x%08x' ) \n", int(t), int(t-tstart), i*toread+j, ir, rdata[count+2+ir], fixeddata );
451
            eventerror++;
452
          }
453
        }
454
      }
455
      if (eventerror) {
456
        readerror++;
457
        if (readerror==3) {
458
          ctrl_c = 1;
459
          system("date >> firmware.lock");
460
        }
461
      } else {
462
        readerror= 0;
463
      }
464
      if (nb>=0) count+=module_header(0x3,&rdata[count],nb/sizeof(uint32_t));  // recid 0x3
465
      if (ctrl_c) break;
466
      if (timer_out) j--;
467
      time(&t);
468
      if (t!=told ) printf("%d events in %2.2f min (%d s) TIMEOUTS=%d %s",ncount, (double)(t-tstart)/60.,int(t-tstart), nerrors, ctime(&t));
469
      if (aborttimeout && (t-tstart)>aborttimeout) {
470
        printf("Abort timeout reached ....\n");
471
        ctrl_c=1;
472
        break;
473
      }
474
      told=t;
475
      if (nb<0) {
476
        nerrors++;
477
        j--;
478
      } else ncount++;
479
    }
480
    if (externalcmd) {
481
      char ecmd[256];
482
      sprintf(ecmd,"%s %u %u %u %u",externalcommand,(unsigned int)  tstart,data, rdata[2], rdata[3]);
483
      if (verbose) printf("Executing external command %s\n",ecmd);
484
      system(ecmd);
485
    }
486
    if (output && writeevent) {
487
      evtrec.id=EVTREC_ID;
488
      evtrec.len=count*sizeof(uint32_t)+ sizeof(evtrec);
489
      evtrec.time=time(NULL);
490
      evtrec.nev=i;
491
      nb = fwrite( &evtrec,  1,  sizeof(evtrec),fp); //gzip
492
      if (count) nb+=fwrite(&rdata[0],1,count*sizeof(uint32_t),fp); //gzip
493
      if (nb!= (int) evtrec.len) printf("Error writing! %d!=%d\n",nb,evtrec.len);
494
      nbtotal+= nb;
495
    }
496
    if (verbose==1)  {
497
      printf("[%d/%d] %u \t", i,count, (unsigned int) time(NULL));
498
      PrintData(rdata,count);
499
    }
500
    if (dt0) sleep(dt0);
501
    if (towrite ==3) {
502
      sa02AsicWrite(address, cmd, dataoff, chip, ch, asicpar, asicshft);
503
      ch += dstep;
504
      if (ch>35) {
505
        ch-=36;
506
        chip++;
507
      }
508
    } else {
509
      data += dstep;
510
    }
511
    if (ctrl_c) {
512
      if (!testfixeddata) printf("Ctrl+C Program interrupted ....\n");
513
      break;
514
    }
515
  }
516
  if (output) {
517
    if (neve>1) H2DWrite2File(h2,fp);
518
    fclose(fp);
519
  }
520
  if (verbose>1)  {
521
    printf("%d bytes written to file %s\n", nbtotal, filename);
522
  }
523
  VME_STOP();
524
  time(&t);
525
  if (toread && !testfixeddata) printf("%d events in %2.2f min  (%d s) TIMEOUTS=%d  %s",ncount, (double)(t-tstart)/60.,int(t-tstart), nerrors, ctime(&t));
526
  return 0;
527
}