Subversion Repositories f9daq

Rev

Rev 231 | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
228 f9daq 1
#include <stdlib.h> 
2
#include <stdio.h> 
3
#include <signal.h> 
4
#include <time.h> 
5
#include <string.h> 
6
#include <sys/types.h> 
7
#include <sys/time.h> 
8
#include <ctype.h> 
9
#include <unistd.h>
10
 
11
#ifdef MRP
12
#include "redpitaya/rp.h"
13
#else
14
#include "calib.h"
15
#endif
16
 
17
#include "fpga_osc.h" 
18
 
19
#define TRUE -1 
20
#define FALSE 0
21
 
22
int timer_out; struct sigaction oact;
23
 
24
int ctrl_c=0;
25
 
26
void SigInt (int sig) {
27
  ctrl_c = 1;
28
}
29
 
30
 
31
void timerast (signumber, code, context) int signumber, code; struct sigcontext context; {
231 f9daq 32
  fprintf(stderr, "Timeout\n");
228 f9daq 33
  timer_out = TRUE;
34
}
35
 
36
void tmlnk (tout) int tout; {
37
  struct sigaction act;
38
  struct itimerval tdelay;
39
 
40
  act.sa_handler = timerast;
41
  sigemptyset (&act.sa_mask);
42
  act.sa_flags = 0;
43
 
44
  tdelay.it_value.tv_sec = tout / 100;
45
  tdelay.it_value.tv_usec = 10000 * (tout % 100);
46
  tdelay.it_interval.tv_sec = 0;
47
  tdelay.it_interval.tv_usec = 0;
48
 
49
  if (sigaction (SIGALRM, &act, &oact) < 0)
50
  {
51
    perror ("sigaction(tmlnk)");
52
    exit (EXIT_FAILURE);
53
  }
54
  if (setitimer (ITIMER_REAL, &tdelay, NULL) < 0)
55
  {
56
    perror ("setitimer(tmlnk)");
57
    exit (EXIT_FAILURE);
58
  }
59
}
60
 
61
void tmulk () {
62
  struct itimerval tdelay;
63
 
64
  tdelay.it_value.tv_sec = 0;
65
  tdelay.it_value.tv_usec = 0;
66
  tdelay.it_interval.tv_sec = 0;
67
  tdelay.it_interval.tv_usec = 0;
68
 
69
  if (setitimer (ITIMER_REAL, &tdelay, NULL) < 0)
70
  {
71
    perror ("setitimer(tmulk)");
72
    exit (EXIT_FAILURE);
73
  }
74
  if (sigaction (SIGALRM, &oact, NULL) < 0)
75
  {
76
    perror ("sigaction(tmulk)");
77
    exit (EXIT_FAILURE);
78
  }
79
}
80
 
81
#ifndef MRP
82
rp_calib_params_t rp_calib_params; /** Pointer to externally defined calibration parameters. */ rp_calib_params_t *gen_calib_params = NULL;
83
#endif
231 f9daq 84
int daq_init (char * buff) {
228 f9daq 85
#ifdef DEBUG
86
        fprintf (stderr, "Server: init\n");
87
#endif
88
   int * hdr = (int *) buff;
89
   int delay = hdr[0];
90
   int decimation = hdr[1];
91
   float threshold_voltage = hdr[2]/1000.;
92
   fprintf(stderr, "delay = %d\tdecimation = %d\tthreshold = %f\n", delay, decimation, threshold_voltage);
93
 
94
/*
95
 
96
   rp_default_calib_params(&rp_calib_params);
97
   gen_calib_params = &rp_calib_params;
98
   if(rp_read_calib_params(gen_calib_params) < 0) {
99
       fprintf(stderr, "rp_read_calib_params() failed, using default"
100
           " parameters\n");
101
   }
102
 
103
*/
104
 
105
  // use this to acquire calibrated offset: int offset = gen_calib_params->fe_ch1_dc_offs;
106
#ifdef MRP
107
        if(rp_Init() != RP_OK){
108
          fprintf(stderr, "Rp api init failed!\n");
109
        }
110
        rp_AcqReset();
111
        rp_AcqSetDecimation(decimation);
112
        const int c[2] = {RP_CH_1, RP_CH_2};
113
        rp_AcqSetTriggerLevel(c[0],threshold_voltage); //Trig level is set in Volts while in SCPI 
114
        rp_AcqSetTriggerLevel(c[1],threshold_voltage);  
115
        rp_AcqSetTriggerDelay(delay);
116
        return 0;
117
#else
118
  // initialization
119
  int start = osc_fpga_init();
120
  if(start)
121
  {
122
      printf("osc_fpga_init didn't work, retval = %d",start);
123
      return -1;
124
  }
125
 
126
  // set acquisition parameters
127
  osc_fpga_set_trigger_delay(delay);
128
  g_osc_fpga_reg_mem->data_dec = decimation;
129
  osc_fpga_reset();
130
  g_osc_fpga_reg_mem->chb_thr = osc_fpga_cnv_v_to_cnt(threshold_voltage); //sets trigger voltage
131
#endif
132
  fprintf(stderr, "%s : %d\n", __FILE__, __LINE__);
133
  return 0;
134
}
135
 
