Subversion Repositories f9daq

Rev

Blame | Last modification | View Log | RSS feed

#include <stdlib.h>
#include <stdio.h>
#include <signal.h>
#include <time.h>
#include <string.h>
#include <sys/types.h>
#include <sys/time.h>
#include <ctype.h>
#include <unistd.h>

#ifdef MRP
#include <rp.h>
#else
#include "calib.h"
#endif

#include "fpga_osc.h"

#define TRUE -1
#define FALSE 0

int timer_out; struct sigaction oact;

int ctrl_c=0;

void SigInt (int sig) {
  ctrl_c = 1;
}


void timerast (signumber, code, context) int signumber, code; struct sigcontext context; {
  fprintf(stderr, "Timeout\n");
  timer_out = TRUE;
}

void tmlnk (tout) int tout; {
  struct sigaction act;
  struct itimerval tdelay;

  act.sa_handler = timerast;
  sigemptyset (&act.sa_mask);
  act.sa_flags = 0;

  tdelay.it_value.tv_sec = tout / 100;
  tdelay.it_value.tv_usec = 10000 * (tout % 100);
  tdelay.it_interval.tv_sec = 0;
  tdelay.it_interval.tv_usec = 0;

  if (sigaction (SIGALRM, &act, &oact) < 0)
  {
    perror ("sigaction(tmlnk)");
    exit (EXIT_FAILURE);
  }
  if (setitimer (ITIMER_REAL, &tdelay, NULL) < 0)
  {
    perror ("setitimer(tmlnk)");
    exit (EXIT_FAILURE);
  }
}

void tmulk () {
  struct itimerval tdelay;

  tdelay.it_value.tv_sec = 0;
  tdelay.it_value.tv_usec = 0;
  tdelay.it_interval.tv_sec = 0;
  tdelay.it_interval.tv_usec = 0;

  if (setitimer (ITIMER_REAL, &tdelay, NULL) < 0)
  {
    perror ("setitimer(tmulk)");
    exit (EXIT_FAILURE);
  }
  if (sigaction (SIGALRM, &oact, NULL) < 0)
  {
    perror ("sigaction(tmulk)");
    exit (EXIT_FAILURE);
  }
}

#ifndef MRP
rp_calib_params_t rp_calib_params; /** Pointer to externally defined calibration parameters. */ rp_calib_params_t *gen_calib_params = NULL;
#endif
int daq_init (char * buff) {
#ifdef DEBUG
        fprintf (stderr, "Server: init\n");
#endif
   int * hdr = (int *) buff;
   int delay = hdr[0];
   int decimation = hdr[1];
   float threshold_voltage = hdr[2]/1000.;
   fprintf(stderr, "delay = %d\tdecimation = %d\tthreshold = %f\n", delay, decimation, threshold_voltage);

/*

   rp_default_calib_params(&rp_calib_params);
   gen_calib_params = &rp_calib_params;
   if(rp_read_calib_params(gen_calib_params) < 0) {
       fprintf(stderr, "rp_read_calib_params() failed, using default"
           " parameters\n");
   }

*/


  // use this to acquire calibrated offset: int offset = gen_calib_params->fe_ch1_dc_offs;
#ifdef MRP
        if(rp_Init() != RP_OK){
          fprintf(stderr, "Rp api init failed!\n");
        }
        rp_AcqReset();
        const int rpdecimation[6]={RP_DEC_1 ,RP_DEC_8 ,RP_DEC_64,
                                   RP_DEC_1024 ,RP_DEC_8192  ,RP_DEC_65536   };
        rp_AcqSetDecimation(rpdecimation[decimation%6]);
        const int c[2] = {RP_CH_1, RP_CH_2};
        rp_AcqSetTriggerLevel(c[0],threshold_voltage); //Trig level is set in Volts while in SCPI
        rp_AcqSetTriggerLevel(c[1],threshold_voltage);  
        rp_AcqSetTriggerDelay(delay);
        return 0;
#else
  // initialization
  int start = osc_fpga_init();
  if(start)
  {
      printf("osc_fpga_init didn't work, retval = %d",start);
      return -1;
  }

  // set acquisition parameters
  osc_fpga_set_trigger_delay(delay);
  g_osc_fpga_reg_mem->data_dec = decimation;
  osc_fpga_reset();
  g_osc_fpga_reg_mem->chb_thr = osc_fpga_cnv_v_to_cnt(threshold_voltage); //sets trigger voltage
#endif
  fprintf(stderr, "%s : %d\n", __FILE__, __LINE__);
  return 0;
}

int daq_end () {
#ifdef DEBUG
        fprintf (stderr, "Server: end\n");
#endif
#ifdef MRP
  rp_Release();
#else
  osc_fpga_exit();
#endif
  return 0;
}

