Subversion Repositories f9daq

Rev

Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
189 f9daq 1
//
2
//  test.c
3
//  
4
//  Description : test program for V729
5
//
6
//  Author : S. Korpar
7
//  Date   : 2005/07/15
8
// adapted to CAEN V1719 by R. Pestotnik  2012/09/07
9
 
10
#include <stdlib.h>
11
#include <stdio.h>
12
#include <string.h>
13
#include <unistd.h>
14
#include <ctype.h>
15
 
16
#include <vector>
17
#include <sys/time.h>
18
#include <sys/stat.h>
19
#include <signal.h>
20
#include <string>
21
#include "vme.h"
22
#include "CAEN_V729_DEF.h"
23
 
24
#define V729_OFFSET 0x880000
25
#define IREG_OFFSET 0x2000
26
#define V729_WAIT 1
27
 
28
 
29
#define TRUE 1
30
#define FALSE 0
31
 
32
uint32_t V729_module=0;
33
 
34
 
35
int timer_out;
36
struct sigaction oact;
37
 
38
//---------------------------------------------------------
39
void SigInt (int sig)
40
{
41
 
42
    timer_out=1;
43
}
44
 
45
//---------------------------------------------------------
46
void timerast (int signumber)
47
{
48
    timer_out = TRUE;
49
    fprintf(stderr,"TIMEOUT !!!\n");
50
}
51
 
52
//---------------------------------------------------------
53
void tmlnk (int tout)
54
{
55
    timer_out = FALSE;
56
    struct sigaction act;
57
    struct itimerval tdelay;
58
 
59
    act.sa_handler = timerast;
60
    sigemptyset (&act.sa_mask);
61
    act.sa_flags = 0;
62
 
63
    tdelay.it_value.tv_sec = tout / 100;
64
    tdelay.it_value.tv_usec = 10000 * (tout % 100);
65
    tdelay.it_interval.tv_sec = 0;
66
    tdelay.it_interval.tv_usec = 0;
67
 
68
    if (sigaction (SIGALRM, &act, &oact) < 0)
69
    {
70
        perror ("sigaction(tmlnk)");
71
        exit (EXIT_FAILURE);
72
    }
73
    if (setitimer (ITIMER_REAL, &tdelay, NULL) < 0)
74
    {
75
        perror ("setitimer(tmlnk)");
76
        exit (EXIT_FAILURE);
77
    }
78
}
79
 
80
//---------------------------------------------------------
81
void tmulk ()
82
{
83
    struct itimerval tdelay;
84
 
85
    tdelay.it_value.tv_sec = 0;
86
    tdelay.it_value.tv_usec = 0;
87
    tdelay.it_interval.tv_sec = 0;
88
    tdelay.it_interval.tv_usec = 0;
89
 
90
    if (setitimer (ITIMER_REAL, &tdelay, NULL) < 0)
91
    {
92
        perror ("setitimer(tmulk)");
93
        exit (EXIT_FAILURE);
94
    }
95
    if (sigaction (SIGALRM, &oact, NULL) < 0)
96
    {
97
        perror ("sigaction(tmulk)");
98
        exit (EXIT_FAILURE);
99
    }
100
}
101
 
102
//---------------------------------------------------------
103
int wait_while(int num){
104
  int i, tmp;
105
 
106
  for ( i =0; i <num; i++ ) tmp = 0;
107
  return tmp;
108
}
109
 
110
//---------------------------------------------------------
111
void V729_map( uint32_t addr)
112
{
113
  V729_module = addr;
114
  return;
115
}
116
 
117
//---------------------------------------------------------
118
void V729_info(FILE *kam)
119
{
120
  unsigned short code, mid, ver;
121
 
122
 
123
  VME_A24D16_R(V729_module+0xFA,&code);
124
  VME_A24D16_R(V729_module+0xFC,&mid);
125
  VME_A24D16_R(V729_module+0xFE,&ver);
126
  fprintf(kam, "code/mid/ver = 0x%04X/0x%04X/0x%04X\n", code, mid, ver);
127
  fprintf(kam, "Fixed code (0xFAF5) = 0x%04X\n", code);
128
  fprintf(kam, "Manufacturer/Type = 0x%02X/0x%03X\n",
129
         (mid & 0xFC00)>>10, mid & 0x3FF);
130
  fprintf(kam, "Version/Serial = %d/%d\n",
131
         (ver & 0xF000)>>12, ver & 0xFFF);
132
  return;
133
}
134
 