136
int daq_end () {
137
#ifdef DEBUG
138
        fprintf (stderr, "Server: end\n");
139
#endif
140
#ifdef MRP
141
  rp_Release();
142
#else
143
  osc_fpga_exit();
144
#endif
145
  return 0;
146
}
147
 
148
int daq_clear () {
149
#ifdef DEBUG
150
        fprintf (stderr, "Server: clear\n");
151
#endif
152
  return 0;
153
}
154
 
231 f9daq 155
 
156
int16_t  chdata[16*1024];
232 f9daq 157
float *  chfdata = (float *) chdata;
228 f9daq 158
int daq_run (const char *par, char ** data, int *maxlen)
159
 
160
{
161
 
162
  int *data_buf;
163
  int neve;
164
 
231 f9daq 165
  unsigned short *sbuff   = (unsigned short *) (par);
228 f9daq 166
  unsigned short maxeve   = sbuff[0];
167
  unsigned short nsamples = sbuff[1];
168
  unsigned short tout     = sbuff[2];
231 f9daq 169
  unsigned char trigger   = par[6];
170
  unsigned char chmask    = par[7];
232 f9daq 171
  clock_t t,t0;
172
  neve = 0;
228 f9daq 173
 
232 f9daq 174
  t0=clock();  
228 f9daq 175
  int eventsize = 0;
176
  if (chmask & 0x1) eventsize += (nsamples+2);
177
  if (chmask & 0x2) eventsize += (nsamples+2);
178
  eventsize+=4;
179
  int required_size = eventsize * maxeve+3;
180
 
181
#ifdef DEBUG
232 f9daq 182
        time_t mtime;
183
        time(&mtime);
184
        fprintf (stderr, "daq_run:\tmaxeve %d\tnsamples=%d\ttimeout=%d\ttrigger=%d\tchmask=%d\t%s",  maxeve ,nsamples,tout,trigger,chmask, ctime(&mtime)); // 
228 f9daq 185
#endif
186
 
187
 
188
   if (required_size > *maxlen ) {
189
     free (*data);
190
     *data = (char *) malloc(required_size *sizeof(int));
191
     fprintf(stderr, "New Buffer with size %d allocated. Old size %d\n", required_size, *maxlen);
192
     *maxlen = required_size;
193
   }
194
 
195
  int *ibuf  = (int *)  (*data);
196
 
197
 
198
  data_buf = ibuf + 3;
199
  const int sleeptime = 135*nsamples/16386; //135 us for 16386 samples and to fill the 16k ADC buffer/
200
 
201
  for (int ieve=0; ieve < maxeve; ieve++)
202
    {
203
 
204
#ifdef MRP
205
 
206
rp_AcqStart();
207
usleep(sleeptime);
208
rp_AcqSetTriggerSrc(trigger);
231 f9daq 209
timer_out = FALSE;
210
tmlnk (tout);
211
rp_acq_trig_src_t source;
212
do {
213
  rp_AcqGetTriggerSrc(&source);
214
  //printf("TRG %d src %d\n", trigger, source);  
215
  if (timer_out || ctrl_c) break;
216
} while (source == trigger);
217
 
218
tmulk ();
219
usleep(sleeptime);
220
 
228 f9daq 221
 
222
#else
223
 
224
       osc_fpga_arm_trigger();
225
       usleep(sleeptime);
226
       osc_fpga_set_trigger(trigger);
227
 
231 f9daq 228
       while (g_osc_fpga_reg_mem->trig_source != 0){
229
           if (timer_out || ctrl_c) break;
230
       }
228 f9daq 231
       // with this loop the program waits until the acquistion is completed before continue.
232
       int trig_ptr = g_osc_fpga_reg_mem->wr_ptr_trigger; // get pointer to mem. adress where trigger was met
233
       int * ch_signal[2];
234
       osc_fpga_get_sig_ptr(&ch_signal[0], &ch_signal[1]);
235
#endif
236
       *(data_buf++) = 0x2;
237
       *(data_buf++) = chmask;
238
 
239
       for (int id = 0;id<2;id++){
240
         if ( !(chmask & (1 << id)) ) continue;
241
 
242
         *(data_buf++) = id;
243
         *(data_buf++) = nsamples;
244
#ifdef MRP
245
        const int c[2] = {RP_CH_1, RP_CH_2};
246
        unsigned int isamples = nsamples;  
232 f9daq 247
        rp_AcqGetLatestDataV(c[id], &isamples, (float *) data_buf );
248
        data_buf+=nsamples;
228 f9daq 249
#else
250
 
251
         const int BUF = 16*1024;
252
         const int offset =  0;
253
         if (trig_ptr > (BUF-nsamples)) // Enter logic to transition from end to beginning of cha_signal buffer.
254
         {
255
            for (int i=trig_ptr;i<BUF;i++) *(data_buf++) = ch_signal[id][i]-offset;
256
            for (int i=0;i<nsamples-(BUF-trig_ptr);i++) *(data_buf++) = ch_signal[id][i]-offset;
257
         }
258
         else // Enter simple logic to send sampleSize from trigger point
259
         {
260
           for (int i=0;i<nsamples;i++) *(data_buf++) = ch_signal[id][trig_ptr + i]-offset;
261
         }
262
#endif
263
       }
264
       *(data_buf++) = 0x3;
265
       *(data_buf++) = neve;
266
       neve++;
231 f9daq 267
       if (ieve+1 % 500 == 0) fprintf(stderr, "Event %d\n", ieve);
228 f9daq 268
       if (timer_out) break;
269
 
270
    }
271
 
231 f9daq 272
 
228 f9daq 273
 
274
  int *len   = ibuf;
275
  int *nev   = ibuf + 1;
232 f9daq 276
  float *dt = (float *)(ibuf + 2);
228 f9daq 277
 
278
  *len   = (data_buf-len)*sizeof(int);
279
  *nev   = neve;
232 f9daq 280
  t = clock();
281
  *dt = t-t0;
282
  *dt /= CLOCKS_PER_SEC;
228 f9daq 283
 
284
  return *len;
285
}
286
 