int daq_clear () {
#ifdef DEBUG
        fprintf (stderr, "Server: clear\n");
#endif
  return 0;
}


int16_t  chdata[16*1024];
float *  chfdata = (float *) chdata;
int daq_run (const char *par, char ** data, int *maxlen)

{
 
  int *data_buf;
  int neve;

  unsigned short *sbuff   = (unsigned short *) (par);
  unsigned short maxeve   = sbuff[0];
  unsigned short nsamples = sbuff[1];
  unsigned short tout     = sbuff[2];
  unsigned char trigger   = par[6];
  unsigned char chmask    = par[7];
  clock_t t,t0;
  neve = 0;

  t0=clock();  
  int eventsize = 0;
  if (chmask & 0x1) eventsize += (nsamples+2);
  if (chmask & 0x2) eventsize += (nsamples+2);
  eventsize+=4;
  int required_size = eventsize * maxeve+3;
 
#ifdef DEBUG
        time_t mtime;
        time(&mtime);
        fprintf (stderr, "daq_run:\tmaxeve %d\tnsamples=%d\ttimeout=%d\ttrigger=%d\tchmask=%d\t%s",  maxeve ,nsamples,tout,trigger,chmask, ctime(&mtime)); //
#endif
   
   
   if (required_size > *maxlen ) {
     free (*data);
     *data = (char *) malloc(required_size *sizeof(int));
     fprintf(stderr, "New Buffer with size %d allocated. Old size %d\n", required_size, *maxlen);
     *maxlen = required_size;
   }

  int *ibuf  = (int *)  (*data);
 
 
  data_buf = ibuf + 3;
  const int sleeptime = 135*nsamples/16386; //135 us for 16386 samples and to fill the 16k ADC buffer/

  for (int ieve=0; ieve < maxeve; ieve++)
    {

#ifdef MRP

rp_AcqStart();
usleep(sleeptime);
rp_AcqSetTriggerSrc(trigger);
timer_out = FALSE;
tmlnk (tout);
rp_acq_trig_src_t source;
do {
  rp_AcqGetTriggerSrc(&source);
  //printf("TRG %d src %d\n", trigger, source);  
  if (timer_out || ctrl_c) break;
} while (source == trigger);
 
tmulk ();
usleep(sleeptime);


#else

       osc_fpga_arm_trigger();
       usleep(sleeptime);
       osc_fpga_set_trigger(trigger);

       while (g_osc_fpga_reg_mem->trig_source != 0){
           if (timer_out || ctrl_c) break;
       }
       // with this loop the program waits until the acquistion is completed before continue.
       int trig_ptr = g_osc_fpga_reg_mem->wr_ptr_trigger; // get pointer to mem. adress where trigger was met
       int * ch_signal[2];
       osc_fpga_get_sig_ptr(&ch_signal[0], &ch_signal[1]);
#endif
       *(data_buf++) = 0x2;
       *(data_buf++) = chmask;

       for (int id = 0;id<2;id++){
         if ( !(chmask & (1 << id)) ) continue;

         *(data_buf++) = id;
         *(data_buf++) = nsamples;
#ifdef MRP
        const int c[2] = {RP_CH_1, RP_CH_2};
        unsigned int isamples = nsamples;  
        rp_AcqGetLatestDataV(c[id], &isamples, (float *) data_buf );
        data_buf+=nsamples;
#else

         const int BUF = 16*1024;
         const int offset =  0;
         if (trig_ptr > (BUF-nsamples)) // Enter logic to transition from end to beginning of cha_signal buffer.
         {
            for (int i=trig_ptr;i<BUF;i++) *(data_buf++) = ch_signal[id][i]-offset;
            for (int i=0;i<nsamples-(BUF-trig_ptr);i++) *(data_buf++) = ch_signal[id][i]-offset;
         }
         else // Enter simple logic to send sampleSize from trigger point
         {
           for (int i=0;i<nsamples;i++) *(data_buf++) = ch_signal[id][trig_ptr + i]-offset;
         }
#endif
       }
       *(data_buf++) = 0x3;
       *(data_buf++) = neve;
       neve++;
       if (ieve+1 % 500 == 0) fprintf(stderr, "Event %d\n", ieve);
       if (timer_out) break;

    }


 
  int *len   = ibuf;
  int *nev   = ibuf + 1;
  float *dt = (float *)(ibuf + 2);
 
  *len   = (data_buf-len)*sizeof(int);
  *nev   = neve;
  t = clock();
  *dt = t-t0;
  *dt /= CLOCKS_PER_SEC;
 
  return *len;
}

