Subversion Repositories f9daq

Rev

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