135
 
136
//---------------------------------------------------------
137
void V729_reg( uint32_t val){
138
 uint32_t push=0;
139
 
140
 VME_A24D16_W(V729_module+V729_FSR, &val);
141
 VME_A24D16_W(V729_module+V729_UFSR, &push); //push
142
 usleep(V729_WAIT);
143
 
144
}
145
 
146
 
147
//---------------------------------------------------------
148
void V729_reset(int nall,int nbefore,int obae,int obaf)
149
{
150
  uint32_t cbl;
151
 
152
//  cbl=4096+12-100;
153
  cbl=4096+12-nbefore;
154
  uint32_t val=0;
155
  VME_A24D16_W(V729_module+V729_RR, &val); // reset
156
  printf("nbefore=%d\t", nbefore);
157
  printf("nall=%d\t", nall);
158
  printf("obae=%d\t", obae);
159
  printf("obaf=%d\n", obaf);
160
 
161
// set AE
162
  V729_reg( (obae & 0xFF)<<8 ) ; //
163
  V729_reg( (obae & 0xF00) ) ; //
164
 
165
 
166
// set AF and CBL
167
  V729_reg( ((obaf & 0xFF)<<8) + (cbl & 0xFF)   );
168
  V729_reg( (obaf & 0xF00) + ((cbl & 0xF00)>>8) );
169
 
170
 
171
 
172
 VME_A24D16_W(V729_module+V729_SR,&nall); //total number of samples
173
 
174
  return;
175
}
176
//---------------------------------------------------------
177
 
178
void V729_set_bias(int range, int bias1, int bias2)
179
{
180
    int i;
181
    uint32_t bias;
182
 
183
    switch (range) {
184
        case 0: //User
185
            for (i=0x18;i<0x27;i+=4){
186
                VME_A24D16_W(V729_module+i, &bias1); //bias
187
                usleep(V729_WAIT);
188
                VME_A24D16_W(V729_module+i+2, &bias2); //bias
189
                usleep(V729_WAIT);
190
            }
191
            printf("Bias + %x  - %x\n", bias1, bias2);
192
            break;
193
        case 1: //Single Ended +
194
            for (i=0x18;i<0x27;i+=4){
195
                bias = 0xCC; VME_A24D16_W(V729_module+i, &bias); //bias
196
                usleep(V729_WAIT);
197
                bias =0x733; VME_A24D16_W(V729_module+i+2, &bias); //bias
198
                usleep(V729_WAIT);
199
            }
200
            break;
201
        case 2: //Single Ended -
202
            for (i=0x18;i<0x27;i+=4){
203
                bias =0x733; VME_A24D16_W(V729_module+i, &bias); //bias
204
                usleep(V729_WAIT);
205
                bias= 0xD99 ; VME_A24D16_W(V729_module+i+2, &bias); //bias
206
                usleep(V729_WAIT);
207
            }
208
            break;
209
        case 4: //Differential Unipolar
210
            for (i=0x18;i<0x27;i+=4){
211
                bias = 0x400; VME_A24D16_W(V729_module+i,&bias); //bias
212
                usleep(V729_WAIT);
213
                bias = 0xA66; VME_A24D16_W(V729_module+i+2, &bias); //bias
214
                usleep(V729_WAIT);
215
            }
216
            break;
217
        case 3: //Single Ended Bipolar
218
        case 5: //Differential Bipolar
219
        default:
220
            for (i=0x18;i<0x27;i+=2){
221
                bias=0x733; VME_A24D16_W(V729_module+i, &bias); //bias
222
                usleep(V729_WAIT);
223
            }
224
            break;
225
    }
226
    return;
227
}
228
 
229
//---------------------------------------------------------
230
void V729_aquisition_mode(uint32_t mode) // mode 0 aqusition mode, 0x30 buffers programming
231
{
232
#ifdef V729_DEBUG
233
  int status;
234
  VME_A24D16_R(V729_module+V729_CSR, &status);
235
  usleep(V729_WAIT);
236
  fprintf(stderr, "0x0E = 0x%04X\n", status);
237
#endif
238
 
239
  VME_A24D16_W(V729_module+V729_CSR, &mode); //aquisition mode
240
  usleep(V729_WAIT);
241
#ifdef V729_DEBUG
242
  VME_A24D16_W(V729_module+V729_CSR, &status);
243
  usleep(V729_WAIT);
244
  fprintf(stderr, "0x0E = 0x%04X\n", status);
245
#endif
246
  return;
247
}
248
 
