Subversion Repositories f9daq

Rev

Blame | Last modification | View Log | RSS feed

  1. //
  2. //  test.c
  3. //  
  4. //  Description : test program for V729
  5. //
  6. //  Author : S. Korpar
  7. //  Date   : 2005/07/15
  8. // adapted to CAEN V1719 by R. Pestotnik  2012/09/07
  9.  
  10. #include <stdlib.h>
  11. #include <stdio.h>
  12. #include <string.h>
  13. #include <unistd.h>
  14. #include <ctype.h>
  15.  
  16. #include <vector>
  17. #include <sys/time.h>
  18. #include <sys/stat.h>
  19. #include <signal.h>
  20. #include <string>
  21. #include "vme.h"
  22. #include "CAEN_V729_DEF.h"
  23.  
  24. #define V729_OFFSET 0x880000
  25. #define IREG_OFFSET 0x2000
  26. #define V729_WAIT 1
  27.  
  28.  
  29. #define TRUE 1
  30. #define FALSE 0
  31.  
  32. uint32_t V729_module=0;
  33.  
  34.  
  35. int timer_out;
  36. struct sigaction oact;
  37.  
  38. //---------------------------------------------------------
  39. void SigInt (int sig)
  40. {
  41.  
  42.     timer_out=1;
  43. }
  44.  
  45. //---------------------------------------------------------
  46. void timerast (int signumber)
  47. {
  48.     timer_out = TRUE;
  49.     fprintf(stderr,"TIMEOUT !!!\n");
  50. }
  51.  
  52. //---------------------------------------------------------
  53. void tmlnk (int tout)
  54. {
  55.     timer_out = FALSE;
  56.     struct sigaction act;
  57.     struct itimerval tdelay;
  58.  
  59.     act.sa_handler = timerast;
  60.     sigemptyset (&act.sa_mask);
  61.     act.sa_flags = 0;
  62.  
  63.     tdelay.it_value.tv_sec = tout / 100;
  64.     tdelay.it_value.tv_usec = 10000 * (tout % 100);
  65.     tdelay.it_interval.tv_sec = 0;
  66.     tdelay.it_interval.tv_usec = 0;
  67.  
  68.     if (sigaction (SIGALRM, &act, &oact) < 0)
  69.     {
  70.         perror ("sigaction(tmlnk)");
  71.         exit (EXIT_FAILURE);
  72.     }
  73.     if (setitimer (ITIMER_REAL, &tdelay, NULL) < 0)
  74.     {
  75.         perror ("setitimer(tmlnk)");
  76.         exit (EXIT_FAILURE);
  77.     }
  78. }
  79.  
  80. //---------------------------------------------------------
  81. void tmulk ()
  82. {
  83.     struct itimerval tdelay;
  84.  
  85.     tdelay.it_value.tv_sec = 0;
  86.     tdelay.it_value.tv_usec = 0;
  87.     tdelay.it_interval.tv_sec = 0;
  88.     tdelay.it_interval.tv_usec = 0;
  89.  
  90.     if (setitimer (ITIMER_REAL, &tdelay, NULL) < 0)
  91.     {
  92.         perror ("setitimer(tmulk)");
  93.         exit (EXIT_FAILURE);
  94.     }
  95.     if (sigaction (SIGALRM, &oact, NULL) < 0)
  96.     {
  97.         perror ("sigaction(tmulk)");
  98.         exit (EXIT_FAILURE);
  99.     }
  100. }
  101.  
  102. //---------------------------------------------------------
  103. int wait_while(int num){
  104.   int i, tmp;
  105.  
  106.   for ( i =0; i <num; i++ ) tmp = 0;
  107.   return tmp;
  108. }
  109.  
  110. //---------------------------------------------------------
  111. void V729_map( uint32_t addr)
  112. {
  113.   V729_module = addr;
  114.   return;
  115. }
  116.  
  117. //---------------------------------------------------------
  118. void V729_info(FILE *kam)
  119. {
  120.   unsigned short code, mid, ver;
  121.  
  122.  
  123.   VME_A24D16_R(V729_module+0xFA,&code);
  124.   VME_A24D16_R(V729_module+0xFC,&mid);
  125.   VME_A24D16_R(V729_module+0xFE,&ver);
  126.   fprintf(kam, "code/mid/ver = 0x%04X/0x%04X/0x%04X\n", code, mid, ver);
  127.   fprintf(kam, "Fixed code (0xFAF5) = 0x%04X\n", code);
  128.   fprintf(kam, "Manufacturer/Type = 0x%02X/0x%03X\n",
  129.          (mid & 0xFC00)>>10, mid & 0x3FF);
  130.   fprintf(kam, "Version/Serial = %d/%d\n",
  131.          (ver & 0xF000)>>12, ver & 0xFFF);
  132.   return;
  133. }
  134.  
  135.  
  136. //---------------------------------------------------------
  137. void V729_reg( uint32_t val){
  138.  uint32_t push=0;
  139.  
  140.  VME_A24D16_W(V729_module+V729_FSR, &val);
  141.  VME_A24D16_W(V729_module+V729_UFSR, &push); //push
  142.  usleep(V729_WAIT);
  143.  
  144. }
  145.  
  146.  
  147. //---------------------------------------------------------
  148. void V729_reset(int nall,int nbefore,int obae,int obaf)
  149. {
  150.   uint32_t cbl;
  151.  
  152. //  cbl=4096+12-100;
  153.   cbl=4096+12-nbefore;
  154.   uint32_t val=0;
  155.   VME_A24D16_W(V729_module+V729_RR, &val); // reset
  156.   printf("nbefore=%d\t", nbefore);
  157.   printf("nall=%d\t", nall);
  158.   printf("obae=%d\t", obae);
  159.   printf("obaf=%d\n", obaf);
  160.  
  161. // set AE
  162.   V729_reg( (obae & 0xFF)<<8 ) ; //
  163.   V729_reg( (obae & 0xF00) ) ; //
  164.  
  165.  
  166. // set AF and CBL
  167.   V729_reg( ((obaf & 0xFF)<<8) + (cbl & 0xFF)   );
  168.   V729_reg( (obaf & 0xF00) + ((cbl & 0xF00)>>8) );
  169.  
  170.  
  171.  
  172.  VME_A24D16_W(V729_module+V729_SR,&nall); //total number of samples
  173.  
  174.   return;
  175. }
  176. //---------------------------------------------------------
  177.  
  178. void V729_set_bias(int range, int bias1, int bias2)
  179. {
  180.     int i;
  181.     uint32_t bias;
  182.  
  183.     switch (range) {
  184.         case 0: //User
  185.             for (i=0x18;i<0x27;i+=4){
  186.                 VME_A24D16_W(V729_module+i, &bias1); //bias
  187.                 usleep(V729_WAIT);
  188.                 VME_A24D16_W(V729_module+i+2, &bias2); //bias
  189.                 usleep(V729_WAIT);
  190.             }
  191.             printf("Bias + %x  - %x\n", bias1, bias2);
  192.             break;
  193.         case 1: //Single Ended +
  194.             for (i=0x18;i<0x27;i+=4){
  195.                 bias = 0xCC; VME_A24D16_W(V729_module+i, &bias); //bias
  196.                 usleep(V729_WAIT);
  197.                 bias =0x733; VME_A24D16_W(V729_module+i+2, &bias); //bias
  198.                 usleep(V729_WAIT);
  199.             }
  200.             break;
  201.         case 2: //Single Ended -
  202.             for (i=0x18;i<0x27;i+=4){
  203.                 bias =0x733; VME_A24D16_W(V729_module+i, &bias); //bias
  204.                 usleep(V729_WAIT);
  205.                 bias= 0xD99 ; VME_A24D16_W(V729_module+i+2, &bias); //bias
  206.                 usleep(V729_WAIT);
  207.             }
  208.             break;
  209.         case 4: //Differential Unipolar
  210.             for (i=0x18;i<0x27;i+=4){
  211.                 bias = 0x400; VME_A24D16_W(V729_module+i,&bias); //bias
  212.                 usleep(V729_WAIT);
  213.                 bias = 0xA66; VME_A24D16_W(V729_module+i+2, &bias); //bias
  214.                 usleep(V729_WAIT);
  215.             }
  216.             break;
  217.         case 3: //Single Ended Bipolar
  218.         case 5: //Differential Bipolar
  219.         default:
  220.             for (i=0x18;i<0x27;i+=2){
  221.                 bias=0x733; VME_A24D16_W(V729_module+i, &bias); //bias
  222.                 usleep(V729_WAIT);
  223.             }
  224.             break;
  225.     }
  226.     return;
  227. }
  228.  
  229. //---------------------------------------------------------
  230. void V729_aquisition_mode(uint32_t mode) // mode 0 aqusition mode, 0x30 buffers programming
  231. {
  232. #ifdef V729_DEBUG
  233.   int status;
  234.   VME_A24D16_R(V729_module+V729_CSR, &status);
  235.   usleep(V729_WAIT);
  236.   fprintf(stderr, "0x0E = 0x%04X\n", status);
  237. #endif
  238.  
  239.   VME_A24D16_W(V729_module+V729_CSR, &mode); //aquisition mode
  240.   usleep(V729_WAIT);
  241. #ifdef V729_DEBUG
  242.   VME_A24D16_W(V729_module+V729_CSR, &status);
  243.   usleep(V729_WAIT);
  244.   fprintf(stderr, "0x0E = 0x%04X\n", status);
  245. #endif
  246.   return;
  247. }
  248.  
  249. //---------------------------------------------------------
  250. void V729_soft_stop()
  251. {
  252.   uint32_t sw=1;
  253.   VME_A24D16_W(V729_module+0x16,&sw);
  254. //  usleep(V729_WAIT);
  255.   sw =0;
  256.   VME_A24D16_W(V729_module+0x16,&sw);
  257. //  usleep(V729_WAIT);
  258.   return;
  259. }
  260.  
  261. //---------------------------------------------------------
  262. void V729_clear_buffer()
  263. {
  264.     const int tout=100; /* 1/100 of a second */
  265.     tmlnk (tout);
  266.     uint32_t data1,data2;
  267.     do {
  268.         VME_A24D32_R(V729_module+V729_OBR1, &data1);
  269.         if (timer_out) break;
  270.     } while (data1 & (0x3<<29));
  271.  
  272.     do {
  273.         VME_A24D32_R(V729_module+V729_OBR2, &data2);
  274.         if (timer_out) break;
  275.     } while (data2 & (0x3<<29));
  276.  
  277.     tmulk();
  278.     return;
  279. }
  280.  
  281. void V729_get_buffer(uint32_t *data1, uint32_t *data2)
  282. {
  283.     VME_A24D32_R(V729_module+V729_OBR1, data1);
  284. //    usleep(V729_WAIT);
  285.     VME_A24D32_R(V729_module+V729_OBR2, data2);
  286. //    usleep(V729_WAIT);
  287.     return;
  288. }
  289. int V729_status()
  290. {
  291.   uint32_t status;
  292.   VME_A24D16_R(V729_module+V729_CSR, &status);
  293.   return status;
  294. }
  295.  
  296.  
  297. //---------------------------------------------------------
  298. void V729_init(uint32_t addr, int nall, int cbl, uint32_t bias1, uint32_t bias2){
  299.   V729_map(addr);
  300.   V729_info(stderr);
  301.   V729_reset(nall,cbl,nall,0xC00);
  302.   V729_set_bias(0,bias1,bias2);
  303.   V729_aquisition_mode(0);
  304. CAENVME_SetFIFOMode(udev,1);
  305.   sleep(1);
  306. }
  307.  
  308.  
  309. //---------------------------------------------------------
  310. int V729_event(int mask, int nall, uint32_t *data,uint32_t *data1,uint32_t *data2){
  311.   uint32_t status;
  312.   const int tout=100; /* 1/100 of a second */
  313.   tmlnk (tout);
  314.   int count=0;
  315.  
  316.   //status= 0x80 ; VME_A16D16_W(IREG_OFFSET+0x8,&status); // pulse ch 8
  317.  
  318.   status = 0x1a ; VME_A16D16_W(IREG_OFFSET+0xC,&status); // clr1 enable1  .... clear busy1 flag
  319.   do {
  320.       //usleep(1);
  321.       VME_A24D16_R(V729_module+V729_CSR, &status);
  322. //    fprintf(stderr,"0x%X, 0x%X\n",status,(status & 0x5) ^ 0x5);
  323.     count++;
  324.     if (timer_out) {
  325.        tmulk ();
  326.        printf("[%d] daq=%x status AE01=%d AE23=%d Waiting for DATA TRG bit... at line %d\n",count , (status>>4)&0x3, status&0x1,(status>>2)&0x1 , __LINE__);
  327.        
  328.        V729_clear_buffer();
  329.        
  330.        return -1;
  331.     }
  332.   } while ((status & 0x5) ^ 0x5);
  333.   tmulk ();
  334.  
  335.  
  336.   int nb;
  337.   const int blt=1;
  338.   if (blt){
  339.  
  340.   VME_A24D32_FIFOBLTR(V729_module+V729_OBR1,data1,(nall+5)*sizeof(uint32_t),&nb);
  341.   VME_A24D32_FIFOBLTR(V729_module+V729_OBR2,data2,(nall+5)*sizeof(uint32_t),&nb);
  342.   for (int i=0;i<nall+5;i++){
  343.     data[2*i]   = data1[i];
  344.     data[2*i+1] = data2[i];
  345.   }
  346.   nb*=2;
  347.   } else {
  348.  
  349.  
  350.   VME_MRRST(); // MultiReadReset
  351.   int nc=0;
  352.   for (int i=0;i<nall+5;i++){
  353.     //if (mask & 0x3)
  354.     VME_A24D32_MR(V729_module+V729_OBR1, &data[nc++]);
  355.     //if (mask & 0xc)
  356.     VME_A24D32_MR(V729_module+V729_OBR2, &data[nc++]);
  357.   }
  358.   int j = VME_MREXEC(data); // MultiReadExecute
  359.   nb=j*sizeof(uint32_t);
  360.  
  361.   }
  362.  
  363.   return nb;
  364. }
  365.  
  366. //---------------------------------------------------------
  367. int V729_decode(uint32_t mask, int nall, uint32_t *data,  uint16_t *dadc, int debug){
  368.   uint16_t *adc[4];
  369.   for (int i=0;i<4;i++) adc[i] = &dadc[4+i*(nall+2)];
  370.  
  371.   int nc=0;
  372.   int narrays=0;
  373.   if (mask & 0x3) narrays++;
  374.   if (mask & 0xc) narrays++;
  375.  
  376.   int indx[4] ={0,0,0,0};
  377.   int shft[4] ={0,0,0,0};
  378.   int ashft[4]={0,0,0,0};
  379.   int nmask=0;
  380.  
  381.   for (int i=0;i<4;i++) if (mask & (1<<i) ) {
  382.     indx[nmask] = i;
  383.     shft[nmask] = (i%2)*12;
  384.     if (( (mask & 0x3) > 0 ) && (i>1))  ashft[nmask]=1  ;
  385.     else ashft[nmask]=0;
  386.     nmask++;
  387.   }
  388.   for (int j=0;j<nmask;j++){
  389.     nc=0;
  390.     for (int i=0;i<nall+5;i++){
  391.       int ii=narrays*i+ashft[j];
  392.      
  393.       uint32_t data1 = data[ii];
  394.      
  395.       if (data1 & (1<<31)) {
  396.         if (debug) fprintf(stdout,"data1: empty flags: 0x%X, time tag: 0x%06X\n", (data1>>29) & 0x3, data1 & 0xFFFFFF);
  397.       } else if ((data1>>29) & 0x3){
  398.         if (nc<nall){
  399.           adc[j][nc] = (data1>>shft[j]) & 0xFFF;
  400.           if (debug) printf("[%d/%d] ADC%d adc0=%d\n", i,nc,indx[j], adc[j][nc]);
  401.           nc++;
  402.         }
  403.  
  404.       } else {
  405.         if (debug) fprintf(stdout,"Data(%4d) %d indx=%d %d nc=%d(%d) %d 0x%08X\n", i, indx[j],narrays*i+ashft[j],j,nc,nmask,narrays, data1);
  406.       }
  407.     }
  408.   }
  409.   return nc;
  410. }
  411. //---------------------------------------------------------
  412.  
  413. // test program
  414. #ifdef V729_MAIN
  415. int ctrlc=0;
  416.  
  417. void CatchSig (int i){
  418.     ctrlc = 1;
  419. }
  420.  
  421.  
  422. int main(int argc,char **argv){
  423.  
  424.    if (argc == 1) {
  425.    
  426.     printf ("*********************************************************************************:\n");
  427.     printf ("Usage: %s <arguments> .........   CAEN V729A data aquisition:\n\n", argv[0]);
  428.     printf ("Arguments: \n");
  429.     printf ("-d <debuglevel>  \n");
  430.     printf ("-b <bias+>  \n");
  431.     printf ("-e <bias->  \n");
  432.     printf ("-a <VME address>  \n");
  433.     printf ("-c <n samples before stop>  \n");
  434.     printf ("-n <number of events> \n");
  435.     printf ("-l <nall> number of samples \n");
  436.     printf ("-m <channel mask: 4bits (1 bit/ch)> \n");
  437.     printf ("-o <output file name> \n");
  438.  
  439.     printf ("*********************************************************************************:\n");
  440.     exit (-1);
  441.   }
  442.  
  443.   uint32_t mask=0xF;
  444.   int  cbl=13;
  445.   int nall=1330;
  446.   char filename[0xFF]="";
  447.   int verbose = 0;
  448.   int neve    = 1;
  449.   uint32_t addr= V729_OFFSET;
  450.   uint32_t bias1 = 0x600; // vecje vrednosti povzročajo težave in zacno kanali oscilirat ....
  451.   uint32_t bias2 = 0x200;
  452.   int append=0;
  453.   int c=0;
  454.   while ((c = getopt (argc, argv, "b:e:a:d:c:l:n:o:m:f:")) != -1)
  455.     switch (c){
  456.       case 'd':
  457.         verbose=atoi(optarg);
  458.         break;
  459.       case 'c':
  460.         cbl=atoi(optarg);
  461.         break;
  462.       case 'l':
  463.         nall=atoi(optarg);
  464.        
  465.         if (nall%16) {
  466.           printf ("buffer length should be multiple of 16 , modulo = %d\n",nall%16);
  467.          // exit(-1);
  468.         }
  469.         break;    
  470.       case 'n':
  471.         neve=atoi(optarg);
  472.         break;  
  473.       case 'a':
  474.         addr=strtoul (optarg,NULL,0);
  475.         break;             // address
  476.       case 'b':
  477.         bias1=strtoul (optarg,NULL,0);
  478.         break;             // bias
  479.       case 'e':
  480.         bias2=strtoul (optarg,NULL,0);
  481.         break;             // bias
  482.  
  483.       case 'm':
  484.         mask=strtoul (optarg,NULL,0);
  485.         break;             // mask
  486.       case 'o':
  487.         sprintf(filename,"%s", optarg );
  488.         append=0;
  489.         break;       // output
  490.       case 'f':
  491.         sprintf(filename,"%s", optarg );
  492.         append=1;
  493.         break;       // output
  494.     }
  495.  
  496. // intercept routine
  497.   if (signal (SIGINT, CatchSig) == SIG_ERR)  perror ("sigignore");
  498.  
  499.  
  500.   // reset timers
  501.   time_t t,told=0, tstart;
  502.   time(&t);
  503.   tstart=t;
  504.  
  505.   // open file
  506.   FILE *fp=NULL;
  507.   int output=0;
  508.   if (strlen(filename)>0) {
  509.     if (verbose) printf("Data in the file:%s\n", filename);
  510.     if (append) fp=fopen(filename,"a");
  511.     else        fp=fopen(filename,"w");
  512.     output=1;
  513.   }
  514.  
  515.   // alloocate storage
  516.   uint32_t *data = new uint32_t[2*(nall+5)];
  517.   uint32_t *data1 = new uint32_t[2*(nall+5)];
  518.   uint32_t *data2 = new uint32_t[2*(nall+5)];
  519.   int nmask=0;
  520.   for (int i=0;i<4;i++) if (mask & (1<<i)) nmask++;
  521.   int adclen = nall+2;
  522.   int len    = nmask* adclen+2;
  523.   uint16_t *adc = new uint16_t[len]; // 4 channels + 4 ch header + 1 event hdr
  524.  
  525.   // write headers
  526.   uint16_t *evhdr  = &adc[0];
  527.   evhdr[0] = 0;
  528.   evhdr[1] = len  *sizeof(uint16_t);
  529.   int imask=0;
  530.   for (int ch=0;ch<4;ch++){
  531.     if (  mask & (1<<ch) ) {
  532.       uint16_t *chhdr= &adc[2+imask*adclen];
  533.       chhdr[0] = ch+1;
  534.       chhdr[1] = adclen *sizeof(uint16_t);
  535.       imask++;
  536.     }
  537.   }
  538.  
  539.   // start
  540.   int ncount =0;
  541.   int nerrors=0;
  542.   int nball  =0;
  543.  
  544.   // open VME and initialize board
  545.   char *serial = new char[100];
  546.  
  547.  
  548.   VME_START(serial);
  549.   printf("CAEN V1718 BoardFWRelease %s\n", serial);
  550.  
  551.   V729_init(addr, nall, cbl, bias1,bias2);
  552.  
  553.   // event loop
  554.   for (int j=0; j<neve; j++) {
  555.      if (ctrlc) break;
  556.      int nb= V729_event(mask,nall,data, data1,data2);
  557.      if (nb<0) {  // timeout
  558.        j--;
  559.        nerrors++;
  560.      } else {
  561.  
  562.        V729_decode(mask,nall,data,adc, verbose);
  563.  
  564.        // V729_clear_buffer();
  565.        if (output) nball += fwrite(adc  ,   1, sizeof(uint16_t)*len, fp);
  566.  
  567.        ncount++;
  568.      }
  569.      time(&t);
  570.      if (t/4!=told ) printf("%d events in %2.2f min (%d s) USBerr=%d TIMEOUTS=%d %s",ncount, (double)(t-tstart)/60.,int(t-tstart), VMEerrors, nerrors, ctime(&t));
  571.      told=t/4;  
  572.   }
  573.  
  574.   // end
  575.   if (output) fclose(fp);
  576.   VME_STOP();
  577.   time(&t);
  578.   printf("%d events in %2.2f min  (%d s) USBerr=%d TIMEOUTS=%d  %s\n",ncount, (double)(t-tstart)/60.,int(t-tstart),VMEerrors, nerrors, ctime(&t));
  579.   return 0;
  580. }
  581.  
  582. #endif //V729_MAIN
  583.