Rev 326 |
Blame |
Compare with Previous |
Last modification |
View Log
| RSS feed
#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;
if (strcmp(optarg
,"TP")==0) {
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
;
}
if (strcmp(optarg
,"ID")==0) {
*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;
}
asic
= strtoul (sasic
,NULL
,0);
ch
= strtoul (v0
,NULL
,0);
gval
= strtoul (v0
,NULL
,0);
cval
= strtoul (v1
,NULL
,0);
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;
}
if (strcmp(cmd
,"init")==0) {
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;
}
if (strcmp(cmd
,"csr1")==0) {
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;
}
if (strcmp(cmd
,"gain") ==0) {
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;
}
if (strcmp(cmd
,"tpenb")==0) {
creg
->tpenb
= cval
;
break;
}
if (strcmp(cmd
,"kill")==0) {
creg
->kill
= cval
;
break;
}
break;
}
}
}
fclose(fp
);
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;
}