249
//---------------------------------------------------------
250
void V729_soft_stop()
251
{
252
  uint32_t sw=1;
253
  VME_A24D16_W(V729_module+0x16,&sw);
254
//  usleep(V729_WAIT);
255
  sw =0;
256
  VME_A24D16_W(V729_module+0x16,&sw);
257
//  usleep(V729_WAIT);
258
  return;
259
}
260
 
261
//---------------------------------------------------------
262
void V729_clear_buffer()
263
{
264
    const int tout=100; /* 1/100 of a second */
265
    tmlnk (tout);
266
    uint32_t data1,data2;
267
    do {
268
        VME_A24D32_R(V729_module+V729_OBR1, &data1);
269
        if (timer_out) break;
270
    } while (data1 & (0x3<<29));
271
 
272
    do {
273
        VME_A24D32_R(V729_module+V729_OBR2, &data2);
274
        if (timer_out) break;
275
    } while (data2 & (0x3<<29));
276
 
277
    tmulk();
278
    return;
279
}
280
 
281
void V729_get_buffer(uint32_t *data1, uint32_t *data2)
282
{
283
    VME_A24D32_R(V729_module+V729_OBR1, data1);
284
//    usleep(V729_WAIT);
285
    VME_A24D32_R(V729_module+V729_OBR2, data2);
286
//    usleep(V729_WAIT);
287
    return;
288
}
289
int V729_status()
290
{
291
  uint32_t status;
292
  VME_A24D16_R(V729_module+V729_CSR, &status);
293
  return status;
294
}
295
 
296
 
297
//---------------------------------------------------------
298
void V729_init(uint32_t addr, int nall, int cbl, uint32_t bias1, uint32_t bias2){
299
  V729_map(addr);
300
  V729_info(stderr);
301
  V729_reset(nall,cbl,nall,0xC00);
302
  V729_set_bias(0,bias1,bias2);
303
  V729_aquisition_mode(0);
304
CAENVME_SetFIFOMode(udev,1);
305
  sleep(1);
306
}
307
 
308
 
309
//---------------------------------------------------------
310
int V729_event(int mask, int nall, uint32_t *data,uint32_t *data1,uint32_t *data2){
311
  uint32_t status;
312
  const int tout=100; /* 1/100 of a second */
313
  tmlnk (tout);
314
  int count=0;
315
 
316
  //status= 0x80 ; VME_A16D16_W(IREG_OFFSET+0x8,&status); // pulse ch 8
317
 
318
  status = 0x1a ; VME_A16D16_W(IREG_OFFSET+0xC,&status); // clr1 enable1  .... clear busy1 flag 
319
  do {
320
      //usleep(1);
321
      VME_A24D16_R(V729_module+V729_CSR, &status);
322
//    fprintf(stderr,"0x%X, 0x%X\n",status,(status & 0x5) ^ 0x5);
323
    count++;
324
    if (timer_out) {
325
       tmulk ();
326
       printf("[%d] daq=%x status AE01=%d AE23=%d Waiting for DATA TRG bit... at line %d\n",count , (status>>4)&0x3, status&0x1,(status>>2)&0x1 , __LINE__);
327
 
328
       V729_clear_buffer();
329
 
330
       return -1;
331
    }
332
  } while ((status & 0x5) ^ 0x5);
333
  tmulk ();
334
 
335
 
336
  int nb;
337
  const int blt=1;
338
  if (blt){
339
 
340
  VME_A24D32_FIFOBLTR(V729_module+V729_OBR1,data1,(nall+5)*sizeof(uint32_t),&nb);
341
  VME_A24D32_FIFOBLTR(V729_module+V729_OBR2,data2,(nall+5)*sizeof(uint32_t),&nb);
342
  for (int i=0;i<nall+5;i++){
343
    data[2*i]   = data1[i];
344
    data[2*i+1] = data2[i];
345
  }
346
  nb*=2;
347
  } else {
348
 
349
 
350
  VME_MRRST(); // MultiReadReset
351
  int nc=0;
352
  for (int i=0;i<nall+5;i++){
353
    //if (mask & 0x3)
354
    VME_A24D32_MR(V729_module+V729_OBR1, &data[nc++]);
355
    //if (mask & 0xc) 
356
    VME_A24D32_MR(V729_module+V729_OBR2, &data[nc++]);
357
  }
358
  int j = VME_MREXEC(data); // MultiReadExecute
359
  nb=j*sizeof(uint32_t);
360
 
361
  }
362
 
363
  return nb;
364
}
365
 
