Subversion Repositories f9daq

Rev

Blame | Last modification | View Log | RSS feed

  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. }
  528.