Subversion Repositories f9daq

Rev

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

  1. #ifdef _CVI_
  2. #include <utility.h>
  3. #else
  4. #include <unistd.h>
  5.  
  6. void Delay(double x) {
  7.   usleep(int(1e6*x));
  8. }
  9. #endif
  10.  
  11. #include <stdlib.h>
  12. #include <stdint.h>
  13. #include <string.h>
  14. #include <stdio.h>
  15. #include "sa02lib.h"
  16.  
  17. //uint32_t  sa02BoardNumber = 0;
  18. uint32_t  sa02BoardType   = 0;
  19. int       sa02Verbose = 0;
  20. int       sa02TimerOut;
  21. int       sa02BltReadout = 0;
  22. uint32_t  sa02Address    = 0;
  23.  
  24.  
  25. int sa02SetAddress(uint32_t address) {
  26.   sa02Address    =  address;
  27.   return 0;
  28. }
  29.  
  30. int sa02Help( void ) {
  31.   sa02Printf ("*********************************************************************************:\n");
  32.   sa02Printf ("Usage: Performs single/multiple read or write access to SA02 via CAEN V1495 multipurpose IO board:\n\n");
  33.   sa02Printf ("Arguments: \n");
  34.   sa02Printf ("-i input parameter filename // can be specified multiple times  \n");
  35.   sa02Printf ("-v verbosity \n");
  36.   sa02Printf ("-g bltreadout \n");
  37.   sa02Printf ("-o output filename \n");
  38.   sa02Printf ("-f output filename - append data to file\n");
  39.   sa02Printf ("-w write command (FE TP DLY0 MUX MUXASIC VTH1 VTH2 TPLVL0 TPLVL1 GREG CREG CMON TMON0 TMON1 DMON) \n");
  40.   sa02Printf ("-a vme base address 0x32100000 \n");
  41.   sa02Printf ("-c asic chip number (0..3) \n");
  42.   sa02Printf ("-x asic channel number (0..36) \n");
  43.   sa02Printf ("-t sleep time bewteen events (sec) \n");
  44.   sa02Printf ("-d data\n");
  45.   sa02Printf ("-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");
  46.   sa02Printf ("-s data step or in case of -b the channel step \n");
  47.   sa02Printf ("-r number of readouts for each event\n");
  48.   sa02Printf ("-n number of events\n");
  49.   sa02Printf ("-h <command> at each event execute external command after readouts are done");
  50.   sa02Printf ("-q enable test pulse\n");
  51.   sa02Printf ("-e send software trigger before reading the data\n");
  52.   sa02Printf ("-p asicparameter ( PHASECMPS GAIN SHAPINGTIME COMPARATOR VRDRIVE MONITOR ID)\n");
  53.   sa02Printf ("-p asicparameter ( DECAYTIME OFFSET FINEADJ_UNIPOL FINEADJ_DIFF TPENB KILL)\n\n");
  54.   sa02Printf ("-u value ... send test SEU software trigger \n");
  55.   sa02Printf ("-z value ... finish the execution of the program in <value> s \n");
  56.   sa02Printf ("-m fixeddata : test fixed data, if error occurs, abort \n");
  57.   sa02Printf ("-l board mask   \n");
  58.   sa02Printf ("*********************************************************************************:\n");
  59.   sa02Printf ("Examples:\n\n");
  60.   sa02Printf ("Threshold scan:\n");
  61.  
  62.   sa02Printf ("100 events TMON0 reading and 10 readings of the data for each event:\n");
  63.   sa02Printf ("./sa02_ctrl  -a 0x32100000  -w TMON0 -n 100 -r 10 -t 10000 -v 1\n\n");
  64.   sa02Printf ("scan 9 points TPLVL0 inital data 111 stepsize 11, send 1 test pulse, read data :\n");
  65.   sa02Printf ("./sa02_ctrl  -a 0x32100000  -w TPLVL0 -d 111 -s 11 -n 9 -e 1 -r 1 -v 1\n\n");
  66.   sa02Printf ("Initialize the board from input.param, Read 10000 events of data. the result is saved in the output.dat\n");
  67.   sa02Printf ("./sa02_ctrl  -a 0x32100000  -i input.param -n 10000 -r 1 -o output.dat \n\n");
  68.   sa02Printf ("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 ");
  69.   sa02Printf ("set TPENB to b after the acquisition, the result is saved in the output.dat\n");
  70.   sa02Printf ("./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");
  71.   return 0;
  72. }
  73.  
  74. void sa02PrintGREG(uint32_t *data, const char *txt) {
  75.   sa02AsicGlobalRegister *a=(sa02AsicGlobalRegister *) data;
  76.   sa02Printf("sa02PrintGREG %s 0x%08x\n",txt, *data);
  77.   sa02Printf("phasecmps   =%d\n",a->phasecmps);
  78.   sa02Printf("gain        =%d\n",a->gain);
  79.   sa02Printf("shapingtime =%d\n",a->shapingtime);
  80.   sa02Printf("comparator  =%d\n",a->comparator);
  81.   sa02Printf("vrdrive     =%d\n",a->vrdrive);
  82.   sa02Printf("monitor     =%d\n",a->monitor);
  83.   sa02Printf("id          =%d\n",a->id);
  84.   sa02Printf("unused      =0x%0x\n",a->unused);
  85. };
  86.  
  87. void sa02PrintCREG(uint32_t *data, const char *txt) {
  88.   sa02AsicChannelRegister *a=(sa02AsicChannelRegister *) data;
  89.   sa02Printf("sa02PrintCREG %s 0x%08x\n",txt, *data);
  90.   sa02Printf("decaytime     =%d\n",a->decaytime);
  91.   sa02Printf("offset        =%d\n",a->offset);
  92.   sa02Printf("fineadj_unipol=%d\n",a->fineadj_unipol);
  93.   sa02Printf("fineadj_diff  =%d\n",a->fineadj_diff);
  94.   sa02Printf("reserved      =%d\n",a->reserved);
  95.   sa02Printf("tpenb         =%d\n",a->tpenb);
  96.   sa02Printf("kill          =%d\n",a->kill);
  97.   sa02Printf("unused      =0x%0x\n",a->unused);
  98. };
  99.  
  100. int sa02MuxMap(int i ) {
  101.  
  102.   if (sa02BoardType > 1) return i;
  103.   switch ( i ) {
  104.     case 0:
  105.       return 2;
  106.     case 1:
  107.       return 0;
  108.     case 2:
  109.       return 3;
  110.     case 3:
  111.       return 1;
  112.   }
  113.   return i;
  114. };
  115.  
  116. //-------------------------------------------------------------------------
  117.  
  118. uint32_t  sa02Write(uint32_t sa02BoardNumber, uint32_t regh, uint32_t regl, uint32_t *response)
  119.  
  120. {
  121.   VME_A32D32_W(sa02Address+FEB_DATAOUT0+FEB_DATA_INC*sa02BoardNumber,regl);
  122.   VME_A32D32_W(sa02Address+FEB_DATAOUT1+FEB_DATA_INC*sa02BoardNumber,regh);
  123.   Delay(0.001);
  124.   VME_A32D32_R(sa02Address+FEB_DATAIN0+FEB_DATA_INC*sa02BoardNumber,response);
  125.   VME_A32D32_R(sa02Address+FEB_DATAIN1+FEB_DATA_INC*sa02BoardNumber,response+1);
  126.  
  127.   if (sa02Verbose>1) {
  128.     sa02Printf("sa02Write board= %d 0x%08x  0x%08x  retval =0x%08X_%08X\n",  sa02BoardNumber, regh, regl, response[1], response[0]);
  129.   }
  130.  
  131.  
  132.   return response[0];
  133.  
  134. }
  135.  
  136. //-------------------------------------------------------------------------
  137. int Sa02DaqMode (uint32_t mode) {
  138.   VME_A32D32_W(sa02Address+FEB_DAQMODE,mode);
  139.   return 0;
  140. }
  141.  
  142. int Sa02SetPtsOutput(uint32_t mask) {
  143.   VME_A32D32_W(sa02Address+FEB_DEBUGMON,mask);
  144.   return 0;
  145. }
  146.  
  147. int Sa02SetNeve (uint32_t neve) {
  148.  
  149.   VME_A32D32_W(sa02Address+FEB_SETNEVE,neve);
  150.   return 0;
  151. }
  152.  
  153. uint32_t Sa02GetNeve (uint32_t*inputtriggers) {
  154.   uint32_t neve=0;
  155.   VME_A32D32_R(sa02Address+FEB_GETNEVE,&neve);
  156.   *inputtriggers = (neve >> 16)  &0xFFFF;
  157.   return neve &0xFFFF;   // output triggers
  158. }
  159.  
  160. uint32_t Sa02GetCounter (uint32_t board, uint32_t *errors) {
  161.   uint32_t neve=0;
  162.   VME_A32D32_R(sa02Address+FEB_CNTR+FEB_DATA_INC*board,&neve);
  163.   *errors = (neve >> 16)  &0xFFFF;
  164.   return neve &0xFFFF;
  165. }
  166.  
  167. uint32_t Sa02GetChAddr (uint32_t board) {
  168.   uint32_t neve=0;
  169.   VME_A32D32_R(sa02Address+FEB_CHADDR+FEB_DATA_INC*board,&neve);
  170.   return neve;
  171. }
  172.  
  173. int sa02Reset1( void ) {
  174.   uint32_t rdy=1;
  175.  
  176.   VME_A32D32_W(sa02Address+FEB_DATA_RST,rdy);
  177.  
  178.   return 0;
  179. }
  180.  
  181. int Sa02SEUTrigger (void) {
  182.   uint32_t rdy;
  183.   rdy=1;
  184.   VME_MWRST();
  185.   VME_MW(VME_A32, VME_D32, sa02Address+FEB_SEUTRG,rdy);
  186.   rdy=0;
  187.   VME_MW(VME_A32, VME_D32, sa02Address+FEB_SEUTRG,rdy);
  188.   VME_MWEXEC();
  189.   return 0;
  190. }
  191.  
  192. int Sa02SelectTrigger (uint32_t trg) {
  193.   VME_A32D32_W(sa02Address+FEB_SELTRG,trg);
  194.   return 0;
  195. }
  196.  
  197. int Sa02SelectTriggerWithMaskAndLength (uint32_t trg, uint32_t mask, uint32_t len) {
  198.   VME_A32D32_W(sa02Address+FEB_SELTRG, trg | (mask << 4) | (len << 16) );
  199.   return 0;
  200. }
  201.  
  202.  
  203. int Sa02SoftwareTrigger (void ) {
  204.   uint32_t rdy =1;
  205.   VME_MWRST();
  206.   VME_MW(VME_A32, VME_D32,sa02Address+FEB_SWTRG,rdy);
  207.   VME_MWEXEC();
  208.   return 0;
  209. }
  210.  
  211.  
  212.  
  213. int Sa02TestPulseEnable (uint32_t board, uint32_t enable ) {
  214.  
  215.   uint32_t response[2]= {0,0};
  216.   return sa02Cmd(board,FEB_TP, enable, 0, 0 ,1,response);
  217. }
  218.  
  219. int sa02Reset( void ) {
  220.   uint32_t rdy;
  221.   rdy=1;
  222.   VME_MWRST();
  223.   VME_MW(VME_A32, VME_D32, sa02Address+FEB_DATA_RST,rdy);
  224.   VME_MWEXEC();
  225.   return 0;
  226. }
  227.  
  228.  
  229. int chaddr[1024];
  230. int sa02Read(uint32_t mask,  uint32_t * data) {
  231.   uint32_t rdy = 0, ready=0;
  232.   int tout=1000; /* 1/100 of a second */
  233.   int count=0;
  234.   int k=0, j=0;
  235.   int nb=0;
  236.   int board;
  237.   uint32_t neve;
  238.   uint32_t c[4]= { 0,0,0,0} ,e[4]= { 0,0,0,0};
  239.  
  240.  
  241.   sa02Tmlnk (tout);
  242.   while (1) {
  243.     VME_A32D32_R(  sa02Address+FEB_DATA_RDY,&rdy);
  244.     if (rdy & (1<<12) )  break;
  245.     count++;
  246.  
  247.     if (sa02TimerOut) {
  248.       uint32_t trgin=0;
  249.       uint32_t value=0;
  250.       VME_A32D32_R(sa02Address+FEB_DEADBEEF, &value);
  251.       sa02Printf("READ at FEB_DEADBEEF 0x%08x\n",  value);
  252.       sa02Printf("[%d] rdy 0x%0x 0x%08x Waiting for DATA READY bit... at line %d\n",count, ready & 0x1, rdy ,  __LINE__);
  253.       for (k=0; k<4; k++)  c[k] = Sa02GetCounter ( k ,&e[k]);
  254.       for (k=0; k<4; k++)  sa02Printf("CNTR%d=%d (ERR=%d)\t",k,c[k],e[k]);
  255.       nb = Sa02GetNeve (&trgin);
  256.       sa02Printf("\tNeve=%d Input triggers %d\n", nb , trgin );
  257.       sa02Tmulk();
  258.       sa02Reset();
  259.       return 0;
  260.     }
  261.   }
  262.   sa02Tmulk();
  263.  
  264.  
  265.  
  266.   for (j=0; j<144*4; j++) data[j]=0;
  267.   if (sa02BltReadout) {
  268.     //int size=sizeof(uint32_t)*FEB_BLTDATA_STOP - FEB_BLTDATA_START ;
  269.     //VME_A32D32BLT_READ(addr, data ,size ,&nb); // BLT RANGE 0x0-0xffc
  270.     //nb = VME_A32D32BLT_R(addr+FEB_BLTDATA_START, data ,size);
  271.     sa02Printf("VME_A32D32BLT_READ not implemented\n %s at line %d\n",__FILE__ ,  __LINE__);
  272.  
  273.   } else {
  274.  
  275.    
  276.     for (board=0; board<4; board++) {
  277.       VME_MRRST(); // MultiReadReset
  278.       for (j=0; j<144; j++) {
  279.         if (mask & (1<<board)) {
  280.           VME_MR(VME_A32, VME_D32,sa02Address+FEB_DATA  +FEB_DATA_INC*board,&data[j+144*board]);
  281.         } else data[j+144*board]=0;
  282.       }
  283.       if ( (mask & (1<<board)) && VME_GetInterface()!= WIENER_VMEMM ) j = VME_MREXEC(&data[144*board]); // MultiReadExecute
  284.  
  285.     }
  286.  
  287.    
  288.     /*
  289.     for (i=0; i<j; i++)
  290.  
  291.       data[i]=((data[i]>>28)&0xF) |
  292.               ((data[i]>>20)&0xF0) |
  293.               ((data[i]>>12)&0xF00) |
  294.               ((data[i]>>4)&0xF000) |
  295.               ((data[i]&0xF000)<<4) |
  296.               ((data[i]&0xF00)<<12) |
  297.               ((data[i]&0xF0)<<20) |
  298.               (data[i]&0xF)<<28;
  299.     */
  300.     /*
  301.       for (i=0; i<j; i++)
  302.         data[i]=(data[i]>>24)&0xFF |
  303.                 (data[i]>>8)&0xFF00 |
  304.                 (data[i]&0xFF00)<<8 |
  305.                 (data[i]&0xFF)<<24;
  306.     */
  307.     nb=j*board*sizeof(uint32_t);
  308.  
  309.   }
  310.   if (sa02Verbose>0) sa02Printf("\tNeve=%d\tCNTR0=%d\tCNTR1=%d\tCNTR2=%d\tCNTR3=%d\n", Sa02GetNeve (&neve), Sa02GetCounter ( 0,&neve ),Sa02GetCounter ( 1 ,&neve),Sa02GetCounter ( 2 ,&neve),Sa02GetCounter ( 3,&neve ));
  311.  
  312.   if (sa02Verbose>1) {
  313.     sa02Printf("sa02Read nb=%d\n",nb);
  314.     for (j=0; j<144*4; j++) printf("%d addr %d data=%d  data=0x%x\n", j, chaddr[j], data[j],data[j] ) ;
  315.   }
  316.   return nb;
  317. }
  318.  
  319. //-------------------------------------------------------------------------
  320. uint32_t  sa02Cmd(uint32_t board, uint32_t cmd, uint32_t data, int chip, int ch, int nload, uint32_t *response) {
  321.   uint32_t datal=0, datah=0, datam, datac;
  322.   uint32_t retval=0,val;
  323.   int i;
  324.  
  325.   if (sa02Verbose>2) {
  326.     sa02Printf("sa02Cmd board=%d cmd=0x%0x data=0x%0x asic=%d ch=%d \n", board, cmd, data, chip, ch);
  327.   }
  328.   switch (cmd & (~ FEB_RO)) {
  329.     case FEB_VTH2:
  330.     case FEB_VTH1:
  331.     case FEB_TPLVL0:
  332.     case FEB_TPLVL1:
  333.       datah = cmd&0xFFFF0000;
  334.       datal = ((cmd<<16)&0xFF0000)|(data&0x0FFF) ;
  335.       for (i=0; i<nload; i++) retval = sa02Write(board,datah,datal,response);
  336.       return retval;
  337.       break;
  338.     case FEB_DLY0:
  339.     case FEB_TP:
  340.     case FEB_ADC_RESET:
  341.     case FEB_SEL_DATA:
  342.     case FEB_SHFT_CLK:
  343.     case FEB_SEND_CLK:
  344.     case FEB_MUX:
  345.       datah = cmd;
  346.       datal = data&0xFFF ;
  347.       for (i=0; i<2; i++) retval = sa02Write(board,datah,datal,response);
  348.       return retval;
  349.       break;
  350.     case FEB_SERIAL:
  351.     case FEB_TMON1:
  352.     case FEB_TMON0:
  353.       datah = cmd;
  354.       datal = data&0xFFF ;
  355.       for (i=0; i<nload; i++) retval = sa02Write(board,datah,datal,response);
  356.       return retval;
  357.       break;
  358.     case FEB_ADC_READ:
  359.       datah = cmd;
  360.       datal = data&0xFFF ;
  361.       val = sa02Write(board,datah,datal,response);
  362.       for (i=0; i<10; i++) {
  363.         retval=sa02Write(board,datah,datal,response);
  364.         if (abs((val&0xFFF)-(retval&0xFFF))<3)
  365.           break;
  366.         else
  367.           val=retval;
  368.       }
  369.       return retval;
  370.       break;
  371.     case SA0x_ASIC0_CMON:
  372.       data  = 36*chip+ch;
  373.     case SA0x_ASIC0_CREG:
  374.       if (sa02Verbose>4) {
  375.         sa02PrintCREG(&data,"Loading creg data->");
  376.       }
  377.       datah = cmd + FEB_SUBA_INC*chip;
  378.       datam = 0x3FFFF;
  379.       datal = ((ch &0x3F )<< 18) | (data & datam );
  380.       datac = datam;
  381.       break;
  382.     case SA0x_ASIC0_GREG:
  383.       if (sa02Verbose>4) {
  384.         sa02PrintGREG(&data,"Loading greg data->");
  385.       }
  386.       datah = cmd + FEB_SUBA_INC*chip;
  387.       datam = 0x3FFFFFF;
  388.       datal = data & datam;
  389.       datac = 0x1FFFF; // greg->id (chip sn ,last 9 bits) is read only
  390.       break;
  391.     default:
  392.       sa02Printf("sa02Cmd: Unknown command 0x%0x\n",cmd);
  393.       return 0;
  394.       break;
  395.   }
  396.   if ((sa02BoardType == 0) && (cmd & FEB_RO)) {
  397.     sa02Printf("sa02Cmd: Readback-only with SA02 NOT possible! 0x%0X\n",cmd);
  398.     return 0;
  399.   }
  400.   if (cmd == SA0x_ASIC0_CMON) {
  401.     for (i=0; i<nload; i++) retval = sa02Write(board,datah,datal,response);
  402.     return 0;
  403.   }
  404.   retval = sa02Write(board,datah,datal,response);
  405.   if (cmd & FEB_RO) return retval;
  406.   if (sa02BoardType) {
  407.     datah |= FEB_RO;
  408.     if (sa02Verbose>4)
  409.           sa02Printf("SA03 read from 0x%x\n", datah );
  410.   } else {
  411.     if (sa02Verbose>4)
  412.           sa02Printf("SA02 reload from 0x%x\n",datah);
  413.   }
  414.   for (i=0; i<5; i++) {
  415.     response[0]=0;
  416.     val = sa02Write(board,datah,datal,response);
  417.     val = sa02Write(board,datah,datal,response);
  418.     retval = sa02Write(board,datah,datal,response);
  419.     if (val==retval) {
  420.       retval &= datam;
  421.       if ((retval & datac) == (data & datac)) return retval;
  422.     }
  423.     sa02Printf("SA0x parameter load attampt %d failed: %d\n",i,144*board+36*chip+ch);
  424.     retval = sa02Write(board,datah&(~FEB_RO),datal,response);
  425.   }
  426. //  if (sa02Verbose>2) {
  427.     switch (cmd) {
  428.       case SA0x_ASIC0_GREG:
  429.         sa02Printf("-----------------------------\n");
  430.         sa02Printf("SA0x_ASIC0_GREG %d  %d 0x%04x 0x%04x chip,ch,read,write\n", chip ,0, retval & 0x1FFFF ,data & 0x3FFFFFF);
  431.         sa02PrintGREG(&data,"Loaded GREG data->");
  432.         sa02PrintGREG(&retval,"Returned GREG data->");
  433.         break;
  434.       case SA0x_ASIC0_CREG:
  435.         sa02Printf("-----------------------------\n");
  436.         sa02Printf("SA0x_ASIC0_CREG %d  %d 0x%04x 0x%04x chip,ch,read,write\n", chip ,ch,retval,data & 0x3FFFF);
  437.         sa02PrintCREG(&data,"Loaded CREG data->");
  438.         sa02PrintCREG(&retval,"Returned CREG data->");
  439.         break;
  440.     }
  441. //  }
  442.   return retval;
  443. }
  444.  
  445. // 1 .read the content of the registers
  446. // 2. modify the registers and
  447. // 3. upload new values
  448. int sa02AsicWrite(uint32_t board, uint32_t reg, uint32_t data, int chip, int ch, uint32_t mask,  uint32_t shft ) {
  449.   uint32_t datar, datal;
  450.   uint32_t response[2]= {0,0};
  451.  
  452.   if (sa02Verbose>3) {
  453.     sa02Printf("-------------------------------------------------------\n");
  454.     sa02Printf("sa02AsicWrite chip %d channel %d data %d mask 0x%0x\n", chip, ch,data,mask);
  455.   }
  456.   // read asic register
  457.   datar = sa02Cmd(board,reg, data, chip, ch, 1 ,response); // load registers one time to get the previous value
  458.   // modify asic register
  459.   datar &= (~mask);
  460.   datal = mask & (data << shft);
  461.   datar |= datal;
  462.   // write asic register
  463.   return sa02Cmd(board,reg, datar, chip, ch ,2,response); // registers are loaded 2 times to get back the value
  464. }
  465. //-------------------------------------------------------------------------
  466. uint32_t sa02GetCmdCode(char *optarg) {
  467.   uint32_t cmd=0;
  468. //    if (strcmp(optarg,"FE")==0)     cmd = FEB_FE;
  469.   if (strcmp(optarg,"TP")==0) {
  470.     cmd = FEB_TP;
  471.   }
  472.   if (strcmp(optarg,"SERIAL")==0) {
  473.     cmd = FEB_SERIAL;
  474.   }
  475.   if (strcmp(optarg,"DLY0")==0) {
  476.     cmd = FEB_DLY0;
  477.   }
  478.   if (strcmp(optarg,"MUX")==0) {
  479.     cmd = FEB_MUX;
  480.   }
  481.   if (strcmp(optarg,"SELDATA")==0) {
  482.     cmd = FEB_SEL_DATA;
  483.   }
  484.   if (strcmp(optarg,"SELMON")==0) {
  485.     cmd = FEB_SEL_MON;
  486.   }
  487.   if (strcmp(optarg,"SHFTCLK")==0) {
  488.     cmd = FEB_SHFT_CLK;
  489.   }
  490.   if (strcmp(optarg,"SENDCLK")==0) {
  491.     cmd = FEB_SEND_CLK;
  492.   }
  493.   if (strcmp(optarg,"MUXASIC")==0) {
  494.     cmd = FEB_MUX;
  495.   }
  496.   if (strcmp(optarg,"VTH2")==0) {
  497.     cmd = FEB_VTH2;
  498.   }
  499.   if (strcmp(optarg,"VTH1")==0) {
  500.     cmd = FEB_VTH1;
  501.   }
  502.   if (strcmp(optarg,"TPLVL0")==0) {
  503.     cmd = FEB_TPLVL0;
  504.   }
  505.   if (strcmp(optarg,"TPLVL1")==0) {
  506.     cmd = FEB_TPLVL1;
  507.   }
  508.   if (strcmp(optarg,"RGREG")==0) {
  509.     cmd = SA0x_ASIC0_GREG | FEB_RO;
  510.   }
  511.   if (strcmp(optarg,"RCREG")==0) {
  512.     cmd = SA0x_ASIC0_CREG | FEB_RO;
  513.   }
  514.   if (strcmp(optarg,"GREG")==0) {
  515.     cmd = SA0x_ASIC0_GREG;
  516.   }
  517.   if (strcmp(optarg,"CREG")==0) {
  518.     cmd = SA0x_ASIC0_CREG;
  519.   }
  520.   if (strcmp(optarg,"CMON")==0) {
  521.     cmd = SA0x_ASIC0_CMON;
  522.   }
  523.   if (strcmp(optarg,"TMON0")==0) {
  524.     cmd = FEB_TMON0;
  525.   }
  526.   if (strcmp(optarg,"TMON1")==0) {
  527.     cmd = FEB_TMON1;
  528.   }
  529.   if (strcmp(optarg,"ADC_READ")==0) {
  530.     cmd = FEB_ADC_READ;
  531.   }
  532.   if (strcmp(optarg,"ADC_RESET")==0) {
  533.     cmd = FEB_ADC_RESET;
  534.   }
  535. // if (strcmp(optarg,"DMON")==0)   cmd = FEB_DMON;
  536.   return cmd;
  537. }
  538. //-------------------------------------------------------------------------
  539.  
  540. uint32_t sa02GetAsicCode(char *optarg, uint32_t *asicpar, uint32_t *asicshft) {
  541.   uint32_t cmd=0;
  542.   if (strcmp(optarg,"PHASECMPS")==0) {
  543.     *asicpar  = ASIC_PHASECMPS;
  544.     *asicshft = ASIC_PHASECMPS_SHFT;
  545.     cmd  = SA0x_ASIC0_GREG;
  546.   }
  547.   if (strcmp(optarg,"GAIN")==0) {
  548.     *asicpar  = ASIC_GAIN;
  549.     *asicshft = ASIC_GAIN;
  550.     cmd  = SA0x_ASIC0_GREG;
  551.   }
  552.   if (strcmp(optarg,"SHAPINGTIME")==0) {
  553.     *asicpar  = ASIC_SHAPINGTIME;
  554.     *asicshft = ASIC_SHAPINGTIME_SHFT;
  555.     cmd  = SA0x_ASIC0_GREG;
  556.   }
  557.   if (strcmp(optarg,"COMPARATOR")==0) {
  558.     *asicpar  = ASIC_COMPARATOR;
  559.     *asicshft = ASIC_COMPARATOR_SHFT;
  560.     cmd  = SA0x_ASIC0_GREG;
  561.   }
  562.   if (strcmp(optarg,"VRDRIVE")==0) {
  563.     *asicpar  = ASIC_VRDRIVE;
  564.     *asicshft = ASIC_VRDRIVE_SHFT;
  565.     cmd  = SA0x_ASIC0_GREG;
  566.   }
  567.   if (strcmp(optarg,"MONITOR")==0) {
  568.     *asicpar  = ASIC_MONITOR;
  569.     *asicshft = ASIC_MONITOR_SHFT;
  570.     cmd  = SA0x_ASIC0_GREG;
  571.   }
  572.   if (strcmp(optarg,"ID")==0) {
  573.     *asicpar = ASIC_ID;
  574.     *asicshft =ASIC_ID_SHFT;
  575.     cmd  = SA0x_ASIC0_GREG;
  576.   }
  577.   if (strcmp(optarg,"DECAYTIME")==0) {
  578.     *asicpar = ASIC_DECAYTIME;
  579.     *asicshft =ASIC_DECAYTIME_SHFT;
  580.     cmd  = SA0x_ASIC0_CREG;
  581.   }
  582.   if (strcmp(optarg,"OFFSET")==0) {
  583.     *asicpar = ASIC_OFFSET;
  584.     *asicshft =ASIC_OFFSET_SHFT;
  585.     cmd  = SA0x_ASIC0_CREG;
  586.   }
  587.   if (strcmp(optarg,"FINEADJ_UNIPOL")==0) {
  588.     *asicpar = ASIC_FINEADJ_UNIPOL;
  589.     *asicshft =ASIC_FINEADJ_UNIPOL_SHFT;
  590.     cmd  = SA0x_ASIC0_CREG;
  591.   }
  592.   if (strcmp(optarg,"FINEADJ_DIFF")==0) {
  593.     *asicpar = ASIC_FINEADJ_DIFF;
  594.     *asicshft =ASIC_FINEADJ_DIFF_SHFT;
  595.     cmd  = SA0x_ASIC0_CREG;
  596.   }
  597.   if (strcmp(optarg,"TPENB")==0) {
  598.     *asicpar = ASIC_TPENDB;
  599.     *asicshft =ASIC_TPENDB_SHFT;
  600.     cmd  = SA0x_ASIC0_CREG;
  601.   }
  602.   if (strcmp(optarg,"KILL")==0) {
  603.     *asicpar  = ASIC_KILL;
  604.     *asicshft =ASIC_KILL_SHFT;
  605.     cmd  = SA0x_ASIC0_CREG;
  606.   }
  607.   return cmd;
  608. }
  609.  
  610. //-------------------------------------------------------------------------
  611. int sa02Init( void ) {
  612.   sa02Printf ("sa02Init not implemeted yet\n");
  613.   return 0;
  614. }
  615.  
  616. //-------------------------------------------------------------------------
  617. int sa02LoadParametersFromFile( const char *fname, uint16_t mask) {
  618.   uint32_t gdata;
  619.   uint32_t cdata;
  620.   uint32_t board=0;
  621.  
  622.   sa02AsicGlobalRegister  *greg = (sa02AsicGlobalRegister  *) &gdata ;
  623.   sa02AsicChannelRegister *creg = (sa02AsicChannelRegister *) &cdata ;
  624. #define NDIM 400
  625.   int ndim=NDIM;
  626.   char line[NDIM];
  627.   char cmd[NDIM];
  628.   char sasic[NDIM];
  629.   char v0[NDIM];
  630.   char v1[NDIM];
  631.   int asic=0, ch=0;
  632.   int gval=0, cval=0;
  633.   int dum=0;
  634.   int b=0;
  635.   uint32_t sa02code;
  636.   uint32_t response[2]= {0,0};
  637.  
  638.   FILE *fp = fopen(fname,"r");
  639.   if (!fp) {
  640.     sa02Printf("Error! Cannot open file %s\n",fname);
  641.     return -1;
  642.   }
  643.   gdata=0;
  644.   cdata=0;
  645.  
  646.   while (fgets(line,ndim,fp)!=NULL) {
  647.     int nb = sscanf(line,"%s%s%s%s",cmd,sasic,v0,v1);
  648.     if (nb<1 || cmd[0]=='#') {
  649.       continue;
  650.     }
  651.     asic =   strtoul (sasic,NULL,0);
  652.     ch   =   strtoul (v0,NULL,0);
  653.     gval =   strtoul (v0,NULL,0);
  654.     cval =   strtoul (v1,NULL,0);
  655.     if (sa02Verbose>2) {
  656.       sa02Printf("%d %s",nb,line);
  657.     }
  658.     sa02code = sa02GetCmdCode(cmd);
  659.     if (strcmp(cmd,"MUXASIC")==0) {
  660.       asic = sa02MuxMap(asic);
  661.     }
  662.        
  663.        
  664.        
  665.    
  666.     switch (nb) {
  667.       case 1: {
  668.         if ( sa02code ) {
  669.           for (b=0;b<4;b++) if (mask &(1<<b)) {
  670.               sa02Cmd(b,sa02code, dum, dum, dum ,2,response);
  671.             }    
  672.           break;
  673.         }
  674.         if (strcmp(cmd,"init")==0) {
  675.           sa02Init();
  676.           break;
  677.         }
  678.         break;
  679.       }
  680.       case 2: {
  681.         if ( sa02code ) {
  682.           for (b=0;b<4;b++) if (mask &(1<<b)) {
  683.               sa02Cmd(b,sa02code, asic, dum, dum, 2,response);
  684.             }    
  685.           break;
  686.         }
  687.         if (strcmp(cmd,"param_board")==0) {
  688.           if (asic != board){
  689.             if ( mask &(1<<asic)) sa02Printf("Parameters for board=%d (mask=0x%x) will be loaded\n",asic,mask );
  690.             else sa02Printf("Parameters for board=%d (mask=0x%x) will not be loaded\n",asic,mask );
  691.           }  
  692.           board = asic;
  693.          
  694.                  
  695.           break;
  696.         }
  697.         if (strcmp(cmd,"load_global")==0) {
  698.           if (mask &(1<<board)) sa02Cmd(board,SA0x_ASIC0_GREG, gdata, asic, ch,1,response);
  699.           break;
  700.         }
  701.         if (strcmp(cmd,"csr1")==0) {
  702.           sa02Printf ("%s not implemeted yet\n",cmd);
  703.           break;
  704.         }
  705.         if (strcmp(cmd,"hdcycle")==0) {
  706.           sa02Printf ("%s not implemeted yet\n",cmd);
  707.           break;
  708.         }
  709.         if (strcmp(cmd,"trgdelay")==0) {
  710.           sa02Printf ("%s not implemeted yet\n",cmd);
  711.           break;
  712.         }
  713.         break;
  714.       }
  715.       case 3: {
  716.         if ( sa02code) {
  717.           sa02Cmd(board,sa02code, gval, asic, dum, 2,response);
  718.           break;
  719.         }
  720.         if (strcmp(cmd,"param_global")==0) {
  721.           gdata = 0;
  722.           break;
  723.         }
  724.         if (strcmp(cmd,"phasecmps")==0) {
  725.           greg->phasecmps = gval;
  726.           break;
  727.         }
  728.         if (strcmp(cmd,"gain")     ==0) {
  729.           greg->gain = gval;
  730.           break;
  731.         }
  732.         if (strcmp(cmd,"shapingtime")==0) {
  733.           greg->shapingtime = gval;
  734.           break;
  735.         }
  736.         if (strcmp(cmd,"comparator")==0) {
  737.           greg->comparator = gval;
  738.           break;
  739.         }
  740.         if (strcmp(cmd,"vrdrive")==0) {
  741.           greg->vrdrive = gval;
  742.           break;
  743.         }
  744.         if (strcmp(cmd,"monitor")==0) {
  745.           greg->monitor = gval;
  746.           break;
  747.         }
  748.         if (strcmp(cmd,"load_ch")==0) {
  749.           //        if (sa02Verbose>2) sa02PrintCREG((uint32_t *)creg);
  750.           if (mask &(1<<board)) sa02Cmd(board,SA0x_ASIC0_CREG, cdata, asic, ch,1,response);
  751.           cdata=0;
  752.           break;
  753.         }
  754.         if (strcmp(cmd,"select")==0) {
  755.           sa02Printf ("%s not implemeted yet\n", cmd);
  756.           break;
  757.         }
  758.         break;
  759.       }
  760.       case 4: {
  761.         if (strcmp(cmd,"param_ch")==0) {
  762.           cdata = 0;
  763.           break;
  764.         }
  765.         if (strcmp(cmd,"decaytime")==0) {
  766.           creg->decaytime = cval;
  767.           break;
  768.         }
  769.         if (strcmp(cmd,"offset")==0) {
  770.           creg->offset = cval;
  771.           break;
  772.         }
  773.         if (strcmp(cmd,"fineadj_unipol")==0) {
  774.           creg->fineadj_unipol = cval;
  775.           break;
  776.         }
  777.         if (strcmp(cmd,"fineadj_diff")==0) {
  778.           creg->fineadj_diff   = cval;
  779.           break;
  780.         }
  781.         if (strcmp(cmd,"tpenb")==0) {
  782.           creg->tpenb = cval;
  783.           break;
  784.         }
  785.         if (strcmp(cmd,"kill")==0) {
  786.           creg->kill  = cval;
  787.           break;
  788.         }
  789.         break;
  790.       }
  791.     }
  792.  
  793.   }
  794.   fclose(fp);
  795.   sa02Printf("Parameters loaded from file %s to FEBs\n", fname);
  796.   return 0;
  797. }
  798.  
  799. //-------------------------------------------------------------------------
  800.  
  801. int sa02GetSerial( uint32_t board, char * serial) {
  802.   uint32_t cmd,response[2]= {0,0};
  803.  
  804.   cmd=FEB_SERIAL;
  805.   sa02Cmd(board,cmd,0,0,0,1,response);
  806.   sprintf(serial,"0x%07X%08X",0x1FFFFFF & response[1],response[0]);
  807.   return 0;
  808. }
  809.  
  810. //-------------------------------------------------------------------------
  811.  
  812. int sa02Status( uint32_t board, char * serial, double *sdata) {
  813.   uint32_t val,data,cmd,response[2]= {0,0};
  814.   int chip,channel,i=0;
  815.   double doubleval;
  816.  
  817.  
  818.   chip=0;
  819.   channel=0;
  820.   data=0;
  821.  
  822.   sa02Printf("FEB SlowControl data:\n");
  823.  
  824.   VME_A32D32_R(sa02Address+FEB_DEADBEEF, &val);
  825.   sa02Printf("READ at FEB_DEADBEEF 0x%08x\n",  val);
  826.  
  827.   sa02GetSerial(board, serial);
  828.   sa02Printf("SERIAL FPGA = %s \n", serial);
  829.  
  830.   cmd=FEB_TMON0;
  831.   val=sa02Cmd(board, cmd, data, chip, channel ,1,response);
  832.   doubleval = ( (val >>2 ) & 0xFFF ) * 0.0625;
  833.   sa02Printf("TMON0 = %5.1f C\n",doubleval);
  834.   sdata[i++]=doubleval;
  835.  
  836.   cmd=FEB_TMON1;
  837.   val=sa02Cmd(board, cmd, data, chip, channel ,1,response);
  838.   doubleval = ( (val >>2 ) & 0xFFF ) * 0.0625;
  839.   sa02Printf("TMON1 = %5.1f C\n",doubleval);
  840.   sdata[i++]=doubleval;
  841.  
  842.   if (sa02BoardType<2) return 0;
  843.  
  844.   cmd=FEB_MUX;
  845.   data=0x10;
  846.   val=sa02Cmd(board, cmd, data, chip, channel ,1,response);
  847.   Delay(0.01);
  848.   cmd=FEB_ADC_READ;
  849.   val=sa02Cmd(board, cmd, data, chip, channel ,1,response);
  850.   doubleval = ((val & 0xFFF) + 0.5)/0x1000 * 3.3;
  851.   sa02Printf("VDD   = %6.3f V\n",doubleval);
  852.   sdata[i++]=doubleval;
  853.  
  854.   cmd=FEB_MUX;
  855.   data=0x11;
  856.   val=sa02Cmd(board, cmd, data, chip, channel ,1,response);
  857.   Delay(0.01);
  858.   cmd=FEB_ADC_READ;
  859.   val=sa02Cmd(board, cmd, data, chip, channel ,1,response);
  860.   doubleval = ((val & 0xFFF) + 0.5)/0x1000 * 3.3;
  861.   sa02Printf("V+2   = %6.3f V\n",doubleval);
  862.   sdata[i++]=doubleval;
  863.  
  864.   cmd=FEB_MUX;
  865.   data=0x12;
  866.   val=sa02Cmd(board, cmd, data, chip, channel ,1,response);
  867.   Delay(0.01);
  868.   cmd=FEB_ADC_READ;
  869.   val=sa02Cmd(board, cmd, data, chip, channel ,1,response);
  870.   doubleval = (2*((val & 0xFFF) + 0.5)/0x1000 - 1.) * 3.3;
  871.   sa02Printf("V-2   = %6.3f V\n",doubleval);
  872.   sdata[i++]=doubleval;
  873.  
  874.  
  875.   cmd=FEB_MUX;
  876.   data=0x13;
  877.   val=sa02Cmd(board, cmd, data, chip, channel ,1,response);
  878.   Delay(0.01);
  879.   cmd=FEB_ADC_READ;
  880.   val=sa02Cmd(board, cmd, data, chip, channel ,1,response);
  881.   doubleval = (2*((val & 0xFFF) + 0.5)/0x1000 - 1.) * 3.3;
  882.   sa02Printf("VSS   = %6.3f V\n",doubleval);
  883.   sdata[i++]=doubleval;
  884.  
  885.   cmd=FEB_MUX;
  886.   data=0x20;
  887.   val=sa02Cmd(board, cmd, data, chip, channel ,1,response);
  888.   Delay(0.01);
  889.   cmd=FEB_ADC_READ;
  890.   val=sa02Cmd(board, cmd, data, chip, channel ,1,response);
  891.   if (sa02BoardType>2)
  892.     doubleval = (2*((val & 0xFFF) + 0.5)/0x1000 - 1.) * 3.3;
  893.   else
  894.     doubleval = ((val & 0xFFF) + 0.5)/0x1000 * 3.3;
  895.   sa02Printf("VTH1  = %6.3f V\n",doubleval);
  896.   sdata[i++]=doubleval;
  897.  
  898.   cmd=FEB_MUX;
  899.   data=0x30;
  900.   val=sa02Cmd(board, cmd, data, chip, channel ,1,response);
  901.   Delay(0.01);
  902.   cmd=FEB_ADC_READ;
  903.   val=sa02Cmd(board, cmd, data, chip, channel ,1,response);
  904.   if (sa02BoardType>2)
  905.     doubleval = (2*((val & 0xFFF) + 0.5)/0x1000 - 1.) * 3.3;
  906.   else
  907.     doubleval = ((val & 0xFFF) + 0.5)/0x1000 * 3.3;
  908.   sa02Printf("VTH2  = %6.3f V\n",doubleval);
  909.   sdata[i++]=doubleval;
  910.  
  911.   cmd=FEB_MUX;
  912.   data=0x40;
  913.   val=sa02Cmd(board, cmd, data, chip, channel ,1,response);
  914.   Delay(0.01);
  915.   cmd=FEB_ADC_READ;
  916.   val=sa02Cmd(board, cmd, data, chip, channel ,1,response);
  917.   doubleval = ((val & 0xFFF) + 0.5)/0x1000 * 3.3;
  918.   sa02Printf("VCC12 = %6.3f V\n",doubleval);
  919.   sdata[i++]=doubleval;
  920.  
  921.   cmd=FEB_MUX;
  922.   data=0x50;
  923.   val=sa02Cmd(board, cmd, data, chip, channel ,1,response);
  924.   Delay(0.01);
  925.   cmd=FEB_ADC_READ;
  926.   val=sa02Cmd(board, cmd, data, chip, channel ,1,response);
  927.   doubleval = ((val & 0xFFF) + 0.5)/0x1000 * 3.3;
  928.   sa02Printf("VCC15 = %6.3f V\n",doubleval);
  929.   sdata[i++]=doubleval;
  930.  
  931.   cmd=FEB_MUX;
  932.   data=0x60;
  933.   val=sa02Cmd(board, cmd, data, chip, channel ,1,response);
  934.   Delay(0.01);
  935.   cmd=FEB_ADC_READ;
  936.   val=sa02Cmd(board, cmd, data, chip, channel ,1,response);
  937.   doubleval = ((val & 0xFFF) + 0.5)/0x1000 * 3.3;
  938.   sa02Printf("VCC25 = %6.3f V\n",doubleval);
  939.   sdata[i++]=doubleval;
  940.  
  941.   cmd=FEB_MUX;
  942.   data=0x70;
  943.   val=sa02Cmd(board, cmd, data, chip, channel ,1,response);
  944.   Delay(0.01);
  945.   cmd=FEB_ADC_READ;
  946.   val=sa02Cmd(board, cmd, data, chip, channel ,1,response);
  947.   doubleval = 2 * ((val & 0xFFF) + 0.5)/0x1000 * 3.3;
  948.   sa02Printf("V+3.8 = %6.3f V\n",doubleval);
  949.   sdata[i++]=doubleval;
  950.  
  951.   cmd=FEB_MUX;
  952.   data=0x00;
  953.   val=sa02Cmd(board, cmd, data, chip, channel ,1,response);
  954.  
  955.   return 0;
  956. }
  957.  
  958.