366
//---------------------------------------------------------
367
int V729_decode(uint32_t mask, int nall, uint32_t *data,  uint16_t *dadc, int debug){
368
  uint16_t *adc[4];
369
  for (int i=0;i<4;i++) adc[i] = &dadc[4+i*(nall+2)];
370
 
371
  int nc=0;
372
  int narrays=0;
373
  if (mask & 0x3) narrays++;
374
  if (mask & 0xc) narrays++;
375
 
376
  int indx[4] ={0,0,0,0};
377
  int shft[4] ={0,0,0,0};
378
  int ashft[4]={0,0,0,0};
379
  int nmask=0;
380
 
381
  for (int i=0;i<4;i++) if (mask & (1<<i) ) {
382
    indx[nmask] = i;
383
    shft[nmask] = (i%2)*12;
384
    if (( (mask & 0x3) > 0 ) && (i>1))  ashft[nmask]=1  ;
385
    else ashft[nmask]=0;
386
    nmask++;
387
  }
388
  for (int j=0;j<nmask;j++){
389
    nc=0;
390
    for (int i=0;i<nall+5;i++){
391
      int ii=narrays*i+ashft[j];
392
 
393
      uint32_t data1 = data[ii];
394
 
395
      if (data1 & (1<<31)) {
396
        if (debug) fprintf(stdout,"data1: empty flags: 0x%X, time tag: 0x%06X\n", (data1>>29) & 0x3, data1 & 0xFFFFFF);
397
      } else if ((data1>>29) & 0x3){
398
        if (nc<nall){
399
          adc[j][nc] = (data1>>shft[j]) & 0xFFF;
400
          if (debug) printf("[%d/%d] ADC%d adc0=%d\n", i,nc,indx[j], adc[j][nc]);
401
          nc++;
402
        }
403
 
404
      } else {
405
        if (debug) fprintf(stdout,"Data(%4d) %d indx=%d %d nc=%d(%d) %d 0x%08X\n", i, indx[j],narrays*i+ashft[j],j,nc,nmask,narrays, data1);
406
      }
407
    }
408
  }
409
  return nc;
410
}
411
//---------------------------------------------------------
412
 
413
// test program
414
#ifdef V729_MAIN
415
int ctrlc=0;
416
 
417
void CatchSig (int i){
418
    ctrlc = 1;
419
}
420
 
421
 