#define MAXLEN 0XFFFF
struct RUNHDR {
  unsigned short neve;
  unsigned short nsamples;
  unsigned short tout;
  unsigned char trigger;
  unsigned char mask;
  int nloops ;
  int data [MAXLEN];
} ;


struct INIHDR {
  int delay ;  
  int decimation;
  int threshold;
};


int daq_help(char *fname, struct INIHDR * i, struct RUNHDR *r, int verbosity){

  printf("-o filename ... output filename %s\n", fname);
  printf("-v verbose ... verbosity %d\n", verbosity);
  printf("-b decimation ... decimation %d\n", i->decimation);
  printf("-i timeout ... interrupt timeout %d\n", r->tout);
  printf("-s nsamples ... number of samples %d\n", r->nsamples);
  printf("-d delay ... delay %d\n", i->delay);
  printf("-t trigger ... trigger type %d\n", r->trigger);
  printf("-l level ... trigger level %f\n", i->threshold*0.001);
  printf("-m mask ... channel mask %d\n", r->mask );
  printf("-n neve ... number of events per call %d\n", r->neve);
  printf("-r nloops ... number of calls %d\n", r->nloops);
  return 0;
}



int daq_main( int argc , char ** argv) {
  // intercept routine
  if (signal (SIGINT, SigInt) == SIG_ERR) {
    perror ("sigignore");
  }


  char filename[0xFF]="";


struct INIHDR inihdr = {
  .decimation = 1,
  .threshold = 100,
  .delay = 1024
};



struct RUNHDR runhdr;


  runhdr.neve =10000;
  runhdr.nsamples = 1024;
  runhdr.tout = 1000;
  runhdr.trigger = 1;
  runhdr.mask = 0x1;
  runhdr.nloops = 1;

  int verbose = 0;
  int argdata = 0;

  if (argc <2) {
    daq_help(filename, &inihdr, &runhdr, verbose);
    exit(-1);
  }

  opterr = 0;
  int c;
  while ((c = getopt (argc, argv, "o:v:b:i:s:d:t:l:m:n:r:h")) != -1)
    switch (c) {
      case 'o':
        sprintf(filename,"%s", optarg );
        break; // output
      case 'v':
        verbose = strtoul (optarg,NULL,0);
        break; // verbosity
      case 'b':
        inihdr.decimation = strtoul (optarg,NULL,0);
        break;
      case 'i':
        runhdr.tout = strtoul (optarg,NULL,0);
        break;
      case 's':
        runhdr.nsamples = strtoul (optarg,NULL,0);
        break;
      case 'd':
        inihdr.delay = strtoul (optarg,NULL,0);
        break;
      case 't':
        runhdr.trigger = strtoul (optarg,NULL,0);
        break;
      case 'm':
        runhdr.mask = strtoul (optarg,NULL,0);
        break;
      case 'n':
        runhdr.neve = atoi (optarg);
        break;
      case 'r':
        runhdr.nloops = atoi (optarg);
        break;
      case 'l':
        inihdr.threshold = (int) (1000*atof (optarg));
        break;
      case 'h':
        daq_help(filename, &inihdr, &runhdr, verbose);
        break;
      case '?':
        if (optopt == 'c')
          fprintf (stderr, "Option -%c requires an argument.\n", optopt);
        else if (isprint (optopt))
          fprintf (stderr, "Unknown option `-%c'.\n", optopt);
        else
          fprintf (stderr,
                   "Unknown option character `\\x%x'.\n",
                   optopt);
        return 1;
      default:
        abort ();
    }
  for (int i=optind; i<argc; i++) argdata = strtoul (argv[i],NULL,0);
  if (verbose) daq_help(filename, &inihdr, &runhdr, verbose);
 
  printf("argdata %d nloops %d\n",argdata,runhdr.nloops);

  daq_init((char *)&inihdr);
  FILE *fp=NULL;
  if (strlen(filename)>0) fp = fopen(filename, "wb");
 
 
  int maxlen = MAXLEN;
  char *data = (char *) malloc(maxlen * sizeof(int));
  time_t t,tstart;
  time(&tstart);

  for (int i=0;i< runhdr.nloops;i++){
    int nb =daq_run((const char*) &runhdr, &data, &maxlen);
    if (ctrl_c) break;
    time(&t);
    fprintf(stderr, "Loop %d dt=%d s\n", i, (int)(t-tstart));
   
    if (fp) {
      fprintf(stderr, "Writing %d to %s", nb, filename);
      fwrite(data, 1, nb, fp);
    }
   
  }
  time(&t);
  fprintf(stderr, "Total events %d in  %d s\n", runhdr.nloops*runhdr.neve, (int)(t-tstart));
  if (fp) fclose(fp);
  if (data!=NULL) free(data);
  return 0;
}