Subversion Repositories f9daq

Rev

Go to most recent revision | Blame | Compare with Previous | Last modification | View Log | RSS feed

  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include <string.h>
  4. #include <unistd.h>
  5. #include <sys/mman.h>
  6. #include <errno.h>
  7. #include <ctype.h>
  8. #include <time.h>
  9. #include <sys/time.h>
  10. #include <sys/stat.h>
  11. #include <signal.h>
  12. #include <zlib.h>
  13.  
  14. #include "CAENV965_DEF.h"
  15. #include "VmUsbStack.h"
  16.  
  17. #include "vme.h"
  18.  
  19. #include "daq.h"
  20.  
  21. #define VERSION 1.0
  22. #define TIMEOUT 3
  23.  
  24.  
  25. /* VME modules */
  26.  
  27. #define CAEN_V792      0x340000  // IJS V792
  28. #define CAEN_V792_1    0x530000  // FMF1 V792
  29. #define CAEN_V792_2    0x630000  // FMF2 V792
  30. #define CAEN_V965      0x350000  // IJS  V965
  31. int addr[3]={CAEN_V792,CAEN_V792_1,CAEN_V965  };
  32. int nadc=3;
  33.  
  34. int gPedestal = 255;
  35.  
  36. #define BUFF_L 2048
  37. static  int stackwrite[10000];
  38. static  int stackdata[10000],stackdump[27000];
  39.  
  40.  
  41. /************************************************/
  42. int weight_while(int num)
  43. {
  44.   int i, tmp;
  45.  
  46.   for ( i =0; i <num; i++ ) tmp = 0;
  47.   return 0;
  48. }
  49. #define WWHILE weight_while(0)
  50.  
  51. #define TRUE 1
  52. #define FALSE 0
  53.  
  54. int timer_out;
  55. struct sigaction oact;
  56. void timerast (int signumber)
  57. {
  58.  timer_out = TRUE;
  59.  fprintf(stderr,"TIMEOUT !!!\n");
  60. }
  61.  
  62. void tmlnk (int tout)
  63. {
  64.  timer_out = FALSE;
  65.  struct sigaction act;
  66.  struct itimerval tdelay;
  67.  
  68.  act.sa_handler = timerast;
  69.  sigemptyset (&act.sa_mask);
  70.  act.sa_flags = 0;
  71.  
  72.  tdelay.it_value.tv_sec = tout / 100;
  73.  tdelay.it_value.tv_usec = 10000 * (tout % 100);
  74.  tdelay.it_interval.tv_sec = 0;
  75.  tdelay.it_interval.tv_usec = 0;
  76.  
  77.  if (sigaction (SIGALRM, &act, &oact) < 0)
  78.  {
  79.    perror ("sigaction(tmlnk)");
  80.    exit (EXIT_FAILURE);
  81.  }
  82.  if (setitimer (ITIMER_REAL, &tdelay, NULL) < 0)
  83.  {
  84.    perror ("setitimer(tmlnk)");
  85.    exit (EXIT_FAILURE);
  86.  }
  87. }
  88.  
  89. void tmulk ()
  90. {
  91.  struct itimerval tdelay;
  92.  
  93.  tdelay.it_value.tv_sec = 0;
  94.  tdelay.it_value.tv_usec = 0;
  95.  tdelay.it_interval.tv_sec = 0;
  96.  tdelay.it_interval.tv_usec = 0;
  97.  
  98.  if (setitimer (ITIMER_REAL, &tdelay, NULL) < 0)
  99.  {
  100.    perror ("setitimer(tmulk)");
  101.    exit (EXIT_FAILURE);
  102.  }
  103.  if (sigaction (SIGALRM, &oact, NULL) < 0)
  104.  {
  105.    perror ("sigaction(tmulk)");
  106.    exit (EXIT_FAILURE);
  107.  }
  108. }
  109.  
  110. int fexist( char * path){
  111.    struct stat sbuf;
  112.    int res;
  113.    if(!path || !*path) return 0;
  114.    res=stat(path,&sbuf);
  115.    if (res){
  116.        if (errno==ENOENT) {
  117.            return 0;
  118.        } else {
  119.            return -1;
  120.        }
  121.    }
  122.    return 1;
  123. }
  124.  
  125.  
  126.  
  127.  
  128. int daq::init(){
  129.  
  130.   xxusb_register_write(udev,1,0x0); // Stop DAQ mode
  131.   while (xxusb_usbfifo_read(udev,(int *) stackdump,BUFF_L,100)>0);
  132.  
  133.  
  134.   int rate=1000;
  135.   int i=80000000/rate-40; // 80 MHz
  136.   if (i<72) i=72;
  137.         // Set DGG channel A as a pulser, output on O1,
  138.         //     with delay =500 x 12.5ns,
  139.         //     and width =  500 x 12.5ns,
  140.         //     not latching or inverting
  141.   //  VME_DGG(udev,0,6,0,24000,6000,0,0);
  142.   VME_DGG(udev,0,6,0,i,40,0,0);
  143.         // Set DGG channel B to trigger on NIM1, output on O2,
  144.         //     with delay =200 x 12.5ns,
  145.         //     and width =  200 x 12.5ns,
  146.         //     not latching or inverting
  147.         VME_DGG(udev,1,1,1,0,10,0,1);
  148.  
  149.  
  150. // INIT stackdata
  151.         int fPedestal=gPedestal;
  152.          printf("CAEN V965 Pedestal set to %d\n", fPedestal);
  153.         if (fInit != NULL ) delete fInit;
  154.         fInit=new VmUsbStack();
  155.  
  156.         for (int i=0;i<nadc;i++){
  157.                 fInit->WriteA24D16( addr[i] + CAENV965_CRN , 0x0);
  158.                 fInit->WriteA24D16( addr[i] + CAENV965_GEO , i);
  159.                 fInit->ReadA24D16(addr[i] + CAENV965_GEO);
  160.     for (int j=0;j<32;j++){
  161.                    fInit->WriteA24D16(addr[i] + CAENV965_THM + 0x02*j, fThreshold[j+i*32]); // threshold/kill for 32 channels
  162.     }
  163.                 fInit->WriteA24D16( addr[i] + CAENV965_BS1, 0x80 ); // soft reset
  164.                 fInit->WriteA24D16( addr[i] + CAENV965_BC1, 0x80 ); // soft reset
  165.                 fInit->WriteA24D16( addr[i] + CAENV965_PED, fPedestal ); // pedestal
  166.                 fInit->WriteA24D16( addr[i] + CAENV965_BS2,0x5000);
  167.                 fInit->WriteA24D16( addr[i] + CAENV965_BS2,0x4);  // clear module
  168.                 fInit->WriteA24D16( addr[i] + CAENV965_BC2,0x4);
  169.         }
  170.         fInit->Marker(0xFAFC);
  171.        
  172. //      fInit->Print();
  173.        
  174.        
  175.         // READOUT stackdata
  176.         if (fStack != NULL ) delete fStack;
  177.         fStack=new VmUsbStack();
  178.         fStack->Marker(0xFFAB);
  179.         //fStack->ConditionalRead(addr[i] + CAENV965_SR1,0x1);        // TRG wait : loop until bit 0 is on
  180.         // fStack->RepeatRead( CMD_A24, CMD_D32, addr[i] + CAENV965_OB,34,0);  // repead read
  181.         //fStack->ConditionalRead(addr[i] + CAENV965_OB ,0x4000000) ; // loop until bit 26 is on, read data
  182.   for (int j=0;j<36;j++) fStack->ReadA24D32(addr[0] + CAENV965_OB);
  183.   for (int j=0;j<36;j++) fStack->ReadA24D32(addr[1] + CAENV965_OB);
  184.   for (int j=0;j<8;j++) fStack->ReadA24D32(addr[2] + CAENV965_OB);// 4 channels connected
  185.         fStack->Marker(0xFAFB);
  186.  
  187.         for (int i=0;i<nadc;i++){
  188.                 fStack->WriteA24D16(addr[i] + CAENV965_BS2,0x4);  // clear module
  189.                 fStack->WriteA24D16(addr[i] + CAENV965_BC2,0x4);  
  190.         }
  191.  
  192.         //fStack->Print();
  193.  
  194.  VME_LED_settings(udev, 0,0,0,0); // Set Yellow LED to light with with USB out buffer not empty
  195.  VME_LED_settings(udev, 1,1,0,0); // Set Red LED to light with NIM1
  196.  VME_LED_settings(udev,2,0,0,0); // Set Green LED to light when stack is not empty
  197.  
  198.  Uint32_t  vmereg;
  199.  VME_register_read(udev,0x00,&vmereg);
  200.  printf("VMUSB Firmware ID -> 0x%08X\n",vmereg);
  201.  
  202.  VME_register_read(udev,0x04,&vmereg);
  203.  printf("VMUSB Global Mode -> 0x%08X\n",vmereg);
  204.  
  205.  vmereg=(vmereg&0xF000)|0x0004;
  206.  VME_register_write(udev,0x04,vmereg);
  207.  VME_register_write(udev,0x08,0x00000080);
  208.  VME_register_write(udev,0x28,0x0);
  209.  VME_register_write(udev,0x2C,0x0);
  210.  VME_register_write(udev,0x30,0x0);
  211.  VME_register_write(udev,0x34,0x0);
  212.  VME_register_write(udev,0x3C,0x000);
  213.  
  214.  int nb = fInit->Get(10000,stackdata);
  215.  int ret= xxusb_stack_execute(udev,(Uint32_t *)stackdata);
  216.  printf("Init::%d ret=%d\n",nb,ret);
  217.  if (ret>0) for (int i=0;i<ret/2;i++) printf ("stackdata=0x%08X\n",stackdata[i]);
  218.  
  219.  int nb0= fStack->Get(10000,&stackwrite[0]);
  220.  if (nb0>768) {
  221.    fprintf(stderr,"nb0=%d > 768 error xxusb_stack_write\n", nb0);
  222.    exit(-1);
  223.  }
  224.  nb =xxusb_stack_write(udev,0x2,(Uint32_t *) stackwrite);
  225.  nb0=xxusb_stack_read(udev,0x2,(Uint32_t *) stackdata);
  226.  for (int i=0;i<stackwrite[0]+1;i++){
  227.    if (stackdata[i]!=stackwrite[i]) printf("%d %d init err %x %x\n",nb,nb0,stackwrite[i], stackdata[i]);
  228.  }
  229.  
  230.  if (fMode==2) xxusb_register_write(udev,1,0x1); // Start DAQ mode
  231.  
  232.  printf("daq::init() \n");
  233.  return 0;
  234. }
  235.  
  236. int daq::connect(){
  237.     VME_START(NULL);
  238.     printf("daq::connect()\n");
  239.     return 0;
  240. }
  241.  
  242. int daq::disconnect(){
  243.   /* zakljuci */
  244.   VME_STOP();
  245.   printf("daq::disconnect()\n");
  246.   return 0;
  247. }
  248.  
  249. int daq:: clear(){    
  250.    return 0;
  251. }
  252.  
  253. inline int module_header(int recid,Uint32_t *data,int len){
  254.    data[0] = recid;
  255.    data[1] = (len >0)? len : 0 ;
  256.    return data[1]+2;
  257. }
  258.  
  259.  
  260. int daq::event(unsigned int *data, int maxn, int *ctr, int print){
  261.    int tout=200; /* 1/100 of a second */
  262.    const int lsize=sizeof(unsigned Uint32_t);  
  263.  
  264.  
  265.    ctr[0]++;
  266.    ctr[1]++;
  267.    
  268.    int count=0;
  269.  
  270.          switch (fMode){
  271.          case 0:// normal calls
  272.                  {
  273.                          unsigned short clr= 0x4;
  274.                          unsigned int status=0;
  275.                          Uint32_t mdata;
  276.                          
  277.                          for (int i=0;i<2;i++){
  278.                                  // wait for trg
  279.                                  tmlnk (tout);
  280.                                  do VME_A24D16_R( addr[i] + CAENV965_SR1, &status); while ( (status&0x1)==0 && timer_out==0 );
  281.                                  tmulk();
  282.                                  // readout data
  283.                                  if (timer_out) return 0;
  284.                                  int len=0;
  285.                                  
  286.                                  do {
  287.                                          VME_A24D32_R(addr[i]  + CAENV965_OB, &mdata);
  288.                                          mdata=data[count++];
  289.                                          len++;
  290.                                  } while  ( (mdata & 0x4000000)==0 && timer_out==0) ; // bit 26 EOB or not valid datum
  291.                                  // clear
  292.                                  VME_A24D16_W( addr[i] + CAENV965_BS2, &clr);
  293.                                  VME_A24D16_W( addr[i] + CAENV965_BC2, &clr);
  294.                                  
  295.                                  if (count+2<maxn) {
  296.                                          if (print)  printf("V965 %3d\n",len);
  297.                                          count+=module_header(0x130+i,&data[count],len);
  298.                                          ctr[2]++;
  299.                                          ctr[3]+=len;
  300.                                  }
  301.                          
  302.                                  timer_out=0;
  303.                          }
  304.                  }
  305.                  break;
  306.          case 1:// stack execute
  307.                  {
  308.                          fStack->Get(10000,(int *)data);
  309.                          int ret=xxusb_stack_execute(udev,(Uint32_t *) data); //The first element of the array is the number of bytes.
  310.        if (ret< 0 ) {
  311.                                  printf ("xxusb_stack_execute error err=%d\n",ret);     \
  312.                                  count = 0;
  313.                          } else count= ret/lsize;
  314.  
  315.                  }
  316.                  break;
  317.          case 2:// stack load
  318.                  {
  319.                          int ret=xxusb_usbfifo_read(udev,(int *) data,BUFF_L,100);
  320.                          if (ret< 0 ) {
  321.                                  if (ret!=-110) {
  322.                                     printf ("xxusb_usbfifo_read error err=%d\n",ret);
  323.                                     end();
  324.                                     init();
  325.                                  }     
  326.                                  count = 0;
  327.                          } else {
  328.                                  if (0 && print && ret>0) {
  329.                                          for (int i=0;i<100;i++) {
  330.                                                  printf ("%4d fifodata=0x%08X\n",i, data[i]);
  331.              if (data[i]==0xFAFB) break;
  332.                                          }
  333.                                          /*
  334.    
  335.    0 fifodata=0x0000000D
  336.    1 fifodata=0x00000049
  337.    2 fifodata=0x0000FFAB
  338.    3 fifodata=0x00002000
  339.    4 fifodata=0x00000200
  340.    5 fifodata=0x00004141
  341.    6 fifodata=0x00000000
  342.    7 fifodata=0x00004057
  343.    8 fifodata=0x00000010
  344.    9 fifodata=0x00004052
  345.   10 fifodata=0x00000001
  346.   11 fifodata=0x0000405C
  347.   12 fifodata=0x00000011
  348.   13 fifodata=0x0000405D
  349.   14 fifodata=0x00000002
  350.   15 fifodata=0x0000405E
  351.   16 fifodata=0x00000012
  352.   17 fifodata=0x0000401C
  353.   18 fifodata=0x00000003
  354.   19 fifodata=0x0000402F
  355.   20 fifodata=0x00000013
  356.   21 fifodata=0x00004024
  357.   22 fifodata=0x00000004
  358.   23 fifodata=0x00004076
  359.   24 fifodata=0x00000014
  360.   25 fifodata=0x0000412F
  361.   26 fifodata=0x00000005
  362.   27 fifodata=0x0000404C
  363.   28 fifodata=0x00000015
  364.   29 fifodata=0x00004132
  365.   30 fifodata=0x00000006
  366.   31 fifodata=0x00004044
  367.   32 fifodata=0x00000016
  368.   33 fifodata=0x0000404A
  369.   34 fifodata=0x00000007
  370.   35 fifodata=0x0000409B
  371.   36 fifodata=0x00000017
  372.   37 fifodata=0x000040F1
  373.   38 fifodata=0x00000008
  374.   39 fifodata=0x00004087
  375.   40 fifodata=0x00000018
  376.   41 fifodata=0x00004173
  377.   42 fifodata=0x00000009
  378.   43 fifodata=0x0000404C
  379.   44 fifodata=0x00000019
  380.   45 fifodata=0x0000406C
  381.   46 fifodata=0x0000000A
  382.   47 fifodata=0x00004070
  383.   48 fifodata=0x0000001A
  384.   49 fifodata=0x0000406E
  385.   50 fifodata=0x0000000B
  386.   51 fifodata=0x00004014
  387.   52 fifodata=0x0000001B
  388.   53 fifodata=0x000040B7
  389.   54 fifodata=0x0000000C
  390.   55 fifodata=0x000040A9
  391.   56 fifodata=0x0000001C
  392.   57 fifodata=0x00004048
  393.   58 fifodata=0x0000000D
  394.   59 fifodata=0x00004118
  395.   60 fifodata=0x0000001D
  396.   61 fifodata=0x0000409D
  397.   62 fifodata=0x0000000E
  398.   63 fifodata=0x0000405B
  399.   64 fifodata=0x0000001E
  400.   65 fifodata=0x00004285
  401.   66 fifodata=0x0000000F
  402.   67 fifodata=0x00004159
  403.   68 fifodata=0x0000001F
  404.   69 fifodata=0x00000035
  405.   70 fifodata=0x00000400
  406.   71 fifodata=0x00000035
  407.   72 fifodata=0x00000600
  408.   73 fifodata=0x00000035
  409.   74 fifodata=0x0000FAFB
  410.  
  411.  
  412.                                          */
  413.                                  }
  414.                                  if (print) printf("------------------ret=%d data[0]=%d\n",ret,(int)data[0]);
  415.                                  count= ret/lsize;
  416.                                  ctr[2]+=data[0];
  417.                                  ctr[3]+=count;
  418.                          }
  419.                  }
  420.                  break;
  421.          }
  422.    return count*lsize;
  423. }
  424.  
  425. int daq::end(){
  426.  
  427.          xxusb_register_write(udev,1,0x0); // Stop DAQ mode
  428.          while (xxusb_usbfifo_read(udev,(int *) stackdata,BUFF_L,30)>0);  
  429.    printf("daq::end()\n");
  430.   return 0;
  431. }
  432.  
  433. daq::daq(){
  434.   fMode = 2;
  435.   fPedestal=255;
  436.   for (int i=0;i<128;i++){
  437.      if (i<72) fThreshold.push_back(0);      
  438.      else      fThreshold.push_back(0x1<<8); // samo 4 kanali na zadnjem modulu so enablani
  439.   }
  440.   fThresholdEnable=0;
  441.   fStop=0;
  442.   fInit=NULL;
  443.   fStack=NULL;
  444.   connect();
  445. }
  446.  
  447. daq::~daq(){
  448. disconnect();
  449. }
  450.  
  451. #ifdef MAIN
  452. /* ------------------- CatchSig ----------------- */
  453. int ctrlcflag=0;
  454.  
  455. void SigInt (int sig)
  456. {
  457.     ctrlcflag = 1;
  458.     timer_out=1;
  459. }
  460.  
  461. int main (int argc, char **argv){
  462.    // intercept routine
  463.    if (signal (SIGINT, SigInt) == SIG_ERR) {
  464.         perror ("sigignore");
  465.    }
  466.  
  467.    // print welcome message
  468.   time_t t,told, tstart, tstop;
  469.   time(&t);
  470.   fprintf(stdout,"#############################################\n");
  471.   fprintf(stdout,"Program %s version %2.1f\n",argv[0], VERSION);
  472.   fprintf(stdout,"Compiled on %s %s\n",__DATE__, __TIME__);
  473.   fprintf(stdout,"Runtime  %s \n",ctime(&t));
  474.   fprintf(stdout,"#############################################\n");
  475.  
  476.  
  477.   int neve=-1;
  478.   char cfname[100]="test.dat";
  479.   char *fname=cfname;
  480.   char *fpedname=NULL;
  481.  
  482. #define BSIZE 10000
  483.   Uint32_t data[10000];
  484.  
  485.  
  486.   daq *d= new daq();
  487.   int c;
  488.  
  489.   while ((c = getopt (argc, argv, "p:n:t:o:")) != -1)
  490.     switch (c)
  491.       {
  492.       case 'o':
  493.         sprintf(fname ,"%s", optarg);
  494.         if (fexist(fname)==1){
  495.           fprintf(stdout,"Error !\n");
  496.           fprintf(stdout,"File %s already exist. Appending ....\n",fname);
  497.           //fprintf(stdout,"Remove the file and restart !!!\n");
  498.           //exit(0);
  499.         }
  500.         break;       // input file
  501.       case 'n':
  502.         neve  = atoi(optarg); // negative argument time ( in s )limited event loop
  503.         break;
  504.       case 't':
  505.         {
  506.          
  507.           sprintf(fpedname ,"%s", optarg);
  508.           FILE *fped=fopen(fpedname,"r");
  509.           int j=0;  
  510.           int ndim=400;
  511.           char line[ndim];  
  512.           int val=0;
  513.           while (fgets(line,ndim,fped)!=NULL){
  514.             sscanf(line,"%d",&val);
  515.             d->fThreshold[j++]=val;
  516.           }
  517.           d->fThresholdEnable=1;
  518.           //fclose(fped);
  519.           fclose(fped);
  520.           break;
  521.         }
  522.       case 'p':
  523.         gPedestal  = atoi(optarg); // injected charge to the qdc
  524.         break;
  525.       }
  526.  
  527.   if (argc==1) {
  528.     fprintf(stdout,"Usage: %s -o [filename] -n [number of events] -t [thresholdfile] -p <qdc inject charge>\n negative number of events = acq time in seconds\n",argv[0]);
  529.     exit(-1);
  530.   }
  531.   //FILE *fp=fopen(fname,"a");
  532.   gzFile fp=gzopen(fname,"a");
  533.  
  534.   d->init();
  535.   d->clear();
  536.  
  537.   int hdr[4]={2}; // recid od run 11 naprej
  538.   int i=0;
  539.   int ntotal=0;
  540.   int counters[30]={0,0,0,0,0, 0,0,0,0,0,0,0};
  541.   char names[10][20]={"TRG","CAEN V965"};
  542.   time(&t);
  543.   tstart=t;
  544.   tstop=tstart+360000;
  545.   if (neve<-1) {
  546.     tstop=tstart-neve;
  547.     neve=-1;
  548.   }
  549.   for (i=0;i!=neve && !ctrlcflag && t<tstop;i++){
  550.      time(&t);
  551.      if (t!=told ) printf("%d in %2.2f min daq::event() %s\n",i, (double)(t-tstart)/60., ctime(&t));
  552.      int nb=d->event(data,BSIZE, counters,t!=told);
  553.      if (nb>0){
  554.       // zapis v datoteko  
  555.       hdr[1]=nb+4*sizeof(int);
  556.       hdr[2]=time(NULL);
  557.       hdr[3]=i;
  558.    
  559.       //fwrite(hdr,   sizeof(int),4 , fp);
  560.       gzwrite(fp, hdr,   sizeof(int)*4); //gzip
  561.      // recid=1 do runa 10.  ntotal += fwrite(data,   sizeof(int),nb, fp);
  562.       //ntotal += fwrite(data, 1,nb, fp);
  563.       ntotal += gzwrite(fp, data, nb);
  564.       told=t;
  565.      } else i--;
  566.   }
  567.  
  568.   d->end();
  569.   delete d;
  570.   printf("Number of Events: %d\n",i);
  571.   if (ctrlcflag) printf("User Program termination CTRL-C\n");
  572.   if (t>tstop  ) printf("Timeout termination tstart# t>tstop: %d# %d >%d\n",(int)t, (int)tstart, (int) tstop);
  573.  
  574.  
  575.   //fclose(fp);  
  576.   gzclose(fp);  
  577.   fprintf(stdout,"%d bytes written to %s\nCounts:\n", (int) (ntotal*sizeof(int)),fname);
  578.   for (i=0;i<2;i++) fprintf(stdout,"%s\t%d\t%d\n",names[i],counters[2*i],counters[2*i+1]) ;
  579.  
  580.  
  581.   return 0;
  582. }
  583. #endif
  584.