#ifdef _CVI_
#include <utility.h>
#else
#include <unistd.h>
void Delay(double x) {
usleep(int(1e6*x));
}
#endif
#include <stdlib.h>
#include <stdint.h>
#include <string.h>
#include <stdio.h>
#include "sa02lib.h"
//uint32_t sa02BoardNumber = 0;
uint32_t sa02BoardType = 0;
int sa02Verbose = 0;
int sa02TimerOut;
int sa02BltReadout = 0;
uint32_t sa02Address = 0;
int sa02SetAddress(uint32_t address) {
sa02Address = address;
return 0;
}
int sa02Help( void ) {
sa02Printf ("*********************************************************************************:\n");
sa02Printf ("Usage: Performs single/multiple read or write access to SA02 via CAEN V1495 multipurpose IO board:\n\n");
sa02Printf ("Arguments: \n");
sa02Printf ("-i input parameter filename // can be specified multiple times \n");
sa02Printf ("-v verbosity \n");
sa02Printf ("-g bltreadout \n");
sa02Printf ("-o output filename \n");
sa02Printf ("-f output filename - append data to file\n");
sa02Printf ("-w write command (FE TP DLY0 MUX MUXASIC VTH1 VTH2 TPLVL0 TPLVL1 GREG CREG CMON TMON0 TMON1 DMON) \n");
sa02Printf ("-a vme base address 0x32100000 \n");
sa02Printf ("-c asic chip number (0..3) \n");
sa02Printf ("-x asic channel number (0..36) \n");
sa02Printf ("-t sleep time bewteen events (sec) \n");
sa02Printf ("-d data\n");
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");
sa02Printf ("-s data step or in case of -b the channel step \n");
sa02Printf ("-r number of readouts for each event\n");
sa02Printf ("-n number of events\n");
sa02Printf ("-h <command> at each event execute external command after readouts are done");
sa02Printf ("-q enable test pulse\n");
sa02Printf ("-e send software trigger before reading the data\n");
sa02Printf ("-p asicparameter ( PHASECMPS GAIN SHAPINGTIME COMPARATOR VRDRIVE MONITOR ID)\n");
sa02Printf ("-p asicparameter ( DECAYTIME OFFSET FINEADJ_UNIPOL FINEADJ_DIFF TPENB KILL)\n\n");
sa02Printf ("-u value ... send test SEU software trigger \n");
sa02Printf ("-z value ... finish the execution of the program in <value> s \n");
sa02Printf ("-m fixeddata : test fixed data, if error occurs, abort \n");
sa02Printf ("-l board mask \n");
sa02Printf ("*********************************************************************************:\n");
sa02Printf ("Examples:\n\n");
sa02Printf ("Threshold scan:\n");
sa02Printf ("100 events TMON0 reading and 10 readings of the data for each event:\n");
sa02Printf ("./sa02_ctrl -a 0x32100000 -w TMON0 -n 100 -r 10 -t 10000 -v 1\n\n");
sa02Printf ("scan 9 points TPLVL0 inital data 111 stepsize 11, send 1 test pulse, read data :\n");
sa02Printf ("./sa02_ctrl -a 0x32100000 -w TPLVL0 -d 111 -s 11 -n 9 -e 1 -r 1 -v 1\n\n");
sa02Printf ("Initialize the board from input.param, Read 10000 events of data. the result is saved in the output.dat\n");
sa02Printf ("./sa02_ctrl -a 0x32100000 -i input.param -n 10000 -r 1 -o output.dat \n\n");
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 ");
sa02Printf ("set TPENB to b after the acquisition, the result is saved in the output.dat\n");
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");
return 0;
}
void sa02PrintGREG(uint32_t *data, const char *txt) {
sa02AsicGlobalRegister *a=(sa02AsicGlobalRegister *) data;
sa02Printf("sa02PrintGREG %s 0x%08x\n",txt, *data);
sa02Printf("phasecmps =%d\n",a->phasecmps);
sa02Printf("gain =%d\n",a->gain);
sa02Printf("shapingtime =%d\n",a->shapingtime);
sa02Printf("comparator =%d\n",a->comparator);
sa02Printf("vrdrive =%d\n",a->vrdrive);
sa02Printf("monitor =%d\n",a->monitor);
sa02Printf("id =%d\n",a->id);
sa02Printf("unused =0x%0x\n",a->unused);
};
void sa02PrintCREG(uint32_t *data, const char *txt) {
sa02AsicChannelRegister *a=(sa02AsicChannelRegister *) data;
sa02Printf("sa02PrintCREG %s 0x%08x\n",txt, *data);
sa02Printf("decaytime =%d\n",a->decaytime);
sa02Printf("offset =%d\n",a->offset);
sa02Printf("fineadj_unipol=%d\n",a->fineadj_unipol);
sa02Printf("fineadj_diff =%d\n",a->fineadj_diff);
sa02Printf("reserved =%d\n",a->reserved);
sa02Printf("tpenb =%d\n",a->tpenb);
sa02Printf("kill =%d\n",a->kill);
sa02Printf("unused =0x%0x\n",a->unused);
};
int sa02MuxMap(int i ) {
if (sa02BoardType > 1) return i;
switch ( i ) {
case 0:
return 2;
case 1:
return 0;
case 2:
return 3;
case 3:
return 1;
}
return i;
};
#define ADC_VCC 3.3
#define AMP_IB_min -1.15e-6
#define ADC_IB_min 2355
#define AMP_IB_max 0.2e-6
#define ADC_IB_max 2665
double sa02ampIb(int adc) {
if (adc <= ADC_IB_min) return AMP_IB_min;
if (adc > ADC_IB_max) return AMP_IB_max;
return AMP_IB_min + ((AMP_IB_max-AMP_IB_min)/(ADC_IB_max-ADC_IB_min)) * (adc - ADC_IB_min);
}
double sa02adc2V(int adc) {
adc &=0xFFF;
return ADC_VCC * (double)adc/4096;
}
double sa02adc2Vp(int adc) {
adc &=0xFFF;
return ADC_VCC * (double)adc/4096 + 1.0e+4 * sa02ampIb(adc);
}
double sa02adc2Vm(int adc) {
adc &=0xFFF;
return ADC_VCC * (2. * (double)adc/4096. - 1.) + 5.1e+4 * sa02ampIb(adc);
}
double sa02adc2V38(int adc) {
adc &=0xFFF;
return ADC_VCC * (2. * (double)adc/4096.) + 5.1e+4 * sa02ampIb(adc);
}
double sa02adc2Va(int adc) {
adc &=0xFFF;
return ADC_VCC * (double)adc/4096. - (ADC_VCC/2. + 0.06);
}
//-------------------------------------------------------------------------
uint32_t sa02Write(uint32_t sa02BoardNumber, uint32_t regh, uint32_t regl, uint32_t *response)
{
VME_A32D32_W(sa02Address+FEB_DATAOUT0+FEB_DATA_INC*sa02BoardNumber,regl);
VME_A32D32_W(sa02Address+FEB_DATAOUT1+FEB_DATA_INC*sa02BoardNumber,regh);
Delay(0.001);
VME_A32D32_R(sa02Address+FEB_DATAIN0+FEB_DATA_INC*sa02BoardNumber,response);
VME_A32D32_R(sa02Address+FEB_DATAIN1+FEB_DATA_INC*sa02BoardNumber,response+1);
if (sa02Verbose>1) {
sa02Printf("sa02Write board= %d 0x%08x 0x%08x retval =0x%08X_%08X\n", sa02BoardNumber, regh, regl, response[1], response[0]);
}
return response[0];
}
//-------------------------------------------------------------------------
int Sa02DaqMode (uint32_t mode) {
VME_A32D32_W(sa02Address+FEB_DAQMODE,mode);
return 0;
}
int Sa02SetPtsOutput(uint32_t mask) {
VME_A32D32_W(sa02Address+FEB_DEBUGMON,mask);
return 0;
}
int Sa02SetNeve (uint32_t neve) {
VME_A32D32_W(sa02Address+FEB_SETNEVE,neve);
return 0;
}
uint32_t Sa02GetNeve (uint32_t*inputtriggers) {
uint32_t neve=0;
VME_A32D32_R(sa02Address+FEB_GETNEVE,&neve);
*inputtriggers = (neve >> 16) &0xFFFF;
return neve &0xFFFF; // output triggers
}
uint32_t Sa02GetCounter (uint32_t board, uint32_t *errors) {
uint32_t neve=0;
VME_A32D32_R(sa02Address+FEB_CNTR+FEB_DATA_INC*board,&neve);
*errors = (neve >> 16) &0xFFFF;
return neve &0xFFFF;
}
uint32_t Sa02GetChAddr (uint32_t board) {
uint32_t neve=0;
VME_A32D32_R(sa02Address+FEB_CHADDR+FEB_DATA_INC*board,&neve);
return neve;
}
int sa02Reset1( void ) {
uint32_t rdy=1;
VME_A32D32_W(sa02Address+FEB_DATA_RST,rdy);
return 0;
}
int Sa02SEUTrigger (void) {
uint32_t rdy;
rdy=1;
VME_MWRST();
VME_MW(VME_A32, VME_D32, sa02Address+FEB_SEUTRG,rdy);
rdy=0;
VME_MW(VME_A32, VME_D32, sa02Address+FEB_SEUTRG,rdy);
VME_MWEXEC();
return 0;
}
int Sa02SelectTrigger (uint32_t trg) {
VME_A32D32_W(sa02Address+FEB_SELTRG,trg);
return 0;
}
int Sa02SelectTriggerWithMaskAndLength (uint32_t trg, uint32_t mask, uint32_t len) {
VME_A32D32_W(sa02Address+FEB_SELTRG, trg | (mask << 4) | (len << 16) );
return 0;
}
int Sa02SoftwareTrigger (void ) {
uint32_t rdy =1;
VME_MWRST();
VME_MW(VME_A32, VME_D32,sa02Address+FEB_SWTRG,rdy);
VME_MWEXEC();
return 0;
}
int Sa02TestPulseEnable (uint32_t board, uint32_t enable ) {
uint32_t response[2]= {0,0};
return sa02Cmd(board,FEB_TP, enable, 0, 0 ,1,response);
}
int sa02Reset( void ) {
uint32_t rdy;
rdy=1;
VME_MWRST();
VME_MW(VME_A32, VME_D32, sa02Address+FEB_DATA_RST,rdy);
VME_MWEXEC();
return 0;
}
int chaddr[1024];
int sa02Read(uint32_t mask, uint32_t * data) {
uint32_t rdy = 0, ready=0;
int tout=1000; /* 1/100 of a second */
int count=0;
int k=0, j=0;
int nb=0;
int board;
uint32_t neve;
uint32_t c[4]= { 0,0,0,0} ,e[4]= { 0,0,0,0};
sa02Tmlnk (tout);
while (1) {
VME_A32D32_R( sa02Address+FEB_DATA_RDY,&rdy);
if (rdy & (1<<12) ) break;
count++;
if (sa02TimerOut) {
uint32_t trgin=0;
uint32_t value=0;
VME_A32D32_R(sa02Address+FEB_DEADBEEF, &value);
sa02Printf("READ at FEB_DEADBEEF 0x%08x\n", value);
sa02Printf("[%d] rdy 0x%0x 0x%08x Waiting for DATA READY bit... at line %d\n",count, ready & 0x1, rdy , __LINE__);
for (k=0; k<4; k++) c[k] = Sa02GetCounter ( k ,&e[k]);
for (k=0; k<4; k++) sa02Printf("CNTR%d=%d (ERR=%d)\t",k,c[k],e[k]);
nb = Sa02GetNeve (&trgin);
sa02Printf("\tNeve=%d Input triggers %d\n", nb , trgin );
sa02Tmulk();
sa02Reset();
return 0;
}
}
sa02Tmulk();
for (j=0; j<144*4; j++) data[j]=0;
if (sa02BltReadout) {
//int size=sizeof(uint32_t)*FEB_BLTDATA_STOP - FEB_BLTDATA_START ;
//VME_A32D32BLT_READ(addr, data ,size ,&nb); // BLT RANGE 0x0-0xffc
//nb = VME_A32D32BLT_R(addr+FEB_BLTDATA_START, data ,size);
sa02Printf("VME_A32D32BLT_READ not implemented\n %s at line %d\n",__FILE__ , __LINE__);
} else {
for (board=0; board<4; board++) {
VME_MRRST(); // MultiReadReset
for (j=0; j<144; j++) {
if (mask & (1<<board)) {
VME_MR(VME_A32, VME_D32,sa02Address+FEB_DATA +FEB_DATA_INC*board,&data[j+144*board]);
} else data[j+144*board]=0;
}
if ( (mask & (1<<board)) && VME_GetInterface()!= WIENER_VMEMM ) j = VME_MREXEC(&data[144*board]); // MultiReadExecute
}
/*
for (i=0; i<j; i++)
data[i]=((data[i]>>28)&0xF) |
((data[i]>>20)&0xF0) |
((data[i]>>12)&0xF00) |
((data[i]>>4)&0xF000) |
((data[i]&0xF000)<<4) |
((data[i]&0xF00)<<12) |
((data[i]&0xF0)<<20) |
(data[i]&0xF)<<28;
*/
/*
for (i=0; i<j; i++)
data[i]=(data[i]>>24)&0xFF |
(data[i]>>8)&0xFF00 |
(data[i]&0xFF00)<<8 |
(data[i]&0xFF)<<24;
*/
nb=j*board*sizeof(uint32_t);
}
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 ));
if (sa02Verbose>1) {
sa02Printf("sa02Read nb=%d\n",nb);
for (j
=0; j
<144*4; j
++) printf("%d addr %d data=%d data=0x%x\n", j
, chaddr
[j
], data
[j
],data
[j
] ) ;
}
return nb;
}
//-------------------------------------------------------------------------
uint32_t sa02Cmd(uint32_t board, uint32_t cmd, uint32_t data, int chip, int ch, int nload, uint32_t *response) {
uint32_t datal=0, datah=0, datam, datac;
uint32_t retval=0,val;
int i;
if (sa02Verbose>2) {
sa02Printf("sa02Cmd board=%d cmd=0x%0x data=0x%0x asic=%d ch=%d \n", board, cmd, data, chip, ch);
}
switch (cmd & (~ FEB_RO)) {
case FEB_VTH2:
case FEB_VTH1:
case FEB_TPLVL0:
case FEB_TPLVL1:
datah = cmd&0xFFFF0000;
datal = ((cmd<<16)&0xFF0000)|(data&0x0FFF) ;
for (i=0; i<nload; i++) retval = sa02Write(board,datah,datal,response);
return retval;
break;
case FEB_DLY0:
case FEB_TP:
case FEB_ADC_RESET:
case FEB_SEL_DATA:
case FEB_SHFT_CLK:
case FEB_SEND_CLK:
case FEB_MUX:
datah = cmd;
datal = data&0xFFF ;
for (i=0; i<2; i++) retval = sa02Write(board,datah,datal,response);
return retval;
break;
case FEB_SERIAL:
case FEB_TMON1:
case FEB_TMON0:
datah = cmd;
datal = data&0xFFF ;
for (i=0; i<nload; i++) retval = sa02Write(board,datah,datal,response);
return retval;
break;
case FEB_ADC_READ:
datah = cmd;
datal = data&0xFFF ;
val = sa02Write(board,datah,datal,response);
for (i=0; i<10; i++) {
retval=sa02Write(board,datah,datal,response);
if (abs((val
&0xFFF)-(retval
&0xFFF))<3)
break;
else
val=retval;
}
return retval;
break;
case SA0x_ASIC0_CMON:
data = 36*chip+ch;
case SA0x_ASIC0_CREG:
if (sa02Verbose>4) {
sa02PrintCREG(&data,"Loading creg data->");
}
datah = cmd + FEB_SUBA_INC*chip;
datam = 0x3FFFF;
datal = ((ch &0x3F )<< 18) | (data & datam );
datac = datam;
break;
case SA0x_ASIC0_GREG:
if (sa02Verbose>4) {
sa02PrintGREG(&data,"Loading greg data->");
}
datah = cmd + FEB_SUBA_INC*chip;
datam = 0x3FFFFFF;
datal = data & datam;
datac = 0x1FFFF; // greg->id (chip sn ,last 9 bits) is read only
break;
default:
sa02Printf("sa02Cmd: Unknown command 0x%0x\n",cmd);
return 0;
break;
}
if ((sa02BoardType == 0) && (cmd & FEB_RO)) {
sa02Printf("sa02Cmd: Readback-only with SA02 NOT possible! 0x%0X\n",cmd);
return 0;
}
if (cmd == SA0x_ASIC0_CMON) {
for (i=0; i<nload; i++) retval = sa02Write(board,datah,datal,response);
return 0;
}
retval = sa02Write(board,datah,datal,response);
if (cmd & FEB_RO) return retval;
if (sa02BoardType) {
datah |= FEB_RO;
if (sa02Verbose>4)
sa02Printf("SA03 read from 0x%x\n", datah );
} else {
if (sa02Verbose>4)
sa02Printf("SA02 reload from 0x%x\n",datah);
}
for (i=0; i<5; i++) {
response[0]=0;
val = sa02Write(board,datah,datal,response);
val = sa02Write(board,datah,datal,response);
retval = sa02Write(board,datah,datal,response);
if (val==retval) {
retval &= datam;
if ((retval & datac) == (data & datac)) return retval;
}
sa02Printf("SA0x parameter load attampt %d failed: %d\n",i,144*board+36*chip+ch);
retval = sa02Write(board,datah&(~FEB_RO),datal,response);
}
// if (sa02Verbose>2) {
switch (cmd) {
case SA0x_ASIC0_GREG:
sa02Printf("-----------------------------\n");
sa02Printf("SA0x_ASIC0_GREG %d %d 0x%04x 0x%04x chip,ch,read,write\n", chip ,0, retval & 0x1FFFF ,data & 0x3FFFFFF);
sa02PrintGREG(&data,"Loaded GREG data->");
sa02PrintGREG(&retval,"Returned GREG data->");
break;
case SA0x_ASIC0_CREG:
sa02Printf("-----------------------------\n");
sa02Printf("SA0x_ASIC0_CREG %d %d 0x%04x 0x%04x chip,ch,read,write\n", chip ,ch,retval,data & 0x3FFFF);
sa02PrintCREG(&data,"Loaded CREG data->");
sa02PrintCREG(&retval,"Returned CREG data->");
break;
}
// }
return retval;
}
// 1 .read the content of the registers
// 2. modify the registers and
// 3. upload new values
int sa02AsicWrite(uint32_t board, uint32_t reg, uint32_t data, int chip, int ch, uint32_t mask, uint32_t shft ) {
uint32_t datar, datal;
uint32_t response[2]= {0,0};
if (sa02Verbose>3) {
sa02Printf("-------------------------------------------------------\n");
sa02Printf("sa02AsicWrite chip %d channel %d data %d mask 0x%0x\n", chip, ch,data,mask);
}
// read asic register
datar = sa02Cmd(board,reg, data, chip, ch, 1 ,response); // load registers one time to get the previous value
// modify asic register
datar &= (~mask);
datal = mask & (data << shft);
datar |= datal;
// write asic register
return sa02Cmd(board,reg, datar, chip, ch ,2,response); // registers are loaded 2 times to get back the value
}
//-------------------------------------------------------------------------
uint32_t sa02GetCmdCode(char *optarg) {
uint32_t cmd=0;
// if (strcmp(optarg,"FE")==0) cmd = FEB_FE;
cmd = FEB_TP;
}
if (strcmp(optarg
,"SERIAL")==0) {
cmd = FEB_SERIAL;
}
if (strcmp(optarg
,"DLY0")==0) {
cmd = FEB_DLY0;
}
if (strcmp(optarg
,"MUX")==0) {
cmd = FEB_MUX;
}
if (strcmp(optarg
,"SELDATA")==0) {
cmd = FEB_SEL_DATA;
}
if (strcmp(optarg
,"SELMON")==0) {
cmd = FEB_SEL_MON;
}
if (strcmp(optarg
,"SHFTCLK")==0) {
cmd = FEB_SHFT_CLK;
}
if (strcmp(optarg
,"SENDCLK")==0) {
cmd = FEB_SEND_CLK;
}
if (strcmp(optarg
,"MUXASIC")==0) {
cmd = FEB_MUX;
}
if (strcmp(optarg
,"VTH2")==0) {
cmd = FEB_VTH2;
}
if (strcmp(optarg
,"VTH1")==0) {
cmd = FEB_VTH1;
}
if (strcmp(optarg
,"TPLVL0")==0) {
cmd = FEB_TPLVL0;
}
if (strcmp(optarg
,"TPLVL1")==0) {
cmd = FEB_TPLVL1;
}
if (strcmp(optarg
,"RGREG")==0) {
cmd = SA0x_ASIC0_GREG | FEB_RO;
}
if (strcmp(optarg
,"RCREG")==0) {
cmd = SA0x_ASIC0_CREG | FEB_RO;
}
if (strcmp(optarg
,"GREG")==0) {
cmd = SA0x_ASIC0_GREG;
}
if (strcmp(optarg
,"CREG")==0) {
cmd = SA0x_ASIC0_CREG;
}
if (strcmp(optarg
,"CMON")==0) {
cmd = SA0x_ASIC0_CMON;
}
if (strcmp(optarg
,"TMON0")==0) {
cmd = FEB_TMON0;
}
if (strcmp(optarg
,"TMON1")==0) {
cmd = FEB_TMON1;
}
if (strcmp(optarg
,"ADC_READ")==0) {
cmd = FEB_ADC_READ;
}
if (strcmp(optarg
,"ADC_RESET")==0) {
cmd = FEB_ADC_RESET;
}
// if (strcmp(optarg,"DMON")==0) cmd = FEB_DMON;
return cmd;
}
//-------------------------------------------------------------------------
uint32_t sa02GetAsicCode(char *optarg, uint32_t *asicpar, uint32_t *asicshft) {
uint32_t cmd=0;
if (strcmp(optarg
,"PHASECMPS")==0) {
*asicpar = ASIC_PHASECMPS;
*asicshft = ASIC_PHASECMPS_SHFT;
cmd = SA0x_ASIC0_GREG;
}
if (strcmp(optarg
,"GAIN")==0) {
*asicpar = ASIC_GAIN;
*asicshft = ASIC_GAIN;
cmd = SA0x_ASIC0_GREG;
}
if (strcmp(optarg
,"SHAPINGTIME")==0) {
*asicpar = ASIC_SHAPINGTIME;
*asicshft = ASIC_SHAPINGTIME_SHFT;
cmd = SA0x_ASIC0_GREG;
}
if (strcmp(optarg
,"COMPARATOR")==0) {
*asicpar = ASIC_COMPARATOR;
*asicshft = ASIC_COMPARATOR_SHFT;
cmd = SA0x_ASIC0_GREG;
}
if (strcmp(optarg
,"VRDRIVE")==0) {
*asicpar = ASIC_VRDRIVE;
*asicshft = ASIC_VRDRIVE_SHFT;
cmd = SA0x_ASIC0_GREG;
}
if (strcmp(optarg
,"MONITOR")==0) {
*asicpar = ASIC_MONITOR;
*asicshft = ASIC_MONITOR_SHFT;
cmd = SA0x_ASIC0_GREG;
}
*asicpar = ASIC_ID;
*asicshft =ASIC_ID_SHFT;
cmd = SA0x_ASIC0_GREG;
}
if (strcmp(optarg
,"DECAYTIME")==0) {
*asicpar = ASIC_DECAYTIME;
*asicshft =ASIC_DECAYTIME_SHFT;
cmd = SA0x_ASIC0_CREG;
}
if (strcmp(optarg
,"OFFSET")==0) {
*asicpar = ASIC_OFFSET;
*asicshft =ASIC_OFFSET_SHFT;
cmd = SA0x_ASIC0_CREG;
}
if (strcmp(optarg
,"FINEADJ_UNIPOL")==0) {
*asicpar = ASIC_FINEADJ_UNIPOL;
*asicshft =ASIC_FINEADJ_UNIPOL_SHFT;
cmd = SA0x_ASIC0_CREG;
}
if (strcmp(optarg
,"FINEADJ_DIFF")==0) {
*asicpar = ASIC_FINEADJ_DIFF;
*asicshft =ASIC_FINEADJ_DIFF_SHFT;
cmd = SA0x_ASIC0_CREG;
}
if (strcmp(optarg
,"TPENB")==0) {
*asicpar = ASIC_TPENDB;
*asicshft =ASIC_TPENDB_SHFT;
cmd = SA0x_ASIC0_CREG;
}
if (strcmp(optarg
,"KILL")==0) {
*asicpar = ASIC_KILL;
*asicshft =ASIC_KILL_SHFT;
cmd = SA0x_ASIC0_CREG;
}
return cmd;
}
//-------------------------------------------------------------------------
int sa02Init( void ) {
sa02Printf ("sa02Init not implemeted yet\n");
return 0;
}
//-------------------------------------------------------------------------
int sa02LoadParametersFromFile( const char *fname, uint16_t mask) {
uint32_t gdata;
uint32_t cdata;
uint32_t board=0;
sa02AsicGlobalRegister *greg = (sa02AsicGlobalRegister *) &gdata ;
sa02AsicChannelRegister *creg = (sa02AsicChannelRegister *) &cdata ;
#define NDIM 400
int ndim=NDIM;
char line[NDIM];
char cmd[NDIM];
char sasic[NDIM];
char v0[NDIM];
char v1[NDIM];
int asic=0, ch=0;
int gval=0, cval=0;
int dum=0;
int b=0;
uint32_t sa02code;
uint32_t response[2]= {0,0};
FILE
*fp
= fopen(fname
,"r");
if (!fp) {
sa02Printf("Error! Cannot open file %s\n",fname);
return -1;
}
gdata=0;
cdata=0;
while (fgets(line
,ndim
,fp
)!=NULL
) {
int nb
= sscanf(line
,"%s%s%s%s",cmd
,sasic
,v0
,v1
);
if (nb<1 || cmd[0]=='#') {
continue;
}
if (sa02Verbose>2) {
sa02Printf("%d %s",nb,line);
}
sa02code = sa02GetCmdCode(cmd);
if (strcmp(cmd
,"MUXASIC")==0) {
asic = sa02MuxMap(asic);
}
switch (nb) {
case 1: {
if ( sa02code ) {
for (b=0;b<4;b++) if (mask &(1<<b)) {
sa02Cmd(b,sa02code, dum, dum, dum ,2,response);
}
break;
}
sa02Init();
break;
}
break;
}
case 2: {
if ( sa02code ) {
for (b=0;b<4;b++) if (mask &(1<<b)) {
sa02Cmd(b,sa02code, asic, dum, dum, 2,response);
}
break;
}
if (strcmp(cmd
,"param_board")==0) {
if (asic != board){
if ( mask &(1<<asic)) sa02Printf("Parameters for board=%d (mask=0x%x) will be loaded\n",asic,mask );
else sa02Printf("Parameters for board=%d (mask=0x%x) will not be loaded\n",asic,mask );
}
board = asic;
break;
}
if (strcmp(cmd
,"load_global")==0) {
if (mask &(1<<board)) sa02Cmd(board,SA0x_ASIC0_GREG, gdata, asic, ch,1,response);
break;
}
sa02Printf ("%s not implemeted yet\n",cmd);
break;
}
if (strcmp(cmd
,"hdcycle")==0) {
sa02Printf ("%s not implemeted yet\n",cmd);
break;
}
if (strcmp(cmd
,"trgdelay")==0) {
sa02Printf ("%s not implemeted yet\n",cmd);
break;
}
break;
}
case 3: {
if ( sa02code) {
sa02Cmd(board,sa02code, gval, asic, dum, 2,response);
break;
}
if (strcmp(cmd
,"param_global")==0) {
gdata = 0;
break;
}
if (strcmp(cmd
,"phasecmps")==0) {
greg->phasecmps = gval;
break;
}
greg->gain = gval;
break;
}
if (strcmp(cmd
,"shapingtime")==0) {
greg->shapingtime = gval;
break;
}
if (strcmp(cmd
,"comparator")==0) {
greg->comparator = gval;
break;
}
if (strcmp(cmd
,"vrdrive")==0) {
greg->vrdrive = gval;
break;
}
if (strcmp(cmd
,"monitor")==0) {
greg->monitor = gval;
break;
}
if (strcmp(cmd
,"load_ch")==0) {
// if (sa02Verbose>2) sa02PrintCREG((uint32_t *)creg);
if (mask &(1<<board)) sa02Cmd(board,SA0x_ASIC0_CREG, cdata, asic, ch,1,response);
cdata=0;
break;
}
if (strcmp(cmd
,"select")==0) {
sa02Printf ("%s not implemeted yet\n", cmd);
break;
}
break;
}
case 4: {
if (strcmp(cmd
,"param_ch")==0) {
cdata = 0;
break;
}
if (strcmp(cmd
,"decaytime")==0) {
creg->decaytime = cval;
break;
}
if (strcmp(cmd
,"offset")==0) {
creg->offset = cval;
break;
}
if (strcmp(cmd
,"fineadj_unipol")==0) {
creg->fineadj_unipol = cval;
break;
}
if (strcmp(cmd
,"fineadj_diff")==0) {
creg->fineadj_diff = cval;
break;
}
creg->tpenb = cval;
break;
}
creg->kill = cval;
break;
}
break;
}
}
}
sa02Printf("Parameters loaded from file %s to FEBs\n", fname);
return 0;
}
//-------------------------------------------------------------------------
int sa02GetSerial( uint32_t board, char * serial) {
uint32_t cmd,response[2]= {0,0};
cmd=FEB_SERIAL;
sa02Cmd(board,cmd,0,0,0,1,response);
sprintf(serial
,"0x%07X%08X",0x1FFFFFF & response
[1],response
[0]);
return 0;
}
//-------------------------------------------------------------------------
int sa02Status( uint32_t board, char * serial, double *sdata) {
uint32_t val,data,cmd,response[2]= {0,0};
int chip,channel,i=0;
double doubleval;
chip=0;
channel=0;
data=0;
sa02Printf("FEB SlowControl data:\n");
VME_A32D32_R(sa02Address+FEB_DEADBEEF, &val);
sa02Printf("READ at FEB_DEADBEEF 0x%08x\n", val);
sa02GetSerial(board, serial);
sa02Printf("SERIAL FPGA = %s \n", serial);
cmd=FEB_TMON0;
val=sa02Cmd(board, cmd, data, chip, channel ,1,response);
doubleval = ( (val >>2 ) & 0xFFF ) * 0.0625;
sa02Printf("TMON0 = %5.1f C\n",doubleval);
sdata[i++]=doubleval;
cmd=FEB_TMON1;
val=sa02Cmd(board, cmd, data, chip, channel ,1,response);
doubleval = ( (val >>2 ) & 0xFFF ) * 0.0625;
sa02Printf("TMON1 = %5.1f C\n",doubleval);
sdata[i++]=doubleval;
if (sa02BoardType<2) return 0;
cmd=FEB_MUX;
data=0x10;
val=sa02Cmd(board, cmd, data, chip, channel ,1,response);
Delay(0.01);
cmd=FEB_ADC_READ;
val=sa02Cmd(board, cmd, data, chip, channel ,1,response);
doubleval = sa02adc2Vp(val);
sa02Printf("VDD = %6.3f V\n",doubleval);
sdata[i++]=doubleval;
cmd=FEB_MUX;
data=0x11;
val=sa02Cmd(board, cmd, data, chip, channel ,1,response);
Delay(0.01);
cmd=FEB_ADC_READ;
val=sa02Cmd(board, cmd, data, chip, channel ,1,response);
doubleval = sa02adc2Vp(val);
sa02Printf("V+2 = %6.3f V\n",doubleval);
sdata[i++]=doubleval;
cmd=FEB_MUX;
data=0x12;
val=sa02Cmd(board, cmd, data, chip, channel ,1,response);
Delay(0.01);
cmd=FEB_ADC_READ;
val=sa02Cmd(board, cmd, data, chip, channel ,1,response);
doubleval = sa02adc2Vm(val);
sa02Printf("V-2 = %6.3f V\n",doubleval);
sdata[i++]=doubleval;
cmd=FEB_MUX;
data=0x13;
val=sa02Cmd(board, cmd, data, chip, channel ,1,response);
Delay(0.01);
cmd=FEB_ADC_READ;
val=sa02Cmd(board, cmd, data, chip, channel ,1,response);
doubleval = sa02adc2Vm(val);
sa02Printf("VSS = %6.3f V\n",doubleval);
sdata[i++]=doubleval;
cmd=FEB_MUX;
data=0x20;
val=sa02Cmd(board, cmd, data, chip, channel ,1,response);
Delay(0.01);
cmd=FEB_ADC_READ;
val=sa02Cmd(board, cmd, data, chip, channel ,1,response);
if (sa02BoardType>2)
doubleval = sa02adc2Vm(val);
else
doubleval = sa02adc2V(val);
sa02Printf("VTH1 = %6.3f V\n",doubleval);
sdata[i++]=doubleval;
cmd=FEB_MUX;
data=0x30;
val=sa02Cmd(board, cmd, data, chip, channel ,1,response);
Delay(0.01);
cmd=FEB_ADC_READ;
val=sa02Cmd(board, cmd, data, chip, channel ,1,response);
if (sa02BoardType>2)
doubleval = sa02adc2Vm(val);
else
doubleval = sa02adc2V(val);
sa02Printf("VTH2 = %6.3f V\n",doubleval);
sdata[i++]=doubleval;
cmd=FEB_MUX;
data=0x40;
val=sa02Cmd(board, cmd, data, chip, channel ,1,response);
Delay(0.01);
cmd=FEB_ADC_READ;
val=sa02Cmd(board, cmd, data, chip, channel ,1,response);
doubleval = sa02adc2Vp(val);
sa02Printf("VCC12 = %6.3f V\n",doubleval);
sdata[i++]=doubleval;
cmd=FEB_MUX;
data=0x50;
val=sa02Cmd(board, cmd, data, chip, channel ,1,response);
Delay(0.01);
cmd=FEB_ADC_READ;
val=sa02Cmd(board, cmd, data, chip, channel ,1,response);
doubleval = sa02adc2Vp(val);
sa02Printf("VCC15 = %6.3f V\n",doubleval);
sdata[i++]=doubleval;
cmd=FEB_MUX;
data=0x60;
val=sa02Cmd(board, cmd, data, chip, channel ,1,response);
Delay(0.01);
cmd=FEB_ADC_READ;
val=sa02Cmd(board, cmd, data, chip, channel ,1,response);
doubleval = sa02adc2Vp(val);
sa02Printf("VCC25 = %6.3f V\n",doubleval);
sdata[i++]=doubleval;
cmd=FEB_MUX;
data=0x70;
val=sa02Cmd(board, cmd, data, chip, channel ,1,response);
Delay(0.01);
cmd=FEB_ADC_READ;
val=sa02Cmd(board, cmd, data, chip, channel ,1,response);
doubleval = sa02adc2V38(val);
sa02Printf("V+3.8 = %6.3f V\n",doubleval);
sdata[i++]=doubleval;
cmd=FEB_MUX;
data=0x00;
val=sa02Cmd(board, cmd, data, chip, channel ,1,response);
return 0;
}