287
#define MAXLEN 0XFFFF
288
struct RUNHDR {
289
  unsigned short neve;
290
  unsigned short nsamples;
291
  unsigned short tout;
292
  unsigned char trigger;
293
  unsigned char mask;
294
  int nloops ;
295
  int data [MAXLEN];
296
} ;
297
 
298
 
299
struct INIHDR {
300
  int delay ;  
301
  int decimation;
302
  int threshold;
303
};
304
 
305
 
306
int daq_help(char *fname, struct INIHDR * i, struct RUNHDR *r, int verbosity){
307
 
308
  printf("-o filename ... output filename %s\n", fname);
309
  printf("-v verbose ... verbosity %d\n", verbosity);
310
  printf("-b decimation ... decimation %d\n", i->decimation);
311
  printf("-i timeout ... interrupt timeout %d\n", r->tout);
312
  printf("-s nsamples ... number of samples %d\n", r->nsamples);
313
  printf("-d delay ... delay %d\n", i->delay);
314
  printf("-t trigger ... trigger type %d\n", r->trigger);
315
  printf("-l level ... trigger level %f\n", i->threshold*0.001);
316
  printf("-m mask ... channel mask %d\n", r->mask );
317
  printf("-n neve ... number of events per call %d\n", r->neve);
318
  printf("-r nloops ... number of calls %d\n", r->nloops);
319
  return 0;
320
}
321
 
322
 
323
 