422
int main(int argc,char **argv){
423
 
424
   if (argc == 1) {
425
 
426
    printf ("*********************************************************************************:\n");
427
    printf ("Usage: %s <arguments> .........   CAEN V729A data aquisition:\n\n", argv[0]);
428
    printf ("Arguments: \n");
429
    printf ("-d <debuglevel>  \n");
430
    printf ("-b <bias+>  \n");
431
    printf ("-e <bias->  \n");
432
    printf ("-a <VME address>  \n");
433
    printf ("-c <n samples before stop>  \n");
434
    printf ("-n <number of events> \n");
435
    printf ("-l <nall> number of samples \n");
436
    printf ("-m <channel mask: 4bits (1 bit/ch)> \n");
437
    printf ("-o <output file name> \n");
438
 
439
    printf ("*********************************************************************************:\n");
440
    exit (-1);
441
  }
442
 
443
  uint32_t mask=0xF;
444
  int  cbl=13;
445
  int nall=1330;
446
  char filename[0xFF]="";
447
  int verbose = 0;
448
  int neve    = 1;
449
  uint32_t addr= V729_OFFSET;
450
  uint32_t bias1 = 0x600; // vecje vrednosti povzročajo težave in zacno kanali oscilirat ....
451
  uint32_t bias2 = 0x200;
452
  int append=0;
453
  int c=0;
454
  while ((c = getopt (argc, argv, "b:e:a:d:c:l:n:o:m:f:")) != -1)
455
    switch (c){
456
      case 'd':
457
        verbose=atoi(optarg);
458
        break;
459
      case 'c':
460
        cbl=atoi(optarg);
461
        break;
462
      case 'l':
463
        nall=atoi(optarg);
464
 
465
        if (nall%16) {
466
          printf ("buffer length should be multiple of 16 , modulo = %d\n",nall%16);
467
         // exit(-1);
468
        }
469
        break;    
470
      case 'n':
471
        neve=atoi(optarg);
472
        break;  
473
      case 'a':
474
        addr=strtoul (optarg,NULL,0);
475
        break;             // address
476
      case 'b':
477
        bias1=strtoul (optarg,NULL,0);
478
        break;             // bias
479
      case 'e':
480
        bias2=strtoul (optarg,NULL,0);
481
        break;             // bias
482
 
483
      case 'm':
484
        mask=strtoul (optarg,NULL,0);
485
        break;             // mask 
486
      case 'o':
487
        sprintf(filename,"%s", optarg );
488
        append=0;
489
        break;       // output
490
      case 'f':
491
        sprintf(filename,"%s", optarg );
492
        append=1;
493
        break;       // output
494
    }
495
 
496
// intercept routine
497
  if (signal (SIGINT, CatchSig) == SIG_ERR)  perror ("sigignore");
498
 
499
 
500
  // reset timers
501
  time_t t,told=0, tstart;
502
  time(&t);
503
  tstart=t;
504
 
505
  // open file
506
  FILE *fp=NULL;
507
  int output=0;
508
  if (strlen(filename)>0) {
509
    if (verbose) printf("Data in the file:%s\n", filename);
510
    if (append) fp=fopen(filename,"a");
511
    else        fp=fopen(filename,"w");
512
    output=1;
513
  }
514
 
515
  // alloocate storage
516
  uint32_t *data = new uint32_t[2*(nall+5)];
517
  uint32_t *data1 = new uint32_t[2*(nall+5)];
518
  uint32_t *data2 = new uint32_t[2*(nall+5)];
519
  int nmask=0;
520
  for (int i=0;i<4;i++) if (mask & (1<<i)) nmask++;
521
  int adclen = nall+2;
522
  int len    = nmask* adclen+2;
523
  uint16_t *adc = new uint16_t[len]; // 4 channels + 4 ch header + 1 event hdr
524
 
525
  // write headers
526
  uint16_t *evhdr  = &adc[0];
527
  evhdr[0] = 0;
528
  evhdr[1] = len  *sizeof(uint16_t);
529
  int imask=0;
530
  for (int ch=0;ch<4;ch++){
531
    if (  mask & (1<<ch) ) {
532
      uint16_t *chhdr= &adc[2+imask*adclen];
533
      chhdr[0] = ch+1;
534
      chhdr[1] = adclen *sizeof(uint16_t);
535
      imask++;
536
    }
537
  }
538
 
539
  // start
540
  int ncount =0;
541
  int nerrors=0;
542
  int nball  =0;
543
 
544
  // open VME and initialize board
545
  char *serial = new char[100];
546
 
547
 
548
  VME_START(serial);
549
  printf("CAEN V1718 BoardFWRelease %s\n", serial);
550
 
551
  V729_init(addr, nall, cbl, bias1,bias2);
552
 
553
  // event loop
554
  for (int j=0; j<neve; j++) {
555
     if (ctrlc) break;
556
     int nb= V729_event(mask,nall,data, data1,data2);
557
     if (nb<0) {  // timeout
558
       j--;
559
       nerrors++;
560
     } else {
561
 
562
       V729_decode(mask,nall,data,adc, verbose);
563
 
564
       // V729_clear_buffer();
565
       if (output) nball += fwrite(adc  ,   1, sizeof(uint16_t)*len, fp);
566
 
567
       ncount++;
568
     }
569
     time(&t);
570
     if (t/4!=told ) printf("%d events in %2.2f min (%d s) USBerr=%d TIMEOUTS=%d %s",ncount, (double)(t-tstart)/60.,int(t-tstart), VMEerrors, nerrors, ctime(&t));
571
     told=t/4;  
572
  }
573
 
574
  // end
575
  if (output) fclose(fp);
576
  VME_STOP();
577
  time(&t);
578
  printf("%d events in %2.2f min  (%d s) USBerr=%d TIMEOUTS=%d  %s\n",ncount, (double)(t-tstart)/60.,int(t-tstart),VMEerrors, nerrors, ctime(&t));
579
  return 0;
580
}
581
 
582
#endif //V729_MAIN