Subversion Repositories f9daq

Rev

Blame | Last modification | View Log | RSS feed

  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 <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; {
  32.   fprintf(stderr, "Timeout\n");
  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
  84. int daq_init (char * buff) {
  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.         const int rpdecimation[6]={RP_DEC_1 ,RP_DEC_8 ,RP_DEC_64,
  112.                                    RP_DEC_1024 ,RP_DEC_8192  ,RP_DEC_65536   };
  113.         rp_AcqSetDecimation(rpdecimation[decimation%6]);
  114.         const int c[2] = {RP_CH_1, RP_CH_2};
  115.         rp_AcqSetTriggerLevel(c[0],threshold_voltage); //Trig level is set in Volts while in SCPI
  116.         rp_AcqSetTriggerLevel(c[1],threshold_voltage);  
  117.         rp_AcqSetTriggerDelay(delay);
  118.         return 0;
  119. #else
  120.   // initialization
  121.   int start = osc_fpga_init();
  122.   if(start)
  123.   {
  124.       printf("osc_fpga_init didn't work, retval = %d",start);
  125.       return -1;
  126.   }
  127.  
  128.   // set acquisition parameters
  129.   osc_fpga_set_trigger_delay(delay);
  130.   g_osc_fpga_reg_mem->data_dec = decimation;
  131.   osc_fpga_reset();
  132.   g_osc_fpga_reg_mem->chb_thr = osc_fpga_cnv_v_to_cnt(threshold_voltage); //sets trigger voltage
  133. #endif
  134.   fprintf(stderr, "%s : %d\n", __FILE__, __LINE__);
  135.   return 0;
  136. }
  137.  
  138. int daq_end () {
  139. #ifdef DEBUG
  140.         fprintf (stderr, "Server: end\n");
  141. #endif
  142. #ifdef MRP
  143.   rp_Release();
  144. #else
  145.   osc_fpga_exit();
  146. #endif
  147.   return 0;
  148. }
  149.  
  150. int daq_clear () {
  151. #ifdef DEBUG
  152.         fprintf (stderr, "Server: clear\n");
  153. #endif
  154.   return 0;
  155. }
  156.  
  157.  
  158. int16_t  chdata[16*1024];
  159. float *  chfdata = (float *) chdata;
  160. int daq_run (const char *par, char ** data, int *maxlen)
  161.  
  162. {
  163.  
  164.   int *data_buf;
  165.   int neve;
  166.  
  167.   unsigned short *sbuff   = (unsigned short *) (par);
  168.   unsigned short maxeve   = sbuff[0];
  169.   unsigned short nsamples = sbuff[1];
  170.   unsigned short tout     = sbuff[2];
  171.   unsigned char trigger   = par[6];
  172.   unsigned char chmask    = par[7];
  173.   clock_t t,t0;
  174.   neve = 0;
  175.  
  176.   t0=clock();  
  177.   int eventsize = 0;
  178.   if (chmask & 0x1) eventsize += (nsamples+2);
  179.   if (chmask & 0x2) eventsize += (nsamples+2);
  180.   eventsize+=4;
  181.   int required_size = eventsize * maxeve+3;
  182.  
  183. #ifdef DEBUG
  184.         time_t mtime;
  185.         time(&mtime);
  186.         fprintf (stderr, "daq_run:\tmaxeve %d\tnsamples=%d\ttimeout=%d\ttrigger=%d\tchmask=%d\t%s",  maxeve ,nsamples,tout,trigger,chmask, ctime(&mtime)); //
  187. #endif
  188.    
  189.    
  190.    if (required_size > *maxlen ) {
  191.      free (*data);
  192.      *data = (char *) malloc(required_size *sizeof(int));
  193.      fprintf(stderr, "New Buffer with size %d allocated. Old size %d\n", required_size, *maxlen);
  194.      *maxlen = required_size;
  195.    }
  196.  
  197.   int *ibuf  = (int *)  (*data);
  198.  
  199.  
  200.   data_buf = ibuf + 3;
  201.   const int sleeptime = 135*nsamples/16386; //135 us for 16386 samples and to fill the 16k ADC buffer/
  202.  
  203.   for (int ieve=0; ieve < maxeve; ieve++)
  204.     {
  205.  
  206. #ifdef MRP
  207.  
  208. rp_AcqStart();
  209. usleep(sleeptime);
  210. rp_AcqSetTriggerSrc(trigger);
  211. timer_out = FALSE;
  212. tmlnk (tout);
  213. rp_acq_trig_src_t source;
  214. do {
  215.   rp_AcqGetTriggerSrc(&source);
  216.   //printf("TRG %d src %d\n", trigger, source);  
  217.   if (timer_out || ctrl_c) break;
  218. } while (source == trigger);
  219.  
  220. tmulk ();
  221. usleep(sleeptime);
  222.  
  223.  
  224. #else
  225.  
  226.        osc_fpga_arm_trigger();
  227.        usleep(sleeptime);
  228.        osc_fpga_set_trigger(trigger);
  229.  
  230.        while (g_osc_fpga_reg_mem->trig_source != 0){
  231.            if (timer_out || ctrl_c) break;
  232.        }
  233.        // with this loop the program waits until the acquistion is completed before continue.
  234.        int trig_ptr = g_osc_fpga_reg_mem->wr_ptr_trigger; // get pointer to mem. adress where trigger was met
  235.        int * ch_signal[2];
  236.        osc_fpga_get_sig_ptr(&ch_signal[0], &ch_signal[1]);
  237. #endif
  238.        *(data_buf++) = 0x2;
  239.        *(data_buf++) = chmask;
  240.  
  241.        for (int id = 0;id<2;id++){
  242.          if ( !(chmask & (1 << id)) ) continue;
  243.  
  244.          *(data_buf++) = id;
  245.          *(data_buf++) = nsamples;
  246. #ifdef MRP
  247.         const int c[2] = {RP_CH_1, RP_CH_2};
  248.         unsigned int isamples = nsamples;  
  249.         rp_AcqGetLatestDataV(c[id], &isamples, (float *) data_buf );
  250.         data_buf+=nsamples;
  251. #else
  252.  
  253.          const int BUF = 16*1024;
  254.          const int offset =  0;
  255.          if (trig_ptr > (BUF-nsamples)) // Enter logic to transition from end to beginning of cha_signal buffer.
  256.          {
  257.             for (int i=trig_ptr;i<BUF;i++) *(data_buf++) = ch_signal[id][i]-offset;
  258.             for (int i=0;i<nsamples-(BUF-trig_ptr);i++) *(data_buf++) = ch_signal[id][i]-offset;
  259.          }
  260.          else // Enter simple logic to send sampleSize from trigger point
  261.          {
  262.            for (int i=0;i<nsamples;i++) *(data_buf++) = ch_signal[id][trig_ptr + i]-offset;
  263.          }
  264. #endif
  265.        }
  266.        *(data_buf++) = 0x3;
  267.        *(data_buf++) = neve;
  268.        neve++;
  269.        if (ieve+1 % 500 == 0) fprintf(stderr, "Event %d\n", ieve);
  270.        if (timer_out) break;
  271.  
  272.     }
  273.  
  274.  
  275.  
  276.   int *len   = ibuf;
  277.   int *nev   = ibuf + 1;
  278.   float *dt = (float *)(ibuf + 2);
  279.  
  280.   *len   = (data_buf-len)*sizeof(int);
  281.   *nev   = neve;
  282.   t = clock();
  283.   *dt = t-t0;
  284.   *dt /= CLOCKS_PER_SEC;
  285.  
  286.   return *len;
  287. }
  288.  
  289. #define MAXLEN 0XFFFF
  290. struct RUNHDR {
  291.   unsigned short neve;
  292.   unsigned short nsamples;
  293.   unsigned short tout;
  294.   unsigned char trigger;
  295.   unsigned char mask;
  296.   int nloops ;
  297.   int data [MAXLEN];
  298. } ;
  299.  
  300.  
  301. struct INIHDR {
  302.   int delay ;  
  303.   int decimation;
  304.   int threshold;
  305. };
  306.  
  307.  
  308. int daq_help(char *fname, struct INIHDR * i, struct RUNHDR *r, int verbosity){
  309.  
  310.   printf("-o filename ... output filename %s\n", fname);
  311.   printf("-v verbose ... verbosity %d\n", verbosity);
  312.   printf("-b decimation ... decimation %d\n", i->decimation);
  313.   printf("-i timeout ... interrupt timeout %d\n", r->tout);
  314.   printf("-s nsamples ... number of samples %d\n", r->nsamples);
  315.   printf("-d delay ... delay %d\n", i->delay);
  316.   printf("-t trigger ... trigger type %d\n", r->trigger);
  317.   printf("-l level ... trigger level %f\n", i->threshold*0.001);
  318.   printf("-m mask ... channel mask %d\n", r->mask );
  319.   printf("-n neve ... number of events per call %d\n", r->neve);
  320.   printf("-r nloops ... number of calls %d\n", r->nloops);
  321.   return 0;
  322. }
  323.  
  324.  
  325.  
  326. int daq_main( int argc , char ** argv) {
  327.   // intercept routine
  328.   if (signal (SIGINT, SigInt) == SIG_ERR) {
  329.     perror ("sigignore");
  330.   }
  331.  
  332.  
  333.   char filename[0xFF]="";
  334.  
  335.  
  336. struct INIHDR inihdr = {
  337.   .decimation = 1,
  338.   .threshold = 100,
  339.   .delay = 1024
  340. };
  341.  
  342.  
  343.  
  344. struct RUNHDR runhdr;
  345.  
  346.  
  347.   runhdr.neve =10000;
  348.   runhdr.nsamples = 1024;
  349.   runhdr.tout = 1000;
  350.   runhdr.trigger = 1;
  351.   runhdr.mask = 0x1;
  352.   runhdr.nloops = 1;
  353.  
  354.   int verbose = 0;
  355.   int argdata = 0;
  356.  
  357.   if (argc <2) {
  358.     daq_help(filename, &inihdr, &runhdr, verbose);
  359.     exit(-1);
  360.   }
  361.  
  362.   opterr = 0;
  363.   int c;
  364.   while ((c = getopt (argc, argv, "o:v:b:i:s:d:t:l:m:n:r:h")) != -1)
  365.     switch (c) {
  366.       case 'o':
  367.         sprintf(filename,"%s", optarg );
  368.         break; // output
  369.       case 'v':
  370.         verbose = strtoul (optarg,NULL,0);
  371.         break; // verbosity
  372.       case 'b':
  373.         inihdr.decimation = strtoul (optarg,NULL,0);
  374.         break;
  375.       case 'i':
  376.         runhdr.tout = strtoul (optarg,NULL,0);
  377.         break;
  378.       case 's':
  379.         runhdr.nsamples = strtoul (optarg,NULL,0);
  380.         break;
  381.       case 'd':
  382.         inihdr.delay = strtoul (optarg,NULL,0);
  383.         break;
  384.       case 't':
  385.         runhdr.trigger = strtoul (optarg,NULL,0);
  386.         break;
  387.       case 'm':
  388.         runhdr.mask = strtoul (optarg,NULL,0);
  389.         break;
  390.       case 'n':
  391.         runhdr.neve = atoi (optarg);
  392.         break;
  393.       case 'r':
  394.         runhdr.nloops = atoi (optarg);
  395.         break;
  396.       case 'l':
  397.         inihdr.threshold = (int) (1000*atof (optarg));
  398.         break;
  399.       case 'h':
  400.         daq_help(filename, &inihdr, &runhdr, verbose);
  401.         break;
  402.       case '?':
  403.         if (optopt == 'c')
  404.           fprintf (stderr, "Option -%c requires an argument.\n", optopt);
  405.         else if (isprint (optopt))
  406.           fprintf (stderr, "Unknown option `-%c'.\n", optopt);
  407.         else
  408.           fprintf (stderr,
  409.                    "Unknown option character `\\x%x'.\n",
  410.                    optopt);
  411.         return 1;
  412.       default:
  413.         abort ();
  414.     }
  415.   for (int i=optind; i<argc; i++) argdata = strtoul (argv[i],NULL,0);
  416.   if (verbose) daq_help(filename, &inihdr, &runhdr, verbose);
  417.  
  418.   printf("argdata %d nloops %d\n",argdata,runhdr.nloops);
  419.  
  420.   daq_init((char *)&inihdr);
  421.   FILE *fp=NULL;
  422.   if (strlen(filename)>0) fp = fopen(filename, "wb");
  423.  
  424.  
  425.   int maxlen = MAXLEN;
  426.   char *data = (char *) malloc(maxlen * sizeof(int));
  427.   time_t t,tstart;
  428.   time(&tstart);
  429.  
  430.   for (int i=0;i< runhdr.nloops;i++){
  431.     int nb =daq_run((const char*) &runhdr, &data, &maxlen);
  432.     if (ctrl_c) break;
  433.     time(&t);
  434.     fprintf(stderr, "Loop %d dt=%d s\n", i, (int)(t-tstart));
  435.    
  436.     if (fp) {
  437.       fprintf(stderr, "Writing %d to %s", nb, filename);
  438.       fwrite(data, 1, nb, fp);
  439.     }
  440.    
  441.   }
  442.   time(&t);
  443.   fprintf(stderr, "Total events %d in  %d s\n", runhdr.nloops*runhdr.neve, (int)(t-tstart));
  444.   if (fp) fclose(fp);
  445.   if (data!=NULL) free(data);
  446.   return 0;
  447. }
  448.