324
int daq_main( int argc , char ** argv) {
325
  // intercept routine
326
  if (signal (SIGINT, SigInt) == SIG_ERR) {
327
    perror ("sigignore");
328
  }
329
 
330
 
331
  char filename[0xFF]="";
332
 
333
 
334
struct INIHDR inihdr = {
335
  .decimation = 1,
336
  .threshold = 100,
337
  .delay = 1024
338
};
339
 
340
 
341
 
342
struct RUNHDR runhdr;
343
 
344
 
345
  runhdr.neve =10000;
346
  runhdr.nsamples = 1024;
347
  runhdr.tout = 1000;
348
  runhdr.trigger = 1;
349
  runhdr.mask = 0x1;
350
  runhdr.nloops = 1;
351
 
352
  int verbose = 0;
353
  int argdata = 0;
354
 
355
  if (argc <2) {
356
    daq_help(filename, &inihdr, &runhdr, verbose);
357
    exit(-1);
358
  }
359
 
360
  opterr = 0;
361
  int c;
362
  while ((c = getopt (argc, argv, "o:v:b:i:s:d:t:l:m:n:r:h")) != -1)
363
    switch (c) {
364
      case 'o':
365
        sprintf(filename,"%s", optarg );
366
        break; // output
367
      case 'v':
368
        verbose = strtoul (optarg,NULL,0);
369
        break; // verbosity
370
      case 'b':
371
        inihdr.decimation = strtoul (optarg,NULL,0);
372
        break;
373
      case 'i':
374
        runhdr.tout = strtoul (optarg,NULL,0);
375
        break;
376
      case 's':
377
        runhdr.nsamples = strtoul (optarg,NULL,0);
378
        break;
379
      case 'd':
380
        inihdr.delay = strtoul (optarg,NULL,0);
381
        break;
382
      case 't':
383
        runhdr.trigger = strtoul (optarg,NULL,0);
384
        break;
385
      case 'm':
386
        runhdr.mask = strtoul (optarg,NULL,0);
387
        break;
388
      case 'n':
389
        runhdr.neve = atoi (optarg);
390
        break;
391
      case 'r':
392
        runhdr.nloops = atoi (optarg);
393
        break;
394
      case 'l':
395
        inihdr.threshold = (int) (1000*atof (optarg));
396
        break;
397
      case 'h':
398
        daq_help(filename, &inihdr, &runhdr, verbose);
399
        break;
400
      case '?':
401
        if (optopt == 'c')
402
          fprintf (stderr, "Option -%c requires an argument.\n", optopt);
403
        else if (isprint (optopt))
404
          fprintf (stderr, "Unknown option `-%c'.\n", optopt);
405
        else
406
          fprintf (stderr,
407
                   "Unknown option character `\\x%x'.\n",
408
                   optopt);
409
        return 1;
410
      default:
411
        abort ();
412
    }
413
  for (int i=optind; i<argc; i++) argdata = strtoul (argv[i],NULL,0);
414
  if (verbose) daq_help(filename, &inihdr, &runhdr, verbose);
415
 
416
  printf("argdata %d nloops %d\n",argdata,runhdr.nloops);
417
 
231 f9daq 418
  daq_init((char *)&inihdr);
228 f9daq 419
  FILE *fp=NULL;
420
  if (strlen(filename)>0) fp = fopen(filename, "wb");
421
 
422
 
423
  int maxlen = MAXLEN;
424
  char *data = (char *) malloc(maxlen * sizeof(int));
425
  time_t t,tstart;
426
  time(&tstart);
427
 
428
  for (int i=0;i< runhdr.nloops;i++){
429
    int nb =daq_run((const char*) &runhdr, &data, &maxlen);
430
    if (ctrl_c) break;
431
    time(&t);
432
    fprintf(stderr, "Loop %d dt=%d s\n", i, (int)(t-tstart));
433
 
434
    if (fp) {
435
      fprintf(stderr, "Writing %d to %s", nb, filename);
436
      fwrite(data, 1, nb, fp);
437
    }
438
 
439
  }
440
  time(&t);
441
  fprintf(stderr, "Total events %d in  %d s\n", runhdr.nloops*runhdr.neve, (int)(t-tstart));
442
  if (fp) fclose(fp);
443
  if (data!=NULL) free(data);
444
  return 0;
445
}